Changeset 11053 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Jul 31, 2008 11:22:56 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 33948
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
r10978 r11053 326 326 327 327 /** 328 * Checks if the IPv4 address is a broadcast address. 329 * @returns true/false. 330 * @param Addr The address, network endian. 331 */ 332 DECLINLINE(bool) intnetR0IPv4AddrIsBroadcast(RTNETADDRIPV4 Addr) 333 { 334 /* Just check for 255.255.255.255 atm. */ 335 return Addr.u == UINT32_MAX; 336 } 337 338 339 /** 340 * Checks if the IPv4 address is a good interface address. 341 * @returns true/false. 342 * @param Addr The address, network endian. 343 */ 344 DECLINLINE(bool) intnetR0IPv4AddrIsGood(RTNETADDRIPV4 Addr) 345 { 346 /* Usual suspects. */ 347 if ( Addr.u == UINT32_MAX /* 255.255.255.255 - broadcast. */ 348 || Addr.au8[0] == 0) /* Current network, can be used as source address. */ 349 return false; 350 351 /* Unusual suspects. */ 352 if (RT_UNLIKELY( Addr.au8[0] == 127 /* Loopback */ 353 || (Addr.au8[0] & 0xf0 == 224) /* Multicast */ 354 )) 355 return false; 356 return true; 357 } 358 359 360 /** 328 361 * Gets the address size of a network layer type. 329 362 * … … 720 753 721 754 /** 755 * Snoops IP assignments and releases from the DHCPv4 trafik. 756 * 757 * The caller is responsible for making sure this trafik between the 758 * BOOTPS and BOOTPC ports and validate the IP header. The UDP packet 759 * need not be validated beyond the ports. 760 * 761 * @param pNetwork The network this frame was seen on. 762 * @param pIpHdr Pointer to a valid IP header. This is for pseudo 763 * header validation, so only the minimum header size 764 * needs to be available and valid here. 765 * @param pUdpHdr Pointer to the UDP header in the frame. 766 * @param cbUdpPkt What's left of the frame when starting at the UDP header. 767 */ 768 static void intnetR0NetworkSnoopDHCP(PINTNETNETWORK pNetwork, PCRTNETIPV4 pIpHdr, PCRTNETUDP pUdpHdr, uint32_t cbUdpPkt) 769 { 770 /** @todo later */ 771 } 772 773 774 /** 722 775 * Deals with an IPv4 packet. 723 776 * … … 727 780 * 728 781 * @param pIf The interface that's sending the frame. 729 * @param p HdrPointer to the IPv4 header in the frame.782 * @param pIpHdr Pointer to the IPv4 header in the frame. 730 783 * @param cbPacket The size of the packet, or more correctly the 731 784 * size of the frame without the ethernet header. 732 785 */ 733 static void intnetR0IfSn iffIPv4SourceAddr(PINTNETIF pIf, PCRTNETIPV4pHdr, uint32_t cbPacket)734 { 735 /* 736 * Check the header size .737 */ 738 if (cbPacket < RT _UOFFSETOF(RTNETIPV4, ip_options)) /** @todo check minimum size requirements here. */786 static void intnetR0IfSnoopIPv4SourceAddr(PINTNETIF pIf, PCRTNETIPV4 pIpHdr, uint32_t cbPacket) 787 { 788 /* 789 * Check the header size first to prevent access invalid data. 790 */ 791 if (cbPacket < RTNETIPV4_MIN_LEN) 739 792 return; 740 uint32_t cbHdr = (uint32_t)p Hdr->ip_hl * 4;793 uint32_t cbHdr = (uint32_t)pIpHdr->ip_hl * 4; 741 794 if ( cbHdr < RT_UOFFSETOF(RTNETIPV4, ip_options) 742 795 || cbPacket < cbHdr) … … 744 797 745 798 /* 746 * Ignore 255.255.255.255 (broadcast), 0.0.0.0 (null) and already cached addresses. 747 */ 799 * Ignore non good IP address (like broadcast and my network), 800 * also skip packets containing address that are already in the 801 * cache. Don't ignore potential DHCP trafik though. 802 */ 803 bool fValidatedIpHdr = false; 748 804 RTNETADDRU Addr; 749 Addr.IPv4 = p Hdr->ip_src;750 if ( Addr.au32[0] == UINT32_C(0xffffffff))751 return;752 753 int i = -1;754 if ( Addr.au32[0] == 0755 || (i = intnetR0IfAddrCacheLookupLikely(&pIf->aAddrCache[kIntNetAddrType_IPv4], &Addr, sizeof(pHdr->ip_src))) >= 0)756 {757 #if 0 /** @todo quick DHCP check? */ 758 if (pHdr->ip_p != RTNETIPV4_PROT_UDP)805 Addr.IPv4 = pIpHdr->ip_src; 806 if ( intnetR0IPv4AddrIsGood(Addr.IPv4) 807 && intnetR0IfAddrCacheLookupLikely(&pIf->aAddrCache[kIntNetAddrType_IPv4], &Addr, sizeof(Addr.IPv4)) < 0) 808 { 809 /* 810 * Got a candidate, check that the IP header is valid before adding it. 811 */ 812 if (!RTNetIPv4IsHdrValid(pIpHdr, cbPacket, cbPacket)) 813 { 814 Log(("intnetR0IfSnoopIPv4SourceAddr: bad ip header\n")); 759 815 return; 760 #endif 761 return; 762 } 763 764 /* 765 * Check the header checksum. 766 */ 767 /** @todo IP checksumming */ 768 769 /* 770 * Add the source address. 771 */ 772 if (i < 0) 816 } 773 817 intnetR0IfAddrCacheAddIt(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv4], &Addr); 774 775 /* 776 * Check for DHCP (properly this time). 777 */ 778 /** @todo DHCPRELEASE request? */ 779 } 780 781 782 783 /** 784 * Sniff up source addresses from an ARP request or reply. 818 fValidatedIpHdr = true; 819 } 820 821 /* 822 * Check for potential DHCP packets. 823 */ 824 if ( pIpHdr->ip_p == RTNETIPV4_PROT_UDP /* DHCP is UDP. */ 825 && cbPacket >= cbHdr + RTNETUDP_MIN_LEN + RTNETBOOTP_DHCP_MIN_LEN) /* Min DHCP packet len */ 826 { 827 PCRTNETUDP pUdpHdr = (PCRTNETUDP)((uint8_t const *)pIpHdr + cbHdr); 828 if ( ( RT_BE2H_U16(pUdpHdr->uh_dport) == RTNETIPV4_PORT_BOOTPS 829 || RT_BE2H_U16(pUdpHdr->uh_sport) == RTNETIPV4_PORT_BOOTPS) 830 && ( RT_BE2H_U16(pUdpHdr->uh_sport) == RTNETIPV4_PORT_BOOTPC 831 || RT_BE2H_U16(pUdpHdr->uh_dport) == RTNETIPV4_PORT_BOOTPC)) 832 { 833 if ( fValidatedIpHdr 834 || RTNetIPv4IsHdrValid(pIpHdr, cbPacket, cbPacket)) 835 intnetR0NetworkSnoopDHCP(pIf->pNetwork, pIpHdr, pUdpHdr, cbPacket - cbHdr); 836 else 837 Log(("intnetR0IfSnoopIPv4SourceAddr: bad ip header (dhcp)\n")); 838 } 839 } 840 } 841 842 843 /** 844 * Snoop up source addresses from an ARP request or reply. 785 845 * 786 846 * @param pIf The interface that's sending the frame. … … 789 849 * request 'cause of min ethernet frame size). 790 850 */ 791 static void intnetR0IfSn iffArpSourceAddr(PINTNETIF pIf, PCRTNETARPHDR pHdr, uint32_t cbPacket)792 { 793 /* 794 * Ignore malformed packets and packets which doesn't inter rest us.851 static void intnetR0IfSnoopArpSourceAddr(PINTNETIF pIf, PCRTNETARPHDR pHdr, uint32_t cbPacket) 852 { 853 /* 854 * Ignore malformed packets and packets which doesn't interest us. 795 855 */ 796 856 if (RT_UNLIKELY( cbPacket <= sizeof(*pHdr) 797 857 || pHdr->ar_hlen != sizeof(PDMMAC) 798 || pHdr->ar_htype != RT_H2BE_U16(RTNET_ARP_ETHER) 799 || ( pHdr->ar_oper != RT_H2BE_U16(RTNET_ARPOP_REQUEST) 800 && pHdr->ar_oper != RT_H2BE_U16(RTNET_ARPOP_REPLY) 801 && pHdr->ar_oper != RT_H2BE_U16(RTNET_ARPOP_REVREQUEST) 802 && pHdr->ar_oper != RT_H2BE_U16(RTNET_ARPOP_REVREPLY) 803 /** @todo Read up on inverse ARP. */ 804 ) 805 ) 806 ) 858 || pHdr->ar_htype != RT_H2BE_U16(RTNET_ARP_ETHER))) 807 859 return; 860 uint16_t ar_oper = RT_H2BE_U16(pHdr->ar_oper); 861 if (RT_UNLIKELY( ar_oper != RTNET_ARPOP_REQUEST 862 && ar_oper != RTNET_ARPOP_REPLY 863 && ar_oper != RTNET_ARPOP_REVREQUEST 864 && ar_oper != RTNET_ARPOP_REVREPLY 865 /** @todo Read up on inverse ARP. */ 866 )) 867 return; 808 868 809 869 /* … … 811 871 */ 812 872 RTNETADDRU Addr; 813 if (pHdr->ar_ptype == RT_H2BE_U16(RTNET_ETHERTYPE_IPV4)) 873 uint16_t ar_ptype = RT_H2BE_U16(pHdr->ar_ptype); 874 if (ar_ptype == RTNET_ETHERTYPE_IPV4) 814 875 { 815 876 /* … … 819 880 if (RT_UNLIKELY( pHdr->ar_plen == sizeof(pReq->ar_spa) 820 881 || cbPacket < sizeof(*pReq) 821 || pReq->ar_spa.u == 0 /** @todo add an inline function for checking that an IP address is worth caching. */ 822 || pReq->ar_spa.u == UINT32_C(0xffffffff))) 882 || !intnetR0IPv4AddrIsGood(pReq->ar_spa))) 823 883 return; 824 884 825 if (RTNET_ARPOP_IS_REPLY(RT_BE2H_U16(pHdr->ar_oper))) 885 if ( RTNET_ARPOP_IS_REPLY(RT_BE2H_U16(pHdr->ar_oper)) 886 && intnetR0IPv4AddrIsGood(pReq->ar_tpa)) 826 887 { 827 888 Addr.IPv4 = pReq->ar_tpa; … … 831 892 intnetR0IfAddrCacheAdd(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv4], &Addr, sizeof(pReq->ar_spa)); 832 893 } 833 else if (pHdr->ar_ptype == RT_H2BE_U16(RTNET_ETHERTYPE_IPV6)) 894 #if 0 /** @todo IPv6 support */ 895 else if (ar_ptype == RT_H2BE_U16(RTNET_ETHERTYPE_IPV6)) 834 896 { 835 897 /* … … 839 901 if (RT_UNLIKELY( pHdr->ar_plen == sizeof(pReq->ar_spa) 840 902 || cbPacket < sizeof(*pReq) 841 /** @todo IPv6 || pReq->ar_spa.au32[0] == 0 or something 842 || pReq->ar_spa.au32[0] == UINT32_C(0xffffffff)*/)) 903 || !intnetR0IPv6AddrIsGood(&pReq->ar_spa))) 843 904 return; 844 905 845 if (RTNET_ARPOP_IS_REPLY(RT_BE2H_U16(pHdr->ar_oper))) 906 if ( RTNET_ARPOP_IS_REPLY(RT_BE2H_U16(pHdr->ar_oper)) 907 && intnetR0IPv6AddrIsGood(&pReq->ar_tpa)) 846 908 { 847 909 Addr.IPv6 = pReq->ar_tpa; … … 851 913 intnetR0IfAddrCacheAdd(pIf, &pIf->aAddrCache[kIntNetAddrType_IPv6], &Addr, sizeof(pReq->ar_spa)); 852 914 } 915 #endif 853 916 else 854 Log(("intnetR0IfSn iffArpSourceAddr: unknown ar_ptype=%#x\n", RT_BE2H_U16(pHdr->ar_ptype)));917 Log(("intnetR0IfSnoopArpSourceAddr: unknown ar_ptype=%#x\n", ar_ptype)); 855 918 } 856 919 … … 865 928 * @param cbFrame The size of the frame. 866 929 */ 867 static void intnetR0I fSniffSourceAddr(PINTNETIF pIf, uint8_t const *pbFrame, uint32_t cbFrame)930 static void intnetR0ISnoopSourceAddr(PINTNETIF pIf, uint8_t const *pbFrame, uint32_t cbFrame) 868 931 { 869 932 /* … … 874 937 cbFrame -= sizeof(RTNETETHERHDR); 875 938 876 uint16_t EtherType = ((PCRTNETETHERHDR)pbFrame)->EtherType;877 if (EtherType == RT _H2BE_U16(RTNET_ETHERTYPE_IPV4))878 intnetR0IfSn iffIPv4SourceAddr(pIf, (PCRTNETIPV4)((PCRTNETETHERHDR)pbFrame + 1), cbFrame);939 uint16_t EtherType = RT_H2BE_U16(((PCRTNETETHERHDR)pbFrame)->EtherType); 940 if (EtherType == RTNET_ETHERTYPE_IPV4) 941 intnetR0IfSnoopIPv4SourceAddr(pIf, (PCRTNETIPV4)((PCRTNETETHERHDR)pbFrame + 1), cbFrame); 879 942 #if 0 /** @todo IntNet: implement IPv6 for wireless MAC sharing. */ 880 else if (EtherType == RT _H2BE_U16(RTNET_ETHERTYPE_IPV6))881 intnetR0IfSn iffIPv6SourceAddr(pIf, (PCINTNETIPV6)((PCRTNETETHERHDR)pbFrame + 1), cbFrame);943 else if (EtherType == RTNET_ETHERTYPE_IPV6) 944 intnetR0IfSnoopIPv6SourceAddr(pIf, (PCINTNETIPV6)((PCRTNETETHERHDR)pbFrame + 1), cbFrame); 882 945 #endif 883 946 #if 0 /** @todo IntNet: implement IPX for wireless MAC sharing? */ 884 else if ( EtherType == RT_H2BE_U16(0x8037) //?? 885 || EtherType == RT_H2BE_U16(0x8137) //?? 947 else if ( EtherType == RT_H2BE_U16(0x8137) //?? 886 948 || EtherType == RT_H2BE_U16(0x8138) //?? 949 || EtherType == RT_H2BE_U16(0x8037) //?? 887 950 ) 888 intnetR0IfSn iffIpxSourceAddr(pIf, (PCINTNETIPX)((PCRTNETETHERHDR)pbFrame + 1), cbFrame);951 intnetR0IfSnoopIpxSourceAddr(pIf, (PCINTNETIPX)((PCRTNETETHERHDR)pbFrame + 1), cbFrame); 889 952 #endif 890 953 else if (EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_ARP)) 891 intnetR0IfSn iffArpSourceAddr(pIf, (PCRTNETARPHDR)((PCRTNETETHERHDR)pbFrame + 1), cbFrame);954 intnetR0IfSnoopArpSourceAddr(pIf, (PCRTNETARPHDR)((PCRTNETETHERHDR)pbFrame + 1), cbFrame); 892 955 } 893 956 … … 1561 1624 { 1562 1625 if (pNetwork->fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE) 1563 intnetR0I fSniffSourceAddr(pIf, (uint8_t *)pvCurFrame, pHdr->cbFrame);1626 intnetR0ISnoopSourceAddr(pIf, (uint8_t *)pvCurFrame, pHdr->cbFrame); 1564 1627 intnetR0SgInitTemp(&Sg, pvCurFrame, pHdr->cbFrame); 1565 1628 intnetR0NetworkSend(pNetwork, pIf, 0, &Sg, !!pTrunkIf);
Note:
See TracChangeset
for help on using the changeset viewer.