⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dns.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
            /* The name 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, 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_Addr */

#if (INCLUDE_DNS == NU_TRUE)
/*****************************************************************************
* FUNCTION                                                                   
*
*   DNS_Resolve                                                              
*
* DESCRIPTION                                                                
*
*    This routine will handle domain based name lookup.  It can hadle both   
*    queries for names and quiries for IP addresses.  Either the name and ttl
*    are returned or an IP address and ttl are returned.                     
*
* INPUTS                                                                     
*
*    name                      A host name.                                  
*    ip_addr                   The host IP address, filled in by this        
*                                function.                                   
*    ttl                       Time To Live, length of time the host info.   
*                                can be cached.  Filled in here.             
*    type                      Type of query, name or address.               
*
* OUTPUTS                                                                    
*
*    NU_SUCCESS                Indicates successful operation.               
*    NU_DNS_ERROR or -1        Indicates failure.                            
*    NU_NO_DNS_SERVER          No DNS servers have been registered with the 
*                                stack.
*
******************************************************************************/
STATUS DNS_Resolve(CHAR *name, CHAR *ip_addr, UNSIGNED *ttl, UINT16 type)
{
    STATUS                  stat;
    CHAR                    *buffer;
    INT                     q_size;
    DNS_SERVER              *cur_server;


    /* Is there at least one DNS Server. */
    if ( !(*(UINT32 *)DNS_Servers.dnss_head->dnss_ip))
    {
        return (NU_NO_DNS_SERVER);
    }

    /* Build the DNS query. */
    switch (type)
    {
        case DNS_TYPE_A :

            if ((q_size = DNS_Build_Query(name, (VOID **)&buffer, type)) < 0)
                return -1;

            break;

        case DNS_TYPE_PTR :

            if ((q_size = DNS_Build_Query(ip_addr, (VOID **)&buffer, type)) < 0)
                return -1;

            break;

        default:

            return -1;
    }

    /* Loop through the list of DNS servers querying them until the query
       is successful or until we exhaust the list (spr474). */
    for( cur_server = DNS_Servers.dnss_head;
         cur_server && ((UINT32 *)cur_server->dnss_ip)[0] != 0;
         cur_server = cur_server->dnss_next)
    {
        /* Query the DNS server.  Upon returning the buffer will contain the
           response to our query. */
        if (DNS_Query(buffer, q_size, cur_server->dnss_ip) > 0)
            break;
    }

    /* If we stepped through every entry in the list or if we stepped through
       every used entry then return failure. */
    if ((cur_server == NU_NULL) || (*(UINT32 *)cur_server->dnss_ip == 0))
    {
        /* Return the buffer to the memory pool. */
        NU_Deallocate_Memory(buffer);

        /* Return error */
        return -1;
    }

        /* Now process the response. */
    switch (type)
    {
        case DNS_TYPE_A :

            stat = DNS_Extract_Data ((DNS_PKT_HEADER *)buffer, ip_addr, ttl,
                                      (INT)type);
            break;

        case DNS_TYPE_PTR :

            stat = DNS_Extract_Data ((DNS_PKT_HEADER *)buffer, name, ttl, (INT)type);
            break;

        default:

            return -1;
    }

    /* Deallocate the memory buffer. */
    NU_Deallocate_Memory(buffer);

    if (stat != NU_SUCCESS)
        return (NU_DNS_ERROR);
    else
        return (stat);

}  /* DNS_Resolve */

/****************************************************************************
* FUNCTION                                                                   
*                                                                            
*   DNS_Build_Query                                                          
*                                                                            
* DESCRIPTION                                                                
*                                                                            
*    This function will build a DNS query packet.                            
*                                                                            
* INPUTS                                                                     
*                                                                            
*    data                                                                    
*    buffer                    A pointer to a buffer pointer.                
*    type                      A query type.                                 
*                                                                            
* OUTPUTS                                                                    
*                                                                            
*    INT:                                                                    
*      > 0                       The size of the packed name.                
*      NU_MEM_ALLOC                                                          
*      < 0                       General failure                             
*                                                                            
******************************************************************************/
INT  DNS_Build_Query(CHAR *data, VOID **buffer, UINT16 type)
{
    DNS_PKT_HEADER      *dns_pkt;
    CHAR                *ptr;
    DNS_RR              *rr_ptr;
    INT                 name_size;
    CHAR                name[80];

    /* 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_NO_MEMORY);
    }

    /* Setup the packet. */
    PUT16(dns_pkt, DNS_ID_OFFSET, 1);
    PUT16(dns_pkt, DNS_FLAGS_OFFSET, DNS_RD);   /* Set the Recursion desired bit. */
    PUT16(dns_pkt, DNS_QDCOUNT_OFFSET, 1);      /* There is only one query.       */
    PUT16(dns_pkt, DNS_ANCOUNT_OFFSET, 0);
    PUT16(dns_pkt, DNS_NSCOUNT_OFFSET, 0);
    PUT16(dns_pkt, DNS_ARCOUNT_OFFSET, 0);

    /* Point to the query section of the packet. */
    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(ptr, data)) < 0 )
            {
                NU_Deallocate_Memory(dns_pkt);  
                return (name_size);
            }
            break;

        case DNS_TYPE_PTR :
            if ((name_size = DNS_Pack_Domain_Name(ptr, name)) < 0)
            {
                NU_Deallocate_Memory(dns_pkt);  
                return (name_size);
            }
            break;

        default :
            NU_Deallocate_Memory(dns_pkt);
            return NU_INVALID_PARM;
    }

    /* Move the pointer past the end of the name. */
    rr_ptr = (DNS_RR *)(ptr + name_size);

    /* Load the type and class fields of the query structure. */
    PUT16(rr_ptr, DNS_TYPE_OFFSET, type);
    PUT16(rr_ptr, DNS_CLASS_OFFSET, DNS_CLASS_IN);

    /* The ttl and rdlength are not needed for a query. Set them to zero. */
    PUT32(rr_ptr, DNS_TTL_OFFSET, 0);
    PUT16(rr_ptr, DNS_RDLENGTH_OFFSET, 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.                                                 
*                                                                            
* INPUTS                                                                     
*                                                                            
*    buffer                    A pointer to a buffer containing a query pkt. 
*    q_size                    The size of the query.                        
*    dns_server                                                              
*                                                                            
* OUTPUTS                                                                    
*                                                                            
*    INT:                                                                    
*      > 0                       The size of the received response.          
*      NU_FAILED_QUERY                                                       
*      < 0                       General failure.                            
*                                                                            
******************************************************************************/
INT  DNS_Query(CHAR *buffer, INT q_size, UINT8 *dns_server)
{
    struct addr_struct      dns_addr;
    FD_SET                  readfs, writefs, exceptfs;
    STATUS                  stat;
    INT                     attempts = DNS_MAX_ATTEMPTS;
    STATUS                  r_size = 0;
    INT32                   bytes_sent;
    INT                     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;
    *(UINT32 *)dns_addr.id.is_ip_addrs = IP_ADDR(dns_server);
    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, (UINT16)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(NSOCKETS, &readfs, &writefs, &exceptfs, 
                        SCK_Ticks_Per_Second);

        /* 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 = (INT)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                                                                

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -