VirtualBox

Ignore:
Timestamp:
Jul 18, 2008 1:52:25 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
33493
Message:

extending the testcase.

File:
1 edited

Legend:

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

    r10681 r10747  
    3434#include <iprt/thread.h>
    3535#include <iprt/param.h>
     36#include <iprt/getopt.h>
    3637
    3738
     
    4243
    4344
     45/**
     46 * Does packet sniffing for a given period of time.
     47 *
     48 * @param   hIf             The interface handle.
     49 * @param   pSession        The session.
     50 * @param   pBuf            The shared interface buffer.
     51 * @param   cMillies        The time period, ms.
     52 * @param   pFileRaw        The file to write the raw data to (optional).
     53 * @param   pFileText       The file to write a textual packet summary to (optional).
     54 */
     55static void doPacketSniffing(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PINTNETBUF pBuf, uint32_t cMillies,
     56                             PRTSTREAM pFileRaw, PRTSTREAM pFileText)
     57{
     58    /*
     59     * Write the raw file header.
     60     */
     61
     62
     63    /*
     64     * The loop.
     65     */
     66    uint64_t const StartTS = RTTimeNanoTS();
     67    PINTNETRINGBUF pRingBuf = &pBuf->Recv;
     68    for (;;)
     69    {
     70        /*
     71         * Wait for a packet to become available.
     72         */
     73        uint64_t cElapsedMillies = (RTTimeNanoTS() - StartTS) / 1000000;
     74        if (cElapsedMillies >= cMillies)
     75            break;
     76        INTNETIFWAITREQ WaitReq;
     77        WaitReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     78        WaitReq.Hdr.cbReq = sizeof(WaitReq);
     79        WaitReq.pSession = pSession;
     80        WaitReq.hIf = hIf;
     81        WaitReq.cMillies = cMillies - (uint32_t)cElapsedMillies;
     82        int rc = SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_IF_WAIT, 0, &WaitReq.Hdr);
     83        if (rc == VERR_TIMEOUT)
     84            break;
     85        if (RT_FAILURE(rc))
     86        {
     87            g_cErrors++;
     88            RTPrintf("tstIntNet-1: VMMR0_DO_INTNET_IF_WAIT returned %Rrc\n", rc);
     89            break;
     90        }
     91
     92        /*
     93         * Process the receive buffer.
     94         */
     95        while (INTNETRingGetReadable(pRingBuf) > 0)
     96        {
     97            PINTNETHDR pHdr = (PINTNETHDR)((uintptr_t)pBuf + pRingBuf->offRead);
     98            if (pHdr->u16Type == INTNETHDR_TYPE_FRAME)
     99            {
     100                size_t      cbFrame = pHdr->cbFrame;
     101                const void *pvFrame = INTNETHdrGetFramePtr(pHdr, pBuf);
     102                uint64_t    NanoTS = RTTimeNanoTS() - StartTS;
     103
     104                if (pFileRaw)
     105                {
     106                }
     107
     108                if (pFileText)
     109                    RTStrmPrintf(pFileText, "%3RU64.%09u: cb=%04x dst=%.6Rhxs src=%.6Rhxs\n",
     110                                 NanoTS / 1000000000, (uint32_t)(NanoTS % 1000000000),
     111                                 cbFrame, pvFrame, (uint8_t *)pvFrame + 6);
     112            }
     113            else
     114            {
     115                RTPrintf("tstIntNet-1: Unknown frame type %d\n", pHdr->u16Type);
     116                g_cErrors++;
     117            }
     118
     119            /* Advance to the next frame. */
     120            INTNETRingSkipFrame(pBuf, pRingBuf);
     121        }
     122    }
     123
     124    uint64_t NanoTS = RTTimeNanoTS() - StartTS;
     125    RTStrmPrintf(pFileText ? pFileText : g_pStdOut,
     126                 "%3RU64.%09u: stopped. cRecvs=%RU64 cbRecv=%RU64 cLost=%RU64 cOYs=%RU64 cNYs=%RU64\n",
     127                 NanoTS / 1000000000, (uint32_t)(NanoTS % 1000000000),
     128                 pBuf->cStatRecvs.c,
     129                 pBuf->cbStatRecv.c,
     130                 pBuf->cStatLost.c,
     131                 pBuf->cStatYieldsOk.c,
     132                 pBuf->cStatYieldsNok.c
     133                 );
     134}
     135
     136
    44137int main(int argc, char **argv)
    45138{
    46139    /*
    47      * Init the runtime, open the support driver and load VMMR0.r0.
     140     * Init the runtime and parse the arguments.
    48141     */
    49142    RTR3Init(false, 0);
     143
     144    static RTOPTIONDEF const s_aOptions[] =
     145    {
     146        { "--duration",     'd', RTGETOPT_REQ_UINT32 },
     147        { "--file",         'f', RTGETOPT_REQ_STRING },
     148        { "--promiscuous",  'p', RTGETOPT_REQ_NOTHING },
     149        { "--recv-buffer",  'r', RTGETOPT_REQ_UINT32 },
     150        { "--send-buffer",  's', RTGETOPT_REQ_UINT32 },
     151        { "--sniffer",      'S', RTGETOPT_REQ_NOTHING },
     152        { "--text-file",    't', RTGETOPT_REQ_STRING },
     153        { "--xmit-test",    'x', RTGETOPT_REQ_NOTHING },
     154    };
     155
     156    uint32_t    cMillies = 1000;
     157    PRTSTREAM   pFileRaw = NULL;
     158#ifdef RT_OS_DARWIN
     159    const char *pszIf = "en0";
     160#elif defined(RT_OS_LINUX)
     161    const char *pszIf = "eth0";
     162#else
     163    const char *pszIf = "em0";
     164#endif
     165    bool        fPromiscuous = false;
     166    const char *pszNetwork = "tstIntNet-1";
     167    uint32_t    cbRecv = 0;
     168    uint32_t    cbSend = 0;
     169    bool        fSniffer = false;
     170    PRTSTREAM   pFileText = g_pStdOut;
     171    bool        fXmitTest = false;
     172
     173    int rc;
     174    int ch;
     175    int iArg = 1;
     176    RTOPTIONUNION Value;
     177    while ((ch = RTGetOpt(argc,argv, &s_aOptions[0], RT_ELEMENTS(s_aOptions), &iArg, &Value)))
     178        switch (ch)
     179        {
     180            case 'd':
     181                cMillies = Value.u32 * 1000;
     182                if (cMillies / 1000 != Value.u32)
     183                {
     184                    RTPrintf("tstIntNet-1: warning duration overflowed\n");
     185                    cMillies = UINT32_MAX - 1;
     186                }
     187                break;
     188
     189            case 'f':
     190                rc = RTStrmOpen(Value.psz, "w+b", &pFileRaw);
     191                if (RT_FAILURE(rc))
     192                {
     193                    RTPrintf("tstIntNet-1: Failed to creating \"%s\" for writing: %Rrc\n", Value.psz, rc);
     194                    return 1;
     195                }
     196                break;
     197
     198            case 'i':
     199                pszIf = Value.psz;
     200                if (strlen(pszIf) >= INTNET_MAX_TRUNK_NAME)
     201                {
     202                    RTPrintf("tstIntNet-1: Interface name is too long (max %d chars): %s\n", INTNET_MAX_TRUNK_NAME - 1, pszIf);
     203                    return 1;
     204                }
     205                break;
     206
     207            case 'n':
     208                pszNetwork = Value.psz;
     209                if (strlen(pszNetwork) >= INTNET_MAX_NETWORK_NAME)
     210                {
     211                    RTPrintf("tstIntNet-1: Network name is too long (max %d chars): %s\n", INTNET_MAX_NETWORK_NAME - 1, pszNetwork);
     212                    return 1;
     213                }
     214                break;
     215
     216            case 'p':
     217                fPromiscuous = true;
     218                break;
     219
     220            case 'r':
     221                cbRecv = Value.u32;
     222                break;
     223
     224            case 's':
     225                cbSend = Value.u32;
     226                break;
     227
     228            case 'S':
     229                fSniffer = true;
     230                break;
     231
     232            case 't':
     233                if (!*Value.psz)
     234                    pFileText = NULL;
     235                else if (!strcmp(Value.psz, "-"))
     236                    pFileText = g_pStdOut;
     237                else if (!strcmp(Value.psz, "!"))
     238                    pFileText = g_pStdErr;
     239                else
     240                {
     241                    rc = RTStrmOpen(Value.psz, "w", &pFileText);
     242                    if (RT_FAILURE(rc))
     243                    {
     244                        RTPrintf("tstIntNet-1: Failed to creating \"%s\" for writing: %Rrc\n", Value.psz, rc);
     245                        return 1;
     246                    }
     247                }
     248                break;
     249
     250            case 'x':
     251                fXmitTest = true;
     252                break;
     253
     254            case '?':
     255            case 'h':
     256                RTPrintf("syntax: tstIntNet-1 [-pSt] [-d <secs>] [-f <file>] [-r <size>] [-s <size>]\n");
     257                return 1;
     258
     259            default:
     260                if (RT_SUCCESS(ch))
     261                    RTPrintf("tstIntNetR0: invalid argument (%#x): %s\n", ch, Value.psz);
     262                else
     263                    RTPrintf("tstIntNetR0: invalid argument: %Rrc - \n", ch, Value.pDef->pszLong);
     264                return 1;
     265        }
     266    if (iArg < argc)
     267    {
     268        RTPrintf("tstIntNetR0: invalid argument: %s\n", argv[iArg]);
     269        return 1;
     270    }
     271
     272
    50273    RTPrintf("tstIntNet-1: TESTING...\n");
    51274
     
    54277     */
    55278    PSUPDRVSESSION pSession;
    56     int rc = SUPInit(&pSession, 0);
     279    rc = SUPInit(&pSession, 0);
    57280    if (RT_FAILURE(rc))
    58281    {
     
    83306    OpenReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    84307    OpenReq.Hdr.cbReq = sizeof(OpenReq);
    85     OpenReq.pSession = pSession; /* later */
    86     if (argc >= 2)
    87         strncpy(OpenReq.szNetwork, argv[2], sizeof(OpenReq.szNetwork));
    88     else
    89         strncpy(OpenReq.szNetwork, "tstIntNet-1", sizeof(OpenReq.szNetwork));
    90     if (argc >= 2)
    91         strncpy(OpenReq.szNetwork, argv[2], sizeof(OpenReq.szNetwork));
    92     else
    93 #ifdef RT_OS_DARWIN
    94         strncpy(OpenReq.szTrunk, "en0", sizeof(OpenReq.szTrunk));
    95 #elif defined(RT_OS_LINUX)
    96         strncpy(OpenReq.szTrunk, "eth0", sizeof(OpenReq.szTrunk));
    97 #else
    98         strncpy(OpenReq.szTrunk, "em0", sizeof(OpenReq.szTrunk));
    99 #endif
     308    OpenReq.pSession = pSession;
     309    strncpy(OpenReq.szNetwork, pszNetwork, sizeof(OpenReq.szNetwork));
     310    strncpy(OpenReq.szTrunk, pszIf, sizeof(OpenReq.szTrunk));
    100311    OpenReq.enmTrunkType = kIntNetTrunkType_NetFlt;
    101312    OpenReq.fFlags = 0;
    102     OpenReq.cbSend = 0;
    103     OpenReq.cbRecv = 0;
     313    OpenReq.cbSend = cbSend;
     314    OpenReq.cbRecv = cbRecv;
    104315    OpenReq.hIf = INTNET_HANDLE_INVALID;
    105316
     
    109320    RTPrintf("tstIntNet-1: attempting to open/create network \"%s\" with NetFlt trunk \"%s\"...\n",
    110321             OpenReq.szNetwork, OpenReq.szTrunk);
    111     RTThreadSleep(250);
     322    RTStrmFlush(g_pStdOut);
    112323    rc = SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_OPEN, 0, &OpenReq.Hdr);
    113324    if (RT_SUCCESS(rc))
    114325    {
    115         RTPrintf("tstIntNet-1: successfully opened/created \"%s\" with NetFlt trunk \"%s\" - hIf=%#x",
     326        RTPrintf("tstIntNet-1: successfully opened/created \"%s\" with NetFlt trunk \"%s\" - hIf=%#x\n",
    116327                 OpenReq.szNetwork, OpenReq.szTrunk, OpenReq.hIf);
    117 
     328        RTStrmFlush(g_pStdOut);
     329
     330        /*
     331         * Get the ring-3 address of the shared interface buffer.
     332         */
     333        INTNETIFGETRING3BUFFERREQ GetRing3BufferReq;
     334        GetRing3BufferReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     335        GetRing3BufferReq.Hdr.cbReq = sizeof(GetRing3BufferReq);
     336        GetRing3BufferReq.pSession = pSession;
     337        GetRing3BufferReq.hIf = OpenReq.hIf;
     338        GetRing3BufferReq.pRing3Buf = NULL;
     339        rc = SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_IF_GET_RING3_BUFFER, 0, &GetRing3BufferReq.Hdr);
     340        if (RT_SUCCESS(rc))
     341        {
     342            PINTNETBUF pBuf = GetRing3BufferReq.pRing3Buf;
     343            RTPrintf("tstIntNet-1: pBuf=%p cbBuf=%d cbSend=%d cbRecv=%d\n",
     344                     pBuf, pBuf->cbBuf, pBuf->cbSend, pBuf->cbRecv);
     345            RTStrmFlush(g_pStdOut);
     346            if (fPromiscuous)
     347            {
     348                INTNETIFSETPROMISCUOUSMODEREQ PromiscReq;
     349                PromiscReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     350                PromiscReq.Hdr.cbReq    = sizeof(PromiscReq);
     351                PromiscReq.pSession     = pSession;
     352                PromiscReq.hIf          = OpenReq.hIf;
     353                PromiscReq.fPromiscuous = true;
     354                rc = SUPCallVMMR0Ex(NIL_RTR0PTR, VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE, 0, &PromiscReq.Hdr);
     355                if (RT_SUCCESS(rc))
     356                    RTPrintf("tstIntNet-1: interface in promiscuous mode\n");
     357            }
     358            if (RT_SUCCESS(rc))
     359            {
     360                /*
     361                 * Either enter sniffing mode or do a timeout thing.
     362                 */
     363                if (fSniffer)
     364                    doPacketSniffing(OpenReq.hIf, pSession, pBuf, cMillies, pFileRaw, pFileText);
     365                else
     366                    RTThreadSleep(cMillies);
     367            }
     368            else
     369            {
     370                RTPrintf("tstIntNet-1: SUPCallVMMR0Ex(,VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE,) failed, rc=%Rrc\n", rc);
     371                g_cErrors++;
     372            }
     373        }
     374        else
     375        {
     376            RTPrintf("tstIntNet-1: SUPCallVMMR0Ex(,VMMR0_DO_INTNET_IF_GET_RING3_BUFFER,) failed, rc=%Rrc\n", rc);
     377            g_cErrors++;
     378        }
    118379    }
    119380    else
    120381    {
    121         RTPrintf("stdIntNet-1: SUPCallVMMR0Ex(,VMMR0_DO_INTNET_OPEN,) failed, rc=%Rrc\n", rc);
     382        RTPrintf("tstIntNet-1: SUPCallVMMR0Ex(,VMMR0_DO_INTNET_OPEN,) failed, rc=%Rrc\n", rc);
    122383        g_cErrors++;
    123384    }
    124385
    125     RTThreadSleep(1000);
    126386    SUPTerm(false /* not forced */);
     387
     388    /* close open files  */
     389    if (pFileRaw)
     390        RTStrmClose(pFileRaw);
     391    if (pFileText && pFileText != g_pStdErr && pFileText != g_pStdOut)
     392        RTStrmClose(pFileText);
    127393
    128394    /*
Note: See TracChangeset for help on using the changeset viewer.

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