2 * Copyright (c) 1999-2007 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
34 #include <sys/types.h>
35 #include <sys/socket.h>
39 #include <netinet/in.h>
40 #include <arpa/nameser.h>
44 #include "dns_private.h"
45 #include "res_private.h"
47 #define DNS_RESOLVER_DIR "/etc/resolver"
49 #define DNS_PRIVATE_HANDLE_TYPE_SUPER 0
50 #define DNS_PRIVATE_HANDLE_TYPE_PLAIN 1
51 #define DNS_DEFAULT_RECEIVE_SIZE 8192
52 #define DNS_MAX_RECEIVE_SIZE 65536
54 #define SDNS_DEFAULT_STAT_LATENCY 10
56 #define DNS_FLAGS_QR_MASK 0x8000
57 #define DNS_FLAGS_QR_QUERY 0x0000
59 #define DNS_FLAGS_OPCODE_MASK 0x7800
61 #define DNS_FLAGS_RCODE_MASK 0x000f
63 #define DNS_FLAGS_AA 0x0400
64 #define DNS_FLAGS_TC 0x0200
65 #define DNS_FLAGS_RD 0x0100
66 #define DNS_FLAGS_RA 0x0080
68 #define DNS_SOCK_UDP 0
69 #define DNS_SOCK_TCP_UNCONNECTED 1
70 #define DNS_SOCK_TCP_CONNECTED 2
72 #define INET_NTOP_AF_INET_OFFSET 4
73 #define INET_NTOP_AF_INET6_OFFSET 8
75 #define MAXPACKET 1024
77 extern void res_client_close(res_state res
);
78 extern int __res_nquery(res_state statp
, const char *name
, int class, int type
, u_char
*answer
, int anslen
);
79 extern int dns_res_send(res_state statp
, const u_char
*buf
, int buflen
, u_char
*ans
, int *anssiz
, struct sockaddr
*from
, int *fromlen
);
80 extern void _check_cache(sdns_handle_t
*sdns
);
81 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
);
82 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
);
83 static pthread_mutex_t _dnsPrintLock
= PTHREAD_MUTEX_INITIALIZER
;
88 pthread_mutex_lock(&_dnsPrintLock
);
92 _dns_print_unlock(void)
94 pthread_mutex_unlock(&_dnsPrintLock
);
99 _dns_parse_uint8(char **p
)
109 _dns_parse_uint16(char **p
)
120 _dns_parse_uint32(char **p
)
131 _dns_cname_length(char *s
)
135 if (s
== NULL
) return 1;
137 while ((s
[l
- 1] == '.') && (l
> 1)) l
--;
142 _dns_insert_cname(char *s
, char *p
)
161 len
= _dns_cname_length(s
);
164 memmove(p
+ 1, s
, len
);
169 for (i
= len
+ 1; i
>= 0; i
--)
181 _dns_parse_string(const char *p
, char **x
, int32_t *remaining
)
186 if (*remaining
< 1) return NULL
;
192 if (*remaining
< len
) return NULL
;
195 str
= malloc(len
+ 1);
196 memmove(str
, *x
, len
);
204 _dns_parse_domain_name(const char *p
, char **x
, int32_t *remaining
)
208 uint16_t i
, j
, dlen
, len
;
209 int more
, compressed
;
210 char *name
, *start
, *y
, *z
;
212 if (*remaining
< 1) return NULL
;
235 if ((dlen
& 0xc0) == 0xc0)
243 v16
= (uint16_t *)*x
;
245 y
= (char *)p
+ (ntohs(*v16
) & 0x3fff);
246 if ((*x
== y
) || (y
> z
))
253 if (compressed
== 0) skip
+= 2;
269 name
= realloc(name
, len
);
278 for (i
= 0; i
< dlen
; i
++)
285 if (compressed
== 0) skip
+= (dlen
+ 1);
287 if (dlen
== 0) more
= 0;
300 name
= realloc(name
, len
);
307 if ((start
+ skip
) > z
)
319 dns_resource_record_t
*
320 _dns_parse_resource_record_internal(const char *p
, char **x
, int32_t *remaining
)
322 uint32_t size
, bx
, mi
;
325 dns_resource_record_t
*r
;
328 if (*remaining
< 1) return NULL
;
330 r
= (dns_resource_record_t
*)calloc(1, sizeof(dns_resource_record_t
));
332 r
->name
= _dns_parse_domain_name(p
, x
, remaining
);
335 dns_free_resource_record(r
);
341 dns_free_resource_record(r
);
345 r
->dnstype
= _dns_parse_uint16(x
);
346 r
->dnsclass
= _dns_parse_uint16(x
);
347 r
->ttl
= _dns_parse_uint32(x
);
348 rdlen
= _dns_parse_uint16(x
);
352 if (*remaining
< rdlen
)
354 dns_free_resource_record(r
);
366 dns_free_resource_record(r
);
372 size
= sizeof(dns_address_record_t
);
373 r
->data
.A
= (dns_address_record_t
*)calloc(1, size
);
374 r
->data
.A
->addr
.s_addr
= htonl(_dns_parse_uint32(x
));
380 dns_free_resource_record(r
);
386 size
= sizeof(dns_in6_address_record_t
);
387 r
->data
.AAAA
= (dns_in6_address_record_t
*)calloc(1, size
);
388 r
->data
.AAAA
->addr
.__u6_addr
.__u6_addr32
[0] = htonl(_dns_parse_uint32(x
));
389 r
->data
.AAAA
->addr
.__u6_addr
.__u6_addr32
[1] = htonl(_dns_parse_uint32(x
));
390 r
->data
.AAAA
->addr
.__u6_addr
.__u6_addr32
[2] = htonl(_dns_parse_uint32(x
));
391 r
->data
.AAAA
->addr
.__u6_addr
.__u6_addr32
[3] = htonl(_dns_parse_uint32(x
));
402 size
= sizeof(dns_domain_name_record_t
);
403 r
->data
.CNAME
= (dns_domain_name_record_t
*)calloc(1,size
);
404 r
->data
.CNAME
->name
= _dns_parse_domain_name(p
, x
, remaining
);
405 if (r
->data
.CNAME
->name
== NULL
)
407 dns_free_resource_record(r
);
413 size
= sizeof(dns_SOA_record_t
);
414 r
->data
.SOA
= (dns_SOA_record_t
*)calloc(1, size
);
416 r
->data
.SOA
->mname
= _dns_parse_domain_name(p
, x
, remaining
);
417 if (r
->data
.SOA
->mname
== NULL
)
419 dns_free_resource_record(r
);
423 r
->data
.SOA
->rname
= _dns_parse_domain_name(p
, x
, remaining
);
424 if (r
->data
.SOA
->rname
== NULL
)
426 dns_free_resource_record(r
);
432 dns_free_resource_record(r
);
438 r
->data
.SOA
->serial
= _dns_parse_uint32(x
);
439 r
->data
.SOA
->refresh
= _dns_parse_uint32(x
);
440 r
->data
.SOA
->retry
= _dns_parse_uint32(x
);
441 r
->data
.SOA
->expire
= _dns_parse_uint32(x
);
442 r
->data
.SOA
->minimum
= _dns_parse_uint32(x
);
448 dns_free_resource_record(r
);
454 size
= sizeof(dns_WKS_record_t
);
455 r
->data
.WKS
= (dns_WKS_record_t
*)calloc(1, size
);
457 r
->data
.WKS
->addr
.s_addr
= htonl(_dns_parse_uint32(x
));
458 r
->data
.WKS
->protocol
= _dns_parse_uint8(x
);
460 r
->data
.WKS
->maplength
= size
* 8;
461 r
->data
.WKS
->map
= NULL
;
462 if (size
== 0) break;
464 r
->data
.WKS
->map
= (uint8_t *)calloc(1, r
->data
.WKS
->maplength
);
466 for (bx
= 0; bx
< size
; bx
++)
468 byte
= _dns_parse_uint8(x
);
469 for (i
= 128; i
>= 1; i
= i
/2)
471 if (byte
& i
) r
->data
.WKS
->map
[mi
] = 0xff;
472 else r
->data
.WKS
->map
[mi
] = 0;
479 size
= sizeof(dns_HINFO_record_t
);
480 r
->data
.HINFO
= (dns_HINFO_record_t
*)calloc(1, size
);
482 r
->data
.HINFO
->cpu
= _dns_parse_string(p
, x
, remaining
);
483 if (r
->data
.HINFO
->cpu
== NULL
)
485 dns_free_resource_record(r
);
489 r
->data
.HINFO
->os
= _dns_parse_string(p
, x
, remaining
);
490 if (r
->data
.HINFO
->os
== NULL
)
492 dns_free_resource_record(r
);
499 size
= sizeof(dns_MINFO_record_t
);
500 r
->data
.MINFO
= (dns_MINFO_record_t
*)calloc(1, size
);
502 r
->data
.MINFO
->rmailbx
= _dns_parse_domain_name(p
, x
, remaining
);
503 if (r
->data
.MINFO
->rmailbx
== NULL
)
505 dns_free_resource_record(r
);
509 r
->data
.MINFO
->emailbx
= _dns_parse_domain_name(p
, x
, remaining
);
510 if (r
->data
.MINFO
->emailbx
== NULL
)
512 dns_free_resource_record(r
);
521 dns_free_resource_record(r
);
527 size
= sizeof(dns_MX_record_t
);
528 r
->data
.MX
= (dns_MX_record_t
*)calloc(1, size
);
530 r
->data
.MX
->preference
= _dns_parse_uint16(x
);
531 r
->data
.MX
->name
= _dns_parse_domain_name(p
, x
, remaining
);
532 if (r
->data
.MX
->name
== NULL
)
534 dns_free_resource_record(r
);
541 size
= sizeof(dns_TXT_record_t
);
542 r
->data
.TXT
= (dns_TXT_record_t
*)malloc(size
);
543 r
->data
.TXT
->string_count
= 0;
544 r
->data
.TXT
->strings
= NULL
;
546 while (*x
< (eor
+ rdlen
))
548 if (r
->data
.TXT
->string_count
== 0)
550 r
->data
.TXT
->strings
= (char **)calloc(1, sizeof(char *));
554 r
->data
.TXT
->strings
= (char **)realloc(r
->data
.TXT
->strings
, (r
->data
.TXT
->string_count
+ 1) * sizeof(char *));
557 r
->data
.TXT
->strings
[r
->data
.TXT
->string_count
] = _dns_parse_string(p
, x
, remaining
);
558 if (r
->data
.TXT
->strings
[r
->data
.TXT
->string_count
] == NULL
)
560 dns_free_resource_record(r
);
563 r
->data
.TXT
->string_count
++;
569 size
= sizeof(dns_RP_record_t
);
570 r
->data
.RP
= (dns_RP_record_t
*)calloc(1, size
);
572 r
->data
.RP
->mailbox
= _dns_parse_domain_name(p
, x
, remaining
);
573 if (r
->data
.RP
->mailbox
== NULL
)
575 dns_free_resource_record(r
);
579 r
->data
.RP
->txtdname
= _dns_parse_domain_name(p
, x
, remaining
);
580 if (r
->data
.RP
->txtdname
== NULL
)
582 dns_free_resource_record(r
);
591 dns_free_resource_record(r
);
596 size
= sizeof(dns_AFSDB_record_t
);
597 r
->data
.AFSDB
= (dns_AFSDB_record_t
*)calloc(1, size
);
599 r
->data
.AFSDB
->subtype
= _dns_parse_uint32(x
);
600 r
->data
.AFSDB
->hostname
= _dns_parse_domain_name(p
, x
, remaining
);
601 if (r
->data
.AFSDB
->hostname
== NULL
)
603 dns_free_resource_record(r
);
610 size
= sizeof(dns_X25_record_t
);
611 r
->data
.X25
= (dns_X25_record_t
*)calloc(1, size
);
613 r
->data
.X25
->psdn_address
= _dns_parse_string(p
, x
, remaining
);
614 if (r
->data
.X25
->psdn_address
== NULL
)
616 dns_free_resource_record(r
);
623 size
= sizeof(dns_ISDN_record_t
);
624 r
->data
.ISDN
= (dns_ISDN_record_t
*)calloc(1, size
);
626 r
->data
.ISDN
->isdn_address
= _dns_parse_string(p
, x
, remaining
);
627 if (r
->data
.ISDN
->isdn_address
== NULL
)
629 dns_free_resource_record(r
);
633 if (*x
< (eor
+ rdlen
))
635 r
->data
.ISDN
->subaddress
= _dns_parse_string(p
, x
, remaining
);
636 if (r
->data
.ISDN
->subaddress
== NULL
)
638 dns_free_resource_record(r
);
644 r
->data
.ISDN
->subaddress
= NULL
;
652 dns_free_resource_record(r
);
658 size
= sizeof(dns_RT_record_t
);
659 r
->data
.RT
= (dns_RT_record_t
*)calloc(1, size
);
661 r
->data
.RT
->preference
= _dns_parse_uint16(x
);
662 r
->data
.RT
->intermediate
= _dns_parse_domain_name(p
, x
, remaining
);
663 if (r
->data
.RT
->intermediate
== NULL
)
665 dns_free_resource_record(r
);
674 dns_free_resource_record(r
);
680 size
= sizeof(dns_LOC_record_t
);
681 r
->data
.LOC
= (dns_LOC_record_t
*)calloc(1, size
);
683 r
->data
.LOC
->version
= _dns_parse_uint8(x
);
684 r
->data
.LOC
->size
= _dns_parse_uint8(x
);
685 r
->data
.LOC
->horizontal_precision
= _dns_parse_uint8(x
);
686 r
->data
.LOC
->vertical_precision
= _dns_parse_uint8(x
);
687 r
->data
.LOC
->latitude
= _dns_parse_uint32(x
);
688 r
->data
.LOC
->longitude
= _dns_parse_uint32(x
);
689 r
->data
.LOC
->altitude
= _dns_parse_uint32(x
);
695 dns_free_resource_record(r
);
701 size
= sizeof(dns_SRV_record_t
);
702 r
->data
.SRV
= (dns_SRV_record_t
*)calloc(1, size
);
704 r
->data
.SRV
->priority
= _dns_parse_uint16(x
);
705 r
->data
.SRV
->weight
= _dns_parse_uint16(x
);
706 r
->data
.SRV
->port
= _dns_parse_uint16(x
);
707 r
->data
.SRV
->target
= _dns_parse_domain_name(p
, x
, remaining
);
708 if (r
->data
.SRV
->target
== NULL
)
710 dns_free_resource_record(r
);
720 size
= sizeof(dns_raw_resource_record_t
);
721 r
->data
.DNSNULL
= (dns_raw_resource_record_t
*)calloc(1, size
);
723 r
->data
.DNSNULL
->length
= rdlen
;
724 r
->data
.DNSNULL
->data
= calloc(1, rdlen
);
725 memmove(r
->data
.DNSNULL
->data
, *x
, rdlen
);
734 dns_resource_record_t
*
735 dns_parse_resource_record(const char *buf
, uint32_t len
)
742 return _dns_parse_resource_record_internal(buf
, &x
, &remaining
);
746 _dns_parse_question_internal(const char *p
, char **x
, int32_t *remaining
)
750 if (x
== NULL
) return NULL
;
751 if (*x
== NULL
) return NULL
;
752 if (*remaining
< 1) return NULL
;
754 q
= (dns_question_t
*)calloc(1, sizeof(dns_question_t
));
756 q
->name
= _dns_parse_domain_name(p
, x
, remaining
);
770 *remaining
= *remaining
- 4;
772 q
->dnstype
= _dns_parse_uint16(x
);
773 q
->dnsclass
= _dns_parse_uint16(x
);
779 dns_parse_question(const char *buf
, uint32_t len
)
786 return _dns_parse_question_internal(buf
, &x
, &remaining
);
791 dns_parse_packet(const char *p
, uint32_t len
)
799 if (p
== NULL
) return NULL
;
800 if (len
< NS_HFIXEDSZ
) return NULL
;
804 r
= (dns_reply_t
*)calloc(1, sizeof(dns_reply_t
));
806 r
->header
= (dns_header_t
*)calloc(1, sizeof(dns_header_t
));
809 h
->xid
= _dns_parse_uint16(&x
);
810 h
->flags
= _dns_parse_uint16(&x
);
811 h
->qdcount
= _dns_parse_uint16(&x
);
812 h
->ancount
= _dns_parse_uint16(&x
);
813 h
->nscount
= _dns_parse_uint16(&x
);
814 h
->arcount
= _dns_parse_uint16(&x
);
816 remaining
= len
- NS_HFIXEDSZ
;
818 size
= sizeof(dns_question_t
*);
819 r
->question
= (dns_question_t
**)calloc(h
->qdcount
, size
);
820 for (i
= 0; i
< h
->qdcount
; i
++)
822 r
->question
[i
] = _dns_parse_question_internal(p
, &x
, &remaining
);
823 if (r
->question
[i
] ==NULL
)
826 if (i
> 0) h
->qdcount
= i
- 1;
835 size
= sizeof(dns_resource_record_t
*);
837 r
->answer
= (dns_resource_record_t
**)calloc(h
->ancount
, size
);
838 for (i
= 0; i
< h
->ancount
; i
++)
840 r
->answer
[i
] = _dns_parse_resource_record_internal(p
, &x
, &remaining
);
841 if (r
->answer
[i
] == NULL
)
844 if (i
> 0) h
->ancount
= i
- 1;
852 r
->authority
= (dns_resource_record_t
**)calloc(h
->nscount
, size
);
853 for (i
= 0; i
< h
->nscount
; i
++)
855 r
->authority
[i
] = _dns_parse_resource_record_internal(p
, &x
, &remaining
);
856 if (r
->authority
[i
] == NULL
)
859 if (i
> 0) h
->nscount
= i
- 1;
866 r
->additional
= (dns_resource_record_t
**)calloc(h
->arcount
, size
);
867 for (i
= 0; i
< h
->arcount
; i
++)
869 r
->additional
[i
] = _dns_parse_resource_record_internal(p
, &x
, &remaining
);
870 if (r
->additional
[i
] == NULL
)
873 if (i
> 0) h
->arcount
= i
- 1;
883 dns_free_resource_record(dns_resource_record_t
*r
)
892 if (r
->data
.A
!= NULL
) free(r
->data
.A
);
896 if (r
->data
.AAAA
!= NULL
) free(r
->data
.AAAA
);
907 if (r
->data
.CNAME
!= NULL
)
909 if (r
->data
.CNAME
->name
!= NULL
) free(r
->data
.CNAME
->name
);
915 if (r
->data
.SOA
!= NULL
)
917 if (r
->data
.SOA
->mname
!= NULL
) free(r
->data
.SOA
->mname
);
918 if (r
->data
.SOA
->rname
!= NULL
) free(r
->data
.SOA
->rname
);
924 if (r
->data
.WKS
!= NULL
)
926 if (r
->data
.WKS
->map
!= NULL
) free(r
->data
.WKS
->map
);
932 if (r
->data
.HINFO
!= NULL
)
934 if (r
->data
.HINFO
->cpu
!= NULL
) free(r
->data
.HINFO
->cpu
);
935 if (r
->data
.HINFO
->os
!= NULL
) free(r
->data
.HINFO
->os
);
941 if (r
->data
.MINFO
!= NULL
)
943 if (r
->data
.MINFO
->rmailbx
!= NULL
) free(r
->data
.MINFO
->rmailbx
);
944 if (r
->data
.MINFO
->emailbx
!= NULL
) free(r
->data
.MINFO
->emailbx
);
950 if (r
->data
.MX
!= NULL
)
952 if (r
->data
.MX
->name
!= NULL
) free(r
->data
.MX
->name
);
959 if (r
->data
.TXT
!= NULL
)
961 for (i
= 0; i
< r
->data
.TXT
->string_count
; i
++) free(r
->data
.TXT
->strings
[i
]);
962 if (r
->data
.TXT
->strings
!= NULL
) free(r
->data
.TXT
->strings
);
968 if (r
->data
.RP
!= NULL
)
970 if (r
->data
.RP
->mailbox
!= NULL
) free(r
->data
.RP
->mailbox
);
971 if (r
->data
.RP
->txtdname
!= NULL
) free(r
->data
.RP
->txtdname
);
977 if (r
->data
.AFSDB
!= NULL
)
979 if (r
->data
.AFSDB
->hostname
!= NULL
) free(r
->data
.AFSDB
->hostname
);
985 if (r
->data
.X25
!= NULL
)
987 if (r
->data
.X25
->psdn_address
!= NULL
) free(r
->data
.X25
->psdn_address
);
993 if (r
->data
.ISDN
!= NULL
)
995 if (r
->data
.ISDN
->isdn_address
!= NULL
) free(r
->data
.ISDN
->isdn_address
);
996 if (r
->data
.ISDN
->subaddress
!= NULL
) free(r
->data
.ISDN
->subaddress
);
1002 if (r
->data
.RT
!= NULL
)
1004 if (r
->data
.RT
->intermediate
!= NULL
) free(r
->data
.RT
->intermediate
);
1010 if (r
->data
.LOC
!= NULL
) free(r
->data
.LOC
);
1014 if (r
->data
.SRV
!= NULL
)
1016 if (r
->data
.SRV
->target
!= NULL
) free(r
->data
.SRV
->target
);
1026 if (r
->data
.DNSNULL
!= NULL
)
1028 if (r
->data
.DNSNULL
->data
!= NULL
) free(r
->data
.DNSNULL
->data
);
1029 free(r
->data
.DNSNULL
);
1038 dns_free_reply(dns_reply_t
*r
)
1042 if (r
== NULL
) return;
1043 if (r
->header
!= NULL
)
1045 for (i
= 0; i
< r
->header
->qdcount
; i
++)
1047 free(r
->question
[i
]->name
);
1048 free(r
->question
[i
]);
1051 for (i
= 0; i
< r
->header
->ancount
; i
++) dns_free_resource_record(r
->answer
[i
]);
1052 for (i
= 0; i
< r
->header
->nscount
; i
++) dns_free_resource_record(r
->authority
[i
]);
1053 for (i
= 0; i
< r
->header
->arcount
; i
++) dns_free_resource_record(r
->additional
[i
]);
1058 if (r
->question
!= NULL
) free(r
->question
);
1059 if (r
->answer
!= NULL
) free(r
->answer
);
1060 if (r
->authority
!= NULL
) free(r
->authority
);
1061 if (r
->additional
!= NULL
) free(r
->additional
);
1063 if (r
->server
!= NULL
) free(r
->server
);
1069 _dns_append_question(dns_question_t
*q
, char **s
, uint16_t *l
)
1074 if (q
== NULL
) return;
1076 len
= *l
+ _dns_cname_length(q
->name
) + 2 + 4;
1077 *s
= realloc(*s
, len
);
1079 _dns_insert_cname(q
->name
, (char *)*s
+ *l
);
1085 *p
= htons(q
->dnstype
);
1089 *p
= htons(q
->dnsclass
);
1094 _dns_append_resource_record(dns_resource_record_t
*r
, char **s
, uint16_t *l
)
1096 uint16_t clen
, len
, *p
, extra
, rdlen
;
1100 if (r
== NULL
) return;
1110 clen
= _dns_cname_length(r
->data
.PTR
->name
);
1116 len
= *l
+ _dns_cname_length(r
->name
) + 2 + extra
;
1117 *s
= realloc(*s
, len
);
1119 _dns_insert_cname(r
->name
, (char *)*s
+ *l
);
1122 x
= *s
+ (len
- extra
);
1125 *p
= htons(r
->dnstype
);
1129 *p
= htons(r
->dnsclass
);
1133 *p2
= htonl(r
->ttl
);
1145 *p2
= htons(r
->data
.A
->addr
.s_addr
);
1150 clen
= _dns_cname_length(r
->data
.PTR
->name
) + 2;
1154 _dns_insert_cname(r
->data
.PTR
->name
, x
);
1163 dns_build_reply(dns_reply_t
*dnsr
, uint16_t *rl
)
1169 if (dnsr
== NULL
) return NULL
;
1179 h
= (dns_header_t
*)s
;
1181 h
->xid
= htons(dnsr
->header
->xid
);
1182 h
->flags
= htons(dnsr
->header
->flags
);
1183 h
->qdcount
= htons(dnsr
->header
->qdcount
);
1184 h
->ancount
= htons(dnsr
->header
->ancount
);
1185 h
->nscount
= htons(dnsr
->header
->nscount
);
1186 h
->arcount
= htons(dnsr
->header
->arcount
);
1188 for (i
= 0; i
< dnsr
->header
->qdcount
; i
++)
1190 _dns_append_question(dnsr
->question
[i
], &s
, rl
);
1193 for (i
= 0; i
< dnsr
->header
->ancount
; i
++)
1195 _dns_append_resource_record(dnsr
->answer
[i
], &s
, rl
);
1198 for (i
= 0; i
< dnsr
->header
->nscount
; i
++)
1200 _dns_append_resource_record(dnsr
->authority
[i
], &s
, rl
);
1203 for (i
= 0; i
< dnsr
->header
->arcount
; i
++)
1205 _dns_append_resource_record(dnsr
->additional
[i
], &s
, rl
);
1212 dns_free_question(dns_question_t
*q
)
1214 if (q
== NULL
) return;
1215 if (q
->name
!= NULL
) free(q
->name
);
1220 dns_set_buffer_size(dns_handle_t d
, uint32_t len
)
1222 dns_private_handle_t
*dns
;
1223 if (d
== NULL
) return;
1225 dns
= (dns_private_handle_t
*)d
;
1226 if (dns
->recvsize
== len
) return;
1228 if (dns
->recvbuf
!= NULL
)
1231 dns
->recvbuf
= NULL
;
1234 dns
->recvsize
= len
;
1235 if (dns
->recvsize
> DNS_MAX_RECEIVE_SIZE
) dns
->recvsize
= DNS_MAX_RECEIVE_SIZE
;
1237 if (dns
->recvsize
> 0) dns
->recvbuf
= malloc(dns
->recvsize
);
1241 dns_get_buffer_size(dns_handle_t d
)
1243 dns_private_handle_t
*dns
;
1244 if (d
== NULL
) return 0;
1246 dns
= (dns_private_handle_t
*)d
;
1247 return dns
->recvsize
;
1251 dns_lookup_soa_min(dns_handle_t d
, const char *name
, uint32_t class, uint32_t type
, int *min
)
1253 dns_private_handle_t
*dns
;
1256 struct sockaddr_storage
*from
;
1259 if (d
== NULL
) return NULL
;
1260 if (name
== NULL
) return NULL
;
1262 dns
= (dns_private_handle_t
*)d
;
1263 if (min
!= NULL
) *min
= -1;
1265 if (dns
->recvbuf
== NULL
)
1267 if (dns
->recvsize
== 0) dns
->recvsize
= DNS_DEFAULT_RECEIVE_SIZE
;
1269 dns
->recvbuf
= malloc(dns
->recvsize
);
1270 if (dns
->recvbuf
== NULL
) return NULL
;
1273 fromlen
= sizeof(struct sockaddr_storage
);
1274 from
= (struct sockaddr_storage
*)calloc(1, sizeof(struct sockaddr_storage
));
1277 if (dns
->handle_type
== DNS_PRIVATE_HANDLE_TYPE_SUPER
)
1279 _check_cache(dns
->sdns
);
1280 len
= _sdns_search(dns
->sdns
, name
, class, type
, 0, 1, dns
->recvbuf
, dns
->recvsize
, (struct sockaddr
*)from
, &fromlen
, min
);
1284 /* NB. Minumium SOA TTL values are NOT provided when the caller passes a DNS_PRIVATE_HANDLE_TYPE_PLAIN handle */
1285 len
= _pdns_search(dns
->sdns
, dns
->pdns
, name
, class, type
, dns
->recvbuf
, dns
->recvsize
, (struct sockaddr
*)from
, &fromlen
);
1294 r
= dns_parse_packet(dns
->recvbuf
, len
);
1296 if (r
== NULL
) free(from
);
1297 else r
->server
= (struct sockaddr
*)from
;
1303 dns_lookup(dns_handle_t d
, const char *name
, uint32_t class, uint32_t type
)
1307 return dns_lookup_soa_min(d
, name
, class, type
, &unused
);
1311 * DNS printing utilities
1315 coord_ntoa(int32_t coord
, uint32_t islat
)
1317 int32_t deg
, min
, sec
, secfrac
;
1318 static char buf
[64];
1321 coord
= coord
- 0x80000000;
1324 if ((islat
== 1) && (coord
< 0))
1340 secfrac
= coord
% 1000;
1341 coord
= coord
/ 1000;
1348 sprintf(buf
, "%d %.2d %.2d.%.3d %c", deg
, min
, sec
, secfrac
, dir
);
1353 alt_ntoa(int32_t alt
)
1355 int32_t ref
, m
, frac
, sign
;
1356 static char buf
[128];
1372 m
= (alt
/ 100) * sign
;
1374 sprintf(buf
, "%d.%.2d", m
, frac
);
1393 precsize_ntoa(uint8_t prec
)
1395 static char buf
[19];
1397 int mantissa
, exponent
;
1399 mantissa
= (int)((prec
>> 4) & 0x0f) % 10;
1400 exponent
= (int)((prec
>> 0) & 0x0f) % 10;
1402 val
= mantissa
* poweroften
[exponent
];
1404 sprintf(buf
, "%ld.%.2ld", val
/100, val%100
);
1409 dns_type_string(uint16_t t
)
1413 case ns_t_a
: return "A ";
1414 case ns_t_ns
: return "NS ";
1415 case ns_t_md
: return "MD ";
1416 case ns_t_mf
: return "MF ";
1417 case ns_t_cname
: return "CNAME";
1418 case ns_t_soa
: return "SOA ";
1419 case ns_t_mb
: return "MB ";
1420 case ns_t_mg
: return "MG ";
1421 case ns_t_mr
: return "MR ";
1422 case ns_t_null
: return "NULL ";
1423 case ns_t_wks
: return "WKS ";
1424 case ns_t_ptr
: return "PTR ";
1425 case ns_t_hinfo
: return "HINFO";
1426 case ns_t_minfo
: return "MINFO";
1427 case ns_t_mx
: return "MX ";
1428 case ns_t_txt
: return "TXT ";
1429 case ns_t_rp
: return "PR ";
1430 case ns_t_afsdb
: return "AFSDB";
1431 case ns_t_x25
: return "X25 ";
1432 case ns_t_isdn
: return "ISDN ";
1433 case ns_t_rt
: return "RT ";
1434 case ns_t_nsap
: return "NSAP ";
1435 case ns_t_nsap_ptr
: return "NSPTR";
1436 case ns_t_sig
: return "SIG ";
1437 case ns_t_key
: return "KEY ";
1438 case ns_t_px
: return "PX ";
1439 case ns_t_gpos
: return "GPOS ";
1440 case ns_t_aaaa
: return "AAAA ";
1441 case ns_t_loc
: return "LOC ";
1442 case ns_t_nxt
: return "NXT ";
1443 case ns_t_eid
: return "EID ";
1444 case ns_t_nimloc
: return "NIMLC";
1445 case ns_t_srv
: return "SRV ";
1446 case ns_t_atma
: return "ATMA ";
1447 case ns_t_naptr
: return "NAPTR";
1448 case ns_t_kx
: return "KX ";
1449 case ns_t_cert
: return "CERT ";
1450 case ns_t_a6
: return "A6 ";
1451 case ns_t_dname
: return "DNAME";
1452 case ns_t_sink
: return "SINK ";
1453 case ns_t_opt
: return "OPT ";
1454 case ns_t_tkey
: return "TKEY ";
1455 case ns_t_tsig
: return "TSIG ";
1456 case ns_t_ixfr
: return "IXFR ";
1457 case ns_t_axfr
: return "AXFR ";
1458 case ns_t_mailb
: return "MAILB";
1459 case ns_t_maila
: return "MAILA";
1460 case ns_t_any
: return "ANY ";
1461 case ns_t_zxfr
: return "ZXFR ";
1462 default: return "?????";
1469 dns_type_number(const char *t
, uint16_t *n
)
1471 if (t
== NULL
) return -1;
1473 if (!strcasecmp(t
, "A")) { *n
= ns_t_a
; return 0; }
1474 if (!strcasecmp(t
, "NS")) { *n
= ns_t_ns
; return 0; }
1475 if (!strcasecmp(t
, "MD")) { *n
= ns_t_md
; return 0; }
1476 if (!strcasecmp(t
, "MF")) { *n
= ns_t_mf
; return 0; }
1477 if (!strcasecmp(t
, "CNAME")) { *n
= ns_t_cname
; return 0; }
1478 if (!strcasecmp(t
, "SOA")) { *n
= ns_t_soa
; return 0; }
1479 if (!strcasecmp(t
, "MB")) { *n
= ns_t_mb
; return 0; }
1480 if (!strcasecmp(t
, "MG")) { *n
= ns_t_mg
; return 0; }
1481 if (!strcasecmp(t
, "MR")) { *n
= ns_t_mr
; return 0; }
1482 if (!strcasecmp(t
, "NULL")) { *n
= ns_t_null
; return 0; }
1483 if (!strcasecmp(t
, "WKS")) { *n
= ns_t_wks
; return 0; }
1484 if (!strcasecmp(t
, "PTR")) { *n
= ns_t_ptr
; return 0; }
1485 if (!strcasecmp(t
, "HINFO")) { *n
= ns_t_hinfo
; return 0; }
1486 if (!strcasecmp(t
, "MINFO")) { *n
= ns_t_minfo
; return 0; }
1487 if (!strcasecmp(t
, "MX")) { *n
= ns_t_mx
; return 0; }
1488 if (!strcasecmp(t
, "TXT")) { *n
= ns_t_txt
; return 0; }
1489 if (!strcasecmp(t
, "RP")) { *n
= ns_t_rp
; return 0; }
1490 if (!strcasecmp(t
, "AFSDB")) { *n
= ns_t_afsdb
; return 0; }
1491 if (!strcasecmp(t
, "X25")) { *n
= ns_t_x25
; return 0; }
1492 if (!strcasecmp(t
, "ISDN")) { *n
= ns_t_isdn
; return 0; }
1493 if (!strcasecmp(t
, "RT")) { *n
= ns_t_rt
; return 0; }
1494 if (!strcasecmp(t
, "NSAP")) { *n
= ns_t_nsap
; return 0; }
1495 if (!strcasecmp(t
, "NSPTR")) { *n
= ns_t_nsap_ptr
; return 0; }
1496 if (!strcasecmp(t
, "NSAP_PTR")){ *n
= ns_t_nsap_ptr
; return 0; }
1497 if (!strcasecmp(t
, "SIG")) { *n
= ns_t_sig
; return 0; }
1498 if (!strcasecmp(t
, "KEY")) { *n
= ns_t_key
; return 0; }
1499 if (!strcasecmp(t
, "PX")) { *n
= ns_t_px
; return 0; }
1500 if (!strcasecmp(t
, "GPOS")) { *n
= ns_t_gpos
; return 0; }
1501 if (!strcasecmp(t
, "AAAA")) { *n
= ns_t_aaaa
; return 0; }
1502 if (!strcasecmp(t
, "LOC")) { *n
= ns_t_loc
; return 0; }
1503 if (!strcasecmp(t
, "NXT")) { *n
= ns_t_nxt
; return 0; }
1504 if (!strcasecmp(t
, "EID")) { *n
= ns_t_eid
; return 0; }
1505 if (!strcasecmp(t
, "NIMLOC")) { *n
= ns_t_nimloc
; return 0; }
1506 if (!strcasecmp(t
, "SRV")) { *n
= ns_t_srv
; return 0; }
1507 if (!strcasecmp(t
, "ATMA")) { *n
= ns_t_atma
; return 0; }
1508 if (!strcasecmp(t
, "NAPTR")) { *n
= ns_t_naptr
; return 0; }
1509 if (!strcasecmp(t
, "KX")) { *n
= ns_t_kx
; return 0; }
1510 if (!strcasecmp(t
, "CERT")) { *n
= ns_t_cert
; return 0; }
1511 if (!strcasecmp(t
, "A6")) { *n
= ns_t_a6
; return 0; }
1512 if (!strcasecmp(t
, "DNAME")) { *n
= ns_t_dname
; return 0; }
1513 if (!strcasecmp(t
, "SINK")) { *n
= ns_t_sink
; return 0; }
1514 if (!strcasecmp(t
, "OPT")) { *n
= ns_t_opt
; return 0; }
1515 if (!strcasecmp(t
, "TKEY")) { *n
= ns_t_tkey
; return 0; }
1516 if (!strcasecmp(t
, "TSIG")) { *n
= ns_t_tsig
; return 0; }
1517 if (!strcasecmp(t
, "IXFR")) { *n
= ns_t_ixfr
; return 0; }
1518 if (!strcasecmp(t
, "AXFR")) { *n
= ns_t_axfr
; return 0; }
1519 if (!strcasecmp(t
, "MAILB")) { *n
= ns_t_mailb
; return 0; }
1520 if (!strcasecmp(t
, "MAILA")) { *n
= ns_t_maila
; return 0; }
1521 if (!strcasecmp(t
, "ANY")) { *n
= ns_t_any
; return 0; }
1522 if (!strcasecmp(t
, "ZXFR")) { *n
= ns_t_zxfr
; return 0; }
1528 dns_class_string(uint16_t c
)
1532 case ns_c_in
: return "IN";
1533 case ns_c_2
: return "CS";
1534 case ns_c_chaos
: return "CH";
1535 case ns_c_hs
: return "HS";
1536 case ns_c_none
: return "NONE";
1537 case ns_c_any
: return "ANY";
1538 default: return "??";
1545 dns_class_number(const char *c
, uint16_t *n
)
1547 if (c
== NULL
) return -1;
1549 if (!strcasecmp(c
, "IN")) { *n
= ns_c_in
; return 0; }
1550 if (!strcasecmp(c
, "CS")) { *n
= ns_c_2
; return 0; }
1551 if (!strcasecmp(c
, "CH")) { *n
= ns_c_chaos
; return 0; }
1552 if (!strcasecmp(c
, "HS")) { *n
= ns_c_hs
; return 0; }
1553 if (!strcasecmp(c
, "NONE")) { *n
= ns_c_none
; return 0; }
1554 if (!strcasecmp(c
, "ANY")) { *n
= ns_c_any
; return 0; }
1560 _dns_print_question_lock(const dns_question_t
*q
, FILE *f
, int lockit
)
1562 if (lockit
!= 0) _dns_print_lock();
1563 fprintf(f
, "%s %s %s\n", q
->name
, dns_class_string(q
->dnsclass
), dns_type_string(q
->dnstype
));
1564 if (lockit
!= 0) _dns_print_unlock();
1568 dns_print_question(const dns_question_t
*q
, FILE *f
)
1570 _dns_print_question_lock(q
, f
, 1);
1574 _dns_print_resource_record_lock(const dns_resource_record_t
*r
, FILE *f
, int lockit
)
1580 struct sockaddr_in6 s6
;
1583 if (lockit
!= 0) _dns_print_lock();
1585 fprintf(f
, "%s %s %s ", r
->name
, dns_class_string(r
->dnsclass
), dns_type_string(r
->dnstype
));
1586 fprintf(f
, "%u", r
->ttl
);
1591 fprintf(f
, " %s", inet_ntoa(r
->data
.A
->addr
));
1595 memset(&s6
, 0, sizeof(struct sockaddr_in6
));
1596 s6
.sin6_len
= sizeof(struct sockaddr_in6
);
1597 s6
.sin6_family
= AF_INET6
;
1598 s6
.sin6_addr
= r
->data
.AAAA
->addr
;
1599 fprintf(f
, " %s", inet_ntop(AF_INET6
, (char *)(&s6
) + INET_NTOP_AF_INET6_OFFSET
, pbuf
, 64));
1610 fprintf(f
, " %s", r
->data
.CNAME
->name
);
1614 fprintf(f
, " %s %s %u %u %u %u %u",
1615 r
->data
.SOA
->mname
, r
->data
.SOA
->rname
,
1616 r
->data
.SOA
->serial
, r
->data
.SOA
->refresh
, r
->data
.SOA
->retry
,
1617 r
->data
.SOA
->expire
, r
->data
.SOA
->minimum
);
1621 fprintf(f
, " %s", inet_ntoa(r
->data
.WKS
->addr
));
1622 p
= getprotobynumber(r
->data
.WKS
->protocol
);
1625 fprintf(f
, " %s", p
->p_name
);
1627 for (i
= 0; i
< r
->data
.WKS
->maplength
; i
++)
1629 if (r
->data
.WKS
->map
[i
])
1631 s
= getservbyport(i
, p
->p_name
);
1632 if (s
== NULL
) fprintf(f
, " %u", i
);
1633 else fprintf(f
, " %s", s
->s_name
);
1637 else fprintf(f
, " UNKNOWN PROTOCOL %u", r
->data
.WKS
->protocol
);
1641 fprintf(f
, " %s %s", r
->data
.HINFO
->cpu
, r
->data
.HINFO
->os
);
1645 fprintf(f
, " %s %s", r
->data
.MINFO
->rmailbx
, r
->data
.MINFO
->emailbx
);
1649 fprintf(f
, " %u %s", r
->data
.MX
->preference
, r
->data
.MX
->name
);
1653 for (i
= 0; i
< r
->data
.TXT
->string_count
; i
++)
1655 fprintf(f
, " \"%s\"", r
->data
.TXT
->strings
[i
]);
1660 fprintf(f
, " %s %s", r
->data
.RP
->mailbox
, r
->data
.RP
->txtdname
);
1664 fprintf(f
, " %u %s", r
->data
.AFSDB
->subtype
,
1665 r
->data
.AFSDB
->hostname
);
1669 fprintf(f
, " %s", r
->data
.X25
->psdn_address
);
1673 fprintf(f
, " %s", r
->data
.ISDN
->isdn_address
);
1674 if (r
->data
.ISDN
->subaddress
!= NULL
)
1675 fprintf(f
, " %s", r
->data
.ISDN
->subaddress
);
1679 fprintf(f
, " %hu %s", r
->data
.RT
->preference
,
1680 r
->data
.RT
->intermediate
);
1684 fprintf(f
, " %s", coord_ntoa(r
->data
.LOC
->latitude
, 1));
1685 fprintf(f
, " %s", coord_ntoa(r
->data
.LOC
->longitude
, 0));
1686 fprintf(f
, " %sm", alt_ntoa(r
->data
.LOC
->altitude
));
1687 fprintf(f
, " %sm", precsize_ntoa(r
->data
.LOC
->size
));
1688 fprintf(f
, " %sm", precsize_ntoa(r
->data
.LOC
->horizontal_precision
));
1689 fprintf(f
, " %sm", precsize_ntoa(r
->data
.LOC
->vertical_precision
));
1693 fprintf(f
, " %hu %hu %hu %s",
1694 r
->data
.SRV
->priority
, r
->data
.SRV
->weight
,
1695 r
->data
.SRV
->port
, r
->data
.SRV
->target
);
1700 len
= r
->data
.DNSNULL
->length
;
1701 fprintf(f
, " %u ", len
);
1702 for (i
= 0; i
< len
; i
++)
1704 x
= r
->data
.DNSNULL
->data
[i
];
1705 fprintf(f
, "%x", x
);
1710 len
= r
->data
.DNSNULL
->length
;
1711 for (i
= 0; i
< len
; i
++)
1713 x
= r
->data
.DNSNULL
->data
[i
];
1714 if (isascii(x
)) fprintf(f
, "%c", x
);
1715 else fprintf(f
, " ");
1723 if (lockit
!= 0) _dns_print_unlock();
1727 dns_print_resource_record(const dns_resource_record_t
*r
, FILE *f
)
1729 _dns_print_resource_record_lock(r
, f
, 1);
1733 dns_print_reply(const dns_reply_t
*r
, FILE *f
, uint16_t mask
)
1738 uint32_t offset
, iface
;
1744 fprintf(f
, "-nil-\n");
1745 _dns_print_unlock();
1749 if (r
->status
!= DNS_STATUS_OK
)
1751 if (r
->status
== DNS_STATUS_TIMEOUT
)
1752 fprintf(f
, "Timeout\n");
1753 else if (r
->status
== DNS_STATUS_SEND_FAILED
)
1754 fprintf(f
, "Send failed\n");
1755 else if (r
->status
== DNS_STATUS_RECEIVE_FAILED
)
1756 fprintf(f
, "Receive failed\n");
1757 else fprintf(f
, "status %u\n", r
->status
);
1759 _dns_print_unlock();
1765 if (mask
& DNS_PRINT_XID
)
1767 fprintf(f
, "Xid: %u\n", h
->xid
);
1770 if (mask
& DNS_PRINT_QR
)
1772 if ((h
->flags
& DNS_FLAGS_QR_MASK
) == DNS_FLAGS_QR_QUERY
)
1773 fprintf(f
, "QR: Query\n");
1775 fprintf(f
, "QR: Reply\n");
1778 if (mask
& DNS_PRINT_SERVER
)
1780 if (r
->server
== NULL
)
1782 fprintf(f
, "Server: -nil-\n");
1786 offset
= INET_NTOP_AF_INET_OFFSET
;
1787 if (r
->server
->sa_family
== AF_INET6
) offset
= INET_NTOP_AF_INET6_OFFSET
;
1789 fprintf(f
, "Server: %s", inet_ntop(r
->server
->sa_family
, (char *)(r
->server
) + offset
, scratch
, 1024));
1790 if (r
->server
->sa_family
== AF_INET
)
1792 memcpy(&iface
, (((struct sockaddr_in
*)(r
->server
))->sin_zero
), 4);
1793 if (iface
> 0) fprintf(f
, "%%%s", if_indextoname(iface
, scratch
));
1795 else if (r
->server
->sa_family
== AF_INET6
)
1797 iface
= ((struct sockaddr_in6
*)(r
->server
))->sin6_scope_id
;
1798 if (iface
> 0) fprintf(f
, "%%%s", if_indextoname(iface
, scratch
));
1804 if (mask
& DNS_PRINT_OPCODE
)
1806 fprintf(f
, "Opcode: ");
1807 switch (h
->flags
& DNS_FLAGS_OPCODE_MASK
)
1809 case ns_o_query
: fprintf(f
, "Standard\n"); break;
1810 case ns_o_iquery
: fprintf(f
, "Inverse\n"); break;
1811 case ns_o_status
: fprintf(f
, "Status\n"); break;
1812 case ns_o_notify
: fprintf(f
, "Notify\n"); break;
1813 case ns_o_update
: fprintf(f
, "Update\n"); break;
1815 fprintf(f
, "Reserved (%hu)\n",
1816 (uint16_t)((h
->flags
& DNS_FLAGS_OPCODE_MASK
) >> 11));
1820 if (mask
& DNS_PRINT_AA
)
1822 if (h
->flags
& DNS_FLAGS_AA
) fprintf(f
, "AA: Authoritative\n");
1823 else fprintf(f
, "AA: Non-Authoritative\n");
1826 if (mask
& DNS_PRINT_TC
)
1828 if (h
->flags
& DNS_FLAGS_TC
) fprintf(f
, "TC: Truncated\n");
1829 else fprintf(f
, "TC: Non-Truncated\n");
1832 if (mask
& DNS_PRINT_RD
)
1834 if (h
->flags
& DNS_FLAGS_RD
) fprintf(f
, "RD: Recursion desired\n");
1835 else fprintf(f
, "RD: No recursion desired\n");
1838 if (mask
& DNS_PRINT_RA
)
1840 if (h
->flags
& DNS_FLAGS_RA
) fprintf(f
, "RA: Recursion available\n");
1841 else fprintf(f
, "RA: No recursion available \n");
1844 if (mask
& DNS_PRINT_RCODE
)
1846 fprintf(f
, "Rcode: ");
1847 switch (h
->flags
& DNS_FLAGS_RCODE_MASK
)
1850 fprintf(f
, "No error\n");
1853 fprintf(f
, "Format error \n");
1856 fprintf(f
, "Server failure\n");
1859 fprintf(f
, "Name error \n");
1862 fprintf(f
, "Not implemented\n");
1865 fprintf(f
, "Refused\n");
1868 fprintf(f
, "Name exists\n");
1871 fprintf(f
, "RR Set exists\n");
1874 fprintf(f
, "RR Set does not exist\n");
1877 fprintf(f
, "Not authoritative\n");
1880 fprintf(f
, "Record zone does not match section zone\n");
1883 fprintf(f
, "Invalid EDNS version or TSIG signature\n");
1886 fprintf(f
, "Invalid key\n");
1889 fprintf(f
, "Invalid time\n");
1892 fprintf(f
, "Reserved (%hu)\n",(uint16_t)(h
->flags
& DNS_FLAGS_RCODE_MASK
));
1896 if (mask
& DNS_PRINT_QUESTION
)
1898 fprintf(f
, "Question (%hu):\n", h
->qdcount
);
1899 for (i
= 0; i
< h
->qdcount
; i
++)
1900 _dns_print_question_lock(r
->question
[i
], f
, 0);
1903 if (mask
& DNS_PRINT_ANSWER
)
1905 fprintf(f
, "Answer (%hu):\n", h
->ancount
);
1906 for (i
= 0; i
< h
->ancount
; i
++)
1907 _dns_print_resource_record_lock(r
->answer
[i
], f
, 0);
1910 if (mask
& DNS_PRINT_AUTHORITY
)
1912 fprintf(f
, "Authority (%hu):\n", h
->nscount
);
1913 for (i
= 0; i
< h
->nscount
; i
++)
1914 _dns_print_resource_record_lock(r
->authority
[i
], f
, 0);
1917 if (mask
& DNS_PRINT_ADDITIONAL
)
1919 fprintf(f
, "Additional records (%hu):\n", h
->arcount
);
1920 for (i
= 0; i
< h
->arcount
; i
++)
1921 _dns_print_resource_record_lock(r
->additional
[i
], f
, 0);
1924 _dns_print_unlock();
1928 _pdns_print_handle(pdns_handle_t
*pdns
, FILE *f
)
1933 struct sockaddr
*sa
;
1938 fprintf(f
, "-nil-\n");
1942 if (pdns
->name
== NULL
) fprintf(f
, "Name: -nil-\n");
1943 else fprintf(f
, "Name: %s\n", pdns
->name
);
1945 fprintf(f
, "Flags:");
1946 if (pdns
->flags
== 0) fprintf(f
, " None\n");
1949 if (pdns
->flags
& DNS_FLAG_DEBUG
) fprintf(f
, " Debug");
1950 if (pdns
->flags
& DNS_FLAG_CHECK_RESOLVER_DIR
) fprintf(f
, " DirCheck");
1951 if (pdns
->flags
& DNS_FLAG_HAVE_IPV6_SERVER
) fprintf(f
, " IPv6");
1952 if (pdns
->flags
& DNS_FLAG_OK_TO_SKIP_AAAA
) fprintf(f
, " SkipAAAA");
1953 if (pdns
->flags
& DNS_FLAG_DEFAULT_RESOLVER
) fprintf(f
, " Default");
1958 if (r
== NULL
) return;
1960 if (r
->defdname
[0] != '\0') fprintf(f
, "Domain: %s\n", r
->defdname
);
1961 fprintf(f
, "Search Order: %d\n", pdns
->search_order
);
1962 fprintf(f
, "Total Timeout: %d\n", pdns
->total_timeout
);
1963 fprintf(f
, "Retry Timeout: %d\n", pdns
->res
->retrans
);
1964 fprintf(f
, "Retry Attempts: %d\n", pdns
->res
->retry
);
1966 fprintf(f
, "Server%s:\n", (r
->nscount
== 1) ? "" : "s");
1967 for (i
= 0; i
< r
->nscount
; i
++)
1969 sa
= get_nsaddr(r
, i
);
1970 offset
= INET_NTOP_AF_INET_OFFSET
;
1971 if (sa
->sa_family
== AF_INET6
) offset
= INET_NTOP_AF_INET6_OFFSET
;
1972 fprintf(f
, " %u: %s", i
, inet_ntop(sa
->sa_family
, (char *)sa
+ offset
, scratch
, 1024));
1976 if (pdns
->search_count
> 0)
1978 fprintf(f
, "Search List:\n");
1979 for (i
= 0; i
< pdns
->search_count
; i
++)
1980 fprintf(f
, " %u: %s\n", i
, pdns
->search_list
[i
]);
1983 if (r
->sort_list
[0].addr
.s_addr
!= 0)
1985 fprintf(f
, "Sortlist:\n");
1986 for (i
= 0; (r
->sort_list
[i
].addr
.s_addr
!= 0); i
++)
1988 fprintf(f
, " %u: ", i
);
1989 a
.s_addr
= r
->sort_list
[i
].addr
.s_addr
;
1990 fprintf(f
, "%s/", inet_ntoa(a
));
1991 a
.s_addr
= r
->sort_list
[i
].mask
;
1992 fprintf(f
, "%s\n", inet_ntoa(a
));
1998 _sdns_print_handle(sdns_handle_t
*sdns
, FILE *f
)
2004 fprintf(f
, "-nil-\n");
2008 for (i
= 0; i
< sdns
->client_count
; i
++)
2010 fprintf(f
, "DNS client %d\n", i
);
2011 _pdns_print_handle(sdns
->client
[i
], f
);
2015 fprintf(f
, "resolver dir mod time = %u\n", sdns
->modtime
);
2016 fprintf(f
, "resolver dir stat time = %u\n", sdns
->stattime
);
2017 fprintf(f
, "resolver dir stat latency = %u\n", sdns
->stat_latency
);
2021 dns_print_handle(dns_handle_t d
, FILE *f
)
2023 dns_private_handle_t
*dns
;
2029 fprintf(f
, "-nil-\n");
2030 _dns_print_unlock();
2034 dns
= (dns_private_handle_t
*)d
;
2036 if (dns
->handle_type
== DNS_PRIVATE_HANDLE_TYPE_SUPER
)
2038 _sdns_print_handle(dns
->sdns
, f
);
2042 _pdns_print_handle(dns
->pdns
, f
);
2045 _dns_print_unlock();
2049 dns_all_server_addrs(dns_handle_t d
, struct sockaddr
***addrs
, uint32_t *count
)
2051 int i
, j
, k
, n
, found
;
2052 dns_private_handle_t
*dns
;
2053 pdns_handle_t
*pdns
;
2054 struct sockaddr
*sa
;
2055 struct sockaddr_storage
**l
;
2063 if (d
== NULL
) return;
2065 dns
= (dns_private_handle_t
*)d
;
2067 if (dns
->handle_type
!= DNS_PRIVATE_HANDLE_TYPE_SUPER
) return;
2069 if (dns
->sdns
== NULL
) return;
2071 /* Just to initialize / validate clients */
2072 i
= dns_search_list_count(d
);
2074 for (i
= 0; i
< dns
->sdns
->client_count
; i
++)
2076 pdns
= dns
->sdns
->client
[i
];
2077 if (pdns
== NULL
) continue;
2080 if (r
== NULL
) continue;
2082 for (j
= 0; j
< r
->nscount
; j
++)
2084 sa
= get_nsaddr(r
, j
);
2086 for (k
= 0; (found
== 0) && (k
< n
); k
++)
2088 if (memcmp(l
[k
], sa
, sa
->sa_len
) == 0) found
= 1;
2090 if (found
== 1) continue;
2094 l
= (struct sockaddr_storage
**)calloc(1, sizeof(struct sockaddr_storage
*));
2098 l
= (struct sockaddr_storage
**)reallocf(l
, (n
+ 1) * sizeof(struct sockaddr_storage
*));
2101 if (l
== NULL
) return;
2103 l
[n
] = (struct sockaddr_storage
*)calloc(1, sizeof(struct sockaddr_storage
));
2104 if (l
[n
] == NULL
) return;
2106 memset(l
[n
], 0, sizeof(struct sockaddr_storage
));
2107 memcpy(l
[n
], sa
, sa
->sa_len
);
2112 *addrs
= (struct sockaddr
**)l
;
2117 dns_res_once(struct sockaddr
*server
, struct timeval
*timeout
, int options
, const char *name
, int class, int type
, u_char
*res
, int *reslen
)
2120 int n
, fromlen
, status
;
2121 struct sockaddr_storage from
;
2122 u_char buf
[MAXPACKET
];
2124 if (server
== NULL
) return DNS_RES_STATUS_INVALID_ARGUMENT
;
2125 if (name
== NULL
) return DNS_RES_STATUS_INVALID_ARGUMENT
;
2126 if (res
== NULL
) return DNS_RES_STATUS_INVALID_ARGUMENT
;
2127 if (reslen
== NULL
) return DNS_RES_STATUS_INVALID_ARGUMENT
;
2129 fromlen
= sizeof(struct sockaddr_storage
);
2131 statp
= res_state_new();
2133 statp
->options
= options
;
2134 statp
->id
= res_randomid();
2135 if (timeout
== NULL
) statp
->retrans
= 5;
2136 else statp
->retrans
= timeout
->tv_sec
;
2139 statp
->_vcsock
= -1;
2142 strcpy(statp
->_u
._ext
.ext
->nsuffix
, "ip6.arpa");
2143 strcpy(statp
->_u
._ext
.ext
->nsuffix2
, "ip6.int");
2144 strcpy(statp
->_u
._ext
.ext
->bsuffix
, "ip6.arpa");
2146 if (server
->sa_family
== AF_INET6
)
2148 memcpy(&(statp
->_u
._ext
.ext
->nsaddrs
[0]), server
, sizeof(struct sockaddr_in6
));
2149 statp
->nsaddr_list
[0].sin_family
= 0;
2153 memcpy(&(statp
->_u
._ext
.ext
->nsaddrs
[0]), server
, sizeof(struct sockaddr_in
));
2154 memcpy(&(statp
->nsaddr_list
[0]), server
, sizeof(struct sockaddr_in
));
2157 n
= res_nmkquery(statp
, ns_o_query
, name
, class, type
, NULL
, 0, NULL
, buf
, sizeof(buf
));
2159 status
= dns_res_send(statp
, buf
, n
, res
, reslen
, (struct sockaddr
*)&from
, &fromlen
);
2161 res_client_close(statp
);