recipes

packages recipes for the <noname> package manager
Log | Files | Refs

djbdns-1.05-ipv6.diff (120115B)


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