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 (IP) */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define NX_SOURCE_CODE
23
24
25
26 /* Include necessary system files. */
27
28 #include "nx_api.h"
29 #include "nx_ipv6.h"
30 #include "nx_icmpv6.h"
31
32 #ifdef FEATURE_NX_IPV6
33
34
35 /**************************************************************************/
36 /* */
37 /* FUNCTION RELEASE */
38 /* */
39 /* _nx_ipv6_process_hop_by_hop_option PORTABLE C */
40 /* 6.1.3 */
41 /* AUTHOR */
42 /* */
43 /* Yuxin Zhou, Microsoft Corporation */
44 /* */
45 /* DESCRIPTION */
46 /* */
47 /* This function processes the Hop by Hop and the Destination headers. */
48 /* */
49 /* INPUT */
50 /* */
51 /* ip_ptr Pointer to IP control block */
52 /* packet_ptr Pointer to packet to process */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* NX_SUCCESS Successful completion */
57 /* NX_OPTION_HEADER_ERROR Error parsing packet options */
58 /* */
59 /* CALLS */
60 /* */
61 /* _nx_ipv6_option_error Handle errors in IPv6 option */
62 /* */
63 /* */
64 /* CALLED BY */
65 /* */
66 /* _nx_ipv6_dispatch_process Process IPv6 optional header */
67 /* */
68 /* RELEASE HISTORY */
69 /* */
70 /* DATE NAME DESCRIPTION */
71 /* */
72 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
73 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
74 /* resulting in version 6.1 */
75 /* 12-31-2020 Yuxin Zhou Modified comment(s), improved */
76 /* buffer read overflow check, */
77 /* resulting in version 6.1.3 */
78 /* */
79 /**************************************************************************/
_nx_ipv6_process_hop_by_hop_option(NX_IP * ip_ptr,NX_PACKET * packet_ptr)80 UINT _nx_ipv6_process_hop_by_hop_option(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
81 {
82
83 INT header_length;
84 UINT offset_base, offset;
85 UINT rv;
86 NX_IPV6_HOP_BY_HOP_OPTION *option;
87
88
89 /* Add debug information. */
90 NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
91
92 /* Make sure there's no OOB when reading Hdr Ext Len from the packet buffer. */
93 if ((UINT)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) < 2)
94 {
95
96 /* return an error code. */
97 return(NX_OPTION_HEADER_ERROR);
98 }
99
100 /* Read the Hdr Ext Len field. */
101 header_length = *(packet_ptr -> nx_packet_prepend_ptr + 1);
102
103 /* Calculate the the true header length: (n + 1) * 8 */
104 header_length = (header_length + 1) << 3;
105
106 /* The 1st option starts from the 3rd byte. */
107 offset = 2;
108
109 /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
110 /*lint -e{737} suppress loss of sign, since nx_packet_append_ptr is assumed to be larger than nx_packet_ip_header. */
111 offset_base = (UINT)((ULONG)(packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_ip_header) - (ULONG)sizeof(NX_IPV6_HEADER));
112 header_length = header_length - (INT)offset;
113
114 /* Sanity check; does the header length data go past the end of the end of the packet buffer? */
115 /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
116 if ((UINT)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) <
117 ((UINT)header_length + offset))
118 {
119
120 /* Yes, handle the error as indicated by the option type 2 msb's. */
121 /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */
122 option = (NX_IPV6_HOP_BY_HOP_OPTION *)(packet_ptr -> nx_packet_prepend_ptr + offset);
123
124 _nx_ipv6_option_error(ip_ptr, packet_ptr, option -> nx_ipv6_hop_by_hop_option_type, offset_base + offset);
125 return(NX_OPTION_HEADER_ERROR);
126 }
127
128 while (header_length > 0)
129 {
130
131 /* Get a pointer to the options. */
132 /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary */
133 option = (NX_IPV6_HOP_BY_HOP_OPTION *)(packet_ptr -> nx_packet_prepend_ptr + offset);
134
135 switch (option -> nx_ipv6_hop_by_hop_option_type)
136 {
137
138 case 0:
139
140 /* Pad1 option. This option indicates the size of the padding is one.
141 So we skip one byte. */
142 offset++;
143 header_length--;
144 break;
145
146 case 1:
147
148 /* PadN option. Skip N+2 bytes. */
149 offset += ((UINT)(option -> nx_ipv6_hop_by_hop_length) + 2);
150 header_length -= ((INT)(option -> nx_ipv6_hop_by_hop_length) + 2);
151 break;
152
153 #ifdef NX_ENABLE_THREAD
154 case 109:
155
156 /* RFC 7731. */
157
158 /* Skip N+2 bytes. */
159 offset += ((UINT)(option -> nx_ipv6_hop_by_hop_length) + 2);
160 header_length -= ((INT)(option -> nx_ipv6_hop_by_hop_length) + 2);
161 break;
162 #endif /* NX_ENABLE_THREAD */
163
164 default:
165
166 /* Unknown option. */
167 rv = _nx_ipv6_option_error(ip_ptr, packet_ptr, option -> nx_ipv6_hop_by_hop_option_type, offset_base + offset);
168
169 /* If no errors, just skip this option and move onto the next option.*/
170 if (rv == NX_SUCCESS)
171 {
172
173 /* Skip this option and continue processing the rest of the header. */
174 offset += ((UINT)(option -> nx_ipv6_hop_by_hop_length) + 2);
175 header_length -= ((INT)(option -> nx_ipv6_hop_by_hop_length) + 2);
176 break;
177 }
178 else
179 {
180
181 /* Return value indicates an error status: we need to drop the entire packet. */
182 return(rv); /* Drop this packet. */
183 }
184 }
185 }
186
187 /* Successful processing of option header. */
188 return(NX_SUCCESS);
189 }
190
191 #endif /* FEATURE_NX_IPV6 */
192
193