2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
35 #include <sys/types.h>
36 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <arpa/nameser.h>
45 #include "dns_private.h"
46 #include "res_private.h"
48 #define DNS_RESOLVER_DIR "/etc/resolver"
50 #define DNS_PRIVATE_HANDLE_TYPE_SUPER 0
51 #define DNS_PRIVATE_HANDLE_TYPE_PLAIN 1
52 #define DNS_DEFAULT_RECEIVE_SIZE 8192
53 #define DNS_MAX_RECEIVE_SIZE 65536
55 #define SDNS_DEFAULT_STAT_LATENCY 10
57 #define DNS_FLAGS_QR_MASK 0x8000
58 #define DNS_FLAGS_QR_QUERY 0x0000
60 #define DNS_FLAGS_OPCODE_MASK 0x7800
62 #define DNS_FLAGS_RCODE_MASK 0x000f
64 #define DNS_FLAGS_AA 0x0400
65 #define DNS_FLAGS_TC 0x0200
66 #define DNS_FLAGS_RD 0x0100
67 #define DNS_FLAGS_RA 0x0080
69 #define DNS_SOCK_UDP 0
70 #define DNS_SOCK_TCP_UNCONNECTED 1
71 #define DNS_SOCK_TCP_CONNECTED 2
73 #define INET_NTOP_AF_INET_OFFSET 4
74 #define INET_NTOP_AF_INET6_OFFSET 8
76 #define MAXPACKET 1024
78 extern void res_client_close(res_state res
);
79 extern int __res_nquery(res_state statp
, const char *name
, int class, int type
, u_char
*answer
, int anslen
);
80 extern int dns_res_send(res_state statp
, const u_char
*buf
, int buflen
, u_char
*ans
, int *anssiz
, struct sockaddr
*from
, int *fromlen
);
81 extern void _check_cache(sdns_handle_t
*sdns
);
82 extern int _sdns_search(sdns_handle_t
*sdns
, const char *name
, uint32_t class, uint32_t type
, uint32_t fqdn
, uint32_t recurse
, char *buf
, uint32_t len
, struct sockaddr
*from
, uint32_t *fromlen
, int *min
);
83 extern int _pdns_search(sdns_handle_t
*sdns
, pdns_handle_t
*pdns
, const char *name
, uint32_t class, uint32_t type
, char *buf
, uint32_t len
, struct sockaddr
*from
, uint32_t *fromlen
);
84 static pthread_mutex_t _dnsPrintLock
= PTHREAD_MUTEX_INITIALIZER
;
89 pthread_mutex_lock(&_dnsPrintLock
);
93 _dns_print_unlock(void)
95 pthread_mutex_unlock(&_dnsPrintLock
);
100 _dns_parse_uint8(char **p
)
110 _dns_parse_uint16(char **p
)
121 _dns_parse_uint32(char **p
)
132 _dns_cname_length(char *s
)
136 if (s
== NULL
) return 1;
138 while ((s
[l
- 1] == '.') && (l
> 1)) l
--;
143 _dns_insert_cname(char *s
, char *p
)
162 len
= _dns_cname_length(s
);
165 memmove(p
+ 1, s
, len
);
170 for (i
= len
+ 1; i
>= 0; i
--)
182 _dns_parse_string(const char *p
, char **x
, int32_t *remaining
)
187 if (*remaining
< 1) return NULL
;
193 if (*remaining
< len
) return NULL
;
196 str
= malloc(len
+ 1);
197 memmove(str
, *x
, len
);
205 _dns_parse_domain_name(const char *p
, char **x
, int32_t *remaining
)
209 uint16_t i
, j
, dlen
, len
;
210 int more
, compressed
;
211 char *name
, *start
, *y
, *z
;
213 if (*remaining
< 1) return NULL
;
236 if ((dlen
& 0xc0) == 0xc0)
244 v16
= (uint16_t *)*x
;
246 y
= (char *)p
+ (ntohs(*v16
) & 0x3fff);
247 if ((*x
== y
) || (y
> z
))
254 if (compressed
== 0) skip
+= 2;
270 name
= realloc(name
, len
);
279 for (i
= 0; i
< dlen
; i
++)
286 if (compressed
== 0) skip
+= (dlen
+ 1);
288 if (dlen
== 0) more
= 0;
301 name
= realloc(name
, len
);
308 if ((start
+ skip
) > z
)
320 dns_resource_record_t
*
321 _dns_parse_resource_record_internal(const char *p
, char **x
, int32_t *remaining
)
323 uint32_t size
, bx
, mi
;
326 dns_resource_record_t
*r
;
329 if (*remaining
< 1) return NULL
;
331 r
= (dns_resource_record_t
*)calloc(1, sizeof(dns_resource_record_t
));
333 r
->name
= _dns_parse_domain_name(p
, x
, remaining
);
346 r
->dnstype
= _dns_parse_uint16(x
);
347 r
->dnsclass
= _dns_parse_uint16(x
);
348 r
->ttl
= _dns_parse_uint32(x
);
349 rdlen
= _dns_parse_uint16(x
);
367 size
= sizeof(dns_address_record_t
);
368 r
->data
.A
= (dns_address_record_t
*)calloc(1, size
);
369 r
->data
.A
->addr
.s_addr
= htonl(_dns_parse_uint32(x
));
381 size
= sizeof(dns_in6_address_record_t
);
382 r
->data
.AAAA
= (dns_in6_address_record_t
*)calloc(1, size
);
383 r
->data
.AAAA
->addr
.__u6_addr
.__u6_addr32
[0] = htonl(_dns_parse_uint32(x
));
384 r
->data
.AAAA
->addr
.__u6_addr
.__u6_addr32
[1] = htonl(_dns_parse_uint32(x
));
385 r
->data
.AAAA
->addr
.__u6_addr
.__u6_addr32
[2] = htonl(_dns_parse_uint32(x
));
386 r
->data
.AAAA
->addr
.__u6_addr
.__u6_addr32
[3] = htonl(_dns_parse_uint32(x
));
397 size
= sizeof(dns_domain_name_record_t
);
398 r
->data
.CNAME
= (dns_domain_name_record_t
*)calloc(1,size
);
399 r
->data
.CNAME
->name
= _dns_parse_domain_name(p
, x
, remaining
);
400 if (r
->data
.CNAME
->name
== NULL
)
409 size
= sizeof(dns_SOA_record_t
);
410 r
->data
.SOA
= (dns_SOA_record_t
*)calloc(1, size
);
412 r
->data
.SOA
->mname
= _dns_parse_domain_name(p
, x
, remaining
);
413 if (r
->data
.SOA
->mname
== NULL
)
420 r
->data
.SOA
->rname
= _dns_parse_domain_name(p
, x
, remaining
);
421 if (r
->data
.SOA
->rname
== NULL
)
423 free(r
->data
.SOA
->mname
);
431 free(r
->data
.SOA
->mname
);
432 free(r
->data
.SOA
->rname
);
440 r
->data
.SOA
->serial
= _dns_parse_uint32(x
);
441 r
->data
.SOA
->refresh
= _dns_parse_uint32(x
);
442 r
->data
.SOA
->retry
= _dns_parse_uint32(x
);
443 r
->data
.SOA
->expire
= _dns_parse_uint32(x
);
444 r
->data
.SOA
->minimum
= _dns_parse_uint32(x
);
456 size
= sizeof(dns_WKS_record_t
);
457 r
->data
.WKS
= (dns_WKS_record_t
*)calloc(1, size
);
459 r
->data
.WKS
->addr
.s_addr
= htonl(_dns_parse_uint32(x
));
460 r
->data
.WKS
->protocol
= _dns_parse_uint8(x
);
462 r
->data
.WKS
->maplength
= size
* 8;
463 r
->data
.WKS
->map
= NULL
;
464 if (size
== 0) break;
466 r
->data
.WKS
->map
= (uint8_t *)calloc(1, r
->data
.WKS
->maplength
);
468 for (bx
= 0; bx
< size
; bx
++)
470 byte
= _dns_parse_uint8(x
);
471 for (i
= 128; i
>= 1; i
= i
/2)
473 if (byte
& i
) r
->data
.WKS
->map
[mi
] = 0xff;
474 else r
->data
.WKS
->map
[mi
] = 0;
481 size
= sizeof(dns_HINFO_record_t
);
482 r
->data
.HINFO
= (dns_HINFO_record_t
*)calloc(1, size
);
484 r
->data
.HINFO
->cpu
= _dns_parse_string(p
, x
, remaining
);
485 if (r
->data
.HINFO
->cpu
== NULL
)
492 r
->data
.HINFO
->os
= _dns_parse_string(p
, x
, remaining
);
493 if (r
->data
.HINFO
->os
== NULL
)
495 free(r
->data
.HINFO
->cpu
);
504 size
= sizeof(dns_MINFO_record_t
);
505 r
->data
.MINFO
= (dns_MINFO_record_t
*)calloc(1, size
);
507 r
->data
.MINFO
->rmailbx
= _dns_parse_domain_name(p
, x
, remaining
);
508 if (r
->data
.MINFO
->rmailbx
== NULL
)
515 r
->data
.MINFO
->emailbx
= _dns_parse_domain_name(p
, x
, remaining
);
516 if (r
->data
.MINFO
->emailbx
== NULL
)
518 free(r
->data
.MINFO
->rmailbx
);
535 size
= sizeof(dns_MX_record_t
);
536 r
->data
.MX
= (dns_MX_record_t
*)calloc(1, size
);
538 r
->data
.MX
->preference
= _dns_parse_uint16(x
);
539 r
->data
.MX
->name
= _dns_parse_domain_name(p
, x
, remaining
);
540 if (r
->data
.MX
->name
== NULL
)
550 size
= sizeof(dns_TXT_record_t
);
551 r
->data
.TXT
= (dns_TXT_record_t
*)malloc(size
);
552 r
->data
.TXT
->string_count
= 0;
553 r
->data
.TXT
->strings
= NULL
;
555 while (*x
< (eor
+ rdlen
))
557 if (r
->data
.TXT
->string_count
== 0)
559 r
->data
.TXT
->strings
= (char **)calloc(1, sizeof(char *));
563 r
->data
.TXT
->strings
= (char **)realloc(r
->data
.TXT
->strings
, (r
->data
.TXT
->string_count
+ 1) * sizeof(char *));
566 r
->data
.TXT
->strings
[r
->data
.TXT
->string_count
] = _dns_parse_string(p
, x
, remaining
);
567 if (r
->data
.TXT
->strings
[r
->data
.TXT
->string_count
] == NULL
)
569 free(r
->data
.TXT
->strings
);
574 r
->data
.TXT
->string_count
++;
580 size
= sizeof(dns_RP_record_t
);
581 r
->data
.RP
= (dns_RP_record_t
*)calloc(1, size
);
583 r
->data
.RP
->mailbox
= _dns_parse_domain_name(p
, x
, remaining
);
584 if (r
->data
.RP
->mailbox
== NULL
)
591 r
->data
.RP
->txtdname
= _dns_parse_domain_name(p
, x
, remaining
);
592 if (r
->data
.RP
->txtdname
== NULL
)
594 free(r
->data
.RP
->mailbox
);
610 size
= sizeof(dns_AFSDB_record_t
);
611 r
->data
.AFSDB
= (dns_AFSDB_record_t
*)calloc(1, size
);
613 r
->data
.AFSDB
->subtype
= _dns_parse_uint32(x
);
614 r
->data
.AFSDB
->hostname
= _dns_parse_domain_name(p
, x
, remaining
);
615 if (r
->data
.AFSDB
->hostname
== NULL
)
625 size
= sizeof(dns_X25_record_t
);
626 r
->data
.X25
= (dns_X25_record_t
*)calloc(1, size
);
628 r
->data
.X25
->psdn_address
= _dns_parse_string(p
, x
, remaining
);
629 if (r
->data
.X25
->psdn_address
== NULL
)
639 size
= sizeof(dns_ISDN_record_t
);
640 r
->data
.ISDN
= (dns_ISDN_record_t
*)calloc(1, size
);
642 r
->data
.ISDN
->isdn_address
= _dns_parse_string(p
, x
, remaining
);
643 if (r
->data
.ISDN
->isdn_address
== NULL
)
650 if (*x
< (eor
+ rdlen
))
652 r
->data
.ISDN
->subaddress
= _dns_parse_string(p
, x
, remaining
);
653 if (r
->data
.ISDN
->subaddress
== NULL
)
655 free(r
->data
.ISDN
->isdn_address
);
663 r
->data
.ISDN
->subaddress
= NULL
;
677 size
= sizeof(dns_RT_record_t
);
678 r
->data
.RT
= (dns_RT_record_t
*)calloc(1, size
);
680 r
->data
.RT
->preference
= _dns_parse_uint16(x
);
681 r
->data
.RT
->intermediate
= _dns_parse_domain_name(p
, x
, remaining
);
682 if (r
->data
.RT
->intermediate
== NULL
)
700 size
= sizeof(dns_LOC_record_t
);
701 r
->data
.LOC
= (dns_LOC_record_t
*)calloc(1, size
);
703 r
->data
.LOC
->version
= _dns_parse_uint8(x
);
704 r
->data
.LOC
->size
= _dns_parse_uint8(x
);
705 r
->data
.LOC
->horizontal_precision
= _dns_parse_uint8(x
);
706 r
->data
.LOC
->vertical_precision
= _dns_parse_uint8(x
);
707 r
->data
.LOC
->latitude
= _dns_parse_uint32(x
);
708 r
->data
.LOC
->longitude
= _dns_parse_uint32(x
);
709 r
->data
.LOC
->altitude
= _dns_parse_uint32(x
);
721 size
= sizeof(dns_SRV_record_t
);
722 r
->data
.SRV
= (dns_SRV_record_t
*)calloc(1, size
);
724 r
->data
.SRV
->priority
= _dns_parse_uint16(x
);
725 r
->data
.SRV
->weight
= _dns_parse_uint16(x
);
726 r
->data
.SRV
->port
= _dns_parse_uint16(x
);
727 r
->data
.SRV
->target
= _dns_parse_domain_name(p
, x
, remaining
);
728 if (r
->data
.SRV
->target
== NULL
)
739 if (*remaining
< rdlen
)
747 size
= sizeof(dns_raw_resource_record_t
);
748 r
->data
.DNSNULL
= (dns_raw_resource_record_t
*)calloc(1, size
);
750 r
->data
.DNSNULL
->length
= rdlen
;
751 r
->data
.DNSNULL
->data
= calloc(1, rdlen
);
752 memmove(r
->data
.DNSNULL
->data
, *x
, rdlen
);
761 dns_resource_record_t
*
762 dns_parse_resource_record(const char *buf
, uint32_t len
)
769 return _dns_parse_resource_record_internal(buf
, &x
, &remaining
);
773 _dns_parse_question_internal(const char *p
, char **x
, int32_t *remaining
)
777 if (x
== NULL
) return NULL
;
778 if (*x
== NULL
) return NULL
;
779 if (*remaining
< 1) return NULL
;
781 q
= (dns_question_t
*)calloc(1, sizeof(dns_question_t
));
783 q
->name
= _dns_parse_domain_name(p
, x
, remaining
);
797 *remaining
= *remaining
- 4;
799 q
->dnstype
= _dns_parse_uint16(x
);
800 q
->dnsclass
= _dns_parse_uint16(x
);
806 dns_parse_question(const char *buf
, uint32_t len
)
813 return _dns_parse_question_internal(buf
, &x
, &remaining
);
818 dns_parse_packet(const char *p
, uint32_t len
)
826 if (p
== NULL
) return NULL
;
827 if (len
< NS_HFIXEDSZ
) return NULL
;
831 r
= (dns_reply_t
*)calloc(1, sizeof(dns_reply_t
));
833 r
->header
= (dns_header_t
*)calloc(1, sizeof(dns_header_t
));
836 h
->xid
= _dns_parse_uint16(&x
);
837 h
->flags
= _dns_parse_uint16(&x
);
838 h
->qdcount
= _dns_parse_uint16(&x
);
839 h
->ancount
= _dns_parse_uint16(&x
);
840 h
->nscount
= _dns_parse_uint16(&x
);
841 h
->arcount
= _dns_parse_uint16(&x
);
843 remaining
= len
- NS_HFIXEDSZ
;
845 size
= sizeof(dns_question_t
*);
846 r
->question
= (dns_question_t
**)calloc(h
->qdcount
, size
);
847 for (i
= 0; i
< h
->qdcount
; i
++)
849 r
->question
[i
] = _dns_parse_question_internal(p
, &x
, &remaining
);
850 if (r
->question
[i
] ==NULL
)
853 if (i
> 0) h
->qdcount
= i
- 1;
862 size
= sizeof(dns_resource_record_t
*);
864 r
->answer
= (dns_resource_record_t
**)calloc(h
->ancount
, size
);
865 for (i
= 0; i
< h
->ancount
; i
++)
867 r
->answer
[i
] = _dns_parse_resource_record_internal(p
, &x
, &remaining
);
868 if (r
->answer
[i
] == NULL
)
871 if (i
> 0) h
->ancount
= i
- 1;
879 r
->authority
= (dns_resource_record_t
**)calloc(h
->nscount
, size
);
880 for (i
= 0; i
< h
->nscount
; i
++)
882 r
->authority
[i
] = _dns_parse_resource_record_internal(p
, &x
, &remaining
);
883 if (r
->authority
[i
] == NULL
)
886 if (i
> 0) h
->nscount
= i
- 1;
893 r
->additional
= (dns_resource_record_t
**)calloc(h
->arcount
, size
);
894 for (i
= 0; i
< h
->arcount
; i
++)
896 r
->additional
[i
] = _dns_parse_resource_record_internal(p
, &x
, &remaining
);
897 if (r
->additional
[i
] == NULL
)
900 if (i
> 0) h
->arcount
= i
- 1;
910 dns_free_resource_record(dns_resource_record_t
*r
)
934 free(r
->data
.CNAME
->name
);
939 free(r
->data
.SOA
->mname
);
940 free(r
->data
.SOA
->rname
);
945 free(r
->data
.WKS
->map
);
950 free(r
->data
.HINFO
->cpu
);
951 free(r
->data
.HINFO
->os
);
956 free(r
->data
.MINFO
->rmailbx
);
957 free(r
->data
.MINFO
->emailbx
);
962 free(r
->data
.MX
->name
);
968 for (i
=0; i
<r
->data
.TXT
->string_count
; i
++)
970 free(r
->data
.TXT
->strings
[i
]);
972 if (r
->data
.TXT
->strings
!= NULL
)
973 free(r
->data
.TXT
->strings
);
978 free(r
->data
.RP
->mailbox
);
979 free(r
->data
.RP
->txtdname
);
984 free(r
->data
.AFSDB
->hostname
);
989 free(r
->data
.X25
->psdn_address
);
994 free(r
->data
.ISDN
->isdn_address
);
995 if (r
->data
.ISDN
->subaddress
!= NULL
)
996 free(r
->data
.ISDN
->subaddress
);
1001 free(r
->data
.RT
->intermediate
);
1010 free(r
->data
.SRV
->target
);
1016 free(r
->data
.DNSNULL
->data
);
1017 free(r
->data
.DNSNULL
);
1025 dns_free_reply(dns_reply_t
*r
)
1029 if (r
== NULL
) return;
1030 if (r
->header
!= NULL
)
1032 for (i
= 0; i
< r
->header
->qdcount
; i
++)
1034 free(r
->question
[i
]->name
);
1035 free(r
->question
[i
]);
1038 for (i
= 0; i
< r
->header
->ancount
; i
++) dns_free_resource_record(r
->answer
[i
]);
1039 for (i
= 0; i
< r
->header
->nscount
; i
++) dns_free_resource_record(r
->authority
[i
]);
1040 for (i
= 0; i
< r
->header
->arcount
; i
++) dns_free_resource_record(r
->additional
[i
]);
1045 if (r
->question
!= NULL
) free(r
->question
);
1046 if (r
->answer
!= NULL
) free(r
->answer
);
1047 if (r
->authority
!= NULL
) free(r
->authority
);
1048 if (r
->additional
!= NULL
) free(r
->additional
);
1050 if (r
->server
!= NULL
) free(r
->server
);
1056 _dns_append_question(dns_question_t
*q
, char **s
, uint16_t *l
)
1061 if (q
== NULL
) return;
1063 len
= *l
+ _dns_cname_length(q
->name
) + 2 + 4;
1064 *s
= realloc(*s
, len
);
1066 _dns_insert_cname(q
->name
, (char *)*s
+ *l
);
1072 *p
= htons(q
->dnstype
);
1076 *p
= htons(q
->dnsclass
);
1081 _dns_append_resource_record(dns_resource_record_t
*r
, char **s
, uint16_t *l
)
1083 uint16_t clen
, len
, *p
, extra
, rdlen
;
1087 if (r
== NULL
) return;
1097 clen
= _dns_cname_length(r
->data
.PTR
->name
);
1103 len
= *l
+ _dns_cname_length(r
->name
) + 2 + extra
;
1104 *s
= realloc(*s
, len
);
1106 _dns_insert_cname(r
->name
, (char *)*s
+ *l
);
1109 x
= *s
+ (len
- extra
);
1112 *p
= htons(r
->dnstype
);
1116 *p
= htons(r
->dnsclass
);
1120 *p2
= htonl(r
->ttl
);
1132 *p2
= htons(r
->data
.A
->addr
.s_addr
);
1137 clen
= _dns_cname_length(r
->data
.PTR
->name
) + 2;
1141 _dns_insert_cname(r
->data
.PTR
->name
, x
);
1150 dns_build_reply(dns_reply_t
*dnsr
, uint16_t *rl
)
1156 if (dnsr
== NULL
) return NULL
;
1166 h
= (dns_header_t
*)s
;
1168 h
->xid
= htons(dnsr
->header
->xid
);
1169 h
->flags
= htons(dnsr
->header
->flags
);
1170 h
->qdcount
= htons(dnsr
->header
->qdcount
);
1171 h
->ancount
= htons(dnsr
->header
->ancount
);
1172 h
->nscount
= htons(dnsr
->header
->nscount
);
1173 h
->arcount
= htons(dnsr
->header
->arcount
);
1175 for (i
= 0; i
< dnsr
->header
->qdcount
; i
++)
1177 _dns_append_question(dnsr
->question
[i
], &s
, rl
);
1180 for (i
= 0; i
< dnsr
->header
->ancount
; i
++)
1182 _dns_append_resource_record(dnsr
->answer
[i
], &s
, rl
);
1185 for (i
= 0; i
< dnsr
->header
->nscount
; i
++)
1187 _dns_append_resource_record(dnsr
->authority
[i
], &s
, rl
);
1190 for (i
= 0; i
< dnsr
->header
->arcount
; i
++)
1192 _dns_append_resource_record(dnsr
->additional
[i
], &s
, rl
);
1199 dns_free_question(dns_question_t
*q
)
1201 if (q
== NULL
) return;
1202 if (q
->name
!= NULL
) free(q
->name
);
1207 dns_set_buffer_size(dns_handle_t d
, uint32_t len
)
1209 dns_private_handle_t
*dns
;
1210 if (d
== NULL
) return;
1212 dns
= (dns_private_handle_t
*)d
;
1213 if (dns
->recvsize
== len
) return;
1215 if (dns
->recvbuf
!= NULL
)
1218 dns
->recvbuf
= NULL
;
1221 dns
->recvsize
= len
;
1222 if (dns
->recvsize
> DNS_MAX_RECEIVE_SIZE
) dns
->recvsize
= DNS_MAX_RECEIVE_SIZE
;
1224 if (dns
->recvsize
> 0) dns
->recvbuf
= malloc(dns
->recvsize
);
1228 dns_get_buffer_size(dns_handle_t d
)
1230 dns_private_handle_t
*dns
;
1231 if (d
== NULL
) return 0;
1233 dns
= (dns_private_handle_t
*)d
;
1234 return dns
->recvsize
;
1238 dns_lookup_soa_min(dns_handle_t d
, const char *name
, uint32_t class, uint32_t type
, int *min
)
1240 dns_private_handle_t
*dns
;
1243 struct sockaddr_storage
*from
;
1246 if (d
== NULL
) return NULL
;
1247 if (name
== NULL
) return NULL
;
1249 dns
= (dns_private_handle_t
*)d
;
1250 if (min
!= NULL
) *min
= -1;
1252 if (dns
->recvbuf
== NULL
)
1254 if (dns
->recvsize
== 0) dns
->recvsize
= DNS_DEFAULT_RECEIVE_SIZE
;
1256 dns
->recvbuf
= malloc(dns
->recvsize
);
1257 if (dns
->recvbuf
== NULL
) return NULL
;
1260 fromlen
= sizeof(struct sockaddr_storage
);
1261 from
= (struct sockaddr_storage
*)calloc(1, sizeof(struct sockaddr_storage
));
1264 if (dns
->handle_type
== DNS_PRIVATE_HANDLE_TYPE_SUPER
)
1266 _check_cache(dns
->sdns
);
1267 len
= _sdns_search(dns
->sdns
, name
, class, type
, 0, 1, dns
->recvbuf
, dns
->recvsize
, (struct sockaddr
*)from
, &fromlen
, min
);
1271 /* NB. Minumium SOA TTL values are NOT provided when the caller passes a DNS_PRIVATE_HANDLE_TYPE_PLAIN handle */
1272 len
= _pdns_search(dns
->sdns
, dns
->pdns
, name
, class, type
, dns
->recvbuf
, dns
->recvsize
, (struct sockaddr
*)from
, &fromlen
);
1281 r
= dns_parse_packet(dns
->recvbuf
, len
);
1283 if (r
== NULL
) free(from
);
1284 else r
->server
= (struct sockaddr
*)from
;
1290 dns_lookup(dns_handle_t d
, const char *name
, uint32_t class, uint32_t type
)
1294 return dns_lookup_soa_min(d
, name
, class, type
, &unused
);
1298 * DNS printing utilities
1302 coord_ntoa(int32_t coord
, uint32_t islat
)
1304 int32_t deg
, min
, sec
, secfrac
;
1305 static char buf
[64];
1308 coord
= coord
- 0x80000000;
1311 if ((islat
== 1) && (coord
< 0))
1327 secfrac
= coord
% 1000;
1328 coord
= coord
/ 1000;
1335 sprintf(buf
, "%d %.2d %.2d.%.3d %c", deg
, min
, sec
, secfrac
, dir
);
1340 alt_ntoa(int32_t alt
)
1342 int32_t ref
, m
, frac
, sign
;
1343 static char buf
[128];
1359 m
= (alt
/ 100) * sign
;
1361 sprintf(buf
, "%d.%.2d", m
, frac
);
1380 precsize_ntoa(uint8_t prec
)
1382 static char buf
[19];
1384 int mantissa
, exponent
;
1386 mantissa
= (int)((prec
>> 4) & 0x0f) % 10;
1387 exponent
= (int)((prec
>> 0) & 0x0f) % 10;
1389 val
= mantissa
* poweroften
[exponent
];
1391 sprintf(buf
, "%ld.%.2ld", val
/100, val%100
);
1396 dns_type_string(uint16_t t
)
1400 case ns_t_a
: return "A ";
1401 case ns_t_ns
: return "NS ";
1402 case ns_t_md
: return "MD ";
1403 case ns_t_mf
: return "MF ";
1404 case ns_t_cname
: return "CNAME";
1405 case ns_t_soa
: return "SOA ";
1406 case ns_t_mb
: return "MB ";
1407 case ns_t_mg
: return "MG ";
1408 case ns_t_mr
: return "MR ";
1409 case ns_t_null
: return "NULL ";
1410 case ns_t_wks
: return "WKS ";
1411 case ns_t_ptr
: return "PTR ";
1412 case ns_t_hinfo
: return "HINFO";
1413 case ns_t_minfo
: return "MINFO";
1414 case ns_t_mx
: return "MX ";
1415 case ns_t_txt
: return "TXT ";
1416 case ns_t_rp
: return "PR ";
1417 case ns_t_afsdb
: return "AFSDB";
1418 case ns_t_x25
: return "X25 ";
1419 case ns_t_isdn
: return "ISDN ";
1420 case ns_t_rt
: return "RT ";
1421 case ns_t_nsap
: return "NSAP ";
1422 case ns_t_nsap_ptr
: return "NSPTR";
1423 case ns_t_sig
: return "SIG ";
1424 case ns_t_key
: return "KEY ";
1425 case ns_t_px
: return "PX ";
1426 case ns_t_gpos
: return "GPOS ";
1427 case ns_t_aaaa
: return "AAAA ";
1428 case ns_t_loc
: return "LOC ";
1429 case ns_t_nxt
: return "NXT ";
1430 case ns_t_eid
: return "EID ";
1431 case ns_t_nimloc
: return "NIMLC";
1432 case ns_t_srv
: return "SRV ";
1433 case ns_t_atma
: return "ATMA ";
1434 case ns_t_naptr
: return "NAPTR";
1435 case ns_t_kx
: return "KX ";
1436 case ns_t_cert
: return "CERT ";
1437 case ns_t_a6
: return "A6 ";
1438 case ns_t_dname
: return "DNAME";
1439 case ns_t_sink
: return "SINK ";
1440 case ns_t_opt
: return "OPT ";
1441 case ns_t_tkey
: return "TKEY ";
1442 case ns_t_tsig
: return "TSIG ";
1443 case ns_t_ixfr
: return "IXFR ";
1444 case ns_t_axfr
: return "AXFR ";
1445 case ns_t_mailb
: return "MAILB";
1446 case ns_t_maila
: return "MAILA";
1447 case ns_t_any
: return "ANY ";
1448 case ns_t_zxfr
: return "ZXFR ";
1449 default: return "?????";
1456 dns_type_number(const char *t
, uint16_t *n
)
1458 if (t
== NULL
) return -1;
1460 if (!strcasecmp(t
, "A")) { *n
= ns_t_a
; return 0; }
1461 if (!strcasecmp(t
, "NS")) { *n
= ns_t_ns
; return 0; }
1462 if (!strcasecmp(t
, "MD")) { *n
= ns_t_md
; return 0; }
1463 if (!strcasecmp(t
, "MF")) { *n
= ns_t_mf
; return 0; }
1464 if (!strcasecmp(t
, "CNAME")) { *n
= ns_t_cname
; return 0; }
1465 if (!strcasecmp(t
, "SOA")) { *n
= ns_t_soa
; return 0; }
1466 if (!strcasecmp(t
, "MB")) { *n
= ns_t_mb
; return 0; }
1467 if (!strcasecmp(t
, "MG")) { *n
= ns_t_mg
; return 0; }
1468 if (!strcasecmp(t
, "MR")) { *n
= ns_t_mr
; return 0; }
1469 if (!strcasecmp(t
, "NULL")) { *n
= ns_t_null
; return 0; }
1470 if (!strcasecmp(t
, "WKS")) { *n
= ns_t_wks
; return 0; }
1471 if (!strcasecmp(t
, "PTR")) { *n
= ns_t_ptr
; return 0; }
1472 if (!strcasecmp(t
, "HINFO")) { *n
= ns_t_hinfo
; return 0; }
1473 if (!strcasecmp(t
, "MINFO")) { *n
= ns_t_minfo
; return 0; }
1474 if (!strcasecmp(t
, "TXT")) { *n
= ns_t_txt
; return 0; }
1475 if (!strcasecmp(t
, "RP")) { *n
= ns_t_rp
; return 0; }
1476 if (!strcasecmp(t
, "AFSDB")) { *n
= ns_t_afsdb
; return 0; }
1477 if (!strcasecmp(t
, "X25")) { *n
= ns_t_x25
; return 0; }
1478 if (!strcasecmp(t
, "ISDN")) { *n
= ns_t_isdn
; return 0; }
1479 if (!strcasecmp(t
, "RT")) { *n
= ns_t_rt
; return 0; }
1480 if (!strcasecmp(t
, "NSAP")) { *n
= ns_t_nsap
; return 0; }
1481 if (!strcasecmp(t
, "NSPTR")) { *n
= ns_t_nsap_ptr
; return 0; }
1482 if (!strcasecmp(t
, "NSAP_PTR")){ *n
= ns_t_nsap_ptr
; return 0; }
1483 if (!strcasecmp(t
, "SIG")) { *n
= ns_t_sig
; return 0; }
1484 if (!strcasecmp(t
, "KEY")) { *n
= ns_t_key
; return 0; }
1485 if (!strcasecmp(t
, "PX")) { *n
= ns_t_px
; return 0; }
1486 if (!strcasecmp(t
, "GPOS")) { *n
= ns_t_gpos
; return 0; }
1487 if (!strcasecmp(t
, "AAAA")) { *n
= ns_t_aaaa
; return 0; }
1488 if (!strcasecmp(t
, "LOC")) { *n
= ns_t_loc
; return 0; }
1489 if (!strcasecmp(t
, "NXT")) { *n
= ns_t_nxt
; return 0; }
1490 if (!strcasecmp(t
, "EID")) { *n
= ns_t_eid
; return 0; }
1491 if (!strcasecmp(t
, "NIMLOC")) { *n
= ns_t_nimloc
; return 0; }
1492 if (!strcasecmp(t
, "SRV")) { *n
= ns_t_srv
; return 0; }
1493 if (!strcasecmp(t
, "ATMA")) { *n
= ns_t_atma
; return 0; }
1494 if (!strcasecmp(t
, "NAPTR")) { *n
= ns_t_naptr
; return 0; }
1495 if (!strcasecmp(t
, "KX")) { *n
= ns_t_kx
; return 0; }
1496 if (!strcasecmp(t
, "CERT")) { *n
= ns_t_cert
; return 0; }
1497 if (!strcasecmp(t
, "A6")) { *n
= ns_t_a6
; return 0; }
1498 if (!strcasecmp(t
, "DNAME")) { *n
= ns_t_dname
; return 0; }
1499 if (!strcasecmp(t
, "SINK")) { *n
= ns_t_sink
; return 0; }
1500 if (!strcasecmp(t
, "OPT")) { *n
= ns_t_opt
; return 0; }
1501 if (!strcasecmp(t
, "TKEY")) { *n
= ns_t_tkey
; return 0; }
1502 if (!strcasecmp(t
, "TSIG")) { *n
= ns_t_tsig
; return 0; }
1503 if (!strcasecmp(t
, "IXFR")) { *n
= ns_t_ixfr
; return 0; }
1504 if (!strcasecmp(t
, "AXFR")) { *n
= ns_t_axfr
; return 0; }
1505 if (!strcasecmp(t
, "MAILB")) { *n
= ns_t_mailb
; return 0; }
1506 if (!strcasecmp(t
, "MAILA")) { *n
= ns_t_maila
; return 0; }
1507 if (!strcasecmp(t
, "ANY")) { *n
= ns_t_any
; return 0; }
1508 if (!strcasecmp(t
, "ZXFR")) { *n
= ns_t_zxfr
; return 0; }
1514 dns_class_string(uint16_t c
)
1518 case ns_c_in
: return "IN";
1519 case ns_c_2
: return "CS";
1520 case ns_c_chaos
: return "CH";
1521 case ns_c_hs
: return "HS";
1522 case ns_c_none
: return "NONE";
1523 case ns_c_any
: return "ANY";
1524 default: return "??";
1531 dns_class_number(const char *c
, uint16_t *n
)
1533 if (c
== NULL
) return -1;
1535 if (!strcasecmp(c
, "IN")) { *n
= ns_c_in
; return 0; }
1536 if (!strcasecmp(c
, "CS")) { *n
= ns_c_2
; return 0; }
1537 if (!strcasecmp(c
, "CH")) { *n
= ns_c_chaos
; return 0; }
1538 if (!strcasecmp(c
, "HS")) { *n
= ns_c_hs
; return 0; }
1539 if (!strcasecmp(c
, "NONE")) { *n
= ns_c_none
; return 0; }
1540 if (!strcasecmp(c
, "ANY")) { *n
= ns_c_any
; return 0; }
1546 _dns_print_question_lock(const dns_question_t
*q
, FILE *f
, int lockit
)
1548 if (lockit
!= 0) _dns_print_lock();
1549 fprintf(f
, "%s %s %s\n", q
->name
, dns_class_string(q
->dnsclass
), dns_type_string(q
->dnstype
));
1550 if (lockit
!= 0) _dns_print_unlock();
1554 dns_print_question(const dns_question_t
*q
, FILE *f
)
1556 _dns_print_question_lock(q
, f
, 1);
1560 _dns_print_resource_record_lock(const dns_resource_record_t
*r
, FILE *f
, int lockit
)
1566 struct sockaddr_in6 s6
;
1569 if (lockit
!= 0) _dns_print_lock();
1571 fprintf(f
, "%s %s %s ", r
->name
, dns_class_string(r
->dnsclass
), dns_type_string(r
->dnstype
));
1572 fprintf(f
, "%u", r
->ttl
);
1577 fprintf(f
, " %s", inet_ntoa(r
->data
.A
->addr
));
1581 memset(&s6
, 0, sizeof(struct sockaddr_in6
));
1582 s6
.sin6_len
= sizeof(struct sockaddr_in6
);
1583 s6
.sin6_family
= AF_INET6
;
1584 s6
.sin6_addr
= r
->data
.AAAA
->addr
;
1585 fprintf(f
, " %s", inet_ntop(AF_INET6
, (char *)(&s6
) + INET_NTOP_AF_INET6_OFFSET
, pbuf
, 64));
1596 fprintf(f
, " %s", r
->data
.CNAME
->name
);
1600 fprintf(f
, " %s %s %u %u %u %u %u",
1601 r
->data
.SOA
->mname
, r
->data
.SOA
->rname
,
1602 r
->data
.SOA
->serial
, r
->data
.SOA
->refresh
, r
->data
.SOA
->retry
,
1603 r
->data
.SOA
->expire
, r
->data
.SOA
->minimum
);
1607 fprintf(f
, " %s", inet_ntoa(r
->data
.WKS
->addr
));
1608 p
= getprotobynumber(r
->data
.WKS
->protocol
);
1611 fprintf(f
, " %s", p
->p_name
);
1613 for (i
= 0; i
< r
->data
.WKS
->maplength
; i
++)
1615 if (r
->data
.WKS
->map
[i
])
1617 s
= getservbyport(i
, p
->p_name
);
1618 if (s
== NULL
) fprintf(f
, " %u", i
);
1619 else fprintf(f
, " %s", s
->s_name
);
1623 else fprintf(f
, " UNKNOWN PROTOCOL %u", r
->data
.WKS
->protocol
);
1627 fprintf(f
, " %s %s", r
->data
.HINFO
->cpu
, r
->data
.HINFO
->os
);
1631 fprintf(f
, " %s %s", r
->data
.MINFO
->rmailbx
, r
->data
.MINFO
->emailbx
);
1635 fprintf(f
, " %u %s", r
->data
.MX
->preference
, r
->data
.MX
->name
);
1639 for (i
= 0; i
< r
->data
.TXT
->string_count
; i
++)
1641 fprintf(f
, " \"%s\"", r
->data
.TXT
->strings
[i
]);
1646 fprintf(f
, " %s %s", r
->data
.RP
->mailbox
, r
->data
.RP
->txtdname
);
1650 fprintf(f
, " %u %s", r
->data
.AFSDB
->subtype
,
1651 r
->data
.AFSDB
->hostname
);
1655 fprintf(f
, " %s", r
->data
.X25
->psdn_address
);
1659 fprintf(f
, " %s", r
->data
.ISDN
->isdn_address
);
1660 if (r
->data
.ISDN
->subaddress
!= NULL
)
1661 fprintf(f
, " %s", r
->data
.ISDN
->subaddress
);
1665 fprintf(f
, " %hu %s", r
->data
.RT
->preference
,
1666 r
->data
.RT
->intermediate
);
1670 fprintf(f
, " %s", coord_ntoa(r
->data
.LOC
->latitude
, 1));
1671 fprintf(f
, " %s", coord_ntoa(r
->data
.LOC
->longitude
, 0));
1672 fprintf(f
, " %sm", alt_ntoa(r
->data
.LOC
->altitude
));
1673 fprintf(f
, " %sm", precsize_ntoa(r
->data
.LOC
->size
));
1674 fprintf(f
, " %sm", precsize_ntoa(r
->data
.LOC
->horizontal_precision
));
1675 fprintf(f
, " %sm", precsize_ntoa(r
->data
.LOC
->vertical_precision
));
1679 fprintf(f
, " %hu %hu %hu %s",
1680 r
->data
.SRV
->priority
, r
->data
.SRV
->weight
,
1681 r
->data
.SRV
->port
, r
->data
.SRV
->target
);
1686 len
= r
->data
.DNSNULL
->length
;
1687 fprintf(f
, " %hu ", len
);
1688 for (i
= 0; i
< len
; i
++)
1690 x
= r
->data
.DNSNULL
->data
[i
];
1691 fprintf(f
, "%x", x
);
1696 len
= r
->data
.DNSNULL
->length
;
1697 for (i
= 0; i
< len
; i
++)
1699 x
= r
->data
.DNSNULL
->data
[i
];
1700 if (isascii(x
)) fprintf(f
, "%c", x
);
1701 else fprintf(f
, " ");
1709 if (lockit
!= 0) _dns_print_unlock();
1713 dns_print_resource_record(const dns_resource_record_t
*r
, FILE *f
)
1715 _dns_print_resource_record_lock(r
, f
, 1);
1719 dns_print_reply(const dns_reply_t
*r
, FILE *f
, uint16_t mask
)
1724 uint32_t offset
, iface
;
1730 fprintf(f
, "-nil-\n");
1731 _dns_print_unlock();
1735 if (r
->status
!= DNS_STATUS_OK
)
1737 if (r
->status
== DNS_STATUS_TIMEOUT
)
1738 fprintf(f
, "Timeout\n");
1739 else if (r
->status
== DNS_STATUS_SEND_FAILED
)
1740 fprintf(f
, "Send failed\n");
1741 else if (r
->status
== DNS_STATUS_RECEIVE_FAILED
)
1742 fprintf(f
, "Receive failed\n");
1743 else fprintf(f
, "status %u\n", r
->status
);
1745 _dns_print_unlock();
1751 if (mask
& DNS_PRINT_XID
)
1753 fprintf(f
, "Xid: %u\n", h
->xid
);
1756 if (mask
& DNS_PRINT_QR
)
1758 if ((h
->flags
& DNS_FLAGS_QR_MASK
) == DNS_FLAGS_QR_QUERY
)
1759 fprintf(f
, "QR: Query\n");
1761 fprintf(f
, "QR: Reply\n");
1764 if (mask
& DNS_PRINT_SERVER
)
1766 if (r
->server
== NULL
)
1768 fprintf(f
, "Server: -nil-\n");
1772 offset
= INET_NTOP_AF_INET_OFFSET
;
1773 if (r
->server
->sa_family
== AF_INET6
) offset
= INET_NTOP_AF_INET6_OFFSET
;
1775 fprintf(f
, "Server: %s", inet_ntop(r
->server
->sa_family
, (char *)(r
->server
) + offset
, scratch
, 1024));
1776 if (r
->server
->sa_family
== AF_INET
)
1778 memcpy(&iface
, (((struct sockaddr_in
*)(r
->server
))->sin_zero
), 4);
1779 if (iface
> 0) fprintf(f
, "%%%s", if_indextoname(iface
, scratch
));
1781 else if (r
->server
->sa_family
== AF_INET6
)
1783 iface
= ((struct sockaddr_in6
*)(r
->server
))->sin6_scope_id
;
1784 if (iface
> 0) fprintf(f
, "%%%s", if_indextoname(iface
, scratch
));
1790 if (mask
& DNS_PRINT_OPCODE
)
1792 fprintf(f
, "Opcode: ");
1793 switch (h
->flags
& DNS_FLAGS_OPCODE_MASK
)
1795 case ns_o_query
: fprintf(f
, "Standard\n"); break;
1796 case ns_o_iquery
: fprintf(f
, "Inverse\n"); break;
1797 case ns_o_status
: fprintf(f
, "Status\n"); break;
1798 case ns_o_notify
: fprintf(f
, "Notify\n"); break;
1799 case ns_o_update
: fprintf(f
, "Update\n"); break;
1801 fprintf(f
, "Reserved (%hu)\n",
1802 (h
->flags
& DNS_FLAGS_OPCODE_MASK
) >> 11);
1806 if (mask
& DNS_PRINT_AA
)
1808 if (h
->flags
& DNS_FLAGS_AA
) fprintf(f
, "AA: Authoritative\n");
1809 else fprintf(f
, "AA: Non-Authoritative\n");
1812 if (mask
& DNS_PRINT_TC
)
1814 if (h
->flags
& DNS_FLAGS_TC
) fprintf(f
, "TC: Truncated\n");
1815 else fprintf(f
, "TC: Non-Truncated\n");
1818 if (mask
& DNS_PRINT_RD
)
1820 if (h
->flags
& DNS_FLAGS_RD
) fprintf(f
, "RD: Recursion desired\n");
1821 else fprintf(f
, "RD: No recursion desired\n");
1824 if (mask
& DNS_PRINT_RA
)
1826 if (h
->flags
& DNS_FLAGS_RA
) fprintf(f
, "RA: Recursion available\n");
1827 else fprintf(f
, "RA: No recursion available \n");
1830 if (mask
& DNS_PRINT_RCODE
)
1832 fprintf(f
, "Rcode: ");
1833 switch (h
->flags
& DNS_FLAGS_RCODE_MASK
)
1836 fprintf(f
, "No error\n");
1839 fprintf(f
, "Format error \n");
1842 fprintf(f
, "Server failure\n");
1845 fprintf(f
, "Name error \n");
1848 fprintf(f
, "Not implemented\n");
1851 fprintf(f
, "Refused\n");
1854 fprintf(f
, "Name exists\n");
1857 fprintf(f
, "RR Set exists\n");
1860 fprintf(f
, "RR Set does not exist\n");
1863 fprintf(f
, "Not authoritative\n");
1866 fprintf(f
, "Record zone does not match section zone\n");
1869 fprintf(f
, "Invalid EDNS version or TSIG signature\n");
1872 fprintf(f
, "Invalid key\n");
1875 fprintf(f
, "Invalid time\n");
1878 fprintf(f
, "Reserved (%hu)\n",h
->flags
& DNS_FLAGS_RCODE_MASK
);
1882 if (mask
& DNS_PRINT_QUESTION
)
1884 fprintf(f
, "Question (%hu):\n", h
->qdcount
);
1885 for (i
= 0; i
< h
->qdcount
; i
++)
1886 _dns_print_question_lock(r
->question
[i
], f
, 0);
1889 if (mask
& DNS_PRINT_ANSWER
)
1891 fprintf(f
, "Answer (%hu):\n", h
->ancount
);
1892 for (i
= 0; i
< h
->ancount
; i
++)
1893 _dns_print_resource_record_lock(r
->answer
[i
], f
, 0);
1896 if (mask
& DNS_PRINT_AUTHORITY
)
1898 fprintf(f
, "Authority (%hu):\n", h
->nscount
);
1899 for (i
= 0; i
< h
->nscount
; i
++)
1900 _dns_print_resource_record_lock(r
->authority
[i
], f
, 0);
1903 if (mask
& DNS_PRINT_ADDITIONAL
)
1905 fprintf(f
, "Additional records (%hu):\n", h
->arcount
);
1906 for (i
= 0; i
< h
->arcount
; i
++)
1907 _dns_print_resource_record_lock(r
->additional
[i
], f
, 0);
1910 _dns_print_unlock();
1914 _pdns_print_handle(pdns_handle_t
*pdns
, FILE *f
)
1919 struct sockaddr
*sa
;
1924 fprintf(f
, "-nil-\n");
1928 if (pdns
->name
== NULL
) fprintf(f
, "Name: -nil-\n");
1929 else fprintf(f
, "Name: %s\n", pdns
->name
);
1931 fprintf(f
, "Flags:");
1932 if (pdns
->flags
== 0) fprintf(f
, " None\n");
1935 if (pdns
->flags
& DNS_FLAG_DEBUG
) fprintf(f
, " Debug");
1936 if (pdns
->flags
& DNS_FLAG_CHECK_RESOLVER_DIR
) fprintf(f
, " DirCheck");
1937 if (pdns
->flags
& DNS_FLAG_HAVE_IPV6_SERVER
) fprintf(f
, " IPv6");
1938 if (pdns
->flags
& DNS_FLAG_OK_TO_SKIP_AAAA
) fprintf(f
, " SkipAAAA");
1939 if (pdns
->flags
& DNS_FLAG_DEFAULT_RESOLVER
) fprintf(f
, " Default");
1944 if (r
== NULL
) return;
1946 if (r
->defdname
[0] != '\0') fprintf(f
, "Domain: %s\n", r
->defdname
);
1947 fprintf(f
, "Search Order: %d\n", pdns
->search_order
);
1948 fprintf(f
, "Total Timeout: %d\n", pdns
->total_timeout
);
1949 fprintf(f
, "Retry Timeout: %d\n", pdns
->res
->retrans
);
1950 fprintf(f
, "Retry Attempts: %d\n", pdns
->res
->retry
);
1952 fprintf(f
, "Server%s:\n", (r
->nscount
== 1) ? "" : "s");
1953 for (i
= 0; i
< r
->nscount
; i
++)
1955 sa
= get_nsaddr(r
, i
);
1956 offset
= INET_NTOP_AF_INET_OFFSET
;
1957 if (sa
->sa_family
== AF_INET6
) offset
= INET_NTOP_AF_INET6_OFFSET
;
1958 fprintf(f
, " %u: %s", i
, inet_ntop(sa
->sa_family
, (char *)sa
+ offset
, scratch
, 1024));
1962 if (pdns
->search_count
> 0)
1964 fprintf(f
, "Search List:\n");
1965 for (i
= 0; i
< pdns
->search_count
; i
++)
1966 fprintf(f
, " %u: %s\n", i
, pdns
->search_list
[i
]);
1969 if (r
->sort_list
[0].addr
.s_addr
!= 0)
1971 fprintf(f
, "Sortlist:\n");
1972 for (i
= 0; (r
->sort_list
[i
].addr
.s_addr
!= 0); i
++)
1974 fprintf(f
, " %u: ", i
);
1975 a
.s_addr
= r
->sort_list
[i
].addr
.s_addr
;
1976 fprintf(f
, "%s/", inet_ntoa(a
));
1977 a
.s_addr
= r
->sort_list
[i
].mask
;
1978 fprintf(f
, "%s\n", inet_ntoa(a
));
1984 _sdns_print_handle(sdns_handle_t
*sdns
, FILE *f
)
1990 fprintf(f
, "-nil-\n");
1994 for (i
= 0; i
< sdns
->client_count
; i
++)
1996 fprintf(f
, "DNS client %d\n", i
);
1997 _pdns_print_handle(sdns
->client
[i
], f
);
2001 fprintf(f
, "resolver dir mod time = %u\n", sdns
->modtime
);
2002 fprintf(f
, "resolver dir stat time = %u\n", sdns
->stattime
);
2003 fprintf(f
, "resolver dir stat latency = %u\n", sdns
->stat_latency
);
2007 dns_print_handle(dns_handle_t d
, FILE *f
)
2009 dns_private_handle_t
*dns
;
2015 fprintf(f
, "-nil-\n");
2016 _dns_print_unlock();
2020 dns
= (dns_private_handle_t
*)d
;
2022 if (dns
->handle_type
== DNS_PRIVATE_HANDLE_TYPE_SUPER
)
2024 _sdns_print_handle(dns
->sdns
, f
);
2028 _pdns_print_handle(dns
->pdns
, f
);
2031 _dns_print_unlock();
2035 dns_all_server_addrs(dns_handle_t d
, struct sockaddr
***addrs
, uint32_t *count
)
2037 int i
, j
, k
, n
, found
;
2038 dns_private_handle_t
*dns
;
2039 pdns_handle_t
*pdns
;
2040 struct sockaddr
*sa
;
2041 struct sockaddr_storage
**l
;
2049 if (d
== NULL
) return;
2051 dns
= (dns_private_handle_t
*)d
;
2053 if (dns
->handle_type
!= DNS_PRIVATE_HANDLE_TYPE_SUPER
) return;
2055 if (dns
->sdns
== NULL
) return;
2057 /* Just to initialize / validate clients */
2058 i
= dns_search_list_count(d
);
2060 for (i
= 0; i
< dns
->sdns
->client_count
; i
++)
2062 pdns
= dns
->sdns
->client
[i
];
2063 if (pdns
== NULL
) continue;
2066 if (r
== NULL
) continue;
2068 for (j
= 0; j
< r
->nscount
; j
++)
2070 sa
= get_nsaddr(r
, j
);
2072 for (k
= 0; (found
== 0) && (k
< n
); k
++)
2074 if (memcmp(l
[k
], sa
, sa
->sa_len
) == 0) found
= 1;
2076 if (found
== 1) continue;
2080 l
= (struct sockaddr_storage
**)calloc(1, sizeof(struct sockaddr_storage
*));
2084 l
= (struct sockaddr_storage
**)reallocf(l
, (n
+ 1) * sizeof(struct sockaddr_storage
*));
2087 if (l
== NULL
) return;
2089 l
[n
] = (struct sockaddr_storage
*)calloc(1, sizeof(struct sockaddr_storage
));
2090 if (l
[n
] == NULL
) return;
2092 memset(l
[n
], 0, sizeof(struct sockaddr_storage
));
2093 memcpy(l
[n
], sa
, sa
->sa_len
);
2098 *addrs
= (struct sockaddr
**)l
;
2103 dns_res_once(struct sockaddr
*server
, struct timeval
*timeout
, int options
, const char *name
, int class, int type
, u_char
*res
, int *reslen
)
2106 int n
, fromlen
, status
;
2107 struct sockaddr_storage from
;
2108 u_char buf
[MAXPACKET
];
2110 if (server
== NULL
) return DNS_RES_STATUS_INVALID_ARGUMENT
;
2111 if (name
== NULL
) return DNS_RES_STATUS_INVALID_ARGUMENT
;
2112 if (res
== NULL
) return DNS_RES_STATUS_INVALID_ARGUMENT
;
2113 if (reslen
== NULL
) return DNS_RES_STATUS_INVALID_ARGUMENT
;
2115 fromlen
= sizeof(struct sockaddr_storage
);
2117 statp
= res_state_new();
2119 statp
->options
= options
;
2120 statp
->id
= res_randomid();
2121 if (timeout
== NULL
) statp
->retrans
= 5;
2122 else statp
->retrans
= timeout
->tv_sec
;
2125 statp
->_vcsock
= -1;
2128 strcpy(statp
->_u
._ext
.ext
->nsuffix
, "ip6.arpa");
2129 strcpy(statp
->_u
._ext
.ext
->nsuffix2
, "ip6.int");
2130 strcpy(statp
->_u
._ext
.ext
->bsuffix
, "ip6.arpa");
2132 if (server
->sa_family
== AF_INET6
)
2134 memcpy(&(statp
->_u
._ext
.ext
->nsaddrs
[0]), server
, sizeof(struct sockaddr_in6
));
2135 statp
->nsaddr_list
[0].sin_family
= 0;
2139 memcpy(&(statp
->_u
._ext
.ext
->nsaddrs
[0]), server
, sizeof(struct sockaddr_in
));
2140 memcpy(&(statp
->nsaddr_list
[0]), server
, sizeof(struct sockaddr_in
));
2143 n
= res_nmkquery(statp
, ns_o_query
, name
, class, type
, NULL
, 0, NULL
, buf
, sizeof(buf
));
2145 status
= dns_res_send(statp
, buf
, n
, res
, reslen
, (struct sockaddr
*)&from
, &fromlen
);
2147 res_client_close(statp
);