Skip to content

Instantly share code, notes, and snippets.

@mr1337357
Created February 7, 2013 23:40
Show Gist options
  • Save mr1337357/4735274 to your computer and use it in GitHub Desktop.
Save mr1337357/4735274 to your computer and use it in GitHub Desktop.
DNS lookup program simply gcc *.c
#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;
}
#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