]>
Commit | Line | Data |
---|---|---|
6d7e8eda | 1 | /* Copyright (C) 1998-2023 Free Software Foundation, Inc. |
6591c335 | 2 | This file is part of the GNU C Library. |
6591c335 UD |
3 | |
4 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
5 | modify it under the terms of the GNU Lesser General Public |
6 | License as published by the Free Software Foundation; either | |
7 | version 2.1 of the License, or (at your option) any later version. | |
6591c335 UD |
8 | |
9 | The GNU C Library is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 12 | Lesser General Public License for more details. |
6591c335 | 13 | |
41bdb6e2 | 14 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 | 15 | License along with the GNU C Library; if not, see |
5a82c748 | 16 | <https://www.gnu.org/licenses/>. */ |
6591c335 UD |
17 | |
18 | /* | |
19 | Testing of some network related lookup functions. | |
20 | The system databases looked up are: | |
21 | - /etc/services | |
22 | - /etc/hosts | |
23 | - /etc/networks | |
24 | - /etc/protocols | |
6591c335 UD |
25 | The tests try to be fairly generic and simple so that they work on |
26 | every possible setup (and might therefore not detect some possible | |
27 | errors). | |
28 | */ | |
29 | ||
30 | #include <netdb.h> | |
6591c335 | 31 | #include <stdio.h> |
3e1f480e AJ |
32 | #include <stdlib.h> |
33 | #include <string.h> | |
6591c335 UD |
34 | #include <arpa/inet.h> |
35 | #include <netinet/in.h> | |
36 | #include <sys/param.h> | |
37 | #include <sys/socket.h> | |
da2d1bc5 | 38 | #include <unistd.h> |
9efc8b95 | 39 | #include <errno.h> |
da2d1bc5 | 40 | #include "nss.h" |
6591c335 | 41 | |
a3fe6a20 DD |
42 | #include <support/support.h> |
43 | ||
6591c335 | 44 | /* |
49c091e5 | 45 | The following define is necessary for glibc 2.0.6 |
6591c335 UD |
46 | */ |
47 | #ifndef INET6_ADDRSTRLEN | |
48 | # define INET6_ADDRSTRLEN 46 | |
49 | #endif | |
50 | ||
51 | int error_count; | |
52 | ||
d6f1fe47 | 53 | static void |
6591c335 UD |
54 | output_servent (const char *call, struct servent *sptr) |
55 | { | |
56 | char **pptr; | |
57 | ||
58 | if (sptr == NULL) | |
59 | printf ("Call: %s returned NULL\n", call); | |
60 | else | |
61 | { | |
62 | printf ("Call: %s, returned: s_name: %s, s_port: %d, s_proto: %s\n", | |
63 | call, sptr->s_name, ntohs(sptr->s_port), sptr->s_proto); | |
64 | for (pptr = sptr->s_aliases; *pptr != NULL; pptr++) | |
65 | printf (" alias: %s\n", *pptr); | |
66 | } | |
67 | } | |
68 | ||
69 | ||
d6f1fe47 | 70 | static void |
6591c335 UD |
71 | test_services (void) |
72 | { | |
73 | struct servent *sptr; | |
74 | ||
75 | sptr = getservbyname ("domain", "tcp"); | |
76 | output_servent ("getservbyname (\"domain\", \"tcp\")", sptr); | |
77 | ||
78 | sptr = getservbyname ("domain", "udp"); | |
79 | output_servent ("getservbyname (\"domain\", \"udp\")", sptr); | |
80 | ||
81 | sptr = getservbyname ("domain", NULL); | |
82 | output_servent ("getservbyname (\"domain\", NULL)", sptr); | |
83 | ||
84 | sptr = getservbyname ("not-existant", NULL); | |
85 | output_servent ("getservbyname (\"not-existant\", NULL)", sptr); | |
86 | ||
dc30f461 UD |
87 | /* This shouldn't return anything. */ |
88 | sptr = getservbyname ("", ""); | |
89 | output_servent ("getservbyname (\"\", \"\")", sptr); | |
90 | ||
91 | sptr = getservbyname ("", "tcp"); | |
92 | output_servent ("getservbyname (\"\", \"tcp\")", sptr); | |
93 | ||
6591c335 UD |
94 | sptr = getservbyport (htons(53), "tcp"); |
95 | output_servent ("getservbyport (htons(53), \"tcp\")", sptr); | |
96 | ||
97 | sptr = getservbyport (htons(53), NULL); | |
98 | output_servent ("getservbyport (htons(53), NULL)", sptr); | |
99 | ||
100 | sptr = getservbyport (htons(1), "udp"); /* shouldn't exist */ | |
101 | output_servent ("getservbyport (htons(1), \"udp\")", sptr); | |
102 | ||
103 | setservent (0); | |
104 | do | |
105 | { | |
106 | sptr = getservent (); | |
107 | output_servent ("getservent ()", sptr); | |
108 | } | |
109 | while (sptr != NULL); | |
110 | endservent (); | |
111 | } | |
112 | ||
113 | ||
d6f1fe47 | 114 | static void |
6591c335 UD |
115 | output_hostent (const char *call, struct hostent *hptr) |
116 | { | |
6591c335 UD |
117 | char **pptr; |
118 | char buf[INET6_ADDRSTRLEN]; | |
119 | ||
120 | if (hptr == NULL) | |
121 | printf ("Call: %s returned NULL\n", call); | |
122 | else | |
123 | { | |
124 | printf ("Call: %s returned: name: %s, addr_type: %d\n", | |
125 | call, hptr->h_name, hptr->h_addrtype); | |
43498f02 AS |
126 | if (hptr->h_aliases) |
127 | for (pptr = hptr->h_aliases; *pptr != NULL; pptr++) | |
128 | printf (" alias: %s\n", *pptr); | |
6591c335 UD |
129 | |
130 | for (pptr = hptr->h_addr_list; *pptr != NULL; pptr++) | |
131 | printf (" ip: %s\n", | |
132 | inet_ntop (hptr->h_addrtype, *pptr, buf, sizeof (buf))); | |
133 | } | |
134 | } | |
135 | ||
d6f1fe47 | 136 | static void |
6591c335 UD |
137 | test_hosts (void) |
138 | { | |
139 | struct hostent *hptr1, *hptr2; | |
9efc8b95 RM |
140 | char *name = NULL; |
141 | size_t namelen = 0; | |
6591c335 UD |
142 | struct in_addr ip; |
143 | ||
144 | hptr1 = gethostbyname ("localhost"); | |
145 | hptr2 = gethostbyname ("LocalHost"); | |
146 | if (hptr1 != NULL || hptr2 != NULL) | |
147 | { | |
148 | if (hptr1 == NULL) | |
149 | { | |
150 | printf ("localhost not found - but LocalHost found:-(\n"); | |
151 | ++error_count; | |
152 | } | |
153 | else if (hptr2 == NULL) | |
154 | { | |
155 | printf ("LocalHost not found - but localhost found:-(\n"); | |
156 | ++error_count; | |
157 | } | |
158 | else if (strcmp (hptr1->h_name, hptr2->h_name) != 0) | |
159 | { | |
160 | printf ("localhost and LocalHost have different canoncial name\n"); | |
161 | printf ("gethostbyname (\"localhost\")->%s\n", hptr1->h_name); | |
162 | printf ("gethostbyname (\"LocalHost\")->%s\n", hptr2->h_name); | |
163 | ++error_count; | |
164 | } | |
165 | else | |
166 | output_hostent ("gethostbyname(\"localhost\")", hptr1); | |
167 | } | |
168 | ||
dc30f461 UD |
169 | hptr1 = gethostbyname ("127.0.0.1"); |
170 | output_hostent ("gethostbyname (\"127.0.0.1\")", hptr1); | |
171 | ||
16b0f634 UD |
172 | hptr1 = gethostbyname ("10.1234"); |
173 | output_hostent ("gethostbyname (\"10.1234\")", hptr1); | |
174 | ||
dc30f461 UD |
175 | hptr1 = gethostbyname2 ("localhost", AF_INET); |
176 | output_hostent ("gethostbyname2 (\"localhost\", AF_INET)", hptr1); | |
6591c335 | 177 | |
9efc8b95 RM |
178 | while (gethostname (name, namelen) < 0 && errno == ENAMETOOLONG) |
179 | { | |
180 | namelen += 2; /* tiny increments to test a lot */ | |
a3fe6a20 | 181 | name = xrealloc (name, namelen); |
9efc8b95 | 182 | } |
6591c335 UD |
183 | if (gethostname (name, namelen) == 0) |
184 | { | |
185 | printf ("Hostname: %s\n", name); | |
bb84d3b3 UD |
186 | if (name != NULL) |
187 | { | |
188 | hptr1 = gethostbyname (name); | |
189 | output_hostent ("gethostbyname (gethostname(...))", hptr1); | |
190 | } | |
6591c335 UD |
191 | } |
192 | ||
193 | ip.s_addr = htonl (INADDR_LOOPBACK); | |
c4f50205 | 194 | hptr1 = gethostbyaddr ((char *) &ip, sizeof (ip), AF_INET); |
6591c335 UD |
195 | if (hptr1 != NULL) |
196 | { | |
197 | printf ("official name of 127.0.0.1: %s\n", hptr1->h_name); | |
198 | } | |
199 | ||
200 | sethostent (0); | |
201 | do | |
202 | { | |
203 | hptr1 = gethostent (); | |
204 | output_hostent ("gethostent ()", hptr1); | |
205 | } | |
206 | while (hptr1 != NULL); | |
207 | endhostent (); | |
208 | ||
209 | } | |
210 | ||
211 | ||
d6f1fe47 | 212 | static void |
6591c335 UD |
213 | output_netent (const char *call, struct netent *nptr) |
214 | { | |
215 | char **pptr; | |
216 | ||
217 | if (nptr == NULL) | |
218 | printf ("Call: %s returned NULL\n", call); | |
219 | else | |
220 | { | |
221 | struct in_addr ip; | |
222 | ||
223 | ip.s_addr = htonl(nptr->n_net); | |
224 | printf ("Call: %s, returned: n_name: %s, network_number: %s\n", | |
225 | call, nptr->n_name, inet_ntoa (ip)); | |
226 | ||
227 | for (pptr = nptr->n_aliases; *pptr != NULL; pptr++) | |
228 | printf (" alias: %s\n", *pptr); | |
229 | } | |
230 | } | |
231 | ||
d6f1fe47 | 232 | static void |
6591c335 UD |
233 | test_network (void) |
234 | { | |
235 | struct netent *nptr; | |
d9fee042 | 236 | uint32_t ip; |
6591c335 UD |
237 | |
238 | /* | |
dc30f461 | 239 | This test needs the following line in /etc/networks: |
6591c335 UD |
240 | loopback 127.0.0.0 |
241 | */ | |
242 | nptr = getnetbyname ("loopback"); | |
243 | output_netent ("getnetbyname (\"loopback\")",nptr); | |
244 | ||
dc30f461 UD |
245 | nptr = getnetbyname ("LoopBACK"); |
246 | output_netent ("getnetbyname (\"LoopBACK\")",nptr); | |
247 | ||
6591c335 UD |
248 | ip = inet_network ("127.0.0.0"); |
249 | nptr = getnetbyaddr (ip, AF_INET); | |
250 | output_netent ("getnetbyaddr (inet_network (\"127.0.0.0\"), AF_INET)",nptr); | |
251 | ||
252 | setnetent (0); | |
253 | do | |
254 | { | |
255 | nptr = getnetent (); | |
256 | output_netent ("getnetent ()", nptr); | |
257 | } | |
258 | while (nptr != NULL); | |
259 | endnetent (); | |
260 | } | |
261 | ||
262 | ||
d6f1fe47 | 263 | static void |
6591c335 UD |
264 | output_protoent (const char *call, struct protoent *prptr) |
265 | { | |
266 | char **pptr; | |
267 | ||
268 | if (prptr == NULL) | |
269 | printf ("Call: %s returned NULL\n", call); | |
270 | else | |
271 | { | |
272 | printf ("Call: %s, returned: p_name: %s, p_proto: %d\n", | |
273 | call, prptr->p_name, prptr->p_proto); | |
274 | for (pptr = prptr->p_aliases; *pptr != NULL; pptr++) | |
275 | printf (" alias: %s\n", *pptr); | |
276 | } | |
277 | } | |
278 | ||
279 | ||
d6f1fe47 | 280 | static void |
6591c335 UD |
281 | test_protocols (void) |
282 | { | |
283 | struct protoent *prptr; | |
284 | ||
285 | prptr = getprotobyname ("IP"); | |
286 | output_protoent ("getprotobyname (\"IP\")", prptr); | |
287 | ||
288 | prptr = getprotobynumber (1); | |
289 | output_protoent ("getprotobynumber (1)", prptr); | |
290 | ||
291 | setprotoent (0); | |
292 | do | |
293 | { | |
294 | prptr = getprotoent (); | |
295 | output_protoent ("getprotoent ()", prptr); | |
296 | } | |
297 | while (prptr != NULL); | |
298 | endprotoent (); | |
299 | } | |
300 | ||
301 | ||
d6f1fe47 AJ |
302 | /* Override /etc/nsswitch.conf for this program. This is mainly |
303 | useful for developers. */ | |
304 | static void __attribute__ ((unused)) | |
6591c335 UD |
305 | setdb (const char *dbname) |
306 | { | |
307 | if (strcmp ("db", dbname)) | |
308 | { | |
309 | /* | |
310 | db is not implemented for hosts, networks | |
311 | */ | |
312 | __nss_configure_lookup ("hosts", dbname); | |
313 | __nss_configure_lookup ("networks", dbname); | |
314 | } | |
315 | __nss_configure_lookup ("protocols", dbname); | |
6591c335 UD |
316 | __nss_configure_lookup ("services", dbname); |
317 | } | |
318 | ||
319 | ||
29955b5d AS |
320 | static int |
321 | do_test (void) | |
6591c335 UD |
322 | { |
323 | /* | |
324 | setdb ("db"); | |
325 | */ | |
dc30f461 | 326 | |
6591c335 UD |
327 | test_hosts (); |
328 | test_network (); | |
329 | test_protocols (); | |
6591c335 UD |
330 | test_services (); |
331 | ||
332 | if (error_count) | |
49c091e5 | 333 | printf ("\n %d errors occurred!\n", error_count); |
6591c335 | 334 | else |
49c091e5 | 335 | printf ("No visible errors occurred!\n"); |
6591c335 | 336 | |
d6f1fe47 | 337 | return (error_count != 0); |
6591c335 | 338 | } |
29955b5d | 339 | |
a3fe6a20 | 340 | #include <support/test-driver.c> |