ThreadX docsThreadX docs
ThreadX
ThreadX Modules
NetX Duo
FileX
GUIX
USBX
TraceX
LevelX
ThreadX
ThreadX Modules
NetX Duo
FileX
GUIX
USBX
TraceX
LevelX
  • NetX Duo Documentation

    • Understand NetX Duo
    • NetX Duo documentation
    • Chapter 1 - Introduction to NetX Duo
    • Chapter 2 - Installation and Use of NetX Duo
    • Chapter 3 - Functional Components of NetX Duo
    • Chapter 4 - Description of NetX Duo Services
    • Chapter 5 - NetX Duo Network Drivers
    • Appendix A - NetX Duo Services
    • Appendix B - NetX Duo Constants
    • Appendix C - NetX Duo Data Types
    • Appendix D - NetX Duo BSD-Compatible Socket API
    • Appendix E - NetX Duo ASCII Character Codes
    • Auto-IP

      • Chapter 1 - Introduction to NetX Duo AutoIP
      • Chapter 2 - Installation and use of NetX Duo AutoIP
      • Chapter 3 - Description of NetX Duo AutoIP services
    • BSD

      • Chapter 1 - Introduction to NetX Duo BSD
      • Chapter 2 - Installation and use of NetX Duo BSD
      • Chapter 3 - NetX Duo BSD Services
    • Crypto

      • Chapter 1 - Introduction to NetX Duo Crypto
      • Chapter 2 - Installation and use of NetX Duo Crypto
      • Chapter 3 - Functional description of NetX Duo Crypto
      • Chapter 4 - NetX Duo Crypto API description
      • Appendix - NetX Duo Crypto CAVS test
    • DHCP Client

      • Chapter 1 - Introduction to the NetX Duo DHCP Client
      • Chapter 2 - Installation and use of NetX Duo DHCP Client
      • Chapter 3 - Description of NetX Duo DHCP Client services
      • Appendix A - Description of the Restore state feature for NetX Duo DHCP Client services
    • DHCP Server

      • Chapter 1 - Introduction to NetX Duo DHCP Server
      • Chapter 2 - Installation and Use of the NetX Duo DHCP Server
      • Chapter 3 - Description of NetX Duo DHCP server services
    • DHCPv6 Client

      • Chapter 1 - Introduction to NetX Duo DHCPv6 Client
      • Chapter 2 - Installation and use of NetX Duo DHCPv6 Client
      • Chapter 3 - NetX Duo DHCPv6 configuration options
      • Chapter 4 - NetX Duo DHCPv6 Client services
      • Appendix A - Description of the Restore State Feature for NetX Duo DHCPv6 Client
    • DHCPv6 Server

      • Chapter 1 - Introduction to NetX Duo DHCPv6 server
      • Chapter 2 - Installation and use of NetX Duo DHCPv6 server
      • Chapter 3 - NetX Duo DHCPv6 server configuration options
      • Chapter 4 - NetX Duo DHCPv6 server services
      • Appendix A – NetX Duo DHCPv6 option codes
      • Appendix B - NetX Duo DHCPv6 server status codes
      • Appendix C - NetX Duo DHCPv6 unique identifiers (DUIDs)
      • Appendix D - NetX Duo Advanced DHCPv6 server example
    • DNS

      • Chapter 1 - Introduction to the NetX Duo DNS Client
      • Chapter 2 - Installation and Use of NetX Duo DNS Client
      • Chapter 3 - Description of NetX Duo DNS Client Services
    • FTP

      • Chapter 1 - Introduction to NetX Duo FTP
      • Chapter 2 - Installation and use of FTP
      • Chapter 3 - Description of FTP services
    • HTTP

      • Chapter 1 - Introduction to NetX Duo HTTP
      • Chapter 2 - Installation and Use of NetX Duo HTTP
      • Chapter 3 - Description of NetX Duo HTTP Services
    • iperf

      • Chapter 1 - Introduction to NetX Duo Iperf
      • Chapter 2 - Installing and using NetX Duo Iperf
      • Chapter 3 - Running the UDP Transmit Test
    • mDNS

      • Chapter 1 - Introduction to NetX Duo mDNS/DNS-SD
      • Chapter 2 - Installation and use of mDNS
      • Chapter 3 - Description of internal service cache
      • Chapter 4 - Description of mDNS services
    • mqtt

      • Chapter 1 - Introduction to NetX Duo MQTT
      • Chapter 2 - Installation and use of NetX Duo MQTT client
      • Chapter 3 - Description of NetX Duo MQTT Client Services
    • NAT

      • Chapter 1 - An introduction to Network Address Translation
      • Chapter 2 - Installation and use of NAT
      • Chapter 3 - NAT configuration options
      • Chapter 4 - Description of NAT services
    • POP3 Client

      • Chapter 1 - Introduction to NetX Duo POP3
      • Chapter 2 - Installation and use of NetX Duo POP3 Client
      • Chapter 3 - Description of POP3 Client services
    • PPP

      • Chapter 1 - Introduction to the NetX Duo Point-to-Point Protocol (PPP)
      • Chapter 2 - Installation and use of NetX Duo Point-to-Point Protocol (PPP)
      • Chapter 3 - Description of NetX Duo Point-to-Point Protocol (PPP) services
    • PTP Client

      • Chapter 1 - Introduction to NetX Duo PTP Client
      • Chapter 2 - Installation and Use of NetX Duo PTP Client
      • Chapter 3 - Description of NetX Duo PTP Client Services
    • rtp

      • Chapter 1 - Introduction to the NetX Duo RTP Sender
      • Chapter 2 - Installation and use of NetX Duo RTP Sender
      • Chapter 3 - Description of NetX Duo RTP Sender Services
    • rtsp

      • Chapter 1 - Introduction to the NetX Duo RTSP Server
      • Chapter 2 - Installation and use of NetX Duo RTSP Server
      • Chapter 3 - Description of NetX Duo RTSP Server Services
    • Secure DTLS

      • Chapter 1 - Introduction to NetX Duo Secure DTLS
      • Chapter 2 - Installation and use of NetX Duo Secure DTLS
      • Chapter 3 - Functional description of NetX Duo Secure DTLS
      • Chapter 4 - Description of NetX Duo Secure DTLS services
      • Appendix A - NetX Duo Secure DTLS return/error codes
    • Secure TLS

      • Chapter 1 - Introduction to NetX Duo Secure
      • Chapter 2 - Installation and use of NetX Duo Secure
      • Chapter 3 - Functional description of NetX Duo Secure
      • Chapter 4 - Description of NetX Duo Secure services
      • Appendix A - NetX Duo Secure return/error codes
    • SMTP Client

      • Chapter 1 - Introduction to NetX Duo SMTP client
      • Chapter 2 - Installation and use of NetX Duo SMTP client
      • Chapter 3 - Client description of SMTP Client services
    • snmp

      • Chapter 1 - Introduction to NetX Duo SNMP
      • Chapter 2 - Installation and use of the NetX Duo SNMP agent
      • Chapter 3 - Description of NetX Duo SNMP agent services
    • sntp client

      • Chapter 1 - Introduction to NetX Duo SNTP
      • Chapter 2 - Installation and Use of NetX Duo SNTP Client
      • Chapter 3 - Description of NetX Duo SNTP Client Services
      • Appendix A - NetX Duo SNTP Fatal Error Codes
    • telnet

      • Chapter 1 - Introduction to NetX Duo Telnet
      • Chapter 2 - Installation and use of NetX Duo Telnet
      • Chapter 3 - Description of NetX Duo Telnet services
    • TFTP

      • Chapter 1 - Introduction to NetX Duo TFTP
      • Chapter 2 - Installation and use of NetX Duo TFTP
      • Chapter 3 - Description of NetX Duo TFTP services
    • Web HTTP

      • Chapter 1 - Introduction to HTTP and HTTPS
      • Chapter 2 - Installation and use of HTTP and HTTPS
      • Chapter 3 - Description of HTTP services
    • About the NetX Duo User Guide

