1 /* $NetBSD: dns_rr_eq_sa.c,v 1.2 2017/02/14 01:16:44 christos 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((void *) &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 <stdlib.h> 83 #include <vstream.h> 84 #include <myaddrinfo.h> 85 #include <inet_proto.h> 86 #include <mymalloc.h> 87 88 static const char *myname; 89 90 static NORETURN usage(void) 91 { 92 msg_fatal("usage: %s hostname address", myname); 93 } 94 95 static int compare_family(const void *a, const void *b) 96 { 97 struct addrinfo *resa = *(struct addrinfo **) a; 98 struct addrinfo *resb = *(struct addrinfo **) b; 99 100 return (resa->ai_family - resb->ai_family); 101 } 102 103 int main(int argc, char **argv) 104 { 105 MAI_HOSTADDR_STR hostaddr; 106 DNS_RR *rr; 107 struct addrinfo *res0; 108 struct addrinfo *res1; 109 struct addrinfo *res; 110 struct addrinfo **resv; 111 size_t len, n; 112 int aierr; 113 114 myname = argv[0]; 115 116 if (argc < 3) 117 usage(); 118 119 inet_proto_init(argv[0], INET_PROTO_NAME_ALL); 120 121 while (*++argv) { 122 if (argv[1] == 0) 123 usage(); 124 125 if ((aierr = hostaddr_to_sockaddr(argv[1], (char *) 0, 0, &res1)) != 0) 126 msg_fatal("host address %s: %s", argv[1], MAI_STRERROR(aierr)); 127 if ((rr = dns_sa_to_rr(argv[1], 0, res1->ai_addr)) == 0) 128 msg_fatal("dns_sa_to_rr: %m"); 129 freeaddrinfo(res1); 130 131 if ((aierr = hostname_to_sockaddr(argv[0], (char *) 0, 0, &res0)) != 0) 132 msg_fatal("host name %s: %s", argv[0], MAI_STRERROR(aierr)); 133 for (len = 0, res = res0; res != 0; res = res->ai_next) 134 len += 1; 135 resv = (struct addrinfo **) mymalloc(len * sizeof(*resv)); 136 for (len = 0, res = res0; res != 0; res = res->ai_next) 137 resv[len++] = res; 138 qsort((void *) resv, len, sizeof(*resv), compare_family); 139 for (n = 0; n < len; n++) { 140 SOCKADDR_TO_HOSTADDR(resv[n]->ai_addr, resv[n]->ai_addrlen, 141 &hostaddr, (MAI_SERVPORT_STR *) 0, 0); 142 vstream_printf("%s =?= %s\n", hostaddr.buf, argv[1]); 143 vstream_printf("tested by function: %s\n", 144 dns_rr_eq_sa(rr, resv[n]->ai_addr) ? 145 "yes" : "no"); 146 vstream_printf("tested by macro: %s\n", 147 DNS_RR_EQ_SA(rr, resv[n]->ai_addr) ? 148 "yes" : "no"); 149 } 150 dns_rr_free(rr); 151 freeaddrinfo(res0); 152 myfree((void *) resv); 153 vstream_fflush(VSTREAM_OUT); 154 argv += 1; 155 } 156 return (0); 157 } 158 159 #endif 160