使用udp发送域名请求
来源:互联网 发布:淘宝关键字 编辑:程序博客网 时间:2024/06/08 05:10
#include <sys/socket.h>#include <stdio.h>#include <sys/types.h>#include <unistd.h>#include <netinet/in.h>#include <string.h>#pragma pack(push)#pragma pack(1)typedef struct dns_query_header{ unsigned short transid; unsigned short flags; unsigned short questions; unsigned short answer; unsigned short authority; unsigned short additional;}dns_query_header, *pdns_query_header;typedef struct dns_query_body{ unsigned char body[100];}dns_query_body;typedef struct dns_answer_body{unsigned char body[100];//name//type//closs//ttl//length//addr}dns_answer_body;#pragma pack(pop)int main(int argc, const char* argv[]){if(argc != 3){printf("%s domain dnsserverip\n", argv[0]);return 0;}const char * domain = argv[1];const char * dns_sever = argv[2]; int sock = socket(AF_INET, SOCK_DGRAM, 0); struct sockaddr_in dnsaddr; dnsaddr.sin_family = AF_INET; dnsaddr.sin_addr.s_addr = inet_addr(dns_sever); dnsaddr.sin_port = htons(53); dns_query_header dqh; dqh.transid = 0x1234; dqh.flags = htons(0x0100); dqh.questions = htons(0x1); dqh.answer = 0; dqh.authority = 0; dqh.additional = 0; int cursor = 0; dns_query_body dqb; memset((void *)dqb.body, 0x00, sizeof(dqb.body));int i = 0; // dqb.body[cursor++] = 3; // int i = 0; // for(i = 0; i < 3; i++) // { // dqb.body[cursor++] = 'w'; // } // dqb.body[cursor++] = 6; // dqb.body[cursor++] = 'g'; // dqb.body[cursor++] = 'o'; // dqb.body[cursor++] = 'o'; // dqb.body[cursor++] = 'g'; // dqb.body[cursor++] = 'l'; // dqb.body[cursor++] = 'e'; // dqb.body[cursor++] = 3; // dqb.body[cursor++] = 'c'; // dqb.body[cursor++] = 'o'; // dqb.body[cursor++] = 'm'; // dqb.body[cursor++] = '\0'; // dqb.body[cursor++] = 3; // dqb.body[cursor++] = 'k'; // dqb.body[cursor++] = 's'; // dqb.body[cursor++] = 'u'; // dqb.body[cursor++] = 3; // dqb.body[cursor++] = 'e'; // dqb.body[cursor++] = 'd'; // dqb.body[cursor++] = 'u'; // dqb.body[cursor++] = '\0'; unsigned char tcount = 0; cursor++; //blank for count for(i = 0; i < strlen(domain); i++) {if(domain[i] != '.'){tcount++;dqb.body[cursor++] = domain[i];}else{dqb.body[cursor-tcount-1] = tcount;tcount = 0;cursor++;} } dqb.body[cursor-tcount-1] = tcount; tcount = 0; dqb.body[cursor++] = '\0'; dqb.body[cursor++] = 0x00; dqb.body[cursor++] = 0x01;//qtype dqb.body[cursor++] = 0x00; dqb.body[cursor++] = 0x01;//qclass char buf[500]; memset((void *)buf, 0x00, sizeof(buf)); memcpy((void *)buf, (void *)&dqh, sizeof(dqh)); memcpy((void *)buf+sizeof(dqh), (void *)&dqb.body, cursor); if(sendto(sock, buf, sizeof(dqh)+cursor, 0, (struct sockaddr *)&dnsaddr, sizeof(dnsaddr)) < 0) {printf("send error\n");return 1; } unsigned char recvbuf[2048] = {""};//may be not enough, just for test if(recvfrom(sock, recvbuf, sizeof(recvbuf), 0, 0, 0) < 0) {printf("recv error\n");return 1; } unsigned short answer = ntohs(((dns_query_header *)&recvbuf)->answer); unsigned char *panswerbody = &recvbuf[sizeof(dns_query_header)+cursor]; int anscursor = 0; unsigned short datalength = 0; if(answer > 0) {for(; answer > 0; answer--){//while(panswerbody[anscursor++] != 0);// skip name//type = panswerbody[anscursor++]anscursor += 2;// skip nameanscursor += 2;// skip type;anscursor += 2;// skip class;anscursor += 4;// skip ttldatalength = ntohs(*(unsigned short *)&panswerbody[anscursor]);anscursor += 2;// skip data lengthif(datalength == 4){//only decode ipv4printf("%d.%d.%d.%d\n", panswerbody[anscursor], panswerbody[anscursor+1], panswerbody[anscursor+2], panswerbody[anscursor+3]);}anscursor += datalength;} } else {printf("not find the domain\n");return 0; } return 0;}