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:
31
FPEngine.cc
31
FPEngine.cc
@@ -118,7 +118,7 @@ FPNetworkControl::~FPNetworkControl() {
|
||||
|
||||
/* (Re)-Initialize object's state (default parameter setup and nsock
|
||||
* initialization). */
|
||||
void FPNetworkControl::init(const char *ifname, devtype iftype) {
|
||||
void FPNetworkControl::init(const char *ifname) {
|
||||
|
||||
/* Init congestion control parameters */
|
||||
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 */
|
||||
this->nsock_init = true;
|
||||
|
||||
/* We don't need to store the eth handle because FPProbes come with a
|
||||
* suitable one (FPProbes::getEthernet()), we just attempt to obtain one
|
||||
* to see if it fails. */
|
||||
netutil_eth_t *ethsd = NULL;
|
||||
|
||||
/* Obtain raw socket or check that we can obtain an eth descriptor. */
|
||||
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
|
||||
* to see if it fails. */
|
||||
if (eth_open_cached(ifname) == NULL)
|
||||
fatal("dnet: failed to open device %s", ifname);
|
||||
this->rawsd = -1;
|
||||
} else {
|
||||
#ifdef WIN32
|
||||
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__);
|
||||
if (!raw_socket_or_eth(o.sendpref, ifname, &this->rawsd, ðsd)) {
|
||||
fatal("Couldn't obtain raw socket or eth handle in %s", __func__);
|
||||
}
|
||||
|
||||
/* De-register existing callers */
|
||||
@@ -1135,7 +1122,7 @@ int FPEngine6::os_scan(std::vector<Target *> &Targets) {
|
||||
|
||||
/* Initialize variables, timers, etc. */
|
||||
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++) {
|
||||
if (o.debugging > 3) {
|
||||
log_write(LOG_PLAIN, "[FPEngine] Allocating FPHost6 for %s %s\n",
|
||||
|
||||
@@ -157,7 +157,7 @@ class FPNetworkControl {
|
||||
public:
|
||||
FPNetworkControl();
|
||||
~FPNetworkControl();
|
||||
void init(const char *ifname, devtype iftype);
|
||||
void init(const char *ifname);
|
||||
int register_caller(FPHost *newcaller);
|
||||
int unregister_caller(FPHost *oldcaller);
|
||||
int setup_sniffer(const char *iface, const char *bfp_filter);
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
#include "NmapOps.h"
|
||||
#include "osscan.h"
|
||||
#include "nmap_error.h"
|
||||
#include "libnetutil/netutil.h"
|
||||
|
||||
NmapOps o;
|
||||
|
||||
|
||||
18
NmapOps.h
18
NmapOps.h
@@ -123,24 +123,6 @@ class NmapOps {
|
||||
u8 debugging;
|
||||
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;
|
||||
bool packetTrace() { return (debugging >= 3)? true : pTrace; }
|
||||
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 ... */
|
||||
/* First we need a raw socket ... */
|
||||
if ((o.sendpref & PACKET_SEND_ETH) && (proxy->host.ifType() == devt_ethernet
|
||||
#ifdef WIN32
|
||||
|| (o.have_pcap && proxy->host.ifType() == devt_loopback)
|
||||
#endif
|
||||
)) {
|
||||
if (!raw_socket_or_eth(o.sendpref, proxy->host.deviceName(),
|
||||
&proxy->rawsd, &proxy->eth.ethsd)) {
|
||||
fatal("%s: Failed to open raw socket or ethernet handle", __func__);
|
||||
}
|
||||
if (proxy->eth.ethsd != NULL) {
|
||||
if (!setTargetNextHopMAC(&proxy->host))
|
||||
fatal("%s: Failed to determine dst MAC address for Idle proxy", __func__);
|
||||
memcpy(proxy->eth.srcmac, proxy->host.SrcMACAddress(), 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;
|
||||
} else {
|
||||
#ifdef WIN32
|
||||
win32_fatal_raw_sockets(proxy->host.deviceName());
|
||||
#endif
|
||||
proxy->rawsd = nmap_raw_socket();
|
||||
if (proxy->rawsd < 0)
|
||||
pfatal("socket troubles in %s", __func__);
|
||||
}
|
||||
else {
|
||||
unblock_socket(proxy->rawsd);
|
||||
proxy->eth.ethsd = NULL;
|
||||
proxy->ethptr = NULL;
|
||||
}
|
||||
|
||||
if (proxy->host.af() == AF_INET6)
|
||||
|
||||
@@ -1088,6 +1088,98 @@ void eth_close_cached() {
|
||||
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,
|
||||
* etc, and returns an ASCII representation (or the string "unknown" if
|
||||
* 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 */
|
||||
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
|
||||
* IPPROTO_IP and returns a ascii representation (or "unknown" if it
|
||||
* doesn't recognize the number). Returned string is in lowercase. */
|
||||
|
||||
@@ -105,7 +105,6 @@ NpingOps::NpingOps() {
|
||||
sendpref_set=false;
|
||||
|
||||
send_eth=false;
|
||||
send_eth_set=false;
|
||||
|
||||
delay=0;
|
||||
delay_set=false;
|
||||
@@ -620,10 +619,10 @@ bool NpingOps::issetPacketCount(){
|
||||
* 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. */
|
||||
int NpingOps::setSendPreference(int v){
|
||||
if( v!=PACKET_SEND_NOPREF && v!=PACKET_SEND_ETH_WEAK &&
|
||||
v!=PACKET_SEND_ETH_STRONG && v!=PACKET_SEND_ETH &&
|
||||
v!=PACKET_SEND_IP_WEAK && v!=PACKET_SEND_IP_STRONG &&
|
||||
v!=PACKET_SEND_IP ){
|
||||
// Validate: no extra bits set
|
||||
if( (v & ~(PACKET_SEND_ETH | PACKET_SEND_IP))
|
||||
// Validate: both ETH and IP cannot be STRONG
|
||||
|| ((v & PACKET_SEND_ETH_STRONG) && (v & PACKET_SEND_IP_STRONG))) {
|
||||
nping_fatal(QT_3,"setSendPreference(): Invalid value supplied\n");
|
||||
return OP_FAILURE;
|
||||
}else{
|
||||
@@ -648,51 +647,31 @@ bool NpingOps::issetSendPreference(){
|
||||
|
||||
/* Returns true if send preference is Ethernet */
|
||||
bool NpingOps::sendPreferenceEthernet(){
|
||||
if ( this->getSendPreference()==PACKET_SEND_ETH_WEAK )
|
||||
return true;
|
||||
else if (this->getSendPreference()==PACKET_SEND_ETH_STRONG)
|
||||
return true;
|
||||
else if (this->getSendPreference()==PACKET_SEND_ETH )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
return (this->sendpref & PACKET_SEND_ETH);
|
||||
} /* End of sendPreferenceEthernet() */
|
||||
|
||||
|
||||
/* Returns true if send preference is Ethernet */
|
||||
bool NpingOps::sendPreferenceIP(){
|
||||
if ( this->getSendPreference()==PACKET_SEND_IP_WEAK )
|
||||
return true;
|
||||
else if (this->getSendPreference()==PACKET_SEND_IP_STRONG)
|
||||
return true;
|
||||
else if (this->getSendPreference()==PACKET_SEND_IP )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
return (this->sendpref & PACKET_SEND_IP);
|
||||
} /* End of sendPreferenceIP() */
|
||||
|
||||
|
||||
/** Sets SendEth.
|
||||
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
|
||||
int NpingOps::setSendEth(bool val){
|
||||
this->send_eth=val;
|
||||
this->send_eth_set=true;
|
||||
this->sendpref = PACKET_SEND_ETH;
|
||||
this->sendpref_set = true;
|
||||
return OP_SUCCESS;
|
||||
} /* End of setSendEth() */
|
||||
|
||||
|
||||
/** Returns value of attribute send_eth */
|
||||
bool NpingOps::sendEth(){
|
||||
return this->send_eth;
|
||||
return (this->sendpref & PACKET_SEND_ETH_STRONG);
|
||||
} /* 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
|
||||
* and must be a long integer greater than zero.
|
||||
* @warning timeout is assumed to be in milliseconds. Use tval2msecs() from
|
||||
|
||||
@@ -97,14 +97,6 @@
|
||||
#define FLAG_SYN 6
|
||||
#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_6 0x06
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ static int ethernet_send (lua_State *L)
|
||||
static int ip_open (lua_State *L)
|
||||
{
|
||||
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 (o.scriptTrace())
|
||||
{
|
||||
|
||||
21
osscan2.cc
21
osscan2.cc
@@ -1336,24 +1336,11 @@ HostOsScan::HostOsScan(Target *t) {
|
||||
rawsd = -1;
|
||||
ethsd = NULL;
|
||||
|
||||
if ((o.sendpref & PACKET_SEND_ETH) && (t->ifType() == devt_ethernet
|
||||
#ifdef WIN32
|
||||
|| (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 (!raw_socket_or_eth(o.sendpref, t->deviceName(), &rawsd, ðsd)) {
|
||||
fatal("%s: Failed to open raw socket or ethernet device", __func__);
|
||||
}
|
||||
if (rawsd >= 0)
|
||||
unblock_socket(rawsd);
|
||||
|
||||
if (o.magic_port_set) {
|
||||
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
|
||||
/* 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
|
||||
interface names (like "\Device\NPF_{...}"). This is the same mapping used by
|
||||
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
|
||||
|
||||
#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"
|
||||
ports found on the machine. It also handles the Machine/Grepable
|
||||
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
|
||||
requires it. */
|
||||
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
|
||||
* ARP ping, which needs Ethernet link. */
|
||||
if (ping_scan_arp && (ethsd == NULL || netutil_eth_datalink(ethsd) != DLT_EN10MB)) {
|
||||
fatal("ARP ping not supported on %s", device);
|
||||
}
|
||||
/* If eth failed, we can fall back to raw socket. The only exception is
|
||||
* ARP ping, which needs Ethernet link. */
|
||||
int sendpref = o.sendpref;
|
||||
if (ping_scan_arp) {
|
||||
assert(!(sendpref & PACKET_SEND_IP_STRONG));
|
||||
sendpref = PACKET_SEND_ETH;
|
||||
}
|
||||
if (ethsd == NULL) {
|
||||
#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;
|
||||
if (!raw_socket_or_eth(sendpref, Targets[0]->deviceName(), &rawsd, ðsd)) {
|
||||
fatal("Couldn't open a raw socket or eth handle.");
|
||||
}
|
||||
/* Raw scan types also need to know the source IP. */
|
||||
Targets[0]->SourceSockAddr(&sourceSockAddr, NULL);
|
||||
|
||||
25
tcpip.cc
25
tcpip.cc
@@ -87,31 +87,6 @@ extern NmapOps o;
|
||||
|
||||
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
|
||||
terminate) with a short representation of the packet stats.
|
||||
Returns buf. Aborts if there is a problem. */
|
||||
|
||||
@@ -837,19 +837,8 @@ TracerouteState::TracerouteState(std::vector<Target *> &targets) {
|
||||
|
||||
assert(targets.size() > 0);
|
||||
|
||||
if ((o.sendpref & PACKET_SEND_ETH) && targets[0]->ifType() == devt_ethernet) {
|
||||
ethsd = eth_open_cached(targets[0]->deviceName());
|
||||
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;
|
||||
if (!raw_socket_or_eth(o.sendpref, targets[0]->deviceName(), &rawsd, ðsd)) {
|
||||
fatal("traceroute: socket troubles");
|
||||
}
|
||||
|
||||
/* Assume that all the targets share the same device. */
|
||||
|
||||
Reference in New Issue
Block a user