OpenVAS Libraries  9.0.3
pcap_openvas.h File Reference
#include <pcap.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 v6_get_mac_addr (struct in6_addr *, char **)
 We send an empty UDP packet to the remote host, and read back its mac. More...
 
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 *)
 

Function Documentation

◆ get_datalink_size()

int get_datalink_size ( int  )

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:

◆ 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 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 }
int ipaddr2devname(char *dev, int sz, struct in_addr *addr)
Definition: pcap.c:351

◆ 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_getsourceip()

int v6_getsourceip ( struct in6_addr *  ,
struct in6_addr *   
)

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_is_local_ip()

int v6_is_local_ip ( struct in6_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 *  )

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: