Changeset 10751 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Jul 18, 2008 4:08:16 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/testcase/tstIntNet-1.cpp
r10747 r10751 35 35 #include <iprt/param.h> 36 36 #include <iprt/getopt.h> 37 #include <iprt/rand.h> 38 #include <iprt/log.h> 39 #include <iprt/crc32.h> 37 40 38 41 … … 41 44 *******************************************************************************/ 42 45 static int g_cErrors = 0; 46 47 48 /** 49 * Writes a frame packet to the buffer. 50 * 51 * @returns VBox status code. 52 * @param pBuf The buffer. 53 * @param pRingBuf The ring buffer to read from. 54 * @param pvFrame The frame to write. 55 * @param cbFrame The size of the frame. 56 * @remark This is the same as INTNETRingWriteFrame and drvIntNetRingWriteFrame. 57 */ 58 static int tstIntNetWriteFrame(PINTNETBUF pBuf, PINTNETRINGBUF pRingBuf, const void *pvFrame, uint32_t cbFrame) 59 { 60 /* 61 * Validate input. 62 */ 63 Assert(pBuf); 64 Assert(pRingBuf); 65 Assert(pvFrame); 66 Assert(cbFrame >= sizeof(PDMMAC) * 2); 67 uint32_t offWrite = pRingBuf->offWrite; 68 Assert(offWrite == RT_ALIGN_32(offWrite, sizeof(INTNETHDR))); 69 uint32_t offRead = pRingBuf->offRead; 70 Assert(offRead == RT_ALIGN_32(offRead, sizeof(INTNETHDR))); 71 72 const uint32_t cb = RT_ALIGN_32(cbFrame, sizeof(INTNETHDR)); 73 if (offRead <= offWrite) 74 { 75 /* 76 * Try fit it all before the end of the buffer. 77 */ 78 if (pRingBuf->offEnd - offWrite >= cb + sizeof(INTNETHDR)) 79 { 80 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite); 81 pHdr->u16Type = INTNETHDR_TYPE_FRAME; 82 pHdr->cbFrame = cbFrame; 83 pHdr->offFrame = sizeof(INTNETHDR); 84 85 memcpy(pHdr + 1, pvFrame, cbFrame); 86 87 offWrite += cb + sizeof(INTNETHDR); 88 Assert(offWrite <= pRingBuf->offEnd && offWrite >= pRingBuf->offStart); 89 if (offWrite >= pRingBuf->offEnd) 90 offWrite = pRingBuf->offStart; 91 Log2(("WriteFrame: offWrite: %#x -> %#x (1)\n", pRingBuf->offWrite, offWrite)); 92 ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite); 93 return VINF_SUCCESS; 94 } 95 96 /* 97 * Try fit the frame at the start of the buffer. 98 * (The header fits before the end of the buffer because of alignment.) 99 */ 100 AssertMsg(pRingBuf->offEnd - offWrite >= sizeof(INTNETHDR), ("offEnd=%x offWrite=%x\n", pRingBuf->offEnd, offWrite)); 101 if (offRead - pRingBuf->offStart > cb) /* not >= ! */ 102 { 103 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite); 104 void *pvFrameOut = (PINTNETHDR)((uint8_t *)pBuf + pRingBuf->offStart); 105 pHdr->u16Type = INTNETHDR_TYPE_FRAME; 106 pHdr->cbFrame = cbFrame; 107 pHdr->offFrame = (intptr_t)pvFrameOut - (intptr_t)pHdr; 108 109 memcpy(pvFrameOut, pvFrame, cbFrame); 110 111 offWrite = pRingBuf->offStart + cb; 112 ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite); 113 Log2(("WriteFrame: offWrite: %#x -> %#x (2)\n", pRingBuf->offWrite, offWrite)); 114 return VINF_SUCCESS; 115 } 116 } 117 /* 118 * The reader is ahead of the writer, try fit it into that space. 119 */ 120 else if (offRead - offWrite > cb + sizeof(INTNETHDR)) /* not >= ! */ 121 { 122 PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pBuf + offWrite); 123 pHdr->u16Type = INTNETHDR_TYPE_FRAME; 124 pHdr->cbFrame = cbFrame; 125 pHdr->offFrame = sizeof(INTNETHDR); 126 127 memcpy(pHdr + 1, pvFrame, cbFrame); 128 129 offWrite += cb + sizeof(INTNETHDR); 130 ASMAtomicXchgU32(&pRingBuf->offWrite, offWrite); 131 Log2(("WriteFrame: offWrite: %#x -> %#x (3)\n", pRingBuf->offWrite, offWrite)); 132 return VINF_SUCCESS; 133 } 134 135 /* (it didn't fit) */ 136 /** @todo stats */ 137 return VERR_BUFFER_OVERFLOW; 138 } 139 140 141 /** 142 * Transmits one frame after appending the CRC. 143 * 144 * @param hIf The interface handle. 145 * @param pSession The session. 146 * @param pBuf The shared interface buffer. 147 * @param pvFrame The frame without a crc. 148 * @param cbFrame The size of it. 149 */ 150 static void doXmitFrame(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PINTNETBUF pBuf, void *pvFrame, size_t cbFrame) 151 { 152 /* 153 * Calcuate and append the checksum. 154 */ 155 uint32_t u32Crc = RTCrc32(pvFrame, cbFrame); 156 u32Crc = RT_H2BE_U32(u32Crc); 157 memcpy(pvFrame, &u32Crc, sizeof(u32Crc)); 158 cbFrame += sizeof(u32Crc); 159 160 /* 161 * Write the frame and push the queue. 162 * 163 * Don't bother with dealing with overflows like DrvIntNet does, because 164 * it's not supposed to happen here in this testcase. 165 */ 166 int rc = tstIntNetWriteFrame(pBuf, &pBuf->Send, pvFrame, cbFrame); 167 if (RT_FAILURE(rc)) 168 { 169 RTPrintf("tstIntNet-1: tstIntNetWriteFrame failed, %Rrc; cbFrame=%d pBuf->cbSend=%d\n", rc, cbFrame, pBuf->cbSend); 170 g_cErrors++; 171 } 172 173 INTNETIFSENDREQ SendReq; 174 SendReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 175 SendReq.Hdr.cbReq = sizeof(SendReq); 176 SendReq.pSession = pSession; 177 SendReq.hIf = hIf; 178 rc = SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_IF_SEND, 0, &SendReq.Hdr); 179 if (RT_FAILURE(rc)) 180 { 181 RTPrintf("tstIntNet-1: SUPCallVMMR0Ex(,VMMR0_DO_INTNET_IF_SEND,) failed, rc=%Rrc\n", rc); 182 g_cErrors++; 183 } 184 } 185 186 187 /** 188 * Does the transmit test. 189 * 190 * @param hIf The interface handle. 191 * @param pSession The session. 192 * @param pBuf The shared interface buffer. 193 * @param pSrcMac The mac address to use as source. 194 */ 195 static void doXmitText(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PINTNETBUF pBuf, PCPDMMAC pSrcMac) 196 { 197 #pragma pack(1) 198 struct 199 { 200 PDMMAC DstMac; 201 PDMMAC SrcMac; 202 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; 229 #pragma pack(0) 230 231 /* 232 * Create a simple DHCP broadcast request. 233 */ 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); 256 } 43 257 44 258 … … 170 384 PRTSTREAM pFileText = g_pStdOut; 171 385 bool fXmitTest = false; 386 PDMMAC SrcMac; 387 SrcMac.au8[0] = 0x08; 388 SrcMac.au8[1] = 0x03; 389 SrcMac.au8[2] = 0x86; 390 RTRandBytes(&SrcMac.au8[3], sizeof(SrcMac) - 3); 172 391 173 392 int rc; … … 359 578 { 360 579 /* 580 * Do the transmit test first and so we can sniff for the response. 581 */ 582 if (fXmitTest) 583 doXmitText(OpenReq.hIf, pSession, pBuf, &SrcMac); 584 585 /* 361 586 * Either enter sniffing mode or do a timeout thing. 362 587 */
Note:
See TracChangeset
for help on using the changeset viewer.