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