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