]> git.ipfire.org Git - thirdparty/cups.git/blame - scheduler/network.c
Load cups into easysw/current.
[thirdparty/cups.git] / scheduler / network.c
CommitLineData
ef416fc2 1/*
f7deaa1a 2 * "$Id: network.c 6086 2006-11-14 15:43:55Z mike $"
ef416fc2 3 *
4 * Network interface functions for the Common UNIX Printing System
5 * (CUPS) scheduler.
6 *
e00b005a 7 * Copyright 1997-2006 by Easy Software Products, all rights reserved.
ef416fc2 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
19 * Hollywood, Maryland 20636 USA
20 *
21 * Voice: (301) 373-9600
22 * EMail: cups-info@cups.org
23 * WWW: http://www.cups.org
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...
e00b005a 30 * compare_netif() - Compare two network interfaces.
ef416fc2 31 */
32
33/*
34 * Include necessary headers.
35 */
36
89d46774 37#include <cups/http-private.h>
ef416fc2 38#include "cupsd.h"
39
e00b005a 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
ef416fc2 49/*
50 * 'cupsdNetIFFind()' - Find a network interface.
51 */
52
53cupsd_netif_t * /* O - Network interface data */
54cupsdNetIFFind(const char *name) /* I - Name of interface */
55{
e00b005a 56 cupsd_netif_t key; /* Search key */
ef416fc2 57
58
59 /*
60 * Update the interface list as needed...
61 */
62
411affcf 63 if (NetIFUpdate)
64 cupsdNetIFUpdate();
ef416fc2 65
66 /*
67 * Search for the named interface...
68 */
69
e00b005a 70 strlcpy(key.name, name, sizeof(key.name));
ef416fc2 71
e00b005a 72 return ((cupsd_netif_t *)cupsArrayFind(NetIFList, &key));
ef416fc2 73}
74
75
76/*
77 * 'cupsdNetIFFree()' - Free the current network interface list.
78 */
79
e00b005a 80static void
ef416fc2 81cupsdNetIFFree(void)
82{
e00b005a 83 cupsd_netif_t *current; /* Current interface in array */
ef416fc2 84
85
86 /*
87 * Loop through the interface list and free all the records...
88 */
89
e00b005a 90 for (current = (cupsd_netif_t *)cupsArrayFirst(NetIFList);
91 current;
92 current = (cupsd_netif_t *)cupsArrayNext(NetIFList))
ef416fc2 93 {
e00b005a 94 cupsArrayRemove(NetIFList, current);
95 free(current);
ef416fc2 96 }
97}
98
99
100/*
101 * 'cupsdNetIFUpdate()' - Update the network interface list as needed...
102 */
103
104void
105cupsdNetIFUpdate(void)
106{
bd7854cb 107 int match; /* Matching address? */
ef416fc2 108 cupsd_listener_t *lis; /* Listen address */
e00b005a 109 cupsd_netif_t *temp; /* New interface */
ef416fc2 110 struct ifaddrs *addrs, /* Interface address list */
111 *addr; /* Current interface address */
112 http_addrlist_t *saddr; /* Current server address */
e00b005a 113 char hostname[1024]; /* Hostname for address */
ef416fc2 114
115
116 /*
411affcf 117 * Only update the list if we need to...
ef416fc2 118 */
119
411affcf 120 if (!NetIFUpdate)
ef416fc2 121 return;
122
411affcf 123 NetIFUpdate = 0;
ef416fc2 124
125 /*
126 * Free the old interfaces...
127 */
128
129 cupsdNetIFFree();
130
e00b005a 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
ef416fc2 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 /*
151 * See if this interface address is IPv4 or IPv6...
152 */
153
154 if (addr->ifa_addr == NULL ||
155 (addr->ifa_addr->sa_family != AF_INET
156#ifdef AF_INET6
157 && addr->ifa_addr->sa_family != AF_INET6
158#endif
159 ) ||
160 addr->ifa_netmask == NULL || addr->ifa_name == NULL)
161 continue;
162
163 /*
e00b005a 164 * Try looking up the hostname for the address as needed...
ef416fc2 165 */
166
e00b005a 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 */
ef416fc2 177
e00b005a 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;
ef416fc2 185
e00b005a 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 }
ef416fc2 193
e00b005a 194 /*
195 * Create a new address element...
196 */
ef416fc2 197
e00b005a 198 if ((temp = calloc(1, sizeof(cupsd_netif_t) +
199 strlen(hostname))) == NULL)
200 break;
ef416fc2 201
202 /*
e00b005a 203 * Copy all of the information...
ef416fc2 204 */
205
206 strlcpy(temp->name, addr->ifa_name, sizeof(temp->name));
e00b005a 207 strcpy(temp->hostname, hostname); /* Safe because hostname is allocated */
ef416fc2 208
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)
219 memcpy(&(temp->broadcast), addr->ifa_dstaddr,
220 sizeof(struct sockaddr_in));
221 }
222#ifdef AF_INET6
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)
233 memcpy(&(temp->broadcast), addr->ifa_dstaddr,
234 sizeof(struct sockaddr_in6));
235 }
236#endif /* AF_INET6 */
237
238 if (!(addr->ifa_flags & IFF_POINTOPOINT) &&
239 !httpAddrLocalhost(&(temp->address)))
240 temp->is_local = 1;
241
242 /*
243 * Determine which port to use when advertising printers...
244 */
245
bd7854cb 246 for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
247 lis;
248 lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
ef416fc2 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
290 /*
e00b005a 291 * Add it to the array...
ef416fc2 292 */
293
e00b005a 294 cupsArrayAdd(NetIFList, temp);
ef416fc2 295
296 cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdNetIFUpdate: \"%s\" = %s...",
297 temp->name, temp->hostname);
298 }
299
300 freeifaddrs(addrs);
301}
302
303
e00b005a 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
ef416fc2 316/*
f7deaa1a 317 * End of "$Id: network.c 6086 2006-11-14 15:43:55Z mike $".
ef416fc2 318 */