]> git.ipfire.org Git - thirdparty/cups.git/blame - scheduler/network.c
Add SSL + LDAP support (STR #1967)
[thirdparty/cups.git] / scheduler / network.c
CommitLineData
2123c23a 1/*
c9d3f842 2 * "$Id$"
2123c23a 3 *
4 * Network interface functions for the Common UNIX Printing System
5 * (CUPS) scheduler.
6 *
71fe79e8 7 * Copyright 1997-2006 by Easy Software Products, all rights reserved.
2123c23a 8 *
9 * These coded instructions, statements, and computer programs are the
10 * property of Easy Software Products and are protected by Federal
11 * copyright law. Distribution and use rights are outlined in the file
12 * "LICENSE" which should have been included with this file. If this
13 * file is missing or damaged please contact Easy Software Products
14 * at:
15 *
16 * Attn: CUPS Licensing Information
17 * Easy Software Products
18 * 44141 Airport View Drive, Suite 204
8650fcf2 19 * Hollywood, Maryland 20636 USA
2123c23a 20 *
edfd3c3d 21 * Voice: (301) 373-9600
2123c23a 22 * EMail: cups-info@cups.org
23 * WWW: http://www.cups.org
f3e786fc 24 *
25 * Contents:
26 *
27 * cupsdNetIFFind() - Find a network interface.
28 * cupsdNetIFFree() - Free the current network interface list.
29 * cupsdNetIFUpdate() - Update the network interface list as needed...
71fe79e8 30 * compare_netif() - Compare two network interfaces.
2123c23a 31 */
32
33/*
34 * Include necessary headers.
35 */
36
846f45a0 37#include <cups/http-private.h>
2123c23a 38#include "cupsd.h"
39
71fe79e8 40
41/*
42 * Local functions...
43 */
44
45static void cupsdNetIFFree(void);
46static int compare_netif(cupsd_netif_t *a, cupsd_netif_t *b);
47
48
2123c23a 49/*
f3e786fc 50 * 'cupsdNetIFFind()' - Find a network interface.
2123c23a 51 */
52
f3e786fc 53cupsd_netif_t * /* O - Network interface data */
54cupsdNetIFFind(const char *name) /* I - Name of interface */
2123c23a 55{
71fe79e8 56 cupsd_netif_t key; /* Search key */
2123c23a 57
58
59 /*
60 * Update the interface list as needed...
61 */
62
87c85a78 63 if (NetIFUpdate)
64 cupsdNetIFUpdate();
2123c23a 65
66 /*
67 * Search for the named interface...
68 */
69
71fe79e8 70 strlcpy(key.name, name, sizeof(key.name));
2123c23a 71
71fe79e8 72 return ((cupsd_netif_t *)cupsArrayFind(NetIFList, &key));
2123c23a 73}
74
75
76/*
589eb420 77 * 'cupsdNetIFFree()' - Free the current network interface list.
2123c23a 78 */
79
71fe79e8 80static void
589eb420 81cupsdNetIFFree(void)
2123c23a 82{
71fe79e8 83 cupsd_netif_t *current; /* Current interface in array */
2123c23a 84
85
86 /*
87 * Loop through the interface list and free all the records...
88 */
89
71fe79e8 90 for (current = (cupsd_netif_t *)cupsArrayFirst(NetIFList);
91 current;
92 current = (cupsd_netif_t *)cupsArrayNext(NetIFList))
2123c23a 93 {
71fe79e8 94 cupsArrayRemove(NetIFList, current);
95 free(current);
2123c23a 96 }
97}
98
99
100/*
589eb420 101 * 'cupsdNetIFUpdate()' - Update the network interface list as needed...
2123c23a 102 */
103
104void
589eb420 105cupsdNetIFUpdate(void)
2123c23a 106{
c7445b9f 107 int match; /* Matching address? */
589eb420 108 cupsd_listener_t *lis; /* Listen address */
71fe79e8 109 cupsd_netif_t *temp; /* New interface */
f3e786fc 110 struct ifaddrs *addrs, /* Interface address list */
111 *addr; /* Current interface address */
086c584d 112 http_addrlist_t *saddr; /* Current server address */
71fe79e8 113 char hostname[1024]; /* Hostname for address */
2123c23a 114
115
116 /*
87c85a78 117 * Only update the list if we need to...
2123c23a 118 */
119
87c85a78 120 if (!NetIFUpdate)
2123c23a 121 return;
122
87c85a78 123 NetIFUpdate = 0;
5fe35f41 124
2123c23a 125 /*
126 * Free the old interfaces...
127 */
128
589eb420 129 cupsdNetIFFree();
2123c23a 130
71fe79e8 131 /*
132 * Make sure we have an array...
133 */
134
135 if (!NetIFList)
136 NetIFList = cupsArrayNew((cups_array_func_t)compare_netif, NULL);
137
138 if (!NetIFList)
139 return;
140
2123c23a 141 /*
142 * Grab a new list of interfaces...
143 */
144
145 if (getifaddrs(&addrs) < 0)
146 return;
147
148 for (addr = addrs; addr != NULL; addr = addr->ifa_next)
149 {
150 /*
20264b99 151 * See if this interface address is IPv4 or IPv6...
2123c23a 152 */
153
20264b99 154 if (addr->ifa_addr == NULL ||
a09840c5 155 (addr->ifa_addr->sa_family != AF_INET
156#ifdef AF_INET6
157 && addr->ifa_addr->sa_family != AF_INET6
158#endif
159 ) ||
2123c23a 160 addr->ifa_netmask == NULL || addr->ifa_name == NULL)
161 continue;
162
163 /*
71fe79e8 164 * Try looking up the hostname for the address as needed...
2123c23a 165 */
166
71fe79e8 167 if (HostNameLookups)
168 httpAddrLookup((http_addr_t *)(addr->ifa_addr), hostname,
169 sizeof(hostname));
170 else
171 {
172 /*
173 * Map the default server address and localhost to the server name
174 * and localhost, respectively; for all other addresses, use the
175 * dotted notation...
176 */
2123c23a 177
71fe79e8 178 if (httpAddrLocalhost((http_addr_t *)(addr->ifa_addr)))
179 strcpy(hostname, "localhost");
180 else
181 {
182 for (saddr = ServerAddrs; saddr; saddr = saddr->next)
183 if (httpAddrEqual((http_addr_t *)(addr->ifa_addr), &(saddr->addr)))
184 break;
7776142f 185
71fe79e8 186 if (saddr)
187 strlcpy(hostname, ServerName, sizeof(hostname));
188 else
189 httpAddrString((http_addr_t *)(addr->ifa_addr), hostname,
190 sizeof(hostname));
191 }
192 }
7776142f 193
71fe79e8 194 /*
195 * Create a new address element...
196 */
7776142f 197
71fe79e8 198 if ((temp = calloc(1, sizeof(cupsd_netif_t) +
199 strlen(hostname))) == NULL)
200 break;
2123c23a 201
202 /*
71fe79e8 203 * Copy all of the information...
2123c23a 204 */
205
def978d5 206 strlcpy(temp->name, addr->ifa_name, sizeof(temp->name));
71fe79e8 207 strcpy(temp->hostname, hostname); /* Safe because hostname is allocated */
2123c23a 208
20264b99 209 if (addr->ifa_addr->sa_family == AF_INET)
210 {
211 /*
212 * Copy IPv4 addresses...
213 */
214
215 memcpy(&(temp->address), addr->ifa_addr, sizeof(struct sockaddr_in));
216 memcpy(&(temp->mask), addr->ifa_netmask, sizeof(struct sockaddr_in));
217
218 if (addr->ifa_dstaddr)
f3e786fc 219 memcpy(&(temp->broadcast), addr->ifa_dstaddr,
220 sizeof(struct sockaddr_in));
20264b99 221 }
a09840c5 222#ifdef AF_INET6
20264b99 223 else
224 {
225 /*
226 * Copy IPv6 addresses...
227 */
228
229 memcpy(&(temp->address), addr->ifa_addr, sizeof(struct sockaddr_in6));
230 memcpy(&(temp->mask), addr->ifa_netmask, sizeof(struct sockaddr_in6));
231
232 if (addr->ifa_dstaddr)
f3e786fc 233 memcpy(&(temp->broadcast), addr->ifa_dstaddr,
234 sizeof(struct sockaddr_in6));
20264b99 235 }
a09840c5 236#endif /* AF_INET6 */
2123c23a 237
d7a9de63 238 if (!(addr->ifa_flags & IFF_POINTOPOINT) &&
239 !httpAddrLocalhost(&(temp->address)))
2123c23a 240 temp->is_local = 1;
241
edd6ee99 242 /*
243 * Determine which port to use when advertising printers...
244 */
245
c7445b9f 246 for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
247 lis;
248 lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
edd6ee99 249 {
250 match = 0;
251
252 if (httpAddrAny(&(lis->address)))
253 match = 1;
254 else if (addr->ifa_addr->sa_family == AF_INET &&
255 lis->address.addr.sa_family == AF_INET &&
256 (lis->address.ipv4.sin_addr.s_addr &
257 temp->mask.ipv4.sin_addr.s_addr) ==
258 temp->address.ipv4.sin_addr.s_addr)
259 match = 1;
260#ifdef AF_INET6
261 else if (addr->ifa_addr->sa_family == AF_INET6 &&
262 lis->address.addr.sa_family == AF_INET6 &&
263 (lis->address.ipv6.sin6_addr.s6_addr[0] &
264 temp->mask.ipv6.sin6_addr.s6_addr[0]) ==
265 temp->address.ipv6.sin6_addr.s6_addr[0] &&
266 (lis->address.ipv6.sin6_addr.s6_addr[1] &
267 temp->mask.ipv6.sin6_addr.s6_addr[1]) ==
268 temp->address.ipv6.sin6_addr.s6_addr[1] &&
269 (lis->address.ipv6.sin6_addr.s6_addr[2] &
270 temp->mask.ipv6.sin6_addr.s6_addr[2]) ==
271 temp->address.ipv6.sin6_addr.s6_addr[2] &&
272 (lis->address.ipv6.sin6_addr.s6_addr[3] &
273 temp->mask.ipv6.sin6_addr.s6_addr[3]) ==
274 temp->address.ipv6.sin6_addr.s6_addr[3])
275 match = 1;
276#endif /* AF_INET6 */
277
278 if (match)
279 {
280 if (lis->address.addr.sa_family == AF_INET)
281 temp->port = ntohs(lis->address.ipv4.sin_port);
282#ifdef AF_INET6
283 else if (lis->address.addr.sa_family == AF_INET6)
284 temp->port = ntohs(lis->address.ipv6.sin6_port);
285#endif /* AF_INET6 */
286 break;
287 }
288 }
289
2123c23a 290 /*
71fe79e8 291 * Add it to the array...
2123c23a 292 */
293
71fe79e8 294 cupsArrayAdd(NetIFList, temp);
40e67cda 295
296 cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdNetIFUpdate: \"%s\" = %s...",
297 temp->name, temp->hostname);
2123c23a 298 }
299
300 freeifaddrs(addrs);
301}
302
303
71fe79e8 304/*
305 * 'compare_netif()' - Compare two network interfaces.
306 */
307
308static int /* O - Result of comparison */
309compare_netif(cupsd_netif_t *a, /* I - First network interface */
310 cupsd_netif_t *b) /* I - Second network interface */
311{
312 return (strcmp(a->name, b->name));
313}
314
315
2123c23a 316/*
c9d3f842 317 * End of "$Id$".
2123c23a 318 */