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