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







  • 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


Anmelden zum Antworten