1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** NetX Component */
17 /** */
18 /** Internet Control Message Protocol (ICMP) */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define NX_SOURCE_CODE
24
25
26 /* Include necessary system files. */
27
28 #include "nx_api.h"
29 #include "nx_packet.h"
30 #include "nx_ip.h"
31 #include "nx_ipv6.h"
32 #include "nx_icmpv6.h"
33
34 #ifdef NX_IPSEC_ENABLE
35 #include "nx_ipsec.h"
36 #endif /* NX_IPSEC_ENABLE */
37
38
39 #ifdef FEATURE_NX_IPV6
40
41
42
43
44 /**************************************************************************/
45 /* */
46 /* FUNCTION RELEASE */
47 /* */
48 /* _nx_icmpv6_packet_process PORTABLE C */
49 /* 6.3.0 */
50 /* AUTHOR */
51 /* */
52 /* Yuxin Zhou, Microsoft Corporation */
53 /* */
54 /* DESCRIPTION */
55 /* */
56 /* This function processes the ICMPv6 received packet, computes the */
57 /* ICMP header checksum, and determines ICMPv6 message type and which */
58 /* handler to process it. It also lifts any associated threads */
59 /* suspended on it. */
60 /* */
61 /* INPUT */
62 /* */
63 /* ip_ptr Pointer to IP control block */
64 /* packet_ptr Received ICMP packet pointer */
65 /* */
66 /* OUTPUT */
67 /* */
68 /* None */
69 /* */
70 /* CALLS */
71 /* */
72 /* _nx_ip_checksum_compute Computer ICMP checksum */
73 /* _nx_packet_release Packet release function */
74 /* _tx_thread_system_preempt_check Check for preemption */
75 /* _nx_icmpv6_process_echo_reply Function that processes the */
76 /* echo reply message. */
77 /* _nx_icmpv6_process_echo_request Function that processes the */
78 /* echo request message. */
79 /* _nx_icmpv6_process_ra Function that processes the */
80 /* router advertisement */
81 /* message. */
82 /* _nx_icmpv6_process_na Function that processes the */
83 /* neighbor advertisement. */
84 /* _nx_icmpv6_process_ns Function that processes the */
85 /* neighbor solicitation */
86 /* message. */
87 /* */
88 /* CALLED BY */
89 /* */
90 /* _nx_icmp_packet_process Main ICMP packet processer */
91 /* */
92 /* RELEASE HISTORY */
93 /* */
94 /* DATE NAME DESCRIPTION */
95 /* */
96 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
97 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
98 /* resulting in version 6.1 */
99 /* 10-31-2023 Bo Chen Modified comment(s), improved */
100 /* packet length verification, */
101 /* resulting in version 6.3.0 */
102 /* */
103 /**************************************************************************/
_nx_icmpv6_packet_process(NX_IP * ip_ptr,NX_PACKET * packet_ptr)104 VOID _nx_icmpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
105 {
106
107 NX_ICMPV6_HEADER *header_ptr;
108 USHORT checksum;
109 #if defined(NX_DISABLE_ICMPV6_RX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE)
110 UINT compute_checksum = 1;
111 #endif /* defined(NX_DISABLE_ICMPV6_RX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE) */
112 NX_IPV6_HEADER *ipv6_header;
113
114
115 /* Add debug information. */
116 NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
117
118 /* Check packet length is at least sizeof(NX_ICMPV6_HEADER). */
119 if ((UINT)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) < sizeof(NX_ICMPV6_HEADER))
120 {
121 #ifndef NX_DISABLE_ICMP_INFO
122
123 /* Increment the ICMP invalid packet error. */
124 ip_ptr -> nx_ip_icmp_invalid_packets++;
125 #endif
126
127 _nx_packet_release(packet_ptr);
128 return;
129 }
130
131 /* Points to the ICMP message header. */
132 /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */
133 header_ptr = (NX_ICMPV6_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
134
135 #ifdef NX_DISABLE_ICMPV6_RX_CHECKSUM
136 compute_checksum = 0;
137 #endif /* NX_DISABLE_ICMPV6_RX_CHECKSUM */
138
139 #ifdef NX_ENABLE_INTERFACE_CAPABILITY
140 if (packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address_attached -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_ICMPV6_RX_CHECKSUM)
141 {
142 compute_checksum = 0;
143 }
144 #endif /* NX_ENABLE_INTERFACE_CAPABILITY */
145 #ifdef NX_IPSEC_ENABLE
146 if ((packet_ptr -> nx_packet_ipsec_sa_ptr != NX_NULL) && (((NX_IPSEC_SA *)(packet_ptr -> nx_packet_ipsec_sa_ptr)) -> nx_ipsec_sa_encryption_method != NX_CRYPTO_NONE))
147 {
148 compute_checksum = 1;
149 }
150 #endif
151 #if defined(NX_DISABLE_ICMPV6_RX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE)
152 if (compute_checksum)
153 #endif /* defined(NX_DISABLE_ICMPV6_RX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE) */
154 {
155 /* Points to the IPv6 header. */
156 /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */
157 ipv6_header = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_ip_header;
158
159 /* Calculate the ICMP message checksum. */
160 checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_ICMPV6,
161 (UINT)packet_ptr -> nx_packet_length,
162 (ipv6_header -> nx_ip_header_source_ip),
163 (ipv6_header -> nx_ip_header_destination_ip));
164
165 checksum = (USHORT)(~checksum) & NX_LOWER_16_MASK;
166
167 /* Determine if the checksum is valid. */
168 if (checksum)
169 {
170
171 #ifndef NX_DISABLE_ICMP_INFO
172
173 /* Increment the ICMP invalid packet error. */
174 ip_ptr -> nx_ip_icmp_invalid_packets++;
175
176 /* Increment the ICMP checksum error count. */
177 ip_ptr -> nx_ip_icmp_checksum_errors++;
178 #endif
179
180 /* Nope, the checksum is invalid. Toss this ICMP packet out. */
181 _nx_packet_release(packet_ptr);
182 return;
183 }
184 }
185
186 /* Determine the message type and call the appropriate handler. */
187 if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_ECHO_REPLY_TYPE)
188 {
189 _nx_icmpv6_process_echo_reply(ip_ptr, packet_ptr);
190 }
191 else if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_ECHO_REQUEST_TYPE)
192 {
193 _nx_icmpv6_process_echo_request(ip_ptr, packet_ptr);
194 }
195 else if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_NEIGHBOR_SOLICITATION_TYPE)
196 {
197
198 _nx_icmpv6_process_ns(ip_ptr, packet_ptr);
199 }
200
201 #ifndef NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS
202 else if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_ROUTER_ADVERTISEMENT_TYPE)
203 {
204
205 _nx_icmpv6_process_ra(ip_ptr, packet_ptr);
206 }
207 #endif
208 else if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_NEIGHBOR_ADVERTISEMENT_TYPE)
209 {
210
211 _nx_icmpv6_process_na(ip_ptr, packet_ptr);
212 }
213 #ifndef NX_DISABLE_ICMPV6_REDIRECT_PROCESS
214 else if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_REDIRECT_MESSAGE_TYPE)
215 {
216
217 _nx_icmpv6_process_redirect(ip_ptr, packet_ptr);
218 }
219 #endif
220
221 #ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
222 else if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_PACKET_TOO_BIG_TYPE)
223 {
224 _nx_icmpv6_process_packet_too_big(ip_ptr, packet_ptr);
225 }
226 #endif /* NX_ENABLE_IPV6_PATH_MTU_DISCOVERY */
227
228 else
229 {
230
231 #ifndef NX_DISABLE_ICMP_INFO
232
233 /* Increment the ICMP unhandled message count. */
234 ip_ptr -> nx_ip_icmp_unhandled_messages++;
235 #endif
236
237 /* Unhandled ICMP message, just release it. */
238 _nx_packet_release(packet_ptr);
239 }
240 }
241
242
243 #endif /* FEATURE_NX_IPV6 */
244
245