Changeset 52543 in vbox
- Timestamp:
- Aug 31, 2014 11:48:41 PM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 95798
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/net.h
r52519 r52543 801 801 802 802 803 /** @todo add ICMPv6 when needed. */ 803 /** 804 * IPv6 ICMP packet header. 805 */ 806 #pragma pack(1) 807 typedef struct RTNETICMPV6HDR 808 { 809 /** 00 - The ICMPv6 message type. */ 810 uint8_t icmp6_type; 811 /** 01 - Type specific code that further qualifies the message. */ 812 uint8_t icmp6_code; 813 /** 02 - Checksum of the ICMPv6 message. */ 814 uint16_t icmp6_cksum; 815 } RTNETICMPV6HDR; 816 #pragma pack() 817 AssertCompileSize(RTNETICMPV6HDR, 4); 818 /** Pointer to an ICMPv6 packet header. */ 819 typedef RTNETICMPV6HDR *PRTNETICMPV6HDR; 820 /** Pointer to a const ICMP packet header. */ 821 typedef RTNETICMPV6HDR const *PCRTNETICMPV6HDR; 804 822 805 823 #define RTNETIPV6_PROT_ICMPV6 (58) 806 #define RTNETIPV6_ICMPV6_CODE_0 (0)807 824 808 825 /** @name Internet Control Message Protocol version 6 (ICMPv6) message types. … … 815 832 /** @} */ 816 833 817 /** @deprecated */ 818 #define RTNETIPV6_ICMP_NS_TYPE (RTNETIPV6_ICMP_TYPE_NS) 819 /** @deprecated */ 820 #define RTNETIPV6_ICMP_NA_TYPE (RTNETIPV6_ICMP_TYPE_NA) 821 834 /** @name Neighbor Discovery option types 835 * @{ */ 822 836 #define RTNETIPV6_ICMP_ND_SLLA_OPT (1) 823 837 #define RTNETIPV6_ICMP_ND_TLLA_OPT (2) 824 #define RTNETIPV6_ICMP_ND_LLA_LEN (1) 825 826 /** ICMPv6 ND Source Link Layer Address option */827 #pragma pack(1) 828 typedef struct RTNETNDP_ SLLA_OPT838 /** @} */ 839 840 /** ICMPv6 ND Source/Target Link Layer Address option */ 841 #pragma pack(1) 842 typedef struct RTNETNDP_LLA_OPT 829 843 { 830 844 uint8_t type; 831 845 uint8_t len; 832 RTMAC slla;833 } RTNETNDP_ SLLA_OPT;834 #pragma pack() 835 836 AssertCompileSize(RTNETNDP_ SLLA_OPT, 1+1+6);837 838 typedef RTNETNDP_ SLLA_OPT *PRTNETNDP_SLLA_OPT;839 typedef RTNETNDP_ SLLA_OPT const *PCRTNETNDP_SLLA_OPT;846 RTMAC lla; 847 } RTNETNDP_LLA_OPT; 848 #pragma pack() 849 850 AssertCompileSize(RTNETNDP_LLA_OPT, 1+1+6); 851 852 typedef RTNETNDP_LLA_OPT *PRTNETNDP_LLA_OPT; 853 typedef RTNETNDP_LLA_OPT const *PCRTNETNDP_LLA_OPT; 840 854 841 855 /** ICMPv6 ND Neighbor Sollicitation */ … … 843 857 typedef struct RTNETNDP 844 858 { 845 /** ICMPv6 type. */ 846 uint8_t icmp6_type; 847 /** ICMPv6 code. */ 848 uint8_t icmp6_code; 849 /** ICMPv6 checksum */ 850 uint16_t icmp6_cksum; 851 /** reserved */ 859 /** 00 - The ICMPv6 header. */ 860 RTNETICMPV6HDR Hdr; 861 /** 04 - reserved */ 852 862 uint32_t reserved; 853 /** target address */863 /** 08 - target address */ 854 864 RTNETADDRIPV6 target_address; 855 865 } RTNETNDP; 856 866 #pragma pack() 857 AssertCompileSize(RTNETNDP, 1+1+2+4+16);867 AssertCompileSize(RTNETNDP, 4+4+16); 858 868 /** Pointer to a NDP ND packet. */ 859 869 typedef RTNETNDP *PRTNETNDP; -
trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
r52518 r52543 2809 2809 } 2810 2810 2811 2812 /** 2813 * Rewrite VM MAC address with shared host MAC address inside IPv6 2814 * Neighbor Discovery datagrams. 2815 */ 2816 static void intnetR0TrunkSharedMacEditIPv6FromIntNet(PINTNETTRUNKIF pThis, PINTNETIF pIfSender, 2817 PRTNETETHERHDR pEthHdr, uint32_t cb) 2818 { 2819 if (RT_UNLIKELY(cb < sizeof(*pEthHdr))) 2820 return; 2821 2822 /* have IPv6 header */ 2823 PRTNETIPV6 pIPv6 = (PRTNETIPV6)(pEthHdr + 1); 2824 cb -= sizeof(*pEthHdr); 2825 if (RT_UNLIKELY(cb < sizeof(*pIPv6))) 2826 return; 2827 2828 if ( pIPv6->ip6_nxt != RTNETIPV6_PROT_ICMPV6 2829 || pIPv6->ip6_hlim != 0xff) 2830 return; 2831 2832 PRTNETICMPV6HDR pICMPv6 = (PRTNETICMPV6HDR)(pIPv6 + 1); 2833 cb -= sizeof(*pIPv6); 2834 if (RT_UNLIKELY(cb < sizeof(*pICMPv6))) 2835 return; 2836 2837 size_t hdrlen = 0; 2838 uint8_t llaopt = RTNETIPV6_ICMP_ND_SLLA_OPT; 2839 2840 uint8_t type = pICMPv6->icmp6_type; 2841 switch (type) 2842 { 2843 case RTNETIPV6_ICMP_TYPE_RS: 2844 hdrlen = 8; 2845 break; 2846 2847 case RTNETIPV6_ICMP_TYPE_RA: 2848 hdrlen = 16; 2849 break; 2850 2851 case RTNETIPV6_ICMP_TYPE_NS: 2852 hdrlen = 24; 2853 break; 2854 2855 case RTNETIPV6_ICMP_TYPE_NA: 2856 hdrlen = 24; 2857 llaopt = RTNETIPV6_ICMP_ND_TLLA_OPT; 2858 break; 2859 2860 default: 2861 return; 2862 } 2863 2864 AssertReturnVoid(hdrlen > 0); 2865 if (RT_UNLIKELY(cb < hdrlen)) 2866 return; 2867 2868 if (RT_UNLIKELY(pICMPv6->icmp6_code != 0)) 2869 return; 2870 2871 PRTNETNDP_LLA_OPT pLLAOpt = NULL; 2872 char *pOpt = (char *)pICMPv6 + hdrlen; 2873 cb -= hdrlen; 2874 2875 while (cb >= 8) 2876 { 2877 uint8_t opt = ((uint8_t *)pOpt)[0]; 2878 size_t optlen = (size_t)((uint8_t *)pOpt)[1] * 8; 2879 if (RT_UNLIKELY(cb < optlen)) 2880 return; 2881 2882 if (opt == llaopt) 2883 { 2884 if (RT_UNLIKELY(optlen != 8)) 2885 return; 2886 pLLAOpt = (PRTNETNDP_LLA_OPT)pOpt; 2887 break; 2888 } 2889 2890 pOpt += optlen; 2891 cb -= optlen; 2892 } 2893 2894 if (pLLAOpt == NULL) 2895 return; 2896 2897 if (memcmp(&pLLAOpt->lla, &pIfSender->MacAddr, sizeof(RTMAC)) != 0) 2898 return; 2899 2900 /* overwrite VM's MAC with host's MAC */ 2901 pLLAOpt->lla = pThis->MacAddr; 2902 2903 /* recompute the checksum */ 2904 pICMPv6->icmp6_cksum = 0; 2905 pICMPv6->icmp6_cksum = computeIPv6FullChecksum(pIPv6); 2906 } 2907 2908 2811 2909 /** 2812 2910 * Sends a frame down the trunk. … … 2888 2986 } 2889 2987 } 2890 else if (pEthHdr->EtherType == RT_H2 BE_U16(RTNET_ETHERTYPE_IPV6))2988 else if (pEthHdr->EtherType == RT_H2N_U16_C(RTNET_ETHERTYPE_IPV6)) 2891 2989 { 2892 /* 2893 * IPV6 ICMP Neighbor Discovery : replace 2894 * 1) the advertised source mac address in outgoing neighbor sollicitations 2895 * with the HW MAC address of the trunk interface, 2896 * 2) the advertised target mac address in outgoing neighbor advertisements 2897 * with the HW mac address of the trunk interface. 2898 * 2899 * Note that this only applies to traffic going out on the trunk. Incoming 2900 * NS/NA will never advertise any VM mac address, so we do not need to touch 2901 * them. Other VMs on this bridge as well as the host will see and use the VM's 2902 * actual mac addresses. 2903 * 2904 */ 2905 2906 PRTNETIPV6 pIPv6 = (PRTNETIPV6)(pEthHdr + 1); 2907 PRTNETNDP pNd = (PRTNETNDP)(pIPv6 + 1); 2908 PRTNETNDP_SLLA_OPT pLLAOpt = (PRTNETNDP_SLLA_OPT)(pNd + 1); 2909 2910 /* make sure we have enough bytes to work with */ 2911 if(pSG->cbTotal >= (RTNETIPV6_MIN_LEN + RTNETIPV6_ICMPV6_ND_WITH_LLA_OPT_MIN_LEN) && 2912 /* ensure the packet came from our LAN (not gone through any router) */ 2913 pIPv6->ip6_hlim == 0xff && 2914 /* protocol has to be icmpv6 */ 2915 pIPv6->ip6_nxt == RTNETIPV6_PROT_ICMPV6 && 2916 /* we either have a sollicitation with source link layer addr. opt, or */ 2917 ((pNd->icmp6_type == RTNETIPV6_ICMP_NS_TYPE && 2918 pNd->icmp6_code == RTNETIPV6_ICMPV6_CODE_0 && 2919 pLLAOpt->type == RTNETIPV6_ICMP_ND_SLLA_OPT) || 2920 /* an advertisement with target link layer addr. option */ 2921 ((pNd->icmp6_type == RTNETIPV6_ICMP_NA_TYPE && 2922 pNd->icmp6_code == RTNETIPV6_ICMPV6_CODE_0 && 2923 pLLAOpt->type == RTNETIPV6_ICMP_ND_TLLA_OPT)) ) && 2924 pLLAOpt->len == RTNETIPV6_ICMP_ND_LLA_LEN) 2925 { 2926 /* swap the advertised VM MAC address with the trunk's */ 2927 pLLAOpt->slla = pThis->MacAddr; 2928 2929 /* recompute the checksum since we changed the packet */ 2930 pNd->icmp6_cksum = 0; 2931 pNd->icmp6_cksum = computeIPv6FullChecksum(pIPv6); 2932 } 2933 2990 intnetR0TrunkSharedMacEditIPv6FromIntNet(pThis, pIfSender, pEthHdr, pSG->cbTotal); 2934 2991 } 2935 2992 } 2936 2993 2937 2994 /* 2938 * Send the frame, handling the GSO fallback 2939 * .2940 * Note! The trunk implementation will re-check that the trunk is active .2995 * Send the frame, handling the GSO fallback. 2996 * 2997 * Note! The trunk implementation will re-check that the trunk is active 2941 2998 * before sending, so we don't have to duplicate that effort here. 2942 2999 */ … … 3099 3156 if ( pIPv6->ip6_hlim == 0xff 3100 3157 && pIPv6->ip6_nxt == RTNETIPV6_PROT_ICMPV6 3101 && pNd-> icmp6_type == RTNETIPV6_ICMP_NS_TYPE3102 && pNd-> icmp6_code == RTNETIPV6_ICMPV6_CODE_03158 && pNd->Hdr.icmp6_type == RTNETIPV6_ICMP_TYPE_NS 3159 && pNd->Hdr.icmp6_code == 0 3103 3160 && pIPv6->ip6_src.QWords.qw0 == 0 3104 3161 && pIPv6->ip6_src.QWords.qw1 == 0)
Note:
See TracChangeset
for help on using the changeset viewer.