rt

解决方案 »

  1.   

    先去看看DNS的查询报文格式吧
      

  2.   

    struct hostent FAR *gethostbyname(
      const char FAR *name  
    );返回的结构里面有关于这个服务器的详细信息
      

  3.   

    关注啊 楼主是要做SMTP服务器吗?
      

  4.   

    nslookuptype = mx应该可以的
      

  5.   

    #ifndef DNS_H
    #define DNS_H#define DNS_SOFT -1
    #define DNS_HARD -2
    #define DNS_MEM -3void dns_init();
    int dns_cname();
    int dns_mxip();
    int dns_ip();
    int dns_ptr();#endif
    以上代码来自qmail, 你可以到qmail.org去找,dns.c文件
      

  6.   

    sigh,你最好还是不要看Dan Bernstein的代码了,那太神奇了,不看也罢.
    还是下载一份Bind的源码罢,http://www.isc.org/products/BIND/bind9.html网上太多太多这种代码了,找找吧.
      

  7.   

    #include "stdafx.h"
    #include <winsock2.h>
    #include <stdio.h>#define ASCII_NULL              '\0'
    #define MAXHOSTNAME             256
    #define BUFSIZE                 2048
    #define QUERYTIMEOUT            30 //secondtypedef struct dns_hdr
    {
            u_short dns_id;          /* client query ID number */
            u_short dns_flags;       /* qualify contents <see below> */
            u_short dns_q_count;     /* number of questions */
            u_short dns_rr_count;    /* number of answer RRs */
            u_short dns_auth_count;  /* number of authority RRs */
            u_short dns_add_count;   /* number of additional RRs */
    } DNS_HDR, *PDNS_HDR, FAR *LPDNS_HDR;#define DNS_HDR_LEN 12#define DNS_FLAG_QR 0x8000
    #define DNS_FLAG_AA 0x0400
    #define DNS_FLAG_TC 0x0200
    #define DNS_FLAG_RD 0x0100
    #define DNS_FLAG_RA 0x0080
    #define DNS_RCODE_MASK  0x000F
    #define DNS_OPCODE_MASK 0x7800/* DNS Opcode (type of query) */
    char *DNS_Opcode[] =
    {
            "Standard Query",         /* 0: QUERY  */
            "Inverse Query",          /* 1: IQUERY */
            "Server Status Request",  /* 2: STATUS */
    };/* DNS Response Codes (error descriptions) */
    char *DNS_RCode[] =
    {
            "No Error",        /* 0: ok */
            "Format Error",    /* 1: bad query */
            "Server Failure",  /* 2: server is hosed */
            "Name Error",      /* 3: name doesn't exist (authoritative) */
            "Not Implemented", /* 4: server doesn't support query */
            "Refused"          /* 5: server refused request */
    };/* DNS Generic Resource Record format (from RFC 1034 and 1035) */
    typedef struct dns_rr_hdr
    {
            u_short rr_type;                /* RR type code (e.g. A, MX, NS, etc.) */
            u_short rr_class;               /* RR class code (IN for Internet) */
            u_long  rr_ttl;         /* Time-to-live for resource */
            u_short rr_rdlength;    /* length of RDATA field (in octets) */
            u_short rr_rdata;               /* (fieldname used as a ptr) */
    } DNS_RR_HDR, *PDNS_RR_HDR, FAR *LPDNS_RR_HDR;#define DNS_RR_HDR_LEN 12/* DNS Resource Record RDATA Field Descriptions */
    char *DNS_RR_Type [] =
    {
            "<invalid>",
            "A",     // 1:  Host Address
            "NS",    // 2:  Authoritative Name Server
            "MD",    // 3:  <obsolete>
            "MF",    // 4:  <obsolete>
            "CNAME", // 5:  The true, canonical name for an alias
            "SOA",   // 6:  Start-of-Zone of authority record
            "MB",    // 7:  Mailbox   <experimental>
            "MG",    // 8:  Mailgroup <experimental>
            "MR",    // 9:  Mail Rename Domain Name <experimental>
            "NULL",  // 10: NULL Resource Record    <experimental>
            "WKS",   // 11: Well-known service description
            "PTR",   // 12: Domain Name Pointer
            "HINFO", // 13: Host Information
            "MINFO", // 14: Mailbox or Mail List information
            "MX",    // 15: Mail Exchange (from RFC 974)
            "TXT"    // 16: Text String
    };#define DNS_RRTYPE_A     1
    #define DNS_RRTYPE_NS    2
    #define DNS_RRTYPE_CNAME 5
    #define DNS_RRTYPE_SOA   6
    #define DNS_RRTYPE_WKS   11
    #define DNS_RRTYPE_PTR   12
    #define DNS_RRTYPE_HINFO 13
    #define DNS_RRTYPE_MX    15
    #define DNS_RRTYPE_TXT   16/* DNS Resource Record Classes: */
    char *DNS_RR_Class [] =
    {
            "<invalid>",
            "IN",    // 1: Internet - used for most queries!
            "CS",    // 2: CSNET <obsolete>
            "CH",    // 3: CHAOS Net
            "HS"     // 4: Hesiod
    };#define DNS_RRCLASS_IN  1
    #define DNS_RRCLASS_CS  2
    #define DNS_RRCLASS_CH  3
    #define DNS_RRCLASS_HS  4/* DNS SOA Resource Data Field */
    typedef struct dns_rdata_soa
    {
            u_long soa_serial;  /* data version for this zone */
            u_long soa_refresh; /* time-to-live for data (in seconds) */
            u_long soa_retry;   /* time between retrieds (in seconds) */
            u_long soa_expire;  /* time until zone not auth (in seconds) */
            u_long soa_minimum; /* default TTL for RRs (in seconds) */
    } DNS_RDATA_SOA, PDNS_RDATA_SOA, FAR *LPDNS_RDATA_SOA;#define DNS_SOA_LEN 20typedef struct dns_rdata_wks
    {
            u_long wks_addr;      /* IPv4 address */
            u_char wks_protocol;  /* Protocol (e.g. 6=TCP, 17=UDP) */
            u_char wks_bitmap;    /* e.g. bit 26 = SMTP (port 25) */
    } DNS_RDATA_WKS, *PDNS_RDATA_WKS, FAR *LPDNS_RDATA_WKS;#define DNS_WKX_LEN 6/* DNS MX Resource Data Field
     */
    typedef struct dns_rdata_mx
    {
            u_short mx_pref;     /* Preference value */
            u_short mx_xchange;  /* QNAME (field used as ptr) */
    } DNS_RDATA_MX, *PDNS_RDATA_MX, FAR *LPDNS_RDATA_MX;#define DNS_MX_LEN 4/* Variables used for DNS Header construction & parsing */
    PDNS_HDR       pDNShdr;
    PDNS_RR_HDR    pDNS_RR;
    PDNS_RDATA_SOA pDNS_SOA;
    PDNS_RDATA_WKS pDNS_WKS;
    PDNS_RDATA_MX  pDNS_MX;    /* For Parsing Names in a Reply */
    #define INDIR_MASK 0xc0 /* Number of bytes of fixed size data in query structure */
    #define QFIXEDSZ 4
    /* number of bytes of fixed size data in resource record */
    #define RRFIXEDSZ 10/* Processor Types */
    char *aszProcessor[] =
    {
            "",
            "",
            "",
            "Intel 386",
            "Intel 486",
            "Intel Pentium"
    };
      

  8.   

    void GetQName( char FAR *pszHostName, char FAR *pQName );
    void PrintQName(const char FAR *pQName );
    int  PutQName(const char FAR *pszHostName, char FAR *pQName );
    int  dn_expand(char *msg,char  *eomorig,char *comp_dn,char *exp_dn,int length);
    int  dn_expand_new(char *msg,char  *eomorig,char *comp_dn,char *exp_dn,int length, bool stop=false);
    u_short _getshort(char *msgp)
    {
    register u_char *p = (u_char *) msgp;
    register u_short u; u = *p++ << 8;
    return ((u_short)(u | *p));
    }u_long _getlong(char *msgp)
    {
    register u_char *p = (u_char *) msgp;
    register u_long u; u = *p++; u <<= 8;
    u |= *p++; u <<= 8;
    u |= *p++; u <<= 8;
    return (u | *p);
    }
    /*
     * Expand compressed domain name 'comp_dn' to full domain name.
     * 'msg' is a pointer to the begining of the message,
     * 'eomorig' points to the first location after the message,
     * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
     * Return size of compressed name or -1 if there was an error.
     */int dn_expand(char *msg,char  *eomorig,char *comp_dn,char *exp_dn,int length)
    {
    register char *cp, *dn;
    register int n, c;
    char *eom;
    int len = -1, checked = 0; dn = exp_dn;
    cp = comp_dn;
    eom = exp_dn + length - 1;
    /*
     * fetch next label in domain name
     */
    while (n = *cp++) {
    /*
     * Check for indirection
     */
    switch (n & INDIR_MASK) {
    case 0:
    if (dn != exp_dn) {
    if (dn >= eom)
    return (-1);
    *dn++ = '.';
    }
    if (dn+n >= eom)
    return (-1);
    checked += n + 1;
    while (--n >= 0) {
    if ((c = *cp++) == '.') {
    if (dn+n+1 >= eom)
    return (-1);
    *dn++ = '\\';
    }
    *dn++ = c;
    if (cp >= eomorig) /* out of range */
    return(-1);
    }
    break; case INDIR_MASK:
    if (len < 0)
    len = cp - comp_dn + 1;
    cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
    if (cp < msg || cp >= eomorig) /* out of range */
    return(-1);
    checked += 2;
    /*
     * Check for loops in the compressed name;
     * if we've looked at the whole message,
     * there must be a loop.
     */
    if (checked >= eomorig - msg)
    return (-1);
    break; default:
    return (-1); /* flag error */
    }
    }
    *dn = '\0';
    if (len < 0)
    len = cp - comp_dn;
    return (len);
    }
      

  9.   

    void GetQName( char FAR *pszHostName, char FAR *pQName )
    {    int i, j, k;    for ( i = 0; i < BUFSIZE; i++ )
        {
                j = *pQName;            if ( j == 0 )
                        break;            for ( k = 1; k <= j; k++ )
                {
                        *pszHostName++ = *( pQName + i + k );
                } // end for loop
        } // end for loop    *pszHostName++ = ASCII_NULL;
    } /* end GetQName() */
    void PrintQName( char FAR *pQName )
    {
        int i, j, k;    for ( i = 0; i < BUFSIZE; i++ )
        {
                j = *pQName;            if ( j == 0 )
                        break;            for ( k = 1; k <= j; k++ )
                {
                        //printf( "%c", *( pQName + i + k ) );
                } // end for loop
        } // end for loop
    } /* end PrintQName() */
    int PutQName(const char FAR *pszHostName, char FAR *pQName )
    {
        int     i;
        int     j = 0;
        int     k = 0;    for ( i = 0; *( pszHostName + i ); i++ )
        {
                char c = *( pszHostName + i );   /* get next character */            if ( c == '.' )
                {
                        /* dot encountered, fill in previous length */
                        *( pQName + j ) = k;                    k = 0;      /* reset segment length */
                        j = i + 1;    /* set index to next counter */
                }
                else
                {
                        *( pQName + i + 1 ) = c;  /* assign to QName */
                        k++;                /* inc count of seg chars */
                } // end if
        } // end for loop    *(pQName + j )                  = k;   /* count for final segment */
        *(pQName + i + 1 )      = 0;   /* count for trailing NULL segment is 0 */    return ( i + 1 );        /* return total length of QName */
    } /* end PutQName() *//*
     * Skip over a compressed domain name. Return the size or -1.
     */
    int dn_skipname(u_char *comp_dn,  u_char *eom)

    {
    register u_char *cp;
    register int n; cp = comp_dn;
    while (cp < eom && (n = *cp++)) {
    /*
     * check for indirection
     */
    switch (n & INDIR_MASK) {
    case 0: /* normal case, n == len */
    cp += n;
    continue;
    default: /* illegal type */
    return (-1);
    case INDIR_MASK: /* indirection */
    cp++;
    }
    break;
    }
    return (cp - comp_dn);
    }