Chapter 2 - Installation and Use of NetX Duo DNS Client

This chapter contains a description of various issues related to installation, setup, and usage of the NetX Duo DNS Client.

Product Distribution

NetX Duo DNS Client is available at https://github.com/eclipse-threadx/netxduo. The package includes two source files and a PDF file that contains this document, as follows:

  • nxd_dns.h Header file for NetX Duo DNS Client
  • nxd_dns.c C Source file for NetX Duo DNS Client
  • nxd_dns.pdf PDF description of NetX Duo DNS Client

DNS Client Installation

To use NetX Duo DNS Client, copy the source code files nxd_dns.c and nxd_dns.h to the same directory where NetX Duo is installed. For example, if NetX Duo is installed in the directory "\threadx\arm7\green" then the nxd_dns.h and nxd_dns.c files should be copied into this directory.

Using the DNS Client

Using NetX Duo DNS Client is easy. Basically, the application code must include nxd_dns.h after it includes tx_api.h and nx_api.h, in order to use ThreadX and NetX Duo, respectively. Once nxd_dns.h is included, the application code is then able to make the DNS function calls specified later in this guide. The application must also add nxd_dns.c to the build process. This file must be compiled in the same manner as other application files and its object form must be linked along with the files of the application. This is all that is required to use NetX Duo DNS.

Note: Since DNS utilizes NetX Duo UDP services, UDP must be enabled with the nx_udp_enable call prior to using DNS.

Small Example System for NetX Duo DNS Client

NetX Duo DNS Client is compatible with existing NetX DNS applications. The list of legacy services and their NetX Duo equivalent is shown below:

NetX DNS API service (IPv4 only)NetX Duo DNS API service (IPv4 and IPv6 supported)
nx_dns_host_by_name_getnxd_dns_host_by_name_get
nx_dns_host_by_address_getnxd_dns_host_by_address_get
nx_dns_server_getnxd_dns_server_get
nx_dns_server_addnxd_dns_server_add
nx_dns_server_removenxd_dns_server_remove

See the description of NetX Duo DNS Client API services in Chapter 3 for more details.

In the example DNS application program provided in this section, nxd_dns.h is included at line 6. NX_DNS_CLIENT_USER_CREATE_PACKET_POOL, which allows the DNS Client application to create the packet pool for the DNS Client, is declared on lines 24-26. This packet pool is used for allocating packets for sending DNS messages. If NX_DNS_CLIENT_USER_CREATE_PACKET_POOL is defined, a packet pool is created in lines 78-98. If this option is not enabled, the DNS Client creates its own packet pool as per the packet payload and pool size set by configuration parameters in nxd_dns.h and described elsewhere in this chapter.

Another packet pool is created in lines 100-112 for the Client IP instance which is used for internal NetX Duo operations. Next the IP instance is created using the nx_ip_create call in line 115. It is possible for the IP task and the DNS Client to share the same packet pool, but since the DNS Client typically sends out larger messages than the control packets sent by the IP task, using separate packet pools makes more efficient use of memory.

ARP and UDP (which is used by IPv4 networks) are enabled in lines 129 and 141 respectively.

Note: This demo uses the 'ram' driver declared on line 44 and used in the nx_ip_create call. This ram driver is distributed with the NetX Duo source code. To actually run the DNS Client the application must supply an actual physical network driver to transmit and receive packets from the DNS server.

The Client thread entry function thread_client_entry is defined below the tx_application_define function. It initially relinquishes control to the system to allow the IP task thread to be initialized by the network driver.

It then creates the DNS Client in line 257, initializes the DNS cache on lines 267- 278, and sets the packet pool previously created to the DNS Client instance on lines 281-295. It then adds DNS server on lines 297-341.

