X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=networking%2Froute.c;h=a3199621a7bed122e6f011011af9175caa460987;hb=4f731ce30ec2a9f5e9b231b47aa68f32b75feb35;hp=d6d9b7dd964f35b9d184b352780d3855b7c7c292;hpb=98ee06d3d46aa7f89c204681c7075b53300a6a6e;p=oweals%2Fbusybox.git diff --git a/networking/route.c b/networking/route.c index d6d9b7dd9..a3199621a 100644 --- a/networking/route.c +++ b/networking/route.c @@ -12,7 +12,6 @@ * * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. * - * $Id: route.c,v 1.26 2004/03/19 23:27:08 mjn3 Exp $ * * displayroute() code added by Vladimir N. Oleynik * adjustments by Larry Doolittle @@ -26,12 +25,12 @@ * remove ridiculous amounts of bloat. */ -#include "busybox.h" -#include "inet_common.h" -#include #include #include +#include "libbb.h" +#include "inet_common.h" + #ifndef RTF_UP /* Keep this in sync with /usr/src/linux/include/linux/route.h */ @@ -50,7 +49,7 @@ #define RTF_REJECT 0x0200 /* Reject route */ #endif -#if defined (SIOCADDRTOLD) || defined (RTF_IRTT) /* route */ +#if defined(SIOCADDRTOLD) || defined(RTF_IRTT) /* route */ #define HAVE_NEW_ADDRT 1 #endif @@ -63,40 +62,40 @@ #endif /* The RTACTION entries must agree with tbl_verb[] below! */ -#define RTACTION_ADD 1 -#define RTACTION_DEL 2 +#define RTACTION_ADD 1 +#define RTACTION_DEL 2 /* For the various tbl_*[] arrays, the 1st byte is the offset to * the next entry and the 2nd byte is return value. */ -#define NET_FLAG 1 -#define HOST_FLAG 2 +#define NET_FLAG 1 +#define HOST_FLAG 2 /* We remap '-' to '#' to avoid problems with getopt. */ -static const char tbl_hash_net_host[] = +static const char tbl_hash_net_host[] ALIGN1 = "\007\001#net\0" /* "\010\002#host\0" */ "\007\002#host" /* Since last, we can save a byte. */ ; -#define KW_TAKES_ARG 020 -#define KW_SETS_FLAG 040 +#define KW_TAKES_ARG 020 +#define KW_SETS_FLAG 040 -#define KW_IPVx_METRIC 020 -#define KW_IPVx_NETMASK 021 -#define KW_IPVx_GATEWAY 022 -#define KW_IPVx_MSS 023 -#define KW_IPVx_WINDOW 024 -#define KW_IPVx_IRTT 025 -#define KW_IPVx_DEVICE 026 +#define KW_IPVx_METRIC 020 +#define KW_IPVx_NETMASK 021 +#define KW_IPVx_GATEWAY 022 +#define KW_IPVx_MSS 023 +#define KW_IPVx_WINDOW 024 +#define KW_IPVx_IRTT 025 +#define KW_IPVx_DEVICE 026 -#define KW_IPVx_FLAG_ONLY 040 -#define KW_IPVx_REJECT 040 -#define KW_IPVx_MOD 041 -#define KW_IPVx_DYN 042 -#define KW_IPVx_REINSTATE 043 +#define KW_IPVx_FLAG_ONLY 040 +#define KW_IPVx_REJECT 040 +#define KW_IPVx_MOD 041 +#define KW_IPVx_DYN 042 +#define KW_IPVx_REINSTATE 043 -static const char tbl_ipvx[] = +static const char tbl_ipvx[] ALIGN1 = /* 020 is the "takes an arg" bit */ #if HAVE_NEW_ADDRT "\011\020metric\0" @@ -152,7 +151,7 @@ static int kw_lookup(const char *kwtbl, char ***pargs) /* Add or delete a route, depending on action. */ -static void INET_setroute(int action, char **args) +static NOINLINE void INET_setroute(int action, char **args) { struct rtentry rt; const char *netmask = NULL; @@ -167,7 +166,7 @@ static void INET_setroute(int action, char **args) } /* Clean out the RTREQ structure. */ - memset((char *) &rt, 0, sizeof(struct rtentry)); + memset(&rt, 0, sizeof(rt)); { const char *target = *args++; @@ -175,11 +174,11 @@ static void INET_setroute(int action, char **args) /* recognize x.x.x.x/mask format. */ prefix = strchr(target, '/'); - if(prefix) { + if (prefix) { int prefix_len; prefix_len = xatoul_range(prefix+1, 0, 32); - mask_in_addr(rt) = htonl( ~ (0xffffffffUL >> prefix_len)); + mask_in_addr(rt) = htonl( ~(0xffffffffUL >> prefix_len)); *prefix = '\0'; #if HAVE_NEW_ADDRT rt.rt_genmask.sa_family = AF_INET; @@ -194,7 +193,7 @@ static void INET_setroute(int action, char **args) if (isnet < 0) { bb_error_msg_and_die("resolving %s", target); } - if(prefix) { + if (prefix) { /* do not destroy prefix for process args */ *prefix = '/'; } @@ -297,13 +296,13 @@ static void INET_setroute(int action, char **args) #ifdef RTF_REJECT if ((rt.rt_flags & RTF_REJECT) && !rt.rt_dev) { - rt.rt_dev = "lo"; + rt.rt_dev = (char*)"lo"; } #endif /* sanity checks.. */ if (mask_in_addr(rt)) { - unsigned long mask = mask_in_addr(rt); + uint32_t mask = mask_in_addr(rt); mask = ~ntohl(mask); if ((rt.rt_flags & RTF_HOST) && mask != 0xffffffff) { @@ -314,7 +313,7 @@ static void INET_setroute(int action, char **args) bb_error_msg_and_die("bogus netmask %s", netmask); } mask = ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr; - if (mask & ~mask_in_addr(rt)) { + if (mask & ~(uint32_t)mask_in_addr(rt)) { bb_error_msg_and_die("netmask and route address conflict"); } } @@ -327,16 +326,17 @@ static void INET_setroute(int action, char **args) /* Create a socket to the INET kernel. */ skfd = xsocket(AF_INET, SOCK_DGRAM, 0); - if (ioctl(skfd, ((action==RTACTION_ADD) ? SIOCADDRT : SIOCDELRT), &rt)<0) { - bb_perror_msg_and_die("SIOC[ADD|DEL]RT"); - } + if (action == RTACTION_ADD) + xioctl(skfd, SIOCADDRT, &rt); + else + xioctl(skfd, SIOCDELRT, &rt); if (ENABLE_FEATURE_CLEAN_UP) close(skfd); } -#ifdef CONFIG_FEATURE_IPV6 +#if ENABLE_FEATURE_IPV6 -static void INET6_setroute(int action, char **args) +static NOINLINE void INET6_setroute(int action, char **args) { struct sockaddr_in6 sa6; struct in6_rtmsg rt; @@ -351,9 +351,10 @@ static void INET6_setroute(int action, char **args) memset(&sa6, 0, sizeof(sa6)); } else { char *cp; - if ((cp = strchr(target, '/'))) { /* Yes... const to non is ok. */ - *cp = 0; - prefix_len = xatoul_range(cp+1, 0, 128); + cp = strchr(target, '/'); /* Yes... const to non is ok. */ + if (cp) { + *cp = '\0'; + prefix_len = xatoul_range(cp + 1, 0, 128); } else { prefix_len = 128; } @@ -363,7 +364,7 @@ static void INET6_setroute(int action, char **args) } /* Clean out the RTREQ structure. */ - memset((char *) &rt, 0, sizeof(struct in6_rtmsg)); + memset(&rt, 0, sizeof(rt)); memcpy(&rt.rtmsg_dst, sa6.sin6_addr.s6_addr, sizeof(struct in6_addr)); @@ -422,30 +423,28 @@ static void INET6_setroute(int action, char **args) if (devname) { struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, devname, sizeof(ifr.ifr_name)); - - if (ioctl(skfd, SIOGIFINDEX, &ifr) < 0) { - bb_perror_msg_and_die("SIOGIFINDEX"); - } + strncpy_IFNAMSIZ(ifr.ifr_name, devname); + xioctl(skfd, SIOGIFINDEX, &ifr); rt.rtmsg_ifindex = ifr.ifr_ifindex; } /* Tell the kernel to accept this route. */ - if (ioctl(skfd, ((action==RTACTION_ADD) ? SIOCADDRT : SIOCDELRT), &rt)<0) { - bb_perror_msg_and_die("SIOC[ADD|DEL]RT"); - } + if (action == RTACTION_ADD) + xioctl(skfd, SIOCADDRT, &rt); + else + xioctl(skfd, SIOCDELRT, &rt); if (ENABLE_FEATURE_CLEAN_UP) close(skfd); } #endif -static const unsigned int flagvals[] = { /* Must agree with flagchars[]. */ +static const unsigned flagvals[] = { /* Must agree with flagchars[]. */ RTF_GATEWAY, RTF_HOST, RTF_REINSTATE, RTF_DYNAMIC, RTF_MODIFIED, -#ifdef CONFIG_FEATURE_IPV6 +#if ENABLE_FEATURE_IPV6 RTF_DEFAULT, RTF_ADDRCONF, RTF_CACHE @@ -455,9 +454,10 @@ static const unsigned int flagvals[] = { /* Must agree with flagchars[]. */ #define IPV4_MASK (RTF_GATEWAY|RTF_HOST|RTF_REINSTATE|RTF_DYNAMIC|RTF_MODIFIED) #define IPV6_MASK (RTF_GATEWAY|RTF_HOST|RTF_DEFAULT|RTF_ADDRCONF|RTF_CACHE) -static const char flagchars[] = /* Must agree with flagvals[]. */ +/* Must agree with flagvals[]. */ +static const char flagchars[] ALIGN1 = "GHRDM" -#ifdef CONFIG_FEATURE_IPV6 +#if ENABLE_FEATURE_IPV6 "DAC" #endif ; @@ -476,15 +476,15 @@ static void set_flags(char *flagstr, int flags) } /* also used in netstat */ -void displayroutes(int noresolve, int netstatfmt) +void FAST_FUNC bb_displayroutes(int noresolve, int netstatfmt) { - char devname[64], flags[16], sdest[16], sgw[16]; - unsigned long int d, g, m; + char devname[64], flags[16], *sdest, *sgw; + unsigned long d, g, m; int flgs, ref, use, metric, mtu, win, ir; struct sockaddr_in s_addr; struct in_addr mask; - FILE *fp = xfopen("/proc/net/route", "r"); + FILE *fp = xfopen_for_read("/proc/net/route"); printf("Kernel IP routing table\n" "Destination Gateway Genmask Flags %s Iface\n", @@ -520,15 +520,14 @@ void displayroutes(int noresolve, int netstatfmt) memset(&s_addr, 0, sizeof(struct sockaddr_in)); s_addr.sin_family = AF_INET; s_addr.sin_addr.s_addr = d; - INET_rresolve(sdest, sizeof(sdest), &s_addr, - (noresolve | 0x8000), m); /* Default instead of *. */ - + sdest = INET_rresolve(&s_addr, (noresolve | 0x8000), m); /* 'default' instead of '*' */ s_addr.sin_addr.s_addr = g; - INET_rresolve(sgw, sizeof(sgw), &s_addr, - (noresolve | 0x4000), m); /* Host instead of net. */ - + sgw = INET_rresolve(&s_addr, (noresolve | 0x4000), m); /* Host instead of net */ mask.s_addr = m; - printf("%-16s%-16s%-16s%-6s", sdest, sgw, inet_ntoa(mask), flags); + /* "%15.15s" truncates hostnames, do we really want that? */ + printf("%-15.15s %-15.15s %-16s%-6s", sdest, sgw, inet_ntoa(mask), flags); + free(sdest); + free(sgw); if (netstatfmt) { printf("%5d %-5d %6d %s\n", mtu, win, ir, devname); } else { @@ -537,11 +536,11 @@ void displayroutes(int noresolve, int netstatfmt) } } -#ifdef CONFIG_FEATURE_IPV6 +#if ENABLE_FEATURE_IPV6 -static void INET6_displayroutes(int noresolve) +static void INET6_displayroutes(void) { - char addr6[128], naddr6[128]; + char addr6[128], *naddr6; /* In addr6x, we store both 40-byte ':'-delimited ipv6 addresses. * We read the non-delimited strings into the tail of the buffer * using fscanf and then modify the buffer by shifting forward @@ -553,7 +552,7 @@ static void INET6_displayroutes(int noresolve) int iflags, metric, refcnt, use, prefix_len, slen; struct sockaddr_in6 snaddr6; - FILE *fp = xfopen("/proc/net/ipv6_route", "r"); + FILE *fp = xfopen_for_read("/proc/net/ipv6_route"); printf("Kernel IPv6 routing table\n%-44s%-40s" "Flags Metric Ref Use Iface\n", @@ -562,8 +561,8 @@ static void INET6_displayroutes(int noresolve) while (1) { int r; r = fscanf(fp, "%32s%x%*s%x%32s%x%x%x%x%s\n", - addr6x+14, &prefix_len, &slen, addr6x+40+7, - &metric, &use, &refcnt, &iflags, iface); + addr6x+14, &prefix_len, &slen, addr6x+40+7, + &metric, &use, &refcnt, &iflags, iface); if (r != 9) { if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */ break; @@ -581,7 +580,7 @@ static void INET6_displayroutes(int noresolve) do { if (!*p) { - if (i==40) { /* nul terminator for 1st address? */ + if (i == 40) { /* nul terminator for 1st address? */ addr6x[39] = 0; /* Fixup... need 0 instead of ':'. */ ++p; /* Skip and continue. */ continue; @@ -589,7 +588,7 @@ static void INET6_displayroutes(int noresolve) goto ERROR; } addr6x[i++] = *p++; - if (!((i+1)%5)) { + if (!((i+1) % 5)) { addr6x[i++] = ':'; } } while (i < 40+28+7); @@ -606,18 +605,19 @@ static void INET6_displayroutes(int noresolve) inet_pton(AF_INET6, addr6x + r, (struct sockaddr *) &snaddr6.sin6_addr); snaddr6.sin6_family = AF_INET6; - INET6_rresolve(naddr6, sizeof(naddr6), - (struct sockaddr_in6 *) &snaddr6, + naddr6 = INET6_rresolve((struct sockaddr_in6 *) &snaddr6, 0x0fff /* Apparently, upstream never resolves. */ ); if (!r) { /* 1st pass */ snprintf(addr6, sizeof(addr6), "%s/%d", naddr6, prefix_len); r += 40; + free(naddr6); } else { /* 2nd pass */ /* Print the info. */ printf("%-43s %-39s %-5s %-6d %-2d %7d %-8s\n", - addr6, naddr6, flags, metric, refcnt, use, iface); + addr6, naddr6, flags, metric, refcnt, use, iface); + free(naddr6); break; } } while (1); @@ -626,20 +626,22 @@ static void INET6_displayroutes(int noresolve) #endif -#define ROUTE_OPT_A 0x01 -#define ROUTE_OPT_n 0x02 -#define ROUTE_OPT_e 0x04 -#define ROUTE_OPT_INET6 0x08 /* Not an actual option. See below. */ +#define ROUTE_OPT_A 0x01 +#define ROUTE_OPT_n 0x02 +#define ROUTE_OPT_e 0x04 +#define ROUTE_OPT_INET6 0x08 /* Not an actual option. See below. */ /* 1st byte is offset to next entry offset. 2nd byte is return value. */ -static const char tbl_verb[] = /* 2nd byte matches RTACTION_* code */ +/* 2nd byte matches RTACTION_* code */ +static const char tbl_verb[] ALIGN1 = "\006\001add\0" "\006\002del\0" /* "\011\002delete\0" */ - "\010\002delete" /* Since last, we can save a byte. */ + "\010\002delete" /* Since it's last, we can save a byte. */ ; -int route_main(int argc, char **argv) +int route_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int route_main(int argc UNUSED_PARAM, char **argv) { unsigned opt; int what; @@ -649,15 +651,15 @@ int route_main(int argc, char **argv) /* First, remap '-net' and '-host' to avoid getopt problems. */ p = argv; while (*++p) { - if ((strcmp(*p, "-net") == 0) || (strcmp(*p, "-host") == 0)) { + if (strcmp(*p, "-net") == 0 || strcmp(*p, "-host") == 0) { p[0][0] = '#'; } } - opt = getopt32(argc, argv, "A:ne", &family); + opt = getopt32(argv, "A:ne", &family); - if ((opt & ROUTE_OPT_A) && strcmp(family, "inet")) { -#ifdef CONFIG_FEATURE_IPV6 + if ((opt & ROUTE_OPT_A) && strcmp(family, "inet") != 0) { +#if ENABLE_FEATURE_IPV6 if (strcmp(family, "inet6") == 0) { opt |= ROUTE_OPT_INET6; /* Set flag for ipv6. */ } else @@ -670,12 +672,12 @@ int route_main(int argc, char **argv) /* No more args means display the routing table. */ if (!*argv) { int noresolve = (opt & ROUTE_OPT_n) ? 0x0fff : 0; -#ifdef CONFIG_FEATURE_IPV6 +#if ENABLE_FEATURE_IPV6 if (opt & ROUTE_OPT_INET6) - INET6_displayroutes(noresolve); + INET6_displayroutes(); else #endif - displayroutes(noresolve, opt & ROUTE_OPT_e); + bb_displayroutes(noresolve, opt & ROUTE_OPT_e); fflush_stdout_and_exit(EXIT_SUCCESS); } @@ -686,7 +688,7 @@ int route_main(int argc, char **argv) bb_show_usage(); } -#ifdef CONFIG_FEATURE_IPV6 +#if ENABLE_FEATURE_IPV6 if (opt & ROUTE_OPT_INET6) INET6_setroute(what, argv); else