Reuse raw socket for IPv6 when possible
Some checks failed
nmap multiplatform autobuilds / build (arm64, gcc, ubuntu-latest-gcc-arm64, ubuntu-latest) (push) Has been cancelled
nmap multiplatform autobuilds / build (clang, freebsd-15-clang, ubuntu-latest) (push) Has been cancelled
nmap multiplatform autobuilds / build (clang, macos-15-clang, macos-15) (push) Has been cancelled
nmap multiplatform autobuilds / build (clang, macos-26-clang, macos-26) (push) Has been cancelled
nmap multiplatform autobuilds / build (clang, netbsd-10-clang, ubuntu-latest) (push) Has been cancelled
nmap multiplatform autobuilds / build (clang, openbsd-7-clang, ubuntu-latest) (push) Has been cancelled
nmap multiplatform autobuilds / build (clang, solaris-11-clang, ubuntu-latest) (push) Has been cancelled
nmap multiplatform autobuilds / build (clang, ubuntu-latest-clang, ubuntu-latest) (push) Has been cancelled
nmap multiplatform autobuilds / build (egcc, openbsd-7-gcc, ubuntu-latest) (push) Has been cancelled
nmap multiplatform autobuilds / build (gcc, freebsd-15-gcc, ubuntu-latest) (push) Has been cancelled
nmap multiplatform autobuilds / build (gcc, netbsd-10-gcc, ubuntu-latest) (push) Has been cancelled
nmap multiplatform autobuilds / build (gcc, solaris-11-gcc, ubuntu-latest) (push) Has been cancelled
nmap multiplatform autobuilds / build (gcc, ubuntu-latest-gcc, ubuntu-latest) (push) Has been cancelled
nmap multiplatform autobuilds / build (msvc, windows-latest-msvc, windows-latest) (push) Has been cancelled

This commit is contained in:
dmiller 2026-06-16 17:32:12 +00:00
parent 63a39b7a90
commit 5767158030
9 changed files with 15 additions and 23 deletions

View file