The remainder of the example program uses the DNS Client services to make DNS queries. Host IP address lookups are performed on lines 193 and 207. The difference between these two services, nxd_dns_host_by_name_get and nx_dns_host_by_name_get, is that the former saves the address data in an NXD_ADDRESS data type, while the latter saves the data in a ULONG data type. Further the latter is limited to IPv4 networks, while the former can be used with IPv6 or IPv4 networks. This is only possible if the IP instance is enabled for IPv6. See the NetX Duo User Guide for more details on enabling the IP instance for IPv6 networking.

Another service for host IP address lookups is shown on line 464, nx_dns_ipv4_address_by_name_get. This service differs from nx_dns_host_by_name_get in that it returns all (or as many will fit in the supplied buffer) of the IPv4 addresses discovered for the domain name, not just the first address received in the DNS Server reply.

Similarly, the nxd_dns_ipv6_address_by_name_get service, called on line 380, returns all the IPv6 addresses discovered by the DNS Client, not just the first one.

Reverse lookups (host name from IP address) are performed on lines 606 (nx_dns_host_by_address_get) and again on line 564 and 588 (nxd_dns_host_by_address_get). nx_dns_host_by_address_get will only work on IPv4 networks, while nxd_dns_host_by_address_get will work on either IPv4 or IPv6 networks (e.g. the IP instance is enabled for IPv6 as well as IPv4 networks).

Two more services for DNS lookups, CNAME and TXT, are demonstrated on lines 627 and 649 respectively, to discover CNAME and domain name data for the input domain name. NetX Duo DNS Client as similar services for other record types, e.g. MX, NS, SRV and SOA. See Chapter 3 for detailed descriptions of all record type lookups available in NetX Duo DNS Client.

When the DNS Client is deleted on line 846, using the nx_dns_delete service, the packet pool for the DNS Client is not deleted unless the DNS Client created its own packet pool. Otherwise, it is up to the application to delete the packet pool if it has no further use for it.

/* This is a small demo of DNS Client for the high-performance NetX TCP/IP stack. */

#include   "tx_api.h"
#include   "nx_api.h"
#include   "nx_udp.h"
#include   "nxd_dns.h"

#ifdef FEATURE_NX_IPV6
#include   "nx_ipv6.h"
#endif

#define     DEMO_STACK_SIZE         4096

#define     NX_PACKET_PAYLOAD       1536
#define     NX_PACKET_POOL_SIZE     30 * NX_PACKET_PAYLOAD
#define     LOCAL_CACHE_SIZE        2048

/* Define the ThreadX and NetX object control blocks... */

NX_DNS                  client_dns;
TX_THREAD               client_thread;
NX_IP                   client_ip;
NX_PACKET_POOL          main_pool;
#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL
NX_PACKET_POOL          client_pool;
#endif
UCHAR                   local_cache[LOCAL_CACHE_SIZE];

UINT                    error_counter = 0;

#ifdef FEATURE_NX_IPV6
/* If IPv6 is enabled in NetX Duo, allow DNS Client to try using IPv6 */
//#define USE_IPV6
#endif

#define CLIENT_ADDRESS      IP_ADDRESS(192,168,0,11)
#define DNS_SERVER_ADDRESS  IP_ADDRESS(192,168,0,1)

/* Define thread prototypes. */

void    thread_client_entry(ULONG thread_input);

/***** Substitute your ethernet driver entry function here *********/
extern  VOID _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr);

/* Define main entry point. */

int main()
{

    /* Enter the ThreadX kernel. */
    tx_kernel_enter();
}

/* Define what the initial system looks like. */

void    tx_application_define(void *first_unused_memory)
{

CHAR    *pointer;
UINT    status;

    /* Setup the working pointer. */
    pointer =  (CHAR *) first_unused_memory;

    /* Create the main thread. */
    tx_thread_create(&client_thread, "Client thread", thread_client_entry, 0,
            pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);

    pointer =  pointer + DEMO_STACK_SIZE;

    /* Initialize the NetX system. */
    nx_system_initialize();

#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL

    /* Create the packet pool for the DNS Client to send packets.

        If the DNS Client is configured for letting the host application create
        the DNS packet pool, (see NX_DNS_CLIENT_USER_CREATE_PACKET_POOL option), see
       nx_dns_create() for guidelines on packet payload size and pool size.
       packet traffic for NetX processes.
    */
    status =  nx_packet_pool_create(&client_pool, "DNS Client Packet Pool", NX_DNS_PACKET_PAYLOAD, pointer, NX_DNS_PACKET_POOL_SIZE);

    pointer = pointer + NX_DNS_PACKET_POOL_SIZE;

    /* Check for pool creation error. */
    if (status)
    {

        error_counter++;
        return;
     }
#endif
     /* Create the packet pool which the IP task will use to send packets. Also available to the host
       application to send packet. */
    status =  nx_packet_pool_create(&main_pool, "Main Packet Pool", NX_PACKET_PAYLOAD, pointer, NX_PACKET_POOL_SIZE);

    pointer = pointer + NX_PACKET_POOL_SIZE;

    /* Check for pool creation error. */
    if (status)
    {

        error_counter++;
        return;
     }

    /* Create an IP instance for the DNS Client. */
    status = nx_ip_create(&client_ip, "DNS Client IP Instance", CLIENT_ADDRESS, 0xFFFFFF00UL,
                          &main_pool, _nx_ram_network_driver, pointer, 2048, 1);

    pointer =  pointer + 2048;

    /* Check for IP create errors. */
    if (status)
    {

        error_counter++;
        return;
     }

    /* Enable ARP and supply ARP cache memory for the DNS Client IP. */
    status =  nx_arp_enable(&client_ip, (void *) pointer, 1024);
    pointer = pointer + 1024;

    /* Check for ARP enable errors. */
    if (status)
    {

        error_counter++;
        return;
     }

    /* Enable UDP traffic because DNS is a UDP based protocol. */
    status =  nx_udp_enable(&client_ip);

    /* Check for UDP enable errors. */
    if (status)
    {

        error_counter++;
        return;
     }
}

