Commit | Line | Data |
---|---|---|
5806b745 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 | |
7f8bbe29 | 32 | * the Free Software Foundation; either version 3, or (at your option) |
5806b745 IJ |
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 | |
8c09a4c6 | 41 | * along with this program; if not, write to the Free Software Foundation. |
5806b745 IJ |
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 | } |