aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--networking/libiproute/ip_parse_common_args.c2
-rw-r--r--networking/libiproute/ipaddress.c32
-rw-r--r--networking/libiproute/iprule.c59
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 */
189static int iprule_modify(int cmd, int argc, char **argv) 188static 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--;