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