ReactOS 0.4.15-dev-8348-gc1b9bb5
dispatch.c
Go to the documentation of this file.
1/* $OpenBSD: dispatch.c,v 1.31 2004/09/21 04:07:03 david Exp $ */
2
3/*
4 * Copyright 2004 Henning Brauer <henning@openbsd.org>
5 * Copyright (c) 1995, 1996, 1997, 1998, 1999
6 * The Internet Software Consortium. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of The Internet Software Consortium nor the names
18 * of its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
22 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
26 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
29 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * This software has been written for the Internet Software Consortium
36 * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
37 * Enterprises. To learn more about the Internet Software Consortium,
38 * see ``http://www.vix.com/isc''. To learn more about Vixie
39 * Enterprises, see ``http://www.vix.com''.
40 */
41
42#include <rosdhcp.h>
43
44#define NDEBUG
45#include <reactos/debug.h>
46
47//#include <sys/ioctl.h>
48
49//#include <net/if_media.h>
50//#include <ifaddrs.h>
51//#include <poll.h>
52
53extern SOCKET DhcpSocket;
55
58static struct timeout *free_timeouts = NULL;
60 struct dhcp_packet *, int, unsigned int,
61 struct iaddr, struct hardware *);
62
63/*
64 * Wait for packets to come in using poll(). When a packet comes in,
65 * call receive_packet to receive the packet and possibly strip hardware
66 * addressing information from it, and then call through the
67 * bootp_packet_handler hook to try to do something with it.
68 */
69void
71{
72 int count, to_msec;
73 struct protocol *l;
74 time_t howlong, cur_time;
75 HANDLE Events[3];
76 int EventCount = 2;
77
79 Events[1] = hStopEvent;
81
82 ApiLock();
83
84 do {
85 /*
86 * Call any expired timeouts, and then if there's still
87 * a timeout registered, time out the select call then.
88 */
89 time(&cur_time);
90
91 if (timeouts)
92 {
93 struct timeout *t;
94
95 if (timeouts->when <= cur_time) {
96 t = timeouts;
97 timeouts = timeouts->next;
98 (*(t->func))(t->what);
99 t->next = free_timeouts;
101 continue;
102 }
103
104 /*
105 * Figure timeout in milliseconds, and check for
106 * potential overflow, so we can cram into an
107 * int for poll, while not polling with a
108 * negative timeout and blocking indefinitely.
109 */
110 howlong = timeouts->when - cur_time;
111 if (howlong > INT_MAX / 1000)
112 howlong = INT_MAX / 1000;
113 to_msec = howlong * 1000;
114 }
115 else
116 {
117 to_msec = INFINITE;
118 }
119
121 {
122 Events[2] = WSACreateEvent();
123 if (Events[2] != WSA_INVALID_EVENT)
124 {
126 if (count != NO_ERROR)
127 {
130 }
131 else
132 {
133 EventCount = 3;
134 }
135 }
136 }
138 {
141
142 EventCount = 2;
143 }
144
145 ApiUnlock();
146 count = WaitForMultipleObjects(EventCount,
147 Events,
148 FALSE,
149 to_msec);
150 ApiLock();
151 if (count == WAIT_OBJECT_0)
152 {
153 /* Adapter state change */
154 continue;
155 }
156 else if (count == WAIT_OBJECT_0 + 1)
157 {
158 /* Stop event signalled */
159 DPRINT("Dispatch thread stop event!\n");
160 break;
161 }
162 else if (count == WAIT_OBJECT_0 + 2)
163 {
164 /* Packet received */
165
166 /* WSA events are manual reset events */
168 }
169 else
170 {
171 /* Timeout */
172 continue;
173 }
174
175 for (l = protocols; l; l = l->next) {
176 struct interface_info *ip;
177 ip = l->local;
178 if (ip && (l->handler != got_one ||
179 !ip->dead)) {
180 DH_DbgPrint(MID_TRACE,("Handling %x\n", l));
181 (*(l->handler))(l);
182 }
183 }
184 } while (1);
185
187
188 ApiUnlock();
189
190 DPRINT("Dispatch thread stopped!\n");
191}
192
193void
195{
196 struct sockaddr_in from;
197 struct hardware hfrom;
198 struct iaddr ifrom;
200 union {
201 /*
202 * Packet input buffer. Must be as large as largest
203 * possible MTU.
204 */
205 unsigned char packbuf[4095];
206 struct dhcp_packet packet;
207 } u;
208 struct interface_info *ip = l->local;
210
211 if ((result = receive_packet(ip, u.packbuf, sizeof(u), &from,
212 &hfrom)) == -1) {
213 warning("receive_packet failed on %s: %d", ip->name,
215 ip->errors++;
216 if (ip->errors > 20) {
217 /* our interface has gone away. */
218 warning("Interface %s no longer appears valid.",
219 ip->name);
220 ip->dead = 1;
221 closesocket(l->fd);
224 if (adapter) {
225 RemoveEntryList(&adapter->ListEntry);
226 free(adapter);
227 }
228 }
229 return;
230 }
231 if (result == 0)
232 return;
233
235 ifrom.len = 4;
236 memcpy(ifrom.iabuf, &from.sin_addr, ifrom.len);
237
238
239 adapter = AdapterFindByHardwareAddress(u.packet.chaddr,
240 u.packet.hlen);
241
242 if (!adapter) {
243 warning("Discarding packet with a non-matching target physical address\n");
244 return;
245 }
246
247 (*bootp_packet_handler)(&adapter->DhclientInfo, &u.packet, result,
248 from.sin_port, ifrom, &hfrom);
249 }
250}
251
252void
253add_timeout(time_t when, void (*where)(void *), void *what)
254{
255 struct timeout *t, *q;
256
257 DH_DbgPrint(MID_TRACE,("Adding timeout %x %p %x\n", when, where, what));
258 /* See if this timeout supersedes an existing timeout. */
259 t = NULL;
260 for (q = timeouts; q; q = q->next) {
261 if (q->func == where && q->what == what) {
262 if (t)
263 t->next = q->next;
264 else
265 timeouts = q->next;
266 break;
267 }
268 t = q;
269 }
270
271 /* If we didn't supersede a timeout, allocate a timeout
272 structure now. */
273 if (!q) {
274 if (free_timeouts) {
276 free_timeouts = q->next;
277 q->func = where;
278 q->what = what;
279 } else {
280 q = malloc(sizeof(struct timeout));
281 if (!q) {
282 error("Can't allocate timeout structure!");
283 return;
284 }
285 q->func = where;
286 q->what = what;
287 }
288 }
289
290 q->when = when;
291
292 /* Now sort this timeout into the timeout list. */
293
294 /* Beginning of list? */
295 if (!timeouts || timeouts->when > q->when) {
296 q->next = timeouts;
297 timeouts = q;
298 return;
299 }
300
301 /* Middle of list? */
302 for (t = timeouts; t->next; t = t->next) {
303 if (t->next->when > q->when) {
304 q->next = t->next;
305 t->next = q;
306 return;
307 }
308 }
309
310 /* End of list. */
311 t->next = q;
312 q->next = NULL;
313}
314
315void
316cancel_timeout(void (*where)(void *), void *what)
317{
318 struct timeout *t, *q;
319
320 /* Look for this timeout on the list, and unlink it if we find it. */
321 t = NULL;
322 for (q = timeouts; q; q = q->next) {
323 if (q->func == where && q->what == what) {
324 if (t)
325 t->next = q->next;
326 else
327 timeouts = q->next;
328 break;
329 }
330 t = q;
331 }
332
333 /* If we found the timeout, put it on the free list. */
334 if (q) {
335 q->next = free_timeouts;
337 }
338}
339
340/* Add a protocol to the list of protocols... */
341void
342add_protocol(char *name, int fd, void (*handler)(struct protocol *),
343 void *local)
344{
345 struct protocol *p;
346
347 p = malloc(sizeof(*p));
348 if (!p)
349 error("can't allocate protocol struct for %s", name);
350
351 p->fd = fd;
352 p->handler = handler;
353 p->local = local;
354 p->next = protocols;
355 protocols = p;
356}
357
358void
360{
361 struct protocol *p, *next, *prev;
362 struct interface_info *ip = proto->local;
363 struct timeout *t, *q, *u;
364
365 t = NULL;
366 q = timeouts;
367 while (q != NULL)
368 {
369 /* Remove all timeouts for this protocol */
370 if (q->what == ip)
371 {
372 /* Unlink the timeout from previous */
373 if (t)
374 t->next = q->next;
375 else
376 timeouts = q->next;
377
378 /* Advance to the next timeout */
379 u = q->next;
380
381 /* Add it to the free list */
382 q->next = free_timeouts;
384 }
385 else
386 {
387 /* Advance to the next timeout */
388 u = q->next;
389
390 /* Update the previous pointer */
391 t = q;
392 }
393
394 /* Advance */
395 q = u;
396 }
397
398 prev = NULL;
399 for (p = protocols; p; p = next) {
400 next = p->next;
401 if (p == proto) {
402 if (prev)
403 prev->next = p->next;
404 else
405 protocols = p->next;
406 free(p);
407 }
408 }
409}
410
411struct protocol *
413{
414 struct protocol *p;
415
416 for( p = protocols; p; p = p->next ) {
417 if( p->local == (void *)info ) return p;
418 }
419
420 return NULL;
421}
422
423int
425{
426 return (1);
427}
PDHCP_ADAPTER AdapterFindByHardwareAddress(u_int8_t haddr[16], u_int8_t hlen)
Definition: adapter.c:540
PDHCP_ADAPTER AdapterFindInfo(struct interface_info *ip)
Definition: adapter.c:526
VOID ApiLock()
Definition: api.c:22
VOID ApiUnlock()
Definition: api.c:26
void add_protocol(char *name, int fd, void(*handler)(struct protocol *), void *local)
Definition: dispatch.c:342
void remove_protocol(struct protocol *proto)
Definition: dispatch.c:359
HANDLE hAdapterStateChangedEvent
Definition: dhcpcsvc.c:20
void cancel_timeout(void(*where)(void *), void *what)
Definition: dispatch.c:316
SOCKET DhcpSocket
Definition: adapter.c:8
static struct timeout * free_timeouts
Definition: dispatch.c:58
void dispatch(HANDLE hStopEvent)
Definition: dispatch.c:70
void got_one(struct protocol *l)
Definition: dispatch.c:194
struct timeout * timeouts
Definition: dispatch.c:57
struct protocol * protocols
Definition: dispatch.c:56
struct protocol * find_protocol_by_adapter(struct interface_info *info)
Definition: dispatch.c:412
int interface_link_status(char *ifname)
Definition: dispatch.c:424
void add_timeout(time_t when, void(*where)(void *), void *what)
Definition: dispatch.c:253
void(* bootp_packet_handler)(struct interface_info *, struct dhcp_packet *, int, unsigned int, struct iaddr, struct hardware *)
Definition: dispatch.c:59
#define MID_TRACE
Definition: debug.h:15
#define DH_DbgPrint(_t_, _x_)
Definition: debug.h:49
HANDLE Events[3]
Definition: schedsvc.c:40
r l[0]
Definition: byte_order.h:168
#define NO_ERROR
Definition: dderror.h:5
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HANDLE hStopEvent
Definition: dhcpcsvc.c:19
time_t cur_time
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7482
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
BOOL WSAAPI WSAResetEvent(IN WSAEVENT hEvent)
Definition: event.c:53
BOOL WSAAPI WSACloseEvent(IN WSAEVENT hEvent)
Definition: event.c:23
INT WSAAPI WSAEventSelect(IN SOCKET s, IN WSAEVENT hEventObject, IN LONG lNetworkEvents)
Definition: select.c:182
__kernel_time_t time_t
Definition: linux.h:252
#define INFINITE
Definition: serial.h:102
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define local
Definition: zutil.h:30
return adapter
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble t
Definition: gl.h:2047
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLfloat GLfloat p
Definition: glext.h:8902
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define INT_MAX
Definition: limits.h:40
__u16 time
Definition: mkdosfs.c:8
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define closesocket
Definition: ncftp.h:477
static unsigned __int64 next
Definition: rand_nt.c:6
int ssize_t
Definition: rosdhcp.h:48
#define warning(s)
Definition: debug.h:83
static int fd
Definition: io.c:51
#define DPRINT
Definition: sndvol32.h:73
ssize_t receive_packet(struct interface_info *ip, unsigned char *packet_data, size_t packet_len, struct sockaddr_in *dest, struct hardware *hardware)
Definition: socket.c:34
CardRegion * from
Definition: spigame.cpp:19
struct define * next
Definition: compiler.c:65
Definition: dhcpd.h:125
int len
Definition: dhcpd.h:126
unsigned char iabuf[16]
Definition: dhcpd.h:127
Definition: dhcpd.h:62
Definition: name.c:39
Definition: dhcpd.h:135
struct protocol * next
Definition: dhcpd.h:253
Definition: dhcpd.h:245
void * what
Definition: dhcpd.h:249
time_t when
Definition: dhcpd.h:247
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
#define WAIT_OBJECT_0
Definition: winbase.h:406
WINSOCK_API_LINKAGE WSAEVENT WSAAPI WSACreateEvent(void)
Definition: event.c:42
#define WSA_INVALID_EVENT
Definition: winsock2.h:623
int PASCAL FAR WSAGetLastError(void)
Definition: dllmain.c:112
#define FD_READ
Definition: winsock.h:405
#define INVALID_SOCKET
Definition: winsock.h:332
#define FD_CLOSE
Definition: winsock.h:410
UINT_PTR SOCKET
Definition: winsock.h:47