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