summaryrefslogtreecommitdiff
path: root/exploits/7350bindnxt/dnslib.c
diff options
context:
space:
mode:
Diffstat (limited to 'exploits/7350bindnxt/dnslib.c')
-rw-r--r--exploits/7350bindnxt/dnslib.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/exploits/7350bindnxt/dnslib.c b/exploits/7350bindnxt/dnslib.c
new file mode 100644
index 0000000..d1afb13
--- /dev/null
+++ b/exploits/7350bindnxt/dnslib.c
@@ -0,0 +1,149 @@
1#include "dnslib.h"
2#include <netinet/in.h>
3#include <arpa/inet.h>
4
5/* make a full dns query including header. Returns length of packet.
6 */
7int
8makequery (char *name, u_int16_t type, u_int8_t *buffer, u_int16_t id)
9{
10 HEADER *head;
11
12 head = (HEADER *)buffer;
13
14 bzero (head, DNSHDRSIZE);
15 head->id = htons (id);
16 head->qr = 0;
17 head->opcode = 0;
18 head->aa = 0;
19 head->tc = 0;
20 head->rd = 1;
21 head->ra = 0;
22 head->rcode = 0;
23 head->qdcount = htons (1);
24 head->ancount = 0;
25 head->nscount = 0;
26 head->arcount = 0;
27
28 return (makeqbody (name, type, buffer + DNSHDRSIZE) + DNSHDRSIZE);
29}
30
31/* convert a \0-terminated string to a DNS domain name.
32 * www.yahoo.com(.) => \003www\005yahoo\003\com\000
33 */
34int
35formatname (char *in, u_int8_t *out)
36{
37 char *start = in, c = 0;
38 int n = strlen (in);
39
40 in += n - 1;
41 out += n + 1;
42
43 *out-- = 0;
44
45 n = 0;
46 while (in >= start) {
47 c = *in--;
48 if (c == '.') {
49 *out-- = n;
50 n = 0;
51 } else {
52 *out-- = c;
53 n++;
54 }
55 }
56
57 if (n)
58 *out-- = n;
59
60 return (strlen (out + 1) + 1);
61}
62
63/* simple function for making a, ptr and ns resource records
64 * doesn't support more complicated stuph.
65 */
66
67int
68makeRR (char *name, u_int16_t type, u_int16_t class, u_int32_t ttl,
69 char *rdata, char *buf)
70{
71 int n;
72 rrec_body *rec;
73 char *ptr = buf;
74
75 /* name the resource record pertains too */
76 ptr += formatname (name, ptr);
77 rec = (rrec_body *)ptr;
78 rec->type = htons (type);
79 rec->class = htons (class);
80 rec->ttl = htonl (ttl);
81 rec->rdlength = 0;
82 ptr += 10;
83
84 switch (type) {
85 case T_A:
86 *(u_int32_t *)ptr = inet_addr (rdata);
87 rec->rdlength = htons (4);
88 ptr += 4;
89 break;
90 case T_PTR:
91 case T_NS:
92 n = formatname (rdata, ptr);
93 ptr += n;
94 rec->rdlength = htons (n);
95 break;
96 default:
97 /**/
98 }
99 return (ptr - buf);
100}
101
102/* make just the body of a DNS query.
103 */
104int
105makeqbody (char *name, u_int16_t type, u_int8_t *buffer)
106{
107 int len;
108
109 len = formatname (name, buffer);
110 buffer += len;
111 PUTSHORT (type, buffer);
112 PUTSHORT (C_IN, buffer);
113 return (len + 4);
114}
115
116
117/* uncompress compressed dns names. ugh.
118 * works for normal formatted dns names too..
119 * returns the length of the first part of the compressed name (i.e.
120 * before redirection).
121 */
122
123int
124uncompress (u_int8_t *in, char *out, u_int8_t *msg)
125{
126 u_int8_t *start = in, *end = NULL;
127 u_int8_t len;
128 u_int16_t off;
129
130 while ((len = *in++)) {
131 if (len & INDIR_MASK) {
132 if (end == NULL)
133 end = in + 1;
134 off = (len & ~INDIR_MASK);
135 off |= *in++ << 8;
136 off = ntohs (off);
137 in = msg + off;
138 continue;
139 }
140 memcpy (out, in, len);
141 out += len;
142 in += len;
143 *out++ = '.';
144 }
145 if (end == NULL)
146 end = in;
147 *out++ = 0;
148 return (end - start);
149}