static int do_set(int argc, char **argv) { char *dev = NULL; __u32 mask = 0; __u32 flags = 0; int qlen = -1; int mtu = -1; char *newaddr = NULL; char *newbrd = NULL; struct ifreq ifr0, ifr1; char *newname = NULL; int htype, halen; while (argc > 0) { if (strcmp(*argv, "up") == 0) { mask |= IFF_UP; flags |= IFF_UP; } else if (strcmp(*argv, "down") == 0) { mask |= IFF_UP; flags &= ~IFF_UP; } else if (strcmp(*argv, "name") == 0) { NEXT_ARG(); newname = *argv; } else if (strcmp(*argv, "mtu") == 0) { NEXT_ARG(); if (mtu != -1) duparg("mtu", *argv); if (get_integer(&mtu, *argv, 0)) invarg("Invalid \"mtu\" value\n", *argv); } else if (strcmp(*argv, "multicast") == 0) { NEXT_ARG(); mask |= IFF_MULTICAST; if (strcmp(*argv, "on") == 0) { flags |= IFF_MULTICAST; } else if (strcmp(*argv, "off") == 0) { flags &= ~IFF_MULTICAST; } else return on_off("multicast"); } else if (strcmp(*argv, "arp") == 0) { NEXT_ARG(); mask |= IFF_NOARP; if (strcmp(*argv, "on") == 0) { flags &= ~IFF_NOARP; } else if (strcmp(*argv, "off") == 0) { flags |= IFF_NOARP; } else return on_off("noarp"); } else if (strcmp(*argv, "addr") == 0) { NEXT_ARG(); newaddr = *argv; } else { if (strcmp(*argv, "dev") == 0) { NEXT_ARG(); } if (dev) duparg2("dev", *argv); dev = *argv; } argc--; argv++; } if (!dev) { bb_error_msg("Not enough of information: \"dev\" argument is required."); exit(-1); } if (newaddr || newbrd) { halen = get_address(dev, &htype); if (halen < 0) return -1; if (newaddr) { if (parse_address(dev, htype, halen, newaddr, &ifr0) < 0) return -1; } if (newbrd) { if (parse_address(dev, htype, halen, newbrd, &ifr1) < 0) return -1; } } if (newname && strcmp(dev, newname)) { if (do_changename(dev, newname) < 0) return -1; dev = newname; } if (qlen != -1) { if (set_qlen(dev, qlen) < 0) return -1; } if (mtu != -1) { if (set_mtu(dev, mtu) < 0) return -1; } if (newaddr || newbrd) { if (newbrd) { if (set_address(&ifr1, 1) < 0) return -1; } if (newaddr) { if (set_address(&ifr0, 0) < 0) return -1; } } if (mask) return do_chflags(dev, flags, mask); return 0; }
/* Return value becomes exitcode. It's okay to not return at all */ static int do_set(char **argv) { char *dev = NULL; uint32_t mask = 0; uint32_t flags = 0; int qlen = -1; int mtu = -1; char *newaddr = NULL; char *newbrd = NULL; struct ifreq ifr0, ifr1; char *newname = NULL; int htype, halen; static const char keywords[] ALIGN1 = "up\0""down\0""name\0""mtu\0""multicast\0" "arp\0""address\0""dev\0"; enum { ARG_up = 0, ARG_down, ARG_name, ARG_mtu, ARG_multicast, ARG_arp, ARG_addr, ARG_dev }; static const char str_on_off[] ALIGN1 = "on\0""off\0"; enum { PARM_on = 0, PARM_off }; smalluint key; while (*argv) { /* substring search ensures that e.g. "addr" and "address" * are both accepted */ key = index_in_substrings(keywords, *argv); if (key == ARG_up) { mask |= IFF_UP; flags |= IFF_UP; } if (key == ARG_down) { mask |= IFF_UP; flags &= ~IFF_UP; } if (key == ARG_name) { NEXT_ARG(); newname = *argv; } if (key == ARG_mtu) { NEXT_ARG(); if (mtu != -1) duparg("mtu", *argv); mtu = get_unsigned(*argv, "mtu"); } if (key == ARG_multicast) { int param; NEXT_ARG(); mask |= IFF_MULTICAST; param = index_in_strings(str_on_off, *argv); if (param < 0) die_must_be_on_off("multicast"); if (param == PARM_on) flags |= IFF_MULTICAST; else flags &= ~IFF_MULTICAST; } if (key == ARG_arp) { int param; NEXT_ARG(); mask |= IFF_NOARP; param = index_in_strings(str_on_off, *argv); if (param < 0) die_must_be_on_off("arp"); if (param == PARM_on) flags &= ~IFF_NOARP; else flags |= IFF_NOARP; } if (key == ARG_addr) { NEXT_ARG(); newaddr = *argv; } if (key >= ARG_dev) { if (key == ARG_dev) { NEXT_ARG(); } if (dev) duparg2("dev", *argv); dev = *argv; } argv++; } if (!dev) { bb_error_msg_and_die(bb_msg_requires_arg, "\"dev\""); } if (newaddr || newbrd) { halen = get_address(dev, &htype); if (newaddr) { parse_address(dev, htype, halen, newaddr, &ifr0); } if (newbrd) { parse_address(dev, htype, halen, newbrd, &ifr1); } } if (newname && strcmp(dev, newname)) { do_changename(dev, newname); dev = newname; } if (qlen != -1) { set_qlen(dev, qlen); } if (mtu != -1) { set_mtu(dev, mtu); } if (newaddr || newbrd) { if (newbrd) { set_address(&ifr1, 1); } if (newaddr) { set_address(&ifr0, 0); } } if (mask) do_chflags(dev, flags, mask); return 0; }
static int do_set(int argc, char **argv) { char *dev = NULL; __u32 mask = 0; __u32 flags = 0; int qlen = -1; int mtu = -1; char *newaddr = NULL; char *newbrd = NULL; struct ifreq ifr0, ifr1; char *newname = NULL; int htype, halen; while (argc > 0) { if (strcmp(*argv, "up") == 0) { mask |= IFF_UP; flags |= IFF_UP; } else if (strcmp(*argv, "down") == 0) { mask |= IFF_UP; flags &= ~IFF_UP; } else if (strcmp(*argv, "name") == 0) { NEXT_ARG(); newname = *argv; } else if (matches(*argv, "address") == 0) { NEXT_ARG(); newaddr = *argv; } else if (matches(*argv, "broadcast") == 0 || strcmp(*argv, "brd") == 0) { NEXT_ARG(); newbrd = *argv; } else if (matches(*argv, "txqueuelen") == 0 || strcmp(*argv, "qlen") == 0 || matches(*argv, "txqlen") == 0) { NEXT_ARG(); if (qlen != -1) duparg("txqueuelen", *argv); if (get_integer(&qlen, *argv, 0)) invarg("Invalid \"txqueuelen\" value\n", *argv); } else if (strcmp(*argv, "mtu") == 0) { NEXT_ARG(); if (mtu != -1) duparg("mtu", *argv); if (get_integer(&mtu, *argv, 0)) invarg("Invalid \"mtu\" value\n", *argv); } else if (strcmp(*argv, "multicast") == 0) { NEXT_ARG(); mask |= IFF_MULTICAST; if (strcmp(*argv, "on") == 0) { flags |= IFF_MULTICAST; } else if (strcmp(*argv, "off") == 0) { flags &= ~IFF_MULTICAST; } else return on_off("multicast", *argv); } else if (strcmp(*argv, "allmulticast") == 0) { NEXT_ARG(); mask |= IFF_ALLMULTI; if (strcmp(*argv, "on") == 0) { flags |= IFF_ALLMULTI; } else if (strcmp(*argv, "off") == 0) { flags &= ~IFF_ALLMULTI; } else return on_off("allmulticast", *argv); } else if (strcmp(*argv, "promisc") == 0) { NEXT_ARG(); mask |= IFF_PROMISC; if (strcmp(*argv, "on") == 0) { flags |= IFF_PROMISC; } else if (strcmp(*argv, "off") == 0) { flags &= ~IFF_PROMISC; } else return on_off("promisc", *argv); } else if (strcmp(*argv, "trailers") == 0) { NEXT_ARG(); mask |= IFF_NOTRAILERS; if (strcmp(*argv, "off") == 0) { flags |= IFF_NOTRAILERS; } else if (strcmp(*argv, "on") == 0) { flags &= ~IFF_NOTRAILERS; } else return on_off("trailers", *argv); } else if (strcmp(*argv, "arp") == 0) { NEXT_ARG(); mask |= IFF_NOARP; if (strcmp(*argv, "on") == 0) { flags &= ~IFF_NOARP; } else if (strcmp(*argv, "off") == 0) { flags |= IFF_NOARP; } else return on_off("noarp", *argv); } else if (matches(*argv, "dynamic") == 0) { NEXT_ARG(); mask |= IFF_DYNAMIC; if (strcmp(*argv, "on") == 0) { flags |= IFF_DYNAMIC; } else if (strcmp(*argv, "off") == 0) { flags &= ~IFF_DYNAMIC; } else return on_off("dynamic", *argv); } else { if (strcmp(*argv, "dev") == 0) { NEXT_ARG(); } if (matches(*argv, "help") == 0) usage(); if (dev) duparg2("dev", *argv); dev = *argv; } argc--; argv++; } if (!dev) { fprintf(stderr, "Not enough of information: \"dev\" argument is required.\n"); exit(-1); } if (newaddr || newbrd) { halen = get_address(dev, &htype); if (halen < 0) return -1; if (newaddr) { if (parse_address(dev, htype, halen, newaddr, &ifr0) < 0) return -1; } if (newbrd) { if (parse_address(dev, htype, halen, newbrd, &ifr1) < 0) return -1; } } if (newname && strcmp(dev, newname)) { if (strlen(newname) == 0) invarg("\"\" is not a valid device identifier\n", "name"); if (do_changename(dev, newname) < 0) return -1; dev = newname; } if (qlen != -1) { if (set_qlen(dev, qlen) < 0) return -1; } if (mtu != -1) { if (set_mtu(dev, mtu) < 0) return -1; } if (newaddr || newbrd) { if (newbrd) { if (set_address(&ifr1, 1) < 0) return -1; } if (newaddr) { if (set_address(&ifr0, 0) < 0) return -1; } } if (mask) return do_chflags(dev, flags, mask); return 0; }