Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/networking/route.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/networking/route.c
r821 r1770 13 13 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 14 14 * 15 * $Id: route.c,v 1.26 2004/03/19 23:27:08 mjn3 Exp $16 15 * 17 16 * displayroute() code added by Vladimir N. Oleynik <dzo@simtreas.ru> … … 27 26 */ 28 27 29 #include <stdio.h>30 #include <stdlib.h>31 #include <string.h>32 #include <errno.h>33 #include <assert.h>34 #include <unistd.h>35 #include <fcntl.h>36 28 #include <getopt.h> 37 #include <sys/types.h>38 #include <sys/ioctl.h>39 29 #include <net/route.h> 40 30 #include <net/if.h> 41 #include "busybox.h" 31 32 #include "libbb.h" 42 33 #include "inet_common.h" 34 43 35 44 36 #ifndef RTF_UP … … 59 51 #endif 60 52 61 #if defined (SIOCADDRTOLD) || defined(RTF_IRTT) /* route */53 #if defined(SIOCADDRTOLD) || defined(RTF_IRTT) /* route */ 62 54 #define HAVE_NEW_ADDRT 1 63 55 #endif … … 72 64 73 65 /* The RTACTION entries must agree with tbl_verb[] below! */ 74 #define RTACTION_ADD 75 #define RTACTION_DEL 66 #define RTACTION_ADD 1 67 #define RTACTION_DEL 2 76 68 77 69 /* For the various tbl_*[] arrays, the 1st byte is the offset to 78 70 * the next entry and the 2nd byte is return value. */ 79 71 80 #define NET_FLAG 81 #define HOST_FLAG 72 #define NET_FLAG 1 73 #define HOST_FLAG 2 82 74 83 75 /* We remap '-' to '#' to avoid problems with getopt. */ 84 static const char tbl_hash_net_host[] =76 static const char tbl_hash_net_host[] ALIGN1 = 85 77 "\007\001#net\0" 86 78 /* "\010\002#host\0" */ … … 88 80 ; 89 81 90 #define KW_TAKES_ARG 91 #define KW_SETS_FLAG 92 93 #define KW_IPVx_METRIC 94 #define KW_IPVx_NETMASK 95 #define KW_IPVx_GATEWAY 96 #define KW_IPVx_MSS 97 #define KW_IPVx_WINDOW 98 #define KW_IPVx_IRTT 99 #define KW_IPVx_DEVICE 100 101 #define KW_IPVx_FLAG_ONLY 102 #define KW_IPVx_REJECT 103 #define KW_IPVx_MOD 104 #define KW_IPVx_DYN 105 #define KW_IPVx_REINSTATE 106 107 static const char tbl_ipvx[] =82 #define KW_TAKES_ARG 020 83 #define KW_SETS_FLAG 040 84 85 #define KW_IPVx_METRIC 020 86 #define KW_IPVx_NETMASK 021 87 #define KW_IPVx_GATEWAY 022 88 #define KW_IPVx_MSS 023 89 #define KW_IPVx_WINDOW 024 90 #define KW_IPVx_IRTT 025 91 #define KW_IPVx_DEVICE 026 92 93 #define KW_IPVx_FLAG_ONLY 040 94 #define KW_IPVx_REJECT 040 95 #define KW_IPVx_MOD 041 96 #define KW_IPVx_DYN 042 97 #define KW_IPVx_REINSTATE 043 98 99 static const char tbl_ipvx[] ALIGN1 = 108 100 /* 020 is the "takes an arg" bit */ 109 101 #if HAVE_NEW_ADDRT … … 167 159 int skfd, isnet, xflag; 168 160 169 assert((action == RTACTION_ADD) || (action == RTACTION_DEL));170 171 161 /* Grab the -net or -host options. Remember they were transformed. */ 172 162 xflag = kw_lookup(tbl_hash_net_host, &args); … … 178 168 179 169 /* Clean out the RTREQ structure. */ 180 memset( (char *) &rt, 0, sizeof(struct rtentry));170 memset(&rt, 0, sizeof(rt)); 181 171 182 172 { … … 186 176 /* recognize x.x.x.x/mask format. */ 187 177 prefix = strchr(target, '/'); 188 if (prefix) {178 if (prefix) { 189 179 int prefix_len; 190 180 191 prefix_len = bb_xgetularg10_bnd(prefix+1, 0, 32);181 prefix_len = xatoul_range(prefix+1, 0, 32); 192 182 mask_in_addr(rt) = htonl( ~ (0xffffffffUL >> prefix_len)); 193 183 *prefix = '\0'; … … 197 187 } else { 198 188 /* Default netmask. */ 199 netmask = bb_ INET_default;189 netmask = bb_str_default; 200 190 } 201 191 /* Prefer hostname lookup is -host flag (xflag==1) was given. */ … … 205 195 bb_error_msg_and_die("resolving %s", target); 206 196 } 207 if (prefix) {197 if (prefix) { 208 198 /* do not destroy prefix for process args */ 209 199 *prefix = '/'; … … 229 219 #if HAVE_NEW_ADDRT 230 220 if (k == KW_IPVx_METRIC) { 231 rt.rt_metric = bb_xgetularg10(args_m1) + 1;221 rt.rt_metric = xatoul(args_m1) + 1; 232 222 continue; 233 223 } … … 270 260 if (k == KW_IPVx_MSS) { /* Check valid MSS bounds. */ 271 261 rt.rt_flags |= RTF_MSS; 272 rt.rt_mss = bb_xgetularg10_bnd(args_m1, 64, 32768);262 rt.rt_mss = xatoul_range(args_m1, 64, 32768); 273 263 continue; 274 264 } … … 276 266 if (k == KW_IPVx_WINDOW) { /* Check valid window bounds. */ 277 267 rt.rt_flags |= RTF_WINDOW; 278 rt.rt_window = bb_xgetularg10_bnd(args_m1, 128, INT_MAX);268 rt.rt_window = xatoul_range(args_m1, 128, INT_MAX); 279 269 continue; 280 270 } … … 283 273 if (k == KW_IPVx_IRTT) { 284 274 rt.rt_flags |= RTF_IRTT; 285 rt.rt_irtt = bb_xgetularg10(args_m1);275 rt.rt_irtt = xatoul(args_m1); 286 276 rt.rt_irtt *= (sysconf(_SC_CLK_TCK) / 100); /* FIXME */ 287 277 #if 0 /* FIXME: do we need to check anything of this? */ … … 308 298 #ifdef RTF_REJECT 309 299 if ((rt.rt_flags & RTF_REJECT) && !rt.rt_dev) { 310 rt.rt_dev = "lo";300 rt.rt_dev = (char*)"lo"; 311 301 } 312 302 #endif … … 336 326 337 327 /* Create a socket to the INET kernel. */ 338 skfd = bb_xsocket(AF_INET, SOCK_DGRAM, 0); 339 340 if (ioctl(skfd, ((action==RTACTION_ADD) ? SIOCADDRT : SIOCDELRT), &rt)<0) { 341 bb_perror_msg_and_die("SIOC[ADD|DEL]RT"); 342 } 328 skfd = xsocket(AF_INET, SOCK_DGRAM, 0); 329 330 if (action == RTACTION_ADD) 331 xioctl(skfd, SIOCADDRT, &rt); 332 else 333 xioctl(skfd, SIOCDELRT, &rt); 343 334 344 335 if (ENABLE_FEATURE_CLEAN_UP) close(skfd); 345 336 } 346 337 347 #if def CONFIG_FEATURE_IPV6338 #if ENABLE_FEATURE_IPV6 348 339 349 340 static void INET6_setroute(int action, char **args) … … 354 345 const char *devname; 355 346 356 assert((action == RTACTION_ADD) || (action == RTACTION_DEL));357 358 {359 347 /* We know args isn't NULL from the check in route_main. */ 360 348 const char *target = *args++; 361 349 362 if (strcmp(target, bb_ INET_default) == 0) {350 if (strcmp(target, bb_str_default) == 0) { 363 351 prefix_len = 0; 364 352 memset(&sa6, 0, sizeof(sa6)); … … 367 355 if ((cp = strchr(target, '/'))) { /* Yes... const to non is ok. */ 368 356 *cp = 0; 369 prefix_len = bb_xgetularg10_bnd(cp+1, 0, 128);357 prefix_len = xatoul_range(cp+1, 0, 128); 370 358 } else { 371 359 prefix_len = 128; … … 375 363 } 376 364 } 377 }378 365 379 366 /* Clean out the RTREQ structure. */ 380 memset( (char *) &rt, 0, sizeof(struct in6_rtmsg));367 memset(&rt, 0, sizeof(rt)); 381 368 382 369 memcpy(&rt.rtmsg_dst, sa6.sin6_addr.s6_addr, sizeof(struct in6_addr)); … … 399 386 400 387 if (k == KW_IPVx_METRIC) { 401 rt.rtmsg_metric = bb_xgetularg10(args_m1);388 rt.rtmsg_metric = xatoul(args_m1); 402 389 continue; 403 390 } … … 430 417 431 418 /* Create a socket to the INET6 kernel. */ 432 skfd = bb_xsocket(AF_INET6, SOCK_DGRAM, 0);419 skfd = xsocket(AF_INET6, SOCK_DGRAM, 0); 433 420 434 421 rt.rtmsg_ifindex = 0; … … 437 424 struct ifreq ifr; 438 425 memset(&ifr, 0, sizeof(ifr)); 439 strcpy(ifr.ifr_name, devname); 440 441 if (ioctl(skfd, SIOGIFINDEX, &ifr) < 0) { 442 bb_perror_msg_and_die("SIOGIFINDEX"); 443 } 426 strncpy(ifr.ifr_name, devname, sizeof(ifr.ifr_name)); 427 xioctl(skfd, SIOGIFINDEX, &ifr); 444 428 rt.rtmsg_ifindex = ifr.ifr_ifindex; 445 429 } 446 430 447 431 /* Tell the kernel to accept this route. */ 448 if (ioctl(skfd, ((action==RTACTION_ADD) ? SIOCADDRT : SIOCDELRT), &rt)<0) { 449 bb_perror_msg_and_die("SIOC[ADD|DEL]RT"); 450 } 432 if (action == RTACTION_ADD) 433 xioctl(skfd, SIOCADDRT, &rt); 434 else 435 xioctl(skfd, SIOCDELRT, &rt); 451 436 452 437 if (ENABLE_FEATURE_CLEAN_UP) close(skfd); … … 454 439 #endif 455 440 456 static const unsigned intflagvals[] = { /* Must agree with flagchars[]. */441 static const unsigned flagvals[] = { /* Must agree with flagchars[]. */ 457 442 RTF_GATEWAY, 458 443 RTF_HOST, … … 460 445 RTF_DYNAMIC, 461 446 RTF_MODIFIED, 462 #if def CONFIG_FEATURE_IPV6447 #if ENABLE_FEATURE_IPV6 463 448 RTF_DEFAULT, 464 449 RTF_ADDRCONF, … … 470 455 #define IPV6_MASK (RTF_GATEWAY|RTF_HOST|RTF_DEFAULT|RTF_ADDRCONF|RTF_CACHE) 471 456 472 static const char flagchars[] = /* Must agree with flagvals[]. */ 457 /* Must agree with flagvals[]. */ 458 static const char flagchars[] ALIGN1 = 473 459 "GHRDM" 474 #if def CONFIG_FEATURE_IPV6460 #if ENABLE_FEATURE_IPV6 475 461 "DAC" 476 462 #endif 477 463 ; 478 464 479 static 480 #ifndef CONFIG_FEATURE_IPV6 481 __inline 482 #endif 483 void set_flags(char *flagstr, int flags) 465 static void set_flags(char *flagstr, int flags) 484 466 { 485 467 int i; … … 487 469 *flagstr++ = 'U'; 488 470 489 for (i =0 ; (*flagstr = flagchars[i]) != 0; i++) {471 for (i = 0; (*flagstr = flagchars[i]) != 0; i++) { 490 472 if (flags & flagvals[i]) { 491 473 ++flagstr; … … 495 477 496 478 /* also used in netstat */ 497 void displayroutes(int noresolve, int netstatfmt); 498 void displayroutes(int noresolve, int netstatfmt) 479 void bb_displayroutes(int noresolve, int netstatfmt) 499 480 { 500 char devname[64], flags[16], sdest[16], sgw[16];501 unsigned long intd, g, m;481 char devname[64], flags[16], *sdest, *sgw; 482 unsigned long d, g, m; 502 483 int flgs, ref, use, metric, mtu, win, ir; 503 484 struct sockaddr_in s_addr; 504 485 struct in_addr mask; 505 486 506 FILE *fp = bb_xfopen("/proc/net/route", "r"); 507 508 bb_printf("Kernel IP routing table\n" 509 "Destination Gateway Genmask" 510 " Flags %s Iface\n", 511 netstatfmt ? " MSS Window irtt" : "Metric Ref Use"); 487 FILE *fp = xfopen("/proc/net/route", "r"); 488 489 printf("Kernel IP routing table\n" 490 "Destination Gateway Genmask Flags %s Iface\n", 491 netstatfmt ? " MSS Window irtt" : "Metric Ref Use"); 512 492 513 493 if (fscanf(fp, "%*[^\n]\n") < 0) { /* Skip the first line. */ … … 523 503 break; 524 504 } 525 505 ERROR: 526 506 bb_error_msg_and_die("fscanf"); 527 507 } … … 541 521 s_addr.sin_family = AF_INET; 542 522 s_addr.sin_addr.s_addr = d; 543 INET_rresolve(sdest, sizeof(sdest), &s_addr, 544 (noresolve | 0x8000), m); /* Default instead of *. */ 545 523 sdest = INET_rresolve(&s_addr, (noresolve | 0x8000), m); /* 'default' instead of '*' */ 546 524 s_addr.sin_addr.s_addr = g; 547 INET_rresolve(sgw, sizeof(sgw), &s_addr, 548 (noresolve | 0x4000), m); /* Host instead of net. */ 549 525 sgw = INET_rresolve(&s_addr, (noresolve | 0x4000), m); /* Host instead of net */ 550 526 mask.s_addr = m; 551 bb_printf("%-16s%-16s%-16s%-6s", sdest, sgw, inet_ntoa(mask), flags); 527 /* "%15.15s" truncates hostnames, do we really want that? */ 528 printf("%-15.15s %-15.15s %-16s%-6s", sdest, sgw, inet_ntoa(mask), flags); 529 free(sdest); 530 free(sgw); 552 531 if (netstatfmt) { 553 bb_printf("%5d %-5d %6d %s\n", mtu, win, ir, devname);532 printf("%5d %-5d %6d %s\n", mtu, win, ir, devname); 554 533 } else { 555 bb_printf("%-6d %-2d %7d %s\n", metric, ref, use, devname);534 printf("%-6d %-2d %7d %s\n", metric, ref, use, devname); 556 535 } 557 536 } 558 537 } 559 538 560 #if def CONFIG_FEATURE_IPV6539 #if ENABLE_FEATURE_IPV6 561 540 562 541 static void INET6_displayroutes(int noresolve) 563 542 { 564 char addr6[128], naddr6[128];543 char addr6[128], *naddr6; 565 544 /* In addr6x, we store both 40-byte ':'-delimited ipv6 addresses. 566 545 * We read the non-delimited strings into the tail of the buffer … … 574 553 struct sockaddr_in6 snaddr6; 575 554 576 FILE *fp = bb_xfopen("/proc/net/ipv6_route", "r");577 578 bb_printf("Kernel IPv6 routing table\n%-44s%-40s"555 FILE *fp = xfopen("/proc/net/ipv6_route", "r"); 556 557 printf("Kernel IPv6 routing table\n%-44s%-40s" 579 558 "Flags Metric Ref Use Iface\n", 580 559 "Destination", "Next Hop"); … … 589 568 break; 590 569 } 591 570 ERROR: 592 571 bb_error_msg_and_die("fscanf"); 593 572 } … … 602 581 do { 603 582 if (!*p) { 604 if (i ==40) { /* nul terminator for 1st address? */583 if (i == 40) { /* nul terminator for 1st address? */ 605 584 addr6x[39] = 0; /* Fixup... need 0 instead of ':'. */ 606 585 ++p; /* Skip and continue. */ … … 610 589 } 611 590 addr6x[i++] = *p++; 612 if (!((i+1) %5)) {591 if (!((i+1) % 5)) { 613 592 addr6x[i++] = ':'; 614 593 } … … 627 606 (struct sockaddr *) &snaddr6.sin6_addr); 628 607 snaddr6.sin6_family = AF_INET6; 629 INET6_rresolve(naddr6, sizeof(naddr6), 630 (struct sockaddr_in6 *) &snaddr6, 631 #if 0 632 (noresolve | 0x8000) /* Default instead of *. */ 633 #else 608 naddr6 = INET6_rresolve((struct sockaddr_in6 *) &snaddr6, 634 609 0x0fff /* Apparently, upstream never resolves. */ 635 #endif636 610 ); 637 611 … … 639 613 snprintf(addr6, sizeof(addr6), "%s/%d", naddr6, prefix_len); 640 614 r += 40; 615 free(naddr6); 641 616 } else { /* 2nd pass */ 642 617 /* Print the info. */ 643 bb_printf("%-43s %-39s %-5s %-6d %-2d %7d %-8s\n", 644 addr6, naddr6, flags, metric, refcnt, use, iface); 618 printf("%-43s %-39s %-5s %-6d %-2d %7d %-8s\n", 619 addr6, naddr6, flags, metric, refcnt, use, iface); 620 free(naddr6); 645 621 break; 646 622 } … … 651 627 #endif 652 628 653 #define ROUTE_OPT_A 654 #define ROUTE_OPT_n 655 #define ROUTE_OPT_e 656 #define ROUTE_OPT_INET6 629 #define ROUTE_OPT_A 0x01 630 #define ROUTE_OPT_n 0x02 631 #define ROUTE_OPT_e 0x04 632 #define ROUTE_OPT_INET6 0x08 /* Not an actual option. See below. */ 657 633 658 634 /* 1st byte is offset to next entry offset. 2nd byte is return value. */ 659 static const char tbl_verb[] = /* 2nd byte matches RTACTION_* code */ 635 /* 2nd byte matches RTACTION_* code */ 636 static const char tbl_verb[] ALIGN1 = 660 637 "\006\001add\0" 661 638 "\006\002del\0" 662 639 /* "\011\002delete\0" */ 663 "\010\002delete" /* Sincelast, we can save a byte. */640 "\010\002delete" /* Since it's last, we can save a byte. */ 664 641 ; 665 642 643 int route_main(int argc, char **argv); 666 644 int route_main(int argc, char **argv) 667 645 { 668 unsigned longopt;646 unsigned opt; 669 647 int what; 670 648 char *family; 649 char **p; 671 650 672 651 /* First, remap '-net' and '-host' to avoid getopt problems. */ 673 { 674 char **p = argv; 675 676 while (*++p) { 677 if ((strcmp(*p, "-net") == 0) || (strcmp(*p, "-host") == 0)) { 678 p[0][0] = '#'; 679 } 680 } 681 } 682 683 opt = bb_getopt_ulflags(argc, argv, "A:ne", &family); 684 685 if ((opt & ROUTE_OPT_A) && strcmp(family, "inet")) { 686 #ifdef CONFIG_FEATURE_IPV6 652 p = argv; 653 while (*++p) { 654 if (strcmp(*p, "-net") == 0 || strcmp(*p, "-host") == 0) { 655 p[0][0] = '#'; 656 } 657 } 658 659 opt = getopt32(argv, "A:ne", &family); 660 661 if ((opt & ROUTE_OPT_A) && strcmp(family, "inet") != 0) { 662 #if ENABLE_FEATURE_IPV6 687 663 if (strcmp(family, "inet6") == 0) { 688 664 opt |= ROUTE_OPT_INET6; /* Set flag for ipv6. */ … … 697 673 if (!*argv) { 698 674 int noresolve = (opt & ROUTE_OPT_n) ? 0x0fff : 0; 699 #if def CONFIG_FEATURE_IPV6675 #if ENABLE_FEATURE_IPV6 700 676 if (opt & ROUTE_OPT_INET6) 701 677 INET6_displayroutes(noresolve); 702 678 else 703 679 #endif 704 displayroutes(noresolve, opt & ROUTE_OPT_e); 705 706 bb_xferror_stdout(); 707 bb_fflush_stdout_and_exit(EXIT_SUCCESS); 680 bb_displayroutes(noresolve, opt & ROUTE_OPT_e); 681 682 fflush_stdout_and_exit(EXIT_SUCCESS); 708 683 } 709 684 … … 714 689 } 715 690 716 #if def CONFIG_FEATURE_IPV6691 #if ENABLE_FEATURE_IPV6 717 692 if (opt & ROUTE_OPT_INET6) 718 693 INET6_setroute(what, argv);
Note:
See TracChangeset
for help on using the changeset viewer.