Commit | Line | Data |
---|---|---|
76af9c49 IJ |
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 | } |