OpenVAS Scanner 23.40.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 1283 of file pcap.c.

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

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

1338{
1339 struct in6_addr src_addr;
1340 char *if_name, *ip_address;
1341
1342 // We get the local address to use, with the remote address.
1343 memset (&src_addr, '\0', sizeof (struct in6_addr));
1344 v6_getsourceip (&src_addr, ipaddr);
1345 ip_address = addr6_as_str (&src_addr);
1346
1347 // Once with the local ip address, we get the source iface name
1348 if_name = get_iface_from_ip (ip_address);
1349 g_free (ip_address);
1350 if (!if_name)
1351 {
1352 g_debug ("%s: Missing interface name", __func__);
1353 return -1;
1354 }
1355
1356 *ifindex = if_nametoindex (if_name);
1357
1358 return 0;
1359}
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:1283

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 ("%s: Could not read from /proc/net/route", __func__);
1115 else
1116 {
1117 while (fgets (buf, sizeof (buf), routez) != NULL)
1118 {
1119 p = strtok (buf, " \t\n");
1120 if (!p)
1121 {
1122 g_message ("Could not find interface in"
1123 " /proc/net/route line");
1124 continue;
1125 }
1126 strncpy (iface, p, sizeof (iface) - 1);
1127 iface[MAX_IFACE_NAME_LEN - 1] = '\0';
1128 if ((p = strchr (iface, ':')))
1129 {
1130 *p = '\0'; /* To support IP aliasing */
1131 }
1132 p = strtok (NULL, " \t\n");
1133 endptr = NULL;
1134 myroutes[numroutes].dest = strtoul (p, &endptr, 16);
1135 if (!endptr || *endptr)
1136 {
1137 g_message (
1138 "Failed to determine Destination from /proc/net/route");
1139 continue;
1140 }
1141 for (i = 0; i < 5; i++)
1142 {
1143 p = strtok (NULL, " \t\n");
1144 if (!p)
1145 break;
1146 }
1147 if (!p)
1148 {
1149 g_message ("Failed to find field %d in"
1150 " /proc/net/route",
1151 i + 2);
1152 continue;
1153 }
1154 endptr = NULL;
1155 myroutes[numroutes].metric = strtol (p, &endptr, 10);
1156 if (!endptr || *endptr)
1157 {
1158 g_message ("Failed to determine metric from /proc/net/route");
1159 continue;
1160 }
1161 p = strtok (NULL, " \t\n");
1162 endptr = NULL;
1163 myroutes[numroutes].mask = strtoul (p, &endptr, 16);
1164 if (!endptr || *endptr)
1165 {
1166 g_message ("Failed to determine mask"
1167 " from /proc/net/route");
1168 continue;
1169 }
1170
1171 g_debug ("#%d: for dev %s, The dest is %lX and the mask is %lX",
1172 numroutes, iface, myroutes[numroutes].dest,
1173 myroutes[numroutes].mask);
1174 for (i = 0; i < numinterfaces; i++)
1175 if (!strcmp (iface, mydevs[i].name))
1176 {
1177 myroutes[numroutes].dev = &mydevs[i];
1178 break;
1179 }
1180 if (i == numinterfaces)
1181 g_message (
1182 "Failed to find interface %s mentioned in /proc/net/route",
1183 iface);
1184 numroutes++;
1185 if (numroutes >= MAXROUTES)
1186 {
1187 g_message ("You seem to have WAY to many routes!");
1188 break;
1189 }
1190 }
1191 }
1192 fclose (routez);
1193 }
1194 else
1195 {
1196 g_message ("Could not read from /proc/net/route");
1197 return NULL;
1198 }
1199 }
1200 else
1201 mydevs = getinterfaces (&numinterfaces);
1202 /* WHEW, that takes care of initializing, now we have the easy job of
1203 finding which route matches */
1204 if (mydevs && islocalhost (dest))
1205 {
1206 if (source)
1207 source->s_addr = htonl (0x7F000001);
1208 /* Now we find the localhost interface name, assuming 127.0.0.1 is
1209 localhost (it damn well better be!)... */
1210 for (i = 0; i < numinterfaces; i++)
1211 {
1212 if (mydevs[i].addr.s_addr == htonl (0x7F000001))
1213 {
1214 return mydevs[i].name;
1215 }
1216 }
1217 return NULL;
1218 }
1219
1220 for (i = 0; i < numroutes; i++)
1221 {
1222 /* Matching route found */
1223 if ((dest->s_addr & myroutes[i].mask) == myroutes[i].dest)
1224 {
1225 /* First time a match is found */
1226 if (-1 == best_match)
1227 {
1228 best_match = i;
1229 }
1230 else
1231 {
1232 /* Better match found */
1233 if (myroutes[i].mask > myroutes[best_match].mask)
1234 {
1235 best_match = i;
1236 }
1237 /* Match with equal mask and smaller (better) metric found */
1238 else if ((myroutes[i].mask == myroutes[best_match].mask)
1239 && (myroutes[i].metric < myroutes[best_match].metric))
1240 {
1241 best_match = i;
1242 }
1243 }
1244 }
1245 }
1246
1247 /* Set source */
1248 if (source)
1249 {
1250 /* Source address is given */
1251 if (src.s_addr != INADDR_ANY)
1252 source->s_addr = src.s_addr;
1253 /* Source address is INADDR_ANY and there is a good route */
1254 else if (best_match != -1)
1255 source->s_addr = myroutes[best_match].dev->addr.s_addr;
1256 /* No best route found and no default */
1257 else
1258 {
1259 /* Assigned first route in the table */
1260 if (myroutes[0].dev)
1261 {
1262 source->s_addr = myroutes[0].dev->addr.s_addr;
1263 best_match = 0;
1264 }
1265 /* or any */
1266 else
1267 source->s_addr = INADDR_ANY;
1268 }
1269 }
1270
1271 if (best_match != -1)
1272 return myroutes[best_match].dev->name;
1273 return NULL;
1274}
const char * name
Definition nasl_init.c:440
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: