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.1 */
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 /* */
100 /**************************************************************************/
_nx_icmpv6_packet_process(NX_IP * ip_ptr,NX_PACKET * packet_ptr)101 VOID _nx_icmpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
102 {
103
104 NX_ICMPV6_HEADER *header_ptr;
105 USHORT checksum;
106 #if defined(NX_DISABLE_ICMPV6_RX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE)
107 UINT compute_checksum = 1;
108 #endif /* defined(NX_DISABLE_ICMPV6_RX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE) */
109 NX_IPV6_HEADER *ipv6_header;
110
111
112 /* Add debug information. */
113 NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
114
115 /* Points to the ICMP message header. */
116 /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */
117 header_ptr = (NX_ICMPV6_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
118
119 #ifdef NX_DISABLE_ICMPV6_RX_CHECKSUM
120 compute_checksum = 0;
121 #endif /* NX_DISABLE_ICMPV6_RX_CHECKSUM */
122
123 #ifdef NX_ENABLE_INTERFACE_CAPABILITY
124 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)
125 {
126 compute_checksum = 0;
127 }
128 #endif /* NX_ENABLE_INTERFACE_CAPABILITY */
129 #ifdef NX_IPSEC_ENABLE
130 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))
131 {
132 compute_checksum = 1;
133 }
134 #endif
135 #if defined(NX_DISABLE_ICMPV6_RX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE)
136 if (compute_checksum)
137 #endif /* defined(NX_DISABLE_ICMPV6_RX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE) */
138 {
139 /* Points to the IPv6 header. */
140 /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */
141 ipv6_header = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_ip_header;
142
143 /* Calculate the ICMP message checksum. */
144 checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_ICMPV6,
145 (UINT)packet_ptr -> nx_packet_length,
146 (ipv6_header -> nx_ip_header_source_ip),
147 (ipv6_header -> nx_ip_header_destination_ip));
148
149 checksum = (USHORT)(~checksum) & NX_LOWER_16_MASK;
150
151 /* Determine if the checksum is valid. */
152 if (checksum)
153 {
154
155 #ifndef NX_DISABLE_ICMP_INFO
156
157 /* Increment the ICMP invalid packet error. */
158 ip_ptr -> nx_ip_icmp_invalid_packets++;
159
160 /* Increment the ICMP checksum error count. */
161 ip_ptr -> nx_ip_icmp_checksum_errors++;
162 #endif
163
164 /* Nope, the checksum is invalid. Toss this ICMP packet out. */
165 _nx_packet_release(packet_ptr);
166 return;
167 }
168 }
169
170 /* Determine the message type and call the appropriate handler. */
171 if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_ECHO_REPLY_TYPE)
172 {
173 _nx_icmpv6_process_echo_reply(ip_ptr, packet_ptr);
174 }
175 else if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_ECHO_REQUEST_TYPE)
176 {
177 _nx_icmpv6_process_echo_request(ip_ptr, packet_ptr);
178 }
179 else if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_NEIGHBOR_SOLICITATION_TYPE)
180 {
181
182 _nx_icmpv6_process_ns(ip_ptr, packet_ptr);
183 }
184
185 #ifndef NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS
186 else if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_ROUTER_ADVERTISEMENT_TYPE)
187 {
188
189 _nx_icmpv6_process_ra(ip_ptr, packet_ptr);
190 }
191 #endif
192 else if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_NEIGHBOR_ADVERTISEMENT_TYPE)
193 {
194
195 _nx_icmpv6_process_na(ip_ptr, packet_ptr);
196 }
197 #ifndef NX_DISABLE_ICMPV6_REDIRECT_PROCESS
198 else if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_REDIRECT_MESSAGE_TYPE)
199 {
200
201 _nx_icmpv6_process_redirect(ip_ptr, packet_ptr);
202 }
203 #endif
204
205 #ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
206 else if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_PACKET_TOO_BIG_TYPE)
207 {
208 _nx_icmpv6_process_packet_too_big(ip_ptr, packet_ptr);
209 }
210 #endif /* NX_ENABLE_IPV6_PATH_MTU_DISCOVERY */
211
212 else
213 {
214
215 #ifndef NX_DISABLE_ICMP_INFO
216
217 /* Increment the ICMP unhandled message count. */
218 ip_ptr -> nx_ip_icmp_unhandled_messages++;
219 #endif
220
221 /* Unhandled ICMP message, just release it. */
222 _nx_packet_release(packet_ptr);
223 }
224 }
225
226
227 #endif /* FEATURE_NX_IPV6 */
228
229