OpenVAS Scanner 23.32.3
pcap.c File Reference
#include "bpf_share.h"
#include "network.h"
#include "pcap_openvas.h"
#include "support.h"
#include <arpa/inet.h>
#include <errno.h>
#include <gvm/base/logging.h>
#include <gvm/base/networking.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <netdb.h>
#include <netinet/in.h>
#include <pcap.h>
#include <pcap/pcap.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/types.h>
#include <unistd.h>
Include dependency graph for pcap.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  interface_info
struct  myroute

Macros

#define MAXROUTES   1024
#define G_LOG_DOMAIN   "lib misc"
 GLib logging domain.
#define MAX_IFACE_NAME_LEN   64
 Maximum length of an interface's name.
#define DEBUG_IPV4(x)

Functions

struct interface_infogetinterfaces (int *howmany)
struct interface_infov6_getinterfaces (int *howmany)
int getipv6routes (struct myroute *myroutes, int *numroutes)
 Get the IPv6 routes and number of routes.
static int ipv6_prefix_to_mask (unsigned prefix, struct in6_addr *mask)
 Generate an ipv6 mask from the given ipv6 prefix.
int v6_is_local_ip (struct in6_addr *addr)
static int v6_ipaddr2devname (char *dev, int sz, struct in6_addr *addr)
static int ipaddr2devname (char *dev, int sz, struct in_addr *addr)
int v6_islocalhost (struct in6_addr *addr)
 Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface.
int islocalhost (struct in_addr *addr)
 Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface.
int get_datalink_size (int datalink)
int v6_getsourceip (struct in6_addr *src, struct in6_addr *dst)
static int getipv4routes (struct myroute *myroutes, int *numroutes)
 Get the ipv4 routes and number of routes.
char * v6_routethrough (struct in6_addr *dest, struct in6_addr *source)
 An awesome function to determine what interface a packet to a given destination should be routed through.
char * routethrough (struct in_addr *dest, struct in_addr *source)
 An awesome function to determine what interface a packet to a given destination should be routed through.
char * get_iface_from_ip (const char *local_ip)
 Given an IP address, determines which interface belongs to.
int get_iface_index (struct in6_addr *ipaddr, int *ifindex)
 Get the interface index depending on the target's IP.

Macro Definition Documentation

◆ DEBUG_IPV4

#define DEBUG_IPV4 ( x)
Value:
g_debug ("AAA %d.%d.%d.%d", x & 0x000000ff, x >> 8 & 0x000000ff, \
x >> 16 & 0x000000ff, x >> 24 & 0x000000ff);

Definition at line 44 of file pcap.c.

44#define DEBUG_IPV4(x) \
45 g_debug ("AAA %d.%d.%d.%d", x & 0x000000ff, x >> 8 & 0x000000ff, \
46 x >> 16 & 0x000000ff, x >> 24 & 0x000000ff);

Referenced by v6_is_local_ip().

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "lib misc"

GLib logging domain.

Definition at line 36 of file pcap.c.

◆ MAX_IFACE_NAME_LEN

#define MAX_IFACE_NAME_LEN   64

Maximum length of an interface's name.

Definition at line 41 of file pcap.c.

Referenced by getinterfaces(), getipv4routes(), and routethrough().

◆ MAXROUTES

#define MAXROUTES   1024

Definition at line 30 of file pcap.c.

Referenced by getipv4routes(), getipv6routes(), routethrough(), v6_is_local_ip(), and v6_routethrough().

Function Documentation

◆ get_datalink_size()

int get_datalink_size ( int datalink)

Definition at line 298 of file pcap.c.

299{
300 int offset = -1;
301 switch (datalink)
302 {
303 case DLT_EN10MB:
304 offset = 14;
305 break;
306 case DLT_IEEE802:
307 offset = 22;
308 break;
309 case DLT_NULL:
310 offset = 4;
311 break;
312 case DLT_SLIP:
313#if (FREEBSD || OPENBSD || NETBSD || BSDI || DARWIN)
314 offset = 16;
315#else
316 offset = 24; /* Anyone use this??? */
317#endif
318 break;
319 case DLT_PPP:
320#if (FREEBSD || OPENBSD || NETBSD || BSDI || DARWIN)
321 offset = 4;
322#else
323#ifdef SOLARIS
324 offset = 8;
325#else
326 offset = 24; /* Anyone use this? */
327#endif /* ifdef solaris */
328#endif /* if freebsd || openbsd || netbsd || bsdi */
329 break;
330 case DLT_RAW:
331 offset = 0;
332 break;
333 }
334 return (offset);
335}

Referenced by capture_next_frame(), capture_next_packet(), capture_next_v6_packet(), nasl_pcap_next(), nasl_send_capture(), and scan().

Here is the caller graph for this function:

◆ get_iface_from_ip()

char * get_iface_from_ip ( const char * local_ip)

Given an IP address, determines which interface belongs to.

Parameters
local_ipIP address.
Returns
Iface name if found, Null otherwise.

Definition at line 1280 of file pcap.c.

1281{
1282 char errbuf[PCAP_ERRBUF_SIZE];
1283 pcap_if_t *alldevsp1 = NULL, *devs_aux = NULL;
1284 char *if_name = NULL;
1285
1286 if (pcap_findalldevs (&alldevsp1, errbuf) == -1)
1287 g_debug ("Error for pcap_findalldevs(): %s", errbuf);
1288
1289 devs_aux = alldevsp1;
1290 while (devs_aux)
1291 {
1292 pcap_addr_t *addr_aux = NULL;
1293
1294 addr_aux = devs_aux->addresses;
1295 while (addr_aux)
1296 {
1297 char buffer[INET6_ADDRSTRLEN];
1298
1299 if (((struct sockaddr *) addr_aux->addr)->sa_family == AF_INET)
1300 inet_ntop (AF_INET,
1301 &(((struct sockaddr_in *) addr_aux->addr)->sin_addr),
1302 buffer, INET_ADDRSTRLEN);
1303 else if (((struct sockaddr *) addr_aux->addr)->sa_family == AF_INET6)
1304 inet_ntop (AF_INET6,
1305 &(((struct sockaddr_in6 *) addr_aux->addr)->sin6_addr),
1306 buffer, INET6_ADDRSTRLEN);
1307
1308 if (!g_strcmp0 (buffer, local_ip))
1309 {
1310 if_name = g_strdup (devs_aux->name);
1311 break;
1312 }
1313 addr_aux = addr_aux->next;
1314 }
1315
1316 if (if_name)
1317 break;
1318 devs_aux = devs_aux->next;
1319 }
1320 pcap_freealldevs (alldevsp1);
1321 g_debug ("returning %s as device", if_name);
1322
1323 return if_name;
1324}

Referenced by get_iface_index(), and get_local_mac_address_from_ip().

Here is the caller graph for this function:

◆ get_iface_index()

int get_iface_index ( struct in6_addr * ipaddr,
int * ifindex )

Get the interface index depending on the target's IP.

Parameters
[in]ipaddrThe ip address of the target.
[out]ifindexthe index of the selected iface
Returns
0 on success, otherwise -1.

Definition at line 1334 of file pcap.c.

1335{
1336 struct in6_addr src_addr;
1337 char *if_name, *ip_address;
1338
1339 // We get the local address to use, with the remote address.
1340 memset (&src_addr, '\0', sizeof (struct in6_addr));
1341 v6_getsourceip (&src_addr, ipaddr);
1342 ip_address = addr6_as_str (&src_addr);
1343
1344 // Once with the local ip address, we get the source iface name
1345 if_name = get_iface_from_ip (ip_address);
1346 g_free (ip_address);
1347 if (!if_name)
1348 {
1349 g_debug ("%s: Missing interface name", __func__);
1350 return -1;
1351 }
1352
1353 *ifindex = if_nametoindex (if_name);
1354
1355 return 0;
1356}
int v6_getsourceip(struct in6_addr *src, struct in6_addr *dst)
Definition pcap.c:487
char * get_iface_from_ip(const char *local_ip)
Given an IP address, determines which interface belongs to.
Definition pcap.c:1280

References get_iface_from_ip(), and v6_getsourceip().

Referenced by send_frame().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getinterfaces()

struct interface_info * getinterfaces ( int * howmany)
Parameters
[out]howmanyReturn location for the number of interfaces found (might be NULL).

Definition at line 413 of file pcap.c.

