VirtualBox

Changeset 17722 in vbox for trunk/src/apps/adpctl


Ignore:
Timestamp:
Mar 12, 2009 9:04:08 AM (16 years ago)
Author:
vboxsync
Message:

#3569: IPv6 static ip config for unix platforms + 'remove' option in helper.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/apps/adpctl/VBoxNetAdpCtl.cpp

    r17424 r17722  
    2525*   Header Files                                                               *
    2626*******************************************************************************/
     27#include <string>
     28#include <list>
     29#include <assert.h>
    2730#include <stdio.h>
    2831#include <stdlib.h>
     
    3538static void showUsage(void)
    3639{
    37     fprintf(stderr, "Usage: VBoxNetAdpCtl <adapter> <address> [netmask <address>]\n");
     40    fprintf(stderr, "Usage: VBoxNetAdpCtl <adapter> <address> ([netmask <address>] | remove)\n");
    3841}
    3942
    40 static int doExec(char *pszAdapterName, char *pszAddress, char *pszNetworkMask)
     43static int executeIfconfig(const char *pcszAdapterName, const char *pcszArg1,
     44                           const char *pcszArg2 = NULL,
     45                           const char *pcszArg3 = NULL,
     46                           const char *pcszArg4 = NULL)
    4147{
    42     char *argv[] =
     48    const char * const argv[] =
    4349    {
    4450        VBOXADPCTL_IFCONFIG_PATH,
    45         pszAdapterName,
    46         NULL, /* [address family] */
    47         NULL, /* address */
    48         NULL, /* ['netmask'] */
    49         NULL, /* [network mask] */
     51        pcszAdapterName,
     52        pcszArg1, /* [address family] */
     53        pcszArg2, /* address */
     54        pcszArg3, /* ['netmask'] */
     55        pcszArg4, /* [network mask] */
    5056        NULL  /* terminator */
    5157    };
    52     int i = 2; /* index in argv. we start from address family */
    53 
    54     if (strchr(pszAddress, ':'))
    55         argv[i++] = "inet6";
    56     argv[i++] = pszAddress;
    57     if (pszNetworkMask)
    58     {
    59         argv[i++] = "netmask";
    60         argv[i++] = pszNetworkMask;
    61     }
    62 
    63     return (execv(VBOXADPCTL_IFCONFIG_PATH, argv) == -1 ? EXIT_FAILURE : EXIT_SUCCESS);
    64 }
    65 
    66 static int executeIfconfig(char *pszAdapterName, char *pszAddress, char *pszNetworkMask)
    67 {
    6858    int rc = EXIT_SUCCESS;
    6959    pid_t childPid = fork();
     
    7565            break;
    7666        case 0: /* Child process. */
    77             rc = doExec(pszAdapterName, pszAddress, pszNetworkMask);
     67            if (execv(VBOXADPCTL_IFCONFIG_PATH, (char * const*)argv) == -1)
     68                rc = EXIT_FAILURE;
    7869            break;
    7970        default: /* Parent process. */
     
    8576}
    8677
     78static bool removeAddresses(char *pszAdapterName)
     79{
     80    static char szCmd[1024], szBuf[1024];
     81
     82    snprintf(szCmd, sizeof(szCmd), VBOXADPCTL_IFCONFIG_PATH " %s", pszAdapterName);
     83    FILE *fp = popen(szCmd, "r");
     84
     85    if (!fp)
     86        return false;
     87
     88    std::list<std::string> Addresses;
     89
     90    while (fgets(szBuf, sizeof(szBuf), fp))
     91    {
     92        int cbSkipWS = strspn(szBuf, " \t");
     93        assert(cbSkipWS < 20);
     94        char *pszWord = strtok(szBuf + cbSkipWS, " ");
     95        /* We are concerned with IPv6 address lines only. */
     96        if (!pszWord || strcmp(pszWord, "inet6"))
     97            continue;
     98        pszWord = strtok(NULL, " ");
     99        /* Skip link-local addresses. */
     100        if (!pszWord || !strncmp(pszWord, "fe80", 4))
     101            continue;
     102        Addresses.push_back(std::string(pszWord));
     103    }
     104    pclose(fp);
     105
     106    std::list<std::string>::const_iterator it;
     107    for (it = Addresses.begin(); it != Addresses.end(); it++)
     108    {
     109        if (executeIfconfig(pszAdapterName, "inet6", it->c_str(), "remove") != EXIT_SUCCESS)
     110            return false;
     111    }
     112
     113    return true;
     114}
     115
     116
    87117int main(int argc, char *argv[])
    88118
     
    91121    char *pszAddress;
    92122    char *pszNetworkMask = NULL;
     123    char *pszOption = NULL;
     124    int rc = EXIT_SUCCESS;
    93125
    94126    switch (argc)
     
    101133                return 1;
    102134            }
     135            pszOption = "netmask";
    103136            pszNetworkMask = argv[4];
    104             /* Fall through */
     137            pszAdapterName = argv[1];
     138            pszAddress = argv[2];
     139            break;
     140        case 4:
     141            if (strcmp("remove", argv[3]))
     142            {
     143                fprintf(stderr, "Invalid argument: %s\n\n", argv[3]);
     144                showUsage();
     145                return 1;
     146            }
     147            pszOption = "remove";
     148            pszAdapterName = argv[1];
     149            pszAddress = argv[2];
     150            break;
    105151        case 3:
    106152            pszAdapterName = argv[1];
     
    121167    }
    122168
    123     return executeIfconfig(pszAdapterName, pszAddress, pszNetworkMask);
     169    if (strchr(pszAddress, ':'))
     170    {
     171        /*
     172         * Before we set IPv6 address we'd like to remove
     173         * all previously assigned addresses except the
     174         * self-assigned one.
     175         */
     176        if (pszOption && !strcmp(pszOption, "remove"))
     177            rc = executeIfconfig(pszAdapterName, "inet6", pszAddress, pszOption);
     178        else if (!removeAddresses(pszAdapterName))
     179            rc = EXIT_FAILURE;
     180        else
     181            rc = executeIfconfig(pszAdapterName, "inet6", pszAddress, pszOption, pszNetworkMask);
     182    }
     183    else
     184        rc = executeIfconfig(pszAdapterName, pszAddress, pszOption, pszNetworkMask);
     185    return rc;
    124186}
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