OpenVAS Scanner  7.0.0~git
pcap.c File Reference
#include "bpf_share.h"
#include "network.h"
#include "pcap_openvas.h"
#include "support.h"
#include <arpa/inet.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 <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:

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. More...
 

Functions

struct interface_infogetinterfaces (int *howmany)
 
struct interface_infov6_getinterfaces (int *howmany)
 
int getipv6routes (struct myroute *myroutes, int *numroutes)
 
static void ipv6addrmask (struct in6_addr *in6addr, int mask)
 
int v6_is_local_ip (struct in6_addr *addr)
 
int v6_ipaddr2devname (char *dev, int sz, struct in6_addr *addr)
 
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. More...
 
int islocalhost (struct in_addr *addr)
 Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface. More...
 
int get_datalink_size (int datalink)
 
int v6_getsourceip (struct in6_addr *src, struct in6_addr *dst)
 
int getipv4routes (struct myroute *myroutes, int *numroutes)
 
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. More...
 
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. More...
 

Macro Definition Documentation

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "lib misc"

GLib logging domain.

Definition at line 48 of file pcap.c.

◆ MAXROUTES

#define MAXROUTES   1024

Definition at line 42 of file pcap.c.

Function Documentation

◆ get_datalink_size()

int get_datalink_size ( int  datalink)

Definition at line 295 of file pcap.c.

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

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

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

411 {
412  static struct interface_info mydevs[1024];
413  int numinterfaces = 0;
414  int sd;
415  int len;
416  char *p;
417  char buf[10240];
418  struct ifconf ifc;
419  struct ifreq *ifr;
420  struct sockaddr_in *sin;
421  char *bufp;
422 
423  /* Dummy socket for ioctl. */
424  sd = socket (AF_INET, SOCK_DGRAM, 0);
425  bzero (buf, sizeof (buf));
426  if (sd < 0)
427  {
428  g_message ("socket in getinterfaces");
429  return NULL;
430  }
431 
432  ifc.ifc_len = sizeof (buf);
433  ifc.ifc_buf = buf;
434  if (ioctl (sd, SIOCGIFCONF, &ifc) < 0)
435  g_message ("Failed to determine your configured interfaces!");
436 
437  close (sd);
438  if (ifc.ifc_len == 0)
439  g_message (
440  "getinterfaces: SIOCGIFCONF claims you have no network interfaces!");
441 
442 #ifndef __FreeBSD__
443  len = sizeof (struct ifmap);
444 #else
445  len = sizeof (struct sockaddr);
446 #endif
447 
448  for (bufp = buf; bufp && *bufp && (bufp < (buf + ifc.ifc_len));
449  bufp += sizeof (ifr->ifr_name) + len)
450  {
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));
455  /* In case it is a stinkin' alias */
456  if ((p = strchr (ifr->ifr_name, ':')))
457  *p = '\0';
458  strncpy (mydevs[numinterfaces].name, ifr->ifr_name, 63);
459  mydevs[numinterfaces].name[63] = '\0';
460  numinterfaces++;
461  if (numinterfaces == 1023)
462  {
463  g_message ("You seem to have more than 1023 network interfaces."
464  " Things may not work right.");
465  break;
466  }
467  mydevs[numinterfaces].name[0] = '\0';
468  }
469 
470  // If output parameter given, set value
471  if (howmany)
472  *howmany = numinterfaces;
473 
474  return mydevs;
475 }

References 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 
)

Definition at line 570 of file pcap.c.

