Changeset 17780 in vbox
- Timestamp:
- Mar 12, 2009 10:23:53 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 44313
- Location:
- trunk/src/VBox/NetworkServices
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.cpp
r17779 r17780 1548 1548 * Send it. 1549 1549 */ 1550 1550 int rc; 1551 #if 0 1552 if (pDhcpMsg->bp_flags & RTNET_DHCP_FLAGS_NO_BROADCAST) 1553 { 1554 RTNETADDRIPV4 IPv4AddrBrdCast; 1555 IPv4AddrBrdCast.u = UINT32_C(0xffffffff); /* broadcast IP */ 1556 rc = VBoxNetUDPUnicast(m_pSession, m_hIf, m_pIfBuf, 1557 m_Ipv4Address, &m_MacAddress, RTNETIPV4_PORT_BOOTPS, /* sender */ 1558 IPv4AddrBrdCast, &pDhcpMsg->bp_chaddr.Mac, RTNETIPV4_PORT_BOOTPC, /* receiver */ 1559 pReply, cbReply); 1560 } 1561 else 1562 #endif 1563 rc = VBoxNetUDPBroadcast(m_pSession, m_hIf, m_pIfBuf, 1564 m_Ipv4Address, &m_MacAddress, RTNETIPV4_PORT_BOOTPS, /* sender */ 1565 RTNETIPV4_PORT_BOOTPC, /* receiver port */ 1566 pReply, cbReply); 1567 if (RT_FAILURE(rc)) 1568 debugPrint(0, true, "error %Rrc when sending the reply", rc); 1551 1569 } 1552 1570 -
trunk/src/VBox/NetworkServices/UDPLib/VBoxNetUDP.cpp
r17403 r17780 23 23 * Header Files * 24 24 *******************************************************************************/ 25 #define LOG_GROUP LOG_GROUP_DEFAULT 25 26 #include "VBoxNetUDP.h" 26 27 #include <iprt/stream.h> 27 28 #include <iprt/string.h> 29 #include <iprt/rand.h> 30 #include <VBox/vmm.h> 31 #include <VBox/log.h> 28 32 29 33 … … 151 155 } 152 156 157 158 /** 159 * Flushes the send buffer. 160 * 161 * @returns VBox status code. 162 * @param pSession The support driver session. 163 * @param hIf The interface handle to flush. 164 */ 165 static int vboxnetudpFlush(PSUPDRVSESSION pSession, INTNETIFHANDLE hIf) 166 { 167 INTNETIFSENDREQ SendReq; 168 SendReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 169 SendReq.Hdr.cbReq = sizeof(SendReq); 170 SendReq.pSession = pSession; 171 SendReq.hIf = hIf; 172 return SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_IF_SEND, 0, &SendReq.Hdr); 173 } 174 175 176 /** 177 * Copys the SG segments into the specified fram. 178 * 179 * @param pvFrame The frame buffer. 180 * @param cSegs The number of segments. 181 * @param paSegs The segments. 182 */ 183 static void vboxnetudpCopySG(void *pvFrame, size_t cSegs, PCINTNETSEG paSegs) 184 { 185 uint8_t *pbDst = (uint8_t *)pvFrame; 186 for (size_t iSeg = 0; iSeg < cSegs; iSeg++) 187 { 188 memcpy(pbDst, paSegs[iSeg].pv, paSegs[iSeg].cb); 189 pbDst += paSegs[iSeg].cb; 190 } 191 } 192 193 194 /** 195 * Writes a frame packet to the buffer. 196 * 197 * @returns VBox status code. 198 * @param pBuf The buffer. 199 * @param pRingBuf The ring buffer to read from. 200 * @param cSegs The number of segments. 201 * @param paSegs The segments. 202 * @remark This is the same as INTNETRingWriteFrame and 203 * drvIntNetRingWriteFrame. 204 */ 205 static int vboxnetudpRingWriteFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf, 206 size_t cSegs, PCINTNETSEG paSegs) 207 { 208 /* 209 * Validate input. 210 */ 211 Assert(pBuf); 212 Assert(pRingBuf); 213 uint32_t offWrite = pRingBuf->offWrite; 214 Assert(offWrite == RT_ALIGN_32(offWrite, sizeof(INTNETHDR))); 215 uint32_t offRead = pRingBuf->offRead; 216 Assert(offRead == RT_ALIGN_32(offRead, sizeof(INTNETHDR))); 217 AssertPtr(paSegs); 218 Assert(cSegs > 0); 219 220 /* Calc frame size. */ 221 uint32_t cbFrame = 0; 222 for (size_t iSeg = 0; iSeg < cSegs; iSeg++) 223 cbFrame += paSegs[iSeg].cb; 224 225 Assert(cbFrame >= sizeof(RTMAC) * 2); 226 227 228 const uint32_t cb = RT_ALIGN_32(cbFrame, sizeof(INTNETHDR)); 229 if (offRead <= offWrite) 230 { 231 /* 232 * Try fit it all before the end of the buffer. 233 */ 234 if (pRingBuf->offEnd - offWrite >= cb + sizeof(INTNETHDR)) 235 { 236 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite); 237 pHdr->u16Type = INTNETHDR_TYPE_FRAME; 238 pHdr->cbFrame = cbFrame; 239 pHdr->offFrame = sizeof(INTNETHDR); 240 241 vboxnetudpCopySG(pHdr + 1, cSegs, paSegs); 242 243 offWrite += cb + sizeof(INTNETHDR); 244 Assert(offWrite <= pRingBuf->offEnd && offWrite >= pRingBuf->offStart); 245 if (offWrite >= pRingBuf->offEnd) 246 offWrite = pRingBuf->offStart; 247 Log2(("WriteFrame: offWrite: %#x -> %#x (1)\n", pRingBuf->offWrite, offWrite)); 248 ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite); 249 return VINF_SUCCESS; 250 } 251 252 /* 253 * Try fit the frame at the start of the buffer. 254 * (The header fits before the end of the buffer because of alignment.) 255 */ 256 AssertMsg(pRingBuf->offEnd - offWrite >= sizeof(INTNETHDR), ("offEnd=%x offWrite=%x\n", pRingBuf->offEnd, offWrite)); 257 if (offRead - pRingBuf->offStart > cb) /* not >= ! */ 258 { 259 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite); 260 void *pvFrameOut = (PINTNETHDR)((uint8_t *)pBuf + pRingBuf->offStart); 261 pHdr->u16Type = INTNETHDR_TYPE_FRAME; 262 pHdr->cbFrame = cbFrame; 263 pHdr->offFrame = (intptr_t)pvFrameOut - (intptr_t)pHdr; 264 265 vboxnetudpCopySG(pvFrameOut, cSegs, paSegs); 266 267 offWrite = pRingBuf->offStart + cb; 268 ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite); 269 Log2(("WriteFrame: offWrite: %#x -> %#x (2)\n", pRingBuf->offWrite, offWrite)); 270 return VINF_SUCCESS; 271 } 272 } 273 /* 274 * The reader is ahead of the writer, try fit it into that space. 275 */ 276 else if (offRead - offWrite > cb + sizeof(INTNETHDR)) /* not >= ! */ 277 { 278 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite); 279 pHdr->u16Type = INTNETHDR_TYPE_FRAME; 280 pHdr->cbFrame = cbFrame; 281 pHdr->offFrame = sizeof(INTNETHDR); 282 283 vboxnetudpCopySG(pHdr + 1, cSegs, paSegs); 284 285 offWrite += cb + sizeof(INTNETHDR); 286 ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite); 287 Log2(("WriteFrame: offWrite: %#x -> %#x (3)\n", pRingBuf->offWrite, offWrite)); 288 return VINF_SUCCESS; 289 } 290 291 /* (it didn't fit) */ 292 /** @todo stats */ 293 return VERR_BUFFER_OVERFLOW; 294 } 295 296 297 /** Internal worker for VBoxNetUDPUnicast and VBoxNetUDPBroadcast. */ 298 static int vboxnetudpSend(PSUPDRVSESSION pSession, INTNETIFHANDLE hIf, PINTNETBUF pBuf, 299 RTNETADDRIPV4 SrcIPv4Addr, PCRTMAC pSrcMacAddr, unsigned uSrcPort, 300 RTNETADDRIPV4 DstIPv4Addr, PCRTMAC pDstMacAddr, unsigned uDstPort, 301 void const *pvData, size_t cbData) 302 { 303 INTNETSEG aSegs[4]; 304 305 /* the Ethernet header */ 306 RTNETETHERHDR EtherHdr; 307 EtherHdr.DstMac = *pDstMacAddr; 308 EtherHdr.SrcMac = *pSrcMacAddr; 309 EtherHdr.EtherType = RT_H2BE_U16_C(RTNET_ETHERTYPE_IPV4); 310 311 aSegs[0].pv = &EtherHdr; 312 aSegs[0].cb = sizeof(EtherHdr); 313 aSegs[0].Phys = NIL_RTHCPHYS; 314 315 /* the IP header */ 316 RTNETIPV4 IpHdr; 317 IpHdr.ip_v = 4; 318 IpHdr.ip_hl = sizeof(RTNETIPV4) / sizeof(uint32_t); 319 IpHdr.ip_tos = 0; 320 IpHdr.ip_len = RT_H2BE_U16(cbData + sizeof(RTNETUDP) + sizeof(RTNETIPV4)); 321 IpHdr.ip_id = (uint16_t)RTRandU32(); 322 IpHdr.ip_off = 0; 323 IpHdr.ip_ttl = 255; 324 IpHdr.ip_p = RTNETIPV4_PROT_UDP; 325 IpHdr.ip_sum = 0; 326 IpHdr.ip_src.u = 0; 327 IpHdr.ip_dst.u = UINT32_C(0xffffffff); /* broadcast */ 328 IpHdr.ip_sum = RTNetIPv4HdrChecksum(&IpHdr); 329 330 aSegs[1].pv = &IpHdr; 331 aSegs[1].cb = sizeof(IpHdr); 332 aSegs[1].Phys = NIL_RTHCPHYS; 333 334 335 /* the UDP bit */ 336 RTNETUDP UdpHdr; 337 UdpHdr.uh_sport = RT_H2BE_U16(uSrcPort); 338 UdpHdr.uh_dport = RT_H2BE_U16(uDstPort); 339 UdpHdr.uh_ulen = RT_H2BE_U16(cbData + sizeof(RTNETUDP)); 340 #if 0 341 UdpHdr.uh_sum = 0; /* pretend checksumming is disabled */ 342 #else 343 UdpHdr.uh_sum = RTNetIPv4UDPChecksum(&IpHdr, &UdpHdr, pvData); 344 #endif 345 346 aSegs[2].pv = &UdpHdr; 347 aSegs[2].cb = sizeof(UdpHdr); 348 aSegs[2].Phys = NIL_RTHCPHYS; 349 350 /* the payload */ 351 aSegs[3].pv = (void *)pvData; 352 aSegs[3].cb = cbData; 353 aSegs[3].Phys = NIL_RTHCPHYS; 354 355 356 /* write it */ 357 int rc = vboxnetudpRingWriteFrame(pBuf, &pBuf->Send, RT_ELEMENTS(aSegs), &aSegs[0]); 358 int rc2 = vboxnetudpFlush(pSession, hIf); 359 if (RT_FAILURE(rc)) 360 { 361 rc = vboxnetudpRingWriteFrame(pBuf, &pBuf->Send, RT_ELEMENTS(aSegs), &aSegs[0]); 362 rc2 = vboxnetudpFlush(pSession, hIf); 363 } 364 365 if (RT_SUCCESS(rc)) 366 rc = rc2; 367 return rc; 368 } 369 370 371 /** 372 * Sends an unicast UDP packet. 373 * 374 * @returns VBox status code. 375 * @param pSession The support driver session handle. 376 * @param hIf The interface handle. 377 * @param pBuf The interface buffer. 378 * @param SrcIPv4Addr The source IPv4 address. 379 * @param pSrcMacAddr The source MAC address. 380 * @param uSrcPort The source port number. 381 * @param DstIPv4Addr The destination IPv4 address. Can be broadcast. 382 * @param pDstMacAddr The destination MAC address. 383 * @param uDstPort The destination port number. 384 * @param pvData The data payload. 385 * @param cbData The size of the data payload. 386 */ 387 int VBoxNetUDPUnicast(PSUPDRVSESSION pSession, INTNETIFHANDLE hIf, PINTNETBUF pBuf, 388 RTNETADDRIPV4 SrcIPv4Addr, PCRTMAC pSrcMacAddr, unsigned uSrcPort, 389 RTNETADDRIPV4 DstIPv4Addr, PCRTMAC pDstMacAddr, unsigned uDstPort, 390 void const *pvData, size_t cbData) 391 { 392 return vboxnetudpSend(pSession, hIf, pBuf, 393 SrcIPv4Addr, pSrcMacAddr, uSrcPort, 394 DstIPv4Addr, pDstMacAddr, uDstPort, 395 pvData, cbData); 396 } 397 398 399 /** 400 * Sends a broadcast UDP packet. 401 * 402 * @returns VBox status code. 403 * @param pSession The support driver session handle. 404 * @param hIf The interface handle. 405 * @param pBuf The interface buffer. 406 * @param SrcIPv4Addr The source IPv4 address. 407 * @param pSrcMacAddr The source MAC address. 408 * @param uSrcPort The source port number. 409 * @param uDstPort The destination port number. 410 * @param pvData The data payload. 411 * @param cbData The size of the data payload. 412 */ 413 int VBoxNetUDPBroadcast(PSUPDRVSESSION pSession, INTNETIFHANDLE hIf, PINTNETBUF pBuf, 414 RTNETADDRIPV4 SrcIPv4Addr, PCRTMAC pSrcMacAddr, unsigned uSrcPort, 415 unsigned uDstPort, 416 void const *pvData, size_t cbData) 417 { 418 RTNETADDRIPV4 IPv4AddrBrdCast; 419 IPv4AddrBrdCast.u = UINT32_C(0xffffffff); 420 RTMAC MacBrdCast; 421 MacBrdCast.au16[0] = MacBrdCast.au16[1] = MacBrdCast.au16[2] = UINT16_C(0xffff); 422 423 return vboxnetudpSend(pSession, hIf, pBuf, 424 SrcIPv4Addr, pSrcMacAddr, uSrcPort, 425 IPv4AddrBrdCast, &MacBrdCast, uDstPort, 426 pvData, cbData); 427 } 428 -
trunk/src/VBox/NetworkServices/UDPLib/VBoxNetUDP.h
r17374 r17780 51 51 /** @} */ 52 52 53 void *VBoxNetUDPMatch(PCINTNETBUF pBuf, unsigned uDstPort, PCRTMAC pDstMac, uint32_t fFlags, PVBOXNETUDPHDRS pHdrs, size_t *pcb); 54 53 void * VBoxNetUDPMatch(PCINTNETBUF pBuf, unsigned uDstPort, PCRTMAC pDstMac, uint32_t fFlags, PVBOXNETUDPHDRS pHdrs, size_t *pcb); 54 int VBoxNetUDPUnicast(PSUPDRVSESSION pSession, INTNETIFHANDLE hIf, PINTNETBUF pBuf, 55 RTNETADDRIPV4 SrcIPv4Addr, PCRTMAC SrcMacAddr, unsigned uSrcPort, 56 RTNETADDRIPV4 DstIPv4Addr, PCRTMAC DstMacAddr, unsigned uDstPort, 57 void const *pvData, size_t cbData); 58 int VBoxNetUDPBroadcast(PSUPDRVSESSION pSession, INTNETIFHANDLE hIf, PINTNETBUF pBuf, 59 RTNETADDRIPV4 SrcIPv4Addr, PCRTMAC SrcMacAddr, unsigned uSrcPort, 60 unsigned uDstPort, 61 void const *pvData, size_t cbData); 55 62 56 63 __END_DECLS
Note:
See TracChangeset
for help on using the changeset viewer.