3f4c8c897fe1b0c1618e6595d138968dc57549e4
3 * - diagnostic functions
7 * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 #include <arpa/inet.h>
30 /* Core diagnostic functions */
32 void adns__vdiag(adns_state ads
, const char *pfx
, adns_initflags prevent
,
33 int serv
, adns_query qu
, const char *fmt
, va_list al
) {
34 const char *bef
, *aft
;
36 if (!(ads
->iflags
& adns_if_debug
) && (!prevent
|| (ads
->iflags
& prevent
))) return;
38 fprintf(stderr
,"adns%s: ",pfx
);
40 vfprintf(stderr
,fmt
,al
);
45 if (qu
&& qu
->query_dgram
) {
47 fprintf(stderr
,"%sQNAME=%s, QTYPE=%s",
49 adns__diag_domain(qu
->ads
,-1,0, &vb
,qu
->flags
,
50 qu
->query_dgram
,qu
->query_dglen
,DNS_HDRSIZE
),
51 qu
->typei ? qu
->typei
->rrtname
: "<unknown>");
52 if (qu
->typei
&& qu
->typei
->fmtname
)
53 fprintf(stderr
,"(%s)",qu
->typei
->fmtname
);
58 fprintf(stderr
,"%sNS=%s",bef
,inet_ntoa(ads
->servers
[serv
].addr
));
65 void adns__debug(adns_state ads
, int serv
, adns_query qu
, const char *fmt
, ...) {
69 adns__vdiag(ads
," debug",0,serv
,qu
,fmt
,al
);
73 void adns__warn(adns_state ads
, int serv
, adns_query qu
, const char *fmt
, ...) {
77 adns__vdiag(ads
," warning",adns_if_noerrprint
|adns_if_noserverwarn
,serv
,qu
,fmt
,al
);
81 void adns__diag(adns_state ads
, int serv
, adns_query qu
, const char *fmt
, ...) {
85 adns__vdiag(ads
,"",adns_if_noerrprint
,serv
,qu
,fmt
,al
);
91 void adns__vbuf_init(vbuf
*vb
) {
92 vb
->used
= vb
->avail
= 0; vb
->buf
= 0;
95 int adns__vbuf_ensure(vbuf
*vb
, int want
) {
98 if (vb
->avail
>= want
) return 1;
99 nb
= realloc(vb
->buf
,want
); if (!nb
) return 0;
105 void adns__vbuf_appendq(vbuf
*vb
, const byte
*data
, int len
) {
106 memcpy(vb
->buf
+vb
->used
,data
,len
);
110 int adns__vbuf_append(vbuf
*vb
, const byte
*data
, int len
) {
114 newlen
= vb
->used
+len
;
115 if (vb
->avail
< newlen
) {
116 if (newlen
<20) newlen
= 20;
118 nb
= realloc(vb
->buf
,newlen
);
119 if (!nb
) { newlen
= vb
->used
+len
; nb
= realloc(vb
->buf
,newlen
); }
124 adns__vbuf_appendq(vb
,data
,len
);
128 int adns__vbuf_appendstr(vbuf
*vb
, const char *data
) {
131 return adns__vbuf_append(vb
,data
,l
);
134 void adns__vbuf_free(vbuf
*vb
) {
139 /* Additional diagnostic functions */
141 const char *adns__diag_domain(adns_state ads
, int serv
, adns_query qu
, vbuf
*vb
,
142 int flags
, const byte
*dgram
, int dglen
, int cbyte
) {
145 st
= adns__parse_domain(ads
,serv
,qu
,vb
, flags
,dgram
,dglen
,&cbyte
,dglen
);
146 if (st
== adns_s_nolocalmem
) {
147 return "<cannot report domain... out of memory>";
151 if (!(adns__vbuf_appendstr(vb
,"<bad format... ") &&
152 adns__vbuf_appendstr(vb
,adns_strerror(st
)) &&
153 adns__vbuf_appendstr(vb
,">") &&
154 adns__vbuf_append(vb
,"",1))) {
155 return "<cannot report bad format... out of memory>";
159 adns__vbuf_appendstr(vb
,"<truncated ...>");
160 adns__vbuf_append(vb
,"",1);
165 adns_status
adns_rr_info(adns_rrtype type
,
166 const char **rrtname_r
, const char **fmtname_r
,
168 const void *datap
, char **data_r
) {
169 const typeinfo
*typei
;
173 typei
= adns__findtype(type
);
174 if (!typei
) return adns_s_notimplemented
;
176 if (rrtname_r
) *rrtname_r
= typei
->rrtname
;
177 if (fmtname_r
) *fmtname_r
= typei
->fmtname
;
178 if (len_r
) *len_r
= typei
->rrsz
;
180 if (!datap
) return adns_s_ok
;
182 adns__vbuf_init(&vb
);
183 st
= typei
->convstring(&vb
,datap
);
184 if (st
) goto x_freevb
;
185 if (!adns__vbuf_append(&vb
,"",1)) { st
= adns_s_nolocalmem
; goto x_freevb
; }
186 assert(strlen(vb
.buf
) == vb
.used
-1);
187 *data_r
= realloc(vb
.buf
,vb
.used
);
188 if (!*data_r
) *data_r
= vb
.buf
;
192 adns__vbuf_free(&vb
);
196 #define SINFO(n,s) { adns_s_##n, s }
198 static const struct sinfo
{
203 SINFO( timeout
, "Timed out" ),
204 SINFO( nolocalmem
, "Out of memory" ),
205 SINFO( allservfail
, "No working nameservers" ),
206 SINFO( servfail
, "Nameserver failure" ),
207 SINFO( notimplemented
, "Query not implemented" ),
208 SINFO( refused
, "Refused by nameserver" ),
209 SINFO( reasonunknown
, "Reason unknown" ),
210 SINFO( norecurse
, "Recursion denied by nameserver" ),
211 SINFO( serverfaulty
, "Nameserver sent bad data" ),
212 SINFO( unknownreply
, "Reply from nameserver not understood" ),
213 SINFO( invaliddata
, "Invalid data" ),
214 SINFO( inconsistent
, "Inconsistent data" ),
215 SINFO( cname
, "RR refers to an alias" ),
216 SINFO( invalidanswerdomain
, "Received syntactically invalid domain" ),
217 SINFO( nxdomain
, "No such domain" ),
218 SINFO( nodata
, "No such data" ),
219 SINFO( invalidquerydomain
, "Domain syntactically invalid" ),
220 SINFO( domaintoolong
, "Domain name too long" )
223 static int si_compar(const void *key
, const void *elem
) {
224 const adns_status
*st
= key
;
225 const struct sinfo
*si
= elem
;
227 return *st
< si
->st ?
-1 : *st
> si
->st ?
1 : 0;
230 const char *adns_strerror(adns_status st
) {
231 static char buf
[100];
233 const struct sinfo
*si
;
235 si
= bsearch(&st
,sinfos
,sizeof(sinfos
)/sizeof(*si
),sizeof(*si
),si_compar
);
236 if (si
) return si
->string
;
238 snprintf(buf
,sizeof(buf
),"code %d",st
);