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 + -
显示快捷键?