Changeset 97086 in vbox for trunk/src/VBox/NetworkServices/Dhcpd/VBoxNetDhcpd.cpp
- Timestamp:
- Oct 11, 2022 8:10:32 AM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/NetworkServices/Dhcpd/VBoxNetDhcpd.cpp
r97078 r97086 102 102 { 103 103 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(VBoxNetDhcpd); 104 105 private:106 PRTLOGGER m_pStderrReleaseLogger;107 108 /* intnet plumbing */109 INTNETIFCTX m_hIf;110 PINTNETBUF m_pIfBuf;111 112 /* lwip stack connected to the intnet */113 struct netif m_LwipNetif;114 115 Config *m_Config;116 117 /* listening pcb */118 struct udp_pcb *m_Dhcp4Pcb;119 120 DHCPD m_server;121 122 104 public: 123 105 VBoxNetDhcpd(); … … 127 109 128 110 private: 111 /** The logger instance. */ 112 PRTLOGGER m_pStderrReleaseLogger; 113 /** Internal network interface handle. */ 114 INTNETIFCTX m_hIf; 115 /** lwip stack connected to the intnet */ 116 struct netif m_LwipNetif; 117 /** The DHCP server config. */ 118 Config *m_Config; 119 /** Listening pcb */ 120 struct udp_pcb *m_Dhcp4Pcb; 121 /** DHCP server instance. */ 122 DHCPD m_server; 123 129 124 int logInitStderr(); 130 125 131 126 /* 132 * Boilerplate code.127 * Internal network plumbing. 133 128 */ 134 129 int ifInit(const RTCString &strNetwork, … … 136 131 INTNETTRUNKTYPE enmTrunkType = kIntNetTrunkType_WhateverNone); 137 132 138 int ifProcessInput(); 139 140 void ifPump(); 141 int ifInput(void *pvSegFrame, uint32_t cbSegFrame); 142 133 static DECLCALLBACK(void) ifInput(void *pvUser, void *pvFrame, uint32_t cbFrame); 134 void ifInputWorker(void *pvFrame, uint32_t cbFrame); 143 135 144 136 /* … … 162 154 VBoxNetDhcpd::VBoxNetDhcpd() 163 155 : m_pStderrReleaseLogger(NULL), 164 m_hIf(INTNET_HANDLE_INVALID), 165 m_pIfBuf(NULL), 156 m_hIf(NULL), 166 157 m_LwipNetif(), 167 158 m_Config(NULL), … … 194 185 static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; 195 186 196 PRTLOGGER pLogger;197 int rc;198 199 187 uint32_t fFlags = 0; 200 188 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) … … 202 190 #endif 203 191 204 rc = RTLogCreate(&pLogger, fFlags, 205 "all -sup all.restrict -default.restrict", 206 NULL, /* environment base */ 207 RT_ELEMENTS(s_apszGroups), s_apszGroups, 208 RTLOGDEST_STDERR, NULL); 192 PRTLOGGER pLogger; 193 int rc = RTLogCreate(&pLogger, fFlags, 194 "all -sup all.restrict -default.restrict", 195 NULL, /* environment base */ 196 RT_ELEMENTS(s_apszGroups), s_apszGroups, 197 RTLOGDEST_STDERR, NULL); 209 198 if (RT_FAILURE(rc)) 210 199 { … … 231 220 0 /*fFlags*/); 232 221 if (RT_SUCCESS(rc)) 233 { 234 rc = IntNetR3IfQueryBufferPtr(m_hIf, &m_pIfBuf); 235 if (RT_SUCCESS(rc)) 236 rc = IntNetR3IfSetActive(m_hIf, true /*fActive*/); 237 } 222 rc = IntNetR3IfSetActive(m_hIf, true /*fActive*/); 238 223 239 224 return rc; … … 241 226 242 227 243 /** 244 * Process incoming packages forever. 245 * 246 * @note This function normally never returns, given that the process is 247 * typically just killed when shutting down a network. 248 */ 249 void VBoxNetDhcpd::ifPump() 250 { 251 for (;;) 252 { 253 /* 254 * Wait for input: 255 */ 256 int rc = IntNetR3IfWait(m_hIf, RT_INDEFINITE_WAIT); 257 /* 258 * Process any pending input before we wait again: 259 */ 260 if ( RT_SUCCESS(rc) 261 || rc == VERR_INTERRUPTED 262 || rc == VERR_TIMEOUT /* paranoia */) 263 ifProcessInput(); 264 else 265 { 266 DHCP_LOG_MSG_ERROR(("ifWait failed: %Rrc\n", rc)); 267 return; 268 } 269 } 270 } 271 272 273 int VBoxNetDhcpd::ifProcessInput() 274 { 275 AssertReturn(m_hIf != NULL, VERR_GENERAL_FAILURE); 276 AssertReturn(m_pIfBuf != NULL, VERR_GENERAL_FAILURE); 277 278 PCINTNETHDR pHdr = IntNetRingGetNextFrameToRead(&m_pIfBuf->Recv); 279 while (pHdr) 280 { 281 const uint8_t u8Type = pHdr->u8Type; 282 void *pvSegFrame; 283 uint32_t cbSegFrame; 284 285 if (u8Type == INTNETHDR_TYPE_FRAME) 286 { 287 pvSegFrame = IntNetHdrGetFramePtr(pHdr, m_pIfBuf); 288 cbSegFrame = pHdr->cbFrame; 289 290 ifInput(pvSegFrame, cbSegFrame); 291 } 292 else if (u8Type == INTNETHDR_TYPE_GSO) 293 { 294 size_t cbGso = pHdr->cbFrame; 295 size_t cbFrame = cbGso - sizeof(PDMNETWORKGSO); 296 297 PCPDMNETWORKGSO pGso = IntNetHdrGetGsoContext(pHdr, m_pIfBuf); 298 if (PDMNetGsoIsValid(pGso, cbGso, cbFrame)) 299 { 300 const uint32_t cSegs = PDMNetGsoCalcSegmentCount(pGso, cbFrame); 301 for (uint32_t i = 0; i < cSegs; ++i) 302 { 303 uint8_t abHdrScratch[256]; 304 pvSegFrame = PDMNetGsoCarveSegmentQD(pGso, (uint8_t *)(pGso + 1), cbFrame, 305 abHdrScratch, 306 i, cSegs, 307 &cbSegFrame); 308 ifInput(pvSegFrame, (uint32_t)cbFrame); 309 } 310 } 311 } 312 313 /* Advance: */ 314 IntNetRingSkipFrame(&m_pIfBuf->Recv); 315 pHdr = IntNetRingGetNextFrameToRead(&m_pIfBuf->Recv); 316 } 317 318 return VINF_SUCCESS; 319 } 320 321 322 /** 323 * Got a frame from the internal network, feed it to the lwIP stack. 324 */ 325 int VBoxNetDhcpd::ifInput(void *pvFrame, uint32_t cbFrame) 326 { 327 if (pvFrame == NULL) 328 return VERR_INVALID_PARAMETER; 329 330 if ( cbFrame <= sizeof(RTNETETHERHDR) 331 || cbFrame > UINT16_MAX - ETH_PAD_SIZE) 332 return VERR_INVALID_PARAMETER; 333 228 void VBoxNetDhcpd::ifInputWorker(void *pvFrame, uint32_t cbFrame) 229 { 334 230 struct pbuf *p = pbuf_alloc(PBUF_RAW, (u16_t)cbFrame + ETH_PAD_SIZE, PBUF_POOL); 335 if (RT_UNLIKELY(p == NULL)) 336 return VERR_NO_MEMORY; 231 AssertPtrReturnVoid(p); 337 232 338 233 /* … … 363 258 364 259 m_LwipNetif.input(p, &m_LwipNetif); 365 return VINF_SUCCESS; 260 } 261 262 263 /** 264 * Got a frame from the internal network, feed it to the lwIP stack. 265 */ 266 /*static*/ 267 DECLCALLBACK(void) VBoxNetDhcpd::ifInput(void *pvUser, void *pvFrame, uint32_t cbFrame) 268 { 269 AssertReturnVoid(pvFrame); 270 AssertReturnVoid( cbFrame > sizeof(RTNETETHERHDR) 271 && cbFrame <= UINT16_MAX - ETH_PAD_SIZE); 272 273 VBoxNetDhcpd *self = static_cast<VBoxNetDhcpd *>(pvUser); 274 self->ifInputWorker(pvFrame, cbFrame); 366 275 } 367 276 … … 375 284 return ERR_ARG; 376 285 377 PINTNETHDR pHdr;378 void *pvFrame;379 286 u16_t cbFrame = pPBuf->tot_len - ETH_PAD_SIZE; 380 int rc = IntNetRingAllocateFrame(&m_pIfBuf->Send, cbFrame, &pHdr, &pvFrame); 287 INTNETFRAME Frame; 288 int rc = IntNetR3IfQueryOutputFrame(m_hIf, cbFrame, &Frame); 381 289 if (RT_FAILURE(rc)) 382 290 return ERR_MEM; 383 291 384 pbuf_copy_partial(pPBuf, pvFrame, cbFrame, ETH_PAD_SIZE); 385 IntNetRingCommitFrameEx(&m_pIfBuf->Send, pHdr, cbFrame); 386 387 IntNetR3IfSend(m_hIf); 292 pbuf_copy_partial(pPBuf, Frame.pvFrame, cbFrame, ETH_PAD_SIZE); 293 IntNetR3IfOutputFrameCommit(m_hIf, &Frame); 388 294 return ERR_OK; 389 295 } … … 467 373 * Pump packets more or less for ever. 468 374 */ 469 ifPump(); 375 rc = IntNetR3IfPumpPkts(m_hIf, ifInput, this, 376 NULL /*pfnInputGso*/, NULL /*pvUserGso*/); 470 377 } 471 378 else
Note:
See TracChangeset
for help on using the changeset viewer.