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 /**   Domain Name System (DNS)                                            */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define NX_DNS_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    "nx_api.h"
35 #include    "nx_ip.h"
36 #include    "nxd_dns.h"
37 #include    "stdio.h"
38 #include    "string.h"
39 #include    "nx_system.h"
40 
41 /* Define the resource record section.  */
42 #define NX_DNS_RR_ANSWER_SECTION        1
43 #define NX_DNS_RR_AUTHORITY_SECTION     2
44 #define NX_DNS_RR_ADDITIONAL_SECTION    3
45 
46 /* Internal DNS functions. */
47 static UINT        _nx_dns_header_create(UCHAR *buffer_ptr, USHORT id, USHORT flags);
48 static UINT        _nx_dns_new_packet_create(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *name, USHORT type);
49 static UINT        _nx_dns_name_size_calculate(UCHAR *name, NX_PACKET *packet_ptr);
50 static UINT        _nx_dns_name_string_encode(UCHAR *ptr, UCHAR *name);
51 static UINT        _nx_dns_name_string_unencode(NX_PACKET *packet_ptr, UCHAR *data, UCHAR *buffer, UINT buffer_size);
52 static USHORT      _nx_dns_network_to_short_convert(UCHAR *ptr);
53 static ULONG       _nx_dns_network_to_long_convert(UCHAR *ptr);
54 static UINT        _nx_dns_question_add(NX_PACKET *packet_ptr, UCHAR *name, USHORT type);
55 static UCHAR *     _nx_dns_resource_data_address_get(UCHAR *resource, NX_PACKET *packet_ptr);
56 static UINT        _nx_dns_resource_data_length_get(UCHAR *resource, NX_PACKET *packet_ptr, UINT *length);
57 static UINT        _nx_dns_resource_type_get(UCHAR *resource, NX_PACKET *packet_ptr, UINT *resource_type);
58 static UINT        _nx_dns_resource_size_get(UCHAR *resource, NX_PACKET *packet_ptr, UINT *resource_size);
59 static VOID        _nx_dns_short_to_network_convert(UCHAR *ptr, USHORT value);
60 #ifndef NX_DISABLE_IPV4
61 static UINT        _nx_dns_number_to_ascii_convert(UINT number, CHAR *buffstring);
62 #endif /* NX_DISABLE_IPV4 */
63 static UINT        _nx_dns_host_resource_data_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, UCHAR *record_buffer, UINT buffer_size,
64                                                           UINT *record_count, UINT lookup_type, ULONG wait_option);
65 static UINT        _nx_dns_response_receive(NX_DNS *dns_ptr, NX_PACKET **packet_ptr, ULONG wait_option);
66 static UINT        _nx_dns_response_process(NX_DNS *dns_ptr, UCHAR *host_name, NX_PACKET *packet_ptr, UCHAR *record_buffer, UINT buffer_size, UINT *record_count);
67 static UINT        _nx_dns_process_a_type(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *data_ptr, UCHAR **buffer_prepend_ptr, UCHAR **buffer_append_ptr, UINT *record_count, UINT rr_location);
68 static UINT        _nx_dns_process_aaaa_type(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *data_ptr, UCHAR **buffer_prepend_ptr, UCHAR **buffer_append_ptr, UINT *record_count, UINT rr_location);
69 
70 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
71 static UINT        _nx_dns_resource_name_real_size_calculate(UCHAR *data, UINT start, UINT data_length);
72 static UINT        _nx_dns_process_cname_type(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *data_ptr, UCHAR *record_buffer, UINT buffer_size, UINT *record_count);
73 static UINT        _nx_dns_process_txt_type(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *data_ptr, UCHAR *record_buffer, UINT buffer_size, UINT *record_count);
74 static UINT        _nx_dns_process_ns_type(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *data_ptr, UCHAR **buffer_prepend_ptr, UCHAR **buffer_append_ptr, UINT *record_count);
75 static UINT        _nx_dns_process_mx_type(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *data_ptr, UCHAR **buffer_prepend_ptr, UCHAR **buffer_append_ptr, UINT *record_count);
76 static UINT        _nx_dns_process_srv_type(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *data_ptr, UCHAR **buffer_prepend_ptr, UCHAR **buffer_append_ptr, UINT *record_count);
77 static UINT        _nx_dns_process_soa_type(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *data_ptr, UCHAR *record_buffer, UINT buffer_size, UINT *record_count);
78 #endif
79 
80 #ifdef NX_DNS_CACHE_ENABLE
81 static UINT        _nx_dns_name_match(UCHAR *src, UCHAR *dst, UINT length);
82 static UINT        _nx_dns_cache_add_rr(NX_DNS *dns_ptr, VOID *cache_ptr, UINT cache_size, NX_DNS_RR *record_ptr, NX_DNS_RR **insert_ptr);
83 static UINT        _nx_dns_cache_find_answer(NX_DNS *dns_ptr, VOID *cache_ptr, UCHAR *query_name, USHORT query_type, UCHAR *buffer, UINT buffer_size, UINT *record_count);
84 static UINT        _nx_dns_cache_delete_rr(NX_DNS *dns_ptr, VOID *cache_ptr, UINT cache_size, NX_DNS_RR *record_ptr);
85 static UINT        _nx_dns_cache_delete_rr_string(NX_DNS *dns_ptr, VOID *cache_ptr, UINT cache_size, NX_DNS_RR *record_ptr);
86 static UINT        _nx_dns_cache_add_string(NX_DNS *dns_ptr, VOID *cache_ptr, UINT cache_size, VOID *string_ptr, UINT string_size, VOID **insert_ptr);
87 static UINT        _nx_dns_cache_delete_string(NX_DNS *dns_ptr, VOID *cache_ptr, UINT cache_size, VOID *string_ptr, UINT string_len);
88 static UINT        _nx_dns_resource_time_to_live_get(UCHAR *resource, NX_PACKET *packet_ptr, ULONG *rr_ttl);
89 #endif /* NX_DNS_CACHE_ENABLE  */
90 
91 #ifdef FEATURE_NX_IPV6
92 static VOID        _nxd_dns_build_an_ipv6_question_string(NXD_ADDRESS *ip_address, UCHAR *buffer, UINT len);
93 #endif
94 static UINT        _nx_dns_server_add_internal(NX_DNS *dns_ptr, NXD_ADDRESS *server_address);
95 static UINT        _nx_dns_server_remove_internal(NX_DNS *dns_ptr, NXD_ADDRESS *server_address);
96 static UINT        _nx_dns_server_get_internal(NX_DNS *dns_ptr, UINT index, NXD_ADDRESS *server_address);
97 static UINT        _nx_dns_host_by_address_get_internal(NX_DNS *dns_ptr, NXD_ADDRESS *host_address_ptr, UCHAR *host_name_ptr,
98                                                         UINT host_name_buffer_size, ULONG wait_option);
99 static UINT        _nx_dns_send_query_by_address(NX_DNS *dns_ptr, NXD_ADDRESS *dns_server, UCHAR *ip_question, UCHAR *host_name_ptr, UINT host_name_buffer_size, ULONG wait_option);
100 static UINT        _nx_dns_send_query_get_rdata_by_name(NX_DNS *dns_ptr, NXD_ADDRESS *server_address, UCHAR *host_name, UCHAR *record_buffer,
101                                                          UINT buffer_size, UINT *record_count, UINT dns_record_type, ULONG wait_option);
102 
103 /* static VOID        _nx_dns_long_to_network_convert(UCHAR *ptr, ULONG value); */
104 /* static UINT        _nx_dns_resource_class_get(UCHAR *resource); */
105 /* static UINT        _nx_dns_resource_time_to_live_get(UCHAR *resource, NX_PACKET *packet_ptr, ULONG *rr_ttl); */
106 /* static UINT        _nx_dns_resource_name_get(UCHAR *buffer, UINT start, UCHAR *destination, UINT size); */
107 
108 
109 /* Bring in externs for caller checking code.  */
110 
111 NX_CALLER_CHECKING_EXTERNS
112 
113 UCHAR lookup_end[] =  "IN-ADDR.ARPA";
114 
115 #ifdef NX_DNS_CACHE_ENABLE
116 static NX_DNS_RR   temp_rr;
117 #endif /* NX_DNS_CACHE_ENABLE  */
118 
119 static UCHAR       temp_string_buffer[NX_DNS_NAME_MAX + 1];
120 
121 /* Record the temp host name,*/
122 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
123 #define TEMP_SRV_BUFFER_SIZE    (NX_DNS_NAME_MAX + 1 + sizeof (NX_DNS_SRV_ENTRY))
124 #endif
125 
126 NX_DNS *_nx_dns_instance_ptr;
127 
128 /**************************************************************************/
129 /*                                                                        */
130 /*  FUNCTION                                               RELEASE        */
131 /*                                                                        */
132 /*    _nxe_dns_create                                     PORTABLE C      */
133 /*                                                           6.1          */
134 /*  AUTHOR                                                                */
135 /*                                                                        */
136 /*    Yuxin Zhou, Microsoft Corporation                                   */
137 /*                                                                        */
138 /*  DESCRIPTION                                                           */
139 /*                                                                        */
140 /*    This function checks for errors in the DNS create function call.    */
141 /*                                                                        */
142 /*  INPUT                                                                 */
143 /*                                                                        */
144 /*    dns_ptr                               Pointer to DNS instance       */
145 /*    ip_ptr                                Pointer to IP instance        */
146 /*    domain_name                           DNS name                      */
147 /*                                                                        */
148 /*  OUTPUT                                                                */
149 /*                                                                        */
150 /*    status                                Completion status             */
151 /*                                                                        */
152 /*  CALLS                                                                 */
153 /*                                                                        */
154 /*    _nx_dns_create                        Actual DNS create function    */
155 /*                                                                        */
156 /*  CALLED BY                                                             */
157 /*                                                                        */
158 /*    Application Code                                                    */
159 /*                                                                        */
160 /*  RELEASE HISTORY                                                       */
161 /*                                                                        */
162 /*    DATE              NAME                      DESCRIPTION             */
163 /*                                                                        */
164 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
165 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
166 /*                                            resulting in version 6.1    */
167 /*                                                                        */
168 /**************************************************************************/
_nxe_dns_create(NX_DNS * dns_ptr,NX_IP * ip_ptr,UCHAR * domain_name)169 UINT  _nxe_dns_create(NX_DNS *dns_ptr, NX_IP *ip_ptr, UCHAR *domain_name)
170 {
171 
172 UINT    status;
173 
174     /* Check for invalid input pointers.  */
175     if ((ip_ptr == NX_NULL) || (ip_ptr -> nx_ip_id != NX_IP_ID) ||
176         (dns_ptr == NX_NULL) || (dns_ptr -> nx_dns_id == NX_DNS_ID))
177         return(NX_PTR_ERROR);
178 
179     /* Check for appropriate caller.  */
180     NX_THREADS_ONLY_CALLER_CHECKING
181 
182     /* Call actual DNS create service.  */
183     status =  _nx_dns_create(dns_ptr, ip_ptr, domain_name);
184 
185     /* Return status.  */
186     return(status);
187 }
188 
189 
190 /**************************************************************************/
191 /*                                                                        */
192 /*  FUNCTION                                               RELEASE        */
193 /*                                                                        */
194 /*    _nx_dns_create                                      PORTABLE C      */
195 /*                                                           6.1.12       */
196 /*  AUTHOR                                                                */
197 /*                                                                        */
198 /*    Yuxin Zhou, Microsoft Corporation                                   */
199 /*                                                                        */
200 /*  DESCRIPTION                                                           */
201 /*                                                                        */
202 /*    This function creates a DNS instance for the specified IP. This     */
203 /*    involves creating a UDP DNS socket, and a mutex for mutual exclusion*/
204 /*    of DNS requests, and binding the DNS socket to the appropriate port.*/
205 /*                                                                        */
206 /*  INPUT                                                                 */
207 /*                                                                        */
208 /*    dns_ptr                               Pointer to DNS instance       */
209 /*    ip_ptr                                Pointer to IP instance        */
210 /*    domain_name                           DNS name                      */
211 /*                                                                        */
212 /*  OUTPUT                                                                */
213 /*                                                                        */
214 /*    status                                Completion status             */
215 /*                                                                        */
216 /*  CALLS                                                                 */
217 /*                                                                        */
218 /*    nx_udp_socket_create                  Create DNS UDP socket         */
219 /*    nx_udp_socket_delete                  Delete DNS UDP socket         */
220 /*    tx_mutex_create                       Create a ThreadX mutex        */
221 /*                                                                        */
222 /*  CALLED BY                                                             */
223 /*                                                                        */
224 /*    Application Code                                                    */
225 /*                                                                        */
226 /*  RELEASE HISTORY                                                       */
227 /*                                                                        */
228 /*    DATE              NAME                      DESCRIPTION             */
229 /*                                                                        */
230 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
231 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
232 /*                                            resulting in version 6.1    */
233 /*  02-02-2021     Yuxin Zhou               Modified comment(s), and      */
234 /*                                            randomized the source port, */
235 /*                                            resulting in version 6.1.4  */
236 /*  07-29-2022     Jidesh Veeramachaneni    Modified comment(s), and      */
237 /*                                            improved internal logic,    */
238 /*                                            resulting in version 6.1.12 */
239 /*                                                                        */
240 /**************************************************************************/
_nx_dns_create(NX_DNS * dns_ptr,NX_IP * ip_ptr,UCHAR * domain_name)241 UINT _nx_dns_create(NX_DNS *dns_ptr, NX_IP *ip_ptr, UCHAR *domain_name)
242 {
243 
244 UINT            status;
245 
246     /* If the host does intend to supply their own packet pool, create one here. */
247 #ifndef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL
248 
249     /* Create the DNS packet pool.  */
250     status =  nx_packet_pool_create(&(dns_ptr -> nx_dns_pool), "DNS Pool", NX_DNS_PACKET_PAYLOAD,
251                                     dns_ptr -> nx_dns_pool_area,  NX_DNS_PACKET_POOL_SIZE);
252 
253     /* Check status of packet pool create.  */
254     if (status != NX_SUCCESS)
255     {
256 
257         /* Return an error.  */
258         return(NX_DNS_ERROR);
259     }
260 
261     /* Set an internal packet pool pointer to the newly created packet pool. */
262     dns_ptr -> nx_dns_packet_pool_ptr = &dns_ptr -> nx_dns_pool;
263 
264 #endif
265 
266     /* Create the DNS UDP socket.  */
267     nx_udp_socket_create(ip_ptr, &(dns_ptr -> nx_dns_socket), "DNS Socket",
268                          NX_DNS_TYPE_OF_SERVICE, NX_DNS_FRAGMENT_OPTION, NX_DNS_TIME_TO_LIVE, NX_DNS_QUEUE_DEPTH);
269 
270     /* Create a DNS mutex for multi-thread access protection.  */
271     status =  tx_mutex_create(&dns_ptr -> nx_dns_mutex, "DNS Mutex", TX_NO_INHERIT);
272 
273     /* Check status of mutex create.  */
274     if (status != TX_SUCCESS)
275     {
276 
277 #ifndef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL
278 
279        /* Delete the packet pool. */
280         nx_packet_pool_delete(dns_ptr -> nx_dns_packet_pool_ptr);
281 #endif
282 
283         /* Delete the socket.  */
284         nx_udp_socket_delete(&(dns_ptr -> nx_dns_socket));
285 
286         /* Return the threadx error.  */
287         return(status);
288     }
289 
290     /* Save the IP structure pointer.  */
291     dns_ptr -> nx_dns_ip_ptr =   ip_ptr;
292     dns_ptr -> nx_dns_domain = domain_name;
293 
294     /* Initialize the rest of the DNS structure.  */
295     dns_ptr -> nx_dns_id =      NX_DNS_ID;
296 
297     /* Clear memory except for client DNS server array. */
298     memset(&dns_ptr -> nx_dns_server_ip_array[0], 0, NX_DNS_MAX_SERVERS * sizeof(NXD_ADDRESS));
299 
300     /* Setup the maximum retry.  */
301     dns_ptr -> nx_dns_retries =  NX_DNS_MAX_RETRIES;
302 
303     /* Is the client's network gateway also the primary DNS server? */
304 #if defined(NX_DNS_IP_GATEWAY_AND_DNS_SERVER) && !defined(NX_DISABLE_IPV4)
305 
306     /* Verify we have a non zero gateway IP address. */
307     if(ip_ptr -> nx_ip_gateway_address != 0)
308     {
309 
310         /* Yes; Assign the IP's gateway address to the first entry in the Client DNS server list. */
311         dns_ptr -> nx_dns_server_ip_array[0].nxd_ip_version = NX_IP_VERSION_V4;
312         dns_ptr -> nx_dns_server_ip_array[0].nxd_ip_address.v4 = ip_ptr -> nx_ip_gateway_address;
313     }
314 
315 #endif /* defined(NX_DNS_IP_GATEWAY_AND_DNS_SERVER) && !defined(NX_DISABLE_IPV4) */
316 
317     _nx_dns_instance_ptr = dns_ptr;
318 
319     /* Return successful completion.  */
320     return(NX_SUCCESS);
321 }
322 
323 
324 /**************************************************************************/
325 /*                                                                        */
326 /*  FUNCTION                                               RELEASE        */
327 /*                                                                        */
328 /*    _nxe_dns_packet_pool_set                            PORTABLE C      */
329 /*                                                           6.1          */
330 /*  AUTHOR                                                                */
331 /*                                                                        */
332 /*    Yuxin Zhou, Microsoft Corporation                                   */
333 /*                                                                        */
334 /*  DESCRIPTION                                                           */
335 /*                                                                        */
336 /*    This function performs error checking for the set the DNS Client    */
337 /*    packet pool service.                                                */
338 /*                                                                        */
339 /*  INPUT                                                                 */
340 /*                                                                        */
341 /*    dns_ptr                               Pointer to DNS instance       */
342 /*    packet_pool_ptr                       Pointer to packet pool        */
343 /*                                                                        */
344 /*  OUTPUT                                                                */
345 /*                                                                        */
346 /*    status                                Actual completion status      */
347 /*    NX_PTR_ERROR                          Invalid pointer input         */
348 /*    NX_NOT_ENABLED                        DNS client not enabled for    */
349 /*                                             user create packet pool    */
350 /*                                                                        */
351 /*  CALLS                                                                 */
352 /*                                                                        */
353 /*    _nx_dns_packet_pool_set               Actual set packet pool service*/
354 /*                                                                        */
355 /*  CALLED BY                                                             */
356 /*                                                                        */
357 /*    Application Code                                                    */
358 /*                                                                        */
359 /*  RELEASE HISTORY                                                       */
360 /*                                                                        */
361 /*    DATE              NAME                      DESCRIPTION             */
362 /*                                                                        */
363 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
364 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
365 /*                                            resulting in version 6.1    */
366 /*                                                                        */
367 /**************************************************************************/
_nxe_dns_packet_pool_set(NX_DNS * dns_ptr,NX_PACKET_POOL * packet_pool_ptr)368 UINT  _nxe_dns_packet_pool_set(NX_DNS *dns_ptr, NX_PACKET_POOL *packet_pool_ptr)
369 {
370 
371 #ifndef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL
372     NX_PARAMETER_NOT_USED(dns_ptr);
373     NX_PARAMETER_NOT_USED(packet_pool_ptr);
374 
375     /* Client not configured for the user creating the packet pool. Return an error status. */
376     return NX_NOT_ENABLED;
377 #else
378 
379 UINT  status;
380 
381 
382     /* Check for invalid pointer input. */
383     if ((dns_ptr == NX_NULL) || (packet_pool_ptr == NX_NULL))
384     {
385 
386         return NX_PTR_ERROR;
387     }
388 
389     status = _nx_dns_packet_pool_set(dns_ptr, packet_pool_ptr);
390 
391     return status;
392 #endif
393 }
394 
395 
396 /**************************************************************************/
397 /*                                                                        */
398 /*  FUNCTION                                               RELEASE        */
399 /*                                                                        */
400 /*    _nx_dns_packet_pool_set                             PORTABLE C      */
401 /*                                                           6.1          */
402 /*  AUTHOR                                                                */
403 /*                                                                        */
404 /*    Yuxin Zhou, Microsoft Corporation                                   */
405 /*                                                                        */
406 /*  DESCRIPTION                                                           */
407 /*                                                                        */
408 /*    This function sets the DNS Client packet pool by passing in a       */
409 /*    packet pool pointer to packet pool already create.  The             */
410 /*    NX_DNS_CLIENT_USER_CREATE_PACKET_POOL must be set. For guidelines on*/
411 /*    packet payload and packet pool size, see the                        */
412 /*    nx_packet_pool_create call in nx_dns_create.                        */
413 /*                                                                        */
414 /*    Note that the DNS Client nx_dns_delete service will delete this     */
415 /*    packet pool when the DNS Client is deleted.                         */
416 /*                                                                        */
417 /*  INPUT                                                                 */
418 /*                                                                        */
419 /*    dns_ptr                               Pointer to DNS instance       */
420 /*    packet_pool_ptr                       Pointer to packet pool        */
421 /*                                                                        */
422 /*  OUTPUT                                                                */
423 /*                                                                        */
424 /*    NX_SUCCESS                            Successful completion status  */
425 /*    NX_NOT_ENABLED                        Setting DNS Client packet     */
426 /*                                             pool not enabled           */
427 /*  CALLS                                                                 */
428 /*                                                                        */
429 /*    None                                                                */
430 /*                                                                        */
431 /*  CALLED BY                                                             */
432 /*                                                                        */
433 /*    Application Code                                                    */
434 /*                                                                        */
435 /*  RELEASE HISTORY                                                       */
436 /*                                                                        */
437 /*    DATE              NAME                      DESCRIPTION             */
438 /*                                                                        */
439 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
440 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
441 /*                                            resulting in version 6.1    */
442 /*                                                                        */
443 /**************************************************************************/
_nx_dns_packet_pool_set(NX_DNS * dns_ptr,NX_PACKET_POOL * packet_pool_ptr)444 UINT  _nx_dns_packet_pool_set(NX_DNS *dns_ptr, NX_PACKET_POOL *packet_pool_ptr)
445 {
446 
447 
448 #ifndef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL
449     NX_PARAMETER_NOT_USED(dns_ptr);
450     NX_PARAMETER_NOT_USED(packet_pool_ptr);
451 
452     /* No, return the error status. */
453     return NX_NOT_ENABLED;
454 #else
455     /* Check the payload size.  */
456     if (packet_pool_ptr -> nx_packet_pool_payload_size < NX_DNS_PACKET_PAYLOAD)
457         return(NX_DNS_PARAM_ERROR);
458 
459     /* Set the Client packet pool to the supplied packet pool. */
460     dns_ptr -> nx_dns_packet_pool_ptr = packet_pool_ptr;
461 
462     return NX_SUCCESS;
463 #endif
464 }
465 
466 
467 /**************************************************************************/
468 /*                                                                        */
469 /*  FUNCTION                                               RELEASE        */
470 /*                                                                        */
471 /*    _nxe_dns_delete                                     PORTABLE C      */
472 /*                                                           6.1          */
473 /*  AUTHOR                                                                */
474 /*                                                                        */
475 /*    Yuxin Zhou, Microsoft Corporation                                   */
476 /*                                                                        */
477 /*  DESCRIPTION                                                           */
478 /*                                                                        */
479 /*    This function checks for errors in the DNS delete function call.    */
480 /*                                                                        */
481 /*  INPUT                                                                 */
482 /*                                                                        */
483 /*    dns_ptr                               Pointer to DNS instance       */
484 /*                                                                        */
485 /*  OUTPUT                                                                */
486 /*                                                                        */
487 /*    status                                Completion status             */
488 /*                                                                        */
489 /*  CALLS                                                                 */
490 /*                                                                        */
491 /*    _nx_dns_delete                        Actual DNS delete function    */
492 /*                                                                        */
493 /*  CALLED BY                                                             */
494 /*                                                                        */
495 /*    Application Code                                                    */
496 /*                                                                        */
497 /*  RELEASE HISTORY                                                       */
498 /*                                                                        */
499 /*    DATE              NAME                      DESCRIPTION             */
500 /*                                                                        */
501 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
502 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
503 /*                                            resulting in version 6.1    */
504 /*                                                                        */
505 /**************************************************************************/
_nxe_dns_delete(NX_DNS * dns_ptr)506 UINT  _nxe_dns_delete(NX_DNS *dns_ptr)
507 {
508 
509 UINT    status;
510 
511     /* Check for invalid input pointers.  */
512     if ((dns_ptr == NX_NULL) || (dns_ptr -> nx_dns_id != NX_DNS_ID))
513         return(NX_PTR_ERROR);
514 
515     /* Check for appropriate caller.  */
516     NX_THREADS_ONLY_CALLER_CHECKING
517 
518     /* Call actual DNS delete service.  */
519     status =  _nx_dns_delete(dns_ptr);
520 
521     /* Return status.  */
522     return(status);
523 }
524 
525 
526 /**************************************************************************/
527 /*                                                                        */
528 /*  FUNCTION                                               RELEASE        */
529 /*                                                                        */
530 /*    _nx_dns_delete                                      PORTABLE C      */
531 /*                                                           6.1.12       */
532 /*  AUTHOR                                                                */
533 /*                                                                        */
534 /*    Yuxin Zhou, Microsoft Corporation                                   */
535 /*                                                                        */
536 /*  DESCRIPTION                                                           */
537 /*                                                                        */
538 /*    This function deletes a previously created DNS instance for the     */
539 /*    specified IP.                                                       */
540 /*                                                                        */
541 /*  INPUT                                                                 */
542 /*                                                                        */
543 /*    dns_ptr                               Pointer to DNS instance       */
544 /*                                                                        */
545 /*  OUTPUT                                                                */
546 /*                                                                        */
547 /*    status                                Completion status             */
548 /*                                                                        */
549 /*  CALLS                                                                 */
550 /*                                                                        */
551 /*    nx_udp_socket_delete                  Delete DNS UDP socket         */
552 /*    tx_mutex_delete                       Delete DNS mutex              */
553 /*                                                                        */
554 /*  CALLED BY                                                             */
555 /*                                                                        */
556 /*    Application Code                                                    */
557 /*                                                                        */
558 /*  RELEASE HISTORY                                                       */
559 /*                                                                        */
560 /*    DATE              NAME                      DESCRIPTION             */
561 /*                                                                        */
562 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
563 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
564 /*                                            resulting in version 6.1    */
565 /*  02-02-2021     Yuxin Zhou               Modified comment(s), and      */
566 /*                                            randomized the source port, */
567 /*                                            resulting in version 6.1.4  */
568 /*  07-29-2022     Jidesh Veeramachaneni    Modified comment(s),          */
569 /*                                            removed error checking for  */
570 /*                                            nx_packet_pool_delete,      */
571 /*                                            resulting in version 6.1.12 */
572 /*                                                                        */
573 /**************************************************************************/
_nx_dns_delete(NX_DNS * dns_ptr)574 UINT  _nx_dns_delete(NX_DNS *dns_ptr)
575 {
576 
577 UINT    status;
578 
579 
580     /* Delete the DNS UDP socket.  */
581     status =  nx_udp_socket_delete(&dns_ptr -> nx_dns_socket);
582 
583     if (status != NX_SUCCESS)
584     {
585         /* Return the socket delete error. */
586         return status;
587     }
588 
589 #ifndef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL
590 
591     /* Delete the DNS packet pool.  */
592     nx_packet_pool_delete(dns_ptr -> nx_dns_packet_pool_ptr);
593 
594 #endif
595 
596     /* Delete the DNS mutex.  */
597     status =  tx_mutex_delete(&dns_ptr -> nx_dns_mutex);
598 
599     if (status != NX_SUCCESS)
600     {
601         /* Return the mutex delete error. */
602         return status;
603     }
604 
605     /* Cleanup entries in the DNS structure.  */
606     dns_ptr -> nx_dns_id =      0;
607     dns_ptr -> nx_dns_ip_ptr =  NX_NULL;
608 
609     /* Return successful completion status.  */
610     return(NX_SUCCESS);
611 }
612 
613 
614 /**************************************************************************/
615 /*                                                                        */
616 /*  FUNCTION                                               RELEASE        */
617 /*                                                                        */
618 /*    _nxe_dns_server_add                                 PORTABLE C      */
619 /*                                                           6.1          */
620 /*  AUTHOR                                                                */
621 /*                                                                        */
622 /*    Yuxin Zhou, Microsoft Corporation                                   */
623 /*                                                                        */
624 /*  DESCRIPTION                                                           */
625 /*                                                                        */
626 /*    This function checks for errors in the DNS add server function      */
627 /*    call.                                                               */
628 /*                                                                        */
629 /*  INPUT                                                                 */
630 /*                                                                        */
631 /*    dns_ptr                               Pointer to DNS instance       */
632 /*    server_address                        DNS Server IP address         */
633 /*                                                                        */
634 /*  OUTPUT                                                                */
635 /*                                                                        */
636 /*    status                                Completion status             */
637 /*                                                                        */
638 /*  CALLS                                                                 */
639 /*                                                                        */
640 /*    _nx_dns_server_add                    Actual DNS add server function*/
641 /*                                                                        */
642 /*  CALLED BY                                                             */
643 /*                                                                        */
644 /*    Application Code                                                    */
645 /*                                                                        */
646 /*  RELEASE HISTORY                                                       */
647 /*                                                                        */
648 /*    DATE              NAME                      DESCRIPTION             */
649 /*                                                                        */
650 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
651 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
652 /*                                            resulting in version 6.1    */
653 /*                                                                        */
654 /**************************************************************************/
_nxe_dns_server_add(NX_DNS * dns_ptr,ULONG server_address)655 UINT  _nxe_dns_server_add(NX_DNS *dns_ptr, ULONG server_address)
656 {
657 
658 #ifndef NX_DISABLE_IPV4
659 UINT    status;
660 
661     /* Check for invalid input pointers.  */
662     if ((dns_ptr == NX_NULL) || (dns_ptr -> nx_dns_id != NX_DNS_ID))
663     {
664 
665         return(NX_PTR_ERROR);
666     }
667 
668     /* Check for invalid server IP address.  */
669     if (server_address == 0)
670     {
671 
672         return(NX_DNS_BAD_ADDRESS_ERROR);
673     }
674 
675     /* Check for appropriate caller.  */
676     NX_THREADS_ONLY_CALLER_CHECKING
677 
678     /* Call actual DNS server add service.  */
679     status =  _nx_dns_server_add(dns_ptr, server_address);
680 
681     /* Return status.  */
682     return(status);
683 #else
684     NX_PARAMETER_NOT_USED(dns_ptr);
685     NX_PARAMETER_NOT_USED(server_address);
686 
687     return(NX_NOT_SUPPORTED);
688 #endif /* NX_DISABLE_IPV4 */
689 }
690 
691 
692 /**************************************************************************/
693 /*                                                                        */
694 /*  FUNCTION                                               RELEASE        */
695 /*                                                                        */
696 /*    _nx_dns_server_add                                  PORTABLE C      */
697 /*                                                           6.1          */
698 /*  AUTHOR                                                                */
699 /*                                                                        */
700 /*    Yuxin Zhou, Microsoft Corporation                                   */
701 /*                                                                        */
702 /*  DESCRIPTION                                                           */
703 /*                                                                        */
704 /*    This function calls the actual service to add DNS server address.   */
705 /*                                                                        */
706 /*  INPUT                                                                 */
707 /*                                                                        */
708 /*    dns_ptr                               Pointer to DNS instance       */
709 /*    server_address                        DNS Server IP address         */
710 /*                                                                        */
711 /*  OUTPUT                                                                */
712 /*                                                                        */
713 /*    status                                Completion status             */
714 /*                                                                        */
715 /*  CALLS                                                                 */
716 /*                                                                        */
717 /*    _nx_dns_server_add_internal           Actual add DNS server service */
718 /*                                                                        */
719 /*  CALLED BY                                                             */
720 /*                                                                        */
721 /*    Application Code                                                    */
722 /*                                                                        */
723 /*  RELEASE HISTORY                                                       */
724 /*                                                                        */
725 /*    DATE              NAME                      DESCRIPTION             */
726 /*                                                                        */
727 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
728 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
729 /*                                            resulting in version 6.1    */
730 /*                                                                        */
731 /**************************************************************************/
_nx_dns_server_add(NX_DNS * dns_ptr,ULONG server_address)732 UINT  _nx_dns_server_add(NX_DNS *dns_ptr, ULONG server_address)
733 {
734 
735 #ifndef NX_DISABLE_IPV4
736 NXD_ADDRESS dns_server_address;
737 
738 
739     memset(&dns_server_address, 0, sizeof(NXD_ADDRESS));
740 
741     /* Construct an IP address structure, and fill in IPv4 address information. */
742     dns_server_address.nxd_ip_version = NX_IP_VERSION_V4;
743     dns_server_address.nxd_ip_address.v4 = server_address;
744 
745     /* Invoke the real function.  */
746     return (_nx_dns_server_add_internal(dns_ptr, &dns_server_address));
747 #else
748     NX_PARAMETER_NOT_USED(dns_ptr);
749     NX_PARAMETER_NOT_USED(server_address);
750 
751     return(NX_NOT_SUPPORTED);
752 #endif /* NX_DISABLE_IPV4 */
753 }
754 
755 
756 /**************************************************************************/
757 /*                                                                        */
758 /*  FUNCTION                                               RELEASE        */
759 /*                                                                        */
760 /*    _nxde_dns_server_add                                PORTABLE C      */
761 /*                                                           6.1.12       */
762 /*  AUTHOR                                                                */
763 /*                                                                        */
764 /*    Yuxin Zhou, Microsoft Corporation                                   */
765 /*                                                                        */
766 /*  DESCRIPTION                                                           */
767 /*                                                                        */
768 /*    This function checks for errors in the DNS add server function      */
769 /*    call.                                                               */
770 /*                                                                        */
771 /*  INPUT                                                                 */
772 /*                                                                        */
773 /*    dns_ptr                               Pointer to DNS instance       */
774 /*    server_address                        DNS Server IP address         */
775 /*                                                                        */
776 /*  OUTPUT                                                                */
777 /*                                                                        */
778 /*    status                                Completion status             */
779 /*                                                                        */
780 /*  CALLS                                                                 */
781 /*                                                                        */
782 /*    _nxd_dns_server_add                   Actual DNS add server function*/
783 /*                                                                        */
784 /*  CALLED BY                                                             */
785 /*                                                                        */
786 /*    Application Code                                                    */
787 /*                                                                        */
788 /*  RELEASE HISTORY                                                       */
789 /*                                                                        */
790 /*    DATE              NAME                      DESCRIPTION             */
791 /*                                                                        */
792 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
793 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
794 /*                                            resulting in version 6.1    */
795 /*  07-29-2022     Jidesh Veeramachaneni    Modified comment(s) and       */
796 /*                                            simplified some branches,   */
797 /*                                            resulting in version 6.1.12 */
798 /*                                                                        */
799 /**************************************************************************/
_nxde_dns_server_add(NX_DNS * dns_ptr,NXD_ADDRESS * server_address)800 UINT  _nxde_dns_server_add(NX_DNS *dns_ptr, NXD_ADDRESS *server_address)
801 {
802 
803 UINT    status;
804 
805 
806     /* Check for invalid pointer input.  */
807     if ((dns_ptr == NX_NULL)|| (server_address == NX_NULL))
808     {
809 
810         return(NX_PTR_ERROR);
811     }
812 
813     /* Check for invalid non pointer input or invalid server attributes. */
814     if ((dns_ptr -> nx_dns_id != NX_DNS_ID) || (server_address -> nxd_ip_version == NX_NULL))
815     {
816 
817         return NX_DNS_PARAM_ERROR;
818     }
819 
820     /* Check if the server address is unspecified (::). */
821     if (server_address -> nxd_ip_version == NX_IP_VERSION_V6)
822     {
823 
824         /* Check for invalid or null address input*/
825 #ifdef FEATURE_NX_IPV6
826         if(CHECK_UNSPECIFIED_ADDRESS(&server_address -> nxd_ip_address.v6[0]))
827         {
828 
829             /* Null address input. */
830             return NX_DNS_BAD_ADDRESS_ERROR;
831         }
832 #else
833 
834         /* Unsupported address type. */
835         return NX_DNS_INVALID_ADDRESS_TYPE;
836 #endif
837 
838     }
839     else if (server_address -> nxd_ip_version == NX_IP_VERSION_V4)
840     {
841 
842 #ifndef NX_DISABLE_IPV4
843         /* Check for null address. */
844         if(server_address -> nxd_ip_address.v4 == 0)
845         {
846 
847             return NX_DNS_BAD_ADDRESS_ERROR;
848         }
849 #else
850 
851         /* Unsupported address type. */
852         return NX_DNS_INVALID_ADDRESS_TYPE;
853 #endif /* NX_DISABLE_IPV4 */
854     }
855     else
856     {
857         return NX_DNS_INVALID_ADDRESS_TYPE;
858     }
859 
860     /* Check for appropriate caller.  */
861     NX_THREADS_ONLY_CALLER_CHECKING
862 
863     /* Call actual DNS add server service.  */
864     status =  _nxd_dns_server_add(dns_ptr, server_address);
865 
866     /* Return status.  */
867     return(status);
868 }
869 
870 
871 /**************************************************************************/
872 /*                                                                        */
873 /*  FUNCTION                                               RELEASE        */
874 /*                                                                        */
875 /*    _nxd_dns_server_add                                 PORTABLE C      */
876 /*                                                           6.1          */
877 /*  AUTHOR                                                                */
878 /*                                                                        */
879 /*    Yuxin Zhou, Microsoft Corporation                                   */
880 /*                                                                        */
881 /*  DESCRIPTION                                                           */
882 /*                                                                        */
883 /*    This function adds the specified DNS server to this DNS (client)    */
884 /*    instance's list of DNS server. DNS servers can be IPv4 or IPv6      */
885 /*    servers.                                                            */
886 /*                                                                        */
887 /*  INPUT                                                                 */
888 /*                                                                        */
889 /*    dns_ptr                               Pointer to DNS client         */
890 /*    dns_server_address                    DNS Server IP address         */
891 /*                                                                        */
892 /*  OUTPUT                                                                */
893 /*                                                                        */
894 /*    status                                Completion status             */
895 /*                                                                        */
896 /*  CALLS                                                                 */
897 /*                                                                        */
898 /*    _nx_dns_server_add_internal           Actual add DNS server service */
899 /*                                                                        */
900 /*  CALLED BY                                                             */
901 /*                                                                        */
902 /*    Application Code                                                    */
903 /*                                                                        */
904 /*  RELEASE HISTORY                                                       */
905 /*                                                                        */
906 /*    DATE              NAME                      DESCRIPTION             */
907 /*                                                                        */
908 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
909 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
910 /*                                            resulting in version 6.1    */
911 /*                                                                        */
912 /**************************************************************************/
_nxd_dns_server_add(NX_DNS * dns_ptr,NXD_ADDRESS * dns_server_address)913 UINT _nxd_dns_server_add(NX_DNS *dns_ptr, NXD_ADDRESS *dns_server_address)
914 {
915 
916 
917     /* Invoke the real function.  */
918     return (_nx_dns_server_add_internal(dns_ptr, dns_server_address));
919 }
920 
921 
922 /**************************************************************************/
923 /*                                                                        */
924 /*  FUNCTION                                               RELEASE        */
925 /*                                                                        */
926 /*    _nx_dns_server_add_internal                         PORTABLE C      */
927 /*                                                           6.1.12       */
928 /*  AUTHOR                                                                */
929 /*                                                                        */
930 /*    Yuxin Zhou, Microsoft Corporation                                   */
931 /*                                                                        */
932 /*  DESCRIPTION                                                           */
933 /*                                                                        */
934 /*    This function adds the specified DNS server to this DNS (client)    */
935 /*    instance's list of DNS server.                                      */
936 /*                                                                        */
937 /*  INPUT                                                                 */
938 /*                                                                        */
939 /*    dns_ptr                               Pointer to DNS client         */
940 /*    dns_server_address                    DNS Server IP address         */
941 /*                                                                        */
942 /*  OUTPUT                                                                */
943 /*                                                                        */
944 /*    status                                Completion status             */
945 /*                                                                        */
946 /*  CALLS                                                                 */
947 /*                                                                        */
948 /*    tx_mutex_get                          Get DNS protection mutex      */
949 /*    tx_mutex_put                          Release DNS protection mutex  */
950 /*                                                                        */
951 /*  CALLED BY                                                             */
952 /*                                                                        */
953 /*    Application Code                                                    */
954 /*                                                                        */
955 /*  RELEASE HISTORY                                                       */
956 /*                                                                        */
957 /*    DATE              NAME                      DESCRIPTION             */
958 /*                                                                        */
959 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
960 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
961 /*                                            resulting in version 6.1    */
962 /*  07-29-2022     Jidesh Veeramachaneni    Modified comment(s) and       */
963 /*                                            simplified branches,        */
964 /*                                            resulting in version 6.1.12 */
965 /*                                                                        */
966 /**************************************************************************/
_nx_dns_server_add_internal(NX_DNS * dns_ptr,NXD_ADDRESS * server_address)967 UINT _nx_dns_server_add_internal(NX_DNS *dns_ptr, NXD_ADDRESS *server_address)
968 {
969 
970 UINT        status;
971 UINT        i;
972 
973     /* Get the protection mutex to make sure no other thread interferes.  */
974     status =  tx_mutex_get(&(dns_ptr -> nx_dns_mutex), TX_WAIT_FOREVER);
975 
976     /* Determine if there was an error getting the mutex.  */
977     if (status != TX_SUCCESS)
978     {
979 
980         /* Return the completion status error.  */
981         return(status);
982     }
983 
984     /* Check for a duplicate entry. */
985     i =  0;
986 
987     /* Check all entries for a either a matching entry or an empty slot is found.  */
988     while (i < NX_DNS_MAX_SERVERS)
989     {
990 
991         /* The dns server IP is IPv4 address. */
992         if (dns_ptr -> nx_dns_server_ip_array[i].nxd_ip_version == NX_IP_VERSION_V4)
993         {
994 
995 #ifndef NX_DISABLE_IPV4
996             /* Is there a match? */
997             if (server_address -> nxd_ip_version == NX_IP_VERSION_V4)
998             {
999                 if (dns_ptr -> nx_dns_server_ip_array[i].nxd_ip_address.v4 == server_address -> nxd_ip_address.v4)
1000                 {
1001 
1002                     /* Error, release the mutex and return.  */
1003                     tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
1004 
1005                     /* Yes, no need to add to the table, just return the 'error' status. */
1006                     return NX_DNS_DUPLICATE_ENTRY;
1007                 }
1008             }
1009 #else
1010             /* Error, release the mutex and return.  */
1011             tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
1012 
1013             return NX_DNS_PARAM_ERROR;
1014 #endif /* NX_DISABLE_IPV4 */
1015         }
1016 
1017         /* The dns server IP is IPv6 address. */
1018         else if (dns_ptr -> nx_dns_server_ip_array[i].nxd_ip_version == NX_IP_VERSION_V6)
1019         {
1020 
1021 #ifdef FEATURE_NX_IPV6
1022             /* Is there a match? */
1023             if (server_address -> nxd_ip_version == NX_IP_VERSION_V6)
1024             {
1025                 if (CHECK_IPV6_ADDRESSES_SAME(&dns_ptr -> nx_dns_server_ip_array[i].nxd_ip_address.v6[0],
1026                                           &(server_address -> nxd_ip_address.v6[0])))
1027                 {
1028 
1029                     /* Error, release the mutex and return.  */
1030                     tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
1031 
1032                     /* Yes, no need to add to the table, just return the 'error' status. */
1033                     return NX_DNS_DUPLICATE_ENTRY;
1034                 }
1035             }
1036 #else
1037             /* Error, release the mutex and return.  */
1038             tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
1039 
1040             return NX_DNS_PARAM_ERROR;
1041 #endif
1042         }
1043 
1044         else
1045         {
1046             /* Yes, find one empty slot in the DNS server array. */
1047             break;
1048         }
1049 
1050         i++;
1051     }
1052 
1053     if(i == NX_DNS_MAX_SERVERS)
1054     {
1055 
1056         /* Can not find one empty slot. Release the mutex and return.  */
1057         tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
1058 
1059         return(NX_NO_MORE_ENTRIES);
1060     }
1061 
1062     /* Add the new entry here.  */
1063     if (server_address -> nxd_ip_version == NX_IP_VERSION_V6)
1064     {
1065 
1066 #ifdef FEATURE_NX_IPV6
1067         COPY_NXD_ADDRESS(server_address, &dns_ptr -> nx_dns_server_ip_array[i]);
1068 #else
1069         /* Error, release the mutex and return.  */
1070         tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
1071 
1072         return NX_DNS_IPV6_NOT_SUPPORTED;
1073 #endif
1074     }
1075     else
1076     {
1077 
1078 #ifndef NX_DISABLE_IPV4
1079         dns_ptr -> nx_dns_server_ip_array[i].nxd_ip_address.v4 = server_address -> nxd_ip_address.v4;
1080         dns_ptr -> nx_dns_server_ip_array[i].nxd_ip_version = NX_IP_VERSION_V4;
1081 #else
1082         /* Error, release the mutex and return.  */
1083         tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
1084 
1085         return NX_DNS_INVALID_ADDRESS_TYPE;
1086 #endif /* NX_DISABLE_IPV4 */
1087     }
1088 
1089     /* Success, release the mutex and return.  */
1090     tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
1091 
1092     /* Return successful completion.  */
1093     return(NX_SUCCESS);
1094 }
1095 
1096 
1097 
1098 /**************************************************************************/
1099 /*                                                                        */
1100 /*  FUNCTION                                               RELEASE        */
1101 /*                                                                        */
1102 /*    _nxe_dns_server_remove                              PORTABLE C      */
1103 /*                                                           6.1          */
1104 /*  AUTHOR                                                                */
1105 /*                                                                        */
1106 /*    Yuxin Zhou, Microsoft Corporation                                   */
1107 /*                                                                        */
1108 /*  DESCRIPTION                                                           */
1109 /*                                                                        */
1110 /*    This function checks for errors in the DNS remove server function   */
1111 /*    call.                                                               */
1112 /*                                                                        */
1113 /*  INPUT                                                                 */
1114 /*                                                                        */
1115 /*    dns_ptr                               Pointer to DNS instance       */
1116 /*    server_address                        DNS Server IP address         */
1117 /*                                                                        */
1118 /*  OUTPUT                                                                */
1119 /*                                                                        */
1120 /*    status                                Completion status             */
1121 /*                                                                        */
1122 /*  CALLS                                                                 */
1123 /*                                                                        */
1124 /*    _nx_dns_server_remove                 Actual DNS remove server      */
1125 /*                                            function                    */
1126 /*                                                                        */
1127 /*  CALLED BY                                                             */
1128 /*                                                                        */
1129 /*    Application Code                                                    */
1130 /*                                                                        */
1131 /*  RELEASE HISTORY                                                       */
1132 /*                                                                        */
1133 /*    DATE              NAME                      DESCRIPTION             */
1134 /*                                                                        */
1135 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1136 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1137 /*                                            resulting in version 6.1    */
1138 /*                                                                        */
1139 /**************************************************************************/
_nxe_dns_server_remove(NX_DNS * dns_ptr,ULONG server_address)1140 UINT  _nxe_dns_server_remove(NX_DNS *dns_ptr, ULONG server_address)
1141 {
1142 
1143 #ifndef NX_DISABLE_IPV4
1144 UINT    status;
1145 
1146     /* Check for invalid input pointers.  */
1147     if ((dns_ptr == NX_NULL) || (dns_ptr -> nx_dns_id != NX_DNS_ID))
1148     {
1149         return(NX_PTR_ERROR);
1150     }
1151 
1152     /* Check for invalid server IP address.  */
1153     if (server_address == 0)
1154     {
1155         return(NX_DNS_BAD_ADDRESS_ERROR);
1156     }
1157 
1158     /* Check for appropriate caller.  */
1159     NX_THREADS_ONLY_CALLER_CHECKING
1160 
1161     /* Call actual DNS remove server service.  */
1162     status =  _nx_dns_server_remove(dns_ptr, server_address);
1163 
1164     /* Return status.  */
1165     return(status);
1166 #else
1167     NX_PARAMETER_NOT_USED(dns_ptr);
1168     NX_PARAMETER_NOT_USED(server_address);
1169 
1170     return(NX_NOT_SUPPORTED);
1171 #endif /* NX_DISABLE_IPV4 */
1172 }
1173 
1174 
1175 /**************************************************************************/
1176 /*                                                                        */
1177 /*  FUNCTION                                               RELEASE        */
1178 /*                                                                        */
1179 /*    _nx_dns_server_remove                               PORTABLE C      */
1180 /*                                                           6.1          */
1181 /*  AUTHOR                                                                */
1182 /*                                                                        */
1183 /*    Yuxin Zhou, Microsoft Corporation                                   */
1184 /*                                                                        */
1185 /*  DESCRIPTION                                                           */
1186 /*                                                                        */
1187 /*    This function calls actual service to remove specified DNS Server.  */
1188 /*                                                                        */
1189 /*  INPUT                                                                 */
1190 /*                                                                        */
1191 /*    dns_ptr                               Pointer to DNS client         */
1192 /*    server_address                        DNS Server IP address         */
1193 /*                                                                        */
1194 /*  OUTPUT                                                                */
1195 /*                                                                        */
1196 /*    status                                Completion status             */
1197 /*                                                                        */
1198 /*  CALLS                                                                 */
1199 /*                                                                        */
1200 /*    _nx_dns_server_remove_internal        Actual DNS server remove      */
1201 /*                                                                        */
1202 /*  CALLED BY                                                             */
1203 /*                                                                        */
1204 /*    Application Code                                                    */
1205 /*                                                                        */
1206 /*  RELEASE HISTORY                                                       */
1207 /*                                                                        */
1208 /*    DATE              NAME                      DESCRIPTION             */
1209 /*                                                                        */
1210 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1211 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1212 /*                                            resulting in version 6.1    */
1213 /*                                                                        */
1214 /**************************************************************************/
_nx_dns_server_remove(NX_DNS * dns_ptr,ULONG server_address)1215 UINT  _nx_dns_server_remove(NX_DNS *dns_ptr, ULONG server_address)
1216 {
1217 
1218 #ifndef NX_DISABLE_IPV4
1219 NXD_ADDRESS dns_server_address;
1220 
1221     /* Construct an IP address structure, and fill in IPv4 address information. */
1222     dns_server_address.nxd_ip_version = NX_IP_VERSION_V4;
1223     dns_server_address.nxd_ip_address.v4 = server_address;
1224 
1225     /* Invoke the real function.  */
1226     return (_nx_dns_server_remove_internal(dns_ptr, &dns_server_address));
1227 #else
1228     NX_PARAMETER_NOT_USED(dns_ptr);
1229     NX_PARAMETER_NOT_USED(server_address);
1230 
1231     return(NX_NOT_SUPPORTED);
1232 #endif /* NX_DISABLE_IPV4 */
1233 }
1234 
1235 
1236 /**************************************************************************/
1237 /*                                                                        */
1238 /*  FUNCTION                                               RELEASE        */
1239 /*                                                                        */
1240 /*    _nxde_dns_server_remove                             PORTABLE C      */
1241 /*                                                           6.1.12       */
1242 /*  AUTHOR                                                                */
1243 /*                                                                        */
1244 /*    Yuxin Zhou, Microsoft Corporation                                   */
1245 /*                                                                        */
1246 /*  DESCRIPTION                                                           */
1247 /*                                                                        */
1248 /*    This function checks for errors in the DNS remove server function   */
1249 /*    call.                                                               */
1250 /*                                                                        */
1251 /*  INPUT                                                                 */
1252 /*                                                                        */
1253 /*    dns_ptr                              Pointer to DNS client          */
1254 /*    server_address                       DNS Server NXD_ADDRESS instance*/
1255 /*                                                                        */
1256 /*  OUTPUT                                                                */
1257 /*                                                                        */
1258 /*    status                               Completion status              */
1259 /*                                                                        */
1260 /*  CALLS                                                                 */
1261 /*                                                                        */
1262 /*    _nx_dns_server_remove                 Actual DNS remove server      */
1263 /*                                            function                    */
1264 /*                                                                        */
1265 /*  CALLED BY                                                             */
1266 /*                                                                        */
1267 /*    Application Code                                                    */
1268 /*                                                                        */
1269 /*  RELEASE HISTORY                                                       */
1270 /*                                                                        */
1271 /*    DATE              NAME                      DESCRIPTION             */
1272 /*                                                                        */
1273 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1274 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1275 /*                                            resulting in version 6.1    */
1276 /*  07-29-2022     Jidesh Veeramachaneni    Modified comment(s) and       */
1277 /*                                            simplified check for        */
1278 /*                                            invalid address types,      */
1279 /*                                            resulting in version 6.1.12 */
1280 /*                                                                        */
1281 /**************************************************************************/
_nxde_dns_server_remove(NX_DNS * dns_ptr,NXD_ADDRESS * server_address)1282 UINT  _nxde_dns_server_remove(NX_DNS *dns_ptr, NXD_ADDRESS *server_address)
1283 {
1284 
1285 UINT    status;
1286 
1287     /* Check for invalid input pointers.  */
1288     if ((dns_ptr == NX_NULL) || (server_address == NX_NULL) || (dns_ptr -> nx_dns_id != NX_DNS_ID))
1289     {
1290         return(NX_PTR_ERROR);
1291     }
1292 
1293     /* Check if the server address is unspecified (::). */
1294     if (server_address -> nxd_ip_version == NX_IP_VERSION_V6)
1295     {
1296 
1297         /* Check for invalid or null address input*/
1298 #ifdef FEATURE_NX_IPV6
1299         if(CHECK_UNSPECIFIED_ADDRESS(&server_address -> nxd_ip_address.v6[0]))
1300         {
1301 
1302             /* Null address input. */
1303             return NX_DNS_BAD_ADDRESS_ERROR;
1304         }
1305 #else
1306 
1307         /* Unsupported address type. */
1308         return NX_DNS_INVALID_ADDRESS_TYPE;
1309 #endif
1310 
1311     }
1312     else if (server_address -> nxd_ip_version == NX_IP_VERSION_V4)
1313     {
1314 
1315 #ifndef NX_DISABLE_IPV4
1316         /* Check for null address. */
1317         if(server_address -> nxd_ip_address.v4 == 0)
1318         {
1319 
1320             return NX_DNS_BAD_ADDRESS_ERROR;
1321         }
1322 #else
1323 
1324         /* Unsupported address type. */
1325         return NX_DNS_INVALID_ADDRESS_TYPE;
1326 #endif /* NX_DISABLE_IPV4 */
1327     }
1328     else
1329     {
1330         return NX_DNS_INVALID_ADDRESS_TYPE;
1331     }
1332 
1333     /* Check for appropriate caller.  */
1334     NX_THREADS_ONLY_CALLER_CHECKING
1335 
1336     /* Call actual DNS remove server service.  */
1337     status =  _nxd_dns_server_remove(dns_ptr, server_address);
1338 
1339     /* Return status.  */
1340     return(status);
1341 }
1342 
1343 
1344 /**************************************************************************/
1345 /*                                                                        */
1346 /*  FUNCTION                                               RELEASE        */
1347 /*                                                                        */
1348 /*    _nxd_dns_server_remove                              PORTABLE C      */
1349 /*                                                           6.1          */
1350 /*  AUTHOR                                                                */
1351 /*                                                                        */
1352 /*    Yuxin Zhou, Microsoft Corporation                                   */
1353 /*                                                                        */
1354 /*  DESCRIPTION                                                           */
1355 /*                                                                        */
1356 /*    This function removes the specified DNS server to this DNS          */
1357 /*    instance. If the server is not found among the client list of DNS   */
1358 /*    servers, the function returns an error. When a server is removed,   */
1359 /*    the servers above the removed server's index are moved down one to  */
1360 /*    fill the empty slot.                                                */
1361 /*                                                                        */
1362 /*  INPUT                                                                 */
1363 /*                                                                        */
1364 /*    dns_ptr                              Pointer to DNS client          */
1365 /*    server_address                       DNS Server NXD_ADDRESS isntance*/
1366 /*                                                                        */
1367 /*  OUTPUT                                                                */
1368 /*                                                                        */
1369 /*    status                                Completion status             */
1370 /*                                                                        */
1371 /*  CALLS                                                                 */
1372 /*                                                                        */
1373 /*    tx_mutex_get                          Get DNS protection mutex      */
1374 /*    tx_mutex_put                          Release DNS protection mutex  */
1375 /*                                                                        */
1376 /*  CALLED BY                                                             */
1377 /*                                                                        */
1378 /*    Application Code                                                    */
1379 /*                                                                        */
1380 /*  RELEASE HISTORY                                                       */
1381 /*                                                                        */
1382 /*    DATE              NAME                      DESCRIPTION             */
1383 /*                                                                        */
1384 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1385 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1386 /*                                            resulting in version 6.1    */
1387 /*                                                                        */
1388 /**************************************************************************/
_nxd_dns_server_remove(NX_DNS * dns_ptr,NXD_ADDRESS * server_address)1389 UINT  _nxd_dns_server_remove(NX_DNS *dns_ptr, NXD_ADDRESS *server_address)
1390 {
1391 
1392 
1393     /* Invoke the real function.  */
1394     return (_nx_dns_server_remove_internal(dns_ptr, server_address));
1395 }
1396 
1397 
1398 /**************************************************************************/
1399 /*                                                                        */
1400 /*  FUNCTION                                               RELEASE        */
1401 /*                                                                        */
1402 /*    _nx_dns_server_remove_internal                      PORTABLE C      */
1403 /*                                                           6.1.12       */
1404 /*  AUTHOR                                                                */
1405 /*                                                                        */
1406 /*    Yuxin Zhou, Microsoft Corporation                                   */
1407 /*                                                                        */
1408 /*  DESCRIPTION                                                           */
1409 /*                                                                        */
1410 /*    This function removes the specified DNS server to this DNS          */
1411 /*    instance. If the server is not found among the client list of DNS   */
1412 /*    servers, the function returns an error. When a server is removed,   */
1413 /*    the servers above the removed server's index are moved down one to  */
1414 /*    fill the empty slot.                                                */
1415 /*                                                                        */
1416 /*  INPUT                                                                 */
1417 /*                                                                        */
1418 /*    dns_ptr                              Pointer to DNS client          */
1419 /*    server_address                       DNS Server address             */
1420 /*                                                                        */
1421 /*  OUTPUT                                                                */
1422 /*                                                                        */
1423 /*    status                                Completion status             */
1424 /*                                                                        */
1425 /*  CALLS                                                                 */
1426 /*                                                                        */
1427 /*    tx_mutex_get                          Get DNS protection mutex      */
1428 /*    tx_mutex_put                          Release DNS protection mutex  */
1429 /*                                                                        */
1430 /*  CALLED BY                                                             */
1431 /*                                                                        */
1432 /*    Application Code                                                    */
1433 /*                                                                        */
1434 /*  RELEASE HISTORY                                                       */
1435 /*                                                                        */
1436 /*    DATE              NAME                      DESCRIPTION             */
1437 /*                                                                        */
1438 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1439 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1440 /*                                            resulting in version 6.1    */
1441 /*  07-29-2022     Jidesh Veeramachaneni    Modified comment(s) and       */
1442 /*                                            removed null IP checks,     */
1443 /*                                            resulting in version 6.1.12 */
1444 /*                                                                        */
1445 /**************************************************************************/
_nx_dns_server_remove_internal(NX_DNS * dns_ptr,NXD_ADDRESS * server_address)1446 static UINT  _nx_dns_server_remove_internal(NX_DNS *dns_ptr, NXD_ADDRESS *server_address)
1447 {
1448 
1449 NXD_ADDRESS     *DNSserver_array;
1450 UINT            status;
1451 UINT            i;
1452 UINT            found_match;
1453 
1454     /* Initialize local variables. */
1455     found_match = NX_FALSE;
1456     i =  0;
1457 
1458     /* Calculate the start of the DNS server array.  */
1459     DNSserver_array =  dns_ptr -> nx_dns_server_ip_array;
1460 
1461     /* Get the protection mutex to make sure no other thread interferes.  */
1462     status =  tx_mutex_get(&(dns_ptr -> nx_dns_mutex), TX_WAIT_FOREVER);
1463 
1464     /* Determine if there was an error getting the mutex.  */
1465     if (status != TX_SUCCESS)
1466     {
1467 
1468         /* Return an error.  */
1469         return(status);
1470     }
1471 
1472     /* Search through the array to see if we can find the server address.  */
1473     do
1474     {
1475 
1476         /* Is there an IPv6 address in this slot? */
1477         if (DNSserver_array[i].nxd_ip_version == NX_IP_VERSION_V6)
1478 #ifndef FEATURE_NX_IPV6
1479         {
1480 
1481             /* Error, release the mutex and return.  */
1482             tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
1483 
1484              return NX_DNS_IPV6_NOT_SUPPORTED;
1485         }
1486 #else
1487         {
1488             /* Determine if this entry matches the specified DNS server.  */
1489             if (CHECK_IPV6_ADDRESSES_SAME(&DNSserver_array[i].nxd_ip_address.v6[0], &(server_address -> nxd_ip_address.v6[0])))
1490             {
1491 
1492                 found_match = NX_TRUE;
1493                 break;
1494             }
1495         }
1496 #endif
1497         else if (DNSserver_array[i].nxd_ip_version == NX_IP_VERSION_V4)
1498 #ifndef NX_DISABLE_IPV4
1499         {
1500             /* Determine if this entry matches the specified DNS server.  */
1501             if (DNSserver_array[i].nxd_ip_address.v4 == server_address -> nxd_ip_address.v4)
1502             {
1503 
1504                 found_match = NX_TRUE;
1505                 break;
1506             }
1507         }
1508 #else
1509         {
1510 
1511             /* Error, release the mutex and return.  */
1512             tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
1513 
1514              return NX_DNS_IPV6_NOT_SUPPORTED;
1515         }
1516 #endif /* NX_DISABLE_IPV4 */
1517 
1518         /* Check the next slot.  */
1519         i++;
1520 
1521     } while (i < NX_DNS_MAX_SERVERS);
1522 
1523     if (!found_match)
1524     {
1525 
1526         /* Release the mutex and return.  */
1527         tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
1528 
1529         /* Return the error.  */
1530         return(NX_DNS_SERVER_NOT_FOUND);
1531     }
1532 
1533     /* We found the DNS server entry. Remove it from the table.  */
1534     while (i < NX_DNS_MAX_SERVERS - 1)
1535     {
1536 
1537         /* Move them up one slot. */
1538 
1539 #ifdef FEATURE_NX_IPV6
1540          /* This will handle IPv6 and IPv4 addresses if IPv6 enabled in NetX Duo. */
1541          COPY_NXD_ADDRESS(&DNSserver_array[i+1], &DNSserver_array[i]);
1542 #else
1543          /* IPv6 is not enabled, so first verify this is not an IPv6 address. */
1544          if (DNSserver_array[i+1].nxd_ip_version == NX_IP_VERSION_V6)
1545          {
1546 
1547              /* Error, release the mutex and return.  */
1548              tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
1549 
1550              /* This should not happen.  return an error. */
1551              return NX_DNS_IPV6_NOT_SUPPORTED;
1552          }
1553 
1554          /* This is an IPv4 address. Copy to the slot above directly. */
1555          DNSserver_array[i].nxd_ip_version = DNSserver_array[i+1].nxd_ip_version;
1556          DNSserver_array[i].nxd_ip_address.v4 = DNSserver_array[i+1].nxd_ip_address.v4;
1557 #endif
1558 
1559         i++;
1560     }
1561 
1562     /* Terminate the last slot. */
1563     memset(&dns_ptr -> nx_dns_server_ip_array[NX_DNS_MAX_SERVERS - 1], 0, sizeof(NXD_ADDRESS));
1564 
1565     /* Release the mutex and return.  */
1566     tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
1567 
1568     /* Return a successful completion.  */
1569     return(NX_SUCCESS);
1570 }
1571 
1572 
1573 /**************************************************************************/
1574 /*                                                                        */
1575 /*  FUNCTION                                               RELEASE        */
1576 /*                                                                        */
1577 /*    _nxe_dns_server_remove_all                          PORTABLE C      */
1578 /*                                                           6.1          */
1579 /*  AUTHOR                                                                */
1580 /*                                                                        */
1581 /*    Yuxin Zhou, Microsoft Corporation                                   */
1582 /*                                                                        */
1583 /*  DESCRIPTION                                                           */
1584 /*                                                                        */
1585 /*    This function checks for errors in the DNS remove all               */
1586 /*    function call.                                                      */
1587 /*                                                                        */
1588 /*  INPUT                                                                 */
1589 /*                                                                        */
1590 /*    dns_ptr                               Pointer to DNS instance       */
1591 /*                                                                        */
1592 /*  OUTPUT                                                                */
1593 /*                                                                        */
1594 /*    status                                Completion status             */
1595 /*                                                                        */
1596 /*  CALLS                                                                 */
1597 /*                                                                        */
1598 /*    _nx_dns_server_remove_all             Actual DNS remove all function*/
1599 /*                                                                        */
1600 /*  CALLED BY                                                             */
1601 /*                                                                        */
1602 /*    Application Code                                                    */
1603 /*                                                                        */
1604 /*  RELEASE HISTORY                                                       */
1605 /*                                                                        */
1606 /*    DATE              NAME                      DESCRIPTION             */
1607 /*                                                                        */
1608 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1609 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1610 /*                                            resulting in version 6.1    */
1611 /*                                                                        */
1612 /**************************************************************************/
_nxe_dns_server_remove_all(NX_DNS * dns_ptr)1613 UINT  _nxe_dns_server_remove_all(NX_DNS *dns_ptr)
1614 {
1615 
1616 UINT    status;
1617 
1618     /* Check for invalid input pointers.  */
1619     if ((dns_ptr == NX_NULL) || (dns_ptr -> nx_dns_id != NX_DNS_ID))
1620         return(NX_PTR_ERROR);
1621 
1622     /* Check for appropriate caller.  */
1623     NX_THREADS_ONLY_CALLER_CHECKING
1624 
1625     /* Call actual DNS remove server service.  */
1626     status =  _nx_dns_server_remove_all(dns_ptr);
1627 
1628     /* Return status.  */
1629     return(status);
1630 }
1631 
1632 
1633 /**************************************************************************/
1634 /*                                                                        */
1635 /*  FUNCTION                                               RELEASE        */
1636 /*                                                                        */
1637 /*    _nx_dns_server_remove_all                           PORTABLE C      */
1638 /*                                                           6.1          */
1639 /*  AUTHOR                                                                */
1640 /*                                                                        */
1641 /*    Yuxin Zhou, Microsoft Corporation                                   */
1642 /*                                                                        */
1643 /*  DESCRIPTION                                                           */
1644 /*                                                                        */
1645 /*    This function removes all DNS servers.                              */
1646 /*                                                                        */
1647 /*  INPUT                                                                 */
1648 /*                                                                        */
1649 /*    dns_ptr                               Pointer to DNS instance       */
1650 /*                                                                        */
1651 /*  OUTPUT                                                                */
1652 /*                                                                        */
1653 /*    status                                Completion status             */
1654 /*                                                                        */
1655 /*  CALLS                                                                 */
1656 /*                                                                        */
1657 /*    tx_mutex_get                          Get DNS protection mutex      */
1658 /*    tx_mutex_put                          Release DNS protection mutex  */
1659 /*                                                                        */
1660 /*  CALLED BY                                                             */
1661 /*                                                                        */
1662 /*    Application Code                                                    */
1663 /*                                                                        */
1664 /*  RELEASE HISTORY                                                       */
1665 /*                                                                        */
1666 /*    DATE              NAME                      DESCRIPTION             */
1667 /*                                                                        */
1668 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1669 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1670 /*                                            resulting in version 6.1    */
1671 /*                                                                        */
1672 /**************************************************************************/
_nx_dns_server_remove_all(NX_DNS * dns_ptr)1673 UINT  _nx_dns_server_remove_all(NX_DNS *dns_ptr)
1674 {
1675 
1676 UINT    status;
1677 
1678     /* Get the protection mutex to make sure no other thread interferes.  */
1679     status =  tx_mutex_get(&(dns_ptr -> nx_dns_mutex), TX_WAIT_FOREVER);
1680 
1681     /* Determine if there was an error getting the mutex.  */
1682     if (status != TX_SUCCESS)
1683     {
1684         /* Return an error.  */
1685         return(NX_DNS_ERROR);
1686     }
1687 
1688     /* Remove all DNS servers.  */
1689     memset(&dns_ptr -> nx_dns_server_ip_array[0], 0, NX_DNS_MAX_SERVERS * sizeof(NXD_ADDRESS));
1690 
1691     /* Release the mutex and return.  */
1692     tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
1693 
1694     /* Return a successful completion.  */
1695     return(NX_SUCCESS);
1696 }
1697 
1698 
1699 /**************************************************************************/
1700 /*                                                                        */
1701 /*  FUNCTION                                               RELEASE        */
1702 /*                                                                        */
1703 /*    _nxe_dns_get_serverlist_size                        PORTABLE C      */
1704 /*                                                           6.1          */
1705 /*  AUTHOR                                                                */
1706 /*                                                                        */
1707 /*    Yuxin Zhou, Microsoft Corporation                                   */
1708 /*                                                                        */
1709 /*  DESCRIPTION                                                           */
1710 /*                                                                        */
1711 /*    This function checks for errors in the get DNS server list size     */
1712 /*    service.                                                            */
1713 /*                                                                        */
1714 /*  INPUT                                                                 */
1715 /*                                                                        */
1716 /*    dns_ptr                               Pointer to DNS instance       */
1717 /*    size                                  Pointer to server size        */
1718 /*                                                                        */
1719 /*  OUTPUT                                                                */
1720 /*                                                                        */
1721 /*    status                                Completion status             */
1722 /*                                                                        */
1723 /*  CALLS                                                                 */
1724 /*                                                                        */
1725 /*    _nx_dns_get_serverlist_size          Actual get DNS server list size*/
1726 /*                                          service                       */
1727 /*                                                                        */
1728 /*  CALLED BY                                                             */
1729 /*                                                                        */
1730 /*    Application Code                                                    */
1731 /*                                                                        */
1732 /*  RELEASE HISTORY                                                       */
1733 /*                                                                        */
1734 /*    DATE              NAME                      DESCRIPTION             */
1735 /*                                                                        */
1736 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1737 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1738 /*                                            resulting in version 6.1    */
1739 /*                                                                        */
1740 /**************************************************************************/
_nxe_dns_get_serverlist_size(NX_DNS * dns_ptr,UINT * size)1741 UINT  _nxe_dns_get_serverlist_size(NX_DNS *dns_ptr, UINT *size)
1742 {
1743 
1744 UINT    status;
1745 
1746     /* Check for invalid input pointers.  */
1747     if ((dns_ptr == NX_NULL) || (dns_ptr -> nx_dns_id != NX_DNS_ID) || (size == NX_NULL))
1748         return(NX_PTR_ERROR);
1749 
1750     /* Check for appropriate caller.  */
1751     NX_THREADS_ONLY_CALLER_CHECKING
1752 
1753     /* Call actual DNS get server size service.  */
1754     status =  _nx_dns_get_serverlist_size(dns_ptr, size);
1755 
1756     /* Return status.  */
1757     return(status);
1758 }
1759 
1760 
1761 /**************************************************************************/
1762 /*                                                                        */
1763 /*  FUNCTION                                               RELEASE        */
1764 /*                                                                        */
1765 /*    _nx_dns_get_serverlist_size                         PORTABLE C      */
1766 /*                                                           6.1          */
1767 /*  AUTHOR                                                                */
1768 /*                                                                        */
1769 /*    Yuxin Zhou, Microsoft Corporation                                   */
1770 /*                                                                        */
1771 /*  DESCRIPTION                                                           */
1772 /*                                                                        */
1773 /*    This function returns the number of DNS servers in the Client list. */
1774 /*                                                                        */
1775 /*  INPUT                                                                 */
1776 /*                                                                        */
1777 /*    dns_ptr                               Pointer to DNS client         */
1778 /*    size                                  Pointer to server list size   */
1779 /*                                                                        */
1780 /*  OUTPUT                                                                */
1781 /*                                                                        */
1782 /*    status                                Completion status             */
1783 /*                                                                        */
1784 /*  CALLS                                                                 */
1785 /*                                                                        */
1786 /*    None                                                                */
1787 /*                                                                        */
1788 /*  CALLED BY                                                             */
1789 /*                                                                        */
1790 /*    Application Code                                                    */
1791 /*                                                                        */
1792 /*  RELEASE HISTORY                                                       */
1793 /*                                                                        */
1794 /*    DATE              NAME                      DESCRIPTION             */
1795 /*                                                                        */
1796 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1797 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1798 /*                                            resulting in version 6.1    */
1799 /*                                                                        */
1800 /**************************************************************************/
_nx_dns_get_serverlist_size(NX_DNS * dns_ptr,UINT * size)1801 UINT  _nx_dns_get_serverlist_size(NX_DNS *dns_ptr, UINT *size)
1802 {
1803 
1804     /* Initialize the list size to zero. */
1805     *size = 0;
1806 
1807     /* Loop through the list till we hit the first empty slot. */
1808     while (*size < NX_DNS_MAX_SERVERS)
1809     {
1810 
1811         /* Is this a valid IP address entry in this slot? */
1812         if (dns_ptr -> nx_dns_server_ip_array[*size].nxd_ip_version == 0)
1813         {
1814 
1815             /* This is an empty slot, so we're at the end of the list. */
1816             break;
1817         }
1818 
1819         (*size)++;
1820     }
1821 
1822     return NX_SUCCESS;
1823 }
1824 
1825 
1826 /**************************************************************************/
1827 /*                                                                        */
1828 /*  FUNCTION                                               RELEASE        */
1829 /*                                                                        */
1830 /*    _nxe_dns_server_get                                 PORTABLE C      */
1831 /*                                                           6.1          */
1832 /*  AUTHOR                                                                */
1833 /*                                                                        */
1834 /*    Yuxin Zhou, Microsoft Corporation                                   */
1835 /*                                                                        */
1836 /*  DESCRIPTION                                                           */
1837 /*                                                                        */
1838 /*    This function checks for errors in the get DNS server service.      */
1839 /*                                                                        */
1840 /*  INPUT                                                                 */
1841 /*                                                                        */
1842 /*    dns_ptr                               Pointer to DNS instance       */
1843 /*    index                                 Index into server list        */
1844 /*    dns_server_address                    DNS Server IP address         */
1845 /*                                                                        */
1846 /*  OUTPUT                                                                */
1847 /*                                                                        */
1848 /*    status                                Completion status             */
1849 /*                                                                        */
1850 /*  CALLS                                                                 */
1851 /*                                                                        */
1852 /*    _nx_dns_server_get                    Actual get DNS server service */
1853 /*                                                                        */
1854 /*  CALLED BY                                                             */
1855 /*                                                                        */
1856 /*    Application Code                                                    */
1857 /*                                                                        */
1858 /*  RELEASE HISTORY                                                       */
1859 /*                                                                        */
1860 /*    DATE              NAME                      DESCRIPTION             */
1861 /*                                                                        */
1862 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1863 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1864 /*                                            resulting in version 6.1    */
1865 /*                                                                        */
1866 /**************************************************************************/
_nxe_dns_server_get(NX_DNS * dns_ptr,UINT index,ULONG * dns_server_address)1867 UINT  _nxe_dns_server_get(NX_DNS *dns_ptr, UINT index, ULONG *dns_server_address)
1868 {
1869 
1870 UINT    status;
1871 
1872     /* Check for invalid input pointers.  */
1873     if ((dns_ptr == NX_NULL) || (dns_ptr -> nx_dns_id != NX_DNS_ID) || (dns_server_address == NX_NULL))
1874     {
1875         return(NX_PTR_ERROR);
1876     }
1877 
1878     /* Check for appropriate caller. */
1879     NX_THREADS_ONLY_CALLER_CHECKING
1880 
1881     /* Call actual get DNS server service.  */
1882     status =  _nx_dns_server_get(dns_ptr, index, dns_server_address);
1883 
1884     /* Return status.  */
1885     return(status);
1886 }
1887 
1888 
1889 /**************************************************************************/
1890 /*                                                                        */
1891 /*  FUNCTION                                               RELEASE        */
1892 /*                                                                        */
1893 /*    _nx_dns_server_get                                  PORTABLE C      */
1894 /*                                                           6.1          */
1895 /*  AUTHOR                                                                */
1896 /*                                                                        */
1897 /*    Yuxin Zhou, Microsoft Corporation                                   */
1898 /*                                                                        */
1899 /*  DESCRIPTION                                                           */
1900 /*                                                                        */
1901 /*    This function calls actual service to get the DNS Server address.   */
1902 /*                                                                        */
1903 /*  INPUT                                                                 */
1904 /*                                                                        */
1905 /*    dns_ptr                               Pointer to DNS client         */
1906 /*    index                                 Index into server list        */
1907 /*    dns_server_address                    DNS Server IP address         */
1908 /*                                                                        */
1909 /*  OUTPUT                                                                */
1910 /*                                                                        */
1911 /*    status                                Completion status             */
1912 /*                                                                        */
1913 /*  CALLS                                                                 */
1914 /*                                                                        */
1915 /*    _nx_dns_server_get                    Get DNS server service        */
1916 /*                                                                        */
1917 /*  CALLED BY                                                             */
1918 /*                                                                        */
1919 /*    Application Code                                                    */
1920 /*                                                                        */
1921 /*  RELEASE HISTORY                                                       */
1922 /*                                                                        */
1923 /*    DATE              NAME                      DESCRIPTION             */
1924 /*                                                                        */
1925 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1926 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1927 /*                                            resulting in version 6.1    */
1928 /*                                                                        */
1929 /**************************************************************************/
_nx_dns_server_get(NX_DNS * dns_ptr,UINT index,ULONG * dns_server_address)1930 UINT  _nx_dns_server_get(NX_DNS *dns_ptr, UINT index, ULONG *dns_server_address)
1931 {
1932 
1933 #ifndef NX_DISABLE_IPV4
1934 UINT        status;
1935 NXD_ADDRESS server_address;
1936 
1937 
1938     /* Initialize to not found. */
1939     *dns_server_address = 0x0;
1940 
1941     /* Invoke the real function. */
1942     status = _nx_dns_server_get_internal(dns_ptr, index, &server_address);
1943 
1944     if (status != NX_SUCCESS)
1945     {
1946         return status;
1947     }
1948 
1949     /* Verify this is an IPv4 address. */
1950     if (server_address.nxd_ip_version != NX_IP_VERSION_V4)
1951     {
1952          return NX_DNS_INVALID_ADDRESS_TYPE;
1953     }
1954 
1955     /* Return the IPv4 address information. */
1956     *dns_server_address = server_address.nxd_ip_address.v4;
1957 
1958     return NX_SUCCESS;
1959 #else
1960     NX_PARAMETER_NOT_USED(dns_ptr);
1961     NX_PARAMETER_NOT_USED(index);
1962     NX_PARAMETER_NOT_USED(dns_server_address);
1963 
1964     return(NX_NOT_SUPPORTED);
1965 #endif /* NX_DISABLE_IPV4 */
1966 }
1967 
1968 
1969 /**************************************************************************/
1970 /*                                                                        */
1971 /*  FUNCTION                                               RELEASE        */
1972 /*                                                                        */
1973 /*    _nxde_dns_server_get                                PORTABLE C      */
1974 /*                                                           6.1          */
1975 /*  AUTHOR                                                                */
1976 /*                                                                        */
1977 /*    Yuxin Zhou, Microsoft Corporation                                   */
1978 /*                                                                        */
1979 /*  DESCRIPTION                                                           */
1980 /*                                                                        */
1981 /*    This function checks for errors in the get DNS server service.      */
1982 /*                                                                        */
1983 /*  INPUT                                                                 */
1984 /*                                                                        */
1985 /*    dns_ptr                              Pointer to DNS client          */
1986 /*    index                                Index into server list         */
1987 /*    dns_server_address                   Pointer to Server address      */
1988 /*                                                                        */
1989 /*  OUTPUT                                                                */
1990 /*                                                                        */
1991 /*    status                               Completion status              */
1992 /*                                                                        */
1993 /*  CALLS                                                                 */
1994 /*                                                                        */
1995 /*    _nx_dns_server_remove                 Actual DNS return server      */
1996 /*                                            service                     */
1997 /*                                                                        */
1998 /*  CALLED BY                                                             */
1999 /*                                                                        */
2000 /*    Application Code                                                    */
2001 /*                                                                        */
2002 /*  RELEASE HISTORY                                                       */
2003 /*                                                                        */
2004 /*    DATE              NAME                      DESCRIPTION             */
2005 /*                                                                        */
2006 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2007 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2008 /*                                            resulting in version 6.1    */
2009 /*                                                                        */
2010 /**************************************************************************/
_nxde_dns_server_get(NX_DNS * dns_ptr,UINT index,NXD_ADDRESS * dns_server_address)2011 UINT  _nxde_dns_server_get(NX_DNS *dns_ptr, UINT index, NXD_ADDRESS *dns_server_address)
2012 {
2013 
2014 UINT    status;
2015 
2016 
2017     /* Check for invalid input pointers.  */
2018     if ((dns_ptr == NX_NULL) || (dns_server_address == NX_NULL) || (dns_ptr -> nx_dns_id != NX_DNS_ID))
2019     {
2020         return(NX_PTR_ERROR);
2021     }
2022 
2023     /* Check for appropriate caller.  */
2024     NX_THREADS_ONLY_CALLER_CHECKING
2025 
2026     /* Call actual get DNS server service.  */
2027     status =  _nxd_dns_server_get(dns_ptr, index, dns_server_address);
2028 
2029     /* Return status.  */
2030     return(status);
2031 }
2032 
2033 
2034 /**************************************************************************/
2035 /*                                                                        */
2036 /*  FUNCTION                                               RELEASE        */
2037 /*                                                                        */
2038 /*    _nxd_dns_server_get                                 PORTABLE C      */
2039 /*                                                           6.1          */
2040 /*  AUTHOR                                                                */
2041 /*                                                                        */
2042 /*    Yuxin Zhou, Microsoft Corporation                                   */
2043 /*                                                                        */
2044 /*  DESCRIPTION                                                           */
2045 /*                                                                        */
2046 /*    This function retreives the DNS server at the specified index into  */
2047 /*    the DNS server list.  If the index exceeds the size of the list or  */
2048 /*    an empty slot is at that index, the function returns an error.      */
2049 /*                                                                        */
2050 /*  INPUT                                                                 */
2051 /*                                                                        */
2052 /*    dns_ptr                              Pointer to DNS client          */
2053 /*    index                                Index into server list         */
2054 /*    dns_server_address                   Pointer to Server IP address   */
2055 /*                                                                        */
2056 /*  OUTPUT                                                                */
2057 /*                                                                        */
2058 /*    status                                Completion status             */
2059 /*                                                                        */
2060 /*  CALLS                                                                 */
2061 /*                                                                        */
2062 /*    tx_mutex_get                          Get DNS protection mutex      */
2063 /*    tx_mutex_put                          Release DNS protection mutex  */
2064 /*                                                                        */
2065 /*  CALLED BY                                                             */
2066 /*                                                                        */
2067 /*    Application Code                                                    */
2068 /*                                                                        */
2069 /*  RELEASE HISTORY                                                       */
2070 /*                                                                        */
2071 /*    DATE              NAME                      DESCRIPTION             */
2072 /*                                                                        */
2073 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2074 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2075 /*                                            resulting in version 6.1    */
2076 /*                                                                        */
2077 /**************************************************************************/
_nxd_dns_server_get(NX_DNS * dns_ptr,UINT index,NXD_ADDRESS * dns_server_address)2078 UINT  _nxd_dns_server_get(NX_DNS *dns_ptr, UINT index, NXD_ADDRESS *dns_server_address)
2079 {
2080 
2081     /* Invoke the real function. */
2082     return(_nx_dns_server_get_internal(dns_ptr, index, dns_server_address));
2083 }
2084 
2085 
2086 /**************************************************************************/
2087 /*                                                                        */
2088 /*  FUNCTION                                               RELEASE        */
2089 /*                                                                        */
2090 /*    _nx_dns_server_get_internal                         PORTABLE C      */
2091 /*                                                           6.1          */
2092 /*  AUTHOR                                                                */
2093 /*                                                                        */
2094 /*    Yuxin Zhou, Microsoft Corporation                                   */
2095 /*                                                                        */
2096 /*  DESCRIPTION                                                           */
2097 /*                                                                        */
2098 /*    This function retreives the DNS server at the specified index into  */
2099 /*    the DNS server list.  If the index exceeds the size of the list or  */
2100 /*    an empty slot is at that index, the function returns an error.      */
2101 /*                                                                        */
2102 /*  INPUT                                                                 */
2103 /*                                                                        */
2104 /*    dns_ptr                              Pointer to DNS client          */
2105 /*    index                                Index into server list         */
2106 /*    dns_server_address                   Pointer to Server IP address   */
2107 /*                                                                        */
2108 /*  OUTPUT                                                                */
2109 /*                                                                        */
2110 /*    status                                Completion status             */
2111 /*                                                                        */
2112 /*  CALLS                                                                 */
2113 /*                                                                        */
2114 /*    tx_mutex_get                          Get DNS protection mutex      */
2115 /*    tx_mutex_put                          Release DNS protection mutex  */
2116 /*                                                                        */
2117 /*  CALLED BY                                                             */
2118 /*                                                                        */
2119 /*    Application Code                                                    */
2120 /*                                                                        */
2121 /*  RELEASE HISTORY                                                       */
2122 /*                                                                        */
2123 /*    DATE              NAME                      DESCRIPTION             */
2124 /*                                                                        */
2125 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2126 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2127 /*                                            resulting in version 6.1    */
2128 /*                                                                        */
2129 /**************************************************************************/
_nx_dns_server_get_internal(NX_DNS * dns_ptr,UINT index,NXD_ADDRESS * server_address)2130 static UINT  _nx_dns_server_get_internal(NX_DNS *dns_ptr, UINT index, NXD_ADDRESS *server_address)
2131 {
2132 
2133 UINT            status;
2134 
2135 
2136     /* Get the protection mutex to make sure no other thread interferes.  */
2137     status =  tx_mutex_get(&(dns_ptr -> nx_dns_mutex), TX_WAIT_FOREVER);
2138 
2139     /* Determine if there was an error getting the mutex.  */
2140     if (status != TX_SUCCESS)
2141     {
2142 
2143         /* Return an error.  */
2144         return(status);
2145     }
2146 
2147     /* Check for an invalid index. The max list size is NX_DNS_MAX_SERVERS.  */
2148     if (index >= NX_DNS_MAX_SERVERS)
2149     {
2150 
2151         return NX_DNS_PARAM_ERROR;
2152     }
2153 
2154     /* Is there a valid IP address entry in this slot? */
2155     if (dns_ptr -> nx_dns_server_ip_array[index].nxd_ip_version == 0)
2156     {
2157 
2158         /* No, release the mutex and return.  */
2159         tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
2160 
2161         return NX_DNS_SERVER_NOT_FOUND;
2162     }
2163 #ifndef NX_DISABLE_IPV4
2164     /* Check for a null IPv4 address if this is an IPv4 type. */
2165     else if ((dns_ptr -> nx_dns_server_ip_array[index].nxd_ip_version == NX_IP_VERSION_V4) &&
2166              (dns_ptr -> nx_dns_server_ip_array[index].nxd_ip_address.v4 == 0))
2167     {
2168 
2169         /* Error, release the mutex and return.  */
2170         tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
2171 
2172         return NX_DNS_BAD_ADDRESS_ERROR;
2173     }
2174 #endif /* NX_DISABLE_IPV4 */
2175     else if (dns_ptr -> nx_dns_server_ip_array[index].nxd_ip_version == NX_IP_VERSION_V6)
2176 #ifndef FEATURE_NX_IPV6
2177     {
2178 
2179          /* IPv6 not enabled, return an error status. */
2180 
2181          /* Release the mutex and return.  */
2182          tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
2183 
2184          return NX_DNS_INVALID_ADDRESS_TYPE;
2185     }
2186 #else
2187     {
2188 
2189         /* Check for unspecified (null) IPv6 address. */
2190          if (CHECK_UNSPECIFIED_ADDRESS(&(dns_ptr -> nx_dns_server_ip_array[index].nxd_ip_address.v6[0])))
2191          {
2192 
2193              /* Error, release the mutex and return.  */
2194              tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
2195 
2196              return NX_DNS_BAD_ADDRESS_ERROR;
2197          }
2198      }
2199 #endif
2200 
2201     /* Set a pointer to the DNS server in the list. */
2202     *server_address = (dns_ptr -> nx_dns_server_ip_array[index]);
2203 
2204     /* Release the mutex.  */
2205     tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
2206 
2207     /* Return a successful completion.  */
2208     return(NX_SUCCESS);
2209 }
2210 
2211 
2212 /**************************************************************************/
2213 /*                                                                        */
2214 /*  FUNCTION                                               RELEASE        */
2215 /*                                                                        */
2216 /*    _nxe_dns_host_by_name_get                           PORTABLE C      */
2217 /*                                                           6.1          */
2218 /*  AUTHOR                                                                */
2219 /*                                                                        */
2220 /*    Yuxin Zhou, Microsoft Corporation                                   */
2221 /*                                                                        */
2222 /*  DESCRIPTION                                                           */
2223 /*                                                                        */
2224 /*    This function checks for errors in the DNS look up host IP address  */
2225 /*    by name service.                                                    */
2226 /*                                                                        */
2227 /*  INPUT                                                                 */
2228 /*                                                                        */
2229 /*    dns_ptr                               Pointer to DNS instance       */
2230 /*    host_name                             Name of host to resolve       */
2231 /*    host_address_ptr                      Pointer to DNS host IP address*/
2232 /*    wait_option                           Timeout value                 */
2233 /*                                                                        */
2234 /*  OUTPUT                                                                */
2235 /*                                                                        */
2236 /*    status                                Completion status             */
2237 /*                                                                        */
2238 /*  CALLS                                                                 */
2239 /*                                                                        */
2240 /*    _nx_dns_host_by_name_get              Actual DNS host IP address    */
2241 /*                                            lookup by host name service */
2242 /*                                                                        */
2243 /*  CALLED BY                                                             */
2244 /*                                                                        */
2245 /*    Application Code                                                    */
2246 /*                                                                        */
2247 /*  RELEASE HISTORY                                                       */
2248 /*                                                                        */
2249 /*    DATE              NAME                      DESCRIPTION             */
2250 /*                                                                        */
2251 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2252 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2253 /*                                            resulting in version 6.1    */
2254 /*                                                                        */
2255 /**************************************************************************/
_nxe_dns_host_by_name_get(NX_DNS * dns_ptr,UCHAR * host_name,ULONG * host_address_ptr,ULONG wait_option)2256 UINT  _nxe_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, ULONG *host_address_ptr, ULONG wait_option)
2257 {
2258 
2259 UINT    status;
2260 
2261 
2262     /* Check for invalid input pointers.  */
2263     if ((dns_ptr == NX_NULL) || (host_name == NX_NULL) || (host_address_ptr == NX_NULL))
2264         return(NX_PTR_ERROR);
2265 
2266     /* Check for invalid non pointer input. */
2267     if (dns_ptr -> nx_dns_id != NX_DNS_ID)
2268     {
2269         return(NX_DNS_PARAM_ERROR);
2270     }
2271 
2272     /* Check for appropriate caller.  */
2273     NX_THREADS_ONLY_CALLER_CHECKING
2274 
2275     /* Call actual DNS get host by name service.  */
2276     status =  _nx_dns_host_by_name_get(dns_ptr, host_name, host_address_ptr, wait_option);
2277 
2278     /* Return status.  */
2279     return(status);
2280 }
2281 
2282 
2283 /**************************************************************************/
2284 /*                                                                        */
2285 /*  FUNCTION                                               RELEASE        */
2286 /*                                                                        */
2287 /*    _nx_dns_host_by_name_get                            PORTABLE C      */
2288 /*                                                           6.1          */
2289 /*  AUTHOR                                                                */
2290 /*                                                                        */
2291 /*    Yuxin Zhou, Microsoft Corporation                                   */
2292 /*                                                                        */
2293 /*  DESCRIPTION                                                           */
2294 /*                                                                        */
2295 /*    This function calls service to get the host address by name service */
2296 /*    as an A record (IPv4) lookup query.                                 */
2297 /*                                                                        */
2298 /*  INPUT                                                                 */
2299 /*                                                                        */
2300 /*    dns_ptr                               Pointer to DNS instance       */
2301 /*    host_name                             Name of host to resolve       */
2302 /*    host_address_ptr                      Pointer to DNS host IP address*/
2303 /*    wait_option                           Timeout value                 */
2304 /*                                                                        */
2305 /*  OUTPUT                                                                */
2306 /*                                                                        */
2307 /*    status                                Completion status             */
2308 /*                                                                        */
2309 /*  CALLS                                                                 */
2310 /*                                                                        */
2311 /*    _nx_dns_host_resource_data_by_name_get                              */
2312 /*                                          Actual DNS get host address   */
2313 /*                                            by name service             */
2314 /*                                                                        */
2315 /*  CALLED BY                                                             */
2316 /*                                                                        */
2317 /*    Application Code                                                    */
2318 /*                                                                        */
2319 /*  RELEASE HISTORY                                                       */
2320 /*                                                                        */
2321 /*    DATE              NAME                      DESCRIPTION             */
2322 /*                                                                        */
2323 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2324 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2325 /*                                            resulting in version 6.1    */
2326 /*                                                                        */
2327 /**************************************************************************/
_nx_dns_host_by_name_get(NX_DNS * dns_ptr,UCHAR * host_name,ULONG * host_address_ptr,ULONG wait_option)2328 UINT  _nx_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, ULONG *host_address_ptr, ULONG wait_option)
2329 {
2330 
2331 UINT        status;
2332 UINT        record_count = 0;
2333 
2334     /* Keep the API consistency. Invoke the real DNS query call. */
2335     status = _nx_dns_host_resource_data_by_name_get(dns_ptr, host_name, (VOID*)host_address_ptr, sizeof(ULONG), &record_count, NX_DNS_RR_TYPE_A, wait_option);
2336 
2337     /* Record_count set to 1 indicates the call is successful. */
2338     if(record_count == 1)
2339     {
2340         /* Set the return value. */
2341         status = NX_SUCCESS;
2342     }
2343 
2344     /* Return completion status. */
2345     return status;
2346 }
2347 
2348 
2349 /**************************************************************************/
2350 /*                                                                        */
2351 /*  FUNCTION                                               RELEASE        */
2352 /*                                                                        */
2353 /*    _nxde_dns_host_by_name_get                          PORTABLE C      */
2354 /*                                                           6.1          */
2355 /*  AUTHOR                                                                */
2356 /*                                                                        */
2357 /*    Yuxin Zhou, Microsoft Corporation                                   */
2358 /*                                                                        */
2359 /*  DESCRIPTION                                                           */
2360 /*                                                                        */
2361 /*    This function checks for errors in the DNS get host by name         */
2362 /*    function call.                                                      */
2363 /*                                                                        */
2364 /*  INPUT                                                                 */
2365 /*                                                                        */
2366 /*    dns_ptr                               Pointer to DNS instance       */
2367 /*    host_name                             Name of host to resolve       */
2368 /*    host_address_ptr                      Pointer to destination of     */
2369 /*                                            host IP address             */
2370 /*    wait_option                           Timeout value                 */
2371 /*    lookup_type                           Lookup for which IP version   */
2372 /*                                                                        */
2373 /*  OUTPUT                                                                */
2374 /*                                                                        */
2375 /*    status                                Completion status             */
2376 /*                                                                        */
2377 /*  CALLS                                                                 */
2378 /*                                                                        */
2379 /*    _nxd_dns_host_by_name_get             Actual DNS get host by name   */
2380 /*                                            function                    */
2381 /*                                                                        */
2382 /*  CALLED BY                                                             */
2383 /*                                                                        */
2384 /*    Application Code                                                    */
2385 /*                                                                        */
2386 /*  RELEASE HISTORY                                                       */
2387 /*                                                                        */
2388 /*    DATE              NAME                      DESCRIPTION             */
2389 /*                                                                        */
2390 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2391 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2392 /*                                            resulting in version 6.1    */
2393 /*                                                                        */
2394 /**************************************************************************/
_nxde_dns_host_by_name_get(NX_DNS * dns_ptr,UCHAR * host_name,NXD_ADDRESS * host_address_ptr,ULONG wait_option,UINT lookup_type)2395 UINT  _nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr,
2396                                  ULONG wait_option, UINT lookup_type)
2397 {
2398 
2399 UINT    status;
2400 
2401     /* Check for invalid pointer input.  */
2402     if ((dns_ptr == NX_NULL) || (host_name == NX_NULL) || (host_address_ptr == NX_NULL))
2403         return(NX_PTR_ERROR);
2404 
2405     /* Check for invalid non pointer input. */
2406     if ((dns_ptr -> nx_dns_id != NX_DNS_ID) || (lookup_type == 0))
2407     {
2408         return NX_DNS_PARAM_ERROR;
2409     }
2410 
2411     /* Check for appropriate caller.  */
2412     NX_THREADS_ONLY_CALLER_CHECKING
2413 
2414     /* Call actual DNS get host by name service.  */
2415     status =  _nxd_dns_host_by_name_get(dns_ptr, host_name, host_address_ptr, wait_option, lookup_type);
2416 
2417     /* Return status.  */
2418     return(status);
2419 }
2420 
2421 
2422 /**************************************************************************/
2423 /*                                                                        */
2424 /*  FUNCTION                                               RELEASE        */
2425 /*                                                                        */
2426 /*    _nxd_dns_host_by_name_get                           PORTABLE C      */
2427 /*                                                           6.1          */
2428 /*  AUTHOR                                                                */
2429 /*                                                                        */
2430 /*    Yuxin Zhou, Microsoft Corporation                                   */
2431 /*                                                                        */
2432 /*  DESCRIPTION                                                           */
2433 /*                                                                        */
2434 /*    This function checks for errors in the DNS get host by name         */
2435 /*    function call.                                                      */
2436 /*                                                                        */
2437 /*  INPUT                                                                 */
2438 /*                                                                        */
2439 /*    dns_ptr                               Pointer to DNS instance       */
2440 /*    host_name                             Name of host to resolve       */
2441 /*    host_address_ptr                      Pointer to host IP address    */
2442 /*    wait_option                           Timeout value                 */
2443 /*    lookup_type                           Lookup for which IP version   */
2444 /*                                                                        */
2445 /*  OUTPUT                                                                */
2446 /*                                                                        */
2447 /*    status                                Completion status             */
2448 /*                                                                        */
2449 /*  CALLS                                                                 */
2450 /*                                                                        */
2451 /*    _nx_dns_host_resource_data_by_name_get                              */
2452 /*                                          Actual DNS get host by name   */
2453 /*                                            function                    */
2454 /*                                                                        */
2455 /*  CALLED BY                                                             */
2456 /*                                                                        */
2457 /*    Application Code                                                    */
2458 /*                                                                        */
2459 /*  RELEASE HISTORY                                                       */
2460 /*                                                                        */
2461 /*    DATE              NAME                      DESCRIPTION             */
2462 /*                                                                        */
2463 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2464 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2465 /*                                            resulting in version 6.1    */
2466 /*                                                                        */
2467 /**************************************************************************/
_nxd_dns_host_by_name_get(NX_DNS * dns_ptr,UCHAR * host_name,NXD_ADDRESS * host_address_ptr,ULONG wait_option,UINT lookup_type)2468 UINT  _nxd_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr,
2469                                 ULONG wait_option, UINT lookup_type)
2470 {
2471 
2472 UINT        status;
2473 UINT        record_count = 0;
2474 
2475 
2476     /* Is this a AAAA record lookup (e.g. expect an IPv6 address)? If no type is specified default to AAAA type. */
2477     if((lookup_type == NX_IP_VERSION_V6) || (lookup_type == 0))
2478     {
2479 
2480 #ifdef FEATURE_NX_IPV6
2481         /* Send AAAA type message, and keep the API consistency. Invoke the real connection call. */
2482         status = _nx_dns_host_resource_data_by_name_get(dns_ptr, host_name, (UCHAR *)&host_address_ptr -> nxd_ip_address.v6[0], 16, &record_count, NX_DNS_RR_TYPE_AAAA, wait_option);
2483 
2484         /* Record_count being set indicates the query gets a valid answer. */
2485         if (record_count)
2486         {
2487 
2488             /* Have recorded the IPv6 address, set the IP version.  */
2489             host_address_ptr -> nxd_ip_version = NX_IP_VERSION_V6;
2490 
2491             /* Modify the return status.*/
2492             status = NX_SUCCESS;
2493         }
2494 #else
2495         return NX_DNS_IPV6_NOT_SUPPORTED;
2496 #endif
2497     }
2498     else if(lookup_type == NX_IP_VERSION_V4)
2499     {
2500 
2501 #ifndef NX_DISABLE_IPV4
2502         /* Keep the API consistency. Invoke the real connection call. */
2503         status = _nx_dns_host_resource_data_by_name_get(dns_ptr, host_name, (UCHAR *)&host_address_ptr -> nxd_ip_address.v4, sizeof(ULONG), &record_count, NX_DNS_RR_TYPE_A, wait_option);
2504 
2505         /* Record_count being set indicates the query gets a valid answer. */
2506         if (record_count)
2507         {
2508 
2509             /* Have recorded the IPv4 address, set the IP version.  */
2510             host_address_ptr -> nxd_ip_version = NX_IP_VERSION_V4;
2511 
2512             /* Modify the return status.*/
2513             status = NX_SUCCESS;
2514         }
2515 #else
2516         return NX_DNS_BAD_ADDRESS_ERROR;
2517 #endif
2518     }
2519 
2520     else
2521     {
2522         return NX_DNS_BAD_ADDRESS_ERROR;
2523     }
2524 
2525     /* Return status.  */
2526     return(status);
2527 }
2528 
2529 
2530 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
2531 /**************************************************************************/
2532 /*                                                                        */
2533 /*  FUNCTION                                               RELEASE        */
2534 /*                                                                        */
2535 /*    _nxe_dns_info_by_name_get                           PORTABLE C      */
2536 /*                                                           6.1          */
2537 /*  AUTHOR                                                                */
2538 /*                                                                        */
2539 /*    Yuxin Zhou, Microsoft Corporation                                   */
2540 /*                                                                        */
2541 /*  DESCRIPTION                                                           */
2542 /*                                                                        */
2543 /*    This function checks for errors in the DNS get info by name         */
2544 /*    function call.                                                      */
2545 /*                                                                        */
2546 /*  INPUT                                                                 */
2547 /*                                                                        */
2548 /*    dns_ptr                               Pointer to DNS instance       */
2549 /*    host_name                             Name of host to resolve       */
2550 /*    host_address_ptr                      Pointer to destination of     */
2551 /*                                            host IP address             */
2552 /*    host_port_ptr                         Pointer to destination of host*/
2553 /*                                            source port                 */
2554 /*    wait_option                           Timeout value                 */
2555 /*                                                                        */
2556 /*  OUTPUT                                                                */
2557 /*                                                                        */
2558 /*    status                                Completion status             */
2559 /*                                                                        */
2560 /*  CALLS                                                                 */
2561 /*                                                                        */
2562 /*    _nx_dns_info_by_name_get              Actual DNS get info by name   */
2563 /*                                            function                    */
2564 /*                                                                        */
2565 /*  CALLED BY                                                             */
2566 /*                                                                        */
2567 /*    Application Code                                                    */
2568 /*                                                                        */
2569 /*  RELEASE HISTORY                                                       */
2570 /*                                                                        */
2571 /*    DATE              NAME                      DESCRIPTION             */
2572 /*                                                                        */
2573 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2574 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2575 /*                                            resulting in version 6.1    */
2576 /*                                                                        */
2577 /**************************************************************************/
_nxe_dns_info_by_name_get(NX_DNS * dns_ptr,UCHAR * host_name,ULONG * host_address_ptr,USHORT * host_port_ptr,ULONG wait_option)2578 UINT  _nxe_dns_info_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, ULONG *host_address_ptr, USHORT *host_port_ptr, ULONG wait_option)
2579 {
2580 
2581 UINT    status;
2582 
2583     /* Check for invalid input pointers.  */
2584     if ((dns_ptr == NX_NULL) || (dns_ptr -> nx_dns_id != NX_DNS_ID) ||
2585         (host_name == NX_NULL) || (host_address_ptr == NX_NULL) || (host_port_ptr == NX_NULL))
2586         return(NX_PTR_ERROR);
2587 
2588     /* Check for appropriate caller.  */
2589     NX_THREADS_ONLY_CALLER_CHECKING
2590 
2591     /* Call actual DNS get host by name service.  */
2592     status =  _nx_dns_info_by_name_get(dns_ptr, host_name, host_address_ptr, host_port_ptr, wait_option);
2593 
2594     /* Return status.  */
2595     return(status);
2596 }
2597 #endif
2598 
2599 
2600 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
2601 /**************************************************************************/
2602 /*                                                                        */
2603 /*  FUNCTION                                               RELEASE        */
2604 /*                                                                        */
2605 /*    _nx_dns_info_by_name_get                            PORTABLE C      */
2606 /*                                                           6.1          */
2607 /*  AUTHOR                                                                */
2608 /*                                                                        */
2609 /*    Yuxin Zhou, Microsoft Corporation                                   */
2610 /*                                                                        */
2611 /*  DESCRIPTION                                                           */
2612 /*                                                                        */
2613 /*    This function uses DNS to get the Service record associated with the*/
2614 /*    specified host name.  If a service rec cannot be found, this        */
2615 /*    routine returns a zero IP address in the input address pointer and a*/
2616 /*    non zero error status return to signal an error.                    */
2617 /*                                                                        */
2618 /*  INPUT                                                                 */
2619 /*                                                                        */
2620 /*    dns_ptr                               Pointer to DNS instance       */
2621 /*    host_name                             Name of host to resolve       */
2622 /*    host_address_ptr                      Pointer to destination of     */
2623 /*                                            host IP address             */
2624 /*    host_port_ptr                         Pointer to destination of     */
2625 /*                                            host port                   */
2626 /*    wait_option                           Timeout value                 */
2627 /*                                                                        */
2628 /*  OUTPUT                                                                */
2629 /*                                                                        */
2630 /*    status                                Completion status             */
2631 /*                                                                        */
2632 /*  CALLS                                                                 */
2633 /*                                                                        */
2634 /*                                                                        */
2635 /*  CALLED BY                                                             */
2636 /*                                                                        */
2637 /*    Application Code                                                    */
2638 /*                                                                        */
2639 /*  RELEASE HISTORY                                                       */
2640 /*                                                                        */
2641 /*    DATE              NAME                      DESCRIPTION             */
2642 /*                                                                        */
2643 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2644 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2645 /*                                            resulting in version 6.1    */
2646 /*                                                                        */
2647 /**************************************************************************/
_nx_dns_info_by_name_get(NX_DNS * dns_ptr,UCHAR * host_name,ULONG * host_address_ptr,USHORT * host_port_ptr,ULONG wait_option)2648 UINT  _nx_dns_info_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, ULONG *host_address_ptr,
2649                                        USHORT *host_port_ptr, ULONG wait_option)
2650 {
2651 
2652 NX_DNS_SRV_ENTRY    *dns_srv_entry;
2653 UINT                record_count;
2654 UINT                status;
2655 UCHAR               temp_buffer[TEMP_SRV_BUFFER_SIZE];
2656 
2657     /* Call the service get function to get information. */
2658     status =  _nx_dns_domain_service_get(dns_ptr, host_name, (VOID *)temp_buffer, TEMP_SRV_BUFFER_SIZE, &record_count, wait_option);
2659 
2660     /* Check erros. */
2661     if(status)
2662     {
2663         return status;
2664     }
2665 
2666     /* Set the srv pointer.  */
2667     dns_srv_entry = (NX_DNS_SRV_ENTRY *)temp_buffer;
2668 
2669     /* record the info returned to user. */
2670     *host_address_ptr = dns_srv_entry -> nx_dns_srv_ipv4_address;
2671     *host_port_ptr = dns_srv_entry -> nx_dns_srv_port_number;
2672 
2673     return NX_SUCCESS;
2674 }
2675 #endif
2676 
2677 
2678 /**************************************************************************/
2679 /*                                                                        */
2680 /*  FUNCTION                                               RELEASE        */
2681 /*                                                                        */
2682 /*    _nxe_dns_ipv4_address_by_name_get                   PORTABLE C      */
2683 /*                                                           6.1          */
2684 /*  AUTHOR                                                                */
2685 /*                                                                        */
2686 /*    Yuxin Zhou, Microsoft Corporation                                   */
2687 /*                                                                        */
2688 /*  DESCRIPTION                                                           */
2689 /*                                                                        */
2690 /*    This function checks for errors in the DNS look up host IP address  */
2691 /*    by name service.                                                    */
2692 /*                                                                        */
2693 /*  INPUT                                                                 */
2694 /*                                                                        */
2695 /*    dns_ptr                              Pointer to DNS instance        */
2696 /*    host_name_ptr                        Name of host to search on      */
2697 /*    record_buffer                        Buffer space for storing       */
2698 /*                                           IPv4 addresses               */
2699 /*    buffer_size                          Size of the record_buffer      */
2700 /*    record_count                         The count of IPv4 addresses    */
2701 /*    wait_option                          Time to wait on server response*/
2702 /*                                                                        */
2703 /*  OUTPUT                                                                */
2704 /*                                                                        */
2705 /*    status                                Completion status             */
2706 /*                                                                        */
2707 /*  CALLS                                                                 */
2708 /*                                                                        */
2709 /*    _nx_dns_ipv4_address_by_name_get      Actual DNS host IP address    */
2710 /*                                            lookup by host name service */
2711 /*                                                                        */
2712 /*  CALLED BY                                                             */
2713 /*                                                                        */
2714 /*    Application Code                                                    */
2715 /*                                                                        */
2716 /*  RELEASE HISTORY                                                       */
2717 /*                                                                        */
2718 /*    DATE              NAME                      DESCRIPTION             */
2719 /*                                                                        */
2720 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2721 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2722 /*                                            resulting in version 6.1    */
2723 /*                                                                        */
2724 /**************************************************************************/
_nxe_dns_ipv4_address_by_name_get(NX_DNS * dns_ptr,UCHAR * host_name_ptr,VOID * record_buffer,UINT buffer_size,UINT * record_count,ULONG wait_option)2725 UINT  _nxe_dns_ipv4_address_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name_ptr, VOID *record_buffer,
2726                                         UINT buffer_size, UINT *record_count, ULONG wait_option)
2727 {
2728 
2729 UINT    status;
2730 
2731     /* Check for invalid input pointers.  */
2732     if ((!dns_ptr) || (!host_name_ptr) || (!record_buffer) || (!record_count))
2733         return(NX_PTR_ERROR);
2734 
2735     /* Check for invalid non pointer input. */
2736     if (dns_ptr -> nx_dns_id != NX_DNS_ID)
2737     {
2738         return(NX_DNS_PARAM_ERROR);
2739     }
2740 
2741     /* Make sure record_buffer is 4-byte aligned. */
2742     if(((ALIGN_TYPE)record_buffer & 0x3) != 0)
2743     {
2744         return(NX_PTR_ERROR);
2745     }
2746 
2747     /* Check for appropriate caller.  */
2748     NX_THREADS_ONLY_CALLER_CHECKING
2749 
2750     /* Call actual DNS get host ipv4 address by name service.  */
2751     status =  _nx_dns_ipv4_address_by_name_get(dns_ptr, host_name_ptr, record_buffer, buffer_size, record_count, wait_option);
2752 
2753     /* Return status.  */
2754     return(status);
2755 }
2756 
2757 
2758 /**************************************************************************/
2759 /*                                                                        */
2760 /*  FUNCTION                                               RELEASE        */
2761 /*                                                                        */
2762 /*    _nx_dns_ipv4_address_by_name_get                    PORTABLE C      */
2763 /*                                                           6.1          */
2764 /*  AUTHOR                                                                */
2765 /*                                                                        */
2766 /*    Yuxin Zhou, Microsoft Corporation                                   */
2767 /*                                                                        */
2768 /*  DESCRIPTION                                                           */
2769 /*                                                                        */
2770 /*    This function calls service to get the host address by name service */
2771 /*    as an A record (IPv4) lookup query.                                 */
2772 /*                                                                        */
2773 /*  INPUT                                                                 */
2774 /*                                                                        */
2775 /*    dns_ptr                               Pointer to DNS instance       */
2776 /*    host_name                             Name of host to resolve       */
2777 /*    record_buffer                         Buffer space for storing      */
2778 /*                                            IPv4 addresses              */
2779 /*    buffer_size                           Size of the record_buffer     */
2780 /*    record_count                          The count of IPv4 addresses   */
2781 /*    wait_option                           Timeout value                 */
2782 /*                                                                        */
2783 /*  OUTPUT                                                                */
2784 /*                                                                        */
2785 /*    status                                Completion status             */
2786 /*                                                                        */
2787 /*  CALLS                                                                 */
2788 /*                                                                        */
2789 /*    _nx_dns_host_resource_data_by_name_get                              */
2790 /*                                          Actual DNS get host rdata     */
2791 /*                                               by name service          */
2792 /*                                                                        */
2793 /*  CALLED BY                                                             */
2794 /*                                                                        */
2795 /*    Application Code                                                    */
2796 /*                                                                        */
2797 /*  RELEASE HISTORY                                                       */
2798 /*                                                                        */
2799 /*    DATE              NAME                      DESCRIPTION             */
2800 /*                                                                        */
2801 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2802 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2803 /*                                            resulting in version 6.1    */
2804 /*                                                                        */
2805 /**************************************************************************/
_nx_dns_ipv4_address_by_name_get(NX_DNS * dns_ptr,UCHAR * host_name_ptr,VOID * buffer,UINT buffer_size,UINT * record_count,ULONG wait_option)2806 UINT  _nx_dns_ipv4_address_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name_ptr, VOID *buffer,
2807                                        UINT buffer_size, UINT *record_count, ULONG wait_option)
2808 {
2809 
2810 UINT        status;
2811 
2812     /* Invoke the real connection call. */
2813     status = _nx_dns_host_resource_data_by_name_get(dns_ptr, host_name_ptr, buffer, buffer_size, record_count, NX_DNS_RR_TYPE_A, wait_option);
2814 
2815     /* Return completion status. */
2816     return status;
2817 }
2818 
2819 
2820 /**************************************************************************/
2821 /*                                                                        */
2822 /*  FUNCTION                                               RELEASE        */
2823 /*                                                                        */
2824 /*    _nxde_dns_ipv6_address_by_name_get                  PORTABLE C      */
2825 /*                                                           6.1          */
2826 /*  AUTHOR                                                                */
2827 /*                                                                        */
2828 /*    Yuxin Zhou, Microsoft Corporation                                   */
2829 /*                                                                        */
2830 /*  DESCRIPTION                                                           */
2831 /*                                                                        */
2832 /*    This function checks for errors in the DNS look up host IPv6 address*/
2833 /*    by name service.                                                    */
2834 /*                                                                        */
2835 /*  INPUT                                                                 */
2836 /*                                                                        */
2837 /*    dns_ptr                              Pointer to DNS instance        */
2838 /*    host_name_ptr                        Name of host to search on      */
2839 /*    record_buffer                        Buffer space for storing IPv6  */
2840 /*                                           addresses.                   */
2841 /*    buffer_size                          Size of record_buffer          */
2842 /*    record_count                         The count of IPv6 addresses    */
2843 /*    wait_option                          Time to wait on server response*/
2844 /*                                                                        */
2845 /*  OUTPUT                                                                */
2846 /*                                                                        */
2847 /*    status                                Completion status             */
2848 /*                                                                        */
2849 /*  CALLS                                                                 */
2850 /*                                                                        */
2851 /*    _nx_dns_ipv6_address_by_name_get      Actual DNS host IPv6 address  */
2852 /*                                            lookup by host name service */
2853 /*                                                                        */
2854 /*  CALLED BY                                                             */
2855 /*                                                                        */
2856 /*    Application Code                                                    */
2857 /*                                                                        */
2858 /*  RELEASE HISTORY                                                       */
2859 /*                                                                        */
2860 /*    DATE              NAME                      DESCRIPTION             */
2861 /*                                                                        */
2862 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2863 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2864 /*                                            resulting in version 6.1    */
2865 /*                                                                        */
2866 /**************************************************************************/
_nxde_dns_ipv6_address_by_name_get(NX_DNS * dns_ptr,UCHAR * host_name_ptr,VOID * record_buffer,UINT buffer_size,UINT * record_count,ULONG wait_option)2867 UINT  _nxde_dns_ipv6_address_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name_ptr, VOID *record_buffer,
2868                                          UINT buffer_size, UINT *record_count, ULONG wait_option)
2869 {
2870 
2871 UINT    status;
2872 
2873     /* Check for invalid input pointers.  */
2874     if ((!dns_ptr) || (!host_name_ptr) || (!record_buffer) || (!record_count))
2875         return(NX_PTR_ERROR);
2876 
2877     /* Check for invalid non pointer input. */
2878     if (dns_ptr -> nx_dns_id != NX_DNS_ID)
2879     {
2880         return(NX_DNS_PARAM_ERROR);
2881     }
2882 
2883     /* Make sure record_buffer is 4-byte aligned. */
2884     if(((ALIGN_TYPE)record_buffer & 0x3) != 0)
2885     {
2886         return(NX_PTR_ERROR);
2887     }
2888 
2889     /* Check for appropriate caller.  */
2890     NX_THREADS_ONLY_CALLER_CHECKING
2891 
2892     /* Call actual DNS get host ipv6 address by name service.  */
2893     status =  _nxd_dns_ipv6_address_by_name_get(dns_ptr, host_name_ptr, record_buffer, buffer_size, record_count, wait_option);
2894 
2895     /* Return status.  */
2896     return(status);
2897 }
2898 
2899 
2900 /**************************************************************************/
2901 /*                                                                        */
2902 /*  FUNCTION                                               RELEASE        */
2903 /*                                                                        */
2904 /*    _nxd_dns_ipv6_address_by_name_get                   PORTABLE C      */
2905 /*                                                           6.1          */
2906 /*  AUTHOR                                                                */
2907 /*                                                                        */
2908 /*    Yuxin Zhou, Microsoft Corporation                                   */
2909 /*                                                                        */
2910 /*  DESCRIPTION                                                           */
2911 /*                                                                        */
2912 /*    This function creates an NXD_ADDRESS instance from the specified    */
2913 /*    IPv6 address and submits it to the actual get host by name service  */
2914 /*    as an AAAA record (IPv6) lookup query.                              */
2915 /*                                                                        */
2916 /*  INPUT                                                                 */
2917 /*                                                                        */
2918 /*    dns_ptr                              Pointer to DNS instance        */
2919 /*    host_name                            Name of host to resolve        */
2920 /*    record_buffer                        Buffer space for storing IPv6  */
2921 /*                                           addresses.                   */
2922 /*    buffer_size                          Size of record_buffer          */
2923 /*    record_count                         The count of IPv6 addresses    */
2924 /*    wait_option                          Timeout value                  */
2925 /*                                                                        */
2926 /*  OUTPUT                                                                */
2927 /*                                                                        */
2928 /*    status                                Completion status             */
2929 /*                                                                        */
2930 /*  CALLS                                                                 */
2931 /*                                                                        */
2932 /*    _nx_dns_host_resource_data_by_name_get                              */
2933 /*                                          Actual NetX Duo DNS get       */
2934 /*                                          host rdata by name service    */
2935 /*                                                                        */
2936 /*  CALLED BY                                                             */
2937 /*                                                                        */
2938 /*    Application Code                                                    */
2939 /*                                                                        */
2940 /*  RELEASE HISTORY                                                       */
2941 /*                                                                        */
2942 /*    DATE              NAME                      DESCRIPTION             */
2943 /*                                                                        */
2944 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2945 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2946 /*                                            resulting in version 6.1    */
2947 /*                                                                        */
2948 /**************************************************************************/
_nxd_dns_ipv6_address_by_name_get(NX_DNS * dns_ptr,UCHAR * host_name_ptr,VOID * buffer,UINT buffer_size,UINT * record_count,ULONG wait_option)2949 UINT  _nxd_dns_ipv6_address_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name_ptr, VOID *buffer,
2950                                         UINT buffer_size, UINT *record_count, ULONG wait_option)
2951 {
2952 
2953 UINT        status;
2954 
2955     /* Invoke the real connection call. */
2956     status = _nx_dns_host_resource_data_by_name_get(dns_ptr, host_name_ptr, buffer, buffer_size, record_count, NX_DNS_RR_TYPE_AAAA, wait_option);
2957 
2958     /* Return completion status. */
2959     return status;
2960 }
2961 
2962 
2963 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
2964 /**************************************************************************/
2965 /*                                                                        */
2966 /*  FUNCTION                                               RELEASE        */
2967 /*                                                                        */
2968 /*    _nxe_dns_cname_get                                  PORTABLE C      */
2969 /*                                                           6.1          */
2970 /*  AUTHOR                                                                */
2971 /*                                                                        */
2972 /*    Yuxin Zhou, Microsoft Corporation                                   */
2973 /*                                                                        */
2974 /*  DESCRIPTION                                                           */
2975 /*                                                                        */
2976 /*    This function checks for errors in the DNS look up host cname       */
2977 /*    by name service.                                                    */
2978 /*                                                                        */
2979 /*  INPUT                                                                 */
2980 /*                                                                        */
2981 /*    dns_ptr                              Pointer to DNS instance        */
2982 /*    host_name                            Name of host to search on      */
2983 /*    record_buffer                        Buffer space for storing       */
2984 /*                                           cname response.              */
2985 /*    buffer_size                          Size of record_buffer          */
2986 /*    wait_option                          Time to wait on server response*/
2987 /*                                                                        */
2988 /*  OUTPUT                                                                */
2989 /*                                                                        */
2990 /*    status                                Completion status             */
2991 /*                                                                        */
2992 /*  CALLS                                                                 */
2993 /*                                                                        */
2994 /*    _nx_dns_host_cname_get                Actual DNS host cname         */
2995 /*                                          lookup by host name service   */
2996 /*                                                                        */
2997 /*  CALLED BY                                                             */
2998 /*                                                                        */
2999 /*    Application Code                                                    */
3000 /*                                                                        */
3001 /*  RELEASE HISTORY                                                       */
3002 /*                                                                        */
3003 /*    DATE              NAME                      DESCRIPTION             */
3004 /*                                                                        */
3005 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3006 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3007 /*                                            resulting in version 6.1    */
3008 /*                                                                        */
3009 /**************************************************************************/
_nxe_dns_cname_get(NX_DNS * dns_ptr,UCHAR * host_name,UCHAR * record_buffer,UINT buffer_size,ULONG wait_option)3010 UINT  _nxe_dns_cname_get(NX_DNS *dns_ptr, UCHAR *host_name,  UCHAR *record_buffer,
3011                          UINT buffer_size, ULONG wait_option)
3012 {
3013 
3014 UINT    status;
3015 
3016     /* Check for invalid input pointers.  */
3017     if (!dns_ptr || !host_name || !record_buffer)
3018         return(NX_PTR_ERROR);
3019 
3020     /* Check for invalid non pointer input. */
3021     if (dns_ptr -> nx_dns_id != NX_DNS_ID)
3022     {
3023         return(NX_DNS_PARAM_ERROR);
3024     }
3025 
3026     /* Check for appropriate caller.  */
3027     NX_THREADS_ONLY_CALLER_CHECKING
3028 
3029     /* Call actual DNS get host by name service.  */
3030     status =  _nx_dns_cname_get(dns_ptr, host_name, record_buffer, buffer_size, wait_option);
3031 
3032     /* Return status.  */
3033     return(status);
3034 }
3035 #endif
3036 
3037 
3038 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
3039 /**************************************************************************/
3040 /*                                                                        */
3041 /*  FUNCTION                                               RELEASE        */
3042 /*                                                                        */
3043 /*    _nx_dns_cname_get                                   PORTABLE C      */
3044 /*                                                           6.1          */
3045 /*  AUTHOR                                                                */
3046 /*                                                                        */
3047 /*    Yuxin Zhou, Microsoft Corporation                                   */
3048 /*                                                                        */
3049 /*  DESCRIPTION                                                           */
3050 /*                                                                        */
3051 /*    This function uses DNS to get the host cname associated with        */
3052 /*    the specified host name. If host cname cannot be found, this        */
3053 /*    routine returns zero for the string size to signal an error.        */
3054 /*                                                                        */
3055 /*  INPUT                                                                 */
3056 /*                                                                        */
3057 /*    dns_ptr                              Pointer to DNS instance        */
3058 /*    host_name                            Name of host to resolve        */
3059 /*    record_buffer                        Buffer space for storing       */
3060 /*                                           cname response.              */
3061 /*    buffer_size                          Size of record_buffer          */
3062 /*    wait_option                          Timeout value                  */
3063 /*                                                                        */
3064 /*  OUTPUT                                                                */
3065 /*                                                                        */
3066 /*    status                                Completion status             */
3067 /*                                                                        */
3068 /*  CALLS                                                                 */
3069 /*                                                                        */
3070 /*    _nx_dns_host_resource_data_by_name_get                              */
3071 /*                                        Actual DNS get host cname       */
3072 /*                                             by name service            */
3073 /*                                                                        */
3074 /*  CALLED BY                                                             */
3075 /*                                                                        */
3076 /*    Application Code                                                    */
3077 /*                                                                        */
3078 /*  RELEASE HISTORY                                                       */
3079 /*                                                                        */
3080 /*    DATE              NAME                      DESCRIPTION             */
3081 /*                                                                        */
3082 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3083 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3084 /*                                            resulting in version 6.1    */
3085 /*                                                                        */
3086 /**************************************************************************/
_nx_dns_cname_get(NX_DNS * dns_ptr,UCHAR * host_name,UCHAR * record_buffer,UINT buffer_size,ULONG wait_option)3087 UINT  _nx_dns_cname_get(NX_DNS *dns_ptr, UCHAR *host_name, UCHAR *record_buffer,
3088                         UINT buffer_size, ULONG wait_option)
3089 {
3090 
3091 UINT        status;
3092 UINT        record_count = 0;
3093 
3094     /* Invoke the real connection call. */
3095     status = _nx_dns_host_resource_data_by_name_get(dns_ptr, host_name, record_buffer, buffer_size,
3096                                                     &record_count, NX_DNS_RR_TYPE_CNAME, wait_option);
3097 
3098     /* Return completion status. */
3099     return status;
3100 }
3101 #endif
3102 
3103 
3104 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
3105 /**************************************************************************/
3106 /*                                                                        */
3107 /*  FUNCTION                                               RELEASE        */
3108 /*                                                                        */
3109 /*    _nxe_dns_domain_name_server_get                     PORTABLE C      */
3110 /*                                                           6.1          */
3111 /*  AUTHOR                                                                */
3112 /*                                                                        */
3113 /*    Yuxin Zhou, Microsoft Corporation                                   */
3114 /*                                                                        */
3115 /*  DESCRIPTION                                                           */
3116 /*                                                                        */
3117 /*    This function checks for errors in the DNS look up the authoritative*/
3118 /*    name servers in a given domain.                                     */
3119 /*                                                                        */
3120 /*  INPUT                                                                 */
3121 /*                                                                        */
3122 /*    dns_ptr                              Pointer to DNS instance        */
3123 /*    host_name                            Name of host to search on      */
3124 /*    record_buffer                        Buffer space for storing       */
3125 /*                                           the data structure that      */
3126 /*                                           holds name server information*/
3127 /*    buffer_size                          Size of the record_buffer      */
3128 /*    record_count                         The number of records stored   */
3129 /*                                           in the record_buffer         */
3130 /*    wait_option                          Time to wait on server response*/
3131 /*                                                                        */
3132 /*  OUTPUT                                                                */
3133 /*                                                                        */
3134 /*    status                               Completion status              */
3135 /*                                                                        */
3136 /*  CALLS                                                                 */
3137 /*                                                                        */
3138 /*    _nx_dns_domain_name_server_get       Actual DNS host NS             */
3139 /*                                           lookup by host name service  */
3140 /*                                                                        */
3141 /*  CALLED BY                                                             */
3142 /*                                                                        */
3143 /*    Application Code                                                    */
3144 /*                                                                        */
3145 /*  RELEASE HISTORY                                                       */
3146 /*                                                                        */
3147 /*    DATE              NAME                      DESCRIPTION             */
3148 /*                                                                        */
3149 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3150 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3151 /*                                            resulting in version 6.1    */
3152 /*                                                                        */
3153 /**************************************************************************/
_nxe_dns_domain_name_server_get(NX_DNS * dns_ptr,UCHAR * host_name,VOID * record_buffer,UINT buffer_size,UINT * record_count,ULONG wait_option)3154 UINT  _nxe_dns_domain_name_server_get(NX_DNS *dns_ptr, UCHAR *host_name,  VOID *record_buffer,
3155                                       UINT buffer_size, UINT *record_count, ULONG wait_option)
3156 {
3157 
3158 UINT    status;
3159 
3160     /* Check for invalid input pointers.  */
3161     if ((!dns_ptr) || (!host_name) || (!record_buffer) || (!record_count))
3162         return(NX_PTR_ERROR);
3163 
3164     /* Check for invalid non pointer input. */
3165     if (dns_ptr -> nx_dns_id != NX_DNS_ID)
3166     {
3167         return(NX_DNS_PARAM_ERROR);
3168     }
3169 
3170     /* Make sure record_buffer is 4-byte aligned. */
3171     if(((ALIGN_TYPE)record_buffer & 0x3) != 0)
3172     {
3173         return(NX_PTR_ERROR);
3174     }
3175 
3176     /* Check for appropriate caller.  */
3177     NX_THREADS_ONLY_CALLER_CHECKING
3178 
3179     /* Call actual DNS get the authoritative name server by name service.  */
3180     status =  _nx_dns_domain_name_server_get(dns_ptr, host_name, record_buffer, buffer_size, record_count, wait_option);
3181 
3182     /* Return status.  */
3183     return(status);
3184 }
3185 #endif
3186 
3187 
3188 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
3189 /**************************************************************************/
3190 /*                                                                        */
3191 /*  FUNCTION                                               RELEASE        */
3192 /*                                                                        */
3193 /*    _nx_dns_domain_name_server_get                      PORTABLE C      */
3194 /*                                                           6.1          */
3195 /*  AUTHOR                                                                */
3196 /*                                                                        */
3197 /*    Yuxin Zhou, Microsoft Corporation                                   */
3198 /*                                                                        */
3199 /*  DESCRIPTION                                                           */
3200 /*                                                                        */
3201 /*    This function uses DNS to get the authoritative name server         */
3202 /*    associated with the specified host name. If host cname cannot       */
3203 /*    be found, this routine returns zero for the string size to          */
3204 /*    signal an error.                                                    */
3205 /*                                                                        */
3206 /*  INPUT                                                                 */
3207 /*                                                                        */
3208 /*    dns_ptr                              Pointer to DNS instance        */
3209 /*    host_name                            Name of host to search on      */
3210 /*    record_buffer                        Buffer space for storing       */
3211 /*                                           the data structure that      */
3212 /*                                           holds name server information*/
3213 /*    buffer_size                          Size of the record_buffer      */
3214 /*    record_count                         The number of records stored   */
3215 /*                                           in the record_buffer         */
3216 /*    wait_option                          Timeout value                  */
3217 /*                                                                        */
3218 /*  OUTPUT                                                                */
3219 /*                                                                        */
3220 /*    status                                Completion status             */
3221 /*                                                                        */
3222 /*  CALLS                                                                 */
3223 /*                                                                        */
3224 /*    _nx_dns_host_resource_data_by_name_get                              */
3225 /*                                          Actual DNS get the            */
3226 /*                                          authoritaive name server      */
3227 /*                                            by name service             */
3228 /*                                                                        */
3229 /*  CALLED BY                                                             */
3230 /*                                                                        */
3231 /*    Application Code                                                    */
3232 /*                                                                        */
3233 /*  RELEASE HISTORY                                                       */
3234 /*                                                                        */
3235 /*    DATE              NAME                      DESCRIPTION             */
3236 /*                                                                        */
3237 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3238 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3239 /*                                            resulting in version 6.1    */
3240 /*                                                                        */
3241 /**************************************************************************/
_nx_dns_domain_name_server_get(NX_DNS * dns_ptr,UCHAR * host_name,VOID * record_buffer,UINT buffer_size,UINT * record_count,ULONG wait_option)3242 UINT  _nx_dns_domain_name_server_get(NX_DNS *dns_ptr, UCHAR *host_name, VOID *record_buffer,
3243                                      UINT buffer_size, UINT *record_count, ULONG wait_option)
3244 {
3245 
3246 UINT        status;
3247 
3248     /* Invoke the real connection call. */
3249     status = _nx_dns_host_resource_data_by_name_get(dns_ptr, host_name, record_buffer, buffer_size, record_count, NX_DNS_RR_TYPE_NS, wait_option);
3250 
3251     /* Return completion status. */
3252     return status;
3253 }
3254 #endif
3255 
3256 
3257 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
3258 /**************************************************************************/
3259 /*                                                                        */
3260 /*  FUNCTION                                               RELEASE        */
3261 /*                                                                        */
3262 /*    _nxe_dns_host_text_get                              PORTABLE C      */
3263 /*                                                           6.1          */
3264 /*  AUTHOR                                                                */
3265 /*                                                                        */
3266 /*    Yuxin Zhou, Microsoft Corporation                                   */
3267 /*                                                                        */
3268 /*  DESCRIPTION                                                           */
3269 /*                                                                        */
3270 /*    This function checks for errors in the DNS look up the text strings */
3271 /*    by name service.                                                    */
3272 /*                                                                        */
3273 /*  INPUT                                                                 */
3274 /*                                                                        */
3275 /*    dns_ptr                              Pointer to DNS instance        */
3276 /*    host_name                            Name of host to search on      */
3277 /*    record_buffer                        Buffer space for storing       */
3278 /*                                           the host text string         */
3279 /*    buffer_size                          Size of record_buffer.         */
3280 /*    wait_option                          Time to wait on server response*/
3281 /*                                                                        */
3282 /*  OUTPUT                                                                */
3283 /*                                                                        */
3284 /*    status                                Completion status             */
3285 /*                                                                        */
3286 /*  CALLS                                                                 */
3287 /*    _nx_dns_host_text_get                  Actual DNS host text strings */
3288 /*                                          lookup by host name service   */
3289 /*                                                                        */
3290 /*  CALLED BY                                                             */
3291 /*                                                                        */
3292 /*    Application Code                                                    */
3293 /*                                                                        */
3294 /*  RELEASE HISTORY                                                       */
3295 /*                                                                        */
3296 /*    DATE              NAME                      DESCRIPTION             */
3297 /*                                                                        */
3298 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3299 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3300 /*                                            resulting in version 6.1    */
3301 /*                                                                        */
3302 /**************************************************************************/
_nxe_dns_host_text_get(NX_DNS * dns_ptr,UCHAR * host_name,UCHAR * record_buffer,UINT buffer_size,ULONG wait_option)3303 UINT  _nxe_dns_host_text_get(NX_DNS *dns_ptr, UCHAR *host_name,  UCHAR *record_buffer,
3304                              UINT buffer_size, ULONG wait_option)
3305 {
3306 
3307 UINT    status;
3308 
3309     /* Check for invalid input pointers.  */
3310     if (!dns_ptr || !host_name || !record_buffer)
3311         return(NX_PTR_ERROR);
3312 
3313     /* Check for invalid non pointer input. */
3314     if (dns_ptr -> nx_dns_id != NX_DNS_ID)
3315     {
3316         return(NX_DNS_PARAM_ERROR);
3317     }
3318 
3319     /* Check for appropriate caller.  */
3320     NX_THREADS_ONLY_CALLER_CHECKING
3321 
3322     /* Call actual DNS get the text strings by name service.  */
3323     status =  _nx_dns_host_text_get(dns_ptr, host_name, record_buffer, buffer_size, wait_option);
3324 
3325     /* Return status.  */
3326     return(status);
3327 }
3328 #endif
3329 
3330 
3331 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
3332 /**************************************************************************/
3333 /*                                                                        */
3334 /*  FUNCTION                                               RELEASE        */
3335 /*                                                                        */
3336 /*    _nx_dns_host_text_get                               PORTABLE C      */
3337 /*                                                           6.1          */
3338 /*  AUTHOR                                                                */
3339 /*                                                                        */
3340 /*    Yuxin Zhou, Microsoft Corporation                                   */
3341 /*                                                                        */
3342 /*  DESCRIPTION                                                           */
3343 /*                                                                        */
3344 /*    This function uses DNS to get the text strings associated with      */
3345 /*    the specified host name. If host cname cannot be found,             */
3346 /*    this routine returns zero for the string size to  signal an error.  */
3347 /*                                                                        */
3348 /*  INPUT                                                                 */
3349 /*                                                                        */
3350 /*    dns_ptr                              Pointer to DNS instance        */
3351 /*    host_name                            Name of host to resolve        */
3352 /*    record_buffer                        Buffer space for storing       */
3353 /*                                           the host text string         */
3354 /*    buffer_size                          Size of record_buffer.         */
3355 /*    wait_option                          Timeout value                  */
3356 /*                                                                        */
3357 /*  OUTPUT                                                                */
3358 /*                                                                        */
3359 /*    status                                Completion status             */
3360 /*                                                                        */
3361 /*  CALLS                                                                 */
3362 /*                                                                        */
3363 /*    _nx_dns_host_resource_data_by_name_get                              */
3364 /*                                         Actual DNS get the text        */
3365 /*                                         strings by name service        */
3366 /*                                                                        */
3367 /*  CALLED BY                                                             */
3368 /*                                                                        */
3369 /*    Application Code                                                    */
3370 /*                                                                        */
3371 /*  RELEASE HISTORY                                                       */
3372 /*                                                                        */
3373 /*    DATE              NAME                      DESCRIPTION             */
3374 /*                                                                        */
3375 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3376 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3377 /*                                            resulting in version 6.1    */
3378 /*                                                                        */
3379 /**************************************************************************/
_nx_dns_host_text_get(NX_DNS * dns_ptr,UCHAR * host_name,UCHAR * record_buffer,UINT buffer_size,ULONG wait_option)3380 UINT  _nx_dns_host_text_get(NX_DNS *dns_ptr, UCHAR *host_name, UCHAR *record_buffer,
3381                             UINT buffer_size, ULONG wait_option)
3382 {
3383 
3384 UINT        status;
3385 UINT        record_count = 0;
3386 
3387     /* Invoke the real connection call. */
3388     status = _nx_dns_host_resource_data_by_name_get(dns_ptr, host_name, record_buffer, buffer_size, &record_count, NX_DNS_RR_TYPE_TXT, wait_option);
3389 
3390     /* Return completion status. */
3391     return status;
3392 }
3393 #endif
3394 
3395 
3396 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
3397 /**************************************************************************/
3398 /*                                                                        */
3399 /*  FUNCTION                                               RELEASE        */
3400 /*                                                                        */
3401 /*    _nxe_dns_domain_mail_exchange_get                   PORTABLE C      */
3402 /*                                                           6.1          */
3403 /*  AUTHOR                                                                */
3404 /*                                                                        */
3405 /*    Yuxin Zhou, Microsoft Corporation                                   */
3406 /*                                                                        */
3407 /*  DESCRIPTION                                                           */
3408 /*                                                                        */
3409 /*    This function checks for errors in the DNS look up the mail         */
3410 /*    exchange by name service.                                           */
3411 /*                                                                        */
3412 /*  INPUT                                                                 */
3413 /*                                                                        */
3414 /*    dns_ptr                              Pointer to DNS instance        */
3415 /*    host_name                            Name of host to search on      */
3416 /*    record_buffer                        Buffer space for recording     */
3417 /*                                           data structure that holds    */
3418 /*                                           the mail exchange information*/
3419 /*    buffer_size                          Size of record_buffer.         */
3420 /*    record_count                         The count of mail exchange     */
3421 /*    wait_option                          Time to wait on server response*/
3422 /*                                                                        */
3423 /*  OUTPUT                                                                */
3424 /*                                                                        */
3425 /*    status                                Completion status             */
3426 /*                                                                        */
3427 /*  CALLS                                                                 */
3428 /*                                                                        */
3429 /*    _nx_dns_domain_mail_exchange_get                                    */
3430 /*                                          Actual DNS host MX lookup     */
3431 /*                                           by host name service   */
3432 /*                                                                        */
3433 /*  CALLED BY                                                             */
3434 /*                                                                        */
3435 /*    Application Code                                                    */
3436 /*                                                                        */
3437 /*  RELEASE HISTORY                                                       */
3438 /*                                                                        */
3439 /*    DATE              NAME                      DESCRIPTION             */
3440 /*                                                                        */
3441 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3442 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3443 /*                                            resulting in version 6.1    */
3444 /*                                                                        */
3445 /**************************************************************************/
_nxe_dns_domain_mail_exchange_get(NX_DNS * dns_ptr,UCHAR * host_name,VOID * record_buffer,UINT buffer_size,UINT * record_count,ULONG wait_option)3446 UINT  _nxe_dns_domain_mail_exchange_get(NX_DNS *dns_ptr, UCHAR *host_name,  VOID *record_buffer,
3447                                         UINT buffer_size, UINT *record_count, ULONG wait_option)
3448 {
3449 
3450 UINT    status;
3451 
3452     /* Check for invalid input pointers.  */
3453     if ((!dns_ptr) || (!host_name) || (!record_buffer) || (!record_count))
3454         return(NX_PTR_ERROR);
3455 
3456     /* Check for invalid non pointer input. */
3457     if (dns_ptr -> nx_dns_id != NX_DNS_ID)
3458     {
3459         return(NX_DNS_PARAM_ERROR);
3460     }
3461 
3462     /* Make sure record_buffer is 4-byte aligned. */
3463     if(((ALIGN_TYPE)record_buffer & 0x3) != 0)
3464     {
3465         return(NX_PTR_ERROR);
3466     }
3467 
3468     /* Check for appropriate caller.  */
3469     NX_THREADS_ONLY_CALLER_CHECKING
3470 
3471     /* Call actual DNS get the mail exchange by name service.  */
3472     status =  _nx_dns_domain_mail_exchange_get(dns_ptr, host_name, record_buffer, buffer_size, record_count, wait_option);
3473 
3474     /* Return status.  */
3475     return(status);
3476 }
3477 #endif
3478 
3479 
3480 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
3481 /**************************************************************************/
3482 /*                                                                        */
3483 /*  FUNCTION                                               RELEASE        */
3484 /*                                                                        */
3485 /*    _nx_dns_domain_mail_exchange_get                    PORTABLE C      */
3486 /*                                                           6.1          */
3487 /*  AUTHOR                                                                */
3488 /*                                                                        */
3489 /*    Yuxin Zhou, Microsoft Corporation                                   */
3490 /*                                                                        */
3491 /*  DESCRIPTION                                                           */
3492 /*                                                                        */
3493 /*    This function uses DNS to get the mail exchange associated with     */
3494 /*    the specified host name. If host cname cannot be found,             */
3495 /*    this routine returns zero for the string size to signal an error.   */
3496 /*                                                                        */
3497 /*  INPUT                                                                 */
3498 /*                                                                        */
3499 /*    dns_ptr                              Pointer to DNS instance        */
3500 /*    host_name                            Name of host to resolve        */
3501 /*    record_buffer                        Buffer space for recording     */
3502 /*                                           data structure that holds    */
3503 /*                                           the mail exchange information*/
3504 /*    buffer_size                          Size of record_buffer.         */
3505 /*    record_count                         The count of mail exchange     */
3506 /*    wait_option                          Timeout value                  */
3507 /*                                                                        */
3508 /*  OUTPUT                                                                */
3509 /*                                                                        */
3510 /*    status                                Completion status             */
3511 /*                                                                        */
3512 /*  CALLS                                                                 */
3513 /*                                                                        */
3514 /*    _nx_dns_host_resource_data_get                                      */
3515 /*                                          Actual DNS get the mail       */
3516 /*                                           exchange by name service     */
3517 /*                                                                        */
3518 /*                                                                        */
3519 /*  CALLED BY                                                             */
3520 /*                                                                        */
3521 /*    Application Code                                                    */
3522 /*                                                                        */
3523 /*  RELEASE HISTORY                                                       */
3524 /*                                                                        */
3525 /*    DATE              NAME                      DESCRIPTION             */
3526 /*                                                                        */
3527 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3528 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3529 /*                                            resulting in version 6.1    */
3530 /*                                                                        */
3531 /**************************************************************************/
_nx_dns_domain_mail_exchange_get(NX_DNS * dns_ptr,UCHAR * host_name,VOID * record_buffer,UINT buffer_size,UINT * record_count,ULONG wait_option)3532 UINT  _nx_dns_domain_mail_exchange_get(NX_DNS *dns_ptr, UCHAR *host_name, VOID *record_buffer,
3533                                        UINT buffer_size, UINT *record_count, ULONG wait_option)
3534 {
3535 
3536 UINT        status;
3537 
3538     /* Invoke the real connection call. */
3539     status = _nx_dns_host_resource_data_by_name_get(dns_ptr, host_name, record_buffer, buffer_size,
3540                                                     record_count, NX_DNS_RR_TYPE_MX, wait_option);
3541 
3542     /* Return completion status. */
3543     return status;
3544 }
3545 #endif
3546 
3547 
3548 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
3549 /**************************************************************************/
3550 /*                                                                        */
3551 /*  FUNCTION                                               RELEASE        */
3552 /*                                                                        */
3553 /*    _nxe_dns_domain_service_get                         PORTABLE C      */
3554 /*                                                           6.1          */
3555 /*  AUTHOR                                                                */
3556 /*                                                                        */
3557 /*    Yuxin Zhou, Microsoft Corporation                                   */
3558 /*                                                                        */
3559 /*  DESCRIPTION                                                           */
3560 /*                                                                        */
3561 /*    This function checks for errors in the DNS look up the service      */
3562 /*    by name service.                                                    */
3563 /*                                                                        */
3564 /*  INPUT                                                                 */
3565 /*                                                                        */
3566 /*    dns_ptr                              Pointer to DNS instance        */
3567 /*    host_name                            Name of host to search on      */
3568 /*    record_buffer                        Buffer space for storing the   */
3569 /*                                           the data structures that     */
3570 /*                                           hold the service information */
3571 /*    buffer_size                          size of record_buffer          */
3572 /*    record_count                         The count of services stored   */
3573 /*                                           in record_buffer             */
3574 /*    wait_option                          Time to wait on server response*/
3575 /*                                                                        */
3576 /*  OUTPUT                                                                */
3577 /*                                                                        */
3578 /*    status                                Completion status             */
3579 /*                                                                        */
3580 /*  CALLS                                                                 */
3581 /*                                                                        */
3582 /*    _nx_dns_domain_service_get                                          */
3583 /*                                          Actual DNS host SRV           */
3584 /*                                          lookup by host name service   */
3585 /*                                                                        */
3586 /*  CALLED BY                                                             */
3587 /*                                                                        */
3588 /*    Application Code                                                    */
3589 /*                                                                        */
3590 /*  RELEASE HISTORY                                                       */
3591 /*                                                                        */
3592 /*    DATE              NAME                      DESCRIPTION             */
3593 /*                                                                        */
3594 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3595 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3596 /*                                            resulting in version 6.1    */
3597 /*                                                                        */
3598 /**************************************************************************/
_nxe_dns_domain_service_get(NX_DNS * dns_ptr,UCHAR * host_name,VOID * record_buffer,UINT buffer_size,UINT * record_count,ULONG wait_option)3599 UINT  _nxe_dns_domain_service_get(NX_DNS *dns_ptr, UCHAR *host_name,  VOID *record_buffer,
3600                                   UINT buffer_size, UINT *record_count, ULONG wait_option)
3601 {
3602 
3603 UINT    status;
3604 
3605     /* Check for invalid input pointers.  */
3606     if ((!dns_ptr) || (!host_name) || (!record_buffer) || (!record_count))
3607         return(NX_PTR_ERROR);
3608 
3609     /* Check for invalid non pointer input. */
3610     if (dns_ptr -> nx_dns_id != NX_DNS_ID)
3611     {
3612         return(NX_DNS_PARAM_ERROR);
3613     }
3614 
3615     /* Make sure record_buffer is 4-byte aligned. */
3616     if(((ALIGN_TYPE)record_buffer & 0x3) != 0)
3617     {
3618         return(NX_PTR_ERROR);
3619     }
3620 
3621     /* Check for appropriate caller.  */
3622     NX_THREADS_ONLY_CALLER_CHECKING
3623 
3624     /* Call actual DNS get the service by name service.  */
3625     status =  _nx_dns_domain_service_get(dns_ptr, host_name, record_buffer, buffer_size, record_count, wait_option);
3626 
3627     /* Return status.  */
3628     return(status);
3629 }
3630 #endif
3631 
3632 
3633 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
3634 /**************************************************************************/
3635 /*                                                                        */
3636 /*  FUNCTION                                               RELEASE        */
3637 /*                                                                        */
3638 /*    _nx_dns_domain_service_get                          PORTABLE C      */
3639 /*                                                           6.1          */
3640 /*  AUTHOR                                                                */
3641 /*                                                                        */
3642 /*    Yuxin Zhou, Microsoft Corporation                                   */
3643 /*                                                                        */
3644 /*  DESCRIPTION                                                           */
3645 /*                                                                        */
3646 /*    This function uses DNS to get the service associated with           */
3647 /*    the specified host name. If host cname cannot be found,             */
3648 /*    this routine returns zero for the string size to signal an error.   */
3649 /*                                                                        */
3650 /*  INPUT                                                                 */
3651 /*                                                                        */
3652 /*    dns_ptr                               Pointer to DNS instance       */
3653 /*    host_name                             Name of host to resolve       */
3654 /*    record_buffer                        Buffer space for storing the   */
3655 /*                                           the data structures that     */
3656 /*                                           hold the service information */
3657 /*    buffer_size                          size of record_buffer          */
3658 /*    record_count                         The count of services stored   */
3659 /*                                           in record_buffer             */
3660 /*    wait_option                           Timeout value                 */
3661 /*                                                                        */
3662 /*  OUTPUT                                                                */
3663 /*                                                                        */
3664 /*    status                                Completion status             */
3665 /*                                                                        */
3666 /*  CALLS                                                                 */
3667 /*                                                                        */
3668 /*    _nx_dns_host_resource_data_by_name_get                              */
3669 /*                                          Route that sends out the      */
3670 /*                                          query and process response.   */
3671 /*                                                                        */
3672 /*                                                                        */
3673 /*  CALLED BY                                                             */
3674 /*                                                                        */
3675 /*    Application Code                                                    */
3676 /*                                                                        */
3677 /*  RELEASE HISTORY                                                       */
3678 /*                                                                        */
3679 /*    DATE              NAME                      DESCRIPTION             */
3680 /*                                                                        */
3681 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3682 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3683 /*                                            resulting in version 6.1    */
3684 /*                                                                        */
3685 /**************************************************************************/
_nx_dns_domain_service_get(NX_DNS * dns_ptr,UCHAR * host_name,VOID * record_buffer,UINT buffer_size,UINT * record_count,ULONG wait_option)3686 UINT  _nx_dns_domain_service_get(NX_DNS *dns_ptr, UCHAR *host_name, VOID *record_buffer,
3687                                  UINT buffer_size, UINT *record_count, ULONG wait_option)
3688 {
3689 
3690 UINT        status;
3691 
3692     /* Invoke the real connection call. */
3693     status = _nx_dns_host_resource_data_by_name_get(dns_ptr, host_name, record_buffer, buffer_size,
3694                                                     record_count, NX_DNS_RR_TYPE_SRV, wait_option);
3695 
3696     /* Return completion status. */
3697     return status;
3698 }
3699 #endif
3700 
3701 
3702 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
3703 /**************************************************************************/
3704 /*                                                                        */
3705 /*  FUNCTION                                               RELEASE        */
3706 /*                                                                        */
3707 /*    _nxe_dns_authority_zone_start_get                   PORTABLE C      */
3708 /*                                                           6.1          */
3709 /*  AUTHOR                                                                */
3710 /*                                                                        */
3711 /*    Yuxin Zhou, Microsoft Corporation                                   */
3712 /*                                                                        */
3713 /*  DESCRIPTION                                                           */
3714 /*                                                                        */
3715 /*    This function checks for errors in the DNS look up the start of     */
3716 /*    a zone of authority by name service.                                */
3717 /*                                                                        */
3718 /*  INPUT                                                                 */
3719 /*                                                                        */
3720 /*    dns_ptr                              Pointer to DNS instance        */
3721 /*    host_name                            Name of host to search on      */
3722 /*    record_buffer                        Buffer space for storing       */
3723 /*                                           the data structures that     */
3724 /*                                           hold the SOA information     */
3725 /*    buffer_size                          Size of record_buffer.         */
3726 /*    wait_option                          Time to wait on server response*/
3727 /*                                                                        */
3728 /*  OUTPUT                                                                */
3729 /*                                                                        */
3730 /*    status                                Completion status             */
3731 /*                                                                        */
3732 /*  CALLS                                                                 */
3733 /*    _nx_dns_authority_zone_start_get       Actual DNS host text strings */
3734 /*                                          lookup by host name service   */
3735 /*                                                                        */
3736 /*  CALLED BY                                                             */
3737 /*                                                                        */
3738 /*    Application Code                                                    */
3739 /*                                                                        */
3740 /*  RELEASE HISTORY                                                       */
3741 /*                                                                        */
3742 /*    DATE              NAME                      DESCRIPTION             */
3743 /*                                                                        */
3744 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3745 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3746 /*                                            resulting in version 6.1    */
3747 /*                                                                        */
3748 /**************************************************************************/
_nxe_dns_authority_zone_start_get(NX_DNS * dns_ptr,UCHAR * host_name,UCHAR * record_buffer,UINT buffer_size,ULONG wait_option)3749 UINT  _nxe_dns_authority_zone_start_get(NX_DNS *dns_ptr, UCHAR *host_name,  UCHAR *record_buffer,
3750                                         UINT buffer_size, ULONG wait_option)
3751 {
3752 
3753 UINT    status;
3754 
3755     /* Check for invalid input pointers.  */
3756     if (!dns_ptr || !host_name || !record_buffer)
3757         return(NX_PTR_ERROR);
3758 
3759     /* Check for invalid non pointer input. */
3760     if (dns_ptr -> nx_dns_id != NX_DNS_ID)
3761     {
3762         return(NX_DNS_PARAM_ERROR);
3763     }
3764 
3765     /* Make sure record_buffer is 4-byte aligned. */
3766     if(((ALIGN_TYPE)record_buffer & 0x3) != 0)
3767     {
3768         return(NX_PTR_ERROR);
3769     }
3770 
3771     /* Check for appropriate caller.  */
3772     NX_THREADS_ONLY_CALLER_CHECKING
3773 
3774     /* Call actual DNS get the start of zone authority by name service.  */
3775     status =  _nx_dns_authority_zone_start_get(dns_ptr, host_name, record_buffer, buffer_size, wait_option);
3776 
3777     /* Return status.  */
3778     return(status);
3779 }
3780 #endif
3781 
3782 
3783 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
3784 /**************************************************************************/
3785 /*                                                                        */
3786 /*  FUNCTION                                               RELEASE        */
3787 /*                                                                        */
3788 /*    _nx_dns_authority_zone_start_get                    PORTABLE C      */
3789 /*                                                           6.1          */
3790 /*  AUTHOR                                                                */
3791 /*                                                                        */
3792 /*    Yuxin Zhou, Microsoft Corporation                                   */
3793 /*                                                                        */
3794 /*  DESCRIPTION                                                           */
3795 /*                                                                        */
3796 /*    This function uses DNS to get the start of a zone of authority      */
3797 /*    associated with the specified host name. If it cannot be found,     */
3798 /*    this routine returns zero for the string size to signal an error.   */
3799 /*                                                                        */
3800 /*  INPUT                                                                 */
3801 /*                                                                        */
3802 /*    dns_ptr                              Pointer to DNS instance        */
3803 /*    host_name                            Name of host to resolve        */
3804 /*    record_buffer                        Buffer space for storing       */
3805 /*                                           the data structures that     */
3806 /*                                           hold the SOA information     */
3807 /*    buffer_size                          Size of record_buffer.         */
3808 /*    wait_option                          Timeout value                  */
3809 /*                                                                        */
3810 /*  OUTPUT                                                                */
3811 /*                                                                        */
3812 /*    status                                Completion status             */
3813 /*                                                                        */
3814 /*  CALLS                                                                 */
3815 /*                                                                        */
3816 /*    _nx_dns_host_resource_data_by_name_get                              */
3817 /*                                         Actual DNS get the authority   */
3818 /*                                         zone by name service           */
3819 /*                                                                        */
3820 /*  CALLED BY                                                             */
3821 /*                                                                        */
3822 /*    Application Code                                                    */
3823 /*                                                                        */
3824 /*  RELEASE HISTORY                                                       */
3825 /*                                                                        */
3826 /*    DATE              NAME                      DESCRIPTION             */
3827 /*                                                                        */
3828 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3829 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3830 /*                                            resulting in version 6.1    */
3831 /*                                                                        */
3832 /**************************************************************************/
_nx_dns_authority_zone_start_get(NX_DNS * dns_ptr,UCHAR * host_name,UCHAR * record_buffer,UINT buffer_size,ULONG wait_option)3833 UINT  _nx_dns_authority_zone_start_get(NX_DNS *dns_ptr, UCHAR *host_name, UCHAR *record_buffer,
3834                                        UINT buffer_size, ULONG wait_option)
3835 {
3836 
3837 UINT        status;
3838 UINT        record_count = 0;
3839 
3840     /* Invoke the real connection call. */
3841     status = _nx_dns_host_resource_data_by_name_get(dns_ptr, host_name, record_buffer, buffer_size, &record_count, NX_DNS_RR_TYPE_SOA, wait_option);
3842 
3843     /* Return completion status. */
3844     return status;
3845 }
3846 #endif
3847 
3848 
3849 /**************************************************************************/
3850 /*                                                                        */
3851 /*  FUNCTION                                               RELEASE        */
3852 /*                                                                        */
3853 /*    _nx_dns_host_resource_data_by_name_get               PORTABLE C     */
3854 /*                                                           6.1.5        */
3855 /*  AUTHOR                                                                */
3856 /*                                                                        */
3857 /*    Yuxin Zhou, Microsoft Corporation                                   */
3858 /*                                                                        */
3859 /*  DESCRIPTION                                                           */
3860 /*                                                                        */
3861 /*    This function attempts to find the IP address associated with the   */
3862 /*    specified host name.  If a DNS server responds but does not have    */
3863 /*    the IP address, this function skips to the next server in the       */
3864 /*    DNS client list.  Otherwise it will resend the same query up to the */
3865 /*    DNS client's max retry times before skipping to the next server.    */
3866 /*                                                                        */
3867 /*  INPUT                                                                 */
3868 /*                                                                        */
3869 /*    dns_ptr                               Pointer to DNS instance       */
3870 /*    host_name                             Name of host to resolve       */
3871 /*    record_buffer                         Buffer for record ipv4 address*/
3872 /*    buffer_size                           Buffer size for ipv4 adress   */
3873 /*    record_count                          The count of ipv4 address     */
3874 /*    wait_option                           Timeout value                 */
3875 /*    lookup_type                           Lookup for which IP version   */
3876 /*                                                                        */
3877 /*  OUTPUT                                                                */
3878 /*                                                                        */
3879 /*    status                                Completion status             */
3880 /*                                                                        */
3881 /*  CALLS                                                                 */
3882 /*                                                                        */
3883 /*    _nx_dns_send_query_get_rdata_by_name                                */
3884 /*                                          Creates and transmits a DNS   */
3885 /*                                            query on supplied host name */
3886 /*    tx_mutex_get                          Get DNS protection mutex      */
3887 /*    tx_mutex_put                          Release DNS protection mutex  */
3888 /*    nx_udp_socket_bind                    Bind DNS UDP socket to port   */
3889 /*    nx_udp_socket_unbind                  Unbind DNS UDP socket         */
3890 /*                                                                        */
3891 /*  CALLED BY                                                             */
3892 /*                                                                        */
3893 /*                                                                        */
3894 /*  RELEASE HISTORY                                                       */
3895 /*                                                                        */
3896 /*    DATE              NAME                      DESCRIPTION             */
3897 /*                                                                        */
3898 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3899 /*  09-30-2020     Yuxin Zhou               Modified comment(s), corrected*/
3900 /*                                            the timeout of first query, */
3901 /*                                            resulting in version 6.1    */
3902 /*  02-02-2021     Yuxin Zhou               Modified comment(s), and      */
3903 /*                                            randomized the source port, */
3904 /*                                            resulting in version 6.1.4  */
3905 /*  03-02-2021     Yuxin Zhou               Modified comment(s), and      */
3906 /*                                            improved the logic of       */
3907 /*                                            receiving dns response,     */
3908 /*                                            resulting in version 6.1.5  */
3909 /*                                                                        */
3910 /**************************************************************************/
_nx_dns_host_resource_data_by_name_get(NX_DNS * dns_ptr,UCHAR * host_name,UCHAR * buffer,UINT buffer_size,UINT * record_count,UINT lookup_type,ULONG wait_option)3911 static UINT  _nx_dns_host_resource_data_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name,
3912                                                     UCHAR *buffer, UINT buffer_size,
3913                                                     UINT *record_count, UINT lookup_type, ULONG wait_option)
3914 {
3915 
3916 UINT        status;
3917 UINT        retries;
3918 UINT        i;
3919 
3920 
3921     /* Get the protection mutex to make sure no other thread interferes.  */
3922     status =  tx_mutex_get(&(dns_ptr -> nx_dns_mutex), wait_option);
3923 
3924     /* Check status.  */
3925     if (status != TX_SUCCESS)
3926     {
3927 
3928         /* The mutex was not granted in the time specified.  Return the threadx error.  */
3929         return(status);
3930     }
3931 
3932     /* Clear the record name buffer and record count.  This way
3933       if the query fails, the API returns zero record. */
3934     memset(buffer, 0, buffer_size);
3935 
3936     /* Initialize the record count.  */
3937     *record_count = 0;
3938 
3939 #ifdef NX_DNS_CACHE_ENABLE
3940 
3941     /* Find the answer in local cache.  */
3942     if(_nx_dns_cache_find_answer(dns_ptr, dns_ptr -> nx_dns_cache, host_name, (USHORT)lookup_type, buffer, buffer_size, record_count) == NX_DNS_SUCCESS)
3943     {
3944 
3945         /* Put the DNS mutex.  */
3946         tx_mutex_put(&dns_ptr -> nx_dns_mutex);
3947 
3948         return (NX_DNS_SUCCESS);
3949     }
3950 #endif /*NX_DNS_CACHE_ENABLE.  */
3951 
3952     /* Determine if there is at least one DNS server. Is there anything in the first slot? */
3953     if (dns_ptr -> nx_dns_server_ip_array[0].nxd_ip_version == 0)
3954     {
3955 
3956         /* No, this means the list is empty. Release the DNS Client lock. */
3957         tx_mutex_put(&dns_ptr -> nx_dns_mutex);
3958 
3959         /* At least one DNS server is required - return an error.  */
3960         return(NX_DNS_NO_SERVER);
3961     }
3962 
3963     /* Bind the UDP socket to random port for each query.  */
3964     status =  nx_udp_socket_bind(&(dns_ptr -> nx_dns_socket), NX_ANY_PORT, TX_WAIT_FOREVER);
3965 
3966     /* Check status.  */
3967     if (status != TX_SUCCESS)
3968     {
3969 
3970         /* Release the DNS Client lock.  */
3971         tx_mutex_put(&dns_ptr -> nx_dns_mutex);
3972         return(status);
3973     }
3974 
3975     /* Limit the timeout to NX_DNS_MAX_RETRANS_TIMEOUT.  */
3976     if (wait_option > NX_DNS_MAX_RETRANS_TIMEOUT)
3977     {
3978         wait_option = NX_DNS_MAX_RETRANS_TIMEOUT;
3979     }
3980 
3981     /* Keep sending queries to all DNS Servers till the retry count expires.  */
3982     for (retries = 0; retries < dns_ptr -> nx_dns_retries; retries++)
3983     {
3984 
3985         /* The client should try other servers and server addresses before repeating a query to a specific address of a server.
3986            RFC1035, Section4.2.1 UDP usage, Page32.  */
3987         /*  Attempt host name resolution from each DNS server till one if found. */
3988         for (i = 0; (i < NX_DNS_MAX_SERVERS) && (dns_ptr -> nx_dns_server_ip_array[i].nxd_ip_version != 0); i ++)
3989         {
3990 
3991             /* Send the DNS query. */
3992             status = _nx_dns_send_query_get_rdata_by_name(dns_ptr, &dns_ptr -> nx_dns_server_ip_array[i], host_name,
3993                                                           buffer, buffer_size, record_count, lookup_type, wait_option);
3994 
3995             /* Check the status.  */
3996             if (status == NX_SUCCESS)
3997             {
3998 
3999                 /* Unbind the socket.  */
4000                 nx_udp_socket_unbind(&(dns_ptr -> nx_dns_socket));
4001 
4002                 /* Release the mutex */
4003                 tx_mutex_put(&dns_ptr -> nx_dns_mutex);
4004 
4005                 /* Yes, have done, just return success.  */
4006                 return NX_SUCCESS;
4007             }
4008             else
4009             {
4010 
4011                 /* Let application controls query retransmission for non-blocking.  */
4012                 if (wait_option == NX_NO_WAIT)
4013                 {
4014 
4015                     /* Check if the query is sent out.  */
4016                     if (status == NX_IN_PROGRESS)
4017                     {
4018 
4019                         /* No need to release mutex and unbind the socket for non-blocking since
4020                            _nx_dns_response_get will receive the response and release the resource.  */
4021                         return(status);
4022                     }
4023                     else
4024                     {
4025 
4026                         /* Unbind the socket.  */
4027                         nx_udp_socket_unbind(&(dns_ptr -> nx_dns_socket));
4028 
4029                         /* Release the mutex */
4030                         tx_mutex_put(&dns_ptr -> nx_dns_mutex);
4031 
4032                         return(status);
4033                     }
4034                 }
4035             }
4036         }
4037 
4038         /* Timed out for querying all DNS servers in this cycle, double the timeout, limited to NX_DNS_MAX_RETRANS_TIMEOUT.  */
4039         if (wait_option <= (NX_DNS_MAX_RETRANS_TIMEOUT >> 1))
4040             wait_option =  (wait_option << 1);
4041         else
4042             wait_option =  NX_DNS_MAX_RETRANS_TIMEOUT;
4043     }
4044 
4045     /* Unbind the socket.  */
4046     nx_udp_socket_unbind(&(dns_ptr -> nx_dns_socket));
4047 
4048     /* Release protection.  */
4049     tx_mutex_put(&dns_ptr -> nx_dns_mutex);
4050 
4051     /* Failed on all servers, return DNS lookup failed status.  */
4052     return(NX_DNS_QUERY_FAILED);
4053 }
4054 
4055 
4056 /**************************************************************************/
4057 /*                                                                        */
4058 /*  FUNCTION                                               RELEASE        */
4059 /*                                                                        */
4060 /*    _nx_dns_send_query_by_address                       PORTABLE C      */
4061 /*                                                           6.1.4        */
4062 /*  AUTHOR                                                                */
4063 /*                                                                        */
4064 /*    Yuxin Zhou, Microsoft Corporation                                   */
4065 /*                                                                        */
4066 /*  DESCRIPTION                                                           */
4067 /*                                                                        */
4068 /*    This function uses DNS to get the name of a host from the specified */
4069 /*    IP address associated.  If the IP address cannot be found, this     */
4070 /*    routine returns a NULL host name                    .               */
4071 /*                                                                        */
4072 /*  INPUT                                                                 */
4073 /*                                                                        */
4074 /*    dns_ptr                               Pointer to DNS instance       */
4075 /*    dns_server                            Pointer to DNS server to use  */
4076 /*    ip_question                           Buffer pointer to IP address  */
4077 /*                                               in ascii to lookup       */
4078 /*    host_name_ptr                         Buffer pointer to host name   */
4079 /*    host_name_buffer_size                 Buffer size for host name     */
4080 /*    wait_option                           Timeout value                 */
4081 /*                                                                        */
4082 /*  OUTPUT                                                                */
4083 /*                                                                        */
4084 /*    status                                Completion status             */
4085 /*                                                                        */
4086 /*  CALLS                                                                 */
4087 /*                                                                        */
4088 /*    _nx_dns_name_size_calculate           Calculate size of name field  */
4089 /*    _nx_dns_network_to_long_convert       Convert to unsigned long      */
4090 /*    _nx_dns_network_to_short_convert      Convert to unsigned short     */
4091 /*    _nx_dns_new_packet_create             Create new DNS packet         */
4092 /*    _nx_dns_resource_data_address_get     Get address of data           */
4093 /*    _nx_dns_resource_data_length_get      Get length of resource        */
4094 /*    _nx_dns_resource_type_get             Get resource type             */
4095 /*    nx_packet_copy                        Copy packet                   */
4096 /*    nx_packet_release                     Release packet                */
4097 /*    nx_udp_socket_receive                 Receive DNS UDP packet        */
4098 /*    nxd_udp_socket_send                   Send DNS UDP packet           */
4099 /*                                                                        */
4100 /*  CALLED BY                                                             */
4101 /*                                                                        */
4102 /*    Application Code                                                    */
4103 /*                                                                        */
4104 /*  RELEASE HISTORY                                                       */
4105 /*                                                                        */
4106 /*    DATE              NAME                      DESCRIPTION             */
4107 /*                                                                        */
4108 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4109 /*  09-30-2020     Yuxin Zhou               Modified comment(s), updated  */
4110 /*                                            resource get function and   */
4111 /*                                            status check to improve     */
4112 /*                                            buffer bound check,         */
4113 /*                                            resulting in version 6.1    */
4114 /*  02-02-2021     Yuxin Zhou               Modified comment(s), improved */
4115 /*                                            packet length verification, */
4116 /*                                            improved id generation,     */
4117 /*                                            improved the logic of       */
4118 /*                                            receiving dns response,     */
4119 /*                                            resulting in version 6.1.4  */
4120 /*                                                                        */
4121 /**************************************************************************/
_nx_dns_send_query_by_address(NX_DNS * dns_ptr,NXD_ADDRESS * dns_server,UCHAR * ip_question,UCHAR * host_name_ptr,UINT host_name_buffer_size,ULONG wait_option)4122 static UINT _nx_dns_send_query_by_address(NX_DNS *dns_ptr, NXD_ADDRESS *dns_server, UCHAR *ip_question, UCHAR *host_name_ptr,
4123                                           UINT host_name_buffer_size, ULONG wait_option)
4124 {
4125 
4126 UINT        status;
4127 USHORT      answerCount;
4128 UCHAR       *data_ptr;
4129 NX_PACKET   *packet_ptr;
4130 NX_PACKET   *receive_packet_ptr;
4131 UINT        ip_question_size;
4132 UINT        name_size;
4133 UINT        resource_type;
4134 UINT        resource_size;
4135 #ifdef NX_DNS_CACHE_ENABLE
4136 ULONG       rr_ttl;
4137 #endif /* NX_DNS_CACHE_ENABLE  */
4138 
4139 
4140 
4141     /* Check for IP question.  */
4142     if (_nx_utility_string_length_check((CHAR *)ip_question, &ip_question_size, NX_DNS_IP_LOOKUP_SIZE))
4143     {
4144         return(NX_DNS_SIZE_ERROR);
4145     }
4146 
4147     /* Allocate a packet.  */
4148     status = nx_packet_allocate(dns_ptr -> nx_dns_packet_pool_ptr, &packet_ptr, NX_UDP_PACKET, NX_DNS_PACKET_ALLOCATE_TIMEOUT);
4149 
4150     /* Check the allocate status.  */
4151     if (status != NX_SUCCESS)
4152     {
4153 
4154         /* Return error status.  */
4155         return(status);
4156     }
4157 
4158     /* Create a request */
4159     status  =  _nx_dns_new_packet_create(dns_ptr, packet_ptr, ip_question, NX_DNS_RR_TYPE_PTR);
4160 
4161     /* Check the DNS packet create status.  */
4162     if (status != NX_SUCCESS)
4163     {
4164 
4165         nx_packet_release(packet_ptr);
4166 
4167         /* Return error status.  */
4168         return(status);
4169     }
4170 
4171     /* We will use the time spent sleeping to clear broadcast DNS packets from a previous query
4172        from the DNS receive queue. This will prevent ensure the most recent DNS response is
4173        processed and avoid the situation of valid DNS response packets overflowing the DNS socket
4174        queue. */
4175 #ifdef NX_DNS_CLIENT_CLEAR_QUEUE
4176     do
4177     {
4178 
4179         /* Is there any packets on the queue?  */
4180         status = nx_udp_socket_receive(&(dns_ptr -> nx_dns_socket), &receive_packet_ptr, NX_NO_WAIT);
4181 
4182         /* Yes, we received a packet on the DNS port! */
4183         if (status == NX_SUCCESS)
4184         {
4185 
4186             /* But we don't want it. Release it! */
4187             nx_packet_release(receive_packet_ptr);
4188         }
4189 
4190         /* Keep checking till the queue becomes empty. */
4191     } while(status == NX_SUCCESS);
4192 #endif /* NX_DNS_CLIENT_CLEAR_QUEUE */
4193 
4194     /* Send the DNS packet out.  */
4195     status =  nxd_udp_socket_send(&dns_ptr -> nx_dns_socket, packet_ptr, dns_server, NX_DNS_PORT);
4196 
4197     /* Check the completion of the send.  */
4198     if (status != NX_SUCCESS)
4199     {
4200 
4201         /* Unsuccessful, release the packet.  */
4202         nx_packet_release(packet_ptr);
4203 
4204         return status;
4205     }
4206 
4207     /* Wait for a DNS response.  */
4208     status = _nx_dns_response_receive(dns_ptr, &receive_packet_ptr, wait_option);
4209 
4210     /* Check status.  */
4211     if (status == NX_SUCCESS)
4212     {
4213 
4214 #ifndef NX_DISABLE_PACKET_CHAIN
4215         if (receive_packet_ptr -> nx_packet_next)
4216         {
4217 
4218             /* Chained packet is not supported. */
4219             nx_packet_release(receive_packet_ptr);
4220             return(NX_INVALID_PACKET);
4221         }
4222 #endif /* NX_DISABLE_PACKET_CHAIN */
4223 
4224         /* We received a response. First, check that there is a valid header.  */
4225         if (receive_packet_ptr -> nx_packet_length <= NX_DNS_QDSECT_OFFSET)
4226         {
4227             /* No; Release the new packet.  */
4228             nx_packet_release(receive_packet_ptr);
4229 
4230             /* Return error status. */
4231             return NX_DNS_MALFORMED_PACKET;
4232         }
4233 
4234         /* Packet is long enough. Check the IDs in the DNS header match.  */
4235         if (_nx_dns_network_to_short_convert(receive_packet_ptr -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET) != dns_ptr -> nx_dns_transmit_id)
4236         {
4237 
4238             /* No; Release the packet.  */
4239             nx_packet_release(receive_packet_ptr);
4240 
4241             /* Return error status. */
4242             return NX_DNS_BAD_ID_ERROR;
4243         }
4244 
4245         /* We have a response with matching ID, check that it is a response
4246            and is successful and has a response record.  */
4247         status =  _nx_dns_network_to_short_convert(receive_packet_ptr -> nx_packet_prepend_ptr + NX_DNS_FLAGS_OFFSET);
4248 
4249         /* Check for indication of DNS server error (cannot authenticate answer or authority portion
4250            of the DNS data. */
4251         if ((status & NX_DNS_ERROR_MASK) == NX_DNS_ERROR_MASK)
4252         {
4253 
4254             /* No; Release the packet.  */
4255             nx_packet_release(receive_packet_ptr);
4256 
4257             return NX_DNS_SERVER_AUTH_ERROR;
4258         }
4259 
4260         answerCount = _nx_dns_network_to_short_convert(receive_packet_ptr -> nx_packet_prepend_ptr + NX_DNS_ANCOUNT_OFFSET);
4261 
4262         /* Is it for our question?  */
4263         if (((status & NX_DNS_QUERY_MASK) == NX_DNS_RESPONSE_FLAG)
4264             && ((status & NX_DNS_RCODE_MASK) == NX_DNS_RCODE_SUCCESS)
4265             && (answerCount >= 1))
4266         {
4267 
4268             /* Yes, set a point to the start of the question to find the response record.  */
4269             data_ptr =  receive_packet_ptr -> nx_packet_prepend_ptr + NX_DNS_QDSECT_OFFSET;
4270 
4271             /* Determine if there is a question still in the server's response.  */
4272             if (_nx_dns_network_to_short_convert(receive_packet_ptr -> nx_packet_prepend_ptr + NX_DNS_QDCOUNT_OFFSET) == 1)
4273             {
4274 
4275                 /* Get name size */
4276                 name_size = _nx_dns_name_size_calculate(data_ptr, receive_packet_ptr);
4277 
4278                 if (!name_size)
4279                 {
4280 
4281                     /* Release the packet. */
4282                     nx_packet_release(receive_packet_ptr);
4283 
4284                     /* NULL-terminate the host name string.  */
4285                     *host_name_ptr =  NX_NULL;
4286 
4287                     /* Return an error!  */
4288                     return(NX_DNS_MALFORMED_PACKET);
4289                 }
4290 
4291                 /* Yes, the question is present in the response, skip it!  */
4292                 data_ptr +=  name_size + 4;
4293             }
4294 
4295             /* Check all the response records */
4296             while (answerCount-- > 0)
4297             {
4298 
4299                 /* Check for valid data_ptr.  */
4300                 if (data_ptr >= receive_packet_ptr -> nx_packet_append_ptr)
4301                 {
4302 
4303                     /* Release the packet. */
4304                     nx_packet_release(receive_packet_ptr);
4305 
4306                     /* NULL-terminate the host name string.  */
4307                     *host_name_ptr =  NX_NULL;
4308 
4309                     /* Return an error!  */
4310                     return(NX_DNS_SIZE_ERROR);
4311                 }
4312 
4313                 /* Get resource type. */
4314                 status = _nx_dns_resource_type_get(data_ptr, receive_packet_ptr, &resource_type);
4315                 if (status)
4316                 {
4317                     /* Release the packet. */
4318                     nx_packet_release(receive_packet_ptr);
4319 
4320                     /* NULL-terminate the host name string.  */
4321                     *host_name_ptr =  NX_NULL;
4322 
4323                     /* Return an error!  */
4324                     return(NX_DNS_MALFORMED_PACKET);
4325                 }
4326 
4327                 /* Check that the answer has a name and there is space for it.  */
4328                 if (resource_type == NX_DNS_RR_TYPE_PTR)
4329                 {
4330 
4331 #ifdef NX_DNS_CACHE_ENABLE
4332                     /* Get the resource record ttl.  */
4333                     status = _nx_dns_resource_time_to_live_get(data_ptr, receive_packet_ptr, &rr_ttl);
4334                     if (status)
4335                     {
4336 
4337                         /* Release the packet. */
4338                         nx_packet_release(receive_packet_ptr);
4339 
4340                         /* NULL-terminate the host name string.  */
4341                         *host_name_ptr =  NX_NULL;
4342 
4343                         /* Return an error!  */
4344                         return(NX_DNS_MALFORMED_PACKET);
4345                     }
4346 #endif /* NX_DNS_CACHE_ENABLE  */
4347 
4348                     /* Update the pointer to point at the response data and get the name.  */
4349                     data_ptr = _nx_dns_resource_data_address_get(data_ptr, receive_packet_ptr);
4350                     if (!data_ptr)
4351                     {
4352 
4353                         /* Release the packet. */
4354                         nx_packet_release(receive_packet_ptr);
4355 
4356                         /* NULL-terminate the host name string.  */
4357                         *host_name_ptr =  NX_NULL;
4358 
4359                         /* Return an error!  */
4360                         return(NX_DNS_MALFORMED_PACKET);
4361                     }
4362 
4363                     /* Determine if there is room for the name - one less for NULL termination.  */
4364                     name_size = _nx_dns_name_string_unencode(receive_packet_ptr, data_ptr, host_name_ptr, host_name_buffer_size - 1);
4365                     if (name_size)
4366                     {
4367 
4368                         /* Yes; We're done! */
4369 
4370                         /* Need to release the packet. */
4371                         nx_packet_release(receive_packet_ptr);
4372 
4373 #ifdef NX_DNS_CACHE_ENABLE
4374                         /* Set the resource record type.  */
4375                         temp_rr.nx_dns_rr_type = NX_DNS_RR_TYPE_PTR;
4376 
4377                         /* Set the resource record ttl.  */
4378                         temp_rr.nx_dns_rr_ttl = rr_ttl;
4379 
4380                         /* Add the name string.  */
4381                         status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, ip_question, ip_question_size, (VOID **)(&(temp_rr.nx_dns_rr_name)));
4382 
4383                         /* Check the status.  */
4384                         if(status)
4385                             return (NX_SUCCESS);
4386 
4387                         /* Add the PTR string.  */
4388                         status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, host_name_ptr, name_size, (VOID **)(&(temp_rr.nx_dns_rr_rdata.nx_dns_rr_rdata_ptr.nx_dns_rr_ptr_name)));
4389 
4390                         /* Check the status.  */
4391                         if(status)
4392                         {
4393                             _nx_dns_cache_delete_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_rr.nx_dns_rr_name, 0);
4394                             return (NX_SUCCESS);
4395                         }
4396 
4397                         /* Add the resource record.  */
4398                         status = _nx_dns_cache_add_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr,  NX_NULL);
4399 
4400                         /* Check the status.  */
4401                         if(status)
4402                         {
4403 
4404                             /* Delete the resource record.  */
4405                             _nx_dns_cache_delete_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr);
4406                         }
4407 #endif /* NX_DNS_CACHE_ENABLE  */
4408 
4409                         /* Return success!  */
4410                         return(NX_SUCCESS);
4411                     }
4412                     else
4413                     {
4414 
4415                         /* Nope, Our destination string is too small.  Release the packet. */
4416                         nx_packet_release(receive_packet_ptr);
4417 
4418                         /* NULL-terminate the host name string.  */
4419                         *host_name_ptr =  NX_NULL;
4420 
4421                         /* Return an error!  */
4422                         return(NX_DNS_SIZE_ERROR);
4423                     }
4424                 }
4425                 else
4426                 {
4427                     /* This response isn't a name, just skip it. */
4428                     status = _nx_dns_resource_size_get(data_ptr, receive_packet_ptr, &resource_size);
4429                     if (status)
4430                     {
4431                         /* Nope, Our destination string is too small.  Release the packet. */
4432                         nx_packet_release(receive_packet_ptr);
4433 
4434                         /* NULL-terminate the host name string.  */
4435                         *host_name_ptr =  NX_NULL;
4436 
4437                         /* Return an error!  */
4438                         return(NX_DNS_SIZE_ERROR);
4439                     }
4440                     data_ptr += resource_size;
4441                 }
4442 
4443             } /* and check the next answer record */
4444         }
4445 
4446         /* We got a packet, but did it supply name resolution? */
4447         if (answerCount == 0)
4448         {
4449 
4450             /* No, set the failed query status. */
4451             status = NX_DNS_QUERY_FAILED;
4452         }
4453 
4454         /* Release the packet.  */
4455         nx_packet_release(receive_packet_ptr);
4456     }
4457 
4458     /* Return completion status. */
4459     return(status);
4460 }
4461 
4462 
4463 /**************************************************************************/
4464 /*                                                                        */
4465 /*  FUNCTION                                               RELEASE        */
4466 /*                                                                        */
4467 /*    _nx_dns_send_query_get_rdata_by_name                 PORTABLE C     */
4468 /*                                                           6.1.5        */
4469 /*  AUTHOR                                                                */
4470 /*                                                                        */
4471 /*    Yuxin Zhou, Microsoft Corporation                                   */
4472 /*                                                                        */
4473 /*  DESCRIPTION                                                           */
4474 /*                                                                        */
4475 /*    This function allocates and sends a new DNS query on the specific   */
4476 /*    information.  On receiving a response, this function also invokes   */
4477 /*    a process function to parse the resposne.                           */
4478 /*                                                                        */
4479 /*  INPUT                                                                 */
4480 /*                                                                        */
4481 /*    dns_ptr                               Pointer to DNS instance       */
4482 /*    server_address                        The DNS server address        */
4483 /*    host_name                             Name of host to resolve       */
4484 /*    record_buffer                         Buffer for resource data      */
4485 /*    buffer_size                           Buffer size for resource data */
4486 /*    record_count                          The count of resource data    */
4487 /*    wait_option                           Timeout value                 */
4488 /*                                                                        */
4489 /*  OUTPUT                                                                */
4490 /*                                                                        */
4491 /*    status                                Completion status             */
4492 /*                                                                        */
4493 /*  CALLS                                                                 */
4494 /*                                                                        */
4495 /*    nx_packet_allocate                    Allocate a new packet         */
4496 /*    _nx_dns_new_packet_create             Create new DNS packet         */
4497 /*    nx_packet_release                     Release packet                */
4498 /*    nxd_udp_socket_send                   Send DNS UDP packet           */
4499 /*    _nx_dns_response_get                  Get DNS response              */
4500 /*                                                                        */
4501 /*  CALLED BY                                                             */
4502 /*                                                                        */
4503 /*    _nx_dns_host_resource_data_by_name_get                              */
4504 /*                                          Get the resource data by name */
4505 /*                                                                        */
4506 /*  RELEASE HISTORY                                                       */
4507 /*                                                                        */
4508 /*    DATE              NAME                      DESCRIPTION             */
4509 /*                                                                        */
4510 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4511 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4512 /*                                            resulting in version 6.1    */
4513 /*  02-02-2021     Yuxin Zhou               Modified comment(s), improved */
4514 /*                                            packet length verification, */
4515 /*                                            improved the logic of       */
4516 /*                                            receiving dns response,     */
4517 /*                                            resulting in version 6.1.4  */
4518 /*  03-02-2021     Yuxin Zhou               Modified comment(s), and      */
4519 /*                                            improved the logic of       */
4520 /*                                            receiving dns response,     */
4521 /*                                            resulting in version 6.1.5  */
4522 /*                                                                        */
4523 /**************************************************************************/
_nx_dns_send_query_get_rdata_by_name(NX_DNS * dns_ptr,NXD_ADDRESS * dns_server_address,UCHAR * host_name,UCHAR * record_buffer,UINT buffer_size,UINT * record_count,UINT dns_record_type,ULONG wait_option)4524 static UINT _nx_dns_send_query_get_rdata_by_name(NX_DNS *dns_ptr, NXD_ADDRESS *dns_server_address,
4525                                                  UCHAR *host_name, UCHAR *record_buffer, UINT buffer_size,
4526                                                  UINT *record_count, UINT dns_record_type, ULONG wait_option)
4527 {
4528 
4529 UINT                status;
4530 NX_PACKET           *packet_ptr;
4531 #ifdef NX_DNS_CLIENT_CLEAR_QUEUE
4532 NX_PACKET           *receive_packet_ptr;
4533 #endif /* NX_DNS_CLIENT_CLEAR_QUEUE */
4534 
4535     /* Allocate a packet.  */
4536     status =  nx_packet_allocate(dns_ptr -> nx_dns_packet_pool_ptr, &packet_ptr, NX_UDP_PACKET, NX_DNS_PACKET_ALLOCATE_TIMEOUT);
4537 
4538     /* Check the allocate status.  */
4539     if (status != NX_SUCCESS)
4540     {
4541 
4542         /* Return error status.  */
4543         return(status);
4544     }
4545 
4546     /* Create a request */
4547     status =  _nx_dns_new_packet_create(dns_ptr, packet_ptr, host_name, (USHORT)dns_record_type);
4548 
4549     /* Check the DNS packet create status.  */
4550     if (status != NX_SUCCESS)
4551     {
4552 
4553         nx_packet_release(packet_ptr);
4554 
4555         /* Return error status.  */
4556         return(status);
4557     }
4558 
4559     /* We will use the time spent sleeping to clear broadcast DNS packets from a previous query
4560        from the DNS receive queue. This will prevent ensure the most recent DNS response is
4561        processed and avoid the situation of valid DNS response packets overflowing the DNS socket
4562        queue. */
4563 #ifdef NX_DNS_CLIENT_CLEAR_QUEUE
4564     do
4565     {
4566 
4567         /* Is there any packets on the queue?  */
4568         status = nx_udp_socket_receive(&(dns_ptr -> nx_dns_socket), &receive_packet_ptr, NX_NO_WAIT);
4569 
4570         /* Yes, we received a packet on the DNS port! */
4571         if (status == NX_SUCCESS)
4572         {
4573 
4574             /* But we don't want it. Release it! */
4575             nx_packet_release(receive_packet_ptr);
4576         }
4577 
4578         /* Keep checking till the queue becomes empty. */
4579     } while(status == NX_SUCCESS);
4580 #endif /* NX_DNS_CLIENT_CLEAR_QUEUE */
4581 
4582     /* Send the DNS packet out.  */
4583     status =  nxd_udp_socket_send(&dns_ptr -> nx_dns_socket, packet_ptr, dns_server_address, NX_DNS_PORT);
4584 
4585     /* Check the completion of the send.  */
4586     if (status != NX_SUCCESS)
4587     {
4588 
4589         /* Unsuccessful, release the packet.  */
4590         nx_packet_release(packet_ptr);
4591 
4592         return status;
4593     }
4594 
4595     /* Check for non-blocking.  */
4596     if (wait_option == NX_NO_WAIT)
4597     {
4598         return(NX_IN_PROGRESS);
4599     }
4600 
4601     /* Wait for a DNS response.  */
4602     status = _nx_dns_response_get(dns_ptr, host_name, record_buffer, buffer_size, record_count, wait_option);
4603 
4604     /* Return completion status. */
4605     return(status);
4606 }
4607 
4608 /**************************************************************************/
4609 /*                                                                        */
4610 /*  FUNCTION                                               RELEASE        */
4611 /*                                                                        */
4612 /*    _nx_dns_response_get                                 PORTABLE C     */
4613 /*                                                           6.1.5        */
4614 /*  AUTHOR                                                                */
4615 /*                                                                        */
4616 /*    Yuxin Zhou, Microsoft Corporation                                   */
4617 /*                                                                        */
4618 /*  DESCRIPTION                                                           */
4619 /*                                                                        */
4620 /*    This function gets dns response.                                    */
4621 /*                                                                        */
4622 /*  INPUT                                                                 */
4623 /*                                                                        */
4624 /*    dns_ptr                               Pointer to DNS instance       */
4625 /*    host_name                             Name of host to resolve       */
4626 /*    record_buffer                         Buffer for resource data      */
4627 /*    buffer_size                           Buffer size for resource data */
4628 /*    record_count                          The count of resource data    */
4629 /*    wait_option                           Timeout value                 */
4630 /*                                                                        */
4631 /*  OUTPUT                                                                */
4632 /*                                                                        */
4633 /*    status                                Completion status             */
4634 /*                                                                        */
4635 /*  CALLS                                                                 */
4636 /*                                                                        */
4637 /*    _nx_dns_response_receive              Receive DNS response          */
4638 /*    _nx_dns_response_process              Process the DNS respondse     */
4639 /*    nx_packet_release                     Release packet                */
4640 /*                                                                        */
4641 /*  CALLED BY                                                             */
4642 /*                                                                        */
4643 /*    _nx_dns_send_query_get_rdata_by_name  Get the resource data by name */
4644 /*                                                                        */
4645 /*  RELEASE HISTORY                                                       */
4646 /*                                                                        */
4647 /*    DATE              NAME                      DESCRIPTION             */
4648 /*                                                                        */
4649 /*  03-02-2021     Yuxin Zhou               Initial Version 6.1.5         */
4650 /*                                                                        */
4651 /**************************************************************************/
_nx_dns_response_get(NX_DNS * dns_ptr,UCHAR * host_name,UCHAR * record_buffer,UINT buffer_size,UINT * record_count,ULONG wait_option)4652 UINT _nx_dns_response_get(NX_DNS *dns_ptr, UCHAR *host_name, UCHAR *record_buffer,
4653                           UINT buffer_size, UINT *record_count, ULONG wait_option)
4654 {
4655 UINT        status;
4656 NX_PACKET  *packet_ptr;
4657 
4658 
4659     /* Wait for a DNS response.  */
4660     status = _nx_dns_response_receive(dns_ptr, &packet_ptr, wait_option);
4661 
4662     /* Check status.  */
4663     if (status == NX_SUCCESS)
4664     {
4665 
4666 #ifndef NX_DISABLE_PACKET_CHAIN
4667         if (packet_ptr -> nx_packet_next)
4668         {
4669 
4670             /* Chained packet is not supported. */
4671             nx_packet_release(packet_ptr);
4672 
4673             /* Release the resource obtained in _nx_dns_host_resource_data_by_name_get for non-blocking.  */
4674             if (wait_option == NX_NO_WAIT)
4675             {
4676 
4677                 /* Unbind the socket.  */
4678                 nx_udp_socket_unbind(&(dns_ptr -> nx_dns_socket));
4679                 tx_mutex_put(&dns_ptr -> nx_dns_mutex);
4680             }
4681 
4682             return(NX_INVALID_PACKET);
4683         }
4684 #endif /* NX_DISABLE_PACKET_CHAIN */
4685 
4686         /* Call the function to process the DNS packet.  */
4687         status = _nx_dns_response_process(dns_ptr, host_name, packet_ptr, record_buffer, buffer_size, record_count);
4688     }
4689 
4690     /* Release the resource obtained in _nx_dns_host_resource_data_by_name_get for non-blocking.  */
4691     if (wait_option == NX_NO_WAIT)
4692     {
4693 
4694         /* Unbind the socket.  */
4695         nx_udp_socket_unbind(&(dns_ptr -> nx_dns_socket));
4696         tx_mutex_put(&dns_ptr -> nx_dns_mutex);
4697     }
4698 
4699     return(status);
4700 }
4701 
4702 /**************************************************************************/
4703 /*                                                                        */
4704 /*  FUNCTION                                               RELEASE        */
4705 /*                                                                        */
4706 /*    _nx_dns_response_receive                             PORTABLE C     */
4707 /*                                                           6.3.0        */
4708 /*  AUTHOR                                                                */
4709 /*                                                                        */
4710 /*    Yuxin Zhou, Microsoft Corporation                                   */
4711 /*                                                                        */
4712 /*  DESCRIPTION                                                           */
4713 /*                                                                        */
4714 /*    This function receives dns response.                                */
4715 /*                                                                        */
4716 /*  INPUT                                                                 */
4717 /*                                                                        */
4718 /*    dns_ptr                               Pointer to DNS instance       */
4719 /*    packet_ptr                            Pointer to UDP packet pointer */
4720 /*    wait_option                           Timeout value                 */
4721 /*                                                                        */
4722 /*  OUTPUT                                                                */
4723 /*                                                                        */
4724 /*    status                                Completion status             */
4725 /*                                                                        */
4726 /*  CALLS                                                                 */
4727 /*                                                                        */
4728 /*    tx_time_get                           Get the system time           */
4729 /*    nx_udp_socket_receive                 Receive DNS UDP packet        */
4730 /*    nx_packet_release                     Release packet                */
4731 /*                                                                        */
4732 /*  CALLED BY                                                             */
4733 /*                                                                        */
4734 /*    _nx_dns_send_query_get_rdata_by_name  Get the resource data by name */
4735 /*                                                                        */
4736 /*  RELEASE HISTORY                                                       */
4737 /*                                                                        */
4738 /*    DATE              NAME                      DESCRIPTION             */
4739 /*                                                                        */
4740 /*  02-02-2021     Yuxin Zhou               Initial Version 6.1.4         */
4741 /*  10-31-2023     Bo Chen                  Modified comment(s), and      */
4742 /*                                            reset the status to avoid   */
4743 /*                                            processing null packet,     */
4744 /*                                            resulting in version 6.3.0  */
4745 /*                                                                        */
4746 /**************************************************************************/
_nx_dns_response_receive(NX_DNS * dns_ptr,NX_PACKET ** packet_ptr,ULONG wait_option)4747 static UINT _nx_dns_response_receive(NX_DNS *dns_ptr, NX_PACKET **packet_ptr, ULONG wait_option)
4748 {
4749 
4750 UINT                status;
4751 ULONG               start_time;
4752 ULONG               current_time;
4753 ULONG               elapsed_time;
4754 ULONG               time_remaining;
4755 
4756 
4757     /* Initialize the value.  */
4758     start_time =  tx_time_get();
4759     elapsed_time = 0;
4760     time_remaining = wait_option;
4761 
4762     do
4763     {
4764 
4765         /* Receive udp packet. */
4766         status = nx_udp_socket_receive(&(dns_ptr -> nx_dns_socket), packet_ptr, time_remaining);
4767 
4768         /* Determine if this one is for us. */
4769         if (status == NX_SUCCESS)
4770         {
4771 
4772             /* Check the IDs in the DNS header match.  */
4773             if (((*packet_ptr) -> nx_packet_length >= sizeof(USHORT)) &&
4774                 (_nx_dns_network_to_short_convert((*packet_ptr) -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET) == dns_ptr -> nx_dns_transmit_id))
4775             {
4776 
4777                 /* They do. We can stop receiving packets and process this one. */
4778                 break;
4779             }
4780             else
4781             {
4782 
4783                 /* They do not. Discard the packet! */
4784                 nx_packet_release((*packet_ptr));
4785 
4786                 /* Set the status.  */
4787                 status = NX_DNS_BAD_ID_ERROR;
4788 
4789                 /* Continue to receive next packet.  */
4790                 if (time_remaining == 0)
4791                 {
4792                     continue;
4793                 }
4794             }
4795         }
4796 
4797         /* Get the current time. */
4798         current_time = tx_time_get();
4799 
4800         /* Has the time wrapped? */
4801         if (current_time >= start_time)
4802         {
4803 
4804             /* No, simply subtract to get the elapsed time.   */
4805             elapsed_time = current_time - start_time;
4806         }
4807         else
4808         {
4809 
4810             /* Yes it has. Time has rolled over the 32-bit boundary.  */
4811             elapsed_time = (((ULONG) 0xFFFFFFFF) - start_time) + current_time;
4812         }
4813 
4814         /* Update the time remaining with the elapsed time. */
4815         if (time_remaining > elapsed_time)
4816         {
4817             time_remaining -= elapsed_time;
4818         }
4819         else
4820         {
4821             time_remaining = 0;
4822         }
4823 
4824     } while(time_remaining > 0);
4825 
4826     /* Return completion status. */
4827     return(status);
4828 }
4829 
4830 /**************************************************************************/
4831 /*                                                                        */
4832 /*  FUNCTION                                               RELEASE        */
4833 /*                                                                        */
4834 /*    _nx_dns_response_process                             PORTABLE C     */
4835 /*                                                           6.1.5        */
4836 /*  AUTHOR                                                                */
4837 /*                                                                        */
4838 /*    Yuxin Zhou, Microsoft Corporation                                   */
4839 /*                                                                        */
4840 /*  DESCRIPTION                                                           */
4841 /*                                                                        */
4842 /*    This function processes a DNS respond packet. If the reply packet   */
4843 /*    includes multiple answers. this service records as many answers     */
4844 /*    into the record_buffer.                                             */
4845 /*                                                                        */
4846 /*  INPUT                                                                 */
4847 /*                                                                        */
4848 /*    dns_ptr                               Pointer to DNS instance       */
4849 /*    host_name                             Name of host to resolve       */
4850 /*    packet_ptr                            Pointer to received packet    */
4851 /*    record_buffer                         Buffer for resource data      */
4852 /*    buffer_size                           Buffer size for resource data */
4853 /*    record_count                          The count of resource data    */
4854 /*    lookup_type                           The DNS query type            */
4855 /*                                                                        */
4856 /*  OUTPUT                                                                */
4857 /*                                                                        */
4858 /*    status                                Completion status             */
4859 /*                                                                        */
4860 /*  CALLS                                                                 */
4861 /*                                                                        */
4862 /*    _nx_dns_name_size_calculate           Calculate size of name field  */
4863 /*    _nx_dns_network_to_short_convert      Convert to unsigned short     */
4864 /*    _nx_dns_resource_type_get             Get the value of the resource */
4865 /*                                            type.                       */
4866 /*    _nx_dns_process_cname_type            Process the CNAME type record */
4867 /*    _nx_dns_process_txt_type              Process the TXT type record   */
4868 /*    _nx_dns_process_ns_type               Process the NS type record    */
4869 /*    _nx_dns_process_mx_type               Process the MX type record    */
4870 /*    _nx_dns_process_srv_type              Process the SRV type record   */
4871 /*    _nx_dns_process_a_type                Process the A type record     */
4872 /*    _nx_dns_process_aaaa_type             Process the AAAA type record  */
4873 /*    _nx_dns_process_soa_type              Process the SOA type record   */
4874 /*    nx_packet_release                     Release the packet.           */
4875 /*                                                                        */
4876 /*  CALLED BY                                                             */
4877 /*                                                                        */
4878 /*    Application Code                                                    */
4879 /*                                                                        */
4880 /*  RELEASE HISTORY                                                       */
4881 /*                                                                        */
4882 /*    DATE              NAME                      DESCRIPTION             */
4883 /*                                                                        */
4884 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4885 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
4886 /*                                            updated resource get APIs to*/
4887 /*                                            improve buffer bound check, */
4888 /*                                            resulting in version 6.1    */
4889 /*  03-02-2021     Yuxin Zhou               Modified comment(s), and      */
4890 /*                                            improved the logic of       */
4891 /*                                            receiving dns response,     */
4892 /*                                            resulting in version 6.1.5  */
4893 /*                                                                        */
4894 /**************************************************************************/
_nx_dns_response_process(NX_DNS * dns_ptr,UCHAR * host_name,NX_PACKET * packet_ptr,UCHAR * record_buffer,UINT buffer_size,UINT * record_count)4895 static UINT _nx_dns_response_process(NX_DNS *dns_ptr, UCHAR *host_name, NX_PACKET *packet_ptr,
4896                                      UCHAR *record_buffer, UINT buffer_size, UINT *record_count)
4897 {
4898 
4899 UINT                status;
4900 USHORT              answerCount;
4901 USHORT              answerRRCount;
4902 USHORT              authorityRRCount;
4903 USHORT              additionalRRCount;
4904 UCHAR               *data_ptr;
4905 UINT                response_type;
4906 UCHAR               *buffer_prepend_ptr;
4907 UCHAR               *buffer_append_ptr;
4908 UINT                rrIndex;
4909 UINT                rr_location;
4910 UINT                answer_found = NX_FALSE;
4911 UINT                resource_size;
4912 UINT                name_size;
4913 UINT                host_name_size;
4914 
4915     /* Set the buffer pointer.  */
4916     buffer_prepend_ptr = record_buffer;
4917     buffer_append_ptr = record_buffer + buffer_size;
4918 
4919     /* We received a response. Is there a valid header?  */
4920     if (packet_ptr -> nx_packet_length <= NX_DNS_QDSECT_OFFSET)
4921     {
4922 
4923         /* No; Release the new packet.  */
4924         nx_packet_release(packet_ptr);
4925 
4926         /* Return error status. */
4927         return NX_DNS_MALFORMED_PACKET;
4928     }
4929 
4930     /* Does the incoming DNS header ID match the query ID we sent out?  */
4931     if (_nx_dns_network_to_short_convert(packet_ptr -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET) != dns_ptr -> nx_dns_transmit_id)
4932     {
4933 
4934         /* No; Release the packet.  */
4935         nx_packet_release(packet_ptr);
4936 
4937         /* Return error status. */
4938         return NX_DNS_BAD_ID_ERROR;
4939     }
4940 
4941     /* Check that the packet has a valid response record.  */
4942     status =  _nx_dns_network_to_short_convert(packet_ptr -> nx_packet_prepend_ptr + NX_DNS_FLAGS_OFFSET);
4943 
4944     /* Check for indication of DNS server error (cannot authenticate answer or authority portion
4945        of the DNS data. */
4946     if ((status & NX_DNS_ERROR_MASK) == NX_DNS_ERROR_MASK)
4947     {
4948 
4949         /* Release the source packet.  */
4950         nx_packet_release(packet_ptr);
4951 
4952         return NX_DNS_SERVER_AUTH_ERROR;
4953     }
4954 
4955     /* Determine if we have any 'answers' to our DNS query. */
4956     answerRRCount = _nx_dns_network_to_short_convert(packet_ptr -> nx_packet_prepend_ptr + NX_DNS_ANCOUNT_OFFSET);
4957     answerCount = answerRRCount;
4958 
4959     /* Also check if there are any 'hints' from the Authoritative nameserver. */
4960     authorityRRCount = _nx_dns_network_to_short_convert(packet_ptr -> nx_packet_prepend_ptr + NX_DNS_NSCOUNT_OFFSET);
4961     answerCount = (USHORT)(answerCount + authorityRRCount);
4962 
4963     /* Include Additional section as well */
4964     additionalRRCount = _nx_dns_network_to_short_convert(packet_ptr -> nx_packet_prepend_ptr + NX_DNS_ARCOUNT_OFFSET);
4965     answerCount = (USHORT)(answerCount + additionalRRCount);
4966 
4967     /* Are there answers in this resposne? */
4968     if (((status & NX_DNS_QUERY_MASK) == NX_DNS_RESPONSE_FLAG)
4969         && ((status & NX_DNS_RCODE_MASK) == NX_DNS_RCODE_SUCCESS)
4970         && (answerCount >= 1))
4971     {
4972 
4973 
4974         /* This looks like the response to our question, now find the response record.  */
4975         /* Point at the start of the question.  */
4976         data_ptr =  packet_ptr -> nx_packet_prepend_ptr + NX_DNS_QDSECT_OFFSET;
4977 
4978         /* Determine if there is a question still in the server's response.  */
4979         if (_nx_dns_network_to_short_convert(packet_ptr -> nx_packet_prepend_ptr + NX_DNS_QDCOUNT_OFFSET) == 1)
4980         {
4981 
4982             /* Get name size */
4983             name_size = _nx_dns_name_string_unencode(packet_ptr, data_ptr, temp_string_buffer, NX_DNS_NAME_MAX);
4984 
4985             if (!name_size)
4986             {
4987 
4988                 /* Release the source packet.  */
4989                 nx_packet_release(packet_ptr);
4990 
4991                 return NX_DNS_MALFORMED_PACKET;
4992             }
4993 
4994             /* Check for name.  */
4995             if (_nx_utility_string_length_check((CHAR *)host_name, &host_name_size, name_size) ||
4996                 (name_size != host_name_size) ||
4997                 (memcmp(host_name, temp_string_buffer, name_size) != 0))
4998             {
4999 
5000                 /* Release the source packet.  */
5001                 nx_packet_release(packet_ptr);
5002 
5003                 /* This was not what the Client requested. Return error status.  */
5004                 return(NX_DNS_MISMATCHED_RESPONSE);
5005             }
5006 
5007             /* Get the length of name field.  */
5008             name_size = _nx_dns_name_size_calculate(data_ptr, packet_ptr);
5009 
5010             /* Check if the data pointer is valid.  */
5011             if (data_ptr + name_size + 4 >= packet_ptr -> nx_packet_append_ptr)
5012             {
5013 
5014                 /* Release the source packet.  */
5015                 nx_packet_release(packet_ptr);
5016 
5017                 return(NX_DNS_MALFORMED_PACKET);
5018             }
5019 
5020             /* Check the type and class.  */
5021             if ((_nx_dns_network_to_short_convert(data_ptr + name_size) != dns_ptr -> nx_dns_lookup_type) ||
5022                 (_nx_dns_network_to_short_convert(data_ptr + name_size + 2) != NX_DNS_RR_CLASS_IN))
5023             {
5024 
5025                 /* Release the source packet.  */
5026                 nx_packet_release(packet_ptr);
5027 
5028                 /* This was not what the Client requested. Return error status.  */
5029                 return(NX_DNS_MISMATCHED_RESPONSE);
5030             }
5031 
5032             /* Yes, the question is present in the response, skip it!  */
5033             data_ptr +=  name_size + 4;
5034         }
5035 
5036         /* Set the status.  */
5037         status = NX_SUCCESS;
5038 
5039         /* Check all the response records */
5040         for(rrIndex = 0; rrIndex < answerCount; rrIndex++)
5041         {
5042 
5043             /* Set the section class.  */
5044             if(answerRRCount && (rrIndex < answerRRCount))
5045                 rr_location = NX_DNS_RR_ANSWER_SECTION;
5046             else if(authorityRRCount && (rrIndex < (UINT)(answerRRCount + authorityRRCount)))
5047                 rr_location = NX_DNS_RR_AUTHORITY_SECTION;
5048             else
5049                 rr_location = NX_DNS_RR_ADDITIONAL_SECTION;
5050 
5051             /* Check for valid data_ptr.  */
5052             if (data_ptr >= packet_ptr -> nx_packet_append_ptr)
5053             {
5054 
5055                 /* Process error.  */
5056                 break;
5057             }
5058 
5059             /* Process the server response. */
5060             status = _nx_dns_resource_type_get(data_ptr, packet_ptr, &response_type);
5061             if (status)
5062             {
5063 
5064                 /* Process error.  */
5065                 break;
5066             }
5067 
5068             /* Is this an A Type? */
5069             if(response_type == NX_DNS_RR_TYPE_A)
5070             {
5071 
5072                 /* Call the function process the A type message. */
5073                 status = _nx_dns_process_a_type(dns_ptr, packet_ptr, data_ptr,  &buffer_prepend_ptr, &buffer_append_ptr, record_count, rr_location);
5074 
5075             }
5076 
5077             /* Is this an AAAA Type? */
5078             else if(response_type == NX_DNS_RR_TYPE_AAAA)
5079             {
5080 
5081                 /* Call the function process the AAAA type message. */
5082                 status = _nx_dns_process_aaaa_type(dns_ptr, packet_ptr, data_ptr,  &buffer_prepend_ptr, &buffer_append_ptr, record_count, rr_location);
5083 
5084             }
5085 
5086 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
5087 
5088             /* Is this a Type NX_DNS_RR_TYPE_CNAME?  */
5089             else if(response_type == NX_DNS_RR_TYPE_CNAME)
5090             {
5091 
5092                 /* Call the function process the CNAME type message. */
5093                 status = _nx_dns_process_cname_type(dns_ptr, packet_ptr, data_ptr, record_buffer, buffer_size, record_count);
5094 
5095             }
5096 
5097             /* Is this a Type NX_DNS_RR_TYPE_TXT?  */
5098             else if(response_type == NX_DNS_RR_TYPE_TXT)
5099             {
5100 
5101                 /* Call the function process the TXT type message. */
5102                 status = _nx_dns_process_txt_type(dns_ptr, packet_ptr, data_ptr, record_buffer, buffer_size, record_count);
5103             }
5104 
5105             /* Is this a Type NX_DNS_RR_TYPE_NS?  */
5106             else if(response_type == NX_DNS_RR_TYPE_NS)
5107             {
5108 
5109                 /* Call the function process the NS type message. */
5110                 status = _nx_dns_process_ns_type(dns_ptr, packet_ptr, data_ptr, &buffer_prepend_ptr, &buffer_append_ptr, record_count);
5111             }
5112 
5113 
5114             /* Is this a Type NX_DNS_RR_TYPE_MX?  */
5115             else if(response_type == NX_DNS_RR_TYPE_MX)
5116             {
5117 
5118                 /* Call the function process the MX type message. */
5119                 status = _nx_dns_process_mx_type(dns_ptr, packet_ptr, data_ptr, &buffer_prepend_ptr, &buffer_append_ptr, record_count);
5120             }
5121 
5122             /* Is this a Type NX_DNS_RR_TYPE_SRV?  */
5123             else if(response_type == NX_DNS_RR_TYPE_SRV)
5124             {
5125 
5126                 /* Call the function process the SRV type message. */
5127                 status = _nx_dns_process_srv_type(dns_ptr, packet_ptr, data_ptr, &buffer_prepend_ptr, &buffer_append_ptr, record_count);
5128             }
5129 
5130             /* Is this a Type NX_DNS_RR_TYPE_SOA?  */
5131             else if(response_type == NX_DNS_RR_TYPE_SOA)
5132             {
5133 
5134                 /* Call the function process the SOA type message. */
5135                 status = _nx_dns_process_soa_type(dns_ptr, packet_ptr, data_ptr, record_buffer, buffer_size, record_count);
5136 
5137             }
5138 #endif
5139 
5140             /* Check the process status.  */
5141             if(status != NX_SUCCESS)
5142             {
5143 
5144                 /* Process error.  */
5145                 break;
5146             }
5147             else
5148             {
5149 
5150                 /* Did we get a correct answer?  */
5151                 if ((answer_found == NX_FALSE) &&
5152                     (response_type == dns_ptr -> nx_dns_lookup_type))
5153                 {
5154                     answer_found = NX_TRUE;
5155                 }
5156             }
5157 
5158             status = _nx_dns_resource_size_get(data_ptr, packet_ptr, &resource_size);
5159             if (status)
5160             {
5161 
5162                 /* Process error, reset answer is not found.  */
5163                 break;
5164             }
5165             data_ptr += resource_size;
5166         }
5167     }
5168 
5169     /* Release the packet.  */
5170     nx_packet_release(packet_ptr);
5171 
5172     /* Check the answer found flag.  */
5173     if (answer_found)
5174         status = NX_SUCCESS;
5175     else
5176         status = NX_DNS_QUERY_FAILED;
5177 
5178     return(status);
5179 }
5180 
5181 
5182 /**************************************************************************/
5183 /*                                                                        */
5184 /*  FUNCTION                                               RELEASE        */
5185 /*                                                                        */
5186 /*    _nx_dns_process_a_type                               PORTABLE C     */
5187 /*                                                           6.1.4        */
5188 /*  AUTHOR                                                                */
5189 /*                                                                        */
5190 /*    Yuxin Zhou, Microsoft Corporation                                   */
5191 /*                                                                        */
5192 /*  DESCRIPTION                                                           */
5193 /*                                                                        */
5194 /*    This function process the A record type.   If the DNS look up type  */
5195 /*    was NS, MX, or SRV type, this function also parses the additional   */
5196 /*    section looking for A type information.                             */
5197 /*                                                                        */
5198 /*  INPUT                                                                 */
5199 /*                                                                        */
5200 /*    dns_ptr                               Pointer to DNS instance       */
5201 /*    packet_ptr                            Pointer to received packet    */
5202 /*    data_ptr                              Pointer to resource data      */
5203 /*                                            section                     */
5204 /*    buffer_prepend_ptr                    Pointer to the starting       */
5205 /*                                            address of available buffer */
5206 /*    buffer_append_ptr                     Pointer to the ending address */
5207 /*                                            of available buffer         */
5208 /*    record_count                          The count of the IPv4 address */
5209 /*    rr_location                           The DNS resource data section */
5210 /*                                                                        */
5211 /*  OUTPUT                                                                */
5212 /*                                                                        */
5213 /*    status                                Completion status             */
5214 /*                                                                        */
5215 /*  CALLS                                                                 */
5216 /*                                                                        */
5217 /*    _nx_dns_resource_type_get             Get resource type             */
5218 /*    _nx_dns_resource_data_address_get     Get address of data           */
5219 /*    _nx_dns_name_string_unencode          Unencode the name and get it. */
5220 /*    _nx_dns_name_size_calculate           Calculate size of name field  */
5221 /*                                                                        */
5222 /*  CALLED BY                                                             */
5223 /*                                                                        */
5224 /*    _nx_dns_response_process                                            */
5225 /*                                                                        */
5226 /*  RELEASE HISTORY                                                       */
5227 /*                                                                        */
5228 /*    DATE              NAME                      DESCRIPTION             */
5229 /*                                                                        */
5230 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5231 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
5232 /*                                            verified memcpy use cases,  */
5233 /*                                            updated resource get APIs to*/
5234 /*                                            improve buffer bound check, */
5235 /*                                            resulting in version 6.1    */
5236 /*  02-02-2021     Yuxin Zhou               Modified comment(s), improved */
5237 /*                                            packet length verification, */
5238 /*                                            resulting in version 6.1.4  */
5239 /*                                                                        */
5240 /**************************************************************************/
_nx_dns_process_a_type(NX_DNS * dns_ptr,NX_PACKET * packet_ptr,UCHAR * data_ptr,UCHAR ** buffer_prepend_ptr,UCHAR ** buffer_append_ptr,UINT * record_count,UINT rr_location)5241 static UINT _nx_dns_process_a_type(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *data_ptr,
5242                                    UCHAR **buffer_prepend_ptr, UCHAR **buffer_append_ptr,
5243                                    UINT *record_count, UINT rr_location)
5244 {
5245 
5246 UINT            response_type;
5247 ULONG           ipv4_address;
5248 UINT            status;
5249 UINT            data_length;
5250 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
5251 UCHAR           *buffer_header_ptr;
5252 #endif
5253 #ifdef NX_DNS_CACHE_ENABLE
5254 UINT            size;
5255 ULONG           rr_ttl;
5256 #endif /* NX_DNS_CACHE_ENABLE  */
5257 
5258 #if !defined(NX_DNS_CACHE_ENABLE) && !defined(NX_DNS_ENABLE_EXTENDED_RR_TYPES)
5259     NX_PARAMETER_NOT_USED(packet_ptr);
5260 #endif
5261 
5262 #ifdef NX_DNS_CACHE_ENABLE
5263     /* Initialize the value.  */
5264     memset(temp_string_buffer, 0, NX_DNS_NAME_MAX + 1);
5265     memset(&temp_rr, 0, sizeof (NX_DNS_RR));
5266 
5267     /* First obtain the string. */
5268     size = _nx_dns_name_string_unencode(packet_ptr, data_ptr, temp_string_buffer, NX_DNS_NAME_MAX);
5269 
5270     /* Check the string correct.  */
5271     if(!size)
5272     {
5273 
5274         /* Return!  */
5275         return(NX_DNS_MALFORMED_PACKET);
5276     }
5277 
5278     /* Get the resource record ttl.  */
5279     status = _nx_dns_resource_time_to_live_get(data_ptr, packet_ptr, &rr_ttl);
5280     if (status)
5281     {
5282 
5283         /* Return!  */
5284         return(NX_DNS_MALFORMED_PACKET);
5285     }
5286 
5287 #endif /* NX_DNS_CACHE_ENABLE  */
5288 
5289     /* Process the server response and get it. */
5290     status = _nx_dns_resource_type_get(data_ptr, packet_ptr, &response_type);
5291     if (status)
5292     {
5293 
5294         /* Return!  */
5295         return(NX_DNS_MALFORMED_PACKET);
5296     }
5297 
5298     /* Process the A type message in the answer section.*/
5299     if((rr_location == NX_DNS_RR_ANSWER_SECTION)||
5300        (rr_location == NX_DNS_RR_AUTHORITY_SECTION))
5301     {
5302 
5303         /* Verify this is what the DNS Client was requesting. */
5304         if (response_type != dns_ptr -> nx_dns_lookup_type)
5305         {
5306 
5307             /* No, this was not what the Client requested. Return error status.
5308             This should not happen so return error to the host application,
5309             might be a problem with the query or the server. */
5310             return NX_DNS_MISMATCHED_RESPONSE;
5311         }
5312 
5313         /* Yes, make sure it has the correct data size.  */
5314         status = _nx_dns_resource_data_length_get(data_ptr, packet_ptr, &data_length);
5315         if (status)
5316         {
5317 
5318             /* Return!  */
5319             return(NX_DNS_MALFORMED_PACKET);
5320         }
5321 
5322         if (data_length == 4)
5323         {
5324 
5325             /* Get data address and check if it is valid. */
5326             data_ptr = _nx_dns_resource_data_address_get(data_ptr, packet_ptr);
5327             if ((!data_ptr) || ((data_ptr + sizeof(ULONG)) > packet_ptr -> nx_packet_append_ptr))
5328             {
5329 
5330                 /* Return!  */
5331                 return(NX_DNS_MALFORMED_PACKET);
5332             }
5333 
5334             /* Finally, get the address!!! */
5335             ipv4_address =  _nx_dns_network_to_long_convert(data_ptr);
5336 
5337             /* Check the buffer space.  */
5338             if (*buffer_prepend_ptr + 4 > *buffer_append_ptr)
5339             {
5340 
5341                 /* The buffer space is not enough.  */
5342                 return(NX_DNS_NEED_MORE_RECORD_BUFFER);
5343             }
5344 
5345             /* Set the return IP address.  */
5346             memcpy(*buffer_prepend_ptr,&ipv4_address,4); /* Use case of memcpy is verified. */
5347 
5348             /* Update the record buffer pointer. */
5349             *buffer_prepend_ptr +=4;
5350 
5351             /* Update the count of ipv4 address.  */
5352             (*record_count) ++;
5353 
5354 #ifdef NX_DNS_CACHE_ENABLE
5355             /* Set the resource record type.  */
5356             temp_rr.nx_dns_rr_type = NX_DNS_RR_TYPE_A;
5357 
5358             /* Set the resource record ttl.  */
5359             temp_rr.nx_dns_rr_ttl = rr_ttl;
5360 
5361             /* Add the name string.  */
5362             status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_string_buffer, size, (VOID **)(&(temp_rr.nx_dns_rr_name)));
5363 
5364             /* Check the status.  */
5365             if(status)
5366                 return (NX_SUCCESS);
5367 
5368             /* Add the IPv4 address.  */
5369             temp_rr.nx_dns_rr_rdata.nx_dns_rr_rdata_a.nx_dns_rr_a_address = ipv4_address;
5370 
5371             /* Add the resource record.  */
5372             status = _nx_dns_cache_add_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr,  NX_NULL);
5373 
5374             /* Check the status.  */
5375             if(status)
5376             {
5377 
5378                 /* Delete the resource record.  */
5379                 _nx_dns_cache_delete_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr);
5380             }
5381 #endif /* NX_DNS_CACHE_ENABLE  */
5382 
5383             /* Success!  Return success to caller!  */
5384             return(NX_SUCCESS);
5385         }
5386         else
5387         {
5388 
5389             /* Return.*/
5390             return(NX_DNS_MALFORMED_PACKET);
5391         }
5392     }
5393 
5394 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
5395     /* Process the A type message in the additional section.  */
5396     else if(rr_location == NX_DNS_RR_ADDITIONAL_SECTION)
5397     {
5398         if(dns_ptr -> nx_dns_lookup_type == NX_DNS_RR_TYPE_NS)
5399         {
5400             NX_DNS_NS_ENTRY *ns_entry;
5401             UINT            entry_index;
5402             UINT            name_size;
5403 
5404             /* Processing NS query, and encountered A type in the additional section. */
5405             /* This means the record_buffer should already contain name server information,
5406                and the name server IP address is in this resource record. */
5407 
5408             /* First obtain the string. */
5409             temp_string_buffer[0] = 0;
5410             name_size = _nx_dns_name_string_unencode(packet_ptr, data_ptr, temp_string_buffer, NX_DNS_NAME_MAX);
5411 
5412             /* Check the string correct.  */
5413             if(!name_size)
5414             {
5415 
5416                 /* Return !*/
5417                 return(NX_DNS_MALFORMED_PACKET);
5418             }
5419 
5420             /* Get the first address of record buffer.  */
5421             buffer_header_ptr = *buffer_prepend_ptr - ((*record_count) * sizeof(NX_DNS_NS_ENTRY));
5422 
5423             /* Go through all the records and match the string. */
5424             for(entry_index = 0; entry_index < *record_count; entry_index++)
5425             {
5426 
5427                 /* Set the NS entry.  */
5428                 ns_entry = (NX_DNS_NS_ENTRY*)(buffer_header_ptr);
5429 
5430                 /* Check the ipv4 address.*/
5431                 if( ns_entry -> nx_dns_ns_ipv4_address != IP_ADDRESS(0, 0, 0, 0))
5432                 {
5433 
5434                     /* Update the buffer prepend pointer, and match the next NS entry.  */
5435                     buffer_header_ptr += sizeof(NX_DNS_NS_ENTRY);
5436 
5437                     continue;
5438                 }
5439 
5440                 /* The nx_dns_ns_hostname_ptr is set internally with null termination. */
5441                 status = _nx_utility_string_length_check((CHAR *)(ns_entry -> nx_dns_ns_hostname_ptr), &data_length, name_size);
5442 
5443                 if((status == NX_SUCCESS) &&
5444                    (data_length == name_size) &&
5445                    ((memcmp(ns_entry -> nx_dns_ns_hostname_ptr, &temp_string_buffer[0], name_size)) == 0))
5446                 {
5447 
5448                     /* This A type record contains the IPv4 address for the NS entry.  */
5449 
5450                     /* Yes, make sure it has the correct data size.  */
5451                     status = _nx_dns_resource_data_length_get(data_ptr, packet_ptr, &data_length);
5452                     if (status)
5453                     {
5454 
5455                         /* Return!  */
5456                         return(NX_DNS_MALFORMED_PACKET);
5457                     }
5458 
5459                     if (data_length == 4)
5460                     {
5461 
5462                         /* Get data address and check if it is valid. */
5463                         data_ptr = _nx_dns_resource_data_address_get(data_ptr, packet_ptr);
5464                         if ((!data_ptr) || ((data_ptr + sizeof(ULONG)) > packet_ptr -> nx_packet_append_ptr))
5465                         {
5466 
5467                             /* Return!  */
5468                             return(NX_DNS_MALFORMED_PACKET);
5469                         }
5470 
5471                         /* Finally, get the address!!! */
5472                         ipv4_address =  _nx_dns_network_to_long_convert(data_ptr);
5473 
5474                         /* Record the NS entry ipv4 address . */
5475                         ns_entry -> nx_dns_ns_ipv4_address = ipv4_address;
5476 
5477                         /* Success!  Return success to caller!  */
5478                         return(NX_SUCCESS);
5479                     }
5480                 }
5481                 else
5482                 {
5483 
5484                     /* Update the buffer prepend pointer, and match the next NS entry.  */
5485                     buffer_header_ptr += sizeof(NX_DNS_NS_ENTRY);
5486                 }
5487             }
5488         }
5489 
5490         else if(dns_ptr -> nx_dns_lookup_type == NX_DNS_RR_TYPE_MX)
5491         {
5492             NX_DNS_MX_ENTRY *mx_entry;
5493             UINT entry_index;
5494             UINT name_size;
5495 
5496             /* Processing MX query, and encountered A type in the additional section. */
5497             /* This means the record_buffer should already contain mail exchange information,
5498                and the mail server IP address is in this resource record. */
5499 
5500             /* First obtain the string. */
5501             temp_string_buffer[0] = 0;
5502             name_size = _nx_dns_name_string_unencode(packet_ptr, data_ptr, temp_string_buffer, NX_DNS_NAME_MAX);
5503 
5504             /* Check the string correct.  */
5505             if(!name_size)
5506             {
5507 
5508                 /* Return !*/
5509                 return(NX_DNS_MALFORMED_PACKET);
5510             }
5511 
5512             /* Set the record buffer prepend.  */
5513             buffer_header_ptr = *buffer_prepend_ptr - ((*record_count) * sizeof(NX_DNS_MX_ENTRY));
5514 
5515             /* Go through all the records and match the string. */
5516             for(entry_index = 0; entry_index < *record_count; entry_index++)
5517             {
5518 
5519                 /* Set the MX entry pointer.  */
5520                 mx_entry = (NX_DNS_MX_ENTRY*)(buffer_header_ptr);
5521 
5522                 /* Check the ipv4 address, If the ipv4 address has been set, skip it..*/
5523                 if( mx_entry -> nx_dns_mx_ipv4_address != IP_ADDRESS(0, 0, 0, 0))
5524                 {
5525 
5526                     /* Update the buffer prepend pointer, and match the next MX entry.  */
5527                     buffer_header_ptr += sizeof(NX_DNS_MX_ENTRY);
5528                     continue;
5529                 }
5530 
5531                 /* The nx_dns_mx_hostname_ptr is set internally with null termination. */
5532                 status = _nx_utility_string_length_check((CHAR *)(mx_entry -> nx_dns_mx_hostname_ptr), &data_length, name_size);
5533 
5534                 if((status == NX_SUCCESS) &&
5535                    (data_length == name_size) &&
5536                    ((memcmp(mx_entry -> nx_dns_mx_hostname_ptr, &temp_string_buffer[0], name_size)) == 0))
5537                 {
5538 
5539                     /* This A type record contains the IPv4 address for the MX entry.  */
5540 
5541                     /* Yes, make sure it has the correct data size.  */
5542                     status = _nx_dns_resource_data_length_get(data_ptr, packet_ptr, &data_length);
5543                     if (status)
5544                     {
5545 
5546                         /* Return!  */
5547                         return(NX_DNS_MALFORMED_PACKET);
5548                     }
5549 
5550                     if (data_length == 4)
5551                     {
5552 
5553                         /* Get data address and check if it is valid. */
5554                         data_ptr = _nx_dns_resource_data_address_get(data_ptr, packet_ptr);
5555                         if ((!data_ptr) || ((data_ptr + sizeof(ULONG)) > packet_ptr -> nx_packet_append_ptr))
5556                         {
5557 
5558                             /* Return!  */
5559                             return(NX_DNS_MALFORMED_PACKET);
5560                         }
5561 
5562                         /* Finally, get the address!!! */
5563                         ipv4_address =  _nx_dns_network_to_long_convert(data_ptr);
5564 
5565                         /* Record the MX entry ipv4 address . */
5566                         mx_entry -> nx_dns_mx_ipv4_address = ipv4_address;
5567 
5568                         /* Success!  Return success to caller!  */
5569                         return(NX_SUCCESS);
5570                     }
5571                 }
5572                 else
5573                 {
5574 
5575                     /* Update the buffer prepend pointer, and match the next MX entry.  */
5576                     buffer_header_ptr += sizeof(NX_DNS_MX_ENTRY);
5577                 }
5578             }
5579         }
5580         else if(dns_ptr -> nx_dns_lookup_type == NX_DNS_RR_TYPE_SRV)
5581         {
5582             NX_DNS_SRV_ENTRY *srv_entry;
5583             UINT entry_index;
5584             UINT name_size;
5585 
5586             /* Processing SRV query, and encountered A type in the additional section. */
5587             /* This means the record_buffer should already contain SRV information,
5588                and the mail server IP address is in this resource record. */
5589 
5590             /* First obtain the string. */
5591             temp_string_buffer[0] = 0;
5592             name_size = _nx_dns_name_string_unencode(packet_ptr, data_ptr, temp_string_buffer, NX_DNS_NAME_MAX);
5593 
5594             /* Check the string correct.  */
5595             if(!name_size)
5596             {
5597 
5598                 /* Return !*/
5599                 return(NX_DNS_MALFORMED_PACKET);
5600             }
5601 
5602             /* Set the record buffer prepend.  */
5603             buffer_header_ptr = *buffer_prepend_ptr - ((*record_count) * sizeof(NX_DNS_SRV_ENTRY));
5604 
5605             /* Go through all the records and match the string. */
5606             for(entry_index = 0; entry_index < *record_count; entry_index++)
5607             {
5608 
5609                 /* Set the MX entry pointer.  */
5610                 srv_entry = (NX_DNS_SRV_ENTRY*)(buffer_header_ptr);
5611 
5612                 /* Check the ipv4 address, If the ipv4 address has been set, skip it..*/
5613                 if( srv_entry -> nx_dns_srv_ipv4_address != IP_ADDRESS(0, 0, 0, 0))
5614                 {
5615 
5616                     /* Update the buffer prepend pointer, and match the next MX entry.  */
5617                     buffer_header_ptr += sizeof(NX_DNS_SRV_ENTRY);
5618                     continue;
5619                 }
5620 
5621                 /* The nx_dns_srv_hostname_ptr is set internally with null termination. */
5622                 status = _nx_utility_string_length_check((CHAR *)(srv_entry -> nx_dns_srv_hostname_ptr), &data_length, name_size);
5623 
5624                 if((status == NX_SUCCESS) &&
5625                    (data_length == name_size) &&
5626                    ((memcmp(srv_entry -> nx_dns_srv_hostname_ptr, &temp_string_buffer[0], name_size)) == 0))
5627                 {
5628 
5629                     /* This A type record contains the IPv4 address for the MX entry.  */
5630 
5631                     /* Yes, make sure it has the correct data size.  */
5632                     status = _nx_dns_resource_data_length_get(data_ptr, packet_ptr, &data_length);
5633                     if (status)
5634                     {
5635 
5636                         /* Return!  */
5637                         return(NX_DNS_MALFORMED_PACKET);
5638                     }
5639 
5640                     if (data_length == 4)
5641                     {
5642 
5643                         /* Get data address and check if it is valid. */
5644                         data_ptr = _nx_dns_resource_data_address_get(data_ptr, packet_ptr);
5645                         if ((!data_ptr) || ((data_ptr + sizeof(ULONG)) > packet_ptr -> nx_packet_append_ptr))
5646                         {
5647 
5648                             /* Return!  */
5649                             return(NX_DNS_MALFORMED_PACKET);
5650                         }
5651 
5652                         /* Finally, get the address!!! */
5653                         ipv4_address =  _nx_dns_network_to_long_convert(data_ptr);
5654 
5655                         /* Record the SRV entry ipv4 address . */
5656                         srv_entry -> nx_dns_srv_ipv4_address = ipv4_address;
5657 
5658                         /* Success!  Return success to caller!  */
5659                         return(NX_SUCCESS);
5660                     }
5661                 }
5662                 else
5663                 {
5664 
5665                     /* Update the buffer prepend pointer, and match the next MX entry.  */
5666                     buffer_header_ptr += sizeof(NX_DNS_SRV_ENTRY);
5667                 }
5668             }
5669         }
5670     }
5671 #endif
5672 
5673     /* Return.*/
5674     return(NX_SUCCESS);
5675 }
5676 
5677 
5678 /**************************************************************************/
5679 /*                                                                        */
5680 /*  FUNCTION                                               RELEASE        */
5681 /*                                                                        */
5682 /*    _nx_dns_process_aaaa_type                            PORTABLE C     */
5683 /*                                                           6.1.4        */
5684 /*  AUTHOR                                                                */
5685 /*                                                                        */
5686 /*    Yuxin Zhou, Microsoft Corporation                                   */
5687 /*                                                                        */
5688 /*  DESCRIPTION                                                           */
5689 /*                                                                        */
5690 /*    This function process the AAAA record type.                         */
5691 /*                                                                        */
5692 /*  INPUT                                                                 */
5693 /*                                                                        */
5694 /*    dns_ptr                               Pointer to DNS instance       */
5695 /*    packet_ptr                            Pointer to received packet    */
5696 /*    data_ptr                              Pointer to resource data      */
5697 /*                                            section                     */
5698 /*    buffer_prepend_ptr                    Pointer to the starting       */
5699 /*                                            address of available buffer */
5700 /*    buffer_append_ptr                     Pointer to the ending address */
5701 /*                                            of available buffer         */
5702 /*    record_count                          The count of the IPv6 address */
5703 /*    rr_location                           The DNS resource data section */
5704 /*                                                                        */
5705 /*  OUTPUT                                                                */
5706 /*                                                                        */
5707 /*    status                                Completion status             */
5708 /*                                                                        */
5709 /*  CALLS                                                                 */
5710 /*                                                                        */
5711 /*    _nx_dns_resource_type_get             Get resource type             */
5712 /*    _nx_dns_resource_data_address_get     Get address of data           */
5713 /*    _nx_dns_name_string_unencode          Unencode the name and get it. */
5714 /*    _nx_dns_name_size_calculate           Calculate size of name field  */
5715 /*                                                                        */
5716 /*  CALLED BY                                                             */
5717 /*                                                                        */
5718 /*    _nx_dns_response_process                                            */
5719 /*                                                                        */
5720 /*  RELEASE HISTORY                                                       */
5721 /*                                                                        */
5722 /*    DATE              NAME                      DESCRIPTION             */
5723 /*                                                                        */
5724 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5725 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
5726 /*                                            updated resource get APIs to*/
5727 /*                                            improve buffer bound check, */
5728 /*                                            resulting in version 6.1    */
5729 /*  02-02-2021     Yuxin Zhou               Modified comment(s), improved */
5730 /*                                            packet length verification, */
5731 /*                                            resulting in version 6.1.4  */
5732 /*                                                                        */
5733 /**************************************************************************/
_nx_dns_process_aaaa_type(NX_DNS * dns_ptr,NX_PACKET * packet_ptr,UCHAR * data_ptr,UCHAR ** buffer_prepend_ptr,UCHAR ** buffer_append_ptr,UINT * record_count,UINT rr_location)5734 static UINT _nx_dns_process_aaaa_type(NX_DNS *dns_ptr, NX_PACKET *packet_ptr,
5735                                       UCHAR *data_ptr, UCHAR **buffer_prepend_ptr,
5736                                       UCHAR **buffer_append_ptr, UINT *record_count,
5737                                       UINT rr_location)
5738 {
5739 
5740 UINT                    response_type;
5741 UINT                    i;
5742 ULONG                   ipv6_address;
5743 NX_DNS_IPV6_ADDRESS     *ipv6_address_ptr;
5744 UINT                    status;
5745 UINT                    data_length;
5746 #ifdef NX_DNS_CACHE_ENABLE
5747 UINT                    size;
5748 ULONG                   rr_ttl;
5749 #endif /* NX_DNS_CACHE_ENABLE  */
5750 
5751 #ifndef NX_DNS_CACHE_ENABLE
5752     NX_PARAMETER_NOT_USED(packet_ptr);
5753 #endif
5754 
5755 #ifdef NX_DNS_CACHE_ENABLE
5756     /* Initialize the value.  */
5757     memset(temp_string_buffer, 0, NX_DNS_NAME_MAX + 1);
5758     memset(&temp_rr, 0, sizeof (NX_DNS_RR));
5759 
5760     /* First obtain the string. */
5761     size = _nx_dns_name_string_unencode(packet_ptr, data_ptr, temp_string_buffer, NX_DNS_NAME_MAX);
5762 
5763     /* Check the string correct.  */
5764     if(!size)
5765     {
5766 
5767         /* Return!  */
5768         return(NX_DNS_MALFORMED_PACKET);
5769     }
5770 
5771     /* Get the resource record ttl.  */
5772     status = _nx_dns_resource_time_to_live_get(data_ptr, packet_ptr, &rr_ttl);
5773     if (status)
5774     {
5775 
5776         /* Return!  */
5777         return(NX_DNS_MALFORMED_PACKET);
5778     }
5779 
5780 #endif /* NX_DNS_CACHE_ENABLE  */
5781 
5782     /* Process the server response and get it. */
5783     status = _nx_dns_resource_type_get(data_ptr, packet_ptr, &response_type);
5784     if (status)
5785     {
5786 
5787         /* Return!  */
5788         return(NX_DNS_MALFORMED_PACKET);
5789     }
5790 
5791     /* Process the A type message in the answer section.*/
5792     if((rr_location == NX_DNS_RR_ANSWER_SECTION)||
5793        (rr_location == NX_DNS_RR_AUTHORITY_SECTION))
5794     {
5795 
5796         /* Verify this is what the DNS Client was requesting. */
5797         if (response_type != dns_ptr -> nx_dns_lookup_type)
5798         {
5799 
5800             /* No, this was not what the Client requested. Return error status.
5801             This should not happen so return error to the host application,
5802             might be a problem with the query or the server. */
5803             return NX_DNS_MISMATCHED_RESPONSE;
5804         }
5805 
5806         /* Yes, make sure it has the correct data size.  */
5807         status = _nx_dns_resource_data_length_get(data_ptr, packet_ptr, &data_length);
5808         if (status)
5809         {
5810 
5811             /* Return!  */
5812             return(NX_DNS_MALFORMED_PACKET);
5813         }
5814 
5815         if (data_length == 16)
5816         {
5817 
5818             /* Check the buffer space.  */
5819             if ((*buffer_prepend_ptr + sizeof(NX_DNS_IPV6_ADDRESS)) > *buffer_append_ptr)
5820             {
5821 
5822                 /* The buffer space is not enough.  */
5823                 return(NX_DNS_NEED_MORE_RECORD_BUFFER);
5824             }
5825 
5826             /* Update the pointer to the ipv6 address.  */
5827             data_ptr = _nx_dns_resource_data_address_get(data_ptr, packet_ptr);
5828             if ((!data_ptr) || ((data_ptr + (4 * sizeof(ULONG))) > packet_ptr -> nx_packet_append_ptr))
5829             {
5830 
5831                 /* Return!  */
5832                 return(NX_DNS_MALFORMED_PACKET);
5833             }
5834 
5835             ipv6_address_ptr = (NX_DNS_IPV6_ADDRESS*)(*buffer_prepend_ptr);
5836 
5837             /* Finally, Record the ipv6 address to record buffer.  */
5838             for(i = 0; i < 4; i++)
5839             {
5840 
5841                 ipv6_address = _nx_dns_network_to_long_convert(data_ptr);
5842 
5843                 ipv6_address_ptr -> ipv6_address[i] = ipv6_address;
5844 
5845                 data_ptr +=4;
5846 
5847             }
5848 
5849             *buffer_prepend_ptr = *buffer_prepend_ptr + sizeof(NX_DNS_IPV6_ADDRESS);
5850 
5851             /* Update the count of ipv6 address.  */
5852             (*record_count) ++;
5853 
5854 #ifdef NX_DNS_CACHE_ENABLE
5855             /* Set the resource record type.  */
5856             temp_rr.nx_dns_rr_type = NX_DNS_RR_TYPE_AAAA;
5857 
5858             /* Set the resource record ttl.  */
5859             temp_rr.nx_dns_rr_ttl = rr_ttl;
5860 
5861             /* Add the name string.  */
5862             status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_string_buffer, size, (VOID **)(&(temp_rr.nx_dns_rr_name)));
5863 
5864             /* Check the status.  */
5865             if(status)
5866                 return (NX_SUCCESS);
5867 
5868             /* Add the IPv6 address string.  */
5869             status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, ipv6_address_ptr, 16, (VOID **)(&(temp_rr.nx_dns_rr_rdata.nx_dns_rr_rdata_aaaa.nx_dns_rr_aaaa_address)));
5870 
5871             /* Check the status.  */
5872             if(status)
5873             {
5874                 _nx_dns_cache_delete_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_rr.nx_dns_rr_name, 0);
5875                 return (NX_SUCCESS);
5876             }
5877 
5878             /* Add the resource record.  */
5879             status = _nx_dns_cache_add_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr,  NX_NULL);
5880 
5881             /* Check the status.  */
5882             if(status)
5883             {
5884 
5885                 /* Delete the resource record.  */
5886                 _nx_dns_cache_delete_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr);
5887             }
5888 #endif /* NX_DNS_CACHE_ENABLE  */
5889 
5890             /* Success!  */
5891             return(NX_SUCCESS);
5892         }
5893         else
5894         {
5895 
5896             /* Return.*/
5897             return(NX_DNS_MALFORMED_PACKET);
5898         }
5899 
5900     }
5901 
5902     /* Return.*/
5903     return(NX_SUCCESS);
5904 
5905 }
5906 
5907 
5908 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
5909 /**************************************************************************/
5910 /*                                                                        */
5911 /*  FUNCTION                                               RELEASE        */
5912 /*                                                                        */
5913 /*    _nx_dns_process_cname_type                           PORTABLE C     */
5914 /*                                                           6.1          */
5915 /*  AUTHOR                                                                */
5916 /*                                                                        */
5917 /*    Yuxin Zhou, Microsoft Corporation                                   */
5918 /*                                                                        */
5919 /*  DESCRIPTION                                                           */
5920 /*                                                                        */
5921 /*    This function process the CNAME record type.                        */
5922 /*                                                                        */
5923 /*  INPUT                                                                 */
5924 /*                                                                        */
5925 /*    dns_ptr                               Pointer to DNS instance       */
5926 /*    packet_ptr                            Pointer to received packet    */
5927 /*    data_ptr                              Pointer to resource data      */
5928 /*                                            section                     */
5929 /*    record_buffer                         Buffer space for storing      */
5930 /*                                            the host cname              */
5931 /*    buffer_size                           Size of record_buffer.        */
5932 /*    record_count                          Record count                  */
5933 /*                                                                        */
5934 /*  OUTPUT                                                                */
5935 /*                                                                        */
5936 /*    status                                Completion status             */
5937 /*                                                                        */
5938 /*  CALLS                                                                 */
5939 /*                                                                        */
5940 /*    _nx_dns_resource_type_get             Get resource type             */
5941 /*    _nx_dns_resource_data_address_get     Get address of data           */
5942 /*    _nx_dns_name_string_unencode          Unencode the name and get it. */
5943 /*    _nx_dns_name_size_calculate           Calculate size of name field  */
5944 /*                                                                        */
5945 /*  CALLED BY                                                             */
5946 /*                                                                        */
5947 /*    _nx_dns_response_process                                            */
5948 /*                                                                        */
5949 /*  RELEASE HISTORY                                                       */
5950 /*                                                                        */
5951 /*    DATE              NAME                      DESCRIPTION             */
5952 /*                                                                        */
5953 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5954 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
5955 /*                                            updated resource get APIs to*/
5956 /*                                            improve buffer bound check, */
5957 /*                                            resulting in version 6.1    */
5958 /*                                                                        */
5959 /**************************************************************************/
_nx_dns_process_cname_type(NX_DNS * dns_ptr,NX_PACKET * packet_ptr,UCHAR * data_ptr,UCHAR * record_buffer,UINT buffer_size,UINT * record_count)5960 static UINT _nx_dns_process_cname_type(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *data_ptr,
5961                                        UCHAR *record_buffer, UINT buffer_size, UINT *record_count)
5962 {
5963 UINT            response_type;
5964 UINT            name_size;
5965 UINT            status;
5966 #ifdef NX_DNS_CACHE_ENABLE
5967 UINT            size;
5968 ULONG           rr_ttl;
5969 #endif /* NX_DNS_CACHE_ENABLE  */
5970 
5971 #ifdef NX_DNS_CACHE_ENABLE
5972     /* Initialize the value.  */
5973     memset(temp_string_buffer, 0, NX_DNS_NAME_MAX + 1);
5974     memset(&temp_rr, 0, sizeof (NX_DNS_RR));
5975 
5976     /* First obtain the string. */
5977     size = _nx_dns_name_string_unencode(packet_ptr, data_ptr, temp_string_buffer, NX_DNS_NAME_MAX);
5978 
5979     /* Check the string correct.  */
5980     if(!size)
5981     {
5982 
5983         /* Return!  */
5984         return(NX_DNS_MALFORMED_PACKET);
5985     }
5986 
5987     /* Get the resource record ttl.  */
5988     status = _nx_dns_resource_time_to_live_get(data_ptr, packet_ptr, &rr_ttl);
5989     if (status)
5990     {
5991 
5992         /* Return!  */
5993         return(NX_DNS_MALFORMED_PACKET);
5994     }
5995 
5996 #endif /* NX_DNS_CACHE_ENABLE  */
5997 
5998     /* Process the server response and get it. */
5999     status = _nx_dns_resource_type_get(data_ptr, packet_ptr, &response_type);
6000     if (status)
6001     {
6002 
6003         /* Return!  */
6004         return(NX_DNS_MALFORMED_PACKET);
6005     }
6006 
6007     /* Verify this is what the DNS Client was requesting. */
6008     if(response_type == dns_ptr -> nx_dns_lookup_type)
6009     {
6010 
6011         /* Update the pointer to point at the resource data.  */
6012         data_ptr = _nx_dns_resource_data_address_get(data_ptr, packet_ptr);
6013         if (!data_ptr)
6014         {
6015             /* Return!  */
6016             return(NX_DNS_MALFORMED_PACKET);
6017         }
6018 
6019         /* Determine if there is room for the name - one less for NULL termination.  */
6020         name_size = _nx_dns_name_string_unencode(packet_ptr, data_ptr, record_buffer, buffer_size - 1);
6021         if (name_size)
6022         {
6023 
6024             /* Yes, got the canonical name successfully,and record the information!  */
6025 
6026             /* Update the count.  */
6027             (*record_count) ++;
6028 
6029 #ifdef NX_DNS_CACHE_ENABLE
6030             /* Set the resource record type.  */
6031             temp_rr.nx_dns_rr_type = NX_DNS_RR_TYPE_CNAME;
6032 
6033             /* Set the resource record ttl.  */
6034             temp_rr.nx_dns_rr_ttl = rr_ttl;
6035 
6036             /* Add the name string.  */
6037             status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_string_buffer, size, (VOID **)(&(temp_rr.nx_dns_rr_name)));
6038 
6039             /* Check the status.  */
6040             if(status)
6041                 return (NX_SUCCESS);
6042 
6043             /* Add the cname string.  */
6044             status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, record_buffer, name_size, (VOID **)(&(temp_rr.nx_dns_rr_rdata.nx_dns_rr_rdata_cname.nx_dns_rr_cname_name)));
6045 
6046             /* Check the status.  */
6047             if(status)
6048             {
6049                 _nx_dns_cache_delete_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_rr.nx_dns_rr_name, 0);
6050                 return (NX_SUCCESS);
6051             }
6052 
6053             /* Add the resource record.  */
6054             status = _nx_dns_cache_add_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr,  NX_NULL);
6055 
6056             /* Check the status.  */
6057             if(status)
6058             {
6059 
6060                 /* Delete the resource record.  */
6061                 _nx_dns_cache_delete_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr);
6062             }
6063 #endif /* NX_DNS_CACHE_ENABLE  */
6064 
6065             return(NX_SUCCESS);
6066         }
6067         else
6068         {
6069 
6070             /* Return !*/
6071             return(NX_DNS_MALFORMED_PACKET);
6072         }
6073     }
6074 
6075     /* If send A type query, should also process the CNAME + A type response.
6076        RFC1034, section3.6.2, page15 and RFC10.5 section 3.3.1, page14. */
6077     else if (dns_ptr -> nx_dns_lookup_type == NX_DNS_RR_TYPE_A)
6078     {
6079 
6080         /* Only get the A type message, skip the CNAME answer process,
6081            and return success to process next A type answer.
6082            The CNAME record to be implemented.  */
6083         return(NX_SUCCESS);
6084     }
6085 
6086     /* Error lookup response*/
6087     else
6088     {
6089         /* Return error status.  */
6090         return NX_DNS_MISMATCHED_RESPONSE;
6091     }
6092 
6093 }
6094 #endif
6095 
6096 
6097 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
6098 /**************************************************************************/
6099 /*                                                                        */
6100 /*  FUNCTION                                               RELEASE        */
6101 /*                                                                        */
6102 /*    _nx_dns_process_txt_type                             PORTABLE C     */
6103 /*                                                           6.1.4        */
6104 /*  AUTHOR                                                                */
6105 /*                                                                        */
6106 /*    Yuxin Zhou, Microsoft Corporation                                   */
6107 /*                                                                        */
6108 /*  DESCRIPTION                                                           */
6109 /*                                                                        */
6110 /*    This function process the TXT DNS type packet and record text string*/
6111 /*                                                                        */
6112 /*  INPUT                                                                 */
6113 /*                                                                        */
6114 /*    dns_ptr                               Pointer to DNS instance       */
6115 /*    packet_ptr                            Pointer to received packet    */
6116 /*    data_ptr                              Pointer to resource data      */
6117 /*                                            section                     */
6118 /*    record_buffer                         Buffer space for storing      */
6119 /*                                            the host text string        */
6120 /*    buffer_size                           Size of record_buffer.        */
6121 /*    record_count                          Record count                  */
6122 /*                                                                        */
6123 /*  OUTPUT                                                                */
6124 /*                                                                        */
6125 /*    status                                Completion status             */
6126 /*                                                                        */
6127 /*  CALLS                                                                 */
6128 /*                                                                        */
6129 /*    _nx_dns_resource_type_get             Get resource type             */
6130 /*    _nx_dns_resource_data_address_get     Get address of data           */
6131 /*                                                                        */
6132 /*  CALLED BY                                                             */
6133 /*                                                                        */
6134 /*    _nx_dns_response_process                                            */
6135 /*                                                                        */
6136 /*  RELEASE HISTORY                                                       */
6137 /*                                                                        */
6138 /*    DATE              NAME                      DESCRIPTION             */
6139 /*                                                                        */
6140 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6141 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
6142 /*                                            verified memcpy use cases,  */
6143 /*                                            updated resource get APIs to*/
6144 /*                                            improve buffer bound check, */
6145 /*                                            resulting in version 6.1    */
6146 /*  02-02-2021     Yuxin Zhou               Modified comment(s), improved */
6147 /*                                            packet length verification, */
6148 /*                                            resulting in version 6.1.4  */
6149 /*                                                                        */
6150 /**************************************************************************/
_nx_dns_process_txt_type(NX_DNS * dns_ptr,NX_PACKET * packet_ptr,UCHAR * data_ptr,UCHAR * record_buffer,UINT buffer_size,UINT * record_count)6151 static UINT _nx_dns_process_txt_type(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *data_ptr,
6152                                      UCHAR *record_buffer, UINT buffer_size, UINT *record_count)
6153 {
6154 UINT            response_type;
6155 UINT            text_data_length;
6156 UINT            status;
6157 #ifdef NX_DNS_CACHE_ENABLE
6158 UINT            size;
6159 ULONG           rr_ttl;
6160 #endif /* NX_DNS_CACHE_ENABLE  */
6161 
6162 #ifdef NX_DNS_CACHE_ENABLE
6163     /* Initialize the value.  */
6164     memset(temp_string_buffer, 0, NX_DNS_NAME_MAX + 1);
6165     memset(&temp_rr, 0, sizeof (NX_DNS_RR));
6166 
6167     /* First obtain the string. */
6168     size = _nx_dns_name_string_unencode(packet_ptr, data_ptr, temp_string_buffer, NX_DNS_NAME_MAX);
6169 
6170     /* Check the string correct.  */
6171     if(!size)
6172     {
6173 
6174         /* Return!  */
6175         return(NX_DNS_MALFORMED_PACKET);
6176     }
6177 
6178     /* Get the resource record ttl.  */
6179     status = _nx_dns_resource_time_to_live_get(data_ptr, packet_ptr, &rr_ttl);
6180     if (status)
6181     {
6182 
6183         /* Return!  */
6184         return(NX_DNS_MALFORMED_PACKET);
6185     }
6186 #else
6187     NX_PARAMETER_NOT_USED(packet_ptr);
6188 #endif /* NX_DNS_CACHE_ENABLE  */
6189 
6190     /* Process the server response and get it. */
6191     status = _nx_dns_resource_type_get(data_ptr, packet_ptr, &response_type);
6192     if (status)
6193     {
6194 
6195         /* Return!  */
6196         return(NX_DNS_MALFORMED_PACKET);
6197     }
6198 
6199     /* Verify this is what the DNS Client was requesting. */
6200     if (response_type != dns_ptr -> nx_dns_lookup_type)
6201     {
6202 
6203         /* No, this was not what the Client requested. Return error status.
6204         This should not happen so return error to the host application,
6205         might be a problem with the query or the server. */
6206         return NX_DNS_MISMATCHED_RESPONSE;
6207     }
6208 
6209     /* Update the pointer to point at the response data.  */
6210     data_ptr = _nx_dns_resource_data_address_get(data_ptr, packet_ptr);
6211     if (!data_ptr)
6212     {
6213 
6214         /* Return!  */
6215         return(NX_DNS_MALFORMED_PACKET);
6216     }
6217 
6218     /* Get the text resource data length.  */
6219     text_data_length = (UINT) (*data_ptr++);
6220 
6221     /* Judge the resource data buffer space.  */
6222     if ((text_data_length > buffer_size - 1) || ((data_ptr + text_data_length) > packet_ptr -> nx_packet_append_ptr))
6223     {
6224 
6225         /* Return error, and release the packet in repsonse*/
6226         return(NX_DNS_MALFORMED_PACKET);
6227 
6228     }
6229     else
6230     {
6231 
6232         /* Record the text string to the buffer.  */
6233         memcpy(&record_buffer[0],data_ptr,text_data_length); /* Use case of memcpy is verified. */
6234 
6235         /* Null terminate text.  */
6236         record_buffer[text_data_length] =  '\0';
6237 
6238         /* Update the count.  */
6239         (*record_count) ++;
6240 
6241 #ifdef NX_DNS_CACHE_ENABLE
6242         /* Set the resource record type.  */
6243         temp_rr.nx_dns_rr_type = NX_DNS_RR_TYPE_TXT;
6244 
6245         /* Set the resource record ttl.  */
6246         temp_rr.nx_dns_rr_ttl = rr_ttl;
6247 
6248         /* Add the name string.  */
6249         status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_string_buffer, size, (VOID **)(&(temp_rr.nx_dns_rr_name)));
6250 
6251         /* Check the status.  */
6252         if(status)
6253             return (NX_SUCCESS);
6254 
6255         /* Add the txt string.  */
6256         status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, record_buffer, text_data_length, (VOID **)(&(temp_rr.nx_dns_rr_rdata.nx_dns_rr_rdata_txt.nx_dns_rr_txt_data)));
6257 
6258         /* Check the status.  */
6259         if(status)
6260         {
6261             _nx_dns_cache_delete_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_rr.nx_dns_rr_name, 0);
6262             return (NX_SUCCESS);
6263         }
6264 
6265         /* Add the resource record.  */
6266         status = _nx_dns_cache_add_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr,  NX_NULL);
6267 
6268         /* Check the status.  */
6269         if(status)
6270         {
6271 
6272             /* Delete the resource record.  */
6273             _nx_dns_cache_delete_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr);
6274         }
6275 #endif /* NX_DNS_CACHE_ENABLE  */
6276 
6277         /* Yes; We're done! Return success!  */
6278         return(NX_SUCCESS);
6279     }
6280 }
6281 #endif
6282 
6283 
6284 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
6285 /**************************************************************************/
6286 /*                                                                        */
6287 /*  FUNCTION                                               RELEASE        */
6288 /*                                                                        */
6289 /*    _nx_dns_process_ns_type                              PORTABLE C     */
6290 /*                                                           6.1.3        */
6291 /*  AUTHOR                                                                */
6292 /*                                                                        */
6293 /*    Yuxin Zhou, Microsoft Corporation                                   */
6294 /*                                                                        */
6295 /*  DESCRIPTION                                                           */
6296 /*                                                                        */
6297 /*    This function process the NS record type.                           */
6298 /*                                                                        */
6299 /*  INPUT                                                                 */
6300 /*                                                                        */
6301 /*    dns_ptr                               Pointer to DNS instance       */
6302 /*    packet_ptr                            Pointer to received packet    */
6303 /*    data_ptr                              Pointer to resource data      */
6304 /*                                            section                     */
6305 /*    buffer_prepend_ptr                    Pointer to the starting       */
6306 /*                                            address of available buffer */
6307 /*    buffer_append_ptr                     Pointer to the ending address */
6308 /*                                            of available buffer         */
6309 /*    record_count                          The count of the name server  */
6310 /*                                                                        */
6311 /*  OUTPUT                                                                */
6312 /*                                                                        */
6313 /*    status                                Completion status             */
6314 /*                                                                        */
6315 /*  CALLS                                                                 */
6316 /*                                                                        */
6317 /*    _nx_dns_resource_type_get             Get resource type             */
6318 /*    _nx_dns_resource_data_address_get     Get address of data           */
6319 /*    _nx_dns_name_string_unencode          Unencode the name and get it. */
6320 /*    _nx_dns_name_size_calculate           Calculate size of name field  */
6321 /*    _nx_dns_resource_name_real_size_calculate                           */
6322 /*                                          Calculate real size of name   */
6323 /*                                                                        */
6324 /*  CALLED BY                                                             */
6325 /*                                                                        */
6326 /*    _nx_dns_response_process                                            */
6327 /*                                                                        */
6328 /*  RELEASE HISTORY                                                       */
6329 /*                                                                        */
6330 /*    DATE              NAME                      DESCRIPTION             */
6331 /*                                                                        */
6332 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6333 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
6334 /*                                            updated resource get APIs to*/
6335 /*                                            improve buffer bound check, */
6336 /*                                            resulting in version 6.1    */
6337 /*  12-31-2020     Yuxin Zhou               Modified comment(s), updated  */
6338 /*                                            input parameter of the API  */
6339 /*                                            to get the real size of     */
6340 /*                                            resource name,              */
6341 /*                                            resulting in version 6.1.3  */
6342 /*                                                                        */
6343 /**************************************************************************/
_nx_dns_process_ns_type(NX_DNS * dns_ptr,NX_PACKET * packet_ptr,UCHAR * data_ptr,UCHAR ** buffer_prepend_ptr,UCHAR ** buffer_append_ptr,UINT * record_count)6344 static UINT _nx_dns_process_ns_type(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *data_ptr,
6345                                     UCHAR **buffer_prepend_ptr, UCHAR **buffer_append_ptr,
6346                                     UINT *record_count)
6347 {
6348 NX_DNS_NS_ENTRY     *nx_dns_ns_entry_ptr;
6349 UINT                response_type;
6350 UINT                name_buffer_size;
6351 UINT                status;
6352 #ifdef NX_DNS_CACHE_ENABLE
6353 UINT                size;
6354 ULONG               rr_ttl;
6355 #endif /* NX_DNS_CACHE_ENABLE  */
6356 
6357 #ifdef NX_DNS_CACHE_ENABLE
6358     /* Initialize the value.  */
6359     memset(temp_string_buffer, 0, NX_DNS_NAME_MAX + 1);
6360     memset(&temp_rr, 0, sizeof (NX_DNS_RR));
6361 
6362     /* First obtain the string. */
6363     size = _nx_dns_name_string_unencode(packet_ptr, data_ptr, temp_string_buffer, NX_DNS_NAME_MAX);
6364 
6365     /* Check the string correct.  */
6366     if(!size)
6367     {
6368 
6369         /* Return!  */
6370         return(NX_DNS_MALFORMED_PACKET);
6371     }
6372 
6373     /* Get the resource record ttl.  */
6374     status = _nx_dns_resource_time_to_live_get(data_ptr, packet_ptr, &rr_ttl);
6375     if (status)
6376     {
6377 
6378         /* Return!  */
6379         return(NX_DNS_MALFORMED_PACKET);
6380     }
6381 #endif /* NX_DNS_CACHE_ENABLE  */
6382 
6383     /* Process the server response and get it. */
6384     status = _nx_dns_resource_type_get(data_ptr, packet_ptr, &response_type);
6385     if (status)
6386     {
6387 
6388         /* Return!  */
6389         return(NX_DNS_MALFORMED_PACKET);
6390     }
6391 
6392     /* Verify this is what the DNS Client was requesting. */
6393     if (response_type != dns_ptr -> nx_dns_lookup_type)
6394     {
6395 
6396         /* No, this was not what the Client requested. Return error status.
6397         This should not happen so return error to the host application,
6398         might be a problem with the query or the server. */
6399         return NX_DNS_MISMATCHED_RESPONSE;
6400     }
6401 
6402     /* Update the pointer to point at the resource data.  */
6403     data_ptr = _nx_dns_resource_data_address_get(data_ptr, packet_ptr);
6404     if (!data_ptr)
6405     {
6406         /* Return!  */
6407         return(NX_DNS_MALFORMED_PACKET);
6408     }
6409 
6410     /* Get the real size of the name, and set the name buffer size.*/
6411     name_buffer_size = _nx_dns_resource_name_real_size_calculate(packet_ptr -> nx_packet_prepend_ptr, (UINT)(data_ptr - packet_ptr -> nx_packet_prepend_ptr), packet_ptr -> nx_packet_length);
6412 
6413     /* Check the buffer space.  */
6414     if ((*buffer_append_ptr - name_buffer_size - 1 ) < (*buffer_prepend_ptr + sizeof(NX_DNS_NS_ENTRY)))
6415     {
6416 
6417         /* The buffer space is not enough.  */
6418         return(NX_DNS_NEED_MORE_RECORD_BUFFER);
6419     }
6420 
6421     /* Set the ns entry pointer.  */
6422     nx_dns_ns_entry_ptr = (NX_DNS_NS_ENTRY *)(*buffer_prepend_ptr);
6423 
6424     /* Initialize the  variables to NULL. */
6425     memset(nx_dns_ns_entry_ptr, 0, sizeof(NX_DNS_NS_ENTRY));
6426 
6427     /* Update the buffer pointer.*/
6428     *buffer_prepend_ptr += sizeof(NX_DNS_NS_ENTRY);
6429 
6430     /* Update the store pointer. include the null flag '\0'.  */
6431     *buffer_append_ptr -= (name_buffer_size + 1);
6432 
6433     /* Determine if there is room for the name - one less for NULL termination.  */
6434     if (_nx_dns_name_string_unencode(packet_ptr, data_ptr, *buffer_append_ptr, name_buffer_size))
6435     {
6436 
6437         /* Yes,record the name server successfully.  */
6438 
6439         /* Update the name server pointer.  */
6440         nx_dns_ns_entry_ptr -> nx_dns_ns_hostname_ptr = *buffer_append_ptr;
6441 
6442         /* Update the count of ns.  */
6443         (*record_count) ++;
6444 
6445 #ifdef NX_DNS_CACHE_ENABLE
6446         /* Set the resource record type.  */
6447         temp_rr.nx_dns_rr_type = NX_DNS_RR_TYPE_NS;
6448 
6449         /* Set the resource record ttl.  */
6450         temp_rr.nx_dns_rr_ttl = rr_ttl;
6451 
6452         /* Add the name string.  */
6453         status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_string_buffer, size, (VOID **)(&(temp_rr.nx_dns_rr_name)));
6454 
6455         /* Check the status.  */
6456         if(status)
6457             return (NX_SUCCESS);
6458 
6459         /* Add the ns string.  */
6460         status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, nx_dns_ns_entry_ptr -> nx_dns_ns_hostname_ptr, name_buffer_size, (VOID **)(&(temp_rr.nx_dns_rr_rdata.nx_dns_rr_rdata_ns.nx_dns_rr_ns_name)));
6461 
6462         /* Check the status.  */
6463         if(status)
6464         {
6465             _nx_dns_cache_delete_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_rr.nx_dns_rr_name, 0);
6466             return (NX_SUCCESS);
6467         }
6468 
6469         /* Add the resource record.  */
6470         status = _nx_dns_cache_add_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr,  NX_NULL);
6471 
6472         /* Check the status.  */
6473         if(status)
6474         {
6475 
6476             /* Delete the resource record.  */
6477             _nx_dns_cache_delete_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr);
6478         }
6479 #endif /* NX_DNS_CACHE_ENABLE  */
6480 
6481         return(NX_SUCCESS);
6482     }
6483     else
6484     {
6485         /* Ruturn.  */
6486         return(NX_DNS_MALFORMED_PACKET);
6487     }
6488 }
6489 #endif
6490 
6491 
6492 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
6493 /**************************************************************************/
6494 /*                                                                        */
6495 /*  FUNCTION                                               RELEASE        */
6496 /*                                                                        */
6497 /*    _nx_dns_process_mx_type                              PORTABLE C     */
6498 /*                                                           6.1.4        */
6499 /*  AUTHOR                                                                */
6500 /*                                                                        */
6501 /*    Yuxin Zhou, Microsoft Corporation                                   */
6502 /*                                                                        */
6503 /*  DESCRIPTION                                                           */
6504 /*                                                                        */
6505 /*    This function processes the MX record type.                         */
6506 /*                                                                        */
6507 /*  INPUT                                                                 */
6508 /*                                                                        */
6509 /*    dns_ptr                               Pointer to DNS instance       */
6510 /*    packet_ptr                            Pointer to received packet    */
6511 /*    data_ptr                              Pointer to resource data      */
6512 /*                                            section                     */
6513 /*    buffer_prepend_ptr                    Pointer to the starting       */
6514 /*                                            address of available buffer */
6515 /*    buffer_append_ptr                     Pointer to the ending address */
6516 /*                                            of available buffer         */
6517 /*    record_count                          The count of the mail exchange*/
6518 /*                                                                        */
6519 /*  OUTPUT                                                                */
6520 /*                                                                        */
6521 /*    status                                Completion status             */
6522 /*                                                                        */
6523 /*  CALLS                                                                 */
6524 /*                                                                        */
6525 /*    _nx_dns_resource_type_get             Get resource type             */
6526 /*    _nx_dns_resource_data_address_get     Get address of data           */
6527 /*    _nx_dns_name_string_unencode          Unencode the name and get it. */
6528 /*    _nx_dns_name_size_calculate           Calculate size of name field  */
6529 /*    _nx_dns_resource_name_real_size_calculate                           */
6530 /*                                          Calculate real size of name   */
6531 /*                                                                        */
6532 /*  CALLED BY                                                             */
6533 /*                                                                        */
6534 /*    _nx_dns_response_process                                            */
6535 /*                                                                        */
6536 /*  RELEASE HISTORY                                                       */
6537 /*                                                                        */
6538 /*    DATE              NAME                      DESCRIPTION             */
6539 /*                                                                        */
6540 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6541 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
6542 /*                                            verified memcpy use cases,  */
6543 /*                                            updated resource get APIs to*/
6544 /*                                            improve buffer bound check, */
6545 /*                                            resulting in version 6.1    */
6546 /*  12-31-2020     Yuxin Zhou               Modified comment(s), updated  */
6547 /*                                            input parameter of the API  */
6548 /*                                            to get the real size of     */
6549 /*                                            resource name,              */
6550 /*                                            resulting in version 6.1.3  */
6551 /*  02-02-2021     Yuxin Zhou               Modified comment(s), improved */
6552 /*                                            packet length verification, */
6553 /*                                            resulting in version 6.1.4  */
6554 /*                                                                        */
6555 /**************************************************************************/
_nx_dns_process_mx_type(NX_DNS * dns_ptr,NX_PACKET * packet_ptr,UCHAR * data_ptr,UCHAR ** buffer_prepend_ptr,UCHAR ** buffer_append_ptr,UINT * record_count)6556 static UINT _nx_dns_process_mx_type(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *data_ptr,
6557                                     UCHAR **buffer_prepend_ptr, UCHAR **buffer_append_ptr,
6558                                     UINT *record_count)
6559 {
6560 NX_DNS_MX_ENTRY     *nx_dns_mx_entry_ptr;
6561 UINT                response_type;
6562 UINT                name_buffer_size;
6563 USHORT              mx_preference;
6564 UINT                name_length;
6565 UINT                status;
6566 #ifdef NX_DNS_CACHE_ENABLE
6567 ULONG               rr_ttl;
6568 UINT                size;
6569 #endif /* NX_DNS_CACHE_ENABLE  */
6570 
6571 #ifdef NX_DNS_CACHE_ENABLE
6572     /* Initialize the value.  */
6573     memset(temp_string_buffer, 0, NX_DNS_NAME_MAX + 1);
6574     memset(&temp_rr, 0, sizeof (NX_DNS_RR));
6575 
6576     /* First obtain the string. */
6577     size = _nx_dns_name_string_unencode(packet_ptr, data_ptr, temp_string_buffer, NX_DNS_NAME_MAX);
6578 
6579     /* Check the string correct.  */
6580     if(!size)
6581     {
6582 
6583         /* Return!  */
6584         return(NX_DNS_MALFORMED_PACKET);
6585     }
6586 
6587     /* Get the resource record ttl.  */
6588     status = _nx_dns_resource_time_to_live_get(data_ptr, packet_ptr, &rr_ttl);
6589     if (status)
6590     {
6591 
6592         /* Return!  */
6593         return(NX_DNS_MALFORMED_PACKET);
6594     }
6595 #endif /* NX_DNS_CACHE_ENABLE  */
6596 
6597     /* Process the server response and get it. */
6598     status = _nx_dns_resource_type_get(data_ptr, packet_ptr, &response_type);
6599     if (status)
6600     {
6601 
6602         /* Return!  */
6603         return(NX_DNS_MALFORMED_PACKET);
6604     }
6605 
6606     /* Verify this is what the DNS Client was requesting. */
6607     if (response_type != dns_ptr -> nx_dns_lookup_type)
6608     {
6609 
6610         /* No, this was not what the Client requested. Return error status.
6611         This should not happen so return error to the host application,
6612         might be a problem with the query or the server. */
6613         return NX_DNS_MISMATCHED_RESPONSE;
6614     }
6615 
6616     /* Update the pointer to point at the resource data.  */
6617     data_ptr = _nx_dns_resource_data_address_get(data_ptr, packet_ptr);
6618     if ((!data_ptr) || ((data_ptr + sizeof(USHORT)) >= packet_ptr -> nx_packet_append_ptr))
6619     {
6620 
6621         /* Return!  */
6622         return(NX_DNS_MALFORMED_PACKET);
6623     }
6624 
6625     /* Get the preference data of the resource data.  */
6626     mx_preference = _nx_dns_network_to_short_convert(data_ptr);
6627 
6628     /* Skip the MX preference, and update the pointer to point at the mail exchange data.  */
6629     data_ptr += 2;
6630 
6631     /* Get the real size of the name, and set the name buffer size.*/
6632     name_buffer_size = _nx_dns_resource_name_real_size_calculate(packet_ptr -> nx_packet_prepend_ptr, (UINT)(data_ptr - packet_ptr -> nx_packet_prepend_ptr), packet_ptr -> nx_packet_length);
6633 
6634     /* Check the buffer space.  */
6635     if ((*buffer_append_ptr - name_buffer_size - 1 ) < (*buffer_prepend_ptr + sizeof(NX_DNS_MX_ENTRY)))
6636     {
6637 
6638         /* The buffer space is not enough.  */
6639         return(NX_DNS_NEED_MORE_RECORD_BUFFER);
6640     }
6641 
6642     /* Set the ns entry pointer.  */
6643     nx_dns_mx_entry_ptr = (NX_DNS_MX_ENTRY *)(*buffer_prepend_ptr);
6644 
6645     /* Initialize the  variables to NULL. */
6646     memset(nx_dns_mx_entry_ptr, 0, sizeof(NX_DNS_MX_ENTRY));
6647 
6648     /* Record the MX preference.  */
6649     nx_dns_mx_entry_ptr -> nx_dns_mx_preference = mx_preference;
6650 
6651     /* Update the buffer pointer.*/
6652     *buffer_prepend_ptr += sizeof(NX_DNS_MX_ENTRY);
6653 
6654     /* Update the store pointer. include the null flag '\0'.  */
6655     *buffer_append_ptr -= (name_buffer_size + 1);
6656 
6657     /* Determine if there is room for the name - one less for NULL termination.  */
6658     name_length = _nx_dns_name_string_unencode(packet_ptr, data_ptr, *buffer_append_ptr, name_buffer_size);
6659 
6660     /* Check the length.  */
6661     if (name_length)
6662     {
6663 
6664         /* Yes,record the name server successfully.  */
6665 
6666         /* Update the name server pointer.  */
6667         nx_dns_mx_entry_ptr -> nx_dns_mx_hostname_ptr = *buffer_append_ptr;
6668 
6669         /* Update the count of mx.  */
6670         (*record_count) ++;
6671 
6672 #ifdef NX_DNS_CACHE_ENABLE
6673 
6674         /* Check the temp buffer size.  */
6675         if (name_length + 2 > NX_DNS_NAME_MAX + 1)
6676             return (NX_SUCCESS);
6677 
6678         /* Set the resource record type.  */
6679         temp_rr.nx_dns_rr_type = NX_DNS_RR_TYPE_MX;
6680 
6681         /* Set the resource record ttl.  */
6682         temp_rr.nx_dns_rr_ttl = rr_ttl;
6683 
6684         /* Add the name string.  */
6685         status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_string_buffer, size, (VOID **)(&(temp_rr.nx_dns_rr_name)));
6686 
6687         /* Check the status.  */
6688         if(status)
6689             return (NX_SUCCESS);
6690 
6691         /* Set the MX rdata preference string.  */
6692         *(USHORT *)(&temp_string_buffer[0]) = mx_preference;
6693 
6694         /* Set the MX rdata string.  */
6695         memcpy((char*)&temp_string_buffer[2], (const char*)nx_dns_mx_entry_ptr -> nx_dns_mx_hostname_ptr, name_length); /* Use case of memcpy is verified. */
6696 
6697         /* Add the MX string.  */
6698         status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_string_buffer, name_length + 2, (VOID **)(&(temp_rr.nx_dns_rr_rdata.nx_dns_rr_rdata_mx.nx_dns_rr_mx_rdata)));
6699 
6700         /* Check the status.  */
6701         if(status)
6702         {
6703             _nx_dns_cache_delete_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_rr.nx_dns_rr_name, 0);
6704             return (NX_SUCCESS);
6705         }
6706 
6707         /* Add the resource record.  */
6708         status = _nx_dns_cache_add_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr,  NX_NULL);
6709 
6710         /* Check the status.  */
6711         if(status)
6712         {
6713 
6714             /* Delete the resource record.  */
6715             _nx_dns_cache_delete_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr);
6716         }
6717 #endif /* NX_DNS_CACHE_ENABLE  */
6718 
6719         return(NX_SUCCESS);
6720     }
6721     else
6722     {
6723 
6724         /* Return.  */
6725         return(NX_DNS_MALFORMED_PACKET);
6726     }
6727 }
6728 #endif
6729 
6730 
6731 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
6732 /**************************************************************************/
6733 /*                                                                        */
6734 /*  FUNCTION                                               RELEASE        */
6735 /*                                                                        */
6736 /*    _nx_dns_process_srv_type                             PORTABLE C     */
6737 /*                                                           6.1.4        */
6738 /*  AUTHOR                                                                */
6739 /*                                                                        */
6740 /*    Yuxin Zhou, Microsoft Corporation                                   */
6741 /*                                                                        */
6742 /*  DESCRIPTION                                                           */
6743 /*                                                                        */
6744 /*    This function process the DNS SRV record type.                      */
6745 /*                                                                        */
6746 /*  INPUT                                                                 */
6747 /*                                                                        */
6748 /*    dns_ptr                               Pointer to DNS instance       */
6749 /*    packet_ptr                            Pointer to received packet    */
6750 /*    data_ptr                              Pointer to resource data      */
6751 /*                                            section                     */
6752 /*    buffer_prepend_ptr                    Pointer to the starting       */
6753 /*                                            address of available buffer */
6754 /*    buffer_append_ptr                     Pointer to the ending address */
6755 /*                                            of available buffer         */
6756 /*    record_count                          The count of the services     */
6757 /*                                                                        */
6758 /*  OUTPUT                                                                */
6759 /*                                                                        */
6760 /*    status                                Completion status             */
6761 /*                                                                        */
6762 /*  CALLS                                                                 */
6763 /*                                                                        */
6764 /*    _nx_dns_resource_type_get             Get resource type             */
6765 /*    _nx_dns_resource_data_address_get     Get address of data           */
6766 /*    _nx_dns_name_string_unencode          Unencode the name and get it. */
6767 /*    _nx_dns_name_size_calculate           Calculate size of name field  */
6768 /*    _nx_dns_resource_name_real_size_calculate                           */
6769 /*                                          Calculate real size of name   */
6770 /*                                                                        */
6771 /*  CALLED BY                                                             */
6772 /*                                                                        */
6773 /*    _nx_dns_response_process                                            */
6774 /*                                                                        */
6775 /*  RELEASE HISTORY                                                       */
6776 /*                                                                        */
6777 /*    DATE              NAME                      DESCRIPTION             */
6778 /*                                                                        */
6779 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6780 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
6781 /*                                            verified memcpy use cases,  */
6782 /*                                            updated resource get APIs to*/
6783 /*                                            improve buffer bound check, */
6784 /*                                            resulting in version 6.1    */
6785 /*  12-31-2020     Yuxin Zhou               Modified comment(s), updated  */
6786 /*                                            input parameter of the API  */
6787 /*                                            to get the real size of     */
6788 /*                                            resource name,              */
6789 /*                                            resulting in version 6.1.3  */
6790 /*  02-02-2021     Yuxin Zhou               Modified comment(s), improved */
6791 /*                                            packet length verification, */
6792 /*                                            resulting in version 6.1.4  */
6793 /*                                                                        */
6794 /**************************************************************************/
_nx_dns_process_srv_type(NX_DNS * dns_ptr,NX_PACKET * packet_ptr,UCHAR * data_ptr,UCHAR ** buffer_prepend_ptr,UCHAR ** buffer_append_ptr,UINT * record_count)6795 static UINT _nx_dns_process_srv_type(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *data_ptr, UCHAR **buffer_prepend_ptr,
6796                                      UCHAR **buffer_append_ptr, UINT *record_count)
6797 {
6798 NX_DNS_SRV_ENTRY    *nx_dns_srv_entry_ptr;
6799 UINT                response_type;
6800 UINT                name_buffer_size;
6801 USHORT              srv_priority;
6802 USHORT              srv_weight;
6803 USHORT              srv_port_number;
6804 UINT                name_length;
6805 UINT                status;
6806 #ifdef NX_DNS_CACHE_ENABLE
6807 ULONG               rr_ttl;
6808 UINT                size;
6809 #endif /* NX_DNS_CACHE_ENABLE  */
6810 
6811 #ifdef NX_DNS_CACHE_ENABLE
6812     /* Initialize the value.  */
6813     memset(temp_string_buffer, 0, NX_DNS_NAME_MAX + 1);
6814     memset(&temp_rr, 0, sizeof (NX_DNS_RR));
6815 
6816     /* First obtain the string. */
6817     size = _nx_dns_name_string_unencode(packet_ptr, data_ptr, temp_string_buffer, NX_DNS_NAME_MAX);
6818 
6819     /* Check the string correct.  */
6820     if(!size)
6821     {
6822 
6823         /* Return!  */
6824         return(NX_DNS_MALFORMED_PACKET);
6825     }
6826 
6827     /* Get the resource record ttl.  */
6828     status =  _nx_dns_resource_time_to_live_get(data_ptr, packet_ptr, &rr_ttl);
6829     if (status)
6830     {
6831 
6832         /* Return!  */
6833         return(NX_DNS_MALFORMED_PACKET);
6834     }
6835 #endif /* NX_DNS_CACHE_ENABLE  */
6836 
6837     /* Process the server response and get it. */
6838     status = _nx_dns_resource_type_get(data_ptr, packet_ptr, &response_type);
6839     if (status)
6840     {
6841 
6842         /* Return!  */
6843         return(NX_DNS_MALFORMED_PACKET);
6844     }
6845 
6846     /* Verify this is what the DNS Client was requesting. */
6847     if (response_type != dns_ptr -> nx_dns_lookup_type)
6848     {
6849 
6850         /* No, this was not what the Client requested. Return error status.
6851         This should not happen so return error to the host application,
6852         might be a problem with the query or the server. */
6853         return NX_DNS_MISMATCHED_RESPONSE;
6854     }
6855 
6856     /* Update the pointer to point at the resource data.  */
6857     data_ptr = _nx_dns_resource_data_address_get(data_ptr, packet_ptr);
6858 
6859     /* Plus 6 for 2 bytes priority, 2 bytes weight and 2 bytes port. */
6860     if ((!data_ptr) || ((data_ptr + 6) >= packet_ptr -> nx_packet_append_ptr))
6861     {
6862 
6863         /* Return!  */
6864         return(NX_DNS_MALFORMED_PACKET);
6865     }
6866 
6867     /* Get the priority data of the resource data.  */
6868     srv_priority = _nx_dns_network_to_short_convert(data_ptr);
6869 
6870     /* Skip the SRV preference, and update the pointer to point at the weight data.  */
6871     data_ptr += 2;
6872 
6873     /* Get the weight data of the resource data.  */
6874     srv_weight = _nx_dns_network_to_short_convert(data_ptr);
6875 
6876     /* Skip the SRV weight, and update the pointer to point at the port data.  */
6877     data_ptr += 2;
6878 
6879     /* Get the port data of the resource data.  */
6880     srv_port_number = _nx_dns_network_to_short_convert(data_ptr);
6881 
6882     /* Skip the SRV port, and update the pointer to point at the target data.  */
6883     data_ptr += 2;
6884 
6885     /* Get the real size of the name, and set the name buffer size.*/
6886     name_buffer_size = _nx_dns_resource_name_real_size_calculate(packet_ptr -> nx_packet_prepend_ptr, (UINT)(data_ptr - packet_ptr -> nx_packet_prepend_ptr), packet_ptr -> nx_packet_length);
6887 
6888     /* Check the buffer space.  */
6889     if ((*buffer_append_ptr - name_buffer_size - 1 ) < (*buffer_prepend_ptr + sizeof(NX_DNS_MX_ENTRY)))
6890     {
6891 
6892         /* The buffer space is not enough.  */
6893         return(NX_DNS_NEED_MORE_RECORD_BUFFER);
6894     }
6895 
6896     /* Set the SRV entry pointer.  */
6897     nx_dns_srv_entry_ptr = (NX_DNS_SRV_ENTRY *)(*buffer_prepend_ptr);
6898 
6899     /* Initialize the  variables to NULL. */
6900     memset(nx_dns_srv_entry_ptr, 0, sizeof(NX_DNS_SRV_ENTRY));
6901 
6902     /* Record the SRV options data.  */
6903     nx_dns_srv_entry_ptr -> nx_dns_srv_priority = srv_priority;
6904     nx_dns_srv_entry_ptr -> nx_dns_srv_weight = srv_weight;
6905     nx_dns_srv_entry_ptr -> nx_dns_srv_port_number = srv_port_number;
6906 
6907     /* Update the buffer pointer.*/
6908     *buffer_prepend_ptr += sizeof(NX_DNS_SRV_ENTRY);
6909 
6910     /* Update the store pointer. include the null flag '\0'.  */
6911     *buffer_append_ptr -= (name_buffer_size + 1);
6912 
6913     /* Determine if there is room for the name - one less for NULL termination.  */
6914     name_length = _nx_dns_name_string_unencode(packet_ptr, data_ptr, *buffer_append_ptr, name_buffer_size);
6915 
6916     /* Check the length.  */
6917     if (name_length)
6918     {
6919 
6920         /* Yes,record the name server successfully.  */
6921 
6922         /* Update the name server pointer.  */
6923         nx_dns_srv_entry_ptr -> nx_dns_srv_hostname_ptr = *buffer_append_ptr;
6924 
6925         /* Update the count of srv.  */
6926         (*record_count) ++;
6927 
6928 #ifdef NX_DNS_CACHE_ENABLE
6929 
6930         /* Check the temp buffer size.  */
6931         if (name_length + 6 > NX_DNS_NAME_MAX + 1)
6932             return (NX_SUCCESS);
6933 
6934         /* Set the resource record type.  */
6935         temp_rr.nx_dns_rr_type = NX_DNS_RR_TYPE_SRV;
6936 
6937         /* Set the resource record ttl.  */
6938         temp_rr.nx_dns_rr_ttl = rr_ttl;
6939 
6940         /* Add the name string.  */
6941         status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_string_buffer, size, (VOID **)(&(temp_rr.nx_dns_rr_name)));
6942 
6943         /* Check the status.  */
6944         if(status)
6945             return (NX_SUCCESS);
6946 
6947         /* Set the SRV priority, weight and port number.  */
6948         *(USHORT *)(&temp_string_buffer[0]) = srv_priority;
6949         *(USHORT *)(&temp_string_buffer[2]) = srv_weight;
6950         *(USHORT *)(&temp_string_buffer[4]) = srv_port_number;
6951 
6952         /* Set the SRV rdata string.  */
6953         memcpy((char*)&temp_string_buffer[6], (const char*)nx_dns_srv_entry_ptr -> nx_dns_srv_hostname_ptr, name_length); /* Use case of memcpy is verified. */
6954 
6955         /* Add the srv string.  */
6956         status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_string_buffer, name_length + 6, (VOID **)(&(temp_rr.nx_dns_rr_rdata.nx_dns_rr_rdata_srv.nx_dns_rr_srv_rdata)));
6957 
6958         /* Check the status.  */
6959         if(status)
6960         {
6961             _nx_dns_cache_delete_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_rr.nx_dns_rr_name, 0);
6962             return (NX_SUCCESS);
6963         }
6964 
6965         /* Add the resource record.  */
6966         status = _nx_dns_cache_add_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr,  NX_NULL);
6967 
6968         /* Check the status.  */
6969         if(status)
6970         {
6971 
6972             /* Delete the resource record.  */
6973             _nx_dns_cache_delete_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr);
6974         }
6975 #endif /* NX_DNS_CACHE_ENABLE  */
6976 
6977         return(NX_SUCCESS);
6978     }
6979     else
6980     {
6981 
6982         /* Return.  */
6983         return(NX_DNS_MALFORMED_PACKET);
6984     }
6985 }
6986 #endif
6987 
6988 
6989 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
6990 /**************************************************************************/
6991 /*                                                                        */
6992 /*  FUNCTION                                               RELEASE        */
6993 /*                                                                        */
6994 /*    _nx_dns_process_soa_type                             PORTABLE C     */
6995 /*                                                           6.1.4        */
6996 /*  AUTHOR                                                                */
6997 /*                                                                        */
6998 /*    Yuxin Zhou, Microsoft Corporation                                   */
6999 /*                                                                        */
7000 /*  DESCRIPTION                                                           */
7001 /*                                                                        */
7002 /*    This function process the SOA record type.                          */
7003 /*                                                                        */
7004 /*  INPUT                                                                 */
7005 /*                                                                        */
7006 /*    dns_ptr                               Pointer to DNS instance       */
7007 /*    packet_ptr                            Pointer to received packet    */
7008 /*    data_ptr                              Pointer to resource data      */
7009 /*                                            section                     */
7010 /*    record_buffer                         Buffer space for storing      */
7011 /*                                            the data structures that    */
7012 /*                                            hold the SOA information    */
7013 /*    buffer_size                           Size of record_buffer.        */
7014 /*    record_count                          Record count                  */
7015 /*                                                                        */
7016 /*  OUTPUT                                                                */
7017 /*                                                                        */
7018 /*    status                                Completion status             */
7019 /*                                                                        */
7020 /*  CALLS                                                                 */
7021 /*                                                                        */
7022 /*    _nx_dns_resource_type_get             Get resource type             */
7023 /*    _nx_dns_resource_data_address_get     Get address of data           */
7024 /*    _nx_dns_name_string_unencode          Unencode the name and get it. */
7025 /*    _nx_dns_name_size_calculate           Calculate size of name field  */
7026 /*                                                                        */
7027 /*  CALLED BY                                                             */
7028 /*                                                                        */
7029 /*    _nx_dns_response_process                                            */
7030 /*                                                                        */
7031 /*  RELEASE HISTORY                                                       */
7032 /*                                                                        */
7033 /*    DATE              NAME                      DESCRIPTION             */
7034 /*                                                                        */
7035 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7036 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
7037 /*                                            verified memcpy use cases,  */
7038 /*                                            and verified buffer size,   */
7039 /*                                            updated resource get APIs to*/
7040 /*                                            improve buffer bound check, */
7041 /*                                            resulting in version 6.1    */
7042 /*  02-02-2021     Yuxin Zhou               Modified comment(s), improved */
7043 /*                                            packet length verification, */
7044 /*                                            resulting in version 6.1.4  */
7045 /*                                                                        */
7046 /**************************************************************************/
_nx_dns_process_soa_type(NX_DNS * dns_ptr,NX_PACKET * packet_ptr,UCHAR * data_ptr,UCHAR * record_buffer,UINT buffer_size,UINT * record_count)7047 static UINT _nx_dns_process_soa_type(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *data_ptr,
7048                                      UCHAR *record_buffer, UINT buffer_size, UINT *record_count)
7049 {
7050 NX_DNS_SOA_ENTRY    *nx_dns_soa_entry_ptr;
7051 UINT                response_type;
7052 ULONG               mname_length;
7053 ULONG               rname_length;
7054 UCHAR               *buffer_start;
7055 UINT                status;
7056 UINT                name_size;
7057 #ifdef NX_DNS_CACHE_ENABLE
7058 ULONG               name_length;
7059 ULONG               rr_ttl;
7060 #endif /* NX_DNS_CACHE_ENABLE  */
7061 
7062 #ifdef NX_DNS_CACHE_ENABLE
7063     /* Initialize the value.  */
7064     memset(temp_string_buffer, 0, NX_DNS_NAME_MAX + 1);
7065     memset(&temp_rr, 0, sizeof (NX_DNS_RR));
7066 
7067     /* First obtain the string. */
7068     name_length = _nx_dns_name_string_unencode(packet_ptr, data_ptr, temp_string_buffer, NX_DNS_NAME_MAX);
7069 
7070     /* Check the string correct.  */
7071     if(!name_length)
7072     {
7073 
7074         /* Return!  */
7075         return(NX_DNS_MALFORMED_PACKET);
7076     }
7077 
7078     /* Get the resource record ttl.  */
7079     status = _nx_dns_resource_time_to_live_get(data_ptr, packet_ptr, &rr_ttl);
7080     if (status)
7081     {
7082 
7083         /* Return!  */
7084         return(NX_DNS_MALFORMED_PACKET);
7085     }
7086 #endif /* NX_DNS_CACHE_ENABLE  */
7087 
7088     /* Process the server response and get it. */
7089     status = _nx_dns_resource_type_get(data_ptr, packet_ptr, &response_type);
7090     if (status)
7091     {
7092 
7093         /* Return!  */
7094         return(NX_DNS_MALFORMED_PACKET);
7095     }
7096 
7097     /* Verify this is what the DNS Client was requesting. */
7098     if (response_type != dns_ptr -> nx_dns_lookup_type)
7099     {
7100 
7101         /* No, this was not what the Client requested. Return error status.
7102         This should not happen so return error to the host application,
7103         might be a problem with the query or the server. */
7104         return NX_DNS_MISMATCHED_RESPONSE;
7105     }
7106 
7107     /* Set the SRV entry pointer.  */
7108     nx_dns_soa_entry_ptr = (NX_DNS_SOA_ENTRY *)(record_buffer);
7109 
7110     if (buffer_size <= sizeof(NX_DNS_SOA_ENTRY))
7111     {
7112         /* The buffer size is not enough.  */
7113         return(NX_DNS_MALFORMED_PACKET);
7114     }
7115 
7116     /* Update the start address of available buffer and the buffer size.  */
7117     buffer_start = record_buffer + sizeof(NX_DNS_SOA_ENTRY);
7118     buffer_size -= sizeof(NX_DNS_SOA_ENTRY);
7119 
7120     /* Update the pointer to point at the resource data.  */
7121     data_ptr = _nx_dns_resource_data_address_get(data_ptr, packet_ptr);
7122     if (!data_ptr)
7123     {
7124 
7125         /* Return!  */
7126         return(NX_DNS_MALFORMED_PACKET);
7127     }
7128     /* Get the primary name server and record it in buffer.  */
7129     mname_length = _nx_dns_name_string_unencode(packet_ptr, data_ptr, buffer_start, buffer_size - 1);
7130 
7131     /* Check the name length.  */
7132     if (mname_length)
7133     {
7134 
7135         /* Yes, got the primary name server successfully. set the mname ptr pointer.  */
7136         nx_dns_soa_entry_ptr -> nx_dns_soa_host_mname_ptr = buffer_start;
7137 
7138         /* Get name size */
7139         name_size = _nx_dns_name_size_calculate(data_ptr, packet_ptr);
7140 
7141         if (!name_size)
7142         {
7143             /* Return!  */
7144             return(NX_DNS_MALFORMED_PACKET);
7145         }
7146 
7147         /* Update the pointer to point at the rname data.  */
7148         data_ptr += name_size;
7149 
7150         /* Update the start address of available buffer and the buffer size. 1 is the Null terminate.  */
7151         buffer_start += mname_length + 1;
7152         buffer_size -= mname_length + 1;
7153     }
7154     else
7155     {
7156 
7157         /* Return !*/
7158         return(NX_DNS_MALFORMED_PACKET);
7159     }
7160 
7161     if (!buffer_size)
7162     {
7163         /* The buffer size is not enough.  */
7164         return(NX_DNS_MALFORMED_PACKET);
7165     }
7166 
7167     /* Get the responsible mail address and record it in buffer.  */
7168     rname_length = _nx_dns_name_string_unencode(packet_ptr, data_ptr, buffer_start, buffer_size - 1);
7169 
7170     if (rname_length)
7171     {
7172 
7173         /* Yes, got the primary name server successfully. set the mname ptr pointer.  */
7174         nx_dns_soa_entry_ptr -> nx_dns_soa_host_rname_ptr = buffer_start;
7175 
7176         /* Get name size */
7177         name_size = _nx_dns_name_size_calculate(data_ptr, packet_ptr);
7178 
7179         /* 20 bytes for 4 bytes serial, 4 bytes refresh, 4 bytes retry, 4 bytes expire and 4 bytes minmum. */
7180         if ((!name_size) || ((data_ptr + name_size + 20) > packet_ptr -> nx_packet_append_ptr))
7181         {
7182             /* Return!  */
7183             return(NX_DNS_MALFORMED_PACKET);
7184         }
7185 
7186         /* Update the pointer to point at the rname data.  */
7187         data_ptr += name_size;
7188 
7189         /* Update the start address of available buffer and the buffer size.1 is the Null terminate.  */
7190         buffer_start +=  rname_length + 1;
7191         buffer_size -= rname_length + 1;
7192     }
7193     else
7194     {
7195 
7196         /* Return !*/
7197         return(NX_DNS_MALFORMED_PACKET);
7198     }
7199 
7200     /* Get the serial number of the resource data.  */
7201     nx_dns_soa_entry_ptr -> nx_dns_soa_serial = _nx_dns_network_to_long_convert(data_ptr);
7202 
7203     /* Skip the serial number, and update the pointer to point at the refresh data.  */
7204     data_ptr += 4;
7205 
7206     /* Get the refresh number of the resource data.  */
7207     nx_dns_soa_entry_ptr -> nx_dns_soa_refresh = _nx_dns_network_to_long_convert(data_ptr);
7208 
7209     /* Skip the refresh number, and update the pointer to point at the retry data.  */
7210     data_ptr += 4;
7211 
7212     /* Get the retry number of the resource data.  */
7213     nx_dns_soa_entry_ptr -> nx_dns_soa_retry = _nx_dns_network_to_long_convert(data_ptr);
7214 
7215     /* Skip the retry number, and update the pointer to point at the expire data.  */
7216     data_ptr += 4;
7217 
7218     /* Get the expire number of the resource data.  */
7219     nx_dns_soa_entry_ptr -> nx_dns_soa_expire = _nx_dns_network_to_long_convert(data_ptr);
7220 
7221     /* Skip the expire number, and update the pointer to point at the minmum data.  */
7222     data_ptr += 4;
7223 
7224     /* Get the minmum number of the resource data.  */
7225     nx_dns_soa_entry_ptr -> nx_dns_soa_minmum = _nx_dns_network_to_long_convert(data_ptr);
7226 
7227     /* Skip the serial number, and update the pointer to point at the refresh data.  */
7228     data_ptr += 4;
7229 
7230     /* Update the count.  */
7231     (*record_count) ++;
7232 
7233 #ifdef NX_DNS_CACHE_ENABLE
7234 
7235     /* Check the temp buffer size.  */
7236     if (mname_length + rname_length + 22 > NX_DNS_NAME_MAX + 1)
7237         return (NX_SUCCESS);
7238 
7239     /* Set the resource record type.  */
7240     temp_rr.nx_dns_rr_type = NX_DNS_RR_TYPE_SOA;
7241 
7242     /* Set the resource record ttl.  */
7243     temp_rr.nx_dns_rr_ttl = rr_ttl;
7244 
7245     /* Add the name string.  */
7246     status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_string_buffer, name_length, (VOID **)(&(temp_rr.nx_dns_rr_name)));
7247 
7248     /* Check the status.  */
7249     if(status)
7250         return (NX_SUCCESS);
7251 
7252     /* Set the SOA MNAME.  */
7253     memcpy((char*)&temp_string_buffer[0], (char*)nx_dns_soa_entry_ptr -> nx_dns_soa_host_mname_ptr, mname_length); /* Use case of memcpy is verified. */
7254     temp_string_buffer[mname_length] = '\0';
7255 
7256     /* Set the SOA RNAME.  */
7257     memcpy((char*)&temp_string_buffer[mname_length + 1], (char*)nx_dns_soa_entry_ptr -> nx_dns_soa_host_rname_ptr, rname_length); /* Use case of memcpy is verified. */
7258     temp_string_buffer[mname_length + 1 + rname_length] = '\0';
7259 
7260     /* Set the SOA Serial, Refresh, Retry, Expire, Minmum.  */
7261     *(ULONG *)(&temp_string_buffer[mname_length + rname_length + 2]) = nx_dns_soa_entry_ptr -> nx_dns_soa_serial;
7262     *(ULONG *)(&temp_string_buffer[mname_length + rname_length + 6]) = nx_dns_soa_entry_ptr -> nx_dns_soa_refresh;
7263     *(ULONG *)(&temp_string_buffer[mname_length + rname_length + 10]) = nx_dns_soa_entry_ptr -> nx_dns_soa_retry;
7264     *(ULONG *)(&temp_string_buffer[mname_length + rname_length + 14]) = nx_dns_soa_entry_ptr -> nx_dns_soa_expire;
7265     *(ULONG *)(&temp_string_buffer[mname_length + rname_length + 18]) = nx_dns_soa_entry_ptr -> nx_dns_soa_minmum;
7266 
7267     /* Add the SOA string, mname length, '\0', rname length, '\0', Refresh, Retry, Expire, Minmum.  */
7268     status = _nx_dns_cache_add_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_string_buffer, mname_length + rname_length + 22, (VOID **)(&(temp_rr.nx_dns_rr_rdata.nx_dns_rr_rdata_soa.nx_dns_rr_soa_rdata)));
7269 
7270     /* Check the status.  */
7271     if(status)
7272     {
7273         _nx_dns_cache_delete_string(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, temp_rr.nx_dns_rr_name, 0);
7274         return (NX_SUCCESS);
7275     }
7276 
7277     /* Add the resource record.  */
7278     status = _nx_dns_cache_add_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr,  NX_NULL);
7279 
7280     /* Check the status.  */
7281     if(status)
7282     {
7283 
7284         /* Delete the resource record.  */
7285         _nx_dns_cache_delete_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, &temp_rr);
7286     }
7287 #endif /* NX_DNS_CACHE_ENABLE  */
7288 
7289     return (NX_SUCCESS);
7290 }
7291 #endif
7292 
7293 
7294 /**************************************************************************/
7295 /*                                                                        */
7296 /*  FUNCTION                                               RELEASE        */
7297 /*                                                                        */
7298 /*    _nxe_dns_host_by_address_get                        PORTABLE C      */
7299 /*                                                           6.1          */
7300 /*  AUTHOR                                                                */
7301 /*                                                                        */
7302 /*    Yuxin Zhou, Microsoft Corporation                                   */
7303 /*                                                                        */
7304 /*  DESCRIPTION                                                           */
7305 /*                                                                        */
7306 /*    This function checks for errors in the DNS get host by address      */
7307 /*    function call.                                                      */
7308 /*                                                                        */
7309 /*  INPUT                                                                 */
7310 /*                                                                        */
7311 /*    dns_ptr                               Pointer to DNS instance       */
7312 /*    ip_address                            IP address to get host name   */
7313 /*    host_name                             Destination for host name     */
7314 /*    host_name_buffer_size                 Buffer size of host name      */
7315 /*    wait_option                           Timeout value                 */
7316 /*                                                                        */
7317 /*  OUTPUT                                                                */
7318 /*                                                                        */
7319 /*    status                                Completion status             */
7320 /*                                                                        */
7321 /*  CALLS                                                                 */
7322 /*                                                                        */
7323 /*    _nx_dns_host_by_address_get           Actual DNS get host by address*/
7324 /*                                            function                    */
7325 /*                                                                        */
7326 /*  CALLED BY                                                             */
7327 /*                                                                        */
7328 /*    Application Code                                                    */
7329 /*                                                                        */
7330 /*  RELEASE HISTORY                                                       */
7331 /*                                                                        */
7332 /*    DATE              NAME                      DESCRIPTION             */
7333 /*                                                                        */
7334 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7335 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7336 /*                                            resulting in version 6.1    */
7337 /*                                                                        */
7338 /**************************************************************************/
_nxe_dns_host_by_address_get(NX_DNS * dns_ptr,ULONG host_address,UCHAR * host_name,UINT host_name_buffer_size,ULONG wait_option)7339 UINT  _nxe_dns_host_by_address_get(NX_DNS *dns_ptr, ULONG host_address, UCHAR *host_name, UINT host_name_buffer_size, ULONG wait_option)
7340 {
7341 
7342 UINT    status;
7343 
7344     /* Check for invalid input pointers.  */
7345     if ((dns_ptr == NX_NULL) || (host_name == NX_NULL))
7346         return(NX_PTR_ERROR);
7347 
7348     /* Check for invalid non pointer input.  */
7349     if (!host_address || dns_ptr -> nx_dns_id != NX_DNS_ID || (host_name_buffer_size == 0))
7350         return(NX_DNS_PARAM_ERROR);
7351 
7352     /* Check for appropriate caller.  */
7353     NX_THREADS_ONLY_CALLER_CHECKING
7354 
7355     /* Call actual DNS get host by address service.  */
7356     status =  _nx_dns_host_by_address_get(dns_ptr, host_address, host_name, host_name_buffer_size, wait_option);
7357 
7358     /* Return status.  */
7359     return(status);
7360 }
7361 
7362 
7363 /**************************************************************************/
7364 /*                                                                        */
7365 /*  FUNCTION                                               RELEASE        */
7366 /*                                                                        */
7367 /*    _nx_dns_host_by_address_get                         PORTABLE C      */
7368 /*                                                           6.1          */
7369 /*  AUTHOR                                                                */
7370 /*                                                                        */
7371 /*    Yuxin Zhou, Microsoft Corporation                                   */
7372 /*                                                                        */
7373 /*  DESCRIPTION                                                           */
7374 /*                                                                        */
7375 /*    This function uses DNS to get the host name associated with the     */
7376 /*    specified IP address.  If a host name cannot be found, this         */
7377 /*    routine returns zero for the string size to signal an error.        */
7378 /*                                                                        */
7379 /*  INPUT                                                                 */
7380 /*                                                                        */
7381 /*    dns_ptr                               Pointer to DNS instance       */
7382 /*    dns_address                           DNS server IP address         */
7383 /*    host_name                             Destination for host name     */
7384 /*    host_name_buffer_size                 Buffer size for host name     */
7385 /*    wait_option                           Timeout value                 */
7386 /*                                                                        */
7387 /*  OUTPUT                                                                */
7388 /*                                                                        */
7389 /*    status                                Completion status             */
7390 /*                                                                        */
7391 /*  CALLS                                                                 */
7392 /*                                                                        */
7393 /*    _nx_dns_host_by_address_get_internal  Actual host address           */
7394 /*                                               get service              */
7395 /*                                                                        */
7396 /*  CALLED BY                                                             */
7397 /*                                                                        */
7398 /*    Application Code                                                    */
7399 /*                                                                        */
7400 /*  RELEASE HISTORY                                                       */
7401 /*                                                                        */
7402 /*    DATE              NAME                      DESCRIPTION             */
7403 /*                                                                        */
7404 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7405 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7406 /*                                            resulting in version 6.1    */
7407 /*                                                                        */
7408 /**************************************************************************/
_nx_dns_host_by_address_get(NX_DNS * dns_ptr,ULONG dns_address,UCHAR * host_name,UINT host_name_buffer_size,ULONG wait_option)7409 UINT  _nx_dns_host_by_address_get(NX_DNS *dns_ptr, ULONG dns_address, UCHAR *host_name, UINT host_name_buffer_size, ULONG wait_option)
7410 {
7411 
7412 #ifndef NX_DISABLE_IPV4
7413 NXD_ADDRESS host_address;
7414 
7415 
7416     /* Check for null address input. */
7417     if (dns_address == 0)
7418     {
7419         return NX_DNS_BAD_ADDRESS_ERROR;
7420     }
7421 
7422     /* Construct an IP address structure, and fill in IPv4 address information. */
7423     host_address.nxd_ip_version = NX_IP_VERSION_V4;
7424     host_address.nxd_ip_address.v4 = dns_address;
7425 
7426     /* Invoke the real function. */
7427     return(_nx_dns_host_by_address_get_internal(dns_ptr, &host_address, host_name, host_name_buffer_size, wait_option));
7428 #else
7429     NX_PARAMETER_NOT_USED(dns_ptr);
7430     NX_PARAMETER_NOT_USED(dns_address);
7431     NX_PARAMETER_NOT_USED(host_name);
7432     NX_PARAMETER_NOT_USED(host_name_buffer_size);
7433     NX_PARAMETER_NOT_USED(wait_option);
7434 
7435     return(NX_NOT_SUPPORTED);
7436 #endif /* NX_DISABLE_IPV4 */
7437 }
7438 
7439 
7440 /**************************************************************************/
7441 /*                                                                        */
7442 /*  FUNCTION                                               RELEASE        */
7443 /*                                                                        */
7444 /*    _nxde_dns_host_by_address_get                       PORTABLE C      */
7445 /*                                                           6.1          */
7446 /*  AUTHOR                                                                */
7447 /*                                                                        */
7448 /*    Yuxin Zhou, Microsoft Corporation                                   */
7449 /*                                                                        */
7450 /*  DESCRIPTION                                                           */
7451 /*                                                                        */
7452 /*    This function checks for errors in the NetX duo compatible DNS get  */
7453 /*    host by address function call.                                      */
7454 /*                                                                        */
7455 /*  INPUT                                                                 */
7456 /*                                                                        */
7457 /*    dns_ptr                               Pointer to DNS instance       */
7458 /*    ip_address                            IP address to get host name   */
7459 /*    host_name_ptr                         Destination for host name     */
7460 /*    host_name_buffer_size                 Size of host name buffer      */
7461 /*    wait_option                           Timeout value                 */
7462 /*                                                                        */
7463 /*  OUTPUT                                                                */
7464 /*                                                                        */
7465 /*    status                                Completion status             */
7466 /*                                                                        */
7467 /*  CALLS                                                                 */
7468 /*                                                                        */
7469 /*    _nxd_dns_host_by_address_get          Actual DNS get host by address*/
7470 /*                                            function                    */
7471 /*                                                                        */
7472 /*  CALLED BY                                                             */
7473 /*                                                                        */
7474 /*    Application Code                                                    */
7475 /*                                                                        */
7476 /*  RELEASE HISTORY                                                       */
7477 /*                                                                        */
7478 /*    DATE              NAME                      DESCRIPTION             */
7479 /*                                                                        */
7480 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7481 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7482 /*                                            resulting in version 6.1    */
7483 /*                                                                        */
7484 /**************************************************************************/
_nxde_dns_host_by_address_get(NX_DNS * dns_ptr,NXD_ADDRESS * host_address,UCHAR * host_name_ptr,UINT host_name_buffer_size,ULONG wait_option)7485 UINT  _nxde_dns_host_by_address_get(NX_DNS *dns_ptr, NXD_ADDRESS *host_address, UCHAR *host_name_ptr, UINT host_name_buffer_size, ULONG wait_option)
7486 {
7487 
7488 UINT    status;
7489 
7490     /* Check for invalid input pointers.  */
7491     if ((dns_ptr == NX_NULL) ||  (host_name_ptr == NX_NULL) || (host_address == NX_NULL))
7492         return(NX_PTR_ERROR);
7493 
7494     /* Check for invalid host name size.  */
7495     if (dns_ptr -> nx_dns_id != NX_DNS_ID || (host_name_buffer_size == 0))
7496         return(NX_DNS_PARAM_ERROR);
7497 
7498     /* Check for appropriate caller.  */
7499     NX_THREADS_ONLY_CALLER_CHECKING
7500 
7501     /* Call actual DNS service get host IP address by host name.  */
7502     status =  _nxd_dns_host_by_address_get(dns_ptr, host_address, host_name_ptr, host_name_buffer_size, wait_option);
7503 
7504     /* Return status.  */
7505     return(status);
7506 }
7507 
7508 
7509 /**************************************************************************/
7510 /*                                                                        */
7511 /*  FUNCTION                                               RELEASE        */
7512 /*                                                                        */
7513 /*    _nxd_dns_host_by_address_get                        PORTABLE C      */
7514 /*                                                           6.1          */
7515 /*  AUTHOR                                                                */
7516 /*                                                                        */
7517 /*    Yuxin Zhou, Microsoft Corporation                                   */
7518 /*                                                                        */
7519 /*  DESCRIPTION                                                           */
7520 /*                                                                        */
7521 /*    This function uses DNS to get the host name associated with the     */
7522 /*    specified IP address.  If a host name cannot be found, this         */
7523 /*    routine returns zero for the string size to signal an error.        */
7524 /*                                                                        */
7525 /*  INPUT                                                                 */
7526 /*                                                                        */
7527 /*    dns_ptr                               Pointer to DNS instance       */
7528 /*    host_address_ptr                      NXD_ADDRESS instance with the */
7529 /*                                            IP address to search for    */
7530 /*                                            host name                   */
7531 /*    host_name_ptr                         Destination for host name     */
7532 /*    host_name_buffer_size                 Buffer size for host name     */
7533 /*    wait_option                           Timeout value                 */
7534 /*                                                                        */
7535 /*  OUTPUT                                                                */
7536 /*                                                                        */
7537 /*    status                                Completion status             */
7538 /*                                                                        */
7539 /*  CALLS                                                                 */
7540 /*                                                                        */
7541 /*    _nxd_dns_build_an_ipv6_question_string Create the DNS query         */
7542 /*    _nx_dns_send_query_by_address          Create and transmit the DNS  */
7543 /*                                             query packet               */
7544 /*    tx_mutex_get                          Get DNS protection mutex      */
7545 /*    tx_mutex_put                          Release DNS protection mutex  */
7546 /*                                                                        */
7547 /*  CALLED BY                                                             */
7548 /*                                                                        */
7549 /*    Application Code                                                    */
7550 /*                                                                        */
7551 /*  RELEASE HISTORY                                                       */
7552 /*                                                                        */
7553 /*    DATE              NAME                      DESCRIPTION             */
7554 /*                                                                        */
7555 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7556 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7557 /*                                            resulting in version 6.1    */
7558 /*                                                                        */
7559 /**************************************************************************/
_nxd_dns_host_by_address_get(NX_DNS * dns_ptr,NXD_ADDRESS * host_address_ptr,UCHAR * host_name_ptr,UINT host_name_buffer_size,ULONG wait_option)7560 UINT  _nxd_dns_host_by_address_get(NX_DNS *dns_ptr, NXD_ADDRESS *host_address_ptr, UCHAR *host_name_ptr,
7561                                    UINT host_name_buffer_size, ULONG wait_option)
7562 {
7563 
7564 
7565     /* Invoke the real function. */
7566     return(_nx_dns_host_by_address_get_internal(dns_ptr, host_address_ptr, host_name_ptr, host_name_buffer_size, wait_option));
7567 }
7568 
7569 
7570 /**************************************************************************/
7571 /*                                                                        */
7572 /*  FUNCTION                                               RELEASE        */
7573 /*                                                                        */
7574 /*    _nx_dns_host_by_address_get_internal                PORTABLE C      */
7575 /*                                                           6.1.4        */
7576 /*  AUTHOR                                                                */
7577 /*                                                                        */
7578 /*    Yuxin Zhou, Microsoft Corporation                                   */
7579 /*                                                                        */
7580 /*  DESCRIPTION                                                           */
7581 /*                                                                        */
7582 /*    This function uses DNS to get the host name associated with the     */
7583 /*    specified IP address.  If a host name cannot be found, this         */
7584 /*    routine returns zero for the string size to signal an error.        */
7585 /*                                                                        */
7586 /*  INPUT                                                                 */
7587 /*                                                                        */
7588 /*    dns_ptr                               Pointer to DNS instance       */
7589 /*    host_address_ptr                      Pointer to host address       */
7590 /*    host_name_ptr                         Destination for host name     */
7591 /*    host_name_buffer_size                 Buffer size for host name     */
7592 /*    wait_option                           Timeout value                 */
7593 /*                                                                        */
7594 /*  OUTPUT                                                                */
7595 /*                                                                        */
7596 /*    status                                Completion status             */
7597 /*                                                                        */
7598 /*  CALLS                                                                 */
7599 /*                                                                        */
7600 /*    _nxd_dns_build_an_ipv6_question_string Create the DNS query         */
7601 /*    _nx_dns_send_query_by_address          Create and transmit the DNS  */
7602 /*                                             query packet               */
7603 /*    tx_mutex_get                          Get DNS protection mutex      */
7604 /*    tx_mutex_put                          Release DNS protection mutex  */
7605 /*    nx_udp_socket_bind                    Bind DNS UDP socket to port   */
7606 /*    nx_udp_socket_unbind                  Unbind DNS UDP socket         */
7607 /*                                                                        */
7608 /*  CALLED BY                                                             */
7609 /*                                                                        */
7610 /*    Application Code                                                    */
7611 /*                                                                        */
7612 /*  RELEASE HISTORY                                                       */
7613 /*                                                                        */
7614 /*    DATE              NAME                      DESCRIPTION             */
7615 /*                                                                        */
7616 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7617 /*  09-30-2020     Yuxin Zhou               Modified comment(s), corrected*/
7618 /*                                            the timeout of first query, */
7619 /*                                            verified memcpy use cases,  */
7620 /*                                            resulting in version 6.1    */
7621 /*  02-02-2021     Yuxin Zhou               Modified comment(s), and      */
7622 /*                                            randomized the source port, */
7623 /*                                            resulting in version 6.1.4  */
7624 /*                                                                        */
7625 /**************************************************************************/
_nx_dns_host_by_address_get_internal(NX_DNS * dns_ptr,NXD_ADDRESS * host_address_ptr,UCHAR * host_name_ptr,UINT host_name_buffer_size,ULONG wait_option)7626 static UINT  _nx_dns_host_by_address_get_internal(NX_DNS *dns_ptr, NXD_ADDRESS *host_address_ptr, UCHAR *host_name_ptr,
7627                                                   UINT host_name_buffer_size, ULONG wait_option)
7628 {
7629 
7630 UINT        retries;
7631 UINT        status;
7632 UCHAR       ip_question[NX_DNS_IP_LOOKUP_SIZE + 1];
7633 UINT        i;
7634 #ifndef NX_DISABLE_IPV4
7635 UCHAR       dot = '.';
7636 UINT        value;
7637 UINT        length, index;
7638 #endif /* NX_DISABLE_IPV4 */
7639 
7640 
7641     /* Check for an invalid address type. */
7642     if ((host_address_ptr -> nxd_ip_version != NX_IP_VERSION_V4) &&
7643         (host_address_ptr -> nxd_ip_version != NX_IP_VERSION_V6))
7644     {
7645 
7646         return NX_DNS_INVALID_ADDRESS_TYPE;
7647     }
7648 
7649     if (host_address_ptr -> nxd_ip_version == NX_IP_VERSION_V6)
7650 #ifdef FEATURE_NX_IPV6
7651     {
7652 
7653         /* Check for Null address input. */
7654         if (CHECK_UNSPECIFIED_ADDRESS(&(host_address_ptr ->nxd_ip_address.v6[0])))
7655         {
7656             return NX_DNS_BAD_ADDRESS_ERROR;
7657         }
7658     }
7659 #else
7660     {
7661         /* IPv6 not supported. */
7662         return NX_DNS_INVALID_ADDRESS_TYPE;
7663     }
7664 #endif
7665     else if (host_address_ptr -> nxd_ip_version == NX_IP_VERSION_V4)
7666     {
7667 
7668 #ifndef NX_DISABLE_IPV4
7669         /* Check for Null address input. */
7670         if (host_address_ptr -> nxd_ip_address.v4== 0)
7671 #endif /* NX_DISABLE_IPV4 */
7672         {
7673 
7674             return NX_DNS_BAD_ADDRESS_ERROR;
7675         }
7676     }
7677     else
7678     {
7679         return NX_DNS_INVALID_ADDRESS_TYPE;
7680     }
7681 
7682     /* Check for an invalid buffer size. */
7683     if (host_name_buffer_size == 0)
7684     {
7685         return(NX_DNS_PARAM_ERROR);
7686     }
7687 
7688     /* Clear the host name buffer.  */
7689     memset(host_name_ptr, 0, sizeof(host_name_buffer_size));
7690 
7691     /* Get the protection mutex to make sure no other thread interferes.  */
7692     status =  tx_mutex_get(&(dns_ptr -> nx_dns_mutex), wait_option);
7693 
7694     /* Check status.  */
7695     if (status != TX_SUCCESS)
7696     {
7697 
7698         /* The mutex was not granted in the time specified.  Return an error.  */
7699         return(NX_DNS_TIMEOUT);
7700     }
7701 
7702     /* Determine if there is at least one DNS server. Is the first slot empty?  */
7703     if (dns_ptr -> nx_dns_server_ip_array[0].nxd_ip_version == 0)
7704     {
7705 
7706         /* No, this means the list is empty. Release the DNS Client lock. */
7707         tx_mutex_put(&dns_ptr -> nx_dns_mutex);
7708 
7709         /* At least one DNS server is required - return an error.  */
7710         return(NX_DNS_NO_SERVER);
7711     }
7712 
7713     /* Is this an IPv6 address we are looking up? */
7714     if (host_address_ptr -> nxd_ip_version == NX_IP_VERSION_V6)
7715     {
7716 
7717 #ifndef FEATURE_NX_IPV6
7718         /* Release the mutex and return. */
7719         tx_mutex_put(&dns_ptr -> nx_dns_mutex);
7720 
7721         return NX_DNS_IPV6_NOT_SUPPORTED;
7722 #else
7723         /* Yes; build the PTR query string containing an IPv6 address. */
7724         _nxd_dns_build_an_ipv6_question_string(host_address_ptr, &ip_question[0], NX_DNS_IP_LOOKUP_SIZE);
7725 #endif
7726     }
7727     else
7728     {
7729 
7730 #ifndef NX_DISABLE_IPV4
7731         memset(ip_question, 0, NX_DNS_IP_LOOKUP_SIZE);
7732         value = host_address_ptr -> nxd_ip_address.v4 & 0xff;
7733         length = _nx_dns_number_to_ascii_convert(value, (CHAR *)&ip_question[0]);
7734         ip_question[length++] = dot;
7735         index = length;
7736 
7737         value = (host_address_ptr -> nxd_ip_address.v4 >> 8) & 0xff;
7738         length += _nx_dns_number_to_ascii_convert(value, (CHAR *)&ip_question[index]);
7739         ip_question[length++] = dot;
7740         index = length;
7741 
7742         value = (host_address_ptr -> nxd_ip_address.v4 >> 16) & 0xff;
7743         length += _nx_dns_number_to_ascii_convert(value, (CHAR *)&ip_question[index]) ;
7744         ip_question[length++] = dot;
7745         index = length;
7746 
7747         value = (host_address_ptr -> nxd_ip_address.v4 >> 24) & 0xff;
7748         length += _nx_dns_number_to_ascii_convert(value, (CHAR *)&ip_question[index]);
7749         ip_question[length++] = dot;
7750         index = length;
7751 
7752         memcpy(&ip_question[length], &lookup_end[0], 12); /* Use case of memcpy is verified. */
7753 #else
7754         /* Release the mutex and return. */
7755         tx_mutex_put(&dns_ptr -> nx_dns_mutex);
7756 
7757         return NX_DNS_BAD_ADDRESS_ERROR;
7758 #endif /* NX_DISABLE_IPV4 */
7759     }
7760 
7761 #ifdef NX_DNS_CACHE_ENABLE
7762 
7763     /* Find the answer in local cache.  */
7764     if(_nx_dns_cache_find_answer(dns_ptr, dns_ptr -> nx_dns_cache, ip_question, NX_DNS_RR_TYPE_PTR, host_name_ptr, host_name_buffer_size, NX_NULL) == NX_DNS_SUCCESS)
7765     {
7766 
7767         /* Release the mutex. */
7768         tx_mutex_put(&dns_ptr -> nx_dns_mutex);
7769 
7770         return (NX_DNS_SUCCESS);
7771     }
7772 #endif /*NX_DNS_CACHE_ENABLE.  */
7773 
7774     /* Bind the UDP socket to random port for each query.  */
7775     status =  nx_udp_socket_bind(&(dns_ptr -> nx_dns_socket), NX_ANY_PORT, TX_WAIT_FOREVER);
7776 
7777     /* Check status.  */
7778     if (status != TX_SUCCESS)
7779     {
7780 
7781         /* Release the DNS Client lock.  */
7782         tx_mutex_put(&dns_ptr -> nx_dns_mutex);
7783         return(status);
7784     }
7785 
7786     /* Limit the timeout to NX_DNS_MAX_RETRANS_TIMEOUT.  */
7787     if (wait_option > NX_DNS_MAX_RETRANS_TIMEOUT)
7788     {
7789         wait_option = NX_DNS_MAX_RETRANS_TIMEOUT;
7790     }
7791 
7792     /* Keep sending queries to all DNS Servers till the retry count expires.  */
7793     for (retries = 0; retries < dns_ptr -> nx_dns_retries; retries++)
7794     {
7795 
7796         /* The client should try other servers and server addresses before repeating a query to a specific address of a server.
7797            RFC1035, Section4.2.1 UDP usage, Page32.  */
7798         /*  Attempt host name resolution from each DNS server till one if found. */
7799         for (i = 0; (i < NX_DNS_MAX_SERVERS) && (dns_ptr -> nx_dns_server_ip_array[i].nxd_ip_version != 0); i ++)
7800         {
7801 
7802             /* Send the PTR/reverse lookup query. */
7803             status = _nx_dns_send_query_by_address(dns_ptr, &dns_ptr -> nx_dns_server_ip_array[i], &ip_question[0],
7804                                                    host_name_ptr, host_name_buffer_size, wait_option);
7805 
7806             /* Check the status.  */
7807             if (status == NX_SUCCESS)
7808             {
7809 
7810                 /* Unbind the socket.  */
7811                 nx_udp_socket_unbind(&(dns_ptr -> nx_dns_socket));
7812 
7813                 /* Release the mutex */
7814                 tx_mutex_put(&dns_ptr -> nx_dns_mutex);
7815 
7816                 /* Yes, have done, just return success.  */
7817                 return NX_SUCCESS;
7818             }
7819         }
7820 
7821         /* Timed out for querying all DNS servers in this cycle, double the timeout, limited to NX_DNS_MAX_RETRANS_TIMEOUT.  */
7822         if (wait_option <= (NX_DNS_MAX_RETRANS_TIMEOUT >> 1))
7823             wait_option = (wait_option << 1);
7824         else
7825             wait_option = NX_DNS_MAX_RETRANS_TIMEOUT;
7826     }
7827 
7828     /* Unbind the socket.  */
7829     nx_udp_socket_unbind(&(dns_ptr -> nx_dns_socket));
7830 
7831     /* Release protection.  */
7832     tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
7833 
7834     /* Failed on all servers, return DNS lookup failed status.  */
7835     return(NX_DNS_QUERY_FAILED);
7836 }
7837 
7838 
7839 /**************************************************************************/
7840 /*                                                                        */
7841 /*  FUNCTION                                               RELEASE        */
7842 /*                                                                        */
7843 /*    _nx_dns_new_packet_create                           PORTABLE C      */
7844 /*                                                           6.1.4        */
7845 /*  AUTHOR                                                                */
7846 /*                                                                        */
7847 /*    Yuxin Zhou, Microsoft Corporation                                   */
7848 /*                                                                        */
7849 /*  DESCRIPTION                                                           */
7850 /*                                                                        */
7851 /*    This routine fills in the header and question in a DNS queyr packet,*/
7852 /*    and updates the size and the question count fields in the header.   */
7853 /*                                                                        */
7854 /*  INPUT                                                                 */
7855 /*                                                                        */
7856 /*    dns_ptr                               Pointer to DNS instance       */
7857 /*    packet_ptr                            Packet allocated for message  */
7858 /*    name                                  Question e.g. host name       */
7859 /*    type                                  DNS message type e.g. A, AAAA */
7860 /*                                                                        */
7861 /*  OUTPUT                                                                */
7862 /*                                                                        */
7863 /*    NX_DNS_PACKET_CREATE_ERROR            Error creating header or query*/
7864 /*    NX_SUCCESS                            Successful compltion          */
7865 /*                                                                        */
7866 /*  CALLS                                                                 */
7867 /*                                                                        */
7868 /*    _nx_dns_header_create                 Create a DNS header           */
7869 /*    _nx_dns_question_add                  Add the DNS question to packet*/
7870 /*    nx_packet_allocate                    Allocate a new DNS packet     */
7871 /*    nx_packet_release                     Release DNS packet            */
7872 /*                                                                        */
7873 /*  CALLED BY                                                             */
7874 /*                                                                        */
7875 /*    _nx_dns_host_by_name_get              Get IP address with name      */
7876 /*    _nx_host_by_address_get               Get name from IP address      */
7877 /*                                                                        */
7878 /*  RELEASE HISTORY                                                       */
7879 /*                                                                        */
7880 /*    DATE              NAME                      DESCRIPTION             */
7881 /*                                                                        */
7882 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7883 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7884 /*                                            resulting in version 6.1    */
7885 /*  02-02-2021     Yuxin Zhou               Modified comment(s), and      */
7886 /*                                            improved id generation,     */
7887 /*                                            resulting in version 6.1.4  */
7888 /*                                                                        */
7889 /**************************************************************************/
_nx_dns_new_packet_create(NX_DNS * dns_ptr,NX_PACKET * packet_ptr,UCHAR * name,USHORT type)7890 static UINT _nx_dns_new_packet_create(NX_DNS *dns_ptr, NX_PACKET *packet_ptr, UCHAR *name, USHORT type)
7891 {
7892 USHORT id;
7893 UINT size;
7894 
7895     /* Generate a random ID based on name. */
7896     id = (USHORT)NX_RAND();
7897 
7898     /* Add the DNS header.  */
7899     size =  _nx_dns_header_create(packet_ptr -> nx_packet_append_ptr, id, NX_DNS_QUERY_FLAGS);
7900 
7901     /* Determine if there was an error.  */
7902     if (size == 0)
7903     {
7904 
7905         /* Return error status. */
7906         return NX_DNS_PACKET_CREATE_ERROR;
7907     }
7908 
7909     /* Save the DNS  transmit id and lookup type.  */
7910     dns_ptr -> nx_dns_transmit_id = id;
7911     dns_ptr -> nx_dns_lookup_type = type;
7912 
7913     /* Setup the packet pointers.  */
7914     packet_ptr -> nx_packet_append_ptr +=  size;
7915     packet_ptr -> nx_packet_length +=      size;
7916 
7917     /* Add the DNS question.  */
7918     size =  _nx_dns_question_add(packet_ptr, name, type);
7919 
7920     /* Determine if there was an error.  */
7921     if (size == 0)
7922     {
7923 
7924         /* Return the error status.  */
7925         return NX_DNS_PACKET_CREATE_ERROR;
7926     }
7927 
7928     /* Successful completion.  */
7929     return NX_SUCCESS;
7930 }
7931 
7932 
7933 /**************************************************************************/
7934 /*                                                                        */
7935 /*  FUNCTION                                               RELEASE        */
7936 /*                                                                        */
7937 /*    _nx_dns_header_create                               PORTABLE C      */
7938 /*                                                           6.1          */
7939 /*  AUTHOR                                                                */
7940 /*                                                                        */
7941 /*    Yuxin Zhou, Microsoft Corporation                                   */
7942 /*                                                                        */
7943 /*  DESCRIPTION                                                           */
7944 /*                                                                        */
7945 /*    This function creates a standard DNS header and returns the size of */
7946 /*    header.                                                             */
7947 /*                                                                        */
7948 /*  INPUT                                                                 */
7949 /*                                                                        */
7950 /*    buffer_ptr                            Pointer to header area        */
7951 /*    id                                    Identification                */
7952 /*    flags                                 Flags                         */
7953 /*                                                                        */
7954 /*  OUTPUT                                                                */
7955 /*                                                                        */
7956 /*    size                                  Size of DNS header            */
7957 /*                                                                        */
7958 /*  CALLS                                                                 */
7959 /*                                                                        */
7960 /*    _nx_dns_short_to_network_convert      Convert from short to network */
7961 /*                                                                        */
7962 /*  CALLED BY                                                             */
7963 /*                                                                        */
7964 /*    _nx_dns_new_packet_create             Create new DNS packet         */
7965 /*                                                                        */
7966 /*  RELEASE HISTORY                                                       */
7967 /*                                                                        */
7968 /*    DATE              NAME                      DESCRIPTION             */
7969 /*                                                                        */
7970 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7971 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7972 /*                                            resulting in version 6.1    */
7973 /*                                                                        */
7974 /**************************************************************************/
_nx_dns_header_create(UCHAR * buffer_ptr,USHORT id,USHORT flags)7975 static UINT  _nx_dns_header_create(UCHAR *buffer_ptr, USHORT id, USHORT flags)
7976 {
7977 
7978     /* Transaction ID.  */
7979     _nx_dns_short_to_network_convert(buffer_ptr + NX_DNS_ID_OFFSET, id);
7980 
7981     /* Flags and Command.  */
7982     _nx_dns_short_to_network_convert(buffer_ptr + NX_DNS_FLAGS_OFFSET, flags);
7983 
7984     /* Initialize counts to 0.  */
7985     memset(buffer_ptr + NX_DNS_QDCOUNT_OFFSET, 0, 8);
7986 
7987     /* Return the size of the DNS header.  */
7988     return(NX_DNS_QDSECT_OFFSET);
7989 }
7990 
7991 
7992 /**************************************************************************/
7993 /*                                                                        */
7994 /*  FUNCTION                                               RELEASE        */
7995 /*                                                                        */
7996 /*    _nx_dns_question_add                                PORTABLE C      */
7997 /*                                                           6.1          */
7998 /*  AUTHOR                                                                */
7999 /*                                                                        */
8000 /*    Yuxin Zhou, Microsoft Corporation                                   */
8001 /*                                                                        */
8002 /*  DESCRIPTION                                                           */
8003 /*                                                                        */
8004 /*    This function adds a question to the packet buffer at the end of    */
8005 /*    the current data and updates the size and the question count        */
8006 /*    (assuming that there is a dns header at the start if the packet     */
8007 /*    buffer). The question class is assumed to be INET.                  */
8008 /*                                                                        */
8009 /*  INPUT                                                                 */
8010 /*                                                                        */
8011 /*    packet_ptr                            Pointer to header area        */
8012 /*    name                                  Host name or IP address that  */
8013 /*                                           is target of the DNS query   */
8014 /*    type                                  DNS record type (e.g. A, AAAA)*/
8015 /*                                                                        */
8016 /*  OUTPUT                                                                */
8017 /*                                                                        */
8018 /*    size                                  Total size of packet          */
8019 /*                                                                        */
8020 /*  CALLS                                                                 */
8021 /*                                                                        */
8022 /*    _nx_dns_name_string_encode            Encode the supplied string    */
8023 /*    _nx_dns_network_to_short_convert      Convert from network to short */
8024 /*    _nx_dns_short_to_network_convert      Convert from short to network */
8025 /*    nx_packet_release                     Release packet                */
8026 /*                                                                        */
8027 /*  CALLED BY                                                             */
8028 /*                                                                        */
8029 /*    _nx_dns_new_packet_create             Create new DNS packet         */
8030 /*                                                                        */
8031 /*  RELEASE HISTORY                                                       */
8032 /*                                                                        */
8033 /*    DATE              NAME                      DESCRIPTION             */
8034 /*                                                                        */
8035 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8036 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8037 /*                                            resulting in version 6.1    */
8038 /*                                                                        */
8039 /**************************************************************************/
_nx_dns_question_add(NX_PACKET * packet_ptr,UCHAR * name,USHORT type)8040 static UINT  _nx_dns_question_add(NX_PACKET *packet_ptr, UCHAR *name, USHORT type)
8041 {
8042 
8043 UINT    name_size;
8044 UINT    size;
8045 USHORT  value;
8046 
8047 
8048     /* Check for name.  */
8049     if (_nx_utility_string_length_check((CHAR *)name, &name_size, NX_DNS_NAME_MAX))
8050     {
8051 
8052         /* Name error, release the packet.  */
8053         nx_packet_release(packet_ptr);
8054 
8055         /* Return a size of 0 to indicate an error.  */
8056         return(0);
8057     }
8058 
8059     /* The question will take the size of the string plus 6 bytes, is there space?  */
8060     if ((name_size + 6) > (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_append_ptr))
8061     {
8062 
8063         /* Size error, release the packet.  */
8064         nx_packet_release(packet_ptr);
8065 
8066         /* Return a size of 0 to indicate an error.  */
8067         return(0);
8068     }
8069 
8070     /* Encode and add the name.  */
8071     size =  _nx_dns_name_string_encode(packet_ptr -> nx_packet_append_ptr, name);
8072 
8073     /* Add the type and class.  */
8074     _nx_dns_short_to_network_convert(packet_ptr -> nx_packet_append_ptr + size, type);
8075     size +=  2;
8076     _nx_dns_short_to_network_convert(packet_ptr -> nx_packet_append_ptr + size, NX_DNS_RR_CLASS_IN);
8077     size +=  2;
8078 
8079     /* Update the packet size and end.  */
8080     packet_ptr -> nx_packet_length +=      size;
8081     packet_ptr -> nx_packet_append_ptr +=  size;
8082 
8083     /* Get the question count. */
8084     value = _nx_dns_network_to_short_convert(packet_ptr -> nx_packet_prepend_ptr + NX_DNS_QDCOUNT_OFFSET);
8085 
8086     /* Increment question count by one. */
8087     value++;
8088     _nx_dns_short_to_network_convert(packet_ptr -> nx_packet_prepend_ptr + NX_DNS_QDCOUNT_OFFSET, value);
8089 
8090     /* Return the size.  */
8091     return(packet_ptr -> nx_packet_length);
8092 }
8093 
8094 
8095 #ifdef FEATURE_NX_IPV6
8096 /**************************************************************************/
8097 /*                                                                        */
8098 /*  FUNCTION                                               RELEASE        */
8099 /*                                                                        */
8100 /*    _nxd_dns_build_an_ipv6_question_string              PORTABLE C      */
8101 /*                                                           6.1          */
8102 /*  AUTHOR                                                                */
8103 /*                                                                        */
8104 /*    Yuxin Zhou, Microsoft Corporation                                   */
8105 /*                                                                        */
8106 /*  DESCRIPTION                                                           */
8107 /*                                                                        */
8108 /*    This function creates the IP address in text form to go into the DNS*/
8109 /*    lookup query ("Name"), including the ip6.arpa tag on the end.       */
8110 /*                                                                        */
8111 /*  INPUT                                                                 */
8112 /*                                                                        */
8113 /*    ip_address                            NXD_ADDRESS instance with the */
8114 /*                                            IP address to search for    */
8115 /*                                            host name                   */
8116 /*    buffer                                Pointer to host name to lookup*/
8117 /*    len                                   Buffer size for host name     */
8118 /*                                                                        */
8119 /*  OUTPUT                                                                */
8120 /*                                                                        */
8121 /*    None                                                                */
8122 /*                                                                        */
8123 /*  CALLS                                                                 */
8124 /*                                                                        */
8125 /*    None                                                                */
8126 /*                                                                        */
8127 /*  CALLED BY                                                             */
8128 /*                                                                        */
8129 /*    _nxd_dns_host_by_address_get         Lookup host by address service */
8130 /*                                                                        */
8131 /*  RELEASE HISTORY                                                       */
8132 /*                                                                        */
8133 /*    DATE              NAME                      DESCRIPTION             */
8134 /*                                                                        */
8135 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8136 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
8137 /*                                            verified memcpy use cases,  */
8138 /*                                            resulting in version 6.1    */
8139 /*                                                                        */
8140 /**************************************************************************/
_nxd_dns_build_an_ipv6_question_string(NXD_ADDRESS * ip_address,UCHAR * buffer,UINT len)8141 static VOID _nxd_dns_build_an_ipv6_question_string(NXD_ADDRESS *ip_address, UCHAR *buffer, UINT len)
8142 {
8143 INT i,  j;
8144 ULONG temp;
8145 
8146     memset(buffer, 0, len);
8147     for (j = 3; j >= 0; j--)
8148     {
8149         i = 0;
8150         while (i <= 7)
8151         {
8152 
8153             temp = ip_address -> nxd_ip_address.v6[j];
8154             temp = temp >> (4 * i++);
8155             temp = (USHORT)temp & 0xf;
8156             if(temp >= 10)
8157                 *buffer = (UCHAR)('a' + ((UCHAR)temp - 10));
8158             else
8159                 *buffer = (UCHAR)('0' + (UCHAR)temp);
8160             buffer ++;
8161             *buffer = '.';
8162             buffer++;
8163         }
8164     }
8165 
8166     memcpy(buffer, "ip6.arpa", sizeof("ip6.arpa")); /* Use case of memcpy is verified. */
8167 
8168     return;
8169 }
8170 #endif
8171 
8172 
8173 /**************************************************************************/
8174 /*                                                                        */
8175 /*  FUNCTION                                               RELEASE        */
8176 /*                                                                        */
8177 /*    _nx_dns_name_string_encode                          PORTABLE C      */
8178 /*                                                           6.1          */
8179 /*  AUTHOR                                                                */
8180 /*                                                                        */
8181 /*    Yuxin Zhou, Microsoft Corporation                                   */
8182 /*                                                                        */
8183 /*  DESCRIPTION                                                           */
8184 /*                                                                        */
8185 /*    This function converts a string containing the name as a list of    */
8186 /*    labels separated by dots to the encoded list of labels specified    */
8187 /*    in RFC1035 for DNS servers. This conversion doesn't handle          */
8188 /*    compression and doesn't check on the lengths of the labels or the   */
8189 /*    entire name.                                                        */
8190 /*                                                                        */
8191 /*  INPUT                                                                 */
8192 /*                                                                        */
8193 /*    ptr                                   Pointer to destination        */
8194 /*    name                                  Source name string            */
8195 /*                                                                        */
8196 /*  OUTPUT                                                                */
8197 /*                                                                        */
8198 /*    count                                 Count of characters encoded   */
8199 /*                                                                        */
8200 /*  CALLS                                                                 */
8201 /*                                                                        */
8202 /*    None                                                                */
8203 /*                                                                        */
8204 /*  CALLED BY                                                             */
8205 /*                                                                        */
8206 /*    _nx_dns_question_add                  Add question to DNS packet    */
8207 /*                                                                        */
8208 /*  RELEASE HISTORY                                                       */
8209 /*                                                                        */
8210 /*    DATE              NAME                      DESCRIPTION             */
8211 /*                                                                        */
8212 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8213 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8214 /*                                            resulting in version 6.1    */
8215 /*                                                                        */
8216 /**************************************************************************/
_nx_dns_name_string_encode(UCHAR * ptr,UCHAR * name)8217 static UINT  _nx_dns_name_string_encode(UCHAR *ptr, UCHAR *name)
8218 {
8219 
8220 UCHAR   *length;
8221 UINT    count =  1;
8222 
8223 
8224     /* Point to the first character position in the buffer.  This will point
8225        to the length of the following name.  */
8226     length =  ptr++;
8227 
8228     /* Default the length to zero.  */
8229     *length =  0;
8230 
8231     /* Move through string, copying bytes and updating length.
8232        Whenever a "." is found, start a new string by updating the
8233        pointer to the length and setting the length to zero.  */
8234     while (*name)
8235     {
8236 
8237         /* Is a dot been found?  */
8238         if (*name == '.')
8239         {
8240 
8241             /* Yes, setup a new length pointer. */
8242             length =  ptr++;
8243 
8244             /* Default the length to zero. */
8245             *length =  0;
8246             name++;
8247         }
8248         else
8249         {
8250 
8251             /* Copy a character to the destination.  */
8252             *ptr++ =  *name++;
8253 
8254             /* Adjust the length of the current segment.  */
8255             (*length)++;
8256         }
8257 
8258         /* Increment the total count here.  */
8259         count++;
8260     }
8261 
8262     /* Add the final zero length, like a NULL terminator.  */
8263     *ptr =  0;
8264 
8265     /* Increment the total count.  */
8266     count++;
8267 
8268     /* Return the count.  */
8269     return(count);
8270 }
8271 
8272 
8273 /**************************************************************************/
8274 /*                                                                        */
8275 /*  FUNCTION                                               RELEASE        */
8276 /*                                                                        */
8277 /*    _nx_dns_name_string_unencode                        PORTABLE C      */
8278 /*                                                           6.1.4        */
8279 /*  AUTHOR                                                                */
8280 /*                                                                        */
8281 /*    Yuxin Zhou, Microsoft Corporation                                   */
8282 /*                                                                        */
8283 /*  DESCRIPTION                                                           */
8284 /*                                                                        */
8285 /*    This function converts from the encoded list of labels as specified */
8286 /*    in RFC 1035 to a string containing the name as a list of labels     */
8287 /*    separated by dots.                                                  */
8288 /*                                                                        */
8289 /*  INPUT                                                                 */
8290 /*                                                                        */
8291 /*    data                                  Pointer to buffer to decode   */
8292 /*    start                                 Location of start of data     */
8293 /*    buffer                                Pointer to decoded data       */
8294 /*    buffer_size                           Size of data buffer to decode */
8295 /*                                                                        */
8296 /*  OUTPUT                                                                */
8297 /*                                                                        */
8298 /*    Size of decoded data                                                */
8299 /*                                                                        */
8300 /*  CALLS                                                                 */
8301 /*                                                                        */
8302 /*    None                                                                */
8303 /*                                                                        */
8304 /*  CALLED BY                                                             */
8305 /*                                                                        */
8306 /*    _nx_dns_send_query_by_address         Send reverse lookup query     */
8307 /*                                                                        */
8308 /*  RELEASE HISTORY                                                       */
8309 /*                                                                        */
8310 /*    DATE              NAME                      DESCRIPTION             */
8311 /*                                                                        */
8312 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8313 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
8314 /*                                            compression pointer check,  */
8315 /*                                            resulting in version 6.1    */
8316 /*  12-31-2020     Yuxin Zhou               Modified comment(s), prevented*/
8317 /*                                            infinite loop in name       */
8318 /*                                            compression, resulting in   */
8319 /*                                            version 6.1.3               */
8320 /*  02-02-2021     Yuxin Zhou               Modified comment(s), improved */
8321 /*                                            packet length verification, */
8322 /*                                            resulting in version 6.1.4  */
8323 /*                                                                        */
8324 /**************************************************************************/
_nx_dns_name_string_unencode(NX_PACKET * packet_ptr,UCHAR * data,UCHAR * buffer,UINT buffer_size)8325 static UINT _nx_dns_name_string_unencode(NX_PACKET *packet_ptr, UCHAR *data, UCHAR *buffer, UINT buffer_size)
8326 {
8327 
8328 UCHAR   *character;
8329 UCHAR   *message_start;
8330 UINT    label_size;
8331 UINT    offset;
8332 UINT    length;
8333 UINT    pointer_count = 0;
8334 
8335     /* Initialize the value.  */
8336     character = data;
8337     message_start = packet_ptr -> nx_packet_prepend_ptr;
8338     length = 0;
8339 
8340     /* As long as there is space in the buffer and we haven't
8341        found a zero terminating label */
8342     while (1)
8343     {
8344 
8345         if (character >= packet_ptr -> nx_packet_append_ptr)
8346         {
8347             return(0);
8348         }
8349 
8350         if (*character == '\0')
8351         {
8352             break;
8353         }
8354 
8355         /* Check the buffer size.  */
8356         if (buffer_size > length)
8357         {
8358 
8359             /* Get the label size.  */
8360             label_size = *character++;
8361 
8362             /* Is this a compression pointer or a count.  */
8363             if (label_size <= NX_DNS_LABEL_MAX)
8364             {
8365 
8366                 /* Simple count, check for space and copy the label.  */
8367                 while ((buffer_size > length) && (label_size > 0))
8368                 {
8369 
8370                     if ((character >= packet_ptr -> nx_packet_append_ptr) || (*character == '\0'))
8371                     {
8372                         return(0);
8373                     }
8374 
8375                     *buffer++ =  *character++;
8376                     length++;
8377                     label_size--;
8378                 }
8379 
8380                 /* Now add the '.' */
8381                 *buffer++ =  '.';
8382                 length++;
8383             }
8384             else if ((label_size & NX_DNS_COMPRESS_MASK) == NX_DNS_COMPRESS_VALUE)
8385             {
8386 
8387                 /* Message compression.  */
8388                 if (character >= packet_ptr -> nx_packet_append_ptr)
8389                 {
8390                     return(0);
8391                 }
8392 
8393                 /* Get the offset.  */
8394                 offset = ((label_size & NX_DNS_LABEL_MAX) << 8) + *character;
8395 
8396                 /* Check the offset.  */
8397                 if (offset >= packet_ptr -> nx_packet_length)
8398                 {
8399 
8400                     /* This is malformed packet.  */
8401                     return(0);
8402                 }
8403                 else
8404                 {
8405 
8406                     /* This is a pointer, just adjust the source.  */
8407                     if (character ==  message_start + offset)
8408                     {
8409                         /* If compression pointer equals the same offset currently being parsed,
8410                            it could lead to an infinite loop. */
8411                         return(0);
8412                     }
8413                     else
8414                     {
8415                         /* Prevent infinite loop with compression pointers. */
8416                         pointer_count++;
8417                         if (pointer_count > NX_DNS_MAX_COMPRESSION_POINTERS)
8418                         {
8419 
8420                             /* This is malformed packet.  */
8421                             return(0);
8422                         }
8423                         /* update valid pointer */
8424                         character =  message_start + offset;
8425                     }
8426                 }
8427             }
8428             else
8429             {
8430 
8431                 /* Not defined, just fail */
8432                 return(0);
8433             }
8434         }
8435         else
8436         {
8437 
8438             /* Size error , just fail */
8439             return(0);
8440         }
8441     }
8442 
8443     /* Check for invalid length.  */
8444     if (length == 0)
8445         return(length);
8446 
8447     /* Done copying the data, set the last . to a trailing null */
8448     if (*(buffer - 1) == '.')
8449     {
8450 
8451         buffer--;
8452         length --;
8453     }
8454 
8455     /* Null terminate name.  */
8456     *buffer =  '\0';
8457 
8458     /* Return name size.  */
8459     return(length);
8460 }
8461 
8462 
8463 /**************************************************************************/
8464 /*                                                                        */
8465 /*  FUNCTION                                               RELEASE        */
8466 /*                                                                        */
8467 /*    _nx_dns_name_size_calculate                         PORTABLE C      */
8468 /*                                                           6.1          */
8469 /*  AUTHOR                                                                */
8470 /*                                                                        */
8471 /*    Yuxin Zhou, Microsoft Corporation                                   */
8472 /*                                                                        */
8473 /*  DESCRIPTION                                                           */
8474 /*                                                                        */
8475 /*    This function calculates the size of the name.                      */
8476 /*                                                                        */
8477 /*  INPUT                                                                 */
8478 /*                                                                        */
8479 /*    name                                  Pointer to the name           */
8480 /*    packet_ptr                            Pointer to received packet    */
8481 /*                                                                        */
8482 /*  OUTPUT                                                                */
8483 /*                                                                        */
8484 /*    UINT                                  Size of name                  */
8485 /*                                                                        */
8486 /*  CALLS                                                                 */
8487 /*                                                                        */
8488 /*    None                                                                */
8489 /*                                                                        */
8490 /*  CALLED BY                                                             */
8491 /*                                                                        */
8492 /*    _nx_dns_host_by_name_get              Get IP address with name      */
8493 /*    _nx_host_by_address_get               Get name from IP address      */
8494 /*    _nx_dns_resource_type_get             Get resource type             */
8495 /*                                                                        */
8496 /*  RELEASE HISTORY                                                       */
8497 /*                                                                        */
8498 /*    DATE              NAME                      DESCRIPTION             */
8499 /*                                                                        */
8500 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8501 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
8502 /*                                            buffer bound check,         */
8503 /*                                            resulting in version 6.1    */
8504 /*                                                                        */
8505 /**************************************************************************/
_nx_dns_name_size_calculate(UCHAR * name,NX_PACKET * packet_ptr)8506 static UINT  _nx_dns_name_size_calculate(UCHAR *name, NX_PACKET *packet_ptr)
8507 {
8508 
8509 UINT size =  0;
8510 
8511 
8512     /* As long as we haven't found a zero length terminating label */
8513     while (*name != '\0')
8514     {
8515 
8516         UINT  labelSize =  *name++;
8517 
8518         /* Is this a compression pointer or a count.  */
8519         if (labelSize <= NX_DNS_LABEL_MAX)
8520         {
8521 
8522             if (name + labelSize >= packet_ptr -> nx_packet_append_ptr)
8523             {
8524 
8525                 /* If name buffer is OOB, just fail. */
8526                 return(0);
8527             }
8528 
8529             /* Simple count, adjust size and skip the label.  */
8530             size +=  labelSize + 1;
8531             name +=  labelSize;
8532         }
8533         else if ((labelSize & NX_DNS_COMPRESS_MASK) == NX_DNS_COMPRESS_VALUE)
8534         {
8535 
8536             /* This is a pointer size is 2 bytes and this is the end of this name */
8537             return(size + 2);
8538         }
8539         else
8540         {
8541 
8542             /* Not defined, just fail */
8543             return(0);
8544         }
8545     }
8546 
8547     /* Adjust size for the final NULL.  */
8548     return(size + 1);
8549 }
8550 
8551 
8552 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
8553 
8554 /**************************************************************************/
8555 /*                                                                        */
8556 /*  FUNCTION                                               RELEASE        */
8557 /*                                                                        */
8558 /*    _nx_dns_resource_name_real_size_calculate           PORTABLE C      */
8559 /*                                                           6.1.4        */
8560 /*  AUTHOR                                                                */
8561 /*                                                                        */
8562 /*    Yuxin Zhou, Microsoft Corporation                                   */
8563 /*                                                                        */
8564 /*  DESCRIPTION                                                           */
8565 /*                                                                        */
8566 /*    This function calculates the real size of the resouce name.         */
8567 /*                                                                        */
8568 /*  INPUT                                                                 */
8569 /*                                                                        */
8570 /*    data                                  Pointer to buffer to decode   */
8571 /*    start                                 Location of start of data     */
8572 /*    data_length                           Data buffer length            */
8573 /*                                                                        */
8574 /*  OUTPUT                                                                */
8575 /*                                                                        */
8576 /*    Real size of a string                                               */
8577 /*                                                                        */
8578 /*  CALLS                                                                 */
8579 /*                                                                        */
8580 /*    None                                                                */
8581 /*                                                                        */
8582 /*  CALLED BY                                                             */
8583 /*                                                                        */
8584 /*    _nx_dns_send_query_by_name             Send reverse lookup query    */
8585 /*                                                                        */
8586 /*  RELEASE HISTORY                                                       */
8587 /*                                                                        */
8588 /*    DATE              NAME                      DESCRIPTION             */
8589 /*                                                                        */
8590 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8591 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
8592 /*                                            compression pointer check,  */
8593 /*                                            resulting in version 6.1    */
8594 /*  12-31-2020     Yuxin Zhou               Modified comment(s), improved */
8595 /*                                            pointer check, prevented    */
8596 /*                                            infinite loop in name       */
8597 /*                                            compression, resulting in   */
8598 /*                                            version 6.1.3               */
8599 /*  02-02-2021     Yuxin Zhou               Modified comment(s), improved */
8600 /*                                            packet length verification, */
8601 /*                                            resulting in version 6.1.4  */
8602 /*                                                                        */
8603 /**************************************************************************/
_nx_dns_resource_name_real_size_calculate(UCHAR * data,UINT start,UINT data_length)8604 static UINT    _nx_dns_resource_name_real_size_calculate(UCHAR *data, UINT start, UINT data_length)
8605 {
8606 
8607 UCHAR   *character =  data + start;
8608 UINT    length = 0;
8609 UINT    offset;
8610 UINT    pointer_count = 0;
8611 UINT    labelSize;
8612 
8613     /* As long as there is space in the buffer and we haven't
8614        found a zero terminating label */
8615     while (1)
8616     {
8617 
8618         if (character >= (data + data_length))
8619         {
8620             return(0);
8621         }
8622 
8623         if (*character == '\0')
8624         {
8625             break;
8626         }
8627 
8628         labelSize =  *character++;
8629 
8630         /* Is this a compression pointer or a count.  */
8631         if (labelSize <= NX_DNS_LABEL_MAX)
8632         {
8633 
8634             /* Simple count, check for space and copy the label.  */
8635             while (labelSize > 0)
8636             {
8637 
8638                 if (character >= (data + data_length))
8639                 {
8640                     return(0);
8641                 }
8642 
8643                 character++;
8644                 length++;
8645                 labelSize--;
8646             }
8647 
8648             /* Now add the '.' space */
8649             length++;
8650         }
8651         else if ((labelSize & NX_DNS_COMPRESS_MASK) == NX_DNS_COMPRESS_VALUE)
8652         {
8653 
8654             if (character >= (data + data_length))
8655             {
8656                 return(0);
8657             }
8658 
8659             /* Get the offset.  */
8660             offset = ((labelSize & NX_DNS_LABEL_MAX) << 8) + *character;
8661 
8662             /* Check the offset.  */
8663             if (offset >= data_length)
8664             {
8665 
8666                 return(0);
8667             }
8668 
8669             /* This is a pointer, just adjust the source.  */
8670             if (character ==  data + offset)
8671             {
8672                 /* If compression pointer equals the same offset currently being parsed,
8673                    it could lead to an infinite loop. */
8674                 return(0);
8675             }
8676             else
8677             {
8678 
8679                 /* Prevent infinite loop with compression pointers. */
8680                 pointer_count++;
8681 
8682                 if (pointer_count > NX_DNS_MAX_COMPRESSION_POINTERS)
8683                 {
8684 
8685                     /* This is malformed packet.  */
8686                     return(0);
8687                 }
8688 
8689                 /* update valid pointer */
8690                 character =  data + offset;
8691             }
8692         }
8693         else
8694         {
8695 
8696             /* Not defined, just fail */
8697             return(0);
8698         }
8699     }
8700 
8701     /* Reduce the last '.' string, update the length.  */
8702     if (length)
8703     {
8704         length --;
8705     }
8706 
8707     /* Return name size.  */
8708     return(length);
8709 }
8710 #endif
8711 
8712 
8713 /**************************************************************************/
8714 /*                                                                        */
8715 /*  FUNCTION                                               RELEASE        */
8716 /*                                                                        */
8717 /*    _nx_dns_resource_type_get                           PORTABLE C      */
8718 /*                                                           6.1          */
8719 /*  AUTHOR                                                                */
8720 /*                                                                        */
8721 /*    Yuxin Zhou, Microsoft Corporation                                   */
8722 /*                                                                        */
8723 /*  DESCRIPTION                                                           */
8724 /*                                                                        */
8725 /*    This function retrieves the resource type. It is a wrapper for the  */
8726 /*    actual internal function that retrieves the name to maintain        */
8727 /*    compatibility with the previous version of DNS Client, e.g. NetX DNS*/
8728 /*    Client.                                                             */
8729 /*                                                                        */
8730 /*  INPUT                                                                 */
8731 /*                                                                        */
8732 /*    resource                              Pointer to the resource       */
8733 /*    packet_ptr                            Pointer to received packet    */
8734 /*    resource_type                         Pointer to resource type      */
8735 /*                                                                        */
8736 /*  OUTPUT                                                                */
8737 /*                                                                        */
8738 /*    status                                Success or failure            */
8739 /*                                                                        */
8740 /*  CALLS                                                                 */
8741 /*                                                                        */
8742 /*    _nx_dns_name_size_calculate           Calculate name's size         */
8743 /*    _nx_dns_network_to_short_convert      Actual get resource type      */
8744 /*                                                service                 */
8745 /*                                                                        */
8746 /*  CALLED BY                                                             */
8747 /*                                                                        */
8748 /*    _nx_dns_host_by_name_get              Get IP address with name      */
8749 /*    _nx_host_by_address_get               Get name from IP address      */
8750 /*    _nx_dns_name_size_calculate           Calculate name's size         */
8751 /*    _nx_dns_network_to_short_convert      Convert network to short      */
8752 /*                                                                        */
8753 /*  RELEASE HISTORY                                                       */
8754 /*                                                                        */
8755 /*    DATE              NAME                      DESCRIPTION             */
8756 /*                                                                        */
8757 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8758 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
8759 /*                                            buffer bound check,         */
8760 /*                                            resulting in version 6.1    */
8761 /*                                                                        */
8762 /**************************************************************************/
_nx_dns_resource_type_get(UCHAR * resource,NX_PACKET * packet_ptr,UINT * resource_type)8763 static UINT  _nx_dns_resource_type_get(UCHAR *resource, NX_PACKET *packet_ptr, UINT *resource_type)
8764 {
8765 UINT    name_size;
8766 
8767     name_size = _nx_dns_name_size_calculate(resource, packet_ptr);
8768 
8769     if (!name_size)
8770     {
8771         /* If name size is not valid, return a failure. */
8772         return(NX_DNS_MALFORMED_PACKET);
8773     }
8774 
8775     /* Resource type is 2 bytes long starting from resource + name_size, check if there is OOB. */
8776     if (resource + name_size + 2 >= packet_ptr -> nx_packet_append_ptr)
8777     {
8778         /* If there is OOB read, return a failure. */
8779         return(NX_OVERFLOW);
8780     }
8781     else
8782     {
8783         *resource_type = _nx_dns_network_to_short_convert(resource + name_size);
8784         return(NX_SUCCESS);
8785     }
8786 }
8787 
8788 
8789 #ifdef NX_DNS_CACHE_ENABLE
8790 /**************************************************************************/
8791 /*                                                                        */
8792 /*  FUNCTION                                               RELEASE        */
8793 /*                                                                        */
8794 /*    _nx_dns_resource_time_to_live_get                   PORTABLE C      */
8795 /*                                                           6.1          */
8796 /*  AUTHOR                                                                */
8797 /*                                                                        */
8798 /*    Yuxin Zhou, Microsoft Corporation                                   */
8799 /*                                                                        */
8800 /*  DESCRIPTION                                                           */
8801 /*                                                                        */
8802 /*    This function retrieves the resource time to live.                  */
8803 /*                                                                        */
8804 /*  INPUT                                                                 */
8805 /*                                                                        */
8806 /*    resource                              Pointer to the resource       */
8807 /*    packet_ptr                            Pointer to received packet    */
8808 /*    rr_ttl                                Pointer to time to live       */
8809 /*                                                                        */
8810 /*  OUTPUT                                                                */
8811 /*                                                                        */
8812 /*    Status                                Success or failure            */
8813 /*                                                                        */
8814 /*  CALLS                                                                 */
8815 /*                                                                        */
8816 /*                                                                        */
8817 /*  CALLED BY                                                             */
8818 /*                                                                        */
8819 /*                                                                        */
8820 /*  RELEASE HISTORY                                                       */
8821 /*                                                                        */
8822 /*    DATE              NAME                      DESCRIPTION             */
8823 /*                                                                        */
8824 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8825 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
8826 /*                                            buffer bound check,         */
8827 /*                                            resulting in version 6.1    */
8828 /*                                                                        */
8829 /**************************************************************************/
_nx_dns_resource_time_to_live_get(UCHAR * resource,NX_PACKET * packet_ptr,ULONG * rr_ttl)8830 static UINT  _nx_dns_resource_time_to_live_get(UCHAR *resource, NX_PACKET *packet_ptr, ULONG *rr_ttl)
8831 {
8832 UINT    name_size;
8833 
8834     name_size = _nx_dns_name_size_calculate(resource, packet_ptr);
8835 
8836     if (!name_size)
8837     {
8838 
8839         /* If name size is not valid, return a failure. */
8840         return(NX_DNS_MALFORMED_PACKET);
8841     }
8842 
8843     /* rr_ttl is 4 bytes long starting from resource + name_size + 4, check if there is OOB. */
8844     if (resource + name_size + 4 + 4 >= packet_ptr -> nx_packet_append_ptr)
8845     {
8846 
8847         /* if there is OOB read, return an invalid value. */
8848         return(NX_OVERFLOW);
8849     }
8850     else
8851     {
8852         *rr_ttl = _nx_dns_network_to_long_convert(resource + name_size + 4);
8853         return(NX_SUCCESS);
8854     }
8855 }
8856 #endif /* NX_DNS_CACHE_ENABLE  */
8857 
8858 
8859 /**************************************************************************/
8860 /*                                                                        */
8861 /*  FUNCTION                                               RELEASE        */
8862 /*                                                                        */
8863 /*    _nx_dns_resource_data_length_get                    PORTABLE C      */
8864 /*                                                           6.1          */
8865 /*  AUTHOR                                                                */
8866 /*                                                                        */
8867 /*    Yuxin Zhou, Microsoft Corporation                                   */
8868 /*                                                                        */
8869 /*  DESCRIPTION                                                           */
8870 /*                                                                        */
8871 /*    This function retrieves the resource data length.                   */
8872 /*                                                                        */
8873 /*  INPUT                                                                 */
8874 /*                                                                        */
8875 /*    resource                              Pointer to the resource       */
8876 /*    packet_ptr                            Pointer to received packet    */
8877 /*    length                                Pointer to data length        */
8878 /*                                                                        */
8879 /*  OUTPUT                                                                */
8880 /*                                                                        */
8881 /*    status                                Success or failure            */
8882 /*                                                                        */
8883 /*  CALLS                                                                 */
8884 /*                                                                        */
8885 /*    _nx_dns_name_size_calculate           Calculate name's size         */
8886 /*    _nx_dns_network_to_short_convert      Convert from network to short */
8887 /*                                                                        */
8888 /*  CALLED BY                                                             */
8889 /*                                                                        */
8890 /*    _nx_dns_host_by_name_get              Get IP address with name      */
8891 /*    _nx_host_by_address_get               Get name from IP address      */
8892 /*    _nx_dns_resource_size_get             Get size of resource          */
8893 /*                                                                        */
8894 /*  RELEASE HISTORY                                                       */
8895 /*                                                                        */
8896 /*    DATE              NAME                      DESCRIPTION             */
8897 /*                                                                        */
8898 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8899 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
8900 /*                                            buffer bound check,         */
8901 /*                                            resulting in version 6.1    */
8902 /*                                                                        */
8903 /**************************************************************************/
_nx_dns_resource_data_length_get(UCHAR * resource,NX_PACKET * packet_ptr,UINT * length)8904 static UINT  _nx_dns_resource_data_length_get(UCHAR *resource, NX_PACKET *packet_ptr, UINT *length)
8905 {
8906 UINT    name_size;
8907 
8908     name_size = _nx_dns_name_size_calculate(resource, packet_ptr);
8909 
8910     if (!name_size)
8911     {
8912         /* If name size is not valid, return a failure. */
8913         return(NX_DNS_MALFORMED_PACKET);
8914     }
8915 
8916 
8917     /* Resource length is 2 bytes long starting from resource + name_size + 8, check if there is OOB. */
8918     if (resource + name_size + 8 + 2 >= packet_ptr -> nx_packet_append_ptr)
8919     {
8920         /* if there is OOB read, return a failure. */
8921         return(NX_OVERFLOW);
8922     }
8923     else
8924     {
8925         *length = (_nx_dns_network_to_short_convert(resource + name_size + 8));
8926         return(NX_SUCCESS);
8927     }
8928 
8929 }
8930 
8931 
8932 /**************************************************************************/
8933 /*                                                                        */
8934 /*  FUNCTION                                               RELEASE        */
8935 /*                                                                        */
8936 /*    _nx_dns_resource_data_address_get                   PORTABLE C      */
8937 /*                                                           6.1          */
8938 /*  AUTHOR                                                                */
8939 /*                                                                        */
8940 /*    Yuxin Zhou, Microsoft Corporation                                   */
8941 /*                                                                        */
8942 /*  DESCRIPTION                                                           */
8943 /*                                                                        */
8944 /*    This function retrieves the resource data address.                  */
8945 /*                                                                        */
8946 /*  INPUT                                                                 */
8947 /*                                                                        */
8948 /*    resource                              Pointer to the resource       */
8949 /*    packet_ptr                            Pointer to received packet    */
8950 /*                                                                        */
8951 /*  OUTPUT                                                                */
8952 /*                                                                        */
8953 /*    pointer to address                                                  */
8954 /*                                                                        */
8955 /*  CALLS                                                                 */
8956 /*                                                                        */
8957 /*    _nx_dns_name_size_calculate           Calculate name's size         */
8958 /*                                                                        */
8959 /*  CALLED BY                                                             */
8960 /*                                                                        */
8961 /*    _nx_dns_host_by_name_get              Get IP address with name      */
8962 /*    _nx_host_by_address_get               Get name from IP address      */
8963 /*                                                                        */
8964 /*  RELEASE HISTORY                                                       */
8965 /*                                                                        */
8966 /*    DATE              NAME                      DESCRIPTION             */
8967 /*                                                                        */
8968 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8969 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
8970 /*                                            buffer bound check,         */
8971 /*                                            resulting in version 6.1    */
8972 /*                                                                        */
8973 /**************************************************************************/
_nx_dns_resource_data_address_get(UCHAR * resource,NX_PACKET * packet_ptr)8974 static UCHAR  *_nx_dns_resource_data_address_get(UCHAR *resource, NX_PACKET *packet_ptr)
8975 {
8976 UINT    name_size;
8977 
8978     name_size = _nx_dns_name_size_calculate(resource, packet_ptr);
8979 
8980     if (!name_size)
8981     {
8982         /* If name size is not valid, return an invalid NULL address. */
8983         return(0);
8984     }
8985 
8986     if (resource + name_size + 10 >= packet_ptr -> nx_packet_append_ptr)
8987     {
8988         /* if there is OOB read, return an invalid NULL address. */
8989         return(0);
8990     }
8991     else
8992     {
8993         return(resource + name_size + 10);
8994     }
8995 }
8996 
8997 
8998 /**************************************************************************/
8999 /*                                                                        */
9000 /*  FUNCTION                                               RELEASE        */
9001 /*                                                                        */
9002 /*    _nx_dns_resource_size_get                           PORTABLE C      */
9003 /*                                                           6.1          */
9004 /*  AUTHOR                                                                */
9005 /*                                                                        */
9006 /*    Yuxin Zhou, Microsoft Corporation                                   */
9007 /*                                                                        */
9008 /*  DESCRIPTION                                                           */
9009 /*                                                                        */
9010 /*    This function retrieves the resource data size.                     */
9011 /*                                                                        */
9012 /*  INPUT                                                                 */
9013 /*                                                                        */
9014 /*    resource                              Pointer to the resource       */
9015 /*    packet_ptr                            Pointer to received packet    */
9016 /*    resource size                         Pointer to resource size      */
9017 /*                                                                        */
9018 /*  OUTPUT                                                                */
9019 /*                                                                        */
9020 /*    status                                Success or failure            */
9021 /*                                                                        */
9022 /*  CALLS                                                                 */
9023 /*                                                                        */
9024 /*    _nx_dns_name_size_calculate           Calculate name's size         */
9025 /*    _nx_dns_resource_data_length_get      Get resource data length      */
9026 /*                                                                        */
9027 /*  CALLED BY                                                             */
9028 /*                                                                        */
9029 /*    _nx_host_by_address_get               Get name from IP address      */
9030 /*                                                                        */
9031 /*  RELEASE HISTORY                                                       */
9032 /*                                                                        */
9033 /*    DATE              NAME                      DESCRIPTION             */
9034 /*                                                                        */
9035 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9036 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
9037 /*                                            buffer bound check,         */
9038 /*                                            resulting in version 6.1    */
9039 /*                                                                        */
9040 /**************************************************************************/
_nx_dns_resource_size_get(UCHAR * resource,NX_PACKET * packet_ptr,UINT * resource_size)9041 static UINT  _nx_dns_resource_size_get(UCHAR *resource, NX_PACKET *packet_ptr, UINT *resource_size)
9042 {
9043 UINT status;
9044 UINT data_length;
9045 UINT name_size;
9046 
9047     status = _nx_dns_resource_data_length_get(resource, packet_ptr, &data_length);
9048     if (status)
9049     {
9050 
9051         /* Return directly if failed to get resource data length. */
9052         return(status);
9053     }
9054 
9055     /* Resource size is
9056     name size + data size + 2 bytes for type, 2 for class, 4 for time to live and 2 for data length
9057     i.e. name size + data size + 10 bytes overhead
9058     */
9059     name_size = _nx_dns_name_size_calculate(resource, packet_ptr);
9060 
9061     if (!name_size)
9062     {
9063 
9064         /* If name size is not valid, return a failure. */
9065         return(NX_DNS_MALFORMED_PACKET);
9066     }
9067 
9068     *resource_size = name_size + data_length + 10;
9069     return(NX_SUCCESS);
9070 }
9071 
9072 
9073 /**************************************************************************/
9074 /*                                                                        */
9075 /*  FUNCTION                                               RELEASE        */
9076 /*                                                                        */
9077 /*    _nx_dns_short_to_network_convert                    PORTABLE C      */
9078 /*                                                           6.1          */
9079 /*  AUTHOR                                                                */
9080 /*                                                                        */
9081 /*    Yuxin Zhou, Microsoft Corporation                                   */
9082 /*                                                                        */
9083 /*  DESCRIPTION                                                           */
9084 /*                                                                        */
9085 /*    This function converts an unsigned short to network byte order,     */
9086 /*    which is big endian.                                                */
9087 /*                                                                        */
9088 /*  INPUT                                                                 */
9089 /*                                                                        */
9090 /*    ptr                                   Pointer to the destination    */
9091 /*    value                                 Source value                  */
9092 /*                                                                        */
9093 /*  OUTPUT                                                                */
9094 /*                                                                        */
9095 /*    None                                                                */
9096 /*                                                                        */
9097 /*  CALLS                                                                 */
9098 /*                                                                        */
9099 /*    None                                                                */
9100 /*                                                                        */
9101 /*  CALLED BY                                                             */
9102 /*                                                                        */
9103 /*    DNS component                                                       */
9104 /*                                                                        */
9105 /*  RELEASE HISTORY                                                       */
9106 /*                                                                        */
9107 /*    DATE              NAME                      DESCRIPTION             */
9108 /*                                                                        */
9109 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9110 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9111 /*                                            resulting in version 6.1    */
9112 /*                                                                        */
9113 /**************************************************************************/
_nx_dns_short_to_network_convert(UCHAR * ptr,USHORT value)9114 static void  _nx_dns_short_to_network_convert(UCHAR *ptr, USHORT value)
9115 {
9116 
9117     *ptr++ =  (UCHAR)(value >> 8);
9118     *ptr   =  (UCHAR)value;
9119 }
9120 
9121 /**************************************************************************/
9122 /*                                                                        */
9123 /*  FUNCTION                                               RELEASE        */
9124 /*                                                                        */
9125 /*    _nx_dns_network_to_short_convert                    PORTABLE C      */
9126 /*                                                           6.1          */
9127 /*  AUTHOR                                                                */
9128 /*                                                                        */
9129 /*    Yuxin Zhou, Microsoft Corporation                                   */
9130 /*                                                                        */
9131 /*  DESCRIPTION                                                           */
9132 /*                                                                        */
9133 /*    This function converts an unsigned short in network format, which   */
9134 /*    big endian, to an unsigned short.                                   */
9135 /*                                                                        */
9136 /*  INPUT                                                                 */
9137 /*                                                                        */
9138 /*    ptr                                   Pointer to the source         */
9139 /*                                                                        */
9140 /*  OUTPUT                                                                */
9141 /*                                                                        */
9142 /*    return value                                                        */
9143 /*                                                                        */
9144 /*  CALLS                                                                 */
9145 /*                                                                        */
9146 /*    None                                                                */
9147 /*                                                                        */
9148 /*  CALLED BY                                                             */
9149 /*                                                                        */
9150 /*    DNS component                                                       */
9151 /*                                                                        */
9152 /*  RELEASE HISTORY                                                       */
9153 /*                                                                        */
9154 /*    DATE              NAME                      DESCRIPTION             */
9155 /*                                                                        */
9156 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9157 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9158 /*                                            resulting in version 6.1    */
9159 /*                                                                        */
9160 /**************************************************************************/
_nx_dns_network_to_short_convert(UCHAR * ptr)9161 static USHORT _nx_dns_network_to_short_convert(UCHAR *ptr)
9162 {
9163 
9164 USHORT value =  *ptr++;
9165 
9166     value =  (USHORT)((value << 8) | *ptr);
9167 
9168     return(value);
9169 }
9170 
9171 
9172 /**************************************************************************/
9173 /*                                                                        */
9174 /*  FUNCTION                                               RELEASE        */
9175 /*                                                                        */
9176 /*    _nx_dns_network_to_long_convert                     PORTABLE C      */
9177 /*                                                           6.1          */
9178 /*  AUTHOR                                                                */
9179 /*                                                                        */
9180 /*    Yuxin Zhou, Microsoft Corporation                                   */
9181 /*                                                                        */
9182 /*  DESCRIPTION                                                           */
9183 /*                                                                        */
9184 /*    This function converts an unsigned long in network format, which    */
9185 /*    big endian, to an unsigned long.                                    */
9186 /*                                                                        */
9187 /*  INPUT                                                                 */
9188 /*                                                                        */
9189 /*    ptr                                   Pointer to the source         */
9190 /*                                                                        */
9191 /*  OUTPUT                                                                */
9192 /*                                                                        */
9193 /*    return value                                                        */
9194 /*                                                                        */
9195 /*  CALLS                                                                 */
9196 /*                                                                        */
9197 /*    None                                                                */
9198 /*                                                                        */
9199 /*  CALLED BY                                                             */
9200 /*                                                                        */
9201 /*    DNS component                                                       */
9202 /*                                                                        */
9203 /*  RELEASE HISTORY                                                       */
9204 /*                                                                        */
9205 /*    DATE              NAME                      DESCRIPTION             */
9206 /*                                                                        */
9207 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9208 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9209 /*                                            resulting in version 6.1    */
9210 /*                                                                        */
9211 /**************************************************************************/
_nx_dns_network_to_long_convert(UCHAR * ptr)9212 static ULONG  _nx_dns_network_to_long_convert(UCHAR *ptr)
9213 {
9214 
9215 ULONG value =  *ptr++;
9216 
9217     value =  (value << 8) | *ptr++;
9218     value =  (value << 8) | *ptr++;
9219     value =  (value << 8) | *ptr;
9220 
9221     return(value);
9222 }
9223 
9224 
9225 #ifndef NX_DISABLE_IPV4
9226 /**************************************************************************/
9227 /*                                                                        */
9228 /*  FUNCTION                                               RELEASE        */
9229 /*                                                                        */
9230 /*    _nx_dns_number_to_ascii_convert                     PORTABLE C      */
9231 /*                                                           6.1          */
9232 /*  AUTHOR                                                                */
9233 /*                                                                        */
9234 /*    Yuxin Zhou, Microsoft Corporation                                   */
9235 /*                                                                        */
9236 /*  DESCRIPTION                                                           */
9237 /*                                                                        */
9238 /*    This function converts single digits into an ASCII character in an  */
9239 /*    NULL terminated string.                                             */
9240 /*                                                                        */
9241 /*  INPUT                                                                 */
9242 /*                                                                        */
9243 /*    number                                Unsigned integer number       */
9244 /*    buffstring                            Destination string            */
9245 /*                                                                        */
9246 /*  OUTPUT                                                                */
9247 /*                                                                        */
9248 /*    Size                                  Number of bytes in string     */
9249 /*                                           (0 implies an error)         */
9250 /*                                                                        */
9251 /*  CALLS                                                                 */
9252 /*                                                                        */
9253 /*    None                                                                */
9254 /*                                                                        */
9255 /*  CALLED BY                                                             */
9256 /*                                                                        */
9257 /*    _nx_dns_host_by_address_get           Send PTR query to DNS server  */
9258 /*                                                                        */
9259 /*  RELEASE HISTORY                                                       */
9260 /*                                                                        */
9261 /*    DATE              NAME                      DESCRIPTION             */
9262 /*                                                                        */
9263 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9264 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9265 /*                                            resulting in version 6.1    */
9266 /*                                                                        */
9267 /**************************************************************************/
_nx_dns_number_to_ascii_convert(UINT number,CHAR * buffstring)9268 static UINT  _nx_dns_number_to_ascii_convert(UINT number, CHAR *buffstring)
9269 {
9270 UINT value;
9271 UINT digit;
9272 UINT index = 0;
9273 
9274     value = number;
9275 
9276     /* Is the value in the range of 100 and 255? */
9277     if(value >= 200)
9278     {
9279         buffstring[index++] = '2';
9280         value -= 200;
9281     }
9282     else if(value >= 100)
9283     {
9284         buffstring[index++] = '1';
9285         value -= 100;
9286     }
9287 
9288     digit = value % 10;
9289     value = value / 10;
9290 
9291     if(value == 0)
9292     {
9293         /* The 10s is zero.  However if we already recorded the hundreds,
9294            we need to insert 0 here. */
9295         if(index != 0)
9296             buffstring[index++] = '0';
9297     }
9298     else
9299         buffstring[index++] = (CHAR)('0' + value);
9300 
9301     /* Last print the digit. */
9302     buffstring[index++] = (CHAR)('0' + digit);
9303 
9304     return index;
9305 }
9306 #endif /* NX_DISABLE_IPV4 */
9307 
9308 
9309 #ifdef NX_DNS_CACHE_ENABLE
9310 /**************************************************************************/
9311 /*                                                                        */
9312 /*  FUNCTION                                               RELEASE        */
9313 /*                                                                        */
9314 /*    _nxe_dns_cache_initialize                           PORTABLE C      */
9315 /*                                                           6.1          */
9316 /*  AUTHOR                                                                */
9317 /*                                                                        */
9318 /*    Yuxin Zhou, Microsoft Corporation                                   */
9319 /*                                                                        */
9320 /*  DESCRIPTION                                                           */
9321 /*                                                                        */
9322 /*    This function checks for errors in the DNS cache initialize         */
9323 /*    function call.                                                      */
9324 /*                                                                        */
9325 /*  INPUT                                                                 */
9326 /*                                                                        */
9327 /*    dns_ptr                           Pointer to DNS instance           */
9328 /*    cache_ptr                         Pointer to cache memory           */
9329 /*    cache_size                       The size of cache                  */
9330 /*                                                                        */
9331 /*  OUTPUT                                                                */
9332 /*                                                                        */
9333 /*    status                            Completion status                 */
9334 /*                                                                        */
9335 /*  CALLS                                                                 */
9336 /*                                                                        */
9337 /*    _nx_dns_cache_initialize         Actual cache initialize function   */
9338 /*                                                                        */
9339 /*  CALLED BY                                                             */
9340 /*                                                                        */
9341 /*    Application Code                                                    */
9342 /*                                                                        */
9343 /*  RELEASE HISTORY                                                       */
9344 /*                                                                        */
9345 /*    DATE              NAME                      DESCRIPTION             */
9346 /*                                                                        */
9347 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9348 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9349 /*                                            resulting in version 6.1    */
9350 /*                                                                        */
9351 /**************************************************************************/
_nxe_dns_cache_initialize(NX_DNS * dns_ptr,VOID * cache_ptr,UINT cache_size)9352 UINT _nxe_dns_cache_initialize(NX_DNS *dns_ptr, VOID *cache_ptr, UINT cache_size)
9353 {
9354 
9355 UINT    status;
9356 
9357 
9358     /* Check for invalid input pointers.  */
9359     if (!dns_ptr)
9360     {
9361         return(NX_PTR_ERROR);
9362     }
9363 
9364     /* Check for invalid non pointer input. */
9365     if (dns_ptr -> nx_dns_id != NX_DNS_ID)
9366     {
9367         return(NX_DNS_PARAM_ERROR);
9368     }
9369 
9370     /* Check for invalid input pointers.  */
9371     if (!cache_ptr)
9372     {
9373         return(NX_DNS_CACHE_ERROR);
9374     }
9375 
9376     /* Make sure peer cache is 4-byte aligned. */
9377     if ((((ALIGN_TYPE)cache_ptr & 0x3) != 0) ||
9378         ((cache_size & 0x3) != 0))
9379     {
9380         return(NX_DNS_ERROR);
9381     }
9382 
9383     /* Call actual DNS cache initialize service.  */
9384     status =  _nx_dns_cache_initialize(dns_ptr, cache_ptr, cache_size);
9385 
9386     /* Return status.  */
9387     return(status);
9388 }
9389 
9390 
9391 /**************************************************************************/
9392 /*                                                                        */
9393 /*  FUNCTION                                               RELEASE        */
9394 /*                                                                        */
9395 /*    _nx_dns_cache_initialize                           PORTABLE C       */
9396 /*                                                           6.1          */
9397 /*  AUTHOR                                                                */
9398 /*                                                                        */
9399 /*    Yuxin Zhou, Microsoft Corporation                                   */
9400 /*                                                                        */
9401 /*  DESCRIPTION                                                           */
9402 /*                                                                        */
9403 /*    This function initializes the DNS cache.                            */
9404 /*                                                                        */
9405 /*  INPUT                                                                 */
9406 /*                                                                        */
9407 /*    dns_ptr                           Pointer to DNS instance           */
9408 /*    cache_ptr                         Pointer to cache memory           */
9409 /*    cache_size                       The size of cache                  */
9410 /*                                                                        */
9411 /*  OUTPUT                                                                */
9412 /*                                                                        */
9413 /*    status                                Completion status             */
9414 /*                                                                        */
9415 /*  CALLS                                                                 */
9416 /*                                                                        */
9417 /*    tx_mutex_get                      Get the DNS mutex                 */
9418 /*    tx_mutex_put                      Put the DNS mutex                 */
9419 /*                                                                        */
9420 /*  CALLED BY                                                             */
9421 /*                                                                        */
9422 /*    Application Code                                                    */
9423 /*                                                                        */
9424 /*  RELEASE HISTORY                                                       */
9425 /*                                                                        */
9426 /*    DATE              NAME                      DESCRIPTION             */
9427 /*                                                                        */
9428 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9429 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9430 /*                                            resulting in version 6.1    */
9431 /*                                                                        */
9432 /**************************************************************************/
_nx_dns_cache_initialize(NX_DNS * dns_ptr,VOID * cache_ptr,UINT cache_size)9433 UINT _nx_dns_cache_initialize(NX_DNS *dns_ptr, VOID *cache_ptr, UINT cache_size)
9434 {
9435 
9436 ALIGN_TYPE *head;
9437 ALIGN_TYPE *tail;
9438 
9439 
9440     /* Get the mutex.  */
9441     tx_mutex_get(&(dns_ptr -> nx_dns_mutex), TX_WAIT_FOREVER);
9442 
9443     /* Zero out the cache. */
9444     memset(cache_ptr, 0, cache_size);
9445 
9446     /* Set the head. */
9447     head = (ALIGN_TYPE*)cache_ptr;
9448     *head = (ALIGN_TYPE)((ALIGN_TYPE*)cache_ptr + 1);
9449 
9450     /* Set the tail. */
9451     tail = (ALIGN_TYPE*)((UCHAR*)cache_ptr + cache_size) - 1;
9452     *tail = (ALIGN_TYPE)tail;
9453 
9454     /* Record the info.  */
9455     dns_ptr -> nx_dns_cache = (UCHAR*)cache_ptr;
9456     dns_ptr -> nx_dns_cache_size = cache_size;
9457 
9458     /* Clear the count.  */
9459     dns_ptr -> nx_dns_rr_count = 0;
9460     dns_ptr -> nx_dns_string_count = 0;
9461     dns_ptr -> nx_dns_string_bytes = 0;
9462 
9463     /* Put the DNS mutex.  */
9464     tx_mutex_put(&dns_ptr -> nx_dns_mutex);
9465 
9466     return(NX_SUCCESS);
9467 }
9468 #endif /* NX_DNS_CACHE_ENABLE  */
9469 
9470 
9471 #ifdef NX_DNS_CACHE_ENABLE
9472 /**************************************************************************/
9473 /*                                                                        */
9474 /*  FUNCTION                                               RELEASE        */
9475 /*                                                                        */
9476 /*    _nxe_dns_cache_notify_set                           PORTABLE C      */
9477 /*                                                           6.1          */
9478 /*  AUTHOR                                                                */
9479 /*                                                                        */
9480 /*    Yuxin Zhou, Microsoft Corporation                                   */
9481 /*                                                                        */
9482 /*  DESCRIPTION                                                           */
9483 /*                                                                        */
9484 /*    This function checks for errors in the DNS cache full notify        */
9485 /*    function call.                                                      */
9486 /*                                                                        */
9487 /*  INPUT                                                                 */
9488 /*                                                                        */
9489 /*    dns_ptr                           Pointer to DNS instance           */
9490 /*    cache_full_notify                 Cache full notify function        */
9491 /*                                                                        */
9492 /*  OUTPUT                                                                */
9493 /*                                                                        */
9494 /*    status                                Completion status             */
9495 /*                                                                        */
9496 /*  CALLS                                                                 */
9497 /*                                                                        */
9498 /*    _nx_dns_cache_notify_set         Actual cache notify set function   */
9499 /*                                                                        */
9500 /*  CALLED BY                                                             */
9501 /*                                                                        */
9502 /*    Application Code                                                    */
9503 /*                                                                        */
9504 /*  RELEASE HISTORY                                                       */
9505 /*                                                                        */
9506 /*    DATE              NAME                      DESCRIPTION             */
9507 /*                                                                        */
9508 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9509 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9510 /*                                            resulting in version 6.1    */
9511 /*                                                                        */
9512 /**************************************************************************/
_nxe_dns_cache_notify_set(NX_DNS * dns_ptr,VOID (* cache_full_notify_cb)(NX_DNS * dns_ptr))9513 UINT _nxe_dns_cache_notify_set(NX_DNS *dns_ptr, VOID (*cache_full_notify_cb)(NX_DNS *dns_ptr))
9514 {
9515 
9516 UINT    status;
9517 
9518 
9519     /* Check for invalid input pointers.  */
9520     if (!dns_ptr)
9521     {
9522         return(NX_PTR_ERROR);
9523     }
9524 
9525     /* Check for invalid non pointer input. */
9526     if (dns_ptr -> nx_dns_id != NX_DNS_ID)
9527     {
9528         return(NX_DNS_PARAM_ERROR);
9529     }
9530 
9531     /* Call actual DNS cache notify set function.  */
9532     status =  _nx_dns_cache_notify_set(dns_ptr, cache_full_notify_cb);
9533 
9534     /* Return status.  */
9535     return(status);
9536 }
9537 
9538 
9539 /**************************************************************************/
9540 /*                                                                        */
9541 /*  FUNCTION                                               RELEASE        */
9542 /*                                                                        */
9543 /*    _nx_dns_cache_notify_set                            PORTABLE C      */
9544 /*                                                           6.1          */
9545 /*  AUTHOR                                                                */
9546 /*                                                                        */
9547 /*    Yuxin Zhou, Microsoft Corporation                                   */
9548 /*                                                                        */
9549 /*  DESCRIPTION                                                           */
9550 /*                                                                        */
9551 /*    This function set the cache full notify function.                   */
9552 /*                                                                        */
9553 /*  INPUT                                                                 */
9554 /*                                                                        */
9555 /*    dns_ptr                           Pointer to DNS instance           */
9556 /*    cache_full_notify                 Cache full notify function        */
9557 /*                                                                        */
9558 /*  OUTPUT                                                                */
9559 /*                                                                        */
9560 /*    status                                Completion status             */
9561 /*                                                                        */
9562 /*  CALLS                                                                 */
9563 /*                                                                        */
9564 /*    tx_mutex_get                      Get the DNS mutex                 */
9565 /*    tx_mutex_put                      Put the DNS mutex                 */
9566 /*                                                                        */
9567 /*  CALLED BY                                                             */
9568 /*                                                                        */
9569 /*    Application Code                                                    */
9570 /*                                                                        */
9571 /*  RELEASE HISTORY                                                       */
9572 /*                                                                        */
9573 /*    DATE              NAME                      DESCRIPTION             */
9574 /*                                                                        */
9575 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9576 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9577 /*                                            resulting in version 6.1    */
9578 /*                                                                        */
9579 /**************************************************************************/
_nx_dns_cache_notify_set(NX_DNS * dns_ptr,VOID (* cache_full_notify_cb)(NX_DNS * dns_ptr))9580 UINT _nx_dns_cache_notify_set(NX_DNS *dns_ptr, VOID (*cache_full_notify_cb)(NX_DNS *dns_ptr))
9581 {
9582 
9583 
9584     /* Get the DNS mutex.  */
9585     tx_mutex_get(&(dns_ptr -> nx_dns_mutex), TX_WAIT_FOREVER);
9586 
9587     /* Set the cache notify.  */
9588     dns_ptr -> nx_dns_cache_full_notify = cache_full_notify_cb;
9589 
9590     /* Release the DNS mutex.  */
9591     tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
9592 
9593     return(NX_DNS_SUCCESS);
9594 }
9595 #endif /* NX_DNS_CACHE_ENABLE  */
9596 
9597 
9598 #ifdef NX_DNS_CACHE_ENABLE
9599 /**************************************************************************/
9600 /*                                                                        */
9601 /*  FUNCTION                                               RELEASE        */
9602 /*                                                                        */
9603 /*    _nxe_dns_cache_notify_clear                         PORTABLE C      */
9604 /*                                                           6.1          */
9605 /*  AUTHOR                                                                */
9606 /*                                                                        */
9607 /*    Yuxin Zhou, Microsoft Corporation                                   */
9608 /*                                                                        */
9609 /*  DESCRIPTION                                                           */
9610 /*                                                                        */
9611 /*    This function checks for errors in the DNS cache full notify clear  */
9612 /*    function call.                                                      */
9613 /*                                                                        */
9614 /*  INPUT                                                                 */
9615 /*                                                                        */
9616 /*    dns_ptr                           Pointer to DNS instance           */
9617 /*    cache_full_notify                 Cache full notify function        */
9618 /*                                                                        */
9619 /*  OUTPUT                                                                */
9620 /*                                                                        */
9621 /*    status                                Completion status             */
9622 /*                                                                        */
9623 /*  CALLS                                                                 */
9624 /*                                                                        */
9625 /*    _nx_dns_cache_notify_clear       Actual cache notify clear function */
9626 /*                                                                        */
9627 /*  CALLED BY                                                             */
9628 /*                                                                        */
9629 /*    Application Code                                                    */
9630 /*                                                                        */
9631 /*  RELEASE HISTORY                                                       */
9632 /*                                                                        */
9633 /*    DATE              NAME                      DESCRIPTION             */
9634 /*                                                                        */
9635 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9636 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9637 /*                                            resulting in version 6.1    */
9638 /*                                                                        */
9639 /**************************************************************************/
_nxe_dns_cache_notify_clear(NX_DNS * dns_ptr)9640 UINT _nxe_dns_cache_notify_clear(NX_DNS *dns_ptr)
9641 {
9642 
9643 UINT    status;
9644 
9645 
9646     /* Check for invalid input pointers.  */
9647     if (!dns_ptr)
9648     {
9649         return(NX_PTR_ERROR);
9650     }
9651 
9652     /* Check for invalid non pointer input. */
9653     if (dns_ptr -> nx_dns_id != NX_DNS_ID)
9654     {
9655         return(NX_DNS_PARAM_ERROR);
9656     }
9657 
9658     /* Call actual DNS cache notify clear function.  */
9659     status =  _nx_dns_cache_notify_clear(dns_ptr);
9660 
9661     /* Return status.  */
9662     return(status);
9663 }
9664 
9665 
9666 /**************************************************************************/
9667 /*                                                                        */
9668 /*  FUNCTION                                               RELEASE        */
9669 /*                                                                        */
9670 /*    _nx_dns_cache_notify_clear                          PORTABLE C      */
9671 /*                                                           6.1          */
9672 /*  AUTHOR                                                                */
9673 /*                                                                        */
9674 /*    Yuxin Zhou, Microsoft Corporation                                   */
9675 /*                                                                        */
9676 /*  DESCRIPTION                                                           */
9677 /*                                                                        */
9678 /*    This function clear the cache full notify function.                 */
9679 /*                                                                        */
9680 /*  INPUT                                                                 */
9681 /*                                                                        */
9682 /*    dns_ptr                           Pointer to DNS instance           */
9683 /*                                                                        */
9684 /*  OUTPUT                                                                */
9685 /*                                                                        */
9686 /*    status                                Completion status             */
9687 /*                                                                        */
9688 /*  CALLS                                                                 */
9689 /*                                                                        */
9690 /*    tx_mutex_get                      Get the DNS mutex                 */
9691 /*    tx_mutex_put                      Put the DNS mutex                 */
9692 /*                                                                        */
9693 /*  CALLED BY                                                             */
9694 /*                                                                        */
9695 /*    Application Code                                                    */
9696 /*                                                                        */
9697 /*  RELEASE HISTORY                                                       */
9698 /*                                                                        */
9699 /*    DATE              NAME                      DESCRIPTION             */
9700 /*                                                                        */
9701 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9702 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9703 /*                                            resulting in version 6.1    */
9704 /*                                                                        */
9705 /**************************************************************************/
_nx_dns_cache_notify_clear(NX_DNS * dns_ptr)9706 UINT _nx_dns_cache_notify_clear(NX_DNS *dns_ptr)
9707 {
9708 
9709 
9710     /* Get the DNS mutex.  */
9711     tx_mutex_get(&(dns_ptr -> nx_dns_mutex), TX_WAIT_FOREVER);
9712 
9713     /* Clear the cache notify.  */
9714     dns_ptr -> nx_dns_cache_full_notify = NX_NULL;
9715 
9716     /* Release the DNS mutex.  */
9717     tx_mutex_put(&(dns_ptr -> nx_dns_mutex));
9718 
9719     return(NX_DNS_SUCCESS);
9720 }
9721 #endif /* NX_DNS_CACHE_ENABLE  */
9722 
9723 
9724 #ifdef NX_DNS_CACHE_ENABLE
9725 /**************************************************************************/
9726 /*                                                                        */
9727 /*  FUNCTION                                               RELEASE        */
9728 /*                                                                        */
9729 /*    _nx_dns_cache_add_rr                                PORTABLE C      */
9730 /*                                                           6.1          */
9731 /*  AUTHOR                                                                */
9732 /*                                                                        */
9733 /*    Yuxin Zhou, Microsoft Corporation                                   */
9734 /*                                                                        */
9735 /*  DESCRIPTION                                                           */
9736 /*                                                                        */
9737 /*    This function adds the DNS  resource record into record buffer.     */
9738 /*                                                                        */
9739 /*  INPUT                                                                 */
9740 /*                                                                        */
9741 /*                                                                        */
9742 /*  OUTPUT                                                                */
9743 /*                                                                        */
9744 /*    status                                Completion status             */
9745 /*                                                                        */
9746 /*  CALLS                                                                 */
9747 /*                                                                        */
9748 /*                                                                        */
9749 /*  CALLED BY                                                             */
9750 /*                                                                        */
9751 /*                                                                        */
9752 /*  RELEASE HISTORY                                                       */
9753 /*                                                                        */
9754 /*    DATE              NAME                      DESCRIPTION             */
9755 /*                                                                        */
9756 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9757 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
9758 /*                                            verified memcpy use cases,  */
9759 /*                                            resulting in version 6.1    */
9760 /*                                                                        */
9761 /**************************************************************************/
_nx_dns_cache_add_rr(NX_DNS * dns_ptr,VOID * cache_ptr,UINT cache_size,NX_DNS_RR * record_ptr,NX_DNS_RR ** insert_ptr)9762 static UINT _nx_dns_cache_add_rr(NX_DNS *dns_ptr, VOID *cache_ptr, UINT cache_size, NX_DNS_RR *record_ptr, NX_DNS_RR **insert_ptr)
9763 {
9764 
9765 ALIGN_TYPE  *tail;
9766 ALIGN_TYPE  *head;
9767 NX_DNS_RR   *p;
9768 NX_DNS_RR   *rr;
9769 ULONG       elapsed_time;
9770 ULONG       current_time;
9771 ULONG       max_elapsed_time;
9772 
9773 
9774     /* Check the cache.  */
9775     if (cache_ptr == NX_NULL)
9776         return(NX_DNS_CACHE_ERROR);
9777 
9778     /* Initialize the parameters.  */
9779     max_elapsed_time = 0;
9780     current_time = tx_time_get();
9781 
9782     /* Get head and tail. */
9783     tail = (ALIGN_TYPE*)((UCHAR*)cache_ptr + cache_size) - 1;
9784     tail = (ALIGN_TYPE*)(*tail);
9785     head = (ALIGN_TYPE*)cache_ptr;
9786     head = (ALIGN_TYPE*)(*head);
9787 
9788     /* Set the pointer.  */
9789     rr = NX_NULL;
9790 
9791     /* Find an empty entry before head. */
9792     for(p = (NX_DNS_RR*)((ALIGN_TYPE*)cache_ptr + 1); p < (NX_DNS_RR*)head; p++)
9793     {
9794         if(!p -> nx_dns_rr_type)
9795         {
9796             rr = p;
9797             break;
9798         }
9799     }
9800 
9801     /* Check the record ptr.  */
9802     if (!rr)
9803     {
9804         /* Check whether the cache is full. */
9805         if((ALIGN_TYPE*)((UCHAR*)head + sizeof(NX_DNS_RR)) > tail)
9806         {
9807 
9808             /* Find an aging resource reocrd and repalce it.  */
9809             for(p = (NX_DNS_RR*)((ALIGN_TYPE*)cache_ptr + 1); p < (NX_DNS_RR*)head; p++)
9810             {
9811 
9812                 if (!p -> nx_dns_rr_name)
9813                     continue;
9814 
9815                 /* Calculate the elapsed time.  */
9816                 elapsed_time = current_time - p -> nx_dns_rr_last_used_time;
9817 
9818                 /* Step1. Find the expired resource record.  */
9819                 if ((elapsed_time / NX_IP_PERIODIC_RATE) >= p ->nx_dns_rr_ttl)
9820                 {
9821 
9822                     /* Yes, find it.  */
9823                     rr = p;
9824                     break;
9825                 }
9826 
9827                 /* Step2. Find the aging resource record.  */
9828                 if (elapsed_time >= max_elapsed_time)
9829                 {
9830                     rr = p;
9831                     max_elapsed_time = elapsed_time;
9832                 }
9833             }
9834 
9835             /* Check the replacement resource record.  */
9836             if (rr)
9837             {
9838 
9839                 /* Delete this record.  */
9840                 _nx_dns_cache_delete_rr(dns_ptr, cache_ptr, cache_size, rr);
9841 
9842                 /* Update the head.  */
9843                 head = (ALIGN_TYPE*)cache_ptr;
9844                 head = (ALIGN_TYPE*)(*head);
9845             }
9846             else
9847             {
9848                 return(NX_DNS_CACHE_ERROR);
9849             }
9850         }
9851         else
9852         {
9853             rr = (NX_DNS_RR*)head;
9854         }
9855     }
9856 
9857     /* Just copy it to cache_ptr. */
9858     memcpy(rr, record_ptr, sizeof(NX_DNS_RR)); /* Use case of memcpy is verified. */
9859 
9860     /* Update the resource record count.  */
9861     dns_ptr -> nx_dns_rr_count ++;
9862 
9863     /* Get the current time to set the elapsed time.  */
9864     rr -> nx_dns_rr_last_used_time = current_time;
9865 
9866     /* Set the insert ptr.  */
9867     if(insert_ptr != NX_NULL)
9868         *insert_ptr = rr;
9869 
9870     if((ALIGN_TYPE*)rr >= head)
9871     {
9872 
9873         /* Update HEAD when new record is added. */
9874         head = (ALIGN_TYPE*)cache_ptr;
9875         *head = (ALIGN_TYPE)(rr + 1);
9876     }
9877 
9878     return(NX_DNS_SUCCESS);
9879 }
9880 #endif /* NX_DNS_CACHE_ENABLE  */
9881 
9882 
9883 #ifdef NX_DNS_CACHE_ENABLE
9884 /**************************************************************************/
9885 /*                                                                        */
9886 /*  FUNCTION                                               RELEASE        */
9887 /*                                                                        */
9888 /*    _nx_dns_cache_find_answer                           PORTABLE C      */
9889 /*                                                           6.1          */
9890 /*  AUTHOR                                                                */
9891 /*                                                                        */
9892 /*    Yuxin Zhou, Microsoft Corporation                                   */
9893 /*                                                                        */
9894 /*  DESCRIPTION                                                           */
9895 /*                                                                        */
9896 /*    This function finds the answer of DNS query in record buffer.       */
9897 /*                                                                        */
9898 /*  INPUT                                                                 */
9899 /*                                                                        */
9900 /*    dns_ptr                           Pointer to DNS instance.          */
9901 /*    cache_ptr                         Pointer to the record buffer      */
9902 /*    query_name                        RR Query name                     */
9903 /*    query_type                        RR Query type                     */
9904 /*    buffer                            Pointer to buffer                 */
9905 /*    buffer_size                       The size of record_buffer         */
9906 /*    record_count                      The count of RR stored            */
9907 /*                                                                        */
9908 /*  OUTPUT                                                                */
9909 /*                                                                        */
9910 /*    status                                Completion status             */
9911 /*                                                                        */
9912 /*  CALLS                                                                 */
9913 /*                                                                        */
9914 /*    None                                                                */
9915 /*                                                                        */
9916 /*  CALLED BY                                                             */
9917 /*                                                                        */
9918 /*                                                                        */
9919 /*  RELEASE HISTORY                                                       */
9920 /*                                                                        */
9921 /*    DATE              NAME                      DESCRIPTION             */
9922 /*                                                                        */
9923 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9924 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
9925 /*                                            verified memcpy use cases,  */
9926 /*                                            resulting in version 6.1    */
9927 /*                                                                        */
9928 /**************************************************************************/
_nx_dns_cache_find_answer(NX_DNS * dns_ptr,VOID * cache_ptr,UCHAR * query_name,USHORT query_type,UCHAR * buffer,UINT buffer_size,UINT * record_count)9929 static UINT _nx_dns_cache_find_answer(NX_DNS *dns_ptr, VOID *cache_ptr, UCHAR *query_name, USHORT query_type, UCHAR *buffer, UINT buffer_size, UINT *record_count)
9930 {
9931 
9932 ALIGN_TYPE          *head;
9933 NX_DNS_RR           *p;
9934 ULONG               current_time;
9935 ULONG               elasped_ttl;
9936 UINT                old_count;
9937 UINT                answer_count;
9938 UCHAR               *buffer_prepend_ptr;
9939 UINT                 query_name_length;
9940 UINT                 name_string_length;
9941 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
9942 UCHAR               *buffer_append_ptr;
9943 NX_DNS_NS_ENTRY     *nx_dns_ns_entry_ptr;
9944 NX_DNS_MX_ENTRY     *nx_dns_mx_entry_ptr;
9945 NX_DNS_SRV_ENTRY    *nx_dns_srv_entry_ptr;
9946 NX_DNS_SOA_ENTRY    *nx_dns_soa_entry_ptr;
9947 UINT                 rname_string_length;
9948 UINT                 mname_string_length;
9949 #endif /* NX_DNS_ENABLE_EXTENDED_RR_TYPES  */
9950 
9951 
9952     /* Check the query name string.  */
9953     if (_nx_utility_string_length_check((CHAR *)query_name, &query_name_length, NX_DNS_NAME_MAX))
9954     {
9955 
9956         /* Return.  */
9957         return(NX_DNS_CACHE_ERROR);
9958     }
9959 
9960     /* Check the cache.  */
9961     if (cache_ptr == NX_NULL)
9962         return(NX_DNS_CACHE_ERROR);
9963 
9964     /* Initialize the value.  */
9965     old_count = 0;
9966     answer_count = 0;
9967     if(record_count)
9968         *record_count = 0;
9969 
9970     /* Set the buffer pointer.  */
9971     buffer_prepend_ptr = buffer;
9972 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
9973     buffer_append_ptr = buffer + buffer_size;
9974 #endif /* NX_DNS_ENABLE_EXTENDED_RR_TYPES  */
9975 
9976     /* Get the current time.  */
9977     current_time = tx_time_get();
9978 
9979     /* Get head. */
9980     head = (ALIGN_TYPE*)cache_ptr;
9981     head = (ALIGN_TYPE*)(*head);
9982 
9983     /* Lookup the cache to delete the expired resource record and find the answer.  */
9984     for(p = (NX_DNS_RR*)((UCHAR*)cache_ptr + sizeof(ALIGN_TYPE)); (ALIGN_TYPE*)p < head; p++)
9985     {
9986 
9987         /* Check whether the resource record is valid. */
9988         if (!p -> nx_dns_rr_name)
9989             continue;
9990 
9991         /* Calucate the elapsed time.  */
9992         elasped_ttl = (current_time - p -> nx_dns_rr_last_used_time) / NX_IP_PERIODIC_RATE;
9993 
9994         /* Compare the ttl.  */
9995         if (elasped_ttl >= p -> nx_dns_rr_ttl)
9996         {
9997 
9998             /* The resource record is expired, Delete the resource record.  */
9999             _nx_dns_cache_delete_rr(dns_ptr, dns_ptr -> nx_dns_cache, dns_ptr -> nx_dns_cache_size, p);
10000             continue;
10001         }
10002 
10003         /* Check the resource record type.  */
10004         if (p -> nx_dns_rr_type != query_type)
10005             continue;
10006 
10007         /* Check the resource record name.  */
10008         if (_nx_dns_name_match(p -> nx_dns_rr_name, query_name, query_name_length))
10009             continue;
10010 
10011         /* Update the elasped time and ttl.  */
10012         p -> nx_dns_rr_last_used_time = current_time;
10013         p -> nx_dns_rr_ttl -= elasped_ttl;
10014 
10015         /* Yes, get the answer.  */
10016 
10017         /* Check the type. */
10018         switch (query_type)
10019         {
10020 
10021             case NX_DNS_RR_TYPE_A:
10022             {
10023 
10024                 /* Check the buffer size.  */
10025                 if (buffer_size < 4)
10026                     break;
10027 
10028                 /* Set the IPv4 address.  */
10029                 *(ULONG *)buffer_prepend_ptr = p -> nx_dns_rr_rdata.nx_dns_rr_rdata_a.nx_dns_rr_a_address;
10030 
10031                 /* Update the count and pointer.  */
10032                 answer_count++;
10033                 buffer_size -= 4;
10034                 buffer_prepend_ptr += 4;
10035 
10036                 break;
10037             }
10038             case NX_DNS_RR_TYPE_AAAA:
10039             {
10040 
10041                 /* Check the buffer size.  */
10042                 if (buffer_size < 16)
10043                     break;
10044 
10045                 /* Set the IPv6 address.  */
10046                 *(ULONG *)buffer_prepend_ptr = p -> nx_dns_rr_rdata.nx_dns_rr_rdata_aaaa.nx_dns_rr_aaaa_address[0];
10047                 *(ULONG *)(buffer_prepend_ptr + 4) = p -> nx_dns_rr_rdata.nx_dns_rr_rdata_aaaa.nx_dns_rr_aaaa_address[1];
10048                 *(ULONG *)(buffer_prepend_ptr + 8) = p -> nx_dns_rr_rdata.nx_dns_rr_rdata_aaaa.nx_dns_rr_aaaa_address[2];
10049                 *(ULONG *)(buffer_prepend_ptr + 12) = p -> nx_dns_rr_rdata.nx_dns_rr_rdata_aaaa.nx_dns_rr_aaaa_address[3];
10050 
10051                 /* Update the count and pointer.  */
10052                 answer_count++;
10053                 buffer_size -= 16;
10054                 buffer_prepend_ptr += 16;
10055 
10056                 break;
10057             }
10058             case NX_DNS_RR_TYPE_PTR:
10059 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
10060             case NX_DNS_RR_TYPE_CNAME:
10061             case NX_DNS_RR_TYPE_TXT:
10062 #endif
10063             {
10064 
10065                 /* PTR, CNAME, TXT record should be only one answer, union: ptr name, cname name, and txt data.  */
10066                 /* Check the name string.  */
10067                 if (_nx_utility_string_length_check((CHAR *)p -> nx_dns_rr_rdata.nx_dns_rr_rdata_ptr.nx_dns_rr_ptr_name, &name_string_length, NX_DNS_NAME_MAX))
10068                 {
10069 
10070                     /* Return.  */
10071                     return(NX_DNS_CACHE_ERROR);
10072                 }
10073 
10074                 /* Make sure there is enough room to store the name and null-terminator.  */
10075                 if (buffer_size < (name_string_length + 1))
10076                 {
10077 
10078                     /* Return.  */
10079                     return(NX_DNS_CACHE_ERROR);
10080                 }
10081 
10082                 /* Set the cname string.  */
10083                 memcpy((char *)buffer_prepend_ptr, (char *)p -> nx_dns_rr_rdata.nx_dns_rr_rdata_ptr.nx_dns_rr_ptr_name, name_string_length); /* Use case of memcpy is verified. */
10084 
10085                 /* Return success.  */
10086                 return (NX_DNS_SUCCESS);
10087             }
10088 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
10089             case NX_DNS_RR_TYPE_NS:
10090             {
10091 
10092                 /* Check the name string.  */
10093                 if (_nx_utility_string_length_check((CHAR *)p -> nx_dns_rr_rdata.nx_dns_rr_rdata_ns.nx_dns_rr_ns_name, &name_string_length, NX_DNS_NAME_MAX))
10094                 {
10095 
10096                     /* Return.  */
10097                     return(NX_DNS_CACHE_ERROR);
10098                 }
10099 
10100                 /* Make sure there is enough room to store the name and null-terminator.  */
10101                 if (buffer_size < (sizeof(NX_DNS_NS_ENTRY) + name_string_length + 1))
10102                     break;
10103 
10104                 /* Set the ns entry pointer.  */
10105                 nx_dns_ns_entry_ptr = (NX_DNS_NS_ENTRY *)(buffer_prepend_ptr);
10106 
10107                 /* Update the store pointer. include the null flag '\0'.  */
10108                 buffer_append_ptr -= (name_string_length + 1);
10109 
10110                 /* Set the ns string.  */
10111                 memcpy((char *)buffer_append_ptr, (char *)p -> nx_dns_rr_rdata.nx_dns_rr_rdata_ns.nx_dns_rr_ns_name, name_string_length); /* Use case of memcpy is verified. */
10112                 nx_dns_ns_entry_ptr -> nx_dns_ns_hostname_ptr = buffer_append_ptr;
10113 
10114                 /* Update the count and pointer.  */
10115                 answer_count++;
10116                 buffer_size -= (sizeof(NX_DNS_NS_ENTRY) + name_string_length + 1);
10117                 buffer_prepend_ptr += sizeof(NX_DNS_NS_ENTRY);
10118 
10119                 break;
10120             }
10121             case NX_DNS_RR_TYPE_MX:
10122             {
10123 
10124                 /* Check the name string.  */
10125                 if (_nx_utility_string_length_check((CHAR *)(p -> nx_dns_rr_rdata.nx_dns_rr_rdata_mx.nx_dns_rr_mx_rdata + 2), &name_string_length, NX_DNS_NAME_MAX))
10126                 {
10127 
10128                     /* Return.  */
10129                     return(NX_DNS_CACHE_ERROR);
10130                 }
10131 
10132                 /* Make sure there is enough room to store the name and null-terminator.  */
10133                 if (buffer_size < (sizeof(NX_DNS_MX_ENTRY) + name_string_length + 1))
10134                     break;
10135 
10136                 /* Set the mx entry pointer.  */
10137                 nx_dns_mx_entry_ptr = (NX_DNS_MX_ENTRY *)(buffer_prepend_ptr);
10138 
10139                 /* Set the mx preference.  */
10140                 nx_dns_mx_entry_ptr -> nx_dns_mx_preference = *(USHORT *)p -> nx_dns_rr_rdata.nx_dns_rr_rdata_mx.nx_dns_rr_mx_rdata;
10141 
10142                 /* Update the store pointer. include the null flag '\0'.  */
10143                 buffer_append_ptr -= (name_string_length + 1);
10144 
10145                 /* Set the mx string.  */
10146                 memcpy((char *)buffer_append_ptr, (char *)(p -> nx_dns_rr_rdata.nx_dns_rr_rdata_mx.nx_dns_rr_mx_rdata + 2), name_string_length); /* Use case of memcpy is verified. */
10147                 nx_dns_mx_entry_ptr -> nx_dns_mx_hostname_ptr = buffer_append_ptr;
10148 
10149                 /* Update the count and pointer.  */
10150                 answer_count++;
10151                 buffer_size -= (sizeof(NX_DNS_MX_ENTRY) + name_string_length + 1);
10152                 buffer_prepend_ptr += sizeof(NX_DNS_MX_ENTRY);
10153 
10154                 break;
10155             }
10156             case NX_DNS_RR_TYPE_SRV:
10157             {
10158 
10159                 /* Check the name string.  */
10160                 if (_nx_utility_string_length_check((CHAR *)(p -> nx_dns_rr_rdata.nx_dns_rr_rdata_srv.nx_dns_rr_srv_rdata + 6), &name_string_length, NX_DNS_NAME_MAX))
10161                 {
10162 
10163                     /* Return.  */
10164                     return(NX_DNS_CACHE_ERROR);
10165                 }
10166 
10167                 /* Make sure there is enough room to store the name and null-terminator.  */
10168                 if (buffer_size < (sizeof(NX_DNS_SRV_ENTRY) + name_string_length + 1))
10169                     break;
10170 
10171                 /* Set the srv entry pointer.  */
10172                 nx_dns_srv_entry_ptr = (NX_DNS_SRV_ENTRY *)(buffer_prepend_ptr);
10173 
10174                 /* Set the priority, weight and port number.  */
10175                 nx_dns_srv_entry_ptr -> nx_dns_srv_priority = *(USHORT *)(p -> nx_dns_rr_rdata.nx_dns_rr_rdata_srv.nx_dns_rr_srv_rdata);
10176                 nx_dns_srv_entry_ptr -> nx_dns_srv_weight = *(USHORT *)(p -> nx_dns_rr_rdata.nx_dns_rr_rdata_srv.nx_dns_rr_srv_rdata + 2);
10177                 nx_dns_srv_entry_ptr -> nx_dns_srv_port_number = *(USHORT *)(p -> nx_dns_rr_rdata.nx_dns_rr_rdata_srv.nx_dns_rr_srv_rdata + 4);
10178 
10179                 /* Update the store pointer. include the null flag '\0'.  */
10180                 buffer_append_ptr -= (name_string_length + 1);
10181 
10182                 /* Set the srv string.  */
10183                 memcpy((char *)buffer_append_ptr, (char *)(p -> nx_dns_rr_rdata.nx_dns_rr_rdata_srv.nx_dns_rr_srv_rdata + 6), name_string_length); /* Use case of memcpy is verified. */
10184                 nx_dns_srv_entry_ptr -> nx_dns_srv_hostname_ptr = buffer_append_ptr;
10185 
10186                 /* Update the count and pointer.  */
10187                 answer_count++;
10188                 buffer_size -= (sizeof(NX_DNS_SRV_ENTRY) + name_string_length + 1);
10189                 buffer_prepend_ptr += sizeof(NX_DNS_SRV_ENTRY);
10190 
10191                 break;
10192             }
10193             case NX_DNS_RR_TYPE_SOA:
10194             {
10195 
10196                 /* Check the mname string.  */
10197                 if (_nx_utility_string_length_check((CHAR *)(p -> nx_dns_rr_rdata.nx_dns_rr_rdata_soa.nx_dns_rr_soa_rdata), &mname_string_length, NX_DNS_NAME_MAX))
10198                 {
10199 
10200                     /* Return.  */
10201                     return(NX_DNS_CACHE_ERROR);
10202                 }
10203 
10204                 /* Check the rname string.  */
10205                 if (_nx_utility_string_length_check((CHAR *)(p -> nx_dns_rr_rdata.nx_dns_rr_rdata_soa.nx_dns_rr_soa_rdata + mname_string_length + 1), &rname_string_length, NX_DNS_NAME_MAX))
10206                 {
10207 
10208                     /* Return.  */
10209                     return(NX_DNS_CACHE_ERROR);
10210                 }
10211 
10212                 /* Make sure there is enough room to store the name and null-terminator.  */
10213                 if (buffer_size < (sizeof(NX_DNS_SOA_ENTRY) + mname_string_length + rname_string_length + 2))
10214                 {
10215 
10216                     /* Return.  */
10217                     return(NX_DNS_CACHE_ERROR);
10218                 }
10219 
10220                 /* Set the soa entry pointer.  */
10221                 nx_dns_soa_entry_ptr = (NX_DNS_SOA_ENTRY *)(buffer_prepend_ptr);
10222 
10223                 /* Update the store pointer. include the null flag '\0'.  */
10224                 buffer_append_ptr -= (mname_string_length + rname_string_length + 2);
10225 
10226                 /* Set the soa mname string.  */
10227                 memcpy((char *)(buffer_append_ptr), (char *)p -> nx_dns_rr_rdata.nx_dns_rr_rdata_soa.nx_dns_rr_soa_rdata, mname_string_length); /* Use case of memcpy is verified. */
10228                 nx_dns_soa_entry_ptr -> nx_dns_soa_host_mname_ptr = buffer_append_ptr;
10229 
10230                 /* Set the soa rname string.  */
10231                 memcpy((char *)(buffer_append_ptr + mname_string_length + 1), (const char *)(p -> nx_dns_rr_rdata.nx_dns_rr_rdata_soa.nx_dns_rr_soa_rdata + mname_string_length + 1), rname_string_length); /* Use case of memcpy is verified. */
10232                 nx_dns_soa_entry_ptr -> nx_dns_soa_host_rname_ptr = (buffer_append_ptr + mname_string_length + 1);
10233 
10234                 /* Set the SOA Serial, Refresh, Retry, Expire, Minmum.  */
10235                 nx_dns_soa_entry_ptr -> nx_dns_soa_serial = *(ULONG *)(p -> nx_dns_rr_rdata.nx_dns_rr_rdata_soa.nx_dns_rr_soa_rdata + mname_string_length + rname_string_length + 2);
10236                 nx_dns_soa_entry_ptr -> nx_dns_soa_refresh = *(ULONG *)(p -> nx_dns_rr_rdata.nx_dns_rr_rdata_soa.nx_dns_rr_soa_rdata + mname_string_length + rname_string_length + 6);
10237                 nx_dns_soa_entry_ptr -> nx_dns_soa_retry = *(ULONG *)(p -> nx_dns_rr_rdata.nx_dns_rr_rdata_soa.nx_dns_rr_soa_rdata + mname_string_length + rname_string_length + 10);
10238                 nx_dns_soa_entry_ptr -> nx_dns_soa_expire = *(ULONG *)(p -> nx_dns_rr_rdata.nx_dns_rr_rdata_soa.nx_dns_rr_soa_rdata + mname_string_length + rname_string_length + 14);
10239                 nx_dns_soa_entry_ptr -> nx_dns_soa_minmum = *(ULONG *)(p -> nx_dns_rr_rdata.nx_dns_rr_rdata_soa.nx_dns_rr_soa_rdata + mname_string_length + rname_string_length + 18);
10240 
10241                 /* Return success.  */
10242                 return (NX_DNS_SUCCESS);
10243             }
10244 #endif /* NX_DNS_ENABLE_EXTENDED_RR_TYPES  */
10245         }
10246 
10247         /* Check if the answer count is updated.  */
10248         if (old_count == answer_count)
10249         {
10250 
10251             /* The answer count is not updated, means the buffer is not enough, stop finding.  */
10252             break;
10253         }
10254         else
10255         {
10256             /* Update the old count.  */
10257             old_count = answer_count;
10258         }
10259     }
10260 
10261     /* Check the answer count.  */
10262     if (answer_count)
10263     {
10264 
10265         /* Update the record count.  */
10266         if (record_count)
10267             *record_count = answer_count;
10268         return (NX_DNS_SUCCESS);
10269     }
10270     else
10271     {
10272         return(NX_DNS_ERROR);
10273     }
10274 }
10275 #endif /* NX_DNS_CACHE_ENABLE  */
10276 
10277 
10278 #ifdef NX_DNS_CACHE_ENABLE
10279 /**************************************************************************/
10280 /*                                                                        */
10281 /*  FUNCTION                                               RELEASE        */
10282 /*                                                                        */
10283 /*    _nx_dns_cache_delete_rr                             PORTABLE C      */
10284 /*                                                           6.1          */
10285 /*  AUTHOR                                                                */
10286 /*                                                                        */
10287 /*    Yuxin Zhou, Microsoft Corporation                                   */
10288 /*                                                                        */
10289 /*  DESCRIPTION                                                           */
10290 /*                                                                        */
10291 /*    This function deletes the DNS resource record from cache.           */
10292 /*                                                                        */
10293 /*  INPUT                                                                 */
10294 /*                                                                        */
10295 /*                                                                        */
10296 /*  OUTPUT                                                                */
10297 /*                                                                        */
10298 /*    status                                Completion status             */
10299 /*                                                                        */
10300 /*  CALLS                                                                 */
10301 /*                                                                        */
10302 /*                                                                        */
10303 /*  CALLED BY                                                             */
10304 /*                                                                        */
10305 /*                                                                        */
10306 /*  RELEASE HISTORY                                                       */
10307 /*                                                                        */
10308 /*    DATE              NAME                      DESCRIPTION             */
10309 /*                                                                        */
10310 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10311 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10312 /*                                            resulting in version 6.1    */
10313 /*                                                                        */
10314 /**************************************************************************/
_nx_dns_cache_delete_rr(NX_DNS * dns_ptr,VOID * cache_ptr,UINT cache_size,NX_DNS_RR * record_ptr)10315 static UINT _nx_dns_cache_delete_rr(NX_DNS *dns_ptr, VOID *cache_ptr, UINT cache_size, NX_DNS_RR *record_ptr)
10316 {
10317 
10318 ALIGN_TYPE  *head;
10319 
10320 
10321     /* Check the cache.  */
10322     if (cache_ptr == NX_NULL)
10323         return(NX_DNS_CACHE_ERROR);
10324 
10325     /* Delete the resource record strings. */
10326     _nx_dns_cache_delete_rr_string(dns_ptr, cache_ptr,cache_size, record_ptr);
10327 
10328     /* Zero out the record. */
10329     memset(record_ptr, 0, sizeof(NX_DNS_RR));
10330 
10331     /* Update the resource record count.  */
10332     dns_ptr -> nx_dns_rr_count --;
10333 
10334     /* Get head. */
10335     head = (ALIGN_TYPE*)cache_ptr;
10336     head = (ALIGN_TYPE*)(*head);
10337 
10338     /* Move HEAD if the last RR is deleted. */
10339     if(record_ptr == ((NX_DNS_RR*)head - 1))
10340     {
10341         while(!record_ptr -> nx_dns_rr_type)
10342         {
10343             record_ptr--;
10344             if(record_ptr < (NX_DNS_RR*)cache_ptr)
10345                 break;
10346         }
10347         *((ALIGN_TYPE*)cache_ptr) = (ALIGN_TYPE)(record_ptr + 1);
10348     }
10349 
10350     return(NX_SUCCESS);
10351 }
10352 #endif /* NX_DNS_CACHE_ENABLE  */
10353 
10354 
10355 #ifdef NX_DNS_CACHE_ENABLE
10356 /**************************************************************************/
10357 /*                                                                        */
10358 /*  FUNCTION                                               RELEASE        */
10359 /*                                                                        */
10360 /*    _nx_dns_cache_delete_rr_string                      PORTABLE C      */
10361 /*                                                           6.1.9        */
10362 /*  AUTHOR                                                                */
10363 /*                                                                        */
10364 /*    Yuxin Zhou, Microsoft Corporation                                   */
10365 /*                                                                        */
10366 /*  DESCRIPTION                                                           */
10367 /*                                                                        */
10368 /*    This function deletes the DNS entry string from the record cache.   */
10369 /*                                                                        */
10370 /*  INPUT                                                                 */
10371 /*                                                                        */
10372 /*                                                                        */
10373 /*  OUTPUT                                                                */
10374 /*                                                                        */
10375 /*    None                                                                */
10376 /*                                                                        */
10377 /*  CALLS                                                                 */
10378 /*                                                                        */
10379 /*                                                                        */
10380 /*  CALLED BY                                                             */
10381 /*                                                                        */
10382 /*                                                                        */
10383 /*  RELEASE HISTORY                                                       */
10384 /*                                                                        */
10385 /*    DATE              NAME                      DESCRIPTION             */
10386 /*                                                                        */
10387 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10388 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10389 /*                                            resulting in version 6.1    */
10390 /*  10-15-2021     Yuxin Zhou               Modified comment(s),          */
10391 /*                                            fixed compiler warnings,    */
10392 /*                                            resulting in version 6.1.9  */
10393 /*                                                                        */
10394 /**************************************************************************/
_nx_dns_cache_delete_rr_string(NX_DNS * dns_ptr,VOID * cache_ptr,UINT cache_size,NX_DNS_RR * record_ptr)10395 static UINT _nx_dns_cache_delete_rr_string(NX_DNS *dns_ptr, VOID *cache_ptr, UINT cache_size, NX_DNS_RR *record_ptr)
10396 {
10397 
10398 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
10399 UINT    string_len;
10400 UINT    size;
10401 #endif /* NX_DNS_ENABLE_EXTENDED_RR_TYPES */
10402 
10403 
10404     /* Check the cache.  */
10405     if (cache_ptr == NX_NULL)
10406         return(NX_DNS_CACHE_ERROR);
10407 
10408     /* Compare the resource record type.  */
10409     if((record_ptr -> nx_dns_rr_type == NX_DNS_RR_TYPE_PTR)
10410 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
10411        ||
10412        (record_ptr -> nx_dns_rr_type == NX_DNS_RR_TYPE_TXT) ||
10413        (record_ptr -> nx_dns_rr_type == NX_DNS_RR_TYPE_CNAME) ||
10414        (record_ptr -> nx_dns_rr_type == NX_DNS_RR_TYPE_NS)
10415 #endif
10416         )
10417     {
10418 
10419         /* Delete the rdata name string. */
10420         _nx_dns_cache_delete_string(dns_ptr, cache_ptr, cache_size, record_ptr -> nx_dns_rr_rdata.nx_dns_rr_rdata_ptr.nx_dns_rr_ptr_name, 0);
10421     }
10422     else if (record_ptr -> nx_dns_rr_type == NX_DNS_RR_TYPE_AAAA)
10423     {
10424 
10425         /* Delete the IPv6 address string. */
10426         _nx_dns_cache_delete_string(dns_ptr, cache_ptr, cache_size, record_ptr -> nx_dns_rr_rdata.nx_dns_rr_rdata_aaaa.nx_dns_rr_aaaa_address, 16);
10427     }
10428 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
10429     else if (record_ptr -> nx_dns_rr_type == NX_DNS_RR_TYPE_SRV)
10430     {
10431 
10432         /* Compute the SRV rdata length.  */
10433         if (_nx_utility_string_length_check((CHAR *)(record_ptr -> nx_dns_rr_rdata.nx_dns_rr_rdata_srv.nx_dns_rr_srv_rdata), &size, NX_DNS_NAME_MAX))
10434         {
10435 
10436             /* Return.  */
10437             return(NX_DNS_CACHE_ERROR);
10438         }
10439         string_len = (UINT)(size + 6);
10440 
10441         /* Delete the SRV rdata string. */
10442         _nx_dns_cache_delete_string(dns_ptr, cache_ptr, cache_size, record_ptr -> nx_dns_rr_rdata.nx_dns_rr_rdata_srv.nx_dns_rr_srv_rdata, string_len);
10443     }
10444     else if (record_ptr -> nx_dns_rr_type == NX_DNS_RR_TYPE_MX)
10445     {
10446 
10447         /* Compute the MX rdata length.  */
10448         if (_nx_utility_string_length_check((CHAR *)(record_ptr -> nx_dns_rr_rdata.nx_dns_rr_rdata_mx.nx_dns_rr_mx_rdata), &size, NX_DNS_NAME_MAX))
10449         {
10450 
10451             /* Return.  */
10452             return(NX_DNS_CACHE_ERROR);
10453         }
10454         string_len = (UINT)(size + 2);
10455 
10456         /* Delete the MX rdata string. */
10457         _nx_dns_cache_delete_string(dns_ptr, cache_ptr, cache_size, record_ptr -> nx_dns_rr_rdata.nx_dns_rr_rdata_mx.nx_dns_rr_mx_rdata, string_len);
10458     }
10459     else if (record_ptr -> nx_dns_rr_type == NX_DNS_RR_TYPE_SOA)
10460     {
10461 
10462         /* Compute the SOA rdata length.  */
10463         if (_nx_utility_string_length_check((CHAR *)(record_ptr -> nx_dns_rr_rdata.nx_dns_rr_rdata_soa.nx_dns_rr_soa_rdata), &size, NX_DNS_NAME_MAX))
10464         {
10465 
10466             /* Return.  */
10467             return(NX_DNS_CACHE_ERROR);
10468         }
10469         string_len = size; /* MNAME  */
10470         string_len += 1; /* '\0'  */
10471 
10472         if (_nx_utility_string_length_check((CHAR *)(record_ptr -> nx_dns_rr_rdata.nx_dns_rr_rdata_soa.nx_dns_rr_soa_rdata + string_len), &size, NX_DNS_NAME_MAX))
10473         {
10474 
10475             /* Return.  */
10476             return(NX_DNS_CACHE_ERROR);
10477         }
10478         string_len += size; /* RNAME  */
10479         string_len += 1;  /* '\0'  */
10480         string_len += 20; /* Serial, Refresh, Retry, Expire, Minmum.  */
10481 
10482         /* Delete the SRV rdata string. */
10483         _nx_dns_cache_delete_string(dns_ptr, cache_ptr, cache_size, record_ptr -> nx_dns_rr_rdata.nx_dns_rr_rdata_soa.nx_dns_rr_soa_rdata, string_len);
10484     }
10485 #endif
10486 
10487     /* Delete the name string. */
10488     _nx_dns_cache_delete_string(dns_ptr, cache_ptr, cache_size, record_ptr -> nx_dns_rr_name, 0);
10489 
10490     return(NX_DNS_SUCCESS);
10491 }
10492 #endif /* NX_DNS_CACHE_ENABLE  */
10493 
10494 
10495 #ifdef NX_DNS_CACHE_ENABLE
10496 /**************************************************************************/
10497 /*                                                                        */
10498 /*  FUNCTION                                               RELEASE        */
10499 /*                                                                        */
10500 /*    _nx_dns_cache_add_string                            PORTABLE C      */
10501 /*                                                           6.1          */
10502 /*  AUTHOR                                                                */
10503 /*                                                                        */
10504 /*    Yuxin Zhou, Microsoft Corporation                                   */
10505 /*                                                                        */
10506 /*  DESCRIPTION                                                           */
10507 /*                                                                        */
10508 /*    This function adds or finds the DNS string in the cache.            */
10509 /*                                                                        */
10510 /*  INPUT                                                                 */
10511 /*                                                                        */
10512 /*                                                                        */
10513 /*  OUTPUT                                                                */
10514 /*                                                                        */
10515 /*    status                                Completion status             */
10516 /*                                                                        */
10517 /*  CALLS                                                                 */
10518 /*                                                                        */
10519 /*    none                                                                */
10520 /*                                                                        */
10521 /*  CALLED BY                                                             */
10522 /*                                                                        */
10523 /*                                                                        */
10524 /*  RELEASE HISTORY                                                       */
10525 /*                                                                        */
10526 /*    DATE              NAME                      DESCRIPTION             */
10527 /*                                                                        */
10528 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10529 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
10530 /*                                            verified memcpy use cases,  */
10531 /*                                            resulting in version 6.1    */
10532 /*                                                                        */
10533 /**************************************************************************/
_nx_dns_cache_add_string(NX_DNS * dns_ptr,VOID * cache_ptr,UINT cache_size,VOID * string_ptr,UINT string_size,VOID ** insert_ptr)10534 static UINT _nx_dns_cache_add_string(NX_DNS *dns_ptr, VOID *cache_ptr, UINT cache_size, VOID *string_ptr, UINT string_size, VOID **insert_ptr)
10535 {
10536 
10537 ALIGN_TYPE  *tail;
10538 ALIGN_TYPE  *head;
10539 UINT        string_len;
10540 USHORT      len, cnt;
10541 USHORT      min_len = 0xFFFF;
10542 UCHAR       *p, *available, *start;
10543 
10544 
10545     /* Check the cache.  */
10546     if (cache_ptr == NX_NULL)
10547         return(NX_DNS_CACHE_ERROR);
10548 
10549     /* Get head and tail. */
10550     tail = (ALIGN_TYPE*)((UCHAR*)cache_ptr + cache_size) - 1;
10551     p = (UCHAR*)tail;
10552     tail = (ALIGN_TYPE*)(*tail);
10553     head = (ALIGN_TYPE*)cache_ptr;
10554     head = (ALIGN_TYPE*)(*head);
10555 
10556     /* Calculate the amount of memory needed to store this string, including CNT and LEN fields. */
10557 
10558     /* Make the length 4 bytes align. */
10559     string_len = string_size;
10560 
10561     /* Add the length of CNT and LEN fields.  */
10562     string_len = ((string_len & 0xFFFFFFFC) + 8) & 0xFFFFFFFF;
10563 
10564     available = (UCHAR*)tail;
10565     while(p > (UCHAR*)tail)
10566     {
10567 
10568         /* Get len and cnt. */
10569         len = *((USHORT*)(p - 2));
10570         cnt = *((USHORT*)(p - 4));
10571         start = p - len;
10572 
10573         if((len == string_len) &&
10574            (!_nx_dns_name_match(start, string_ptr, string_size)))
10575         {
10576 
10577             /* The same string exists in the string table. */
10578             if(insert_ptr)
10579                 *insert_ptr = start;
10580 
10581             /* Increase the use count CNT. */
10582             cnt++;
10583             *((USHORT*)(p - 4)) = cnt;
10584 
10585             return(NX_SUCCESS);
10586         }
10587 
10588         /* This slot is not being used. The size of the slot is a smaller
10589            fit for this string. */
10590         if((cnt == 0) && (len >= string_len) && (len < min_len))
10591         {
10592 
10593             /* This place is better to insert. */
10594             available = p;
10595             min_len = len;
10596         }
10597 
10598         /* Move to the next string. */
10599         p = start;
10600     }
10601 
10602     /* If we reach this point, the string needs to be added to the string table. */
10603     if(available == (UCHAR*)tail)
10604     {
10605 
10606         /* Make sure the service cache still has room to add this string
10607            (without overwriting the RR area.) */
10608         if(((UCHAR*)tail - string_len) < (UCHAR*)head)
10609         {
10610 
10611             /* This service cache does not have room for the string table to grow. */
10612             /* Invoke user-installed cache full notify function .*/
10613             if(dns_ptr -> nx_dns_cache_full_notify)
10614             {
10615 
10616                 /* Call the notify function.  */
10617                 (dns_ptr -> nx_dns_cache_full_notify)(dns_ptr);
10618             }
10619 
10620             /* The buffer is full. */
10621             return(NX_DNS_SIZE_ERROR);
10622         }
10623 
10624         /* Update TAIL. */
10625         *((ALIGN_TYPE*)((UCHAR*)cache_ptr + cache_size) - 1) = (ALIGN_TYPE)(available - string_len);
10626 
10627     }
10628     else if(string_len < min_len)
10629     {
10630 
10631         /* Set the LEN for remaining space. */
10632         *((USHORT*)(available - 2 - string_len)) = (USHORT)(min_len - string_len);
10633     }
10634 
10635     /* Set LEN and CNT. */
10636     *((USHORT*)(available - 2)) = (USHORT)string_len;
10637     *((USHORT*)(available - 4)) = 1;
10638 
10639     /* Clear last 4 bytes. */
10640     *((ULONG*)(available - 8)) = 0;
10641 
10642     /* Insert string to cache. */
10643     memcpy(available - string_len, string_ptr, string_size); /* Use case of memcpy is verified. */
10644 
10645     /* Set end character 0. */
10646     *(available - string_len + string_size) = 0;
10647 
10648     /* Update the string length and count .  */
10649     dns_ptr -> nx_dns_string_count ++;
10650     dns_ptr -> nx_dns_string_bytes += string_len;
10651 
10652     if(insert_ptr)
10653         *insert_ptr = available - string_len;
10654 
10655     return(NX_SUCCESS);
10656 }
10657 #endif /* NX_DNS_CACHE_ENABLE  */
10658 
10659 
10660 #ifdef NX_DNS_CACHE_ENABLE
10661 /**************************************************************************/
10662 /*                                                                        */
10663 /*  FUNCTION                                               RELEASE        */
10664 /*                                                                        */
10665 /*    _nx_dns_cache_delete_string                         PORTABLE C      */
10666 /*                                                           6.1          */
10667 /*  AUTHOR                                                                */
10668 /*                                                                        */
10669 /*    Yuxin Zhou, Microsoft Corporation                                   */
10670 /*                                                                        */
10671 /*  DESCRIPTION                                                           */
10672 /*                                                                        */
10673 /*    This function deletes the DNS string from the record buffer.        */
10674 /*                                                                        */
10675 /*  INPUT                                                                 */
10676 /*                                                                        */
10677 /*    dns_ptr                           Pointer to DNS instance.          */
10678 /*    cache_ptr                         Pointer to the record buffer      */
10679 /*    cache_size                        The size of buffer.               */
10680 /*    string_ptr                        Pointer to the string             */
10681 /*                                                                        */
10682 /*  OUTPUT                                                                */
10683 /*                                                                        */
10684 /*    status                                Completion status             */
10685 /*                                                                        */
10686 /*  CALLS                                                                 */
10687 /*                                                                        */
10688 /*    None                                                                */
10689 /*                                                                        */
10690 /*  CALLED BY                                                             */
10691 /*                                                                        */
10692 /*                                                                        */
10693 /*  RELEASE HISTORY                                                       */
10694 /*                                                                        */
10695 /*    DATE              NAME                      DESCRIPTION             */
10696 /*                                                                        */
10697 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10698 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10699 /*                                            resulting in version 6.1    */
10700 /*                                                                        */
10701 /**************************************************************************/
_nx_dns_cache_delete_string(NX_DNS * dns_ptr,VOID * cache_ptr,UINT cache_size,VOID * string_ptr,UINT string_len)10702 static UINT _nx_dns_cache_delete_string(NX_DNS *dns_ptr, VOID *cache_ptr, UINT cache_size, VOID *string_ptr, UINT string_len)
10703 {
10704 
10705 ALIGN_TYPE  *tail;
10706 ALIGN_TYPE  *end;
10707 USHORT      cnt;
10708 
10709 
10710     /* Check the cache.  */
10711     if (cache_ptr == NX_NULL)
10712         return(NX_DNS_CACHE_ERROR);
10713 
10714     /* Validate input parameter. */
10715     if (string_ptr == NX_NULL)
10716         return(NX_DNS_PARAM_ERROR);
10717 
10718     /* Validate string. */
10719     if (_nx_utility_string_length_check((CHAR *)string_ptr, &string_len, NX_DNS_NAME_MAX))
10720         return(NX_DNS_SIZE_ERROR);
10721 
10722     /* Add the length of CNT and LEN fields.  */
10723     /* Also make the total length 4 bytes align. */
10724     string_len = ((string_len & 0xFFFFFFFC) + 8) & 0xFFFFFFFF;
10725 
10726     end = (ALIGN_TYPE*)((UCHAR*)string_ptr + string_len);
10727 
10728     /* Get tail. */
10729 
10730     /* Validate the string table. */
10731     tail = (ALIGN_TYPE*)((UCHAR*)cache_ptr + cache_size) - 1;
10732     if(end > tail)
10733     {
10734 
10735         /* The end of string exceeds cache_ptr. */
10736         return(NX_DNS_SIZE_ERROR);
10737     }
10738     tail = (ALIGN_TYPE*)(*tail);
10739     if((UCHAR*)string_ptr < (UCHAR*)tail)
10740     {
10741 
10742         /* The end of string exceeds cache_ptr. */
10743         return(NX_DNS_SIZE_ERROR);
10744     }
10745 
10746     /* Decrease the usage counter value. */
10747     cnt = *((USHORT*)((UCHAR*)end - 4));
10748     cnt--;
10749     *((USHORT*)((UCHAR*)end - 4)) = cnt;
10750 
10751     /* Clear the memory if cnt is zero. */
10752     if(cnt == 0)
10753     {
10754         memset(string_ptr, 0, string_len - 2);
10755 
10756         /* Update the string length and count .  */
10757         dns_ptr -> nx_dns_string_count --;
10758         dns_ptr -> nx_dns_string_bytes -= string_len;
10759 
10760         /* Update the tail pointer if the string at the tail is deleted. */
10761         if(string_ptr == tail)
10762         {
10763             tail = end;
10764 
10765             while(end < ((ALIGN_TYPE*)((UCHAR*)cache_ptr + cache_size) - 1))
10766             {
10767 
10768                 /* Set the string pt and string length.  */
10769                 string_ptr = end;
10770 
10771                 /* Validate string. */
10772                 if (_nx_utility_string_length_check((CHAR *)string_ptr, &string_len, NX_DNS_NAME_MAX))
10773                     return(NX_DNS_SIZE_ERROR);
10774 
10775                 /* Check the string length.  */
10776                 if(string_len == 0)
10777                 {
10778 
10779                     /* This slot is cleared. */
10780                     while(*((ULONG*)string_ptr) == 0)
10781                         string_ptr = (UCHAR*)string_ptr + 4;
10782 
10783                     end = (ALIGN_TYPE*)((UCHAR*)string_ptr + 4);
10784                     cnt = *((USHORT*)string_ptr);
10785                 }
10786                 else
10787                 {
10788 
10789                     /* Make the length 4 bytes align and add the length of CNT and LEN fields.  */
10790                     string_len = ((string_len & 0xFFFFFFFC) + 8) & 0xFFFFFFFF;
10791 
10792                     end = (ALIGN_TYPE*)((UCHAR*)string_ptr + string_len);
10793                     cnt = *((USHORT*)((UCHAR*)end - 4));
10794                 }
10795 
10796                 /* Check whether this slot is never referenced. */
10797                 if(cnt == 0)
10798                     tail = end;
10799                 else
10800                     break;
10801             }
10802             *((ALIGN_TYPE*)((UCHAR*)cache_ptr + cache_size) - 1) = (ALIGN_TYPE)tail;
10803         }
10804     }
10805 
10806     return(NX_SUCCESS);
10807 }
10808 #endif /* NX_DNS_CACHE_ENABLE  */
10809 
10810 
10811 #ifdef NX_DNS_CACHE_ENABLE
10812 /**************************************************************************/
10813 /*                                                                        */
10814 /*  FUNCTION                                               RELEASE        */
10815 /*                                                                        */
10816 /*    _nx_dns_name_match                                  PORTABLE C      */
10817 /*                                                           6.1          */
10818 /*  AUTHOR                                                                */
10819 /*                                                                        */
10820 /*    Yuxin Zhou, Microsoft Corporation                                   */
10821 /*                                                                        */
10822 /*  DESCRIPTION                                                           */
10823 /*                                                                        */
10824 /*    This function name string match, the lowercase letters "a" to "z"   */
10825 /*    match their uppercase equivalents "A" to "Z".                       */
10826 /*                                                                        */
10827 /*  INPUT                                                                 */
10828 /*                                                                        */
10829 /*    ptr                                   Pointer to destination        */
10830 /*    name                                  Source name string            */
10831 /*                                                                        */
10832 /*  OUTPUT                                                                */
10833 /*                                                                        */
10834 /*    status                                Completion status             */
10835 /*                                                                        */
10836 /*  CALLS                                                                 */
10837 /*                                                                        */
10838 /*    None                                                                */
10839 /*                                                                        */
10840 /*  CALLED BY                                                             */
10841 /*                                                                        */
10842 /*                                                                        */
10843 /*  RELEASE HISTORY                                                       */
10844 /*                                                                        */
10845 /*    DATE              NAME                      DESCRIPTION             */
10846 /*                                                                        */
10847 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10848 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10849 /*                                            resulting in version 6.1    */
10850 /*                                                                        */
10851 /**************************************************************************/
_nx_dns_name_match(UCHAR * src,UCHAR * dst,UINT length)10852 static UINT  _nx_dns_name_match(UCHAR *src, UCHAR *dst, UINT length)
10853 {
10854 
10855 UINT    index = 0;
10856 
10857 
10858     /* Check the name.  */
10859     while (*dst != '\0')
10860     {
10861         if((*src) != (*dst))
10862         {
10863             if((((*src) | 0x20) >= 'a') && (((*src) | 0x20) <= 'z'))
10864             {
10865                 /* Match the characters, case in-sensitive. */
10866                 if(((*src) | 0x20) != ((*dst) | 0x20))
10867                     return(NX_DNS_NAME_MISMATCH);
10868             }
10869             else
10870             {
10871                 return(NX_DNS_NAME_MISMATCH);
10872             }
10873         }
10874         src ++;
10875         dst ++;
10876         index ++;
10877     }
10878 
10879     /* Check the scan length.  */
10880     if (index != length)
10881     {
10882         return (NX_DNS_NAME_MISMATCH);
10883     }
10884 
10885     /* Return success.  */
10886     return(NX_DNS_SUCCESS);
10887 }
10888 #endif /* NX_DNS_CACHE_ENABLE  */
10889