ReactOS  0.4.15-dev-3446-g30010a5
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 
71 unsigned long debug_trace_level = 0; /* DEBUG_ULTRA */
72 
75 
76 int log_perror = 1;
77 int privfd;
78 //int nullfd = -1;
79 
80 struct 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 
94 int unknown_ok = 1;
95 int routefd;
96 
97 void usage(void);
98 int check_option(struct client_lease *l, int option);
99 int ipv4addrs(char * buf);
100 int res_hnok(const char *dn);
101 char *option_as_string(unsigned int code, unsigned char *data, int len);
102 int fork_privchld(int, int);
103 int check_arp( struct interface_info *ip, struct client_lease *lp );
104 
105 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
106 
108 
109 
110 int
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 
128 void
130 {
131  // AdapterStop();
132  // ApiFree();
133  /* FIXME: Close pipe and kill pipe thread */
134 }
135 
136 /* XXX Implement me */
137 int 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 
171 void
172 state_reboot(void *ipp)
173 {
174  struct interface_info *ip = ipp;
175  ULONG foo = (ULONG) GetTickCount();
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. */
202  send_request(ip);
203 }
204 
205 /*
206  * Called when a lease has completely expired and we've
207  * been unable to renew it.
208  */
209 void
210 state_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. */
227  send_discover(ip);
228 }
229 
230 /*
231  * state_selecting is called when one or more DHCPOFFER packets
232  * have been received and a configurable period of time has passed.
233  */
234 void
235 state_selecting(void *ipp)
236 {
237  struct interface_info *ip = ipp;
238  struct client_lease *lp, *next, *picked;
240 
242 
243  time(&cur_time);
244 
245  /* Cancel state_selecting and send_discover timeouts, since either
246  one could have got us here. */
249 
250  /* We have received one or more DHCPOFFER packets. Currently,
251  the only criterion by which we judge leases is whether or
252  not we get a response when we arp for them. */
253  picked = NULL;
254  for (lp = ip->client->offered_leases; lp; lp = next) {
255  next = lp->next;
256 
257  /* Check to see if we got an ARPREPLY for the address
258  in this particular lease. */
259  if (!picked) {
260  if( !check_arp(ip,lp) ) goto freeit;
261  picked = lp;
262  picked->next = NULL;
263  } else {
264 freeit:
265  free_client_lease(lp);
266  }
267  }
268  ip->client->offered_leases = NULL;
269 
270  /* If we just tossed all the leases we were offered, go back
271  to square one. */
272  if (!picked) {
273  ip->client->state = S_INIT;
274  state_init(ip);
275  return;
276  }
277 
278  /* If it was a BOOTREPLY, we can just take the address right now. */
279  if (!picked->options[DHO_DHCP_MESSAGE_TYPE].len) {
280  ip->client->new = picked;
281 
282  /* Make up some lease expiry times
283  XXX these should be configurable. */
284  ip->client->new->expiry = cur_time + 12000;
285  ip->client->new->renewal += cur_time + 8000;
286  ip->client->new->rebind += cur_time + 10000;
287 
288  ip->client->state = S_REQUESTING;
289 
290  /* Bind to the address we received. */
291  bind_lease(ip);
292  return;
293  }
294 
295  /* Go to the REQUESTING state. */
296  ip->client->destination = iaddr_broadcast;
297  ip->client->state = S_REQUESTING;
298  ip->client->first_sending = cur_time;
299  ip->client->interval = ip->client->config->initial_interval;
300 
301  /* Make a DHCPREQUEST packet from the lease we picked. */
302  make_request(ip, picked);
303  ip->client->xid = ip->client->packet.xid;
304 
305  /* Toss the lease we picked - we'll get it back in a DHCPACK. */
306  free_client_lease(picked);
307 
308  /* Add an immediate timeout to send the first DHCPREQUEST packet. */
309  send_request(ip);
310 }
311 
312 /* state_requesting is called when we receive a DHCPACK message after
313  having sent out one or more DHCPREQUEST packets. */
314 
315 void
317 {
318  struct interface_info *ip = packet->interface;
319  struct client_lease *lease;
321 
322  time(&cur_time);
323 
324  /* If we're not receptive to an offer right now, or if the offer
325  has an unrecognizable transaction id, then just drop it. */
326  if (packet->interface->client->xid != packet->raw->xid ||
327  (packet->interface->hw_address.hlen != packet->raw->hlen) ||
328  (memcmp(packet->interface->hw_address.haddr,
329  packet->raw->chaddr, packet->raw->hlen)))
330  return;
331 
332  if (ip->client->state != S_REBOOTING &&
333  ip->client->state != S_REQUESTING &&
334  ip->client->state != S_RENEWING &&
335  ip->client->state != S_REBINDING)
336  return;
337 
338  note("DHCPACK from %s", piaddr(packet->client_addr));
339 
340  lease = packet_to_lease(packet);
341  if (!lease) {
342  note("packet_to_lease failed.");
343  return;
344  }
345 
346  ip->client->new = lease;
347 
348  /* Stop resending DHCPREQUEST. */
350 
351  /* Figure out the lease time. */
352  if (ip->client->new->options[DHO_DHCP_LEASE_TIME].data)
353  ip->client->new->expiry = getULong(
354  ip->client->new->options[DHO_DHCP_LEASE_TIME].data);
355  else
356  ip->client->new->expiry = DHCP_DEFAULT_LEASE_TIME;
357  /* A number that looks negative here is really just very large,
358  because the lease expiry offset is unsigned. */
359  if (ip->client->new->expiry < 0)
360  ip->client->new->expiry = TIME_MAX;
361  /* XXX should be fixed by resetting the client state */
362  if (ip->client->new->expiry < 60)
363  ip->client->new->expiry = 60;
364 
365  /* Take the server-provided renewal time if there is one;
366  otherwise figure it out according to the spec. */
367  if (ip->client->new->options[DHO_DHCP_RENEWAL_TIME].len)
368  ip->client->new->renewal = getULong(
369  ip->client->new->options[DHO_DHCP_RENEWAL_TIME].data);
370  else
371  ip->client->new->renewal = ip->client->new->expiry / 2;
372 
373  /* Same deal with the rebind time. */
374  if (ip->client->new->options[DHO_DHCP_REBINDING_TIME].len)
375  ip->client->new->rebind = getULong(
376  ip->client->new->options[DHO_DHCP_REBINDING_TIME].data);
377  else
378  ip->client->new->rebind = ip->client->new->renewal +
379  ip->client->new->renewal / 2 + ip->client->new->renewal / 4;
380 
381 #ifdef __REACTOS__
382  ip->client->new->obtained = cur_time;
383 #endif
384  ip->client->new->expiry += cur_time;
385  /* Lease lengths can never be negative. */
386  if (ip->client->new->expiry < cur_time)
387  ip->client->new->expiry = TIME_MAX;
388  ip->client->new->renewal += cur_time;
389  if (ip->client->new->renewal < cur_time)
390  ip->client->new->renewal = TIME_MAX;
391  ip->client->new->rebind += cur_time;
392  if (ip->client->new->rebind < cur_time)
393  ip->client->new->rebind = TIME_MAX;
394 
395  bind_lease(ip);
396 }
397 
398 void set_name_servers( PDHCP_ADAPTER Adapter, struct client_lease *new_lease ) {
399  CHAR Buffer[200] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
400  HKEY RegKey;
401 
402  strcat(Buffer, Adapter->DhclientInfo.name);
404  return;
405 
406 
407  if( new_lease->options[DHO_DOMAIN_NAME_SERVERS].len ) {
408 
409  struct iaddr nameserver;
410  char *nsbuf;
411  int i, addrs =
412  new_lease->options[DHO_DOMAIN_NAME_SERVERS].len / sizeof(ULONG);
413 
414  nsbuf = malloc( addrs * sizeof(IP_ADDRESS_STRING) );
415 
416  if( nsbuf) {
417  nsbuf[0] = 0;
418  for( i = 0; i < addrs; i++ ) {
419  nameserver.len = sizeof(ULONG);
420  memcpy( nameserver.iabuf,
421  new_lease->options[DHO_DOMAIN_NAME_SERVERS].data +
422  (i * sizeof(ULONG)), sizeof(ULONG) );
423  strcat( nsbuf, piaddr(nameserver) );
424  if( i != addrs-1 ) strcat( nsbuf, "," );
425  }
426 
427  DH_DbgPrint(MID_TRACE,("Setting DhcpNameserver: %s\n", nsbuf));
428 
429  RegSetValueExA( RegKey, "DhcpNameServer", 0, REG_SZ,
430  (LPBYTE)nsbuf, strlen(nsbuf) + 1 );
431  free( nsbuf );
432  }
433 
434  } else {
435  RegDeleteValueW( RegKey, L"DhcpNameServer" );
436  }
437 
438  RegCloseKey( RegKey );
439 
440 }
441 
442 void
444  struct client_lease *new_lease)
445 {
446  CHAR Buffer1[MAX_PATH] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
447  CHAR Buffer2[MAX_PATH] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters";
448  HKEY RegKey1, RegKey2;
449 
450  strcat(Buffer1, Adapter->DhclientInfo.name);
451 
452  if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, Buffer1, 0, KEY_WRITE, &RegKey1 ) != ERROR_SUCCESS)
453  {
454  return;
455  }
456 
457  if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, Buffer2, 0, KEY_WRITE, &RegKey2 ) != ERROR_SUCCESS)
458  {
459  RegCloseKey(RegKey1);
460  return;
461  }
462 
463  if (new_lease->options[DHO_DOMAIN_NAME].len)
464  {
465  DH_DbgPrint(MID_TRACE, ("Setting DhcpDomain: %s\n", new_lease->options[DHO_DOMAIN_NAME].data));
466 
467  RegSetValueExA(RegKey1,
468  "DhcpDomain",
469  0,
470  REG_SZ,
471  (LPBYTE)new_lease->options[DHO_DOMAIN_NAME].data,
472  new_lease->options[DHO_DOMAIN_NAME].len);
473 
474  RegSetValueExA(RegKey2,
475  "DhcpDomain",
476  0,
477  REG_SZ,
478  (LPBYTE)new_lease->options[DHO_DOMAIN_NAME].data,
479  new_lease->options[DHO_DOMAIN_NAME].len);
480  }
481  else
482  {
483  RegDeleteValueW(RegKey1, L"DhcpDomain");
484  RegDeleteValueW(RegKey2, L"DhcpDomain");
485  }
486 
487  RegCloseKey(RegKey1);
488  RegCloseKey(RegKey2);
489 
490 }
491 
492 void setup_adapter( PDHCP_ADAPTER Adapter, struct client_lease *new_lease ) {
493  CHAR Buffer[200] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
494  struct iaddr netmask;
495  HKEY hkey;
496  int i;
497  DWORD dwEnableDHCP;
498 
499  strcat(Buffer, Adapter->DhclientInfo.name);
501  hkey = NULL;
502 
503 
504  if( Adapter->NteContext )
505  {
506  DeleteIPAddress( Adapter->NteContext );
507  Adapter->NteContext = 0;
508  }
509 
510  /* Set up our default router if we got one from the DHCP server */
511  if( new_lease->options[DHO_SUBNET_MASK].len ) {
513 
514  memcpy( netmask.iabuf,
515  new_lease->options[DHO_SUBNET_MASK].data,
516  new_lease->options[DHO_SUBNET_MASK].len );
518  ( *((ULONG*)new_lease->address.iabuf),
519  *((ULONG*)netmask.iabuf),
520  Adapter->IfMib.dwIndex,
521  &Adapter->NteContext,
522  &Adapter->NteInstance );
523  if (hkey) {
524  RegSetValueExA(hkey, "DhcpIPAddress", 0, REG_SZ, (LPBYTE)piaddr(new_lease->address), strlen(piaddr(new_lease->address))+1);
525  Buffer[0] = '\0';
526  for(i = 0; i < new_lease->options[DHO_SUBNET_MASK].len; i++)
527  {
528  sprintf(&Buffer[strlen(Buffer)], "%u", new_lease->options[DHO_SUBNET_MASK].data[i]);
529  if (i + 1 < new_lease->options[DHO_SUBNET_MASK].len)
530  strcat(Buffer, ".");
531  }
532  RegSetValueExA(hkey, "DhcpSubnetMask", 0, REG_SZ, (LPBYTE)Buffer, strlen(Buffer)+1);
533  dwEnableDHCP = 1;
534  RegSetValueExA(hkey, "EnableDHCP", 0, REG_DWORD, (LPBYTE)&dwEnableDHCP, sizeof(DWORD));
535  }
536 
537  if( !NT_SUCCESS(Status) )
538  warning("AddIPAddress: %lx\n", Status);
539  }
540 
541  if( new_lease->options[DHO_ROUTERS].len ) {
543 
544  Adapter->RouterMib.dwForwardDest = 0; /* Default route */
545  Adapter->RouterMib.dwForwardMask = 0;
546  Adapter->RouterMib.dwForwardMetric1 = 1;
547  Adapter->RouterMib.dwForwardIfIndex = Adapter->IfMib.dwIndex;
548 
549  if( Adapter->RouterMib.dwForwardNextHop ) {
550  /* If we set a default route before, delete it before continuing */
551  DeleteIpForwardEntry( &Adapter->RouterMib );
552  }
553 
554  Adapter->RouterMib.dwForwardNextHop =
555  *((ULONG*)new_lease->options[DHO_ROUTERS].data);
556 
557  Status = CreateIpForwardEntry( &Adapter->RouterMib );
558 
559  if( !NT_SUCCESS(Status) )
560  warning("CreateIpForwardEntry: %lx\n", Status);
561 
562  if (hkey) {
563  Buffer[0] = '\0';
564  for(i = 0; i < new_lease->options[DHO_ROUTERS].len; i++)
565  {
566  sprintf(&Buffer[strlen(Buffer)], "%u", new_lease->options[DHO_ROUTERS].data[i]);
567  if (i + 1 < new_lease->options[DHO_ROUTERS].len)
568  strcat(Buffer, ".");
569  }
570  RegSetValueExA(hkey, "DhcpDefaultGateway", 0, REG_SZ, (LPBYTE)Buffer, strlen(Buffer)+1);
571  }
572  }
573 
574  if (hkey)
575  RegCloseKey(hkey);
576 }
577 
578 
579 void
581 {
582  PDHCP_ADAPTER Adapter;
583  struct client_lease *new_lease = ip->client->new;
585 
586  time(&cur_time);
587 
588  /* Remember the medium. */
589  ip->client->new->medium = ip->client->medium;
590 
591  /* Replace the old active lease with the new one. */
592  if (ip->client->active)
593  free_client_lease(ip->client->active);
594  ip->client->active = ip->client->new;
595  ip->client->new = NULL;
596 
597  /* Set up a timeout to start the renewal process. */
598  /* Timeout of zero means no timeout (some implementations seem to use
599  * one day).
600  */
601  if( ip->client->active->renewal - cur_time )
602  add_timeout(ip->client->active->renewal, state_bound, ip);
603 
604  note("bound to %s -- renewal in %ld seconds.",
605  piaddr(ip->client->active->address),
606  (long int)(ip->client->active->renewal - cur_time));
607 
608  ip->client->state = S_BOUND;
609 
610  Adapter = AdapterFindInfo( ip );
611 
612  if( Adapter ) setup_adapter( Adapter, new_lease );
613  else {
614  warning("Could not find adapter for info %p\n", ip);
615  return;
616  }
617  set_name_servers( Adapter, new_lease );
618  set_domain( Adapter, new_lease );
619 }
620 
621 /*
622  * state_bound is called when we've successfully bound to a particular
623  * lease, but the renewal time on that lease has expired. We are
624  * expected to unicast a DHCPREQUEST to the server that gave us our
625  * original lease.
626  */
627 void
628 state_bound(void *ipp)
629 {
630  struct interface_info *ip = ipp;
631 
633 
634  /* T1 has expired. */
635  make_request(ip, ip->client->active);
636  ip->client->xid = ip->client->packet.xid;
637 
638  if (ip->client->active->options[DHO_DHCP_SERVER_IDENTIFIER].len == 4) {
639  memcpy(ip->client->destination.iabuf, ip->client->active->
641  ip->client->destination.len = 4;
642  } else
643  ip->client->destination = iaddr_broadcast;
644 
645  time(&ip->client->first_sending);
646  ip->client->interval = ip->client->config->initial_interval;
647  ip->client->state = S_RENEWING;
648 
649  /* Send the first packet immediately. */
650  send_request(ip);
651 }
652 
653 void
655 {
656  struct iaddrlist *ap;
657 
658  if (packet->raw->op != BOOTREPLY)
659  return;
660 
661  /* If there's a reject list, make sure this packet's sender isn't
662  on it. */
663  for (ap = packet->interface->client->config->reject_list;
664  ap; ap = ap->next) {
665  if (addr_eq(packet->client_addr, ap->addr)) {
666  note("BOOTREPLY from %s rejected.", piaddr(ap->addr));
667  return;
668  }
669  }
670  dhcpoffer(packet);
671 }
672 
673 void
675 {
676  struct iaddrlist *ap;
677  void (*handler)(struct packet *);
678  char *type;
679 
680  switch (packet->packet_type) {
681  case DHCPOFFER:
682  handler = dhcpoffer;
683  type = "DHCPOFFER";
684  break;
685  case DHCPNAK:
686  handler = dhcpnak;
687  type = "DHCPNACK";
688  break;
689  case DHCPACK:
690  handler = dhcpack;
691  type = "DHCPACK";
692  break;
693  default:
694  return;
695  }
696 
697  /* If there's a reject list, make sure this packet's sender isn't
698  on it. */
699  for (ap = packet->interface->client->config->reject_list;
700  ap; ap = ap->next) {
701  if (addr_eq(packet->client_addr, ap->addr)) {
702  note("%s from %s rejected.", type, piaddr(ap->addr));
703  return;
704  }
705  }
706  (*handler)(packet);
707 }
708 
709 void
711 {
712  struct interface_info *ip = packet->interface;
713  struct client_lease *lease, *lp;
714  int i;
715  int arp_timeout_needed = 0, stop_selecting;
716  char *name = packet->options[DHO_DHCP_MESSAGE_TYPE].len ?
717  "DHCPOFFER" : "BOOTREPLY";
719 
720  time(&cur_time);
721 
722  /* If we're not receptive to an offer right now, or if the offer
723  has an unrecognizable transaction id, then just drop it. */
724  if (ip->client->state != S_SELECTING ||
725  packet->interface->client->xid != packet->raw->xid ||
726  (packet->interface->hw_address.hlen != packet->raw->hlen) ||
727  (memcmp(packet->interface->hw_address.haddr,
728  packet->raw->chaddr, packet->raw->hlen)))
729  return;
730 
731  note("%s from %s", name, piaddr(packet->client_addr));
732 
733 
734  /* If this lease doesn't supply the minimum required parameters,
735  blow it off. */
736  for (i = 0; ip->client->config->required_options[i]; i++) {
737  if (!packet->options[ip->client->config->
738  required_options[i]].len) {
739  note("%s isn't satisfactory.", name);
740  return;
741  }
742  }
743 
744  /* If we've already seen this lease, don't record it again. */
745  for (lease = ip->client->offered_leases;
746  lease; lease = lease->next) {
747  if (lease->address.len == sizeof(packet->raw->yiaddr) &&
748  !memcmp(lease->address.iabuf,
749  &packet->raw->yiaddr, lease->address.len)) {
750  debug("%s already seen.", name);
751  return;
752  }
753  }
754 
755  lease = packet_to_lease(packet);
756  if (!lease) {
757  note("packet_to_lease failed.");
758  return;
759  }
760 
761  /* If this lease was acquired through a BOOTREPLY, record that
762  fact. */
764  lease->is_bootp = 1;
765 
766  /* Record the medium under which this lease was offered. */
767  lease->medium = ip->client->medium;
768 
769  /* Send out an ARP Request for the offered IP address. */
770  if( !check_arp( ip, lease ) ) {
771  note("Arp check failed\n");
772  return;
773  }
774 
775  /* Figure out when we're supposed to stop selecting. */
776  stop_selecting =
777  ip->client->first_sending + ip->client->config->select_interval;
778 
779  /* If this is the lease we asked for, put it at the head of the
780  list, and don't mess with the arp request timeout. */
781  if (lease->address.len == ip->client->requested_address.len &&
782  !memcmp(lease->address.iabuf,
783  ip->client->requested_address.iabuf,
784  ip->client->requested_address.len)) {
785  lease->next = ip->client->offered_leases;
786  ip->client->offered_leases = lease;
787  } else {
788  /* If we already have an offer, and arping for this
789  offer would take us past the selection timeout,
790  then don't extend the timeout - just hope for the
791  best. */
792  if (ip->client->offered_leases &&
793  (cur_time + arp_timeout_needed) > stop_selecting)
794  arp_timeout_needed = 0;
795 
796  /* Put the lease at the end of the list. */
797  lease->next = NULL;
798  if (!ip->client->offered_leases)
799  ip->client->offered_leases = lease;
800  else {
801  for (lp = ip->client->offered_leases; lp->next;
802  lp = lp->next)
803  ; /* nothing */
804  lp->next = lease;
805  }
806  }
807 
808  /* If we're supposed to stop selecting before we've had time
809  to wait for the ARPREPLY, add some delay to wait for
810  the ARPREPLY. */
811  if (stop_selecting - cur_time < arp_timeout_needed)
812  stop_selecting = cur_time + arp_timeout_needed;
813 
814  /* If the selecting interval has expired, go immediately to
815  state_selecting(). Otherwise, time out into
816  state_selecting at the select interval. */
817  if (stop_selecting <= 0)
819  else {
820  add_timeout(stop_selecting, state_selecting, ip);
822  }
823 }
824 
825 /* Allocate a client_lease structure and initialize it from the parameters
826  in the specified packet. */
827 
828 struct client_lease *
830 {
831  struct client_lease *lease;
832  int i;
833 
834  lease = malloc(sizeof(struct client_lease));
835 
836  if (!lease) {
837  warning("dhcpoffer: no memory to record lease.");
838  return (NULL);
839  }
840 
841  memset(lease, 0, sizeof(*lease));
842 
843  /* Copy the lease options. */
844  for (i = 0; i < 256; i++) {
845  if (packet->options[i].len) {
846  lease->options[i].data =
847  malloc(packet->options[i].len + 1);
848  if (!lease->options[i].data) {
849  warning("dhcpoffer: no memory for option %d", i);
850  free_client_lease(lease);
851  return (NULL);
852  } else {
853  memcpy(lease->options[i].data,
854  packet->options[i].data,
855  packet->options[i].len);
856  lease->options[i].len =
857  packet->options[i].len;
858  lease->options[i].data[lease->options[i].len] =
859  0;
860  }
861  if (!check_option(lease,i)) {
862  /* ignore a bogus lease offer */
863  warning("Invalid lease option - ignoring offer");
864  free_client_lease(lease);
865  return (NULL);
866  }
867  }
868  }
869 
870  lease->address.len = sizeof(packet->raw->yiaddr);
871  memcpy(lease->address.iabuf, &packet->raw->yiaddr, lease->address.len);
872 #ifdef __REACTOS__
873  lease->serveraddress.len = sizeof(packet->raw->siaddr);
874  memcpy(lease->serveraddress.iabuf, &packet->raw->siaddr, lease->address.len);
875 #endif
876 
877  /* If the server name was filled out, copy it. */
879  !(packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2)) &&
880  packet->raw->sname[0]) {
881  lease->server_name = malloc(DHCP_SNAME_LEN + 1);
882  if (!lease->server_name) {
883  warning("dhcpoffer: no memory for server name.");
884  free_client_lease(lease);
885  return (NULL);
886  }
887  memcpy(lease->server_name, packet->raw->sname, DHCP_SNAME_LEN);
888  lease->server_name[DHCP_SNAME_LEN]='\0';
889  if (!res_hnok(lease->server_name) ) {
890  warning("Bogus server name %s", lease->server_name );
891  free_client_lease(lease);
892  return (NULL);
893  }
894 
895  }
896 
897  /* Ditto for the filename. */
899  !(packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 1)) &&
900  packet->raw->file[0]) {
901  /* Don't count on the NUL terminator. */
902  lease->filename = malloc(DHCP_FILE_LEN + 1);
903  if (!lease->filename) {
904  warning("dhcpoffer: no memory for filename.");
905  free_client_lease(lease);
906  return (NULL);
907  }
908  memcpy(lease->filename, packet->raw->file, DHCP_FILE_LEN);
909  lease->filename[DHCP_FILE_LEN]='\0';
910  }
911  return lease;
912 }
913 
914 void
916 {
917  struct interface_info *ip = packet->interface;
918 
919  /* If we're not receptive to an offer right now, or if the offer
920  has an unrecognizable transaction id, then just drop it. */
921  if (packet->interface->client->xid != packet->raw->xid ||
922  (packet->interface->hw_address.hlen != packet->raw->hlen) ||
923  (memcmp(packet->interface->hw_address.haddr,
924  packet->raw->chaddr, packet->raw->hlen)))
925  return;
926 
927  if (ip->client->state != S_REBOOTING &&
928  ip->client->state != S_REQUESTING &&
929  ip->client->state != S_RENEWING &&
930  ip->client->state != S_REBINDING)
931  return;
932 
933  note("DHCPNAK from %s", piaddr(packet->client_addr));
934 
935  if (!ip->client->active) {
936  note("DHCPNAK with no active lease.\n");
937  return;
938  }
939 
940  free_client_lease(ip->client->active);
941  ip->client->active = NULL;
942 
943  /* Stop sending DHCPREQUEST packets... */
945 
946  ip->client->state = S_INIT;
947  state_init(ip);
948 }
949 
950 /* Send out a DHCPDISCOVER packet, and set a timeout to send out another
951  one after the right interval has expired. If we don't get an offer by
952  the time we reach the panic interval, call the panic function. */
953 
954 void
955 send_discover(void *ipp)
956 {
957  struct interface_info *ip = ipp;
958  int interval, increase = 1;
960 
961  DH_DbgPrint(MID_TRACE,("Doing discover on interface %p\n",ip));
962 
963  time(&cur_time);
964 
965  /* Figure out how long it's been since we started transmitting. */
966  interval = cur_time - ip->client->first_sending;
967 
968  /* If we're past the panic timeout, call the script and tell it
969  we haven't found anything for this interface yet. */
970  if (interval > ip->client->config->timeout) {
971  state_panic(ip);
972  ip->client->first_sending = cur_time;
973  }
974 
975  /* If we're selecting media, try the whole list before doing
976  the exponential backoff, but if we've already received an
977  offer, stop looping, because we obviously have it right. */
978  if (!ip->client->offered_leases &&
979  ip->client->config->media) {
980  int fail = 0;
981 
982  if (ip->client->medium) {
983  ip->client->medium = ip->client->medium->next;
984  increase = 0;
985  }
986  if (!ip->client->medium) {
987  if (fail)
988  error("No valid media types for %s!", ip->name);
989  ip->client->medium = ip->client->config->media;
990  increase = 1;
991  }
992 
993  note("Trying medium \"%s\" %d", ip->client->medium->string,
994  increase);
995  /* XXX Support other media types eventually */
996  }
997 
998  /*
999  * If we're supposed to increase the interval, do so. If it's
1000  * currently zero (i.e., we haven't sent any packets yet), set
1001  * it to one; otherwise, add to it a random number between zero
1002  * and two times itself. On average, this means that it will
1003  * double with every transmission.
1004  */
1005  if (increase) {
1006  if (!ip->client->interval)
1007  ip->client->interval =
1008  ip->client->config->initial_interval;
1009  else {
1010  ip->client->interval += (rand() >> 2) %
1011  (2 * ip->client->interval);
1012  }
1013 
1014  /* Don't backoff past cutoff. */
1015  if (ip->client->interval >
1016  ip->client->config->backoff_cutoff)
1017  ip->client->interval =
1018  ((ip->client->config->backoff_cutoff / 2)
1019  + ((rand() >> 2) %
1020  ip->client->config->backoff_cutoff));
1021  } else if (!ip->client->interval)
1022  ip->client->interval =
1023  ip->client->config->initial_interval;
1024 
1025  /* If the backoff would take us to the panic timeout, just use that
1026  as the interval. */
1027  if (cur_time + ip->client->interval >
1028  ip->client->first_sending + ip->client->config->timeout)
1029  ip->client->interval =
1030  (ip->client->first_sending +
1031  ip->client->config->timeout) - cur_time + 1;
1032 
1033  /* Record the number of seconds since we started sending. */
1034  if (interval < 65536)
1035  ip->client->packet.secs = htons(interval);
1036  else
1037  ip->client->packet.secs = htons(65535);
1038  ip->client->secs = ip->client->packet.secs;
1039 
1040  note("DHCPDISCOVER on %s to %s port %d interval %ld",
1041  ip->name, inet_ntoa(sockaddr_broadcast.sin_addr),
1042  ntohs(sockaddr_broadcast.sin_port), (long int)ip->client->interval);
1043 
1044  /* Send out a packet. */
1045  (void)send_packet(ip, &ip->client->packet, ip->client->packet_length,
1047 
1048  DH_DbgPrint(MID_TRACE,("discover timeout: now %x -> then %x\n",
1049  cur_time, cur_time + ip->client->interval));
1050 
1051  add_timeout(cur_time + ip->client->interval, send_discover, ip);
1052 }
1053 
1054 /*
1055  * state_panic gets called if we haven't received any offers in a preset
1056  * amount of time. When this happens, we try to use existing leases
1057  * that haven't yet expired, and failing that, we call the client script
1058  * and hope it can do something.
1059  */
1060 void
1061 state_panic(void *ipp)
1062 {
1063  struct interface_info *ip = ipp;
1064  uint16_t address_low;
1065  int i;
1066  IPAddr IpAddress;
1067  ULONG Buffer[20];
1068  ULONG BufferSize;
1069  DWORD ret;
1070  PDHCP_ADAPTER Adapter = AdapterFindInfo(ip);
1071 
1072  note("No DHCPOFFERS received.");
1073 
1074  if (!Adapter->NteContext)
1075  {
1076  /* Generate an automatic private address */
1077  DbgPrint("DHCPCSVC: Failed to receive a response from a DHCP server. An automatic private address will be assigned.\n");
1078 
1079  /* FIXME: The address generation code sucks */
1080  srand(0);
1081 
1082  for (;;)
1083  {
1084  address_low = rand();
1085  for (i = 0; i < ip->hw_address.hlen; i++)
1086  address_low += ip->hw_address.haddr[i];
1087 
1088  IpAddress = htonl(0xA9FE0000 | address_low); // 169.254.X.X
1089 
1090  /* Send an ARP request to check if the IP address is already in use */
1091  BufferSize = sizeof(Buffer);
1092  ret = SendARP(IpAddress,
1093  IpAddress,
1094  Buffer,
1095  &BufferSize);
1096  DH_DbgPrint(MID_TRACE,("DHCPCSVC: SendARP returned %lu\n", ret));
1097  if (ret != 0)
1098  {
1099  /* The IP address is not in use */
1100  DH_DbgPrint(MID_TRACE,("DHCPCSVC: Using automatic private address\n"));
1101  AddIPAddress(IpAddress,
1102  htonl(0xFFFF0000), // 255.255.0.0
1103  Adapter->IfMib.dwIndex,
1104  &Adapter->NteContext,
1105  &Adapter->NteInstance);
1106  return;
1107  }
1108  }
1109  }
1110 }
1111 
1112 void
1113 send_request(void *ipp)
1114 {
1115  struct interface_info *ip = ipp;
1116  struct sockaddr_in destination;
1117  struct in_addr from;
1118  int interval;
1119  time_t cur_time;
1120 
1121  time(&cur_time);
1122 
1123  /* Figure out how long it's been since we started transmitting. */
1124  interval = cur_time - ip->client->first_sending;
1125 
1126  /* If we're in the INIT-REBOOT or REQUESTING state and we're
1127  past the reboot timeout, go to INIT and see if we can
1128  DISCOVER an address... */
1129  /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
1130  means either that we're on a network with no DHCP server,
1131  or that our server is down. In the latter case, assuming
1132  that there is a backup DHCP server, DHCPDISCOVER will get
1133  us a new address, but we could also have successfully
1134  reused our old address. In the former case, we're hosed
1135  anyway. This is not a win-prone situation. */
1136  if ((ip->client->state == S_REBOOTING ||
1137  ip->client->state == S_REQUESTING) &&
1138  interval > ip->client->config->reboot_timeout) {
1139  ip->client->state = S_INIT;
1141  state_init(ip);
1142  return;
1143  }
1144 
1145  /* If we're in the reboot state, make sure the media is set up
1146  correctly. */
1147  if (ip->client->state == S_REBOOTING &&
1148  !ip->client->medium &&
1149  ip->client->active->medium ) {
1150  /* If the medium we chose won't fly, go to INIT state. */
1151  /* XXX Nothing for now */
1152 
1153  /* Record the medium. */
1154  ip->client->medium = ip->client->active->medium;
1155  }
1156 
1157  /* If the lease has expired, relinquish the address and go back
1158  to the INIT state. */
1159  if (ip->client->state != S_REQUESTING &&
1160  cur_time > ip->client->active->expiry) {
1161  PDHCP_ADAPTER Adapter = AdapterFindInfo( ip );
1162  /* Run the client script with the new parameters. */
1163  /* No script actions necessary in the expiry case */
1164  /* Now do a preinit on the interface so that we can
1165  discover a new address. */
1166 
1167  if( Adapter )
1168  {
1169  DeleteIPAddress( Adapter->NteContext );
1170  Adapter->NteContext = 0;
1171  }
1172 
1173  ip->client->state = S_INIT;
1174  state_init(ip);
1175  return;
1176  }
1177 
1178  /* Do the exponential backoff... */
1179  if (!ip->client->interval)
1180  ip->client->interval = ip->client->config->initial_interval;
1181  else
1182  ip->client->interval += ((rand() >> 2) %
1183  (2 * ip->client->interval));
1184 
1185  /* Don't backoff past cutoff. */
1186  if (ip->client->interval >
1187  ip->client->config->backoff_cutoff)
1188  ip->client->interval =
1189  ((ip->client->config->backoff_cutoff / 2) +
1190  ((rand() >> 2) % ip->client->interval));
1191 
1192  /* If the backoff would take us to the expiry time, just set the
1193  timeout to the expiry time. */
1194  if (ip->client->state != S_REQUESTING &&
1195  cur_time + ip->client->interval >
1196  ip->client->active->expiry)
1197  ip->client->interval =
1198  ip->client->active->expiry - cur_time + 1;
1199 
1200  /* If the lease T2 time has elapsed, or if we're not yet bound,
1201  broadcast the DHCPREQUEST rather than unicasting. */
1202  memset(&destination, 0, sizeof(destination));
1203  if (ip->client->state == S_REQUESTING ||
1204  ip->client->state == S_REBOOTING ||
1205  cur_time > ip->client->active->rebind)
1206  destination.sin_addr.s_addr = INADDR_BROADCAST;
1207  else
1208  memcpy(&destination.sin_addr.s_addr,
1209  ip->client->destination.iabuf,
1210  sizeof(destination.sin_addr.s_addr));
1211  destination.sin_port = htons(REMOTE_PORT);
1212  destination.sin_family = AF_INET;
1213 // destination.sin_len = sizeof(destination);
1214 
1215  if (ip->client->state != S_REQUESTING)
1216  memcpy(&from, ip->client->active->address.iabuf,
1217  sizeof(from));
1218  else
1219  from.s_addr = INADDR_ANY;
1220 
1221  /* Record the number of seconds since we started sending. */
1222  if (ip->client->state == S_REQUESTING)
1223  ip->client->packet.secs = ip->client->secs;
1224  else {
1225  if (interval < 65536)
1226  ip->client->packet.secs = htons(interval);
1227  else
1228  ip->client->packet.secs = htons(65535);
1229  }
1230 
1231  note("DHCPREQUEST on %s to %s port %d", ip->name,
1232  inet_ntoa(destination.sin_addr), ntohs(destination.sin_port));
1233 
1234  /* Send out a packet. */
1235  (void) send_packet(ip, &ip->client->packet, ip->client->packet_length,
1236  from, &destination, NULL);
1237 
1238  add_timeout(cur_time + ip->client->interval, send_request, ip);
1239 }
1240 
1241 void
1242 send_decline(void *ipp)
1243 {
1244  struct interface_info *ip = ipp;
1245 
1246  note("DHCPDECLINE on %s to %s port %d", ip->name,
1247  inet_ntoa(sockaddr_broadcast.sin_addr),
1248  ntohs(sockaddr_broadcast.sin_port));
1249 
1250  /* Send out a packet. */
1251  (void) send_packet(ip, &ip->client->packet, ip->client->packet_length,
1253 }
1254 
1255 void
1257 {
1258  unsigned char discover = DHCPDISCOVER;
1259  struct tree_cache *options[256];
1260  struct tree_cache option_elements[256];
1261  int i;
1262  ULONG foo = (ULONG) GetTickCount();
1263 
1264  memset(option_elements, 0, sizeof(option_elements));
1265  memset(options, 0, sizeof(options));
1266  memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1267 
1268  /* Set DHCP_MESSAGE_TYPE to DHCPDISCOVER */
1270  options[i] = &option_elements[i];
1271  options[i]->value = &discover;
1272  options[i]->len = sizeof(discover);
1273  options[i]->buf_size = sizeof(discover);
1274  options[i]->timeout = 0xFFFFFFFF;
1275 
1276  /* Request the options we want */
1278  options[i] = &option_elements[i];
1279  options[i]->value = ip->client->config->requested_options;
1280  options[i]->len = ip->client->config->requested_option_count;
1281  options[i]->buf_size =
1282  ip->client->config->requested_option_count;
1283  options[i]->timeout = 0xFFFFFFFF;
1284 
1285  /* If we had an address, try to get it again. */
1286  if (lease) {
1287  ip->client->requested_address = lease->address;
1289  options[i] = &option_elements[i];
1290  options[i]->value = lease->address.iabuf;
1291  options[i]->len = lease->address.len;
1292  options[i]->buf_size = lease->address.len;
1293  options[i]->timeout = 0xFFFFFFFF;
1294  } else
1295  ip->client->requested_address.len = 0;
1296 
1297  /* Send any options requested in the config file. */
1298  for (i = 0; i < 256; i++)
1299  if (!options[i] &&
1300  ip->client->config->send_options[i].data) {
1301  options[i] = &option_elements[i];
1302  options[i]->value =
1303  ip->client->config->send_options[i].data;
1304  options[i]->len =
1305  ip->client->config->send_options[i].len;
1306  options[i]->buf_size =
1307  ip->client->config->send_options[i].len;
1308  options[i]->timeout = 0xFFFFFFFF;
1309  }
1310 
1311  /* Set up the option buffer... */
1312  ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1313  options);
1314  if (ip->client->packet_length < BOOTP_MIN_LEN)
1315  ip->client->packet_length = BOOTP_MIN_LEN;
1316 
1317  ip->client->packet.op = BOOTREQUEST;
1318  ip->client->packet.htype = ip->hw_address.htype;
1319  ip->client->packet.hlen = ip->hw_address.hlen;
1320  ip->client->packet.hops = 0;
1321  ip->client->packet.xid = RtlRandom(&foo);
1322  ip->client->packet.secs = 0; /* filled in by send_discover. */
1323  ip->client->packet.flags = 0;
1324 
1325  memset(&(ip->client->packet.ciaddr),
1326  0, sizeof(ip->client->packet.ciaddr));
1327  memset(&(ip->client->packet.yiaddr),
1328  0, sizeof(ip->client->packet.yiaddr));
1329  memset(&(ip->client->packet.siaddr),
1330  0, sizeof(ip->client->packet.siaddr));
1331  memset(&(ip->client->packet.giaddr),
1332  0, sizeof(ip->client->packet.giaddr));
1333  memcpy(ip->client->packet.chaddr,
1334  ip->hw_address.haddr, ip->hw_address.hlen);
1335 }
1336 
1337 
1338 void
1339 make_request(struct interface_info *ip, struct client_lease * lease)
1340 {
1341  unsigned char request = DHCPREQUEST;
1342  struct tree_cache *options[256];
1343  struct tree_cache option_elements[256];
1344  int i;
1345 
1346  memset(options, 0, sizeof(options));
1347  memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1348 
1349  /* Set DHCP_MESSAGE_TYPE to DHCPREQUEST */
1351  options[i] = &option_elements[i];
1352  options[i]->value = &request;
1353  options[i]->len = sizeof(request);
1354  options[i]->buf_size = sizeof(request);
1355  options[i]->timeout = 0xFFFFFFFF;
1356 
1357  /* Request the options we want */
1359  options[i] = &option_elements[i];
1360  options[i]->value = ip->client->config->requested_options;
1361  options[i]->len = ip->client->config->requested_option_count;
1362  options[i]->buf_size =
1363  ip->client->config->requested_option_count;
1364  options[i]->timeout = 0xFFFFFFFF;
1365 
1366  /* If we are requesting an address that hasn't yet been assigned
1367  to us, use the DHCP Requested Address option. */
1368  if (ip->client->state == S_REQUESTING) {
1369  /* Send back the server identifier... */
1371  options[i] = &option_elements[i];
1372  options[i]->value = lease->options[i].data;
1373  options[i]->len = lease->options[i].len;
1374  options[i]->buf_size = lease->options[i].len;
1375  options[i]->timeout = 0xFFFFFFFF;
1376  }
1377  if (ip->client->state == S_REQUESTING ||
1378  ip->client->state == S_REBOOTING) {
1379  ip->client->requested_address = lease->address;
1381  options[i] = &option_elements[i];
1382  options[i]->value = lease->address.iabuf;
1383  options[i]->len = lease->address.len;
1384  options[i]->buf_size = lease->address.len;
1385  options[i]->timeout = 0xFFFFFFFF;
1386  } else
1387  ip->client->requested_address.len = 0;
1388 
1389  /* Send any options requested in the config file. */
1390  for (i = 0; i < 256; i++)
1391  if (!options[i] &&
1392  ip->client->config->send_options[i].data) {
1393  options[i] = &option_elements[i];
1394  options[i]->value =
1395  ip->client->config->send_options[i].data;
1396  options[i]->len =
1397  ip->client->config->send_options[i].len;
1398  options[i]->buf_size =
1399  ip->client->config->send_options[i].len;
1400  options[i]->timeout = 0xFFFFFFFF;
1401  }
1402 
1403  /* Set up the option buffer... */
1404  ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1405  options);
1406  if (ip->client->packet_length < BOOTP_MIN_LEN)
1407  ip->client->packet_length = BOOTP_MIN_LEN;
1408 
1409  ip->client->packet.op = BOOTREQUEST;
1410  ip->client->packet.htype = ip->hw_address.htype;
1411  ip->client->packet.hlen = ip->hw_address.hlen;
1412  ip->client->packet.hops = 0;
1413  ip->client->packet.xid = ip->client->xid;
1414  ip->client->packet.secs = 0; /* Filled in by send_request. */
1415 
1416  /* If we own the address we're requesting, put it in ciaddr;
1417  otherwise set ciaddr to zero. */
1418  if (ip->client->state == S_BOUND ||
1419  ip->client->state == S_RENEWING ||
1420  ip->client->state == S_REBINDING) {
1421  memcpy(&ip->client->packet.ciaddr,
1422  lease->address.iabuf, lease->address.len);
1423  ip->client->packet.flags = 0;
1424  } else {
1425  memset(&ip->client->packet.ciaddr, 0,
1426  sizeof(ip->client->packet.ciaddr));
1427  ip->client->packet.flags = 0;
1428  }
1429 
1430  memset(&ip->client->packet.yiaddr, 0,
1431  sizeof(ip->client->packet.yiaddr));
1432  memset(&ip->client->packet.siaddr, 0,
1433  sizeof(ip->client->packet.siaddr));
1434  memset(&ip->client->packet.giaddr, 0,
1435  sizeof(ip->client->packet.giaddr));
1436  memcpy(ip->client->packet.chaddr,
1437  ip->hw_address.haddr, ip->hw_address.hlen);
1438 }
1439 
1440 void
1442 {
1443  struct tree_cache *options[256], message_type_tree;
1444  struct tree_cache requested_address_tree;
1445  struct tree_cache server_id_tree, client_id_tree;
1446  unsigned char decline = DHCPDECLINE;
1447  int i;
1448 
1449  memset(options, 0, sizeof(options));
1450  memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1451 
1452  /* Set DHCP_MESSAGE_TYPE to DHCPDECLINE */
1454  options[i] = &message_type_tree;
1455  options[i]->value = &decline;
1456  options[i]->len = sizeof(decline);
1457  options[i]->buf_size = sizeof(decline);
1458  options[i]->timeout = 0xFFFFFFFF;
1459 
1460  /* Send back the server identifier... */
1462  options[i] = &server_id_tree;
1463  options[i]->value = lease->options[i].data;
1464  options[i]->len = lease->options[i].len;
1465  options[i]->buf_size = lease->options[i].len;
1466  options[i]->timeout = 0xFFFFFFFF;
1467 
1468  /* Send back the address we're declining. */
1470  options[i] = &requested_address_tree;
1471  options[i]->value = lease->address.iabuf;
1472  options[i]->len = lease->address.len;
1473  options[i]->buf_size = lease->address.len;
1474  options[i]->timeout = 0xFFFFFFFF;
1475 
1476  /* Send the uid if the user supplied one. */
1478  if (ip->client->config->send_options[i].len) {
1479  options[i] = &client_id_tree;
1480  options[i]->value = ip->client->config->send_options[i].data;
1481  options[i]->len = ip->client->config->send_options[i].len;
1482  options[i]->buf_size = ip->client->config->send_options[i].len;
1483  options[i]->timeout = 0xFFFFFFFF;
1484  }
1485 
1486 
1487  /* Set up the option buffer... */
1488  ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1489  options);
1490  if (ip->client->packet_length < BOOTP_MIN_LEN)
1491  ip->client->packet_length = BOOTP_MIN_LEN;
1492 
1493  ip->client->packet.op = BOOTREQUEST;
1494  ip->client->packet.htype = ip->hw_address.htype;
1495  ip->client->packet.hlen = ip->hw_address.hlen;
1496  ip->client->packet.hops = 0;
1497  ip->client->packet.xid = ip->client->xid;
1498  ip->client->packet.secs = 0; /* Filled in by send_request. */
1499  ip->client->packet.flags = 0;
1500 
1501  /* ciaddr must always be zero. */
1502  memset(&ip->client->packet.ciaddr, 0,
1503  sizeof(ip->client->packet.ciaddr));
1504  memset(&ip->client->packet.yiaddr, 0,
1505  sizeof(ip->client->packet.yiaddr));
1506  memset(&ip->client->packet.siaddr, 0,
1507  sizeof(ip->client->packet.siaddr));
1508  memset(&ip->client->packet.giaddr, 0,
1509  sizeof(ip->client->packet.giaddr));
1510  memcpy(ip->client->packet.chaddr,
1511  ip->hw_address.haddr, ip->hw_address.hlen);
1512 }
1513 
1514 void
1516 {
1517  int i;
1518 
1519  if (lease->server_name)
1520  free(lease->server_name);
1521  if (lease->filename)
1522  free(lease->filename);
1523  for (i = 0; i < 256; i++) {
1524  if (lease->options[i].len)
1525  free(lease->options[i].data);
1526  }
1527  free(lease);
1528 }
1529 
1531 
1532 void
1534 {
1535  struct client_lease *lp;
1536 
1537  if (!leaseFile) {
1539  if (!leaseFile)
1540  error("can't create %s", path_dhclient_db);
1541  } else {
1542  fflush(leaseFile);
1543  rewind(leaseFile);
1544  }
1545 
1546  for (lp = ifi->client->leases; lp; lp = lp->next)
1547  write_client_lease(ifi, lp, 1);
1548  if (ifi->client->active)
1549  write_client_lease(ifi, ifi->client->active, 1);
1550 
1551  fflush(leaseFile);
1552 }
1553 
1554 void
1556  int rewrite)
1557 {
1558  static int leases_written;
1559  struct tm *t;
1560  int i;
1561 
1562  if (!rewrite) {
1563  if (leases_written++ > 20) {
1565  leases_written = 0;
1566  }
1567  }
1568 
1569  /* If the lease came from the config file, we don't need to stash
1570  a copy in the lease database. */
1571  if (lease->is_static)
1572  return;
1573 
1574  if (!leaseFile) { /* XXX */
1576  if (!leaseFile) {
1577  error("can't create %s", path_dhclient_db);
1578  return;
1579  }
1580  }
1581 
1582  fprintf(leaseFile, "lease {\n");
1583  if (lease->is_bootp)
1584  fprintf(leaseFile, " bootp;\n");
1585  fprintf(leaseFile, " interface \"%s\";\n", ip->name);
1586  fprintf(leaseFile, " fixed-address %s;\n", piaddr(lease->address));
1587  if (lease->filename)
1588  fprintf(leaseFile, " filename \"%s\";\n", lease->filename);
1589  if (lease->server_name)
1590  fprintf(leaseFile, " server-name \"%s\";\n",
1591  lease->server_name);
1592  if (lease->medium)
1593  fprintf(leaseFile, " medium \"%s\";\n", lease->medium->string);
1594  for (i = 0; i < 256; i++)
1595  if (lease->options[i].len)
1596  fprintf(leaseFile, " option %s %s;\n",
1597  dhcp_options[i].name,
1598  pretty_print_option(i, lease->options[i].data,
1599  lease->options[i].len, 1, 1));
1600 
1601  t = gmtime(&lease->renewal);
1602  if (t)
1603  fprintf(leaseFile, " renew %d %d/%d/%d %02d:%02d:%02d;\n",
1604  t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
1605  t->tm_hour, t->tm_min, t->tm_sec);
1606  t = gmtime(&lease->rebind);
1607  if (t)
1608  fprintf(leaseFile, " rebind %d %d/%d/%d %02d:%02d:%02d;\n",
1609  t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
1610  t->tm_hour, t->tm_min, t->tm_sec);
1611  t = gmtime(&lease->expiry);
1612  if (t)
1613  fprintf(leaseFile, " expire %d %d/%d/%d %02d:%02d:%02d;\n",
1614  t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
1615  t->tm_hour, t->tm_min, t->tm_sec);
1616  fprintf(leaseFile, "}\n");
1617  fflush(leaseFile);
1618 }
1619 
1620 void
1621 priv_script_init(struct interface_info *ip, char *reason, char *medium)
1622 {
1623  if (ip) {
1624  // XXX Do we need to do anything?
1625  }
1626 }
1627 
1628 void
1629 priv_script_write_params(struct interface_info *ip, char *prefix, struct client_lease *lease)
1630 {
1631  u_int8_t dbuf[1500];
1632  int i, len = 0;
1633 
1634 #if 0
1635  script_set_env(ip->client, prefix, "ip_address",
1636  piaddr(lease->address));
1637 #endif
1638 
1639  if (lease->options[DHO_SUBNET_MASK].len &&
1640  (lease->options[DHO_SUBNET_MASK].len <
1641  sizeof(lease->address.iabuf))) {
1642  struct iaddr netmask, subnet, broadcast;
1643 
1644  memcpy(netmask.iabuf, lease->options[DHO_SUBNET_MASK].data,
1645  lease->options[DHO_SUBNET_MASK].len);
1646  netmask.len = lease->options[DHO_SUBNET_MASK].len;
1647 
1648  subnet = subnet_number(lease->address, netmask);
1649  if (subnet.len) {
1650 #if 0
1651  script_set_env(ip->client, prefix, "network_number",
1652  piaddr(subnet));
1653 #endif
1654  if (!lease->options[DHO_BROADCAST_ADDRESS].len) {
1655  broadcast = broadcast_addr(subnet, netmask);
1656  if (broadcast.len)
1657 #if 0
1658  script_set_env(ip->client, prefix,
1659  "broadcast_address",
1660  piaddr(broadcast));
1661 #else
1662  ;
1663 #endif
1664  }
1665  }
1666  }
1667 
1668 #if 0
1669  if (lease->filename)
1670  script_set_env(ip->client, prefix, "filename", lease->filename);
1671  if (lease->server_name)
1672  script_set_env(ip->client, prefix, "server_name",
1673  lease->server_name);
1674 #endif
1675 
1676  for (i = 0; i < 256; i++) {
1677  u_int8_t *dp = NULL;
1678 
1679  if (ip->client->config->defaults[i].len) {
1680  if (lease->options[i].len) {
1681  switch (
1682  ip->client->config->default_actions[i]) {
1683  case ACTION_DEFAULT:
1684  dp = lease->options[i].data;
1685  len = lease->options[i].len;
1686  break;
1687  case ACTION_SUPERSEDE:
1688 supersede:
1689  dp = ip->client->
1690  config->defaults[i].data;
1691  len = ip->client->
1692  config->defaults[i].len;
1693  break;
1694  case ACTION_PREPEND:
1695  len = ip->client->
1696  config->defaults[i].len +
1697  lease->options[i].len;
1698  if (len >= sizeof(dbuf)) {
1699  warning("no space to %s %s",
1700  "prepend option",
1701  dhcp_options[i].name);
1702  goto supersede;
1703  }
1704  dp = dbuf;
1705  memcpy(dp,
1706  ip->client->
1707  config->defaults[i].data,
1708  ip->client->
1709  config->defaults[i].len);
1710  memcpy(dp + ip->client->
1711  config->defaults[i].len,
1712  lease->options[i].data,
1713  lease->options[i].len);
1714  dp[len] = '\0';
1715  break;
1716  case ACTION_APPEND:
1717  len = ip->client->
1718  config->defaults[i].len +
1719  lease->options[i].len + 1;
1720  if (len > sizeof(dbuf)) {
1721  warning("no space to %s %s",
1722  "append option",
1723  dhcp_options[i].name);
1724  goto supersede;
1725  }
1726  dp = dbuf;
1727  memcpy(dp,
1728  lease->options[i].data,
1729  lease->options[i].len);
1730  memcpy(dp + lease->options[i].len,
1731  ip->client->
1732  config->defaults[i].data,
1733  ip->client->
1734  config->defaults[i].len);
1735  dp[len-1] = '\0';
1736  }
1737  } else {
1738  dp = ip->client->
1739  config->defaults[i].data;
1740  len = ip->client->
1741  config->defaults[i].len;
1742  }
1743  } else if (lease->options[i].len) {
1744  len = lease->options[i].len;
1745  dp = lease->options[i].data;
1746  } else {
1747  len = 0;
1748  }
1749 #if 0
1750  if (len) {
1751  char name[256];
1752 
1753  if (dhcp_option_ev_name(name, sizeof(name),
1754  &dhcp_options[i]))
1755  script_set_env(ip->client, prefix, name,
1756  pretty_print_option(i, dp, len, 0, 0));
1757  }
1758 #endif
1759  }
1760 #if 0
1761  snprintf(tbuf, sizeof(tbuf), "%d", (int)lease->expiry);
1762  script_set_env(ip->client, prefix, "expiry", tbuf);
1763 #endif
1764 }
1765 
1766 int
1767 dhcp_option_ev_name(char *buf, size_t buflen, struct dhcp_option *option)
1768 {
1769  int i;
1770 
1771  for (i = 0; option->name[i]; i++) {
1772  if (i + 1 == buflen)
1773  return 0;
1774  if (option->name[i] == '-')
1775  buf[i] = '_';
1776  else
1777  buf[i] = option->name[i];
1778  }
1779 
1780  buf[i] = 0;
1781  return 1;
1782 }
1783 
1784 #if 0
1785 void
1786 go_daemon(void)
1787 {
1788  static int state = 0;
1789 
1790  if (no_daemon || state)
1791  return;
1792 
1793  state = 1;
1794 
1795  /* Stop logging to stderr... */
1796  log_perror = 0;
1797 
1798  if (daemon(1, 0) == -1)
1799  error("daemon");
1800 
1801  /* we are chrooted, daemon(3) fails to open /dev/null */
1802  if (nullfd != -1) {
1803  dup2(nullfd, STDIN_FILENO);
1804  dup2(nullfd, STDOUT_FILENO);
1805  dup2(nullfd, STDERR_FILENO);
1806  close(nullfd);
1807  nullfd = -1;
1808  }
1809 }
1810 #endif
1811 
1812 int
1814 {
1815  char *opbuf;
1816  char *sbuf;
1817 
1818  /* we use this, since this is what gets passed to dhclient-script */
1819 
1820  opbuf = pretty_print_option(option, l->options[option].data,
1821  l->options[option].len, 0, 0);
1822 
1823  sbuf = option_as_string(option, l->options[option].data,
1824  l->options[option].len);
1825 
1826  switch (option) {
1827  case DHO_SUBNET_MASK:
1828  case DHO_TIME_SERVERS:
1829  case DHO_NAME_SERVERS:
1830  case DHO_ROUTERS:
1832  case DHO_LOG_SERVERS:
1833  case DHO_COOKIE_SERVERS:
1834  case DHO_LPR_SERVERS:
1835  case DHO_IMPRESS_SERVERS:
1837  case DHO_SWAP_SERVER:
1838  case DHO_BROADCAST_ADDRESS:
1839  case DHO_NIS_SERVERS:
1840  case DHO_NTP_SERVERS:
1842  case DHO_NETBIOS_DD_SERVER:
1843  case DHO_FONT_SERVERS:
1845  if (!ipv4addrs(opbuf)) {
1846  warning("Invalid IP address in option(%d): %s", option, opbuf);
1847  return (0);
1848  }
1849  return (1) ;
1850  case DHO_HOST_NAME:
1851  case DHO_DOMAIN_NAME:
1852  case DHO_NIS_DOMAIN:
1853  if (!res_hnok(sbuf))
1854  warning("Bogus Host Name option %d: %s (%s)", option,
1855  sbuf, opbuf);
1856  return (1);
1857  case DHO_PAD:
1858  case DHO_TIME_OFFSET:
1859  case DHO_BOOT_SIZE:
1860  case DHO_MERIT_DUMP:
1861  case DHO_ROOT_PATH:
1862  case DHO_EXTENSIONS_PATH:
1863  case DHO_IP_FORWARDING:
1865  case DHO_POLICY_FILTER:
1867  case DHO_DEFAULT_IP_TTL:
1870  case DHO_INTERFACE_MTU:
1871  case DHO_ALL_SUBNETS_LOCAL:
1873  case DHO_MASK_SUPPLIER:
1874  case DHO_ROUTER_DISCOVERY:
1876  case DHO_STATIC_ROUTES:
1878  case DHO_ARP_CACHE_TIMEOUT:
1880  case DHO_DEFAULT_TCP_TTL:
1884  case DHO_NETBIOS_NODE_TYPE:
1885  case DHO_NETBIOS_SCOPE:
1886  case DHO_X_DISPLAY_MANAGER:
1888  case DHO_DHCP_LEASE_TIME:
1890  case DHO_DHCP_MESSAGE_TYPE:
1892  case DHO_DHCP_MESSAGE:
1894  case DHO_DHCP_RENEWAL_TIME:
1899  case DHO_END:
1900  return (1);
1901  default:
1902  warning("unknown dhcp option value 0x%x", option);
1903  return (unknown_ok);
1904  }
1905 }
1906 
1907 int
1908 res_hnok(const char *dn)
1909 {
1910  int pch = PERIOD, ch = *dn++;
1911 
1912  while (ch != '\0') {
1913  int nch = *dn++;
1914 
1915  if (periodchar(ch)) {
1916  ;
1917  } else if (periodchar(pch)) {
1918  if (!borderchar(ch))
1919  return (0);
1920  } else if (periodchar(nch) || nch == '\0') {
1921  if (!borderchar(ch))
1922  return (0);
1923  } else {
1924  if (!middlechar(ch))
1925  return (0);
1926  }
1927  pch = ch, ch = nch;
1928  }
1929  return (1);
1930 }
1931 
1932 /* Does buf consist only of dotted decimal ipv4 addrs?
1933  * return how many if so,
1934  * otherwise, return 0
1935  */
1936 int
1938 {
1939  char *tmp;
1940  struct in_addr jnk;
1941  int i = 0;
1942 
1943  note("Input: %s", buf);
1944 
1945  do {
1946  tmp = strtok(buf, " ");
1947  note("got %s", tmp);
1948  if( tmp && inet_aton(tmp, &jnk) ) i++;
1949  buf = NULL;
1950  } while( tmp );
1951 
1952  return (i);
1953 }
1954 
1955 
1956 char *
1957 option_as_string(unsigned int code, unsigned char *data, int len)
1958 {
1959  static char optbuf[32768]; /* XXX */
1960  char *op = optbuf;
1961  int opleft = sizeof(optbuf);
1962  unsigned char *dp = data;
1963 
1964  if (code > 255)
1965  error("option_as_string: bad code %d", code);
1966 
1967  for (; dp < data + len; dp++) {
1968  if (!isascii(*dp) || !isprint(*dp)) {
1969  if (dp + 1 != data + len || *dp != 0) {
1970  _snprintf(op, opleft, "\\%03o", *dp);
1971  op += 4;
1972  opleft -= 4;
1973  }
1974  } else if (*dp == '"' || *dp == '\'' || *dp == '$' ||
1975  *dp == '`' || *dp == '\\') {
1976  *op++ = '\\';
1977  *op++ = *dp;
1978  opleft -= 2;
1979  } else {
1980  *op++ = *dp;
1981  opleft--;
1982  }
1983  }
1984  if (opleft < 1)
1985  goto toobig;
1986  *op = 0;
1987  return optbuf;
1988 toobig:
1989  warning("dhcp option too large");
1990  return "<error>";
1991 }
1992 
ULONG NteInstance
Definition: rosdhcp.h:70
NTSYSAPI ULONG NTAPI RtlRandom(_Inout_ PULONG Seed)
#define _PATH_DHCLIENT_CONF
Definition: dhcpd.h:274
#define DHO_NAME_SERVERS
Definition: dhcp.h:101
Definition: dhcpd.h:175
#define DHO_IMPRESS_SERVERS
Definition: dhcp.h:106
time_t rebind
Definition: dhcpd.h:155
_CRTIMP void __cdecl tzset(void)
#define DHO_DHCP_MESSAGE
Definition: dhcp.h:152
#define DHO_IP_FORWARDING
Definition: dhcp.h:115
#define INADDR_BROADCAST
Definition: winsock.h:313
DWORD WINAPI CreateIpForwardEntry(PMIB_IPFORWARDROW pRoute)
#define DHO_END
Definition: dhcp.h:159
MIB_IFROW IfMib
Definition: rosdhcp.h:66
#define MID_TRACE
Definition: debug.h:15
void send_request(void *ipp)
Definition: dhclient.c:1113
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
void state_reboot(void *ipp)
Definition: dhclient.c:172
int addr_eq(struct iaddr a, struct iaddr b)
Definition: util.c:100
u_short sin_port
Definition: winsock.h:511
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define ERROR_SUCCESS
Definition: deptool.c:10
#define DbgPrint
Definition: hal.h:12
DWORD WINAPI DeleteIpForwardEntry(PMIB_IPFORWARDROW pRoute)
void dhcpoffer(struct packet *packet)
Definition: dhclient.c:710
#define error(str)
Definition: mkdosfs.c:1605
int no_daemon
Definition: dhclient.c:93
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
ULONG NteContext
Definition: rosdhcp.h:70
void rewrite_client_leases(struct interface_info *ifi)
Definition: dhclient.c:1533
UCHAR packet[_PAGE_SIZE]
Definition: serial.c:53
void dhcpnak(struct packet *packet)
Definition: dhclient.c:915
#define DHO_DHCP_CLASS_IDENTIFIER
Definition: dhcp.h:156
#define DHCPOFFER
Definition: dhcp.h:163
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
int check_option(struct client_lease *l, int option)
Definition: dhclient.c:1813
#define DHO_NON_LOCAL_SOURCE_ROUTING
Definition: dhcp.h:116
#define DHO_DHCP_LEASE_TIME
Definition: dhcp.h:147
#define REMOTE_PORT
Definition: dhcpd.h:113
#define DHO_ROUTER_SOLICITATION_ADDRESS
Definition: dhcp.h:128
char * pretty_print_option(unsigned int code, unsigned char *data, int len, int emit_commas, int emit_quotes)
Definition: options.c:396
void AdapterInit()
Definition: adapter.c:192
time_t expiry
Definition: dhcpd.h:155
#define DHCPACK
Definition: dhcp.h:166
#define DHO_NETBIOS_NODE_TYPE
Definition: dhcp.h:142
char CHAR
Definition: xmlstorage.h:175
#define free
Definition: debug_ros.c:5
unsigned char iabuf[16]
Definition: dhcpd.h:127
#define DHO_DHCP_MESSAGE_TYPE
Definition: dhcp.h:149
Definition: dhcpd.h:172
FILE * leaseFile
Definition: dhclient.c:1530
LONG NTSTATUS
Definition: precomp.h:26
int routefd
Definition: dhclient.c:95
#define DHO_NIS_DOMAIN
Definition: dhcp.h:136
void write_client_lease(struct interface_info *ip, struct client_lease *lease, int rewrite)
Definition: dhclient.c:1555
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
void __cdecl srand(_In_ unsigned int _Seed)
struct client_state * client
Definition: dhcpd.h:238
time_t cur_time
struct iaddr iaddr_broadcast
Definition: dhclient.c:80
GLdouble GLdouble t
Definition: gl.h:2047
#define DHO_LOG_SERVERS
Definition: dhcp.h:103
void setup_adapter(PDHCP_ADAPTER Adapter, struct client_lease *new_lease)
Definition: dhclient.c:492
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3321
#define snprintf
Definition: wintirpc.h:48
#define INADDR_ANY
Definition: StrAddr.c:4
#define DHO_PAD
Definition: dhcp.h:96
DWORD dwForwardMask
Definition: ipmib.h:72
void dhcpack(struct packet *packet)
Definition: dhclient.c:316
void make_discover(struct interface_info *ip, struct client_lease *lease)
Definition: dhclient.c:1256
void bootp(struct packet *packet)
Definition: dhclient.c:654
void state_bound(void *ipp)
Definition: dhclient.c:628
__u16 time
Definition: mkdosfs.c:366
unsigned short int uint16_t
Definition: acefiex.h:54
int res_hnok(const char *dn)
Definition: dhclient.c:1908
#define DHO_DHCP_PARAMETER_REQUEST_LIST
Definition: dhcp.h:151
#define htonl(x)
Definition: module.h:212
#define pch(ap)
Definition: match.c:418
#define DHCP_FILE_LEN
Definition: dhcp.h:47
#define STDIN_FILENO
Definition: syshdrs.h:88
#define BOOTP_MIN_LEN
Definition: dhcp.h:54
#define DHO_NTP_SERVERS
Definition: dhcp.h:138
void priv_script_write_params(struct interface_info *ip, char *prefix, struct client_lease *lease)
Definition: dhclient.c:1629
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
void send_decline(void *ipp)
Definition: dhclient.c:1242
#define DHO_ROUTERS
Definition: dhcp.h:99
char * filename
Definition: dhcpd.h:162
#define DHO_ROUTER_DISCOVERY
Definition: dhcp.h:127
#define sprintf(buf, format,...)
Definition: sprintf.c:55
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
struct dhcp_option dhcp_options[256]
Definition: tables.c:68
FxRequest * request
int len
Definition: dhcpd.h:126
#define _snprintf
Definition: xmlstorage.h:200
#define L(x)
Definition: ntvdm.h:50
char * path_dhclient_conf
Definition: dhclient.c:73
void stop_client(void)
Definition: dhclient.c:129
unsigned char * LPBYTE
Definition: typedefs.h:53
char * path_dhclient_db
Definition: dhclient.c:74
#define PERIOD
Definition: dhclient.c:58
#define DHO_EXTENSIONS_PATH
Definition: dhcp.h:114
void cancel_timeout(void(*where)(void *), void *what)
Definition: dispatch.c:316
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_ int __cdecl rand(void)
Definition: rand.c:10
struct dhcp_packet * raw
Definition: dhcpd.h:136
#define DHO_DHCP_CLIENT_IDENTIFIER
Definition: dhcp.h:157
void script_set_env(struct client_state *, const char *, const char *, const char *)
unsigned char u_int8_t
Definition: rosdhcp.h:33
#define DHO_TIME_OFFSET
Definition: dhcp.h:98
WCHAR * name
Definition: getopt.h:110
int check_arp(struct interface_info *ip, struct client_lease *lp)
Definition: dhclient.c:137
void bind_lease(struct interface_info *ip)
Definition: dhclient.c:580
#define DHO_ALL_SUBNETS_LOCAL
Definition: dhcp.h:123
VOID ApiInit()
Definition: api.c:18
int privfd
Definition: dhclient.c:77
int note(char *format,...)
Definition: util.c:12
#define DHCPDISCOVER
Definition: dhcp.h:162
Definition: getopt.h:108
#define DHO_ARP_CACHE_TIMEOUT
Definition: dhcp.h:131
#define TIME_MAX
Definition: dhclient.c:90
#define DH_DbgPrint(_t_, _x_)
Definition: debug.h:49
#define DHO_TCP_KEEPALIVE_INTERVAL
Definition: dhcp.h:134
Definition: bufpool.h:45
MIB_IPFORWARDROW RouterMib
Definition: rosdhcp.h:67
#define STDOUT_FILENO
Definition: syshdrs.h:89
#define DHO_INTERFACE_MTU
Definition: dhcp.h:122
ULONG IPAddr
Definition: pfhook.h:35
PDHCP_ADAPTER AdapterFindInfo(struct interface_info *ip)
Definition: adapter.c:526
_Check_return_ _CRTIMP int __cdecl dup2(_In_ int _FileHandleSrc, _In_ int _FileHandleDst)
void set_name_servers(PDHCP_ADAPTER Adapter, struct client_lease *new_lease)
Definition: dhclient.c:398
_CRTIMP void __cdecl rewind(_Inout_ FILE *_File)
#define inet_ntoa(addr)
Definition: inet.h:100
struct interface_info * interface
Definition: dhcpd.h:142
struct iaddr subnet_number(struct iaddr addr, struct iaddr mask)
Definition: util.c:172
IF_INDEX dwForwardIfIndex
Definition: ipmib.h:75
r l[0]
Definition: byte_order.h:167
#define DHO_MAX_DGRAM_REASSEMBLY
Definition: dhcp.h:118
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
#define DHO_FONT_SERVERS
Definition: dhcp.h:144
#define DHO_X_DISPLAY_MANAGER
Definition: dhcp.h:145
Status
Definition: gdiplustypes.h:24
Definition: dhcpd.h:135
#define KEY_WRITE
Definition: nt_native.h:1031
#define DHO_TCP_KEEPALIVE_GARBAGE
Definition: dhcp.h:135
DWORD WINAPI AddIPAddress(IPAddr Address, IPMask Netmask, DWORD IfIndex, PULONG NteContext, PULONG NteInstance)
Definition: iphlpapi_main.c:71
#define middlechar(c)
Definition: dhclient.c:68
DWORD dwForwardNextHop
Definition: ipmib.h:74
#define DHO_TRAILER_ENCAPSULATION
Definition: dhcp.h:130
Definition: dhcpd.h:61
#define DHO_NETBIOS_DD_SERVER
Definition: dhcp.h:141
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DHO_DHCP_RENEWAL_TIME
Definition: dhcp.h:154
struct client_lease * next
Definition: dhcpd.h:154
#define DHO_NETBIOS_SCOPE
Definition: dhcp.h:143
int cons_options(struct packet *inpacket, struct dhcp_packet *outpacket, int mms, struct tree_cache **options)
Definition: options.c:199
void state_panic(void *ipp)
Definition: dhclient.c:1061
Definition: tcpip.h:125
#define DHO_IEEE802_3_ENCAPSULATION
Definition: dhcp.h:132
#define MAX_PATH
Definition: compat.h:34
int packet_type
Definition: dhcpd.h:138
void usage(void)
Definition: sort.c:65
DWORD dwForwardDest
Definition: ipmib.h:71
#define DHO_SUBNET_MASK
Definition: dhcp.h:97
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DHO_DHCP_OPTION_OVERLOAD
Definition: dhcp.h:148
UINT op
Definition: effect.c:236
struct option_data options[256]
Definition: dhcpd.h:144
#define inet_aton(ap, inp)
Definition: adns_win32.h:161
#define BOOTREQUEST
Definition: dhcp.h:78
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
struct option_data options[256]
Definition: dhcpd.h:166
#define DHCPDECLINE
Definition: dhcp.h:165
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1904
void(* bootp_packet_handler)(struct interface_info *, struct dhcp_packet *, int, unsigned int, struct iaddr, struct hardware *)
Definition: dispatch.c:59
#define DHO_RESOURCE_LOCATION_SERVERS
Definition: dhcp.h:107
char * option_as_string(unsigned int code, unsigned char *data, int len)
Definition: dhclient.c:1957
int ret
#define DHO_PATH_MTU_PLATEAU_TABLE
Definition: dhcp.h:121
#define BOOTREPLY
Definition: dhcp.h:79
#define ASSERT_STATE(state_is, state_shouldbe)
Definition: dhclient.c:88
#define DHO_STATIC_ROUTES
Definition: dhcp.h:129
time_t scripttime
Definition: dhclient.c:107
#define ntohs(x)
Definition: module.h:208
#define DHO_PERFORM_MASK_DISCOVERY
Definition: dhcp.h:125
#define DHCPNAK
Definition: dhcp.h:167
Definition: dhcpd.h:125
static int state
Definition: maze.c:121
struct interface_info DhclientInfo
Definition: rosdhcp.h:71
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
#define DHO_NETBIOS_NAME_SERVERS
Definition: dhcp.h:140
Definition: time.h:68
#define close
Definition: acwin.h:98
Definition: inflate.c:139
#define DHO_PATH_MTU_AGING_TIMEOUT
Definition: dhcp.h:120
void send_discover(void *ipp)
Definition: dhclient.c:955
#define DHO_DHCP_REBINDING_TIME
Definition: dhcp.h:155
struct in_addr sin_addr
Definition: winsock.h:512
int log_priority
Definition: dhclient.c:92
void state_selecting(void *ipp)
Definition: dhclient.c:235
#define DHO_TIME_SERVERS
Definition: dhcp.h:100
static unsigned __int64 next
Definition: rand_nt.c:6
struct client_lease * packet_to_lease(struct packet *packet)
Definition: dhclient.c:829
DWORD WINAPI DeleteIPAddress(ULONG NTEContext)
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
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2355
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
__kernel_time_t time_t
Definition: linux.h:252
#define htons(x)
Definition: module.h:213
int init_client(void)
Definition: dhclient.c:111
#define DHO_SWAP_SERVER
Definition: dhcp.h:112
#define DHO_BOOT_SIZE
Definition: dhcp.h:109
#define isascii
Definition: ctype.h:742
#define DHO_BROADCAST_ADDRESS
Definition: dhcp.h:124
struct iaddr broadcast_addr(struct iaddr addr, struct iaddr mask)
Definition: util.c:167
time_t renewal
Definition: dhcpd.h:155
#define DHO_HOST_NAME
Definition: dhcp.h:108
int dhcp_option_ev_name(char *buf, size_t buflen, struct dhcp_option *option)
Definition: dhclient.c:1767
int log_perror
Definition: dhclient.c:76
#define DHCPREQUEST
Definition: dhcp.h:164
#define NULL
Definition: types.h:112
static void increase(int &a_)
char * piaddr(struct iaddr addr)
Definition: util.c:6
struct string_list * medium
Definition: dhcpd.h:163
char * strtok(char *String, const char *Delimiters)
Definition: utclib.c:338
u_int32_t getULong(unsigned char *data)
Definition: util.c:96
#define DHO_DHCP_SERVER_IDENTIFIER
Definition: dhcp.h:150
Definition: tftpd.h:85
int unknown_ok
Definition: dhclient.c:94
void add_timeout(time_t when, void(*where)(void *), void *what)
Definition: dispatch.c:253
struct sockaddr_in sockaddr_broadcast
Definition: dhclient.c:82
struct iaddr client_addr
Definition: dhcpd.h:141
#define DHO_DHCP_USER_CLASS_ID
Definition: dhcp.h:158
int nch
Definition: scanf.h:135
#define isprint(c)
Definition: acclib.h:73
#define borderchar(c)
Definition: dhclient.c:67
#define DHO_VENDOR_ENCAPSULATED_OPTIONS
Definition: dhcp.h:139
#define DHCP_DEFAULT_LEASE_TIME
Definition: rosdhcp.h:30
#define DHO_DHCP_REQUESTED_ADDRESS
Definition: dhcp.h:146
#define DHO_DEFAULT_IP_TTL
Definition: dhcp.h:119
#define DHO_NIS_SERVERS
Definition: dhcp.h:137
struct in_addr inaddr_any
Definition: dhclient.c:81
Definition: name.c:38
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
void dhcp(struct packet *packet)
Definition: dhclient.c:674
void state_init(void *ipp)
Definition: dhclient.c:210
#define DHO_DEFAULT_TCP_TTL
Definition: dhcp.h:133
#define DHO_DHCP_MAX_MESSAGE_SIZE
Definition: dhcp.h:153
struct iaddr address
Definition: dhcpd.h:156
unsigned int ULONG
Definition: retypes.h:1
#define AF_INET
Definition: tcpip.h:117
#define DHO_DOMAIN_NAME
Definition: dhcp.h:111
unsigned int is_bootp
Definition: dhcpd.h:165
#define debug(msg)
Definition: key_call.c:71
#define malloc
Definition: debug_ros.c:4
_CRTIMP struct tm *__cdecl gmtime(const time_t *_Time)
Definition: time.h:415
DWORD dwIndex
Definition: ifmib.h:38
void set_domain(PDHCP_ADAPTER Adapter, struct client_lease *new_lease)
Definition: dhclient.c:443
#define DHO_DOMAIN_NAME_SERVERS
Definition: dhcp.h:102
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4816
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7786
#define DHO_MASK_SUPPLIER
Definition: dhcp.h:126
void make_request(struct interface_info *ip, struct client_lease *lease)
Definition: dhclient.c:1339
DWORD dwForwardMetric1
Definition: ipmib.h:88
CardRegion * from
Definition: spigame.cpp:19
#define DHCP_SNAME_LEN
Definition: dhcp.h:46
#define DHO_POLICY_FILTER
Definition: dhcp.h:117
void make_decline(struct interface_info *ip, struct client_lease *lease)
Definition: dhclient.c:1441
#define memset(x, y, z)
Definition: compat.h:39
#define REG_DWORD
Definition: sdbapi.c:596
unsigned int is_static
Definition: dhcpd.h:164
int fork_privchld(int, int)
#define DHO_MERIT_DUMP
Definition: dhcp.h:110
int ipv4addrs(char *buf)
Definition: dhclient.c:1937
unsigned long debug_trace_level
Definition: dhclient.c:71
void free_client_lease(struct client_lease *lease)
Definition: dhclient.c:1515
short sin_family
Definition: winsock.h:510
void go_daemon(void)
#define RegCloseKey(hKey)
Definition: registry.h:40
DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAddrLen)
#define BufferSize
Definition: mmc.h:75
#define warning(s)
Definition: debug.h:83
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:251
#define DHO_LPR_SERVERS
Definition: dhcp.h:105
#define STDERR_FILENO
Definition: syshdrs.h:90
#define DHO_COOKIE_SERVERS
Definition: dhcp.h:104
#define DHO_ROOT_PATH
Definition: dhcp.h:113
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
void priv_script_init(struct interface_info *ip, char *reason, char *medium)
Definition: dhclient.c:1621
char * server_name
Definition: dhcpd.h:157
#define REG_SZ
Definition: layer.c:22
#define periodchar(c)
Definition: dhclient.c:61