571 {
572  struct interface_info *mydevs;
573  int i;
574  int numinterfaces;
575  char buf[1024];
576  char *p, *endptr;
577  char iface[64];
578  FILE *routez;
579  unsigned long dest;
580  struct in_addr inaddr;
581  unsigned long mask;
582  unsigned long ones;
583 
584  /* Dummy socket for ioctl */
585  mydevs = v6_getinterfaces (&numinterfaces);
586 
587  /* Now we must go through several techniques to determine info */
588  routez = fopen ("/proc/net/route", "r");
589 
590  if (routez)
591  {
592  /* OK, linux style /proc/net/route ... we can handle this ... */
593  /* Now that we've got the interfaces, we g0 after the r0ut3Z */
594  if (fgets (buf, sizeof (buf), routez) == NULL) /* Kill the first line */
595  {
596  // /proc/net/route was empty or an error occurred.
597  g_message ("Could not read from /proc/net/route");
598  fclose (routez);
599  return -1;
600  }
601  while (fgets (buf, sizeof (buf), routez))
602  {
603  p = strtok (buf, " \t\n");
604  if (!p)
605  {
606  g_message ("Could not find interface in"
607  " /proc/net/route line");
608  continue;
609  }
610  strncpy (iface, p, sizeof (iface));
611  if ((p = strchr (iface, ':')))
612  {
613  *p = '\0'; /* To support IP aliasing */
614  }
615  p = strtok (NULL, " \t\n");
616  endptr = NULL;
617  dest = strtoul (p, &endptr, 16);
618  g_debug ("ipv4 dest is %s\n", p);
619  if (!endptr || *endptr)
620  {
621  g_message ("Failed to determine Destination from"
622  " /proc/net/route");
623  continue;
624  }
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++)
631  {
632  p = strtok (NULL, " \t\n");
633  if (!p)
634  break;
635  }
636  if (!p)
637  {
638  g_message ("Failed to find field %d in"
639  " /proc/net/route",
640  i + 2);
641  continue;
642  }
643  endptr = NULL;
644  mask = strtoul (p, &endptr, 16);
645  ones = 0;
646  i = 0;
647  while (mask & (1 << i++) && i < 32)
648  ones++;
649  myroutes[*numroutes].mask = ones + 96;
650  g_debug ("mask is %lu\n", myroutes[*numroutes].mask);
651  if (!endptr || *endptr)
652  {
653  g_message ("Failed to determine mask from"
654  " /proc/net/route");
655  continue;
656  }
657 
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))
663  {
664  myroutes[*numroutes].dev = &mydevs[i];
665  break;
666  }
667  if (i == numinterfaces)
668  g_message (
669  "Failed to find interface %s mentioned in /proc/net/route",
670  iface);
671  (*numroutes)++;
672  if (*numroutes >= MAXROUTES)
673  {
674  g_message ("You seem to have WAY to many routes!");
675  break;
676  }
677  }
678  fclose (routez);
679  return 0;
680  }
681  else
682  return -1;
683 }

References myroute::dest6, myroute::dev, myroute::mask, MAXROUTES, 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 
)

Definition at line 686 of file pcap.c.

