OpenVAS Scanner 23.32.3
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.
int v6_islocalhost (struct in6_addr *)
 Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface.
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.
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.
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.
int get_iface_index (struct in6_addr *, int *)
 Get the interface index depending on the target's IP.

Detailed Description

Header file for module pcap.

Definition in file pcap_openvas.h.

Function Documentation

◆ get_datalink_size()

int get_datalink_size ( int datalink)

Definition at line 298 of file pcap.c.

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

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

Here is the caller graph for this function:

◆ get_iface_from_ip()

char * get_iface_from_ip ( const char * local_ip)

Given an IP address, determines which interface belongs to.

Parameters
local_ipIP address.
Returns
Iface name if found, Null otherwise.

Definition at line 1280 of file pcap.c.

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

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

1335{
1336 struct in6_addr src_addr;
1337 char *if_name, *ip_address;
1338
1339 // We get the local address to use, with the remote address.
1340 memset (&src_addr, '\0', sizeof (struct in6_addr));
1341 v6_getsourceip (&src_addr, ipaddr);
1342 ip_address = addr6_as_str (&src_addr);
1343
1344 // Once with the local ip address, we get the source iface name
1345 if_name = get_iface_from_ip (ip_address);
1346 g_free (ip_address);
1347 if (!if_name)
1348 {
1349 g_debug ("%s: Missing interface name", __func__);
1350 return -1;
1351 }
1352
1353 *ifindex = if_nametoindex (if_name);
1354
1355 return 0;
1356}
int v6_getsourceip(struct in6_addr *src, struct in6_addr *dst)
Definition pcap.c:487
char * get_iface_from_ip(const char *local_ip)
Given an IP address, determines which interface belongs to.
Definition pcap.c:1280

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 * addr)

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

Definition at line 271 of file pcap.c.

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

◆ routethrough()

char * routethrough ( struct in_addr * dest,
struct in_addr * source )

An awesome function to determine what interface a packet to a given destination should be routed through.

It returns NULL if no appropriate interface is found, otherwise it returns the device name and fills in the source parameter. Some of the stuff is from Stevens' Unix Network Programming V2. He had an easier suggestion for doing this (in the book), but it isn't portable :(

Definition at line 1070 of file pcap.c.

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

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

Referenced by Ensure(), Ensure(), Ensure(), Ensure(), Ensure(), init_capture_device(), nasl_pcap_next(), nasl_send_arp_request(), nasl_send_capture(), nasl_tcp_ping(), and openbpf().

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

◆ v6_getsourceip()

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

Definition at line 487 of file pcap.c.

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

References name.

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

Here is the caller graph for this function:

◆ v6_is_local_ip()

int v6_is_local_ip ( struct in6_addr * addr)

Definition at line 115 of file pcap.c.

116{
117 int i, j, ifaces, numroutes = 0;
118 struct interface_info *ifs;
119 static struct myroute myroutes[MAXROUTES];
120 struct in6_addr network, mask;
121
122 if ((ifs = v6_getinterfaces (&ifaces)) == NULL)
123 return -1;
124
125 if (IN6_IS_ADDR_V4MAPPED (addr))
126 {
127 for (i = 0; i < ifaces; i++)
128 {
129 int if_net = ifs[i].mask.s6_addr32[3] & ifs[i].addr6.s6_addr32[3];
130 int addr_net = addr->s6_addr32[3] & ifs[i].mask.s6_addr32[3];
131 g_debug ("iface %s", ifs[i].name);
132 DEBUG_IPV4 (if_net)
133 DEBUG_IPV4 (addr_net)
134 DEBUG_IPV4 (ifs[i].mask.s6_addr32[3])
135
136 if (if_net == addr_net && addr_net)
137 return 1;
138 }
139 }
140 else
141 {
142 if (IN6_IS_ADDR_LINKLOCAL (addr))
143 return 1;
144 if (IN6_IS_ADDR_LOOPBACK (addr))
145 return 1;
146 if (getipv6routes (myroutes, &numroutes) == 0)
147 {
148 for (i = 0; i < numroutes; i++)
149 {
150 char addr1[INET6_ADDRSTRLEN];
151 char addr2[INET6_ADDRSTRLEN];
152
153 if (ipv6_prefix_to_mask (myroutes[i].mask, &mask) == -1)
154 return -1;
155 for (j = 0; j < (int) sizeof (struct in6_addr); j++)
156 network.s6_addr[j] = addr->s6_addr[j] & mask.s6_addr[j];
157
158 g_debug ("comparing addresses %s and %s",
159 inet_ntop (AF_INET6, &network, addr1, sizeof (addr1)),
160 inet_ntop (AF_INET6, &myroutes[i].dest6, addr2,
161 sizeof (addr2)));
162 if (IN6_ARE_ADDR_EQUAL (&network, &myroutes[i].dest6))
163 {
164 return 1;
165 }
166 }
167 }
168 }
169 return 0;
170}
struct interface_info * v6_getinterfaces(int *howmany)
Definition pcap.c:338
int getipv6routes(struct myroute *myroutes, int *numroutes)
Get the IPv6 routes and number of routes.
Definition pcap.c:729
static int ipv6_prefix_to_mask(unsigned prefix, struct in6_addr *mask)
Generate an ipv6 mask from the given ipv6 prefix.
Definition pcap.c:89
#define DEBUG_IPV4(x)
Definition pcap.c:44
struct in6_addr addr6
Definition pcap.c:53
struct in6_addr mask
Definition pcap.c:54

References interface_info::addr6, DEBUG_IPV4, getipv6routes(), ipv6_prefix_to_mask(), interface_info::mask, MAXROUTES, name, and v6_getinterfaces().

Referenced by nasl_islocalnet().

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

◆ v6_islocalhost()

int v6_islocalhost ( struct in6_addr * addr)

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

Definition at line 234 of file pcap.c.

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

References interface_info::addr, and v6_ipaddr2devname().

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

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

◆ v6_routethrough()

char * v6_routethrough ( struct in6_addr * dest,
struct in6_addr * source )

An awesome function to determine what interface a packet to a given destination should be routed through.

It returns NULL if no appropriate interface is found, otherwise it returns the device name and fills in the source parameter. Some of the stuff is from Stevens' Unix Network Programming V2. He had an easier suggestion for doing this (in the book), but it isn't portable :(

Definition at line 851 of file pcap.c.

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

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

Referenced by get_mtu(), init_v6_capture_device(), nasl_pcap_next(), nasl_send_capture(), nasl_tcp_v6_ping(), and v6_openbpf().

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