414{
415 static struct interface_info mydevs[1024];
416 int numinterfaces = 0;
417 int sd;
418 int len;
419 char *p;
420 char buf[10240];
421 struct ifconf ifc;
422 struct ifreq *ifr;
423 struct sockaddr_in *sin;
424 char *bufp;
425
426 /* Dummy socket for ioctl. */
427 sd = socket (AF_INET, SOCK_DGRAM, 0);
428 bzero (buf, sizeof (buf));
429 if (sd < 0)
430 {
431 g_message ("socket in getinterfaces");
432 return NULL;
433 }
434
435 ifc.ifc_len = sizeof (buf);
436 ifc.ifc_buf = buf;
437 if (ioctl (sd, SIOCGIFCONF, &ifc) < 0)
438 g_message ("Failed to determine your configured interfaces!");
439
440 close (sd);
441 if (ifc.ifc_len == 0)
442 g_message (
443 "getinterfaces: SIOCGIFCONF claims you have no network interfaces!");
444
445#ifndef __FreeBSD__
446 len = sizeof (struct ifmap);
447#else
448 len = sizeof (struct sockaddr);
449#endif
450
451 for (bufp = buf; bufp && *bufp && (bufp < (buf + ifc.ifc_len));
452 bufp += sizeof (ifr->ifr_name) + len)
453 {
454 ifr = (struct ifreq *) bufp;
455 sin = (struct sockaddr_in *) &ifr->ifr_addr;
456 memcpy (&(mydevs[numinterfaces].addr), (char *) &(sin->sin_addr),
457 sizeof (struct in_addr));
458 /* In case it is a stinkin' alias */
459 if ((p = strchr (ifr->ifr_name, ':')))
460 *p = '\0';
461
462 memset (mydevs[numinterfaces].name, '\0', MAX_IFACE_NAME_LEN);
463 if (strlen (ifr->ifr_name) < MAX_IFACE_NAME_LEN)
464 memcpy (mydevs[numinterfaces].name, ifr->ifr_name,
465 strlen (ifr->ifr_name));
466 else
467 memcpy (mydevs[numinterfaces].name, ifr->ifr_name,
469 numinterfaces++;
470 if (numinterfaces == 1023)
471 {
472 g_message ("You seem to have more than 1023 network interfaces."
473 " Things may not work right.");
474 break;
475 }
476 mydevs[numinterfaces].name[0] = '\0';
477 }
478
479 // If output parameter given, set value
480 if (howmany)
481 *howmany = numinterfaces;
482
483 return mydevs;
484}
const char * name
Definition nasl_init.c:439
uint8_t len
#define MAX_IFACE_NAME_LEN
Maximum length of an interface's name.
Definition pcap.c:41

References len, MAX_IFACE_NAME_LEN, interface_info::name, and name.

Referenced by ipaddr2devname(), and routethrough().

Here is the caller graph for this function:

◆ getipv4routes()

int getipv4routes ( struct myroute * myroutes,
int * numroutes )
static

Get the ipv4 routes and number of routes.

This function is only used for getting the ipv4 routes in v6_routethrough(). routethrough() overwrites the global myroutes struct with a local version and uses its own logic for getting the routes from /proc/net/route.

Parameters
[out]myroutesArray of routes.
[out]numroutesNumber of routes in myroutes.
Returns
0 on success, -1 on error.

Definition at line 591 of file pcap.c.

592{
593 struct interface_info *mydevs;
594 int i;
595 int numinterfaces;
596 char buf[1024];
597 char *p, *endptr;
598 char iface[MAX_IFACE_NAME_LEN];
599 FILE *routez;
600 unsigned long dest;
601 struct in_addr inaddr;
602 unsigned long mask;
603 unsigned long ones;
604
605 /* Dummy socket for ioctl */
606 mydevs = v6_getinterfaces (&numinterfaces);
607
608 /* Now we must go through several techniques to determine info */
609 routez = fopen ("/proc/net/route", "r");
610
611 if (routez)
612 {
613 /* OK, linux style /proc/net/route ... we can handle this ... */
614 /* Now that we've got the interfaces, we g0 after the r0ut3Z */
615 if (fgets (buf, sizeof (buf), routez) == NULL) /* Kill the first line */
616 {
617 // /proc/net/route was empty or an error occurred.
618 g_message ("Could not read from /proc/net/route");
619 fclose (routez);
620 return -1;
621 }
622 while (fgets (buf, sizeof (buf), routez))
623 {
624 p = strtok (buf, " \t\n");
625 if (!p)
626 {
627 g_message ("Could not find interface in"
628 " /proc/net/route line");
629 continue;
630 }
631 strncpy (iface, p, sizeof (iface) - 1);
632 iface[MAX_IFACE_NAME_LEN - 1] = '\0';
633 if ((p = strchr (iface, ':')))
634 {
635 *p = '\0'; /* To support IP aliasing */
636 }
637 p = strtok (NULL, " \t\n");
638 endptr = NULL;
639 dest = strtoul (p, &endptr, 16);
640 g_debug ("ipv4 dest is %s", p);
641 if (!endptr || *endptr)
642 {
643 g_message ("Failed to determine Destination from"
644 " /proc/net/route");
645 continue;
646 }
647 inaddr.s_addr = dest;
648 myroutes[*numroutes].dest6.s6_addr32[0] = 0;
649 myroutes[*numroutes].dest6.s6_addr32[1] = 0;
650 myroutes[*numroutes].dest6.s6_addr32[2] = htonl (0xffff);
651 myroutes[*numroutes].dest6.s6_addr32[3] = inaddr.s_addr;
652 for (i = 0; i < 5; i++)
653 {
654 p = strtok (NULL, " \t\n");
655 if (!p)
656 break;
657 }
658 if (!p)
659 {
660 g_message ("Failed to find field %d in"
661 " /proc/net/route",
662 i + 2);
663 continue;
664 }
665 /* set metric */
666 endptr = NULL;
667 myroutes[*numroutes].metric = strtol (p, &endptr, 10);
668 if (!endptr || *endptr)
669 {
670 g_message ("%s: Failed to determine metric from /proc/net/route",
671 __func__);
672 continue;
673 }
674 p = strtok (NULL, " \t\n");
675 endptr = NULL;
676 mask = strtoul (p, &endptr, 16);
677 ones = 0;
678 i = 0;
679 while (mask & (1 << i++) && i < 32)
680 ones++;
681 myroutes[*numroutes].mask = ones + 96;
682 g_debug ("mask is %lu", myroutes[*numroutes].mask);
683 if (!endptr || *endptr)
684 {
685 g_message ("Failed to determine mask from"
686 " /proc/net/route");
687 continue;
688 }
689
690 g_debug ("#%d: for dev %s, The dest is %lX and the mask is %lX",
691 *numroutes, iface, myroutes[*numroutes].dest,
692 myroutes[*numroutes].mask);
693 for (i = 0; i < numinterfaces; i++)
694 if (!strcmp (iface, mydevs[i].name))
695 {
696 myroutes[*numroutes].dev = &mydevs[i];
697 break;
698 }
699 if (i == numinterfaces)
700 g_message (
701 "Failed to find interface %s mentioned in /proc/net/route",
702 iface);
703 (*numroutes)++;
704 if (*numroutes >= MAXROUTES)
705 {
706 g_message ("You seem to have WAY to many routes!");
707 break;
708 }
709 }
710 fclose (routez);
711 return 0;
712 }
713 else
714 return -1;
715}
struct interface_info * v6_getinterfaces(int *howmany)
Definition pcap.c:338
#define MAXROUTES
Definition pcap.c:30
struct in6_addr dest6
Definition pcap.c:64
unsigned long mask
Definition pcap.c:65
unsigned long metric
Definition pcap.c:67
struct interface_info * dev
Definition pcap.c:63

References myroute::dest6, myroute::dev, myroute::mask, MAX_IFACE_NAME_LEN, MAXROUTES, myroute::metric, name, and v6_getinterfaces().

Referenced by v6_routethrough().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getipv6routes()

int getipv6routes ( struct myroute * myroutes,
int * numroutes )

Get the IPv6 routes and number of routes.

This function parses the /proc/net/ipv6_route file into an array of myroute structs.

Parameters
[out]myroutesArray of routes.
[out]numroutesNumber of routes in myroutes.
Returns
0 on success, -1 when no routes are found.

Definition at line 729 of file pcap.c.

730{
731 struct interface_info *mydevs;
732 int i, j;
733 int len;
734 struct in6_addr in6addr;
735 char destaddr[100];
736 int numinterfaces;
737 char buf[1024];
738 char *endptr;
739 FILE *routez;
740 char v6addr[INET6_ADDRSTRLEN];
741 char *token;
742 int cnt;
743
744 /* Dummy socket for ioctl */
745 mydevs = v6_getinterfaces (&numinterfaces);
746 routez = fopen ("/proc/net/ipv6_route", "r");
747 if (routez)
748 {
749 /* linux style /proc/net/ipv6_route ... we can handle this too... */
750 while (fgets (buf, sizeof (buf), routez) != NULL)
751 {
752 char iface[64];
753
754 token = strtok (buf, " \t\n");
755 if (token)
756 {
757 g_debug ("first token is %s", token);
758 strncpy (destaddr, token, sizeof (destaddr) - 1);
759 len = strlen (destaddr);
760 for (i = 0, j = 0; j < len; j++)
761 {
762 v6addr[i++] = destaddr[j];
763 if (j % 4 == 3)
764 v6addr[i++] = ':';
765 }
766 v6addr[--i] = '\0';
767 g_debug ("ipv6 dest is %s", v6addr);
768 if (inet_pton (AF_INET6, v6addr, &in6addr) <= 0)
769 {
770 g_message ("invalid ipv6 addressd");
771 continue;
772 }
773 memcpy (&myroutes[*numroutes].dest6, &in6addr,
774 sizeof (struct in6_addr));
775 }
776 token = strtok (NULL, " \t\n");
777 if (token)
778 {
779 endptr = NULL;
780 myroutes[*numroutes].mask = strtoul (token, &endptr, 16);
781 }
782
783 /* set metric */
784 cnt = 4;
785 while (cnt--)
786 {
787 token = strtok (NULL, " \t\n");
788 if (!token)
789 g_message ("getipv6routes error");
790 }
791 endptr = NULL;
792 myroutes[*numroutes].metric = strtoul (token, &endptr, 16);
793 if (!endptr || *endptr)
794 {
795 g_message (
796 "%s: Failed to determine metric from /proc/net/ipv6_route",
797 __func__);
798 continue;
799 }
800
801 /* set interface name */
802 cnt = 3;
803 while (cnt--)
804 {
805 token = strtok (NULL, " \t\n");
806 if (!token)
807 g_message ("getipv6routes error");
808 }
809 bzero (iface, sizeof (iface));
810 token = strtok (NULL, " \t\n");
811 if (token)
812 strncpy (iface, token, sizeof (iface) - 1);
813 for (i = 0; i < numinterfaces; i++)
814 if (!strcmp (iface, mydevs[i].name)
815 && !IN6_IS_ADDR_V4MAPPED (&mydevs[i].addr6))
816 {
817 myroutes[*numroutes].dev = &mydevs[i];
818 break;
819 }
820 if (i == numinterfaces)
821 g_message (
822 "Failed to find interface %s mentioned in /proc/net/ipv6_route",
823 iface);
824 (*numroutes)++;
825 if (*numroutes >= MAXROUTES)
826 {
827 g_message ("You seem to have WAY to many routes!");
828 break;
829 }
830 }
831 fclose (routez);
832 return 0;
833 }
834 else
835 {
836 g_message ("Didn't find IPv6 routes");
837 return -1;
838 }
839}

References myroute::dev, len, myroute::mask, MAXROUTES, myroute::metric, name, and v6_getinterfaces().

Referenced by v6_is_local_ip(), and v6_routethrough().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ipaddr2devname()

int ipaddr2devname ( char * dev,
int sz,
struct in_addr * addr )
static

Definition at line 207 of file pcap.c.

208{
209 struct interface_info *mydevs;
210 int numdevs;
211 int i;
212 mydevs = getinterfaces (&numdevs);
213
214 if (!mydevs)
215 return -1;
216
217 for (i = 0; i < numdevs; i++)
218 {
219 if (addr->s_addr == mydevs[i].addr.s_addr)
220 {
221 dev[sz - 1] = '\0';
222 strncpy (dev, mydevs[i].name, sz);
223 return 0;
224 }
225 }
226 return -1;
227}
struct interface_info * getinterfaces(int *howmany)
Definition pcap.c:413
struct in_addr addr
Definition pcap.c:52

References interface_info::addr, getinterfaces(), and name.

Referenced by islocalhost().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ipv6_prefix_to_mask()

int ipv6_prefix_to_mask ( unsigned prefix,
struct in6_addr * mask )
static

Generate an ipv6 mask from the given ipv6 prefix.

This function is a copy of the function ipv6_prefix_to_mask() obtained from GPL-2.0 licensed https://gitlab.com/ipcalc/ipcalc/-/blob/master/ipcalc.c.

Parameters
[in]prefixThe ipv6 prefix.
[out]maskThe mask corresponding to the prefix.
Returns
0 on success, -1 on error.

Definition at line 89 of file pcap.c.

90{
91 struct in6_addr in6;
92 int i, j;
93
94 if (prefix > 128)
95 return -1;
96
97 memset (&in6, 0x0, sizeof (in6));
98 for (i = prefix, j = 0; i > 0; i -= 8, j++)
99 {
100 if (i >= 8)
101 {
102 in6.s6_addr[j] = 0xff;
103 }
104 else
105 {
106 in6.s6_addr[j] = (unsigned long) (0xffU << (8 - i));
107 }
108 }
109
110 memcpy (mask, &in6, sizeof (*mask));
111 return 0;
112}
static void prefix(int n, int i)
Definition nasl_tree.c:219

References prefix().

Referenced by Ensure(), openvas_routethrough(), v6_is_local_ip(), and v6_routethrough().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ islocalhost()

int islocalhost ( struct in_addr * addr)

Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface.

Definition at line 271 of file pcap.c.

272{
273 char dev[128];
274
275 if (addr == NULL)
276 return -1;
277
278 /* If it is 0.0.0.0 or starts with 127.0.0.1 then it is
279 probably localhost */
280 if ((addr->s_addr & htonl (0xFF000000)) == htonl (0x7F000000))
281 return 1;
282
283 if (!addr->s_addr)
284 return 1;
285
286 /* If it is the same addy as a local interface, then it is
287 probably localhost */
288
289 if (ipaddr2devname (dev, sizeof (dev), addr) != -1)
290 return 1;
291
292 /* OK, so to a first approximation, this addy is probably not
293 localhost */
294 return 0;
295}
static int ipaddr2devname(char *dev, int sz, struct in_addr *addr)
Definition pcap.c:207

References interface_info::addr, and ipaddr2devname().

Referenced by Ensure(), init_capture_device(), nasl_send_packet(), nasl_tcp_ping(), openvas_routethrough(), plugin_run_synscan(), and routethrough().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ routethrough()

char * routethrough ( struct in_addr * dest,
struct in_addr * source )

An awesome function to determine what interface a packet to a given destination should be routed through.

It returns NULL if no appropriate interface is found, otherwise it returns the device name and fills in the source parameter. Some of the stuff is from Stevens' Unix Network Programming V2. He had an easier suggestion for doing this (in the book), but it isn't portable :(

Definition at line 1070 of file pcap.c.

1071{
1072 static int initialized = 0;
1073 int i;
1074 char buf[10240];
1075 struct interface_info *mydevs;
1076 static struct myroute
1077 {
1078 struct interface_info *dev;
1079 unsigned long mask;
1080 unsigned long dest;
1081 unsigned long metric;
1082 } myroutes[MAXROUTES];
1083 int numinterfaces = 0;
1084 char *p, *endptr;
1085 char iface[MAX_IFACE_NAME_LEN];
1086 static int numroutes = 0;
1087 FILE *routez;
1088 long best_match = -1;
1089
1090 struct in_addr src;
1091
1092 gvm_source_addr (&src);
1093 if (!dest)
1094 {
1095 g_message ("ipaddr2devname passed a NULL dest address");
1096 return NULL;
1097 }
1098
1099 if (!initialized)
1100 {
1101 /* Dummy socket for ioctl */
1102 initialized = 1;
1103 mydevs = getinterfaces (&numinterfaces);
1104 if (!mydevs)
1105 return NULL;
1106
1107 routez = fopen ("/proc/net/route", "r");
1108 if (routez)
1109 {
1110 /* OK, linux style /proc/net/route ... we can handle this ... */
1111 /* Now that we've got the interfaces, we g0 after the r0ut3Z */
1112 if (fgets (buf, sizeof (buf), routez)
1113 == NULL) /* Kill the first line */
1114 g_message ("Could not read from /proc/net/route");
1115 while (fgets (buf, sizeof (buf), routez))
1116 {
1117 p = strtok (buf, " \t\n");
1118 if (!p)
1119 {
1120 g_message ("Could not find interface in"
1121 " /proc/net/route line");
1122 continue;
1123 }
1124 strncpy (iface, p, sizeof (iface) - 1);
1125 iface[MAX_IFACE_NAME_LEN - 1] = '\0';
1126 if ((p = strchr (iface, ':')))
1127 {
1128 *p = '\0'; /* To support IP aliasing */
1129 }
1130 p = strtok (NULL, " \t\n");
1131 endptr = NULL;
1132 myroutes[numroutes].dest = strtoul (p, &endptr, 16);
1133 if (!endptr || *endptr)
1134 {
1135 g_message (
1136 "Failed to determine Destination from /proc/net/route");
1137 continue;
1138 }
1139 for (i = 0; i < 5; i++)
1140 {
1141 p = strtok (NULL, " \t\n");
1142 if (!p)
1143 break;
1144 }
1145 if (!p)
1146 {
1147 g_message ("Failed to find field %d in"
1148 " /proc/net/route",
1149 i + 2);
1150 continue;
1151 }
1152 endptr = NULL;
1153 myroutes[numroutes].metric = strtol (p, &endptr, 10);
1154 if (!endptr || *endptr)
1155 {
1156 g_message ("Failed to determine metric from /proc/net/route");
1157 continue;
1158 }
1159 p = strtok (NULL, " \t\n");
1160 endptr = NULL;
1161 myroutes[numroutes].mask = strtoul (p, &endptr, 16);
1162 if (!endptr || *endptr)
1163 {
1164 g_message ("Failed to determine mask"
1165 " from /proc/net/route");
1166 continue;
1167 }
1168
1169 g_debug ("#%d: for dev %s, The dest is %lX and the mask is %lX",
1170 numroutes, iface, myroutes[numroutes].dest,
1171 myroutes[numroutes].mask);
1172 for (i = 0; i < numinterfaces; i++)
1173 if (!strcmp (iface, mydevs[i].name))
1174 {
1175 myroutes[numroutes].dev = &mydevs[i];
1176 break;
1177 }
1178 if (i == numinterfaces)
1179 g_message (
1180 "Failed to find interface %s mentioned in /proc/net/route",
1181 iface);
1182 numroutes++;
1183 if (numroutes >= MAXROUTES)
1184 {
1185 g_message ("You seem to have WAY to many routes!");
1186 break;
1187 }
1188 }
1189 fclose (routez);
1190 }
1191 else
1192 {
1193 g_message ("Could not read from /proc/net/route");
1194 return NULL;
1195 }
1196 }
1197 else
1198 mydevs = getinterfaces (&numinterfaces);
1199 /* WHEW, that takes care of initializing, now we have the easy job of
1200 finding which route matches */
1201 if (mydevs && islocalhost (dest))
1202 {
1203 if (source)
1204 source->s_addr = htonl (0x7F000001);
1205 /* Now we find the localhost interface name, assuming 127.0.0.1 is
1206 localhost (it damn well better be!)... */
1207 for (i = 0; i < numinterfaces; i++)
1208 {
1209 if (mydevs[i].addr.s_addr == htonl (0x7F000001))
1210 {
1211 return mydevs[i].name;
1212 }
1213 }
1214 return NULL;
1215 }
1216
1217 for (i = 0; i < numroutes; i++)
1218 {
1219 /* Matching route found */
1220 if ((dest->s_addr & myroutes[i].mask) == myroutes[i].dest)
1221 {
1222 /* First time a match is found */
1223 if (-1 == best_match)
1224 {
1225 best_match = i;
1226 }
1227 else
1228 {
1229 /* Better match found */
1230 if (myroutes[i].mask > myroutes[best_match].mask)
1231 {
1232 best_match = i;
1233 }
1234 /* Match with equal mask and smaller (better) metric found */
1235 else if ((myroutes[i].mask == myroutes[best_match].mask)
1236 && (myroutes[i].metric < myroutes[best_match].metric))
1237 {
1238 best_match = i;
1239 }
1240 }
1241 }
1242 }
1243
1244 /* Set source */
1245 if (source)
1246 {
1247 /* Source address is given */
1248 if (src.s_addr != INADDR_ANY)
1249 source->s_addr = src.s_addr;
1250 /* Source address is INADDR_ANY and there is a good route */
1251 else if (best_match != -1)
1252 source->s_addr = myroutes[best_match].dev->addr.s_addr;
1253 /* No best route found and no default */
1254 else
1255 {
1256 /* Assigned first route in the table */
1257 if (myroutes[0].dev)
1258 {
1259 source->s_addr = myroutes[0].dev->addr.s_addr;
1260 best_match = 0;
1261 }
1262 /* or any */
1263 else
1264 source->s_addr = INADDR_ANY;
1265 }
1266 }
1267
1268 if (best_match != -1)
1269 return myroutes[best_match].dev->name;
1270 return NULL;
1271}
int islocalhost(struct in_addr *addr)
Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface.
Definition pcap.c:271
char name[MAX_IFACE_NAME_LEN]
Definition pcap.c:51
Definition pcap.c:62
unsigned long dest
Definition pcap.c:66

References myroute::dest, myroute::dev, getinterfaces(), islocalhost(), myroute::mask, MAX_IFACE_NAME_LEN, MAXROUTES, myroute::metric, interface_info::name, and name.

Referenced by Ensure(), Ensure(), Ensure(), Ensure(), Ensure(), init_capture_device(), nasl_pcap_next(), nasl_send_arp_request(), nasl_send_capture(), nasl_tcp_ping(), and openbpf().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ v6_getinterfaces()

struct interface_info * v6_getinterfaces ( int * howmany)

Definition at line 338 of file pcap.c.

339{
340 struct sockaddr_in *saddr;
341 struct sockaddr_in6 *s6addr;
342 static struct interface_info mydevs[1024];
343 int numinterfaces = 0;
344 struct ifaddrs *ifaddr, *ifa;
345 int family;
346
347 if (getifaddrs (&ifaddr) == -1)
348 {
349 perror ("getifaddrs");
350 }
351 else
352 {
353 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
354 {
355 if (ifa->ifa_addr == NULL)
356 continue;
357
358 family = ifa->ifa_addr->sa_family;
359 if (family == AF_INET)
360 {
361 strncpy (mydevs[numinterfaces].name, ifa->ifa_name,
362 sizeof (mydevs[numinterfaces].name) - 1);
363 saddr = (struct sockaddr_in *) ifa->ifa_addr;
364 g_debug ("interface name is %s", ifa->ifa_name);
365 g_debug ("\tAF_INET family");
366 g_debug ("\taddress is %s", inet_ntoa (saddr->sin_addr));
367 mydevs[numinterfaces].addr6.s6_addr32[0] = 0;
368 mydevs[numinterfaces].addr6.s6_addr32[1] = 0;
369 mydevs[numinterfaces].addr6.s6_addr32[2] = htonl (0xffff);
370 mydevs[numinterfaces].addr6.s6_addr32[3] = saddr->sin_addr.s_addr;
371 saddr = (struct sockaddr_in *) ifa->ifa_netmask;
372 mydevs[numinterfaces].mask.s6_addr32[0] = 0;
373 mydevs[numinterfaces].mask.s6_addr32[1] = 0;
374 mydevs[numinterfaces].mask.s6_addr32[2] = htonl (0xffff);
375 mydevs[numinterfaces].mask.s6_addr32[3] = saddr->sin_addr.s_addr;
376 g_debug ("\tnetmask is %s", inet_ntoa (saddr->sin_addr));
377 numinterfaces++;
378 }
379 else if (family == AF_INET6)
380 {
381 char ipaddr[INET6_ADDRSTRLEN];
382
383 strncpy (mydevs[numinterfaces].name, ifa->ifa_name,
384 sizeof (mydevs[numinterfaces].name) - 1);
385 s6addr = (struct sockaddr_in6 *) ifa->ifa_addr;
386 memcpy (&(mydevs[numinterfaces].addr6),
387 (char *) &(s6addr->sin6_addr), sizeof (struct in6_addr));
388 s6addr = (struct sockaddr_in6 *) ifa->ifa_netmask;
389 memcpy (&(mydevs[numinterfaces].mask),
390 (char *) &(s6addr->sin6_addr), sizeof (struct in6_addr));
391 numinterfaces++;
392 g_debug ("\tAF_INET6 family");
393 g_debug ("interface name is %s", ifa->ifa_name);
394 g_debug ("\taddress is %s",
395 inet_ntop (AF_INET6, &s6addr->sin6_addr, ipaddr,
396 sizeof (ipaddr)));
397 }
398 else
399 g_debug ("\tfamily is %d", ifa->ifa_addr->sa_family);
400 }
401 *howmany = numinterfaces;
402
403 freeifaddrs (ifaddr);
404 }
405 return mydevs;
406}
struct in_addr saddr
struct in6_addr s6addr

References interface_info::addr6, interface_info::mask, name, s6addr, and saddr.

Referenced by getipv4routes(), getipv6routes(), v6_ipaddr2devname(), v6_is_local_ip(), and v6_routethrough().

Here is the caller graph for this function:

◆ v6_getsourceip()

int v6_getsourceip ( struct in6_addr * src,
struct in6_addr * dst )

Definition at line 487 of file pcap.c.

488{
489 int sd;
490 struct sockaddr_in sock;
491 unsigned int socklen;
492 unsigned short p1;
493
494 p1 = (unsigned short) rand ();
495 if (p1 < 5000)
496 p1 += 5000;
497
498 if (IN6_IS_ADDR_V4MAPPED (dst))
499 {
500 char name[INET6_ADDRSTRLEN];
501
502 if ((sd = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
503 {
504 perror ("Socket troubles");
505 return 0;
506 }
507 bzero (&sock, sizeof (struct sockaddr_in));
508 sock.sin_family = AF_INET;
509 sock.sin_addr.s_addr = dst->s6_addr32[3];
510 sock.sin_port = htons (p1);
511 if (connect (sd, (struct sockaddr *) &sock, sizeof (struct sockaddr_in))
512 == -1)
513 {
514 close (sd);
515 return 0;
516 }
517 bzero (&sock, sizeof (struct sockaddr_in));
518 socklen = sizeof (struct sockaddr_in);
519 if (getsockname (sd, (struct sockaddr *) &sock, &socklen) == -1)
520 {
521 perror ("getsockname");
522 close (sd);
523 return 0;
524 }
525
526 src->s6_addr32[0] = 0;
527 src->s6_addr32[1] = 0;
528 src->s6_addr32[2] = htonl (0xffff);
529 src->s6_addr32[3] = sock.sin_addr.s_addr;
530 g_debug ("source address is %s",
531 inet_ntop (AF_INET6, src, name, sizeof (name)));
532 close (sd);
533 }
534 else
535 {
536 struct sockaddr_in6 sock6;
537 char name[INET6_ADDRSTRLEN];
538
539 if ((sd = socket (AF_INET6, SOCK_DGRAM, 0)) == -1)
540 {
541 perror ("Socket troubles");
542 return 0;
543 }
544 bzero (&sock6, sizeof (sock6));
545 sock6.sin6_family = AF_INET6;
546 sock6.sin6_addr.s6_addr32[0] = dst->s6_addr32[0];
547 sock6.sin6_addr.s6_addr32[1] = dst->s6_addr32[1];
548 sock6.sin6_addr.s6_addr32[2] = dst->s6_addr32[2];
549 sock6.sin6_addr.s6_addr32[3] = dst->s6_addr32[3];
550 sock6.sin6_port = htons (p1);
551 if (connect (sd, (struct sockaddr *) &sock6, sizeof (struct sockaddr_in6))
552 == -1)
553 {
554 close (sd);
555 return 0;
556 }
557 bzero (&sock6, sizeof (struct sockaddr_in6));
558 socklen = sizeof (struct sockaddr_in6);
559 if (getsockname (sd, (struct sockaddr *) &sock6, &socklen) == -1)
560 {
561 perror ("getsockname");
562 close (sd);
563 return 0;
564 }
565
566 src->s6_addr32[0] = sock6.sin6_addr.s6_addr32[0];
567 src->s6_addr32[1] = sock6.sin6_addr.s6_addr32[1];
568 src->s6_addr32[2] = sock6.sin6_addr.s6_addr32[2];
569 src->s6_addr32[3] = sock6.sin6_addr.s6_addr32[3];
570 memcpy (src, &sock6.sin6_addr, sizeof (struct in6_addr));
571 g_debug ("source addrss is %s",
572 inet_ntop (AF_INET6, src, name, sizeof (name)));
573 close (sd);
574 }
575 return 1; /* Calling function responsible for checking validity */
576}

References name.

Referenced by get_iface_index(), nasl_this_host(), and v6_routethrough().

Here is the caller graph for this function:

◆ v6_ipaddr2devname()

int v6_ipaddr2devname ( char * dev,
int sz,
struct in6_addr * addr )
static

Definition at line 176 of file pcap.c.

177{
178 struct interface_info *mydevs;
179 int numdevs = 0;
180 int i;
181 mydevs = v6_getinterfaces (&numdevs);
182
183 if (!mydevs)
184 return -1;
185
186 for (i = 0; i < numdevs; i++)
187 {
188 char addr1[INET6_ADDRSTRLEN];
189 char addr2[INET6_ADDRSTRLEN];
190 g_debug ("comparing addresses %s and %s",
191 inet_ntop (AF_INET6, addr, addr1, sizeof (addr1)),
192 inet_ntop (AF_INET6, &mydevs[i].addr6, addr2, sizeof (addr2)));
193 if (IN6_ARE_ADDR_EQUAL (addr, &mydevs[i].addr6))
194 {
195 dev[sz - 1] = '\0';
196 strncpy (dev, mydevs[i].name, sz);
197 return 0;
198 }
199 }
200 return -1;
201}
struct in6_addr addr6
Definition pcap.c:53

References interface_info::addr, interface_info::addr6, name, and v6_getinterfaces().

Referenced by v6_islocalhost().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ v6_is_local_ip()

int v6_is_local_ip ( struct in6_addr * addr)

Definition at line 115 of file pcap.c.

116{
117 int i, j, ifaces, numroutes = 0;
118 struct interface_info *ifs;
119 static struct myroute myroutes[MAXROUTES];
120 struct in6_addr network, mask;
121
122 if ((ifs = v6_getinterfaces (&ifaces)) == NULL)
123 return -1;
124
125 if (IN6_IS_ADDR_V4MAPPED (addr))
126 {
127 for (i = 0; i < ifaces; i++)
128 {
129 int if_net = ifs[i].mask.s6_addr32[3] & ifs[i].addr6.s6_addr32[3];
130 int addr_net = addr->s6_addr32[3] & ifs[i].mask.s6_addr32[3];
131 g_debug ("iface %s", ifs[i].name);
132 DEBUG_IPV4 (if_net)
133 DEBUG_IPV4 (addr_net)
134 DEBUG_IPV4 (ifs[i].mask.s6_addr32[3])
135
136 if (if_net == addr_net && addr_net)
137 return 1;
138 }
139 }
140 else
141 {
142 if (IN6_IS_ADDR_LINKLOCAL (addr))
143 return 1;
144 if (IN6_IS_ADDR_LOOPBACK (addr))
145 return 1;
146 if (getipv6routes (myroutes, &numroutes) == 0)
147 {
148 for (i = 0; i < numroutes; i++)
149 {
150 char addr1[INET6_ADDRSTRLEN];
151 char addr2[INET6_ADDRSTRLEN];
152
153 if (ipv6_prefix_to_mask (myroutes[i].mask, &mask) == -1)
154 return -1;
155 for (j = 0; j < (int) sizeof (struct in6_addr); j++)
156 network.s6_addr[j] = addr->s6_addr[j] & mask.s6_addr[j];
157
158 g_debug ("comparing addresses %s and %s",
159 inet_ntop (AF_INET6, &network, addr1, sizeof (addr1)),
160 inet_ntop (AF_INET6, &myroutes[i].dest6, addr2,
161 sizeof (addr2)));
162 if (IN6_ARE_ADDR_EQUAL (&network, &myroutes[i].dest6))
163 {
164 return 1;
165 }
166 }
167 }
168 }
169 return 0;
170}
int getipv6routes(struct myroute *myroutes, int *numroutes)
Get the IPv6 routes and number of routes.
Definition pcap.c:729
static int ipv6_prefix_to_mask(unsigned prefix, struct in6_addr *mask)
Generate an ipv6 mask from the given ipv6 prefix.
Definition pcap.c:89
#define DEBUG_IPV4(x)
Definition pcap.c:44
struct in6_addr mask
Definition pcap.c:54

References interface_info::addr6, DEBUG_IPV4, getipv6routes(), ipv6_prefix_to_mask(), interface_info::mask, MAXROUTES, name, and v6_getinterfaces().

Referenced by nasl_islocalnet().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ v6_islocalhost()

int v6_islocalhost ( struct in6_addr * addr)

Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface.

Definition at line 234 of file pcap.c.

235{
236 char dev[128];
237
238 if (addr == NULL)
239 return -1;
240
241 if (IN6_IS_ADDR_V4MAPPED (addr))
242 {
243 /* If it is 0.0.0.0 or starts with 127.0.0.1 then it is
244 probably localhost */
245 if ((addr->s6_addr32[3] & htonl (0xFF000000)) == htonl (0x7F000000))
246 return 1;
247
248 if (!addr->s6_addr32[3])
249 return 1;
250 }
251
252 if (IN6_IS_ADDR_LOOPBACK (addr))
253 return 1;
254
255 /* If it is the same addy as a local interface, then it is
256 probably localhost */
257
258 if (v6_ipaddr2devname (dev, sizeof (dev), addr) != -1)
259 return 1;
260
261 /* OK, so to a first approximation, this addy is probably not
262 localhost */
263 return 0;
264}
static int v6_ipaddr2devname(char *dev, int sz, struct in6_addr *addr)
Definition pcap.c:176

References interface_info::addr, and v6_ipaddr2devname().

Referenced by Ensure(), init_v6_capture_device(), nasl_islocalhost(), nasl_send_v6packet(), nasl_tcp_v6_ping(), nasl_this_host(), openvas_routethrough(), and v6_routethrough().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ v6_routethrough()

char * v6_routethrough ( struct in6_addr * dest,
struct in6_addr * source )

An awesome function to determine what interface a packet to a given destination should be routed through.

It returns NULL if no appropriate interface is found, otherwise it returns the device name and fills in the source parameter. Some of the stuff is from Stevens' Unix Network Programming V2. He had an easier suggestion for doing this (in the book), but it isn't portable :(

Definition at line 851 of file pcap.c.

852{
853 static int initialized = 0;
854 int i;
855 struct in6_addr addy;
856 static enum {
857 procroutetechnique,
858 connectsockettechnique,
859 guesstechnique
860 } technique = procroutetechnique;
861 struct interface_info *mydevs;
862 static struct myroute myroutes[MAXROUTES];
863 int numinterfaces = 0;
864 static int numroutes = 0;
865 struct in6_addr mask;
866 struct in6_addr network = {0};
867 struct in6_addr src;
868 long best_match = -1;
869
870 if (!dest)
871 {
872 g_message ("ipaddr2devname passed a NULL dest address");
873 return NULL;
874 }
875
876 if (IN6_IS_ADDR_V4MAPPED (dest))
877 gvm_source_addr_as_addr6 (&src);
878 else
879 gvm_source_addr6 (&src);
880
881 if (!initialized)
882 {
883 /* Dummy socket for ioctl */
884 initialized = 1;
885 mydevs = v6_getinterfaces (&numinterfaces);
886 if (IN6_IS_ADDR_V4MAPPED (dest))
887 {
888 if (getipv4routes (myroutes, &numroutes) < 0)
889 technique = connectsockettechnique;
890 }
891 else
892 {
893 if (getipv6routes (myroutes, &numroutes) < 0)
894 technique = connectsockettechnique;
895 }
896 }
897 else
898 {
899 mydevs = v6_getinterfaces (&numinterfaces);
900 }
901 /* WHEW, that takes care of initializing, now we have the easy job of
902 finding which route matches */
903 if (v6_islocalhost (dest))
904 {
905 if (source)
906 {
907 if (IN6_IS_ADDR_V4MAPPED (source))
908 {
909 source->s6_addr32[0] = 0;
910 source->s6_addr32[1] = 0;
911 source->s6_addr32[2] = htonl (0xffff);
912 source->s6_addr32[3] = htonl (0x7F000001);
913 }
914 else
915 {
916 source->s6_addr32[0] = 0;
917 source->s6_addr32[1] = 0;
918 source->s6_addr32[2] = 0;
919 source->s6_addr32[3] = htonl (1);
920 }
921 }
922 /* Now we find the localhost interface name, assuming 127.0.0.1
923 or ::1 is localhost (it damn well better be!)... */
924 for (i = 0; i < numinterfaces; i++)
925 {
926 if (IN6_IS_ADDR_V4MAPPED (&mydevs[i].addr6))
927 {
928 if (mydevs[i].addr6.s6_addr32[3] == htonl (0x7F000001))
929 return mydevs[i].name;
930 }
931 else
932 {
933 if (IN6_ARE_ADDR_EQUAL (&in6addr_any, &mydevs[i].addr6))
934 return mydevs[i].name;
935 }
936 }
937 return NULL;
938 }
939
940 if (technique == procroutetechnique)
941 {
942 char addr1[INET6_ADDRSTRLEN];
943 char addr2[INET6_ADDRSTRLEN];
944 for (i = 0; i < numroutes; i++)
945 {
946 if (ipv6_prefix_to_mask (myroutes[i].mask, &mask) == -1)
947 {
948 g_warning ("error creating IPv6 mask from prefix: %ld",
949 myroutes[i].mask);
950 return NULL;
951 }
952 for (int j = 0; j < (int) sizeof (struct in6_addr); j++)
953 network.s6_addr[j] = dest->s6_addr[j] & mask.s6_addr[j];
954
955 g_debug (
956 "comparing addresses %s and %s",
957 inet_ntop (AF_INET6, &network, addr1, sizeof (addr1)),
958 inet_ntop (AF_INET6, &myroutes[i].dest6, addr2, sizeof (addr2)));
959 /* matching route found */
960 if (IN6_ARE_ADDR_EQUAL (&network, &myroutes[i].dest6))
961 {
962 /* First time a match is found */
963 if (-1 == best_match)
964 {
965 best_match = i;
966 }
967 else
968 {
969 /* Better match found */
970 if (myroutes[i].mask > myroutes[best_match].mask)
971 {
972 best_match = i;
973 }
974 /* Match with equal mask and smaller (better) metric found */
975 else if ((myroutes[i].mask == myroutes[best_match].mask)
976 && (myroutes[i].metric
977 < myroutes[best_match].metric))
978 {
979 best_match = i;
980 }
981 }
982 }
983 }
984 if (source)
985 {
986 if (!IN6_ARE_ADDR_EQUAL (&src, &in6addr_any))
987 memcpy (source, &src, sizeof (struct in6_addr));
988 else
989 {
990 if (myroutes[best_match].dev != NULL)
991 {
992 memcpy (source, &myroutes[best_match].dev->addr6,
993 sizeof (struct in6_addr));
994 }
995 }
996 }
997 g_debug (
998 "%s: Best matching route with dst '%s' metric '%ld' and interface '%s'",
999 __func__,
1000 inet_ntop (AF_INET6, &myroutes[best_match].dest6, addr1,
1001 sizeof (addr1)),
1002 myroutes[best_match].mask, myroutes[best_match].dev->name);
1003 if (best_match != -1)
1004 return myroutes[best_match].dev->name;
1005
1006 technique = connectsockettechnique;
1007 }
1008 if (technique == connectsockettechnique)
1009 {
1010 if (!v6_getsourceip (&addy, dest))
1011 return NULL;
1012 if (IN6_ARE_ADDR_EQUAL (&addy, &network))
1013 {
1014 struct hostent *myhostent = NULL;
1015 char myname[MAXHOSTNAMELEN + 1];
1016
1017 myhostent = gethostbyname (myname);
1018 if (gethostname (myname, MAXHOSTNAMELEN) || !myhostent)
1019 g_message ("Cannot get hostname!");
1020 else if (myhostent->h_addrtype == AF_INET)
1021 {
1022 addy.s6_addr32[0] = 0;
1023 addy.s6_addr32[1] = 0;
1024 addy.s6_addr32[2] = htonl (0xffff);
1025 memcpy (&addy.s6_addr32[0], myhostent->h_addr_list[0],
1026 sizeof (struct in6_addr));
1027 }
1028 else
1029 memcpy (&addy, myhostent->h_addr_list[0], sizeof (struct in6_addr));
1030 }
1031
1032 /* Now we insure this claimed address is a real interface ... */
1033 for (i = 0; i < numinterfaces; i++)
1034 {
1035 char addr1[INET6_ADDRSTRLEN];
1036 char addr2[INET6_ADDRSTRLEN];
1037
1038 g_debug (
1039 "comparing addresses %s and %s",
1040 inet_ntop (AF_INET6, &mydevs[i].addr6, addr1, sizeof (addr1)),
1041 inet_ntop (AF_INET6, &addy, addr2, sizeof (addr2)));
1042 if (IN6_ARE_ADDR_EQUAL (&mydevs[i].addr6, &addy))
1043 {
1044 if (source)
1045 {
1046 memcpy (source, &addy, sizeof (struct in6_addr));
1047 }
1048 return mydevs[i].name;
1049 }
1050 }
1051 return NULL;
1052 }
1053 else
1054 g_message ("%s: Provided technique is neither proc route nor"
1055 " connect socket",
1056 __func__);
1057 return NULL;
1058}
static int getipv4routes(struct myroute *myroutes, int *numroutes)
Get the ipv4 routes and number of routes.
Definition pcap.c:591
int v6_islocalhost(struct in6_addr *addr)
Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface.
Definition pcap.c:234

References myroute::dev, getipv4routes(), getipv6routes(), ipv6_prefix_to_mask(), MAXROUTES, interface_info::name, v6_getinterfaces(), v6_getsourceip(), and v6_islocalhost().

Referenced by get_mtu(), init_v6_capture_device(), nasl_pcap_next(), nasl_send_capture(), nasl_tcp_v6_ping(), and v6_openbpf().

Here is the call graph for this function:
Here is the caller graph for this function: