1/* $NetBSD: dns_strrecord.c,v 1.3 2023/12/23 20:30:43 christos Exp $ */ 2 3/*++ 4/* NAME 5/* dns_strrecord 3 6/* SUMMARY 7/* name service resource record printable forms 8/* SYNOPSIS 9/* #include <dns.h> 10/* 11/* char *dns_strrecord(buf, record) 12/* VSTRING *buf; 13/* DNS_RR *record; 14/* DESCRIPTION 15/* dns_strrecord() formats a DNS resource record as "name ttl 16/* class type preference value", where the class field is 17/* always "IN", the preference field exists only for MX records, 18/* and all names end in ".". The result value is the payload 19/* of the buffer argument. 20/* LICENSE 21/* .ad 22/* .fi 23/* The Secure Mailer license must be distributed with this software. 24/* AUTHOR(S) 25/* Wietse Venema 26/* IBM T.J. Watson Research 27/* P.O. Box 704 28/* Yorktown Heights, NY 10598, USA 29/* 30/* Wietse Venema 31/* Google, Inc. 32/* 111 8th Avenue 33/* New York, NY 10011, USA 34/*--*/ 35 36/* System library. */ 37 38#include <sys_defs.h> 39#include <string.h> /* memcpy */ 40 41/* Utility library. */ 42 43#include <vstring.h> 44#include <msg.h> 45 46/* DNS library. */ 47 48#include <dns.h> 49 50/* dns_strrecord - format resource record as generic string */ 51 52char *dns_strrecord(VSTRING *buf, DNS_RR *rr) 53{ 54 const char myname[] = "dns_strrecord"; 55 MAI_HOSTADDR_STR host; 56 UINT32_TYPE soa_buf[5]; 57 58 vstring_sprintf(buf, "%s. %u IN %s ", 59 rr->rname, rr->ttl, dns_strtype(rr->type)); 60 switch (rr->type) { 61 case T_A: 62#ifdef T_AAAA 63 case T_AAAA: 64#endif 65 if (dns_rr_to_pa(rr, &host) == 0) 66 msg_fatal("%s: conversion error for resource record type %s: %m", 67 myname, dns_strtype(rr->type)); 68 vstring_sprintf_append(buf, "%s", host.buf); 69 break; 70 case T_CNAME: 71 case T_DNAME: 72 case T_MB: 73 case T_MG: 74 case T_MR: 75 case T_NS: 76 case T_PTR: 77 vstring_sprintf_append(buf, "%s.", rr->data); 78 break; 79 case T_TXT: 80 vstring_sprintf_append(buf, "%s", rr->data); 81 break; 82 case T_MX: 83 vstring_sprintf_append(buf, "%u %s.", rr->pref, rr->data); 84 break; 85 case T_SRV: 86 vstring_sprintf_append(buf, "%u %u %u %s.", rr->pref, rr->weight, 87 rr->port, rr->data); 88 break; 89 case T_TLSA: 90 if (rr->data_len >= 3) { 91 uint8_t *ip = (uint8_t *) rr->data; 92 uint8_t usage = *ip++; 93 uint8_t selector = *ip++; 94 uint8_t mtype = *ip++; 95 unsigned i; 96 97 /* /\.example\. \d+ IN TLSA \d+ \d+ \d+ [\da-f]*$/ IGNORE */ 98 vstring_sprintf_append(buf, "%d %d %d ", usage, selector, mtype); 99 for (i = 3; i < rr->data_len; ++i) 100 vstring_sprintf_append(buf, "%02x", *ip++); 101 } else { 102 vstring_sprintf_append(buf, "[truncated record]"); 103 } 104 105 /* 106 * We use the SOA record TTL to determine the negative reply TTL. We 107 * save the time fields in the SOA record for debugging, but for now 108 * we don't bother saving the source host and mailbox information, as 109 * that would require changes to the DNS_RR structure. See also code 110 * in dns_get_rr(). 111 */ 112 case T_SOA: 113 memcpy(soa_buf, rr->data, sizeof(soa_buf)); 114 vstring_sprintf_append(buf, "- - %u %u %u %u %u", 115 soa_buf[0], soa_buf[1], soa_buf[2], 116 soa_buf[3], soa_buf[4]); 117 break; 118 default: 119 msg_fatal("%s: don't know how to print type %s", 120 myname, dns_strtype(rr->type)); 121 } 122 return (vstring_str(buf)); 123} 124