26 #include <arpa/inet.h>
27 #include <gvm/base/logging.h>
28 #include <gvm/base/networking.h>
32 #include <netinet/in.h>
37 #include <sys/ioctl.h>
38 #include <sys/param.h>
39 #include <sys/types.h>
42 #define MAXROUTES 1024
48 #define G_LOG_DOMAIN "lib misc"
83 ptr = (uint32_t *) in6addr;
87 ptr[1] = ptr[2] = ptr[3] = 0;
89 addr = ntohl (
addr) >> (32 - wordmask);
90 addr = htonl (
addr << (32 - wordmask));
96 addr = ntohl (
addr) >> (32 - wordmask);
97 addr = htonl (
addr << (32 - wordmask));
103 addr = ntohl (
addr) >> (32 - wordmask);
104 addr = htonl (
addr << (32 - wordmask));
109 addr = ntohl (
addr) >> (32 - wordmask);
110 addr = htonl (
addr << (32 - wordmask));
124 struct in6_addr in6addr;
129 if (IN6_IS_ADDR_V4MAPPED (addr))
131 for (i = 0; i < ifaces; i++)
133 bpf_u_int32 net, mask;
134 char errbuf[PCAP_ERRBUF_SIZE];
135 pcap_lookupnet (ifs[i].
name, &net, &mask, errbuf);
136 if ((net & mask) == (addr->s6_addr32[3] & mask))
142 if (IN6_IS_ADDR_LINKLOCAL (addr))
144 if (IN6_IS_ADDR_LOOPBACK (addr))
148 for (i = 0; i < numroutes; i++)
150 char addr1[INET6_ADDRSTRLEN];
151 char addr2[INET6_ADDRSTRLEN];
153 memcpy (&in6addr, addr,
sizeof (
struct in6_addr));
155 g_debug (
"comparing addresses %s and %s\n",
156 inet_ntop (AF_INET6, &in6addr, addr1,
sizeof (addr1)),
157 inet_ntop (AF_INET6, &myroutes[i].dest6, addr2,
159 if (IN6_ARE_ADDR_EQUAL (&in6addr, &myroutes[i].dest6))
183 for (i = 0; i < numdevs; i++)
185 char addr1[INET6_ADDRSTRLEN];
186 char addr2[INET6_ADDRSTRLEN];
187 g_debug (
"comparing addresses %s and %s\n",
188 inet_ntop (AF_INET6,
addr, addr1,
sizeof (addr1)),
189 inet_ntop (AF_INET6, &mydevs[i].
addr6, addr2,
sizeof (addr2)));
190 if (IN6_ARE_ADDR_EQUAL (
addr, &mydevs[i].
addr6))
193 strncpy (dev, mydevs[i].
name, sz);
214 for (i = 0; i < numdevs; i++)
216 if (
addr->s_addr == mydevs[i].
addr.s_addr)
219 strncpy (dev, mydevs[i].
name, sz);
238 if (IN6_IS_ADDR_V4MAPPED (
addr))
242 if ((
addr->s6_addr32[3] & htonl (0xFF000000)) == htonl (0x7F000000))
245 if (!
addr->s6_addr32[3])
249 if (IN6_IS_ADDR_LOOPBACK (
addr))
277 if ((
addr->s_addr & htonl (0xFF000000)) == htonl (0x7F000000))
310 #if (FREEBSD || OPENBSD || NETBSD || BSDI || DARWIN)
317 #if (FREEBSD || OPENBSD || NETBSD || BSDI || DARWIN)
337 struct sockaddr_in *saddr;
338 struct sockaddr_in6 *s6addr;
340 int numinterfaces = 0;
341 struct ifaddrs *ifaddr, *ifa;
344 if (getifaddrs (&ifaddr) == -1)
346 perror (
"getifaddrs");
350 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
352 if (ifa->ifa_addr == NULL)
355 family = ifa->ifa_addr->sa_family;
356 if (family == AF_INET)
358 strncpy (mydevs[numinterfaces].
name, ifa->ifa_name,
359 sizeof (mydevs[numinterfaces].
name) - 1);
360 saddr = (
struct sockaddr_in *) ifa->ifa_addr;
361 mydevs[numinterfaces].
addr6.s6_addr32[0] = 0;
362 mydevs[numinterfaces].
addr6.s6_addr32[1] = 0;
363 mydevs[numinterfaces].
addr6.s6_addr32[2] = htonl (0xffff);
364 mydevs[numinterfaces].
addr6.s6_addr32[3] = saddr->sin_addr.s_addr;
365 saddr = (
struct sockaddr_in *) ifa->ifa_netmask;
366 mydevs[numinterfaces].
mask.s6_addr32[0] = 0;
367 mydevs[numinterfaces].
mask.s6_addr32[1] = 0;
368 mydevs[numinterfaces].
mask.s6_addr32[2] = htonl (0xffff);
369 mydevs[numinterfaces].
mask.s6_addr32[3] = saddr->sin_addr.s_addr;
370 g_debug (
"interface name is %s\n", ifa->ifa_name);
371 g_debug (
"\tAF_INET family\n");
372 g_debug (
"\taddress is %s\n", inet_ntoa (saddr->sin_addr));
373 g_debug (
"\tnetmask is %s\n", inet_ntoa (saddr->sin_addr));
376 else if (family == AF_INET6)
378 char ipaddr[INET6_ADDRSTRLEN];
380 strncpy (mydevs[numinterfaces].
name, ifa->ifa_name,
381 sizeof (mydevs[numinterfaces].
name) - 1);
382 s6addr = (
struct sockaddr_in6 *) ifa->ifa_addr;
383 memcpy (&(mydevs[numinterfaces].addr6),
384 (
char *) &(s6addr->sin6_addr),
sizeof (
struct in6_addr));
385 s6addr = (
struct sockaddr_in6 *) ifa->ifa_netmask;
386 memcpy (&(mydevs[numinterfaces].mask),
387 (
char *) &(s6addr->sin6_addr),
sizeof (
struct in6_addr));
389 g_debug (
"\tAF_INET6 family\n");
390 g_debug (
"interface name is %s\n", ifa->ifa_name);
391 g_debug (
"\taddress is %s\n",
392 inet_ntop (AF_INET6, &s6addr->sin6_addr, ipaddr,
396 g_debug (
"\tfamily is %d\n", ifa->ifa_addr->sa_family);
398 *howmany = numinterfaces;
400 freeifaddrs (ifaddr);
413 int numinterfaces = 0;
420 struct sockaddr_in *sin;
424 sd = socket (AF_INET, SOCK_DGRAM, 0);
425 bzero (buf,
sizeof (buf));
428 g_message (
"socket in getinterfaces");
432 ifc.ifc_len =
sizeof (buf);
434 if (ioctl (sd, SIOCGIFCONF, &ifc) < 0)
435 g_message (
"Failed to determine your configured interfaces!");
438 if (ifc.ifc_len == 0)
440 "getinterfaces: SIOCGIFCONF claims you have no network interfaces!");
443 len =
sizeof (
struct ifmap);
445 len =
sizeof (
struct sockaddr);
448 for (bufp = buf; bufp && *bufp && (bufp < (buf + ifc.ifc_len));
449 bufp +=
sizeof (ifr->ifr_name) + len)
451 ifr = (
struct ifreq *) bufp;
452 sin = (
struct sockaddr_in *) &ifr->ifr_addr;
453 memcpy (&(mydevs[numinterfaces].addr), (
char *) &(sin->sin_addr),
454 sizeof (
struct in_addr));
456 if ((p = strchr (ifr->ifr_name,
':')))
458 strncpy (mydevs[numinterfaces].
name, ifr->ifr_name, 63);
459 mydevs[numinterfaces].
name[63] =
'\0';
461 if (numinterfaces == 1023)
463 g_message (
"You seem to have more than 1023 network interfaces."
464 " Things may not work right.");
467 mydevs[numinterfaces].
name[0] =
'\0';
472 *howmany = numinterfaces;
481 struct sockaddr_in sock;
482 unsigned int socklen;
485 p1 = (
unsigned short) rand ();
489 if (IN6_IS_ADDR_V4MAPPED (dst))
491 char name[INET6_ADDRSTRLEN];
493 if ((sd = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
495 perror (
"Socket troubles");
498 bzero (&sock,
sizeof (
struct sockaddr_in));
499 sock.sin_family = AF_INET;
500 sock.sin_addr.s_addr = dst->s6_addr32[3];
501 sock.sin_port = htons (p1);
502 if (connect (sd, (
struct sockaddr *) &sock,
sizeof (
struct sockaddr_in))
508 bzero (&sock,
sizeof (
struct sockaddr_in));
509 socklen =
sizeof (
struct sockaddr_in);
510 if (getsockname (sd, (
struct sockaddr *) &sock, &socklen) == -1)
512 perror (
"getsockname");
517 src->s6_addr32[0] = 0;
518 src->s6_addr32[1] = 0;
519 src->s6_addr32[2] = htonl (0xffff);
520 src->s6_addr32[3] = sock.sin_addr.s_addr;
521 g_debug (
"source address is %s\n",
522 inet_ntop (AF_INET6, src,
name,
sizeof (
name)));
527 struct sockaddr_in6 sock6;
528 char name[INET6_ADDRSTRLEN];
530 if ((sd = socket (AF_INET6, SOCK_DGRAM, 0)) == -1)
532 perror (
"Socket troubles");
535 bzero (&sock6,
sizeof (sock6));
536 sock6.sin6_family = AF_INET6;
537 sock6.sin6_addr.s6_addr32[0] = dst->s6_addr32[0];
538 sock6.sin6_addr.s6_addr32[1] = dst->s6_addr32[1];
539 sock6.sin6_addr.s6_addr32[2] = dst->s6_addr32[2];
540 sock6.sin6_addr.s6_addr32[3] = dst->s6_addr32[3];
541 sock6.sin6_port = htons (p1);
542 if (connect (sd, (
struct sockaddr *) &sock6,
sizeof (
struct sockaddr_in6))
548 bzero (&sock6,
sizeof (
struct sockaddr_in6));
549 socklen =
sizeof (
struct sockaddr_in6);
550 if (getsockname (sd, (
struct sockaddr *) &sock6, &socklen) == -1)
552 perror (
"getsockname");
557 src->s6_addr32[0] = sock6.sin6_addr.s6_addr32[0];
558 src->s6_addr32[1] = sock6.sin6_addr.s6_addr32[1];
559 src->s6_addr32[2] = sock6.sin6_addr.s6_addr32[2];
560 src->s6_addr32[3] = sock6.sin6_addr.s6_addr32[3];
561 memcpy (src, &sock6.sin6_addr, sizeof (
struct in6_addr));
562 g_debug (
"source addrss is %s\n",
563 inet_ntop (AF_INET6, src,
name,
sizeof (
name)));
580 struct in_addr inaddr;
588 routez = fopen (
"/proc/net/route",
"r");
594 if (fgets (buf,
sizeof (buf), routez) == NULL)
597 g_message (
"Could not read from /proc/net/route");
601 while (fgets (buf,
sizeof (buf), routez))
603 p = strtok (buf,
" \t\n");
606 g_message (
"Could not find interface in"
607 " /proc/net/route line");
610 strncpy (iface, p,
sizeof (iface));
611 if ((p = strchr (iface,
':')))
615 p = strtok (NULL,
" \t\n");
617 dest = strtoul (p, &endptr, 16);
618 g_debug (
"ipv4 dest is %s\n", p);
619 if (!endptr || *endptr)
621 g_message (
"Failed to determine Destination from"
625 inaddr.s_addr = dest;
626 myroutes[*numroutes].
dest6.s6_addr32[0] = 0;
627 myroutes[*numroutes].
dest6.s6_addr32[1] = 0;
628 myroutes[*numroutes].
dest6.s6_addr32[2] = htonl (0xffff);
629 myroutes[*numroutes].
dest6.s6_addr32[3] = inaddr.s_addr;
630 for (i = 0; i < 6; i++)
632 p = strtok (NULL,
" \t\n");
638 g_message (
"Failed to find field %d in"
644 mask = strtoul (p, &endptr, 16);
647 while (mask & (1 << i++) && i < 32)
649 myroutes[*numroutes].
mask = ones + 96;
650 g_debug (
"mask is %lu\n", myroutes[*numroutes].mask);
651 if (!endptr || *endptr)
653 g_message (
"Failed to determine mask from"
658 g_debug (
"#%d: for dev %s, The dest is %lX and the mask is %lX\n",
659 *numroutes, iface, myroutes[*numroutes].dest,
660 myroutes[*numroutes].mask);
661 for (i = 0; i < numinterfaces; i++)
662 if (!strcmp (iface, mydevs[i].
name))
664 myroutes[*numroutes].
dev = &mydevs[i];
667 if (i == numinterfaces)
669 "Failed to find interface %s mentioned in /proc/net/route",
674 g_message (
"You seem to have WAY to many routes!");
691 struct in6_addr in6addr;
697 char v6addr[INET6_ADDRSTRLEN];
703 routez = fopen (
"/proc/net/ipv6_route",
"r");
707 while (fgets (buf,
sizeof (buf), routez) != NULL)
711 token = strtok (buf,
" \t\n");
714 g_debug (
"first token is %s\n", token);
715 strncpy (destaddr, token,
sizeof (destaddr) - 1);
716 len = strlen (destaddr);
717 for (i = 0, j = 0; j < len; j++)
719 v6addr[i++] = destaddr[j];
724 g_debug (
"ipv6 dest is %s\n", v6addr);
725 if (inet_pton (AF_INET6, v6addr, &in6addr) <= 0)
727 g_message (
"invalid ipv6 addressd");
730 memcpy (&myroutes[*numroutes].dest6, &in6addr,
731 sizeof (
struct in6_addr));
733 token = strtok (NULL,
" \t\n");
737 myroutes[*numroutes].
mask = strtoul (token, &endptr, 16);
742 token = strtok (NULL,
" \t\n");
744 g_message (
"getipv6routes error");
747 bzero (iface,
sizeof (iface));
748 token = strtok (NULL,
" \t\n");
750 strncpy (iface, token,
sizeof (iface) - 1);
751 for (i = 0; i < numinterfaces; i++)
752 if (!strcmp (iface, mydevs[i].
name)
753 && !IN6_IS_ADDR_V4MAPPED (&mydevs[i].addr6))
755 myroutes[*numroutes].
dev = &mydevs[i];
758 if (i == numinterfaces)
760 "Failed to find interface %s mentioned in /proc/net/route\n",
765 g_message (
"You seem to have WAY to many routes!");
774 g_message (
"Didn't find IPv6 routes");
791 static int initialized = 0;
793 struct in6_addr addy;
796 connectsockettechnique,
798 } technique = procroutetechnique;
801 int numinterfaces = 0;
802 static int numroutes = 0;
803 struct in6_addr in6addr;
808 g_message (
"ipaddr2devname passed a NULL dest address");
812 if (IN6_IS_ADDR_V4MAPPED (dest))
813 gvm_source_addr_as_addr6 (&src);
815 gvm_source_addr6 (&src);
822 if (IN6_IS_ADDR_V4MAPPED (dest))
825 technique = connectsockettechnique;
830 technique = connectsockettechnique;
843 if (IN6_IS_ADDR_V4MAPPED (source))
845 source->s6_addr32[0] = 0;
846 source->s6_addr32[1] = 0;
847 source->s6_addr32[2] = htonl (0xffff);
848 source->s6_addr32[3] = htonl (0x7F000001);
852 source->s6_addr32[0] = 0;
853 source->s6_addr32[1] = 0;
854 source->s6_addr32[2] = 0;
855 source->s6_addr32[3] = htonl (1);
860 for (i = 0; i < numinterfaces; i++)
862 if (IN6_IS_ADDR_V4MAPPED (&mydevs[i].addr6))
864 if (mydevs[i].addr6.s6_addr32[3] == htonl (0x7F000001))
865 return mydevs[i].
name;
869 if (IN6_ARE_ADDR_EQUAL (&in6addr_any, &mydevs[i].addr6))
870 return mydevs[i].
name;
876 if (technique == procroutetechnique)
878 for (i = 0; i < numroutes; i++)
880 char addr1[INET6_ADDRSTRLEN];
881 char addr2[INET6_ADDRSTRLEN];
883 memcpy (&in6addr, dest,
sizeof (
struct in6_addr));
886 "comparing addresses %s and %s\n",
887 inet_ntop (AF_INET6, &in6addr, addr1,
sizeof (addr1)),
888 inet_ntop (AF_INET6, &myroutes[i].dest6, addr2,
sizeof (addr2)));
889 if (IN6_ARE_ADDR_EQUAL (&in6addr, &myroutes[i].dest6))
893 if (!IN6_ARE_ADDR_EQUAL (&src, &in6addr_any))
894 memcpy (source, &src,
sizeof (
struct in6_addr));
897 if (myroutes[i].dev != NULL)
899 g_debug (
"copying address %s\n",
900 inet_ntop (AF_INET6, &myroutes[i].dev->addr6,
901 addr1, sizeof (addr1)));
902 g_debug (
"dev name is %s\n", myroutes[i].dev->name);
903 memcpy (source, &myroutes[i].dev->addr6,
904 sizeof (
struct in6_addr));
910 technique = connectsockettechnique;
913 if (technique == connectsockettechnique)
917 if (IN6_ARE_ADDR_EQUAL (&addy, &in6addr))
919 struct hostent *myhostent = NULL;
920 char myname[MAXHOSTNAMELEN + 1];
922 myhostent = gethostbyname (myname);
923 if (gethostname (myname, MAXHOSTNAMELEN) || !myhostent)
924 g_message (
"Cannot get hostname!");
925 else if (myhostent->h_addrtype == AF_INET)
927 addy.s6_addr32[0] = 0;
928 addy.s6_addr32[1] = 0;
929 addy.s6_addr32[2] = htonl (0xffff);
930 memcpy (&addy.s6_addr32[0], myhostent->h_addr_list[0],
931 sizeof (
struct in6_addr));
934 memcpy (&addy, myhostent->h_addr_list[0], sizeof (
struct in6_addr));
938 for (i = 0; i < numinterfaces; i++)
940 char addr1[INET6_ADDRSTRLEN];
941 char addr2[INET6_ADDRSTRLEN];
944 "comparing addresses %s and %s\n",
945 inet_ntop (AF_INET6, &mydevs[i].addr6, addr1,
sizeof (addr1)),
946 inet_ntop (AF_INET6, &addy, addr2,
sizeof (addr2)));
947 if (IN6_ARE_ADDR_EQUAL (&mydevs[i].addr6, &addy))
951 memcpy (source, &addy,
sizeof (
struct in6_addr));
953 return mydevs[i].
name;
959 g_message (
"%s: Provided technique is neither proc route nor"
977 static int initialized = 0;
987 int numinterfaces = 0;
990 static int numroutes = 0;
993 unsigned long bestmatch = 0;
997 gvm_source_addr (&src);
1000 g_message (
"ipaddr2devname passed a NULL dest address");
1012 routez = fopen (
"/proc/net/route",
"r");
1017 if (fgets (buf,
sizeof (buf), routez)
1019 g_message (
"Could not read from /proc/net/route");
1020 while (fgets (buf,
sizeof (buf), routez))
1022 p = strtok (buf,
" \t\n");
1025 g_message (
"Could not find interface in"
1026 " /proc/net/route line");
1029 strncpy (iface, p,
sizeof (iface));
1030 if ((p = strchr (iface,
':')))
1034 p = strtok (NULL,
" \t\n");
1036 myroutes[numroutes].dest = strtoul (p, &endptr, 16);
1037 if (!endptr || *endptr)
1040 "Failed to determine Destination from /proc/net/route");
1043 for (i = 0; i < 6; i++)
1045 p = strtok (NULL,
" \t\n");
1051 g_message (
"Failed to find field %d in"
1057 myroutes[numroutes].mask = strtoul (p, &endptr, 16);
1058 if (!endptr || *endptr)
1060 g_message (
"Failed to determine mask"
1061 " from /proc/net/route");
1065 g_debug (
"#%d: for dev %s, The dest is %lX and the mask is %lX\n",
1066 numroutes, iface, myroutes[numroutes].dest,
1067 myroutes[numroutes].mask);
1068 for (i = 0; i < numinterfaces; i++)
1069 if (!strcmp (iface, mydevs[i].
name))
1071 myroutes[numroutes].dev = &mydevs[i];
1074 if (i == numinterfaces)
1076 "Failed to find interface %s mentioned in /proc/net/route",
1081 g_message (
"You seem to have WAY to many routes!");
1089 g_message (
"Could not read from /proc/net/route");
1100 source->s_addr = htonl (0x7F000001);
1103 for (i = 0; i < numinterfaces; i++)
1105 if (mydevs[i].addr.s_addr == htonl (0x7F000001))
1107 return mydevs[i].
name;
1113 for (i = 0; i < numroutes; i++)
1115 if ((dest->s_addr & myroutes[i].mask) == myroutes[i].dest
1116 && myroutes[i].mask >= bestmatch)
1120 if (src.s_addr != INADDR_ANY)
1121 source->s_addr = src.s_addr;
1123 source->s_addr = myroutes[i].dev->addr.s_addr;
1126 bestmatch = myroutes[i].mask;
1130 return myroutes[match].dev->name;