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 /**                                                                       */
15 /** NetX Component                                                        */
16 /**                                                                       */
17 /**   Internet Control Message Protocol (ICMP)                            */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 
23 /**************************************************************************/
24 /*                                                                        */
25 /*  COMPONENT DEFINITION                                   RELEASE        */
26 /*                                                                        */
27 /*    nx_icmpv6.h                                         PORTABLE C      */
28 /*                                                           6.3.0        */
29 /*  AUTHOR                                                                */
30 /*                                                                        */
31 /*    Yuxin Zhou, Microsoft Corporation                                   */
32 /*                                                                        */
33 /*  DESCRIPTION                                                           */
34 /*                                                                        */
35 /*    This file defines the NetX Internet Control Message Protocol (ICMP) */
36 /*    component, including all data types and external references.  It is */
37 /*    assumed that nx_api.h and nx_port.h have already been included.     */
38 /*                                                                        */
39 /*  RELEASE HISTORY                                                       */
40 /*                                                                        */
41 /*    DATE              NAME                      DESCRIPTION             */
42 /*                                                                        */
43 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
44 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
45 /*                                            resulting in version 6.1    */
46 /*  10-31-2023     Bo Chen                  Modified comment(s), improved */
47 /*                                            packet length verification, */
48 /*                                            resulting in version 6.3.0  */
49 /*                                                                        */
50 /**************************************************************************/
51 
52 #ifndef NX_ICMPV6_H
53 #define NX_ICMPV6_H
54 
55 
56 #include "nx_nd_cache.h"
57 #ifdef FEATURE_NX_IPV6
58 
59 
60 
61 
62 /* Define ICMP types and codes.  */
63 
64 #define NX_ICMPV6_DEST_UNREACHABLE_TYPE       1
65 #define NX_ICMPV6_PACKET_TOO_BIG_TYPE         2
66 #define NX_ICMPV6_TIME_EXCEED_TYPE            3
67 #define NX_ICMPV6_PARAMETER_PROBLEM_TYPE      4
68 #define NX_ICMPV6_ECHO_REPLY_TYPE             129
69 #define NX_ICMPV6_ECHO_REQUEST_TYPE           128
70 #define NX_ICMPV6_ROUTER_SOLICITATION_TYPE    133
71 #define NX_ICMPV6_ROUTER_ADVERTISEMENT_TYPE   134
72 #define NX_ICMPV6_NEIGHBOR_SOLICITATION_TYPE  135
73 #define NX_ICMPV6_NEIGHBOR_ADVERTISEMENT_TYPE 136
74 #define NX_ICMPV6_REDIRECT_MESSAGE_TYPE       137
75 
76 
77 
78 #define ICMPV6_OPTION_TYPE_SRC_LINK_ADDR      1
79 #define ICMPV6_OPTION_TYPE_TRG_LINK_ADDR      2
80 #define ICMPV6_OPTION_TYPE_PREFIX_INFO        3
81 /*
82 #define ICMPV6_OPTION_REDIRECTED_HEADER       4
83  */
84 #define ICMPV6_OPTION_TYPE_MTU                5
85 
86 /* Flag indicicatting that the option field should not contain
87    source link layer address. */
88 #define NX_NO_SLLA                            1
89 
90 /* Define symbols for ICMPv6 error code. */
91 /*
92 #defineNX_ICMPV6_NO_ROUTE_TO_DESTINATION_CODE                    0
93 #define NX_ICMPV6_COMMUNICATION_WITH_DESTINATION_PROHIBITED_CODE 1
94 #define NX_ICMPV6_BEYOND_SCOPE_OF_SOURCE_ADDRESS_CODE            2
95 #define NX_ICMPV6_ADDRESS_UNREACHABLE_CODE                       3
96  */
97 #define NX_ICMPV6_DEST_UNREACHABLE_CODE                          4
98 /*
99 #define NX_ICMPV6_SOURCE_ADDRESS_FAILED_I_E_POLICY_CODE          5
100 #define NX_ICMPV6_REJECT_ROUTE_TO_DESTINATION_CODE               6
101  */
102 
103 
104 /* Set host constants as per RFC 2461 Section 10. */
105 
106 #ifndef NX_DISABLE_ICMPV6_ROUTER_SOLICITATION
107 
108 /* Define the maximum number of router solicitations a node sends until a router response
109    is received.  If no response is received, the node concludes no router is present.
110    For backward compatibility, the symbol NXDUO_ICMPV6_MAX_RTR_SOLICITATIONS is mapped to
111    NX_ICMPV6_MAX_RTR_SOLICITATIONS. */
112 
113 #ifdef NXDUO_ICMPV6_MAX_RTR_SOLICITATIONS
114 #define NX_ICMPV6_MAX_RTR_SOLICITATIONS        NXDUO_ICMPV6_MAX_RTR_SOLICITATIONS
115 #endif /* NXDUO_ICMPV6_MAX_RTR_SOLICITATIONS  */
116 
117 #ifndef NX_ICMPV6_MAX_RTR_SOLICITATIONS
118 #define NX_ICMPV6_MAX_RTR_SOLICITATIONS        3
119 #ifndef NXDUO_ICMPV6_MAX_RTR_SOLICITATIONS
120 #define NXDUO_ICMPV6_MAX_RTR_SOLICITATIONS     NX_ICMPV6_MAX_RTR_SOLICITATIONS
121 #endif  /* NXDUO_ICMPV6_MAX_RTR_SOLICITATIONS  */
122 #endif  /* NX_ICMPV6_MAX_RTR_SOLICITATIONS  */
123 
124 /* Define the interval between which the host sends router solicitations in seconds. */
125 /* For backward compatibility, convert map NXDUO_ICMPV6_RTR_SOLICITATION_INTERVAL to NX_ICMPV6_RTR_SOLICITATION_INTERVAL */
126 
127 #ifdef NXDUO_ICMPV6_RTR_SOLICITATION_INTERVAL
128 #define NX_ICMPV6_RTR_SOLICITATION_INTERVAL    NXDUO_ICMPV6_RTR_SOLICITATION_INTERVAL
129 #endif /* NXDUO_ICMPV6_RTR_SOLICITATION_INTERVAL  */
130 
131 #ifndef NX_ICMPV6_RTR_SOLICITATION_INTERVAL
132 #define NX_ICMPV6_RTR_SOLICITATION_INTERVAL    4
133 #ifndef NXDUO_ICMPV6_RTR_SOLICITATION_INTERVAL
134 #define NXDUO_ICMPV6_RTR_SOLICITATION_INTERVAL NX_ICMPV6_RTR_SOLICITATION_INTERVAL
135 #endif  /* NXDUO_ICMPV6_RTR_SOLICITATION_INTERVAL  */
136 #endif  /* NX_ICMPV6_RTR_SOLICITATION_INTERVAL  */
137 
138 /* Define the maximum delay for the initial router solicitation in seconds. */
139 #ifndef NX_ICMPV6_RTR_SOLICITATION_DELAY
140 #define NX_ICMPV6_RTR_SOLICITATION_DELAY       1
141 #endif /* NX_ICMPV6_RTR_SOLICITATION_DELAY */
142 
143 #endif
144 
145 
146 /* Define the minimum size path MTUs recommended by RFC 2460. */
147 
148 #define NX_MINIMUM_IPV6_PATH_MTU               1280
149 
150 
151 /* Define basic ICMPv6 packet header data type. */
152 
153 typedef  struct NX_ICMPV6_HEADER_STRUCT
154 {
155 
156     /*  Header field for ICMPv6 message type */
157     UCHAR   nx_icmpv6_header_type;
158 
159     /*  Header field for ICMPv6 message code (type context specific) */
160     UCHAR   nx_icmpv6_header_code;
161 
162     /*  Header field for ICMPv6 header checksum */
163     USHORT  nx_icmpv6_header_checksum;
164 } NX_ICMPV6_HEADER;
165 
166 
167 /* Define ICMPv6 error message type. */
168 
169 typedef struct NX_ICMPV6_ERROR_STRUCT
170 {
171     /* General ICMPv6 header. */
172     NX_ICMPV6_HEADER nx_icmpv6_error_header;
173 
174     /* Pointer to the original IPv6 packet where error is detected. */
175     ULONG            nx_icmpv6_error_pointer;
176 } NX_ICMPV6_ERROR;
177 
178 
179 /* ICMPv6 echo request message type. */
180 
181 typedef struct NX_ICMPV6_ECHO_STRUCT
182 {
183     /* General ICMPv6 header. */
184     NX_ICMPV6_HEADER nx_icmpv6_echo_header;
185 
186     /* Echo request message ID */
187     USHORT           nx_icmpv6_echo_identifier;
188 
189     /* Echo request message sequence number */
190     USHORT           nx_icmpv6_echo_sequence_num;
191 } NX_ICMPV6_ECHO;
192 
193 /* Define the ICMPv6 Neighbor Discovery message type. */
194 
195 typedef struct NX_ICMPV6_ND_STRUCT
196 {
197     /* General ICMPv6 header. */
198     NX_ICMPV6_HEADER nx_icmpv6_nd_header;
199 
200     /* Neighbor Discovery flag. */
201     ULONG            nx_icmpv6_nd_flag;
202 
203     /* Neighbor Discovery taget address. */
204     ULONG            nx_icmpv6_nd_targetAddress[4];
205 } NX_ICMPV6_ND;
206 
207 /* Define the ICMPv6 additional option type. */
208 
209 typedef struct NX_ICMPV6_OPTION_STRUCT
210 {
211     /* Option type. */
212     UCHAR   nx_icmpv6_option_type;
213 
214     /* Size of the option. */
215     UCHAR   nx_icmpv6_option_length;
216 
217     /* Option data. This field is used to retrieve starting address of option. The size is decided by option length. */
218     USHORT  nx_icmpv6_option_data;
219 } NX_ICMPV6_OPTION;
220 
221 
222 /* Define the Prefix option type. */
223 
224 typedef struct NX_ICMPV6_OPTION_PREFIX_STRUCT
225 {
226 
227     /* prefix type. */
228     /*lint -esym(768,NX_ICMPV6_OPTION_PREFIX_STRUCT::nx_icmpv6_option_prefix_type) suppress member not referenced. It is used before type casting from NX_ICMPV6_OPTION. */
229     UCHAR nx_icmpv6_option_prefix_type;
230 
231     /* option lenght. */
232     /*lint -esym(768,NX_ICMPV6_OPTION_PREFIX_STRUCT::nx_icmpv6_option_prefix_optionlength) suppress member not referenced. It is used before type casting from NX_ICMPV6_OPTION. */
233     UCHAR nx_icmpv6_option_prefix_optionlength;
234 
235     /* Prefix length. */
236     UCHAR nx_icmpv6_option_prefix_length;
237 
238     /* Flag. */
239     UCHAR nx_icmpv6_option_prefix_flag;
240 
241     /* Valid life time, in seconds. */
242     ULONG nx_icmpv6_option_prefix_valid_lifetime;
243 
244     /* Preferred life time, in seconds. */
245     ULONG nx_icmpv6_option_prefix_preferred_lifetime;
246 
247     /* Unused  */
248     /*lint -esym(768,NX_ICMPV6_OPTION_PREFIX_STRUCT::nx_icmpv6_option_prefix_reserved) suppress member not referenced. It is reserved for future use. */
249     ULONG nx_icmpv6_option_prefix_reserved;
250 
251     /* Prefix. */
252     ULONG nx_icmpv6_option_prefix[4];
253 } NX_ICMPV6_OPTION_PREFIX;
254 
255 /* Define the MTU option type. */
256 
257 typedef struct NX_ICMPV6_OPTION_MTU_STRUCT
258 {
259 
260     /* General ICMPv6 header. */
261     /*lint -esym(768,NX_ICMPV6_OPTION_MTU_STRUCT::nx_icmpv6_option_mtu_icmpv6_header) suppress member not referenced. It is used before type casting from NX_ICMPV6_HEADER. */
262     NX_ICMPV6_HEADER nx_icmpv6_option_mtu_icmpv6_header;
263 
264     /* MTU length. */
265     ULONG nx_icmpv6_option_mtu_path_mtu;
266 
267 } NX_ICMPV6_OPTION_MTU;
268 
269 /* Define the Router solicitation message type.  */
270 
271 typedef struct NX_ICMPV6_RS_STRUCT
272 {
273     /* General ICMPv6 header. */
274     NX_ICMPV6_HEADER nx_icmpv6_rs_icmpv6_header;
275 
276     /* Unused; reserved for future use. */
277     ULONG            nx_icmpv6_rs_reserved;
278 } NX_ICMPV6_RS;
279 
280 /* Define the Router advertisement type. */
281 
282 typedef struct NX_ICMPV6_RA_STRUCT
283 {
284     /* General ICMPv6 header. */
285     NX_ICMPV6_HEADER nx_icmpv6_ra_icmpv6_header;
286 
287     /* Hop limit. */
288     UCHAR nx_icmpv6_ra_hop_limit;
289 
290     /* Router advertisement flag. */
291     UCHAR nx_icmpv6_ra_flag;
292 
293     /* Router life time. */
294     USHORT nx_icmpv6_ra_router_lifetime;
295 
296     /* Router reachable time, in millisecond */
297     ULONG nx_icmpv6_ra_reachable_time;
298 
299     /* Local network retrans timer, in millisecond. */
300     ULONG nx_icmpv6_ra_retrans_time;
301 } NX_ICMPV6_RA;
302 
303 
304 /* Define the Redirect Message type. */
305 
306 typedef struct NX_ICMPV6_REDIRECT_MESSAGE_STRUCT
307 {
308     /* General ICMPv6 header. */
309     NX_ICMPV6_HEADER nx_icmpv6_redirect_icmpv6_header;
310 
311     /* Unused field. */
312     /*lint -esym(768,NX_ICMPV6_REDIRECT_MESSAGE_STRUCT::nx_icmpv6_redirect_reserved) suppress member not referenced. It is reserved for future use. */
313     ULONG nx_icmpv6_redirect_reserved;
314 
315     /* Next hop address. */
316     ULONG nx_icmpv6_redirect_target_address[4];
317 
318     /* Redirected host address. */
319     ULONG nx_icmpv6_redirect_destination_address[4];
320 } NX_ICMPV6_REDIRECT_MESSAGE;
321 
322 #ifndef NX_DISABLE_ICMPV6_ERROR_MESSAGE
323 /* Define macros for sending out ICMPv6 error messages. */
324 #define NX_ICMPV6_SEND_DEST_UNREACHABLE(ip_ptr, packet, code) \
325     _nx_icmpv6_send_error_message((ip_ptr), (packet), (ULONG)((NX_ICMPV6_DEST_UNREACHABLE_TYPE << 24) | ((code) << 16)), 0)
326 
327 #if 0
328 #define NX_ICMPV6_SEND_PACKET_TOO_BIG(ip_ptr, packet, code) \
329     _nx_icmpv6_send_error_message((ip_ptr), (packet), ((NX_ICMPV6_PACKET_TOO_BIG_TYPE << 24) | ((code) << 16)), 0)
330 #endif
331 
332 #define NX_ICMPV6_SEND_TIME_EXCEED(ip_ptr, packet, code) \
333     _nx_icmpv6_send_error_message((ip_ptr), (packet), (ULONG)((NX_ICMPV6_TIME_EXCEED_TYPE << 24) | ((code) << 16)), 0)
334 
335 #define NX_ICMPV6_SEND_PARAMETER_PROBLEM(ip_ptr, packet, code, offset) \
336     _nx_icmpv6_send_error_message((ip_ptr), (packet), (ULONG)((NX_ICMPV6_PARAMETER_PROBLEM_TYPE << 24) | ((code) << 16)), (offset))
337 
338 #endif /* NX_DISABLE_ICMPV6_ERROR_MESSAGE */
339 
340 /* Define ICMPv6 API function prototypes. */
341 
342 UINT _nx_icmp_ping6(NX_IP *ip_ptr, NXD_ADDRESS *ip_address,
343                     CHAR *data_ptr, ULONG data_size,
344                     NX_PACKET **response_ptr, ULONG wait_option);
345 UINT _nx_icmp_interface_ping6(NX_IP *ip_ptr, NXD_ADDRESS *ip_address,
346                               CHAR *data_ptr, ULONG data_size, NXD_IPV6_ADDRESS *ipv6_address,
347                               NX_PACKET **response_ptr, ULONG wait_option);
348 VOID _nx_icmpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
349 
350 
351 /* Define service for performing the Duplicate Address Detection protocol. */
352 
353 #ifndef NX_DISABLE_IPV6_DAD
354 VOID _nx_icmpv6_perform_DAD(NX_IP *);
355 #endif /* NX_DISABLE_IPV6_DAD */
356 
357 
358 /* Define services for performing minimum Path MTU. */
359 
360 #ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
361 UINT _nx_icmpv6_process_packet_too_big(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
362 VOID _nx_icmpv6_destination_table_periodic_update(NX_IP *ip_ptr);
363 #endif
364 
365 /* Define the destination search table function. */
366 
367 #ifndef NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS
368 VOID _nx_icmpv6_process_ra(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
369 UINT _nx_icmpv6_validate_ra(NX_PACKET *packet_ptr);
370 #endif
371 
372 /* Define service for processing redirect packets. */
373 
374 #ifndef NX_DISABLE_ICMPV6_REDIRECT_PROCESS
375 VOID _nx_icmpv6_process_redirect(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
376 #endif /* NX_DISABLE_ICMPV6_REDIRECT_PROCESS */
377 
378 
379 /* Define service for sending ICMPv6 error messages. */
380 
381 #ifndef NX_DISABLE_ICMPV6_ERROR_MESSAGE
382 VOID _nx_icmpv6_send_error_message(NX_IP *ip_ptr, NX_PACKET *packet, ULONG word1, ULONG pointer);
383 #endif /* NX_DISABLE_ICMPV6_ERROR_MESSAGE */
384 
385 /* Define service for sending router solicitation requests. */
386 
387 #ifndef NX_DISABLE_ICMPV6_ROUTER_SOLICITATION
388 UINT _nx_icmpv6_send_rs(NX_IP *ip_ptr, UINT if_index);
389 #endif
390 
391 /* Define internal ICMPv6 handling functions. */
392 
393 VOID _nx_icmpv6_send_queued_packets(NX_IP *ip_ptr, ND_CACHE_ENTRY *nd_entry);
394 UINT _nx_icmpv6_validate_options(NX_ICMPV6_OPTION *option, INT length, INT additional_check);
395 UINT _nxd_ipv6_destination_table_find_next_hop(NX_IP *ip_ptr, ULONG *destination_ip, ULONG *next_hop);
396 UINT _nx_icmpv6_dest_table_find(NX_IP *ip_ptr, ULONG *destination_address, NX_IPV6_DESTINATION_ENTRY **dest_entry_ptr,
397                                 ULONG path_mtu, ULONG mtu_timeout);
398 UINT _nx_icmpv6_dest_table_add(NX_IP *ip_ptr, ULONG *destination_address,
399                                NX_IPV6_DESTINATION_ENTRY **dest_entry_ptr, ULONG *next_hop,
400                                ULONG path_mtu, ULONG mtu_timeout, NXD_IPV6_ADDRESS *ipv6_address);
401 VOID _nx_icmpv6_process_echo_reply(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
402 VOID _nx_icmpv6_process_echo_request(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
403 VOID _nx_icmpv6_process_ns(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
404 VOID _nx_icmpv6_process_na(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
405 VOID _nx_icmpv6_DAD_clear_NDCache_entry(NX_IP *ip_ptr, ULONG *ip_addr);
406 UINT _nx_icmpv6_validate_neighbor_message(NX_PACKET *packet_ptr);
407 VOID _nx_icmpv6_DAD_failure(NX_IP *ip_ptr, NXD_IPV6_ADDRESS *ipv6_address);
408 VOID _nx_icmpv6_send_ns(NX_IP *ip_ptr, ULONG *neighbor_IP_address, INT send_slla, NXD_IPV6_ADDRESS *outgoing_address,
409                         INT sendUnicast, ND_CACHE_ENTRY *NDCacheEntry);
410 #endif /* FEATURE_NX_IPV6 */
411 
412 
413 /* Define external ICMPv6 handling functions. */
414 UINT _nxd_icmpv6_ra_flag_callback_set(NX_IP *ip_ptr, VOID (*icmpv6_ra_flag_callback)(NX_IP *ip_ptr, UINT ra_flag));
415 
416 /* Define error checking shells for API services.  These are only referenced by the application.  */
417 UINT _nxde_icmpv6_ra_flag_callback_set(NX_IP *ip_ptr, VOID (*icmpv6_ra_flag_callback)(NX_IP *ip_ptr, UINT ra_flag));
418 
419 #endif
420 
421