VirtualBox

Changeset 12597 in vbox


Ignore:
Timestamp:
Sep 19, 2008 11:46:06 AM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
36840
Message:

Solaris/vboxnetflt: Implemented a dedicated promiscuous stream.

Location:
trunk/src/VBox/HostDrivers/VBoxNetFlt
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h

    r12008 r12597  
    154154             * @{ */
    155155            /** Pointer to the bound IP stream. */
    156             void *pvStream;
     156            void *pvIpStream;
    157157            /** Pointer to the bound ARP stream. */
    158158            void *pvArpStream;
     159            /** Pointer to the unbound promiscuous stream. */
     160            void *pvPromiscStream;
     161            /** Layered device handle to the interface. */
     162            ldi_handle_t hIface;
    159163            /** The MAC address of the interface. */
    160164            RTMAC Mac;
     
    168172#endif
    169173        /** Padding. */
    170         uint8_t abPadding[32];
     174        uint8_t abPadding[64];
    171175    } u;
    172176
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c

    r12531 r12597  
    274274    kUndefined = 0,
    275275    kIpStream = 0x1b,
    276     kArpStream = 0xab
     276    kArpStream = 0xab,
     277    kPromiscStream = 0xdf
    277278} VBOXNETFLTSTREAMTYPE;
    278279
     
    284285    int DevMinor;                         /* minor device no. (for clone) */
    285286    queue_t *pReadQueue;                  /* read side queue */
    286     queue_t *pArpReadQueue;               /* ARP read queue */
    287     struct vboxnetflt_state_t *pState;    /* state associated with this queue */
    288287    struct vboxnetflt_stream_t *pNext;    /* next stream in list */
    289288    bool fPromisc;                        /* cached promiscous value */
    290289    bool fRawMode;                        /* whether raw mode request was successful */
    291290    uint32_t ModeReqId;                   /* track MIOCTLs for swallowing our fake request acknowledgements */
    292     t_uscalar_t UnAckPrim;                /* unacknowledged primitive sent by this stream, again fake DL request tracking stuff  */
    293291    PVBOXNETFLTINS pThis;                 /* the backend instance */
    294292    VBOXNETFLTSTREAMTYPE Type;            /* the type of the stream Ip/Arp */
     
    322320static int vboxNetFltSolarisPhysAddrReq(queue_t *pQueue);
    323321static void vboxNetFltSolarisCachePhysAddr(PVBOXNETFLTINS pThis, mblk_t *pPhysAddrAckMsg);
     322static mblk_t *vboxNetFltSolarisBindReq(queue_t *pQueue, int SAP);
    324323
    325324static int vboxNetFltSolarisUnitDataToRaw(PVBOXNETFLTINS pThis, mblk_t *pMsg, mblk_t **ppRawMsg);
     
    393392
    394393                LogRel((DEVICE_NAME ":mod_install failed. rc=%d\n", rc));
    395                 vboxNetFltTryDeleteGlobals(&g_VBoxNetFltSolarisGlobals);               
     394                vboxNetFltTryDeleteGlobals(&g_VBoxNetFltSolarisGlobals);
    396395            }
    397396            else
     
    633632    pStream->DevMinor = DevMinor;
    634633    pStream->pReadQueue = pQueue;
    635     pStream->pArpReadQueue = NULL;
    636     pStream->pState = pState;
    637634    pStream->fPromisc = false;
    638635    pStream->fRawMode = false;
     
    645642    pStream->Type = pState->CurType;
    646643    if (pState->CurType == kIpStream)
    647         pState->pCurInstance->u.s.pvStream = pStream;
    648     else
     644        pState->pCurInstance->u.s.pvIpStream = pStream;
     645    else if (pState->CurType == kArpStream)
    649646        pState->pCurInstance->u.s.pvArpStream = pStream;
     647    else if (pState->CurType == kPromiscStream)
     648        pState->pCurInstance->u.s.pvPromiscStream = pStream;
    650649
    651650    pStream->ModeReqId = 0;
    652     pStream->UnAckPrim = 0;
    653651    pQueue->q_ptr = pStream;
    654652    WR(pQueue)->q_ptr = pStream;
     
    662660    qprocson(pQueue);
    663661
    664     /*
    665      * Request the physical address (we cache the acknowledgement).
    666      */
    667     if (pStream->Type == kIpStream)
     662    if (pStream->Type == kPromiscStream)
     663    {
     664        /*
     665         * Bind to SAP 0 (DL_ETHER).
     666         * Note: We don't support DL_TPR (token passing ring) SAP as that is
     667         * unnecessary asynchronous work to get DL_INFO_REQ acknowledgements
     668         * and determine SAP based on the Mac Type etc. Besides nobody uses
     669         * TPR anymore as far as I know.
     670         */
     671        vboxNetFltSolarisBindReq(pStream->pReadQueue, 0 /* SAP */);
     672
     673        /*
     674         * Request the physical address (we cache the acknowledgement).
     675         */
     676        /** @todo take a look at DLPI notifications additionally for these things. */
    668677        vboxNetFltSolarisPhysAddrReq(pStream->pReadQueue);
    669678
    670     /*
    671      * Enable raw mode.
    672      */
    673     if (pStream->Type == kIpStream)
     679        /*
     680         * Enable raw mode.
     681         */
    674682        vboxNetFltSolarisSetRawMode(pStream->pReadQueue);
     683    }
    675684
    676685    pStream->pThis->fDisconnectedFromHost = false;
     
    702711    vboxnetflt_stream_t *pStream = NULL;
    703712    vboxnetflt_stream_t **ppPrevStream = NULL;
    704     vboxnetflt_state_t *pState = NULL;
    705713
    706714    /*
     
    713721        return ENXIO;
    714722    }
    715     pState = pStream->pState;
    716     Assert(pState);
    717 
    718     /*
    719      * Enable native mode.
    720      */
    721     if (pStream->Type == kIpStream)
    722         vboxNetFltSolarisSetFastMode(pStream->pReadQueue);
    723723
    724724    pStream->pThis->fDisconnectedFromHost = true;
     
    728728     * Unlink it from the list of streams.
    729729     */
    730     for (ppPrevStream = &pState->pOpenedStreams; (pStream = *ppPrevStream) != NULL; ppPrevStream = &pStream->pNext)
     730    for (ppPrevStream = &g_VBoxNetFltSolarisState.pOpenedStreams; (pStream = *ppPrevStream) != NULL; ppPrevStream = &pStream->pNext)
    731731        if (pStream == (vboxnetflt_stream_t *)pQueue->q_ptr)
    732732            break;
     
    737737     */
    738738    if (pStream->Type == kIpStream)
    739         pStream->pThis->u.s.pvStream = NULL;
     739        pStream->pThis->u.s.pvIpStream = NULL;
     740    else if (pStream->Type == kArpStream)
     741        pStream->pThis->u.s.pvArpStream = NULL;
    740742    else
    741         pStream->pThis->u.s.pvArpStream = NULL;
     743        pStream->pThis->u.s.pvPromiscStream = NULL;
     744
    742745    RTMemFree(pStream);
    743746    pQueue->q_ptr = NULL;
     
    761764static int VBoxNetFltSolarisModReadPut(queue_t *pQueue, mblk_t *pMsg)
    762765{
    763     if (!pMsg)
    764         return 0;
    765 
    766     LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut pQueue=%p pMsg=%p\n"));
     766    LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut pQueue=%p pMsg=%p\n", pQueue, pMsg));
    767767
    768768    bool fSendUpstream = true;
     
    776776     */
    777777    if (   pStream
    778         && pStream->Type == kIpStream
     778        && pStream->Type == kPromiscStream
    779779        && pMsg)
    780780    {
     
    798798                    LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut M_DATA\n"));
    799799
    800                     if (fActive)
     800                    if (   fActive
     801                        && pStream->fRawMode)
    801802                    {
    802803                        vboxNetFltSolarisRecv(pThis, pStream, pQueue, pMsg);
     
    815816                    switch (Prim)
    816817                    {
     818#if 0
    817819                        case DL_UNITDATA_IND:
    818820                        {
     
    830832                            break;
    831833                        }
     834#endif
     835
     836                        case DL_BIND_ACK:
     837                        {
     838                            /*
     839                             * Swallow our bind request acknowledgement.
     840                             */
     841                            LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: DL_BIND_ACK. Bound to requested SAP!\n"));
     842                            freemsg(pMsg);
     843                            fSendUpstream = false;
     844                            break;
     845                        }
    832846
    833847                        case DL_PHYS_ADDR_ACK:
    834848                        {
     849                            /*
     850                             * Swallow our physical address request acknowledgement.
     851                             */
    835852                            vboxNetFltSolarisCachePhysAddr(pThis, pMsg);
    836 
    837                             /*
    838                              * Swallow our fake physical address request acknowledgement.
    839                              */
    840                             if (pStream->UnAckPrim == DL_PHYS_ADDR_REQ)
    841                             {
    842                                 freemsg(pMsg);
    843                                 fSendUpstream = false;
    844                             }
     853                            freemsg(pMsg);
     854                            fSendUpstream = false;
    845855                            break;
    846856                        }
     
    848858                        case DL_OK_ACK:
    849859                        {
     860                            /*
     861                             * Swallow our fake promiscous request acknowledgement.
     862                             */
    850863                            dl_ok_ack_t *pOkAck = (dl_ok_ack_t *)pMsg->b_rptr;
    851864                            if (pOkAck->dl_correct_primitive == DL_PROMISCON_REQ)
     
    860873                            }
    861874
    862                             /*
    863                              * Swallow our fake promiscous request acknowledgement.
    864                              */
    865                             if (pStream->UnAckPrim == pOkAck->dl_correct_primitive)
    866                             {
    867                                 freemsg(pMsg);
    868                                 fSendUpstream = false;
    869                             }
     875                            freemsg(pMsg);
     876                            fSendUpstream = false;
    870877                            break;
    871878                        }
     
    951958    PVBOXNETFLTINS pThis = NULL;
    952959
     960#if 0
    953961    /*
    954962     * In the unlikely case where VirtualBox crashed and this filter
     
    10591067                            LogRel((DEVICE_NAME ":VBoxNetFltSolarisModWritePut: Invalid header in fast path request!\n"));
    10601068                            miocnak(pQueue, pMsg, 0, ENOMEM);
    1061                             break;                               
     1069                            break;
    10621070                        }
    10631071
    10641072                        PRTNETETHERHDR pEthHdr = (PRTNETETHERHDR)pMsg->b_rptr;
    10651073                        bcopy(&pDLSapAddr->Mac, &pEthHdr->DstMac, sizeof(RTMAC));
    1066                         bcopy(&pThis->u.s.Mac, &pEthHdr->SrcMac, sizeof(RTMAC)); 
     1074                        bcopy(&pThis->u.s.Mac, &pEthHdr->SrcMac, sizeof(RTMAC));
    10671075                        pEthHdr->EtherType = RT_H2BE_U16(pDLSapAddr->SAP);
    10681076
     
    11121120            LogRel((DEVICE_NAME ":VBoxNetFltSolarisModWritePut: Could not find VirtualBox instance!!\n"));
    11131121    }
     1122#endif
     1123
    11141124
    11151125    if (   fSendDownstream
     
    11921202
    11931203
     1204#if 0
    11941205/**
    11951206 * Put the stream back in fast path mode.
     
    12351246    return VINF_SUCCESS;
    12361247}
     1248#endif
    12371249
    12381250
     
    12731285        return VERR_NO_MEMORY;
    12741286    }
    1275 
    1276     vboxnetflt_stream_t *pStream = pQueue->q_ptr;
    1277     pStream->UnAckPrim = Cmd;
    12781287
    12791288    if (fPromisc)
     
    13121321        return VERR_NO_MEMORY;
    13131322
    1314     vboxnetflt_stream_t *pStream = pQueue->q_ptr;
    1315     pStream->UnAckPrim = Cmd;
    1316 
    13171323    dl_phys_addr_req_t *pPhysAddrReq = (dl_phys_addr_req_t *)pPhysAddrMsg->b_rptr;
    13181324    pPhysAddrReq->dl_addr_type = DL_CURR_PHYS_ADDR;
    13191325
    13201326    qreply(pQueue, pPhysAddrMsg);
    1321     return VERR_GENERAL_FAILURE;
     1327    return VINF_SUCCESS;
    13221328}
    13231329
     
    13431349                    &pThis->u.s.Mac));
    13441350    }
     1351}
     1352
     1353
     1354/**
     1355 * Prepare DLPI bind request to a SAP.
     1356 *
     1357 * @returns Pointer to the request message.
     1358 */
     1359static mblk_t *vboxNetFltSolarisBindReq(queue_t *pQueue, int SAP)
     1360{
     1361    LogFlow((DEVICE_NAME ":vboxNetFltSolarisBindReq SAP=%u\n", SAP));
     1362
     1363    mblk_t *pBindMsg = mexchange(NULL, NULL, DL_BIND_REQ_SIZE, M_PROTO, DL_BIND_REQ);
     1364    if (RT_UNLIKELY(!pBindMsg))
     1365        return NULL;
     1366
     1367    dl_bind_req_t *pBindReq = (dl_bind_req_t *)pBindMsg->b_rptr;
     1368    pBindReq->dl_sap = SAP;
     1369    pBindReq->dl_max_conind = 0;
     1370    pBindReq->dl_conn_mgmt = 0;
     1371    pBindReq->dl_xidtest_flg = 0;
     1372    pBindReq->dl_service_mode = DL_CLDLS;
     1373
     1374    qreply(pQueue, pBindMsg);
     1375    return VINF_SUCCESS;
    13451376}
    13461377
     
    15741605
    15751606/**
     1607 * Opens up dedicated stream on top of the interface.
     1608 * As a side-effect, the stream gets opened during
     1609 * the I_PUSH phase.
     1610 *
     1611 */
     1612static int vboxNetFltSolarisOpenStream(PVBOXNETFLTINS pThis)
     1613{
     1614    ldi_ident_t DevId;
     1615    DevId = ldi_ident_from_anon();
     1616    int ret;
     1617
     1618    char szDev[128];
     1619    RTStrPrintf(szDev, sizeof(szDev), "/dev/%s", pThis->szName);
     1620
     1621    int rc = ldi_open_by_name(szDev, FREAD | FWRITE, kcred, &pThis->u.s.hIface, DevId);
     1622    ldi_ident_release(DevId);
     1623    if (rc)
     1624    {
     1625        LogRel((DEVICE_NAME ":vboxNetFltSolarisOpenStream Failed to open '%s'\n", szDev));
     1626        return VERR_INTNET_FLT_IF_FAILED;
     1627    }
     1628
     1629    rc = ldi_ioctl(pThis->u.s.hIface, I_FIND, (intptr_t)DEVICE_NAME, FKIOCTL, kcred, &ret);
     1630    if (!rc)
     1631    {
     1632        if (!ret)
     1633        {
     1634            g_VBoxNetFltSolarisState.pCurInstance = pThis;
     1635            g_VBoxNetFltSolarisState.CurType = kPromiscStream;
     1636
     1637            rc = ldi_ioctl(pThis->u.s.hIface, I_PUSH, (intptr_t)DEVICE_NAME, FKIOCTL, kcred, &ret);
     1638
     1639            g_VBoxNetFltSolarisState.pCurInstance = NULL;
     1640            g_VBoxNetFltSolarisState.CurType = kUndefined;
     1641
     1642            if (!rc)
     1643                return VINF_SUCCESS;
     1644
     1645            LogRel((DEVICE_NAME ":vboxNetFltSolarisOpenStream Failed to push filter onto host interface '%s'\n", pThis->szName));
     1646        }
     1647        else
     1648            return VINF_SUCCESS;
     1649    }
     1650    else
     1651        LogRel((DEVICE_NAME ":vboxNetFltSolarisOpenStream Failed to search for filter in interface '%s'.\n", pThis->szName));
     1652
     1653    return VERR_INTNET_FLT_IF_FAILED;
     1654}
     1655
     1656
     1657/**
     1658 * De-activates the dedicated promiscuous stream.
     1659 */
     1660static void vboxNetFltSolarisCloseStream(PVBOXNETFLTINS pThis)
     1661{
     1662    ldi_close(pThis->u.s.hIface, FREAD | FWRITE, kcred);
     1663}
     1664
     1665
     1666/**
    15761667 * Dynamically attaches this streams module on to the host stack.
    1577  * As a side-effect, this streams also gets opened/closed during
     1668 * As a side-effect, the streams also gets opened/closed during
    15781669 * the actual injection/ejection phase.
    15791670 *
     
    18191910    AssertRC(rc);
    18201911
    1821     rc = vboxNetFltSolarisModSetup(pThis, true);
     1912    rc = vboxNetFltSolarisOpenStream(pThis);
     1913    if (RT_SUCCESS(rc))
     1914        rc = vboxNetFltSolarisModSetup(pThis, true);
     1915    else
     1916        LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface vboxNetFltSolarisOpenStream failed rc=%Vrc\n", rc));
    18221917
    18231918    RTSemFastMutexRelease(g_VBoxNetFltSolarisMtx);
     
    18391934    AssertRC(rc);
    18401935
     1936    vboxNetFltSolarisCloseStream(pThis);
    18411937    rc = vboxNetFltSolarisModSetup(pThis, false);
    18421938
     
    21322228
    21332229    AssertCompile(sizeof(struct ether_header) == sizeof(RTNETETHERHDR));
    2134     Assert(pStream->Type == kIpStream);
    2135 
    2136     /*
    2137      * Due to the asynchronous nature of streams we may get messages before the
    2138      * raw mode is turned on, in this case just pass through.
    2139      */
    2140     if (!pStream->fRawMode)
    2141     {
    2142         LogFlow((DEVICE_NAME ":IP stream not yet in raw mode. Passing through packet.\n"));
    2143         putnext(pQueue, pOrigMsg);
     2230    Assert(pStream->Type == kPromiscStream);
     2231
     2232    mblk_t *pMsg = pOrigMsg;
     2233
     2234    /*
     2235     * Don't loopback packets we transmit to the wire.
     2236     */
     2237    /** @todo -XXX- fix this with proper loopback handling. We must not be using unspecified flags. */
     2238    if (pMsg->b_flag & MSGNOLOOP)
     2239    {
     2240        LogFlow((DEVICE_NAME ":Avoiding packet loopback.\n"));
     2241        freemsg(pMsg);
    21442242        return VINF_SUCCESS;
    2145     }
    2146 
    2147     /*
    2148      * Make a copy as we will alter pMsg.
    2149      */
    2150     mblk_t *pMsg = copymsg(pOrigMsg);
    2151 
    2152     /*
    2153      * Sort out M_PROTO and M_DATA.
    2154      */
    2155     bool fOriginalIsRaw = true;
    2156     if (DB_TYPE(pMsg) == M_PROTO)
    2157     {
    2158         fOriginalIsRaw = false;
    2159         mblk_t *pRawMsg;
    2160         int rc = vboxNetFltSolarisUnitDataToRaw(pThis, pMsg, &pRawMsg);
    2161         if (RT_SUCCESS(rc))
    2162             pMsg = pRawMsg;
    2163         else
    2164         {
    2165             freemsg(pMsg);
    2166             LogRel((DEVICE_NAME ":vboxNetFltSolarisRecv invalid message!\n"));
    2167             return VERR_GENERAL_FAILURE;
    2168         }
    21692243    }
    21702244
     
    21782252        fSrc = INTNETTRUNKDIR_HOST;
    21792253
    2180     bool fChecksumAdjusted = false;
    2181 #if 1
    21822254    if (fSrc & INTNETTRUNKDIR_HOST)
    21832255    {
    21842256        mblk_t *pCorrectedMsg = vboxNetFltSolarisFixChecksums(pMsg);
    21852257        if (pCorrectedMsg)
    2186         {
    2187             fChecksumAdjusted = true;
    21882258            pMsg = pCorrectedMsg;
    2189         }
    2190     }
    2191 #endif
     2259    }
     2260
     2261    vboxNetFltSolarisAnalyzeMBlk(pMsg);
    21922262
    21932263    /*
     
    21972267    PINTNETSG pSG = (PINTNETSG)alloca(RT_OFFSETOF(INTNETSG, aSegs[cSegs]));
    21982268    int rc = vboxNetFltSolarisMBlkToSG(pThis, pMsg, pSG, cSegs, fSrc);
    2199     if (RT_FAILURE(rc))
    2200     {
     2269    if (RT_SUCCESS(rc))
     2270        pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, fSrc);
     2271    else
    22012272        LogRel((DEVICE_NAME ":vboxNetFltSolarisMBlkToSG failed. rc=%d\n", rc));
    2202         return rc;
    2203     }
    2204 
    2205     bool fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, fSrc);
    2206 
    2207     /*
    2208      * Drop messages consumed by the internal network.
    2209      */
    2210     if (fDropIt)
    2211     {
    2212         LogFlow((DEVICE_NAME ":vboxNetFltSolarisRecv Packet consumed by internal network.\n"));
    2213         freemsg(pOrigMsg);
    2214         freemsg(pMsg);
    2215     }
    2216     else
    2217     {
    2218         /*
    2219          * Packets from the host, push them up in raw mode.
    2220          * Packets from the wire, we must push them in their original form
    2221          * as upstream consumers expect this format.
    2222          */
    2223         if (fSrc & INTNETTRUNKDIR_HOST)
    2224         {
    2225             /* Raw packets with correct checksums, pass-through the original */
    2226             if (    fOriginalIsRaw
    2227                 && !fChecksumAdjusted)
    2228             {
    2229                 putnext(pQueue, pOrigMsg);
    2230             }
    2231             else    /* For M_PROTO packets or checksum corrected raw packets, pass-through the raw */
    2232             {
    2233                 putnext(pQueue, pMsg);
    2234                 pMsg = pOrigMsg;        /* for the freemsg that follows */
    2235             }
    2236         }
    2237         else    /* INTNETTRUNKDIR_WIRE */
    2238         {
    2239             if (fOriginalIsRaw)
    2240                 pOrigMsg->b_rptr += sizeof(RTNETETHERHDR);
    2241 
    2242             putnext(pQueue, pOrigMsg);
    2243         }
    2244 
    2245         freemsg(pMsg);
    2246     }
    2247 
     2273
     2274    freemsg(pMsg);
    22482275    return VINF_SUCCESS;
    22492276}
     
    23172344            {
    23182345                LogRel((DEVICE_NAME ":vboxNetFltSolarisFixChecksums failed to alloc new message of %d bytes.\n", cbFullMsg));
    2319                 return false;
     2346                return NULL;
    23202347            }
    23212348
     
    23272354                    pFullMsg->b_wptr += MBLKL(pTmp);
    23282355                }
    2329                 else
    2330                     LogFlow((DEVICE_NAME ":Not M_DATA.. this is really bad.\n"));
    23312356            }
    23322357
     
    23422367         */
    23432368        PRTNETIPV4 pIpHdr = (PRTNETIPV4)(pEthHdr + 1);
    2344         if (!RTNetIPv4IsHdrValid(pIpHdr, cbIpPacket, cbIpPacket))
    2345         {
    2346             LogFlow((DEVICE_NAME ":Invalid IP checksum detected. Trying to fix...\n"));
    2347 
    2348             /*
    2349              * Fix up TCP/UDP and IP checksums if they're incomplete/invalid.
    2350              */
    2351             if (pIpHdr->ip_p == RTNETIPV4_PROT_TCP)
     2369        bool fChecksumAdjusted = false;
     2370
     2371        /*
     2372         * Fix up TCP/UDP and IP checksums if they're incomplete/invalid.
     2373         */
     2374        if (pIpHdr->ip_p == RTNETIPV4_PROT_TCP)
     2375        {
     2376            size_t cbTcpPacket = cbIpPacket - (pIpHdr->ip_hl << 2);
     2377
     2378            PRTNETTCP pTcpHdr = (PRTNETTCP)((uint32_t *)(pIpHdr + pIpHdr->ip_hl));
     2379            if (!RTNetIPv4IsTCPValid(pIpHdr, pTcpHdr, cbTcpPacket, NULL, cbTcpPacket))
    23522380            {
    2353                 size_t cbTcpPacket = cbIpPacket - (pIpHdr->ip_hl << 2);
    2354 
    2355                 PRTNETTCP pTcpHdr = (PRTNETTCP)(pIpHdr + 1);
    2356                 if (!RTNetIPv4IsTCPValid(pIpHdr, pTcpHdr, cbTcpPacket, NULL, cbTcpPacket))
    2357                 {
    2358                     RTNetIPv4TCPChecksum(pIpHdr, pTcpHdr, NULL);
    2359                     LogFlow((DEVICE_NAME ":fixed TCP checkum.\n"));
    2360                 }
    2361                 else
    2362                     LogFlow((DEVICE_NAME ":valid TCP checksum invalid IP checksum...\n"));
     2381                pTcpHdr->th_sum = RTNetIPv4TCPChecksum(pIpHdr, pTcpHdr, NULL);
     2382                fChecksumAdjusted = true;
     2383                LogFlow((DEVICE_NAME ":fixed TCP checkum.\n"));
    23632384            }
    2364             else if (pIpHdr->ip_p == RTNETIPV4_PROT_UDP)
     2385
     2386            if (!RTNetIPv4IsHdrValid(pIpHdr, cbIpPacket, cbIpPacket))
    23652387            {
    2366                 size_t cbUdpPacket = cbIpPacket - (pIpHdr->ip_hl << 2);
    2367 
    2368                 PRTNETUDP pUdpHdr = (PRTNETUDP)(pIpHdr + 1);
    2369                 RTNetIPv4UDPChecksum(pIpHdr, pUdpHdr, pUdpHdr + 1);
    2370 
    2371                 LogFlow((DEVICE_NAME ":fixed UDP checksum.\n"));
     2388                pIpHdr->ip_sum = RTNetIPv4HdrChecksum(pIpHdr);
     2389                fChecksumAdjusted = true;
     2390                LogFlow((DEVICE_NAME ":fixed IP checkum.\n"));
    23722391            }
    2373             else
     2392        }
     2393        else if (pIpHdr->ip_p == RTNETIPV4_PROT_UDP)
     2394        {
     2395            size_t cbUdpPacket = cbIpPacket - (pIpHdr->ip_hl << 2);
     2396            PRTNETUDP pUdpHdr = (PRTNETUDP)((uint32_t *)pIpHdr + pIpHdr->ip_hl);
     2397            uint16_t UdpChecksum = RTNetIPv4UDPChecksum(pIpHdr, pUdpHdr, pUdpHdr + 1);
     2398
     2399            if (pUdpHdr->uh_sum != UdpChecksum)
    23742400            {
    2375                 LogFlow((DEVICE_NAME ":Non TCP/UDP protocol with invalid IP header!\n"));
     2401                pUdpHdr->uh_sum = UdpChecksum;
     2402                fChecksumAdjusted = true;
     2403                LogFlow((DEVICE_NAME ":Invalid UDP checksum!!"));
    23762404            }
    23772405
    2378             RTNetIPv4HdrChecksum(pIpHdr);
    2379             LogFlow((DEVICE_NAME ":fixed IP checkum.\n"));
    2380 
     2406            if (!RTNetIPv4IsHdrValid(pIpHdr, cbIpPacket, cbIpPacket))
     2407            {
     2408                pIpHdr->ip_sum = RTNetIPv4HdrChecksum(pIpHdr);
     2409                fChecksumAdjusted = true;
     2410                LogFlow((DEVICE_NAME ":fixed IP checkum.\n"));
     2411            }
     2412        }
     2413
     2414        if (fChecksumAdjusted)
     2415        {
    23812416            /*
    23822417             * If we made a copy and the checksum is corrected on the copy,
     
    23982433        if (pFullMsg)
    23992434            freemsg(pFullMsg);
     2435
     2436        return NULL;
    24002437    }
    24012438
     
    24112448static void vboxNetFltSolarisAnalyzeMBlk(mblk_t *pMsg)
    24122449{
    2413     LogFlow((DEVICE_NAME ":vboxNetFltSolarisAnalyzeMBlk pMsg=%p\n"));
     2450    LogFlow((DEVICE_NAME ":vboxNetFltSolarisAnalyzeMBlk pMsg=%p\n", pMsg));
    24142451
    24152452    PCRTNETETHERHDR pEthHdr = (PCRTNETETHERHDR)pMsg->b_rptr;
     
    24192456        PRTNETIPV4 pIpHdr = (PRTNETIPV4)(pEthHdr + 1);
    24202457        size_t cbLen = MBLKL(pMsg) - sizeof(*pEthHdr);
    2421         if (RTNetIPv4IsHdrValid(pIpHdr, cbLen, cbLen))
     2458        if (!pMsg->b_cont)
    24222459        {
    24232460            if (pIpHdr->ip_p == RTNETIPV4_PROT_ICMP)
     
    24262463                LogFlow((DEVICE_NAME ":TCP D=%.6Rhxs  S=%.6Rhxs\n", pb, pb + 6));
    24272464            else if (pIpHdr->ip_p == RTNETIPV4_PROT_UDP)
    2428                 LogFlow((DEVICE_NAME ":UDP D=%.6Rhxs  S=%.6Rhxs\n", pb, pb + 6));
    2429         }
    2430         else if (!pMsg->b_cont)
    2431         {
    2432             LogFlow((DEVICE_NAME ":Invalid IP header.\n"));
     2465            {
     2466                PCRTNETUDP pUdpHdr = (PCRTNETUDP)((uint32_t *)pIpHdr + pIpHdr->ip_hl);
     2467                if (   RT_BE2H_U16(pUdpHdr->uh_sport) == 67
     2468                    && RT_BE2H_U16(pUdpHdr->uh_dport) == 68)
     2469                {
     2470                    LogFlow((DEVICE_NAME ":UDP bootp ack D=%.6Rhxs S=%.6Rhxs UDP_CheckSum=%04x Computex=%04x\n", pb, pb + 6,
     2471                                RT_BE2H_U16(pUdpHdr->uh_sum), RT_BE2H_U16(RTNetIPv4UDPChecksum(pIpHdr, pUdpHdr, pUdpHdr + 1))));
     2472                }
     2473            }
    24332474        }
    24342475        else
    24352476        {
    2436             LogFlow((DEVICE_NAME ":Chained IP packet. Skipped validity check.\n"));
     2477            LogFlow((DEVICE_NAME ":Chained IP packet. Skipping validity check.\n"));
    24372478        }
    24382479    }
     
    24442485    else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPV6))
    24452486    {
    2446         LogFlow((DEVICE_NAME ":IPv6 D=%.6Rhxs S=%.6Rhxs\n", pb, pb + 6));       
     2487        LogFlow((DEVICE_NAME ":IPv6 D=%.6Rhxs S=%.6Rhxs\n", pb, pb + 6));
    24472488    }
    24482489    else if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPX_1)
     
    24512492    {
    24522493        LogFlow((DEVICE_NAME ":IPX packet.\n"));
    2453     }   
     2494    }
    24542495    else
    24552496    {
     
    24642505bool vboxNetFltPortOsIsPromiscuous(PVBOXNETFLTINS pThis)
    24652506{
    2466     vboxnetflt_stream_t *pStream = pThis->u.s.pvStream;
    2467     if (pStream)
    2468         return pStream->fPromisc;
    2469 
    2470     LogRel((DEVICE_NAME ":vboxNetFltPortOsIsPromiscuous stream not found!!\n"));
     2507    /*
     2508     * There is no easy way of obtaining the global host side promiscuous counter.
     2509     * Currently we just return false.
     2510     */
    24712511    return false;
    24722512}
     
    25092549     * Enable/disable promiscuous mode.
    25102550     */
    2511     vboxnetflt_stream_t *pStream = pThis->u.s.pvStream;
     2551    vboxnetflt_stream_t *pStream = pThis->u.s.pvPromiscStream;
    25122552    if (pStream)
    25132553    {
     
    25542594     * Init. the solaris specific data.
    25552595     */
    2556     pThis->u.s.pvStream = NULL;
     2596    pThis->u.s.pvIpStream = NULL;
    25572597    pThis->u.s.pvArpStream = NULL;
     2598    pThis->u.s.pvPromiscStream = NULL;
    25582599    bzero(&pThis->u.s.Mac, sizeof(pThis->u.s.Mac));
    25592600    return VINF_SUCCESS;
     
    25752616    LogFlow((DEVICE_NAME ":vboxNetFltPortOsXmit pThis=%p pSG=%p fDst=%d\n", pThis, pSG, fDst));
    25762617
    2577     vboxnetflt_stream_t *pStream = pThis->u.s.pvStream;
    2578     queue_t *pReadQueue = pStream->pReadQueue;
    2579     queue_t *pWriteQueue = WR(pReadQueue);
    2580 
    25812618    /*
    25822619     * Create a message block and send it down the wire (downstream).
     
    25842621    if (fDst & INTNETTRUNKDIR_WIRE)
    25852622    {
     2623        vboxnetflt_stream_t *pPromiscStream = pThis->u.s.pvPromiscStream;
     2624        queue_t *pPromiscWriteQueue = WR(pPromiscStream->pReadQueue);
     2625
    25862626        mblk_t *pMsg = vboxNetFltSolarisMBlkFromSG(pThis, pSG, fDst);
    25872627        if (RT_UNLIKELY(!pMsg))
     
    25912631        }
    25922632
    2593         LogFlow((DEVICE_NAME ":vboxNetFltPortOsXmit INTNETTRUNKDIR_WIRE\n", pMsg));
    2594         putnext(pWriteQueue, pMsg);
     2633        LogFlow((DEVICE_NAME ":vboxNetFltPortOsXmit INTNETTRUNKDIR_WIRE %u\n", DB_CKSUM16(pMsg)));
     2634
     2635        /*
     2636         * Flag for avoiding loopback. (Should be fixed later)
     2637         */
     2638        pMsg->b_flag |= MSGNOLOOP;
     2639        putnext(pPromiscWriteQueue, pMsg);
    25952640    }
    25962641
     
    26412686             * Send messages up IP stream.
    26422687             */
    2643             putnext(pReadQueue, pMsg);
     2688            vboxnetflt_stream_t *pIpStream = pThis->u.s.pvIpStream;
     2689            queue_t *pIpReadQueue = pIpStream->pReadQueue;
     2690            putnext(pIpReadQueue, pMsg);
    26442691        }
    26452692    }
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