4 * conversion routines from the wire format
5 * to the presentation format (strings)
7 * (c) NLnet Labs, 2004-2006
9 * See the file LICENSE for the license
14 * Contains functions to translate the wireformat to text
15 * representation, as well as functions to print them.
18 #include "ldns/wire2str.h"
19 #include "ldns/str2wire.h"
20 #include "ldns/rrdef.h"
21 #include "ldns/pkthdr.h"
22 #include "ldns/parseutil.h"
23 #include "ldns/sbuffer.h"
24 #include "ldns/keyraw.h"
35 /* lookup tables for standard DNS stuff */
36 /* Taken from RFC 2535, section 7. */
37 static sldns_lookup_table sldns_algorithms_data
[] = {
38 { LDNS_RSAMD5
, "RSAMD5" },
42 { LDNS_RSASHA1
, "RSASHA1" },
43 { LDNS_DSA_NSEC3
, "DSA-NSEC3-SHA1" },
44 { LDNS_RSASHA1_NSEC3
, "RSASHA1-NSEC3-SHA1" },
45 { LDNS_RSASHA256
, "RSASHA256"},
46 { LDNS_RSASHA512
, "RSASHA512"},
47 { LDNS_ECC_GOST
, "ECC-GOST"},
48 { LDNS_ECDSAP256SHA256
, "ECDSAP256SHA256"},
49 { LDNS_ECDSAP384SHA384
, "ECDSAP384SHA384"},
50 { LDNS_INDIRECT
, "INDIRECT" },
51 { LDNS_PRIVATEDNS
, "PRIVATEDNS" },
52 { LDNS_PRIVATEOID
, "PRIVATEOID" },
55 sldns_lookup_table
* sldns_algorithms
= sldns_algorithms_data
;
57 /* hash algorithms in DS record */
58 static sldns_lookup_table sldns_hashes_data
[] = {
59 { LDNS_SHA1
, "SHA1" },
60 { LDNS_SHA256
, "SHA256" },
61 { LDNS_HASH_GOST
, "HASH-GOST" },
62 { LDNS_SHA384
, "SHA384" },
65 sldns_lookup_table
* sldns_hashes
= sldns_hashes_data
;
67 /* Taken from RFC 4398 */
68 static sldns_lookup_table sldns_cert_algorithms_data
[] = {
69 { LDNS_CERT_PKIX
, "PKIX" },
70 { LDNS_CERT_SPKI
, "SPKI" },
71 { LDNS_CERT_PGP
, "PGP" },
72 { LDNS_CERT_IPKIX
, "IPKIX" },
73 { LDNS_CERT_ISPKI
, "ISPKI" },
74 { LDNS_CERT_IPGP
, "IPGP" },
75 { LDNS_CERT_ACPKIX
, "ACPKIX" },
76 { LDNS_CERT_IACPKIX
, "IACPKIX" },
77 { LDNS_CERT_URI
, "URI" },
78 { LDNS_CERT_OID
, "OID" },
81 sldns_lookup_table
* sldns_cert_algorithms
= sldns_cert_algorithms_data
;
83 /* if these are used elsewhere */
84 static sldns_lookup_table sldns_rcodes_data
[] = {
85 { LDNS_RCODE_NOERROR
, "NOERROR" },
86 { LDNS_RCODE_FORMERR
, "FORMERR" },
87 { LDNS_RCODE_SERVFAIL
, "SERVFAIL" },
88 { LDNS_RCODE_NXDOMAIN
, "NXDOMAIN" },
89 { LDNS_RCODE_NOTIMPL
, "NOTIMPL" },
90 { LDNS_RCODE_REFUSED
, "REFUSED" },
91 { LDNS_RCODE_YXDOMAIN
, "YXDOMAIN" },
92 { LDNS_RCODE_YXRRSET
, "YXRRSET" },
93 { LDNS_RCODE_NXRRSET
, "NXRRSET" },
94 { LDNS_RCODE_NOTAUTH
, "NOTAUTH" },
95 { LDNS_RCODE_NOTZONE
, "NOTZONE" },
98 sldns_lookup_table
* sldns_rcodes
= sldns_rcodes_data
;
100 static sldns_lookup_table sldns_opcodes_data
[] = {
101 { LDNS_PACKET_QUERY
, "QUERY" },
102 { LDNS_PACKET_IQUERY
, "IQUERY" },
103 { LDNS_PACKET_STATUS
, "STATUS" },
104 { LDNS_PACKET_NOTIFY
, "NOTIFY" },
105 { LDNS_PACKET_UPDATE
, "UPDATE" },
108 sldns_lookup_table
* sldns_opcodes
= sldns_opcodes_data
;
110 static sldns_lookup_table sldns_wireparse_errors_data
[] = {
111 { LDNS_WIREPARSE_ERR_OK
, "no parse error" },
112 { LDNS_WIREPARSE_ERR_GENERAL
, "parse error" },
113 { LDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW
, "Domainname length overflow" },
114 { LDNS_WIREPARSE_ERR_DOMAINNAME_UNDERFLOW
, "Domainname length underflow (zero length)" },
115 { LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL
, "buffer too small" },
116 { LDNS_WIREPARSE_ERR_LABEL_OVERFLOW
, "Label length overflow" },
117 { LDNS_WIREPARSE_ERR_EMPTY_LABEL
, "Empty label" },
118 { LDNS_WIREPARSE_ERR_SYNTAX_BAD_ESCAPE
, "Syntax error, bad escape sequence" },
119 { LDNS_WIREPARSE_ERR_SYNTAX
, "Syntax error, could not parse the RR" },
120 { LDNS_WIREPARSE_ERR_SYNTAX_TTL
, "Syntax error, could not parse the RR's TTL" },
121 { LDNS_WIREPARSE_ERR_SYNTAX_TYPE
, "Syntax error, could not parse the RR's type" },
122 { LDNS_WIREPARSE_ERR_SYNTAX_CLASS
, "Syntax error, could not parse the RR's class" },
123 { LDNS_WIREPARSE_ERR_SYNTAX_RDATA
, "Syntax error, could not parse the RR's rdata" },
124 { LDNS_WIREPARSE_ERR_SYNTAX_MISSING_VALUE
, "Syntax error, value expected" },
125 { LDNS_WIREPARSE_ERR_INVALID_STR
, "Conversion error, string expected" },
126 { LDNS_WIREPARSE_ERR_SYNTAX_B64
, "Conversion error, b64 encoding expected" },
127 { LDNS_WIREPARSE_ERR_SYNTAX_B32_EXT
, "Conversion error, b32 ext encoding expected" },
128 { LDNS_WIREPARSE_ERR_SYNTAX_HEX
, "Conversion error, hex encoding expected" },
129 { LDNS_WIREPARSE_ERR_CERT_BAD_ALGORITHM
, "Bad algorithm type for CERT record" },
130 { LDNS_WIREPARSE_ERR_SYNTAX_TIME
, "Conversion error, time encoding expected" },
131 { LDNS_WIREPARSE_ERR_SYNTAX_PERIOD
, "Conversion error, time period encoding expected" },
132 { LDNS_WIREPARSE_ERR_SYNTAX_ILNP64
, "Conversion error, 4 colon separated hex numbers expected" },
133 { LDNS_WIREPARSE_ERR_SYNTAX_EUI48
,
134 "Conversion error, 6 two character hex numbers "
135 "separated by dashes expected (i.e. xx-xx-xx-xx-xx-xx" },
136 { LDNS_WIREPARSE_ERR_SYNTAX_EUI64
,
137 "Conversion error, 8 two character hex numbers "
138 "separated by dashes expected (i.e. xx-xx-xx-xx-xx-xx-xx-xx" },
139 { LDNS_WIREPARSE_ERR_SYNTAX_TAG
,
140 "Conversion error, a non-zero sequence of US-ASCII letters "
141 "and numbers in lower case expected" },
142 { LDNS_WIREPARSE_ERR_NOT_IMPL
, "not implemented" },
143 { LDNS_WIREPARSE_ERR_SYNTAX_INT
, "Conversion error, integer expected" },
144 { LDNS_WIREPARSE_ERR_SYNTAX_IP4
, "Conversion error, ip4 addr expected" },
145 { LDNS_WIREPARSE_ERR_SYNTAX_IP6
, "Conversion error, ip6 addr expected" },
146 { LDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW
, "Syntax error, integer overflow" },
147 { LDNS_WIREPARSE_ERR_INCLUDE
, "$INCLUDE directive was seen in the zone" },
148 { LDNS_WIREPARSE_ERR_PARENTHESIS
, "Parse error, parenthesis mismatch" },
151 sldns_lookup_table
* sldns_wireparse_errors
= sldns_wireparse_errors_data
;
153 static sldns_lookup_table sldns_edns_flags_data
[] = {
157 sldns_lookup_table
* sldns_edns_flags
= sldns_edns_flags_data
;
159 static sldns_lookup_table sldns_edns_options_data
[] = {
163 /* 4 draft-cheshire-edns0-owner-option */
167 { 8, "edns-client-subnet" },
170 sldns_lookup_table
* sldns_edns_options
= sldns_edns_options_data
;
172 char* sldns_wire2str_pkt(uint8_t* data
, size_t len
)
174 size_t slen
= (size_t)sldns_wire2str_pkt_buf(data
, len
, NULL
, 0);
175 char* result
= (char*)malloc(slen
+1);
176 if(!result
) return NULL
;
177 sldns_wire2str_pkt_buf(data
, len
, result
, slen
+1);
181 char* sldns_wire2str_rr(uint8_t* rr
, size_t len
)
183 size_t slen
= (size_t)sldns_wire2str_rr_buf(rr
, len
, NULL
, 0);
184 char* result
= (char*)malloc(slen
+1);
185 if(!result
) return NULL
;
186 sldns_wire2str_rr_buf(rr
, len
, result
, slen
+1);
190 char* sldns_wire2str_type(uint16_t rrtype
)
193 sldns_wire2str_type_buf(rrtype
, buf
, sizeof(buf
));
197 char* sldns_wire2str_class(uint16_t rrclass
)
200 sldns_wire2str_class_buf(rrclass
, buf
, sizeof(buf
));
204 char* sldns_wire2str_dname(uint8_t* dname
, size_t dname_len
)
206 size_t slen
=(size_t)sldns_wire2str_dname_buf(dname
, dname_len
, NULL
, 0);
207 char* result
= (char*)malloc(slen
+1);
208 if(!result
) return NULL
;
209 sldns_wire2str_dname_buf(dname
, dname_len
, result
, slen
+1);
213 char* sldns_wire2str_rcode(int rcode
)
216 sldns_wire2str_rcode_buf(rcode
, buf
, sizeof(buf
));
220 int sldns_wire2str_pkt_buf(uint8_t* d
, size_t dlen
, char* s
, size_t slen
)
222 /* use arguments as temporary variables */
223 return sldns_wire2str_pkt_scan(&d
, &dlen
, &s
, &slen
);
226 int sldns_wire2str_rr_buf(uint8_t* d
, size_t dlen
, char* s
, size_t slen
)
228 /* use arguments as temporary variables */
229 return sldns_wire2str_rr_scan(&d
, &dlen
, &s
, &slen
, NULL
, 0);
232 int sldns_wire2str_rdata_buf(uint8_t* rdata
, size_t rdata_len
, char* str
,
233 size_t str_len
, uint16_t rrtype
)
235 /* use arguments as temporary variables */
236 return sldns_wire2str_rdata_scan(&rdata
, &rdata_len
, &str
, &str_len
,
240 int sldns_wire2str_rr_unknown_buf(uint8_t* d
, size_t dlen
, char* s
, size_t slen
)
242 /* use arguments as temporary variables */
243 return sldns_wire2str_rr_unknown_scan(&d
, &dlen
, &s
, &slen
, NULL
, 0);
246 int sldns_wire2str_rr_comment_buf(uint8_t* rr
, size_t rrlen
, size_t dname_len
,
247 char* s
, size_t slen
)
249 uint16_t rrtype
= sldns_wirerr_get_type(rr
, rrlen
, dname_len
);
250 return sldns_wire2str_rr_comment_print(&s
, &slen
, rr
, rrlen
, dname_len
,
254 int sldns_wire2str_type_buf(uint16_t rrtype
, char* s
, size_t slen
)
256 /* use arguments as temporary variables */
257 return sldns_wire2str_type_print(&s
, &slen
, rrtype
);
260 int sldns_wire2str_class_buf(uint16_t rrclass
, char* s
, size_t slen
)
262 /* use arguments as temporary variables */
263 return sldns_wire2str_class_print(&s
, &slen
, rrclass
);
266 int sldns_wire2str_rcode_buf(int rcode
, char* s
, size_t slen
)
268 /* use arguments as temporary variables */
269 return sldns_wire2str_rcode_print(&s
, &slen
, rcode
);
272 int sldns_wire2str_dname_buf(uint8_t* d
, size_t dlen
, char* s
, size_t slen
)
274 /* use arguments as temporary variables */
275 return sldns_wire2str_dname_scan(&d
, &dlen
, &s
, &slen
, NULL
, 0);
278 int sldns_str_vprint(char** str
, size_t* slen
, const char* format
, va_list args
)
280 int w
= vsnprintf(*str
, *slen
, format
, args
);
282 /* error in printout */
284 } else if((size_t)w
>= *slen
) {
285 *str
= NULL
; /* we do not want str to point outside of buffer*/
294 int sldns_str_print(char** str
, size_t* slen
, const char* format
, ...)
298 va_start(args
, format
);
299 w
= sldns_str_vprint(str
, slen
, format
, args
);
304 /** print hex format into text buffer for specified length */
305 static int print_hex_buf(char** s
, size_t* slen
, uint8_t* buf
, size_t len
)
307 const char* hex
= "0123456789ABCDEF";
309 for(i
=0; i
<len
; i
++) {
310 (void)sldns_str_print(s
, slen
, "%c%c", hex
[(buf
[i
]&0xf0)>>4],
316 /** print remainder of buffer in hex format with prefixed text */
317 static int print_remainder_hex(const char* pref
, uint8_t** d
, size_t* dlen
,
318 char** s
, size_t* slen
)
321 w
+= sldns_str_print(s
, slen
, "%s", pref
);
322 w
+= print_hex_buf(s
, slen
, *d
, *dlen
);
328 int sldns_wire2str_pkt_scan(uint8_t** d
, size_t* dlen
, char** s
, size_t* slen
)
331 unsigned qdcount
, ancount
, nscount
, arcount
, i
;
333 size_t pktlen
= *dlen
;
334 if(*dlen
>= LDNS_HEADER_SIZE
) {
335 qdcount
= (unsigned)LDNS_QDCOUNT(*d
);
336 ancount
= (unsigned)LDNS_ANCOUNT(*d
);
337 nscount
= (unsigned)LDNS_NSCOUNT(*d
);
338 arcount
= (unsigned)LDNS_ARCOUNT(*d
);
340 qdcount
= ancount
= nscount
= arcount
= 0;
342 w
+= sldns_wire2str_header_scan(d
, dlen
, s
, slen
);
343 w
+= sldns_str_print(s
, slen
, "\n");
344 w
+= sldns_str_print(s
, slen
, ";; QUESTION SECTION:\n");
345 for(i
=0; i
<qdcount
; i
++) {
346 w
+= sldns_wire2str_rrquestion_scan(d
, dlen
, s
, slen
,
350 w
+= sldns_str_print(s
, slen
, "\n");
351 w
+= sldns_str_print(s
, slen
, ";; ANSWER SECTION:\n");
352 for(i
=0; i
<ancount
; i
++) {
353 w
+= sldns_wire2str_rr_scan(d
, dlen
, s
, slen
, pkt
, pktlen
);
356 w
+= sldns_str_print(s
, slen
, "\n");
357 w
+= sldns_str_print(s
, slen
, ";; AUTHORITY SECTION:\n");
358 for(i
=0; i
<nscount
; i
++) {
359 w
+= sldns_wire2str_rr_scan(d
, dlen
, s
, slen
, pkt
, pktlen
);
362 w
+= sldns_str_print(s
, slen
, "\n");
363 w
+= sldns_str_print(s
, slen
, ";; ADDITIONAL SECTION:\n");
364 for(i
=0; i
<arcount
; i
++) {
365 w
+= sldns_wire2str_rr_scan(d
, dlen
, s
, slen
, pkt
, pktlen
);
368 /* other fields: WHEN(time), SERVER(IP) not available here. */
369 w
+= sldns_str_print(s
, slen
, ";; MSG SIZE rcvd: %d\n", (int)pktlen
);
371 w
+= print_remainder_hex(";; trailing garbage 0x",
373 w
+= sldns_str_print(s
, slen
, "\n");
378 /** scan type, class and ttl and printout, for rr */
379 static int sldns_rr_tcttl_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
386 return w
+ print_remainder_hex("; Error malformed 0x",
388 /* these print values or 0x.. if none left */
389 t
= sldns_read_uint16(*d
);
390 c
= sldns_read_uint16((*d
)+2);
393 w
+= sldns_wire2str_class_print(s
, sl
, c
);
394 w
+= sldns_str_print(s
, sl
, "\t");
395 w
+= sldns_wire2str_type_print(s
, sl
, t
);
397 return w
+ sldns_str_print(s
, sl
, "; Error no ttl");
398 return w
+ print_remainder_hex(
399 "; Error malformed ttl 0x", d
, dl
, s
, sl
);
401 t
= sldns_read_uint16(*d
);
402 c
= sldns_read_uint16((*d
)+2);
403 ttl
= sldns_read_uint32((*d
)+4);
406 w
+= sldns_str_print(s
, sl
, "%lu\t", (unsigned long)ttl
);
407 w
+= sldns_wire2str_class_print(s
, sl
, c
);
408 w
+= sldns_str_print(s
, sl
, "\t");
409 w
+= sldns_wire2str_type_print(s
, sl
, t
);
413 int sldns_wire2str_rr_scan(uint8_t** d
, size_t* dlen
, char** s
, size_t* slen
,
414 uint8_t* pkt
, size_t pktlen
)
418 size_t rrlen
= *dlen
, dname_off
, rdlen
, ordlen
;
421 if(*dlen
>= 3 && (*d
)[0]==0 &&
422 sldns_read_uint16((*d
)+1)==LDNS_RR_TYPE_OPT
) {
423 /* perform EDNS OPT processing */
424 return sldns_wire2str_edns_scan(d
, dlen
, s
, slen
, pkt
, pktlen
);
427 /* try to scan the rdata with pretty-printing, but if that fails, then
428 * scan the rdata as an unknown RR type */
429 w
+= sldns_wire2str_dname_scan(d
, dlen
, s
, slen
, pkt
, pktlen
);
430 w
+= sldns_str_print(s
, slen
, "\t");
431 dname_off
= rrlen
-(*dlen
);
433 /* like a question-RR */
434 uint16_t t
= sldns_read_uint16(*d
);
435 uint16_t c
= sldns_read_uint16((*d
)+2);
438 w
+= sldns_wire2str_class_print(s
, slen
, c
);
439 w
+= sldns_str_print(s
, slen
, "\t");
440 w
+= sldns_wire2str_type_print(s
, slen
, t
);
441 w
+= sldns_str_print(s
, slen
, " ; Error no ttl,rdata\n");
446 return w
+ sldns_str_print(s
, slen
, ";Error missing RR\n");
447 w
+= print_remainder_hex(";Error partial RR 0x", d
, dlen
, s
, slen
);
448 return w
+ sldns_str_print(s
, slen
, "\n");
450 rrtype
= sldns_read_uint16(*d
);
451 w
+= sldns_rr_tcttl_scan(d
, dlen
, s
, slen
);
452 w
+= sldns_str_print(s
, slen
, "\t");
457 return w
+ sldns_str_print(s
, slen
, ";Error missing rdatalen\n");
458 w
+= print_remainder_hex(";Error missing rdatalen 0x",
460 return w
+ sldns_str_print(s
, slen
, "\n");
462 rdlen
= sldns_read_uint16(*d
);
467 w
+= sldns_str_print(s
, slen
, "\\# %u ", (unsigned)rdlen
);
469 return w
+ sldns_str_print(s
, slen
, ";Error missing rdata\n");
470 w
+= print_remainder_hex(";Error partial rdata 0x", d
, dlen
, s
, slen
);
471 return w
+ sldns_str_print(s
, slen
, "\n");
473 w
+= sldns_wire2str_rdata_scan(d
, &rdlen
, s
, slen
, rrtype
, pkt
, pktlen
);
474 (*dlen
) -= (ordlen
-rdlen
);
476 /* default comment */
477 w
+= sldns_wire2str_rr_comment_print(s
, slen
, rr
, rrlen
, dname_off
,
479 w
+= sldns_str_print(s
, slen
, "\n");
483 int sldns_wire2str_rrquestion_scan(uint8_t** d
, size_t* dlen
, char** s
,
484 size_t* slen
, uint8_t* pkt
, size_t pktlen
)
488 w
+= sldns_wire2str_dname_scan(d
, dlen
, s
, slen
, pkt
, pktlen
);
489 w
+= sldns_str_print(s
, slen
, "\t");
492 return w
+ sldns_str_print(s
, slen
, "Error malformed\n");
493 w
+= print_remainder_hex("Error malformed 0x", d
, dlen
, s
, slen
);
494 return w
+ sldns_str_print(s
, slen
, "\n");
496 t
= sldns_read_uint16(*d
);
497 c
= sldns_read_uint16((*d
)+2);
500 w
+= sldns_wire2str_class_print(s
, slen
, c
);
501 w
+= sldns_str_print(s
, slen
, "\t");
502 w
+= sldns_wire2str_type_print(s
, slen
, t
);
503 w
+= sldns_str_print(s
, slen
, "\n");
507 int sldns_wire2str_rr_unknown_scan(uint8_t** d
, size_t* dlen
, char** s
,
508 size_t* slen
, uint8_t* pkt
, size_t pktlen
)
510 size_t rdlen
, ordlen
;
512 w
+= sldns_wire2str_dname_scan(d
, dlen
, s
, slen
, pkt
, pktlen
);
513 w
+= sldns_str_print(s
, slen
, "\t");
514 w
+= sldns_rr_tcttl_scan(d
, dlen
, s
, slen
);
515 w
+= sldns_str_print(s
, slen
, "\t");
518 return w
+ sldns_str_print(s
, slen
, ";Error missing rdatalen\n");
519 w
+= print_remainder_hex(";Error missing rdatalen 0x",
521 return w
+ sldns_str_print(s
, slen
, "\n");
523 rdlen
= sldns_read_uint16(*d
);
528 w
+= sldns_str_print(s
, slen
, "\\# %u ", (unsigned)rdlen
);
530 return w
+ sldns_str_print(s
, slen
, ";Error missing rdata\n");
531 w
+= print_remainder_hex(";Error partial rdata 0x", d
, dlen
, s
, slen
);
532 return w
+ sldns_str_print(s
, slen
, "\n");
534 w
+= sldns_wire2str_rdata_unknown_scan(d
, &rdlen
, s
, slen
);
535 (*dlen
) -= (ordlen
-rdlen
);
536 w
+= sldns_str_print(s
, slen
, "\n");
540 /** print rr comment for type DNSKEY */
541 static int rr_comment_dnskey(char** s
, size_t* slen
, uint8_t* rr
,
542 size_t rrlen
, size_t dname_off
)
547 if(rrlen
< dname_off
+ 10) return 0;
548 rdlen
= sldns_read_uint16(rr
+dname_off
+8);
549 if(rrlen
< dname_off
+ 10 + rdlen
) return 0;
550 rdata
= rr
+ dname_off
+ 10;
551 flags
= (int)sldns_read_uint16(rdata
);
552 w
+= sldns_str_print(s
, slen
, " ;{");
555 w
+= sldns_str_print(s
, slen
, "id = %u",
556 sldns_calc_keytag_raw(rdata
, rdlen
));
559 if((flags
&LDNS_KEY_ZONE_KEY
)) {
560 if((flags
&LDNS_KEY_SEP_KEY
))
561 w
+= sldns_str_print(s
, slen
, " (ksk)");
562 else w
+= sldns_str_print(s
, slen
, " (zsk)");
567 w
+= sldns_str_print(s
, slen
, ", ");
568 w
+= sldns_str_print(s
, slen
, "size = %db",
569 (int)sldns_rr_dnskey_key_size_raw(
570 (unsigned char*)rdata
+4, rdlen
-4, (int)(rdata
[3])));
573 w
+= sldns_str_print(s
, slen
, "}");
577 /** print rr comment for type RRSIG */
578 static int rr_comment_rrsig(char** s
, size_t* slen
, uint8_t* rr
,
579 size_t rrlen
, size_t dname_off
)
583 if(rrlen
< dname_off
+ 10) return 0;
584 rdlen
= sldns_read_uint16(rr
+dname_off
+8);
585 if(rrlen
< dname_off
+ 10 + rdlen
) return 0;
586 rdata
= rr
+ dname_off
+ 10;
587 if(rdlen
< 18) return 0;
588 return sldns_str_print(s
, slen
, " ;{id = %d}",
589 (int)sldns_read_uint16(rdata
+16));
592 /** print rr comment for type NSEC3 */
593 static int rr_comment_nsec3(char** s
, size_t* slen
, uint8_t* rr
,
594 size_t rrlen
, size_t dname_off
)
599 if(rrlen
< dname_off
+ 10) return 0;
600 rdlen
= sldns_read_uint16(rr
+dname_off
+8);
601 if(rrlen
< dname_off
+ 10 + rdlen
) return 0;
602 rdata
= rr
+ dname_off
+ 10;
603 if(rdlen
< 2) return 0;
604 if((rdata
[1] & LDNS_NSEC3_VARS_OPTOUT_MASK
))
605 w
+= sldns_str_print(s
, slen
, " ;{flags: optout}");
609 int sldns_wire2str_rr_comment_print(char** s
, size_t* slen
, uint8_t* rr
,
610 size_t rrlen
, size_t dname_off
, uint16_t rrtype
)
612 if(rrtype
== LDNS_RR_TYPE_DNSKEY
) {
613 return rr_comment_dnskey(s
, slen
, rr
, rrlen
, dname_off
);
614 } else if(rrtype
== LDNS_RR_TYPE_RRSIG
) {
615 return rr_comment_rrsig(s
, slen
, rr
, rrlen
, dname_off
);
616 } else if(rrtype
== LDNS_RR_TYPE_NSEC3
) {
617 return rr_comment_nsec3(s
, slen
, rr
, rrlen
, dname_off
);
622 int sldns_wire2str_header_scan(uint8_t** d
, size_t* dlen
, char** s
,
627 w
+= sldns_str_print(s
, slen
, ";; ->>HEADER<<- ");
629 return w
+sldns_str_print(s
, slen
, "Error empty packet");
631 return w
+print_remainder_hex("Error header too short 0x", d
, dlen
, s
, slen
);
632 opcode
= (int)LDNS_OPCODE_WIRE(*d
);
633 rcode
= (int)LDNS_RCODE_WIRE(*d
);
634 w
+= sldns_str_print(s
, slen
, "opcode: ");
635 w
+= sldns_wire2str_opcode_print(s
, slen
, opcode
);
636 w
+= sldns_str_print(s
, slen
, ", ");
637 w
+= sldns_str_print(s
, slen
, "rcode: ");
638 w
+= sldns_wire2str_rcode_print(s
, slen
, rcode
);
639 w
+= sldns_str_print(s
, slen
, ", ");
640 w
+= sldns_str_print(s
, slen
, "id: %d\n", (int)LDNS_ID_WIRE(*d
));
641 w
+= sldns_str_print(s
, slen
, ";; flags:");
642 if(LDNS_QR_WIRE(*d
)) w
+= sldns_str_print(s
, slen
, " qr");
643 if(LDNS_AA_WIRE(*d
)) w
+= sldns_str_print(s
, slen
, " aa");
644 if(LDNS_TC_WIRE(*d
)) w
+= sldns_str_print(s
, slen
, " tc");
645 if(LDNS_RD_WIRE(*d
)) w
+= sldns_str_print(s
, slen
, " rd");
646 if(LDNS_CD_WIRE(*d
)) w
+= sldns_str_print(s
, slen
, " cd");
647 if(LDNS_RA_WIRE(*d
)) w
+= sldns_str_print(s
, slen
, " ra");
648 if(LDNS_AD_WIRE(*d
)) w
+= sldns_str_print(s
, slen
, " ad");
649 if(LDNS_Z_WIRE(*d
)) w
+= sldns_str_print(s
, slen
, " z");
650 w
+= sldns_str_print(s
, slen
, " ; ");
651 if(*dlen
< LDNS_HEADER_SIZE
)
652 return w
+print_remainder_hex("Error header too short 0x", d
, dlen
, s
, slen
);
653 w
+= sldns_str_print(s
, slen
, "QUERY: %d, ", (int)LDNS_QDCOUNT(*d
));
654 w
+= sldns_str_print(s
, slen
, "ANSWER: %d, ", (int)LDNS_ANCOUNT(*d
));
655 w
+= sldns_str_print(s
, slen
, "AUTHORITY: %d, ", (int)LDNS_NSCOUNT(*d
));
656 w
+= sldns_str_print(s
, slen
, "ADDITIONAL: %d ", (int)LDNS_ARCOUNT(*d
));
657 *d
+= LDNS_HEADER_SIZE
;
658 *dlen
-= LDNS_HEADER_SIZE
;
662 int sldns_wire2str_rdata_scan(uint8_t** d
, size_t* dlen
, char** s
,
663 size_t* slen
, uint16_t rrtype
, uint8_t* pkt
, size_t pktlen
)
665 /* try to prettyprint, but if that fails, use unknown format */
668 size_t origdlen
= *dlen
, origslen
= *slen
;
669 uint16_t r_cnt
, r_max
;
670 sldns_rdf_type rdftype
;
673 const sldns_rr_descriptor
*desc
= sldns_rr_descript(rrtype
);
674 if(!desc
) /* unknown format */
675 return sldns_wire2str_rdata_unknown_scan(d
, dlen
, s
, slen
);
676 /* dlen equals the rdatalen for the rdata */
678 r_max
= sldns_rr_descriptor_maximum(desc
);
679 for(r_cnt
=0; r_cnt
< r_max
; r_cnt
++) {
681 if(r_cnt
< sldns_rr_descriptor_minimum(desc
))
683 break; /* nothing more to print */
685 rdftype
= sldns_rr_descriptor_field_type(desc
, r_cnt
);
687 w
+= sldns_str_print(s
, slen
, " ");
688 n
= sldns_wire2str_rdf_scan(d
, dlen
, s
, slen
, rdftype
,
692 /* failed, use unknown format */
693 *d
= origd
; *s
= origs
;
694 *dlen
= origdlen
; *slen
= origslen
;
695 return sldns_wire2str_rdata_unknown_scan(d
, dlen
,
703 int sldns_wire2str_rdata_unknown_scan(uint8_t** d
, size_t* dlen
, char** s
,
709 w
+= sldns_str_print(s
, slen
, "\\# %u", (unsigned)*dlen
);
711 /* print rdlen in hex */
713 w
+= sldns_str_print(s
, slen
, " ");
714 w
+= print_hex_buf(s
, slen
, *d
, *dlen
);
720 /** print and escape one character for a domain dname */
721 static int dname_char_print(char** s
, size_t* slen
, uint8_t c
)
723 if(c
== '.' || c
== ';' || c
== '(' || c
== ')' || c
== '\\')
724 return sldns_str_print(s
, slen
, "\\%c", c
);
725 else if(!(isascii((unsigned char)c
) && isgraph((unsigned char)c
)))
726 return sldns_str_print(s
, slen
, "\\%03u", (unsigned)c
);
736 int sldns_wire2str_dname_scan(uint8_t** d
, size_t* dlen
, char** s
, size_t* slen
,
737 uint8_t* pkt
, size_t pktlen
)
740 /* spool labels onto the string, use compression if its there */
742 unsigned i
, counter
=0;
743 const unsigned maxcompr
= 1000; /* loop detection, max compr ptrs */
745 if(*dlen
== 0) return sldns_str_print(s
, slen
, "ErrorMissingDname");
749 return sldns_str_print(s
, slen
, ".");
752 /* read label length */
753 uint8_t labellen
= *pos
++;
754 if(in_buf
) { (*d
)++; (*dlen
)--; }
756 /* find out what sort of label we have */
757 if((labellen
&0xc0) == 0xc0) {
760 if(in_buf
&& *dlen
== 0)
761 return w
+ sldns_str_print(s
, slen
,
762 "ErrorPartialDname");
763 else if(!in_buf
&& pos
+1 > pkt
+pktlen
)
764 return w
+ sldns_str_print(s
, slen
,
765 "ErrorPartialDname");
766 target
= ((labellen
&0x3f)<<8) | *pos
;
767 if(in_buf
) { (*d
)++; (*dlen
)--; }
768 /* move to target, if possible */
769 if(!pkt
|| target
>= pktlen
)
770 return w
+ sldns_str_print(s
, slen
,
771 "ErrorComprPtrOutOfBounds");
772 if(counter
++ > maxcompr
)
773 return w
+ sldns_str_print(s
, slen
,
774 "ErrorComprPtrLooped");
778 } else if((labellen
&0xc0)) {
779 /* notimpl label type */
780 w
+= sldns_str_print(s
, slen
,
781 "ErrorLABELTYPE%xIsUnknown",
782 (int)(labellen
&0xc0));
786 /* spool label characters, end with '.' */
787 if(in_buf
&& *dlen
< labellen
) labellen
= *dlen
;
788 else if(!in_buf
&& pos
+labellen
> pkt
+pktlen
)
789 labellen
= (uint8_t)(pkt
+ pktlen
- pos
);
790 for(i
=0; i
<(unsigned)labellen
; i
++) {
791 w
+= dname_char_print(s
, slen
, *pos
++);
796 if(*dlen
== 0) break;
798 w
+= sldns_str_print(s
, slen
, ".");
800 /* skip over final root label */
801 if(in_buf
&& *dlen
> 0) { (*d
)++; (*dlen
)--; }
802 /* in case we printed no labels, terminate dname */
803 if(w
== 0) w
+= sldns_str_print(s
, slen
, ".");
807 int sldns_wire2str_opcode_print(char** s
, size_t* slen
, int opcode
)
809 sldns_lookup_table
*lt
= sldns_lookup_by_id(sldns_opcodes
, opcode
);
810 if (lt
&& lt
->name
) {
811 return sldns_str_print(s
, slen
, "%s", lt
->name
);
813 return sldns_str_print(s
, slen
, "OPCODE%u", (unsigned)opcode
);
816 int sldns_wire2str_rcode_print(char** s
, size_t* slen
, int rcode
)
818 sldns_lookup_table
*lt
= sldns_lookup_by_id(sldns_rcodes
, rcode
);
819 if (lt
&& lt
->name
) {
820 return sldns_str_print(s
, slen
, "%s", lt
->name
);
822 return sldns_str_print(s
, slen
, "RCODE%u", (unsigned)rcode
);
825 int sldns_wire2str_class_print(char** s
, size_t* slen
, uint16_t rrclass
)
827 sldns_lookup_table
*lt
= sldns_lookup_by_id(sldns_rr_classes
,
829 if (lt
&& lt
->name
) {
830 return sldns_str_print(s
, slen
, "%s", lt
->name
);
832 return sldns_str_print(s
, slen
, "CLASS%u", (unsigned)rrclass
);
835 int sldns_wire2str_type_print(char** s
, size_t* slen
, uint16_t rrtype
)
837 const sldns_rr_descriptor
*descriptor
= sldns_rr_descript(rrtype
);
838 if (descriptor
&& descriptor
->_name
) {
839 return sldns_str_print(s
, slen
, "%s", descriptor
->_name
);
841 return sldns_str_print(s
, slen
, "TYPE%u", (unsigned)rrtype
);
844 int sldns_wire2str_edns_option_code_print(char** s
, size_t* slen
,
847 sldns_lookup_table
*lt
= sldns_lookup_by_id(sldns_edns_options
,
849 if (lt
&& lt
->name
) {
850 return sldns_str_print(s
, slen
, "%s", lt
->name
);
852 return sldns_str_print(s
, slen
, "OPT%u", (unsigned)opcode
);
855 int sldns_wire2str_class_scan(uint8_t** d
, size_t* dlen
, char** s
, size_t* slen
)
858 if(*dlen
== 0) return 0;
859 if(*dlen
< 2) return print_remainder_hex("Error malformed 0x", d
, dlen
, s
, slen
);
860 c
= sldns_read_uint16(*d
);
863 return sldns_wire2str_class_print(s
, slen
, c
);
866 int sldns_wire2str_type_scan(uint8_t** d
, size_t* dlen
, char** s
, size_t* slen
)
869 if(*dlen
== 0) return 0;
870 if(*dlen
< 2) return print_remainder_hex("Error malformed 0x", d
, dlen
, s
, slen
);
871 t
= sldns_read_uint16(*d
);
874 return sldns_wire2str_type_print(s
, slen
, t
);
877 int sldns_wire2str_ttl_scan(uint8_t** d
, size_t* dlen
, char** s
, size_t* slen
)
880 if(*dlen
== 0) return 0;
881 if(*dlen
< 4) return print_remainder_hex("Error malformed 0x", d
, dlen
, s
, slen
);
882 ttl
= sldns_read_uint32(*d
);
885 return sldns_str_print(s
, slen
, "%u", (unsigned)ttl
);
888 int sldns_wire2str_rdf_scan(uint8_t** d
, size_t* dlen
, char** s
, size_t* slen
,
889 int rdftype
, uint8_t* pkt
, size_t pktlen
)
891 if(*dlen
== 0) return 0;
893 case LDNS_RDF_TYPE_NONE
:
895 case LDNS_RDF_TYPE_DNAME
:
896 return sldns_wire2str_dname_scan(d
, dlen
, s
, slen
, pkt
, pktlen
);
897 case LDNS_RDF_TYPE_INT8
:
898 return sldns_wire2str_int8_scan(d
, dlen
, s
, slen
);
899 case LDNS_RDF_TYPE_INT16
:
900 return sldns_wire2str_int16_scan(d
, dlen
, s
, slen
);
901 case LDNS_RDF_TYPE_INT32
:
902 return sldns_wire2str_int32_scan(d
, dlen
, s
, slen
);
903 case LDNS_RDF_TYPE_PERIOD
:
904 return sldns_wire2str_period_scan(d
, dlen
, s
, slen
);
905 case LDNS_RDF_TYPE_TSIGTIME
:
906 return sldns_wire2str_tsigtime_scan(d
, dlen
, s
, slen
);
907 case LDNS_RDF_TYPE_A
:
908 return sldns_wire2str_a_scan(d
, dlen
, s
, slen
);
909 case LDNS_RDF_TYPE_AAAA
:
910 return sldns_wire2str_aaaa_scan(d
, dlen
, s
, slen
);
911 case LDNS_RDF_TYPE_STR
:
912 return sldns_wire2str_str_scan(d
, dlen
, s
, slen
);
913 case LDNS_RDF_TYPE_APL
:
914 return sldns_wire2str_apl_scan(d
, dlen
, s
, slen
);
915 case LDNS_RDF_TYPE_B32_EXT
:
916 return sldns_wire2str_b32_ext_scan(d
, dlen
, s
, slen
);
917 case LDNS_RDF_TYPE_B64
:
918 return sldns_wire2str_b64_scan(d
, dlen
, s
, slen
);
919 case LDNS_RDF_TYPE_HEX
:
920 return sldns_wire2str_hex_scan(d
, dlen
, s
, slen
);
921 case LDNS_RDF_TYPE_NSEC
:
922 return sldns_wire2str_nsec_scan(d
, dlen
, s
, slen
);
923 case LDNS_RDF_TYPE_NSEC3_SALT
:
924 return sldns_wire2str_nsec3_salt_scan(d
, dlen
, s
, slen
);
925 case LDNS_RDF_TYPE_TYPE
:
926 return sldns_wire2str_type_scan(d
, dlen
, s
, slen
);
927 case LDNS_RDF_TYPE_CLASS
:
928 return sldns_wire2str_class_scan(d
, dlen
, s
, slen
);
929 case LDNS_RDF_TYPE_CERT_ALG
:
930 return sldns_wire2str_cert_alg_scan(d
, dlen
, s
, slen
);
931 case LDNS_RDF_TYPE_ALG
:
932 return sldns_wire2str_alg_scan(d
, dlen
, s
, slen
);
933 case LDNS_RDF_TYPE_UNKNOWN
:
934 return sldns_wire2str_unknown_scan(d
, dlen
, s
, slen
);
935 case LDNS_RDF_TYPE_TIME
:
936 return sldns_wire2str_time_scan(d
, dlen
, s
, slen
);
937 case LDNS_RDF_TYPE_LOC
:
938 return sldns_wire2str_loc_scan(d
, dlen
, s
, slen
);
939 case LDNS_RDF_TYPE_WKS
:
940 case LDNS_RDF_TYPE_SERVICE
:
941 return sldns_wire2str_wks_scan(d
, dlen
, s
, slen
);
942 case LDNS_RDF_TYPE_NSAP
:
943 return sldns_wire2str_nsap_scan(d
, dlen
, s
, slen
);
944 case LDNS_RDF_TYPE_ATMA
:
945 return sldns_wire2str_atma_scan(d
, dlen
, s
, slen
);
946 case LDNS_RDF_TYPE_IPSECKEY
:
947 return sldns_wire2str_ipseckey_scan(d
, dlen
, s
, slen
, pkt
,
949 case LDNS_RDF_TYPE_HIP
:
950 return sldns_wire2str_hip_scan(d
, dlen
, s
, slen
);
951 case LDNS_RDF_TYPE_INT16_DATA
:
952 return sldns_wire2str_int16_data_scan(d
, dlen
, s
, slen
);
953 case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER
:
954 return sldns_wire2str_b32_ext_scan(d
, dlen
, s
, slen
);
955 case LDNS_RDF_TYPE_ILNP64
:
956 return sldns_wire2str_ilnp64_scan(d
, dlen
, s
, slen
);
957 case LDNS_RDF_TYPE_EUI48
:
958 return sldns_wire2str_eui48_scan(d
, dlen
, s
, slen
);
959 case LDNS_RDF_TYPE_EUI64
:
960 return sldns_wire2str_eui64_scan(d
, dlen
, s
, slen
);
961 case LDNS_RDF_TYPE_TAG
:
962 return sldns_wire2str_tag_scan(d
, dlen
, s
, slen
);
963 case LDNS_RDF_TYPE_LONG_STR
:
964 return sldns_wire2str_long_str_scan(d
, dlen
, s
, slen
);
966 /* unknown rdf type */
970 int sldns_wire2str_int8_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
973 if(*dl
< 1) return -1;
974 w
= sldns_str_print(s
, sl
, "%u", (unsigned)**d
);
980 int sldns_wire2str_int16_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
983 if(*dl
< 2) return -1;
984 w
= sldns_str_print(s
, sl
, "%lu", (unsigned long)sldns_read_uint16(*d
));
990 int sldns_wire2str_int32_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
993 if(*dl
< 4) return -1;
994 w
= sldns_str_print(s
, sl
, "%lu", (unsigned long)sldns_read_uint32(*d
));
1000 int sldns_wire2str_period_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1003 if(*dl
< 4) return -1;
1004 w
= sldns_str_print(s
, sl
, "%u", (unsigned)sldns_read_uint32(*d
));
1010 int sldns_wire2str_tsigtime_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1012 /* tsigtime is 48 bits network order unsigned integer */
1014 uint64_t tsigtime
= 0;
1015 uint64_t d0
, d1
, d2
, d3
, d4
, d5
;
1016 if(*dl
< 6) return -1;
1017 d0
= (*d
)[0]; /* cast to uint64 for shift operations */
1023 tsigtime
= (d0
<<40) | (d1
<<32) | (d2
<<24) | (d3
<<16) | (d4
<<8) | d5
;
1025 w
= sldns_str_print(s
, sl
, "%llu", (long long)tsigtime
);
1027 w
= sldns_str_print(s
, sl
, "%I64u", (long long)tsigtime
);
1034 int sldns_wire2str_a_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1038 if(*dl
< 4) return -1;
1039 if(!inet_ntop(AF_INET
, *d
, buf
, (socklen_t
)sizeof(buf
)))
1041 w
= sldns_str_print(s
, sl
, "%s", buf
);
1047 int sldns_wire2str_aaaa_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1052 if(*dl
< 16) return -1;
1053 if(!inet_ntop(AF_INET6
, *d
, buf
, (socklen_t
)sizeof(buf
)))
1055 w
= sldns_str_print(s
, sl
, "%s", buf
);
1064 /** printout escaped TYPE_STR character */
1065 static int str_char_print(char** s
, size_t* sl
, uint8_t c
)
1067 if(isprint((unsigned char)c
) || c
== '\t') {
1068 if(c
== '\"' || c
== '\\')
1069 return sldns_str_print(s
, sl
, "\\%c", c
);
1077 return sldns_str_print(s
, sl
, "\\%03u", (unsigned)c
);
1080 int sldns_wire2str_str_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1084 if(*dl
< 1) return -1;
1086 if(*dl
< 1+len
) return -1;
1089 w
+= sldns_str_print(s
, sl
, "\"");
1090 for(i
=0; i
<len
; i
++)
1091 w
+= str_char_print(s
, sl
, (*d
)[i
]);
1092 w
+= sldns_str_print(s
, sl
, "\"");
1098 int sldns_wire2str_apl_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1102 uint8_t negation
, prefix
, adflength
;
1103 if(*dl
< 4) return -1;
1104 family
= sldns_read_uint16(*d
);
1106 negation
= ((*d
)[3] & LDNS_APL_NEGATION
);
1107 adflength
= ((*d
)[3] & LDNS_APL_MASK
);
1108 if(*dl
< 4+(size_t)adflength
) return -1;
1109 if(family
!= LDNS_APL_IP4
&& family
!= LDNS_APL_IP6
)
1110 return -1; /* unknown address family */
1112 w
+= sldns_str_print(s
, sl
, "!");
1113 w
+= sldns_str_print(s
, sl
, "%u:", (unsigned)family
);
1114 if(family
== LDNS_APL_IP4
) {
1115 /* check if prefix <32 ? */
1116 /* address is variable length 0 - 4 */
1117 for(i
=0; i
<4; i
++) {
1119 w
+= sldns_str_print(s
, sl
, ".");
1120 if(i
< (int)adflength
)
1121 w
+= sldns_str_print(s
, sl
, "%d", (*d
)[4+i
]);
1122 else w
+= sldns_str_print(s
, sl
, "0");
1124 } else if(family
== LDNS_APL_IP6
) {
1125 /* check if prefix <128 ? */
1126 /* address is variable length 0 - 16 */
1127 for(i
=0; i
<16; i
++) {
1129 w
+= sldns_str_print(s
, sl
, ":");
1130 if(i
< (int)adflength
)
1131 w
+= sldns_str_print(s
, sl
, "%02x", (*d
)[4+i
]);
1132 else w
+= sldns_str_print(s
, sl
, "00");
1135 w
+= sldns_str_print(s
, sl
, "/%u", (unsigned)prefix
);
1136 (*d
) += 4+adflength
;
1137 (*dl
) -= 4+adflength
;
1141 int sldns_wire2str_b32_ext_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1145 if(*dl
< 1) return -1;
1147 if(*dl
< 1+datalen
) return -1;
1148 sz
= sldns_b32_ntop_calculate_size(datalen
);
1151 (*dl
) -= (datalen
+1);
1152 return (int)sz
; /* out of space really, but would need buffer
1153 in order to truncate the output */
1155 sldns_b32_ntop_extended_hex((*d
)+1, datalen
, *s
, *sl
);
1157 (*dl
) -= (datalen
+1);
1163 /** scan number of bytes from wire into b64 presentation format */
1164 static int sldns_wire2str_b64_scan_num(uint8_t** d
, size_t* dl
, char** s
,
1165 size_t* sl
, size_t num
)
1167 /* b64_ntop_calculate size includes null at the end */
1168 size_t sz
= sldns_b64_ntop_calculate_size(num
)-1;
1172 return (int)sz
; /* out of space really, but would need buffer
1173 in order to truncate the output */
1175 sldns_b64_ntop(*d
, num
, *s
, *sl
);
1183 int sldns_wire2str_b64_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1185 return sldns_wire2str_b64_scan_num(d
, dl
, s
, sl
, *dl
);
1188 int sldns_wire2str_hex_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1190 return print_remainder_hex("", d
, dl
, s
, sl
);
1193 int sldns_wire2str_nsec_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1197 unsigned i
, bit
, window
, block_len
;
1201 /* check for errors */
1203 if(pl
< 2) return -1;
1204 block_len
= (unsigned)p
[1];
1205 if(pl
< 2+block_len
) return -1;
1214 if(pl
< 2) return -1; /* cannot happen */
1215 window
= (unsigned)p
[0];
1216 block_len
= (unsigned)p
[1];
1217 if(pl
< 2+block_len
) return -1; /* cannot happen */
1219 for(i
=0; i
<block_len
; i
++) {
1220 if(p
[i
] == 0) continue;
1221 /* base type number for this octet */
1222 t
= ((window
)<<8) | (i
<< 3);
1223 for(bit
=0; bit
<8; bit
++) {
1224 if((p
[i
]&(0x80>>bit
))) {
1225 if(w
) w
+= sldns_str_print(s
, sl
, " ");
1226 w
+= sldns_wire2str_type_print(s
, sl
,
1239 int sldns_wire2str_nsec3_salt_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1243 if(*dl
< 1) return -1;
1244 salt_len
= (size_t)(*d
)[0];
1245 if(*dl
< 1+salt_len
) return -1;
1249 return sldns_str_print(s
, sl
, "-");
1251 w
= print_hex_buf(s
, sl
, *d
, salt_len
);
1257 int sldns_wire2str_cert_alg_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1259 sldns_lookup_table
*lt
;
1261 if(*dl
< 2) return -1;
1262 data
= (int)sldns_read_uint16(*d
);
1263 lt
= sldns_lookup_by_id(sldns_cert_algorithms
, data
);
1265 w
= sldns_str_print(s
, sl
, "%s", lt
->name
);
1266 else w
= sldns_str_print(s
, sl
, "%d", data
);
1272 int sldns_wire2str_alg_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1274 /* don't use algorithm mnemonics in the presentation format
1275 * this kind of got sneaked into the rfc's */
1276 return sldns_wire2str_int8_scan(d
, dl
, s
, sl
);
1279 int sldns_wire2str_unknown_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1281 return sldns_wire2str_rdata_unknown_scan(d
, dl
, s
, sl
);
1284 int sldns_wire2str_time_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1286 /* create a YYYYMMDDHHMMSS string if possible */
1290 memset(&tm
, 0, sizeof(tm
));
1291 if(*dl
< 4) return -1;
1292 t
= sldns_read_uint32(*d
);
1294 if(sldns_serial_arithmitics_gmtime_r(t
, time(NULL
), &tm
) &&
1295 strftime(date_buf
, 15, "%Y%m%d%H%M%S", &tm
)) {
1298 return sldns_str_print(s
, sl
, "%s", date_buf
);
1304 loc_cm_print(char** str
, size_t* sl
, uint8_t mantissa
, uint8_t exponent
)
1308 /* is it 0.<two digits> ? */
1312 return sldns_str_print(str
, sl
, "0.%02ld", (long)mantissa
);
1314 /* always <digit><string of zeros> */
1315 w
+= sldns_str_print(str
, sl
, "%d", (int)mantissa
);
1316 for(i
=0; i
<exponent
-2; i
++)
1317 w
+= sldns_str_print(str
, sl
, "0");
1321 int sldns_wire2str_loc_scan(uint8_t** d
, size_t* dl
, char** str
, size_t* sl
)
1323 /* we could do checking (ie degrees < 90 etc)? */
1326 uint8_t horizontal_precision
;
1327 uint8_t vertical_precision
;
1336 uint32_t equator
= (uint32_t)1 << 31; /* 2**31 */
1339 if(*dl
< 16) return -1;
1342 return sldns_wire2str_hex_scan(d
, dl
, str
, sl
);
1344 horizontal_precision
= (*d
)[2];
1345 vertical_precision
= (*d
)[3];
1347 latitude
= sldns_read_uint32((*d
)+4);
1348 longitude
= sldns_read_uint32((*d
)+8);
1349 altitude
= sldns_read_uint32((*d
)+12);
1351 if (latitude
> equator
) {
1353 latitude
= latitude
- equator
;
1356 latitude
= equator
- latitude
;
1358 h
= latitude
/ (1000 * 60 * 60);
1359 latitude
= latitude
% (1000 * 60 * 60);
1360 m
= latitude
/ (1000 * 60);
1361 latitude
= latitude
% (1000 * 60);
1362 s
= (double) latitude
/ 1000.0;
1363 w
+= sldns_str_print(str
, sl
, "%02u %02u %06.3f %c ",
1364 h
, m
, s
, northerness
);
1366 if (longitude
> equator
) {
1368 longitude
= longitude
- equator
;
1371 longitude
= equator
- longitude
;
1373 h
= longitude
/ (1000 * 60 * 60);
1374 longitude
= longitude
% (1000 * 60 * 60);
1375 m
= longitude
/ (1000 * 60);
1376 longitude
= longitude
% (1000 * 60);
1377 s
= (double) longitude
/ (1000.0);
1378 w
+= sldns_str_print(str
, sl
, "%02u %02u %06.3f %c ",
1379 h
, m
, s
, easterness
);
1381 s
= ((double) altitude
) / 100;
1384 if(altitude%100
!= 0)
1385 w
+= sldns_str_print(str
, sl
, "%.2f", s
);
1387 w
+= sldns_str_print(str
, sl
, "%.0f", s
);
1389 w
+= sldns_str_print(str
, sl
, "m ");
1391 w
+= loc_cm_print(str
, sl
, (size
& 0xf0) >> 4, size
& 0x0f);
1392 w
+= sldns_str_print(str
, sl
, "m ");
1394 w
+= loc_cm_print(str
, sl
, (horizontal_precision
& 0xf0) >> 4,
1395 horizontal_precision
& 0x0f);
1396 w
+= sldns_str_print(str
, sl
, "m ");
1398 w
+= loc_cm_print(str
, sl
, (vertical_precision
& 0xf0) >> 4,
1399 vertical_precision
& 0x0f);
1400 w
+= sldns_str_print(str
, sl
, "m");
1407 int sldns_wire2str_wks_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1409 /* protocol, followed by bitmap of services */
1410 const char* proto_name
= NULL
;
1411 struct protoent
*protocol
;
1412 struct servent
*service
;
1413 uint8_t protocol_nr
;
1414 int bit
, port
, w
= 0;
1416 /* we cannot print with strings because they
1417 * are not portable, the presentation format may
1418 * not be able to be read in on another computer. */
1419 int print_symbols
= 0;
1422 if(*dl
< 1) return -1;
1423 protocol_nr
= (*d
)[0];
1426 protocol
= getprotobynumber((int)protocol_nr
);
1427 if(protocol
&& (protocol
->p_name
!= NULL
)) {
1428 w
+= sldns_str_print(s
, sl
, "%s", protocol
->p_name
);
1429 proto_name
= protocol
->p_name
;
1431 w
+= sldns_str_print(s
, sl
, "%u", (unsigned)protocol_nr
);
1434 for(i
=0; i
<*dl
; i
++) {
1437 for(bit
=0; bit
<8; bit
++) {
1438 if(!(((*d
)[i
])&(0x80>>bit
)))
1440 port
= (int)i
*8 + bit
;
1445 service
= getservbyport(
1446 (int)htons((uint16_t)port
), proto_name
);
1447 if(service
&& service
->s_name
)
1448 w
+= sldns_str_print(s
, sl
, " %s",
1450 else w
+= sldns_str_print(s
, sl
, " %u",
1455 #ifdef HAVE_ENDSERVENT
1458 #ifdef HAVE_ENDPROTOENT
1466 int sldns_wire2str_nsap_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1468 return print_remainder_hex("0x", d
, dl
, s
, sl
);
1471 int sldns_wire2str_atma_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1473 return print_remainder_hex("", d
, dl
, s
, sl
);
1476 /* internal scan routine that can modify arguments on failure */
1477 static int sldns_wire2str_ipseckey_scan_internal(uint8_t** d
, size_t* dl
,
1478 char** s
, size_t* sl
, uint8_t* pkt
, size_t pktlen
)
1480 /* http://www.ietf.org/internet-drafts/draft-ietf-ipseckey-rr-12.txt*/
1481 uint8_t precedence
, gateway_type
, algorithm
;
1484 if(*dl
< 3) return -1;
1485 precedence
= (*d
)[0];
1486 gateway_type
= (*d
)[1];
1487 algorithm
= (*d
)[2];
1488 if(gateway_type
> 3)
1489 return -1; /* unknown */
1492 w
+= sldns_str_print(s
, sl
, "%d %d %d ",
1493 (int)precedence
, (int)gateway_type
, (int)algorithm
);
1495 switch(gateway_type
) {
1496 case 0: /* no gateway */
1497 w
+= sldns_str_print(s
, sl
, ".");
1500 w
+= sldns_wire2str_a_scan(d
, dl
, s
, sl
);
1503 w
+= sldns_wire2str_aaaa_scan(d
, dl
, s
, sl
);
1506 w
+= sldns_wire2str_dname_scan(d
, dl
, s
, sl
, pkt
, pktlen
);
1508 default: /* unknown */
1514 w
+= sldns_str_print(s
, sl
, " ");
1515 w
+= sldns_wire2str_b64_scan_num(d
, dl
, s
, sl
, *dl
);
1519 int sldns_wire2str_ipseckey_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
,
1520 uint8_t* pkt
, size_t pktlen
)
1524 size_t odl
= *dl
, osl
= *sl
;
1525 int w
=sldns_wire2str_ipseckey_scan_internal(d
, dl
, s
, sl
, pkt
, pktlen
);
1536 int sldns_wire2str_hip_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1539 uint8_t algo
, hitlen
;
1547 pklen
= sldns_read_uint16((*d
)+2);
1548 if(*dl
< (size_t)4 + (size_t)hitlen
+ (size_t)pklen
)
1551 /* write: algo hit pubkey */
1552 w
= sldns_str_print(s
, sl
, "%u ", (unsigned)algo
);
1553 w
+= print_hex_buf(s
, sl
, (*d
)+4, hitlen
);
1554 w
+= sldns_str_print(s
, sl
, " ");
1557 w
+= sldns_wire2str_b64_scan_num(d
, dl
, s
, sl
, pklen
);
1561 int sldns_wire2str_int16_data_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1566 n
= sldns_read_uint16(*d
);
1567 if(*dl
< 2+(size_t)n
)
1571 return sldns_wire2str_b64_scan_num(d
, dl
, s
, sl
, n
);
1574 int sldns_wire2str_nsec3_next_owner_scan(uint8_t** d
, size_t* dl
, char** s
,
1577 return sldns_wire2str_b32_ext_scan(d
, dl
, s
, sl
);
1580 int sldns_wire2str_ilnp64_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1585 w
= sldns_str_print(s
, sl
, "%.4x:%.4x:%.4x:%.4x",
1586 sldns_read_uint16(*d
), sldns_read_uint16((*d
)+2),
1587 sldns_read_uint16((*d
)+4), sldns_read_uint16((*d
)+6));
1593 int sldns_wire2str_eui48_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1598 w
= sldns_str_print(s
, sl
, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
1599 (*d
)[0], (*d
)[1], (*d
)[2], (*d
)[3], (*d
)[4], (*d
)[5]);
1605 int sldns_wire2str_eui64_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1610 w
= sldns_str_print(s
, sl
, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
1611 (*d
)[0], (*d
)[1], (*d
)[2], (*d
)[3], (*d
)[4], (*d
)[5],
1618 int sldns_wire2str_tag_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1624 n
= (size_t)((*d
)[0]);
1628 if(!isalnum((unsigned char)(*d
)[i
]))
1631 w
+= sldns_str_print(s
, sl
, "%c", (char)(*d
)[i
]);
1637 int sldns_wire2str_long_str_scan(uint8_t** d
, size_t* dl
, char** s
, size_t* sl
)
1641 w
+= sldns_str_print(s
, sl
, "\"");
1642 for(i
=0; i
<*dl
; i
++)
1643 w
+= str_char_print(s
, sl
, (*d
)[i
]);
1644 w
+= sldns_str_print(s
, sl
, "\"");
1650 int sldns_wire2str_edns_llq_print(char** s
, size_t* sl
, uint8_t* data
,
1654 const char* llq_errors
[] = {"NO-ERROR", "SERV-FULL", "STATIC",
1655 "FORMAT-ERR", "NO-SUCH-LLQ", "BAD-VERS", "UNKNOWN_ERR"};
1656 const unsigned int llq_errors_num
= 7;
1657 const char* llq_opcodes
[] = {"LLQ-SETUP", "LLQ-REFRESH", "LLQ-EVENT"};
1658 const unsigned int llq_opcodes_num
= 3;
1659 uint16_t version
, llq_opcode
, error_code
;
1661 uint32_t lease_life
; /* Requested or granted life of LLQ, in seconds */
1664 /* read the record */
1666 w
+= sldns_str_print(s
, sl
, "malformed LLQ ");
1667 w
+= print_hex_buf(s
, sl
, data
, len
);
1670 version
= sldns_read_uint16(data
);
1671 llq_opcode
= sldns_read_uint16(data
+2);
1672 error_code
= sldns_read_uint16(data
+4);
1673 memmove(&llq_id
, data
+6, sizeof(llq_id
));
1674 lease_life
= sldns_read_uint32(data
+14);
1677 w
+= sldns_str_print(s
, sl
, "v%d ", (int)version
);
1678 if(llq_opcode
< llq_opcodes_num
)
1679 w
+= sldns_str_print(s
, sl
, "%s", llq_opcodes
[llq_opcode
]);
1680 else w
+= sldns_str_print(s
, sl
, "opcode %d", (int)llq_opcode
);
1681 if(error_code
< llq_errors_num
)
1682 w
+= sldns_str_print(s
, sl
, " %s", llq_errors
[error_code
]);
1683 else w
+= sldns_str_print(s
, sl
, " error %d", (int)error_code
);
1685 w
+= sldns_str_print(s
, sl
, " id %llx lease-life %lu",
1686 (unsigned long long)llq_id
, (unsigned long)lease_life
);
1688 w
+= sldns_str_print(s
, sl
, " id %I64x lease-life %lu",
1689 (unsigned long long)llq_id
, (unsigned long)lease_life
);
1694 int sldns_wire2str_edns_ul_print(char** s
, size_t* sl
, uint8_t* data
,
1700 w
+= sldns_str_print(s
, sl
, "malformed UL ");
1701 w
+= print_hex_buf(s
, sl
, data
, len
);
1704 lease
= sldns_read_uint32(data
);
1705 w
+= sldns_str_print(s
, sl
, "lease %lu", (unsigned long)lease
);
1709 int sldns_wire2str_edns_nsid_print(char** s
, size_t* sl
, uint8_t* data
,
1713 size_t i
, printed
=0;
1714 w
+= print_hex_buf(s
, sl
, data
, len
);
1715 for(i
=0; i
<len
; i
++) {
1716 if(isprint((unsigned char)data
[i
]) || data
[i
] == '\t') {
1718 w
+= sldns_str_print(s
, sl
, " (");
1721 w
+= sldns_str_print(s
, sl
, "%c", (char)data
[i
]);
1725 w
+= sldns_str_print(s
, sl
, ")");
1729 int sldns_wire2str_edns_dau_print(char** s
, size_t* sl
, uint8_t* data
,
1732 sldns_lookup_table
*lt
;
1735 for(i
=0; i
<len
; i
++) {
1736 lt
= sldns_lookup_by_id(sldns_algorithms
, (int)data
[i
]);
1738 w
+= sldns_str_print(s
, sl
, " %s", lt
->name
);
1739 else w
+= sldns_str_print(s
, sl
, " %d", (int)data
[i
]);
1744 int sldns_wire2str_edns_dhu_print(char** s
, size_t* sl
, uint8_t* data
,
1747 sldns_lookup_table
*lt
;
1750 for(i
=0; i
<len
; i
++) {
1751 lt
= sldns_lookup_by_id(sldns_hashes
, (int)data
[i
]);
1753 w
+= sldns_str_print(s
, sl
, " %s", lt
->name
);
1754 else w
+= sldns_str_print(s
, sl
, " %d", (int)data
[i
]);
1759 int sldns_wire2str_edns_n3u_print(char** s
, size_t* sl
, uint8_t* data
,
1764 for(i
=0; i
<len
; i
++) {
1766 w
+= sldns_str_print(s
, sl
, " SHA1");
1767 else w
+= sldns_str_print(s
, sl
, " %d", (int)data
[i
]);
1772 int sldns_wire2str_edns_subnet_print(char** s
, size_t* sl
, uint8_t* data
,
1777 uint8_t source
, scope
;
1779 w
+= sldns_str_print(s
, sl
, "malformed subnet ");
1780 w
+= print_hex_buf(s
, sl
, data
, len
);
1783 family
= sldns_read_uint16(data
);
1790 memset(ip4
, 0, sizeof(ip4
));
1792 w
+= sldns_str_print(s
, sl
, "trailingdata:");
1793 w
+= print_hex_buf(s
, sl
, data
+4+4, len
-4-4);
1794 w
+= sldns_str_print(s
, sl
, " ");
1797 memmove(ip4
, data
+4, len
-4);
1798 if(!inet_ntop(AF_INET
, ip4
, buf
, (socklen_t
)sizeof(buf
))) {
1799 w
+= sldns_str_print(s
, sl
, "ip4ntoperror ");
1800 w
+= print_hex_buf(s
, sl
, data
+4+4, len
-4-4);
1802 w
+= sldns_str_print(s
, sl
, "%s", buf
);
1804 } else if(family
== 2) {
1808 memset(ip6
, 0, sizeof(ip6
));
1810 w
+= sldns_str_print(s
, sl
, "trailingdata:");
1811 w
+= print_hex_buf(s
, sl
, data
+4+16, len
-4-16);
1812 w
+= sldns_str_print(s
, sl
, " ");
1815 memmove(ip6
, data
+4, len
-4);
1817 if(!inet_ntop(AF_INET6
, ip6
, buf
, (socklen_t
)sizeof(buf
))) {
1818 w
+= sldns_str_print(s
, sl
, "ip6ntoperror ");
1819 w
+= print_hex_buf(s
, sl
, data
+4+4, len
-4-4);
1821 w
+= sldns_str_print(s
, sl
, "%s", buf
);
1824 w
+= print_hex_buf(s
, sl
, data
+4+4, len
-4-4);
1828 w
+= sldns_str_print(s
, sl
, "family %d ",
1830 w
+= print_hex_buf(s
, sl
, data
, len
);
1832 w
+= sldns_str_print(s
, sl
, "/%d scope /%d", (int)source
, (int)scope
);
1836 int sldns_wire2str_edns_option_print(char** s
, size_t* sl
,
1837 uint16_t option_code
, uint8_t* optdata
, size_t optlen
)
1840 w
+= sldns_wire2str_edns_option_code_print(s
, sl
, option_code
);
1841 w
+= sldns_str_print(s
, sl
, ": ");
1842 switch(option_code
) {
1844 w
+= sldns_wire2str_edns_llq_print(s
, sl
, optdata
, optlen
);
1847 w
+= sldns_wire2str_edns_ul_print(s
, sl
, optdata
, optlen
);
1849 case LDNS_EDNS_NSID
:
1850 w
+= sldns_wire2str_edns_nsid_print(s
, sl
, optdata
, optlen
);
1853 w
+= sldns_wire2str_edns_dau_print(s
, sl
, optdata
, optlen
);
1856 w
+= sldns_wire2str_edns_dhu_print(s
, sl
, optdata
, optlen
);
1859 w
+= sldns_wire2str_edns_n3u_print(s
, sl
, optdata
, optlen
);
1861 case LDNS_EDNS_CLIENT_SUBNET
:
1862 w
+= sldns_wire2str_edns_subnet_print(s
, sl
, optdata
, optlen
);
1865 /* unknown option code */
1866 w
+= print_hex_buf(s
, sl
, optdata
, optlen
);
1872 /** print the edns options to string */
1874 print_edns_opts(char** s
, size_t* sl
, uint8_t* rdata
, size_t rdatalen
)
1876 uint16_t option_code
, option_len
;
1878 while(rdatalen
> 0) {
1881 w
+= sldns_str_print(s
, sl
, " ; malformed: ");
1882 w
+= print_hex_buf(s
, sl
, rdata
, rdatalen
);
1885 option_code
= sldns_read_uint16(rdata
);
1886 option_len
= sldns_read_uint16(rdata
+2);
1891 if(rdatalen
< (size_t)option_len
) {
1892 w
+= sldns_str_print(s
, sl
, " ; malformed ");
1893 w
+= sldns_wire2str_edns_option_code_print(s
, sl
,
1895 w
+= sldns_str_print(s
, sl
, ": ");
1896 w
+= print_hex_buf(s
, sl
, rdata
, rdatalen
);
1899 w
+= sldns_str_print(s
, sl
, " ; ");
1900 w
+= sldns_wire2str_edns_option_print(s
, sl
, option_code
,
1902 rdata
+= option_len
;
1903 rdatalen
-= option_len
;
1908 int sldns_wire2str_edns_scan(uint8_t** data
, size_t* data_len
, char** str
,
1909 size_t* str_len
, uint8_t* pkt
, size_t pktlen
)
1912 uint8_t ext_rcode
, edns_version
;
1913 uint16_t udpsize
, edns_bits
, rdatalen
;
1914 w
+= sldns_str_print(str
, str_len
, "; EDNS:");
1916 /* some input checks, domain name */
1917 if(*data_len
< 1+10)
1918 return w
+ print_remainder_hex("Error malformed 0x",
1919 data
, data_len
, str
, str_len
);
1921 return w
+ print_remainder_hex("Error nonrootdname 0x",
1922 data
, data_len
, str
, str_len
);
1927 /* check type and read fixed contents */
1928 if(sldns_read_uint16((*data
)) != LDNS_RR_TYPE_OPT
) {
1929 return w
+ print_remainder_hex("Error nottypeOPT 0x",
1930 data
, data_len
, str
, str_len
);
1932 udpsize
= sldns_read_uint16((*data
)+2);
1933 ext_rcode
= (*data
)[4];
1934 edns_version
= (*data
)[5];
1935 edns_bits
= sldns_read_uint16((*data
)+6);
1936 rdatalen
= sldns_read_uint16((*data
)+8);
1940 w
+= sldns_str_print(str
, str_len
, " version: %u;",
1941 (unsigned)edns_version
);
1942 w
+= sldns_str_print(str
, str_len
, " flags:");
1943 if((edns_bits
& LDNS_EDNS_MASK_DO_BIT
))
1944 w
+= sldns_str_print(str
, str_len
, " do");
1945 /* the extended rcode is the value set, shifted four bits,
1946 * and or'd with the original rcode */
1948 int rc
= ((int)ext_rcode
)<<4;
1949 if(pkt
&& pktlen
>= LDNS_HEADER_SIZE
)
1950 rc
|= LDNS_RCODE_WIRE(pkt
);
1951 w
+= sldns_str_print(str
, str_len
, " ; ext-rcode: %d", rc
);
1953 w
+= sldns_str_print(str
, str_len
, " ; udp: %u", (unsigned)udpsize
);
1956 if(*data_len
< rdatalen
) {
1957 w
+= sldns_str_print(str
, str_len
,
1958 " ; Error EDNS rdata too short; ");
1959 rdatalen
= *data_len
;
1961 w
+= print_edns_opts(str
, str_len
, *data
, rdatalen
);
1962 (*data
) += rdatalen
;
1963 (*data_len
) -= rdatalen
;
1965 w
+= sldns_str_print(str
, str_len
, "\n");