📄 dns.c
字号:
/*****************************************************************************
*
* Copyright (c) 1993 - 2001 By Accelerated Technology, Inc.
*
* PROPRIETARY RIGHTS of Accelerated Technology are involved in the subject
* matter of this material. All manufacturing, reproduction, use and sales
* rights pertaining to this subject matter are governed by the license
* agreement. The recipient of this software implicity accepts the terms
* of the license.
*
******************************************************************************/
/*****************************************************************************
*
* FILENAME VERSION
*
* DNS.C 4.4
*
* DESCRIPTION
*
* This file contains the Domain Name System (DNS) component. Given a
* name this component will discover the matching IP address.
*
* DATA STRUCTURES
*
* DNS_Hosts A list of hosts names and IP addresses.
*
* FUNCTIONS
*
* DNS_Initialize Initialize the DNS component.
* DNS_Resolve Resolve a host's IP address.
* DNS_Build_Query Build a DNS query packet.
* DNS_Query Send a DNS query packet.
* DNS_Pack_Domain_Name Convert a name to the format expected by a
* format expected by a DNS server.
* DNS_Unpack_Domain_Name Upack a domain name.
* DNS_Extract_Data Get info (IP address or name) from the DNS
* response.
* DNS_Find_Host_By_Name Search for a host.
* DNS_Add_Host Add a host to the "hosts file".
* DNS_Find_Host_By_Addr Search for a host.
* DNS_Addr_To_String Convert an IP address to ascii string.
* NU_Add_DNS_Server Register a DNS server with the stack.
* NU_Delete_DNS_Server Delete a DNS server.
* NU_Get_DNS_Servers Retrieve a list of DNS servers.
*
* DEPENDENCIES
*
*****************************************************************************/
#include "plus/nucleus.h"
#include "net/inc/externs.h"
#include "net/inc/ip.h"
#include "net/inc/net_extr.h"
#include "net/inc/dns.h"
#include "net/inc/ncl.h"
#if (INCLUDE_DNS == NU_TRUE)
/* This is a list of DNS servers or resolvers. */
DNS_SERVER_LIST DNS_Servers;
#endif
/* This is the list of hosts. If a host can not be found in this list, DNS will
be used to retrieve the information. The new host will be added to the list.
*/
DNS_HOST_LIST DNS_Hosts;
/* Function Prototypes. */
STATUS DNS_Resolve(CHAR *name, CHAR *ip_addr, UNSIGNED *ttl, UINT16 type);
INT DNS_Build_Query(CHAR *data, VOID **buffer, UINT16 type);
INT DNS_Query(CHAR *buffer, INT q_size, UINT8 *dns_server);
INT DNS_Pack_Domain_Name (CHAR *dst, CHAR *src);
INT DNS_Unpack_Domain_Name(CHAR *dst, CHAR *src, CHAR *buf_begin);
STATUS DNS_Extract_Data (DNS_PKT_HEADER *pkt, CHAR *ip_addr, UNSIGNED *ttl,
INT type);
DNS_HOST *DNS_Add_Host(CHAR *name, CHAR *ip_addr, UNSIGNED ttl);
STATUS DNS_Addr_To_String(CHAR *addr, CHAR *new_name);
#ifdef VIRTUAL_NET_INCLUDED
extern STATUS VDRV_DNS_Init(VOID);
#endif
extern struct host hostTable[];
/****************************************************************************
* FUNCTION
*
* DNS_Initialize
*
* DESCRIPTION
*
* This function initializes the DNS component.
*
* INPUTS
*
* None.
*
* OUTPUTS
*
* NU_SUCCESS Indicates successful operation.
* NU_MEM_ALLOC Indicates not enough dynamic memory was
* available.
*
******************************************************************************/
STATUS DNS_Initialize(VOID)
{
struct host *hst;
INT host_count;
INT i;
DNS_HOST *dns_host;
#if (INCLUDE_DNS == NU_TRUE)
DNS_SERVER *dns_server;
#endif
#if (INCLUDE_DNS == NU_TRUE)
/* Create a list of DNS servers. Initially there will be
DNS_MAX_DNS_SERVERS entries in the list. All entries will have a null
ip address initiallly. That is the list will be empty until an
aplication adds a DNS_Server. */
/* Allocate a block of memeory to build the DNS server list with. */
if (NU_Allocate_Memory (&System_Memory, (VOID **)&dns_server,
sizeof (DNS_SERVER) * DNS_MAX_DNS_SERVERS,
NU_NO_SUSPEND) != NU_SUCCESS)
{
return (NU_MEM_ALLOC);
}
DNS_Servers.dnss_head = NU_NULL;
DNS_Servers.dnss_tail = NU_NULL;
for (i = 0; i < DNS_MAX_DNS_SERVERS; i++, dns_server++)
{
/* Clear the IP address. */
*(UINT32 *)dns_server->dnss_ip = 0;
/* Add this host to the list. */
DLL_Enqueue(&DNS_Servers, dns_server);
}
#endif /* INCLUDE_DNS == NU_TRUE */
/* Count the number of hosts. */
for ( hst = hostTable, host_count = 0;
hst->name[0];
hst++, host_count++ );
/* Allocate a block of memeory to build the hosts list with. */
if (NU_Allocate_Memory (&System_Memory, (VOID **)&dns_host,
(UNSIGNED)(sizeof (DNS_HOST) * host_count),
NU_NO_SUSPEND) != NU_SUCCESS)
{
return (NU_MEM_ALLOC);
}
/* Build the HOST list. */
for (i = 0; i < host_count; i++, dns_host++)
{
/* Setup the name and IP address. */
dns_host->dns_name = hostTable[i].name;
memcpy(dns_host->dns_ipaddr, hostTable[i].address, 4);
/* Set the TTL. A TTL of 0 indicates that an entry is permanent. */
dns_host->dns_ttl = 0;
/* Setup the length of the name. Account for the null terminator. */
dns_host->dns_name_size = strlen(hostTable[i].name) + 1;
/* Add this host to the list. */
DLL_Enqueue(&DNS_Hosts, dns_host);
}
#ifdef VIRTUAL_NET_INCLUDED
if (VDRV_DNS_Init() != NU_SUCCESS)
return -1;
#endif
return (NU_SUCCESS);
} /* DNS_Initialize */
/****************************************************************************
* FUNCTION
*
* DNS_Find_Host_By_Name
*
* DESCRIPTION
*
* This function searches the "hosts" file for a host with a matching name.
* If the host is not found DNS is used to resolve the host name if
* if possible.
*
* INPUTS
*
* name The name of the host to find.
*
* OUTPUTS
*
* DNS_HOST* Host pointer, or NULL if not found.
*
******************************************************************************/
STATUS DNS_Find_Host_By_Name(CHAR *name, DNS_HOST **host)
{
STATUS status = NU_NOT_A_HOST;
DNS_HOST *l_host;
#if (INCLUDE_DNS == NU_TRUE)
CHAR ip_addr[4];
UNSIGNED ttl;
#endif
/* Search for a matching host. */
for ( l_host = DNS_Hosts.dns_head; l_host ; l_host = l_host->dns_next)
{
/* Is this one we're looking for. */
if (NU_STRICMP((const char *)l_host->dns_name, name) == 0)
{
/* We found a match. If this is a permanent entry, or if the ttl
has not expired then return it. Else it needs to be updated, so
break so that it can be resolved below. */
if ( (!l_host->dns_ttl) ||
(INT32_CMP(l_host->dns_ttl, NU_Retrieve_Clock()) > 0) )
{
status = NU_SUCCESS;
*host = l_host;
break;
}
else
{
status = NU_NOT_A_HOST;
break;
}
}
}
#if (INCLUDE_DNS == NU_TRUE)
/* If the host was not found in the local cache or it had expired, then try
to resolve it through DNS. */
if (status < 0)
{
if ((status = DNS_Resolve(name, ip_addr, &ttl, DNS_TYPE_A)) == NU_SUCCESS)
{
/* The address was resolved. Add this host to the cache. The only reason
this addition can fail is if there is no memory. */
l_host = DNS_Add_Host(name, ip_addr, ttl);
if (l_host == NU_NULL)
{
status = NU_NO_MEMORY;
}
else
{
status = NU_SUCCESS;
*host = l_host;
}
}
}
#endif /* INCLUDE_DNS == NU_TRUE */
return (status);
} /* DNS_Find_Host_By_Name */
/****************************************************************************
* FUNCTION
*
* DNS_Find_Host_By_Addr
*
* DESCRIPTION
*
* This function searches the "hosts" file for a host with a matching addr.
* If the host is not found DNS is used to resolve the host address
* if possible.
*
* INPUTS
*
* addr The address of the host to find.
*
* OUTPUTS
*
* DNS_HOST* Host pointer, or NULL if not found.
*
******************************************************************************/
STATUS DNS_Find_Host_By_Addr(CHAR *addr, DNS_HOST **host)
{
STATUS status = NU_NOT_A_HOST;
DNS_HOST *l_host;
#if (INCLUDE_DNS == NU_TRUE)
CHAR name[255];
UNSIGNED ttl;
#endif
/* Search for a matching host. */
for ( l_host = DNS_Hosts.dns_head; l_host ; l_host = l_host->dns_next)
{
/* Is this one we're looking for. */
if (IP_ADDR((UINT8 *)l_host->dns_ipaddr) == IP_ADDR((UINT8 *)addr))
{
/* We found a match. If this is a permanent entry or if the ttl has
not expired then return it. Else it needs to be updated so break.
The DNS resolver will be invoked below. */
if ( (!l_host->dns_ttl) ||
(INT32_CMP(l_host->dns_ttl, NU_Retrieve_Clock()) > 0) )
{
status = NU_SUCCESS;
*host = l_host;
break;
}
else
{
status = NU_NOT_A_HOST;
break;
}
}
}
#if (INCLUDE_DNS == NU_TRUE)
/* If the host was not found in the local cache or the ttl had expired, then
try to resolve it through DNS. */
if (status < 0)
{
if ((status = DNS_Resolve(name, addr, &ttl, DNS_TYPE_PTR)) == NU_SUCCESS)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -