VirtualBox

Changeset 10751 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Jul 18, 2008 4:08:16 PM (16 years ago)
Author:
vboxsync
Message:

Implemented a send testcase.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/testcase/tstIntNet-1.cpp

    r10747 r10751  
    3535#include <iprt/param.h>
    3636#include <iprt/getopt.h>
     37#include <iprt/rand.h>
     38#include <iprt/log.h>
     39#include <iprt/crc32.h>
    3740
    3841
     
    4144*******************************************************************************/
    4245static 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 */
     58static 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 */
     150static 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 */
     195static 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}
    43257
    44258
     
    170384    PRTSTREAM   pFileText = g_pStdOut;
    171385    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);
    172391
    173392    int rc;
     
    359578            {
    360579                /*
     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                /*
    361586                 * Either enter sniffing mode or do a timeout thing.
    362587                 */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette