int Adapter::remove(const char *pcszName) { VBOXNETADPREQ Req; memset(&Req, '\0', sizeof(Req)); snprintf(Req.szName, sizeof(Req.szName), "%s", pcszName); return doIOCtl(VBOXNETADP_CTL_REMOVE, &Req); }
int Adapter::add(char *pszName /* in/out */) { VBOXNETADPREQ Req; memset(&Req, '\0', sizeof(Req)); snprintf(Req.szName, sizeof(Req.szName), "%s", pszName); int rc = doIOCtl(VBOXNETADP_CTL_ADD, &Req); if (rc == 0) strncpy(pszName, Req.szName, VBOXNETADP_MAX_NAME_LEN); return rc; }
int main(int argc, char *argv[]) { char szAdapterName[VBOXNETADP_MAX_NAME_LEN]; char *pszAdapterName = NULL; const char *pszAddress = NULL; const char *pszNetworkMask = NULL; const char *pszOption = NULL; int rc = EXIT_SUCCESS; bool fRemove = false; VBOXNETADPREQ Req; setPathIfConfig(); switch (argc) { case 5: { /* Add a netmask to existing interface */ if (strcmp("netmask", argv[3])) { fprintf(stderr, "Invalid argument: %s\n\n", argv[3]); showUsage(); return 1; } pszOption = "netmask"; pszNetworkMask = argv[4]; pszAdapterName = argv[1]; pszAddress = argv[2]; break; } case 4: { /* Remove a single address from existing interface */ if (strcmp("remove", argv[3])) { fprintf(stderr, "Invalid argument: %s\n\n", argv[3]); showUsage(); return 1; } fRemove = true; pszAdapterName = argv[1]; pszAddress = argv[2]; break; } case 3: { pszAdapterName = argv[1]; memset(&Req, '\0', sizeof(Req)); #ifdef RT_OS_LINUX if (strcmp("speed", argv[2]) == 0) { /* * This ugly hack is needed for retrieving the link speed on * pre-2.6.33 kernels (see @bugref{6345}). */ if (strlen(pszAdapterName) >= IFNAMSIZ) { showUsage(); return -1; } struct ifreq IfReq; struct ethtool_value EthToolVal; struct ethtool_cmd EthToolReq; int fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { fprintf(stderr, "VBoxNetAdpCtl: Error while retrieving link " "speed for %s: ", pszAdapterName); perror("VBoxNetAdpCtl: failed to open control socket"); return ADPCTLERR_SOCKET_FAILED; } /* Get link status first. */ memset(&EthToolVal, 0, sizeof(EthToolVal)); memset(&IfReq, 0, sizeof(IfReq)); snprintf(IfReq.ifr_name, sizeof(IfReq.ifr_name), "%s", pszAdapterName); EthToolVal.cmd = ETHTOOL_GLINK; IfReq.ifr_data = (caddr_t)&EthToolVal; rc = ioctl(fd, SIOCETHTOOL, &IfReq); if (rc == 0) { if (EthToolVal.data) { memset(&IfReq, 0, sizeof(IfReq)); snprintf(IfReq.ifr_name, sizeof(IfReq.ifr_name), "%s", pszAdapterName); EthToolReq.cmd = ETHTOOL_GSET; IfReq.ifr_data = (caddr_t)&EthToolReq; rc = ioctl(fd, SIOCETHTOOL, &IfReq); if (rc == 0) { printf("%u", EthToolReq.speed); } else { fprintf(stderr, "VBoxNetAdpCtl: Error while retrieving link " "speed for %s: ", pszAdapterName); perror("VBoxNetAdpCtl: ioctl failed"); rc = ADPCTLERR_IOCTL_FAILED; } } else printf("0"); } else { fprintf(stderr, "VBoxNetAdpCtl: Error while retrieving link " "status for %s: ", pszAdapterName); perror("VBoxNetAdpCtl: ioctl failed"); rc = ADPCTLERR_IOCTL_FAILED; } close(fd); return rc; } #endif rc = checkAdapterName(pszAdapterName, szAdapterName); if (rc) return rc; snprintf(Req.szName, sizeof(Req.szName), "%s", szAdapterName); pszAddress = argv[2]; if (strcmp("remove", pszAddress) == 0) { /* Remove an existing interface */ #ifdef RT_OS_SOLARIS return 1; #else return doIOCtl(VBOXNETADP_CTL_REMOVE, &Req); #endif } else if (strcmp("add", pszAddress) == 0) { /* Create an interface with given name */ #ifdef RT_OS_SOLARIS return 1; #else rc = doIOCtl(VBOXNETADP_CTL_ADD, &Req); if (rc == 0) puts(Req.szName); #endif return rc; } break; } case 2: { /* Create a new interface */ if (strcmp("add", argv[1]) == 0) { #ifdef RT_OS_SOLARIS return 1; #else memset(&Req, '\0', sizeof(Req)); rc = doIOCtl(VBOXNETADP_CTL_ADD, &Req); if (rc == 0) puts(Req.szName); #endif return rc; } /* Fall through */ } default: fprintf(stderr, "Invalid number of arguments.\n\n"); /* Fall through */ case 1: showUsage(); return 1; } rc = checkAdapterName(pszAdapterName, szAdapterName); if (rc) return rc; pszAdapterName = szAdapterName; if (fRemove) { if (strchr(pszAddress, ':')) rc = executeIfconfig(pszAdapterName, "inet6", VBOXADPCTL_DEL_CMD, pszAddress); else { #if defined(RT_OS_LINUX) rc = executeIfconfig(pszAdapterName, "0.0.0.0"); #else rc = executeIfconfig(pszAdapterName, VBOXADPCTL_DEL_CMD, pszAddress); #endif #ifdef RT_OS_SOLARIS /* On Solaris we can unplumb the ipv4 interface */ executeIfconfig(pszAdapterName, "inet", "unplumb"); #endif } } else { /* We are setting/replacing address. */ if (strchr(pszAddress, ':')) { #ifdef RT_OS_SOLARIS /* On Solaris we need to plumb the interface first if it's not already plumbed. */ if (executeIfconfig(pszAdapterName, "inet6") != 0) executeIfconfig(pszAdapterName, "inet6", "plumb", "up"); #endif /* * Before we set IPv6 address we'd like to remove * all previously assigned addresses except the * self-assigned one. */ if (!removeAddresses(pszAdapterName)) rc = EXIT_FAILURE; else rc = executeIfconfig(pszAdapterName, "inet6", VBOXADPCTL_ADD_CMD, pszAddress, pszOption, pszNetworkMask); } else { #ifdef RT_OS_SOLARIS /* On Solaris we need to plumb the interface first if it's not already plumbed. */ if (executeIfconfig(pszAdapterName, "inet") != 0) executeIfconfig(pszAdapterName, "plumb", "up"); #endif rc = executeIfconfig(pszAdapterName, pszAddress, pszOption, pszNetworkMask); } } return rc; }
int main(int argc, char *argv[]) { char szAdapterName[VBOXNETADP_MAX_NAME_LEN]; char *pszAdapterName = NULL; const char *pszAddress = NULL; const char *pszNetworkMask = NULL; const char *pszOption = NULL; int rc = EXIT_SUCCESS; bool fRemove = false; VBOXNETADPREQ Req; switch (argc) { case 5: { /* Add a netmask to existing interface */ if (strcmp("netmask", argv[3])) { fprintf(stderr, "Invalid argument: %s\n\n", argv[3]); showUsage(); return 1; } pszOption = "netmask"; pszNetworkMask = argv[4]; pszAdapterName = argv[1]; pszAddress = argv[2]; break; } case 4: { /* Remove a single address from existing interface */ if (strcmp("remove", argv[3])) { fprintf(stderr, "Invalid argument: %s\n\n", argv[3]); showUsage(); return 1; } fRemove = true; pszAdapterName = argv[1]; pszAddress = argv[2]; break; } case 3: { pszAdapterName = argv[1]; memset(&Req, '\0', sizeof(Req)); rc = checkAdapterName(pszAdapterName, szAdapterName); if (rc) return rc; snprintf(Req.szName, sizeof(Req.szName), "%s", szAdapterName); pszAddress = argv[2]; if (strcmp("remove", pszAddress) == 0) { /* Remove an existing interface */ #ifdef RT_OS_SOLARIS return 1; #else return doIOCtl(VBOXNETADP_CTL_REMOVE, &Req); #endif } else if (strcmp("add", pszAddress) == 0) { /* Create an interface with given name */ #ifdef RT_OS_SOLARIS return 1; #else rc = doIOCtl(VBOXNETADP_CTL_ADD, &Req); if (rc == 0) puts(Req.szName); #endif return rc; } break; } case 2: { /* Create a new interface */ if (strcmp("add", argv[1]) == 0) { #ifdef RT_OS_SOLARIS return 1; #else memset(&Req, '\0', sizeof(Req)); rc = doIOCtl(VBOXNETADP_CTL_ADD, &Req); if (rc == 0) puts(Req.szName); #endif return rc; } /* Fall through */ } default: fprintf(stderr, "Invalid number of arguments.\n\n"); /* Fall through */ case 1: showUsage(); return 1; } rc = checkAdapterName(pszAdapterName, szAdapterName); if (rc) return rc; pszAdapterName = szAdapterName; if (fRemove) { if (strchr(pszAddress, ':')) rc = executeIfconfig(pszAdapterName, "inet6", VBOXADPCTL_DEL_CMD, pszAddress); else { #if defined(RT_OS_LINUX) rc = executeIfconfig(pszAdapterName, "0.0.0.0"); #else rc = executeIfconfig(pszAdapterName, VBOXADPCTL_DEL_CMD, pszAddress); #endif #ifdef RT_OS_SOLARIS /* On Solaris we can unplumb the ipv4 interface */ executeIfconfig(pszAdapterName, "inet", "unplumb"); #endif } } else { /* We are setting/replacing address. */ if (strchr(pszAddress, ':')) { #ifdef RT_OS_SOLARIS /* On Solaris we need to plumb the interface first if it's not already plumbed. */ if (executeIfconfig(pszAdapterName, "inet6") != 0) executeIfconfig(pszAdapterName, "inet6", "plumb", "up"); #endif /* * Before we set IPv6 address we'd like to remove * all previously assigned addresses except the * self-assigned one. */ if (!removeAddresses(pszAdapterName)) rc = EXIT_FAILURE; else rc = executeIfconfig(pszAdapterName, "inet6", VBOXADPCTL_ADD_CMD, pszAddress, pszOption, pszNetworkMask); } else { #ifdef RT_OS_SOLARIS /* On Solaris we need to plumb the interface first if it's not already plumbed. */ if (executeIfconfig(pszAdapterName, "inet") != 0) executeIfconfig(pszAdapterName, "plumb", "up"); #endif rc = executeIfconfig(pszAdapterName, pszAddress, pszOption, pszNetworkMask); } } return rc; }