#define BUFFER_SIZE     200
#define RECORD_COUNT    10

/* Define the Client thread. */

void    thread_client_entry(ULONG thread_input)
{

UCHAR           record_buffer[200];
UINT            record_count;
UINT            status;
ULONG           host_ip_address;
#ifdef FEATURE_NX_IPV6
NXD_ADDRESS     host_ipduo_address;
NXD_ADDRESS     test_ipduo_server_address;
#ifdef USE_IPV6
NXD_ADDRESS     client_ipv6_address;
NXD_ADDRESS     dns_ipv6_server_address;
UINT            iface_index, address_index;
#endif
#endif
UINT            i;
ULONG           *ipv4_address_ptr[RECORD_COUNT];
NX_DNS_IPV6_ADDRESS
                *ipv6_address_ptr[RECORD_COUNT];
#ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
NX_DNS_NS_ENTRY
                *nx_dns_ns_entry_ptr[RECORD_COUNT];
NX_DNS_MX_ENTRY
                *nx_dns_mx_entry_ptr[RECORD_COUNT];
NX_DNS_SRV_ENTRY
                *nx_dns_srv_entry_ptr[RECORD_COUNT];
NX_DNS_SOA_ENTRY
                *nx_dns_soa_entry_ptr;
ULONG           host_address;
USHORT          host_port;
#endif

    /* Give NetX IP task a chance to get initialized . */
    tx_thread_sleep(100);

#ifdef FEATURE_NX_IPV6
#ifdef USE_IPV6

    /* Make the DNS Client IPv6 enabled. */
    status = nxd_ipv6_enable(&client_ip);

    /* Check for enable errors. */
    if (status)
    {

        error_counter++;
        return;
     }
    status = nxd_icmp_enable(&client_ip);

    /* Check for enable errors. */
    if (status)
    {

        error_counter++;
        return;
    }

    client_ipv6_address.nxd_ip_address.v6[3] = 0x101;
    client_ipv6_address.nxd_ip_address.v6[2] = 0x0;
    client_ipv6_address.nxd_ip_address.v6[1] = 0x0000f101;
    client_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8;
    client_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6;


     /* Set the link local address with the host MAC address. */
    iface_index = 0;

    /* This assumes we are using the primary network interface (index 0). */
    status = nxd_ipv6_address_set(&client_ip, iface_index, NX_NULL, 10, &address_index);

    /* Check for link local address set error. */
    if (status)
    {

        error_counter++;
        return;
     }

    /* Set the host global IP address. We are assuming a 64
       bit prefix here but this can be any value (< 128). */
    status = nxd_ipv6_address_set(&client_ip, iface_index, &client_ipv6_address, 64, &address_index);

    /* Check for global address set error. */
    if (status)
    {

        error_counter++;
        return;
     }

    /* Wait while NetX Duo validates the link local and global address. */
    tx_thread_sleep(500);
#endif
#endif

    /* Create a DNS instance for the Client. Note this function will create
       the DNS Client packet pool for creating DNS message packets intended
       for querying its DNS server. */
    status =  nx_dns_create(&client_dns, &client_ip, (UCHAR *)"DNS Client");

    /* Check for DNS create error. */
    if (status)
    {

        error_counter++;
        return;
     }

#ifdef NX_DNS_CACHE_ENABLE
    /* Initialize the cache. */
    status = nx_dns_cache_initialize(&client_dns, local_cache, LOCAL_CACHE_SIZE);

    /* Check for DNS cache error. */
    if (status)
    {

        error_counter++;
        return;
     }
#endif

    /* Is the DNS client configured for the host application to create the packet pool? */
#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL

    /* Yes, use the packet pool created above which has appropriate payload size
       for DNS messages. */
     status = nx_dns_packet_pool_set(&client_dns, &client_pool);

     /* Check for set DNS packet pool error. */
     if (status)
     {

         error_counter++;
         return;
      }

#endif /* NX_DNS_CLIENT_USER_CREATE_PACKET_POOL */

#ifdef FEATURE_NX_IPV6
#ifdef USE_IPV6

    /* Add an IPv6 DNS server to the DNS client. */
    dns_ipv6_server_address.nxd_ip_address.v6[3] = 0x106;
    dns_ipv6_server_address.nxd_ip_address.v6[2] = 0x0;
    dns_ipv6_server_address.nxd_ip_address.v6[1] = 0x0000f101;
    dns_ipv6_server_address.nxd_ip_address.v6[0] = 0x20010db8;
    dns_ipv6_server_address.nxd_ip_version = NX_IP_VERSION_V6;

    status = nxd_dns_server_add(&client_dns, &dns_ipv6_server_address);

    /* Check for DNS add server error. */
    if (status)
    {

        error_counter++;
        return;
     }
#else

    /* Add an IPv4 server address to the Client list. */
    status = nx_dns_server_add(&client_dns, DNS_SERVER_ADDRESS);

    /* Check for DNS add server error. */
    if (status)
    {

        error_counter++;
        return;
     }
#endif
#else

    /* Add an IPv4 server address to the Client list. */
    status = nx_dns_server_add(&client_dns, DNS_SERVER_ADDRESS);

    /* Check for DNS add server error. */
    if (status)
    {

        error_counter++;
        return;
     }
#endif


/********************************************************************************/
/*                                  Type AAAA                                   */
/*     Send AAAA type DNS Query to its DNS server and get the IPv6 address. */
/********************************************************************************/
#ifdef FEATURE_NX_IPV6

    /* Send a DNS Client name query. Indicate the Client expects an IPv6 address (containing an AAAA record). The DNS
       Client will send AAAA type query to its DNS server. */
    status = nxd_dns_host_by_name_get(&client_dns, (UCHAR *)"www.my_example.com", &host_ipduo_address, 400, NX_IP_VERSION_V6);

    /* Check for DNS query error. */
    if (status != NX_SUCCESS)
    {
        error_counter++;
    }

    else
    {

        printf("------------------------------------------------------\n");
        printf("Test AAAA: \n");

        printf("IP address: %x:%x:%x:%x:%x:%x:%x:%x\n",
            (UINT)host_ipduo_address.nxd_ip_address.v6[0]  >>16 & 0xFFFF,
            (UINT)host_ipduo_address.nxd_ip_address.v6[0]  & 0xFFFF,
            (UINT)host_ipduo_address.nxd_ip_address.v6[1]  >>16 & 0xFFFF,
            (UINT)host_ipduo_address.nxd_ip_address.v6[1]  & 0xFFFF,
            (UINT)host_ipduo_address.nxd_ip_address.v6[2]  >>16 & 0xFFFF,
            (UINT)host_ipduo_address.nxd_ip_address.v6[2]  & 0xFFFF,
            (UINT)host_ipduo_address.nxd_ip_address.v6[3]  >>16 & 0xFFFF,
            (UINT)host_ipduo_address.nxd_ip_address.v6[3]  & 0xFFFF);
    }

#endif

    /* Look up IPv6 addresses(AAAA TYPE) to record multiple IPv6 addresses in record_buffer and return the IPv6 address count. */
    status = nxd_dns_ipv6_address_by_name_get(&client_dns, (UCHAR *)"www.my_example.com", &record_buffer[0], BUFFER_SIZE, &record_count, 400);

    /* Check for DNS add server error. */
    if (status != NX_SUCCESS)
    {
        error_counter++;
    }

    else
    {

        printf("------------------------------------------------------\n");
        printf("Test AAAA: ");
        printf("record_count = %d \n", record_count);
    }

    /* Get the IPv6 addresses of host. */
    for(i =0; i< record_count; i++)
    {
        ipv6_address_ptr[i] = (NX_DNS_IPV6_ADDRESS *)(record_buffer + i * sizeof(NX_DNS_IPV6_ADDRESS));

        printf("record %d: IP address: %x:%x:%x:%x:%x:%x:%x:%x\n", i,
                (UINT)(ipv6_address_ptr[i] -> ipv6_address[0]  >>16 & 0xFFFF),
                (UINT)(ipv6_address_ptr[i] -> ipv6_address[0]  & 0xFFFF),
                (UINT)(ipv6_address_ptr[i] -> ipv6_address[1]  >>16 & 0xFFFF),
                (UINT)(ipv6_address_ptr[i] -> ipv6_address[1]  & 0xFFFF),
                (UINT)(ipv6_address_ptr[i] -> ipv6_address[2]  >>16 & 0xFFFF),
                (UINT)(ipv6_address_ptr[i] -> ipv6_address[2]  & 0xFFFF),
                (UINT)(ipv6_address_ptr[i] -> ipv6_address[3]  >>16 & 0xFFFF),
                (UINT)(ipv6_address_ptr[i] -> ipv6_address[3]  & 0xFFFF));
    }


/********************************************************************************/
/*                                  Type A                                      */
/*       Send A type DNS Query to its DNS server and get the IPv4 address. */
/********************************************************************************/
#ifdef FEATURE_NX_IPV6
    /* Send a DNS Client name query. Indicate the Client expects an IPv4 address (containing an A record). If the DNS client
       is using an IPv6 DNS server it will send this query over IPv6; otherwise it will be sent over IPv4. */
    status = nxd_dns_host_by_name_get(&client_dns, (UCHAR *)"www.my_example.com", &host_ipduo_address, 400, NX_IP_VERSION_V4);

    /* Check for DNS query error. */
    if (status != NX_SUCCESS)
    {
        error_counter++;
    }
    else
    {

        printf("------------------------------------------------------\n");
        printf("Test A: \n");
        printf("IP address: %lu.%lu.%lu.%lu\n",
              host_ipduo_address.nxd_ip_address.v4 >> 24,
              host_ipduo_address.nxd_ip_address.v4 >> 16 & 0xFF,
              host_ipduo_address.nxd_ip_address.v4 >> 8 & 0xFF,
              host_ipduo_address.nxd_ip_address.v4 & 0xFF);
    }

#endif

    /* Look up an IPv4 address over IPv4. */
    status = nx_dns_host_by_name_get(&client_dns, (UCHAR *)"www.my_example.com", &host_ip_address, 400);

    /* Check for DNS query error. */
    if (status != NX_SUCCESS)
    {
        error_counter++;
    }

    else
    {

        printf("------------------------------------------------------\n");
        printf("Test A: \n");
        printf("IP address: %lu.%lu.%lu.%lu\n",
        host_ip_address >> 24,
        host_ip_address >> 16 & 0xFF,
        host_ip_address >> 8 & 0xFF,
        host_ip_address & 0xFF);
    }


    /* Look up IPv4 addresses to record multiple IPv4 addresses in record_buffer and return the IPv4 address count. */
    status = nx_dns_ipv4_address_by_name_get(&client_dns, (UCHAR *)"www.my_example.com", &record_buffer[0], BUFFER_SIZE, &record_count, 400);

    /* Check for DNS query error. */
    if (status != NX_SUCCESS)
    {
        error_counter++;
    }

    else
    {

        printf("------------------------------------------------------\n");
        printf("Test A: ");
        printf("record_count = %d \n", record_count);
    }

    /* Get the IPv4 addresses of host. */
    for(i =0; i< record_count; i++)
    {
        ipv4_address_ptr[i] = (ULONG *)(record_buffer + i * sizeof(ULONG));
        printf("record %d: IP address: %lu.%lu.%lu.%lu\n", i,
                *ipv4_address_ptr[i] >> 24,
                *ipv4_address_ptr[i] >> 16 & 0xFF,
                *ipv4_address_ptr[i] >> 8 & 0xFF,
                *ipv4_address_ptr[i] & 0xFF);
    }


/********************************************************************************/
/*                                  Type A + CNAME response                     */
/*       Send A type DNS Query to its DNS server and get the IPv4 address. */
/********************************************************************************/
    /* Look up an IPv4 address over IPv4. */
    status = nx_dns_host_by_name_get(&client_dns, (UCHAR *)"www.my_example.com", &host_ip_address, 400);

    /* Check for DNS query error. */
    if (status != NX_SUCCESS)
    {
        error_counter++;
    }

    else
    {

        printf("------------------------------------------------------\n");
        printf("Test A + CNAME response: \n");
        printf("IP address: %lu.%lu.%lu.%lu\n",
        host_ip_address >> 24,
        host_ip_address >> 16 & 0xFF,
        host_ip_address >> 8 & 0xFF,
        host_ip_address & 0xFF);
    }


    /* Look up IPv4 addresses to record multiple IPv4 addresses in record_buffer and return the IPv4 address count. */
    status = nx_dns_ipv4_address_by_name_get(&client_dns, (UCHAR *)"www.my_example.com", &record_buffer[0], BUFFER_SIZE, &record_count, 400);

    /* Check for DNS query error. */
    if (status != NX_SUCCESS)
    {
        error_counter++;
    }

    else
    {

        printf("------------------------------------------------------\n");
        printf("Test Test A + CNAME response: ");
        printf("record_count = %d \n", record_count);
    }

    /* Get the IPv4 addresses of host. */
    for(i =0; i< record_count; i++)
    {
        ipv4_address_ptr[i] = (ULONG *)(record_buffer + i * sizeof(ULONG));
        printf("record %d: IP address: %lu.%lu.%lu.%lu\n", i,
                *ipv4_address_ptr[i] >> 24,
                *ipv4_address_ptr[i] >> 16 & 0xFF,
                *ipv4_address_ptr[i] >> 8 & 0xFF,
                *ipv4_address_ptr[i] & 0xFF);
    }


/********************************************************************************/
/*                                  Type PTR                                    */
/*       Send PTR type DNS Query to its DNS server and get the host name. */
/********************************************************************************/

#ifdef FEATURE_NX_IPV6

    /* Look up a host name from an IPv6 address (reverse lookup). */

    /* Create an IPv6 address for a reverse lookup. */
    test_ipduo_server_address.nxd_ip_version = NX_IP_VERSION_V6;
    test_ipduo_server_address.nxd_ip_address.v6[0] = 0x24046800;
    test_ipduo_server_address.nxd_ip_address.v6[1] = 0x40050c00;
    test_ipduo_server_address.nxd_ip_address.v6[2] = 0x00000000;
    test_ipduo_server_address.nxd_ip_address.v6[3] = 0x00000065;

    /* This will be sent over IPv6 to the DNS server who should return a PTR record if it can find the information. */
    status = nxd_dns_host_by_address_get(&client_dns, &test_ipduo_server_address, &record_buffer[0], BUFFER_SIZE, 450);

    /* Check for DNS query error. */
    if (status != NX_SUCCESS)
    {
        error_counter++;
    }

    else
    {

        printf("------------------------------------------------------\n");
        printf("Test PTR: %s\n", record_buffer);
    }
#endif

#ifdef FEATURE_NX_IPV6

    /* Create an IPv4 address for the reverse lookup. If the DNS client is IPv6 enabled, it will send this over
       IPv6 to the DNS server; otherwise it will send it over IPv4. In either case the respective server will
       return a PTR record if it has the information. */
    test_ipduo_server_address.nxd_ip_version = NX_IP_VERSION_V4;
    test_ipduo_server_address.nxd_ip_address.v4 = IP_ADDRESS(74, 125, 71, 106);

    status = nxd_dns_host_by_address_get(&client_dns, &test_ipduo_server_address, &record_buffer[0], BUFFER_SIZE, 450);

     /* Check for DNS query error. */
     if (status != NX_SUCCESS)
     {
         error_counter++;
     }

    else
    {

        printf("------------------------------------------------------\n");
        printf("Test PTR: %s\n", record_buffer);
    }
#endif

     /* Look up host name over IPv4. */
     host_ip_address = IP_ADDRESS(74, 125, 71, 106);
     status = nx_dns_host_by_address_get(&client_dns, host_ip_address, &record_buffer[0], BUFFER_SIZE, 450);

     /* Check for DNS query error. */
     if (status != NX_SUCCESS)
     {
         error_counter++;
     }

    else
    {
        printf("------------------------------------------------------\n");
        printf("Test PTR: %s\n", record_buffer);
    }

#ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
/********************************************************************************/
/*                                  Type CNAME                                  */
/*   Send CNAME type DNS Query to its DNS server and get the canonical name . */
/********************************************************************************/

     /* Send CNAME type to record the canonical name of host in record_buffer. */
     status = nx_dns_cname_get(&client_dns, (UCHAR *)"www.my_example.com", &record_buffer[0], BUFFER_SIZE, 400);

     /* Check for DNS query error. */
     if (status != NX_SUCCESS)
     {
         error_counter++;
     }

    else
    {

        printf("------------------------------------------------------\n");
        printf("Test CNAME: %s\n", record_buffer);
    }


/********************************************************************************/
/*                                  Type TXT                                    */
/*      Send TXT type DNS Query to its DNS server and get descriptive text. */
/********************************************************************************/

     /* Send TXT type to record the descriptive test of host in record_buffer. */
     status = nx_dns_host_text_get(&client_dns, (UCHAR *)"www.my_example.com", &record_buffer[0], BUFFER_SIZE, 400);

     /* Check for DNS query error. */
     if (status != NX_SUCCESS)
     {
         error_counter++;
     }

    else
    {

        printf("------------------------------------------------------\n");
        printf("Test TXT: %s\n", record_buffer);
    }


/********************************************************************************/
/*                                  Type NS                                     */
/*   Send NS type DNS Query to its DNS server and get the domain name server. */
/********************************************************************************/

     /* Send NS type to record multiple name servers in record_buffer and return the name server count.
        If the DNS response includes the IPv4 addresses of name server, record it similarly in record_buffer. */
     status = nx_dns_domain_name_server_get(&client_dns, (UCHAR *)"www.my_example.com", &record_buffer[0], BUFFER_SIZE, &record_count, 400);

     /* Check for DNS query error. */
     if (status != NX_SUCCESS)
     {
         error_counter++;
     }

    else
    {

        printf("------------------------------------------------------\n");
        printf("Test NS: ");
        printf("record_count = %d \n", record_count);
    }

    /* Get the name server. */
    for(i =0; i< record_count; i++)
    {
        nx_dns_ns_entry_ptr[i] = (NX_DNS_NS_ENTRY *)(record_buffer + i * sizeof(NX_DNS_NS_ENTRY));

        printf("record %d: IP address: %d.%d.%d.%d\n", i,
                nx_dns_ns_entry_ptr[i] -> nx_dns_ns_ipv4_address  >> 24,
                nx_dns_ns_entry_ptr[i] -> nx_dns_ns_ipv4_address >> 16 & 0xFF,
                nx_dns_ns_entry_ptr[i] -> nx_dns_ns_ipv4_address >> 8 & 0xFF,
                nx_dns_ns_entry_ptr[i] -> nx_dns_ns_ipv4_address & 0xFF);
        if(nx_dns_ns_entry_ptr[i] -> nx_dns_ns_hostname_ptr)
            printf("hostname = %s\n", nx_dns_ns_entry_ptr[i] -> nx_dns_ns_hostname_ptr);
        else
            printf("hostname is not set\n");
    }

/********************************************************************************/
/*                                  Type MX                                     */
/*   Send MX type DNS Query to its DNS server and get the domain mail exchange. */
/********************************************************************************/

     /* Send MX DNS query type to record multiple mail exchanges in record_buffer and return the mail exchange count.
        If the DNS response includes the IPv4 addresses of mail exchange, record it similarly in record_buffer. */
     status = nx_dns_domain_mail_exchange_get(&client_dns, (UCHAR *)"www.my_example.com", &record_buffer[0], BUFFER_SIZE, &record_count, 400);

     /* Check for DNS query error. */
     if (status != NX_SUCCESS)
     {
         error_counter++;
     }

    else
    {

        printf("------------------------------------------------------\n");
        printf("Test MX: ");
        printf("record_count = %d \n", record_count);
    }

    /* Get the mail exchange. */
    for(i =0; i< record_count; i++)
    {
        nx_dns_mx_entry_ptr[i] = (NX_DNS_MX_ENTRY *)(record_buffer + i * sizeof(NX_DNS_MX_ENTRY));

        printf("record %d: IP address: %d.%d.%d.%d\n", i,
                nx_dns_mx_entry_ptr[i] -> nx_dns_mx_ipv4_address >> 24,
                nx_dns_mx_entry_ptr[i] -> nx_dns_mx_ipv4_address >> 16 & 0xFF,
                nx_dns_mx_entry_ptr[i] -> nx_dns_mx_ipv4_address >> 8 & 0xFF,
                nx_dns_mx_entry_ptr[i] -> nx_dns_mx_ipv4_address & 0xFF);
        printf("preference = %d \n ", nx_dns_mx_entry_ptr[i] -> nx_dns_mx_preference);
        if(nx_dns_mx_entry_ptr[i] -> nx_dns_mx_hostname_ptr)
            printf("hostname = %s\n", nx_dns_mx_entry_ptr[i] -> nx_dns_mx_hostname_ptr);
        else
            printf("hostname is not set\n");
    }

/********************************************************************************/
/*                                  Type SRV                                    */
/*  Send SRV type DNS Query to its DNS server and get the location of services. */
/********************************************************************************/

     /* Send SRV DNS query type to record the location of services in record_buffer and return count.
        If the DNS response includes the IPv4 addresses of service name, record it similarly in record_buffer. */
     status = nx_dns_domain_service_get(&client_dns, (UCHAR *)"www.my_example.com", &record_buffer[0], BUFFER_SIZE, &record_count, 400);

     /* Check for DNS query error. */
     if (status != NX_SUCCESS)
     {
         error_counter++;
     }

    else
    {

        printf("------------------------------------------------------\n");
        printf("Test SRV: ");
        printf("record_count = %d \n", record_count);
    }

    /* Get the location of services. */
    for(i =0; i< record_count; i++)
    {
        nx_dns_srv_entry_ptr[i] = (NX_DNS_SRV_ENTRY *)(record_buffer + i * sizeof(NX_DNS_SRV_ENTRY));

        printf("record %d: IP address: %d.%d.%d.%d\n", i,
                nx_dns_srv_entry_ptr[i] -> nx_dns_srv_ipv4_address >> 24,
                nx_dns_srv_entry_ptr[i] -> nx_dns_srv_ipv4_address >> 16 & 0xFF,
                nx_dns_srv_entry_ptr[i] -> nx_dns_srv_ipv4_address >> 8 & 0xFF,
                nx_dns_srv_entry_ptr[i] -> nx_dns_srv_ipv4_address & 0xFF);
        printf("port number = %d\n", nx_dns_srv_entry_ptr[i] -> nx_dns_srv_port_number );
        printf("priority = %d\n", nx_dns_srv_entry_ptr[i] -> nx_dns_srv_priority );
        printf("weight = %d\n", nx_dns_srv_entry_ptr[i] -> nx_dns_srv_weight );
        if(nx_dns_srv_entry_ptr[i] -> nx_dns_srv_hostname_ptr)
            printf("hostname = %s\n", nx_dns_srv_entry_ptr[i] -> nx_dns_srv_hostname_ptr);
        else
            printf("hostname is not set\n");
    }

    /* Get the service info, NetX old API.*/
    status = nx_dns_info_by_name_get(&client_dns, (UCHAR *)"www.my_example.com", &host_address, &host_port, 200);

    /* Check for DNS add server error. */
     if (status != NX_SUCCESS)
     {
         error_counter++;
     }

    else
    {

        printf("------------------------------------------------------\n");
        printf("Test SRV: ");
        printf("IP address: %d.%d.%d.%d\n",
                host_address >> 24,
                host_address >> 16 & 0xFF,
                host_address >> 8 & 0xFF,
                host_address & 0xFF);
        printf("port number = %d\n", host_port);
    }

/********************************************************************************/
/*                                  Type SOA                                    */
/* Send SOA type DNS Query to its DNS server and get zone of start of authority.*/
/********************************************************************************/

     /* Send SOA DNS query type to record the zone of start of authority in record_buffer. */
     status = nx_dns_authority_zone_start_get(&client_dns, (UCHAR *)"www.my_example.com", &record_buffer[0], BUFFER_SIZE, 400);

     /* Check for DNS query error. */
     if (status != NX_SUCCESS)
     {
         error_counter++;
     }

     /* Get the loc*/
     nx_dns_soa_entry_ptr = (NX_DNS_SOA_ENTRY *) record_buffer;
     printf("------------------------------------------------------\n");
     printf("Test SOA: \n");
     printf("serial = %d\n", nx_dns_soa_entry_ptr -> nx_dns_soa_serial );
     printf("refresh = %d\n", nx_dns_soa_entry_ptr -> nx_dns_soa_refresh );
     printf("retry = %d\n", nx_dns_soa_entry_ptr -> nx_dns_soa_retry );
     printf("expire = %d\n", nx_dns_soa_entry_ptr -> nx_dns_soa_expire );
     printf("minmum = %d\n", nx_dns_soa_entry_ptr -> nx_dns_soa_minmum );
     if(nx_dns_soa_entry_ptr -> nx_dns_soa_host_mname_ptr)
         printf("host mname = %s\n", nx_dns_soa_entry_ptr -> nx_dns_soa_host_mname_ptr);
     else
         printf("host mname is not set\n");
     if(nx_dns_soa_entry_ptr -> nx_dns_soa_host_rname_ptr)
         printf("host rname = %s\n", nx_dns_soa_entry_ptr -> nx_dns_soa_host_rname_ptr);
     else
         printf("host rname is not set\n");


#endif

    /* Shutting down...*/

    /* Terminate the DNS Client thread. */
    status = nx_dns_delete(&client_dns);

    return;
}

