域名解析-vs2010代码示例

来源:互联网 发布:vb.net加载dll 编辑:程序博客网 时间:2024/05/01 14:40

头文件的内容dns.h

/** * file dns.h * Define the DNS request packet header format. * Author : Wen Shifang * 2015.8.20 */#ifndef __DNS_H__#define __DNS_H__#define PLATFORM_WINDOWS   /* 域名查询请求报文头定义,1字节对齐*/#if defined(PLATFORM_WINDOWS)#pragma  pack(push)#pragma  pack(1)#endifstruct DnsHeader{    unsigned short id;    unsigned char rd:1; /*期望递归解析*/    unsigned char tc:1;   /*报文未截断 */    unsigned char aa:1;   /*授权解析服务器 */    unsigned char opcode:4;/*标准查询 */    unsigned char qr:1;   /*0:查询,1:响应 */    unsigned char rcode:4;/*响应吗:0没有出错 */    unsigned char z:3;    /*保留将来使用 */    unsigned char ra:1;   /*DNS服务器是否支持递归解析 */    unsigned short qdCount; /* 问题数*/    unsigned short anCount; /* 应答数*/    unsigned short nsCount; /* 授权机构数 */    unsigned short arCount; /* 附加信息数 */}#if defined (PLATFORM_LINUX)__attribute__(("packed"))#endif;#if defined(PLATFORM_WINDOWS)#pragma  pack(pop)#endif#define COMMENT_MAX 64#define SYMBOL_MAX  8struct QueryType{    unsigned short q_class;    unsigned char mnemonic_symbol[SYMBOL_MAX];    unsigned char comment[COMMENT_MAX];};#endif

主文件内容main.c