687 {
688  struct interface_info *mydevs;
689  int i, j;
690  int len;
691  struct in6_addr in6addr;
692  char destaddr[100];
693  int numinterfaces;
694  char buf[1024];
695  char *endptr;
696  FILE *routez;
697  char v6addr[INET6_ADDRSTRLEN];
698  char *token;
699  int cnt;
700 
701  /* Dummy socket for ioctl */
702  mydevs = v6_getinterfaces (&numinterfaces);
703  routez = fopen ("/proc/net/ipv6_route", "r");
704  if (routez)
705  {
706  /* linux style /proc/net/ipv6_route ... we can handle this too... */
707  while (fgets (buf, sizeof (buf), routez) != NULL)
708  {
709  char iface[64];
710 
711  token = strtok (buf, " \t\n");
712  if (token)
713  {
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++)
718  {
719  v6addr[i++] = destaddr[j];
720  if (j % 4 == 3)
721  v6addr[i++] = ':';
722  }
723  v6addr[--i] = '\0';
724  g_debug ("ipv6 dest is %s\n", v6addr);
725  if (inet_pton (AF_INET6, v6addr, &in6addr) <= 0)
726  {
727  g_message ("invalid ipv6 addressd");
728  continue;
729  }
730  memcpy (&myroutes[*numroutes].dest6, &in6addr,
731  sizeof (struct in6_addr));
732  }
733  token = strtok (NULL, " \t\n");
734  if (token)
735  {
736  endptr = NULL;
737  myroutes[*numroutes].mask = strtoul (token, &endptr, 16);
738  }
739  cnt = 7;
740  while (cnt--)
741  {
742  token = strtok (NULL, " \t\n");
743  if (!token)
744  g_message ("getipv6routes error");
745  }
746 
747  bzero (iface, sizeof (iface));
748  token = strtok (NULL, " \t\n");
749  if (token)
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))
754  {
755  myroutes[*numroutes].dev = &mydevs[i];
756  break;
757  }
758  if (i == numinterfaces)
759  g_message (
760  "Failed to find interface %s mentioned in /proc/net/route\n",
761  iface);
762  (*numroutes)++;
763  if (*numroutes >= MAXROUTES)
764  {
765  g_message ("You seem to have WAY to many routes!");
766  break;
767  }
768  }
769  fclose (routez);
770  return 0;
771  }
772  else
773  {
774  g_message ("Didn't find IPv6 routes");
775  return -1;
776  }
777 }

References myroute::dev, myroute::mask, MAXROUTES, 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 
)

Definition at line 204 of file pcap.c.

205 {
206  struct interface_info *mydevs;
207  int numdevs;
208  int i;
209  mydevs = getinterfaces (&numdevs);
210 
211  if (!mydevs)
212  return -1;
213 
214  for (i = 0; i < numdevs; i++)
215  {
216  if (addr->s_addr == mydevs[i].addr.s_addr)
217  {
218  dev[sz - 1] = '\0';
219  strncpy (dev, mydevs[i].name, sz);
220  return 0;
221  }
222  }
223  return -1;
224 }

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:

◆ ipv6addrmask()

static void ipv6addrmask ( struct in6_addr *  in6addr,
int  mask 
)
static

Definition at line 74 of file pcap.c.

75 {
76  int wordmask;
77  int word;
78  uint32_t *ptr;
79  uint32_t addr;
80 
81  word = mask / 32;
82  wordmask = mask % 32;
83  ptr = (uint32_t *) in6addr;
84  switch (word)
85  {
86  case 0:
87  ptr[1] = ptr[2] = ptr[3] = 0;
88  addr = ptr[0];
89  addr = ntohl (addr) >> (32 - wordmask);
90  addr = htonl (addr << (32 - wordmask));
91  ptr[0] = addr;
92  break;
93  case 1:
94  ptr[2] = ptr[3] = 0;
95  addr = ptr[1];
96  addr = ntohl (addr) >> (32 - wordmask);
97  addr = htonl (addr << (32 - wordmask));
98  ptr[1] = addr;
99  break;
100  case 2:
101  ptr[3] = 0;
102  addr = ptr[2];
103  addr = ntohl (addr) >> (32 - wordmask);
104  addr = htonl (addr << (32 - wordmask));
105  ptr[2] = addr;
106  break;
107  case 3:
108  addr = ptr[3];
109  addr = ntohl (addr) >> (32 - wordmask);
110  addr = htonl (addr << (32 - wordmask));
111  ptr[3] = addr;
112  break;
113  }
114 }

References interface_info::addr, and interface_info::mask.

Referenced by v6_is_local_ip(), and v6_routethrough().

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

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

References interface_info::addr, and ipaddr2devname().

Referenced by init_capture_device(), nasl_send_packet(), nasl_tcp_ping(), 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 975 of file pcap.c.

