]>
Commit | Line | Data |
---|---|---|
e92958ad | 1 | /* |
64bbab09 | 2 | * "$Id: http-addr.c,v 1.1.2.12 2004/02/25 16:58:32 mike Exp $" |
e92958ad | 3 | * |
4 | * HTTP address routines for the Common UNIX Printing System (CUPS). | |
5 | * | |
1d9595ab | 6 | * Copyright 1997-2003 by Easy Software Products, all rights reserved. |
e92958ad | 7 | * |
8 | * These coded instructions, statements, and computer programs are the | |
9 | * property of Easy Software Products and are protected by Federal | |
10 | * copyright law. Distribution and use rights are outlined in the file | |
11 | * "LICENSE.txt" which should have been included with this file. If this | |
12 | * file is missing or damaged please contact Easy Software Products | |
13 | * at: | |
14 | * | |
15 | * Attn: CUPS Licensing Information | |
16 | * Easy Software Products | |
17 | * 44141 Airport View Drive, Suite 204 | |
18 | * Hollywood, Maryland 20636-3111 USA | |
19 | * | |
20 | * Voice: (301) 373-9603 | |
21 | * EMail: cups-info@cups.org | |
22 | * WWW: http://www.cups.org | |
23 | * | |
24 | * Contents: | |
25 | * | |
0f71c41e | 26 | * httpAddrAny() - Check for the "any" address. |
e92958ad | 27 | * httpAddrEqual() - Compare two addresses. |
28 | * httpAddrLoad() - Load a host entry address into an HTTP address. | |
29 | * httpAddrLocalhost() - Check for the local loopback address. | |
30 | * httpAddrLookup() - Lookup the hostname associated with the address. | |
31 | * httpAddrString() - Convert an IP address to a dotted string. | |
365cfbcc | 32 | * httpGetHostByName() - Lookup a hostname or IP address, and return |
33 | * address records for the specified name. | |
e92958ad | 34 | */ |
35 | ||
36 | /* | |
37 | * Include necessary headers... | |
38 | */ | |
39 | ||
40 | #include "http.h" | |
41 | #include "debug.h" | |
42 | #include "string.h" | |
43 | ||
44 | ||
0f71c41e | 45 | /* |
46 | * 'httpAddrAny()' - Check for the "any" address. | |
47 | */ | |
48 | ||
49 | int /* O - 1 if "any", 0 otherwise */ | |
50 | httpAddrAny(const http_addr_t *addr) /* I - Address to check */ | |
51 | { | |
52 | #ifdef AF_INET6 | |
53 | if (addr->addr.sa_family == AF_INET6 && | |
54 | IN6_IS_ADDR_UNSPECIFIED(&(addr->ipv6.sin6_addr))) | |
55 | return (1); | |
56 | #endif /* AF_INET6 */ | |
57 | ||
58 | if (addr->addr.sa_family == AF_INET && | |
59 | ntohl(addr->ipv4.sin_addr.s_addr) == 0x00000000) | |
60 | return (1); | |
61 | ||
62 | return (0); | |
63 | } | |
64 | ||
65 | ||
e92958ad | 66 | /* |
67 | * 'httpAddrEqual()' - Compare two addresses. | |
68 | */ | |
69 | ||
70 | int /* O - 1 if equal, 0 if != */ | |
71 | httpAddrEqual(const http_addr_t *addr1, /* I - First address */ | |
72 | const http_addr_t *addr2) /* I - Second address */ | |
73 | { | |
74 | if (addr1->addr.sa_family != addr2->addr.sa_family) | |
75 | return (0); | |
76 | ||
77 | #ifdef AF_INET6 | |
78 | if (addr1->addr.sa_family == AF_INET6) | |
79 | return (memcmp(&(addr1->ipv6.sin6_addr), &(addr2->ipv6.sin6_addr), 16) == 0); | |
80 | #endif /* AF_INET6 */ | |
81 | ||
82 | return (addr1->ipv4.sin_addr.s_addr == addr2->ipv4.sin_addr.s_addr); | |
83 | } | |
84 | ||
85 | ||
86 | /* | |
87 | * 'httpAddrLoad()' - Load a host entry address into an HTTP address. | |
88 | */ | |
89 | ||
90 | void | |
91 | httpAddrLoad(const struct hostent *host, /* I - Host entry */ | |
92 | int port, /* I - Port number */ | |
93 | int n, /* I - Index into host entry */ | |
94 | http_addr_t *addr) /* O - Address to load */ | |
95 | { | |
96 | #ifdef AF_INET6 | |
97 | if (host->h_addrtype == AF_INET6) | |
98 | { | |
99 | # ifdef WIN32 | |
100 | addr->ipv6.sin6_port = htons((u_short)port); | |
101 | # else | |
102 | addr->ipv6.sin6_port = htons(port); | |
103 | # endif /* WIN32 */ | |
104 | ||
105 | memcpy((char *)&(addr->ipv6.sin6_addr), host->h_addr_list[n], | |
106 | host->h_length); | |
ed093015 | 107 | addr->ipv6.sin6_family = AF_INET6; |
e92958ad | 108 | } |
109 | else | |
110 | #endif /* AF_INET6 */ | |
111 | { | |
112 | # ifdef WIN32 | |
113 | addr->ipv4.sin_port = htons((u_short)port); | |
114 | # else | |
115 | addr->ipv4.sin_port = htons(port); | |
116 | # endif /* WIN32 */ | |
117 | ||
118 | memcpy((char *)&(addr->ipv4.sin_addr), host->h_addr_list[n], | |
119 | host->h_length); | |
ed093015 | 120 | addr->ipv4.sin_family = AF_INET; |
e92958ad | 121 | } |
122 | } | |
123 | ||
124 | ||
125 | /* | |
126 | * 'httpAddrLocalhost()' - Check for the local loopback address. | |
127 | */ | |
128 | ||
0f71c41e | 129 | int /* O - 1 if local host, 0 otherwise */ |
130 | httpAddrLocalhost(const http_addr_t *addr) | |
131 | /* I - Address to check */ | |
e92958ad | 132 | { |
133 | #ifdef AF_INET6 | |
134 | if (addr->addr.sa_family == AF_INET6 && | |
135 | IN6_IS_ADDR_LOOPBACK(&(addr->ipv6.sin6_addr))) | |
136 | return (1); | |
137 | #endif /* AF_INET6 */ | |
138 | ||
139 | if (addr->addr.sa_family == AF_INET && | |
140 | ntohl(addr->ipv4.sin_addr.s_addr) == 0x7f000001) | |
141 | return (1); | |
142 | ||
143 | return (0); | |
144 | } | |
145 | ||
146 | ||
147 | #ifdef __sgi | |
148 | # define ADDR_CAST (struct sockaddr *) | |
149 | #else | |
150 | # define ADDR_CAST (char *) | |
151 | #endif /* __sgi */ | |
152 | ||
153 | ||
154 | /* | |
155 | * 'httpAddrLookup()' - Lookup the hostname associated with the address. | |
156 | */ | |
157 | ||
158 | char * /* O - Host name */ | |
159 | httpAddrLookup(const http_addr_t *addr, /* I - Address to lookup */ | |
160 | char *name, /* I - Host name buffer */ | |
161 | int namelen) /* I - Size of name buffer */ | |
162 | { | |
163 | struct hostent *host; /* Host from name service */ | |
164 | ||
165 | ||
166 | #ifdef AF_INET6 | |
167 | if (addr->addr.sa_family == AF_INET6) | |
168 | host = gethostbyaddr(ADDR_CAST &(addr->ipv6.sin6_addr), | |
169 | sizeof(struct in6_addr), AF_INET6); | |
170 | else | |
171 | #endif /* AF_INET6 */ | |
172 | if (addr->addr.sa_family == AF_INET) | |
173 | host = gethostbyaddr(ADDR_CAST &(addr->ipv4.sin_addr), | |
174 | sizeof(struct in_addr), AF_INET); | |
175 | else | |
176 | host = NULL; | |
177 | ||
178 | if (host == NULL) | |
179 | { | |
180 | httpAddrString(addr, name, namelen); | |
181 | return (NULL); | |
182 | } | |
183 | ||
184 | strncpy(name, host->h_name, namelen - 1); | |
185 | name[namelen - 1] = '\0'; | |
186 | ||
187 | return (name); | |
188 | } | |
189 | ||
190 | ||
191 | /* | |
192 | * 'httpAddrString()' - Convert an IP address to a dotted string. | |
193 | */ | |
194 | ||
195 | char * /* O - IP string */ | |
196 | httpAddrString(const http_addr_t *addr, /* I - Address to convert */ | |
197 | char *s, /* I - String buffer */ | |
198 | int slen) /* I - Length of string */ | |
199 | { | |
200 | #ifdef AF_INET6 | |
201 | if (addr->addr.sa_family == AF_INET6) | |
202 | snprintf(s, slen, "%u.%u.%u.%u", | |
203 | ntohl(addr->ipv6.sin6_addr.s6_addr32[0]), | |
204 | ntohl(addr->ipv6.sin6_addr.s6_addr32[1]), | |
205 | ntohl(addr->ipv6.sin6_addr.s6_addr32[2]), | |
206 | ntohl(addr->ipv6.sin6_addr.s6_addr32[3])); | |
207 | else | |
208 | #endif /* AF_INET6 */ | |
209 | if (addr->addr.sa_family == AF_INET) | |
210 | { | |
211 | unsigned temp; /* Temporary address */ | |
212 | ||
213 | ||
214 | temp = ntohl(addr->ipv4.sin_addr.s_addr); | |
215 | ||
216 | snprintf(s, slen, "%d.%d.%d.%d", (temp >> 24) & 255, | |
217 | (temp >> 16) & 255, (temp >> 8) & 255, temp & 255); | |
218 | } | |
219 | else | |
220 | { | |
221 | strncpy(s, "UNKNOWN", slen - 1); | |
222 | s[slen - 1] = '\0'; | |
223 | } | |
224 | ||
225 | return (s); | |
226 | } | |
227 | ||
228 | ||
229 | /* | |
365cfbcc | 230 | * 'httpGetHostByName()' - Lookup a hostname or IP address, and return |
231 | * address records for the specified name. | |
232 | */ | |
233 | ||
234 | struct hostent * /* O - Host entry */ | |
235 | httpGetHostByName(const char *name) /* I - Hostname or IP address */ | |
236 | { | |
237 | const char *nameptr; /* Pointer into name */ | |
238 | unsigned ip[4]; /* IP address components */ | |
239 | static unsigned packed_ip; /* Packed IPv4 address */ | |
240 | static char *packed_ptr[2]; /* Pointer to packed address */ | |
241 | static struct hostent host_ip; /* Host entry for IP address */ | |
242 | ||
6db7190f | 243 | |
365cfbcc | 244 | #if defined(__APPLE__) |
245 | /* OS X hack to avoid it's ocassional long delay in lookupd */ | |
6db7190f | 246 | static const char sLoopback[] = "127.0.0.1"; |
365cfbcc | 247 | if (strcmp(name, "localhost") == 0) |
248 | name = sLoopback; | |
249 | #endif /* __APPLE__ */ | |
250 | ||
251 | /* | |
252 | * This function is needed because some operating systems have a | |
253 | * buggy implementation of gethostbyname() that does not support | |
254 | * IP addresses. If the first character of the name string is a | |
255 | * number, then sscanf() is used to extract the IP components. | |
256 | * We then pack the components into an IPv4 address manually, | |
257 | * since the inet_aton() function is deprecated. We use the | |
258 | * htonl() macro to get the right byte order for the address. | |
259 | */ | |
260 | ||
64bbab09 | 261 | for (nameptr = name; isdigit(*nameptr & 255) || *nameptr == '.'; nameptr ++); |
365cfbcc | 262 | |
263 | if (!*nameptr) | |
264 | { | |
265 | /* | |
266 | * We have an IP address; break it up and provide the host entry | |
267 | * to the caller. Currently only supports IPv4 addresses, although | |
268 | * it should be trivial to support IPv6 in CUPS 1.2. | |
269 | */ | |
270 | ||
271 | if (sscanf(name, "%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3) != 4) | |
272 | return (NULL); /* Must have 4 numbers */ | |
273 | ||
274 | packed_ip = htonl(((((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8) | ip[3])); | |
275 | ||
276 | /* | |
277 | * Fill in the host entry and return it... | |
278 | */ | |
279 | ||
280 | host_ip.h_name = (char *)name; | |
281 | host_ip.h_aliases = NULL; | |
282 | host_ip.h_addrtype = AF_INET; | |
283 | host_ip.h_length = 4; | |
284 | host_ip.h_addr_list = packed_ptr; | |
285 | packed_ptr[0] = (char *)(&packed_ip); | |
286 | packed_ptr[1] = NULL; | |
287 | ||
288 | return (&host_ip); | |
289 | } | |
290 | else | |
291 | { | |
292 | /* | |
293 | * Use the gethostbyname() function to get the IP address for | |
294 | * the name... | |
295 | */ | |
296 | ||
297 | return (gethostbyname(name)); | |
298 | } | |
299 | } | |
300 | ||
301 | ||
302 | /* | |
64bbab09 | 303 | * End of "$Id: http-addr.c,v 1.1.2.12 2004/02/25 16:58:32 mike Exp $". |
e92958ad | 304 | */ |