VirtualBox

Changeset 2453 in vbox for trunk/src


Ignore:
Timestamp:
May 2, 2007 4:03:55 PM (18 years ago)
Author:
vboxsync
Message:

Updated the Linux TAP code again to make it more legacy compatible

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r2396 r2453  
    56195619  * @param   tapSetupApplication the name of the setup script
    56205620  */
    5621 HRESULT Console::callTapSetupApplication(Bstr &tapDevice, Bstr &tapSetupApplication)
     5621HRESULT Console::callTapSetupApplication(bool isStatic, RTFILE tapFD, Bstr &tapDevice,
     5622                                         Bstr &tapSetupApplication)
    56225623{
    56235624    LogFlowThisFunc(("\n"));
    56245625#ifdef __LINUX__
    56255626    /* Command line to start the script with. */
    5626     const char *pszArgs;
    5627     /* Buffer to read the script output to.  It doesn't have to be long, as we are only
    5628         interested in the first few (normally 5 or 6) bytes. */
    5629     char acBuffer[64];
    5630     /* The size of the string returned by the script.  We only accept strings of 63 characters
    5631        or less. */
    5632     size_t cBufSize;
     5627    char szCommand[4096];
    56335628    /* Result code */
    56345629    int rc;
    56355630
    56365631    /* Get the script name. */
    5637     Utf8Str tapSetupApp(tapSetupApplication);
    5638     pszArgs = tapSetupApp.raw();
     5632    Utf8Str tapSetupAppUtf8(tapSetupApplication), tapDeviceUtf8(tapDevice);
     5633    RTStrPrintf(szCommand, sizeof(szCommand), "%s %d %s", tapSetupAppUtf8.raw(),
     5634                isStatic ? tapFD : 0, isStatic ? tapDeviceUtf8.raw() : "");
    56395635    /*
    56405636     * Create the process and read its output.
    56415637     */
    5642     FILE *pfScriptHandle = popen(pszArgs, "r");
     5638    Log2(("About to start the TAP setup script with the following command line: %s\n",
     5639          szCommand));
     5640    FILE *pfScriptHandle = popen(szCommand, "r");
    56435641    if (pfScriptHandle == 0)
    56445642    {
    56455643        int iErr = errno;
    56465644        Log(("Failed to start the TAP interface setup script %s, error text: %s\n",
    5647               pszArgs, strerror(iErr)));
     5645              szCommand, strerror(iErr)));
    56485646        LogFlowThisFunc(("rc=E_FAIL\n"));
    56495647        return setError(E_FAIL, tr ("Failed to run the host networking set up command %s: %s"),
    5650                         pszArgs, strerror(iErr));
    5651     }
    5652     fgets(acBuffer, sizeof(acBuffer), pfScriptHandle);
    5653     cBufSize = strlen(acBuffer);
    5654     /* The script must return the name of the interface followed by a carriage return as the
    5655        first line of its output.  We need a null-terminated string. */
    5656     if ((cBufSize < 2) || (acBuffer[cBufSize - 1] != '\n'))
    5657     {
    5658         pclose(pfScriptHandle);
    5659         Log(("The TAP interface setup script did not return the name of a TAP device.\n"));
    5660         LogFlowThisFunc(("rc=E_FAIL\n"));
    5661         return setError(E_FAIL, tr ("The host networking set up command did not supply an interface name"));
    5662     }
    5663     acBuffer[cBufSize - 1] = 0;
    5664     tapDevice = acBuffer;
     5648                        szCommand, strerror(iErr));
     5649    }
     5650    /* If we are using a dynamic TAP interface, we need to get the interface name. */
     5651    if (!isStatic)
     5652    {
     5653        /* Buffer to read the application output to.  It doesn't have to be long, as we are only
     5654            interested in the first few (normally 5 or 6) bytes. */
     5655        char acBuffer[64];
     5656        /* The length of the string returned by the application.  We only accept strings of 63
     5657           characters or less. */
     5658        size_t cBufSize;
     5659
     5660        /* Read the name of the device from the application. */
     5661        fgets(acBuffer, sizeof(acBuffer), pfScriptHandle);
     5662        cBufSize = strlen(acBuffer);
     5663        /* The script must return the name of the interface followed by a carriage return as the
     5664          first line of its output.  We need a null-terminated string. */
     5665        if ((cBufSize < 2) || (acBuffer[cBufSize - 1] != '\n'))
     5666        {
     5667            pclose(pfScriptHandle);
     5668            Log(("The TAP interface setup script did not return the name of a TAP device.\n"));
     5669            LogFlowThisFunc(("rc=E_FAIL\n"));
     5670            return setError(E_FAIL, tr ("The host networking set up command did not supply an interface name"));
     5671        }
     5672        /* Overwrite the terminating newline character. */
     5673        acBuffer[cBufSize - 1] = 0;
     5674        tapDevice = acBuffer;
     5675    }
    56655676    rc = pclose(pfScriptHandle);
    56665677    if (!WIFEXITED(rc))
     
    57495760             * Set/obtain the tap interface.
    57505761             */
     5762            bool isStatic = false;
    57515763            struct ifreq IfReq;
    57525764            memset(&IfReq, 0, sizeof(IfReq));
     
    57545766            Bstr tapDeviceName, tapSetupApplication;
    57555767            rc = networkAdapter->COMGETTER(HostInterface)(tapDeviceName.asOutParam());
    5756             if (FAILED(rc) || tapDeviceName.isEmpty())
     5768            if (FAILED(rc))
    57575769            {
    5758                 networkAdapter->COMGETTER(TAPSetupApplication)(tapSetupApplication.asOutParam());
    5759                 if (tapSetupApplication.isEmpty())
    5760                 {
    5761                     Log(("No setup application was supplied for the TAP interface.\n"));
    5762                     rc = setError(E_FAIL, tr ("No setup application was supplied for the host networking interface"));
    5763                 }
    5764                 else
    5765                 {
    5766                     rc = callTapSetupApplication(tapDeviceName, tapSetupApplication);
    5767                 }
     5770                tapDeviceName.setNull();  /* Is this necessary? */
    57685771            }
    5769             if (SUCCEEDED(rc))
     5772            else if (!tapDeviceName.isEmpty())
    57705773            {
     5774                isStatic = true;
     5775                /* If we are using a static TAP device then try to open it. */
    57715776                Utf8Str str(tapDeviceName);
    57725777                if (str.length() <= sizeof(IfReq.ifr_name))
     
    57765781                IfReq.ifr_flags = IFF_TAP | IFF_NO_PI;
    57775782                rcVBox = ioctl(maTapFD[slot], TUNSETIFF, &IfReq);
    5778                 if (!rcVBox)
     5783                if (rcVBox != 0)
     5784                {
     5785                    Log(("Failed to open the host network interface %ls\n", tapDeviceName.raw()));
     5786                    rc = setError(E_FAIL, tr ("Failed to open the host network interface %ls"),
     5787                                          tapDeviceName.raw());
     5788                }
     5789            }
     5790            if (SUCCEEDED(rc))
     5791            {
     5792                networkAdapter->COMGETTER(TAPSetupApplication)(tapSetupApplication.asOutParam());
     5793                if (tapSetupApplication.isEmpty())
     5794                {
     5795                    if (tapDeviceName.isEmpty())
     5796                    {
     5797                        Log(("No setup application was supplied for the TAP interface.\n"));
     5798                        rc = setError(E_FAIL, tr ("No setup application was supplied for the host networking interface"));
     5799                    }
     5800                }
     5801                else
     5802                {
     5803                    rc = callTapSetupApplication(isStatic, maTapFD[slot], tapDeviceName,
     5804                                                 tapSetupApplication);
     5805                }
     5806            }
     5807            if (SUCCEEDED(rc))
     5808            {
     5809                if (!isStatic)
     5810                {
     5811                    Utf8Str str(tapDeviceName);
     5812                    if (str.length() <= sizeof(IfReq.ifr_name))
     5813                        strcpy(IfReq.ifr_name, str.raw());
     5814                    else
     5815                        memcpy(IfReq.ifr_name, str.raw(), sizeof(IfReq.ifr_name) - 1); /** @todo bitch about names which are too long... */
     5816                    IfReq.ifr_flags = IFF_TAP | IFF_NO_PI;
     5817                    rcVBox = ioctl(maTapFD[slot], TUNSETIFF, &IfReq);
     5818                    if (rcVBox != 0)
     5819                    {
     5820                        Log(("Failed to open the host network interface %ls returned by the setup script", tapDeviceName.raw()));
     5821                        rc = setError(E_FAIL, tr ("Failed to open the host network interface %ls returned by the setup script"), tapDeviceName.raw());
     5822                    }
     5823                }
     5824                if (SUCCEEDED(rc))
    57795825                {
    57805826                    /*
     
    57835829                    if (fcntl(maTapFD[slot], F_SETFL, O_NONBLOCK) != -1)
    57845830                    {
    5785                         tapDeviceName = IfReq.ifr_name;
    5786                         if (tapDeviceName)
    5787                         {
    5788                             Log(("attachToHostInterface: %RTfile %ls\n", maTapFD[slot], tapDeviceName.raw()));
    5789 
    5790                             /*
    5791                             * Here is the right place to communicate the TAP file descriptor and
    5792                             * the host interface name to the server if/when it becomes really
    5793                             * necessary.
    5794                             */
    5795                             maTAPDeviceName[slot] = tapDeviceName;
    5796                             rcVBox = VINF_SUCCESS;
    5797                             rc = S_OK;
    5798                         }
    5799                         else
    5800                             rcVBox = VERR_NO_MEMORY;
     5831                        Log(("attachToHostInterface: %RTfile %ls\n", maTapFD[slot], tapDeviceName.raw()));
     5832
     5833                        /*
     5834                        * Here is the right place to communicate the TAP file descriptor and
     5835                        * the host interface name to the server if/when it becomes really
     5836                        * necessary.
     5837                        */
     5838                        maTAPDeviceName[slot] = tapDeviceName;
     5839                        rcVBox = VINF_SUCCESS;
    58015840                    }
    58025841                    else
     
    58075846                                              strerror(errno));
    58085847                    }
    5809                 }
    5810                 else
    5811                 {
    5812                     AssertMsgFailed(("Configuration error: Failed to configure /dev/net/tun. errno=%d\n", errno));
    5813                     rcVBox = VERR_HOSTIF_IOCTL;
    5814                     rc = setError(E_FAIL, tr ("Could not set up the host networking device: %s"),
    5815                                           strerror(errno));
    58165848                }
    58175849            }
     
    58835915         * Close the file handle.
    58845916         */
    5885         int rcVBox = RTFileClose(maTapFD[slot]);
    5886         AssertRC(rcVBox);
     5917        Bstr tapDeviceName, tapTerminateApplication;
     5918        bool isStatic = true;
     5919        rc = networkAdapter->COMGETTER(HostInterface)(tapDeviceName.asOutParam());
     5920        if (FAILED(rc) || tapDeviceName.isEmpty())
     5921        {
     5922            /* If the name is not empty, this is a dynamic TAP device, so close it now,
     5923               so that the termination script can remove the interface.  Otherwise we still
     5924               need the FD to pass to the termination script. */
     5925            isStatic = false;
     5926            int rcVBox = RTFileClose(maTapFD[slot]);
     5927            AssertRC(rcVBox);
     5928            maTapFD[slot] = NIL_RTFILE;
     5929        }
    58875930        /*
    58885931         * Execute the termination command.
    58895932         */
    5890         Bstr tapTerminateApplication;
    58915933        networkAdapter->COMGETTER(TAPTerminateApplication)(tapTerminateApplication.asOutParam());
    58925934        if (tapTerminateApplication)
     
    58975939            /* Build the command line. */
    58985940            char szCommand[4096];
    5899             RTStrPrintf(szCommand, sizeof(szCommand), "%s %s", tapTermAppUtf8.raw(),
    5900                         maTAPDeviceName[slot].isEmpty() ? "" : maTAPDeviceName[slot].raw());
     5941            RTStrPrintf(szCommand, sizeof(szCommand), "%s %d %s", tapTermAppUtf8.raw(),
     5942                        isStatic ? maTapFD[slot] : 0, maTAPDeviceName[slot].raw());
    59015943
    59025944            /*
     
    59225964        }
    59235965
     5966        if (isStatic)
     5967        {
     5968            /* If we are using a static TAP device, we close it now, after having called the
     5969               termination script. */
     5970            int rcVBox = RTFileClose(maTapFD[slot]);
     5971            AssertRC(rcVBox);
     5972        }
    59245973        /* the TAP device name and handle are no longer valid */
    59255974        maTapFD[slot] = NIL_RTFILE;
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r2386 r2453  
    340340    HRESULT powerDown();
    341341
    342     HRESULT callTapSetupApplication(Bstr &tapDevice, Bstr &tapSetupApplication);
     342    HRESULT callTapSetupApplication(bool isStatic, RTFILE tapFD, Bstr &tapDevice,
     343                                    Bstr &tapSetupApplication);
    343344    HRESULT attachToHostInterface(INetworkAdapter *networkAdapter);
    344345    HRESULT detachFromHostInterface(INetworkAdapter *networkAdapter);
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