mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Consolidate raw socket acquisition.
This commit is contained in:
29
FPEngine.cc
29
FPEngine.cc
@@ -118,7 +118,7 @@ FPNetworkControl::~FPNetworkControl() {
|
|||||||
|
|
||||||
/* (Re)-Initialize object's state (default parameter setup and nsock
|
/* (Re)-Initialize object's state (default parameter setup and nsock
|
||||||
* initialization). */
|
* initialization). */
|
||||||
void FPNetworkControl::init(const char *ifname, devtype iftype) {
|
void FPNetworkControl::init(const char *ifname) {
|
||||||
|
|
||||||
/* Init congestion control parameters */
|
/* Init congestion control parameters */
|
||||||
this->cc_init();
|
this->cc_init();
|
||||||
@@ -155,27 +155,14 @@ void FPNetworkControl::init(const char *ifname, devtype iftype) {
|
|||||||
/* Flag it as already initialized so we free this nsp next time */
|
/* Flag it as already initialized so we free this nsp next time */
|
||||||
this->nsock_init = true;
|
this->nsock_init = true;
|
||||||
|
|
||||||
/* Obtain raw socket or check that we can obtain an eth descriptor. */
|
/* We don't need to store the eth handle because FPProbes come with a
|
||||||
if ((o.sendpref & PACKET_SEND_ETH) && (iftype == devt_ethernet
|
|
||||||
#ifdef WIN32
|
|
||||||
|| (o.have_pcap && iftype == devt_loopback)
|
|
||||||
#endif
|
|
||||||
) && ifname != NULL) {
|
|
||||||
/* We don't need to store the eth handler because FPProbes come with a
|
|
||||||
* suitable one (FPProbes::getEthernet()), we just attempt to obtain one
|
* suitable one (FPProbes::getEthernet()), we just attempt to obtain one
|
||||||
* to see if it fails. */
|
* to see if it fails. */
|
||||||
if (eth_open_cached(ifname) == NULL)
|
netutil_eth_t *ethsd = NULL;
|
||||||
fatal("dnet: failed to open device %s", ifname);
|
|
||||||
this->rawsd = -1;
|
/* Obtain raw socket or check that we can obtain an eth descriptor. */
|
||||||
} else {
|
if (!raw_socket_or_eth(o.sendpref, ifname, &this->rawsd, ðsd)) {
|
||||||
#ifdef WIN32
|
fatal("Couldn't obtain raw socket or eth handle in %s", __func__);
|
||||||
win32_fatal_raw_sockets(ifname);
|
|
||||||
#endif
|
|
||||||
if (this->rawsd >= 0)
|
|
||||||
close(this->rawsd);
|
|
||||||
rawsd = nmap_raw_socket();
|
|
||||||
if (rawsd < 0)
|
|
||||||
pfatal("Couldn't obtain raw socket in %s", __func__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* De-register existing callers */
|
/* De-register existing callers */
|
||||||
@@ -1135,7 +1122,7 @@ int FPEngine6::os_scan(std::vector<Target *> &Targets) {
|
|||||||
|
|
||||||
/* Initialize variables, timers, etc. */
|
/* Initialize variables, timers, etc. */
|
||||||
gettimeofday(&begin_time, NULL);
|
gettimeofday(&begin_time, NULL);
|
||||||
global_netctl.init(Targets[0]->deviceName(), Targets[0]->ifType());
|
global_netctl.init(Targets[0]->deviceName());
|
||||||
for (size_t i = 0; i < Targets.size(); i++) {
|
for (size_t i = 0; i < Targets.size(); i++) {
|
||||||
if (o.debugging > 3) {
|
if (o.debugging > 3) {
|
||||||
log_write(LOG_PLAIN, "[FPEngine] Allocating FPHost6 for %s %s\n",
|
log_write(LOG_PLAIN, "[FPEngine] Allocating FPHost6 for %s %s\n",
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ class FPNetworkControl {
|
|||||||
public:
|
public:
|
||||||
FPNetworkControl();
|
FPNetworkControl();
|
||||||
~FPNetworkControl();
|
~FPNetworkControl();
|
||||||
void init(const char *ifname, devtype iftype);
|
void init(const char *ifname);
|
||||||
int register_caller(FPHost *newcaller);
|
int register_caller(FPHost *newcaller);
|
||||||
int unregister_caller(FPHost *oldcaller);
|
int unregister_caller(FPHost *oldcaller);
|
||||||
int setup_sniffer(const char *iface, const char *bfp_filter);
|
int setup_sniffer(const char *iface, const char *bfp_filter);
|
||||||
|
|||||||
@@ -68,6 +68,7 @@
|
|||||||
#include "NmapOps.h"
|
#include "NmapOps.h"
|
||||||
#include "osscan.h"
|
#include "osscan.h"
|
||||||
#include "nmap_error.h"
|
#include "nmap_error.h"
|
||||||
|
#include "libnetutil/netutil.h"
|
||||||
|
|
||||||
NmapOps o;
|
NmapOps o;
|
||||||
|
|
||||||
|
|||||||
18
NmapOps.h
18
NmapOps.h
@@ -123,24 +123,6 @@ class NmapOps {
|
|||||||
u8 debugging;
|
u8 debugging;
|
||||||
bool resuming;
|
bool resuming;
|
||||||
|
|
||||||
#define PACKET_SEND_NOPREF 1
|
|
||||||
#define PACKET_SEND_ETH_WEAK 2
|
|
||||||
#define PACKET_SEND_ETH_STRONG 4
|
|
||||||
#define PACKET_SEND_ETH 6
|
|
||||||
#define PACKET_SEND_IP_WEAK 8
|
|
||||||
#define PACKET_SEND_IP_STRONG 16
|
|
||||||
#define PACKET_SEND_IP 24
|
|
||||||
|
|
||||||
/* How should we send raw IP packets? Nmap can generally use either
|
|
||||||
ethernet or raw ip sockets. Which is better depends on platform
|
|
||||||
and goals. A _STRONG preference means that Nmap should use the
|
|
||||||
preferred method whenever it is possible (obviously it isn't
|
|
||||||
always possible -- sending ethernet frames won't work over a PPP
|
|
||||||
connection). This is useful when the other type doesn't work at
|
|
||||||
all. A _WEAK preference means that Nmap may use the other type
|
|
||||||
where it is substantially more efficient to do so. For example,
|
|
||||||
Nmap will still do an ARP ping scan of a local network even when
|
|
||||||
the pref is SEND_IP_WEAK */
|
|
||||||
int sendpref;
|
int sendpref;
|
||||||
bool packetTrace() { return (debugging >= 3)? true : pTrace; }
|
bool packetTrace() { return (debugging >= 3)? true : pTrace; }
|
||||||
bool versionTrace() { return packetTrace()? true : vTrace; }
|
bool versionTrace() { return packetTrace()? true : vTrace; }
|
||||||
|
|||||||
25
idle_scan.cc
25
idle_scan.cc
@@ -599,30 +599,19 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
|
|||||||
|
|
||||||
/* Now lets send some probes to check IP ID algorithm ... */
|
/* Now lets send some probes to check IP ID algorithm ... */
|
||||||
/* First we need a raw socket ... */
|
/* First we need a raw socket ... */
|
||||||
if ((o.sendpref & PACKET_SEND_ETH) && (proxy->host.ifType() == devt_ethernet
|
if (!raw_socket_or_eth(o.sendpref, proxy->host.deviceName(),
|
||||||
#ifdef WIN32
|
&proxy->rawsd, &proxy->eth.ethsd)) {
|
||||||
|| (o.have_pcap && proxy->host.ifType() == devt_loopback)
|
fatal("%s: Failed to open raw socket or ethernet handle", __func__);
|
||||||
#endif
|
}
|
||||||
)) {
|
if (proxy->eth.ethsd != NULL) {
|
||||||
if (!setTargetNextHopMAC(&proxy->host))
|
if (!setTargetNextHopMAC(&proxy->host))
|
||||||
fatal("%s: Failed to determine dst MAC address for Idle proxy", __func__);
|
fatal("%s: Failed to determine dst MAC address for Idle proxy", __func__);
|
||||||
memcpy(proxy->eth.srcmac, proxy->host.SrcMACAddress(), 6);
|
memcpy(proxy->eth.srcmac, proxy->host.SrcMACAddress(), 6);
|
||||||
memcpy(proxy->eth.dstmac, proxy->host.NextHopMACAddress(), 6);
|
memcpy(proxy->eth.dstmac, proxy->host.NextHopMACAddress(), 6);
|
||||||
proxy->eth.ethsd = eth_open_cached(proxy->host.deviceName());
|
|
||||||
if (proxy->eth.ethsd == NULL)
|
|
||||||
fatal("%s: Failed to open ethernet device (%s)", __func__, proxy->host.deviceName());
|
|
||||||
proxy->rawsd = -1;
|
|
||||||
proxy->ethptr = &proxy->eth;
|
proxy->ethptr = &proxy->eth;
|
||||||
} else {
|
}
|
||||||
#ifdef WIN32
|
else {
|
||||||
win32_fatal_raw_sockets(proxy->host.deviceName());
|
|
||||||
#endif
|
|
||||||
proxy->rawsd = nmap_raw_socket();
|
|
||||||
if (proxy->rawsd < 0)
|
|
||||||
pfatal("socket troubles in %s", __func__);
|
|
||||||
unblock_socket(proxy->rawsd);
|
unblock_socket(proxy->rawsd);
|
||||||
proxy->eth.ethsd = NULL;
|
|
||||||
proxy->ethptr = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proxy->host.af() == AF_INET6)
|
if (proxy->host.af() == AF_INET6)
|
||||||
|
|||||||
@@ -1088,6 +1088,98 @@ void eth_close_cached() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void netutil_perror(const char *msg) {
|
||||||
|
int err = socket_errno();
|
||||||
|
netutil_error("%s: (%d) %s", msg, err, socket_strerror(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a raw socket and do things that always apply to raw sockets:
|
||||||
|
* Set SO_BROADCAST.
|
||||||
|
* Set IP_HDRINCL.
|
||||||
|
* Bind to an interface with SO_BINDTODEVICE (if device is not NULL).
|
||||||
|
The socket is created with address family AF_INET, but may be usable for
|
||||||
|
AF_INET6, depending on the operating system. */
|
||||||
|
int netutil_raw_socket(const char *device) {
|
||||||
|
#ifdef WIN32
|
||||||
|
netutil_error("Windows does not have adequate raw socket support.");
|
||||||
|
return -1;
|
||||||
|
#else
|
||||||
|
int rawsd;
|
||||||
|
int one = 1;
|
||||||
|
|
||||||
|
rawsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
|
||||||
|
if (rawsd < 0) {
|
||||||
|
netutil_perror("Couldn't open a raw socket. "
|
||||||
|
#if defined(sun) && defined(__SVR4)
|
||||||
|
"In Solaris shared-IP non-global zones, this requires the PRIV_NET_RAWACCESS privilege. "
|
||||||
|
#endif
|
||||||
|
"Error");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (setsockopt (rawsd, SOL_SOCKET, SO_BROADCAST, (const char *) &one, sizeof(int)) != 0) {
|
||||||
|
netutil_perror("setsockopt(SO_BROADCAST) failed");
|
||||||
|
}
|
||||||
|
sethdrinclude(rawsd);
|
||||||
|
socket_bindtodevice(rawsd, device);
|
||||||
|
|
||||||
|
return rawsd;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int raw_socket_or_eth(int sendpref, const char *ifname,
|
||||||
|
int *rawsd, netutil_eth_t **ethsd) {
|
||||||
|
assert(rawsd != NULL);
|
||||||
|
*rawsd = -1;
|
||||||
|
assert(ethsd != NULL);
|
||||||
|
*ethsd = NULL;
|
||||||
|
bool may_try_eth = ifname && !(sendpref & PACKET_SEND_IP_STRONG);
|
||||||
|
bool may_try_ip = !(sendpref & PACKET_SEND_ETH_STRONG);
|
||||||
|
bool try_eth = may_try_eth && (sendpref & PACKET_SEND_ETH);
|
||||||
|
bool try_ip = may_try_ip && (sendpref & PACKET_SEND_IP);
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
if (try_eth) {
|
||||||
|
try_eth = false;
|
||||||
|
may_try_eth = false;
|
||||||
|
try_ip = may_try_ip;
|
||||||
|
|
||||||
|
netutil_eth_t *e = eth_open_cached(ifname);
|
||||||
|
*ethsd = e;
|
||||||
|
if (e == NULL) {
|
||||||
|
netutil_error("dnet: failed to open device %s", ifname);
|
||||||
|
}
|
||||||
|
else if (!netutil_eth_can_send(e)) {
|
||||||
|
netutil_error("%s is not a supported device for sending.", ifname);
|
||||||
|
e = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (try_ip) {
|
||||||
|
try_ip = false;
|
||||||
|
may_try_ip = false;
|
||||||
|
try_eth = may_try_eth;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
/* For Windows, don't even bother trying unless the caller insists, to
|
||||||
|
* avoid excessive error messages. */
|
||||||
|
if (!(sendpref & PACKET_SEND_IP_STRONG)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
int sd = netutil_raw_socket(ifname);
|
||||||
|
*rawsd = sd;
|
||||||
|
if (sd >= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*ethsd != NULL || *rawsd >= 0) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Takes a protocol number like IPPROTO_TCP, IPPROTO_UDP, IPPROTO_IP,
|
/* Takes a protocol number like IPPROTO_TCP, IPPROTO_UDP, IPPROTO_IP,
|
||||||
* etc, and returns an ASCII representation (or the string "unknown" if
|
* etc, and returns an ASCII representation (or the string "unknown" if
|
||||||
* it doesn't recognize the number). If uppercase is non zero, the
|
* it doesn't recognize the number). If uppercase is non zero, the
|
||||||
|
|||||||
@@ -305,6 +305,34 @@ int netutil_eth_can_send(const netutil_eth_t *e);
|
|||||||
/* See the description for eth_open_cached */
|
/* See the description for eth_open_cached */
|
||||||
void eth_close_cached();
|
void eth_close_cached();
|
||||||
|
|
||||||
|
/* Create a raw socket and do things that always apply to raw sockets:
|
||||||
|
* Set SO_BROADCAST.
|
||||||
|
* Set IP_HDRINCL.
|
||||||
|
* Bind to an interface with SO_BINDTODEVICE (if device is not NULL).
|
||||||
|
The socket is created with address family AF_INET, but may be usable for
|
||||||
|
AF_INET6, depending on the operating system. */
|
||||||
|
int netutil_raw_socket(const char *device);
|
||||||
|
|
||||||
|
/* How should we send raw IP packets? Nmap can generally use either
|
||||||
|
ethernet or raw ip sockets. Which is better depends on platform
|
||||||
|
and goals. A _STRONG preference means that Nmap should use the
|
||||||
|
preferred method whenever it is possible (obviously it isn't
|
||||||
|
always possible -- sending ethernet frames won't work over a PPP
|
||||||
|
connection). This is useful when the other type doesn't work at
|
||||||
|
all. A _WEAK preference means that Nmap may use the other type
|
||||||
|
where it is substantially more efficient to do so. For example,
|
||||||
|
Nmap will still do an ARP ping scan of a local network even when
|
||||||
|
the pref is SEND_IP_WEAK */
|
||||||
|
#define PACKET_SEND_NOPREF 0x01
|
||||||
|
#define PACKET_SEND_ETH_WEAK 0x02
|
||||||
|
#define PACKET_SEND_ETH_STRONG 0x04
|
||||||
|
#define PACKET_SEND_ETH (PACKET_SEND_ETH_WEAK | PACKET_SEND_ETH_STRONG)
|
||||||
|
#define PACKET_SEND_IP_WEAK 0x08
|
||||||
|
#define PACKET_SEND_IP_STRONG 0x10
|
||||||
|
#define PACKET_SEND_IP (PACKET_SEND_IP_WEAK | PACKET_SEND_IP_STRONG)
|
||||||
|
int raw_socket_or_eth(int sendpref, const char *ifname,
|
||||||
|
int *rawsd, netutil_eth_t **ethsd);
|
||||||
|
|
||||||
/* Takes a protocol number like IPPROTO_TCP, IPPROTO_UDP, or
|
/* Takes a protocol number like IPPROTO_TCP, IPPROTO_UDP, or
|
||||||
* IPPROTO_IP and returns a ascii representation (or "unknown" if it
|
* IPPROTO_IP and returns a ascii representation (or "unknown" if it
|
||||||
* doesn't recognize the number). Returned string is in lowercase. */
|
* doesn't recognize the number). Returned string is in lowercase. */
|
||||||
|
|||||||
@@ -105,7 +105,6 @@ NpingOps::NpingOps() {
|
|||||||
sendpref_set=false;
|
sendpref_set=false;
|
||||||
|
|
||||||
send_eth=false;
|
send_eth=false;
|
||||||
send_eth_set=false;
|
|
||||||
|
|
||||||
delay=0;
|
delay=0;
|
||||||
delay_set=false;
|
delay_set=false;
|
||||||
@@ -620,10 +619,10 @@ bool NpingOps::issetPacketCount(){
|
|||||||
* PACKET_SEND_ETH, PACKET_SEND_IP_WEAK, PACKET_SEND_IP_STRONG, PACKET_SEND_IP
|
* PACKET_SEND_ETH, PACKET_SEND_IP_WEAK, PACKET_SEND_IP_STRONG, PACKET_SEND_IP
|
||||||
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
|
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
|
||||||
int NpingOps::setSendPreference(int v){
|
int NpingOps::setSendPreference(int v){
|
||||||
if( v!=PACKET_SEND_NOPREF && v!=PACKET_SEND_ETH_WEAK &&
|
// Validate: no extra bits set
|
||||||
v!=PACKET_SEND_ETH_STRONG && v!=PACKET_SEND_ETH &&
|
if( (v & ~(PACKET_SEND_ETH | PACKET_SEND_IP))
|
||||||
v!=PACKET_SEND_IP_WEAK && v!=PACKET_SEND_IP_STRONG &&
|
// Validate: both ETH and IP cannot be STRONG
|
||||||
v!=PACKET_SEND_IP ){
|
|| ((v & PACKET_SEND_ETH_STRONG) && (v & PACKET_SEND_IP_STRONG))) {
|
||||||
nping_fatal(QT_3,"setSendPreference(): Invalid value supplied\n");
|
nping_fatal(QT_3,"setSendPreference(): Invalid value supplied\n");
|
||||||
return OP_FAILURE;
|
return OP_FAILURE;
|
||||||
}else{
|
}else{
|
||||||
@@ -648,51 +647,31 @@ bool NpingOps::issetSendPreference(){
|
|||||||
|
|
||||||
/* Returns true if send preference is Ethernet */
|
/* Returns true if send preference is Ethernet */
|
||||||
bool NpingOps::sendPreferenceEthernet(){
|
bool NpingOps::sendPreferenceEthernet(){
|
||||||
if ( this->getSendPreference()==PACKET_SEND_ETH_WEAK )
|
return (this->sendpref & PACKET_SEND_ETH);
|
||||||
return true;
|
|
||||||
else if (this->getSendPreference()==PACKET_SEND_ETH_STRONG)
|
|
||||||
return true;
|
|
||||||
else if (this->getSendPreference()==PACKET_SEND_ETH )
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
} /* End of sendPreferenceEthernet() */
|
} /* End of sendPreferenceEthernet() */
|
||||||
|
|
||||||
|
|
||||||
/* Returns true if send preference is Ethernet */
|
/* Returns true if send preference is Ethernet */
|
||||||
bool NpingOps::sendPreferenceIP(){
|
bool NpingOps::sendPreferenceIP(){
|
||||||
if ( this->getSendPreference()==PACKET_SEND_IP_WEAK )
|
return (this->sendpref & PACKET_SEND_IP);
|
||||||
return true;
|
|
||||||
else if (this->getSendPreference()==PACKET_SEND_IP_STRONG)
|
|
||||||
return true;
|
|
||||||
else if (this->getSendPreference()==PACKET_SEND_IP )
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
} /* End of sendPreferenceIP() */
|
} /* End of sendPreferenceIP() */
|
||||||
|
|
||||||
|
|
||||||
/** Sets SendEth.
|
/** Sets SendEth.
|
||||||
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
|
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
|
||||||
int NpingOps::setSendEth(bool val){
|
int NpingOps::setSendEth(bool val){
|
||||||
this->send_eth=val;
|
this->sendpref = PACKET_SEND_ETH;
|
||||||
this->send_eth_set=true;
|
this->sendpref_set = true;
|
||||||
return OP_SUCCESS;
|
return OP_SUCCESS;
|
||||||
} /* End of setSendEth() */
|
} /* End of setSendEth() */
|
||||||
|
|
||||||
|
|
||||||
/** Returns value of attribute send_eth */
|
/** Returns value of attribute send_eth */
|
||||||
bool NpingOps::sendEth(){
|
bool NpingOps::sendEth(){
|
||||||
return this->send_eth;
|
return (this->sendpref & PACKET_SEND_ETH_STRONG);
|
||||||
} /* End of getSendEth() */
|
} /* End of getSendEth() */
|
||||||
|
|
||||||
|
|
||||||
/* Returns true if option has been set */
|
|
||||||
bool NpingOps::issetSendEth(){
|
|
||||||
return this->send_eth_set;
|
|
||||||
} /* End of issetSendEth() */
|
|
||||||
|
|
||||||
|
|
||||||
/** Sets inter-probe delay. Supplied parameter is assumed to be in milliseconds
|
/** Sets inter-probe delay. Supplied parameter is assumed to be in milliseconds
|
||||||
* and must be a long integer greater than zero.
|
* and must be a long integer greater than zero.
|
||||||
* @warning timeout is assumed to be in milliseconds. Use tval2msecs() from
|
* @warning timeout is assumed to be in milliseconds. Use tval2msecs() from
|
||||||
|
|||||||
@@ -97,14 +97,6 @@
|
|||||||
#define FLAG_SYN 6
|
#define FLAG_SYN 6
|
||||||
#define FLAG_FIN 7
|
#define FLAG_FIN 7
|
||||||
|
|
||||||
#define PACKET_SEND_NOPREF 1 /* These have been taken from NmapOps.h */
|
|
||||||
#define PACKET_SEND_ETH_WEAK 2
|
|
||||||
#define PACKET_SEND_ETH_STRONG 4
|
|
||||||
#define PACKET_SEND_ETH 6
|
|
||||||
#define PACKET_SEND_IP_WEAK 8
|
|
||||||
#define PACKET_SEND_IP_STRONG 16
|
|
||||||
#define PACKET_SEND_IP 24
|
|
||||||
|
|
||||||
#define IP_VERSION_4 0x04
|
#define IP_VERSION_4 0x04
|
||||||
#define IP_VERSION_6 0x06
|
#define IP_VERSION_6 0x06
|
||||||
|
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ static int ethernet_send (lua_State *L)
|
|||||||
static int ip_open (lua_State *L)
|
static int ip_open (lua_State *L)
|
||||||
{
|
{
|
||||||
nse_dnet_udata *udata = (nse_dnet_udata *) nseU_checkudata(L, 1, DNET_METATABLE, "dnet");
|
nse_dnet_udata *udata = (nse_dnet_udata *) nseU_checkudata(L, 1, DNET_METATABLE, "dnet");
|
||||||
udata->sock = nmap_raw_socket();
|
udata->sock = netutil_raw_socket(NULL);
|
||||||
if (udata->sock == -1) {
|
if (udata->sock == -1) {
|
||||||
if (o.scriptTrace())
|
if (o.scriptTrace())
|
||||||
{
|
{
|
||||||
|
|||||||
21
osscan2.cc
21
osscan2.cc
@@ -1336,24 +1336,11 @@ HostOsScan::HostOsScan(Target *t) {
|
|||||||
rawsd = -1;
|
rawsd = -1;
|
||||||
ethsd = NULL;
|
ethsd = NULL;
|
||||||
|
|
||||||
if ((o.sendpref & PACKET_SEND_ETH) && (t->ifType() == devt_ethernet
|
if (!raw_socket_or_eth(o.sendpref, t->deviceName(), &rawsd, ðsd)) {
|
||||||
#ifdef WIN32
|
fatal("%s: Failed to open raw socket or ethernet device", __func__);
|
||||||
|| (o.have_pcap && t->ifType() == devt_loopback)
|
|
||||||
#endif
|
|
||||||
)) {
|
|
||||||
if ((ethsd = eth_open_cached(t->deviceName())) == NULL)
|
|
||||||
fatal("%s: Failed to open ethernet device (%s)", __func__, t->deviceName());
|
|
||||||
rawsd = -1;
|
|
||||||
} else {
|
|
||||||
#ifdef WIN32
|
|
||||||
win32_fatal_raw_sockets(t->deviceName());
|
|
||||||
#endif
|
|
||||||
rawsd = nmap_raw_socket();
|
|
||||||
if (rawsd < 0)
|
|
||||||
pfatal("socket troubles in %s", __func__);
|
|
||||||
unblock_socket(rawsd);
|
|
||||||
ethsd = NULL;
|
|
||||||
}
|
}
|
||||||
|
if (rawsd >= 0)
|
||||||
|
unblock_socket(rawsd);
|
||||||
|
|
||||||
if (o.magic_port_set) {
|
if (o.magic_port_set) {
|
||||||
tcpPortBase = o.magic_port;
|
tcpPortBase = o.magic_port;
|
||||||
|
|||||||
16
output.cc
16
output.cc
@@ -218,22 +218,6 @@ static void print_xml_service(const struct serviceDeductions *sd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
/* Show a fatal error explaining that an interface is not Ethernet and won't
|
|
||||||
work on Windows. Do nothing if --send-ip (PACKET_SEND_IP_STRONG) was used. */
|
|
||||||
void win32_fatal_raw_sockets(const char *devname) {
|
|
||||||
if ((o.sendpref & PACKET_SEND_IP_STRONG) != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (devname != NULL) {
|
|
||||||
fatal("Only ethernet devices can be used for raw scans on Windows, and\n"
|
|
||||||
"\"%s\" is not an ethernet device. Use the --unprivileged option\n"
|
|
||||||
"for this scan.", devname);
|
|
||||||
} else {
|
|
||||||
fatal("Only ethernet devices can be used for raw scans on Windows. Use\n"
|
|
||||||
"the --unprivileged option for this scan.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Display the mapping from libdnet interface names (like "eth0") to Npcap
|
/* Display the mapping from libdnet interface names (like "eth0") to Npcap
|
||||||
interface names (like "\Device\NPF_{...}"). This is the same mapping used by
|
interface names (like "\Device\NPF_{...}"). This is the same mapping used by
|
||||||
eth_open and so can help diagnose connection problems. Additionally display
|
eth_open and so can help diagnose connection problems. Additionally display
|
||||||
|
|||||||
6
output.h
6
output.h
@@ -123,12 +123,6 @@ class Target;
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
/* Show a fatal error explaining that an interface is not Ethernet and won't
|
|
||||||
work on Windows. Do nothing if --send-ip (PACKET_SEND_IP_STRONG) was used. */
|
|
||||||
void win32_fatal_raw_sockets(const char *devname);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Prints the familiar Nmap tabular output showing the "interesting"
|
/* Prints the familiar Nmap tabular output showing the "interesting"
|
||||||
ports found on the machine. It also handles the Machine/Grepable
|
ports found on the machine. It also handles the Machine/Grepable
|
||||||
output and the XML output. It is pretty ugly -- in particular I
|
output and the XML output. It is pretty ugly -- in particular I
|
||||||
|
|||||||
@@ -949,39 +949,15 @@ void UltraScanInfo::Init(std::vector<Target *> &Targets, const struct scan_lists
|
|||||||
aren't doing a TCP connect scan, or if we're doing a ping scan that
|
aren't doing a TCP connect scan, or if we're doing a ping scan that
|
||||||
requires it. */
|
requires it. */
|
||||||
if (isRawScan()) {
|
if (isRawScan()) {
|
||||||
const char *device = Targets[0]->deviceName();
|
|
||||||
if (ping_scan_arp || (ping_scan_nd && o.sendpref != PACKET_SEND_IP_STRONG) || (o.sendpref & PACKET_SEND_ETH)) {
|
|
||||||
/* We'll send ethernet packets with dnet */
|
|
||||||
ethsd = eth_open_cached(device);
|
|
||||||
if (ethsd == NULL) {
|
|
||||||
error("dnet: Failed to open device %s", device);
|
|
||||||
}
|
|
||||||
else if (!netutil_eth_can_send(ethsd)) {
|
|
||||||
ethsd = NULL;
|
|
||||||
}
|
|
||||||
/* If eth failed, we can fall back to raw socket. The only exception is
|
/* If eth failed, we can fall back to raw socket. The only exception is
|
||||||
* ARP ping, which needs Ethernet link. */
|
* ARP ping, which needs Ethernet link. */
|
||||||
if (ping_scan_arp && (ethsd == NULL || netutil_eth_datalink(ethsd) != DLT_EN10MB)) {
|
int sendpref = o.sendpref;
|
||||||
fatal("ARP ping not supported on %s", device);
|
if (ping_scan_arp) {
|
||||||
|
assert(!(sendpref & PACKET_SEND_IP_STRONG));
|
||||||
|
sendpref = PACKET_SEND_ETH;
|
||||||
}
|
}
|
||||||
}
|
if (!raw_socket_or_eth(sendpref, Targets[0]->deviceName(), &rawsd, ðsd)) {
|
||||||
if (ethsd == NULL) {
|
fatal("Couldn't open a raw socket or eth handle.");
|
||||||
#ifdef WIN32
|
|
||||||
win32_fatal_raw_sockets(Targets[0]->deviceName());
|
|
||||||
#endif
|
|
||||||
rawsd = nmap_raw_socket();
|
|
||||||
if (rawsd < 0)
|
|
||||||
pfatal("Couldn't open a raw socket. "
|
|
||||||
#if defined(sun) && defined(__SVR4)
|
|
||||||
"In Solaris shared-IP non-global zones, this requires the PRIV_NET_RAWACCESS privilege. "
|
|
||||||
#endif
|
|
||||||
"Error"
|
|
||||||
);
|
|
||||||
/* We do not want to unblock the socket since we want to wait
|
|
||||||
if kernel send buffers fill up rather than get ENOBUF, and
|
|
||||||
we won't be receiving on the socket anyway
|
|
||||||
unblock_socket(rawsd);*/
|
|
||||||
ethsd = NULL;
|
|
||||||
}
|
}
|
||||||
/* Raw scan types also need to know the source IP. */
|
/* Raw scan types also need to know the source IP. */
|
||||||
Targets[0]->SourceSockAddr(&sourceSockAddr, NULL);
|
Targets[0]->SourceSockAddr(&sourceSockAddr, NULL);
|
||||||
|
|||||||
25
tcpip.cc
25
tcpip.cc
@@ -87,31 +87,6 @@ extern NmapOps o;
|
|||||||
|
|
||||||
static PacketCounter PktCt;
|
static PacketCounter PktCt;
|
||||||
|
|
||||||
/* Create a raw socket and do things that always apply to raw sockets:
|
|
||||||
* Set SO_BROADCAST.
|
|
||||||
* Set IP_HDRINCL.
|
|
||||||
* Bind to an interface with SO_BINDTODEVICE (if o.device is set).
|
|
||||||
The socket is created with address family AF_INET, but may be usable for
|
|
||||||
AF_INET6, depending on the operating system. */
|
|
||||||
int nmap_raw_socket() {
|
|
||||||
int rawsd;
|
|
||||||
int one = 1;
|
|
||||||
|
|
||||||
rawsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
|
|
||||||
if (rawsd < 0)
|
|
||||||
return rawsd;
|
|
||||||
if (setsockopt (rawsd, SOL_SOCKET, SO_BROADCAST, (const char *) &one, sizeof(int)) != 0) {
|
|
||||||
error("Failed to secure socket broadcasting permission");
|
|
||||||
perror("setsockopt");
|
|
||||||
}
|
|
||||||
#ifndef WIN32
|
|
||||||
sethdrinclude(rawsd);
|
|
||||||
#endif
|
|
||||||
socket_bindtodevice(rawsd, o.device);
|
|
||||||
|
|
||||||
return rawsd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill buf (up to buflen -- truncate if necessary but always
|
/* Fill buf (up to buflen -- truncate if necessary but always
|
||||||
terminate) with a short representation of the packet stats.
|
terminate) with a short representation of the packet stats.
|
||||||
Returns buf. Aborts if there is a problem. */
|
Returns buf. Aborts if there is a problem. */
|
||||||
|
|||||||
@@ -837,19 +837,8 @@ TracerouteState::TracerouteState(std::vector<Target *> &targets) {
|
|||||||
|
|
||||||
assert(targets.size() > 0);
|
assert(targets.size() > 0);
|
||||||
|
|
||||||
if ((o.sendpref & PACKET_SEND_ETH) && targets[0]->ifType() == devt_ethernet) {
|
if (!raw_socket_or_eth(o.sendpref, targets[0]->deviceName(), &rawsd, ðsd)) {
|
||||||
ethsd = eth_open_cached(targets[0]->deviceName());
|
fatal("traceroute: socket troubles");
|
||||||
if (ethsd == NULL)
|
|
||||||
fatal("dnet: failed to open device %s", targets[0]->deviceName());
|
|
||||||
rawsd = -1;
|
|
||||||
} else {
|
|
||||||
#ifdef WIN32
|
|
||||||
win32_fatal_raw_sockets(targets[0]->deviceName());
|
|
||||||
#endif
|
|
||||||
rawsd = nmap_raw_socket();
|
|
||||||
if (rawsd < 0)
|
|
||||||
pfatal("traceroute: socket troubles");
|
|
||||||
ethsd = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assume that all the targets share the same device. */
|
/* Assume that all the targets share the same device. */
|
||||||
|
|||||||
Reference in New Issue
Block a user