dns.c

来自「mcf5307实验源代码」· C语言 代码 · 共 1,215 行 · 第 1/5 页

C
1,215
字号

        /* Assume all labels have been copied until proven otherwise. */
        *p = 0;

        /* Copy the label. */
        for ( n = 0;
              *src && (*src != '.') && (n <= DNS_MAX_LABEL_SIZE);
              *dst++ = *src++, ++n );

        /* Check to see if the label exceded the maximum length. */
        if ( n > DNS_MAX_LABEL_SIZE)
            return (NU_INVALID_LABEL);

        /* Store the length of the label. */
        *p = dst - p - 1;

        /* Point to where the next length value will be stored. */
        p = dst;

        if (*src)
            src++;

    } while (*src);

    /* The end of the name is marked with a 0 length label. */
    *p = 0;

    dst++;

    return (dst - original_dest);

} /* DNS_Pack_Domain_Name */

/******************************************************************************/
/* FUNCTION                                                                   */
/*                                                                            */
/*   DNS_Unpack_Domain_Name                                                   */
/*                                                                            */
/* DESCRIPTION                                                                */
/*                                                                            */
/*    This function packed name and converts it to a character string.        */
/*                                                                            */
/* AUTHOR                                                                     */
/*                                                                            */
/*    Glen Johnson,      Accelerated Technology Inc.                          */
/*                                                                            */
/* CALLED BY                                                                  */
/*                                                                            */
/*    DNS_Extract_Data          Get data from a DNS response.                 */
/*                                                                            */
/* CALLS                                                                      */
/*                                                                            */
/*                                                                            */
/* INPUTS                                                                     */
/*                                                                            */
/*    dst                       The new name.                                 */
/*    src                       The original name.                            */
/*    buf_begin                 Pointer to start od response packet.          */
/*                                                                            */
/* OUTPUTS                                                                    */
/*                                                                            */
/*    The size of the new name.                                               */
/*                                                                            */
/* HISTORY                                                                    */
/*                                                                            */
/*    NAME                DATE        REMARKS                                 */
/*                                                                            */
/*    Glen Johnson      06/17/97    Created initial version for NET 3.1       */
/*                                                                            */
/******************************************************************************/
INT DNS_Unpack_Domain_Name(CHAR *dst, CHAR *src, CHAR *buf_begin)
{
    int16           size;
    INT             i, retval = 0;
    CHAR            *savesrc;

	savesrc = src;

    /* The end of the name is marked by a 0 length label. */
    while (*src)
	{
        /* Get the size of the label. */
        size = *src;

        /* Check to see if this is a pointer instead of a label size. */
        while ((size & 0xC0) == 0xC0)
		{
            /* If we have not encountered a pointer yet compute the size of the
               name so far. */
            if (!retval)
			{
				retval = src - savesrc + 2;
			}

            src++;

            /* Point to the new location. */
            src = &buf_begin[(size & 0x3f) * 256 + *src];
            size = *src;
		}

        /* Move the pointer past the label size. */
        src++;

        /* Copy the label. */
        for (i = 0; i < (size & 0x3f); i++)
		{
			*dst++ = *src++;
		}

        /* Insert the period between labels. */
        *dst++ = '.';
	}

    /* Add the terminator. */
    *(--dst) = 0;

    /* Account for the terminator on src. */
    src++;

    /* If the name included a pointer then the return value has already been
       computed. */
    if (!retval)
	{
		retval = src - savesrc;
	}

	return (retval);
}  /* DNS_Unpack_Domain_Name */

