VirtualBox

Ignore:
Timestamp:
Feb 18, 2013 5:26:05 PM (12 years ago)
Author:
vboxsync
Message:

Main/Metrics: Generic implentation of link state and stubs for line speed for all platforms (#6345)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/linux/NetIf-linux.cpp

    r44529 r44742  
    7070    }
    7171    return VERR_INTERNAL_ERROR;
     72}
     73
     74static uint32_t getInterfaceSpeed(const char *pszName)
     75{
     76    /*
     77     * I wish I could do simple ioctl here, but older kernels require root
     78     * privileges for any ethtool commands.
     79     */
     80    char szBuf[256];
     81    uint32_t uSpeed = 0;
     82    /* First, we try to retrieve the speed via sysfs. */
     83    RTStrPrintf(szBuf, sizeof(szBuf), "/sys/class/net/%s/speed", pszName);
     84    FILE *fp = fopen(szBuf, "r");
     85    if (fp)
     86    {
     87        if (fscanf(fp, "%u", &uSpeed) != 1)
     88            uSpeed = 0;
     89        fclose(fp);
     90    }
     91    if (uSpeed == 10)
     92    {
     93        /* Check the cable is plugged in at all */
     94        unsigned uCarrier = 0;
     95        RTStrPrintf(szBuf, sizeof(szBuf), "/sys/class/net/%s/carrier", pszName);
     96        fp = fopen(szBuf, "r");
     97        if (fp)
     98        {
     99            if (fscanf(fp, "%u", &uCarrier) != 1 || uCarrier == 0)
     100                uSpeed = 0;
     101            fclose(fp);
     102        }
     103    }
     104   
     105    if (uSpeed == 0)
     106    {
     107        /* Failed to get speed via sysfs, go to plan B. */
     108        int rc = NetIfAdpCtlOut(pszName, "speed", szBuf, sizeof(szBuf));
     109        if (RT_SUCCESS(rc))
     110            uSpeed = RTStrToUInt32(szBuf);
     111    }
     112    return uSpeed;
    72113}
    73114
     
    153194         * produces errors.
    154195         */
    155         pInfo->uSpeedMbits = 0;
    156196        if (pInfo->enmMediumType == NETIF_T_ETHERNET)
    157         {
    158             /*
    159              * I wish I could do simple ioctl here, but older kernels require root
    160              * privileges for any ethtool commands.
    161              */
    162             char szBuf[256];
    163             /* First, we try to retrieve the speed via sysfs. */
    164             RTStrPrintf(szBuf, sizeof(szBuf), "/sys/class/net/%s/speed", pszName);
    165             fp = fopen(szBuf, "r");
    166             if (fp)
    167             {
    168                 if (fscanf(fp, "%u", &pInfo->uSpeedMbits) != 1)
    169                     pInfo->uSpeedMbits = 0;
    170                 fclose(fp);
    171             }
    172             if (pInfo->uSpeedMbits == 10)
    173             {
    174                 /* Check the cable is plugged in at all */
    175                 unsigned uCarrier = 0;
    176                 RTStrPrintf(szBuf, sizeof(szBuf), "/sys/class/net/%s/carrier", pszName);
    177                 fp = fopen(szBuf, "r");
    178                 if (fp)
    179                 {
    180                     if (fscanf(fp, "%u", &uCarrier) != 1 || uCarrier == 0)
    181                         pInfo->uSpeedMbits = 0;
    182                     fclose(fp);
    183                 }
    184             }
    185 
    186             if (pInfo->uSpeedMbits == 0)
    187             {
    188                 /* Failed to get speed via sysfs, go to plan B. */
    189                 int rc = NetIfAdpCtlOut(pszName, "speed", szBuf, sizeof(szBuf));
    190                 if (RT_SUCCESS(rc))
    191                     pInfo->uSpeedMbits = RTStrToUInt32(szBuf);
    192             }
    193         }
     197            pInfo->uSpeedMbits = getInterfaceSpeed(pszName);
     198        else
     199            pInfo->uSpeedMbits = 0;
    194200    }
    195201    return VINF_SUCCESS;
     
    266272    return rc;
    267273}
     274
     275/**
     276 * Retrieve the physical link speed in megabits per second. If the interface is
     277 * not up or otherwise unavailable the zero speed is returned.
     278 *
     279 * @returns VBox status code.
     280 *
     281 * @param   pcszIfName  Interface name.
     282 * @param   puMbits     Where to store the link speed.
     283 */
     284int NetIfGetLinkSpeed(const char *pcszIfName, uint32_t *puMbits)
     285{
     286    int sock = socket(AF_INET, SOCK_DGRAM, 0);
     287    if (sock < 0)
     288        return VERR_OUT_OF_RESOURCES;
     289    struct ifreq Req;
     290    memset(&Req, 0, sizeof(Req));
     291    strncpy(Req.ifr_name, pcszIfName, sizeof(Req.ifr_name) - 1);
     292    if (ioctl(sock, SIOCGIFHWADDR, &Req) >= 0)
     293    {
     294        if (ioctl(sock, SIOCGIFFLAGS, &Req) >= 0)
     295            if (Req.ifr_flags & IFF_UP)
     296            {
     297                *puMbits = getInterfaceSpeed(pcszIfName);
     298                return VINF_SUCCESS;
     299            }
     300    }
     301    *puMbits = 0;
     302    return VWRN_NOT_FOUND;
     303}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette