1 /*************************************************************************** 2 * Copyright (c) 2024 Microsoft Corporation 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the MIT License which is available at 6 * https://opensource.org/licenses/MIT. 7 * 8 * SPDX-License-Identifier: MIT 9 **************************************************************************/ 10 11 /**************************************************************************/ 12 /**************************************************************************/ 13 /** */ 14 /** NetX Component */ 15 /** */ 16 /** Internet Control Message Protocol (ICMP) */ 17 /** */ 18 /**************************************************************************/ 19 /**************************************************************************/ 20 21 #define NX_SOURCE_CODE 22 /* Include necessary system files. */ 23 24 #include "nx_api.h" 25 #include "nx_ipv6.h" 26 #include "nx_icmpv6.h" 27 28 #ifdef FEATURE_NX_IPV6 29 30 31 #ifndef NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS 32 33 /**************************************************************************/ 34 /* */ 35 /* FUNCTION RELEASE */ 36 /* */ 37 /* _nx_icmpv6_validate_ra PORTABLE C */ 38 /* 6.1 */ 39 /* AUTHOR */ 40 /* */ 41 /* Yuxin Zhou, Microsoft Corporation */ 42 /* */ 43 /* DESCRIPTION */ 44 /* */ 45 /* This function validates incoming router advertisement messages. */ 46 /* */ 47 /* INPUT */ 48 /* */ 49 /* packet_ptr ICMP packet pointer */ 50 /* */ 51 /* OUTPUT */ 52 /* */ 53 /* NX_SUCCESS Successful completion (no */ 54 /* option fields to validate) */ 55 /* NX_NOT_SUCCESSFUL Invalid ICMP header data */ 56 /* */ 57 /* CALLS */ 58 /* */ 59 /* IPv6_Address_Type Find IP address type. */ 60 /* _nx_icmpv6_validate_options Validate option field. */ 61 /* */ 62 /* CALLED BY */ 63 /* */ 64 /* _nx_icmpv6_process_ra Main ICMP packet pocess */ 65 /* */ 66 /* RELEASE HISTORY */ 67 /* */ 68 /* DATE NAME DESCRIPTION */ 69 /* */ 70 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ 71 /* 09-30-2020 Yuxin Zhou Modified comment(s), */ 72 /* resulting in version 6.1 */ 73 /* */ 74 /**************************************************************************/ _nx_icmpv6_validate_ra(NX_PACKET * packet_ptr)75UINT _nx_icmpv6_validate_ra(NX_PACKET *packet_ptr) 76 { 77 78 NX_IPV6_HEADER *ipv6_header; 79 NX_ICMPV6_RA *header_ptr; 80 NX_ICMPV6_OPTION *option_ptr; 81 INT option_length; 82 ULONG source_address_type, dest_address_type; 83 84 85 /* Set a pointer to he ICMP message header. */ 86 /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */ 87 header_ptr = (NX_ICMPV6_RA *)packet_ptr -> nx_packet_prepend_ptr; 88 89 /* Set a pointer to the IPv6 header. */ 90 /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */ 91 ipv6_header = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_ip_header; 92 93 source_address_type = IPv6_Address_Type(ipv6_header -> nx_ip_header_source_ip); 94 dest_address_type = IPv6_Address_Type(ipv6_header -> nx_ip_header_destination_ip); 95 96 /* Validate the IP header information. */ 97 98 /* The source address must be the link local router address. RFC2461 4.2 */ 99 if ((source_address_type & IPV6_ADDRESS_LINKLOCAL) != IPV6_ADDRESS_LINKLOCAL) 100 { 101 102 return(NX_NOT_SUCCESSFUL); 103 } 104 105 /* IP destination address must be multicast address or solicited sender link local address. */ 106 if ((dest_address_type != (ULONG)(IPV6_ADDRESS_LINKLOCAL | IPV6_ADDRESS_UNICAST)) && 107 (dest_address_type != (ULONG)(IPV6_ALL_NODE_MCAST | IPV6_ADDRESS_MULTICAST))) 108 { 109 110 return(NX_NOT_SUCCESSFUL); 111 } 112 113 /* The IP header hop limit must be 255 */ 114 if ((ipv6_header -> nx_ip_header_word_1 & 0xFF) != 0xFF) 115 { 116 117 return(NX_NOT_SUCCESSFUL); 118 } 119 120 /* Validate ICMP fields */ 121 if (header_ptr -> nx_icmpv6_ra_icmpv6_header.nx_icmpv6_header_code != 0) 122 { 123 124 return(NX_NOT_SUCCESSFUL); 125 } 126 127 /* Locate the option field. */ 128 /*lint -e{923} suppress cast between pointer and ULONG, since it is necessary */ 129 option_ptr = (NX_ICMPV6_OPTION *)NX_UCHAR_POINTER_ADD(header_ptr, sizeof(NX_ICMPV6_RA)); 130 option_length = (INT)(packet_ptr -> nx_packet_length - sizeof(NX_ICMPV6_RA)); 131 132 /* Check for options (if there is a non zero option length ICMPv6 header field). */ 133 if (option_length) 134 { 135 136 /* Validate option field(s). */ 137 return(_nx_icmpv6_validate_options(option_ptr, option_length, NX_NULL)); 138 } 139 140 return(NX_SUCCESS); 141 } 142 143 144 #endif /* NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS */ 145 146 #endif /* FEATURE_NX_IPV6 */ 147 148