dns.c
来自「mcf5307实验源代码」· C语言 代码 · 共 1,215 行 · 第 1/5 页
C
1,215 行
/* < 0 Failure */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* Glen Johnson 06/16/97 Created initial version for NET 3.1 */
/* */
/******************************************************************************/
INT DNS_Build_Query(CHAR *data, VOID **buffer, INT type)
{
DNS_PKT_HEADER *dns_pkt;
CHAR *q_ptr;
INT name_size;
CHAR name[30];
/* Allocate a block of memeory to build the query packet in. */
if (NU_Allocate_Memory (&System_Memory, (VOID **)&dns_pkt,
DNS_MAX_MESSAGE_SIZE, NU_NO_SUSPEND) != NU_SUCCESS)
{
return (NU_MEM_ALLOC);
}
/* Setup the packet. */
/* SGJ: Make this a proper ID. */
dns_pkt->dns_id = intswap(1);
dns_pkt->dns_flags = intswap(DNS_RD); /* Set the Recursion desired bit. */
dns_pkt->dns_qdcount = intswap(1); /* There is only one query. */
dns_pkt->dns_ancount = 0;
dns_pkt->dns_nscount = 0;
dns_pkt->dns_arcount = 0;
/* Point to the query section of the packet. */
q_ptr = (CHAR *)(dns_pkt + 1);
/* If we have a IP address and trying to get a name, convert the address to
a character string. */
if (type == DNS_TYPE_PTR)
DNS_Addr_To_String(data, name);
/* Pack the domain name, i.e., put it in a format the server will
understand. The packed domain name will be copied into the location
pointer to by q_ptr. */
switch (type)
{
case DNS_TYPE_A :
if ((name_size = DNS_Pack_Domain_Name((CHAR *)q_ptr, data)) < 0 )
return (name_size);
break;
case DNS_TYPE_PTR :
if ((name_size = DNS_Pack_Domain_Name((CHAR *)q_ptr, name)) < 0)
return (name_size);
break;
default :
return -1;
}
/* Move the pointer past the end of the name. */
q_ptr += name_size;
/* Load the type and class fields of the query structure a byte at a time so
that platforms that require word alignment won't choke. */
*q_ptr++ = 0;
*q_ptr++ = type; /* The type is < 255, so high byte=0. */
/* Fill in the class. */
*q_ptr++ = 0;
*q_ptr = DNS_CLASS_IN; /* The class is < 255, so high byte=0. */
/* Return a pointer to the DNS packet. */
*buffer = dns_pkt;
return (sizeof(DNS_PKT_HEADER) + name_size + 4);
} /* DNS_Build_Query */
/******************************************************************************/
/* FUNCTION */
/* */
/* DNS_Query */
/* */
/* DESCRIPTION */
/* */
/* This function queries a DNS server. It sends a DNS query packet and */
/* waits for the response. */
/* */
/* AUTHOR */
/* */
/* Glen Johnson, Accelerated Technology Inc. */
/* */
/* CALLED BY */
/* */
/* DNS_Resolve Resolve a host IP address. */
/* */
/* CALLS */
/* */
/* NU_Close_Socket Shut down a socket. */
/* NU_FD_Init Zero out the a bit map. */
/* NU_FD_Set Set a bit in a bit map. */
/* NU_Recv_From Receive a UDP packet. */
/* NU_Select Check for data on a socket. */
/* NU_Send_To Send a UDP packet. */
/* NU_Socket Create a communication socket. */
/* */
/* INPUTS */
/* */
/* buffer A pointer to a buffer containing a query pkt. */
/* q_size The size of the query. */
/* */
/* OUTPUTS */
/* */
/* > 0 The size of the received response. */
/* < 0 Failure */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* Glen Johnson 06/17/97 Created initial version for NET 3.1 */
/* */
/******************************************************************************/
INT DNS_Query(CHAR *buffer, int16 q_size)
{
struct addr_struct dns_addr;
FD_SET readfs, writefs, exceptfs;
STATUS stat;
INT attempts = DNS_MAX_ATTEMPTS;
int16 r_size = 0;
int16 bytes_sent;
int16 socketd;
if ((socketd = NU_Socket(NU_FAMILY_IP, NU_TYPE_DGRAM, 0)) < 0)
return (socketd);
/* Fill in a structure with the server address */
dns_addr.family = NU_FAMILY_IP;
dns_addr.port = DNS_PORT;
dns_addr.id.is_ip_addrs[0] = DNS_Server[0];
dns_addr.id.is_ip_addrs[1] = DNS_Server[1];
dns_addr.id.is_ip_addrs[2] = DNS_Server[2];
dns_addr.id.is_ip_addrs[3] = DNS_Server[3];
dns_addr.name = "";
/* Initially all the bits should be cleared. */
NU_FD_Init(&readfs);
while (attempts)
{
/* Send the DNS query. */
bytes_sent = NU_Send_To(socketd, buffer, q_size, 0, &dns_addr, 0);
/* If the data was not sent, we have a problem. */
if (bytes_sent < 0)
break;
/* Decrement the number of attempts left. */
attempts--;
/* Specify which socket we want to select on. */
NU_FD_Set(socketd, &readfs);
/* Select on the specified socket for one second. */
stat = NU_Select(NPORTS, &readfs, &writefs, &exceptfs, TICKSPERSEC);
/* If there is no data on the socket, either send the query again or
give up. */
if (stat != NU_SUCCESS)
continue;
/* Go get the server's response. */
r_size = NU_Recv_From(socketd, buffer, 1000, 0, &dns_addr, 0);
break;
}
/* Close the socket. */
NU_Close_Socket(socketd);
if (r_size > 0)
return r_size;
else
return (NU_FAILED_QUERY);
} /* DNS_Query */
/******************************************************************************/
/* FUNCTION */
/* */
/* DNS_Pack_Domain_Name */
/* */
/* DESCRIPTION */
/* */
/* This function takes a domain name and converts it to a format a DNS */
/* server expects. */
/* */
/* AUTHOR */
/* */
/* Glen Johnson, Accelerated Technology Inc. */
/* */
/* CALLED BY */
/* */
/* DNS_Build_Query Create a DNS query packet. */
/* */
/* CALLS */
/* */
/* */
/* INPUTS */
/* */
/* dst The converted name. */
/* src The original name. */
/* */
/* OUTPUTS */
/* */
/* > 0 The size of the new name. */
/* < 0 Failure */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* Glen Johnson 06/17/97 Created initial version for NET 3.1 */
/* */
/******************************************************************************/
INT DNS_Pack_Domain_Name (CHAR *dst, CHAR *src)
{
CHAR *p;
CHAR *original_dest;
INT n;
/* If this is a null string return an error. */
if (!*src)
return (NU_INVALID_LABEL);
p = original_dest = dst;
do
{
/* Move past the byte where the length will be saved. */
dst++;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?