1/* dnsmasq is Copyright (c) 2000-2009 Simon Kelley
2
3   This program is free software; you can redistribute it and/or modify
4   it under the terms of the GNU General Public License as published by
5   the Free Software Foundation; version 2 dated June, 1991, or
6   (at your option) version 3 dated 29 June, 2007.
7
8   This program is distributed in the hope that it will be useful,
9   but WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   GNU General Public License for more details.
12
13   You should have received a copy of the GNU General Public License
14   along with this program.  If not, see <http://www.gnu.org/licenses/>.
15*/
16
17#include "dnsmasq.h"
18
19#ifdef HAVE_DHCP
20
21struct iface_param {
22  struct in_addr relay, primary;
23  struct dhcp_context *current;
24  int ind;
25};
26
27static int complete_context(struct in_addr local, int if_index,
28			    struct in_addr netmask, struct in_addr broadcast, void *vparam);
29
30void dhcp_init(void)
31{
32  int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
33  struct sockaddr_in saddr;
34  int oneopt = 1;
35#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
36  int mtu = IP_PMTUDISC_DONT;
37#endif
38
39  if (fd == -1)
40    die (_("cannot create DHCP socket: %s"), NULL, EC_BADNET);
41
42  if (!fix_fd(fd) ||
43#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
44      setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu)) == -1 ||
45#endif
46#if defined(HAVE_LINUX_NETWORK)
47      setsockopt(fd, SOL_IP, IP_PKTINFO, &oneopt, sizeof(oneopt)) == -1 ||
48#else
49      setsockopt(fd, IPPROTO_IP, IP_RECVIF, &oneopt, sizeof(oneopt)) == -1 ||
50#endif
51      setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &oneopt, sizeof(oneopt)) == -1)
52    die(_("failed to set options on DHCP socket: %s"), NULL, EC_BADNET);
53
54  /* When bind-interfaces is set, there might be more than one dnmsasq
55     instance binding port 67. That's OK if they serve different networks.
56     Need to set REUSEADDR to make this posible, or REUSEPORT on *BSD. */
57  if (daemon->options & OPT_NOWILD)
58    {
59#ifdef SO_REUSEPORT
60      int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt));
61#else
62      int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
63#endif
64      if (rc == -1)
65	die(_("failed to set SO_REUSE{ADDR|PORT} on DHCP socket: %s"), NULL, EC_BADNET);
66    }
67
68  memset(&saddr, 0, sizeof(saddr));
69  saddr.sin_family = AF_INET;
70  saddr.sin_port = htons(daemon->dhcp_server_port);
71  saddr.sin_addr.s_addr = INADDR_ANY;
72#ifdef HAVE_SOCKADDR_SA_LEN
73  saddr.sin_len = sizeof(struct sockaddr_in);
74#endif
75
76  if (bind(fd, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in)))
77    die(_("failed to bind DHCP server socket: %s"), NULL, EC_BADNET);
78
79  daemon->dhcpfd = fd;
80
81#if defined(HAVE_BSD_NETWORK)
82  /* When we're not using capabilities, we need to do this here before
83     we drop root. Also, set buffer size small, to avoid wasting
84     kernel buffers */
85
86  if (daemon->options & OPT_NO_PING)
87    daemon->dhcp_icmp_fd = -1;
88  else if ((daemon->dhcp_icmp_fd = make_icmp_sock()) == -1 ||
89	   setsockopt(daemon->dhcp_icmp_fd, SOL_SOCKET, SO_RCVBUF, &oneopt, sizeof(oneopt)) == -1 )
90    die(_("cannot create ICMP raw socket: %s."), NULL, EC_BADNET);
91
92  /* Make BPF raw send socket */
93  init_bpf();
94#endif
95
96  check_dhcp_hosts(1);
97
98  daemon->dhcp_packet.iov_len = sizeof(struct dhcp_packet);
99  daemon->dhcp_packet.iov_base = safe_malloc(daemon->dhcp_packet.iov_len);
100}
101
102void dhcp_packet(time_t now)
103{
104  struct dhcp_packet *mess;
105  struct dhcp_context *context;
106  struct iname *tmp;
107  struct ifreq ifr;
108  struct msghdr msg;
109  struct sockaddr_in dest;
110  struct cmsghdr *cmptr;
111  struct iovec iov;
112  ssize_t sz;
113  int iface_index = 0, unicast_dest = 0, is_inform = 0;
114  struct in_addr iface_addr, *addrp = NULL;
115  struct iface_param parm;
116
117  union {
118    struct cmsghdr align; /* this ensures alignment */
119#if defined(HAVE_LINUX_NETWORK)
120    char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
121#elif defined(HAVE_SOLARIS_NETWORK)
122    char control[CMSG_SPACE(sizeof(unsigned int))];
123#elif defined(HAVE_BSD_NETWORK)
124    char control[CMSG_SPACE(sizeof(struct sockaddr_dl))];
125#endif
126  } control_u;
127
128  msg.msg_control = NULL;
129  msg.msg_controllen = 0;
130  msg.msg_name = NULL;
131  msg.msg_namelen = 0;
132  msg.msg_iov = &daemon->dhcp_packet;
133  msg.msg_iovlen = 1;
134
135  while (1)
136    {
137      msg.msg_flags = 0;
138      while ((sz = recvmsg(daemon->dhcpfd, &msg, MSG_PEEK | MSG_TRUNC)) == -1 && errno == EINTR);
139
140      if (sz == -1)
141	return;
142
143      if (!(msg.msg_flags & MSG_TRUNC))
144	break;
145
146      /* Very new Linux kernels return the actual size needed,
147	 older ones always return truncated size */
148      if ((size_t)sz == daemon->dhcp_packet.iov_len)
149	{
150	  if (!expand_buf(&daemon->dhcp_packet, sz + 100))
151	    return;
152	}
153      else
154	{
155	  expand_buf(&daemon->dhcp_packet, sz);
156	  break;
157	}
158    }
159
160  /* expand_buf may have moved buffer */
161  mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
162  msg.msg_controllen = sizeof(control_u);
163  msg.msg_control = control_u.control;
164  msg.msg_flags = 0;
165  msg.msg_name = &dest;
166  msg.msg_namelen = sizeof(dest);
167
168  while ((sz = recvmsg(daemon->dhcpfd, &msg, 0)) == -1 && errno == EINTR);
169
170  if ((msg.msg_flags & MSG_TRUNC) || sz < (ssize_t)(sizeof(*mess) - sizeof(mess->options)))
171    return;
172
173#if defined (HAVE_LINUX_NETWORK)
174  if (msg.msg_controllen >= sizeof(struct cmsghdr))
175    for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
176      if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO)
177	{
178	  iface_index = ((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_ifindex;
179	  if (((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_addr.s_addr != INADDR_BROADCAST)
180	    unicast_dest = 1;
181	}
182
183#elif defined(HAVE_BSD_NETWORK)
184  if (msg.msg_controllen >= sizeof(struct cmsghdr))
185    for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
186      if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
187        iface_index = ((struct sockaddr_dl *)CMSG_DATA(cmptr))->sdl_index;
188
189
190#elif defined(HAVE_SOLARIS_NETWORK)
191  if (msg.msg_controllen >= sizeof(struct cmsghdr))
192    for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
193      if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
194	iface_index = *((unsigned int *)CMSG_DATA(cmptr));
195
196#endif
197
198  if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name))
199    return;
200
201#ifdef MSG_BCAST
202  /* OpenBSD tells us when a packet was broadcast */
203  if (!(msg.msg_flags & MSG_BCAST))
204    unicast_dest = 1;
205#endif
206
207  ifr.ifr_addr.sa_family = AF_INET;
208  if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1 )
209    {
210      addrp = &iface_addr;
211      iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
212    }
213
214  if (!iface_check(AF_INET, (struct all_addr *)addrp, ifr.ifr_name, &iface_index))
215    return;
216
217  for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
218    if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
219      return;
220
221  /* interface may have been changed by alias in iface_check */
222  if (!addrp)
223    {
224      if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) == -1)
225	{
226	  my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
227	  return;
228	}
229      else
230	iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
231    }
232
233  /* unlinked contexts are marked by context->current == context */
234  for (context = daemon->dhcp; context; context = context->next)
235    context->current = context;
236
237  parm.relay = mess->giaddr;
238  parm.primary = iface_addr;
239  parm.current = NULL;
240  parm.ind = iface_index;
241
242  if (!iface_enumerate(&parm, complete_context, NULL))
243    return;
244  lease_prune(NULL, now); /* lose any expired leases */
245  iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz,
246			   now, unicast_dest, &is_inform);
247  lease_update_file(now);
248  lease_update_dns();
249
250  if (iov.iov_len == 0)
251    return;
252
253  msg.msg_name = &dest;
254  msg.msg_namelen = sizeof(dest);
255  msg.msg_control = NULL;
256  msg.msg_controllen = 0;
257  msg.msg_iov = &iov;
258  iov.iov_base = daemon->dhcp_packet.iov_base;
259
260  /* packet buffer may have moved */
261  mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
262
263#ifdef HAVE_SOCKADDR_SA_LEN
264  dest.sin_len = sizeof(struct sockaddr_in);
265#endif
266
267  if (mess->giaddr.s_addr)
268    {
269      /* Send to BOOTP relay  */
270      dest.sin_port = htons(daemon->dhcp_server_port);
271      dest.sin_addr = mess->giaddr;
272    }
273  else if (mess->ciaddr.s_addr)
274    {
275      /* If the client's idea of its own address tallys with
276	 the source address in the request packet, we believe the
277	 source port too, and send back to that.  If we're replying
278	 to a DHCPINFORM, trust the source address always. */
279      if ((!is_inform && dest.sin_addr.s_addr != mess->ciaddr.s_addr) ||
280	  dest.sin_port == 0 || dest.sin_addr.s_addr == 0)
281	{
282	  dest.sin_port = htons(daemon->dhcp_client_port);
283	  dest.sin_addr = mess->ciaddr;
284	}
285    }
286#if defined(HAVE_LINUX_NETWORK)
287  else if ((ntohs(mess->flags) & 0x8000) || mess->hlen == 0 ||
288	   mess->hlen > sizeof(ifr.ifr_addr.sa_data) || mess->htype == 0)
289    {
290      /* broadcast to 255.255.255.255 (or mac address invalid) */
291      struct in_pktinfo *pkt;
292      msg.msg_control = control_u.control;
293      msg.msg_controllen = sizeof(control_u);
294      cmptr = CMSG_FIRSTHDR(&msg);
295      pkt = (struct in_pktinfo *)CMSG_DATA(cmptr);
296      pkt->ipi_ifindex = iface_index;
297      pkt->ipi_spec_dst.s_addr = 0;
298      msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
299      cmptr->cmsg_level = SOL_IP;
300      cmptr->cmsg_type = IP_PKTINFO;
301      dest.sin_addr.s_addr = INADDR_BROADCAST;
302      dest.sin_port = htons(daemon->dhcp_client_port);
303    }
304  else
305    {
306      /* unicast to unconfigured client. Inject mac address direct into ARP cache.
307	 struct sockaddr limits size to 14 bytes. */
308      struct arpreq req;
309      dest.sin_addr = mess->yiaddr;
310      dest.sin_port = htons(daemon->dhcp_client_port);
311      *((struct sockaddr_in *)&req.arp_pa) = dest;
312      req.arp_ha.sa_family = mess->htype;
313      memcpy(req.arp_ha.sa_data, mess->chaddr, mess->hlen);
314      strncpy(req.arp_dev, ifr.ifr_name, 16);
315      req.arp_flags = ATF_COM;
316      ioctl(daemon->dhcpfd, SIOCSARP, &req);
317    }
318#elif defined(HAVE_SOLARIS_NETWORK)
319  else if ((ntohs(mess->flags) & 0x8000) || mess->hlen != ETHER_ADDR_LEN || mess->htype != ARPHRD_ETHER)
320    {
321      /* broadcast to 255.255.255.255 (or mac address invalid) */
322      dest.sin_addr.s_addr = INADDR_BROADCAST;
323      dest.sin_port = htons(daemon->dhcp_client_port);
324      /* note that we don't specify the interface here: that's done by the
325	 IP_BOUND_IF sockopt lower down. */
326    }
327  else
328    {
329      /* unicast to unconfigured client. Inject mac address direct into ARP cache.
330	 Note that this only works for ethernet on solaris, because we use SIOCSARP
331	 and not SIOCSXARP, which would be perfect, except that it returns ENXIO
332	 mysteriously. Bah. Fall back to broadcast for other net types. */
333      struct arpreq req;
334      dest.sin_addr = mess->yiaddr;
335      dest.sin_port = htons(daemon->dhcp_client_port);
336      *((struct sockaddr_in *)&req.arp_pa) = dest;
337      req.arp_ha.sa_family = AF_UNSPEC;
338      memcpy(req.arp_ha.sa_data, mess->chaddr, mess->hlen);
339      req.arp_flags = ATF_COM;
340      ioctl(daemon->dhcpfd, SIOCSARP, &req);
341    }
342#elif defined(HAVE_BSD_NETWORK)
343  else
344    {
345      send_via_bpf(mess, iov.iov_len, iface_addr, &ifr);
346      return;
347    }
348#endif
349
350#ifdef HAVE_SOLARIS_NETWORK
351  setsockopt(daemon->dhcpfd, IPPROTO_IP, IP_BOUND_IF, &iface_index, sizeof(iface_index));
352#endif
353
354  while(sendmsg(daemon->dhcpfd, &msg, 0) == -1 && retry_send());
355}
356
357/* This is a complex routine: it gets called with each (address,netmask,broadcast) triple
358   of each interface (and any relay address) and does the  following things:
359
360   1) Discards stuff for interfaces other than the one on which a DHCP packet just arrived.
361   2) Fills in any netmask and broadcast addresses which have not been explicitly configured.
362   3) Fills in local (this host) and router (this host or relay) addresses.
363   4) Links contexts which are valid for hosts directly connected to the arrival interface on ->current.
364
365   Note that the current chain may be superceded later for configured hosts or those coming via gateways. */
366
367static int complete_context(struct in_addr local, int if_index,
368			    struct in_addr netmask, struct in_addr broadcast, void *vparam)
369{
370  struct dhcp_context *context;
371  struct iface_param *param = vparam;
372
373  for (context = daemon->dhcp; context; context = context->next)
374    {
375      if (!(context->flags & CONTEXT_NETMASK) &&
376	  (is_same_net(local, context->start, netmask) ||
377	   is_same_net(local, context->end, netmask)))
378      {
379	if (context->netmask.s_addr != netmask.s_addr &&
380	    !(is_same_net(local, context->start, netmask) &&
381	      is_same_net(local, context->end, netmask)))
382	  {
383	    strcpy(daemon->dhcp_buff, inet_ntoa(context->start));
384	    strcpy(daemon->dhcp_buff2, inet_ntoa(context->end));
385	    my_syslog(MS_DHCP | LOG_WARNING, _("DHCP range %s -- %s is not consistent with netmask %s"),
386		      daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(netmask));
387	  }
388 	context->netmask = netmask;
389      }
390
391      if (context->netmask.s_addr)
392	{
393	  if (is_same_net(local, context->start, context->netmask) &&
394	      is_same_net(local, context->end, context->netmask))
395	    {
396	      /* link it onto the current chain if we've not seen it before */
397	      if (if_index == param->ind && context->current == context)
398		{
399		  context->router = local;
400		  context->local = local;
401		  context->current = param->current;
402		  param->current = context;
403		}
404
405	      if (!(context->flags & CONTEXT_BRDCAST))
406		{
407		  if (is_same_net(broadcast, context->start, context->netmask))
408		    context->broadcast = broadcast;
409		  else
410		    context->broadcast.s_addr  = context->start.s_addr | ~context->netmask.s_addr;
411		}
412	    }
413	  else if (param->relay.s_addr && is_same_net(param->relay, context->start, context->netmask))
414	    {
415	      context->router = param->relay;
416	      context->local = param->primary;
417	      /* fill in missing broadcast addresses for relayed ranges */
418	      if (!(context->flags & CONTEXT_BRDCAST))
419		context->broadcast.s_addr  = context->start.s_addr | ~context->netmask.s_addr;
420	    }
421
422	}
423    }
424
425  return 1;
426}
427
428struct dhcp_context *address_available(struct dhcp_context *context,
429				       struct in_addr taddr,
430				       struct dhcp_netid *netids)
431{
432  /* Check is an address is OK for this network, check all
433     possible ranges. Make sure that the address isn't in use
434     by the server itself. */
435
436  unsigned int start, end, addr = ntohl(taddr.s_addr);
437  struct dhcp_context *tmp;
438
439  for (tmp = context; tmp; tmp = tmp->current)
440    if (taddr.s_addr == context->router.s_addr)
441      return NULL;
442
443  for (tmp = context; tmp; tmp = tmp->current)
444    {
445      start = ntohl(tmp->start.s_addr);
446      end = ntohl(tmp->end.s_addr);
447
448      if (!(tmp->flags & CONTEXT_STATIC) &&
449	  addr >= start &&
450	  addr <= end &&
451	  match_netid(tmp->filter, netids, 1))
452	return tmp;
453    }
454
455  return NULL;
456}
457
458struct dhcp_context *narrow_context(struct dhcp_context *context,
459				    struct in_addr taddr,
460				    struct dhcp_netid *netids)
461{
462  /* We start of with a set of possible contexts, all on the current physical interface.
463     These are chained on ->current.
464     Here we have an address, and return the actual context correponding to that
465     address. Note that none may fit, if the address came a dhcp-host and is outside
466     any dhcp-range. In that case we return a static range if possible, or failing that,
467     any context on the correct subnet. (If there's more than one, this is a dodgy
468     configuration: maybe there should be a warning.) */
469
470  struct dhcp_context *tmp;
471
472  if (!(tmp = address_available(context, taddr, netids)))
473    {
474      for (tmp = context; tmp; tmp = tmp->current)
475	if (is_same_net(taddr, tmp->start, tmp->netmask) &&
476	    (tmp->flags & CONTEXT_STATIC))
477	  break;
478
479      if (!tmp)
480	for (tmp = context; tmp; tmp = tmp->current)
481	  if (is_same_net(taddr, tmp->start, tmp->netmask))
482	    break;
483    }
484
485  /* Only one context allowed now */
486  if (tmp)
487    tmp->current = NULL;
488
489  return tmp;
490}
491
492struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr)
493{
494  struct dhcp_config *config;
495
496  for (config = configs; config; config = config->next)
497    if ((config->flags & CONFIG_ADDR) && config->addr.s_addr == addr.s_addr)
498      return config;
499
500  return NULL;
501}
502
503/* Is every member of check matched by a member of pool?
504   If tagnotneeded, untagged is OK */
505int match_netid(struct dhcp_netid *check, struct dhcp_netid *pool, int tagnotneeded)
506{
507  struct dhcp_netid *tmp1;
508
509  if (!check && !tagnotneeded)
510    return 0;
511
512  for (; check; check = check->next)
513    {
514      if (check->net[0] != '#')
515	{
516	  for (tmp1 = pool; tmp1; tmp1 = tmp1->next)
517	    if (strcmp(check->net, tmp1->net) == 0)
518	      break;
519	  if (!tmp1)
520	    return 0;
521	}
522      else
523	for (tmp1 = pool; tmp1; tmp1 = tmp1->next)
524	  if (strcmp((check->net)+1, tmp1->net) == 0)
525	    return 0;
526    }
527  return 1;
528}
529
530int address_allocate(struct dhcp_context *context,
531		     struct in_addr *addrp, unsigned char *hwaddr, int hw_len,
532		     struct dhcp_netid *netids, time_t now)
533{
534  /* Find a free address: exclude anything in use and anything allocated to
535     a particular hwaddr/clientid/hostname in our configuration.
536     Try to return from contexts which match netids first. */
537
538  struct in_addr start, addr;
539  struct dhcp_context *c, *d;
540  int i, pass;
541  unsigned int j;
542
543  /* hash hwaddr */
544  for (j = 0, i = 0; i < hw_len; i++)
545    j += hwaddr[i] + (hwaddr[i] << 8) + (hwaddr[i] << 16);
546
547  for (pass = 0; pass <= 1; pass++)
548    for (c = context; c; c = c->current)
549      if (c->flags & CONTEXT_STATIC)
550	continue;
551      else if (!match_netid(c->filter, netids, pass))
552	continue;
553      else
554	{
555	  /* pick a seed based on hwaddr then iterate until we find a free address. */
556	  start.s_addr = addr.s_addr =
557	    htonl(ntohl(c->start.s_addr) +
558		  ((j + c->addr_epoch) % (1 + ntohl(c->end.s_addr) - ntohl(c->start.s_addr))));
559
560	  do {
561	    /* eliminate addresses in use by the server. */
562	    for (d = context; d; d = d->current)
563	      if (addr.s_addr == d->router.s_addr)
564		break;
565
566	    /* Addresses which end in .255 and .0 are broken in Windows even when using
567	       supernetting. ie dhcp-range=192.168.0.1,192.168.1.254,255,255,254.0
568	       then 192.168.0.255 is a valid IP address, but not for Windows as it's
569	       in the class C range. See  KB281579. We therefore don't allocate these
570	       addresses to avoid hard-to-diagnose problems. Thanks Bill. */
571	    if (!d &&
572		!lease_find_by_addr(addr) &&
573		!config_find_by_address(daemon->dhcp_conf, addr) &&
574		(!IN_CLASSC(ntohl(addr.s_addr)) ||
575		 ((ntohl(addr.s_addr) & 0xff) != 0xff && ((ntohl(addr.s_addr) & 0xff) != 0x0))))
576	      {
577		struct ping_result *r, *victim = NULL;
578		int count, max = (int)(0.6 * (((float)PING_CACHE_TIME)/
579					      ((float)PING_WAIT)));
580
581		*addrp = addr;
582
583		if (daemon->options & OPT_NO_PING)
584		  return 1;
585
586		/* check if we failed to ping addr sometime in the last
587		   PING_CACHE_TIME seconds. If so, assume the same situation still exists.
588		   This avoids problems when a stupid client bangs
589		   on us repeatedly. As a final check, if we did more
590		   than 60% of the possible ping checks in the last
591		   PING_CACHE_TIME, we are in high-load mode, so don't do any more. */
592		for (count = 0, r = daemon->ping_results; r; r = r->next)
593		  if (difftime(now, r->time) >  (float)PING_CACHE_TIME)
594		    victim = r; /* old record */
595		  else if (++count == max || r->addr.s_addr == addr.s_addr)
596		    return 1;
597
598		if (icmp_ping(addr))
599		  /* address in use: perturb address selection so that we are
600		     less likely to try this address again. */
601		  c->addr_epoch++;
602		else
603		  {
604		    /* at this point victim may hold an expired record */
605		    if (!victim)
606		      {
607			if ((victim = whine_malloc(sizeof(struct ping_result))))
608			  {
609			    victim->next = daemon->ping_results;
610			    daemon->ping_results = victim;
611			  }
612		      }
613
614		    /* record that this address is OK for 30s
615		       without more ping checks */
616		    if (victim)
617		      {
618			victim->addr = addr;
619			victim->time = now;
620		      }
621		    return 1;
622		  }
623	      }
624
625	    addr.s_addr = htonl(ntohl(addr.s_addr) + 1);
626
627	    if (addr.s_addr == htonl(ntohl(c->end.s_addr) + 1))
628	      addr = c->start;
629
630	  } while (addr.s_addr != start.s_addr);
631	}
632  return 0;
633}
634
635static int is_addr_in_context(struct dhcp_context *context, struct dhcp_config *config)
636{
637  if (!context) /* called via find_config() from lease_update_from_configs() */
638    return 1;
639  if (!(config->flags & CONFIG_ADDR))
640    return 1;
641  for (; context; context = context->current)
642    if (is_same_net(config->addr, context->start, context->netmask))
643      return 1;
644
645  return 0;
646}
647
648int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type)
649{
650  struct hwaddr_config *conf_addr;
651
652  for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next)
653    if (conf_addr->wildcard_mask == 0 &&
654	conf_addr->hwaddr_len == len &&
655	(conf_addr->hwaddr_type == type || conf_addr->hwaddr_type == 0) &&
656	memcmp(conf_addr->hwaddr, hwaddr, len) == 0)
657      return 1;
658
659  return 0;
660}
661
662struct dhcp_config *find_config(struct dhcp_config *configs,
663				struct dhcp_context *context,
664				unsigned char *clid, int clid_len,
665				unsigned char *hwaddr, int hw_len,
666				int hw_type, char *hostname)
667{
668  int count, new;
669  struct dhcp_config *config, *candidate;
670  struct hwaddr_config *conf_addr;
671
672  if (clid)
673    for (config = configs; config; config = config->next)
674      if (config->flags & CONFIG_CLID)
675	{
676	  if (config->clid_len == clid_len &&
677	      memcmp(config->clid, clid, clid_len) == 0 &&
678	      is_addr_in_context(context, config))
679	    return config;
680
681	  /* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and
682	     cope with that here */
683	  if (*clid == 0 && config->clid_len == clid_len-1  &&
684	      memcmp(config->clid, clid+1, clid_len-1) == 0 &&
685	      is_addr_in_context(context, config))
686	    return config;
687	}
688
689
690  for (config = configs; config; config = config->next)
691    if (config_has_mac(config, hwaddr, hw_len, hw_type) &&
692	is_addr_in_context(context, config))
693      return config;
694
695  if (hostname && context)
696    for (config = configs; config; config = config->next)
697      if ((config->flags & CONFIG_NAME) &&
698	  hostname_isequal(config->hostname, hostname) &&
699	  is_addr_in_context(context, config))
700	return config;
701
702  /* use match with fewest wildcast octets */
703  for (candidate = NULL, count = 0, config = configs; config; config = config->next)
704    if (is_addr_in_context(context, config))
705      for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next)
706	if (conf_addr->wildcard_mask != 0 &&
707	    conf_addr->hwaddr_len == hw_len &&
708	    (conf_addr->hwaddr_type == hw_type || conf_addr->hwaddr_type == 0) &&
709	    (new = memcmp_masked(conf_addr->hwaddr, hwaddr, hw_len, conf_addr->wildcard_mask)) > count)
710	  {
711	    count = new;
712	    candidate = config;
713	  }
714
715  return candidate;
716}
717
718void dhcp_read_ethers(void)
719{
720  FILE *f = fopen(ETHERSFILE, "r");
721  unsigned int flags;
722  char *buff = daemon->namebuff;
723  char *ip, *cp;
724  struct in_addr addr;
725  unsigned char hwaddr[ETHER_ADDR_LEN];
726  struct dhcp_config **up, *tmp;
727  struct dhcp_config *config;
728  int count = 0, lineno = 0;
729
730  addr.s_addr = 0; /* eliminate warning */
731
732  if (!f)
733    {
734      my_syslog(MS_DHCP | LOG_ERR, _("failed to read %s: %s"), ETHERSFILE, strerror(errno));
735      return;
736    }
737
738  /* This can be called again on SIGHUP, so remove entries created last time round. */
739  for (up = &daemon->dhcp_conf, config = daemon->dhcp_conf; config; config = tmp)
740    {
741      tmp = config->next;
742      if (config->flags & CONFIG_FROM_ETHERS)
743	{
744	  *up = tmp;
745	  /* cannot have a clid */
746	  if (config->flags & CONFIG_NAME)
747	    free(config->hostname);
748	  free(config->hwaddr);
749	  free(config);
750	}
751      else
752	up = &config->next;
753    }
754
755  while (fgets(buff, MAXDNAME, f))
756    {
757      char *host = NULL;
758
759      lineno++;
760
761      while (strlen(buff) > 0 && isspace((int)buff[strlen(buff)-1]))
762	buff[strlen(buff)-1] = 0;
763
764      if ((*buff == '#') || (*buff == '+') || (*buff == 0))
765	continue;
766
767      for (ip = buff; *ip && !isspace((int)*ip); ip++);
768      for(; *ip && isspace((int)*ip); ip++)
769	*ip = 0;
770      if (!*ip || parse_hex(buff, hwaddr, ETHER_ADDR_LEN, NULL, NULL) != ETHER_ADDR_LEN)
771	{
772	  my_syslog(MS_DHCP | LOG_ERR, _("bad line at %s line %d"), ETHERSFILE, lineno);
773	  continue;
774	}
775
776      /* check for name or dotted-quad */
777      for (cp = ip; *cp; cp++)
778	if (!(*cp == '.' || (*cp >='0' && *cp <= '9')))
779	  break;
780
781      if (!*cp)
782	{
783	  if ((addr.s_addr = inet_addr(ip)) == (in_addr_t)-1)
784	    {
785	      my_syslog(MS_DHCP | LOG_ERR, _("bad address at %s line %d"), ETHERSFILE, lineno);
786	      continue;
787	    }
788
789	  flags = CONFIG_ADDR;
790
791	  for (config = daemon->dhcp_conf; config; config = config->next)
792	    if ((config->flags & CONFIG_ADDR) && config->addr.s_addr == addr.s_addr)
793	      break;
794	}
795      else
796	{
797	  int nomem;
798	  if (!(host = canonicalise(ip, &nomem)) || !legal_hostname(host))
799	    {
800	      if (!nomem)
801		my_syslog(MS_DHCP | LOG_ERR, _("bad name at %s line %d"), ETHERSFILE, lineno);
802	      free(host);
803	      continue;
804	    }
805
806	  flags = CONFIG_NAME;
807
808	  for (config = daemon->dhcp_conf; config; config = config->next)
809	    if ((config->flags & CONFIG_NAME) && hostname_isequal(config->hostname, host))
810	      break;
811	}
812
813      if (config && (config->flags & CONFIG_FROM_ETHERS))
814	{
815	  my_syslog(MS_DHCP | LOG_ERR, _("ignoring %s line %d, duplicate name or IP address"), ETHERSFILE, lineno);
816	  continue;
817	}
818
819      if (!config)
820	{
821	  for (config = daemon->dhcp_conf; config; config = config->next)
822	    {
823	      struct hwaddr_config *conf_addr = config->hwaddr;
824	      if (conf_addr &&
825		  conf_addr->next == NULL &&
826		  conf_addr->wildcard_mask == 0 &&
827		  conf_addr->hwaddr_len == ETHER_ADDR_LEN &&
828		  (conf_addr->hwaddr_type == ARPHRD_ETHER || conf_addr->hwaddr_type == 0) &&
829		  memcmp(conf_addr->hwaddr, hwaddr, ETHER_ADDR_LEN) == 0)
830		break;
831	    }
832
833	  if (!config)
834	    {
835	      if (!(config = whine_malloc(sizeof(struct dhcp_config))))
836		continue;
837	      config->flags = CONFIG_FROM_ETHERS;
838	      config->hwaddr = NULL;
839	      config->domain = NULL;
840	      config->next = daemon->dhcp_conf;
841	      daemon->dhcp_conf = config;
842	    }
843
844	  config->flags |= flags;
845
846	  if (flags & CONFIG_NAME)
847	    {
848	      config->hostname = host;
849	      host = NULL;
850	    }
851
852	  if (flags & CONFIG_ADDR)
853	    config->addr = addr;
854	}
855
856      config->flags |= CONFIG_NOCLID;
857      if (!config->hwaddr)
858	config->hwaddr = whine_malloc(sizeof(struct hwaddr_config));
859      if (config->hwaddr)
860	{
861	  memcpy(config->hwaddr->hwaddr, hwaddr, ETHER_ADDR_LEN);
862	  config->hwaddr->hwaddr_len = ETHER_ADDR_LEN;
863	  config->hwaddr->hwaddr_type = ARPHRD_ETHER;
864	  config->hwaddr->wildcard_mask = 0;
865	  config->hwaddr->next = NULL;
866	}
867      count++;
868
869      free(host);
870
871    }
872
873  fclose(f);
874
875  my_syslog(MS_DHCP | LOG_INFO, _("read %s - %d addresses"), ETHERSFILE, count);
876}
877
878void check_dhcp_hosts(int fatal)
879{
880  /* If the same IP appears in more than one host config, then DISCOVER
881     for one of the hosts will get the address, but REQUEST will be NAKed,
882     since the address is reserved by the other one -> protocol loop.
883     Also check that FQDNs match the domain we are using. */
884
885  struct dhcp_config *configs, *cp;
886
887  for (configs = daemon->dhcp_conf; configs; configs = configs->next)
888    {
889      char *domain;
890
891      if ((configs->flags & DHOPT_BANK) || fatal)
892       {
893	 for (cp = configs->next; cp; cp = cp->next)
894	   if ((configs->flags & cp->flags & CONFIG_ADDR) && configs->addr.s_addr == cp->addr.s_addr)
895	     {
896	       if (fatal)
897		 die(_("duplicate IP address %s in dhcp-config directive."),
898		     inet_ntoa(cp->addr), EC_BADCONF);
899	       else
900		 my_syslog(MS_DHCP | LOG_ERR, _("duplicate IP address %s in %s."),
901			   inet_ntoa(cp->addr), daemon->dhcp_hosts_file);
902	       configs->flags &= ~CONFIG_ADDR;
903	     }
904
905	 /* split off domain part */
906	 if ((configs->flags & CONFIG_NAME) && (domain = strip_hostname(configs->hostname)))
907	   configs->domain = domain;
908       }
909    }
910}
911
912void dhcp_update_configs(struct dhcp_config *configs)
913{
914  /* Some people like to keep all static IP addresses in /etc/hosts.
915     This goes through /etc/hosts and sets static addresses for any DHCP config
916     records which don't have an address and whose name matches.
917     We take care to maintain the invariant that any IP address can appear
918     in at most one dhcp-host. Since /etc/hosts can be re-read by SIGHUP,
919     restore the status-quo ante first. */
920
921  struct dhcp_config *config;
922  struct crec *crec;
923
924  for (config = configs; config; config = config->next)
925    if (config->flags & CONFIG_ADDR_HOSTS)
926      config->flags &= ~(CONFIG_ADDR | CONFIG_ADDR_HOSTS);
927
928
929  if (daemon->port != 0)
930    for (config = configs; config; config = config->next)
931      if (!(config->flags & CONFIG_ADDR) &&
932	  (config->flags & CONFIG_NAME) &&
933	  (crec = cache_find_by_name(NULL, config->hostname, 0, F_IPV4)) &&
934	  (crec->flags & F_HOSTS))
935	{
936	  if (cache_find_by_name(crec, config->hostname, 0, F_IPV4))
937	    {
938	      /* use primary (first) address */
939	      while (crec && !(crec->flags & F_REVERSE))
940		crec = cache_find_by_name(crec, config->hostname, 0, F_IPV4);
941	      if (!crec)
942		continue; /* should be never */
943	      my_syslog(MS_DHCP | LOG_WARNING, _("%s has more than one address in hostsfile, using %s for DHCP"),
944			config->hostname, inet_ntoa(crec->addr.addr.addr.addr4));
945	    }
946
947	  if (config_find_by_address(configs, crec->addr.addr.addr.addr4))
948	    my_syslog(MS_DHCP | LOG_WARNING, _("duplicate IP address %s (%s) in dhcp-config directive"),
949		      inet_ntoa(crec->addr.addr.addr.addr4), config->hostname);
950	  else
951	    {
952	      config->addr = crec->addr.addr.addr.addr4;
953	      config->flags |= CONFIG_ADDR | CONFIG_ADDR_HOSTS;
954	    }
955	}
956}
957
958/* If we've not found a hostname any other way, try and see if there's one in /etc/hosts
959   for this address. If it has a domain part, that must match the set domain and
960   it gets stripped. The set of legal domain names is bigger than the set of legal hostnames
961   so check here that the domain name is legal as a hostname. */
962char *host_from_dns(struct in_addr addr)
963{
964  struct crec *lookup;
965  char *hostname = NULL;
966  char *d1, *d2;
967
968  if (daemon->port == 0)
969    return NULL; /* DNS disabled. */
970
971  lookup = cache_find_by_addr(NULL, (struct all_addr *)&addr, 0, F_IPV4);
972  if (lookup && (lookup->flags & F_HOSTS))
973    {
974      hostname = daemon->dhcp_buff;
975      strncpy(hostname, cache_get_name(lookup), 256);
976      hostname[255] = 0;
977      d1 = strip_hostname(hostname);
978      d2 = get_domain(addr);
979      if (!legal_hostname(hostname) || (d1 && (!d2 || !hostname_isequal(d1, d2))))
980	hostname = NULL;
981    }
982
983  return hostname;
984}
985
986/* return domain or NULL if none. */
987char *strip_hostname(char *hostname)
988{
989  char *dot = strchr(hostname, '.');
990
991  if (!dot)
992    return NULL;
993
994  *dot = 0; /* truncate */
995  if (strlen(dot+1) != 0)
996    return dot+1;
997
998  return NULL;
999}
1000
1001#endif
1002
1003