Changeset 49735 in vbox
- Timestamp:
- Nov 30, 2013 2:08:42 AM (11 years ago)
- Location:
- trunk/src/VBox/NetworkServices
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/NetworkServices/DHCP/Config.cpp
r49569 r49735 6 6 7 7 #include <iprt/asm.h> 8 #include <iprt/getopt.h> 8 9 #include <iprt/net.h> 9 10 #include <iprt/time.h> … … 19 20 #include <iprt/cpp/xml.h> 20 21 22 #define BASE_SERVICES_ONLY 23 #include "../NetLib/VBoxNetBaseService.h" 21 24 #include "../NetLib/VBoxNetLib.h" 22 25 #include "../NetLib/shared_ptr.h" … … 666 669 cbBooPReplyMsg = 0; 667 670 668 m_pSession = NIL_RTR0PTR;669 m_pIfBuf = NULL;670 671 m_OurAddress.u = 0; 671 672 m_OurNetmask.u = 0; … … 679 680 int cbBooPReplyMsg; 680 681 681 /* XXX: artifacts should be hidden or removed from here. */682 PSUPDRVSESSION m_pSession;683 INTNETIFHANDLE m_hIf;684 PINTNETBUF m_pIfBuf;685 686 682 RTNETADDRIPV4 m_OurAddress; 687 683 RTNETADDRIPV4 m_OurNetmask; 688 684 RTMAC m_OurMac; 685 const VBoxNetHlpUDPService *m_service; 689 686 }; 690 687 … … 748 745 749 746 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 } 747 void NetworkManager::setService(const VBoxNetHlpUDPService *srv) 748 { 749 m->m_service = srv; 750 } 751 766 752 /** 767 753 * Network manager creates DHCPOFFER datagramm … … 982 968 else 983 969 #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); 992 974 993 975 AssertRCReturn(rc,rc); -
trunk/src/VBox/NetworkServices/DHCP/Config.h
r49568 r49735 503 503 void setOurMac(const RTMAC& aMac); 504 504 505 void setSession(PSUPDRVSESSION);506 void setInterface(INTNETIFHANDLE);507 void setRingBuffer(PINTNETBUF);508 509 505 bool handleDhcpReqDiscover(PCRTNETBOOTP pDhcpMsg, size_t cb); 510 506 bool handleDhcpReqRequest(PCRTNETBOOTP pDhcpMsg, size_t cb); 511 507 bool handleDhcpReqDecline(PCRTNETBOOTP pDhcpMsg, size_t cb); 512 508 bool handleDhcpReqRelease(PCRTNETBOOTP pDhcpMsg, size_t cb); 509 510 void setService(const VBoxNetHlpUDPService *); 513 511 private: 514 512 NetworkManager(); -
trunk/src/VBox/NetworkServices/DHCP/NetworkManagerDhcp.cpp
r49566 r49735 21 21 #include <iprt/asm.h> 22 22 #include <iprt/cdefs.h> 23 #include <iprt/getopt.h> 23 24 #include <iprt/net.h> 24 25 #include <iprt/param.h> … … 38 39 #include <VBox/intnet.h> 39 40 41 #define BASE_SERVICES_ONLY 42 #include "../NetLib/VBoxNetBaseService.h" 40 43 #include "Config.h" 41 44 #include "ClientDataInt.h" -
trunk/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp
r49564 r49735 95 95 void usage(void) { /* XXX: document options */ }; 96 96 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 97 101 98 102 protected: … … 169 173 * Construct a DHCP server with a default configuration. 170 174 */ 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; 175 VBoxNetDhcp::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 192 194 m_uCurMsgType = UINT8_MAX; 193 195 m_cbCurMsg = 0; … … 198 200 199 201 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]); 221 203 } 222 204 … … 282 264 NetworkManager *netManager = NetworkManager::getNetworkManager(); 283 265 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); 287 270 288 271 if (isMainNeeded()) … … 304 287 int VBoxNetDhcp::run(void) 305 288 { 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(); 376 290 return 0; 291 } 292 293 294 int 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; 377 314 } 378 315 … … 495 432 CmdParameterIterator it; 496 433 434 RTNETADDRIPV4 address = getIpv4Address(); 435 RTNETADDRIPV4 netmask = getIpv4Netmask(); 497 436 RTNETADDRIPV4 networkId; 498 networkId.u = m_Ipv4Address.u & m_Ipv4Netmask.u; 499 RTNETADDRIPV4 netmask = m_Ipv4Netmask; 437 networkId.u = address.u & netmask.u; 500 438 501 439 RTNETADDRIPV4 UpperAddress; … … 524 462 confManager->addNetwork(unconst(g_RootConfig), 525 463 networkId, 526 m_Ipv4Netmask,464 netmask, 527 465 LowerAddress, 528 466 UpperAddress); … … 538 476 */ 539 477 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()); 543 482 AssertComRCReturn(hrc, VERR_INTERNAL_ERROR); 544 483 545 hrc = virtualbox->FindNATNetworkByName(com::Bstr( m_Network.c_str()).raw(),484 hrc = virtualbox->FindNATNetworkByName(com::Bstr(networkName.c_str()).raw(), 546 485 m_NATNetwork.asOutParam()); 547 486 … … 602 541 } 603 542 543 544 RTNETADDRIPV4 address = getIpv4Address(); 545 RTNETADDRIPV4 netmask = getIpv4Netmask(); 604 546 strs.setNull(); 605 547 ComPtr<IHost> host; … … 621 563 if (MapIp4Addr2Off[addr] != 0) 622 564 { 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) 624 566 + MapIp4Addr2Off[addr]); 625 567 } … … 661 603 662 604 RTNETADDRIPV4 networkId; 663 networkId.u = m_Ipv4Address.u & m_Ipv4Netmask.u;605 networkId.u = address.u & netmask.u; 664 606 std::string name = std::string("default"); 665 607 666 608 confManager->addNetwork(unconst(g_RootConfig), 667 609 networkId, 668 m_Ipv4Netmask,610 netmask, 669 611 LowerAddress, 670 612 UpperAddress); … … 673 615 hrc = virtualbox->COMGETTER(HomeFolder)(bstr.asOutParam()); 674 616 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()); 676 618 confManager->loadFromFile(strXmlLeaseFile); 677 619 -
trunk/src/VBox/NetworkServices/NAT/Makefile.kmk
r49713 r49735 45 45 VBoxNetLwipNAT_SOURCES += VBoxNetLwipNAT.cpp \ 46 46 ../NetLib/VBoxNetBaseService.cpp \ 47 ../NetLib/VBoxNetPortForwardString.cpp 47 ../NetLib/VBoxNetPortForwardString.cpp \ 48 ../NetLib/VBoxNetIntIf.cpp \ 49 ../NetLib/VBoxNetUDP.cpp \ 50 ../NetLib/VBoxNetARP.cpp 51 48 52 VBoxNetLwipNAT_LIBS = \ 49 53 $(LIB_RUNTIME) -
trunk/src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp
r49711 r49735 164 164 /* VBoxNetNAT always needs Main */ 165 165 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 166 170 private: 167 171 struct proxy_options m_ProxyOptions; … … 187 191 ComPtr<IHost> m_host; 188 192 ComObjPtr<NATNetworkListenerImpl> m_vboxListener; 193 static INTNETSEG aXmitSeg[64]; 189 194 190 195 STDMETHOD(HandleEvent)(VBoxEventType_T aEventType, IEvent *pEvent); … … 202 207 static err_t netifLinkoutput(netif *pNetif, pbuf *pBuf); 203 208 static int intNetThreadRecv(RTTHREAD, void *); 204 static void vboxNetLwipNATProcessXmit(void);205 209 206 210 VECNATSERVICEPF m_vecPortForwardRule4; … … 213 217 214 218 static VBoxNetLwipNAT *g_pLwipNat; 219 INTNETSEG VBoxNetLwipNAT::aXmitSeg[64]; 215 220 216 221 STDMETHODIMP NATNetworkListener::HandleEvent(VBoxEventType_T aEventType, IEvent *pEvent) … … 411 416 412 417 /* 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; 415 422 416 423 ip_addr LwipIpAddr, LwipIpNetMask, LwipIpNetwork; 417 424 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)); 421 428 422 429 netif *pNetif = netif_add(&g_pLwipNat->m_LwipNetIf /* Lwip Interface */, … … 504 511 505 512 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)); 507 515 508 516 pNat->m_u16Mtu = 1500; // XXX: FIXME … … 561 569 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to initialize COM!"); 562 570 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(); 670 572 /* 3. deinitilization and termination */ 671 573 LogFlowFuncLeaveRC(rc); … … 674 576 675 577 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 692 578 err_t VBoxNetLwipNAT::netifLinkoutput(netif *pNetif, pbuf *pPBuf) 693 579 { 694 int rc = VINF_SUCCESS;695 err_t rcLwip = ERR_OK;696 580 AssertPtrReturn(pNetif, ERR_ARG); 697 581 AssertPtrReturn(pPBuf, ERR_ARG); 698 582 AssertReturn((void *)g_pLwipNat == pNetif->state, ERR_ARG); 583 699 584 LogFlowFunc(("ENTER: pNetif[%c%c%d], pPbuf:%p\n", 700 585 pNetif->name[0], … … 703 588 pPBuf)); 704 589 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); 758 603 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 612 VBoxNetLwipNAT::VBoxNetLwipNAT(SOCKET icmpsock4, SOCKET icmpsock6) : VBoxNetBaseService("VBoxNetNAT", "nat-network") 765 613 { 766 614 LogFlowFuncEnter(); … … 785 633 m_LwipNetIf.name[0] = 'N'; 786 634 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); 795 651 796 652 fDontLoadRulesOnStartup = false; 797 653 798 654 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]); 802 656 803 657 LogFlowFuncLeave(); … … 898 752 AssertRCReturn(rc, rc); 899 753 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(), 901 756 m_net.asOutParam()); 902 757 AssertComRCReturn(hrc, VERR_NOT_FOUND); … … 955 810 956 811 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()); 958 813 com::Bstr bstrSourceIpX; 959 814 hrc = virtualbox->GetExtraData(bstrSourceIp4Key.raw(), bstrSourceIpX.asOutParam()); … … 1169 1024 } 1170 1025 return VERR_NOT_FOUND; 1026 } 1027 1028 1029 int 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 1053 int 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; 1171 1085 } 1172 1086 -
trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
r49558 r49735 71 71 * Structures and Typedefs * 72 72 *******************************************************************************/ 73 struct 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 }; 73 116 74 117 /******************************************************************************* … … 90 133 91 134 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; 135 VBoxNetBaseService::VBoxNetBaseService(const std::string& aName, const std::string& aNetworkName):m(NULL) 136 { 137 m = new VBoxNetBaseService::Data(aName, aNetworkName); 106 138 107 139 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]); 109 141 } 110 142 … … 115 147 * Close the interface connection. 116 148 */ 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 } 135 174 } 136 175 … … 150 189 } 151 190 191 192 bool VBoxNetBaseService::isMainNeeded() const 193 { 194 return m->m_fNeedMain; 195 } 152 196 153 197 /** … … 164 208 RTGETOPTSTATE State; 165 209 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*/); 167 211 AssertRCReturn(rc, 49); 168 212 #if 0 … … 181 225 { 182 226 case 'N': // --name 183 m _Name = Val.psz;227 m->m_Name = Val.psz; 184 228 break; 185 229 186 230 case 'n': // --network 187 m _Network = Val.psz;231 m->m_Network = Val.psz; 188 232 break; 189 233 190 234 case 't': //--trunk-name 191 m _TrunkName = Val.psz;235 m->m_TrunkName = Val.psz; 192 236 break; 193 237 194 238 case 'T': //--trunk-type 195 239 if (!strcmp(Val.psz, "none")) 196 m _enmTrunkType = kIntNetTrunkType_None;240 m->m_enmTrunkType = kIntNetTrunkType_None; 197 241 else if (!strcmp(Val.psz, "whatever")) 198 m _enmTrunkType = kIntNetTrunkType_WhateverNone;242 m->m_enmTrunkType = kIntNetTrunkType_WhateverNone; 199 243 else if (!strcmp(Val.psz, "netflt")) 200 m _enmTrunkType = kIntNetTrunkType_NetFlt;244 m->m_enmTrunkType = kIntNetTrunkType_NetFlt; 201 245 else if (!strcmp(Val.psz, "netadp")) 202 m _enmTrunkType = kIntNetTrunkType_NetAdp;246 m->m_enmTrunkType = kIntNetTrunkType_NetAdp; 203 247 else if (!strcmp(Val.psz, "srvnat")) 204 m _enmTrunkType = kIntNetTrunkType_SrvNat;248 m->m_enmTrunkType = kIntNetTrunkType_SrvNat; 205 249 else 206 250 { … … 211 255 212 256 case 'a': // --mac-address 213 m _MacAddress = Val.MacAddr;257 m->m_MacAddress = Val.MacAddr; 214 258 break; 215 259 216 260 case 'i': // --ip-address 217 m _Ipv4Address = Val.IPv4Addr;261 m->m_Ipv4Address = Val.IPv4Addr; 218 262 break; 219 263 220 264 case 'm': // --netmask 221 m _Ipv4Netmask = Val.IPv4Addr;265 m->m_Ipv4Netmask = Val.IPv4Addr; 222 266 break; 223 267 224 268 case 'v': // --verbose 225 m _cVerbosity++;269 m->m_cVerbosity++; 226 270 break; 227 271 … … 231 275 232 276 case 'M': // --need-main 233 m _fNeedMain = true;277 m->m_fNeedMain = true; 234 278 break; 235 279 … … 246 290 RTBldCfgRevision(), 247 291 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); 250 294 usage(); /* to print Service Specific usage */ 251 295 return 1; … … 272 316 * Open the session, load ring-0 and issue the request. 273 317 */ 274 int rc = SUPR3Init(&m _pSession);318 int rc = SUPR3Init(&m->m_pSession); 275 319 if (RT_FAILURE(rc)) 276 320 { 277 m _pSession = NIL_RTR0PTR;321 m->m_pSession = NIL_RTR0PTR; 278 322 LogRel(("VBoxNetBaseService: SUPR3Init -> %Rrc\n", rc)); 279 323 return rc; … … 302 346 OpenReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 303 347 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)); 306 350 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)); 308 352 OpenReq.szTrunk[sizeof(OpenReq.szTrunk) - 1] = '\0'; 309 OpenReq.enmTrunkType = m _enmTrunkType;353 OpenReq.enmTrunkType = m->m_enmTrunkType; 310 354 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; 313 357 OpenReq.hIf = INTNET_HANDLE_INVALID; 314 358 … … 323 367 return rc; 324 368 } 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)); 327 371 328 372 /* … … 332 376 GetBufferPtrsReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 333 377 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; 336 380 GetBufferPtrsReq.pRing3Buf = NULL; 337 381 GetBufferPtrsReq.pRing0Buf = NIL_RTR0PTR; … … 345 389 Log2(("pBuf=%p cbBuf=%d cbSend=%d cbRecv=%d\n", 346 390 pBuf, pBuf->cbBuf, pBuf->cbSend, pBuf->cbRecv)); 347 m _pIfBuf = pBuf;391 m->m_pIfBuf = pBuf; 348 392 349 393 /* … … 353 397 ActiveReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 354 398 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; 357 401 ActiveReq.fActive = true; 358 402 rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_SET_ACTIVE, 0, &ActiveReq.Hdr); … … 370 414 void VBoxNetBaseService::shutdown(void) 371 415 { 416 } 417 418 419 int VBoxNetBaseService::syncEnter() 420 { 421 return RTCritSectEnter(&m->m_csThis); 422 } 423 424 425 int VBoxNetBaseService::syncLeave() 426 { 427 return RTCritSectLeave(&m->m_csThis); 372 428 } 373 429 … … 380 436 WaitReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 381 437 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; 384 440 WaitReq.cMillies = cMillis; 385 441 … … 392 448 int VBoxNetBaseService::sendBufferOnWire(PCINTNETSEG pcSg, int cSg, size_t cbFrame) 393 449 { 394 int rc = VINF_SUCCESS;395 450 PINTNETHDR pHdr = NULL; 396 451 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 */ 397 458 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) 404 460 { 405 461 memcpy(&pu8Frame[offFrame], pcSg[idxSg].pv, pcSg[idxSg].cb); 406 462 offFrame+=pcSg[idxSg].cb; 407 463 } 464 408 465 /* Commit */ 409 IntNetRingCommitFrame (&m_pIfBuf->Send, pHdr);466 IntNetRingCommitFrameEx(&m->m_pIfBuf->Send, pHdr, cbFrame); 410 467 411 468 LogFlowFuncLeaveRC(rc); 412 469 return rc; 413 470 } 471 414 472 /** 415 473 * forcible ask for send packet on the "wire" … … 421 479 SendReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 422 480 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; 425 483 rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_SEND, 0, &SendReq.Hdr); 426 484 AssertRCReturnVoid(rc); 427 485 LogFlowFuncLeave(); 428 486 487 } 488 489 490 int 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 500 const std::string VBoxNetBaseService::getName() const 501 { 502 return m->m_Name; 503 } 504 505 506 void VBoxNetBaseService::setName(const std::string& aName) 507 { 508 m->m_Name = aName; 509 } 510 511 512 const std::string VBoxNetBaseService::getNetwork() const 513 { 514 return m->m_Network; 515 } 516 517 518 void VBoxNetBaseService::setNetwork(const std::string& aNetwork) 519 { 520 m->m_Network = aNetwork; 521 } 522 523 524 const RTMAC VBoxNetBaseService::getMacAddress() const 525 { 526 return m->m_MacAddress; 527 } 528 529 530 void VBoxNetBaseService::setMacAddress(const RTMAC& aMac) 531 { 532 m->m_MacAddress = aMac; 533 } 534 535 536 const RTNETADDRIPV4 VBoxNetBaseService::getIpv4Address() const 537 { 538 return m->m_Ipv4Address; 539 } 540 541 542 void VBoxNetBaseService::setIpv4Address(const RTNETADDRIPV4& aAddress) 543 { 544 m->m_Ipv4Address = aAddress; 545 } 546 547 548 const RTNETADDRIPV4 VBoxNetBaseService::getIpv4Netmask() const 549 { 550 return m->m_Ipv4Netmask; 551 } 552 553 554 void VBoxNetBaseService::setIpv4Netmask(const RTNETADDRIPV4& aNetmask) 555 { 556 m->m_Ipv4Netmask = aNetmask; 557 } 558 559 560 uint32_t VBoxNetBaseService::getSendBufSize() const 561 { 562 return m->m_cbSendBuf; 563 } 564 565 566 void VBoxNetBaseService::setSendBufSize(uint32_t cbBuf) 567 { 568 m->m_cbSendBuf = cbBuf; 569 } 570 571 572 uint32_t VBoxNetBaseService::getRecvBufSize() const 573 { 574 return m->m_cbRecvBuf; 575 } 576 577 578 void VBoxNetBaseService::setRecvBufSize(uint32_t cbBuf) 579 { 580 m->m_cbRecvBuf = cbBuf; 581 } 582 583 584 int32_t VBoxNetBaseService::getVerbosityLevel() const 585 { 586 return m->m_cVerbosity; 587 } 588 589 590 void VBoxNetBaseService::setVerbosityLevel(int32_t aVerbosity) 591 { 592 m->m_cVerbosity = aVerbosity; 593 } 594 595 596 void VBoxNetBaseService::addCommandLineOption(const PRTGETOPTDEF optDef) 597 { 598 m->m_vecOptionDefs.push_back(optDef); 599 } 600 601 602 void 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 680 void 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 } 429 689 } 430 690 … … 440 700 void VBoxNetBaseService::debugPrintV(int iMinLevel, bool fMsg, const char *pszFmt, va_list va) const 441 701 { 442 if (iMinLevel <= m _cVerbosity)702 if (iMinLevel <= m->m_cVerbosity) 443 703 { 444 704 va_list vaCopy; /* This dude is *very* special, thus the copy. */ … … 458 718 { 459 719 PRTGETOPTDEF pOptArray = NULL; 460 pOptArray = (PRTGETOPTDEF)RTMemAlloc(sizeof(RTGETOPTDEF) * m _vecOptionDefs.size());720 pOptArray = (PRTGETOPTDEF)RTMemAlloc(sizeof(RTGETOPTDEF) * m->m_vecOptionDefs.size()); 461 721 if (!pOptArray) 462 722 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)); 467 727 } 468 728 return pOptArray; -
trunk/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.h
r49560 r49735 20 20 21 21 #include <iprt/critsect.h> 22 class VBoxNetBaseService 22 23 24 class VBoxNetHlpUDPService 23 25 { 24 26 public: 25 VBoxNetBaseService(); 27 virtual int hlpUDPBroadcast(unsigned uSrcPort, unsigned uDstPort, 28 void const *pvData, size_t cbData) const = 0; 29 }; 30 31 32 # ifndef BASE_SERVICES_ONLY 33 class VBoxNetBaseService: public VBoxNetHlpUDPService 34 { 35 public: 36 VBoxNetBaseService(const std::string& aName, const std::string& aNetworkName); 26 37 virtual ~VBoxNetBaseService(); 27 38 int parseArgs(int argc, char **argv); 28 39 int tryGoOnline(void); 29 40 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(); 32 43 int waitForIntNetEvent(int cMillis); 33 44 int sendBufferOnWire(PCINTNETSEG pSg, int cSg, size_t cbBuffer); 34 45 void flushWire(); 35 46 47 virtual int hlpUDPBroadcast(unsigned uSrcPort, unsigned uDstPort, 48 void const *pvData, size_t cbData) const; 36 49 virtual void usage(void) = 0; 37 50 virtual int run(void) = 0; 38 51 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 39 56 40 57 virtual int init(void); 41 virtual bool isMainNeeded() const { return m_fNeedMain; } 42 /* VirtualBox instance */ 43 ComPtr<IVirtualBox> virtualbox; 58 virtual bool isMainNeeded() const; 44 59 45 60 protected: 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 46 87 /** 47 88 * Print debug message depending on the m_cVerbosity level. … … 52 93 * @param ... Optional arguments. 53 94 */ 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; 65 96 virtual void debugPrintV(int32_t iMinLevel, bool fMsg, const char *pszFmt, va_list va) const; 66 97 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 101 protected: 102 /* VirtualBox instance */ 103 ComPtr<IVirtualBox> virtualbox; 104 105 private: 106 struct Data; 107 Data *m; 108 89 109 private: 90 110 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 /** @} */98 111 }; 112 # endif 99 113 #endif
Note:
See TracChangeset
for help on using the changeset viewer.