@ -161,7 +161,7 @@ void FPNetworkControl::init(const char *ifname, devtype iftype) {
netutil_eth_t *ethsd = NULL;
/* Obtain raw socket or check that we can obtain an eth descriptor. */
if (!raw_socket_or_eth(o.sendpref, ifname, iftype, &this->rawsd, &ethsd)) {
if (!raw_socket_or_eth(o.sendpref, ifname, iftype, &this->rawsd, &ethsd, AF_INET6)) {
fatal("Couldn't obtain raw socket or eth handle in %s", __func__);
}

View file

@ -587,7 +587,7 @@ 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 (!raw_socket_or_eth(o.sendpref, proxy->host.deviceName(), proxy->host.ifType(),
&proxy->rawsd, &proxy->eth.ethsd)) {
&proxy->rawsd, &proxy->eth.ethsd, proxy->host.af())) {
fatal("%s: Failed to open raw socket or ethernet handle", __func__);
}
if (proxy->eth.ethsd != NULL) {

View file

@ -1236,7 +1236,7 @@ static void netutil_perror(const char *msg) {
* 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) {
int netutil_raw_socket(const char *device, int af) {
#ifdef WIN32
netutil_error("Windows does not have adequate raw socket support.");
return -1;
@ -1244,7 +1244,7 @@ int netutil_raw_socket(const char *device) {
int rawsd;
int one = 1;
rawsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
rawsd = socket(af, SOCK_RAW, IPPROTO_RAW);
if (rawsd < 0) {
netutil_perror("Couldn't open a raw socket. "
#if defined(sun) && defined(__SVR4)
@ -1266,7 +1266,7 @@ int netutil_raw_socket(const char *device) {
}
int raw_socket_or_eth(int sendpref, const char *ifname, devtype iftype,
int *rawsd, netutil_eth_t **ethsd) {
int *rawsd, netutil_eth_t **ethsd, int af) {
assert(rawsd != NULL);
*rawsd = -1;
assert(ethsd != NULL);
@ -1317,7 +1317,7 @@ int raw_socket_or_eth(int sendpref, const char *ifname, devtype iftype,
continue;
}
#endif
int sd = netutil_raw_socket(ifname);
int sd = netutil_raw_socket(ifname, af);
if (sd >= 0) {
*rawsd = sd;
break;
@ -2790,14 +2790,12 @@ int send_frag_ip_packet(int sd, const struct eth_nfo *eth,
/* Send an IPv6 packet over a raw socket, on platforms where IPPROTO_RAW implies
IP_HDRINCL-like behavior. */
static int send_ipv6_ipproto_raw(const struct sockaddr_in6 *dst,
static int send_ipv6_ipproto_raw(int sd, const struct sockaddr_in6 *dst,
const unsigned char *packet, unsigned int packetlen) {
int sd, n;
int n;
sd = -1;
n = -1;
sd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
if (sd == -1) {
perror("socket");
goto bail;
@ -2806,9 +2804,6 @@ static int send_ipv6_ipproto_raw(const struct sockaddr_in6 *dst,
n = Sendto(__func__, sd, packet, packetlen, 0, (struct sockaddr *) dst, sizeof(*dst));
bail:
if (sd != -1)
close(sd);
return n;
}
@ -2991,14 +2986,13 @@ bail:
#endif
/* For now, the sd argument is ignored. */
int send_ipv6_packet_eth_or_sd(int sd, const struct eth_nfo *eth,
const struct sockaddr_in6 *dst, const u8 *packet, unsigned int packetlen) {
if (eth != NULL) {
return send_ip_packet_eth(eth, packet, packetlen, AF_INET6);
} else {
#if HAVE_IPV6_IPPROTO_RAW
return send_ipv6_ipproto_raw(dst, packet, packetlen);
return send_ipv6_ipproto_raw(sd, dst, packet, packetlen);
#elif !WIN32
return send_ipv6_ip(dst, packet, packetlen);
#endif

View file

@ -318,7 +318,7 @@ void eth_close_cached();
* 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);
int netutil_raw_socket(const char *device, int af=AF_INET);
/* How should we send raw IP packets? Nmap can generally use either
ethernet or raw ip sockets. Which is better depends on platform
@ -338,7 +338,7 @@ int netutil_raw_socket(const char *device);
#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, devtype iftype,
int *rawsd, netutil_eth_t **ethsd);
int *rawsd, netutil_eth_t **ethsd, int af=AF_INET);
/* Takes a protocol number like IPPROTO_TCP, IPPROTO_UDP, or
* IPPROTO_IP and returns a ascii representation (or "unknown" if it

View file

@ -304,7 +304,7 @@ int ProbeMode::start(){
if( o.getMode()!=ARP && o.sendEth()==false ){
/* Get socket descriptor. No need for it in ARP since we send at eth level */
if ((rawipsd = netutil_raw_socket(o.getDevice())) < 0 )
if ((rawipsd = netutil_raw_socket(o.getDevice(), o.ipv6() ? AF_INET6 : AF_INET)) < 0 )
nping_fatal(QT_3,"Couldn't acquire raw socket. Are you root?");
}

View file

@ -1344,7 +1344,7 @@ HostOsScan::HostOsScan(Target *t) {
ethsd = NULL;
int sendpref = o.sendpref;
if (!raw_socket_or_eth(sendpref, t->deviceName(), t->ifType(), &rawsd, &ethsd)) {
if (!raw_socket_or_eth(sendpref, t->deviceName(), t->ifType(), &rawsd, &ethsd, AF_INET)) {
fatal("%s: Failed to open raw socket or ethernet device", __func__);
}
if (rawsd >= 0)

View file

@ -964,7 +964,7 @@ void UltraScanInfo::Init(std::vector<Target *> &Targets, const struct scan_lists
sendpref = PACKET_SEND_ETH_WEAK;
}
if (!raw_socket_or_eth(sendpref, Targets[0]->deviceName(), Targets[0]->ifType(),
&rawsd, &ethsd)) {
&rawsd, &ethsd, Targets[0]->af())) {
fatal("Couldn't open a raw socket or eth handle.");
}
/* Raw scan types also need to know the source IP. */

View file

@ -76,8 +76,6 @@ class Target;
#define INET_ADDRSTRLEN 16
#endif
int nmap_raw_socket();
/* Used for tracing all packets sent or received (eg the
--packet-trace option) */

View file

@ -833,7 +833,7 @@ TracerouteState::TracerouteState(std::vector<Target *> &targets) {
assert(targets.size() > 0);
if (!raw_socket_or_eth(o.sendpref, targets[0]->deviceName(), targets[0]->ifType(),
&rawsd, &ethsd)) {
&rawsd, &ethsd, targets[0]->af())) {
fatal("traceroute: socket troubles");
}