ReactOS 0.4.16-dev-2613-g9533ad7
dhclient.c
Go to the documentation of this file.
1/* $OpenBSD: dhclient.c,v 1.62 2004/12/05 18:35:51 deraadt 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 * This client was substantially modified and enhanced by Elliot Poger
42 * for use on Linux while he was working on the MosquitoNet project at
43 * Stanford.
44 *
45 * The current version owes much to Elliot's Linux enhancements, but
46 * was substantially reorganized and partially rewritten by Ted Lemon
47 * so as to use the same networking framework that the Internet Software
48 * Consortium DHCP server uses. Much system-specific configuration code
49 * was moved into a shell script so that as support for more operating
50 * systems is added, it will not be necessary to port and maintain
51 * system-specific configuration code to these operating systems - instead,
52 * the shell script can invoke the native tools to accomplish the same
53 * purpose.
54 */
55
56#include <rosdhcp.h>
57
58#define PERIOD 0x2e
59#define hyphenchar(c) ((c) == 0x2d)
60#define bslashchar(c) ((c) == 0x5c)
61#define periodchar(c) ((c) == PERIOD)
62#define asterchar(c) ((c) == 0x2a)
63#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) || \
64 ((c) >= 0x61 && (c) <= 0x7a))
65#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
66
67#define borderchar(c) (alphachar(c) || digitchar(c))
68#define middlechar(c) (borderchar(c) || hyphenchar(c))
69#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
70
71unsigned long debug_trace_level = 0; /* DEBUG_ULTRA */
72
75
76int log_perror = 1;
78//int nullfd = -1;
79
80struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
83
84/*
85 * ASSERT_STATE() does nothing now; it used to be
86 * assert (state_is == state_shouldbe).
87 */
88#define ASSERT_STATE(state_is, state_shouldbe) {}
89
90#define TIME_MAX 2147483647
91
94int unknown_ok = 1;
96
97void usage(void);
98int check_option(struct client_lease *l, int option);
99int ipv4addrs(char * buf);
100int res_hnok(const char *dn);
101char *option_as_string(unsigned int code, unsigned char *data, int len);
102int fork_privchld(int, int);
103int check_arp( struct interface_info *ip, struct client_lease *lp );
104
105#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
106
108
109
110int
112{
113 ApiInit();
114 AdapterInit();
115
116 tzset();
117
119 sockaddr_broadcast.sin_family = AF_INET;
121 sockaddr_broadcast.sin_addr.s_addr = INADDR_BROADCAST;
122 inaddr_any.s_addr = INADDR_ANY;
124
125 return 1; // TRUE
126}
127
128void
130{
131 // AdapterStop();
132 // ApiFree();
133 /* FIXME: Close pipe and kill pipe thread */
134}
135
136/* XXX Implement me */
137int check_arp( struct interface_info *ip, struct client_lease *lp ) {
138 return 1;
139}
140
141/*
142 * Individual States:
143 *
144 * Each routine is called from the dhclient_state_machine() in one of
145 * these conditions:
146 * -> entering INIT state
147 * -> recvpacket_flag == 0: timeout in this state
148 * -> otherwise: received a packet in this state
149 *
150 * Return conditions as handled by dhclient_state_machine():
151 * Returns 1, sendpacket_flag = 1: send packet, reset timer.
152 * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone).
153 * Returns 0: finish the nap which was interrupted for no good reason.
154 *
155 * Several per-interface variables are used to keep track of the process:
156 * active_lease: the lease that is being used on the interface
157 * (null pointer if not configured yet).
158 * offered_leases: leases corresponding to DHCPOFFER messages that have
159 * been sent to us by DHCP servers.
160 * acked_leases: leases corresponding to DHCPACK messages that have been
161 * sent to us by DHCP servers.
162 * sendpacket: DHCP packet we're trying to send.
163 * destination: IP address to send sendpacket to
164 * In addition, there are several relevant per-lease variables.
165 * T1_expiry, T2_expiry, lease_expiry: lease milestones
166 * In the active lease, these control the process of renewing the lease;
167 * In leases on the acked_leases list, this simply determines when we
168 * can no longer legitimately use the lease.
169 */
170
171void
172state_reboot(void *ipp)
173{
174 struct interface_info *ip = ipp;
176
177 /* If we don't remember an active lease, go straight to INIT. */
178 if (!ip->client->active || ip->client->active->is_bootp) {
179 state_init(ip);
180 return;
181 }
182
183 /* We are in the rebooting state. */
184 ip->client->state = S_REBOOTING;
185
186 /* make_request doesn't initialize xid because it normally comes
187 from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
188 so pick an xid now. */
189 ip->client->xid = RtlRandom(&foo);
190
191 /* Make a DHCPREQUEST packet, and set appropriate per-interface
192 flags. */
193 make_request(ip, ip->client->active);
194 ip->client->destination = iaddr_broadcast;
195 time(&ip->client->first_sending);
196 ip->client->interval = ip->client->config->initial_interval;
197
198 /* Zap the medium list... */
199 ip->client->medium = NULL;
200
201 /* Send out the first DHCPREQUEST packet. */
203}
204
205/*
206 * Called when a lease has completely expired and we've
207 * been unable to renew it.
208 */
209void
210state_init(void *ipp)
211{
212 struct interface_info *ip = ipp;
213
215
216 /* Make a DHCPDISCOVER packet, and set appropriate per-interface
217 flags. */
218 make_discover(ip, ip->client->active);
219 ip->client->xid = ip->client->packet.xid;
220 ip->client->destination = iaddr_broadcast;
221 ip->client->state = S_SELECTING;
222 time(&ip->client->first_sending);
223 ip->client->interval = ip->client->config->initial_interval;
224
225 /* Add an immediate timeout to cause the first DHCPDISCOVER packet
226 to go out. */
228}
229
230void
232{
233 struct interface_info *ip = ipp;
235
237
238 /* Make a DHCPRELEASE packet, and set appropriate per-interface
239 flags. */
240 make_release(ip, ip->client->active);
241
242 /* make_request doesn't initialize xid because it normally comes
243 from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
244 so pick an xid now. */
245 ip->client->xid = RtlRandom(&foo);
247
248 ip->client->state = S_RELEASED;
250}
251
252/*
253 * state_selecting is called when one or more DHCPOFFER packets
254 * have been received and a configurable period of time has passed.
255 */
256void
258{
259 struct interface_info *ip = ipp;
260 struct client_lease *lp, *next, *picked;
262
264
265 time(&cur_time);
266
267 /* Cancel state_selecting and send_discover timeouts, since either
268 one could have got us here. */
271
272 /* We have received one or more DHCPOFFER packets. Currently,
273 the only criterion by which we judge leases is whether or
274 not we get a response when we arp for them. */
275 picked = NULL;
276 for (lp = ip->client->offered_leases; lp; lp = next) {
277 next = lp->next;
278
279 /* Check to see if we got an ARPREPLY for the address
280 in this particular lease. */
281 if (!picked) {
282 if( !check_arp(ip,lp) ) goto freeit;
283 picked = lp;
284 picked->next = NULL;
285 } else {
286freeit:
288 }
289 }
290 ip->client->offered_leases = NULL;
291
292 /* If we just tossed all the leases we were offered, go back
293 to square one. */
294 if (!picked) {
295 ip->client->state = S_INIT;
296 state_init(ip);
297 return;
298 }
299
300 /* If it was a BOOTREPLY, we can just take the address right now. */
301 if (!picked->options[DHO_DHCP_MESSAGE_TYPE].len) {
302 ip->client->new = picked;
303
304 /* Make up some lease expiry times
305 XXX these should be configurable. */
306 ip->client->new->expiry = cur_time + 12000;
307 ip->client->new->renewal += cur_time + 8000;
308 ip->client->new->rebind += cur_time + 10000;
309
310 ip->client->state = S_REQUESTING;
311
312 /* Bind to the address we received. */
313 bind_lease(ip);
314 return;
315 }
316
317 /* Go to the REQUESTING state. */
318 ip->client->destination = iaddr_broadcast;
319 ip->client->state = S_REQUESTING;
320 ip->client->first_sending = cur_time;
321 ip->client->interval = ip->client->config->initial_interval;
322
323 /* Make a DHCPREQUEST packet from the lease we picked. */
324 make_request(ip, picked);
325 ip->client->xid = ip->client->packet.xid;
326
327 /* Toss the lease we picked - we'll get it back in a DHCPACK. */
328 free_client_lease(picked);
329
330 /* Add an immediate timeout to send the first DHCPREQUEST packet. */
332}
333
334/* state_requesting is called when we receive a DHCPACK message after
335 having sent out one or more DHCPREQUEST packets. */
336
337void
339{
341 struct client_lease *lease;
343
344 time(&cur_time);
345
346 /* If we're not receptive to an offer right now, or if the offer
347 has an unrecognizable transaction id, then just drop it. */
348 if (packet->interface->client->xid != packet->raw->xid ||
349 (packet->interface->hw_address.hlen != packet->raw->hlen) ||
350 (memcmp(packet->interface->hw_address.haddr,
351 packet->raw->chaddr, packet->raw->hlen)))
352 return;
353
354 if (ip->client->state != S_REBOOTING &&
355 ip->client->state != S_REQUESTING &&
356 ip->client->state != S_RENEWING &&
357 ip->client->state != S_REBINDING)
358 return;
359
360 note("DHCPACK from %s", piaddr(packet->client_addr));
361
362 lease = packet_to_lease(packet);
363 if (!lease) {
364 note("packet_to_lease failed.");
365 return;
366 }
367
368 ip->client->new = lease;
369
370 /* Stop resending DHCPREQUEST. */
372
373 /* Figure out the lease time. */
374 if (ip->client->new->options[DHO_DHCP_LEASE_TIME].data)
375 ip->client->new->expiry = getULong(
376 ip->client->new->options[DHO_DHCP_LEASE_TIME].data);
377 else
378 ip->client->new->expiry = DHCP_DEFAULT_LEASE_TIME;
379 /* A number that looks negative here is really just very large,
380 because the lease expiry offset is unsigned. */
381 if (ip->client->new->expiry < 0)
382 ip->client->new->expiry = TIME_MAX;
383 /* XXX should be fixed by resetting the client state */
384 if (ip->client->new->expiry < 60)
385 ip->client->new->expiry = 60;
386
387 /* Take the server-provided renewal time if there is one;
388 otherwise figure it out according to the spec. */
389 if (ip->client->new->options[DHO_DHCP_RENEWAL_TIME].len)
390 ip->client->new->renewal = getULong(
391 ip->client->new->options[DHO_DHCP_RENEWAL_TIME].data);
392 else
393 ip->client->new->renewal = ip->client->new->expiry / 2;
394
395 /* Same deal with the rebind time. */
396 if (ip->client->new->options[DHO_DHCP_REBINDING_TIME].len)
397 ip->client->new->rebind = getULong(
398 ip->client->new->options[DHO_DHCP_REBINDING_TIME].data);
399 else
400 ip->client->new->rebind = ip->client->new->renewal +
401 ip->client->new->renewal / 2 + ip->client->new->renewal / 4;
402
403#ifdef __REACTOS__
404 ip->client->new->lease = ip->client->new->expiry;
405 ip->client->new->obtained = cur_time;
406#endif
407 ip->client->new->expiry += cur_time;
408 /* Lease lengths can never be negative. */
409 if (ip->client->new->expiry < cur_time)
410 ip->client->new->expiry = TIME_MAX;
411 ip->client->new->renewal += cur_time;
412 if (ip->client->new->renewal < cur_time)
413 ip->client->new->renewal = TIME_MAX;
414 ip->client->new->rebind += cur_time;
415 if (ip->client->new->rebind < cur_time)
416 ip->client->new->rebind = TIME_MAX;
417
418 bind_lease(ip);
419}
420
421void set_name_servers( PDHCP_ADAPTER Adapter, struct client_lease *new_lease ) {
422 CHAR Buffer[200] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
423 HKEY RegKey;
424
425 strcat(Buffer, Adapter->DhclientInfo.name);
427 return;
428
429
430 if( new_lease->options[DHO_DOMAIN_NAME_SERVERS].len ) {
431
432 struct iaddr nameserver;
433 char *nsbuf;
434 int i, addrs =
435 new_lease->options[DHO_DOMAIN_NAME_SERVERS].len / sizeof(ULONG);
436
437 nsbuf = malloc( addrs * sizeof(IP_ADDRESS_STRING) );
438
439 if( nsbuf) {
440 nsbuf[0] = 0;
441 for( i = 0; i < addrs; i++ ) {
442 nameserver.len = sizeof(ULONG);
443 memcpy( nameserver.iabuf,
444 new_lease->options[DHO_DOMAIN_NAME_SERVERS].data +
445 (i * sizeof(ULONG)), sizeof(ULONG) );
446 strcat( nsbuf, piaddr(nameserver) );
447 if( i != addrs-1 ) strcat( nsbuf, "," );
448 }
449
450 DH_DbgPrint(MID_TRACE,("Setting DhcpNameserver: %s\n", nsbuf));
451
452 RegSetValueExA( RegKey, "DhcpNameServer", 0, REG_SZ,
453 (LPBYTE)nsbuf, strlen(nsbuf) + 1 );
454 free( nsbuf );
455 }
456
457 } else {
458 RegDeleteValueW( RegKey, L"DhcpNameServer" );
459 }
460
461 RegCloseKey( RegKey );
462
463}
464
465void
467 PDHCP_ADAPTER Adapter)
468{
469 CHAR Buffer[200] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
470 HKEY RegKey;
471
472 strcat(Buffer, Adapter->DhclientInfo.name);
474 return;
475
476 RegDeleteValueW( RegKey, L"DhcpNameServer" );
477
478 RegCloseKey( RegKey );
479}
480
481
482void
484 struct client_lease *new_lease)
485{
486 CHAR Buffer1[MAX_PATH] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
487 CHAR Buffer2[MAX_PATH] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters";
488 HKEY RegKey1, RegKey2;
489
490 strcat(Buffer1, Adapter->DhclientInfo.name);
491
492 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, Buffer1, 0, KEY_WRITE, &RegKey1 ) != ERROR_SUCCESS)
493 {
494 return;
495 }
496
497 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, Buffer2, 0, KEY_WRITE, &RegKey2 ) != ERROR_SUCCESS)
498 {
499 RegCloseKey(RegKey1);
500 return;
501 }
502
503 if (new_lease->options[DHO_DOMAIN_NAME].len)
504 {
505 DH_DbgPrint(MID_TRACE, ("Setting DhcpDomain: %s\n", new_lease->options[DHO_DOMAIN_NAME].data));
506
507 RegSetValueExA(RegKey1,
508 "DhcpDomain",
509 0,
510 REG_SZ,
511 (LPBYTE)new_lease->options[DHO_DOMAIN_NAME].data,
512 new_lease->options[DHO_DOMAIN_NAME].len);
513
514 RegSetValueExA(RegKey2,
515 "DhcpDomain",
516 0,
517 REG_SZ,
518 (LPBYTE)new_lease->options[DHO_DOMAIN_NAME].data,
519 new_lease->options[DHO_DOMAIN_NAME].len);
520 }
521 else
522 {
523 RegDeleteValueW(RegKey1, L"DhcpDomain");
524 RegDeleteValueW(RegKey2, L"DhcpDomain");
525 }
526
527 RegCloseKey(RegKey1);
528 RegCloseKey(RegKey2);
529
530}
531
532void
534 PDHCP_ADAPTER Adapter)
535{
536 CHAR Buffer1[MAX_PATH] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
537 CHAR Buffer2[MAX_PATH] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters";
538 HKEY RegKey1, RegKey2;
539
540 strcat(Buffer1, Adapter->DhclientInfo.name);
541
542 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, Buffer1, 0, KEY_WRITE, &RegKey1 ) != ERROR_SUCCESS)
543 {
544 return;
545 }
546
547 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, Buffer2, 0, KEY_WRITE, &RegKey2 ) != ERROR_SUCCESS)
548 {
549 RegCloseKey(RegKey1);
550 return;
551 }
552
553 RegDeleteValueW(RegKey1, L"DhcpDomain");
554 RegDeleteValueW(RegKey2, L"DhcpDomain");
555
556 RegCloseKey(RegKey1);
557 RegCloseKey(RegKey2);
558}
559
560
561void setup_adapter( PDHCP_ADAPTER Adapter, struct client_lease *new_lease ) {
562 CHAR Buffer[200] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
563 struct iaddr netmask;
564 HKEY hkey;
565 int i;
566
567 strcat(Buffer, Adapter->DhclientInfo.name);
569 hkey = NULL;
570
571
572 if( Adapter->NteContext )
573 {
574 DeleteIPAddress( Adapter->NteContext );
575 Adapter->NteContext = 0;
576 }
577
578 /* Set up our default router if we got one from the DHCP server */
579 if( new_lease->options[DHO_SUBNET_MASK].len ) {
581
582 memcpy( netmask.iabuf,
583 new_lease->options[DHO_SUBNET_MASK].data,
584 new_lease->options[DHO_SUBNET_MASK].len );
586 ( *((ULONG*)new_lease->address.iabuf),
587 *((ULONG*)netmask.iabuf),
588 Adapter->IfMib.dwIndex,
589 &Adapter->NteContext,
590 &Adapter->NteInstance );
591 if (hkey) {
592 RegSetValueExA(hkey, "DhcpIPAddress", 0, REG_SZ, (LPBYTE)piaddr(new_lease->address), strlen(piaddr(new_lease->address))+1);
593 Buffer[0] = '\0';
594 for(i = 0; i < new_lease->options[DHO_SUBNET_MASK].len; i++)
595 {
596 sprintf(&Buffer[strlen(Buffer)], "%u", new_lease->options[DHO_SUBNET_MASK].data[i]);
597 if (i + 1 < new_lease->options[DHO_SUBNET_MASK].len)
598 strcat(Buffer, ".");
599 }
600 RegSetValueExA(hkey, "DhcpSubnetMask", 0, REG_SZ, (LPBYTE)Buffer, strlen(Buffer)+1);
601 RegSetValueExA(hkey, "DhcpServer", 0, REG_SZ, (LPBYTE)piaddr(new_lease->serveraddress), strlen(piaddr(new_lease->serveraddress))+1);
602
603 RegSetValueExA(hkey, "Lease", 0, REG_DWORD, (LPBYTE)&new_lease->lease, sizeof(DWORD));
604 RegSetValueExA(hkey, "LeaseObtainedTime", 0, REG_DWORD, (LPBYTE)&new_lease->obtained, sizeof(DWORD));
605 RegSetValueExA(hkey, "LeaseTerminatesTime", 0, REG_DWORD, (LPBYTE)&new_lease->expiry, sizeof(DWORD));
606 RegSetValueExA(hkey, "T1", 0, REG_DWORD, (LPBYTE)&new_lease->renewal, sizeof(DWORD));
607 RegSetValueExA(hkey, "T2", 0, REG_DWORD, (LPBYTE)&new_lease->rebind, sizeof(DWORD));
608 }
609
610 if( !NT_SUCCESS(Status) )
611 warning("AddIPAddress: %lx\n", Status);
612 }
613
614 if( new_lease->options[DHO_ROUTERS].len ) {
616
617 Adapter->RouterMib.dwForwardDest = 0; /* Default route */
618 Adapter->RouterMib.dwForwardMask = 0;
619 Adapter->RouterMib.dwForwardMetric1 = 1;
620 Adapter->RouterMib.dwForwardIfIndex = Adapter->IfMib.dwIndex;
621
622 if( Adapter->RouterMib.dwForwardNextHop ) {
623 /* If we set a default route before, delete it before continuing */
624 DeleteIpForwardEntry( &Adapter->RouterMib );
625 }
626
627 Adapter->RouterMib.dwForwardNextHop =
628 *((ULONG*)new_lease->options[DHO_ROUTERS].data);
629
631
632 if( !NT_SUCCESS(Status) )
633 warning("CreateIpForwardEntry: %lx\n", Status);
634
635 if (hkey) {
636 Buffer[0] = '\0';
637 for(i = 0; i < new_lease->options[DHO_ROUTERS].len; i++)
638 {
639 sprintf(&Buffer[strlen(Buffer)], "%u", new_lease->options[DHO_ROUTERS].data[i]);
640 if (i + 1 < new_lease->options[DHO_ROUTERS].len)
641 strcat(Buffer, ".");
642 }
643 RegSetValueExA(hkey, "DhcpDefaultGateway", 0, REG_SZ, (LPBYTE)Buffer, strlen(Buffer)+1);
644 }
645 }
646
647 if (hkey)
648 RegCloseKey(hkey);
649}
650
651void
653 CHAR Buffer[200] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
654 CHAR IpAddress[] = "0.0.0.0";
655 CHAR SubnetMask[] = "255.0.0.0";
656 CHAR Server[] = "255.255.255.255";
657 HKEY hkey;
658 DWORD lease;
659 time_t cur_time, new_time;
660
661 time(&cur_time);
662
663 strcat(Buffer, Adapter->DhclientInfo.name);
665 hkey = NULL;
666
667 if( Adapter->NteContext )
668 {
669 DeleteIPAddress( Adapter->NteContext );
670 Adapter->NteContext = 0;
671 }
672
673 if (hkey) {
674 RegSetValueExA(hkey, "DhcpIPAddress", 0, REG_SZ, (LPBYTE)IpAddress, strlen(IpAddress)+1);
675 RegSetValueExA(hkey, "DhcpSubnetMask", 0, REG_SZ, (LPBYTE)SubnetMask, strlen(SubnetMask)+1);
676 RegSetValueExA(hkey, "DhcpServer", 0, REG_SZ, (LPBYTE)Server, strlen(Server)+1);
677
678 lease = 3600;
679 RegSetValueExA(hkey, "Lease", 0, REG_DWORD, (LPBYTE)&lease, sizeof(DWORD));
680 RegSetValueExA(hkey, "LeaseObtainedTime", 0, REG_DWORD, (LPBYTE)&cur_time, sizeof(DWORD));
681 new_time = cur_time + lease;
682 RegSetValueExA(hkey, "LeaseTerminatesTime", 0, REG_DWORD, (LPBYTE)&new_time, sizeof(DWORD));
683 new_time = cur_time + (lease / 2);
684 RegSetValueExA(hkey, "T1", 0, REG_DWORD, (LPBYTE)&new_time, sizeof(DWORD));
685 new_time = cur_time + lease - (lease / 8);
686 RegSetValueExA(hkey, "T2", 0, REG_DWORD, (LPBYTE)&new_time, sizeof(DWORD));
687 }
688
689 if( Adapter->RouterMib.dwForwardNextHop ) {
690 DeleteIpForwardEntry( &Adapter->RouterMib );
691 }
692
693 if (hkey) {
694 RegDeleteValueA(hkey, "DhcpDefaultGateway");
695 }
696
697 if (hkey)
698 RegCloseKey(hkey);
699}
700
701
702void
704{
705 PDHCP_ADAPTER Adapter;
706 struct client_lease *new_lease = ip->client->new;
708
709 time(&cur_time);
710
711 /* Remember the medium. */
712 ip->client->new->medium = ip->client->medium;
713
714 /* Replace the old active lease with the new one. */
715 if (ip->client->active)
716 free_client_lease(ip->client->active);
717 ip->client->active = ip->client->new;
718 ip->client->new = NULL;
719
720 /* Set up a timeout to start the renewal process. */
721 /* Timeout of zero means no timeout (some implementations seem to use
722 * one day).
723 */
724 if( ip->client->active->renewal - cur_time )
725 add_timeout(ip->client->active->renewal, state_bound, ip);
726
727 note("bound to %s -- renewal in %ld seconds.",
728 piaddr(ip->client->active->address),
729 (long int)(ip->client->active->renewal - cur_time));
730
731 ip->client->state = S_BOUND;
732
733 Adapter = AdapterFindInfo( ip );
734
735 if( Adapter ) setup_adapter( Adapter, new_lease );
736 else {
737 warning("Could not find adapter for info %p\n", ip);
738 return;
739 }
740 set_name_servers( Adapter, new_lease );
741 set_domain( Adapter, new_lease );
742}
743
744void
746{
747 PDHCP_ADAPTER Adapter;
748
749 if (ip->client->active) {
750 free_client_lease(ip->client->active);
751 ip->client->active = NULL;
752 }
753
754 Adapter = AdapterFindInfo( ip );
755 if (Adapter) {
756 reset_adapter(Adapter);
757 unset_name_servers(Adapter);
758 unset_domain(Adapter);
759 }
760 else {
761 warning("Could not find adapter for info %p\n", ip);
762 return;
763 }
764}
765
766/*
767 * state_bound is called when we've successfully bound to a particular
768 * lease, but the renewal time on that lease has expired. We are
769 * expected to unicast a DHCPREQUEST to the server that gave us our
770 * original lease.
771 */
772void
773state_bound(void *ipp)
774{
775 struct interface_info *ip = ipp;
776
778
779 /* T1 has expired. */
780 make_request(ip, ip->client->active);
781 ip->client->xid = ip->client->packet.xid;
782
783 if (ip->client->active->options[DHO_DHCP_SERVER_IDENTIFIER].len == 4) {
784 memcpy(ip->client->destination.iabuf, ip->client->active->
786 ip->client->destination.len = 4;
787 } else
788 ip->client->destination = iaddr_broadcast;
789
790 time(&ip->client->first_sending);
791 ip->client->interval = ip->client->config->initial_interval;
792 ip->client->state = S_RENEWING;
793
794 /* Send the first packet immediately. */
796}
797
798void
800{
801 struct iaddrlist *ap;
802
803 if (packet->raw->op != BOOTREPLY)
804 return;
805
806 /* If there's a reject list, make sure this packet's sender isn't
807 on it. */
808 for (ap = packet->interface->client->config->reject_list;
809 ap; ap = ap->next) {
810 if (addr_eq(packet->client_addr, ap->addr)) {
811 note("BOOTREPLY from %s rejected.", piaddr(ap->addr));
812 return;
813 }
814 }
816}
817
818void
820{
821 struct iaddrlist *ap;
822 void (*handler)(struct packet *);
823 char *type;
824
825 switch (packet->packet_type) {
826 case DHCPOFFER:
828 type = "DHCPOFFER";
829 break;
830 case DHCPNAK:
832 type = "DHCPNACK";
833 break;
834 case DHCPACK:
836 type = "DHCPACK";
837 break;
838 default:
839 return;
840 }
841
842 /* If there's a reject list, make sure this packet's sender isn't
843 on it. */
844 for (ap = packet->interface->client->config->reject_list;
845 ap; ap = ap->next) {
846 if (addr_eq(packet->client_addr, ap->addr)) {
847 note("%s from %s rejected.", type, piaddr(ap->addr));
848 return;
849 }
850 }
851 (*handler)(packet);
852}
853
854void
856{
858 struct client_lease *lease, *lp;
859 int i;
860 int arp_timeout_needed = 0, stop_selecting;
862 "DHCPOFFER" : "BOOTREPLY";
864
865 time(&cur_time);
866
867 /* If we're not receptive to an offer right now, or if the offer
868 has an unrecognizable transaction id, then just drop it. */
869 if (ip->client->state != S_SELECTING ||
870 packet->interface->client->xid != packet->raw->xid ||
871 (packet->interface->hw_address.hlen != packet->raw->hlen) ||
872 (memcmp(packet->interface->hw_address.haddr,
873 packet->raw->chaddr, packet->raw->hlen)))
874 return;
875
876 note("%s from %s", name, piaddr(packet->client_addr));
877
878
879 /* If this lease doesn't supply the minimum required parameters,
880 blow it off. */
881 for (i = 0; ip->client->config->required_options[i]; i++) {
882 if (!packet->options[ip->client->config->
883 required_options[i]].len) {
884 note("%s isn't satisfactory.", name);
885 return;
886 }
887 }
888
889 /* If we've already seen this lease, don't record it again. */
890 for (lease = ip->client->offered_leases;
891 lease; lease = lease->next) {
892 if (lease->address.len == sizeof(packet->raw->yiaddr) &&
893 !memcmp(lease->address.iabuf,
894 &packet->raw->yiaddr, lease->address.len)) {
895 debug("%s already seen.", name);
896 return;
897 }
898 }
899
900 lease = packet_to_lease(packet);
901 if (!lease) {
902 note("packet_to_lease failed.");
903 return;
904 }
905
906 /* If this lease was acquired through a BOOTREPLY, record that
907 fact. */
909 lease->is_bootp = 1;
910
911 /* Record the medium under which this lease was offered. */
912 lease->medium = ip->client->medium;
913
914 /* Send out an ARP Request for the offered IP address. */
915 if( !check_arp( ip, lease ) ) {
916 note("Arp check failed\n");
917 return;
918 }
919
920 /* Figure out when we're supposed to stop selecting. */
921 stop_selecting =
922 ip->client->first_sending + ip->client->config->select_interval;
923
924 /* If this is the lease we asked for, put it at the head of the
925 list, and don't mess with the arp request timeout. */
926 if (lease->address.len == ip->client->requested_address.len &&
927 !memcmp(lease->address.iabuf,
928 ip->client->requested_address.iabuf,
929 ip->client->requested_address.len)) {
930 lease->next = ip->client->offered_leases;
931 ip->client->offered_leases = lease;
932 } else {
933 /* If we already have an offer, and arping for this
934 offer would take us past the selection timeout,
935 then don't extend the timeout - just hope for the
936 best. */
937 if (ip->client->offered_leases &&
938 (cur_time + arp_timeout_needed) > stop_selecting)
939 arp_timeout_needed = 0;
940
941 /* Put the lease at the end of the list. */
942 lease->next = NULL;
943 if (!ip->client->offered_leases)
944 ip->client->offered_leases = lease;
945 else {
946 for (lp = ip->client->offered_leases; lp->next;
947 lp = lp->next)
948 ; /* nothing */
949 lp->next = lease;
950 }
951 }
952
953 /* If we're supposed to stop selecting before we've had time
954 to wait for the ARPREPLY, add some delay to wait for
955 the ARPREPLY. */
956 if (stop_selecting - cur_time < arp_timeout_needed)
957 stop_selecting = cur_time + arp_timeout_needed;
958
959 /* If the selecting interval has expired, go immediately to
960 state_selecting(). Otherwise, time out into
961 state_selecting at the select interval. */
962 if (stop_selecting <= 0)
964 else {
965 add_timeout(stop_selecting, state_selecting, ip);
967 }
968}
969
970/* Allocate a client_lease structure and initialize it from the parameters
971 in the specified packet. */
972
973struct client_lease *
975{
976 struct client_lease *lease;
977 int i;
978
979 lease = malloc(sizeof(struct client_lease));
980
981 if (!lease) {
982 warning("dhcpoffer: no memory to record lease.");
983 return (NULL);
984 }
985
986 memset(lease, 0, sizeof(*lease));
987
988 /* Copy the lease options. */
989 for (i = 0; i < 256; i++) {
990 if (packet->options[i].len) {
991 lease->options[i].data =
992 malloc(packet->options[i].len + 1);
993 if (!lease->options[i].data) {
994 warning("dhcpoffer: no memory for option %d", i);
995 free_client_lease(lease);
996 return (NULL);
997 } else {
998 memcpy(lease->options[i].data,
999 packet->options[i].data,
1000 packet->options[i].len);
1001 lease->options[i].len =
1002 packet->options[i].len;
1003 lease->options[i].data[lease->options[i].len] =
1004 0;
1005 }
1006 if (!check_option(lease,i)) {
1007 /* ignore a bogus lease offer */
1008 warning("Invalid lease option - ignoring offer");
1009 free_client_lease(lease);
1010 return (NULL);
1011 }
1012 }
1013 }
1014
1015 lease->address.len = sizeof(packet->raw->yiaddr);
1016 memcpy(lease->address.iabuf, &packet->raw->yiaddr, lease->address.len);
1017#ifdef __REACTOS__
1018 if (packet->raw->siaddr.S_un.S_addr == 0)
1019 {
1020 lease->serveraddress.len = packet->client_addr.len;
1021 memcpy(lease->serveraddress.iabuf, &packet->client_addr.iabuf, packet->client_addr.len);
1022 }
1023 else
1024 {
1025 lease->serveraddress.len = sizeof(packet->raw->siaddr);
1026 memcpy(lease->serveraddress.iabuf, &packet->raw->siaddr, lease->serveraddress.len);
1027 }
1028#endif
1029
1030 /* If the server name was filled out, copy it. */
1032 !(packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2)) &&
1033 packet->raw->sname[0]) {
1034 lease->server_name = malloc(DHCP_SNAME_LEN + 1);
1035 if (!lease->server_name) {
1036 warning("dhcpoffer: no memory for server name.");
1037 free_client_lease(lease);
1038 return (NULL);
1039 }
1040 memcpy(lease->server_name, packet->raw->sname, DHCP_SNAME_LEN);
1041 lease->server_name[DHCP_SNAME_LEN]='\0';
1042 if (!res_hnok(lease->server_name) ) {
1043 warning("Bogus server name %s", lease->server_name );
1044 free_client_lease(lease);
1045 return (NULL);
1046 }
1047
1048 }
1049
1050 /* Ditto for the filename. */
1052 !(packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 1)) &&
1053 packet->raw->file[0]) {
1054 /* Don't count on the NUL terminator. */
1055 lease->filename = malloc(DHCP_FILE_LEN + 1);
1056 if (!lease->filename) {
1057 warning("dhcpoffer: no memory for filename.");
1058 free_client_lease(lease);
1059 return (NULL);
1060 }
1061 memcpy(lease->filename, packet->raw->file, DHCP_FILE_LEN);
1062 lease->filename[DHCP_FILE_LEN]='\0';
1063 }
1064 return lease;
1065}
1066
1067void
1069{
1070 struct interface_info *ip = packet->interface;
1071
1072 /* If we're not receptive to an offer right now, or if the offer
1073 has an unrecognizable transaction id, then just drop it. */
1074 if (packet->interface->client->xid != packet->raw->xid ||
1075 (packet->interface->hw_address.hlen != packet->raw->hlen) ||
1076 (memcmp(packet->interface->hw_address.haddr,
1077 packet->raw->chaddr, packet->raw->hlen)))
1078 return;
1079
1080 if (ip->client->state != S_REBOOTING &&
1081 ip->client->state != S_REQUESTING &&
1082 ip->client->state != S_RENEWING &&
1083 ip->client->state != S_REBINDING)
1084 return;
1085
1086 note("DHCPNAK from %s", piaddr(packet->client_addr));
1087
1088 if (!ip->client->active) {
1089 note("DHCPNAK with no active lease.\n");
1090 return;
1091 }
1092
1093 free_client_lease(ip->client->active);
1094 ip->client->active = NULL;
1095
1096 /* Stop sending DHCPREQUEST packets... */
1098
1099 ip->client->state = S_INIT;
1100 state_init(ip);
1101}
1102
1103/* Send out a DHCPDISCOVER packet, and set a timeout to send out another
1104 one after the right interval has expired. If we don't get an offer by
1105 the time we reach the panic interval, call the panic function. */
1106
1107void
1109{
1110 struct interface_info *ip = ipp;
1111 int interval, increase = 1;
1113
1114 DH_DbgPrint(MID_TRACE,("Doing discover on interface %p\n",ip));
1115
1116 time(&cur_time);
1117
1118 /* Figure out how long it's been since we started transmitting. */
1119 interval = cur_time - ip->client->first_sending;
1120
1121 /* If we're past the panic timeout, call the script and tell it
1122 we haven't found anything for this interface yet. */
1123 if (interval > ip->client->config->timeout) {
1124 state_panic(ip);
1125 ip->client->first_sending = cur_time;
1126 }
1127
1128 /* If we're selecting media, try the whole list before doing
1129 the exponential backoff, but if we've already received an
1130 offer, stop looping, because we obviously have it right. */
1131 if (!ip->client->offered_leases &&
1132 ip->client->config->media) {
1133 int fail = 0;
1134
1135 if (ip->client->medium) {
1136 ip->client->medium = ip->client->medium->next;
1137 increase = 0;
1138 }
1139 if (!ip->client->medium) {
1140 if (fail)
1141 error("No valid media types for %s!", ip->name);
1142 ip->client->medium = ip->client->config->media;
1143 increase = 1;
1144 }
1145
1146 note("Trying medium \"%s\" %d", ip->client->medium->string,
1147 increase);
1148 /* XXX Support other media types eventually */
1149 }
1150
1151 /*
1152 * If we're supposed to increase the interval, do so. If it's
1153 * currently zero (i.e., we haven't sent any packets yet), set
1154 * it to one; otherwise, add to it a random number between zero
1155 * and two times itself. On average, this means that it will
1156 * double with every transmission.
1157 */
1158 if (increase) {
1159 if (!ip->client->interval)
1160 ip->client->interval =
1161 ip->client->config->initial_interval;
1162 else {
1163 ip->client->interval += (rand() >> 2) %
1164 (2 * ip->client->interval);
1165 }
1166
1167 /* Don't backoff past cutoff. */
1168 if (ip->client->interval >
1169 ip->client->config->backoff_cutoff)
1170 ip->client->interval =
1171 ((ip->client->config->backoff_cutoff / 2)
1172 + ((rand() >> 2) %
1173 ip->client->config->backoff_cutoff));
1174 } else if (!ip->client->interval)
1175 ip->client->interval =
1176 ip->client->config->initial_interval;
1177
1178 /* If the backoff would take us to the panic timeout, just use that
1179 as the interval. */
1180 if (cur_time + ip->client->interval >
1181 ip->client->first_sending + ip->client->config->timeout)
1182 ip->client->interval =
1183 (ip->client->first_sending +
1184 ip->client->config->timeout) - cur_time + 1;
1185
1186 /* Record the number of seconds since we started sending. */
1187 if (interval < 65536)
1188 ip->client->packet.secs = htons(interval);
1189 else
1190 ip->client->packet.secs = htons(65535);
1191 ip->client->secs = ip->client->packet.secs;
1192
1193 note("DHCPDISCOVER on %s to %s port %d interval %ld",
1194 ip->name, inet_ntoa(sockaddr_broadcast.sin_addr),
1195 ntohs(sockaddr_broadcast.sin_port), (long int)ip->client->interval);
1196
1197 /* Send out a packet. */
1198 (void)send_packet(ip, &ip->client->packet, ip->client->packet_length,
1200
1201 DH_DbgPrint(MID_TRACE,("discover timeout: now %x -> then %x\n",
1202 cur_time, cur_time + ip->client->interval));
1203
1204 add_timeout(cur_time + ip->client->interval, send_discover, ip);
1205}
1206
1207/*
1208 * state_panic gets called if we haven't received any offers in a preset
1209 * amount of time. When this happens, we try to use existing leases
1210 * that haven't yet expired, and failing that, we call the client script
1211 * and hope it can do something.
1212 */
1213void
1214state_panic(void *ipp)
1215{
1216 CHAR szKeyNameBuffer[200] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
1217 CHAR Server[] = "255.255.255.255";
1218 CHAR SubnetMask[] = "255.255.0.0";
1219 CHAR AddressBuffer[32];
1220 struct interface_info *ip = ipp;
1221 uint16_t address_low;
1222 int i;
1223 IPAddr IpAddress;
1224 ULONG Buffer[20];
1226 DWORD ret;
1227 HKEY hKey = NULL;
1228 PDHCP_ADAPTER Adapter = AdapterFindInfo(ip);
1230 DWORD lease = 0;
1231 time_t cur_time, never_time = 0x7FFFFFFF;
1232 struct in_addr addr;
1233
1234 note("No DHCPOFFERS received.");
1235
1236 time(&cur_time);
1237
1238 strcat(szKeyNameBuffer, Adapter->DhclientInfo.name);
1239 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, szKeyNameBuffer, 0, KEY_WRITE, &hKey) != ERROR_SUCCESS)
1240 hKey = NULL;
1241
1242 if (Adapter && !Adapter->NteContext)
1243 {
1244 DH_DbgPrint(MID_TRACE,("DHCPCSVC: Failed to receive a response from a DHCP server\n"));
1245 if ((Adapter->AlternateConfiguration != NULL) &&
1246 (Adapter->AlternateConfiguration->IpAddress != 0))
1247 {
1248 /* Use the alternate configuration */
1249 DH_DbgPrint(MID_TRACE,("DHCPCSVC: The alternate configuration will be used.\n"));
1250
1251 /* IPAddress & SubnetMask */
1254 Adapter->IfMib.dwIndex,
1255 &Adapter->NteContext,
1256 &Adapter->NteInstance);
1257 if (!NT_SUCCESS(Status))
1258 DH_DbgPrint(MID_TRACE,("AddIPAddress: %lx\n", Status));
1259
1260 /* DefaultGateway */
1261 if (Adapter->AlternateConfiguration->DefaultGateway != 0)
1262 {
1263 Adapter->RouterMib.dwForwardDest = 0; /* Default route */
1264 Adapter->RouterMib.dwForwardMask = 0;
1265 Adapter->RouterMib.dwForwardMetric1 = 1;
1266 Adapter->RouterMib.dwForwardIfIndex = Adapter->IfMib.dwIndex;
1267
1268 if (Adapter->RouterMib.dwForwardNextHop)
1269 {
1270 /* If we set a default route before, delete it before continuing */
1272 }
1273
1275
1277 if (!NT_SUCCESS(Status))
1278 DH_DbgPrint(MID_TRACE,("CreateIpForwardEntry: %lx\n", Status));
1279 }
1280
1281 if (hKey)
1282 {
1283 addr.S_un.S_addr = htonl(Adapter->AlternateConfiguration->IpAddress);
1284 RtlIpv4AddressToStringA(&addr, AddressBuffer);
1285 RegSetValueExA(hKey, "DhcpIPAddress", 0, REG_SZ, (LPBYTE)AddressBuffer, strlen(AddressBuffer) + 1);
1286 addr.S_un.S_addr = htonl(Adapter->AlternateConfiguration->SubnetMask);
1287 RtlIpv4AddressToStringA(&addr, AddressBuffer);
1288 RegSetValueExA(hKey, "DhcpSubnetMask", 0, REG_SZ, (LPBYTE)AddressBuffer, strlen(AddressBuffer) + 1);
1289 if (Adapter->AlternateConfiguration->DefaultGateway != 0)
1290 {
1291 addr.S_un.S_addr = htonl(Adapter->AlternateConfiguration->DefaultGateway);
1292 RtlIpv4AddressToStringA(&addr, AddressBuffer);
1293 RegSetValueExA(hKey, "DhcpDefaultGateway", 0, REG_SZ, (LPBYTE)AddressBuffer, strlen(AddressBuffer) + 1);
1294 }
1295 else
1296 {
1297 RegDeleteValueA(hKey, "DhcpDefaultGateway");
1298 }
1299 RegSetValueExA(hKey, "DhcpServer", 0, REG_SZ, (LPBYTE)Server, strlen(Server) + 1);
1300 RegDeleteValueA(hKey, "DhcpDomain");
1301
1302 if (Adapter->AlternateConfiguration->DnsServer1 != 0)
1303 {
1304 char *pPtr;
1305 addr.S_un.S_addr = htonl(Adapter->AlternateConfiguration->DnsServer1);
1306 pPtr = RtlIpv4AddressToStringA(&addr, AddressBuffer);
1307 if (Adapter->AlternateConfiguration->DnsServer2 != 0)
1308 {
1309 *pPtr = ' ';
1310 pPtr++;
1311 addr.S_un.S_addr = htonl(Adapter->AlternateConfiguration->DnsServer2);
1313 }
1314
1315 RegSetValueExA(hKey, "DhcpNameServer", 0, REG_SZ, (LPBYTE)AddressBuffer, strlen(AddressBuffer) + 1);
1316 }
1317 else
1318 {
1319 RegDeleteValueA(hKey, "DhcpNameServer");
1320 }
1321
1322 RegDeleteValueA(hKey, "IPAutoconfigurationAddress");
1323 RegDeleteValueA(hKey, "IPAutoconfigurationMask");
1324
1325 RegSetValueExA(hKey, "Lease", 0, REG_DWORD, (LPBYTE)&lease, sizeof(DWORD));
1326 RegSetValueExA(hKey, "LeaseObtainedTime", 0, REG_DWORD, (LPBYTE)&cur_time, sizeof(DWORD));
1327 RegSetValueExA(hKey, "LeaseTerminatesTime", 0, REG_DWORD, (LPBYTE)&never_time, sizeof(DWORD));
1328 RegSetValueExA(hKey, "T1", 0, REG_DWORD, (LPBYTE)&cur_time, sizeof(DWORD));
1329 RegSetValueExA(hKey, "T2", 0, REG_DWORD, (LPBYTE)&cur_time, sizeof(DWORD));
1330 }
1331 }
1332 else
1333 {
1334 /* Generate an automatic private address */
1335 DH_DbgPrint(MID_TRACE,("DHCPCSVC: An automatic private address will be assigned.\n"));
1336
1337 /* FIXME: The address generation code sucks */
1338 srand(0);
1339
1340 for (;;)
1341 {
1342 address_low = rand();
1343 for (i = 0; i < ip->hw_address.hlen; i++)
1344 address_low += ip->hw_address.haddr[i];
1345
1346 IpAddress = htonl(0xA9FE0000 | address_low); // 169.254.X.X
1347
1348 /* Send an ARP request to check if the IP address is already in use */
1349 BufferSize = sizeof(Buffer);
1350 ret = SendARP(IpAddress,
1351 IpAddress,
1352 Buffer,
1353 &BufferSize);
1354 DH_DbgPrint(MID_TRACE,("DHCPCSVC: SendARP returned %lu\n", ret));
1355 if (ret != 0)
1356 {
1357 /* The IP address is not in use */
1358 DH_DbgPrint(MID_TRACE,("DHCPCSVC: Using automatic private address\n"));
1359 Status = AddIPAddress(IpAddress,
1360 htonl(0xFFFF0000), // 255.255.0.0
1361 Adapter->IfMib.dwIndex,
1362 &Adapter->NteContext,
1363 &Adapter->NteInstance);
1364 if (!NT_SUCCESS(Status))
1365 DH_DbgPrint(MID_TRACE,("AddIPAddress: %lx\n", Status));
1366
1367 if (hKey)
1368 {
1369 addr.S_un.S_addr = IpAddress;
1370 RtlIpv4AddressToStringA(&addr, AddressBuffer);
1371 RegSetValueExA(hKey, "DhcpIPAddress", 0, REG_SZ, (LPBYTE)AddressBuffer, strlen(AddressBuffer) + 1);
1372 RegSetValueExA(hKey, "DhcpSubnetMask", 0, REG_SZ, (LPBYTE)SubnetMask, strlen(SubnetMask) + 1);
1373 RegSetValueExA(hKey, "DhcpServer", 0, REG_SZ, (LPBYTE)Server, strlen(Server) + 1);
1374 RegDeleteValueA(hKey, "DhcpDefaultGateway");
1375 RegDeleteValueA(hKey, "DhcpDomain");
1376 RegDeleteValueA(hKey, "DhcpNameServer");
1377
1378 RegSetValueExA(hKey, "IPAutoconfigurationAddress", 0, REG_SZ, (LPBYTE)AddressBuffer, strlen(AddressBuffer) + 1);
1379 RegSetValueExA(hKey, "IPAutoconfigurationMask", 0, REG_SZ, (LPBYTE)SubnetMask, strlen(SubnetMask) + 1);
1380
1381 RegSetValueExA(hKey, "Lease", 0, REG_DWORD, (LPBYTE)&lease, sizeof(DWORD));
1382 RegSetValueExA(hKey, "LeaseObtainedTime", 0, REG_DWORD, (LPBYTE)&cur_time, sizeof(DWORD));
1383 RegSetValueExA(hKey, "LeaseTerminatesTime", 0, REG_DWORD, (LPBYTE)&never_time, sizeof(DWORD));
1384 RegSetValueExA(hKey, "T1", 0, REG_DWORD, (LPBYTE)&cur_time, sizeof(DWORD));
1385 RegSetValueExA(hKey, "T2", 0, REG_DWORD, (LPBYTE)&cur_time, sizeof(DWORD));
1386 }
1387
1388 goto done;
1389 }
1390 }
1391 }
1392 }
1393
1394done:
1395 if (hKey)
1397}
1398
1399void
1401{
1402 struct interface_info *ip = ipp;
1403 struct sockaddr_in destination;
1404 struct in_addr from;
1405 int interval;
1407
1408 time(&cur_time);
1409
1410 /* Figure out how long it's been since we started transmitting. */
1411 interval = cur_time - ip->client->first_sending;
1412
1413 /* If we're in the INIT-REBOOT or REQUESTING state and we're
1414 past the reboot timeout, go to INIT and see if we can
1415 DISCOVER an address... */
1416 /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
1417 means either that we're on a network with no DHCP server,
1418 or that our server is down. In the latter case, assuming
1419 that there is a backup DHCP server, DHCPDISCOVER will get
1420 us a new address, but we could also have successfully
1421 reused our old address. In the former case, we're hosed
1422 anyway. This is not a win-prone situation. */
1423 if ((ip->client->state == S_REBOOTING ||
1424 ip->client->state == S_REQUESTING) &&
1425 interval > ip->client->config->reboot_timeout) {
1426 ip->client->state = S_INIT;
1428 state_init(ip);
1429 return;
1430 }
1431
1432 /* If we're in the reboot state, make sure the media is set up
1433 correctly. */
1434 if (ip->client->state == S_REBOOTING &&
1435 !ip->client->medium &&
1436 ip->client->active->medium ) {
1437 /* If the medium we chose won't fly, go to INIT state. */
1438 /* XXX Nothing for now */
1439
1440 /* Record the medium. */
1441 ip->client->medium = ip->client->active->medium;
1442 }
1443
1444 /* If the lease has expired, relinquish the address and go back
1445 to the INIT state. */
1446 if (ip->client->state != S_REQUESTING &&
1447 cur_time > ip->client->active->expiry) {
1448 PDHCP_ADAPTER Adapter = AdapterFindInfo( ip );
1449 /* Run the client script with the new parameters. */
1450 /* No script actions necessary in the expiry case */
1451 /* Now do a preinit on the interface so that we can
1452 discover a new address. */
1453
1454 if( Adapter )
1455 {
1456 DeleteIPAddress( Adapter->NteContext );
1457 Adapter->NteContext = 0;
1458 }
1459
1460 ip->client->state = S_INIT;
1461 state_init(ip);
1462 return;
1463 }
1464
1465 /* Do the exponential backoff... */
1466 if (!ip->client->interval)
1467 ip->client->interval = ip->client->config->initial_interval;
1468 else
1469 ip->client->interval += ((rand() >> 2) %
1470 (2 * ip->client->interval));
1471
1472 /* Don't backoff past cutoff. */
1473 if (ip->client->interval >
1474 ip->client->config->backoff_cutoff)
1475 ip->client->interval =
1476 ((ip->client->config->backoff_cutoff / 2) +
1477 ((rand() >> 2) % ip->client->interval));
1478
1479 /* If the backoff would take us to the expiry time, just set the
1480 timeout to the expiry time. */
1481 if (ip->client->state != S_REQUESTING &&
1482 cur_time + ip->client->interval >
1483 ip->client->active->expiry)
1484 ip->client->interval =
1485 ip->client->active->expiry - cur_time + 1;
1486
1487 /* If the lease T2 time has elapsed, or if we're not yet bound,
1488 broadcast the DHCPREQUEST rather than unicasting. */
1489 memset(&destination, 0, sizeof(destination));
1490 if (ip->client->state == S_REQUESTING ||
1491 ip->client->state == S_REBOOTING ||
1492 cur_time > ip->client->active->rebind)
1493 destination.sin_addr.s_addr = INADDR_BROADCAST;
1494 else
1495 memcpy(&destination.sin_addr.s_addr,
1496 ip->client->destination.iabuf,
1497 sizeof(destination.sin_addr.s_addr));
1498 destination.sin_port = htons(REMOTE_PORT);
1499 destination.sin_family = AF_INET;
1500// destination.sin_len = sizeof(destination);
1501
1502 if (ip->client->state != S_REQUESTING)
1503 memcpy(&from, ip->client->active->address.iabuf,
1504 sizeof(from));
1505 else
1506 from.s_addr = INADDR_ANY;
1507
1508 /* Record the number of seconds since we started sending. */
1509 if (ip->client->state == S_REQUESTING)
1510 ip->client->packet.secs = ip->client->secs;
1511 else {
1512 if (interval < 65536)
1513 ip->client->packet.secs = htons(interval);
1514 else
1515 ip->client->packet.secs = htons(65535);
1516 }
1517
1518 note("DHCPREQUEST on %s to %s port %d", ip->name,
1519 inet_ntoa(destination.sin_addr), ntohs(destination.sin_port));
1520
1521 /* Send out a packet. */
1522 (void) send_packet(ip, &ip->client->packet, ip->client->packet_length,
1523 from, &destination, NULL);
1524
1525 add_timeout(cur_time + ip->client->interval, send_request, ip);
1526}
1527
1528void
1530{
1531 struct interface_info *ip = ipp;
1532
1533 note("DHCPDECLINE on %s to %s port %d", ip->name,
1534 inet_ntoa(sockaddr_broadcast.sin_addr),
1535 ntohs(sockaddr_broadcast.sin_port));
1536
1537 /* Send out a packet. */
1538 (void) send_packet(ip, &ip->client->packet, ip->client->packet_length,
1540}
1541
1542void
1544{
1545 struct interface_info *ip = ipp;
1546 struct sockaddr_in destination;
1547 struct in_addr from;
1548
1549 memset(&destination, 0, sizeof(destination));
1550 memcpy(&destination.sin_addr.s_addr,
1551 ip->client->destination.iabuf,
1552 sizeof(destination.sin_addr.s_addr));
1553 destination.sin_port = htons(REMOTE_PORT);
1554 destination.sin_family = AF_INET;
1555
1556 memcpy(&from, ip->client->active->address.iabuf,
1557 sizeof(from));
1558
1559 note("DHCPRELEASE on %s to %s port %d", ip->name,
1560 inet_ntoa(destination.sin_addr), ntohs(destination.sin_port));
1561
1562 /* Send out a packet. */
1563 (void) send_packet(ip, &ip->client->packet, ip->client->packet_length,
1564 from, &destination, NULL);
1565}
1566
1567void
1569{
1570 unsigned char discover = DHCPDISCOVER;
1571 struct tree_cache *options[256];
1572 struct tree_cache option_elements[256];
1573 int i;
1575
1576 memset(option_elements, 0, sizeof(option_elements));
1577 memset(options, 0, sizeof(options));
1578 memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1579
1580 /* Set DHCP_MESSAGE_TYPE to DHCPDISCOVER */
1582 options[i] = &option_elements[i];
1583 options[i]->value = &discover;
1584 options[i]->len = sizeof(discover);
1585 options[i]->buf_size = sizeof(discover);
1586 options[i]->timeout = 0xFFFFFFFF;
1587
1588 /* Request the options we want */
1590 options[i] = &option_elements[i];
1591 options[i]->value = ip->client->config->requested_options;
1592 options[i]->len = ip->client->config->requested_option_count;
1593 options[i]->buf_size =
1594 ip->client->config->requested_option_count;
1595 options[i]->timeout = 0xFFFFFFFF;
1596
1597 /* If we had an address, try to get it again. */
1598 if (lease) {
1599 ip->client->requested_address = lease->address;
1601 options[i] = &option_elements[i];
1602 options[i]->value = lease->address.iabuf;
1603 options[i]->len = lease->address.len;
1604 options[i]->buf_size = lease->address.len;
1605 options[i]->timeout = 0xFFFFFFFF;
1606 } else
1607 ip->client->requested_address.len = 0;
1608
1609 /* Send any options requested in the config file. */
1610 for (i = 0; i < 256; i++)
1611 if (!options[i] &&
1612 ip->client->config->send_options[i].data) {
1613 options[i] = &option_elements[i];
1614 options[i]->value =
1615 ip->client->config->send_options[i].data;
1616 options[i]->len =
1617 ip->client->config->send_options[i].len;
1618 options[i]->buf_size =
1619 ip->client->config->send_options[i].len;
1620 options[i]->timeout = 0xFFFFFFFF;
1621 }
1622
1623 /* Set up the option buffer... */
1624 ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1625 options);
1626 if (ip->client->packet_length < BOOTP_MIN_LEN)
1627 ip->client->packet_length = BOOTP_MIN_LEN;
1628
1629 ip->client->packet.op = BOOTREQUEST;
1630 ip->client->packet.htype = ip->hw_address.htype;
1631 ip->client->packet.hlen = ip->hw_address.hlen;
1632 ip->client->packet.hops = 0;
1633 ip->client->packet.xid = RtlRandom(&foo);
1634 ip->client->packet.secs = 0; /* filled in by send_discover. */
1635 ip->client->packet.flags = 0;
1636
1637 memset(&(ip->client->packet.ciaddr),
1638 0, sizeof(ip->client->packet.ciaddr));
1639 memset(&(ip->client->packet.yiaddr),
1640 0, sizeof(ip->client->packet.yiaddr));
1641 memset(&(ip->client->packet.siaddr),
1642 0, sizeof(ip->client->packet.siaddr));
1643 memset(&(ip->client->packet.giaddr),
1644 0, sizeof(ip->client->packet.giaddr));
1645 memcpy(ip->client->packet.chaddr,
1646 ip->hw_address.haddr, ip->hw_address.hlen);
1647}
1648
1649
1650void
1652{
1653 unsigned char request = DHCPREQUEST;
1654 struct tree_cache *options[256];
1655 struct tree_cache option_elements[256];
1656 int i;
1657
1658 memset(options, 0, sizeof(options));
1659 memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1660
1661 /* Set DHCP_MESSAGE_TYPE to DHCPREQUEST */
1663 options[i] = &option_elements[i];
1664 options[i]->value = &request;
1665 options[i]->len = sizeof(request);
1666 options[i]->buf_size = sizeof(request);
1667 options[i]->timeout = 0xFFFFFFFF;
1668
1669 /* Request the options we want */
1671 options[i] = &option_elements[i];
1672 options[i]->value = ip->client->config->requested_options;
1673 options[i]->len = ip->client->config->requested_option_count;
1674 options[i]->buf_size =
1675 ip->client->config->requested_option_count;
1676 options[i]->timeout = 0xFFFFFFFF;
1677
1678 /* If we are requesting an address that hasn't yet been assigned
1679 to us, use the DHCP Requested Address option. */
1680 if (ip->client->state == S_REQUESTING) {
1681 /* Send back the server identifier... */
1683 options[i] = &option_elements[i];
1684 options[i]->value = lease->options[i].data;
1685 options[i]->len = lease->options[i].len;
1686 options[i]->buf_size = lease->options[i].len;
1687 options[i]->timeout = 0xFFFFFFFF;
1688 }
1689 if (ip->client->state == S_REQUESTING ||
1690 ip->client->state == S_REBOOTING) {
1691 ip->client->requested_address = lease->address;
1693 options[i] = &option_elements[i];
1694 options[i]->value = lease->address.iabuf;
1695 options[i]->len = lease->address.len;
1696 options[i]->buf_size = lease->address.len;
1697 options[i]->timeout = 0xFFFFFFFF;
1698 } else
1699 ip->client->requested_address.len = 0;
1700
1701 /* Send any options requested in the config file. */
1702 for (i = 0; i < 256; i++)
1703 if (!options[i] &&
1704 ip->client->config->send_options[i].data) {
1705 options[i] = &option_elements[i];
1706 options[i]->value =
1707 ip->client->config->send_options[i].data;
1708 options[i]->len =
1709 ip->client->config->send_options[i].len;
1710 options[i]->buf_size =
1711 ip->client->config->send_options[i].len;
1712 options[i]->timeout = 0xFFFFFFFF;
1713 }
1714
1715 /* Set up the option buffer... */
1716 ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1717 options);
1718 if (ip->client->packet_length < BOOTP_MIN_LEN)
1719 ip->client->packet_length = BOOTP_MIN_LEN;
1720
1721 ip->client->packet.op = BOOTREQUEST;
1722 ip->client->packet.htype = ip->hw_address.htype;
1723 ip->client->packet.hlen = ip->hw_address.hlen;
1724 ip->client->packet.hops = 0;
1725 ip->client->packet.xid = ip->client->xid;
1726 ip->client->packet.secs = 0; /* Filled in by send_request. */
1727
1728 /* If we own the address we're requesting, put it in ciaddr;
1729 otherwise set ciaddr to zero. */
1730 if (ip->client->state == S_BOUND ||
1731 ip->client->state == S_RENEWING ||
1732 ip->client->state == S_REBINDING) {
1733 memcpy(&ip->client->packet.ciaddr,
1734 lease->address.iabuf, lease->address.len);
1735 ip->client->packet.flags = 0;
1736 } else {
1737 memset(&ip->client->packet.ciaddr, 0,
1738 sizeof(ip->client->packet.ciaddr));
1739 ip->client->packet.flags = 0;
1740 }
1741
1742 memset(&ip->client->packet.yiaddr, 0,
1743 sizeof(ip->client->packet.yiaddr));
1744 memset(&ip->client->packet.siaddr, 0,
1745 sizeof(ip->client->packet.siaddr));
1746 memset(&ip->client->packet.giaddr, 0,
1747 sizeof(ip->client->packet.giaddr));
1748 memcpy(ip->client->packet.chaddr,
1749 ip->hw_address.haddr, ip->hw_address.hlen);
1750}
1751
1752void
1754{
1755 struct tree_cache *options[256], message_type_tree;
1756 struct tree_cache requested_address_tree;
1757 struct tree_cache server_id_tree, client_id_tree;
1758 unsigned char decline = DHCPDECLINE;
1759 int i;
1760
1761 memset(options, 0, sizeof(options));
1762 memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1763
1764 /* Set DHCP_MESSAGE_TYPE to DHCPDECLINE */
1766 options[i] = &message_type_tree;
1767 options[i]->value = &decline;
1768 options[i]->len = sizeof(decline);
1769 options[i]->buf_size = sizeof(decline);
1770 options[i]->timeout = 0xFFFFFFFF;
1771
1772 /* Send back the server identifier... */
1774 options[i] = &server_id_tree;
1775 options[i]->value = lease->options[i].data;
1776 options[i]->len = lease->options[i].len;
1777 options[i]->buf_size = lease->options[i].len;
1778 options[i]->timeout = 0xFFFFFFFF;
1779
1780 /* Send back the address we're declining. */
1782 options[i] = &requested_address_tree;
1783 options[i]->value = lease->address.iabuf;
1784 options[i]->len = lease->address.len;
1785 options[i]->buf_size = lease->address.len;
1786 options[i]->timeout = 0xFFFFFFFF;
1787
1788 /* Send the uid if the user supplied one. */
1790 if (ip->client->config->send_options[i].len) {
1791 options[i] = &client_id_tree;
1792 options[i]->value = ip->client->config->send_options[i].data;
1793 options[i]->len = ip->client->config->send_options[i].len;
1794 options[i]->buf_size = ip->client->config->send_options[i].len;
1795 options[i]->timeout = 0xFFFFFFFF;
1796 }
1797
1798
1799 /* Set up the option buffer... */
1800 ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1801 options);
1802 if (ip->client->packet_length < BOOTP_MIN_LEN)
1803 ip->client->packet_length = BOOTP_MIN_LEN;
1804
1805 ip->client->packet.op = BOOTREQUEST;
1806 ip->client->packet.htype = ip->hw_address.htype;
1807 ip->client->packet.hlen = ip->hw_address.hlen;
1808 ip->client->packet.hops = 0;
1809 ip->client->packet.xid = ip->client->xid;
1810 ip->client->packet.secs = 0; /* Filled in by send_request. */
1811 ip->client->packet.flags = 0;
1812
1813 /* ciaddr must always be zero. */
1814 memset(&ip->client->packet.ciaddr, 0,
1815 sizeof(ip->client->packet.ciaddr));
1816 memset(&ip->client->packet.yiaddr, 0,
1817 sizeof(ip->client->packet.yiaddr));
1818 memset(&ip->client->packet.siaddr, 0,
1819 sizeof(ip->client->packet.siaddr));
1820 memset(&ip->client->packet.giaddr, 0,
1821 sizeof(ip->client->packet.giaddr));
1822 memcpy(ip->client->packet.chaddr,
1823 ip->hw_address.haddr, ip->hw_address.hlen);
1824}
1825
1826void
1828{
1829 struct tree_cache *options[256], message_type_tree;
1830 struct tree_cache server_id_tree, client_id_tree;
1831 unsigned char release = DHCPRELEASE;
1832 int i;
1833
1834 memset(options, 0, sizeof(options));
1835 memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1836
1837 /* Set DHCP_MESSAGE_TYPE to DHCPRELEASE */
1839 options[i] = &message_type_tree;
1840 options[i]->value = &release;
1841 options[i]->len = sizeof(release);
1842 options[i]->buf_size = sizeof(release);
1843 options[i]->timeout = 0xFFFFFFFF;
1844
1845 /* Send back the server identifier... */
1847 options[i] = &server_id_tree;
1848 options[i]->value = lease->options[i].data;
1849 options[i]->len = lease->options[i].len;
1850 options[i]->buf_size = lease->options[i].len;
1851 options[i]->timeout = 0xFFFFFFFF;
1852
1853 /* Send the uid if the user supplied one. */
1855 if (ip->client->config->send_options[i].len)
1856 {
1857 options[i] = &client_id_tree;
1858 options[i]->value = ip->client->config->send_options[i].data;
1859 options[i]->len = ip->client->config->send_options[i].len;
1860 options[i]->buf_size = ip->client->config->send_options[i].len;
1861 options[i]->timeout = 0xFFFFFFFF;
1862 }
1863
1864 /* Set up the option buffer... */
1865 ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0, options);
1866 if (ip->client->packet_length < BOOTP_MIN_LEN)
1867 ip->client->packet_length = BOOTP_MIN_LEN;
1868
1869 ip->client->packet.op = BOOTREQUEST;
1870 ip->client->packet.htype = ip->hw_address.htype;
1871 ip->client->packet.hlen = ip->hw_address.hlen;
1872 ip->client->packet.hops = 0;
1873 ip->client->packet.xid = 0;
1874 ip->client->packet.secs = 0;
1875 ip->client->packet.flags = 0;
1876
1877 /* ciaddr is the address to be released */
1878 memcpy(&ip->client->packet.ciaddr,
1879 lease->address.iabuf, lease->address.len);
1880 memset(&ip->client->packet.yiaddr, 0,
1881 sizeof(ip->client->packet.yiaddr));
1882 memset(&ip->client->packet.siaddr, 0,
1883 sizeof(ip->client->packet.siaddr));
1884 memset(&ip->client->packet.giaddr, 0,
1885 sizeof(ip->client->packet.giaddr));
1886 memcpy(ip->client->packet.chaddr,
1887 ip->hw_address.haddr, ip->hw_address.hlen);
1888}
1889
1890void
1892{
1893 int i;
1894
1895 if (lease->server_name)
1896 free(lease->server_name);
1897 if (lease->filename)
1898 free(lease->filename);
1899 for (i = 0; i < 256; i++) {
1900 if (lease->options[i].len)
1901 free(lease->options[i].data);
1902 }
1903 free(lease);
1904}
1905
1907
1908void
1910{
1911 struct client_lease *lp;
1912
1913 if (!leaseFile) {
1915 if (!leaseFile)
1916 error("can't create %s", path_dhclient_db);
1917 } else {
1920 }
1921
1922 for (lp = ifi->client->leases; lp; lp = lp->next)
1923 write_client_lease(ifi, lp, 1);
1924 if (ifi->client->active)
1925 write_client_lease(ifi, ifi->client->active, 1);
1926
1928}
1929
1930void
1932 int rewrite)
1933{
1934 static int leases_written;
1935 struct tm *t;
1936 int i;
1937
1938 if (!rewrite) {
1939 if (leases_written++ > 20) {
1941 leases_written = 0;
1942 }
1943 }
1944
1945 /* If the lease came from the config file, we don't need to stash
1946 a copy in the lease database. */
1947 if (lease->is_static)
1948 return;
1949
1950 if (!leaseFile) { /* XXX */
1952 if (!leaseFile) {
1953 error("can't create %s", path_dhclient_db);
1954 return;
1955 }
1956 }
1957
1958 fprintf(leaseFile, "lease {\n");
1959 if (lease->is_bootp)
1960 fprintf(leaseFile, " bootp;\n");
1961 fprintf(leaseFile, " interface \"%s\";\n", ip->name);
1962 fprintf(leaseFile, " fixed-address %s;\n", piaddr(lease->address));
1963 if (lease->filename)
1964 fprintf(leaseFile, " filename \"%s\";\n", lease->filename);
1965 if (lease->server_name)
1966 fprintf(leaseFile, " server-name \"%s\";\n",
1967 lease->server_name);
1968 if (lease->medium)
1969 fprintf(leaseFile, " medium \"%s\";\n", lease->medium->string);
1970 for (i = 0; i < 256; i++)
1971 if (lease->options[i].len)
1972 fprintf(leaseFile, " option %s %s;\n",
1974 pretty_print_option(i, lease->options[i].data,
1975 lease->options[i].len, 1, 1));
1976
1977 t = gmtime(&lease->renewal);
1978 if (t)
1979 fprintf(leaseFile, " renew %d %d/%d/%d %02d:%02d:%02d;\n",
1980 t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
1981 t->tm_hour, t->tm_min, t->tm_sec);
1982 t = gmtime(&lease->rebind);
1983 if (t)
1984 fprintf(leaseFile, " rebind %d %d/%d/%d %02d:%02d:%02d;\n",
1985 t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
1986 t->tm_hour, t->tm_min, t->tm_sec);
1987 t = gmtime(&lease->expiry);
1988 if (t)
1989 fprintf(leaseFile, " expire %d %d/%d/%d %02d:%02d:%02d;\n",
1990 t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
1991 t->tm_hour, t->tm_min, t->tm_sec);
1992 fprintf(leaseFile, "}\n");
1994}
1995
1996void
1997priv_script_init(struct interface_info *ip, char *reason, char *medium)
1998{
1999 if (ip) {
2000 // XXX Do we need to do anything?
2001 }
2002}
2003
2004void
2006{
2007 u_int8_t dbuf[1500];
2008 int i, len = 0;
2009
2010#if 0
2011 script_set_env(ip->client, prefix, "ip_address",
2012 piaddr(lease->address));
2013#endif
2014
2015 if (lease->options[DHO_SUBNET_MASK].len &&
2016 (lease->options[DHO_SUBNET_MASK].len <
2017 sizeof(lease->address.iabuf))) {
2018 struct iaddr netmask, subnet, broadcast;
2019
2020 memcpy(netmask.iabuf, lease->options[DHO_SUBNET_MASK].data,
2021 lease->options[DHO_SUBNET_MASK].len);
2022 netmask.len = lease->options[DHO_SUBNET_MASK].len;
2023
2024 subnet = subnet_number(lease->address, netmask);
2025 if (subnet.len) {
2026#if 0
2027 script_set_env(ip->client, prefix, "network_number",
2028 piaddr(subnet));
2029#endif
2030 if (!lease->options[DHO_BROADCAST_ADDRESS].len) {
2031 broadcast = broadcast_addr(subnet, netmask);
2032 if (broadcast.len)
2033#if 0
2034 script_set_env(ip->client, prefix,
2035 "broadcast_address",
2036 piaddr(broadcast));
2037#else
2038 ;
2039#endif
2040 }
2041 }
2042 }
2043
2044#if 0
2045 if (lease->filename)
2046 script_set_env(ip->client, prefix, "filename", lease->filename);
2047 if (lease->server_name)
2048 script_set_env(ip->client, prefix, "server_name",
2049 lease->server_name);
2050#endif
2051
2052 for (i = 0; i < 256; i++) {
2053 u_int8_t *dp = NULL;
2054
2055 if (ip->client->config->defaults[i].len) {
2056 if (lease->options[i].len) {
2057 switch (
2058 ip->client->config->default_actions[i]) {
2059 case ACTION_DEFAULT:
2060 dp = lease->options[i].data;
2061 len = lease->options[i].len;
2062 break;
2063 case ACTION_SUPERSEDE:
2064supersede:
2065 dp = ip->client->
2066 config->defaults[i].data;
2067 len = ip->client->
2068 config->defaults[i].len;
2069 break;
2070 case ACTION_PREPEND:
2071 len = ip->client->
2072 config->defaults[i].len +
2073 lease->options[i].len;
2074 if (len >= sizeof(dbuf)) {
2075 warning("no space to %s %s",
2076 "prepend option",
2078 goto supersede;
2079 }
2080 dp = dbuf;
2081 memcpy(dp,
2082 ip->client->
2083 config->defaults[i].data,
2084 ip->client->
2085 config->defaults[i].len);
2086 memcpy(dp + ip->client->
2087 config->defaults[i].len,
2088 lease->options[i].data,
2089 lease->options[i].len);
2090 dp[len] = '\0';
2091 break;
2092 case ACTION_APPEND:
2093 len = ip->client->
2094 config->defaults[i].len +
2095 lease->options[i].len + 1;
2096 if (len > sizeof(dbuf)) {
2097 warning("no space to %s %s",
2098 "append option",
2100 goto supersede;
2101 }
2102 dp = dbuf;
2103 memcpy(dp,
2104 lease->options[i].data,
2105 lease->options[i].len);
2106 memcpy(dp + lease->options[i].len,
2107 ip->client->
2108 config->defaults[i].data,
2109 ip->client->
2110 config->defaults[i].len);
2111 dp[len-1] = '\0';
2112 }
2113 } else {
2114 dp = ip->client->
2115 config->defaults[i].data;
2116 len = ip->client->
2117 config->defaults[i].len;
2118 }
2119 } else if (lease->options[i].len) {
2120 len = lease->options[i].len;
2121 dp = lease->options[i].data;
2122 } else {
2123 len = 0;
2124 }
2125#if 0
2126 if (len) {
2127 char name[256];
2128
2129 if (dhcp_option_ev_name(name, sizeof(name),
2130 &dhcp_options[i]))
2131 script_set_env(ip->client, prefix, name,
2132 pretty_print_option(i, dp, len, 0, 0));
2133 }
2134#endif
2135 }
2136#if 0
2137 snprintf(tbuf, sizeof(tbuf), "%d", (int)lease->expiry);
2138 script_set_env(ip->client, prefix, "expiry", tbuf);
2139#endif
2140}
2141
2142int
2143dhcp_option_ev_name(char *buf, size_t buflen, struct dhcp_option *option)
2144{
2145 int i;
2146
2147 for (i = 0; option->name[i]; i++) {
2148 if (i + 1 == buflen)
2149 return 0;
2150 if (option->name[i] == '-')
2151 buf[i] = '_';
2152 else
2153 buf[i] = option->name[i];
2154 }
2155
2156 buf[i] = 0;
2157 return 1;
2158}
2159
2160#if 0
2161void
2162go_daemon(void)
2163{
2164 static int state = 0;
2165
2166 if (no_daemon || state)
2167 return;
2168
2169 state = 1;
2170
2171 /* Stop logging to stderr... */
2172 log_perror = 0;
2173
2174 if (daemon(1, 0) == -1)
2175 error("daemon");
2176
2177 /* we are chrooted, daemon(3) fails to open /dev/null */
2178 if (nullfd != -1) {
2179 dup2(nullfd, STDIN_FILENO);
2180 dup2(nullfd, STDOUT_FILENO);
2181 dup2(nullfd, STDERR_FILENO);
2182 close(nullfd);
2183 nullfd = -1;
2184 }
2185}
2186#endif
2187
2188int
2190{
2191 char *opbuf;
2192 char *sbuf;
2193
2194 /* we use this, since this is what gets passed to dhclient-script */
2195
2196 opbuf = pretty_print_option(option, l->options[option].data,
2197 l->options[option].len, 0, 0);
2198
2199 sbuf = option_as_string(option, l->options[option].data,
2200 l->options[option].len);
2201
2202 switch (option) {
2203 case DHO_SUBNET_MASK:
2204 case DHO_TIME_SERVERS:
2205 case DHO_NAME_SERVERS:
2206 case DHO_ROUTERS:
2208 case DHO_LOG_SERVERS:
2209 case DHO_COOKIE_SERVERS:
2210 case DHO_LPR_SERVERS:
2213 case DHO_SWAP_SERVER:
2215 case DHO_NIS_SERVERS:
2216 case DHO_NTP_SERVERS:
2219 case DHO_FONT_SERVERS:
2221 if (!ipv4addrs(opbuf)) {
2222 warning("Invalid IP address in option(%d): %s", option, opbuf);
2223 return (0);
2224 }
2225 return (1) ;
2226 case DHO_HOST_NAME:
2227 case DHO_DOMAIN_NAME:
2228 case DHO_NIS_DOMAIN:
2229 if (!res_hnok(sbuf))
2230 warning("Bogus Host Name option %d: %s (%s)", option,
2231 sbuf, opbuf);
2232 return (1);
2233 case DHO_PAD:
2234 case DHO_TIME_OFFSET:
2235 case DHO_BOOT_SIZE:
2236 case DHO_MERIT_DUMP:
2237 case DHO_ROOT_PATH:
2239 case DHO_IP_FORWARDING:
2241 case DHO_POLICY_FILTER:
2243 case DHO_DEFAULT_IP_TTL:
2246 case DHO_INTERFACE_MTU:
2249 case DHO_MASK_SUPPLIER:
2252 case DHO_STATIC_ROUTES:
2261 case DHO_NETBIOS_SCOPE:
2268 case DHO_DHCP_MESSAGE:
2275 case DHO_END:
2276 return (1);
2277 default:
2278 warning("unknown dhcp option value 0x%x", option);
2279 return (unknown_ok);
2280 }
2281}
2282
2283int
2284res_hnok(const char *dn)
2285{
2286 int pch = PERIOD, ch = *dn++;
2287
2288 while (ch != '\0') {
2289 int nch = *dn++;
2290
2291 if (periodchar(ch)) {
2292 ;
2293 } else if (periodchar(pch)) {
2294 if (!borderchar(ch))
2295 return (0);
2296 } else if (periodchar(nch) || nch == '\0') {
2297 if (!borderchar(ch))
2298 return (0);
2299 } else {
2300 if (!middlechar(ch))
2301 return (0);
2302 }
2303 pch = ch, ch = nch;
2304 }
2305 return (1);
2306}
2307
2308/* Does buf consist only of dotted decimal ipv4 addrs?
2309 * return how many if so,
2310 * otherwise, return 0
2311 */
2312int
2314{
2315 char *tmp;
2316 struct in_addr jnk;
2317 int i = 0;
2318
2319 note("Input: %s", buf);
2320
2321 do {
2322 tmp = strtok(buf, " ");
2323 note("got %s", tmp);
2324 if( tmp && inet_aton(tmp, &jnk) ) i++;
2325 buf = NULL;
2326 } while( tmp );
2327
2328 return (i);
2329}
2330
2331
2332char *
2333option_as_string(unsigned int code, unsigned char *data, int len)
2334{
2335 static char optbuf[32768]; /* XXX */
2336 char *op = optbuf;
2337 int opleft = sizeof(optbuf);
2338 unsigned char *dp = data;
2339
2340 if (code > 255)
2341 error("option_as_string: bad code %d", code);
2342
2343 for (; dp < data + len; dp++) {
2344 if (!isascii(*dp) || !isprint(*dp)) {
2345 if (dp + 1 != data + len || *dp != 0) {
2346 _snprintf(op, opleft, "\\%03o", *dp);
2347 op += 4;
2348 opleft -= 4;
2349 }
2350 } else if (*dp == '"' || *dp == '\'' || *dp == '$' ||
2351 *dp == '`' || *dp == '\\') {
2352 *op++ = '\\';
2353 *op++ = *dp;
2354 opleft -= 2;
2355 } else {
2356 *op++ = *dp;
2357 opleft--;
2358 }
2359 }
2360 if (opleft < 1)
2361 goto toobig;
2362 *op = 0;
2363 return optbuf;
2364toobig:
2365 warning("dhcp option too large");
2366 return "<error>";
2367}
2368
#define isprint(c)
Definition: acclib.h:73
#define close
Definition: acwin.h:98
CHAR FAR *WSAAPI inet_ntoa(IN IN_ADDR in)
Definition: addrconv.c:160
#define inet_aton(ap, inp)
Definition: adns_win32.h:161
static int state
Definition: maze.c:121
LONG NTSTATUS
Definition: precomp.h:26
void AdapterInit()
Definition: adapter.c:289
PDHCP_ADAPTER AdapterFindInfo(struct interface_info *ip)
Definition: adapter.c:638
VOID ApiInit()
Definition: api.c:18
void cancel_timeout(void(*where)(void *), void *what)
Definition: dispatch.c:316
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
char * pretty_print_option(unsigned int code, unsigned char *data, int len, int emit_commas, int emit_quotes)
Definition: options.c:396
int cons_options(struct packet *inpacket, struct dhcp_packet *outpacket, int mms, struct tree_cache **options)
Definition: options.c:199
void do_packet(struct interface_info *interface, struct dhcp_packet *packet, int len, unsigned int from_port, struct iaddr from, struct hardware *hfrom)
Definition: options.c:635
struct dhcp_option dhcp_options[256]
Definition: tables.c:68
int note(char *format,...)
Definition: util.c:12
int addr_eq(struct iaddr a, struct iaddr b)
Definition: util.c:100
struct iaddr broadcast_addr(struct iaddr addr, struct iaddr mask)
Definition: util.c:178
char * piaddr(struct iaddr addr)
Definition: util.c:6
u_int32_t getULong(unsigned char *data)
Definition: util.c:96
struct iaddr subnet_number(struct iaddr addr, struct iaddr mask)
Definition: util.c:183
#define MID_TRACE
Definition: debug.h:15
#define DH_DbgPrint(_t_, _x_)
Definition: debug.h:49
#define DHO_DHCP_MESSAGE
Definition: dhcp.h:152
#define DHO_MASK_SUPPLIER
Definition: dhcp.h:126
#define DHCPREQUEST
Definition: dhcp.h:164
#define DHO_TCP_KEEPALIVE_GARBAGE
Definition: dhcp.h:135
#define DHO_DHCP_MAX_MESSAGE_SIZE
Definition: dhcp.h:153
#define DHO_ROUTER_DISCOVERY
Definition: dhcp.h:127
#define DHO_NAME_SERVERS
Definition: dhcp.h:101
#define DHO_VENDOR_ENCAPSULATED_OPTIONS
Definition: dhcp.h:139
#define DHO_PERFORM_MASK_DISCOVERY
Definition: dhcp.h:125
#define DHO_NIS_SERVERS
Definition: dhcp.h:137
#define BOOTP_MIN_LEN
Definition: dhcp.h:54
#define DHO_NON_LOCAL_SOURCE_ROUTING
Definition: dhcp.h:116
#define DHCPRELEASE
Definition: dhcp.h:168
#define DHO_NTP_SERVERS
Definition: dhcp.h:138
#define DHO_MERIT_DUMP
Definition: dhcp.h:110
#define DHO_NETBIOS_NAME_SERVERS
Definition: dhcp.h:140
#define DHO_DHCP_PARAMETER_REQUEST_LIST
Definition: dhcp.h:151
#define DHO_FONT_SERVERS
Definition: dhcp.h:144
#define DHO_NETBIOS_SCOPE
Definition: dhcp.h:143
#define DHCPNAK
Definition: dhcp.h:167
#define DHCP_SNAME_LEN
Definition: dhcp.h:46
#define DHO_LOG_SERVERS
Definition: dhcp.h:103
#define DHCPACK
Definition: dhcp.h:166
#define DHCP_FILE_LEN
Definition: dhcp.h:47
#define DHO_NETBIOS_NODE_TYPE
Definition: dhcp.h:142
#define DHO_NIS_DOMAIN
Definition: dhcp.h:136
#define BOOTREPLY
Definition: dhcp.h:79
#define DHO_PAD
Definition: dhcp.h:96
#define DHO_HOST_NAME
Definition: dhcp.h:108
#define DHO_TCP_KEEPALIVE_INTERVAL
Definition: dhcp.h:134
#define DHO_BROADCAST_ADDRESS
Definition: dhcp.h:124
#define DHO_TIME_SERVERS
Definition: dhcp.h:100
#define DHO_NETBIOS_DD_SERVER
Definition: dhcp.h:141
#define DHO_IP_FORWARDING
Definition: dhcp.h:115
#define DHO_IMPRESS_SERVERS
Definition: dhcp.h:106
#define DHO_TRAILER_ENCAPSULATION
Definition: dhcp.h:130
#define DHO_PATH_MTU_PLATEAU_TABLE
Definition: dhcp.h:121
#define DHO_DHCP_USER_CLASS_ID
Definition: dhcp.h:158
#define DHO_EXTENSIONS_PATH
Definition: dhcp.h:114
#define DHO_DHCP_CLIENT_IDENTIFIER
Definition: dhcp.h:157
#define DHO_TIME_OFFSET
Definition: dhcp.h:98
#define DHO_DEFAULT_TCP_TTL
Definition: dhcp.h:133
#define DHO_DHCP_MESSAGE_TYPE
Definition: dhcp.h:149
#define DHO_INTERFACE_MTU
Definition: dhcp.h:122
#define DHO_X_DISPLAY_MANAGER
Definition: dhcp.h:145
#define DHO_POLICY_FILTER
Definition: dhcp.h:117
#define DHO_ALL_SUBNETS_LOCAL
Definition: dhcp.h:123
#define DHO_MAX_DGRAM_REASSEMBLY
Definition: dhcp.h:118
#define BOOTREQUEST
Definition: dhcp.h:78
#define DHCPDISCOVER
Definition: dhcp.h:162
#define DHO_END
Definition: dhcp.h:159
#define DHO_COOKIE_SERVERS
Definition: dhcp.h:104
#define DHO_DOMAIN_NAME
Definition: dhcp.h:111
#define DHO_DHCP_RENEWAL_TIME
Definition: dhcp.h:154
#define DHCPOFFER
Definition: dhcp.h:163
#define DHO_SWAP_SERVER
Definition: dhcp.h:112
#define DHO_DOMAIN_NAME_SERVERS
Definition: dhcp.h:102
#define DHO_DEFAULT_IP_TTL
Definition: dhcp.h:119
#define DHO_BOOT_SIZE
Definition: dhcp.h:109
#define DHO_DHCP_REBINDING_TIME
Definition: dhcp.h:155
#define DHO_DHCP_OPTION_OVERLOAD
Definition: dhcp.h:148
#define DHO_DHCP_SERVER_IDENTIFIER
Definition: dhcp.h:150
#define DHO_ROOT_PATH
Definition: dhcp.h:113
#define DHO_ARP_CACHE_TIMEOUT
Definition: dhcp.h:131
#define DHO_ROUTERS
Definition: dhcp.h:99
#define DHO_IEEE802_3_ENCAPSULATION
Definition: dhcp.h:132
#define DHO_DHCP_REQUESTED_ADDRESS
Definition: dhcp.h:146
#define DHO_DHCP_LEASE_TIME
Definition: dhcp.h:147
#define DHO_STATIC_ROUTES
Definition: dhcp.h:129
#define DHO_SUBNET_MASK
Definition: dhcp.h:97
#define DHO_DHCP_CLASS_IDENTIFIER
Definition: dhcp.h:156
#define DHO_LPR_SERVERS
Definition: dhcp.h:105
#define DHO_ROUTER_SOLICITATION_ADDRESS
Definition: dhcp.h:128
#define DHCPDECLINE
Definition: dhcp.h:165
#define DHO_PATH_MTU_AGING_TIMEOUT
Definition: dhcp.h:120
#define DHO_RESOURCE_LOCATION_SERVERS
Definition: dhcp.h:107
#define RegCloseKey(hKey)
Definition: registry.h:49
r l[0]
Definition: byte_order.h:168
Definition: bufpool.h:45
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define BufferSize
Definition: mmc.h:75
#define ERROR_SUCCESS
Definition: deptool.c:10
void make_request(struct interface_info *ip, struct client_lease *lease)
Definition: dhclient.c:1651
void unset_domain(PDHCP_ADAPTER Adapter)
Definition: dhclient.c:533
#define TIME_MAX
Definition: dhclient.c:90
int init_client(void)
Definition: dhclient.c:111
struct client_lease * packet_to_lease(struct packet *packet)
Definition: dhclient.c:974
void make_release(struct interface_info *ip, struct client_lease *lease)
Definition: dhclient.c:1827
void bootp(struct packet *packet)
Definition: dhclient.c:799
int unknown_ok
Definition: dhclient.c:94
void bind_lease(struct interface_info *ip)
Definition: dhclient.c:703
void dhcp(struct packet *packet)
Definition: dhclient.c:819
#define middlechar(c)
Definition: dhclient.c:68
char * path_dhclient_db
Definition: dhclient.c:74
int privfd
Definition: dhclient.c:77
void send_discover(void *ipp)
Definition: dhclient.c:1108
void free_client_lease(struct client_lease *lease)
Definition: dhclient.c:1891
void dhcpnak(struct packet *packet)
Definition: dhclient.c:1068
int dhcp_option_ev_name(char *buf, size_t buflen, struct dhcp_option *option)
Definition: dhclient.c:2143
struct iaddr iaddr_broadcast
Definition: dhclient.c:80
void write_client_lease(struct interface_info *ip, struct client_lease *lease, int rewrite)
Definition: dhclient.c:1931
struct in_addr inaddr_any
Definition: dhclient.c:81
int check_option(struct client_lease *l, int option)
Definition: dhclient.c:2189
void unset_name_servers(PDHCP_ADAPTER Adapter)
Definition: dhclient.c:466
void state_bound(void *ipp)
Definition: dhclient.c:773
int ipv4addrs(char *buf)
Definition: dhclient.c:2313
void send_release(void *ipp)
Definition: dhclient.c:1543
char * path_dhclient_conf
Definition: dhclient.c:73
void setup_adapter(PDHCP_ADAPTER Adapter, struct client_lease *new_lease)
Definition: dhclient.c:561
int fork_privchld(int, int)
void make_decline(struct interface_info *ip, struct client_lease *lease)
Definition: dhclient.c:1753
#define periodchar(c)
Definition: dhclient.c:61
struct sockaddr_in sockaddr_broadcast
Definition: dhclient.c:82
int no_daemon
Definition: dhclient.c:93
void state_selecting(void *ipp)
Definition: dhclient.c:257
void send_decline(void *ipp)
Definition: dhclient.c:1529
void state_release(void *ipp)
Definition: dhclient.c:231
int check_arp(struct interface_info *ip, struct client_lease *lp)
Definition: dhclient.c:137
void state_reboot(void *ipp)
Definition: dhclient.c:172
void set_domain(PDHCP_ADAPTER Adapter, struct client_lease *new_lease)
Definition: dhclient.c:483
void dhcpack(struct packet *packet)
Definition: dhclient.c:338
void state_panic(void *ipp)
Definition: dhclient.c:1214
void unbind_lease(struct interface_info *ip)
Definition: dhclient.c:745
void stop_client(void)
Definition: dhclient.c:129
#define borderchar(c)
Definition: dhclient.c:67
FILE * leaseFile
Definition: dhclient.c:1906
char * option_as_string(unsigned int code, unsigned char *data, int len)
Definition: dhclient.c:2333
int log_perror
Definition: dhclient.c:76
void reset_adapter(PDHCP_ADAPTER Adapter)
Definition: dhclient.c:652
void priv_script_init(struct interface_info *ip, char *reason, char *medium)
Definition: dhclient.c:1997
void priv_script_write_params(struct interface_info *ip, char *prefix, struct client_lease *lease)
Definition: dhclient.c:2005
time_t scripttime
Definition: dhclient.c:107
void state_init(void *ipp)
Definition: dhclient.c:210
int routefd
Definition: dhclient.c:95
int res_hnok(const char *dn)
Definition: dhclient.c:2284
int log_priority
Definition: dhclient.c:92
#define ASSERT_STATE(state_is, state_shouldbe)
Definition: dhclient.c:88
void set_name_servers(PDHCP_ADAPTER Adapter, struct client_lease *new_lease)
Definition: dhclient.c:421
void rewrite_client_leases(struct interface_info *ifi)
Definition: dhclient.c:1909
void usage(void)
void dhcpoffer(struct packet *packet)
Definition: dhclient.c:855
unsigned long debug_trace_level
Definition: dhclient.c:71
#define PERIOD
Definition: dhclient.c:58
void make_discover(struct interface_info *ip, struct client_lease *lease)
Definition: dhclient.c:1568
void go_daemon(void)
time_t cur_time
@ S_RELEASED
Definition: dhcpd.h:180
@ S_REBOOTING
Definition: dhcpd.h:172
@ S_BOUND
Definition: dhcpd.h:176
@ S_RENEWING
Definition: dhcpd.h:177
@ S_REBINDING
Definition: dhcpd.h:178
@ S_SELECTING
Definition: dhcpd.h:174
@ S_REQUESTING
Definition: dhcpd.h:175
@ S_INIT
Definition: dhcpd.h:173
#define REMOTE_PORT
Definition: dhcpd.h:113
#define _PATH_DHCLIENT_CONF
Definition: dhcpd.h:277
void script_set_env(struct client_state *, const char *, const char *, const char *)
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
UINT op
Definition: effect.c:236
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4799
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3298
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2287
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2330
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1904
#define MAX_PATH
Definition: compat.h:34
ULONG WINAPI DECLSPEC_HOTPATCH GetTickCount(void)
Definition: sync.c:182
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7512
unsigned char ch[4][2]
Definition: console.c:118
int WINAPIV fprintf(FILE *file, const char *format,...)
Definition: file.c:5549
FILE *CDECL fopen(const char *path, const char *mode)
Definition: file.c:4310
void CDECL rewind(FILE *file)
Definition: file.c:1712
int CDECL fflush(FILE *file)
Definition: file.c:1182
__time32_t time_t
Definition: corecrt.h:228
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
static int dup2(int od, int nd)
Definition: io.h:20
unsigned short uint16_t
Definition: stdint.h:35
static int __cdecl _snprintf(char *buffer, size_t size, const char *format,...) __WINE_CRT_PRINTF_ATTR(3
Definition: stdio.h:507
#define STDOUT_FILENO
Definition: stdio.h:25
#define STDERR_FILENO
Definition: stdio.h:26
#define STDIN_FILENO
Definition: stdio.h:24
_ACRTIMP int __cdecl rand(void)
Definition: misc.c:59
_ACRTIMP void __cdecl srand(unsigned int)
Definition: misc.c:50
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
_ACRTIMP char *__cdecl strtok(char *, const char *)
Definition: string.c:285
static struct tm * gmtime(const time_t *t)
Definition: time.h:120
int nch
Definition: scanf.h:201
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
#define AF_INET
Definition: tcpip.h:117
unsigned long DWORD
Definition: ntddk_ex.h:95
static void increase(int &a_)
FxAutoRegKey hKey
Status
Definition: gdiplustypes.h:25
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble t
Definition: gl.h:2047
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum const GLvoid * addr
Definition: glext.h:9621
GLenum GLsizei len
Definition: glext.h:6722
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 const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
DWORD WINAPI AddIPAddress(IPAddr Address, IPMask Netmask, DWORD IfIndex, PULONG NteContext, PULONG NteInstance)
Definition: iphlpapi_main.c:67
DWORD WINAPI DeleteIpForwardEntry(PMIB_IPFORWARDROW pRoute)
DWORD WINAPI CreateIpForwardEntry(PMIB_IPFORWARDROW pRoute)
DWORD WINAPI DeleteIPAddress(ULONG NTEContext)
DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAddrLen)
#define debug(msg)
Definition: key_call.c:71
#define REG_SZ
Definition: layer.c:22
#define INADDR_BROADCAST
Definition: inet.h:82
#define INADDR_ANY
Definition: inet.h:80
__u16 time
Definition: mkdosfs.c:8
#define error(str)
Definition: mkdosfs.c:1605
#define pch(ap)
Definition: match.c:418
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define htons(x)
Definition: module.h:215
#define ntohs(x)
Definition: module.h:210
#define htonl(x)
Definition: module.h:214
#define sprintf
Definition: sprintf.c:45
NTSYSAPI ULONG NTAPI RtlRandom(_Inout_ PULONG Seed)
#define KEY_WRITE
Definition: nt_native.h:1034
char CHAR
Definition: pedump.c:57
ULONG IPAddr
Definition: pfhook.h:35
static unsigned __int64 next
Definition: rand_nt.c:6
unsigned char u_int8_t
Definition: rosdhcp.h:37
#define DHCP_DEFAULT_LEASE_TIME
Definition: rosdhcp.h:34
#define REG_DWORD
Definition: sdbapi.c:615
#define isascii
Definition: ctype.h:742
_CRTIMP void __cdecl tzset(void)
#define warning(s)
Definition: debug.h:83
strcat
Definition: string.h:92
#define memset(x, y, z)
Definition: compat.h:39
ssize_t send_packet(struct interface_info *ip, struct dhcp_packet *p, size_t size, struct in_addr addr, struct sockaddr_in *broadcast, struct hardware *hardware)
Definition: socket.c:9
CardRegion * from
Definition: spigame.cpp:19
static void Server(int port)
Definition: srltest.c:69
ULONG NteContext
Definition: rosdhcp.h:85
ULONG NteInstance
Definition: rosdhcp.h:85
MIB_IPFORWARDROW RouterMib
Definition: rosdhcp.h:82
PALTERNATE_CONFIGURATION AlternateConfiguration
Definition: rosdhcp.h:80
struct interface_info DhclientInfo
Definition: rosdhcp.h:86
MIB_IFROW IfMib
Definition: rosdhcp.h:81
DWORD dwIndex
Definition: ifmib.h:38
DWORD dwForwardNextHop
Definition: ipmib.h:74
DWORD dwForwardMetric1
Definition: ipmib.h:88
IF_INDEX dwForwardIfIndex
Definition: ipmib.h:75
DWORD dwForwardDest
Definition: ipmib.h:71
DWORD dwForwardMask
Definition: ipmib.h:72
unsigned int is_static
Definition: dhcpd.h:165
struct string_list * medium
Definition: dhcpd.h:164
struct option_data options[256]
Definition: dhcpd.h:167
struct iaddr address
Definition: dhcpd.h:156
char * filename
Definition: dhcpd.h:163
char * server_name
Definition: dhcpd.h:157
unsigned int is_bootp
Definition: dhcpd.h:166
struct client_lease * next
Definition: dhcpd.h:154
time_t renewal
Definition: dhcpd.h:155
time_t rebind
Definition: dhcpd.h:155
time_t expiry
Definition: dhcpd.h:155
Definition: inflate.c:139
Definition: dhcpd.h:125
int len
Definition: dhcpd.h:126
unsigned char iabuf[16]
Definition: dhcpd.h:127
Definition: tcpip.h:126
struct client_state * client
Definition: dhcpd.h:241
Definition: dhcpd.h:62
Definition: name.c:39
Definition: getopt.h:109
WCHAR * name
Definition: getopt.h:110
Definition: dhcpd.h:135
struct dhcp_packet * raw
Definition: dhcpd.h:136
struct interface_info * interface
Definition: dhcpd.h:142
struct option_data options[256]
Definition: dhcpd.h:144
int packet_type
Definition: dhcpd.h:138
struct iaddr client_addr
Definition: dhcpd.h:141
Definition: tftpd.h:86
struct in_addr sin_addr
Definition: winsock.h:506
short sin_family
Definition: winsock.h:504
u_short sin_port
Definition: winsock.h:505
NTSYSAPI PSTR NTAPI RtlIpv4AddressToStringA(_In_ const struct in_addr *Addr, _Out_writes_(16) PSTR S)
Character const *const prefix
Definition: tempnam.cpp:195
static const u8_t broadcast[6]
Definition: test_dhcp.c:23
unsigned char * LPBYTE
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define snprintf
Definition: wintirpc.h:48