OpenVAS Scanner 23.40.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 1283 of file pcap.c.

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

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 1337 of file pcap.c.

1338{
1339 struct in6_addr src_addr;
1340 char *if_name, *ip_address;
1341
1342 // We get the local address to use, with the remote address.
1343 memset (&src_addr, '\0', sizeof (struct in6_addr));
1344 v6_getsourceip (&src_addr, ipaddr);
1345 ip_address = addr6_as_str (&src_addr);
1346
1347 // Once with the local ip address, we get the source iface name
1348 if_name = get_iface_from_ip (ip_address);
1349 g_free (ip_address);
1350 if (!if_name)
1351 {
1352 g_debug ("%s: Missing interface name", __func__);
1353 return -1;
1354 }
1355
1356 *ifindex = if_nametoindex (if_name);
1357
1358 return 0;
1359}
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:1283

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:440
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 ("%s: Could not read from /proc/net/route", __func__);
1115 else
1116 {
1117 while (fgets (buf, sizeof (buf), routez) != NULL)
1118 {
1119 p = strtok (buf, " \t\n");
1120 if (!p)
1121 {
1122 g_message ("Could not find interface in"
1123 " /proc/net/route line");
1124 continue;
1125 }
1126 strncpy (iface, p, sizeof (iface) - 1);
1127 iface[MAX_IFACE_NAME_LEN - 1] = '\0';
1128 if ((p = strchr (iface, ':')))
1129 {
1130 *p = '\0'; /* To support IP aliasing */
1131 }
1132 p = strtok (NULL, " \t\n");
1133 endptr = NULL;
1134 myroutes[numroutes].dest = strtoul (p, &endptr, 16);
1135 if (!endptr || *endptr)
1136 {
1137 g_message (
1138 "Failed to determine Destination from /proc/net/route");
1139 continue;
1140 }
1141 for (i = 0; i < 5; i++)
1142 {
1143 p = strtok (NULL, " \t\n");
1144 if (!p)
1145 break;
1146 }
1147 if (!p)
1148 {
1149 g_message ("Failed to find field %d in"
1150 " /proc/net/route",
1151 i + 2);
1152 continue;
1153 }
1154 endptr = NULL;
1155 myroutes[numroutes].metric = strtol (p, &endptr, 10);
1156 if (!endptr || *endptr)
1157 {
1158 g_message ("Failed to determine metric from /proc/net/route");
1159 continue;
1160 }
1161 p = strtok (NULL, " \t\n");
1162 endptr = NULL;
1163 myroutes[numroutes].mask = strtoul (p, &endptr, 16);
1164 if (!endptr || *endptr)
1165 {
1166 g_message ("Failed to determine mask"
1167 " from /proc/net/route");
1168 continue;
1169 }
1170
1171 g_debug ("#%d: for dev %s, The dest is %lX and the mask is %lX",
1172 numroutes, iface, myroutes[numroutes].dest,
1173 myroutes[numroutes].mask);
1174 for (i = 0; i < numinterfaces; i++)
1175 if (!strcmp (iface, mydevs[i].name))
1176 {
1177 myroutes[numroutes].dev = &mydevs[i];
1178 break;
1179 }
1180 if (i == numinterfaces)
1181 g_message (
1182 "Failed to find interface %s mentioned in /proc/net/route",
1183 iface);
1184 numroutes++;
1185 if (numroutes >= MAXROUTES)
1186 {
1187 g_message ("You seem to have WAY to many routes!");
1188 break;
1189 }
1190 }
1191 }
1192 fclose (routez);
1193 }
1194 else
1195 {
1196 g_message ("Could not read from /proc/net/route");
1197 return NULL;
1198 }
1199 }
1200 else
1201 mydevs = getinterfaces (&numinterfaces);
1202 /* WHEW, that takes care of initializing, now we have the easy job of
1203 finding which route matches */
1204 if (mydevs && islocalhost (dest))
1205 {
1206 if (source)
1207 source->s_addr = htonl (0x7F000001);
1208 /* Now we find the localhost interface name, assuming 127.0.0.1 is
1209 localhost (it damn well better be!)... */
1210 for (i = 0; i < numinterfaces; i++)
1211 {
1212 if (mydevs[i].addr.s_addr == htonl (0x7F000001))
1213 {
1214 return mydevs[i].name;
1215 }
1216 }
1217 return NULL;
1218 }
1219
1220 for (i = 0; i < numroutes; i++)
1221 {
1222 /* Matching route found */
1223 if ((dest->s_addr & myroutes[i].mask) == myroutes[i].dest)
1224 {
1225 /* First time a match is found */
1226 if (-1 == best_match)
1227 {
1228 best_match = i;
1229 }
1230 else
1231 {
1232 /* Better match found */
1233 if (myroutes[i].mask > myroutes[best_match].mask)
1234 {
1235 best_match = i;
1236 }
1237 /* Match with equal mask and smaller (better) metric found */
1238 else if ((myroutes[i].mask == myroutes[best_match].mask)
1239 && (myroutes[i].metric < myroutes[best_match].metric))
1240 {
1241 best_match = i;
1242 }
1243 }
1244 }
1245 }
1246
1247 /* Set source */
1248 if (source)
1249 {
1250 /* Source address is given */
1251 if (src.s_addr != INADDR_ANY)
1252 source->s_addr = src.s_addr;
1253 /* Source address is INADDR_ANY and there is a good route */
1254 else if (best_match != -1)
1255 source->s_addr = myroutes[best_match].dev->addr.s_addr;
1256 /* No best route found and no default */
1257 else
1258 {
1259 /* Assigned first route in the table */
1260 if (myroutes[0].dev)
1261 {
1262 source->s_addr = myroutes[0].dev->addr.s_addr;
1263 best_match = 0;
1264 }
1265 /* or any */
1266 else
1267 source->s_addr = INADDR_ANY;
1268 }
1269 }
1270
1271 if (best_match != -1)
1272 return myroutes[best_match].dev->name;
1273 return NULL;
1274}
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: