diff options
-rw-r--r-- | networking/libiproute/ip_parse_common_args.c | 2 | ||||
-rw-r--r-- | networking/libiproute/ipaddress.c | 32 | ||||
-rw-r--r-- | networking/libiproute/iprule.c | 59 |
3 files changed, 50 insertions, 43 deletions
diff --git a/networking/libiproute/ip_parse_common_args.c b/networking/libiproute/ip_parse_common_args.c index 3606d3877..a6ab39924 100644 --- a/networking/libiproute/ip_parse_common_args.c +++ b/networking/libiproute/ip_parse_common_args.c | |||
@@ -30,7 +30,7 @@ void ip_parse_common_args(int *argcp, char ***argvp) | |||
30 | {"-family", "inet", "inet6", "link", | 30 | {"-family", "inet", "inet6", "link", |
31 | "-4", "-6", "-0", "-oneline", 0}; | 31 | "-4", "-6", "-0", "-oneline", 0}; |
32 | enum { | 32 | enum { |
33 | ARG_family, | 33 | ARG_family = 1, |
34 | ARG_inet, | 34 | ARG_inet, |
35 | ARG_inet6, | 35 | ARG_inet6, |
36 | ARG_link, | 36 | ARG_link, |
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index e504862a9..a4add6a47 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c | |||
@@ -604,7 +604,6 @@ static int ipaddr_modify(int cmd, int argc, char **argv) | |||
604 | "peer", "remote", "broadcast", "brd", | 604 | "peer", "remote", "broadcast", "brd", |
605 | "anycast", "scope", "dev", "label", "local", 0 | 605 | "anycast", "scope", "dev", "label", "local", 0 |
606 | }; | 606 | }; |
607 | |||
608 | struct rtnl_handle rth; | 607 | struct rtnl_handle rth; |
609 | struct { | 608 | struct { |
610 | struct nlmsghdr n; | 609 | struct nlmsghdr n; |
@@ -619,7 +618,7 @@ static int ipaddr_modify(int cmd, int argc, char **argv) | |||
619 | int peer_len = 0; | 618 | int peer_len = 0; |
620 | int brd_len = 0; | 619 | int brd_len = 0; |
621 | int any_len = 0; | 620 | int any_len = 0; |
622 | int scoped = 0; | 621 | bool scoped = 0; |
623 | 622 | ||
624 | memset(&req, 0, sizeof(req)); | 623 | memset(&req, 0, sizeof(req)); |
625 | 624 | ||
@@ -724,7 +723,7 @@ static int ipaddr_modify(int cmd, int argc, char **argv) | |||
724 | bb_error_msg(bb_msg_requires_arg,"\"dev\""); | 723 | bb_error_msg(bb_msg_requires_arg,"\"dev\""); |
725 | return -1; | 724 | return -1; |
726 | } | 725 | } |
727 | if (l && matches(d, l) != 0) { | 726 | if (l && strncmp(d, l, strlen(d)) != 0) { |
728 | bb_error_msg_and_die("\"dev\" (%s) must match \"label\" (%s)", d, l); | 727 | bb_error_msg_and_die("\"dev\" (%s) must match \"label\" (%s)", d, l); |
729 | } | 728 | } |
730 | 729 | ||
@@ -775,22 +774,21 @@ int do_ipaddr(int argc, char **argv) | |||
775 | "add", "delete", "list", "show", "lst", "flush", 0 | 774 | "add", "delete", "list", "show", "lst", "flush", 0 |
776 | }; | 775 | }; |
777 | 776 | ||
778 | int command_num = 2; | 777 | int command_num = 2; /* default command is list */ |
779 | 778 | ||
780 | if (*argv) { | 779 | if (*argv) { |
781 | command_num = index_in_substr_array(commands, *argv); | 780 | command_num = index_in_substr_array(commands, *argv); |
782 | } | 781 | } |
783 | switch (command_num) { | 782 | if (command_num < 0 || command_num > 5) |
784 | case 0: /* add */ | 783 | bb_error_msg_and_die("unknown command %s", *argv); |
785 | return ipaddr_modify(RTM_NEWADDR, argc-1, argv+1); | 784 | --argc; |
786 | case 1: /* delete */ | 785 | ++argv; |
787 | return ipaddr_modify(RTM_DELADDR, argc-1, argv+1); | 786 | if (command_num == 0) /* add */ |
788 | case 2: /* list */ | 787 | return ipaddr_modify(RTM_NEWADDR, argc, argv); |
789 | case 3: /* show */ | 788 | else if (command_num == 1) /* delete */ |
790 | case 4: /* lst */ | 789 | return ipaddr_modify(RTM_DELADDR, argc, argv); |
791 | return ipaddr_list_or_flush(argc-1, argv+1, 0); | 790 | else if (command_num == 5) /* flush */ |
792 | case 5: /* flush */ | 791 | return ipaddr_list_or_flush(argc, argv, 1); |
793 | return ipaddr_list_or_flush(argc-1, argv+1, 1); | 792 | else /* 2 == list, 3 == show, 4 == lst */ |
794 | } | 793 | return ipaddr_list_or_flush(argc, argv, 0); |
795 | bb_error_msg_and_die("unknown command %s", *argv); | ||
796 | } | 794 | } |
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c index e2e96f023..a62eae1fe 100644 --- a/networking/libiproute/iprule.c +++ b/networking/libiproute/iprule.c | |||
@@ -184,17 +184,24 @@ static int iprule_list(int argc, char **argv) | |||
184 | return 0; | 184 | return 0; |
185 | } | 185 | } |
186 | 186 | ||
187 | |||
188 | /* Return value becomes exitcode. It's okay to not return at all */ | 187 | /* Return value becomes exitcode. It's okay to not return at all */ |
189 | static int iprule_modify(int cmd, int argc, char **argv) | 188 | static int iprule_modify(int cmd, int argc, char **argv) |
190 | { | 189 | { |
191 | int table_ok = 0; | 190 | bool table_ok = 0; |
192 | struct rtnl_handle rth; | 191 | struct rtnl_handle rth; |
193 | struct { | 192 | struct { |
194 | struct nlmsghdr n; | 193 | struct nlmsghdr n; |
195 | struct rtmsg r; | 194 | struct rtmsg r; |
196 | char buf[1024]; | 195 | char buf[1024]; |
197 | } req; | 196 | } req; |
197 | static const char * const keywords[] = | ||
198 | { "from", "to", "preference", "order", "priority", "tos", "fwmark", | ||
199 | "realms", "table", "lookup", "dev", "iif", "nat", "map-to", "type", | ||
200 | "help", NULL}; | ||
201 | enum { ARG_from = 1, ARG_to, ARG_preference, ARG_order, ARG_priority, | ||
202 | ARG_tos, ARG_fwmark, ARG_realms, ARG_table, ARG_lookup, ARG_dev, | ||
203 | ARG_iif, ARG_nat, ARG_map_to, ARG_type, ARG_help }; | ||
204 | smalluint key; | ||
198 | 205 | ||
199 | memset(&req, 0, sizeof(req)); | 206 | memset(&req, 0, sizeof(req)); |
200 | 207 | ||
@@ -213,72 +220,74 @@ static int iprule_modify(int cmd, int argc, char **argv) | |||
213 | } | 220 | } |
214 | 221 | ||
215 | while (argc > 0) { | 222 | while (argc > 0) { |
216 | if (strcmp(*argv, "from") == 0) { | 223 | key = index_in_substr_array(keywords, *argv) + 1; |
224 | if (key == 0) /* no match found in keywords array, bail out. */ | ||
225 | bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); | ||
226 | if (key == ARG_from) { | ||
217 | inet_prefix dst; | 227 | inet_prefix dst; |
218 | NEXT_ARG(); | 228 | NEXT_ARG(); |
219 | get_prefix(&dst, *argv, req.r.rtm_family); | 229 | get_prefix(&dst, *argv, req.r.rtm_family); |
220 | req.r.rtm_src_len = dst.bitlen; | 230 | req.r.rtm_src_len = dst.bitlen; |
221 | addattr_l(&req.n, sizeof(req), RTA_SRC, &dst.data, dst.bytelen); | 231 | addattr_l(&req.n, sizeof(req), RTA_SRC, &dst.data, dst.bytelen); |
222 | } else if (strcmp(*argv, "to") == 0) { | 232 | } else if (key == ARG_to) { |
223 | inet_prefix dst; | 233 | inet_prefix dst; |
224 | NEXT_ARG(); | 234 | NEXT_ARG(); |
225 | get_prefix(&dst, *argv, req.r.rtm_family); | 235 | get_prefix(&dst, *argv, req.r.rtm_family); |
226 | req.r.rtm_dst_len = dst.bitlen; | 236 | req.r.rtm_dst_len = dst.bitlen; |
227 | addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen); | 237 | addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen); |
228 | } else if (matches(*argv, "preference") == 0 || | 238 | } else if (key == ARG_preference || |
229 | matches(*argv, "order") == 0 || | 239 | key == ARG_order || |
230 | matches(*argv, "priority") == 0) { | 240 | key == ARG_priority) { |
231 | uint32_t pref; | 241 | uint32_t pref; |
232 | NEXT_ARG(); | 242 | NEXT_ARG(); |
233 | if (get_u32(&pref, *argv, 0)) | 243 | if (get_u32(&pref, *argv, 0)) |
234 | invarg("preference value", *argv); | 244 | invarg(*argv, "preference"); |
235 | addattr32(&req.n, sizeof(req), RTA_PRIORITY, pref); | 245 | addattr32(&req.n, sizeof(req), RTA_PRIORITY, pref); |
236 | } else if (strcmp(*argv, "tos") == 0) { | 246 | } else if (key == ARG_tos) { |
237 | uint32_t tos; | 247 | uint32_t tos; |
238 | NEXT_ARG(); | 248 | NEXT_ARG(); |
239 | if (rtnl_dsfield_a2n(&tos, *argv)) | 249 | if (rtnl_dsfield_a2n(&tos, *argv)) |
240 | invarg("TOS value", *argv); | 250 | invarg(*argv, "TOS"); |
241 | req.r.rtm_tos = tos; | 251 | req.r.rtm_tos = tos; |
242 | } else if (strcmp(*argv, "fwmark") == 0) { | 252 | } else if (key == ARG_fwmark) { |
243 | uint32_t fwmark; | 253 | uint32_t fwmark; |
244 | NEXT_ARG(); | 254 | NEXT_ARG(); |
245 | if (get_u32(&fwmark, *argv, 0)) | 255 | if (get_u32(&fwmark, *argv, 0)) |
246 | invarg("fwmark value", *argv); | 256 | invarg(*argv, "fwmark"); |
247 | addattr32(&req.n, sizeof(req), RTA_PROTOINFO, fwmark); | 257 | addattr32(&req.n, sizeof(req), RTA_PROTOINFO, fwmark); |
248 | } else if (matches(*argv, "realms") == 0) { | 258 | } else if (key == ARG_realms) { |
249 | uint32_t realm; | 259 | uint32_t realm; |
250 | NEXT_ARG(); | 260 | NEXT_ARG(); |
251 | if (get_rt_realms(&realm, *argv)) | 261 | if (get_rt_realms(&realm, *argv)) |
252 | invarg("realms", *argv); | 262 | invarg(*argv, "realms"); |
253 | addattr32(&req.n, sizeof(req), RTA_FLOW, realm); | 263 | addattr32(&req.n, sizeof(req), RTA_FLOW, realm); |
254 | } else if (matches(*argv, "table") == 0 || | 264 | } else if (key == ARG_table || |
255 | strcmp(*argv, "lookup") == 0) { | 265 | key == ARG_lookup) { |
256 | uint32_t tid; | 266 | uint32_t tid; |
257 | NEXT_ARG(); | 267 | NEXT_ARG(); |
258 | if (rtnl_rttable_a2n(&tid, *argv)) | 268 | if (rtnl_rttable_a2n(&tid, *argv)) |
259 | invarg("table ID", *argv); | 269 | invarg(*argv, "table ID"); |
260 | req.r.rtm_table = tid; | 270 | req.r.rtm_table = tid; |
261 | table_ok = 1; | 271 | table_ok = 1; |
262 | } else if (strcmp(*argv, "dev") == 0 || | 272 | } else if (key == ARG_dev || |
263 | strcmp(*argv, "iif") == 0) { | 273 | key == ARG_iif) { |
264 | NEXT_ARG(); | 274 | NEXT_ARG(); |
265 | addattr_l(&req.n, sizeof(req), RTA_IIF, *argv, strlen(*argv)+1); | 275 | addattr_l(&req.n, sizeof(req), RTA_IIF, *argv, strlen(*argv)+1); |
266 | } else if (strcmp(*argv, "nat") == 0 || | 276 | } else if (key == ARG_nat || |
267 | matches(*argv, "map-to") == 0) { | 277 | key == ARG_map_to) { |
268 | NEXT_ARG(); | 278 | NEXT_ARG(); |
269 | addattr32(&req.n, sizeof(req), RTA_GATEWAY, get_addr32(*argv)); | 279 | addattr32(&req.n, sizeof(req), RTA_GATEWAY, get_addr32(*argv)); |
270 | req.r.rtm_type = RTN_NAT; | 280 | req.r.rtm_type = RTN_NAT; |
271 | } else { | 281 | } else { |
272 | int type; | 282 | int type; |
273 | 283 | ||
274 | if (strcmp(*argv, "type") == 0) { | 284 | if (key == ARG_type) { |
275 | NEXT_ARG(); | 285 | NEXT_ARG(); |
276 | } | 286 | } |
277 | if (matches(*argv, "help") == 0) | 287 | if (key == ARG_help) |
278 | bb_show_usage(); | 288 | bb_show_usage(); |
279 | if (rtnl_rtntype_a2n(&type, *argv)) | 289 | if (rtnl_rtntype_a2n(&type, *argv)) |
280 | // bogus-looking error message "invalid argument 'cannot parse rule type' to '<*argv>'" | 290 | invarg(*argv, "type"); |
281 | invarg("cannot parse rule type", *argv); | ||
282 | req.r.rtm_type = type; | 291 | req.r.rtm_type = type; |
283 | } | 292 | } |
284 | argc--; | 293 | argc--; |