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