域名解析-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
- 域名解析-vs2010代码示例
- C++域名解析代码段
- nginx配置多个域名解析示例
- 域名解析
- 域名解析
- 域名解析
- 域名解析
- 域名解析
- 域名解析
- 域名解析
- 域名解析
- 域名解析
- 域名解析
- 域名解析
- 域名解析
- 域名解析
- 域名解析
- 域名解析
- 解决“只能通过Chrome网上应用商店安装该程序”的方法
- JVM核心之 JVM运行和类加载全过程
- mapreduce读取hbase中表的数据,直接打印或者回传数据到hbase数据库表
- 1030. Travel Plan (30)
- UVALive 6657 GCD XOR 异或,因子筛法
- 域名解析-vs2010代码示例
- 用图片平铺背景色
- Bootloader架构设计
- Oracle的常见问题
- 图片整理
- change Java on Ubuntu Kylin 15.04
- 黑马程序员—— Java 基础 面向对象之继承 (复习)
- 堆排序2.0
- POJ2503词典 Babelfish在外文中查找对应的英文