summaryrefslogtreecommitdiffstats
path: root/main.c
blob: ec94e3f3385058b4e50743e56614d5a377d49f1e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#include <sys/socket.h> /* udp(7) */	/* TODO: random XID */
#include <netinet/in.h>
#include <netinet/udp.h>
#include <poll.h> /* poll(2) */
#include <sys/types.h> /* socket(2) */
#include <sys/socket.h>
#include <unistd.h> /* close(2) */
#include <stdio.h> /* perror(3) */
#include <sys/stat.h> /* open(2) */
#include <fcntl.h>
#include <errno.h> /* errno(3) */
#include <arpa/inet.h> /* byteorder(3) */
#include <string.h> /* strlen(3) */
#include "domain2name.c"
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MAXDOMAIN 255
#define QUERYDOMAIN "http://sijanec.eu/link?r=.sijanec.eu."
#define	EXPECTEDA 93.103.235.126
#define HELP "find recursive DNS resolvers on IPv4 networks\n" \
	"%s [-h] [-d domain] [-a ipv4] network1 [network2 [network3 ...]]\n" \
	"	-a Specify the IPv4 of the -d domain to be used instead of getaddrinfo(3).\n" \
	"	-d Specify the domain name to be used in queries that has a single A record.\n" \
	"	-h Show this help and exit.\n" \
	"Networks are specified as domain names or IPv4 addresses followed by a forward slash\n" \
	"and the netmask in decimal (0-32) or dot notation. For example: example.com/32. \n" \
	"When scanning the Internet please make sure that you specify your own domain instead\n" \
	"of the default one (f@sijanec.eu-http://sijanec.eu/link?r=.sijanec.eu). Make sure it\n" \
	"somehow contains your contact information so the network/server administrator when\n" \
	"looking at the logs will be able to contact you.\n"
/* DNS PACKET: HEADER (12 bytes) QUESTION ANSWER AUTHORITY ADDITIONAL

DEFINITIONS: (those appear somewhere in the packet, packet does not start with definitions!)
	LABLEN	 8 bits: first two bits zero, then 6 bits length of label
	POINTER	 8 bits: first two bits one, then 6 bits as offset from first byte of packet
	STRING	a single byte for defining length (0-256 - all eight bits) and then string of chars
	DOMAIN	 i.) one or more LABLEN followed by ASCII label (no dots) end with either LABLEN 0
		or a POINTER that points to some LABLEN somewhere else in the packet		-OR-:
		ii.) a POINTER that points to some LABLEN somewhere else in the packet

HEADER:
	XID	16 bits: random string to be matched in response to prevent cache poisoning
     /	QR	 1 bit : what type is this packet?	0 query	1 response
    |	OPCODE   4 bits: type of query			0 std	1 invrs	2 srvst	3-15 reserved
1 byte	AA	 1 bit : is response authoritative?	0 no	1 yes
    |	TC	 1 bit : was response truncated?	0 no	1 yes
     \	RD       1 bit : does query desire recursion?	0 no	1 yes
     /	RA	 1 bit : does response server recurse?	0 no	1 yes
1 byte	Z	 3 bits: reserved for future		0 only option
     \	RCODE	 4 bits: error condition	0 ok	1 fmter	2 srvfa	3 nxdom	4 N/I	5 forbidden
    	QDCOUNT	16 bits: number of questions
	ANCOUNT 16 bits: number of answers
	NSCOUNT 16 bits: authority section (where to ask for actual response - NS RECORDS)
	ARCOUNT 16 bits: additional section (glue records)
QUESTION:
	QNAME	DOMAIN
	QTYPE	16 bits: 1 A 	2 NS	5 CNAME	6 SOA	10 NULL	12 PTR 13 HINFO	15 MX	16 TXT ...
	QCLASS	16 bits: 1 INTERNET	2 CSNET	(obsolete)	3 CHAOS	4 HESIOD	255 ANY ...
ANSWER:
	NAME	DOMAIN
	TYPE	same as QTYPE
	CLASS	same description as QCLASS, except class 255 ANY is not allowed here
	RDLEN	16 bits: length of RDATA field - this is a number 0-65536, no two zero bits
	RDATA	A: 4 bytes IP address		NS: DOMAIN	CNAME: DOMAIN
		SOA: NAME-ns1 NAME-email 32b-serial 32b-refresh 32b-retry 32b-expire 32b-nxdomainttl
		NULL: any data up to RDLEN 	PTR: DOMAIN	HINFO: STRING-CPU, STRING-OS
		MX: 16 bit preference, NAME-like domain		TXT: one or more STRING


*/
enum qr {
	Query,
	Response
};
enum opcode {
	Query,
	Iquery,
	Stauts
};
enum rcode {
	Success,
	Format_error,
	Servfail,
	Nxdomain,
	Ni,
	Forbidden
};
enum type {
	A = 1,
	Ns,
	Md,
	Mf,
	Cname,
	Soa,
	Mb,
	Mg,
	Mr,
	Null,
	Wks,
	Ptr,
	Hinfo,
	Minfo,
	Mx,
	Txt
}
enum class {
	In = 1,
	Cs,
	Ch,
	He,
	Any = 255
}
struct header {
	uint16_t xid;
	enum qr qr : 1;
	enum opcode opcode : 4;
	unsigned int aa : 1;
	unsigned int tc : 1;
	unsigned int rd : 1;
	unsigned int ra : 1;
	unsigned int z : 3;
	enum rcode rcode : 4;
	uint16_t qdcount;
	uint16_t ancount;
	uint16_t nscount;
	uint16_t arcount;
};
struct question {
	char * qname;
	enum qtype qtype : 16;
	enum qclass qclass : 16;
};
struct answer {
	char * name;
	enum class class : 16;
	uint16_t rdlen;
	char * rdata;
}
int main (int argc, char ** argv) {
	int r = 0;
	while (t) {
		switch (getopt(argc, argv, ":a:d:h")) {
			/* TODO */
			case 'h':
				printf(HELP, argv[0]);
				r = 0;
				goto r;
			case -1:
				d = optarg;
				if (!d || !*d) {
					fprintf(stderr, "specify the domain :: " HELP, argv[0]);
					r = 4;
					goto r;
				}
				if (strlen(d) > MAXDOMAIN) {
					fprintf(stderr, "domain is too long - max "#MAXDOMAIN".\n");
					r = 5;
					goto r;
				}
				t = 0;
				break;
			case '?':
				fprintf(stderr, "unknown option :: " HELP, argv[0]);
				if (db != -1)
					close(db);
				r = 6;
				goto r;
			case ':':
				fprintf(stderr, "missing option argument :: " HELP, argv[0]);
				r = 7;
				goto r;
		}
	}
r:
	if (s != -1)
		if (close(s))
			perror("close(s)");
	}
	return r;
}
int handle () {
	char buf[512]; /* we don't support EDNS0 here, so max DNS packet is 512 bytes */
	recvfrom();
}
int query () {
	sendto();
}
int erase (char * dbfn, int dbfd, char * db) {
	
}