OpenVAS Scanner  22.7.9
pcap_openvas.h File Reference

Header file for module pcap. More...

#include <arpa/inet.h>
#include <pcap.h>
#include <sys/param.h>
Include dependency graph for pcap_openvas.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int v6_is_local_ip (struct in6_addr *)
 
int islocalhost (struct in_addr *)
 Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface. More...
 
int v6_islocalhost (struct in6_addr *)
 Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface. More...
 
int get_datalink_size (int)
 
char * routethrough (struct in_addr *, struct in_addr *)
 An awesome function to determine what interface a packet to a given destination should be routed through. More...
 
char * v6_routethrough (struct in6_addr *, struct in6_addr *)
 An awesome function to determine what interface a packet to a given destination should be routed through. More...
 
int v6_getsourceip (struct in6_addr *, struct in6_addr *)
 
char * get_iface_from_ip (const char *)
 Given an IP address, determines which interface belongs to. More...
 
int get_iface_index (struct in6_addr *, int *)
 Get the interface index depending on the target's IP. More...
 

Detailed Description

Header file for module pcap.

Definition in file pcap_openvas.h.

Function Documentation

◆ get_datalink_size()

int get_datalink_size ( int  )

Definition at line 288 of file pcap.c.

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

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

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

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

1325 {
1326  struct in6_addr src_addr;
1327  char *if_name, *ip_address;
1328 
1329  // We get the local address to use, with the remote address.
1330  memset (&src_addr, '\0', sizeof (struct in6_addr));
1331  v6_getsourceip (&src_addr, ipaddr);
1332  ip_address = addr6_as_str (&src_addr);
1333 
1334  // Once with the local ip address, we get the source iface name
1335  if_name = get_iface_from_ip (ip_address);
1336  g_free (ip_address);
1337  if (!if_name)
1338  {
1339  g_debug ("%s: Missing interface name", __func__);
1340  return -1;
1341  }
1342 
1343  *ifindex = if_nametoindex (if_name);
1344 
1345  return 0;
1346 }

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:

◆ islocalhost()

int islocalhost ( struct in_addr *  )

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

Definition at line 261 of file pcap.c.

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

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

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

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

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

int v6_getsourceip ( struct in6_addr *  ,
struct in6_addr *   
)

Definition at line 477 of file pcap.c.

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

References name.

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

Here is the caller graph for this function:

◆ v6_is_local_ip()

int v6_is_local_ip ( struct in6_addr *  )

Definition at line 108 of file pcap.c.

109 {
110  int i, j, ifaces, numroutes = 0;
111  struct interface_info *ifs;
112  static struct myroute myroutes[MAXROUTES];
113  struct in6_addr network, mask;
114  bpf_u_int32 v4mappednet, v4mappedmask;
115 
116  if ((ifs = v6_getinterfaces (&ifaces)) == NULL)
117  return -1;
118 
119  if (IN6_IS_ADDR_V4MAPPED (addr))
120  {
121  for (i = 0; i < ifaces; i++)
122  {
123  char errbuf[PCAP_ERRBUF_SIZE];
124  pcap_lookupnet (ifs[i].name, &v4mappednet, &v4mappedmask, errbuf);
125  if ((v4mappednet & v4mappedmask)
126  == (addr->s6_addr32[3] & v4mappedmask))
127  return 1;
128  }
129  }
130  else
131  {
132  if (IN6_IS_ADDR_LINKLOCAL (addr))
133  return 1;
134  if (IN6_IS_ADDR_LOOPBACK (addr))
135  return 1;
136  if (getipv6routes (myroutes, &numroutes) == 0)
137  {
138  for (i = 0; i < numroutes; i++)
139  {
140  char addr1[INET6_ADDRSTRLEN];
141  char addr2[INET6_ADDRSTRLEN];
142 
143  if (ipv6_prefix_to_mask (myroutes[i].mask, &mask) == -1)
144  return -1;
145  for (j = 0; j < (int) sizeof (struct in6_addr); j++)
146  network.s6_addr[j] = addr->s6_addr[j] & mask.s6_addr[j];
147 
148  g_debug ("comparing addresses %s and %s",
149  inet_ntop (AF_INET6, &network, addr1, sizeof (addr1)),
150  inet_ntop (AF_INET6, &myroutes[i].dest6, addr2,
151  sizeof (addr2)));
152  if (IN6_ARE_ADDR_EQUAL (&network, &myroutes[i].dest6))
153  {
154  return 1;
155  }
156  }
157  }
158  }
159  return 0;
160 }

References getipv6routes(), ipv6_prefix_to_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 *  )

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

Definition at line 224 of file pcap.c.

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

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

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

References myroute::dev, getipv4routes(), getipv6routes(), ipv6_prefix_to_mask(), MAXROUTES, myroute::metric, 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:
getipv6routes
int getipv6routes(struct myroute *myroutes, int *numroutes)
Get the IPv6 routes and number of routes.
Definition: pcap.c:719
v6_getinterfaces
struct interface_info * v6_getinterfaces(int *howmany)
Definition: pcap.c:328
getipv4routes
static int getipv4routes(struct myroute *myroutes, int *numroutes)
Get the ipv4 routes and number of routes.
Definition: pcap.c:581
myroute::mask
unsigned long mask
Definition: pcap.c:58
ipv6_prefix_to_mask
static int ipv6_prefix_to_mask(unsigned prefix, struct in6_addr *mask)
Generate an ipv6 mask from the given ipv6 prefix.
Definition: pcap.c:82
getinterfaces
struct interface_info * getinterfaces(int *howmany)
Definition: pcap.c:403
interface_info::name
char name[MAX_IFACE_NAME_LEN]
Definition: pcap.c:44
name
const char * name
Definition: nasl_init.c:411
get_iface_from_ip
char * get_iface_from_ip(const char *local_ip)
Given an IP address, determines which interface belongs to.
Definition: pcap.c:1270
v6_getsourceip
int v6_getsourceip(struct in6_addr *src, struct in6_addr *dst)
Definition: pcap.c:477
v6_ipaddr2devname
static int v6_ipaddr2devname(char *dev, int sz, struct in6_addr *addr)
Definition: pcap.c:166
myroute::metric
unsigned long metric
Definition: pcap.c:60
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:261
ipaddr2devname
static int ipaddr2devname(char *dev, int sz, struct in_addr *addr)
Definition: pcap.c:197
MAXROUTES
#define MAXROUTES
Definition: pcap.c:29
myroute::dev
struct interface_info * dev
Definition: pcap.c:56
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:224
myroute
Definition: pcap.c:55
interface_info
Definition: pcap.c:43
MAX_IFACE_NAME_LEN
#define MAX_IFACE_NAME_LEN
Maximum length of an interface's name.
Definition: pcap.c:40
myroute::dest
unsigned long dest
Definition: pcap.c:59