Changeset 68056 in vbox
- Timestamp:
- Jul 20, 2017 9:47:06 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/adpctl/VBoxNetAdpCtl.cpp
r67757 r68056 33 33 #include <fcntl.h> 34 34 #ifdef RT_OS_LINUX 35 # include <arpa/inet.h> 35 36 # include <net/if.h> 36 37 # include <linux/types.h> … … 254 255 255 256 257 #ifdef RT_OS_LINUX 258 /* 259 * Helper class to incapsulate IPv4 address conversion. 260 */ 261 class AddressIPv4 262 { 263 public: 264 AddressIPv4(const char *pcszAddress, const char *pcszNetmask = 0) 265 { 266 if (pcszNetmask) 267 m_Prefix = maskToPrefix(pcszNetmask); 268 else 269 { 270 /* 271 * Since guessing network mask is probably futile we simply use 24, 272 * as it matches our defaults. When non-default values are used 273 * providing a proper netmask is up to the user. 274 */ 275 m_Prefix = 24; 276 } 277 inet_pton(AF_INET, pcszAddress, &(m_Address.sin_addr)); 278 snprintf(m_szAddressAndMask, sizeof(m_szAddressAndMask), "%s/%d", pcszAddress, m_Prefix); 279 m_Broadcast.sin_addr.s_addr = computeBroadcast(m_Address.sin_addr.s_addr, m_Prefix); 280 inet_ntop(AF_INET, &(m_Broadcast.sin_addr), m_szBroadcast, sizeof(m_szBroadcast)); 281 } 282 const char *getBroadcast() const { return m_szBroadcast; }; 283 const char *getAddressAndMask() const { return m_szAddressAndMask; }; 284 private: 285 unsigned int maskToPrefix(const char *pcszNetmask); 286 unsigned long computeBroadcast(unsigned long ulAddress, unsigned int uPrefix); 287 288 unsigned int m_Prefix; 289 struct sockaddr_in m_Address; 290 struct sockaddr_in m_Broadcast; 291 char m_szAddressAndMask[INET_ADDRSTRLEN + 3]; /* e.g. 192.168.56.101/24 */ 292 char m_szBroadcast[INET_ADDRSTRLEN]; 293 }; 294 295 unsigned int AddressIPv4::maskToPrefix(const char *pcszNetmask) 296 { 297 unsigned cBits = 0; 298 unsigned m[4]; 299 300 if (sscanf(pcszNetmask, "%u.%u.%u.%u", &m[0], &m[1], &m[2], &m[3]) == 4) 301 { 302 for (int i = 0; i < 4 && m[i]; ++i) 303 { 304 int mask = m[i]; 305 while (mask & 0x80) 306 { 307 cBits++; 308 mask <<= 1; 309 } 310 } 311 } 312 return cBits; 313 } 314 315 unsigned long AddressIPv4::computeBroadcast(unsigned long ulAddress, unsigned int uPrefix) 316 { 317 /* Note: the address is big-endian. */ 318 unsigned long ulNetworkMask = (1l << uPrefix) - 1; 319 return (ulAddress & ulNetworkMask) | ~ulNetworkMask; 320 } 321 322 256 323 /* 257 324 * Linux-specific implementation of 'ip' command, as other platforms do not support it. … … 260 327 { 261 328 public: 262 CmdIpLinux() { pszBuffer = 0; m_pszPath = "/sbin/ip"; }; 263 virtual ~CmdIpLinux() { delete pszBuffer; }; 329 CmdIpLinux() { m_pszPath = "/sbin/ip"; }; 264 330 /** 265 331 * IPv4 and IPv6 syntax is the same, so we override `remove` instead of implementing … … 273 339 virtual int addV4(const char *pcszAdapter, const char *pcszAddress, const char *pcszNetmask = 0) 274 340 { 275 return execute(CmdList("addr") << "add" << combine(pcszAddress, pcszNetmask) << 276 "dev" << pcszAdapter); 341 AddressIPv4 addr(pcszAddress, pcszNetmask); 342 bringUp(pcszAdapter); 343 return execute(CmdList("addr") << "add" << addr.getAddressAndMask() << 344 "broadcast" << addr.getBroadcast() << "dev" << pcszAdapter); 277 345 }; 278 346 virtual int addV6(const char *pcszAdapter, const char *pcszAddress, const char *pcszNetmask = 0) 279 347 { 348 bringUp(pcszAdapter); 280 349 return execute(CmdList("addr") << "add" << pcszAddress << "dev" << pcszAdapter); 281 350 NOREF(pcszNetmask); … … 296 365 { return CmdList("addr") << "show" << "dev" << pcszAdapter; }; 297 366 private: 298 /** Converts address and network mask into a single string in CIDR notation (like 192.168.1.1/24) */ 299 const char *combine(const char *pcszAddress, const char *pcszNetmask); 300 301 char *pszBuffer; 302 }; 303 304 const char * CmdIpLinux::combine(const char *pcszAddress, const char *pcszNetmask) 305 { 306 delete pszBuffer; 307 if (pcszNetmask) 308 { 309 unsigned cBits = 0; 310 unsigned m[4]; 311 if (sscanf(pcszNetmask, "%u.%u.%u.%u", &m[0], &m[1], &m[2], &m[3]) == 4) 312 { 313 for (int i = 0; i < 4 && m[i]; ++i) 314 { 315 int mask = m[i]; 316 while (mask & 0x80) 317 { 318 cBits++; 319 mask <<= 1; 320 } 321 } 322 const size_t cbBuf = strlen(pcszAddress) + 4; 323 pszBuffer = new char[cbBuf]; // '/xx\0' 324 snprintf(pszBuffer, cbBuf, "%s/%u", pcszAddress, cBits); 325 return pszBuffer; 326 } 327 } 328 return pcszAddress; 329 } 330 367 /** Brings up the adapter */ 368 void bringUp(const char *pcszAdapter) 369 { execute(CmdList("link") << "set" << "dev" << pcszAdapter << "up"); }; 370 }; 371 #endif /* RT_OS_LINUX */ 331 372 332 373
Note:
See TracChangeset
for help on using the changeset viewer.