976 {
977  static int initialized = 0;
978  int i;
979  char buf[10240];
980  struct interface_info *mydevs;
981  static struct myroute
982  {
983  struct interface_info *dev;
984  unsigned long mask;
985  unsigned long dest;
986  } myroutes[MAXROUTES];
987  int numinterfaces = 0;
988  char *p, *endptr;
989  char iface[64];
990  static int numroutes = 0;
991  FILE *routez;
992  long match = -1;
993  unsigned long bestmatch = 0;
994 
995  struct in_addr src;
996 
997  gvm_source_addr (&src);
998  if (!dest)
999  {
1000  g_message ("ipaddr2devname passed a NULL dest address");
1001  return NULL;
1002  }
1003 
1004  if (!initialized)
1005  {
1006  /* Dummy socket for ioctl */
1007  initialized = 1;
1008  mydevs = getinterfaces (&numinterfaces);
1009  if (!mydevs)
1010  return NULL;
1011 
1012  routez = fopen ("/proc/net/route", "r");
1013  if (routez)
1014  {
1015  /* OK, linux style /proc/net/route ... we can handle this ... */
1016  /* Now that we've got the interfaces, we g0 after the r0ut3Z */
1017  if (fgets (buf, sizeof (buf), routez)
1018  == NULL) /* Kill the first line */
1019  g_message ("Could not read from /proc/net/route");
1020  while (fgets (buf, sizeof (buf), routez))
1021  {
1022  p = strtok (buf, " \t\n");
1023  if (!p)
1024  {
1025  g_message ("Could not find interface in"
1026  " /proc/net/route line");
1027  continue;
1028  }
1029  strncpy (iface, p, sizeof (iface));
1030  if ((p = strchr (iface, ':')))
1031  {
1032  *p = '\0'; /* To support IP aliasing */
1033  }
1034  p = strtok (NULL, " \t\n");
1035  endptr = NULL;
1036  myroutes[numroutes].dest = strtoul (p, &endptr, 16);
1037  if (!endptr || *endptr)
1038  {
1039  g_message (
1040  "Failed to determine Destination from /proc/net/route");
1041  continue;
1042  }
1043  for (i = 0; i < 6; i++)
1044  {
1045  p = strtok (NULL, " \t\n");
1046  if (!p)
1047  break;
1048  }
1049  if (!p)
1050  {
1051  g_message ("Failed to find field %d in"
1052  " /proc/net/route",
1053  i + 2);
1054  continue;
1055  }
1056  endptr = NULL;
1057  myroutes[numroutes].mask = strtoul (p, &endptr, 16);
1058  if (!endptr || *endptr)
1059  {
1060  g_message ("Failed to determine mask"
1061  " from /proc/net/route");
1062  continue;
1063  }
1064 
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))
1070  {
1071  myroutes[numroutes].dev = &mydevs[i];
1072  break;
1073  }
1074  if (i == numinterfaces)
1075  g_message (
1076  "Failed to find interface %s mentioned in /proc/net/route",
1077  iface);
1078  numroutes++;
1079  if (numroutes >= MAXROUTES)
1080  {
1081  g_message ("You seem to have WAY to many routes!");
1082  break;
1083  }
1084  }
1085  fclose (routez);
1086  }
1087  else
1088  {
1089  g_message ("Could not read from /proc/net/route");
1090  return NULL;
1091  }
1092  }
1093  else
1094  mydevs = getinterfaces (&numinterfaces);
1095  /* WHEW, that takes care of initializing, now we have the easy job of
1096  finding which route matches */
1097  if (mydevs && islocalhost (dest))
1098  {
1099  if (source)
1100  source->s_addr = htonl (0x7F000001);
1101  /* Now we find the localhost interface name, assuming 127.0.0.1 is
1102  localhost (it damn well better be!)... */
1103  for (i = 0; i < numinterfaces; i++)
1104  {
1105  if (mydevs[i].addr.s_addr == htonl (0x7F000001))
1106  {
1107  return mydevs[i].name;
1108  }
1109  }
1110  return NULL;
1111  }
1112 
1113  for (i = 0; i < numroutes; i++)
1114  {
1115  if ((dest->s_addr & myroutes[i].mask) == myroutes[i].dest
1116  && myroutes[i].mask >= bestmatch)
1117  {
1118  if (source)
1119  {
1120  if (src.s_addr != INADDR_ANY)
1121  source->s_addr = src.s_addr;
1122  else
1123  source->s_addr = myroutes[i].dev->addr.s_addr;
1124  }
1125  match = i;
1126  bestmatch = myroutes[i].mask;
1127  }
1128  }
1129  if (match != -1)
1130  return myroutes[match].dev->name;
1131  return NULL;
1132 }

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

