Changeset 11072 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Aug 1, 2008 10:24:51 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 33974
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
r11069 r11072 171 171 * This may be NULL if we're orphaned? */ 172 172 struct INTNETNETWORK *pNetwork; 173 /** The cached MAC address of the interface the trunk is attached to. 174 * This is for the situations where we cannot take the out-bound 175 * semaphore (the recv case) but need to make frame edits (ARP). */ 176 RTMAC CachedMac; 173 177 /** Whether to supply physical addresses with the outbound SGs. */ 174 178 bool volatile fPhysSG; … … 331 335 332 336 /** 337 * Worker for intnetR0SgWritePart that deals with the case where the 338 * request doesn't fit into the first segment. 339 * 340 * @returns true, unless the request or SG invalid. 341 * @param pSG The SG list to write to. 342 * @param off Where to start writing (offset into the SG). 343 * @param cb How much to write. 344 * @param pvBuf The buffer to containing the bits to write. 345 */ 346 static bool intnetR0SgWritePartSlow(PCINTNETSG pSG, uint32_t off, uint32_t cb, void const *pvBuf) 347 { 348 if (RT_UNLIKELY(off + cb > pSG->cbTotal)) 349 return false; 350 351 /* 352 * Skip ahead to the segment where off starts. 353 */ 354 unsigned const cSegs = pSG->cSegsUsed; Assert(cSegs == pSG->cSegsUsed); 355 unsigned iSeg = 0; 356 while (off > pSG->aSegs[iSeg].cb) 357 { 358 off -= pSG->aSegs[iSeg++].cb; 359 AssertReturn(iSeg < cSegs, false); 360 } 361 362 /* 363 * Copy the data, hoping that it's all from one segment... 364 */ 365 uint32_t cbCanCopy = pSG->aSegs[iSeg].cb - off; 366 if (cbCanCopy >= cb) 367 memcpy((uint8_t *)pSG->aSegs[iSeg].pv + off, pvBuf, cb); 368 else 369 { 370 /* copy the portion in the current segment. */ 371 memcpy((uint8_t *)pSG->aSegs[iSeg].pv + off, pvBuf, cbCanCopy); 372 cb -= cbCanCopy; 373 374 /* copy the portions in the other segments. */ 375 do 376 { 377 pvBuf = (uint8_t const *)pvBuf + cbCanCopy; 378 iSeg++; 379 AssertReturn(iSeg < cSegs, false); 380 381 cbCanCopy = RT_MIN(cb, pSG->aSegs[iSeg].cb); 382 memcpy(pSG->aSegs[iSeg].pv, pvBuf, cbCanCopy); 383 384 cb -= cbCanCopy; 385 } while (cb > 0); 386 } 387 388 return true; 389 } 390 391 392 /** 393 * Writes to a part of an SG. 394 * 395 * @returns true on success, false on failure (out of bounds). 396 * @param pSG The SG list to write to. 397 * @param off Where to start writing (offset into the SG). 398 * @param cb How much to write. 399 * @param pvBuf The buffer to containing the bits to write. 400 */ 401 DECLINLINE(bool) intnetR0SgWritePart(PCINTNETSG pSG, uint32_t off, uint32_t cb, void const *pvBuf) 402 { 403 Assert(off + cb > off); 404 405 /* The optimized case. */ 406 if (RT_LIKELY( pSG->cSegsUsed == 1 407 || pSG->aSegs[0].cb >= off + cb)) 408 { 409 Assert(pSG->cbTotal == pSG->aSegs[0].cb); 410 memcpy((uint8_t *)pSG->aSegs[0].pv + off, pvBuf, cb); 411 return true; 412 } 413 return intnetR0SgWritePartSlow(pSG, off, cb, pvBuf); 414 } 415 416 417 /** 333 418 * Reads a byte from a SG list. 334 419 * … … 399 484 400 485 cbCanCopy = RT_MIN(cb, pSG->aSegs[iSeg].cb); 401 memcpy(pvBuf, (uint8_t const *)pSG->aSegs[iSeg].pv + off, cbCanCopy);486 memcpy(pvBuf, (uint8_t const *)pSG->aSegs[iSeg].pv, cbCanCopy); 402 487 403 488 cb -= cbCanCopy; … … 749 834 static void intnetR0IfAddrCacheDeleteIt(PINTNETIF pIf, PINTNETADDRCACHE pCache, int iEntry, const char *pszMsg) 750 835 { 836 #if 0 /** @todo the inbound ARP snooping is busted. */ 751 837 Log(("intnetR0IfAddrCacheDeleteIt: hIf=%RX32 type=%d #%d %.*Rhxs %s\n", pIf->hIf, 752 838 (int)(intptr_t)(pCache - &pIf->aAddrCache[0]), iEntry, pCache->cbAddress, … … 758 844 pCache->pbEntries + (iEntry + 1) * pCache->cbEntry, 759 845 (pCache->cEntries - iEntry) * pCache->cbEntry); 846 #endif 760 847 } 761 848 … … 769 856 * @param cbAddr The address size (optimization). 770 857 */ 771 DECLINLINE(void) intnetR0IfAddrCacheDelete(PINTNETIF pIf, PINTNETADDRCACHE pCache, PCRTNETADDRU pAddr, uint8_t const cbAddr )858 DECLINLINE(void) intnetR0IfAddrCacheDelete(PINTNETIF pIf, PINTNETADDRCACHE pCache, PCRTNETADDRU pAddr, uint8_t const cbAddr, const char *pszMsg) 772 859 { 773 860 int i = intnetR0IfAddrCacheLookup(pCache, pAddr, cbAddr); 774 861 if (RT_UNLIKELY(i >= 0)) 775 intnetR0IfAddrCacheDeleteIt(pIf, pCache, i, "if");862 intnetR0IfAddrCacheDeleteIt(pIf, pCache, i, pszMsg); 776 863 } 777 864 … … 823 910 intnetR0IfAddrCacheDeleteIt(pIf, &pIf->aAddrCache[enmType], i, pszMsg); 824 911 } 912 } 913 914 915 /** 916 * Lookup an address on the network, returning the (first) interface 917 * having it in its address cache. 918 * 919 * @returns Pointer to the interface on success, NULL if not found. 920 * @param pNetwork The network. 921 * @param pAddr The address to lookup. 922 * @param enmType The address type. 923 * @param cbAddr The size of the address. 924 */ 925 DECLINLINE(PINTNETIF) intnetR0NetworkAddrCacheLookupIf(PINTNETNETWORK pNetwork, PCRTNETADDRU pAddr, INTNETADDRTYPE const enmType, uint8_t const cbAddr) 926 { 927 for (PINTNETIF pIf = pNetwork->pIFs; pIf; pIf = pIf->pNext) 928 { 929 int i = intnetR0IfAddrCacheLookup(&pIf->aAddrCache[enmType], pAddr, cbAddr); 930 if (i >= 0) 931 return pIf; 932 } 933 return NULL; 825 934 } 826 935 … … 1024 1133 if (RT_UNLIKELY( ar_oper != RTNET_ARPOP_REQUEST 1025 1134 && ar_oper != RTNET_ARPOP_REPLY 1135 /* These doesn't interest us at the moment since they are rarely used on ethernet: 1026 1136 && ar_oper != RTNET_ARPOP_REVREQUEST 1027 1137 && ar_oper != RTNET_ARPOP_REVREPLY 1028 /** @todo Read up on inverse ARP. */ 1138 && ar_oper != RTNET_ARPOP_INVREQUEST 1139 && ar_oper != RTNET_ARPOP_INVREPLY */ 1029 1140 )) 1030 1141 return; … … 1049 1160 intnetR0NetworkAddrCacheDelete(pNetwork, &Addr, kIntNetAddrType_IPv4, sizeof(pReq->ar_spa), "tif/arp"); 1050 1161 } 1051 #if 0 /** @todo IPv6 support */ 1052 else if (ar_ptype == RT_H2BE_U16(RTNET_ETHERTYPE_IPV6)) 1053 { 1054 /* 1055 * IPv6. 1056 */ 1057 PCINTNETARPIPV6 pReq = (PCINTNETARPIPV6)pHdr; 1058 if (RT_UNLIKELY( pHdr->ar_plen != sizeof(pReq->ar_spa) 1059 || cbPacket < sizeof(*pReq) 1060 || !intnetR0IPv6AddrIsGood(&pReq->ar_spa))) 1061 return; 1062 1063 Addr.IPv6 = pReq->ar_spa; 1064 intnetR0NetworkAddrCacheDelete(pNetwork, &Addr, kIntNetAddrType_IPv6, sizeof(pReq->ar_spa), "tif/arp"); 1065 } 1162 #if 0 /** @todo IPv6 ARP support? Is it used at all? */ 1066 1163 #endif 1067 1164 else … … 1198 1295 * @param cbPacket The size of the packet (migth be larger than the ARP 1199 1296 * request 'cause of min ethernet frame size). 1200 */ 1201 static void intnetR0IfSnoopArpAddr(PINTNETIF pIf, PCRTNETARPHDR pHdr, uint32_t cbPacket) 1297 * @param pfSgFlags Pointer to the SG flags. This is used to tag the packet so we 1298 * don't have to repeat the frame parsing in intnetR0TrunkIfSend. 1299 */ 1300 static void intnetR0IfSnoopArpAddr(PINTNETIF pIf, PCRTNETARPHDR pHdr, uint32_t cbPacket, uint16_t *pfSgFlags) 1202 1301 { 1203 1302 /* … … 1211 1310 if (RT_UNLIKELY( ar_oper != RTNET_ARPOP_REQUEST 1212 1311 && ar_oper != RTNET_ARPOP_REPLY 1312 /* These doesn't interest us at the moment since they are rarely used on ethernet: 1213 1313 && ar_oper != RTNET_ARPOP_REVREQUEST 1214 1314 && ar_oper != RTNET_ARPOP_REVREPLY 1215 /** @todo Read up on inverse ARP. */ 1315 && ar_oper != RTNET_ARPOP_INVREQUEST 1316 && ar_oper != RTNET_ARPOP_INVREPLY */ 1216 1317 )) 1217 1318 return; … … 1229 1330 PCRTNETARPIPV4 pReq = (PCRTNETARPIPV4)pHdr; 1230 1331 if (RT_UNLIKELY( pHdr->ar_plen != sizeof(pReq->ar_spa) 1231 || cbPacket < sizeof(*pReq) 1232 || !intnetR0IPv4AddrIsGood(pReq->ar_spa))) 1332 || cbPacket < sizeof(*pReq))) 1233 1333 return; 1234 1235 if ( RTNET_ARPOP_IS_REPLY(RT_BE2H_U16(pHdr->ar_oper)) 1334 *pfSgFlags |= INTNETSG_FLAGS_ARP_IPV4; 1335 /** @todo should check the MAC addresses here. */ 1336 if ( RTNET_ARPOP_IS_REPLY(ar_oper) 1236 1337 && intnetR0IPv4AddrIsGood(pReq->ar_tpa)) 1237 1338 { 1238 1339 Addr.IPv4 = pReq->ar_tpa; 1239 intnetR0IfAddrCacheDelete(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv4], &Addr, sizeof(pReq->ar_tpa) );1340 intnetR0IfAddrCacheDelete(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv4], &Addr, sizeof(pReq->ar_tpa), "if/arp"); 1240 1341 } 1241 Addr.IPv4 = pReq->ar_spa; 1242 intnetR0IfAddrCacheAdd(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv4], &Addr, sizeof(pReq->ar_spa), "if/arp"); 1243 } 1244 #if 0 /** @todo IPv6 support */ 1245 else if (ar_ptype == RT_H2BE_U16(RTNET_ETHERTYPE_IPV6)) 1246 { 1247 /* 1248 * IPv6. 1249 */ 1250 PCINTNETARPIPV6 pReq = (PCINTNETARPIPV6)pHdr; 1251 if (RT_UNLIKELY( pHdr->ar_plen != sizeof(pReq->ar_spa) 1252 || cbPacket < sizeof(*pReq) 1253 || !intnetR0IPv6AddrIsGood(&pReq->ar_spa))) 1254 return; 1255 1256 if ( RTNET_ARPOP_IS_REPLY(RT_BE2H_U16(pHdr->ar_oper)) 1257 && intnetR0IPv6AddrIsGood(&pReq->ar_tpa)) 1342 if (intnetR0IPv4AddrIsGood(pReq->ar_spa)) 1258 1343 { 1259 Addr.IPv 6 = pReq->ar_tpa;1260 intnetR0IfAddrCache Delete(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv6], &Addr, sizeof(pReq->ar_tpa));1344 Addr.IPv4 = pReq->ar_spa; 1345 intnetR0IfAddrCacheAdd(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv4], &Addr, sizeof(pReq->ar_spa), "if/arp"); 1261 1346 } 1262 Addr.IPv6 = pReq->ar_spa; 1263 intnetR0IfAddrCacheAdd(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv6], &Addr, sizeof(pReq->ar_spa), "if/arp"); 1264 } 1347 } 1348 #if 0 /** @todo IPv6 ARP support? Is it used at all? */ 1265 1349 #endif 1266 1350 else … … 1277 1361 * @param pbFrame The frame. 1278 1362 * @param cbFrame The size of the frame. 1279 */ 1280 static void intnetR0IfSnoopAddr(PINTNETIF pIf, uint8_t const *pbFrame, uint32_t cbFrame) 1363 * @param pfSgFlags Pointer to the SG flags. This is used to tag the packet so we 1364 * don't have to repeat the frame parsing in intnetR0TrunkIfSend. 1365 */ 1366 static void intnetR0IfSnoopAddr(PINTNETIF pIf, uint8_t const *pbFrame, uint32_t cbFrame, uint16_t *pfSgFlags) 1281 1367 { 1282 1368 /* … … 1306 1392 #endif 1307 1393 case RTNET_ETHERTYPE_ARP: 1308 intnetR0IfSnoopArpAddr(pIf, (PCRTNETARPHDR)((PCRTNETETHERHDR)pbFrame + 1), cbFrame );1394 intnetR0IfSnoopArpAddr(pIf, (PCRTNETARPHDR)((PCRTNETETHERHDR)pbFrame + 1), cbFrame, pfSgFlags); 1309 1395 break; 1310 1396 } … … 1521 1607 * @param pThis The trunk. 1522 1608 * @param pNetwork The network the frame is being sent to. 1609 * @param pIfSender The IF sending the frame. Used for MAC address checks in shared MAC mode. 1523 1610 * @param fDst The destination flags. 1524 1611 * @param pSG Pointer to the gather list. 1525 1612 * @param fTrunkLocked Whether the caller owns the out-bound trunk lock. 1526 1613 */ 1527 static void intnetR0TrunkIfSend(PINTNETTRUNKIF pThis, PINTNETNETWORK pNetwork, uint32_t fDst, PINTNETSG pSG, bool fTrunkLocked) 1614 static void intnetR0TrunkIfSend(PINTNETTRUNKIF pThis, PINTNETNETWORK pNetwork, PINTNETIF pIfSender, 1615 uint32_t fDst, PINTNETSG pSG, bool fTrunkLocked) 1528 1616 { 1529 1617 /* … … 1537 1625 1538 1626 /* 1539 * If we're supposed to be sharing the MAC address with the host 1540 * interface when hitting the wire, change INTNETTRUNKDIR_WIRE to 1541 * INTNETTRUNKDIR_WIRE_SHARED before calling pfnXmit. 1627 * Do frame modifications when sharing MAC address on the wire. 1628 * 1629 * If the frame is headed for both the host and the wire, we'll 1630 * have to send it to the host before making any modifications, 1631 * and force a copy of the frame. 1542 1632 */ 1543 1633 if ( (pNetwork->fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE) 1544 1634 && (fDst & INTNETTRUNKDIR_WIRE)) 1545 fDst = (fDst & ~INTNETTRUNKDIR_WIRE) | INTNETTRUNKDIR_WIRE_SHARED; 1635 { 1636 /* Dispatch it to the host before making changes. */ 1637 if (fDst & INTNETTRUNKDIR_HOST) 1638 { 1639 Assert(pSG->fFlags & INTNETSG_FLAGS_TEMP); /* make sure copy is forced */ 1640 intnetR0TrunkIfSend(pThis, pNetwork, pIfSender, INTNETTRUNKDIR_HOST, pSG, fTrunkLocked); 1641 fDst &= ~INTNETTRUNKDIR_HOST; 1642 } 1643 1644 /* ASSUME frame from INTNETR0IfSend! */ 1645 AssertReturnVoid(pSG->cSegsUsed == 1); 1646 AssertReturnVoid(pSG->cbTotal >= sizeof(RTNETETHERHDR)); 1647 AssertReturnVoid(fTrunkLocked); 1648 AssertReturnVoid(pIfSender); 1649 PRTNETETHERHDR pEthHdr = (PRTNETETHERHDR)pSG->aSegs[0].pv; 1650 1651 /* 1652 * Get the host mac address and update the ethernet header. 1653 * 1654 * The reason for caching it in the trunk structure is because 1655 * we cannot take the trunk out-bound semaphore when we handle 1656 * stuff like ARP replies from the wire. 1657 */ 1658 pThis->pIfPort->pfnGetMacAddress(pThis->pIfPort, &pThis->CachedMac); 1659 if (!memcmp(&pEthHdr->SrcMac, &pIfSender->Mac, sizeof(RTMAC))) 1660 pEthHdr->SrcMac = pThis->CachedMac; 1661 1662 /* 1663 * Deal with tags from the snooping phase. 1664 */ 1665 if (pSG->fFlags & INTNETSG_FLAGS_ARP_IPV4) 1666 { 1667 PRTNETARPIPV4 pArp = (PRTNETARPIPV4)(pEthHdr + 1); 1668 if (!memcmp(&pArp->ar_sha, &pIfSender->Mac, sizeof(RTMAC))) 1669 { 1670 Log6(("tw: ar_sha %.6Rhxs -> %.6Rhxs\n", &pArp->ar_sha, &pThis->CachedMac)); 1671 pArp->ar_sha = pThis->CachedMac; 1672 } 1673 if (!memcmp(&pArp->ar_tha, &pIfSender->Mac, sizeof(RTMAC))) /* just in case... */ 1674 { 1675 Log6(("tw: ar_tha %.6Rhxs -> %.6Rhxs\n", &pArp->ar_tha, &pThis->CachedMac)); 1676 pArp->ar_tha = pThis->CachedMac; 1677 } 1678 } 1679 } 1546 1680 1547 1681 /* … … 1599 1733 1600 1734 /** 1735 * Edits an ARP packet arriving from the wire via the trunk connection. 1736 * 1737 * @param pNetwork The network the frame is being sent to. 1738 * @param pSG Pointer to the gather list for the frame. 1739 * The flags and data content may be updated. 1740 * @param pEthHdr Pointer to the ethernet header. This may also be 1741 * updated if it's a unicast... 1742 */ 1743 static void intnetR0NetworkEditArpFromWire(PINTNETNETWORK pNetwork, PINTNETSG pSG, PRTNETETHERHDR pEthHdr) 1744 { 1745 /* 1746 * Check the minimum size first. 1747 */ 1748 if (RT_UNLIKELY(pSG->cbTotal < INTNET_ARP_MIN_LEN)) 1749 return; 1750 1751 /* 1752 * Copy to temporary buffer if necessary. 1753 */ 1754 size_t cbPacket = RT_MIN(pSG->cbTotal, INTNET_ARP_MAX_LEN); 1755 PCRTNETARPHDR pHdr = (PCRTNETARPHDR)((uintptr_t)pSG->aSegs[0].pv + sizeof(RTNETETHERHDR)); 1756 if ( pSG->cSegsUsed != 1 1757 && pSG->aSegs[0].cb < cbPacket) 1758 { 1759 Log6(("fw: Copying ARP pkt %u\n", cbPacket)); 1760 if (!intnetR0SgReadPart(pSG, sizeof(RTNETETHERHDR), cbPacket, pNetwork->pbTmp)) 1761 return; 1762 pHdr = (PCRTNETARPHDR)pNetwork->pbTmp; 1763 pSG->fFlags |= INTNETSG_FLAGS_PKT_CP_IN_TMP; 1764 } 1765 1766 /* 1767 * Ignore malformed packets and packets which doesn't interest us. 1768 */ 1769 if (RT_UNLIKELY( pHdr->ar_hlen != sizeof(RTMAC) 1770 || pHdr->ar_htype != RT_H2BE_U16(RTNET_ARP_ETHER))) 1771 return; 1772 uint16_t ar_oper = RT_H2BE_U16(pHdr->ar_oper); 1773 if (RT_UNLIKELY( ar_oper != RTNET_ARPOP_REQUEST 1774 && ar_oper != RTNET_ARPOP_REPLY 1775 /* These doesn't interest us at the moment since they are rarely used on ethernet: 1776 && ar_oper != RTNET_ARPOP_REVREQUEST 1777 && ar_oper != RTNET_ARPOP_REVREPLY 1778 && ar_oper != RTNET_ARPOP_INVREQUEST 1779 && ar_oper != RTNET_ARPOP_INVREPLY */ 1780 )) 1781 return; 1782 1783 /* 1784 * Deal with the protocols. 1785 * 1786 * The thing we're interested in here is a reply to a query 1787 * made by a guest since we've modified the MAC in the initial 1788 * request the guest made. 1789 */ 1790 bool fModified = false; 1791 uint16_t ar_ptype = RT_H2BE_U16(pHdr->ar_ptype); 1792 if (ar_ptype == RTNET_ETHERTYPE_IPV4) 1793 { 1794 /* 1795 * IPv4. 1796 */ 1797 PRTNETARPIPV4 pReq = (PRTNETARPIPV4)pHdr; 1798 if (RT_UNLIKELY( pHdr->ar_plen != sizeof(pReq->ar_spa) 1799 || cbPacket < sizeof(*pReq))) 1800 return; 1801 pSG->fFlags |= INTNETSG_FLAGS_ARP_IPV4; 1802 if ( ar_oper == RTNET_ARPOP_REPLY 1803 && !memcmp(&pReq->ar_tha, &pNetwork->pTrunkIF->CachedMac, sizeof(RTMAC))) 1804 { 1805 PINTNETIF pIf = intnetR0NetworkAddrCacheLookupIf(pNetwork, (PCRTNETADDRU)&pReq->ar_tpa, 1806 kIntNetAddrType_IPv4, sizeof(pReq->ar_tpa)); 1807 if (pIf) 1808 { 1809 Log6(("fw: ar_tha %.6Rhxs -> %.6Rhxs\n", &pReq->ar_tha, &pIf->Mac)); 1810 pReq->ar_tha = pIf->Mac; 1811 if (!memcmp(&pEthHdr->DstMac, &pNetwork->pTrunkIF->CachedMac, sizeof(RTMAC))) 1812 { 1813 Log6(("fw: DstMac %.6Rhxs -> %.6Rhxs\n", &pEthHdr->DstMac, &pIf->Mac)); 1814 pEthHdr->DstMac = pIf->Mac; 1815 if ((void *)pEthHdr != pSG->aSegs[0].pv) 1816 intnetR0SgWritePart(pSG, RT_OFFSETOF(RTNETETHERHDR, DstMac), sizeof(RTMAC), &pIf->Mac); 1817 } 1818 1819 fModified = true; 1820 } 1821 } 1822 } 1823 #if 0 /** @todo IPv6 support, does it use ARP at all? */ 1824 #endif 1825 else 1826 Log(("intnetR0TrunkIfSnoopArp: unknown ar_ptype=%#x\n", ar_ptype)); 1827 1828 /* 1829 * Write back the packet if we've been making changes 1830 * to a buffered copy. 1831 */ 1832 if ( (pSG->fFlags & INTNETSG_FLAGS_PKT_CP_IN_TMP) 1833 && fModified) 1834 intnetR0SgWritePart(pSG, sizeof(RTNETETHERHDR), cbPacket, pHdr); 1835 } 1836 1837 1838 /** 1601 1839 * Sends a broadcast frame. 1602 1840 * … … 1612 1850 * @param pEthHdr Pointer to the ethernet header. 1613 1851 */ 1614 static bool intnetR0NetworkSendBroadcast(PINTNETNETWORK pNetwork, PINTNETIF pIfSender, PINTNETSG pSG, bool fTrunkLocked, PCRTNETETHERHDR pEthHdr) 1615 { 1852 static bool intnetR0NetworkSendBroadcast(PINTNETNETWORK pNetwork, PINTNETIF pIfSender, uint32_t fSrc, 1853 PINTNETSG pSG, bool fTrunkLocked, PRTNETETHERHDR pEthHdr) 1854 { 1855 /* 1856 * Check for ARP packets from the wire since we'll have to make 1857 * modification to them if we're sharing the MAC address with the host. 1858 */ 1859 if ( (pNetwork->fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE) 1860 && (fSrc & INTNETTRUNKDIR_WIRE) 1861 && RT_BE2H_U16(pEthHdr->EtherType) == RTNET_ETHERTYPE_ARP) 1862 intnetR0NetworkEditArpFromWire(pNetwork, pSG, pEthHdr); 1863 1616 1864 /* 1617 1865 * This is a broadcast or multicast address. For the present we treat those … … 1631 1879 if ( pIfSender 1632 1880 && pTrunkIf) 1633 intnetR0TrunkIfSend(pTrunkIf, pNetwork, INTNETTRUNKDIR_HOST | INTNETTRUNKDIR_WIRE, pSG, fTrunkLocked);1881 intnetR0TrunkIfSend(pTrunkIf, pNetwork, pIfSender, INTNETTRUNKDIR_HOST | INTNETTRUNKDIR_WIRE, pSG, fTrunkLocked); 1634 1882 1635 1883 /* … … 1642 1890 if ( ( EtherType == RTNET_ETHERTYPE_IPV4 /* for DHCP */ 1643 1891 && pSG->cbTotal >= sizeof(RTNETETHERHDR) + RTNETIPV4_MIN_LEN + RTNETUDP_MIN_LEN + RTNETBOOTP_DHCP_MIN_LEN) 1644 || EtherType == RTNET_ETHERTYPE_ARP)1892 || (pSG->fFlags & (INTNETSG_FLAGS_ARP_IPV4)) ) 1645 1893 intnetR0TrunkIfSnoopAddr(pNetwork, pSG, EtherType); 1646 1894 } … … 1663 1911 * @param pEthHdr Pointer to the ethernet header. 1664 1912 */ 1665 static bool intnetR0NetworkSendMulticast(PINTNETNETWORK pNetwork, PINTNETIF pIfSender, uint32_t fSrc, PINTNETSG pSG, bool fTrunkLocked, P CRTNETETHERHDR pEthHdr)1913 static bool intnetR0NetworkSendMulticast(PINTNETNETWORK pNetwork, PINTNETIF pIfSender, uint32_t fSrc, PINTNETSG pSG, bool fTrunkLocked, PRTNETETHERHDR pEthHdr) 1666 1914 { 1667 1915 /** @todo implement multicast */ 1668 return intnetR0NetworkSendBroadcast(pNetwork, pIfSender, pSG, fTrunkLocked, pEthHdr);1916 return intnetR0NetworkSendBroadcast(pNetwork, pIfSender, fSrc, pSG, fTrunkLocked, pEthHdr); 1669 1917 } 1670 1918 … … 1682 1930 * @param pEthHdr Pointer to the ethernet header. 1683 1931 */ 1684 static bool intnetR0NetworkSendUnicastWithSharedMac(PINTNETNETWORK pNetwork, PINTNETSG pSG, bool fTrunkLocked, P CRTNETETHERHDR pEthHdr)1932 static bool intnetR0NetworkSendUnicastWithSharedMac(PINTNETNETWORK pNetwork, PINTNETSG pSG, bool fTrunkLocked, PRTNETETHERHDR pEthHdr) 1685 1933 { 1686 1934 /* … … 1734 1982 case RTNET_ETHERTYPE_ARP: 1735 1983 Log6(("intnetshareduni: ARP\n")); 1736 return intnetR0NetworkSendBroadcast(pNetwork, NULL, pSG, fTrunkLocked, pEthHdr);1984 return intnetR0NetworkSendBroadcast(pNetwork, NULL, INTNETTRUNKDIR_WIRE, pSG, fTrunkLocked, pEthHdr); 1737 1985 1738 1986 /* … … 1828 2076 && pTrunkIf->pIfPort) 1829 2077 { 2078 Assert(!fSrc); 2079 1830 2080 /* promiscuous checks first as they are cheaper than pfnIsHostMac. */ 1831 2081 if ( pTrunkIf->fPromiscuousWire … … 1846 2096 1847 2097 if (fDst) 1848 intnetR0TrunkIfSend(pTrunkIf, pNetwork, fDst, pSG, fTrunkLocked);2098 intnetR0TrunkIfSend(pTrunkIf, pNetwork, pIfSender, fDst, pSG, fTrunkLocked); 1849 2099 } 1850 2100 … … 1944 2194 * Distribute the frame. 1945 2195 */ 1946 if (RT_UNLIKELY(EthHdr.DstMac.au8[0] & 1)) /* multicast address */ 2196 if ( EthHdr.DstMac.au16[0] == 0xffff /* broadcast address. */ 2197 && EthHdr.DstMac.au16[1] == 0xffff 2198 && EthHdr.DstMac.au16[2] == 0xffff) 2199 fRc = intnetR0NetworkSendBroadcast(pNetwork, pIfSender, fSrc, pSG, fTrunkLocked, &EthHdr); 2200 else if (RT_UNLIKELY(EthHdr.DstMac.au8[0] & 1)) /* multicast address */ 1947 2201 fRc = intnetR0NetworkSendMulticast(pNetwork, pIfSender, fSrc, pSG, fTrunkLocked, &EthHdr); 1948 else if ( EthHdr.DstMac.au16[0] == 0xffff /* broadcast address. */1949 && EthHdr.DstMac.au16[1] == 0xffff1950 && EthHdr.DstMac.au16[2] == 0xffff)1951 fRc = intnetR0NetworkSendBroadcast(pNetwork, pIfSender, pSG, fTrunkLocked, &EthHdr);1952 2202 else if ( !(pNetwork->fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE) 1953 2203 || !(fSrc & INTNETTRUNKDIR_WIRE)) … … 2056 2306 if (pvCurFrame) 2057 2307 { 2308 intnetR0SgInitTemp(&Sg, pvCurFrame, pHdr->cbFrame); 2058 2309 if (pNetwork->fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE) 2059 intnetR0IfSnoopAddr(pIf, (uint8_t *)pvCurFrame, pHdr->cbFrame); 2060 intnetR0SgInitTemp(&Sg, pvCurFrame, pHdr->cbFrame); 2310 intnetR0IfSnoopAddr(pIf, (uint8_t *)pvCurFrame, pHdr->cbFrame, (uint16_t *)&Sg.fFlags); 2061 2311 intnetR0NetworkSend(pNetwork, pIf, 0, &Sg, !!pTrunkIf); 2062 2312 } … … 3240 3490 //pTrunkIF->fPhysSG = false; 3241 3491 //pTrunkIF->fPromiscuousWire = false; 3492 pTrunkIF->CachedMac.au8[0] = 0xfe; 3493 pTrunkIF->CachedMac.au8[1] = 0xff; 3494 pTrunkIF->CachedMac.au8[2] = 0xff; 3495 pTrunkIF->CachedMac.au8[3] = 0xff; 3496 pTrunkIF->CachedMac.au8[4] = 0xff; 3497 pTrunkIF->CachedMac.au8[5] = 0xff; 3242 3498 int rc = RTSemFastMutexCreate(&pTrunkIF->FastMutex); 3243 3499 if (RT_SUCCESS(rc))
Note:
See TracChangeset
for help on using the changeset viewer.