使用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;}