7 /* resource record to socket address
11 /* int dns_rr_to_sa(rr, port, sa, sa_length)
14 /* struct sockaddr *sa;
15 /* SOCKADDR_SIZE *sa_length;
17 /* dns_rr_to_sa() converts the address in a DNS resource record into
18 /* a socket address of the corresponding type.
22 /* DNS resource record pointer.
24 /* TCP or UDP port, network byte order.
26 /* Socket address pointer.
28 /* On input, the available socket address storage space.
29 /* On output, the amount of space actually used.
31 /* The result is non-zero in case of problems, with the
32 /* error type returned via the errno variable.
36 /* The Secure Mailer license must be distributed with this software.
39 /* IBM T.J. Watson Research
41 /* Yorktown Heights, NY 10598, USA
44 /* System libraries. */
49 /* Utility library. */
57 /* dns_rr_to_sa - resource record to socket address */
59 int dns_rr_to_sa(DNS_RR
*rr
, unsigned port
, struct sockaddr
* sa
,
60 SOCKADDR_SIZE
*sa_length
)
62 SOCKADDR_SIZE sock_addr_len
;
64 if (rr
->type
== T_A
) {
65 if (rr
->data_len
!= sizeof(SOCK_ADDR_IN_ADDR(sa
))) {
68 } else if ((sock_addr_len
= sizeof(*SOCK_ADDR_IN_PTR(sa
))) > *sa_length
) {
72 memset((char *) SOCK_ADDR_IN_PTR(sa
), 0, sock_addr_len
);
73 SOCK_ADDR_IN_FAMILY(sa
) = AF_INET
;
74 SOCK_ADDR_IN_PORT(sa
) = port
;
75 SOCK_ADDR_IN_ADDR(sa
) = IN_ADDR(rr
->data
);
77 sa
->sa_len
= sock_addr_len
;
79 *sa_length
= sock_addr_len
;
83 } else if (rr
->type
== T_AAAA
) {
84 if (rr
->data_len
!= sizeof(SOCK_ADDR_IN6_ADDR(sa
))) {
87 } else if ((sock_addr_len
= sizeof(*SOCK_ADDR_IN6_PTR(sa
))) > *sa_length
) {
91 memset((char *) SOCK_ADDR_IN6_PTR(sa
), 0, sock_addr_len
);
92 SOCK_ADDR_IN6_FAMILY(sa
) = AF_INET6
;
93 SOCK_ADDR_IN6_PORT(sa
) = port
;
94 SOCK_ADDR_IN6_ADDR(sa
) = IN6_ADDR(rr
->data
);
96 sa
->sa_len
= sock_addr_len
;
98 *sa_length
= sock_addr_len
;
103 errno
= EAFNOSUPPORT
;
109 * Stand-alone test program.
114 #include <stringops.h>
116 #include <myaddrinfo.h>
118 static const char *myname
;
120 static NORETURN
usage(void)
122 msg_fatal("usage: %s dnsaddrtype hostname portnumber", myname
);
125 int main(int argc
, char **argv
)
128 MAI_HOSTADDR_STR hostaddr
;
129 MAI_SERVPORT_STR portnum
;
130 struct sockaddr_storage ss
;
131 struct sockaddr
*sa
= (struct sockaddr
*) & ss
;
132 SOCKADDR_SIZE sa_length
= sizeof(ss
);
140 why
= vstring_alloc(1);
143 if (argv
[1] == 0 || argv
[2] == 0)
145 if ((type
= dns_type(argv
[0])) == 0)
147 if (!alldig(argv
[2]) || (port
= atoi(argv
[2])) > 65535)
149 if (dns_lookup(argv
[1], type
, 0, &rr
, (VSTRING
*) 0, why
) != DNS_OK
)
150 msg_fatal("%s: %s", argv
[1], vstring_str(why
));
151 sa_length
= sizeof(ss
);
152 if (dns_rr_to_sa(rr
, htons(port
), sa
, &sa_length
) != 0)
153 msg_fatal("dns_rr_to_sa: %m");
154 SOCKADDR_TO_HOSTADDR(sa
, sa_length
, &hostaddr
, &portnum
, 0);
155 vstream_printf("%s %s -> %s %s\n",
156 argv
[1], argv
[2], hostaddr
.buf
, portnum
.buf
);
157 vstream_fflush(VSTREAM_OUT
);