Replace index_in_[sub]str_array with index_in_[sub]strings,
which scans thru "abc\0def\0123\0\0" type strings. Saves 250 bytes.

   text    data     bss     dec     hex filename
 781266    1328   11844  794438   c1f46 busybox_old
 781010    1328   11844  794182   c1e46 busybox_unstripped

diff --git a/networking/libiproute/ip_parse_common_args.c b/networking/libiproute/ip_parse_common_args.c
index 2d597ea..0e429a0 100644
--- a/networking/libiproute/ip_parse_common_args.c
+++ b/networking/libiproute/ip_parse_common_args.c
@@ -26,9 +26,9 @@
 {
 	int argc = *argcp;
 	char **argv = *argvp;
-	static const char * const ip_common_commands[] =
-		{"-family", "inet", "inet6", "link",
-		 "-4", "-6", "-0", "-oneline", 0};
+	static const char ip_common_commands[] =
+		"-family\0""inet\0""inet6\0""link\0"
+		"-4\0""-6\0""-0\0""-oneline\0";
 	enum {
 		ARG_family = 1,
 		ARG_inet,
@@ -53,13 +53,13 @@
 			break;
 		if (opt[1] == '-')
 			opt++;
-		arg = index_in_str_array(ip_common_commands, opt) + 1;
+		arg = index_in_strings(ip_common_commands, opt) + 1;
 		if (arg == ARG_family) {
 			argc--;
 			argv++;
 			if (!argv[1])
 				bb_show_usage();
-			arg = index_in_str_array(ip_common_commands, argv[1]) + 1;
+			arg = index_in_strings(ip_common_commands, argv[1]) + 1;
 			if (arg == ARG_inet)
 				preferred_family = AF_INET;
 			else if (arg == ARG_inet6)
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index 955a9d9..8874fdb 100644
--- a/networking/libiproute/ipaddress.c
+++ b/networking/libiproute/ipaddress.c
@@ -412,7 +412,7 @@
 /* Return value becomes exitcode. It's okay to not return at all */
 int ipaddr_list_or_flush(int argc, char **argv, int flush)
 {
-	static const char *const option[] = { "to", "scope", "up", "label", "dev", 0 };
+	static const char option[] = "to\0""scope\0""up\0""label\0""dev\0";
 
 	struct nlmsg_list *linfo = NULL;
 	struct nlmsg_list *ainfo = NULL;
@@ -437,7 +437,7 @@
 	}
 
 	while (argc > 0) {
-		const int option_num = index_in_str_array(option, *argv);
+		const int option_num = index_in_strings(option, *argv);
 		switch (option_num) {
 			case 0: /* to */
 				NEXT_ARG();
@@ -599,18 +599,17 @@
 /* Return value becomes exitcode. It's okay to not return at all */
 static int ipaddr_modify(int cmd, int argc, char **argv)
 {
-	static const char *const option[] = {
-		"peer", "remote", "broadcast", "brd",
-		"anycast", "scope", "dev", "label", "local", 0
-	};
+	static const char option[] =
+		"peer\0""remote\0""broadcast\0""brd\0"
+		"anycast\0""scope\0""dev\0""label\0""local\0";
 	struct rtnl_handle rth;
 	struct {
-		struct nlmsghdr		n;
-		struct ifaddrmsg	ifa;
-		char			buf[256];
+		struct nlmsghdr  n;
+		struct ifaddrmsg ifa;
+		char             buf[256];
 	} req;
-	char  *d = NULL;
-	char  *l = NULL;
+	char *d = NULL;
+	char *l = NULL;
 	inet_prefix lcl;
 	inet_prefix peer;
 	int local_len = 0;
@@ -627,7 +626,7 @@
 	req.ifa.ifa_family = preferred_family;
 
 	while (argc > 0) {
-		const int option_num = index_in_str_array(option, *argv);
+		const int option_num = index_in_strings(option, *argv);
 		switch (option_num) {
 			case 0: /* peer */
 			case 1: /* remote */
@@ -769,14 +768,13 @@
 /* Return value becomes exitcode. It's okay to not return at all */
 int do_ipaddr(int argc, char **argv)
 {
-	static const char *const commands[] = {
-		"add", "delete", "list", "show", "lst", "flush", 0
-	};
+	static const char commands[] =
+		"add\0""delete\0""list\0""show\0""lst\0""flush\0";
 
 	int command_num = 2; /* default command is list */
 
 	if (*argv) {
-		command_num = index_in_substr_array(commands, *argv);
+		command_num = index_in_substrings(commands, *argv);
 	}
 	if (command_num < 0 || command_num > 5)
 		bb_error_msg_and_die("unknown command %s", *argv);
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c
index 3d3ea2a..69ce84e 100644
--- a/networking/libiproute/iplink.c
+++ b/networking/libiproute/iplink.c
@@ -171,16 +171,15 @@
 	struct ifreq ifr0, ifr1;
 	char *newname = NULL;
 	int htype, halen;
-	static const char * const keywords[] = {
-		"up", "down", "name", "mtu", "multicast", "arp", "addr", "dev",
-		"on", "off", NULL
-	};
+	static const char keywords[] =
+		"up\0""down\0""name\0""mtu\0""multicast\0""arp\0""addr\0""dev\0"
+		"on\0""off\0";
 	enum { ARG_up = 1, ARG_down, ARG_name, ARG_mtu, ARG_multicast, ARG_arp,
 		ARG_addr, ARG_dev, PARM_on, PARM_off };
 	smalluint key;
 
 	while (argc > 0) {
-		key = index_in_str_array(keywords, *argv) + 1;
+		key = index_in_strings(keywords, *argv) + 1;
 		if (key == ARG_up) {
 			mask |= IFF_UP;
 			flags |= IFF_UP;
@@ -199,7 +198,7 @@
 		} else if (key == ARG_multicast) {
 			NEXT_ARG();
 			mask |= IFF_MULTICAST;
-			key = index_in_str_array(keywords, *argv) + 1;
+			key = index_in_strings(keywords, *argv) + 1;
 			if (key == PARM_on) {
 				flags |= IFF_MULTICAST;
 			} else if (key == PARM_off) {
@@ -209,7 +208,7 @@
 		} else if (key == ARG_arp) {
 			NEXT_ARG();
 			mask |= IFF_NOARP;
-			key = index_in_str_array(keywords, *argv) + 1;
+			key = index_in_strings(keywords, *argv) + 1;
 			if (key == PARM_on) {
 				flags &= ~IFF_NOARP;
 			} else if (key == PARM_off) {
@@ -276,13 +275,12 @@
 /* Return value becomes exitcode. It's okay to not return at all */
 int do_iplink(int argc, char **argv)
 {
-	static const char * const keywords[] = {
-		"set", "show", "lst", "list", NULL
-	};
+	static const char keywords[] =
+		"set\0""show\0""lst\0""list\0";
 	smalluint key;
 	if (argc <= 0)
 		return ipaddr_list_link(0, NULL);
-	key = index_in_substr_array(keywords, *argv) + 1;
+	key = index_in_substrings(keywords, *argv) + 1;
 	if (key == 0)
 		bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
 	argc--; argv++;
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index 75e5293..0d171c7 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -294,22 +294,9 @@
 /* Return value becomes exitcode. It's okay to not return at all */
 static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
 {
-	struct rtnl_handle rth;
-	struct {
-		struct nlmsghdr		n;
-		struct rtmsg		r;
-		char			buf[1024];
-	} req;
-	char mxbuf[256];
-	struct rtattr * mxrta = (void*)mxbuf;
-	unsigned mxlock = 0;
-	char *d = NULL;
-	enum { gw_ok = 1<<0, dst_ok = 1<<1, proto_ok = 1<<2, type_ok = 1<<3};
-	smalluint ok = 0;
-	static const char * const keywords[] = {
-		"src", "via", "mtu", "lock", "protocol", USE_FEATURE_IP_RULE("table",)
-		"dev", "oif", "to", NULL
-	};
+	static const char keywords[] =
+		"src\0""via\0""mtu\0""lock\0""protocol\0"USE_FEATURE_IP_RULE("table\0")
+		"dev\0""oif\0""to\0";
 	enum {
 		ARG_src,
 		ARG_via,
@@ -320,6 +307,23 @@
 		ARG_oif,
 		ARG_to
 	};
+	enum {
+		gw_ok = 1 << 0,
+		dst_ok = 1 << 1,
+		proto_ok = 1 << 2,
+		type_ok = 1 << 3
+	};
+	struct rtnl_handle rth;
+	struct {
+		struct nlmsghdr		n;
+		struct rtmsg		r;
+		char			buf[1024];
+	} req;
+	char mxbuf[256];
+	struct rtattr * mxrta = (void*)mxbuf;
+	unsigned mxlock = 0;
+	char *d = NULL;
+	smalluint ok = 0;
 	int arg;
 
 	memset(&req, 0, sizeof(req));
@@ -341,7 +345,7 @@
 	mxrta->rta_len = RTA_LENGTH(0);
 
 	while (argc > 0) {
-		arg = index_in_substr_array(keywords, *argv);
+		arg = index_in_substrings(keywords, *argv);
 		if (arg == ARG_src) {
 			inet_prefix addr;
 			NEXT_ARG();
@@ -361,7 +365,7 @@
 		} else if (arg == ARG_mtu) {
 			unsigned mtu;
 			NEXT_ARG();
-			if (index_in_str_array(keywords, *argv) == PARM_lock) {
+			if (index_in_strings(keywords, *argv) == PARM_lock) {
 				mxlock |= (1<<RTAX_MTU);
 				NEXT_ARG();
 			}
@@ -513,10 +517,9 @@
 	struct rtnl_handle rth;
 	char *id = NULL;
 	char *od = NULL;
-	static const char * const keywords[] = {
-		"protocol", "all", "dev", "oif", "iif", "via", "table", "cache",/*all,*/
-		"from", "root", "match", "exact", "to", /*root,match,exact*/ NULL
-	};
+	static const char keywords[] =
+		"protocol\0""all\0""dev\0""oif\0""iif\0""via\0""table\0""cache\0" /*all*/
+		"from\0""root\0""match\0""exact\0""to\0"/*root match exact*/;
 	enum {
 		ARG_proto, PARM_all,
 		ARG_dev,
@@ -535,13 +538,13 @@
 		bb_error_msg_and_die(bb_msg_requires_arg, "\"ip route flush\"");
 
 	while (argc > 0) {
-		arg = index_in_substr_array(keywords, *argv);
+		arg = index_in_substrings(keywords, *argv);
 		if (arg == ARG_proto) {
 			uint32_t prot = 0;
 			NEXT_ARG();
 			filter.protocolmask = -1;
 			if (rtnl_rtprot_a2n(&prot, *argv)) {
-				if (index_in_str_array(keywords, *argv) != PARM_all)
+				if (index_in_strings(keywords, *argv) != PARM_all)
 					invarg(*argv, "protocol");
 				prot = 0;
 				filter.protocolmask = 0;
@@ -558,7 +561,7 @@
 			get_prefix(&filter.rvia, *argv, do_ipv6);
 		} else if (arg == ARG_table) {
 			NEXT_ARG();
-			parm = index_in_substr_array(keywords, *argv);
+			parm = index_in_substrings(keywords, *argv);
 			if (parm == PARM_cache)
 				filter.tb = -1;
 			else if (parm == PARM_all)
@@ -567,7 +570,7 @@
 				invarg(*argv, "table");
 		} else if (arg == ARG_from) {
 			NEXT_ARG();
-			parm = index_in_substr_array(keywords, *argv);
+			parm = index_in_substrings(keywords, *argv);
 			if (parm == PARM_root) {
 				NEXT_ARG();
 				get_prefix(&filter.rsrc, *argv, do_ipv6);
@@ -584,7 +587,7 @@
 			/* parm = arg; // would be more plausible, we reuse arg here */
 			if (arg == ARG_to) {
 				NEXT_ARG();
-				arg = index_in_substr_array(keywords, *argv);
+				arg = index_in_substrings(keywords, *argv);
 			}
 			if (arg == PARM_root) {
 				NEXT_ARG();
@@ -645,9 +648,8 @@
 			xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
 			filter.flushed = 0;
 			xrtnl_dump_filter(&rth, print_route, stdout);
-			if (filter.flushed == 0) {
+			if (filter.flushed == 0)
 				return 0;
-			}
 			if (flush_update())
 				return 1;
 		}
@@ -655,10 +657,8 @@
 
 	if (filter.tb != -1) {
 		xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
-	} else {
-		if (rtnl_rtcache_request(&rth, do_ipv6) < 0) {
-			bb_perror_msg_and_die("cannot send dump request");
-		}
+	} else if (rtnl_rtcache_request(&rth, do_ipv6) < 0) {
+		bb_perror_msg_and_die("cannot send dump request");
 	}
 	xrtnl_dump_filter(&rth, print_route, stdout);
 
@@ -671,16 +671,16 @@
 {
 	struct rtnl_handle rth;
 	struct {
-		struct nlmsghdr		n;
-		struct rtmsg		r;
-		char			buf[1024];
+		struct nlmsghdr n;
+		struct rtmsg    r;
+		char            buf[1024];
 	} req;
-	char  *idev = NULL;
-	char  *odev = NULL;
+	char *idev = NULL;
+	char *odev = NULL;
 	bool connected = 0;
 	bool from_ok = 0;
-	static const char * const options[] =
-		{ "from", "iif", "oif", "dev", "notify", "connected", "to", 0 };
+	static const char options[] =
+		"from\0""iif\0""oif\0""dev\0""notify\0""connected\0""to\0";
 
 	memset(&req, 0, sizeof(req));
 
@@ -699,7 +699,7 @@
 	req.r.rtm_tos = 0;
 
 	while (argc > 0) {
-		switch (index_in_str_array(options, *argv)) {
+		switch (index_in_strings(options, *argv)) {
 			case 0: /* from */
 			{
 				inet_prefix addr;
@@ -824,19 +824,18 @@
 /* Return value becomes exitcode. It's okay to not return at all */
 int do_iproute(int argc, char **argv)
 {
-	static const char * const ip_route_commands[] = {
-	/*0-3*/	"add", "append", "change", "chg",
-	/*4-7*/	"delete", "get", "list", "show",
-	/*8..*/	"prepend", "replace", "test", "flush", 0
-	};
+	static const char ip_route_commands[] =
+	/*0-3*/	"add\0""append\0""change\0""chg\0"
+	/*4-7*/	"delete\0""get\0""list\0""show\0"
+	/*8..*/	"prepend\0""replace\0""test\0""flush\0";
 	int command_num = 6;
-	unsigned int flags = 0;
+	unsigned flags = 0;
 	int cmd = RTM_NEWROUTE;
 
 	/* "Standard" 'ip r a' treats 'a' as 'add', not 'append' */
 	/* It probably means that it is using "first match" rule */
 	if (*argv) {
-		command_num = index_in_substr_array(ip_route_commands, *argv);
+		command_num = index_in_substrings(ip_route_commands, *argv);
 	}
 	switch (command_num) {
 		case 0: /* add */
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c
index a62eae1..8e2a06f 100644
--- a/networking/libiproute/iprule.c
+++ b/networking/libiproute/iprule.c
@@ -187,6 +187,15 @@
 /* Return value becomes exitcode. It's okay to not return at all */
 static int iprule_modify(int cmd, int argc, char **argv)
 {
+	static const char keywords[] =
+		"from\0""to\0""preference\0""order\0""priority\0"
+		"tos\0""fwmark\0""realms\0""table\0""lookup\0""dev\0"
+		"iif\0""nat\0""map-to\0""type\0""help\0";
+	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
+	};
 	bool table_ok = 0;
 	struct rtnl_handle rth;
 	struct {
@@ -194,13 +203,6 @@
 		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));
@@ -220,7 +222,7 @@
 	}
 
 	while (argc > 0) {
-		key = index_in_substr_array(keywords, *argv) + 1;
+		key = index_in_substrings(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) {
@@ -311,14 +313,14 @@
 /* Return value becomes exitcode. It's okay to not return at all */
 int do_iprule(int argc, char **argv)
 {
-	static const char * const ip_rule_commands[] =
-		{"add", "delete", "list", "show", 0};
+	static const char ip_rule_commands[] =
+		"add\0""delete\0""list\0""show\0";
 	int cmd = 2; /* list */
 
 	if (argc < 1)
 		return iprule_list(0, NULL);
 	if (*argv)
-		cmd = index_in_substr_array(ip_rule_commands, *argv);
+		cmd = index_in_substrings(ip_rule_commands, *argv);
 
 	switch (cmd) {
 		case 0: /* add */
diff --git a/networking/libiproute/iptunnel.c b/networking/libiproute/iptunnel.c
index 90d0e11..a293387 100644
--- a/networking/libiproute/iptunnel.c
+++ b/networking/libiproute/iptunnel.c
@@ -128,16 +128,13 @@
 /* Dies on error */
 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
-	};
+	static const char keywords[] =
+		"mode\0""ipip\0""ip/ip\0""gre\0""gre/ip\0""sit\0""ipv6/ip\0"
+		"key\0""ikey\0""okey\0""seq\0""iseq\0""oseq\0"
+		"csum\0""icsum\0""ocsum\0""nopmtudisc\0""pmtudisc\0"
+		"remote\0""any\0""local\0""dev\0"
+		"ttl\0""inherit\0""tos\0""dsfield\0"
+		"name\0";
 	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,
@@ -146,22 +143,25 @@
 		ARG_ttl, ARG_inherit, ARG_tos, ARG_dsfield,
 		ARG_name
 	};
+	int count = 0;
+	char medium[IFNAMSIZ];
 	int key;
+
 	memset(p, 0, sizeof(*p));
 	memset(&medium, 0, sizeof(medium));
 
 	p->iph.version = 4;
 	p->iph.ihl = 5;
 #ifndef IP_DF
-#define IP_DF		0x4000		/* Flag: "Don't Fragment"	*/
+#define IP_DF 0x4000  /* Flag: "Don't Fragment" */
 #endif
 	p->iph.frag_off = htons(IP_DF);
 
 	while (argc > 0) {
-		key = index_in_str_array(keywords, *argv);
+		key = index_in_strings(keywords, *argv);
 		if (key == ARG_mode) {
 			NEXT_ARG();
-			key = index_in_str_array(keywords, *argv);
+			key = index_in_strings(keywords, *argv);
 			if (key == ARG_ipip ||
 			    key == ARG_ip_ip) {
 				if (p->iph.protocol && p->iph.protocol != IPPROTO_IPIP) {
@@ -240,12 +240,12 @@
 			p->iph.frag_off = htons(IP_DF);
 		} else if (key == ARG_remote) {
 			NEXT_ARG();
-			key = index_in_str_array(keywords, *argv);
+			key = index_in_strings(keywords, *argv);
 			if (key == ARG_any)
 				p->iph.daddr = get_addr32(*argv);
 		} else if (key == ARG_local) {
 			NEXT_ARG();
-			key = index_in_str_array(keywords, *argv);
+			key = index_in_strings(keywords, *argv);
 			if (key == ARG_any)
 				p->iph.saddr = get_addr32(*argv);
 		} else if (key == ARG_dev) {
@@ -254,7 +254,7 @@
 		} else if (key == ARG_ttl) {
 			unsigned uval;
 			NEXT_ARG();
-			key = index_in_str_array(keywords, *argv);
+			key = index_in_strings(keywords, *argv);
 			if (key != ARG_inherit) {
 				if (get_unsigned(&uval, *argv, 0))
 					invarg(*argv, "TTL");
@@ -266,7 +266,7 @@
 			   key == ARG_dsfield) {
 			uint32_t uval;
 			NEXT_ARG();
-			key = index_in_str_array(keywords, *argv);
+			key = index_in_strings(keywords, *argv);
 			if (key != ARG_inherit) {
 				if (rtnl_dsfield_a2n(&uval, *argv))
 					invarg(*argv, "TOS");
@@ -519,14 +519,13 @@
 /* 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
-	};
+	static const char keywords[] =
+		"add\0""change\0""delete\0""show\0""list\0""lst\0";
 	enum { ARG_add = 0, ARG_change, ARG_del, ARG_show, ARG_list, ARG_lst };
 	int key;
 
 	if (argc) {
-		key = index_in_substr_array(keywords, *argv);
+		key = index_in_substrings(keywords, *argv);
 		if (key < 0)
 			bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
 		--argc;
diff --git a/networking/libiproute/rtm_map.c b/networking/libiproute/rtm_map.c
index 593017b..96b2d17 100644
--- a/networking/libiproute/rtm_map.c
+++ b/networking/libiproute/rtm_map.c
@@ -51,16 +51,16 @@
 
 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,
+	static const char keywords[] =
+		"local\0""nat\0""broadcast\0""brd\0""anycast\0"
+		"multicast\0""prohibit\0""unreachable\0""blackhole\0"
+		"xresolve\0""unicast\0""throw\0";
+	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;
+	const smalluint key = index_in_substrings(keywords, arg) + 1;
 	char *end;
 	unsigned long res;