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 Protocol version 6 (IPv6)                                  */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 
23 /**************************************************************************/
24 /*                                                                        */
25 /*  COMPONENT DEFINITION                                   RELEASE        */
26 /*                                                                        */
27 /*    nx_ipv6.h                                           PORTABLE C      */
28 /*                                                           6.1.9        */
29 /*  AUTHOR                                                                */
30 /*                                                                        */
31 /*    Yuxin Zhou, Microsoft Corporation                                   */
32 /*                                                                        */
33 /*  DESCRIPTION                                                           */
34 /*                                                                        */
35 /*    This file defines the NetX Internet Protocol component,             */
36 /*    including all data types and external references.  It is assumed    */
37 /*    that nx_api.h and nx_port.h have already been included.             */
38 /*                                                                        */
39 /*    This header file is for NetX Duo internal use only.  Application    */
40 /*    shall not include this file directly.                               */
41 /*                                                                        */
42 /*  RELEASE HISTORY                                                       */
43 /*                                                                        */
44 /*    DATE              NAME                      DESCRIPTION             */
45 /*                                                                        */
46 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
47 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
48 /*                                            resulting in version 6.1    */
49 /*  10-15-2021     Yuxin Zhou               Modified comment(s), included */
50 /*                                            necessary header file,      */
51 /*                                            resulting in version 6.1.9  */
52 /*                                                                        */
53 /**************************************************************************/
54 
55 #ifndef NX_IPV6_H
56 #define NX_IPV6_H
57 
58 #include "nx_api.h"
59 #ifdef FEATURE_NX_IPV6
60 
61 /* Define basic IP Header constant.  */
62 
63 /* Define Basic Internet packet header data type.  This will be used to
64    build new IP packets and to examine incoming packets into NetX.  */
65 
66 typedef  struct NX_IPV6_HEADER_STRUCT
67 {
68     /*
69        Define the first 32-bit word of the IP header.  This word contains
70        the following information:
71 
72             bits 31-28  IP Version = 0x6  (IP Version6)
73             bits 27-20  Traffic Class
74             bits 19-00  Flow Lable
75      */
76     ULONG nx_ip_header_word_0;
77 
78     /*
79        Define the second word of the IP header.  This word contains
80        the following information:
81 
82             bits 31-16  Payload Length
83             bits 15-8   Next Header;
84             bits  7-0   Hop limit
85      */
86     ULONG nx_ip_header_word_1;
87 
88     /* Sender IP address. */
89     ULONG nx_ip_header_source_ip[4];
90 
91     /* Define the destination IP address.  */
92     ULONG nx_ip_header_destination_ip[4];
93 } NX_IPV6_HEADER;
94 
95 
96 /* Define the data structure of the IPv6 optional field used in
97    hop-by-hop option and destination option headers. */
98 typedef struct NX_IPV6_HEADER_OPTION_STRUCT
99 {
100 
101     /* A hint to the protocol that follows. */
102     UCHAR nx_ipv6_header_option_next_header;
103 
104     /* Size of this option field.*/
105     UCHAR nx_ipv6_header_option_ext_length;
106 
107     /* ICMPv6 Option header type. */
108     /*lint -esym(768,NX_IPV6_HEADER_OPTION_STRUCT::nx_ipv6_header_option_type) suppress member not referenced. It is not used as a host. */
109     UCHAR nx_ipv6_header_option_type;
110 
111     /* ICMPv6 Option-specific area. */
112     /*lint -esym(768,NX_IPV6_HEADER_OPTION_STRUCT::nx_ipv6_header_option_data) suppress member not referenced. It is not used as a host. */
113     UCHAR nx_ipv6_header_option_data;
114 } NX_IPV6_HEADER_OPTION;
115 
116 
117 /* Hop by hop header optoin. */
118 typedef struct NX_IPV6_HOP_BY_HOP_OPTION_STRUCT
119 {
120     /* Option type. */
121     UCHAR nx_ipv6_hop_by_hop_option_type;
122 
123     /* Size of this option field.*/
124     UCHAR nx_ipv6_hop_by_hop_length;
125 
126     /* Start point of the option data. */
127     /*lint -esym(768,NX_IPV6_HOP_BY_HOP_OPTION_STRUCT::nx_ipv6_hop_by_hop_data) suppress member not referenced. It is not used as a host. */
128     USHORT nx_ipv6_hop_by_hop_data;
129 } NX_IPV6_HOP_BY_HOP_OPTION;
130 
131 
132 /* Routing header option. */
133 typedef struct NX_IPV6_HEADER_ROUTING_OPTION_STRUCT
134 {
135 
136     /* A hint to the protocol that follows. */
137     /*lint -esym(768,NX_IPV6_HEADER_ROUTING_OPTION_STRUCT::nx_ipv6_header_routing_option_next_header) suppress member not referenced. It is not used as a host. */
138     UCHAR nx_ipv6_header_routing_option_next_header;
139 
140     /* Header length. */
141     /*lint -esym(768,NX_IPV6_HEADER_ROUTING_OPTION_STRUCT::nx_ipv6_header_routing_option_hdr_ext_len) suppress member not referenced. It is not used as a host. */
142     UCHAR nx_ipv6_header_routing_option_hdr_ext_len;
143 
144     /* Router type. */
145     /*lint -esym(768,NX_IPV6_HEADER_ROUTING_OPTION_STRUCT::nx_ipv6_header_routing_option_routing_type) suppress member not referenced. It is not used as a host. */
146     UCHAR nx_ipv6_header_routing_option_routing_type;
147 
148     /* Segments left. */
149     UCHAR nx_ipv6_header_routing_option_segments_left;
150 
151     /* Data. */
152     /*lint -esym(768,NX_IPV6_HEADER_ROUTING_OPTION_STRUCT::nx_ipv6_header_routing_option_data) suppress member not referenced. It is not used as a host. */
153     ULONG *nx_ipv6_header_routing_option_data;
154 } NX_IPV6_HEADER_ROUTING_OPTION;
155 
156 /* Fragment header option. */
157 typedef struct NX_IPV6_HEADER_FRAGMENT_OPTION_STRUCT
158 {
159     /* A hint to the protocol that follows. */
160     UCHAR nx_ipv6_header_fragment_option_next_header;
161 
162     /* Unused field. */
163     UCHAR nx_ipv6_header_fragment_option_reserved;
164 
165     /* Fragment offset. Last 3 bits are used as flags. */
166     USHORT nx_ipv6_header_fragment_option_offset_flag;
167 
168     /* ID field. */
169     ULONG nx_ipv6_header_fragment_option_packet_id;
170 } NX_IPV6_HEADER_FRAGMENT_OPTION;
171 
172 /* Unicast address type.  Note that site local address types have been
173    deprectated in RFC 4291 and are treated as global address types. */
174 #define IPV6_ADDRESS_LINKLOCAL    0x00000001
175 /*
176 #define IPV6_ADDRESS_SITELOCAL    0x00000002
177  */
178 #define IPV6_ADDRESS_GLOBAL       0x00000004
179 
180 /* Multicast address type */
181 #define IPV6_ALL_NODE_MCAST       0x00000010
182 #define IPV6_ALL_ROUTER_MCAST     0x00000020
183 #define IPV6_SOLICITED_NODE_MCAST 0x00000040
184 
185 #define IPV6_ADDRESS_UNICAST      0x80000000
186 #define IPV6_ADDRESS_MULTICAST    0x40000000
187 #define IPV6_ADDRESS_UNSPECIFIED  0x20000000
188 #define IPV6_ADDRESS_LOOPBACK     0x10000000
189 
190 
191 
192 /*
193     The following symbols define the order of the IPv6 optional
194     headers.  Each value represents a state during the parse of the
195     optional headers.  An error occurs when the parser encounters
196     an optional header when it is not expecting the header, i.e.
197     the header is out of order. .
198 
199 
200     IPv6 defines the order of the optional headers: (RFC2460 section 4.1)
201     * IPv6 Header
202     * Hop-by-Hop Options header
203     * Destination Options header
204     * Routnig header
205     * Fragment header
206     * Authentication header
207     * Encapsulating Security Payload header
208     * Destination Options header
209     * Upper-layer header
210  */
211 enum NX_IPV6_OPTION_STATE
212 {
213     IPV6_BASE_HEADER,               /* 0 */
214     HOP_BY_HOP_HEADER,              /* 1 */
215     DESTINATION_HEADER_1,           /* 2 */
216     ROUTING_HEADER,                 /* 3 */
217     FRAGMENT_HEADER,                /* 4 */
218 #ifdef NX_IPSEC_ENABLE
219     AUTHENTICATION_HEADER,          /* 5 */
220     ENCAP_SECURITY_HEADER,          /* 6 */
221 #endif /* NX_IPSEC_ENABLE */
222     DESTINATION_HEADER_2            /* 7 */
223 };
224 
225 
226 
227 /* Define IPv6 internal functions. */
228 
229 UINT  _nxd_ipv6_default_router_add_internal(NX_IP *ip_ptr, ULONG *router_addr, ULONG router_lifetime, NX_INTERFACE *if_ptr, INT router_type, NX_IPV6_DEFAULT_ROUTER_ENTRY **_new_entry);
230 VOID  _nxd_ipv6_default_router_table_init(NX_IP *ip_ptr);
231 UINT  _nxd_ipv6_find_max_prefix_length(ULONG *addr1, ULONG *addr, UINT max_length);
232 VOID  _nx_ipv6_fragment_process(struct NX_IP_DRIVER_STRUCT *driver_req_ptr, UINT mtu);
233 UINT  _nx_ipv6_header_add(NX_IP *ip_ptr, NX_PACKET **packet_pptr,
234                           ULONG protocol, ULONG payload_size, ULONG hop_limit,
235                           ULONG *src_address, ULONG *dest_address, ULONG *fragment);
236 UINT  _nx_ipv6_packet_copy(NX_PACKET *source_pkt_head, NX_PACKET *dest_pkt_head, UINT size);
237 UINT  _nx_ipv6_multicast_join(NX_IP *, ULONG *, NX_INTERFACE *);
238 UINT  _nx_ipv6_multicast_leave(NX_IP *, ULONG *, NX_INTERFACE *);
239 UINT  _nx_ipv6_option_error(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UCHAR option_type, UINT offset);
240 VOID  _nx_ipv6_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
241 VOID  _nx_ipv6_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr, ULONG protocol, ULONG payload_size, ULONG hop_limit, ULONG *src_address, ULONG *dest_address);
242 UINT  _nx_ipv6_prefix_list_add_entry(NX_IP *ip_ptr, ULONG *prefix, ULONG prefix_length, ULONG valid_lifetime);
243 VOID  _nx_ipv6_prefix_list_delete(NX_IP *ip_ptr, ULONG *prefix, INT prefix_length);
244 VOID  _nx_ipv6_prefix_list_delete_entry(NX_IP *ip_ptr, NX_IPV6_PREFIX_ENTRY *entry);
245 UINT  _nx_ipv6_process_hop_by_hop_option(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
246 UINT  _nx_ipv6_process_routing_option(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
247 UINT  _nx_ipv6_process_fragment_option(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
248 
249 UINT  _nxd_ipv6_interface_find(NX_IP *ip_ptr, ULONG *dest_address,
250                                NXD_IPV6_ADDRESS **ipv6_addr, NX_INTERFACE *if_ptr);
251 UINT  _nxd_ipv6_router_lookup(NX_IP *ip_ptr, NX_INTERFACE *if_ptr, ULONG *router_address, void **nd_cache_entry);
252 VOID  _nxd_ipv6_router_solicitation_check(NX_IP *ip_ptr);
253 UINT  _nxd_ipv6_raw_packet_send_internal(NX_IP *ip_ptr, NX_PACKET *packet_ptr,  NXD_ADDRESS *destination_ip, ULONG protocol);
254 VOID  _nxd_ipv6_prefix_router_timer_tick(NX_IP *ip_ptr);
255 NX_IPV6_DEFAULT_ROUTER_ENTRY* _nxd_ipv6_find_default_router_from_address(NX_IP *ip_ptr, ULONG *ip_addr);
256 INT   _nxd_ipv6_search_onlink(NX_IP *ip_ptr, ULONG *dest_addr);
257 
258 #endif /* FEATURE_NX_IPV6 */
259 
260 
261 
262 /*
263    If NX_IPV6_UTIL_INLINE is defined, the functions are compiled as inline functions.
264    Inline functions improve execution speed.  However it also increases code size.
265    Applications concerning more about code size should have the symbol undefeind
266    when building NetX Duo library and the application.
267  */
268 #ifndef NX_IPV6_UTIL_INLINE
269 
270 #ifdef NX_IPSEC_ENABLE
271 INT  CHECK_IPV6_ADDRESS_RANGE(ULONG *ip_addr_start, ULONG *ip_addr_end, ULONG *ip_addr);
272 #endif /* NX_IPSEC_ENABLE */
273 INT  CHECK_IPV6_ADDRESSES_SAME(ULONG *ip_dest, ULONG *myip);
274 INT  CHECK_UNSPECIFIED_ADDRESS(ULONG *ip_addr);
275 void SET_UNSPECIFIED_ADDRESS(ULONG *ip_addr);
276 void COPY_IPV6_ADDRESS(ULONG *copy_from, ULONG *copy_to);
277 void COPY_NXD_ADDRESS(NXD_ADDRESS *copy_from, NXD_ADDRESS  *copy_to);
278 void SET_SOLICITED_NODE_MULTICAST_ADDRESS(ULONG *address, ULONG *unicast_address);
279 INT  CHECK_ALL_ROUTER_MCAST_ADDRESS(ULONG *address);
280 VOID _nx_ipv6_address_change_endian(ULONG *address);
281 
282 #endif /* NX_IPV6_UTIL_INLINE */
283 INT   CHECK_IP_ADDRESSES_BY_PREFIX(ULONG *ip_addr1, ULONG *ip_addr2, ULONG prefix_len);
284 INT   CHECK_IPV6_SOLICITED_NODE_MCAST_ADDRESS(ULONG *dest_ip, ULONG *myip);
285 ULONG IPv6_Address_Type(ULONG *ip_address);
286 
287 /* Define IPv6 API function prototype. */
288 UINT _nxd_ipv6_enable(NX_IP *ip_ptr);
289 UINT _nxd_ipv6_disable(NX_IP *ip_ptr);
290 UINT _nxd_ipv6_address_get(NX_IP *ip_ptr, UINT address_index, NXD_ADDRESS *ip_address, ULONG *prefix_length, UINT *interface_index);
291 UINT _nxd_ipv6_address_set(NX_IP *ip_ptr, UINT interface_index, NXD_ADDRESS *ip_address, ULONG prefix_length, UINT *address_index);
292 UINT _nxd_ipv6_address_delete(NX_IP *ip_ptr, UINT address_index);
293 UINT _nxd_ipv6_address_change_notify(NX_IP *ip_ptr, VOID (*ipv6_address_change_notfiy)(NX_IP *ip_ptr, UINT status, UINT interface_index, UINT address_index, ULONG *ip_address));
294 UINT _nxd_ipv6_default_router_add(NX_IP *ip_ptr, NXD_ADDRESS *router_addr, ULONG router_lifetime, UINT interface_index);
295 UINT _nxd_ipv6_default_router_delete(NX_IP *ip_ptr, NXD_ADDRESS *router_address);
296 UINT _nxd_ipv6_default_router_get(NX_IP *ip_ptr, UINT interface_index, NXD_ADDRESS *router_addr, ULONG *router_lifetime, ULONG *prefix_length);
297 UINT _nxd_ipv6_default_router_entry_get(NX_IP *ip_ptr, UINT interface_index, UINT entry_index, NXD_ADDRESS *router_addr, ULONG *router_lifetime, ULONG *prefix_length, ULONG *configuration_method);
298 UINT _nxd_ipv6_default_router_number_of_entries_get(NX_IP *ip_ptr, UINT interface_index, UINT *num_entries);
299 UINT _nxd_ipv6_multicast_interface_join(NX_IP *ip_ptr, NXD_ADDRESS *group_address, UINT interface_index);
300 UINT _nxd_ipv6_multicast_interface_leave(NX_IP *ip_ptr, NXD_ADDRESS *group_address, UINT interface_index);
301 UINT _nxd_ipv6_stateless_address_autoconfig_disable(NX_IP *ip_ptr, UINT interface_index);
302 UINT _nxd_ipv6_stateless_address_autoconfig_enable(NX_IP *ip_ptr, UINT interface_index);
303 
304 /* Define error checking shells for API services.  These are only referenced by the application.  */
305 UINT _nxde_ipv6_enable(NX_IP *ip_ptr);
306 UINT _nxde_ipv6_disable(NX_IP *ip_ptr);
307 UINT _nxde_ipv6_stateless_address_autoconfig_disable(NX_IP *ip_ptr, UINT interface_index);
308 UINT _nxde_ipv6_stateless_address_autoconfig_enable(NX_IP *ip_ptr, UINT interface_index);
309 UINT _nxde_ipv6_address_get(NX_IP *ip_ptr, UINT address_index, NXD_ADDRESS *ip_address, ULONG *prefix_length, UINT *interface_index);
310 UINT _nxde_ipv6_address_set(NX_IP *ip_ptr, UINT interface_index, NXD_ADDRESS *ip_address, ULONG prefix_length, UINT *address_index);
311 UINT _nxde_ipv6_address_delete(NX_IP *ip_ptr, UINT address_index);
312 UINT _nxde_ipv6_address_change_notify(NX_IP *ip_ptr, VOID (*ipv6_address_change_notfiy)(NX_IP *ip_ptr, UINT status, UINT interface_index, UINT address_index, ULONG *ip_address));
313 UINT _nxde_ipv6_default_router_add(NX_IP *ip_ptr, NXD_ADDRESS *router_addr, ULONG router_lifetime, UINT interface_index);
314 UINT _nxde_ipv6_default_router_delete(NX_IP *ip_ptr, NXD_ADDRESS *router_address);
315 UINT _nxde_ipv6_default_router_get(NX_IP *ip_ptr, UINT interface_index, NXD_ADDRESS *router_addr, ULONG *router_lifetime, ULONG *prefix_length);
316 UINT _nxde_ipv6_default_router_entry_get(NX_IP *ip_ptr, UINT interface_index, UINT entry_index, NXD_ADDRESS *router_addr, ULONG *router_lifetime, ULONG *prefix_length, ULONG *configuration_method);
317 UINT _nxde_ipv6_default_router_number_of_entries_get(NX_IP *ip_ptr, UINT interface_index, UINT *num_entries);
318 UINT _nxde_ip_raw_packet_send(NX_IP *ip_ptr, NX_PACKET **packet_ptr_ptr,
319                               NXD_ADDRESS *destination_ip, ULONG protocol, UINT ttl, ULONG tos);
320 UINT _nxde_ipv6_multicast_interface_join(NX_IP *ip_ptr, NXD_ADDRESS *group_address, UINT interface_index);
321 UINT _nxde_ipv6_multicast_interface_leave(NX_IP *ip_ptr, NXD_ADDRESS *group_address, UINT interface_index);
322 
323 #endif /* NX_IPV6_H */
324 
325