1 /* $NetBSD: dns_sa_to_rr.c,v 1.2 2017/02/14 01:16:44 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* dns_sa_to_rr 3 6 /* SUMMARY 7 /* socket address to resource record 8 /* SYNOPSIS 9 /* #include <dns.h> 10 /* 11 /* DNS_RR *dns_sa_to_rr(hostname, pref, sa) 12 /* const char *hostname; 13 /* unsigned pref; 14 /* struct sockaddr *sa; 15 /* DESCRIPTION 16 /* dns_sa_to_rr() converts a socket address into a DNS resource record. 17 /* 18 /* Arguments: 19 /* .IP hostname 20 /* The resource record host name. This will be both the qname 21 /* and the rname in the synthetic DNS resource record. 22 /* .IP pref 23 /* The resource record MX host preference, if applicable. 24 /* .IP sa 25 /* Binary address. 26 /* DIAGNOSTICS 27 /* The result is a null pointer in case of problems, with the 28 /* errno variable set to indicate the problem type. 29 /* LICENSE 30 /* .ad 31 /* .fi 32 /* The Secure Mailer license must be distributed with this software. 33 /* AUTHOR(S) 34 /* Wietse Venema 35 /* IBM T.J. Watson Research 36 /* P.O. Box 704 37 /* Yorktown Heights, NY 10598, USA 38 /*--*/ 39 40 /* System libraries. */ 41 42 #include <sys_defs.h> 43 #include <errno.h> 44 45 /* Utility library. */ 46 47 #include <msg.h> 48 49 /* DNS library. */ 50 51 #include <dns.h> 52 53 /* dns_sa_to_rr - socket address to resource record */ 54 55 DNS_RR *dns_sa_to_rr(const char *hostname, unsigned pref, struct sockaddr *sa) 56 { 57 #define DUMMY_TTL 0 58 59 if (sa->sa_family == AF_INET) { 60 return (dns_rr_create(hostname, hostname, T_A, C_IN, DUMMY_TTL, pref, 61 (char *) &SOCK_ADDR_IN_ADDR(sa), 62 sizeof(SOCK_ADDR_IN_ADDR(sa)))); 63 #ifdef HAS_IPV6 64 } else if (sa->sa_family == AF_INET6) { 65 return (dns_rr_create(hostname, hostname, T_AAAA, C_IN, DUMMY_TTL, pref, 66 (char *) &SOCK_ADDR_IN6_ADDR(sa), 67 sizeof(SOCK_ADDR_IN6_ADDR(sa)))); 68 #endif 69 } else { 70 errno = EAFNOSUPPORT; 71 return (0); 72 } 73 } 74 75 /* 76 * Stand-alone test program. 77 */ 78 #ifdef TEST 79 #include <stdlib.h> 80 #include <vstream.h> 81 #include <myaddrinfo.h> 82 #include <inet_proto.h> 83 #include <mymalloc.h> 84 85 static const char *myname; 86 87 static NORETURN usage(void) 88 { 89 msg_fatal("usage: %s hostname", myname); 90 } 91 92 static int compare_family(const void *a, const void *b) 93 { 94 struct addrinfo *resa = *(struct addrinfo **) a; 95 struct addrinfo *resb = *(struct addrinfo **) b; 96 97 return (resa->ai_family - resb->ai_family); 98 } 99 100 int main(int argc, char **argv) 101 { 102 MAI_HOSTADDR_STR hostaddr; 103 struct addrinfo *res0; 104 struct addrinfo *res; 105 struct addrinfo **resv; 106 size_t len, n; 107 DNS_RR *rr; 108 int aierr; 109 110 myname = argv[0]; 111 if (argc < 2) 112 usage(); 113 114 inet_proto_init(argv[0], INET_PROTO_NAME_ALL); 115 116 while (*++argv) { 117 if ((aierr = hostname_to_sockaddr(argv[0], (char *) 0, 0, &res0)) != 0) 118 msg_fatal("%s: %s", argv[0], MAI_STRERROR(aierr)); 119 for (len = 0, res = res0; res != 0; res = res->ai_next) 120 len += 1; 121 resv = (struct addrinfo **) mymalloc(len * sizeof(*resv)); 122 for (len = 0, res = res0; res != 0; res = res->ai_next) 123 resv[len++] = res; 124 qsort((void *) resv, len, sizeof(*resv), compare_family); 125 for (n = 0; n < len; n++) { 126 if ((rr = dns_sa_to_rr(argv[0], 0, resv[n]->ai_addr)) == 0) 127 msg_fatal("dns_sa_to_rr: %m"); 128 if (dns_rr_to_pa(rr, &hostaddr) == 0) 129 msg_fatal("dns_rr_to_pa: %m"); 130 vstream_printf("%s -> %s\n", argv[0], hostaddr.buf); 131 vstream_fflush(VSTREAM_OUT); 132 dns_rr_free(rr); 133 } 134 freeaddrinfo(res0); 135 myfree((void *) resv); 136 } 137 return (0); 138 } 139 140 #endif 141