Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}