Created
February 7, 2013 23:40
-
-
Save mr1337357/4735274 to your computer and use it in GitHub Desktop.
DNS lookup program
simply gcc *.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#include <stdio.h> | |
#include <string.h> | |
#pragma pack(1) | |
typedef unsigned int u32; | |
typedef unsigned short u16; | |
typedef unsigned char u8; | |
char *get_type(u16 type) { | |
switch(type) { | |
case 0x0005: | |
return "cname"; | |
case 0x0001: | |
return "a"; | |
default: | |
return "unknown"; | |
} | |
} | |
struct dns_header { | |
u16 trans_id; | |
u16 flags; | |
u16 questions; | |
u16 ans_rrs; | |
u16 auth_rrs; | |
u16 other_rrs; | |
}; | |
struct dns_ans { | |
u16 name; | |
u16 type; | |
u16 class; | |
u32 ttl; | |
u16 len; | |
u8 data[]; | |
}; | |
int next_dot(char *buff) { | |
int i=0; | |
while(*buff) { | |
if(*buff == '.') { | |
return i; | |
} | |
i++; | |
buff++; | |
} | |
return i; | |
} | |
int prep(char *buff,char *dest) { | |
char *start = buff; | |
int sz = 2; | |
struct dns_header *hdr = (struct dns_header*)buff; | |
hdr->trans_id = ((u16)dest)^0x5555; | |
hdr->flags = htons(0x0100); | |
hdr->questions = htons(1); | |
hdr->ans_rrs = 0; | |
hdr->auth_rrs = 0; | |
hdr->other_rrs = 0; | |
buff+=12; | |
while(sz) { | |
sz=next_dot(dest); | |
*buff++=(u8)sz; | |
memcpy(buff,dest,sz); | |
dest+=sz; | |
buff+=sz; | |
if(!*dest) { | |
break; | |
} | |
dest++; | |
} | |
*buff++=0; | |
*buff++=0; | |
*buff++=1; | |
*buff++=0; | |
*buff++=1; | |
return buff-start; | |
} | |
void print_info(char *pkt) { | |
int i; | |
u8 size; | |
int count; | |
struct dns_header *hdr = (struct dns_header *)pkt; | |
struct dns_ans *ans; | |
char *val; | |
printf("Status: %s Found\n",(ntohs(hdr->flags)&0x0007)?"Not":""); | |
count = ntohs(hdr->ans_rrs); | |
printf("Answers: %d\n",count); | |
pkt+=12; | |
while(*pkt) { | |
pkt+=*pkt+1; | |
} | |
pkt+=5; | |
ans = (struct dns_ans *)pkt; | |
for(i=1;i<=count;i++) { | |
printf(" %d:\n",i); | |
ans->type = ntohs(ans->type); | |
printf(" Type: %s 0x%04x\n",get_type(ans->type),ans->type); | |
ans->class = ntohs(ans->class); | |
printf(" Class: %s 0x%04x\n","unknown", ans->class); | |
ans->ttl = ntohl(ans->ttl); | |
printf(" TTL: %us (%uh%um%us)\n",ans->ttl,ans->ttl/3600,(ans->ttl/60)%60,ans->ttl%60); | |
ans->len = ntohs(ans->len); | |
printf(" Size: %u bytes\n",ans->len); | |
if(ans->type == 0x0005) { | |
val = (char *)ans->data; | |
size = *val; | |
do { | |
*val = '.'; | |
val+=size+1; | |
size = *val; | |
if(size == 0xc0) { | |
size = 0; | |
} | |
} while(size); | |
*val=0; | |
printf(" Value: %s\n",(char *)ans->data+1); | |
} | |
if(ans->type == 0x0001) { | |
printf(" Value: %d.%d.%d.%d\n",ans->data[0],ans->data[1],ans->data[2],ans->data[3]); | |
} | |
pkt+=ans->len+12; | |
ans=(struct dns_ans *)pkt; | |
} | |
} | |
void lookup(char *server,char *dest) { | |
char pktbuf[512]; | |
int len = prep(pktbuf,dest); | |
int sockfd; | |
struct sockaddr_in servaddr,recvaddr; | |
socklen_t size; | |
printf("looking up %s on %s\n",dest,server); | |
sockfd = socket(AF_INET,SOCK_DGRAM,0); | |
if(sockfd < 0) { | |
fprintf(stderr,"Failed to get socket!\n"); | |
return; | |
} | |
servaddr.sin_family = AF_INET; | |
servaddr.sin_addr.s_addr = inet_addr(server); | |
servaddr.sin_port = htons(53); | |
if(servaddr.sin_addr.s_addr == INADDR_NONE) { | |
fprintf(stderr,"Bad server address!\n"); | |
return; | |
} | |
sendto(sockfd,pktbuf,len,0,(struct sockaddr *)&servaddr,sizeof(servaddr)); | |
recvfrom(sockfd,pktbuf,512,0,(struct sockaddr *)&recvaddr,&size); | |
print_info(pktbuf); | |
return; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <unistd.h> | |
#include <getopt.h> | |
extern void lookup(char *server,char *dest); | |
int main(int argc, char **argv) { | |
char c=0; | |
char *server=0; | |
char *dest=0; | |
struct option long_options[] = { | |
{"server",required_argument,0,'s'}, | |
{"target",required_argument,0,'t'}, | |
{0,0,0,0} | |
}; | |
int option_index = 0; | |
while(c!=-1) { | |
c = getopt_long(argc,argv,"s:t:",long_options,&option_index); | |
if(c=='s') { | |
server = optarg; | |
} | |
if(c=='t') { | |
dest = optarg; | |
} | |
} | |
if(server == 0) { | |
fprintf(stderr,"Server not set.\n"); | |
return -1; | |
} | |
if(dest == 0) { | |
if(optind>=argc) { | |
fprintf(stderr,"Destination not set.\n"); | |
return -1; | |
} | |
dest = argv[optind]; | |
} | |
printf("%s\n%s\n",server,dest); | |
lookup(server,dest); | |
printf("\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment