From 8ee2bac0af0a194d99fb1073b5362b0cd5c07130 Mon Sep 17 00:00:00 2001
From: Joel Grunbaum <joelgrun@gmail.com>
Date: Sun, 18 Oct 2020 11:30:53 +0000
Subject: [PATCH] split dns into own file and printing into own function

---
 Makefile |   12 +
 main.c   |  273 ---------------------------
 dns.h    |   12 +
 dns.c    |  269 ++++++++++++++++++++++++++
 4 files changed, 294 insertions(+), 272 deletions(-)

diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..80b5744
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,12 @@
+CC=gcc
+OBJ=main.o dns.o
+DEPS=dns.h
+CFLAGS=-g
+
+default: all
+
+%.o: %.c $(DEPS)
+	$(CC) $(CFLAGS) -c -o $@ $<
+
+all: $(OBJ)
+	$(CC) $(CFLAGS) $^
diff --git a/dns.c b/dns.c
new file mode 100644
index 0000000..af08c44
--- /dev/null
+++ b/dns.c
@@ -0,0 +1,269 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+//#include <netint/in.h>
+//#include <netdb.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include "dns.h"
+
+// DNS code copied from
+// https://gist.github.com/fffaraz/9d9170b57791c28ccda9255b48315168
+
+/* DNS header struct */
+struct DNS_HEADER
+{
+	 unsigned short id;			//ID number
+	 unsigned char rd :1;		//recursion
+	 unsigned char tc :1;		//truncated message
+	 unsigned char aa :1;		//authoritive answer
+	 unsigned char opcode :4;	//message purpose
+	 unsigned char qr :1;		//query response
+	 unsigned char rcode :4;	//response code
+	 unsigned char cd :1;		//checking disabled
+	 unsigned char ad :1;		//authenticated data
+	 unsigned char z :1;		//reserved for future use
+	 unsigned char ra :1;		//recursion available
+	 unsigned short q_count;	//number of question entries
+	 unsigned short ans_count;	//number of answer entries
+	 unsigned short auth_count; //number of authority entries
+	 unsigned short add_count;  //number of resource entries
+};
+
+/* structured for query structure */
+struct QUESTION
+{
+	 unsigned short qtype;
+	 unsigned short qclass;
+};
+
+/* Query structure */
+struct QUERY
+{
+	 unsigned char* name;
+	 struct QUESTION* ques;
+};
+
+/* Constant sized fields of record structure */
+#pragma pack(push, 1)
+struct R_DATA
+{
+	 unsigned short type;
+	 unsigned short _class;
+	 unsigned int ttl;
+	 unsigned short data_len;
+};
+#pragma pack(pop)
+
+/* Pointers to record components */
+struct RES_RECORD
+{
+	 unsigned char* name;
+	 struct R_DATA* resource;
+	 unsigned char* rdata;
+};
+
+void resolve(char* hostname, char* dns_ip, int query_type, int read)
+{
+	 int s, i, j;
+	 struct sockaddr_in dest, a;
+	 unsigned char buf[65536], *qname, *reader;
+	 struct DNS_HEADER* dns = NULL;
+	 struct QUESTION* qinfo = NULL;
+
+	 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	 dest.sin_family = AF_INET;
+	 dest.sin_port = htons(53);
+	 dest.sin_addr.s_addr = inet_addr(dns_ip);
+
+	 //dns packet header
+	 dns = (struct DNS_HEADER*)&buf;
+	 dns->id = (unsigned short) htons(getpid());
+	 dns->qr = 0;				//make query
+	 dns->opcode = 0;			//standard query
+	 dns->aa = 0;				//not authoritive
+	 dns->tc = 0;				//not trucated
+	 dns->rd = 1;				//want recursion
+	 dns->ra = 0;				//recursion not available
+	 dns->z = 0;
+	 dns->ad = 0;
+	 dns->cd = 0;
+	 dns->rcode = 0;
+	 dns->q_count = htons(1);	//one question
+	 dns->ans_count = 0;
+	 dns->auth_count = 0;
+	 dns->add_count = 0;
+
+	 //dns packet query
+	 qname = (unsigned char*)&buf[sizeof(struct DNS_HEADER)];
+	 change_to_DNS_name_format(qname, (unsigned char*)hostname);
+	 qinfo = (struct QUESTION*)&buf[sizeof(struct DNS_HEADER) + strlen((const char*)qname) + 1];
+	 qinfo->qtype = htons(query_type); //type of query from argument (A,AAAA,MX,CNAME,NS,...)
+	 qinfo->qclass = htons(1); //internet class
+
+	 //send request
+	 // return less than 0 is a fail
+	 sendto(s,(char*)buf, sizeof(struct DNS_HEADER)+strlen((const char*)qname)+1+sizeof(struct QUESTION), 0, (struct sockaddr*)&dest, sizeof(dest));
+
+	 //receive response
+	 //negative return is a fail
+	 i = sizeof(dest);
+	 recvfrom(s, (char*)buf, 65536, 0, (struct sockaddr*)&dest, (socklen_t*)&i);
+
+	 //read response
+	 if (read) {
+		  print_packet(buf);
+	 }
+	 return;
+}
+
+void print_packet(unsigned char* buf)
+{
+	 struct RES_RECORD answers[20], auth[20], addit[20];
+	 struct DNS_HEADER *dns;
+	 struct sockaddr_in a;
+	 char* qname = buf+sizeof(struct DNS_HEADER), *reader;
+	 int stop, i, j;
+	 dns = (struct DNS_HEADER*)buf;
+	 reader = &buf[sizeof(struct DNS_HEADER)+strlen((const char*)qname)+1+sizeof(struct QUESTION)];
+	 printf("Response contains %d Qs, %d ans, %d auth serv, %d add reconds\n", ntohs(dns->q_count), ntohs(dns->ans_count), ntohs(dns->auth_count), ntohs(dns->add_count));
+	 stop = 0;
+	 for (i = 0; i < ntohs(dns->ans_count); i++) {
+		  answers[i].name = read_name(reader, buf, &stop);
+		  reader = reader + stop;
+		  answers[i].resource = (struct R_DATA*)reader;
+		  reader = reader+sizeof(struct R_DATA);
+		  
+		  if (ntohs(answers[i].resource->type) == T_A) { //IPv4 address
+			   answers[i].rdata = (unsigned char*)malloc(ntohs(answers[i].resource->data_len));
+			   for (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 = reader + ntohs(answers[i].resource->data_len);
+		  } else {
+			   answers[i].rdata = read_name(reader, buf, &stop);
+			   reader = reader + stop;
+		  }
+	 }
+	 
+	 //read authorities
+	 for (i = 0; i < ntohs(dns->auth_count); i++) {
+		  auth[i].name = read_name(reader, buf, &stop);
+		  reader += stop;
+		  auth[i].resource = (struct R_DATA*)reader;
+		  reader += sizeof(struct R_DATA);
+		  auth[i].rdata = read_name(reader, buf, &stop);
+		  reader += stop;
+	 }
+	 
+	 //read additional
+	 for (i = 0; i < ntohs(dns->add_count); i++) {
+		  addit[i].name = read_name(reader, buf, &stop);
+		  reader += stop;
+		  addit[i].resource = (struct R_DATA*)reader;
+		  reader += sizeof(struct R_DATA);
+
+		  if (ntohs(addit[i].resource->type) == 1) {
+			   addit[i].rdata = malloc(ntohs(addit[i].resource->data_len));
+			   for (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 = read_name(reader, buf, &stop);
+			   reader += stop;
+		  }
+	 }
+	 
+	 //print answers
+	 printf("ans recs: %d\n", ntohs(dns->ans_count));
+	 for (i = 0; i < ntohs(dns->ans_count); i++) {
+		  printf("name: %s ", answers[i].name);
+		  if (ntohs(answers[i].resource->type) == T_A) { //IPv4
+			   long* p;
+			   p = (long*)answers[i].rdata;
+			   a.sin_addr.s_addr=(*p);
+			   printf("has IPv4 addresss: %s", inet_ntoa(a.sin_addr));
+		  } else if (ntohs(answers[i].resource->type) == T_CNAME) { //CNAME
+			   printf("has alias: %s", answers[i].rdata);
+		  }
+		  putc('\n', stdout);
+	 }
+
+	 //print authorities
+	 printf("Auth recs: %d\n", ntohs(dns->auth_count));
+	 for (i = 0; i < ntohs(dns->auth_count); i++) {
+		  printf("name: %s ", addit[i].name);
+		  if (ntohs(addit[i].resource->type) == 1) {
+			   long* p;
+			   p = (long*)addit[i].rdata;
+			   a.sin_addr.s_addr = *p;
+			   printf("has IPv4 address: %s", inet_ntoa(a.sin_addr));
+		  }
+		  putc('\n', stdout);
+	 }
+}
+
+
+void change_to_DNS_name_format(unsigned char* dns, unsigned char* host)
+{
+	 int lock = 0;
+	 char h[300];
+	 strcpy(h, host);
+	 strcat((char*)h,".");
+
+	 for (int i = 0; i < strlen((char*)h); i++) {
+		  if (h[i] == '.') {
+			   *dns++ = i-lock;
+			   for (;lock<i;lock++) {
+					*dns++ = h[lock];
+			   }
+			   lock++;
+		  }
+	 }
+	 *dns++ = '\0';
+}
+
+char* read_name(unsigned char* reader, unsigned char* buffer, int* count)
+{
+	 unsigned char* name;
+	 unsigned int p=0, jumped=0, offset;
+	 int i, j;
+	 *count = 1;
+	 name = (unsigned char*)malloc(256);
+	 name[0]='\0';
+
+	 while (*reader != 0) {
+		  if (*reader >= 192) {
+			   offset = (*reader)*256+ *(reader+1) - 49152;
+			   reader = buffer+offset-1;
+			   jumped=1;
+		  } else {
+			   name[p++]=*reader;
+		  }
+		  reader = reader+1;
+		  if (jumped == 0) {
+			   *count = *count+1;
+		  }
+	 }
+	 name[p] = '\0';
+	 if (jumped == 1) {
+		  *count = *count + 1;
+	 }
+
+	 //convert from dns format to normal
+	 for (i = 0; i < strlen((const char*)name); i++) {
+		  p = name[i];
+		  for (j = 0; j < p; j++) {
+			   name[i] = name[i+1];
+			   i++;
+		  }
+		  name[i] = '.';
+	 }
+	 name[i-1] = '\0';
+	 return name;
+}
diff --git a/dns.h b/dns.h
new file mode 100644
index 0000000..1443dbf
--- /dev/null
+++ b/dns.h
@@ -0,0 +1,12 @@
+// DNS resource records
+#define T_A 1 // IPv4 address
+#define T_NS // Name Server
+#define T_CNAME 5 // Cannonical name
+#define T_SOA 6 // State of Authority
+#define T_PTR 12 // Domain name pointer
+#define T_MX 15 // Mail exchange
+
+void resolve(char* hostname, char* dns_ip, int query_type, int read);
+void print_packet(unsigned char* buf);
+void change_to_DNS_name_format(unsigned char* dns, unsigned char* host);
+char* read_name(unsigned char* reader, unsigned char* buffer, int* count);
diff --git a/main.c b/main.c
index 3c5961c..1e36b9e 100644
--- a/main.c
+++ b/main.c
@@ -1,278 +1,7 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-//#include <netint/in.h>
-//#include <netdb.h>
-#include <sys/time.h>
-#include <unistd.h>
-
-// DNS code copied from
-// https://gist.github.com/fffaraz/9d9170b57791c28ccda9255b48315168
-
-// DNS resource records
-#define T_A 1 // IPv4 address
-#define T_NS // Name Server
-#define T_CNAME 5 // Cannonical name
-#define T_SOA 6 // State of Authority
-#define T_PTR 12 // Domain name pointer
-#define T_MX 15 // Mail exchange
-
-/* DNS header struct */
-struct DNS_HEADER
-{
-	 unsigned short id;			//ID number
-	 unsigned char rd :1;		//recursion
-	 unsigned char tc :1;		//truncated message
-	 unsigned char aa :1;		//authoritive answer
-	 unsigned char opcode :4;	//message purpose
-	 unsigned char qr :1;		//query response
-	 unsigned char rcode :4;	//response code
-	 unsigned char cd :1;		//checking disabled
-	 unsigned char ad :1;		//authenticated data
-	 unsigned char z :1;		//reserved for future use
-	 unsigned char ra :1;		//recursion available
-	 unsigned short q_count;	//number of question entries
-	 unsigned short ans_count;	//number of answer entries
-	 unsigned short auth_count; //number of authority entries
-	 unsigned short add_count;  //number of resource entries
-};
-
-/* structured for query structure */
-struct QUESTION
-{
-	 unsigned short qtype;
-	 unsigned short qclass;
-};
-
-/* Query structure */
-struct QUERY
-{
-	 unsigned char* name;
-	 struct QUESTION* ques;
-};
-
-/* Constant sized fields of record structure */
-#pragma pack(push, 1)
-struct R_DATA
-{
-	 unsigned short type;
-	 unsigned short _class;
-	 unsigned int ttl;
-	 unsigned short data_len;
-};
-#pragma pack(pop)
-
-/* Pointers to record components */
-struct RES_RECORD
-{
-	 unsigned char* name;
-	 struct R_DATA* resource;
-	 unsigned char* rdata;
-};
-
-void resolve(char* hostname, char* dns_ip, int query_type, int read);
-void change_to_DNS_name_format(unsigned char* dns, unsigned char* host);
-u_char* read_name(unsigned char* reader, unsigned char* buffer, int* count);
+#include "dns.h"
 
 int main(int argc, char** argv)
 {
 	 resolve("google.com", "1.1.1.1", T_A, 1);
 	 return 0;
 }
-
-void resolve(char* hostname, char* dns_ip, int query_type, int read)
-{
-	 int s, i, j;
-	 struct sockaddr_in dest, a;
-	 unsigned char buf[65536], *qname, *reader;
-	 struct DNS_HEADER* dns = NULL;
-	 struct QUESTION* qinfo = NULL;
-
-	 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-	 dest.sin_family = AF_INET;
-	 dest.sin_port = htons(53);
-	 dest.sin_addr.s_addr = inet_addr(dns_ip);
-
-	 //dns packet header
-	 dns = (struct DNS_HEADER*)&buf;
-	 dns->id = (unsigned short) htons(getpid());
-	 dns->qr = 0;				//make query
-	 dns->opcode = 0;			//standard query
-	 dns->aa = 0;				//not authoritive
-	 dns->tc = 0;				//not trucated
-	 dns->rd = 1;				//want recursion
-	 dns->ra = 0;				//recursion not available
-	 dns->z = 0;
-	 dns->ad = 0;
-	 dns->cd = 0;
-	 dns->rcode = 0;
-	 dns->q_count = htons(1);	//one question
-	 dns->ans_count = 0;
-	 dns->auth_count = 0;
-	 dns->add_count = 0;
-
-	 //dns packet query
-	 qname = (unsigned char*)&buf[sizeof(struct DNS_HEADER)];
-	 change_to_DNS_name_format(qname, (unsigned char*)hostname);
-	 qinfo = (struct QUESTION*)&buf[sizeof(struct DNS_HEADER) + strlen((const char*)qname) + 1];
-	 qinfo->qtype = htons(query_type); //type of query from argument (A,AAAA,MX,CNAME,NS,...)
-	 qinfo->qclass = htons(1); //internet class
-
-	 //send request
-	 // return less than 0 is a fail
-	 sendto(s,(char*)buf, sizeof(struct DNS_HEADER)+strlen((const char*)qname)+1+sizeof(struct QUESTION), 0, (struct sockaddr*)&dest, sizeof(dest));
-
-	 //receive response
-	 //negative return is a fail
-	 i = sizeof(dest);
-	 recvfrom(s, (char*)buf, 65536, 0, (struct sockaddr*)&dest, (socklen_t*)&i);
-
-	 //read response
-	 if (read) {
-		  struct RES_RECORD answers[20], auth[20], addit[20];
-		  int stop;
-		  dns = (struct DNS_HEADER*)buf;
-		  reader = &buf[sizeof(struct DNS_HEADER)+strlen((const char*)qname)+1+sizeof(struct QUESTION)];
-		  printf("Response contains %d Qs, %d ans, %d auth serv, %d add reconds\n", ntohs(dns->q_count), ntohs(dns->ans_count), ntohs(dns->auth_count), ntohs(dns->add_count));
-		  stop = 0;
-		  for (i = 0; i < ntohs(dns->ans_count); i++) {
-			   answers[i].name = read_name(reader, buf, &stop);
-			   reader = reader + stop;
-			   answers[i].resource = (struct R_DATA*)reader;
-			   reader = reader+sizeof(struct R_DATA);
-
-			   if (ntohs(answers[i].resource->type) == T_A) { //IPv4 address
-					answers[i].rdata = (unsigned char*)malloc(ntohs(answers[i].resource->data_len));
-					for (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 = reader + ntohs(answers[i].resource->data_len);
-			   } else {
-					answers[i].rdata = read_name(reader, buf, &stop);
-					reader = reader + stop;
-			   }
-		  }
-
-		  //read authorities
-		  for (i = 0; i < ntohs(dns->auth_count); i++) {
-			   auth[i].name = read_name(reader, buf, &stop);
-			   reader += stop;
-			   auth[i].resource = (struct R_DATA*)reader;
-			   reader += sizeof(struct R_DATA);
-			   auth[i].rdata = read_name(reader, buf, &stop);
-			   reader += stop;
-		  }
-
-		  //read additional
-		  for (i = 0; i < ntohs(dns->add_count); i++) {
-			   addit[i].name = read_name(reader, buf, &stop);
-			   reader += stop;
-			   addit[i].resource = (struct R_DATA*)reader;
-			   reader += sizeof(struct R_DATA);
-
-			   if (ntohs(addit[i].resource->type) == 1) {
-					addit[i].rdata = malloc(ntohs(addit[i].resource->data_len));
-					for (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 = read_name(reader, buf, &stop);
-					reader += stop;
-			   }
-		  }
-
-		  //print answers
-		  printf("ans recs: %d\n", ntohs(dns->ans_count));
-		  for (i = 0; i < ntohs(dns->ans_count); i++) {
-			   printf("name: %s ", answers[i].name);
-			   if (ntohs(answers[i].resource->type) == T_A) { //IPv4
-					long* p;
-					p = (long*)answers[i].rdata;
-					a.sin_addr.s_addr=(*p);
-					printf("has IPv4 addresss: %s", inet_ntoa(a.sin_addr));
-			   } else if (ntohs(answers[i].resource->type) == T_CNAME) { //CNAME
-					printf("has alias: %s", answers[i].rdata);
-			   }
-			   putc('\n', stdout);
-		  }
-
-		  //print authorities
-		  printf("Auth recs: %d\n", ntohs(dns->auth_count));
-		  for (i = 0; i < ntohs(dns->auth_count); i++) {
-			   printf("name: %s ", addit[i].name);
-			   if (ntohs(addit[i].resource->type) == 1) {
-					long* p;
-					p = (long*)addit[i].rdata;
-					a.sin_addr.s_addr = *p;
-					printf("has IPv4 address: %s", inet_ntoa(a.sin_addr));
-			   }
-			   putc('\n', stdout);
-		  }
-	 }
-	 return;
-}
-
-
-void change_to_DNS_name_format(unsigned char* dns, unsigned char* host)
-{
-	 int lock = 0;
-	 char h[300];
-	 strcpy(h, host);
-	 strcat((char*)h,".");
-
-	 for (int i = 0; i < strlen((char*)h); i++) {
-		  if (h[i] == '.') {
-			   *dns++ = i-lock;
-			   for (;lock<i;lock++) {
-					*dns++ = h[lock];
-			   }
-			   lock++;
-		  }
-	 }
-	 *dns++ = '\0';
-}
-
-u_char* read_name(unsigned char* reader, unsigned char* buffer, int* count)
-{
-	 unsigned char* name;
-	 unsigned int p=0, jumped=0, offset;
-	 int i, j;
-	 *count = 1;
-	 name = (unsigned char*)malloc(256);
-	 name[0]='\0';
-
-	 while (*reader != 0) {
-		  if (*reader >= 192) {
-			   offset = (*reader)*256+ *(reader+1) - 49152;
-			   reader = buffer+offset-1;
-			   jumped=1;
-		  } else {
-			   name[p++]=*reader;
-		  }
-		  reader = reader+1;
-		  if (jumped == 0) {
-			   *count = *count+1;
-		  }
-	 }
-	 name[p] = '\0';
-	 if (jumped == 1) {
-		  *count = *count + 1;
-	 }
-
-	 //convert from dns format to normal
-	 for (i = 0; i < strlen((const char*)name); i++) {
-		  p = name[i];
-		  for (j = 0; j < p; j++) {
-			   name[i] = name[i+1];
-			   i++;
-		  }
-		  name[i] = '.';
-	 }
-	 name[i-1] = '\0';
-	 return name;
-}

--
Gitblit v1.10.0