/******************************************************************************/
/* FUNCTION                                                                   */
/*                                                                            */
/*   DNS_Extract_Data                                                         */
/*                                                                            */
/* DESCRIPTION                                                                */
/*                                                                            */
/*    This function takes a DNS response and extracts either an IP address or */
/*    a domain name, which ever the case may be.                              */
/*                                                                            */
/* AUTHOR                                                                     */
/*                                                                            */
/*    Glen Johnson,      Accelerated Technology Inc.                          */
/*                                                                            */
/* CALLED BY                                                                  */
/*                                                                            */
/*    DNS_Resolve               Resolve and IP address or host name.          */
/*                                                                            */
/* CALLS                                                                      */
/*                                                                            */
/*    NU_Allocate_Memory        Allocate memory.                              */
/*    NU_Deallocate_Memory      Deallocate a block of memory.                 */
/*    DNS_Unpack_Domain_Name    Unpack a domain name.                         */
/*    intswap                   Swap the bytes in an integer.                 */
/*    longswap                  Swap the bytes in a long.                     */
/*                                                                            */
/*                                                                            */
/* INPUTS                                                                     */
/*                                                                            */
/*    pkt                       A pointer to the DNS response.                */
/*    data                      Put the address or name here.                 */
/*    ttl                       Put the Time To Live here.                    */
/*    type                      The type of query.                            */
/*                                                                            */
/* OUTPUTS                                                                    */
/*                                                                            */
/*    NU_SUCCESS (0)            Indicates success.                            */
/*     < 0                      Indicates failure.                            */
/*                                                                            */
/* HISTORY                                                                    */
/*                                                                            */
/*    NAME                DATE        REMARKS                                 */
/*                                                                            */
/*    Glen Johnson      06/17/97    Created initial version for NET 3.1       */
/*                                                                            */
/******************************************************************************/
STATUS DNS_Extract_Data (DNS_PKT_HEADER *pkt, CHAR *data, UNSIGNED *ttl,
                         INT type)
{
    DNS_RR          *rr_ptr;
    INT             name_size, length, n_answers, rcode;
    CHAR            *p_ptr, *name;
    CHAR            answer_received = 0;

    /* Get the number of answers in this message. */
    n_answers = intswap (pkt->dns_ancount);

    /* Extract the return code. */
    rcode = DNS_RCODE_MASK & intswap (pkt->dns_flags);

    /* Was an error returned? */
    if (rcode)
        return (NU_DNS_ERROR);

    /* If there is at least one answer and this is a response, process it. */
    if ((n_answers > 0) && (intswap (pkt->dns_flags) & DNS_QR))
    {
        /* Point to where the question starts. */
        p_ptr = (CHAR *)(pkt + 1);

        /* Allocate a block of memory to put the name in. */
        if (NU_Allocate_Memory (&System_Memory, (VOID **)&name,
                                DNS_MAX_NAME_SIZE,
                                NU_NO_SUSPEND) != NU_SUCCESS)
        {
            return (NU_MEM_ALLOC);
        }

        /* Extract the name. */
        name_size = DNS_Unpack_Domain_Name (name, p_ptr, (CHAR *)pkt);

        /*  Move the pointer past the name QTYPE and QCLASS to point at the
            answer section of the response. */
        p_ptr += name_size + 4;

        /*
        *  At this point, there may be several answers.  We will take the first
		*  one which has an IP number.	There may be other types of answers that
		*  we want to support later.
		*/
        while ((n_answers--) > 0)
        {
            /* Extract the name from the answer. */
            name_size = DNS_Unpack_Domain_Name (name, p_ptr, (CHAR *)pkt);

            /* Move the pointer past the name. */
            p_ptr += name_size;

            /* Point to the resource record. */
            rr_ptr = (DNS_RR *)p_ptr;

            /* Since the is no guarantee that the resource record will be on a
               word boundary check the fields a byte at a time. */
            if ((!*p_ptr) && (*(p_ptr + 1) == type)
                && (!*(p_ptr + 2)) && (*(p_ptr + 3) == DNS_CLASS_IN))
			{
                switch (type)
                {
                    case DNS_TYPE_A :

                        /* The answer has the correct type and class. Copy
                           the IP addr. */
                        memcpy (data, rr_ptr->dns_rdata, 4);

⌨️ 快捷键说明

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