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