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