1 /*	$NetBSD: dns_rr_eq_sa.c,v 1.1.1.1 2009/06/23 10:08:43 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	dns_rr_eq_sa 3
6 /* SUMMARY
7 /*	compare resource record with socket address
8 /* SYNOPSIS
9 /*	#include <dns.h>
10 /*
11 /*	int	dns_rr_eq_sa(DNS_RR *rr, struct sockaddr *sa)
12 /*	DNS_RR	*rr;
13 /*	struct sockaddr *sa;
14 /*
15 /*	int	DNS_RR_EQ_SA(DNS_RR *rr, struct sockaddr *sa)
16 /*	DNS_RR	*rr;
17 /*	struct sockaddr *sa;
18 /* DESCRIPTION
19 /*	dns_rr_eq_sa() compares a DNS resource record with a socket
20 /*	address.  The result is non-zero when the resource type
21 /*	matches the socket address family, and when the network
22 /*	address information is identical.
23 /*
24 /*	DNS_RR_EQ_SA() is an unsafe macro version for those who live fast.
25 /*
26 /*	Arguments:
27 /* .IP rr
28 /*	DNS resource record pointer.
29 /* .IP sa
30 /*	Binary address pointer.
31 /* DIAGNOSTICS
32 /*	Panic: unknown socket address family.
33 /* LICENSE
34 /* .ad
35 /* .fi
36 /*	The Secure Mailer license must be distributed with this software.
37 /* AUTHOR(S)
38 /*	Wietse Venema
39 /*	IBM T.J. Watson Research
40 /*	P.O. Box 704
41 /*	Yorktown Heights, NY 10598, USA
42 /*--*/
43 
44 /* System libraries. */
45 
46 #include <sys_defs.h>
47 
48 /* Utility library. */
49 
50 #include <msg.h>
51 #include <sock_addr.h>
52 
53 /* DNS library. */
54 
55 #include <dns.h>
56 
57 /* dns_rr_eq_sa - compare resource record with socket address */
58 
59 int     dns_rr_eq_sa(DNS_RR *rr, struct sockaddr * sa)
60 {
61     const char *myname = "dns_rr_eq_sa";
62 
63     if (sa->sa_family == AF_INET) {
64 	return (rr->type == T_A
65 		&& SOCK_ADDR_IN_ADDR(sa).s_addr == IN_ADDR(rr->data).s_addr);
66 #ifdef HAS_IPV6
67     } else if (sa->sa_family == AF_INET6) {
68 	return (rr->type == T_AAAA
69 		&& memcmp((char *) &SOCK_ADDR_IN6_ADDR(sa),
70 			  rr->data, rr->data_len) == 0);
71 #endif
72     } else {
73 	msg_panic("%s: unsupported socket address family type: %d",
74 		  myname, sa->sa_family);
75     }
76 }
77 
78  /*
79   * Stand-alone test program.
80   */
81 #ifdef TEST
82 #include <vstream.h>
83 #include <myaddrinfo.h>
84 #include <inet_proto.h>
85 
86 static const char *myname;
87 
88 static NORETURN usage(void)
89 {
90     msg_fatal("usage: %s hostname address", myname);
91 }
92 
93 int     main(int argc, char **argv)
94 {
95     MAI_HOSTADDR_STR hostaddr;
96     DNS_RR *rr;
97     struct addrinfo *res0;
98     struct addrinfo *res1;
99     struct addrinfo *res;
100     int     aierr;
101 
102     myname = argv[0];
103 
104     if (argc < 3)
105 	usage();
106 
107     inet_proto_init(argv[0], INET_PROTO_NAME_ALL);
108 
109     while (*++argv) {
110 	if (argv[1] == 0)
111 	    usage();
112 
113 	if ((aierr = hostaddr_to_sockaddr(argv[1], (char *) 0, 0, &res1)) != 0)
114 	    msg_fatal("host address %s: %s", argv[1], MAI_STRERROR(aierr));
115 	if ((rr = dns_sa_to_rr(argv[1], 0, res1->ai_addr)) == 0)
116 	    msg_fatal("dns_sa_to_rr: %m");
117 	freeaddrinfo(res1);
118 
119 	if ((aierr = hostname_to_sockaddr(argv[0], (char *) 0, 0, &res0)) != 0)
120 	    msg_fatal("host name %s: %s", argv[0], MAI_STRERROR(aierr));
121 	for (res = res0; res != 0; res = res->ai_next) {
122 	    SOCKADDR_TO_HOSTADDR(res->ai_addr, res->ai_addrlen,
123 				 &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
124 	    vstream_printf("%s =?= %s\n", hostaddr.buf, argv[1]);
125 	    vstream_printf("tested by function: %s\n",
126 			   dns_rr_eq_sa(rr, res->ai_addr) ?
127 			   "yes" : "no");
128 	    vstream_printf("tested by macro:    %s\n",
129 			   DNS_RR_EQ_SA(rr, res->ai_addr) ?
130 			   "yes" : "no");
131 	}
132 	dns_rr_free(rr);
133 	freeaddrinfo(res0);
134 	vstream_fflush(VSTREAM_OUT);
135 	argv += 1;
136     }
137     return (0);
138 }
139 
140 #endif
141