diff options
-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 3327b27a3..b12bceb45 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) | |||
137 | { | 137 | { |
138 | int count = 0; | 138 | int count = 0; |
139 | char medium[IFNAMSIZ]; | 139 | char medium[IFNAMSIZ]; |
140 | static const char * const keywords[] = { | ||
141 | "mode", "ipip", "ip/ip", "gre", "gre/ip", "sit", "ipv6/ip", | ||
142 | "key", "ikey", "okey", "seq", "iseq", "oseq", | ||
143 | "csum", "icsum", "ocsum", "nopmtudisc", "pmtudisc", | ||
144 | "remote", "any", "local", "dev", | ||
145 | "ttl", "inherit", "tos", "dsfield", | ||
146 | "name", NULL | ||
147 | }; | ||
148 | enum { | ||
149 | ARG_mode, ARG_ipip, ARG_ip_ip, ARG_gre, ARG_gre_ip, ARG_sit, ARG_ip6_ip, | ||
150 | ARG_key, ARG_ikey, ARG_okey, ARG_seq, ARG_iseq, ARG_oseq, | ||
151 | ARG_csum, ARG_icsum, ARG_ocsum, ARG_nopmtudisc, ARG_pmtudisc, | ||
152 | ARG_remote, ARG_any, ARG_local, ARG_dev, | ||
153 | ARG_ttl, ARG_inherit, ARG_tos, ARG_dsfield, | ||
154 | ARG_name | ||
155 | }; | ||
156 | int key; | ||
140 | memset(p, 0, sizeof(*p)); | 157 | memset(p, 0, sizeof(*p)); |
141 | memset(&medium, 0, sizeof(medium)); | 158 | memset(&medium, 0, sizeof(medium)); |
142 | 159 | ||
@@ -148,22 +165,24 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) | |||
148 | p->iph.frag_off = htons(IP_DF); | 165 | p->iph.frag_off = htons(IP_DF); |
149 | 166 | ||
150 | while (argc > 0) { | 167 | while (argc > 0) { |
151 | if (strcmp(*argv, "mode") == 0) { | 168 | key = index_in_str_array(keywords, *argv); |
169 | if (key == ARG_mode) { | ||
152 | NEXT_ARG(); | 170 | NEXT_ARG(); |
153 | if (strcmp(*argv, "ipip") == 0 || | 171 | key = index_in_str_array(keywords, *argv); |
154 | strcmp(*argv, "ip/ip") == 0) { | 172 | if (key == ARG_ipip || |
173 | key == ARG_ip_ip) { | ||
155 | if (p->iph.protocol && p->iph.protocol != IPPROTO_IPIP) { | 174 | if (p->iph.protocol && p->iph.protocol != IPPROTO_IPIP) { |
156 | bb_error_msg_and_die("you managed to ask for more than one tunnel mode"); | 175 | bb_error_msg_and_die("you managed to ask for more than one tunnel mode"); |
157 | } | 176 | } |
158 | p->iph.protocol = IPPROTO_IPIP; | 177 | p->iph.protocol = IPPROTO_IPIP; |
159 | } else if (strcmp(*argv, "gre") == 0 || | 178 | } else if (key == ARG_gre || |
160 | strcmp(*argv, "gre/ip") == 0) { | 179 | key == ARG_gre_ip) { |
161 | if (p->iph.protocol && p->iph.protocol != IPPROTO_GRE) { | 180 | if (p->iph.protocol && p->iph.protocol != IPPROTO_GRE) { |
162 | bb_error_msg_and_die("you managed to ask for more than one tunnel mode"); | 181 | bb_error_msg_and_die("you managed to ask for more than one tunnel mode"); |
163 | } | 182 | } |
164 | p->iph.protocol = IPPROTO_GRE; | 183 | p->iph.protocol = IPPROTO_GRE; |
165 | } else if (strcmp(*argv, "sit") == 0 || | 184 | } else if (key == ARG_sit || |
166 | strcmp(*argv, "ipv6/ip") == 0) { | 185 | key == ARG_ip6_ip) { |
167 | if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) { | 186 | if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) { |
168 | bb_error_msg_and_die("you managed to ask for more than one tunnel mode"); | 187 | bb_error_msg_and_die("you managed to ask for more than one tunnel mode"); |
169 | } | 188 | } |
@@ -171,7 +190,7 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) | |||
171 | } else { | 190 | } else { |
172 | bb_error_msg_and_die("cannot guess tunnel mode"); | 191 | bb_error_msg_and_die("cannot guess tunnel mode"); |
173 | } | 192 | } |
174 | } else if (strcmp(*argv, "key") == 0) { | 193 | } else if (key == ARG_key) { |
175 | unsigned uval; | 194 | unsigned uval; |
176 | NEXT_ARG(); | 195 | NEXT_ARG(); |
177 | p->i_flags |= GRE_KEY; | 196 | p->i_flags |= GRE_KEY; |
@@ -184,7 +203,7 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) | |||
184 | } | 203 | } |
185 | p->i_key = p->o_key = htonl(uval); | 204 | p->i_key = p->o_key = htonl(uval); |
186 | } | 205 | } |
187 | } else if (strcmp(*argv, "ikey") == 0) { | 206 | } else if (key == ARG_ikey) { |
188 | unsigned uval; | 207 | unsigned uval; |
189 | NEXT_ARG(); | 208 | NEXT_ARG(); |
190 | p->i_flags |= GRE_KEY; | 209 | p->i_flags |= GRE_KEY; |
@@ -196,7 +215,7 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) | |||
196 | } | 215 | } |
197 | p->i_key = htonl(uval); | 216 | p->i_key = htonl(uval); |
198 | } | 217 | } |
199 | } else if (strcmp(*argv, "okey") == 0) { | 218 | } else if (key == ARG_okey) { |
200 | unsigned uval; | 219 | unsigned uval; |
201 | NEXT_ARG(); | 220 | NEXT_ARG(); |
202 | p->o_flags |= GRE_KEY; | 221 | p->o_flags |= GRE_KEY; |
@@ -208,57 +227,61 @@ static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) | |||
208 | } | 227 | } |
209 | p->o_key = htonl(uval); | 228 | p->o_key = htonl(uval); |
210 | } | 229 | } |
211 | } else if (strcmp(*argv, "seq") == 0) { | 230 | } else if (key == ARG_seq) { |
212 | p->i_flags |= GRE_SEQ; | 231 | p->i_flags |= GRE_SEQ; |
213 | p->o_flags |= GRE_SEQ; | 232 | p->o_flags |= GRE_SEQ; |
214 | } else if (strcmp(*argv, "iseq") == 0) { | 233 | } else if (key == ARG_iseq) { |
215 | p->i_flags |= GRE_SEQ; | 234 | p->i_flags |= GRE_SEQ; |
216 | } else if (strcmp(*argv, "oseq") == 0) { | 235 | } else if (key == ARG_oseq) { |
217 | p->o_flags |= GRE_SEQ; | 236 | p->o_flags |= GRE_SEQ; |
218 | } else if (strcmp(*argv, "csum") == 0) { | 237 | } else if (key == ARG_csum) { |
219 | p->i_flags |= GRE_CSUM; | 238 | p->i_flags |= GRE_CSUM; |
220 | p->o_flags |= GRE_CSUM; | 239 | p->o_flags |= GRE_CSUM; |
221 | } else if (strcmp(*argv, "icsum") == 0) { | 240 | } else if (key == ARG_icsum) { |
222 | p->i_flags |= GRE_CSUM; | 241 | p->i_flags |= GRE_CSUM; |
223 | } else if (strcmp(*argv, "ocsum") == 0) { | 242 | } else if (key == ARG_ocsum) { |
224 | p->o_flags |= GRE_CSUM; | 243 | p->o_flags |= GRE_CSUM; |
225 | } else if (strcmp(*argv, "nopmtudisc") == 0) { | 244 | } else if (key == ARG_nopmtudisc) { |
226 | p->iph.frag_off = 0; | 245 | p->iph.frag_off = 0; |
227 | } else if (strcmp(*argv, "pmtudisc") == 0) { | 246 | } else if (key == ARG_pmtudisc) { |
228 | p->iph.frag_off = htons(IP_DF); | 247 | p->iph.frag_off = htons(IP_DF); |
229 | } else if (strcmp(*argv, "remote") == 0) { | 248 | } else if (key == ARG_remote) { |
230 | NEXT_ARG(); | 249 | NEXT_ARG(); |
231 | if (strcmp(*argv, "any")) | 250 | key = index_in_str_array(keywords, *argv); |
251 | if (key == ARG_any) | ||
232 | p->iph.daddr = get_addr32(*argv); | 252 | p->iph.daddr = get_addr32(*argv); |
233 | } else if (strcmp(*argv, "local") == 0) { | 253 | } else if (key == ARG_local) { |
234 | NEXT_ARG(); | 254 | NEXT_ARG(); |
235 | if (strcmp(*argv, "any")) | 255 | key = index_in_str_array(keywords, *argv); |
256 | if (key == ARG_any) | ||
236 | p->iph.saddr = get_addr32(*argv); | 257 | p->iph.saddr = get_addr32(*argv); |
237 | } else if (strcmp(*argv, "dev") == 0) { | 258 | } else if (key == ARG_dev) { |
238 | NEXT_ARG(); | 259 | NEXT_ARG(); |
239 | strncpy(medium, *argv, IFNAMSIZ-1); | 260 | strncpy(medium, *argv, IFNAMSIZ-1); |
240 | } else if (strcmp(*argv, "ttl") == 0) { | 261 | } else if (key == ARG_ttl) { |
241 | unsigned uval; | 262 | unsigned uval; |
242 | NEXT_ARG(); | 263 | NEXT_ARG(); |
243 | if (strcmp(*argv, "inherit") != 0) { | 264 | key = index_in_str_array(keywords, *argv); |
265 | if (key != ARG_inherit) { | ||
244 | if (get_unsigned(&uval, *argv, 0)) | 266 | if (get_unsigned(&uval, *argv, 0)) |
245 | invarg(*argv, "TTL"); | 267 | invarg(*argv, "TTL"); |
246 | if (uval > 255) | 268 | if (uval > 255) |
247 | invarg(*argv, "TTL must be <=255"); | 269 | invarg(*argv, "TTL must be <=255"); |
248 | p->iph.ttl = uval; | 270 | p->iph.ttl = uval; |
249 | } | 271 | } |
250 | } else if (strcmp(*argv, "tos") == 0 || | 272 | } else if (key == ARG_tos || |
251 | matches(*argv, "dsfield") == 0) { | 273 | key == ARG_dsfield) { |
252 | uint32_t uval; | 274 | uint32_t uval; |
253 | NEXT_ARG(); | 275 | NEXT_ARG(); |
254 | if (strcmp(*argv, "inherit") != 0) { | 276 | key = index_in_str_array(keywords, *argv); |
277 | if (key != ARG_inherit) { | ||
255 | if (rtnl_dsfield_a2n(&uval, *argv)) | 278 | if (rtnl_dsfield_a2n(&uval, *argv)) |
256 | invarg(*argv, "TOS"); | 279 | invarg(*argv, "TOS"); |
257 | p->iph.tos = uval; | 280 | p->iph.tos = uval; |
258 | } else | 281 | } else |
259 | p->iph.tos = 1; | 282 | p->iph.tos = 1; |
260 | } else { | 283 | } else { |
261 | if (strcmp(*argv, "name") == 0) { | 284 | if (key == ARG_name) { |
262 | NEXT_ARG(); | 285 | NEXT_ARG(); |
263 | } | 286 | } |
264 | if (p->name[0]) | 287 | if (p->name[0]) |
@@ -438,7 +461,7 @@ static void do_tunnels_list(struct ip_tunnel_parm *p) | |||
438 | ptr = strchr(buf, ':'); | 461 | ptr = strchr(buf, ':'); |
439 | if (ptr == NULL || | 462 | if (ptr == NULL || |
440 | (*ptr++ = 0, sscanf(buf, "%s", name) != 1)) { | 463 | (*ptr++ = 0, sscanf(buf, "%s", name) != 1)) { |
441 | bb_error_msg("wrong format of /proc/net/dev. Sorry"); | 464 | bb_error_msg("wrong format of /proc/net/dev"); |
442 | return; | 465 | return; |
443 | } | 466 | } |
444 | if (sscanf(ptr, "%lu%lu%lu%lu%lu%lu%lu%*d%lu%lu%lu%lu%lu%lu%lu", | 467 | 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) | |||
503 | /* Return value becomes exitcode. It's okay to not return at all */ | 526 | /* Return value becomes exitcode. It's okay to not return at all */ |
504 | int do_iptunnel(int argc, char **argv) | 527 | int do_iptunnel(int argc, char **argv) |
505 | { | 528 | { |
529 | static const char * const keywords[] = { | ||
530 | "add", "change", "delete", "show", "list", "lst", NULL | ||
531 | }; | ||
532 | enum {ARG_add = 1, ARG_change, ARG_del, ARG_show, ARG_list, ARG_lst}; | ||
533 | smalluint key = 4; /* show */ | ||
506 | if (argc > 0) { | 534 | if (argc > 0) { |
507 | if (matches(*argv, "add") == 0) | 535 | key = index_in_substr_array(keywords, *argv) +1; |
508 | return do_add(SIOCADDTUNNEL, argc-1, argv+1); | 536 | --argc; |
509 | if (matches(*argv, "change") == 0) | 537 | ++argv; |
510 | return do_add(SIOCCHGTUNNEL, argc-1, argv+1); | ||
511 | if (matches(*argv, "del") == 0) | ||
512 | return do_del(argc-1, argv+1); | ||
513 | if (matches(*argv, "show") == 0 || | ||
514 | matches(*argv, "lst") == 0 || | ||
515 | matches(*argv, "list") == 0) | ||
516 | return do_show(argc-1, argv+1); | ||
517 | } else | 538 | } else |
518 | return do_show(0, NULL); | 539 | return do_show(0, NULL); |
519 | 540 | if (key < ARG_add) | |
520 | bb_error_msg_and_die("command \"%s\" is unknown", *argv); | 541 | bail: |
542 | bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); | ||
543 | |||
544 | if (key == ARG_add) | ||
545 | return do_add(SIOCADDTUNNEL, argc, argv); | ||
546 | if (key == ARG_change) | ||
547 | return do_add(SIOCCHGTUNNEL, argc, argv); | ||
548 | if (key == ARG_del) | ||
549 | return do_del(argc, argv); | ||
550 | if (key == ARG_show || key == ARG_list || key == ARG_lst) | ||
551 | return do_show(argc, argv); | ||
552 | /* be gentle to gcc; avoid warning about non returning */ | ||
553 | goto bail; /* never reached */ | ||
521 | } | 554 | } |
diff --git a/networking/libiproute/rtm_map.c b/networking/libiproute/rtm_map.c index 7fad0ecc8..593017bf1 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) | |||
51 | 51 | ||
52 | int rtnl_rtntype_a2n(int *id, char *arg) | 52 | int rtnl_rtntype_a2n(int *id, char *arg) |
53 | { | 53 | { |
54 | static const char * const keywords[] = { | ||
55 | "local", "nat", "broadcast", "brd", "anycast", | ||
56 | "multicast", "prohibit", "unreachable", "blackhole", | ||
57 | "xresolve", "unicast", "throw", NULL | ||
58 | }; | ||
59 | enum { ARG_local = 1, ARG_nat, ARG_broadcast, ARG_brd, ARG_anycast, | ||
60 | ARG_multicast, ARG_prohibit, ARG_unreachable, ARG_blackhole, | ||
61 | ARG_xresolve, ARG_unicast, ARG_throw | ||
62 | }; | ||
63 | const smalluint key = index_in_substr_array(keywords, arg) + 1; | ||
54 | char *end; | 64 | char *end; |
55 | unsigned long res; | 65 | unsigned long res; |
56 | 66 | ||
57 | if (strcmp(arg, "local") == 0) | 67 | if (key == ARG_local) |
58 | res = RTN_LOCAL; | 68 | res = RTN_LOCAL; |
59 | else if (strcmp(arg, "nat") == 0) | 69 | else if (key == ARG_nat) |
60 | res = RTN_NAT; | 70 | res = RTN_NAT; |
61 | else if (matches(arg, "broadcast") == 0 || | 71 | else if (key == ARG_broadcast || key == ARG_brd) |
62 | strcmp(arg, "brd") == 0) | ||
63 | res = RTN_BROADCAST; | 72 | res = RTN_BROADCAST; |
64 | else if (matches(arg, "anycast") == 0) | 73 | else if (key == ARG_anycast) |
65 | res = RTN_ANYCAST; | 74 | res = RTN_ANYCAST; |
66 | else if (matches(arg, "multicast") == 0) | 75 | else if (key == ARG_multicast) |
67 | res = RTN_MULTICAST; | 76 | res = RTN_MULTICAST; |
68 | else if (matches(arg, "prohibit") == 0) | 77 | else if (key == ARG_prohibit) |
69 | res = RTN_PROHIBIT; | 78 | res = RTN_PROHIBIT; |
70 | else if (matches(arg, "unreachable") == 0) | 79 | else if (key == ARG_unreachable) |
71 | res = RTN_UNREACHABLE; | 80 | res = RTN_UNREACHABLE; |
72 | else if (matches(arg, "blackhole") == 0) | 81 | else if (key == ARG_blackhole) |
73 | res = RTN_BLACKHOLE; | 82 | res = RTN_BLACKHOLE; |
74 | else if (matches(arg, "xresolve") == 0) | 83 | else if (key == ARG_xresolve) |
75 | res = RTN_XRESOLVE; | 84 | res = RTN_XRESOLVE; |
76 | else if (matches(arg, "unicast") == 0) | 85 | else if (key == ARG_unicast) |
77 | res = RTN_UNICAST; | 86 | res = RTN_UNICAST; |
78 | else if (strcmp(arg, "throw") == 0) | 87 | else if (key == ARG_throw) |
79 | res = RTN_THROW; | 88 | res = RTN_THROW; |
80 | else { | 89 | else { |
81 | res = strtoul(arg, &end, 0); | 90 | res = strtoul(arg, &end, 0); |
diff --git a/networking/libiproute/utils.c b/networking/libiproute/utils.c index a0d08246a..e63bb27fb 100644 --- a/networking/libiproute/utils.c +++ b/networking/libiproute/utils.c | |||
@@ -251,13 +251,6 @@ void duparg2(const char *key, const char *arg) | |||
251 | bb_error_msg_and_die("either \"%s\" is duplicate, or \"%s\" is garbage", key, arg); | 251 | bb_error_msg_and_die("either \"%s\" is duplicate, or \"%s\" is garbage", key, arg); |
252 | } | 252 | } |
253 | 253 | ||
254 | int matches(const char *cmd, const char *pattern) | ||
255 | { | ||
256 | int len = strlen(cmd); | ||
257 | |||
258 | return strncmp(pattern, cmd, len); | ||
259 | } | ||
260 | |||
261 | int inet_addr_match(inet_prefix * a, inet_prefix * b, int bits) | 254 | int inet_addr_match(inet_prefix * a, inet_prefix * b, int bits) |
262 | { | 255 | { |
263 | uint32_t *a1 = a->data; | 256 | uint32_t *a1 = a->data; |
diff --git a/networking/libiproute/utils.h b/networking/libiproute/utils.h index 3bbc71d14..2c4dffd95 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 | |||
76 | void invarg(const char *, const char *) ATTRIBUTE_NORETURN; | 76 | void invarg(const char *, const char *) ATTRIBUTE_NORETURN; |
77 | void duparg(const char *, const char *) ATTRIBUTE_NORETURN; | 77 | void duparg(const char *, const char *) ATTRIBUTE_NORETURN; |
78 | void duparg2(const char *, const char *) ATTRIBUTE_NORETURN; | 78 | void duparg2(const char *, const char *) ATTRIBUTE_NORETURN; |
79 | int ATTRIBUTE_DEPRECATED matches(const char *arg, const char *pattern); | ||
80 | int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits); | 79 | int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits); |
81 | 80 | ||
82 | const char *dnet_ntop(int af, const void *addr, char *str, size_t len); | 81 | const char *dnet_ntop(int af, const void *addr, char *str, size_t len); |