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