VirtualBox

Changeset 10756 in vbox for trunk


Ignore:
Timestamp:
Jul 18, 2008 7:58:48 PM (16 years ago)
Author:
vboxsync
Message:

Made the DHCP DISCOVER request work and implemented writing of a pcap file.

Location:
trunk/src/VBox/Devices
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Makefile.kmk

    r10663 r10756  
    794794 tstIntNet-1_TEMPLATE    = VBOXR3TSTEXE
    795795 tstIntNet-1_SOURCES     = \
    796         Network/testcase/tstIntNet-1.cpp
     796        Network/testcase/tstIntNet-1.cpp \
     797        Network/Pcap.cpp
    797798endif
    798799
  • trunk/src/VBox/Devices/Network/testcase/tstIntNet-1.cpp

    r10751 r10756  
    3939#include <iprt/crc32.h>
    4040
     41#include "../Pcap.h"
     42
    4143
    4244/*******************************************************************************
    4345*   Global Variables                                                           *
    4446*******************************************************************************/
    45 static int g_cErrors = 0;
     47static int      g_cErrors = 0;
     48static uint64_t g_StartTS = 0;
     49
    4650
    4751
     
    147151 * @param   pvFrame         The frame without a crc.
    148152 * @param   cbFrame         The size of it.
     153 * @param   pFileRaw        The file to write the raw data to (optional).
    149154 */
    150 static void doXmitFrame(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PINTNETBUF pBuf, void *pvFrame, size_t cbFrame)
     155static void doXmitFrame(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PINTNETBUF pBuf, void *pvFrame, size_t cbFrame, PRTSTREAM pFileRaw)
    151156{
    152157    /*
     
    154159     */
    155160    uint32_t u32Crc = RTCrc32(pvFrame, cbFrame);
    156     u32Crc = RT_H2BE_U32(u32Crc);
    157     memcpy(pvFrame, &u32Crc, sizeof(u32Crc));
     161    u32Crc = RT_H2LE_U32(u32Crc); /* huh? */
     162    memcpy((uint8_t *)pvFrame + cbFrame, &u32Crc, sizeof(u32Crc));
    158163    cbFrame += sizeof(u32Crc);
    159164
     
    165170     */
    166171    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
    168178    {
    169179        RTPrintf("tstIntNet-1: tstIntNetWriteFrame failed, %Rrc; cbFrame=%d pBuf->cbSend=%d\n", rc, cbFrame, pBuf->cbSend);
     
    182192        g_cErrors++;
    183193    }
     194
     195}
     196
     197
     198/**
     199 * Internt protocol checksumming
     200 * This is great fun because of the pseudo header.
     201 */
     202static 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 */
     260static 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;
    184283}
    185284
     
    192291 * @param   pBuf            The shared interface buffer.
    193292 * @param   pSrcMac         The mac address to use as source.
     293 * @param   pFileRaw        The file to write the raw data to (optional).
    194294 */
    195 static void doXmitText(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PINTNETBUF pBuf, PCPDMMAC pSrcMac)
     295static void doXmitText(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PINTNETBUF pBuf, PCPDMMAC pSrcMac, PRTSTREAM pFileRaw)
    196296{
     297    uint8_t abFrame[4096];
     298
    197299#pragma pack(1)
    198     struct
     300
     301    struct MyEthHdr
    199302    {
    200303        PDMMAC      DstMac;
    201304        PDMMAC      SrcMac;
    202305        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
    229362#pragma pack(0)
    230363
     
    232365     * Create a simple DHCP broadcast request.
    233366     */
    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);
    256446}
    257447
     
    271461{
    272462    /*
    273      * Write the raw file header.
    274      */
    275 
    276 
    277     /*
    278463     * The loop.
    279464     */
    280     uint64_t const StartTS = RTTimeNanoTS();
    281465    PINTNETRINGBUF pRingBuf = &pBuf->Recv;
    282466    for (;;)
     
    285469         * Wait for a packet to become available.
    286470         */
    287         uint64_t cElapsedMillies = (RTTimeNanoTS() - StartTS) / 1000000;
     471        uint64_t cElapsedMillies = (RTTimeNanoTS() - g_StartTS) / 1000000;
    288472        if (cElapsedMillies >= cMillies)
    289473            break;
     
    314498                size_t      cbFrame = pHdr->cbFrame;
    315499                const void *pvFrame = INTNETHdrGetFramePtr(pHdr, pBuf);
    316                 uint64_t    NanoTS = RTTimeNanoTS() - StartTS;
     500                uint64_t    NanoTS = RTTimeNanoTS() - g_StartTS;
    317501
    318502                if (pFileRaw)
    319                 {
    320                 }
     503                    PcapStreamFrame(pFileRaw, g_StartTS, pvFrame, cbFrame, 0xffff);
    321504
    322505                if (pFileText)
     
    336519    }
    337520
    338     uint64_t NanoTS = RTTimeNanoTS() - StartTS;
     521    uint64_t NanoTS = RTTimeNanoTS() - g_StartTS;
    339522    RTStrmPrintf(pFileText ? pFileText : g_pStdOut,
    340523                 "%3RU64.%09u: stopped. cRecvs=%RU64 cbRecv=%RU64 cLost=%RU64 cOYs=%RU64 cNYs=%RU64\n",
     
    578761            {
    579762                /*
     763                 * Start the stop watch, init the pcap file.
     764                 */
     765                g_StartTS = RTTimeNanoTS();
     766                if (pFileRaw)
     767                    PcapStreamHdr(pFileRaw, g_StartTS);
     768
     769                /*
    580770                 * Do the transmit test first and so we can sniff for the response.
    581771                 */
    582772                if (fXmitTest)
    583                     doXmitText(OpenReq.hIf, pSession, pBuf, &SrcMac);
     773                    doXmitText(OpenReq.hIf, pSession, pBuf, &SrcMac, pFileRaw);
    584774
    585775                /*
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