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 /**   Dynamic Host Configuration Protocol over IPv6 (DHCPv6 Client)       */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define NX_DHCPV6_SOURCE_CODE
24 
25 
26 /* Force error checking to be disabled in this module */
27 
28 #ifndef NX_DISABLE_ERROR_CHECKING
29 #define NX_DISABLE_ERROR_CHECKING
30 #endif
31 
32 /* Include necessary system files.  */
33 
34 #include    <stdio.h>
35 #include    "nx_api.h"
36 #include    "nx_system.h"
37 #include    "nx_ip.h"
38 #include    "nx_ipv6.h"
39 #include    "nx_udp.h"
40 #include    "nxd_dhcpv6_client.h"
41 #include    "tx_timer.h"
42 
43 #ifdef FEATURE_NX_IPV6
44 
45 /* Bring in externs for caller checking code.  */
46 
47 NX_CALLER_CHECKING_EXTERNS
48 
49 
50 /* Define the address of All DHCP Relay Agents and Servers as per RFC3315.  */
51 static NXD_ADDRESS  All_DHCPv6_Relay_Servers_Address;
52 
53 /* Keep the DHCPv6 instance for DAD callback notify.  */
54 static NX_DHCPV6    *_nx_dhcpv6_DAD_ptr;
55 
56 
57 /**************************************************************************/
58 /*                                                                        */
59 /*  FUNCTION                                               RELEASE        */
60 /*                                                                        */
61 /*    _nx_dhcpv6_add_client_duid                          PORTABLE C      */
62 /*                                                           6.1          */
63 /*  AUTHOR                                                                */
64 /*                                                                        */
65 /*    Yuxin Zhou, Microsoft Corporation                                   */
66 /*                                                                        */
67 /*  DESCRIPTION                                                           */
68 /*                                                                        */
69 /*    This function adds the client DUID to the Client request packet     */
70 /*    based on the Client DUID on record, checking to make sure it does   */
71 /*    not go past the end of the packet payload.                          */
72 /*                                                                        */
73 /*  INPUT                                                                 */
74 /*                                                                        */
75 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
76 /*    received_buffer                   Pointer to server reply           */
77 /*    length                            Size of server reply buffer       */
78 /*                                                                        */
79 /*  OUTPUT                                                                */
80 /*                                                                        */
81 /*    NX_SUCCESS                        Successful completion status      */
82 /*    NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD                               */
83 /*                                      Not enough room for the Client    */
84 /*                                        DUID in the packet payload      */
85 /*  CALLS                                                                 */
86 /*                                                                        */
87 /*    memset                            Clears specified area of memory   */
88 /*    memcpy                            Copies specified area of memory   */
89 /*                                                                        */
90 /*  CALLED BY                                                             */
91 /*                                                                        */
92 /*    _nx_dhcpv6_send_request           Compiles and sends the Client     */
93 /*                                            DHCPv6 request              */
94 /*                                                                        */
95 /*  RELEASE HISTORY                                                       */
96 /*                                                                        */
97 /*    DATE              NAME                      DESCRIPTION             */
98 /*                                                                        */
99 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
100 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
101 /*                                            verified memcpy use cases,  */
102 /*                                            resulting in version 6.1    */
103 /*                                                                        */
104 /**************************************************************************/
_nx_dhcpv6_add_client_duid(NX_DHCPV6 * dhcpv6_ptr,UCHAR * buffer_ptr,UINT * index)105 UINT  _nx_dhcpv6_add_client_duid(NX_DHCPV6 *dhcpv6_ptr, UCHAR *buffer_ptr, UINT *index)
106 {
107 
108 ULONG message_word;
109 ULONG available_payload;
110 UCHAR mac[8];
111 UINT  i = 0;
112 
113 
114     /* Compute the available payload in the packet buffer. */
115     available_payload = dhcpv6_ptr -> nx_dhcpv6_pool_ptr -> nx_packet_pool_payload_size -
116                         (ULONG)sizeof(NX_IPV6_HEADER) - (ULONG)sizeof(NX_UDP_HEADER) - *index;
117 
118     /* Check if the largest possible client DUID will fit in the packet buffer. */
119     if ((available_payload - 4) < ((ULONG)(dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_option_length)))
120     {
121 
122         /* Hmmm... not enough! Can't do it. */
123         return NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD;
124     }
125 
126     /* Build the header from the client DUID. */
127     message_word = (((ULONG)(dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_op_code)) << 16);
128     message_word |= (dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_option_length);
129 
130     /* Adjust for endianness. */
131     NX_CHANGE_ULONG_ENDIAN(message_word);
132 
133     /* Copy first half of the Client DUID option to packet buffer. */
134     memcpy((buffer_ptr + (*index)), &message_word, sizeof(UINT)); /* Use case of memcpy is verified. */
135     (*index) += (ULONG)sizeof(UINT);
136 
137     /* Build the DUID type and hardware type.  */
138     message_word = (((ULONG)(dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_duid_type)) << 16);
139     message_word |= dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_hardware_type;
140 
141     /* Adjust for endianness. */
142     NX_CHANGE_ULONG_ENDIAN(message_word);
143 
144     /* Set up the DUID type and hardware type. */
145     memcpy((buffer_ptr + (*index)), &message_word, sizeof(UINT)); /* Use case of memcpy is verified. */
146     (*index) += (ULONG)sizeof(UINT);
147 
148     /* Include the 'time' field if this is a Link layer time DUID type. */
149     if (dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_duid_type == NX_DHCPV6_DUID_TYPE_LINK_TIME)
150     {
151 
152         /* Build the time.  */
153         message_word = dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_duid_time;
154 
155         /* Adjust for endianness. */
156         NX_CHANGE_ULONG_ENDIAN(message_word);
157 
158         /* Set up the time.  */
159         memcpy((buffer_ptr + (*index)), &message_word, sizeof(ULONG)); /* Use case of memcpy is verified. */
160         (*index) += (ULONG)sizeof(ULONG);
161     }
162 
163     /* Build the link layer address.  */
164     if (dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_hardware_type == NX_DHCPV6_CLIENT_HARDWARE_TYPE_ETHERNET)
165     {
166 
167         /* The length of link layer address is 48 bit.  */
168 
169         /* Build the MSW.  */
170         mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_link_layer_address_msw >> 8);
171         mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_link_layer_address_msw);
172     }
173     else if(dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_hardware_type == NX_DHCPV6_CLIENT_HARDWARE_TYPE_EUI_64)
174     {
175 
176         /* The length of link layer address is 64 bits.  */
177 
178         /* Build the MSW.  */
179         mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_link_layer_address_msw >> 24);
180         mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_link_layer_address_msw >> 16);
181         mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_link_layer_address_msw >> 8);
182         mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_link_layer_address_msw);
183     }
184 
185     /* Build the LSW.  */
186     mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_link_layer_address_lsw >> 24);
187     mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_link_layer_address_lsw >> 16);
188     mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_link_layer_address_lsw >> 8);
189     mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_link_layer_address_lsw);
190 
191     /* Set up the link layer address.  */
192     memcpy((buffer_ptr + (*index)), mac, i); /* Use case of memcpy is verified. */
193     (*index) += i;
194 
195     return NX_SUCCESS;
196 }
197 
198 
199 /**************************************************************************/
200 /*                                                                        */
201 /*  FUNCTION                                               RELEASE        */
202 /*                                                                        */
203 /*    _nx_dhcpv6_add_elapsed_time                         PORTABLE C      */
204 /*                                                           6.1          */
205 /*  AUTHOR                                                                */
206 /*                                                                        */
207 /*    Yuxin Zhou, Microsoft Corporation                                   */
208 /*                                                                        */
209 /*  DESCRIPTION                                                           */
210 /*                                                                        */
211 /*    This function adds the elapsed time option to the Client request    */
212 /*    packet using the session duration time tracked by the DHCPv6 Client */
213 /*    thread, and checks to make sure it does not go past the end of the  */
214 /*    packet payload.                                                     */
215 /*                                                                        */
216 /*    Note that the elapsed time is the time from which the Client        */
217 /*    initiates the request to the time the it gets and processes a valid */
218 /*    server reply.  Its accuracy depends on the resolution of the session*/
219 /*    timer.                                                              */
220 /*                                                                        */
221 /*  INPUT                                                                 */
222 /*                                                                        */
223 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
224 /*    buffer_ptr                        Pointer to request packet buffer  */
225 /*    index                             Location into buffer to write data*/
226 /*                                                                        */
227 /*  OUTPUT                                                                */
228 /*                                                                        */
229 /*    NX_SUCCESS                        Successful completion status      */
230 /*    NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD                               */
231 /*                                      Not enough room for the elapsed   */
232 /*                                       time option in the packet payload*/
233 /*  CALLS                                                                 */
234 /*                                                                        */
235 /*    memset                            Clears specified area of memory   */
236 /*    memcpy                            Copies specified area of memory   */
237 /*                                                                        */
238 /*  CALLED BY                                                             */
239 /*                                                                        */
240 /*    _nx_dhcpv6_send_request           Compiles and sends the Client     */
241 /*                                            DHCPv6 request              */
242 /*                                                                        */
243 /*  RELEASE HISTORY                                                       */
244 /*                                                                        */
245 /*    DATE              NAME                      DESCRIPTION             */
246 /*                                                                        */
247 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
248 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
249 /*                                            verified memcpy use cases,  */
250 /*                                            resulting in version 6.1    */
251 /*                                                                        */
252 /**************************************************************************/
_nx_dhcpv6_add_elapsed_time(NX_DHCPV6 * dhcpv6_ptr,UCHAR * buffer_ptr,UINT * index)253 UINT _nx_dhcpv6_add_elapsed_time(NX_DHCPV6 *dhcpv6_ptr, UCHAR *buffer_ptr, UINT *index)
254 {
255 
256 ULONG available_payload;
257 
258 
259     /* Compute the available payload for DHCP data in the packet buffer. */
260     available_payload = (dhcpv6_ptr -> nx_dhcpv6_pool_ptr -> nx_packet_pool_payload_size -
261                          (ULONG)sizeof(NX_IPV6_HEADER) - (ULONG)sizeof(NX_UDP_HEADER) - *index);
262 
263     /* Check if the data will fit in the packet buffer. */
264     if (available_payload < sizeof(NX_DHCPV6_ELAPSED_TIME))
265     {
266 
267         /* Hmmm... not enough! Can't do it. */
268         return NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD;
269     }
270 
271     /* Adjust for endianness. */
272     NX_CHANGE_USHORT_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_op_code);
273     NX_CHANGE_USHORT_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_op_length);
274     NX_CHANGE_USHORT_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time);
275 
276     /* Set up the elapsed time option, in hundredths of seconds. */
277     memcpy((buffer_ptr + (*index)), &(dhcpv6_ptr -> nx_dhcpv6_elapsed_time), sizeof(NX_DHCPV6_ELAPSED_TIME)); /* Use case of memcpy is verified. */
278     *index += (ULONG)sizeof(NX_DHCPV6_ELAPSED_TIME);
279 
280     /* Swap bytes back. */
281     NX_CHANGE_USHORT_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_op_code);
282     NX_CHANGE_USHORT_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_op_length);
283     NX_CHANGE_USHORT_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time);
284 
285     return NX_SUCCESS;
286 }
287 
288 
289 /**************************************************************************/
290 /*                                                                        */
291 /*  FUNCTION                                               RELEASE        */
292 /*                                                                        */
293 /*    _nx_dhcpv6_add_ia_address                           PORTABLE C      */
294 /*                                                           6.1          */
295 /*  AUTHOR                                                                */
296 /*                                                                        */
297 /*    Yuxin Zhou, Microsoft Corporation                                   */
298 /*                                                                        */
299 /*  DESCRIPTION                                                           */
300 /*                                                                        */
301 /*    This function adds the IA address option to the Client request      */
302 /*    packet using the Client IA on record.  Also checks to make sure     */
303 /*    adding the IA option does not go past the end of the packet payload.*/
304 /*                                                                        */
305 /*  INPUT                                                                 */
306 /*                                                                        */
307 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
308 /*    buffer_ptr                        Pointer to request packet buffer  */
309 /*    index                             Location into buffer to write data*/
310 /*    ia_index                          The index of IA address           */
311 /*                                                                        */
312 /*  OUTPUT                                                                */
313 /*                                                                        */
314 /*    NX_SUCCESS                        Successful completion status      */
315 /*    NX_DHCPV6_INVALID_IA_ADDRESS      IA address on record is NULL      */
316 /*    NX_DHCPV6_OPTION_NO_DATA          No IA option in client record     */
317 /*    NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD                               */
318 /*                                      Not enough room for the IA address*/
319 /*                                           option in the packet payload */
320 /*  CALLS                                                                 */
321 /*                                                                        */
322 /*    memset                            Clears specified area of memory   */
323 /*    memcpy                            Copies specified area of memory   */
324 /*                                                                        */
325 /*  CALLED BY                                                             */
326 /*                                                                        */
327 /*    _nx_dhcpv6_add_iana               Adds the IANA and optionally the  */
328 /*                                         IA option to Client request    */
329 /*                                                                        */
330 /*  RELEASE HISTORY                                                       */
331 /*                                                                        */
332 /*    DATE              NAME                      DESCRIPTION             */
333 /*                                                                        */
334 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
335 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
336 /*                                            verified memcpy use cases,  */
337 /*                                            resulting in version 6.1    */
338 /*                                                                        */
339 /**************************************************************************/
_nx_dhcpv6_add_ia_address(NX_DHCPV6 * dhcpv6_ptr,UCHAR * buffer_ptr,UINT * index,UINT ia_index)340 UINT _nx_dhcpv6_add_ia_address(NX_DHCPV6 *dhcpv6_ptr, UCHAR *buffer_ptr, UINT *index, UINT ia_index)
341 {
342 
343 ULONG   message_word;
344 ULONG   available_payload;
345 
346     /* Set the IA option length. */
347     dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_option_length = (6 * sizeof(ULONG));
348 
349     /* Compute the available payload for DHCP data in the packet buffer. */
350     available_payload = (dhcpv6_ptr -> nx_dhcpv6_pool_ptr -> nx_packet_pool_payload_size -
351                          (ULONG)sizeof(NX_IPV6_HEADER) - (ULONG)sizeof(NX_UDP_HEADER) - *index);
352 
353     /* Check if the client IA address option will fit in the packet buffer. */
354     if (available_payload < (((ULONG)dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_option_length) + 4))
355     {
356 
357         /* Hmmm... not enough! Can't do it. */
358         return NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD;
359     }
360 
361     /* Check that the IA address option has been created. */
362     if (dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_op_code != NX_DHCPV6_OP_IA_ADDRESS)
363     {
364 
365         /* Missing or invalid IA option and/or data.  */
366         return NX_DHCPV6_INVALID_IA_DATA;
367     }
368 
369     /* Make sure the IA address block has a non zero IP address. */
370     if ((dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[0] == 0) &&
371         (dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[1] == 0) &&
372         (dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[2] == 0) &&
373         (dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[3] == 0))
374     {
375 
376         return NX_DHCPV6_INVALID_IA_ADDRESS;
377     }
378 
379     /* If the client has created an address option, apply it to the message. */
380 
381     /* Clear memory to make the first word of the IA option header. */
382     memset(&message_word, 0, sizeof(ULONG));
383 
384     /* Extract the IA data from the client record. */
385     message_word = (((ULONG)dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_op_code) << 16);
386     message_word |= dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_option_length;
387 
388     /* Adjust for endianness. */
389     NX_CHANGE_ULONG_ENDIAN(message_word);
390 
391     /* Copy IA data into the packet and update the index into the buffer. */
392     memcpy((buffer_ptr + (*index)), &message_word, sizeof(ULONG)); /* Use case of memcpy is verified. */
393      (*index) += (ULONG)sizeof(ULONG);
394 
395      /* Add the IPv6 address.  */
396     /* Adjust for endianness.  */
397     NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[0]);
398     NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[1]);
399     NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[2]);
400     NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[3]);
401 
402     /* Copy the Client preferred IPv6 address to the packet. */
403     memcpy((buffer_ptr + (*index)), &(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[0]), sizeof(ULONG)); /* Use case of memcpy is verified. */
404     (*index) += (ULONG)sizeof(ULONG);
405     memcpy((buffer_ptr + (*index)), &(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[1]), sizeof(ULONG)); /* Use case of memcpy is verified. */
406     (*index) += (ULONG)sizeof(ULONG);
407     memcpy((buffer_ptr + (*index)), &(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[2]), sizeof(ULONG)); /* Use case of memcpy is verified. */
408     (*index) += (ULONG)sizeof(ULONG);
409     memcpy((buffer_ptr + (*index)), &(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[3]), sizeof(ULONG)); /* Use case of memcpy is verified. */
410     (*index) += (ULONG)sizeof(ULONG);
411 
412     /* Swap bytes back. */
413     NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[0]);
414     NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[1]);
415     NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[2]);
416     NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[3]);
417 
418     /* Add the preferred lifetime and valid lifetime option.  */
419     if((dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) ||
420        (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type == NX_DHCPV6_MESSAGE_TYPE_CONFIRM) ||
421        (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type == NX_DHCPV6_MESSAGE_TYPE_DECLINE) ||
422        (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type == NX_DHCPV6_MESSAGE_TYPE_RELEASE))
423     {
424 
425         /* When sending a confirm request, DHCPv6 Client should set its T1,T2,preferred-lifetime and
426            valid-lifetime to zero, as the server will ignore these fields, RFC3315,page41.  */
427         memset((buffer_ptr + (*index)), 0, sizeof(ULONG));
428         (*index) += (ULONG)sizeof(ULONG);
429         memset((buffer_ptr + (*index)), 0, sizeof(ULONG));
430         (*index) += (ULONG)sizeof(ULONG);
431     }
432     else
433     {
434 
435         /* Adjust for endianness. */
436         NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_preferred_lifetime);
437         NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_valid_lifetime);
438 
439         memcpy((buffer_ptr + (*index)), &(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_preferred_lifetime), sizeof(ULONG)); /* Use case of memcpy is verified. */
440         (*index) += (ULONG)sizeof(ULONG);
441         memcpy((buffer_ptr + (*index)), &(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_valid_lifetime), sizeof(ULONG)); /* Use case of memcpy is verified. */
442         (*index) += (ULONG)sizeof(ULONG);
443 
444         /* Swap bytes back. */
445         NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_preferred_lifetime);
446         NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_valid_lifetime);
447 
448     }
449 
450     return NX_SUCCESS;
451 }
452 
453 
454 /**************************************************************************/
455 /*                                                                        */
456 /*  FUNCTION                                               RELEASE        */
457 /*                                                                        */
458 /*    _nx_dhcpv6_add_iana                                 PORTABLE C      */
459 /*                                                           6.1          */
460 /*  AUTHOR                                                                */
461 /*                                                                        */
462 /*    Yuxin Zhou, Microsoft Corporation                                   */
463 /*                                                                        */
464 /*  DESCRIPTION                                                           */
465 /*                                                                        */
466 /*    This function adds the IANA option to the Client request  packet    */
467 /*    using the Client IANA on record.  Also checks to make sure adding   */
468 /*    the IANA option does not go past the end of the packet payload. If  */
469 /*    exist IA options, it will call the service to add the IA option     */
470 /*    within the IANA option data. It then updates the IANA length field  */
471 /*    for the embedded IA option.                                         */
472 /*                                                                        */
473 /*  INPUT                                                                 */
474 /*                                                                        */
475 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
476 /*    buffer_ptr                        Pointer to request packet buffer  */
477 /*    index                             Location into buffer to write data*/
478 /*                                                                        */
479 /*  OUTPUT                                                                */
480 /*                                                                        */
481 /*    status                            Actual completion status          */
482 /*    NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD                               */
483 /*                                      Not enough room for the IANA      */
484 /*                                           option in the packet payload */
485 /*  CALLS                                                                 */
486 /*                                                                        */
487 /*    _nx_dhcpv6_add_ia_address         Adds the IA option to buffer      */
488 /*    memset                            Clears specified area of memory   */
489 /*    memcpy                            Copies specified area of memory   */
490 /*                                                                        */
491 /*  CALLED BY                                                             */
492 /*                                                                        */
493 /*    _nx_dhcpv6_send_request           Compiles and sends the Client     */
494 /*                                            DHCPv6 request              */
495 /*                                                                        */
496 /*  RELEASE HISTORY                                                       */
497 /*                                                                        */
498 /*    DATE              NAME                      DESCRIPTION             */
499 /*                                                                        */
500 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
501 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
502 /*                                            verified memcpy use cases,  */
503 /*                                            resulting in version 6.1    */
504 /*                                                                        */
505 /**************************************************************************/
_nx_dhcpv6_add_iana(NX_DHCPV6 * dhcpv6_ptr,UCHAR * buffer_ptr,UINT * index)506 UINT _nx_dhcpv6_add_iana(NX_DHCPV6 *dhcpv6_ptr, UCHAR *buffer_ptr, UINT *index)
507 {
508 
509 UINT    status;
510 UINT    temp_index;
511 UINT    ia_index;
512 UINT    ia_length;
513 ULONG   message_word;
514 ULONG   available_payload;
515 
516 
517     /* Initialize the completion status variable. */
518     status = NX_SUCCESS;
519     ia_length = 0;
520 
521     /* Compute the available payload in the packet buffer. */
522     available_payload = dhcpv6_ptr -> nx_dhcpv6_pool_ptr -> nx_packet_pool_payload_size -
523                         (ULONG)sizeof(NX_IPV6_HEADER) - (ULONG)sizeof(NX_UDP_HEADER) - *index;
524 
525     /* Check if the client IANA will fit in the packet buffer. */
526     if (available_payload < (((ULONG)dhcpv6_ptr -> nx_dhcpv6_iana.nx_option_length) + 4))
527     {
528 
529         /* Hmmm... not enough! Can't do it. */
530         return NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD;
531     }
532 
533     /* Save this location in the buffer. */
534     temp_index = *index;
535 
536     /* Skip the option code and option lenght of IA_NA, write these option after padding the all IA option. */
537     (*index) += (ULONG)sizeof(ULONG);
538 
539     /* Add the IA_NA ID.  */
540     NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_iana.nx_IA_NA_id);
541     memcpy((buffer_ptr + (*index)), &(dhcpv6_ptr -> nx_dhcpv6_iana.nx_IA_NA_id), sizeof(ULONG)); /* Use case of memcpy is verified. */
542     (*index) += (ULONG)sizeof(ULONG);
543     NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_iana.nx_IA_NA_id);
544 
545     /* Add the T1 and T2 option.  */
546     if((dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) ||
547        (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type == NX_DHCPV6_MESSAGE_TYPE_CONFIRM) ||
548        (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type == NX_DHCPV6_MESSAGE_TYPE_DECLINE) ||
549        (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type == NX_DHCPV6_MESSAGE_TYPE_RELEASE))
550     {
551 
552         /* When sending a confirm request, DHCPv6 Client should set its T1,T2,preferred-lifetime and
553            valid-lifetime to zero, as the server will ignore these fields, RFC3315,page41.  */
554         memset((buffer_ptr + (*index)), 0, sizeof(ULONG)); /* Use case of memcpy is verified. */
555         (*index) += (ULONG)sizeof(ULONG);
556         memset((buffer_ptr + (*index)), 0, sizeof(ULONG)); /* Use case of memcpy is verified. */
557         (*index) += (ULONG)sizeof(ULONG);
558     }
559     else
560     {
561 
562         /* Adjust the data.  */
563         NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_iana.nx_T1);
564         NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_iana.nx_T2);
565 
566         memcpy((buffer_ptr + (*index)), &(dhcpv6_ptr -> nx_dhcpv6_iana.nx_T1), sizeof(ULONG)); /* Use case of memcpy is verified. */
567         (*index) += (ULONG)sizeof(ULONG);
568         memcpy((buffer_ptr + (*index)), &(dhcpv6_ptr -> nx_dhcpv6_iana.nx_T2), sizeof(ULONG)); /* Use case of memcpy is verified. */
569         (*index) += (ULONG)sizeof(ULONG);
570 
571         /* Swap bytes back. */
572         NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_iana.nx_T1);
573         NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_iana.nx_T2);
574     }
575 
576     for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
577     {
578 
579         /* Check the IA address status.  */
580         if(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status)
581         {
582 
583             /* Yes, so add one...*/
584             status = _nx_dhcpv6_add_ia_address(dhcpv6_ptr, buffer_ptr, index, ia_index);
585 
586             /* Was the IA address option get appended successfully? */
587             if (status == NX_SUCCESS)
588             {
589 
590                 /* Update the IA address to record the IANA option length.  */
591                 ia_length = (UINT)(ia_length + dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_option_length + 4);
592             }
593         }
594     }
595 
596     /* Clear memory to make the first word of the IA-NA header. */
597     memset(&message_word, 0, sizeof(ULONG));
598 
599     /* Set the IA_NA option code and option length.  */
600     dhcpv6_ptr -> nx_dhcpv6_iana.nx_op_code = NX_DHCPV6_OP_IA_NA;
601     dhcpv6_ptr -> nx_dhcpv6_iana.nx_option_length = (USHORT)(ia_length + 12);
602 
603     /* Write the IANA opcode and data length into one word. */
604     message_word = (((ULONG)(dhcpv6_ptr -> nx_dhcpv6_iana.nx_op_code)) << 16);
605     message_word |= dhcpv6_ptr -> nx_dhcpv6_iana.nx_option_length;
606 
607     /* Adjust for endianness. */
608     NX_CHANGE_ULONG_ENDIAN(message_word);
609 
610     /* Copy the word into the packet buffer going to the server. */
611     memcpy((buffer_ptr + temp_index), &message_word, sizeof(ULONG)); /* Use case of memcpy is verified. */
612 
613     return NX_SUCCESS;
614 }
615 
616 
617 /**************************************************************************/
618 /*                                                                        */
619 /*  FUNCTION                                               RELEASE        */
620 /*                                                                        */
621 /*    _nx_dhcpv6_add_option_request                       PORTABLE C      */
622 /*                                                           6.1          */
623 /*  AUTHOR                                                                */
624 /*                                                                        */
625 /*    Yuxin Zhou, Microsoft Corporation                                   */
626 /*                                                                        */
627 /*  DESCRIPTION                                                           */
628 /*                                                                        */
629 /*    This function adds the option request option to the Client request  */
630 /*    packet using the internal 'register' in the DHCPv6 Client instance  */
631 /*    for what DHCPv6 options have been set or cleared. Also checks to    */
632 /*    make sure it does not go past the end of the packet payload.        */
633 /*                                                                        */
634 /*  INPUT                                                                 */
635 /*                                                                        */
636 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
637 /*    buffer_ptr                        Pointer to request packet buffer  */
638 /*    index                             Location into buffer to write data*/
639 /*                                                                        */
640 /*  OUTPUT                                                                */
641 /*                                                                        */
642 /*    NX_SUCCESS                        Successful completion status      */
643 /*    NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD                               */
644 /*                                      Not enough room for the option    */
645 /*                                       request in the packet payload    */
646 /*  CALLS                                                                 */
647 /*                                                                        */
648 /*    memset                            Clears specified area of memory   */
649 /*    memcpy                            Copies specified area of memory   */
650 /*                                                                        */
651 /*  CALLED BY                                                             */
652 /*                                                                        */
653 /*    _nx_dhcpv6_send_request           Compiles and sends the Client     */
654 /*                                            DHCPv6 request              */
655 /*                                                                        */
656 /*  RELEASE HISTORY                                                       */
657 /*                                                                        */
658 /*    DATE              NAME                      DESCRIPTION             */
659 /*                                                                        */
660 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
661 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
662 /*                                            verified memcpy use cases,  */
663 /*                                            resulting in version 6.1    */
664 /*                                                                        */
665 /**************************************************************************/
_nx_dhcpv6_add_option_request(NX_DHCPV6 * dhcpv6_ptr,UCHAR * buffer_ptr,UINT * index)666 UINT _nx_dhcpv6_add_option_request(NX_DHCPV6 *dhcpv6_ptr, UCHAR *buffer_ptr, UINT *index)
667 {
668 
669 USHORT   message_word;
670 USHORT   option_list;
671 USHORT   option_length = 0;
672 UCHAR    *option_length_ptr;
673 ULONG    available_payload;
674 
675 
676     /* Compute the available payload for DHCP data in the packet buffer. */
677     available_payload = (dhcpv6_ptr -> nx_dhcpv6_pool_ptr -> nx_packet_pool_payload_size -
678                          (ULONG)sizeof(NX_IPV6_HEADER) - (ULONG)sizeof(NX_UDP_HEADER) - *index);
679 
680     /* Check if the option request option will fit in the packet buffer. */
681     if (available_payload < (((ULONG)(dhcpv6_ptr -> nx_dhcpv6_option_request.nx_option_length)) + 4))
682     {
683 
684         /* Hmmm... not enough! Can't do it. */
685         return NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD;
686     }
687 
688     /* Set a local variable for convenience. */
689     option_list = dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request;
690 
691     /* Update the option code.
692        Adjust for endianness. */
693     NX_CHANGE_USHORT_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_code);
694 
695     /* Copy the option code to the packet. */
696     memcpy((buffer_ptr + (*index)), &(dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_code), sizeof(USHORT)); /* Use case of memcpy is verified. */
697     *index += (ULONG)sizeof(USHORT);
698 
699     /* Swap bytes back. */
700     NX_CHANGE_USHORT_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_code);
701 
702     /* Record the option length pointer and skip it, update the option length after fill the option data.  */
703     option_length_ptr = buffer_ptr + (*index);
704     *index += (ULONG)sizeof(USHORT);
705 
706     /* Now check to see which options we add as option data: */
707 
708     /* Is the DNS server option requested? */
709     if(option_list & NX_DHCPV6_DNS_SERVER_OPTION)
710     {
711 
712         /* Yes, add this option code into the option request data. */
713         message_word = NX_DHCPV6_OP_DNS_SERVER;
714 
715         /* Adjust for endianness. */
716         NX_CHANGE_USHORT_ENDIAN(message_word);
717 
718         memcpy((buffer_ptr + (*index)), &message_word, sizeof(SHORT)); /* Use case of memcpy is verified. */
719 
720         /* Update the location of the buffer write pointer. */
721         *index += (ULONG)sizeof(SHORT);
722         option_length = (USHORT)(option_length + sizeof(SHORT));
723     }
724 
725     /* Is the timeS server option requested? */
726     if(option_list & NX_DHCPV6_SNTP_SERVER_OPTION)
727     {
728 
729         /* Yes, add this option code into the option request data. */
730         message_word = NX_DHCPV6_OP_SNTP_SERVER;
731 
732         /* Adjust for endianness. */
733         NX_CHANGE_USHORT_ENDIAN(message_word);
734 
735         memcpy((buffer_ptr + (*index)), &message_word, sizeof(SHORT)); /* Use case of memcpy is verified. */
736 
737         /* Update the location of the buffer write pointer. */
738         *index += (ULONG)sizeof(SHORT);
739         option_length = (USHORT)(option_length + sizeof(SHORT));
740     }
741 
742     /* Is the time zone option requested? */
743     if(option_list & NX_DHCPV6_NEW_POSIX_TIMEZONE_OPTION)
744     {
745 
746         /* Yes, add this option code into the option request data. */
747         message_word = NX_DHCPV6_OP_NEW_POSIX_TIMEZONE;
748 
749         /* Adjust for endianness. */
750         NX_CHANGE_USHORT_ENDIAN(message_word);
751 
752         memcpy((buffer_ptr + (*index)), &message_word, sizeof(SHORT)); /* Use case of memcpy is verified. */
753 
754         /* Update the location of the buffer write pointer. */
755         *index += (ULONG)sizeof(SHORT);
756         option_length = (USHORT)(option_length + sizeof(SHORT));
757     }
758 
759     /* Is the domain name option requested? */
760     if(option_list & NX_DHCPV6_DOMAIN_NAME_OPTION)
761     {
762 
763         /* Yes, add this option code into the option request data. */
764         message_word = NX_DHCPV6_OP_DOMAIN_NAME;
765 
766         /* Adjust for endianness. */
767         NX_CHANGE_USHORT_ENDIAN(message_word);
768 
769         memcpy((buffer_ptr + (*index)), &message_word, sizeof(SHORT)); /* Use case of memcpy is verified. */
770 
771         /* Update the location of the buffer write pointer. */
772         *index += (ULONG)sizeof(SHORT);
773         option_length = (USHORT)(option_length + sizeof(SHORT));
774     }
775 
776     /* Is the fully qualified domain name option requested?
777        A client MUST only include the Client FQDN option in SOLICIT, REQUEST, RENEW, or REBIND message.
778        A client that sends the Client FQDN option MUST also include the option in the Option Requst option
779        if it expects the server to include the Client FQDN option in any responses. RFC4704, Section5, Page7.  */
780     if(((dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) ||
781         (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) ||
782         (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type == NX_DHCPV6_MESSAGE_TYPE_RENEW) ||
783         (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type == NX_DHCPV6_MESSAGE_TYPE_REBIND)) &&
784        (option_list & NX_DHCPV6_CLIENT_FQDN_OPTION))
785     {
786 
787         /* Yes, add this option code into the option request data. */
788         message_word = NX_DHCPV6_OP_CLIENT_FQDN;
789 
790         /* Adjust for endianness. */
791         NX_CHANGE_USHORT_ENDIAN(message_word);
792 
793         memcpy((buffer_ptr + (*index)), &message_word, sizeof(SHORT)); /* Use case of memcpy is verified. */
794 
795         /* Update the location of the buffer write pointer. */
796         *index += (ULONG)sizeof(SHORT);
797         option_length = (USHORT)(option_length + sizeof(SHORT));
798     }
799 
800     /* Now record and update the option lenght.  */
801     dhcpv6_ptr -> nx_dhcpv6_option_request.nx_option_length = option_length;
802     NX_CHANGE_USHORT_ENDIAN(option_length);
803     memcpy(option_length_ptr, &option_length, sizeof(SHORT)); /* Use case of memcpy is verified. */
804 
805     return NX_SUCCESS;
806 }
807 
808 
809 /**************************************************************************/
810 /*                                                                        */
811 /*  FUNCTION                                               RELEASE        */
812 /*                                                                        */
813 /*    _nx_dhcpv6_add_server_duid                          PORTABLE C      */
814 /*                                                           6.1          */
815 /*  AUTHOR                                                                */
816 /*                                                                        */
817 /*    Yuxin Zhou, Microsoft Corporation                                   */
818 /*                                                                        */
819 /*  DESCRIPTION                                                           */
820 /*                                                                        */
821 /*    This function adds the server DUID to the Client request packet     */
822 /*    based on the server DUID on record, checking to make sure it does   */
823 /*    not go past the end of the packet payload.                          */
824 /*                                                                        */
825 /*  INPUT                                                                 */
826 /*                                                                        */
827 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
828 /*    received_buffer                   Pointer to server reply           */
829 /*    length                            Size of server reply buffer       */
830 /*                                                                        */
831 /*  OUTPUT                                                                */
832 /*                                                                        */
833 /*    NX_SUCCESS                        Successful completion status      */
834 /*    NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD                               */
835 /*                                      Not enough room for the server    */
836 /*                                        DUID in the packet payload      */
837 /*  CALLS                                                                 */
838 /*                                                                        */
839 /*    memset                            Clears specified area of memory   */
840 /*    memcpy                            Copies specified area of memory   */
841 /*                                                                        */
842 /*  CALLED BY                                                             */
843 /*                                                                        */
844 /*    _nx_dhcpv6_send_request           Compiles and sends the Client     */
845 /*                                            DHCPv6 request              */
846 /*                                                                        */
847 /*  RELEASE HISTORY                                                       */
848 /*                                                                        */
849 /*    DATE              NAME                      DESCRIPTION             */
850 /*                                                                        */
851 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
852 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
853 /*                                            verified memcpy use cases,  */
854 /*                                            resulting in version 6.1    */
855 /*                                                                        */
856 /**************************************************************************/
_nx_dhcpv6_add_server_duid(NX_DHCPV6 * dhcpv6_ptr,UCHAR * buffer_ptr,UINT * index)857 UINT _nx_dhcpv6_add_server_duid(NX_DHCPV6 *dhcpv6_ptr, UCHAR *buffer_ptr, UINT *index)
858 {
859 
860 ULONG   message_word;
861 ULONG   available_payload;
862 UCHAR   mac[8];
863 UINT    i = 0;
864 
865 
866     /* Compute the available payload for DHCP data in the packet buffer. */
867     available_payload = (dhcpv6_ptr -> nx_dhcpv6_pool_ptr -> nx_packet_pool_payload_size -
868                          (ULONG)sizeof(NX_IPV6_HEADER) - (ULONG)sizeof(NX_UDP_HEADER) - *index);
869 
870     /* Check if the largest possible server DUID will fit in the packet buffer. */
871     if (available_payload < (((ULONG)(dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_option_length)) + 4))
872     {
873 
874         /* Hmmm... not enough! Can't do it. */
875         return NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD;
876     }
877 
878     /* Make sure the Client has a valid Server DUID. */
879     if (dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_op_code != NX_DHCPV6_OP_SERVER_ID)
880     {
881 
882         /* Missing or invalid option data.  */
883         return NX_DHCPV6_INVALID_SERVER_DUID;
884     }
885 
886     /* Build the header from the client's record of its DHCPv6 Server DUID. */
887     message_word = (((ULONG)(dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_op_code)) << 16);
888     message_word |= (dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_option_length);
889 
890     /* Adjust for endianness. */
891     NX_CHANGE_ULONG_ENDIAN(message_word);
892 
893     /* Copy first half of the Server DUID option to packet buffer. */
894     memcpy((buffer_ptr + (*index)), &message_word, sizeof(ULONG)); /* Use case of memcpy is verified. */
895     *index += (ULONG)sizeof(ULONG);
896 
897     /* Build the DUID type and hardware type.  */
898     message_word = (((ULONG)(dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_duid_type)) << 16);
899     message_word |= dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_hardware_type;
900 
901     /* Adjust for endianness. */
902     NX_CHANGE_ULONG_ENDIAN(message_word);
903 
904     /* Set up the DUID type and hardware type. */
905     memcpy((buffer_ptr + (*index)), &message_word, sizeof(UINT)); /* Use case of memcpy is verified. */
906     *index += (ULONG)sizeof(UINT);
907 
908     /* Include the 'time' field if this is a Link layer time DUID type. */
909     if (dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_duid_type == NX_DHCPV6_DUID_TYPE_LINK_TIME)
910     {
911 
912         /* Build the time.  */
913         message_word = dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_duid_time;
914 
915         /* Adjust for endianness. */
916         NX_CHANGE_ULONG_ENDIAN(message_word);
917 
918         /* Set up the time.  */
919         memcpy((buffer_ptr + (*index)), &message_word, sizeof(ULONG)); /* Use case of memcpy is verified. */
920         (*index) += (ULONG)sizeof(ULONG);
921     }
922 
923     /* Build the link layer address.  */
924     if (dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_hardware_type == NX_DHCPV6_CLIENT_HARDWARE_TYPE_ETHERNET)
925     {
926 
927         /* The length of link layer address is 48 bit.  */
928 
929         /* Build the MSW.  */
930         mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_link_layer_address_msw >> 8);
931         mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_link_layer_address_msw);
932     }
933     else if(dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_hardware_type == NX_DHCPV6_CLIENT_HARDWARE_TYPE_EUI_64)
934     {
935 
936         /* The length of link layer address is 64 bits.  */
937 
938         /* Build the MSW.  */
939         mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_link_layer_address_msw >> 24);
940         mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_link_layer_address_msw >> 16);
941         mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_link_layer_address_msw >> 8);
942         mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_link_layer_address_msw);
943     }
944 
945     /* Build the LSW.  */
946     mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_link_layer_address_lsw >> 24);
947     mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_link_layer_address_lsw >> 16);
948     mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_link_layer_address_lsw >> 8);
949     mac[i++] = (UCHAR)(dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_link_layer_address_lsw);
950 
951     /* Set up the link layer address.  */
952     memcpy((buffer_ptr + (*index)), mac, i); /* Use case of memcpy is verified. */
953     (*index) += i;
954 
955     return NX_SUCCESS;
956 }
957 
958 
959 /**************************************************************************/
960 /*                                                                        */
961 /*  FUNCTION                                               RELEASE        */
962 /*                                                                        */
963 /*    _nx_dhcpv6_add_client_FQDN                          PORTABLE C      */
964 /*                                                           6.1          */
965 /*  AUTHOR                                                                */
966 /*                                                                        */
967 /*    Yuxin Zhou, Microsoft Corporation                                   */
968 /*                                                                        */
969 /*  DESCRIPTION                                                           */
970 /*                                                                        */
971 /*    This function adds the DHCPv6 Client FQDN Option to the Client      */
972 /*    request packet , checking to make sure it does not go past the end  */
973 /*    of the packet payload.                                              */
974 /*                                                                        */
975 /*  INPUT                                                                 */
976 /*                                                                        */
977 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
978 /*    received_buffer                   Pointer to server reply           */
979 /*    length                            Size of server reply buffer       */
980 /*                                                                        */
981 /*  OUTPUT                                                                */
982 /*                                                                        */
983 /*    NX_SUCCESS                        Successful completion status      */
984 /*    NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD                               */
985 /*                                      Not enough room for the server    */
986 /*                                        DUID in the packet payload      */
987 /*  CALLS                                                                 */
988 /*                                                                        */
989 /*    memset                            Clears specified area of memory   */
990 /*    memcpy                            Copies specified area of memory   */
991 /*                                                                        */
992 /*  CALLED BY                                                             */
993 /*                                                                        */
994 /*    _nx_dhcpv6_send_request           Compiles and sends the Client     */
995 /*                                            DHCPv6 request              */
996 /*                                                                        */
997 /*  RELEASE HISTORY                                                       */
998 /*                                                                        */
999 /*    DATE              NAME                      DESCRIPTION             */
1000 /*                                                                        */
1001 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1002 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
1003 /*                                            verified memcpy use cases,  */
1004 /*                                            resulting in version 6.1    */
1005 /*                                                                        */
1006 /**************************************************************************/
_nx_dhcpv6_add_client_FQDN(NX_DHCPV6 * dhcpv6_ptr,UCHAR * buffer_ptr,UINT * index)1007 UINT _nx_dhcpv6_add_client_FQDN(NX_DHCPV6 *dhcpv6_ptr, UCHAR *buffer_ptr, UINT *index)
1008 {
1009 
1010 ULONG   message_word;
1011 ULONG   available_payload;
1012 UINT    domain_name_length;
1013 
1014 
1015     /* Compute the available payload for DHCP data in the packet buffer. */
1016     available_payload = (dhcpv6_ptr -> nx_dhcpv6_pool_ptr -> nx_packet_pool_payload_size -
1017                          (ULONG)sizeof(NX_IPV6_HEADER) - (ULONG)sizeof(NX_UDP_HEADER) - *index);
1018 
1019     /* Check if the largest possible server DUID will fit in the packet buffer. */
1020     if (available_payload < (((ULONG)(dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_option_length)) + 4))
1021     {
1022 
1023         /* Hmmm... not enough! Can't do it. */
1024         return NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD;
1025     }
1026 
1027     memset(&message_word, 0, sizeof(ULONG));
1028 
1029     /* Set the option code and option length.  */
1030     message_word = (((ULONG)(dhcpv6_ptr -> nx_dhcpv6_client_FQDN.nx_op_code)) << 16);
1031     message_word |= (dhcpv6_ptr -> nx_dhcpv6_client_FQDN.nx_op_length);
1032 
1033     /* Adjust for endianness. */
1034     NX_CHANGE_ULONG_ENDIAN(message_word);
1035 
1036     /* Add the option code and option length into packet buffer. */
1037     memcpy((buffer_ptr + (*index)), &message_word, sizeof(ULONG)); /* Use case of memcpy is verified. */
1038     *index += (ULONG)sizeof(ULONG);
1039 
1040     /* Add the flags into packet buffer.  */
1041     *(buffer_ptr + (*index)) = dhcpv6_ptr -> nx_dhcpv6_client_FQDN.nx_flags;
1042     *index += 1;
1043 
1044     /* Encode the domain name into the packet buffer.  */
1045     domain_name_length = _nx_dhcpv6_name_string_encode(buffer_ptr + (*index), (UCHAR *)dhcpv6_ptr -> nx_dhcpv6_client_FQDN.nx_domain_name);
1046     *index += domain_name_length;
1047 
1048     return NX_SUCCESS;
1049 }
1050 
1051 
1052 /**************************************************************************/
1053 /*                                                                        */
1054 /*  FUNCTION                                               RELEASE        */
1055 /*                                                                        */
1056 /*    _nxe_dhcpv6_client_create                           PORTABLE C      */
1057 /*                                                           6.1          */
1058 /*  AUTHOR                                                                */
1059 /*                                                                        */
1060 /*    Yuxin Zhou, Microsoft Corporation                                   */
1061 /*                                                                        */
1062 /*  DESCRIPTION                                                           */
1063 /*                                                                        */
1064 /*    This function performs error checking on the NetX create dhcpv6     */
1065 /*    client service.                                                     */
1066 /*                                                                        */
1067 /*  INPUT                                                                 */
1068 /*                                                                        */
1069 /*    dhcpv6_ptr                          Pointer to DHCPV6 Client        */
1070 /*    ip_ptr                              Pointer to Client IP instance   */
1071 /*    name_ptr                            DHCPV6 name pointer             */
1072 /*    packet_pool_ptr                     Pointer to Client packet pool   */
1073 /*    stack_ptr                           Pointer to free memory          */
1074 /*    stack_size                          Size of client stack memory     */
1075 /*    dhcpv6_state_change_notify          Client state change handler     */
1076 /*    dhcpv6_server_error_handler         Server error status handler     */
1077 /*                                                                        */
1078 /*  OUTPUT                                                                */
1079 /*                                                                        */
1080 /*    status                              Completion status               */
1081 /*    NX_PTR_ERROR                        Invalid pointer input           */
1082 /*    NX_DHCPV6_PARAM_ERROR               Invalid non pointer input       */
1083 /*                                                                        */
1084 /*  CALLS                                                                 */
1085 /*                                                                        */
1086 /*    _nx_dhcpv6_client_create           Actual Client create function    */
1087 /*                                                                        */
1088 /*  CALLED BY                                                             */
1089 /*                                                                        */
1090 /*    Application Code                                                    */
1091 /*                                                                        */
1092 /*  RELEASE HISTORY                                                       */
1093 /*                                                                        */
1094 /*    DATE              NAME                      DESCRIPTION             */
1095 /*                                                                        */
1096 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1097 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1098 /*                                            resulting in version 6.1    */
1099 /*                                                                        */
1100 /**************************************************************************/
_nxe_dhcpv6_client_create(NX_DHCPV6 * dhcpv6_ptr,NX_IP * ip_ptr,CHAR * name_ptr,NX_PACKET_POOL * packet_pool_ptr,VOID * stack_ptr,ULONG stack_size,VOID (* dhcpv6_state_change_notify)(struct NX_DHCPV6_STRUCT * dhcpv6_ptr,UINT old_state,UINT new_state),VOID (* dhcpv6_server_error_handler)(struct NX_DHCPV6_STRUCT * dhcpv6_ptr,UINT op_code,UINT status_code,UINT message_type))1101 UINT  _nxe_dhcpv6_client_create(NX_DHCPV6 *dhcpv6_ptr, NX_IP *ip_ptr, CHAR *name_ptr,
1102                                 NX_PACKET_POOL *packet_pool_ptr, VOID *stack_ptr, ULONG stack_size,
1103                                 VOID (*dhcpv6_state_change_notify)(struct NX_DHCPV6_STRUCT *dhcpv6_ptr, UINT old_state, UINT new_state),
1104                                 VOID (*dhcpv6_server_error_handler)(struct NX_DHCPV6_STRUCT *dhcpv6_ptr, UINT op_code, UINT status_code, UINT message_type))
1105 {
1106 
1107 UINT    status;
1108 
1109 
1110     /* Check for invalid pointer input.  */
1111     if (!dhcpv6_ptr ||!ip_ptr || !packet_pool_ptr || !stack_ptr)
1112     {
1113 
1114         return NX_PTR_ERROR;
1115     }
1116 
1117     /* Check for invalid non pointer input. */
1118     if ((ip_ptr -> nx_ip_id != NX_IP_ID) || (stack_size < TX_MINIMUM_STACK))
1119     {
1120 
1121         return NX_DHCPV6_PARAM_ERROR;
1122     }
1123 
1124     /* Call actual DHCPV6 create service.  */
1125     status =  _nx_dhcpv6_client_create(dhcpv6_ptr, ip_ptr, name_ptr, packet_pool_ptr, stack_ptr, stack_size,
1126                                        dhcpv6_state_change_notify, dhcpv6_server_error_handler);
1127 
1128     /* Return status.  */
1129     return(status);
1130 }
1131 
1132 
1133 /**************************************************************************/
1134 /*                                                                        */
1135 /*  FUNCTION                                               RELEASE        */
1136 /*                                                                        */
1137 /*    _nx_dhcpv6_client_create                            PORTABLE C      */
1138 /*                                                           6.1          */
1139 /*  AUTHOR                                                                */
1140 /*                                                                        */
1141 /*    Yuxin Zhou, Microsoft Corporation                                   */
1142 /*                                                                        */
1143 /*  DESCRIPTION                                                           */
1144 /*                                                                        */
1145 /*    This function creates the DHCPv6 Client instance with a Netx packet */
1146 /*    pool, processing thread, and various flag event queues, timers and  */
1147 /*    mutexes necessary for DHCPv6 Client operations. Reocrd the DHCPv6   */
1148 /*    pointer for DAD callback function process.                          */
1149 /*                                                                        */
1150 /*  INPUT                                                                 */
1151 /*                                                                        */
1152 /*    dhcpv6_ptr                          Pointer to DHCPV6 Client        */
1153 /*    ip_ptr                              Pointer to Client IP instance   */
1154 /*    name_ptr                            DHCPV6 name pointer             */
1155 /*    packet_pool_ptr                     Pointer to Client packet pool   */
1156 /*    stack_ptr                           Pointer to free memory          */
1157 /*    stack_size                          Size of Client stack memory     */
1158 /*    dhcpv6_state_change_notify          Client state change handler     */
1159 /*    dhcpv6_server_error_handler         Server error status handler     */
1160 /*                                                                        */
1161 /*  OUTPUT                                                                */
1162 /*                                                                        */
1163 /*    status                                Actual completion status      */
1164 /*    NX_SUCCESS                            Successful completion status  */
1165 /*                                                                        */
1166 /*  CALLS                                                                 */
1167 /*                                                                        */
1168 /*    tx_event_flags_create                Create ThreadX flag event queue*/
1169 /*    tx_mutex_create                      Create mutex lock on resource  */
1170 /*    nx_packet_pool_delete                 Delete the DHCPV6 packet pool */
1171 /*    nx_udp_socket_create                  Create the DHCPV6 UDP socket  */
1172 /*    nx_udp_socket_delete                  Delete the DHCPV6 UDP socket  */
1173 /*    tx_mutex_create                       Create DHCPV6 mutex           */
1174 /*    tx_mutex_delete                       Delete DHCPV6 mutex           */
1175 /*    tx_thread_create                      Create DHCPV6 thread          */
1176 /*    tx_timer_create                       Create DHCPV6 timer           */
1177 /*    tx_timer_delete                       Delete DHCPV6 timer           */
1178 /*    nxd_ipv6_address_change_notify        Set the DAD callback function */
1179 /*                                                                        */
1180 /*  CALLED BY                                                             */
1181 /*                                                                        */
1182 /*    Application Code                                                    */
1183 /*                                                                        */
1184 /*  RELEASE HISTORY                                                       */
1185 /*                                                                        */
1186 /*    DATE              NAME                      DESCRIPTION             */
1187 /*                                                                        */
1188 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1189 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1190 /*                                            resulting in version 6.1    */
1191 /*                                                                        */
1192 /**************************************************************************/
_nx_dhcpv6_client_create(NX_DHCPV6 * dhcpv6_ptr,NX_IP * ip_ptr,CHAR * name_ptr,NX_PACKET_POOL * packet_pool_ptr,VOID * stack_ptr,ULONG stack_size,VOID (* dhcpv6_state_change_notify)(struct NX_DHCPV6_STRUCT * dhcpv6_ptr,UINT old_state,UINT new_state),VOID (* dhcpv6_server_error_handler)(struct NX_DHCPV6_STRUCT * dhcpv6_ptr,UINT op_code,UINT status_code,UINT message_type))1193 UINT  _nx_dhcpv6_client_create(NX_DHCPV6 *dhcpv6_ptr, NX_IP *ip_ptr, CHAR *name_ptr,
1194                                NX_PACKET_POOL *packet_pool_ptr, VOID *stack_ptr, ULONG stack_size,
1195                                VOID (*dhcpv6_state_change_notify)(struct NX_DHCPV6_STRUCT *dhcpv6_ptr, UINT old_state, UINT new_state),
1196                                VOID (*dhcpv6_server_error_handler)(struct NX_DHCPV6_STRUCT *dhcpv6_ptr, UINT op_code, UINT status_code, UINT message_type))
1197 
1198 {
1199 
1200 UINT  status;
1201 
1202 
1203     /* Initialize the DHCPV6 control block to zero.  */
1204     memset((void *) dhcpv6_ptr, 0, sizeof(NX_DHCPV6));
1205 
1206     /* Initialize the DHCPV6 Server and Relay multicast address.  */
1207     memset(&All_DHCPv6_Relay_Servers_Address, 0, sizeof(NXD_ADDRESS));
1208     All_DHCPv6_Relay_Servers_Address.nxd_ip_version = NX_IP_VERSION_V6;
1209     All_DHCPv6_Relay_Servers_Address.nxd_ip_address.v6[0] = 0xff020000;
1210     All_DHCPv6_Relay_Servers_Address.nxd_ip_address.v6[1] = 0x00000000;
1211     All_DHCPv6_Relay_Servers_Address.nxd_ip_address.v6[2] = 0x00000000;
1212     All_DHCPv6_Relay_Servers_Address.nxd_ip_address.v6[3] = 0x00010002;
1213 
1214     /* Set the destination address.  */
1215     COPY_NXD_ADDRESS(&All_DHCPv6_Relay_Servers_Address, &(dhcpv6_ptr -> nx_dhcpv6_client_destination_address));
1216 
1217     /* Set the DHCPv6 IP pointer.  */
1218     dhcpv6_ptr -> nx_dhcpv6_ip_ptr =  ip_ptr;
1219 
1220     /* Set the DHCPV6 name.  */
1221     dhcpv6_ptr -> nx_dhcpv6_name =  name_ptr;
1222 
1223     /* If multihome support is available, default the client DHCP network to the primary interface. */
1224     dhcpv6_ptr -> nx_dhcpv6_client_interface_index = 0;
1225 
1226     /* Set the Client packet pool for sending messages to the Server. */
1227     dhcpv6_ptr -> nx_dhcpv6_pool_ptr = packet_pool_ptr;
1228 
1229     /* Create the IP timer event flag instance.  */
1230     status = tx_event_flags_create(&(dhcpv6_ptr -> nx_dhcpv6_events), "DHCPv6 Client Timer Events Queue");
1231 
1232     /* Check for error. */
1233     if (status != TX_SUCCESS)
1234     {
1235 
1236         return status;
1237     }
1238 
1239     /* Create the DHCPV6 client mutex.  */
1240     status =  tx_mutex_create(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex), "DHCPV6 Client Process State", TX_NO_INHERIT);
1241 
1242     /* Determine if the mutexes creation was successful.  */
1243     if (status)
1244     {
1245 
1246         /* Delete the flag queue.  */
1247         tx_event_flags_delete(&dhcpv6_ptr -> nx_dhcpv6_events);
1248 
1249         /* No, return error status.  */
1250         return status;
1251     }
1252 
1253     /* Create the DHCPV6 timer for keeping track of the IP lease's time remaining before expiration.  */
1254     status =  tx_timer_create(&(dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_timer), "NetX DHCPV6 Client IP Lease timer",
1255                               _nx_dhcpv6_IP_lifetime_timeout_entry, (ULONG)(ALIGN_TYPE)dhcpv6_ptr,
1256                               (NX_DHCPV6_IP_LIFETIME_TIMER_INTERVAL * NX_DHCPV6_TICKS_PER_SECOND),
1257                               (NX_DHCPV6_IP_LIFETIME_TIMER_INTERVAL * NX_DHCPV6_TICKS_PER_SECOND),
1258                               TX_NO_ACTIVATE);
1259 
1260     NX_TIMER_EXTENSION_PTR_SET(&(dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_timer), dhcpv6_ptr)
1261 
1262     /* Determine if the timer creation was successful.  */
1263     if (status)
1264     {
1265 
1266         /* Delete the mutex. */
1267         tx_mutex_delete(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
1268 
1269         /* Delete all the timers, since we don't know which create call fails. */
1270         tx_timer_delete(&(dhcpv6_ptr -> nx_dhcpv6_session_timer));
1271 
1272         /* Delete the UDP socket. */
1273         nx_udp_socket_delete(&(dhcpv6_ptr -> nx_dhcpv6_socket));
1274 
1275         /* Delete the packet pool. */
1276         /* Delete the flag queue. */
1277         tx_event_flags_delete(&dhcpv6_ptr -> nx_dhcpv6_events);
1278 
1279         /* No, return error status. */
1280         return status;
1281     }
1282 
1283     /* Create the DHCPV6 timer for keeping track of the DHCPv6 Client session time.  */
1284     status =  tx_timer_create(&(dhcpv6_ptr -> nx_dhcpv6_session_timer), "NetX DHCPV6 Client Session Duration timer",
1285                              _nx_dhcpv6_session_timeout_entry, (ULONG)(ALIGN_TYPE)dhcpv6_ptr,
1286                              (NX_DHCPV6_SESSION_TIMER_INTERVAL * NX_DHCPV6_TICKS_PER_SECOND),
1287                              (NX_DHCPV6_SESSION_TIMER_INTERVAL * NX_DHCPV6_TICKS_PER_SECOND),
1288                               TX_NO_ACTIVATE);
1289 
1290     NX_TIMER_EXTENSION_PTR_SET(&(dhcpv6_ptr -> nx_dhcpv6_session_timer), dhcpv6_ptr)
1291 
1292     /* Determine if the timers creation was successful.  */
1293     if (status)
1294     {
1295 
1296         /* Delete the mutex. */
1297         tx_mutex_delete(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
1298 
1299         /* Delete all the timers, since we don't know which create call fails. */
1300         tx_timer_delete(&(dhcpv6_ptr -> nx_dhcpv6_session_timer));
1301         tx_timer_delete(&(dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_timer));
1302 
1303         /* Delete the UDP socket. */
1304         nx_udp_socket_delete(&(dhcpv6_ptr -> nx_dhcpv6_socket));
1305 
1306         /* Delete the packet pool. */
1307         /* Delete the flag queue. */
1308         tx_event_flags_delete(&dhcpv6_ptr -> nx_dhcpv6_events);
1309 
1310         /* No, return error status. */
1311         return status;
1312     }
1313 
1314     /* Create the DHCPV6 processing thread. */
1315     status =  tx_thread_create(&(dhcpv6_ptr -> nx_dhcpv6_thread), "NetX DHCPV6 Client", _nx_dhcpv6_thread_entry,
1316                                (ULONG)(ALIGN_TYPE)dhcpv6_ptr, stack_ptr, stack_size,
1317                                NX_DHCPV6_THREAD_PRIORITY, NX_DHCPV6_THREAD_PRIORITY, 1, TX_DONT_START);
1318 
1319     NX_THREAD_EXTENSION_PTR_SET(&(dhcpv6_ptr -> nx_dhcpv6_thread), dhcpv6_ptr)
1320 
1321     /* Determine if the thread creation was successful. */
1322     if (status)
1323     {
1324 
1325         /* Delete the timers.  */
1326         tx_timer_delete(&(dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_timer));
1327         tx_timer_delete(&(dhcpv6_ptr -> nx_dhcpv6_session_timer));
1328 
1329         /* Delete the mutex.  */
1330         tx_mutex_delete(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
1331 
1332         /* Delete the flag queue.  */
1333         tx_event_flags_delete(&dhcpv6_ptr -> nx_dhcpv6_events);
1334 
1335         /* No, return error status.  */
1336         return status;
1337     }
1338 
1339     /* Create the DHCP socket. */
1340     status = nx_udp_socket_create(dhcpv6_ptr -> nx_dhcpv6_ip_ptr, &(dhcpv6_ptr -> nx_dhcpv6_socket), "NetX DHCPV6 Client",
1341                                   NX_DHCPV6_TYPE_OF_SERVICE, NX_DONT_FRAGMENT,
1342                                   NX_DHCPV6_TIME_TO_LIVE, NX_DHCPV6_QUEUE_DEPTH);
1343 
1344     /* Was the socket creation successful?  */
1345     if (status != NX_SUCCESS)
1346     {
1347 
1348         /* Delete the timers.  */
1349         tx_timer_delete(&(dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_timer));
1350         tx_timer_delete(&(dhcpv6_ptr -> nx_dhcpv6_session_timer));
1351 
1352         /* Delete the mutex.  */
1353         tx_mutex_delete(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
1354 
1355         /* Delete the flag queue.  */
1356         tx_event_flags_delete(&dhcpv6_ptr -> nx_dhcpv6_events);
1357 
1358         tx_thread_delete(&dhcpv6_ptr -> nx_dhcpv6_thread);
1359 
1360         /* No, return error status.  */
1361         return status;
1362     }
1363 
1364     /* Set the Client in the initial state.  */
1365     dhcpv6_ptr -> nx_dhcpv6_state =  NX_DHCPV6_STATE_INIT;
1366 
1367     /* Set the 'time accrued' on the Client global IP address at zero seconds. */
1368     dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_time_accrued = 0;
1369 
1370     /* Update the DHCPv6 Client ID.  */
1371     dhcpv6_ptr -> nx_dhcpv6_id =  NX_DHCPV6_ID;
1372 
1373     /* Save the DHCPV6 instance pointer in the socket. */
1374     dhcpv6_ptr -> nx_dhcpv6_socket.nx_udp_socket_reserved_ptr =  (void *) dhcpv6_ptr;
1375 
1376     /* Set up the elapsed time for the anticipated message exchange with the DHCPv6 Server. */
1377     dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_op_code = NX_DHCPV6_OP_ELAPSED_TIME;
1378     dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = 0;
1379 
1380     /* Set the elapsed time option data length, minus the option header. */
1381     dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_op_length = sizeof(NX_DHCPV6_ELAPSED_TIME) - 4;
1382 
1383     /* Set the option request option code. Cannot set the data length as yet. */
1384     dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_code = NX_DHCPV6_OP_OPTION_REQUEST;
1385 
1386     /* Assign the various handlers (server error messages and state change). */
1387     dhcpv6_ptr -> nx_dhcpv6_state_change_callback =  dhcpv6_state_change_notify;
1388     dhcpv6_ptr -> nx_dhcpv6_server_error_handler = dhcpv6_server_error_handler;
1389 
1390 #if !defined (NX_DISABLE_IPV6_DAD) && defined (NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY)
1391     /* Set the callback function to detect DAD process.
1392        If DAD failure, automatically set event to send DHCP decline meessage.
1393        Notice: other modules should not set the address change notify function again.  */
1394     status = nxd_ipv6_address_change_notify(dhcpv6_ptr -> nx_dhcpv6_ip_ptr, _nx_dhcpv6_ipv6_address_DAD_notify);
1395 
1396     /* Was the callback notify fucntion creation successful?  */
1397     if (status != NX_SUCCESS)
1398     {
1399 
1400         /* Delete the timers.  */
1401         tx_timer_delete(&(dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_timer));
1402         tx_timer_delete(&(dhcpv6_ptr -> nx_dhcpv6_session_timer));
1403 
1404         /* Delete the mutex.  */
1405         tx_mutex_delete(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
1406 
1407         /* Delete the flag queue.  */
1408         tx_event_flags_delete(&dhcpv6_ptr -> nx_dhcpv6_events);
1409 
1410         /* Delete the thread.  */
1411         tx_thread_delete(&dhcpv6_ptr -> nx_dhcpv6_thread);
1412 
1413         /* Delete the thread.  */
1414         nx_udp_socket_delete(&(dhcpv6_ptr -> nx_dhcpv6_socket));
1415 
1416         /* No, return error status.  */
1417         return status;
1418     }
1419 #endif
1420 
1421     /* Keep the DHCPv6 instance for DAD callback notify.  */
1422     _nx_dhcpv6_DAD_ptr = dhcpv6_ptr;
1423 
1424     /* Return a successful status.  */
1425     return(NX_SUCCESS);
1426 }
1427 
1428 
1429 /**************************************************************************/
1430 /*                                                                        */
1431 /*  FUNCTION                                               RELEASE        */
1432 /*                                                                        */
1433 /*    _nxe_dhcpv6_client_delete                           PORTABLE C      */
1434 /*                                                           6.1          */
1435 /*  AUTHOR                                                                */
1436 /*                                                                        */
1437 /*    Yuxin Zhou, Microsoft Corporation                                   */
1438 /*                                                                        */
1439 /*  DESCRIPTION                                                           */
1440 /*                                                                        */
1441 /*    This function performs error checking on the NetX delete dhcpv6     */
1442 /*    client service.                                                     */
1443 /*                                                                        */
1444 /*  INPUT                                                                 */
1445 /*                                                                        */
1446 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
1447 /*                                                                        */
1448 /*  OUTPUT                                                                */
1449 /*                                                                        */
1450 /*  OUTPUT                                                                */
1451 /*                                                                        */
1452 /*    status                              Completion status               */
1453 /*    NX_PTR_ERROR                        Invalid pointer input           */
1454 /*                                                                        */
1455 /*                                                                        */
1456 /*  CALLS                                                                 */
1457 /*                                                                        */
1458 /*    _nx_dhcpv6_client_delete            Actual DHCPV6 delete function   */
1459 /*                                                                        */
1460 /*  CALLED BY                                                             */
1461 /*                                                                        */
1462 /*    Application Code                                                    */
1463 /*                                                                        */
1464 /*  RELEASE HISTORY                                                       */
1465 /*                                                                        */
1466 /*    DATE              NAME                      DESCRIPTION             */
1467 /*                                                                        */
1468 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1469 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1470 /*                                            resulting in version 6.1    */
1471 /*                                                                        */
1472 /**************************************************************************/
_nxe_dhcpv6_client_delete(NX_DHCPV6 * dhcpv6_ptr)1473 UINT  _nxe_dhcpv6_client_delete(NX_DHCPV6 *dhcpv6_ptr)
1474 {
1475 
1476 UINT    status;
1477 
1478 
1479     /* Check for invalid input pointers.  */
1480     if ((dhcpv6_ptr == NX_NULL) || (dhcpv6_ptr -> nx_dhcpv6_id != NX_DHCPV6_ID))
1481     {
1482         return(NX_PTR_ERROR);
1483     }
1484 
1485     /* Check for appropriate caller.  */
1486     NX_THREADS_ONLY_CALLER_CHECKING
1487 
1488     /* Call actual DHCPV6 delete service.  */
1489     status =  _nx_dhcpv6_client_delete(dhcpv6_ptr);
1490 
1491     /* Return commpletion status.  */
1492     return(status);
1493 }
1494 
1495 
1496 /**************************************************************************/
1497 /*                                                                        */
1498 /*  FUNCTION                                               RELEASE        */
1499 /*                                                                        */
1500 /*    _nx_dhcpv6_client_delete                            PORTABLE C      */
1501 /*                                                           6.1          */
1502 /*  AUTHOR                                                                */
1503 /*                                                                        */
1504 /*    Yuxin Zhou, Microsoft Corporation                                   */
1505 /*                                                                        */
1506 /*  DESCRIPTION                                                           */
1507 /*                                                                        */
1508 /*    This function deletes the DHCPV6 Client instance and releases all   */
1509 /*    NetX Duo and ThreadX resources.                                     */
1510 /*                                                                        */
1511 /*  INPUT                                                                 */
1512 /*                                                                        */
1513 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
1514 /*                                                                        */
1515 /*  OUTPUT                                                                */
1516 /*                                                                        */
1517 /*    NX_SUCCESS                            Successful Completion status  */
1518 /*                                                                        */
1519 /*  CALLS                                                                 */
1520 /*                                                                        */
1521 /*    nx_udp_socket_unbind                  Release DHCPV6 UDP socket port*/
1522 /*    nx_udp_socket_delete                  Delete the DHCPV6 UDP socket  */
1523 /*    tx_thread_terminate                   Terminate DHCPV6 thread       */
1524 /*    tx_thread_delete                      Delete DHCPV6 thread          */
1525 /*    tx_timer_delete                       Delete DHCPV6 timers          */
1526 /*    tx_mutex_delete                       Delete DHCPV6 mutexes         */
1527 /*    tx_event_flags_delete                 Delete DHCPV6 flag queue      */
1528 /*                                                                        */
1529 /*  CALLED BY                                                             */
1530 /*                                                                        */
1531 /*    Application Code                                                    */
1532 /*                                                                        */
1533 /*  RELEASE HISTORY                                                       */
1534 /*                                                                        */
1535 /*    DATE              NAME                      DESCRIPTION             */
1536 /*                                                                        */
1537 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1538 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1539 /*                                            resulting in version 6.1    */
1540 /*                                                                        */
1541 /**************************************************************************/
_nx_dhcpv6_client_delete(NX_DHCPV6 * dhcpv6_ptr)1542 UINT  _nx_dhcpv6_client_delete(NX_DHCPV6 *dhcpv6_ptr)
1543 {
1544 
1545 
1546     /* Terminate the DHCPV6 processing thread.  */
1547     tx_thread_terminate(&(dhcpv6_ptr -> nx_dhcpv6_thread));
1548 
1549     /* Delete the DHCPV6 processing thread.  */
1550     tx_thread_delete(&(dhcpv6_ptr -> nx_dhcpv6_thread));
1551 
1552     /* Delete the flag event queue. */
1553     tx_event_flags_delete(&dhcpv6_ptr -> nx_dhcpv6_events);
1554 
1555     /* Delete the timers */
1556     tx_timer_delete(&(dhcpv6_ptr->nx_dhcpv6_IP_lifetime_timer));
1557     tx_timer_delete(&(dhcpv6_ptr->nx_dhcpv6_session_timer));
1558 
1559     /* Delete the mutex.  */
1560     tx_mutex_delete(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
1561 
1562     /* Release the UDP socket port. */
1563     nx_udp_socket_unbind(&(dhcpv6_ptr -> nx_dhcpv6_socket));
1564 
1565     /* Delete the UDP socket.  */
1566     nx_udp_socket_delete(&(dhcpv6_ptr -> nx_dhcpv6_socket));
1567 
1568     /* Clear the dhcpv6 structure ID. */
1569     dhcpv6_ptr -> nx_dhcpv6_id =  0;
1570 
1571     /* Return a successful status.  */
1572     return(NX_SUCCESS);
1573 }
1574 
1575 
1576 /**************************************************************************/
1577 /*                                                                        */
1578 /*  FUNCTION                                               RELEASE        */
1579 /*                                                                        */
1580 /*    _nxe_dhcpv6_create_client_duid                      PORTABLE C      */
1581 /*                                                           6.1          */
1582 /*  AUTHOR                                                                */
1583 /*                                                                        */
1584 /*    Yuxin Zhou, Microsoft Corporation                                   */
1585 /*                                                                        */
1586 /*  DESCRIPTION                                                           */
1587 /*                                                                        */
1588 /*    This function performs error checking on the create Client DUID     */
1589 /*    service.                                                            */
1590 /*                                                                        */
1591 /*  INPUT                                                                 */
1592 /*                                                                        */
1593 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
1594 /*    duid_type                         Type of DUID (link layer +/- time)*/
1595 /*    hardware_type                     Network hardware type e.g IEEE 802*/
1596 /*    time                              Time stamp unique DUID identifier */
1597 /*                                                                        */
1598 /*  OUTPUT                                                                */
1599 /*                                                                        */
1600 /*    status                             Actual completion status         */
1601 /*    NX_PTR_ERROR                       Invalid pointer input            */
1602 /*    NX_DHCPV6_PARAM_ERROR              Invalid non pointer input        */
1603 /*    NX_DHCPV6_UNSUPPORTED_DUID_TYPE    Unsupported DUID type            */
1604 /*    NX_DHCPV6_UNSUPPORTED_DUID_HW_TYPE Unsupported DUID hardware type   */
1605 /*                                                                        */
1606 /*  CALLS                                                                 */
1607 /*                                                                        */
1608 /*    _nx_dhcpv6_create_client_duid     Actual create client DUID service */
1609 /*                                                                        */
1610 /*  CALLED BY                                                             */
1611 /*                                                                        */
1612 /*    Application Code                                                    */
1613 /*                                                                        */
1614 /*  RELEASE HISTORY                                                       */
1615 /*                                                                        */
1616 /*    DATE              NAME                      DESCRIPTION             */
1617 /*                                                                        */
1618 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1619 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1620 /*                                            resulting in version 6.1    */
1621 /*                                                                        */
1622 /**************************************************************************/
_nxe_dhcpv6_create_client_duid(NX_DHCPV6 * dhcpv6_ptr,UINT duid_type,UINT hardware_type,ULONG time)1623 UINT    _nxe_dhcpv6_create_client_duid(NX_DHCPV6 *dhcpv6_ptr, UINT duid_type, UINT hardware_type, ULONG time)
1624 {
1625 
1626 UINT status;
1627 
1628 
1629     /* Check for invalid pointer input. */
1630     if (!dhcpv6_ptr)
1631     {
1632 
1633         return NX_PTR_ERROR;
1634     }
1635 
1636     /* Check for valid non pointer input. */
1637     if ((duid_type < NX_DHCPV6_DUID_TYPE_LINK_TIME) || (duid_type > NX_DHCPV6_DUID_TYPE_LINK_ONLY))
1638     {
1639         return NX_DHCPV6_PARAM_ERROR;
1640     }
1641 
1642     /* Ethernet is the only a hardware type supported by this API. */
1643     if ((hardware_type != NX_DHCPV6_CLIENT_HARDWARE_TYPE_ETHERNET) && (hardware_type != NX_DHCPV6_CLIENT_HARDWARE_TYPE_EUI_64))
1644     {
1645 
1646         /* Return any other type as an error status. */
1647         return NX_DHCPV6_UNSUPPORTED_DUID_HW_TYPE;
1648     }
1649 
1650     /* This DUID type is not supported by this API. */
1651     if (duid_type == NX_DHCPV6_DUID_TYPE_VENDOR_ASSIGNED)
1652     {
1653 
1654         /* Return as an error status. */
1655         return NX_DHCPV6_UNSUPPORTED_DUID_TYPE;
1656     }
1657 
1658     /* Call the actual service. */
1659     status = _nx_dhcpv6_create_client_duid(dhcpv6_ptr, duid_type, hardware_type, time);
1660 
1661     return status;
1662 }
1663 
1664 
1665 /**************************************************************************/
1666 /*                                                                        */
1667 /*  FUNCTION                                               RELEASE        */
1668 /*                                                                        */
1669 /*    _nx_dhcpv6_create_client_duid                       PORTABLE C      */
1670 /*                                                           6.1          */
1671 /*  AUTHOR                                                                */
1672 /*                                                                        */
1673 /*    Yuxin Zhou, Microsoft Corporation                                   */
1674 /*                                                                        */
1675 /*  DESCRIPTION                                                           */
1676 /*                                                                        */
1677 /*    This function updates the DHCPv6 client DHCP Unique Identifier      */
1678 /*    (DUID) with the input values, sets the linklocal address while the  */
1679 /*    Client does not have an assigned global IP address, after waiting   */
1680 /*    for the IPv6 thread task to read its MAC address.  If the caller    */
1681 /*    does not supply a time ID, it will generate one in place for Link   */
1682 /*    Layer Plus Time DUIDs.                                              */
1683 /*                                                                        */
1684 /*  INPUT                                                                 */
1685 /*                                                                        */
1686 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
1687 /*    duid_type                         Type of DUID (link layer +/- time)*/
1688 /*    hardware_type                     Network hardware type e.g IEEE 802*/
1689 /*    time                              Time stamp unique DUID identifier */
1690 /*                                                                        */
1691 /*  OUTPUT                                                                */
1692 /*                                                                        */
1693 /*    NX_SUCCESS                          Successful completion status    */
1694 /*                                                                        */
1695 /*  CALLS                                                                 */
1696 /*                                                                        */
1697 /*    memset                            Clear specified area of memory    */
1698 /*    rand                              Generate random number for time ID*/
1699 /*    tx_thread_sleep                   Relinquish thread control (sleep) */
1700 /*    nxd_ipv6_linklocal_address_set    Use MAC address as temporary IP   */
1701 /*                                            source address              */
1702 /*                                                                        */
1703 /*  CALLED BY                                                             */
1704 /*                                                                        */
1705 /*    Application Code                                                    */
1706 /*                                                                        */
1707 /*  RELEASE HISTORY                                                       */
1708 /*                                                                        */
1709 /*    DATE              NAME                      DESCRIPTION             */
1710 /*                                                                        */
1711 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1712 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1713 /*                                            resulting in version 6.1    */
1714 /*                                                                        */
1715 /**************************************************************************/
_nx_dhcpv6_create_client_duid(NX_DHCPV6 * dhcpv6_ptr,UINT duid_type,UINT hardware_type,ULONG time)1716 UINT    _nx_dhcpv6_create_client_duid(NX_DHCPV6 *dhcpv6_ptr, UINT duid_type, UINT hardware_type, ULONG time)
1717 {
1718 
1719 NX_INTERFACE  *interface_ptr;
1720 USHORT         option_length;
1721 
1722 
1723     /* Set the interface pointer.  */
1724     interface_ptr = &(dhcpv6_ptr -> nx_dhcpv6_ip_ptr -> nx_ip_interface[dhcpv6_ptr -> nx_dhcpv6_client_interface_index]);
1725 
1726     /* Initialize the DUID to null. */
1727     memset(&(dhcpv6_ptr -> nx_dhcpv6_client_duid), 0, sizeof(NX_DHCPV6_DUID));
1728 
1729     /* Assign the DUID op code. */
1730     dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_op_code = NX_DHCPV6_OP_CLIENT_ID;
1731 
1732     /* Assign field attributes depending on the DUID type. */
1733     if ((duid_type == NX_DHCPV6_DUID_TYPE_LINK_TIME) || (duid_type == NX_DHCPV6_DUID_TYPE_LINK_ONLY))
1734     {
1735 
1736         /* Set the option data length minus the option header and size of the time field. */
1737         dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_duid_type = (USHORT)duid_type;
1738         dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_hardware_type = (USHORT)hardware_type;
1739         option_length = 4;
1740 
1741         /* Is the Link Layer Time DUID type? */
1742         if (duid_type == NX_DHCPV6_DUID_TYPE_LINK_TIME)
1743         {
1744 
1745             /* Yes; add the size of the time field to the data length. */
1746             option_length = (USHORT)(option_length + 4);
1747 
1748             /* Did the caller supplied a time?  */
1749             if (!time)
1750             {
1751                 /* No, create a time field using the defined time constant plus a randomizing factor.*/
1752                 dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_duid_time = (SECONDS_SINCE_JAN_1_2000_MOD_32 + (ULONG)(NX_RAND())) & 0xFFFFFFFF;
1753             }
1754             else
1755             {
1756                 /* Apply the input time. */
1757                 dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_duid_time = time;
1758             }
1759         }
1760 
1761         /* Set the globally unique link layer address. */
1762         dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_link_layer_address_msw = interface_ptr -> nx_interface_physical_address_msw;
1763         dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_link_layer_address_lsw = interface_ptr -> nx_interface_physical_address_lsw;
1764 
1765         /* Check the hardware type.  */
1766         if (hardware_type == NX_DHCPV6_CLIENT_HARDWARE_TYPE_ETHERNET)
1767         {
1768 
1769             /* The length of link layer address is 48 bits.  */
1770             option_length = (USHORT)(option_length + 6);
1771         }
1772         else if (hardware_type == NX_DHCPV6_CLIENT_HARDWARE_TYPE_EUI_64)
1773         {
1774 
1775             /* The length of link layer address is 64 bits.  */
1776             option_length = (USHORT)(option_length + 8);
1777         }
1778 
1779         /* Set the option length.  */
1780         dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_option_length = option_length;
1781     }
1782 
1783      return NX_SUCCESS;
1784 }
1785 
1786 
1787 /**************************************************************************/
1788 /*                                                                        */
1789 /*  FUNCTION                                               RELEASE        */
1790 /*                                                                        */
1791 /*    _nxe_dhcpv6_add_client_ia                           PORTABLE C      */
1792 /*                                                           6.1          */
1793 /*  AUTHOR                                                                */
1794 /*                                                                        */
1795 /*    Yuxin Zhou, Microsoft Corporation                                   */
1796 /*                                                                        */
1797 /*  DESCRIPTION                                                           */
1798 /*                                                                        */
1799 /*    This function performs error checking on the add Client IA          */
1800 /*   (Identity Association) option service, including checking for invalid*/
1801 /*    preferred and valid lifetimes.                                      */
1802 /*                                                                        */
1803 /*  INPUT                                                                 */
1804 /*                                                                        */
1805 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
1806 /*    ipv6_address                      Requested IPv6 address            */
1807 /*    preferred_lifetime                Requested IP lease time before    */
1808 /*                                           address is deprecated        */
1809 /*    valid_lifetime                    Requested IP lease time before    */
1810 /*                                           address is expired           */
1811 /*                                                                        */
1812 /*  OUTPUT                                                                */
1813 /*                                                                        */
1814 /*    status                            Actual completion status          */
1815 /*    NX_PTR_ERROR                      Invalid pointer input             */
1816 /*    NX_DHCPV6_PARAM_ERROR             Invalid non pointer input         */
1817 /*                                                                        */
1818 /*  CALLS                                                                 */
1819 /*                                                                        */
1820 /*    _nx_dhcpv6_add_client_ia          Actual add client IA service      */
1821 /*                                                                        */
1822 /*  CALLED BY                                                             */
1823 /*                                                                        */
1824 /*    Application Code                                                    */
1825 /*                                                                        */
1826 /*  RELEASE HISTORY                                                       */
1827 /*                                                                        */
1828 /*    DATE              NAME                      DESCRIPTION             */
1829 /*                                                                        */
1830 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1831 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1832 /*                                            resulting in version 6.1    */
1833 /*                                                                        */
1834 /**************************************************************************/
_nxe_dhcpv6_add_client_ia(NX_DHCPV6 * dhcpv6_ptr,NXD_ADDRESS * ipv6_address,ULONG preferred_lifetime,ULONG valid_lifetime)1835 UINT    _nxe_dhcpv6_add_client_ia(NX_DHCPV6 *dhcpv6_ptr, NXD_ADDRESS *ipv6_address,
1836                                   ULONG preferred_lifetime, ULONG valid_lifetime)
1837 {
1838 
1839 UINT status;
1840 
1841 
1842     /* Check for invalid pointer input. */
1843     if (!dhcpv6_ptr || !ipv6_address)
1844     {
1845 
1846         return NX_PTR_ERROR;
1847     }
1848 
1849     /* Make sure the IPv6 address valid. */
1850     if ((ipv6_address -> nxd_ip_address.v6[0] == 0) &&
1851         (ipv6_address -> nxd_ip_address.v6[1] == 0) &&
1852         (ipv6_address -> nxd_ip_address.v6[2] == 0) &&
1853         (ipv6_address -> nxd_ip_address.v6[3] == 0))
1854     {
1855 
1856         return NX_DHCPV6_INVALID_IA_ADDRESS;
1857     }
1858 
1859     /* Check for valid non pointer input. */
1860     if (preferred_lifetime > valid_lifetime)
1861     {
1862 
1863        /* Client preferred time must be less than valid time or
1864           server will reject it. */
1865         return NX_DHCPV6_PARAM_ERROR;
1866     }
1867 
1868     /* Check for an empty IANA instance. */
1869     if (!dhcpv6_ptr -> nx_dhcpv6_iana.nx_op_code)
1870     {
1871 
1872         return NX_DHCPV6_PARAM_ERROR;
1873     }
1874 
1875     /* Call the actual service. */
1876     status = _nx_dhcpv6_add_client_ia(dhcpv6_ptr, ipv6_address, preferred_lifetime, valid_lifetime);
1877 
1878     /* Return completion status. */
1879     return status;
1880 }
1881 
1882 
1883 /**************************************************************************/
1884 /*                                                                        */
1885 /*  FUNCTION                                               RELEASE        */
1886 /*                                                                        */
1887 /*    _nx_dhcpv6_add_client_ia                            PORTABLE C      */
1888 /*                                                           6.1          */
1889 /*  AUTHOR                                                                */
1890 /*                                                                        */
1891 /*    Yuxin Zhou, Microsoft Corporation                                   */
1892 /*                                                                        */
1893 /*  DESCRIPTION                                                           */
1894 /*                                                                        */
1895 /*    This function adds the Client Identity Association address with     */
1896 /*    the input values.                                                   */
1897 /*                                                                        */
1898 /*  INPUT                                                                 */
1899 /*                                                                        */
1900 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
1901 /*    ipv6_address                      Requested IPv6 address            */
1902 /*    preferred_lifetime                Requested IP lease time before    */
1903 /*                                           address is deprecated        */
1904 /*    valid_lifetime                    Requested IP lease time before    */
1905 /*                                           address is expired           */
1906 /*                                                                        */
1907 /*  OUTPUT                                                                */
1908 /*                                                                        */
1909 /*    NX_SUCCESS                        Successful completion status      */
1910 /*    NX_DHCPV6_REACHED_MAX_IA_ADDRESS  No space to record IA address     */
1911 /*                                                                        */
1912 /*  CALLS                                                                 */
1913 /*                                                                        */
1914 /*    memset                            Clear specified area of memory    */
1915 /*                                                                        */
1916 /*  CALLED BY                                                             */
1917 /*                                                                        */
1918 /*    Application Code                                                    */
1919 /*                                                                        */
1920 /*  RELEASE HISTORY                                                       */
1921 /*                                                                        */
1922 /*    DATE              NAME                      DESCRIPTION             */
1923 /*                                                                        */
1924 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1925 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1926 /*                                            resulting in version 6.1    */
1927 /*                                                                        */
1928 /**************************************************************************/
_nx_dhcpv6_add_client_ia(NX_DHCPV6 * dhcpv6_ptr,NXD_ADDRESS * ipv6_address,ULONG preferred_lifetime,ULONG valid_lifetime)1929 UINT    _nx_dhcpv6_add_client_ia(NX_DHCPV6 *dhcpv6_ptr, NXD_ADDRESS *ipv6_address,
1930                                  ULONG preferred_lifetime, ULONG valid_lifetime)
1931 {
1932 UINT    ia_index;
1933 
1934 
1935     /* Perform duplicate address detection.  */
1936     for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
1937     {
1938         if((dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[0] == ipv6_address->nxd_ip_address.v6[0]) &&
1939            (dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[1] == ipv6_address->nxd_ip_address.v6[1]) &&
1940            (dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[2] == ipv6_address->nxd_ip_address.v6[2]) &&
1941            (dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[3] == ipv6_address->nxd_ip_address.v6[3]))
1942         {
1943 
1944             /* The IA address has already exists.  */
1945             return (NX_DHCPV6_IA_ADDRESS_ALREADY_EXIST);
1946         }
1947     }
1948 
1949     /* Find one valid space to set the IA address.  */
1950     for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
1951     {
1952 
1953         if(!dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status)
1954         {
1955 
1956             /* Yes, got it.  */
1957             break;
1958         }
1959     }
1960 
1961     if(ia_index < NX_DHCPV6_MAX_IA_ADDRESS)
1962     {
1963 
1964         /* Yes, get it, set the IA address.  */
1965 
1966         /* Initialize the IA-Address to null. */
1967         memset(&(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index]), 0, sizeof(NX_DHCPV6_IA_ADDRESS));
1968 
1969         dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_op_code = NX_DHCPV6_OP_IA_ADDRESS;
1970 
1971         /* Set the IA option length - minus the option header. */
1972         dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_option_length = (7 * sizeof(ULONG)) - 4;
1973 
1974         /* Set the IP address parameters as a hint to the server. */
1975         dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_version = NX_IP_VERSION_V6;
1976         COPY_IPV6_ADDRESS(&(ipv6_address -> nxd_ip_address.v6[0]), &(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[0]));
1977 
1978         /* Set the life time parameters as a hint to the server. */
1979         dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_preferred_lifetime = preferred_lifetime;
1980         dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_valid_lifetime = valid_lifetime;
1981         dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status = NX_DHCPV6_IA_ADDRESS_STATE_INITIAL;
1982 
1983         return NX_SUCCESS;
1984     }
1985     else
1986     {
1987         return NX_DHCPV6_REACHED_MAX_IA_ADDRESS;
1988     }
1989 }
1990 
1991 
1992 /**************************************************************************/
1993 /*                                                                        */
1994 /*  FUNCTION                                               RELEASE        */
1995 /*                                                                        */
1996 /*    _nxe_dhcpv6_create_client_iana                      PORTABLE C      */
1997 /*                                                           6.1          */
1998 /*  AUTHOR                                                                */
1999 /*                                                                        */
2000 /*    Yuxin Zhou, Microsoft Corporation                                   */
2001 /*                                                                        */
2002 /*  DESCRIPTION                                                           */
2003 /*                                                                        */
2004 /*    This function performs error checking on the create Client IA-NA    */
2005 /*    option service, including checking for invalid T1 and T2 times.     */
2006 /*                                                                        */
2007 /*  INPUT                                                                 */
2008 /*                                                                        */
2009 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
2010 /*    IA_ident                          Interface Association ID          */
2011 /*    T1                                Requested lease time with server  */
2012 /*                                           assigning IP (renew)         */
2013 /*    T2                                Requested lease time with any     */
2014 /*                                           other server (rebind)        */
2015 /*                                                                        */
2016 /*  OUTPUT                                                                */
2017 /*                                                                        */
2018 /*    status                            Actual completion status          */
2019 /*    NX_PTR_ERROR                      Invalid pointer input             */
2020 /*    NX_DHCPV6_PARAM_ERROR             Invalid non pointer input         */
2021 /*                                                                        */
2022 /*  CALLS                                                                 */
2023 /*                                                                        */
2024 /*    _nx_dhcpv6_create_client_iana     Actual create client IANA service */
2025 /*                                                                        */
2026 /*  CALLED BY                                                             */
2027 /*                                                                        */
2028 /*    Application Code                                                    */
2029 /*                                                                        */
2030 /*  RELEASE HISTORY                                                       */
2031 /*                                                                        */
2032 /*    DATE              NAME                      DESCRIPTION             */
2033 /*                                                                        */
2034 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2035 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2036 /*                                            resulting in version 6.1    */
2037 /*                                                                        */
2038 /**************************************************************************/
_nxe_dhcpv6_create_client_iana(NX_DHCPV6 * dhcpv6_ptr,UINT IA_ident,ULONG T1,ULONG T2)2039 UINT    _nxe_dhcpv6_create_client_iana(NX_DHCPV6 *dhcpv6_ptr, UINT IA_ident, ULONG T1, ULONG T2)
2040 {
2041 
2042 UINT status;
2043 
2044 
2045     /* Check for invalid pointer input. */
2046     if (!dhcpv6_ptr || !IA_ident)
2047     {
2048 
2049         return NX_PTR_ERROR;
2050     }
2051 
2052     /* Check for valid non pointer input. */
2053     if (T1 > T2)
2054     {
2055 
2056        /* Client preferred time must be less than valid time or server will reject it. */
2057         return NX_DHCPV6_PARAM_ERROR;
2058     }
2059 
2060 
2061     /* Call the actual service. */
2062     status = _nx_dhcpv6_create_client_iana(dhcpv6_ptr, IA_ident, T1,  T2);
2063 
2064     /* Return completion status. */
2065     return status;
2066 }
2067 
2068 
2069 /**************************************************************************/
2070 /*                                                                        */
2071 /*  FUNCTION                                               RELEASE        */
2072 /*                                                                        */
2073 /*    _nx_dhcpv6_create_client_iana                       PORTABLE C      */
2074 /*                                                           6.1          */
2075 /*  AUTHOR                                                                */
2076 /*                                                                        */
2077 /*    Yuxin Zhou, Microsoft Corporation                                   */
2078 /*                                                                        */
2079 /*  DESCRIPTION                                                           */
2080 /*                                                                        */
2081 /*    This function updates the Client's Identity Association for Non     */
2082 /*    Temporary Address (IANA) with the input values.                     */
2083 /*                                                                        */
2084 /*  INPUT                                                                 */
2085 /*                                                                        */
2086 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
2087 /*    IA_ident                          Interface Association ID          */
2088 /*    T1                                Requested lease time with server  */
2089 /*                                           assigning IP (renew)         */
2090 /*    T2                                Requested lease time with any     */
2091 /*                                           other server (rebind)        */
2092 /*                                                                        */
2093 /*  OUTPUT                                                                */
2094 /*                                                                        */
2095 /*    NX_SUCCESS                          Successful completion status    */
2096 /*                                                                        */
2097 /*  CALLS                                                                 */
2098 /*                                                                        */
2099 /*    memset                            Clear specified area of memory    */
2100 /*                                                                        */
2101 /*  CALLED BY                                                             */
2102 /*                                                                        */
2103 /*    Application Code                                                    */
2104 /*                                                                        */
2105 /*  RELEASE HISTORY                                                       */
2106 /*                                                                        */
2107 /*    DATE              NAME                      DESCRIPTION             */
2108 /*                                                                        */
2109 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2110 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2111 /*                                            resulting in version 6.1    */
2112 /*                                                                        */
2113 /**************************************************************************/
_nx_dhcpv6_create_client_iana(NX_DHCPV6 * dhcpv6_ptr,UINT IA_ident,ULONG T1,ULONG T2)2114 UINT    _nx_dhcpv6_create_client_iana(NX_DHCPV6 *dhcpv6_ptr, UINT IA_ident, ULONG T1, ULONG T2)
2115 {
2116 
2117     /* Initialize the IANA to null. */
2118     memset(&(dhcpv6_ptr -> nx_dhcpv6_iana), 0, sizeof(NX_DHCPV6_IA_NA));
2119 
2120     /* Assign the IANA attributes. */
2121     dhcpv6_ptr -> nx_dhcpv6_iana.nx_op_code = NX_DHCPV6_OP_IA_NA;
2122     dhcpv6_ptr -> nx_dhcpv6_iana.nx_IA_NA_id = IA_ident;
2123 
2124     /* Set the IANA option data length, minus the option header. */
2125     dhcpv6_ptr -> nx_dhcpv6_iana.nx_option_length = 3 * sizeof(ULONG);
2126 
2127     /* Apply the Client's preference for IP renew/rebind times. */
2128     dhcpv6_ptr -> nx_dhcpv6_iana.nx_T1 = T1;
2129     dhcpv6_ptr -> nx_dhcpv6_iana.nx_T2 = T2;
2130 
2131     return NX_SUCCESS;
2132 }
2133 
2134 
2135 /**************************************************************************/
2136 /*                                                                        */
2137 /*  FUNCTION                                               RELEASE        */
2138 /*                                                                        */
2139 /*    _nxe_dhcpv6_get_client_duid_time_id                 PORTABLE C      */
2140 /*                                                           6.1          */
2141 /*  AUTHOR                                                                */
2142 /*                                                                        */
2143 /*    Yuxin Zhou, Microsoft Corporation                                   */
2144 /*                                                                        */
2145 /*  DESCRIPTION                                                           */
2146 /*                                                                        */
2147 /*    This function performs error checking on the get Client DUID time ID*/
2148 /*    service.                                                            */
2149 /*                                                                        */
2150 /*  INPUT                                                                 */
2151 /*                                                                        */
2152 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
2153 /*    time_id                             Pointer to DUID time field      */
2154 /*                                                                        */
2155 /*  OUTPUT                                                                */
2156 /*                                                                        */
2157 /*    status                              Actual completion status        */
2158 /*    NX_PTR_ERROR                        Invalid pointer input           */
2159 /*                                                                        */
2160 /*  CALLS                                                                 */
2161 /*                                                                        */
2162 /*    _nx_dhcpv6_get_client_duid_time_id  Actual get Client DUID time ID  */
2163 /*                                          service                       */
2164 /*                                                                        */
2165 /*  CALLED BY                                                             */
2166 /*                                                                        */
2167 /*    Application Code                                                    */
2168 /*                                                                        */
2169 /*  RELEASE HISTORY                                                       */
2170 /*                                                                        */
2171 /*    DATE              NAME                      DESCRIPTION             */
2172 /*                                                                        */
2173 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2174 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2175 /*                                            resulting in version 6.1    */
2176 /*                                                                        */
2177 /**************************************************************************/
_nxe_dhcpv6_get_client_duid_time_id(NX_DHCPV6 * dhcpv6_ptr,ULONG * time_id)2178 UINT _nxe_dhcpv6_get_client_duid_time_id(NX_DHCPV6 *dhcpv6_ptr, ULONG *time_id)
2179 {
2180 
2181 UINT status;
2182 
2183 
2184     /* Check for valid pointer input. */
2185     if (!dhcpv6_ptr || !time_id)
2186     {
2187 
2188         return NX_PTR_ERROR;
2189     }
2190 
2191     /* Check for appropriate caller.  */
2192     NX_THREADS_ONLY_CALLER_CHECKING
2193 
2194     /* Call the actual service. */
2195     status =  _nx_dhcpv6_get_client_duid_time_id(dhcpv6_ptr, time_id);
2196 
2197     /* Return completion status. */
2198     return status;
2199 }
2200 
2201 
2202 /**************************************************************************/
2203 /*                                                                        */
2204 /*  FUNCTION                                               RELEASE        */
2205 /*                                                                        */
2206 /*    _nx_dhcpv6_get_client_duid_time_id                  PORTABLE C      */
2207 /*                                                           6.1          */
2208 /*  AUTHOR                                                                */
2209 /*                                                                        */
2210 /*    Yuxin Zhou, Microsoft Corporation                                   */
2211 /*                                                                        */
2212 /*  DESCRIPTION                                                           */
2213 /*                                                                        */
2214 /*    This function retrieves the Client DUID time ID saved to the client */
2215 /*    record.  It does not check if the DUID is properly filled out. It is*/
2216 /*    up to the caller to check for a zero value (invalid) time ID.       */
2217 /*                                                                        */
2218 /*  INPUT                                                                 */
2219 /*                                                                        */
2220 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
2221 /*    time_id                             Pointer to DUID time field      */
2222 /*                                                                        */
2223 /*  OUTPUT                                                                */
2224 /*                                                                        */
2225 /*    status                              Actual completion status        */
2226 /*    NX_PTR_ERROR                        Invalid pointer input           */
2227 /*                                                                        */
2228 /*  CALLS                                                                 */
2229 /*                                                                        */
2230 /*    _nx_dhcpv6_get_client_duid_time_id  Actual get Client DUID time ID  */
2231 /*                                          service                       */
2232 /*                                                                        */
2233 /*  CALLED BY                                                             */
2234 /*                                                                        */
2235 /*    Application Code                                                    */
2236 /*                                                                        */
2237 /*  RELEASE HISTORY                                                       */
2238 /*                                                                        */
2239 /*    DATE              NAME                      DESCRIPTION             */
2240 /*                                                                        */
2241 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2242 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2243 /*                                            resulting in version 6.1    */
2244 /*                                                                        */
2245 /**************************************************************************/
_nx_dhcpv6_get_client_duid_time_id(NX_DHCPV6 * dhcpv6_ptr,ULONG * time_id)2246 UINT   _nx_dhcpv6_get_client_duid_time_id(NX_DHCPV6 *dhcpv6_ptr, ULONG *time_id)
2247 {
2248 
2249     /* The Time field is part of the NX_DHCPV6_DUID struct in the Client record. */
2250     *time_id = dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_duid_time;
2251 
2252     /* Return successful completion. */
2253     return NX_SUCCESS;
2254 }
2255 
2256 
2257 /**************************************************************************/
2258 /*                                                                        */
2259 /*  FUNCTION                                               RELEASE        */
2260 /*                                                                        */
2261 /*    _nx_dhcpv6_register_IP_address                      PORTABLE C      */
2262 /*                                                           6.1          */
2263 /*  AUTHOR                                                                */
2264 /*                                                                        */
2265 /*    Yuxin Zhou, Microsoft Corporation                                   */
2266 /*                                                                        */
2267 /*  DESCRIPTION                                                           */
2268 /*                                                                        */
2269 /*    This function registers the assigned IP address to the IP task,     */
2270 /*    which adds the input address to the IP address table.In either case,*/
2271 /*    the address index in the IP address table is recorded to the Client */
2272 /*    record.It will require it if the DHCPv6 Client wants to clear the   */
2273 /*    IPv6 address.                                                       */
2274 /*                                                                        */
2275 /*    Note: the host application should perform address verification      */
2276 /*    e.g. Duplicate Address Detection to verify uniqueness of the input  */
2277 /*    address. If duplicate address detection is enabled in NetX Duo this */
2278 /*    is done automatically.                                              */
2279 /*                                                                        */
2280 /*  INPUT                                                                 */
2281 /*                                                                        */
2282 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
2283 /*                                                                        */
2284 /*  OUTPUT                                                                */
2285 /*                                                                        */
2286 /*    status                              Actual completion status        */
2287 /*                                                                        */
2288 /*  CALLS                                                                 */
2289 /*                                                                        */
2290 /*    _nxd_ipv6_address_set               Add global address to IP        */
2291 /*    tx_mutex_get                        Get the DHCPv6 mutex            */
2292 /*    tx_mutex_put                        Put the DHCPv6 mutex            */
2293 /*                                                                        */
2294 /*  CALLED BY                                                             */
2295 /*                                                                        */
2296 /*    nx_dhcpv6_process                   Process received packets        */
2297 /*                                                                        */
2298 /*  RELEASE HISTORY                                                       */
2299 /*                                                                        */
2300 /*    DATE              NAME                      DESCRIPTION             */
2301 /*                                                                        */
2302 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2303 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2304 /*                                            resulting in version 6.1    */
2305 /*                                                                        */
2306 /**************************************************************************/
_nx_dhcpv6_register_IP_address(NX_DHCPV6 * dhcpv6_ptr)2307 UINT _nx_dhcpv6_register_IP_address(NX_DHCPV6 *dhcpv6_ptr)
2308 {
2309 
2310 UINT    status;
2311 UINT    address_index;
2312 UINT    ia_index;
2313 
2314     /* Set the DHCPv6 Client IPv6 addresses.  */
2315     for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
2316     {
2317 
2318         if(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status == NX_DHCPV6_IA_ADDRESS_STATE_INITIAL)
2319         {
2320 
2321             /* Add the address to the IP instance address table. */
2322             status = nxd_ipv6_address_set(dhcpv6_ptr -> nx_dhcpv6_ip_ptr, dhcpv6_ptr -> nx_dhcpv6_client_interface_index,
2323                                           &dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address, 64, &address_index);
2324 
2325             /* Check for successful result. */
2326             if (status == NX_SUCCESS)
2327             {
2328 
2329                 /* Get the mutex protection for DHCP client. */
2330                 tx_mutex_get(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex), NX_DHCPV6_MUTEX_WAIT);
2331 
2332 #if !defined (NX_DISABLE_IPV6_DAD) && defined (NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY)
2333 
2334                 /* Set the IPv6 address status as DAD tentative, the status will be updated in _nx_dhcpv6_ipv6_address_DAD_notify.  */
2335                 dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status = NX_DHCPV6_IA_ADDRESS_STATE_DAD_TENTATIVE;
2336 #else
2337 
2338                 /* Set the IPv6 address status as valid.  */
2339                 dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status = NX_DHCPV6_IA_ADDRESS_STATE_VALID;
2340 #endif
2341 
2342                 /* Record the address index in the Client record. */
2343                 dhcpv6_ptr -> nx_dhcpv6_client_address_index[ia_index] = address_index;
2344 
2345                 /* All done! Release the mutex.*/
2346                 tx_mutex_put(&dhcpv6_ptr -> nx_dhcpv6_client_mutex);
2347             }
2348 
2349         }
2350     }
2351 
2352     /* Add the default router.  */
2353     nxd_ipv6_default_router_add(dhcpv6_ptr -> nx_dhcpv6_ip_ptr, &(dhcpv6_ptr-> nx_dhcpv6_server_address),
2354                                 NX_WAIT_FOREVER, dhcpv6_ptr -> nx_dhcpv6_client_interface_index);
2355 
2356     return NX_SUCCESS;
2357 }
2358 
2359 /**************************************************************************/
2360 /*                                                                        */
2361 /*  FUNCTION                                               RELEASE        */
2362 /*                                                                        */
2363 /*    _nxe_dhcpv6_get_IP_address                          PORTABLE C      */
2364 /*                                                           6.1          */
2365 /*  AUTHOR                                                                */
2366 /*                                                                        */
2367 /*    Yuxin Zhou, Microsoft Corporation                                   */
2368 /*                                                                        */
2369 /*  DESCRIPTION                                                           */
2370 /*                                                                        */
2371 /*    This function performs error checking on the get Client global IP   */
2372 /*    address service.                                                    */
2373 /*                                                                        */
2374 /*  INPUT                                                                 */
2375 /*                                                                        */
2376 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
2377 /*    ip_address                          Pointer to global IP address    */
2378 /*                                                                        */
2379 /*  OUTPUT                                                                */
2380 /*                                                                        */
2381 /*    status                            Actual completion status          */
2382 /*    NX_PTR_ERROR                      Invalid pointer input             */
2383 /*                                                                        */
2384 /*  CALLS                                                                 */
2385 /*                                                                        */
2386 /*    _nx_dhcpv6_get_IP_address         Actual get Client global IP       */
2387 /*                                         address service                */
2388 /*                                                                        */
2389 /*  CALLED BY                                                             */
2390 /*                                                                        */
2391 /*    Application Code                                                    */
2392 /*                                                                        */
2393 /*  RELEASE HISTORY                                                       */
2394 /*                                                                        */
2395 /*    DATE              NAME                      DESCRIPTION             */
2396 /*                                                                        */
2397 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2398 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2399 /*                                            resulting in version 6.1    */
2400 /*                                                                        */
2401 /**************************************************************************/
_nxe_dhcpv6_get_IP_address(NX_DHCPV6 * dhcpv6_ptr,NXD_ADDRESS * ip_address)2402 UINT _nxe_dhcpv6_get_IP_address(NX_DHCPV6 *dhcpv6_ptr, NXD_ADDRESS *ip_address)
2403 {
2404 
2405 UINT status;
2406 
2407 
2408     /* Check for valid pointer input. */
2409     if (!dhcpv6_ptr || !ip_address)
2410     {
2411 
2412         return NX_PTR_ERROR;
2413     }
2414 
2415     /* Check for appropriate caller.  */
2416     NX_THREADS_ONLY_CALLER_CHECKING
2417 
2418     /* Call the actual service. */
2419     status =  _nx_dhcpv6_get_IP_address(dhcpv6_ptr,  ip_address);
2420 
2421     /* Return completion status. */
2422     return status;
2423 }
2424 
2425 
2426 /**************************************************************************/
2427 /*                                                                        */
2428 /*  FUNCTION                                               RELEASE        */
2429 /*                                                                        */
2430 /*    _nx_dhcpv6_get_IP_address                           PORTABLE C      */
2431 /*                                                           6.1          */
2432 /*  AUTHOR                                                                */
2433 /*                                                                        */
2434 /*    Yuxin Zhou, Microsoft Corporation                                   */
2435 /*                                                                        */
2436 /*  DESCRIPTION                                                           */
2437 /*                                                                        */
2438 /*    This function retrieves the IP address from the DHCPv6              */
2439 /*    Client record.  If the client address is not valid, a null IP       */
2440 /*    address is returned and an error status is set.                     */
2441 /*                                                                        */
2442 /*    Note that if the Client has received an IP address from the DHCPv6  */
2443 /*    server the host must register that ddress with NetX Duo by calling  */
2444 /*    address with NetX Duo by calling the service nxd_ipv6_address_set.  */
2445 /*    Once the address is registered, the host can confirm its address by */
2446 /*    calling nxd_ipv6_address_get.                                       */
2447 /*                                                                        */
2448 /*  INPUT                                                                 */
2449 /*                                                                        */
2450 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
2451 /*    ip_address                          Pointer to NetX Duo address     */
2452 /*                                                                        */
2453 /*  OUTPUT                                                                */
2454 /*                                                                        */
2455 /*    NX_SUCCESS                          Returned non zero IP address    */
2456 /*    NX_DHCPV6_IA_ADDRESS_NOT_VALID      Client not assigned an address  */
2457 /*                                                                        */
2458 /*  CALLS                                                                 */
2459 /*                                                                        */
2460 /*     None                                                               */
2461 /*                                                                        */
2462 /*  CALLED BY                                                             */
2463 /*                                                                        */
2464 /*    Application                                                         */
2465 /*                                                                        */
2466 /*  RELEASE HISTORY                                                       */
2467 /*                                                                        */
2468 /*    DATE              NAME                      DESCRIPTION             */
2469 /*                                                                        */
2470 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2471 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2472 /*                                            resulting in version 6.1    */
2473 /*                                                                        */
2474 /**************************************************************************/
_nx_dhcpv6_get_IP_address(NX_DHCPV6 * dhcpv6_ptr,NXD_ADDRESS * ip_address)2475 UINT _nx_dhcpv6_get_IP_address(NX_DHCPV6 *dhcpv6_ptr, NXD_ADDRESS *ip_address)
2476 {
2477 
2478 UINT status;
2479 
2480 
2481     /* Clear the address buffer. */
2482     SET_UNSPECIFIED_ADDRESS(&ip_address -> nxd_ip_address.v6[0]);
2483 
2484     /* Initialize the outcome as no address assigned. */
2485     status = NX_DHCPV6_IA_ADDRESS_NOT_VALID;
2486 
2487     /* Is the client assigned a valid address? */
2488     if (dhcpv6_ptr -> nx_dhcpv6_ia[0].nx_address_status == NX_DHCPV6_IA_ADDRESS_STATE_VALID)
2489     {
2490         /* Yes; return the assigned IP address from the DHCPv6 Client record. */
2491         COPY_IPV6_ADDRESS(&(dhcpv6_ptr -> nx_dhcpv6_ia[0].nx_global_address.nxd_ip_address.v6[0]),
2492                           &(ip_address -> nxd_ip_address.v6[0]));
2493 
2494         status = NX_SUCCESS;
2495     }
2496 
2497     return status;
2498 }
2499 
2500 
2501 /**************************************************************************/
2502 /*                                                                        */
2503 /*  FUNCTION                                               RELEASE        */
2504 /*                                                                        */
2505 /*    _nxe_dhcpv6_get_lease_time_data                     PORTABLE C      */
2506 /*                                                           6.1          */
2507 /*  AUTHOR                                                                */
2508 /*                                                                        */
2509 /*    Yuxin Zhou, Microsoft Corporation                                   */
2510 /*                                                                        */
2511 /*  DESCRIPTION                                                           */
2512 /*                                                                        */
2513 /*    This function performs error checking on the get Client IP lease    */
2514 /*    time service.                                                       */
2515 /*                                                                        */
2516 /*  INPUT                                                                 */
2517 /*                                                                        */
2518 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
2519 /*    T1                                  Pointer to T1 time              */
2520 /*    T2                                  Pointer to T2 time              */
2521 /*    preferred_lifetime                  Pointer to preferred lifetime   */
2522 /*    valid_lifetime                      Pointer to valid lifetime       */
2523 /*                                                                        */
2524 /*  OUTPUT                                                                */
2525 /*                                                                        */
2526 /*    status                            Actual completion status          */
2527 /*    NX_PTR_ERROR                      Invalid pointer input             */
2528 /*                                                                        */
2529 /*  CALLS                                                                 */
2530 /*                                                                        */
2531 /*    _nx_dhcpv6_get_lease_time_data    Actual get Client IP lease time   */
2532 /*                                                 service                */
2533 /*                                                                        */
2534 /*  CALLED BY                                                             */
2535 /*                                                                        */
2536 /*    Application Code                                                    */
2537 /*                                                                        */
2538 /*  RELEASE HISTORY                                                       */
2539 /*                                                                        */
2540 /*    DATE              NAME                      DESCRIPTION             */
2541 /*                                                                        */
2542 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2543 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2544 /*                                            resulting in version 6.1    */
2545 /*                                                                        */
2546 /**************************************************************************/
_nxe_dhcpv6_get_lease_time_data(NX_DHCPV6 * dhcpv6_ptr,ULONG * T1,ULONG * T2,ULONG * preferred_lifetime,ULONG * valid_lifetime)2547 UINT _nxe_dhcpv6_get_lease_time_data(NX_DHCPV6 *dhcpv6_ptr, ULONG *T1, ULONG *T2, ULONG *preferred_lifetime,
2548                                     ULONG *valid_lifetime)
2549 {
2550 
2551 UINT status;
2552 
2553 
2554     /* Check for valid pointer input. */
2555     if (!dhcpv6_ptr || !T1 || !T2 || !preferred_lifetime || !valid_lifetime )
2556     {
2557         return NX_PTR_ERROR;
2558     }
2559 
2560     /* Check for appropriate caller.  */
2561     NX_THREADS_ONLY_CALLER_CHECKING
2562 
2563     /* Call the actual service. */
2564     status =  _nx_dhcpv6_get_lease_time_data(dhcpv6_ptr, T1, T2, preferred_lifetime, valid_lifetime);
2565 
2566     /* Return completion status. */
2567     return status;
2568 }
2569 
2570 
2571 /**************************************************************************/
2572 /*                                                                        */
2573 /*  FUNCTION                                               RELEASE        */
2574 /*                                                                        */
2575 /*    _nx_dhcpv6_get_lease_time_data                      PORTABLE C      */
2576 /*                                                           6.1          */
2577 /*  AUTHOR                                                                */
2578 /*                                                                        */
2579 /*    Yuxin Zhou, Microsoft Corporation                                   */
2580 /*                                                                        */
2581 /*  DESCRIPTION                                                           */
2582 /*                                                                        */
2583 /*    This function retrieves the Client's global IP lease times T1 and T2*/
2584 /*    and valid and preferred lifetimes. The address_status input field   */
2585 /*    indicates if the IP address on the Client record is valid and       */
2586 /*    registered. If so the lease and valid lifetimes are also registered */
2587 /*    with the server (not merely Client preference or left over from an  */
2588 /*    expired IP address).                                                */
2589 /*                                                                        */
2590 /*  INPUT                                                                 */
2591 /*                                                                        */
2592 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
2593 /*    T1                                  Pointer to T1 time              */
2594 /*    T2                                  Pointer to T2 time              */
2595 /*    preferred_lifetime                  Pointer to preferred lifetime   */
2596 /*    valid_lifetime                      Pointer to valid lifetime       */
2597 /*                                                                        */
2598 /*  OUTPUT                                                                */
2599 /*                                                                        */
2600 /*    NX_SUCCESS                          Successful completion status    */
2601 /*                                                                        */
2602 /*  CALLS                                                                 */
2603 /*                                                                        */
2604 /*     None                                                               */
2605 /*                                                                        */
2606 /*  CALLED BY                                                             */
2607 /*                                                                        */
2608 /*    Application                                                         */
2609 /*                                                                        */
2610 /*  RELEASE HISTORY                                                       */
2611 /*                                                                        */
2612 /*    DATE              NAME                      DESCRIPTION             */
2613 /*                                                                        */
2614 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2615 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2616 /*                                            resulting in version 6.1    */
2617 /*                                                                        */
2618 /**************************************************************************/
_nx_dhcpv6_get_lease_time_data(NX_DHCPV6 * dhcpv6_ptr,ULONG * T1,ULONG * T2,ULONG * preferred_lifetime,ULONG * valid_lifetime)2619 UINT _nx_dhcpv6_get_lease_time_data(NX_DHCPV6 *dhcpv6_ptr, ULONG *T1, ULONG *T2, ULONG *preferred_lifetime,
2620                                     ULONG *valid_lifetime)
2621 {
2622 
2623     /* Initialize data to zero. */
2624     *T1 = 0;
2625     *T2 = 0;
2626     *valid_lifetime = 0;
2627     *preferred_lifetime = 0;
2628 
2629     /* If the client has a valid IP address status, return the actual lease time data. */
2630     if (dhcpv6_ptr -> nx_dhcpv6_ia[0].nx_address_status == NX_DHCPV6_IA_ADDRESS_STATE_VALID)
2631     {
2632         /* Get the time data from the Client record IA. */
2633         *T1 = dhcpv6_ptr -> nx_dhcpv6_iana.nx_T1;
2634         *T2 = dhcpv6_ptr -> nx_dhcpv6_iana.nx_T2;
2635         *preferred_lifetime = dhcpv6_ptr -> nx_dhcpv6_ia[0].nx_preferred_lifetime;
2636         *valid_lifetime = dhcpv6_ptr -> nx_dhcpv6_ia[0].nx_valid_lifetime;
2637     }
2638 
2639     /* Return successful completion. */
2640     return NX_SUCCESS;
2641 }
2642 
2643 /**************************************************************************/
2644 /*                                                                        */
2645 /*  FUNCTION                                               RELEASE        */
2646 /*                                                                        */
2647 /*    _nxe_dhcpv6_get_DNS_server_address                  PORTABLE C      */
2648 /*                                                           6.1          */
2649 /*  AUTHOR                                                                */
2650 /*                                                                        */
2651 /*    Yuxin Zhou, Microsoft Corporation                                   */
2652 /*                                                                        */
2653 /*  DESCRIPTION                                                           */
2654 /*                                                                        */
2655 /*                                                                        */
2656 /*  INPUT                                                                 */
2657 /*                                                                        */
2658 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
2659 /*    index                               Index into DNS server list      */
2660 /*    server_address                      Pointer to copy address to      */
2661 /*                                                                        */
2662 /*  OUTPUT                                                                */
2663 /*                                                                        */
2664 /*    NX_SUCCESS                          Successful completion status    */
2665 /*    NX_PTR_ERROR                        Invalid pointer input           */
2666 /*                                                                        */
2667 /*  CALLS                                                                 */
2668 /*    _nx_dhcpv6_get_DNS_server_address   Actual get DNS server address   */
2669 /*                                              service                   */
2670 /*                                                                        */
2671 /*  CALLED BY                                                             */
2672 /*                                                                        */
2673 /*    Application                                                         */
2674 /*                                                                        */
2675 /*  RELEASE HISTORY                                                       */
2676 /*                                                                        */
2677 /*    DATE              NAME                      DESCRIPTION             */
2678 /*                                                                        */
2679 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2680 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2681 /*                                            resulting in version 6.1    */
2682 /*                                                                        */
2683 /**************************************************************************/
_nxe_dhcpv6_get_DNS_server_address(NX_DHCPV6 * dhcpv6_ptr,UINT index,NXD_ADDRESS * server_address)2684 UINT  _nxe_dhcpv6_get_DNS_server_address(NX_DHCPV6 *dhcpv6_ptr, UINT index, NXD_ADDRESS *server_address)
2685 {
2686 
2687 UINT status;
2688 
2689 
2690     /* Check for valid pointer input. */
2691     if (dhcpv6_ptr == NX_NULL)
2692     {
2693         return NX_PTR_ERROR;
2694     }
2695 
2696     /* Check for appropriate caller.  */
2697     NX_THREADS_ONLY_CALLER_CHECKING
2698 
2699     /* Call the actual service. */
2700     status =  _nx_dhcpv6_get_DNS_server_address(dhcpv6_ptr, index, server_address);
2701 
2702     /* Return completion status. */
2703     return status;
2704 }
2705 
2706 
2707 /**************************************************************************/
2708 /*                                                                        */
2709 /*  FUNCTION                                               RELEASE        */
2710 /*                                                                        */
2711 /*    _nx_dhcpv6_get_DNS_server_address                   PORTABLE C      */
2712 /*                                                           6.1          */
2713 /*  AUTHOR                                                                */
2714 /*                                                                        */
2715 /*    Yuxin Zhou, Microsoft Corporation                                   */
2716 /*                                                                        */
2717 /*  DESCRIPTION                                                           */
2718 /*                                                                        */
2719 /*    This function retrieves the DNS server address at the specified     */
2720 /*    index in the DHCP Client DNS list.  The Client DNS server list is   */
2721 /*    compiled from DHCP Server messages supplying DNS server address     */
2722 /*    data.                                                               */
2723 /*                                                                        */
2724 /*    Note: the DHCPv6 Client is configured to store up to                */
2725 /*    NX_DHCPV6_NUM_DNS_SERVERS DNS server addresses. It is up to the     */
2726 /*    caller to supply the index to get each server in the list if there  */
2727 /*    is more than one stored.                                            */
2728 /*                                                                        */
2729 /*  INPUT                                                                 */
2730 /*                                                                        */
2731 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
2732 /*    index                               Index into DNS server list      */
2733 /*    server_address                      Pointer to copy address to      */
2734 /*                                                                        */
2735 /*  OUTPUT                                                                */
2736 /*                                                                        */
2737 /*    NX_SUCCESS                          Successful completion status    */
2738 /*    NX_DHCPV6_PARAM_ERROR               Invalid index supplied          */
2739 /*                                                                        */
2740 /*  CALLS                                                                 */
2741 /*                                                                        */
2742 /*    _nx_dhcpv6_get_DNS_server_address  Actual get DNS server address    */
2743 /*                                            service                     */
2744 /*                                                                        */
2745 /*  CALLED BY                                                             */
2746 /*                                                                        */
2747 /*    Application                                                         */
2748 /*                                                                        */
2749 /*  RELEASE HISTORY                                                       */
2750 /*                                                                        */
2751 /*    DATE              NAME                      DESCRIPTION             */
2752 /*                                                                        */
2753 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2754 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2755 /*                                            resulting in version 6.1    */
2756 /*                                                                        */
2757 /**************************************************************************/
2758 
_nx_dhcpv6_get_DNS_server_address(NX_DHCPV6 * dhcpv6_ptr,UINT index,NXD_ADDRESS * server_address)2759 UINT  _nx_dhcpv6_get_DNS_server_address(NX_DHCPV6 *dhcpv6_ptr, UINT index, NXD_ADDRESS *server_address)
2760 {
2761 
2762 
2763     /* Check for a valid input. */
2764     if (index >= NX_DHCPV6_NUM_DNS_SERVERS)
2765     {
2766 
2767         return NX_DHCPV6_PARAM_ERROR;
2768     }
2769 
2770     /* Store the specified DNS server addresses in the DHCPv6 Client list. */
2771     COPY_NXD_ADDRESS(&(dhcpv6_ptr -> nx_dhcpv6_DNS_name_server_address[index]), server_address);
2772 
2773     return NX_SUCCESS;
2774 }
2775 
2776 
2777 /**************************************************************************/
2778 /*                                                                        */
2779 /*  FUNCTION                                               RELEASE        */
2780 /*                                                                        */
2781 /*    _nxe_dhcpv6_get_time_server_address                 PORTABLE C      */
2782 /*                                                           6.1          */
2783 /*  AUTHOR                                                                */
2784 /*                                                                        */
2785 /*    Yuxin Zhou, Microsoft Corporation                                   */
2786 /*                                                                        */
2787 /*  DESCRIPTION                                                           */
2788 /*                                                                        */
2789 /*                                                                        */
2790 /*  INPUT                                                                 */
2791 /*                                                                        */
2792 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
2793 /*    index                               Index into time server list     */
2794 /*    server_address                      Pointer to copy address to      */
2795 /*                                                                        */
2796 /*  OUTPUT                                                                */
2797 /*                                                                        */
2798 /*    NX_SUCCESS                          Successful completion status    */
2799 /*    NX_PTR_ERROR                        Invalid pointer input           */
2800 /*                                                                        */
2801 /*  CALLS                                                                 */
2802 /*    _nx_dhcpv6_get_time_server_address   Actual get time server address */
2803 /*                                              service                   */
2804 /*                                                                        */
2805 /*  CALLED BY                                                             */
2806 /*                                                                        */
2807 /*    Application                                                         */
2808 /*                                                                        */
2809 /*  RELEASE HISTORY                                                       */
2810 /*                                                                        */
2811 /*    DATE              NAME                      DESCRIPTION             */
2812 /*                                                                        */
2813 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2814 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2815 /*                                            resulting in version 6.1    */
2816 /*                                                                        */
2817 /**************************************************************************/
_nxe_dhcpv6_get_time_server_address(NX_DHCPV6 * dhcpv6_ptr,UINT index,NXD_ADDRESS * server_address)2818 UINT  _nxe_dhcpv6_get_time_server_address(NX_DHCPV6 *dhcpv6_ptr, UINT index, NXD_ADDRESS *server_address)
2819 {
2820 
2821 UINT status;
2822 
2823 
2824     /* Check for valid pointer input. */
2825     if (dhcpv6_ptr == NX_NULL)
2826     {
2827         return NX_PTR_ERROR;
2828     }
2829 
2830     /* Check for appropriate caller.  */
2831     NX_THREADS_ONLY_CALLER_CHECKING
2832 
2833     /* Call the actual service. */
2834     status =  _nx_dhcpv6_get_time_server_address(dhcpv6_ptr, index, server_address);
2835 
2836     /* Return completion status. */
2837     return status;
2838 }
2839 
2840 
2841 /**************************************************************************/
2842 /*                                                                        */
2843 /*  FUNCTION                                               RELEASE        */
2844 /*                                                                        */
2845 /*    _nx_dhcpv6_get_time_server_address                  PORTABLE C      */
2846 /*                                                           6.1          */
2847 /*  AUTHOR                                                                */
2848 /*                                                                        */
2849 /*    Yuxin Zhou, Microsoft Corporation                                   */
2850 /*                                                                        */
2851 /*  DESCRIPTION                                                           */
2852 /*                                                                        */
2853 /*    This function retrieves the time server address at the specified    */
2854 /*    index in the DHCP Client time list. The Client time server list is  */
2855 /*    compiled from DHCP Server messages supplying time server address    */
2856 /*    data.                                                               */
2857 /*                                                                        */
2858 /*    Note: the DHCPv6 Client is configured to store up to                */
2859 /*    NX_DHCPV6_NUM_TIME_SERVERS TIME server addresses. It is up to the   */
2860 /*    caller to supply the index to get each server in the list if there  */
2861 /*    is more than one stored.                                            */
2862 /*                                                                        */
2863 /*  INPUT                                                                 */
2864 /*                                                                        */
2865 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
2866 /*    index                               Index into time server list     */
2867 /*    server_address                      Pointer to copy address to      */
2868 /*                                                                        */
2869 /*  OUTPUT                                                                */
2870 /*                                                                        */
2871 /*    NX_SUCCESS                          Successful completion status    */
2872 /*    NX_DHCPV6_PARAM_ERROR               Invalid index supplied          */
2873 /*                                                                        */
2874 /*  CALLS                                                                 */
2875 /*                                                                        */
2876 /*    _nx_dhcpv6_get_time_server_address  Actual get time server address  */
2877 /*                                            service                     */
2878 /*                                                                        */
2879 /*  CALLED BY                                                             */
2880 /*                                                                        */
2881 /*    Application                                                         */
2882 /*                                                                        */
2883 /*  RELEASE HISTORY                                                       */
2884 /*                                                                        */
2885 /*    DATE              NAME                      DESCRIPTION             */
2886 /*                                                                        */
2887 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2888 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2889 /*                                            resulting in version 6.1    */
2890 /*                                                                        */
2891 /**************************************************************************/
_nx_dhcpv6_get_time_server_address(NX_DHCPV6 * dhcpv6_ptr,UINT index,NXD_ADDRESS * server_address)2892 UINT  _nx_dhcpv6_get_time_server_address(NX_DHCPV6 *dhcpv6_ptr, UINT index, NXD_ADDRESS *server_address)
2893 {
2894 
2895 
2896     /* Check for a valid input. */
2897     if (index >= NX_DHCPV6_NUM_TIME_SERVERS)
2898     {
2899 
2900         return NX_DHCPV6_PARAM_ERROR;
2901     }
2902 
2903     /* Store the specified time server addresses in the DHCPv6 Client list. */
2904     COPY_NXD_ADDRESS(&(dhcpv6_ptr -> nx_dhcpv6_time_server_address[index]), server_address);
2905 
2906     return NX_SUCCESS;
2907 }
2908 
2909 
2910 /**************************************************************************/
2911 /*                                                                        */
2912 /*  FUNCTION                                               RELEASE        */
2913 /*                                                                        */
2914 /*    _nxe_dhcpv6_get_other_option_data                   PORTABLE C      */
2915 /*                                                           6.1          */
2916 /*  AUTHOR                                                                */
2917 /*                                                                        */
2918 /*    Yuxin Zhou, Microsoft Corporation                                   */
2919 /*                                                                        */
2920 /*  DESCRIPTION                                                           */
2921 /*                                                                        */
2922 /*                                                                        */
2923 /*  INPUT                                                                 */
2924 /*                                                                        */
2925 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
2926 /*    option_code                         Option code of requested data   */
2927 /*    buffer                              Buffer to copy data to          */
2928 /*    buffer_length                       Size of buffer to copy to       */
2929 /*                                                                        */
2930 /*  OUTPUT                                                                */
2931 /*                                                                        */
2932 /*    status                              Completion status               */
2933 /*    NX_PTR_ERROR                        Invalid pointer input           */
2934 /*    NX_DHCPV6_PARAM_ERROR               Invalid non pointer input       */
2935 /*                                                                        */
2936 /*  CALLS                                                                 */
2937 /*     _nx_dhcpv6_get_other_option_data   Actual get other option data    */
2938 /*                                              service                   */
2939 /*                                                                        */
2940 /*  CALLED BY                                                             */
2941 /*                                                                        */
2942 /*    Application                                                         */
2943 /*                                                                        */
2944 /*  RELEASE HISTORY                                                       */
2945 /*                                                                        */
2946 /*    DATE              NAME                      DESCRIPTION             */
2947 /*                                                                        */
2948 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2949 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2950 /*                                            resulting in version 6.1    */
2951 /*                                                                        */
2952 /**************************************************************************/
_nxe_dhcpv6_get_other_option_data(NX_DHCPV6 * dhcpv6_ptr,UINT option_code,UCHAR * buffer,UINT buffer_length)2953 UINT  _nxe_dhcpv6_get_other_option_data(NX_DHCPV6 *dhcpv6_ptr, UINT option_code, UCHAR *buffer,UINT buffer_length)
2954 {
2955 
2956 UINT status;
2957 
2958 
2959     /* Check for valid pointer input. */
2960     if (!dhcpv6_ptr || !buffer)
2961     {
2962         return NX_PTR_ERROR;
2963     }
2964 
2965     /* Check for invalid non pointer input. */
2966     if (!option_code || !buffer_length)
2967     {
2968 
2969         return NX_DHCPV6_PARAM_ERROR;
2970     }
2971 
2972     /* Check for appropriate caller.  */
2973     NX_THREADS_ONLY_CALLER_CHECKING
2974 
2975     /* Call the actual service. */
2976     status =  _nx_dhcpv6_get_other_option_data(dhcpv6_ptr, option_code, buffer, buffer_length);
2977 
2978     /* Return completion status. */
2979     return status;
2980 }
2981 
2982 
2983 /**************************************************************************/
2984 /*                                                                        */
2985 /*  FUNCTION                                               RELEASE        */
2986 /*                                                                        */
2987 /*    _nx_dhcpv6_get_other_option_data                    PORTABLE C      */
2988 /*                                                           6.1          */
2989 /*  AUTHOR                                                                */
2990 /*                                                                        */
2991 /*    Yuxin Zhou, Microsoft Corporation                                   */
2992 /*                                                                        */
2993 /*  DESCRIPTION                                                           */
2994 /*                                                                        */
2995 /*    This function retrieves the option information requested in the     */
2996 /*    input parameter. Note that there are only 2 options  which the      */
2997 /*    NetX DHCPv6 client supports. Some options have their own specific   */
2998 /*    API such as _nx_dhcpv6_get_DNS_server_address.  The complete list   */
2999 /*    of options is not supported by the NetX Duo DHCPv6 Client.          */
3000 /*                                                                        */
3001 /*  INPUT                                                                 */
3002 /*                                                                        */
3003 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
3004 /*    option_code                         Option code of requested data   */
3005 /*    buffer                              Buffer to copy data to          */
3006 /*    buffer_length                       Size of buffer to copy to       */
3007 /*                                                                        */
3008 /*  OUTPUT                                                                */
3009 /*                                                                        */
3010 /*    status                              Completion status               */
3011 /*    NX_DHCPV6_UNKNOWN_OPTION            Unknown option specified        */
3012 /*                                                                        */
3013 /*  CALLS                                                                 */
3014 /*                                                                        */
3015 /*     memcpy                          Copy specified area of memory      */
3016 /*                                                                        */
3017 /*  CALLED BY                                                             */
3018 /*                                                                        */
3019 /*    Application                                                         */
3020 /*                                                                        */
3021 /*  RELEASE HISTORY                                                       */
3022 /*                                                                        */
3023 /*    DATE              NAME                      DESCRIPTION             */
3024 /*                                                                        */
3025 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3026 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
3027 /*                                            verified memcpy use cases,  */
3028 /*                                            resulting in version 6.1    */
3029 /*                                                                        */
3030 /**************************************************************************/
_nx_dhcpv6_get_other_option_data(NX_DHCPV6 * dhcpv6_ptr,UINT option_code,UCHAR * buffer,UINT buffer_length)3031 UINT  _nx_dhcpv6_get_other_option_data(NX_DHCPV6 *dhcpv6_ptr, UINT option_code, UCHAR *buffer, UINT buffer_length)
3032 {
3033 
3034 
3035 UINT length = 0;
3036 
3037     /* Check to see which option data is requested: */
3038     switch (option_code)
3039     {
3040 
3041         case NX_DHCPV6_NEW_POSIX_TIMEZONE_OPTION:
3042 
3043             /* Update the amount of data we are copying into the buffer. */
3044             length += NX_DHCPV6_TIME_ZONE_BUFFER_SIZE;
3045 
3046             /* Check that we don't overrun the buffer. */
3047             if (length > buffer_length)
3048             {
3049                 return NX_DHCPV6_INVALID_DATA_SIZE;
3050             }
3051 
3052             /* Copy the time zone data to the supplied buffer. */
3053             memcpy(buffer, dhcpv6_ptr -> nx_dhcpv6_time_zone, NX_DHCPV6_TIME_ZONE_BUFFER_SIZE);  /* Use case of memcpy is verified. */
3054 
3055             break;
3056 
3057 
3058         case NX_DHCPV6_DOMAIN_NAME_OPTION:
3059 
3060             /* Update the amount of data we are copying into the buffer. */
3061             length +=  NX_DHCPV6_DOMAIN_NAME_BUFFER_SIZE;
3062 
3063             /* Check that we don't overrun the buffer. */
3064             if (length > buffer_length)
3065             {
3066                 return NX_DHCPV6_INVALID_DATA_SIZE;
3067             }
3068 
3069             /* Copy the domain name data to the supplied buffer. */
3070             memcpy(buffer, dhcpv6_ptr -> nx_dhcpv6_domain_name, NX_DHCPV6_DOMAIN_NAME_BUFFER_SIZE); /* Use case of memcpy is verified. */
3071             break;
3072 
3073         /* Unknown or unsupported option*/
3074         default:
3075 
3076             return NX_DHCPV6_UNKNOWN_OPTION;
3077     }
3078 
3079     return NX_SUCCESS;
3080 }
3081 
3082 
3083 /**************************************************************************/
3084 /*                                                                        */
3085 /*  FUNCTION                                               RELEASE        */
3086 /*                                                                        */
3087 /*    _nxe_dhcpv6_get_time_accrued                        PORTABLE C      */
3088 /*                                                           6.1          */
3089 /*  AUTHOR                                                                */
3090 /*                                                                        */
3091 /*    Yuxin Zhou, Microsoft Corporation                                   */
3092 /*                                                                        */
3093 /*  DESCRIPTION                                                           */
3094 /*                                                                        */
3095 /*    This function performs error checking on the get time accrued on    */
3096 /*    Client IP lease service.                                            */
3097 /*                                                                        */
3098 /*  INPUT                                                                 */
3099 /*                                                                        */
3100 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
3101 /*    time_accrued                        Pointer to time since IP lease  */
3102 /*                                            assigned (secs)             */
3103 /*                                                                        */
3104 /*  OUTPUT                                                                */
3105 /*                                                                        */
3106 /*    status                            Actual completion status          */
3107 /*    NX_PTR_ERROR                      Invalid pointer input             */
3108 /*                                                                        */
3109 /*  CALLS                                                                 */
3110 /*                                                                        */
3111 /*    _nx_dhcpv6_get_time_accrued       Actual get time accrued on Client */
3112 /*                                          IP address lease service      */
3113 /*                                                                        */
3114 /*  CALLED BY                                                             */
3115 /*                                                                        */
3116 /*    Application Code                                                    */
3117 /*                                                                        */
3118 /*  RELEASE HISTORY                                                       */
3119 /*                                                                        */
3120 /*    DATE              NAME                      DESCRIPTION             */
3121 /*                                                                        */
3122 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3123 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3124 /*                                            resulting in version 6.1    */
3125 /*                                                                        */
3126 /**************************************************************************/
_nxe_dhcpv6_get_time_accrued(NX_DHCPV6 * dhcpv6_ptr,ULONG * time_accrued)3127 UINT _nxe_dhcpv6_get_time_accrued(NX_DHCPV6 *dhcpv6_ptr, ULONG *time_accrued)
3128 {
3129 
3130 UINT status;
3131 
3132 
3133     /* Check for valid pointer input. */
3134     if (!dhcpv6_ptr || !time_accrued)
3135     {
3136         return NX_PTR_ERROR;
3137     }
3138 
3139     /* Check for appropriate caller.  */
3140     NX_THREADS_ONLY_CALLER_CHECKING
3141 
3142     /* Call the actual service. */
3143     status =  _nx_dhcpv6_get_time_accrued(dhcpv6_ptr, time_accrued);
3144 
3145     /* Return completion status. */
3146     return status;
3147 }
3148 
3149 
3150 /**************************************************************************/
3151 /*                                                                        */
3152 /*  FUNCTION                                               RELEASE        */
3153 /*                                                                        */
3154 /*    _nx_dhcpv6_get_time_accrued                         PORTABLE C      */
3155 /*                                                           6.1          */
3156 /*  AUTHOR                                                                */
3157 /*                                                                        */
3158 /*    Yuxin Zhou, Microsoft Corporation                                   */
3159 /*                                                                        */
3160 /*  DESCRIPTION                                                           */
3161 /*                                                                        */
3162 /*    This function retrieves the time accrued on the assigned global IP  */
3163 /*    address lease.  IP address to verify the address is still valid.    */
3164 /*                                                                        */
3165 /*  INPUT                                                                 */
3166 /*                                                                        */
3167 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
3168 /*    time_accrued                        Pointer to time since IP lease  */
3169 /*                                            assigned (secs)             */
3170 /*                                                                        */
3171 /*  OUTPUT                                                                */
3172 /*                                                                        */
3173 /*    NX_SUCCESS                          Successful completion status    */
3174 /*                                                                        */
3175 /*  CALLS                                                                 */
3176 /*                                                                        */
3177 /*     tx_mutex_get                      Obtain exclusive lock on Client  */
3178 /*                                         time accrued variable          */
3179 /*     tx_mutex_put                      Release exclusive lock in Client */
3180 /*                                         time variable                  */
3181 /*                                                                        */
3182 /*  CALLED BY                                                             */
3183 /*                                                                        */
3184 /*    Application                                                         */
3185 /*                                                                        */
3186 /*  RELEASE HISTORY                                                       */
3187 /*                                                                        */
3188 /*    DATE              NAME                      DESCRIPTION             */
3189 /*                                                                        */
3190 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3191 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3192 /*                                            resulting in version 6.1    */
3193 /*                                                                        */
3194 /**************************************************************************/
_nx_dhcpv6_get_time_accrued(NX_DHCPV6 * dhcpv6_ptr,ULONG * time_accrued)3195 UINT _nx_dhcpv6_get_time_accrued(NX_DHCPV6 *dhcpv6_ptr, ULONG *time_accrued)
3196 {
3197 UINT    ia_index;
3198 UINT    found_ia = 0;
3199 
3200     /* Initialize the time accrued to zero. */
3201     *time_accrued = 0;
3202 
3203     /* Check if the client currently has a valid IP address assigned. */
3204     for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
3205     {
3206 
3207         if(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status == NX_DHCPV6_IA_ADDRESS_STATE_VALID)
3208         {
3209 
3210             /* Yes, got it.  */
3211             found_ia= 1;
3212             break;
3213         }
3214     }
3215 
3216     if(found_ia == 1)
3217     {
3218 
3219         /* Get the time accrued on the IP address lease. */
3220         *time_accrued = dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_time_accrued;
3221     }
3222 
3223     /* Return successful completion. */
3224     return NX_SUCCESS;
3225 }
3226 
3227 
3228 /**************************************************************************/
3229 /*                                                                        */
3230 /*  FUNCTION                                               RELEASE        */
3231 /*                                                                        */
3232 /*    _nxe_dhcpv6_get_iana_lease_time                     PORTABLE C      */
3233 /*                                                           6.1          */
3234 /*  AUTHOR                                                                */
3235 /*                                                                        */
3236 /*    Yuxin Zhou, Microsoft Corporation                                   */
3237 /*                                                                        */
3238 /*  DESCRIPTION                                                           */
3239 /*                                                                        */
3240 /*    This function performs error checking on the get T1 and T2 value    */
3241 /*    of IANA option.                                                     */
3242 /*                                                                        */
3243 /*  INPUT                                                                 */
3244 /*                                                                        */
3245 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
3246 /*    T1                                  Pointer to T1 time              */
3247 /*    T2                                  Pointer to T2 time              */
3248 /*                                                                        */
3249 /*  OUTPUT                                                                */
3250 /*                                                                        */
3251 /*    status                            Actual completion status          */
3252 /*    NX_PTR_ERROR                      Invalid pointer input             */
3253 /*                                                                        */
3254 /*  CALLS                                                                 */
3255 /*                                                                        */
3256 /*    _nx_dhcpv6_get_iana_lease_time    Actual get Client IP T1/T2 time   */
3257 /*                                                                        */
3258 /*  CALLED BY                                                             */
3259 /*                                                                        */
3260 /*    Application Code                                                    */
3261 /*                                                                        */
3262 /*  RELEASE HISTORY                                                       */
3263 /*                                                                        */
3264 /*    DATE              NAME                      DESCRIPTION             */
3265 /*                                                                        */
3266 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3267 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3268 /*                                            resulting in version 6.1    */
3269 /*                                                                        */
3270 /**************************************************************************/
_nxe_dhcpv6_get_iana_lease_time(NX_DHCPV6 * dhcpv6_ptr,ULONG * T1,ULONG * T2)3271 UINT _nxe_dhcpv6_get_iana_lease_time(NX_DHCPV6 *dhcpv6_ptr, ULONG *T1, ULONG *T2)
3272 {
3273 
3274 UINT status;
3275 
3276 
3277     /* Check for valid pointer input. */
3278     if (!dhcpv6_ptr || !T1 || !T2)
3279     {
3280         return NX_PTR_ERROR;
3281     }
3282 
3283     /* Check for appropriate caller.  */
3284     NX_THREADS_ONLY_CALLER_CHECKING
3285 
3286     /* Call the actual service. */
3287     status =  _nx_dhcpv6_get_iana_lease_time(dhcpv6_ptr, T1, T2);
3288 
3289     /* Return completion status. */
3290     return status;
3291 }
3292 
3293 
3294 /**************************************************************************/
3295 /*                                                                        */
3296 /*  FUNCTION                                               RELEASE        */
3297 /*                                                                        */
3298 /*    _nx_dhcpv6_get_iana_lease_time                      PORTABLE C      */
3299 /*                                                           6.1          */
3300 /*  AUTHOR                                                                */
3301 /*                                                                        */
3302 /*    Yuxin Zhou, Microsoft Corporation                                   */
3303 /*                                                                        */
3304 /*  DESCRIPTION                                                           */
3305 /*                                                                        */
3306 /*    This function retrieves the T1 and T2 of Client's global IP.        */
3307 /*                                                                        */
3308 /*  INPUT                                                                 */
3309 /*                                                                        */
3310 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
3311 /*    T1                                  Pointer to T1 time              */
3312 /*    T2                                  Pointer to T2 time              */
3313 /*                                                                        */
3314 /*  OUTPUT                                                                */
3315 /*                                                                        */
3316 /*    NX_SUCCESS                          Successful completion status    */
3317 /*                                                                        */
3318 /*  CALLS                                                                 */
3319 /*                                                                        */
3320 /*     None                                                               */
3321 /*                                                                        */
3322 /*  CALLED BY                                                             */
3323 /*                                                                        */
3324 /*    Application                                                         */
3325 /*                                                                        */
3326 /*  RELEASE HISTORY                                                       */
3327 /*                                                                        */
3328 /*    DATE              NAME                      DESCRIPTION             */
3329 /*                                                                        */
3330 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3331 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3332 /*                                            resulting in version 6.1    */
3333 /*                                                                        */
3334 /**************************************************************************/
_nx_dhcpv6_get_iana_lease_time(NX_DHCPV6 * dhcpv6_ptr,ULONG * T1,ULONG * T2)3335 UINT _nx_dhcpv6_get_iana_lease_time(NX_DHCPV6 *dhcpv6_ptr, ULONG *T1, ULONG *T2)
3336 {
3337 UINT    ia_index;
3338 UINT    found_ia = 0;
3339 
3340     /* Initialize data to zero. */
3341     *T1 = 0;
3342     *T2 = 0;
3343 
3344     /* Check if the client currently has a valid IP address assigned. */
3345     for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
3346     {
3347 
3348         if(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status == NX_DHCPV6_IA_ADDRESS_STATE_VALID)
3349         {
3350 
3351             /* Yes, got it.  */
3352             found_ia= 1;
3353             break;
3354         }
3355     }
3356 
3357     if(found_ia == 1)
3358     {
3359 
3360         /* Get the time data from the Client record IA. */
3361         *T1 = dhcpv6_ptr -> nx_dhcpv6_iana.nx_T1;
3362         *T2 = dhcpv6_ptr -> nx_dhcpv6_iana.nx_T2;
3363     }
3364 
3365     /* Return successful completion. */
3366     return NX_SUCCESS;
3367 }
3368 
3369 
3370 /**************************************************************************/
3371 /*                                                                        */
3372 /*  FUNCTION                                               RELEASE        */
3373 /*                                                                        */
3374 /*    _nxe_dhcpv6_get_valid_ip_address_count              PORTABLE C      */
3375 /*                                                           6.1          */
3376 /*  AUTHOR                                                                */
3377 /*                                                                        */
3378 /*    Yuxin Zhou, Microsoft Corporation                                   */
3379 /*                                                                        */
3380 /*  DESCRIPTION                                                           */
3381 /*                                                                        */
3382 /*    This function performs error checking on the get valid IP address   */
3383 /*    count.                                                              */
3384 /*                                                                        */
3385 /*  INPUT                                                                 */
3386 /*                                                                        */
3387 /*    dhcpv6_ptr                        Pointer to DHCPv6 Client          */
3388 /*    address_count                     The count of valid IP address     */
3389 /*                                                                        */
3390 /*  OUTPUT                                                                */
3391 /*                                                                        */
3392 /*    status                            Actual completion status          */
3393 /*    NX_PTR_ERROR                      Invalid pointer input             */
3394 /*                                                                        */
3395 /*  CALLS                                                                 */
3396 /*                                                                        */
3397 /*    _nx_dhcpv6_get_valid_ip_address_count                               */
3398 /*                                      Actual get the valid IP count     */
3399 /*                                                                        */
3400 /*  CALLED BY                                                             */
3401 /*                                                                        */
3402 /*    Application Code                                                    */
3403 /*                                                                        */
3404 /*  RELEASE HISTORY                                                       */
3405 /*                                                                        */
3406 /*    DATE              NAME                      DESCRIPTION             */
3407 /*                                                                        */
3408 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3409 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3410 /*                                            resulting in version 6.1    */
3411 /*                                                                        */
3412 /**************************************************************************/
_nxe_dhcpv6_get_valid_ip_address_count(NX_DHCPV6 * dhcpv6_ptr,UINT * address_count)3413 UINT _nxe_dhcpv6_get_valid_ip_address_count(NX_DHCPV6 *dhcpv6_ptr, UINT *address_count)
3414 {
3415 
3416 UINT status;
3417 
3418 
3419     /* Check for valid pointer input. */
3420     if (!dhcpv6_ptr || !address_count)
3421     {
3422         return NX_PTR_ERROR;
3423     }
3424 
3425     /* Check for appropriate caller.  */
3426     NX_THREADS_ONLY_CALLER_CHECKING
3427 
3428     /* Call the actual service. */
3429     status =  _nx_dhcpv6_get_valid_ip_address_count(dhcpv6_ptr, address_count);
3430 
3431     /* Return completion status. */
3432     return status;
3433 }
3434 
3435 
3436 /**************************************************************************/
3437 /*                                                                        */
3438 /*  FUNCTION                                               RELEASE        */
3439 /*                                                                        */
3440 /*    _nx_dhcpv6_get_valid_ip_address_count               PORTABLE C      */
3441 /*                                                           6.1          */
3442 /*  AUTHOR                                                                */
3443 /*                                                                        */
3444 /*    Yuxin Zhou, Microsoft Corporation                                   */
3445 /*                                                                        */
3446 /*  DESCRIPTION                                                           */
3447 /*                                                                        */
3448 /*    This function retrieves the Client's global IP, then record the     */
3449 /*    count of valid IP address                                           */
3450 /*                                                                        */
3451 /*  INPUT                                                                 */
3452 /*                                                                        */
3453 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
3454 /*    address_count                       The count of valid IP address   */
3455 /*                                                                        */
3456 /*  OUTPUT                                                                */
3457 /*                                                                        */
3458 /*    NX_SUCCESS                          Successful completion status    */
3459 /*                                                                        */
3460 /*  CALLS                                                                 */
3461 /*                                                                        */
3462 /*     None                                                               */
3463 /*                                                                        */
3464 /*  CALLED BY                                                             */
3465 /*                                                                        */
3466 /*    Application                                                         */
3467 /*                                                                        */
3468 /*  RELEASE HISTORY                                                       */
3469 /*                                                                        */
3470 /*    DATE              NAME                      DESCRIPTION             */
3471 /*                                                                        */
3472 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3473 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3474 /*                                            resulting in version 6.1    */
3475 /*                                                                        */
3476 /**************************************************************************/
_nx_dhcpv6_get_valid_ip_address_count(NX_DHCPV6 * dhcpv6_ptr,UINT * address_count)3477 UINT _nx_dhcpv6_get_valid_ip_address_count(NX_DHCPV6 *dhcpv6_ptr, UINT *address_count)
3478 {
3479 
3480 UINT    ia_index;
3481 
3482     /* Initialize data to zero. */
3483     *address_count = 0;
3484 
3485     /* Check if the client currently has a valid IP address assigned. */
3486     for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
3487     {
3488 
3489         if(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status == NX_DHCPV6_IA_ADDRESS_STATE_VALID)
3490         {
3491 
3492             /* Yes, get one, update the count. */
3493             (*address_count)++;
3494         }
3495     }
3496 
3497     /* Return successful completion. */
3498     return NX_SUCCESS;
3499 }
3500 
3501 
3502 /**************************************************************************/
3503 /*                                                                        */
3504 /*  FUNCTION                                               RELEASE        */
3505 /*                                                                        */
3506 /*    _nxe_dhcpv6_get_valid_ip_address_lease_time         PORTABLE C      */
3507 /*                                                           6.1          */
3508 /*  AUTHOR                                                                */
3509 /*                                                                        */
3510 /*    Yuxin Zhou, Microsoft Corporation                                   */
3511 /*                                                                        */
3512 /*  DESCRIPTION                                                           */
3513 /*                                                                        */
3514 /*    This function performs error checking on the get valid IP address,  */
3515 /*    the preferred lifetime and the valid lifetime by the address index. */
3516 /*                                                                        */
3517 /*  INPUT                                                                 */
3518 /*                                                                        */
3519 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
3520 /*    address_index                       The valid address index         */
3521 /*    ip_address                          Pointer to IP address           */
3522 /*    preferred_lifetime                  Pointer to preferred lifetime   */
3523 /*    valid_lifetime                      Pointer to valid lifetime       */
3524 /*                                                                        */
3525 /*  OUTPUT                                                                */
3526 /*                                                                        */
3527 /*    status                            Actual completion status          */
3528 /*    NX_PTR_ERROR                      Invalid pointer input             */
3529 /*                                                                        */
3530 /*  CALLS                                                                 */
3531 /*                                                                        */
3532 /*    _nx_dhcpv6_get_lvalid_ip_address_lease_time                         */
3533 /*                                      Actual get Client IP valid address*/
3534 /*                                        and the lease time of IP        */
3535 /*                                                                        */
3536 /*  CALLED BY                                                             */
3537 /*                                                                        */
3538 /*    Application Code                                                    */
3539 /*                                                                        */
3540 /*  RELEASE HISTORY                                                       */
3541 /*                                                                        */
3542 /*    DATE              NAME                      DESCRIPTION             */
3543 /*                                                                        */
3544 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3545 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3546 /*                                            resulting in version 6.1    */
3547 /*                                                                        */
3548 /**************************************************************************/
_nxe_dhcpv6_get_valid_ip_address_lease_time(NX_DHCPV6 * dhcpv6_ptr,UINT address_index,NXD_ADDRESS * ip_address,ULONG * preferred_lifetime,ULONG * valid_lifetime)3549 UINT _nxe_dhcpv6_get_valid_ip_address_lease_time(NX_DHCPV6 *dhcpv6_ptr, UINT address_index, NXD_ADDRESS *ip_address,
3550                                                  ULONG *preferred_lifetime, ULONG *valid_lifetime)
3551 {
3552 
3553 UINT status;
3554 
3555 
3556     /* Check for valid pointer input. */
3557     if (!dhcpv6_ptr || !ip_address || !preferred_lifetime || !valid_lifetime )
3558     {
3559         return NX_PTR_ERROR;
3560     }
3561 
3562     /* Check for appropriate caller.  */
3563     NX_THREADS_ONLY_CALLER_CHECKING
3564 
3565     /* Call the actual service. */
3566     status =  _nx_dhcpv6_get_valid_ip_address_lease_time(dhcpv6_ptr, address_index, ip_address, preferred_lifetime, valid_lifetime);
3567 
3568     /* Return completion status. */
3569     return status;
3570 }
3571 
3572 
3573 /**************************************************************************/
3574 /*                                                                        */
3575 /*  FUNCTION                                               RELEASE        */
3576 /*                                                                        */
3577 /*    _nx_dhcpv6_get_valid_ip_address_lease_time          PORTABLE C      */
3578 /*                                                           6.1          */
3579 /*  AUTHOR                                                                */
3580 /*                                                                        */
3581 /*    Yuxin Zhou, Microsoft Corporation                                   */
3582 /*                                                                        */
3583 /*  DESCRIPTION                                                           */
3584 /*                                                                        */
3585 /*    This function retrieves the Client's valid global IP addresses,     */
3586 /*    preferred lifetime and valid lifetime by address index.             */
3587 /*                                                                        */
3588 /*  INPUT                                                                 */
3589 /*                                                                        */
3590 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
3591 /*    address_index                       The valid address index         */
3592 /*    ip_address                          Pointer to IPv6 address         */
3593 /*    preferred_lifetime                  Pointer to preferred lifetime   */
3594 /*    valid_lifetime                      Pointer to valid lifetime       */
3595 /*                                                                        */
3596 /*  OUTPUT                                                                */
3597 /*                                                                        */
3598 /*    NX_SUCCESS                          Successful completion status    */
3599 /*                                                                        */
3600 /*  CALLS                                                                 */
3601 /*                                                                        */
3602 /*     None                                                               */
3603 /*                                                                        */
3604 /*  CALLED BY                                                             */
3605 /*                                                                        */
3606 /*    Application                                                         */
3607 /*                                                                        */
3608 /*  RELEASE HISTORY                                                       */
3609 /*                                                                        */
3610 /*    DATE              NAME                      DESCRIPTION             */
3611 /*                                                                        */
3612 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3613 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3614 /*                                            resulting in version 6.1    */
3615 /*                                                                        */
3616 /**************************************************************************/
_nx_dhcpv6_get_valid_ip_address_lease_time(NX_DHCPV6 * dhcpv6_ptr,UINT address_index,NXD_ADDRESS * ip_address,ULONG * preferred_lifetime,ULONG * valid_lifetime)3617 UINT _nx_dhcpv6_get_valid_ip_address_lease_time(NX_DHCPV6 *dhcpv6_ptr, UINT address_index, NXD_ADDRESS *ip_address,
3618                                                 ULONG *preferred_lifetime, ULONG *valid_lifetime)
3619 {
3620 
3621 UINT    status;
3622 UINT    ia_index;
3623 UINT    valid_ia_count;
3624 
3625 
3626     /* Initialize data to zero. */
3627     valid_ia_count = 0;
3628     *valid_lifetime = 0;
3629     *preferred_lifetime = 0;
3630     status = NX_DHCPV6_IA_ADDRESS_NOT_VALID;
3631 
3632     /* Clear the address buffer. */
3633     SET_UNSPECIFIED_ADDRESS(&ip_address -> nxd_ip_address.v6[0]);
3634 
3635     /* Check if the client currently has a valid IP address assigned. */
3636     for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
3637     {
3638 
3639         /* Skip empty or invalidated addresses. */
3640         if(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status == NX_DHCPV6_IA_ADDRESS_STATE_VALID)
3641         {
3642 
3643             if((valid_ia_count++) == address_index)
3644             {
3645 
3646                 /* Yes, got it.  */
3647                 break;
3648             }
3649         }
3650     }
3651 
3652     if(ia_index < NX_DHCPV6_MAX_IA_ADDRESS)
3653     {
3654 
3655         /* Yes; return the assigned IP address from the DHCPv6 Client record. */
3656         COPY_IPV6_ADDRESS(&(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[0]),
3657                           &(ip_address -> nxd_ip_address.v6[0]));
3658 
3659         /* Set the IP version.  */
3660         ip_address -> nxd_ip_version = NX_IP_VERSION_V6;
3661 
3662         /* Return the preferred lifetime and valid lifetime.  */
3663         *preferred_lifetime = dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_preferred_lifetime;
3664         *valid_lifetime = dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_valid_lifetime;
3665 
3666         status = NX_SUCCESS;
3667     }
3668 
3669     /* Return. */
3670     return status;
3671 }
3672 
3673 
3674 /**************************************************************************/
3675 /*                                                                        */
3676 /*  FUNCTION                                               RELEASE        */
3677 /*                                                                        */
3678 /*    _nx_dhcpv6_IP_lifetime_timeout_entry                PORTABLE C      */
3679 /*                                                           6.1          */
3680 /*  AUTHOR                                                                */
3681 /*                                                                        */
3682 /*    Yuxin Zhou, Microsoft Corporation                                   */
3683 /*                                                                        */
3684 /*  DESCRIPTION                                                           */
3685 /*                                                                        */
3686 /*    This function is scheduled by the ThreadX scheduler on a user       */
3687 /*    configurable time interval.  It updates the time accrued since the  */
3688 /*    Client was assigned its global IP address so that the DHCP Client   */
3689 /*    knows when to renew or rebind its IP address.                       */
3690 /*                                                                        */
3691 /*  INPUT                                                                 */
3692 /*                                                                        */
3693 /*    dhcpv6_ptr_value                      Pointer to the DHCPV6 Client  */
3694 /*                                                                        */
3695 /*  OUTPUT                                                                */
3696 /*                                                                        */
3697 /*    None                                                                */
3698 /*                                                                        */
3699 /*  CALLS                                                                 */
3700 /*                                                                        */
3701 /*    None                                                                */
3702 /*                                                                        */
3703 /*  CALLED BY                                                             */
3704 /*                                                                        */
3705 /*                                                                        */
3706 /*  RELEASE HISTORY                                                       */
3707 /*                                                                        */
3708 /*    DATE              NAME                      DESCRIPTION             */
3709 /*                                                                        */
3710 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3711 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3712 /*                                            resulting in version 6.1    */
3713 /*                                                                        */
3714 /**************************************************************************/
_nx_dhcpv6_IP_lifetime_timeout_entry(ULONG dhcpv6_ptr_value)3715 VOID  _nx_dhcpv6_IP_lifetime_timeout_entry(ULONG dhcpv6_ptr_value)
3716 {
3717 
3718 NX_DHCPV6 *dhcpv6_ptr;
3719 
3720 
3721     /* Setup DHCPv6 Client pointer.  */
3722     NX_TIMER_EXTENSION_PTR_GET(dhcpv6_ptr, NX_DHCPV6, dhcpv6_ptr_value)
3723 
3724     /* Check if the DHCPv6 Client has valid IP address assigned and a finite IP
3725        address lease (no point in waiting for an infinite lease to time out!) */
3726     if ((dhcpv6_ptr -> nx_dhcpv6_iana.nx_T1 != NX_DHCPV6_INFINITE_LEASE) &&
3727         (dhcpv6_ptr -> nx_dhcpv6_iana.nx_T1 != 0))
3728     {
3729 
3730         /* Update the time remaining on the Client IP address lease.
3731            The current time expressed in units of seconds. */
3732         dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_time_accrued += NX_DHCPV6_IP_LIFETIME_TIMER_INTERVAL;
3733     }
3734 
3735     return;
3736 }
3737 
3738 
3739 /**************************************************************************/
3740 /*                                                                        */
3741 /*  FUNCTION                                               RELEASE        */
3742 /*                                                                        */
3743 /*    _nx_dhcpv6_process                                  PORTABLE C      */
3744 /*                                                           6.1          */
3745 /*  AUTHOR                                                                */
3746 /*                                                                        */
3747 /*    Yuxin Zhou, Microsoft Corporation                                   */
3748 /*                                                                        */
3749 /*  DESCRIPTION                                                           */
3750 /*                                                                        */
3751 /*    This function executes the DHCPV6 Client request.  It compiles      */
3752 /*    and sends the DHCPv6 request message, and updates the Client record */
3753 /*    with server data.  It maintains the DHCPv6 Client state and calls   */
3754 /*    the state change callback if one is registered with the DHCPv6      */
3755 /*    Client.                                                             */
3756 /*                                                                        */
3757 /*  INPUT                                                                 */
3758 /*                                                                        */
3759 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
3760 /*                                                                        */
3761 /*  OUTPUT                                                                */
3762 /*                                                                        */
3763 /*     None                                                               */
3764 /*                                                                        */
3765 /*  CALLS                                                                 */
3766 /*                                                                        */
3767 /*    _nx_dhcpv6_send_request           Send the Client DHCPv6 request    */
3768 /*    _nx_dhcpv6_waiting_on_reply       Wait for valid DHCPv6 server reply*/
3769 /*    _nx_dhcpv6_request_decline        Send the DHCPv6 DECLINE request   */
3770 /*    _nx_dhcpv6_register_IP_address    Register Client IP address        */
3771 /*    _nx_dhcpv6_remove_assigned_address                                  */
3772 /*                                      Remove Client global IP address   */
3773 /*    _nx_dhcpv6_update_retransmit_info Update the retransmit information */
3774 /*    _nx_dhcpv6_send_solicit           Send the DHCPv6 solicit message   */
3775 /*    _nx_dhcpv6_flush_queue_packets    Flush the queue packets           */
3776 /*    tx_mutex_get                      Obtain lock on Client resource    */
3777 /*    tx_mutex_put                      Release lock on Client resourse   */
3778 /*    tx_timer_deactivate               Deactivate the session timer      */
3779 /*                                                                        */
3780 /*  CALLED BY                                                             */
3781 /*                                                                        */
3782 /*    _nx_dhcpv6_thread_entry           Processing thread for DHCPv6      */
3783 /*                                                                        */
3784 /*  RELEASE HISTORY                                                       */
3785 /*                                                                        */
3786 /*    DATE              NAME                      DESCRIPTION             */
3787 /*                                                                        */
3788 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3789 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3790 /*                                            resulting in version 6.1    */
3791 /*                                                                        */
3792 /**************************************************************************/
_nx_dhcpv6_process(NX_DHCPV6 * dhcpv6_ptr)3793 VOID  _nx_dhcpv6_process(NX_DHCPV6 *dhcpv6_ptr)
3794 {
3795 
3796 UINT      status;
3797 UCHAR     original_state;
3798 
3799     /* Initialize the DHCPv6 Client status as no errors. */
3800     dhcpv6_ptr -> nx_status_code = NX_DHCPV6_SUCCESS;
3801 
3802     /* Clear any previous messages from the DHCPv6 server. */
3803     memset(dhcpv6_ptr -> nx_status_message, 0, NX_DHCPV6_MAX_MESSAGE_SIZE);
3804 
3805     /* Remember the original DHCPv6 state for the changed state callback function.  */
3806     original_state =  dhcpv6_ptr -> nx_dhcpv6_state;
3807 
3808     /* Process the DHCPv6 Client for the state it is in. */
3809     switch (dhcpv6_ptr -> nx_dhcpv6_state)
3810     {
3811 
3812         /* The DHCPv6 remains initial status or DHCPv6 interactive process has completed.
3813            Just clear the timer and message ID. */
3814         case NX_DHCPV6_STATE_INIT:
3815         case NX_DHCPV6_STATE_BOUND_TO_ADDRESS:
3816         {
3817 
3818             /* Clear the message id.  */
3819             dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid = 0;
3820 
3821             /* Deactivate the session timer of elapsed time.  */
3822             tx_timer_deactivate(&(dhcpv6_ptr -> nx_dhcpv6_session_timer));
3823 
3824             /* Flush the queue packets.  */
3825             _nx_dhcpv6_flush_queue_packets(dhcpv6_ptr);
3826 
3827             return;
3828         }
3829 
3830         /* The caller has requested to send a solicit message. */
3831         case NX_DHCPV6_STATE_SENDING_SOLICIT:
3832         {
3833 
3834             dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type =  NX_DHCPV6_MESSAGE_TYPE_SOLICIT;
3835 
3836             dhcpv6_ptr -> nx_dhcpv6_solicitations_sent++;
3837 
3838             /* Send the DHCPV6 Solicit message.  */
3839             status = _nx_dhcpv6_send_request(dhcpv6_ptr);
3840 
3841             /* Check for error. */
3842             if (status != NX_SUCCESS)
3843             {
3844 
3845                 /* Return. Can't do any more now. */
3846                 return;
3847             }
3848 
3849             /* Make sure the server DUID is cleared. Client should be accepting any server reply. */
3850             memset(&(dhcpv6_ptr -> nx_dhcpv6_server_duid), 0, sizeof(NX_DHCPV6_DUID));
3851 
3852             /* Wait for a reply from the server. This will also extract the
3853                server packet information and update the DHCPv6 Client record (and state). */
3854             status = _nx_dhcpv6_waiting_on_reply(dhcpv6_ptr);
3855 
3856             /* Check for processing error or error code sent by server. As per RFC 3315 section 17.1.3,
3857                the Client ignores status errors (e.g. No Addresses Available)  from the server, and continues
3858                sending Solicit messages. */
3859             if ((status != NX_SUCCESS) || (dhcpv6_ptr -> nx_status_code != NX_DHCPV6_SUCCESS))
3860             {
3861 
3862                 /* Update the retransmission information. */
3863                 if (_nx_dhcpv6_update_retransmit_info(dhcpv6_ptr))
3864                 {
3865 
3866                     /* The retry limit on Solicit messages is exceeded. Set the CLient back to
3867                        the INIT state and stop sending solicit messages for now. */
3868                     dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_INIT;
3869 
3870                     /* Request attempt failed. The state change callback if set will be called. */
3871                 }
3872             }
3873             else
3874             {
3875 
3876                 if(dhcpv6_ptr -> nx_dhcpv6_request_solicit_mode == NX_DHCPV6_SOLICIT_NORMAL)
3877                 {
3878                     /* Server has responded to and accepted the SOLICIT request with an ADVERTISE message.
3879                        Move to the next state to continue the DHCPv6 protocol. */
3880 
3881                     /* Set the DHCP Client state to Requesting.  */
3882                     dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_SENDING_REQUEST;
3883 
3884                     /* Reset the retransmission timeout and retry. */
3885                     dhcpv6_ptr -> nx_dhcpv6_transmission_timeout =  NX_DHCPV6_INIT_REQ_TRANSMISSION_TIMEOUT;
3886                     dhcpv6_ptr -> nx_dhcpv6_retransmission_count = 0;
3887 
3888                     /* Set the initaial elasped time of DHCPv6 message.  */
3889                     dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = 0;
3890 
3891                     /* Set the retransmission information(IRT, MRC, MRT, MRD). */
3892                     dhcpv6_ptr -> nx_dhcpv6_init_retransmission_timeout = NX_DHCPV6_INIT_REQ_TRANSMISSION_TIMEOUT;
3893                     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_count = NX_DHCPV6_MAX_REQ_RETRANSMISSION_COUNT;
3894                     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_timeout = NX_DHCPV6_MAX_REQ_RETRANSMISSION_TIMEOUT;
3895                     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_duration = NX_DHCPV6_MAX_REQ_RETRANSMISSION_DURATION;
3896 
3897                     /* The next sending packet is the new packet, so reset the message id.  */
3898                     dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid = 0;
3899 
3900                     /* Increment the number of solicitation responses.  */
3901                     dhcpv6_ptr -> nx_dhcpv6_solicitation_responses++;
3902                 }
3903                 else
3904                 {
3905 
3906                     /* Server sending the REPLY message responded to and accepted the SOLICIT request with Rapid Commit option,
3907                        Move to the next state to continue the DHCPv6 protocol. */
3908 
3909                     /* Set the initaial elasped time of DHCPv6 message.  */
3910                     dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = 0;
3911 
3912                     /* Increment the number of solicitation responses.  */
3913                     dhcpv6_ptr -> nx_dhcpv6_solicitation_responses++;
3914 
3915                     /* Clear the message id.  */
3916                     dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid = 0;
3917 
3918                     /* Deactivate the session timer of elapsed time.  */
3919                     tx_timer_deactivate(&(dhcpv6_ptr -> nx_dhcpv6_session_timer));
3920 
3921                     /* Set the DHCP Client state to Requesting.  */
3922                     dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_BOUND_TO_ADDRESS;
3923 
3924                     /* Yes, get the IPv6 address by DHCPv6. set it.  */
3925                     status = _nx_dhcpv6_register_IP_address(dhcpv6_ptr);
3926 
3927                 }
3928 
3929             }
3930 
3931             break;
3932         }
3933 
3934 
3935         /* The DHCP Client is in the REQUEST state; send the Request message till the server responds
3936            or the number of retries exceeds the max. */
3937         case NX_DHCPV6_STATE_SENDING_REQUEST:
3938         {
3939 
3940             /* Reset the initial timeout and zero out transmission count. */
3941             dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type =  NX_DHCPV6_MESSAGE_TYPE_REQUEST;
3942 
3943             /* Transmit the Request message.  */
3944             status = _nx_dhcpv6_send_request(dhcpv6_ptr);
3945 
3946             /* Check for transmission error. */
3947             if (status != NX_SUCCESS)
3948             {
3949 
3950                 /* Return. Can't do any more now. */
3951                 return;
3952             }
3953 
3954             dhcpv6_ptr -> nx_dhcpv6_requests_sent++;
3955 
3956             /* Send the message to the server. */
3957             status = _nx_dhcpv6_waiting_on_reply(dhcpv6_ptr);
3958 
3959             /* Check for socket receive error or Server error code. */
3960             if ((status != NX_SUCCESS) || (dhcpv6_ptr -> nx_status_code != NX_DHCPV6_SUCCESS))
3961             {
3962 
3963                 /* Check the status.  */
3964                 if ((status == NX_SUCCESS) &&
3965                     ((dhcpv6_ptr -> nx_status_code == NX_DHCPV6_NOT_ON_LINK) ||
3966                      (dhcpv6_ptr -> nx_status_code == NX_DHCPV6_NO_ADDRESS_AVAILABLE)))
3967                 {
3968 
3969                     /* Indicate the DHCP Client process is idle. */
3970                     dhcpv6_ptr -> nx_dhcpv6_sleep_flag =  NX_TRUE;
3971 
3972                     /* The next sending packet is the new packet, so reset the message id.  */
3973                     dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid = 0;
3974 
3975                     /* Clear the assigned IP address.  */
3976                     _nx_dhcpv6_remove_assigned_address(dhcpv6_ptr,NX_DHCPV6_REMOVE_ALL_IA_ADDRESS);
3977 
3978                     /* When the client receives a NotOnLink status from the server in response to a Request,
3979                        the client can restart the DHCP server discovery process. RFC3315, Section18.1.8, Page48.  */
3980                     _nx_dhcpv6_request_solicit(dhcpv6_ptr);
3981                 }
3982 
3983                 else
3984                 {
3985 
3986                     /* Update the retransmission information. */
3987                     if (_nx_dhcpv6_update_retransmit_info(dhcpv6_ptr))
3988                     {
3989 
3990                         /* The retry limit on Request messages is exceeded. Set the Client back to
3991                         the INIT state and stop sending request messages for now. */
3992                         dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_INIT;
3993 
3994                         /* Request attempt failed. The state change callback if set will be called. */
3995                     }
3996                 }
3997             }
3998             else
3999             {
4000 
4001                 /* The Server responded to and accepted the REQUEST message. The Client is now bound to assigned
4002                    IPv6 address. The Client must still register this IPv6 address with NetX Duo to verify it is
4003                    unique on the network.  */
4004 
4005                 /* Clear the time accrued on the new IP lease to zero. */
4006                 dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_time_accrued = 0;
4007 
4008                 /* The next sending packet is the new packet, so reset the message id.  */
4009                 dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid = 0;
4010 
4011                 /* Receive the correct response, so deactivate the session timer of elapsed time. */
4012                 tx_timer_deactivate(&(dhcpv6_ptr -> nx_dhcpv6_session_timer));
4013 
4014                 /* Increment the number of Request responses received.  */
4015                 dhcpv6_ptr -> nx_dhcpv6_request_responses++;
4016 
4017                 /* Indicate the Client is bound to an assigned IPv6 address. */
4018                 dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_BOUND_TO_ADDRESS;
4019 
4020                 /* Yes, get the IPv6 address by DHCPv6. set it.  */
4021                 status = _nx_dhcpv6_register_IP_address(dhcpv6_ptr);
4022             }
4023 
4024             break;
4025         }
4026 
4027         /* The caller has requested a RENEW request message be sent. */
4028         case NX_DHCPV6_STATE_SENDING_RENEW:
4029         {
4030 
4031             dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type =  NX_DHCPV6_MESSAGE_TYPE_RENEW;
4032 
4033             dhcpv6_ptr -> nx_dhcpv6_renews_sent++;
4034 
4035             /* Send the DHCPV6 RENEW message.  */
4036             status = _nx_dhcpv6_send_request(dhcpv6_ptr);
4037 
4038             /* Check for transmission error. */
4039             if (status != NX_SUCCESS)
4040             {
4041 
4042                 /* Return. Can't do any more now. */
4043                 return;
4044             }
4045 
4046             /* Send the message to the server. */
4047             status = _nx_dhcpv6_waiting_on_reply(dhcpv6_ptr);
4048 
4049             /* Check for socket receive error or Server error code. */
4050             if ((status != NX_SUCCESS) ||
4051                 (dhcpv6_ptr -> nx_status_code != NX_DHCPV6_SUCCESS) ||
4052                 ((dhcpv6_ptr -> nx_dhcpv6_reply_option_flags & NX_DHCPV6_INCLUDE_IA_ADDRESS_OPTION) == 0))
4053             {
4054 
4055                 /* Process the NoBinding status.  */
4056                 if ((status == NX_SUCCESS) && (dhcpv6_ptr -> nx_status_code == NX_DHCPV6_NO_BINDING))
4057                 {
4058 
4059                     /* When the client receives a Reply message in response to a Renew or Rebind message,
4060                        send a Request message if the IA contains a Status Code option with the NoBinding status.
4061                        RFC 3315, Sectoon 18.1.8, Page 48.  */
4062                     dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_SENDING_REQUEST;
4063 
4064                     /* Reset the retransmission timeout and retry. */
4065                     dhcpv6_ptr -> nx_dhcpv6_transmission_timeout =  NX_DHCPV6_INIT_REQ_TRANSMISSION_TIMEOUT;
4066                     dhcpv6_ptr -> nx_dhcpv6_retransmission_count = 0;
4067 
4068                     /* Set the initaial elasped time of DHCPv6 message.  */
4069                     dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = 0;
4070 
4071                     /* Set the retransmission information(IRT, MRC, MRT, MRD). */
4072                     dhcpv6_ptr -> nx_dhcpv6_init_retransmission_timeout = NX_DHCPV6_INIT_REQ_TRANSMISSION_TIMEOUT;
4073                     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_count = NX_DHCPV6_MAX_REQ_RETRANSMISSION_COUNT;
4074                     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_timeout = NX_DHCPV6_MAX_REQ_RETRANSMISSION_TIMEOUT;
4075                     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_duration = NX_DHCPV6_MAX_REQ_RETRANSMISSION_DURATION;
4076 
4077                     /* The next sending packet is the new packet, so reset the message id.  */
4078                     dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid = 0;
4079                 }
4080                 else
4081                 {
4082 
4083                     /* Update the retransmission information. */
4084                     if (_nx_dhcpv6_update_retransmit_info(dhcpv6_ptr))
4085                     {
4086 
4087                         /* Clear the assigned IP address.  */
4088                         _nx_dhcpv6_remove_assigned_address(dhcpv6_ptr, NX_DHCPV6_REMOVE_ALL_IA_ADDRESS);
4089 
4090                         /* The retry limit on Renew messages is exceeded. Set the Client back to
4091                         the INIT state and stop sending Renew messages for now. */
4092                         dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_INIT;
4093 
4094                         /* Renew attempt failed. The state change callback if set will be called. */
4095                     }
4096                 }
4097             }
4098             else
4099             {
4100 
4101                 /* The Server responded to and accepted our RENEW request. Update the Client to a bound
4102                    state and reset the lease timers.  */
4103 
4104                 /* Indicate the Client is bound to an assigned IPv6 address. */
4105                 dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_BOUND_TO_ADDRESS;
4106 
4107                 /* Reset the time keeper! */
4108                 dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_time_accrued = 0;
4109 
4110                 /* The next sending packet is the new packet, so reset the message id.  */
4111                 dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid = 0;
4112 
4113                 /* Receive the correct response, so deactivate the session timer of elapsed time. */
4114                 tx_timer_deactivate(&(dhcpv6_ptr -> nx_dhcpv6_session_timer));
4115 
4116                 /* Yes, get the IPv6 address by DHCPv6. set it.  */
4117                 status = _nx_dhcpv6_register_IP_address(dhcpv6_ptr);
4118 
4119                 /* Increment the number of renew responses received.  */
4120                 dhcpv6_ptr -> nx_dhcpv6_renew_responses++;
4121             }
4122 
4123             break;
4124         }
4125 
4126         /* The caller has requested to send a rebind request message. */
4127         case NX_DHCPV6_STATE_SENDING_REBIND:
4128         {
4129 
4130             dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type =  NX_DHCPV6_MESSAGE_TYPE_REBIND;
4131 
4132             /* Increase the count of retries. */
4133             dhcpv6_ptr -> nx_dhcpv6_rebinds_sent++;
4134 
4135             /* Send the DHCPV6 Rebind message.  */
4136             status = _nx_dhcpv6_send_request(dhcpv6_ptr);
4137 
4138             /* Check for socket send error. */
4139             if (status != NX_SUCCESS)
4140             {
4141 
4142                 /* Return. Can't do any more now. */
4143                 return;
4144             }
4145 
4146             /* Make sure the server DUID is cleared. Client should be accepting any server reply. */
4147             memset(&(dhcpv6_ptr -> nx_dhcpv6_server_duid), 0, sizeof(NX_DHCPV6_DUID));
4148 
4149             /* Send the message to the server. */
4150             status = _nx_dhcpv6_waiting_on_reply(dhcpv6_ptr);
4151 
4152             /* Check for socket receive error or Server error code. */
4153             if ((status != NX_SUCCESS) ||
4154                 (dhcpv6_ptr -> nx_status_code != NX_DHCPV6_SUCCESS) ||
4155                 ((dhcpv6_ptr -> nx_dhcpv6_reply_option_flags & NX_DHCPV6_INCLUDE_IA_ADDRESS_OPTION) == 0))
4156             {
4157 
4158                 /* Process the NoBinding status.  */
4159                 if ((status == NX_SUCCESS) && (dhcpv6_ptr -> nx_status_code == NX_DHCPV6_NO_BINDING))
4160                 {
4161 
4162                     /* When the client receives a Reply message in response to a Renew or Rebind message,
4163                        send a Request message if the IA contains a Status Code option with the NoBinding status.
4164                        RFC 3315, Section 18.1.8, Page 48.  */
4165                     dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_SENDING_REQUEST;
4166 
4167                     /* Reset the retransmission timeout and retry. */
4168                     dhcpv6_ptr -> nx_dhcpv6_transmission_timeout =  NX_DHCPV6_INIT_REQ_TRANSMISSION_TIMEOUT;
4169                     dhcpv6_ptr -> nx_dhcpv6_retransmission_count = 0;
4170 
4171                     /* Set the initaial elasped time of DHCPv6 message.  */
4172                     dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = 0;
4173 
4174                     /* Set the retransmission information(IRT, MRC, MRT, MRD). */
4175                     dhcpv6_ptr -> nx_dhcpv6_init_retransmission_timeout = NX_DHCPV6_INIT_REQ_TRANSMISSION_TIMEOUT;
4176                     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_count = NX_DHCPV6_MAX_REQ_RETRANSMISSION_COUNT;
4177                     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_timeout = NX_DHCPV6_MAX_REQ_RETRANSMISSION_TIMEOUT;
4178                     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_duration = NX_DHCPV6_MAX_REQ_RETRANSMISSION_DURATION;
4179 
4180                     /* The next sending packet is the new packet, so reset the message id.  */
4181                     dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid = 0;
4182                 }
4183                 else
4184                 {
4185 
4186                     /* Update the retransmission information. */
4187                     if (_nx_dhcpv6_update_retransmit_info(dhcpv6_ptr))
4188                     {
4189 
4190                         /* Clear the assigned IP address.  */
4191                         _nx_dhcpv6_remove_assigned_address(dhcpv6_ptr, NX_DHCPV6_REMOVE_ALL_IA_ADDRESS);
4192 
4193                         /* The retry limit on Rebind messages is exceeded. Set the Client back to
4194                         the INIT state and stop sending Rebind messages for now. */
4195                         dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_INIT;
4196 
4197                         /* Rebind attempt failed. The client state change callback if set will be called. */
4198                     }
4199                 }
4200             }
4201             else
4202             {
4203 
4204                 /* Make sure the Client state is set to Bound to an assigned IPv6 address. */
4205                 dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_BOUND_TO_ADDRESS;
4206 
4207                 /* Reset the time keeper! */
4208                 dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_time_accrued = 0;
4209 
4210                 /* The next sending packet is the new packet, so reset the message id.  */
4211                 dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid = 0;
4212 
4213                 /* Yes, get the IPv6 address by DHCPv6. set it.  */
4214                 status = _nx_dhcpv6_register_IP_address(dhcpv6_ptr);
4215 
4216                 /* Increment the number of rebind responses received.  */
4217                 dhcpv6_ptr -> nx_dhcpv6_rebind_responses++;
4218 
4219                 /* Receive the correct response, so deactivate the session timer of elapsed time. */
4220                 tx_timer_deactivate(&(dhcpv6_ptr -> nx_dhcpv6_session_timer));
4221             }
4222 
4223             break;
4224         }
4225 
4226         case NX_DHCPV6_STATE_SENDING_CONFIRM:
4227         {
4228 
4229             /* Set the message type.  */
4230             dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type =  NX_DHCPV6_MESSAGE_TYPE_CONFIRM;
4231 
4232             /* Increase the count of retries. */
4233             dhcpv6_ptr -> nx_dhcpv6_confirms_sent++;
4234 
4235             /* Send the DHCPV6 Confirm message.  */
4236             status = _nx_dhcpv6_send_request(dhcpv6_ptr);
4237 
4238             /* Send the message until we get a reply from the server. */
4239             status = _nx_dhcpv6_waiting_on_reply(dhcpv6_ptr);
4240 
4241             /* Check for socket receive error or Server error code. */
4242             if ((status != NX_SUCCESS) || (dhcpv6_ptr -> nx_status_code != NX_DHCPV6_SUCCESS))
4243             {
4244 
4245                 if ((status == NX_SUCCESS) && (dhcpv6_ptr -> nx_status_code == NX_DHCPV6_NOT_ON_LINK))
4246                 {
4247 
4248                     /* Indicate the DHCP Client process is idle. */
4249                     dhcpv6_ptr -> nx_dhcpv6_sleep_flag =  NX_TRUE;
4250 
4251                     /* The next sending packet is the new packet, so reset the message id.  */
4252                     dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid = 0;
4253 
4254                     /* Clear the assigned IP address.  */
4255                     _nx_dhcpv6_remove_assigned_address(dhcpv6_ptr,NX_DHCPV6_REMOVE_ALL_IA_ADDRESS);
4256 
4257                     /* When the client receives a NotOnLink status from the server in response to a Confirm messag,
4258                        the client performs DHCP server solicitation. RFC3315, Section18.1.8, Page48.  */
4259                     _nx_dhcpv6_request_solicit(dhcpv6_ptr);
4260                 }
4261 
4262                 /* Retransmit the Confirm message.  */
4263                 else
4264                 {
4265 
4266                     /* Update the retransmission information. */
4267                     if (_nx_dhcpv6_update_retransmit_info(dhcpv6_ptr))
4268                     {
4269 
4270                         /* The retry limit on Confirm messages is exceeded. Set the Client back to
4271                         the INIT state and stop sending rebind messages for now. */
4272                         dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_INIT;
4273 
4274                         /* Confirm request failed. The state change callback if set will be called. */
4275                     }
4276                 }
4277             }
4278             else
4279             {
4280 
4281                 /* Successful confirmation. Set the assigned address status to valid (confirmed). */
4282 
4283                 /* Yes, get the IPv6 address by DHCPv6. set it.  */
4284                 status = _nx_dhcpv6_register_IP_address(dhcpv6_ptr);
4285 
4286                 /* Increment the number of responses to confirm.  */
4287                 dhcpv6_ptr -> nx_dhcpv6_confirm_responses++;
4288 
4289                 /* Restore the Client state depending on its IANA address status. */
4290                 dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_BOUND_TO_ADDRESS;
4291 
4292                 /* The next sending packet is the new packet, so reset the message id.  */
4293                 dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid = 0;
4294 
4295                 /* Receive the correct response, so deactivate the session timer of elapsed time. */
4296                 tx_timer_deactivate(&(dhcpv6_ptr -> nx_dhcpv6_session_timer));
4297             }
4298 
4299             break;
4300 
4301         }
4302 
4303         case NX_DHCPV6_STATE_SENDING_RELEASE:
4304         {
4305 
4306             dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type =  NX_DHCPV6_MESSAGE_TYPE_RELEASE;
4307 
4308             /* Increase the count of releases. */
4309             dhcpv6_ptr -> nx_dhcpv6_releases_sent++;
4310 
4311             /* Send the DHCPV6 Release message.  */
4312             status = _nx_dhcpv6_send_request(dhcpv6_ptr);
4313 
4314             /* Check for socket error. */
4315             if (status != NX_SUCCESS)
4316             {
4317 
4318                 /* Return. Can't do any more now. */
4319                 return;
4320             }
4321 
4322             /* Send the message to the server. */
4323             status = _nx_dhcpv6_waiting_on_reply(dhcpv6_ptr);
4324 
4325             /* Check for socket receive error.  For the release message, consider the release
4326                request completed if the server responds, regardless of Server error code. RFC 3315 Section 18.1.8 */
4327             if (status != NX_SUCCESS)
4328             {
4329 
4330                 /* Update the retransmission information. */
4331                 if (_nx_dhcpv6_update_retransmit_info(dhcpv6_ptr))
4332                 {
4333 
4334                     /* Clear global ip address and lifetime parameters from the Client record. */
4335                     _nx_dhcpv6_remove_assigned_address(dhcpv6_ptr, NX_DHCPV6_REMOVE_ALL_IA_ADDRESS);
4336 
4337                     /* The retry limit on release messages is exceeded. Set the Client back to
4338                        the INIT state and stop sending rebind messages for now. */
4339                     dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_INIT;
4340 
4341                     /* No response to release message from server. The state change callback if set will be called. */
4342                 }
4343             }
4344             else
4345             {
4346                 /* Increment the number of responses to release request.  */
4347                 dhcpv6_ptr -> nx_dhcpv6_release_responses++;
4348 
4349                 /* The next sending packet is the new packet, so reset the message id.  */
4350                 dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid = 0;
4351 
4352                 /* Receive the correct response, so deactivate the session timer of elapsed time. */
4353                 tx_timer_deactivate(&(dhcpv6_ptr -> nx_dhcpv6_session_timer));
4354 
4355                 /* Clear global ip address and lifetime parameters from the Client record. */
4356                 _nx_dhcpv6_remove_assigned_address(dhcpv6_ptr, NX_DHCPV6_REMOVE_ALL_IA_ADDRESS);
4357 
4358                 /* Update the Client state to not bound. */
4359                 dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_INIT;
4360             }
4361 
4362             break;
4363         }
4364 
4365         case NX_DHCPV6_STATE_SENDING_DECLINE:
4366         {
4367 
4368             dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type =  NX_DHCPV6_MESSAGE_TYPE_DECLINE;
4369 
4370             /* Increase the count of declines. */
4371             dhcpv6_ptr -> nx_dhcpv6_declines_sent++;
4372 
4373             /* Send the DHCPV6 Decline message.  */
4374             status = _nx_dhcpv6_send_request(dhcpv6_ptr);
4375 
4376             /* Check for interal error. */
4377             if (status != NX_SUCCESS)
4378             {
4379 
4380                 /* Return. Can't do any more now. */
4381                 return;
4382             }
4383 
4384             /* Send the message to the server. */
4385             status = _nx_dhcpv6_waiting_on_reply(dhcpv6_ptr);
4386 
4387             /* Check for socket receive error.  For the decline message, consider the release
4388                request completed if the server responds, regardless of Server error code. RFC3315,Section 18.1.7 */
4389             if (status != NX_SUCCESS)
4390             {
4391 
4392                 /* Update the retransmission information. */
4393                 if (_nx_dhcpv6_update_retransmit_info(dhcpv6_ptr))
4394                 {
4395 
4396                     /* Clear global ip address and lifetime parameters from the Client record. */
4397                     _nx_dhcpv6_remove_assigned_address(dhcpv6_ptr, NX_DHCPV6_REMOVE_ALL_IA_ADDRESS);
4398 
4399                     /* The retry limit on decline messages is exceeded. Set the Client back to
4400                        the INIT state and stop sending rebind messages for now. */
4401                     dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_INIT;
4402 
4403                     /* No response to decline message from server. The state change callback if set will be called. */
4404                 }
4405             }
4406             else
4407             {
4408 
4409                 /* Increment the number of server responses to Decline request.  */
4410                 dhcpv6_ptr -> nx_dhcpv6_decline_responses++;
4411 
4412                 /* The next sending packet is the new packet, so reset the message id.  */
4413                 dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid = 0;
4414 
4415                 /* Receive the correct response, so deactivate the session timer of elapsed time. */
4416                 tx_timer_deactivate(&(dhcpv6_ptr -> nx_dhcpv6_session_timer));
4417 
4418                 /* Clear global ip address and lifetime parameters from the Client record. */
4419                 status = _nx_dhcpv6_remove_assigned_address(dhcpv6_ptr, NX_DHCPV6_REMOVE_ALL_IA_ADDRESS);
4420 
4421                 /* Change the DHCPv6 Client to the unbound state. */
4422                 dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_INIT;
4423             }
4424 
4425             break;
4426         }
4427 
4428         case NX_DHCPV6_STATE_SENDING_INFORM_REQUEST:
4429         {
4430 
4431             dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type =  NX_DHCPV6_MESSAGE_TYPE_INFORM_REQUEST;
4432 
4433             /* Increase the count of declines. */
4434             dhcpv6_ptr -> nx_dhcpv6_inform_req_sent++;
4435 
4436             /* Send the Inform Request message.  */
4437             status = _nx_dhcpv6_send_request(dhcpv6_ptr);
4438 
4439             /* Check for transmission error. */
4440             if (status != NX_SUCCESS)
4441             {
4442 
4443                 /* Return. Nothing more to do. */
4444                 return;
4445             }
4446 
4447             /* Wait for a reply from the server. This will also extract the
4448                server packet information and update the DHCPv6 Client state. */
4449             status = _nx_dhcpv6_waiting_on_reply(dhcpv6_ptr);
4450 
4451             /* Check for socket receive error or Server error code. */
4452             if ((status != NX_SUCCESS) || (dhcpv6_ptr -> nx_status_code != NX_DHCPV6_SUCCESS))
4453             {
4454 
4455                 /* Update the retransmission information. */
4456                 if (_nx_dhcpv6_update_retransmit_info(dhcpv6_ptr))
4457                 {
4458 
4459                     /* The retry limit on decline messages is exceeded. Set the Client back to
4460                        the INIT state and stop sending rebind messages for now. */
4461                     dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_INIT;
4462                 }
4463             }
4464             else
4465             {
4466                 /* Increment the number of responses to Inform Request received.  */
4467                 dhcpv6_ptr -> nx_dhcpv6_inform_req_responses++;
4468 
4469                 /* The next sending packet is the new packet, so reset the message id.  */
4470                 dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid = 0;
4471 
4472                 /* Receive the correct response, so deactivate the session timer of elapsed time. */
4473                 tx_timer_deactivate(&(dhcpv6_ptr -> nx_dhcpv6_session_timer));
4474 
4475                 /* Restore the Client state depending on its IANA address status. */
4476                 if (dhcpv6_ptr -> nx_dhcpv6_ia[0].nx_address_status == NX_DHCPV6_IA_ADDRESS_STATE_VALID)
4477                 {
4478                     dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_BOUND_TO_ADDRESS;
4479                 }
4480                 else
4481                 {
4482                     dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_INIT;
4483                 }
4484             }
4485 
4486             break;
4487         }
4488 
4489         default:
4490         {
4491 
4492             /* Unknown or unsupported DHCPv6 request (state). */
4493             return;
4494         }
4495     }
4496 
4497     /* Is there a state change callback registered with the Client?  */
4498     if ((dhcpv6_ptr -> nx_dhcpv6_state_change_callback) && (original_state != (dhcpv6_ptr -> nx_dhcpv6_state)))
4499     {
4500 
4501         /* Yes, call the the state change callback with the original and new state.  */
4502         (dhcpv6_ptr -> nx_dhcpv6_state_change_callback)(dhcpv6_ptr, original_state, dhcpv6_ptr -> nx_dhcpv6_state);
4503     }
4504 
4505     return;
4506 }
4507 
4508 
4509 /**************************************************************************/
4510 /*                                                                        */
4511 /*  FUNCTION                                               RELEASE        */
4512 /*                                                                        */
4513 /*    _nx_dhcpv6_process_client_duid                      PORTABLE C      */
4514 /*                                                           6.1          */
4515 /*  AUTHOR                                                                */
4516 /*                                                                        */
4517 /*    Yuxin Zhou, Microsoft Corporation                                   */
4518 /*                                                                        */
4519 /*  DESCRIPTION                                                           */
4520 /*                                                                        */
4521 /*    This function extracts the client DUID from the server reply and    */
4522 /*    verifies that it matches the Client DUID on record.                 */
4523 /*                                                                        */
4524 /*  INPUT                                                                 */
4525 /*                                                                        */
4526 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
4527 /*    option_data                       Pointer to option data            */
4528 /*    option_length                     Size of option data               */
4529 /*                                                                        */
4530 /*  OUTPUT                                                                */
4531 /*                                                                        */
4532 /*    NX_SUCCESS                        Successful completion status      */
4533 /*    NX_DHCPV6_INVALID_CLIENT_DUID     Client DUID is missing data or    */
4534 /*                                       does not match the DUID on record*/
4535 /*  CALLS                                                                 */
4536 /*                                                                        */
4537 /*    _nx_dhcpv6_utility_get_data       Parses data from specified buffer */
4538 /*                                                                        */
4539 /*  CALLED BY                                                             */
4540 /*                                                                        */
4541 /*    _nx_dhcpv6_extract_packet_information                               */
4542 /*                                      Extracts server reply from packet */
4543 /*                                                                        */
4544 /*  RELEASE HISTORY                                                       */
4545 /*                                                                        */
4546 /*    DATE              NAME                      DESCRIPTION             */
4547 /*                                                                        */
4548 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4549 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
4550 /*                                            packet length verification, */
4551 /*                                            resulting in version 6.1    */
4552 /*                                                                        */
4553 /**************************************************************************/
_nx_dhcpv6_process_client_duid(NX_DHCPV6 * dhcpv6_ptr,UCHAR * option_data,UINT option_length)4554 UINT _nx_dhcpv6_process_client_duid(NX_DHCPV6 *dhcpv6_ptr, UCHAR *option_data, UINT option_length)
4555 {
4556 
4557 ULONG   data;
4558 UINT    index = 0;
4559 
4560 
4561     /* The Client should already have its own DUID on record. So just parse the
4562        data and compare each DUID field with the Client's DUID. */
4563 
4564     /* Check option length for DUID type and hardware type.  */
4565     if (option_length < 4)
4566     {
4567         return(NX_DHCPV6_INVALID_CLIENT_DUID);
4568     }
4569 
4570     /* Extract the DUID type which should be the next 2 bytes.  */
4571     _nx_dhcpv6_utility_get_data((option_data + index), 2, &data);
4572 
4573     /* Does this match the Client DUID type on record? */
4574     if (data != (dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_duid_type))
4575     {
4576 
4577         /* No, return the error status to reject this packet. */
4578         return NX_DHCPV6_INVALID_CLIENT_DUID;
4579     }
4580 
4581     index += 2;
4582 
4583     /* Extract the hardware type which should be the next 2 bytes.  */
4584     _nx_dhcpv6_utility_get_data((option_data + index), 2, &data);
4585 
4586     /* Does this match the Client DUID hardware type on record? */
4587     if (data != (dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_hardware_type))
4588     {
4589 
4590         /* No, return the error status to reject this packet. */
4591         return NX_DHCPV6_INVALID_CLIENT_DUID;
4592     }
4593 
4594     index += 2;
4595 
4596     /* IS this a link layer plus time DUID type? */
4597     if ((dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_duid_type) == NX_DHCPV6_DUID_TYPE_LINK_TIME)
4598     {
4599 
4600         /* Check option length for time.  */
4601         if (index + 4 > option_length)
4602         {
4603             return(NX_DHCPV6_INVALID_CLIENT_DUID);
4604         }
4605 
4606         /* Yes; Extract the time which should be the next 4 bytes.  */
4607         _nx_dhcpv6_utility_get_data((option_data + index), 4, &data);
4608 
4609         /* Does this match the Client DUID time on record? */
4610         if (data != (dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_duid_time))
4611         {
4612 
4613             /* No, return the error status to reject this packet. */
4614             return NX_DHCPV6_INVALID_CLIENT_DUID;
4615         }
4616 
4617         index += 4;
4618     }
4619 
4620     /* Check the hardware type to extract the MSW.  */
4621     if (dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_hardware_type == NX_DHCPV6_CLIENT_HARDWARE_TYPE_ETHERNET)
4622     {
4623 
4624         /* The length of link layer address is 48 bits.  */
4625 
4626         /* Check option length for 48 bits mac address.  */
4627         if (index + 6 > option_length)
4628         {
4629             return(NX_DHCPV6_INVALID_CLIENT_DUID);
4630         }
4631 
4632         /* Yes; Extract the link local address msw which should be the next 2 bytes.  */
4633         _nx_dhcpv6_utility_get_data((option_data + index), 2, &data);
4634         index += 2;
4635     }
4636     else if (dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_hardware_type == NX_DHCPV6_CLIENT_HARDWARE_TYPE_EUI_64)
4637     {
4638 
4639         /* The length of link layer address is 64 bits.  */
4640 
4641         /* Check option length for 64 bits mac address.  */
4642         if (index + 8 > option_length)
4643         {
4644             return(NX_DHCPV6_INVALID_CLIENT_DUID);
4645         }
4646 
4647         /* Yes; Extract the link local address msw which should be the next 4 bytes.  */
4648         _nx_dhcpv6_utility_get_data((option_data + index), 4, &data);
4649         index += 4;
4650     }
4651 
4652     /* Does this match the Client DUID link layer most significant bytes on record? */
4653     if (data != (dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_link_layer_address_msw))
4654     {
4655 
4656         /* No, return the error status to reject this packet. */
4657         return NX_DHCPV6_INVALID_CLIENT_DUID;
4658     }
4659 
4660     /* Yes; Extract the link local address lsw which should be the next 4 bytes.  */
4661     _nx_dhcpv6_utility_get_data((option_data + index), 4, &data);
4662     index += 4;
4663 
4664     /* Does this match the Client DUID link layer least significant bytes on record? */
4665     if (data != ((dhcpv6_ptr -> nx_dhcpv6_client_duid).nx_link_layer_address_lsw))
4666     {
4667 
4668         /* No, return the error status to reject this packet. */
4669         return NX_DHCPV6_INVALID_CLIENT_DUID;
4670     }
4671 
4672     /* Are we past the end of the buffer.  */
4673     if (index != option_length)
4674     {
4675 
4676         /* Yes, return the error status to reject this packet. */
4677         return NX_DHCPV6_INVALID_CLIENT_DUID;
4678     }
4679 
4680     return NX_SUCCESS;
4681 }
4682 
4683 
4684 /**************************************************************************/
4685 /*                                                                        */
4686 /*  FUNCTION                                               RELEASE        */
4687 /*                                                                        */
4688 /*    _nx_dhcpv6_process_domain_name                      PORTABLE C      */
4689 /*                                                           6.1          */
4690 /*  AUTHOR                                                                */
4691 /*                                                                        */
4692 /*    Yuxin Zhou, Microsoft Corporation                                   */
4693 /*                                                                        */
4694 /*  DESCRIPTION                                                           */
4695 /*                                                                        */
4696 /*    This function extracts the domain name option from the server reply.*/
4697 /*    It will save as much of the domain name that will fit in the Client */
4698 /*    domain name buffer. Buffer size is user configurable.               */
4699 /*                                                                        */
4700 /*  INPUT                                                                 */
4701 /*                                                                        */
4702 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
4703 /*    packet_start                      Pointer to packet buffer          */
4704 /*    option_data                       Pointer to option data            */
4705 /*    option_length                     Size of option data               */
4706 /*                                                                        */
4707 /*  OUTPUT                                                                */
4708 /*                                                                        */
4709 /*    NX_SUCCESS                        Successful completion status      */
4710 /*                                                                        */
4711 /*  CALLS                                                                 */
4712 /*                                                                        */
4713 /*    _nx_dhcpv6_name_string_unencode   Decode the name string            */
4714 /*                                                                        */
4715 /*  CALLED BY                                                             */
4716 /*                                                                        */
4717 /*    _nx_dhcpv6_extract_packet_information                               */
4718 /*                                      Extracts DHCPv6 options from      */
4719 /*                                             server reply               */
4720 /*                                                                        */
4721 /*  RELEASE HISTORY                                                       */
4722 /*                                                                        */
4723 /*    DATE              NAME                      DESCRIPTION             */
4724 /*                                                                        */
4725 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4726 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
4727 /*                                            packet length verification, */
4728 /*                                            resulting in version 6.1    */
4729 /*                                                                        */
4730 /**************************************************************************/
_nx_dhcpv6_process_domain_name(NX_DHCPV6 * dhcpv6_ptr,UCHAR * packet_start,UCHAR * option_data,UINT option_length)4731 UINT _nx_dhcpv6_process_domain_name(NX_DHCPV6 *dhcpv6_ptr, UCHAR *packet_start, UCHAR *option_data, UINT option_length)
4732 {
4733 
4734 UINT        domain_name_length;
4735 UINT        temp_length;
4736 UCHAR       *domain_name_ptr;
4737 UCHAR       *buffer_prepend_ptr;
4738 UINT        buffer_size;
4739 UINT        i;
4740 
4741 
4742     /* Initialize the value.  */
4743     domain_name_length = 0;
4744     temp_length = 0;
4745     domain_name_ptr = option_data;
4746     buffer_prepend_ptr = &dhcpv6_ptr -> nx_dhcpv6_domain_name[0];
4747     buffer_size = NX_DHCPV6_DOMAIN_NAME_BUFFER_SIZE;
4748 
4749     /* Process the domain search list options.  */
4750     while(temp_length < option_length)
4751     {
4752 
4753         /* Calculate the domain name length in the Domaim Search List option,include the null flag '\0'.  */
4754         for (i = 0; (i + temp_length < option_length) && (domain_name_ptr[i] != '\0'); i++);
4755 
4756         if (i + temp_length == option_length)
4757         {
4758             return(NX_DHCPV6_PROCESSING_ERROR);
4759         }
4760         else
4761         {
4762             temp_length += (i + 1);
4763         }
4764 
4765         /* Check buffer size.  */
4766         if (buffer_size < 1)
4767         {
4768             return(NX_DHCPV6_PROCESSING_ERROR);
4769         }
4770 
4771         /* Record the real domain name and return the length, one less for NULL termination. */
4772         domain_name_length = _nx_dhcpv6_name_string_unencode(packet_start, (UINT)(domain_name_ptr - packet_start), buffer_prepend_ptr, (UINT)((buffer_size - 1) & 0xFFFFFFFF));
4773 
4774         /* Check the domain name length.  */
4775         if(!domain_name_length)
4776         {
4777 
4778             /* Process error, return.  */
4779             return NX_DHCPV6_PROCESSING_ERROR;
4780         }
4781 
4782         else
4783         {
4784 
4785             /* Update the buffer value,include the null flag '\0'.  */
4786             domain_name_ptr += temp_length;
4787             buffer_prepend_ptr += (domain_name_length + 1);
4788             buffer_size -= (domain_name_length + 1);
4789         }
4790     }
4791 
4792     /* Return successful completion. */
4793     return NX_SUCCESS;
4794 }
4795 
4796 
4797 
4798 /**************************************************************************/
4799 /*                                                                        */
4800 /*  FUNCTION                                               RELEASE        */
4801 /*                                                                        */
4802 /*    _nx_dhcpv6_name_string_encode                       PORTABLE C      */
4803 /*                                                           6.1          */
4804 /*  AUTHOR                                                                */
4805 /*                                                                        */
4806 /*    Yuxin Zhou, Microsoft Corporation                                   */
4807 /*                                                                        */
4808 /*  DESCRIPTION                                                           */
4809 /*                                                                        */
4810 /*    This function converts a string containing the name as a list of    */
4811 /*    labels separated by dots to the encoded list of labels specified    */
4812 /*    in RFC1035 for DNS servers. This conversion doesn't handle          */
4813 /*    compression and doesn't check on the lengths of the labels or the   */
4814 /*    entire name.                                                        */
4815 /*                                                                        */
4816 /*  INPUT                                                                 */
4817 /*                                                                        */
4818 /*    ptr                                   Pointer to destination        */
4819 /*    name                                  Source name string            */
4820 /*                                                                        */
4821 /*  OUTPUT                                                                */
4822 /*                                                                        */
4823 /*    count                                 Count of characters encoded   */
4824 /*                                                                        */
4825 /*  CALLS                                                                 */
4826 /*                                                                        */
4827 /*    None                                                                */
4828 /*                                                                        */
4829 /*  CALLED BY                                                             */
4830 /*                                                                        */
4831 /*    _nx_dhcpv6_add_client_FQDN         Add FQDN Option to DHCPv6 packet */
4832 /*                                                                        */
4833 /*  RELEASE HISTORY                                                       */
4834 /*                                                                        */
4835 /*    DATE              NAME                      DESCRIPTION             */
4836 /*                                                                        */
4837 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4838 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4839 /*                                            resulting in version 6.1    */
4840 /*                                                                        */
4841 /**************************************************************************/
_nx_dhcpv6_name_string_encode(UCHAR * ptr,UCHAR * name)4842 UINT  _nx_dhcpv6_name_string_encode(UCHAR *ptr, UCHAR *name)
4843 {
4844 
4845 UCHAR   *length;
4846 UINT    count =  1;
4847 
4848 
4849     /* Point to the first character position in the buffer.  This will point
4850        to the length of the following name.  */
4851     length =  ptr++;
4852 
4853     /* Default the length to zero.  */
4854     *length =  0;
4855 
4856     /* Move through string, copying bytes and updating length.
4857        Whenever a "." is found, start a new string by updating the
4858        pointer to the length and setting the length to zero.  */
4859     while (*name)
4860     {
4861 
4862         /* Is a dot been found?  */
4863         if (*name == '.')
4864         {
4865 
4866             /* Yes, setup a new length pointer. */
4867             length =  ptr++;
4868 
4869             /* Default the length to zero. */
4870             *length =  0;
4871             name++;
4872         }
4873         else
4874         {
4875 
4876             /* Copy a character to the destination.  */
4877             *ptr++ =  *name++;
4878 
4879             /* Adjust the length of the current segment.  */
4880             (*length)++;
4881         }
4882 
4883         /* Increment the total count here.  */
4884         count++;
4885     }
4886 
4887     /* Add the final zero length, like a NULL terminator.  */
4888     *ptr =  0;
4889 
4890     /* Increment the total count.  */
4891     count++;
4892 
4893     /* Return the count.  */
4894     return(count);
4895 }
4896 
4897 
4898 /**************************************************************************/
4899 /*                                                                        */
4900 /*  FUNCTION                                               RELEASE        */
4901 /*                                                                        */
4902 /*    _nx_dhcpv6_name_string_unencode                     PORTABLE C      */
4903 /*                                                           6.1.2        */
4904 /*  AUTHOR                                                                */
4905 /*                                                                        */
4906 /*    Yuxin Zhou, Microsoft Corporation                                   */
4907 /*                                                                        */
4908 /*  DESCRIPTION                                                           */
4909 /*                                                                        */
4910 /*    This function converts from the encoded list of labels as specified */
4911 /*    in RFC 1035 to a string containing the name as a list of labels     */
4912 /*    separated by dots.                                                  */
4913 /*                                                                        */
4914 /*  INPUT                                                                 */
4915 /*                                                                        */
4916 /*    data                                  Pointer to buffer to decode   */
4917 /*    start                                 Location of start of data     */
4918 /*    buffer                                Pointer to decoded data       */
4919 /*    size                                  Size of data buffer to decode */
4920 /*                                                                        */
4921 /*  OUTPUT                                                                */
4922 /*                                                                        */
4923 /*    Size of decoded data                                                */
4924 /*                                                                        */
4925 /*  CALLS                                                                 */
4926 /*                                                                        */
4927 /*    None                                                                */
4928 /*                                                                        */
4929 /*  CALLED BY                                                             */
4930 /*                                                                        */
4931 /*    _nx_dhcpv6_process_domain_name        Process the domain name       */
4932 /*                                                                        */
4933 /*  RELEASE HISTORY                                                       */
4934 /*                                                                        */
4935 /*    DATE              NAME                      DESCRIPTION             */
4936 /*                                                                        */
4937 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4938 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4939 /*                                            resulting in version 6.1    */
4940 /*  11-09-2020     Yuxin Zhou               Modified comment(s), fixed    */
4941 /*                                            domain name labelSize issue,*/
4942 /*                                            resulting in version 6.1.2  */
4943 /*                                                                        */
4944 /**************************************************************************/
_nx_dhcpv6_name_string_unencode(UCHAR * data,UINT start,UCHAR * buffer,UINT size)4945 UINT _nx_dhcpv6_name_string_unencode(UCHAR *data, UINT start, UCHAR *buffer, UINT size)
4946 {
4947 
4948 UCHAR   *character =  data + start;
4949 UINT    length = 0;
4950 
4951 
4952     /* As long as there is space in the buffer and we haven't
4953        found a zero terminating label */
4954     while ((size > length) && (*character != '\0'))
4955     {
4956 
4957     UINT  labelSize =  *character++;
4958 
4959         /* Check labelSize.  */
4960         if (labelSize <= NX_DHCPV6_LABEL_MAX)
4961         {
4962 
4963             /* Simple count, check for space and copy the label.  */
4964             while ((size > length) && (labelSize > 0))
4965             {
4966 
4967                 *buffer++ =  *character++;
4968                 length++;
4969                 labelSize--;
4970             }
4971 
4972             /* Now add the '.' */
4973             *buffer++ =  '.';
4974             length++;
4975         }
4976         else
4977         {
4978             /* Not defined or in compressed form. Based on section 8 of RFC 3315,
4979                 a domain name, or list of domain names, in DHCP MUST NOT be stored
4980                 in compressed form, so just fail */
4981             return(0);
4982         }
4983     }
4984 
4985     /* Validate the length.  */
4986     if (length == 0)
4987     {
4988         return(length);
4989     }
4990 
4991     /* Done copying the data, set the last . to a trailing null */
4992     if (*(buffer - 1) == '.')
4993     {
4994 
4995         buffer--;
4996         length --;
4997     }
4998 
4999     /* Null terminate name.  */
5000     *buffer =  '\0';
5001 
5002     /* Return name size.  */
5003     return(length);
5004 }
5005 
5006 
5007 /**************************************************************************/
5008 /*                                                                        */
5009 /*  FUNCTION                                               RELEASE        */
5010 /*                                                                        */
5011 /*    _nx_dhcpv6_process_DNS_server                       PORTABLE C      */
5012 /*                                                           6.1          */
5013 /*  AUTHOR                                                                */
5014 /*                                                                        */
5015 /*    Yuxin Zhou, Microsoft Corporation                                   */
5016 /*                                                                        */
5017 /*  DESCRIPTION                                                           */
5018 /*                                                                        */
5019 /*    This function extracts the DNS server option from the server reply. */
5020 /*    It will save as many DNS name server addresses as are in the reply  */
5021 /*    for which the Client is configured to save.                         */
5022 /*                                                                        */
5023 /*  INPUT                                                                 */
5024 /*                                                                        */
5025 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
5026 /*    option_data                       Pointer to option data            */
5027 /*    option_length                     Size of option data               */
5028 /*                                                                        */
5029 /*  OUTPUT                                                                */
5030 /*                                                                        */
5031 /*    NX_SUCCESS                        Successful completion status      */
5032 /*    NX_DHCPV6_INVALID_OPTION_DATA     DNS server option missing data or */
5033 /*                                            improperly formatted        */
5034 /*                                                                        */
5035 /*  CALLS                                                                 */
5036 /*                                                                        */
5037 /*    memcpy                            Copies specified area of memory   */
5038 /*                                                                        */
5039 /*  CALLED BY                                                             */
5040 /*                                                                        */
5041 /*    _nx_dhcpv6_extract_packet_information                               */
5042 /*                                      Extracts DHCPv6 options from      */
5043 /*                                             server reply               */
5044 /*                                                                        */
5045 /*  RELEASE HISTORY                                                       */
5046 /*                                                                        */
5047 /*    DATE              NAME                      DESCRIPTION             */
5048 /*                                                                        */
5049 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5050 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
5051 /*                                            packet length verification, */
5052 /*                                            verified memcpy use cases,  */
5053 /*                                            resulting in version 6.1    */
5054 /*                                                                        */
5055 /**************************************************************************/
_nx_dhcpv6_process_DNS_server(NX_DHCPV6 * dhcpv6_ptr,UCHAR * option_data,UINT option_length)5056 UINT _nx_dhcpv6_process_DNS_server(NX_DHCPV6 *dhcpv6_ptr, UCHAR *option_data, UINT option_length)
5057 {
5058 
5059 UINT   index = 0;
5060 UINT   w, j = 0;
5061 
5062 
5063     /* Loop through the length of the buffer to parse. */
5064     while ((index + 16) <= option_length)
5065     {
5066 
5067         /* Is the DHCPv6 Client configured to store another DNS server address? */
5068         if (j < NX_DHCPV6_NUM_DNS_SERVERS)
5069         {
5070 
5071             /* Set the IP version. */
5072             dhcpv6_ptr -> nx_dhcpv6_DNS_name_server_address[j].nxd_ip_version = NX_IP_VERSION_V6;
5073 
5074             /* Get the next IPv6 DNS server address. */
5075             for (w = 0; w <= 3; w++)
5076             {
5077 
5078                 /* Yes; copy the next word into the current DNS server address. */
5079                 memcpy(&(dhcpv6_ptr -> nx_dhcpv6_DNS_name_server_address[j].nxd_ip_address.v6[w]), /* Use case of memcpy is verified. */
5080                         (option_data + index), sizeof(ULONG));
5081 
5082                 /* Adjust for endianness. */
5083                 NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_DNS_name_server_address[j].nxd_ip_address.v6[w]);
5084 
5085                 /* Move to the next IPv6 address word. */
5086                 index += 4;
5087             }
5088 
5089             /* Get the next DNS server address in the reply buffer. */
5090             j++;
5091         }
5092         else
5093         {
5094 
5095             /* Move to the next IPv6 address. */
5096             index += 16;
5097         }
5098     }
5099 
5100     /* Is there any more data in the buffer? */
5101     if (index != option_length)
5102     {
5103 
5104         /* Yes, not sure what is going on with this packet. Treat as an error. */
5105         return NX_DHCPV6_INVALID_OPTION_DATA;
5106     }
5107 
5108     return NX_SUCCESS;
5109 }
5110 
5111 
5112 /**************************************************************************/
5113 /*                                                                        */
5114 /*  FUNCTION                                               RELEASE        */
5115 /*                                                                        */
5116 /*    _nx_dhcpv6_process_ia                               PORTABLE C      */
5117 /*                                                           6.1          */
5118 /*  AUTHOR                                                                */
5119 /*                                                                        */
5120 /*    Yuxin Zhou, Microsoft Corporation                                   */
5121 /*                                                                        */
5122 /*  DESCRIPTION                                                           */
5123 /*                                                                        */
5124 /*    This function extracts the IA address option from the server reply. */
5125 /*    It also checks that the server preferred and valid lifetimes are    */
5126 /*    legitamate. If the IANA option contains an IA option, that will also*/
5127 /*    be processed as well as any status code options.                    */
5128 /*                                                                        */
5129 /*  INPUT                                                                 */
5130 /*                                                                        */
5131 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
5132 /*    option_data                       Pointer to option data            */
5133 /*    option_length                     Size of option data               */
5134 /*    ia_index                          The index of IA address           */
5135 /*                                                                        */
5136 /*  OUTPUT                                                                */
5137 /*                                                                        */
5138 /*    NX_SUCCESS                        Successful completion status      */
5139 /*    NX_DHCPV6_INVALID_IA_DATA         IA option is missing data or      */
5140 /*                                          improperly formatted          */
5141 /*    NX_DHCPV6_INVALID_IA_TIME         IA option lifetime data is invalid*/
5142 /*    NX_DHCPV6_UNKNOWN_OPTION          Unkonw option type                */
5143 /*                                                                        */
5144 /*  CALLS                                                                 */
5145 /*                                                                        */
5146 /*    _nx_dhcpv6_utility_get_block_option_length                          */
5147 /*                                      Get the option code and length    */
5148 /*    _nx_dhcpv6_process_status         Processes STAUTS in reply buffer  */
5149 /*    nx_dhcpv6_server_error_handler    Pointer to error code handler     */
5150 /*    memcpy                            Copies specified area of memory   */
5151 /*                                                                        */
5152 /*  CALLED BY                                                             */
5153 /*                                                                        */
5154 /*    _nx_dhcpv6_process_iana           Processes IANA in reply buffer    */
5155 /*                                            DHCPv6 request              */
5156 /*                                                                        */
5157 /*  RELEASE HISTORY                                                       */
5158 /*                                                                        */
5159 /*    DATE              NAME                      DESCRIPTION             */
5160 /*                                                                        */
5161 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5162 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
5163 /*                                            packet length verification, */
5164 /*                                            verified memcpy use cases,  */
5165 /*                                            resulting in version 6.1    */
5166 /*                                                                        */
5167 /**************************************************************************/
_nx_dhcpv6_process_ia(NX_DHCPV6 * dhcpv6_ptr,UCHAR * option_data,UINT option_length,UINT ia_index)5168 UINT _nx_dhcpv6_process_ia(NX_DHCPV6 *dhcpv6_ptr, UCHAR *option_data, UINT option_length, UINT ia_index)
5169 {
5170 
5171 ULONG   preferred_lifetime;
5172 ULONG   valid_lifetime;
5173 UINT    index = 0, w;
5174 UINT    status;
5175 ULONG   ia_option_code, ia_option_length;
5176 
5177 
5178     /* Fill in the IA address code and length. Client might already have one on
5179        record, but use the server's data instead. */
5180     dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_op_code = (USHORT)NX_DHCPV6_OP_IA_ADDRESS;
5181     dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_option_length = (USHORT)option_length;
5182 
5183     /* Check option length for Ipv6 address (16 bytes), preferred-lifetime (4 bytes) and valid-lifetime (4 bytes).  */
5184     if (option_length < 24)
5185     {
5186         return(NX_DHCPV6_INVALID_IA_DATA);
5187     }
5188 
5189     /* Process IPv6 address.  */
5190     for (w = 0; w <= 3; w++)
5191     {
5192 
5193         /* Copy each IPv6 address word into the IA address. */
5194         memcpy(&(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[w]), /* Use case of memcpy is verified. */
5195                (option_data + index), sizeof(ULONG));
5196 
5197         /* Adjust for endianness. */
5198         NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[w]);
5199 
5200         /* Move to the next IPv6 address word. */
5201         index += 4;
5202     }
5203 
5204     dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_version = NX_IP_VERSION_V6;
5205 
5206     /* Copy the lifetime data from the reply buffer to temporary variables.*/
5207     memcpy(&preferred_lifetime, (option_data + index), sizeof(ULONG)); /* Use case of memcpy is verified. */
5208     index += 4;
5209 
5210     /* Adjust for endianness. */
5211     NX_CHANGE_ULONG_ENDIAN(preferred_lifetime);
5212 
5213     memcpy(&valid_lifetime, (option_data + index), sizeof(ULONG)); /* Use case of memcpy is verified. */
5214     index += 4;
5215 
5216     /* Adjust for endianness. */
5217     NX_CHANGE_ULONG_ENDIAN(valid_lifetime);
5218 
5219     /* Check for invalid lifetime data. The preferred lifetime MUST be less than
5220       the valid lifetime.  Note that a zero lifetime is acceptable
5221       (the server is letting the Client use its own preference). */
5222     if (preferred_lifetime > valid_lifetime)
5223     {
5224         /* Discard this address. We cannot use it. */
5225         return NX_DHCPV6_INVALID_IA_TIME;
5226     }
5227 
5228     /* OK to assign time data to the client. */
5229     dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_preferred_lifetime = preferred_lifetime;
5230     dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_valid_lifetime = valid_lifetime;
5231 
5232     /* Update the address status.  */
5233     if(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status == NX_DHCPV6_IA_ADDRESS_STATE_INVALID)
5234     {
5235         dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status = NX_DHCPV6_IA_ADDRESS_STATE_INITIAL;
5236     }
5237 
5238     /* Update the map status, 0xFFFFFFFF indicate the IPv6 address of IA option has been processed.  */
5239     dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_map = 0xFFFFFFFF;
5240 
5241     /* Check if we're at the end of option data yet. */
5242     if (index == option_length)
5243     {
5244 
5245         /* Yes, all done. */
5246         return NX_SUCCESS;
5247     }
5248 
5249     /* Check option length for status code option.  */
5250     if (index + 4 > option_length)
5251     {
5252         return(NX_DHCPV6_INVALID_IA_DATA);
5253     }
5254 
5255     /* Process the status code option. */
5256     status = _nx_dhcpv6_utility_get_block_option_length(option_data + index, &ia_option_code, &ia_option_length);
5257 
5258     /* Check that the block data is valid. */
5259     if (status != NX_SUCCESS)
5260     {
5261 
5262         /* No, return the error status. */
5263         return status;
5264     }
5265 
5266     /* Skip status option code and length.  */
5267     index += 4;
5268 
5269     /* This is a double check to verify we haven't gone off the end of the packet buffer. */
5270     if (index + ia_option_length > option_length)
5271     {
5272         return (NX_DHCPV6_INVALID_IA_DATA);
5273     }
5274 
5275     /* Check if this is an IAaddr status option request. */
5276     if (ia_option_code == NX_DHCPV6_OP_STATUS_CODE)
5277     {
5278         /* The IAaddr option returned by the DHCPv6 server includes a status option. */
5279 
5280         /* Process the status. */
5281         status = _nx_dhcpv6_process_status(dhcpv6_ptr, (option_data + index), ia_option_length);
5282 
5283         /* Now check on the server status of the previous option in the DHCP message. */
5284         if ((status == NX_SUCCESS) && (dhcpv6_ptr -> nx_status_code != NX_DHCPV6_SUCCESS))
5285         {
5286 
5287             /* Does the dhcpv6 client have a server error handler? */
5288             if (dhcpv6_ptr -> nx_dhcpv6_server_error_handler)
5289             {
5290 
5291                 /* Call the error handler with status code, option (IAaddr) and which message type it refers to. */
5292                 dhcpv6_ptr -> nx_dhcpv6_server_error_handler(dhcpv6_ptr, NX_DHCPV6_ERROR_STATUS_CODE_IN_IA_ADDRESS, dhcpv6_ptr -> nx_status_code,
5293                                                              dhcpv6_ptr -> nx_dhcpv6_received_message_type);
5294             }
5295         }
5296 
5297         /* Check for errors processing the DHCPv6 message. */
5298         if (status != NX_SUCCESS)
5299         {
5300 
5301             /* Abort further processing. Return error status. */
5302             return status;
5303         }
5304     }
5305 
5306     else
5307     {
5308         return NX_DHCPV6_UNKNOWN_OPTION;
5309     }
5310 
5311     /* Keep track of how far into the packet we have parsed. */
5312     index += ia_option_length;
5313 
5314     /* Check if we went past the reported size of IA address data. */
5315     if (index != option_length)
5316     {
5317 
5318         /* Return an error status. Cannot accept this reply. */
5319         return NX_DHCPV6_INVALID_IA_DATA;
5320     }
5321 
5322     return NX_SUCCESS;
5323 }
5324 
5325 
5326 /**************************************************************************/
5327 /*                                                                        */
5328 /*  FUNCTION                                               RELEASE        */
5329 /*                                                                        */
5330 /*    _nx_dhcpv6_process_iana                             PORTABLE C      */
5331 /*                                                           6.1          */
5332 /*  AUTHOR                                                                */
5333 /*                                                                        */
5334 /*    Yuxin Zhou, Microsoft Corporation                                   */
5335 /*                                                                        */
5336 /*  DESCRIPTION                                                           */
5337 /*                                                                        */
5338 /*    This function extracts the IANA option from the server reply.  It   */
5339 /*    verifies the IANA option ID matches the IANA option ID on client    */
5340 /*    record. It also checks that the server T1 and T2 lease times are    */
5341 /*    legitamate. If the IANA option contains an IA option, that will also*/
5342 /*    be processed as well as any status code options.                    */
5343 /*                                                                        */
5344 /*  INPUT                                                                 */
5345 /*                                                                        */
5346 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
5347 /*    option_data                       Pointer to option data            */
5348 /*    option_length                     Size of option data               */
5349 /*                                                                        */
5350 /*  OUTPUT                                                                */
5351 /*                                                                        */
5352 /*    status                            Actual completion status          */
5353 /*    NX_DHCPV6_BAD_IANA_ID             IANA option ID does not match IANA*/
5354 /*                                        option on client record         */
5355 /*    NX_DHCPV6_INVALID_IANA_TIME       IANA T1 and T2 values are invalid */
5356 /*    NX_DHCPV6_STATE_IP_FAILURE        Indicates server rejected IANA/IA */
5357 /*    NX_DHCPV6_INVALID_IANA_DATA       IANA option is missing data or    */
5358 /*                                       improperly formatted             */
5359 /*  CALLS                                                                 */
5360 /*                                                                        */
5361 /*    _nx_dhcpv6_utility_get_data     Parses data from reply buffer       */
5362 /*    _nx_dhcpv6_utility_get_block_option_length                          */
5363 /*                                    Parses option header from buffer    */
5364 /*    _nx_dhcpv6_process_ia           Process IA option in reply buffer   */
5365 /*    _nx_dhcpv6_process_status       Process status option in buffer     */
5366 /*    nx_dhcpv6_server_error_handler  Pointer to server error code handler*/
5367 /*                                                                        */
5368 /*  CALLED BY                                                             */
5369 /*                                                                        */
5370 /*    _nx_dhcpv6_extract_packet_information                               */
5371 /*                                      Extracts server reply from packet */
5372 /*                                                                        */
5373 /*  RELEASE HISTORY                                                       */
5374 /*                                                                        */
5375 /*    DATE              NAME                      DESCRIPTION             */
5376 /*                                                                        */
5377 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5378 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
5379 /*                                            packet length verification, */
5380 /*                                            resulting in version 6.1    */
5381 /*                                                                        */
5382 /**************************************************************************/
_nx_dhcpv6_process_iana(NX_DHCPV6 * dhcpv6_ptr,UCHAR * option_data,UINT option_length)5383 UINT _nx_dhcpv6_process_iana(NX_DHCPV6 *dhcpv6_ptr, UCHAR *option_data, UINT option_length)
5384 {
5385 
5386 UINT    status;
5387 ULONG   T1, T2, data;
5388 UINT    index = 0;
5389 ULONG   iana_option_code, iana_option_length;
5390 UINT    ia_index;
5391 UINT    ia_count = 0;
5392 UINT    ia_status;
5393 
5394 
5395     /* Check option length for IANA ID.  */
5396     if (option_length < 4)
5397     {
5398         return(NX_DHCPV6_INVALID_IANA_DATA);
5399     }
5400 
5401     /* Get the IANA ID. */
5402     memcpy(&data, (option_data + index), 4); /* Use case of memcpy is verified. */
5403 
5404     /* Adjust for endianness. */
5405     NX_CHANGE_ULONG_ENDIAN(data);
5406 
5407     /* The server response must return the correct IANA ID; this is applicable
5408        to clients configured with more than one IANA. */
5409     if (data != (dhcpv6_ptr -> nx_dhcpv6_iana.nx_IA_NA_id))
5410     {
5411 
5412         /* IANA does not match. */
5413         return NX_DHCPV6_BAD_IANA_ID;
5414     }
5415 
5416     /* Update the write location index. */
5417     index += 4;
5418 
5419     /* Check option length for T1 and T2.  */
5420     if (index + 8 > option_length)
5421     {
5422         return(NX_DHCPV6_INVALID_IANA_DATA);
5423     }
5424 
5425     /* Copy T1 and T2 from the buffer into temporary variables. */
5426     memcpy(&T1, (option_data + index), 4); /* Use case of memcpy is verified. */
5427     index += 4;
5428 
5429     /* Adjust for endianness. */
5430     NX_CHANGE_ULONG_ENDIAN(T1);
5431 
5432     memcpy(&T2, (option_data + index), 4); /* Use case of memcpy is verified. */
5433     index += 4;
5434 
5435     /* Adjust for endianness. */
5436     NX_CHANGE_ULONG_ENDIAN(T2);
5437 
5438     /* Check for invalid T1/T2 lifetimes. */
5439     if (T1 > T2)
5440     {
5441 
5442         /* Reject the server DHCPv6 response. */
5443         return NX_DHCPV6_INVALID_IANA_TIME;
5444     }
5445 
5446     /* Record the T1 and T2.  */
5447     /* Yes, the server will let the Client use its own T1 time? */
5448     if (T1 != 0)
5449     {
5450 
5451         /* Now, assign the server T1 to the client IA-NA. */
5452         dhcpv6_ptr -> nx_dhcpv6_iana.nx_T1 = T1;
5453     }
5454 
5455     /* Yes,the server will let the Client use its own T2 time? */
5456     if (T2 != 0)
5457     {
5458         /* Now, assign the server T2 to the client IA-NA. */
5459         dhcpv6_ptr -> nx_dhcpv6_iana.nx_T2 = T2;
5460     }
5461 
5462     /* Check if we're at the end of option data yet. */
5463     if (index == option_length)
5464     {
5465 
5466         /* Yes, all done. */
5467         return NX_SUCCESS;
5468     }
5469 
5470     /* If the reply message includes IA address option, clear the record.  */
5471     if(dhcpv6_ptr -> nx_dhcpv6_reply_option_flags & NX_DHCPV6_INCLUDE_IA_ADDRESS_OPTION)
5472     {
5473 
5474         /* Clear the IA address table according to the address map value.   */
5475         for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
5476         {
5477 
5478             /* The reply message does not include this IA option.*/
5479             if(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_map == 0)
5480             {
5481 
5482                 /* Clear it.  */
5483                 status = _nx_dhcpv6_remove_assigned_address(dhcpv6_ptr, ia_index);
5484             }
5485         }
5486     }
5487 
5488     /* Now we recurse into the options embedded in the IANA option. */
5489     while (index + 4 <= option_length)
5490     {
5491 
5492         /* Get the next option code and length. */
5493         status = _nx_dhcpv6_utility_get_block_option_length((option_data + index), &iana_option_code, &iana_option_length);
5494 
5495         /* Check that the block data is valid. */
5496         if (status != NX_SUCCESS)
5497         {
5498 
5499             /* No, return the error status. */
5500             return status;
5501         }
5502 
5503         /* Skip IANA sub option code and length.  */
5504         index += 4;
5505 
5506         /* This is a double check to verify we haven't gone off the end of the packet buffer. */
5507         if (index + iana_option_length > option_length)
5508         {
5509             return (NX_DHCPV6_INVALID_IANA_DATA);
5510         }
5511 
5512         /* Check if this is an IA address option request. */
5513         if (iana_option_code == NX_DHCPV6_OP_IA_ADDRESS)
5514         {
5515 
5516             /* Set the ia count to record the IA option of reply message.  */
5517             ia_count ++;
5518             ia_status = 0;
5519 
5520             /* First, find the same IPv6 address.  */
5521             for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
5522             {
5523 
5524                 /* The IPv6 address is new,so find the empty space to record it.  */
5525                 if(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_map == ia_count)
5526                 {
5527 
5528                     /* Yes, find it, update the IA option.  */
5529                     status = _nx_dhcpv6_process_ia(dhcpv6_ptr, (option_data + index), iana_option_length, ia_index);
5530 
5531                     /* Check the process status. */
5532                     if (status != NX_SUCCESS)
5533                     {
5534 
5535                         /* No, return the error status. */
5536                         return status;
5537                     }
5538 
5539                     /* Yes, set success.  */
5540                     ia_status = 1;
5541 
5542                     break;
5543                 }
5544             }
5545 
5546             /* Record the IA option failure.  */
5547             if(ia_status == 0)
5548             {
5549 
5550                 /* Second, find one empty IA to record it.  */
5551                 for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
5552                 {
5553 
5554                     /* The IPv6 address is new,so find the empty space to record it.  */
5555                     if(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_map == 0)
5556                     {
5557 
5558                         /* Yes, it is available, update the IA option.  */
5559                         status = _nx_dhcpv6_process_ia(dhcpv6_ptr, (option_data + index), iana_option_length, ia_index);
5560 
5561                         /* Check the process status. */
5562                         if (status != NX_SUCCESS)
5563                         {
5564 
5565                             /* No, return the error status. */
5566                             return status;
5567                         }
5568 
5569                         break;
5570                     }
5571                 }
5572             }
5573         }
5574 
5575         /* Check if this is an IAaddr status option request. */
5576         if (iana_option_code == NX_DHCPV6_OP_STATUS_CODE)
5577         {
5578             /* The IAaddr option returned by the DHCPv6 server includes a status option. */
5579 
5580             /* Process the status. */
5581             status = _nx_dhcpv6_process_status(dhcpv6_ptr, (option_data + index), iana_option_length);
5582 
5583             /* Now check on the server status of the previous option in the DHCP message. */
5584             if ((status == NX_SUCCESS) && (dhcpv6_ptr -> nx_status_code != NX_DHCPV6_SUCCESS))
5585             {
5586 
5587                 /* Does the dhcpv6 client have a server error handler? */
5588                 if (dhcpv6_ptr -> nx_dhcpv6_server_error_handler)
5589                 {
5590 
5591                     /* Call the error handler with status code, option (IA_NA) and which message type it refers to. */
5592                     dhcpv6_ptr -> nx_dhcpv6_server_error_handler(dhcpv6_ptr, NX_DHCPV6_ERROR_STATUS_CODE_IN_IA_NA, dhcpv6_ptr -> nx_status_code,
5593                                                                  dhcpv6_ptr -> nx_dhcpv6_received_message_type);
5594                 }
5595             }
5596 
5597             /* Check for errors processing the DHCPv6 message. */
5598             if (status != NX_SUCCESS)
5599             {
5600 
5601                 /* Abort further processing. Return error status. */
5602                 return status;
5603             }
5604         }
5605 
5606         /* Keep track of how far into the packet we have parsed. */
5607         index += iana_option_length;
5608     }
5609 
5610     return NX_SUCCESS;
5611 }
5612 
5613 
5614 /**************************************************************************/
5615 /*                                                                        */
5616 /*  FUNCTION                                               RELEASE        */
5617 /*                                                                        */
5618 /*    _nx_dhcpv6_process_preference                       PORTABLE C      */
5619 /*                                                           6.1          */
5620 /*  AUTHOR                                                                */
5621 /*                                                                        */
5622 /*    Yuxin Zhou, Microsoft Corporation                                   */
5623 /*                                                                        */
5624 /*  DESCRIPTION                                                           */
5625 /*                                                                        */
5626 /*    This function extracts the preference option from the server reply. */
5627 /*    It will save as much of the time zone that will fit in the Client   */
5628 /*    time zone buffer. Buffer size is user configurable.                 */
5629 /*                                                                        */
5630 /*  INPUT                                                                 */
5631 /*                                                                        */
5632 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
5633 /*    option_data                       Pointer to option data            */
5634 /*    option_length                     Size of option data               */
5635 /*                                                                        */
5636 /*  OUTPUT                                                                */
5637 /*                                                                        */
5638 /*    NX_SUCCESS                        Successful completion status      */
5639 /*    NX_DHCPV6_INVALID_PREF_DATA       Preference option is missing data */
5640 /*                                         or improperly formatted        */
5641 /*  CALLS                                                                 */
5642 /*                                                                        */
5643 /*    None                                                                */
5644 /*                                                                        */
5645 /*  CALLED BY                                                             */
5646 /*                                                                        */
5647 /*    _nx_dhcpv6_extract_packet_information                               */
5648 /*                                      Extracts DHCPv6 options from      */
5649 /*                                             server reply               */
5650 /*                                                                        */
5651 /*  RELEASE HISTORY                                                       */
5652 /*                                                                        */
5653 /*    DATE              NAME                      DESCRIPTION             */
5654 /*                                                                        */
5655 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5656 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
5657 /*                                            packet length verification, */
5658 /*                                            resulting in version 6.1    */
5659 /*                                                                        */
5660 /**************************************************************************/
_nx_dhcpv6_process_preference(NX_DHCPV6 * dhcpv6_ptr,UCHAR * option_data,UINT option_length)5661 UINT _nx_dhcpv6_process_preference(NX_DHCPV6 *dhcpv6_ptr, UCHAR *option_data, UINT option_length)
5662 {
5663 
5664 
5665     /* Fill in the option code and length. */
5666     dhcpv6_ptr -> nx_dhcpv6_preference.nx_op_code = NX_DHCPV6_OP_PREFERENCE;
5667     dhcpv6_ptr -> nx_dhcpv6_preference.nx_option_length = (USHORT)option_length;
5668 
5669     /* Check option length for preference value.  */
5670     if (option_length != 1)
5671     {
5672         return(NX_DHCPV6_INVALID_PREF_DATA);
5673     }
5674 
5675     /* Get the server preference field, and apply to the DHCPv6 Client. */
5676     dhcpv6_ptr -> nx_dhcpv6_preference.nx_pref_value = (USHORT)(*option_data);
5677 
5678     return NX_SUCCESS;
5679 }
5680 
5681 
5682 /**************************************************************************/
5683 /*                                                                        */
5684 /*  FUNCTION                                               RELEASE        */
5685 /*                                                                        */
5686 /*    _nx_dhcpv6_process_server_duid                      PORTABLE C      */
5687 /*                                                           6.1          */
5688 /*  AUTHOR                                                                */
5689 /*                                                                        */
5690 /*    Yuxin Zhou, Microsoft Corporation                                   */
5691 /*                                                                        */
5692 /*  DESCRIPTION                                                           */
5693 /*                                                                        */
5694 /*    This function extracts the server DUID from the server reply and,   */
5695 /*    if the Client already has a DHCPv6 server on record, verifies that  */
5696 /*    it matches the Client's server DUID.                                */
5697 /*                                                                        */
5698 /*  INPUT                                                                 */
5699 /*                                                                        */
5700 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
5701 /*    option_data                       Pointer to option data            */
5702 /*    option_length                     Size of option data               */
5703 /*                                                                        */
5704 /*  OUTPUT                                                                */
5705 /*                                                                        */
5706 /*    NX_SUCCESS                        Successful completion status      */
5707 /*    NX_DHCPV6_INVALID_SERVER_DUID     Server DUID is missing data or    */
5708 /*                                       does not match the DUID on record*/
5709 /*  CALLS                                                                 */
5710 /*                                                                        */
5711 /*    _nx_dhcpv6_utility_get_data       Parses data from specified buffer */
5712 /*                                                                        */
5713 /*  CALLED BY                                                             */
5714 /*                                                                        */
5715 /*    _nx_dhcpv6_extract_packet_information                               */
5716 /*                                      Extracts server reply from packet */
5717 /*                                                                        */
5718 /*  RELEASE HISTORY                                                       */
5719 /*                                                                        */
5720 /*    DATE              NAME                      DESCRIPTION             */
5721 /*                                                                        */
5722 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5723 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
5724 /*                                            packet length verification, */
5725 /*                                            resulting in version 6.1    */
5726 /*                                                                        */
5727 /**************************************************************************/
_nx_dhcpv6_process_server_duid(NX_DHCPV6 * dhcpv6_ptr,UCHAR * option_data,UINT option_length)5728 UINT _nx_dhcpv6_process_server_duid(NX_DHCPV6 *dhcpv6_ptr, UCHAR *option_data, UINT option_length)
5729 {
5730 
5731 UINT    index = 0;
5732 ULONG   temp_type;
5733 ULONG   temp_hardware_type;
5734 ULONG   temp_time = 0;
5735 ULONG   temp_msw = 0;
5736 ULONG   temp_lsw = 0;
5737 
5738 
5739     /* Set the DHCPv6 option header fields for a Server DUID. */
5740     dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_op_code = NX_DHCPV6_OP_SERVER_ID;
5741     dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_option_length = (USHORT)option_length;
5742 
5743     /* Check option length for DUID type and hardware type.  */
5744     if (option_length < 4)
5745     {
5746         return(NX_DHCPV6_INVALID_SERVER_DUID);
5747     }
5748 
5749     /* Extract the DUID type which should be the next 2 bytes.  */
5750     _nx_dhcpv6_utility_get_data((option_data + index), 2, &temp_type);
5751 
5752     /* Update the index for moving the buffer pointer forward. */
5753     index += 2;
5754 
5755     /* Extract the hardware type which should be the next 2 bytes.  */
5756     _nx_dhcpv6_utility_get_data((option_data + index), 2, &temp_hardware_type);
5757 
5758     /* Update the index for moving the buffer pointer forward. */
5759     index += 2;
5760 
5761     /* Is this a link layer plus time DUID type? */
5762     if (temp_type == NX_DHCPV6_DUID_TYPE_LINK_TIME)
5763     {
5764 
5765         /* Check option length for time.  */
5766         if (index + 4 > option_length)
5767         {
5768             return(NX_DHCPV6_INVALID_SERVER_DUID);
5769         }
5770 
5771         /* Yes; Extract the time which should be the next 4 bytes.  */
5772         _nx_dhcpv6_utility_get_data((option_data + index), 4,  &temp_time);
5773 
5774         /* Update the index for moving the buffer pointer forward. */
5775         index += 4;
5776     }
5777 
5778     /* Check the hardware type to extract the MSW.  */
5779     if (temp_hardware_type == NX_DHCPV6_CLIENT_HARDWARE_TYPE_ETHERNET)
5780     {
5781 
5782         /* The length of link layer address is 48 bits.  */
5783 
5784         /* Check option length for 48 bits mac address.  */
5785         if (index + 6 > option_length)
5786         {
5787             return(NX_DHCPV6_INVALID_SERVER_DUID);
5788         }
5789 
5790         /* Yes; Extract the link local address msw which should be the next 2 bytes.  */
5791         _nx_dhcpv6_utility_get_data((option_data + index), 2, &temp_msw);
5792 
5793         /* Update the index for moving the buffer pointer forward. */
5794         index += 2;
5795     }
5796     else if (temp_hardware_type == NX_DHCPV6_CLIENT_HARDWARE_TYPE_EUI_64)
5797     {
5798 
5799         /* The length of link layer address is 64 bits.  */
5800 
5801         /* Check option length for 64 bits mac address.  */
5802         if (index + 8 > option_length)
5803         {
5804             return(NX_DHCPV6_INVALID_SERVER_DUID);
5805         }
5806 
5807         /* Yes; Extract the link local address msw which should be the next 4 bytes.  */
5808         _nx_dhcpv6_utility_get_data((option_data + index), 4, &temp_msw);
5809 
5810         /* Update the index for moving the buffer pointer forward. */
5811         index += 4;
5812     }
5813 
5814     /* Yes; Extract the link local address lsw which should be the next 4 bytes.  */
5815     _nx_dhcpv6_utility_get_data((option_data + index), 4, &temp_lsw);
5816 
5817     /* Update the index for moving the buffer pointer forward. */
5818     index += 4;
5819 
5820     /* Check if we are past the end of the buffer. */
5821     if (index != option_length)
5822     {
5823 
5824         /* Yes, return the error status to reject the packet. */
5825         return NX_DHCPV6_INVALID_SERVER_DUID;
5826     }
5827 
5828     /* If the client state in SENDING SOLICIT/CONFRIM/REBIND/INFORM_REQUEST, record the server DUID.  */
5829     if (dhcpv6_ptr -> nx_dhcpv6_state == NX_DHCPV6_STATE_SENDING_SOLICIT ||
5830         dhcpv6_ptr -> nx_dhcpv6_state == NX_DHCPV6_STATE_SENDING_CONFIRM ||
5831         dhcpv6_ptr -> nx_dhcpv6_state == NX_DHCPV6_STATE_SENDING_REBIND ||
5832         dhcpv6_ptr -> nx_dhcpv6_state == NX_DHCPV6_STATE_SENDING_INFORM_REQUEST )
5833     {
5834 
5835         /* No previous server DUID in the Client record.  Copy it over now. */
5836         dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_duid_type = (USHORT)temp_type;
5837 
5838         /* Is this a TIME Duid type? */
5839         if (temp_type == NX_DHCPV6_DUID_TYPE_LINK_TIME)
5840         {
5841 
5842             /* Yes, write in the time data. */
5843             dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_duid_time = temp_time;
5844         }
5845 
5846         dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_hardware_type = (USHORT)temp_hardware_type;
5847         dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_link_layer_address_msw = temp_msw;
5848         dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_link_layer_address_lsw = temp_lsw;
5849     }
5850     else
5851     {
5852 
5853         /* Yes; Verify this Server DUID matches the Server DUID from the Client record. */
5854         if ((dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_duid_time != temp_time) ||
5855             (dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_link_layer_address_msw != temp_msw) ||
5856             (dhcpv6_ptr -> nx_dhcpv6_server_duid.nx_link_layer_address_lsw != temp_lsw))
5857         {
5858 
5859             /* It doesn't. Return an error status to reject this packet! */
5860             return NX_DHCPV6_INVALID_SERVER_DUID;
5861         }
5862     }
5863 
5864     /* Return successful completion status. */
5865     return NX_SUCCESS;
5866 }
5867 
5868 
5869 /**************************************************************************/
5870 /*                                                                        */
5871 /*  FUNCTION                                               RELEASE        */
5872 /*                                                                        */
5873 /*    _nx_dhcpv6_process_status                           PORTABLE C      */
5874 /*                                                           6.1          */
5875 /*  AUTHOR                                                                */
5876 /*                                                                        */
5877 /*    Yuxin Zhou, Microsoft Corporation                                   */
5878 /*                                                                        */
5879 /*  DESCRIPTION                                                           */
5880 /*                                                                        */
5881 /*    This function extracts the option status option from the server     */
5882 /*    reply. It also attempts to save the as much of server status message*/
5883 /*    that will fit into the status message buffer.                       */
5884 /*                                                                        */
5885 /*  INPUT                                                                 */
5886 /*                                                                        */
5887 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
5888 /*    option_data                       Pointer to option data            */
5889 /*    option_length                     Size of option data               */
5890 /*                                                                        */
5891 /*  OUTPUT                                                                */
5892 /*                                                                        */
5893 /*    NX_SUCCESS                        Successful completion status      */
5894 /*                                                                        */
5895 /*  CALLS                                                                 */
5896 /*                                                                        */
5897 /*    memcpy                            Copies specified area of memory   */
5898 /*                                                                        */
5899 /*  CALLED BY                                                             */
5900 /*                                                                        */
5901 /*    _nx_dhcpv6_process_iana           Processes IANA in reply buffer    */
5902 /*                                            DHCPv6 request              */
5903 /*    _nx_dhcpv6_process_ia             Processes IA in reply buffer      */
5904 /*                                                                        */
5905 /*  RELEASE HISTORY                                                       */
5906 /*                                                                        */
5907 /*    DATE              NAME                      DESCRIPTION             */
5908 /*                                                                        */
5909 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5910 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
5911 /*                                            packet length verification, */
5912 /*                                            verified memcpy use cases,  */
5913 /*                                            resulting in version 6.1    */
5914 /*                                                                        */
5915 /**************************************************************************/
_nx_dhcpv6_process_status(NX_DHCPV6 * dhcpv6_ptr,UCHAR * option_data,UINT option_length)5916 UINT _nx_dhcpv6_process_status(NX_DHCPV6 *dhcpv6_ptr, UCHAR *option_data, UINT option_length)
5917 {
5918 
5919 UINT  index = 0;
5920 UINT  message_length;
5921 ULONG status_code;
5922 
5923 
5924     /* Check option length for status code.  */
5925     if (option_length < 2)
5926     {
5927         return(NX_DHCPV6_INVALID_OPTION_DATA);
5928     }
5929 
5930     /* Get the status field itself. */
5931     _nx_dhcpv6_utility_get_data((option_data + index), sizeof(USHORT), &status_code);
5932 
5933     /* Update the index for moving the buffer pointer forward. */
5934     index += 2;
5935 
5936     /* Set the status code.  */
5937     dhcpv6_ptr -> nx_status_code = (USHORT)status_code;
5938 
5939     /* Now figure out how much of the message we can save, if not all of it. */
5940     if ((option_length - 2) > NX_DHCPV6_MAX_MESSAGE_SIZE)
5941     {
5942 
5943         /* Store up to this much, message is truncated but possibly still useful. */
5944         message_length = NX_DHCPV6_MAX_MESSAGE_SIZE;
5945     }
5946     else
5947     {
5948 
5949         /* Store all of it. */
5950         message_length = option_length - 2;
5951     }
5952 
5953     /* Copy the status into the Client record. */
5954     memcpy(dhcpv6_ptr -> nx_status_message, (option_data + index), message_length); /* Use case of memcpy is verified. */
5955 
5956     return NX_SUCCESS;
5957 }
5958 
5959 
5960 /**************************************************************************/
5961 /*                                                                        */
5962 /*  FUNCTION                                               RELEASE        */
5963 /*                                                                        */
5964 /*    _nx_dhcpv6_process_time_zone                        PORTABLE C      */
5965 /*                                                           6.1          */
5966 /*  AUTHOR                                                                */
5967 /*                                                                        */
5968 /*    Yuxin Zhou, Microsoft Corporation                                   */
5969 /*                                                                        */
5970 /*  DESCRIPTION                                                           */
5971 /*                                                                        */
5972 /*    This function extracts the time zone option from the server reply.  */
5973 /*    It will save as much of the time zone that will fit in the Client   */
5974 /*    time zone buffer. Buffer size is user configurable.                 */
5975 /*                                                                        */
5976 /*  INPUT                                                                 */
5977 /*                                                                        */
5978 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
5979 /*    option_data                       Pointer to option data            */
5980 /*    option_length                     Size of option data               */
5981 /*                                                                        */
5982 /*  OUTPUT                                                                */
5983 /*                                                                        */
5984 /*    NX_SUCCESS                        Successful completion status      */
5985 /*                                                                        */
5986 /*  CALLS                                                                 */
5987 /*                                                                        */
5988 /*    None                                                                */
5989 /*                                                                        */
5990 /*  CALLED BY                                                             */
5991 /*                                                                        */
5992 /*    _nx_dhcpv6_extract_packet_information                               */
5993 /*                                      Extracts DHCPv6 options from      */
5994 /*                                             server reply               */
5995 /*                                                                        */
5996 /*  RELEASE HISTORY                                                       */
5997 /*                                                                        */
5998 /*    DATE              NAME                      DESCRIPTION             */
5999 /*                                                                        */
6000 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6001 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
6002 /*                                            packet length verification, */
6003 /*                                            resulting in version 6.1    */
6004 /*                                                                        */
6005 /**************************************************************************/
_nx_dhcpv6_process_time_zone(NX_DHCPV6 * dhcpv6_ptr,UCHAR * option_data,UINT option_length)6006 UINT _nx_dhcpv6_process_time_zone(NX_DHCPV6 *dhcpv6_ptr, UCHAR *option_data, UINT option_length)
6007 {
6008 
6009 UINT i;
6010 
6011 
6012     /* Make sure the time zone fits in the client buffer. */
6013     if (option_length > NX_DHCPV6_TIME_ZONE_BUFFER_SIZE)
6014     {
6015 
6016         /* It doesn't.  Fit what we can. */
6017         option_length = NX_DHCPV6_TIME_ZONE_BUFFER_SIZE;
6018     }
6019 
6020     /* Copy the time zone from the buffer to the Client record. */
6021     for (i = 0; i < option_length; i++)
6022     {
6023 
6024         dhcpv6_ptr -> nx_dhcpv6_time_zone[i] = *(option_data + i);
6025     }
6026 
6027     /* Return completion status. */
6028     return NX_SUCCESS;
6029 }
6030 
6031 
6032 /**************************************************************************/
6033 /*                                                                        */
6034 /*  FUNCTION                                               RELEASE        */
6035 /*                                                                        */
6036 /*    _nx_dhcpv6_process_time_server                      PORTABLE C      */
6037 /*                                                           6.1          */
6038 /*  AUTHOR                                                                */
6039 /*                                                                        */
6040 /*    Yuxin Zhou, Microsoft Corporation                                   */
6041 /*                                                                        */
6042 /*  DESCRIPTION                                                           */
6043 /*                                                                        */
6044 /*    This function extracts the time server option from the server reply.*/
6045 /*    It will save as many time server addresses as are in the reply for  */
6046 /*    which the Client is configured to save.                             */
6047 /*                                                                        */
6048 /*  INPUT                                                                 */
6049 /*                                                                        */
6050 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
6051 /*    option_data                       Pointer to option data            */
6052 /*    option_length                     Size of option data               */
6053 /*                                                                        */
6054 /*  OUTPUT                                                                */
6055 /*                                                                        */
6056 /*    NX_SUCCESS                        Successful completion status      */
6057 /*                                                                        */
6058 /*  CALLS                                                                 */
6059 /*                                                                        */
6060 /*    memcpy                            Copies specified area of memory   */
6061 /*                                                                        */
6062 /*  CALLED BY                                                             */
6063 /*                                                                        */
6064 /*    _nx_dhcpv6_extract_packet_information                               */
6065 /*                                      Extracts DHCPv6 options from      */
6066 /*                                             server reply               */
6067 /*                                                                        */
6068 /*  RELEASE HISTORY                                                       */
6069 /*                                                                        */
6070 /*    DATE              NAME                      DESCRIPTION             */
6071 /*                                                                        */
6072 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6073 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
6074 /*                                            packet length verification, */
6075 /*                                            verified memcpy use cases,  */
6076 /*                                            resulting in version 6.1    */
6077 /*                                                                        */
6078 /**************************************************************************/
_nx_dhcpv6_process_time_server(NX_DHCPV6 * dhcpv6_ptr,UCHAR * option_data,UINT option_length)6079 UINT _nx_dhcpv6_process_time_server(NX_DHCPV6 *dhcpv6_ptr, UCHAR *option_data, UINT option_length)
6080 {
6081 
6082 UINT   index = 0;
6083 UINT   w, j = 0;
6084 
6085 
6086     /* Loop through the length of the buffer to parse. */
6087     while (index + 16 <= option_length)
6088     {
6089 
6090         /* Check that the DHCPv6 Client configured to store this time server address e.g. it may
6091             only store one address, but the server could be sending two or more. */
6092         if (j < NX_DHCPV6_NUM_TIME_SERVERS)
6093         {
6094 
6095             /* Set the IP version. */
6096             dhcpv6_ptr -> nx_dhcpv6_time_server_address[j].nxd_ip_version = NX_IP_VERSION_V6;
6097 
6098             /* Get the next IPv6 time server address. */
6099             for (w = 0; w <= 3; w++)
6100             {
6101 
6102                 /* Yes; copy each IPv6 address word into the time server address. */
6103                 memcpy(&(dhcpv6_ptr -> nx_dhcpv6_time_server_address[j].nxd_ip_address.v6[w]), /* Use case of memcpy is verified. */
6104                        (option_data + index), sizeof(ULONG));
6105 
6106                 /* Adjust for endianness. */
6107                 NX_CHANGE_ULONG_ENDIAN(dhcpv6_ptr -> nx_dhcpv6_time_server_address[j].nxd_ip_address.v6[w]);
6108 
6109                 /* Move to the next IPv6 address word. */
6110                 index += 4;
6111             }
6112 
6113             /* Start parsing the next time server address, if there is one.  */
6114             j++;
6115         }
6116         else
6117         {
6118 
6119             /* Move to the next timer server address. */
6120             index += 16;
6121         }
6122     }
6123 
6124     /* Is there any more data in this option? */
6125     if (index != option_length)
6126     {
6127 
6128         /* Yes, treat as in improperly formatted packet. */
6129         return NX_DHCPV6_INVALID_OPTION_DATA;
6130     }
6131 
6132     return NX_SUCCESS;
6133 }
6134 
6135 
6136 /**************************************************************************/
6137 /*                                                                        */
6138 /*  FUNCTION                                               RELEASE        */
6139 /*                                                                        */
6140 /*    _nx_dhcpv6_remove_assigned_address                  PORTABLE C      */
6141 /*                                                           6.1          */
6142 /*  AUTHOR                                                                */
6143 /*                                                                        */
6144 /*    Yuxin Zhou, Microsoft Corporation                                   */
6145 /*                                                                        */
6146 /*  DESCRIPTION                                                           */
6147 /*                                                                        */
6148 /*    This function removes the DHCPv6 Client address from the Client     */
6149 /*    record and from the IP address table. IP lease lifetimes and IP     */
6150 /*    addresses in the Client record are also cleared.                    */
6151 /*                                                                        */
6152 /*  INPUT                                                                 */
6153 /*                                                                        */
6154 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
6155 /*                                                                        */
6156 /*  OUTPUT                                                                */
6157 /*                                                                        */
6158 /*    NX_SUCCESS                         Successful Completion status     */
6159 /*    NX_INVALID_INTERFACE               Invalid index in IP address table*/
6160 /*    status                             Failed mutex get                 */
6161 /*                                                                        */
6162 /*  CALLS                                                                 */
6163 /*                                                                        */
6164 /*    tx_mutex_get                       Get exclusive lock on time keeper*/
6165 /*    tx_mutex_put                       Release the lock on time keeper  */
6166 /*    _nx_dhcpv6_set_IP_address_NULL     Set the IP address to NULL       */
6167 /*                                                                        */
6168 /*  CALLED BY                                                             */
6169 /*                                                                        */
6170 /*    nx_dhcpv6_process                                                    */
6171 /*                                                                        */
6172 /*  RELEASE HISTORY                                                       */
6173 /*                                                                        */
6174 /*    DATE              NAME                      DESCRIPTION             */
6175 /*                                                                        */
6176 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6177 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6178 /*                                            resulting in version 6.1    */
6179 /*                                                                        */
6180 /**************************************************************************/
_nx_dhcpv6_remove_assigned_address(NX_DHCPV6 * dhcpv6_ptr,UINT ia_index)6181 UINT _nx_dhcpv6_remove_assigned_address(NX_DHCPV6 *dhcpv6_ptr, UINT ia_index)
6182 {
6183 UINT    index;
6184 
6185     /* Only clear one address.  */
6186     if(ia_index != NX_DHCPV6_REMOVE_ALL_IA_ADDRESS)
6187     {
6188 
6189         /* Check for invalid IA index.  */
6190         if (ia_index >= NX_DHCPV6_MAX_IA_ADDRESS)
6191         {
6192             return(NX_DHCPV6_REACHED_MAX_IA_ADDRESS);
6193         }
6194 
6195         if((dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status) &&
6196            (dhcpv6_ptr -> nx_dhcpv6_client_address_index[ia_index] != 0) &&
6197            (dhcpv6_ptr -> nx_dhcpv6_client_address_index[ia_index] != 0xFFFFFFFF))
6198         {
6199 
6200             /* Now remove the address from the IP address table. */
6201             nxd_ipv6_address_delete(dhcpv6_ptr -> nx_dhcpv6_ip_ptr, dhcpv6_ptr -> nx_dhcpv6_client_address_index[ia_index]);
6202 
6203             /* Set the address index to invalid. */
6204             dhcpv6_ptr -> nx_dhcpv6_client_address_index[ia_index] = 0xFFFFFFFF;
6205         }
6206 
6207         /* Clear the IA data.  */
6208         memset(&dhcpv6_ptr -> nx_dhcpv6_ia[ia_index], 0, sizeof(NX_DHCPV6_IA_ADDRESS));
6209 
6210     }
6211 
6212     /* Clear the all addresses.  */
6213     else
6214     {
6215 
6216         /* Zero out time accrued on the current lease. */
6217         dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_time_accrued = 0;
6218 
6219         /* Set all lease lifetime and time fields to zero. */
6220         dhcpv6_ptr -> nx_dhcpv6_iana.nx_T1 = 0;
6221         dhcpv6_ptr -> nx_dhcpv6_iana.nx_T2 = 0;
6222 
6223         /* Delete the IPv6 address of IP instance.  */
6224         for(index = 0; index < NX_DHCPV6_MAX_IA_ADDRESS; index++)
6225         {
6226 
6227             if((dhcpv6_ptr -> nx_dhcpv6_ia[index].nx_address_status) &&
6228                (dhcpv6_ptr -> nx_dhcpv6_client_address_index[index] != 0) &&
6229                (dhcpv6_ptr -> nx_dhcpv6_client_address_index[index] != 0xFFFFFFFF))
6230             {
6231 
6232                 /* Now remove the address from the IP address table. */
6233                 nxd_ipv6_address_delete(dhcpv6_ptr -> nx_dhcpv6_ip_ptr, dhcpv6_ptr -> nx_dhcpv6_client_address_index[index]);
6234 
6235                 /* Set the address index to invalid. */
6236                 dhcpv6_ptr -> nx_dhcpv6_client_address_index[index] = 0xFFFFFFFF;
6237             }
6238         }
6239 
6240         /* Clear the all IA data.  */
6241         memset(&dhcpv6_ptr -> nx_dhcpv6_ia[0], 0, NX_DHCPV6_MAX_IA_ADDRESS * sizeof(NX_DHCPV6_IA_ADDRESS));
6242 
6243         /* Removed the default router.  */
6244         if (dhcpv6_ptr -> nx_dhcpv6_state >= NX_DHCPV6_STATE_SENDING_RENEW)
6245         {
6246             nxd_ipv6_default_router_delete(dhcpv6_ptr -> nx_dhcpv6_ip_ptr, &(dhcpv6_ptr -> nx_dhcpv6_server_address));
6247             memset(&(dhcpv6_ptr -> nx_dhcpv6_server_address), 0, sizeof(NXD_ADDRESS));
6248         }
6249     }
6250 
6251     /* Clear the all address.  */
6252     return NX_SUCCESS;
6253 }
6254 
6255 
6256 /**************************************************************************/
6257 /*                                                                        */
6258 /*  FUNCTION                                               RELEASE        */
6259 /*                                                                        */
6260 /*    _nx_dhcpv6_request                                  PORTABLE C      */
6261 /*                                                           6.1          */
6262 /*  AUTHOR                                                                */
6263 /*                                                                        */
6264 /*    Yuxin Zhou, Microsoft Corporation                                   */
6265 /*                                                                        */
6266 /*  DESCRIPTION                                                           */
6267 /*                                                                        */
6268 /*    This function sets the DHCPv6 Client state with the supplied state  */
6269 /*    (request). The DHCP Client thread will detect a state change and    */
6270 /*    process the new state.                                              */
6271 /*                                                                        */
6272 /*    Note the return status only reflects the outcome of sending the     */
6273 /*    message, it does not indicate whether the request was successfully  */
6274 /*    granted. The host application is notified of "state" changes e.g.   */
6275 /*    NX_DHCPV6_STATE_SUCCESS or NX_DHCPV6_STATE_IP_FAILURE in the        */
6276 /*    callback function nx_dhcpv6_state_change_callback.                  */
6277 /*                                                                        */
6278 /*  INPUT                                                                 */
6279 /*                                                                        */
6280 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
6281 /*    dhcpv6_state                       State for making DHCPv6 request  */
6282 /*                                                                        */
6283 /*  OUTPUT                                                                */
6284 /*                                                                        */
6285 /*    NX_SUCCESS                         Successful completion status     */
6286 /*    NX_DHCP_NOT_STARTED                DHCPv6 Client not started        */
6287 /*    status                             Get mutex status                 */
6288 /*                                                                        */
6289 /*  CALLS                                                                 */
6290 /*                                                                        */
6291 /*    tx_mutex_get                       Get DHCPv6 Client mutex          */
6292 /*    tx_mutex_put                       Releases the Client mutex        */
6293 /*                                                                        */
6294 /*  CALLED BY                                                             */
6295 /*                                                                        */
6296 /*    _nx_dhcpv6_request_solicit       Submits a SOLICIT request to Client*/
6297 /*    _nx_dhcpv6_request_renew         Submits a RENEW request to Client  */
6298 /*    _nx_dhcpv6_request_rebind        Submits a REBIND request to Client */
6299 /*    _nx_dhcpv6_request_release       Submits a RELEASE request to Client*/
6300 /*    _nx_dhcpv6_request_decline       Submits a DECLINE request to Client*/
6301 /*    _nx_dhcpv6_request_confirm       Submits a CONFIRM request to Client*/
6302 /*    _nx_dhcpv6_request_inform_request                                   */
6303 /*                                     Submits an Inform Request request  */
6304 /*                                              to Client                 */
6305 /*                                                                        */
6306 /*  RELEASE HISTORY                                                       */
6307 /*                                                                        */
6308 /*    DATE              NAME                      DESCRIPTION             */
6309 /*                                                                        */
6310 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6311 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6312 /*                                            resulting in version 6.1    */
6313 /*                                                                        */
6314 /**************************************************************************/
_nx_dhcpv6_request(NX_DHCPV6 * dhcpv6_ptr,UINT dhcpv6_state)6315 UINT  _nx_dhcpv6_request(NX_DHCPV6 *dhcpv6_ptr, UINT dhcpv6_state)
6316 {
6317 
6318 UINT            status;
6319 
6320 
6321     /* First get an exclusive lock on the DHCPv6 Client. */
6322     status = tx_mutex_get(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex), NX_DHCPV6_MUTEX_WAIT);
6323 
6324     /* Check for error. */
6325     if (status != TX_SUCCESS)
6326     {
6327 
6328         /* Return the error status. */
6329         return status;
6330     }
6331 
6332     /* Determine if DHCP is started.  */
6333     if (dhcpv6_ptr -> nx_dhcpv6_started == NX_FALSE)
6334     {
6335 
6336         /* Release the DHCP mutex.  */
6337         tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
6338 
6339 
6340         /* DHCP is not started so it can't be stopped.  */
6341         return(NX_DHCPV6_NOT_STARTED);
6342     }
6343 
6344     /* Wait for an opportunity to stop the DHCPv6 Client thread e.g. not in the midst of
6345        modifying the host DHCP profile!  */
6346     while (dhcpv6_ptr -> nx_dhcpv6_sleep_flag != NX_TRUE)
6347     {
6348 
6349         /* Release the DHCP mutex.  */
6350         tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
6351 
6352         /* Sleep temporarily. */
6353         tx_thread_sleep(1);
6354 
6355         /* Get the DHCP mutex.  */
6356         tx_mutex_get(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex), NX_DHCPV6_MUTEX_WAIT);
6357     }
6358 
6359     /* Set the Client state to process the DHCPv6 request. */
6360     dhcpv6_ptr -> nx_dhcpv6_state = (UCHAR)dhcpv6_state;
6361 
6362     /* Release the Client mutex. */
6363     tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
6364 
6365     return NX_SUCCESS;
6366 }
6367 
6368 
6369 /**************************************************************************/
6370 /*                                                                        */
6371 /*  FUNCTION                                               RELEASE        */
6372 /*                                                                        */
6373 /*    _nxe_dhcpv6_request_confirm                         PORTABLE C      */
6374 /*                                                           6.1          */
6375 /*  AUTHOR                                                                */
6376 /*                                                                        */
6377 /*    Yuxin Zhou, Microsoft Corporation                                   */
6378 /*                                                                        */
6379 /*  DESCRIPTION                                                           */
6380 /*                                                                        */
6381 /*    This function performs error checking on the NetX DHCPv6 Confirm    */
6382 /*    request service.                                                    */
6383 /*                                                                        */
6384 /*  INPUT                                                                 */
6385 /*                                                                        */
6386 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
6387 /*                                                                        */
6388 /*  OUTPUT                                                                */
6389 /*                                                                        */
6390 /*    status                             Completion status                */
6391 /*    NX_PTR_ERROR                       Invalid pointer input            */
6392 /*                                                                        */
6393 /*                                                                        */
6394 /*  CALLS                                                                 */
6395 /*                                                                        */
6396 /*    _nx_dhcpv6_request_confirm         Actual DHCPV6 process Confirm    */
6397 /*                                                  request service       */
6398 /*                                                                        */
6399 /*  CALLED BY                                                             */
6400 /*                                                                        */
6401 /*    Application Code                                                    */
6402 /*                                                                        */
6403 /*  RELEASE HISTORY                                                       */
6404 /*                                                                        */
6405 /*    DATE              NAME                      DESCRIPTION             */
6406 /*                                                                        */
6407 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6408 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6409 /*                                            resulting in version 6.1    */
6410 /*                                                                        */
6411 /**************************************************************************/
_nxe_dhcpv6_request_confirm(NX_DHCPV6 * dhcpv6_ptr)6412 UINT  _nxe_dhcpv6_request_confirm(NX_DHCPV6 *dhcpv6_ptr)
6413 {
6414 
6415 UINT status;
6416 
6417 
6418     /* Check for invalid pointer input. */
6419     if (!dhcpv6_ptr)
6420     {
6421 
6422         return NX_PTR_ERROR;
6423     }
6424 
6425     /* Check for appropriate caller.  */
6426     NX_THREADS_ONLY_CALLER_CHECKING
6427 
6428     /* Call the actual service. */
6429     status = _nx_dhcpv6_request_confirm(dhcpv6_ptr);
6430 
6431     /* Return completion status. */
6432     return status;
6433 }
6434 
6435 
6436 /**************************************************************************/
6437 /*                                                                        */
6438 /*  FUNCTION                                               RELEASE        */
6439 /*                                                                        */
6440 /*    _nx_dhcpv6_request_confirm                          PORTABLE C      */
6441 /*                                                           6.1          */
6442 /*  AUTHOR                                                                */
6443 /*                                                                        */
6444 /*    Yuxin Zhou, Microsoft Corporation                                   */
6445 /*                                                                        */
6446 /*  DESCRIPTION                                                           */
6447 /*                                                                        */
6448 /*    This function sends a confirm request to the server for the Client  */
6449 /*    to know the DHCPv6 IP address already assigned to it by the server. */
6450 /*                                                                        */
6451 /*    A host application should call this service after a host has been   */
6452 /*    disconnected from the network or powered down to verify its address */
6453 /*    is still valid.                                                     */
6454 /*                                                                        */
6455 /*  INPUT                                                                 */
6456 /*                                                                        */
6457 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
6458 /*                                                                        */
6459 /*  OUTPUT                                                                */
6460 /*                                                                        */
6461 /*    status                             Completion status                */
6462 /*                                                                        */
6463 /*  CALLS                                                                 */
6464 /*                                                                        */
6465 /*    _nx_dhcpv6_request                  Actual DHCPV6 request service   */
6466 /*    tx_timer_activate                   Activate the session timer      */
6467 /*                                                                        */
6468 /*  CALLED BY                                                             */
6469 /*                                                                        */
6470 /*    Application Code                                                    */
6471 /*                                                                        */
6472 /*  RELEASE HISTORY                                                       */
6473 /*                                                                        */
6474 /*    DATE              NAME                      DESCRIPTION             */
6475 /*                                                                        */
6476 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6477 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6478 /*                                            resulting in version 6.1    */
6479 /*                                                                        */
6480 /**************************************************************************/
_nx_dhcpv6_request_confirm(NX_DHCPV6 * dhcpv6_ptr)6481 UINT  _nx_dhcpv6_request_confirm(NX_DHCPV6 *dhcpv6_ptr)
6482 {
6483 
6484 UINT status;
6485 
6486     /* Set the initial and max retransmission timeouts, and max number of retries.  */
6487     dhcpv6_ptr -> nx_dhcpv6_transmission_timeout =  NX_DHCPV6_INIT_CONFIRM_TRANSMISSION_TIMEOUT;
6488     dhcpv6_ptr -> nx_dhcpv6_retransmission_count = 0;
6489 
6490     /* Set the initaial elasped time of DHCPv6 message.  */
6491     dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = 0;
6492 
6493     /* Set the retransmission information(IRT, MRC, MRT, MRD). */
6494     dhcpv6_ptr -> nx_dhcpv6_init_retransmission_timeout = NX_DHCPV6_INIT_CONFIRM_TRANSMISSION_TIMEOUT;
6495     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_count = NX_DHCPV6_MAX_CONFIRM_RETRANSMISSION_COUNT;
6496     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_timeout = NX_DHCPV6_MAX_CONFIRM_RETRANSMISSION_TIMEOUT;
6497     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_duration = NX_DHCPV6_MAX_CONFIRM_RETRANSMISSION_DURATION;
6498 
6499     /* Activate the session timer to update the elapsed time.  */
6500     tx_timer_activate(&dhcpv6_ptr -> nx_dhcpv6_session_timer);
6501 
6502     /* Call the internal function. */
6503     status = _nx_dhcpv6_request(dhcpv6_ptr, NX_DHCPV6_STATE_SENDING_CONFIRM);
6504 
6505     /* Return completion status. */
6506     return status;
6507 }
6508 
6509 
6510 /**************************************************************************/
6511 /*                                                                        */
6512 /*  FUNCTION                                               RELEASE        */
6513 /*                                                                        */
6514 /*    _nx_dhcpv6_request_decline                          PORTABLE C      */
6515 /*                                                           6.1          */
6516 /*  AUTHOR                                                                */
6517 /*                                                                        */
6518 /*    Yuxin Zhou, Microsoft Corporation                                   */
6519 /*                                                                        */
6520 /*  DESCRIPTION                                                           */
6521 /*                                                                        */
6522 /*    This function sends a decline request to the server for the Client  */
6523 /*    to tell the server it does not accept the assigned address.         */
6524 /*                                                                        */
6525 /*  INPUT                                                                 */
6526 /*                                                                        */
6527 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
6528 /*                                                                        */
6529 /*  OUTPUT                                                                */
6530 /*                                                                        */
6531 /*    status                             Completion status                */
6532 /*                                                                        */
6533 /*  CALLS                                                                 */
6534 /*                                                                        */
6535 /*    _nx_dhcpv6_request                 Actual DHCPV6 request service    */
6536 /*    tx_timer_activate                   Activate the session timer      */
6537 /*                                                                        */
6538 /*  CALLED BY                                                             */
6539 /*                                                                        */
6540 /*    _nx_dhcpv6_process                 Processes server replies to      */
6541 /*                                          DHCPv6 Client requests        */
6542 /*                                                                        */
6543 /*  RELEASE HISTORY                                                       */
6544 /*                                                                        */
6545 /*    DATE              NAME                      DESCRIPTION             */
6546 /*                                                                        */
6547 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6548 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6549 /*                                            resulting in version 6.1    */
6550 /*                                                                        */
6551 /**************************************************************************/
_nx_dhcpv6_request_decline(NX_DHCPV6 * dhcpv6_ptr)6552 UINT  _nx_dhcpv6_request_decline(NX_DHCPV6 *dhcpv6_ptr)
6553 {
6554 
6555 UINT    status;
6556 UINT    ia_index;
6557 
6558     /* Set the initial and max retransmission timeout and max number of retries.  */
6559     dhcpv6_ptr -> nx_dhcpv6_transmission_timeout =  NX_DHCPV6_INIT_DECLINE_TRANSMISSION_TIMEOUT;
6560     dhcpv6_ptr -> nx_dhcpv6_retransmission_count = 0;
6561 
6562     /* Set the initaial elasped time of DHCPv6 message.  */
6563     dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = 0;
6564 
6565     /* Set the retransmission information(IRT, MRC, MRT, MRD). */
6566     dhcpv6_ptr -> nx_dhcpv6_init_retransmission_timeout = NX_DHCPV6_INIT_DECLINE_TRANSMISSION_TIMEOUT;
6567     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_count = NX_DHCPV6_MAX_DECLINE_RETRANSMISSION_COUNT;
6568     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_timeout = NX_DHCPV6_MAX_DECLINE_RETRANSMISSION_TIMEOUT;
6569     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_duration = NX_DHCPV6_MAX_DECLINE_RETRANSMISSION_DURATION;
6570 
6571     /* Activate the session timer to update the elapsed time.  */
6572     tx_timer_activate(&dhcpv6_ptr -> nx_dhcpv6_session_timer);
6573 
6574     /* Now remove the address from the IP address table,the client MUST NOT use any of the addresses it is declining
6575        as the source address in the Release message or in any subsequently transmitted message, RFC3315,section18.1.7.. */
6576 
6577     /* Set the DHCPv6 Client IPv6 addresses.  */
6578     for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
6579     {
6580 
6581         /* Now remove the address from the IP address table,the client MUST NOT use any of the addresses it is declining
6582         as the source address in the Release message or in any subsequently transmitted message, RFC3315,section18.1.7.. */
6583 
6584         /* Verify we have a valid address index. */
6585         if(dhcpv6_ptr -> nx_dhcpv6_client_address_index[ia_index] >= NX_MAX_IPV6_ADDRESSES)
6586         {
6587 
6588             return NX_INVALID_INTERFACE;
6589         }
6590 
6591         if(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status == NX_DHCPV6_IA_ADDRESS_STATE_DAD_FAILURE)
6592         {
6593             /* Remove the address from the IP instance address table. */
6594 
6595             nxd_ipv6_address_delete(dhcpv6_ptr -> nx_dhcpv6_ip_ptr, dhcpv6_ptr -> nx_dhcpv6_client_address_index[ia_index]);
6596 
6597             /* Record the address index in the Client record. */
6598             dhcpv6_ptr -> nx_dhcpv6_client_address_index[ia_index] = 0xFFFFFFFF;
6599         }
6600     }
6601 
6602     /* Call the internal function and return completion status. */
6603     status = _nx_dhcpv6_request(dhcpv6_ptr, NX_DHCPV6_STATE_SENDING_DECLINE);
6604 
6605     /* Return completion status. */
6606     return status;
6607 }
6608 
6609 
6610 /**************************************************************************/
6611 /*                                                                        */
6612 /*  FUNCTION                                               RELEASE        */
6613 /*                                                                        */
6614 /*    _nxe_dhcpv6_request_inform_request                  PORTABLE C      */
6615 /*                                                           6.1          */
6616 /*  AUTHOR                                                                */
6617 /*                                                                        */
6618 /*    Yuxin Zhou, Microsoft Corporation                                   */
6619 /*                                                                        */
6620 /*  DESCRIPTION                                                           */
6621 /*                                                                        */
6622 /*    This function performs error checking on the NetX DHCPv6 information*/
6623 /*    request service.                                                    */
6624 /*                                                                        */
6625 /*  INPUT                                                                 */
6626 /*                                                                        */
6627 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
6628 /*                                                                        */
6629 /*  OUTPUT                                                                */
6630 /*                                                                        */
6631 /*    status                             Completion status                */
6632 /*    NX_PTR_ERROR                       Invalid pointer input            */
6633 /*                                                                        */
6634 /*                                                                        */
6635 /*  CALLS                                                                 */
6636 /*                                                                        */
6637 /*    _nx_dhcpv6_request_inform_request  Actual DHCPV6 process Inform     */
6638 /*                                          Request request service       */
6639 /*                                                                        */
6640 /*  CALLED BY                                                             */
6641 /*                                                                        */
6642 /*    Application Code                                                    */
6643 /*                                                                        */
6644 /*  RELEASE HISTORY                                                       */
6645 /*                                                                        */
6646 /*    DATE              NAME                      DESCRIPTION             */
6647 /*                                                                        */
6648 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6649 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6650 /*                                            resulting in version 6.1    */
6651 /*                                                                        */
6652 /**************************************************************************/
_nxe_dhcpv6_request_inform_request(NX_DHCPV6 * dhcpv6_ptr)6653 UINT  _nxe_dhcpv6_request_inform_request(NX_DHCPV6 *dhcpv6_ptr)
6654 {
6655 
6656 UINT status;
6657 
6658 
6659     /* Check for invalid pointer input. */
6660     if (!dhcpv6_ptr)
6661     {
6662         return NX_PTR_ERROR;
6663     }
6664 
6665     /* Check for appropriate caller.  */
6666     NX_THREADS_ONLY_CALLER_CHECKING
6667 
6668     /* Call the actual service. */
6669     status = _nx_dhcpv6_request_inform_request(dhcpv6_ptr);
6670 
6671     /* Return completion status. */
6672     return status;
6673 }
6674 
6675 
6676 /**************************************************************************/
6677 /*                                                                        */
6678 /*  FUNCTION                                               RELEASE        */
6679 /*                                                                        */
6680 /*    _nx_dhcpv6_request_inform_request                   PORTABLE C      */
6681 /*                                                           6.1          */
6682 /*  AUTHOR                                                                */
6683 /*                                                                        */
6684 /*    Yuxin Zhou, Microsoft Corporation                                   */
6685 /*                                                                        */
6686 /*  DESCRIPTION                                                           */
6687 /*                                                                        */
6688 /*    This function sends a inform request to the server for the Client   */
6689 /*    to obtain network parameters from any DHCPv6 server on the network. */
6690 /*                                                                        */
6691 /*  INPUT                                                                 */
6692 /*                                                                        */
6693 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
6694 /*                                                                        */
6695 /*  OUTPUT                                                                */
6696 /*                                                                        */
6697 /*    status                             Completion status                */
6698 /*                                                                        */
6699 /*  CALLS                                                                 */
6700 /*                                                                        */
6701 /*    _nx_dhcpv6_request                 Actual DHCPV6 request service    */
6702 /*    tx_timer_activate                  Activate the session timer       */
6703 /*                                                                        */
6704 /*  CALLED BY                                                             */
6705 /*                                                                        */
6706 /*    Application Code                                                    */
6707 /*                                                                        */
6708 /*  RELEASE HISTORY                                                       */
6709 /*                                                                        */
6710 /*    DATE              NAME                      DESCRIPTION             */
6711 /*                                                                        */
6712 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6713 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6714 /*                                            resulting in version 6.1    */
6715 /*                                                                        */
6716 /**************************************************************************/
_nx_dhcpv6_request_inform_request(NX_DHCPV6 * dhcpv6_ptr)6717 UINT  _nx_dhcpv6_request_inform_request(NX_DHCPV6 *dhcpv6_ptr)
6718 {
6719 
6720 UINT status;
6721 
6722 
6723     /* Set the initial and max retransmission timeout and max number of retries.  */
6724     dhcpv6_ptr -> nx_dhcpv6_transmission_timeout =  NX_DHCPV6_INIT_INFORM_TRANSMISSION_TIMEOUT;
6725     dhcpv6_ptr -> nx_dhcpv6_retransmission_count = 0;
6726 
6727     /* Set the initaial elasped time of DHCPv6 message.  */
6728     dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = 0;
6729 
6730     /* Set the retransmission information(IRT, MRC, MRT, MRD). */
6731     dhcpv6_ptr -> nx_dhcpv6_init_retransmission_timeout = NX_DHCPV6_INIT_INFORM_TRANSMISSION_TIMEOUT;
6732     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_count = NX_DHCPV6_MAX_INFORM_RETRANSMISSION_COUNT;
6733     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_timeout = NX_DHCPV6_MAX_INFORM_RETRANSMISSION_TIMEOUT;
6734     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_duration = NX_DHCPV6_MAX_INFORM_RETRANSMISSION_DURATION;
6735 
6736     /* Activate the session timer to update the elapsed time.  */
6737     tx_timer_activate(&dhcpv6_ptr -> nx_dhcpv6_session_timer);
6738 
6739     /* Call the internal function and return completion status. */
6740     status = _nx_dhcpv6_request(dhcpv6_ptr, NX_DHCPV6_STATE_SENDING_INFORM_REQUEST);
6741 
6742     /* Return actual completion status. */
6743     return status;
6744 }
6745 
6746 
6747 /**************************************************************************/
6748 /*                                                                        */
6749 /*  FUNCTION                                               RELEASE        */
6750 /*                                                                        */
6751 /*    _nxe_dhcpv6_request_option_DNS_server               PORTABLE C      */
6752 /*                                                           6.1          */
6753 /*  AUTHOR                                                                */
6754 /*                                                                        */
6755 /*    Yuxin Zhou, Microsoft Corporation                                   */
6756 /*                                                                        */
6757 /*  DESCRIPTION                                                           */
6758 /*                                                                        */
6759 /*    This function performs error checking on the NetX submit and process*/
6760 /*    the DNS server request option from the DHPCv6 Server service.       */
6761 /*                                                                        */
6762 /*  INPUT                                                                 */
6763 /*                                                                        */
6764 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
6765 /*    enable                             Flag indicating if the DNS server*/
6766 /*                                          request enabled or disabled   */
6767 /*  OUTPUT                                                                */
6768 /*                                                                        */
6769 /*    status                             Completion status                */
6770 /*    NX_PTR_ERROR                       Invalid pointer input            */
6771 /*                                                                        */
6772 /*                                                                        */
6773 /*  CALLS                                                                 */
6774 /*                                                                        */
6775 /*    _nx_dhcpv6_request_option_DNS_server                                */
6776 /*                                       Actual DHCPV6 process DNS server */
6777 /*                                                  request service       */
6778 /*                                                                        */
6779 /*  CALLED BY                                                             */
6780 /*                                                                        */
6781 /*    Application Code                                                    */
6782 /*                                                                        */
6783 /*  RELEASE HISTORY                                                       */
6784 /*                                                                        */
6785 /*    DATE              NAME                      DESCRIPTION             */
6786 /*                                                                        */
6787 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6788 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6789 /*                                            resulting in version 6.1    */
6790 /*                                                                        */
6791 /**************************************************************************/
_nxe_dhcpv6_request_option_DNS_server(NX_DHCPV6 * dhcpv6_ptr,UINT enable)6792 UINT  _nxe_dhcpv6_request_option_DNS_server(NX_DHCPV6 *dhcpv6_ptr, UINT enable)
6793 {
6794 
6795 UINT status;
6796 
6797     /* Check for invalid pointer input. */
6798     if (!dhcpv6_ptr)
6799     {
6800 
6801         return NX_PTR_ERROR;
6802     }
6803 
6804     /* Check for appropriate caller.  */
6805     NX_THREADS_ONLY_CALLER_CHECKING
6806 
6807     /* Call the actual service. */
6808     status = _nx_dhcpv6_request_option_DNS_server(dhcpv6_ptr, enable);
6809 
6810     /* Return completion status. */
6811     return status;
6812 }
6813 
6814 
6815 /**************************************************************************/
6816 /*                                                                        */
6817 /*  FUNCTION                                               RELEASE        */
6818 /*                                                                        */
6819 /*    _nx_dhcpv6_request_option_DNS_server                PORTABLE C      */
6820 /*                                                           6.1          */
6821 /*  AUTHOR                                                                */
6822 /*                                                                        */
6823 /*    Yuxin Zhou, Microsoft Corporation                                   */
6824 /*                                                                        */
6825 /*  DESCRIPTION                                                           */
6826 /*                                                                        */
6827 /*    This function enables or disables the DHCPv6 DNS server option.  If */
6828 /*    enabled this option is added to the option list in DHCPv6 messages  */
6829 /*    the Client sends to the server.                                     */
6830 /*                                                                        */
6831 /*  INPUT                                                                 */
6832 /*                                                                        */
6833 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
6834 /*    enable                             Flag indicating if the DNS server*/
6835 /*                                          request enabled or disabled   */
6836 /*                                                                        */
6837 /*  OUTPUT                                                                */
6838 /*                                                                        */
6839 /*    NX_SUCCESS                         Successful completion status     */
6840 /*                                                                        */
6841 /*  CALLS                                                                 */
6842 /*                                                                        */
6843 /*    None                                                                */
6844 /*                                                                        */
6845 /*  CALLED BY                                                             */
6846 /*                                                                        */
6847 /*    Application code                                                    */
6848 /*                                                                        */
6849 /*  RELEASE HISTORY                                                       */
6850 /*                                                                        */
6851 /*    DATE              NAME                      DESCRIPTION             */
6852 /*                                                                        */
6853 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6854 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6855 /*                                            resulting in version 6.1    */
6856 /*                                                                        */
6857 /**************************************************************************/
_nx_dhcpv6_request_option_DNS_server(NX_DHCPV6 * dhcpv6_ptr,UINT enable)6858 UINT  _nx_dhcpv6_request_option_DNS_server(NX_DHCPV6 *dhcpv6_ptr, UINT enable)
6859 {
6860 
6861     /* Are we enabling this feature? */
6862     if (enable == NX_TRUE)
6863     {
6864 
6865         /* Yes, register this option request with the DHCPv6 Client. */
6866         dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request |= (USHORT)NX_DHCPV6_DNS_SERVER_OPTION;
6867     }
6868     else
6869     {
6870 
6871         /* Clear this option request with the DHCPv6 Client. */
6872         dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request &= (USHORT)(~NX_DHCPV6_DNS_SERVER_OPTION);
6873     }
6874 
6875     /* Return successful completion. */
6876     return NX_SUCCESS;
6877 }
6878 
6879 
6880 /**************************************************************************/
6881 /*                                                                        */
6882 /*  FUNCTION                                               RELEASE        */
6883 /*                                                                        */
6884 /*    _nxe_dhcpv6_request_option_domain_name              PORTABLE C      */
6885 /*                                                           6.1          */
6886 /*  AUTHOR                                                                */
6887 /*                                                                        */
6888 /*    Yuxin Zhou, Microsoft Corporation                                   */
6889 /*                                                                        */
6890 /*  DESCRIPTION                                                           */
6891 /*                                                                        */
6892 /*    This function performs error checking on the NetX submit and process*/
6893 /*    the domain name request option from the DHPCv6 Server service.      */
6894 /*                                                                        */
6895 /*  INPUT                                                                 */
6896 /*                                                                        */
6897 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
6898 /*    enable                            Flag indicating if the domain name*/
6899 /*                                          request enabled or disabled   */
6900 /*  OUTPUT                                                                */
6901 /*                                                                        */
6902 /*    status                             Completion status                */
6903 /*    NX_PTR_ERROR                       Invalid pointer input            */
6904 /*                                                                        */
6905 /*                                                                        */
6906 /*  CALLS                                                                 */
6907 /*                                                                        */
6908 /*    _nx_dhcpv6_request_option_time_server                               */
6909 /*                                       Actual DHCPV6 process domain name*/
6910 /*                                                  request service       */
6911 /*                                                                        */
6912 /*  CALLED BY                                                             */
6913 /*                                                                        */
6914 /*    Application Code                                                    */
6915 /*                                                                        */
6916 /*  RELEASE HISTORY                                                       */
6917 /*                                                                        */
6918 /*    DATE              NAME                      DESCRIPTION             */
6919 /*                                                                        */
6920 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6921 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6922 /*                                            resulting in version 6.1    */
6923 /*                                                                        */
6924 /**************************************************************************/
_nxe_dhcpv6_request_option_domain_name(NX_DHCPV6 * dhcpv6_ptr,UINT enable)6925 UINT  _nxe_dhcpv6_request_option_domain_name(NX_DHCPV6 *dhcpv6_ptr, UINT enable)
6926 {
6927 
6928 UINT status;
6929 
6930 
6931     /* Check for invalid pointer input. */
6932     if (!dhcpv6_ptr)
6933     {
6934 
6935         return NX_PTR_ERROR;
6936     }
6937 
6938     /* Check for appropriate caller.  */
6939     NX_THREADS_ONLY_CALLER_CHECKING
6940 
6941     /* Call the actual service. */
6942     status = _nx_dhcpv6_request_option_domain_name(dhcpv6_ptr, enable);
6943 
6944     /* Return completion status. */
6945     return status;
6946 }
6947 
6948 
6949 /**************************************************************************/
6950 /*                                                                        */
6951 /*  FUNCTION                                               RELEASE        */
6952 /*                                                                        */
6953 /*    _nx_dhcpv6_request_option_domain_name               PORTABLE C      */
6954 /*                                                           6.1          */
6955 /*  AUTHOR                                                                */
6956 /*                                                                        */
6957 /*    Yuxin Zhou, Microsoft Corporation                                   */
6958 /*                                                                        */
6959 /*  DESCRIPTION                                                           */
6960 /*                                                                        */
6961 /*    This function enables or disables the DHCPv6 domain name option.  If*/
6962 /*    enabled this option is added to the option list in DHCPv6 messages  */
6963 /*    the Client sends to the server.                                     */
6964 /*                                                                        */
6965 /*  INPUT                                                                 */
6966 /*                                                                        */
6967 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
6968 /*    enable                            Flag indicating if the domain name*/
6969 /*                                          request enabled or disabled   */
6970 /*                                                                        */
6971 /*  OUTPUT                                                                */
6972 /*                                                                        */
6973 /*    NX_SUCCESS                         Successful completion status     */
6974 /*                                                                        */
6975 /*  CALLS                                                                 */
6976 /*                                                                        */
6977 /*    None                                                                */
6978 /*                                                                        */
6979 /*  CALLED BY                                                             */
6980 /*                                                                        */
6981 /*    Application code                                                    */
6982 /*                                                                        */
6983 /*  RELEASE HISTORY                                                       */
6984 /*                                                                        */
6985 /*    DATE              NAME                      DESCRIPTION             */
6986 /*                                                                        */
6987 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6988 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6989 /*                                            resulting in version 6.1    */
6990 /*                                                                        */
6991 /**************************************************************************/
_nx_dhcpv6_request_option_domain_name(NX_DHCPV6 * dhcpv6_ptr,UINT enable)6992 UINT  _nx_dhcpv6_request_option_domain_name(NX_DHCPV6 *dhcpv6_ptr, UINT enable)
6993 {
6994 
6995     /* Are we enabling this feature? */
6996     if (enable == NX_TRUE)
6997     {
6998         /* Yes, register this option request with the DHCPv6 Client. */
6999         dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request |= (USHORT)NX_DHCPV6_DOMAIN_NAME_OPTION;
7000     }
7001     else
7002     {
7003 
7004         /* Clear this option request with the DHCPv6 Client. */
7005         dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request &= (USHORT)(~NX_DHCPV6_DOMAIN_NAME_OPTION);
7006     }
7007 
7008     return NX_SUCCESS;
7009 }
7010 
7011 
7012 /**************************************************************************/
7013 /*                                                                        */
7014 /*  FUNCTION                                               RELEASE        */
7015 /*                                                                        */
7016 /*    _nxe_dhcpv6_request_option_time_server              PORTABLE C      */
7017 /*                                                           6.1          */
7018 /*  AUTHOR                                                                */
7019 /*                                                                        */
7020 /*    Yuxin Zhou, Microsoft Corporation                                   */
7021 /*                                                                        */
7022 /*  DESCRIPTION                                                           */
7023 /*                                                                        */
7024 /*    This function performs error checking on the NetX submit and process*/
7025 /*    the time server request option from the DHPCv6 Server service.      */
7026 /*                                                                        */
7027 /*  INPUT                                                                 */
7028 /*                                                                        */
7029 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
7030 /*    enable                            Flag indicating if the time server*/
7031 /*                                          request enabled or disabled   */
7032 /*  OUTPUT                                                                */
7033 /*                                                                        */
7034 /*    status                             Completion status                */
7035 /*    NX_PTR_ERROR                       Invalid pointer input            */
7036 /*                                                                        */
7037 /*                                                                        */
7038 /*  CALLS                                                                 */
7039 /*                                                                        */
7040 /*    _nx_dhcpv6_request_option_time_server                               */
7041 /*                                       Actual DHCPV6 process time server*/
7042 /*                                                  request service       */
7043 /*                                                                        */
7044 /*  CALLED BY                                                             */
7045 /*                                                                        */
7046 /*    Application Code                                                    */
7047 /*                                                                        */
7048 /*  RELEASE HISTORY                                                       */
7049 /*                                                                        */
7050 /*    DATE              NAME                      DESCRIPTION             */
7051 /*                                                                        */
7052 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7053 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7054 /*                                            resulting in version 6.1    */
7055 /*                                                                        */
7056 /**************************************************************************/
_nxe_dhcpv6_request_option_time_server(NX_DHCPV6 * dhcpv6_ptr,UINT enable)7057 UINT  _nxe_dhcpv6_request_option_time_server(NX_DHCPV6 *dhcpv6_ptr, UINT enable)
7058 {
7059 
7060 UINT status;
7061 
7062 
7063     /* Check for invalid pointer input. */
7064     if (!dhcpv6_ptr)
7065     {
7066         return NX_PTR_ERROR;
7067     }
7068 
7069     /* Check for appropriate caller.  */
7070     NX_THREADS_ONLY_CALLER_CHECKING
7071 
7072     /* Call the actual service. */
7073     status = _nx_dhcpv6_request_option_time_server(dhcpv6_ptr, enable);
7074 
7075     /* Return completion status. */
7076     return status;
7077 }
7078 
7079 
7080 /**************************************************************************/
7081 /*                                                                        */
7082 /*  FUNCTION                                               RELEASE        */
7083 /*                                                                        */
7084 /*    _nx_dhcpv6_request_option_time_server               PORTABLE C      */
7085 /*                                                           6.1          */
7086 /*  AUTHOR                                                                */
7087 /*                                                                        */
7088 /*    Yuxin Zhou, Microsoft Corporation                                   */
7089 /*                                                                        */
7090 /*  DESCRIPTION                                                           */
7091 /*                                                                        */
7092 /*    This function enables or disables the DHCPv6 time server option.  If*/
7093 /*    enabled this option is added to the option list in DHCPv6 messages  */
7094 /*    the Client sends to the server.                                     */
7095 /*                                                                        */
7096 /*  INPUT                                                                 */
7097 /*                                                                        */
7098 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
7099 /*    enable                            Flag indicating if the time server*/
7100 /*                                          request enabled or disabled   */
7101 /*                                                                        */
7102 /*  OUTPUT                                                                */
7103 /*                                                                        */
7104 /*    status                             Actual completion status         */
7105 /*    NX_SUCCESS                         Successful completion status     */
7106 /*                                                                        */
7107 /*  CALLS                                                                 */
7108 /*                                                                        */
7109 /*    None                                                                */
7110 /*                                                                        */
7111 /*  CALLED BY                                                             */
7112 /*                                                                        */
7113 /*    Application code                                                    */
7114 /*                                                                        */
7115 /*  RELEASE HISTORY                                                       */
7116 /*                                                                        */
7117 /*    DATE              NAME                      DESCRIPTION             */
7118 /*                                                                        */
7119 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7120 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7121 /*                                            resulting in version 6.1    */
7122 /*                                                                        */
7123 /**************************************************************************/
_nx_dhcpv6_request_option_time_server(NX_DHCPV6 * dhcpv6_ptr,UINT enable)7124 UINT  _nx_dhcpv6_request_option_time_server(NX_DHCPV6 *dhcpv6_ptr, UINT enable)
7125 {
7126 
7127     /* Is the caller requesting the time server option? */
7128     if (enable == NX_TRUE)
7129     {
7130         /* Yes, register this option request with the DHCPv6 Client. */
7131         dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request |= (USHORT)NX_DHCPV6_SNTP_SERVER_OPTION;
7132     }
7133     else
7134     {
7135 
7136         /* Clear this option request with the DHCPv6 Client. */
7137         dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request &= (USHORT)(~NX_DHCPV6_SNTP_SERVER_OPTION);
7138     }
7139 
7140     return NX_SUCCESS;
7141 }
7142 
7143 
7144 /**************************************************************************/
7145 /*                                                                        */
7146 /*  FUNCTION                                               RELEASE        */
7147 /*                                                                        */
7148 /*    _nxe_dhcpv6_request_option_timezone                 PORTABLE C      */
7149 /*                                                           6.1          */
7150 /*  AUTHOR                                                                */
7151 /*                                                                        */
7152 /*    Yuxin Zhou, Microsoft Corporation                                   */
7153 /*                                                                        */
7154 /*  DESCRIPTION                                                           */
7155 /*                                                                        */
7156 /*    This function performs error checking on the NetX submit and process*/
7157 /*    the time zone request option from the DHPCv6 Server service.        */
7158 /*                                                                        */
7159 /*  INPUT                                                                 */
7160 /*                                                                        */
7161 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
7162 /*    enable                            Flag indicating if the time zone  */
7163 /*                                          request enabled or disabled   */
7164 /*  OUTPUT                                                                */
7165 /*                                                                        */
7166 /*    status                             Completion status                */
7167 /*    NX_PTR_ERROR                       Invalid pointer input            */
7168 /*                                                                        */
7169 /*                                                                        */
7170 /*  CALLS                                                                 */
7171 /*                                                                        */
7172 /*   _nx_dhcpv6_request_option_time_zone  Actual DHCPV6 process time zone */
7173 /*                                                  request service       */
7174 /*                                                                        */
7175 /*  CALLED BY                                                             */
7176 /*                                                                        */
7177 /*    Application Code                                                    */
7178 /*                                                                        */
7179 /*  RELEASE HISTORY                                                       */
7180 /*                                                                        */
7181 /*    DATE              NAME                      DESCRIPTION             */
7182 /*                                                                        */
7183 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7184 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7185 /*                                            resulting in version 6.1    */
7186 /*                                                                        */
7187 /**************************************************************************/
_nxe_dhcpv6_request_option_timezone(NX_DHCPV6 * dhcpv6_ptr,UINT enable)7188 UINT  _nxe_dhcpv6_request_option_timezone(NX_DHCPV6 *dhcpv6_ptr, UINT enable)
7189 {
7190 
7191 UINT status;
7192 
7193 
7194     /* Check for invalid pointer input. */
7195     if (!dhcpv6_ptr)
7196     {
7197 
7198         return NX_PTR_ERROR;
7199     }
7200 
7201     /* Check for appropriate caller.  */
7202     NX_THREADS_ONLY_CALLER_CHECKING
7203 
7204     /* Call the actual service. */
7205     status = _nx_dhcpv6_request_option_timezone(dhcpv6_ptr, enable);
7206 
7207     /* Return completion status. */
7208     return status;
7209 }
7210 
7211 
7212 /**************************************************************************/
7213 /*                                                                        */
7214 /*  FUNCTION                                               RELEASE        */
7215 /*                                                                        */
7216 /*    _nx_dhcpv6_request_option_timezone                  PORTABLE C      */
7217 /*                                                           6.1          */
7218 /*  AUTHOR                                                                */
7219 /*                                                                        */
7220 /*    Yuxin Zhou, Microsoft Corporation                                   */
7221 /*                                                                        */
7222 /*  DESCRIPTION                                                           */
7223 /*                                                                        */
7224 /*    This function enables or disables the DHCPv6 time zone option.  If  */
7225 /*    enabled this option is added to the option list in DHCPv6 messages  */
7226 /*    the Client sends to the server.                                     */
7227 /*                                                                        */
7228 /*  INPUT                                                                 */
7229 /*                                                                        */
7230 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
7231 /*    enable                             Flag indicating if the time zone */
7232 /*                                          request enabled or disabled   */
7233 /*                                                                        */
7234 /*  OUTPUT                                                                */
7235 /*                                                                        */
7236 /*    NX_SUCCESS                         Successful completion status     */
7237 /*                                                                        */
7238 /*  CALLS                                                                 */
7239 /*                                                                        */
7240 /*    None                                                                */
7241 /*                                                                        */
7242 /*  CALLED BY                                                             */
7243 /*                                                                        */
7244 /*    Application code                                                    */
7245 /*                                                                        */
7246 /*  RELEASE HISTORY                                                       */
7247 /*                                                                        */
7248 /*    DATE              NAME                      DESCRIPTION             */
7249 /*                                                                        */
7250 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7251 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7252 /*                                            resulting in version 6.1    */
7253 /*                                                                        */
7254 /**************************************************************************/
_nx_dhcpv6_request_option_timezone(NX_DHCPV6 * dhcpv6_ptr,UINT enable)7255 UINT  _nx_dhcpv6_request_option_timezone(NX_DHCPV6 *dhcpv6_ptr, UINT enable)
7256 {
7257 
7258     /* Are we enabling this feature? */
7259     if (enable == NX_TRUE)
7260     {
7261         /* Yes, register this option request with the DHCPv6 Client. */
7262         dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request |= NX_DHCPV6_NEW_POSIX_TIMEZONE_OPTION;
7263     }
7264     else
7265     {
7266 
7267         /* Clear this option request with the DHCPv6 Client. */
7268         dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request &= (USHORT)(~NX_DHCPV6_NEW_POSIX_TIMEZONE_OPTION);
7269     }
7270 
7271     return NX_SUCCESS;
7272 }
7273 
7274 
7275 
7276 /**************************************************************************/
7277 /*                                                                        */
7278 /*  FUNCTION                                               RELEASE        */
7279 /*                                                                        */
7280 /*    _nxe_dhcpv6_request_option_FQDN                     PORTABLE C      */
7281 /*                                                           6.1          */
7282 /*  AUTHOR                                                                */
7283 /*                                                                        */
7284 /*    Yuxin Zhou, Microsoft Corporation                                   */
7285 /*                                                                        */
7286 /*  DESCRIPTION                                                           */
7287 /*                                                                        */
7288 /*    This function performs error checking on the request fully qualified*/
7289 /*    domain name option service.                                         */
7290 /*                                                                        */
7291 /*  INPUT                                                                 */
7292 /*                                                                        */
7293 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
7294 /*    domain_name                        DHCPv6 CLient domain name        */
7295 /*    op                                 DHCPv6 Client operation          */
7296 /*                                                                        */
7297 /*  OUTPUT                                                                */
7298 /*                                                                        */
7299 /*    status                             Completion status                */
7300 /*    NX_PTR_ERROR                       Invalid pointer input            */
7301 /*                                                                        */
7302 /*                                                                        */
7303 /*  CALLS                                                                 */
7304 /*                                                                        */
7305 /*   _nx_dhcpv6_request_option_FQDN       Actual DHCPv6 process FQDN      */
7306 /*                                                                        */
7307 /*  CALLED BY                                                             */
7308 /*                                                                        */
7309 /*    Application Code                                                    */
7310 /*                                                                        */
7311 /*  RELEASE HISTORY                                                       */
7312 /*                                                                        */
7313 /*    DATE              NAME                      DESCRIPTION             */
7314 /*                                                                        */
7315 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7316 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7317 /*                                            resulting in version 6.1    */
7318 /*                                                                        */
7319 /**************************************************************************/
_nxe_dhcpv6_request_option_FQDN(NX_DHCPV6 * dhcpv6_ptr,CHAR * domain_name,UINT op)7320 UINT  _nxe_dhcpv6_request_option_FQDN(NX_DHCPV6 *dhcpv6_ptr, CHAR *domain_name, UINT op)
7321 {
7322 
7323 UINT status;
7324 
7325 
7326     /* Check for invalid pointer input. */
7327     if ((!dhcpv6_ptr) || (!domain_name))
7328     {
7329         return NX_PTR_ERROR;
7330     }
7331 
7332     /* Check for appropriate caller.  */
7333     NX_THREADS_ONLY_CALLER_CHECKING
7334 
7335     /* Call the actual service. */
7336     status = _nx_dhcpv6_request_option_FQDN(dhcpv6_ptr, domain_name, op);
7337 
7338     /* Return completion status. */
7339     return status;
7340 }
7341 
7342 
7343 /**************************************************************************/
7344 /*                                                                        */
7345 /*  FUNCTION                                               RELEASE        */
7346 /*                                                                        */
7347 /*    _nx_dhcpv6_request_option_FQDN                      PORTABLE C      */
7348 /*                                                           6.1          */
7349 /*  AUTHOR                                                                */
7350 /*                                                                        */
7351 /*    Yuxin Zhou, Microsoft Corporation                                   */
7352 /*                                                                        */
7353 /*  DESCRIPTION                                                           */
7354 /*                                                                        */
7355 /*    This function processes the DHCPv6 Client fully qualified domain    */
7356 /*    name. DHCPv6 Client sends this option to indicate if the server     */
7357 /*    SHOULD or SHOULD NOT perform the AAAA RR or DNS updates.            */
7358 /*                                                                        */
7359 /*  INPUT                                                                 */
7360 /*                                                                        */
7361 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
7362 /*    domain_name                        DHCPv6 CLient domain name        */
7363 /*    op                                 DHCPv6 Client operation          */
7364 /*                                                                        */
7365 /*  OUTPUT                                                                */
7366 /*                                                                        */
7367 /*    NX_SUCCESS                         Successful completion status     */
7368 /*                                                                        */
7369 /*  CALLS                                                                 */
7370 /*                                                                        */
7371 /*    None                                                                */
7372 /*                                                                        */
7373 /*  CALLED BY                                                             */
7374 /*                                                                        */
7375 /*    Application code                                                    */
7376 /*                                                                        */
7377 /*  RELEASE HISTORY                                                       */
7378 /*                                                                        */
7379 /*    DATE              NAME                      DESCRIPTION             */
7380 /*                                                                        */
7381 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7382 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7383 /*                                            resulting in version 6.1    */
7384 /*                                                                        */
7385 /**************************************************************************/
_nx_dhcpv6_request_option_FQDN(NX_DHCPV6 * dhcpv6_ptr,CHAR * domain_name,UINT op)7386 UINT  _nx_dhcpv6_request_option_FQDN(NX_DHCPV6 *dhcpv6_ptr, CHAR *domain_name, UINT op)
7387 {
7388 UINT name_length;
7389 
7390     /* Set the Client FQDN option code.  */
7391     dhcpv6_ptr -> nx_dhcpv6_client_FQDN.nx_op_code = NX_DHCPV6_OP_CLIENT_FQDN;
7392 
7393     /* Check domain name lengrh. The total length of a domain name is restricted to 255 octets or less. RFC1035.  */
7394     if (_nx_utility_string_length_check(domain_name, &name_length, NX_DHCPV6_MAX_NAME_SIZE))
7395     {
7396         return(NX_DHCPV6_PARAM_ERROR);
7397     }
7398 
7399     /* Set the Client FQDN option length. 1 + length of domain name(domain name length + label + terminator) .  */
7400     dhcpv6_ptr -> nx_dhcpv6_client_FQDN.nx_op_length = (USHORT)(1 + name_length + 2);
7401 
7402     /* Set the Client fully qualified domain name.  */
7403     dhcpv6_ptr -> nx_dhcpv6_client_FQDN.nx_domain_name = domain_name;
7404 
7405     /* Flags Field.
7406        0 1 2 3 4 5 6 7
7407        +-+-+-+-+-+-+-+-+
7408        |  MBZ    |N|O|S|
7409        +-+-+-+-+-+-+-+-+
7410     */
7411 
7412     /* Set the flags.  */
7413     if (op == NX_DHCPV6_CLIENT_DESIRES_UPDATE_AAAA_RR)
7414     {
7415 
7416         /* DHCPv6 Client chooses to update the FQDN-to-IPv6 address mapping for FQDN and address(es) used by the Cslient.
7417            Set the "S", "O" and "N" bits as 0.  */
7418         dhcpv6_ptr -> nx_dhcpv6_client_FQDN.nx_flags = 0x00;
7419     }
7420     else if (op == NX_DHCPV6_CLIENT_DESIRES_SERVER_DO_DNS_UPDATE)
7421     {
7422 
7423         /* DHCPv6 Client chooses to update the FQDN-to-IPv6 address mapping for FQDN and address(es) used by the Client to the Server.
7424            Set the "S" bit as 1, Set "O" and "N" bits as 0.  */
7425         dhcpv6_ptr -> nx_dhcpv6_client_FQDN.nx_flags = 0x01;
7426     }
7427     else
7428     {
7429 
7430         /* DHCPv6 Client choose to request that the Server perform no DNS updates on its behalf.
7431            Set the "N" bit as 1, Set "O" and "S" bits as 0.  */
7432         dhcpv6_ptr -> nx_dhcpv6_client_FQDN.nx_flags = 0x04;
7433     }
7434 
7435     /* Yes, register this option request with the DHCPv6 Client. */
7436     dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request |= NX_DHCPV6_CLIENT_FQDN_OPTION;
7437 
7438     return NX_SUCCESS;
7439 }
7440 
7441 
7442 /**************************************************************************/
7443 /*                                                                        */
7444 /*  FUNCTION                                               RELEASE        */
7445 /*                                                                        */
7446 /*    _nx_dhcpv6_request_rebind                           PORTABLE C      */
7447 /*                                                           6.1          */
7448 /*  AUTHOR                                                                */
7449 /*                                                                        */
7450 /*    Yuxin Zhou, Microsoft Corporation                                   */
7451 /*                                                                        */
7452 /*  DESCRIPTION                                                           */
7453 /*                                                                        */
7454 /*    This function sends a rebind request to the server for the Client to*/
7455 /*    obtain or rebind an IP address with a DHCPv6 server on the network. */
7456 /*                                                                        */
7457 /*    Note: the Client thread task will detect when it is time to rebind  */
7458 /*    the Client IP address and call the expired address handler if one is*/
7459 /*    set.  The expired address handler is where the host should call this*/
7460 /*    service from.                                                       */
7461 /*                                                                        */
7462 /*  INPUT                                                                 */
7463 /*                                                                        */
7464 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
7465 /*                                                                        */
7466 /*  OUTPUT                                                                */
7467 /*                                                                        */
7468 /*    NX_SUCCESS                         Rebind already initiated         */
7469 /*    status                             Completion status                */
7470 /*                                                                        */
7471 /*  CALLS                                                                 */
7472 /*                                                                        */
7473 /*    _nx_dhcpv6_request                 Actual DHCPV6 request service    */
7474 /*    tx_timer_activate                  Activate the session timer       */
7475 /*                                                                        */
7476 /*  CALLED BY                                                             */
7477 /*                                                                        */
7478 /*    Application Code                                                    */
7479 /*    _nx_dhcpv6_thread_entry            DHCPv6 Client thread task        */
7480 /*                                                                        */
7481 /*  RELEASE HISTORY                                                       */
7482 /*                                                                        */
7483 /*    DATE              NAME                      DESCRIPTION             */
7484 /*                                                                        */
7485 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7486 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7487 /*                                            resulting in version 6.1    */
7488 /*                                                                        */
7489 /**************************************************************************/
_nx_dhcpv6_request_rebind(NX_DHCPV6 * dhcpv6_ptr)7490 UINT  _nx_dhcpv6_request_rebind(NX_DHCPV6 *dhcpv6_ptr)
7491 {
7492 
7493 UINT    status;
7494 UINT    ia_index;
7495 UINT    max_valid_lifetime = 0;
7496 
7497 
7498     /* Is the Client state set to REBIND yet? */
7499     if (dhcpv6_ptr -> nx_dhcpv6_state == NX_DHCPV6_STATE_SENDING_REBIND)
7500     {
7501 
7502         /* Yes, the rebind process is already started. No need to re-request it.
7503            Also must not zero out retry count or reset timeout back to starting value. */
7504         return NX_SUCCESS;
7505     }
7506 
7507 
7508     /* Set the initial and max retransmission timeouts and max number of retries. */
7509     dhcpv6_ptr -> nx_dhcpv6_transmission_timeout =  NX_DHCPV6_INIT_REBIND_TRANSMISSION_TIMEOUT;
7510     dhcpv6_ptr -> nx_dhcpv6_retransmission_count = 0;
7511 
7512     /* Set the initaial elasped time of DHCPv6 message.  */
7513     dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = 0;
7514 
7515     /* Set the retransmission information(IRT, MRC, MRT, MRD). */
7516     dhcpv6_ptr -> nx_dhcpv6_init_retransmission_timeout = NX_DHCPV6_INIT_REBIND_TRANSMISSION_TIMEOUT;
7517     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_count = NX_DHCPV6_MAX_REBIND_RETRANSMISSION_COUNT;
7518     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_timeout = NX_DHCPV6_MAX_REBIND_RETRANSMISSION_TIMEOUT;
7519 
7520     /* Find the max valid lifetime.  */
7521     for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
7522     {
7523 
7524         /* Check the address status.  */
7525         if((dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status == NX_DHCPV6_IA_ADDRESS_STATE_VALID) &&
7526            (dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_valid_lifetime > max_valid_lifetime))
7527         {
7528 
7529             /* Find the max valid lifetime of all IAs.  */
7530             max_valid_lifetime = dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_valid_lifetime;
7531         }
7532     }
7533 
7534     /* Set the max duration time.The message exchange is terminated when the valid lifetimes of all the addresses assigned to the IA expire,
7535        RFC3315, Section18.1.4, Page43.  */
7536     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_duration = max_valid_lifetime;
7537 
7538     /* Activate the session timer to update the elapsed time.  */
7539     tx_timer_activate(&dhcpv6_ptr -> nx_dhcpv6_session_timer);
7540 
7541     /* Call the internal function and return completion status. */
7542     status = _nx_dhcpv6_request(dhcpv6_ptr, NX_DHCPV6_STATE_SENDING_REBIND);
7543 
7544     /* Return the actual completion status. */
7545     return status;
7546 }
7547 
7548 
7549 /**************************************************************************/
7550 /*                                                                        */
7551 /*  FUNCTION                                               RELEASE        */
7552 /*                                                                        */
7553 /*    _nxe_dhcpv6_request_release                         PORTABLE C      */
7554 /*                                                           6.1          */
7555 /*  AUTHOR                                                                */
7556 /*                                                                        */
7557 /*    Yuxin Zhou, Microsoft Corporation                                   */
7558 /*                                                                        */
7559 /*  DESCRIPTION                                                           */
7560 /*                                                                        */
7561 /*    This function performs error checking on the NetX DHCPv6 Release    */
7562 /*    request service.                                                    */
7563 /*                                                                        */
7564 /*  INPUT                                                                 */
7565 /*                                                                        */
7566 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
7567 /*                                                                        */
7568 /*  OUTPUT                                                                */
7569 /*                                                                        */
7570 /*    status                             Completion status                */
7571 /*    NX_PTR_ERROR                       Invalid pointer input            */
7572 /*                                                                        */
7573 /*                                                                        */
7574 /*  CALLS                                                                 */
7575 /*                                                                        */
7576 /*    _nx_dhcpv6_request_release         Actual DHCPV6 process Release    */
7577 /*                                             request service            */
7578 /*                                                                        */
7579 /*  CALLED BY                                                             */
7580 /*                                                                        */
7581 /*    Application Code                                                    */
7582 /*                                                                        */
7583 /*  RELEASE HISTORY                                                       */
7584 /*                                                                        */
7585 /*    DATE              NAME                      DESCRIPTION             */
7586 /*                                                                        */
7587 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7588 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7589 /*                                            resulting in version 6.1    */
7590 /*                                                                        */
7591 /**************************************************************************/
_nxe_dhcpv6_request_release(NX_DHCPV6 * dhcpv6_ptr)7592 UINT  _nxe_dhcpv6_request_release(NX_DHCPV6 *dhcpv6_ptr)
7593 {
7594 
7595 UINT status;
7596 
7597     /* Check for invalid pointer input. */
7598     if (!dhcpv6_ptr)
7599     {
7600         return NX_PTR_ERROR;
7601     }
7602 
7603     /* Check for appropriate caller.  */
7604     NX_THREADS_ONLY_CALLER_CHECKING
7605 
7606     /* Call the actual service. */
7607     status = _nx_dhcpv6_request_release(dhcpv6_ptr);
7608 
7609     /* Return completion status. */
7610     return status;
7611 }
7612 
7613 
7614 /**************************************************************************/
7615 /*                                                                        */
7616 /*  FUNCTION                                               RELEASE        */
7617 /*                                                                        */
7618 /*    _nx_dhcpv6_request_release                          PORTABLE C      */
7619 /*                                                           6.1          */
7620 /*  AUTHOR                                                                */
7621 /*                                                                        */
7622 /*    Yuxin Zhou, Microsoft Corporation                                   */
7623 /*                                                                        */
7624 /*  DESCRIPTION                                                           */
7625 /*                                                                        */
7626 /*    This function sends a release request to the server for the Client  */
7627 /*    to release a assigned IP address back to the DHCPv6 server who      */
7628 /*    previously assigned it.                                             */
7629 /*                                                                        */
7630 /*  INPUT                                                                 */
7631 /*                                                                        */
7632 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
7633 /*                                                                        */
7634 /*  OUTPUT                                                                */
7635 /*                                                                        */
7636 /*    status                             Actual completion status         */
7637 /*    NX_DHCPV6_IA_ADDRESS_NOT_VALID     Client not assigned an address   */
7638 /*                                                                        */
7639 /*  CALLS                                                                 */
7640 /*                                                                        */
7641 /*    _nx_dhcpv6_request                  Actual DHCPV6 request service   */
7642 /*    tx_timer_activate                  Activate the session timer       */
7643 /*                                                                        */
7644 /*  CALLED BY                                                             */
7645 /*                                                                        */
7646 /*    Application Code                                                    */
7647 /*                                                                        */
7648 /*  RELEASE HISTORY                                                       */
7649 /*                                                                        */
7650 /*    DATE              NAME                      DESCRIPTION             */
7651 /*                                                                        */
7652 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7653 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7654 /*                                            resulting in version 6.1    */
7655 /*                                                                        */
7656 /**************************************************************************/
_nx_dhcpv6_request_release(NX_DHCPV6 * dhcpv6_ptr)7657 UINT  _nx_dhcpv6_request_release(NX_DHCPV6 *dhcpv6_ptr)
7658 {
7659 
7660 UINT    status;
7661 UINT    ia_index;
7662 
7663     /* Check if the Client is bound to an assigned address. */
7664     if((dhcpv6_ptr -> nx_dhcpv6_state != NX_DHCPV6_STATE_BOUND_TO_ADDRESS) &&
7665        (dhcpv6_ptr -> nx_dhcpv6_state != NX_DHCPV6_STATE_SENDING_RENEW) &&
7666        (dhcpv6_ptr -> nx_dhcpv6_state != NX_DHCPV6_STATE_SENDING_REBIND))
7667     {
7668 
7669         /* It is not. The host application should use the nx_dhcpv6_stop if the DHCP Client
7670            has simply failed to obtain an IP address from the server instead. */
7671 
7672         /* Benign error so return successful outcome. */
7673         return NX_DHCPV6_IA_ADDRESS_NOT_VALID;
7674     }
7675 
7676     /* Set the initial and max retransmission timeouts and max number of retries.  */
7677     dhcpv6_ptr -> nx_dhcpv6_transmission_timeout =  NX_DHCPV6_INIT_RELEASE_TRANSMISSION_TIMEOUT;
7678     dhcpv6_ptr -> nx_dhcpv6_retransmission_count = 0;
7679 
7680     /* Set the initaial elasped time of DHCPv6 message.  */
7681     dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = 0;
7682 
7683     /* Set the retransmission information(IRT, MRC, MRT, MRD). */
7684     dhcpv6_ptr -> nx_dhcpv6_init_retransmission_timeout = NX_DHCPV6_INIT_RELEASE_TRANSMISSION_TIMEOUT;
7685     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_count = NX_DHCPV6_MAX_RELEASE_RETRANSMISSION_COUNT;
7686     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_timeout = NX_DHCPV6_MAX_RELEASE_RETRANSMISSION_TIMEOUT;
7687     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_duration = NX_DHCPV6_MAX_RELEASE_RETRANSMISSION_DURATION;
7688 
7689     /* Activate the session timer to update the elapsed time.  */
7690     tx_timer_activate(&dhcpv6_ptr -> nx_dhcpv6_session_timer);
7691 
7692     /* Set the DHCPv6 Client IPv6 addresses.  */
7693     for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
7694     {
7695 
7696         /* Now remove the address from the IP address table,the client MUST NOT use any of the addresses it is declining
7697         as the source address in the Release message or in any subsequently transmitted message, RFC3315,section18.1.7.. */
7698 
7699         /* Verify we have a valid address index. */
7700         if(dhcpv6_ptr -> nx_dhcpv6_client_address_index[ia_index] >= NX_MAX_IPV6_ADDRESSES)
7701         {
7702 
7703             return NX_INVALID_INTERFACE;
7704         }
7705 
7706         if(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_op_code)
7707         {
7708             /* Remove the address from the IP instance address table. */
7709 
7710             nxd_ipv6_address_delete(dhcpv6_ptr -> nx_dhcpv6_ip_ptr, dhcpv6_ptr -> nx_dhcpv6_client_address_index[ia_index]);
7711 
7712             /* Record the address index in the Client record. */
7713             dhcpv6_ptr -> nx_dhcpv6_client_address_index[ia_index] = 0xFFFFFFFF;
7714         }
7715     }
7716 
7717     /* Call the internal function and return completion status. */
7718     status = _nx_dhcpv6_request(dhcpv6_ptr, NX_DHCPV6_STATE_SENDING_RELEASE);
7719 
7720     /* Return completion status. */
7721     return status;
7722 }
7723 
7724 
7725 /**************************************************************************/
7726 /*                                                                        */
7727 /*  FUNCTION                                               RELEASE        */
7728 /*                                                                        */
7729 /*    _nx_dhcpv6_request_renew                            PORTABLE C      */
7730 /*                                                           6.1          */
7731 /*  AUTHOR                                                                */
7732 /*                                                                        */
7733 /*    Yuxin Zhou, Microsoft Corporation                                   */
7734 /*                                                                        */
7735 /*  DESCRIPTION                                                           */
7736 /*                                                                        */
7737 /*    This function calls the internal request service to renew the       */
7738 /*    DHCPv6 IP address assigned to it by the server.                     */
7739 /*                                                                        */
7740 /*    Note: the Client thread task will detect when it is time to renew   */
7741 /*    the Client IP address and call the deprecated address handler if one*/
7742 /*    is set.  The deprecated address handler is where the host should    */
7743 /*    call this service from.                                             */
7744 /*                                                                        */
7745 /*  INPUT                                                                 */
7746 /*                                                                        */
7747 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
7748 /*                                                                        */
7749 /*  OUTPUT                                                                */
7750 /*                                                                        */
7751 /*    NX_SUCCESS                         Renew already initiated          */
7752 /*    status                             Completion status                */
7753 /*                                                                        */
7754 /*  CALLS                                                                 */
7755 /*                                                                        */
7756 /*    _nx_dhcpv6_request                 Actual DHCPV6 request service    */
7757 /*    tx_timer_activate                  Activate the session timer       */
7758 /*                                                                        */
7759 /*  CALLED BY                                                             */
7760 /*                                                                        */
7761 /*    Application Code                                                    */
7762 /*    _nx_dhcpv6_thread_entry            DHCPv6 Client thread task        */
7763 /*                                                                        */
7764 /*  RELEASE HISTORY                                                       */
7765 /*                                                                        */
7766 /*    DATE              NAME                      DESCRIPTION             */
7767 /*                                                                        */
7768 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7769 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7770 /*                                            resulting in version 6.1    */
7771 /*                                                                        */
7772 /**************************************************************************/
_nx_dhcpv6_request_renew(NX_DHCPV6 * dhcpv6_ptr)7773 UINT  _nx_dhcpv6_request_renew(NX_DHCPV6 *dhcpv6_ptr)
7774 {
7775 
7776 UINT status;
7777 
7778 
7779     /* Is the Client state set to RENEW yet? */
7780     if (dhcpv6_ptr -> nx_dhcpv6_state == NX_DHCPV6_STATE_SENDING_RENEW)
7781     {
7782 
7783         /* Yes, the renew process is already started. No need to re-request it.
7784            Also must not zero out retry count or reset timeout back to starting value. */
7785         return NX_SUCCESS;
7786     }
7787 
7788     /* Set initial retry and timeout values for sending the Renew request. */
7789     dhcpv6_ptr -> nx_dhcpv6_retransmission_count = 0;
7790     dhcpv6_ptr -> nx_dhcpv6_transmission_timeout =  NX_DHCPV6_INIT_RENEW_TRANSMISSION_TIMEOUT;
7791 
7792     /* Set the initaial elasped time of DHCPv6 message.  */
7793     dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = 0;
7794 
7795     /* Set the retransmission information(IRT, MRC, MRT, MRD). */
7796     dhcpv6_ptr -> nx_dhcpv6_init_retransmission_timeout = NX_DHCPV6_INIT_RENEW_TRANSMISSION_TIMEOUT;
7797     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_count = NX_DHCPV6_MAX_RENEW_RETRANSMISSION_COUNT;
7798     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_timeout = NX_DHCPV6_MAX_RENEW_RETRANSMISSION_TIMEOUT;
7799     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_duration = dhcpv6_ptr -> nx_dhcpv6_iana.nx_T2;
7800 
7801     /* Activate the session timer to update the elapsed time.  */
7802     tx_timer_activate(&dhcpv6_ptr -> nx_dhcpv6_session_timer);
7803 
7804     /* Set the Client to the Renewing state for the DHCP Client thread to process. */
7805     status = _nx_dhcpv6_request(dhcpv6_ptr, NX_DHCPV6_STATE_SENDING_RENEW);
7806 
7807     /* Actual completion status. */
7808     return status;
7809 }
7810 
7811 
7812 /**************************************************************************/
7813 /*                                                                        */
7814 /*  FUNCTION                                               RELEASE        */
7815 /*                                                                        */
7816 /*    _nxe_dhcpv6_request_solicit                         PORTABLE C      */
7817 /*                                                           6.1          */
7818 /*  AUTHOR                                                                */
7819 /*                                                                        */
7820 /*    Yuxin Zhou, Microsoft Corporation                                   */
7821 /*                                                                        */
7822 /*  DESCRIPTION                                                           */
7823 /*                                                                        */
7824 /*    This function performs error checking on the NetX DHCPv6 solicit    */
7825 /*    request service.                                                    */
7826 /*                                                                        */
7827 /*  INPUT                                                                 */
7828 /*                                                                        */
7829 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
7830 /*                                                                        */
7831 /*  OUTPUT                                                                */
7832 /*                                                                        */
7833 /*    status                              Completion status               */
7834 /*    NX_PTR_ERROR                        Invalid pointer input           */
7835 /*                                                                        */
7836 /*                                                                        */
7837 /*  CALLS                                                                 */
7838 /*                                                                        */
7839 /*    _nx_dhcpv6_request_solicit          Actual DHCPV6 process Solicit   */
7840 /*                                             request service            */
7841 /*                                                                        */
7842 /*  CALLED BY                                                             */
7843 /*                                                                        */
7844 /*    Application Code                                                    */
7845 /*                                                                        */
7846 /*  RELEASE HISTORY                                                       */
7847 /*                                                                        */
7848 /*    DATE              NAME                      DESCRIPTION             */
7849 /*                                                                        */
7850 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7851 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7852 /*                                            resulting in version 6.1    */
7853 /*                                                                        */
7854 /**************************************************************************/
_nxe_dhcpv6_request_solicit(NX_DHCPV6 * dhcpv6_ptr)7855 UINT  _nxe_dhcpv6_request_solicit(NX_DHCPV6 *dhcpv6_ptr)
7856 {
7857 
7858 UINT status;
7859 
7860 
7861     /* Check for invalid pointer input. */
7862     if (!dhcpv6_ptr)
7863     {
7864         return NX_PTR_ERROR;
7865     }
7866 
7867     /* Check for appropriate caller.  */
7868     NX_THREADS_ONLY_CALLER_CHECKING
7869 
7870     /* Call the actual service. */
7871     status = _nx_dhcpv6_request_solicit(dhcpv6_ptr);
7872 
7873     /* Return completion status. */
7874     return status;
7875 }
7876 
7877 
7878 /**************************************************************************/
7879 /*                                                                        */
7880 /*  FUNCTION                                               RELEASE        */
7881 /*                                                                        */
7882 /*    _nx_dhcpv6_request_solicit                          PORTABLE C      */
7883 /*                                                           6.1          */
7884 /*  AUTHOR                                                                */
7885 /*                                                                        */
7886 /*    Yuxin Zhou, Microsoft Corporation                                   */
7887 /*                                                                        */
7888 /*  DESCRIPTION                                                           */
7889 /*                                                                        */
7890 /*    This function sends a solicit request for the Client to obtain an IP*/
7891 /*    address from any DHCPv6 server on the network.                      */
7892 /*                                                                        */
7893 /*  INPUT                                                                 */
7894 /*                                                                        */
7895 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
7896 /*                                                                        */
7897 /*  OUTPUT                                                                */
7898 /*                                                                        */
7899 /*    status                             Completion status                */
7900 /*                                                                        */
7901 /*  CALLS                                                                 */
7902 /*                                                                        */
7903 /*    _nx_dhcpv6_request                 Actual DHCPV6 request service    */
7904 /*    tx_timer_activate                  Activate the session timer       */
7905 /*                                                                        */
7906 /*  CALLED BY                                                             */
7907 /*                                                                        */
7908 /*    Application Code                                                    */
7909 /*    _nx_dhcpv6_process                 Send the DHCPv6 solicit message  */
7910 /*                                                                        */
7911 /*  RELEASE HISTORY                                                       */
7912 /*                                                                        */
7913 /*    DATE              NAME                      DESCRIPTION             */
7914 /*                                                                        */
7915 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7916 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7917 /*                                            resulting in version 6.1    */
7918 /*                                                                        */
7919 /**************************************************************************/
_nx_dhcpv6_request_solicit(NX_DHCPV6 * dhcpv6_ptr)7920 UINT  _nx_dhcpv6_request_solicit(NX_DHCPV6 *dhcpv6_ptr)
7921 {
7922 
7923 UINT status;
7924 
7925 
7926     /* Set the mode of sending the solicit message.  Do not override a rapid option if set. */
7927     if (dhcpv6_ptr ->nx_dhcpv6_request_solicit_mode != NX_DHCPV6_SOLICIT_RAPID)
7928     {
7929 
7930         /* Set the mode of sending the solicit message.  */
7931         dhcpv6_ptr -> nx_dhcpv6_request_solicit_mode = NX_DHCPV6_SOLICIT_NORMAL;
7932     }
7933 
7934     /* Set the initial and maximum timeout and retries.  */
7935     dhcpv6_ptr -> nx_dhcpv6_transmission_timeout =  NX_DHCPV6_INIT_SOL_TRANSMISSION_TIMEOUT;
7936     dhcpv6_ptr -> nx_dhcpv6_retransmission_count = 0;
7937 
7938     /* Set the initaial elasped time of DHCPv6 message.  */
7939     dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = 0;
7940 
7941     /* Set the retransmission information(IRT, MRC, MRT, MRD). */
7942     dhcpv6_ptr -> nx_dhcpv6_init_retransmission_timeout = NX_DHCPV6_INIT_SOL_TRANSMISSION_TIMEOUT;
7943     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_count = NX_DHCPV6_MAX_SOL_RETRANSMISSION_COUNT;
7944     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_timeout = NX_DHCPV6_MAX_SOL_RETRANSMISSION_TIMEOUT;
7945     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_duration = NX_DHCPV6_MAX_SOL_RETRANSMISSION_DURATION;
7946 
7947     /* Reset the preference value if the Client previously accepted an Advertise message. */
7948     dhcpv6_ptr -> nx_dhcpv6_preference.nx_pref_value = 0;
7949 
7950     /* Activate the session timer to update the elapsed time.  */
7951     tx_timer_activate(&dhcpv6_ptr -> nx_dhcpv6_session_timer);
7952 
7953     /* Set the Client to the Solicity state for the DHCP Client thread to process. */
7954     status = _nx_dhcpv6_request(dhcpv6_ptr, NX_DHCPV6_STATE_SENDING_SOLICIT);
7955 
7956     /* Return the completion status. */
7957     return status;
7958 }
7959 
7960 
7961 /**************************************************************************/
7962 /*                                                                        */
7963 /*  FUNCTION                                               RELEASE        */
7964 /*                                                                        */
7965 /*    _nxe_dhcpv6_request_solicit_rapid                   PORTABLE C      */
7966 /*                                                           6.1          */
7967 /*  AUTHOR                                                                */
7968 /*                                                                        */
7969 /*    Yuxin Zhou, Microsoft Corporation                                   */
7970 /*                                                                        */
7971 /*  DESCRIPTION                                                           */
7972 /*                                                                        */
7973 /*    This function performs error checking on the NetX DHCPv6 solicit    */
7974 /*    request service with rapid commit option.                           */
7975 /*                                                                        */
7976 /*  INPUT                                                                 */
7977 /*                                                                        */
7978 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
7979 /*                                                                        */
7980 /*  OUTPUT                                                                */
7981 /*                                                                        */
7982 /*    status                              Completion status               */
7983 /*    NX_PTR_ERROR                        Invalid pointer input           */
7984 /*                                                                        */
7985 /*                                                                        */
7986 /*  CALLS                                                                 */
7987 /*                                                                        */
7988 /*    _nx_dhcpv6_request_solicit_rapid    Actual DHCPV6 process Solicit   */
7989 /*                                             request service            */
7990 /*                                                                        */
7991 /*  CALLED BY                                                             */
7992 /*                                                                        */
7993 /*    Application Code                                                    */
7994 /*                                                                        */
7995 /*  RELEASE HISTORY                                                       */
7996 /*                                                                        */
7997 /*    DATE              NAME                      DESCRIPTION             */
7998 /*                                                                        */
7999 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8000 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8001 /*                                            resulting in version 6.1    */
8002 /*                                                                        */
8003 /**************************************************************************/
_nxe_dhcpv6_request_solicit_rapid(NX_DHCPV6 * dhcpv6_ptr)8004 UINT  _nxe_dhcpv6_request_solicit_rapid(NX_DHCPV6 *dhcpv6_ptr)
8005 {
8006 
8007 UINT status;
8008 
8009 
8010     /* Check for invalid pointer input. */
8011     if (!dhcpv6_ptr)
8012     {
8013         return NX_PTR_ERROR;
8014     }
8015 
8016     /* Check for appropriate caller.  */
8017     NX_THREADS_ONLY_CALLER_CHECKING
8018 
8019     /* Call the actual service. */
8020     status = _nx_dhcpv6_request_solicit_rapid(dhcpv6_ptr);
8021 
8022     /* Return completion status. */
8023     return status;
8024 }
8025 
8026 
8027 /**************************************************************************/
8028 /*                                                                        */
8029 /*  FUNCTION                                               RELEASE        */
8030 /*                                                                        */
8031 /*    _nx_dhcpv6_request_solicit_rapid                    PORTABLE C      */
8032 /*                                                           6.1          */
8033 /*  AUTHOR                                                                */
8034 /*                                                                        */
8035 /*    Yuxin Zhou, Microsoft Corporation                                   */
8036 /*                                                                        */
8037 /*  DESCRIPTION                                                           */
8038 /*                                                                        */
8039 /*    This function sends a solicit request with rapid commit option for  */
8040 /*    the Client to rapidly obtain an IP address from any DHCPv6 server.  */
8041 /*                                                                        */
8042 /*  INPUT                                                                 */
8043 /*                                                                        */
8044 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
8045 /*                                                                        */
8046 /*  OUTPUT                                                                */
8047 /*                                                                        */
8048 /*    status                             Completion status                */
8049 /*                                                                        */
8050 /*  CALLS                                                                 */
8051 /*                                                                        */
8052 /*    _nx_dhcpv6_request                  Actual DHCPV6 request service   */
8053 /*    tx_timer_activate                   Activate the session timer      */
8054 /*                                                                        */
8055 /*  CALLED BY                                                             */
8056 /*                                                                        */
8057 /*    Application Code                                                    */
8058 /*                                                                        */
8059 /*  RELEASE HISTORY                                                       */
8060 /*                                                                        */
8061 /*    DATE              NAME                      DESCRIPTION             */
8062 /*                                                                        */
8063 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8064 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8065 /*                                            resulting in version 6.1    */
8066 /*                                                                        */
8067 /**************************************************************************/
_nx_dhcpv6_request_solicit_rapid(NX_DHCPV6 * dhcpv6_ptr)8068 UINT  _nx_dhcpv6_request_solicit_rapid(NX_DHCPV6 *dhcpv6_ptr)
8069 {
8070 
8071 UINT status;
8072 
8073 
8074     /* Set the mode of sending the solicit message.  */
8075     dhcpv6_ptr ->nx_dhcpv6_request_solicit_mode = NX_DHCPV6_SOLICIT_RAPID;
8076 
8077     /* Set the initial and maximum timeout and retries.  */
8078     dhcpv6_ptr -> nx_dhcpv6_transmission_timeout =  NX_DHCPV6_INIT_SOL_TRANSMISSION_TIMEOUT;
8079     dhcpv6_ptr -> nx_dhcpv6_retransmission_count = 0;
8080 
8081     /* Set the initaial elasped time of DHCPv6 message.  */
8082     dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = 0;
8083 
8084     /* Set the retransmission information(IRT, MRC, MRT, MRD). */
8085     dhcpv6_ptr -> nx_dhcpv6_init_retransmission_timeout = NX_DHCPV6_INIT_SOL_TRANSMISSION_TIMEOUT;
8086     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_count = NX_DHCPV6_MAX_SOL_RETRANSMISSION_COUNT;
8087     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_timeout = NX_DHCPV6_MAX_SOL_RETRANSMISSION_TIMEOUT;
8088     dhcpv6_ptr -> nx_dhcpv6_max_retransmission_duration = NX_DHCPV6_MAX_SOL_RETRANSMISSION_DURATION;
8089 
8090     /* Reset the preference value if the Client previously accepted an Advertise message. */
8091     dhcpv6_ptr -> nx_dhcpv6_preference.nx_pref_value = 0;
8092 
8093     /* Activate the session timer to update the elapsed time.  */
8094     tx_timer_activate(&dhcpv6_ptr -> nx_dhcpv6_session_timer);
8095 
8096     /* Set the Client to the Solicity state for the DHCP Client thread to process. */
8097     status = _nx_dhcpv6_request(dhcpv6_ptr, NX_DHCPV6_STATE_SENDING_SOLICIT);
8098 
8099     /* Return the completion status. */
8100     return status;
8101 }
8102 
8103 
8104 /**************************************************************************/
8105 /*                                                                        */
8106 /*  FUNCTION                                               RELEASE        */
8107 /*                                                                        */
8108 /*    _nxe_dhcpv6_resume                                  PORTABLE C      */
8109 /*                                                           6.1          */
8110 /*  AUTHOR                                                                */
8111 /*                                                                        */
8112 /*    Yuxin Zhou, Microsoft Corporation                                   */
8113 /*                                                                        */
8114 /*  DESCRIPTION                                                           */
8115 /*                                                                        */
8116 /*    This function performs error checking on the resume NetX DHCPv6     */
8117 /*    client task service.                                                */
8118 /*                                                                        */
8119 /*  INPUT                                                                 */
8120 /*                                                                        */
8121 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
8122 /*                                                                        */
8123 /*  OUTPUT                                                                */
8124 /*                                                                        */
8125 /*  OUTPUT                                                                */
8126 /*                                                                        */
8127 /*    status                              Completion status               */
8128 /*    NX_PTR_ERROR                        Invalid pointer input           */
8129 /*                                                                        */
8130 /*  CALLS                                                                 */
8131 /*                                                                        */
8132 /*    _nx_dhcpv6_resume                   Actual DHCPV6 resume function   */
8133 /*                                                                        */
8134 /*  CALLED BY                                                             */
8135 /*                                                                        */
8136 /*    Application Code                                                    */
8137 /*                                                                        */
8138 /*  RELEASE HISTORY                                                       */
8139 /*                                                                        */
8140 /*    DATE              NAME                      DESCRIPTION             */
8141 /*                                                                        */
8142 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8143 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8144 /*                                            resulting in version 6.1    */
8145 /*                                                                        */
8146 /**************************************************************************/
_nxe_dhcpv6_resume(NX_DHCPV6 * dhcpv6_ptr)8147  UINT  _nxe_dhcpv6_resume(NX_DHCPV6 *dhcpv6_ptr)
8148 {
8149 
8150 UINT    status;
8151 
8152 
8153     /* Check for invalid input pointer.  */
8154     if ((dhcpv6_ptr == NX_NULL) || (dhcpv6_ptr -> nx_dhcpv6_id != NX_DHCPV6_ID))
8155     {
8156         return(NX_PTR_ERROR);
8157     }
8158 
8159     /* Check for appropriate caller.  */
8160     NX_THREADS_ONLY_CALLER_CHECKING
8161 
8162     /* Call actual DHCPV6 stop service.  */
8163     status =  _nx_dhcpv6_resume(dhcpv6_ptr);
8164 
8165     /* Return status.  */
8166     return(status);
8167 }
8168 
8169 
8170 /**************************************************************************/
8171 /*                                                                        */
8172 /*  FUNCTION                                               RELEASE        */
8173 /*                                                                        */
8174 /*    _nx_dhcpv6_resume                                   PORTABLE C      */
8175 /*                                                           6.1          */
8176 /*  AUTHOR                                                                */
8177 /*                                                                        */
8178 /*    Yuxin Zhou, Microsoft Corporation                                   */
8179 /*                                                                        */
8180 /*  DESCRIPTION                                                           */
8181 /*                                                                        */
8182 /*    This function resumes DHCPV6 processing thread and updates the      */
8183 /*    DHCPv6 client state according to nx_dhcpv6_IP_lifetime_time_accrued.*/
8184 /*                                                                        */
8185 /*  INPUT                                                                 */
8186 /*                                                                        */
8187 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
8188 /*                                                                        */
8189 /*  OUTPUT                                                                */
8190 /*                                                                        */
8191 /*    status                             Actual completion status         */
8192 /*                                                                        */
8193 /*  CALLS                                                                 */
8194 /*                                                                        */
8195 /*    nx_dhcpv6_start                    Starts DHCPV6 thread task        */
8196 /*                                                                        */
8197 /*  CALLED BY                                                             */
8198 /*                                                                        */
8199 /*    Application Code                                                    */
8200 /*                                                                        */
8201 /*  RELEASE HISTORY                                                       */
8202 /*                                                                        */
8203 /*    DATE              NAME                      DESCRIPTION             */
8204 /*                                                                        */
8205 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8206 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8207 /*                                            resulting in version 6.1    */
8208 /*                                                                        */
8209 /**************************************************************************/
_nx_dhcpv6_resume(NX_DHCPV6 * dhcpv6_ptr)8210 UINT  _nx_dhcpv6_resume(NX_DHCPV6 *dhcpv6_ptr)
8211 {
8212 
8213 UINT      status;
8214 UCHAR     original_state;
8215 
8216     /* Get the DHCP mutex.  */
8217     tx_mutex_get(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex), NX_DHCPV6_MUTEX_WAIT);
8218 
8219     /* Determine if DHCPV6 has already been started.  */
8220     if (dhcpv6_ptr -> nx_dhcpv6_started)
8221     {
8222 
8223         /* Release the DHCPv6 Client mutex.  */
8224         tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
8225 
8226         /* Error, the DHCPV6 client has already been started.  */
8227         return(NX_DHCPV6_ALREADY_STARTED);
8228     }
8229 
8230     /* Determine if Client has created its DUID and IANA yet. */
8231     if ((dhcpv6_ptr -> nx_dhcpv6_ip_ptr == NX_NULL)                 ||
8232         (dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_option_length == 0) ||
8233         (dhcpv6_ptr -> nx_dhcpv6_iana.nx_option_length == 0))
8234     {
8235 
8236         /* Release the DHCPv6 Client mutex.  */
8237         tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
8238 
8239         /* No, this DHCPv6 Client is not ready to run! */
8240         return NX_DHCPV6_MISSING_REQUIRED_OPTIONS;
8241     }
8242 
8243     /* Remember the original DHCPv6 state for the changed state callback function.  */
8244     original_state =  dhcpv6_ptr -> nx_dhcpv6_state;
8245 
8246     /* Bind the UDP socket to the DHCPV6 Client port.  */
8247     status =  nx_udp_socket_bind(&(dhcpv6_ptr -> nx_dhcpv6_socket), NX_DHCPV6_CLIENT_UDP_PORT, TX_WAIT_FOREVER);
8248 
8249     /* Check for success */
8250     if (status)
8251     {
8252 
8253         /* Release the DHCPv6 Client mutex.  */
8254         tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
8255 
8256         /* Return completion status.  */
8257         return(status);
8258     }
8259 
8260     /* Check the DHCPv6 Client state. */
8261     if ((dhcpv6_ptr -> nx_dhcpv6_state != NX_DHCPV6_STATE_BOUND_TO_ADDRESS) &&
8262         (dhcpv6_ptr -> nx_dhcpv6_state != NX_DHCPV6_STATE_SENDING_RENEW) &&
8263         (dhcpv6_ptr -> nx_dhcpv6_state != NX_DHCPV6_STATE_SENDING_REBIND))
8264     {
8265 
8266         /* Set the DHCPv6 Client state to Init.*/
8267         dhcpv6_ptr -> nx_dhcpv6_state =  NX_DHCPV6_STATE_INIT;
8268 
8269         /* Clear the session time, lease lifetime, retransmission counters. */
8270         dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = 0;
8271         dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_time_accrued = 0;
8272         dhcpv6_ptr -> nx_dhcpv6_transmission_timeout = 0;
8273         dhcpv6_ptr -> nx_dhcpv6_retransmission_count = 0;
8274     }
8275     else
8276     {
8277 
8278         /* Check the accrued time to upate the state.  */
8279         if ((dhcpv6_ptr -> nx_dhcpv6_state == NX_DHCPV6_STATE_BOUND_TO_ADDRESS) && ((dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_time_accrued >= dhcpv6_ptr -> nx_dhcpv6_iana.nx_T2)))
8280         {
8281 
8282             /* Update the status as NX_DHCPV6_STATE_SENDING_RENEW to send rebinding message in _nx_dhcpv6_thread_entry function.  */
8283             dhcpv6_ptr -> nx_dhcpv6_state = NX_DHCPV6_STATE_SENDING_RENEW;
8284         }
8285     }
8286 
8287 
8288     /* Set the DHCPv6 started flag to indicate DHCPv6 Client is now running.  */
8289     dhcpv6_ptr -> nx_dhcpv6_started =  NX_TRUE;
8290 
8291     /* Activate the DHCPv6 timers.  */
8292     tx_timer_activate(&dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_timer);
8293 
8294     /* Resume the DHCPv6 processing thread.  */
8295     tx_thread_resume(&(dhcpv6_ptr -> nx_dhcpv6_thread));
8296 
8297     /* Is there a state change callback registered with the Client?  */
8298     if ((dhcpv6_ptr -> nx_dhcpv6_state_change_callback) && (original_state != (dhcpv6_ptr -> nx_dhcpv6_state)))
8299     {
8300 
8301         /* Yes, call the the state change callback with the original and new state.  */
8302         (dhcpv6_ptr -> nx_dhcpv6_state_change_callback)(dhcpv6_ptr, original_state, dhcpv6_ptr -> nx_dhcpv6_state);
8303     }
8304 
8305     /* Release the DHCPv6 Client mutex.  */
8306     tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
8307 
8308     /* Return completion status.  */
8309     return(status);
8310 }
8311 
8312 
8313 /**************************************************************************/
8314 /*                                                                        */
8315 /*  FUNCTION                                               RELEASE        */
8316 /*                                                                        */
8317 /*    _nx_dhcpv6_send_request                             PORTABLE C      */
8318 /*                                                           6.1.12       */
8319 /*  AUTHOR                                                                */
8320 /*                                                                        */
8321 /*    Yuxin Zhou, Microsoft Corporation                                   */
8322 /*                                                                        */
8323 /*  DESCRIPTION                                                           */
8324 /*                                                                        */
8325 /*   This function sends a DHCPV6 request to the server.  All options     */
8326 /*   required for each Client DHCPv6 message are compiled into the Client */
8327 /*   request package. Since each message must have a unique transaction   */
8328 /*   ID, it is up to the caller to set the Client transaction ID in the   */
8329 /*   Client record before calling this service.  The server reply must    */
8330 /*   contain the matching message transaction ID for each message type the*/
8331 /*   Client sends it. This function will check for invalid message types. */
8332 /*                                                                        */
8333 /*   To send a message, the Client allocates a packet from its own packet */
8334 /*   pool.  It then must set the IPv6 packet interface depending if the   */
8335 /*   Client has a valid global IP address or is using its link local      */
8336 /*   address till it can get a global IP address.  It can send the packet */
8337 /*   either to all servers on its network or include server and relays    */
8338 /*   (user configurable).                                                 */
8339 /*                                                                        */
8340 /*  INPUT                                                                 */
8341 /*                                                                        */
8342 /*    dhcpv6_ptr                            Pointer to DHCPV6 Client      */
8343 /*                                                                        */
8344 /*  OUTPUT                                                                */
8345 /*                                                                        */
8346 /*    status                                Actual completion status      */
8347 /*    NX_DHCPV6_ILLEGAL_MESSAGE_TYPE        Illegal message type to send  */
8348 /*                                                                        */
8349 /*  CALLS                                                                 */
8350 /*                                                                        */
8351 /*    nx_packet_allocate                    Allocate a DHCPV6 packet      */
8352 /*    nx_packet_release                     Release DHCPV6 packet         */
8353 /*    nx_udp_socket_send                    Send DHCPV6 packet            */
8354 /*   _nx_dhcpv6_add_client_duid             Add Client DUID to request    */
8355 /*   _nx_dhcpv6_add_server_duid             Add server DUID to request    */
8356 /*   _nx_dhcpv6_add_elapsed_time            Add elapsed time option       */
8357 /*   _nx_dhcpv6_add_iana                    Add IANA option to request    */
8358 /*   _nx_dhcpv6_add_ia_address              Add IA address option         */
8359 /*   _nx_dhcpv6_add_option_request          Add option request option     */
8360 /*    memcpy                                Copy specified area of memory */
8361 /*                                                                        */
8362 /*  CALLED BY                                                             */
8363 /*                                                                        */
8364 /*    _nx_dhcpv6_process                   Process DHCPv6 client request  */
8365 /*    _nx_dhcpv6_waiting_on_reply          Process replies to valid server*/
8366 /*                                                 reply received         */
8367 /*  RELEASE HISTORY                                                       */
8368 /*                                                                        */
8369 /*    DATE              NAME                      DESCRIPTION             */
8370 /*                                                                        */
8371 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8372 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
8373 /*                                            packet length verification, */
8374 /*                                            verified memcpy use cases,  */
8375 /*                                            fixed compiler warnings,    */
8376 /*                                            resulting in version 6.1    */
8377 /*  07-29-2022     Yuxin Zhou               Modified comment(s), supported*/
8378 /*                                            adding user options,        */
8379 /*                                            resulting in version 6.1.12 */
8380 /*                                                                        */
8381 /**************************************************************************/
_nx_dhcpv6_send_request(NX_DHCPV6 * dhcpv6_ptr)8382 UINT  _nx_dhcpv6_send_request(NX_DHCPV6 *dhcpv6_ptr)
8383 {
8384 
8385 NX_PACKET   *packet_ptr;
8386 UCHAR       *buffer;
8387 UINT        status;
8388 ULONG       message_word;
8389 UINT        index;
8390 NX_INTERFACE     *interface_ptr;
8391 NXD_IPV6_ADDRESS *ipv6_address;
8392 ULONG             available_payload;
8393 UCHAR            *user_option_ptr;
8394 UINT              user_option_length;
8395 
8396 
8397     /* Initialize local variables. */
8398     index = 0;
8399 
8400     /* Check for invalid or illegal message type. */
8401     if ((dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type == NX_DHCPV6_MESSAGE_TYPE_ADVERTISE)     ||
8402         (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type == NX_DHCPV6_MESSAGE_TYPE_REPLY)         ||
8403         (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type == NX_DHCPV6_MESSAGE_TYPE_RECONFIGURE)   ||
8404         (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type > NX_DHCPV6_MESSAGE_TYPE_INFORM_REQUEST) ||
8405         (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type == 0))
8406     {
8407 
8408         /* Return error status. */
8409         return NX_DHCPV6_ILLEGAL_MESSAGE_TYPE;
8410     }
8411 
8412     /* Allocate a DHCPV6 packet.  */
8413     status =  nx_packet_allocate(dhcpv6_ptr -> nx_dhcpv6_pool_ptr, &packet_ptr, NX_IPv6_UDP_PACKET, NX_DHCPV6_PACKET_TIME_OUT);
8414 
8415     /* Was the packet allocation successful?  */
8416     if (status != NX_SUCCESS)
8417     {
8418 
8419         /* Return status.  */
8420         return(status);
8421     }
8422 
8423     /* Verify packet payload. */
8424     if ((packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < 4)
8425     {
8426         nx_packet_release(packet_ptr);
8427         return(NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD);
8428     }
8429 
8430     /* Indicate this is an IPv6 packet. */
8431     packet_ptr -> nx_packet_ip_version = NX_IP_VERSION_V6;
8432 
8433     /* Setup the buffer pointer.  */
8434     buffer =  packet_ptr -> nx_packet_prepend_ptr;
8435 
8436     /* Use the message id value to judge whether the next packet is retransmit packet or not.
8437        If the id value is 0, indicate the new dhcpv6 request, then generate a random number, else,leave the transaction  ID unchanged.
8438        A client MUST leave the transaction ID unchanged in retransmissions of a message,RFC3315,section 15.1,page 28.  */
8439     if(dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid == 0)
8440     {
8441 
8442         /* Generate "random" transaction ID using physical address and a random factor for each request
8443         to the Server.  The Server must include a matching transaction ID in its reply. */
8444         dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid =
8445             ((dhcpv6_ptr -> nx_dhcpv6_ip_ptr -> nx_ip_arp_physical_address_msw) ^
8446             (dhcpv6_ptr -> nx_dhcpv6_ip_ptr -> nx_ip_arp_physical_address_lsw) ^
8447             (ULONG)(NX_RAND()));
8448 
8449         /* Now reduce it to three bytes. */
8450         dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid = (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid & (ULONG)(0x0ffffff));
8451     }
8452 
8453     /* Clear memory to make the message header. */
8454     memset(&message_word, 0, sizeof(ULONG));
8455 
8456     /* Add the message type and transaction ID as the DHCPv6 header fields. */
8457     message_word = (((ULONG)(dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type)) << 24);
8458 
8459     message_word |= (((ULONG)(0x0ffffff)) & (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid));
8460 
8461     /* Adjust for endianness. */
8462     NX_CHANGE_ULONG_ENDIAN(message_word);
8463 
8464     /* Copy the message header to the packet buffer. */
8465     memcpy(buffer, &message_word, 4); /* Use case of memcpy is verified. */
8466 
8467     /* Update the buffer 'pointer'. */
8468     index += (ULONG)sizeof(ULONG);
8469 
8470     /* Add the Client DUID to the packet buffer. */
8471     status = _nx_dhcpv6_add_client_duid(dhcpv6_ptr, buffer, &index);
8472 
8473     /* Check for error. */
8474     if(status != NX_SUCCESS)
8475     {
8476 
8477         nx_packet_release(packet_ptr);
8478 
8479         return status;
8480     }
8481 
8482     /* Determine if any additional options need to be added relative to the DHCPV6 message type.  */
8483     switch (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type)
8484     {
8485 
8486         case NX_DHCPV6_MESSAGE_TYPE_SOLICIT:
8487         {
8488             /* Append the IA-NA option and depending on host state. */
8489             status = _nx_dhcpv6_add_iana(dhcpv6_ptr, buffer, &index);
8490 
8491             /* Check for internal errors. */
8492             if (status != NX_SUCCESS)
8493             {
8494 
8495                 nx_packet_release(packet_ptr);
8496 
8497                 /* Return the error status and abort. */
8498                 return status;
8499             }
8500 
8501             /* Compute the session time so far and add an elapsed time option. */
8502             status = _nx_dhcpv6_add_elapsed_time(dhcpv6_ptr, buffer, &index);
8503 
8504             /* Check for internal errors. */
8505             if (status != NX_SUCCESS)
8506             {
8507 
8508                 nx_packet_release(packet_ptr);
8509 
8510                 /* Return the error status and abort. */
8511                 return status;
8512             }
8513 
8514             /* Did the Client ask for a DHCPv6 Client FQDN option ?
8515                A client MUST only include the Client FQDN option in SOLICIT, REQUEST, RENEW, or REBIND messsage.  */
8516             if (dhcpv6_ptr ->nx_dhcpv6_client_FQDN.nx_op_code)
8517             {
8518 
8519                 /* Add the option request. */
8520                 status = _nx_dhcpv6_add_client_FQDN(dhcpv6_ptr, buffer, &index);
8521 
8522                 /* Check for internal error. */
8523                 if (status != NX_SUCCESS)
8524                 {
8525 
8526                     nx_packet_release(packet_ptr);
8527 
8528                     /* Return the error status and abort. */
8529                     return status;
8530                 }
8531             }
8532 
8533             /* Did the Client ask for a requested option? */
8534             if (dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request)
8535             {
8536 
8537                 /* Add the option request. */
8538                 status = _nx_dhcpv6_add_option_request(dhcpv6_ptr, buffer, &index);
8539 
8540                 /* Check for internal error. */
8541                 if (status != NX_SUCCESS)
8542                 {
8543 
8544                     nx_packet_release(packet_ptr);
8545 
8546                     /* Return the error status and abort. */
8547                     return status;
8548                 }
8549             }
8550 
8551             /* Did the Client ask for rapid commit option? */
8552             if (dhcpv6_ptr -> nx_dhcpv6_request_solicit_mode == NX_DHCPV6_SOLICIT_RAPID)
8553             {
8554 
8555                 /* Compute the available payload for DHCP data in the packet buffer. */
8556                 available_payload = (ULONG)(dhcpv6_ptr -> nx_dhcpv6_pool_ptr -> nx_packet_pool_payload_size -
8557                                             sizeof(NX_IPV6_HEADER) - sizeof(NX_UDP_HEADER) - index);
8558 
8559                 /* Check if the data will fit in the packet buffer. */
8560                 if (available_payload < sizeof(ULONG))
8561                 {
8562 
8563                     /* Hmmm... not enough! Can't do it. */
8564                     return NX_DHCPV6_INSUFFICIENT_PACKET_PAYLOAD;
8565                 }
8566 
8567                 /* Add the rapid commit option request. */
8568                 /* Clear memory to make the message header, and add the message type.  */
8569                 memset(&message_word, 0, sizeof(ULONG));
8570 
8571                 /* Add the message type. */
8572                 message_word = (((ULONG)NX_DHCPV6_OP_RAPID_COMMIT) << 16);
8573 
8574                 /* Adjust for endianness. */
8575                 NX_CHANGE_ULONG_ENDIAN(message_word);
8576 
8577                 /* Copy the message to the packet buffer. */
8578                 memcpy((buffer + index), &message_word, sizeof(ULONG)); /* Use case of memcpy is verified. */
8579 
8580                 /* Update the index.  */
8581                 index += (ULONG)sizeof(ULONG);
8582             }
8583 
8584             /* Increment the number of Solicit messages sent.  */
8585             dhcpv6_ptr -> nx_dhcpv6_solicitations_sent++;
8586 
8587             break;
8588         }
8589 
8590         case NX_DHCPV6_MESSAGE_TYPE_REQUEST:
8591         {
8592             /* Compute the session time so far and add an elapsed time option. */
8593             status = _nx_dhcpv6_add_elapsed_time(dhcpv6_ptr, buffer, &index);
8594 
8595             /* Check for internal error. */
8596             if (status != NX_SUCCESS)
8597             {
8598 
8599                 nx_packet_release(packet_ptr);
8600 
8601                 /* Return error status. */
8602                 return status;
8603             }
8604 
8605             /* Add the server DUID just extracted from the Server Advertise message. */
8606             status = _nx_dhcpv6_add_server_duid(dhcpv6_ptr, buffer, &index);
8607 
8608             /* Check for internal error. */
8609             if (status != NX_SUCCESS)
8610             {
8611 
8612                 nx_packet_release(packet_ptr);
8613 
8614                 /* Return error status. */
8615                 return status;
8616             }
8617 
8618             /* Append an IA-NA with the IA address option received from server added to the IA-NA option. */
8619             status = _nx_dhcpv6_add_iana(dhcpv6_ptr, buffer, &index);
8620 
8621             /* Check for internal error. */
8622             if (status != NX_SUCCESS)
8623             {
8624 
8625                 nx_packet_release(packet_ptr);
8626 
8627                 /* Return error status. */
8628                 return status;
8629             }
8630 
8631             /* Did the Client ask for a DHCPv6 Client FQDN option ?
8632                A client MUST only include the Client FQDN option in SOLICIT, REQUEST, RENEW, or REBIND messsage.  */
8633             if (dhcpv6_ptr ->nx_dhcpv6_client_FQDN.nx_op_code)
8634             {
8635 
8636                 /* Add the option request. */
8637                 status = _nx_dhcpv6_add_client_FQDN(dhcpv6_ptr, buffer, &index);
8638 
8639                 /* Check for internal error. */
8640                 if (status != NX_SUCCESS)
8641                 {
8642 
8643                     nx_packet_release(packet_ptr);
8644 
8645                     /* Return the error status and abort. */
8646                     return status;
8647                 }
8648             }
8649 
8650             /* Did the Client ask for a requested option? */
8651             if (dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request)
8652             {
8653                 /* Add the server DUID just extracted from the Server Advertise message. */
8654                 status = _nx_dhcpv6_add_option_request(dhcpv6_ptr, buffer, &index);
8655 
8656                 /* Check for internal error. */
8657                 if (status != NX_SUCCESS)
8658                 {
8659 
8660                     nx_packet_release(packet_ptr);
8661 
8662                     /* Return error status. */
8663                     return status;
8664                 }
8665             }
8666 
8667             /* Increment the number of Request messages sent.  */
8668             dhcpv6_ptr -> nx_dhcpv6_requests_sent++;
8669 
8670             break;
8671         }
8672 
8673         case NX_DHCPV6_MESSAGE_TYPE_RENEW:
8674         {
8675             /* Compute the session time so far and add an elapsed time option. */
8676             status = _nx_dhcpv6_add_elapsed_time(dhcpv6_ptr, buffer, &index);
8677 
8678             /* Check for internal error. */
8679             if (status != NX_SUCCESS)
8680             {
8681 
8682                 nx_packet_release(packet_ptr);
8683 
8684                 /* Return error status. */
8685                 return status;
8686             }
8687 
8688             /* Add the server DUID just extracted from the Server Advertise message. */
8689             status = _nx_dhcpv6_add_server_duid(dhcpv6_ptr, buffer, &index);
8690 
8691             /* Check for internal error. */
8692             if (status != NX_SUCCESS)
8693             {
8694 
8695                 nx_packet_release(packet_ptr);
8696 
8697                 /* Return error status. */
8698                 return status;
8699             }
8700 
8701             status = _nx_dhcpv6_add_iana(dhcpv6_ptr, buffer, &index);
8702 
8703             /* Check for internal errors. */
8704             if (status != NX_SUCCESS)
8705             {
8706 
8707                 nx_packet_release(packet_ptr);
8708 
8709                 /* Return the error status and abort. */
8710                 return status;
8711             }
8712 
8713             /* Did the Client ask for a DHCPv6 Client FQDN option ?
8714                A client MUST only include the Client FQDN option in SOLICIT, REQUEST, RENEW, or REBIND messsage.  */
8715             if (dhcpv6_ptr ->nx_dhcpv6_client_FQDN.nx_op_code)
8716             {
8717 
8718                 /* Add the option request. */
8719                 status = _nx_dhcpv6_add_client_FQDN(dhcpv6_ptr, buffer, &index);
8720 
8721                 /* Check for internal error. */
8722                 if (status != NX_SUCCESS)
8723                 {
8724 
8725                     nx_packet_release(packet_ptr);
8726 
8727                     /* Return the error status and abort. */
8728                     return status;
8729                 }
8730             }
8731 
8732             /* A client MAY include an Option Request option in a Solicit, Request, Renew, Rebind, Confirm or Information-request
8733                message to inform the server about options the client wants the server to send to the client. RFC3315, Section22.7, Page78.*/
8734             if (dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request)
8735             {
8736                 /* Add the server DUID just extracted from the Server Advertise message. */
8737                 status = _nx_dhcpv6_add_option_request(dhcpv6_ptr, buffer, &index);
8738 
8739                 /* Check for internal error. */
8740                 if (status != NX_SUCCESS)
8741                 {
8742 
8743                     nx_packet_release(packet_ptr);
8744 
8745                     /* Return error status. */
8746                     return status;
8747                 }
8748             }
8749 
8750             dhcpv6_ptr -> nx_dhcpv6_renews_sent++;
8751 
8752             break;
8753         }
8754 
8755         case NX_DHCPV6_MESSAGE_TYPE_REBIND:
8756         {
8757             /* Compute the session time so far and add an elapsed time option. */
8758             status = _nx_dhcpv6_add_elapsed_time(dhcpv6_ptr, buffer, &index);
8759 
8760             /* Check for internal errors. */
8761             if (status != NX_SUCCESS)
8762             {
8763 
8764                 nx_packet_release(packet_ptr);
8765 
8766                 /* Return the error status and abort. */
8767                 return status;
8768             }
8769 
8770             /* Rebind message includes the current IA/IA-NA, current IA address. */
8771             status = _nx_dhcpv6_add_iana(dhcpv6_ptr, buffer, &index);
8772 
8773             /* Check for internal errors. */
8774             if (status != NX_SUCCESS)
8775             {
8776 
8777                 nx_packet_release(packet_ptr);
8778 
8779                 /* Return the error status and abort. */
8780                 return status;
8781             }
8782 
8783             /* Did the Client ask for a DHCPv6 Client FQDN option ?
8784                A client MUST only include the Client FQDN option in SOLICIT, REQUEST, RENEW, or REBIND messsage.  */
8785             if (dhcpv6_ptr ->nx_dhcpv6_client_FQDN.nx_op_code)
8786             {
8787 
8788                 /* Add the option request. */
8789                 status = _nx_dhcpv6_add_client_FQDN(dhcpv6_ptr, buffer, &index);
8790 
8791                 /* Check for internal error. */
8792                 if (status != NX_SUCCESS)
8793                 {
8794 
8795                     nx_packet_release(packet_ptr);
8796 
8797                     /* Return the error status and abort. */
8798                     return status;
8799                 }
8800             }
8801 
8802             /* Did the Client ask for a requested option? */
8803             if (dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request)
8804             {
8805 
8806                 /* Add the server DUID just extracted from the Server Advertise message. */
8807                 status = _nx_dhcpv6_add_option_request(dhcpv6_ptr, buffer, &index);
8808 
8809                 /* Check for internal errors. */
8810                 if (status != NX_SUCCESS)
8811                 {
8812 
8813                     nx_packet_release(packet_ptr);
8814 
8815                     /* Return the error status and abort. */
8816                     return status;
8817                 }
8818             }
8819 
8820             /* Increment the number of Solicit messages sent.  */
8821             dhcpv6_ptr -> nx_dhcpv6_rebinds_sent++;
8822 
8823             break;
8824         }
8825 
8826         case NX_DHCPV6_MESSAGE_TYPE_CONFIRM:
8827         {
8828             /* Compute the session time so far and add an elapsed time option. */
8829             status = _nx_dhcpv6_add_elapsed_time(dhcpv6_ptr, buffer, &index);
8830 
8831             /* Check for internal errors. */
8832             if (status != NX_SUCCESS)
8833             {
8834 
8835                 nx_packet_release(packet_ptr);
8836 
8837                 /* Return the error status and abort. */
8838                 return status;
8839             }
8840 
8841             /* Rebind message includes the current IA/IA-NA, current IA address. */
8842             status = _nx_dhcpv6_add_iana(dhcpv6_ptr, buffer, &index);
8843 
8844             /* Check for internal errors. */
8845             if (status != NX_SUCCESS)
8846             {
8847 
8848                 /* Return the error status and abort. */
8849                 return status;
8850             }
8851 
8852             /* A client MAY include an Option Request option in a Solicit, Request, Renew, Rebind, Confirm or Information-request
8853                message to inform the server about options the client wants the server to send to the client. RFC3315, Section22.7, Page78.*/
8854             if (dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request)
8855             {
8856                 /* Add the server DUID just extracted from the Server Advertise message. */
8857                 status = _nx_dhcpv6_add_option_request(dhcpv6_ptr, buffer, &index);
8858 
8859                 /* Check for internal error. */
8860                 if (status != NX_SUCCESS)
8861                 {
8862 
8863                     nx_packet_release(packet_ptr);
8864 
8865                     /* Return error status. */
8866                     return status;
8867                 }
8868             }
8869 
8870             /* Increment the number of Solicit messages sent.  */
8871             dhcpv6_ptr -> nx_dhcpv6_confirms_sent++;
8872 
8873             break;
8874         }
8875 
8876         case NX_DHCPV6_MESSAGE_TYPE_DECLINE:
8877         {
8878 
8879             /* Add the server DUID just extracted from the Server Advertise message. */
8880             status = _nx_dhcpv6_add_server_duid(dhcpv6_ptr, buffer, &index);
8881 
8882             /* Check for internal error. */
8883             if (status != NX_SUCCESS)
8884             {
8885 
8886                 nx_packet_release(packet_ptr);
8887 
8888                 /* Return error status. */
8889                 return status;
8890             }
8891 
8892             /* Compute the session time so far and add an elapsed time option. */
8893             status = _nx_dhcpv6_add_elapsed_time(dhcpv6_ptr, buffer, &index);
8894 
8895             /* Check for internal errors. */
8896             if (status != NX_SUCCESS)
8897             {
8898 
8899                 /* Return the error status and abort. */
8900                 return status;
8901             }
8902 
8903             /* Decling the message in the current IA/IA-NA, current IA address. */
8904             status = _nx_dhcpv6_add_iana(dhcpv6_ptr, buffer, &index);
8905 
8906             /* Check for internal errors. */
8907             if (status != NX_SUCCESS)
8908             {
8909 
8910                 nx_packet_release(packet_ptr);
8911 
8912                 /* Return the error status and abort. */
8913                 return status;
8914             }
8915 
8916             /* Increment the number of Decline messages sent.  */
8917             dhcpv6_ptr -> nx_dhcpv6_declines_sent++;
8918 
8919             break;
8920         }
8921 
8922         case NX_DHCPV6_MESSAGE_TYPE_RELEASE:
8923         {
8924 
8925             /* Add the server DUID just extracted from the Server Advertise message. */
8926             status = _nx_dhcpv6_add_server_duid(dhcpv6_ptr, buffer, &index);
8927 
8928             /* Check for internal error. */
8929             if (status != NX_SUCCESS)
8930             {
8931 
8932                 nx_packet_release(packet_ptr);
8933 
8934                 /* Return error status. */
8935                 return status;
8936             }
8937 
8938             /* Compute the session time so far and add an elapsed time option. */
8939             status = _nx_dhcpv6_add_elapsed_time(dhcpv6_ptr, buffer, &index);
8940 
8941             /* Check for internal errors. */
8942             if (status != NX_SUCCESS)
8943             {
8944 
8945                 nx_packet_release(packet_ptr);
8946 
8947                 /* Return the error status and abort. */
8948                 return status;
8949             }
8950 
8951             /* Decling the message in the current IA/IA-NA, current IA address. */
8952             status = _nx_dhcpv6_add_iana(dhcpv6_ptr, buffer, &index);
8953 
8954             /* Check for internal errors. */
8955             if (status != NX_SUCCESS)
8956             {
8957 
8958                 nx_packet_release(packet_ptr);
8959 
8960                 /* Return the error status and abort. */
8961                 return status;
8962             }
8963 
8964             /* Increment the number of Releases messages sent.  */
8965             dhcpv6_ptr -> nx_dhcpv6_releases_sent++;
8966 
8967             break;
8968         }
8969 
8970         case NX_DHCPV6_MESSAGE_TYPE_INFORM_REQUEST:
8971         {
8972 
8973             /* Did the Client ask for a requested option? */
8974             if (!dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request)
8975             {
8976 
8977                 /* No, so don't bother sending out the request. */
8978 
8979                 nx_packet_release(packet_ptr);
8980 
8981                 return NX_SUCCESS;
8982             }
8983 
8984             /* Compute the session time so far and add an elapsed time option. */
8985             status = _nx_dhcpv6_add_elapsed_time(dhcpv6_ptr, buffer, &index);
8986 
8987             /* Check for internal error. */
8988             if (status != NX_SUCCESS)
8989             {
8990 
8991                 nx_packet_release(packet_ptr);
8992 
8993                 /* Return error status. */
8994                 return status;
8995             }
8996 
8997             /* Did the Client ask for a requested option? */
8998             if (dhcpv6_ptr -> nx_dhcpv6_option_request.nx_op_request)
8999             {
9000                 /* Add the server DUID just extracted from the Server Advertise message. */
9001                 status = _nx_dhcpv6_add_option_request(dhcpv6_ptr, buffer, &index);
9002 
9003                 /* Check for internal error. */
9004                 if (status != NX_SUCCESS)
9005                 {
9006 
9007                     nx_packet_release(packet_ptr);
9008 
9009                     /* Return error status. */
9010                     return status;
9011                 }
9012             }
9013 
9014             /* Increment the number of Inform Request messages sent.  */
9015             dhcpv6_ptr -> nx_dhcpv6_inform_req_sent++;
9016 
9017             break;
9018         }
9019 
9020         default:
9021         {
9022             nx_packet_release(packet_ptr);
9023 
9024             return NX_DHCPV6_UNKNOWN_MSG_TYPE;
9025         }
9026     }
9027 
9028     /* Add any user supplied options to the buffer.  */
9029     if (dhcpv6_ptr -> nx_dhcpv6_user_option_add)
9030     {
9031 
9032         /* Set the pointer for adding user option.  */
9033         user_option_ptr = buffer + index;
9034 
9035         /* Calculate the available length for user options.  */
9036         user_option_length = (UINT)(packet_ptr -> nx_packet_data_end - user_option_ptr);
9037 
9038         /* Add the specific DHCP option user wanted.  */
9039         if (dhcpv6_ptr -> nx_dhcpv6_user_option_add(dhcpv6_ptr, dhcpv6_ptr -> nx_dhcpv6_client_interface_index, dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_type, user_option_ptr, &user_option_length) == NX_TRUE)
9040         {
9041 
9042             /* Update the index to include the user options.  */
9043             index += user_option_length;
9044         }
9045         else
9046         {
9047 
9048             /* Invalid user options. Release the packet.  */
9049             nx_packet_release(packet_ptr);
9050             return(NX_DHCPV6_UNKNOWN_OPTION);
9051         }
9052     }
9053 
9054     /* Setup the packet pointers.  */
9055     packet_ptr -> nx_packet_length = index;
9056 
9057     packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + index;
9058 
9059     /* Select Client Source address:
9060        1. When a client sends a DHCP message to the All_DHCP_Relay_Agents_and_Servers address,
9061           the client must use a link-local address assigned to the interface for which it
9062           is requesting configuration as the source address.
9063        2. When a client sends a DHCP message directly to a server using unicast,
9064           the source address must be an address assigned to the interface for which the
9065           client is interested in obtaining configuration.
9066        RFC 3315, Section 16. Client Source Address and Interface Selection, Page 32.  */
9067 
9068     /* Set the interface pointer.  */
9069     interface_ptr = &(dhcpv6_ptr -> nx_dhcpv6_ip_ptr -> nx_ip_interface[dhcpv6_ptr ->nx_dhcpv6_client_interface_index]);
9070 
9071     /* Check the destination address.  */
9072     if (CHECK_IPV6_ADDRESSES_SAME(dhcpv6_ptr -> nx_dhcpv6_client_destination_address.nxd_ip_address.v6, All_DHCPv6_Relay_Servers_Address.nxd_ip_address.v6))
9073     {
9074 
9075         /* Find the link-local address as source adress. Get first address from interface.  */
9076         ipv6_address = interface_ptr -> nxd_interface_ipv6_address_list_head;
9077 
9078         /* Loop to check the address.  */
9079         while (ipv6_address)
9080         {
9081 
9082             /* Check for a valid address. */
9083             if (ipv6_address -> nxd_ipv6_address_state != NX_IPV6_ADDR_STATE_VALID)
9084             {
9085                 ipv6_address = ipv6_address -> nxd_ipv6_address_next;
9086             }
9087 
9088             /* Check for link-local address. */
9089             else if (IPv6_Address_Type(ipv6_address -> nxd_ipv6_address) & IPV6_ADDRESS_LINKLOCAL)
9090             {
9091 
9092                 /* Find the Link-Local Address.  */
9093                 break;
9094             }
9095             else
9096             {
9097                 ipv6_address = ipv6_address -> nxd_ipv6_address_next;
9098             }
9099         }
9100 
9101         /* Check if found the link-local address.  */
9102         if(ipv6_address == NX_NULL)
9103         {
9104 
9105             /* No valid link-local address.  */
9106             nx_packet_release(packet_ptr);
9107             return(NX_IP_ADDRESS_ERROR);
9108         }
9109     }
9110     else
9111     {
9112 
9113         /* Find the source address.  */
9114         status = _nxd_ipv6_interface_find(dhcpv6_ptr -> nx_dhcpv6_ip_ptr, dhcpv6_ptr -> nx_dhcpv6_client_destination_address.nxd_ip_address.v6,
9115                                           &ipv6_address, interface_ptr);
9116 
9117         /* Check if found the address.  */
9118         if (status)
9119         {
9120 
9121             /* No valid source address.  */
9122             nx_packet_release(packet_ptr);
9123             return(NX_IP_ADDRESS_ERROR);
9124         }
9125     }
9126 
9127     /* Send the packet out! */
9128     status = _nxd_udp_socket_source_send(&(dhcpv6_ptr -> nx_dhcpv6_socket), packet_ptr,
9129                                          &dhcpv6_ptr -> nx_dhcpv6_client_destination_address, NX_DHCPV6_SERVER_UDP_PORT,
9130                                          ipv6_address -> nxd_ipv6_address_index);
9131 
9132     /* If an error is detected, the packet was not sent and we have to release the packet. */
9133     if (status != NX_SUCCESS)
9134     {
9135 
9136         /* Release the packet.  */
9137         nx_packet_release(packet_ptr);
9138     }
9139 
9140     /* Return completion status.  */
9141     return(status);
9142 }
9143 
9144 
9145 /**************************************************************************/
9146 /*                                                                        */
9147 /*  FUNCTION                                               RELEASE        */
9148 /*                                                                        */
9149 /*    _nx_dhcpv6_session_timeout_entry                    PORTABLE C      */
9150 /*                                                           6.1          */
9151 /*  AUTHOR                                                                */
9152 /*                                                                        */
9153 /*    Yuxin Zhou, Microsoft Corporation                                   */
9154 /*                                                                        */
9155 /*  DESCRIPTION                                                           */
9156 /*                                                                        */
9157 /*    This function updates the Client session duration time with the     */
9158 /*    Server. This information is used for the Elapsed Time data in DHCPv6*/
9159 /*    Client messages sends to the server as part of the DHCPv6 protocol. */
9160 /*                                                                        */
9161 /*  INPUT                                                                 */
9162 /*                                                                        */
9163 /*    dhcpv6_ptr_value                      Pointer to the DHCPV6 Client  */
9164 /*                                                                        */
9165 /*  OUTPUT                                                                */
9166 /*                                                                        */
9167 /*    None                                                                */
9168 /*                                                                        */
9169 /*  CALLS                                                                 */
9170 /*                                                                        */
9171 /*    None                                                                */
9172 /*                                                                        */
9173 /*  CALLED BY                                                             */
9174 /*                                                                        */
9175 /*                                                                        */
9176 /*  RELEASE HISTORY                                                       */
9177 /*                                                                        */
9178 /*    DATE              NAME                      DESCRIPTION             */
9179 /*                                                                        */
9180 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9181 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9182 /*                                            resulting in version 6.1    */
9183 /*                                                                        */
9184 /**************************************************************************/
_nx_dhcpv6_session_timeout_entry(ULONG dhcpv6_ptr_value)9185 VOID  _nx_dhcpv6_session_timeout_entry(ULONG dhcpv6_ptr_value)
9186 {
9187 
9188 NX_DHCPV6 *dhcpv6_ptr;
9189 
9190 
9191     /* Setup DHCPv6 Client pointer.  */
9192     NX_TIMER_EXTENSION_PTR_GET(dhcpv6_ptr, NX_DHCPV6, dhcpv6_ptr_value)
9193 
9194     /* Check the elapsed time, the time is expressed in hundredths of 1 second, 65500 is the largest time value.  */
9195     if(dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time < 65500)
9196     {
9197 
9198         /* Update the elapsed time of current DHCP session.
9199            This time is expressed in hundredths of a second.  */
9200         dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = (USHORT)(dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time + NX_DHCPV6_SESSION_TIMER_INTERVAL * 100);
9201     }
9202     else
9203     {
9204 
9205         /* Set the value 0xFFFF to represent any elapsed time values greater than the largest time value . */
9206         dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = 0xFFFF;
9207     }
9208     return;
9209 }
9210 
9211 /**************************************************************************/
9212 /*                                                                        */
9213 /*  FUNCTION                                               RELEASE        */
9214 /*                                                                        */
9215 /*    _nxe_dhcpv6_set_time_accrued                        PORTABLE C      */
9216 /*                                                           6.1          */
9217 /*  AUTHOR                                                                */
9218 /*                                                                        */
9219 /*    Yuxin Zhou, Microsoft Corporation                                   */
9220 /*                                                                        */
9221 /*  DESCRIPTION                                                           */
9222 /*                                                                        */
9223 /*    This function performs error checking on the set time accrued on    */
9224 /*    Client IP lease service.                                            */
9225 /*                                                                        */
9226 /*  INPUT                                                                 */
9227 /*                                                                        */
9228 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
9229 /*    time_accrued                        Pointer to time since IP lease  */
9230 /*                                            assigned (secs)             */
9231 /*                                                                        */
9232 /*  OUTPUT                                                                */
9233 /*                                                                        */
9234 /*    status                            Actual completion status          */
9235 /*    NX_PTR_ERROR                      Invalid pointer input             */
9236 /*                                                                        */
9237 /*  CALLS                                                                 */
9238 /*                                                                        */
9239 /*    _nx_dhcpv6_set_time_accrued       Actual set time accrued on Client */
9240 /*                                          IP address lease service      */
9241 /*                                                                        */
9242 /*  CALLED BY                                                             */
9243 /*                                                                        */
9244 /*    Application Code                                                    */
9245 /*                                                                        */
9246 /*  RELEASE HISTORY                                                       */
9247 /*                                                                        */
9248 /*    DATE              NAME                      DESCRIPTION             */
9249 /*                                                                        */
9250 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9251 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9252 /*                                            resulting in version 6.1    */
9253 /*                                                                        */
9254 /**************************************************************************/
_nxe_dhcpv6_set_time_accrued(NX_DHCPV6 * dhcpv6_ptr,ULONG time_accrued)9255 UINT _nxe_dhcpv6_set_time_accrued(NX_DHCPV6 *dhcpv6_ptr, ULONG time_accrued)
9256 {
9257 
9258 UINT status;
9259 
9260 
9261     /* Check for valid pointer input. */
9262     if (!dhcpv6_ptr)
9263     {
9264         return NX_PTR_ERROR;
9265     }
9266 
9267     /* Call the actual service. */
9268     status =  _nx_dhcpv6_set_time_accrued(dhcpv6_ptr, time_accrued);
9269 
9270     /* Return completion status. */
9271     return status;
9272 }
9273 
9274 
9275 /**************************************************************************/
9276 /*                                                                        */
9277 /*  FUNCTION                                               RELEASE        */
9278 /*                                                                        */
9279 /*    _nx_dhcpv6_set_time_accrued                         PORTABLE C      */
9280 /*                                                           6.1          */
9281 /*  AUTHOR                                                                */
9282 /*                                                                        */
9283 /*    Yuxin Zhou, Microsoft Corporation                                   */
9284 /*                                                                        */
9285 /*  DESCRIPTION                                                           */
9286 /*                                                                        */
9287 /*    This function enables the host to set the time accrued on the       */
9288 /*    Client's IP address lease.  The caller must first suspend the       */
9289 /*    DHCPv6 Client using the nx_dhcpv6_suspend service before using this */
9290 /*    service.                                                            */
9291 /*                                                                        */
9292 /*  INPUT                                                                 */
9293 /*                                                                        */
9294 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
9295 /*    time_accrued                        Pointer to time to set the      */
9296 /*                                            lient accrued time (secs)   */
9297 /*                                                                        */
9298 /*  OUTPUT                                                                */
9299 /*                                                                        */
9300 /*    NX_SUCCESS                          Successful completion status    */
9301 /*                                                                        */
9302 /*  CALLS                                                                 */
9303 /*                                                                        */
9304 /*    None                                                                */
9305 /*                                                                        */
9306 /*  CALLED BY                                                             */
9307 /*                                                                        */
9308 /*    Application                                                         */
9309 /*                                                                        */
9310 /*  RELEASE HISTORY                                                       */
9311 /*                                                                        */
9312 /*    DATE              NAME                      DESCRIPTION             */
9313 /*                                                                        */
9314 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9315 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9316 /*                                            resulting in version 6.1    */
9317 /*                                                                        */
9318 /**************************************************************************/
_nx_dhcpv6_set_time_accrued(NX_DHCPV6 * dhcpv6_ptr,ULONG time_accrued)9319 UINT _nx_dhcpv6_set_time_accrued(NX_DHCPV6 *dhcpv6_ptr, ULONG time_accrued)
9320 {
9321 
9322 
9323     /* Check if the DHCPv6 Client has been started. */
9324     if (dhcpv6_ptr -> nx_dhcpv6_started)
9325     {
9326         /* It has.  We cannot set the time accrued if the DHCPv6 client thread is running. */
9327         return NX_DHCPV6_ALREADY_STARTED;
9328     }
9329 
9330     /* Set the time accrued on the Client IP address lease. */
9331     dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_time_accrued = time_accrued;
9332 
9333     /* Return successful completion. */
9334     return NX_SUCCESS;
9335 }
9336 
9337 
9338 /**************************************************************************/
9339 /*                                                                        */
9340 /*  FUNCTION                                               RELEASE        */
9341 /*                                                                        */
9342 /*    _nxe_dhcpv6_client_set_interface                    PORTABLE C      */
9343 /*                                                           6.1          */
9344 /*  AUTHOR                                                                */
9345 /*                                                                        */
9346 /*    Yuxin Zhou, Microsoft Corporation                                   */
9347 /*                                                                        */
9348 /*  DESCRIPTION                                                           */
9349 /*                                                                        */
9350 /*    This function performs error checking on the set client interface   */
9351 /*    service.                                                            */
9352 /*                                                                        */
9353 /*  INPUT                                                                 */
9354 /*                                                                        */
9355 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
9356 /*    interface_index                     Index for DHCP network interface*/
9357 /*                                                                        */
9358 /*  OUTPUT                                                                */
9359 /*                                                                        */
9360 /*    status                            Actual completion status          */
9361 /*    NX_PTR_ERROR                      Invalid pointer input             */
9362 /*    NX_INVALID_INTERFACE              Invalid interface index input     */
9363 /*                                                                        */
9364 /*  CALLS                                                                 */
9365 /*                                                                        */
9366 /*    _nx_dhcpv6_client_set_interface   Actual set interface service      */
9367 /*                                                                        */
9368 /*  CALLED BY                                                             */
9369 /*                                                                        */
9370 /*    Application Code                                                    */
9371 /*                                                                        */
9372 /*  RELEASE HISTORY                                                       */
9373 /*                                                                        */
9374 /*    DATE              NAME                      DESCRIPTION             */
9375 /*                                                                        */
9376 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9377 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9378 /*                                            resulting in version 6.1    */
9379 /*                                                                        */
9380 /**************************************************************************/
_nxe_dhcpv6_client_set_interface(NX_DHCPV6 * dhcpv6_ptr,UINT interface_index)9381 UINT _nxe_dhcpv6_client_set_interface(NX_DHCPV6 *dhcpv6_ptr, UINT interface_index)
9382 {
9383 
9384 UINT status;
9385 
9386 
9387     /* Check for valid pointer input. */
9388     if (!dhcpv6_ptr)
9389     {
9390         return NX_PTR_ERROR;
9391     }
9392 
9393     /* Check for an invalid interface specified. */
9394     if (interface_index >= NX_MAX_PHYSICAL_INTERFACES)
9395     {
9396         return NX_INVALID_INTERFACE;
9397     }
9398 
9399     /* Call the actual service. */
9400     status =  _nx_dhcpv6_client_set_interface(dhcpv6_ptr, interface_index);
9401 
9402     /* Return completion status. */
9403     return status;
9404 }
9405 
9406 
9407 /**************************************************************************/
9408 /*                                                                        */
9409 /*  FUNCTION                                               RELEASE        */
9410 /*                                                                        */
9411 /*    _nx_dhcpv6_client_set_interface                     PORTABLE C      */
9412 /*                                                           6.1          */
9413 /*  AUTHOR                                                                */
9414 /*                                                                        */
9415 /*    Yuxin Zhou, Microsoft Corporation                                   */
9416 /*                                                                        */
9417 /*  DESCRIPTION                                                           */
9418 /*                                                                        */
9419 /*    This function specifies the physical interface for DHCP             */
9420 /*    communications with the server in NetX Duo environments that support*/
9421 /*    mult-homed hosts.                                                   */
9422 /*                                                                        */
9423 /*  INPUT                                                                 */
9424 /*                                                                        */
9425 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
9426 /*    interface_index                     Index for DHCP network interface*/
9427 /*                                                                        */
9428 /*  OUTPUT                                                                */
9429 /*                                                                        */
9430 /*    NX_SUCCESS                          Successful completion status    */
9431 /*    NX_NOT_ENABLED                      NetXDuo version does not support*/
9432 /*                                           multiple network interfaces  */
9433 /*                                                                        */
9434 /*  CALLS                                                                 */
9435 /*                                                                        */
9436 /*    None                                                                */
9437 /*                                                                        */
9438 /*  CALLED BY                                                             */
9439 /*                                                                        */
9440 /*    Application                                                         */
9441 /*                                                                        */
9442 /*  RELEASE HISTORY                                                       */
9443 /*                                                                        */
9444 /*    DATE              NAME                      DESCRIPTION             */
9445 /*                                                                        */
9446 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9447 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9448 /*                                            resulting in version 6.1    */
9449 /*                                                                        */
9450 /**************************************************************************/
_nx_dhcpv6_client_set_interface(NX_DHCPV6 * dhcpv6_ptr,UINT interface_index)9451 UINT _nx_dhcpv6_client_set_interface(NX_DHCPV6 *dhcpv6_ptr, UINT interface_index)
9452 {
9453 
9454 
9455     /* Set the client interface. */
9456     dhcpv6_ptr -> nx_dhcpv6_client_interface_index = interface_index;
9457 
9458     /* Return successful completion. */
9459     return NX_SUCCESS;
9460 }
9461 
9462 
9463 /**************************************************************************/
9464 /*                                                                        */
9465 /*  FUNCTION                                               RELEASE        */
9466 /*                                                                        */
9467 /*    _nxe_dhcpv6_client_set_destination_address          PORTABLE C      */
9468 /*                                                           6.1          */
9469 /*  AUTHOR                                                                */
9470 /*                                                                        */
9471 /*    Yuxin Zhou, Microsoft Corporation                                   */
9472 /*                                                                        */
9473 /*  DESCRIPTION                                                           */
9474 /*                                                                        */
9475 /*    This function performs error checking on the set destination        */
9476 /*    address service.                                                    */
9477 /*                                                                        */
9478 /*  INPUT                                                                 */
9479 /*                                                                        */
9480 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
9481 /*    destination_address                 Destination address             */
9482 /*                                                                        */
9483 /*  OUTPUT                                                                */
9484 /*                                                                        */
9485 /*    status                            Actual completion status          */
9486 /*    NX_PTR_ERROR                      Invalid pointer input             */
9487 /*                                                                        */
9488 /*  CALLS                                                                 */
9489 /*                                                                        */
9490 /*    _nx_dhcpv6_client_set_destination_address                           */
9491 /*                                      Actual set address service        */
9492 /*                                                                        */
9493 /*  CALLED BY                                                             */
9494 /*                                                                        */
9495 /*    Application Code                                                    */
9496 /*                                                                        */
9497 /*  RELEASE HISTORY                                                       */
9498 /*                                                                        */
9499 /*    DATE              NAME                      DESCRIPTION             */
9500 /*                                                                        */
9501 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9502 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9503 /*                                            resulting in version 6.1    */
9504 /*                                                                        */
9505 /**************************************************************************/
_nxe_dhcpv6_client_set_destination_address(NX_DHCPV6 * dhcpv6_ptr,NXD_ADDRESS * destination_address)9506 UINT _nxe_dhcpv6_client_set_destination_address(NX_DHCPV6 *dhcpv6_ptr, NXD_ADDRESS *destination_address)
9507 {
9508 
9509 UINT status;
9510 
9511 
9512     /* Check for invalid input pointer.  */
9513     if ((dhcpv6_ptr == NX_NULL) || (dhcpv6_ptr -> nx_dhcpv6_id != NX_DHCPV6_ID))
9514     {
9515         return(NX_PTR_ERROR);
9516     }
9517 
9518     /* Check for an invalid address type. */
9519     if (destination_address -> nxd_ip_version != NX_IP_VERSION_V6)
9520     {
9521 
9522         /* Invalid address type.  */
9523         return(NX_DHCPV6_PARAM_ERROR);
9524     }
9525 
9526     /* Check if the server address is unspecified (::). */
9527     if(CHECK_UNSPECIFIED_ADDRESS(destination_address -> nxd_ip_address.v6))
9528     {
9529 
9530         /* Null address input. */
9531         return(NX_DHCPV6_PARAM_ERROR);
9532     }
9533 
9534     /* Call the actual service. */
9535     status =  _nx_dhcpv6_client_set_destination_address(dhcpv6_ptr, destination_address);
9536 
9537     /* Return completion status. */
9538     return(status);
9539 }
9540 
9541 
9542 /**************************************************************************/
9543 /*                                                                        */
9544 /*  FUNCTION                                               RELEASE        */
9545 /*                                                                        */
9546 /*    _nx_dhcpv6_client_set_destination_address           PORTABLE C      */
9547 /*                                                           6.1          */
9548 /*  AUTHOR                                                                */
9549 /*                                                                        */
9550 /*    Yuxin Zhou, Microsoft Corporation                                   */
9551 /*                                                                        */
9552 /*  DESCRIPTION                                                           */
9553 /*                                                                        */
9554 /*    This function set the destination address where DHCP message should */
9555 /*    be sent. By default is All_DHCP_Relay_Agents_and_Servers(FF02::1:2).*/
9556 /*                                                                        */
9557 /*  INPUT                                                                 */
9558 /*                                                                        */
9559 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
9560 /*    destination_address                 Destination address             */
9561 /*                                                                        */
9562 /*  OUTPUT                                                                */
9563 /*                                                                        */
9564 /*    NX_SUCCESS                          Successful completion status    */
9565 /*                                                                        */
9566 /*  CALLS                                                                 */
9567 /*                                                                        */
9568 /*    None                                                                */
9569 /*                                                                        */
9570 /*  CALLED BY                                                             */
9571 /*                                                                        */
9572 /*    Application                                                         */
9573 /*                                                                        */
9574 /*  RELEASE HISTORY                                                       */
9575 /*                                                                        */
9576 /*    DATE              NAME                      DESCRIPTION             */
9577 /*                                                                        */
9578 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9579 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9580 /*                                            resulting in version 6.1    */
9581 /*                                                                        */
9582 /**************************************************************************/
_nx_dhcpv6_client_set_destination_address(NX_DHCPV6 * dhcpv6_ptr,NXD_ADDRESS * destination_address)9583 UINT _nx_dhcpv6_client_set_destination_address(NX_DHCPV6 *dhcpv6_ptr, NXD_ADDRESS *destination_address)
9584 {
9585 
9586 
9587     /* Get the DHCP mutex.  */
9588     tx_mutex_get(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex), NX_WAIT_FOREVER);
9589 
9590     /* Set the destination address.  */
9591     COPY_NXD_ADDRESS(destination_address, &(dhcpv6_ptr -> nx_dhcpv6_client_destination_address));
9592 
9593     /* Release the DHCPv6 Client mutex.  */
9594     tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
9595 
9596     /* Return successful completion. */
9597     return NX_SUCCESS;
9598 }
9599 
9600 
9601 /**************************************************************************/
9602 /*                                                                        */
9603 /*  FUNCTION                                               RELEASE        */
9604 /*                                                                        */
9605 /*    _nxe_dhcpv6_start                                   PORTABLE C      */
9606 /*                                                           6.1          */
9607 /*  AUTHOR                                                                */
9608 /*                                                                        */
9609 /*    Yuxin Zhou, Microsoft Corporation                                   */
9610 /*                                                                        */
9611 /*  DESCRIPTION                                                           */
9612 /*                                                                        */
9613 /*    This function performs error checking on the NetX start the dhcpv6  */
9614 /*    client service.                                                     */
9615 /*                                                                        */
9616 /*  INPUT                                                                 */
9617 /*                                                                        */
9618 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
9619 /*                                                                        */
9620 /*  OUTPUT                                                                */
9621 /*                                                                        */
9622 /*    status                              Completion status               */
9623 /*    NX_PTR_ERROR                        Invalid pointer input           */
9624 /*                                                                        */
9625 /*                                                                        */
9626 /*  CALLS                                                                 */
9627 /*                                                                        */
9628 /*    _nx_dhcpv6_start                    Actual DHCPV6 start function    */
9629 /*                                                                        */
9630 /*  CALLED BY                                                             */
9631 /*                                                                        */
9632 /*    Application Code                                                    */
9633 /*                                                                        */
9634 /*  RELEASE HISTORY                                                       */
9635 /*                                                                        */
9636 /*    DATE              NAME                      DESCRIPTION             */
9637 /*                                                                        */
9638 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9639 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9640 /*                                            resulting in version 6.1    */
9641 /*                                                                        */
9642 /**************************************************************************/
_nxe_dhcpv6_start(NX_DHCPV6 * dhcpv6_ptr)9643 UINT  _nxe_dhcpv6_start(NX_DHCPV6 *dhcpv6_ptr)
9644 {
9645 
9646 UINT    status;
9647 
9648 
9649     /* Check for invalid input pointer.  */
9650     if ((dhcpv6_ptr == NX_NULL) || (dhcpv6_ptr -> nx_dhcpv6_id != NX_DHCPV6_ID))
9651     {
9652         return(NX_PTR_ERROR);
9653     }
9654 
9655     /* Check for appropriate caller.  */
9656     NX_THREADS_ONLY_CALLER_CHECKING
9657 
9658     /* Call actual DHCPV6 start service.  */
9659     status =  _nx_dhcpv6_start(dhcpv6_ptr);
9660 
9661     /* Return status.  */
9662     return(status);
9663 }
9664 
9665 
9666 /**************************************************************************/
9667 /*                                                                        */
9668 /*  FUNCTION                                               RELEASE        */
9669 /*                                                                        */
9670 /*    _nx_dhcpv6_start                                    PORTABLE C      */
9671 /*                                                           6.1          */
9672 /*  AUTHOR                                                                */
9673 /*                                                                        */
9674 /*    Yuxin Zhou, Microsoft Corporation                                   */
9675 /*                                                                        */
9676 /*  DESCRIPTION                                                           */
9677 /*                                                                        */
9678 /*    This function starts the DHCPV6 processing thread and readies the   */
9679 /*    DHCPv6 Client to initiate DHCPv6 requests.  The Client state is set */
9680 /*    to INIT and awaits the host application requesting a DHCPv6 meesage */
9681 /*    sent e.g. the SOLICIT message. For hosts binding (or attempting to  */
9682 /*    obtain) a IP address in a previous session, this will clear session */
9683 /*    parameters such as accrued lease time and message retry count.      */
9684 /*                                                                        */
9685 /*  INPUT                                                                 */
9686 /*                                                                        */
9687 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
9688 /*                                                                        */
9689 /*  OUTPUT                                                                */
9690 /*                                                                        */
9691 /*    status                              Completion status               */
9692 /*    NX_DHCPV6_ALREADY_STARTED           DHCPv6 Client already started   */
9693 /*    NX_DHCPV6_MISSING_REQUIRED_OPTIONS  Client missing required options */
9694 /*                                                                        */
9695 /*  CALLS                                                                 */
9696 /*                                                                        */
9697 /*    nx_udp_socket_create                  Create the Client UDP socket  */
9698 /*    nx_udp_socket_bind                    Bind the Client socket        */
9699 /*    nx_udp_socket_unbind                  Unbind the Client socket      */
9700 /*    tx_timer_activate                     Activate Client timers        */
9701 /*    tx_timer_deactivate                   Deactivate Client timers      */
9702 /*    tx_thread_resume                      Resume Client thread task     */
9703 /*                                                                        */
9704 /*  CALLED BY                                                             */
9705 /*                                                                        */
9706 /*    Application Code                                                    */
9707 /*                                                                        */
9708 /*  RELEASE HISTORY                                                       */
9709 /*                                                                        */
9710 /*    DATE              NAME                      DESCRIPTION             */
9711 /*                                                                        */
9712 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9713 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9714 /*                                            resulting in version 6.1    */
9715 /*                                                                        */
9716 /**************************************************************************/
_nx_dhcpv6_start(NX_DHCPV6 * dhcpv6_ptr)9717 UINT  _nx_dhcpv6_start(NX_DHCPV6 *dhcpv6_ptr)
9718 {
9719 
9720 UINT        status;
9721 
9722 
9723     /* Get the DHCP mutex.  */
9724     tx_mutex_get(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex), NX_DHCPV6_MUTEX_WAIT);
9725 
9726     /* Determine if DHCPV6 has already been started.  */
9727     if (dhcpv6_ptr -> nx_dhcpv6_started)
9728     {
9729 
9730         /* Release the DHCPv6 Client mutex.  */
9731         tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
9732 
9733         /* Error, the DHCPV6 client has already been started.  */
9734         return(NX_DHCPV6_ALREADY_STARTED);
9735     }
9736 
9737     /* Determine if Client has created its DUID and IANA yet. */
9738     if ((dhcpv6_ptr -> nx_dhcpv6_ip_ptr == NX_NULL)                 ||
9739         (dhcpv6_ptr -> nx_dhcpv6_client_duid.nx_option_length == 0) ||
9740         (dhcpv6_ptr -> nx_dhcpv6_iana.nx_option_length == 0))
9741     {
9742 
9743         /* Release the DHCPv6 Client mutex.  */
9744         tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
9745 
9746         /* No, this DHCPv6 Client is not ready to run! */
9747         return NX_DHCPV6_MISSING_REQUIRED_OPTIONS;
9748     }
9749 
9750     /* Set the DHCPv6 Client state to Init.*/
9751     dhcpv6_ptr -> nx_dhcpv6_state =  NX_DHCPV6_STATE_INIT;
9752 
9753     /* Clear the session time, lease lifetime, retransmission counters. */
9754     dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time = 0;
9755     dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_time_accrued = 0;
9756     dhcpv6_ptr -> nx_dhcpv6_transmission_timeout = 0;
9757     dhcpv6_ptr -> nx_dhcpv6_retransmission_count = 0;
9758 
9759     /* Bind the UDP socket to the DHCPV6 Client port.  */
9760     status =  nx_udp_socket_bind(&(dhcpv6_ptr -> nx_dhcpv6_socket), NX_DHCPV6_CLIENT_UDP_PORT, TX_WAIT_FOREVER);
9761 
9762     /* Check for success */
9763     if (status == NX_SUCCESS)
9764     {
9765 
9766         /* Resume the DHCPv6 processing thread.  */
9767         status =  tx_thread_resume(&(dhcpv6_ptr -> nx_dhcpv6_thread));
9768 
9769         /* Determine if the resume was successful.  */
9770         if (status == NX_SUCCESS)
9771         {
9772 
9773             /* Set the DHCPv6 started flag to indicate DHCPv6 Client is now running.  */
9774             dhcpv6_ptr -> nx_dhcpv6_started =  NX_TRUE;
9775 
9776             /* Activate the DHCPv6 timers.  */
9777             tx_timer_activate(&dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_timer);
9778         }
9779         else
9780         {
9781 
9782             /* Error, unbind the DHCPv6 socket.  */
9783             nx_udp_socket_unbind(&(dhcpv6_ptr -> nx_dhcpv6_socket));
9784         }
9785     }
9786 
9787     /* Release the DHCPv6 Client mutex.  */
9788     tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
9789 
9790     /* Return completion status.  */
9791     return(status);
9792 }
9793 
9794 
9795 /**************************************************************************/
9796 /*                                                                        */
9797 /*  FUNCTION                                               RELEASE        */
9798 /*                                                                        */
9799 /*    _nxe_dhcpv6_suspend                                 PORTABLE C      */
9800 /*                                                           6.1          */
9801 /*  AUTHOR                                                                */
9802 /*                                                                        */
9803 /*    Yuxin Zhou, Microsoft Corporation                                   */
9804 /*                                                                        */
9805 /*  DESCRIPTION                                                           */
9806 /*                                                                        */
9807 /*    This function performs error checking on the suspend NetX DHCPv6    */
9808 /*    client task service.                                                */
9809 /*                                                                        */
9810 /*  INPUT                                                                 */
9811 /*                                                                        */
9812 /*    dhcpv6_ptr                         Pointer to DHCPV6 Client instance*/
9813 /*                                                                        */
9814 /*  OUTPUT                                                                */
9815 /*                                                                        */
9816 /*    status                              Completion status               */
9817 /*    NX_PTR_ERROR                        Invalid pointer input           */
9818 /*                                                                        */
9819 /*  CALLS                                                                 */
9820 /*                                                                        */
9821 /*    _nx_dhcpv6_suspend                  Actual DHCPV6 suspend function  */
9822 /*                                                                        */
9823 /*  CALLED BY                                                             */
9824 /*                                                                        */
9825 /*    Application Code                                                    */
9826 /*                                                                        */
9827 /*  RELEASE HISTORY                                                       */
9828 /*                                                                        */
9829 /*    DATE              NAME                      DESCRIPTION             */
9830 /*                                                                        */
9831 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9832 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9833 /*                                            resulting in version 6.1    */
9834 /*                                                                        */
9835 /**************************************************************************/
_nxe_dhcpv6_suspend(NX_DHCPV6 * dhcpv6_ptr)9836 UINT  _nxe_dhcpv6_suspend(NX_DHCPV6 *dhcpv6_ptr)
9837 {
9838 
9839 UINT    status;
9840 
9841 
9842     /* Check for invalid input pointer.  */
9843     if ((dhcpv6_ptr == NX_NULL) || (dhcpv6_ptr -> nx_dhcpv6_id != NX_DHCPV6_ID))
9844     {
9845 
9846         return(NX_PTR_ERROR);
9847     }
9848 
9849     /* Check for appropriate caller.  */
9850     NX_THREADS_ONLY_CALLER_CHECKING
9851 
9852     /* Call actual DHCPV6 stop service.  */
9853     status =  _nx_dhcpv6_suspend(dhcpv6_ptr);
9854 
9855     /* Return status.  */
9856     return(status);
9857 }
9858 
9859 
9860 /**************************************************************************/
9861 /*                                                                        */
9862 /*  FUNCTION                                               RELEASE        */
9863 /*                                                                        */
9864 /*    _nx_dhcpv6_suspend                                  PORTABLE C      */
9865 /*                                                           6.1          */
9866 /*  AUTHOR                                                                */
9867 /*                                                                        */
9868 /*    Yuxin Zhou, Microsoft Corporation                                   */
9869 /*                                                                        */
9870 /*  DESCRIPTION                                                           */
9871 /*                                                                        */
9872 /*    This function suspends (stops) DHCPV6 processing thread, stops the  */
9873 /*    DHCP session and IP address lease timers, and clears the started    */
9874 /*    status of the DHCPv6 Client. It resets the DHCPv6 Client to the     */
9875 /*    INIT.  The DHCP socket is unbound and the DHCP thread aborted.      */
9876 /*                                                                        */
9877 /*  INPUT                                                                 */
9878 /*                                                                        */
9879 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
9880 /*                                                                        */
9881 /*  OUTPUT                                                                */
9882 /*                                                                        */
9883 /*    NX_SUCCESS                          Successful completion status    */
9884 /*    NX_DHCPV6_NOT_STARTED               Task not running; can't be      */
9885 /*                                               suspended                */
9886 /*                                                                        */
9887 /*  CALLS                                                                 */
9888 /*                                                                        */
9889 /*    tx_thread_suspend                     Suspend DHCPV6 thread task    */
9890 /*    tx_timer_deactivate                   Deactivate timer              */
9891 /*                                                                        */
9892 /*  CALLED BY                                                             */
9893 /*                                                                        */
9894 /*    Application Code                                                    */
9895 /*                                                                        */
9896 /*  RELEASE HISTORY                                                       */
9897 /*                                                                        */
9898 /*    DATE              NAME                      DESCRIPTION             */
9899 /*                                                                        */
9900 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9901 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9902 /*                                            resulting in version 6.1    */
9903 /*                                                                        */
9904 /**************************************************************************/
_nx_dhcpv6_suspend(NX_DHCPV6 * dhcpv6_ptr)9905 UINT  _nx_dhcpv6_suspend(NX_DHCPV6 *dhcpv6_ptr)
9906 {
9907 
9908 UINT status;
9909 
9910 
9911     status = _nx_dhcpv6_stop(dhcpv6_ptr);
9912 
9913     return status;
9914 }
9915 
9916 
9917 /**************************************************************************/
9918 /*                                                                        */
9919 /*  FUNCTION                                               RELEASE        */
9920 /*                                                                        */
9921 /*    _nx_dhcpv6_stop                                     PORTABLE C      */
9922 /*                                                           6.1          */
9923 /*  AUTHOR                                                                */
9924 /*                                                                        */
9925 /*    Yuxin Zhou, Microsoft Corporation                                   */
9926 /*                                                                        */
9927 /*  DESCRIPTION                                                           */
9928 /*                                                                        */
9929 /*    This function performs error checking on the DHCPv6 Client stop     */
9930 /*    service.                                                            */
9931 /*                                                                        */
9932 /*  INPUT                                                                 */
9933 /*                                                                        */
9934 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
9935 /*                                                                        */
9936 /*  OUTPUT                                                                */
9937 /*                                                                        */
9938 /*    status                            Actual completion status          */
9939 /*                                                                        */
9940 /*  CALLS                                                                 */
9941 /*                                                                        */
9942 /*    _nx_dhcpv6_stop                   Actual stop DHCPV6 thread task    */
9943 /*                                                                        */
9944 /*  CALLED BY                                                             */
9945 /*                                                                        */
9946 /*    Application Code                                                    */
9947 /*                                                                        */
9948 /*  RELEASE HISTORY                                                       */
9949 /*                                                                        */
9950 /*    DATE              NAME                      DESCRIPTION             */
9951 /*                                                                        */
9952 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9953 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9954 /*                                            resulting in version 6.1    */
9955 /*                                                                        */
9956 /**************************************************************************/
_nxe_dhcpv6_stop(NX_DHCPV6 * dhcpv6_ptr)9957 UINT  _nxe_dhcpv6_stop(NX_DHCPV6 *dhcpv6_ptr)
9958 {
9959 
9960 UINT    status;
9961 
9962 
9963     /* Check for invalid input pointer.  */
9964     if ((dhcpv6_ptr == NX_NULL) || (dhcpv6_ptr -> nx_dhcpv6_id != NX_DHCPV6_ID))
9965     {
9966         return(NX_PTR_ERROR);
9967     }
9968 
9969     /* Check for appropriate caller.  */
9970     NX_THREADS_ONLY_CALLER_CHECKING
9971 
9972     /* Call actual DHCPV6 stop service.  */
9973     status =  _nx_dhcpv6_stop(dhcpv6_ptr);
9974 
9975     /* Return status.  */
9976     return(status);
9977 }
9978 
9979 /**************************************************************************/
9980 /*                                                                        */
9981 /*  FUNCTION                                               RELEASE        */
9982 /*                                                                        */
9983 /*    _nx_dhcpv6_stop                                     PORTABLE C      */
9984 /*                                                           6.1          */
9985 /*  AUTHOR                                                                */
9986 /*                                                                        */
9987 /*    Yuxin Zhou, Microsoft Corporation                                   */
9988 /*                                                                        */
9989 /*  DESCRIPTION                                                           */
9990 /*                                                                        */
9991 /*    This function suspends (stops) DHCPV6 processing thread, stops the  */
9992 /*    DHCP session and IP address lease timers. The DHCP socket is unbound*/
9993 /*    and the DHCP thread aborted.                                        */
9994 /*                                                                        */
9995 /*    Stopping the DHCP Client is necessary to restart the DHCP client,   */
9996 /*    example if a previously assigned address is declined or released,   */
9997 /*    and the host would like to solicit an IP address again.             */
9998 /*                                                                        */
9999 /*  INPUT                                                                 */
10000 /*                                                                        */
10001 /*    dhcpv6_ptr                        Pointer to DHCPV6 Client instance */
10002 /*                                                                        */
10003 /*  OUTPUT                                                                */
10004 /*                                                                        */
10005 /*    NX_SUCCESS                          Successful completion status    */
10006 /*    NX_DHCPV6_NOT_STARTED               Task not running; can't be      */
10007 /*                                               suspended                */
10008 /*                                                                        */
10009 /*  CALLS                                                                 */
10010 /*                                                                        */
10011 /*    tx_thread_suspend                     Suspend DHCPV6 thread task    */
10012 /*    tx_timer_deactivate                   Deactivate timer              */
10013 /*    tx_mutex_get                          Obtain  Client mutex          */
10014 /*    tx_mutex_put                          Release Client mutex          */
10015 /*                                                                        */
10016 /*  CALLED BY                                                             */
10017 /*                                                                        */
10018 /*    Application Code                                                    */
10019 /*                                                                        */
10020 /*  RELEASE HISTORY                                                       */
10021 /*                                                                        */
10022 /*    DATE              NAME                      DESCRIPTION             */
10023 /*                                                                        */
10024 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10025 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10026 /*                                            resulting in version 6.1    */
10027 /*                                                                        */
10028 /**************************************************************************/
10029 
_nx_dhcpv6_stop(NX_DHCPV6 * dhcpv6_ptr)10030 UINT  _nx_dhcpv6_stop(NX_DHCPV6 *dhcpv6_ptr)
10031 {
10032 
10033 UINT    current_preemption;
10034 
10035 
10036     /* Get the DHCP mutex.  */
10037     tx_mutex_get(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex), NX_DHCPV6_MUTEX_WAIT);
10038 
10039     /* Determine if DHCPV6 is started.  */
10040     if (dhcpv6_ptr -> nx_dhcpv6_started == NX_FALSE)
10041     {
10042 
10043         /* Release the DHCP mutex.  */
10044         tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
10045 
10046         /* DHCPV6 has not been started so we cannot stop it.  */
10047         return(NX_DHCPV6_NOT_STARTED);
10048     }
10049 
10050     /* Clear the DHCPV6 started flag to indicate DHCPV6 task is not running.  */
10051     dhcpv6_ptr -> nx_dhcpv6_started =  NX_FALSE;
10052 
10053     /* Disable preemption for critical section.  */
10054     tx_thread_preemption_change(tx_thread_identify(), 0, &current_preemption);
10055 
10056     /* Loop to wait for the DHCP Client thread to be in a position to be stopped.  */
10057     while (dhcpv6_ptr -> nx_dhcpv6_sleep_flag != NX_TRUE)
10058     {
10059 
10060         /* Release the DHCP mutex.  */
10061         tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
10062 
10063         /* Sleep temporarily. */
10064         tx_thread_sleep(1);
10065 
10066         /* Get the DHCP mutex.  */
10067         tx_mutex_get(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex), NX_DHCPV6_MUTEX_WAIT);
10068     }
10069 
10070     /* Clear the flag.  */
10071     dhcpv6_ptr -> nx_dhcpv6_sleep_flag =  NX_FALSE;
10072 
10073     /* Suspend the DHCP thread.  */
10074     tx_thread_suspend(&(dhcpv6_ptr -> nx_dhcpv6_thread));
10075 
10076     /* Abort the wait on the DHCP Client thread.  */
10077     tx_thread_wait_abort(&(dhcpv6_ptr -> nx_dhcpv6_thread));
10078 
10079     /* Unbind the port.  */
10080     nx_udp_socket_unbind(&(dhcpv6_ptr -> nx_dhcpv6_socket));
10081 
10082     /* Stop the timers. */
10083     tx_timer_deactivate(&(dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_timer));
10084     tx_timer_deactivate(&(dhcpv6_ptr -> nx_dhcpv6_session_timer));
10085 
10086     /* Restore preemption.  */
10087     tx_thread_preemption_change(tx_thread_identify(), current_preemption, &current_preemption);
10088 
10089 
10090     /* Release the DHCP mutex.  */
10091     tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
10092 
10093     /* Return completion status.  */
10094     return(NX_SUCCESS);
10095 }
10096 
10097 /**************************************************************************/
10098 /*                                                                        */
10099 /*  FUNCTION                                               RELEASE        */
10100 /*                                                                        */
10101 /*    _nxd_dhcpv6_reinitialize                            PORTABLE C      */
10102 /*                                                           6.1          */
10103 /*  AUTHOR                                                                */
10104 /*                                                                        */
10105 /*    Yuxin Zhou, Microsoft Corporation                                   */
10106 /*                                                                        */
10107 /*  DESCRIPTION                                                           */
10108 /*                                                                        */
10109 /*    This function performs error checking for the reinitializes the     */
10110 /*    DHCPv6 Client service.                                              */
10111 /*                                                                        */
10112 /*  INPUT                                                                 */
10113 /*                                                                        */
10114 /*    dhcpv6_ptr                            Pointer to DHCPv6 Client      */
10115 /*                                                                        */
10116 /*  OUTPUT                                                                */
10117 /*                                                                        */
10118 /*    status                                Actual completion status      */
10119 /*                                                                        */
10120 /*  CALLS                                                                 */
10121 /*                                                                        */
10122 /*    _nx_dhcpv6_reinitialize               Actual clear address service  */
10123 /*                                                                        */
10124 /*  CALLED BY                                                             */
10125 /*                                                                        */
10126 /*    Application Code                                                    */
10127 /*                                                                        */
10128 /*  RELEASE HISTORY                                                       */
10129 /*                                                                        */
10130 /*    DATE              NAME                      DESCRIPTION             */
10131 /*                                                                        */
10132 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10133 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10134 /*                                            resulting in version 6.1    */
10135 /*                                                                        */
10136 /**************************************************************************/
10137 
_nxe_dhcpv6_reinitialize(NX_DHCPV6 * dhcpv6_ptr)10138 UINT _nxe_dhcpv6_reinitialize(NX_DHCPV6 *dhcpv6_ptr)
10139 {
10140 
10141 UINT status;
10142 
10143        if (dhcpv6_ptr == NX_NULL)
10144        {
10145            return NX_PTR_ERROR;
10146        }
10147 
10148        /* Check for appropriate caller.  */
10149        NX_THREADS_ONLY_CALLER_CHECKING
10150 
10151        status = _nx_dhcpv6_reinitialize(dhcpv6_ptr);
10152 
10153        return status;
10154 }
10155 
10156 /**************************************************************************/
10157 /*                                                                        */
10158 /*  FUNCTION                                               RELEASE        */
10159 /*                                                                        */
10160 /*    _nx_dhcpv6_reinitialize                             PORTABLE C      */
10161 /*                                                           6.1          */
10162 /*  AUTHOR                                                                */
10163 /*                                                                        */
10164 /*    Yuxin Zhou, Microsoft Corporation                                   */
10165 /*                                                                        */
10166 /*  DESCRIPTION                                                           */
10167 /*                                                                        */
10168 /*    This function reinitializes the DHCP instance for restarting the    */
10169 /*    DHCP client state machine and re-running the DHCPv6 protocol.  This */
10170 /*    is not necessary if the Client has not previously obtained an       */
10171 /*    IP address from the server.  The IP address in both the DHCP Client */
10172 /*    data record and in the IP instance is cleared.                      */
10173 /*                                                                        */
10174 /*    Note: the host MUST stop the DHCPv6 client before calling this      */
10175 /*    service with the nx_dhcpv6_stop service.                            */
10176 /*                                                                        */
10177 /*  INPUT                                                                 */
10178 /*                                                                        */
10179 /*    dhcpv6_ptr                            Pointer to DHCPv6 Client      */
10180 /*                                                                        */
10181 /*  OUTPUT                                                                */
10182 /*                                                                        */
10183 /*    NX_DHCPV6_ALREADY_STARTED             DHCPv6 client is running      */
10184 /*    status                                Actual completion status      */
10185 /*                                                                        */
10186 /*  CALLS                                                                 */
10187 /*                                                                        */
10188 /*    _nx_dhcpv6_remove_assigned_address    Clears client IP address      */
10189 /*                                                                        */
10190 /*  CALLED BY                                                             */
10191 /*                                                                        */
10192 /*    Application Code                                                    */
10193 /*                                                                        */
10194 /*  RELEASE HISTORY                                                       */
10195 /*                                                                        */
10196 /*    DATE              NAME                      DESCRIPTION             */
10197 /*                                                                        */
10198 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10199 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10200 /*                                            resulting in version 6.1    */
10201 /*                                                                        */
10202 /**************************************************************************/
10203 
_nx_dhcpv6_reinitialize(NX_DHCPV6 * dhcpv6_ptr)10204 UINT _nx_dhcpv6_reinitialize(NX_DHCPV6 *dhcpv6_ptr)
10205 {
10206 
10207 UINT status;
10208 
10209 
10210     /* Check that the DHCPv6 client is started. */
10211     if (dhcpv6_ptr -> nx_dhcpv6_started ==  NX_TRUE)
10212     {
10213 
10214         /* Need to stop the DHCP client before we can reinitialize it. */
10215         return NX_DHCPV6_ALREADY_STARTED;
10216     }
10217 
10218     /* This clears the assigned IP address from the Client record, as well as
10219        removes the assigned IP address from the IP address table. */
10220     status = _nx_dhcpv6_remove_assigned_address(dhcpv6_ptr, NX_DHCPV6_REMOVE_ALL_IA_ADDRESS);
10221 
10222     return status;
10223 }
10224 
10225 
10226 /**************************************************************************/
10227 /*                                                                        */
10228 /*  FUNCTION                                               RELEASE        */
10229 /*                                                                        */
10230 /*    _nx_dhcpv6_thread_entry                             PORTABLE C      */
10231 /*                                                           6.1          */
10232 /*  AUTHOR                                                                */
10233 /*                                                                        */
10234 /*    Yuxin Zhou, Microsoft Corporation                                   */
10235 /*                                                                        */
10236 /*  DESCRIPTION                                                           */
10237 /*                                                                        */
10238 /*    This function is the background processing thread for the DHCPV6    */
10239 /*    Client.  It waits to be notified by ThreadX event flags when to     */
10240 /*    perform certain actions.  These include updating the time remaining */
10241 /*    on the Client IP address lease time, and maintaining the duration of*/
10242 /*    the current Client Server session (if Client has made a request).   */
10243 /*    It will terminate if a host application handler is called and       */
10244 /*    indicates the Client should abort.                                  */
10245 /*                                                                        */
10246 /*  INPUT                                                                 */
10247 /*                                                                        */
10248 /*    info                               Pointer to DHCPV6 Client instance*/
10249 /*                                                                        */
10250 /*  OUTPUT                                                                */
10251 /*                                                                        */
10252 /*    None                                                                */
10253 /*                                                                        */
10254 /*  CALLS                                                                 */
10255 /*                                                                        */
10256 /*    tx_event_flags_get                Receive notice of event flags set */
10257 /*    tx_mutex_get                      Obtain lock on Client resource    */
10258 /*    tx_mutex_put                      Release lock on Client resource   */
10259 /*    _nx_dhcpv6_request_renew          Initiate the RENEW request        */
10260 /*    _nx_dhcpv6_request_rebind         Initiate the REBIND request       */
10261 /*    _nx_dhcpv6_request_decline        Initiate the DECLINE request      */
10262 /*    _nx_dhcpv6_remove_assigned_address                                  */
10263 /*                                      Remove the assigned IPv6 address  */
10264 /*                                                                        */
10265 /*  CALLED BY                                                             */
10266 /*                                                                        */
10267 /*    ThreadX                                                             */
10268 /*                                                                        */
10269 /*  RELEASE HISTORY                                                       */
10270 /*                                                                        */
10271 /*    DATE              NAME                      DESCRIPTION             */
10272 /*                                                                        */
10273 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10274 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10275 /*                                            resulting in version 6.1    */
10276 /*                                                                        */
10277 /**************************************************************************/
_nx_dhcpv6_thread_entry(ULONG info)10278 VOID  _nx_dhcpv6_thread_entry(ULONG info)
10279 {
10280 
10281 UINT        status;
10282 NX_DHCPV6   *dhcpv6_ptr;
10283 UINT        current_preemption;
10284 ULONG       dhcpv6_events;
10285 UINT        ia_index;
10286 UINT        original_state;
10287 
10288     /* Setup the DHCPV6 Client pointer.  */
10289     NX_THREAD_EXTENSION_PTR_GET(dhcpv6_ptr, NX_DHCPV6, info)
10290 
10291     /* Process periodic DHCPv6 Client tasks. */
10292     do
10293     {
10294 
10295         /* Loop to get the DHCP mutex to handle error, release, and
10296            stop requests properly.  */
10297         do
10298         {
10299 
10300             /* Get the DHCP mutex.  */
10301             status =  tx_mutex_get(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex), NX_DHCPV6_MUTEX_WAIT);
10302 
10303         } while (status != TX_SUCCESS);
10304 
10305 
10306         /* Check the state of the DHCP Client state for further DHCP messaging. */
10307         _nx_dhcpv6_process(dhcpv6_ptr);
10308 
10309          /* Release the DHCP mutex.  */
10310         tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
10311 
10312         /* Disable preemption for critical section.  */
10313         tx_thread_preemption_change(tx_thread_identify(), 0, &current_preemption);
10314 
10315         /* Indicate the DHCP Client process is idle. */
10316         dhcpv6_ptr -> nx_dhcpv6_sleep_flag =  NX_TRUE;
10317 
10318         /* Sleep for timer interval.  */
10319         tx_thread_sleep(NX_DHCPV6_SESSION_TIMER_INTERVAL);
10320 
10321         /* Clear flag to indicate DHCP thread is not in a position to be stopped.  */
10322         dhcpv6_ptr -> nx_dhcpv6_sleep_flag =  NX_FALSE;
10323 
10324         /* Restore original preemption.  */
10325         tx_thread_preemption_change(tx_thread_identify(), current_preemption, &current_preemption);
10326 
10327         /* Check the expiration on valid and preferred lifetimes only if the Client is in the Bound state. */
10328         if (dhcpv6_ptr -> nx_dhcpv6_state == NX_DHCPV6_STATE_BOUND_TO_ADDRESS)
10329         {
10330 
10331             /* At time T1 for an IA, the client initiates a Renew message exchange to extend the lifetimes. RFC3315,page 42.*/
10332             if (dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_time_accrued >= dhcpv6_ptr -> nx_dhcpv6_iana.nx_T1)
10333             {
10334 
10335                 /* Indicate the DHCP Client process is idle while the handler executes. */
10336                 dhcpv6_ptr -> nx_dhcpv6_sleep_flag =  NX_TRUE;
10337 
10338                 /* Sending the renew message.  */
10339                 _nx_dhcpv6_request_renew(dhcpv6_ptr);
10340 
10341                 /* Reset flag to indicate DHCP thread is not idle (not stoppable).  */
10342                 dhcpv6_ptr -> nx_dhcpv6_sleep_flag =  NX_FALSE;
10343             }
10344         }
10345 
10346         /* Check the expiration on valid and preferred lifetimes only if the Client is in the sending renew state. */
10347         if (dhcpv6_ptr -> nx_dhcpv6_state == NX_DHCPV6_STATE_SENDING_RENEW)
10348         {
10349 
10350             /* At time T2 for an IA, The Client initiates a Rebind message exchanges. RFC3315, page 43. */
10351             if (dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_time_accrued >= dhcpv6_ptr -> nx_dhcpv6_iana.nx_T2)
10352             {
10353 
10354                 /* Indicate the DHCP Client process is idle while the handler executes. */
10355                 dhcpv6_ptr -> nx_dhcpv6_sleep_flag =  NX_TRUE;
10356 
10357                 /* Sending the rebind message.  */
10358                 _nx_dhcpv6_request_rebind(dhcpv6_ptr);
10359 
10360                 /* Reset flag to indicate DHCP thread is not idle (not stoppable).  */
10361                 dhcpv6_ptr -> nx_dhcpv6_sleep_flag =  NX_FALSE;
10362             }
10363         }
10364 
10365         /* Check the DHCPv6 Client state. */
10366         if ((dhcpv6_ptr -> nx_dhcpv6_state == NX_DHCPV6_STATE_BOUND_TO_ADDRESS) ||
10367             (dhcpv6_ptr -> nx_dhcpv6_state == NX_DHCPV6_STATE_SENDING_RENEW) ||
10368             (dhcpv6_ptr -> nx_dhcpv6_state == NX_DHCPV6_STATE_SENDING_REBIND))
10369         {
10370 
10371             for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
10372             {
10373 
10374                 /* Has the IP address valid lifetime expired?  */
10375                 if ((dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status) &&
10376                     (dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_time_accrued >= dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_valid_lifetime))
10377                 {
10378 
10379                     /* Save the existing state of the DHCPv6 Client. */
10380                     original_state = dhcpv6_ptr -> nx_dhcpv6_state;
10381 
10382                     /*  Clear the assigned IP address. */
10383                     _nx_dhcpv6_remove_assigned_address(dhcpv6_ptr, ia_index);
10384 
10385                     /* Indicate the DHCP Client process is idle while the handler executes. */
10386                     dhcpv6_ptr -> nx_dhcpv6_sleep_flag =  NX_TRUE;
10387 
10388                     /* Restart the Client to the solicit IP address request state. */
10389                     _nx_dhcpv6_request_solicit(dhcpv6_ptr);
10390 
10391                     /* Indicate the DHCP Client process is idle while the handler executes. */
10392                     dhcpv6_ptr -> nx_dhcpv6_sleep_flag =  NX_FALSE;
10393 
10394                     if (dhcpv6_ptr -> nx_dhcpv6_state_change_callback && (original_state != dhcpv6_ptr -> nx_dhcpv6_state))
10395                     {
10396                         /* Yes, call the state change callback with the original and new state. */
10397                         (dhcpv6_ptr -> nx_dhcpv6_state_change_callback)(dhcpv6_ptr, original_state, dhcpv6_ptr -> nx_dhcpv6_state);
10398                     }
10399                  }
10400             }
10401         }
10402 
10403 
10404 
10405         /* Pickup IP event flags.  */
10406         status = tx_event_flags_get(&(_nx_dhcpv6_DAD_ptr -> nx_dhcpv6_events), NX_IP_ALL_EVENTS, TX_OR_CLEAR, &dhcpv6_events, TX_NO_WAIT);
10407 
10408         /* Check for an IP receive packet event.  */
10409         if ((status == TX_SUCCESS) && (dhcpv6_events & NX_DHCPV6_DAD_FAILURE_EVENT))
10410         {
10411 
10412             /* Indicate the DHCP Client process is idle while the handler executes. */
10413             dhcpv6_ptr -> nx_dhcpv6_sleep_flag =  NX_TRUE;
10414 
10415             /* The DAD process failure, send DHCPv6 DECLINE message.  */
10416             _nx_dhcpv6_request_decline(dhcpv6_ptr);
10417 
10418             dhcpv6_events = dhcpv6_events & ~(ULONG)(NX_DHCPV6_DAD_FAILURE_EVENT);
10419 
10420             /* Reset flag to indicate DHCP thread is not idle (not stoppable).  */
10421             dhcpv6_ptr -> nx_dhcpv6_sleep_flag =  NX_FALSE;
10422         }
10423 
10424     } while (1);
10425 
10426 }
10427 
10428 
10429 /**************************************************************************/
10430 /*                                                                        */
10431 /*  FUNCTION                                               RELEASE        */
10432 /*                                                                        */
10433 /*    _nx_dhcpv6_utility_get_block_option_length          PORTABLE C      */
10434 /*                                                           6.1          */
10435 /*  AUTHOR                                                                */
10436 /*                                                                        */
10437 /*    Yuxin Zhou, Microsoft Corporation                                   */
10438 /*                                                                        */
10439 /*  DESCRIPTION                                                           */
10440 /*                                                                        */
10441 /*    This function parses the input buffer (assuming to be an option     */
10442 /*    block in a server reply) for option code and length. It assumes the */
10443 /*    buffer pointer is pointed to the first byte of the option buffer.   */
10444 /*                                                                        */
10445 /*  INPUT                                                                 */
10446 /*                                                                        */
10447 /*    dhcpv6_                             Pointer to DHCPv6 Client        */
10448 /*    option                              Option code of requested data   */
10449 /*    buffer_ptr                          Buffer to copy data to          */
10450 /*    length                              Size of buffer                  */
10451 /*                                              valid                     */
10452 /*                                                                        */
10453 /*  OUTPUT                                                                */
10454 /*                                                                        */
10455 /*    status                              Completion status               */
10456 /*    NX_DHCPV6_INCOMPLETE_OPTION_BLOCK   Unknown option specified        */
10457 /*                                                                        */
10458 /*  CALLS                                                                 */
10459 /*                                                                        */
10460 /*    _nx_dhcpv6_utility_get_data       Parses a specific data from the  */
10461 /*                                           DHCPv6 option                */
10462 /*                                                                        */
10463 /*  CALLED BY                                                             */
10464 /*                                                                        */
10465 /*    _nx_dhcpv6_utility_get_block_option_length                          */
10466 /*                                     Parses option code and length      */
10467 /*    _nx_dhcpv6_extract_packet_information                               */
10468 /*                                     Parses each option from server     */
10469 /*                                        reply and updates Client record */
10470 /*                                                                        */
10471 /*  RELEASE HISTORY                                                       */
10472 /*                                                                        */
10473 /*    DATE              NAME                      DESCRIPTION             */
10474 /*                                                                        */
10475 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10476 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10477 /*                                            resulting in version 6.1    */
10478 /*                                                                        */
10479 /**************************************************************************/
_nx_dhcpv6_utility_get_block_option_length(UCHAR * buffer_ptr,ULONG * option,ULONG * length)10480 UINT  _nx_dhcpv6_utility_get_block_option_length(UCHAR *buffer_ptr, ULONG *option, ULONG *length)
10481 {
10482 
10483     /* Initialize to zero. */
10484     *option = 0;
10485     *length = 0;
10486 
10487     /* First byte should be the op code. */
10488     _nx_dhcpv6_utility_get_data(buffer_ptr, 2, option);
10489 
10490     buffer_ptr += 2;
10491 
10492     /* Next byte should be the option length. */
10493     _nx_dhcpv6_utility_get_data(buffer_ptr, 2, length);
10494 
10495     /* Buffer is now pointed at the data (past the length field). */
10496     buffer_ptr += 2;
10497 
10498     /* Check for null data. */
10499     if (*option == 0)
10500     {
10501 
10502         return NX_DHCPV6_INCOMPLETE_OPTION_BLOCK;
10503     }
10504 
10505     return(NX_SUCCESS);
10506 
10507 }
10508 
10509 
10510 /**************************************************************************/
10511 /*                                                                        */
10512 /*  FUNCTION                                               RELEASE        */
10513 /*                                                                        */
10514 /*    _nx_dhcpv6_utility_get_data                         PORTABLE C      */
10515 /*                                                           6.1          */
10516 /*  AUTHOR                                                                */
10517 /*                                                                        */
10518 /*    Yuxin Zhou, Microsoft Corporation                                   */
10519 /*                                                                        */
10520 /*  DESCRIPTION                                                           */
10521 /*                                                                        */
10522 /*    This function parses the input buffer and returns numeric data      */
10523 /*    specified by the size argument, up to 4 bytes long.  Note that if   */
10524 /*    caller is using this utility to extract bytes from a DHCPv6 packet  */
10525 /*    there is no need for byte swapping, as compared to using memcpy in  */
10526 /*    which case there is for little endian processors.                   */
10527 /*                                                                        */
10528 /*  INPUT                                                                 */
10529 /*                                                                        */
10530 /*    buffer                            Pointer to data buffer            */
10531 /*    value                             Pointer to data parsed from buffer*/
10532 /*    size                              Size of buffer                    */
10533 /*                                                                        */
10534 /*  OUTPUT                                                                */
10535 /*                                                                        */
10536 /*    NX_DHCPV6_INVALID_DATA_SIZE       Requested data size too large     */
10537 /*    NX_SUCCESS                        Successful completion status      */
10538 /*                                                                        */
10539 /*  CALLS                                                                 */
10540 /*                                                                        */
10541 /*    None                                                                */
10542 /*                                                                        */
10543 /*  CALLED BY                                                             */
10544 /*    _nx_dhcpv6_process_server_duid   Process server duid in server reply*/
10545 /*    _nx_dhcpv6_process_client_duid   Process server duid in server reply*/
10546 /*    _nx_dhcpv6_utility_get_block_option_length                          */
10547 /*                                     Parses option code and length      */
10548 /*    _nx_dhcpv6_extract_packet_information                               */
10549 /*                                     Parses each option from server     */
10550 /*                                        reply and updates Client record */
10551 /*                                                                        */
10552 /*  RELEASE HISTORY                                                       */
10553 /*                                                                        */
10554 /*    DATE              NAME                      DESCRIPTION             */
10555 /*                                                                        */
10556 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10557 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10558 /*                                            resulting in version 6.1    */
10559 /*                                                                        */
10560 /**************************************************************************/
_nx_dhcpv6_utility_get_data(UCHAR * buffer,UINT size,ULONG * value)10561 UINT  _nx_dhcpv6_utility_get_data(UCHAR *buffer, UINT size, ULONG *value)
10562 {
10563 
10564 
10565     /* Check that the size of the data fits in a ULONG. */
10566     if (size > sizeof(ULONG))
10567     {
10568         return NX_DHCPV6_INVALID_DATA_SIZE;
10569     }
10570 
10571     *value = 0;
10572 
10573     /* Process the data retrieval request.  */
10574     while (size-- > 0)
10575     {
10576 
10577         /* Build return value.  */
10578         *value = (((*value) << 8) | (*buffer));
10579         buffer++;
10580     }
10581 
10582     /* Return value.  */
10583     return NX_SUCCESS;
10584 }
10585 
10586 
10587 /**************************************************************************/
10588 /*                                                                        */
10589 /*  FUNCTION                                               RELEASE        */
10590 /*                                                                        */
10591 /*    _nx_dhcpv6_utility_time_randomize                   PORTABLE C      */
10592 /*                                                           6.1          */
10593 /*  AUTHOR                                                                */
10594 /*                                                                        */
10595 /*    Yuxin Zhou, Microsoft Corporation                                   */
10596 /*                                                                        */
10597 /*  DESCRIPTION                                                           */
10598 /*                                                                        */
10599 /*    This function returns a value of between -1 seconds and 1 second    */
10600 /*    in system ticks.  It is used to randomize timeouts as required by   */
10601 /*    the RFC's so as to not overload a network server after power out.   */
10602 /*                                                                        */
10603 /*  INPUT                                                                 */
10604 /*                                                                        */
10605 /*    None                                                                */
10606 /*                                                                        */
10607 /*  OUTPUT                                                                */
10608 /*                                                                        */
10609 /*    ticks                                 Number of ticks between 1 & -1*/
10610 /*                                                                        */
10611 /*  CALLS                                                                 */
10612 /*                                                                        */
10613 /*    None                                                                */
10614 /*                                                                        */
10615 /*  CALLED BY                                                             */
10616 /*                                                                        */
10617 /*    _nx_dhcpv6_convert_delay_to_ticks     Convert seconds to ticks      */
10618 /*                                                                        */
10619 /*  RELEASE HISTORY                                                       */
10620 /*                                                                        */
10621 /*    DATE              NAME                      DESCRIPTION             */
10622 /*                                                                        */
10623 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10624 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10625 /*                                            resulting in version 6.1    */
10626 /*                                                                        */
10627 /**************************************************************************/
_nx_dhcpv6_utility_time_randomize(void)10628 INT  _nx_dhcpv6_utility_time_randomize(void)
10629 {
10630 
10631 UINT temp;
10632 UINT sign;
10633 INT temp_signed;
10634 
10635     temp = (UINT)(NX_RAND());
10636     temp &= (UINT)(0x001F);
10637     sign = (temp & (UINT)(0x8));
10638     temp_signed = (INT)temp;
10639 
10640     /* Try for a number between 0 and 0x1F. */
10641     if (sign)
10642     {
10643         temp_signed = -temp_signed;
10644     }
10645 
10646     return temp_signed;
10647 
10648 }
10649 
10650 /**************************************************************************/
10651 /*                                                                        */
10652 /*  FUNCTION                                               RELEASE        */
10653 /*                                                                        */
10654 /*    _nx_dhcpv6_waiting_on_reply                         PORTABLE C      */
10655 /*                                                           6.1          */
10656 /*  AUTHOR                                                                */
10657 /*                                                                        */
10658 /*    Yuxin Zhou, Microsoft Corporation                                   */
10659 /*                                                                        */
10660 /*  DESCRIPTION                                                           */
10661 /*                                                                        */
10662 /*    This function waits to receive a DHCPv6 server packet for the wait  */
10663 /*    time set by the DHCPv6 client previously. If a reply is received,   */
10664 /*    call function to process it.                                        */
10665 /*                                                                        */
10666 /*  INPUT                                                                 */
10667 /*                                                                        */
10668 /*    dhcpv6_ptr                       Pointer to DHCPV6 Client instance  */
10669 /*                                                                        */
10670 /*  OUTPUT                                                                */
10671 /*                                                                        */
10672 /*    status                           Actual completion status           */
10673 /*    NX_SUCCESS                       Valid packet received              */
10674 /*                                                                        */
10675 /*  CALLS                                                                 */
10676 /*                                                                        */
10677 /*    nx_udp_socket_receive            Receive UDP packet                 */
10678 /*    nx_packet_release                Release packet to packet pool      */
10679 /*    _nx_dhcpv6_packet_procss         Process the dhcpv6 packet          */
10680 /*    _nx_dhcpv6_flush_queue_packets   Flush the queue packets            */
10681 /*                                                                        */
10682 /*  CALLED BY                                                             */
10683 /*                                                                        */
10684 /*    _nx_dhcpv6_process               Process current client state       */
10685 /*                                                                        */
10686 /*  RELEASE HISTORY                                                       */
10687 /*                                                                        */
10688 /*    DATE              NAME                      DESCRIPTION             */
10689 /*                                                                        */
10690 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10691 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10692 /*                                            fixed compiler warnings,    */
10693 /*                                            resulting in version 6.1    */
10694 /*                                                                        */
10695 /**************************************************************************/
_nx_dhcpv6_waiting_on_reply(NX_DHCPV6 * dhcpv6_ptr)10696 UINT _nx_dhcpv6_waiting_on_reply(NX_DHCPV6 *dhcpv6_ptr)
10697 {
10698 
10699 UINT        current_preemption;
10700 UINT        status;
10701 NX_PACKET   *packet_ptr;
10702 ULONG       start_time;
10703 ULONG       current_time;
10704 ULONG       elapsed_time;
10705 ULONG       receive_wait;
10706 UINT        time_remaining;
10707 UINT        valid_answer;
10708 
10709     /* Initialize the parameters.  */
10710     packet_ptr = NX_NULL;
10711     valid_answer = NX_FALSE;
10712     time_remaining = dhcpv6_ptr -> nx_dhcpv6_transmission_timeout;
10713 
10714     /* Wait in short intervals to receive a valid packet while continuously checking for packets not intended
10715        for this DHCP Client to be removed from the receive queue. */
10716     do
10717     {
10718 
10719         /* Release the DHCP mutex while the Client will be blocked on a receive socket call.  */
10720         tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
10721 
10722         /* Disable preemption for critical section.  */
10723         tx_thread_preemption_change(tx_thread_identify(), 0, &current_preemption);
10724 
10725         /* Indicate the DHCP Client can be stopped.  */
10726         dhcpv6_ptr -> nx_dhcpv6_sleep_flag =  NX_TRUE;
10727 
10728         start_time = tx_time_get();
10729 
10730         if (time_remaining < NX_DHCPV6_TIME_INTERVAL)
10731         {
10732             receive_wait = time_remaining;
10733         }
10734         else
10735         {
10736             receive_wait = NX_DHCPV6_TIME_INTERVAL;
10737         }
10738 
10739         status = nx_udp_socket_receive(&(dhcpv6_ptr -> nx_dhcpv6_socket), &packet_ptr, receive_wait);
10740 
10741         /* Indicate the DHCP Client can not be stopped.  */
10742         dhcpv6_ptr -> nx_dhcpv6_sleep_flag =  NX_FALSE;
10743 
10744         /* Restore preemption/ end of critical section.  */
10745         tx_thread_preemption_change(tx_thread_identify(), current_preemption, &current_preemption);
10746 
10747         /* Yes, receive a packet.  */
10748         if (status == NX_SUCCESS)
10749         {
10750 
10751             /* Get the DHCP mutex.  */
10752             while((tx_mutex_get(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex), NX_NO_WAIT) != TX_SUCCESS) &&
10753                 (time_remaining > 0))
10754             {
10755 
10756                 if (time_remaining < NX_DHCPV6_TIME_INTERVAL)
10757                 {
10758                     tx_thread_sleep(time_remaining);
10759                     time_remaining = 0;
10760                 }
10761                 else
10762                 {
10763                     tx_thread_sleep(NX_DHCPV6_TIME_INTERVAL);
10764                     time_remaining = (UINT)(time_remaining - NX_DHCPV6_TIME_INTERVAL);
10765                 }
10766             }
10767 
10768             /* Process the dhcpv6 packet.  */
10769             status = _nx_dhcpv6_packet_process(dhcpv6_ptr, packet_ptr);
10770 
10771             /* Check the status.  */
10772             if(status == NX_SUCCESS)
10773             {
10774 
10775                 /* Yes, Get a valid advertise or reply message.  */
10776                 valid_answer = NX_TRUE;
10777 
10778                 /* DHCPv6 client MUST collect Advertise messages for the first RT seconds,
10779                    unless it receives an Advertise message with a preference value of 255.
10780                    RFC 3315, Section 17.1.2, Page 34.  */
10781                 if((dhcpv6_ptr -> nx_dhcpv6_state == NX_DHCPV6_STATE_SENDING_SOLICIT) &&
10782                    (dhcpv6_ptr -> nx_dhcpv6_retransmission_count == 0))
10783                 {
10784 
10785                     /* Process the rapid solicit mode.  */
10786                     if(dhcpv6_ptr -> nx_dhcpv6_request_solicit_mode == NX_DHCPV6_SOLICIT_RAPID)
10787                     {
10788 
10789                         /* Client terminates the waiting process as soon as a reply message
10790                            with a Rapid Commit option is received. RFC3315, Section17.1.2, Page34. */
10791                         break;
10792                     }
10793 
10794                     /* Process the normal solicit mode.  */
10795                     if(dhcpv6_ptr -> nx_dhcpv6_preference.nx_pref_value == 255)
10796                     {
10797 
10798                         /* If the client receives an Advertise message that includes a Preference option with
10799                            a preference value of 255, the client can terminates the waiting. */
10800                         break;
10801                     }
10802                 }
10803                 else
10804                 {
10805 
10806                     /* Yes, Get the answer.  */
10807                     break;
10808                 }
10809             }
10810         }
10811 
10812         /* How much time has elapsed? */
10813         current_time = tx_time_get();
10814 
10815         /* Has the time wrapped? */
10816         if (current_time >= start_time)
10817         {
10818             /* No, simply subtract to get the elapsed time.   */
10819             elapsed_time =  current_time - start_time;
10820         }
10821         else
10822         {
10823 
10824             /* Yes it has. Time has rolled over the 32-bit boundary.  */
10825             elapsed_time =  (((ULONG) 0xFFFFFFFF) - start_time) + current_time;
10826         }
10827 
10828         /* Update the time remaining. */
10829         if (time_remaining > elapsed_time)
10830         {
10831             time_remaining -= elapsed_time;
10832         }
10833         else
10834         {
10835             /*  Time is up, break out of this loop. */
10836             time_remaining = 0;
10837 
10838             /* But not before restoring preemption/ end of critical section! */
10839             tx_thread_preemption_change(tx_thread_identify(), current_preemption, &current_preemption);
10840 
10841             break;
10842         }
10843 
10844     } while(time_remaining > 0);
10845 
10846     /* Flush the queue packets.  */
10847     _nx_dhcpv6_flush_queue_packets(dhcpv6_ptr);
10848 
10849     /* Check the valid answer flag.  */
10850     if (valid_answer == NX_TRUE)
10851     {
10852         return NX_SUCCESS;
10853     }
10854     else
10855     {
10856         return NX_DHCPV6_INVALID_SERVER_PACKET;
10857     }
10858 }
10859 
10860 
10861 /**************************************************************************/
10862 /*                                                                        */
10863 /*  FUNCTION                                               RELEASE        */
10864 /*                                                                        */
10865 /*    _nx_dhcpv6_packet_process                           PORTABLE C      */
10866 /*                                                           6.1          */
10867 /*  AUTHOR                                                                */
10868 /*                                                                        */
10869 /*    Yuxin Zhou, Microsoft Corporation                                   */
10870 /*                                                                        */
10871 /*  DESCRIPTION                                                           */
10872 /*                                                                        */
10873 /*    This function process the receive pacet. the data is copied to      */
10874 /*    another packet from the DHCPv6 Client packet pool,and the original  */
10875 /*    received packet is released back to the receive pool immediately.   */
10876 /*    Then process the reply message.                                     */
10877 /*                                                                        */
10878 /*  INPUT                                                                 */
10879 /*                                                                        */
10880 /*    dhcpv6_ptr                       Pointer to DHCPV6 Client instance  */
10881 /*    packet_ptr                          Pointer to received packet      */
10882 /*                                                                        */
10883 /*  OUTPUT                                                                */
10884 /*                                                                        */
10885 /*    status                           Actual completion status           */
10886 /*    NX_SUCCESS                       Process correctly                  */
10887 /*                                                                        */
10888 /*  CALLS                                                                 */
10889 /*                                                                        */
10890 /*    nx_udp_socket_extract            Get the reply information          */
10891 /*    nx_packet_release                Release packet to packet pool      */
10892 /*    nx_packet_allocate               Allocate a new packet.             */
10893 /*    nx_packet_data_extract_offset    Store the received pacet data.     */
10894 /*    _nx_dhcpv6_scan_packet_options   Scan and record the reply options. */
10895 /*    _nx_dhcpv6_preprocess_packet_information                            */
10896 /*                                     Preprocess the packet according to */
10897 /*                                     the options record.                */
10898 /*    _nx_dhcpv6_extract_packet_information                               */
10899 /*                                     Extract server reply data          */
10900 /*                                                                        */
10901 /*  CALLED BY                                                             */
10902 /*                                                                        */
10903 /*    _nx_dhcpv6_waiting_on_reply      Process current client message     */
10904 /*                                                                        */
10905 /*  RELEASE HISTORY                                                       */
10906 /*                                                                        */
10907 /*    DATE              NAME                      DESCRIPTION             */
10908 /*                                                                        */
10909 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10910 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10911 /*                                            resulting in version 6.1    */
10912 /*                                                                        */
10913 /**************************************************************************/
_nx_dhcpv6_packet_process(NX_DHCPV6 * dhcpv6_ptr,NX_PACKET * packet_ptr)10914 UINT _nx_dhcpv6_packet_process(NX_DHCPV6 *dhcpv6_ptr, NX_PACKET *packet_ptr)
10915 {
10916 
10917 UINT        status;
10918 UINT        port;
10919 ULONG       bytes_copied;
10920 NXD_ADDRESS server_IP_Address;
10921 NX_PACKET   *new_packet_ptr;
10922 
10923 
10924     /* Check for valid packet length (message type and ID).  */
10925     if (packet_ptr -> nx_packet_length < 4)
10926     {
10927 
10928         /* Release the packet. */
10929         nx_packet_release(packet_ptr);
10930 
10931         /* Return.  */
10932         return(NX_DHCPV6_INVALID_DATA_SIZE);
10933     }
10934 
10935     /* Extract the IP and port number from the packet and set the reply address.  */
10936     status =  nxd_udp_source_extract(packet_ptr, &server_IP_Address, &port);
10937 
10938     /* Check status.  */
10939     if (status != NX_SUCCESS)
10940     {
10941 
10942         /* Release the packet. We don't want it. */
10943         nx_packet_release(packet_ptr);
10944 
10945         /* Error extracting packet source information, return error status.  */
10946         return(status);
10947     }
10948 
10949     /* Copy the received packet into the packet allocated by the DHCPv6 Client.  */
10950     status =  nx_packet_allocate(dhcpv6_ptr -> nx_dhcpv6_pool_ptr,
10951                                  &new_packet_ptr, NX_IPv6_UDP_PACKET,
10952                                  NX_DHCPV6_PACKET_TIME_OUT);
10953 
10954     /* Check for errors. */
10955     if (status != NX_SUCCESS)
10956     {
10957 
10958         /* Release the receive packet. We can't use it. */
10959         nx_packet_release(packet_ptr);
10960 
10961         return status;
10962     }
10963 
10964     /* Verify the incoming packet does not exceed our DHCPv6 Client packet payload. */
10965     if ((ULONG)(new_packet_ptr -> nx_packet_data_end - new_packet_ptr -> nx_packet_prepend_ptr) < packet_ptr -> nx_packet_length)
10966     {
10967 
10968         /* Release the packet allocated from the Client pool*/
10969         nx_packet_release(new_packet_ptr);
10970 
10971         /* Release the received packet. We can't use it. */
10972         nx_packet_release(packet_ptr);
10973 
10974         return(NX_DHCPV6_INVALID_DATA_SIZE);
10975     }
10976 
10977     /* Use a packet from the DHCP Client as a buffer to store the received packet data.
10978        Then we can release the received packet back to its packet pool. */
10979     status = nx_packet_data_extract_offset(packet_ptr, 0,(VOID *)new_packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length, &bytes_copied);
10980 
10981     /* Check status.  */
10982     if ((status != NX_SUCCESS) || (bytes_copied == 0))
10983     {
10984 
10985         /* Release the packet allocated from the Client pool*/
10986         nx_packet_release(new_packet_ptr);
10987 
10988         /* Release the received packet. We can't use it. */
10989         nx_packet_release(packet_ptr);
10990 
10991         /* Error extracting packet buffer, return error status.  */
10992         return(status);
10993     }
10994 
10995     /* Now we can release the received packet. */
10996     nx_packet_release(packet_ptr);
10997 
10998     /* Update the new packet with the bytes copied.  For chained packets, this will reflect the total
10999        'datagram' length. */
11000     new_packet_ptr -> nx_packet_length = bytes_copied;
11001     new_packet_ptr -> nx_packet_append_ptr = new_packet_ptr -> nx_packet_prepend_ptr + bytes_copied;
11002 
11003     /* Process the DHCPv6 packet.*/
11004 
11005     /* Scan the packet options and record it.  */
11006     status = _nx_dhcpv6_scan_packet_options(dhcpv6_ptr, new_packet_ptr);
11007 
11008     /* Check for errors processing the packet. */
11009     if (status != NX_SUCCESS)
11010     {
11011 
11012         /* Release the Client packet. We can't use it. */
11013         nx_packet_release(new_packet_ptr);
11014 
11015         /* Return error status. */
11016         return status;
11017     }
11018 
11019     /* Preprocess the packet options.  */
11020     status = _nx_dhcpv6_preprocess_packet_information(dhcpv6_ptr, new_packet_ptr);
11021 
11022     /* Check for errors processing the packet. */
11023     if (status != NX_SUCCESS)
11024     {
11025 
11026         /* Release the Client packet. We can't use it. */
11027         nx_packet_release(new_packet_ptr);
11028 
11029         /* Return error status. */
11030         return status;
11031     }
11032 
11033     /*  Extract the info from the packet buffer into the Client record. */
11034     status = _nx_dhcpv6_extract_packet_information(dhcpv6_ptr, new_packet_ptr);
11035 
11036     /* Release the Client packet. We are done with it. */
11037     nx_packet_release(new_packet_ptr);
11038 
11039     /* Store the DHCPv6 server address.  */
11040     if ((status == NX_SUCCESS) && (dhcpv6_ptr -> nx_dhcpv6_received_message_type == NX_DHCPV6_MESSAGE_TYPE_REPLY))
11041     {
11042         COPY_NXD_ADDRESS(&server_IP_Address, &(dhcpv6_ptr-> nx_dhcpv6_server_address));
11043     }
11044 
11045     /* Successfully processed response from the server. */
11046     return status;
11047 }
11048 
11049 
11050 /**************************************************************************/
11051 /*                                                                        */
11052 /*  FUNCTION                                               RELEASE        */
11053 /*                                                                        */
11054 /*    _nx_dhcpv6_scan_packet_options                      PORTABLE C      */
11055 /*                                                           6.1          */
11056 /*  AUTHOR                                                                */
11057 /*                                                                        */
11058 /*    Yuxin Zhou, Microsoft Corporation                                   */
11059 /*                                                                        */
11060 /*  DESCRIPTION                                                           */
11061 /*                                                                        */
11062 /*    This function scan the packet options of DHCPv6 server response and */
11063 /*    record the relevant options.                                        */
11064 /*                                                                        */
11065 /*  INPUT                                                                 */
11066 /*                                                                        */
11067 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
11068 /*    packet_ptr                          Pointer to received packet      */
11069 /*                                                                        */
11070 /*  OUTPUT                                                                */
11071 /*                                                                        */
11072 /*    status                              Actual completion status        */
11073 /*    NX_SUCCESS                          Successful completion status    */
11074 /*    NX_DHCPV6_UNKNOWN_OPTION            Unknown option in message       */
11075 /*                                                                        */
11076 /*  CALLS                                                                 */
11077 /*                                                                        */
11078 /*    _nx_dhcpv6_utility_get_block_option_length                          */
11079 /*                                        Extract option and length data  */
11080 /*    memcpy                              Copies specified area of memory */
11081 /*                                                                        */
11082 /*  CALLED BY                                                             */
11083 /*                                                                        */
11084 /*    _nx_dhcpv6_packet_process           Process dhcpv6 packet.          */
11085 /*                                                                        */
11086 /*  RELEASE HISTORY                                                       */
11087 /*                                                                        */
11088 /*    DATE              NAME                      DESCRIPTION             */
11089 /*                                                                        */
11090 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11091 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
11092 /*                                            verified memcpy use cases,  */
11093 /*                                            resulting in version 6.1    */
11094 /*                                                                        */
11095 /**************************************************************************/
_nx_dhcpv6_scan_packet_options(NX_DHCPV6 * dhcpv6_ptr,NX_PACKET * packet_ptr)11096 UINT  _nx_dhcpv6_scan_packet_options(NX_DHCPV6 *dhcpv6_ptr, NX_PACKET *packet_ptr)
11097 {
11098 
11099 UINT        status;
11100 UCHAR       *dhcpv6_option_ptr;
11101 UINT        index;
11102 ULONG       option_code;
11103 ULONG       option_length;
11104 UCHAR       *dhcpv6_iana_option_ptr;
11105 UINT        iana_index;
11106 ULONG       iana_option_code;
11107 ULONG       iana_option_length;
11108 UCHAR       *dhcpv6_ia_option_ptr;
11109 ULONG       ia_option_index;
11110 ULONG       ia_option_code;
11111 ULONG       ia_option_length;
11112 ULONG       ipv6_address[4];
11113 USHORT      status_code;
11114 UINT        ia_index;
11115 UINT        w;
11116 UINT        ia_count = 0;
11117 
11118     /* Set a pointer to the start of DHCPv6 options.  */
11119     dhcpv6_option_ptr = (packet_ptr -> nx_packet_prepend_ptr + 4);
11120 
11121     /* Initialize local variables. */
11122     index = 4;
11123     dhcpv6_ptr -> nx_dhcpv6_reply_option_flags = 0;
11124     dhcpv6_ptr -> nx_dhcpv6_reply_option_current_pref_value = 0;
11125 
11126     /* Clear the IA address map status.   */
11127     for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
11128     {
11129 
11130         dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_map = 0;
11131     }
11132 
11133     /* Now parse all the DHCPv6 option blocks in the packet buffer. */
11134     /* 4 bytes is data pointer offset, and 4 bytes for option code and option length. */
11135     while (index + 4 <= packet_ptr -> nx_packet_length)
11136     {
11137 
11138         /* Get the option code and length of data of the current option block. */
11139         status = _nx_dhcpv6_utility_get_block_option_length(dhcpv6_option_ptr, &option_code, &option_length);
11140 
11141         /* Check that the block data is valid. */
11142         if (status != NX_SUCCESS)
11143         {
11144 
11145             /* No, return the error status. */
11146             return status;
11147         }
11148 
11149         /* Check if option data is in the packet.  */
11150         if ((dhcpv6_option_ptr + 4 + option_length) > packet_ptr -> nx_packet_append_ptr)
11151         {
11152             return(NX_DHCPV6_INCOMPLETE_OPTION_BLOCK);
11153         }
11154 
11155         /* Process the option code with an option specific API. */
11156         switch (option_code)
11157         {
11158 
11159             /* Note - these 'process' functions will not move the buffer pointer. */
11160             case NX_DHCPV6_OP_CLIENT_ID:
11161             {
11162 
11163                 /* Yes, The message includes the Client DUID option.  */
11164                 dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_CLIENT_ID_OPTION;
11165                 break;
11166             }
11167 
11168             case NX_DHCPV6_OP_SERVER_ID:
11169             {
11170 
11171                 /* Yes, The message includes the Server DUID option.  */
11172                 dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_SERVER_ID_OPTION;
11173                 break;
11174             }
11175             case NX_DHCPV6_OP_IA_NA:
11176             {
11177 
11178                 /* The minimum length of IANA option field is 12 bytes.  */
11179                 if (option_length < 12)
11180                 {
11181                     return(NX_DHCPV6_INCOMPLETE_OPTION_BLOCK);
11182                 }
11183 
11184                 /* Yes, The message includes the Server DUID option.  */
11185                 dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_IA_NA_OPTION;
11186 
11187                 /* Skip the IA_NA header data (4 bytes for IANA option code and option length, 12 bytes for IANA option field).  */
11188                 dhcpv6_iana_option_ptr = dhcpv6_option_ptr + 4 + 12;
11189                 iana_index = 0;
11190 
11191                 /* Process the IA and status options embedded in the IANA option.  */
11192                 /* 12 bytes is IA_NA header, 4 bytes for iana sub option code and option length.  */
11193                 while(iana_index + 4 <= (option_length - 12))
11194                 {
11195 
11196                     /* Get the next option code and length. */
11197                     status = _nx_dhcpv6_utility_get_block_option_length(dhcpv6_iana_option_ptr, &iana_option_code, &iana_option_length);
11198 
11199                     /* Check if the option data is in the packet.  */
11200                     if ((dhcpv6_iana_option_ptr + 4 + iana_option_length) > packet_ptr -> nx_packet_append_ptr)
11201                     {
11202                         return(NX_DHCPV6_INCOMPLETE_OPTION_BLOCK);
11203                     }
11204 
11205                     /* Check the IA address option embedded in the IANA option. */
11206                     if(iana_option_code == NX_DHCPV6_OP_IA_ADDRESS)
11207                     {
11208 
11209                         /* The minimum length of IA address option is 24 bytes.  */
11210                         if (iana_option_length < 24)
11211                         {
11212                             return(NX_DHCPV6_INCOMPLETE_OPTION_BLOCK);
11213                         }
11214 
11215                         /* Yes, The message includes the IA option.  */
11216                         dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_IA_ADDRESS_OPTION;
11217 
11218                         /* Increase the IA option count.  */
11219                         ia_count ++;
11220 
11221                         /* Skip the IA type and length option.  */
11222                         ia_option_index = 4;
11223 
11224                         /* Get the IPv6 address of IA option.  */
11225                         for (w = 0; w <= 3; w++)
11226                         {
11227 
11228                             /* Copy each IPv6 address word into the IA address. */
11229                             memcpy(&ipv6_address[w], (dhcpv6_iana_option_ptr + ia_option_index), sizeof(ULONG)); /* Use case of memcpy is verified. */
11230 
11231                             /* Adjust for endianness. */
11232                             NX_CHANGE_ULONG_ENDIAN(ipv6_address[w]);
11233 
11234                             ia_option_index += 4;
11235                         }
11236 
11237                         /* Check the IA table, find the same IPv6 address.  */
11238                         for(w = 0; w < NX_DHCPV6_MAX_IA_ADDRESS; w++)
11239                         {
11240 
11241                             if(!(memcmp(&(dhcpv6_ptr->nx_dhcpv6_ia[w].nx_global_address.nxd_ip_address.v6[0]), &ipv6_address[0], 16)))
11242                             {
11243 
11244                                 /* Yes, it is, record the index to store the IA option, 0 means is IA address inexistence.
11245                                    Then update the IA option according to the IA count in nx_dhcpv6_update_ia function.  */
11246                                 dhcpv6_ptr -> nx_dhcpv6_ia[w].nx_address_map = ia_count;
11247                                 break;
11248                             }
11249                         }
11250 
11251                         /* Check the IA option whether include the status codes or not.  */
11252                         /* 24 bytes is IA address option, 4 bytes for next option code and option length.  */
11253                         if(iana_option_length >= (24 + 4))
11254                         {
11255 
11256                             /* Yes, include status codes, skip the IA header data.  */
11257                             dhcpv6_ia_option_ptr = dhcpv6_iana_option_ptr + 28;
11258 
11259                             /* Get the status code and length. */
11260                             status = _nx_dhcpv6_utility_get_block_option_length(dhcpv6_ia_option_ptr, &ia_option_code, &ia_option_length);
11261 
11262                             /* Check if the option data is in the packet.  */
11263                             if ((dhcpv6_ia_option_ptr + 4 + ia_option_length) > packet_ptr -> nx_packet_append_ptr)
11264                             {
11265                                 return(NX_DHCPV6_INCOMPLETE_OPTION_BLOCK);
11266                             }
11267 
11268                             if(ia_option_code == NX_DHCPV6_OP_STATUS_CODE)
11269                             {
11270                                 if (ia_option_length < 2)
11271                                 {
11272                                     return(NX_DHCPV6_INCOMPLETE_OPTION_BLOCK);
11273                                 }
11274 
11275                                 /* Yes, the message includes the STATUS option, get the code.  */
11276                                 memcpy(&status_code, (dhcpv6_ia_option_ptr + 4), sizeof(USHORT)); /* Use case of memcpy is verified. */
11277 
11278                                 /* Adjust for endianness. */
11279                                 NX_CHANGE_USHORT_ENDIAN(status_code);
11280 
11281                                 if(status_code == 0)
11282                                 {
11283 
11284                                     /* Yes, The message includes the Success status option.  */
11285                                     dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_SUCCESS_OPTION;
11286                                 }
11287                                 else if(status_code == 1)
11288                                 {
11289 
11290                                     /* Yes, The message includes the UnspecFail status option.  */
11291                                     dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_UNSPEC_FAIL_OPTION;
11292                                 }
11293                                 else if(status_code == 2)
11294                                 {
11295 
11296                                     /* Yes, The message includes the NoAddrsAvail status option.  */
11297                                     dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_NO_ADDR_AVAIL_OPTION;
11298                                 }
11299                                 else if(status_code == 3)
11300                                 {
11301 
11302                                     /* Yes, The message includes the NoBinding status option.  */
11303                                     dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_NO_BIND_OPTION;
11304                                 }
11305                                 else if(status_code == 4)
11306                                 {
11307 
11308                                     /* Yes, The message includes the NotOnLink status option.  */
11309                                     dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_NOT_ONLINK_OPTION;
11310                                 }
11311                                 else if(status_code == 5)
11312                                 {
11313 
11314                                     /* Yes, The message includes the UseMulticast status option.  */
11315                                     dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_USE_MULTICAST_OPTION;
11316                                 }
11317                                 else
11318                                 {
11319 
11320                                     /* This is an unsupported or unknown option. */
11321                                     return NX_DHCPV6_UNKNOWN_OPTION;
11322                                 }
11323 
11324                             }
11325                             else
11326                             {
11327 
11328                                 /* This is an unsupported or unknown option. */
11329                                 return NX_DHCPV6_UNKNOWN_OPTION;
11330                             }
11331                         }
11332                     }
11333 
11334                     /* Check if this is an status option request. */
11335                     else if(iana_option_code == NX_DHCPV6_OP_STATUS_CODE)
11336                     {
11337                         if (iana_option_length < 2)
11338                         {
11339                             return(NX_DHCPV6_INCOMPLETE_OPTION_BLOCK);
11340                         }
11341 
11342                         /* Yes, the message includes the STATUS option, get the code.  */
11343                         memcpy(&status_code, (dhcpv6_iana_option_ptr + 4), sizeof(USHORT)); /* Use case of memcpy is verified. */
11344 
11345                         /* Adjust for endianness. */
11346                         NX_CHANGE_USHORT_ENDIAN(status_code);
11347 
11348                         if(status_code == 0)
11349                         {
11350 
11351                             /* Yes, The message includes the Success status option.  */
11352                             dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_SUCCESS_OPTION;
11353                         }
11354                         else if(status_code == 1)
11355                         {
11356 
11357                             /* Yes, The message includes the UnspecFail status option.  */
11358                             dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_UNSPEC_FAIL_OPTION;
11359                         }
11360                         else if(status_code == 2)
11361                         {
11362 
11363                             /* Yes, The message includes the NoAddrsAvail status option.  */
11364                             dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_NO_ADDR_AVAIL_OPTION;
11365                         }
11366                         else if(status_code == 3)
11367                         {
11368 
11369                             /* Yes, The message includes the NoBinding status option.  */
11370                             dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_NO_BIND_OPTION;
11371                         }
11372                         else if(status_code == 4)
11373                         {
11374 
11375                             /* Yes, The message includes the NotOnLink status option.  */
11376                             dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_NOT_ONLINK_OPTION;
11377                         }
11378                         else if(status_code == 5)
11379                         {
11380 
11381                             /* Yes, The message includes the UseMulticast status option.  */
11382                             dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_USE_MULTICAST_OPTION;
11383                         }
11384                         else
11385                         {
11386 
11387                             /* This is an unsupported or unknown option. */
11388                             return NX_DHCPV6_UNKNOWN_OPTION;
11389                         }
11390                     }
11391                     else
11392                     {
11393 
11394                         /* This is an unsupported or unknown option. */
11395                         return NX_DHCPV6_UNKNOWN_OPTION;
11396                     }
11397 
11398                     /* Move to the next top level option. */
11399                     dhcpv6_iana_option_ptr += iana_option_length + 4;
11400 
11401                     /* Update the iana_index.  */
11402                     iana_index += iana_option_length + 4;
11403 
11404                 }
11405 
11406                 break;
11407             }
11408 
11409             case NX_DHCPV6_OP_PREFERENCE:
11410             {
11411 
11412                 /* The preference option length must be 1 byte.  */
11413                 if (option_length != 1)
11414                 {
11415                     return(NX_DHCPV6_INCOMPLETE_OPTION_BLOCK);
11416                 }
11417 
11418                 /* Yes, The message includes the preference option.  */
11419                 dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_PREFERENCE_OPTION;
11420 
11421                 /* Record the preference option value of current advetise message.  */
11422                 dhcpv6_ptr -> nx_dhcpv6_reply_option_current_pref_value = (USHORT)(*(dhcpv6_option_ptr + 4));
11423 
11424                 break;
11425             }
11426 
11427             case NX_DHCPV6_OP_STATUS_CODE:
11428             {
11429 
11430                 /* The minimum length of status option is 2 bytes.  */
11431                 if (option_length < 2)
11432                 {
11433                     return(NX_DHCPV6_INCOMPLETE_OPTION_BLOCK);
11434                 }
11435 
11436                 /* Yes, the message includes the STATUS option, get the code.  */
11437                 memcpy(&status_code, (dhcpv6_option_ptr + 4), sizeof(USHORT)); /* Use case of memcpy is verified. */
11438 
11439                 /* Adjust for endianness. */
11440                 NX_CHANGE_USHORT_ENDIAN(status_code);
11441 
11442                 if(status_code == 0)
11443                 {
11444 
11445                     /* Yes, The message includes the Success status option.  */
11446                     dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_SUCCESS_OPTION;
11447                 }
11448                 else if(status_code == 1)
11449                 {
11450 
11451                     /* Yes, The message includes the UnspecFail status option.  */
11452                     dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_UNSPEC_FAIL_OPTION;
11453                 }
11454                 else if(status_code == 2)
11455                 {
11456 
11457                     /* Yes, The message includes the NoAddrsAvail status option.  */
11458                     dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_NO_ADDR_AVAIL_OPTION;
11459                 }
11460                 else if(status_code == 3)
11461                 {
11462 
11463                     /* Yes, The message includes the NoBinding status option.  */
11464                     dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_NO_BIND_OPTION;
11465                 }
11466                 else if(status_code == 4)
11467                 {
11468 
11469                     /* Yes, The message includes the NotOnLink status option.  */
11470                     dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_NOT_ONLINK_OPTION;
11471                 }
11472                 else if(status_code == 5)
11473                 {
11474 
11475                     /* Yes, The message includes the UseMulticast status option.  */
11476                     dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_STATUS_USE_MULTICAST_OPTION;
11477                 }
11478                 else
11479                 {
11480 
11481                     /* This is an unsupported or unknown option. */
11482                     return NX_DHCPV6_UNKNOWN_OPTION;
11483                 }
11484                 break;
11485             }
11486 
11487             case NX_DHCPV6_OP_RAPID_COMMIT:
11488             {
11489 
11490                 /* Yes, The message includes the Rapid Commit option.  */
11491                 dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_RAPID_COMMIT_OPTION;
11492                 break;
11493             }
11494 
11495             case NX_DHCPV6_OP_DNS_SERVER:
11496             {
11497 
11498                 /* Yes, The message includes the DNS server option.  */
11499                 dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_DNS_SERVER_OPTION;
11500                 break;
11501             }
11502 
11503             case NX_DHCPV6_OP_DOMAIN_NAME:
11504             {
11505 
11506                 /* Yes, The message includes the domain name option.  */
11507                 dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_DOMAIN_NAME_OPTION;
11508                 break;
11509             }
11510 
11511             case NX_DHCPV6_OP_SNTP_SERVER:
11512             {
11513 
11514                 /* Yes, The message includes the timer server option.  */
11515                 dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_SNTP_SERVER_OPTION;
11516                 break;
11517             }
11518 
11519             case NX_DHCPV6_OP_CLIENT_FQDN:
11520             {
11521 
11522                 /* Yes, The message includes the Client FQDN option.  */
11523                 dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_CLIENT_FQDN_OPTION;
11524                 break;
11525             }
11526 
11527             case NX_DHCPV6_OP_NEW_POSIX_TIMEZONE:
11528             {
11529 
11530                 /* Yes, The message includes the time zone option.  */
11531                 dhcpv6_ptr -> nx_dhcpv6_reply_option_flags |= NX_DHCPV6_INCLUDE_NEW_POSIX_TIIMEZONE_OPTION;
11532                 break;
11533             }
11534 
11535             default:
11536             {
11537                 break;
11538             }
11539         }
11540 
11541         /* Move to the next top level option. */
11542          dhcpv6_option_ptr += option_length + 4;
11543 
11544         /* Keep track of how far into the packet we have parsed. */
11545         index += option_length + 4;
11546     }
11547 
11548     /* Yes, scan is complete, just return success. */
11549     return NX_SUCCESS;
11550 }
11551 
11552 /**************************************************************************/
11553 /*                                                                        */
11554 /*  FUNCTION                                               RELEASE        */
11555 /*                                                                        */
11556 /*    _nx_dhcpv6_preprocess_packet_information            PORTABLE C      */
11557 /*                                                           6.1          */
11558 /*  AUTHOR                                                                */
11559 /*                                                                        */
11560 /*    Yuxin Zhou, Microsoft Corporation                                   */
11561 /*                                                                        */
11562 /*  DESCRIPTION                                                           */
11563 /*                                                                        */
11564 /*    This function preprocess packet information according to reply      */
11565 /*    message option.                                                     */
11566 /*                                                                        */
11567 /*  INPUT                                                                 */
11568 /*                                                                        */
11569 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
11570 /*    packet_ptr                          Pointer to received packet      */
11571 /*                                                                        */
11572 /*  OUTPUT                                                                */
11573 /*                                                                        */
11574 /*    NX_DHCPv6_SUCCESS                   Successful completion status    */
11575 /*    NX_DHCPV6_NO_DUID_OPTION            Message has no DUID option      */
11576 /*    NX_DHCPV6_NO_RAPID_COMMIT_OPTION    Message has no rapid            */
11577 /*                                             commit  option             */
11578 /*    NX_DHCPV6_IA_ADDRESS_NOT_VALID      Message has no IA option        */
11579 /*    NX_DHCPV6_EQUAL_OR_LESS_PREF_VALUE  Preference value is equal to    */
11580 /*                                             or less than               */
11581 /*    NX_DHCPV6_UNKNOWN_MSG_TYPE          Unknown message type            */
11582 /*                                                                        */
11583 /*  CALLS                                                                 */
11584 /*                                                                        */
11585 /*    _nx_dhcpv6_utility_get_data         Get the data in reply message   */
11586 /*                                                                        */
11587 /*  CALLED BY                                                             */
11588 /*                                                                        */
11589 /*    _nx_dhcpv6_packet_process           Process the packet.             */
11590 /*                                                                        */
11591 /*  RELEASE HISTORY                                                       */
11592 /*                                                                        */
11593 /*    DATE              NAME                      DESCRIPTION             */
11594 /*                                                                        */
11595 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11596 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11597 /*                                            resulting in version 6.1    */
11598 /*                                                                        */
11599 /**************************************************************************/
_nx_dhcpv6_preprocess_packet_information(NX_DHCPV6 * dhcpv6_ptr,NX_PACKET * packet_ptr)11600 UINT  _nx_dhcpv6_preprocess_packet_information(NX_DHCPV6 *dhcpv6_ptr, NX_PACKET *packet_ptr)
11601 {
11602 
11603 ULONG       received_message_type;
11604 ULONG       returned_xid;
11605 
11606     /* Preprocess the DHCPv6 packet.  */
11607 
11608     /* Extract the message type which should be the first byte.  */
11609     _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr, 1, &received_message_type);
11610 
11611     /* Check for an illegal message type. */
11612     if ((received_message_type != NX_DHCPV6_MESSAGE_TYPE_ADVERTISE) &&
11613         (received_message_type != NX_DHCPV6_MESSAGE_TYPE_REPLY) &&
11614         (received_message_type != NX_DHCPV6_MESSAGE_TYPE_RECONFIGURE))
11615     {
11616 
11617         /* These should only be sent to DHCPv6 servers! */
11618         return NX_DHCPV6_ILLEGAL_MESSAGE_TYPE;
11619     }
11620 
11621     /* Set the received message type.  */
11622     dhcpv6_ptr -> nx_dhcpv6_received_message_type = (UCHAR)received_message_type;
11623 
11624     /* This is a unicast packet (valid). Parse the transaction ID. */
11625     _nx_dhcpv6_utility_get_data((packet_ptr -> nx_packet_prepend_ptr + 1), 3, &returned_xid);
11626 
11627     /* Make sure the DHCP transaction ID matches our current session. */
11628     if (returned_xid != (dhcpv6_ptr -> nx_dhcpv6_message_hdr.nx_message_xid))
11629     {
11630 
11631         /* Return the bad transmaction ID.  */
11632         return NX_DHCPV6_BAD_TRANSACTION_ID;
11633     }
11634 
11635     /* Check the options.  */
11636     switch (dhcpv6_ptr -> nx_dhcpv6_state)
11637     {
11638 
11639         /* The DHCPv6 remains initial status or DHCPv6 interactive process has been completed.
11640            Just clear the timer and message ID. */
11641         case NX_DHCPV6_STATE_BOUND_TO_ADDRESS:
11642         case NX_DHCPV6_STATE_INIT:
11643         {
11644 
11645             /* In these state, DHCPv6 Client do not expect any packet.  */
11646             return NX_DHCPV6_ILLEGAL_MESSAGE_TYPE;
11647         }
11648 
11649         /* The DHCPv6 CLient has sent a solicit message and expect advertise message. */
11650         case NX_DHCPV6_STATE_SENDING_SOLICIT:
11651         {
11652 
11653             /* DHCPv6 Client must discrd the received advertise messages
11654                that meet the message does not inlcude SERVER ID or CLIENT ID.  */
11655             if(!(dhcpv6_ptr -> nx_dhcpv6_reply_option_flags & NX_DHCPV6_INCLUDE_CLIENT_ID_OPTION) ||
11656                !(dhcpv6_ptr -> nx_dhcpv6_reply_option_flags & NX_DHCPV6_INCLUDE_SERVER_ID_OPTION))
11657             {
11658 
11659                 /* The packet does not include DUID option.*/
11660                 return NX_DHCPV6_NO_DUID_OPTION;
11661             }
11662 
11663             /* DHcpv6 Client must ignore any advertise message that includes a status code option
11664                containing the value NoAddrsAvail.  */
11665             if(dhcpv6_ptr -> nx_dhcpv6_reply_option_flags & NX_DHCPV6_INCLUDE_STATUS_NO_ADDR_AVAIL_OPTION)
11666             {
11667                 return NX_DHCPV6_IA_ADDRESS_NOT_VALID;
11668             }
11669 
11670             if(dhcpv6_ptr -> nx_dhcpv6_request_solicit_mode == NX_DHCPV6_SOLICIT_RAPID)
11671             {
11672                 if(!(dhcpv6_ptr -> nx_dhcpv6_reply_option_flags & NX_DHCPV6_INCLUDE_RAPID_COMMIT_OPTION))
11673                 {
11674 
11675                     return NX_DHCPV6_NO_RAPID_COMMIT_OPTION;
11676                 }
11677             }
11678             else
11679             {
11680 
11681                 /* Check the preference value.  */
11682                 if((dhcpv6_ptr -> nx_dhcpv6_preference.nx_pref_value != 0) &&
11683                    (dhcpv6_ptr -> nx_dhcpv6_reply_option_current_pref_value <= dhcpv6_ptr -> nx_dhcpv6_preference.nx_pref_value))
11684                 {
11685 
11686                     /* The current preference value is equal to or less than the recorded preference valude,
11687                        DHCPv6 Client need not process the message, return.  */
11688                     return NX_DHCPV6_EQUAL_OR_LESS_PREF_VALUE;
11689                 }
11690             }
11691 
11692             break;
11693         }
11694 
11695         /* The DHCPv6 CLien has sent a request message and expect reply message. */
11696         case NX_DHCPV6_STATE_SENDING_REQUEST:
11697         case NX_DHCPV6_STATE_SENDING_RENEW:
11698         case NX_DHCPV6_STATE_SENDING_REBIND:
11699         case NX_DHCPV6_STATE_SENDING_CONFIRM:
11700         case NX_DHCPV6_STATE_SENDING_RELEASE:
11701         case NX_DHCPV6_STATE_SENDING_DECLINE:
11702         case NX_DHCPV6_STATE_SENDING_INFORM_REQUEST:
11703         {
11704 
11705             /* DHCPv6 Client must discrd the received advertise messages
11706                that meet the message does not inlcude SERVE ID or CLIENT ID.  */
11707             if(!(dhcpv6_ptr -> nx_dhcpv6_reply_option_flags & NX_DHCPV6_INCLUDE_CLIENT_ID_OPTION) ||
11708                !(dhcpv6_ptr -> nx_dhcpv6_reply_option_flags & NX_DHCPV6_INCLUDE_SERVER_ID_OPTION))
11709             {
11710 
11711                 /* The packet does not include DUID option.*/
11712                 return NX_DHCPV6_NO_DUID_OPTION;
11713             }
11714             break;
11715         }
11716 
11717         default:
11718         {
11719 
11720             /* Unknown or unsupported DHCPv6 request (state).  */
11721             return NX_DHCPV6_UNKNOWN_MSG_TYPE;
11722         }
11723     }
11724 
11725     return NX_DHCPV6_SUCCESS;
11726 }
11727 
11728 
11729 /**************************************************************************/
11730 /*                                                                        */
11731 /*  FUNCTION                                               RELEASE        */
11732 /*                                                                        */
11733 /*    _nx_dhcpv6_extract_packet_information               PORTABLE C      */
11734 /*                                                           6.1          */
11735 /*  AUTHOR                                                                */
11736 /*                                                                        */
11737 /*    Yuxin Zhou, Microsoft Corporation                                   */
11738 /*                                                                        */
11739 /*  DESCRIPTION                                                           */
11740 /*                                                                        */
11741 /*    This function parses the DHCPv6 server response to Client requests. */
11742 /*    It checks for valid reply message types for the current Client      */
11743 /*    request, and if all is well, then parses each option in sequential  */
11744 /*    order and updates the server reply data to the Client record. At the*/
11745 /*    end of the data extraction, it then verifies that the server reply  */
11746 /*    contained both valid Client and server DUID options.                */
11747 /*                                                                        */
11748 /*  INPUT                                                                 */
11749 /*                                                                        */
11750 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
11751 /*    packet_ptr                          Pointer to received packet      */
11752 /*                                                                        */
11753 /*  OUTPUT                                                                */
11754 /*                                                                        */
11755 /*    status                              Actual completion status        */
11756 /*    NX_SUCCESS                          Successful completion status    */
11757 /*    NX_DHCPV6_ILLEGAL_MESSAGE_TYPE      Packet message type illegal     */
11758 /*    NX_DHCPV6_BAD_TRANSACTION_ID        Message ID fails to match up    */
11759 /*    NX_DHCPV6_PROCESSING_ERROR          Packet length is different than */
11760 /*                                                   expected             */
11761 /*    NX_DHCPV6_UNKNOWN_OPTION            Unknown option in message       */
11762 /*    NX_DHCPV6_MISSING_IANA_OPTION       Message has no IANA option      */
11763 /*                                                                        */
11764 /*  CALLS                                                                 */
11765 /*                                                                        */
11766 /*    _nx_dhcpv6_utility_get_block_option_length                          */
11767 /*                                        Extract option header data      */
11768 /*    _nx_dhcpv6_process_client_duid      Extract Client DUID from reply  */
11769 /*    _nx_dhcpv6_process_server_duid      Extract Server DUID from reply  */
11770 /*    _nx_dhcpv6_process_iana             Extract IANA option from reply  */
11771 /*    _nx_dhcpv6_process_preference       Extract server preference       */
11772 /*    _nx_dhcpv6_process_DNS_server       Extract DNS server from reply   */
11773 /*    _nx_dhcpv6_process_time_server      Extract time server from reply  */
11774 /*    _nx_dhcpv6_process_time_zone        Extract time zone from reply    */
11775 /*    _nx_dhcpv6_process_domain_name      Extract domain name from reply  */
11776 /*                                                                        */
11777 /*  CALLED BY                                                             */
11778 /*                                                                        */
11779 /*    _nx_dhcpv6_packet_process           Process the dhcpv6 reply message*/
11780 /*                                                                        */
11781 /*  RELEASE HISTORY                                                       */
11782 /*                                                                        */
11783 /*    DATE              NAME                      DESCRIPTION             */
11784 /*                                                                        */
11785 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11786 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
11787 /*                                            packet length verification, */
11788 /*                                            resulting in version 6.1    */
11789 /*                                                                        */
11790 /**************************************************************************/
_nx_dhcpv6_extract_packet_information(NX_DHCPV6 * dhcpv6_ptr,NX_PACKET * packet_ptr)11791 UINT  _nx_dhcpv6_extract_packet_information(NX_DHCPV6 *dhcpv6_ptr, NX_PACKET *packet_ptr)
11792 {
11793 
11794 UINT        status;
11795 ULONG       option_code;
11796 ULONG       option_length;
11797 UCHAR       *buffer_ptr;
11798 UINT        index;
11799 
11800     /* The DHCPv6 header has been processed in preprocess function, so process the options.  */
11801     /* Set a pointer to the options of DHCPv6. */
11802     buffer_ptr = packet_ptr -> nx_packet_prepend_ptr + 4;
11803 
11804     /* Update index to the options. */
11805     index = 4;
11806 
11807     /* Now parse all the DHCPv6 option blocks in the packet buffer. */
11808     while (index + 4 <= packet_ptr -> nx_packet_length)
11809     {
11810 
11811         /* Get the option code and length of data of the current option block. */
11812         status = _nx_dhcpv6_utility_get_block_option_length(buffer_ptr, &option_code, &option_length);
11813 
11814         /* Check that the block data is valid. */
11815         if (status != NX_SUCCESS)
11816         {
11817 
11818             /* No, return the error status. */
11819             return status;
11820         }
11821 
11822         /* Keep track of how far into the packet we have parsed. */
11823         index += option_length + 4;
11824 
11825         /* This is a double check to verify we haven't gone off the end of the packet buffer. */
11826         if (index > packet_ptr -> nx_packet_length)
11827         {
11828             return(NX_DHCPV6_INVALID_DATA_SIZE);
11829         }
11830 
11831         /* Update buffer pointer to option data.  */
11832         buffer_ptr += 4;
11833 
11834         /* Process the option code with an option specific API. */
11835         switch (option_code)
11836         {
11837 
11838             /* Note - these 'process' functions will not move the buffer pointer. */
11839 
11840             case NX_DHCPV6_OP_CLIENT_ID:
11841             {
11842 
11843                 /* Process the Client DUID.  */
11844                 status = _nx_dhcpv6_process_client_duid(dhcpv6_ptr, buffer_ptr, option_length);
11845 
11846                 break;
11847             }
11848 
11849             case NX_DHCPV6_OP_SERVER_ID:
11850             {
11851 
11852                 /* Process the Server DUID.  */
11853                 status = _nx_dhcpv6_process_server_duid(dhcpv6_ptr, buffer_ptr, option_length);
11854 
11855                 break;
11856             }
11857             case NX_DHCPV6_OP_IA_NA:
11858             {
11859 
11860                 status = _nx_dhcpv6_process_iana(dhcpv6_ptr, buffer_ptr, option_length);
11861 
11862                 /* Note: this API directly handles any server error codes received. */
11863 
11864                 break;
11865             }
11866 
11867             /* This should not happen. The IA address option must be embedded in the IANA option. */
11868             case NX_DHCPV6_OP_IA_ADDRESS:
11869             {
11870 
11871                 /* Don't process an IA address option outside of an address association (IANA). */
11872                 status = NX_DHCPV6_MISSING_IANA_OPTION;
11873 
11874                 break;
11875             }
11876 
11877             /* The RFC for DHCPv6 indicates any option can have a status option applied to it. So a status
11878                option outside of an IANA option (where it is usually found) has to be handled. */
11879             case NX_DHCPV6_OP_STATUS_CODE:
11880             {
11881                 status = _nx_dhcpv6_process_status(dhcpv6_ptr, buffer_ptr, option_length);
11882 
11883                 /* Now check on the server status of the previous option in the DHCP message. */
11884                 if ((status == NX_SUCCESS) && (dhcpv6_ptr -> nx_status_code != NX_DHCPV6_SUCCESS))
11885                 {
11886 
11887                     /* Does the dhcpv6 client have a server error handler? */
11888                     if (dhcpv6_ptr -> nx_dhcpv6_server_error_handler)
11889                     {
11890 
11891                         /* Send the status and which option the status is reported for to the handler. */
11892                         (dhcpv6_ptr -> nx_dhcpv6_server_error_handler)(dhcpv6_ptr, NX_DHCPV6_ERROR_STATUS_CODE_IN_OPTION_FIELD, dhcpv6_ptr -> nx_status_code,
11893                                                                        dhcpv6_ptr -> nx_dhcpv6_received_message_type);
11894                     }
11895                 }
11896 
11897                 break;
11898             }
11899 
11900             /* Process the preference option.  */
11901             case NX_DHCPV6_OP_PREFERENCE:
11902             {
11903 
11904                 status = _nx_dhcpv6_process_preference(dhcpv6_ptr, buffer_ptr, option_length);
11905                 break;
11906             }
11907 
11908             /* The remainder are RFC mandated option codes for specific options. Not all of these
11909                have been finalized by IANA as of this release. */
11910 
11911             case NX_DHCPV6_OP_DNS_SERVER:
11912             {
11913 
11914                 status = _nx_dhcpv6_process_DNS_server(dhcpv6_ptr, buffer_ptr, option_length);
11915 
11916                 break;
11917             }
11918 
11919             case NX_DHCPV6_OP_DOMAIN_NAME:
11920             {
11921                 status = _nx_dhcpv6_process_domain_name(dhcpv6_ptr, packet_ptr -> nx_packet_prepend_ptr, buffer_ptr, option_length);
11922                 break;
11923             }
11924 
11925             case NX_DHCPV6_OP_SNTP_SERVER:
11926             {
11927 
11928                 status = _nx_dhcpv6_process_time_server(dhcpv6_ptr, buffer_ptr, option_length);
11929                 break;
11930             }
11931 
11932             case NX_DHCPV6_OP_NEW_POSIX_TIMEZONE:
11933             {
11934                 status = _nx_dhcpv6_process_time_zone(dhcpv6_ptr, buffer_ptr, option_length);
11935                 break;
11936             }
11937 
11938             default:
11939             {
11940                 break;
11941             }
11942         }
11943 
11944         /* Check for errors from option block processing. */
11945         if (status != NX_SUCCESS)
11946         {
11947 
11948             return status;
11949         }
11950 
11951         /* Move to the next top level option. */
11952         buffer_ptr += option_length;
11953     }
11954 
11955     /* Now, the index should be the packet length.  */
11956     if(index != packet_ptr -> nx_packet_length)
11957     {
11958         return(NX_DHCPV6_INVALID_DATA_SIZE);
11959     }
11960 
11961     /* Yes, the packet data processing is completed.  */
11962     return NX_SUCCESS;
11963 }
11964 
11965 
11966 /**************************************************************************/
11967 /*                                                                        */
11968 /*  FUNCTION                                               RELEASE        */
11969 /*                                                                        */
11970 /*    _nx_dhcpv6_flush_queue_packets                      PORTABLE C      */
11971 /*                                                           6.1          */
11972 /*  AUTHOR                                                                */
11973 /*                                                                        */
11974 /*    Yuxin Zhou, Microsoft Corporation                                   */
11975 /*                                                                        */
11976 /*  DESCRIPTION                                                           */
11977 /*                                                                        */
11978 /*    This function flush the useless queue packets.                      */
11979 /*                                                                        */
11980 /*  INPUT                                                                 */
11981 /*                                                                        */
11982 /*    dhcpv6_ptr                          Pointer to DHCPv6 Client        */
11983 /*                                                                        */
11984 /*  OUTPUT                                                                */
11985 /*                                                                        */
11986 /*    None                                                                */
11987 /*                                                                        */
11988 /*  CALLS                                                                 */
11989 /*                                                                        */
11990 /*    nx_udp_socket_receive            Receive UDP packet                 */
11991 /*    nx_packet_release                Release packet to packet pool      */
11992 /*                                                                        */
11993 /*  CALLED BY                                                             */
11994 /*                                                                        */
11995 /*    _nx_dhcpv6_process               Process the DHCPv6 Client request  */
11996 /*                                                                        */
11997 /*  RELEASE HISTORY                                                       */
11998 /*                                                                        */
11999 /*    DATE              NAME                      DESCRIPTION             */
12000 /*                                                                        */
12001 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12002 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12003 /*                                            resulting in version 6.1    */
12004 /*                                                                        */
12005 /**************************************************************************/
_nx_dhcpv6_flush_queue_packets(NX_DHCPV6 * dhcpv6_ptr)12006 VOID  _nx_dhcpv6_flush_queue_packets(NX_DHCPV6 *dhcpv6_ptr)
12007 {
12008 
12009 UINT        status = NX_SUCCESS;
12010 NX_PACKET   *packet_ptr;
12011 
12012 
12013     /* Loop to receive the queue packets.  */
12014     while(status == NX_SUCCESS)
12015     {
12016 
12017         /* Receive the queue packets and release it.  */
12018         status = nx_udp_socket_receive(&(dhcpv6_ptr -> nx_dhcpv6_socket), &packet_ptr, NX_NO_WAIT);
12019 
12020         /* Check the status.  */
12021         if (status == NX_SUCCESS)
12022         {
12023 
12024             /* Release the packet.  */
12025             nx_packet_release(packet_ptr);
12026         }
12027     }
12028 }
12029 
12030 
12031 /**************************************************************************/
12032 /*                                                                        */
12033 /*  FUNCTION                                               RELEASE        */
12034 /*                                                                        */
12035 /*    _nx_dhcpv6_update_retransmit_info                   PORTABLE C      */
12036 /*                                                           6.1          */
12037 /*  AUTHOR                                                                */
12038 /*                                                                        */
12039 /*    Yuxin Zhou, Microsoft Corporation                                   */
12040 /*                                                                        */
12041 /*  DESCRIPTION                                                           */
12042 /*                                                                        */
12043 /*    This function process the retransmission,update the retransmission  */
12044 /*    count and retransmission timeout according to the RFC3315,Section14.*/
12045 /*                                                                        */
12046 /*  INPUT                                                                 */
12047 /*                                                                        */
12048 /*    dhcpv6_ptr                       Pointer to DHCPV6 Client instance  */
12049 /*                                                                        */
12050 /*  OUTPUT                                                                */
12051 /*                                                                        */
12052 /*    status                           Actual completion status           */
12053 /*    NX_SUCCESS                       Valid retransmit                   */
12054 /*                                                                        */
12055 /*  CALLS                                                                 */
12056 /*                                                                        */
12057 /*                                                                        */
12058 /*  CALLED BY                                                             */
12059 /*                                                                        */
12060 /*    _nx_dhcpv6_process               Process current client state       */
12061 /*                                                                        */
12062 /*  RELEASE HISTORY                                                       */
12063 /*                                                                        */
12064 /*    DATE              NAME                      DESCRIPTION             */
12065 /*                                                                        */
12066 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12067 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12068 /*                                            resulting in version 6.1    */
12069 /*                                                                        */
12070 /**************************************************************************/
_nx_dhcpv6_update_retransmit_info(NX_DHCPV6 * dhcpv6_ptr)12071 UINT _nx_dhcpv6_update_retransmit_info(NX_DHCPV6 *dhcpv6_ptr)
12072 {
12073 
12074     /* Process the retransmission according to the RFC3315, Section 14, page26.  */
12075     if((dhcpv6_ptr -> nx_dhcpv6_max_retransmission_count != 0) || (dhcpv6_ptr -> nx_dhcpv6_max_retransmission_duration != 0))
12076     {
12077 
12078         if((dhcpv6_ptr -> nx_dhcpv6_max_retransmission_count != 0) &&
12079            (dhcpv6_ptr -> nx_dhcpv6_retransmission_count >= dhcpv6_ptr -> nx_dhcpv6_max_retransmission_count))
12080         {
12081 
12082             /* Has reached the max retransmission count, return. */
12083             return NX_DHCPV6_REACHED_MAX_RETRANSMISSION_COUNT;
12084         }
12085 
12086         if((dhcpv6_ptr -> nx_dhcpv6_max_retransmission_duration != 0) &&
12087            (dhcpv6_ptr -> nx_dhcpv6_elapsed_time.nx_session_time >= (dhcpv6_ptr -> nx_dhcpv6_max_retransmission_duration * 100)))
12088         {
12089 
12090             /* Has reached the max retransmission timeout, return. */
12091             return NX_DHCPV6_REACHED_MAX_RETRANSMISSION_TIMEOUT;
12092         }
12093     }
12094 
12095     /* Increase the count of retransmission. */
12096     dhcpv6_ptr -> nx_dhcpv6_retransmission_count++;
12097 
12098     /* Double the retransmission timeout for the next retransmit. */
12099     dhcpv6_ptr -> nx_dhcpv6_transmission_timeout = 2 * dhcpv6_ptr -> nx_dhcpv6_transmission_timeout;
12100 
12101     /* Is the retransmission timeout greater than the max allowable timeout, if there is one? */
12102     if ((dhcpv6_ptr -> nx_dhcpv6_max_retransmission_timeout != 0) &&
12103         (dhcpv6_ptr -> nx_dhcpv6_transmission_timeout > dhcpv6_ptr -> nx_dhcpv6_max_retransmission_timeout))
12104     {
12105 
12106         /* Limit the transmission time to the max for the next message. */
12107         dhcpv6_ptr -> nx_dhcpv6_transmission_timeout = dhcpv6_ptr -> nx_dhcpv6_max_retransmission_timeout;
12108     }
12109 
12110     /* Can retransmit the request. */
12111     return NX_SUCCESS;
12112 }
12113 
12114 
12115 /**************************************************************************/
12116 /*                                                                        */
12117 /*  FUNCTION                                               RELEASE        */
12118 /*                                                                        */
12119 /*    _nxe_dhcpv6_user_option_add_callback_set             PORTABLE C     */
12120 /*                                                           6.1.12       */
12121 /*  AUTHOR                                                                */
12122 /*                                                                        */
12123 /*    Yuxin Zhou, Microsoft Corporation                                   */
12124 /*                                                                        */
12125 /*  DESCRIPTION                                                           */
12126 /*                                                                        */
12127 /*    This function performs error checking on the user option add        */
12128 /*    callback set service.                                               */
12129 /*                                                                        */
12130 /*  INPUT                                                                 */
12131 /*                                                                        */
12132 /*    dhcpv6_ptr                            Pointer to DHCPv6 instance    */
12133 /*    dhcpv6_user_option_add                Pointer to application's      */
12134 /*                                            option add function         */
12135 /*                                                                        */
12136 /*  OUTPUT                                                                */
12137 /*                                                                        */
12138 /*    status                                Completion status             */
12139 /*                                                                        */
12140 /*  CALLS                                                                 */
12141 /*                                                                        */
12142 /*    _nx_dhcpv6_user_option_add_callback_set Actual user option callback */
12143 /*                                            set service                 */
12144 /*                                                                        */
12145 /*  CALLED BY                                                             */
12146 /*                                                                        */
12147 /*    Application Code                                                    */
12148 /*                                                                        */
12149 /*  RELEASE HISTORY                                                       */
12150 /*                                                                        */
12151 /*    DATE              NAME                      DESCRIPTION             */
12152 /*                                                                        */
12153 /*  07-29-2022     Yuxin Zhou               Initial Version 6.1.12        */
12154 /*                                                                        */
12155 /**************************************************************************/
_nxe_dhcpv6_user_option_add_callback_set(NX_DHCPV6 * dhcpv6_ptr,UINT (* dhcpv6_user_option_add)(NX_DHCPV6 * dhcpv6_ptr,UINT interface_index,UINT message_type,UCHAR * user_option_ptr,UINT * user_option_length))12156 UINT _nxe_dhcpv6_user_option_add_callback_set(NX_DHCPV6 *dhcpv6_ptr, UINT (*dhcpv6_user_option_add)(NX_DHCPV6 *dhcpv6_ptr, UINT interface_index, UINT message_type,
12157                                                                                                     UCHAR *user_option_ptr, UINT *user_option_length))
12158 {
12159 
12160 UINT    status;
12161 
12162     /* Check for invalid input. */
12163     if ((dhcpv6_ptr == NX_NULL) || (dhcpv6_user_option_add == NX_NULL))
12164     {
12165         return(NX_PTR_ERROR);
12166     }
12167 
12168     /* Call actual DHCPv6 user option callback set service.  */
12169     status =  _nx_dhcpv6_user_option_add_callback_set(dhcpv6_ptr, dhcpv6_user_option_add);
12170 
12171     /* Return status.  */
12172     return(status);
12173 }
12174 
12175 
12176 /**************************************************************************/
12177 /*                                                                        */
12178 /*  FUNCTION                                               RELEASE        */
12179 /*                                                                        */
12180 /*    _nx_dhcpv6_user_option_add_callback_set             PORTABLE C      */
12181 /*                                                           6.1.12       */
12182 /*  AUTHOR                                                                */
12183 /*                                                                        */
12184 /*    Yuxin Zhou, Microsoft Corporation                                   */
12185 /*                                                                        */
12186 /*  DESCRIPTION                                                           */
12187 /*                                                                        */
12188 /*    This function sets the user option add callback.                    */
12189 /*                                                                        */
12190 /*  INPUT                                                                 */
12191 /*                                                                        */
12192 /*    dhcpv6_ptr                            Pointer to DHCPv6 instance    */
12193 /*    dhcpv6_user_option_add                Pointer to application's      */
12194 /*                                            option add function         */
12195 /*                                                                        */
12196 /*  OUTPUT                                                                */
12197 /*                                                                        */
12198 /*    status                                Completion status             */
12199 /*                                                                        */
12200 /*  CALLS                                                                 */
12201 /*                                                                        */
12202 /*    None                                                                */
12203 /*                                                                        */
12204 /*  CALLED BY                                                             */
12205 /*                                                                        */
12206 /*    Application Code                                                    */
12207 /*                                                                        */
12208 /*  RELEASE HISTORY                                                       */
12209 /*                                                                        */
12210 /*    DATE              NAME                      DESCRIPTION             */
12211 /*                                                                        */
12212 /*  07-29-2022     Yuxin Zhou               Initial Version 6.1.12        */
12213 /*                                                                        */
12214 /**************************************************************************/
_nx_dhcpv6_user_option_add_callback_set(NX_DHCPV6 * dhcpv6_ptr,UINT (* dhcpv6_user_option_add)(NX_DHCPV6 * dhcpv6_ptr,UINT interface_index,UINT message_type,UCHAR * user_option_ptr,UINT * user_option_length))12215 UINT _nx_dhcpv6_user_option_add_callback_set(NX_DHCPV6 *dhcpv6_ptr, UINT (*dhcpv6_user_option_add)(NX_DHCPV6 *dhcpv6_ptr, UINT interface_index, UINT message_type,
12216                                                                                                    UCHAR *user_option_ptr, UINT *user_option_length))
12217 {
12218 
12219     /* Obtain DHCPv6 Client protection mutex. */
12220     tx_mutex_get(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex), TX_WAIT_FOREVER);
12221 
12222     /* Set the callback.  */
12223     dhcpv6_ptr -> nx_dhcpv6_user_option_add = dhcpv6_user_option_add;
12224 
12225     /* Release the mutex.  */
12226     tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
12227 
12228     /* Return a successful status.  */
12229     return(NX_SUCCESS);
12230 }
12231 
12232 
12233 #if !defined (NX_DISABLE_IPV6_DAD) && defined (NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY)
12234 /**************************************************************************/
12235 /*                                                                        */
12236 /*  FUNCTION                                               RELEASE        */
12237 /*                                                                        */
12238 /*    _nx_dhcpv6_ipv6_address_DAD_notify                  PORTABLE C      */
12239 /*                                                           6.1          */
12240 /*  AUTHOR                                                                */
12241 /*                                                                        */
12242 /*    Yuxin Zhou, Microsoft Corporation                                   */
12243 /*                                                                        */
12244 /*  DESCRIPTION                                                           */
12245 /*                                                                        */
12246 /*    This function is the IPv6 address perform DAD notify callback.      */
12247 /*    And set the DHCPv6 event to notify DHCPv6 Client thread. If this    */
12248 /*    function is used in DHCPv6 function, nxd_ipv6_address_change_notify */
12249 /*    function should not be used again.                                  */
12250 /*                                                                        */
12251 /*  INPUT                                                                 */
12252 /*                                                                        */
12253 /*    ip_ptr                                Pointer to IP instance        */
12254 /*    status                                DAD process status            */
12255 /*    interface_index                       The interface index           */
12256 /*    ipv6_addr_index                       The IPv6 address index        */
12257 /*    ipv6_address                          Pointer to IPv6 address       */
12258 /*                                                                        */
12259 /*  OUTPUT                                                                */
12260 /*                                                                        */
12261 /*    None                                                                */
12262 /*                                                                        */
12263 /*  CALLS                                                                 */
12264 /*                                                                        */
12265 /*    tx_event_flags_set                    Set event flags to wake       */
12266 /*                                          DHCPv6 thread to process      */
12267 /*                                                                        */
12268 /*  CALLED BY                                                             */
12269 /*                                                                        */
12270 /*    UDP receive callback                                                */
12271 /*                                                                        */
12272 /*  RELEASE HISTORY                                                       */
12273 /*                                                                        */
12274 /*    DATE              NAME                      DESCRIPTION             */
12275 /*                                                                        */
12276 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12277 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12278 /*                                            resulting in version 6.1    */
12279 /*                                                                        */
12280 /**************************************************************************/
_nx_dhcpv6_ipv6_address_DAD_notify(NX_IP * ip_ptr,UINT status,UINT interface_index,UINT ipv6_addr_index,ULONG * ipv6_address)12281 VOID _nx_dhcpv6_ipv6_address_DAD_notify(NX_IP *ip_ptr, UINT status, UINT interface_index, UINT ipv6_addr_index, ULONG *ipv6_address)
12282 {
12283 UINT    ia_index;
12284 
12285     NX_PARAMETER_NOT_USED(interface_index);
12286 
12287     /* Make sure the DHCPv6 DAD instance is normal.  */
12288     if((_nx_dhcpv6_DAD_ptr -> nx_dhcpv6_id != NX_DHCPV6_ID) ||
12289        (!_nx_dhcpv6_DAD_ptr -> nx_dhcpv6_name) ||
12290        (_nx_dhcpv6_DAD_ptr -> nx_dhcpv6_ip_ptr != ip_ptr) ||
12291        (_nx_dhcpv6_DAD_ptr -> nx_dhcpv6_state != NX_DHCPV6_STATE_BOUND_TO_ADDRESS))
12292         return;
12293 
12294 
12295     /* Check the DAD status.  */
12296     if(status == NX_IPV6_ADDRESS_DAD_FAILURE)
12297     {
12298 
12299         /* Now find where this address cross references in the DHCP address list. */
12300         for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
12301         {
12302 
12303             if((_nx_dhcpv6_DAD_ptr -> nx_dhcpv6_client_address_index[ia_index] == ipv6_addr_index) &&
12304                (!memcmp(&(_nx_dhcpv6_DAD_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[0]), ipv6_address, 16)))
12305             {
12306 
12307                 /* Set the IPv6 address status DAD failure.  */
12308                 _nx_dhcpv6_DAD_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status = NX_DHCPV6_IA_ADDRESS_STATE_DAD_FAILURE;
12309 
12310                 /* Wakeup DHCPv6 thread for processing DAD failure event.  */
12311                 tx_event_flags_set(&_nx_dhcpv6_DAD_ptr -> nx_dhcpv6_events, NX_DHCPV6_DAD_FAILURE_EVENT, TX_OR);
12312 
12313                 break;
12314             }
12315         }
12316     }
12317 
12318     /* Check the DAD status.  */
12319     if(status == NX_IPV6_ADDRESS_DAD_SUCCESSFUL)
12320     {
12321 
12322         for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
12323         {
12324 
12325             if((_nx_dhcpv6_DAD_ptr -> nx_dhcpv6_client_address_index[ia_index] == ipv6_addr_index) &&
12326                (!memcmp(&(_nx_dhcpv6_DAD_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address.nxd_ip_address.v6[0]), ipv6_address, 16)))
12327             {
12328 
12329                 /* Set the IPv6 address status valid.  */
12330                 _nx_dhcpv6_DAD_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status = NX_DHCPV6_IA_ADDRESS_STATE_VALID;
12331 
12332                 break;
12333             }
12334         }
12335     }
12336 
12337     return;
12338 }
12339 #endif
12340 
12341 
12342 #ifdef NX_DHCPV6_CLIENT_RESTORE_STATE
12343 /**************************************************************************/
12344 /*                                                                        */
12345 /*  FUNCTION                                               RELEASE        */
12346 /*                                                                        */
12347 /*    _nxe_dhcpv6_client_get_record                       PORTABLE C      */
12348 /*                                                           6.1          */
12349 /*  AUTHOR                                                                */
12350 /*                                                                        */
12351 /*    Yuxin Zhou, Microsoft Corporation                                   */
12352 /*                                                                        */
12353 /*  DESCRIPTION                                                           */
12354 /*                                                                        */
12355 /*    This function performs error checking on the get DHCPv6 Client      */
12356 /*    record service.                                                     */
12357 /*                                                                        */
12358 /*  INPUT                                                                 */
12359 /*                                                                        */
12360 /*    dhcpv6_ptr                            Pointer to DHCPv6 instance    */
12361 /*    client_record_ptr                     Pointer to memory to save     */
12362 /*                                             Client record to           */
12363 /*                                                                        */
12364 /*  OUTPUT                                                                */
12365 /*                                                                        */
12366 /*    NX_PTR_ERROR                          Invalid pointer input         */
12367 /*    status                                Completion status from        */
12368 /*                                            internal DHCP calls         */
12369 /*                                                                        */
12370 /*  CALLS                                                                 */
12371 /*                                                                        */
12372 /*   _nx_dhcpv6_client_create_record                                      */
12373 /*                                                                        */
12374 /*  CALLED BY                                                             */
12375 /*                                                                        */
12376 /*    Application code                                                    */
12377 /*                                                                        */
12378 /*  RELEASE HISTORY                                                       */
12379 /*                                                                        */
12380 /*    DATE              NAME                      DESCRIPTION             */
12381 /*                                                                        */
12382 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12383 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12384 /*                                            resulting in version 6.1    */
12385 /*                                                                        */
12386 /**************************************************************************/
_nxe_dhcpv6_client_get_record(NX_DHCPV6 * dhcpv6_ptr,NX_DHCPV6_CLIENT_RECORD * client_record_ptr)12387 UINT  _nxe_dhcpv6_client_get_record(NX_DHCPV6 *dhcpv6_ptr, NX_DHCPV6_CLIENT_RECORD *client_record_ptr)
12388 {
12389 
12390 UINT status;
12391 
12392 
12393     /* Check for invalid pointer input.  */
12394     if ((dhcpv6_ptr == NX_NULL) || (client_record_ptr == NX_NULL))
12395     {
12396         return NX_PTR_ERROR;
12397     }
12398 
12399     /* Call actual DHCPv6 client get record service.  */
12400     status = _nx_dhcpv6_client_get_record(dhcpv6_ptr, client_record_ptr);
12401 
12402     return status;
12403 }
12404 
12405 /**************************************************************************/
12406 /*                                                                        */
12407 /*  FUNCTION                                               RELEASE        */
12408 /*                                                                        */
12409 /*    _nx_dhcpv6_client_get_record                        PORTABLE C      */
12410 /*                                                           6.1          */
12411 /*  AUTHOR                                                                */
12412 /*                                                                        */
12413 /*    Yuxin Zhou, Microsoft Corporation                                   */
12414 /*                                                                        */
12415 /*  DESCRIPTION                                                           */
12416 /*                                                                        */
12417 /*    This function creates a DHCPv6 Client record for restoring the      */
12418 /*    Client state between power cycles or idle (sleep) mode. It then     */
12419 /*    copies the Client record to the supplied client record pointer. It  */
12420 /*    should be that the DHCPv6 Client state be restored from the Client  */
12421 /*    record saved to the input pointer client_record_ptr.                */
12422 /*                                                                        */
12423 /*  INPUT                                                                 */
12424 /*                                                                        */
12425 /*    dhcpv6_ptr                            Pointer to DHCPv6 instance    */
12426 /*    client_record_ptr                     Pointer to memory to save     */
12427 /*                                             Client record to           */
12428 /*                                                                        */
12429 /*  OUTPUT                                                                */
12430 /*                                                                        */
12431 /*    NX_SUCCESS                            Successful completion status  */
12432 /*    NX_DHCPV6_NOT_BOUND                   DHCPv6 was not bound          */
12433 /*                                                                        */
12434 /*  CALLS                                                                 */
12435 /*                                                                        */
12436 /*    memcpy                                Copy specified area of memory */
12437 /*                                                                        */
12438 /*  CALLED BY                                                             */
12439 /*                                                                        */
12440 /*    Application code                                                    */
12441 /*                                                                        */
12442 /*  RELEASE HISTORY                                                       */
12443 /*                                                                        */
12444 /*    DATE              NAME                      DESCRIPTION             */
12445 /*                                                                        */
12446 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12447 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
12448 /*                                            verified memcpy use cases,  */
12449 /*                                            resulting in version 6.1    */
12450 /*                                                                        */
12451 /**************************************************************************/
_nx_dhcpv6_client_get_record(NX_DHCPV6 * dhcpv6_ptr,NX_DHCPV6_CLIENT_RECORD * client_record_ptr)12452 UINT  _nx_dhcpv6_client_get_record(NX_DHCPV6 *dhcpv6_ptr, NX_DHCPV6_CLIENT_RECORD *client_record_ptr)
12453 {
12454 
12455 
12456     /* Get the DHCP mutex.  */
12457     tx_mutex_get(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex), NX_DHCPV6_MUTEX_WAIT);
12458 
12459     /* Clear memory before filling with data. */
12460     memset(client_record_ptr, 0, sizeof(NX_DHCPV6_CLIENT_RECORD));
12461 
12462     /* The DHCPv6 Client is not Bound to an IP address. Cannot create a record for restoring Client
12463        state if not bound to an IP lease. */
12464     if (dhcpv6_ptr -> nx_dhcpv6_state != NX_DHCPV6_STATE_BOUND_TO_ADDRESS)
12465     {
12466         return NX_DHCPV6_NOT_BOUND;
12467     }
12468 
12469     /* Set the DHCPv6 record.  */
12470     client_record_ptr -> nx_dhcpv6_state = dhcpv6_ptr -> nx_dhcpv6_state;
12471 
12472     /* Set the interface and address index.  */
12473     client_record_ptr -> nx_dhcpv6_client_interface_index = dhcpv6_ptr -> nx_dhcpv6_client_interface_index;
12474     memcpy(client_record_ptr -> nx_dhcpv6_client_address_index, dhcpv6_ptr -> nx_dhcpv6_client_address_index, sizeof(UINT) * NX_DHCPV6_MAX_IA_ADDRESS); /* Use case of memcpy is verified. */
12475 
12476     /* Set the time since client set its IP address.  */
12477     client_record_ptr -> nx_dhcpv6_IP_lifetime_time_accrued = dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_time_accrued;
12478 
12479     /* Set the Client DUID.  */
12480     memcpy(&client_record_ptr -> nx_dhcpv6_client_duid, &dhcpv6_ptr -> nx_dhcpv6_client_duid, sizeof(NX_DHCPV6_DUID)); /* Use case of memcpy is verified. */
12481 
12482     /* Set the Server DUID.  */
12483     memcpy(&client_record_ptr -> nx_dhcpv6_server_duid, &dhcpv6_ptr -> nx_dhcpv6_server_duid, sizeof(NX_DHCPV6_DUID)); /* Use case of memcpy is verified. */
12484 
12485     /* Set the IANA.  */
12486     memcpy(&client_record_ptr -> nx_dhcpv6_iana, &dhcpv6_ptr -> nx_dhcpv6_iana, sizeof(NX_DHCPV6_IA_NA)); /* Use case of memcpy is verified. */
12487 
12488     /* Set the IA Address.  */
12489     memcpy(&client_record_ptr -> nx_dhcpv6_ia, &dhcpv6_ptr -> nx_dhcpv6_ia, sizeof(NX_DHCPV6_IA_ADDRESS) * NX_DHCPV6_MAX_IA_ADDRESS); /* Use case of memcpy is verified. */
12490 
12491     /* Set the Option request.  */
12492     memcpy(&client_record_ptr -> nx_dhcpv6_option_request, &dhcpv6_ptr -> nx_dhcpv6_option_request, sizeof(NX_DHCPV6_OPTIONREQUEST)); /* Use case of memcpy is verified. */
12493 
12494     /* Set the Client FQDN.  */
12495     memcpy(&client_record_ptr -> nx_dhcpv6_client_FQDN, &dhcpv6_ptr -> nx_dhcpv6_client_FQDN, sizeof(NX_DHCPV6_CLIENT_FQDN)); /* Use case of memcpy is verified. */
12496 
12497     /* Set the dns name server address.  */
12498     memcpy(&client_record_ptr -> nx_dhcpv6_DNS_name_server_address, &dhcpv6_ptr -> nx_dhcpv6_DNS_name_server_address, sizeof(NXD_ADDRESS) * NX_DHCPV6_NUM_DNS_SERVERS); /* Use case of memcpy is verified. */
12499 
12500     /* Set the time server address.  */
12501     memcpy(&client_record_ptr -> nx_dhcpv6_time_server_address, &dhcpv6_ptr -> nx_dhcpv6_time_server_address, sizeof(NXD_ADDRESS) * NX_DHCPV6_NUM_TIME_SERVERS); /* Use case of memcpy is verified. */
12502 
12503     /* Set the domain name.  */
12504     memcpy(client_record_ptr -> nx_dhcpv6_domain_name, dhcpv6_ptr -> nx_dhcpv6_domain_name, NX_DHCPV6_DOMAIN_NAME_BUFFER_SIZE); /* Use case of memcpy is verified. */
12505 
12506     /* Set the time zone.  */
12507     memcpy(client_record_ptr -> nx_dhcpv6_time_zone, dhcpv6_ptr -> nx_dhcpv6_time_zone, NX_DHCPV6_TIME_ZONE_BUFFER_SIZE); /* Use case of memcpy is verified. */
12508 
12509     /* Release the DHCPv6 Client mutex.  */
12510     tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
12511 
12512     return NX_SUCCESS;
12513 }
12514 
12515 
12516 /**************************************************************************/
12517 /*                                                                        */
12518 /*  FUNCTION                                               RELEASE        */
12519 /*                                                                        */
12520 /*    _nxe_dhcpv6_client_restore_record                   PORTABLE C      */
12521 /*                                                           6.1          */
12522 /*  AUTHOR                                                                */
12523 /*                                                                        */
12524 /*    Yuxin Zhou, Microsoft Corporation                                   */
12525 /*                                                                        */
12526 /*  DESCRIPTION                                                           */
12527 /*                                                                        */
12528 /*    This function performs error checking on the client restore service.*/
12529 /*                                                                        */
12530 /*  INPUT                                                                 */
12531 /*                                                                        */
12532 /*    dhcpv6_ptr                            Pointer to DHCPv6 instance    */
12533 /*    client_record_ptr                     Pointer to previously saved   */
12534 /*                                             Client record              */
12535 /*    time_elapsed                          time input in timer ticks     */
12536 /*                                                                        */
12537 /*  OUTPUT                                                                */
12538 /*                                                                        */
12539 /*    NX_PTR_ERRPR                          Invalid pointer input         */
12540 /*    status                                NetX completion status        */
12541 /*                                                                        */
12542 /*  CALLS                                                                 */
12543 /*                                                                        */
12544 /*   _nx_dhcp_client_restore_record                                       */
12545 /*                                                                        */
12546 /*  CALLED BY                                                             */
12547 /*                                                                        */
12548 /*    Application code                                                    */
12549 /*                                                                        */
12550 /*  RELEASE HISTORY                                                       */
12551 /*                                                                        */
12552 /*    DATE              NAME                      DESCRIPTION             */
12553 /*                                                                        */
12554 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12555 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12556 /*                                            resulting in version 6.1    */
12557 /*                                                                        */
12558 /**************************************************************************/
_nxe_dhcpv6_client_restore_record(NX_DHCPV6 * dhcpv6_ptr,NX_DHCPV6_CLIENT_RECORD * client_record_ptr,ULONG time_elapsed)12559 UINT  _nxe_dhcpv6_client_restore_record(NX_DHCPV6 *dhcpv6_ptr, NX_DHCPV6_CLIENT_RECORD *client_record_ptr, ULONG time_elapsed)
12560 {
12561 
12562 UINT status;
12563 
12564 
12565     /* Check for invalid pointer input.  */
12566     if ((dhcpv6_ptr == NX_NULL) || (client_record_ptr == NX_NULL))
12567     {
12568         return NX_PTR_ERROR;
12569     }
12570 
12571     /* Call actual DHCPv6 client get record service.  */
12572     status = _nx_dhcpv6_client_restore_record(dhcpv6_ptr, client_record_ptr, time_elapsed);
12573 
12574     return status;
12575 }
12576 
12577 /**************************************************************************/
12578 /*                                                                        */
12579 /*  FUNCTION                                               RELEASE        */
12580 /*                                                                        */
12581 /*    _nx_dhcpv6_client_restore_record                    PORTABLE C      */
12582 /*                                                           6.1          */
12583 /*  AUTHOR                                                                */
12584 /*                                                                        */
12585 /*    Yuxin Zhou, Microsoft Corporation                                   */
12586 /*                                                                        */
12587 /*  DESCRIPTION                                                           */
12588 /*                                                                        */
12589 /*    This function updates the DHCPv6 CLient state with the supplied DHCP*/
12590 /*    Client record pointed to by the client_record_ptr pointer. It then  */
12591 /*    updates the time out parameters of the DHCPv6 Client with the       */
12592 /*    time_elapsed parameter (in timer ticks). It is intended for         */
12593 /*    restoring Client state between reboots and assumes the DHCPv6 Client*/
12594 /*    state was previously obtained and stored in NVRAM before power down.*/
12595 /*                                                                        */
12596 /*    Note: after restore the DHCPv6 Client record, should call           */
12597 /*    nx_dhcpv6_resume to update the DHCPv6 Client state and resume the   */
12598 /*    DHCPv6 processing thread.                                           */
12599 /*                                                                        */
12600 /*  INPUT                                                                 */
12601 /*                                                                        */
12602 /*    dhcpv6_ptr                            Pointer to DHCPv6 instance    */
12603 /*    client_record_ptr                     Pointer to previously saved   */
12604 /*                                             Client record              */
12605 /*    time_elapsed                          time input in timer ticks     */
12606 /*                                                                        */
12607 /*  OUTPUT                                                                */
12608 /*                                                                        */
12609 /*    NX_SUCCESS                            Successful completion status  */
12610 /*    status                                NetX completion status        */
12611 /*                                                                        */
12612 /*  CALLS                                                                 */
12613 /*                                                                        */
12614 /*    nx_ip_interface_address_set                                         */
12615 /*    nx_ip_address_set                                                   */
12616 /*    _nx_dhcp_client_update_time_remaining                               */
12617 /*    memcpy                                                              */
12618 /*                                                                        */
12619 /*  CALLED BY                                                             */
12620 /*                                                                        */
12621 /*    Application code                                                    */
12622 /*                                                                        */
12623 /*  RELEASE HISTORY                                                       */
12624 /*                                                                        */
12625 /*    DATE              NAME                      DESCRIPTION             */
12626 /*                                                                        */
12627 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12628 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
12629 /*                                            verified memcpy use cases,  */
12630 /*                                            resulting in version 6.1    */
12631 /*                                                                        */
12632 /**************************************************************************/
_nx_dhcpv6_client_restore_record(NX_DHCPV6 * dhcpv6_ptr,NX_DHCPV6_CLIENT_RECORD * client_record_ptr,ULONG time_elapsed)12633 UINT  _nx_dhcpv6_client_restore_record(NX_DHCPV6 *dhcpv6_ptr, NX_DHCPV6_CLIENT_RECORD *client_record_ptr, ULONG time_elapsed)
12634 {
12635 
12636 UINT    ia_index;
12637 
12638 
12639     /* Get the DHCP mutex.  */
12640     tx_mutex_get(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex), NX_DHCPV6_MUTEX_WAIT);
12641 
12642     /* Set the DHCPv6 record.  */
12643     dhcpv6_ptr -> nx_dhcpv6_state = client_record_ptr -> nx_dhcpv6_state;
12644 
12645     /* Set the interface and address index.  */
12646     dhcpv6_ptr -> nx_dhcpv6_client_interface_index = client_record_ptr -> nx_dhcpv6_client_interface_index;
12647     memcpy(dhcpv6_ptr -> nx_dhcpv6_client_address_index, client_record_ptr -> nx_dhcpv6_client_address_index, sizeof(UINT) * NX_DHCPV6_MAX_IA_ADDRESS); /* Use case of memcpy is verified. */
12648 
12649     /* Set the Client DUID.  */
12650     memcpy(&dhcpv6_ptr -> nx_dhcpv6_client_duid, &client_record_ptr -> nx_dhcpv6_client_duid, sizeof(NX_DHCPV6_DUID)); /* Use case of memcpy is verified. */
12651 
12652     /* Set the Server DUID.  */
12653     memcpy(&dhcpv6_ptr -> nx_dhcpv6_server_duid, &client_record_ptr -> nx_dhcpv6_server_duid, sizeof(NX_DHCPV6_DUID)); /* Use case of memcpy is verified. */
12654 
12655     /* Set the IANA.  */
12656     memcpy(&dhcpv6_ptr -> nx_dhcpv6_iana, &client_record_ptr -> nx_dhcpv6_iana, sizeof(NX_DHCPV6_IA_NA)); /* Use case of memcpy is verified. */
12657 
12658     /* Set the IA Address.  */
12659     memcpy(&dhcpv6_ptr -> nx_dhcpv6_ia, &client_record_ptr -> nx_dhcpv6_ia, sizeof(NX_DHCPV6_IA_ADDRESS) * NX_DHCPV6_MAX_IA_ADDRESS); /* Use case of memcpy is verified. */
12660 
12661     /* Set the Option request.  */
12662     memcpy(&dhcpv6_ptr -> nx_dhcpv6_option_request, &client_record_ptr -> nx_dhcpv6_option_request, sizeof(NX_DHCPV6_OPTIONREQUEST)); /* Use case of memcpy is verified. */
12663 
12664     /* Set the Client FQDN.  */
12665     memcpy(&dhcpv6_ptr -> nx_dhcpv6_client_FQDN, &client_record_ptr -> nx_dhcpv6_client_FQDN, sizeof(NX_DHCPV6_CLIENT_FQDN)); /* Use case of memcpy is verified. */
12666 
12667     /* Set the dns name server address.  */
12668     memcpy(&dhcpv6_ptr -> nx_dhcpv6_DNS_name_server_address, &client_record_ptr -> nx_dhcpv6_DNS_name_server_address, sizeof(NXD_ADDRESS) * NX_DHCPV6_NUM_DNS_SERVERS); /* Use case of memcpy is verified. */
12669 
12670     /* Set the time server address.  */
12671     memcpy(&dhcpv6_ptr -> nx_dhcpv6_time_server_address, &client_record_ptr -> nx_dhcpv6_time_server_address, sizeof(NXD_ADDRESS) * NX_DHCPV6_NUM_TIME_SERVERS); /* Use case of memcpy is verified. */
12672 
12673     /* Set the domain name.  */
12674     memcpy(dhcpv6_ptr -> nx_dhcpv6_domain_name, client_record_ptr -> nx_dhcpv6_domain_name, NX_DHCPV6_DOMAIN_NAME_BUFFER_SIZE); /* Use case of memcpy is verified. */
12675 
12676     /* Set the time zone.  */
12677     memcpy(dhcpv6_ptr -> nx_dhcpv6_time_zone, client_record_ptr -> nx_dhcpv6_time_zone, NX_DHCPV6_TIME_ZONE_BUFFER_SIZE); /* Use case of memcpy is verified. */
12678 
12679     /* Set the time since client set its IP address.  */
12680     dhcpv6_ptr -> nx_dhcpv6_IP_lifetime_time_accrued = (client_record_ptr -> nx_dhcpv6_IP_lifetime_time_accrued + time_elapsed);
12681 
12682     /* Set the DHCPv6 Client IPv6 addresses.  */
12683     for(ia_index = 0; ia_index < NX_DHCPV6_MAX_IA_ADDRESS; ia_index++)
12684     {
12685 
12686         if(dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_address_status == NX_DHCPV6_IA_ADDRESS_STATE_VALID)
12687         {
12688 
12689             /* Add the address to the IP instance address table. */
12690             nxd_ipv6_address_set(dhcpv6_ptr -> nx_dhcpv6_ip_ptr, dhcpv6_ptr -> nx_dhcpv6_client_interface_index,
12691                                  &dhcpv6_ptr -> nx_dhcpv6_ia[ia_index].nx_global_address, 64, &dhcpv6_ptr -> nx_dhcpv6_client_address_index[ia_index]);
12692         }
12693     }
12694 
12695     /* Release the DHCPv6 Client mutex.  */
12696     tx_mutex_put(&(dhcpv6_ptr -> nx_dhcpv6_client_mutex));
12697 
12698     return NX_SUCCESS;
12699 }
12700 #endif /* NX_DHCPV6_CLIENT_RESTORE_STATE */
12701 #endif /* FEATURE_NX_IPV6 */
12702