Referenced by init_capture_device(), nasl_pcap_next(), 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 335 of file pcap.c.

336 {
337  struct sockaddr_in *saddr;
338  struct sockaddr_in6 *s6addr;
339  static struct interface_info mydevs[1024];
340  int numinterfaces = 0;
341  struct ifaddrs *ifaddr, *ifa;
342  int family;
343 
344  if (getifaddrs (&ifaddr) == -1)
345  {
346  perror ("getifaddrs");
347  }
348  else
349  {
350  for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
351  {
352  if (ifa->ifa_addr == NULL)
353  continue;
354 
355  family = ifa->ifa_addr->sa_family;
356  if (family == AF_INET)
357  {
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));
374  numinterfaces++;
375  }
376  else if (family == AF_INET6)
377  {
378  char ipaddr[INET6_ADDRSTRLEN];
379 
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));
388  numinterfaces++;
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,
393  sizeof (ipaddr)));
394  }
395  else
396  g_debug ("\tfamily is %d\n", ifa->ifa_addr->sa_family);
397  }
398  *howmany = numinterfaces;
399 
400  freeifaddrs (ifaddr);
401  }
402  return mydevs;
403 }

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

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

479 {
480  int sd;
481  struct sockaddr_in sock;
482  unsigned int socklen;
483  unsigned short p1;
484 
485  p1 = (unsigned short) rand ();
486  if (p1 < 5000)
487  p1 += 5000;
488 
489  if (IN6_IS_ADDR_V4MAPPED (dst))
490  {
491  char name[INET6_ADDRSTRLEN];
492 
493  if ((sd = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
494  {
495  perror ("Socket troubles");
496  return 0;
497  }
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))
503  == -1)
504  {
505  close (sd);
506  return 0;
507  }
508  bzero (&sock, sizeof (struct sockaddr_in));
509  socklen = sizeof (struct sockaddr_in);
510  if (getsockname (sd, (struct sockaddr *) &sock, &socklen) == -1)
511  {
512  perror ("getsockname");
513  close (sd);
514  return 0;
515  }
516 
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)));
523  close (sd);
524  }
525  else
526  {
527  struct sockaddr_in6 sock6;
528  char name[INET6_ADDRSTRLEN];
529 
530  if ((sd = socket (AF_INET6, SOCK_DGRAM, 0)) == -1)
531  {
532  perror ("Socket troubles");
533  return 0;
534  }
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))
543  == -1)
544  {
545  close (sd);
546  return 0;
547  }
548  bzero (&sock6, sizeof (struct sockaddr_in6));
549  socklen = sizeof (struct sockaddr_in6);
550  if (getsockname (sd, (struct sockaddr *) &sock6, &socklen) == -1)
551  {
552  perror ("getsockname");
553  close (sd);
554  return 0;
555  }
556 
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)));
564  close (sd);
565  }
566  return 1; /* Calling function responsible for checking validity */
567 }

References name.

Referenced by 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 
)

Definition at line 173 of file pcap.c.

174 {
175  struct interface_info *mydevs;
176  int numdevs = 0;
177  int i;
178  mydevs = v6_getinterfaces (&numdevs);
179 
180  if (!mydevs)
181  return -1;
182 
183  for (i = 0; i < numdevs; i++)
184  {
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))
191  {
192  dev[sz - 1] = '\0';
193  strncpy (dev, mydevs[i].name, sz);
194  return 0;
195  }
196  }
197  return -1;
198 }

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

