OpenVAS Libraries  9.0.3
pcap.c File Reference
#include <netinet/in.h>
#include <resolv.h>
#include <pcap.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <ifaddrs.h>
#include "bpf_share.h"
#include "pcap_openvas.h"
#include "openvas_logging.h"
#include "network.h"
#include "support.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
 

Functions

struct interface_infogetinterfaces (int *howmany)
 
struct interface_infov6_getinterfaces (int *howmany)
 
int getipv6routes (struct myroute *myroutes, int *numroutes)
 
int v6_is_local_ip (struct in6_addr *addr)
 
int v6_get_mac_addr (struct in6_addr *addr, char **mac)
 We send an empty UDP packet to the remote host, and read back its mac. More...
 
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 get_random_bytes (void *buf, int numbytes)
 
int v6_getsourceip (struct in6_addr *src, struct in6_addr *dst)
 
int getsourceip (struct in_addr *src, struct in_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

◆ MAXROUTES

#define MAXROUTES   1024

Definition at line 39 of file pcap.c.

Function Documentation

◆ get_datalink_size()

int get_datalink_size ( int  datalink)

Definition at line 442 of file pcap.c.

443 {
444  int offset = -1;
445  switch (datalink)
446  {
447  case DLT_EN10MB:
448  offset = 14;
449  break;
450  case DLT_IEEE802:
451  offset = 22;
452  break;
453  case DLT_NULL:
454  offset = 4;
455  break;
456  case DLT_SLIP:
457 #if (FREEBSD || OPENBSD || NETBSD || BSDI || DARWIN)
458  offset = 16;
459 #else
460  offset = 24; /* Anyone use this??? */
461 #endif
462  break;
463  case DLT_PPP:
464 #if (FREEBSD || OPENBSD || NETBSD || BSDI || DARWIN)
465  offset = 4;
466 #else
467 #ifdef SOLARIS
468  offset = 8;
469 #else
470  offset = 24; /* Anyone use this? */
471 #endif /* ifdef solaris */
472 #endif /* if freebsd || openbsd || netbsd || bsdi */
473  break;
474  case DLT_RAW:
475  offset = 0;
476  break;
477  }
478  return (offset);
479 }

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

Here is the caller graph for this function:

◆ get_random_bytes()

int get_random_bytes ( void *  buf,
int  numbytes 
)

Definition at line 482 of file pcap.c.

483 {
484  static char bytebuf[2048];
485  static char badrandomwarning = 0;
486  static int bytesleft = 0;
487  int res;
488  int tmp;
489  struct timeval tv;
490  FILE *fp = NULL;
491  short *iptr;
492 
493  if (numbytes < 0 || numbytes > 0xFFFF)
494  return -1;
495 
496  if (bytesleft == 0)
497  {
498  fp = fopen ("/dev/urandom", "r");
499  if (!fp)
500  fp = fopen ("/dev/random", "r");
501  if (fp)
502  {
503  res = fread (bytebuf, 1, sizeof (bytebuf), fp);
504  if (res != sizeof (bytebuf))
505  {
506  fclose (fp);
507  fp = NULL;
508  }
509  bytesleft = sizeof (bytebuf);
510  }
511  if (!fp)
512  {
513  unsigned int i;
514 
515  if (badrandomwarning == 0)
516  {
517  badrandomwarning++;
518  }
519  /* Seed our random generator */
520  gettimeofday (&tv, NULL);
521  srand ((tv.tv_sec ^ tv.tv_usec) ^ getpid ());
522 
523  for (i = 0; i < sizeof (bytebuf) / sizeof (short); i++)
524  {
525  iptr = (short *) ((char *) bytebuf + i * sizeof (short));
526  *iptr = rand ();
527  }
528  bytesleft = (sizeof (bytebuf) / sizeof (short)) * sizeof (short);
529  /* ^^^^^^^^^^^^^^^not as meaningless as it looks */
530  }
531  else
532  fclose (fp);
533  }
534  if (numbytes <= bytesleft)
535  { /* we can cover it */
536  memcpy (buf, bytebuf + (sizeof (bytebuf) - bytesleft), numbytes);
537  bytesleft -= numbytes;
538  return 0;
539  }
540 
541  /* We don't have enough */
542  memcpy (buf, bytebuf + (sizeof (bytebuf) - bytesleft), bytesleft);
543  tmp = bytesleft;
544  bytesleft = 0;
545  return get_random_bytes ((char *) buf + tmp, numbytes - tmp);
546 }
int get_random_bytes(void *buf, int numbytes)
Definition: pcap.c:482
struct timeval timeval(unsigned long val)

References timeval().

Referenced by getsourceip(), and v6_getsourceip().

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

631 {
632  static struct interface_info mydevs[1024];
633  int numinterfaces = 0;
634  int sd;
635  int len;
636  char *p;
637  char buf[10240];
638  struct ifconf ifc;
639  struct ifreq *ifr;
640  struct sockaddr_in *sin;
641  char *bufp;
642 
643  /* Dummy socket for ioctl. */
644  sd = socket (AF_INET, SOCK_DGRAM, 0);
645  bzero (buf, sizeof (buf));
646  if (sd < 0)
647  log_legacy_write ("socket in getinterfaces");
648 
649  ifc.ifc_len = sizeof (buf);
650  ifc.ifc_buf = buf;
651  if (ioctl (sd, SIOCGIFCONF, &ifc) < 0)
652  log_legacy_write ("Failed to determine your configured interfaces!");
653 
654  close (sd);
655  if (ifc.ifc_len == 0)
657  ("getinterfaces: SIOCGIFCONF claims you have no network interfaces!");
658 
659  len = sizeof (struct ifmap);
660 
661  for (bufp = buf; bufp && *bufp && (bufp < (buf + ifc.ifc_len));
662  bufp += sizeof (ifr->ifr_name) + len)
663  {
664  ifr = (struct ifreq *) bufp;
665  sin = (struct sockaddr_in *) &ifr->ifr_addr;
666  memcpy (&(mydevs[numinterfaces].addr), (char *) &(sin->sin_addr),
667  sizeof (struct in_addr));
668  /* In case it is a stinkin' alias */
669  if ((p = strchr (ifr->ifr_name, ':')))
670  *p = '\0';
671  strncpy (mydevs[numinterfaces].name, ifr->ifr_name, 63);
672  mydevs[numinterfaces].name[63] = '\0';
673  numinterfaces++;
674  if (numinterfaces == 1023)
675  {
677  ("You seem to have more than 1023 network interfaces."
678  " Things may not work right.");
679  break;
680  }
681  mydevs[numinterfaces].name[0] = '\0';
682  }
683 
684  // If output parameter given, set value
685  if (howmany)
686  *howmany = numinterfaces;
687 
688  return mydevs;
689 }
void log_legacy_write(const char *format,...)
Legacy function to write a log message.
const char * name
Definition: nasl_init.c:524

References log_legacy_write(), interface_info::name, and name.

Referenced by ipaddr2devname().

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

◆ getipv4routes()

int getipv4routes ( struct myroute myroutes,
int *  numroutes 
)

Definition at line 826 of file pcap.c.

827 {
828  struct interface_info *mydevs;
829  int i;
830  int numinterfaces;
831  char buf[1024];
832  char *p, *endptr;
833  char iface[64];
834  FILE *routez;
835  unsigned long dest;
836  struct in_addr inaddr;
837  unsigned long mask;
838  unsigned long ones;
839 
840  /* Dummy socket for ioctl */
841  mydevs = v6_getinterfaces (&numinterfaces);
842 
843  /* Now we must go through several techniques to determine info */
844  routez = fopen ("/proc/net/route", "r");
845 
846  if (routez)
847  {
848  /* OK, linux style /proc/net/route ... we can handle this ... */
849  /* Now that we've got the interfaces, we g0 after the r0ut3Z */
850  if (fgets (buf, sizeof (buf), routez) == NULL) /* Kill the first line */
851  {
852  // /proc/net/route was empty or an error occurred.
853  log_legacy_write ("Could not read from /proc/net/route");
854  fclose (routez);
855  return -1;
856  }
857  while (fgets (buf, sizeof (buf), routez))
858  {
859  p = strtok (buf, " \t\n");
860  if (!p)
861  {
862  log_legacy_write ("Could not find interface in"
863  " /proc/net/route line");
864  continue;
865  }
866  strncpy (iface, p, sizeof (iface));
867  if ((p = strchr (iface, ':')))
868  {
869  *p = '\0'; /* To support IP aliasing */
870  }
871  p = strtok (NULL, " \t\n");
872  endptr = NULL;
873  dest = strtoul (p, &endptr, 16);
874 #ifdef TCPIP_DEBUGGING
875  printf ("ipv4 dest is %s\n", p);
876 #endif
877  if (!endptr || *endptr)
878  {
879  log_legacy_write ("Failed to determine Destination from"
880  " /proc/net/route");
881  continue;
882  }
883  inaddr.s_addr = dest;
884  myroutes[*numroutes].dest6.s6_addr32[0] = 0;
885  myroutes[*numroutes].dest6.s6_addr32[1] = 0;
886  myroutes[*numroutes].dest6.s6_addr32[2] = htonl (0xffff);
887  myroutes[*numroutes].dest6.s6_addr32[3] = inaddr.s_addr;
888  for (i = 0; i < 6; i++)
889  {
890  p = strtok (NULL, " \t\n");
891  if (!p)
892  break;
893  }
894  if (!p)
895  {
896  log_legacy_write ("Failed to find field %d in"
897  " /proc/net/route", i + 2);
898  continue;
899  }
900  endptr = NULL;
901  mask = strtoul (p, &endptr, 16);
902  ones = 0;
903  i = 0;
904  while (mask & (1 << i++) && i < 32)
905  ones++;
906  myroutes[*numroutes].mask = ones + 96;
907 #ifdef TCPIP_DEBUGGING
908  printf ("mask is %lu\n", myroutes[*numroutes].mask);
909 #endif
910  if (!endptr || *endptr)
911  {
912  log_legacy_write ("Failed to determine mask from"
913  " /proc/net/route");
914  continue;
915  }
916 
917 
918 #if TCPIP_DEBUGGING
919  printf ("#%d: for dev %s, The dest is %lX and the mask is %lX\n",
920  *numroutes, iface, myroutes[*numroutes].dest,
921  myroutes[*numroutes].mask);
922 #endif
923  for (i = 0; i < numinterfaces; i++)
924  if (!strcmp (iface, mydevs[i].name))
925  {
926  myroutes[*numroutes].dev = &mydevs[i];
927  break;
928  }
929  if (i == numinterfaces)
931  ("Failed to find interface %s mentioned in /proc/net/route",
932  iface);
933  (*numroutes)++;
934  if (*numroutes >= MAXROUTES)
935  {
936  log_legacy_write ("You seem to have WAY to many routes!");
937  break;
938  }
939  }
940  fclose (routez);
941  return 0;
942  }
943  else
944  return -1;
945 }
struct interface_info * dev
Definition: pcap.c:52
void log_legacy_write(const char *format,...)
Legacy function to write a log message.
struct interface_info * v6_getinterfaces(int *howmany)
Definition: pcap.c:549
struct in6_addr dest6
Definition: pcap.c:53
const char * name
Definition: nasl_init.c:524
unsigned long mask
Definition: pcap.c:54
#define MAXROUTES
Definition: pcap.c:39

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

Here is the call graph for this function:

◆ getipv6routes()

int getipv6routes ( struct myroute myroutes,
int *  numroutes 
)

Definition at line 948 of file pcap.c.

949 {
950  struct interface_info *mydevs;
951  int i, j;
952  int len;
953  struct in6_addr in6addr;
954  char destaddr[100];
955  int numinterfaces;
956  char buf[1024];
957  char *endptr;
958  char iface[64];
959  FILE *routez;
960  char v6addr[INET6_ADDRSTRLEN];
961  char *token;
962  int cnt;
963 
964  /* Dummy socket for ioctl */
965  mydevs = v6_getinterfaces (&numinterfaces);
966  routez = fopen ("/proc/net/ipv6_route", "r");
967  if (routez)
968  {
969  /* linux style /proc/net/ipv6_route ... we can handle this too... */
970  while (fgets (buf, sizeof (buf), routez) != NULL)
971  {
972 #if TCPIP_DEBUGGING
973  printf ("%s\n", buf);
974 #endif
975  token = strtok (buf, " \t\n");
976  if (token)
977  {
978 #if TCPIP_DEBUGGING
979  printf ("first token is %s\n", token);
980 #endif
981  strcpy (destaddr, token);
982  len = strlen (destaddr);
983  for (i = 0, j = 0; j < len; j++)
984  {
985  v6addr[i++] = destaddr[j];
986  if (j % 4 == 3)
987  v6addr[i++] = ':';
988  }
989  v6addr[--i] = '\0';
990 #if TCPIP_DEBUGGING
991  printf ("ipv6 dest is %s\n", v6addr);
992 #endif
993  if (inet_pton (AF_INET6, v6addr, &in6addr) <= 0)
994  {
995  log_legacy_write ("invalid ipv6 addressd");
996  continue;
997  }
998  memcpy (&myroutes[*numroutes].dest6, &in6addr,
999  sizeof (struct in6_addr));
1000  }
1001  token = strtok (NULL, " \t\n");
1002  if (token)
1003  {
1004  endptr = NULL;
1005  myroutes[*numroutes].mask = strtoul (token, &endptr, 16);
1006  }
1007  cnt = 7;
1008  while (cnt--)
1009  {
1010  token = strtok (NULL, " \t\n");
1011  if (!token)
1012  log_legacy_write ("getipv6routes error");
1013  }
1014 
1015  token = strtok (NULL, " \t\n");
1016  if (token)
1017  {
1018  strcpy (iface, token);
1019 #ifdef _DEBUG
1020  printf ("name token is %s\n", token);
1021 #endif
1022  }
1023  for (i = 0; i < numinterfaces; i++)
1024  if (!strcmp (iface, mydevs[i].name)
1025  && !IN6_IS_ADDR_V4MAPPED (&mydevs[i].addr6))
1026  {
1027  myroutes[*numroutes].dev = &mydevs[i];
1028  break;
1029  }
1030  if (i == numinterfaces)
1032  ("Failed to find interface %s mentioned in /proc/net/route\n",
1033  iface);
1034  (*numroutes)++;
1035  if (*numroutes >= MAXROUTES)
1036  {
1037  log_legacy_write ("You seem to have WAY to many routes!");
1038  break;
1039  }
1040  }
1041  fclose (routez);
1042  return 0;
1043  }
1044  else
1045  {
1046  log_legacy_write ("Didn't find IPv6 routes");
1047  return -1;
1048  }
1049 }
struct interface_info * dev
Definition: pcap.c:52
void log_legacy_write(const char *format,...)
Legacy function to write a log message.
struct interface_info * v6_getinterfaces(int *howmany)
Definition: pcap.c:549
const char * name
Definition: nasl_init.c:524
unsigned long mask
Definition: pcap.c:54
#define MAXROUTES
Definition: pcap.c:39

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

Referenced by v6_is_local_ip().

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

◆ getsourceip()

int getsourceip ( struct in_addr *  src,
struct in_addr *  dst 
)

Definition at line 787 of file pcap.c.

788 {
789  int sd;
790  struct sockaddr_in sock;
791  unsigned int socklen = sizeof (struct sockaddr_in);
792  unsigned short p1;
793 
794  get_random_bytes (&p1, 2);
795  if (p1 < 5000)
796  p1 += 5000;
797 
798  if ((sd = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
799  {
800  perror ("Socket troubles");
801  return 0;
802  }
803  sock.sin_family = AF_INET;
804  sock.sin_addr = *dst;
805  sock.sin_port = htons (p1);
806  if (connect (sd, (struct sockaddr *) &sock, sizeof (struct sockaddr_in)) ==
807  -1)
808  {
809  close (sd);
810  return 0;
811  }
812  bzero (&sock, sizeof (struct sockaddr_in));
813  if (getsockname (sd, (struct sockaddr *) &sock, &socklen) == -1)
814  {
815  perror ("getsockname");
816  close (sd);
817  return 0;
818  }
819 
820  src->s_addr = sock.sin_addr.s_addr;
821  close (sd);
822  return 1; /* Calling function responsible for checking validity */
823 }
int get_random_bytes(void *buf, int numbytes)
Definition: pcap.c:482

References get_random_bytes().

Here is the call graph for this function:

◆ ipaddr2devname()

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

Definition at line 351 of file pcap.c.

352 {
353  struct interface_info *mydevs;
354  int numdevs;
355  int i;
356  mydevs = getinterfaces (&numdevs);
357 
358  if (!mydevs)
359  return -1;
360 
361  for (i = 0; i < numdevs; i++)
362  {
363  if (addr->s_addr == mydevs[i].addr.s_addr)
364  {
365  dev[sz - 1] = '\0';
366  strncpy (dev, mydevs[i].name, sz);
367  return 0;
368  }
369  }
370  return -1;
371 }
struct in_addr addr
Definition: pcap.c:45
struct interface_info * getinterfaces(int *howmany)
Definition: pcap.c:630
const char * name
Definition: nasl_init.c:524

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:

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

416 {
417  char dev[128];
418 
419  if (addr == NULL)
420  return -1;
421 
422  /* If it is 0.0.0.0 or starts with 127.0.0.1 then it is
423  probably localhost */
424  if ((addr->s_addr & htonl (0xFF000000)) == htonl (0x7F000000))
425  return 1;
426 
427  if (!addr->s_addr)
428  return 1;
429 
430  /* If it is the same addy as a local interface, then it is
431  probably localhost */
432 
433  if (ipaddr2devname (dev, sizeof (dev), addr) != -1)
434  return 1;
435 
436  /* OK, so to a first approximation, this addy is probably not
437  localhost */
438  return 0;
439 }
struct in_addr addr
Definition: pcap.c:45
int ipaddr2devname(char *dev, int sz, struct in_addr *addr)
Definition: pcap.c:351

References interface_info::addr, and ipaddr2devname().

Referenced by init_capture_device(), nasl_tcp_ping(), and plugin_run_synscan().

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, oterwise 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 1244 of file pcap.c.

1245 {
1246  static int initialized = 0;
1247  int i;
1248  struct in_addr addy;
1249  static enum
1250  { procroutetechnique, connectsockettechnique, guesstechnique } technique =
1251  procroutetechnique;
1252  char buf[10240];
1253  struct interface_info *mydevs;
1254  static struct myroute
1255  {
1256  struct interface_info *dev;
1257  unsigned long mask;
1258  unsigned long dest;
1259  } myroutes[MAXROUTES];
1260  int numinterfaces = 0;
1261  char *p, *endptr;
1262  char iface[64];
1263  static int numroutes = 0;
1264  FILE *routez;
1265  long match = -1;
1266  unsigned long bestmatch = 0;
1267 
1268  struct in_addr src;
1269 
1270  openvas_source_addr (&src);
1271  if (!dest)
1272  log_legacy_write ("ipaddr2devname passed a NULL dest address");
1273 
1274  if (!initialized)
1275  {
1276  /* Dummy socket for ioctl */
1277  initialized = 1;
1278  mydevs = getinterfaces (&numinterfaces);
1279 
1280  /* Now we must go through several techniques to determine info */
1281  routez = fopen ("/proc/net/route", "r");
1282 
1283  if (routez)
1284  {
1285  /* OK, linux style /proc/net/route ... we can handle this ... */
1286  /* Now that we've got the interfaces, we g0 after the r0ut3Z */
1287  if (fgets (buf, sizeof (buf), routez) == NULL) /* Kill the first line */
1288  log_legacy_write ("Could not read from /proc/net/route");
1289  while (fgets (buf, sizeof (buf), routez))
1290  {
1291  p = strtok (buf, " \t\n");
1292  if (!p)
1293  {
1294  log_legacy_write ("Could not find interface in"
1295  " /proc/net/route line");
1296  continue;
1297  }
1298  strncpy (iface, p, sizeof (iface));
1299  if ((p = strchr (iface, ':')))
1300  {
1301  *p = '\0'; /* To support IP aliasing */
1302  }
1303  p = strtok (NULL, " \t\n");
1304  endptr = NULL;
1305  myroutes[numroutes].dest = strtoul (p, &endptr, 16);
1306  if (!endptr || *endptr)
1307  {
1309  ("Failed to determine Destination from /proc/net/route");
1310  continue;
1311  }
1312  for (i = 0; i < 6; i++)
1313  {
1314  p = strtok (NULL, " \t\n");
1315  if (!p)
1316  break;
1317  }
1318  if (!p)
1319  {
1320  log_legacy_write ("Failed to find field %d in"
1321  " /proc/net/route", i + 2);
1322  continue;
1323  }
1324  endptr = NULL;
1325  myroutes[numroutes].mask = strtoul (p, &endptr, 16);
1326  if (!endptr || *endptr)
1327  {
1328  log_legacy_write ("Failed to determine mask"
1329  " from /proc/net/route");
1330  continue;
1331  }
1332 
1333 
1334 #if TCPIP_DEBUGGING
1335  printf ("#%d: for dev %s, The dest is %lX and the mask is %lX\n",
1336  numroutes, iface, myroutes[numroutes].dest,
1337  myroutes[numroutes].mask);
1338 #endif
1339  for (i = 0; i < numinterfaces; i++)
1340  if (!strcmp (iface, mydevs[i].name))
1341  {
1342  myroutes[numroutes].dev = &mydevs[i];
1343  break;
1344  }
1345  if (i == numinterfaces)
1347  ("Failed to find interface %s mentioned in /proc/net/route",
1348  iface);
1349  numroutes++;
1350  if (numroutes >= MAXROUTES)
1351  {
1352  log_legacy_write ("You seem to have WAY to many routes!");
1353  break;
1354  }
1355  }
1356  fclose (routez);
1357  }
1358  else
1359  {
1360  technique = connectsockettechnique;
1361  }
1362  }
1363  else
1364  {
1365  mydevs = getinterfaces (&numinterfaces);
1366  }
1367  /* WHEW, that takes care of initializing, now we have the easy job of
1368  finding which route matches */
1369  if (islocalhost (dest))
1370  {
1371  if (source)
1372  source->s_addr = htonl (0x7F000001);
1373  /* Now we find the localhost interface name, assuming 127.0.0.1 is
1374  localhost (it damn well better be!)... */
1375  for (i = 0; i < numinterfaces; i++)
1376  {
1377  if (mydevs[i].addr.s_addr == htonl (0x7F000001))
1378  {
1379  return mydevs[i].name;
1380  }
1381  }
1382  return NULL;
1383  }
1384 
1385  if (technique == procroutetechnique)
1386  {
1387  for (i = 0; i < numroutes; i++)
1388  {
1389  if ((dest->s_addr & myroutes[i].mask) == myroutes[i].dest && myroutes[i].mask >= bestmatch)
1390  {
1391  if (source)
1392  {
1393  if (src.s_addr != INADDR_ANY)
1394  source->s_addr = src.s_addr;
1395  else
1396  source->s_addr = myroutes[i].dev->addr.s_addr;
1397  }
1398  match = i;
1399  bestmatch = myroutes[i].mask;
1400  }
1401  }
1402  if (match != -1)
1403  return myroutes[match].dev->name;
1404  }
1405  else if (technique == connectsockettechnique)
1406  {
1407  if (!getsourceip (&addy, dest))
1408  return NULL;
1409  if (!addy.s_addr)
1410  { /* Solaris 2.4 */
1411  struct hostent *myhostent = NULL;
1412  char myname[MAXHOSTNAMELEN + 1];
1413  myhostent = gethostbyname (myname);
1414  if (gethostname (myname, MAXHOSTNAMELEN) || !myhostent)
1415  log_legacy_write ("Cannot get hostname!");
1416  memcpy (&(addy.s_addr), myhostent->h_addr_list[0],
1417  sizeof (struct in_addr));
1418  }
1419 
1420  /* Now we insure this claimed address is a real interface ... */
1421  for (i = 0; i < numinterfaces; i++)
1422  if (mydevs[i].addr.s_addr == addy.s_addr)
1423  {
1424  if (source)
1425  {
1426  source->s_addr = addy.s_addr;
1427  }
1428  return mydevs[i].name;
1429  }
1430  return NULL;
1431  }
1432  else
1433  log_legacy_write ("%s: Provided technique is neither proc route"
1434  " nor connect socket", __FUNCTION__);
1435  return NULL;
1436 }
Definition: pcap.c:50
void openvas_source_addr(void *addr)
Gives the source IPv4 address.
struct interface_info * dev
Definition: pcap.c:52
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:415
void log_legacy_write(const char *format,...)
Legacy function to write a log message.
struct interface_info * getinterfaces(int *howmany)
Definition: pcap.c:630
#define MAXHOSTNAMELEN
const char * name
Definition: nasl_init.c:524
unsigned long dest
Definition: pcap.c:55
int getsourceip(struct in_addr *src, struct in_addr *dst)
Definition: pcap.c:787
unsigned long mask
Definition: pcap.c:54
char name[64]
Definition: pcap.c:44
#define MAXROUTES
Definition: pcap.c:39

Referenced by ids_open_sock_tcp(), ids_send(), init_capture_device(), nasl_pcap_next(), nasl_send_capture(), nasl_tcp_ping(), and openbpf().

Here is the caller graph for this function:

◆ v6_get_mac_addr()

int v6_get_mac_addr ( struct in6_addr *  addr,
char **  mac 
)

We send an empty UDP packet to the remote host, and read back its mac.

address.

(we should first interrogate the kernel's arp cache - we may rely on libdnet in the future to do that)

As a bonus, this function works well as a local ping.

Definition at line 171 of file pcap.c.

172 {
173  int soc;
174  struct sockaddr_in soca;
175  struct sockaddr_in6 soca6;
176  int bpf;
177  struct in6_addr me;
178  struct in_addr inaddr;
179  char *iface = v6_routethrough (addr, &me);
180  char filter[255];
181  char *src_host, *dst_host;
182  unsigned char *packet;
183  int len;
184  char hostname[INET6_ADDRSTRLEN];
185 
186  if (IN6_IS_ADDR_V4MAPPED (addr))
187  {
188  soc = socket (AF_INET, SOCK_DGRAM, 0);
189  *mac = NULL;
190  if (soc < 0)
191  return -1;
192 
193  inaddr.s_addr = me.s6_addr32[3];
194  src_host = g_strdup (inet_ntoa (inaddr));
195  inaddr.s_addr = addr->s6_addr32[3];
196  dst_host = g_strdup (inet_ntoa (inaddr));
197  snprintf (filter, sizeof (filter)-1, "ip and (src host %s and dst host %s)",
198  src_host, dst_host);
199  g_free (src_host);
200  g_free (dst_host);
201 
202  bpf = bpf_open_live (iface, filter);
203  if (bpf < 0)
204  {
205  close (soc);
206  return -1;
207  }
208 
209  /*
210  * We only deal with ethernet
211  */
212  if (bpf_datalink (bpf) != DLT_EN10MB)
213  {
214  bpf_close (bpf);
215  close (soc);
216  return -1;
217  }
218 
219 
220  soca.sin_addr.s_addr = addr->s6_addr32[3];
221  soca.sin_port = htons (9); /* or whatever */
222  soca.sin_family = AF_INET;
223  if (sendto (soc, NULL, 0, 0, (struct sockaddr *) &soca, sizeof (soca)) !=
224  0)
225  {
226  bpf_close (bpf);
227  close (soc);
228  return -1;
229  }
230  }
231  else
232  {
233  soc = socket (AF_INET6, SOCK_DGRAM, 0);
234  *mac = NULL;
235  if (soc < 0)
236  return -1;
237  src_host =
238  g_strdup (inet_ntop (AF_INET6, &me, hostname, sizeof (hostname)));
239  dst_host =
240  g_strdup (inet_ntop (AF_INET6, addr, hostname, sizeof (hostname)));
241  snprintf (filter, sizeof (filter)-1,
242  "ip6 and (src host %s and dst host %s)", src_host, dst_host);
243  g_free (src_host);
244  g_free (dst_host);
245 
246 
247  bpf = bpf_open_live (iface, filter);
248  if (bpf < 0)
249  {
250  close (soc);
251  return -1;
252  }
253 
254  /* We only deal with ethernet. */
255  if (bpf_datalink (bpf) != DLT_EN10MB)
256  {
257  bpf_close (bpf);
258  close (soc);
259  return -1;
260  }
261 
262 
263  memcpy (&soca6.sin6_addr, addr, sizeof (struct in6_addr));
264  soca6.sin6_port = htons (9); /* or whatever */
265  soca6.sin6_family = AF_INET6;
266  if (sendto (soc, NULL, 0, 0, (struct sockaddr *) &soca6, sizeof (soca6))
267  != 0)
268  {
269  bpf_close (bpf);
270  close (soc);
271  return -1;
272  }
273  }
274 
275  packet = (unsigned char *) bpf_next (bpf, &len);
276  if (packet)
277  {
278  if (len >= get_datalink_size (bpf_datalink (bpf)))
279  {
280  int i;
281  for (i = 0; i < 6; i++)
282  if (packet[i] != 0xFF)
283  break;
284 
285  if (i == 6)
286  {
287  bpf_close (bpf);
288  close (soc);
289  return 1;
290  }
291 
292  *mac = g_malloc0 (23);
293  snprintf (*mac, 22, "%.2x.%.2x.%.2x.%.2x.%.2x.%.2x",
294  (unsigned char) packet[0], (unsigned char) packet[1],
295  (unsigned char) packet[2], (unsigned char) packet[3],
296  (unsigned char) packet[4], (unsigned char) packet[5]);
297  bpf_close (bpf);
298  close (soc);
299  return 0;
300  }
301  }
302  else
303  {
304  bpf_close (bpf);
305  close (soc);
306  return 1;
307  }
308  return 1; /* keep the compiler happy */
309 }
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 thro...
Definition: pcap.c:1061
void bpf_close(int bpf)
Definition: bpf_share.c:153
int get_datalink_size(int datalink)
Definition: pcap.c:442
int bpf_datalink(int bpf)
Definition: bpf_share.c:146
int bpf_open_live(char *iface, char *filter)
Definition: bpf_share.c:40
u_char * bpf_next(int bpf, int *caplen)
Definition: bpf_share.c:137

References bpf_close(), bpf_datalink(), bpf_next(), bpf_open_live(), get_datalink_size(), and v6_routethrough().

Here is the call graph for this function:

◆ v6_getinterfaces()

struct interface_info * v6_getinterfaces ( int *  howmany)

Definition at line 549 of file pcap.c.

550 {
551  struct sockaddr_in *saddr;
552  struct sockaddr_in6 *s6addr;
553  static struct interface_info mydevs[1024];
554  int numinterfaces = 0;
555  struct ifaddrs *ifaddr, *ifa;
556  int family;
557 
558  if (getifaddrs (&ifaddr) == -1)
559  {
560  perror ("getifaddrs");
561  }
562  else
563  {
564  for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
565  {
566  if (ifa->ifa_addr == NULL)
567  continue;
568 
569  family = ifa->ifa_addr->sa_family;
570  if (family == AF_INET)
571  {
572  memcpy (mydevs[numinterfaces].name, ifa->ifa_name,
573  strlen (ifa->ifa_name));
574  saddr = (struct sockaddr_in *) ifa->ifa_addr;
575  mydevs[numinterfaces].addr6.s6_addr32[0] = 0;
576  mydevs[numinterfaces].addr6.s6_addr32[1] = 0;
577  mydevs[numinterfaces].addr6.s6_addr32[2] = htonl (0xffff);
578  mydevs[numinterfaces].addr6.s6_addr32[3] = saddr->sin_addr.s_addr;
579  saddr = (struct sockaddr_in *) ifa->ifa_netmask;
580  mydevs[numinterfaces].mask.s6_addr32[0] = 0;
581  mydevs[numinterfaces].mask.s6_addr32[1] = 0;
582  mydevs[numinterfaces].mask.s6_addr32[2] = htonl (0xffff);
583  mydevs[numinterfaces].mask.s6_addr32[3] = saddr->sin_addr.s_addr;
584 #ifdef TCPIP_DEBUGGING
585  printf ("interface name is %s\n", ifa->ifa_name);
586  printf ("\tAF_INET family\n");
587  printf ("\taddress is %s\n", inet_ntoa (saddr->sin_addr));
588  printf ("\tnetmask is %s\n", inet_ntoa (saddr->sin_addr));
589 #endif
590  numinterfaces++;
591  }
592  else if (family == AF_INET6)
593  {
594  memcpy (mydevs[numinterfaces].name, ifa->ifa_name,
595  strlen (ifa->ifa_name));
596  s6addr = (struct sockaddr_in6 *) ifa->ifa_addr;
597  memcpy (&(mydevs[numinterfaces].addr6),
598  (char *) &(s6addr->sin6_addr), sizeof (struct in6_addr));
599  s6addr = (struct sockaddr_in6 *) ifa->ifa_netmask;
600  memcpy (&(mydevs[numinterfaces].mask),
601  (char *) &(s6addr->sin6_addr), sizeof (struct in6_addr));
602  numinterfaces++;
603 #ifdef TCPIP_DEBUGGING
604  printf ("\tAF_INET6 family\n");
605  printf ("interface name is %s\n", ifa->ifa_name);
606  printf ("\taddress is %s\n",
607  inet_ntop (AF_INET6, &s6addr->sin6_addr, ipaddr,
608  sizeof (ipaddr)));
609 #endif
610  }
611  else
612  {
613 #ifdef TCPIP_DEBUGGING
614  printf ("\tfamily is %d\n", ifa->ifa_addr->sa_family);
615 #endif
616  }
617  }
618  *howmany = numinterfaces;
619 
620  freeifaddrs (ifaddr);
621  }
622  return mydevs;
623 }
const char * name
Definition: nasl_init.c:524

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

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

Here is the caller graph for this function:

◆ v6_getsourceip()

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

Definition at line 692 of file pcap.c.

693 {
694  int sd;
695  struct sockaddr_in sock;
696  struct sockaddr_in6 sock6;
697  unsigned int socklen;
698  unsigned short p1;
699 
700 #ifdef TCPIP_DEBUGGING
701  char name[INET6_ADDRSTRLEN];
702 #endif
703 
704  get_random_bytes (&p1, 2);
705  if (p1 < 5000)
706  p1 += 5000;
707 
708  if (IN6_IS_ADDR_V4MAPPED (dst))
709  {
710  if ((sd = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
711  {
712  perror ("Socket troubles");
713  return 0;
714  }
715  sock.sin_family = AF_INET;
716  sock.sin_addr.s_addr = dst->s6_addr32[3];
717  sock.sin_port = htons (p1);
718  if (connect (sd, (struct sockaddr *) &sock, sizeof (struct sockaddr_in))
719  == -1)
720  {
721  close (sd);
722  return 0;
723  }
724  bzero (&sock, sizeof (struct sockaddr_in));
725  socklen = sizeof (struct sockaddr_in);
726  if (getsockname (sd, (struct sockaddr *) &sock, &socklen) == -1)
727  {
728  perror ("getsockname");
729  close (sd);
730  return 0;
731  }
732 
733 
734  src->s6_addr32[0] = 0;
735  src->s6_addr32[1] = 0;
736  src->s6_addr32[2] = htonl (0xffff);
737  src->s6_addr32[3] = sock.sin_addr.s_addr;
738 #ifdef TCPIP_DEBUGGING
739  printf ("source addrss is %s\n",
740  inet_ntop (AF_INET6, src, name, sizeof (name)));
741 #endif
742  close (sd);
743  }
744  else
745  {
746  if ((sd = socket (AF_INET6, SOCK_DGRAM, 0)) == -1)
747  {
748  perror ("Socket troubles");
749  return 0;
750  }
751  sock6.sin6_family = AF_INET6;
752  sock6.sin6_addr.s6_addr32[0] = dst->s6_addr32[0];
753  sock6.sin6_addr.s6_addr32[1] = dst->s6_addr32[1];
754  sock6.sin6_addr.s6_addr32[2] = dst->s6_addr32[2];
755  sock6.sin6_addr.s6_addr32[3] = dst->s6_addr32[3];
756  sock6.sin6_port = htons (p1);
757  if (connect (sd, (struct sockaddr *) &sock6, sizeof (struct sockaddr_in6))
758  == -1)
759  {
760  close (sd);
761  return 0;
762  }
763  bzero (&sock6, sizeof (struct sockaddr_in6));
764  socklen = sizeof (struct sockaddr_in6);
765  if (getsockname (sd, (struct sockaddr *) &sock6, &socklen) == -1)
766  {
767  perror ("getsockname");
768  close (sd);
769  return 0;
770  }
771 
772  src->s6_addr32[0] = sock6.sin6_addr.s6_addr32[0];
773  src->s6_addr32[1] = sock6.sin6_addr.s6_addr32[1];
774  src->s6_addr32[2] = sock6.sin6_addr.s6_addr32[2];
775  src->s6_addr32[3] = sock6.sin6_addr.s6_addr32[3];
776  memcpy (src, &sock6.sin6_addr, sizeof (struct in6_addr));
777 #ifdef TCPIP_DEBUGGING
778  printf ("source addrss is %s\n",
779  inet_ntop (AF_INET6, src, name, sizeof (name)));
780 #endif
781  close (sd);
782  }
783  return 1; /* Calling function responsible for checking validity */
784 }
int get_random_bytes(void *buf, int numbytes)
Definition: pcap.c:482
const char * name
Definition: nasl_init.c:524

References get_random_bytes(), and name.

Referenced by nasl_this_host().

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

◆ v6_ipaddr2devname()

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

Definition at line 316 of file pcap.c.

317 {
318  struct interface_info *mydevs;
319  int numdevs;
320  int i;
321  mydevs = v6_getinterfaces (&numdevs);
322 #if TCPIP_DEBUGGING
323  char addr1[INET6_ADDRSTRLEN];
324  char addr2[INET6_ADDRSTRLEN];
325 #endif
326 
327  if (!mydevs)
328  return -1;
329 
330  for (i = 0; i < numdevs; i++)
331  {
332 #if TCPIP_DEBUGGING
333  printf ("comparing addresses %s and %s\n",
334  inet_ntop (AF_INET6, addr, addr1, sizeof (addr1)),
335  inet_ntop (AF_INET6, &mydevs[i].addr6, addr2, sizeof (addr2)));
336 #endif
337  if (IN6_ARE_ADDR_EQUAL (addr, &mydevs[i].addr6))
338  {
339  dev[sz - 1] = '\0';
340  strncpy (dev, mydevs[i].name, sz);
341  return 0;
342  }
343  }
344  return -1;
345 }
struct in_addr addr
Definition: pcap.c:45
struct in6_addr addr6
Definition: pcap.c:46
struct interface_info * v6_getinterfaces(int *howmany)
Definition: pcap.c:549
const char * name
Definition: nasl_init.c:524

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

107 {
108  int ifaces;
109  struct interface_info *ifs;
110  int i;
111  static struct myroute myroutes[MAXROUTES];
112  int numroutes = 0;
113  struct in6_addr in6addr;
114 #if TCPIP_DEBUGGING
115  char addr1[INET6_ADDRSTRLEN];
116  char addr2[INET6_ADDRSTRLEN];
117 #endif
118 
119  if ((ifs = v6_getinterfaces (&ifaces)) == NULL)
120  return -1;
121 
122  if (IN6_IS_ADDR_V4MAPPED (addr))
123  {
124  for (i = 0; i < ifaces; i++)
125  {
126  bpf_u_int32 net, mask;
127  char errbuf[PCAP_ERRBUF_SIZE];
128  pcap_lookupnet (ifs[i].name, &net, &mask, errbuf);
129  if ((net & mask) == (addr->s6_addr32[3] & mask))
130  return 1;
131  }
132  }
133  else
134  {
135  if (IN6_IS_ADDR_LINKLOCAL (addr))
136  return 1;
137  if (IN6_IS_ADDR_LOOPBACK (addr))
138  return 1;
139  if (getipv6routes (myroutes, &numroutes) == 0)
140  {
141  for (i = 0; i < numroutes; i++)
142  {
143  memcpy (&in6addr, addr, sizeof (struct in6_addr));
144  ipv6addrmask (&in6addr, myroutes[i].mask);
145 #if TCPIP_DEBUGGING
146  printf ("comparing addresses %s and %s\n",
147  inet_ntop (AF_INET6, &in6addr, addr1, sizeof (addr1)),
148  inet_ntop (AF_INET6, &myroutes[i].dest6, addr2,
149  sizeof (addr2)));
150 #endif
151  if (IN6_ARE_ADDR_EQUAL (&in6addr, &myroutes[i].dest6))
152  {
153  return 1;
154  }
155  }
156  }
157  }
158  return 0;
159 }
Definition: pcap.c:50
int getipv6routes(struct myroute *myroutes, int *numroutes)
Definition: pcap.c:948
struct interface_info * v6_getinterfaces(int *howmany)
Definition: pcap.c:549
const char * name
Definition: nasl_init.c:524
#define MAXROUTES
Definition: pcap.c:39

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

379 {
380  char dev[128];
381 
382  if (addr == NULL)
383  return -1;
384 
385  if (IN6_IS_ADDR_V4MAPPED (addr))
386  {
387  /* If it is 0.0.0.0 or starts with 127.0.0.1 then it is
388  probably localhost */
389  if ((addr->s6_addr32[3] & htonl (0xFF000000)) == htonl (0x7F000000))
390  return 1;
391 
392  if (!addr->s6_addr32[3])
393  return 1;
394  }
395 
396  if (IN6_IS_ADDR_LOOPBACK (addr))
397  return 1;
398 
399  /* If it is the same addy as a local interface, then it is
400  probably localhost */
401 
402  if (v6_ipaddr2devname (dev, sizeof (dev), addr) != -1)
403  return 1;
404 
405  /* OK, so to a first approximation, this addy is probably not
406  localhost */
407  return 0;
408 }
int v6_ipaddr2devname(char *dev, int sz, struct in6_addr *addr)
Definition: pcap.c:316

References interface_info::addr, and v6_ipaddr2devname().

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

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, oterwise 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 1061 of file pcap.c.

1062 {
1063  static int initialized = 0;
1064  int i;
1065  struct in6_addr addy;
1066  static enum
1067  { procroutetechnique, connectsockettechnique, guesstechnique } technique =
1068  procroutetechnique;
1069  struct interface_info *mydevs;
1070  static struct myroute myroutes[MAXROUTES];
1071  int numinterfaces = 0;
1072  static int numroutes = 0;
1073  struct in6_addr in6addr;
1074 #ifdef TCPIP_DEBUGGING
1075  char addr1[INET6_ADDRSTRLEN];
1076  char addr2[INET6_ADDRSTRLEN];
1077 #endif
1078  struct in6_addr src;
1079 
1080  if (!dest)
1081  log_legacy_write ("ipaddr2devname passed a NULL dest address");
1082 
1083  if (IN6_IS_ADDR_V4MAPPED (dest))
1085  else
1086  openvas_source_addr6 (&src);
1087 
1088  if (!initialized)
1089  {
1090  /* Dummy socket for ioctl */
1091  initialized = 1;
1092  mydevs = v6_getinterfaces (&numinterfaces);
1093  if (IN6_IS_ADDR_V4MAPPED (dest))
1094  {
1095  if (getipv4routes (myroutes, &numroutes) < 0)
1096  technique = connectsockettechnique;
1097  }
1098  else
1099  {
1100  if (getipv6routes (myroutes, &numroutes) < 0)
1101  technique = connectsockettechnique;
1102  }
1103  }
1104  else
1105  {
1106  mydevs = v6_getinterfaces (&numinterfaces);
1107  }
1108  /* WHEW, that takes care of initializing, now we have the easy job of
1109  finding which route matches */
1110  if (v6_islocalhost (dest))
1111  {
1112  if (source)
1113  {
1114  if (IN6_IS_ADDR_V4MAPPED (source))
1115  {
1116  source->s6_addr32[0] = 0;
1117  source->s6_addr32[1] = 0;
1118  source->s6_addr32[2] = htonl (0xffff);
1119  source->s6_addr32[3] = htonl (0x7F000001);
1120  }
1121  else
1122  {
1123  source->s6_addr32[0] = 0;
1124  source->s6_addr32[1] = 0;
1125  source->s6_addr32[2] = 0;
1126  source->s6_addr32[3] = htonl (1);
1127  }
1128  }
1129  /* Now we find the localhost interface name, assuming 127.0.0.1
1130  or ::1 is localhost (it damn well better be!)... */
1131  for (i = 0; i < numinterfaces; i++)
1132  {
1133  if (IN6_IS_ADDR_V4MAPPED (&mydevs[i].addr6))
1134  {
1135  if (mydevs[i].addr6.s6_addr32[3] == htonl (0x7F000001))
1136  return mydevs[i].name;
1137  }
1138  else
1139  {
1140  if (IN6_ARE_ADDR_EQUAL (&in6addr_any, &mydevs[i].addr6))
1141  return mydevs[i].name;
1142  }
1143  }
1144  return NULL;
1145  }
1146 
1147  if (technique == procroutetechnique)
1148  {
1149  for (i = 0; i < numroutes; i++)
1150  {
1151  memcpy (&in6addr, dest, sizeof (struct in6_addr));
1152  ipv6addrmask (&in6addr, myroutes[i].mask);
1153 #if TCPIP_DEBUGGING
1154  printf ("comparing addresses %s and %s\n",
1155  inet_ntop (AF_INET6, &in6addr, addr1, sizeof (addr1)),
1156  inet_ntop (AF_INET6, &myroutes[i].dest6, addr2,
1157  sizeof (addr2)));
1158 #endif
1159  if (IN6_ARE_ADDR_EQUAL (&in6addr, &myroutes[i].dest6))
1160  {
1161  if (source)
1162  {
1163  if (!IN6_ARE_ADDR_EQUAL (&src, &in6addr_any))
1164  memcpy (source, &src, sizeof (struct in6_addr));
1165  else
1166  {
1167  if (myroutes[i].dev != NULL)
1168  {
1169 #if TCPIP_DEBUGGING
1170  printf ("copying address %s\n",
1171  inet_ntop (AF_INET6, &myroutes[i].dev->addr6,
1172  addr1, sizeof (addr1)));
1173  printf ("dev name is %s\n", myroutes[i].dev->name);
1174 #endif
1175  memcpy (source, &myroutes[i].dev->addr6,
1176  sizeof (struct in6_addr));
1177  }
1178  }
1179  }
1180  return myroutes[i].dev->name;
1181  }
1182  technique = connectsockettechnique;
1183  }
1184  }
1185  if (technique == connectsockettechnique)
1186  {
1187  if (!v6_getsourceip (&addy, dest))
1188  return NULL;
1189  if (IN6_ARE_ADDR_EQUAL (&addy, &in6addr))
1190  {
1191  struct hostent *myhostent = NULL;
1192  char myname[MAXHOSTNAMELEN + 1];
1193 
1194  myhostent = gethostbyname (myname);
1195  if (gethostname (myname, MAXHOSTNAMELEN) || !myhostent)
1196  log_legacy_write ("Cannot get hostname!");
1197  if (myhostent->h_addrtype == AF_INET)
1198  {
1199  addy.s6_addr32[0] = 0;
1200  addy.s6_addr32[1] = 0;
1201  addy.s6_addr32[2] = htonl (0xffff);
1202  memcpy (&addy.s6_addr32[0], myhostent->h_addr_list[0],
1203  sizeof (struct in6_addr));
1204  }
1205  else
1206  memcpy (&addy, myhostent->h_addr_list[0], sizeof (struct in6_addr));
1207  }
1208 
1209  /* Now we insure this claimed address is a real interface ... */
1210  for (i = 0; i < numinterfaces; i++)
1211  {
1212 #ifdef TCPIP_DEBUGGING
1213  printf ("comparing addresses %s and %s\n",
1214  inet_ntop (AF_INET6, &mydevs[i].addr6, addr1, sizeof (addr1)),
1215  inet_ntop (AF_INET6, &addy, addr2, sizeof (addr2)));
1216 #endif
1217  if (IN6_ARE_ADDR_EQUAL (&mydevs[i].addr6, &addy))
1218  {
1219  if (source)
1220  {
1221  memcpy (source, &addy, sizeof (struct in6_addr));
1222  }
1223  return mydevs[i].name;
1224  }
1225  }
1226  return NULL;
1227  }
1228  else
1229  log_legacy_write ("%s: Provided technique is neither proc route nor"
1230  " connect socket", __FUNCTION__);
1231  return NULL;
1232 }
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:378
void openvas_source_addr6(void *addr6)
Gives the source IPv6 address.
Definition: pcap.c:50
int v6_getsourceip(struct in6_addr *src, struct in6_addr *dst)
Definition: pcap.c:692
int getipv6routes(struct myroute *myroutes, int *numroutes)
Definition: pcap.c:948
void log_legacy_write(const char *format,...)
Legacy function to write a log message.
struct interface_info * v6_getinterfaces(int *howmany)
Definition: pcap.c:549
#define MAXHOSTNAMELEN
int getipv4routes(struct myroute *myroutes, int *numroutes)
Definition: pcap.c:826
void openvas_source_addr_as_addr6(struct in6_addr *addr6)
Gives the source IPv4 mapped as an IPv6 address. eg. 192.168.20.10 would map to ::ffff:192....
char name[64]
Definition: pcap.c:44
#define MAXROUTES
Definition: pcap.c:39

Referenced by ids_open_sock_tcp(), ids_send(), init_v6_capture_device(), nasl_pcap_next(), nasl_send_capture(), nasl_tcp_v6_ping(), v6_get_mac_addr(), and v6_openbpf().

Here is the caller graph for this function: