Commit | Line | Data |
---|---|---|
6c5ce29f IJ |
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 2, 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 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
43 | */ | |
44 | ||
45 | #include <sys/types.h> | |
46 | #include <sys/socket.h> | |
47 | #include <netdb.h> | |
48 | #include <stdbool.h> | |
49 | #include <string.h> | |
50 | #include <errno.h> | |
51 | #include <inttypes.h> | |
52 | ||
53 | #include "config.h" | |
54 | #include "adns.h" | |
55 | ||
56 | #define PORT 1234 | |
57 | ||
58 | #define STRING(x) STRING2(x) | |
59 | #define STRING2(x) #x | |
60 | ||
61 | static int fails; | |
62 | ||
63 | static void hex(const void *data_v, int l) { | |
64 | const uint8_t *data= data_v; | |
65 | int i; | |
66 | for (i=0; i<l; i++) | |
67 | printf("%02x",data[i]); | |
68 | } | |
69 | ||
70 | static void dump(const char *pfx, struct sockaddr *sa, socklen_t salen) { | |
71 | int i; | |
72 | printf(" %s: ",pfx); | |
73 | hex(sa, salen); | |
74 | ||
75 | for (i=0; i<salen; i++) | |
76 | printf("%02x",((const uint8_t*)sa)[i]); | |
77 | ||
78 | printf(" %d ", sa->sa_family); | |
79 | ||
80 | switch (sa->sa_family) { | |
81 | case AF_INET: { | |
82 | const struct sockaddr_in *s = (const void*)sa; | |
83 | printf(".port=%d .addr=%08"PRIx32"", | |
84 | ntohs(s->sin_port), | |
85 | (uint32_t)ntohl(s->sin_addr.s_addr)); | |
86 | break; | |
87 | } | |
88 | case AF_INET6: { | |
89 | const struct sockaddr_in6 *s = (const void*)sa; | |
90 | printf(".port=%d .flowinfo=%08"PRIx32" .scope_id=%08"PRIx32" .addr=", | |
91 | ntohs(s->sin6_port), | |
92 | (uint32_t)ntohl(s->sin6_flowinfo), | |
93 | (uint32_t)ntohl(s->sin6_scope_id)); | |
94 | hex(&s->sin6_addr, sizeof(s->sin6_addr)); | |
95 | break; | |
96 | } | |
97 | } | |
98 | printf("\n"); | |
99 | } | |
100 | ||
101 | static void dotest(const char *input) { | |
102 | adns_sockaddr ours; | |
103 | socklen_t socklen; | |
104 | struct addrinfo aip; | |
105 | struct addrinfo *air=0; | |
106 | char ourbuf[ADNS_ADDR2TEXT_BUFLEN]; | |
107 | char theirbuf[ADNS_ADDR2TEXT_BUFLEN]; | |
108 | ||
109 | memset(&ours,0,sizeof(ours)); | |
110 | ||
111 | socklen= sizeof(ours); | |
112 | int our_r= adns_text2addr(input,PORT,0,&ours.sa,&socklen); | |
113 | ||
114 | memset(&aip,0,sizeof(aip)); | |
115 | aip.ai_flags= AI_NUMERICHOST|AI_NUMERICSERV; | |
116 | aip.ai_socktype= SOCK_DGRAM; | |
117 | aip.ai_protocol= IPPROTO_UDP; | |
118 | air= 0; | |
119 | int libc_r= getaddrinfo(input,STRING(PORT),&aip,&air); | |
120 | printf("`%s': us %s; libc %s, air=%p", | |
121 | input, strerror(our_r), libc_r ? gai_strerror(libc_r) : "0", air); | |
122 | if (air) | |
123 | printf(" .family=%d .socklen=%ld .addr=%p .next=%p", | |
124 | air->ai_family, (long)air->ai_addrlen, air->ai_addr, air->ai_next); | |
125 | printf(":"); | |
126 | ||
127 | if (libc_r==EAI_NONAME && !air) { | |
128 | if (strchr(input,'%') && (our_r==ENOSYS || our_r==ENXIO)) { | |
129 | printf(" bad-scope"); | |
130 | goto ok; | |
131 | } | |
132 | if (strchr(input,'%') && our_r==ENOSYS) { | |
133 | printf(" bad-scope"); | |
134 | goto ok; | |
135 | } | |
136 | if (our_r==EINVAL) { | |
137 | printf(" invalid"); | |
138 | goto ok; | |
139 | } | |
140 | } | |
141 | printf(" valid"); | |
142 | ||
143 | #define FAIL do{ printf(" | FAIL\n"); fails++; }while(0) | |
144 | #define WANT(x) if (!(x)) { printf(" not %s",STRING(x)); FAIL; return; } else; | |
145 | ||
146 | WANT(!our_r); | |
147 | WANT(!libc_r); | |
148 | WANT(air); | |
149 | WANT(air->ai_addr); | |
150 | WANT(!air->ai_next); | |
151 | if (air->ai_addrlen!=socklen || memcmp(&ours,air->ai_addr,socklen)) { | |
152 | printf(" mismatch"); | |
153 | FAIL; | |
154 | dump("ours",&ours.sa,socklen); | |
155 | dump("libc",air->ai_addr,air->ai_addrlen); | |
156 | return; | |
157 | } | |
158 | ||
159 | printf(" |"); | |
160 | ||
161 | int ourbuflen= sizeof(ourbuf); | |
162 | int ourport; | |
163 | our_r= adns_addr2text(&ours.sa,0, ourbuf,&ourbuflen, &ourport); | |
164 | ||
165 | printf(" us %s",strerror(our_r)); | |
166 | if (!our_r) | |
167 | printf(" `%s'",ourbuf); | |
168 | ||
169 | size_t theirbuflen= sizeof(theirbuf); | |
170 | libc_r= getnameinfo(&ours.sa,socklen, theirbuf,theirbuflen, 0,0, | |
171 | NI_NUMERICHOST|NI_NUMERICSERV); | |
172 | printf("; libc %s", libc_r ? gai_strerror(libc_r) : "0"); | |
173 | if (!libc_r) | |
174 | printf(" `%s'",theirbuf); | |
175 | ||
176 | printf(":"); | |
177 | ||
178 | WANT(!our_r); | |
179 | WANT(!libc_r); | |
180 | WANT(ourport==PORT); | |
181 | if (strcmp(ourbuf,theirbuf)) { | |
182 | printf(" mismatch"); | |
183 | FAIL; | |
184 | return; | |
185 | } | |
186 | ||
187 | ok: | |
188 | printf(" | PASS\n"); | |
189 | } | |
190 | ||
191 | int main(int argc, char **argv) { | |
192 | const char *arg; | |
193 | while ((arg= *++argv)) { | |
194 | dotest(arg); | |
195 | } | |
196 | return !!fails; | |
197 | } |