diff options
Diffstat (limited to 'networking')
-rw-r--r-- | networking/libiproute/iptunnel.c | 117 | ||||
-rw-r--r-- | networking/libiproute/rtm_map.c | 33 | ||||
-rw-r--r-- | networking/libiproute/utils.c | 7 | ||||
-rw-r--r-- | networking/libiproute/utils.h | 1 |
4 files changed, 96 insertions, 62 deletions
diff --git a/networking/libiproute/iptunnel.c b/networking/libiproute/iptunnel.c index 3327b27..b12bceb 100644 --- a/networking/libiproute/iptunnel.c +++ b/networking/libiproute/iptunnel.c @@ -137,6 +137,23 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) { int count = 0; char medium[IFNAMSIZ]; + static const char * const keywords[] = { + "mode", "ipip", "ip/ip", "gre", "gre/ip", "sit", "ipv6/ip", + "key", "ikey", "okey", "seq", "iseq", "oseq", + "csum", "icsum", "ocsum", "nopmtudisc", "pmtudisc", + "remote", "any", "local", "dev", + "ttl", "inherit", "tos", "dsfield", + "name", NULL + }; + enum { + ARG_mode, ARG_ipip, ARG_ip_ip, ARG_gre, ARG_gre_ip, ARG_sit, ARG_ip6_ip, + ARG_key, ARG_ikey, ARG_okey, ARG_seq, ARG_iseq, ARG_oseq, + ARG_csum, ARG_icsum, ARG_ocsum, ARG_nopmtudisc, ARG_pmtudisc, + ARG_remote, ARG_any, ARG_local, ARG_dev, + ARG_ttl, ARG_inherit, ARG_tos, ARG_dsfield, + ARG_name + }; + int key; memset(p, 0, sizeof(*p)); memset(&medium, 0, sizeof(medium)); @@ -148,22 +165,24 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) p->iph.frag_off = htons(IP_DF); while (argc > 0) { - if (strcmp(*argv, "mode") == 0) { + key = index_in_str_array(keywords, *argv); + if (key == ARG_mode) { NEXT_ARG(); - if (strcmp(*argv, "ipip") == 0 || - strcmp(*argv, "ip/ip") == 0) { + key = index_in_str_array(keywords, *argv); + if (key == ARG_ipip || + key == ARG_ip_ip) { if (p->iph.protocol && p->iph.protocol != IPPROTO_IPIP) { bb_error_msg_and_die("you managed to ask for more than one tunnel mode"); } p->iph.protocol = IPPROTO_IPIP; - } else if (strcmp(*argv, "gre") == 0 || - strcmp(*argv, "gre/ip") == 0) { + } else if (key == ARG_gre || + key == ARG_gre_ip) { if (p->iph.protocol && p->iph.protocol != IPPROTO_GRE) { bb_error_msg_and_die("you managed to ask for more than one tunnel mode"); } p->iph.protocol = IPPROTO_GRE; - } else if (strcmp(*argv, "sit") == 0 || - strcmp(*argv, "ipv6/ip") == 0) { + } else if (key == ARG_sit || + key == ARG_ip6_ip) { if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) { bb_error_msg_and_die("you managed to ask for more than one tunnel mode"); } @@ -171,7 +190,7 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) } else { bb_error_msg_and_die("cannot guess tunnel mode"); } - } else if (strcmp(*argv, "key") == 0) { + } else if (key == ARG_key) { unsigned uval; NEXT_ARG(); p->i_flags |= GRE_KEY; @@ -184,7 +203,7 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) } p->i_key = p->o_key = htonl(uval); } - } else if (strcmp(*argv, "ikey") == 0) { + } else if (key == ARG_ikey) { unsigned uval; NEXT_ARG(); p->i_flags |= GRE_KEY; @@ -196,7 +215,7 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) } p->i_key = htonl(uval); } - } else if (strcmp(*argv, "okey") == 0) { + } else if (key == ARG_okey) { unsigned uval; NEXT_ARG(); p->o_flags |= GRE_KEY; @@ -208,57 +227,61 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) } p->o_key = htonl(uval); } - } else if (strcmp(*argv, "seq") == 0) { + } else if (key == ARG_seq) { p->i_flags |= GRE_SEQ; p->o_flags |= GRE_SEQ; - } else if (strcmp(*argv, "iseq") == 0) { + } else if (key == ARG_iseq) { p->i_flags |= GRE_SEQ; - } else if (strcmp(*argv, "oseq") == 0) { + } else if (key == ARG_oseq) { p->o_flags |= GRE_SEQ; - } else if (strcmp(*argv, "csum") == 0) { + } else if (key == ARG_csum) { p->i_flags |= GRE_CSUM; p->o_flags |= GRE_CSUM; - } else if (strcmp(*argv, "icsum") == 0) { + } else if (key == ARG_icsum) { p->i_flags |= GRE_CSUM; - } else if (strcmp(*argv, "ocsum") == 0) { + } else if (key == ARG_ocsum) { p->o_flags |= GRE_CSUM; - } else if (strcmp(*argv, "nopmtudisc") == 0) { + } else if (key == ARG_nopmtudisc) { p->iph.frag_off = 0; - } else if (strcmp(*argv, "pmtudisc") == 0) { + } else if (key == ARG_pmtudisc) { p->iph.frag_off = htons(IP_DF); - } else if (strcmp(*argv, "remote") == 0) { + } else if (key == ARG_remote) { NEXT_ARG(); - if (strcmp(*argv, "any")) + key = index_in_str_array(keywords, *argv); + if (key == ARG_any) p->iph.daddr = get_addr32(*argv); - } else if (strcmp(*argv, "local") == 0) { + } else if (key == ARG_local) { NEXT_ARG(); - if (strcmp(*argv, "any")) + key = index_in_str_array(keywords, *argv); + if (key == ARG_any) p->iph.saddr = get_addr32(*argv); - } else if (strcmp(*argv, "dev") == 0) { + } else if (key == ARG_dev) { NEXT_ARG(); strncpy(medium, *argv, IFNAMSIZ-1); - } else if (strcmp(*argv, "ttl") == 0) { + } else if (key == ARG_ttl) { unsigned uval; NEXT_ARG(); - if (strcmp(*argv, "inherit") != 0) { + key = index_in_str_array(keywords, *argv); + if (key != ARG_inherit) { if (get_unsigned(&uval, *argv, 0)) invarg(*argv, "TTL"); if (uval > 255) invarg(*argv, "TTL must be <=255"); p->iph.ttl = uval; } - } else if (strcmp(*argv, "tos") == 0 || - matches(*argv, "dsfield") == 0) { + } else if (key == ARG_tos || + key == ARG_dsfield) { uint32_t uval; NEXT_ARG(); - if (strcmp(*argv, "inherit") != 0) { + key = index_in_str_array(keywords, *argv); + if (key != ARG_inherit) { if (rtnl_dsfield_a2n(&uval, *argv)) invarg(*argv, "TOS"); p->iph.tos = uval; } else p->iph.tos = 1; } else { - if (strcmp(*argv, "name") == 0) { + if (key == ARG_name) { NEXT_ARG(); } if (p->name[0]) @@ -438,7 +461,7 @@ static void do_tunnels_list(struct ip_tunnel_parm *p) ptr = strchr(buf, ':'); if (ptr == NULL || (*ptr++ = 0, sscanf(buf, "%s", name) != 1)) { - bb_error_msg("wrong format of /proc/net/dev. Sorry"); + bb_error_msg("wrong format of /proc/net/dev"); return; } if (sscanf(ptr, "%lu%lu%lu%lu%lu%lu%lu%*d%lu%lu%lu%lu%lu%lu%lu", @@ -503,19 +526,29 @@ static int do_show(int argc, char **argv) /* Return value becomes exitcode. It's okay to not return at all */ int do_iptunnel(int argc, char **argv) { + static const char * const keywords[] = { + "add", "change", "delete", "show", "list", "lst", NULL + }; + enum {ARG_add = 1, ARG_change, ARG_del, ARG_show, ARG_list, ARG_lst}; + smalluint key = 4; /* show */ if (argc > 0) { - if (matches(*argv, "add") == 0) - return do_add(SIOCADDTUNNEL, argc-1, argv+1); - if (matches(*argv, "change") == 0) - return do_add(SIOCCHGTUNNEL, argc-1, argv+1); - if (matches(*argv, "del") == 0) - return do_del(argc-1, argv+1); - if (matches(*argv, "show") == 0 || - matches(*argv, "lst") == 0 || - matches(*argv, "list") == 0) - return do_show(argc-1, argv+1); + key = index_in_substr_array(keywords, *argv) +1; + --argc; + ++argv; } else return do_show(0, NULL); - - bb_error_msg_and_die("command \"%s\" is unknown", *argv); + if (key < ARG_add) + bail: + bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); + + if (key == ARG_add) + return do_add(SIOCADDTUNNEL, argc, argv); + if (key == ARG_change) + return do_add(SIOCCHGTUNNEL, argc, argv); + if (key == ARG_del) + return do_del(argc, argv); + if (key == ARG_show || key == ARG_list || key == ARG_lst) + return do_show(argc, argv); + /* be gentle to gcc; avoid warning about non returning */ + goto bail; /* never reached */ } diff --git a/networking/libiproute/rtm_map.c b/networking/libiproute/rtm_map.c index 7fad0ec..593017b 100644 --- a/networking/libiproute/rtm_map.c +++ b/networking/libiproute/rtm_map.c @@ -51,31 +51,40 @@ const char *rtnl_rtntype_n2a(int id, char *buf, int len) int rtnl_rtntype_a2n(int *id, char *arg) { + static const char * const keywords[] = { + "local", "nat", "broadcast", "brd", "anycast", + "multicast", "prohibit", "unreachable", "blackhole", + "xresolve", "unicast", "throw", NULL + }; + enum { ARG_local = 1, ARG_nat, ARG_broadcast, ARG_brd, ARG_anycast, + ARG_multicast, ARG_prohibit, ARG_unreachable, ARG_blackhole, + ARG_xresolve, ARG_unicast, ARG_throw + }; + const smalluint key = index_in_substr_array(keywords, arg) + 1; char *end; unsigned long res; - if (strcmp(arg, "local") == 0) + if (key == ARG_local) res = RTN_LOCAL; - else if (strcmp(arg, "nat") == 0) + else if (key == ARG_nat) res = RTN_NAT; - else if (matches(arg, "broadcast") == 0 || - strcmp(arg, "brd") == 0) + else if (key == ARG_broadcast || key == ARG_brd) res = RTN_BROADCAST; - else if (matches(arg, "anycast") == 0) + else if (key == ARG_anycast) res = RTN_ANYCAST; - else if (matches(arg, "multicast") == 0) + else if (key == ARG_multicast) res = RTN_MULTICAST; - else if (matches(arg, "prohibit") == 0) + else if (key == ARG_prohibit) res = RTN_PROHIBIT; - else if (matches(arg, "unreachable") == 0) + else if (key == ARG_unreachable) res = RTN_UNREACHABLE; - else if (matches(arg, "blackhole") == 0) + else if (key == ARG_blackhole) res = RTN_BLACKHOLE; - else if (matches(arg, "xresolve") == 0) + else if (key == ARG_xresolve) res = RTN_XRESOLVE; - else if (matches(arg, "unicast") == 0) + else if (key == ARG_unicast) res = RTN_UNICAST; - else if (strcmp(arg, "throw") == 0) + else if (key == ARG_throw) res = RTN_THROW; else { res = strtoul(arg, &end, 0); diff --git a/networking/libiproute/utils.c b/networking/libiproute/utils.c index a0d0824..e63bb27 100644 --- a/networking/libiproute/utils.c +++ b/networking/libiproute/utils.c @@ -251,13 +251,6 @@ void duparg2(const char *key, const char *arg) bb_error_msg_and_die("either \"%s\" is duplicate, or \"%s\" is garbage", key, arg); } -int matches(const char *cmd, const char *pattern) -{ - int len = strlen(cmd); - - return strncmp(pattern, cmd, len); -} - int inet_addr_match(inet_prefix * a, inet_prefix * b, int bits) { uint32_t *a1 = a->data; diff --git a/networking/libiproute/utils.h b/networking/libiproute/utils.h index 3bbc71d..2c4dffd 100644 --- a/networking/libiproute/utils.h +++ b/networking/libiproute/utils.h @@ -76,7 +76,6 @@ extern const char *rt_addr_n2a(int af, int len, void *addr, char *buf, int bufle void invarg(const char *, const char *) ATTRIBUTE_NORETURN; void duparg(const char *, const char *) ATTRIBUTE_NORETURN; void duparg2(const char *, const char *) ATTRIBUTE_NORETURN; -int ATTRIBUTE_DEPRECATED matches(const char *arg, const char *pattern); int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits); const char *dnet_ntop(int af, const void *addr, char *str, size_t len); |