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) {"-family", "inet", "inet6", "link", "-4", "-6", "-0", "-oneline", 0}; enum { - ARG_family, + ARG_family = 1, ARG_inet, ARG_inet6, 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) "peer", "remote", "broadcast", "brd", "anycast", "scope", "dev", "label", "local", 0 }; - struct rtnl_handle rth; struct { struct nlmsghdr n; @@ -619,7 +618,7 @@ static int ipaddr_modify(int cmd, int argc, char **argv) int peer_len = 0; int brd_len = 0; int any_len = 0; - int scoped = 0; + bool scoped = 0; memset(&req, 0, sizeof(req)); @@ -724,7 +723,7 @@ static int ipaddr_modify(int cmd, int argc, char **argv) bb_error_msg(bb_msg_requires_arg,"\"dev\""); return -1; } - if (l && matches(d, l) != 0) { + if (l && strncmp(d, l, strlen(d)) != 0) { bb_error_msg_and_die("\"dev\" (%s) must match \"label\" (%s)", d, l); } @@ -775,22 +774,21 @@ int do_ipaddr(int argc, char **argv) "add", "delete", "list", "show", "lst", "flush", 0 }; - int command_num = 2; + int command_num = 2; /* default command is list */ if (*argv) { command_num = index_in_substr_array(commands, *argv); } - switch (command_num) { - case 0: /* add */ - return ipaddr_modify(RTM_NEWADDR, argc-1, argv+1); - case 1: /* delete */ - return ipaddr_modify(RTM_DELADDR, argc-1, argv+1); - case 2: /* list */ - case 3: /* show */ - case 4: /* lst */ - return ipaddr_list_or_flush(argc-1, argv+1, 0); - case 5: /* flush */ - return ipaddr_list_or_flush(argc-1, argv+1, 1); - } - bb_error_msg_and_die("unknown command %s", *argv); + if (command_num < 0 || command_num > 5) + bb_error_msg_and_die("unknown command %s", *argv); + --argc; + ++argv; + if (command_num == 0) /* add */ + return ipaddr_modify(RTM_NEWADDR, argc, argv); + else if (command_num == 1) /* delete */ + return ipaddr_modify(RTM_DELADDR, argc, argv); + else if (command_num == 5) /* flush */ + return ipaddr_list_or_flush(argc, argv, 1); + else /* 2 == list, 3 == show, 4 == lst */ + return ipaddr_list_or_flush(argc, argv, 0); } 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) return 0; } - /* Return value becomes exitcode. It's okay to not return at all */ static int iprule_modify(int cmd, int argc, char **argv) { - int table_ok = 0; + bool table_ok = 0; struct rtnl_handle rth; struct { struct nlmsghdr n; struct rtmsg r; char buf[1024]; } req; + static const char * const keywords[] = + { "from", "to", "preference", "order", "priority", "tos", "fwmark", + "realms", "table", "lookup", "dev", "iif", "nat", "map-to", "type", + "help", NULL}; + enum { ARG_from = 1, ARG_to, ARG_preference, ARG_order, ARG_priority, + ARG_tos, ARG_fwmark, ARG_realms, ARG_table, ARG_lookup, ARG_dev, + ARG_iif, ARG_nat, ARG_map_to, ARG_type, ARG_help }; + smalluint key; memset(&req, 0, sizeof(req)); @@ -213,72 +220,74 @@ static int iprule_modify(int cmd, int argc, char **argv) } while (argc > 0) { - if (strcmp(*argv, "from") == 0) { + key = index_in_substr_array(keywords, *argv) + 1; + if (key == 0) /* no match found in keywords array, bail out. */ + bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); + if (key == ARG_from) { inet_prefix dst; NEXT_ARG(); get_prefix(&dst, *argv, req.r.rtm_family); req.r.rtm_src_len = dst.bitlen; addattr_l(&req.n, sizeof(req), RTA_SRC, &dst.data, dst.bytelen); - } else if (strcmp(*argv, "to") == 0) { + } else if (key == ARG_to) { inet_prefix dst; NEXT_ARG(); get_prefix(&dst, *argv, req.r.rtm_family); req.r.rtm_dst_len = dst.bitlen; addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen); - } else if (matches(*argv, "preference") == 0 || - matches(*argv, "order") == 0 || - matches(*argv, "priority") == 0) { + } else if (key == ARG_preference || + key == ARG_order || + key == ARG_priority) { uint32_t pref; NEXT_ARG(); if (get_u32(&pref, *argv, 0)) - invarg("preference value", *argv); + invarg(*argv, "preference"); addattr32(&req.n, sizeof(req), RTA_PRIORITY, pref); - } else if (strcmp(*argv, "tos") == 0) { + } else if (key == ARG_tos) { uint32_t tos; NEXT_ARG(); if (rtnl_dsfield_a2n(&tos, *argv)) - invarg("TOS value", *argv); + invarg(*argv, "TOS"); req.r.rtm_tos = tos; - } else if (strcmp(*argv, "fwmark") == 0) { + } else if (key == ARG_fwmark) { uint32_t fwmark; NEXT_ARG(); if (get_u32(&fwmark, *argv, 0)) - invarg("fwmark value", *argv); + invarg(*argv, "fwmark"); addattr32(&req.n, sizeof(req), RTA_PROTOINFO, fwmark); - } else if (matches(*argv, "realms") == 0) { + } else if (key == ARG_realms) { uint32_t realm; NEXT_ARG(); if (get_rt_realms(&realm, *argv)) - invarg("realms", *argv); + invarg(*argv, "realms"); addattr32(&req.n, sizeof(req), RTA_FLOW, realm); - } else if (matches(*argv, "table") == 0 || - strcmp(*argv, "lookup") == 0) { + } else if (key == ARG_table || + key == ARG_lookup) { uint32_t tid; NEXT_ARG(); if (rtnl_rttable_a2n(&tid, *argv)) - invarg("table ID", *argv); + invarg(*argv, "table ID"); req.r.rtm_table = tid; table_ok = 1; - } else if (strcmp(*argv, "dev") == 0 || - strcmp(*argv, "iif") == 0) { + } else if (key == ARG_dev || + key == ARG_iif) { NEXT_ARG(); addattr_l(&req.n, sizeof(req), RTA_IIF, *argv, strlen(*argv)+1); - } else if (strcmp(*argv, "nat") == 0 || - matches(*argv, "map-to") == 0) { + } else if (key == ARG_nat || + key == ARG_map_to) { NEXT_ARG(); addattr32(&req.n, sizeof(req), RTA_GATEWAY, get_addr32(*argv)); req.r.rtm_type = RTN_NAT; } else { int type; - if (strcmp(*argv, "type") == 0) { + if (key == ARG_type) { NEXT_ARG(); } - if (matches(*argv, "help") == 0) + if (key == ARG_help) bb_show_usage(); if (rtnl_rtntype_a2n(&type, *argv)) -// bogus-looking error message "invalid argument 'cannot parse rule type' to '<*argv>'" - invarg("cannot parse rule type", *argv); + invarg(*argv, "type"); req.r.rtm_type = type; } argc--;