118 {
119  int ifaces;
120  struct interface_info *ifs;
121  int i;
122  static struct myroute myroutes[MAXROUTES];
123  int numroutes = 0;
124  struct in6_addr in6addr;
125 
126  if ((ifs = v6_getinterfaces (&ifaces)) == NULL)
127  return -1;
128 
129  if (IN6_IS_ADDR_V4MAPPED (addr))
130  {
131  for (i = 0; i < ifaces; i++)
132  {
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))
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  memcpy (&in6addr, addr, sizeof (struct in6_addr));
154  ipv6addrmask (&in6addr, myroutes[i].mask);
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,
158  sizeof (addr2)));
159  if (IN6_ARE_ADDR_EQUAL (&in6addr, &myroutes[i].dest6))
160  {
161  return 1;
162  }
163  }
164  }
165  }
166  return 0;
167 }

References getipv6routes(), ipv6addrmask(), 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 231 of file pcap.c.

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

References interface_info::addr, and v6_ipaddr2devname().

Referenced by init_v6_capture_device(), nasl_islocalhost(), nasl_send_v6packet(), nasl_tcp_v6_ping(), nasl_this_host(), 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 789 of file pcap.c.

790 {
791  static int initialized = 0;
792  int i;
793  struct in6_addr addy;
794  static enum {
795  procroutetechnique,
796  connectsockettechnique,
797  guesstechnique
798  } technique = procroutetechnique;
799  struct interface_info *mydevs;
800  static struct myroute myroutes[MAXROUTES];
801  int numinterfaces = 0;
802  static int numroutes = 0;
803  struct in6_addr in6addr;
804  struct in6_addr src;
805 
806  if (!dest)
807  {
808  g_message ("ipaddr2devname passed a NULL dest address");
809  return NULL;
810  }
811 
812  if (IN6_IS_ADDR_V4MAPPED (dest))
813  gvm_source_addr_as_addr6 (&src);
814  else
815  gvm_source_addr6 (&src);
816 
817  if (!initialized)
818  {
819  /* Dummy socket for ioctl */
820  initialized = 1;
821  mydevs = v6_getinterfaces (&numinterfaces);
822  if (IN6_IS_ADDR_V4MAPPED (dest))
823  {
824  if (getipv4routes (myroutes, &numroutes) < 0)
825  technique = connectsockettechnique;
826  }
827  else
828  {
829  if (getipv6routes (myroutes, &numroutes) < 0)
830  technique = connectsockettechnique;
831  }
832  }
833  else
834  {
835  mydevs = v6_getinterfaces (&numinterfaces);
836  }
837  /* WHEW, that takes care of initializing, now we have the easy job of
838  finding which route matches */
839  if (v6_islocalhost (dest))
840  {
841  if (source)
842  {
843  if (IN6_IS_ADDR_V4MAPPED (source))
844  {
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);
849  }
850  else
851  {
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);
856  }
857  }
858  /* Now we find the localhost interface name, assuming 127.0.0.1
859  or ::1 is localhost (it damn well better be!)... */
860  for (i = 0; i < numinterfaces; i++)
861  {
862  if (IN6_IS_ADDR_V4MAPPED (&mydevs[i].addr6))
863  {
864  if (mydevs[i].addr6.s6_addr32[3] == htonl (0x7F000001))
865  return mydevs[i].name;
866  }
867  else
868  {
869  if (IN6_ARE_ADDR_EQUAL (&in6addr_any, &mydevs[i].addr6))
870  return mydevs[i].name;
871  }
872  }
873  return NULL;
874  }
875 
876  if (technique == procroutetechnique)
877  {
878  for (i = 0; i < numroutes; i++)
879  {
880  char addr1[INET6_ADDRSTRLEN];
881  char addr2[INET6_ADDRSTRLEN];
882 
883  memcpy (&in6addr, dest, sizeof (struct in6_addr));
884  ipv6addrmask (&in6addr, myroutes[i].mask);
885  g_debug (
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))
890  {
891  if (source)
892  {
893  if (!IN6_ARE_ADDR_EQUAL (&src, &in6addr_any))
894  memcpy (source, &src, sizeof (struct in6_addr));
895  else
896  {
897  if (myroutes[i].dev != NULL)
898  {
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));
905  }
906  }
907  }
908  return myroutes[i].dev->name;
909  }
910  technique = connectsockettechnique;
911  }
912  }
913  if (technique == connectsockettechnique)
914  {
915  if (!v6_getsourceip (&addy, dest))
916  return NULL;
917  if (IN6_ARE_ADDR_EQUAL (&addy, &in6addr))
918  {
919  struct hostent *myhostent = NULL;
920  char myname[MAXHOSTNAMELEN + 1];
921 
922  myhostent = gethostbyname (myname);
923  if (gethostname (myname, MAXHOSTNAMELEN) || !myhostent)
924  g_message ("Cannot get hostname!");
925  else if (myhostent->h_addrtype == AF_INET)
926  {
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));
932  }
933  else
934  memcpy (&addy, myhostent->h_addr_list[0], sizeof (struct in6_addr));
935  }
936 
937  /* Now we insure this claimed address is a real interface ... */
938  for (i = 0; i < numinterfaces; i++)
939  {
940  char addr1[INET6_ADDRSTRLEN];
941  char addr2[INET6_ADDRSTRLEN];
942 
943  g_debug (
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))
948  {
949  if (source)
950  {
951  memcpy (source, &addy, sizeof (struct in6_addr));
952  }
953  return mydevs[i].name;
954  }
955  }
956  return NULL;
957  }
958  else
959  g_message ("%s: Provided technique is neither proc route nor"
960  " connect socket",
961  __FUNCTION__);
962  return NULL;
963 }

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

Referenced by 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:
getipv6routes
int getipv6routes(struct myroute *myroutes, int *numroutes)
Definition: pcap.c:686
getipv4routes
int getipv4routes(struct myroute *myroutes, int *numroutes)
Definition: pcap.c:570
v6_getinterfaces
struct interface_info * v6_getinterfaces(int *howmany)
Definition: pcap.c:335
myroute::mask
unsigned long mask
Definition: pcap.c:62
interface_info::addr6
struct in6_addr addr6
Definition: pcap.c:54
getinterfaces
struct interface_info * getinterfaces(int *howmany)
Definition: pcap.c:410
v6_ipaddr2devname
int v6_ipaddr2devname(char *dev, int sz, struct in6_addr *addr)
Definition: pcap.c:173
name
const char * name
Definition: nasl_init.c:377
v6_getsourceip
int v6_getsourceip(struct in6_addr *src, struct in6_addr *dst)
Definition: pcap.c:478
islocalhost
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:268
MAXROUTES
#define MAXROUTES
Definition: pcap.c:42
ipv6addrmask
static void ipv6addrmask(struct in6_addr *in6addr, int mask)
Definition: pcap.c:74
myroute::dev
struct interface_info * dev
Definition: pcap.c:60
interface_info::name
char name[64]
Definition: pcap.c:52
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: pcap.c:231
myroute
Definition: pcap.c:58
interface_info
Definition: pcap.c:50
interface_info::addr
struct in_addr addr
Definition: pcap.c:53
interface_info::mask
struct in6_addr mask
Definition: pcap.c:55
myroute::dest
unsigned long dest
Definition: pcap.c:63
ipaddr2devname
int ipaddr2devname(char *dev, int sz, struct in_addr *addr)
Definition: pcap.c:204
myroute::dest6
struct in6_addr dest6
Definition: pcap.c:61