summaryrefslogtreecommitdiff
path: root/networking/libiproute
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2007-04-12 11:34:39 +0000
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2007-04-12 11:34:39 +0000
commitb290889f0265e1278e8a868aa82a65bcc9099b0f (patch)
tree2fc8dcc3b7f525f61817417e32c2827b57e17b8a /networking/libiproute
parent51742f4bb0c57a4d5063ece9437a2f34a42e52c8 (diff)
downloadbusybox-w32-b290889f0265e1278e8a868aa82a65bcc9099b0f.tar.gz
busybox-w32-b290889f0265e1278e8a868aa82a65bcc9099b0f.tar.bz2
busybox-w32-b290889f0265e1278e8a868aa82a65bcc9099b0f.zip
- add xsendto and use where appropriate; shrink iplink; sanitize libiproute a bit.
-916 byte
Diffstat (limited to 'networking/libiproute')
-rw-r--r--networking/libiproute/ipaddress.c42
-rw-r--r--networking/libiproute/iplink.c75
-rw-r--r--networking/libiproute/iproute.c74
-rw-r--r--networking/libiproute/iprule.c15
-rw-r--r--networking/libiproute/libnetlink.c66
-rw-r--r--networking/libiproute/libnetlink.h10
-rw-r--r--networking/libiproute/ll_map.c37
-rw-r--r--networking/libiproute/ll_map.h2
-rw-r--r--networking/libiproute/utils.h2
9 files changed, 127 insertions, 196 deletions
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index ab9706492..4f83924ae 100644
--- a/networking/libiproute/ipaddress.c
+++ b/networking/libiproute/ipaddress.c
@@ -486,22 +486,13 @@ int ipaddr_list_or_flush(int argc, char **argv, int flush)
486 argc--; 486 argc--;
487 } 487 }
488 488
489 if (rtnl_open(&rth, 0) < 0) 489 xrtnl_open(&rth);
490 exit(1);
491 490
492 if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK) < 0) { 491 xrtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK);
493 bb_perror_msg_and_die("cannot send dump request"); 492 xrtnl_dump_filter(&rth, store_nlmsg, &linfo);
494 }
495
496 if (rtnl_dump_filter(&rth, store_nlmsg, &linfo, NULL, NULL) < 0) {
497 bb_error_msg_and_die("dump terminated");
498 }
499 493
500 if (filter_dev) { 494 if (filter_dev) {
501 filter.ifindex = ll_name_to_index(filter_dev); 495 filter.ifindex = xll_name_to_index(filter_dev);
502 if (filter.ifindex <= 0) {
503 bb_error_msg_and_die("device \"%s\" does not exist", filter_dev);
504 }
505 } 496 }
506 497
507 if (flush) { 498 if (flush) {
@@ -513,13 +504,9 @@ int ipaddr_list_or_flush(int argc, char **argv, int flush)
513 filter.rth = &rth; 504 filter.rth = &rth;
514 505
515 for (;;) { 506 for (;;) {
516 if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { 507 xrtnl_wilddump_request(&rth, filter.family, RTM_GETADDR);
517 bb_perror_msg_and_die("cannot send dump request");
518 }
519 filter.flushed = 0; 508 filter.flushed = 0;
520 if (rtnl_dump_filter(&rth, print_addrinfo, stdout, NULL, NULL) < 0) { 509 xrtnl_dump_filter(&rth, print_addrinfo, stdout);
521 bb_error_msg_and_die("flush terminated");
522 }
523 if (filter.flushed == 0) { 510 if (filter.flushed == 0) {
524 return 0; 511 return 0;
525 } 512 }
@@ -529,13 +516,8 @@ int ipaddr_list_or_flush(int argc, char **argv, int flush)
529 } 516 }
530 517
531 if (filter.family != AF_PACKET) { 518 if (filter.family != AF_PACKET) {
532 if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { 519 xrtnl_wilddump_request(&rth, filter.family, RTM_GETADDR);
533 bb_perror_msg_and_die("cannot send dump request"); 520 xrtnl_dump_filter(&rth, store_nlmsg, &ainfo);
534 }
535
536 if (rtnl_dump_filter(&rth, store_nlmsg, &ainfo, NULL, NULL) < 0) {
537 bb_error_msg_and_die("dump terminated");
538 }
539 } 521 }
540 522
541 523
@@ -779,15 +761,11 @@ static int ipaddr_modify(int cmd, int argc, char **argv)
779 if (!scoped && cmd != RTM_DELADDR) 761 if (!scoped && cmd != RTM_DELADDR)
780 req.ifa.ifa_scope = default_scope(&lcl); 762 req.ifa.ifa_scope = default_scope(&lcl);
781 763
782 if (rtnl_open(&rth, 0) < 0) 764 xrtnl_open(&rth);
783 exit(1);
784 765
785 ll_init_map(&rth); 766 ll_init_map(&rth);
786 767
787 req.ifa.ifa_index = ll_name_to_index(d); 768 req.ifa.ifa_index = xll_name_to_index(d);
788 if (req.ifa.ifa_index == 0) {
789 bb_error_msg_and_die("cannot find device \"%s\"", d);
790 }
791 769
792 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) 770 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
793 return 2; 771 return 2;
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c
index 0943726e1..5feab1e49 100644
--- a/networking/libiproute/iplink.c
+++ b/networking/libiproute/iplink.c
@@ -42,10 +42,7 @@ static int get_ctl_fd(void)
42 fd = socket(PF_PACKET, SOCK_DGRAM, 0); 42 fd = socket(PF_PACKET, SOCK_DGRAM, 0);
43 if (fd >= 0) 43 if (fd >= 0)
44 return fd; 44 return fd;
45 fd = socket(PF_INET6, SOCK_DGRAM, 0); 45 return xsocket(PF_INET6, SOCK_DGRAM, 0);
46 if (fd >= 0)
47 return fd;
48 bb_perror_msg_and_die("cannot create control socket");
49} 46}
50 47
51/* Exits on error */ 48/* Exits on error */
@@ -125,10 +122,7 @@ static int get_address(char *dev, int *htype)
125 socklen_t alen; 122 socklen_t alen;
126 int s; 123 int s;
127 124
128 s = socket(PF_PACKET, SOCK_DGRAM, 0); 125 s = xsocket(PF_PACKET, SOCK_DGRAM, 0);
129 if (s < 0) {
130 bb_perror_msg_and_die("socket(PF_PACKET)");
131 }
132 126
133 memset(&ifr, 0, sizeof(ifr)); 127 memset(&ifr, 0, sizeof(ifr));
134 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 128 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
@@ -140,9 +134,7 @@ static int get_address(char *dev, int *htype)
140 me.sll_family = AF_PACKET; 134 me.sll_family = AF_PACKET;
141 me.sll_ifindex = ifr.ifr_ifindex; 135 me.sll_ifindex = ifr.ifr_ifindex;
142 me.sll_protocol = htons(ETH_P_LOOP); 136 me.sll_protocol = htons(ETH_P_LOOP);
143 if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { 137 xbind(s, (struct sockaddr*)&me, sizeof(me));
144 bb_perror_msg_and_die("bind");
145 }
146 138
147 alen = sizeof(me); 139 alen = sizeof(me);
148 if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) { 140 if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) {
@@ -195,54 +187,63 @@ static int do_set(int argc, char **argv)
195 struct ifreq ifr0, ifr1; 187 struct ifreq ifr0, ifr1;
196 char *newname = NULL; 188 char *newname = NULL;
197 int htype, halen; 189 int htype, halen;
190 static const char * const keywords[] = {
191 "up", "down", "name", "mtu", "multicast", "arp", "addr", "dev",
192 "on", "off", NULL
193 };
194 enum { ARG_up = 1, ARG_down, ARG_name, ARG_mtu, ARG_multicast, ARG_arp,
195 ARG_addr, ARG_dev, PARM_on, PARM_off };
196 smalluint key;
198 197
199 while (argc > 0) { 198 while (argc > 0) {
200 if (strcmp(*argv, "up") == 0) { 199 key = index_in_str_array(keywords, *argv) + 1;
200 if (key == ARG_up) {
201 mask |= IFF_UP; 201 mask |= IFF_UP;
202 flags |= IFF_UP; 202 flags |= IFF_UP;
203 } else if (strcmp(*argv, "down") == 0) { 203 } else if (key == ARG_down) {
204 mask |= IFF_UP; 204 mask |= IFF_UP;
205 flags &= ~IFF_UP; 205 flags &= ~IFF_UP;
206 } else if (strcmp(*argv, "name") == 0) { 206 } else if (key == ARG_name) {
207 NEXT_ARG(); 207 NEXT_ARG();
208 newname = *argv; 208 newname = *argv;
209 } else if (strcmp(*argv, "mtu") == 0) { 209 } else if (key == ARG_mtu) {
210 NEXT_ARG(); 210 NEXT_ARG();
211 if (mtu != -1) 211 if (mtu != -1)
212 duparg("mtu", *argv); 212 duparg("mtu", *argv);
213 if (get_integer(&mtu, *argv, 0)) 213 if (get_integer(&mtu, *argv, 0))
214 invarg(*argv, "mtu"); 214 invarg(*argv, "mtu");
215 } else if (strcmp(*argv, "multicast") == 0) { 215 } else if (key == ARG_multicast) {
216 NEXT_ARG(); 216 NEXT_ARG();
217 mask |= IFF_MULTICAST; 217 mask |= IFF_MULTICAST;
218 if (strcmp(*argv, "on") == 0) { 218 key = index_in_str_array(keywords, *argv) + 1;
219 if (key == PARM_on) {
219 flags |= IFF_MULTICAST; 220 flags |= IFF_MULTICAST;
220 } else if (strcmp(*argv, "off") == 0) { 221 } else if (key == PARM_off) {
221 flags &= ~IFF_MULTICAST; 222 flags &= ~IFF_MULTICAST;
222 } else 223 } else
223 on_off("multicast"); 224 on_off("multicast");
224 } else if (strcmp(*argv, "arp") == 0) { 225 } else if (key == ARG_arp) {
225 NEXT_ARG(); 226 NEXT_ARG();
226 mask |= IFF_NOARP; 227 mask |= IFF_NOARP;
227 if (strcmp(*argv, "on") == 0) { 228 key = index_in_str_array(keywords, *argv) + 1;
229 if (key == PARM_on) {
228 flags &= ~IFF_NOARP; 230 flags &= ~IFF_NOARP;
229 } else if (strcmp(*argv, "off") == 0) { 231 } else if (key == PARM_off) {
230 flags |= IFF_NOARP; 232 flags |= IFF_NOARP;
231 } else 233 } else
232 on_off("noarp"); 234 on_off("arp");
233 } else if (strcmp(*argv, "addr") == 0) { 235 } else if (key == ARG_addr) {
234 NEXT_ARG(); 236 NEXT_ARG();
235 newaddr = *argv; 237 newaddr = *argv;
236 } else { 238 } else {
237 if (strcmp(*argv, "dev") == 0) { 239 if (key == ARG_dev) {
238 NEXT_ARG(); 240 NEXT_ARG();
239 } 241 }
240 if (dev) 242 if (dev)
241 duparg2("dev", *argv); 243 duparg2("dev", *argv);
242 dev = *argv; 244 dev = *argv;
243 } 245 }
244 argc--; 246 argc--; argv++;
245 argv++;
246 } 247 }
247 248
248 if (!dev) { 249 if (!dev) {
@@ -291,16 +292,18 @@ static int ipaddr_list_link(int argc, char **argv)
291/* Return value becomes exitcode. It's okay to not return at all */ 292/* Return value becomes exitcode. It's okay to not return at all */
292int do_iplink(int argc, char **argv) 293int do_iplink(int argc, char **argv)
293{ 294{
295 static const char * const keywords[] = {
296 "set", "show", "lst", "list", NULL
297 };
298 smalluint key;
294 if (argc <= 0) 299 if (argc <= 0)
295 return ipaddr_list_link(0, NULL); 300 return ipaddr_list_link(0, NULL);
296 301 key = index_in_substr_array(keywords, *argv) + 1;
297 if (matches(*argv, "set") == 0) 302 if (key == 0)
298 return do_set(argc-1, argv+1); 303 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
299 304 argc--; argv++;
300 if (matches(*argv, "show") == 0 || 305 if (key == 1) /* set */
301 matches(*argv, "lst") == 0 || 306 return do_set(argc, argv);
302 matches(*argv, "list") == 0) 307 else /* show, lst, list */
303 return ipaddr_list_link(argc-1, argv+1); 308 return ipaddr_list_link(argc, argv);
304
305 bb_error_msg_and_die("command \"%s\" is unknown", *argv);
306} 309}
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index 23d416344..e7ad7d9c4 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -102,10 +102,8 @@ static int print_route(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
102 if (filter.flushb && n->nlmsg_type != RTM_NEWROUTE) 102 if (filter.flushb && n->nlmsg_type != RTM_NEWROUTE)
103 return 0; 103 return 0;
104 len -= NLMSG_LENGTH(sizeof(*r)); 104 len -= NLMSG_LENGTH(sizeof(*r));
105 if (len < 0) { 105 if (len < 0)
106 bb_error_msg("wrong nlmsg len %d", len); 106 bb_error_msg_and_die("wrong nlmsg len %d", len);
107 return -1;
108 }
109 107
110 if (r->rtm_family == AF_INET6) 108 if (r->rtm_family == AF_INET6)
111 host_len = 128; 109 host_len = 128;
@@ -186,7 +184,7 @@ static int print_route(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
186 struct nlmsghdr *fn; 184 struct nlmsghdr *fn;
187 if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { 185 if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
188 if (flush_update()) 186 if (flush_update())
189 return -1; 187 bb_error_msg_and_die("flush");
190 } 188 }
191 fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp)); 189 fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp));
192 memcpy(fn, n, n->nlmsg_len); 190 memcpy(fn, n, n->nlmsg_len);
@@ -410,9 +408,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
410 argc--; argv++; 408 argc--; argv++;
411 } 409 }
412 410
413 if (rtnl_open(&rth, 0) < 0) { 411 xrtnl_open(&rth);
414 return 1;
415 }
416 412
417 if (d) { 413 if (d) {
418 int idx; 414 int idx;
@@ -420,10 +416,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
420 ll_init_map(&rth); 416 ll_init_map(&rth);
421 417
422 if (d) { 418 if (d) {
423 idx = ll_name_to_index(d); 419 idx = xll_name_to_index(d);
424 if (idx == 0) {
425 bb_error_msg_and_die("cannot find device \"%s\"", d);
426 }
427 addattr32(&req.n, sizeof(req), RTA_OIF, idx); 420 addattr32(&req.n, sizeof(req), RTA_OIF, idx);
428 } 421 }
429 } 422 }
@@ -478,7 +471,7 @@ static int rtnl_rtcache_request(struct rtnl_handle *rth, int family)
478 req.rtm.rtm_family = family; 471 req.rtm.rtm_family = family;
479 req.rtm.rtm_flags |= RTM_F_CLONED; 472 req.rtm.rtm_flags |= RTM_F_CLONED;
480 473
481 return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); 474 return xsendto(rth->fd, (void*)&req, sizeof(req), (struct sockaddr*)&nladdr, sizeof(nladdr));
482} 475}
483 476
484static void iproute_flush_cache(void) 477static void iproute_flush_cache(void)
@@ -592,9 +585,7 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
592 do_ipv6 = AF_INET; 585 do_ipv6 = AF_INET;
593 } 586 }
594 587
595 if (rtnl_open(&rth, 0) < 0) { 588 xrtnl_open(&rth);
596 return 1;
597 }
598 589
599 ll_init_map(&rth); 590 ll_init_map(&rth);
600 591
@@ -602,18 +593,12 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
602 int idx; 593 int idx;
603 594
604 if (id) { 595 if (id) {
605 idx = ll_name_to_index(id); 596 idx = xll_name_to_index(id);
606 if (idx == 0) {
607 bb_error_msg_and_die("cannot find device \"%s\"", id);
608 }
609 filter.iif = idx; 597 filter.iif = idx;
610 filter.iifmask = -1; 598 filter.iifmask = -1;
611 } 599 }
612 if (od) { 600 if (od) {
613 idx = ll_name_to_index(od); 601 idx = xll_name_to_index(od);
614 if (idx == 0) {
615 bb_error_msg("cannot find device \"%s\"", od);
616 }
617 filter.oif = idx; 602 filter.oif = idx;
618 filter.oifmask = -1; 603 filter.oifmask = -1;
619 } 604 }
@@ -635,13 +620,9 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
635 filter.rth = &rth; 620 filter.rth = &rth;
636 621
637 for (;;) { 622 for (;;) {
638 if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) { 623 xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
639 bb_perror_msg_and_die("cannot send dump request");
640 }
641 filter.flushed = 0; 624 filter.flushed = 0;
642 if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) { 625 xrtnl_dump_filter(&rth, print_route, stdout);
643 bb_error_msg_and_die("flush terminated");
644 }
645 if (filter.flushed == 0) { 626 if (filter.flushed == 0) {
646 return 0; 627 return 0;
647 } 628 }
@@ -651,18 +632,13 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
651 } 632 }
652 633
653 if (filter.tb != -1) { 634 if (filter.tb != -1) {
654 if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) { 635 xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
655 bb_perror_msg_and_die("cannot send dump request");
656 }
657 } else { 636 } else {
658 if (rtnl_rtcache_request(&rth, do_ipv6) < 0) { 637 if (rtnl_rtcache_request(&rth, do_ipv6) < 0) {
659 bb_perror_msg_and_die("cannot send dump request"); 638 bb_perror_msg_and_die("cannot send dump request");
660 } 639 }
661 } 640 }
662 641 xrtnl_dump_filter(&rth, print_route, stdout);
663 if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) {
664 bb_error_msg_and_die("dump terminated");
665 }
666 642
667 return 0; 643 return 0;
668} 644}
@@ -755,8 +731,7 @@ static int iproute_get(int argc, char **argv)
755 bb_error_msg_and_die("need at least destination address"); 731 bb_error_msg_and_die("need at least destination address");
756 } 732 }
757 733
758 if (rtnl_open(&rth, 0) < 0) 734 xrtnl_open(&rth);
759 return 1;
760 735
761 ll_init_map(&rth); 736 ll_init_map(&rth);
762 737
@@ -764,17 +739,11 @@ static int iproute_get(int argc, char **argv)
764 int idx; 739 int idx;
765 740
766 if (idev) { 741 if (idev) {
767 idx = ll_name_to_index(idev); 742 idx = xll_name_to_index(idev);
768 if (idx == 0) {
769 bb_error_msg_and_die("cannot find device \"%s\"", idev);
770 }
771 addattr32(&req.n, sizeof(req), RTA_IIF, idx); 743 addattr32(&req.n, sizeof(req), RTA_IIF, idx);
772 } 744 }
773 if (odev) { 745 if (odev) {
774 idx = ll_name_to_index(odev); 746 idx = xll_name_to_index(odev);
775 if (idx == 0) {
776 bb_error_msg_and_die("cannot find device \"%s\"", odev);
777 }
778 addattr32(&req.n, sizeof(req), RTA_OIF, idx); 747 addattr32(&req.n, sizeof(req), RTA_OIF, idx);
779 } 748 }
780 } 749 }
@@ -792,9 +761,7 @@ static int iproute_get(int argc, char **argv)
792 int len = req.n.nlmsg_len; 761 int len = req.n.nlmsg_len;
793 struct rtattr * tb[RTA_MAX+1]; 762 struct rtattr * tb[RTA_MAX+1];
794 763
795 if (print_route(NULL, &req.n, (void*)stdout) < 0) { 764 print_route(NULL, &req.n, (void*)stdout);
796 bb_error_msg_and_die("an error :-)");
797 }
798 765
799 if (req.n.nlmsg_type != RTM_NEWROUTE) { 766 if (req.n.nlmsg_type != RTM_NEWROUTE) {
800 bb_error_msg_and_die("not a route?"); 767 bb_error_msg_and_die("not a route?");
@@ -829,12 +796,7 @@ static int iproute_get(int argc, char **argv)
829 return 2; 796 return 2;
830 } 797 }
831 } 798 }
832 799 print_route(NULL, &req.n, (void*)stdout);
833 if (print_route(NULL, &req.n, (void*)stdout) < 0) {
834// how is this useful?
835 bb_error_msg_and_die("an error :-)");
836 }
837
838 return 0; 800 return 0;
839} 801}
840 802
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c
index d4cf2826c..0499a0994 100644
--- a/networking/libiproute/iprule.c
+++ b/networking/libiproute/iprule.c
@@ -175,16 +175,10 @@ static int iprule_list(int argc, char **argv)
175 return -1; 175 return -1;
176 } 176 }
177 177
178 if (rtnl_open(&rth, 0) < 0) 178 xrtnl_open(&rth);
179 return 1;
180 179
181 if (rtnl_wilddump_request(&rth, af, RTM_GETRULE) < 0) { 180 xrtnl_wilddump_request(&rth, af, RTM_GETRULE);
182 bb_perror_msg_and_die("cannot send dump request"); 181 xrtnl_dump_filter(&rth, print_rule, stdout);
183 }
184
185 if (rtnl_dump_filter(&rth, print_rule, stdout, NULL, NULL) < 0) {
186 bb_error_msg_and_die("dump terminated");
187 }
188 182
189 return 0; 183 return 0;
190} 184}
@@ -296,8 +290,7 @@ static int iprule_modify(int cmd, int argc, char **argv)
296 if (!table_ok && cmd == RTM_NEWRULE) 290 if (!table_ok && cmd == RTM_NEWRULE)
297 req.r.rtm_table = RT_TABLE_MAIN; 291 req.r.rtm_table = RT_TABLE_MAIN;
298 292
299 if (rtnl_open(&rth, 0) < 0) 293 xrtnl_open(&rth);
300 return 1;
301 294
302 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) 295 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
303 return 2; 296 return 2;
diff --git a/networking/libiproute/libnetlink.c b/networking/libiproute/libnetlink.c
index 969648067..5307cec2c 100644
--- a/networking/libiproute/libnetlink.c
+++ b/networking/libiproute/libnetlink.c
@@ -28,44 +28,31 @@ void rtnl_close(struct rtnl_handle *rth)
28 close(rth->fd); 28 close(rth->fd);
29} 29}
30 30
31int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions) 31int xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/)
32{ 32{
33 socklen_t addr_len; 33 socklen_t addr_len;
34 34
35 memset(rth, 0, sizeof(rth)); 35 memset(rth, 0, sizeof(rth));
36 36
37 rth->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 37 rth->fd = xsocket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
38 if (rth->fd < 0) {
39 bb_perror_msg("cannot open netlink socket");
40 return -1;
41 }
42 38
43 memset(&rth->local, 0, sizeof(rth->local)); 39 memset(&rth->local, 0, sizeof(rth->local));
44 rth->local.nl_family = AF_NETLINK; 40 rth->local.nl_family = AF_NETLINK;
45 rth->local.nl_groups = subscriptions; 41 /*rth->local.nl_groups = subscriptions;*/
46 42
47 if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) { 43 xbind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local));
48 bb_perror_msg("cannot bind netlink socket");
49 return -1;
50 }
51 addr_len = sizeof(rth->local); 44 addr_len = sizeof(rth->local);
52 if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) { 45 if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0)
53 bb_perror_msg("cannot getsockname"); 46 bb_perror_msg_and_die("cannot getsockname");
54 return -1; 47 if (addr_len != sizeof(rth->local))
55 } 48 bb_error_msg_and_die("wrong address length %d", addr_len);
56 if (addr_len != sizeof(rth->local)) { 49 if (rth->local.nl_family != AF_NETLINK)
57 bb_error_msg("wrong address length %d", addr_len); 50 bb_error_msg_and_die("wrong address family %d", rth->local.nl_family);
58 return -1;
59 }
60 if (rth->local.nl_family != AF_NETLINK) {
61 bb_error_msg("wrong address family %d", rth->local.nl_family);
62 return -1;
63 }
64 rth->seq = time(NULL); 51 rth->seq = time(NULL);
65 return 0; 52 return 0;
66} 53}
67 54
68int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) 55int xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
69{ 56{
70 struct { 57 struct {
71 struct nlmsghdr nlh; 58 struct nlmsghdr nlh;
@@ -83,7 +70,8 @@ int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
83 req.nlh.nlmsg_seq = rth->dump = ++rth->seq; 70 req.nlh.nlmsg_seq = rth->dump = ++rth->seq;
84 req.g.rtgen_family = family; 71 req.g.rtgen_family = family;
85 72
86 return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); 73 return xsendto(rth->fd, (void*)&req, sizeof(req),
74 (struct sockaddr*)&nladdr, sizeof(nladdr));
87} 75}
88 76
89int rtnl_send(struct rtnl_handle *rth, char *buf, int len) 77int rtnl_send(struct rtnl_handle *rth, char *buf, int len)
@@ -93,7 +81,7 @@ int rtnl_send(struct rtnl_handle *rth, char *buf, int len)
93 memset(&nladdr, 0, sizeof(nladdr)); 81 memset(&nladdr, 0, sizeof(nladdr));
94 nladdr.nl_family = AF_NETLINK; 82 nladdr.nl_family = AF_NETLINK;
95 83
96 return sendto(rth->fd, buf, len, 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); 84 return xsendto(rth->fd, buf, len, (struct sockaddr*)&nladdr, sizeof(nladdr));
97} 85}
98 86
99int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) 87int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len)
@@ -120,11 +108,11 @@ int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len)
120 return sendmsg(rth->fd, &msg, 0); 108 return sendmsg(rth->fd, &msg, 0);
121} 109}
122 110
123int rtnl_dump_filter(struct rtnl_handle *rth, 111static int rtnl_dump_filter(struct rtnl_handle *rth,
124 int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *), 112 int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *),
125 void *arg1, 113 void *arg1/*,
126 int (*junk)(struct sockaddr_nl *, struct nlmsghdr *n, void *), 114 int (*junk)(struct sockaddr_nl *, struct nlmsghdr *n, void *),
127 void *arg2) 115 void *arg2*/)
128{ 116{
129 char buf[8192]; 117 char buf[8192];
130 struct sockaddr_nl nladdr; 118 struct sockaddr_nl nladdr;
@@ -164,12 +152,11 @@ int rtnl_dump_filter(struct rtnl_handle *rth,
164 if (nladdr.nl_pid != 0 || 152 if (nladdr.nl_pid != 0 ||
165 h->nlmsg_pid != rth->local.nl_pid || 153 h->nlmsg_pid != rth->local.nl_pid ||
166 h->nlmsg_seq != rth->dump) { 154 h->nlmsg_seq != rth->dump) {
167 if (junk) { 155/* if (junk) {
168 err = junk(&nladdr, h, arg2); 156 err = junk(&nladdr, h, arg2);
169 if (err < 0) { 157 if (err < 0)
170 return err; 158 return err;
171 } 159 } */
172 }
173 goto skip_it; 160 goto skip_it;
174 } 161 }
175 162
@@ -187,9 +174,8 @@ int rtnl_dump_filter(struct rtnl_handle *rth,
187 return -1; 174 return -1;
188 } 175 }
189 err = filter(&nladdr, h, arg1); 176 err = filter(&nladdr, h, arg1);
190 if (err < 0) { 177 if (err < 0)
191 return err; 178 return err;
192 }
193 179
194skip_it: 180skip_it:
195 h = NLMSG_NEXT(h, status); 181 h = NLMSG_NEXT(h, status);
@@ -204,6 +190,16 @@ skip_it:
204 } 190 }
205} 191}
206 192
193int xrtnl_dump_filter(struct rtnl_handle *rth,
194 int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *),
195 void *arg1)
196{
197 int ret = rtnl_dump_filter(rth, filter, arg1/*, NULL, NULL*/);
198 if (ret < 0)
199 bb_error_msg_and_die("dump terminated");
200 return ret;
201}
202
207int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, 203int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer,
208 unsigned groups, struct nlmsghdr *answer, 204 unsigned groups, struct nlmsghdr *answer,
209 int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *), 205 int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *),
diff --git a/networking/libiproute/libnetlink.h b/networking/libiproute/libnetlink.h
index 9a5a9d351..316bd9b68 100644
--- a/networking/libiproute/libnetlink.h
+++ b/networking/libiproute/libnetlink.h
@@ -17,15 +17,13 @@ struct rtnl_handle
17 uint32_t dump; 17 uint32_t dump;
18}; 18};
19 19
20extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions); 20extern int xrtnl_open(struct rtnl_handle *rth);
21extern void rtnl_close(struct rtnl_handle *rth); 21extern void rtnl_close(struct rtnl_handle *rth);
22extern int rtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type); 22extern int xrtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type);
23extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len); 23extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len);
24extern int rtnl_dump_filter(struct rtnl_handle *rth, 24extern int xrtnl_dump_filter(struct rtnl_handle *rth,
25 int (*filter)(struct sockaddr_nl*, struct nlmsghdr *n, void*), 25 int (*filter)(struct sockaddr_nl*, struct nlmsghdr *n, void*),
26 void *arg1, 26 void *arg1);
27 int (*junk)(struct sockaddr_nl *, struct nlmsghdr *n, void *),
28 void *arg2);
29extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, 27extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer,
30 unsigned groups, struct nlmsghdr *answer, 28 unsigned groups, struct nlmsghdr *answer,
31 int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *), 29 int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *),
diff --git a/networking/libiproute/ll_map.c b/networking/libiproute/ll_map.c
index a8fcd7f88..e9a1616cc 100644
--- a/networking/libiproute/ll_map.c
+++ b/networking/libiproute/ll_map.c
@@ -128,7 +128,7 @@ unsigned ll_index_to_flags(int idx)
128} 128}
129 129
130// TODO: caching is not warranted - no users which repeatedly call it 130// TODO: caching is not warranted - no users which repeatedly call it
131int ll_name_to_index(char *name) 131int xll_name_to_index(const char * const name)
132{ 132{
133 static char ncache[16]; 133 static char ncache[16];
134 static int icache; 134 static int icache;
@@ -136,17 +136,21 @@ int ll_name_to_index(char *name)
136 struct idxmap *im; 136 struct idxmap *im;
137 int sock_fd; 137 int sock_fd;
138 int i; 138 int i;
139 int ret = 0;
139 140
140 if (name == NULL) 141 if (name == NULL)
141 return 0; 142 goto out;
142 if (icache && strcmp(name, ncache) == 0) 143 if (icache && strcmp(name, ncache) == 0) {
143 return icache; 144 ret = icache;
145 goto out;
146 }
144 for (i = 0; i < 16; i++) { 147 for (i = 0; i < 16; i++) {
145 for (im = idxmap[i]; im; im = im->next) { 148 for (im = idxmap[i]; im; im = im->next) {
146 if (strcmp(im->name, name) == 0) { 149 if (strcmp(im->name, name) == 0) {
147 icache = im->index; 150 icache = im->index;
148 strcpy(ncache, name); 151 strcpy(ncache, name);
149 return im->index; 152 ret = im->index;
153 goto out;
150 } 154 }
151 } 155 }
152 } 156 }
@@ -160,29 +164,26 @@ int ll_name_to_index(char *name)
160 sock_fd = socket(AF_INET, SOCK_DGRAM, 0); 164 sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
161 if (sock_fd) { 165 if (sock_fd) {
162 struct ifreq ifr; 166 struct ifreq ifr;
163 int ret; 167 int tmp;
164 strncpy(ifr.ifr_name, name, IFNAMSIZ); 168 strncpy(ifr.ifr_name, name, IFNAMSIZ);
165 ifr.ifr_ifindex = -1; 169 ifr.ifr_ifindex = -1;
166 ret = ioctl(sock_fd, SIOCGIFINDEX, &ifr); 170 tmp = ioctl(sock_fd, SIOCGIFINDEX, &ifr);
167 close(sock_fd); 171 close(sock_fd);
168 if (ret >= 0) 172 if (tmp >= 0)
169 /* In theory, we should redump the interface list 173 /* In theory, we should redump the interface list
170 * to update our cache, this is left as an exercise 174 * to update our cache, this is left as an exercise
171 * to the reader... Jean II */ 175 * to the reader... Jean II */
172 return ifr.ifr_ifindex; 176 ret = ifr.ifr_ifindex;
173 } 177 }
174 178out:
175 return 0; 179 if (ret <= 0)
180 bb_error_msg_and_die("cannot find device \"%s\"", name);
181 return ret;
176} 182}
177 183
178int ll_init_map(struct rtnl_handle *rth) 184int ll_init_map(struct rtnl_handle *rth)
179{ 185{
180 if (rtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK) < 0) { 186 xrtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK);
181 bb_perror_msg_and_die("cannot send dump request"); 187 xrtnl_dump_filter(rth, ll_remember_index, &idxmap);
182 }
183
184 if (rtnl_dump_filter(rth, ll_remember_index, &idxmap, NULL, NULL) < 0) {
185 bb_error_msg_and_die("dump terminated");
186 }
187 return 0; 188 return 0;
188} 189}
diff --git a/networking/libiproute/ll_map.h b/networking/libiproute/ll_map.h
index 226d48fc2..abb640444 100644
--- a/networking/libiproute/ll_map.h
+++ b/networking/libiproute/ll_map.h
@@ -4,7 +4,7 @@
4 4
5extern int ll_remember_index(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); 5extern int ll_remember_index(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
6extern int ll_init_map(struct rtnl_handle *rth); 6extern int ll_init_map(struct rtnl_handle *rth);
7extern int ll_name_to_index(char *name); 7extern int xll_name_to_index(const char * const name);
8extern const char *ll_index_to_name(int idx); 8extern const char *ll_index_to_name(int idx);
9extern const char *ll_idx_n2a(int idx, char *buf); 9extern const char *ll_idx_n2a(int idx, char *buf);
10extern int ll_index_to_type(int idx); 10extern int ll_index_to_type(int idx);
diff --git a/networking/libiproute/utils.h b/networking/libiproute/utils.h
index 3b6fef1e3..f76ad124d 100644
--- a/networking/libiproute/utils.h
+++ b/networking/libiproute/utils.h
@@ -78,7 +78,7 @@ extern const char *rt_addr_n2a(int af, int len, void *addr, char *buf, int bufle
78void invarg(const char *, const char *) ATTRIBUTE_NORETURN; 78void invarg(const char *, const char *) ATTRIBUTE_NORETURN;
79void duparg(const char *, const char *) ATTRIBUTE_NORETURN; 79void duparg(const char *, const char *) ATTRIBUTE_NORETURN;
80void duparg2(const char *, const char *) ATTRIBUTE_NORETURN; 80void duparg2(const char *, const char *) ATTRIBUTE_NORETURN;
81int ATTRIBUTE_DEPRECATED matches(const char *arg, const char *pattern); 81int /*ATTRIBUTE_DEPRECATED*/ matches(const char *arg, const char *pattern);
82int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits); 82int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits);
83 83
84const char *dnet_ntop(int af, const void *addr, char *str, size_t len); 84const char *dnet_ntop(int af, const void *addr, char *str, size_t len);