]> git.ipfire.org Git - thirdparty/dhcp.git/blame - common/dispatch.c
Change names of error functions to be more consistent.
[thirdparty/dhcp.git] / common / dispatch.c
CommitLineData
48d507a9 1/* dispatch.c
decf33c2 2
48d507a9 3 Network input dispatcher... */
decf33c2
TL
4
5/*
b25cbbad 6 * Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium.
decf33c2
TL
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of The Internet Software Consortium nor the names
19 * of its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * This software has been written for the Internet Software Consortium
37 * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
38 * Enterprises. To learn more about the Internet Software Consortium,
39 * see ``http://www.vix.com/isc''. To learn more about Vixie
40 * Enterprises, see ``http://www.vix.com''.
41 */
42
43#ifndef lint
44static char copyright[] =
8ae2d595 45"$Id: dispatch.c,v 1.53 1999/02/24 17:56:44 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
decf33c2
TL
46#endif /* not lint */
47
48#include "dhcpd.h"
decf33c2 49
e4749e75 50struct protocol *protocols;
6806c5ae
TL
51struct timeout *timeouts;
52static struct timeout *free_timeouts;
decf33c2 53
7d77172d 54int interfaces_invalidated;
decf33c2 55
9c5225a5 56#ifdef USE_POLL
b25cbbad
TL
57/* Wait for packets to come in using poll(). When a packet comes in,
58 call receive_packet to receive the packet and possibly strip hardware
59 addressing information from it, and then call through the
60 bootp_packet_handler hook to try to do something with it. */
9c5225a5 61
e4749e75 62void dispatch ()
9c5225a5 63{
e4749e75 64 struct protocol *l;
9c5225a5
TL
65 int nfds = 0;
66 struct pollfd *fds;
67 int count;
68 int i;
6806c5ae 69 int to_msec;
9c5225a5
TL
70
71 nfds = 0;
e4749e75 72 for (l = protocols; l; l = l -> next) {
9c5225a5
TL
73 ++nfds;
74 }
c5568eb5 75 fds = (struct pollfd *)malloc ((nfds) * sizeof (struct pollfd));
9c5225a5 76 if (!fds)
8ae2d595 77 log_fatal ("Can't allocate poll structures.");
9c5225a5 78
9c5225a5 79 do {
6806c5ae
TL
80 /* Call any expired timeouts, and then if there's
81 still a timeout registered, time out the select
82 call then. */
83 another:
84 if (timeouts) {
85 struct timeout *t;
86 if (timeouts -> when <= cur_time) {
87 t = timeouts;
88 timeouts = timeouts -> next;
9652af24 89 (*(t -> func)) (t -> what);
6806c5ae
TL
90 t -> next = free_timeouts;
91 free_timeouts = t;
92 goto another;
93 }
94 /* Figure timeout in milliseconds, and check for
95 potential overflow. We assume that integers
96 are 32 bits, which is harmless if they're 64
97 bits - we'll just get extra timeouts in that
98 case. Lease times would have to be quite
99 long in order for a 32-bit integer to overflow,
100 anyway. */
101 to_msec = timeouts -> when - cur_time;
102 if (to_msec > 2147483)
103 to_msec = 2147483;
104 to_msec *= 1000;
105 } else
106 to_msec = -1;
107
c3585217
TL
108 /* Set up the descriptors to be polled. */
109 i = 0;
e4749e75
TL
110 for (l = protocols; l; l = l -> next) {
111 fds [i].fd = l -> fd;
c3585217
TL
112 fds [i].events = POLLIN;
113 fds [i].revents = 0;
114 ++i;
115 }
116
9c5225a5 117 /* Wait for a packet or a timeout... XXX */
6806c5ae 118 count = poll (fds, nfds, to_msec);
9c5225a5
TL
119
120 /* Get the current time... */
121 GET_TIME (&cur_time);
122
123 /* Not likely to be transitory... */
73d0a743 124 if (count < 0) {
93ad415e 125 if (errno == EAGAIN || errno == EINTR)
73d0a743
TL
126 continue;
127 else
8ae2d595 128 log_fatal ("poll: %m");
73d0a743 129 }
9c5225a5
TL
130
131 i = 0;
e4749e75 132 for (l = protocols; l; l = l -> next) {
0c413cce
TL
133 if ((fds [i].revents & POLLIN)) {
134 fds [i].revents = 0;
e4749e75
TL
135 if (l -> handler)
136 (*(l -> handler)) (l);
c3585217
TL
137 if (interfaces_invalidated)
138 break;
0c413cce
TL
139 }
140 ++i;
9c5225a5 141 }
c3585217 142 interfaces_invalidated = 0;
9c5225a5
TL
143 } while (1);
144}
145#else
decf33c2
TL
146/* Wait for packets to come in using select(). When one does, call
147 receive_packet to receive the packet and possibly strip hardware
b25cbbad
TL
148 addressing information from it, and then call through the
149 bootp_packet_handler hook to try to do something with it. */
decf33c2 150
e4749e75 151void dispatch ()
decf33c2 152{
decf33c2 153 fd_set r, w, x;
e4749e75 154 struct protocol *l;
decf33c2
TL
155 int max = 0;
156 int count;
6806c5ae 157 struct timeval tv, *tvp;
decf33c2 158
decf33c2
TL
159 FD_ZERO (&w);
160 FD_ZERO (&x);
161
162 do {
6806c5ae
TL
163 /* Call any expired timeouts, and then if there's
164 still a timeout registered, time out the select
165 call then. */
166 another:
167 if (timeouts) {
168 struct timeout *t;
169 if (timeouts -> when <= cur_time) {
170 t = timeouts;
171 timeouts = timeouts -> next;
e4749e75 172 (*(t -> func)) (t -> what);
6806c5ae
TL
173 t -> next = free_timeouts;
174 free_timeouts = t;
175 goto another;
176 }
177 tv.tv_sec = timeouts -> when - cur_time;
178 tv.tv_usec = 0;
179 tvp = &tv;
180 } else
181 tvp = (struct timeval *)0;
182
c3585217
TL
183 /* Set up the read mask. */
184 FD_ZERO (&r);
185
e4749e75
TL
186 for (l = protocols; l; l = l -> next) {
187 FD_SET (l -> fd, &r);
e4749e75
TL
188 if (l -> fd > max)
189 max = l -> fd;
c3585217 190 }
c3585217 191
decf33c2 192 /* Wait for a packet or a timeout... XXX */
6806c5ae 193 count = select (max + 1, &r, &w, &x, tvp);
decf33c2
TL
194
195 /* Get the current time... */
196 GET_TIME (&cur_time);
197
198 /* Not likely to be transitory... */
199 if (count < 0)
8ae2d595 200 log_fatal ("select: %m");
decf33c2 201
e4749e75
TL
202 for (l = protocols; l; l = l -> next) {
203 if (!FD_ISSET (l -> fd, &r))
decf33c2 204 continue;
e4749e75
TL
205 if (l -> handler)
206 (*(l -> handler)) (l);
c3585217
TL
207 if (interfaces_invalidated)
208 break;
decf33c2 209 }
e7b9429f 210 interfaces_invalidated = 0;
decf33c2
TL
211 } while (1);
212}
9c5225a5 213#endif /* USE_POLL */
decf33c2 214
accc7894
TL
215int locate_network (packet)
216 struct packet *packet;
217{
218 struct iaddr ia;
219
220 /* If this came through a gateway, find the corresponding subnet... */
221 if (packet -> raw -> giaddr.s_addr) {
222 struct subnet *subnet;
223 ia.len = 4;
224 memcpy (ia.iabuf, &packet -> raw -> giaddr, 4);
225 subnet = find_subnet (ia);
226 if (subnet)
227 packet -> shared_network = subnet -> shared_network;
228 else
229 packet -> shared_network = (struct shared_network *)0;
230 } else {
231 packet -> shared_network =
232 packet -> interface -> shared_network;
233 }
0c413cce
TL
234 if (packet -> shared_network)
235 return 1;
236 return 0;
accc7894 237}
6806c5ae
TL
238
239void add_timeout (when, where, what)
240 TIME when;
e4749e75
TL
241 void (*where) PROTO ((void *));
242 void *what;
6806c5ae
TL
243{
244 struct timeout *t, *q;
245
246 /* See if this timeout supersedes an existing timeout. */
247 t = (struct timeout *)0;
248 for (q = timeouts; q; q = q -> next) {
e4749e75 249 if (q -> func == where && q -> what == what) {
6806c5ae
TL
250 if (t)
251 t -> next = q -> next;
252 else
253 timeouts = q -> next;
254 break;
255 }
256 t = q;
257 }
258
259 /* If we didn't supersede a timeout, allocate a timeout
260 structure now. */
261 if (!q) {
262 if (free_timeouts) {
263 q = free_timeouts;
264 free_timeouts = q -> next;
265 q -> func = where;
e4749e75 266 q -> what = what;
6806c5ae
TL
267 } else {
268 q = (struct timeout *)malloc (sizeof (struct timeout));
269 if (!q)
8ae2d595 270 log_fatal ("Can't allocate timeout structure!");
6806c5ae 271 q -> func = where;
e4749e75 272 q -> what = what;
6806c5ae
TL
273 }
274 }
275
276 q -> when = when;
277
278 /* Now sort this timeout into the timeout list. */
279
280 /* Beginning of list? */
281 if (!timeouts || timeouts -> when > q -> when) {
282 q -> next = timeouts;
283 timeouts = q;
284 return;
285 }
286
287 /* Middle of list? */
288 for (t = timeouts; t -> next; t = t -> next) {
289 if (t -> next -> when > q -> when) {
290 q -> next = t -> next;
291 t -> next = q;
292 return;
293 }
294 }
295
296 /* End of list. */
297 t -> next = q;
298 q -> next = (struct timeout *)0;
299}
300
301void cancel_timeout (where, what)
e4749e75
TL
302 void (*where) PROTO ((void *));
303 void *what;
6806c5ae
TL
304{
305 struct timeout *t, *q;
306
307 /* Look for this timeout on the list, and unlink it if we find it. */
308 t = (struct timeout *)0;
309 for (q = timeouts; q; q = q -> next) {
e4749e75 310 if (q -> func == where && q -> what == what) {
6806c5ae
TL
311 if (t)
312 t -> next = q -> next;
313 else
314 timeouts = q -> next;
315 break;
316 }
317 t = q;
318 }
319
320 /* If we found the timeout, put it on the free list. */
321 if (q) {
322 q -> next = free_timeouts;
323 free_timeouts = q;
324 }
325}
e4749e75
TL
326
327/* Add a protocol to the list of protocols... */
fb1989a8 328struct protocol *add_protocol (name, fd, handler, local)
e4749e75
TL
329 char *name;
330 int fd;
94b63c64 331 void (*handler) PROTO ((struct protocol *));
e4749e75
TL
332 void *local;
333{
334 struct protocol *p;
335
336 p = (struct protocol *)malloc (sizeof *p);
337 if (!p)
8ae2d595 338 log_fatal ("can't allocate protocol struct for %s", name);
e4749e75
TL
339
340 p -> fd = fd;
341 p -> handler = handler;
342 p -> local = local;
343
344 p -> next = protocols;
345 protocols = p;
fb1989a8 346 return p;
e4749e75 347}
78b8c306
TL
348
349void remove_protocol (proto)
350 struct protocol *proto;
351{
352 struct protocol *p, *next, *prev;
353
354 prev = (struct protocol *)0;
355 for (p = protocols; p; p = next) {
356 next = p -> next;
357 if (p == proto) {
358 if (prev)
359 prev -> next = p -> next;
360 else
361 protocols = p -> next;
362 free (p);
363 }
364 }
365}