Configuration Options

There are several configuration options for building DNS for NetX Duo. These options can be redefined in nxd_dns.h. The following list describes each in detail:

  • NX_DNS_TYPE_OF_SERVICE Type of service required for the DNS UDP requests. By default, this value is defined as NX_IP_NORMAL for normal IP packet service.

  • NX_DNS_TIME_TO_LIVE Specifies the maximum number of routers a packet can pass before it is discarded. The default value is 0x80.

  • NX_DNS_FRAGMENT_OPTION Sets the socket property to allow or disallow fragmentation of outgoing packets. The default value is NX_DONT_FRAGMENT.

  • NX_DNS_QUEUE_DEPTH Sets the maximum number of packets to store on the socket receive queue. The default value is 5.

  • NX_DNS_MAX_SERVERS Specifies the maximum number of DNS Servers in the Client server list. The default value is 5.

  • NX_DNS_MESSAGE_MAX The maximum DNS message size for sending DNS queries. The default value is 512, which is also the maximum size specified in RFC 1035 Section 2.3.4.

  • NX_DNS_PACKET_PAYLOAD_UNALIGNED If not defined, the size of the Client packet payload which includes the Ethernet, IP (or IPv6), and UDP headers plus the maximum DNS message size specified by NX_DNS_MESSAGE_MAX. Regardless if defined, the packet payload is the 4-byte aligned and stored in NX_DNS_PACKET_PAYLOAD.

  • NX_DNS_PACKET_POOL_SIZE Size of the Client packet pool for sending DNS queries if NX_DNS_CLIENT_USER_CREATE_PACKET_POOL is not defined. The default value is large enough for 16 packets of payload size defined by NX_DNS_PACKET_PAYLOAD, and is 4-byte aligned.

  • NX_DNS_MAX_RETRIES The maximum number of times the DNS Client will query the current DNS server before trying another server or aborting the DNS query. The default value is 3.

  • NX_DNS_MAX_RETRANS_TIMEOUT The maximum retransmission timeout on a DNS query to a specific DNS server. The default value is 64 seconds (64 * NX_IP_PERIODIC_RATE).

  • NX_DNS_IP_GATEWAY_AND_DNS_SERVER If defined and the Client IPv4 gateway address is non zero, the DNS Client sets the IPv4 gateway as the Client's primary DNS server. The default value is disabled.

  • NX_DNS_PACKET_ALLOCATE_TIMEOUT This sets the timeout option for allocating a packet from the DNS client packet pool. The default value is 1 second (1*NX_IP_PERIODIC_RATE).

  • NX_DNS_CLIENT_USER_CREATE_PACKET_POOL This enables the DNS Client to let the application create and set the DNS Client packet pool. By default this option is disabled, and the DNS Client creates its own packet pool in nx_dns_create.

  • NX_DNS_CLIENT_CLEAR_QUEUE This enables the DNS Client to clear old DNS messages off the receive queue before sending a new query. Removing these packets from previous DNS queries prevents the DNS Client socket queue from overflowing and dropping valid packets.

  • NX_DNS_ENABLE_EXTENDED_RR_TYPES This enables the DNS Client to query on additional DNS record types in (e.g. CNAME, NS, MX, SOA, SRV and TXT).

  • NX_DNS_CACHE_ENABLE This enables the DNS Client to store the answer records into DNS cache.

Prev
Chapter 1 - Introduction to the NetX Duo DNS Client
Next
Chapter 3 - Description of NetX Duo DNS Client Services