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)75 UINT _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