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