109a3aaf3SDag-Erling Smørgrav /* 209a3aaf3SDag-Erling Smørgrav * wire2str.c 309a3aaf3SDag-Erling Smørgrav * 409a3aaf3SDag-Erling Smørgrav * conversion routines from the wire format 509a3aaf3SDag-Erling Smørgrav * to the presentation format (strings) 609a3aaf3SDag-Erling Smørgrav * 709a3aaf3SDag-Erling Smørgrav * (c) NLnet Labs, 2004-2006 809a3aaf3SDag-Erling Smørgrav * 909a3aaf3SDag-Erling Smørgrav * See the file LICENSE for the license 1009a3aaf3SDag-Erling Smørgrav */ 1109a3aaf3SDag-Erling Smørgrav /** 1209a3aaf3SDag-Erling Smørgrav * \file 1309a3aaf3SDag-Erling Smørgrav * 1409a3aaf3SDag-Erling Smørgrav * Contains functions to translate the wireformat to text 1509a3aaf3SDag-Erling Smørgrav * representation, as well as functions to print them. 1609a3aaf3SDag-Erling Smørgrav */ 1709a3aaf3SDag-Erling Smørgrav #include "config.h" 1809a3aaf3SDag-Erling Smørgrav #include "sldns/wire2str.h" 1909a3aaf3SDag-Erling Smørgrav #include "sldns/str2wire.h" 2009a3aaf3SDag-Erling Smørgrav #include "sldns/rrdef.h" 2109a3aaf3SDag-Erling Smørgrav #include "sldns/pkthdr.h" 2209a3aaf3SDag-Erling Smørgrav #include "sldns/parseutil.h" 2309a3aaf3SDag-Erling Smørgrav #include "sldns/sbuffer.h" 2409a3aaf3SDag-Erling Smørgrav #include "sldns/keyraw.h" 250eefd307SCy Schubert #include "util/data/dname.h" 2609a3aaf3SDag-Erling Smørgrav #ifdef HAVE_TIME_H 2709a3aaf3SDag-Erling Smørgrav #include <time.h> 2809a3aaf3SDag-Erling Smørgrav #endif 2909a3aaf3SDag-Erling Smørgrav #include <sys/time.h> 3009a3aaf3SDag-Erling Smørgrav #include <stdarg.h> 3109a3aaf3SDag-Erling Smørgrav #include <ctype.h> 3209a3aaf3SDag-Erling Smørgrav #ifdef HAVE_NETDB_H 3309a3aaf3SDag-Erling Smørgrav #include <netdb.h> 3409a3aaf3SDag-Erling Smørgrav #endif 3509a3aaf3SDag-Erling Smørgrav 3609a3aaf3SDag-Erling Smørgrav /* lookup tables for standard DNS stuff */ 3709a3aaf3SDag-Erling Smørgrav /* Taken from RFC 2535, section 7. */ 3809a3aaf3SDag-Erling Smørgrav static sldns_lookup_table sldns_algorithms_data[] = { 3909a3aaf3SDag-Erling Smørgrav { LDNS_RSAMD5, "RSAMD5" }, 4009a3aaf3SDag-Erling Smørgrav { LDNS_DH, "DH" }, 4109a3aaf3SDag-Erling Smørgrav { LDNS_DSA, "DSA" }, 4209a3aaf3SDag-Erling Smørgrav { LDNS_ECC, "ECC" }, 4309a3aaf3SDag-Erling Smørgrav { LDNS_RSASHA1, "RSASHA1" }, 4409a3aaf3SDag-Erling Smørgrav { LDNS_DSA_NSEC3, "DSA-NSEC3-SHA1" }, 4509a3aaf3SDag-Erling Smørgrav { LDNS_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" }, 4609a3aaf3SDag-Erling Smørgrav { LDNS_RSASHA256, "RSASHA256"}, 4709a3aaf3SDag-Erling Smørgrav { LDNS_RSASHA512, "RSASHA512"}, 4809a3aaf3SDag-Erling Smørgrav { LDNS_ECC_GOST, "ECC-GOST"}, 4909a3aaf3SDag-Erling Smørgrav { LDNS_ECDSAP256SHA256, "ECDSAP256SHA256"}, 5009a3aaf3SDag-Erling Smørgrav { LDNS_ECDSAP384SHA384, "ECDSAP384SHA384"}, 5165b390aaSDag-Erling Smørgrav { LDNS_ED25519, "ED25519"}, 5265b390aaSDag-Erling Smørgrav { LDNS_ED448, "ED448"}, 5309a3aaf3SDag-Erling Smørgrav { LDNS_INDIRECT, "INDIRECT" }, 5409a3aaf3SDag-Erling Smørgrav { LDNS_PRIVATEDNS, "PRIVATEDNS" }, 5509a3aaf3SDag-Erling Smørgrav { LDNS_PRIVATEOID, "PRIVATEOID" }, 5609a3aaf3SDag-Erling Smørgrav { 0, NULL } 5709a3aaf3SDag-Erling Smørgrav }; 5809a3aaf3SDag-Erling Smørgrav sldns_lookup_table* sldns_algorithms = sldns_algorithms_data; 5909a3aaf3SDag-Erling Smørgrav 6009a3aaf3SDag-Erling Smørgrav /* hash algorithms in DS record */ 6109a3aaf3SDag-Erling Smørgrav static sldns_lookup_table sldns_hashes_data[] = { 6209a3aaf3SDag-Erling Smørgrav { LDNS_SHA1, "SHA1" }, 6309a3aaf3SDag-Erling Smørgrav { LDNS_SHA256, "SHA256" }, 6409a3aaf3SDag-Erling Smørgrav { LDNS_HASH_GOST, "HASH-GOST" }, 6509a3aaf3SDag-Erling Smørgrav { LDNS_SHA384, "SHA384" }, 6609a3aaf3SDag-Erling Smørgrav { 0, NULL } 6709a3aaf3SDag-Erling Smørgrav }; 6809a3aaf3SDag-Erling Smørgrav sldns_lookup_table* sldns_hashes = sldns_hashes_data; 6909a3aaf3SDag-Erling Smørgrav 7009a3aaf3SDag-Erling Smørgrav /* Taken from RFC 4398 */ 7109a3aaf3SDag-Erling Smørgrav static sldns_lookup_table sldns_cert_algorithms_data[] = { 7209a3aaf3SDag-Erling Smørgrav { LDNS_CERT_PKIX, "PKIX" }, 7309a3aaf3SDag-Erling Smørgrav { LDNS_CERT_SPKI, "SPKI" }, 7409a3aaf3SDag-Erling Smørgrav { LDNS_CERT_PGP, "PGP" }, 7509a3aaf3SDag-Erling Smørgrav { LDNS_CERT_IPKIX, "IPKIX" }, 7609a3aaf3SDag-Erling Smørgrav { LDNS_CERT_ISPKI, "ISPKI" }, 7709a3aaf3SDag-Erling Smørgrav { LDNS_CERT_IPGP, "IPGP" }, 7809a3aaf3SDag-Erling Smørgrav { LDNS_CERT_ACPKIX, "ACPKIX" }, 7909a3aaf3SDag-Erling Smørgrav { LDNS_CERT_IACPKIX, "IACPKIX" }, 8009a3aaf3SDag-Erling Smørgrav { LDNS_CERT_URI, "URI" }, 8109a3aaf3SDag-Erling Smørgrav { LDNS_CERT_OID, "OID" }, 8209a3aaf3SDag-Erling Smørgrav { 0, NULL } 8309a3aaf3SDag-Erling Smørgrav }; 8409a3aaf3SDag-Erling Smørgrav sldns_lookup_table* sldns_cert_algorithms = sldns_cert_algorithms_data; 8509a3aaf3SDag-Erling Smørgrav 8609a3aaf3SDag-Erling Smørgrav /* if these are used elsewhere */ 8709a3aaf3SDag-Erling Smørgrav static sldns_lookup_table sldns_rcodes_data[] = { 8809a3aaf3SDag-Erling Smørgrav { LDNS_RCODE_NOERROR, "NOERROR" }, 8909a3aaf3SDag-Erling Smørgrav { LDNS_RCODE_FORMERR, "FORMERR" }, 9009a3aaf3SDag-Erling Smørgrav { LDNS_RCODE_SERVFAIL, "SERVFAIL" }, 9109a3aaf3SDag-Erling Smørgrav { LDNS_RCODE_NXDOMAIN, "NXDOMAIN" }, 9209a3aaf3SDag-Erling Smørgrav { LDNS_RCODE_NOTIMPL, "NOTIMPL" }, 9309a3aaf3SDag-Erling Smørgrav { LDNS_RCODE_REFUSED, "REFUSED" }, 9409a3aaf3SDag-Erling Smørgrav { LDNS_RCODE_YXDOMAIN, "YXDOMAIN" }, 9509a3aaf3SDag-Erling Smørgrav { LDNS_RCODE_YXRRSET, "YXRRSET" }, 9609a3aaf3SDag-Erling Smørgrav { LDNS_RCODE_NXRRSET, "NXRRSET" }, 9709a3aaf3SDag-Erling Smørgrav { LDNS_RCODE_NOTAUTH, "NOTAUTH" }, 9809a3aaf3SDag-Erling Smørgrav { LDNS_RCODE_NOTZONE, "NOTZONE" }, 9909a3aaf3SDag-Erling Smørgrav { 0, NULL } 10009a3aaf3SDag-Erling Smørgrav }; 10109a3aaf3SDag-Erling Smørgrav sldns_lookup_table* sldns_rcodes = sldns_rcodes_data; 10209a3aaf3SDag-Erling Smørgrav 10309a3aaf3SDag-Erling Smørgrav static sldns_lookup_table sldns_opcodes_data[] = { 10409a3aaf3SDag-Erling Smørgrav { LDNS_PACKET_QUERY, "QUERY" }, 10509a3aaf3SDag-Erling Smørgrav { LDNS_PACKET_IQUERY, "IQUERY" }, 10609a3aaf3SDag-Erling Smørgrav { LDNS_PACKET_STATUS, "STATUS" }, 10709a3aaf3SDag-Erling Smørgrav { LDNS_PACKET_NOTIFY, "NOTIFY" }, 10809a3aaf3SDag-Erling Smørgrav { LDNS_PACKET_UPDATE, "UPDATE" }, 10909a3aaf3SDag-Erling Smørgrav { 0, NULL } 11009a3aaf3SDag-Erling Smørgrav }; 11109a3aaf3SDag-Erling Smørgrav sldns_lookup_table* sldns_opcodes = sldns_opcodes_data; 11209a3aaf3SDag-Erling Smørgrav 11309a3aaf3SDag-Erling Smørgrav static sldns_lookup_table sldns_wireparse_errors_data[] = { 11409a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_OK, "no parse error" }, 11509a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_GENERAL, "parse error" }, 11609a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW, "Domainname length overflow" }, 11709a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_DOMAINNAME_UNDERFLOW, "Domainname length underflow (zero length)" }, 11809a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, "buffer too small" }, 11909a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_LABEL_OVERFLOW, "Label length overflow" }, 12009a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_EMPTY_LABEL, "Empty label" }, 12109a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_BAD_ESCAPE, "Syntax error, bad escape sequence" }, 12209a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX, "Syntax error, could not parse the RR" }, 12309a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_TTL, "Syntax error, could not parse the RR's TTL" }, 12409a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_TYPE, "Syntax error, could not parse the RR's type" }, 12509a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_CLASS, "Syntax error, could not parse the RR's class" }, 12609a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_RDATA, "Syntax error, could not parse the RR's rdata" }, 12709a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_MISSING_VALUE, "Syntax error, value expected" }, 12809a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_INVALID_STR, "Conversion error, string expected" }, 12909a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_B64, "Conversion error, b64 encoding expected" }, 13009a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_B32_EXT, "Conversion error, b32 ext encoding expected" }, 13109a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_HEX, "Conversion error, hex encoding expected" }, 13209a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_CERT_BAD_ALGORITHM, "Bad algorithm type for CERT record" }, 13309a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_TIME, "Conversion error, time encoding expected" }, 13409a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_PERIOD, "Conversion error, time period encoding expected" }, 13509a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_ILNP64, "Conversion error, 4 colon separated hex numbers expected" }, 13609a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_EUI48, 13709a3aaf3SDag-Erling Smørgrav "Conversion error, 6 two character hex numbers " 13809a3aaf3SDag-Erling Smørgrav "separated by dashes expected (i.e. xx-xx-xx-xx-xx-xx" }, 13909a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_EUI64, 14009a3aaf3SDag-Erling Smørgrav "Conversion error, 8 two character hex numbers " 14109a3aaf3SDag-Erling Smørgrav "separated by dashes expected (i.e. xx-xx-xx-xx-xx-xx-xx-xx" }, 14209a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_TAG, 14309a3aaf3SDag-Erling Smørgrav "Conversion error, a non-zero sequence of US-ASCII letters " 14409a3aaf3SDag-Erling Smørgrav "and numbers in lower case expected" }, 14509a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_NOT_IMPL, "not implemented" }, 14609a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_INT, "Conversion error, integer expected" }, 14709a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_IP4, "Conversion error, ip4 addr expected" }, 14809a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_IP6, "Conversion error, ip6 addr expected" }, 14909a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW, "Syntax error, integer overflow" }, 15009a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_INCLUDE, "$INCLUDE directive was seen in the zone" }, 15109a3aaf3SDag-Erling Smørgrav { LDNS_WIREPARSE_ERR_PARENTHESIS, "Parse error, parenthesis mismatch" }, 1525469a995SCy Schubert { LDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY, "Unknown SvcParamKey"}, 1535469a995SCy Schubert { LDNS_WIREPARSE_ERR_SVCB_MISSING_PARAM, "SvcParam is missing a SvcParamValue"}, 1545469a995SCy Schubert { LDNS_WIREPARSE_ERR_SVCB_DUPLICATE_KEYS, "Duplicate SVCB key found"}, 1555469a995SCy Schubert { LDNS_WIREPARSE_ERR_SVCB_MANDATORY_TOO_MANY_KEYS, "Too many keys in mandatory" }, 1565469a995SCy Schubert { LDNS_WIREPARSE_ERR_SVCB_TOO_MANY_PARAMS, 1575469a995SCy Schubert "Too many SvcParams. Unbound only allows 63 entries" }, 1585469a995SCy Schubert { LDNS_WIREPARSE_ERR_SVCB_MANDATORY_MISSING_PARAM, 1595469a995SCy Schubert "Mandatory SvcParamKey is missing"}, 1605469a995SCy Schubert { LDNS_WIREPARSE_ERR_SVCB_MANDATORY_DUPLICATE_KEY, 1615469a995SCy Schubert "Keys in SvcParam mandatory MUST be unique" }, 1625469a995SCy Schubert { LDNS_WIREPARSE_ERR_SVCB_MANDATORY_IN_MANDATORY, 1635469a995SCy Schubert "mandatory MUST not be included as mandatory parameter" }, 1645469a995SCy Schubert { LDNS_WIREPARSE_ERR_SVCB_PORT_VALUE_SYNTAX, 1655469a995SCy Schubert "Could not parse port SvcParamValue" }, 1665469a995SCy Schubert { LDNS_WIREPARSE_ERR_SVCB_IPV4_TOO_MANY_ADDRESSES, 1675469a995SCy Schubert "Too many IPv4 addresses in ipv4hint" }, 1685469a995SCy Schubert { LDNS_WIREPARSE_ERR_SVCB_IPV6_TOO_MANY_ADDRESSES, 1695469a995SCy Schubert "Too many IPv6 addresses in ipv6hint" }, 1705469a995SCy Schubert { LDNS_WIREPARSE_ERR_SVCB_ALPN_KEY_TOO_LARGE, 1715469a995SCy Schubert "Alpn strings need to be smaller than 255 chars"}, 1725469a995SCy Schubert { LDNS_WIREPARSE_ERR_SVCB_NO_DEFAULT_ALPN_VALUE, 1735469a995SCy Schubert "No-default-alpn should not have a value" }, 1745469a995SCy Schubert { LDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA, 1755469a995SCy Schubert "General SVCParam error" }, 17609a3aaf3SDag-Erling Smørgrav { 0, NULL } 17709a3aaf3SDag-Erling Smørgrav }; 17809a3aaf3SDag-Erling Smørgrav sldns_lookup_table* sldns_wireparse_errors = sldns_wireparse_errors_data; 17909a3aaf3SDag-Erling Smørgrav 18009a3aaf3SDag-Erling Smørgrav static sldns_lookup_table sldns_edns_flags_data[] = { 18109a3aaf3SDag-Erling Smørgrav { 3600, "do"}, 18209a3aaf3SDag-Erling Smørgrav { 0, NULL} 18309a3aaf3SDag-Erling Smørgrav }; 18409a3aaf3SDag-Erling Smørgrav sldns_lookup_table* sldns_edns_flags = sldns_edns_flags_data; 18509a3aaf3SDag-Erling Smørgrav 18609a3aaf3SDag-Erling Smørgrav static sldns_lookup_table sldns_edns_options_data[] = { 18709a3aaf3SDag-Erling Smørgrav { 1, "LLQ" }, 18809a3aaf3SDag-Erling Smørgrav { 2, "UL" }, 18909a3aaf3SDag-Erling Smørgrav { 3, "NSID" }, 19009a3aaf3SDag-Erling Smørgrav /* 4 draft-cheshire-edns0-owner-option */ 19109a3aaf3SDag-Erling Smørgrav { 5, "DAU" }, 19209a3aaf3SDag-Erling Smørgrav { 6, "DHU" }, 19309a3aaf3SDag-Erling Smørgrav { 7, "N3U" }, 19409a3aaf3SDag-Erling Smørgrav { 8, "edns-client-subnet" }, 195103ba509SCy Schubert { 10, "COOKIE" }, 19665b390aaSDag-Erling Smørgrav { 11, "edns-tcp-keepalive"}, 197e2d15004SDag-Erling Smørgrav { 12, "Padding" }, 198a39a5a69SCy Schubert { 15, "EDE"}, 19909a3aaf3SDag-Erling Smørgrav { 0, NULL} 20009a3aaf3SDag-Erling Smørgrav }; 20109a3aaf3SDag-Erling Smørgrav sldns_lookup_table* sldns_edns_options = sldns_edns_options_data; 20209a3aaf3SDag-Erling Smørgrav 203103ba509SCy Schubert /* From RFC8914 5.2 Table 3, the "Extended DNS Error Codes" registry. */ 204103ba509SCy Schubert static sldns_lookup_table sldns_edns_ede_codes_data[] = { 205103ba509SCy Schubert { LDNS_EDE_NONE, "None" }, 206103ba509SCy Schubert { LDNS_EDE_OTHER, "Other Error" }, 207103ba509SCy Schubert { LDNS_EDE_UNSUPPORTED_DNSKEY_ALG, "Unsupported DNSKEY Algorithm" }, 208103ba509SCy Schubert { LDNS_EDE_UNSUPPORTED_DS_DIGEST, "Unsupported DS Digest Type" }, 209103ba509SCy Schubert { LDNS_EDE_STALE_ANSWER, "Stale Answer" }, 210103ba509SCy Schubert { LDNS_EDE_FORGED_ANSWER, "Forged Answer" }, 211103ba509SCy Schubert { LDNS_EDE_DNSSEC_INDETERMINATE, "DNSSEC Indeterminate" }, 212103ba509SCy Schubert { LDNS_EDE_DNSSEC_BOGUS, "DNSSEC Bogus" }, 213103ba509SCy Schubert { LDNS_EDE_SIGNATURE_EXPIRED, "Signature Expired" }, 214103ba509SCy Schubert { LDNS_EDE_SIGNATURE_NOT_YET_VALID, "Signature Not Yet Valid" }, 215103ba509SCy Schubert { LDNS_EDE_DNSKEY_MISSING, "DNSKEY Missing" }, 216103ba509SCy Schubert { LDNS_EDE_RRSIGS_MISSING, "RRSIGs Missing" }, 217103ba509SCy Schubert { LDNS_EDE_NO_ZONE_KEY_BIT_SET, "No Zone Key Bit Set" }, 218103ba509SCy Schubert { LDNS_EDE_NSEC_MISSING, "NSEC Missing" }, 219103ba509SCy Schubert { LDNS_EDE_CACHED_ERROR, "Cached Error" }, 220103ba509SCy Schubert { LDNS_EDE_NOT_READY, "Not Ready" }, 221103ba509SCy Schubert { LDNS_EDE_BLOCKED, "Blocked" }, 222103ba509SCy Schubert { LDNS_EDE_CENSORED, "Censored" }, 223103ba509SCy Schubert { LDNS_EDE_FILTERED, "Filtered" }, 224103ba509SCy Schubert { LDNS_EDE_PROHIBITED, "Prohibited" }, 225103ba509SCy Schubert { LDNS_EDE_STALE_NXDOMAIN_ANSWER, "Stale NXDOMAIN Answer" }, 226103ba509SCy Schubert { LDNS_EDE_NOT_AUTHORITATIVE, "Not Authoritative" }, 227103ba509SCy Schubert { LDNS_EDE_NOT_SUPPORTED, "Not Supported" }, 228103ba509SCy Schubert { LDNS_EDE_NO_REACHABLE_AUTHORITY, "No Reachable Authority" }, 229103ba509SCy Schubert { LDNS_EDE_NETWORK_ERROR, "Network Error" }, 230103ba509SCy Schubert { LDNS_EDE_INVALID_DATA, "Invalid Data" }, 231*56850988SCy Schubert { LDNS_EDE_SIGNATURE_EXPIRED_BEFORE_VALID, "Signature Expired Before Valid" }, 232*56850988SCy Schubert { LDNS_EDE_TOO_EARLY, "Non-Replayable Transactions Received in 0-RTT Data" }, 233*56850988SCy Schubert { LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS, "Unsupported NSEC3 Iterations Value" }, 234*56850988SCy Schubert { LDNS_EDE_BADPROXYPOLICY, "Unable to Conform to Policy" }, 235*56850988SCy Schubert { LDNS_EDE_SYNTHESIZED, "Synthesized Answer" }, 236103ba509SCy Schubert { 0, NULL} 237103ba509SCy Schubert }; 238103ba509SCy Schubert sldns_lookup_table* sldns_edns_ede_codes = sldns_edns_ede_codes_data; 239103ba509SCy Schubert 240c7f4d7adSDag-Erling Smørgrav static sldns_lookup_table sldns_tsig_errors_data[] = { 241c7f4d7adSDag-Erling Smørgrav { LDNS_TSIG_ERROR_NOERROR, "NOERROR" }, 242c7f4d7adSDag-Erling Smørgrav { LDNS_RCODE_FORMERR, "FORMERR" }, 243c7f4d7adSDag-Erling Smørgrav { LDNS_RCODE_SERVFAIL, "SERVFAIL" }, 244c7f4d7adSDag-Erling Smørgrav { LDNS_RCODE_NXDOMAIN, "NXDOMAIN" }, 245c7f4d7adSDag-Erling Smørgrav { LDNS_RCODE_NOTIMPL, "NOTIMPL" }, 246c7f4d7adSDag-Erling Smørgrav { LDNS_RCODE_REFUSED, "REFUSED" }, 247c7f4d7adSDag-Erling Smørgrav { LDNS_RCODE_YXDOMAIN, "YXDOMAIN" }, 248c7f4d7adSDag-Erling Smørgrav { LDNS_RCODE_YXRRSET, "YXRRSET" }, 249c7f4d7adSDag-Erling Smørgrav { LDNS_RCODE_NXRRSET, "NXRRSET" }, 250c7f4d7adSDag-Erling Smørgrav { LDNS_RCODE_NOTAUTH, "NOTAUTH" }, 251c7f4d7adSDag-Erling Smørgrav { LDNS_RCODE_NOTZONE, "NOTZONE" }, 252c7f4d7adSDag-Erling Smørgrav { LDNS_TSIG_ERROR_BADSIG, "BADSIG" }, 253c7f4d7adSDag-Erling Smørgrav { LDNS_TSIG_ERROR_BADKEY, "BADKEY" }, 254c7f4d7adSDag-Erling Smørgrav { LDNS_TSIG_ERROR_BADTIME, "BADTIME" }, 255c7f4d7adSDag-Erling Smørgrav { LDNS_TSIG_ERROR_BADMODE, "BADMODE" }, 256c7f4d7adSDag-Erling Smørgrav { LDNS_TSIG_ERROR_BADNAME, "BADNAME" }, 257c7f4d7adSDag-Erling Smørgrav { LDNS_TSIG_ERROR_BADALG, "BADALG" }, 258c7f4d7adSDag-Erling Smørgrav { 0, NULL } 259c7f4d7adSDag-Erling Smørgrav }; 260c7f4d7adSDag-Erling Smørgrav sldns_lookup_table* sldns_tsig_errors = sldns_tsig_errors_data; 261c7f4d7adSDag-Erling Smørgrav 2625469a995SCy Schubert /* draft-ietf-dnsop-svcb-https-06: 6. Initial SvcParamKeys */ 2635469a995SCy Schubert const char *svcparamkey_strs[] = { 2645469a995SCy Schubert "mandatory", "alpn", "no-default-alpn", "port", 2658f76bb7dSCy Schubert "ipv4hint", "ech", "ipv6hint", "dohpath" 2665469a995SCy Schubert }; 2675469a995SCy Schubert 26809a3aaf3SDag-Erling Smørgrav char* sldns_wire2str_pkt(uint8_t* data, size_t len) 26909a3aaf3SDag-Erling Smørgrav { 27009a3aaf3SDag-Erling Smørgrav size_t slen = (size_t)sldns_wire2str_pkt_buf(data, len, NULL, 0); 27109a3aaf3SDag-Erling Smørgrav char* result = (char*)malloc(slen+1); 27209a3aaf3SDag-Erling Smørgrav if(!result) return NULL; 27309a3aaf3SDag-Erling Smørgrav sldns_wire2str_pkt_buf(data, len, result, slen+1); 27409a3aaf3SDag-Erling Smørgrav return result; 27509a3aaf3SDag-Erling Smørgrav } 27609a3aaf3SDag-Erling Smørgrav 27709a3aaf3SDag-Erling Smørgrav char* sldns_wire2str_rr(uint8_t* rr, size_t len) 27809a3aaf3SDag-Erling Smørgrav { 27909a3aaf3SDag-Erling Smørgrav size_t slen = (size_t)sldns_wire2str_rr_buf(rr, len, NULL, 0); 28009a3aaf3SDag-Erling Smørgrav char* result = (char*)malloc(slen+1); 28109a3aaf3SDag-Erling Smørgrav if(!result) return NULL; 28209a3aaf3SDag-Erling Smørgrav sldns_wire2str_rr_buf(rr, len, result, slen+1); 28309a3aaf3SDag-Erling Smørgrav return result; 28409a3aaf3SDag-Erling Smørgrav } 28509a3aaf3SDag-Erling Smørgrav 28609a3aaf3SDag-Erling Smørgrav char* sldns_wire2str_type(uint16_t rrtype) 28709a3aaf3SDag-Erling Smørgrav { 28809a3aaf3SDag-Erling Smørgrav char buf[16]; 28909a3aaf3SDag-Erling Smørgrav sldns_wire2str_type_buf(rrtype, buf, sizeof(buf)); 29009a3aaf3SDag-Erling Smørgrav return strdup(buf); 29109a3aaf3SDag-Erling Smørgrav } 29209a3aaf3SDag-Erling Smørgrav 29309a3aaf3SDag-Erling Smørgrav char* sldns_wire2str_class(uint16_t rrclass) 29409a3aaf3SDag-Erling Smørgrav { 29509a3aaf3SDag-Erling Smørgrav char buf[16]; 29609a3aaf3SDag-Erling Smørgrav sldns_wire2str_class_buf(rrclass, buf, sizeof(buf)); 29709a3aaf3SDag-Erling Smørgrav return strdup(buf); 29809a3aaf3SDag-Erling Smørgrav } 29909a3aaf3SDag-Erling Smørgrav 30009a3aaf3SDag-Erling Smørgrav char* sldns_wire2str_dname(uint8_t* dname, size_t dname_len) 30109a3aaf3SDag-Erling Smørgrav { 30209a3aaf3SDag-Erling Smørgrav size_t slen=(size_t)sldns_wire2str_dname_buf(dname, dname_len, NULL, 0); 30309a3aaf3SDag-Erling Smørgrav char* result = (char*)malloc(slen+1); 30409a3aaf3SDag-Erling Smørgrav if(!result) return NULL; 30509a3aaf3SDag-Erling Smørgrav sldns_wire2str_dname_buf(dname, dname_len, result, slen+1); 30609a3aaf3SDag-Erling Smørgrav return result; 30709a3aaf3SDag-Erling Smørgrav } 30809a3aaf3SDag-Erling Smørgrav 30909a3aaf3SDag-Erling Smørgrav char* sldns_wire2str_rcode(int rcode) 31009a3aaf3SDag-Erling Smørgrav { 31109a3aaf3SDag-Erling Smørgrav char buf[16]; 31209a3aaf3SDag-Erling Smørgrav sldns_wire2str_rcode_buf(rcode, buf, sizeof(buf)); 31309a3aaf3SDag-Erling Smørgrav return strdup(buf); 31409a3aaf3SDag-Erling Smørgrav } 31509a3aaf3SDag-Erling Smørgrav 31609a3aaf3SDag-Erling Smørgrav int sldns_wire2str_pkt_buf(uint8_t* d, size_t dlen, char* s, size_t slen) 31709a3aaf3SDag-Erling Smørgrav { 31809a3aaf3SDag-Erling Smørgrav /* use arguments as temporary variables */ 31909a3aaf3SDag-Erling Smørgrav return sldns_wire2str_pkt_scan(&d, &dlen, &s, &slen); 32009a3aaf3SDag-Erling Smørgrav } 32109a3aaf3SDag-Erling Smørgrav 32209a3aaf3SDag-Erling Smørgrav int sldns_wire2str_rr_buf(uint8_t* d, size_t dlen, char* s, size_t slen) 32309a3aaf3SDag-Erling Smørgrav { 32409a3aaf3SDag-Erling Smørgrav /* use arguments as temporary variables */ 3250eefd307SCy Schubert return sldns_wire2str_rr_scan(&d, &dlen, &s, &slen, NULL, 0, NULL); 32609a3aaf3SDag-Erling Smørgrav } 32709a3aaf3SDag-Erling Smørgrav 32857bddd21SDag-Erling Smørgrav int sldns_wire2str_rrquestion_buf(uint8_t* d, size_t dlen, char* s, size_t slen) 32957bddd21SDag-Erling Smørgrav { 33057bddd21SDag-Erling Smørgrav /* use arguments as temporary variables */ 3310eefd307SCy Schubert return sldns_wire2str_rrquestion_scan(&d, &dlen, &s, &slen, NULL, 0, NULL); 33257bddd21SDag-Erling Smørgrav } 33357bddd21SDag-Erling Smørgrav 33409a3aaf3SDag-Erling Smørgrav int sldns_wire2str_rdata_buf(uint8_t* rdata, size_t rdata_len, char* str, 33509a3aaf3SDag-Erling Smørgrav size_t str_len, uint16_t rrtype) 33609a3aaf3SDag-Erling Smørgrav { 33709a3aaf3SDag-Erling Smørgrav /* use arguments as temporary variables */ 33809a3aaf3SDag-Erling Smørgrav return sldns_wire2str_rdata_scan(&rdata, &rdata_len, &str, &str_len, 3390eefd307SCy Schubert rrtype, NULL, 0, NULL); 34009a3aaf3SDag-Erling Smørgrav } 34109a3aaf3SDag-Erling Smørgrav 34209a3aaf3SDag-Erling Smørgrav int sldns_wire2str_rr_unknown_buf(uint8_t* d, size_t dlen, char* s, size_t slen) 34309a3aaf3SDag-Erling Smørgrav { 34409a3aaf3SDag-Erling Smørgrav /* use arguments as temporary variables */ 3450eefd307SCy Schubert return sldns_wire2str_rr_unknown_scan(&d, &dlen, &s, &slen, NULL, 0, NULL); 34609a3aaf3SDag-Erling Smørgrav } 34709a3aaf3SDag-Erling Smørgrav 34809a3aaf3SDag-Erling Smørgrav int sldns_wire2str_rr_comment_buf(uint8_t* rr, size_t rrlen, size_t dname_len, 34909a3aaf3SDag-Erling Smørgrav char* s, size_t slen) 35009a3aaf3SDag-Erling Smørgrav { 35109a3aaf3SDag-Erling Smørgrav uint16_t rrtype = sldns_wirerr_get_type(rr, rrlen, dname_len); 35209a3aaf3SDag-Erling Smørgrav return sldns_wire2str_rr_comment_print(&s, &slen, rr, rrlen, dname_len, 35309a3aaf3SDag-Erling Smørgrav rrtype); 35409a3aaf3SDag-Erling Smørgrav } 35509a3aaf3SDag-Erling Smørgrav 35609a3aaf3SDag-Erling Smørgrav int sldns_wire2str_type_buf(uint16_t rrtype, char* s, size_t slen) 35709a3aaf3SDag-Erling Smørgrav { 35809a3aaf3SDag-Erling Smørgrav /* use arguments as temporary variables */ 35909a3aaf3SDag-Erling Smørgrav return sldns_wire2str_type_print(&s, &slen, rrtype); 36009a3aaf3SDag-Erling Smørgrav } 36109a3aaf3SDag-Erling Smørgrav 36209a3aaf3SDag-Erling Smørgrav int sldns_wire2str_class_buf(uint16_t rrclass, char* s, size_t slen) 36309a3aaf3SDag-Erling Smørgrav { 36409a3aaf3SDag-Erling Smørgrav /* use arguments as temporary variables */ 36509a3aaf3SDag-Erling Smørgrav return sldns_wire2str_class_print(&s, &slen, rrclass); 36609a3aaf3SDag-Erling Smørgrav } 36709a3aaf3SDag-Erling Smørgrav 36809a3aaf3SDag-Erling Smørgrav int sldns_wire2str_rcode_buf(int rcode, char* s, size_t slen) 36909a3aaf3SDag-Erling Smørgrav { 37009a3aaf3SDag-Erling Smørgrav /* use arguments as temporary variables */ 37109a3aaf3SDag-Erling Smørgrav return sldns_wire2str_rcode_print(&s, &slen, rcode); 37209a3aaf3SDag-Erling Smørgrav } 37309a3aaf3SDag-Erling Smørgrav 37465b390aaSDag-Erling Smørgrav int sldns_wire2str_opcode_buf(int opcode, char* s, size_t slen) 37565b390aaSDag-Erling Smørgrav { 37665b390aaSDag-Erling Smørgrav /* use arguments as temporary variables */ 37765b390aaSDag-Erling Smørgrav return sldns_wire2str_opcode_print(&s, &slen, opcode); 37865b390aaSDag-Erling Smørgrav } 37965b390aaSDag-Erling Smørgrav 38009a3aaf3SDag-Erling Smørgrav int sldns_wire2str_dname_buf(uint8_t* d, size_t dlen, char* s, size_t slen) 38109a3aaf3SDag-Erling Smørgrav { 38209a3aaf3SDag-Erling Smørgrav /* use arguments as temporary variables */ 3830eefd307SCy Schubert return sldns_wire2str_dname_scan(&d, &dlen, &s, &slen, NULL, 0, NULL); 38409a3aaf3SDag-Erling Smørgrav } 38509a3aaf3SDag-Erling Smørgrav 38609a3aaf3SDag-Erling Smørgrav int sldns_str_vprint(char** str, size_t* slen, const char* format, va_list args) 38709a3aaf3SDag-Erling Smørgrav { 38809a3aaf3SDag-Erling Smørgrav int w = vsnprintf(*str, *slen, format, args); 38909a3aaf3SDag-Erling Smørgrav if(w < 0) { 39009a3aaf3SDag-Erling Smørgrav /* error in printout */ 39109a3aaf3SDag-Erling Smørgrav return 0; 39209a3aaf3SDag-Erling Smørgrav } else if((size_t)w >= *slen) { 39309a3aaf3SDag-Erling Smørgrav *str = NULL; /* we do not want str to point outside of buffer*/ 39409a3aaf3SDag-Erling Smørgrav *slen = 0; 39509a3aaf3SDag-Erling Smørgrav } else { 39609a3aaf3SDag-Erling Smørgrav *str += w; 39709a3aaf3SDag-Erling Smørgrav *slen -= w; 39809a3aaf3SDag-Erling Smørgrav } 39909a3aaf3SDag-Erling Smørgrav return w; 40009a3aaf3SDag-Erling Smørgrav } 40109a3aaf3SDag-Erling Smørgrav 40209a3aaf3SDag-Erling Smørgrav int sldns_str_print(char** str, size_t* slen, const char* format, ...) 40309a3aaf3SDag-Erling Smørgrav { 40409a3aaf3SDag-Erling Smørgrav int w; 40509a3aaf3SDag-Erling Smørgrav va_list args; 40609a3aaf3SDag-Erling Smørgrav va_start(args, format); 40709a3aaf3SDag-Erling Smørgrav w = sldns_str_vprint(str, slen, format, args); 40809a3aaf3SDag-Erling Smørgrav va_end(args); 40909a3aaf3SDag-Erling Smørgrav return w; 41009a3aaf3SDag-Erling Smørgrav } 41109a3aaf3SDag-Erling Smørgrav 41209a3aaf3SDag-Erling Smørgrav /** print hex format into text buffer for specified length */ 41309a3aaf3SDag-Erling Smørgrav static int print_hex_buf(char** s, size_t* slen, uint8_t* buf, size_t len) 41409a3aaf3SDag-Erling Smørgrav { 41509a3aaf3SDag-Erling Smørgrav const char* hex = "0123456789ABCDEF"; 41609a3aaf3SDag-Erling Smørgrav size_t i; 41709a3aaf3SDag-Erling Smørgrav for(i=0; i<len; i++) { 41809a3aaf3SDag-Erling Smørgrav (void)sldns_str_print(s, slen, "%c%c", hex[(buf[i]&0xf0)>>4], 41909a3aaf3SDag-Erling Smørgrav hex[buf[i]&0x0f]); 42009a3aaf3SDag-Erling Smørgrav } 42109a3aaf3SDag-Erling Smørgrav return (int)len*2; 42209a3aaf3SDag-Erling Smørgrav } 42309a3aaf3SDag-Erling Smørgrav 42409a3aaf3SDag-Erling Smørgrav /** print remainder of buffer in hex format with prefixed text */ 42509a3aaf3SDag-Erling Smørgrav static int print_remainder_hex(const char* pref, uint8_t** d, size_t* dlen, 42609a3aaf3SDag-Erling Smørgrav char** s, size_t* slen) 42709a3aaf3SDag-Erling Smørgrav { 42809a3aaf3SDag-Erling Smørgrav int w = 0; 42909a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "%s", pref); 43009a3aaf3SDag-Erling Smørgrav w += print_hex_buf(s, slen, *d, *dlen); 43109a3aaf3SDag-Erling Smørgrav *d += *dlen; 43209a3aaf3SDag-Erling Smørgrav *dlen = 0; 43309a3aaf3SDag-Erling Smørgrav return w; 43409a3aaf3SDag-Erling Smørgrav } 43509a3aaf3SDag-Erling Smørgrav 43609a3aaf3SDag-Erling Smørgrav int sldns_wire2str_pkt_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen) 43709a3aaf3SDag-Erling Smørgrav { 4380eefd307SCy Schubert int w = 0, comprloop = 0; 43909a3aaf3SDag-Erling Smørgrav unsigned qdcount, ancount, nscount, arcount, i; 44009a3aaf3SDag-Erling Smørgrav uint8_t* pkt = *d; 44109a3aaf3SDag-Erling Smørgrav size_t pktlen = *dlen; 44209a3aaf3SDag-Erling Smørgrav if(*dlen >= LDNS_HEADER_SIZE) { 44309a3aaf3SDag-Erling Smørgrav qdcount = (unsigned)LDNS_QDCOUNT(*d); 44409a3aaf3SDag-Erling Smørgrav ancount = (unsigned)LDNS_ANCOUNT(*d); 44509a3aaf3SDag-Erling Smørgrav nscount = (unsigned)LDNS_NSCOUNT(*d); 44609a3aaf3SDag-Erling Smørgrav arcount = (unsigned)LDNS_ARCOUNT(*d); 44709a3aaf3SDag-Erling Smørgrav } else { 44809a3aaf3SDag-Erling Smørgrav qdcount = ancount = nscount = arcount = 0; 44909a3aaf3SDag-Erling Smørgrav } 45009a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_header_scan(d, dlen, s, slen); 45109a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\n"); 45209a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, ";; QUESTION SECTION:\n"); 45309a3aaf3SDag-Erling Smørgrav for(i=0; i<qdcount; i++) { 45409a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_rrquestion_scan(d, dlen, s, slen, 4550eefd307SCy Schubert pkt, pktlen, &comprloop); 45609a3aaf3SDag-Erling Smørgrav if(!*dlen) break; 45709a3aaf3SDag-Erling Smørgrav } 45809a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\n"); 45909a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, ";; ANSWER SECTION:\n"); 46009a3aaf3SDag-Erling Smørgrav for(i=0; i<ancount; i++) { 4610eefd307SCy Schubert w += sldns_wire2str_rr_scan(d, dlen, s, slen, pkt, pktlen, &comprloop); 46209a3aaf3SDag-Erling Smørgrav if(!*dlen) break; 46309a3aaf3SDag-Erling Smørgrav } 46409a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\n"); 46509a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, ";; AUTHORITY SECTION:\n"); 46609a3aaf3SDag-Erling Smørgrav for(i=0; i<nscount; i++) { 4670eefd307SCy Schubert w += sldns_wire2str_rr_scan(d, dlen, s, slen, pkt, pktlen, &comprloop); 46809a3aaf3SDag-Erling Smørgrav if(!*dlen) break; 46909a3aaf3SDag-Erling Smørgrav } 47009a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\n"); 47109a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, ";; ADDITIONAL SECTION:\n"); 47209a3aaf3SDag-Erling Smørgrav for(i=0; i<arcount; i++) { 4730eefd307SCy Schubert w += sldns_wire2str_rr_scan(d, dlen, s, slen, pkt, pktlen, &comprloop); 47409a3aaf3SDag-Erling Smørgrav if(!*dlen) break; 47509a3aaf3SDag-Erling Smørgrav } 47609a3aaf3SDag-Erling Smørgrav /* other fields: WHEN(time), SERVER(IP) not available here. */ 47709a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, ";; MSG SIZE rcvd: %d\n", (int)pktlen); 47809a3aaf3SDag-Erling Smørgrav if(*dlen > 0) { 47909a3aaf3SDag-Erling Smørgrav w += print_remainder_hex(";; trailing garbage 0x", 48009a3aaf3SDag-Erling Smørgrav d, dlen, s, slen); 48109a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\n"); 48209a3aaf3SDag-Erling Smørgrav } 48309a3aaf3SDag-Erling Smørgrav return w; 48409a3aaf3SDag-Erling Smørgrav } 48509a3aaf3SDag-Erling Smørgrav 48609a3aaf3SDag-Erling Smørgrav /** scan type, class and ttl and printout, for rr */ 48709a3aaf3SDag-Erling Smørgrav static int sldns_rr_tcttl_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 48809a3aaf3SDag-Erling Smørgrav { 48909a3aaf3SDag-Erling Smørgrav int w = 0; 49009a3aaf3SDag-Erling Smørgrav uint16_t t, c; 49109a3aaf3SDag-Erling Smørgrav uint32_t ttl; 49209a3aaf3SDag-Erling Smørgrav if(*dl < 8) { 49309a3aaf3SDag-Erling Smørgrav if(*dl < 4) 49409a3aaf3SDag-Erling Smørgrav return w + print_remainder_hex("; Error malformed 0x", 49509a3aaf3SDag-Erling Smørgrav d, dl, s, sl); 49609a3aaf3SDag-Erling Smørgrav /* these print values or 0x.. if none left */ 49709a3aaf3SDag-Erling Smørgrav t = sldns_read_uint16(*d); 49809a3aaf3SDag-Erling Smørgrav c = sldns_read_uint16((*d)+2); 49909a3aaf3SDag-Erling Smørgrav (*d)+=4; 50009a3aaf3SDag-Erling Smørgrav (*dl)-=4; 50109a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_class_print(s, sl, c); 50209a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "\t"); 50309a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_type_print(s, sl, t); 50409a3aaf3SDag-Erling Smørgrav if(*dl == 0) 50509a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, sl, "; Error no ttl"); 50609a3aaf3SDag-Erling Smørgrav return w + print_remainder_hex( 50709a3aaf3SDag-Erling Smørgrav "; Error malformed ttl 0x", d, dl, s, sl); 50809a3aaf3SDag-Erling Smørgrav } 50909a3aaf3SDag-Erling Smørgrav t = sldns_read_uint16(*d); 51009a3aaf3SDag-Erling Smørgrav c = sldns_read_uint16((*d)+2); 51109a3aaf3SDag-Erling Smørgrav ttl = sldns_read_uint32((*d)+4); 51209a3aaf3SDag-Erling Smørgrav (*d)+=8; 51309a3aaf3SDag-Erling Smørgrav (*dl)-=8; 51409a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "%lu\t", (unsigned long)ttl); 51509a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_class_print(s, sl, c); 51609a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "\t"); 51709a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_type_print(s, sl, t); 51809a3aaf3SDag-Erling Smørgrav return w; 51909a3aaf3SDag-Erling Smørgrav } 52009a3aaf3SDag-Erling Smørgrav 52109a3aaf3SDag-Erling Smørgrav int sldns_wire2str_rr_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen, 5220eefd307SCy Schubert uint8_t* pkt, size_t pktlen, int* comprloop) 52309a3aaf3SDag-Erling Smørgrav { 52409a3aaf3SDag-Erling Smørgrav int w = 0; 52509a3aaf3SDag-Erling Smørgrav uint8_t* rr = *d; 52609a3aaf3SDag-Erling Smørgrav size_t rrlen = *dlen, dname_off, rdlen, ordlen; 52709a3aaf3SDag-Erling Smørgrav uint16_t rrtype = 0; 52809a3aaf3SDag-Erling Smørgrav 52909a3aaf3SDag-Erling Smørgrav if(*dlen >= 3 && (*d)[0]==0 && 53009a3aaf3SDag-Erling Smørgrav sldns_read_uint16((*d)+1)==LDNS_RR_TYPE_OPT) { 53109a3aaf3SDag-Erling Smørgrav /* perform EDNS OPT processing */ 53209a3aaf3SDag-Erling Smørgrav return sldns_wire2str_edns_scan(d, dlen, s, slen, pkt, pktlen); 53309a3aaf3SDag-Erling Smørgrav } 53409a3aaf3SDag-Erling Smørgrav 53509a3aaf3SDag-Erling Smørgrav /* try to scan the rdata with pretty-printing, but if that fails, then 53609a3aaf3SDag-Erling Smørgrav * scan the rdata as an unknown RR type */ 5370eefd307SCy Schubert w += sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen, comprloop); 53809a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\t"); 53909a3aaf3SDag-Erling Smørgrav dname_off = rrlen-(*dlen); 54009a3aaf3SDag-Erling Smørgrav if(*dlen == 4) { 54109a3aaf3SDag-Erling Smørgrav /* like a question-RR */ 54209a3aaf3SDag-Erling Smørgrav uint16_t t = sldns_read_uint16(*d); 54309a3aaf3SDag-Erling Smørgrav uint16_t c = sldns_read_uint16((*d)+2); 54409a3aaf3SDag-Erling Smørgrav (*d)+=4; 54509a3aaf3SDag-Erling Smørgrav (*dlen)-=4; 54609a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_class_print(s, slen, c); 54709a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\t"); 54809a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_type_print(s, slen, t); 54909a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, " ; Error no ttl,rdata\n"); 55009a3aaf3SDag-Erling Smørgrav return w; 55109a3aaf3SDag-Erling Smørgrav } 55209a3aaf3SDag-Erling Smørgrav if(*dlen < 8) { 55309a3aaf3SDag-Erling Smørgrav if(*dlen == 0) 55409a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, slen, ";Error missing RR\n"); 55509a3aaf3SDag-Erling Smørgrav w += print_remainder_hex(";Error partial RR 0x", d, dlen, s, slen); 55609a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, slen, "\n"); 55709a3aaf3SDag-Erling Smørgrav } 55809a3aaf3SDag-Erling Smørgrav rrtype = sldns_read_uint16(*d); 55909a3aaf3SDag-Erling Smørgrav w += sldns_rr_tcttl_scan(d, dlen, s, slen); 56009a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\t"); 56109a3aaf3SDag-Erling Smørgrav 56209a3aaf3SDag-Erling Smørgrav /* rdata */ 56309a3aaf3SDag-Erling Smørgrav if(*dlen < 2) { 56409a3aaf3SDag-Erling Smørgrav if(*dlen == 0) 56509a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, slen, ";Error missing rdatalen\n"); 56609a3aaf3SDag-Erling Smørgrav w += print_remainder_hex(";Error missing rdatalen 0x", 56709a3aaf3SDag-Erling Smørgrav d, dlen, s, slen); 56809a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, slen, "\n"); 56909a3aaf3SDag-Erling Smørgrav } 57009a3aaf3SDag-Erling Smørgrav rdlen = sldns_read_uint16(*d); 57109a3aaf3SDag-Erling Smørgrav ordlen = rdlen; 57209a3aaf3SDag-Erling Smørgrav (*d)+=2; 57309a3aaf3SDag-Erling Smørgrav (*dlen)-=2; 57409a3aaf3SDag-Erling Smørgrav if(*dlen < rdlen) { 57509a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\\# %u ", (unsigned)rdlen); 57609a3aaf3SDag-Erling Smørgrav if(*dlen == 0) 57709a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, slen, ";Error missing rdata\n"); 57809a3aaf3SDag-Erling Smørgrav w += print_remainder_hex(";Error partial rdata 0x", d, dlen, s, slen); 57909a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, slen, "\n"); 58009a3aaf3SDag-Erling Smørgrav } 5810eefd307SCy Schubert w += sldns_wire2str_rdata_scan(d, &rdlen, s, slen, rrtype, pkt, pktlen, 5820eefd307SCy Schubert comprloop); 58309a3aaf3SDag-Erling Smørgrav (*dlen) -= (ordlen-rdlen); 58409a3aaf3SDag-Erling Smørgrav 58509a3aaf3SDag-Erling Smørgrav /* default comment */ 58609a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_rr_comment_print(s, slen, rr, rrlen, dname_off, 58709a3aaf3SDag-Erling Smørgrav rrtype); 58809a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\n"); 58909a3aaf3SDag-Erling Smørgrav return w; 59009a3aaf3SDag-Erling Smørgrav } 59109a3aaf3SDag-Erling Smørgrav 59209a3aaf3SDag-Erling Smørgrav int sldns_wire2str_rrquestion_scan(uint8_t** d, size_t* dlen, char** s, 5930eefd307SCy Schubert size_t* slen, uint8_t* pkt, size_t pktlen, int* comprloop) 59409a3aaf3SDag-Erling Smørgrav { 59509a3aaf3SDag-Erling Smørgrav int w = 0; 59609a3aaf3SDag-Erling Smørgrav uint16_t t, c; 5970eefd307SCy Schubert w += sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen, comprloop); 59809a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\t"); 59909a3aaf3SDag-Erling Smørgrav if(*dlen < 4) { 60009a3aaf3SDag-Erling Smørgrav if(*dlen == 0) 60109a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, slen, "Error malformed\n"); 60209a3aaf3SDag-Erling Smørgrav w += print_remainder_hex("Error malformed 0x", d, dlen, s, slen); 60309a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, slen, "\n"); 60409a3aaf3SDag-Erling Smørgrav } 60509a3aaf3SDag-Erling Smørgrav t = sldns_read_uint16(*d); 60609a3aaf3SDag-Erling Smørgrav c = sldns_read_uint16((*d)+2); 60709a3aaf3SDag-Erling Smørgrav (*d)+=4; 60809a3aaf3SDag-Erling Smørgrav (*dlen)-=4; 60909a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_class_print(s, slen, c); 61009a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\t"); 61109a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_type_print(s, slen, t); 61209a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\n"); 61309a3aaf3SDag-Erling Smørgrav return w; 61409a3aaf3SDag-Erling Smørgrav } 61509a3aaf3SDag-Erling Smørgrav 61609a3aaf3SDag-Erling Smørgrav int sldns_wire2str_rr_unknown_scan(uint8_t** d, size_t* dlen, char** s, 6170eefd307SCy Schubert size_t* slen, uint8_t* pkt, size_t pktlen, int* comprloop) 61809a3aaf3SDag-Erling Smørgrav { 61909a3aaf3SDag-Erling Smørgrav size_t rdlen, ordlen; 62009a3aaf3SDag-Erling Smørgrav int w = 0; 6210eefd307SCy Schubert w += sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen, comprloop); 62209a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\t"); 62309a3aaf3SDag-Erling Smørgrav w += sldns_rr_tcttl_scan(d, dlen, s, slen); 62409a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\t"); 62509a3aaf3SDag-Erling Smørgrav if(*dlen < 2) { 62609a3aaf3SDag-Erling Smørgrav if(*dlen == 0) 62709a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, slen, ";Error missing rdatalen\n"); 62809a3aaf3SDag-Erling Smørgrav w += print_remainder_hex(";Error missing rdatalen 0x", 62909a3aaf3SDag-Erling Smørgrav d, dlen, s, slen); 63009a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, slen, "\n"); 63109a3aaf3SDag-Erling Smørgrav } 63209a3aaf3SDag-Erling Smørgrav rdlen = sldns_read_uint16(*d); 63309a3aaf3SDag-Erling Smørgrav ordlen = rdlen; 63409a3aaf3SDag-Erling Smørgrav (*d) += 2; 63509a3aaf3SDag-Erling Smørgrav (*dlen) -= 2; 63609a3aaf3SDag-Erling Smørgrav if(*dlen < rdlen) { 63709a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\\# %u ", (unsigned)rdlen); 63809a3aaf3SDag-Erling Smørgrav if(*dlen == 0) 63909a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, slen, ";Error missing rdata\n"); 64009a3aaf3SDag-Erling Smørgrav w += print_remainder_hex(";Error partial rdata 0x", d, dlen, s, slen); 64109a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, slen, "\n"); 64209a3aaf3SDag-Erling Smørgrav } 64309a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_rdata_unknown_scan(d, &rdlen, s, slen); 64409a3aaf3SDag-Erling Smørgrav (*dlen) -= (ordlen-rdlen); 64509a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\n"); 64609a3aaf3SDag-Erling Smørgrav return w; 64709a3aaf3SDag-Erling Smørgrav } 64809a3aaf3SDag-Erling Smørgrav 64909a3aaf3SDag-Erling Smørgrav /** print rr comment for type DNSKEY */ 65009a3aaf3SDag-Erling Smørgrav static int rr_comment_dnskey(char** s, size_t* slen, uint8_t* rr, 65109a3aaf3SDag-Erling Smørgrav size_t rrlen, size_t dname_off) 65209a3aaf3SDag-Erling Smørgrav { 65309a3aaf3SDag-Erling Smørgrav size_t rdlen; 65409a3aaf3SDag-Erling Smørgrav uint8_t* rdata; 65509a3aaf3SDag-Erling Smørgrav int flags, w = 0; 65609a3aaf3SDag-Erling Smørgrav if(rrlen < dname_off + 10) return 0; 65709a3aaf3SDag-Erling Smørgrav rdlen = sldns_read_uint16(rr+dname_off+8); 65809a3aaf3SDag-Erling Smørgrav if(rrlen < dname_off + 10 + rdlen) return 0; 6590eefd307SCy Schubert if(rdlen < 2) return 0; 66009a3aaf3SDag-Erling Smørgrav rdata = rr + dname_off + 10; 66109a3aaf3SDag-Erling Smørgrav flags = (int)sldns_read_uint16(rdata); 66209a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, " ;{"); 66309a3aaf3SDag-Erling Smørgrav 66409a3aaf3SDag-Erling Smørgrav /* id */ 66509a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "id = %u", 66609a3aaf3SDag-Erling Smørgrav sldns_calc_keytag_raw(rdata, rdlen)); 66709a3aaf3SDag-Erling Smørgrav 66809a3aaf3SDag-Erling Smørgrav /* flags */ 66909a3aaf3SDag-Erling Smørgrav if((flags&LDNS_KEY_ZONE_KEY)) { 67009a3aaf3SDag-Erling Smørgrav if((flags&LDNS_KEY_SEP_KEY)) 67109a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, " (ksk)"); 67209a3aaf3SDag-Erling Smørgrav else w += sldns_str_print(s, slen, " (zsk)"); 67309a3aaf3SDag-Erling Smørgrav } 67409a3aaf3SDag-Erling Smørgrav 67509a3aaf3SDag-Erling Smørgrav /* keysize */ 67609a3aaf3SDag-Erling Smørgrav if(rdlen > 4) { 67709a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, ", "); 67809a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "size = %db", 67909a3aaf3SDag-Erling Smørgrav (int)sldns_rr_dnskey_key_size_raw( 68009a3aaf3SDag-Erling Smørgrav (unsigned char*)rdata+4, rdlen-4, (int)(rdata[3]))); 68109a3aaf3SDag-Erling Smørgrav } 68209a3aaf3SDag-Erling Smørgrav 68309a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "}"); 68409a3aaf3SDag-Erling Smørgrav return w; 68509a3aaf3SDag-Erling Smørgrav } 68609a3aaf3SDag-Erling Smørgrav 68709a3aaf3SDag-Erling Smørgrav /** print rr comment for type RRSIG */ 68809a3aaf3SDag-Erling Smørgrav static int rr_comment_rrsig(char** s, size_t* slen, uint8_t* rr, 68909a3aaf3SDag-Erling Smørgrav size_t rrlen, size_t dname_off) 69009a3aaf3SDag-Erling Smørgrav { 69109a3aaf3SDag-Erling Smørgrav size_t rdlen; 69209a3aaf3SDag-Erling Smørgrav uint8_t* rdata; 69309a3aaf3SDag-Erling Smørgrav if(rrlen < dname_off + 10) return 0; 69409a3aaf3SDag-Erling Smørgrav rdlen = sldns_read_uint16(rr+dname_off+8); 69509a3aaf3SDag-Erling Smørgrav if(rrlen < dname_off + 10 + rdlen) return 0; 69609a3aaf3SDag-Erling Smørgrav rdata = rr + dname_off + 10; 69709a3aaf3SDag-Erling Smørgrav if(rdlen < 18) return 0; 69809a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, slen, " ;{id = %d}", 69909a3aaf3SDag-Erling Smørgrav (int)sldns_read_uint16(rdata+16)); 70009a3aaf3SDag-Erling Smørgrav } 70109a3aaf3SDag-Erling Smørgrav 70209a3aaf3SDag-Erling Smørgrav /** print rr comment for type NSEC3 */ 70309a3aaf3SDag-Erling Smørgrav static int rr_comment_nsec3(char** s, size_t* slen, uint8_t* rr, 70409a3aaf3SDag-Erling Smørgrav size_t rrlen, size_t dname_off) 70509a3aaf3SDag-Erling Smørgrav { 70609a3aaf3SDag-Erling Smørgrav size_t rdlen; 70709a3aaf3SDag-Erling Smørgrav uint8_t* rdata; 70809a3aaf3SDag-Erling Smørgrav int w = 0; 70909a3aaf3SDag-Erling Smørgrav if(rrlen < dname_off + 10) return 0; 71009a3aaf3SDag-Erling Smørgrav rdlen = sldns_read_uint16(rr+dname_off+8); 71109a3aaf3SDag-Erling Smørgrav if(rrlen < dname_off + 10 + rdlen) return 0; 71209a3aaf3SDag-Erling Smørgrav rdata = rr + dname_off + 10; 71309a3aaf3SDag-Erling Smørgrav if(rdlen < 2) return 0; 71409a3aaf3SDag-Erling Smørgrav if((rdata[1] & LDNS_NSEC3_VARS_OPTOUT_MASK)) 71509a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, " ;{flags: optout}"); 71609a3aaf3SDag-Erling Smørgrav return w; 71709a3aaf3SDag-Erling Smørgrav } 71809a3aaf3SDag-Erling Smørgrav 71909a3aaf3SDag-Erling Smørgrav int sldns_wire2str_rr_comment_print(char** s, size_t* slen, uint8_t* rr, 72009a3aaf3SDag-Erling Smørgrav size_t rrlen, size_t dname_off, uint16_t rrtype) 72109a3aaf3SDag-Erling Smørgrav { 72209a3aaf3SDag-Erling Smørgrav if(rrtype == LDNS_RR_TYPE_DNSKEY) { 72309a3aaf3SDag-Erling Smørgrav return rr_comment_dnskey(s, slen, rr, rrlen, dname_off); 72409a3aaf3SDag-Erling Smørgrav } else if(rrtype == LDNS_RR_TYPE_RRSIG) { 72509a3aaf3SDag-Erling Smørgrav return rr_comment_rrsig(s, slen, rr, rrlen, dname_off); 72609a3aaf3SDag-Erling Smørgrav } else if(rrtype == LDNS_RR_TYPE_NSEC3) { 72709a3aaf3SDag-Erling Smørgrav return rr_comment_nsec3(s, slen, rr, rrlen, dname_off); 72809a3aaf3SDag-Erling Smørgrav } 72909a3aaf3SDag-Erling Smørgrav return 0; 73009a3aaf3SDag-Erling Smørgrav } 73109a3aaf3SDag-Erling Smørgrav 73209a3aaf3SDag-Erling Smørgrav int sldns_wire2str_header_scan(uint8_t** d, size_t* dlen, char** s, 73309a3aaf3SDag-Erling Smørgrav size_t* slen) 73409a3aaf3SDag-Erling Smørgrav { 73509a3aaf3SDag-Erling Smørgrav int w = 0; 73609a3aaf3SDag-Erling Smørgrav int opcode, rcode; 73709a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, ";; ->>HEADER<<- "); 73809a3aaf3SDag-Erling Smørgrav if(*dlen == 0) 73909a3aaf3SDag-Erling Smørgrav return w+sldns_str_print(s, slen, "Error empty packet"); 74009a3aaf3SDag-Erling Smørgrav if(*dlen < 4) 74109a3aaf3SDag-Erling Smørgrav return w+print_remainder_hex("Error header too short 0x", d, dlen, s, slen); 74209a3aaf3SDag-Erling Smørgrav opcode = (int)LDNS_OPCODE_WIRE(*d); 74309a3aaf3SDag-Erling Smørgrav rcode = (int)LDNS_RCODE_WIRE(*d); 74409a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "opcode: "); 74509a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_opcode_print(s, slen, opcode); 74609a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, ", "); 74709a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "rcode: "); 74809a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_rcode_print(s, slen, rcode); 74909a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, ", "); 75009a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "id: %d\n", (int)LDNS_ID_WIRE(*d)); 75109a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, ";; flags:"); 75209a3aaf3SDag-Erling Smørgrav if(LDNS_QR_WIRE(*d)) w += sldns_str_print(s, slen, " qr"); 75309a3aaf3SDag-Erling Smørgrav if(LDNS_AA_WIRE(*d)) w += sldns_str_print(s, slen, " aa"); 75409a3aaf3SDag-Erling Smørgrav if(LDNS_TC_WIRE(*d)) w += sldns_str_print(s, slen, " tc"); 75509a3aaf3SDag-Erling Smørgrav if(LDNS_RD_WIRE(*d)) w += sldns_str_print(s, slen, " rd"); 75609a3aaf3SDag-Erling Smørgrav if(LDNS_CD_WIRE(*d)) w += sldns_str_print(s, slen, " cd"); 75709a3aaf3SDag-Erling Smørgrav if(LDNS_RA_WIRE(*d)) w += sldns_str_print(s, slen, " ra"); 75809a3aaf3SDag-Erling Smørgrav if(LDNS_AD_WIRE(*d)) w += sldns_str_print(s, slen, " ad"); 75909a3aaf3SDag-Erling Smørgrav if(LDNS_Z_WIRE(*d)) w += sldns_str_print(s, slen, " z"); 76009a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, " ; "); 76109a3aaf3SDag-Erling Smørgrav if(*dlen < LDNS_HEADER_SIZE) 76209a3aaf3SDag-Erling Smørgrav return w+print_remainder_hex("Error header too short 0x", d, dlen, s, slen); 76309a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "QUERY: %d, ", (int)LDNS_QDCOUNT(*d)); 76409a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "ANSWER: %d, ", (int)LDNS_ANCOUNT(*d)); 76509a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "AUTHORITY: %d, ", (int)LDNS_NSCOUNT(*d)); 76609a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "ADDITIONAL: %d ", (int)LDNS_ARCOUNT(*d)); 76709a3aaf3SDag-Erling Smørgrav *d += LDNS_HEADER_SIZE; 76809a3aaf3SDag-Erling Smørgrav *dlen -= LDNS_HEADER_SIZE; 76909a3aaf3SDag-Erling Smørgrav return w; 77009a3aaf3SDag-Erling Smørgrav } 77109a3aaf3SDag-Erling Smørgrav 77209a3aaf3SDag-Erling Smørgrav int sldns_wire2str_rdata_scan(uint8_t** d, size_t* dlen, char** s, 7730eefd307SCy Schubert size_t* slen, uint16_t rrtype, uint8_t* pkt, size_t pktlen, 7740eefd307SCy Schubert int* comprloop) 77509a3aaf3SDag-Erling Smørgrav { 77609a3aaf3SDag-Erling Smørgrav /* try to prettyprint, but if that fails, use unknown format */ 77709a3aaf3SDag-Erling Smørgrav uint8_t* origd = *d; 77809a3aaf3SDag-Erling Smørgrav char* origs = *s; 77909a3aaf3SDag-Erling Smørgrav size_t origdlen = *dlen, origslen = *slen; 780bc892140SDag-Erling Smørgrav size_t r_cnt, r_max; 78109a3aaf3SDag-Erling Smørgrav sldns_rdf_type rdftype; 78209a3aaf3SDag-Erling Smørgrav int w = 0, n; 78309a3aaf3SDag-Erling Smørgrav 78409a3aaf3SDag-Erling Smørgrav const sldns_rr_descriptor *desc = sldns_rr_descript(rrtype); 78509a3aaf3SDag-Erling Smørgrav if(!desc) /* unknown format */ 78609a3aaf3SDag-Erling Smørgrav return sldns_wire2str_rdata_unknown_scan(d, dlen, s, slen); 78709a3aaf3SDag-Erling Smørgrav /* dlen equals the rdatalen for the rdata */ 78809a3aaf3SDag-Erling Smørgrav 78909a3aaf3SDag-Erling Smørgrav r_max = sldns_rr_descriptor_maximum(desc); 79009a3aaf3SDag-Erling Smørgrav for(r_cnt=0; r_cnt < r_max; r_cnt++) { 79109a3aaf3SDag-Erling Smørgrav if(*dlen == 0) { 79209a3aaf3SDag-Erling Smørgrav if(r_cnt < sldns_rr_descriptor_minimum(desc)) 79309a3aaf3SDag-Erling Smørgrav goto failed; 79409a3aaf3SDag-Erling Smørgrav break; /* nothing more to print */ 79509a3aaf3SDag-Erling Smørgrav } 79609a3aaf3SDag-Erling Smørgrav rdftype = sldns_rr_descriptor_field_type(desc, r_cnt); 79709a3aaf3SDag-Erling Smørgrav if(r_cnt != 0) 79809a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, " "); 79909a3aaf3SDag-Erling Smørgrav n = sldns_wire2str_rdf_scan(d, dlen, s, slen, rdftype, 8000eefd307SCy Schubert pkt, pktlen, comprloop); 80109a3aaf3SDag-Erling Smørgrav if(n == -1) { 80209a3aaf3SDag-Erling Smørgrav failed: 80309a3aaf3SDag-Erling Smørgrav /* failed, use unknown format */ 80409a3aaf3SDag-Erling Smørgrav *d = origd; *s = origs; 80509a3aaf3SDag-Erling Smørgrav *dlen = origdlen; *slen = origslen; 80609a3aaf3SDag-Erling Smørgrav return sldns_wire2str_rdata_unknown_scan(d, dlen, 80709a3aaf3SDag-Erling Smørgrav s, slen); 80809a3aaf3SDag-Erling Smørgrav } 80909a3aaf3SDag-Erling Smørgrav w += n; 81009a3aaf3SDag-Erling Smørgrav } 81105ab2901SDag-Erling Smørgrav if(*dlen != 0) { 81205ab2901SDag-Erling Smørgrav goto failed; 81305ab2901SDag-Erling Smørgrav } 81409a3aaf3SDag-Erling Smørgrav return w; 81509a3aaf3SDag-Erling Smørgrav } 81609a3aaf3SDag-Erling Smørgrav 81709a3aaf3SDag-Erling Smørgrav int sldns_wire2str_rdata_unknown_scan(uint8_t** d, size_t* dlen, char** s, 81809a3aaf3SDag-Erling Smørgrav size_t* slen) 81909a3aaf3SDag-Erling Smørgrav { 82009a3aaf3SDag-Erling Smørgrav int w = 0; 82109a3aaf3SDag-Erling Smørgrav 82209a3aaf3SDag-Erling Smørgrav /* print length */ 82309a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "\\# %u", (unsigned)*dlen); 82409a3aaf3SDag-Erling Smørgrav 82509a3aaf3SDag-Erling Smørgrav /* print rdlen in hex */ 82609a3aaf3SDag-Erling Smørgrav if(*dlen != 0) 82709a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, " "); 82809a3aaf3SDag-Erling Smørgrav w += print_hex_buf(s, slen, *d, *dlen); 82909a3aaf3SDag-Erling Smørgrav (*d) += *dlen; 83009a3aaf3SDag-Erling Smørgrav (*dlen) = 0; 83109a3aaf3SDag-Erling Smørgrav return w; 83209a3aaf3SDag-Erling Smørgrav } 83309a3aaf3SDag-Erling Smørgrav 83409a3aaf3SDag-Erling Smørgrav /** print and escape one character for a domain dname */ 83509a3aaf3SDag-Erling Smørgrav static int dname_char_print(char** s, size_t* slen, uint8_t c) 83609a3aaf3SDag-Erling Smørgrav { 83709a3aaf3SDag-Erling Smørgrav if(c == '.' || c == ';' || c == '(' || c == ')' || c == '\\') 83809a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, slen, "\\%c", c); 83909a3aaf3SDag-Erling Smørgrav else if(!(isascii((unsigned char)c) && isgraph((unsigned char)c))) 84009a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, slen, "\\%03u", (unsigned)c); 84109a3aaf3SDag-Erling Smørgrav /* plain printout */ 84209a3aaf3SDag-Erling Smørgrav if(*slen) { 84309a3aaf3SDag-Erling Smørgrav **s = (char)c; 84409a3aaf3SDag-Erling Smørgrav (*s)++; 84509a3aaf3SDag-Erling Smørgrav (*slen)--; 84609a3aaf3SDag-Erling Smørgrav } 84709a3aaf3SDag-Erling Smørgrav return 1; 84809a3aaf3SDag-Erling Smørgrav } 84909a3aaf3SDag-Erling Smørgrav 85009a3aaf3SDag-Erling Smørgrav int sldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen, 8510eefd307SCy Schubert uint8_t* pkt, size_t pktlen, int* comprloop) 85209a3aaf3SDag-Erling Smørgrav { 85309a3aaf3SDag-Erling Smørgrav int w = 0; 85409a3aaf3SDag-Erling Smørgrav /* spool labels onto the string, use compression if its there */ 85509a3aaf3SDag-Erling Smørgrav uint8_t* pos = *d; 85609a3aaf3SDag-Erling Smørgrav unsigned i, counter=0; 8570eefd307SCy Schubert unsigned maxcompr = MAX_COMPRESS_PTRS; /* loop detection, max compr ptrs */ 85809a3aaf3SDag-Erling Smørgrav int in_buf = 1; 8599cf5bc93SCy Schubert size_t dname_len = 0; 8600eefd307SCy Schubert if(comprloop) { 8610eefd307SCy Schubert if(*comprloop != 0) 8620eefd307SCy Schubert maxcompr = 30; /* for like ipv6 reverse name, per label */ 8630eefd307SCy Schubert if(*comprloop > 4) 8640eefd307SCy Schubert maxcompr = 4; /* just don't want to spend time, any more */ 8650eefd307SCy Schubert } 86609a3aaf3SDag-Erling Smørgrav if(*dlen == 0) return sldns_str_print(s, slen, "ErrorMissingDname"); 86709a3aaf3SDag-Erling Smørgrav if(*pos == 0) { 86809a3aaf3SDag-Erling Smørgrav (*d)++; 86909a3aaf3SDag-Erling Smørgrav (*dlen)--; 87009a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, slen, "."); 87109a3aaf3SDag-Erling Smørgrav } 8720eefd307SCy Schubert while((!pkt || pos < pkt+pktlen) && *pos) { 87309a3aaf3SDag-Erling Smørgrav /* read label length */ 87409a3aaf3SDag-Erling Smørgrav uint8_t labellen = *pos++; 87509a3aaf3SDag-Erling Smørgrav if(in_buf) { (*d)++; (*dlen)--; } 87609a3aaf3SDag-Erling Smørgrav 87709a3aaf3SDag-Erling Smørgrav /* find out what sort of label we have */ 87809a3aaf3SDag-Erling Smørgrav if((labellen&0xc0) == 0xc0) { 87909a3aaf3SDag-Erling Smørgrav /* compressed */ 88009a3aaf3SDag-Erling Smørgrav uint16_t target = 0; 88109a3aaf3SDag-Erling Smørgrav if(in_buf && *dlen == 0) 88209a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, slen, 88309a3aaf3SDag-Erling Smørgrav "ErrorPartialDname"); 88409a3aaf3SDag-Erling Smørgrav else if(!in_buf && pos+1 > pkt+pktlen) 88509a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, slen, 88609a3aaf3SDag-Erling Smørgrav "ErrorPartialDname"); 88709a3aaf3SDag-Erling Smørgrav target = ((labellen&0x3f)<<8) | *pos; 88809a3aaf3SDag-Erling Smørgrav if(in_buf) { (*d)++; (*dlen)--; } 88909a3aaf3SDag-Erling Smørgrav /* move to target, if possible */ 89009a3aaf3SDag-Erling Smørgrav if(!pkt || target >= pktlen) 89109a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, slen, 89209a3aaf3SDag-Erling Smørgrav "ErrorComprPtrOutOfBounds"); 8930eefd307SCy Schubert if(counter++ > maxcompr) { 8940eefd307SCy Schubert if(comprloop && *comprloop < 10) 8950eefd307SCy Schubert (*comprloop)++; 89609a3aaf3SDag-Erling Smørgrav return w + sldns_str_print(s, slen, 89709a3aaf3SDag-Erling Smørgrav "ErrorComprPtrLooped"); 8980eefd307SCy Schubert } 89909a3aaf3SDag-Erling Smørgrav in_buf = 0; 90009a3aaf3SDag-Erling Smørgrav pos = pkt+target; 90109a3aaf3SDag-Erling Smørgrav continue; 90209a3aaf3SDag-Erling Smørgrav } else if((labellen&0xc0)) { 90309a3aaf3SDag-Erling Smørgrav /* notimpl label type */ 90409a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, 90509a3aaf3SDag-Erling Smørgrav "ErrorLABELTYPE%xIsUnknown", 90609a3aaf3SDag-Erling Smørgrav (int)(labellen&0xc0)); 90709a3aaf3SDag-Erling Smørgrav return w; 90809a3aaf3SDag-Erling Smørgrav } 90909a3aaf3SDag-Erling Smørgrav 91009a3aaf3SDag-Erling Smørgrav /* spool label characters, end with '.' */ 911bc892140SDag-Erling Smørgrav if(in_buf && *dlen < (size_t)labellen) 912bc892140SDag-Erling Smørgrav labellen = (uint8_t)*dlen; 913bc892140SDag-Erling Smørgrav else if(!in_buf && pos+(size_t)labellen > pkt+pktlen) 91409a3aaf3SDag-Erling Smørgrav labellen = (uint8_t)(pkt + pktlen - pos); 9159cf5bc93SCy Schubert dname_len += ((size_t)labellen)+1; 9169cf5bc93SCy Schubert if(dname_len > LDNS_MAX_DOMAINLEN) { 9179cf5bc93SCy Schubert /* dname_len counts the uncompressed length we have 9189cf5bc93SCy Schubert * seen so far, and the domain name has become too 9199cf5bc93SCy Schubert * long, prevent the loop from printing overly long 9209cf5bc93SCy Schubert * content. */ 9219cf5bc93SCy Schubert w += sldns_str_print(s, slen, 9229cf5bc93SCy Schubert "ErrorDomainNameTooLong"); 9239cf5bc93SCy Schubert return w; 9249cf5bc93SCy Schubert } 92509a3aaf3SDag-Erling Smørgrav for(i=0; i<(unsigned)labellen; i++) { 92609a3aaf3SDag-Erling Smørgrav w += dname_char_print(s, slen, *pos++); 92709a3aaf3SDag-Erling Smørgrav } 92809a3aaf3SDag-Erling Smørgrav if(in_buf) { 92909a3aaf3SDag-Erling Smørgrav (*d) += labellen; 93009a3aaf3SDag-Erling Smørgrav (*dlen) -= labellen; 93109a3aaf3SDag-Erling Smørgrav if(*dlen == 0) break; 93209a3aaf3SDag-Erling Smørgrav } 93309a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, slen, "."); 93409a3aaf3SDag-Erling Smørgrav } 93509a3aaf3SDag-Erling Smørgrav /* skip over final root label */ 93609a3aaf3SDag-Erling Smørgrav if(in_buf && *dlen > 0) { (*d)++; (*dlen)--; } 93709a3aaf3SDag-Erling Smørgrav /* in case we printed no labels, terminate dname */ 93809a3aaf3SDag-Erling Smørgrav if(w == 0) w += sldns_str_print(s, slen, "."); 93909a3aaf3SDag-Erling Smørgrav return w; 94009a3aaf3SDag-Erling Smørgrav } 94109a3aaf3SDag-Erling Smørgrav 94209a3aaf3SDag-Erling Smørgrav int sldns_wire2str_opcode_print(char** s, size_t* slen, int opcode) 94309a3aaf3SDag-Erling Smørgrav { 94409a3aaf3SDag-Erling Smørgrav sldns_lookup_table *lt = sldns_lookup_by_id(sldns_opcodes, opcode); 94509a3aaf3SDag-Erling Smørgrav if (lt && lt->name) { 94609a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, slen, "%s", lt->name); 94709a3aaf3SDag-Erling Smørgrav } 94809a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, slen, "OPCODE%u", (unsigned)opcode); 94909a3aaf3SDag-Erling Smørgrav } 95009a3aaf3SDag-Erling Smørgrav 95109a3aaf3SDag-Erling Smørgrav int sldns_wire2str_rcode_print(char** s, size_t* slen, int rcode) 95209a3aaf3SDag-Erling Smørgrav { 95309a3aaf3SDag-Erling Smørgrav sldns_lookup_table *lt = sldns_lookup_by_id(sldns_rcodes, rcode); 95409a3aaf3SDag-Erling Smørgrav if (lt && lt->name) { 95509a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, slen, "%s", lt->name); 95609a3aaf3SDag-Erling Smørgrav } 95709a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, slen, "RCODE%u", (unsigned)rcode); 95809a3aaf3SDag-Erling Smørgrav } 95909a3aaf3SDag-Erling Smørgrav 96009a3aaf3SDag-Erling Smørgrav int sldns_wire2str_class_print(char** s, size_t* slen, uint16_t rrclass) 96109a3aaf3SDag-Erling Smørgrav { 96209a3aaf3SDag-Erling Smørgrav sldns_lookup_table *lt = sldns_lookup_by_id(sldns_rr_classes, 96309a3aaf3SDag-Erling Smørgrav (int)rrclass); 96409a3aaf3SDag-Erling Smørgrav if (lt && lt->name) { 96509a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, slen, "%s", lt->name); 96609a3aaf3SDag-Erling Smørgrav } 96709a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, slen, "CLASS%u", (unsigned)rrclass); 96809a3aaf3SDag-Erling Smørgrav } 96909a3aaf3SDag-Erling Smørgrav 97009a3aaf3SDag-Erling Smørgrav int sldns_wire2str_type_print(char** s, size_t* slen, uint16_t rrtype) 97109a3aaf3SDag-Erling Smørgrav { 97209a3aaf3SDag-Erling Smørgrav const sldns_rr_descriptor *descriptor = sldns_rr_descript(rrtype); 97309a3aaf3SDag-Erling Smørgrav if (descriptor && descriptor->_name) { 97409a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, slen, "%s", descriptor->_name); 97509a3aaf3SDag-Erling Smørgrav } 97609a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, slen, "TYPE%u", (unsigned)rrtype); 97709a3aaf3SDag-Erling Smørgrav } 97809a3aaf3SDag-Erling Smørgrav 97909a3aaf3SDag-Erling Smørgrav int sldns_wire2str_edns_option_code_print(char** s, size_t* slen, 98009a3aaf3SDag-Erling Smørgrav uint16_t opcode) 98109a3aaf3SDag-Erling Smørgrav { 98209a3aaf3SDag-Erling Smørgrav sldns_lookup_table *lt = sldns_lookup_by_id(sldns_edns_options, 98309a3aaf3SDag-Erling Smørgrav (int)opcode); 98409a3aaf3SDag-Erling Smørgrav if (lt && lt->name) { 98509a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, slen, "%s", lt->name); 98609a3aaf3SDag-Erling Smørgrav } 98709a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, slen, "OPT%u", (unsigned)opcode); 98809a3aaf3SDag-Erling Smørgrav } 98909a3aaf3SDag-Erling Smørgrav 99009a3aaf3SDag-Erling Smørgrav int sldns_wire2str_class_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen) 99109a3aaf3SDag-Erling Smørgrav { 99209a3aaf3SDag-Erling Smørgrav uint16_t c; 99309a3aaf3SDag-Erling Smørgrav if(*dlen == 0) return 0; 99409a3aaf3SDag-Erling Smørgrav if(*dlen < 2) return print_remainder_hex("Error malformed 0x", d, dlen, s, slen); 99509a3aaf3SDag-Erling Smørgrav c = sldns_read_uint16(*d); 99609a3aaf3SDag-Erling Smørgrav (*d)+=2; 99709a3aaf3SDag-Erling Smørgrav (*dlen)-=2; 99809a3aaf3SDag-Erling Smørgrav return sldns_wire2str_class_print(s, slen, c); 99909a3aaf3SDag-Erling Smørgrav } 100009a3aaf3SDag-Erling Smørgrav 100109a3aaf3SDag-Erling Smørgrav int sldns_wire2str_type_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen) 100209a3aaf3SDag-Erling Smørgrav { 100309a3aaf3SDag-Erling Smørgrav uint16_t t; 100409a3aaf3SDag-Erling Smørgrav if(*dlen == 0) return 0; 100509a3aaf3SDag-Erling Smørgrav if(*dlen < 2) return print_remainder_hex("Error malformed 0x", d, dlen, s, slen); 100609a3aaf3SDag-Erling Smørgrav t = sldns_read_uint16(*d); 100709a3aaf3SDag-Erling Smørgrav (*d)+=2; 100809a3aaf3SDag-Erling Smørgrav (*dlen)-=2; 100909a3aaf3SDag-Erling Smørgrav return sldns_wire2str_type_print(s, slen, t); 101009a3aaf3SDag-Erling Smørgrav } 101109a3aaf3SDag-Erling Smørgrav 101209a3aaf3SDag-Erling Smørgrav int sldns_wire2str_ttl_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen) 101309a3aaf3SDag-Erling Smørgrav { 101409a3aaf3SDag-Erling Smørgrav uint32_t ttl; 101509a3aaf3SDag-Erling Smørgrav if(*dlen == 0) return 0; 101609a3aaf3SDag-Erling Smørgrav if(*dlen < 4) return print_remainder_hex("Error malformed 0x", d, dlen, s, slen); 101709a3aaf3SDag-Erling Smørgrav ttl = sldns_read_uint32(*d); 101809a3aaf3SDag-Erling Smørgrav (*d)+=4; 101909a3aaf3SDag-Erling Smørgrav (*dlen)-=4; 102009a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, slen, "%u", (unsigned)ttl); 102109a3aaf3SDag-Erling Smørgrav } 102209a3aaf3SDag-Erling Smørgrav 10235469a995SCy Schubert static int 10245469a995SCy Schubert sldns_print_svcparamkey(char** s, size_t* slen, uint16_t svcparamkey) 10255469a995SCy Schubert { 10265469a995SCy Schubert if (svcparamkey < SVCPARAMKEY_COUNT) { 10275469a995SCy Schubert return sldns_str_print(s, slen, "%s", svcparamkey_strs[svcparamkey]); 10285469a995SCy Schubert } 10295469a995SCy Schubert else { 10305469a995SCy Schubert return sldns_str_print(s, slen, "key%d", (int)svcparamkey); 10315469a995SCy Schubert } 10325469a995SCy Schubert } 10335469a995SCy Schubert 10345469a995SCy Schubert static int sldns_wire2str_svcparam_port2str(char** s, 10355469a995SCy Schubert size_t* slen, uint16_t data_len, uint8_t* data) 10365469a995SCy Schubert { 10375469a995SCy Schubert int w = 0; 10385469a995SCy Schubert 10395469a995SCy Schubert if (data_len != 2) 10405469a995SCy Schubert return -1; /* wireformat error, a short is 2 bytes */ 10415469a995SCy Schubert w = sldns_str_print(s, slen, "=%d", (int)sldns_read_uint16(data)); 10425469a995SCy Schubert 10435469a995SCy Schubert return w; 10445469a995SCy Schubert } 10455469a995SCy Schubert 10465469a995SCy Schubert static int sldns_wire2str_svcparam_ipv4hint2str(char** s, 10475469a995SCy Schubert size_t* slen, uint16_t data_len, uint8_t* data) 10485469a995SCy Schubert { 10495469a995SCy Schubert char ip_str[INET_ADDRSTRLEN + 1]; 10505469a995SCy Schubert 10515469a995SCy Schubert int w = 0; 10525469a995SCy Schubert 10535469a995SCy Schubert assert(data_len > 0); 10545469a995SCy Schubert 10555469a995SCy Schubert if ((data_len % LDNS_IP4ADDRLEN) == 0) { 10565469a995SCy Schubert if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL) 10575469a995SCy Schubert return -1; /* wireformat error, incorrect size or inet family */ 10585469a995SCy Schubert 10595469a995SCy Schubert w += sldns_str_print(s, slen, "=%s", ip_str); 10605469a995SCy Schubert data += LDNS_IP4ADDRLEN; 10615469a995SCy Schubert 10625469a995SCy Schubert while ((data_len -= LDNS_IP4ADDRLEN) > 0) { 10635469a995SCy Schubert if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL) 10645469a995SCy Schubert return -1; /* wireformat error, incorrect size or inet family */ 10655469a995SCy Schubert 10665469a995SCy Schubert w += sldns_str_print(s, slen, ",%s", ip_str); 10675469a995SCy Schubert data += LDNS_IP4ADDRLEN; 10685469a995SCy Schubert } 10695469a995SCy Schubert } else 10705469a995SCy Schubert return -1; 10715469a995SCy Schubert 10725469a995SCy Schubert return w; 10735469a995SCy Schubert } 10745469a995SCy Schubert 10755469a995SCy Schubert static int sldns_wire2str_svcparam_ipv6hint2str(char** s, 10765469a995SCy Schubert size_t* slen, uint16_t data_len, uint8_t* data) 10775469a995SCy Schubert { 10785469a995SCy Schubert char ip_str[INET6_ADDRSTRLEN + 1]; 10795469a995SCy Schubert 10805469a995SCy Schubert int w = 0; 10815469a995SCy Schubert 10825469a995SCy Schubert assert(data_len > 0); 10835469a995SCy Schubert 10845469a995SCy Schubert if ((data_len % LDNS_IP6ADDRLEN) == 0) { 10855469a995SCy Schubert if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL) 10865469a995SCy Schubert return -1; /* wireformat error, incorrect size or inet family */ 10875469a995SCy Schubert 10885469a995SCy Schubert w += sldns_str_print(s, slen, "=%s", ip_str); 10895469a995SCy Schubert data += LDNS_IP6ADDRLEN; 10905469a995SCy Schubert 10915469a995SCy Schubert while ((data_len -= LDNS_IP6ADDRLEN) > 0) { 10925469a995SCy Schubert if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL) 10935469a995SCy Schubert return -1; /* wireformat error, incorrect size or inet family */ 10945469a995SCy Schubert 10955469a995SCy Schubert w += sldns_str_print(s, slen, ",%s", ip_str); 10965469a995SCy Schubert data += LDNS_IP6ADDRLEN; 10975469a995SCy Schubert } 10985469a995SCy Schubert } else 10995469a995SCy Schubert return -1; 11005469a995SCy Schubert 11015469a995SCy Schubert return w; 11025469a995SCy Schubert } 11035469a995SCy Schubert 11045469a995SCy Schubert static int sldns_wire2str_svcparam_mandatory2str(char** s, 11055469a995SCy Schubert size_t* slen, uint16_t data_len, uint8_t* data) 11065469a995SCy Schubert { 11075469a995SCy Schubert int w = 0; 11085469a995SCy Schubert 11095469a995SCy Schubert assert(data_len > 0); 11105469a995SCy Schubert 11115469a995SCy Schubert if (data_len % sizeof(uint16_t)) 1112790c6b24SCy Schubert return -1; /* wireformat error, data_len must be multiple of shorts */ 11135469a995SCy Schubert w += sldns_str_print(s, slen, "="); 11145469a995SCy Schubert w += sldns_print_svcparamkey(s, slen, sldns_read_uint16(data)); 11155469a995SCy Schubert data += 2; 11165469a995SCy Schubert 11175469a995SCy Schubert while ((data_len -= sizeof(uint16_t))) { 11185469a995SCy Schubert w += sldns_str_print(s, slen, ","); 11195469a995SCy Schubert w += sldns_print_svcparamkey(s, slen, sldns_read_uint16(data)); 11205469a995SCy Schubert data += 2; 11215469a995SCy Schubert } 11225469a995SCy Schubert 11235469a995SCy Schubert return w; 11245469a995SCy Schubert } 11255469a995SCy Schubert 11265469a995SCy Schubert static int sldns_wire2str_svcparam_alpn2str(char** s, 11275469a995SCy Schubert size_t* slen, uint16_t data_len, uint8_t* data) 11285469a995SCy Schubert { 11295469a995SCy Schubert uint8_t *dp = (void *)data; 11305469a995SCy Schubert int w = 0; 11315469a995SCy Schubert 11325469a995SCy Schubert assert(data_len > 0); /* Guaranteed by sldns_wire2str_svcparam_scan */ 11335469a995SCy Schubert 11345469a995SCy Schubert w += sldns_str_print(s, slen, "=\""); 11355469a995SCy Schubert while (data_len) { 11365469a995SCy Schubert /* alpn is list of length byte (str_len) followed by a string of that size */ 11375469a995SCy Schubert uint8_t i, str_len = *dp++; 11385469a995SCy Schubert 11395469a995SCy Schubert if (str_len > --data_len) 11405469a995SCy Schubert return -1; 11415469a995SCy Schubert 11425469a995SCy Schubert for (i = 0; i < str_len; i++) { 11435469a995SCy Schubert if (dp[i] == '"' || dp[i] == '\\') 11445469a995SCy Schubert w += sldns_str_print(s, slen, "\\\\\\%c", dp[i]); 11455469a995SCy Schubert 11465469a995SCy Schubert else if (dp[i] == ',') 11475469a995SCy Schubert w += sldns_str_print(s, slen, "\\\\%c", dp[i]); 11485469a995SCy Schubert 11495469a995SCy Schubert else if (!isprint(dp[i])) 11505469a995SCy Schubert w += sldns_str_print(s, slen, "\\%03u", (unsigned) dp[i]); 11515469a995SCy Schubert 11525469a995SCy Schubert else 11535469a995SCy Schubert w += sldns_str_print(s, slen, "%c", dp[i]); 11545469a995SCy Schubert } 11555469a995SCy Schubert dp += str_len; 11565469a995SCy Schubert if ((data_len -= str_len)) 11575469a995SCy Schubert w += sldns_str_print(s, slen, "%s", ","); 11585469a995SCy Schubert } 11595469a995SCy Schubert w += sldns_str_print(s, slen, "\""); 11605469a995SCy Schubert 11615469a995SCy Schubert return w; 11625469a995SCy Schubert } 11635469a995SCy Schubert 11645469a995SCy Schubert static int sldns_wire2str_svcparam_ech2str(char** s, 11655469a995SCy Schubert size_t* slen, uint16_t data_len, uint8_t* data) 11665469a995SCy Schubert { 11675469a995SCy Schubert int size; 11685469a995SCy Schubert int w = 0; 11695469a995SCy Schubert 11705469a995SCy Schubert assert(data_len > 0); /* Guaranteed by sldns_wire2str_svcparam_scan */ 11715469a995SCy Schubert 11725469a995SCy Schubert w += sldns_str_print(s, slen, "=\""); 11735469a995SCy Schubert 11745469a995SCy Schubert if ((size = sldns_b64_ntop(data, data_len, *s, *slen)) < 0) 11755469a995SCy Schubert return -1; 11765469a995SCy Schubert 11775469a995SCy Schubert (*s) += size; 11785469a995SCy Schubert (*slen) -= size; 11795469a995SCy Schubert 11805469a995SCy Schubert w += sldns_str_print(s, slen, "\""); 11815469a995SCy Schubert 11825469a995SCy Schubert return w + size; 11835469a995SCy Schubert } 11845469a995SCy Schubert 11855469a995SCy Schubert int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen) 11865469a995SCy Schubert { 11875469a995SCy Schubert uint8_t ch; 11885469a995SCy Schubert uint16_t svcparamkey, data_len; 11895469a995SCy Schubert int written_chars = 0; 11905469a995SCy Schubert int r, i; 11915469a995SCy Schubert 11925469a995SCy Schubert /* verify that we have enough data to read svcparamkey and data_len */ 11935469a995SCy Schubert if(*dlen < 4) 11945469a995SCy Schubert return -1; 11955469a995SCy Schubert 11965469a995SCy Schubert svcparamkey = sldns_read_uint16(*d); 11975469a995SCy Schubert data_len = sldns_read_uint16(*d+2); 11985469a995SCy Schubert *d += 4; 11995469a995SCy Schubert *dlen -= 4; 12005469a995SCy Schubert 12015469a995SCy Schubert /* verify that we have data_len data */ 12025469a995SCy Schubert if (data_len > *dlen) 12035469a995SCy Schubert return -1; 12045469a995SCy Schubert 12055469a995SCy Schubert written_chars += sldns_print_svcparamkey(s, slen, svcparamkey); 12065469a995SCy Schubert if (!data_len) { 12075469a995SCy Schubert 12085469a995SCy Schubert /* Some SvcParams MUST have values */ 12095469a995SCy Schubert switch (svcparamkey) { 12105469a995SCy Schubert case SVCB_KEY_ALPN: 12115469a995SCy Schubert case SVCB_KEY_PORT: 12125469a995SCy Schubert case SVCB_KEY_IPV4HINT: 12135469a995SCy Schubert case SVCB_KEY_IPV6HINT: 12145469a995SCy Schubert case SVCB_KEY_MANDATORY: 12158f76bb7dSCy Schubert case SVCB_KEY_DOHPATH: 12165469a995SCy Schubert return -1; 12175469a995SCy Schubert default: 12185469a995SCy Schubert return written_chars; 12195469a995SCy Schubert } 12205469a995SCy Schubert } 12215469a995SCy Schubert 12225469a995SCy Schubert switch (svcparamkey) { 12235469a995SCy Schubert case SVCB_KEY_PORT: 12245469a995SCy Schubert r = sldns_wire2str_svcparam_port2str(s, slen, data_len, *d); 12255469a995SCy Schubert break; 12265469a995SCy Schubert case SVCB_KEY_IPV4HINT: 12275469a995SCy Schubert r = sldns_wire2str_svcparam_ipv4hint2str(s, slen, data_len, *d); 12285469a995SCy Schubert break; 12295469a995SCy Schubert case SVCB_KEY_IPV6HINT: 12305469a995SCy Schubert r = sldns_wire2str_svcparam_ipv6hint2str(s, slen, data_len, *d); 12315469a995SCy Schubert break; 12325469a995SCy Schubert case SVCB_KEY_MANDATORY: 12335469a995SCy Schubert r = sldns_wire2str_svcparam_mandatory2str(s, slen, data_len, *d); 12345469a995SCy Schubert break; 12355469a995SCy Schubert case SVCB_KEY_NO_DEFAULT_ALPN: 12365469a995SCy Schubert return -1; /* wireformat error, should not have a value */ 12375469a995SCy Schubert case SVCB_KEY_ALPN: 12385469a995SCy Schubert r = sldns_wire2str_svcparam_alpn2str(s, slen, data_len, *d); 12395469a995SCy Schubert break; 12405469a995SCy Schubert case SVCB_KEY_ECH: 12415469a995SCy Schubert r = sldns_wire2str_svcparam_ech2str(s, slen, data_len, *d); 12425469a995SCy Schubert break; 12438f76bb7dSCy Schubert case SVCB_KEY_DOHPATH: 1244*56850988SCy Schubert ATTR_FALLTHROUGH 12458f76bb7dSCy Schubert /* fallthrough */ 12465469a995SCy Schubert default: 12475469a995SCy Schubert r = sldns_str_print(s, slen, "=\""); 12485469a995SCy Schubert 12495469a995SCy Schubert for (i = 0; i < data_len; i++) { 12505469a995SCy Schubert ch = (*d)[i]; 12515469a995SCy Schubert 12525469a995SCy Schubert if (ch == '"' || ch == '\\') 12535469a995SCy Schubert r += sldns_str_print(s, slen, "\\%c", ch); 12545469a995SCy Schubert 12555469a995SCy Schubert else if (!isprint(ch)) 12565469a995SCy Schubert r += sldns_str_print(s, slen, "\\%03u", (unsigned) ch); 12575469a995SCy Schubert 12585469a995SCy Schubert else 12595469a995SCy Schubert r += sldns_str_print(s, slen, "%c", ch); 12605469a995SCy Schubert 12615469a995SCy Schubert } 12625469a995SCy Schubert r += sldns_str_print(s, slen, "\""); 12635469a995SCy Schubert break; 12645469a995SCy Schubert } 12655469a995SCy Schubert if (r <= 0) 12665469a995SCy Schubert return -1; /* wireformat error */ 12675469a995SCy Schubert 12685469a995SCy Schubert written_chars += r; 12695469a995SCy Schubert *d += data_len; 12705469a995SCy Schubert *dlen -= data_len; 12715469a995SCy Schubert return written_chars; 12725469a995SCy Schubert } 12735469a995SCy Schubert 127409a3aaf3SDag-Erling Smørgrav int sldns_wire2str_rdf_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen, 12750eefd307SCy Schubert int rdftype, uint8_t* pkt, size_t pktlen, int* comprloop) 127609a3aaf3SDag-Erling Smørgrav { 127709a3aaf3SDag-Erling Smørgrav if(*dlen == 0) return 0; 127809a3aaf3SDag-Erling Smørgrav switch(rdftype) { 127909a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_NONE: 128009a3aaf3SDag-Erling Smørgrav return 0; 128109a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_DNAME: 12820eefd307SCy Schubert return sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen, comprloop); 128309a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_INT8: 128409a3aaf3SDag-Erling Smørgrav return sldns_wire2str_int8_scan(d, dlen, s, slen); 128509a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_INT16: 128609a3aaf3SDag-Erling Smørgrav return sldns_wire2str_int16_scan(d, dlen, s, slen); 128709a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_INT32: 128809a3aaf3SDag-Erling Smørgrav return sldns_wire2str_int32_scan(d, dlen, s, slen); 128909a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_PERIOD: 129009a3aaf3SDag-Erling Smørgrav return sldns_wire2str_period_scan(d, dlen, s, slen); 129109a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_TSIGTIME: 129209a3aaf3SDag-Erling Smørgrav return sldns_wire2str_tsigtime_scan(d, dlen, s, slen); 129309a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_A: 129409a3aaf3SDag-Erling Smørgrav return sldns_wire2str_a_scan(d, dlen, s, slen); 129509a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_AAAA: 129609a3aaf3SDag-Erling Smørgrav return sldns_wire2str_aaaa_scan(d, dlen, s, slen); 129709a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_STR: 129809a3aaf3SDag-Erling Smørgrav return sldns_wire2str_str_scan(d, dlen, s, slen); 129909a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_APL: 130009a3aaf3SDag-Erling Smørgrav return sldns_wire2str_apl_scan(d, dlen, s, slen); 130109a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_B32_EXT: 130209a3aaf3SDag-Erling Smørgrav return sldns_wire2str_b32_ext_scan(d, dlen, s, slen); 130309a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_B64: 130409a3aaf3SDag-Erling Smørgrav return sldns_wire2str_b64_scan(d, dlen, s, slen); 130509a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_HEX: 130609a3aaf3SDag-Erling Smørgrav return sldns_wire2str_hex_scan(d, dlen, s, slen); 130709a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_NSEC: 130809a3aaf3SDag-Erling Smørgrav return sldns_wire2str_nsec_scan(d, dlen, s, slen); 130909a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_NSEC3_SALT: 131009a3aaf3SDag-Erling Smørgrav return sldns_wire2str_nsec3_salt_scan(d, dlen, s, slen); 131109a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_TYPE: 131209a3aaf3SDag-Erling Smørgrav return sldns_wire2str_type_scan(d, dlen, s, slen); 131309a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_CLASS: 131409a3aaf3SDag-Erling Smørgrav return sldns_wire2str_class_scan(d, dlen, s, slen); 131509a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_CERT_ALG: 131609a3aaf3SDag-Erling Smørgrav return sldns_wire2str_cert_alg_scan(d, dlen, s, slen); 131709a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_ALG: 131809a3aaf3SDag-Erling Smørgrav return sldns_wire2str_alg_scan(d, dlen, s, slen); 131909a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_UNKNOWN: 132009a3aaf3SDag-Erling Smørgrav return sldns_wire2str_unknown_scan(d, dlen, s, slen); 132109a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_TIME: 132209a3aaf3SDag-Erling Smørgrav return sldns_wire2str_time_scan(d, dlen, s, slen); 132309a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_LOC: 132409a3aaf3SDag-Erling Smørgrav return sldns_wire2str_loc_scan(d, dlen, s, slen); 132509a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_WKS: 132609a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_SERVICE: 132709a3aaf3SDag-Erling Smørgrav return sldns_wire2str_wks_scan(d, dlen, s, slen); 132809a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_NSAP: 132909a3aaf3SDag-Erling Smørgrav return sldns_wire2str_nsap_scan(d, dlen, s, slen); 133009a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_ATMA: 133109a3aaf3SDag-Erling Smørgrav return sldns_wire2str_atma_scan(d, dlen, s, slen); 133209a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_IPSECKEY: 133309a3aaf3SDag-Erling Smørgrav return sldns_wire2str_ipseckey_scan(d, dlen, s, slen, pkt, 13340eefd307SCy Schubert pktlen, comprloop); 133509a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_HIP: 133609a3aaf3SDag-Erling Smørgrav return sldns_wire2str_hip_scan(d, dlen, s, slen); 133709a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_INT16_DATA: 133809a3aaf3SDag-Erling Smørgrav return sldns_wire2str_int16_data_scan(d, dlen, s, slen); 133909a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER: 134009a3aaf3SDag-Erling Smørgrav return sldns_wire2str_b32_ext_scan(d, dlen, s, slen); 134109a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_ILNP64: 134209a3aaf3SDag-Erling Smørgrav return sldns_wire2str_ilnp64_scan(d, dlen, s, slen); 134309a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_EUI48: 134409a3aaf3SDag-Erling Smørgrav return sldns_wire2str_eui48_scan(d, dlen, s, slen); 134509a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_EUI64: 134609a3aaf3SDag-Erling Smørgrav return sldns_wire2str_eui64_scan(d, dlen, s, slen); 134709a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_TAG: 134809a3aaf3SDag-Erling Smørgrav return sldns_wire2str_tag_scan(d, dlen, s, slen); 134909a3aaf3SDag-Erling Smørgrav case LDNS_RDF_TYPE_LONG_STR: 135009a3aaf3SDag-Erling Smørgrav return sldns_wire2str_long_str_scan(d, dlen, s, slen); 13515469a995SCy Schubert case LDNS_RDF_TYPE_SVCPARAM: 13525469a995SCy Schubert return sldns_wire2str_svcparam_scan(d, dlen, s, slen); 1353c7f4d7adSDag-Erling Smørgrav case LDNS_RDF_TYPE_TSIGERROR: 1354c7f4d7adSDag-Erling Smørgrav return sldns_wire2str_tsigerror_scan(d, dlen, s, slen); 135509a3aaf3SDag-Erling Smørgrav } 135609a3aaf3SDag-Erling Smørgrav /* unknown rdf type */ 135709a3aaf3SDag-Erling Smørgrav return -1; 135809a3aaf3SDag-Erling Smørgrav } 135909a3aaf3SDag-Erling Smørgrav 136009a3aaf3SDag-Erling Smørgrav int sldns_wire2str_int8_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 136109a3aaf3SDag-Erling Smørgrav { 136209a3aaf3SDag-Erling Smørgrav int w; 136309a3aaf3SDag-Erling Smørgrav if(*dl < 1) return -1; 136409a3aaf3SDag-Erling Smørgrav w = sldns_str_print(s, sl, "%u", (unsigned)**d); 136509a3aaf3SDag-Erling Smørgrav (*d)++; 136609a3aaf3SDag-Erling Smørgrav (*dl)--; 136709a3aaf3SDag-Erling Smørgrav return w; 136809a3aaf3SDag-Erling Smørgrav } 136909a3aaf3SDag-Erling Smørgrav 137009a3aaf3SDag-Erling Smørgrav int sldns_wire2str_int16_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 137109a3aaf3SDag-Erling Smørgrav { 137209a3aaf3SDag-Erling Smørgrav int w; 137309a3aaf3SDag-Erling Smørgrav if(*dl < 2) return -1; 137409a3aaf3SDag-Erling Smørgrav w = sldns_str_print(s, sl, "%lu", (unsigned long)sldns_read_uint16(*d)); 137509a3aaf3SDag-Erling Smørgrav (*d)+=2; 137609a3aaf3SDag-Erling Smørgrav (*dl)-=2; 137709a3aaf3SDag-Erling Smørgrav return w; 137809a3aaf3SDag-Erling Smørgrav } 137909a3aaf3SDag-Erling Smørgrav 138009a3aaf3SDag-Erling Smørgrav int sldns_wire2str_int32_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 138109a3aaf3SDag-Erling Smørgrav { 138209a3aaf3SDag-Erling Smørgrav int w; 138309a3aaf3SDag-Erling Smørgrav if(*dl < 4) return -1; 138409a3aaf3SDag-Erling Smørgrav w = sldns_str_print(s, sl, "%lu", (unsigned long)sldns_read_uint32(*d)); 138509a3aaf3SDag-Erling Smørgrav (*d)+=4; 138609a3aaf3SDag-Erling Smørgrav (*dl)-=4; 138709a3aaf3SDag-Erling Smørgrav return w; 138809a3aaf3SDag-Erling Smørgrav } 138909a3aaf3SDag-Erling Smørgrav 139009a3aaf3SDag-Erling Smørgrav int sldns_wire2str_period_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 139109a3aaf3SDag-Erling Smørgrav { 139209a3aaf3SDag-Erling Smørgrav int w; 139309a3aaf3SDag-Erling Smørgrav if(*dl < 4) return -1; 139409a3aaf3SDag-Erling Smørgrav w = sldns_str_print(s, sl, "%u", (unsigned)sldns_read_uint32(*d)); 139509a3aaf3SDag-Erling Smørgrav (*d)+=4; 139609a3aaf3SDag-Erling Smørgrav (*dl)-=4; 139709a3aaf3SDag-Erling Smørgrav return w; 139809a3aaf3SDag-Erling Smørgrav } 139909a3aaf3SDag-Erling Smørgrav 140009a3aaf3SDag-Erling Smørgrav int sldns_wire2str_tsigtime_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 140109a3aaf3SDag-Erling Smørgrav { 140209a3aaf3SDag-Erling Smørgrav /* tsigtime is 48 bits network order unsigned integer */ 140309a3aaf3SDag-Erling Smørgrav int w; 140409a3aaf3SDag-Erling Smørgrav uint64_t tsigtime = 0; 140509a3aaf3SDag-Erling Smørgrav uint64_t d0, d1, d2, d3, d4, d5; 140609a3aaf3SDag-Erling Smørgrav if(*dl < 6) return -1; 140709a3aaf3SDag-Erling Smørgrav d0 = (*d)[0]; /* cast to uint64 for shift operations */ 140809a3aaf3SDag-Erling Smørgrav d1 = (*d)[1]; 140909a3aaf3SDag-Erling Smørgrav d2 = (*d)[2]; 141009a3aaf3SDag-Erling Smørgrav d3 = (*d)[3]; 141109a3aaf3SDag-Erling Smørgrav d4 = (*d)[4]; 141209a3aaf3SDag-Erling Smørgrav d5 = (*d)[5]; 141309a3aaf3SDag-Erling Smørgrav tsigtime = (d0<<40) | (d1<<32) | (d2<<24) | (d3<<16) | (d4<<8) | d5; 141409a3aaf3SDag-Erling Smørgrav #ifndef USE_WINSOCK 141509a3aaf3SDag-Erling Smørgrav w = sldns_str_print(s, sl, "%llu", (long long)tsigtime); 141609a3aaf3SDag-Erling Smørgrav #else 141709a3aaf3SDag-Erling Smørgrav w = sldns_str_print(s, sl, "%I64u", (long long)tsigtime); 141809a3aaf3SDag-Erling Smørgrav #endif 141909a3aaf3SDag-Erling Smørgrav (*d)+=6; 142009a3aaf3SDag-Erling Smørgrav (*dl)-=6; 142109a3aaf3SDag-Erling Smørgrav return w; 142209a3aaf3SDag-Erling Smørgrav } 142309a3aaf3SDag-Erling Smørgrav 142409a3aaf3SDag-Erling Smørgrav int sldns_wire2str_a_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 142509a3aaf3SDag-Erling Smørgrav { 142609a3aaf3SDag-Erling Smørgrav char buf[32]; 142709a3aaf3SDag-Erling Smørgrav int w; 142809a3aaf3SDag-Erling Smørgrav if(*dl < 4) return -1; 142909a3aaf3SDag-Erling Smørgrav if(!inet_ntop(AF_INET, *d, buf, (socklen_t)sizeof(buf))) 143009a3aaf3SDag-Erling Smørgrav return -1; 143109a3aaf3SDag-Erling Smørgrav w = sldns_str_print(s, sl, "%s", buf); 143209a3aaf3SDag-Erling Smørgrav (*d)+=4; 143309a3aaf3SDag-Erling Smørgrav (*dl)-=4; 143409a3aaf3SDag-Erling Smørgrav return w; 143509a3aaf3SDag-Erling Smørgrav } 143609a3aaf3SDag-Erling Smørgrav 143709a3aaf3SDag-Erling Smørgrav int sldns_wire2str_aaaa_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 143809a3aaf3SDag-Erling Smørgrav { 143909a3aaf3SDag-Erling Smørgrav #ifdef AF_INET6 144009a3aaf3SDag-Erling Smørgrav char buf[64]; 144109a3aaf3SDag-Erling Smørgrav int w; 144209a3aaf3SDag-Erling Smørgrav if(*dl < 16) return -1; 144309a3aaf3SDag-Erling Smørgrav if(!inet_ntop(AF_INET6, *d, buf, (socklen_t)sizeof(buf))) 144409a3aaf3SDag-Erling Smørgrav return -1; 144509a3aaf3SDag-Erling Smørgrav w = sldns_str_print(s, sl, "%s", buf); 144609a3aaf3SDag-Erling Smørgrav (*d)+=16; 144709a3aaf3SDag-Erling Smørgrav (*dl)-=16; 144809a3aaf3SDag-Erling Smørgrav return w; 144909a3aaf3SDag-Erling Smørgrav #else 145009a3aaf3SDag-Erling Smørgrav return -1; 145109a3aaf3SDag-Erling Smørgrav #endif 145209a3aaf3SDag-Erling Smørgrav } 145309a3aaf3SDag-Erling Smørgrav 145409a3aaf3SDag-Erling Smørgrav /** printout escaped TYPE_STR character */ 145509a3aaf3SDag-Erling Smørgrav static int str_char_print(char** s, size_t* sl, uint8_t c) 145609a3aaf3SDag-Erling Smørgrav { 145709a3aaf3SDag-Erling Smørgrav if(isprint((unsigned char)c) || c == '\t') { 145809a3aaf3SDag-Erling Smørgrav if(c == '\"' || c == '\\') 145909a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, sl, "\\%c", c); 146009a3aaf3SDag-Erling Smørgrav if(*sl) { 146109a3aaf3SDag-Erling Smørgrav **s = (char)c; 146209a3aaf3SDag-Erling Smørgrav (*s)++; 146309a3aaf3SDag-Erling Smørgrav (*sl)--; 146409a3aaf3SDag-Erling Smørgrav } 146509a3aaf3SDag-Erling Smørgrav return 1; 146609a3aaf3SDag-Erling Smørgrav } 146709a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, sl, "\\%03u", (unsigned)c); 146809a3aaf3SDag-Erling Smørgrav } 146909a3aaf3SDag-Erling Smørgrav 147009a3aaf3SDag-Erling Smørgrav int sldns_wire2str_str_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 147109a3aaf3SDag-Erling Smørgrav { 147209a3aaf3SDag-Erling Smørgrav int w = 0; 147309a3aaf3SDag-Erling Smørgrav size_t i, len; 147409a3aaf3SDag-Erling Smørgrav if(*dl < 1) return -1; 147509a3aaf3SDag-Erling Smørgrav len = **d; 147609a3aaf3SDag-Erling Smørgrav if(*dl < 1+len) return -1; 147709a3aaf3SDag-Erling Smørgrav (*d)++; 147809a3aaf3SDag-Erling Smørgrav (*dl)--; 147909a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "\""); 148009a3aaf3SDag-Erling Smørgrav for(i=0; i<len; i++) 148109a3aaf3SDag-Erling Smørgrav w += str_char_print(s, sl, (*d)[i]); 148209a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "\""); 148309a3aaf3SDag-Erling Smørgrav (*d)+=len; 148409a3aaf3SDag-Erling Smørgrav (*dl)-=len; 148509a3aaf3SDag-Erling Smørgrav return w; 148609a3aaf3SDag-Erling Smørgrav } 148709a3aaf3SDag-Erling Smørgrav 148809a3aaf3SDag-Erling Smørgrav int sldns_wire2str_apl_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 148909a3aaf3SDag-Erling Smørgrav { 149009a3aaf3SDag-Erling Smørgrav int i, w = 0; 149109a3aaf3SDag-Erling Smørgrav uint16_t family; 149209a3aaf3SDag-Erling Smørgrav uint8_t negation, prefix, adflength; 149309a3aaf3SDag-Erling Smørgrav if(*dl < 4) return -1; 149409a3aaf3SDag-Erling Smørgrav family = sldns_read_uint16(*d); 149509a3aaf3SDag-Erling Smørgrav prefix = (*d)[2]; 149609a3aaf3SDag-Erling Smørgrav negation = ((*d)[3] & LDNS_APL_NEGATION); 149709a3aaf3SDag-Erling Smørgrav adflength = ((*d)[3] & LDNS_APL_MASK); 149809a3aaf3SDag-Erling Smørgrav if(*dl < 4+(size_t)adflength) return -1; 149909a3aaf3SDag-Erling Smørgrav if(family != LDNS_APL_IP4 && family != LDNS_APL_IP6) 150009a3aaf3SDag-Erling Smørgrav return -1; /* unknown address family */ 150109a3aaf3SDag-Erling Smørgrav if(negation) 150209a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "!"); 150309a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "%u:", (unsigned)family); 150409a3aaf3SDag-Erling Smørgrav if(family == LDNS_APL_IP4) { 150509a3aaf3SDag-Erling Smørgrav /* check if prefix <32 ? */ 150609a3aaf3SDag-Erling Smørgrav /* address is variable length 0 - 4 */ 150709a3aaf3SDag-Erling Smørgrav for(i=0; i<4; i++) { 150809a3aaf3SDag-Erling Smørgrav if(i > 0) 150909a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "."); 151009a3aaf3SDag-Erling Smørgrav if(i < (int)adflength) 151109a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "%d", (*d)[4+i]); 151209a3aaf3SDag-Erling Smørgrav else w += sldns_str_print(s, sl, "0"); 151309a3aaf3SDag-Erling Smørgrav } 151409a3aaf3SDag-Erling Smørgrav } else if(family == LDNS_APL_IP6) { 151509a3aaf3SDag-Erling Smørgrav /* check if prefix <128 ? */ 151609a3aaf3SDag-Erling Smørgrav /* address is variable length 0 - 16 */ 151709a3aaf3SDag-Erling Smørgrav for(i=0; i<16; i++) { 151809a3aaf3SDag-Erling Smørgrav if(i%2 == 0 && i>0) 151909a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, ":"); 152009a3aaf3SDag-Erling Smørgrav if(i < (int)adflength) 152109a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "%02x", (*d)[4+i]); 152209a3aaf3SDag-Erling Smørgrav else w += sldns_str_print(s, sl, "00"); 152309a3aaf3SDag-Erling Smørgrav } 152409a3aaf3SDag-Erling Smørgrav } 152509a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "/%u", (unsigned)prefix); 152609a3aaf3SDag-Erling Smørgrav (*d) += 4+adflength; 152709a3aaf3SDag-Erling Smørgrav (*dl) -= 4+adflength; 152809a3aaf3SDag-Erling Smørgrav return w; 152909a3aaf3SDag-Erling Smørgrav } 153009a3aaf3SDag-Erling Smørgrav 153109a3aaf3SDag-Erling Smørgrav int sldns_wire2str_b32_ext_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 153209a3aaf3SDag-Erling Smørgrav { 153309a3aaf3SDag-Erling Smørgrav size_t datalen; 153409a3aaf3SDag-Erling Smørgrav size_t sz; 153509a3aaf3SDag-Erling Smørgrav if(*dl < 1) return -1; 153609a3aaf3SDag-Erling Smørgrav datalen = (*d)[0]; 153709a3aaf3SDag-Erling Smørgrav if(*dl < 1+datalen) return -1; 153809a3aaf3SDag-Erling Smørgrav sz = sldns_b32_ntop_calculate_size(datalen); 153909a3aaf3SDag-Erling Smørgrav if(*sl < sz+1) { 154009a3aaf3SDag-Erling Smørgrav (*d) += datalen+1; 154109a3aaf3SDag-Erling Smørgrav (*dl) -= (datalen+1); 154209a3aaf3SDag-Erling Smørgrav return (int)sz; /* out of space really, but would need buffer 154309a3aaf3SDag-Erling Smørgrav in order to truncate the output */ 154409a3aaf3SDag-Erling Smørgrav } 154509a3aaf3SDag-Erling Smørgrav sldns_b32_ntop_extended_hex((*d)+1, datalen, *s, *sl); 154609a3aaf3SDag-Erling Smørgrav (*d) += datalen+1; 154709a3aaf3SDag-Erling Smørgrav (*dl) -= (datalen+1); 154809a3aaf3SDag-Erling Smørgrav (*s) += sz; 154909a3aaf3SDag-Erling Smørgrav (*sl) -= sz; 155009a3aaf3SDag-Erling Smørgrav return (int)sz; 155109a3aaf3SDag-Erling Smørgrav } 155209a3aaf3SDag-Erling Smørgrav 155309a3aaf3SDag-Erling Smørgrav /** scan number of bytes from wire into b64 presentation format */ 155409a3aaf3SDag-Erling Smørgrav static int sldns_wire2str_b64_scan_num(uint8_t** d, size_t* dl, char** s, 155509a3aaf3SDag-Erling Smørgrav size_t* sl, size_t num) 155609a3aaf3SDag-Erling Smørgrav { 155709a3aaf3SDag-Erling Smørgrav /* b64_ntop_calculate size includes null at the end */ 155809a3aaf3SDag-Erling Smørgrav size_t sz = sldns_b64_ntop_calculate_size(num)-1; 155909a3aaf3SDag-Erling Smørgrav if(*sl < sz+1) { 156009a3aaf3SDag-Erling Smørgrav (*d) += num; 156109a3aaf3SDag-Erling Smørgrav (*dl) -= num; 156209a3aaf3SDag-Erling Smørgrav return (int)sz; /* out of space really, but would need buffer 156309a3aaf3SDag-Erling Smørgrav in order to truncate the output */ 156409a3aaf3SDag-Erling Smørgrav } 156509a3aaf3SDag-Erling Smørgrav sldns_b64_ntop(*d, num, *s, *sl); 156609a3aaf3SDag-Erling Smørgrav (*d) += num; 156709a3aaf3SDag-Erling Smørgrav (*dl) -= num; 156809a3aaf3SDag-Erling Smørgrav (*s) += sz; 156909a3aaf3SDag-Erling Smørgrav (*sl) -= sz; 157009a3aaf3SDag-Erling Smørgrav return (int)sz; 157109a3aaf3SDag-Erling Smørgrav } 157209a3aaf3SDag-Erling Smørgrav 157309a3aaf3SDag-Erling Smørgrav int sldns_wire2str_b64_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 157409a3aaf3SDag-Erling Smørgrav { 1575971980c3SDag-Erling Smørgrav if(*dl == 0) { 1576971980c3SDag-Erling Smørgrav return sldns_str_print(s, sl, "0"); 1577971980c3SDag-Erling Smørgrav } 157809a3aaf3SDag-Erling Smørgrav return sldns_wire2str_b64_scan_num(d, dl, s, sl, *dl); 157909a3aaf3SDag-Erling Smørgrav } 158009a3aaf3SDag-Erling Smørgrav 158109a3aaf3SDag-Erling Smørgrav int sldns_wire2str_hex_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 158209a3aaf3SDag-Erling Smørgrav { 1583971980c3SDag-Erling Smørgrav if(*dl == 0) { 1584971980c3SDag-Erling Smørgrav return sldns_str_print(s, sl, "0"); 1585971980c3SDag-Erling Smørgrav } 158609a3aaf3SDag-Erling Smørgrav return print_remainder_hex("", d, dl, s, sl); 158709a3aaf3SDag-Erling Smørgrav } 158809a3aaf3SDag-Erling Smørgrav 158909a3aaf3SDag-Erling Smørgrav int sldns_wire2str_nsec_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 159009a3aaf3SDag-Erling Smørgrav { 159109a3aaf3SDag-Erling Smørgrav uint8_t* p = *d; 159209a3aaf3SDag-Erling Smørgrav size_t pl = *dl; 159309a3aaf3SDag-Erling Smørgrav unsigned i, bit, window, block_len; 159409a3aaf3SDag-Erling Smørgrav uint16_t t; 159509a3aaf3SDag-Erling Smørgrav int w = 0; 159609a3aaf3SDag-Erling Smørgrav 159709a3aaf3SDag-Erling Smørgrav /* check for errors */ 159809a3aaf3SDag-Erling Smørgrav while(pl) { 159909a3aaf3SDag-Erling Smørgrav if(pl < 2) return -1; 160009a3aaf3SDag-Erling Smørgrav block_len = (unsigned)p[1]; 160109a3aaf3SDag-Erling Smørgrav if(pl < 2+block_len) return -1; 160209a3aaf3SDag-Erling Smørgrav p += block_len+2; 160309a3aaf3SDag-Erling Smørgrav pl -= block_len+2; 160409a3aaf3SDag-Erling Smørgrav } 160509a3aaf3SDag-Erling Smørgrav 160609a3aaf3SDag-Erling Smørgrav /* do it */ 160709a3aaf3SDag-Erling Smørgrav p = *d; 160809a3aaf3SDag-Erling Smørgrav pl = *dl; 160909a3aaf3SDag-Erling Smørgrav while(pl) { 161009a3aaf3SDag-Erling Smørgrav if(pl < 2) return -1; /* cannot happen */ 161109a3aaf3SDag-Erling Smørgrav window = (unsigned)p[0]; 161209a3aaf3SDag-Erling Smørgrav block_len = (unsigned)p[1]; 161309a3aaf3SDag-Erling Smørgrav if(pl < 2+block_len) return -1; /* cannot happen */ 161409a3aaf3SDag-Erling Smørgrav p += 2; 161509a3aaf3SDag-Erling Smørgrav for(i=0; i<block_len; i++) { 161609a3aaf3SDag-Erling Smørgrav if(p[i] == 0) continue; 161709a3aaf3SDag-Erling Smørgrav /* base type number for this octet */ 161809a3aaf3SDag-Erling Smørgrav t = ((window)<<8) | (i << 3); 161909a3aaf3SDag-Erling Smørgrav for(bit=0; bit<8; bit++) { 162009a3aaf3SDag-Erling Smørgrav if((p[i]&(0x80>>bit))) { 162109a3aaf3SDag-Erling Smørgrav if(w) w += sldns_str_print(s, sl, " "); 162209a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_type_print(s, sl, 162309a3aaf3SDag-Erling Smørgrav t+bit); 162409a3aaf3SDag-Erling Smørgrav } 162509a3aaf3SDag-Erling Smørgrav } 162609a3aaf3SDag-Erling Smørgrav } 162709a3aaf3SDag-Erling Smørgrav p += block_len; 162809a3aaf3SDag-Erling Smørgrav pl -= block_len+2; 162909a3aaf3SDag-Erling Smørgrav } 163009a3aaf3SDag-Erling Smørgrav (*d) += *dl; 163109a3aaf3SDag-Erling Smørgrav (*dl) = 0; 163209a3aaf3SDag-Erling Smørgrav return w; 163309a3aaf3SDag-Erling Smørgrav } 163409a3aaf3SDag-Erling Smørgrav 163509a3aaf3SDag-Erling Smørgrav int sldns_wire2str_nsec3_salt_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 163609a3aaf3SDag-Erling Smørgrav { 163709a3aaf3SDag-Erling Smørgrav size_t salt_len; 163809a3aaf3SDag-Erling Smørgrav int w; 163909a3aaf3SDag-Erling Smørgrav if(*dl < 1) return -1; 164009a3aaf3SDag-Erling Smørgrav salt_len = (size_t)(*d)[0]; 164109a3aaf3SDag-Erling Smørgrav if(*dl < 1+salt_len) return -1; 164209a3aaf3SDag-Erling Smørgrav (*d)++; 164309a3aaf3SDag-Erling Smørgrav (*dl)--; 164409a3aaf3SDag-Erling Smørgrav if(salt_len == 0) { 164509a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, sl, "-"); 164609a3aaf3SDag-Erling Smørgrav } 164709a3aaf3SDag-Erling Smørgrav w = print_hex_buf(s, sl, *d, salt_len); 164809a3aaf3SDag-Erling Smørgrav (*dl)-=salt_len; 164909a3aaf3SDag-Erling Smørgrav (*d)+=salt_len; 165009a3aaf3SDag-Erling Smørgrav return w; 165109a3aaf3SDag-Erling Smørgrav } 165209a3aaf3SDag-Erling Smørgrav 165309a3aaf3SDag-Erling Smørgrav int sldns_wire2str_cert_alg_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 165409a3aaf3SDag-Erling Smørgrav { 165509a3aaf3SDag-Erling Smørgrav sldns_lookup_table *lt; 165609a3aaf3SDag-Erling Smørgrav int data, w; 165709a3aaf3SDag-Erling Smørgrav if(*dl < 2) return -1; 165809a3aaf3SDag-Erling Smørgrav data = (int)sldns_read_uint16(*d); 165909a3aaf3SDag-Erling Smørgrav lt = sldns_lookup_by_id(sldns_cert_algorithms, data); 166009a3aaf3SDag-Erling Smørgrav if(lt && lt->name) 166109a3aaf3SDag-Erling Smørgrav w = sldns_str_print(s, sl, "%s", lt->name); 166209a3aaf3SDag-Erling Smørgrav else w = sldns_str_print(s, sl, "%d", data); 166309a3aaf3SDag-Erling Smørgrav (*dl)-=2; 166409a3aaf3SDag-Erling Smørgrav (*d)+=2; 166509a3aaf3SDag-Erling Smørgrav return w; 166609a3aaf3SDag-Erling Smørgrav } 166709a3aaf3SDag-Erling Smørgrav 166809a3aaf3SDag-Erling Smørgrav int sldns_wire2str_alg_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 166909a3aaf3SDag-Erling Smørgrav { 167009a3aaf3SDag-Erling Smørgrav /* don't use algorithm mnemonics in the presentation format 167109a3aaf3SDag-Erling Smørgrav * this kind of got sneaked into the rfc's */ 167209a3aaf3SDag-Erling Smørgrav return sldns_wire2str_int8_scan(d, dl, s, sl); 167309a3aaf3SDag-Erling Smørgrav } 167409a3aaf3SDag-Erling Smørgrav 167509a3aaf3SDag-Erling Smørgrav int sldns_wire2str_unknown_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 167609a3aaf3SDag-Erling Smørgrav { 167709a3aaf3SDag-Erling Smørgrav return sldns_wire2str_rdata_unknown_scan(d, dl, s, sl); 167809a3aaf3SDag-Erling Smørgrav } 167909a3aaf3SDag-Erling Smørgrav 168009a3aaf3SDag-Erling Smørgrav int sldns_wire2str_time_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 168109a3aaf3SDag-Erling Smørgrav { 168209a3aaf3SDag-Erling Smørgrav /* create a YYYYMMDDHHMMSS string if possible */ 168309a3aaf3SDag-Erling Smørgrav struct tm tm; 168409a3aaf3SDag-Erling Smørgrav char date_buf[16]; 168509a3aaf3SDag-Erling Smørgrav uint32_t t; 168609a3aaf3SDag-Erling Smørgrav memset(&tm, 0, sizeof(tm)); 168709a3aaf3SDag-Erling Smørgrav if(*dl < 4) return -1; 168809a3aaf3SDag-Erling Smørgrav t = sldns_read_uint32(*d); 168909a3aaf3SDag-Erling Smørgrav date_buf[15]=0; 16908a384985SDag-Erling Smørgrav if(sldns_serial_arithmetics_gmtime_r(t, time(NULL), &tm) && 169109a3aaf3SDag-Erling Smørgrav strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) { 169209a3aaf3SDag-Erling Smørgrav (*d) += 4; 169309a3aaf3SDag-Erling Smørgrav (*dl) -= 4; 169409a3aaf3SDag-Erling Smørgrav return sldns_str_print(s, sl, "%s", date_buf); 169509a3aaf3SDag-Erling Smørgrav } 169609a3aaf3SDag-Erling Smørgrav return -1; 169709a3aaf3SDag-Erling Smørgrav } 169809a3aaf3SDag-Erling Smørgrav 169909a3aaf3SDag-Erling Smørgrav static int 170009a3aaf3SDag-Erling Smørgrav loc_cm_print(char** str, size_t* sl, uint8_t mantissa, uint8_t exponent) 170109a3aaf3SDag-Erling Smørgrav { 170209a3aaf3SDag-Erling Smørgrav int w = 0; 170309a3aaf3SDag-Erling Smørgrav uint8_t i; 170409a3aaf3SDag-Erling Smørgrav /* is it 0.<two digits> ? */ 170509a3aaf3SDag-Erling Smørgrav if(exponent < 2) { 170609a3aaf3SDag-Erling Smørgrav if(exponent == 1) 170709a3aaf3SDag-Erling Smørgrav mantissa *= 10; 170809a3aaf3SDag-Erling Smørgrav return sldns_str_print(str, sl, "0.%02ld", (long)mantissa); 170909a3aaf3SDag-Erling Smørgrav } 171009a3aaf3SDag-Erling Smørgrav /* always <digit><string of zeros> */ 171109a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, sl, "%d", (int)mantissa); 171209a3aaf3SDag-Erling Smørgrav for(i=0; i<exponent-2; i++) 171309a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, sl, "0"); 171409a3aaf3SDag-Erling Smørgrav return w; 171509a3aaf3SDag-Erling Smørgrav } 171609a3aaf3SDag-Erling Smørgrav 171709a3aaf3SDag-Erling Smørgrav int sldns_wire2str_loc_scan(uint8_t** d, size_t* dl, char** str, size_t* sl) 171809a3aaf3SDag-Erling Smørgrav { 171909a3aaf3SDag-Erling Smørgrav /* we could do checking (ie degrees < 90 etc)? */ 172009a3aaf3SDag-Erling Smørgrav uint8_t version; 172109a3aaf3SDag-Erling Smørgrav uint8_t size; 172209a3aaf3SDag-Erling Smørgrav uint8_t horizontal_precision; 172309a3aaf3SDag-Erling Smørgrav uint8_t vertical_precision; 172409a3aaf3SDag-Erling Smørgrav uint32_t longitude; 172509a3aaf3SDag-Erling Smørgrav uint32_t latitude; 172609a3aaf3SDag-Erling Smørgrav uint32_t altitude; 172709a3aaf3SDag-Erling Smørgrav char northerness; 172809a3aaf3SDag-Erling Smørgrav char easterness; 172909a3aaf3SDag-Erling Smørgrav uint32_t h; 173009a3aaf3SDag-Erling Smørgrav uint32_t m; 173109a3aaf3SDag-Erling Smørgrav double s; 173209a3aaf3SDag-Erling Smørgrav uint32_t equator = (uint32_t)1 << 31; /* 2**31 */ 173309a3aaf3SDag-Erling Smørgrav int w = 0; 173409a3aaf3SDag-Erling Smørgrav 173509a3aaf3SDag-Erling Smørgrav if(*dl < 16) return -1; 173609a3aaf3SDag-Erling Smørgrav version = (*d)[0]; 173709a3aaf3SDag-Erling Smørgrav if(version != 0) 173809a3aaf3SDag-Erling Smørgrav return sldns_wire2str_hex_scan(d, dl, str, sl); 173909a3aaf3SDag-Erling Smørgrav size = (*d)[1]; 174009a3aaf3SDag-Erling Smørgrav horizontal_precision = (*d)[2]; 174109a3aaf3SDag-Erling Smørgrav vertical_precision = (*d)[3]; 174209a3aaf3SDag-Erling Smørgrav 174309a3aaf3SDag-Erling Smørgrav latitude = sldns_read_uint32((*d)+4); 174409a3aaf3SDag-Erling Smørgrav longitude = sldns_read_uint32((*d)+8); 174509a3aaf3SDag-Erling Smørgrav altitude = sldns_read_uint32((*d)+12); 174609a3aaf3SDag-Erling Smørgrav 174709a3aaf3SDag-Erling Smørgrav if (latitude > equator) { 174809a3aaf3SDag-Erling Smørgrav northerness = 'N'; 174909a3aaf3SDag-Erling Smørgrav latitude = latitude - equator; 175009a3aaf3SDag-Erling Smørgrav } else { 175109a3aaf3SDag-Erling Smørgrav northerness = 'S'; 175209a3aaf3SDag-Erling Smørgrav latitude = equator - latitude; 175309a3aaf3SDag-Erling Smørgrav } 175409a3aaf3SDag-Erling Smørgrav h = latitude / (1000 * 60 * 60); 175509a3aaf3SDag-Erling Smørgrav latitude = latitude % (1000 * 60 * 60); 175609a3aaf3SDag-Erling Smørgrav m = latitude / (1000 * 60); 175709a3aaf3SDag-Erling Smørgrav latitude = latitude % (1000 * 60); 175809a3aaf3SDag-Erling Smørgrav s = (double) latitude / 1000.0; 175909a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, sl, "%02u %02u %06.3f %c ", 176009a3aaf3SDag-Erling Smørgrav h, m, s, northerness); 176109a3aaf3SDag-Erling Smørgrav 176209a3aaf3SDag-Erling Smørgrav if (longitude > equator) { 176309a3aaf3SDag-Erling Smørgrav easterness = 'E'; 176409a3aaf3SDag-Erling Smørgrav longitude = longitude - equator; 176509a3aaf3SDag-Erling Smørgrav } else { 176609a3aaf3SDag-Erling Smørgrav easterness = 'W'; 176709a3aaf3SDag-Erling Smørgrav longitude = equator - longitude; 176809a3aaf3SDag-Erling Smørgrav } 176909a3aaf3SDag-Erling Smørgrav h = longitude / (1000 * 60 * 60); 177009a3aaf3SDag-Erling Smørgrav longitude = longitude % (1000 * 60 * 60); 177109a3aaf3SDag-Erling Smørgrav m = longitude / (1000 * 60); 177209a3aaf3SDag-Erling Smørgrav longitude = longitude % (1000 * 60); 177309a3aaf3SDag-Erling Smørgrav s = (double) longitude / (1000.0); 177409a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, sl, "%02u %02u %06.3f %c ", 177509a3aaf3SDag-Erling Smørgrav h, m, s, easterness); 177609a3aaf3SDag-Erling Smørgrav 177709a3aaf3SDag-Erling Smørgrav s = ((double) altitude) / 100; 177809a3aaf3SDag-Erling Smørgrav s -= 100000; 177909a3aaf3SDag-Erling Smørgrav 178009a3aaf3SDag-Erling Smørgrav if(altitude%100 != 0) 178109a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, sl, "%.2f", s); 178209a3aaf3SDag-Erling Smørgrav else 178309a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, sl, "%.0f", s); 178409a3aaf3SDag-Erling Smørgrav 178509a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, sl, "m "); 178609a3aaf3SDag-Erling Smørgrav 178709a3aaf3SDag-Erling Smørgrav w += loc_cm_print(str, sl, (size & 0xf0) >> 4, size & 0x0f); 178809a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, sl, "m "); 178909a3aaf3SDag-Erling Smørgrav 179009a3aaf3SDag-Erling Smørgrav w += loc_cm_print(str, sl, (horizontal_precision & 0xf0) >> 4, 179109a3aaf3SDag-Erling Smørgrav horizontal_precision & 0x0f); 179209a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, sl, "m "); 179309a3aaf3SDag-Erling Smørgrav 179409a3aaf3SDag-Erling Smørgrav w += loc_cm_print(str, sl, (vertical_precision & 0xf0) >> 4, 179509a3aaf3SDag-Erling Smørgrav vertical_precision & 0x0f); 179609a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, sl, "m"); 179709a3aaf3SDag-Erling Smørgrav 179809a3aaf3SDag-Erling Smørgrav (*d)+=16; 179909a3aaf3SDag-Erling Smørgrav (*dl)-=16; 180009a3aaf3SDag-Erling Smørgrav return w; 180109a3aaf3SDag-Erling Smørgrav } 180209a3aaf3SDag-Erling Smørgrav 180309a3aaf3SDag-Erling Smørgrav int sldns_wire2str_wks_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 180409a3aaf3SDag-Erling Smørgrav { 180509a3aaf3SDag-Erling Smørgrav /* protocol, followed by bitmap of services */ 180609a3aaf3SDag-Erling Smørgrav const char* proto_name = NULL; 180709a3aaf3SDag-Erling Smørgrav struct protoent *protocol; 180809a3aaf3SDag-Erling Smørgrav struct servent *service; 180909a3aaf3SDag-Erling Smørgrav uint8_t protocol_nr; 181009a3aaf3SDag-Erling Smørgrav int bit, port, w = 0; 181109a3aaf3SDag-Erling Smørgrav size_t i; 181209a3aaf3SDag-Erling Smørgrav /* we cannot print with strings because they 181309a3aaf3SDag-Erling Smørgrav * are not portable, the presentation format may 181409a3aaf3SDag-Erling Smørgrav * not be able to be read in on another computer. */ 181509a3aaf3SDag-Erling Smørgrav int print_symbols = 0; 181609a3aaf3SDag-Erling Smørgrav 181709a3aaf3SDag-Erling Smørgrav /* protocol */ 181809a3aaf3SDag-Erling Smørgrav if(*dl < 1) return -1; 181909a3aaf3SDag-Erling Smørgrav protocol_nr = (*d)[0]; 182009a3aaf3SDag-Erling Smørgrav (*d)++; 182109a3aaf3SDag-Erling Smørgrav (*dl)--; 182209a3aaf3SDag-Erling Smørgrav protocol = getprotobynumber((int)protocol_nr); 182309a3aaf3SDag-Erling Smørgrav if(protocol && (protocol->p_name != NULL)) { 182409a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "%s", protocol->p_name); 182509a3aaf3SDag-Erling Smørgrav proto_name = protocol->p_name; 1826971980c3SDag-Erling Smørgrav } else if(protocol_nr == 6) { 1827971980c3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "tcp"); 1828971980c3SDag-Erling Smørgrav } else if(protocol_nr == 17) { 1829971980c3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "udp"); 183009a3aaf3SDag-Erling Smørgrav } else { 183109a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "%u", (unsigned)protocol_nr); 183209a3aaf3SDag-Erling Smørgrav } 183309a3aaf3SDag-Erling Smørgrav 183409a3aaf3SDag-Erling Smørgrav for(i=0; i<*dl; i++) { 183509a3aaf3SDag-Erling Smørgrav if((*d)[i] == 0) 183609a3aaf3SDag-Erling Smørgrav continue; 183709a3aaf3SDag-Erling Smørgrav for(bit=0; bit<8; bit++) { 183809a3aaf3SDag-Erling Smørgrav if(!(((*d)[i])&(0x80>>bit))) 183909a3aaf3SDag-Erling Smørgrav continue; 184009a3aaf3SDag-Erling Smørgrav port = (int)i*8 + bit; 184109a3aaf3SDag-Erling Smørgrav 184209a3aaf3SDag-Erling Smørgrav if(!print_symbols) 184309a3aaf3SDag-Erling Smørgrav service = NULL; 184409a3aaf3SDag-Erling Smørgrav else 184509a3aaf3SDag-Erling Smørgrav service = getservbyport( 184609a3aaf3SDag-Erling Smørgrav (int)htons((uint16_t)port), proto_name); 184709a3aaf3SDag-Erling Smørgrav if(service && service->s_name) 184809a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, " %s", 184909a3aaf3SDag-Erling Smørgrav service->s_name); 185009a3aaf3SDag-Erling Smørgrav else w += sldns_str_print(s, sl, " %u", 185109a3aaf3SDag-Erling Smørgrav (unsigned)port); 185209a3aaf3SDag-Erling Smørgrav } 185309a3aaf3SDag-Erling Smørgrav } 185409a3aaf3SDag-Erling Smørgrav 185509a3aaf3SDag-Erling Smørgrav #ifdef HAVE_ENDSERVENT 185609a3aaf3SDag-Erling Smørgrav endservent(); 185709a3aaf3SDag-Erling Smørgrav #endif 185809a3aaf3SDag-Erling Smørgrav #ifdef HAVE_ENDPROTOENT 185909a3aaf3SDag-Erling Smørgrav endprotoent(); 186009a3aaf3SDag-Erling Smørgrav #endif 186109a3aaf3SDag-Erling Smørgrav (*d) += *dl; 186209a3aaf3SDag-Erling Smørgrav (*dl) = 0; 186309a3aaf3SDag-Erling Smørgrav return w; 186409a3aaf3SDag-Erling Smørgrav } 186509a3aaf3SDag-Erling Smørgrav 186609a3aaf3SDag-Erling Smørgrav int sldns_wire2str_nsap_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 186709a3aaf3SDag-Erling Smørgrav { 186809a3aaf3SDag-Erling Smørgrav return print_remainder_hex("0x", d, dl, s, sl); 186909a3aaf3SDag-Erling Smørgrav } 187009a3aaf3SDag-Erling Smørgrav 187109a3aaf3SDag-Erling Smørgrav int sldns_wire2str_atma_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 187209a3aaf3SDag-Erling Smørgrav { 187309a3aaf3SDag-Erling Smørgrav return print_remainder_hex("", d, dl, s, sl); 187409a3aaf3SDag-Erling Smørgrav } 187509a3aaf3SDag-Erling Smørgrav 187609a3aaf3SDag-Erling Smørgrav /* internal scan routine that can modify arguments on failure */ 187709a3aaf3SDag-Erling Smørgrav static int sldns_wire2str_ipseckey_scan_internal(uint8_t** d, size_t* dl, 18780eefd307SCy Schubert char** s, size_t* sl, uint8_t* pkt, size_t pktlen, int* comprloop) 187909a3aaf3SDag-Erling Smørgrav { 188009a3aaf3SDag-Erling Smørgrav /* http://www.ietf.org/internet-drafts/draft-ietf-ipseckey-rr-12.txt*/ 188109a3aaf3SDag-Erling Smørgrav uint8_t precedence, gateway_type, algorithm; 188209a3aaf3SDag-Erling Smørgrav int w = 0; 188309a3aaf3SDag-Erling Smørgrav 188409a3aaf3SDag-Erling Smørgrav if(*dl < 3) return -1; 188509a3aaf3SDag-Erling Smørgrav precedence = (*d)[0]; 188609a3aaf3SDag-Erling Smørgrav gateway_type = (*d)[1]; 188709a3aaf3SDag-Erling Smørgrav algorithm = (*d)[2]; 188809a3aaf3SDag-Erling Smørgrav if(gateway_type > 3) 188909a3aaf3SDag-Erling Smørgrav return -1; /* unknown */ 189009a3aaf3SDag-Erling Smørgrav (*d)+=3; 189109a3aaf3SDag-Erling Smørgrav (*dl)-=3; 189209a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "%d %d %d ", 189309a3aaf3SDag-Erling Smørgrav (int)precedence, (int)gateway_type, (int)algorithm); 189409a3aaf3SDag-Erling Smørgrav 189509a3aaf3SDag-Erling Smørgrav switch(gateway_type) { 189609a3aaf3SDag-Erling Smørgrav case 0: /* no gateway */ 189709a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "."); 189809a3aaf3SDag-Erling Smørgrav break; 189909a3aaf3SDag-Erling Smørgrav case 1: /* ip4 */ 190009a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_a_scan(d, dl, s, sl); 190109a3aaf3SDag-Erling Smørgrav break; 190209a3aaf3SDag-Erling Smørgrav case 2: /* ip6 */ 190309a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_aaaa_scan(d, dl, s, sl); 190409a3aaf3SDag-Erling Smørgrav break; 190509a3aaf3SDag-Erling Smørgrav case 3: /* dname */ 19060eefd307SCy Schubert w += sldns_wire2str_dname_scan(d, dl, s, sl, pkt, pktlen, comprloop); 190709a3aaf3SDag-Erling Smørgrav break; 190809a3aaf3SDag-Erling Smørgrav default: /* unknown */ 190909a3aaf3SDag-Erling Smørgrav return -1; 191009a3aaf3SDag-Erling Smørgrav } 191109a3aaf3SDag-Erling Smørgrav 191209a3aaf3SDag-Erling Smørgrav if(*dl < 1) 191309a3aaf3SDag-Erling Smørgrav return -1; 191409a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, " "); 191509a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_b64_scan_num(d, dl, s, sl, *dl); 191609a3aaf3SDag-Erling Smørgrav return w; 191709a3aaf3SDag-Erling Smørgrav } 191809a3aaf3SDag-Erling Smørgrav 191909a3aaf3SDag-Erling Smørgrav int sldns_wire2str_ipseckey_scan(uint8_t** d, size_t* dl, char** s, size_t* sl, 19200eefd307SCy Schubert uint8_t* pkt, size_t pktlen, int* comprloop) 192109a3aaf3SDag-Erling Smørgrav { 192209a3aaf3SDag-Erling Smørgrav uint8_t* od = *d; 192309a3aaf3SDag-Erling Smørgrav char* os = *s; 192409a3aaf3SDag-Erling Smørgrav size_t odl = *dl, osl = *sl; 19250eefd307SCy Schubert int w=sldns_wire2str_ipseckey_scan_internal(d, dl, s, sl, pkt, pktlen, comprloop); 192609a3aaf3SDag-Erling Smørgrav if(w == -1) { 192709a3aaf3SDag-Erling Smørgrav *d = od; 192809a3aaf3SDag-Erling Smørgrav *s = os; 192909a3aaf3SDag-Erling Smørgrav *dl = odl; 193009a3aaf3SDag-Erling Smørgrav *sl = osl; 193109a3aaf3SDag-Erling Smørgrav return -1; 193209a3aaf3SDag-Erling Smørgrav } 193309a3aaf3SDag-Erling Smørgrav return w; 193409a3aaf3SDag-Erling Smørgrav } 193509a3aaf3SDag-Erling Smørgrav 193609a3aaf3SDag-Erling Smørgrav int sldns_wire2str_hip_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 193709a3aaf3SDag-Erling Smørgrav { 193809a3aaf3SDag-Erling Smørgrav int w; 193909a3aaf3SDag-Erling Smørgrav uint8_t algo, hitlen; 194009a3aaf3SDag-Erling Smørgrav uint16_t pklen; 194109a3aaf3SDag-Erling Smørgrav 194209a3aaf3SDag-Erling Smørgrav /* read lengths */ 194309a3aaf3SDag-Erling Smørgrav if(*dl < 4) 194409a3aaf3SDag-Erling Smørgrav return -1; 194509a3aaf3SDag-Erling Smørgrav hitlen = (*d)[0]; 194609a3aaf3SDag-Erling Smørgrav algo = (*d)[1]; 194709a3aaf3SDag-Erling Smørgrav pklen = sldns_read_uint16((*d)+2); 194809a3aaf3SDag-Erling Smørgrav if(*dl < (size_t)4 + (size_t)hitlen + (size_t)pklen) 194909a3aaf3SDag-Erling Smørgrav return -1; 195009a3aaf3SDag-Erling Smørgrav 195109a3aaf3SDag-Erling Smørgrav /* write: algo hit pubkey */ 195209a3aaf3SDag-Erling Smørgrav w = sldns_str_print(s, sl, "%u ", (unsigned)algo); 195309a3aaf3SDag-Erling Smørgrav w += print_hex_buf(s, sl, (*d)+4, hitlen); 195409a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, " "); 195509a3aaf3SDag-Erling Smørgrav (*d)+=4+hitlen; 195609a3aaf3SDag-Erling Smørgrav (*dl)-= (4+hitlen); 195709a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_b64_scan_num(d, dl, s, sl, pklen); 195809a3aaf3SDag-Erling Smørgrav return w; 195909a3aaf3SDag-Erling Smørgrav } 196009a3aaf3SDag-Erling Smørgrav 196109a3aaf3SDag-Erling Smørgrav int sldns_wire2str_int16_data_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 196209a3aaf3SDag-Erling Smørgrav { 1963c7f4d7adSDag-Erling Smørgrav int w; 196409a3aaf3SDag-Erling Smørgrav uint16_t n; 196509a3aaf3SDag-Erling Smørgrav if(*dl < 2) 196609a3aaf3SDag-Erling Smørgrav return -1; 196709a3aaf3SDag-Erling Smørgrav n = sldns_read_uint16(*d); 196809a3aaf3SDag-Erling Smørgrav if(*dl < 2+(size_t)n) 196909a3aaf3SDag-Erling Smørgrav return -1; 197009a3aaf3SDag-Erling Smørgrav (*d)+=2; 197109a3aaf3SDag-Erling Smørgrav (*dl)-=2; 1972c7f4d7adSDag-Erling Smørgrav if(n == 0) { 1973c7f4d7adSDag-Erling Smørgrav return sldns_str_print(s, sl, "0"); 1974c7f4d7adSDag-Erling Smørgrav } 1975c7f4d7adSDag-Erling Smørgrav w = sldns_str_print(s, sl, "%u ", (unsigned)n); 1976c7f4d7adSDag-Erling Smørgrav w += sldns_wire2str_b64_scan_num(d, dl, s, sl, n); 1977c7f4d7adSDag-Erling Smørgrav return w; 197809a3aaf3SDag-Erling Smørgrav } 197909a3aaf3SDag-Erling Smørgrav 198009a3aaf3SDag-Erling Smørgrav int sldns_wire2str_nsec3_next_owner_scan(uint8_t** d, size_t* dl, char** s, 198109a3aaf3SDag-Erling Smørgrav size_t* sl) 198209a3aaf3SDag-Erling Smørgrav { 198309a3aaf3SDag-Erling Smørgrav return sldns_wire2str_b32_ext_scan(d, dl, s, sl); 198409a3aaf3SDag-Erling Smørgrav } 198509a3aaf3SDag-Erling Smørgrav 198609a3aaf3SDag-Erling Smørgrav int sldns_wire2str_ilnp64_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 198709a3aaf3SDag-Erling Smørgrav { 198809a3aaf3SDag-Erling Smørgrav int w; 198909a3aaf3SDag-Erling Smørgrav if(*dl < 8) 199009a3aaf3SDag-Erling Smørgrav return -1; 199109a3aaf3SDag-Erling Smørgrav w = sldns_str_print(s, sl, "%.4x:%.4x:%.4x:%.4x", 199209a3aaf3SDag-Erling Smørgrav sldns_read_uint16(*d), sldns_read_uint16((*d)+2), 199309a3aaf3SDag-Erling Smørgrav sldns_read_uint16((*d)+4), sldns_read_uint16((*d)+6)); 199409a3aaf3SDag-Erling Smørgrav (*d)+=8; 199509a3aaf3SDag-Erling Smørgrav (*dl)-=8; 199609a3aaf3SDag-Erling Smørgrav return w; 199709a3aaf3SDag-Erling Smørgrav } 199809a3aaf3SDag-Erling Smørgrav 199909a3aaf3SDag-Erling Smørgrav int sldns_wire2str_eui48_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 200009a3aaf3SDag-Erling Smørgrav { 200109a3aaf3SDag-Erling Smørgrav int w; 200209a3aaf3SDag-Erling Smørgrav if(*dl < 6) 200309a3aaf3SDag-Erling Smørgrav return -1; 200409a3aaf3SDag-Erling Smørgrav w = sldns_str_print(s, sl, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", 200509a3aaf3SDag-Erling Smørgrav (*d)[0], (*d)[1], (*d)[2], (*d)[3], (*d)[4], (*d)[5]); 200609a3aaf3SDag-Erling Smørgrav (*d)+=6; 200709a3aaf3SDag-Erling Smørgrav (*dl)-=6; 200809a3aaf3SDag-Erling Smørgrav return w; 200909a3aaf3SDag-Erling Smørgrav } 201009a3aaf3SDag-Erling Smørgrav 201109a3aaf3SDag-Erling Smørgrav int sldns_wire2str_eui64_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 201209a3aaf3SDag-Erling Smørgrav { 201309a3aaf3SDag-Erling Smørgrav int w; 201409a3aaf3SDag-Erling Smørgrav if(*dl < 8) 201509a3aaf3SDag-Erling Smørgrav return -1; 201609a3aaf3SDag-Erling Smørgrav w = sldns_str_print(s, sl, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", 201709a3aaf3SDag-Erling Smørgrav (*d)[0], (*d)[1], (*d)[2], (*d)[3], (*d)[4], (*d)[5], 201809a3aaf3SDag-Erling Smørgrav (*d)[6], (*d)[7]); 201909a3aaf3SDag-Erling Smørgrav (*d)+=8; 202009a3aaf3SDag-Erling Smørgrav (*dl)-=8; 202109a3aaf3SDag-Erling Smørgrav return w; 202209a3aaf3SDag-Erling Smørgrav } 202309a3aaf3SDag-Erling Smørgrav 202409a3aaf3SDag-Erling Smørgrav int sldns_wire2str_tag_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 202509a3aaf3SDag-Erling Smørgrav { 202609a3aaf3SDag-Erling Smørgrav size_t i, n; 202709a3aaf3SDag-Erling Smørgrav int w = 0; 202809a3aaf3SDag-Erling Smørgrav if(*dl < 1) 202909a3aaf3SDag-Erling Smørgrav return -1; 203009a3aaf3SDag-Erling Smørgrav n = (size_t)((*d)[0]); 203109a3aaf3SDag-Erling Smørgrav if(*dl < 1+n) 203209a3aaf3SDag-Erling Smørgrav return -1; 203309a3aaf3SDag-Erling Smørgrav for(i=0; i<n; i++) 2034c7f4d7adSDag-Erling Smørgrav if(!isalnum((unsigned char)(*d)[i+1])) 203509a3aaf3SDag-Erling Smørgrav return -1; 203609a3aaf3SDag-Erling Smørgrav for(i=0; i<n; i++) 2037c7f4d7adSDag-Erling Smørgrav w += sldns_str_print(s, sl, "%c", (char)(*d)[i+1]); 203809a3aaf3SDag-Erling Smørgrav (*d)+=n+1; 203909a3aaf3SDag-Erling Smørgrav (*dl)-=(n+1); 204009a3aaf3SDag-Erling Smørgrav return w; 204109a3aaf3SDag-Erling Smørgrav } 204209a3aaf3SDag-Erling Smørgrav 204309a3aaf3SDag-Erling Smørgrav int sldns_wire2str_long_str_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 204409a3aaf3SDag-Erling Smørgrav { 204509a3aaf3SDag-Erling Smørgrav size_t i; 204609a3aaf3SDag-Erling Smørgrav int w = 0; 204709a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "\""); 204809a3aaf3SDag-Erling Smørgrav for(i=0; i<*dl; i++) 204909a3aaf3SDag-Erling Smørgrav w += str_char_print(s, sl, (*d)[i]); 205009a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "\""); 205109a3aaf3SDag-Erling Smørgrav (*d)+=*dl; 205209a3aaf3SDag-Erling Smørgrav (*dl)=0; 205309a3aaf3SDag-Erling Smørgrav return w; 205409a3aaf3SDag-Erling Smørgrav } 205509a3aaf3SDag-Erling Smørgrav 2056c7f4d7adSDag-Erling Smørgrav int sldns_wire2str_tsigerror_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 2057c7f4d7adSDag-Erling Smørgrav { 2058c7f4d7adSDag-Erling Smørgrav sldns_lookup_table *lt; 2059c7f4d7adSDag-Erling Smørgrav int data, w; 2060c7f4d7adSDag-Erling Smørgrav if(*dl < 2) return -1; 2061c7f4d7adSDag-Erling Smørgrav data = (int)sldns_read_uint16(*d); 2062c7f4d7adSDag-Erling Smørgrav lt = sldns_lookup_by_id(sldns_tsig_errors, data); 2063c7f4d7adSDag-Erling Smørgrav if(lt && lt->name) 2064c7f4d7adSDag-Erling Smørgrav w = sldns_str_print(s, sl, "%s", lt->name); 2065c7f4d7adSDag-Erling Smørgrav else w = sldns_str_print(s, sl, "%d", data); 2066c7f4d7adSDag-Erling Smørgrav (*dl)-=2; 2067c7f4d7adSDag-Erling Smørgrav (*d)+=2; 2068c7f4d7adSDag-Erling Smørgrav return w; 2069c7f4d7adSDag-Erling Smørgrav } 2070c7f4d7adSDag-Erling Smørgrav 207109a3aaf3SDag-Erling Smørgrav int sldns_wire2str_edns_llq_print(char** s, size_t* sl, uint8_t* data, 207209a3aaf3SDag-Erling Smørgrav size_t len) 207309a3aaf3SDag-Erling Smørgrav { 207409a3aaf3SDag-Erling Smørgrav /* LLQ constants */ 207509a3aaf3SDag-Erling Smørgrav const char* llq_errors[] = {"NO-ERROR", "SERV-FULL", "STATIC", 207609a3aaf3SDag-Erling Smørgrav "FORMAT-ERR", "NO-SUCH-LLQ", "BAD-VERS", "UNKNOWN_ERR"}; 207709a3aaf3SDag-Erling Smørgrav const unsigned int llq_errors_num = 7; 207809a3aaf3SDag-Erling Smørgrav const char* llq_opcodes[] = {"LLQ-SETUP", "LLQ-REFRESH", "LLQ-EVENT"}; 207909a3aaf3SDag-Erling Smørgrav const unsigned int llq_opcodes_num = 3; 208009a3aaf3SDag-Erling Smørgrav uint16_t version, llq_opcode, error_code; 208109a3aaf3SDag-Erling Smørgrav uint64_t llq_id; 208209a3aaf3SDag-Erling Smørgrav uint32_t lease_life; /* Requested or granted life of LLQ, in seconds */ 208309a3aaf3SDag-Erling Smørgrav int w = 0; 208409a3aaf3SDag-Erling Smørgrav 208509a3aaf3SDag-Erling Smørgrav /* read the record */ 208609a3aaf3SDag-Erling Smørgrav if(len != 18) { 208709a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "malformed LLQ "); 208809a3aaf3SDag-Erling Smørgrav w += print_hex_buf(s, sl, data, len); 208909a3aaf3SDag-Erling Smørgrav return w; 209009a3aaf3SDag-Erling Smørgrav } 209109a3aaf3SDag-Erling Smørgrav version = sldns_read_uint16(data); 209209a3aaf3SDag-Erling Smørgrav llq_opcode = sldns_read_uint16(data+2); 209309a3aaf3SDag-Erling Smørgrav error_code = sldns_read_uint16(data+4); 209409a3aaf3SDag-Erling Smørgrav memmove(&llq_id, data+6, sizeof(llq_id)); 209509a3aaf3SDag-Erling Smørgrav lease_life = sldns_read_uint32(data+14); 209609a3aaf3SDag-Erling Smørgrav 209709a3aaf3SDag-Erling Smørgrav /* print it */ 209809a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "v%d ", (int)version); 209909a3aaf3SDag-Erling Smørgrav if(llq_opcode < llq_opcodes_num) 210009a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "%s", llq_opcodes[llq_opcode]); 210109a3aaf3SDag-Erling Smørgrav else w += sldns_str_print(s, sl, "opcode %d", (int)llq_opcode); 210209a3aaf3SDag-Erling Smørgrav if(error_code < llq_errors_num) 210309a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, " %s", llq_errors[error_code]); 210409a3aaf3SDag-Erling Smørgrav else w += sldns_str_print(s, sl, " error %d", (int)error_code); 210509a3aaf3SDag-Erling Smørgrav #ifndef USE_WINSOCK 210609a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, " id %llx lease-life %lu", 210709a3aaf3SDag-Erling Smørgrav (unsigned long long)llq_id, (unsigned long)lease_life); 210809a3aaf3SDag-Erling Smørgrav #else 210909a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, " id %I64x lease-life %lu", 211009a3aaf3SDag-Erling Smørgrav (unsigned long long)llq_id, (unsigned long)lease_life); 211109a3aaf3SDag-Erling Smørgrav #endif 211209a3aaf3SDag-Erling Smørgrav return w; 211309a3aaf3SDag-Erling Smørgrav } 211409a3aaf3SDag-Erling Smørgrav 211509a3aaf3SDag-Erling Smørgrav int sldns_wire2str_edns_ul_print(char** s, size_t* sl, uint8_t* data, 211609a3aaf3SDag-Erling Smørgrav size_t len) 211709a3aaf3SDag-Erling Smørgrav { 211809a3aaf3SDag-Erling Smørgrav uint32_t lease; 211909a3aaf3SDag-Erling Smørgrav int w = 0; 212009a3aaf3SDag-Erling Smørgrav if(len != 4) { 212109a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "malformed UL "); 212209a3aaf3SDag-Erling Smørgrav w += print_hex_buf(s, sl, data, len); 212309a3aaf3SDag-Erling Smørgrav return w; 212409a3aaf3SDag-Erling Smørgrav } 212509a3aaf3SDag-Erling Smørgrav lease = sldns_read_uint32(data); 212609a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "lease %lu", (unsigned long)lease); 212709a3aaf3SDag-Erling Smørgrav return w; 212809a3aaf3SDag-Erling Smørgrav } 212909a3aaf3SDag-Erling Smørgrav 213009a3aaf3SDag-Erling Smørgrav int sldns_wire2str_edns_nsid_print(char** s, size_t* sl, uint8_t* data, 213109a3aaf3SDag-Erling Smørgrav size_t len) 213209a3aaf3SDag-Erling Smørgrav { 213309a3aaf3SDag-Erling Smørgrav int w = 0; 213409a3aaf3SDag-Erling Smørgrav size_t i, printed=0; 213509a3aaf3SDag-Erling Smørgrav w += print_hex_buf(s, sl, data, len); 213609a3aaf3SDag-Erling Smørgrav for(i=0; i<len; i++) { 213709a3aaf3SDag-Erling Smørgrav if(isprint((unsigned char)data[i]) || data[i] == '\t') { 213809a3aaf3SDag-Erling Smørgrav if(!printed) { 213909a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, " ("); 214009a3aaf3SDag-Erling Smørgrav printed = 1; 214109a3aaf3SDag-Erling Smørgrav } 214209a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "%c", (char)data[i]); 214309a3aaf3SDag-Erling Smørgrav } 214409a3aaf3SDag-Erling Smørgrav } 214509a3aaf3SDag-Erling Smørgrav if(printed) 214609a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, ")"); 214709a3aaf3SDag-Erling Smørgrav return w; 214809a3aaf3SDag-Erling Smørgrav } 214909a3aaf3SDag-Erling Smørgrav 215009a3aaf3SDag-Erling Smørgrav int sldns_wire2str_edns_dau_print(char** s, size_t* sl, uint8_t* data, 215109a3aaf3SDag-Erling Smørgrav size_t len) 215209a3aaf3SDag-Erling Smørgrav { 215309a3aaf3SDag-Erling Smørgrav sldns_lookup_table *lt; 215409a3aaf3SDag-Erling Smørgrav size_t i; 215509a3aaf3SDag-Erling Smørgrav int w = 0; 215609a3aaf3SDag-Erling Smørgrav for(i=0; i<len; i++) { 215709a3aaf3SDag-Erling Smørgrav lt = sldns_lookup_by_id(sldns_algorithms, (int)data[i]); 215809a3aaf3SDag-Erling Smørgrav if(lt && lt->name) 215909a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, " %s", lt->name); 216009a3aaf3SDag-Erling Smørgrav else w += sldns_str_print(s, sl, " %d", (int)data[i]); 216109a3aaf3SDag-Erling Smørgrav } 216209a3aaf3SDag-Erling Smørgrav return w; 216309a3aaf3SDag-Erling Smørgrav } 216409a3aaf3SDag-Erling Smørgrav 216509a3aaf3SDag-Erling Smørgrav int sldns_wire2str_edns_dhu_print(char** s, size_t* sl, uint8_t* data, 216609a3aaf3SDag-Erling Smørgrav size_t len) 216709a3aaf3SDag-Erling Smørgrav { 216809a3aaf3SDag-Erling Smørgrav sldns_lookup_table *lt; 216909a3aaf3SDag-Erling Smørgrav size_t i; 217009a3aaf3SDag-Erling Smørgrav int w = 0; 217109a3aaf3SDag-Erling Smørgrav for(i=0; i<len; i++) { 217209a3aaf3SDag-Erling Smørgrav lt = sldns_lookup_by_id(sldns_hashes, (int)data[i]); 217309a3aaf3SDag-Erling Smørgrav if(lt && lt->name) 217409a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, " %s", lt->name); 217509a3aaf3SDag-Erling Smørgrav else w += sldns_str_print(s, sl, " %d", (int)data[i]); 217609a3aaf3SDag-Erling Smørgrav } 217709a3aaf3SDag-Erling Smørgrav return w; 217809a3aaf3SDag-Erling Smørgrav } 217909a3aaf3SDag-Erling Smørgrav 218009a3aaf3SDag-Erling Smørgrav int sldns_wire2str_edns_n3u_print(char** s, size_t* sl, uint8_t* data, 218109a3aaf3SDag-Erling Smørgrav size_t len) 218209a3aaf3SDag-Erling Smørgrav { 218309a3aaf3SDag-Erling Smørgrav size_t i; 218409a3aaf3SDag-Erling Smørgrav int w = 0; 218509a3aaf3SDag-Erling Smørgrav for(i=0; i<len; i++) { 218609a3aaf3SDag-Erling Smørgrav if(data[i] == 1) 218709a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, " SHA1"); 218809a3aaf3SDag-Erling Smørgrav else w += sldns_str_print(s, sl, " %d", (int)data[i]); 218909a3aaf3SDag-Erling Smørgrav } 219009a3aaf3SDag-Erling Smørgrav return w; 219109a3aaf3SDag-Erling Smørgrav } 219209a3aaf3SDag-Erling Smørgrav 219309a3aaf3SDag-Erling Smørgrav int sldns_wire2str_edns_subnet_print(char** s, size_t* sl, uint8_t* data, 219409a3aaf3SDag-Erling Smørgrav size_t len) 219509a3aaf3SDag-Erling Smørgrav { 219609a3aaf3SDag-Erling Smørgrav int w = 0; 219709a3aaf3SDag-Erling Smørgrav uint16_t family; 219809a3aaf3SDag-Erling Smørgrav uint8_t source, scope; 219909a3aaf3SDag-Erling Smørgrav if(len < 4) { 220009a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "malformed subnet "); 220109a3aaf3SDag-Erling Smørgrav w += print_hex_buf(s, sl, data, len); 220209a3aaf3SDag-Erling Smørgrav return w; 220309a3aaf3SDag-Erling Smørgrav } 220409a3aaf3SDag-Erling Smørgrav family = sldns_read_uint16(data); 220509a3aaf3SDag-Erling Smørgrav source = data[2]; 220609a3aaf3SDag-Erling Smørgrav scope = data[3]; 220709a3aaf3SDag-Erling Smørgrav if(family == 1) { 220809a3aaf3SDag-Erling Smørgrav /* IP4 */ 220909a3aaf3SDag-Erling Smørgrav char buf[64]; 221009a3aaf3SDag-Erling Smørgrav uint8_t ip4[4]; 221109a3aaf3SDag-Erling Smørgrav memset(ip4, 0, sizeof(ip4)); 221209a3aaf3SDag-Erling Smørgrav if(len-4 > 4) { 221309a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "trailingdata:"); 221409a3aaf3SDag-Erling Smørgrav w += print_hex_buf(s, sl, data+4+4, len-4-4); 221509a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, " "); 221609a3aaf3SDag-Erling Smørgrav len = 4+4; 221709a3aaf3SDag-Erling Smørgrav } 221809a3aaf3SDag-Erling Smørgrav memmove(ip4, data+4, len-4); 221909a3aaf3SDag-Erling Smørgrav if(!inet_ntop(AF_INET, ip4, buf, (socklen_t)sizeof(buf))) { 222009a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "ip4ntoperror "); 222109a3aaf3SDag-Erling Smørgrav w += print_hex_buf(s, sl, data+4+4, len-4-4); 222209a3aaf3SDag-Erling Smørgrav } else { 222309a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "%s", buf); 222409a3aaf3SDag-Erling Smørgrav } 222509a3aaf3SDag-Erling Smørgrav } else if(family == 2) { 222609a3aaf3SDag-Erling Smørgrav /* IP6 */ 222709a3aaf3SDag-Erling Smørgrav char buf[64]; 222809a3aaf3SDag-Erling Smørgrav uint8_t ip6[16]; 222909a3aaf3SDag-Erling Smørgrav memset(ip6, 0, sizeof(ip6)); 223009a3aaf3SDag-Erling Smørgrav if(len-4 > 16) { 223109a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "trailingdata:"); 223209a3aaf3SDag-Erling Smørgrav w += print_hex_buf(s, sl, data+4+16, len-4-16); 223309a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, " "); 223409a3aaf3SDag-Erling Smørgrav len = 4+16; 223509a3aaf3SDag-Erling Smørgrav } 223609a3aaf3SDag-Erling Smørgrav memmove(ip6, data+4, len-4); 223709a3aaf3SDag-Erling Smørgrav #ifdef AF_INET6 223809a3aaf3SDag-Erling Smørgrav if(!inet_ntop(AF_INET6, ip6, buf, (socklen_t)sizeof(buf))) { 223909a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "ip6ntoperror "); 224009a3aaf3SDag-Erling Smørgrav w += print_hex_buf(s, sl, data+4+4, len-4-4); 224109a3aaf3SDag-Erling Smørgrav } else { 224209a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "%s", buf); 224309a3aaf3SDag-Erling Smørgrav } 224409a3aaf3SDag-Erling Smørgrav #else 224509a3aaf3SDag-Erling Smørgrav w += print_hex_buf(s, sl, data+4+4, len-4-4); 224609a3aaf3SDag-Erling Smørgrav #endif 224709a3aaf3SDag-Erling Smørgrav } else { 224809a3aaf3SDag-Erling Smørgrav /* unknown */ 224909a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "family %d ", 225009a3aaf3SDag-Erling Smørgrav (int)family); 225109a3aaf3SDag-Erling Smørgrav w += print_hex_buf(s, sl, data, len); 225209a3aaf3SDag-Erling Smørgrav } 225309a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, "/%d scope /%d", (int)source, (int)scope); 225409a3aaf3SDag-Erling Smørgrav return w; 225509a3aaf3SDag-Erling Smørgrav } 225609a3aaf3SDag-Erling Smørgrav 2257e86b9096SDag-Erling Smørgrav static int sldns_wire2str_edns_keepalive_print(char** s, size_t* sl, 2258e86b9096SDag-Erling Smørgrav uint8_t* data, size_t len) 225965b390aaSDag-Erling Smørgrav { 226065b390aaSDag-Erling Smørgrav int w = 0; 226165b390aaSDag-Erling Smørgrav uint16_t timeout; 226265b390aaSDag-Erling Smørgrav if(!(len == 0 || len == 2)) { 226365b390aaSDag-Erling Smørgrav w += sldns_str_print(s, sl, "malformed keepalive "); 226465b390aaSDag-Erling Smørgrav w += print_hex_buf(s, sl, data, len); 226565b390aaSDag-Erling Smørgrav return w; 226665b390aaSDag-Erling Smørgrav } 226765b390aaSDag-Erling Smørgrav if(len == 0 ) { 226865b390aaSDag-Erling Smørgrav w += sldns_str_print(s, sl, "no timeout value (only valid for client option) "); 226965b390aaSDag-Erling Smørgrav } else { 227065b390aaSDag-Erling Smørgrav timeout = sldns_read_uint16(data); 227165b390aaSDag-Erling Smørgrav w += sldns_str_print(s, sl, "timeout value in units of 100ms %u", (int)timeout); 227265b390aaSDag-Erling Smørgrav } 227365b390aaSDag-Erling Smørgrav return w; 227465b390aaSDag-Erling Smørgrav } 227565b390aaSDag-Erling Smørgrav 2276103ba509SCy Schubert int sldns_wire2str_edns_ede_print(char** s, size_t* sl, 2277103ba509SCy Schubert uint8_t* data, size_t len) 2278103ba509SCy Schubert { 2279103ba509SCy Schubert uint16_t ede_code; 2280103ba509SCy Schubert int w = 0; 2281103ba509SCy Schubert sldns_lookup_table *lt; 2282103ba509SCy Schubert size_t i; 2283103ba509SCy Schubert int printable; 2284103ba509SCy Schubert 2285103ba509SCy Schubert if(len < 2) { 2286103ba509SCy Schubert w += sldns_str_print(s, sl, "malformed ede "); 2287103ba509SCy Schubert w += print_hex_buf(s, sl, data, len); 2288103ba509SCy Schubert return w; 2289103ba509SCy Schubert } 2290103ba509SCy Schubert 2291103ba509SCy Schubert ede_code = sldns_read_uint16(data); 2292103ba509SCy Schubert lt = sldns_lookup_by_id(sldns_edns_ede_codes, (int)ede_code); 2293103ba509SCy Schubert if(lt && lt->name) 2294103ba509SCy Schubert w += sldns_str_print(s, sl, "%s", lt->name); 2295103ba509SCy Schubert else w += sldns_str_print(s, sl, "%d", (int)ede_code); 2296103ba509SCy Schubert 2297103ba509SCy Schubert if(len == 2) 2298103ba509SCy Schubert return w; 2299103ba509SCy Schubert 2300103ba509SCy Schubert w += sldns_str_print(s, sl, " "); 2301103ba509SCy Schubert 2302103ba509SCy Schubert /* If it looks like text, show it as text. */ 2303103ba509SCy Schubert printable=1; 2304103ba509SCy Schubert for(i=2; i<len; i++) { 2305103ba509SCy Schubert if(isprint((unsigned char)data[i]) || data[i] == '\t') 2306103ba509SCy Schubert continue; 2307103ba509SCy Schubert printable = 0; 2308103ba509SCy Schubert break; 2309103ba509SCy Schubert } 2310103ba509SCy Schubert if(printable) { 2311103ba509SCy Schubert w += sldns_str_print(s, sl, "\""); 2312103ba509SCy Schubert for(i=2; i<len; i++) { 2313103ba509SCy Schubert w += str_char_print(s, sl, data[i]); 2314103ba509SCy Schubert } 2315103ba509SCy Schubert w += sldns_str_print(s, sl, "\""); 2316103ba509SCy Schubert } else { 2317103ba509SCy Schubert w += print_hex_buf(s, sl, data+2, len-2); 2318103ba509SCy Schubert } 2319103ba509SCy Schubert return w; 2320103ba509SCy Schubert } 2321103ba509SCy Schubert 232209a3aaf3SDag-Erling Smørgrav int sldns_wire2str_edns_option_print(char** s, size_t* sl, 232309a3aaf3SDag-Erling Smørgrav uint16_t option_code, uint8_t* optdata, size_t optlen) 232409a3aaf3SDag-Erling Smørgrav { 232509a3aaf3SDag-Erling Smørgrav int w = 0; 232609a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_edns_option_code_print(s, sl, option_code); 232709a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, ": "); 232809a3aaf3SDag-Erling Smørgrav switch(option_code) { 232909a3aaf3SDag-Erling Smørgrav case LDNS_EDNS_LLQ: 233009a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_edns_llq_print(s, sl, optdata, optlen); 233109a3aaf3SDag-Erling Smørgrav break; 233209a3aaf3SDag-Erling Smørgrav case LDNS_EDNS_UL: 233309a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_edns_ul_print(s, sl, optdata, optlen); 233409a3aaf3SDag-Erling Smørgrav break; 233509a3aaf3SDag-Erling Smørgrav case LDNS_EDNS_NSID: 233609a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_edns_nsid_print(s, sl, optdata, optlen); 233709a3aaf3SDag-Erling Smørgrav break; 233809a3aaf3SDag-Erling Smørgrav case LDNS_EDNS_DAU: 233909a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_edns_dau_print(s, sl, optdata, optlen); 234009a3aaf3SDag-Erling Smørgrav break; 234109a3aaf3SDag-Erling Smørgrav case LDNS_EDNS_DHU: 234209a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_edns_dhu_print(s, sl, optdata, optlen); 234309a3aaf3SDag-Erling Smørgrav break; 234409a3aaf3SDag-Erling Smørgrav case LDNS_EDNS_N3U: 234509a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_edns_n3u_print(s, sl, optdata, optlen); 234609a3aaf3SDag-Erling Smørgrav break; 234709a3aaf3SDag-Erling Smørgrav case LDNS_EDNS_CLIENT_SUBNET: 234809a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_edns_subnet_print(s, sl, optdata, optlen); 234909a3aaf3SDag-Erling Smørgrav break; 235065b390aaSDag-Erling Smørgrav case LDNS_EDNS_KEEPALIVE: 235165b390aaSDag-Erling Smørgrav w += sldns_wire2str_edns_keepalive_print(s, sl, optdata, optlen); 235265b390aaSDag-Erling Smørgrav break; 2353e2d15004SDag-Erling Smørgrav case LDNS_EDNS_PADDING: 2354e2d15004SDag-Erling Smørgrav w += print_hex_buf(s, sl, optdata, optlen); 2355e2d15004SDag-Erling Smørgrav break; 2356103ba509SCy Schubert case LDNS_EDNS_EDE: 2357103ba509SCy Schubert w += sldns_wire2str_edns_ede_print(s, sl, optdata, optlen); 2358103ba509SCy Schubert break; 235909a3aaf3SDag-Erling Smørgrav default: 236009a3aaf3SDag-Erling Smørgrav /* unknown option code */ 236109a3aaf3SDag-Erling Smørgrav w += print_hex_buf(s, sl, optdata, optlen); 236209a3aaf3SDag-Erling Smørgrav break; 236309a3aaf3SDag-Erling Smørgrav } 236409a3aaf3SDag-Erling Smørgrav return w; 236509a3aaf3SDag-Erling Smørgrav } 236609a3aaf3SDag-Erling Smørgrav 236709a3aaf3SDag-Erling Smørgrav /** print the edns options to string */ 236809a3aaf3SDag-Erling Smørgrav static int 236909a3aaf3SDag-Erling Smørgrav print_edns_opts(char** s, size_t* sl, uint8_t* rdata, size_t rdatalen) 237009a3aaf3SDag-Erling Smørgrav { 237109a3aaf3SDag-Erling Smørgrav uint16_t option_code, option_len; 237209a3aaf3SDag-Erling Smørgrav int w = 0; 237309a3aaf3SDag-Erling Smørgrav while(rdatalen > 0) { 237409a3aaf3SDag-Erling Smørgrav /* option name */ 237509a3aaf3SDag-Erling Smørgrav if(rdatalen < 4) { 237609a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, " ; malformed: "); 237709a3aaf3SDag-Erling Smørgrav w += print_hex_buf(s, sl, rdata, rdatalen); 237809a3aaf3SDag-Erling Smørgrav return w; 237909a3aaf3SDag-Erling Smørgrav } 238009a3aaf3SDag-Erling Smørgrav option_code = sldns_read_uint16(rdata); 238109a3aaf3SDag-Erling Smørgrav option_len = sldns_read_uint16(rdata+2); 238209a3aaf3SDag-Erling Smørgrav rdata += 4; 238309a3aaf3SDag-Erling Smørgrav rdatalen -= 4; 238409a3aaf3SDag-Erling Smørgrav 238509a3aaf3SDag-Erling Smørgrav /* option value */ 238609a3aaf3SDag-Erling Smørgrav if(rdatalen < (size_t)option_len) { 238709a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, " ; malformed "); 238809a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_edns_option_code_print(s, sl, 238909a3aaf3SDag-Erling Smørgrav option_code); 239009a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, ": "); 239109a3aaf3SDag-Erling Smørgrav w += print_hex_buf(s, sl, rdata, rdatalen); 239209a3aaf3SDag-Erling Smørgrav return w; 239309a3aaf3SDag-Erling Smørgrav } 239409a3aaf3SDag-Erling Smørgrav w += sldns_str_print(s, sl, " ; "); 239509a3aaf3SDag-Erling Smørgrav w += sldns_wire2str_edns_option_print(s, sl, option_code, 239609a3aaf3SDag-Erling Smørgrav rdata, option_len); 239709a3aaf3SDag-Erling Smørgrav rdata += option_len; 239809a3aaf3SDag-Erling Smørgrav rdatalen -= option_len; 239909a3aaf3SDag-Erling Smørgrav } 240009a3aaf3SDag-Erling Smørgrav return w; 240109a3aaf3SDag-Erling Smørgrav } 240209a3aaf3SDag-Erling Smørgrav 240309a3aaf3SDag-Erling Smørgrav int sldns_wire2str_edns_scan(uint8_t** data, size_t* data_len, char** str, 240409a3aaf3SDag-Erling Smørgrav size_t* str_len, uint8_t* pkt, size_t pktlen) 240509a3aaf3SDag-Erling Smørgrav { 240609a3aaf3SDag-Erling Smørgrav int w = 0; 240709a3aaf3SDag-Erling Smørgrav uint8_t ext_rcode, edns_version; 240809a3aaf3SDag-Erling Smørgrav uint16_t udpsize, edns_bits, rdatalen; 240909a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, str_len, "; EDNS:"); 241009a3aaf3SDag-Erling Smørgrav 241109a3aaf3SDag-Erling Smørgrav /* some input checks, domain name */ 241209a3aaf3SDag-Erling Smørgrav if(*data_len < 1+10) 241309a3aaf3SDag-Erling Smørgrav return w + print_remainder_hex("Error malformed 0x", 241409a3aaf3SDag-Erling Smørgrav data, data_len, str, str_len); 241509a3aaf3SDag-Erling Smørgrav if(*data[0] != 0) { 241609a3aaf3SDag-Erling Smørgrav return w + print_remainder_hex("Error nonrootdname 0x", 241709a3aaf3SDag-Erling Smørgrav data, data_len, str, str_len); 241809a3aaf3SDag-Erling Smørgrav } 241909a3aaf3SDag-Erling Smørgrav (*data)++; 242009a3aaf3SDag-Erling Smørgrav (*data_len)--; 242109a3aaf3SDag-Erling Smørgrav 242209a3aaf3SDag-Erling Smørgrav /* check type and read fixed contents */ 242309a3aaf3SDag-Erling Smørgrav if(sldns_read_uint16((*data)) != LDNS_RR_TYPE_OPT) { 242409a3aaf3SDag-Erling Smørgrav return w + print_remainder_hex("Error nottypeOPT 0x", 242509a3aaf3SDag-Erling Smørgrav data, data_len, str, str_len); 242609a3aaf3SDag-Erling Smørgrav } 242709a3aaf3SDag-Erling Smørgrav udpsize = sldns_read_uint16((*data)+2); 242809a3aaf3SDag-Erling Smørgrav ext_rcode = (*data)[4]; 242909a3aaf3SDag-Erling Smørgrav edns_version = (*data)[5]; 243009a3aaf3SDag-Erling Smørgrav edns_bits = sldns_read_uint16((*data)+6); 243109a3aaf3SDag-Erling Smørgrav rdatalen = sldns_read_uint16((*data)+8); 243209a3aaf3SDag-Erling Smørgrav (*data)+=10; 243309a3aaf3SDag-Erling Smørgrav (*data_len)-=10; 243409a3aaf3SDag-Erling Smørgrav 243509a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, str_len, " version: %u;", 243609a3aaf3SDag-Erling Smørgrav (unsigned)edns_version); 243709a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, str_len, " flags:"); 243809a3aaf3SDag-Erling Smørgrav if((edns_bits & LDNS_EDNS_MASK_DO_BIT)) 243909a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, str_len, " do"); 244009a3aaf3SDag-Erling Smørgrav /* the extended rcode is the value set, shifted four bits, 244109a3aaf3SDag-Erling Smørgrav * and or'd with the original rcode */ 244209a3aaf3SDag-Erling Smørgrav if(ext_rcode) { 244309a3aaf3SDag-Erling Smørgrav int rc = ((int)ext_rcode)<<4; 244409a3aaf3SDag-Erling Smørgrav if(pkt && pktlen >= LDNS_HEADER_SIZE) 244509a3aaf3SDag-Erling Smørgrav rc |= LDNS_RCODE_WIRE(pkt); 244609a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, str_len, " ; ext-rcode: %d", rc); 244709a3aaf3SDag-Erling Smørgrav } 244809a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, str_len, " ; udp: %u", (unsigned)udpsize); 244909a3aaf3SDag-Erling Smørgrav 245009a3aaf3SDag-Erling Smørgrav if(rdatalen) { 2451bc892140SDag-Erling Smørgrav if((size_t)*data_len < rdatalen) { 245209a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, str_len, 245309a3aaf3SDag-Erling Smørgrav " ; Error EDNS rdata too short; "); 2454bc892140SDag-Erling Smørgrav rdatalen = (uint16_t)*data_len; 245509a3aaf3SDag-Erling Smørgrav } 245609a3aaf3SDag-Erling Smørgrav w += print_edns_opts(str, str_len, *data, rdatalen); 245709a3aaf3SDag-Erling Smørgrav (*data) += rdatalen; 245809a3aaf3SDag-Erling Smørgrav (*data_len) -= rdatalen; 245909a3aaf3SDag-Erling Smørgrav } 246009a3aaf3SDag-Erling Smørgrav w += sldns_str_print(str, str_len, "\n"); 246109a3aaf3SDag-Erling Smørgrav return w; 246209a3aaf3SDag-Erling Smørgrav } 2463