1/* $NetBSD$ */ 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 59int 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 86static const char *myname; 87 88static NORETURN usage(void) 89{ 90 msg_fatal("usage: %s hostname address", myname); 91} 92 93int 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