VirtualBox

Changeset 49735 in vbox


Ignore:
Timestamp:
Nov 30, 2013 2:08:42 AM (11 years ago)
Author:
vboxsync
Message:

VBoxNetBaseService hides all details of internal network implementation and become responsible for supporting receiving loop. Notification of children are done via introduced interface:

virtual int processFrame(void *, size_t) = 0;
virtual int processGSO(PCPDMNETWORKGSO, size_t) = 0;
virtual int processUDP(void *, size_t) = 0;

processFrame() and processGSO() might return VERR_IGNORED, to inform base service switch to processUDP() (e.g. for DHCP needs)

Location:
trunk/src/VBox/NetworkServices
Files:
8 edited

Legend:

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

    r49569 r49735  
    66
    77#include <iprt/asm.h>
     8#include <iprt/getopt.h>
    89#include <iprt/net.h>
    910#include <iprt/time.h>
     
    1920#include <iprt/cpp/xml.h>
    2021
     22#define BASE_SERVICES_ONLY
     23#include "../NetLib/VBoxNetBaseService.h"
    2124#include "../NetLib/VBoxNetLib.h"
    2225#include "../NetLib/shared_ptr.h"
     
    666669        cbBooPReplyMsg = 0;
    667670       
    668         m_pSession = NIL_RTR0PTR;
    669         m_pIfBuf = NULL;
    670671        m_OurAddress.u = 0;
    671672        m_OurNetmask.u = 0;
     
    679680    int cbBooPReplyMsg;
    680681
    681     /* XXX: artifacts should be hidden or removed from here. */
    682     PSUPDRVSESSION m_pSession;
    683     INTNETIFHANDLE m_hIf;
    684     PINTNETBUF m_pIfBuf;
    685 
    686682    RTNETADDRIPV4 m_OurAddress;
    687683    RTNETADDRIPV4 m_OurNetmask;
    688684    RTMAC m_OurMac;
     685    const VBoxNetHlpUDPService *m_service;
    689686};
    690687
     
    748745
    749746
    750 void NetworkManager::setSession(PSUPDRVSESSION aSession)
    751 {
    752     m->m_pSession = aSession;
    753 }
    754 
    755 
    756 void NetworkManager::setInterface(INTNETIFHANDLE aIf)
    757 {
    758     m->m_hIf = aIf;
    759 }
    760 
    761 
    762 void NetworkManager::setRingBuffer(PINTNETBUF aBuf)
    763 {
    764     m->m_pIfBuf = aBuf;
    765 }
     747void NetworkManager::setService(const VBoxNetHlpUDPService *srv)
     748{
     749    m->m_service = srv;
     750}
     751
    766752/**
    767753 * Network manager creates DHCPOFFER datagramm
     
    982968    else
    983969#endif
    984         rc = VBoxNetUDPBroadcast(m->m_pSession,
    985                                  m->m_hIf,
    986                                  m->m_pIfBuf,
    987                                  m->m_OurAddress,
    988                                  &m->m_OurMac,
    989                                  RTNETIPV4_PORT_BOOTPS,               /* sender */
    990                                  RTNETIPV4_PORT_BOOTPC,
    991                                  &m->BootPReplyMsg, RTNET_DHCP_NORMAL_SIZE);
     970        rc = m->m_service->hlpUDPBroadcast(RTNETIPV4_PORT_BOOTPS,               /* sender */
     971                                           RTNETIPV4_PORT_BOOTPC,
     972                                           &m->BootPReplyMsg,
     973                                           RTNET_DHCP_NORMAL_SIZE);
    992974
    993975    AssertRCReturn(rc,rc);
  • trunk/src/VBox/NetworkServices/DHCP/Config.h

    r49568 r49735  
    503503    void setOurMac(const RTMAC& aMac);
    504504
    505     void setSession(PSUPDRVSESSION);
    506     void setInterface(INTNETIFHANDLE);
    507     void setRingBuffer(PINTNETBUF);
    508 
    509505    bool handleDhcpReqDiscover(PCRTNETBOOTP pDhcpMsg, size_t cb);
    510506    bool handleDhcpReqRequest(PCRTNETBOOTP pDhcpMsg, size_t cb);
    511507    bool handleDhcpReqDecline(PCRTNETBOOTP pDhcpMsg, size_t cb);
    512508    bool handleDhcpReqRelease(PCRTNETBOOTP pDhcpMsg, size_t cb);
     509
     510    void setService(const VBoxNetHlpUDPService *);
    513511private:
    514512    NetworkManager();
  • trunk/src/VBox/NetworkServices/DHCP/NetworkManagerDhcp.cpp

    r49566 r49735  
    2121#include <iprt/asm.h>
    2222#include <iprt/cdefs.h>
     23#include <iprt/getopt.h>
    2324#include <iprt/net.h>
    2425#include <iprt/param.h>
     
    3839#include <VBox/intnet.h>
    3940
     41#define BASE_SERVICES_ONLY
     42#include "../NetLib/VBoxNetBaseService.h"
    4043#include "Config.h"
    4144#include "ClientDataInt.h"
  • trunk/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp

    r49564 r49735  
    9595    void                usage(void) { /* XXX: document options */ };
    9696    int                 parseOpt(int rc, const RTGETOPTUNION& getOptVal);
     97    int                 processFrame(void *, size_t) {return VERR_IGNORED; };
     98    int                 processGSO(PCPDMNETWORKGSO, size_t) {return VERR_IGNORED; };
     99    int                 processUDP(void *, size_t);
     100
    97101
    98102protected:
     
    169173 * Construct a DHCP server with a default configuration.
    170174 */
    171 VBoxNetDhcp::VBoxNetDhcp()
    172 {
    173     m_Name                  = "VBoxNetDhcp";
    174     m_Network               = "VBoxNetDhcp";
    175     m_TrunkName             = "";
    176     m_enmTrunkType          = kIntNetTrunkType_WhateverNone;
    177     m_MacAddress.au8[0]     = 0x08;
    178     m_MacAddress.au8[1]     = 0x00;
    179     m_MacAddress.au8[2]     = 0x27;
    180     m_MacAddress.au8[3]     = 0x40;
    181     m_MacAddress.au8[4]     = 0x41;
    182     m_MacAddress.au8[5]     = 0x42;
    183     m_Ipv4Address.u         = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10,  0,  2,  5)));
    184 
    185     m_pSession              = NIL_RTR0PTR;
    186     m_cbSendBuf             =  8192;
    187     m_cbRecvBuf             = 51200; /** @todo tune to 64 KB with help from SrvIntR0 */
    188     m_hIf                   = INTNET_HANDLE_INVALID;
    189     m_pIfBuf                = NULL;
    190 
    191     m_cVerbosity            = 0;
     175VBoxNetDhcp::VBoxNetDhcp():VBoxNetBaseService("VBoxNetDhcp", "VBoxNetDhcp")
     176{
     177    /*   m_enmTrunkType          = kIntNetTrunkType_WhateverNone; */
     178    RTMAC mac;
     179    mac.au8[0]     = 0x08;
     180    mac.au8[1]     = 0x00;
     181    mac.au8[2]     = 0x27;
     182    mac.au8[3]     = 0x40;
     183    mac.au8[4]     = 0x41;
     184    mac.au8[5]     = 0x42;
     185    setMacAddress(mac);
     186
     187    RTNETADDRIPV4 address;
     188    address.u = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10,  0,  2,  5)));
     189    setIpv4Address(address);
     190
     191    setSendBufSize(8 * _1K);
     192    setRecvBufSize(50 * _1K);
     193
    192194    m_uCurMsgType           = UINT8_MAX;
    193195    m_cbCurMsg              = 0;
     
    198200
    199201    for(unsigned int i = 0; i < RT_ELEMENTS(g_aOptionDefs); ++i)
    200         m_vecOptionDefs.push_back(&g_aOptionDefs[i]);
    201 
    202 #if 0 /* enable to hack the code without a mile long argument list. */
    203     VBoxNetDhcpCfg *pDefCfg = new VBoxNetDhcpCfg();
    204     pDefCfg->m_LowerAddr.u    = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10,  0,  2,100)));
    205     pDefCfg->m_UpperAddr.u    = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10,  0,  2,250)));
    206     pDefCfg->m_SubnetMask.u   = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8(255,255,255,  0)));
    207     RTNETADDRIPV4 Addr;
    208     Addr.u                    = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10,  0,  2,  1)));
    209     pDefCfg->m_Routers.push_back(Addr);
    210     Addr.u                    = RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8( 10,  0,  2,  2)));
    211     pDefCfg->m_DNSes.push_back(Addr);
    212     pDefCfg->m_DomainName     = "vboxnetdhcp.org";
    213 # if 0
    214     pDefCfg->m_cSecLease      = 60*60; /* 1 hour */
    215 # else
    216     pDefCfg->m_cSecLease      = 30; /* sec */
    217 # endif
    218     pDefCfg->m_TftpServer     = "10.0.2.3"; //??
    219     this->addConfig(pDefCfg);
    220 #endif
     202        addCommandLineOption(&g_aOptionDefs[i]);
    221203}
    222204
     
    282264    NetworkManager *netManager = NetworkManager::getNetworkManager();
    283265
    284     netManager->setOurAddress(m_Ipv4Address);
    285     netManager->setOurNetmask(m_Ipv4Netmask);
    286     netManager->setOurMac(m_MacAddress);
     266    netManager->setOurAddress(getIpv4Address());
     267    netManager->setOurNetmask(getIpv4Netmask());
     268    netManager->setOurMac(getMacAddress());
     269    netManager->setService(this);
    287270   
    288271    if (isMainNeeded())
     
    304287int VBoxNetDhcp::run(void)
    305288{
    306 
    307     /* XXX: shortcut should be hidden from network manager */
    308     NetworkManager *netManager = NetworkManager::getNetworkManager();
    309     netManager->setSession(m_pSession);
    310     netManager->setInterface(m_hIf);
    311     netManager->setRingBuffer(m_pIfBuf);
    312 
    313     /*
    314      * The loop.
    315      */
    316     PINTNETRINGBUF  pRingBuf = &m_pIfBuf->Recv;
    317     for (;;)
    318     {
    319         /*
    320          * Wait for a packet to become available.
    321          */
    322         INTNETIFWAITREQ WaitReq;
    323         WaitReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    324         WaitReq.Hdr.cbReq = sizeof(WaitReq);
    325         WaitReq.pSession = m_pSession;
    326         WaitReq.hIf = m_hIf;
    327         WaitReq.cMillies = 2000; /* 2 secs - the sleep is for some reason uninterruptible... */  /** @todo fix interruptability in SrvIntNet! */
    328         int rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_WAIT, 0, &WaitReq.Hdr);
    329         if (RT_FAILURE(rc))
    330         {
    331             if (rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED)
    332                 continue;
    333             RTStrmPrintf(g_pStdErr, "VBoxNetDHCP: VMMR0_DO_INTNET_IF_WAIT returned %Rrc\n", rc);
    334             return 1;
    335         }
    336 
    337         /*
    338          * Process the receive buffer.
    339          */
    340         while (IntNetRingHasMoreToRead(pRingBuf))
    341         {
    342             size_t  cb;
    343             void   *pv = VBoxNetUDPMatch(m_pIfBuf, RTNETIPV4_PORT_BOOTPS, &m_MacAddress,
    344                                          VBOXNETUDP_MATCH_UNICAST | VBOXNETUDP_MATCH_BROADCAST | VBOXNETUDP_MATCH_CHECKSUM
    345                                          | (m_cVerbosity > 2 ? VBOXNETUDP_MATCH_PRINT_STDERR : 0),
    346                                          &m_CurHdrs, &cb);
    347             if (pv && cb)
    348             {
    349                 PCRTNETBOOTP pDhcpMsg = (PCRTNETBOOTP)pv;
    350                 m_pCurMsg  = pDhcpMsg;
    351                 m_cbCurMsg = cb;
    352 
    353                 uint8_t uMsgType;
    354                 if (RTNetIPv4IsDHCPValid(NULL /* why is this here? */, pDhcpMsg, cb, &uMsgType))
    355                 {
    356                     m_uCurMsgType = uMsgType;
    357                     handleDhcpMsg(uMsgType, pDhcpMsg, cb);
    358                     m_uCurMsgType = UINT8_MAX;
    359                 }
    360                 else
    361                     debugPrint(1, true, "VBoxNetDHCP: Skipping invalid DHCP packet.\n"); /** @todo handle pure bootp clients too? */
    362 
    363                 m_pCurMsg = NULL;
    364                 m_cbCurMsg = 0;
    365             }
    366             else if (VBoxNetArpHandleIt(m_pSession, m_hIf, m_pIfBuf, &m_MacAddress, m_Ipv4Address))
    367             {
    368                 /* nothing */
    369             }
    370 
    371             /* Advance to the next frame. */
    372             IntNetRingSkipFrame(pRingBuf);
    373         }
    374     }
    375 
     289    doReceiveLoop();
    376290    return 0;
     291}
     292
     293
     294int  VBoxNetDhcp::processUDP(void *pv, size_t cbPv)
     295{
     296    PCRTNETBOOTP pDhcpMsg = (PCRTNETBOOTP)pv;
     297    m_pCurMsg  = pDhcpMsg;
     298    m_cbCurMsg = cbPv;
     299
     300    uint8_t uMsgType;
     301    if (RTNetIPv4IsDHCPValid(NULL /* why is this here? */, pDhcpMsg, cbPv, &uMsgType))
     302    {
     303        m_uCurMsgType = uMsgType;
     304        handleDhcpMsg(uMsgType, pDhcpMsg, cbPv);
     305        m_uCurMsgType = UINT8_MAX;
     306    }
     307    else
     308        debugPrint(1, true, "VBoxNetDHCP: Skipping invalid DHCP packet.\n"); /** @todo handle pure bootp clients too? */
     309
     310    m_pCurMsg = NULL;
     311    m_cbCurMsg = 0;
     312
     313    return VINF_SUCCESS;
    377314}
    378315
     
    495432    CmdParameterIterator it;
    496433
     434    RTNETADDRIPV4 address = getIpv4Address();
     435    RTNETADDRIPV4 netmask = getIpv4Netmask();
    497436    RTNETADDRIPV4 networkId;
    498     networkId.u = m_Ipv4Address.u & m_Ipv4Netmask.u;
    499     RTNETADDRIPV4 netmask = m_Ipv4Netmask;
     437    networkId.u = address.u & netmask.u;
    500438
    501439    RTNETADDRIPV4 UpperAddress;
     
    524462    confManager->addNetwork(unconst(g_RootConfig),
    525463                            networkId,
    526                             m_Ipv4Netmask,
     464                            netmask,
    527465                            LowerAddress,
    528466                            UpperAddress);
     
    538476     */
    539477    AssertRCReturn(virtualbox.isNull(), VERR_INTERNAL_ERROR);
    540 
    541     HRESULT hrc = virtualbox->FindDHCPServerByNetworkName(com::Bstr(m_Network.c_str()).raw(),
    542                                                   m_DhcpServer.asOutParam());
     478    std::string networkName = getNetwork();
     479
     480    HRESULT hrc = virtualbox->FindDHCPServerByNetworkName(com::Bstr(networkName.c_str()).raw(),
     481                                                          m_DhcpServer.asOutParam());
    543482    AssertComRCReturn(hrc, VERR_INTERNAL_ERROR);
    544483
    545     hrc = virtualbox->FindNATNetworkByName(com::Bstr(m_Network.c_str()).raw(),
     484    hrc = virtualbox->FindNATNetworkByName(com::Bstr(networkName.c_str()).raw(),
    546485                                           m_NATNetwork.asOutParam());
    547486
     
    602541    }
    603542
     543
     544    RTNETADDRIPV4 address = getIpv4Address();
     545    RTNETADDRIPV4 netmask = getIpv4Netmask();
    604546    strs.setNull();
    605547    ComPtr<IHost> host;
     
    621563                        if (MapIp4Addr2Off[addr] != 0)
    622564                        {
    623                             addr.u = RT_H2N_U32(RT_N2H_U32(m_Ipv4Address.u & m_Ipv4Netmask.u)
     565                            addr.u = RT_H2N_U32(RT_N2H_U32(address.u & netmask.u)
    624566                                                + MapIp4Addr2Off[addr]);
    625567                        }
     
    661603
    662604    RTNETADDRIPV4 networkId;
    663     networkId.u = m_Ipv4Address.u & m_Ipv4Netmask.u;
     605    networkId.u = address.u & netmask.u;
    664606    std::string name = std::string("default");
    665607
    666608    confManager->addNetwork(unconst(g_RootConfig),
    667609                            networkId,
    668                             m_Ipv4Netmask,
     610                            netmask,
    669611                            LowerAddress,
    670612                            UpperAddress);
     
    673615    hrc = virtualbox->COMGETTER(HomeFolder)(bstr.asOutParam());
    674616    std::string strXmlLeaseFile(com::Utf8StrFmt("%ls%c%s.leases",
    675                                                 bstr.raw(), RTPATH_DELIMITER, m_Network.c_str()).c_str());
     617                                                bstr.raw(), RTPATH_DELIMITER, networkName.c_str()).c_str());
    676618    confManager->loadFromFile(strXmlLeaseFile);
    677619
  • trunk/src/VBox/NetworkServices/NAT/Makefile.kmk

    r49713 r49735  
    4545VBoxNetLwipNAT_SOURCES += VBoxNetLwipNAT.cpp    \
    4646        ../NetLib/VBoxNetBaseService.cpp \
    47         ../NetLib/VBoxNetPortForwardString.cpp
     47        ../NetLib/VBoxNetPortForwardString.cpp \
     48        ../NetLib/VBoxNetIntIf.cpp \
     49        ../NetLib/VBoxNetUDP.cpp \
     50        ../NetLib/VBoxNetARP.cpp
     51
    4852VBoxNetLwipNAT_LIBS = \
    4953        $(LIB_RUNTIME)
  • trunk/src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp

    r49711 r49735  
    164164    /* VBoxNetNAT always needs Main */
    165165    virtual bool isMainNeeded() const { return true; }
     166    virtual int processFrame(void *, size_t);
     167    virtual int processGSO(PCPDMNETWORKGSO, size_t);
     168    virtual int processUDP(void *, size_t) { return VERR_IGNORED; }
     169
    166170   private:
    167171    struct proxy_options m_ProxyOptions;
     
    187191    ComPtr<IHost> m_host;
    188192    ComObjPtr<NATNetworkListenerImpl> m_vboxListener;
     193    static INTNETSEG aXmitSeg[64];
    189194
    190195    STDMETHOD(HandleEvent)(VBoxEventType_T aEventType, IEvent *pEvent);
     
    202207    static err_t netifLinkoutput(netif *pNetif, pbuf *pBuf);
    203208    static int intNetThreadRecv(RTTHREAD, void *);
    204     static void vboxNetLwipNATProcessXmit(void);
    205209
    206210    VECNATSERVICEPF m_vecPortForwardRule4;
     
    213217
    214218static VBoxNetLwipNAT *g_pLwipNat;
     219INTNETSEG VBoxNetLwipNAT::aXmitSeg[64];
    215220
    216221STDMETHODIMP NATNetworkListener::HandleEvent(VBoxEventType_T aEventType, IEvent *pEvent)
     
    411416
    412417    /* lwip thread */
    413     RTNETADDRIPV4 IpNetwork;
    414     IpNetwork.u = g_pLwipNat->m_Ipv4Address.u & g_pLwipNat->m_Ipv4Netmask.u;
     418    RTNETADDRIPV4 network;
     419    RTNETADDRIPV4 address = g_pLwipNat->getIpv4Address();
     420    RTNETADDRIPV4 netmask = g_pLwipNat->getIpv4Netmask();
     421    network.u = address.u & netmask.u;
    415422
    416423    ip_addr LwipIpAddr, LwipIpNetMask, LwipIpNetwork;
    417424
    418     memcpy(&LwipIpAddr, &g_pLwipNat->m_Ipv4Address, sizeof(ip_addr));
    419     memcpy(&LwipIpNetMask, &g_pLwipNat->m_Ipv4Netmask, sizeof(ip_addr));
    420     memcpy(&LwipIpNetwork, &IpNetwork, sizeof(ip_addr));
     425    memcpy(&LwipIpAddr, &address, sizeof(ip_addr));
     426    memcpy(&LwipIpNetMask, &netmask, sizeof(ip_addr));
     427    memcpy(&LwipIpNetwork, &network, sizeof(ip_addr));
    421428
    422429    netif *pNetif = netif_add(&g_pLwipNat->m_LwipNetIf /* Lwip Interface */,
     
    504511
    505512    pNetif->hwaddr_len = sizeof(RTMAC);
    506     memcpy(pNetif->hwaddr, &pNat->m_MacAddress, sizeof(RTMAC));
     513    RTMAC mac = g_pLwipNat->getMacAddress();
     514    memcpy(pNetif->hwaddr, &mac, sizeof(RTMAC));
    507515
    508516    pNat->m_u16Mtu = 1500; // XXX: FIXME
     
    561569        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to initialize COM!");
    562570
    563     /* Well we're ready */
    564     PINTNETRINGBUF  pRingBuf = &g_pLwipNat->m_pIfBuf->Recv;
    565 
    566     for (;;)
    567     {
    568         /*
    569          * Wait for a packet to become available.
    570          */
    571         /* 2. waiting for request for */
    572         rc = g_pLwipNat->waitForIntNetEvent(2000);
    573         if (RT_FAILURE(rc))
    574         {
    575             if (rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED)
    576             {
    577                 /* do we want interrupt anyone ??? */
    578                 continue;
    579             }
    580             LogRel(("VBoxNetNAT: waitForIntNetEvent returned %Rrc\n", rc));
    581             AssertRCReturn(rc,ERR_IF);
    582         }
    583 
    584         /*
    585          * Process the receive buffer.
    586          */
    587         PCINTNETHDR pHdr;
    588 
    589         while ((pHdr = IntNetRingGetNextFrameToRead(pRingBuf)) != NULL)
    590         {
    591             uint8_t const u8Type = pHdr->u8Type;
    592             size_t         cbFrame = pHdr->cbFrame;
    593             uint8_t        *pu8Frame = NULL;
    594             pbuf           *pPbufHdr = NULL;
    595             pbuf           *pPbuf = NULL;
    596             switch (u8Type)
    597             {
    598 
    599                 case INTNETHDR_TYPE_FRAME:
    600                     /* @todo:should it be really here?
    601                      * Well well well, we're accessing lwip code here
    602                      */
    603                     pPbufHdr = pPbuf = pbuf_alloc(PBUF_RAW, pHdr->cbFrame, PBUF_POOL);
    604                     if (!pPbuf)
    605                     {
    606                         LogRel(("NAT: Can't allocate send buffer cbFrame=%u\n", cbFrame));
    607                         break;
    608                     }
    609                     Assert(pPbufHdr->tot_len == cbFrame);
    610                     pu8Frame = (uint8_t *)IntNetHdrGetFramePtr(pHdr, g_pLwipNat->m_pIfBuf);
    611                     while(pPbuf)
    612                     {
    613                         memcpy(pPbuf->payload, pu8Frame, pPbuf->len);
    614                         pu8Frame += pPbuf->len;
    615                         pPbuf = pPbuf->next;
    616                     }
    617 
    618                     g_pLwipNat->m_LwipNetIf.input(pPbufHdr, &g_pLwipNat->m_LwipNetIf);
    619 
    620                     AssertReleaseRC(rc);
    621                     break;
    622                 case INTNETHDR_TYPE_GSO:
    623                   {
    624                       PCPDMNETWORKGSO pGso = IntNetHdrGetGsoContext(pHdr,
    625                                                                     g_pLwipNat->m_pIfBuf);
    626                       if (!PDMNetGsoIsValid(pGso, cbFrame,
    627                                             cbFrame - sizeof(PDMNETWORKGSO)))
    628                           break;
    629                       cbFrame -= sizeof(PDMNETWORKGSO);
    630                       uint8_t         abHdrScratch[256];
    631                       uint32_t const  cSegs = PDMNetGsoCalcSegmentCount(pGso,
    632                                                                         cbFrame);
    633                       for (size_t iSeg = 0; iSeg < cSegs; iSeg++)
    634                       {
    635                           uint32_t cbSegFrame;
    636                           void    *pvSegFrame =
    637                             PDMNetGsoCarveSegmentQD(pGso,
    638                                                     (uint8_t *)(pGso + 1),
    639                                                     cbFrame,
    640                                                     abHdrScratch,
    641                                                     iSeg,
    642                                                     cSegs,
    643                                                     &cbSegFrame);
    644 
    645                           pPbuf = pbuf_alloc(PBUF_RAW, cbSegFrame, PBUF_POOL);
    646                           if (!pPbuf)
    647                           {
    648                               LogRel(("NAT: Can't allocate send buffer cbFrame=%u\n", cbSegFrame));
    649                               break;
    650                           }
    651                           Assert(   !pPbuf->next
    652                                  && pPbuf->len == cbSegFrame);
    653                           memcpy(pPbuf->payload, pvSegFrame, cbSegFrame);
    654                           g_pLwipNat->m_LwipNetIf.input(pPbuf, &g_pLwipNat->m_LwipNetIf);
    655 
    656                       }
    657 
    658                   }
    659                   break;
    660                 case INTNETHDR_TYPE_PADDING:
    661                     break;
    662                 default:
    663                     STAM_REL_COUNTER_INC(&g_pLwipNat->m_pIfBuf->cStatBadFrames);
    664                     break;
    665             }
    666             IntNetRingSkipFrame(&g_pLwipNat->m_pIfBuf->Recv);
    667 
    668         } /* loop */
    669     }
     571    g_pLwipNat->doReceiveLoop();
    670572    /* 3. deinitilization and termination */
    671573    LogFlowFuncLeaveRC(rc);
     
    674576
    675577
    676 /**
    677  *
    678  */
    679 void VBoxNetLwipNAT::vboxNetLwipNATProcessXmit()
    680 {
    681     int rc = VINF_SUCCESS;
    682     INTNETIFSENDREQ SendReq;
    683     SendReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    684     SendReq.Hdr.cbReq    = sizeof(SendReq);
    685     SendReq.pSession     = g_pLwipNat->m_pSession;
    686     SendReq.hIf          = g_pLwipNat->m_hIf;
    687     rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_SEND, 0, &SendReq.Hdr);
    688     AssertRC(rc);
    689 }
    690 
    691 
    692578err_t VBoxNetLwipNAT::netifLinkoutput(netif *pNetif, pbuf *pPBuf)
    693579{
    694     int rc = VINF_SUCCESS;
    695     err_t rcLwip = ERR_OK;
    696580    AssertPtrReturn(pNetif, ERR_ARG);
    697581    AssertPtrReturn(pPBuf, ERR_ARG);
    698582    AssertReturn((void *)g_pLwipNat == pNetif->state, ERR_ARG);
     583
    699584    LogFlowFunc(("ENTER: pNetif[%c%c%d], pPbuf:%p\n",
    700585                 pNetif->name[0],
     
    703588                 pPBuf));
    704589
    705     /*
    706      * We're on the lwip thread ...
    707      * try accure Xmit lock (actually we DO accure the lock ... )
    708      * 1. we've entered csXmit so we should create frame
    709      *   1.a. Frame creation success see 2.
    710      *   1.b. (hm ... what about queue processing in place)
    711      *   1.c. 2nd attempt create frame
    712      *   1.d. Unlock the Xmit
    713      *   1.e. goto BUSY.1
    714      * 2. Copy pbuf to the frame
    715      * 3. Send
    716      * 4. leave csXmit & return.
    717      *
    718      * @todo: perhaps we can use it for optimization,
    719      * e.g. drop UDP and reoccure lock on TCP NOTE: now BUSY is unachievable!
    720      * Otherwise (BUSY)
    721      * 1. Unbuffered (drop)
    722      * (buffered)
    723      * 1. Copy pbuf to entermediate buffer.
    724      * 2. Add call buffer to the queue
    725      * 3. return.
    726      */
    727     /* see p.1 */
    728     rc = VINF_SUCCESS;
    729     PINTNETHDR pHdr = NULL;
    730     uint8_t *pu8Frame = NULL;
    731     int offFrame = 0;
    732     int idxSg = 0;
    733     struct pbuf *pPBufPtr = pPBuf;
    734     /* Allocate frame, and pad it if required. */
    735     rc = IntNetRingAllocateFrame(&g_pLwipNat->m_pIfBuf->Send, pPBuf->tot_len, &pHdr, (void **)&pu8Frame);
    736     if (RT_SUCCESS(rc))
    737     {
    738         /* see p. 2 */
    739         while (pPBufPtr)
    740         {
    741             memcpy(&pu8Frame[offFrame], pPBufPtr->payload, pPBufPtr->len);
    742             offFrame += pPBufPtr->len;
    743             pPBufPtr = pPBufPtr->next;
    744         }
    745     }
    746     if (RT_FAILURE(rc))
    747     {
    748         /* Could it be that some frames are still in the ring buffer */
    749         /* 1.c */
    750         AssertMsgFailed(("Debug Me!"));
    751     }
    752 
    753     /* Commit - what really this function do  */
    754     IntNetRingCommitFrameEx(&g_pLwipNat->m_pIfBuf->Send, pHdr, pPBuf->tot_len);
    755 
    756     g_pLwipNat->vboxNetLwipNATProcessXmit();
    757 
     590    RT_ZERO(VBoxNetLwipNAT::aXmitSeg);
     591   
     592    unsigned idx = 0;
     593    for( struct pbuf *pPBufPtr = pPBuf;
     594         pPBufPtr;
     595         pPBufPtr = pPBufPtr->next, ++idx)
     596    {
     597        AssertReturn(idx < RT_ELEMENTS(VBoxNetLwipNAT::aXmitSeg), ERR_MEM);
     598        VBoxNetLwipNAT::aXmitSeg[idx].pv = pPBufPtr->payload;
     599        VBoxNetLwipNAT::aXmitSeg[idx].cb = pPBufPtr->len;
     600    }
     601
     602    int rc = g_pLwipNat->sendBufferOnWire(VBoxNetLwipNAT::aXmitSeg, idx, pPBuf->tot_len);
    758603    AssertRCReturn(rc, ERR_IF);
    759     LogFlowFunc(("LEAVE: %d\n", rcLwip));
    760     return rcLwip;
    761 }
    762 
    763 
    764 VBoxNetLwipNAT::VBoxNetLwipNAT(SOCKET icmpsock4, SOCKET icmpsock6)
     604
     605    g_pLwipNat->flushWire();
     606
     607    LogFlowFunc(("LEAVE: %d\n", ERR_OK));
     608    return ERR_OK;
     609}
     610
     611
     612VBoxNetLwipNAT::VBoxNetLwipNAT(SOCKET icmpsock4, SOCKET icmpsock6) : VBoxNetBaseService("VBoxNetNAT", "nat-network")
    765613{
    766614    LogFlowFuncEnter();
     
    785633    m_LwipNetIf.name[0] = 'N';
    786634    m_LwipNetIf.name[1] = 'T';
    787     m_MacAddress.au8[0] = 0x52;
    788     m_MacAddress.au8[1] = 0x54;
    789     m_MacAddress.au8[2] = 0;
    790     m_MacAddress.au8[3] = 0x12;
    791     m_MacAddress.au8[4] = 0x35;
    792     m_MacAddress.au8[5] = 0;
    793     m_Ipv4Address.u     = RT_MAKE_U32_FROM_U8( 10,  0,  2,  2); // NB: big-endian
    794     m_Ipv4Netmask.u     = RT_H2N_U32_C(0xffffff00);
     635
     636    RTMAC mac;
     637    mac.au8[0] = 0x52;
     638    mac.au8[1] = 0x54;
     639    mac.au8[2] = 0;
     640    mac.au8[3] = 0x12;
     641    mac.au8[4] = 0x35;
     642    mac.au8[5] = 0;
     643    setMacAddress(mac);
     644
     645    RTNETADDRIPV4 address;
     646    address.u     = RT_MAKE_U32_FROM_U8( 10,  0,  2,  2); // NB: big-endian
     647    setIpv4Address(address);
     648   
     649    address.u     = RT_H2N_U32_C(0xffffff00);
     650    setIpv4Netmask(address);
    795651
    796652    fDontLoadRulesOnStartup = false;
    797653
    798654    for(unsigned int i = 0; i < RT_ELEMENTS(g_aGetOptDef); ++i)
    799         m_vecOptionDefs.push_back(&g_aGetOptDef[i]);
    800 
    801     m_enmTrunkType = kIntNetTrunkType_SrvNat;
     655        addCommandLineOption(&g_aGetOptDef[i]);
    802656
    803657    LogFlowFuncLeave();
     
    898752    AssertRCReturn(rc, rc);
    899753
    900     hrc = virtualbox->FindNATNetworkByName(com::Bstr(m_Network.c_str()).raw(),
     754    std::string networkName = getNetwork();
     755    hrc = virtualbox->FindNATNetworkByName(com::Bstr(networkName.c_str()).raw(),
    901756                                                  m_net.asOutParam());
    902757    AssertComRCReturn(hrc, VERR_NOT_FOUND);
     
    955810
    956811
    957     com::Bstr bstrSourceIp4Key = com::BstrFmt("NAT/%s/SourceIp4",m_Network.c_str());
     812    com::Bstr bstrSourceIp4Key = com::BstrFmt("NAT/%s/SourceIp4", networkName.c_str());
    958813    com::Bstr bstrSourceIpX;
    959814    hrc = virtualbox->GetExtraData(bstrSourceIp4Key.raw(), bstrSourceIpX.asOutParam());
     
    11691024    }
    11701025    return VERR_NOT_FOUND;
     1026}
     1027
     1028
     1029int VBoxNetLwipNAT::processFrame(void *pvFrame, size_t cbFrame)
     1030{
     1031    AssertReturn(pvFrame && cbFrame, VERR_INVALID_PARAMETER);
     1032
     1033    struct  pbuf *pPbufHdr, *pPbuf;
     1034    pPbufHdr = pPbuf = pbuf_alloc(PBUF_RAW, cbFrame, PBUF_POOL);
     1035
     1036    AssertMsgReturn(pPbuf, ("NAT: Can't allocate send buffer cbFrame=%u\n", cbFrame), VERR_INTERNAL_ERROR);
     1037    AssertReturn(pPbufHdr->tot_len == cbFrame, VERR_INTERNAL_ERROR);
     1038                   
     1039    uint8_t *pu8Frame = (uint8_t *)pvFrame;
     1040    while(pPbuf)
     1041    {
     1042        memcpy(pPbuf->payload, pu8Frame, pPbuf->len);
     1043        pu8Frame += pPbuf->len;
     1044        pPbuf = pPbuf->next;
     1045    }
     1046
     1047    m_LwipNetIf.input(pPbufHdr, &m_LwipNetIf);
     1048   
     1049    return VINF_SUCCESS;
     1050}
     1051
     1052
     1053int VBoxNetLwipNAT::processGSO(PCPDMNETWORKGSO pGso, size_t cbFrame)
     1054{
     1055    if (!PDMNetGsoIsValid(pGso, cbFrame,
     1056                          cbFrame - sizeof(PDMNETWORKGSO)))
     1057        return VERR_INVALID_PARAMETER;
     1058   
     1059    cbFrame -= sizeof(PDMNETWORKGSO);
     1060    uint8_t         abHdrScratch[256];
     1061    uint32_t const  cSegs = PDMNetGsoCalcSegmentCount(pGso,
     1062                                                      cbFrame);
     1063    for (size_t iSeg = 0; iSeg < cSegs; iSeg++)
     1064    {
     1065        uint32_t cbSegFrame;
     1066        void    *pvSegFrame =
     1067          PDMNetGsoCarveSegmentQD(pGso,
     1068                                  (uint8_t *)(pGso + 1),
     1069                                  cbFrame,
     1070                                  abHdrScratch,
     1071                                  iSeg,
     1072                                  cSegs,
     1073                                  &cbSegFrame);
     1074
     1075        struct pbuf *pPbuf = pbuf_alloc(PBUF_RAW, cbSegFrame, PBUF_POOL);
     1076
     1077        AssertMsgReturn(pPbuf, ("NAT: Can't allocate send buffer cbFrame=%u\n", cbSegFrame), VERR_INTERNAL_ERROR);
     1078        AssertReturn(!pPbuf->next && pPbuf->len == cbSegFrame, VERR_INTERNAL_ERROR);
     1079
     1080        memcpy(pPbuf->payload, pvSegFrame, cbSegFrame);
     1081        m_LwipNetIf.input(pPbuf, &g_pLwipNat->m_LwipNetIf);
     1082    }
     1083
     1084    return VINF_SUCCESS;
    11711085}
    11721086
  • trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp

    r49558 r49735  
    7171*   Structures and Typedefs                                                    *
    7272*******************************************************************************/
     73struct VBoxNetBaseService::Data
     74{
     75    Data(const std::string& aName, const std::string& aNetworkName):
     76      m_Name(aName),
     77      m_Network(aNetworkName),
     78      m_enmTrunkType(kIntNetTrunkType_WhateverNone),
     79      m_pSession(NIL_RTR0PTR),
     80      m_cbSendBuf(128 * _1K),
     81      m_cbRecvBuf(256 * _1K),
     82      m_hIf(INTNET_HANDLE_INVALID),
     83      m_pIfBuf(NULL),
     84      m_cVerbosity(0),
     85      m_fNeedMain(false)
     86    {
     87        int rc = RTCritSectInit(&m_csThis);
     88        AssertRC(rc);
     89    };
     90
     91    std::string         m_Name;
     92    std::string         m_Network;
     93    std::string         m_TrunkName;
     94    INTNETTRUNKTYPE     m_enmTrunkType;
     95
     96    RTMAC               m_MacAddress;
     97    RTNETADDRIPV4       m_Ipv4Address;
     98    RTNETADDRIPV4       m_Ipv4Netmask;
     99
     100    PSUPDRVSESSION      m_pSession;
     101    uint32_t            m_cbSendBuf;
     102    uint32_t            m_cbRecvBuf;
     103    INTNETIFHANDLE      m_hIf;          /**< The handle to the network interface. */
     104    PINTNETBUF          m_pIfBuf;       /**< Interface buffer. */
     105
     106    std::vector<PRTGETOPTDEF> m_vecOptionDefs;
     107
     108    int32_t             m_cVerbosity;
     109
     110    /* cs for syncing */
     111    RTCRITSECT          m_csThis;
     112
     113    /* Controls whether service will connect SVC for runtime needs */
     114    bool                m_fNeedMain;
     115};
    73116
    74117/*******************************************************************************
     
    90133
    91134
    92 VBoxNetBaseService::VBoxNetBaseService()
    93 {
    94     int rc = RTCritSectInit(&m_csThis);
    95     AssertRC(rc);
    96     /* numbers from DrvIntNet */
    97     m_cbSendBuf             = 128 * _1K;
    98     m_cbRecvBuf             = 256 * _1K;
    99     m_hIf                   = INTNET_HANDLE_INVALID;
    100     m_pIfBuf                = NULL;
    101 
    102     m_cVerbosity            = 0;
    103     m_Name                  = "VBoxNetNAT";
    104     m_Network               = "intnet";
    105     m_fNeedMain             = false;
     135VBoxNetBaseService::VBoxNetBaseService(const std::string& aName, const std::string& aNetworkName):m(NULL)
     136{
     137    m = new VBoxNetBaseService::Data(aName, aNetworkName);
    106138
    107139    for(unsigned int i = 0; i < RT_ELEMENTS(g_aGetOptDef); ++i)
    108         m_vecOptionDefs.push_back(&g_aGetOptDef[i]);
     140        m->m_vecOptionDefs.push_back(&g_aGetOptDef[i]);
    109141}
    110142
     
    115147     * Close the interface connection.
    116148     */
    117     if (m_hIf != INTNET_HANDLE_INVALID)
    118     {
    119         INTNETIFCLOSEREQ CloseReq;
    120         CloseReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    121         CloseReq.Hdr.cbReq = sizeof(CloseReq);
    122         CloseReq.pSession = m_pSession;
    123         CloseReq.hIf = m_hIf;
    124         m_hIf = INTNET_HANDLE_INVALID;
    125         int rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_RTCPUID, VMMR0_DO_INTNET_IF_CLOSE, 0, &CloseReq.Hdr);
    126         AssertRC(rc);
    127     }
    128 
    129     if (m_pSession)
    130     {
    131         SUPR3Term(false /*fForced*/);
    132         m_pSession = NIL_RTR0PTR;
    133     }
    134     RTCritSectDelete(&m_csThis);
     149    if (m != NULL)
     150    {
     151        if (m->m_hIf != INTNET_HANDLE_INVALID)
     152        {
     153            INTNETIFCLOSEREQ CloseReq;
     154            CloseReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     155            CloseReq.Hdr.cbReq = sizeof(CloseReq);
     156            CloseReq.pSession = m->m_pSession;
     157            CloseReq.hIf = m->m_hIf;
     158            m->m_hIf = INTNET_HANDLE_INVALID;
     159            int rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_RTCPUID, VMMR0_DO_INTNET_IF_CLOSE, 0, &CloseReq.Hdr);
     160            AssertRC(rc);
     161        }
     162
     163        if (m->m_pSession != NIL_RTR0PTR)
     164        {
     165            SUPR3Term(false /*fForced*/);
     166            m->m_pSession = NIL_RTR0PTR;
     167        }
     168
     169        RTCritSectDelete(&m->m_csThis);
     170       
     171        delete m;
     172        m = NULL;
     173    }       
    135174}
    136175
     
    150189}
    151190
     191
     192bool VBoxNetBaseService::isMainNeeded() const
     193{
     194    return m->m_fNeedMain;
     195}
    152196
    153197/**
     
    164208    RTGETOPTSTATE State;
    165209    PRTGETOPTDEF paOptionArray = getOptionsPtr();
    166     int rc = RTGetOptInit(&State, argc, argv, paOptionArray, m_vecOptionDefs.size(), 0, 0 /*fFlags*/);
     210    int rc = RTGetOptInit(&State, argc, argv, paOptionArray, m->m_vecOptionDefs.size(), 0, 0 /*fFlags*/);
    167211    AssertRCReturn(rc, 49);
    168212#if 0
     
    181225        {
    182226            case 'N': // --name
    183                 m_Name = Val.psz;
     227                m->m_Name = Val.psz;
    184228                break;
    185229
    186230            case 'n': // --network
    187                 m_Network = Val.psz;
     231                m->m_Network = Val.psz;
    188232                break;
    189233
    190234            case 't': //--trunk-name
    191                 m_TrunkName = Val.psz;
     235                m->m_TrunkName = Val.psz;
    192236                break;
    193237
    194238            case 'T': //--trunk-type
    195239                if (!strcmp(Val.psz, "none"))
    196                     m_enmTrunkType = kIntNetTrunkType_None;
     240                    m->m_enmTrunkType = kIntNetTrunkType_None;
    197241                else if (!strcmp(Val.psz, "whatever"))
    198                     m_enmTrunkType = kIntNetTrunkType_WhateverNone;
     242                    m->m_enmTrunkType = kIntNetTrunkType_WhateverNone;
    199243                else if (!strcmp(Val.psz, "netflt"))
    200                     m_enmTrunkType = kIntNetTrunkType_NetFlt;
     244                    m->m_enmTrunkType = kIntNetTrunkType_NetFlt;
    201245                else if (!strcmp(Val.psz, "netadp"))
    202                     m_enmTrunkType = kIntNetTrunkType_NetAdp;
     246                    m->m_enmTrunkType = kIntNetTrunkType_NetAdp;
    203247                else if (!strcmp(Val.psz, "srvnat"))
    204                     m_enmTrunkType = kIntNetTrunkType_SrvNat;
     248                    m->m_enmTrunkType = kIntNetTrunkType_SrvNat;
    205249                else
    206250                {
     
    211255
    212256            case 'a': // --mac-address
    213                 m_MacAddress = Val.MacAddr;
     257                m->m_MacAddress = Val.MacAddr;
    214258                break;
    215259
    216260            case 'i': // --ip-address
    217                 m_Ipv4Address = Val.IPv4Addr;
     261                m->m_Ipv4Address = Val.IPv4Addr;
    218262                break;
    219263
    220264            case 'm': // --netmask
    221                 m_Ipv4Netmask = Val.IPv4Addr;
     265                m->m_Ipv4Netmask = Val.IPv4Addr;
    222266                break;
    223267
    224268            case 'v': // --verbose
    225                 m_cVerbosity++;
     269                m->m_cVerbosity++;
    226270                break;
    227271
     
    231275
    232276            case 'M': // --need-main
    233                 m_fNeedMain = true;
     277                m->m_fNeedMain = true;
    234278                break;
    235279
     
    246290                         RTBldCfgRevision(),
    247291                         RTProcShortName());
    248                 for (unsigned int i = 0; i < m_vecOptionDefs.size(); i++)
    249                     RTPrintf("    -%c, %s\n", m_vecOptionDefs[i]->iShort, m_vecOptionDefs[i]->pszLong);
     292                for (unsigned int i = 0; i < m->m_vecOptionDefs.size(); i++)
     293                    RTPrintf("    -%c, %s\n", m->m_vecOptionDefs[i]->iShort, m->m_vecOptionDefs[i]->pszLong);
    250294                usage(); /* to print Service Specific usage */
    251295                return 1;
     
    272316     * Open the session, load ring-0 and issue the request.
    273317     */
    274     int rc = SUPR3Init(&m_pSession);
     318    int rc = SUPR3Init(&m->m_pSession);
    275319    if (RT_FAILURE(rc))
    276320    {
    277         m_pSession = NIL_RTR0PTR;
     321        m->m_pSession = NIL_RTR0PTR;
    278322        LogRel(("VBoxNetBaseService: SUPR3Init -> %Rrc\n", rc));
    279323        return rc;
     
    302346    OpenReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    303347    OpenReq.Hdr.cbReq = sizeof(OpenReq);
    304     OpenReq.pSession = m_pSession;
    305     strncpy(OpenReq.szNetwork, m_Network.c_str(), sizeof(OpenReq.szNetwork));
     348    OpenReq.pSession = m->m_pSession;
     349    strncpy(OpenReq.szNetwork, m->m_Network.c_str(), sizeof(OpenReq.szNetwork));
    306350    OpenReq.szNetwork[sizeof(OpenReq.szNetwork) - 1] = '\0';
    307     strncpy(OpenReq.szTrunk, m_TrunkName.c_str(), sizeof(OpenReq.szTrunk));
     351    strncpy(OpenReq.szTrunk, m->m_TrunkName.c_str(), sizeof(OpenReq.szTrunk));
    308352    OpenReq.szTrunk[sizeof(OpenReq.szTrunk) - 1] = '\0';
    309     OpenReq.enmTrunkType = m_enmTrunkType;
     353    OpenReq.enmTrunkType = m->m_enmTrunkType;
    310354    OpenReq.fFlags = 0; /** @todo check this */
    311     OpenReq.cbSend = m_cbSendBuf;
    312     OpenReq.cbRecv = m_cbRecvBuf;
     355    OpenReq.cbSend = m->m_cbSendBuf;
     356    OpenReq.cbRecv = m->m_cbRecvBuf;
    313357    OpenReq.hIf = INTNET_HANDLE_INVALID;
    314358
     
    323367        return rc;
    324368    }
    325     m_hIf = OpenReq.hIf;
    326     Log2(("successfully opened/created \"%s\" - hIf=%#x\n", OpenReq.szNetwork, m_hIf));
     369    m->m_hIf = OpenReq.hIf;
     370    Log2(("successfully opened/created \"%s\" - hIf=%#x\n", OpenReq.szNetwork, m->m_hIf));
    327371
    328372    /*
     
    332376    GetBufferPtrsReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    333377    GetBufferPtrsReq.Hdr.cbReq = sizeof(GetBufferPtrsReq);
    334     GetBufferPtrsReq.pSession = m_pSession;
    335     GetBufferPtrsReq.hIf = m_hIf;
     378    GetBufferPtrsReq.pSession = m->m_pSession;
     379    GetBufferPtrsReq.hIf = m->m_hIf;
    336380    GetBufferPtrsReq.pRing3Buf = NULL;
    337381    GetBufferPtrsReq.pRing0Buf = NIL_RTR0PTR;
     
    345389    Log2(("pBuf=%p cbBuf=%d cbSend=%d cbRecv=%d\n",
    346390               pBuf, pBuf->cbBuf, pBuf->cbSend, pBuf->cbRecv));
    347     m_pIfBuf = pBuf;
     391    m->m_pIfBuf = pBuf;
    348392
    349393    /*
     
    353397    ActiveReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    354398    ActiveReq.Hdr.cbReq = sizeof(ActiveReq);
    355     ActiveReq.pSession = m_pSession;
    356     ActiveReq.hIf = m_hIf;
     399    ActiveReq.pSession = m->m_pSession;
     400    ActiveReq.hIf = m->m_hIf;
    357401    ActiveReq.fActive = true;
    358402    rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_SET_ACTIVE, 0, &ActiveReq.Hdr);
     
    370414void VBoxNetBaseService::shutdown(void)
    371415{
     416}
     417
     418
     419int VBoxNetBaseService::syncEnter()
     420{
     421    return RTCritSectEnter(&m->m_csThis);
     422}
     423
     424
     425int VBoxNetBaseService::syncLeave()
     426{
     427    return RTCritSectLeave(&m->m_csThis);
    372428}
    373429
     
    380436    WaitReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    381437    WaitReq.Hdr.cbReq = sizeof(WaitReq);
    382     WaitReq.pSession = m_pSession;
    383     WaitReq.hIf = m_hIf;
     438    WaitReq.pSession = m->m_pSession;
     439    WaitReq.hIf = m->m_hIf;
    384440    WaitReq.cMillies = cMillis;
    385441
     
    392448int VBoxNetBaseService::sendBufferOnWire(PCINTNETSEG pcSg, int cSg, size_t cbFrame)
    393449{
    394     int rc = VINF_SUCCESS;
    395450    PINTNETHDR pHdr = NULL;
    396451    uint8_t *pu8Frame = NULL;
     452
     453    /* Allocate frame */
     454    int rc = IntNetRingAllocateFrame(&m->m_pIfBuf->Send, cbFrame, &pHdr, (void **)&pu8Frame);
     455    AssertRCReturn(rc, rc);
     456
     457    /* Now we fill pvFrame with S/G above */
    397458    int offFrame = 0;
    398     int idxSg = 0;
    399     /* Allocate frame */
    400     rc = IntNetRingAllocateFrame(&m_pIfBuf->Send, cbFrame, &pHdr, (void **)&pu8Frame);
    401     AssertRCReturn(rc, rc);
    402     /* Now we fill pvFrame with S/G above */
    403     for (idxSg = 0; idxSg < cSg; ++idxSg)
     459    for (int idxSg = 0; idxSg < cSg; ++idxSg)
    404460    {
    405461        memcpy(&pu8Frame[offFrame], pcSg[idxSg].pv, pcSg[idxSg].cb);
    406462        offFrame+=pcSg[idxSg].cb;
    407463    }
     464
    408465    /* Commit */
    409     IntNetRingCommitFrame(&m_pIfBuf->Send, pHdr);
     466    IntNetRingCommitFrameEx(&m->m_pIfBuf->Send, pHdr, cbFrame);
    410467
    411468    LogFlowFuncLeaveRC(rc);
    412469    return rc;
    413470}
     471
    414472/**
    415473 * forcible ask for send packet on the "wire"
     
    421479    SendReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    422480    SendReq.Hdr.cbReq    = sizeof(SendReq);
    423     SendReq.pSession     = m_pSession;
    424     SendReq.hIf          = m_hIf;
     481    SendReq.pSession     = m->m_pSession;
     482    SendReq.hIf          = m->m_hIf;
    425483    rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_SEND, 0, &SendReq.Hdr);
    426484    AssertRCReturnVoid(rc);
    427485    LogFlowFuncLeave();
    428486
     487}
     488
     489
     490int VBoxNetBaseService::hlpUDPBroadcast(unsigned uSrcPort, unsigned uDstPort,
     491                                         void const *pvData, size_t cbData) const
     492{
     493    return VBoxNetUDPBroadcast(m->m_pSession, m->m_hIf, m->m_pIfBuf,
     494                        m->m_Ipv4Address, &m->m_MacAddress, uSrcPort,
     495                        uDstPort, pvData, cbData);
     496
     497}
     498
     499
     500const std::string VBoxNetBaseService::getName() const
     501{
     502    return m->m_Name;
     503}
     504
     505
     506void VBoxNetBaseService::setName(const std::string& aName)
     507{
     508    m->m_Name = aName;
     509}
     510
     511
     512const std::string VBoxNetBaseService::getNetwork() const
     513{
     514    return m->m_Network;
     515}
     516
     517
     518void VBoxNetBaseService::setNetwork(const std::string& aNetwork)
     519{
     520    m->m_Network = aNetwork;
     521}
     522
     523
     524const RTMAC VBoxNetBaseService::getMacAddress() const
     525{
     526    return m->m_MacAddress;
     527}
     528
     529
     530void VBoxNetBaseService::setMacAddress(const RTMAC& aMac)
     531{
     532    m->m_MacAddress = aMac;
     533}
     534
     535
     536const RTNETADDRIPV4 VBoxNetBaseService::getIpv4Address() const
     537{
     538    return m->m_Ipv4Address;
     539}
     540
     541
     542void VBoxNetBaseService::setIpv4Address(const RTNETADDRIPV4& aAddress)
     543{
     544    m->m_Ipv4Address = aAddress;
     545}
     546
     547
     548const RTNETADDRIPV4 VBoxNetBaseService::getIpv4Netmask() const
     549{
     550    return m->m_Ipv4Netmask;
     551}
     552
     553
     554void VBoxNetBaseService::setIpv4Netmask(const RTNETADDRIPV4& aNetmask)
     555{
     556    m->m_Ipv4Netmask = aNetmask;
     557}
     558
     559
     560uint32_t VBoxNetBaseService::getSendBufSize() const
     561{
     562    return m->m_cbSendBuf;
     563}
     564
     565
     566void VBoxNetBaseService::setSendBufSize(uint32_t cbBuf)
     567{
     568    m->m_cbSendBuf = cbBuf;
     569}
     570
     571
     572uint32_t VBoxNetBaseService::getRecvBufSize() const
     573{
     574    return m->m_cbRecvBuf;
     575}
     576
     577
     578void VBoxNetBaseService::setRecvBufSize(uint32_t cbBuf)
     579{
     580    m->m_cbRecvBuf = cbBuf;
     581}
     582
     583
     584int32_t VBoxNetBaseService::getVerbosityLevel() const
     585{
     586    return m->m_cVerbosity;
     587}
     588
     589
     590void VBoxNetBaseService::setVerbosityLevel(int32_t aVerbosity)
     591{
     592    m->m_cVerbosity = aVerbosity;
     593}
     594
     595
     596void VBoxNetBaseService::addCommandLineOption(const PRTGETOPTDEF optDef)
     597{
     598    m->m_vecOptionDefs.push_back(optDef);
     599}
     600
     601
     602void VBoxNetBaseService::doReceiveLoop()
     603{
     604    int rc;
     605    /* Well we're ready */
     606    PINTNETRINGBUF  pRingBuf = &m->m_pIfBuf->Recv;
     607
     608    for (;;)
     609    {
     610        /*
     611         * Wait for a packet to become available.
     612         */
     613        /* 2. waiting for request for */
     614        rc = waitForIntNetEvent(2000);
     615        if (RT_FAILURE(rc))
     616        {
     617            if (rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED)
     618            {
     619                /* do we want interrupt anyone ??? */
     620                continue;
     621            }
     622            LogRel(("VBoxNetNAT: waitForIntNetEvent returned %Rrc\n", rc));
     623            AssertRCReturnVoid(rc);
     624        }
     625
     626        /*
     627         * Process the receive buffer.
     628         */
     629        PCINTNETHDR pHdr;
     630
     631        while ((pHdr = IntNetRingGetNextFrameToRead(pRingBuf)) != NULL)
     632        {
     633            uint8_t const u8Type = pHdr->u8Type;
     634            size_t         cbFrame = pHdr->cbFrame;
     635            switch (u8Type)
     636            {
     637
     638                case INTNETHDR_TYPE_FRAME:
     639                    {
     640                        void *pvFrame = IntNetHdrGetFramePtr(pHdr, m->m_pIfBuf);
     641                        rc = processFrame(pvFrame, cbFrame);
     642                        if (RT_FAILURE(rc) && rc == VERR_IGNORED)
     643                        {
     644                            /* XXX: UDP + ARP for DHCP */
     645                            VBOXNETUDPHDRS Hdrs;
     646                            size_t  cb;
     647                            void   *pv = VBoxNetUDPMatch(m->m_pIfBuf, RTNETIPV4_PORT_BOOTPS, &m->m_MacAddress,
     648                                                         VBOXNETUDP_MATCH_UNICAST | VBOXNETUDP_MATCH_BROADCAST
     649                                                         | VBOXNETUDP_MATCH_CHECKSUM
     650                                                         | (m->m_cVerbosity > 2 ? VBOXNETUDP_MATCH_PRINT_STDERR : 0),
     651                                                         &Hdrs, &cb);
     652                            if (pv && cb)
     653                                processUDP(pv, cb);
     654                            else
     655                                VBoxNetArpHandleIt(m->m_pSession, m->m_hIf, m->m_pIfBuf, &m->m_MacAddress, m->m_Ipv4Address);
     656                        }
     657                    }
     658                    break;
     659                case INTNETHDR_TYPE_GSO:
     660                  {
     661                      PCPDMNETWORKGSO pGso = IntNetHdrGetGsoContext(pHdr, m->m_pIfBuf);
     662                      rc = processGSO(pGso, cbFrame);
     663                      if (RT_FAILURE(rc) && rc == VERR_IGNORED)
     664                          break;
     665                  }
     666                  break;
     667                case INTNETHDR_TYPE_PADDING:
     668                    break;
     669                default:
     670                    break;
     671            }
     672            IntNetRingSkipFrame(&m->m_pIfBuf->Recv);
     673
     674        } /* loop */
     675    }
     676
     677}
     678
     679
     680void VBoxNetBaseService::debugPrint(int32_t iMinLevel, bool fMsg, const char *pszFmt, ...) const
     681{
     682    if (iMinLevel <= m->m_cVerbosity)
     683    {
     684        va_list va;
     685        va_start(va, pszFmt);
     686        debugPrintV(iMinLevel, fMsg, pszFmt, va);
     687        va_end(va);
     688    }
    429689}
    430690
     
    440700void VBoxNetBaseService::debugPrintV(int iMinLevel, bool fMsg, const char *pszFmt, va_list va) const
    441701{
    442     if (iMinLevel <= m_cVerbosity)
     702    if (iMinLevel <= m->m_cVerbosity)
    443703    {
    444704        va_list vaCopy;                 /* This dude is *very* special, thus the copy. */
     
    458718{
    459719    PRTGETOPTDEF pOptArray = NULL;
    460     pOptArray = (PRTGETOPTDEF)RTMemAlloc(sizeof(RTGETOPTDEF) * m_vecOptionDefs.size());
     720    pOptArray = (PRTGETOPTDEF)RTMemAlloc(sizeof(RTGETOPTDEF) * m->m_vecOptionDefs.size());
    461721    if (!pOptArray)
    462722        return NULL;
    463     for (unsigned int i = 0; i < m_vecOptionDefs.size(); ++i)
    464     {
    465         PRTGETOPTDEF pOpt = m_vecOptionDefs[i];
    466         memcpy(&pOptArray[i], m_vecOptionDefs[i], sizeof(RTGETOPTDEF));
     723    for (unsigned int i = 0; i < m->m_vecOptionDefs.size(); ++i)
     724    {
     725        PRTGETOPTDEF pOpt = m->m_vecOptionDefs[i];
     726        memcpy(&pOptArray[i], m->m_vecOptionDefs[i], sizeof(RTGETOPTDEF));
    467727    }
    468728    return pOptArray;
  • trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h

    r49560 r49735  
    2020
    2121#include <iprt/critsect.h>
    22 class VBoxNetBaseService
     22
     23
     24class VBoxNetHlpUDPService
    2325{
    2426public:
    25     VBoxNetBaseService();
     27virtual int                 hlpUDPBroadcast(unsigned uSrcPort, unsigned uDstPort,
     28                                        void const *pvData, size_t cbData) const = 0;
     29};
     30
     31
     32# ifndef BASE_SERVICES_ONLY
     33class VBoxNetBaseService: public VBoxNetHlpUDPService
     34{
     35public:
     36    VBoxNetBaseService(const std::string& aName, const std::string& aNetworkName);
    2637    virtual ~VBoxNetBaseService();
    2738    int                 parseArgs(int argc, char **argv);
    2839    int                 tryGoOnline(void);
    2940    void                shutdown(void);
    30     int                 syncEnter() { return RTCritSectEnter(&this->m_csThis);}
    31     int                 syncLeave() { return RTCritSectLeave(&this->m_csThis);}
     41    int                 syncEnter();
     42    int                 syncLeave();
    3243    int                 waitForIntNetEvent(int cMillis);
    3344    int                 sendBufferOnWire(PCINTNETSEG pSg, int cSg, size_t cbBuffer);
    3445    void                flushWire();
    3546
     47    virtual int         hlpUDPBroadcast(unsigned uSrcPort, unsigned uDstPort,
     48                                        void const *pvData, size_t cbData) const;
    3649    virtual void        usage(void) = 0;
    3750    virtual int         run(void) = 0;
    3851    virtual int         parseOpt(int rc, const RTGETOPTUNION& getOptVal) = 0;
     52    virtual int         processFrame(void *, size_t) = 0;
     53    virtual int         processGSO(PCPDMNETWORKGSO, size_t) = 0;
     54    virtual int         processUDP(void *, size_t) = 0;
     55
    3956
    4057    virtual int         init(void);
    41     virtual bool        isMainNeeded() const { return m_fNeedMain; }
    42     /* VirtualBox instance */
    43     ComPtr<IVirtualBox> virtualbox;
     58    virtual bool        isMainNeeded() const;
    4459
    4560protected:
     61    const std::string getName() const;
     62    void setName(const std::string&);
     63
     64    const std::string getNetwork() const;
     65    void setNetwork(const std::string&);
     66
     67    const RTMAC getMacAddress() const;
     68    void setMacAddress(const RTMAC&);
     69
     70    const RTNETADDRIPV4 getIpv4Address() const;
     71    void setIpv4Address(const RTNETADDRIPV4&);
     72
     73    const RTNETADDRIPV4 getIpv4Netmask() const;
     74    void setIpv4Netmask(const RTNETADDRIPV4&);
     75
     76    uint32_t getSendBufSize() const;
     77    void setSendBufSize(uint32_t);
     78
     79    uint32_t getRecvBufSize() const;
     80    void setRecvBufSize(uint32_t);
     81
     82    int32_t getVerbosityLevel() const;
     83    void setVerbosityLevel(int32_t);
     84
     85    void addCommandLineOption(const PRTGETOPTDEF);
     86
    4687    /**
    4788     * Print debug message depending on the m_cVerbosity level.
     
    5293     * @param   ...             Optional arguments.
    5394     */
    54     void debugPrint(int32_t iMinLevel, bool fMsg, const char *pszFmt, ...) const
    55     {
    56         if (iMinLevel <= m_cVerbosity)
    57         {
    58             va_list va;
    59             va_start(va, pszFmt);
    60             debugPrintV(iMinLevel, fMsg, pszFmt, va);
    61             va_end(va);
    62         }
    63     }
    64 
     95    void debugPrint(int32_t iMinLevel, bool fMsg, const char *pszFmt, ...) const;
    6596    virtual void debugPrintV(int32_t iMinLevel, bool fMsg, const char *pszFmt, va_list va) const;
    6697
    67     /** @name The server configuration data members.
    68      * @{ */
    69     std::string         m_Name;
    70     std::string         m_Network;
    71     std::string         m_TrunkName;
    72     INTNETTRUNKTYPE     m_enmTrunkType;
    73     RTMAC               m_MacAddress;
    74     RTNETADDRIPV4       m_Ipv4Address;
    75     RTNETADDRIPV4       m_Ipv4Netmask;
    76     /** @} */
    77     /** @name The network interface
    78      * @{ */
    79     PSUPDRVSESSION      m_pSession;
    80     uint32_t            m_cbSendBuf;
    81     uint32_t            m_cbRecvBuf;
    82     INTNETIFHANDLE      m_hIf;          /**< The handle to the network interface. */
    83     PINTNETBUF          m_pIfBuf;       /**< Interface buffer. */
    84     std::vector<PRTGETOPTDEF> m_vecOptionDefs;
    85     /** @} */
    86     /** @name Debug stuff
    87      * @{  */
    88     int32_t             m_cVerbosity;
     98    void doReceiveLoop();
     99   
     100
     101protected:
     102    /* VirtualBox instance */
     103    ComPtr<IVirtualBox> virtualbox;
     104
     105private:
     106    struct Data;
     107    Data *m;
     108
    89109private:
    90110    PRTGETOPTDEF getOptionsPtr();
    91 
    92     /* cs for syncing */
    93     RTCRITSECT          m_csThis;
    94     /* Controls whether service will connect SVC for runtime needs */
    95     bool                m_fNeedMain;
    96 
    97     /** @} */
    98111};
     112# endif
    99113#endif
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