diff options
Diffstat (limited to 'networking/libiproute/iplink.c')
-rw-r--r-- | networking/libiproute/iplink.c | 166 |
1 files changed, 61 insertions, 105 deletions
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c index cb6ee962b..0943726e1 100644 --- a/networking/libiproute/iplink.c +++ b/networking/libiproute/iplink.c @@ -22,63 +22,54 @@ #include "utils.h" #include "ip_common.h" -/* take from linux/sockios.h */ +/* taken from linux/sockios.h */ #define SIOCSIFNAME 0x8923 /* set interface name */ -static int on_off(const char *msg) +static void on_off(const char *msg) ATTRIBUTE_NORETURN; +static void on_off(const char *msg) { - bb_error_msg("error: argument of \"%s\" must be \"on\" or \"off\"", msg); - return -1; + bb_error_msg_and_die("error: argument of \"%s\" must be \"on\" or \"off\"", msg); } +/* Exits on error */ static int get_ctl_fd(void) { - int s_errno; int fd; fd = socket(PF_INET, SOCK_DGRAM, 0); if (fd >= 0) return fd; - s_errno = errno; fd = socket(PF_PACKET, SOCK_DGRAM, 0); if (fd >= 0) return fd; fd = socket(PF_INET6, SOCK_DGRAM, 0); if (fd >= 0) return fd; - errno = s_errno; - bb_perror_msg("cannot create control socket"); - return -1; + bb_perror_msg_and_die("cannot create control socket"); } -static int do_chflags(char *dev, uint32_t flags, uint32_t mask) +/* Exits on error */ +static void do_chflags(char *dev, uint32_t flags, uint32_t mask) { struct ifreq ifr; int fd; - int err; strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); fd = get_ctl_fd(); - if (fd < 0) - return -1; - err = ioctl(fd, SIOCGIFFLAGS, &ifr); - if (err) { - bb_perror_msg("SIOCGIFFLAGS"); - close(fd); - return -1; + if (ioctl(fd, SIOCGIFFLAGS, &ifr)) { + bb_perror_msg_and_die("SIOCGIFFLAGS"); } - if ((ifr.ifr_flags^flags)&mask) { + if ((ifr.ifr_flags ^ flags) & mask) { ifr.ifr_flags &= ~mask; - ifr.ifr_flags |= mask&flags; - err = ioctl(fd, SIOCSIFFLAGS, &ifr); - if (err) - bb_perror_msg("SIOCSIFFLAGS"); + ifr.ifr_flags |= mask & flags; + if (ioctl(fd, SIOCSIFFLAGS, &ifr)) + bb_perror_msg_and_die("SIOCSIFFLAGS"); } close(fd); - return err; } -static int do_changename(char *dev, char *newdev) +/* Exits on error */ +static void do_changename(char *dev, char *newdev) { struct ifreq ifr; int fd; @@ -87,62 +78,46 @@ static int do_changename(char *dev, char *newdev) strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); strncpy(ifr.ifr_newname, newdev, sizeof(ifr.ifr_newname)); fd = get_ctl_fd(); - if (fd < 0) - return -1; err = ioctl(fd, SIOCSIFNAME, &ifr); if (err) { - bb_perror_msg("SIOCSIFNAME"); - close(fd); - return -1; + bb_perror_msg_and_die("SIOCSIFNAME"); } close(fd); - return err; } -static int set_qlen(char *dev, int qlen) +/* Exits on error */ +static void set_qlen(char *dev, int qlen) { struct ifreq ifr; int s; s = get_ctl_fd(); - if (s < 0) - return -1; - memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); ifr.ifr_qlen = qlen; if (ioctl(s, SIOCSIFTXQLEN, &ifr) < 0) { - bb_perror_msg("SIOCSIFXQLEN"); - close(s); - return -1; + bb_perror_msg_and_die("SIOCSIFXQLEN"); } close(s); - - return 0; } -static int set_mtu(char *dev, int mtu) +/* Exits on error */ +static void set_mtu(char *dev, int mtu) { struct ifreq ifr; int s; s = get_ctl_fd(); - if (s < 0) - return -1; - memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); ifr.ifr_mtu = mtu; if (ioctl(s, SIOCSIFMTU, &ifr) < 0) { - bb_perror_msg("SIOCSIFMTU"); - close(s); - return -1; + bb_perror_msg_and_die("SIOCSIFMTU"); } close(s); - - return 0; } +/* Exits on error */ static int get_address(char *dev, int *htype) { struct ifreq ifr; @@ -152,16 +127,13 @@ static int get_address(char *dev, int *htype) s = socket(PF_PACKET, SOCK_DGRAM, 0); if (s < 0) { - bb_perror_msg("socket(PF_PACKET)"); - return -1; + bb_perror_msg_and_die("socket(PF_PACKET)"); } memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { - bb_perror_msg("SIOCGIFINDEX"); - close(s); - return -1; + bb_perror_msg_and_die("SIOCGIFINDEX"); } memset(&me, 0, sizeof(me)); @@ -169,23 +141,20 @@ static int get_address(char *dev, int *htype) me.sll_ifindex = ifr.ifr_ifindex; me.sll_protocol = htons(ETH_P_LOOP); if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { - bb_perror_msg("bind"); - close(s); - return -1; + bb_perror_msg_and_die("bind"); } alen = sizeof(me); if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) { - bb_perror_msg("getsockname"); - close(s); - return -1; + bb_perror_msg_and_die("getsockname"); } close(s); *htype = me.sll_hatype; return me.sll_halen; } -static int parse_address(char *dev, int hatype, int halen, char *lla, struct ifreq *ifr) +/* Exits on error */ +static void parse_address(char *dev, int hatype, int halen, char *lla, struct ifreq *ifr) { int alen; @@ -194,31 +163,26 @@ static int parse_address(char *dev, int hatype, int halen, char *lla, struct ifr ifr->ifr_hwaddr.sa_family = hatype; alen = ll_addr_a2n((unsigned char *)(ifr->ifr_hwaddr.sa_data), 14, lla); if (alen < 0) - return -1; + exit(1); if (alen != halen) { - bb_error_msg("wrong address (%s) length: expected %d bytes", lla, halen); - return -1; + bb_error_msg_and_die("wrong address (%s) length: expected %d bytes", lla, halen); } - return 0; } -static int set_address(struct ifreq *ifr, int brd) +/* Exits on error */ +static void set_address(struct ifreq *ifr, int brd) { int s; s = get_ctl_fd(); - if (s < 0) - return -1; - if (ioctl(s, brd?SIOCSIFHWBROADCAST:SIOCSIFHWADDR, ifr) < 0) { - bb_perror_msg(brd ? "SIOCSIFHWBROADCAST" : "SIOCSIFHWADDR"); - close(s); - return -1; + if (ioctl(s, brd ? SIOCSIFHWBROADCAST :SIOCSIFHWADDR, ifr) < 0) { + bb_perror_msg_and_die(brd ? "SIOCSIFHWBROADCAST" : "SIOCSIFHWADDR"); } close(s); - return 0; } +/* Return value becomes exitcode. It's okay to not return at all */ static int do_set(int argc, char **argv) { char *dev = NULL; @@ -256,7 +220,7 @@ static int do_set(int argc, char **argv) } else if (strcmp(*argv, "off") == 0) { flags &= ~IFF_MULTICAST; } else - return on_off("multicast"); + on_off("multicast"); } else if (strcmp(*argv, "arp") == 0) { NEXT_ARG(); mask |= IFF_NOARP; @@ -265,7 +229,7 @@ static int do_set(int argc, char **argv) } else if (strcmp(*argv, "off") == 0) { flags |= IFF_NOARP; } else - return on_off("noarp"); + on_off("noarp"); } else if (strcmp(*argv, "addr") == 0) { NEXT_ARG(); newaddr = *argv; @@ -277,53 +241,44 @@ static int do_set(int argc, char **argv) duparg2("dev", *argv); dev = *argv; } - argc--; argv++; + argc--; + argv++; } if (!dev) { - bb_error_msg(bb_msg_requires_arg, "\"dev\""); - exit(-1); + bb_error_msg_and_die(bb_msg_requires_arg, "\"dev\""); } 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; + parse_address(dev, htype, halen, newaddr, &ifr0); } if (newbrd) { - if (parse_address(dev, htype, halen, newbrd, &ifr1) < 0) - return -1; + parse_address(dev, htype, halen, newbrd, &ifr1); } } if (newname && strcmp(dev, newname)) { - if (do_changename(dev, newname) < 0) - return -1; + do_changename(dev, newname); dev = newname; } if (qlen != -1) { - if (set_qlen(dev, qlen) < 0) - return -1; + set_qlen(dev, qlen); } if (mtu != -1) { - if (set_mtu(dev, mtu) < 0) - return -1; + set_mtu(dev, mtu); } if (newaddr || newbrd) { if (newbrd) { - if (set_address(&ifr1, 1) < 0) - return -1; + set_address(&ifr1, 1); } if (newaddr) { - if (set_address(&ifr0, 0) < 0) - return -1; + set_address(&ifr0, 0); } } if (mask) - return do_chflags(dev, flags, mask); + do_chflags(dev, flags, mask); return 0; } @@ -333,18 +288,19 @@ static int ipaddr_list_link(int argc, char **argv) return ipaddr_list_or_flush(argc, argv, 0); } +/* Return value becomes exitcode. It's okay to not return at all */ int do_iplink(int argc, char **argv) { - if (argc > 0) { - if (matches(*argv, "set") == 0) - return do_set(argc-1, argv+1); - if (matches(*argv, "show") == 0 || - matches(*argv, "lst") == 0 || - matches(*argv, "list") == 0) - return ipaddr_list_link(argc-1, argv+1); - } else + if (argc <= 0) return ipaddr_list_link(0, NULL); - bb_error_msg("command \"%s\" is unknown", *argv); - exit(-1); + if (matches(*argv, "set") == 0) + return do_set(argc-1, argv+1); + + if (matches(*argv, "show") == 0 || + matches(*argv, "lst") == 0 || + matches(*argv, "list") == 0) + return ipaddr_list_link(argc-1, argv+1); + + bb_error_msg_and_die("command \"%s\" is unknown", *argv); } |