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