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
;
23 struct dhcp_relay
*relay
;
24 struct in_addr relay_local
;
30 struct in_addr netmask
, broadcast
, addr
;
33 static int complete_context(struct in_addr local
, int if_index
, char *label
,
34 struct in_addr netmask
, struct in_addr broadcast
, void *vparam
);
35 static int check_listen_addrs(struct in_addr local
, int if_index
, char *label
,
36 struct in_addr netmask
, struct in_addr broadcast
, void *vparam
);
37 static int relay_upstream4(struct dhcp_relay
*relay
, struct dhcp_packet
*mess
, size_t sz
, int iface_index
);
38 static struct dhcp_relay
*relay_reply4(struct dhcp_packet
*mess
, char *arrival_interface
);
40 static int make_fd(int port
)
42 int fd
= socket(PF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
43 struct sockaddr_in saddr
;
45 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
46 int mtu
= IP_PMTUDISC_DONT
;
48 #if defined(IP_TOS) && defined(IPTOS_CLASS_CS6)
49 int tos
= IPTOS_CLASS_CS6
;
53 die (_("cannot create DHCP socket: %s"), NULL
, EC_BADNET
);
56 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
57 setsockopt(fd
, IPPROTO_IP
, IP_MTU_DISCOVER
, &mtu
, sizeof(mtu
)) == -1 ||
59 #if defined(IP_TOS) && defined(IPTOS_CLASS_CS6)
60 setsockopt(fd
, IPPROTO_IP
, IP_TOS
, &tos
, sizeof(tos
)) == -1 ||
62 #if defined(HAVE_LINUX_NETWORK)
63 setsockopt(fd
, IPPROTO_IP
, IP_PKTINFO
, &oneopt
, sizeof(oneopt
)) == -1 ||
65 setsockopt(fd
, IPPROTO_IP
, IP_RECVIF
, &oneopt
, sizeof(oneopt
)) == -1 ||
67 setsockopt(fd
, SOL_SOCKET
, SO_BROADCAST
, &oneopt
, sizeof(oneopt
)) == -1)
68 die(_("failed to set options on DHCP socket: %s"), NULL
, EC_BADNET
);
70 /* When bind-interfaces is set, there might be more than one dnmsasq
71 instance binding port 67. That's OK if they serve different networks.
72 Need to set REUSEADDR|REUSEPORT to make this posible.
73 Handle the case that REUSEPORT is defined, but the kernel doesn't
74 support it. This handles the introduction of REUSEPORT on Linux. */
75 if (option_bool(OPT_NOWILD
) || option_bool(OPT_CLEVERBIND
))
80 if ((rc
= setsockopt(fd
, SOL_SOCKET
, SO_REUSEPORT
, &oneopt
, sizeof(oneopt
))) == -1 &&
86 rc
= setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &oneopt
, sizeof(oneopt
));
89 die(_("failed to set SO_REUSE{ADDR|PORT} on DHCP socket: %s"), NULL
, EC_BADNET
);
92 memset(&saddr
, 0, sizeof(saddr
));
93 saddr
.sin_family
= AF_INET
;
94 saddr
.sin_port
= htons(port
);
95 saddr
.sin_addr
.s_addr
= INADDR_ANY
;
96 #ifdef HAVE_SOCKADDR_SA_LEN
97 saddr
.sin_len
= sizeof(struct sockaddr_in
);
100 if (bind(fd
, (struct sockaddr
*)&saddr
, sizeof(struct sockaddr_in
)))
101 die(_("failed to bind DHCP server socket: %s"), NULL
, EC_BADNET
);
108 #if defined(HAVE_BSD_NETWORK)
112 daemon
->dhcpfd
= make_fd(daemon
->dhcp_server_port
);
113 if (daemon
->enable_pxe
)
114 daemon
->pxefd
= make_fd(PXE_PORT
);
118 #if defined(HAVE_BSD_NETWORK)
119 /* When we're not using capabilities, we need to do this here before
120 we drop root. Also, set buffer size small, to avoid wasting
123 if (option_bool(OPT_NO_PING
))
124 daemon
->dhcp_icmp_fd
= -1;
125 else if ((daemon
->dhcp_icmp_fd
= make_icmp_sock()) == -1 ||
126 setsockopt(daemon
->dhcp_icmp_fd
, SOL_SOCKET
, SO_RCVBUF
, &oneopt
, sizeof(oneopt
)) == -1 )
127 die(_("cannot create ICMP raw socket: %s."), NULL
, EC_BADNET
);
129 /* Make BPF raw send socket */
134 void dhcp_packet(time_t now
, int pxe_fd
)
136 int fd
= pxe_fd
? daemon
->pxefd
: daemon
->dhcpfd
;
137 struct dhcp_packet
*mess
;
138 struct dhcp_context
*context
;
139 struct dhcp_relay
*relay
;
140 int is_relay_reply
= 0;
144 struct sockaddr_in dest
;
145 struct cmsghdr
*cmptr
;
148 int iface_index
= 0, unicast_dest
= 0, is_inform
= 0;
149 struct in_addr iface_addr
;
150 struct iface_param parm
;
151 #ifdef HAVE_LINUX_NETWORK
152 struct arpreq arp_req
;
156 struct cmsghdr align
; /* this ensures alignment */
157 #if defined(HAVE_LINUX_NETWORK)
158 char control
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
159 #elif defined(HAVE_SOLARIS_NETWORK)
160 char control
[CMSG_SPACE(sizeof(unsigned int))];
161 #elif defined(HAVE_BSD_NETWORK)
162 char control
[CMSG_SPACE(sizeof(struct sockaddr_dl
))];
165 struct dhcp_bridge
*bridge
, *alias
;
167 msg
.msg_controllen
= sizeof(control_u
);
168 msg
.msg_control
= control_u
.control
;
169 msg
.msg_name
= &dest
;
170 msg
.msg_namelen
= sizeof(dest
);
171 msg
.msg_iov
= &daemon
->dhcp_packet
;
174 if ((sz
= recv_dhcp_packet(fd
, &msg
)) == -1 ||
175 (sz
< (ssize_t
)(sizeof(*mess
) - sizeof(mess
->options
))))
178 #if defined (HAVE_LINUX_NETWORK)
179 if (msg
.msg_controllen
>= sizeof(struct cmsghdr
))
180 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
181 if (cmptr
->cmsg_level
== IPPROTO_IP
&& cmptr
->cmsg_type
== IP_PKTINFO
)
185 struct in_pktinfo
*p
;
187 p
.c
= CMSG_DATA(cmptr
);
188 iface_index
= p
.p
->ipi_ifindex
;
189 if (p
.p
->ipi_addr
.s_addr
!= INADDR_BROADCAST
)
193 #elif defined(HAVE_BSD_NETWORK)
194 if (msg
.msg_controllen
>= sizeof(struct cmsghdr
))
195 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
196 if (cmptr
->cmsg_level
== IPPROTO_IP
&& cmptr
->cmsg_type
== IP_RECVIF
)
200 struct sockaddr_dl
*s
;
202 p
.c
= CMSG_DATA(cmptr
);
203 iface_index
= p
.s
->sdl_index
;
206 #elif defined(HAVE_SOLARIS_NETWORK)
207 if (msg
.msg_controllen
>= sizeof(struct cmsghdr
))
208 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
209 if (cmptr
->cmsg_level
== IPPROTO_IP
&& cmptr
->cmsg_type
== IP_RECVIF
)
215 p
.c
= CMSG_DATA(cmptr
);
216 iface_index
= *(p
.i
);
220 if (!indextoname(daemon
->dhcpfd
, iface_index
, ifr
.ifr_name
))
223 #ifdef HAVE_LINUX_NETWORK
224 /* ARP fiddling uses original interface even if we pretend to use a different one. */
225 strncpy(arp_req
.arp_dev
, ifr
.ifr_name
, 16);
228 /* One form of bridging on BSD has the property that packets
229 can be recieved on bridge interfaces which do not have an IP address.
230 We allow these to be treated as aliases of another interface which does have
231 an IP address with --dhcp-bridge=interface,alias,alias */
232 for (bridge
= daemon
->bridges
; bridge
; bridge
= bridge
->next
)
234 for (alias
= bridge
->alias
; alias
; alias
= alias
->next
)
235 if (strncmp(ifr
.ifr_name
, alias
->iface
, IF_NAMESIZE
) == 0)
237 if (!(iface_index
= if_nametoindex(bridge
->iface
)))
239 my_syslog(LOG_WARNING
, _("unknown interface %s in bridge-interface"), ifr
.ifr_name
);
244 strncpy(ifr
.ifr_name
, bridge
->iface
, IF_NAMESIZE
);
254 /* OpenBSD tells us when a packet was broadcast */
255 if (!(msg
.msg_flags
& MSG_BCAST
))
259 if ((relay
= relay_reply4((struct dhcp_packet
*)daemon
->dhcp_packet
.iov_base
, ifr
.ifr_name
)))
261 /* Reply from server, using us as relay. */
262 iface_index
= relay
->iface_index
;
263 if (!indextoname(daemon
->dhcpfd
, iface_index
, ifr
.ifr_name
))
267 #ifdef HAVE_LINUX_NETWORK
268 strncpy(arp_req
.arp_dev
, ifr
.ifr_name
, 16);
273 ifr
.ifr_addr
.sa_family
= AF_INET
;
274 if (ioctl(daemon
->dhcpfd
, SIOCGIFADDR
, &ifr
) != -1 )
275 iface_addr
= ((struct sockaddr_in
*) &ifr
.ifr_addr
)->sin_addr
;
278 my_syslog(MS_DHCP
| LOG_WARNING
, _("DHCP packet received on %s which has no address"), ifr
.ifr_name
);
282 for (tmp
= daemon
->dhcp_except
; tmp
; tmp
= tmp
->next
)
283 if (tmp
->name
&& wildcard_match(tmp
->name
, ifr
.ifr_name
))
286 /* unlinked contexts/relays are marked by context->current == context */
287 for (context
= daemon
->dhcp
; context
; context
= context
->next
)
288 context
->current
= context
;
290 for (relay
= daemon
->relay4
; relay
; relay
= relay
->next
)
291 relay
->current
= relay
;
295 parm
.relay_local
.s_addr
= 0;
296 parm
.ind
= iface_index
;
298 if (!iface_check(AF_INET
, (struct all_addr
*)&iface_addr
, ifr
.ifr_name
, NULL
))
300 /* If we failed to match the primary address of the interface, see if we've got a --listen-address
302 struct match_param match
;
305 match
.ind
= iface_index
;
307 if (!daemon
->if_addrs
||
308 !iface_enumerate(AF_INET
, &match
, check_listen_addrs
) ||
312 iface_addr
= match
.addr
;
313 /* make sure secondary address gets priority in case
314 there is more than one address on the interface in the same subnet */
315 complete_context(match
.addr
, iface_index
, NULL
, match
.netmask
, match
.broadcast
, &parm
);
318 if (!iface_enumerate(AF_INET
, &parm
, complete_context
))
321 /* We're relaying this request */
322 if (parm
.relay_local
.s_addr
!= 0 &&
323 relay_upstream4(parm
.relay
, (struct dhcp_packet
*)daemon
->dhcp_packet
.iov_base
, (size_t)sz
, iface_index
))
326 /* May have configured relay, but not DHCP server */
330 lease_prune(NULL
, now
); /* lose any expired leases */
331 iov
.iov_len
= dhcp_reply(parm
.current
, ifr
.ifr_name
, iface_index
, (size_t)sz
,
332 now
, unicast_dest
, &is_inform
, pxe_fd
, iface_addr
);
333 lease_update_file(now
);
336 if (iov
.iov_len
== 0)
340 msg
.msg_name
= &dest
;
341 msg
.msg_namelen
= sizeof(dest
);
342 msg
.msg_control
= NULL
;
343 msg
.msg_controllen
= 0;
345 iov
.iov_base
= daemon
->dhcp_packet
.iov_base
;
347 /* packet buffer may have moved */
348 mess
= (struct dhcp_packet
*)daemon
->dhcp_packet
.iov_base
;
350 #ifdef HAVE_SOCKADDR_SA_LEN
351 dest
.sin_len
= sizeof(struct sockaddr_in
);
356 if (mess
->ciaddr
.s_addr
!= 0)
357 dest
.sin_addr
= mess
->ciaddr
;
359 else if (mess
->giaddr
.s_addr
&& !is_relay_reply
)
361 /* Send to BOOTP relay */
362 dest
.sin_port
= htons(daemon
->dhcp_server_port
);
363 dest
.sin_addr
= mess
->giaddr
;
365 else if (mess
->ciaddr
.s_addr
)
367 /* If the client's idea of its own address tallys with
368 the source address in the request packet, we believe the
369 source port too, and send back to that. If we're replying
370 to a DHCPINFORM, trust the source address always. */
371 if ((!is_inform
&& dest
.sin_addr
.s_addr
!= mess
->ciaddr
.s_addr
) ||
372 dest
.sin_port
== 0 || dest
.sin_addr
.s_addr
== 0 || is_relay_reply
)
374 dest
.sin_port
= htons(daemon
->dhcp_client_port
);
375 dest
.sin_addr
= mess
->ciaddr
;
378 #if defined(HAVE_LINUX_NETWORK)
379 else if ((ntohs(mess
->flags
) & 0x8000) || mess
->hlen
== 0 ||
380 mess
->hlen
> sizeof(ifr
.ifr_addr
.sa_data
) || mess
->htype
== 0)
382 /* broadcast to 255.255.255.255 (or mac address invalid) */
383 struct in_pktinfo
*pkt
;
384 msg
.msg_control
= control_u
.control
;
385 msg
.msg_controllen
= sizeof(control_u
);
386 cmptr
= CMSG_FIRSTHDR(&msg
);
387 pkt
= (struct in_pktinfo
*)CMSG_DATA(cmptr
);
388 pkt
->ipi_ifindex
= iface_index
;
389 pkt
->ipi_spec_dst
.s_addr
= 0;
390 msg
.msg_controllen
= cmptr
->cmsg_len
= CMSG_LEN(sizeof(struct in_pktinfo
));
391 cmptr
->cmsg_level
= IPPROTO_IP
;
392 cmptr
->cmsg_type
= IP_PKTINFO
;
393 dest
.sin_addr
.s_addr
= INADDR_BROADCAST
;
394 dest
.sin_port
= htons(daemon
->dhcp_client_port
);
398 /* unicast to unconfigured client. Inject mac address direct into ARP cache.
399 struct sockaddr limits size to 14 bytes. */
400 dest
.sin_addr
= mess
->yiaddr
;
401 dest
.sin_port
= htons(daemon
->dhcp_client_port
);
402 memcpy(&arp_req
.arp_pa
, &dest
, sizeof(struct sockaddr_in
));
403 arp_req
.arp_ha
.sa_family
= mess
->htype
;
404 memcpy(arp_req
.arp_ha
.sa_data
, mess
->chaddr
, mess
->hlen
);
405 /* interface name already copied in */
406 arp_req
.arp_flags
= ATF_COM
;
407 ioctl(daemon
->dhcpfd
, SIOCSARP
, &arp_req
);
409 #elif defined(HAVE_SOLARIS_NETWORK)
410 else if ((ntohs(mess
->flags
) & 0x8000) || mess
->hlen
!= ETHER_ADDR_LEN
|| mess
->htype
!= ARPHRD_ETHER
)
412 /* broadcast to 255.255.255.255 (or mac address invalid) */
413 dest
.sin_addr
.s_addr
= INADDR_BROADCAST
;
414 dest
.sin_port
= htons(daemon
->dhcp_client_port
);
415 /* note that we don't specify the interface here: that's done by the
416 IP_BOUND_IF sockopt lower down. */
420 /* unicast to unconfigured client. Inject mac address direct into ARP cache.
421 Note that this only works for ethernet on solaris, because we use SIOCSARP
422 and not SIOCSXARP, which would be perfect, except that it returns ENXIO
423 mysteriously. Bah. Fall back to broadcast for other net types. */
425 dest
.sin_addr
= mess
->yiaddr
;
426 dest
.sin_port
= htons(daemon
->dhcp_client_port
);
427 *((struct sockaddr_in
*)&req
.arp_pa
) = dest
;
428 req
.arp_ha
.sa_family
= AF_UNSPEC
;
429 memcpy(req
.arp_ha
.sa_data
, mess
->chaddr
, mess
->hlen
);
430 req
.arp_flags
= ATF_COM
;
431 ioctl(daemon
->dhcpfd
, SIOCSARP
, &req
);
433 #elif defined(HAVE_BSD_NETWORK)
436 send_via_bpf(mess
, iov
.iov_len
, iface_addr
, &ifr
);
441 #ifdef HAVE_SOLARIS_NETWORK
442 setsockopt(fd
, IPPROTO_IP
, IP_BOUND_IF
, &iface_index
, sizeof(iface_index
));
445 while(sendmsg(fd
, &msg
, 0) == -1 && retry_send());
448 /* check against secondary interface addresses */
449 static int check_listen_addrs(struct in_addr local
, int if_index
, char *label
,
450 struct in_addr netmask
, struct in_addr broadcast
, void *vparam
)
452 struct match_param
*param
= vparam
;
457 if (if_index
== param
->ind
)
459 for (tmp
= daemon
->if_addrs
; tmp
; tmp
= tmp
->next
)
460 if ( tmp
->addr
.sa
.sa_family
== AF_INET
&&
461 tmp
->addr
.in
.sin_addr
.s_addr
== local
.s_addr
)
465 param
->netmask
= netmask
;
466 param
->broadcast
= broadcast
;
474 /* This is a complex routine: it gets called with each (address,netmask,broadcast) triple
475 of each interface (and any relay address) and does the following things:
477 1) Discards stuff for interfaces other than the one on which a DHCP packet just arrived.
478 2) Fills in any netmask and broadcast addresses which have not been explicitly configured.
479 3) Fills in local (this host) and router (this host or relay) addresses.
480 4) Links contexts which are valid for hosts directly connected to the arrival interface on ->current.
482 Note that the current chain may be superceded later for configured hosts or those coming via gateways. */
484 static int complete_context(struct in_addr local
, int if_index
, char *label
,
485 struct in_addr netmask
, struct in_addr broadcast
, void *vparam
)
487 struct dhcp_context
*context
;
488 struct dhcp_relay
*relay
;
489 struct iface_param
*param
= vparam
;
493 for (context
= daemon
->dhcp
; context
; context
= context
->next
)
495 if (!(context
->flags
& CONTEXT_NETMASK
) &&
496 (is_same_net(local
, context
->start
, netmask
) ||
497 is_same_net(local
, context
->end
, netmask
)))
499 if (context
->netmask
.s_addr
!= netmask
.s_addr
&&
500 !(is_same_net(local
, context
->start
, netmask
) &&
501 is_same_net(local
, context
->end
, netmask
)))
503 strcpy(daemon
->dhcp_buff
, inet_ntoa(context
->start
));
504 strcpy(daemon
->dhcp_buff2
, inet_ntoa(context
->end
));
505 my_syslog(MS_DHCP
| LOG_WARNING
, _("DHCP range %s -- %s is not consistent with netmask %s"),
506 daemon
->dhcp_buff
, daemon
->dhcp_buff2
, inet_ntoa(netmask
));
508 context
->netmask
= netmask
;
511 if (context
->netmask
.s_addr
!= 0 &&
512 is_same_net(local
, context
->start
, context
->netmask
) &&
513 is_same_net(local
, context
->end
, context
->netmask
))
515 /* link it onto the current chain if we've not seen it before */
516 if (if_index
== param
->ind
&& context
->current
== context
)
518 context
->router
= local
;
519 context
->local
= local
;
520 context
->current
= param
->current
;
521 param
->current
= context
;
524 if (!(context
->flags
& CONTEXT_BRDCAST
))
526 if (is_same_net(broadcast
, context
->start
, context
->netmask
))
527 context
->broadcast
= broadcast
;
529 context
->broadcast
.s_addr
= context
->start
.s_addr
| ~context
->netmask
.s_addr
;
534 for (relay
= daemon
->relay4
; relay
; relay
= relay
->next
)
535 if (if_index
== param
->ind
&& relay
->local
.addr
.addr4
.s_addr
== local
.s_addr
&& relay
->current
== relay
&&
536 (param
->relay_local
.s_addr
== 0 || param
->relay_local
.s_addr
== local
.s_addr
))
538 relay
->current
= param
->relay
;
539 param
->relay
= relay
;
540 param
->relay_local
= local
;
546 struct dhcp_context
*address_available(struct dhcp_context
*context
,
547 struct in_addr taddr
,
548 struct dhcp_netid
*netids
)
550 /* Check is an address is OK for this network, check all
551 possible ranges. Make sure that the address isn't in use
552 by the server itself. */
554 unsigned int start
, end
, addr
= ntohl(taddr
.s_addr
);
555 struct dhcp_context
*tmp
;
557 for (tmp
= context
; tmp
; tmp
= tmp
->current
)
558 if (taddr
.s_addr
== context
->router
.s_addr
)
561 for (tmp
= context
; tmp
; tmp
= tmp
->current
)
563 start
= ntohl(tmp
->start
.s_addr
);
564 end
= ntohl(tmp
->end
.s_addr
);
566 if (!(tmp
->flags
& (CONTEXT_STATIC
| CONTEXT_PROXY
)) &&
569 match_netid(tmp
->filter
, netids
, 1))
576 struct dhcp_context
*narrow_context(struct dhcp_context
*context
,
577 struct in_addr taddr
,
578 struct dhcp_netid
*netids
)
580 /* We start of with a set of possible contexts, all on the current physical interface.
581 These are chained on ->current.
582 Here we have an address, and return the actual context correponding to that
583 address. Note that none may fit, if the address came a dhcp-host and is outside
584 any dhcp-range. In that case we return a static range if possible, or failing that,
585 any context on the correct subnet. (If there's more than one, this is a dodgy
586 configuration: maybe there should be a warning.) */
588 struct dhcp_context
*tmp
;
590 if (!(tmp
= address_available(context
, taddr
, netids
)))
592 for (tmp
= context
; tmp
; tmp
= tmp
->current
)
593 if (match_netid(tmp
->filter
, netids
, 1) &&
594 is_same_net(taddr
, tmp
->start
, tmp
->netmask
) &&
595 (tmp
->flags
& CONTEXT_STATIC
))
599 for (tmp
= context
; tmp
; tmp
= tmp
->current
)
600 if (match_netid(tmp
->filter
, netids
, 1) &&
601 is_same_net(taddr
, tmp
->start
, tmp
->netmask
) &&
602 !(tmp
->flags
& CONTEXT_PROXY
))
606 /* Only one context allowed now */
613 struct dhcp_config
*config_find_by_address(struct dhcp_config
*configs
, struct in_addr addr
)
615 struct dhcp_config
*config
;
617 for (config
= configs
; config
; config
= config
->next
)
618 if ((config
->flags
& CONFIG_ADDR
) && config
->addr
.s_addr
== addr
.s_addr
)
624 int address_allocate(struct dhcp_context
*context
,
625 struct in_addr
*addrp
, unsigned char *hwaddr
, int hw_len
,
626 struct dhcp_netid
*netids
, time_t now
)
628 /* Find a free address: exclude anything in use and anything allocated to
629 a particular hwaddr/clientid/hostname in our configuration.
630 Try to return from contexts which match netids first. */
632 struct in_addr start
, addr
;
633 struct dhcp_context
*c
, *d
;
637 /* hash hwaddr: use the SDBM hashing algorithm. Seems to give good
638 dispersal even with similarly-valued "strings". */
639 for (j
= 0, i
= 0; i
< hw_len
; i
++)
640 j
+= hwaddr
[i
] + (j
<< 6) + (j
<< 16) - j
;
642 for (pass
= 0; pass
<= 1; pass
++)
643 for (c
= context
; c
; c
= c
->current
)
644 if (c
->flags
& (CONTEXT_STATIC
| CONTEXT_PROXY
))
646 else if (!match_netid(c
->filter
, netids
, pass
))
650 if (option_bool(OPT_CONSEC_ADDR
))
651 /* seed is largest extant lease addr in this context */
652 start
= lease_find_max_addr(c
);
654 /* pick a seed based on hwaddr */
655 start
.s_addr
= htonl(ntohl(c
->start
.s_addr
) +
656 ((j
+ c
->addr_epoch
) % (1 + ntohl(c
->end
.s_addr
) - ntohl(c
->start
.s_addr
))));
658 /* iterate until we find a free address. */
662 /* eliminate addresses in use by the server. */
663 for (d
= context
; d
; d
= d
->current
)
664 if (addr
.s_addr
== d
->router
.s_addr
)
667 /* Addresses which end in .255 and .0 are broken in Windows even when using
668 supernetting. ie dhcp-range=192.168.0.1,192.168.1.254,255,255,254.0
669 then 192.168.0.255 is a valid IP address, but not for Windows as it's
670 in the class C range. See KB281579. We therefore don't allocate these
671 addresses to avoid hard-to-diagnose problems. Thanks Bill. */
673 !lease_find_by_addr(addr
) &&
674 !config_find_by_address(daemon
->dhcp_conf
, addr
) &&
675 (!IN_CLASSC(ntohl(addr
.s_addr
)) ||
676 ((ntohl(addr
.s_addr
) & 0xff) != 0xff && ((ntohl(addr
.s_addr
) & 0xff) != 0x0))))
678 struct ping_result
*r
, *victim
= NULL
;
679 int count
, max
= (int)(0.6 * (((float)PING_CACHE_TIME
)/
680 ((float)PING_WAIT
)));
684 /* check if we failed to ping addr sometime in the last
685 PING_CACHE_TIME seconds. If so, assume the same situation still exists.
686 This avoids problems when a stupid client bangs
687 on us repeatedly. As a final check, if we did more
688 than 60% of the possible ping checks in the last
689 PING_CACHE_TIME, we are in high-load mode, so don't do any more. */
690 for (count
= 0, r
= daemon
->ping_results
; r
; r
= r
->next
)
691 if (difftime(now
, r
->time
) > (float)PING_CACHE_TIME
)
692 victim
= r
; /* old record */
696 if (r
->addr
.s_addr
== addr
.s_addr
)
698 /* consec-ip mode: we offered this address for another client
699 (different hash) recently, don't offer it to this one. */
700 if (option_bool(OPT_CONSEC_ADDR
) && r
->hash
!= j
)
709 if ((count
< max
) && !option_bool(OPT_NO_PING
) && icmp_ping(addr
))
711 /* address in use: perturb address selection so that we are
712 less likely to try this address again. */
713 if (!option_bool(OPT_CONSEC_ADDR
))
718 /* at this point victim may hold an expired record */
721 if ((victim
= whine_malloc(sizeof(struct ping_result
))))
723 victim
->next
= daemon
->ping_results
;
724 daemon
->ping_results
= victim
;
728 /* record that this address is OK for 30s
729 without more ping checks */
741 addr
.s_addr
= htonl(ntohl(addr
.s_addr
) + 1);
743 if (addr
.s_addr
== htonl(ntohl(c
->end
.s_addr
) + 1))
746 } while (addr
.s_addr
!= start
.s_addr
);
752 static int is_addr_in_context(struct dhcp_context
*context
, struct dhcp_config
*config
)
754 if (!context
) /* called via find_config() from lease_update_from_configs() */
756 if (!(config
->flags
& CONFIG_ADDR
))
758 for (; context
; context
= context
->current
)
759 if (is_same_net(config
->addr
, context
->start
, context
->netmask
))
765 int config_has_mac(struct dhcp_config
*config
, unsigned char *hwaddr
, int len
, int type
)
767 struct hwaddr_config
*conf_addr
;
769 for (conf_addr
= config
->hwaddr
; conf_addr
; conf_addr
= conf_addr
->next
)
770 if (conf_addr
->wildcard_mask
== 0 &&
771 conf_addr
->hwaddr_len
== len
&&
772 (conf_addr
->hwaddr_type
== type
|| conf_addr
->hwaddr_type
== 0) &&
773 memcmp(conf_addr
->hwaddr
, hwaddr
, len
) == 0)
779 struct dhcp_config
*find_config(struct dhcp_config
*configs
,
780 struct dhcp_context
*context
,
781 unsigned char *clid
, int clid_len
,
782 unsigned char *hwaddr
, int hw_len
,
783 int hw_type
, char *hostname
)
786 struct dhcp_config
*config
, *candidate
;
787 struct hwaddr_config
*conf_addr
;
790 for (config
= configs
; config
; config
= config
->next
)
791 if (config
->flags
& CONFIG_CLID
)
793 if (config
->clid_len
== clid_len
&&
794 memcmp(config
->clid
, clid
, clid_len
) == 0 &&
795 is_addr_in_context(context
, config
))
798 /* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and
799 cope with that here */
800 if (*clid
== 0 && config
->clid_len
== clid_len
-1 &&
801 memcmp(config
->clid
, clid
+1, clid_len
-1) == 0 &&
802 is_addr_in_context(context
, config
))
807 for (config
= configs
; config
; config
= config
->next
)
808 if (config_has_mac(config
, hwaddr
, hw_len
, hw_type
) &&
809 is_addr_in_context(context
, config
))
812 if (hostname
&& context
)
813 for (config
= configs
; config
; config
= config
->next
)
814 if ((config
->flags
& CONFIG_NAME
) &&
815 hostname_isequal(config
->hostname
, hostname
) &&
816 is_addr_in_context(context
, config
))
819 /* use match with fewest wildcard octets */
820 for (candidate
= NULL
, count
= 0, config
= configs
; config
; config
= config
->next
)
821 if (is_addr_in_context(context
, config
))
822 for (conf_addr
= config
->hwaddr
; conf_addr
; conf_addr
= conf_addr
->next
)
823 if (conf_addr
->wildcard_mask
!= 0 &&
824 conf_addr
->hwaddr_len
== hw_len
&&
825 (conf_addr
->hwaddr_type
== hw_type
|| conf_addr
->hwaddr_type
== 0) &&
826 (new = memcmp_masked(conf_addr
->hwaddr
, hwaddr
, hw_len
, conf_addr
->wildcard_mask
)) > count
)
835 void dhcp_read_ethers(void)
837 FILE *f
= fopen(ETHERSFILE
, "r");
839 char *buff
= daemon
->namebuff
;
842 unsigned char hwaddr
[ETHER_ADDR_LEN
];
843 struct dhcp_config
**up
, *tmp
;
844 struct dhcp_config
*config
;
845 int count
= 0, lineno
= 0;
847 addr
.s_addr
= 0; /* eliminate warning */
851 my_syslog(MS_DHCP
| LOG_ERR
, _("failed to read %s: %s"), ETHERSFILE
, strerror(errno
));
855 /* This can be called again on SIGHUP, so remove entries created last time round. */
856 for (up
= &daemon
->dhcp_conf
, config
= daemon
->dhcp_conf
; config
; config
= tmp
)
859 if (config
->flags
& CONFIG_FROM_ETHERS
)
862 /* cannot have a clid */
863 if (config
->flags
& CONFIG_NAME
)
864 free(config
->hostname
);
865 free(config
->hwaddr
);
872 while (fgets(buff
, MAXDNAME
, f
))
878 while (strlen(buff
) > 0 && isspace((int)buff
[strlen(buff
)-1]))
879 buff
[strlen(buff
)-1] = 0;
881 if ((*buff
== '#') || (*buff
== '+') || (*buff
== 0))
884 for (ip
= buff
; *ip
&& !isspace((int)*ip
); ip
++);
885 for(; *ip
&& isspace((int)*ip
); ip
++)
887 if (!*ip
|| parse_hex(buff
, hwaddr
, ETHER_ADDR_LEN
, NULL
, NULL
) != ETHER_ADDR_LEN
)
889 my_syslog(MS_DHCP
| LOG_ERR
, _("bad line at %s line %d"), ETHERSFILE
, lineno
);
893 /* check for name or dotted-quad */
894 for (cp
= ip
; *cp
; cp
++)
895 if (!(*cp
== '.' || (*cp
>='0' && *cp
<= '9')))
900 if ((addr
.s_addr
= inet_addr(ip
)) == (in_addr_t
)-1)
902 my_syslog(MS_DHCP
| LOG_ERR
, _("bad address at %s line %d"), ETHERSFILE
, lineno
);
908 for (config
= daemon
->dhcp_conf
; config
; config
= config
->next
)
909 if ((config
->flags
& CONFIG_ADDR
) && config
->addr
.s_addr
== addr
.s_addr
)
915 if (!(host
= canonicalise(ip
, &nomem
)) || !legal_hostname(host
))
918 my_syslog(MS_DHCP
| LOG_ERR
, _("bad name at %s line %d"), ETHERSFILE
, lineno
);
925 for (config
= daemon
->dhcp_conf
; config
; config
= config
->next
)
926 if ((config
->flags
& CONFIG_NAME
) && hostname_isequal(config
->hostname
, host
))
930 if (config
&& (config
->flags
& CONFIG_FROM_ETHERS
))
932 my_syslog(MS_DHCP
| LOG_ERR
, _("ignoring %s line %d, duplicate name or IP address"), ETHERSFILE
, lineno
);
938 for (config
= daemon
->dhcp_conf
; config
; config
= config
->next
)
940 struct hwaddr_config
*conf_addr
= config
->hwaddr
;
942 conf_addr
->next
== NULL
&&
943 conf_addr
->wildcard_mask
== 0 &&
944 conf_addr
->hwaddr_len
== ETHER_ADDR_LEN
&&
945 (conf_addr
->hwaddr_type
== ARPHRD_ETHER
|| conf_addr
->hwaddr_type
== 0) &&
946 memcmp(conf_addr
->hwaddr
, hwaddr
, ETHER_ADDR_LEN
) == 0)
952 if (!(config
= whine_malloc(sizeof(struct dhcp_config
))))
954 config
->flags
= CONFIG_FROM_ETHERS
;
955 config
->hwaddr
= NULL
;
956 config
->domain
= NULL
;
957 config
->netid
= NULL
;
958 config
->next
= daemon
->dhcp_conf
;
959 daemon
->dhcp_conf
= config
;
962 config
->flags
|= flags
;
964 if (flags
& CONFIG_NAME
)
966 config
->hostname
= host
;
970 if (flags
& CONFIG_ADDR
)
974 config
->flags
|= CONFIG_NOCLID
;
976 config
->hwaddr
= whine_malloc(sizeof(struct hwaddr_config
));
979 memcpy(config
->hwaddr
->hwaddr
, hwaddr
, ETHER_ADDR_LEN
);
980 config
->hwaddr
->hwaddr_len
= ETHER_ADDR_LEN
;
981 config
->hwaddr
->hwaddr_type
= ARPHRD_ETHER
;
982 config
->hwaddr
->wildcard_mask
= 0;
983 config
->hwaddr
->next
= NULL
;
993 my_syslog(MS_DHCP
| LOG_INFO
, _("read %s - %d addresses"), ETHERSFILE
, count
);
997 /* If we've not found a hostname any other way, try and see if there's one in /etc/hosts
998 for this address. If it has a domain part, that must match the set domain and
999 it gets stripped. The set of legal domain names is bigger than the set of legal hostnames
1000 so check here that the domain name is legal as a hostname.
1001 NOTE: we're only allowed to overwrite daemon->dhcp_buff if we succeed. */
1002 char *host_from_dns(struct in_addr addr
)
1004 struct crec
*lookup
;
1006 if (daemon
->port
== 0)
1007 return NULL
; /* DNS disabled. */
1009 lookup
= cache_find_by_addr(NULL
, (struct all_addr
*)&addr
, 0, F_IPV4
);
1011 if (lookup
&& (lookup
->flags
& F_HOSTS
))
1013 char *dot
, *hostname
= cache_get_name(lookup
);
1014 dot
= strchr(hostname
, '.');
1016 if (dot
&& strlen(dot
+1) != 0)
1018 char *d2
= get_domain(addr
);
1019 if (!d2
|| !hostname_isequal(dot
+1, d2
))
1020 return NULL
; /* wrong domain */
1023 if (!legal_hostname(hostname
))
1026 strncpy(daemon
->dhcp_buff
, hostname
, 256);
1027 daemon
->dhcp_buff
[255] = 0;
1028 strip_hostname(daemon
->dhcp_buff
);
1030 return daemon
->dhcp_buff
;
1036 static int relay_upstream4(struct dhcp_relay
*relay
, struct dhcp_packet
*mess
, size_t sz
, int iface_index
)
1038 /* ->local is same value for all relays on ->current chain */
1039 struct all_addr from
;
1041 if (mess
->op
!= BOOTREQUEST
)
1044 /* source address == relay address */
1045 from
.addr
.addr4
= relay
->local
.addr
.addr4
;
1047 /* already gatewayed ? */
1048 if (mess
->giaddr
.s_addr
)
1050 /* if so check if by us, to stomp on loops. */
1051 if (mess
->giaddr
.s_addr
== relay
->local
.addr
.addr4
.s_addr
)
1056 /* plug in our address */
1057 mess
->giaddr
.s_addr
= relay
->local
.addr
.addr4
.s_addr
;
1060 if ((mess
->hops
++) > 20)
1063 for (; relay
; relay
= relay
->current
)
1065 union mysockaddr to
;
1067 to
.sa
.sa_family
= AF_INET
;
1068 to
.in
.sin_addr
= relay
->server
.addr
.addr4
;
1069 to
.in
.sin_port
= htons(daemon
->dhcp_server_port
);
1071 send_from(daemon
->dhcpfd
, 0, (char *)mess
, sz
, &to
, &from
, 0);
1073 if (option_bool(OPT_LOG_OPTS
))
1075 inet_ntop(AF_INET
, &relay
->local
, daemon
->addrbuff
, ADDRSTRLEN
);
1076 my_syslog(MS_DHCP
| LOG_INFO
, _("DHCP relay %s -> %s"), daemon
->addrbuff
, inet_ntoa(relay
->server
.addr
.addr4
));
1079 /* Save this for replies */
1080 relay
->iface_index
= iface_index
;
1087 static struct dhcp_relay
*relay_reply4(struct dhcp_packet
*mess
, char *arrival_interface
)
1089 struct dhcp_relay
*relay
;
1091 if (mess
->giaddr
.s_addr
== 0 || mess
->op
!= BOOTREPLY
)
1094 for (relay
= daemon
->relay4
; relay
; relay
= relay
->next
)
1096 if (mess
->giaddr
.s_addr
== relay
->local
.addr
.addr4
.s_addr
)
1098 if (!relay
->interface
|| wildcard_match(relay
->interface
, arrival_interface
))
1099 return relay
->iface_index
!= 0 ? relay
: NULL
;