1 /* $NetBSD: dns_sa_to_rr.c,v 1.3 2023/12/23 20:30:43 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
dns_sa_to_rr(const char * hostname,unsigned pref,struct sockaddr * sa)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_noport(hostname, hostname, T_A, C_IN, DUMMY_TTL,
61 pref, (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_noport(hostname, hostname, T_AAAA, C_IN, DUMMY_TTL,
66 pref, (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
usage(void)87 static NORETURN usage(void)
88 {
89 msg_fatal("usage: %s hostname", myname);
90 }
91
compare_family(const void * a,const void * b)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
main(int argc,char ** argv)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], DNS_RR_NOPREF, 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