chiark / gitweb /
Update copyright dates
[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
25  *    Copyright (C) 1997-2000,2003,2006,2014-2016  Ian Jackson
26  *    Copyright (C) 2014  Mark Wooding
27  *    Copyright (C) 1999-2000,2003,2006  Tony Finch
28  *    Copyright (C) 1991 Massachusetts Institute of Technology
29  *  (See the file INSTALL for full details.)
30  *  
31  *  This program is free software; you can redistribute it and/or modify
32  *  it under the terms of the GNU General Public License as published by
33  *  the Free Software Foundation; either version 3, or (at your option)
34  *  any later version.
35  *  
36  *  This program is distributed in the hope that it will be useful,
37  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
38  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
39  *  GNU General Public License for more details.
40  *  
41  *  You should have received a copy of the GNU General Public License
42  *  along with this program; if not, write to the Free Software Foundation.
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 }