简单的C语言DNS客户端实现
whitebear
写着玩儿的……
只能查询并解析A记录。
<br></br>#include <stdio.h><br></br>#include <stdlib.h><br></br>#include <string.h><br></br>#include <strings.h></strings.h></string.h></stdlib.h></stdio.h>
#include
#include
#include <netdb.h></netdb.h>
#define DNSSERVER (“8.8.8.8”)
extern int errno;
struct DNSHeader{
short TranscationID;
short Flags;
short Questions;
short AnswerRRs;
short AuthorityRRs;
short AdditionalRRs;
}__attribute__((packed));
struct DNSQuery{
short Type;
short Class;
}__attribute__((packed));
struct DNSAnswerRR{
short Name;
short Type;
short Class;
int TTL;
short Length;
int Address;
}__attribute__((packed));
int main(int argc, const char **argv){
if(argc != 3){
printf(“Usage: %s domainname extname\n”, argv[0]);
return 0;
}
const char *domain = argv[1];
const char *ext = argv[2];
struct servent *dnsserv;
if((dnsserv = getservbyname(“domain”, “udp”)) == NULL){
fprintf(stderr, “getservbyname(): failed to find domain service info.\n”);
return -1;
}
struct sockaddr_in remoteaddr;
remoteaddr.sin_family = PF_INET;
if((remoteaddr.sin_addr.s_addr = inet_addr(DNSSERVER)) == -1){
perror(“inet_addr()”);
return -1;
}
remoteaddr.sin_port = dnsserv->s_port;
struct protoent *proto;
if((proto = getprotobyname(“udp”)) == NULL){
fprintf(stderr, “getprotobyname(): failed to find udp protocol info\n”);
return -1;
}
int sockfd = -1;
if((sockfd = socket(PF_INET, SOCK_DGRAM, proto->p_proto)) TranscationID));
printf(“Flags = 0x%x\n”, ntohs(responseheader->Flags));
printf(“Questions = %d\n”, ntohs(responseheader->Questions));
printf(“AnswerRRs = %d\n”, ntohs(responseheader->AnswerRRs));
printf(“AuthorityRRs = %d\n”, ntohs(responseheader->AuthorityRRs));
printf(“AdditionalRRs = %d\n”, ntohs(responseheader->AdditionalRRs));
char tmp;
char *ptmp = buffer + sizeof(struct DNSHeader);
tmp = *ptmp++;
printf(“domainlen = %d\n”, tmp);
ptmp += tmp;
tmp = *ptmp++;
printf(“extlen = %d\n”, tmp);
ptmp += tmp;
ptmp++;
struct DNSQuery *responsequery = (struct DNSQuery*)ptmp;
printf(“Type = %x\n”, ntohs(responsequery->Type));
printf(“Class = %x\n”, ntohs(responsequery->Class));
ptmp += 4;
for(int i = 0; i AnswerRRs); i++){
printf("********** Record %d **********\n", i + 1);
struct DNSAnswerRR *answer = (struct DNSAnswerRR*)ptmp;
printf(“Name = 0x%x\n”, ntohs(answer->Name));
printf(“Type = 0x%x\n”, ntohs(answer->Type));
printf(“Class = 0x%x\n”, ntohs(answer->Class));
printf(“TTL = %d\n”, ntohl(answer->TTL));
printf(“Length = %d\n”, answer->Length);
struct in_addr addr;
addr.s_addr = answer->Address;
printf(“IP = %s\n”, inet_ntoa(addr));
ptmp += sizeof(struct DNSAnswerRR);
}
return 0;
}