- Timestamp:
- Jul 18, 2008 7:58:48 PM (16 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Makefile.kmk
r10663 r10756 794 794 tstIntNet-1_TEMPLATE = VBOXR3TSTEXE 795 795 tstIntNet-1_SOURCES = \ 796 Network/testcase/tstIntNet-1.cpp 796 Network/testcase/tstIntNet-1.cpp \ 797 Network/Pcap.cpp 797 798 endif 798 799 -
trunk/src/VBox/Devices/Network/testcase/tstIntNet-1.cpp
r10751 r10756 39 39 #include <iprt/crc32.h> 40 40 41 #include "../Pcap.h" 42 41 43 42 44 /******************************************************************************* 43 45 * Global Variables * 44 46 *******************************************************************************/ 45 static int g_cErrors = 0; 47 static int g_cErrors = 0; 48 static uint64_t g_StartTS = 0; 49 46 50 47 51 … … 147 151 * @param pvFrame The frame without a crc. 148 152 * @param cbFrame The size of it. 153 * @param pFileRaw The file to write the raw data to (optional). 149 154 */ 150 static void doXmitFrame(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PINTNETBUF pBuf, void *pvFrame, size_t cbFrame )155 static void doXmitFrame(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PINTNETBUF pBuf, void *pvFrame, size_t cbFrame, PRTSTREAM pFileRaw) 151 156 { 152 157 /* … … 154 159 */ 155 160 uint32_t u32Crc = RTCrc32(pvFrame, cbFrame); 156 u32Crc = RT_H2 BE_U32(u32Crc);157 memcpy( pvFrame, &u32Crc, sizeof(u32Crc));161 u32Crc = RT_H2LE_U32(u32Crc); /* huh? */ 162 memcpy((uint8_t *)pvFrame + cbFrame, &u32Crc, sizeof(u32Crc)); 158 163 cbFrame += sizeof(u32Crc); 159 164 … … 165 170 */ 166 171 int rc = tstIntNetWriteFrame(pBuf, &pBuf->Send, pvFrame, cbFrame); 167 if (RT_FAILURE(rc)) 172 if (RT_SUCCESS(rc)) 173 { 174 if (pFileRaw) 175 PcapStreamFrame(pFileRaw, g_StartTS, pvFrame, cbFrame, 0xffff); 176 } 177 else 168 178 { 169 179 RTPrintf("tstIntNet-1: tstIntNetWriteFrame failed, %Rrc; cbFrame=%d pBuf->cbSend=%d\n", rc, cbFrame, pBuf->cbSend); … … 182 192 g_cErrors++; 183 193 } 194 195 } 196 197 198 /** 199 * Internt protocol checksumming 200 * This is great fun because of the pseudo header. 201 */ 202 static uint16_t tstIntNet1InetCheckSum(void const *pvBuf, size_t cbBuf, uint32_t u32Src, uint32_t u32Dst, uint8_t u8Proto) 203 { 204 /* 205 * Construct the pseudo header and sum it. 206 */ 207 struct pseudo_header 208 { 209 uint32_t u32Src; 210 uint32_t u32Dst; 211 uint8_t u8Zero; 212 uint8_t u8Proto; 213 uint16_t u16Len; 214 } s = 215 { 216 RT_H2BE_U32(u32Src), 217 RT_H2BE_U32(u32Dst), 218 0, 219 u8Proto, 220 RT_H2BE_U16((uint16_t)cbBuf) 221 }; 222 const uint16_t *pu16 = (const uint16_t *)&s; 223 int32_t iSum = *pu16++; 224 iSum += *pu16++; 225 iSum += *pu16++; 226 iSum += *pu16++; 227 iSum += *pu16++; 228 iSum += *pu16++; 229 AssertCompileSize(s, 12); 230 231 /* 232 * Continue with protocol header and data. 233 */ 234 pu16 = (const uint16_t *)pvBuf; 235 while (cbBuf > 1) 236 { 237 iSum += *pu16++; 238 cbBuf -= 2; 239 } 240 241 /* deal with odd size */ 242 if (cbBuf) 243 { 244 RTUINT16U u16; 245 u16.u = 0; 246 u16.au8[0] = *(uint8_t const *)pu16; 247 iSum += u16.u; 248 } 249 250 /* 16-bit one complement fun */ 251 iSum = (iSum >> 16) + (iSum & 0xffff); /* hi + low words */ 252 iSum += iSum >> 16; /* carry */ 253 return (uint16_t)~iSum; 254 } 255 256 257 /** 258 * IP checksumming 259 */ 260 static uint16_t tstIntNet1IpCheckSum(void const *pvBuf, size_t cbBuf) 261 { 262 const uint16_t *pu16 = (const uint16_t *)pvBuf; 263 int32_t iSum = 0; 264 while (cbBuf > 1) 265 { 266 iSum += *pu16++; 267 cbBuf -= 2; 268 } 269 270 /* deal with odd size */ 271 if (cbBuf) 272 { 273 RTUINT16U u16; 274 u16.u = 0; 275 u16.au8[0] = *(uint8_t const *)pu16; 276 iSum += u16.u; 277 } 278 279 /* 16-bit one complement fun */ 280 iSum = (iSum >> 16) + (iSum & 0xffff); /* hi + low words */ 281 iSum += iSum >> 16; /* carry */ 282 return (uint16_t)~iSum; 184 283 } 185 284 … … 192 291 * @param pBuf The shared interface buffer. 193 292 * @param pSrcMac The mac address to use as source. 293 * @param pFileRaw The file to write the raw data to (optional). 194 294 */ 195 static void doXmitText(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PINTNETBUF pBuf, PCPDMMAC pSrcMac )295 static void doXmitText(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PINTNETBUF pBuf, PCPDMMAC pSrcMac, PRTSTREAM pFileRaw) 196 296 { 297 uint8_t abFrame[4096]; 298 197 299 #pragma pack(1) 198 struct 300 301 struct MyEthHdr 199 302 { 200 303 PDMMAC DstMac; 201 304 PDMMAC SrcMac; 202 305 uint16_t u16Type; 203 204 union 205 { 206 uint8_t abData[4096]; 207 struct 208 { 209 210 uint8_t Op; 211 uint8_t HType; 212 uint8_t HLen; 213 uint8_t Hops; 214 uint32_t XID; 215 uint16_t Secs; 216 uint16_t Flags; 217 uint32_t CIAddr; 218 uint32_t YIAddr; 219 uint32_t SIAddr; 220 uint32_t GIAddr; 221 uint8_t CHAddr[16]; 222 uint8_t SName[64]; 223 uint8_t File[128]; 224 uint8_t Options[64]; 225 uint8_t u8TheEnd; 226 } DhcpMsg; 227 } u; 228 } Frame; 306 } *pEthHdr = (struct MyEthHdr *)&abFrame[0]; 307 struct MyIpHdr 308 { 309 #ifdef RT_BIG_ENDIAN 310 unsigned int ip_v : 4; 311 unsigned int ip_hl : 4; 312 unsigned int ip_tos : 8; 313 unsigned int ip_len : 16; 314 #else 315 unsigned int ip_hl : 4; 316 unsigned int ip_v : 4; 317 unsigned int ip_tos : 8; 318 unsigned int ip_len : 16; 319 #endif 320 uint16_t ip_id; 321 uint16_t ip_off; 322 uint8_t ip_ttl; 323 uint8_t ip_p; 324 uint16_t ip_sum; 325 uint32_t ip_src; 326 uint32_t ip_dst; 327 /* more */ 328 uint32_t ip_options[1]; 329 } *pIpHdr = (struct MyIpHdr *)(pEthHdr + 1); 330 331 struct MyUdpHdr 332 { 333 uint16_t uh_sport; 334 uint16_t uh_dport; 335 uint16_t uh_ulen; 336 uint16_t uh_sum; 337 } *pUdpHdr = (struct MyUdpHdr *)(pIpHdr + 1); 338 339 struct MyDhcpMsg 340 { 341 uint8_t Op; 342 uint8_t HType; 343 uint8_t HLen; 344 uint8_t Hops; 345 uint32_t XID; 346 uint16_t Secs; 347 uint16_t Flags; 348 uint32_t CIAddr; 349 uint32_t YIAddr; 350 uint32_t SIAddr; 351 uint32_t GIAddr; 352 uint8_t CHAddr[16]; 353 uint8_t SName[64]; 354 uint8_t File[128]; 355 uint8_t abMagic[4]; 356 uint8_t DhcpOpt; 357 uint8_t DhcpLen; /* 1 */ 358 uint8_t DhcpReq; 359 uint8_t abOptions[57]; 360 } *pDhcpMsg = (struct MyDhcpMsg *)(pUdpHdr + 1); 361 229 362 #pragma pack(0) 230 363 … … 232 365 * Create a simple DHCP broadcast request. 233 366 */ 234 memset(&Frame, 0, sizeof(Frame)); 235 memset(&Frame.DstMac, 0xff, sizeof(Frame.DstMac)); 236 Frame.SrcMac = *pSrcMac; 237 Frame.u16Type = 0x0800; 238 Frame.u.DhcpMsg.Op = 1; /* request */ 239 Frame.u.DhcpMsg.HType = 6; 240 Frame.u.DhcpMsg.HLen = sizeof(PDMMAC); 241 Frame.u.DhcpMsg.Hops = 0; 242 Frame.u.DhcpMsg.XID = RTRandU32(); 243 Frame.u.DhcpMsg.Secs = 0; 244 Frame.u.DhcpMsg.Flags = 1; /* broadcast */ 245 Frame.u.DhcpMsg.CIAddr = 0; 246 Frame.u.DhcpMsg.YIAddr = 0; 247 Frame.u.DhcpMsg.SIAddr = 0; 248 Frame.u.DhcpMsg.GIAddr = 0; 249 memset(&Frame.u.DhcpMsg.CHAddr[0], '\0', sizeof(Frame.u.DhcpMsg.CHAddr)); 250 memcpy(&Frame.u.DhcpMsg.CHAddr[0], pSrcMac, sizeof(*pSrcMac)); 251 memset(&Frame.u.DhcpMsg.SName[0], '\0', sizeof(Frame.u.DhcpMsg.SName)); 252 memset(&Frame.u.DhcpMsg.File[0], '\0', sizeof(Frame.u.DhcpMsg.File)); 253 memset(&Frame.u.DhcpMsg.Options[0], '\0', sizeof(Frame.u.DhcpMsg.Options)); 254 255 doXmitFrame(hIf,pSession,pBuf, &Frame, &Frame.u.DhcpMsg.u8TheEnd - (uint8_t *)&Frame); 367 memset(&abFrame, 0, sizeof(abFrame)); 368 369 pDhcpMsg->Op = 1; /* request */ 370 pDhcpMsg->HType = 1; 371 pDhcpMsg->HLen = sizeof(PDMMAC); 372 pDhcpMsg->Hops = 0; 373 pDhcpMsg->XID = RTRandU32(); 374 pDhcpMsg->Secs = 0; 375 pDhcpMsg->Flags = 0; /* unicast */ //RT_H2BE_U16(0x8000); /* broadcast */ 376 pDhcpMsg->CIAddr = 0; 377 pDhcpMsg->YIAddr = 0; 378 pDhcpMsg->SIAddr = 0; 379 pDhcpMsg->GIAddr = 0; 380 memset(&pDhcpMsg->CHAddr[0], '\0', sizeof(pDhcpMsg->CHAddr)); 381 memcpy(&pDhcpMsg->CHAddr[0], pSrcMac, sizeof(*pSrcMac)); 382 memset(&pDhcpMsg->SName[0], '\0', sizeof(pDhcpMsg->SName)); 383 memset(&pDhcpMsg->File[0], '\0', sizeof(pDhcpMsg->File)); 384 pDhcpMsg->abMagic[0] = 99; 385 pDhcpMsg->abMagic[1] = 130; 386 pDhcpMsg->abMagic[2] = 83; 387 pDhcpMsg->abMagic[3] = 99; 388 389 pDhcpMsg->DhcpOpt = 53; /* DHCP Msssage Type option */ 390 pDhcpMsg->DhcpLen = 1; 391 pDhcpMsg->DhcpReq = 1; /* DHCPDISCOVER */ 392 393 memset(&pDhcpMsg->abOptions[0], '\0', sizeof(pDhcpMsg->abOptions)); 394 uint8_t *pbOpt = &pDhcpMsg->abOptions[0]; 395 396 *pbOpt++ = 116; /* DHCP Auto-Configure */ 397 *pbOpt++ = 1; 398 *pbOpt++ = 1; 399 400 *pbOpt++ = 61; /* Client identifier */ 401 *pbOpt++ = 1 + sizeof(*pSrcMac); 402 *pbOpt++ = 1; /* hw type: ethernet */ 403 memcpy(pbOpt, pSrcMac, sizeof(*pSrcMac)); 404 pbOpt += sizeof(*pSrcMac); 405 406 *pbOpt++ = 12; /* Host name */ 407 *pbOpt++ = sizeof("tstIntNet-1") - 1; 408 memcpy(pbOpt, "tstIntNet-1", sizeof("tstIntNet-1") - 1); 409 pbOpt += sizeof("tstIntNet-1") - 1; 410 411 *pbOpt = 0xff; /* the end */ 412 413 /* UDP */ 414 pUdpHdr->uh_sport = RT_H2BE_U16(68); /* bootp */ 415 pUdpHdr->uh_dport = RT_H2BE_U16(67); /* bootps */ 416 pUdpHdr->uh_ulen = RT_H2BE_U16(sizeof(*pDhcpMsg) + sizeof(*pUdpHdr)); 417 pUdpHdr->uh_sum = 0; /* pretend checksumming is disabled */ 418 419 /* IP */ 420 pIpHdr->ip_v = 4; 421 pIpHdr->ip_hl = sizeof(*pIpHdr) / sizeof(uint32_t); 422 pIpHdr->ip_tos = 0; 423 pIpHdr->ip_len = RT_H2BE_U16(sizeof(*pDhcpMsg) + sizeof(*pUdpHdr) + sizeof(*pIpHdr)); 424 pIpHdr->ip_id = (uint16_t)RTRandU32(); 425 pIpHdr->ip_off = 0; 426 pIpHdr->ip_ttl = 255; 427 pIpHdr->ip_p = 0x11; /* UDP */ 428 pIpHdr->ip_sum = 0; 429 pIpHdr->ip_src = 0; 430 pIpHdr->ip_dst = UINT32_C(0xffffffff); /* broadcast */ 431 pIpHdr->ip_sum = tstIntNet1IpCheckSum(pIpHdr, sizeof(*pIpHdr)); 432 433 /* calc the UDP checksum. */ 434 pUdpHdr->uh_sum = tstIntNet1InetCheckSum(pUdpHdr, 435 RT_BE2H_U16(pUdpHdr->uh_ulen), 436 RT_BE2H_U32(pIpHdr->ip_src), 437 RT_BE2H_U32(pIpHdr->ip_dst), 438 pIpHdr->ip_p); 439 440 /* Ethernet */ 441 memset(&pEthHdr->DstMac, 0xff, sizeof(pEthHdr->DstMac)); /* broadcast */ 442 pEthHdr->SrcMac = *pSrcMac; 443 pEthHdr->u16Type = RT_H2BE_U16(0x0800); /* IP */ 444 445 doXmitFrame(hIf, pSession, pBuf, &abFrame[0], (uint8_t *)(pDhcpMsg + 1) - (uint8_t *)&abFrame[0], pFileRaw); 256 446 } 257 447 … … 271 461 { 272 462 /* 273 * Write the raw file header.274 */275 276 277 /*278 463 * The loop. 279 464 */ 280 uint64_t const StartTS = RTTimeNanoTS();281 465 PINTNETRINGBUF pRingBuf = &pBuf->Recv; 282 466 for (;;) … … 285 469 * Wait for a packet to become available. 286 470 */ 287 uint64_t cElapsedMillies = (RTTimeNanoTS() - StartTS) / 1000000;471 uint64_t cElapsedMillies = (RTTimeNanoTS() - g_StartTS) / 1000000; 288 472 if (cElapsedMillies >= cMillies) 289 473 break; … … 314 498 size_t cbFrame = pHdr->cbFrame; 315 499 const void *pvFrame = INTNETHdrGetFramePtr(pHdr, pBuf); 316 uint64_t NanoTS = RTTimeNanoTS() - StartTS;500 uint64_t NanoTS = RTTimeNanoTS() - g_StartTS; 317 501 318 502 if (pFileRaw) 319 { 320 } 503 PcapStreamFrame(pFileRaw, g_StartTS, pvFrame, cbFrame, 0xffff); 321 504 322 505 if (pFileText) … … 336 519 } 337 520 338 uint64_t NanoTS = RTTimeNanoTS() - StartTS;521 uint64_t NanoTS = RTTimeNanoTS() - g_StartTS; 339 522 RTStrmPrintf(pFileText ? pFileText : g_pStdOut, 340 523 "%3RU64.%09u: stopped. cRecvs=%RU64 cbRecv=%RU64 cLost=%RU64 cOYs=%RU64 cNYs=%RU64\n", … … 578 761 { 579 762 /* 763 * Start the stop watch, init the pcap file. 764 */ 765 g_StartTS = RTTimeNanoTS(); 766 if (pFileRaw) 767 PcapStreamHdr(pFileRaw, g_StartTS); 768 769 /* 580 770 * Do the transmit test first and so we can sniff for the response. 581 771 */ 582 772 if (fXmitTest) 583 doXmitText(OpenReq.hIf, pSession, pBuf, &SrcMac );773 doXmitText(OpenReq.hIf, pSession, pBuf, &SrcMac, pFileRaw); 584 774 585 775 /*
Note:
See TracChangeset
for help on using the changeset viewer.