572ee0fa2ff6dc255fd99ed09e302d1483f1c3bb
[adns] / client / addrtext.c
1 /*
2 some test cases
3
4
5 ./addrtext_s fe80::1%wlanx
6 ./addrtext_s fe80::1%wlan0
7 ./addrtext_s fe80::1%23
8 ./addrtext_s fe80::1%1
9 ./addrtext_s 2001:ba8:1e3::%wlan0
10 ./addrtext_s 2001:ba8:1e3::%23
11 ./addrtext_s 2001:ba8:1e3::%1 # normally lo
12 ./addrtext_s 127.0.0.1x
13 ./addrtext_s 172.18.45.6
14 ./addrtext_s 12345
15
16
17 */
18
19 /*
20 * addrtext.c
21 * - test program for address<->string conversion, not part of the library
22 */
23 /*
24 * This file is part of adns, which is
25 * Copyright (C) 1997-2000,2003,2006,2014 Ian Jackson
26 * Copyright (C) 1999-2000,2003,2006 Tony Finch
27 * Copyright (C) 1991 Massachusetts Institute of Technology
28 * (See the file INSTALL for full details.)
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 3, or (at your option)
33 * any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License
41 * along with this program; if not, write to the Free Software Foundation.
42 */
43
44 #include <sys/types.h>
45 #include <sys/socket.h>
46 #include <netdb.h>
47 #include <stdbool.h>
48 #include <string.h>
49 #include <errno.h>
50 #include <inttypes.h>
51
52 #include "config.h"
53 #include "adns.h"
54
55 #define PORT 1234
56
57 #define STRING(x) STRING2(x)
58 #define STRING2(x) #x
59
60 static int fails;
61
62 static void hex(const void *data_v, int l) {
63 const uint8_t *data= data_v;
64 int i;
65 for (i=0; i<l; i++)
66 printf("%02x",data[i]);
67 }
68
69 static void dump(const char *pfx, struct sockaddr *sa, socklen_t salen) {
70 int i;
71 printf(" %s: ",pfx);
72 hex(sa, salen);
73
74 for (i=0; i<salen; i++)
75 printf("%02x",((const uint8_t*)sa)[i]);
76
77 printf(" %d ", sa->sa_family);
78
79 switch (sa->sa_family) {
80 case AF_INET: {
81 const struct sockaddr_in *s = (const void*)sa;
82 printf(".port=%d .addr=%08"PRIx32"",
83 ntohs(s->sin_port),
84 (uint32_t)ntohl(s->sin_addr.s_addr));
85 break;
86 }
87 case AF_INET6: {
88 const struct sockaddr_in6 *s = (const void*)sa;
89 printf(".port=%d .flowinfo=%08"PRIx32" .scope_id=%08"PRIx32" .addr=",
90 ntohs(s->sin6_port),
91 (uint32_t)ntohl(s->sin6_flowinfo),
92 (uint32_t)ntohl(s->sin6_scope_id));
93 hex(&s->sin6_addr, sizeof(s->sin6_addr));
94 break;
95 }
96 }
97 printf("\n");
98 }
99
100 static void dotest(const char *input) {
101 adns_sockaddr ours;
102 socklen_t socklen;
103 struct addrinfo aip;
104 struct addrinfo *air=0;
105 char ourbuf[ADNS_ADDR2TEXT_BUFLEN];
106 char theirbuf[ADNS_ADDR2TEXT_BUFLEN];
107
108 memset(&ours,0,sizeof(ours));
109
110 socklen= sizeof(ours);
111 int our_r= adns_text2addr(input,PORT,0,&ours.sa,&socklen);
112
113 memset(&aip,0,sizeof(aip));
114 aip.ai_flags= AI_NUMERICHOST|AI_NUMERICSERV;
115 aip.ai_socktype= SOCK_DGRAM;
116 aip.ai_protocol= IPPROTO_UDP;
117 air= 0;
118 int libc_r= getaddrinfo(input,STRING(PORT),&aip,&air);
119 printf("`%s': us %s; libc %s, air=%p",
120 input, strerror(our_r), libc_r ? gai_strerror(libc_r) : "0", air);
121 if (air)
122 printf(" .family=%d .socklen=%ld .addr=%p .next=%p",
123 air->ai_family, (long)air->ai_addrlen, air->ai_addr, air->ai_next);
124 printf(":");
125
126 if (libc_r==EAI_NONAME && !air) {
127 if (strchr(input,'%') && (our_r==ENOSYS || our_r==ENXIO)) {
128 printf(" bad-scope");
129 goto ok;
130 }
131 if (strchr(input,'%') && our_r==ENOSYS) {
132 printf(" bad-scope");
133 goto ok;
134 }
135 if (our_r==EINVAL) {
136 printf(" invalid");
137 goto ok;
138 }
139 }
140 printf(" valid");
141
142 #define FAIL do{ printf(" | FAIL\n"); fails++; }while(0)
143 #define WANT(x) if (!(x)) { printf(" not %s",STRING(x)); FAIL; return; } else;
144
145 WANT(!our_r);
146 WANT(!libc_r);
147 WANT(air);
148 WANT(air->ai_addr);
149 WANT(!air->ai_next);
150 if (air->ai_addrlen!=socklen || memcmp(&ours,air->ai_addr,socklen)) {
151 printf(" mismatch");
152 FAIL;
153 dump("ours",&ours.sa,socklen);
154 dump("libc",air->ai_addr,air->ai_addrlen);
155 return;
156 }
157
158 printf(" |");
159
160 int ourbuflen= sizeof(ourbuf);
161 int ourport;
162 our_r= adns_addr2text(&ours.sa,0, ourbuf,&ourbuflen, &ourport);
163
164 printf(" us %s",strerror(our_r));
165 if (!our_r)
166 printf(" `%s'",ourbuf);
167
168 size_t theirbuflen= sizeof(theirbuf);
169 libc_r= getnameinfo(&ours.sa,socklen, theirbuf,theirbuflen, 0,0,
170 NI_NUMERICHOST|NI_NUMERICSERV);
171 printf("; libc %s", libc_r ? gai_strerror(libc_r) : "0");
172 if (!libc_r)
173 printf(" `%s'",theirbuf);
174
175 printf(":");
176
177 WANT(!our_r);
178 WANT(!libc_r);
179 WANT(ourport==PORT);
180 if (strcmp(ourbuf,theirbuf)) {
181 printf(" mismatch");
182 FAIL;
183 return;
184 }
185
186 ok:
187 printf(" | PASS\n");
188 }
189
190 int main(int argc, char **argv) {
191 const char *arg;
192 while ((arg= *++argv)) {
193 dotest(arg);
194 }
195 return !!fails;
196 }