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.
 
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 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}
int v6_getsourceip(struct in6_addr *src, struct in6_addr *dst)
Definition: pcap.c:477
char * get_iface_from_ip(const char *local_ip)
Given an IP address, determines which interface belongs to.
Definition: pcap.c:1270

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

◆ 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}
const char * name
Definition: nasl_init.c:411
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
struct interface_info * getinterfaces(int *howmany)
Definition: pcap.c:403
#define MAX_IFACE_NAME_LEN
Maximum length of an interface's name.
Definition: pcap.c:40
#define MAXROUTES
Definition: pcap.c:29
char name[MAX_IFACE_NAME_LEN]
Definition: pcap.c:44
Definition: pcap.c:55
unsigned long mask
Definition: pcap.c:58
unsigned long metric
Definition: pcap.c:60
unsigned long dest
Definition: pcap.c:59
struct interface_info * dev
Definition: pcap.c:56

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 *  src,
struct in6_addr *  dst 
)

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 *  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}
struct interface_info * v6_getinterfaces(int *howmany)
Definition: pcap.c:328
int getipv6routes(struct myroute *myroutes, int *numroutes)
Get the IPv6 routes and number of routes.
Definition: pcap.c:719
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

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 *  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}
static int v6_ipaddr2devname(char *dev, int sz, struct in6_addr *addr)
Definition: pcap.c:166

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}
static int getipv4routes(struct myroute *myroutes, int *numroutes)
Get the ipv4 routes and number of routes.
Definition: pcap.c:581
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

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: