Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/networking/route.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 532 by niro, Sat Sep 1 22:45:15 2007 UTC revision 816 by niro, Fri Apr 24 18:33:46 2009 UTC
# Line 12  Line 12 
12   *   *
13   * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.   * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
14   *   *
  * $Id: route.c,v 1.1 2007-09-01 22:43:53 niro Exp $  
15   *   *
16   * displayroute() code added by Vladimir N. Oleynik <dzo@simtreas.ru>   * displayroute() code added by Vladimir N. Oleynik <dzo@simtreas.ru>
17   * adjustments by Larry Doolittle  <LRDoolittle@lbl.gov>   * adjustments by Larry Doolittle  <LRDoolittle@lbl.gov>
# Line 26  Line 25 
25   * remove ridiculous amounts of bloat.   * remove ridiculous amounts of bloat.
26   */   */
27    
 #include "busybox.h"  
 #include "inet_common.h"  
 #include <getopt.h>  
28  #include <net/route.h>  #include <net/route.h>
29  #include <net/if.h>  #include <net/if.h>
30    
31    #include "libbb.h"
32    #include "inet_common.h"
33    
34    
35  #ifndef RTF_UP  #ifndef RTF_UP
36  /* Keep this in sync with /usr/src/linux/include/linux/route.h */  /* Keep this in sync with /usr/src/linux/include/linux/route.h */
# Line 50  Line 49 
49  #define RTF_REJECT      0x0200 /* Reject route                 */  #define RTF_REJECT      0x0200 /* Reject route                 */
50  #endif  #endif
51    
52  #if defined (SIOCADDRTOLD) || defined (RTF_IRTT) /* route */  #if defined(SIOCADDRTOLD) || defined(RTF_IRTT) /* route */
53  #define HAVE_NEW_ADDRT 1  #define HAVE_NEW_ADDRT 1
54  #endif  #endif
55    
# Line 63  Line 62 
62  #endif  #endif
63    
64  /* The RTACTION entries must agree with tbl_verb[] below! */  /* The RTACTION entries must agree with tbl_verb[] below! */
65  #define RTACTION_ADD 1  #define RTACTION_ADD 1
66  #define RTACTION_DEL 2  #define RTACTION_DEL 2
67    
68  /* For the various tbl_*[] arrays, the 1st byte is the offset to  /* For the various tbl_*[] arrays, the 1st byte is the offset to
69   * the next entry and the 2nd byte is return value. */   * the next entry and the 2nd byte is return value. */
70    
71  #define NET_FLAG 1  #define NET_FLAG  1
72  #define HOST_FLAG 2  #define HOST_FLAG 2
73    
74  /* We remap '-' to '#' to avoid problems with getopt. */  /* We remap '-' to '#' to avoid problems with getopt. */
75  static const char tbl_hash_net_host[] =  static const char tbl_hash_net_host[] ALIGN1 =
76   "\007\001#net\0"   "\007\001#net\0"
77  /* "\010\002#host\0" */  /* "\010\002#host\0" */
78   "\007\002#host" /* Since last, we can save a byte. */   "\007\002#host" /* Since last, we can save a byte. */
79  ;  ;
80    
81  #define KW_TAKES_ARG 020  #define KW_TAKES_ARG            020
82  #define KW_SETS_FLAG 040  #define KW_SETS_FLAG            040
83    
84  #define KW_IPVx_METRIC 020  #define KW_IPVx_METRIC          020
85  #define KW_IPVx_NETMASK 021  #define KW_IPVx_NETMASK         021
86  #define KW_IPVx_GATEWAY 022  #define KW_IPVx_GATEWAY         022
87  #define KW_IPVx_MSS 023  #define KW_IPVx_MSS             023
88  #define KW_IPVx_WINDOW 024  #define KW_IPVx_WINDOW          024
89  #define KW_IPVx_IRTT 025  #define KW_IPVx_IRTT            025
90  #define KW_IPVx_DEVICE 026  #define KW_IPVx_DEVICE          026
91    
92  #define KW_IPVx_FLAG_ONLY 040  #define KW_IPVx_FLAG_ONLY       040
93  #define KW_IPVx_REJECT 040  #define KW_IPVx_REJECT          040
94  #define KW_IPVx_MOD 041  #define KW_IPVx_MOD             041
95  #define KW_IPVx_DYN 042  #define KW_IPVx_DYN             042
96  #define KW_IPVx_REINSTATE 043  #define KW_IPVx_REINSTATE       043
97    
98  static const char tbl_ipvx[] =  static const char tbl_ipvx[] ALIGN1 =
99   /* 020 is the "takes an arg" bit */   /* 020 is the "takes an arg" bit */
100  #if HAVE_NEW_ADDRT  #if HAVE_NEW_ADDRT
101   "\011\020metric\0"   "\011\020metric\0"
# Line 167  static void INET_setroute(int action, ch Line 166  static void INET_setroute(int action, ch
166   }   }
167    
168   /* Clean out the RTREQ structure. */   /* Clean out the RTREQ structure. */
169   memset((char *) &rt, 0, sizeof(struct rtentry));   memset(&rt, 0, sizeof(rt));
170    
171   {   {
172   const char *target = *args++;   const char *target = *args++;
# Line 175  static void INET_setroute(int action, ch Line 174  static void INET_setroute(int action, ch
174    
175   /* recognize x.x.x.x/mask format. */   /* recognize x.x.x.x/mask format. */
176   prefix = strchr(target, '/');   prefix = strchr(target, '/');
177   if(prefix) {   if (prefix) {
178   int prefix_len;   int prefix_len;
179    
180   prefix_len = xatoul_range(prefix+1, 0, 32);   prefix_len = xatoul_range(prefix+1, 0, 32);
# Line 194  static void INET_setroute(int action, ch Line 193  static void INET_setroute(int action, ch
193   if (isnet < 0) {   if (isnet < 0) {
194   bb_error_msg_and_die("resolving %s", target);   bb_error_msg_and_die("resolving %s", target);
195   }   }
196   if(prefix) {   if (prefix) {
197   /* do not destroy prefix for process args */   /* do not destroy prefix for process args */
198   *prefix = '/';   *prefix = '/';
199   }   }
# Line 297  static void INET_setroute(int action, ch Line 296  static void INET_setroute(int action, ch
296    
297  #ifdef RTF_REJECT  #ifdef RTF_REJECT
298   if ((rt.rt_flags & RTF_REJECT) && !rt.rt_dev) {   if ((rt.rt_flags & RTF_REJECT) && !rt.rt_dev) {
299   rt.rt_dev = "lo";   rt.rt_dev = (char*)"lo";
300   }   }
301  #endif  #endif
302    
303   /* sanity checks.. */   /* sanity checks.. */
304   if (mask_in_addr(rt)) {   if (mask_in_addr(rt)) {
305   unsigned long mask = mask_in_addr(rt);   uint32_t mask = mask_in_addr(rt);
306    
307   mask = ~ntohl(mask);   mask = ~ntohl(mask);
308   if ((rt.rt_flags & RTF_HOST) && mask != 0xffffffff) {   if ((rt.rt_flags & RTF_HOST) && mask != 0xffffffff) {
# Line 314  static void INET_setroute(int action, ch Line 313  static void INET_setroute(int action, ch
313   bb_error_msg_and_die("bogus netmask %s", netmask);   bb_error_msg_and_die("bogus netmask %s", netmask);
314   }   }
315   mask = ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr;   mask = ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr;
316   if (mask & ~mask_in_addr(rt)) {   if (mask & ~(uint32_t)mask_in_addr(rt)) {
317   bb_error_msg_and_die("netmask and route address conflict");   bb_error_msg_and_die("netmask and route address conflict");
318   }   }
319   }   }
# Line 327  static void INET_setroute(int action, ch Line 326  static void INET_setroute(int action, ch
326   /* Create a socket to the INET kernel. */   /* Create a socket to the INET kernel. */
327   skfd = xsocket(AF_INET, SOCK_DGRAM, 0);   skfd = xsocket(AF_INET, SOCK_DGRAM, 0);
328    
329   if (ioctl(skfd, ((action==RTACTION_ADD) ? SIOCADDRT : SIOCDELRT), &rt)<0) {   if (action == RTACTION_ADD)
330   bb_perror_msg_and_die("SIOC[ADD|DEL]RT");   xioctl(skfd, SIOCADDRT, &rt);
331   }   else
332     xioctl(skfd, SIOCDELRT, &rt);
333    
334   if (ENABLE_FEATURE_CLEAN_UP) close(skfd);   if (ENABLE_FEATURE_CLEAN_UP) close(skfd);
335  }  }
336    
337  #ifdef CONFIG_FEATURE_IPV6  #if ENABLE_FEATURE_IPV6
338    
339  static void INET6_setroute(int action, char **args)  static void INET6_setroute(int action, char **args)
340  {  {
# Line 351  static void INET6_setroute(int action, c Line 351  static void INET6_setroute(int action, c
351   memset(&sa6, 0, sizeof(sa6));   memset(&sa6, 0, sizeof(sa6));
352   } else {   } else {
353   char *cp;   char *cp;
354   if ((cp = strchr(target, '/'))) { /* Yes... const to non is ok. */   cp = strchr(target, '/'); /* Yes... const to non is ok. */
355   *cp = 0;   if (cp) {
356   prefix_len = xatoul_range(cp+1, 0, 128);   *cp = '\0';
357     prefix_len = xatoul_range(cp + 1, 0, 128);
358   } else {   } else {
359   prefix_len = 128;   prefix_len = 128;
360   }   }
# Line 363  static void INET6_setroute(int action, c Line 364  static void INET6_setroute(int action, c
364   }   }
365    
366   /* Clean out the RTREQ structure. */   /* Clean out the RTREQ structure. */
367   memset((char *) &rt, 0, sizeof(struct in6_rtmsg));   memset(&rt, 0, sizeof(rt));
368    
369   memcpy(&rt.rtmsg_dst, sa6.sin6_addr.s6_addr, sizeof(struct in6_addr));   memcpy(&rt.rtmsg_dst, sa6.sin6_addr.s6_addr, sizeof(struct in6_addr));
370    
# Line 423  static void INET6_setroute(int action, c Line 424  static void INET6_setroute(int action, c
424   struct ifreq ifr;   struct ifreq ifr;
425   memset(&ifr, 0, sizeof(ifr));   memset(&ifr, 0, sizeof(ifr));
426   strncpy(ifr.ifr_name, devname, sizeof(ifr.ifr_name));   strncpy(ifr.ifr_name, devname, sizeof(ifr.ifr_name));
427     xioctl(skfd, SIOGIFINDEX, &ifr);
  if (ioctl(skfd, SIOGIFINDEX, &ifr) < 0) {  
  bb_perror_msg_and_die("SIOGIFINDEX");  
  }  
428   rt.rtmsg_ifindex = ifr.ifr_ifindex;   rt.rtmsg_ifindex = ifr.ifr_ifindex;
429   }   }
430    
431   /* Tell the kernel to accept this route. */   /* Tell the kernel to accept this route. */
432   if (ioctl(skfd, ((action==RTACTION_ADD) ? SIOCADDRT : SIOCDELRT), &rt)<0) {   if (action == RTACTION_ADD)
433   bb_perror_msg_and_die("SIOC[ADD|DEL]RT");   xioctl(skfd, SIOCADDRT, &rt);
434   }   else
435     xioctl(skfd, SIOCDELRT, &rt);
436    
437   if (ENABLE_FEATURE_CLEAN_UP) close(skfd);   if (ENABLE_FEATURE_CLEAN_UP) close(skfd);
438  }  }
439  #endif  #endif
440    
441  static const unsigned int flagvals[] = { /* Must agree with flagchars[]. */  static const unsigned flagvals[] = { /* Must agree with flagchars[]. */
442   RTF_GATEWAY,   RTF_GATEWAY,
443   RTF_HOST,   RTF_HOST,
444   RTF_REINSTATE,   RTF_REINSTATE,
445   RTF_DYNAMIC,   RTF_DYNAMIC,
446   RTF_MODIFIED,   RTF_MODIFIED,
447  #ifdef CONFIG_FEATURE_IPV6  #if ENABLE_FEATURE_IPV6
448   RTF_DEFAULT,   RTF_DEFAULT,
449   RTF_ADDRCONF,   RTF_ADDRCONF,
450   RTF_CACHE   RTF_CACHE
# Line 455  static const unsigned int flagvals[] = { Line 454  static const unsigned int flagvals[] = {
454  #define IPV4_MASK (RTF_GATEWAY|RTF_HOST|RTF_REINSTATE|RTF_DYNAMIC|RTF_MODIFIED)  #define IPV4_MASK (RTF_GATEWAY|RTF_HOST|RTF_REINSTATE|RTF_DYNAMIC|RTF_MODIFIED)
455  #define IPV6_MASK (RTF_GATEWAY|RTF_HOST|RTF_DEFAULT|RTF_ADDRCONF|RTF_CACHE)  #define IPV6_MASK (RTF_GATEWAY|RTF_HOST|RTF_DEFAULT|RTF_ADDRCONF|RTF_CACHE)
456    
457  static const char flagchars[] = /* Must agree with flagvals[]. */  /* Must agree with flagvals[]. */
458    static const char flagchars[] ALIGN1 =
459   "GHRDM"   "GHRDM"
460  #ifdef CONFIG_FEATURE_IPV6  #if ENABLE_FEATURE_IPV6
461   "DAC"   "DAC"
462  #endif  #endif
463  ;  ;
# Line 476  static void set_flags(char *flagstr, int Line 476  static void set_flags(char *flagstr, int
476  }  }
477    
478  /* also used in netstat */  /* also used in netstat */
479  void displayroutes(int noresolve, int netstatfmt)  void FAST_FUNC bb_displayroutes(int noresolve, int netstatfmt)
480  {  {
481   char devname[64], flags[16], sdest[16], sgw[16];   char devname[64], flags[16], *sdest, *sgw;
482   unsigned long int d, g, m;   unsigned long d, g, m;
483   int flgs, ref, use, metric, mtu, win, ir;   int flgs, ref, use, metric, mtu, win, ir;
484   struct sockaddr_in s_addr;   struct sockaddr_in s_addr;
485   struct in_addr mask;   struct in_addr mask;
486    
487   FILE *fp = xfopen("/proc/net/route", "r");   FILE *fp = xfopen_for_read("/proc/net/route");
488    
489   printf("Kernel IP routing table\n"   printf("Kernel IP routing table\n"
490         "Destination     Gateway         Genmask         Flags %s Iface\n",         "Destination     Gateway         Genmask         Flags %s Iface\n",
# Line 520  void displayroutes(int noresolve, int ne Line 520  void displayroutes(int noresolve, int ne
520   memset(&s_addr, 0, sizeof(struct sockaddr_in));   memset(&s_addr, 0, sizeof(struct sockaddr_in));
521   s_addr.sin_family = AF_INET;   s_addr.sin_family = AF_INET;
522   s_addr.sin_addr.s_addr = d;   s_addr.sin_addr.s_addr = d;
523   INET_rresolve(sdest, sizeof(sdest), &s_addr,   sdest = INET_rresolve(&s_addr, (noresolve | 0x8000), m); /* 'default' instead of '*' */
   (noresolve | 0x8000), m); /* Default instead of *. */  
   
524   s_addr.sin_addr.s_addr = g;   s_addr.sin_addr.s_addr = g;
525   INET_rresolve(sgw, sizeof(sgw), &s_addr,   sgw = INET_rresolve(&s_addr, (noresolve | 0x4000), m); /* Host instead of net */
   (noresolve | 0x4000), m); /* Host instead of net. */  
   
526   mask.s_addr = m;   mask.s_addr = m;
527   printf("%-16s%-16s%-16s%-6s", sdest, sgw, inet_ntoa(mask), flags);   /* "%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);
531   if (netstatfmt) {   if (netstatfmt) {
532   printf("%5d %-5d %6d %s\n", mtu, win, ir, devname);   printf("%5d %-5d %6d %s\n", mtu, win, ir, devname);
533   } else {   } else {
# Line 537  void displayroutes(int noresolve, int ne Line 536  void displayroutes(int noresolve, int ne
536   }   }
537  }  }
538    
539  #ifdef CONFIG_FEATURE_IPV6  #if ENABLE_FEATURE_IPV6
540    
541  static void INET6_displayroutes(int noresolve)  static void INET6_displayroutes(void)
542  {  {
543   char addr6[128], naddr6[128];   char addr6[128], *naddr6;
544   /* In addr6x, we store both 40-byte ':'-delimited ipv6 addresses.   /* In addr6x, we store both 40-byte ':'-delimited ipv6 addresses.
545   * We read the non-delimited strings into the tail of the buffer   * We read the non-delimited strings into the tail of the buffer
546   * using fscanf and then modify the buffer by shifting forward   * using fscanf and then modify the buffer by shifting forward
# Line 553  static void INET6_displayroutes(int nore Line 552  static void INET6_displayroutes(int nore
552   int iflags, metric, refcnt, use, prefix_len, slen;   int iflags, metric, refcnt, use, prefix_len, slen;
553   struct sockaddr_in6 snaddr6;   struct sockaddr_in6 snaddr6;
554    
555   FILE *fp = xfopen("/proc/net/ipv6_route", "r");   FILE *fp = xfopen_for_read("/proc/net/ipv6_route");
556    
557   printf("Kernel IPv6 routing table\n%-44s%-40s"   printf("Kernel IPv6 routing table\n%-44s%-40s"
558    "Flags Metric Ref    Use Iface\n",    "Flags Metric Ref    Use Iface\n",
# Line 562  static void INET6_displayroutes(int nore Line 561  static void INET6_displayroutes(int nore
561   while (1) {   while (1) {
562   int r;   int r;
563   r = fscanf(fp, "%32s%x%*s%x%32s%x%x%x%x%s\n",   r = fscanf(fp, "%32s%x%*s%x%32s%x%x%x%x%s\n",
564     addr6x+14, &prefix_len, &slen, addr6x+40+7,   addr6x+14, &prefix_len, &slen, addr6x+40+7,
565     &metric, &use, &refcnt, &iflags, iface);   &metric, &use, &refcnt, &iflags, iface);
566   if (r != 9) {   if (r != 9) {
567   if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */   if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */
568   break;   break;
# Line 581  static void INET6_displayroutes(int nore Line 580  static void INET6_displayroutes(int nore
580    
581   do {   do {
582   if (!*p) {   if (!*p) {
583   if (i==40) { /* nul terminator for 1st address? */   if (i == 40) { /* nul terminator for 1st address? */
584   addr6x[39] = 0; /* Fixup... need 0 instead of ':'. */   addr6x[39] = 0; /* Fixup... need 0 instead of ':'. */
585   ++p; /* Skip and continue. */   ++p; /* Skip and continue. */
586   continue;   continue;
# Line 589  static void INET6_displayroutes(int nore Line 588  static void INET6_displayroutes(int nore
588   goto ERROR;   goto ERROR;
589   }   }
590   addr6x[i++] = *p++;   addr6x[i++] = *p++;
591   if (!((i+1)%5)) {   if (!((i+1) % 5)) {
592   addr6x[i++] = ':';   addr6x[i++] = ':';
593   }   }
594   } while (i < 40+28+7);   } while (i < 40+28+7);
# Line 606  static void INET6_displayroutes(int nore Line 605  static void INET6_displayroutes(int nore
605   inet_pton(AF_INET6, addr6x + r,   inet_pton(AF_INET6, addr6x + r,
606    (struct sockaddr *) &snaddr6.sin6_addr);    (struct sockaddr *) &snaddr6.sin6_addr);
607   snaddr6.sin6_family = AF_INET6;   snaddr6.sin6_family = AF_INET6;
608   INET6_rresolve(naddr6, sizeof(naddr6),   naddr6 = INET6_rresolve((struct sockaddr_in6 *) &snaddr6,
    (struct sockaddr_in6 *) &snaddr6,  
609     0x0fff /* Apparently, upstream never resolves. */     0x0fff /* Apparently, upstream never resolves. */
610     );     );
611    
612   if (!r) { /* 1st pass */   if (!r) { /* 1st pass */
613   snprintf(addr6, sizeof(addr6), "%s/%d", naddr6, prefix_len);   snprintf(addr6, sizeof(addr6), "%s/%d", naddr6, prefix_len);
614   r += 40;   r += 40;
615     free(naddr6);
616   } else { /* 2nd pass */   } else { /* 2nd pass */
617   /* Print the info. */   /* Print the info. */
618   printf("%-43s %-39s %-5s %-6d %-2d %7d %-8s\n",   printf("%-43s %-39s %-5s %-6d %-2d %7d %-8s\n",
619    addr6, naddr6, flags, metric, refcnt, use, iface);   addr6, naddr6, flags, metric, refcnt, use, iface);
620     free(naddr6);
621   break;   break;
622   }   }
623   } while (1);   } while (1);
# Line 626  static void INET6_displayroutes(int nore Line 626  static void INET6_displayroutes(int nore
626    
627  #endif  #endif
628    
629  #define ROUTE_OPT_A 0x01  #define ROUTE_OPT_A     0x01
630  #define ROUTE_OPT_n 0x02  #define ROUTE_OPT_n     0x02
631  #define ROUTE_OPT_e 0x04  #define ROUTE_OPT_e     0x04
632  #define ROUTE_OPT_INET6 0x08 /* Not an actual option. See below. */  #define ROUTE_OPT_INET6 0x08 /* Not an actual option. See below. */
633    
634  /* 1st byte is offset to next entry offset.  2nd byte is return value. */  /* 1st byte is offset to next entry offset.  2nd byte is return value. */
635  static const char tbl_verb[] = /* 2nd byte matches RTACTION_* code */  /* 2nd byte matches RTACTION_* code */
636    static const char tbl_verb[] ALIGN1 =
637   "\006\001add\0"   "\006\001add\0"
638   "\006\002del\0"   "\006\002del\0"
639  /* "\011\002delete\0" */  /* "\011\002delete\0" */
640   "\010\002delete" /* Since last, we can save a byte. */   "\010\002delete"  /* Since it's last, we can save a byte. */
641  ;  ;
642    
643  int route_main(int argc, char **argv)  int route_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
644    int route_main(int argc UNUSED_PARAM, char **argv)
645  {  {
646   unsigned opt;   unsigned opt;
647   int what;   int what;
# Line 649  int route_main(int argc, char **argv) Line 651  int route_main(int argc, char **argv)
651   /* First, remap '-net' and '-host' to avoid getopt problems. */   /* First, remap '-net' and '-host' to avoid getopt problems. */
652   p = argv;   p = argv;
653   while (*++p) {   while (*++p) {
654   if ((strcmp(*p, "-net") == 0) || (strcmp(*p, "-host") == 0)) {   if (strcmp(*p, "-net") == 0 || strcmp(*p, "-host") == 0) {
655   p[0][0] = '#';   p[0][0] = '#';
656   }   }
657   }   }
658    
659   opt = getopt32(argc, argv, "A:ne", &family);   opt = getopt32(argv, "A:ne", &family);
660    
661   if ((opt & ROUTE_OPT_A) && strcmp(family, "inet")) {   if ((opt & ROUTE_OPT_A) && strcmp(family, "inet") != 0) {
662  #ifdef CONFIG_FEATURE_IPV6  #if ENABLE_FEATURE_IPV6
663   if (strcmp(family, "inet6") == 0) {   if (strcmp(family, "inet6") == 0) {
664   opt |= ROUTE_OPT_INET6; /* Set flag for ipv6. */   opt |= ROUTE_OPT_INET6; /* Set flag for ipv6. */
665   } else   } else
# Line 670  int route_main(int argc, char **argv) Line 672  int route_main(int argc, char **argv)
672   /* No more args means display the routing table. */   /* No more args means display the routing table. */
673   if (!*argv) {   if (!*argv) {
674   int noresolve = (opt & ROUTE_OPT_n) ? 0x0fff : 0;   int noresolve = (opt & ROUTE_OPT_n) ? 0x0fff : 0;
675  #ifdef CONFIG_FEATURE_IPV6  #if ENABLE_FEATURE_IPV6
676   if (opt & ROUTE_OPT_INET6)   if (opt & ROUTE_OPT_INET6)
677   INET6_displayroutes(noresolve);   INET6_displayroutes();
678   else   else
679  #endif  #endif
680   displayroutes(noresolve, opt & ROUTE_OPT_e);   bb_displayroutes(noresolve, opt & ROUTE_OPT_e);
681    
682   fflush_stdout_and_exit(EXIT_SUCCESS);   fflush_stdout_and_exit(EXIT_SUCCESS);
683   }   }
# Line 686  int route_main(int argc, char **argv) Line 688  int route_main(int argc, char **argv)
688   bb_show_usage();   bb_show_usage();
689   }   }
690    
691  #ifdef CONFIG_FEATURE_IPV6  #if ENABLE_FEATURE_IPV6
692   if (opt & ROUTE_OPT_INET6)   if (opt & ROUTE_OPT_INET6)
693   INET6_setroute(what, argv);   INET6_setroute(what, argv);
694   else   else

Legend:
Removed from v.532  
changed lines
  Added in v.816