X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=networking%2Fifplugd.c;h=41b04c4ed83cf290d0959d840e1eb59a587d5602;hb=823b636cd14d337ebb8766c5c181737fb3860b42;hp=3567dea03a5c89a7317a0f3abe34a79c32a85c3a;hpb=651a2697f725f10c1ebdb8947925b5a9c6cf4fe2;p=oweals%2Fbusybox.git diff --git a/networking/ifplugd.c b/networking/ifplugd.c index 3567dea03..41b04c4ed 100644 --- a/networking/ifplugd.c +++ b/networking/ifplugd.c @@ -1,6 +1,6 @@ /* vi: set sw=4 ts=4: */ /* - * ifplugd for busybox + * ifplugd for busybox, based on ifplugd 0.28 (written by Lennart Poettering). * * Copyright (C) 2009 Maksym Kryzhanovskyy * @@ -22,7 +22,11 @@ #include /* -TODO: describe compat status here. +From initial port to busybox, removed most of the redundancy by +converting implementation of a polymorphic interface to the strict +functional style. The main role is run a script when link state +changed, other activities like audio signal or detailed reports +are on the script itself. One questionable point of the design is netlink usage: @@ -214,7 +218,7 @@ static int network_ioctl(int request, void* data, const char *errmsg) { int r = ioctl(ioctl_fd, request, data); if (r < 0 && errmsg) - bb_perror_msg(errmsg); + bb_perror_msg("%s failed", errmsg); return r; } @@ -239,7 +243,7 @@ static void up_iface(void) return; set_ifreq_to_ifname(&ifrequest); - if (network_ioctl(SIOCGIFFLAGS, &ifrequest, "can't get interface flags") < 0) { + if (network_ioctl(SIOCGIFFLAGS, &ifrequest, "getting interface flags") < 0) { G.iface_exists = 0; return; } @@ -248,7 +252,7 @@ static void up_iface(void) ifrequest.ifr_flags |= IFF_UP; /* Let user know we mess up with interface */ bb_error_msg("upping interface"); - if (network_ioctl(SIOCSIFFLAGS, &ifrequest, "can't set interface flags") < 0) + if (network_ioctl(SIOCSIFFLAGS, &ifrequest, "setting interface flags") < 0) xfunc_die(); } @@ -307,13 +311,13 @@ static smallint detect_link_mii(void) set_ifreq_to_ifname(&ifreq); - if (network_ioctl(SIOCGMIIPHY, &ifreq, "SIOCGMIIPHY failed") < 0) { + if (network_ioctl(SIOCGMIIPHY, &ifreq, "SIOCGMIIPHY") < 0) { return IFSTATUS_ERR; } mii->reg_num = 1; - if (network_ioctl(SIOCGMIIREG, &ifreq, "SIOCGMIIREG failed") < 0) { + if (network_ioctl(SIOCGMIIREG, &ifreq, "SIOCGMIIREG") < 0) { return IFSTATUS_ERR; } @@ -327,13 +331,13 @@ static smallint detect_link_priv(void) set_ifreq_to_ifname(&ifreq); - if (network_ioctl(SIOCDEVPRIVATE, &ifreq, "SIOCDEVPRIVATE failed") < 0) { + if (network_ioctl(SIOCDEVPRIVATE, &ifreq, "SIOCDEVPRIVATE") < 0) { return IFSTATUS_ERR; } mii->reg_num = 1; - if (network_ioctl(SIOCDEVPRIVATE+1, &ifreq, "SIOCDEVPRIVATE+1 failed") < 0) { + if (network_ioctl(SIOCDEVPRIVATE+1, &ifreq, "SIOCDEVPRIVATE+1") < 0) { return IFSTATUS_ERR; } @@ -350,7 +354,7 @@ static smallint detect_link_ethtool(void) edata.cmd = ETHTOOL_GLINK; ifreq.ifr_data = (void*) &edata; - if (network_ioctl(SIOCETHTOOL, &ifreq, "ETHTOOL_GLINK failed") < 0) { + if (network_ioctl(SIOCETHTOOL, &ifreq, "ETHTOOL_GLINK") < 0) { return IFSTATUS_ERR; } @@ -363,7 +367,7 @@ static smallint detect_link_iff(void) set_ifreq_to_ifname(&ifreq); - if (network_ioctl(SIOCGIFFLAGS, &ifreq, "SIOCGIFFLAGS failed") < 0) { + if (network_ioctl(SIOCGIFFLAGS, &ifreq, "SIOCGIFFLAGS") < 0) { return IFSTATUS_ERR; } @@ -381,20 +385,21 @@ static smallint detect_link_iff(void) static smallint detect_link_wlan(void) { + int i; struct iwreq iwrequest; uint8_t mac[ETH_ALEN]; - memset(&iwrequest, 0, sizeof(struct iwreq)); + memset(&iwrequest, 0, sizeof(iwrequest)); strncpy_IFNAMSIZ(iwrequest.ifr_ifrn.ifrn_name, G.iface); - if (network_ioctl(SIOCGIWAP, &iwrequest, "SIOCGIWAP failed") < 0) { + if (network_ioctl(SIOCGIWAP, &iwrequest, "SIOCGIWAP") < 0) { return IFSTATUS_ERR; } - memcpy(mac, &(iwrequest.u.ap_addr.sa_data), ETH_ALEN); + memcpy(mac, &iwrequest.u.ap_addr.sa_data, ETH_ALEN); if (mac[0] == 0xFF || mac[0] == 0x44 || mac[0] == 0x00) { - for (int i = 1; i < ETH_ALEN; ++i) { + for (i = 1; i < ETH_ALEN; ++i) { if (mac[i] != mac[0]) return IFSTATUS_UP; } @@ -406,7 +411,17 @@ static smallint detect_link_wlan(void) static smallint detect_link_auto(void) { - const char *method; + static const struct { + const char *name; + smallint (*func)(void); + } method[] = { + { "SIOCETHTOOL" , &detect_link_ethtool }, + { "SIOCGMIIPHY" , &detect_link_mii }, + { "SIOCDEVPRIVATE" , &detect_link_priv }, + { "wireless extension", &detect_link_wlan }, + { "IFF_RUNNING" , &detect_link_iff }, + }; + int i; smallint iface_status; smallint sv_logmode; @@ -417,48 +432,17 @@ static smallint detect_link_auto(void) } sv_logmode = logmode; - logmode = LOGMODE_NONE; - - iface_status = detect_link_ethtool(); - if (iface_status != IFSTATUS_ERR) { - G.cached_detect_link_func = detect_link_ethtool; - method = "SIOCETHTOOL"; - found_method: + for (i = 0; i < ARRAY_SIZE(method); i++) { + logmode = LOGMODE_NONE; + iface_status = method[i].func(); logmode = sv_logmode; - bb_error_msg("using %s detection mode", method); - return iface_status; - } - - iface_status = detect_link_mii(); - if (iface_status != IFSTATUS_ERR) { - G.cached_detect_link_func = detect_link_mii; - method = "SIOCGMIIPHY"; - goto found_method; - } - - iface_status = detect_link_priv(); - if (iface_status != IFSTATUS_ERR) { - G.cached_detect_link_func = detect_link_priv; - method = "SIOCDEVPRIVATE"; - goto found_method; - } - - iface_status = detect_link_wlan(); - if (iface_status != IFSTATUS_ERR) { - G.cached_detect_link_func = detect_link_wlan; - method = "wireless extension"; - goto found_method; - } - - iface_status = detect_link_iff(); - if (iface_status != IFSTATUS_ERR) { - G.cached_detect_link_func = detect_link_iff; - method = "IFF_RUNNING"; - goto found_method; + if (iface_status != IFSTATUS_ERR) { + G.cached_detect_link_func = method[i].func; + bb_error_msg("using %s detection mode", method[i].name); + break; + } } - - logmode = sv_logmode; - return iface_status; /* IFSTATUS_ERR */ + return iface_status; } static smallint detect_link(void) @@ -501,8 +485,10 @@ static smallint detect_link(void) static NOINLINE int check_existence_through_netlink(void) { + int iface_len; char replybuf[1024]; + iface_len = strlen(G.iface); while (1) { struct nlmsghdr *mhdr; ssize_t bytes; @@ -520,38 +506,31 @@ static NOINLINE int check_existence_through_netlink(void) mhdr = (struct nlmsghdr*)replybuf; while (bytes > 0) { - if (!NLMSG_OK(mhdr, bytes) - || bytes < sizeof(struct nlmsghdr) - || bytes < mhdr->nlmsg_len - ) { + if (!NLMSG_OK(mhdr, bytes)) { bb_error_msg("netlink packet too small or truncated"); return -1; } if (mhdr->nlmsg_type == RTM_NEWLINK || mhdr->nlmsg_type == RTM_DELLINK) { struct rtattr *attr; - struct ifinfomsg *imsg; int attr_len; - imsg = NLMSG_DATA(mhdr); - if (mhdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg))) { bb_error_msg("netlink packet too small or truncated"); return -1; } - attr = (struct rtattr*)((char*)imsg + NLMSG_ALIGN(sizeof(struct ifinfomsg))); - attr_len = NLMSG_PAYLOAD(mhdr, sizeof(struct ifinfomsg)); + attr = IFLA_RTA(NLMSG_DATA(mhdr)); + attr_len = IFLA_PAYLOAD(mhdr); while (RTA_OK(attr, attr_len)) { if (attr->rta_type == IFLA_IFNAME) { - char ifname[IFNAMSIZ + 1]; int len = RTA_PAYLOAD(attr); - if (len > IFNAMSIZ) len = IFNAMSIZ; - memcpy(ifname, RTA_DATA(attr), len); - if (strcmp(G.iface, ifname) == 0) { + if (iface_len <= len + && strncmp(G.iface, RTA_DATA(attr), len) == 0 + ) { G.iface_exists = (mhdr->nlmsg_type == RTM_NEWLINK); } }