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