VirtualBox

Changeset 17321 in vbox


Ignore:
Timestamp:
Mar 4, 2009 4:44:29 AM (16 years ago)
Author:
vboxsync
Message:

VBoxNetDHCP: Connect and run code.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp

    r17320 r17321  
    99#include <iprt/time.h>
    1010#include <iprt/stream.h>
     11#include <iprt/path.h>
     12#include <iprt/param.h>
    1113#include <iprt/getopt.h>
    1214
    13 #ifdef VBOX_WITH_HARDENING
    14 # include <VBox/sup.h>
    15 #endif
     15#include <VBox/sup.h>
     16#include <VBox/intnet.h>
     17#include <VBox/vmm.h>
    1618#include <VBox/version.h>
    1719
     
    190192    /** The current leases. */
    191193    std::vector<VBoxNetDhcpLease> m_Leases;
     194
     195    /** @name The network interface
     196     * @{ */
     197    PSUPDRVSESSION      m_pSession;
     198    uint32_t            m_cbSendBuf;
     199    uint32_t            m_cbRecvBuf;
     200    INTNETIFHANDLE      m_hIf;          /**< The handle to the network interface. */
     201    PINTNETBUF          m_pIfBuf;       /**< Interface buffer. */
     202    /** @} */
    192203};
    193204
     
    215226    m_MacAddress.au8[5]     = 0x42;
    216227    m_IpAddress.u           = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10,  0,  2,  5)));
     228
     229    m_pSession              = NULL;
     230    m_cbSendBuf             =  8192;
     231    m_cbRecvBuf             = 51200; /** @todo tune to 64 KB with help from SrvIntR0 */
     232    m_hIf                   = INTNET_HANDLE_INVALID;
     233    m_pIfBuf                = NULL;
     234
    217235
    218236#if 1 /* while hacking. */
     
    241259     * Close the interface connection.
    242260     */
     261    if (m_hIf != INTNET_HANDLE_INVALID)
     262    {
     263        INTNETIFCLOSEREQ CloseReq;
     264        CloseReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     265        CloseReq.Hdr.cbReq = sizeof(CloseReq);
     266        CloseReq.pSession = m_pSession;
     267        CloseReq.hIf = m_hIf;
     268        m_hIf = INTNET_HANDLE_INVALID;
     269        int rc = SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_IF_CLOSE, 0, &CloseReq.Hdr);
     270        AssertRC(rc);
     271    }
     272
     273    if (m_pSession)
     274    {
     275        SUPTerm(false /* not forced */);
     276        m_pSession = NULL;
     277    }
    243278}
    244279
     
    406441int VBoxNetDhcp::tryGoOnline(void)
    407442{
    408     return 0;
     443    /*
     444     * Open the session, load ring-0 and issue the request.
     445     */
     446    int rc = SUPR3Init(&m_pSession);
     447    if (RT_FAILURE(rc))
     448    {
     449        m_pSession = NULL;
     450        RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: SUPR3Init -> %Rrc\n", rc);
     451        return 1;
     452    }
     453
     454    char szPath[RTPATH_MAX];
     455    rc = RTPathProgram(szPath, sizeof(szPath) - sizeof("/VMMR0.r0"));
     456    if (RT_FAILURE(rc))
     457    {
     458        RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: RTPathProgram -> %Rrc\n", rc);
     459        return 1;
     460    }
     461
     462    rc = SUPLoadVMM(strcat(szPath, "/VMMR0.r0"));
     463    if (RT_FAILURE(rc))
     464    {
     465        RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: SUPLoadVMM(\"%s\") -> %Rrc\n", szPath, rc);
     466        return 1;
     467    }
     468
     469    /*
     470     * Create the open request.
     471     */
     472    INTNETOPENREQ OpenReq;
     473    OpenReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     474    OpenReq.Hdr.cbReq = sizeof(OpenReq);
     475    OpenReq.pSession = m_pSession;
     476    strncpy(OpenReq.szNetwork, m_Network.c_str(), sizeof(OpenReq.szNetwork));
     477    OpenReq.szTrunk[0] = '\0';
     478    OpenReq.enmTrunkType = kIntNetTrunkType_WhateverNone;
     479    OpenReq.fFlags = 0; /** @todo check this */
     480    OpenReq.cbSend = m_cbSendBuf;
     481    OpenReq.cbRecv = m_cbRecvBuf;
     482    OpenReq.hIf = INTNET_HANDLE_INVALID;
     483
     484    /*
     485     * Issue the request.
     486     */
     487    if (m_cVerbosity >= 2)
     488        RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: attempting to open/create network \"%s\"...\n", OpenReq.szNetwork);
     489    rc = SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_OPEN, 0, &OpenReq.Hdr);
     490    if (RT_SUCCESS(rc))
     491    {
     492        m_hIf = OpenReq.hIf;
     493        if (m_cVerbosity >= 1)
     494            RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: successfully opened/created \"%s\" - hIf=%#x\n",
     495                         OpenReq.szNetwork, m_hIf);
     496
     497        /*
     498         * Get the ring-3 address of the shared interface buffer.
     499         */
     500        INTNETIFGETRING3BUFFERREQ GetRing3BufferReq;
     501        GetRing3BufferReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     502        GetRing3BufferReq.Hdr.cbReq = sizeof(GetRing3BufferReq);
     503        GetRing3BufferReq.pSession = m_pSession;
     504        GetRing3BufferReq.hIf = m_hIf;
     505        GetRing3BufferReq.pRing3Buf = NULL;
     506        rc = SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_IF_GET_RING3_BUFFER, 0, &GetRing3BufferReq.Hdr);
     507        if (RT_SUCCESS(rc))
     508        {
     509            PINTNETBUF pBuf = GetRing3BufferReq.pRing3Buf;
     510            if (m_cVerbosity >= 1)
     511                RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: pBuf=%p cbBuf=%d cbSend=%d cbRecv=%d\n",
     512                             pBuf, pBuf->cbBuf, pBuf->cbSend, pBuf->cbRecv);
     513            m_pIfBuf = pBuf;
     514
     515            /*
     516             * Activate the interface.
     517             */
     518            INTNETIFSETACTIVEREQ ActiveReq;
     519            ActiveReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     520            ActiveReq.Hdr.cbReq = sizeof(ActiveReq);
     521            ActiveReq.pSession = m_pSession;
     522            ActiveReq.hIf = m_hIf;
     523            ActiveReq.fActive = true;
     524            rc = SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_IF_SET_ACTIVE, 0, &ActiveReq.Hdr);
     525            if (RT_SUCCESS(rc))
     526                return 0;
     527
     528            /* bail out */
     529            RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: SUPCallVMMR0Ex(,VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE,) failed, rc=%Rrc\n", rc);
     530        }
     531        else
     532            RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: SUPCallVMMR0Ex(,VMMR0_DO_INTNET_IF_GET_RING3_BUFFER,) failed, rc=%Rrc\n", rc);
     533    }
     534    else
     535        RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: SUPCallVMMR0Ex(,VMMR0_DO_INTNET_OPEN,) failed, rc=%Rrc\n", rc);
     536
     537    return RT_SUCCESS(rc) ? 0 : 1;
    409538}
    410539
     
    413542 * Runs the DHCP server.
    414543 *
    415  * @returns 0 on success, exit code + error message to stderr on failure.
     544 * @returns exit code + error message to stderr on failure, won't return on
     545 *          success (you must kill this process).
    416546 */
    417547int VBoxNetDhcp::run(void)
    418548{
     549/** @todo The idea is that run() to use VBoxNetUDP here to mimic sockets and not
     550 *        do all the parsing here...  */
     551
     552
     553    /*
     554     * The loop.
     555     */
     556    PINTNETRINGBUF  pRingBuf = &m_pIfBuf->Recv;
     557    for (;;)
     558    {
     559        /*
     560         * Wait for a packet to become available.
     561         */
     562        INTNETIFWAITREQ WaitReq;
     563        WaitReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     564        WaitReq.Hdr.cbReq = sizeof(WaitReq);
     565        WaitReq.pSession = m_pSession;
     566        WaitReq.hIf = m_hIf;
     567        WaitReq.cMillies = RT_INDEFINITE_WAIT;
     568        int rc = SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_IF_WAIT, 0, &WaitReq.Hdr);
     569        if (RT_FAILURE(rc))
     570        {
     571            RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: VMMR0_DO_INTNET_IF_WAIT returned %Rrc\n", rc);
     572            return 1;
     573        }
     574
     575        /*
     576         * Process the receive buffer.
     577         */
     578        while (INTNETRingGetReadable(pRingBuf) > 0)
     579        {
     580            PINTNETHDR pHdr = (PINTNETHDR)((uintptr_t)m_pIfBuf + pRingBuf->offRead);
     581            if (pHdr->u16Type == INTNETHDR_TYPE_FRAME)
     582            {
     583                size_t      cbFrame = pHdr->cbFrame;
     584                const void *pvFrame = INTNETHdrGetFramePtr(pHdr, m_pIfBuf);
     585
     586                PCRTNETETHERHDR pEthHdr = (PCRTNETETHERHDR)pvFrame;
     587                if (m_cVerbosity >= 2)
     588                    RTStrmPrintf(g_pStdErr, "frame: cb=%04x dst=%.6Rhxs src=%.6Rhxs type=%04x%s\n",
     589                                 cbFrame, &pEthHdr->DstMac, &pEthHdr->SrcMac, RT_BE2H_U16(pEthHdr->EtherType),
     590                                 !memcmp(&pEthHdr->DstMac, &m_MacAddress, sizeof(m_MacAddress)) ? " Mine!" : "");
     591
     592                /* Look for the DHCP messages. */
     593                if (    cbFrame > 64
     594                    &&  RT_BE2H_U16(pEthHdr->EtherType) == 0x0800 /* EtherType == IP */)
     595                {
     596                    PCRTNETIPV4 pIpHdr = (PCRTNETIPV4)(pEthHdr + 1);
     597                    PCRTNETUDP pUdpHdr = (PCRTNETUDP)((uint32_t *)pIpHdr + pIpHdr->ip_hl);
     598                    if (    pIpHdr->ip_p == 0x11 /*UDP*/
     599                        &&  RT_BE2H_U16(pUdpHdr->uh_dport) == 68 /* bootp */
     600                        &&  RT_BE2H_U16(pUdpHdr->uh_sport) == 67 /* bootps */)
     601                    {
     602
     603//                        PCRTNETDHCP pDhcpMsg = (PCRTNETDHCP)(pUdpHdr + 1);
     604
     605                    }
     606                }
     607            }
     608
     609            /* Advance to the next frame. */
     610            INTNETRingSkipFrame(m_pIfBuf, pRingBuf);
     611        }
     612    }
     613
    419614    return 0;
    420615}
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