Imported Upstream version 2.88
[platform/upstream/dnsmasq.git] / src / dhcp.c
1 /* dnsmasq is Copyright (c) 2000-2022 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
21 struct iface_param {
22   struct dhcp_context *current;
23   int ind;
24 };
25
26 struct match_param {
27   int ind, matched;
28   struct in_addr netmask, broadcast, addr;
29 };
30
31 static int complete_context(struct in_addr local, int if_index, char *label,
32                             struct in_addr netmask, struct in_addr broadcast, void *vparam);
33 static int check_listen_addrs(struct in_addr local, int if_index, char *label,
34                               struct in_addr netmask, struct in_addr broadcast, void *vparam);
35 static int relay_upstream4(int iface_index, struct dhcp_packet *mess, size_t sz);
36 static struct dhcp_relay *relay_reply4(struct dhcp_packet *mess, char *arrival_interface);
37
38 static int make_fd(int port)
39 {
40   int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
41   struct sockaddr_in saddr;
42   int oneopt = 1;
43 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
44   int mtu = IP_PMTUDISC_DONT;
45 #endif
46 #if defined(IP_TOS) && defined(IPTOS_CLASS_CS6)
47   int tos = IPTOS_CLASS_CS6;
48 #endif
49
50   if (fd == -1)
51     die (_("cannot create DHCP socket: %s"), NULL, EC_BADNET);
52   
53   if (!fix_fd(fd) ||
54 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
55       setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu)) == -1 ||
56 #endif
57 #if defined(IP_TOS) && defined(IPTOS_CLASS_CS6)
58       setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) == -1 ||
59 #endif
60 #if defined(HAVE_LINUX_NETWORK)
61       setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &oneopt, sizeof(oneopt)) == -1 ||
62 #else
63       setsockopt(fd, IPPROTO_IP, IP_RECVIF, &oneopt, sizeof(oneopt)) == -1 ||
64 #endif
65       setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &oneopt, sizeof(oneopt)) == -1)  
66     die(_("failed to set options on DHCP socket: %s"), NULL, EC_BADNET);
67   
68   /* When bind-interfaces is set, there might be more than one dnsmasq
69      instance binding port 67. That's OK if they serve different networks.
70      Need to set REUSEADDR|REUSEPORT to make this possible.
71      Handle the case that REUSEPORT is defined, but the kernel doesn't 
72      support it. This handles the introduction of REUSEPORT on Linux. */
73   if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
74     {
75       int rc = 0;
76
77 #ifdef SO_REUSEPORT
78       if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt))) == -1 && 
79           errno == ENOPROTOOPT)
80         rc = 0;
81 #endif
82       
83       if (rc != -1)
84         rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
85       
86       if (rc == -1)
87         die(_("failed to set SO_REUSE{ADDR|PORT} on DHCP socket: %s"), NULL, EC_BADNET);
88     }
89   
90   memset(&saddr, 0, sizeof(saddr));
91   saddr.sin_family = AF_INET;
92   saddr.sin_port = htons(port);
93   saddr.sin_addr.s_addr = INADDR_ANY;
94 #ifdef HAVE_SOCKADDR_SA_LEN
95   saddr.sin_len = sizeof(struct sockaddr_in);
96 #endif
97
98   if (bind(fd, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in)))
99     die(_("failed to bind DHCP server socket: %s"), NULL, EC_BADNET);
100
101   return fd;
102 }
103
104 void dhcp_init(void)
105 {
106 #if defined(HAVE_BSD_NETWORK)
107   int oneopt = 1;
108 #endif
109
110   daemon->dhcpfd = make_fd(daemon->dhcp_server_port);
111   if (daemon->enable_pxe)
112     daemon->pxefd = make_fd(PXE_PORT);
113   else
114     daemon->pxefd = -1;
115
116 #if defined(HAVE_BSD_NETWORK)
117   /* When we're not using capabilities, we need to do this here before
118      we drop root. Also, set buffer size small, to avoid wasting
119      kernel buffers */
120   
121   if (option_bool(OPT_NO_PING))
122     daemon->dhcp_icmp_fd = -1;
123   else if ((daemon->dhcp_icmp_fd = make_icmp_sock()) == -1 ||
124            setsockopt(daemon->dhcp_icmp_fd, SOL_SOCKET, SO_RCVBUF, &oneopt, sizeof(oneopt)) == -1 )
125     die(_("cannot create ICMP raw socket: %s."), NULL, EC_BADNET);
126   
127   /* Make BPF raw send socket */
128   init_bpf();
129 #endif  
130 }
131
132 void dhcp_packet(time_t now, int pxe_fd)
133 {
134   int fd = pxe_fd ? daemon->pxefd : daemon->dhcpfd;
135   struct dhcp_packet *mess;
136   struct dhcp_context *context;
137   struct dhcp_relay *relay;
138   int is_relay_reply = 0;
139   struct iname *tmp;
140   struct ifreq ifr;
141   struct msghdr msg;
142   struct sockaddr_in dest;
143   struct cmsghdr *cmptr;
144   struct iovec iov;
145   ssize_t sz; 
146   int iface_index = 0, unicast_dest = 0, is_inform = 0, loopback = 0;
147   int rcvd_iface_index;
148   struct in_addr iface_addr;
149   struct iface_param parm;
150   time_t recvtime = now;
151 #ifdef HAVE_LINUX_NETWORK
152   struct arpreq arp_req;
153   struct timeval tv;
154 #endif
155   
156   union {
157     struct cmsghdr align; /* this ensures alignment */
158 #if defined(HAVE_LINUX_NETWORK)
159     char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
160 #elif defined(HAVE_SOLARIS_NETWORK)
161     char control[CMSG_SPACE(sizeof(unsigned int))];
162 #elif defined(HAVE_BSD_NETWORK) 
163     char control[CMSG_SPACE(sizeof(struct sockaddr_dl))];
164 #endif
165   } control_u;
166   struct dhcp_bridge *bridge, *alias;
167
168   msg.msg_controllen = sizeof(control_u);
169   msg.msg_control = control_u.control;
170   msg.msg_name = &dest;
171   msg.msg_namelen = sizeof(dest);
172   msg.msg_iov = &daemon->dhcp_packet;
173   msg.msg_iovlen = 1;
174   
175   if ((sz = recv_dhcp_packet(fd, &msg)) == -1 || 
176       (sz < (ssize_t)(sizeof(*mess) - sizeof(mess->options)))) 
177     return;
178   
179 #ifdef HAVE_DUMPFILE
180   dump_packet_udp(DUMP_DHCP, (void *)daemon->dhcp_packet.iov_base, sz, (union mysockaddr *)&dest, NULL, fd);
181 #endif
182   
183 #if defined (HAVE_LINUX_NETWORK)
184   if (ioctl(fd, SIOCGSTAMP, &tv) == 0)
185     recvtime = tv.tv_sec;
186   
187   if (msg.msg_controllen >= sizeof(struct cmsghdr))
188     for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
189       if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
190         {
191           union {
192             unsigned char *c;
193             struct in_pktinfo *p;
194           } p;
195           p.c = CMSG_DATA(cmptr);
196           iface_index = p.p->ipi_ifindex;
197           if (p.p->ipi_addr.s_addr != INADDR_BROADCAST)
198             unicast_dest = 1;
199         }
200
201 #elif defined(HAVE_BSD_NETWORK) 
202   if (msg.msg_controllen >= sizeof(struct cmsghdr))
203     for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
204       if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
205         {
206           union {
207             unsigned char *c;
208             struct sockaddr_dl *s;
209           } p;
210           p.c = CMSG_DATA(cmptr);
211           iface_index = p.s->sdl_index;
212         }
213   
214 #elif defined(HAVE_SOLARIS_NETWORK) 
215   if (msg.msg_controllen >= sizeof(struct cmsghdr))
216     for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
217       if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
218         {
219           union {
220             unsigned char *c;
221             unsigned int *i;
222           } p;
223           p.c = CMSG_DATA(cmptr);
224           iface_index = *(p.i);
225         }
226 #endif
227         
228   if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name) ||
229       ioctl(daemon->dhcpfd, SIOCGIFFLAGS, &ifr) != 0)
230     return;
231   
232   mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
233   loopback = !mess->giaddr.s_addr && (ifr.ifr_flags & IFF_LOOPBACK);
234   
235 #ifdef HAVE_LINUX_NETWORK
236   /* ARP fiddling uses original interface even if we pretend to use a different one. */
237   safe_strncpy(arp_req.arp_dev, ifr.ifr_name, sizeof(arp_req.arp_dev));
238 #endif 
239
240   /* If the interface on which the DHCP request was received is an
241      alias of some other interface (as specified by the
242      --bridge-interface option), change ifr.ifr_name so that we look
243      for DHCP contexts associated with the aliased interface instead
244      of with the aliasing one. */
245   rcvd_iface_index = iface_index;
246   for (bridge = daemon->bridges; bridge; bridge = bridge->next)
247     {
248       for (alias = bridge->alias; alias; alias = alias->next)
249         if (wildcard_matchn(alias->iface, ifr.ifr_name, IF_NAMESIZE))
250           {
251             if (!(iface_index = if_nametoindex(bridge->iface)))
252               {
253                 my_syslog(MS_DHCP | LOG_WARNING,
254                           _("unknown interface %s in bridge-interface"),
255                           bridge->iface);
256                 return;
257               }
258             else 
259               {
260                 safe_strncpy(ifr.ifr_name,  bridge->iface, sizeof(ifr.ifr_name));
261                 break;
262               }
263           }
264       
265       if (alias)
266         break;
267     }
268
269 #ifdef MSG_BCAST
270   /* OpenBSD tells us when a packet was broadcast */
271   if (!(msg.msg_flags & MSG_BCAST))
272     unicast_dest = 1;
273 #endif
274   
275   if ((relay = relay_reply4((struct dhcp_packet *)daemon->dhcp_packet.iov_base, ifr.ifr_name)))
276     {
277       /* Reply from server, using us as relay. */
278       rcvd_iface_index = relay->iface_index;
279       if (!indextoname(daemon->dhcpfd, rcvd_iface_index, ifr.ifr_name))
280         return;
281       is_relay_reply = 1; 
282       iov.iov_len = sz;
283 #ifdef HAVE_LINUX_NETWORK
284       safe_strncpy(arp_req.arp_dev, ifr.ifr_name, sizeof(arp_req.arp_dev));
285 #endif 
286     }
287   else
288     {
289       ifr.ifr_addr.sa_family = AF_INET;
290       if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1 )
291         iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
292       else
293         {
294           if (iface_check(AF_INET, NULL, ifr.ifr_name, NULL))
295             my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
296           return;
297         }
298       
299       for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
300         if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
301           return;
302       
303       /* unlinked contexts/relays are marked by context->current == context */
304       for (context = daemon->dhcp; context; context = context->next)
305         context->current = context;
306       
307       parm.current = NULL;
308       parm.ind = iface_index;
309       
310       if (!iface_check(AF_INET, (union all_addr *)&iface_addr, ifr.ifr_name, NULL))
311         {
312           /* If we failed to match the primary address of the interface, see if we've got a --listen-address
313              for a secondary */
314           struct match_param match;
315           
316           match.matched = 0;
317           match.ind = iface_index;
318           
319           if (!daemon->if_addrs ||
320               !iface_enumerate(AF_INET, &match, check_listen_addrs) ||
321               !match.matched)
322             return;
323           
324           iface_addr = match.addr;
325           /* make sure secondary address gets priority in case
326              there is more than one address on the interface in the same subnet */
327           complete_context(match.addr, iface_index, NULL, match.netmask, match.broadcast, &parm);
328         }    
329             
330       if (relay_upstream4(iface_index, mess, (size_t)sz))
331         return;
332       
333       if (!iface_enumerate(AF_INET, &parm, complete_context))
334         return;
335
336       /* Check for a relay again after iface_enumerate/complete_context has had
337          chance to fill in relay->iface_index fields. This handles first time through
338          and any changes in interface config. */
339        if (relay_upstream4(iface_index, mess, (size_t)sz))
340         return;
341        
342       /* May have configured relay, but not DHCP server */
343       if (!daemon->dhcp)
344         return;
345
346       lease_prune(NULL, now); /* lose any expired leases */
347       iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz, 
348                                now, unicast_dest, loopback, &is_inform, pxe_fd, iface_addr, recvtime);
349       lease_update_file(now);
350       lease_update_dns(0);
351       
352       if (iov.iov_len == 0)
353         return;
354     }
355
356   msg.msg_name = &dest;
357   msg.msg_namelen = sizeof(dest);
358   msg.msg_control = NULL;
359   msg.msg_controllen = 0;
360   msg.msg_iov = &iov;
361   iov.iov_base = daemon->dhcp_packet.iov_base;
362   
363   /* packet buffer may have moved */
364   mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
365   
366 #ifdef HAVE_SOCKADDR_SA_LEN
367   dest.sin_len = sizeof(struct sockaddr_in);
368 #endif
369   
370   if (pxe_fd)
371     { 
372       if (mess->ciaddr.s_addr != 0)
373         dest.sin_addr = mess->ciaddr;
374     }
375   else if (mess->giaddr.s_addr && !is_relay_reply)
376     {
377       /* Send to BOOTP relay  */
378       dest.sin_port = htons(daemon->dhcp_server_port);
379       dest.sin_addr = mess->giaddr; 
380     }
381   else if (mess->ciaddr.s_addr)
382     {
383       /* If the client's idea of its own address tallys with
384          the source address in the request packet, we believe the
385          source port too, and send back to that.  If we're replying 
386          to a DHCPINFORM, trust the source address always. */
387       if ((!is_inform && dest.sin_addr.s_addr != mess->ciaddr.s_addr) ||
388           dest.sin_port == 0 || dest.sin_addr.s_addr == 0 || is_relay_reply)
389         {
390           dest.sin_port = htons(daemon->dhcp_client_port); 
391           dest.sin_addr = mess->ciaddr;
392         }
393     } 
394 #if defined(HAVE_LINUX_NETWORK)
395   else
396     {
397       /* fill cmsg for outbound interface (both broadcast & unicast) */
398       struct in_pktinfo *pkt;
399       msg.msg_control = control_u.control;
400       msg.msg_controllen = sizeof(control_u);
401       cmptr = CMSG_FIRSTHDR(&msg);
402       pkt = (struct in_pktinfo *)CMSG_DATA(cmptr);
403       pkt->ipi_ifindex = rcvd_iface_index;
404       pkt->ipi_spec_dst.s_addr = 0;
405       msg.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
406       cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
407       cmptr->cmsg_level = IPPROTO_IP;
408       cmptr->cmsg_type = IP_PKTINFO;
409
410       if ((ntohs(mess->flags) & 0x8000) || mess->hlen == 0 ||
411          mess->hlen > sizeof(ifr.ifr_addr.sa_data) || mess->htype == 0)
412         {
413           /* broadcast to 255.255.255.255 (or mac address invalid) */
414           dest.sin_addr.s_addr = INADDR_BROADCAST;
415           dest.sin_port = htons(daemon->dhcp_client_port);
416         }
417       else
418         {
419           /* unicast to unconfigured client. Inject mac address direct into ARP cache.
420           struct sockaddr limits size to 14 bytes. */
421           dest.sin_addr = mess->yiaddr;
422           dest.sin_port = htons(daemon->dhcp_client_port);
423           memcpy(&arp_req.arp_pa, &dest, sizeof(struct sockaddr_in));
424           arp_req.arp_ha.sa_family = mess->htype;
425           memcpy(arp_req.arp_ha.sa_data, mess->chaddr, mess->hlen);
426           /* interface name already copied in */
427           arp_req.arp_flags = ATF_COM;
428           if (ioctl(daemon->dhcpfd, SIOCSARP, &arp_req) == -1)
429             my_syslog(MS_DHCP | LOG_ERR, _("ARP-cache injection failed: %s"), strerror(errno));
430         }
431     }
432 #elif defined(HAVE_SOLARIS_NETWORK)
433   else if ((ntohs(mess->flags) & 0x8000) || mess->hlen != ETHER_ADDR_LEN || mess->htype != ARPHRD_ETHER)
434     {
435       /* broadcast to 255.255.255.255 (or mac address invalid) */
436       dest.sin_addr.s_addr = INADDR_BROADCAST;
437       dest.sin_port = htons(daemon->dhcp_client_port);
438       /* note that we don't specify the interface here: that's done by the
439          IP_BOUND_IF sockopt lower down. */
440     }
441   else
442     {
443       /* unicast to unconfigured client. Inject mac address direct into ARP cache. 
444          Note that this only works for ethernet on solaris, because we use SIOCSARP
445          and not SIOCSXARP, which would be perfect, except that it returns ENXIO 
446          mysteriously. Bah. Fall back to broadcast for other net types. */
447       struct arpreq req;
448       dest.sin_addr = mess->yiaddr;
449       dest.sin_port = htons(daemon->dhcp_client_port);
450       *((struct sockaddr_in *)&req.arp_pa) = dest;
451       req.arp_ha.sa_family = AF_UNSPEC;
452       memcpy(req.arp_ha.sa_data, mess->chaddr, mess->hlen);
453       req.arp_flags = ATF_COM;
454       ioctl(daemon->dhcpfd, SIOCSARP, &req);
455     }
456 #elif defined(HAVE_BSD_NETWORK)
457   else 
458     {
459 #ifdef HAVE_DUMPFILE
460       if (ntohs(mess->flags) & 0x8000)
461         dest.sin_addr.s_addr = INADDR_BROADCAST;
462       else
463         dest.sin_addr = mess->yiaddr;
464       dest.sin_port = htons(daemon->dhcp_client_port);
465       
466       dump_packet_udp(DUMP_DHCP, (void *)iov.iov_base, iov.iov_len, NULL,
467                       (union mysockaddr *)&dest, fd);
468 #endif
469       
470       send_via_bpf(mess, iov.iov_len, iface_addr, &ifr);
471       return;
472     }
473 #endif
474    
475 #ifdef HAVE_SOLARIS_NETWORK
476   setsockopt(fd, IPPROTO_IP, IP_BOUND_IF, &iface_index, sizeof(iface_index));
477 #endif
478
479 #ifdef HAVE_DUMPFILE
480   dump_packet_udp(DUMP_DHCP, (void *)iov.iov_base, iov.iov_len, NULL,
481                   (union mysockaddr *)&dest, fd);
482 #endif
483   
484   while(retry_send(sendmsg(fd, &msg, 0)));
485
486   /* This can fail when, eg, iptables DROPS destination 255.255.255.255 */
487   if (errno != 0)
488     {
489       inet_ntop(AF_INET, &dest.sin_addr, daemon->addrbuff, ADDRSTRLEN);
490       my_syslog(MS_DHCP | LOG_WARNING, _("Error sending DHCP packet to %s: %s"),
491                 daemon->addrbuff, strerror(errno));
492     }
493 }
494
495 /* check against secondary interface addresses */
496 static int check_listen_addrs(struct in_addr local, int if_index, char *label,
497                               struct in_addr netmask, struct in_addr broadcast, void *vparam)
498 {
499   struct match_param *param = vparam;
500   struct iname *tmp;
501
502   (void) label;
503
504   if (if_index == param->ind)
505     {
506       for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
507         if ( tmp->addr.sa.sa_family == AF_INET &&
508              tmp->addr.in.sin_addr.s_addr == local.s_addr)
509           {
510             param->matched = 1;
511             param->addr = local;
512             param->netmask = netmask;
513             param->broadcast = broadcast;
514             break;
515           }
516     }
517   
518   return 1;
519 }
520
521 /* This is a complex routine: it gets called with each (address,netmask,broadcast) triple 
522    of each interface (and any relay address) and does the  following things:
523
524    1) Discards stuff for interfaces other than the one on which a DHCP packet just arrived.
525    2) Fills in any netmask and broadcast addresses which have not been explicitly configured.
526    3) Fills in local (this host) and router (this host or relay) addresses.
527    4) Links contexts which are valid for hosts directly connected to the arrival interface on ->current.
528
529    Note that the current chain may be superseded later for configured hosts or those coming via gateways. */
530
531 static void guess_range_netmask(struct in_addr addr, struct in_addr netmask)
532 {
533   struct dhcp_context *context;
534
535   for (context = daemon->dhcp; context; context = context->next)
536     if (!(context->flags & CONTEXT_NETMASK) &&
537         (is_same_net(addr, context->start, netmask) ||
538          is_same_net(addr, context->end, netmask)))
539       { 
540         if (context->netmask.s_addr != netmask.s_addr &&
541             !(is_same_net(addr, context->start, netmask) &&
542               is_same_net(addr, context->end, netmask)))
543           {
544             inet_ntop(AF_INET, &context->start, daemon->dhcp_buff, DHCP_BUFF_SZ);
545             inet_ntop(AF_INET, &context->end, daemon->dhcp_buff2, DHCP_BUFF_SZ);
546             inet_ntop(AF_INET, &netmask, daemon->addrbuff, ADDRSTRLEN);
547             my_syslog(MS_DHCP | LOG_WARNING, _("DHCP range %s -- %s is not consistent with netmask %s"),
548                       daemon->dhcp_buff, daemon->dhcp_buff2, daemon->addrbuff);
549           }     
550         context->netmask = netmask;
551       }
552 }
553
554 static int complete_context(struct in_addr local, int if_index, char *label,
555                             struct in_addr netmask, struct in_addr broadcast, void *vparam)
556 {
557   struct dhcp_context *context;
558   struct dhcp_relay *relay;
559   struct iface_param *param = vparam;
560   struct shared_network *share;
561   
562   (void)label;
563
564   for (share = daemon->shared_networks; share; share = share->next)
565     {
566       
567 #ifdef HAVE_DHCP6
568       if (share->shared_addr.s_addr == 0)
569         continue;
570 #endif
571       
572       if (share->if_index != 0)
573         {
574           if (share->if_index != if_index)
575             continue;
576         }
577       else
578         {
579           if (share->match_addr.s_addr != local.s_addr)
580             continue;
581         }
582
583       for (context = daemon->dhcp; context; context = context->next)
584         {
585           if (context->netmask.s_addr != 0 &&
586               is_same_net(share->shared_addr, context->start, context->netmask) &&
587               is_same_net(share->shared_addr, context->end, context->netmask))
588             {
589               /* link it onto the current chain if we've not seen it before */
590               if (context->current == context)
591                 {
592                   /* For a shared network, we have no way to guess what the default route should be. */
593                   context->router.s_addr = 0;
594                   context->local = local; /* Use configured address for Server Identifier */
595                   context->current = param->current;
596                   param->current = context;
597                 }
598               
599               if (!(context->flags & CONTEXT_BRDCAST))
600                 context->broadcast.s_addr  = context->start.s_addr | ~context->netmask.s_addr;
601             }           
602         }
603     }
604
605   guess_range_netmask(local, netmask);
606   
607   for (context = daemon->dhcp; context; context = context->next)
608     {
609       if (context->netmask.s_addr != 0 &&
610           is_same_net(local, context->start, context->netmask) &&
611           is_same_net(local, context->end, context->netmask))
612         {
613           /* link it onto the current chain if we've not seen it before */
614           if (if_index == param->ind && context->current == context)
615             {
616               context->router = local;
617               context->local = local;
618               context->current = param->current;
619               param->current = context;
620             }
621           
622           if (!(context->flags & CONTEXT_BRDCAST))
623             {
624               if (is_same_net(broadcast, context->start, context->netmask))
625                 context->broadcast = broadcast;
626               else 
627                 context->broadcast.s_addr  = context->start.s_addr | ~context->netmask.s_addr;
628             }
629         }               
630     }
631
632   for (relay = daemon->relay4; relay; relay = relay->next)
633     if (relay->local.addr4.s_addr == local.s_addr)
634       relay->iface_index = if_index;
635   
636   return 1;
637 }
638           
639 struct dhcp_context *address_available(struct dhcp_context *context, 
640                                        struct in_addr taddr,
641                                        struct dhcp_netid *netids)
642 {
643   /* Check is an address is OK for this network, check all
644      possible ranges. Make sure that the address isn't in use
645      by the server itself. */
646   
647   unsigned int start, end, addr = ntohl(taddr.s_addr);
648   struct dhcp_context *tmp;
649
650   for (tmp = context; tmp; tmp = tmp->current)
651     if (taddr.s_addr == context->router.s_addr)
652       return NULL;
653   
654   for (tmp = context; tmp; tmp = tmp->current)
655     {
656       start = ntohl(tmp->start.s_addr);
657       end = ntohl(tmp->end.s_addr);
658
659       if (!(tmp->flags & (CONTEXT_STATIC | CONTEXT_PROXY)) &&
660           addr >= start &&
661           addr <= end &&
662           match_netid(tmp->filter, netids, 1))
663         return tmp;
664     }
665
666   return NULL;
667 }
668
669 struct dhcp_context *narrow_context(struct dhcp_context *context, 
670                                     struct in_addr taddr,
671                                     struct dhcp_netid *netids)
672 {
673   /* We start of with a set of possible contexts, all on the current physical interface.
674      These are chained on ->current.
675      Here we have an address, and return the actual context corresponding to that
676      address. Note that none may fit, if the address came a dhcp-host and is outside
677      any dhcp-range. In that case we return a static range if possible, or failing that,
678      any context on the correct subnet. (If there's more than one, this is a dodgy 
679      configuration: maybe there should be a warning.) */
680   
681   struct dhcp_context *tmp;
682
683   if (!(tmp = address_available(context, taddr, netids)))
684     {
685       for (tmp = context; tmp; tmp = tmp->current)
686         if (match_netid(tmp->filter, netids, 1) &&
687             is_same_net(taddr, tmp->start, tmp->netmask) && 
688             (tmp->flags & CONTEXT_STATIC))
689           break;
690       
691       if (!tmp)
692         for (tmp = context; tmp; tmp = tmp->current)
693           if (match_netid(tmp->filter, netids, 1) &&
694               is_same_net(taddr, tmp->start, tmp->netmask) &&
695               !(tmp->flags & CONTEXT_PROXY))
696             break;
697     }
698   
699   /* Only one context allowed now */
700   if (tmp)
701     tmp->current = NULL;
702   
703   return tmp;
704 }
705
706 struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr)
707 {
708   struct dhcp_config *config;
709   
710   for (config = configs; config; config = config->next)
711     if ((config->flags & CONFIG_ADDR) && config->addr.s_addr == addr.s_addr)
712       return config;
713
714   return NULL;
715 }
716
717 /* Check if and address is in use by sending ICMP ping.
718    This wrapper handles a cache and load-limiting.
719    Return is NULL is address in use, or a pointer to a cache entry
720    recording that it isn't. */
721 struct ping_result *do_icmp_ping(time_t now, struct in_addr addr, unsigned int hash, int loopback)
722 {
723   static struct ping_result dummy;
724   struct ping_result *r, *victim = NULL;
725   int count, max = (int)(0.6 * (((float)PING_CACHE_TIME)/
726                                 ((float)PING_WAIT)));
727
728   /* check if we failed to ping addr sometime in the last
729      PING_CACHE_TIME seconds. If so, assume the same situation still exists.
730      This avoids problems when a stupid client bangs
731      on us repeatedly. As a final check, if we did more
732      than 60% of the possible ping checks in the last 
733      PING_CACHE_TIME, we are in high-load mode, so don't do any more. */
734   for (count = 0, r = daemon->ping_results; r; r = r->next)
735     if (difftime(now, r->time) >  (float)PING_CACHE_TIME)
736       victim = r; /* old record */
737     else 
738       {
739         count++;
740         if (r->addr.s_addr == addr.s_addr)
741           return r;
742       }
743   
744   /* didn't find cached entry */
745   if ((count >= max) || option_bool(OPT_NO_PING) || loopback)
746     {
747       /* overloaded, or configured not to check, loopback interface, return "not in use" */
748       dummy.hash = hash;
749       return &dummy;
750     }
751   else if (icmp_ping(addr))
752     return NULL; /* address in use. */
753   else
754     {
755       /* at this point victim may hold an expired record */
756       if (!victim)
757         {
758           if ((victim = whine_malloc(sizeof(struct ping_result))))
759             {
760               victim->next = daemon->ping_results;
761               daemon->ping_results = victim;
762             }
763         }
764       
765       /* record that this address is OK for 30s 
766          without more ping checks */
767       if (victim)
768         {
769           victim->addr = addr;
770           victim->time = now;
771           victim->hash = hash;
772         }
773       return victim;
774     }
775 }
776
777 int address_allocate(struct dhcp_context *context,
778                      struct in_addr *addrp, unsigned char *hwaddr, int hw_len, 
779                      struct dhcp_netid *netids, time_t now, int loopback)   
780 {
781   /* Find a free address: exclude anything in use and anything allocated to
782      a particular hwaddr/clientid/hostname in our configuration.
783      Try to return from contexts which match netids first. */
784
785   struct in_addr start, addr;
786   struct dhcp_context *c, *d;
787   int i, pass;
788   unsigned int j; 
789
790   /* hash hwaddr: use the SDBM hashing algorithm.  Seems to give good
791      dispersal even with similarly-valued "strings". */ 
792   for (j = 0, i = 0; i < hw_len; i++)
793     j = hwaddr[i] + (j << 6) + (j << 16) - j;
794
795   /* j == 0 is marker */
796   if (j == 0)
797     j = 1;
798   
799   for (pass = 0; pass <= 1; pass++)
800     for (c = context; c; c = c->current)
801       if (c->flags & (CONTEXT_STATIC | CONTEXT_PROXY))
802         continue;
803       else if (!match_netid(c->filter, netids, pass))
804         continue;
805       else
806         {
807           if (option_bool(OPT_CONSEC_ADDR))
808             /* seed is largest extant lease addr in this context */
809             start = lease_find_max_addr(c);
810           else
811             /* pick a seed based on hwaddr */
812             start.s_addr = htonl(ntohl(c->start.s_addr) + 
813                                  ((j + c->addr_epoch) % (1 + ntohl(c->end.s_addr) - ntohl(c->start.s_addr))));
814
815           /* iterate until we find a free address. */
816           addr = start;
817           
818           do {
819             /* eliminate addresses in use by the server. */
820             for (d = context; d; d = d->current)
821               if (addr.s_addr == d->router.s_addr)
822                 break;
823
824             /* Addresses which end in .255 and .0 are broken in Windows even when using 
825                supernetting. ie dhcp-range=192.168.0.1,192.168.1.254,255,255,254.0
826                then 192.168.0.255 is a valid IP address, but not for Windows as it's
827                in the class C range. See  KB281579. We therefore don't allocate these 
828                addresses to avoid hard-to-diagnose problems. Thanks Bill. */        
829             if (!d &&
830                 !lease_find_by_addr(addr) && 
831                 !config_find_by_address(daemon->dhcp_conf, addr) &&
832                 (!IN_CLASSC(ntohl(addr.s_addr)) || 
833                  ((ntohl(addr.s_addr) & 0xff) != 0xff && ((ntohl(addr.s_addr) & 0xff) != 0x0))))
834               {
835                 /* in consec-ip mode, skip addresses equal to
836                    the number of addresses rejected by clients. This
837                    should avoid the same client being offered the same
838                    address after it has rjected it. */
839                 if (option_bool(OPT_CONSEC_ADDR) && c->addr_epoch)
840                   c->addr_epoch--;
841                 else
842                   {
843                     struct ping_result *r;
844                     
845                     if ((r = do_icmp_ping(now, addr, j, loopback)))
846                       {
847                         /* consec-ip mode: we offered this address for another client
848                            (different hash) recently, don't offer it to this one. */
849                         if (!option_bool(OPT_CONSEC_ADDR) || r->hash == j)
850                           {
851                             *addrp = addr;
852                             return 1;
853                           }
854                       }
855                     else
856                       {
857                         /* address in use: perturb address selection so that we are
858                            less likely to try this address again. */
859                         if (!option_bool(OPT_CONSEC_ADDR))
860                           c->addr_epoch++;
861                       }
862                   }
863               }
864             
865             addr.s_addr = htonl(ntohl(addr.s_addr) + 1);
866             
867             if (addr.s_addr == htonl(ntohl(c->end.s_addr) + 1))
868               addr = c->start;
869             
870           } while (addr.s_addr != start.s_addr);
871         }
872
873   return 0;
874 }
875
876 void dhcp_read_ethers(void)
877 {
878   FILE *f = fopen(ETHERSFILE, "r");
879   unsigned int flags;
880   char *buff = daemon->namebuff;
881   char *ip, *cp;
882   struct in_addr addr;
883   unsigned char hwaddr[ETHER_ADDR_LEN];
884   struct dhcp_config **up, *tmp;
885   struct dhcp_config *config;
886   int count = 0, lineno = 0;
887
888   addr.s_addr = 0; /* eliminate warning */
889   
890   if (!f)
891     {
892       my_syslog(MS_DHCP | LOG_ERR, _("failed to read %s: %s"), ETHERSFILE, strerror(errno));
893       return;
894     }
895
896   /* This can be called again on SIGHUP, so remove entries created last time round. */
897   for (up = &daemon->dhcp_conf, config = daemon->dhcp_conf; config; config = tmp)
898     {
899       tmp = config->next;
900       if (config->flags & CONFIG_FROM_ETHERS)
901         {
902           *up = tmp;
903           /* cannot have a clid */
904           if (config->flags & CONFIG_NAME)
905             free(config->hostname);
906           free(config->hwaddr);
907           free(config);
908         }
909       else
910         up = &config->next;
911     }
912
913   while (fgets(buff, MAXDNAME, f))
914     {
915       char *host = NULL;
916       
917       lineno++;
918       
919       while (strlen(buff) > 0 && isspace((int)buff[strlen(buff)-1]))
920         buff[strlen(buff)-1] = 0;
921       
922       if ((*buff == '#') || (*buff == '+') || (*buff == 0))
923         continue;
924       
925       for (ip = buff; *ip && !isspace((int)*ip); ip++);
926       for(; *ip && isspace((int)*ip); ip++)
927         *ip = 0;
928       if (!*ip || parse_hex(buff, hwaddr, ETHER_ADDR_LEN, NULL, NULL) != ETHER_ADDR_LEN)
929         {
930           my_syslog(MS_DHCP | LOG_ERR, _("bad line at %s line %d"), ETHERSFILE, lineno); 
931           continue;
932         }
933       
934       /* check for name or dotted-quad */
935       for (cp = ip; *cp; cp++)
936         if (!(*cp == '.' || (*cp >='0' && *cp <= '9')))
937           break;
938       
939       if (!*cp)
940         {
941           if (inet_pton(AF_INET, ip, &addr.s_addr) < 1)
942             {
943               my_syslog(MS_DHCP | LOG_ERR, _("bad address at %s line %d"), ETHERSFILE, lineno); 
944               continue;
945             }
946
947           flags = CONFIG_ADDR;
948           
949           for (config = daemon->dhcp_conf; config; config = config->next)
950             if ((config->flags & CONFIG_ADDR) && config->addr.s_addr == addr.s_addr)
951               break;
952         }
953       else 
954         {
955           int nomem;
956           if (!(host = canonicalise(ip, &nomem)) || !legal_hostname(host))
957             {
958               if (!nomem)
959                 my_syslog(MS_DHCP | LOG_ERR, _("bad name at %s line %d"), ETHERSFILE, lineno); 
960               free(host);
961               continue;
962             }
963               
964           flags = CONFIG_NAME;
965
966           for (config = daemon->dhcp_conf; config; config = config->next)
967             if ((config->flags & CONFIG_NAME) && hostname_isequal(config->hostname, host))
968               break;
969         }
970
971       if (config && (config->flags & CONFIG_FROM_ETHERS))
972         {
973           my_syslog(MS_DHCP | LOG_ERR, _("ignoring %s line %d, duplicate name or IP address"), ETHERSFILE, lineno); 
974           continue;
975         }
976         
977       if (!config)
978         { 
979           for (config = daemon->dhcp_conf; config; config = config->next)
980             {
981               struct hwaddr_config *conf_addr = config->hwaddr;
982               if (conf_addr && 
983                   conf_addr->next == NULL && 
984                   conf_addr->wildcard_mask == 0 &&
985                   conf_addr->hwaddr_len == ETHER_ADDR_LEN &&
986                   (conf_addr->hwaddr_type == ARPHRD_ETHER || conf_addr->hwaddr_type == 0) &&
987                   memcmp(conf_addr->hwaddr, hwaddr, ETHER_ADDR_LEN) == 0)
988                 break;
989             }
990           
991           if (!config)
992             {
993               if (!(config = whine_malloc(sizeof(struct dhcp_config))))
994                 continue;
995               config->flags = CONFIG_FROM_ETHERS;
996               config->hwaddr = NULL;
997               config->domain = NULL;
998               config->netid = NULL;
999               config->next = daemon->dhcp_conf;
1000               daemon->dhcp_conf = config;
1001             }
1002           
1003           config->flags |= flags;
1004           
1005           if (flags & CONFIG_NAME)
1006             {
1007               config->hostname = host;
1008               host = NULL;
1009             }
1010           
1011           if (flags & CONFIG_ADDR)
1012             config->addr = addr;
1013         }
1014       
1015       config->flags |= CONFIG_NOCLID;
1016       if (!config->hwaddr)
1017         config->hwaddr = whine_malloc(sizeof(struct hwaddr_config));
1018       if (config->hwaddr)
1019         {
1020           memcpy(config->hwaddr->hwaddr, hwaddr, ETHER_ADDR_LEN);
1021           config->hwaddr->hwaddr_len = ETHER_ADDR_LEN;
1022           config->hwaddr->hwaddr_type = ARPHRD_ETHER;
1023           config->hwaddr->wildcard_mask = 0;
1024           config->hwaddr->next = NULL;
1025         }
1026       count++;
1027       
1028       free(host);
1029
1030     }
1031   
1032   fclose(f);
1033
1034   my_syslog(MS_DHCP | LOG_INFO, _("read %s - %d addresses"), ETHERSFILE, count);
1035 }
1036
1037
1038 /* If we've not found a hostname any other way, try and see if there's one in /etc/hosts
1039    for this address. If it has a domain part, that must match the set domain and
1040    it gets stripped. The set of legal domain names is bigger than the set of legal hostnames
1041    so check here that the domain name is legal as a hostname. 
1042    NOTE: we're only allowed to overwrite daemon->dhcp_buff if we succeed. */
1043 char *host_from_dns(struct in_addr addr)
1044 {
1045   struct crec *lookup;
1046
1047   if (daemon->port == 0)
1048     return NULL; /* DNS disabled. */
1049   
1050   lookup = cache_find_by_addr(NULL, (union all_addr *)&addr, 0, F_IPV4);
1051
1052   if (lookup && (lookup->flags & F_HOSTS))
1053     {
1054       char *dot, *hostname = cache_get_name(lookup);
1055       dot = strchr(hostname, '.');
1056       
1057       if (dot && strlen(dot+1) != 0)
1058         {
1059           char *d2 = get_domain(addr);
1060           if (!d2 || !hostname_isequal(dot+1, d2))
1061             return NULL; /* wrong domain */
1062         }
1063
1064       if (!legal_hostname(hostname))
1065         return NULL;
1066       
1067       safe_strncpy(daemon->dhcp_buff, hostname, 256);
1068       strip_hostname(daemon->dhcp_buff);
1069
1070       return daemon->dhcp_buff;
1071     }
1072   
1073   return NULL;
1074 }
1075
1076 static int relay_upstream4(int iface_index, struct dhcp_packet *mess, size_t sz)
1077 {
1078   struct in_addr giaddr = mess->giaddr;
1079   u8 hops = mess->hops;
1080   struct dhcp_relay *relay;
1081
1082   if (mess->op != BOOTREQUEST)
1083     return 0;
1084
1085   for (relay = daemon->relay4; relay; relay = relay->next)
1086     if (relay->iface_index != 0 && relay->iface_index == iface_index)
1087       break;
1088
1089   /* No relay config. */
1090   if (!relay)
1091     return 0;
1092   
1093   for (; relay; relay = relay->next)
1094     if (relay->iface_index != 0 && relay->iface_index == iface_index)
1095       {
1096         union mysockaddr to;
1097         union all_addr from;
1098
1099         mess->hops = hops;
1100         mess->giaddr = giaddr;
1101         
1102         if ((mess->hops++) > 20)
1103           continue;
1104         
1105         /* source address == relay address */
1106         from.addr4 = relay->local.addr4;
1107
1108         /* already gatewayed ? */
1109         if (giaddr.s_addr)
1110           {
1111             /* if so check if by us, to stomp on loops. */
1112             if (giaddr.s_addr == relay->local.addr4.s_addr)
1113               continue;
1114           }
1115         else
1116           {
1117             /* plug in our address */
1118             mess->giaddr.s_addr = relay->local.addr4.s_addr;
1119           }
1120         
1121         to.sa.sa_family = AF_INET;
1122         to.in.sin_addr = relay->server.addr4;
1123         to.in.sin_port = htons(relay->port);
1124         
1125         /* Broadcasting to server. */
1126         if (relay->server.addr4.s_addr == 0)
1127           {
1128             struct ifreq ifr;
1129             
1130             if (relay->interface)
1131               safe_strncpy(ifr.ifr_name, relay->interface, IF_NAMESIZE);
1132             
1133             if (!relay->interface || strchr(relay->interface, '*') ||
1134                 ioctl(daemon->dhcpfd, SIOCGIFBRDADDR, &ifr) == -1)
1135               {
1136                 my_syslog(MS_DHCP | LOG_ERR, _("Cannot broadcast DHCP relay via interface %s"), relay->interface);
1137                 continue;
1138               }
1139             
1140             to.in.sin_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
1141           }
1142         
1143 #ifdef HAVE_DUMPFILE
1144         {
1145           union mysockaddr fromsock;
1146           fromsock.in.sin_port = htons(daemon->dhcp_server_port);
1147           fromsock.in.sin_addr = from.addr4;
1148           fromsock.sa.sa_family = AF_INET;
1149
1150           dump_packet_udp(DUMP_DHCP, (void *)mess, sz, &fromsock, &to, -1);
1151         }
1152 #endif
1153         
1154          send_from(daemon->dhcpfd, 0, (char *)mess, sz, &to, &from, 0);
1155          
1156          if (option_bool(OPT_LOG_OPTS))
1157            {
1158              inet_ntop(AF_INET, &relay->local, daemon->addrbuff, ADDRSTRLEN);
1159              if (relay->server.addr4.s_addr == 0)
1160                snprintf(daemon->dhcp_buff2, DHCP_BUFF_SZ, _("broadcast via %s"), relay->interface);
1161              else
1162                inet_ntop(AF_INET, &relay->server.addr4, daemon->dhcp_buff2, DHCP_BUFF_SZ);
1163              my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay at %s -> %s"), daemon->addrbuff, daemon->dhcp_buff2);
1164            }
1165       }
1166   
1167   return 1;
1168 }
1169
1170
1171 static struct dhcp_relay *relay_reply4(struct dhcp_packet *mess, char *arrival_interface)
1172 {
1173   struct dhcp_relay *relay;
1174
1175   if (mess->giaddr.s_addr == 0 || mess->op != BOOTREPLY)
1176     return NULL;
1177
1178   for (relay = daemon->relay4; relay; relay = relay->next)
1179     {
1180       if (mess->giaddr.s_addr == relay->local.addr4.s_addr)
1181         {
1182           if (!relay->interface || wildcard_match(relay->interface, arrival_interface))
1183             return relay->iface_index != 0 ? relay : NULL;
1184         }
1185     }
1186   
1187   return NULL;   
1188 }     
1189
1190 #endif