1 /* dnsmasq is Copyright (c) 2000-2013 Simon Kelley
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.
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.
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/>.
22 struct dhcp_context
*current
;
28 struct in_addr netmask
, broadcast
, addr
;
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
);
36 static int make_fd(int port
)
38 int fd
= socket(PF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
39 struct sockaddr_in saddr
;
41 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
42 int mtu
= IP_PMTUDISC_DONT
;
44 #if defined(IP_TOS) && defined(IPTOS_CLASS_CS6)
45 int tos
= IPTOS_CLASS_CS6
;
49 die (_("cannot create DHCP socket: %s"), NULL
, EC_BADNET
);
52 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
53 setsockopt(fd
, IPPROTO_IP
, IP_MTU_DISCOVER
, &mtu
, sizeof(mtu
)) == -1 ||
55 #if defined(IP_TOS) && defined(IPTOS_CLASS_CS6)
56 setsockopt(fd
, IPPROTO_IP
, IP_TOS
, &tos
, sizeof(tos
)) == -1 ||
58 #if defined(HAVE_LINUX_NETWORK)
59 setsockopt(fd
, IPPROTO_IP
, IP_PKTINFO
, &oneopt
, sizeof(oneopt
)) == -1 ||
61 setsockopt(fd
, IPPROTO_IP
, IP_RECVIF
, &oneopt
, sizeof(oneopt
)) == -1 ||
63 setsockopt(fd
, SOL_SOCKET
, SO_BROADCAST
, &oneopt
, sizeof(oneopt
)) == -1)
64 die(_("failed to set options on DHCP socket: %s"), NULL
, EC_BADNET
);
66 /* When bind-interfaces is set, there might be more than one dnmsasq
67 instance binding port 67. That's OK if they serve different networks.
68 Need to set REUSEADDR|REUSEPORT to make this posible.
69 Handle the case that REUSEPORT is defined, but the kernel doesn't
70 support it. This handles the introduction of REUSEPORT on Linux. */
71 if (option_bool(OPT_NOWILD
) || option_bool(OPT_CLEVERBIND
))
73 int rc
= -1, porterr
= 0;
76 if ((rc
= setsockopt(fd
, SOL_SOCKET
, SO_REUSEPORT
, &oneopt
, sizeof(oneopt
))) == -1 &&
81 if (rc
== -1 && !porterr
)
82 rc
= setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &oneopt
, sizeof(oneopt
));
85 die(_("failed to set SO_REUSE{ADDR|PORT} on DHCP socket: %s"), NULL
, EC_BADNET
);
88 memset(&saddr
, 0, sizeof(saddr
));
89 saddr
.sin_family
= AF_INET
;
90 saddr
.sin_port
= htons(port
);
91 saddr
.sin_addr
.s_addr
= INADDR_ANY
;
92 #ifdef HAVE_SOCKADDR_SA_LEN
93 saddr
.sin_len
= sizeof(struct sockaddr_in
);
96 if (bind(fd
, (struct sockaddr
*)&saddr
, sizeof(struct sockaddr_in
)))
97 die(_("failed to bind DHCP server socket: %s"), NULL
, EC_BADNET
);
104 #if defined(HAVE_BSD_NETWORK)
108 daemon
->dhcpfd
= make_fd(daemon
->dhcp_server_port
);
109 if (daemon
->enable_pxe
)
110 daemon
->pxefd
= make_fd(PXE_PORT
);
114 #if defined(HAVE_BSD_NETWORK)
115 /* When we're not using capabilities, we need to do this here before
116 we drop root. Also, set buffer size small, to avoid wasting
119 if (option_bool(OPT_NO_PING
))
120 daemon
->dhcp_icmp_fd
= -1;
121 else if ((daemon
->dhcp_icmp_fd
= make_icmp_sock()) == -1 ||
122 setsockopt(daemon
->dhcp_icmp_fd
, SOL_SOCKET
, SO_RCVBUF
, &oneopt
, sizeof(oneopt
)) == -1 )
123 die(_("cannot create ICMP raw socket: %s."), NULL
, EC_BADNET
);
125 /* Make BPF raw send socket */
130 void dhcp_packet(time_t now
, int pxe_fd
)
132 int fd
= pxe_fd
? daemon
->pxefd
: daemon
->dhcpfd
;
133 struct dhcp_packet
*mess
;
134 struct dhcp_context
*context
;
138 struct sockaddr_in dest
;
139 struct cmsghdr
*cmptr
;
142 int iface_index
= 0, unicast_dest
= 0, is_inform
= 0;
143 struct in_addr iface_addr
;
144 struct iface_param parm
;
145 #ifdef HAVE_LINUX_NETWORK
146 struct arpreq arp_req
;
150 struct cmsghdr align
; /* this ensures alignment */
151 #if defined(HAVE_LINUX_NETWORK)
152 char control
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
153 #elif defined(HAVE_SOLARIS_NETWORK)
154 char control
[CMSG_SPACE(sizeof(unsigned int))];
155 #elif defined(HAVE_BSD_NETWORK)
156 char control
[CMSG_SPACE(sizeof(struct sockaddr_dl
))];
159 struct dhcp_bridge
*bridge
, *alias
;
161 msg
.msg_controllen
= sizeof(control_u
);
162 msg
.msg_control
= control_u
.control
;
163 msg
.msg_name
= &dest
;
164 msg
.msg_namelen
= sizeof(dest
);
165 msg
.msg_iov
= &daemon
->dhcp_packet
;
168 if ((sz
= recv_dhcp_packet(fd
, &msg
)) == -1 ||
169 (sz
< (ssize_t
)(sizeof(*mess
) - sizeof(mess
->options
))))
172 #if defined (HAVE_LINUX_NETWORK)
173 if (msg
.msg_controllen
>= sizeof(struct cmsghdr
))
174 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
175 if (cmptr
->cmsg_level
== IPPROTO_IP
&& cmptr
->cmsg_type
== IP_PKTINFO
)
179 struct in_pktinfo
*p
;
181 p
.c
= CMSG_DATA(cmptr
);
182 iface_index
= p
.p
->ipi_ifindex
;
183 if (p
.p
->ipi_addr
.s_addr
!= INADDR_BROADCAST
)
187 #elif defined(HAVE_BSD_NETWORK)
188 if (msg
.msg_controllen
>= sizeof(struct cmsghdr
))
189 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
190 if (cmptr
->cmsg_level
== IPPROTO_IP
&& cmptr
->cmsg_type
== IP_RECVIF
)
194 struct sockaddr_dl
*s
;
196 p
.c
= CMSG_DATA(cmptr
);
197 iface_index
= p
.s
->sdl_index
;
200 #elif defined(HAVE_SOLARIS_NETWORK)
201 if (msg
.msg_controllen
>= sizeof(struct cmsghdr
))
202 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
203 if (cmptr
->cmsg_level
== IPPROTO_IP
&& cmptr
->cmsg_type
== IP_RECVIF
)
209 p
.c
= CMSG_DATA(cmptr
);
210 iface_index
= *(p
.i
);
214 if (!indextoname(daemon
->dhcpfd
, iface_index
, ifr
.ifr_name
))
217 #ifdef HAVE_LINUX_NETWORK
218 /* ARP fiddling uses original interface even if we pretend to use a different one. */
219 strncpy(arp_req
.arp_dev
, ifr
.ifr_name
, 16);
222 /* One form of bridging on BSD has the property that packets
223 can be recieved on bridge interfaces which do not have an IP address.
224 We allow these to be treated as aliases of another interface which does have
225 an IP address with --dhcp-bridge=interface,alias,alias */
226 for (bridge
= daemon
->bridges
; bridge
; bridge
= bridge
->next
)
228 for (alias
= bridge
->alias
; alias
; alias
= alias
->next
)
229 if (strncmp(ifr
.ifr_name
, alias
->iface
, IF_NAMESIZE
) == 0)
231 if (!(iface_index
= if_nametoindex(bridge
->iface
)))
233 my_syslog(LOG_WARNING
, _("unknown interface %s in bridge-interface"), ifr
.ifr_name
);
238 strncpy(ifr
.ifr_name
, bridge
->iface
, IF_NAMESIZE
);
248 /* OpenBSD tells us when a packet was broadcast */
249 if (!(msg
.msg_flags
& MSG_BCAST
))
253 ifr
.ifr_addr
.sa_family
= AF_INET
;
254 if (ioctl(daemon
->dhcpfd
, SIOCGIFADDR
, &ifr
) != -1 )
255 iface_addr
= ((struct sockaddr_in
*) &ifr
.ifr_addr
)->sin_addr
;
258 my_syslog(MS_DHCP
| LOG_WARNING
, _("DHCP packet received on %s which has no address"), ifr
.ifr_name
);
262 for (tmp
= daemon
->dhcp_except
; tmp
; tmp
= tmp
->next
)
263 if (tmp
->name
&& wildcard_match(tmp
->name
, ifr
.ifr_name
))
266 /* unlinked contexts are marked by context->current == context */
267 for (context
= daemon
->dhcp
; context
; context
= context
->next
)
268 context
->current
= context
;
271 parm
.ind
= iface_index
;
273 if (!iface_check(AF_INET
, (struct all_addr
*)&iface_addr
, ifr
.ifr_name
, NULL
))
275 /* If we failed to match the primary address of the interface, see if we've got a --listen-address
277 struct match_param match
;
280 match
.ind
= iface_index
;
282 if (!daemon
->if_addrs
||
283 !iface_enumerate(AF_INET
, &match
, check_listen_addrs
) ||
287 iface_addr
= match
.addr
;
288 /* make sure secondary address gets priority in case
289 there is more than one address on the interface in the same subnet */
290 complete_context(match
.addr
, iface_index
, NULL
, match
.netmask
, match
.broadcast
, &parm
);
293 if (!iface_enumerate(AF_INET
, &parm
, complete_context
))
296 lease_prune(NULL
, now
); /* lose any expired leases */
297 iov
.iov_len
= dhcp_reply(parm
.current
, ifr
.ifr_name
, iface_index
, (size_t)sz
,
298 now
, unicast_dest
, &is_inform
, pxe_fd
, iface_addr
);
299 lease_update_file(now
);
302 if (iov
.iov_len
== 0)
305 msg
.msg_name
= &dest
;
306 msg
.msg_namelen
= sizeof(dest
);
307 msg
.msg_control
= NULL
;
308 msg
.msg_controllen
= 0;
310 iov
.iov_base
= daemon
->dhcp_packet
.iov_base
;
312 /* packet buffer may have moved */
313 mess
= (struct dhcp_packet
*)daemon
->dhcp_packet
.iov_base
;
315 #ifdef HAVE_SOCKADDR_SA_LEN
316 dest
.sin_len
= sizeof(struct sockaddr_in
);
321 if (mess
->ciaddr
.s_addr
!= 0)
322 dest
.sin_addr
= mess
->ciaddr
;
324 else if (mess
->giaddr
.s_addr
)
326 /* Send to BOOTP relay */
327 dest
.sin_port
= htons(daemon
->dhcp_server_port
);
328 dest
.sin_addr
= mess
->giaddr
;
330 else if (mess
->ciaddr
.s_addr
)
332 /* If the client's idea of its own address tallys with
333 the source address in the request packet, we believe the
334 source port too, and send back to that. If we're replying
335 to a DHCPINFORM, trust the source address always. */
336 if ((!is_inform
&& dest
.sin_addr
.s_addr
!= mess
->ciaddr
.s_addr
) ||
337 dest
.sin_port
== 0 || dest
.sin_addr
.s_addr
== 0)
339 dest
.sin_port
= htons(daemon
->dhcp_client_port
);
340 dest
.sin_addr
= mess
->ciaddr
;
343 #if defined(HAVE_LINUX_NETWORK)
344 else if ((ntohs(mess
->flags
) & 0x8000) || mess
->hlen
== 0 ||
345 mess
->hlen
> sizeof(ifr
.ifr_addr
.sa_data
) || mess
->htype
== 0)
347 /* broadcast to 255.255.255.255 (or mac address invalid) */
348 struct in_pktinfo
*pkt
;
349 msg
.msg_control
= control_u
.control
;
350 msg
.msg_controllen
= sizeof(control_u
);
351 cmptr
= CMSG_FIRSTHDR(&msg
);
352 pkt
= (struct in_pktinfo
*)CMSG_DATA(cmptr
);
353 pkt
->ipi_ifindex
= iface_index
;
354 pkt
->ipi_spec_dst
.s_addr
= 0;
355 msg
.msg_controllen
= cmptr
->cmsg_len
= CMSG_LEN(sizeof(struct in_pktinfo
));
356 cmptr
->cmsg_level
= IPPROTO_IP
;
357 cmptr
->cmsg_type
= IP_PKTINFO
;
358 dest
.sin_addr
.s_addr
= INADDR_BROADCAST
;
359 dest
.sin_port
= htons(daemon
->dhcp_client_port
);
363 /* unicast to unconfigured client. Inject mac address direct into ARP cache.
364 struct sockaddr limits size to 14 bytes. */
365 dest
.sin_addr
= mess
->yiaddr
;
366 dest
.sin_port
= htons(daemon
->dhcp_client_port
);
367 memcpy(&arp_req
.arp_pa
, &dest
, sizeof(struct sockaddr_in
));
368 arp_req
.arp_ha
.sa_family
= mess
->htype
;
369 memcpy(arp_req
.arp_ha
.sa_data
, mess
->chaddr
, mess
->hlen
);
370 /* interface name already copied in */
371 arp_req
.arp_flags
= ATF_COM
;
372 ioctl(daemon
->dhcpfd
, SIOCSARP
, &arp_req
);
374 #elif defined(HAVE_SOLARIS_NETWORK)
375 else if ((ntohs(mess
->flags
) & 0x8000) || mess
->hlen
!= ETHER_ADDR_LEN
|| mess
->htype
!= ARPHRD_ETHER
)
377 /* broadcast to 255.255.255.255 (or mac address invalid) */
378 dest
.sin_addr
.s_addr
= INADDR_BROADCAST
;
379 dest
.sin_port
= htons(daemon
->dhcp_client_port
);
380 /* note that we don't specify the interface here: that's done by the
381 IP_BOUND_IF sockopt lower down. */
385 /* unicast to unconfigured client. Inject mac address direct into ARP cache.
386 Note that this only works for ethernet on solaris, because we use SIOCSARP
387 and not SIOCSXARP, which would be perfect, except that it returns ENXIO
388 mysteriously. Bah. Fall back to broadcast for other net types. */
390 dest
.sin_addr
= mess
->yiaddr
;
391 dest
.sin_port
= htons(daemon
->dhcp_client_port
);
392 *((struct sockaddr_in
*)&req
.arp_pa
) = dest
;
393 req
.arp_ha
.sa_family
= AF_UNSPEC
;
394 memcpy(req
.arp_ha
.sa_data
, mess
->chaddr
, mess
->hlen
);
395 req
.arp_flags
= ATF_COM
;
396 ioctl(daemon
->dhcpfd
, SIOCSARP
, &req
);
398 #elif defined(HAVE_BSD_NETWORK)
401 send_via_bpf(mess
, iov
.iov_len
, iface_addr
, &ifr
);
406 #ifdef HAVE_SOLARIS_NETWORK
407 setsockopt(fd
, IPPROTO_IP
, IP_BOUND_IF
, &iface_index
, sizeof(iface_index
));
410 while(sendmsg(fd
, &msg
, 0) == -1 && retry_send());
413 /* check against secondary interface addresses */
414 static int check_listen_addrs(struct in_addr local
, int if_index
, char *label
,
415 struct in_addr netmask
, struct in_addr broadcast
, void *vparam
)
417 struct match_param
*param
= vparam
;
422 if (if_index
== param
->ind
)
424 for (tmp
= daemon
->if_addrs
; tmp
; tmp
= tmp
->next
)
425 if ( tmp
->addr
.sa
.sa_family
== AF_INET
&&
426 tmp
->addr
.in
.sin_addr
.s_addr
== local
.s_addr
)
430 param
->netmask
= netmask
;
431 param
->broadcast
= broadcast
;
439 /* This is a complex routine: it gets called with each (address,netmask,broadcast) triple
440 of each interface (and any relay address) and does the following things:
442 1) Discards stuff for interfaces other than the one on which a DHCP packet just arrived.
443 2) Fills in any netmask and broadcast addresses which have not been explicitly configured.
444 3) Fills in local (this host) and router (this host or relay) addresses.
445 4) Links contexts which are valid for hosts directly connected to the arrival interface on ->current.
447 Note that the current chain may be superceded later for configured hosts or those coming via gateways. */
449 static int complete_context(struct in_addr local
, int if_index
, char *label
,
450 struct in_addr netmask
, struct in_addr broadcast
, void *vparam
)
452 struct dhcp_context
*context
;
453 struct iface_param
*param
= vparam
;
457 for (context
= daemon
->dhcp
; context
; context
= context
->next
)
459 if (!(context
->flags
& CONTEXT_NETMASK
) &&
460 (is_same_net(local
, context
->start
, netmask
) ||
461 is_same_net(local
, context
->end
, netmask
)))
463 if (context
->netmask
.s_addr
!= netmask
.s_addr
&&
464 !(is_same_net(local
, context
->start
, netmask
) &&
465 is_same_net(local
, context
->end
, netmask
)))
467 strcpy(daemon
->dhcp_buff
, inet_ntoa(context
->start
));
468 strcpy(daemon
->dhcp_buff2
, inet_ntoa(context
->end
));
469 my_syslog(MS_DHCP
| LOG_WARNING
, _("DHCP range %s -- %s is not consistent with netmask %s"),
470 daemon
->dhcp_buff
, daemon
->dhcp_buff2
, inet_ntoa(netmask
));
472 context
->netmask
= netmask
;
475 if (context
->netmask
.s_addr
!= 0 &&
476 is_same_net(local
, context
->start
, context
->netmask
) &&
477 is_same_net(local
, context
->end
, context
->netmask
))
479 /* link it onto the current chain if we've not seen it before */
480 if (if_index
== param
->ind
&& context
->current
== context
)
482 context
->router
= local
;
483 context
->local
= local
;
484 context
->current
= param
->current
;
485 param
->current
= context
;
488 if (!(context
->flags
& CONTEXT_BRDCAST
))
490 if (is_same_net(broadcast
, context
->start
, context
->netmask
))
491 context
->broadcast
= broadcast
;
493 context
->broadcast
.s_addr
= context
->start
.s_addr
| ~context
->netmask
.s_addr
;
501 struct dhcp_context
*address_available(struct dhcp_context
*context
,
502 struct in_addr taddr
,
503 struct dhcp_netid
*netids
)
505 /* Check is an address is OK for this network, check all
506 possible ranges. Make sure that the address isn't in use
507 by the server itself. */
509 unsigned int start
, end
, addr
= ntohl(taddr
.s_addr
);
510 struct dhcp_context
*tmp
;
512 for (tmp
= context
; tmp
; tmp
= tmp
->current
)
513 if (taddr
.s_addr
== context
->router
.s_addr
)
516 for (tmp
= context
; tmp
; tmp
= tmp
->current
)
518 start
= ntohl(tmp
->start
.s_addr
);
519 end
= ntohl(tmp
->end
.s_addr
);
521 if (!(tmp
->flags
& (CONTEXT_STATIC
| CONTEXT_PROXY
)) &&
524 match_netid(tmp
->filter
, netids
, 1))
531 struct dhcp_context
*narrow_context(struct dhcp_context
*context
,
532 struct in_addr taddr
,
533 struct dhcp_netid
*netids
)
535 /* We start of with a set of possible contexts, all on the current physical interface.
536 These are chained on ->current.
537 Here we have an address, and return the actual context correponding to that
538 address. Note that none may fit, if the address came a dhcp-host and is outside
539 any dhcp-range. In that case we return a static range if possible, or failing that,
540 any context on the correct subnet. (If there's more than one, this is a dodgy
541 configuration: maybe there should be a warning.) */
543 struct dhcp_context
*tmp
;
545 if (!(tmp
= address_available(context
, taddr
, netids
)))
547 for (tmp
= context
; tmp
; tmp
= tmp
->current
)
548 if (match_netid(tmp
->filter
, netids
, 1) &&
549 is_same_net(taddr
, tmp
->start
, tmp
->netmask
) &&
550 (tmp
->flags
& CONTEXT_STATIC
))
554 for (tmp
= context
; tmp
; tmp
= tmp
->current
)
555 if (match_netid(tmp
->filter
, netids
, 1) &&
556 is_same_net(taddr
, tmp
->start
, tmp
->netmask
) &&
557 !(tmp
->flags
& CONTEXT_PROXY
))
561 /* Only one context allowed now */
568 struct dhcp_config
*config_find_by_address(struct dhcp_config
*configs
, struct in_addr addr
)
570 struct dhcp_config
*config
;
572 for (config
= configs
; config
; config
= config
->next
)
573 if ((config
->flags
& CONFIG_ADDR
) && config
->addr
.s_addr
== addr
.s_addr
)
579 int address_allocate(struct dhcp_context
*context
,
580 struct in_addr
*addrp
, unsigned char *hwaddr
, int hw_len
,
581 struct dhcp_netid
*netids
, time_t now
)
583 /* Find a free address: exclude anything in use and anything allocated to
584 a particular hwaddr/clientid/hostname in our configuration.
585 Try to return from contexts which match netids first. */
587 struct in_addr start
, addr
;
588 struct dhcp_context
*c
, *d
;
592 /* hash hwaddr: use the SDBM hashing algorithm. Seems to give good
593 dispersal even with similarly-valued "strings". */
594 for (j
= 0, i
= 0; i
< hw_len
; i
++)
595 j
+= hwaddr
[i
] + (j
<< 6) + (j
<< 16) - j
;
597 for (pass
= 0; pass
<= 1; pass
++)
598 for (c
= context
; c
; c
= c
->current
)
599 if (c
->flags
& (CONTEXT_STATIC
| CONTEXT_PROXY
))
601 else if (!match_netid(c
->filter
, netids
, pass
))
605 if (option_bool(OPT_CONSEC_ADDR
))
606 /* seed is largest extant lease addr in this context */
607 start
= lease_find_max_addr(c
);
609 /* pick a seed based on hwaddr */
610 start
.s_addr
= htonl(ntohl(c
->start
.s_addr
) +
611 ((j
+ c
->addr_epoch
) % (1 + ntohl(c
->end
.s_addr
) - ntohl(c
->start
.s_addr
))));
613 /* iterate until we find a free address. */
617 /* eliminate addresses in use by the server. */
618 for (d
= context
; d
; d
= d
->current
)
619 if (addr
.s_addr
== d
->router
.s_addr
)
622 /* Addresses which end in .255 and .0 are broken in Windows even when using
623 supernetting. ie dhcp-range=192.168.0.1,192.168.1.254,255,255,254.0
624 then 192.168.0.255 is a valid IP address, but not for Windows as it's
625 in the class C range. See KB281579. We therefore don't allocate these
626 addresses to avoid hard-to-diagnose problems. Thanks Bill. */
628 !lease_find_by_addr(addr
) &&
629 !config_find_by_address(daemon
->dhcp_conf
, addr
) &&
630 (!IN_CLASSC(ntohl(addr
.s_addr
)) ||
631 ((ntohl(addr
.s_addr
) & 0xff) != 0xff && ((ntohl(addr
.s_addr
) & 0xff) != 0x0))))
633 struct ping_result
*r
, *victim
= NULL
;
634 int count
, max
= (int)(0.6 * (((float)PING_CACHE_TIME
)/
635 ((float)PING_WAIT
)));
639 /* check if we failed to ping addr sometime in the last
640 PING_CACHE_TIME seconds. If so, assume the same situation still exists.
641 This avoids problems when a stupid client bangs
642 on us repeatedly. As a final check, if we did more
643 than 60% of the possible ping checks in the last
644 PING_CACHE_TIME, we are in high-load mode, so don't do any more. */
645 for (count
= 0, r
= daemon
->ping_results
; r
; r
= r
->next
)
646 if (difftime(now
, r
->time
) > (float)PING_CACHE_TIME
)
647 victim
= r
; /* old record */
651 if (r
->addr
.s_addr
== addr
.s_addr
)
653 /* consec-ip mode: we offered this address for another client
654 (different hash) recently, don't offer it to this one. */
655 if (option_bool(OPT_CONSEC_ADDR
) && r
->hash
!= j
)
664 if ((count
< max
) && !option_bool(OPT_NO_PING
) && icmp_ping(addr
))
666 /* address in use: perturb address selection so that we are
667 less likely to try this address again. */
668 if (!option_bool(OPT_CONSEC_ADDR
))
673 /* at this point victim may hold an expired record */
676 if ((victim
= whine_malloc(sizeof(struct ping_result
))))
678 victim
->next
= daemon
->ping_results
;
679 daemon
->ping_results
= victim
;
683 /* record that this address is OK for 30s
684 without more ping checks */
696 addr
.s_addr
= htonl(ntohl(addr
.s_addr
) + 1);
698 if (addr
.s_addr
== htonl(ntohl(c
->end
.s_addr
) + 1))
701 } while (addr
.s_addr
!= start
.s_addr
);
707 static int is_addr_in_context(struct dhcp_context
*context
, struct dhcp_config
*config
)
709 if (!context
) /* called via find_config() from lease_update_from_configs() */
711 if (!(config
->flags
& CONFIG_ADDR
))
713 for (; context
; context
= context
->current
)
714 if (is_same_net(config
->addr
, context
->start
, context
->netmask
))
720 int config_has_mac(struct dhcp_config
*config
, unsigned char *hwaddr
, int len
, int type
)
722 struct hwaddr_config
*conf_addr
;
724 for (conf_addr
= config
->hwaddr
; conf_addr
; conf_addr
= conf_addr
->next
)
725 if (conf_addr
->wildcard_mask
== 0 &&
726 conf_addr
->hwaddr_len
== len
&&
727 (conf_addr
->hwaddr_type
== type
|| conf_addr
->hwaddr_type
== 0) &&
728 memcmp(conf_addr
->hwaddr
, hwaddr
, len
) == 0)
734 struct dhcp_config
*find_config(struct dhcp_config
*configs
,
735 struct dhcp_context
*context
,
736 unsigned char *clid
, int clid_len
,
737 unsigned char *hwaddr
, int hw_len
,
738 int hw_type
, char *hostname
)
741 struct dhcp_config
*config
, *candidate
;
742 struct hwaddr_config
*conf_addr
;
745 for (config
= configs
; config
; config
= config
->next
)
746 if (config
->flags
& CONFIG_CLID
)
748 if (config
->clid_len
== clid_len
&&
749 memcmp(config
->clid
, clid
, clid_len
) == 0 &&
750 is_addr_in_context(context
, config
))
753 /* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and
754 cope with that here */
755 if (*clid
== 0 && config
->clid_len
== clid_len
-1 &&
756 memcmp(config
->clid
, clid
+1, clid_len
-1) == 0 &&
757 is_addr_in_context(context
, config
))
762 for (config
= configs
; config
; config
= config
->next
)
763 if (config_has_mac(config
, hwaddr
, hw_len
, hw_type
) &&
764 is_addr_in_context(context
, config
))
767 if (hostname
&& context
)
768 for (config
= configs
; config
; config
= config
->next
)
769 if ((config
->flags
& CONFIG_NAME
) &&
770 hostname_isequal(config
->hostname
, hostname
) &&
771 is_addr_in_context(context
, config
))
774 /* use match with fewest wildcard octets */
775 for (candidate
= NULL
, count
= 0, config
= configs
; config
; config
= config
->next
)
776 if (is_addr_in_context(context
, config
))
777 for (conf_addr
= config
->hwaddr
; conf_addr
; conf_addr
= conf_addr
->next
)
778 if (conf_addr
->wildcard_mask
!= 0 &&
779 conf_addr
->hwaddr_len
== hw_len
&&
780 (conf_addr
->hwaddr_type
== hw_type
|| conf_addr
->hwaddr_type
== 0) &&
781 (new = memcmp_masked(conf_addr
->hwaddr
, hwaddr
, hw_len
, conf_addr
->wildcard_mask
)) > count
)
790 void dhcp_read_ethers(void)
792 FILE *f
= fopen(ETHERSFILE
, "r");
794 char *buff
= daemon
->namebuff
;
797 unsigned char hwaddr
[ETHER_ADDR_LEN
];
798 struct dhcp_config
**up
, *tmp
;
799 struct dhcp_config
*config
;
800 int count
= 0, lineno
= 0;
802 addr
.s_addr
= 0; /* eliminate warning */
806 my_syslog(MS_DHCP
| LOG_ERR
, _("failed to read %s: %s"), ETHERSFILE
, strerror(errno
));
810 /* This can be called again on SIGHUP, so remove entries created last time round. */
811 for (up
= &daemon
->dhcp_conf
, config
= daemon
->dhcp_conf
; config
; config
= tmp
)
814 if (config
->flags
& CONFIG_FROM_ETHERS
)
817 /* cannot have a clid */
818 if (config
->flags
& CONFIG_NAME
)
819 free(config
->hostname
);
820 free(config
->hwaddr
);
827 while (fgets(buff
, MAXDNAME
, f
))
833 while (strlen(buff
) > 0 && isspace((int)buff
[strlen(buff
)-1]))
834 buff
[strlen(buff
)-1] = 0;
836 if ((*buff
== '#') || (*buff
== '+') || (*buff
== 0))
839 for (ip
= buff
; *ip
&& !isspace((int)*ip
); ip
++);
840 for(; *ip
&& isspace((int)*ip
); ip
++)
842 if (!*ip
|| parse_hex(buff
, hwaddr
, ETHER_ADDR_LEN
, NULL
, NULL
) != ETHER_ADDR_LEN
)
844 my_syslog(MS_DHCP
| LOG_ERR
, _("bad line at %s line %d"), ETHERSFILE
, lineno
);
848 /* check for name or dotted-quad */
849 for (cp
= ip
; *cp
; cp
++)
850 if (!(*cp
== '.' || (*cp
>='0' && *cp
<= '9')))
855 if ((addr
.s_addr
= inet_addr(ip
)) == (in_addr_t
)-1)
857 my_syslog(MS_DHCP
| LOG_ERR
, _("bad address at %s line %d"), ETHERSFILE
, lineno
);
863 for (config
= daemon
->dhcp_conf
; config
; config
= config
->next
)
864 if ((config
->flags
& CONFIG_ADDR
) && config
->addr
.s_addr
== addr
.s_addr
)
870 if (!(host
= canonicalise(ip
, &nomem
)) || !legal_hostname(host
))
873 my_syslog(MS_DHCP
| LOG_ERR
, _("bad name at %s line %d"), ETHERSFILE
, lineno
);
880 for (config
= daemon
->dhcp_conf
; config
; config
= config
->next
)
881 if ((config
->flags
& CONFIG_NAME
) && hostname_isequal(config
->hostname
, host
))
885 if (config
&& (config
->flags
& CONFIG_FROM_ETHERS
))
887 my_syslog(MS_DHCP
| LOG_ERR
, _("ignoring %s line %d, duplicate name or IP address"), ETHERSFILE
, lineno
);
893 for (config
= daemon
->dhcp_conf
; config
; config
= config
->next
)
895 struct hwaddr_config
*conf_addr
= config
->hwaddr
;
897 conf_addr
->next
== NULL
&&
898 conf_addr
->wildcard_mask
== 0 &&
899 conf_addr
->hwaddr_len
== ETHER_ADDR_LEN
&&
900 (conf_addr
->hwaddr_type
== ARPHRD_ETHER
|| conf_addr
->hwaddr_type
== 0) &&
901 memcmp(conf_addr
->hwaddr
, hwaddr
, ETHER_ADDR_LEN
) == 0)
907 if (!(config
= whine_malloc(sizeof(struct dhcp_config
))))
909 config
->flags
= CONFIG_FROM_ETHERS
;
910 config
->hwaddr
= NULL
;
911 config
->domain
= NULL
;
912 config
->netid
= NULL
;
913 config
->next
= daemon
->dhcp_conf
;
914 daemon
->dhcp_conf
= config
;
917 config
->flags
|= flags
;
919 if (flags
& CONFIG_NAME
)
921 config
->hostname
= host
;
925 if (flags
& CONFIG_ADDR
)
929 config
->flags
|= CONFIG_NOCLID
;
931 config
->hwaddr
= whine_malloc(sizeof(struct hwaddr_config
));
934 memcpy(config
->hwaddr
->hwaddr
, hwaddr
, ETHER_ADDR_LEN
);
935 config
->hwaddr
->hwaddr_len
= ETHER_ADDR_LEN
;
936 config
->hwaddr
->hwaddr_type
= ARPHRD_ETHER
;
937 config
->hwaddr
->wildcard_mask
= 0;
938 config
->hwaddr
->next
= NULL
;
948 my_syslog(MS_DHCP
| LOG_INFO
, _("read %s - %d addresses"), ETHERSFILE
, count
);
952 /* If we've not found a hostname any other way, try and see if there's one in /etc/hosts
953 for this address. If it has a domain part, that must match the set domain and
954 it gets stripped. The set of legal domain names is bigger than the set of legal hostnames
955 so check here that the domain name is legal as a hostname.
956 NOTE: we're only allowed to overwrite daemon->dhcp_buff if we succeed. */
957 char *host_from_dns(struct in_addr addr
)
961 if (daemon
->port
== 0)
962 return NULL
; /* DNS disabled. */
964 lookup
= cache_find_by_addr(NULL
, (struct all_addr
*)&addr
, 0, F_IPV4
);
966 if (lookup
&& (lookup
->flags
& F_HOSTS
))
968 char *dot
, *hostname
= cache_get_name(lookup
);
969 dot
= strchr(hostname
, '.');
971 if (dot
&& strlen(dot
+1) != 0)
973 char *d2
= get_domain(addr
);
974 if (!d2
|| !hostname_isequal(dot
+1, d2
))
975 return NULL
; /* wrong domain */
978 if (!legal_hostname(hostname
))
981 strncpy(daemon
->dhcp_buff
, hostname
, 256);
982 daemon
->dhcp_buff
[255] = 0;
983 strip_hostname(daemon
->dhcp_buff
);
985 return daemon
->dhcp_buff
;