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