aboutsummaryrefslogtreecommitdiff
path: root/networking/traceroute.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/traceroute.c')
-rw-r--r--networking/traceroute.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/networking/traceroute.c b/networking/traceroute.c
index ce8dc8395..5d39ae3cf 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -371,6 +371,8 @@ struct globals {
371static int 371static int
372ifaddrlist(struct IFADDRLIST **ipaddrp) 372ifaddrlist(struct IFADDRLIST **ipaddrp)
373{ 373{
374 enum { IFREQ_BUFSIZE = (32 * 1024) / sizeof(struct ifreq) };
375
374 int fd, nipaddr; 376 int fd, nipaddr;
375#ifdef HAVE_SOCKADDR_SA_LEN 377#ifdef HAVE_SOCKADDR_SA_LEN
376 int n; 378 int n;
@@ -379,22 +381,24 @@ ifaddrlist(struct IFADDRLIST **ipaddrp)
379 struct sockaddr_in *addr_sin; 381 struct sockaddr_in *addr_sin;
380 struct IFADDRLIST *al; 382 struct IFADDRLIST *al;
381 struct ifconf ifc; 383 struct ifconf ifc;
382 struct ifreq ibuf[(32 * 1024) / sizeof(struct ifreq)], ifr; 384 struct ifreq ifr;
385 /* Was on stack, but 32k is a bit too much: */
386 struct ifreq *ibuf = xmalloc(IFREQ_BUFSIZE * sizeof(ibuf[0]));
383 struct IFADDRLIST *st_ifaddrlist; 387 struct IFADDRLIST *st_ifaddrlist;
384 388
385 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 389 fd = xsocket(AF_INET, SOCK_DGRAM, 0);
386 390
387 ifc.ifc_len = sizeof(ibuf); 391 ifc.ifc_len = IFREQ_BUFSIZE * sizeof(ibuf[0]);
388 ifc.ifc_buf = (caddr_t)ibuf; 392 ifc.ifc_buf = (caddr_t)ibuf;
389 393
390 if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 || 394 if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0
391 ifc.ifc_len < sizeof(struct ifreq)) { 395 || ifc.ifc_len < sizeof(struct ifreq)
396 ) {
392 if (errno == EINVAL) 397 if (errno == EINVAL)
393 bb_error_msg_and_die( 398 bb_error_msg_and_die(
394 "SIOCGIFCONF: ifreq struct too small (%d bytes)", 399 "SIOCGIFCONF: ifreq struct too small (%d bytes)",
395 (int)sizeof(ibuf)); 400 IFREQ_BUFSIZE * sizeof(ibuf[0]));
396 else 401 bb_perror_msg_and_die("SIOCGIFCONF");
397 bb_perror_msg_and_die("SIOCGIFCONF");
398 } 402 }
399 ifrp = ibuf; 403 ifrp = ibuf;
400 ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len); 404 ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len);
@@ -449,9 +453,10 @@ ifaddrlist(struct IFADDRLIST **ipaddrp)
449 ++nipaddr; 453 ++nipaddr;
450 } 454 }
451 if (nipaddr == 0) 455 if (nipaddr == 0)
452 bb_error_msg_and_die ("can't find any network interfaces"); 456 bb_error_msg_and_die("can't find any network interfaces");
453 (void)close(fd);
454 457
458 free(ibuf);
459 close(fd);
455 *ipaddrp = st_ifaddrlist; 460 *ipaddrp = st_ifaddrlist;
456 return nipaddr; 461 return nipaddr;
457} 462}
@@ -492,11 +497,13 @@ findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from)
492 ++n; 497 ++n;
493 if (n == 1 && strncmp(buf, "Iface", 5) == 0) 498 if (n == 1 && strncmp(buf, "Iface", 5) == 0)
494 continue; 499 continue;
495 if ((i = sscanf(buf, "%255s %x %*s %*s %*s %*s %*s %x", 500 i = sscanf(buf, "%255s %x %*s %*s %*s %*s %*s %x",
496 tdevice, &dest, &tmask)) != 3) 501 tdevice, &dest, &tmask);
497 bb_error_msg_and_die ("junk in buffer"); 502 if (i != 3)
498 if ((to->sin_addr.s_addr & tmask) == dest && 503 bb_error_msg_and_die("junk in buffer");
499 (tmask > mask || mask == 0)) { 504 if ((to->sin_addr.s_addr & tmask) == dest
505 && (tmask > mask || mask == 0)
506 ) {
500 mask = tmask; 507 mask = tmask;
501 strcpy(device, tdevice); 508 strcpy(device, tdevice);
502 } 509 }
@@ -504,7 +511,7 @@ findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from)
504 fclose(f); 511 fclose(f);
505 512
506 if (device[0] == '\0') 513 if (device[0] == '\0')
507 bb_error_msg_and_die ("can't find interface"); 514 bb_error_msg_and_die("can't find interface");
508 515
509 /* Get the interface address list */ 516 /* Get the interface address list */
510 n = ifaddrlist(&al); 517 n = ifaddrlist(&al);
@@ -808,7 +815,7 @@ packet_ok(unsigned char *buf, int cc, struct sockaddr_in *from, int seq)
808 "%s: icmp type %d (%s) code %d\n", 815 "%s: icmp type %d (%s) code %d\n",
809 cc, inet_ntoa(from->sin_addr), 816 cc, inet_ntoa(from->sin_addr),
810 inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code); 817 inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
811 for (i = 4; i < cc ; i += sizeof(*lp)) 818 for (i = 4; i < cc; i += sizeof(*lp))
812 printf("%2d: x%8.8x\n", i, *lp++); 819 printf("%2d: x%8.8x\n", i, *lp++);
813 } 820 }
814#endif 821#endif