Commit | Line | Data |
---|---|---|
b4588d5c GP |
1 | From 816e84a7c1357b9a60cc2102f4641735cae3a34b Mon Sep 17 00:00:00 2001 |
2 | From: Gerrit Pape <pape@smarden.org> | |
3 | Date: Mon, 12 May 2008 16:51:21 +0000 | |
4 | Subject: [PATCH] Apply fefe's djbdns-1.05-test23 ipv6 patch. | |
5 | ||
6 | What is djbdns and why does it need IPv6? | |
7 | ||
8 | Most people agree that IPv6 will come sooner or later, but obviously you | |
9 | need a DNS infrastructure that supports IPv6. djbdns is a full blown | |
10 | DNS server which outperforms BIND in nearly all respects. However, it | |
11 | does not support IPv6 out of the box. | |
12 | ||
13 | Fortunately, Dan Bernstein (the author of djbdns) has defined a very | |
14 | clean API that made the conversion possible in a few days. | |
15 | ||
16 | What does your diff do? | |
17 | ||
18 | The current version adds support for AAAA records (those are the DNS | |
19 | records that store IPv6 numbers). tinydns-conf will now create | |
20 | /etc/tinydns/add-host6 and /etc/tinydns/add-alias6, and data can now | |
21 | contain records of type "6" and "3". Also, dnsq now understand AAAA | |
22 | records and a new program called "dnsip6" is the IPv6 equivalent of the | |
23 | old dnsip. [new] Automatic internal lookup of some reserved IPv6 | |
24 | addresses (like "::1"). There is also experimental IPv6 transport | |
25 | support. | |
26 | ||
27 | This diff also integrates an ipv6 port of Russ Nelson's anti-Verisign | |
28 | patch. Boycott saboteurs! | |
29 | ||
30 | What does not work yet? | |
31 | ||
32 | tinydns-edit won't accept IPv6 addresses for NS or MX records yet. I | |
33 | haven't even started to look at axfr, but it should just work if you use | |
34 | my IPv6 patches for ucspi-tcp. | |
35 | ||
36 | How do reverse lookups work? | |
37 | ||
38 | The reverse lookup for 2001:658:0:2:2e0:18ff:fe98:b03d looks like this: | |
39 | ||
40 | d.3.0.b.8.9.e.f.f.f.8.1.0.e.2.0.2.0.0.0.0.0.0.0.8.5.6.0.1.0.0.2.ip6.int | |
41 | ||
42 | My patch will put a record like this in your data.cdb, but you still | |
43 | need to get a delegation for your range. For a /64, the delegation | |
44 | would mean leaving half the digits away, as in | |
45 | 2.0.0.0.0.0.0.0.8.5.6.0.1.0.0.2.ip6.int. Talk to your ISP about this! | |
46 | ||
47 | There also is a supposedly new and better scheme for doing DNS for IPv6, | |
48 | and it employs bit strings, DNAME and A6 records, which are really | |
49 | broken by design. Dan has a good write-up about this issue. Rumour has | |
50 | it that the IETF has seen the light and killed this mindblowingly bad | |
51 | proposal. I have not implemented it and probably will not in the | |
52 | future. It involves the domain ip6.arpa, in case you see that | |
53 | somewhere. (News July 2002: The IEFT really has seen the light) | |
54 | --- | |
55 | FILES | 11 +++ | |
56 | Makefile | 160 +++++++++++++++++++++++++++++---- | |
57 | TARGETS | 25 +++++ | |
58 | axfr-get.c | 9 ++ | |
59 | dns.h | 15 +++- | |
60 | dns_ip6.c | 103 +++++++++++++++++++++ | |
61 | dns_ipq6.c | 72 +++++++++++++++ | |
62 | dns_name.c | 22 +++++ | |
63 | dns_nd6.c | 35 +++++++ | |
64 | dns_rcip.c | 25 +++--- | |
65 | dns_resolve.c | 5 +- | |
66 | dns_sortip6.c | 20 ++++ | |
67 | dns_transmit.c | 25 +++--- | |
68 | dnscache.c | 64 ++++++++++---- | |
69 | dnsfilter.c | 5 +- | |
70 | dnsip6.c | 40 ++++++++ | |
71 | dnsip6q.c | 43 +++++++++ | |
72 | dnsname.c | 15 +++- | |
73 | dnsq.c | 13 ++-- | |
74 | dnstrace.c | 50 +++++++---- | |
75 | error.h | 2 +- | |
76 | fmt_xlong.c | 22 +++++ | |
77 | haveip6.h1 | 1 + | |
78 | haveip6.h2 | 1 + | |
79 | haven2i.h1 | 1 + | |
80 | haven2i.h2 | 1 + | |
81 | hier.c | 2 + | |
82 | ip6.h | 28 ++++++ | |
83 | ip6_fmt.c | 60 +++++++++++++ | |
84 | ip6_scan.c | 115 ++++++++++++++++++++++++ | |
85 | log.c | 39 ++++---- | |
86 | okclient.c | 18 +++- | |
87 | printrecord.c | 10 ++ | |
88 | qlog.c | 10 +- | |
89 | query.c | 256 ++++++++++++++++++++++++++++++++++++++++++++++++----- | |
90 | query.h | 7 +- | |
91 | roots.c | 17 ++-- | |
92 | scan_xlong.c | 23 +++++ | |
93 | server.c | 100 +++++++++++++++++---- | |
94 | sockaddr_in6.h1 | 21 +++++ | |
95 | sockaddr_in6.h2 | 4 + | |
96 | socket.h | 18 ++++- | |
97 | socket_accept6.c | 43 +++++++++ | |
98 | socket_bind.c | 2 +- | |
99 | socket_bind6.c | 43 +++++++++ | |
100 | socket_connect6.c | 39 ++++++++ | |
101 | socket_getifidx.c | 13 +++ | |
102 | socket_noipv6.c | 7 ++ | |
103 | socket_recv6.c | 42 +++++++++ | |
104 | socket_send6.c | 39 ++++++++ | |
105 | socket_tcp6.c | 44 +++++++++ | |
106 | socket_udp6.c | 43 +++++++++ | |
107 | tdlookup.c | 54 ++++++++--- | |
108 | tinydns-conf.c | 12 +++ | |
109 | tinydns-data.c | 30 ++++++ | |
110 | tinydns-edit.c | 35 +++++++- | |
111 | tryip6.c | 8 ++ | |
112 | tryn2i.c | 8 ++ | |
113 | trysa6.c | 8 ++ | |
114 | 59 files changed, 1786 insertions(+), 197 deletions(-) | |
115 | create mode 100644 dns_ip6.c | |
116 | create mode 100644 dns_ipq6.c | |
117 | create mode 100644 dns_nd6.c | |
118 | create mode 100644 dns_sortip6.c | |
119 | create mode 100644 dnsip6.c | |
120 | create mode 100644 dnsip6q.c | |
121 | create mode 100644 fmt_xlong.c | |
122 | create mode 100644 haveip6.h1 | |
123 | create mode 100644 haveip6.h2 | |
124 | create mode 100644 haven2i.h1 | |
125 | create mode 100644 haven2i.h2 | |
126 | create mode 100644 ip6.h | |
127 | create mode 100644 ip6_fmt.c | |
128 | create mode 100644 ip6_scan.c | |
129 | create mode 100644 scan_xlong.c | |
130 | create mode 100644 sockaddr_in6.h1 | |
131 | create mode 100644 sockaddr_in6.h2 | |
132 | create mode 100644 socket_accept6.c | |
133 | create mode 100644 socket_bind6.c | |
134 | create mode 100644 socket_connect6.c | |
135 | create mode 100644 socket_getifidx.c | |
136 | create mode 100644 socket_noipv6.c | |
137 | create mode 100644 socket_recv6.c | |
138 | create mode 100644 socket_send6.c | |
139 | create mode 100644 socket_tcp6.c | |
140 | create mode 100644 socket_udp6.c | |
141 | create mode 100644 tryip6.c | |
142 | create mode 100644 tryn2i.c | |
143 | create mode 100644 trysa6.c | |
144 | ||
145 | diff --git a/FILES b/FILES | |
146 | index 7adf6d4..27a4e26 100644 | |
147 | --- a/FILES | |
148 | +++ b/FILES | |
149 | @@ -135,6 +135,7 @@ error_str.c | |
150 | exit.h | |
151 | fmt.h | |
152 | fmt_ulong.c | |
153 | +fmt_xlong.c | |
154 | gen_alloc.h | |
155 | gen_allocdefs.h | |
156 | getln.c | |
157 | @@ -151,6 +152,9 @@ iopause.h2 | |
158 | ip4.h | |
159 | ip4_fmt.c | |
160 | ip4_scan.c | |
161 | +ip6.h | |
162 | +ip6_fmt.c | |
163 | +ip6_scan.c | |
164 | ndelay.h | |
165 | ndelay_off.c | |
166 | ndelay_on.c | |
167 | @@ -164,6 +168,7 @@ prot.h | |
168 | readclose.c | |
169 | readclose.h | |
170 | scan.h | |
171 | +scan_0x.c | |
172 | scan_ulong.c | |
173 | seek.h | |
174 | seek_set.c | |
175 | @@ -241,3 +246,9 @@ uint64.h2 | |
176 | warn-shsgr | |
177 | buffer_read.c | |
178 | buffer_write.c | |
179 | +dns_nd6.c | |
180 | +socket_udp6.c | |
181 | +socket_getifidx.c | |
182 | +tryn2i.c | |
183 | +haven2i.h1 | |
184 | +haven2i.h2 | |
185 | diff --git a/Makefile b/Makefile | |
186 | index 1429643..44bd989 100644 | |
187 | --- a/Makefile | |
188 | +++ b/Makefile | |
189 | @@ -120,12 +120,14 @@ makelib byte_chr.o byte_copy.o byte_cr.o byte_diff.o byte_zero.o \ | |
190 | case_diffb.o case_diffs.o case_lowerb.o fmt_ulong.o ip4_fmt.o \ | |
191 | ip4_scan.o scan_ulong.o str_chr.o str_diff.o str_len.o str_rchr.o \ | |
192 | str_start.o uint16_pack.o uint16_unpack.o uint32_pack.o \ | |
193 | -uint32_unpack.o | |
194 | +uint32_unpack.o ip6_fmt.o ip6_scan.o fmt_xlong.o \ | |
195 | +scan_xlong.o | |
196 | ./makelib byte.a byte_chr.o byte_copy.o byte_cr.o \ | |
197 | byte_diff.o byte_zero.o case_diffb.o case_diffs.o \ | |
198 | case_lowerb.o fmt_ulong.o ip4_fmt.o ip4_scan.o scan_ulong.o \ | |
199 | str_chr.o str_diff.o str_len.o str_rchr.o str_start.o \ | |
200 | - uint16_pack.o uint16_unpack.o uint32_pack.o uint32_unpack.o | |
201 | + uint16_pack.o uint16_unpack.o uint32_pack.o uint32_unpack.o \ | |
202 | + ip6_fmt.o ip6_scan.o fmt_xlong.o scan_xlong.o | |
203 | ||
204 | byte_chr.o: \ | |
205 | compile byte_chr.c byte.h | |
206 | @@ -228,11 +230,13 @@ choose compile trydrent.c direntry.h1 direntry.h2 | |
207 | dns.a: \ | |
208 | makelib dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o dns_ipq.o dns_mx.o \ | |
209 | dns_name.o dns_nd.o dns_packet.o dns_random.o dns_rcip.o dns_rcrw.o \ | |
210 | -dns_resolve.o dns_sortip.o dns_transmit.o dns_txt.o | |
211 | +dns_resolve.o dns_sortip.o dns_transmit.o dns_txt.o dns_ip6.o \ | |
212 | +dns_sortip6.o dns_nd6.o dns_ipq6.o | |
213 | ./makelib dns.a dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o \ | |
214 | dns_ipq.o dns_mx.o dns_name.o dns_nd.o dns_packet.o \ | |
215 | dns_random.o dns_rcip.o dns_rcrw.o dns_resolve.o \ | |
216 | - dns_sortip.o dns_transmit.o dns_txt.o | |
217 | + dns_sortip.o dns_transmit.o dns_txt.o dns_ip6.o dns_sortip6.o \ | |
218 | + dns_nd6.o dns_ipq6.o | |
219 | ||
220 | dns_dfd.o: \ | |
221 | compile dns_dfd.c error.h alloc.h byte.h dns.h stralloc.h gen_alloc.h \ | |
222 | @@ -254,11 +258,21 @@ compile dns_ip.c stralloc.h gen_alloc.h uint16.h byte.h dns.h \ | |
223 | stralloc.h iopause.h taia.h tai.h uint64.h taia.h | |
224 | ./compile dns_ip.c | |
225 | ||
226 | +dns_ip6.o: \ | |
227 | +compile dns_ip6.c stralloc.h gen_alloc.h uint16.h byte.h dns.h \ | |
228 | +stralloc.h iopause.h taia.h tai.h uint64.h taia.h | |
229 | + ./compile dns_ip6.c | |
230 | + | |
231 | dns_ipq.o: \ | |
232 | compile dns_ipq.c stralloc.h gen_alloc.h case.h byte.h str.h dns.h \ | |
233 | stralloc.h iopause.h taia.h tai.h uint64.h taia.h | |
234 | ./compile dns_ipq.c | |
235 | ||
236 | +dns_ipq6.o: \ | |
237 | +compile dns_ipq6.c stralloc.h gen_alloc.h case.h byte.h str.h dns.h \ | |
238 | +stralloc.h iopause.h taia.h tai.h uint64.h taia.h | |
239 | + ./compile dns_ipq6.c | |
240 | + | |
241 | dns_mx.o: \ | |
242 | compile dns_mx.c stralloc.h gen_alloc.h byte.h uint16.h dns.h \ | |
243 | stralloc.h iopause.h taia.h tai.h uint64.h taia.h | |
244 | @@ -274,6 +288,11 @@ compile dns_nd.c byte.h fmt.h dns.h stralloc.h gen_alloc.h iopause.h \ | |
245 | taia.h tai.h uint64.h taia.h | |
246 | ./compile dns_nd.c | |
247 | ||
248 | +dns_nd6.o: \ | |
249 | +compile dns_nd6.c byte.h fmt.h dns.h stralloc.h gen_alloc.h iopause.h \ | |
250 | +taia.h tai.h uint64.h taia.h | |
251 | + ./compile dns_nd6.c | |
252 | + | |
253 | dns_packet.o: \ | |
254 | compile dns_packet.c error.h dns.h stralloc.h gen_alloc.h iopause.h \ | |
255 | taia.h tai.h uint64.h taia.h | |
256 | @@ -306,6 +325,11 @@ compile dns_sortip.c byte.h dns.h stralloc.h gen_alloc.h iopause.h \ | |
257 | taia.h tai.h uint64.h taia.h | |
258 | ./compile dns_sortip.c | |
259 | ||
260 | +dns_sortip6.o: \ | |
261 | +compile dns_sortip6.c byte.h dns.h stralloc.h gen_alloc.h iopause.h \ | |
262 | +taia.h tai.h uint64.h taia.h | |
263 | + ./compile dns_sortip6.c | |
264 | + | |
265 | dns_transmit.o: \ | |
266 | compile dns_transmit.c socket.h uint16.h alloc.h error.h byte.h \ | |
267 | uint16.h dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h uint64.h \ | |
268 | @@ -369,6 +393,17 @@ compile dnsip.c buffer.h exit.h strerr.h ip4.h dns.h stralloc.h \ | |
269 | gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h | |
270 | ./compile dnsip.c | |
271 | ||
272 | +dnsip6: \ | |
273 | +load dnsip6.o iopause.o dns.a env.a libtai.a alloc.a buffer.a unix.a \ | |
274 | +byte.a socket.lib | |
275 | + ./load dnsip6 iopause.o dns.a env.a libtai.a alloc.a \ | |
276 | + buffer.a unix.a byte.a `cat socket.lib` | |
277 | + | |
278 | +dnsip6.o: \ | |
279 | +compile dnsip6.c buffer.h exit.h strerr.h ip6.h dns.h stralloc.h \ | |
280 | +gen_alloc.h iopause.h taia.h tai.h uint64.h | |
281 | + ./compile dnsip6.c | |
282 | + | |
283 | dnsipq: \ | |
284 | load dnsipq.o iopause.o dns.a env.a libtai.a alloc.a buffer.a unix.a \ | |
285 | byte.a socket.lib | |
286 | @@ -380,6 +415,17 @@ compile dnsipq.c buffer.h exit.h strerr.h ip4.h dns.h stralloc.h \ | |
287 | gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h | |
288 | ./compile dnsipq.c | |
289 | ||
290 | +dnsip6q: \ | |
291 | +load dnsip6q.o iopause.o dns.a env.a libtai.a alloc.a buffer.a unix.a \ | |
292 | +byte.a socket.lib | |
293 | + ./load dnsip6q iopause.o dns.a env.a libtai.a alloc.a \ | |
294 | + buffer.a unix.a byte.a `cat socket.lib` | |
295 | + | |
296 | +dnsip6q.o: \ | |
297 | +compile dnsip6q.c buffer.h exit.h strerr.h ip4.h dns.h stralloc.h \ | |
298 | +gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h | |
299 | + ./compile dnsip6q.c | |
300 | + | |
301 | dnsmx: \ | |
302 | load dnsmx.o iopause.o dns.a env.a libtai.a alloc.a buffer.a unix.a \ | |
303 | byte.a socket.lib | |
304 | @@ -399,7 +445,7 @@ byte.a socket.lib | |
305 | ||
306 | dnsname.o: \ | |
307 | compile dnsname.c buffer.h exit.h strerr.h ip4.h dns.h stralloc.h \ | |
308 | -gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h | |
309 | +gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h ip6.h | |
310 | ./compile dnsname.c | |
311 | ||
312 | dnsq: \ | |
313 | @@ -484,6 +530,10 @@ fmt_ulong.o: \ | |
314 | compile fmt_ulong.c fmt.h | |
315 | ./compile fmt_ulong.c | |
316 | ||
317 | +fmt_xlong.o: \ | |
318 | +compile fmt_xlong.c scan.h | |
319 | + ./compile fmt_xlong.c | |
320 | + | |
321 | generic-conf.o: \ | |
322 | compile generic-conf.c strerr.h buffer.h open.h generic-conf.h \ | |
323 | buffer.h | |
324 | @@ -546,10 +596,18 @@ ip4_fmt.o: \ | |
325 | compile ip4_fmt.c fmt.h ip4.h | |
326 | ./compile ip4_fmt.c | |
327 | ||
328 | +ip6_fmt.o: \ | |
329 | +compile ip6_fmt.c fmt.h ip6.h | |
330 | + ./compile ip6_fmt.c | |
331 | + | |
332 | ip4_scan.o: \ | |
333 | compile ip4_scan.c scan.h ip4.h | |
334 | ./compile ip4_scan.c | |
335 | ||
336 | +ip6_scan.o: \ | |
337 | +compile ip6_scan.c scan.h ip6.h | |
338 | + ./compile ip6_scan.c | |
339 | + | |
340 | it: \ | |
341 | prog install instcheck | |
342 | ||
343 | @@ -626,9 +684,9 @@ iopause.h taia.h tai.h uint64.h taia.h uint16.h parsetype.h | |
344 | ./compile parsetype.c | |
345 | ||
346 | pickdns: \ | |
347 | -load pickdns.o server.o response.o droproot.o qlog.o prot.o dns.a \ | |
348 | +load pickdns.o server.o iopause.o response.o droproot.o qlog.o prot.o dns.a \ | |
349 | env.a libtai.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib | |
350 | - ./load pickdns server.o response.o droproot.o qlog.o \ | |
351 | + ./load pickdns server.o iopause.o response.o droproot.o qlog.o \ | |
352 | prot.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \ | |
353 | byte.a `cat socket.lib` | |
354 | ||
355 | @@ -677,7 +735,7 @@ dnscache-conf dnscache walldns-conf walldns rbldns-conf rbldns \ | |
356 | rbldns-data pickdns-conf pickdns pickdns-data tinydns-conf tinydns \ | |
357 | tinydns-data tinydns-get tinydns-edit axfr-get axfrdns-conf axfrdns \ | |
358 | dnsip dnsipq dnsname dnstxt dnsmx dnsfilter random-ip dnsqr dnsq \ | |
359 | -dnstrace dnstracesort cachetest utime rts | |
360 | +dnstrace dnstracesort cachetest utime rts dnsip6 dnsip6q | |
361 | ||
362 | prot.o: \ | |
363 | compile prot.c hasshsgr.h prot.h | |
364 | @@ -704,9 +762,9 @@ gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h | |
365 | ./compile random-ip.c | |
366 | ||
367 | rbldns: \ | |
368 | -load rbldns.o server.o response.o dd.o droproot.o qlog.o prot.o dns.a \ | |
369 | +load rbldns.o server.o iopause.o response.o dd.o droproot.o qlog.o prot.o dns.a \ | |
370 | env.a libtai.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib | |
371 | - ./load rbldns server.o response.o dd.o droproot.o qlog.o \ | |
372 | + ./load rbldns server.o iopause.o response.o dd.o droproot.o qlog.o \ | |
373 | prot.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \ | |
374 | byte.a `cat socket.lib` | |
375 | ||
376 | @@ -762,6 +820,10 @@ scan_ulong.o: \ | |
377 | compile scan_ulong.c scan.h | |
378 | ./compile scan_ulong.c | |
379 | ||
380 | +scan_xlong.o: \ | |
381 | +compile scan_xlong.c scan.h | |
382 | + ./compile scan_xlong.c | |
383 | + | |
384 | seek_set.o: \ | |
385 | compile seek_set.c seek.h | |
386 | ./compile seek_set.c | |
387 | @@ -774,7 +836,7 @@ server.o: \ | |
388 | compile server.c byte.h case.h env.h buffer.h strerr.h ip4.h uint16.h \ | |
389 | ndelay.h socket.h uint16.h droproot.h qlog.h uint16.h response.h \ | |
390 | uint32.h dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h uint64.h \ | |
391 | -taia.h | |
392 | +taia.h iopause.h alloc.h str.h | |
393 | ./compile server.c | |
394 | ||
395 | setup: \ | |
396 | @@ -796,14 +858,26 @@ socket_accept.o: \ | |
397 | compile socket_accept.c byte.h socket.h uint16.h | |
398 | ./compile socket_accept.c | |
399 | ||
400 | +socket_accept6.o: \ | |
401 | +compile socket_accept6.c byte.h socket.h uint16.h | |
402 | + ./compile socket_accept6.c | |
403 | + | |
404 | socket_bind.o: \ | |
405 | compile socket_bind.c byte.h socket.h uint16.h | |
406 | ./compile socket_bind.c | |
407 | ||
408 | +socket_bind6.o: \ | |
409 | +compile socket_bind6.c sockaddr_in6.h haveip6.h byte.h socket.h uint16.h uint32.h ip6.h error.h | |
410 | + ./compile socket_bind6.c | |
411 | + | |
412 | socket_conn.o: \ | |
413 | compile socket_conn.c byte.h socket.h uint16.h | |
414 | ./compile socket_conn.c | |
415 | ||
416 | +socket_connect6.o: \ | |
417 | +compile socket_connect6.c byte.h socket.h uint16.h uint32.h | |
418 | + ./compile socket_connect6.c | |
419 | + | |
420 | socket_listen.o: \ | |
421 | compile socket_listen.c socket.h uint16.h | |
422 | ./compile socket_listen.c | |
423 | @@ -812,18 +886,47 @@ socket_recv.o: \ | |
424 | compile socket_recv.c byte.h socket.h uint16.h | |
425 | ./compile socket_recv.c | |
426 | ||
427 | +socket_recv6.o: \ | |
428 | +compile socket_recv6.c sockaddr_in6.h haveip6.h byte.h socket.h uint16.h uint32.h ip6.h error.h | |
429 | + ./compile socket_recv6.c | |
430 | + | |
431 | socket_send.o: \ | |
432 | compile socket_send.c byte.h socket.h uint16.h | |
433 | ./compile socket_send.c | |
434 | ||
435 | +socket_send6.o: \ | |
436 | +compile socket_send6.c byte.h socket.h uint16.h uint32.h ip6.h haveip6.h error.h | |
437 | + ./compile socket_send6.c | |
438 | + | |
439 | socket_tcp.o: \ | |
440 | compile socket_tcp.c ndelay.h socket.h uint16.h | |
441 | ./compile socket_tcp.c | |
442 | ||
443 | +socket_tcp6.o: \ | |
444 | +compile socket_tcp6.c ndelay.h socket.h uint16.h uint32.h haveip6.h | |
445 | + ./compile socket_tcp6.c | |
446 | + | |
447 | socket_udp.o: \ | |
448 | compile socket_udp.c ndelay.h socket.h uint16.h | |
449 | ./compile socket_udp.c | |
450 | ||
451 | +socket_udp6.o: \ | |
452 | +compile socket_udp6.c ndelay.h socket.h uint16.h uint32.h haveip6.h | |
453 | + ./compile socket_udp6.c | |
454 | + | |
455 | +socket_noipv6.o: \ | |
456 | +compile socket_noipv6.c haveip6.h | |
457 | + ./compile socket_noipv6.c | |
458 | + | |
459 | +socket_getifidx.o: \ | |
460 | +compile socket_getifidx.c socket.h uint16.h uint32.h haven2i.h | |
461 | + ./compile socket_getifidx.c | |
462 | + | |
463 | +haven2i.h: \ | |
464 | +tryn2i.c choose compile load socket.lib haven2i.h1 haven2i.h2 | |
465 | + cp /dev/null haven2i.h | |
466 | + ./choose cL tryn2i haven2i.h1 haven2i.h2 socket > haven2i.h | |
467 | + | |
468 | str_chr.o: \ | |
469 | compile str_chr.c str.h | |
470 | ./compile str_chr.c | |
471 | @@ -965,7 +1068,7 @@ compile taia_uint.c taia.h tai.h uint64.h | |
472 | tdlookup.o: \ | |
473 | compile tdlookup.c uint16.h open.h tai.h uint64.h cdb.h uint32.h \ | |
474 | byte.h case.h dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h \ | |
475 | -taia.h seek.h response.h uint32.h | |
476 | +taia.h seek.h response.h uint32.h ip6.h | |
477 | ./compile tdlookup.c | |
478 | ||
479 | timeoutread.o: \ | |
480 | @@ -979,10 +1082,10 @@ timeoutwrite.h | |
481 | ./compile timeoutwrite.c | |
482 | ||
483 | tinydns: \ | |
484 | -load tinydns.o server.o droproot.o tdlookup.o response.o qlog.o \ | |
485 | +load tinydns.o server.o iopause.o droproot.o tdlookup.o response.o qlog.o \ | |
486 | prot.o dns.a libtai.a env.a cdb.a alloc.a buffer.a unix.a byte.a \ | |
487 | socket.lib | |
488 | - ./load tinydns server.o droproot.o tdlookup.o response.o \ | |
489 | + ./load tinydns server.o iopause.o droproot.o tdlookup.o response.o \ | |
490 | qlog.o prot.o dns.a libtai.a env.a cdb.a alloc.a buffer.a \ | |
491 | unix.a byte.a `cat socket.lib` | |
492 | ||
493 | @@ -1005,7 +1108,7 @@ tinydns-data.o: \ | |
494 | compile tinydns-data.c uint16.h uint32.h str.h byte.h fmt.h ip4.h \ | |
495 | exit.h case.h scan.h buffer.h strerr.h getln.h buffer.h stralloc.h \ | |
496 | gen_alloc.h cdb_make.h buffer.h uint32.h stralloc.h open.h dns.h \ | |
497 | -stralloc.h iopause.h taia.h tai.h uint64.h taia.h | |
498 | +stralloc.h iopause.h taia.h tai.h uint64.h taia.h ip6.h | |
499 | ./compile tinydns-data.c | |
500 | ||
501 | tinydns-edit: \ | |
502 | @@ -1068,12 +1171,18 @@ unix.a: \ | |
503 | makelib buffer_read.o buffer_write.o error.o error_str.o ndelay_off.o \ | |
504 | ndelay_on.o open_read.o open_trunc.o openreadclose.o readclose.o \ | |
505 | seek_set.o socket_accept.o socket_bind.o socket_conn.o \ | |
506 | -socket_listen.o socket_recv.o socket_send.o socket_tcp.o socket_udp.o | |
507 | +socket_listen.o socket_recv.o socket_send.o socket_tcp.o socket_udp.o \ | |
508 | +socket_udp6.o socket_getifidx.o socket_recv6.o socket_send6.o \ | |
509 | +socket_bind6.o socket_noipv6.o socket_tcp6.o socket_connect6.o \ | |
510 | +socket_accept6.o | |
511 | ./makelib unix.a buffer_read.o buffer_write.o error.o \ | |
512 | error_str.o ndelay_off.o ndelay_on.o open_read.o \ | |
513 | open_trunc.o openreadclose.o readclose.o seek_set.o \ | |
514 | socket_accept.o socket_bind.o socket_conn.o socket_listen.o \ | |
515 | - socket_recv.o socket_send.o socket_tcp.o socket_udp.o | |
516 | + socket_recv.o socket_send.o socket_tcp.o socket_udp.o \ | |
517 | + socket_udp6.o socket_getifidx.o socket_recv6.o socket_send6.o \ | |
518 | + socket_bind6.o socket_noipv6.o socket_tcp6.o socket_connect6.o \ | |
519 | + socket_accept6.o | |
520 | ||
521 | utime: \ | |
522 | load utime.o byte.a | |
523 | @@ -1084,10 +1193,10 @@ compile utime.c scan.h exit.h | |
524 | ./compile utime.c | |
525 | ||
526 | walldns: \ | |
527 | -load walldns.o server.o response.o droproot.o qlog.o prot.o dd.o \ | |
528 | +load walldns.o server.o iopause.o response.o droproot.o qlog.o prot.o dd.o \ | |
529 | dns.a env.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib | |
530 | - ./load walldns server.o response.o droproot.o qlog.o \ | |
531 | - prot.o dd.o dns.a env.a cdb.a alloc.a buffer.a unix.a \ | |
532 | + ./load walldns server.o iopause.o response.o droproot.o qlog.o \ | |
533 | + prot.o dd.o dns.a libtai.a env.a cdb.a alloc.a buffer.a unix.a \ | |
534 | byte.a `cat socket.lib` | |
535 | ||
536 | walldns-conf: \ | |
537 | @@ -1104,3 +1213,14 @@ walldns.o: \ | |
538 | compile walldns.c byte.h dns.h stralloc.h gen_alloc.h iopause.h \ | |
539 | taia.h tai.h uint64.h taia.h dd.h response.h uint32.h | |
540 | ./compile walldns.c | |
541 | + | |
542 | +haveip6.h: \ | |
543 | +tryip6.c choose compile haveip6.h1 haveip6.h2 | |
544 | + ./choose c tryip6 haveip6.h1 haveip6.h2 > haveip6.h | |
545 | + | |
546 | +sockaddr_in6.h: \ | |
547 | +trysa6.c choose compile sockaddr_in6.h1 sockaddr_in6.h2 haveip6.h | |
548 | + ./choose c trysa6 sockaddr_in6.h1 sockaddr_in6.h2 > sockaddr_in6.h | |
549 | + | |
550 | +clean: | |
551 | + rm -f `cat TARGETS` | |
552 | diff --git a/TARGETS b/TARGETS | |
553 | index 2490b1a..afc4c49 100644 | |
554 | --- a/TARGETS | |
555 | +++ b/TARGETS | |
556 | @@ -102,6 +102,7 @@ dns_domain.o | |
557 | dns_dtda.o | |
558 | dns_ip.o | |
559 | dns_ipq.o | |
560 | +dns_ipq6.o | |
561 | dns_mx.o | |
562 | dns_name.o | |
563 | dns_nd.o | |
564 | @@ -180,6 +181,8 @@ dnsip.o | |
565 | dnsip | |
566 | dnsipq.o | |
567 | dnsipq | |
568 | +dnsip6q.o | |
569 | +dnsip6q | |
570 | dnsname.o | |
571 | dnsname | |
572 | dnstxt.o | |
573 | @@ -214,3 +217,25 @@ instcheck | |
574 | it | |
575 | setup | |
576 | check | |
577 | +scan_0x.o | |
578 | +fmt_xlong.o | |
579 | +ip6_scan.o | |
580 | +ip6_fmt.o | |
581 | +dnsip6.o | |
582 | +dns_ip6.o | |
583 | +dns_sortip6.o | |
584 | +dnsip6 | |
585 | +dns_nd6.o | |
586 | +socket_udp6.o | |
587 | +socket_getifidx.o | |
588 | +socket_bind6.o | |
589 | +socket_noipv6.o | |
590 | +socket_recv6.o | |
591 | +socket_send6.o | |
592 | +haveip6.h | |
593 | +haven2i.h | |
594 | +sockaddr_in6.h | |
595 | +scan_xlong.o | |
596 | +socket_accept6.o | |
597 | +socket_connect6.o | |
598 | +socket_tcp6.o | |
599 | diff --git a/axfr-get.c b/axfr-get.c | |
600 | index 75db627..f6bf5bd 100644 | |
601 | --- a/axfr-get.c | |
602 | +++ b/axfr-get.c | |
603 | @@ -13,6 +13,7 @@ | |
604 | #include "byte.h" | |
605 | #include "str.h" | |
606 | #include "ip4.h" | |
607 | +#include "ip6.h" | |
608 | #include "timeoutread.h" | |
609 | #include "timeoutwrite.h" | |
610 | #include "dns.h" | |
611 | @@ -217,6 +218,14 @@ unsigned int doit(char *buf,unsigned int len,unsigned int pos) | |
612 | x_copy(buf,len,pos,data,4); | |
613 | if (!stralloc_catb(&line,ipstr,ip4_fmt(ipstr,data))) return 0; | |
614 | } | |
615 | + else if (byte_equal(data,2,DNS_T_AAAA)) { | |
616 | + char ipstr[IP6_FMT]; | |
617 | + if (!stralloc_copys(&line,"3")) return 0; | |
618 | + if (!dns_domain_todot_cat(&line,d1)) return 0; | |
619 | + if (!stralloc_cats(&line,":")) return 0; | |
620 | + x_copy(buf,len,pos,data,16); | |
621 | + if (!stralloc_catb(&line,ipstr,ip6_fmt_flat(ipstr,data))) return 0; | |
622 | + } | |
623 | else { | |
624 | unsigned char ch; | |
625 | unsigned char ch2; | |
626 | diff --git a/dns.h b/dns.h | |
627 | index 2f899ef..5398e2b 100644 | |
628 | --- a/dns.h | |
629 | +++ b/dns.h | |
630 | @@ -35,7 +35,8 @@ struct dns_transmit { | |
631 | struct taia deadline; | |
632 | unsigned int pos; | |
633 | const char *servers; | |
634 | - char localip[4]; | |
635 | + char localip[16]; | |
636 | + unsigned int scope_id; | |
637 | char qtype[2]; | |
638 | } ; | |
639 | ||
640 | @@ -43,6 +44,7 @@ extern void dns_random_init(const char *); | |
641 | extern unsigned int dns_random(unsigned int); | |
642 | ||
643 | extern void dns_sortip(char *,unsigned int); | |
644 | +extern void dns_sortip6(char *,unsigned int); | |
645 | ||
646 | extern void dns_domain_free(char **); | |
647 | extern int dns_domain_copy(char **,const char *); | |
648 | @@ -68,10 +70,13 @@ extern struct dns_transmit dns_resolve_tx; | |
649 | ||
650 | extern int dns_ip4_packet(stralloc *,const char *,unsigned int); | |
651 | extern int dns_ip4(stralloc *,const stralloc *); | |
652 | +extern int dns_ip6_packet(stralloc *,char *,unsigned int); | |
653 | +extern int dns_ip6(stralloc *,stralloc *); | |
654 | extern int dns_name_packet(stralloc *,const char *,unsigned int); | |
655 | extern void dns_name4_domain(char *,const char *); | |
656 | #define DNS_NAME4_DOMAIN 31 | |
657 | extern int dns_name4(stralloc *,const char *); | |
658 | +extern int dns_name6(stralloc *,const char *); | |
659 | extern int dns_txt_packet(stralloc *,const char *,unsigned int); | |
660 | extern int dns_txt(stralloc *,const stralloc *); | |
661 | extern int dns_mx_packet(stralloc *,const char *,unsigned int); | |
662 | @@ -80,5 +85,13 @@ extern int dns_mx(stralloc *,const stralloc *); | |
663 | extern int dns_resolvconfrewrite(stralloc *); | |
664 | extern int dns_ip4_qualify_rules(stralloc *,stralloc *,const stralloc *,const stralloc *); | |
665 | extern int dns_ip4_qualify(stralloc *,stralloc *,const stralloc *); | |
666 | +extern int dns_ip6_qualify_rules(stralloc *,stralloc *,const stralloc *,const stralloc *); | |
667 | +extern int dns_ip6_qualify(stralloc *,stralloc *,const stralloc *); | |
668 | + | |
669 | +#define DNS_IP6_INT 0 | |
670 | +#define DNS_IP6_ARPA 1 | |
671 | + | |
672 | +extern int dns_name6_domain(char *,const char *,int); | |
673 | +#define DNS_NAME6_DOMAIN (4*16+11) | |
674 | ||
675 | #endif | |
676 | diff --git a/dns_ip6.c b/dns_ip6.c | |
677 | new file mode 100644 | |
678 | index 0000000..30ce699 | |
679 | --- /dev/null | |
680 | +++ b/dns_ip6.c | |
681 | @@ -0,0 +1,103 @@ | |
682 | +#include "stralloc.h" | |
683 | +#include "uint16.h" | |
684 | +#include "byte.h" | |
685 | +#include "dns.h" | |
686 | +#include "ip4.h" | |
687 | +#include "ip6.h" | |
688 | + | |
689 | +static int dns_ip6_packet_add(stralloc *out,char *buf,unsigned int len) | |
690 | +{ | |
691 | + unsigned int pos; | |
692 | + char header[16]; | |
693 | + uint16 numanswers; | |
694 | + uint16 datalen; | |
695 | + | |
696 | + pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1; | |
697 | + uint16_unpack_big(header + 6,&numanswers); | |
698 | + pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; | |
699 | + pos += 4; | |
700 | + | |
701 | + while (numanswers--) { | |
702 | + pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; | |
703 | + pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1; | |
704 | + uint16_unpack_big(header + 8,&datalen); | |
705 | + if (byte_equal(header,2,DNS_T_AAAA)) { | |
706 | + if (byte_equal(header + 2,2,DNS_C_IN)) | |
707 | + if (datalen == 16) { | |
708 | + if (!dns_packet_copy(buf,len,pos,header,16)) return -1; | |
709 | + if (!stralloc_catb(out,header,16)) return -1; | |
710 | + } | |
711 | + } else if (byte_equal(header,2,DNS_T_A)) | |
712 | + if (byte_equal(header + 2,2,DNS_C_IN)) | |
713 | + if (datalen == 4) { | |
714 | + byte_copy(header,12,V4mappedprefix); | |
715 | + if (!dns_packet_copy(buf,len,pos,header+12,4)) return -1; | |
716 | + if (!stralloc_catb(out,header,16)) return -1; | |
717 | + } | |
718 | + pos += datalen; | |
719 | + } | |
720 | + | |
721 | + dns_sortip6(out->s,out->len); | |
722 | + return 0; | |
723 | +} | |
724 | + | |
725 | +int dns_ip6_packet(stralloc *out,char *buf,unsigned int len) { | |
726 | + if (!stralloc_copys(out,"")) return -1; | |
727 | + return dns_ip6_packet_add(out,buf,len); | |
728 | +} | |
729 | + | |
730 | +static char *q = 0; | |
731 | + | |
732 | +int dns_ip6(stralloc *out,stralloc *fqdn) | |
733 | +{ | |
734 | + unsigned int i; | |
735 | + char code; | |
736 | + char ch; | |
737 | + char ip[16]; | |
738 | + | |
739 | + if (!stralloc_copys(out,"")) return -1; | |
740 | + if (!stralloc_readyplus(fqdn,1)) return -1; | |
741 | + fqdn->s[fqdn->len]=0; | |
742 | + if ((i=ip6_scan(fqdn->s,ip))) { | |
743 | + if (fqdn->s[i]) return -1; | |
744 | + stralloc_copyb(out,ip,16); | |
745 | + return 0; | |
746 | + } | |
747 | + code = 0; | |
748 | + for (i = 0;i <= fqdn->len;++i) { | |
749 | + if (i < fqdn->len) | |
750 | + ch = fqdn->s[i]; | |
751 | + else | |
752 | + ch = '.'; | |
753 | + | |
754 | + if ((ch == '[') || (ch == ']')) continue; | |
755 | + if (ch == '.') { | |
756 | + if (!stralloc_append(out,&code)) return -1; | |
757 | + code = 0; | |
758 | + continue; | |
759 | + } | |
760 | + if ((ch >= '0') && (ch <= '9')) { | |
761 | + code *= 10; | |
762 | + code += ch - '0'; | |
763 | + continue; | |
764 | + } | |
765 | + | |
766 | + if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1; | |
767 | + if (!stralloc_copys(out,"")) return -1; | |
768 | + if (dns_resolve(q,DNS_T_AAAA) != -1) | |
769 | + if (dns_ip6_packet_add(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) != -1) { | |
770 | + dns_transmit_free(&dns_resolve_tx); | |
771 | + dns_domain_free(&q); | |
772 | + } | |
773 | + if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1; | |
774 | + if (dns_resolve(q,DNS_T_A) != -1) | |
775 | + if (dns_ip6_packet_add(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) != -1) { | |
776 | + dns_transmit_free(&dns_resolve_tx); | |
777 | + dns_domain_free(&q); | |
778 | + } | |
779 | + return out->a>0?0:-1; | |
780 | + } | |
781 | + | |
782 | + out->len &= ~3; | |
783 | + return 0; | |
784 | +} | |
785 | diff --git a/dns_ipq6.c b/dns_ipq6.c | |
786 | new file mode 100644 | |
787 | index 0000000..d5cea12 | |
788 | --- /dev/null | |
789 | +++ b/dns_ipq6.c | |
790 | @@ -0,0 +1,72 @@ | |
791 | +#include "stralloc.h" | |
792 | +#include "case.h" | |
793 | +#include "byte.h" | |
794 | +#include "str.h" | |
795 | +#include "dns.h" | |
796 | + | |
797 | +static int doit(stralloc *work,const char *rule) | |
798 | +{ | |
799 | + char ch; | |
800 | + unsigned int colon; | |
801 | + unsigned int prefixlen; | |
802 | + | |
803 | + ch = *rule++; | |
804 | + if ((ch != '?') && (ch != '=') && (ch != '*') && (ch != '-')) return 1; | |
805 | + colon = str_chr(rule,':'); | |
806 | + if (!rule[colon]) return 1; | |
807 | + | |
808 | + if (work->len < colon) return 1; | |
809 | + prefixlen = work->len - colon; | |
810 | + if ((ch == '=') && prefixlen) return 1; | |
811 | + if (case_diffb(rule,colon,work->s + prefixlen)) return 1; | |
812 | + if (ch == '?') { | |
813 | + if (byte_chr(work->s,prefixlen,'.') < prefixlen) return 1; | |
814 | + if (byte_chr(work->s,prefixlen,':') < prefixlen) return 1; | |
815 | + if (byte_chr(work->s,prefixlen,'[') < prefixlen) return 1; | |
816 | + if (byte_chr(work->s,prefixlen,']') < prefixlen) return 1; | |
817 | + } | |
818 | + | |
819 | + work->len = prefixlen; | |
820 | + if (ch == '-') work->len = 0; | |
821 | + return stralloc_cats(work,rule + colon + 1); | |
822 | +} | |
823 | + | |
824 | +int dns_ip6_qualify_rules(stralloc *out,stralloc *fqdn,const stralloc *in,const stralloc *rules) | |
825 | +{ | |
826 | + unsigned int i; | |
827 | + unsigned int j; | |
828 | + unsigned int plus; | |
829 | + unsigned int fqdnlen; | |
830 | + | |
831 | + if (!stralloc_copy(fqdn,in)) return -1; | |
832 | + | |
833 | + for (j = i = 0;j < rules->len;++j) | |
834 | + if (!rules->s[j]) { | |
835 | + if (!doit(fqdn,rules->s + i)) return -1; | |
836 | + i = j + 1; | |
837 | + } | |
838 | + | |
839 | + fqdnlen = fqdn->len; | |
840 | + plus = byte_chr(fqdn->s,fqdnlen,'+'); | |
841 | + if (plus >= fqdnlen) | |
842 | + return dns_ip6(out,fqdn); | |
843 | + | |
844 | + i = plus + 1; | |
845 | + for (;;) { | |
846 | + j = byte_chr(fqdn->s + i,fqdnlen - i,'+'); | |
847 | + byte_copy(fqdn->s + plus,j,fqdn->s + i); | |
848 | + fqdn->len = plus + j; | |
849 | + if (dns_ip6(out,fqdn) == -1) return -1; | |
850 | + if (out->len) return 0; | |
851 | + i += j; | |
852 | + if (i >= fqdnlen) return 0; | |
853 | + ++i; | |
854 | + } | |
855 | +} | |
856 | + | |
857 | +int dns_ip6_qualify(stralloc *out,stralloc *fqdn,const stralloc *in) | |
858 | +{ | |
859 | + static stralloc rules; | |
860 | + if (dns_resolvconfrewrite(&rules) == -1) return -1; | |
861 | + return dns_ip6_qualify_rules(out,fqdn,in,&rules); | |
862 | +} | |
863 | diff --git a/dns_name.c b/dns_name.c | |
864 | index 6f7cdc3..518a0c0 100644 | |
865 | --- a/dns_name.c | |
866 | +++ b/dns_name.c | |
867 | @@ -2,6 +2,7 @@ | |
868 | #include "uint16.h" | |
869 | #include "byte.h" | |
870 | #include "dns.h" | |
871 | +#include "ip6.h" | |
872 | ||
873 | static char *q = 0; | |
874 | ||
875 | @@ -46,3 +47,24 @@ int dns_name4(stralloc *out,const char ip[4]) | |
876 | dns_domain_free(&q); | |
877 | return 0; | |
878 | } | |
879 | + | |
880 | +int dns_name6_inner(stralloc *out,const char ip[16],int t) | |
881 | +{ | |
882 | + char name[DNS_NAME6_DOMAIN]; | |
883 | + | |
884 | + dns_name6_domain(name,ip,t); | |
885 | + if (dns_resolve(name,DNS_T_PTR) == -1) return -1; | |
886 | + if (dns_name_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1; | |
887 | + dns_transmit_free(&dns_resolve_tx); | |
888 | + dns_domain_free(&q); | |
889 | + return 0; | |
890 | +} | |
891 | + | |
892 | +int dns_name6(stralloc *out,const char ip[16]) | |
893 | +{ | |
894 | + if (ip6_isv4mapped(ip)) | |
895 | + return dns_name4(out,ip+12); | |
896 | + if (dns_name6_inner(out,ip,DNS_IP6_ARPA)) return -1; | |
897 | + if (!out->len) return dns_name6_inner(out,ip,DNS_IP6_INT); | |
898 | + return 0; | |
899 | +} | |
900 | diff --git a/dns_nd6.c b/dns_nd6.c | |
901 | new file mode 100644 | |
902 | index 0000000..6dbeb89 | |
903 | --- /dev/null | |
904 | +++ b/dns_nd6.c | |
905 | @@ -0,0 +1,35 @@ | |
906 | +#include "byte.h" | |
907 | +#include "fmt.h" | |
908 | +#include "dns.h" | |
909 | + | |
910 | +/* RFC1886: | |
911 | + * 4321:0:1:2:3:4:567:89ab | |
912 | + * -> | |
913 | + * b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.4.IP6.INT. | |
914 | + * b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.4.IP6.ARPA. | |
915 | + */ | |
916 | + | |
917 | +extern char tohex(char num); | |
918 | + | |
919 | +unsigned int mkint(unsigned char a,unsigned char b) { | |
920 | + return ((unsigned int)a << 8) + (unsigned int)b; | |
921 | +} | |
922 | + | |
923 | +int dns_name6_domain(char name[DNS_NAME6_DOMAIN],const char ip[16],int t) | |
924 | +{ | |
925 | + unsigned int j; | |
926 | + | |
927 | + for (j=0; j<16; j++) { | |
928 | + name[j*4]=1; | |
929 | + name[j*4+1]=tohex(ip[15-j] & 15); | |
930 | + name[j*4+2]=1; | |
931 | + name[j*4+3]=tohex((unsigned char)ip[15-j] >> 4); | |
932 | + } | |
933 | + if (t==DNS_IP6_INT) | |
934 | + byte_copy(name + 4*16,9,"\3ip6\3int\0"); | |
935 | + else if (t==DNS_IP6_ARPA) | |
936 | + byte_copy(name + 4*16,10,"\3ip6\4arpa\0"); | |
937 | + else return 0; | |
938 | + return 4*16+9+t; | |
939 | +} | |
940 | + | |
941 | diff --git a/dns_rcip.c b/dns_rcip.c | |
942 | index 97bd8f5..efd1b21 100644 | |
943 | --- a/dns_rcip.c | |
944 | +++ b/dns_rcip.c | |
945 | @@ -2,12 +2,13 @@ | |
946 | #include "openreadclose.h" | |
947 | #include "byte.h" | |
948 | #include "ip4.h" | |
949 | +#include "ip6.h" | |
950 | #include "env.h" | |
951 | #include "dns.h" | |
952 | ||
953 | static stralloc data = {0}; | |
954 | ||
955 | -static int init(char ip[64]) | |
956 | +static int init(char ip[256]) | |
957 | { | |
958 | int i; | |
959 | int j; | |
960 | @@ -20,10 +21,10 @@ static int init(char ip[64]) | |
961 | if (*x == '.') | |
962 | ++x; | |
963 | else { | |
964 | - i = ip4_scan(x,ip + iplen); | |
965 | + i = ip6_scan(x,ip + iplen); | |
966 | if (!i) break; | |
967 | x += i; | |
968 | - iplen += 4; | |
969 | + iplen += 16; | |
970 | } | |
971 | } | |
972 | ||
973 | @@ -40,10 +41,8 @@ static int init(char ip[64]) | |
974 | while ((data.s[i] == ' ') || (data.s[i] == '\t')) | |
975 | ++i; | |
976 | if (iplen <= 60) | |
977 | - if (ip4_scan(data.s + i,ip + iplen)) { | |
978 | - if (byte_equal(ip + iplen,4,"\0\0\0\0")) | |
979 | - byte_copy(ip + iplen,4,"\177\0\0\1"); | |
980 | - iplen += 4; | |
981 | + if (ip6_scan(data.s + i,ip + iplen)) { | |
982 | + iplen += 16; | |
983 | } | |
984 | } | |
985 | i = j + 1; | |
986 | @@ -52,19 +51,19 @@ static int init(char ip[64]) | |
987 | } | |
988 | ||
989 | if (!iplen) { | |
990 | - byte_copy(ip,4,"\177\0\0\1"); | |
991 | - iplen = 4; | |
992 | + byte_copy(ip,16,"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1"); | |
993 | + iplen = 16; | |
994 | } | |
995 | - byte_zero(ip + iplen,64 - iplen); | |
996 | + byte_zero(ip + iplen,256 - iplen); | |
997 | return 0; | |
998 | } | |
999 | ||
1000 | static int ok = 0; | |
1001 | static unsigned int uses; | |
1002 | static struct taia deadline; | |
1003 | -static char ip[64]; /* defined if ok */ | |
1004 | +static char ip[256]; /* defined if ok */ | |
1005 | ||
1006 | -int dns_resolvconfip(char s[64]) | |
1007 | +int dns_resolvconfip(char s[256]) | |
1008 | { | |
1009 | struct taia now; | |
1010 | ||
1011 | @@ -81,6 +80,6 @@ int dns_resolvconfip(char s[64]) | |
1012 | } | |
1013 | ||
1014 | --uses; | |
1015 | - byte_copy(s,64,ip); | |
1016 | + byte_copy(s,256,ip); | |
1017 | return 0; | |
1018 | } | |
1019 | diff --git a/dns_resolve.c b/dns_resolve.c | |
1020 | index 8bdea0d..82b5bbb 100644 | |
1021 | --- a/dns_resolve.c | |
1022 | +++ b/dns_resolve.c | |
1023 | @@ -2,6 +2,7 @@ | |
1024 | #include "taia.h" | |
1025 | #include "byte.h" | |
1026 | #include "dns.h" | |
1027 | +#include "ip6.h" | |
1028 | ||
1029 | struct dns_transmit dns_resolve_tx = {0}; | |
1030 | ||
1031 | @@ -9,12 +10,12 @@ int dns_resolve(const char *q,const char qtype[2]) | |
1032 | { | |
1033 | struct taia stamp; | |
1034 | struct taia deadline; | |
1035 | - char servers[64]; | |
1036 | + char servers[256]; | |
1037 | iopause_fd x[1]; | |
1038 | int r; | |
1039 | ||
1040 | if (dns_resolvconfip(servers) == -1) return -1; | |
1041 | - if (dns_transmit_start(&dns_resolve_tx,servers,1,q,qtype,"\0\0\0\0") == -1) return -1; | |
1042 | + if (dns_transmit_start(&dns_resolve_tx,servers,1,q,qtype,V6any) == -1) return -1; | |
1043 | ||
1044 | for (;;) { | |
1045 | taia_now(&stamp); | |
1046 | diff --git a/dns_sortip6.c b/dns_sortip6.c | |
1047 | new file mode 100644 | |
1048 | index 0000000..7e752e9 | |
1049 | --- /dev/null | |
1050 | +++ b/dns_sortip6.c | |
1051 | @@ -0,0 +1,20 @@ | |
1052 | +#include "byte.h" | |
1053 | +#include "dns.h" | |
1054 | + | |
1055 | +/* XXX: sort servers by configurable notion of closeness? */ | |
1056 | +/* XXX: pay attention to competence of each server? */ | |
1057 | + | |
1058 | +void dns_sortip6(char *s,unsigned int n) | |
1059 | +{ | |
1060 | + unsigned int i; | |
1061 | + char tmp[16]; | |
1062 | + | |
1063 | + n >>= 4; | |
1064 | + while (n > 1) { | |
1065 | + i = dns_random(n); | |
1066 | + --n; | |
1067 | + byte_copy(tmp,16,s + (i << 4)); | |
1068 | + byte_copy(s + (i << 4),16,s + (n << 4)); | |
1069 | + byte_copy(s + (n << 4),16,tmp); | |
1070 | + } | |
1071 | +} | |
1072 | diff --git a/dns_transmit.c b/dns_transmit.c | |
1073 | index 4d6e39f..cba1fd2 100644 | |
1074 | --- a/dns_transmit.c | |
1075 | +++ b/dns_transmit.c | |
1076 | @@ -7,6 +7,7 @@ | |
1077 | #include "byte.h" | |
1078 | #include "uint16.h" | |
1079 | #include "dns.h" | |
1080 | +#include "ip6.h" | |
1081 | ||
1082 | static int serverwantstcp(const char *buf,unsigned int len) | |
1083 | { | |
1084 | @@ -85,9 +86,9 @@ static int randombind(struct dns_transmit *d) | |
1085 | int j; | |
1086 | ||
1087 | for (j = 0;j < 10;++j) | |
1088 | - if (socket_bind4(d->s1 - 1,d->localip,1025 + dns_random(64510)) == 0) | |
1089 | + if (socket_bind6(d->s1 - 1,d->localip,1025 + dns_random(64510),d->scope_id) == 0) | |
1090 | return 0; | |
1091 | - if (socket_bind4(d->s1 - 1,d->localip,0) == 0) | |
1092 | + if (socket_bind6(d->s1 - 1,d->localip,0,d->scope_id) == 0) | |
1093 | return 0; | |
1094 | return -1; | |
1095 | } | |
1096 | @@ -102,16 +103,16 @@ static int thisudp(struct dns_transmit *d) | |
1097 | ||
1098 | while (d->udploop < 4) { | |
1099 | for (;d->curserver < 16;++d->curserver) { | |
1100 | - ip = d->servers + 4 * d->curserver; | |
1101 | - if (byte_diff(ip,4,"\0\0\0\0")) { | |
1102 | + ip = d->servers + 16 * d->curserver; | |
1103 | + if (byte_diff(ip,16,V6any)) { | |
1104 | d->query[2] = dns_random(256); | |
1105 | d->query[3] = dns_random(256); | |
1106 | ||
1107 | - d->s1 = 1 + socket_udp(); | |
1108 | + d->s1 = 1 + socket_udp6(); | |
1109 | if (!d->s1) { dns_transmit_free(d); return -1; } | |
1110 | if (randombind(d) == -1) { dns_transmit_free(d); return -1; } | |
1111 | ||
1112 | - if (socket_connect4(d->s1 - 1,ip,53) == 0) | |
1113 | + if (socket_connect6(d->s1 - 1,ip,53,d->scope_id) == 0) | |
1114 | if (send(d->s1 - 1,d->query + 2,d->querylen - 2,0) == d->querylen - 2) { | |
1115 | struct taia now; | |
1116 | taia_now(&now); | |
1117 | @@ -153,19 +154,19 @@ static int thistcp(struct dns_transmit *d) | |
1118 | packetfree(d); | |
1119 | ||
1120 | for (;d->curserver < 16;++d->curserver) { | |
1121 | - ip = d->servers + 4 * d->curserver; | |
1122 | - if (byte_diff(ip,4,"\0\0\0\0")) { | |
1123 | + ip = d->servers + 16 * d->curserver; | |
1124 | + if (byte_diff(ip,16,V6any)) { | |
1125 | d->query[2] = dns_random(256); | |
1126 | d->query[3] = dns_random(256); | |
1127 | ||
1128 | - d->s1 = 1 + socket_tcp(); | |
1129 | + d->s1 = 1 + socket_tcp6(); | |
1130 | if (!d->s1) { dns_transmit_free(d); return -1; } | |
1131 | if (randombind(d) == -1) { dns_transmit_free(d); return -1; } | |
1132 | ||
1133 | taia_now(&now); | |
1134 | taia_uint(&d->deadline,10); | |
1135 | taia_add(&d->deadline,&d->deadline,&now); | |
1136 | - if (socket_connect4(d->s1 - 1,ip,53) == 0) { | |
1137 | + if (socket_connect6(d->s1 - 1,ip,53,d->scope_id) == 0) { | |
1138 | d->tcpstate = 2; | |
1139 | return 0; | |
1140 | } | |
1141 | @@ -193,7 +194,7 @@ static int nexttcp(struct dns_transmit *d) | |
1142 | return thistcp(d); | |
1143 | } | |
1144 | ||
1145 | -int dns_transmit_start(struct dns_transmit *d,const char servers[64],int flagrecursive,const char *q,const char qtype[2],const char localip[4]) | |
1146 | +int dns_transmit_start(struct dns_transmit *d,const char servers[256],int flagrecursive,const char *q,const char qtype[2],const char localip[16]) | |
1147 | { | |
1148 | unsigned int len; | |
1149 | ||
1150 | @@ -213,7 +214,7 @@ int dns_transmit_start(struct dns_transmit *d,const char servers[64],int flagrec | |
1151 | ||
1152 | byte_copy(d->qtype,2,qtype); | |
1153 | d->servers = servers; | |
1154 | - byte_copy(d->localip,4,localip); | |
1155 | + byte_copy(d->localip,16,localip); | |
1156 | ||
1157 | d->udploop = flagrecursive ? 1 : 0; | |
1158 | ||
1159 | diff --git a/dnscache.c b/dnscache.c | |
1160 | index 8c899a3..abcba69 100644 | |
1161 | --- a/dnscache.c | |
1162 | +++ b/dnscache.c | |
1163 | @@ -5,6 +5,7 @@ | |
1164 | #include "strerr.h" | |
1165 | #include "error.h" | |
1166 | #include "ip4.h" | |
1167 | +#include "ip6.h" | |
1168 | #include "uint16.h" | |
1169 | #include "uint64.h" | |
1170 | #include "socket.h" | |
1171 | @@ -23,6 +24,10 @@ | |
1172 | #include "okclient.h" | |
1173 | #include "droproot.h" | |
1174 | ||
1175 | +long interface; | |
1176 | + | |
1177 | +stralloc ignoreip = {0}; | |
1178 | + | |
1179 | static int packetquery(char *buf,unsigned int len,char **q,char qtype[2],char qclass[2],char id[2]) | |
1180 | { | |
1181 | unsigned int pos; | |
1182 | @@ -46,8 +51,8 @@ static int packetquery(char *buf,unsigned int len,char **q,char qtype[2],char qc | |
1183 | } | |
1184 | ||
1185 | ||
1186 | -static char myipoutgoing[4]; | |
1187 | -static char myipincoming[4]; | |
1188 | +static char myipoutgoing[16]; | |
1189 | +static char myipincoming[16]; | |
1190 | static char buf[1024]; | |
1191 | uint64 numqueries = 0; | |
1192 | ||
1193 | @@ -60,9 +65,10 @@ static struct udpclient { | |
1194 | struct taia start; | |
1195 | uint64 active; /* query number, if active; otherwise 0 */ | |
1196 | iopause_fd *io; | |
1197 | - char ip[4]; | |
1198 | + char ip[16]; | |
1199 | uint16 port; | |
1200 | char id[2]; | |
1201 | + uint32 scope_id; | |
1202 | } u[MAXUDP]; | |
1203 | int uactive = 0; | |
1204 | ||
1205 | @@ -78,7 +84,7 @@ void u_respond(int j) | |
1206 | if (!u[j].active) return; | |
1207 | response_id(u[j].id); | |
1208 | if (response_len > 512) response_tc(); | |
1209 | - socket_send4(udp53,response,response_len,u[j].ip,u[j].port); | |
1210 | + socket_send6(udp53,response,response_len,u[j].ip,u[j].port,u[j].scope_id); | |
1211 | log_querydone(&u[j].active,response_len); | |
1212 | u[j].active = 0; --uactive; | |
1213 | } | |
1214 | @@ -109,7 +115,7 @@ void u_new(void) | |
1215 | x = u + j; | |
1216 | taia_now(&x->start); | |
1217 | ||
1218 | - len = socket_recv4(udp53,buf,sizeof buf,x->ip,&x->port); | |
1219 | + len = socket_recv6(udp53,buf,sizeof buf,x->ip,&x->port,&x->scope_id); | |
1220 | if (len == -1) return; | |
1221 | if (len >= sizeof buf) return; | |
1222 | if (x->port < 1024) if (x->port != 53) return; | |
1223 | @@ -119,7 +125,7 @@ void u_new(void) | |
1224 | ||
1225 | x->active = ++numqueries; ++uactive; | |
1226 | log_query(&x->active,x->ip,x->port,x->id,q,qtype); | |
1227 | - switch(query_start(&x->q,q,qtype,qclass,myipoutgoing)) { | |
1228 | + switch(query_start(&x->q,q,qtype,qclass,myipoutgoing,interface)) { | |
1229 | case -1: | |
1230 | u_drop(j); | |
1231 | return; | |
1232 | @@ -128,7 +134,6 @@ void u_new(void) | |
1233 | } | |
1234 | } | |
1235 | ||
1236 | - | |
1237 | static int tcp53; | |
1238 | ||
1239 | #define MAXTCP 20 | |
1240 | @@ -138,7 +143,7 @@ struct tcpclient { | |
1241 | struct taia timeout; | |
1242 | uint64 active; /* query number or 1, if active; otherwise 0 */ | |
1243 | iopause_fd *io; | |
1244 | - char ip[4]; /* send response to this address */ | |
1245 | + char ip[16]; /* send response to this address */ | |
1246 | uint16 port; /* send response to this port */ | |
1247 | char id[2]; | |
1248 | int tcp; /* open TCP socket, if active */ | |
1249 | @@ -146,6 +151,7 @@ struct tcpclient { | |
1250 | char *buf; /* 0, or dynamically allocated of length len */ | |
1251 | unsigned int len; | |
1252 | unsigned int pos; | |
1253 | + uint32 scope_id; | |
1254 | } t[MAXTCP]; | |
1255 | int tactive = 0; | |
1256 | ||
1257 | @@ -254,7 +260,7 @@ void t_rw(int j) | |
1258 | ||
1259 | x->active = ++numqueries; | |
1260 | log_query(&x->active,x->ip,x->port,x->id,q,qtype); | |
1261 | - switch(query_start(&x->q,q,qtype,qclass,myipoutgoing)) { | |
1262 | + switch(query_start(&x->q,q,qtype,qclass,myipoutgoing,interface)) { | |
1263 | case -1: | |
1264 | t_drop(j); | |
1265 | return; | |
1266 | @@ -291,7 +297,7 @@ void t_new(void) | |
1267 | x = t + j; | |
1268 | taia_now(&x->start); | |
1269 | ||
1270 | - x->tcp = socket_accept4(tcp53,x->ip,&x->port); | |
1271 | + x->tcp = socket_accept6(tcp53,x->ip,&x->port,&x->scope_id); | |
1272 | if (x->tcp == -1) return; | |
1273 | if (x->port < 1024) if (x->port != 53) { close(x->tcp); return; } | |
1274 | if (!okclient(x->ip)) { close(x->tcp); return; } | |
1275 | @@ -389,24 +395,36 @@ char seed[128]; | |
1276 | int main() | |
1277 | { | |
1278 | char *x; | |
1279 | + unsigned int i, j, k; | |
1280 | unsigned long cachesize; | |
1281 | + static stralloc sa = {0}; | |
1282 | + | |
1283 | + x = env_get("INTERFACE"); | |
1284 | + if (x) scan_ulong(x,&interface); | |
1285 | ||
1286 | x = env_get("IP"); | |
1287 | if (!x) | |
1288 | strerr_die2x(111,FATAL,"$IP not set"); | |
1289 | - if (!ip4_scan(x,myipincoming)) | |
1290 | + if (!ip6_scan(x,myipincoming)) | |
1291 | strerr_die3x(111,FATAL,"unable to parse IP address ",x); | |
1292 | ||
1293 | - udp53 = socket_udp(); | |
1294 | +#if 0 | |
1295 | + /* if if IP is a mapped-IPv4 address, disable IPv6 functionality */ | |
1296 | + /* this is actually a bad idea */ | |
1297 | + if (ip6_isv4mapped(myipincoming)) | |
1298 | + noipv6 = 1; | |
1299 | +#endif | |
1300 | + | |
1301 | + udp53 = socket_udp6(); | |
1302 | if (udp53 == -1) | |
1303 | strerr_die2sys(111,FATAL,"unable to create UDP socket: "); | |
1304 | - if (socket_bind4_reuse(udp53,myipincoming,53) == -1) | |
1305 | + if (socket_bind6_reuse(udp53,myipincoming,53,interface) == -1) | |
1306 | strerr_die2sys(111,FATAL,"unable to bind UDP socket: "); | |
1307 | ||
1308 | - tcp53 = socket_tcp(); | |
1309 | + tcp53 = socket_tcp6(); | |
1310 | if (tcp53 == -1) | |
1311 | strerr_die2sys(111,FATAL,"unable to create TCP socket: "); | |
1312 | - if (socket_bind4_reuse(tcp53,myipincoming,53) == -1) | |
1313 | + if (socket_bind6_reuse(tcp53,myipincoming,53,interface) == -1) | |
1314 | strerr_die2sys(111,FATAL,"unable to bind TCP socket: "); | |
1315 | ||
1316 | droproot(FATAL); | |
1317 | @@ -421,7 +439,7 @@ int main() | |
1318 | x = env_get("IPSEND"); | |
1319 | if (!x) | |
1320 | strerr_die2x(111,FATAL,"$IPSEND not set"); | |
1321 | - if (!ip4_scan(x,myipoutgoing)) | |
1322 | + if (!ip6_scan(x,myipoutgoing)) | |
1323 | strerr_die3x(111,FATAL,"unable to parse IP address ",x); | |
1324 | ||
1325 | x = env_get("CACHESIZE"); | |
1326 | @@ -431,6 +449,20 @@ int main() | |
1327 | if (!cache_init(cachesize)) | |
1328 | strerr_die3x(111,FATAL,"not enough memory for cache of size ",x); | |
1329 | ||
1330 | + if (openreadclose("ignoreip",&sa,64) < 0) | |
1331 | + strerr_die2x(111,FATAL,"trouble reading ignoreip"); | |
1332 | + for(j = k = i = 0; i < sa.len; i++) | |
1333 | + if (sa.s[i] == '\n') { | |
1334 | + sa.s[i] = '\0'; | |
1335 | + if (!stralloc_readyplus(&ignoreip,16)) | |
1336 | + strerr_die2x(111,FATAL,"out of memory parsing ignoreip"); | |
1337 | + if (!ip6_scan(sa.s+k,ignoreip.s+j)) | |
1338 | + strerr_die3x(111,FATAL,"unable to parse address in ignoreip ",ignoreip.s+k); | |
1339 | + j += 16; | |
1340 | + k = i + 1; | |
1341 | + } | |
1342 | + ignoreip.len = j; | |
1343 | + | |
1344 | if (env_get("HIDETTL")) | |
1345 | response_hidettl(); | |
1346 | if (env_get("FORWARDONLY")) | |
1347 | diff --git a/dnsfilter.c b/dnsfilter.c | |
1348 | index 9e6863a..822ff1e 100644 | |
1349 | --- a/dnsfilter.c | |
1350 | +++ b/dnsfilter.c | |
1351 | @@ -12,6 +12,7 @@ | |
1352 | #include "iopause.h" | |
1353 | #include "error.h" | |
1354 | #include "exit.h" | |
1355 | +#include "ip6.h" | |
1356 | ||
1357 | #define FATAL "dnsfilter: fatal: " | |
1358 | ||
1359 | @@ -44,7 +45,7 @@ int flag0 = 1; | |
1360 | iopause_fd *io; | |
1361 | int iolen; | |
1362 | ||
1363 | -char servers[64]; | |
1364 | +char servers[256]; | |
1365 | char ip[4]; | |
1366 | char name[DNS_NAME4_DOMAIN]; | |
1367 | ||
1368 | @@ -191,7 +192,7 @@ int main(int argc,char **argv) | |
1369 | dns_name4_domain(name,ip); | |
1370 | if (dns_resolvconfip(servers) == -1) | |
1371 | strerr_die2sys(111,FATAL,"unable to read /etc/resolv.conf: "); | |
1372 | - if (dns_transmit_start(&x[xnum].dt,servers,1,name,DNS_T_PTR,"\0\0\0\0") == -1) | |
1373 | + if (dns_transmit_start(&x[xnum].dt,servers,1,name,DNS_T_PTR,V6any) == -1) | |
1374 | errout(xnum); | |
1375 | else { | |
1376 | x[xnum].flagactive = 1; | |
1377 | diff --git a/dnsip6.c b/dnsip6.c | |
1378 | new file mode 100644 | |
1379 | index 0000000..5b65823 | |
1380 | --- /dev/null | |
1381 | +++ b/dnsip6.c | |
1382 | @@ -0,0 +1,40 @@ | |
1383 | +#include "buffer.h" | |
1384 | +#include "exit.h" | |
1385 | +#include "strerr.h" | |
1386 | +#include "ip6.h" | |
1387 | +#include "dns.h" | |
1388 | + | |
1389 | +#define FATAL "dnsip: fatal: " | |
1390 | + | |
1391 | +static char seed[128]; | |
1392 | + | |
1393 | +static stralloc fqdn; | |
1394 | +static stralloc out; | |
1395 | +char str[IP6_FMT]; | |
1396 | + | |
1397 | +main(int argc,char **argv) | |
1398 | +{ | |
1399 | + int i; | |
1400 | + | |
1401 | + dns_random_init(seed); | |
1402 | + | |
1403 | + if (*argv) ++argv; | |
1404 | + | |
1405 | + while (*argv) { | |
1406 | + if (!stralloc_copys(&fqdn,*argv)) | |
1407 | + strerr_die2x(111,FATAL,"out of memory"); | |
1408 | + if (dns_ip6(&out,&fqdn) == -1) | |
1409 | + strerr_die4sys(111,FATAL,"unable to find IPv6 address for ",*argv,": "); | |
1410 | + | |
1411 | + for (i = 0;i + 16 <= out.len;i += 16) { | |
1412 | + buffer_put(buffer_1,str,ip6_fmt(str,out.s + i)); | |
1413 | + buffer_puts(buffer_1," "); | |
1414 | + } | |
1415 | + buffer_puts(buffer_1,"\n"); | |
1416 | + | |
1417 | + ++argv; | |
1418 | + } | |
1419 | + | |
1420 | + buffer_flush(buffer_1); | |
1421 | + _exit(0); | |
1422 | +} | |
1423 | diff --git a/dnsip6q.c b/dnsip6q.c | |
1424 | new file mode 100644 | |
1425 | index 0000000..82ab04e | |
1426 | --- /dev/null | |
1427 | +++ b/dnsip6q.c | |
1428 | @@ -0,0 +1,43 @@ | |
1429 | +#include "buffer.h" | |
1430 | +#include "exit.h" | |
1431 | +#include "strerr.h" | |
1432 | +#include "ip6.h" | |
1433 | +#include "dns.h" | |
1434 | + | |
1435 | +#define FATAL "dnsipq: fatal: " | |
1436 | + | |
1437 | +static char seed[128]; | |
1438 | + | |
1439 | +static stralloc in; | |
1440 | +static stralloc fqdn; | |
1441 | +static stralloc out; | |
1442 | +char str[IP6_FMT]; | |
1443 | + | |
1444 | +int main(int argc,char **argv) | |
1445 | +{ | |
1446 | + int i; | |
1447 | + | |
1448 | + dns_random_init(seed); | |
1449 | + | |
1450 | + if (*argv) ++argv; | |
1451 | + | |
1452 | + while (*argv) { | |
1453 | + if (!stralloc_copys(&in,*argv)) | |
1454 | + strerr_die2x(111,FATAL,"out of memory"); | |
1455 | + if (dns_ip6_qualify(&out,&fqdn,&in) == -1) | |
1456 | + strerr_die4sys(111,FATAL,"unable to find IP6 address for ",*argv,": "); | |
1457 | + | |
1458 | + buffer_put(buffer_1,fqdn.s,fqdn.len); | |
1459 | + buffer_puts(buffer_1," "); | |
1460 | + for (i = 0;i + 16 <= out.len;i += 16) { | |
1461 | + buffer_put(buffer_1,str,ip6_fmt(str,out.s + i)); | |
1462 | + buffer_puts(buffer_1," "); | |
1463 | + } | |
1464 | + buffer_puts(buffer_1,"\n"); | |
1465 | + | |
1466 | + ++argv; | |
1467 | + } | |
1468 | + | |
1469 | + buffer_flush(buffer_1); | |
1470 | + _exit(0); | |
1471 | +} | |
1472 | diff --git a/dnsname.c b/dnsname.c | |
1473 | index 0e5eb26..ff9166d 100644 | |
1474 | --- a/dnsname.c | |
1475 | +++ b/dnsname.c | |
1476 | @@ -2,6 +2,7 @@ | |
1477 | #include "exit.h" | |
1478 | #include "strerr.h" | |
1479 | #include "ip4.h" | |
1480 | +#include "ip6.h" | |
1481 | #include "dns.h" | |
1482 | ||
1483 | #define FATAL "dnsname: fatal: " | |
1484 | @@ -9,6 +10,7 @@ | |
1485 | static char seed[128]; | |
1486 | ||
1487 | char ip[4]; | |
1488 | +char ip6[16]; | |
1489 | static stralloc out; | |
1490 | ||
1491 | int main(int argc,char **argv) | |
1492 | @@ -18,10 +20,15 @@ int main(int argc,char **argv) | |
1493 | if (*argv) ++argv; | |
1494 | ||
1495 | while (*argv) { | |
1496 | - if (!ip4_scan(*argv,ip)) | |
1497 | - strerr_die3x(111,FATAL,"unable to parse IP address ",*argv); | |
1498 | - if (dns_name4(&out,ip) == -1) | |
1499 | - strerr_die4sys(111,FATAL,"unable to find host name for ",*argv,": "); | |
1500 | + if (ip6_scan(*argv,ip6)) { | |
1501 | + if (dns_name6(&out,ip6) == -1) | |
1502 | + strerr_die4sys(111,FATAL,"unable to find host name for ",*argv,": "); | |
1503 | + } else { | |
1504 | + if (!ip4_scan(*argv,ip)) | |
1505 | + strerr_die3x(111,FATAL,"unable to parse IP address ",*argv); | |
1506 | + if (dns_name4(&out,ip) == -1) | |
1507 | + strerr_die4sys(111,FATAL,"unable to find host name for ",*argv,": "); | |
1508 | + } | |
1509 | ||
1510 | buffer_put(buffer_1,out.s,out.len); | |
1511 | buffer_puts(buffer_1,"\n"); | |
1512 | diff --git a/dnsq.c b/dnsq.c | |
1513 | index 533e6af..9e89efe 100644 | |
1514 | --- a/dnsq.c | |
1515 | +++ b/dnsq.c | |
1516 | @@ -10,6 +10,7 @@ | |
1517 | #include "printpacket.h" | |
1518 | #include "parsetype.h" | |
1519 | #include "dns.h" | |
1520 | +#include "ip6.h" | |
1521 | ||
1522 | #define FATAL "dnsq: fatal: " | |
1523 | ||
1524 | @@ -24,14 +25,14 @@ void oops(void) | |
1525 | ||
1526 | static struct dns_transmit tx; | |
1527 | ||
1528 | -int resolve(char *q,char qtype[2],char servers[64]) | |
1529 | +int resolve(char *q,char qtype[2],char servers[256]) | |
1530 | { | |
1531 | struct taia stamp; | |
1532 | struct taia deadline; | |
1533 | iopause_fd x[1]; | |
1534 | int r; | |
1535 | ||
1536 | - if (dns_transmit_start(&tx,servers,0,q,qtype,"\0\0\0\0") == -1) return -1; | |
1537 | + if (dns_transmit_start(&tx,servers,0,q,qtype,V6any) == -1) return -1; | |
1538 | ||
1539 | for (;;) { | |
1540 | taia_now(&stamp); | |
1541 | @@ -47,7 +48,7 @@ int resolve(char *q,char qtype[2],char servers[64]) | |
1542 | return 0; | |
1543 | } | |
1544 | ||
1545 | -char servers[64]; | |
1546 | +char servers[256]; | |
1547 | static stralloc ip; | |
1548 | static stralloc fqdn; | |
1549 | ||
1550 | @@ -73,9 +74,9 @@ int main(int argc,char **argv) | |
1551 | ||
1552 | if (!*++argv) usage(); | |
1553 | if (!stralloc_copys(&out,*argv)) oops(); | |
1554 | - if (dns_ip4_qualify(&ip,&fqdn,&out) == -1) oops(); | |
1555 | - if (ip.len >= 64) ip.len = 64; | |
1556 | - byte_zero(servers,64); | |
1557 | + if (dns_ip6_qualify(&ip,&fqdn,&out) == -1) oops(); | |
1558 | + if (ip.len >= 256) ip.len = 256; | |
1559 | + byte_zero(servers,256); | |
1560 | byte_copy(servers,ip.len,ip.s); | |
1561 | ||
1562 | if (!stralloc_copys(&out,"")) oops(); | |
1563 | diff --git a/dnstrace.c b/dnstrace.c | |
1564 | index 3f2159b..1d331bd 100644 | |
1565 | --- a/dnstrace.c | |
1566 | +++ b/dnstrace.c | |
1567 | @@ -4,6 +4,7 @@ | |
1568 | #include "str.h" | |
1569 | #include "byte.h" | |
1570 | #include "ip4.h" | |
1571 | +#include "ip6.h" | |
1572 | #include "gen_alloc.h" | |
1573 | #include "gen_allocdefs.h" | |
1574 | #include "exit.h" | |
1575 | @@ -30,7 +31,7 @@ void usage(void) | |
1576 | } | |
1577 | ||
1578 | static stralloc querystr; | |
1579 | -char ipstr[IP4_FMT]; | |
1580 | +char ipstr[IP6_FMT]; | |
1581 | static stralloc tmp; | |
1582 | ||
1583 | void printdomain(const char *d) | |
1584 | @@ -42,19 +43,19 @@ void printdomain(const char *d) | |
1585 | ||
1586 | static struct dns_transmit tx; | |
1587 | ||
1588 | -int resolve(char *q,char qtype[2],char ip[4]) | |
1589 | +int resolve(char *q,char qtype[2],char ip[16]) | |
1590 | { | |
1591 | struct taia start; | |
1592 | struct taia stamp; | |
1593 | struct taia deadline; | |
1594 | - char servers[64]; | |
1595 | + char servers[256]; | |
1596 | iopause_fd x[1]; | |
1597 | int r; | |
1598 | ||
1599 | taia_now(&start); | |
1600 | ||
1601 | - byte_zero(servers,64); | |
1602 | - byte_copy(servers,4,ip); | |
1603 | + byte_zero(servers,256); | |
1604 | + byte_copy(servers,16,ip); | |
1605 | ||
1606 | if (dns_transmit_start(&tx,servers,0,q,qtype,"\0\0\0\0") == -1) return -1; | |
1607 | ||
1608 | @@ -82,7 +83,7 @@ int resolve(char *q,char qtype[2],char ip[4]) | |
1609 | ||
1610 | struct address { | |
1611 | char *owner; | |
1612 | - char ip[4]; | |
1613 | + char ip[16]; | |
1614 | } ; | |
1615 | ||
1616 | GEN_ALLOC_typedef(address_alloc,struct address,s,len,a) | |
1617 | @@ -117,7 +118,7 @@ struct qt { | |
1618 | char *owner; | |
1619 | char type[2]; | |
1620 | char *control; | |
1621 | - char ip[4]; | |
1622 | + char ip[16]; | |
1623 | } ; | |
1624 | ||
1625 | GEN_ALLOC_typedef(qt_alloc,struct qt,s,len,a) | |
1626 | @@ -126,7 +127,7 @@ GEN_ALLOC_append(qt_alloc,struct qt,s,len,a,i,n,x,30,qt_alloc_readyplus,qt_alloc | |
1627 | ||
1628 | static qt_alloc qt; | |
1629 | ||
1630 | -void qt_add(const char *q,const char type[2],const char *control,const char ip[4]) | |
1631 | +void qt_add(const char *q,const char type[2],const char *control,const char ip[16]) | |
1632 | { | |
1633 | struct qt x; | |
1634 | int i; | |
1635 | @@ -137,14 +138,14 @@ void qt_add(const char *q,const char type[2],const char *control,const char ip[4 | |
1636 | if (dns_domain_equal(qt.s[i].owner,q)) | |
1637 | if (dns_domain_equal(qt.s[i].control,control)) | |
1638 | if (byte_equal(qt.s[i].type,2,type)) | |
1639 | - if (byte_equal(qt.s[i].ip,4,ip)) | |
1640 | + if (byte_equal(qt.s[i].ip,16,ip)) | |
1641 | return; | |
1642 | ||
1643 | byte_zero(&x,sizeof x); | |
1644 | if (!dns_domain_copy(&x.owner,q)) nomem(); | |
1645 | if (!dns_domain_copy(&x.control,control)) nomem(); | |
1646 | byte_copy(x.type,2,type); | |
1647 | - byte_copy(x.ip,4,ip); | |
1648 | + byte_copy(x.ip,16,ip); | |
1649 | if (!qt_alloc_append(&qt,&x)) nomem(); | |
1650 | } | |
1651 | ||
1652 | @@ -203,7 +204,7 @@ void ns_add(const char *owner,const char *server) | |
1653 | qt_add(query.s[i].owner,query.s[i].type,owner,address.s[j].ip); | |
1654 | } | |
1655 | ||
1656 | -void address_add(const char *owner,const char ip[4]) | |
1657 | +void address_add(const char *owner,const char ip[16]) | |
1658 | { | |
1659 | struct address x; | |
1660 | int i; | |
1661 | @@ -213,17 +214,20 @@ void address_add(const char *owner,const char ip[4]) | |
1662 | buffer_puts(buffer_1,"A:"); | |
1663 | printdomain(owner); | |
1664 | buffer_puts(buffer_1,":"); | |
1665 | - buffer_put(buffer_1,ipstr,ip4_fmt(ipstr,ip)); | |
1666 | + if (ip6_isv4mapped(ip)) | |
1667 | + buffer_put(buffer_1,ipstr,ip4_fmt(ipstr,ip+12)); | |
1668 | + else | |
1669 | + buffer_put(buffer_1,ipstr,ip6_fmt(ipstr,ip)); | |
1670 | buffer_puts(buffer_1,"\n"); | |
1671 | ||
1672 | for (i = 0;i < address.len;++i) | |
1673 | if (dns_domain_equal(address.s[i].owner,owner)) | |
1674 | - if (byte_equal(address.s[i].ip,4,ip)) | |
1675 | + if (byte_equal(address.s[i].ip,16,ip)) | |
1676 | return; | |
1677 | ||
1678 | byte_zero(&x,sizeof x); | |
1679 | if (!dns_domain_copy(&x.owner,owner)) nomem(); | |
1680 | - byte_copy(x.ip,4,ip); | |
1681 | + byte_copy(x.ip,16,ip); | |
1682 | if (!address_alloc_append(&address,&x)) nomem(); | |
1683 | ||
1684 | for (i = 0;i < ns.len;++i) | |
1685 | @@ -331,7 +335,12 @@ void parsepacket(const char *buf,unsigned int len,const char *d,const char dtype | |
1686 | ns_add(t1,t2); | |
1687 | } | |
1688 | else if (typematch(header,DNS_T_A) && datalen == 4) { | |
1689 | - if (!dns_packet_copy(buf,len,pos,misc,4)) goto DIE; | |
1690 | + if (!dns_packet_copy(buf,len,pos,misc+12,4)) goto DIE; | |
1691 | + byte_copy(misc,12,V4mappedprefix); | |
1692 | + address_add(t1,misc); | |
1693 | + } | |
1694 | + else if (typematch(header,DNS_T_AAAA) && datalen == 16) { | |
1695 | + if (!dns_packet_copy(buf,len,pos,misc,16)) goto DIE; | |
1696 | address_add(t1,misc); | |
1697 | } | |
1698 | } | |
1699 | @@ -419,8 +428,8 @@ int main(int argc,char **argv) | |
1700 | ||
1701 | while (*++argv) { | |
1702 | if (!stralloc_copys(&udn,*argv)) nomem(); | |
1703 | - if (dns_ip4_qualify(&out,&fqdn,&udn) == -1) nomem(); /* XXX */ | |
1704 | - for (i = 0;i + 4 <= out.len;i += 4) | |
1705 | + if (dns_ip6_qualify(&out,&fqdn,&udn) == -1) nomem(); /* XXX */ | |
1706 | + for (i = 0;i + 16 <= out.len;i += 16) | |
1707 | address_add("",out.s + i); | |
1708 | } | |
1709 | ||
1710 | @@ -429,7 +438,7 @@ int main(int argc,char **argv) | |
1711 | control = qt.s[i].control; | |
1712 | if (!dns_domain_suffix(q,control)) continue; | |
1713 | byte_copy(type,2,qt.s[i].type); | |
1714 | - byte_copy(ip,4,qt.s[i].ip); | |
1715 | + byte_copy(ip,16,qt.s[i].ip); | |
1716 | ||
1717 | if (!stralloc_copys(&querystr,"")) nomem(); | |
1718 | uint16_unpack_big(type,&u16); | |
1719 | @@ -439,7 +448,10 @@ int main(int argc,char **argv) | |
1720 | if (!stralloc_cats(&querystr,":")) nomem(); | |
1721 | if (!dns_domain_todot_cat(&querystr,control)) nomem(); | |
1722 | if (!stralloc_cats(&querystr,":")) nomem(); | |
1723 | - if (!stralloc_catb(&querystr,ipstr,ip4_fmt(ipstr,ip))) nomem(); | |
1724 | + if (ip6_isv4mapped(ip)) { | |
1725 | + if (!stralloc_catb(&querystr,ipstr,ip4_fmt(ipstr,ip+12))) nomem(); | |
1726 | + } else | |
1727 | + if (!stralloc_catb(&querystr,ipstr,ip6_fmt(ipstr,ip))) nomem(); | |
1728 | if (!stralloc_cats(&querystr,":")) nomem(); | |
1729 | ||
1730 | buffer_put(buffer_1,querystr.s,querystr.len); | |
1731 | diff --git a/error.h b/error.h | |
1732 | index 35c976e..9cdd527 100644 | |
1733 | --- a/error.h | |
1734 | +++ b/error.h | |
1735 | @@ -1,7 +1,7 @@ | |
1736 | #ifndef ERROR_H | |
1737 | #define ERROR_H | |
1738 | ||
1739 | -extern int errno; | |
1740 | +#include <errno.h> | |
1741 | ||
1742 | extern int error_intr; | |
1743 | extern int error_nomem; | |
1744 | diff --git a/fmt_xlong.c b/fmt_xlong.c | |
1745 | new file mode 100644 | |
1746 | index 0000000..332fc9a | |
1747 | --- /dev/null | |
1748 | +++ b/fmt_xlong.c | |
1749 | @@ -0,0 +1,22 @@ | |
1750 | +#include "fmt.h" | |
1751 | + | |
1752 | +char tohex(char num) { | |
1753 | + if (num<10) | |
1754 | + return num+'0'; | |
1755 | + else if (num<16) | |
1756 | + return num-10+'a'; | |
1757 | + else | |
1758 | + return -1; | |
1759 | +} | |
1760 | + | |
1761 | +unsigned int fmt_xlong(register char *s,register unsigned long u) | |
1762 | +{ | |
1763 | + register unsigned int len; register unsigned long q; | |
1764 | + len = 1; q = u; | |
1765 | + while (q > 15) { ++len; q /= 16; } | |
1766 | + if (s) { | |
1767 | + s += len; | |
1768 | + do { *--s = tohex(u % 16); u /= 16; } while(u); /* handles u == 0 */ | |
1769 | + } | |
1770 | + return len; | |
1771 | +} | |
1772 | diff --git a/haveip6.h1 b/haveip6.h1 | |
1773 | new file mode 100644 | |
1774 | index 0000000..8b13789 | |
1775 | --- /dev/null | |
1776 | +++ b/haveip6.h1 | |
1777 | @@ -0,0 +1 @@ | |
1778 | + | |
1779 | diff --git a/haveip6.h2 b/haveip6.h2 | |
1780 | new file mode 100644 | |
1781 | index 0000000..5564de9 | |
1782 | --- /dev/null | |
1783 | +++ b/haveip6.h2 | |
1784 | @@ -0,0 +1 @@ | |
1785 | +#define LIBC_HAS_IP6 1 | |
1786 | diff --git a/haven2i.h1 b/haven2i.h1 | |
1787 | new file mode 100644 | |
1788 | index 0000000..732c485 | |
1789 | --- /dev/null | |
1790 | +++ b/haven2i.h1 | |
1791 | @@ -0,0 +1 @@ | |
1792 | +#undef HAVE_N2I | |
1793 | diff --git a/haven2i.h2 b/haven2i.h2 | |
1794 | new file mode 100644 | |
1795 | index 0000000..fd50644 | |
1796 | --- /dev/null | |
1797 | +++ b/haven2i.h2 | |
1798 | @@ -0,0 +1 @@ | |
1799 | +#define HAVE_N2I | |
1800 | diff --git a/hier.c b/hier.c | |
1801 | index b57dba0..e4b1a7f 100644 | |
1802 | --- a/hier.c | |
1803 | +++ b/hier.c | |
1804 | @@ -32,7 +32,9 @@ void hier() | |
1805 | c(auto_home,"bin","axfr-get",-1,-1,0755); | |
1806 | ||
1807 | c(auto_home,"bin","dnsip",-1,-1,0755); | |
1808 | + c(auto_home,"bin","dnsip6",-1,-1,0755); | |
1809 | c(auto_home,"bin","dnsipq",-1,-1,0755); | |
1810 | + c(auto_home,"bin","dnsip6q",-1,-1,0755); | |
1811 | c(auto_home,"bin","dnsname",-1,-1,0755); | |
1812 | c(auto_home,"bin","dnstxt",-1,-1,0755); | |
1813 | c(auto_home,"bin","dnsmx",-1,-1,0755); | |
1814 | diff --git a/ip6.h b/ip6.h | |
1815 | new file mode 100644 | |
1816 | index 0000000..c1135e9 | |
1817 | --- /dev/null | |
1818 | +++ b/ip6.h | |
1819 | @@ -0,0 +1,28 @@ | |
1820 | +#ifndef IP6_H | |
1821 | +#define IP6_H | |
1822 | + | |
1823 | +extern unsigned int ip6_scan(const char *,char *); | |
1824 | +extern unsigned int ip6_fmt(char *,const char *); | |
1825 | + | |
1826 | +extern unsigned int ip6_scan_flat(const char *,char *); | |
1827 | +extern unsigned int ip6_fmt_flat(char *,char *); | |
1828 | + | |
1829 | +/* | |
1830 | + ip6 address syntax: (h = hex digit), no leading '0' required | |
1831 | + 1. hhhh:hhhh:hhhh:hhhh:hhhh:hhhh:hhhh:hhhh | |
1832 | + 2. any number of 0000 may be abbreviated as "::", but only once | |
1833 | + flat ip6 address syntax: | |
1834 | + hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh | |
1835 | + */ | |
1836 | + | |
1837 | +#define IP6_FMT 40 | |
1838 | + | |
1839 | +const static unsigned char V4mappedprefix[12]={0,0,0,0,0,0,0,0,0,0,0xff,0xff}; | |
1840 | +const static unsigned char V6loopback[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; | |
1841 | +const static unsigned char V6any[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; | |
1842 | + | |
1843 | +#define ip6_isv4mapped(ip) (byte_equal(ip,12,V4mappedprefix)) | |
1844 | + | |
1845 | +const static char ip4loopback[4] = {127,0,0,1}; | |
1846 | + | |
1847 | +#endif | |
1848 | diff --git a/ip6_fmt.c b/ip6_fmt.c | |
1849 | new file mode 100644 | |
1850 | index 0000000..b2444bb | |
1851 | --- /dev/null | |
1852 | +++ b/ip6_fmt.c | |
1853 | @@ -0,0 +1,60 @@ | |
1854 | +#include "fmt.h" | |
1855 | +#include "byte.h" | |
1856 | +#include "ip4.h" | |
1857 | +#include "ip6.h" | |
1858 | +#include <stdio.h> | |
1859 | + | |
1860 | +extern char tohex(char num); | |
1861 | + | |
1862 | +unsigned int ip6_fmt(char *s,const char ip[16]) | |
1863 | +{ | |
1864 | + unsigned int len; | |
1865 | + unsigned int i; | |
1866 | + unsigned int temp; | |
1867 | + unsigned int compressing; | |
1868 | + unsigned int compressed; | |
1869 | + int j; | |
1870 | + | |
1871 | + len = 0; compressing = 0; compressed = 0; | |
1872 | + for (j=0; j<16; j+=2) { | |
1873 | + if (j==12 && ip6_isv4mapped(ip)) { | |
1874 | + temp=ip4_fmt(s,ip+12); | |
1875 | + len+=temp; | |
1876 | + break; | |
1877 | + } | |
1878 | + temp = ((unsigned long) (unsigned char) ip[j] << 8) + | |
1879 | + (unsigned long) (unsigned char) ip[j+1]; | |
1880 | + if (temp == 0 && !compressed) { | |
1881 | + if (!compressing) { | |
1882 | + compressing=1; | |
1883 | + if (j==0) { | |
1884 | + if (s) *s++=':'; ++len; | |
1885 | + } | |
1886 | + } | |
1887 | + } else { | |
1888 | + if (compressing) { | |
1889 | + compressing=0; ++compressed; | |
1890 | + if (s) *s++=':'; ++len; | |
1891 | + } | |
1892 | + i = fmt_xlong(s,temp); len += i; if (s) s += i; | |
1893 | + if (j<14) { | |
1894 | + if (s) *s++ = ':'; | |
1895 | + ++len; | |
1896 | + } | |
1897 | + } | |
1898 | + } | |
1899 | + if (compressing) { *s++=':'; ++len; } | |
1900 | + | |
1901 | +/* if (s) *s=0; */ | |
1902 | + return len; | |
1903 | +} | |
1904 | + | |
1905 | +unsigned int ip6_fmt_flat(char *s,char ip[16]) | |
1906 | +{ | |
1907 | + int i; | |
1908 | + for (i=0; i<16; i++) { | |
1909 | + *s++=tohex((unsigned char)ip[i] >> 4); | |
1910 | + *s++=tohex((unsigned char)ip[i] & 15); | |
1911 | + } | |
1912 | + return 32; | |
1913 | +} | |
1914 | diff --git a/ip6_scan.c b/ip6_scan.c | |
1915 | new file mode 100644 | |
1916 | index 0000000..f355d46 | |
1917 | --- /dev/null | |
1918 | +++ b/ip6_scan.c | |
1919 | @@ -0,0 +1,115 @@ | |
1920 | +#include "scan.h" | |
1921 | +#include "ip4.h" | |
1922 | +#include "ip6.h" | |
1923 | +#include "byte.h" | |
1924 | + | |
1925 | +/* | |
1926 | + * IPv6 addresses are really ugly to parse. | |
1927 | + * Syntax: (h = hex digit) | |
1928 | + * 1. hhhh:hhhh:hhhh:hhhh:hhhh:hhhh:hhhh:hhhh | |
1929 | + * 2. any number of 0000 may be abbreviated as "::", but only once | |
1930 | + * 3. The last two words may be written as IPv4 address | |
1931 | + */ | |
1932 | + | |
1933 | +unsigned int ip6_scan(const char *s,char ip[16]) | |
1934 | +{ | |
1935 | + unsigned int i; | |
1936 | + unsigned int len=0; | |
1937 | + unsigned long u; | |
1938 | + | |
1939 | + char suffix[16]; | |
1940 | + int prefixlen=0; | |
1941 | + int suffixlen=0; | |
1942 | + | |
1943 | + if ((i=ip4_scan(s,ip+12))) { | |
1944 | + const char *c=V4mappedprefix; | |
1945 | + if (byte_equal(ip+12,4,V6any)) c=V6any; | |
1946 | + for (len=0; len<12; ++len) ip[len]=c[len]; | |
1947 | + return i; | |
1948 | + } | |
1949 | + for (i=0; i<16; i++) ip[i]=0; | |
1950 | + for (;;) { | |
1951 | + if (*s == ':') { | |
1952 | + len++; | |
1953 | + if (s[1] == ':') { /* Found "::", skip to part 2 */ | |
1954 | + s+=2; | |
1955 | + len++; | |
1956 | + break; | |
1957 | + } | |
1958 | + s++; | |
1959 | + } | |
1960 | + i = scan_xlong(s,&u); | |
1961 | + if (!i) return 0; | |
1962 | + if (prefixlen==12 && s[i]=='.') { | |
1963 | + /* the last 4 bytes may be written as IPv4 address */ | |
1964 | + i=ip4_scan(s,ip+12); | |
1965 | + if (i) | |
1966 | + return i+len; | |
1967 | + else | |
1968 | + return 0; | |
1969 | + } | |
1970 | + ip[prefixlen++] = (u >> 8); | |
1971 | + ip[prefixlen++] = (u & 255); | |
1972 | + s += i; len += i; | |
1973 | + if (prefixlen==16) | |
1974 | + return len; | |
1975 | + } | |
1976 | + | |
1977 | +/* part 2, after "::" */ | |
1978 | + for (;;) { | |
1979 | + if (*s == ':') { | |
1980 | + if (suffixlen==0) | |
1981 | + break; | |
1982 | + s++; | |
1983 | + len++; | |
1984 | + } else if (suffixlen!=0) | |
1985 | + break; | |
1986 | + i = scan_xlong(s,&u); | |
1987 | + if (!i) { | |
1988 | + len--; | |
1989 | + break; | |
1990 | + } | |
1991 | + if (suffixlen+prefixlen<=12 && s[i]=='.') { | |
1992 | + int j=ip4_scan(s,suffix+suffixlen); | |
1993 | + if (j) { | |
1994 | + suffixlen+=4; | |
1995 | + len+=j; | |
1996 | + break; | |
1997 | + } else | |
1998 | + prefixlen=12-suffixlen; /* make end-of-loop test true */ | |
1999 | + } | |
2000 | + suffix[suffixlen++] = (u >> 8); | |
2001 | + suffix[suffixlen++] = (u & 255); | |
2002 | + s += i; len += i; | |
2003 | + if (prefixlen+suffixlen==16) | |
2004 | + break; | |
2005 | + } | |
2006 | + for (i=0; i<suffixlen; i++) | |
2007 | + ip[16-suffixlen+i] = suffix[i]; | |
2008 | + return len; | |
2009 | +} | |
2010 | + | |
2011 | +static long int fromhex(unsigned char c) { | |
2012 | + if (c>='0' && c<='9') | |
2013 | + return c-'0'; | |
2014 | + else if (c>='A' && c<='F') | |
2015 | + return c-'A'+10; | |
2016 | + else if (c>='a' && c<='f') | |
2017 | + return c-'a'+10; | |
2018 | + return -1; | |
2019 | +} | |
2020 | + | |
2021 | +unsigned int ip6_scan_flat(const char *s,char ip[16]) | |
2022 | +{ | |
2023 | + int i; | |
2024 | + for (i=0; i<16; i++) { | |
2025 | + int tmp; | |
2026 | + tmp=fromhex(*s++); | |
2027 | + if (tmp<0) return 0; | |
2028 | + ip[i]=tmp << 4; | |
2029 | + tmp=fromhex(*s++); | |
2030 | + if (tmp<0) return 0; | |
2031 | + ip[i]+=tmp; | |
2032 | + } | |
2033 | + return 32; | |
2034 | +} | |
2035 | diff --git a/log.c b/log.c | |
2036 | index c43e8b0..df465e2 100644 | |
2037 | --- a/log.c | |
2038 | +++ b/log.c | |
2039 | @@ -3,6 +3,7 @@ | |
2040 | #include "uint16.h" | |
2041 | #include "error.h" | |
2042 | #include "byte.h" | |
2043 | +#include "ip6.h" | |
2044 | #include "log.h" | |
2045 | ||
2046 | /* work around gcc 2.95.2 bug */ | |
2047 | @@ -45,12 +46,10 @@ static void space(void) | |
2048 | string(" "); | |
2049 | } | |
2050 | ||
2051 | -static void ip(const char i[4]) | |
2052 | +static void ip(const char i[16]) | |
2053 | { | |
2054 | - hex(i[0]); | |
2055 | - hex(i[1]); | |
2056 | - hex(i[2]); | |
2057 | - hex(i[3]); | |
2058 | + int j; | |
2059 | + for (j=0; j<16; ++j) hex(i[j]); | |
2060 | } | |
2061 | ||
2062 | static void logid(const char id[2]) | |
2063 | @@ -94,7 +93,7 @@ void log_startup(void) | |
2064 | line(); | |
2065 | } | |
2066 | ||
2067 | -void log_query(uint64 *qnum,const char client[4],unsigned int port,const char id[2],const char *q,const char qtype[2]) | |
2068 | +void log_query(uint64 *qnum,const char client[16],unsigned int port,const char id[2],const char *q,const char qtype[2]) | |
2069 | { | |
2070 | string("query "); number(*qnum); space(); | |
2071 | ip(client); string(":"); hex(port >> 8); hex(port & 255); | |
2072 | @@ -119,14 +118,14 @@ void log_querydrop(uint64 *qnum) | |
2073 | line(); | |
2074 | } | |
2075 | ||
2076 | -void log_tcpopen(const char client[4],unsigned int port) | |
2077 | +void log_tcpopen(const char client[16],unsigned int port) | |
2078 | { | |
2079 | string("tcpopen "); | |
2080 | ip(client); string(":"); hex(port >> 8); hex(port & 255); | |
2081 | line(); | |
2082 | } | |
2083 | ||
2084 | -void log_tcpclose(const char client[4],unsigned int port) | |
2085 | +void log_tcpclose(const char client[16],unsigned int port) | |
2086 | { | |
2087 | const char *x = error_str(errno); | |
2088 | string("tcpclose "); | |
2089 | @@ -135,15 +134,15 @@ void log_tcpclose(const char client[4],unsigned int port) | |
2090 | line(); | |
2091 | } | |
2092 | ||
2093 | -void log_tx(const char *q,const char qtype[2],const char *control,const char servers[64],unsigned int gluelessness) | |
2094 | +void log_tx(const char *q,const char qtype[2],const char *control,const char servers[256],unsigned int gluelessness) | |
2095 | { | |
2096 | int i; | |
2097 | ||
2098 | string("tx "); number(gluelessness); space(); | |
2099 | logtype(qtype); space(); name(q); space(); | |
2100 | name(control); | |
2101 | - for (i = 0;i < 64;i += 4) | |
2102 | - if (byte_diff(servers + i,4,"\0\0\0\0")) { | |
2103 | + for (i = 0;i < 256;i += 16) | |
2104 | + if (byte_diff(servers + i,16,V6any)) { | |
2105 | space(); | |
2106 | ip(servers + i); | |
2107 | } | |
2108 | @@ -175,21 +174,21 @@ void log_cachednxdomain(const char *dn) | |
2109 | line(); | |
2110 | } | |
2111 | ||
2112 | -void log_nxdomain(const char server[4],const char *q,unsigned int ttl) | |
2113 | +void log_nxdomain(const char server[16],const char *q,unsigned int ttl) | |
2114 | { | |
2115 | string("nxdomain "); ip(server); space(); number(ttl); space(); | |
2116 | name(q); | |
2117 | line(); | |
2118 | } | |
2119 | ||
2120 | -void log_nodata(const char server[4],const char *q,const char qtype[2],unsigned int ttl) | |
2121 | +void log_nodata(const char server[16],const char *q,const char qtype[2],unsigned int ttl) | |
2122 | { | |
2123 | string("nodata "); ip(server); space(); number(ttl); space(); | |
2124 | logtype(qtype); space(); name(q); | |
2125 | line(); | |
2126 | } | |
2127 | ||
2128 | -void log_lame(const char server[4],const char *control,const char *referral) | |
2129 | +void log_lame(const char server[16],const char *control,const char *referral) | |
2130 | { | |
2131 | string("lame "); ip(server); space(); | |
2132 | name(control); space(); name(referral); | |
2133 | @@ -205,7 +204,7 @@ void log_servfail(const char *dn) | |
2134 | line(); | |
2135 | } | |
2136 | ||
2137 | -void log_rr(const char server[4],const char *q,const char type[2],const char *buf,unsigned int len,unsigned int ttl) | |
2138 | +void log_rr(const char server[16],const char *q,const char type[2],const char *buf,unsigned int len,unsigned int ttl) | |
2139 | { | |
2140 | int i; | |
2141 | ||
2142 | @@ -222,7 +221,7 @@ void log_rr(const char server[4],const char *q,const char type[2],const char *bu | |
2143 | line(); | |
2144 | } | |
2145 | ||
2146 | -void log_rrns(const char server[4],const char *q,const char *data,unsigned int ttl) | |
2147 | +void log_rrns(const char server[16],const char *q,const char *data,unsigned int ttl) | |
2148 | { | |
2149 | string("rr "); ip(server); space(); number(ttl); | |
2150 | string(" ns "); name(q); space(); | |
2151 | @@ -230,7 +229,7 @@ void log_rrns(const char server[4],const char *q,const char *data,unsigned int t | |
2152 | line(); | |
2153 | } | |
2154 | ||
2155 | -void log_rrcname(const char server[4],const char *q,const char *data,unsigned int ttl) | |
2156 | +void log_rrcname(const char server[16],const char *q,const char *data,unsigned int ttl) | |
2157 | { | |
2158 | string("rr "); ip(server); space(); number(ttl); | |
2159 | string(" cname "); name(q); space(); | |
2160 | @@ -238,7 +237,7 @@ void log_rrcname(const char server[4],const char *q,const char *data,unsigned in | |
2161 | line(); | |
2162 | } | |
2163 | ||
2164 | -void log_rrptr(const char server[4],const char *q,const char *data,unsigned int ttl) | |
2165 | +void log_rrptr(const char server[16],const char *q,const char *data,unsigned int ttl) | |
2166 | { | |
2167 | string("rr "); ip(server); space(); number(ttl); | |
2168 | string(" ptr "); name(q); space(); | |
2169 | @@ -246,7 +245,7 @@ void log_rrptr(const char server[4],const char *q,const char *data,unsigned int | |
2170 | line(); | |
2171 | } | |
2172 | ||
2173 | -void log_rrmx(const char server[4],const char *q,const char *mx,const char pref[2],unsigned int ttl) | |
2174 | +void log_rrmx(const char server[16],const char *q,const char *mx,const char pref[2],unsigned int ttl) | |
2175 | { | |
2176 | uint16 u; | |
2177 | ||
2178 | @@ -257,7 +256,7 @@ void log_rrmx(const char server[4],const char *q,const char *mx,const char pref[ | |
2179 | line(); | |
2180 | } | |
2181 | ||
2182 | -void log_rrsoa(const char server[4],const char *q,const char *n1,const char *n2,const char misc[20],unsigned int ttl) | |
2183 | +void log_rrsoa(const char server[16],const char *q,const char *n1,const char *n2,const char misc[20],unsigned int ttl) | |
2184 | { | |
2185 | uint32 u; | |
2186 | int i; | |
2187 | diff --git a/okclient.c b/okclient.c | |
2188 | index a648c02..9a0d3c6 100644 | |
2189 | --- a/okclient.c | |
2190 | +++ b/okclient.c | |
2191 | @@ -2,24 +2,34 @@ | |
2192 | #include <sys/stat.h> | |
2193 | #include "str.h" | |
2194 | #include "ip4.h" | |
2195 | +#include "ip6.h" | |
2196 | +#include "byte.h" | |
2197 | #include "okclient.h" | |
2198 | ||
2199 | -static char fn[3 + IP4_FMT]; | |
2200 | +static char fn[3 + IP6_FMT]; | |
2201 | ||
2202 | -int okclient(char ip[4]) | |
2203 | +int okclient(char ip[16]) | |
2204 | { | |
2205 | struct stat st; | |
2206 | int i; | |
2207 | + char sep; | |
2208 | ||
2209 | fn[0] = 'i'; | |
2210 | fn[1] = 'p'; | |
2211 | fn[2] = '/'; | |
2212 | - fn[3 + ip4_fmt(fn + 3,ip)] = 0; | |
2213 | + if (byte_equal(ip,12,V4mappedprefix)) { | |
2214 | + fn[3 + ip4_fmt(fn + 3,ip+12)] = 0; | |
2215 | + sep='.'; | |
2216 | + } else { | |
2217 | + fn[3 + ip6_fmt(fn + 3,ip)] = 0; | |
2218 | + sep=':'; | |
2219 | + } | |
2220 | ||
2221 | for (;;) { | |
2222 | + if (!fn[3]) return 0; | |
2223 | if (stat(fn,&st) == 0) return 1; | |
2224 | /* treat temporary error as rejection */ | |
2225 | - i = str_rchr(fn,'.'); | |
2226 | + i = str_rchr(fn,sep); | |
2227 | if (!fn[i]) return 0; | |
2228 | fn[i] = 0; | |
2229 | } | |
2230 | diff --git a/printrecord.c b/printrecord.c | |
2231 | index ed0b42d..4bc7c3e 100644 | |
2232 | --- a/printrecord.c | |
2233 | +++ b/printrecord.c | |
2234 | @@ -4,6 +4,7 @@ | |
2235 | #include "byte.h" | |
2236 | #include "dns.h" | |
2237 | #include "printrecord.h" | |
2238 | +#include "ip6.h" | |
2239 | ||
2240 | static char *d; | |
2241 | ||
2242 | @@ -82,6 +83,15 @@ unsigned int printrecord_cat(stralloc *out,const char *buf,unsigned int len,unsi | |
2243 | if (!stralloc_catulong0(out,ch,0)) return 0; | |
2244 | } | |
2245 | } | |
2246 | + else if (byte_equal(misc,2,DNS_T_AAAA)) { | |
2247 | + char ip6str[IP6_FMT]; | |
2248 | + int stringlen; | |
2249 | + if (datalen != 16) { errno = error_proto; return 0; } | |
2250 | + if (!stralloc_cats(out," AAAA ")) return 0; | |
2251 | + pos = dns_packet_copy(buf,len,pos,misc,16); if (!pos) return 0; | |
2252 | + stringlen=ip6_fmt(ip6str,misc); | |
2253 | + if (!stralloc_catb(out,ip6str,stringlen)) return 0; | |
2254 | + } | |
2255 | else { | |
2256 | if (!stralloc_cats(out," ")) return 0; | |
2257 | uint16_unpack_big(misc,&u16); | |
2258 | diff --git a/qlog.c b/qlog.c | |
2259 | index 5c5c7ba..60816df 100644 | |
2260 | --- a/qlog.c | |
2261 | +++ b/qlog.c | |
2262 | @@ -20,15 +20,15 @@ static void octal(unsigned char c) | |
2263 | put('0' + (c & 7)); | |
2264 | } | |
2265 | ||
2266 | -void qlog(const char ip[4],uint16 port,const char id[2],const char *q,const char qtype[2],const char *result) | |
2267 | +void qlog(const char ip[16],uint16 port,const char id[2],const char *q,const char qtype[2],const char *result) | |
2268 | { | |
2269 | char ch; | |
2270 | char ch2; | |
2271 | ||
2272 | - hex(ip[0]); | |
2273 | - hex(ip[1]); | |
2274 | - hex(ip[2]); | |
2275 | - hex(ip[3]); | |
2276 | + { | |
2277 | + int i; | |
2278 | + for (i=0; i<16; ++i) hex(ip[i]); | |
2279 | + } | |
2280 | put(':'); | |
2281 | hex(port >> 8); | |
2282 | hex(port & 255); | |
2283 | diff --git a/query.c b/query.c | |
2284 | index 46cdc00..e0f48b3 100644 | |
2285 | --- a/query.c | |
2286 | +++ b/query.c | |
2287 | @@ -12,6 +12,9 @@ | |
2288 | #include "alloc.h" | |
2289 | #include "response.h" | |
2290 | #include "query.h" | |
2291 | +#include "ip6.h" | |
2292 | + | |
2293 | +extern stralloc ignoreip; | |
2294 | ||
2295 | static int flagforwardonly = 0; | |
2296 | ||
2297 | @@ -110,7 +113,7 @@ static int rqa(struct query *z) | |
2298 | return 1; | |
2299 | } | |
2300 | ||
2301 | -static int globalip(char *d,char ip[4]) | |
2302 | +static int globalip(char *d,char ip[16]) | |
2303 | { | |
2304 | if (dns_domain_equal(d,"\011localhost\0")) { | |
2305 | byte_copy(ip,4,"\177\0\0\1"); | |
2306 | @@ -165,7 +168,7 @@ static int doit(struct query *z,int state) | |
2307 | char *buf; | |
2308 | unsigned int len; | |
2309 | const char *whichserver; | |
2310 | - char header[12]; | |
2311 | + char header[24]; | |
2312 | char misc[20]; | |
2313 | unsigned int rcode; | |
2314 | unsigned int posanswers; | |
2315 | @@ -193,6 +196,7 @@ static int doit(struct query *z,int state) | |
2316 | int k; | |
2317 | int p; | |
2318 | int q; | |
2319 | + unsigned int ii; | |
2320 | ||
2321 | errno = error_io; | |
2322 | if (state == 1) goto HAVEPACKET; | |
2323 | @@ -210,9 +214,10 @@ static int doit(struct query *z,int state) | |
2324 | ||
2325 | if (globalip(d,misc)) { | |
2326 | if (z->level) { | |
2327 | - for (k = 0;k < 64;k += 4) | |
2328 | - if (byte_equal(z->servers[z->level - 1] + k,4,"\0\0\0\0")) { | |
2329 | - byte_copy(z->servers[z->level - 1] + k,4,misc); | |
2330 | + for (k = 0;k < 256;k += 16) | |
2331 | + if (byte_equal(z->servers[z->level - 1] + k,16,V6any)) { | |
2332 | + byte_copy(z->servers[z->level - 1] + k,12,V4mappedprefix); | |
2333 | + byte_copy(z->servers[z->level - 1] + k + 12,4,misc); | |
2334 | break; | |
2335 | } | |
2336 | goto LOWERLEVEL; | |
2337 | @@ -227,6 +232,158 @@ static int doit(struct query *z,int state) | |
2338 | return 1; | |
2339 | } | |
2340 | ||
2341 | + if (dns_domain_equal(d,"\0011\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\003ip6\003int\0")) { | |
2342 | + if (z->level) goto LOWERLEVEL; | |
2343 | + if (!rqa(z)) goto DIE; | |
2344 | + if (typematch(DNS_T_PTR,dtype)) { | |
2345 | + if (!response_rstart(d,DNS_T_PTR,655360)) goto DIE; | |
2346 | + if (!response_addname("\016ipv6-localhost\0")) goto DIE; | |
2347 | + if (!response_addname("\015ipv6-loopback\0")) goto DIE; | |
2348 | + response_rfinish(RESPONSE_ANSWER); | |
2349 | + } | |
2350 | + cleanup(z); | |
2351 | + return 1; | |
2352 | + } | |
2353 | + | |
2354 | + if (dns_domain_equal(d,"\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\001e\001f\003ip6\003int\0")) { | |
2355 | + if (z->level) goto LOWERLEVEL; | |
2356 | + if (!rqa(z)) goto DIE; | |
2357 | + if (typematch(DNS_T_PTR,dtype)) { | |
2358 | + if (!response_rstart(d,DNS_T_PTR,655360)) goto DIE; | |
2359 | + if (!response_addname("\015ipv6-localnet\0")) goto DIE; | |
2360 | + response_rfinish(RESPONSE_ANSWER); | |
2361 | + } | |
2362 | + cleanup(z); | |
2363 | + return 1; | |
2364 | + } | |
2365 | + | |
2366 | + if (dns_domain_equal(d,"\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\001f\001f\003ip6\003int\0")) { | |
2367 | + if (z->level) goto LOWERLEVEL; | |
2368 | + if (!rqa(z)) goto DIE; | |
2369 | + if (typematch(DNS_T_PTR,dtype)) { | |
2370 | + if (!response_rstart(d,DNS_T_PTR,655360)) goto DIE; | |
2371 | + if (!response_addname("\020ipv6-mcastprefix\0")) goto DIE; | |
2372 | + response_rfinish(RESPONSE_ANSWER); | |
2373 | + } | |
2374 | + cleanup(z); | |
2375 | + return 1; | |
2376 | + } | |
2377 | + | |
2378 | + if (dns_domain_equal(d,"\0011\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0012\0010\001f\001f\003ip6\003int\0")) { | |
2379 | + if (z->level) goto LOWERLEVEL; | |
2380 | + if (!rqa(z)) goto DIE; | |
2381 | + if (typematch(DNS_T_PTR,dtype)) { | |
2382 | + if (!response_rstart(d,DNS_T_PTR,655360)) goto DIE; | |
2383 | + if (!response_addname("\015ipv6-allnodes\0")) goto DIE; | |
2384 | + response_rfinish(RESPONSE_ANSWER); | |
2385 | + } | |
2386 | + cleanup(z); | |
2387 | + return 1; | |
2388 | + } | |
2389 | + | |
2390 | + if (dns_domain_equal(d,"\0012\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0012\0010\001f\001f\003ip6\003int\0")) { | |
2391 | + if (z->level) goto LOWERLEVEL; | |
2392 | + if (!rqa(z)) goto DIE; | |
2393 | + if (typematch(DNS_T_PTR,dtype)) { | |
2394 | + if (!response_rstart(d,DNS_T_PTR,655360)) goto DIE; | |
2395 | + if (!response_addname("\017ipv6-allrouters\0")) goto DIE; | |
2396 | + response_rfinish(RESPONSE_ANSWER); | |
2397 | + } | |
2398 | + cleanup(z); | |
2399 | + return 1; | |
2400 | + } | |
2401 | + | |
2402 | + if (dns_domain_equal(d,"\0011\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0010\0012\0010\001f\001f\003ip6\003int\0")) { | |
2403 | + if (z->level) goto LOWERLEVEL; | |
2404 | + if (!rqa(z)) goto DIE; | |
2405 | + if (typematch(DNS_T_PTR,dtype)) { | |
2406 | + if (!response_rstart(d,DNS_T_PTR,655360)) goto DIE; | |
2407 | + if (!response_addname("\015ipv6-allhosts\0")) goto DIE; | |
2408 | + response_rfinish(RESPONSE_ANSWER); | |
2409 | + } | |
2410 | + cleanup(z); | |
2411 | + return 1; | |
2412 | + } | |
2413 | + | |
2414 | + if (dns_domain_equal(d,"\016ipv6-localhost\0") || | |
2415 | + dns_domain_equal(d,"\015ipv6-loopback\0")) | |
2416 | + { | |
2417 | + if (z->level) goto LOWERLEVEL; | |
2418 | + if (!rqa(z)) goto DIE; | |
2419 | + if (typematch(DNS_T_AAAA,dtype)) { | |
2420 | + if (!response_rstart(d,DNS_T_AAAA,655360)) goto DIE; | |
2421 | + if (!response_addbytes("\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001",16)) goto DIE; | |
2422 | + response_rfinish(RESPONSE_ANSWER); | |
2423 | + } | |
2424 | + cleanup(z); | |
2425 | + return 1; | |
2426 | + } | |
2427 | + | |
2428 | + if (dns_domain_equal(d,"\015ipv6-localnet\0")) | |
2429 | + { | |
2430 | + if (z->level) goto LOWERLEVEL; | |
2431 | + if (!rqa(z)) goto DIE; | |
2432 | + if (typematch(DNS_T_AAAA,dtype)) { | |
2433 | + if (!response_rstart(d,DNS_T_AAAA,655360)) goto DIE; | |
2434 | + if (!response_addbytes("\376\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",16)) goto DIE; | |
2435 | + response_rfinish(RESPONSE_ANSWER); | |
2436 | + } | |
2437 | + cleanup(z); | |
2438 | + return 1; | |
2439 | + } | |
2440 | + | |
2441 | + if (dns_domain_equal(d,"\020ipv6-mcastprefix\0")) | |
2442 | + { | |
2443 | + if (z->level) goto LOWERLEVEL; | |
2444 | + if (!rqa(z)) goto DIE; | |
2445 | + if (typematch(DNS_T_AAAA,dtype)) { | |
2446 | + if (!response_rstart(d,DNS_T_AAAA,655360)) goto DIE; | |
2447 | + if (!response_addbytes("\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",16)) goto DIE; | |
2448 | + response_rfinish(RESPONSE_ANSWER); | |
2449 | + } | |
2450 | + cleanup(z); | |
2451 | + return 1; | |
2452 | + } | |
2453 | + | |
2454 | + if (dns_domain_equal(d,"\15ipv6-allnodes\0")) | |
2455 | + { | |
2456 | + if (z->level) goto LOWERLEVEL; | |
2457 | + if (!rqa(z)) goto DIE; | |
2458 | + if (typematch(DNS_T_AAAA,dtype)) { | |
2459 | + if (!response_rstart(d,DNS_T_AAAA,655360)) goto DIE; | |
2460 | + if (!response_addbytes("\377\002\000\000\000\000\000\000\000\000\000\000\000\000\000\001",16)) goto DIE; | |
2461 | + response_rfinish(RESPONSE_ANSWER); | |
2462 | + } | |
2463 | + cleanup(z); | |
2464 | + return 1; | |
2465 | + } | |
2466 | + | |
2467 | + if (dns_domain_equal(d,"\17ipv6-allrouters\0")) | |
2468 | + { | |
2469 | + if (z->level) goto LOWERLEVEL; | |
2470 | + if (!rqa(z)) goto DIE; | |
2471 | + if (typematch(DNS_T_AAAA,dtype)) { | |
2472 | + if (!response_rstart(d,DNS_T_AAAA,655360)) goto DIE; | |
2473 | + if (!response_addbytes("\377\002\000\000\000\000\000\000\000\000\000\000\000\000\000\002",16)) goto DIE; | |
2474 | + response_rfinish(RESPONSE_ANSWER); | |
2475 | + } | |
2476 | + cleanup(z); | |
2477 | + return 1; | |
2478 | + } | |
2479 | + | |
2480 | + if (dns_domain_equal(d,"\15ipv6-allhosts\0")) | |
2481 | + { | |
2482 | + if (z->level) goto LOWERLEVEL; | |
2483 | + if (!rqa(z)) goto DIE; | |
2484 | + if (typematch(DNS_T_AAAA,dtype)) { | |
2485 | + if (!response_rstart(d,DNS_T_AAAA,655360)) goto DIE; | |
2486 | + if (!response_addbytes("\377\002\000\000\000\000\000\000\000\000\000\000\000\000\000\003",16)) goto DIE; | |
2487 | + response_rfinish(RESPONSE_ANSWER); | |
2488 | + } | |
2489 | + cleanup(z); | |
2490 | + return 1; | |
2491 | + } | |
2492 | + | |
2493 | if (dns_domain_equal(d,"\0011\0010\0010\003127\7in-addr\4arpa\0")) { | |
2494 | if (z->level) goto LOWERLEVEL; | |
2495 | if (!rqa(z)) goto DIE; | |
2496 | @@ -326,9 +483,10 @@ static int doit(struct query *z,int state) | |
2497 | if (z->level) { | |
2498 | log_cachedanswer(d,DNS_T_A); | |
2499 | while (cachedlen >= 4) { | |
2500 | - for (k = 0;k < 64;k += 4) | |
2501 | - if (byte_equal(z->servers[z->level - 1] + k,4,"\0\0\0\0")) { | |
2502 | - byte_copy(z->servers[z->level - 1] + k,4,cached); | |
2503 | + for (k = 0;k < 256;k += 16) | |
2504 | + if (byte_equal(z->servers[z->level - 1] + k,16,V6any)) { | |
2505 | + byte_copy(z->servers[z->level - 1] + k,12,V4mappedprefix); | |
2506 | + byte_copy(z->servers[z->level - 1] + k + 12,4,cached); | |
2507 | break; | |
2508 | } | |
2509 | cached += 4; | |
2510 | @@ -351,7 +509,39 @@ static int doit(struct query *z,int state) | |
2511 | } | |
2512 | } | |
2513 | ||
2514 | - if (!typematch(DNS_T_ANY,dtype) && !typematch(DNS_T_AXFR,dtype) && !typematch(DNS_T_CNAME,dtype) && !typematch(DNS_T_NS,dtype) && !typematch(DNS_T_PTR,dtype) && !typematch(DNS_T_A,dtype) && !typematch(DNS_T_MX,dtype)) { | |
2515 | + if (typematch(DNS_T_AAAA,dtype)) { | |
2516 | + byte_copy(key,2,DNS_T_AAAA); | |
2517 | + cached = cache_get(key,dlen + 2,&cachedlen,&ttl); | |
2518 | + if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) { | |
2519 | + if (z->level) { | |
2520 | + log_cachedanswer(d,DNS_T_AAAA); | |
2521 | + while (cachedlen >= 16) { | |
2522 | + for (k = 0;k < 256;k += 16) | |
2523 | + if (byte_equal(z->servers[z->level - 1] + k,16,V6any)) { | |
2524 | + byte_copy(z->servers[z->level - 1] + k,16,cached); | |
2525 | + break; | |
2526 | + } | |
2527 | + cached += 16; | |
2528 | + cachedlen -= 16; | |
2529 | + } | |
2530 | + goto LOWERLEVEL; | |
2531 | + } | |
2532 | + | |
2533 | + log_cachedanswer(d,DNS_T_AAAA); | |
2534 | + if (!rqa(z)) goto DIE; | |
2535 | + while (cachedlen >= 16) { | |
2536 | + if (!response_rstart(d,DNS_T_AAAA,ttl)) goto DIE; | |
2537 | + if (!response_addbytes(cached,16)) goto DIE; | |
2538 | + response_rfinish(RESPONSE_ANSWER); | |
2539 | + cached += 16; | |
2540 | + cachedlen -= 16; | |
2541 | + } | |
2542 | + cleanup(z); | |
2543 | + return 1; | |
2544 | + } | |
2545 | + } | |
2546 | + | |
2547 | + if (!typematch(DNS_T_ANY,dtype) && !typematch(DNS_T_AXFR,dtype) && !typematch(DNS_T_CNAME,dtype) && !typematch(DNS_T_NS,dtype) && !typematch(DNS_T_PTR,dtype) && !typematch(DNS_T_A,dtype) && !typematch(DNS_T_MX,dtype) && !typematch(DNS_T_AAAA,dtype)) { | |
2548 | byte_copy(key,2,dtype); | |
2549 | cached = cache_get(key,dlen + 2,&cachedlen,&ttl); | |
2550 | if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) { | |
2551 | @@ -390,7 +580,7 @@ static int doit(struct query *z,int state) | |
2552 | cached = cache_get(key,dlen + 2,&cachedlen,&ttl); | |
2553 | if (cached && cachedlen) { | |
2554 | z->control[z->level] = d; | |
2555 | - byte_zero(z->servers[z->level],64); | |
2556 | + byte_zero(z->servers[z->level],256); | |
2557 | for (j = 0;j < QUERY_MAXNS;++j) | |
2558 | dns_domain_free(&z->ns[z->level][j]); | |
2559 | pos = 0; | |
2560 | @@ -423,12 +613,12 @@ static int doit(struct query *z,int state) | |
2561 | dns_domain_free(&z->ns[z->level][j]); | |
2562 | } | |
2563 | ||
2564 | - for (j = 0;j < 64;j += 4) | |
2565 | - if (byte_diff(z->servers[z->level] + j,4,"\0\0\0\0")) | |
2566 | + for (j = 0;j < 256;j += 16) | |
2567 | + if (byte_diff(z->servers[z->level] + j,16,V6any)) | |
2568 | break; | |
2569 | - if (j == 64) goto SERVFAIL; | |
2570 | + if (j == 256) goto SERVFAIL; | |
2571 | ||
2572 | - dns_sortip(z->servers[z->level],64); | |
2573 | + dns_sortip6(z->servers[z->level],256); | |
2574 | if (z->level) { | |
2575 | log_tx(z->name[z->level],DNS_T_A,z->control[z->level],z->servers[z->level],z->level); | |
2576 | if (dns_transmit_start(&z->dt,z->servers[z->level],flagforwardonly,z->name[z->level],DNS_T_A,z->localip) == -1) goto DIE; | |
2577 | @@ -453,7 +643,7 @@ static int doit(struct query *z,int state) | |
2578 | buf = z->dt.packet; | |
2579 | len = z->dt.packetlen; | |
2580 | ||
2581 | - whichserver = z->dt.servers + 4 * z->dt.curserver; | |
2582 | + whichserver = z->dt.servers + 16 * z->dt.curserver; | |
2583 | control = z->control[z->level]; | |
2584 | d = z->name[z->level]; | |
2585 | dtype = z->level ? DNS_T_A : z->type; | |
2586 | @@ -519,7 +709,7 @@ static int doit(struct query *z,int state) | |
2587 | if (!flagcname && !rcode && !flagout && flagreferral && !flagsoa) | |
2588 | if (dns_domain_equal(referral,control) || !dns_domain_suffix(referral,control)) { | |
2589 | log_lame(whichserver,control,referral); | |
2590 | - byte_zero(whichserver,4); | |
2591 | + byte_zero(whichserver,16); | |
2592 | goto HAVENS; | |
2593 | } | |
2594 | ||
2595 | @@ -643,6 +833,11 @@ static int doit(struct query *z,int state) | |
2596 | pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE; | |
2597 | if (byte_equal(header + 8,2,"\0\4")) { | |
2598 | pos = dns_packet_copy(buf,len,pos,header,4); if (!pos) goto DIE; | |
2599 | + if (ignoreip.len) | |
2600 | + for(ii = 0; ii < ignoreip.len; ii+= 16) { | |
2601 | + if (byte_equal(ignoreip.s+ii,12,V4mappedprefix) && | |
2602 | + byte_equal(header,4,ignoreip.s+ii+12)) goto NXDOMAIN; | |
2603 | + } | |
2604 | save_data(header,4); | |
2605 | log_rr(whichserver,t1,DNS_T_A,header,4,ttl); | |
2606 | } | |
2607 | @@ -650,6 +845,23 @@ static int doit(struct query *z,int state) | |
2608 | } | |
2609 | save_finish(DNS_T_A,t1,ttl); | |
2610 | } | |
2611 | + else if (byte_equal(type,2,DNS_T_AAAA)) { | |
2612 | + save_start(); | |
2613 | + while (i < j) { | |
2614 | + pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE; | |
2615 | + pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE; | |
2616 | + if (byte_equal(header + 8,2,"\0\20")) { | |
2617 | + pos = dns_packet_copy(buf,len,pos,header,16); if (!pos) goto DIE; | |
2618 | + if (ignoreip.len) | |
2619 | + for(ii = 0; ii < ignoreip.len; ii+= 16) | |
2620 | + if (byte_equal(header,16,ignoreip.s+ii)) goto NXDOMAIN; | |
2621 | + save_data(header,16); | |
2622 | + log_rr(whichserver,t1,DNS_T_AAAA,header,16,ttl); | |
2623 | + } | |
2624 | + ++i; | |
2625 | + } | |
2626 | + save_finish(DNS_T_AAAA,t1,ttl); | |
2627 | + } | |
2628 | else { | |
2629 | save_start(); | |
2630 | while (i < j) { | |
2631 | @@ -723,9 +935,10 @@ static int doit(struct query *z,int state) | |
2632 | if (typematch(header,DNS_T_A)) | |
2633 | if (byte_equal(header + 2,2,DNS_C_IN)) /* should always be true */ | |
2634 | if (datalen == 4) | |
2635 | - for (k = 0;k < 64;k += 4) | |
2636 | - if (byte_equal(z->servers[z->level - 1] + k,4,"\0\0\0\0")) { | |
2637 | - if (!dns_packet_copy(buf,len,pos,z->servers[z->level - 1] + k,4)) goto DIE; | |
2638 | + for (k = 0;k < 256;k += 16) | |
2639 | + if (byte_equal(z->servers[z->level - 1] + k,16,V6any)) { | |
2640 | + byte_copy(z->servers[z->level - 1] + k,12,V4mappedprefix); | |
2641 | + if (!dns_packet_copy(buf,len,pos,z->servers[z->level - 1] + k + 12,4)) goto DIE; | |
2642 | break; | |
2643 | } | |
2644 | pos += datalen; | |
2645 | @@ -818,7 +1031,7 @@ static int doit(struct query *z,int state) | |
2646 | return -1; | |
2647 | } | |
2648 | ||
2649 | -int query_start(struct query *z,char *dn,char type[2],char class[2],char localip[4]) | |
2650 | +int query_start(struct query *z,char *dn,char type[2],char class[2],char localip[16],unsigned int scope_id) | |
2651 | { | |
2652 | if (byte_equal(type,2,DNS_T_AXFR)) { errno = error_perm; return -1; } | |
2653 | ||
2654 | @@ -829,7 +1042,8 @@ int query_start(struct query *z,char *dn,char type[2],char class[2],char localip | |
2655 | if (!dns_domain_copy(&z->name[0],dn)) return -1; | |
2656 | byte_copy(z->type,2,type); | |
2657 | byte_copy(z->class,2,class); | |
2658 | - byte_copy(z->localip,4,localip); | |
2659 | + byte_copy(z->localip,16,localip); | |
2660 | + z->scope_id=scope_id; | |
2661 | ||
2662 | return doit(z,0); | |
2663 | } | |
2664 | diff --git a/query.h b/query.h | |
2665 | index eff68b2..f179c22 100644 | |
2666 | --- a/query.h | |
2667 | +++ b/query.h | |
2668 | @@ -14,16 +14,17 @@ struct query { | |
2669 | char *name[QUERY_MAXLEVEL]; | |
2670 | char *control[QUERY_MAXLEVEL]; /* pointing inside name */ | |
2671 | char *ns[QUERY_MAXLEVEL][QUERY_MAXNS]; | |
2672 | - char servers[QUERY_MAXLEVEL][64]; | |
2673 | + char servers[QUERY_MAXLEVEL][256]; | |
2674 | char *alias[QUERY_MAXALIAS]; | |
2675 | uint32 aliasttl[QUERY_MAXALIAS]; | |
2676 | - char localip[4]; | |
2677 | + char localip[16]; | |
2678 | + uint32 scope_id; | |
2679 | char type[2]; | |
2680 | char class[2]; | |
2681 | struct dns_transmit dt; | |
2682 | } ; | |
2683 | ||
2684 | -extern int query_start(struct query *,char *,char *,char *,char *); | |
2685 | +extern int query_start(struct query *,char *,char *,char *,char *,unsigned int); | |
2686 | extern void query_io(struct query *,iopause_fd *,struct taia *); | |
2687 | extern int query_get(struct query *,iopause_fd *,struct taia *); | |
2688 | ||
2689 | diff --git a/roots.c b/roots.c | |
2690 | index 3cfe959..4162ec5 100644 | |
2691 | --- a/roots.c | |
2692 | +++ b/roots.c | |
2693 | @@ -6,6 +6,7 @@ | |
2694 | #include "error.h" | |
2695 | #include "direntry.h" | |
2696 | #include "ip4.h" | |
2697 | +#include "ip6.h" | |
2698 | #include "dns.h" | |
2699 | #include "openreadclose.h" | |
2700 | #include "roots.h" | |
2701 | @@ -22,7 +23,7 @@ static int roots_find(char *q) | |
2702 | j = dns_domain_length(data.s + i); | |
2703 | if (dns_domain_equal(data.s + i,q)) return i + j; | |
2704 | i += j; | |
2705 | - i += 64; | |
2706 | + i += 256; | |
2707 | } | |
2708 | return -1; | |
2709 | } | |
2710 | @@ -40,12 +41,12 @@ static int roots_search(char *q) | |
2711 | } | |
2712 | } | |
2713 | ||
2714 | -int roots(char servers[64],char *q) | |
2715 | +int roots(char servers[256],char *q) | |
2716 | { | |
2717 | int r; | |
2718 | r = roots_find(q); | |
2719 | if (r == -1) return 0; | |
2720 | - byte_copy(servers,64,data.s + r); | |
2721 | + byte_copy(servers,256,data.s + r); | |
2722 | return 1; | |
2723 | } | |
2724 | ||
2725 | @@ -60,7 +61,7 @@ static int init2(DIR *dir) | |
2726 | const char *fqdn; | |
2727 | static char *q; | |
2728 | static stralloc text; | |
2729 | - char servers[64]; | |
2730 | + char servers[256]; | |
2731 | int serverslen; | |
2732 | int i; | |
2733 | int j; | |
2734 | @@ -86,14 +87,14 @@ static int init2(DIR *dir) | |
2735 | for (i = 0;i < text.len;++i) | |
2736 | if (text.s[i] == '\n') { | |
2737 | if (serverslen <= 60) | |
2738 | - if (ip4_scan(text.s + j,servers + serverslen)) | |
2739 | - serverslen += 4; | |
2740 | + if (ip6_scan(text.s + j,servers + serverslen)) | |
2741 | + serverslen += 16; | |
2742 | j = i + 1; | |
2743 | } | |
2744 | - byte_zero(servers + serverslen,64 - serverslen); | |
2745 | + byte_zero(servers + serverslen,256 - serverslen); | |
2746 | ||
2747 | if (!stralloc_catb(&data,q,dns_domain_length(q))) return 0; | |
2748 | - if (!stralloc_catb(&data,servers,64)) return 0; | |
2749 | + if (!stralloc_catb(&data,servers,256)) return 0; | |
2750 | } | |
2751 | } | |
2752 | } | |
2753 | diff --git a/scan_xlong.c b/scan_xlong.c | |
2754 | new file mode 100644 | |
2755 | index 0000000..1113433 | |
2756 | --- /dev/null | |
2757 | +++ b/scan_xlong.c | |
2758 | @@ -0,0 +1,23 @@ | |
2759 | +#include "scan.h" | |
2760 | + | |
2761 | +static inline int fromhex(unsigned char c) { | |
2762 | + if (c>='0' && c<='9') | |
2763 | + return c-'0'; | |
2764 | + else if (c>='A' && c<='F') | |
2765 | + return c-'A'+10; | |
2766 | + else if (c>='a' && c<='f') | |
2767 | + return c-'a'+10; | |
2768 | + return -1; | |
2769 | +} | |
2770 | + | |
2771 | +unsigned int scan_xlong(const char *src,unsigned long *dest) { | |
2772 | + register const char *tmp=src; | |
2773 | + register int l=0; | |
2774 | + register unsigned char c; | |
2775 | + while ((c=fromhex(*tmp))<16) { | |
2776 | + l=(l<<4)+c; | |
2777 | + ++tmp; | |
2778 | + } | |
2779 | + *dest=l; | |
2780 | + return tmp-src; | |
2781 | +} | |
2782 | diff --git a/server.c b/server.c | |
2783 | index e486fe1..d52ce87 100644 | |
2784 | --- a/server.c | |
2785 | +++ b/server.c | |
2786 | @@ -4,6 +4,7 @@ | |
2787 | #include "buffer.h" | |
2788 | #include "strerr.h" | |
2789 | #include "ip4.h" | |
2790 | +#include "ip6.h" | |
2791 | #include "uint16.h" | |
2792 | #include "ndelay.h" | |
2793 | #include "socket.h" | |
2794 | @@ -11,13 +12,16 @@ | |
2795 | #include "qlog.h" | |
2796 | #include "response.h" | |
2797 | #include "dns.h" | |
2798 | +#include "alloc.h" | |
2799 | +#include "iopause.h" | |
2800 | +#include "str.h" | |
2801 | ||
2802 | extern char *fatal; | |
2803 | extern char *starting; | |
2804 | extern int respond(char *,char *,char *); | |
2805 | extern void initialize(void); | |
2806 | ||
2807 | -static char ip[4]; | |
2808 | +static char ip[16]; | |
2809 | static uint16 port; | |
2810 | ||
2811 | static char buf[513]; | |
2812 | @@ -25,6 +29,11 @@ static int len; | |
2813 | ||
2814 | static char *q; | |
2815 | ||
2816 | +void nomem() | |
2817 | +{ | |
2818 | + strerr_die2x(111,fatal,"out of memory"); | |
2819 | +} | |
2820 | + | |
2821 | static int doit(void) | |
2822 | { | |
2823 | unsigned int pos; | |
2824 | @@ -82,35 +91,86 @@ static int doit(void) | |
2825 | int main() | |
2826 | { | |
2827 | char *x; | |
2828 | - int udp53; | |
2829 | + int *udp53; | |
2830 | + unsigned int off; | |
2831 | + unsigned int cnt; | |
2832 | + iopause_fd *iop; | |
2833 | ||
2834 | x = env_get("IP"); | |
2835 | if (!x) | |
2836 | strerr_die2x(111,fatal,"$IP not set"); | |
2837 | - if (!ip4_scan(x,ip)) | |
2838 | - strerr_die3x(111,fatal,"unable to parse IP address ",x); | |
2839 | - | |
2840 | - udp53 = socket_udp(); | |
2841 | - if (udp53 == -1) | |
2842 | - strerr_die2sys(111,fatal,"unable to create UDP socket: "); | |
2843 | - if (socket_bind4_reuse(udp53,ip,53) == -1) | |
2844 | - strerr_die2sys(111,fatal,"unable to bind UDP socket: "); | |
2845 | - | |
2846 | + off=cnt=0; | |
2847 | + while (x[off]) { | |
2848 | + unsigned int l; | |
2849 | + char dummy[16]; | |
2850 | + l=ip6_scan(x+off,dummy); | |
2851 | + if (!l) | |
2852 | + strerr_die3x(111,fatal,"unable to parse IP address ",x+off); | |
2853 | + cnt++; | |
2854 | + if (!x[off+l]) break; | |
2855 | + if (x[off+l]=='%') | |
2856 | + while (x[off+l] && x[off+l]!=',') ++l; | |
2857 | + if (x[off+l]!=',') | |
2858 | + strerr_die3x(111,fatal,"unable to parse IP address ",x+off); | |
2859 | + off+=l+1; | |
2860 | + } | |
2861 | + udp53=(int *) alloc(sizeof(int) *cnt); | |
2862 | + if (!udp53) nomem(); | |
2863 | + iop=(iopause_fd *) alloc(sizeof(*iop) * cnt); | |
2864 | + if (!iop) nomem(); | |
2865 | + | |
2866 | + off=cnt=0; | |
2867 | + while (x[off]) { | |
2868 | + unsigned int l; | |
2869 | + uint32 ifid=0; | |
2870 | + l=ip6_scan(x+off,ip); | |
2871 | + udp53[cnt] = socket_udp6(); | |
2872 | + if (udp53[cnt] == -1) | |
2873 | + strerr_die2sys(111,fatal,"unable to create UDP socket: "); | |
2874 | + if (x[off+l]=='%') { | |
2875 | + char* interface=x+off+l+1; | |
2876 | + int Len=str_chr(interface,','); | |
2877 | + if (interface[Len]) { | |
2878 | + interface[Len]=0; | |
2879 | + ifid=socket_getifidx(interface); | |
2880 | + interface[Len]=','; | |
2881 | + } else | |
2882 | + ifid=socket_getifidx(interface); | |
2883 | + l+=Len; | |
2884 | + } | |
2885 | + if (socket_bind6_reuse(udp53[cnt],ip,53,ifid) == -1) | |
2886 | + strerr_die2sys(111,fatal,"unable to bind UDP socket: "); | |
2887 | + ndelay_off(udp53[cnt]); | |
2888 | + socket_tryreservein(udp53[cnt],65536); | |
2889 | + iop[cnt].fd=udp53[cnt]; | |
2890 | + iop[cnt].events=IOPAUSE_READ; | |
2891 | + cnt++; | |
2892 | + if (!x[off+l]) break; | |
2893 | + off+=l+1; | |
2894 | + } | |
2895 | droproot(fatal); | |
2896 | ||
2897 | initialize(); | |
2898 | - | |
2899 | - ndelay_off(udp53); | |
2900 | - socket_tryreservein(udp53,65536); | |
2901 | ||
2902 | buffer_putsflush(buffer_2,starting); | |
2903 | ||
2904 | for (;;) { | |
2905 | - len = socket_recv4(udp53,buf,sizeof buf,ip,&port); | |
2906 | - if (len < 0) continue; | |
2907 | - if (!doit()) continue; | |
2908 | - if (response_len > 512) response_tc(); | |
2909 | - socket_send4(udp53,response,response_len,ip,port); | |
2910 | - /* may block for buffer space; if it fails, too bad */ | |
2911 | + struct taia stamp; | |
2912 | + struct taia deadline; | |
2913 | + unsigned int i; | |
2914 | + uint32 ifid; | |
2915 | + taia_now(&stamp); | |
2916 | + taia_uint(&deadline,300); | |
2917 | + taia_add(&deadline,&deadline,&stamp); | |
2918 | + iopause(iop,cnt,&deadline,&stamp); | |
2919 | + for (i=0;i<cnt;i++) | |
2920 | + if (iop[i].revents) { | |
2921 | + len = socket_recv6(udp53[i],buf,sizeof buf,ip,&port,&ifid); | |
2922 | + if (len < 0) continue; | |
2923 | + if (!doit()) continue; | |
2924 | + if (response_len > 512) response_tc(); | |
2925 | + socket_send6(udp53[i],response,response_len,ip,port,ifid); | |
2926 | + /* may block for buffer space; if it fails, too bad */ | |
2927 | + } | |
2928 | } | |
2929 | } | |
2930 | diff --git a/sockaddr_in6.h1 b/sockaddr_in6.h1 | |
2931 | new file mode 100644 | |
2932 | index 0000000..b1f8f5e | |
2933 | --- /dev/null | |
2934 | +++ b/sockaddr_in6.h1 | |
2935 | @@ -0,0 +1,21 @@ | |
2936 | +#include "haveip6.h" | |
2937 | +#ifdef LIBC_HAS_IP6 | |
2938 | +#include <sys/types.h> | |
2939 | +#include <sys/socket.h> | |
2940 | +#define sockaddr_in6 blub | |
2941 | +#include <netinet/in.h> | |
2942 | +#undef sockaddr_in6 | |
2943 | + | |
2944 | +struct sockaddr_in6 { | |
2945 | + sa_family_t sin6_family; /* AF_INET6 */ | |
2946 | + unsigned short sin6_port; /* transport layer port # */ | |
2947 | + uint32_t sin6_flowinfo; /* IPv6 traffic class & flow info */ | |
2948 | + struct in6_addr sin6_addr; /* IPv6 address */ | |
2949 | + uint32_t sin6_scope_id; /* set of interfaces for a scope */ | |
2950 | +}; | |
2951 | + | |
2952 | +#else | |
2953 | +#include <sys/types.h> | |
2954 | +#include <sys/socket.h> | |
2955 | +#include <netinet/in.h> | |
2956 | +#endif | |
2957 | diff --git a/sockaddr_in6.h2 b/sockaddr_in6.h2 | |
2958 | new file mode 100644 | |
2959 | index 0000000..d484041 | |
2960 | --- /dev/null | |
2961 | +++ b/sockaddr_in6.h2 | |
2962 | @@ -0,0 +1,4 @@ | |
2963 | +#include <sys/types.h> | |
2964 | +#include <sys/socket.h> | |
2965 | +#include <netinet/in.h> | |
2966 | + | |
2967 | diff --git a/socket.h b/socket.h | |
2968 | index 95e2a7c..bbb0f82 100644 | |
2969 | --- a/socket.h | |
2970 | +++ b/socket.h | |
2971 | @@ -2,21 +2,37 @@ | |
2972 | #define SOCKET_H | |
2973 | ||
2974 | #include "uint16.h" | |
2975 | +#include "uint32.h" | |
2976 | ||
2977 | extern int socket_tcp(void); | |
2978 | extern int socket_udp(void); | |
2979 | +extern int socket_tcp6(void); | |
2980 | +extern int socket_udp6(void); | |
2981 | ||
2982 | extern int socket_connect4(int,const char *,uint16); | |
2983 | +extern int socket_connect6(int s,const char ip[16],uint16 port,uint32 scope_id); | |
2984 | extern int socket_connected(int); | |
2985 | -extern int socket_bind4(int,char *,uint16); | |
2986 | +extern int socket_bind4(int,const char *,uint16); | |
2987 | extern int socket_bind4_reuse(int,char *,uint16); | |
2988 | +extern int socket_bind6(int s,const char *ip,uint16 port,uint32 scope_id); | |
2989 | +extern int socket_bind6_reuse(int s,const char *ip,uint16 port,uint32 scope_id); | |
2990 | extern int socket_listen(int,int); | |
2991 | extern int socket_accept4(int,char *,uint16 *); | |
2992 | +extern int socket_accept6(int s,char *ip,uint16 *port,uint32 *scope_id); | |
2993 | extern int socket_recv4(int,char *,int,char *,uint16 *); | |
2994 | extern int socket_send4(int,const char *,int,const char *,uint16); | |
2995 | +extern int socket_recv6(int s,char *buf,unsigned int len,char *ip,uint16 *port,uint32 *scope_id); | |
2996 | +extern int socket_send6(int s,const char *buf,unsigned int len,const char *ip,uint16 port,uint32 scope_id); | |
2997 | extern int socket_local4(int,char *,uint16 *); | |
2998 | extern int socket_remote4(int,char *,uint16 *); | |
2999 | +extern int socket_local6(int s,char *ip,uint16 *port,uint32 *scope_id); | |
3000 | +extern int socket_remote6(int s,char *ip,uint16 *port,uint32 *scope_id); | |
3001 | ||
3002 | extern void socket_tryreservein(int,int); | |
3003 | ||
3004 | +extern const char* socket_getifname(uint32 interface); | |
3005 | +extern uint32 socket_getifidx(const char *ifname); | |
3006 | + | |
3007 | +extern int noipv6; | |
3008 | + | |
3009 | #endif | |
3010 | diff --git a/socket_accept6.c b/socket_accept6.c | |
3011 | new file mode 100644 | |
3012 | index 0000000..48a0b6d | |
3013 | --- /dev/null | |
3014 | +++ b/socket_accept6.c | |
3015 | @@ -0,0 +1,43 @@ | |
3016 | +#include <sys/param.h> | |
3017 | +#include <sys/socket.h> | |
3018 | +#include <netinet/in.h> | |
3019 | +#include "byte.h" | |
3020 | +#include "socket.h" | |
3021 | +#include "ip6.h" | |
3022 | +#include "haveip6.h" | |
3023 | +#include "error.h" | |
3024 | + | |
3025 | +int socket_accept6(int s,char ip[16],uint16 *port,uint32 *scope_id) | |
3026 | +{ | |
3027 | +#ifdef LIBC_HAS_IP6 | |
3028 | + struct sockaddr_in6 sa; | |
3029 | +#else | |
3030 | + struct sockaddr_in sa; | |
3031 | +#endif | |
3032 | + unsigned int dummy = sizeof sa; | |
3033 | + int fd; | |
3034 | + | |
3035 | + fd = accept(s,(struct sockaddr *) &sa,&dummy); | |
3036 | + if (fd == -1) return -1; | |
3037 | + | |
3038 | +#ifdef LIBC_HAS_IP6 | |
3039 | + if (sa.sin6_family==AF_INET) { | |
3040 | + struct sockaddr_in *sa4=(struct sockaddr_in*)&sa; | |
3041 | + byte_copy(ip,12,V4mappedprefix); | |
3042 | + byte_copy(ip+12,4,(char *) &sa4->sin_addr); | |
3043 | + uint16_unpack_big((char *) &sa4->sin_port,port); | |
3044 | + return fd; | |
3045 | + } | |
3046 | + byte_copy(ip,16,(char *) &sa.sin6_addr); | |
3047 | + uint16_unpack_big((char *) &sa.sin6_port,port); | |
3048 | + if (scope_id) *scope_id=sa.sin6_scope_id; | |
3049 | + | |
3050 | + return fd; | |
3051 | +#else | |
3052 | + byte_copy(ip,12,V4mappedprefix); | |
3053 | + byte_copy(ip+12,4,(char *) &sa.sin_addr); | |
3054 | + uint16_unpack_big((char *) &sa.sin_port,port); | |
3055 | + if (scope_id) *scope_id=0; | |
3056 | + return fd; | |
3057 | +#endif | |
3058 | +} | |
3059 | diff --git a/socket_bind.c b/socket_bind.c | |
3060 | index 20830a4..a33efca 100644 | |
3061 | --- a/socket_bind.c | |
3062 | +++ b/socket_bind.c | |
3063 | @@ -5,7 +5,7 @@ | |
3064 | #include "byte.h" | |
3065 | #include "socket.h" | |
3066 | ||
3067 | -int socket_bind4(int s,char ip[4],uint16 port) | |
3068 | +int socket_bind4(int s,const char ip[4],uint16 port) | |
3069 | { | |
3070 | struct sockaddr_in sa; | |
3071 | ||
3072 | diff --git a/socket_bind6.c b/socket_bind6.c | |
3073 | new file mode 100644 | |
3074 | index 0000000..20b22b8 | |
3075 | --- /dev/null | |
3076 | +++ b/socket_bind6.c | |
3077 | @@ -0,0 +1,43 @@ | |
3078 | +#include <sys/param.h> | |
3079 | +#include "sockaddr_in6.h" | |
3080 | +#include "byte.h" | |
3081 | +#include "socket.h" | |
3082 | +#include "ip6.h" | |
3083 | +#include "haveip6.h" | |
3084 | +#include "error.h" | |
3085 | + | |
3086 | +int socket_bind6(int s,const char ip[16],uint16 port,uint32 scope_id) | |
3087 | +{ | |
3088 | +#ifdef LIBC_HAS_IP6 | |
3089 | + struct sockaddr_in6 sa; | |
3090 | + | |
3091 | + if (noipv6) { | |
3092 | +#endif | |
3093 | + int i; | |
3094 | + for (i=0; i<16; i++) | |
3095 | + if (ip[i]!=0) break; | |
3096 | + if (i==16 || ip6_isv4mapped(ip)) | |
3097 | + return socket_bind4(s,ip+12,port); | |
3098 | +#ifdef LIBC_HAS_IP6 | |
3099 | + } | |
3100 | + byte_zero(&sa,sizeof sa); | |
3101 | + sa.sin6_family = AF_INET6; | |
3102 | + uint16_pack_big((char *) &sa.sin6_port,port); | |
3103 | +/* implicit: sa.sin6_flowinfo = 0; */ | |
3104 | + byte_copy((char *) &sa.sin6_addr,16,ip); | |
3105 | + sa.sin6_scope_id=scope_id; | |
3106 | + | |
3107 | + return bind(s,(struct sockaddr *) &sa,sizeof sa); | |
3108 | +#else | |
3109 | + errno=error_proto; | |
3110 | + return -1; | |
3111 | +#endif | |
3112 | +} | |
3113 | + | |
3114 | +int socket_bind6_reuse(int s,const char ip[16],uint16 port,uint32 scope_id) | |
3115 | +{ | |
3116 | + int opt = 1; | |
3117 | + setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof opt); | |
3118 | + return socket_bind6(s,ip,port,scope_id); | |
3119 | +} | |
3120 | + | |
3121 | diff --git a/socket_connect6.c b/socket_connect6.c | |
3122 | new file mode 100644 | |
3123 | index 0000000..d2df4a2 | |
3124 | --- /dev/null | |
3125 | +++ b/socket_connect6.c | |
3126 | @@ -0,0 +1,39 @@ | |
3127 | +#include <sys/param.h> | |
3128 | +#include <sys/types.h> | |
3129 | +#include <sys/socket.h> | |
3130 | +#include <netinet/in.h> | |
3131 | +#include <errno.h> | |
3132 | +#include "byte.h" | |
3133 | +#include "socket.h" | |
3134 | +#include "ip6.h" | |
3135 | +#include "haveip6.h" | |
3136 | +#include "error.h" | |
3137 | +#include "uint32.h" | |
3138 | +#include "ip4.h" | |
3139 | + | |
3140 | +int socket_connect6(int s,const char ip[16],uint16 port,uint32 scope_id) | |
3141 | +{ | |
3142 | +#ifdef LIBC_HAS_IP6 | |
3143 | + struct sockaddr_in6 sa; | |
3144 | + | |
3145 | + if (noipv6) { | |
3146 | +#endif | |
3147 | + if (ip6_isv4mapped(ip)) | |
3148 | + return socket_connect4(s,ip+12,port); | |
3149 | + if (byte_equal(ip,16,V6loopback)) | |
3150 | + return socket_connect4(s,ip4loopback,port); | |
3151 | +#ifdef LIBC_HAS_IP6 | |
3152 | + } | |
3153 | + byte_zero(&sa,sizeof sa); | |
3154 | + sa.sin6_family = PF_INET6; | |
3155 | + uint16_pack_big((char *) &sa.sin6_port,port); | |
3156 | + sa.sin6_flowinfo = 0; | |
3157 | + sa.sin6_scope_id = scope_id; | |
3158 | + byte_copy((char *) &sa.sin6_addr,16,ip); | |
3159 | + | |
3160 | + return connect(s,(struct sockaddr *) &sa,sizeof sa); | |
3161 | +#else | |
3162 | + errno=error_proto; | |
3163 | + return -1; | |
3164 | +#endif | |
3165 | +} | |
3166 | diff --git a/socket_getifidx.c b/socket_getifidx.c | |
3167 | new file mode 100644 | |
3168 | index 0000000..c71fc48 | |
3169 | --- /dev/null | |
3170 | +++ b/socket_getifidx.c | |
3171 | @@ -0,0 +1,13 @@ | |
3172 | +#include <sys/types.h> | |
3173 | +#include <sys/socket.h> | |
3174 | +#include <net/if.h> | |
3175 | +#include "socket.h" | |
3176 | +#include "haven2i.h" | |
3177 | + | |
3178 | +uint32 socket_getifidx(const char* ifname) { | |
3179 | +#ifdef HAVE_N2I | |
3180 | + return if_nametoindex(ifname); | |
3181 | +#else | |
3182 | + return 0; | |
3183 | +#endif | |
3184 | +} | |
3185 | diff --git a/socket_noipv6.c b/socket_noipv6.c | |
3186 | new file mode 100644 | |
3187 | index 0000000..289d699 | |
3188 | --- /dev/null | |
3189 | +++ b/socket_noipv6.c | |
3190 | @@ -0,0 +1,7 @@ | |
3191 | +#include "haveip6.h" | |
3192 | + | |
3193 | +#ifdef LIBC_HAS_IP6 | |
3194 | +int noipv6=0; | |
3195 | +#else | |
3196 | +int noipv6=1; | |
3197 | +#endif | |
3198 | diff --git a/socket_recv6.c b/socket_recv6.c | |
3199 | new file mode 100644 | |
3200 | index 0000000..1fb9b4d | |
3201 | --- /dev/null | |
3202 | +++ b/socket_recv6.c | |
3203 | @@ -0,0 +1,42 @@ | |
3204 | +#include <sys/param.h> | |
3205 | +#include "sockaddr_in6.h" | |
3206 | +#include "byte.h" | |
3207 | +#include "socket.h" | |
3208 | +#include "ip6.h" | |
3209 | +#include "haveip6.h" | |
3210 | +#include "error.h" | |
3211 | + | |
3212 | +int socket_recv6(int s,char *buf,unsigned int len,char ip[16],uint16 *port,uint32 *scope_id) | |
3213 | +{ | |
3214 | +#ifdef LIBC_HAS_IP6 | |
3215 | + struct sockaddr_in6 sa; | |
3216 | +#else | |
3217 | + struct sockaddr_in sa; | |
3218 | +#endif | |
3219 | + unsigned int dummy = sizeof sa; | |
3220 | + int r; | |
3221 | + | |
3222 | + byte_zero(&sa,dummy); | |
3223 | + r = recvfrom(s,buf,len,0,(struct sockaddr *) &sa,&dummy); | |
3224 | + if (r == -1) return -1; | |
3225 | + | |
3226 | +#ifdef LIBC_HAS_IP6 | |
3227 | + if (noipv6) { | |
3228 | + struct sockaddr_in *sa4=(struct sockaddr_in *)&sa; | |
3229 | + byte_copy(ip,12,V4mappedprefix); | |
3230 | + byte_copy(ip+12,4,(char *) &sa4->sin_addr); | |
3231 | + uint16_unpack_big((char *) &sa4->sin_port,port); | |
3232 | + return r; | |
3233 | + } | |
3234 | + byte_copy(ip,16,(char *) &sa.sin6_addr); | |
3235 | + uint16_unpack_big((char *) &sa.sin6_port,port); | |
3236 | + if (scope_id) *scope_id=sa.sin6_scope_id; | |
3237 | +#else | |
3238 | + byte_copy(ip,12,(char *)V4mappedprefix); | |
3239 | + byte_copy(ip+12,4,(char *) &sa.sin_addr); | |
3240 | + uint16_unpack_big((char *) &sa.sin_port,port); | |
3241 | + if (scope_id) *scope_id=0; | |
3242 | +#endif | |
3243 | + | |
3244 | + return r; | |
3245 | +} | |
3246 | diff --git a/socket_send6.c b/socket_send6.c | |
3247 | new file mode 100644 | |
3248 | index 0000000..ded6793 | |
3249 | --- /dev/null | |
3250 | +++ b/socket_send6.c | |
3251 | @@ -0,0 +1,39 @@ | |
3252 | +#include <sys/types.h> | |
3253 | +#include <sys/param.h> | |
3254 | +#include <sys/socket.h> | |
3255 | +#include <netinet/in.h> | |
3256 | +#include "byte.h" | |
3257 | +#include "socket.h" | |
3258 | +#include "ip6.h" | |
3259 | +#include "haveip6.h" | |
3260 | +#include "error.h" | |
3261 | + | |
3262 | +int socket_send6(int s,const char *buf,unsigned int len,const char ip[16],uint16 port,uint32 scope_id) | |
3263 | +{ | |
3264 | +#ifdef LIBC_HAS_IP6 | |
3265 | + struct sockaddr_in6 sa; | |
3266 | +#else | |
3267 | + struct sockaddr_in sa; | |
3268 | +#endif | |
3269 | + | |
3270 | + byte_zero(&sa,sizeof sa); | |
3271 | +#ifdef LIBC_HAS_IP6 | |
3272 | + if (noipv6) { | |
3273 | +#endif | |
3274 | + if (ip6_isv4mapped(ip)) | |
3275 | + return socket_send4(s,buf,len,ip+12,port); | |
3276 | + if (byte_equal(ip,16,V6loopback)) | |
3277 | + return socket_send4(s,buf,len,ip4loopback,port); | |
3278 | +#ifdef LIBC_HAS_IP6 | |
3279 | + errno=error_proto; | |
3280 | + return -1; | |
3281 | + } | |
3282 | + sa.sin6_family = AF_INET6; | |
3283 | + uint16_pack_big((char *) &sa.sin6_port,port); | |
3284 | + byte_copy((char *) &sa.sin6_addr,16,ip); | |
3285 | + return sendto(s,buf,len,0,(struct sockaddr *) &sa,sizeof sa); | |
3286 | +#else | |
3287 | + errno=error_proto; | |
3288 | + return -1; | |
3289 | +#endif | |
3290 | +} | |
3291 | diff --git a/socket_tcp6.c b/socket_tcp6.c | |
3292 | new file mode 100644 | |
3293 | index 0000000..77bf7bd | |
3294 | --- /dev/null | |
3295 | +++ b/socket_tcp6.c | |
3296 | @@ -0,0 +1,44 @@ | |
3297 | +#include <sys/types.h> | |
3298 | +#include <sys/param.h> | |
3299 | +#include <sys/socket.h> | |
3300 | +#include <netinet/in.h> | |
3301 | +#include <errno.h> | |
3302 | +#include <unistd.h> | |
3303 | +#include "ndelay.h" | |
3304 | +#include "socket.h" | |
3305 | +#include "haveip6.h" | |
3306 | +#include "error.h" | |
3307 | + | |
3308 | +#ifndef EAFNOSUPPORT | |
3309 | +#define EAFNOSUPPORT EINVAL | |
3310 | +#endif | |
3311 | + | |
3312 | +int socket_tcp6(void) | |
3313 | +{ | |
3314 | +#ifdef LIBC_HAS_IP6 | |
3315 | + int s; | |
3316 | + | |
3317 | + if (noipv6) goto compat; | |
3318 | + s = socket(PF_INET6,SOCK_STREAM,0); | |
3319 | + if (s == -1) { | |
3320 | + if (errno == EINVAL || errno == EAFNOSUPPORT) { | |
3321 | +compat: | |
3322 | + s=socket(AF_INET,SOCK_STREAM,0); | |
3323 | + noipv6=1; | |
3324 | + if (s==-1) return -1; | |
3325 | + } else | |
3326 | + return -1; | |
3327 | + } | |
3328 | + if (ndelay_on(s) == -1) { close(s); return -1; } | |
3329 | +#ifdef IPV6_V6ONLY | |
3330 | + { | |
3331 | + int zero=0; | |
3332 | + setsockopt(s,IPPROTO_IPV6,IPV6_V6ONLY,(void*)&zero,sizeof(zero)); | |
3333 | + } | |
3334 | +#endif | |
3335 | + return s; | |
3336 | +#else | |
3337 | + return socket_tcp(); | |
3338 | +#endif | |
3339 | +} | |
3340 | + | |
3341 | diff --git a/socket_udp6.c b/socket_udp6.c | |
3342 | new file mode 100644 | |
3343 | index 0000000..3a10f49 | |
3344 | --- /dev/null | |
3345 | +++ b/socket_udp6.c | |
3346 | @@ -0,0 +1,43 @@ | |
3347 | +#include <sys/types.h> | |
3348 | +#include <sys/param.h> | |
3349 | +#include <sys/socket.h> | |
3350 | +#include <netinet/in.h> | |
3351 | +#include <errno.h> | |
3352 | +#include <unistd.h> | |
3353 | +#include "ndelay.h" | |
3354 | +#include "socket.h" | |
3355 | +#include "haveip6.h" | |
3356 | +#include "error.h" | |
3357 | + | |
3358 | +#ifndef EAFNOSUPPORT | |
3359 | +#define EAFNOSUPPORT EINVAL | |
3360 | +#endif | |
3361 | + | |
3362 | +int socket_udp6(void) | |
3363 | +{ | |
3364 | +#ifdef LIBC_HAS_IP6 | |
3365 | + int s; | |
3366 | + | |
3367 | + if (noipv6) goto compat; | |
3368 | + s = socket(PF_INET6,SOCK_DGRAM,0); | |
3369 | + if (s == -1) { | |
3370 | + if (errno == EINVAL || errno == EAFNOSUPPORT) { | |
3371 | +compat: | |
3372 | + s=socket(AF_INET,SOCK_DGRAM,0); | |
3373 | + noipv6=1; | |
3374 | + if (s==-1) return -1; | |
3375 | + } else | |
3376 | + return -1; | |
3377 | + } | |
3378 | + if (ndelay_on(s) == -1) { close(s); return -1; } | |
3379 | +#ifdef IPV6_V6ONLY | |
3380 | + { | |
3381 | + int zero=0; | |
3382 | + setsockopt(s,IPPROTO_IPV6,IPV6_V6ONLY,(void*)&zero,sizeof(zero)); | |
3383 | + } | |
3384 | +#endif | |
3385 | + return s; | |
3386 | +#else | |
3387 | + return socket_udp(); | |
3388 | +#endif | |
3389 | +} | |
3390 | diff --git a/tdlookup.c b/tdlookup.c | |
3391 | index da7420d..d3e473e 100644 | |
3392 | --- a/tdlookup.c | |
3393 | +++ b/tdlookup.c | |
3394 | @@ -8,6 +8,7 @@ | |
3395 | #include "dns.h" | |
3396 | #include "seek.h" | |
3397 | #include "response.h" | |
3398 | +#include "ip6.h" | |
3399 | ||
3400 | static int want(const char *owner,const char type[2]) | |
3401 | { | |
3402 | @@ -119,8 +120,9 @@ static int doit(char *q,char qtype[2]) | |
3403 | char x[20]; | |
3404 | uint16 u16; | |
3405 | char addr[8][4]; | |
3406 | - int addrnum; | |
3407 | - uint32 addrttl; | |
3408 | + char addr6[8][16]; | |
3409 | + int addrnum,addr6num; | |
3410 | + uint32 addrttl,addr6ttl; | |
3411 | int i; | |
3412 | ||
3413 | anpos = response_len; | |
3414 | @@ -152,8 +154,8 @@ static int doit(char *q,char qtype[2]) | |
3415 | wild = q; | |
3416 | ||
3417 | for (;;) { | |
3418 | - addrnum = 0; | |
3419 | - addrttl = 0; | |
3420 | + addrnum = addr6num = 0; | |
3421 | + addrttl = addr6ttl = 0; | |
3422 | cdb_findstart(&c); | |
3423 | while (r = find(wild,wild != q)) { | |
3424 | if (r == -1) return 0; | |
3425 | @@ -171,6 +173,17 @@ static int doit(char *q,char qtype[2]) | |
3426 | if (addrnum < 1000000) ++addrnum; | |
3427 | continue; | |
3428 | } | |
3429 | + if (byte_equal(type,2,DNS_T_AAAA) && (dlen - dpos == 16)) { | |
3430 | + addr6ttl = ttl; | |
3431 | + i = dns_random(addr6num + 1); | |
3432 | + if (i < 8) { | |
3433 | + if ((i < addr6num) && (addr6num < 8)) | |
3434 | + byte_copy(addr6[addr6num],16,addr6[i]); | |
3435 | + byte_copy(addr6[i],16,data + dpos); | |
3436 | + } | |
3437 | + if (addr6num < 1000000) ++addr6num; | |
3438 | + continue; | |
3439 | + } | |
3440 | if (!response_rstart(q,type,ttl)) return 0; | |
3441 | if (byte_equal(type,2,DNS_T_NS) || byte_equal(type,2,DNS_T_CNAME) || byte_equal(type,2,DNS_T_PTR)) { | |
3442 | if (!doname()) return 0; | |
3443 | @@ -195,6 +208,12 @@ static int doit(char *q,char qtype[2]) | |
3444 | if (!response_addbytes(addr[i],4)) return 0; | |
3445 | response_rfinish(RESPONSE_ANSWER); | |
3446 | } | |
3447 | + for (i = 0;i < addr6num;++i) | |
3448 | + if (i < 8) { | |
3449 | + if (!response_rstart(q,DNS_T_AAAA,addr6ttl)) return 0; | |
3450 | + if (!response_addbytes(addr6[i],16)) return 0; | |
3451 | + response_rfinish(RESPONSE_ANSWER); | |
3452 | + } | |
3453 | ||
3454 | if (flagfound) break; | |
3455 | if (wild == control) break; | |
3456 | @@ -259,6 +278,11 @@ static int doit(char *q,char qtype[2]) | |
3457 | if (!dobytes(4)) return 0; | |
3458 | response_rfinish(RESPONSE_ADDITIONAL); | |
3459 | } | |
3460 | + else if (byte_equal(type,2,DNS_T_AAAA)) { | |
3461 | + if (!response_rstart(d1,DNS_T_AAAA,ttl)) return 0; | |
3462 | + if (!dobytes(16)) return 0; | |
3463 | + response_rfinish(RESPONSE_ADDITIONAL); | |
3464 | + } | |
3465 | } | |
3466 | } | |
3467 | } | |
3468 | @@ -278,7 +302,7 @@ static int doit(char *q,char qtype[2]) | |
3469 | return 1; | |
3470 | } | |
3471 | ||
3472 | -int respond(char *q,char qtype[2],char ip[4]) | |
3473 | +int respond(char *q,char qtype[2],char ip[16]) | |
3474 | { | |
3475 | int fd; | |
3476 | int r; | |
3477 | @@ -292,15 +316,17 @@ int respond(char *q,char qtype[2],char ip[4]) | |
3478 | byte_zero(clientloc,2); | |
3479 | key[0] = 0; | |
3480 | key[1] = '%'; | |
3481 | - byte_copy(key + 2,4,ip); | |
3482 | - r = cdb_find(&c,key,6); | |
3483 | - if (!r) r = cdb_find(&c,key,5); | |
3484 | - if (!r) r = cdb_find(&c,key,4); | |
3485 | - if (!r) r = cdb_find(&c,key,3); | |
3486 | - if (!r) r = cdb_find(&c,key,2); | |
3487 | - if (r == -1) return 0; | |
3488 | - if (r && (cdb_datalen(&c) == 2)) | |
3489 | - if (cdb_read(&c,clientloc,2,cdb_datapos(&c)) == -1) return 0; | |
3490 | + if (byte_equal(ip,12,V4mappedprefix)) { | |
3491 | + byte_copy(key + 2,4,ip+12); | |
3492 | + r = cdb_find(&c,key,6); | |
3493 | + if (!r) r = cdb_find(&c,key,5); | |
3494 | + if (!r) r = cdb_find(&c,key,4); | |
3495 | + if (!r) r = cdb_find(&c,key,3); | |
3496 | + if (!r) r = cdb_find(&c,key,2); | |
3497 | + if (r == -1) return 0; | |
3498 | + if (r && (cdb_datalen(&c) == 2)) | |
3499 | + if (cdb_read(&c,clientloc,2,cdb_datapos(&c)) == -1) return 0; | |
3500 | + } | |
3501 | ||
3502 | r = doit(q,qtype); | |
3503 | ||
3504 | diff --git a/tinydns-conf.c b/tinydns-conf.c | |
3505 | index d3a4ce5..db83f11 100644 | |
3506 | --- a/tinydns-conf.c | |
3507 | +++ b/tinydns-conf.c | |
3508 | @@ -82,6 +82,18 @@ int main(int argc,char **argv) | |
3509 | finish(); | |
3510 | perm(0755); | |
3511 | ||
3512 | + start("root/add-host6"); | |
3513 | + outs("#!/bin/sh\nexec "); | |
3514 | + outs(auto_home); outs("/bin/tinydns-edit data data.new add host6 ${1+\"$@\"}\n"); | |
3515 | + finish(); | |
3516 | + perm(0755); | |
3517 | + | |
3518 | + start("root/add-alias6"); | |
3519 | + outs("#!/bin/sh\nexec "); | |
3520 | + outs(auto_home); outs("/bin/tinydns-edit data data.new add alias6 ${1+\"$@\"}\n"); | |
3521 | + finish(); | |
3522 | + perm(0755); | |
3523 | + | |
3524 | start("root/add-mx"); | |
3525 | outs("#!/bin/sh\nexec "); | |
3526 | outs(auto_home); outs("/bin/tinydns-edit data data.new add mx ${1+\"$@\"}\n"); | |
3527 | diff --git a/tinydns-data.c b/tinydns-data.c | |
3528 | index ba82f84..b42bd62 100644 | |
3529 | --- a/tinydns-data.c | |
3530 | +++ b/tinydns-data.c | |
3531 | @@ -8,6 +8,7 @@ | |
3532 | #include "byte.h" | |
3533 | #include "fmt.h" | |
3534 | #include "ip4.h" | |
3535 | +#include "ip6.h" | |
3536 | #include "exit.h" | |
3537 | #include "case.h" | |
3538 | #include "scan.h" | |
3539 | @@ -172,6 +173,7 @@ static stralloc f[NUMFIELDS]; | |
3540 | static char *d1; | |
3541 | static char *d2; | |
3542 | char dptr[DNS_NAME4_DOMAIN]; | |
3543 | +char d6ptr[DNS_NAME6_DOMAIN]; | |
3544 | ||
3545 | char strnum[FMT_ULONG]; | |
3546 | ||
3547 | @@ -193,6 +195,7 @@ int main() | |
3548 | char loc[2]; | |
3549 | unsigned long u; | |
3550 | char ip[4]; | |
3551 | + char ip6[16]; | |
3552 | char type[2]; | |
3553 | char soa[20]; | |
3554 | char buf[4]; | |
3555 | @@ -339,6 +342,33 @@ int main() | |
3556 | } | |
3557 | break; | |
3558 | ||
3559 | + case '6': case '3': | |
3560 | + if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); | |
3561 | + if (!stralloc_0(&f[2])) nomem(); | |
3562 | + if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE; | |
3563 | + ttdparse(&f[3],ttd); | |
3564 | + locparse(&f[4],loc); | |
3565 | + | |
3566 | + if (!stralloc_0(&f[1])) nomem(); | |
3567 | + if (ip6_scan_flat(f[1].s,ip6)) { | |
3568 | + rr_start(DNS_T_AAAA,ttl,ttd,loc); | |
3569 | + rr_add(ip6,16); | |
3570 | + rr_finish(d1); | |
3571 | + | |
3572 | + if (line.s[0] == '6') { /* emit both .ip6.arpa and .ip6.int */ | |
3573 | + dns_name6_domain(d6ptr,ip6,DNS_IP6_ARPA); | |
3574 | + rr_start(DNS_T_PTR,ttl,ttd,loc); | |
3575 | + rr_addname(d1); | |
3576 | + rr_finish(d6ptr); | |
3577 | + | |
3578 | + dns_name6_domain(d6ptr,ip6,DNS_IP6_INT); | |
3579 | + rr_start(DNS_T_PTR,ttl,ttd,loc); | |
3580 | + rr_addname(d1); | |
3581 | + rr_finish(d6ptr); | |
3582 | + } | |
3583 | + } | |
3584 | + break; | |
3585 | + | |
3586 | case '@': | |
3587 | if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); | |
3588 | if (!stralloc_0(&f[4])) nomem(); | |
3589 | diff --git a/tinydns-edit.c b/tinydns-edit.c | |
3590 | index 126a7e0..8633220 100644 | |
3591 | --- a/tinydns-edit.c | |
3592 | +++ b/tinydns-edit.c | |
3593 | @@ -13,6 +13,7 @@ | |
3594 | #include "str.h" | |
3595 | #include "fmt.h" | |
3596 | #include "ip4.h" | |
3597 | +#include "ip6.h" | |
3598 | #include "dns.h" | |
3599 | ||
3600 | #define FATAL "tinydns-edit: fatal: " | |
3601 | @@ -25,7 +26,8 @@ char *fnnew; | |
3602 | ||
3603 | void die_usage() | |
3604 | { | |
3605 | - strerr_die1x(100,"tinydns-edit: usage: tinydns-edit data data.new add [ns|childns|host|alias|mx] domain a.b.c.d"); | |
3606 | + strerr_die1x(100,"tinydns-edit: usage: tinydns-edit data data.new add [ns|childns|host|alias|mx] domain a.b.c.d\n" | |
3607 | + "tinydns-edit: usage: tinydns-edit data data.new add [host6|alias6] domain a:b:c:d:e:f:g:h"); | |
3608 | } | |
3609 | void nomem() | |
3610 | { | |
3611 | @@ -43,6 +45,7 @@ void die_write() | |
3612 | char mode; | |
3613 | static char *target; | |
3614 | char targetip[4]; | |
3615 | +char targetip6[16]; | |
3616 | ||
3617 | int fd; | |
3618 | buffer b; | |
3619 | @@ -61,7 +64,9 @@ static stralloc f[NUMFIELDS]; | |
3620 | static char *d1; | |
3621 | static char *d2; | |
3622 | char ip[4]; | |
3623 | +char ip6[16]; | |
3624 | char ipstr[IP4_FMT]; | |
3625 | +char ip6str[IP6_FMT]; | |
3626 | char strnum[FMT_ULONG]; | |
3627 | ||
3628 | static char *names[26]; | |
3629 | @@ -96,7 +101,9 @@ int main(int argc,char **argv) | |
3630 | if (str_equal(*argv,"ns")) mode = '.'; | |
3631 | else if (str_equal(*argv,"childns")) mode = '&'; | |
3632 | else if (str_equal(*argv,"host")) mode = '='; | |
3633 | + else if (str_equal(*argv,"host6")) mode = '6'; | |
3634 | else if (str_equal(*argv,"alias")) mode = '+'; | |
3635 | + else if (str_equal(*argv,"alias6")) mode = '3'; | |
3636 | else if (str_equal(*argv,"mx")) mode = '@'; | |
3637 | else die_usage(); | |
3638 | ||
3639 | @@ -104,7 +111,11 @@ int main(int argc,char **argv) | |
3640 | if (!dns_domain_fromdot(&target,*argv,str_len(*argv))) nomem(); | |
3641 | ||
3642 | if (!*++argv) die_usage(); | |
3643 | - if (!ip4_scan(*argv,targetip)) die_usage(); | |
3644 | + if (mode == '6' || mode == '3') { | |
3645 | + if (!ip6_scan(*argv,targetip6)) die_usage(); | |
3646 | + } else { | |
3647 | + if (!ip4_scan(*argv,targetip)) die_usage(); | |
3648 | + } | |
3649 | ||
3650 | umask(077); | |
3651 | ||
3652 | @@ -129,7 +140,7 @@ int main(int argc,char **argv) | |
3653 | if (!dns_domain_fromdot(&names[i],f[0].s,f[0].len)) nomem(); | |
3654 | } | |
3655 | break; | |
3656 | - case '+': case '=': | |
3657 | + case '+': case '=': case '6': case '3': | |
3658 | ttl = TTL_POSITIVE; | |
3659 | break; | |
3660 | case '@': | |
3661 | @@ -203,6 +214,18 @@ int main(int argc,char **argv) | |
3662 | } | |
3663 | break; | |
3664 | ||
3665 | + case '6': | |
3666 | + if (line.s[0] == '6') { | |
3667 | + if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); | |
3668 | + if (dns_domain_equal(d1,target)) | |
3669 | + strerr_die2x(100,FATAL,"host name already used"); | |
3670 | + if (!stralloc_0(&f[1])) nomem(); | |
3671 | + if (ip6_scan(f[1].s,ip6)) | |
3672 | + if (byte_equal(ip,16,targetip6)) | |
3673 | + strerr_die2x(100,FATAL,"IPv6 address already used"); | |
3674 | + } | |
3675 | + break; | |
3676 | + | |
3677 | case '@': | |
3678 | if (line.s[0] == '@') { | |
3679 | if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); | |
3680 | @@ -228,7 +251,11 @@ int main(int argc,char **argv) | |
3681 | if (!stralloc_copyb(&f[0],&mode,1)) nomem(); | |
3682 | if (!dns_domain_todot_cat(&f[0],target)) nomem(); | |
3683 | if (!stralloc_cats(&f[0],":")) nomem(); | |
3684 | - if (!stralloc_catb(&f[0],ipstr,ip4_fmt(ipstr,targetip))) nomem(); | |
3685 | + if (mode == '6' || mode == '3') { | |
3686 | + if (!stralloc_catb(&f[0],ip6str,ip6_fmt_flat(ip6str,targetip6))) nomem(); | |
3687 | + } else { | |
3688 | + if (!stralloc_catb(&f[0],ipstr,ip4_fmt(ipstr,targetip))) nomem(); | |
3689 | + } | |
3690 | switch(mode) { | |
3691 | case '.': case '&': case '@': | |
3692 | for (i = 0;i < 26;++i) | |
3693 | diff --git a/tryip6.c b/tryip6.c | |
3694 | new file mode 100644 | |
3695 | index 0000000..e0d7cfb | |
3696 | --- /dev/null | |
3697 | +++ b/tryip6.c | |
3698 | @@ -0,0 +1,8 @@ | |
3699 | +#include <sys/types.h> | |
3700 | +#include <sys/socket.h> | |
3701 | +#include <netinet/in.h> | |
3702 | + | |
3703 | +main() { | |
3704 | + struct sockaddr_in6 sa; | |
3705 | + sa.sin6_family = PF_INET6; | |
3706 | +} | |
3707 | diff --git a/tryn2i.c b/tryn2i.c | |
3708 | new file mode 100644 | |
3709 | index 0000000..84c3a08 | |
3710 | --- /dev/null | |
3711 | +++ b/tryn2i.c | |
3712 | @@ -0,0 +1,8 @@ | |
3713 | +#include <sys/types.h> | |
3714 | +#include <sys/socket.h> | |
3715 | +#include <net/if.h> | |
3716 | + | |
3717 | +int main() { | |
3718 | + static char ifname[IFNAMSIZ]; | |
3719 | + char *tmp=if_indextoname(0,ifname); | |
3720 | +} | |
3721 | diff --git a/trysa6.c b/trysa6.c | |
3722 | new file mode 100644 | |
3723 | index 0000000..0fd180c | |
3724 | --- /dev/null | |
3725 | +++ b/trysa6.c | |
3726 | @@ -0,0 +1,8 @@ | |
3727 | +#include <sys/types.h> | |
3728 | +#include <sys/socket.h> | |
3729 | +#include <netinet/in.h> | |
3730 | + | |
3731 | +main() { | |
3732 | + struct sockaddr_in6 sa; | |
3733 | + sa.sin6_scope_id = 1; | |
3734 | +} | |
3735 | -- | |
3736 | 1.6.2 | |
3737 |