#include "rt_names.h"
#include "utils.h"
-#include "ip_common.h"
#include "busybox.h"
inet_prefix msrc;
} filter;
-int print_route(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+static int print_route(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
FILE *fp = (FILE*)arg;
struct rtmsg *r = NLMSG_DATA(n);
return 0;
}
-int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
+static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
{
struct rtnl_handle rth;
struct {
return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr));
}
+static void iproute_reset_filter(void)
+{
+ memset(&filter, 0, sizeof(filter));
+ filter.mdst.bitlen = -1;
+ filter.msrc.bitlen = -1;
+}
+
static int iproute_list(int argc, char **argv)
{
int do_ipv6 = preferred_family;
}
if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) {
- error_msg_and_die"Dump terminated");
+ error_msg_and_die("Dump terminated");
}
exit(0);
}
-int iproute_get(int argc, char **argv)
+static int iproute_get(int argc, char **argv)
{
struct rtnl_handle rth;
struct {
char *odev = NULL;
int connected = 0;
int from_ok = 0;
+ const char *options[] = { "from", "iif", "oif", "dev", "notify", "connected", "to", 0 };
memset(&req, 0, sizeof(req));
req.r.rtm_tos = 0;
while (argc > 0) {
- if (matches(*argv, "from") == 0) {
- inet_prefix addr;
- NEXT_ARG();
- from_ok = 1;
- get_prefix(&addr, *argv, req.r.rtm_family);
- if (req.r.rtm_family == AF_UNSPEC)
- req.r.rtm_family = addr.family;
- if (addr.bytelen)
- addattr_l(&req.n, sizeof(req), RTA_SRC, &addr.data, addr.bytelen);
- req.r.rtm_src_len = addr.bitlen;
- } else if (matches(*argv, "iif") == 0) {
- NEXT_ARG();
- idev = *argv;
- } else if (matches(*argv, "oif") == 0 ||
- strcmp(*argv, "dev") == 0) {
- NEXT_ARG();
- odev = *argv;
- } else if (matches(*argv, "notify") == 0) {
- req.r.rtm_flags |= RTM_F_NOTIFY;
- } else if (matches(*argv, "connected") == 0) {
- connected = 1;
- } else {
- inet_prefix addr;
- if (strcmp(*argv, "to") == 0) {
+ switch (compare_string_array(options, *argv)) {
+ case 0: /* from */
+ {
+ inet_prefix addr;
NEXT_ARG();
+ from_ok = 1;
+ get_prefix(&addr, *argv, req.r.rtm_family);
+ if (req.r.rtm_family == AF_UNSPEC) {
+ req.r.rtm_family = addr.family;
+ }
+ if (addr.bytelen) {
+ addattr_l(&req.n, sizeof(req), RTA_SRC, &addr.data, addr.bytelen);
+ }
+ req.r.rtm_src_len = addr.bitlen;
+ break;
}
- get_prefix(&addr, *argv, req.r.rtm_family);
- if (req.r.rtm_family == AF_UNSPEC)
- req.r.rtm_family = addr.family;
- if (addr.bytelen)
- addattr_l(&req.n, sizeof(req), RTA_DST, &addr.data, addr.bytelen);
- req.r.rtm_dst_len = addr.bitlen;
+ case 1: /* iif */
+ NEXT_ARG();
+ idev = *argv;
+ break;
+ case 2: /* oif */
+ case 3: /* dev */
+ NEXT_ARG();
+ odev = *argv;
+ break;
+ case 4: /* notify */
+ req.r.rtm_flags |= RTM_F_NOTIFY;
+ break;
+ case 5: /* connected */
+ connected = 1;
+ break;
+ case 6: /* to */
+ NEXT_ARG();
+ default:
+ {
+ inet_prefix addr;
+ get_prefix(&addr, *argv, req.r.rtm_family);
+ if (req.r.rtm_family == AF_UNSPEC) {
+ req.r.rtm_family = addr.family;
+ }
+ if (addr.bytelen) {
+ addattr_l(&req.n, sizeof(req), RTA_DST, &addr.data, addr.bytelen);
+ }
+ req.r.rtm_dst_len = addr.bitlen;
+ }
+ argc--; argv++;
}
- argc--; argv++;
}
if (req.r.rtm_dst_len == 0) {
exit(0);
}
-void iproute_reset_filter()
-{
- memset(&filter, 0, sizeof(filter));
- filter.mdst.bitlen = -1;
- filter.msrc.bitlen = -1;
-}
-
int do_iproute(int argc, char **argv)
{
- if (argc < 1) {
- return iproute_list(0, NULL);
- }
-
- if (matches(*argv, "add") == 0) {
- return iproute_modify(RTM_NEWROUTE, NLM_F_CREATE|NLM_F_EXCL,
- argc-1, argv+1);
- }
- if (matches(*argv, "change") == 0 || strcmp(*argv, "chg") == 0) {
- return iproute_modify(RTM_NEWROUTE, NLM_F_REPLACE,
- argc-1, argv+1);
- }
- if (matches(*argv, "replace") == 0) {
- return iproute_modify(RTM_NEWROUTE, NLM_F_CREATE|NLM_F_REPLACE,
- argc-1, argv+1);
- }
- if (matches(*argv, "prepend") == 0) {
- return iproute_modify(RTM_NEWROUTE, NLM_F_CREATE,
- argc-1, argv+1);
- }
- if (matches(*argv, "append") == 0) {
- return iproute_modify(RTM_NEWROUTE, NLM_F_CREATE|NLM_F_APPEND,
- argc-1, argv+1);
- }
- if (matches(*argv, "test") == 0) {
- return iproute_modify(RTM_NEWROUTE, NLM_F_EXCL,
- argc-1, argv+1);
- }
- if (matches(*argv, "delete") == 0) {
- return iproute_modify(RTM_DELROUTE, 0,
- argc-1, argv+1);
- }
- if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
- || matches(*argv, "lst") == 0) {
- return iproute_list(argc-1, argv+1);
- }
- if (matches(*argv, "get") == 0) {
- return iproute_get(argc-1, argv+1);
- }
- error_msg_and_die("Command \"%s\" is unknown, try \"ip route help\".", *argv);
+ const char *ip_route_commands[] = { "add", "append", "change", "chg",
+ "delete", "get", "list", "show", "prepend", "replace", "test", 0 };
+ unsigned short command_num = 6;
+ unsigned int flags = 0;
+ int cmd = RTM_NEWROUTE;
+
+ if (*argv) {
+ command_num = compare_string_array(ip_route_commands, *argv);
+ }
+ switch(command_num) {
+ case 0: /* add*/
+ flags = NLM_F_CREATE|NLM_F_EXCL;
+ break;
+ case 1: /* append */
+ flags = NLM_F_CREATE|NLM_F_APPEND;
+ break;
+ case 2: /* change */
+ case 3: /* chg */
+ flags = NLM_F_REPLACE;
+ break;
+ case 4: /* delete */
+ cmd = RTM_DELROUTE;
+ break;
+ case 5: /* get */
+ return iproute_get(argc-1, argv+1);
+ case 6: /* list */
+ case 7: /* show */
+ return iproute_list(argc-1, argv+1);
+ case 8: /* prepend */
+ flags = NLM_F_CREATE;
+ case 9: /* replace */
+ flags = NLM_F_CREATE|NLM_F_REPLACE;
+ case 10: /* test */
+ flags = NLM_F_EXCL;
+ default:
+ error_msg_and_die("Unknown command %s", *argv);
+ }
+
+ return iproute_modify(cmd, flags, argc-1, argv+1);
}