#include <stdio.h>  #include <winsock2.h>  #include "dns.h"#pragma comment(lib,"ws2_32.lib")  #define DNS_ADDR  "202.96.134.33"#define SERVER_PORT 53#define MAX_TRY_CNT  3static unsigned short packet_id = 0x55AA;/* 交换字节序 */void exchangeByteOrder(unsigned char *byte){    unsigned char temp;    temp = byte[0];    byte[0] = byte[1];    byte[1] = temp;}/* 交换一个字的字节顺序 */void exchangeWordOrder(unsigned int *word){    unsigned char temp;    unsigned char *ptr[4];    ptr[0] = (unsigned char *)(word);    ptr[1] = ((unsigned char *)(word))+1;    ptr[2] = ((unsigned char *)(word))+2;    ptr[3] = ((unsigned char *)(word))+3;    temp = *ptr[0];    *ptr[0] = *ptr[3];    *ptr[3] = temp;    temp = *ptr[1];    *ptr[1] = *ptr[2];    *ptr[2] = temp;}/* 构造 DNS 请求报文包头(12 bytes) */int dns_packet_hdr_construct(struct DnsHeader *header){    /* 定义DNS查询报文请求头,没有使用的字段必须设置为0 */    header->id = packet_id;     /* ID ,由进程任意指定,以作标识 */    header->rd = 1;             /*期望递归解析*/    header->tc = 0;    header->aa = 0;    header->opcode = 0;         /*标准查询 */    header->qr = 0;    header->rcode = 0;    header->z = 0;    header->ra = 0;    header->qdCount = 1;        /*问题数量 */    header->anCount = 0;    header->nsCount = 0;    header->arCount = 0;    /* 16 bits 的本地格式转换为网络格式 */    exchangeByteOrder((unsigned char *)&header->anCount);    exchangeByteOrder((unsigned char *)&header->qdCount);    exchangeByteOrder((unsigned char *)&header->nsCount);    exchangeByteOrder((unsigned char *)&header->arCount);    return sizeof(struct DnsHeader);}/* 构造 NDS 请求报文内容 */int dns_packet_body_construct(char *packet_body, const char *buf){    const char *domain_ptr = buf ;    int i = 0, j = 0;    while(*domain_ptr != '\0'){        if(*domain_ptr != '.'){            packet_body[i+1] = *domain_ptr;            j++;        }else{            packet_body[i-j] = j;            j = 0;        }        i++; domain_ptr++;    }    packet_body[i-j] = j;    packet_body[++i] = 0;           /* null */    packet_body[++i] = 0x00;    packet_body[++i] = 0x01;        /* 查询类型  为 1 : IPv4地址 */    packet_body[++i] = 0x00;        /* 查询类 为 1 : Inetnet数据 */    packet_body[++i] = 0x01;    return i;}/** * 解析 问题 * packet:数据包头部指针 * body:  指向问题域开始部分 */const char *dns_packet_question_resovle(const struct DnsHeader *packet, const char *body){    const char *ptr;    unsigned char cnt = 0;    unsigned char len = 0;    printf("the queston:");    ptr = body;    while(*ptr != '\0'){        cnt = *ptr++;        while(cnt--){            printf("%c", *ptr);            ptr++;        }        if(*ptr != '\0'){            printf(".");        }    }    printf("\n");    ptr++;  /* skip null */    printf("Type : ");    if(*ptr == 0x0 && *(ptr+1) == 0x1){        printf("Host Address\n");    }else{        printf("%02x%02x\n",*ptr, *(ptr+1));    }    ptr += 2; /* skip Type area */    printf("Class : ");    if(*ptr == 0x0 && *(ptr+1) == 0x01){        printf("IN\n");    }else{        printf("%02x%02x\n");    }    ptr += 2;  /* skip Class area */    return ptr;}/* 解析名字 */const char *dns_packet_name_resovle(const struct DnsHeader *packet, const  char *name){    const char *p;    unsigned char cnt,len;    p = name;    len = 0;    while(*p != '\0'){        if(((*p & 0xC0) >> 6) == 0x3){            p = (const char *)packet + (((*p & 0x3F)<<8) | *(p+1));             p = dns_packet_name_resovle(packet, p);        }else{            cnt = *p++;            while(cnt--){                printf("%c",*p++);            }            if(*p != '\0'){                printf(".");            }        }    }    return  p;}/* 解析资源数据 */const char *dns_packet_rr_resovle(const struct DnsHeader *packet, const  char *rr, unsigned short rlen){    const char *p;    unsigned char cnt = 0;    if(rlen == 0x4){        /* IP addr */        printf("%d.%d.%d.%d\n", (unsigned char)rr[0],(unsigned char)rr[1],            (unsigned char)rr[2],(unsigned char)rr[3]);        return (rr += 4);    }    while(rlen > 0){        if(((*rr & 0xC0) >> 6) == 0x3){            p = (const char *)packet + ((*rr & 0x3F)<<8 | (*(rr+1)));            rlen -= 2;            cnt = *p++;            rr +=  2;        }else{            p = rr;            cnt = *p++;            rlen -= ( cnt + 1 );            rr += ( cnt + 1 );        }        while(cnt--){            printf("%c", *p);            p++;        }        if(rlen != 0){            printf(".");        }    }    printf("\n");    return rr;}/** * 解析 应答 * packet:数据包头部指针 * body:  指向应答域开始部分 */const char *dns_packet_response_resovle(const struct DnsHeader *packet, const char *body){    const char *ptr;    unsigned char cnt = 0;    unsigned char len = 0;    unsigned int  ttl = 0;    unsigned short rs_len = 0;    printf("\nthe answer:\nName : ");    ptr = dns_packet_name_resovle(packet, body);    printf("%\n");    ptr = body + 2;  /* skip null ,Get Type (2 bytes) */    printf("Type : ");    if((*ptr == 0x0) && (*(ptr+1) == 0x1)){        printf("Host Address\n");    }else if((*ptr == 0x0) && (*(ptr+1) == 0x5)){        printf("CNAME (Canonical name for an alias)\n");    }else{        printf("%02x%02x\n",*ptr, *(ptr+1));    }    ptr += 2; /* skip Type area , Get Class (2 bytes) */    printf("Class : ");    if(*ptr == 0x0 && *(ptr+1) == 0x01){        printf("IN\n");    }else{        printf("%02x%02x\n");    }    ptr += 2;  /* skip Class area ,Get TTL(4 bytes) */    ttl = *(unsigned int *)(ptr);    exchangeWordOrder(&ttl);    printf("TTL(Time To live) :");    printf("%d\n",ttl);    ptr += 4;  /* skip TTL area , Get Resource length (2 bytes) */    rs_len =  *(unsigned short*)(ptr);    exchangeByteOrder((unsigned char *)&rs_len);    printf("Data length :");    printf("%d\n",rs_len );    ptr += 2;   /* skip Resource length area ,Get Resource Records */    printf("Data : ");    ptr = dns_packet_rr_resovle(packet, ptr, rs_len);    return ptr;}/** * 解析 授权机构 * packet:数据包头部指针 * body:  指向授权机构开始部分 */const char * dns_packet_authority_resovle(const struct DnsHeader *packet, const char *body){    return 0;}/** * 解析 附加信息 * packet:数据包头部指针 * body:  指向附加信息域开始部分 */const char * dns_packet_addtional_resovle(const struct DnsHeader *packet, const char *body){    return 0;}/* 解析 DNS 响应内容 */int dns_packet_body_resolve(const char *packet){    const struct DnsHeader *header;    const char *ptr;    unsigned short cnt;    header = (struct DnsHeader *)packet;    ptr = (const char *)header+sizeof(struct DnsHeader);    printf("Queston count is %d\n", header->qdCount);    printf("Answer count is %d\n", header->anCount);    printf("Authoritative count is %d\n", header->nsCount);    printf("Addtional count is %d\n", header->arCount);    /* 如果问题数量不为0,则解析问题域 */    if(header->qdCount > 0){        cnt = header->qdCount;        while(cnt--){               ptr = dns_packet_question_resovle(header, ptr);        }    }    /* 如果回答数量不为零,则解析回答域 */    if(header->anCount > 0){        cnt = header->anCount;        while(cnt--){            ptr = dns_packet_response_resovle(header, ptr);        }    }    /* 如果授权机构数不为零,则解析授权机构 */    if(header->nsCount > 0){        cnt = header->nsCount;        while(cnt--){            ptr = dns_packet_authority_resovle(header, ptr);        }    }    /* 如果附加信息数不为0,则解析附加信息 */    if(header->arCount > 0){        cnt = header->arCount;        while(1){            ptr = dns_packet_addtional_resovle(header, ptr);        }    }    return 0;}/* 解析 DNS 响应报文头 */int dns_packet_hdr_resolve(char *rbuf, int rlen){    struct DnsHeader *header;    header = (struct DnsHeader *)(rbuf);    if(header->id != packet_id){        printf("Packet don't match us\n");        return -1;    }    if(header->qr != 1){        printf("Not a response packet\n");        return -1;    }    /* 16 bits 的网络格式转换为 本地格式*/    exchangeByteOrder((unsigned char *)&header->anCount);    exchangeByteOrder((unsigned char *)&header->qdCount);    exchangeByteOrder((unsigned char *)&header->nsCount);    exchangeByteOrder((unsigned char *)&header->arCount);    if(header->anCount == 0){        printf("Answer count is zero\n");        return -1;    }    printf("Now ,we get a valid DNS response\n");    printf("Resovle Now.......\n");    dns_packet_body_resolve((char *)header);    return 0;}int main(int argc, char *argv[])  {      SOCKET soc;      SOCKADDR_IN addr,raddr;     char rbuf[BUFSIZ],sbuf[BUFSIZ];      struct DnsHeader header;    WSADATA wsa;      int i = 0,j = 0;    int rlen = 0, addr_len,try_cnt = 0;    if(argc != 2){        printf("usage   : dns_request domain_name\n");        printf("example : dns_requst www.baidu.com");        return -1;    }    /* Initial Ws2_32.dll by a process */    if(WSAStartup(MAKEWORD(2,2), &wsa) != 0){        printf("WSAStartup : Error code %d\n",WSAGetLastError());        return -1;    }      if((soc = socket(AF_INET,SOCK_DGRAM,0)) <= 0)      {          printf("Create socket fail!\n");          return -1;      }      addr_len = sizeof(raddr);    memset(&addr, 0, sizeof(addr));    addr.sin_family = AF_INET;      addr.sin_addr.s_addr = inet_addr(DNS_ADDR);      addr.sin_port = htons(SERVER_PORT);      /* fill domain name field */    dns_packet_hdr_construct(&header);    memcpy(sbuf, (char *)&header, sizeof(header));    i = dns_packet_body_construct(sbuf + sizeof(header), argv[1]);    while(1) {          printf("try to request DNS(%s) to resolve the %s\n", DNS_ADDR, argv[1]);        if(sendto(soc, sbuf, i + sizeof(header) + 1, 0, (struct sockaddr *)&addr, sizeof(addr))< 0){            printf("sendto Error\n", WSAGetLastError());            break;        }        printf("waiting to response...");        if((rlen = recvfrom(soc, rbuf, BUFSIZ, 0, (struct sockaddr *)&raddr, &addr_len)) < 0){            printf("recvfrom Error Err %d\n", WSAGetLastError());            break;        }else{            if(dns_packet_hdr_resolve(rbuf, rlen)  == 0){                printf("ok DNS request successfully\n");                break;            }        }        if(++try_cnt >= MAX_TRY_CNT){            printf("try %d times total, but still can't resolve the %s\n", MAX_TRY_CNT,argv[1]);            break;        }    }      WSACleanup();   //clean up Ws2_32.dll      return 0;  } 
0 0
原创粉丝点击