-
- G.cached_detect_link_func = NULL;
-}
-
-static smallint detect_link_mii(void)
-{
- struct ifreq ifreq;
-
- set_ifreq_to_ifname(&ifreq);
-
- if (network_ioctl(SIOCGMIIPHY, &ifreq) < 0) {
- bb_perror_msg("SIOCGMIIPHY failed");
- return IFSTATUS_ERR;
- }
-
- ((unsigned short*)&ifreq.ifr_data)[1] = 1;
-
- if (network_ioctl(SIOCGMIIREG, &ifreq) < 0) {
- bb_perror_msg("SIOCGMIIREG failed");
- return IFSTATUS_ERR;
- }
-
- return (((unsigned short*)&ifreq.ifr_data)[3] & 0x0004) ?
- IFSTATUS_UP : IFSTATUS_DOWN;
-}
-
-static smallint detect_link_priv(void)
-{
- struct ifreq ifreq;
-
- set_ifreq_to_ifname(&ifreq);
-
- if (network_ioctl(SIOCDEVPRIVATE, &ifreq) < 0) {
- bb_perror_msg("SIOCDEVPRIVATE failed");
- return IFSTATUS_ERR;
- }
-
- ((unsigned short*) &ifreq.ifr_data)[1] = 1;
-
- if (network_ioctl(SIOCDEVPRIVATE+1, &ifreq) < 0) {
- bb_perror_msg("SIOCDEVPRIVATE+1 failed");
- return IFSTATUS_ERR;
- }
-
- return (((unsigned short*)&ifreq.ifr_data)[3] & 0x0004) ?
- IFSTATUS_UP : IFSTATUS_DOWN;
-}
-
-static smallint detect_link_ethtool(void)
-{
- struct ifreq ifreq;
- struct ethtool_value edata;
-
- set_ifreq_to_ifname(&ifreq);
-
- edata.cmd = ETHTOOL_GLINK;
- ifreq.ifr_data = &edata;
-
- if (network_ioctl(SIOCETHTOOL, &ifreq) < 0) {
- bb_perror_msg("ETHTOOL_GLINK failed");
- return IFSTATUS_ERR;
- }
-
- return edata.data ? IFSTATUS_UP : IFSTATUS_DOWN;
-}
-
-static smallint detect_link_iff(void)
-{
- struct ifreq ifreq;
-
- set_ifreq_to_ifname(&ifreq);
-
- if (network_ioctl(SIOCGIFFLAGS, &ifreq) < 0) {
- bb_perror_msg("SIOCGIFFLAGS failed");
- return IFSTATUS_ERR;
- }
-
- return (ifreq.ifr_flags & IFF_RUNNING) ? IFSTATUS_UP : IFSTATUS_DOWN;
-}
-
-static smallint detect_link_wlan(void)
-{
- struct iwreq iwrequest;
- uint8_t mac[ETH_ALEN];
-
- memset(&iwrequest, 0, sizeof(struct iwreq));
- strncpy(iwrequest.ifr_ifrn.ifrn_name, G.iface, IFNAMSIZ);
-
- if (network_ioctl(SIOCGIWAP, &iwrequest) < 0) {
- bb_perror_msg("SIOCGIWAP failed");
- return IFSTATUS_ERR;
- }
-
- 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) {
- if (mac[i] != mac[0])
- return IFSTATUS_UP;
- }
- return IFSTATUS_DOWN;
- }
-
- return IFSTATUS_UP;
-}
-
-static smallint detect_link_auto(void)
-{
- const char *method;
- smallint iface_status;
- smallint sv_logmode;
-
- if (G.cached_detect_link_func) {
- iface_status = G.cached_detect_link_func();
- if (iface_status != IFSTATUS_ERR)
- return iface_status;
- }
-
- 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:
- 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;
- }
-
- logmode = sv_logmode;
- return iface_status; /* IFSTATUS_ERR */