Yet another major rework of the BusyBox config system, using the considerably
[oweals/busybox.git] / networking / libiproute / iproute.c
index b5833d7cc8ceb3a3b4f396a03b4a1b519b9632c4..f29a5158a823a9dd0652a97abcc891e0e13bd712 100644 (file)
@@ -30,7 +30,6 @@
 
 #include "rt_names.h"
 #include "utils.h"
-#include "ip_common.h"
 
 #include "busybox.h"
 
@@ -60,7 +59,7 @@ static struct
        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);
@@ -238,7 +237,7 @@ int print_route(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
        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 {
@@ -402,6 +401,13 @@ static int rtnl_rtcache_request(struct rtnl_handle *rth, int family)
        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;
@@ -516,7 +522,7 @@ static int iproute_list(int argc, char **argv)
 }
 
 
-int iproute_get(int argc, char **argv)
+static int iproute_get(int argc, char **argv)
 {
        struct rtnl_handle rth;
        struct {
@@ -528,6 +534,7 @@ int iproute_get(int argc, char **argv)
        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));
 
@@ -546,40 +553,53 @@ int iproute_get(int argc, char **argv)
        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) {
@@ -671,54 +691,46 @@ int iproute_get(int argc, char **argv)
        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);
 }