Changeset 44742 in vbox for trunk/src/VBox/Main/src-server/linux
- Timestamp:
- Feb 18, 2013 5:26:05 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/linux/NetIf-linux.cpp
r44529 r44742 70 70 } 71 71 return VERR_INTERNAL_ERROR; 72 } 73 74 static 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; 72 113 } 73 114 … … 153 194 * produces errors. 154 195 */ 155 pInfo->uSpeedMbits = 0;156 196 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; 194 200 } 195 201 return VINF_SUCCESS; … … 266 272 return rc; 267 273 } 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 */ 284 int 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.