Branch data Line data Source code
1 : : /* Test the getaddrinfo module.
2 : :
3 : : Copyright (C) 2006-2012 Free Software Foundation, Inc.
4 : :
5 : : This program is free software: you can redistribute it and/or modify
6 : : it under the terms of the GNU General Public License as published by
7 : : the Free Software Foundation; either version 3 of the License, or
8 : : (at your option) any later version.
9 : :
10 : : This program is distributed in the hope that it will be useful,
11 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : : GNU General Public License for more details.
14 : :
15 : : You should have received a copy of the GNU General Public License
16 : : along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 : :
18 : : /* Written by Simon Josefsson. */
19 : :
20 : : #include <config.h>
21 : :
22 : : #include <netdb.h>
23 : :
24 : : #include "signature.h"
25 : : SIGNATURE_CHECK (freeaddrinfo, void, (struct addrinfo *));
26 : : SIGNATURE_CHECK (gai_strerror, char const *, (int));
27 : : SIGNATURE_CHECK (getaddrinfo, int, (char const *, char const *,
28 : : struct addrinfo const *,
29 : : struct addrinfo **));
30 : :
31 : : #include <arpa/inet.h>
32 : : #include <errno.h>
33 : : #include <netinet/in.h>
34 : : #include <stdio.h>
35 : : #include <string.h>
36 : :
37 : : /* Whether to print debugging messages. */
38 : : #define ENABLE_DEBUGGING 0
39 : :
40 : : #if ENABLE_DEBUGGING
41 : : # define dbgprintf printf
42 : : #else
43 : : # define dbgprintf if (0) printf
44 : : #endif
45 : :
46 : : /* BeOS does not have AF_UNSPEC. */
47 : : #ifndef AF_UNSPEC
48 : : # define AF_UNSPEC 0
49 : : #endif
50 : :
51 : : #ifndef EAI_SERVICE
52 : : # define EAI_SERVICE 0
53 : : #endif
54 : :
55 : : static int
56 : 4 : simple (char const *host, char const *service)
57 : : {
58 : : char buf[BUFSIZ];
59 : : static int skip = 0;
60 : : struct addrinfo hints;
61 : : struct addrinfo *ai0, *ai;
62 : : int res;
63 : : int err;
64 : :
65 : : /* Once we skipped the test, do not try anything else */
66 [ - + ]: 4 : if (skip)
67 : 0 : return 0;
68 : :
69 : : dbgprintf ("Finding %s service %s...\n", host, service);
70 : :
71 : : /* This initializes "hints" but does not use it. Is there a reason
72 : : for this? If so, please fix this comment. */
73 : 4 : memset (&hints, 0, sizeof (hints));
74 : 4 : hints.ai_flags = AI_CANONNAME;
75 : 4 : hints.ai_family = AF_UNSPEC;
76 : 4 : hints.ai_socktype = SOCK_STREAM;
77 : :
78 : 4 : res = getaddrinfo (host, service, 0, &ai0);
79 : 4 : err = errno;
80 : :
81 : : dbgprintf ("res %d: %s\n", res, gai_strerror (res));
82 : :
83 [ - + ]: 4 : if (res != 0)
84 : : {
85 : : /* EAI_AGAIN is returned if no network is available. Don't fail
86 : : the test merely because someone is down the country on their
87 : : in-law's farm. */
88 [ # # ]: 0 : if (res == EAI_AGAIN)
89 : : {
90 : 0 : skip++;
91 : 0 : fprintf (stderr, "skipping getaddrinfo test: no network?\n");
92 : 0 : return 77;
93 : : }
94 : : /* IRIX reports EAI_NONAME for "https". Don't fail the test
95 : : merely because of this. */
96 [ # # ]: 0 : if (res == EAI_NONAME)
97 : 0 : return 0;
98 : : /* Solaris reports EAI_SERVICE for "http" and "https". Don't
99 : : fail the test merely because of this. */
100 [ # # ]: 0 : if (res == EAI_SERVICE)
101 : 0 : return 0;
102 : : #ifdef EAI_NODATA
103 : : /* AIX reports EAI_NODATA for "https". Don't fail the test
104 : : merely because of this. */
105 [ # # ]: 0 : if (res == EAI_NODATA)
106 : 0 : return 0;
107 : : #endif
108 : : /* Provide details if errno was set. */
109 [ # # ]: 0 : if (res == EAI_SYSTEM)
110 : 0 : fprintf (stderr, "system error: %s\n", strerror (err));
111 : :
112 : 0 : return 1;
113 : : }
114 : :
115 [ + + ]: 14 : for (ai = ai0; ai; ai = ai->ai_next)
116 : : {
117 : : dbgprintf ("\tflags %x\n", ai->ai_flags);
118 : : dbgprintf ("\tfamily %x\n", ai->ai_family);
119 : : dbgprintf ("\tsocktype %x\n", ai->ai_socktype);
120 : : dbgprintf ("\tprotocol %x\n", ai->ai_protocol);
121 : : dbgprintf ("\taddrlen %ld: ", (unsigned long) ai->ai_addrlen);
122 : : dbgprintf ("\tFound %s\n",
123 : : inet_ntop (ai->ai_family,
124 : : &((struct sockaddr_in *)
125 : : ai->ai_addr)->sin_addr,
126 : : buf, sizeof (buf) - 1));
127 : 10 : if (ai->ai_canonname)
128 : : dbgprintf ("\tFound %s...\n", ai->ai_canonname);
129 : :
130 : : {
131 : : char ipbuf[BUFSIZ];
132 : : char portbuf[BUFSIZ];
133 : :
134 : 10 : res = getnameinfo (ai->ai_addr, ai->ai_addrlen,
135 : : ipbuf, sizeof (ipbuf) - 1,
136 : : portbuf, sizeof (portbuf) - 1,
137 : : NI_NUMERICHOST|NI_NUMERICSERV);
138 : : dbgprintf ("\t\tgetnameinfo %d: %s\n", res, gai_strerror (res));
139 : : if (res == 0)
140 : : {
141 : : dbgprintf ("\t\tip %s\n", ipbuf);
142 : : dbgprintf ("\t\tport %s\n", portbuf);
143 : : }
144 : : }
145 : :
146 : : }
147 : :
148 : 4 : freeaddrinfo (ai0);
149 : :
150 : 4 : return 0;
151 : : }
152 : :
153 : : #define HOST1 "www.gnu.org"
154 : : #define SERV1 "http"
155 : : #define HOST2 "www.ibm.com"
156 : : #define SERV2 "https"
157 : : #define HOST3 "microsoft.com"
158 : : #define SERV3 "http"
159 : : #define HOST4 "google.org"
160 : : #define SERV4 "ldap"
161 : :
162 : 1 : int main (void)
163 : : {
164 : 2 : return simple (HOST1, SERV1)
165 : 1 : + simple (HOST2, SERV2)
166 : 1 : + simple (HOST3, SERV3)
167 : 1 : + simple (HOST4, SERV4);
168 : : }
|