DNS Query mit Hilfe von Sockets senden
-
Hi,
ich würde gerne ein Programm schreiben, dass über eine Socketverbindung eineDNS Query an einen DNS Server sendet. Mit Hilfe dieser Query soll entweder ein Full qualified Name in eine IP aufgelöst werden oder eine IP in einen Full Qualified Name. Hab schon nach Beispielen gesucht, aber ich finde nichts gescheites was ich benutzen könnte.
Kennt vielleicht jmd von euch ein paar Beispiele oder gute Links?
Gruß Danny
-
-
Guckst Du hier:
http://support.microsoft.com/kb/831226/de
-
natürlich nur, wenn es nicht unbedingt Sockets sein müssen.....
-
@MeeepMuup
Die DnsQuery-Funktion hab ich schon ausprobiert. Die meldet öfters mal, das eine IP oder ein Name nicht aufgelöst werden kann, obwohl die IP oder der Name ohne Probleme aufgelöst werden kann.
Deshalb will ich ja was mit Sockets machen. Hab jetzt mittlerweile was gefunden, aber damit bekomm ich es nur hin, dass ich den Full Qualified Namen übergebe und die entsprechende IP erhalte.
Was muss ich ändern, damit ich auch IP Adressen übergeben kann und diese in Full Qulaified Names aufgelöst bekomme?
void ngethostbyname(char* dnsServerIP, unsigned char *host) { SOCKET s; s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); //UDP packet for DNS queries RES_RECORD answers[20],auth[20],addit[20]; //the replies from the DNS server sockaddr_in dest; dest.sin_family=AF_INET; dest.sin_port=htons(53); dest.sin_addr.s_addr=inet_addr(dnsServerIP); //dns servers unsigned char buf[65536],*qname,*reader; DNS_HEADER *dns = NULL; QUESTION *qinfo = NULL; //Set the DNS structure to standard queries dns=(DNS_HEADER*)&buf; dns->id = (unsigned short)htons(GetCurrentProcessId()); dns->qr = 0; //This is a query dns->opcode = 0; //This is a standard query dns->aa = 0; //Not Authoritative dns->tc = 0; //This message is not truncated dns->rd = 1; //Recursion Desired dns->ra = 0; //Recursion not available! hey we dont have it (lol) dns->z = 0; dns->ad = 0; dns->cd = 0; dns->rcode = 0; dns->q_count = htons(1); //we have only 1 question dns->ans_count = 0; dns->auth_count = 0; dns->add_count = 0; //point to the query portion qname =(unsigned char*)&buf[sizeof(DNS_HEADER)]; ChangetoDnsNameFormat(qname,host); qinfo =(QUESTION*)&buf[sizeof(DNS_HEADER) + (strlen((const char*)qname) + 1)]; //fill it qinfo->qtype = htons(1); //we are requesting the ipv4 address qinfo->qclass = htons(1); //its internet (lol) printf("\nSending Packet..."); if(sendto(s,(char*)buf,sizeof(DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(QUESTION),0,(sockaddr*)&dest,sizeof(dest))==SOCKET_ERROR) { printf("%d error",WSAGetLastError()); } printf("Sent"); int i=sizeof(dest); printf("\nReceiving answer..."); if(recvfrom (s,(char*)buf,65536,0,(sockaddr*)&dest,&i)==SOCKET_ERROR) { printf("Failed. Error Code : %d",WSAGetLastError()); } printf("Received."); dns=(DNS_HEADER*)buf; //move ahead of the dns header and the query field reader=&buf[sizeof(DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(QUESTION)]; printf("\nThe response contains : "); printf("\n %d Questions.",ntohs(dns->q_count)); printf("\n %d Answers.",ntohs(dns->ans_count)); printf("\n %d Authoritative Servers.",ntohs(dns->auth_count)); printf("\n %d Additional records.\n\n",ntohs(dns->add_count)); //reading answers int stop=0; for(i=0;i<ntohs(dns->ans_count);i++) { answers[i].name=ReadName(reader,buf,stop); reader+=stop; answers[i].resource=(R_DATA*)(reader); reader+=sizeof(R_DATA); if(ntohs(answers[i].resource->type)==1) { answers[i].rdata=new unsigned char[ntohs(answers[i].resource->data_len)]; for(int j=0;j<ntohs(answers[i].resource->data_len);j++) answers[i].rdata[j]=reader[j]; answers[i].rdata[ntohs(answers[i].resource->data_len)]='\0'; reader+=ntohs(answers[i].resource->data_len); } else { answers[i].rdata=ReadName(reader,buf,stop); reader+=stop; } } //read authorities for(i=0;i<ntohs(dns->auth_count);i++) { auth[i].name=ReadName(reader,buf,stop); reader+=stop; auth[i].resource=(R_DATA*)(reader); reader+=sizeof(R_DATA); auth[i].rdata=ReadName(reader,buf,stop); reader+=stop; } //read additional for(i=0;i<ntohs(dns->add_count);i++) { addit[i].name=ReadName(reader,buf,stop); reader+=stop; addit[i].resource=(R_DATA*)(reader); reader+=sizeof(R_DATA); if(ntohs(addit[i].resource->type)==1) { addit[i].rdata=new unsigned char[ntohs(addit[i].resource->data_len)]; for(int j=0;j<ntohs(addit[i].resource->data_len);j++) addit[i].rdata[j]=reader[j]; addit[i].rdata[ntohs(addit[i].resource->data_len)]='\0'; reader+=ntohs(addit[i].resource->data_len); } else { addit[i].rdata=ReadName(reader,buf,stop); reader+=stop; } } //print answers for(i=0;i<ntohs(dns->ans_count);i++) { //printf("\nAnswer : %d",i+1); printf("Name : %s ",answers[i].name); if(ntohs(answers[i].resource->type)==1) { sockaddr_in a; long *p; p=(long*)answers[i].rdata; a.sin_addr.s_addr=(*p); //working without ntohl printf("has IPv4 address : %s",inet_ntoa(a.sin_addr)); } if(ntohs(answers[i].resource->type)==5) printf("has alias name : %s",answers[i].rdata); printf("\n"); } //print authorities for(i=0;i<ntohs(dns->auth_count);i++) { //printf("\nAuthorities : %d",i+1); printf("Name : %s ",auth[i].name); if(ntohs(auth[i].resource->type)==2) printf("has authoritative nameserver : %s",auth[i].rdata); printf("\n"); } //print additional resource records for(i=0;i<ntohs(dns->add_count);i++) { //printf("\nAdditional : %d",i+1); printf("Name : %s ",addit[i].name); if(ntohs(addit[i].resource->type)==1) { sockaddr_in a; long *p; p=(long*)addit[i].rdata; a.sin_addr.s_addr=(*p); //working without ntohl printf("has IPv4 address : %s",inet_ntoa(a.sin_addr)); } printf("\n"); } return; } unsigned char* ReadName(unsigned char* reader,unsigned char* buffer,int &count) { unsigned char *name; name=new unsigned char[256]; name[0]='\0'; unsigned int p=0,jumped=0,offset; count=1; //read the names in 3www6google3com format while(*reader!=0) { if(*reader>=192) { offset = (*reader)*256 + *(reader+1) - 49152; //49152 = 11000000 00000000 ;) reader = buffer + offset - 1; jumped = 1; //we have jumped to another location so counting wont go up! } else name[p++]=*reader; reader=reader+1; if(jumped==0) count++; //if we havent jumped to another location then we can count up } name[p]='\0'; //string complete if(jumped==1) count++; //number of steps we actually moved forward in the packet //now convert 3www6google3com0 to www.google.com for(int i=0;i<(int)strlen((const char*)name);i++) { p=name[i]; for(int j=0;j<(int)p;j++) { name[i]=name[i+1]; i=i+1; } name[i]='.'; } name[i-1]='\0'; //remove the last dot return name; } //this will convert www.google.com to 3www6google3com ;got it :) void ChangetoDnsNameFormat(unsigned char* dns,unsigned char* host) { int lock=0; strcat((char*)host,"."); for(int i=0;i<(int)strlen((char*)host);i++) { if(host[i]=='.') { *dns++=i-lock; for(;lock<i;lock++) { *dns++=host[lock]; } lock++; //or lock=i+1; } } *dns++='\0'; }
Gruß Danny