1 /* dnsmasq is Copyright (c) 2000-2022 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/>.
21 #define option_len(opt) ((int)(((unsigned char *)(opt))[1]))
22 #define option_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[2u+(unsigned int)(i)]))
25 static void add_extradata_opt(struct dhcp_lease *lease, unsigned char *opt);
28 static int sanitise(unsigned char *opt, char *buf);
29 static struct in_addr server_id(struct dhcp_context *context, struct in_addr override, struct in_addr fallback);
30 static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config *config, unsigned char *opt);
31 static void option_put(struct dhcp_packet *mess, unsigned char *end, int opt, int len, unsigned int val);
32 static void option_put_string(struct dhcp_packet *mess, unsigned char *end,
33 int opt, const char *string, int null_term);
34 static struct in_addr option_addr(unsigned char *opt);
35 static unsigned int option_uint(unsigned char *opt, int offset, int size);
36 static void log_packet(char *type, void *addr, unsigned char *ext_mac,
37 int mac_len, char *interface, char *string, char *err, u32 xid);
38 static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize);
39 static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize);
40 static size_t dhcp_packet_size(struct dhcp_packet *mess, unsigned char *agent_id, unsigned char *real_end);
41 static void clear_packet(struct dhcp_packet *mess, unsigned char *end);
42 static int in_list(unsigned char *list, int opt);
43 static void do_options(struct dhcp_context *context,
44 struct dhcp_packet *mess,
46 unsigned char *req_options,
49 struct dhcp_netid *netid,
50 struct in_addr subnet_addr,
51 unsigned char fqdn_flags,
52 int null_term, int pxe_arch,
56 unsigned int lease_time,
58 const char *pxevendor);
61 static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt);
62 static int do_encap_opts(struct dhcp_opt *opt, int encap, int flag, struct dhcp_packet *mess, unsigned char *end, int null_term);
63 static void pxe_misc(struct dhcp_packet *mess, unsigned char *end, unsigned char *uuid, const char *pxevendor);
64 static int prune_vendor_opts(struct dhcp_netid *netid);
65 static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct in_addr local, time_t now);
66 struct dhcp_boot *find_boot(struct dhcp_netid *netid);
67 static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dhcp_packet *mess, struct in_addr local, time_t now, int pxe);
68 static void apply_delay(u32 xid, time_t recvtime, struct dhcp_netid *netid);
69 static int is_pxe_client(struct dhcp_packet *mess, size_t sz, const char **pxe_vendor);
71 size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
72 size_t sz, time_t now, int unicast_dest, int loopback,
73 int *is_inform, int pxe, struct in_addr fallback, time_t recvtime)
75 unsigned char *opt, *clid = NULL;
76 struct dhcp_lease *ltmp, *lease = NULL;
77 struct dhcp_vendor *vendor;
79 struct dhcp_netid_list *id_list;
80 int clid_len = 0, ignore = 0, do_classes = 0, rapid_commit = 0, selecting = 0, pxearch = -1;
81 const char *pxevendor = NULL;
82 struct dhcp_packet *mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
83 unsigned char *end = (unsigned char *)(mess + 1);
84 unsigned char *real_end = (unsigned char *)(mess + 1);
85 char *hostname = NULL, *offer_hostname = NULL, *client_hostname = NULL, *domain = NULL;
86 int hostname_auth = 0, borken_opt = 0;
87 unsigned char *req_options = NULL;
90 struct dhcp_config *config;
91 struct dhcp_netid *netid, *tagif_netid;
92 struct in_addr subnet_addr, override;
93 unsigned short fuzz = 0;
94 unsigned int mess_type = 0;
95 unsigned char fqdn_flags = 0;
96 unsigned char *agent_id = NULL, *uuid = NULL;
97 unsigned char *emac = NULL;
98 int vendor_class_len = 0, emac_len = 0;
99 struct dhcp_netid known_id, iface_id, cpewan_id;
101 unsigned char pxe_uuid[17];
102 unsigned char *oui = NULL, *serial = NULL;
104 unsigned char *class = NULL;
107 subnet_addr.s_addr = override.s_addr = 0;
109 /* set tag with name == interface */
110 iface_id.net = iface_name;
111 iface_id.next = NULL;
114 if (mess->op != BOOTREQUEST || mess->hlen > DHCP_CHADDR_MAX)
117 if (mess->htype == 0 && mess->hlen != 0)
120 /* check for DHCP rather than BOOTP */
121 if ((opt = option_find(mess, sz, OPTION_MESSAGE_TYPE, 1)))
123 u32 cookie = htonl(DHCP_COOKIE);
125 /* only insist on a cookie for DHCP. */
126 if (memcmp(mess->options, &cookie, sizeof(u32)) != 0)
129 mess_type = option_uint(opt, 0, 1);
131 /* two things to note here: expand_buf may move the packet,
132 so reassign mess from daemon->packet. Also, the size
133 sent includes the IP and UDP headers, hence the magic "-28" */
134 if ((opt = option_find(mess, sz, OPTION_MAXMESSAGE, 2)))
136 size_t size = (size_t)option_uint(opt, 0, 2) - 28;
138 if (size > DHCP_PACKET_MAX)
139 size = DHCP_PACKET_MAX;
140 else if (size < sizeof(struct dhcp_packet))
141 size = sizeof(struct dhcp_packet);
143 if (expand_buf(&daemon->dhcp_packet, size))
145 mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
146 real_end = end = ((unsigned char *)mess) + size;
150 /* Some buggy clients set ciaddr when they shouldn't, so clear that here since
151 it can affect the context-determination code. */
152 if ((option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ) || mess_type == DHCPDISCOVER))
153 mess->ciaddr.s_addr = 0;
155 /* search for device identity from CPEWAN devices, we pass this through to the script */
156 if ((opt = option_find(mess, sz, OPTION_VENDOR_IDENT_OPT, 5)))
158 unsigned int elen, offset, len = option_len(opt);
160 for (offset = 0; offset < (len - 5); offset += elen + 5)
162 elen = option_uint(opt, offset + 4 , 1);
163 if (option_uint(opt, offset, 4) == BRDBAND_FORUM_IANA && offset + elen + 5 <= len)
165 unsigned char *x = option_ptr(opt, offset + 5);
166 unsigned char *y = option_ptr(opt, offset + elen + 5);
167 oui = option_find1(x, y, 1, 1);
168 serial = option_find1(x, y, 2, 1);
170 class = option_find1(x, y, 3, 1);
172 /* If TR069-id is present set the tag "cpewan-id" to facilitate echoing
173 the gateway id back. Note that the device class is optional */
176 cpewan_id.net = "cpewan-id";
177 cpewan_id.next = netid;
185 if ((opt = option_find(mess, sz, OPTION_AGENT_ID, 1)))
187 /* Any agent-id needs to be copied back out, verbatim, as the last option
188 in the packet. Here, we shift it to the very end of the buffer, if it doesn't
189 get overwritten, then it will be shuffled back at the end of processing.
190 Note that the incoming options must not be overwritten here, so there has to
191 be enough free space at the end of the packet to copy the option. */
193 unsigned int total = option_len(opt) + 2;
194 unsigned char *last_opt = option_find1(&mess->options[0] + sizeof(u32), ((unsigned char *)mess) + sz,
196 if (last_opt && last_opt < end - total)
200 memcpy(agent_id, opt, total);
203 /* look for RFC3527 Link selection sub-option */
204 if ((sopt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), SUBOPT_SUBNET_SELECT, INADDRSZ)))
205 subnet_addr = option_addr(sopt);
207 /* look for RFC5107 server-identifier-override */
208 if ((sopt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), SUBOPT_SERVER_OR, INADDRSZ)))
209 override = option_addr(sopt);
211 /* if a circuit-id or remote-is option is provided, exact-match to options. */
212 for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
216 if (vendor->match_type == MATCH_CIRCUIT)
217 search = SUBOPT_CIRCUIT_ID;
218 else if (vendor->match_type == MATCH_REMOTE)
219 search = SUBOPT_REMOTE_ID;
220 else if (vendor->match_type == MATCH_SUBSCRIBER)
221 search = SUBOPT_SUBSCR_ID;
225 if ((sopt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), search, 1)) &&
226 vendor->len == option_len(sopt) &&
227 memcmp(option_ptr(sopt, 0), vendor->data, vendor->len) == 0)
229 vendor->netid.next = netid;
230 netid = &vendor->netid;
235 /* Check for RFC3011 subnet selector - only if RFC3527 one not present */
236 if (subnet_addr.s_addr == 0 && (opt = option_find(mess, sz, OPTION_SUBNET_SELECT, INADDRSZ)))
237 subnet_addr = option_addr(opt);
239 /* If there is no client identifier option, use the hardware address */
240 if (!option_bool(OPT_IGNORE_CLID) && (opt = option_find(mess, sz, OPTION_CLIENT_ID, 1)))
242 clid_len = option_len(opt);
243 clid = option_ptr(opt, 0);
246 /* do we have a lease in store? */
247 lease = lease_find_by_client(mess->chaddr, mess->hlen, mess->htype, clid, clid_len);
249 /* If this request is missing a clid, but we've seen one before,
250 use it again for option matching etc. */
251 if (lease && !clid && lease->clid)
253 clid_len = lease->clid_len;
257 /* find mac to use for logging and hashing */
258 emac = extended_hwaddr(mess->htype, mess->hlen, mess->chaddr, clid_len, clid, &emac_len);
261 for (mac = daemon->dhcp_macs; mac; mac = mac->next)
262 if (mac->hwaddr_len == mess->hlen &&
263 (mac->hwaddr_type == mess->htype || mac->hwaddr_type == 0) &&
264 memcmp_masked(mac->hwaddr, mess->chaddr, mess->hlen, mac->mask))
266 mac->netid.next = netid;
270 /* Determine network for this packet. Our caller will have already linked all the
271 contexts which match the addresses of the receiving interface but if the
272 machine has an address already, or came via a relay, or we have a subnet selector,
273 we search again. If we don't have have a giaddr or explicit subnet selector,
274 use the ciaddr. This is necessary because a machine which got a lease via a
275 relay won't use the relay to renew. If matching a ciaddr fails but we have a context
276 from the physical network, continue using that to allow correct DHCPNAK generation later. */
277 if (mess->giaddr.s_addr || subnet_addr.s_addr || mess->ciaddr.s_addr)
279 struct dhcp_context *context_tmp, *context_new = NULL;
280 struct shared_network *share = NULL;
282 int force = 0, via_relay = 0;
284 if (subnet_addr.s_addr)
289 else if (mess->giaddr.s_addr)
297 /* If ciaddr is in the hardware derived set of contexts, leave that unchanged */
299 for (context_tmp = context; context_tmp; context_tmp = context_tmp->current)
300 if (context_tmp->netmask.s_addr &&
301 is_same_net(addr, context_tmp->start, context_tmp->netmask) &&
302 is_same_net(addr, context_tmp->end, context_tmp->netmask))
304 context_new = context;
311 for (context_tmp = daemon->dhcp; context_tmp; context_tmp = context_tmp->next)
313 struct in_addr netmask = context_tmp->netmask;
315 /* guess the netmask for relayed networks */
316 if (!(context_tmp->flags & CONTEXT_NETMASK) && context_tmp->netmask.s_addr == 0)
318 if (IN_CLASSA(ntohl(context_tmp->start.s_addr)) && IN_CLASSA(ntohl(context_tmp->end.s_addr)))
319 netmask.s_addr = htonl(0xff000000);
320 else if (IN_CLASSB(ntohl(context_tmp->start.s_addr)) && IN_CLASSB(ntohl(context_tmp->end.s_addr)))
321 netmask.s_addr = htonl(0xffff0000);
322 else if (IN_CLASSC(ntohl(context_tmp->start.s_addr)) && IN_CLASSC(ntohl(context_tmp->end.s_addr)))
323 netmask.s_addr = htonl(0xffffff00);
326 /* check to see is a context is OK because of a shared address on
327 the relayed subnet. */
329 for (share = daemon->shared_networks; share; share = share->next)
332 if (share->shared_addr.s_addr == 0)
335 if (share->if_index != 0 ||
336 share->match_addr.s_addr != mess->giaddr.s_addr)
339 if (netmask.s_addr != 0 &&
340 is_same_net(share->shared_addr, context_tmp->start, netmask) &&
341 is_same_net(share->shared_addr, context_tmp->end, netmask))
345 /* This section fills in context mainly when a client which is on a remote (relayed)
346 network renews a lease without using the relay, after dnsmasq has restarted. */
348 (netmask.s_addr != 0 &&
349 is_same_net(addr, context_tmp->start, netmask) &&
350 is_same_net(addr, context_tmp->end, netmask)))
352 context_tmp->netmask = netmask;
353 if (context_tmp->local.s_addr == 0)
354 context_tmp->local = fallback;
355 if (context_tmp->router.s_addr == 0 && !share)
356 context_tmp->router = mess->giaddr;
358 /* fill in missing broadcast addresses for relayed ranges */
359 if (!(context_tmp->flags & CONTEXT_BRDCAST) && context_tmp->broadcast.s_addr == 0 )
360 context_tmp->broadcast.s_addr = context_tmp->start.s_addr | ~context_tmp->netmask.s_addr;
362 context_tmp->current = context_new;
363 context_new = context_tmp;
369 if (context_new || force)
370 context = context_new;
376 if (subnet_addr.s_addr)
378 via = _("with subnet selector");
379 inet_ntop(AF_INET, &subnet_addr, daemon->addrbuff, ADDRSTRLEN);
384 if (mess->giaddr.s_addr)
385 inet_ntop(AF_INET, &mess->giaddr, daemon->addrbuff, ADDRSTRLEN);
387 safe_strncpy(daemon->addrbuff, iface_name, ADDRSTRLEN);
389 my_syslog(MS_DHCP | LOG_WARNING, _("no address range available for DHCP request %s %s"),
390 via, daemon->addrbuff);
394 if (option_bool(OPT_LOG_OPTS))
396 struct dhcp_context *context_tmp;
397 for (context_tmp = context; context_tmp; context_tmp = context_tmp->current)
399 inet_ntop(AF_INET, &context_tmp->start, daemon->namebuff, MAXDNAME);
400 if (context_tmp->flags & (CONTEXT_STATIC | CONTEXT_PROXY))
402 inet_ntop(AF_INET, &context_tmp->netmask, daemon->addrbuff, ADDRSTRLEN);
403 my_syslog(MS_DHCP | LOG_INFO, _("%u available DHCP subnet: %s/%s"),
404 ntohl(mess->xid), daemon->namebuff, daemon->addrbuff);
408 inet_ntop(AF_INET, &context_tmp->end, daemon->addrbuff, ADDRSTRLEN);
409 my_syslog(MS_DHCP | LOG_INFO, _("%u available DHCP range: %s -- %s"),
410 ntohl(mess->xid), daemon->namebuff, daemon->addrbuff);
415 /* dhcp-match. If we have hex-and-wildcards, look for a left-anchored match.
416 Otherwise assume the option is an array, and look for a matching element.
417 If no data given, existence of the option is enough. This code handles
418 rfc3925 V-I classes too. */
419 for (o = daemon->dhcp_match; o; o = o->next)
421 unsigned int len, elen, match = 0;
424 if (o->flags & DHOPT_RFC3925)
426 if (!(opt = option_find(mess, sz, OPTION_VENDOR_IDENT, 5)))
429 for (offset = 0; offset < (option_len(opt) - 5u); offset += len + 5)
431 len = option_uint(opt, offset + 4 , 1);
432 /* Need to take care that bad data can't run us off the end of the packet */
433 if ((offset + len + 5 <= (unsigned)(option_len(opt))) &&
434 (option_uint(opt, offset, 4) == (unsigned int)o->u.encap))
435 for (o2 = offset + 5; o2 < offset + len + 5; o2 += elen + 1)
437 elen = option_uint(opt, o2, 1);
438 if ((o2 + elen + 1 <= (unsigned)option_len(opt)) &&
439 (match = match_bytes(o, option_ptr(opt, o2 + 1), elen)))
448 if (!(opt = option_find(mess, sz, o->opt, 1)))
451 match = match_bytes(o, option_ptr(opt, 0), option_len(opt));
456 o->netid->next = netid;
461 /* user-class options are, according to RFC3004, supposed to contain
462 a set of counted strings. Here we check that this is so (by seeing
463 if the counts are consistent with the overall option length) and if
464 so zero the counts so that we don't get spurious matches between
465 the vendor string and the counts. If the lengths don't add up, we
466 assume that the option is a single string and non RFC3004 compliant
467 and just do the substring match. dhclient provides these broken options.
468 The code, later, which sends user-class data to the lease-change script
469 relies on the transformation done here.
472 if ((opt = option_find(mess, sz, OPTION_USER_CLASS, 1)))
474 unsigned char *ucp = option_ptr(opt, 0);
476 for (j = 0; j < option_len(opt); j += ucp[j] + 1);
477 if (j == option_len(opt))
478 for (j = 0; j < option_len(opt); j = tmp)
480 tmp = j + ucp[j] + 1;
485 for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
489 if (vendor->match_type == MATCH_VENDOR)
490 mopt = OPTION_VENDOR_ID;
491 else if (vendor->match_type == MATCH_USER)
492 mopt = OPTION_USER_CLASS;
496 if ((opt = option_find(mess, sz, mopt, 1)))
499 for (i = 0; i <= (option_len(opt) - vendor->len); i++)
500 if (memcmp(vendor->data, option_ptr(opt, i), vendor->len) == 0)
502 vendor->netid.next = netid;
503 netid = &vendor->netid;
509 /* mark vendor-encapsulated options which match the client-supplied vendor class,
510 save client-supplied vendor class */
511 if ((opt = option_find(mess, sz, OPTION_VENDOR_ID, 1)))
513 memcpy(daemon->dhcp_buff3, option_ptr(opt, 0), option_len(opt));
514 vendor_class_len = option_len(opt);
516 match_vendor_opts(opt, daemon->dhcp_opts);
518 if (option_bool(OPT_LOG_OPTS))
520 if (sanitise(opt, daemon->namebuff))
521 my_syslog(MS_DHCP | LOG_INFO, _("%u vendor class: %s"), ntohl(mess->xid), daemon->namebuff);
522 if (sanitise(option_find(mess, sz, OPTION_USER_CLASS, 1), daemon->namebuff))
523 my_syslog(MS_DHCP | LOG_INFO, _("%u user class: %s"), ntohl(mess->xid), daemon->namebuff);
526 mess->op = BOOTREPLY;
528 config = find_config(daemon->dhcp_conf, context, clid, clid_len,
529 mess->chaddr, mess->hlen, mess->htype, NULL, run_tag_if(netid));
531 /* set "known" tag for known hosts */
534 known_id.net = "known";
535 known_id.next = netid;
538 else if (find_config(daemon->dhcp_conf, NULL, clid, clid_len,
539 mess->chaddr, mess->hlen, mess->htype, NULL, run_tag_if(netid)))
541 known_id.net = "known-othernet";
542 known_id.next = netid;
546 if (mess_type == 0 && !pxe)
549 struct dhcp_netid id, bootp_id;
550 struct in_addr *logaddr = NULL;
552 /* must have a MAC addr for bootp */
553 if (mess->htype == 0 || mess->hlen == 0 || (context->flags & CONTEXT_PROXY))
556 if (have_config(config, CONFIG_DISABLE))
557 message = _("disabled");
559 end = mess->options + 64; /* BOOTP vend area is only 64 bytes */
561 if (have_config(config, CONFIG_NAME))
563 hostname = config->hostname;
564 domain = config->domain;
569 struct dhcp_netid_list *list;
571 for (list = config->netid; list; list = list->next)
573 list->list->next = netid;
578 /* Match incoming filename field as a netid. */
581 memcpy(daemon->dhcp_buff2, mess->file, sizeof(mess->file));
582 daemon->dhcp_buff2[sizeof(mess->file) + 1] = 0; /* ensure zero term. */
583 id.net = (char *)daemon->dhcp_buff2;
588 /* Add "bootp" as a tag to allow different options, address ranges etc
590 bootp_id.net = "bootp";
591 bootp_id.next = netid;
594 tagif_netid = run_tag_if(netid);
596 for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
597 if (match_netid(id_list->list, tagif_netid, 0))
598 message = _("ignored");
604 if (have_config(config, CONFIG_ADDR))
607 logaddr = &config->addr;
608 mess->yiaddr = config->addr;
609 if ((lease = lease_find_by_addr(config->addr)) &&
610 (lease->hwaddr_len != mess->hlen ||
611 lease->hwaddr_type != mess->htype ||
612 memcmp(lease->hwaddr, mess->chaddr, lease->hwaddr_len) != 0))
613 message = _("address in use");
617 if (!(lease = lease_find_by_client(mess->chaddr, mess->hlen, mess->htype, NULL, 0)) ||
618 !address_available(context, lease->addr, tagif_netid))
622 /* lease exists, wrong network. */
623 lease_prune(lease, now);
626 if (!address_allocate(context, &mess->yiaddr, mess->chaddr, mess->hlen, tagif_netid, now, loopback))
627 message = _("no address available");
630 mess->yiaddr = lease->addr;
633 if (!message && !(context = narrow_context(context, mess->yiaddr, netid)))
634 message = _("wrong network");
635 else if (context->netid.net)
637 context->netid.next = netid;
638 tagif_netid = run_tag_if(&context->netid);
641 log_tags(tagif_netid, ntohl(mess->xid));
643 if (!message && !nailed)
645 for (id_list = daemon->bootp_dynamic; id_list; id_list = id_list->next)
646 if ((!id_list->list) || match_netid(id_list->list, tagif_netid, 0))
649 message = _("no address configured");
654 (!(lease = lease4_allocate(mess->yiaddr))))
655 message = _("no leases left");
659 logaddr = &mess->yiaddr;
661 lease_set_hwaddr(lease, mess->chaddr, NULL, mess->hlen, mess->htype, 0, now, 1);
663 lease_set_hostname(lease, hostname, 1, get_domain(lease->addr), domain);
664 /* infinite lease unless nailed in dhcp-host line. */
665 lease_set_expires(lease,
666 have_config(config, CONFIG_TIME) ? config->lease_time : 0xffffffff,
668 lease_set_interface(lease, int_index, now);
670 clear_packet(mess, end);
671 do_options(context, mess, end, NULL, hostname, get_domain(mess->yiaddr),
672 netid, subnet_addr, 0, 0, -1, NULL, vendor_class_len, now, 0xffffffff, 0, NULL);
676 daemon->metrics[METRIC_BOOTP]++;
677 log_packet("BOOTP", logaddr, mess->chaddr, mess->hlen, iface_name, NULL, message, mess->xid);
679 return message ? 0 : dhcp_packet_size(mess, agent_id, real_end);
682 if ((opt = option_find(mess, sz, OPTION_CLIENT_FQDN, 3)))
684 /* http://tools.ietf.org/wg/dhc/draft-ietf-dhc-fqdn-option/draft-ietf-dhc-fqdn-option-10.txt */
685 int len = option_len(opt);
686 char *pq = daemon->dhcp_buff;
687 unsigned char *pp, *op = option_ptr(opt, 0);
694 /* NB, the following always sets at least one bit */
695 if (option_bool(OPT_FQDN_UPDATE))
697 if (fqdn_flags & 0x01)
699 fqdn_flags |= 0x02; /* set O */
700 fqdn_flags &= ~0x01; /* clear S */
702 fqdn_flags |= 0x08; /* set N */
706 if (!(fqdn_flags & 0x01))
707 fqdn_flags |= 0x03; /* set S and O */
708 fqdn_flags &= ~0x08; /* clear N */
711 if (fqdn_flags & 0x04)
712 while (*op != 0 && ((op + (*op)) - pp) < len)
714 memcpy(pq, op+1, *op);
722 if (len > 0 && op[len-1] == 0)
727 if (pq != daemon->dhcp_buff)
732 if (legal_hostname(daemon->dhcp_buff))
733 offer_hostname = client_hostname = daemon->dhcp_buff;
735 else if ((opt = option_find(mess, sz, OPTION_HOSTNAME, 1)))
737 int len = option_len(opt);
738 memcpy(daemon->dhcp_buff, option_ptr(opt, 0), len);
739 /* Microsoft clients are broken, and need zero-terminated strings
740 in options. We detect this state here, and do the same in
741 any options we send */
742 if (len > 0 && daemon->dhcp_buff[len-1] == 0)
745 daemon->dhcp_buff[len] = 0;
746 if (legal_hostname(daemon->dhcp_buff))
747 client_hostname = daemon->dhcp_buff;
752 struct dhcp_match_name *m;
753 size_t nl = strlen(client_hostname);
755 if (option_bool(OPT_LOG_OPTS))
756 my_syslog(MS_DHCP | LOG_INFO, _("%u client provides name: %s"), ntohl(mess->xid), client_hostname);
757 for (m = daemon->dhcp_name_match; m; m = m->next)
759 size_t ml = strlen(m->name);
766 save = client_hostname[ml];
767 client_hostname[ml] = 0;
770 if (hostname_isequal(client_hostname, m->name) &&
771 (save == 0 || m->wildcard))
773 m->netid->next = netid;
778 client_hostname[ml] = save;
782 if (have_config(config, CONFIG_NAME))
784 hostname = config->hostname;
785 domain = config->domain;
787 /* be careful not to send an OFFER with a hostname not matching the DISCOVER. */
788 if (fqdn_flags != 0 || !client_hostname || hostname_isequal(hostname, client_hostname))
789 offer_hostname = hostname;
791 else if (client_hostname)
793 domain = strip_hostname(client_hostname);
795 if (strlen(client_hostname) != 0)
797 hostname = client_hostname;
801 /* Search again now we have a hostname.
802 Only accept configs without CLID and HWADDR here, (they won't match)
803 to avoid impersonation by name. */
804 struct dhcp_config *new = find_config(daemon->dhcp_conf, context, NULL, 0,
805 mess->chaddr, mess->hlen,
806 mess->htype, hostname, run_tag_if(netid));
807 if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr)
810 /* set "known" tag for known hosts */
811 known_id.net = "known";
812 known_id.next = netid;
821 struct dhcp_netid_list *list;
823 for (list = config->netid; list; list = list->next)
825 list->list->next = netid;
830 tagif_netid = run_tag_if(netid);
832 /* if all the netids in the ignore list are present, ignore this client */
833 for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
834 if (match_netid(id_list->list, tagif_netid, 0))
837 /* If configured, we can override the server-id to be the address of the relay,
838 so that all traffic goes via the relay and can pick up agent-id info. This can be
839 configured for all relays, or by address. */
840 if (daemon->override && mess->giaddr.s_addr != 0 && override.s_addr == 0)
842 if (!daemon->override_relays)
843 override = mess->giaddr;
847 for (l = daemon->override_relays; l; l = l->next)
848 if (l->addr.s_addr == mess->giaddr.s_addr)
851 override = mess->giaddr;
855 /* Can have setting to ignore the client ID for a particular MAC address or hostname */
856 if (have_config(config, CONFIG_NOCLID))
859 /* Check if client is PXE client. */
860 if (daemon->enable_pxe &&
861 is_pxe_client(mess, sz, &pxevendor))
863 if ((opt = option_find(mess, sz, OPTION_PXE_UUID, 17)))
865 memcpy(pxe_uuid, option_ptr(opt, 0), 17);
869 /* Check if this is really a PXE bootserver request, and handle specially if so. */
870 if ((mess_type == DHCPREQUEST || mess_type == DHCPINFORM) &&
871 (opt = option_find(mess, sz, OPTION_VENDOR_CLASS_OPT, 1)) &&
872 (opt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), SUBOPT_PXE_BOOT_ITEM, 4)))
874 struct pxe_service *service;
875 int type = option_uint(opt, 0, 2);
876 int layer = option_uint(opt, 2, 2);
877 unsigned char save71[4];
878 struct dhcp_opt opt71;
885 my_syslog(MS_DHCP | LOG_ERR, _("PXE BIS not supported"));
889 memcpy(save71, option_ptr(opt, 0), 4);
891 for (service = daemon->pxe_services; service; service = service->next)
892 if (service->type == type)
895 for (; context; context = context->current)
896 if (match_netid(context->filter, tagif_netid, 1) &&
897 is_same_net(mess->ciaddr, context->start, context->netmask))
900 if (!service || !service->basename || !context)
903 clear_packet(mess, end);
905 mess->yiaddr = mess->ciaddr;
906 mess->ciaddr.s_addr = 0;
908 mess->siaddr = a_record_from_hosts(service->sname, now);
909 else if (service->server.s_addr != 0)
910 mess->siaddr = service->server;
912 mess->siaddr = context->local;
914 if (strchr(service->basename, '.'))
915 snprintf((char *)mess->file, sizeof(mess->file),
916 "%s", service->basename);
918 snprintf((char *)mess->file, sizeof(mess->file),
919 "%s.%d", service->basename, layer);
921 option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
922 option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(context->local.s_addr));
923 pxe_misc(mess, end, uuid, pxevendor);
925 prune_vendor_opts(tagif_netid);
927 opt71.opt = SUBOPT_PXE_BOOT_ITEM;
929 opt71.flags = DHOPT_VENDOR_MATCH;
931 opt71.next = daemon->dhcp_opts;
932 do_encap_opts(&opt71, OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
934 log_packet("PXE", &mess->yiaddr, emac, emac_len, iface_name, (char *)mess->file, NULL, mess->xid);
935 log_tags(tagif_netid, ntohl(mess->xid));
936 return dhcp_packet_size(mess, agent_id, real_end);
939 if ((opt = option_find(mess, sz, OPTION_ARCH, 2)))
941 pxearch = option_uint(opt, 0, 2);
943 /* proxy DHCP here. */
944 if ((mess_type == DHCPDISCOVER || (pxe && mess_type == DHCPREQUEST)))
946 struct dhcp_context *tmp;
949 for (tmp = context; tmp; tmp = tmp->current)
950 if ((tmp->flags & CONTEXT_PROXY) &&
951 match_netid(tmp->filter, tagif_netid, 1))
956 struct dhcp_boot *boot;
957 int redirect4011 = 0;
961 tmp->netid.next = netid;
962 tagif_netid = run_tag_if(&tmp->netid);
965 boot = find_boot(tagif_netid);
967 mess->yiaddr.s_addr = 0;
968 if (mess_type == DHCPDISCOVER || mess->ciaddr.s_addr == 0)
970 mess->ciaddr.s_addr = 0;
971 mess->flags |= htons(0x8000); /* broadcast */
974 clear_packet(mess, end);
976 /* Redirect EFI clients to port 4011 */
980 mess->siaddr = tmp->local;
983 /* Returns true if only one matching service is available. On port 4011,
984 it also inserts the boot file and server name. */
985 workaround = pxe_uefi_workaround(pxearch, tagif_netid, mess, tmp->local, now, pxe);
987 if (!workaround && boot)
989 /* Provide the bootfile here, for iPXE, and in case we have no menu items
990 and set discovery_control = 8 */
991 if (boot->next_server.s_addr)
992 mess->siaddr = boot->next_server;
993 else if (boot->tftp_sname)
994 mess->siaddr = a_record_from_hosts(boot->tftp_sname, now);
997 safe_strncpy((char *)mess->file, boot->file, sizeof(mess->file));
1000 option_put(mess, end, OPTION_MESSAGE_TYPE, 1,
1001 mess_type == DHCPDISCOVER ? DHCPOFFER : DHCPACK);
1002 option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(tmp->local.s_addr));
1003 pxe_misc(mess, end, uuid, pxevendor);
1004 prune_vendor_opts(tagif_netid);
1005 if ((pxe && !workaround) || !redirect4011)
1006 do_encap_opts(pxe_opts(pxearch, tagif_netid, tmp->local, now), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
1008 daemon->metrics[METRIC_PXE]++;
1009 log_packet("PXE", NULL, emac, emac_len, iface_name, ignore ? "proxy-ignored" : "proxy", NULL, mess->xid);
1010 log_tags(tagif_netid, ntohl(mess->xid));
1012 apply_delay(mess->xid, recvtime, tagif_netid);
1013 return ignore ? 0 : dhcp_packet_size(mess, agent_id, real_end);
1019 /* if we're just a proxy server, go no further */
1020 if ((context->flags & CONTEXT_PROXY) || pxe)
1023 if ((opt = option_find(mess, sz, OPTION_REQUESTED_OPTIONS, 0)))
1025 req_options = (unsigned char *)daemon->dhcp_buff2;
1026 memcpy(req_options, option_ptr(opt, 0), option_len(opt));
1027 req_options[option_len(opt)] = OPTION_END;
1033 if (!(opt = option_find(mess, sz, OPTION_SERVER_IDENTIFIER, INADDRSZ)) ||
1034 option_addr(opt).s_addr != server_id(context, override, fallback).s_addr)
1037 /* sanitise any message. Paranoid? Moi? */
1038 sanitise(option_find(mess, sz, OPTION_MESSAGE, 1), daemon->dhcp_buff);
1040 if (!(opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
1043 daemon->metrics[METRIC_DHCPDECLINE]++;
1044 log_packet("DHCPDECLINE", option_ptr(opt, 0), emac, emac_len, iface_name, NULL, daemon->dhcp_buff, mess->xid);
1046 if (lease && lease->addr.s_addr == option_addr(opt).s_addr)
1047 lease_prune(lease, now);
1049 if (have_config(config, CONFIG_ADDR) &&
1050 config->addr.s_addr == option_addr(opt).s_addr)
1052 prettyprint_time(daemon->dhcp_buff, DECLINE_BACKOFF);
1053 inet_ntop(AF_INET, &config->addr, daemon->addrbuff, ADDRSTRLEN);
1054 my_syslog(MS_DHCP | LOG_WARNING, _("disabling DHCP static address %s for %s"),
1055 daemon->addrbuff, daemon->dhcp_buff);
1056 config->flags |= CONFIG_DECLINED;
1057 config->decline_time = now;
1060 /* make sure this host gets a different address next time. */
1061 for (; context; context = context->current)
1062 context->addr_epoch++;
1067 if (!(context = narrow_context(context, mess->ciaddr, tagif_netid)) ||
1068 !(opt = option_find(mess, sz, OPTION_SERVER_IDENTIFIER, INADDRSZ)) ||
1069 option_addr(opt).s_addr != server_id(context, override, fallback).s_addr)
1072 if (lease && lease->addr.s_addr == mess->ciaddr.s_addr)
1073 lease_prune(lease, now);
1075 message = _("unknown lease");
1077 daemon->metrics[METRIC_DHCPRELEASE]++;
1078 log_packet("DHCPRELEASE", &mess->ciaddr, emac, emac_len, iface_name, NULL, message, mess->xid);
1083 if (ignore || have_config(config, CONFIG_DISABLE))
1085 if (option_bool(OPT_QUIET_DHCP))
1087 message = _("ignored");
1092 struct in_addr addr, conf;
1094 addr.s_addr = conf.s_addr = 0;
1096 if ((opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
1097 addr = option_addr(opt);
1099 if (have_config(config, CONFIG_ADDR))
1101 inet_ntop(AF_INET, &config->addr, daemon->addrbuff, ADDRSTRLEN);
1103 if ((ltmp = lease_find_by_addr(config->addr)) &&
1105 !config_has_mac(config, ltmp->hwaddr, ltmp->hwaddr_len, ltmp->hwaddr_type))
1108 unsigned char *mac = extended_hwaddr(ltmp->hwaddr_type, ltmp->hwaddr_len,
1109 ltmp->hwaddr, ltmp->clid_len, ltmp->clid, &len);
1110 my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is leased to %s"),
1111 daemon->addrbuff, print_mac(daemon->namebuff, mac, len));
1115 struct dhcp_context *tmp;
1116 for (tmp = context; tmp; tmp = tmp->current)
1117 if (context->router.s_addr == config->addr.s_addr)
1120 my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is in use by the server or relay"), daemon->addrbuff);
1121 else if (have_config(config, CONFIG_DECLINED) &&
1122 difftime(now, config->decline_time) < (float)DECLINE_BACKOFF)
1123 my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it was previously declined"), daemon->addrbuff);
1125 conf = config->addr;
1130 mess->yiaddr = conf;
1132 address_available(context, lease->addr, tagif_netid) &&
1133 !config_find_by_address(daemon->dhcp_conf, lease->addr))
1134 mess->yiaddr = lease->addr;
1135 else if (opt && address_available(context, addr, tagif_netid) && !lease_find_by_addr(addr) &&
1136 !config_find_by_address(daemon->dhcp_conf, addr) && do_icmp_ping(now, addr, 0, loopback))
1137 mess->yiaddr = addr;
1138 else if (emac_len == 0)
1139 message = _("no unique-id");
1140 else if (!address_allocate(context, &mess->yiaddr, emac, emac_len, tagif_netid, now, loopback))
1141 message = _("no address available");
1144 daemon->metrics[METRIC_DHCPDISCOVER]++;
1145 log_packet("DHCPDISCOVER", opt ? option_ptr(opt, 0) : NULL, emac, emac_len, iface_name, NULL, message, mess->xid);
1147 if (message || !(context = narrow_context(context, mess->yiaddr, tagif_netid)))
1150 if (context->netid.net)
1152 context->netid.next = netid;
1153 tagif_netid = run_tag_if(&context->netid);
1156 apply_delay(mess->xid, recvtime, tagif_netid);
1158 if (option_bool(OPT_RAPID_COMMIT) && option_find(mess, sz, OPTION_RAPID_COMMIT, 0))
1161 /* If a lease exists for this host and another address, squash it. */
1162 if (lease && lease->addr.s_addr != mess->yiaddr.s_addr)
1164 lease_prune(lease, now);
1170 log_tags(tagif_netid, ntohl(mess->xid));
1172 daemon->metrics[METRIC_DHCPOFFER]++;
1173 log_packet("DHCPOFFER" , &mess->yiaddr, emac, emac_len, iface_name, NULL, NULL, mess->xid);
1175 time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
1176 clear_packet(mess, end);
1177 option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPOFFER);
1178 option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
1179 option_put(mess, end, OPTION_LEASE_TIME, 4, time);
1180 /* T1 and T2 are required in DHCPOFFER by HP's wacky Jetdirect client. */
1181 do_options(context, mess, end, req_options, offer_hostname, get_domain(mess->yiaddr),
1182 netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now, time, fuzz, pxevendor);
1184 return dhcp_packet_size(mess, agent_id, real_end);
1188 if (ignore || have_config(config, CONFIG_DISABLE))
1190 if ((opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
1192 /* SELECTING or INIT_REBOOT */
1193 mess->yiaddr = option_addr(opt);
1195 /* send vendor and user class info for new or recreated lease */
1198 if ((opt = option_find(mess, sz, OPTION_SERVER_IDENTIFIER, INADDRSZ)))
1203 if (override.s_addr != 0)
1205 if (option_addr(opt).s_addr != override.s_addr)
1210 for (; context; context = context->current)
1211 if (context->local.s_addr == option_addr(opt).s_addr)
1216 /* Handle very strange configs where clients have more than one route to the server.
1217 If a clients idea of its server-id matches any of our DHCP interfaces, we let it pass.
1218 Have to set override to make sure we echo back the correct server-id */
1221 enumerate_interfaces(0);
1223 for (intr = daemon->interfaces; intr; intr = intr->next)
1224 if (intr->addr.sa.sa_family == AF_INET &&
1225 intr->addr.in.sin_addr.s_addr == option_addr(opt).s_addr &&
1230 override = intr->addr.in.sin_addr;
1233 /* In auth mode, a REQUEST sent to the wrong server
1234 should be faulted, so that the client establishes
1235 communication with us, otherwise, silently ignore. */
1236 if (!option_bool(OPT_AUTHORITATIVE))
1238 message = _("wrong server-ID");
1243 /* If a lease exists for this host and another address, squash it. */
1244 if (lease && lease->addr.s_addr != mess->yiaddr.s_addr)
1246 lease_prune(lease, now);
1253 if (!lease && !option_bool(OPT_AUTHORITATIVE))
1256 if (lease && lease->addr.s_addr != mess->yiaddr.s_addr)
1257 message = _("wrong address");
1262 /* RENEWING or REBINDING */
1263 /* Check existing lease for this address.
1264 We allow it to be missing if dhcp-authoritative mode
1265 as long as we can allocate the lease now - checked below.
1266 This makes for a smooth recovery from a lost lease DB */
1267 if ((lease && mess->ciaddr.s_addr != lease->addr.s_addr) ||
1268 (!lease && !option_bool(OPT_AUTHORITATIVE)))
1270 /* A client rebinding will broadcast the request, so we may see it even
1271 if the lease is held by another server. Just ignore it in that case.
1272 If the request is unicast to us, then somethings wrong, NAK */
1275 message = _("lease not found");
1276 /* ensure we broadcast NAK */
1280 /* desynchronise renewals */
1282 mess->yiaddr = mess->ciaddr;
1285 daemon->metrics[METRIC_DHCPREQUEST]++;
1286 log_packet("DHCPREQUEST", &mess->yiaddr, emac, emac_len, iface_name, NULL, NULL, mess->xid);
1291 struct dhcp_config *addr_config;
1292 struct dhcp_context *tmp = NULL;
1294 if (have_config(config, CONFIG_ADDR))
1295 for (tmp = context; tmp; tmp = tmp->current)
1296 if (context->router.s_addr == config->addr.s_addr)
1299 if (!(context = narrow_context(context, mess->yiaddr, tagif_netid)))
1301 /* If a machine moves networks whilst it has a lease, we catch that here. */
1302 message = _("wrong network");
1303 /* ensure we broadcast NAK */
1307 /* Check for renewal of a lease which is outside the allowed range. */
1308 else if (!address_available(context, mess->yiaddr, tagif_netid) &&
1309 (!have_config(config, CONFIG_ADDR) || config->addr.s_addr != mess->yiaddr.s_addr))
1310 message = _("address not available");
1312 /* Check if a new static address has been configured. Be very sure that
1313 when the client does DISCOVER, it will get the static address, otherwise
1314 an endless protocol loop will ensue. */
1315 else if (!tmp && !selecting &&
1316 have_config(config, CONFIG_ADDR) &&
1317 (!have_config(config, CONFIG_DECLINED) ||
1318 difftime(now, config->decline_time) > (float)DECLINE_BACKOFF) &&
1319 config->addr.s_addr != mess->yiaddr.s_addr &&
1320 (!(ltmp = lease_find_by_addr(config->addr)) || ltmp == lease))
1321 message = _("static lease available");
1323 /* Check to see if the address is reserved as a static address for another host */
1324 else if ((addr_config = config_find_by_address(daemon->dhcp_conf, mess->yiaddr)) && addr_config != config)
1325 message = _("address reserved");
1327 else if (!lease && (ltmp = lease_find_by_addr(mess->yiaddr)))
1329 /* If a host is configured with more than one MAC address, it's OK to 'nix
1330 a lease from one of it's MACs to give the address to another. */
1331 if (config && config_has_mac(config, ltmp->hwaddr, ltmp->hwaddr_len, ltmp->hwaddr_type))
1333 inet_ntop(AF_INET, <mp->addr, daemon->addrbuff, ADDRSTRLEN);
1334 my_syslog(MS_DHCP | LOG_INFO, _("abandoning lease to %s of %s"),
1335 print_mac(daemon->namebuff, ltmp->hwaddr, ltmp->hwaddr_len),
1340 message = _("address in use");
1346 message = _("no unique-id");
1350 if ((lease = lease4_allocate(mess->yiaddr)))
1353 message = _("no leases left");
1360 daemon->metrics[rapid_commit ? METRIC_NOANSWER : METRIC_DHCPNAK]++;
1361 log_packet(rapid_commit ? "NOANSWER" : "DHCPNAK", &mess->yiaddr, emac, emac_len, iface_name, NULL, message, mess->xid);
1363 /* rapid commit case: lease allocate failed but don't send DHCPNAK */
1367 mess->yiaddr.s_addr = 0;
1368 clear_packet(mess, end);
1369 option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPNAK);
1370 option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
1371 option_put_string(mess, end, OPTION_MESSAGE, message, borken_opt);
1372 /* This fixes a problem with the DHCP spec, broadcasting a NAK to a host on
1373 a distant subnet which unicast a REQ to us won't work. */
1374 if (!unicast_dest || mess->giaddr.s_addr != 0 ||
1375 mess->ciaddr.s_addr == 0 || is_same_net(context->local, mess->ciaddr, context->netmask))
1377 mess->flags |= htons(0x8000); /* broadcast */
1378 mess->ciaddr.s_addr = 0;
1383 if (context->netid.net)
1385 context->netid.next = netid;
1386 tagif_netid = run_tag_if( &context->netid);
1389 log_tags(tagif_netid, ntohl(mess->xid));
1393 /* pick up INIT-REBOOT events. */
1394 lease->flags |= LEASE_CHANGED;
1397 if (daemon->lease_change_command)
1399 struct dhcp_netid *n;
1401 if (mess->giaddr.s_addr)
1402 lease->giaddr = mess->giaddr;
1404 free(lease->extradata);
1405 lease->extradata = NULL;
1406 lease->extradata_size = lease->extradata_len = 0;
1408 add_extradata_opt(lease, option_find(mess, sz, OPTION_VENDOR_ID, 1));
1409 add_extradata_opt(lease, option_find(mess, sz, OPTION_HOSTNAME, 1));
1410 add_extradata_opt(lease, oui);
1411 add_extradata_opt(lease, serial);
1412 add_extradata_opt(lease, class);
1414 if ((opt = option_find(mess, sz, OPTION_AGENT_ID, 1)))
1416 add_extradata_opt(lease, option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), SUBOPT_CIRCUIT_ID, 1));
1417 add_extradata_opt(lease, option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), SUBOPT_SUBSCR_ID, 1));
1418 add_extradata_opt(lease, option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), SUBOPT_REMOTE_ID, 1));
1422 add_extradata_opt(lease, NULL);
1423 add_extradata_opt(lease, NULL);
1424 add_extradata_opt(lease, NULL);
1427 /* DNSMASQ_REQUESTED_OPTIONS */
1428 if ((opt = option_find(mess, sz, OPTION_REQUESTED_OPTIONS, 1)))
1430 int i, len = option_len(opt);
1431 unsigned char *rop = option_ptr(opt, 0);
1433 for (i = 0; i < len; i++)
1434 lease_add_extradata(lease, (unsigned char *)daemon->namebuff,
1435 sprintf(daemon->namebuff, "%u", rop[i]), (i + 1) == len ? 0 : ',');
1438 lease_add_extradata(lease, NULL, 0, 0);
1440 add_extradata_opt(lease, option_find(mess, sz, OPTION_MUD_URL_V4, 1));
1442 /* space-concat tag set */
1444 add_extradata_opt(lease, NULL);
1446 for (n = tagif_netid; n; n = n->next)
1448 struct dhcp_netid *n1;
1450 for (n1 = n->next; n1; n1 = n1->next)
1451 if (strcmp(n->net, n1->net) == 0)
1454 lease_add_extradata(lease, (unsigned char *)n->net, strlen(n->net), n->next ? ' ' : 0);
1457 if ((opt = option_find(mess, sz, OPTION_USER_CLASS, 1)))
1459 int len = option_len(opt);
1460 unsigned char *ucp = option_ptr(opt, 0);
1461 /* If the user-class option started as counted strings, the first byte will be zero. */
1462 if (len != 0 && ucp[0] == 0)
1464 lease_add_extradata(lease, ucp, len, -1);
1470 if (!hostname_auth && (client_hostname = host_from_dns(mess->yiaddr)))
1472 domain = get_domain(mess->yiaddr);
1473 hostname = client_hostname;
1477 time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
1478 lease_set_hwaddr(lease, mess->chaddr, clid, mess->hlen, mess->htype, clid_len, now, do_classes);
1480 /* if all the netids in the ignore_name list are present, ignore client-supplied name */
1483 for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next)
1484 if ((!id_list->list) || match_netid(id_list->list, tagif_netid, 0))
1490 /* Last ditch, if configured, generate hostname from mac address */
1491 if (!hostname && emac_len != 0)
1493 for (id_list = daemon->dhcp_gen_names; id_list; id_list = id_list->next)
1494 if ((!id_list->list) || match_netid(id_list->list, tagif_netid, 0))
1500 hostname = daemon->dhcp_buff;
1501 /* buffer is 256 bytes, 3 bytes per octet */
1502 for (i = 0; (i < emac_len) && (i < 80); i++)
1503 hostname += sprintf(hostname, "%.2x%s", emac[i], (i == emac_len - 1) ? "" : "-");
1504 hostname = daemon->dhcp_buff;
1509 lease_set_hostname(lease, hostname, hostname_auth, get_domain(lease->addr), domain);
1511 lease_set_expires(lease, time, now);
1512 lease_set_interface(lease, int_index, now);
1514 if (override.s_addr != 0)
1515 lease->override = override;
1517 override = lease->override;
1519 daemon->metrics[METRIC_DHCPACK]++;
1520 log_packet("DHCPACK", &mess->yiaddr, emac, emac_len, iface_name, hostname, NULL, mess->xid);
1522 clear_packet(mess, end);
1523 option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
1524 option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
1525 option_put(mess, end, OPTION_LEASE_TIME, 4, time);
1527 option_put(mess, end, OPTION_RAPID_COMMIT, 0, 0);
1528 do_options(context, mess, end, req_options, hostname, get_domain(mess->yiaddr),
1529 netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now, time, fuzz, pxevendor);
1532 return dhcp_packet_size(mess, agent_id, real_end);
1535 if (ignore || have_config(config, CONFIG_DISABLE))
1536 message = _("ignored");
1538 daemon->metrics[METRIC_DHCPINFORM]++;
1539 log_packet("DHCPINFORM", &mess->ciaddr, emac, emac_len, iface_name, message, NULL, mess->xid);
1541 if (message || mess->ciaddr.s_addr == 0)
1544 /* For DHCPINFORM only, cope without a valid context */
1545 context = narrow_context(context, mess->ciaddr, tagif_netid);
1547 /* Find a least based on IP address if we didn't
1548 get one from MAC address/client-d */
1550 (lease = lease_find_by_addr(mess->ciaddr)) &&
1552 hostname = lease->hostname;
1555 hostname = host_from_dns(mess->ciaddr);
1557 if (context && context->netid.net)
1559 context->netid.next = netid;
1560 tagif_netid = run_tag_if(&context->netid);
1563 log_tags(tagif_netid, ntohl(mess->xid));
1565 daemon->metrics[METRIC_DHCPACK]++;
1566 log_packet("DHCPACK", &mess->ciaddr, emac, emac_len, iface_name, hostname, NULL, mess->xid);
1570 lease_set_interface(lease, int_index, now);
1571 if (override.s_addr != 0)
1572 lease->override = override;
1574 override = lease->override;
1577 clear_packet(mess, end);
1578 option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
1579 option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
1581 /* RFC 2131 says that DHCPINFORM shouldn't include lease-time parameters, but
1582 we supply a utility which makes DHCPINFORM requests to get this information.
1583 Only include lease time if OPTION_LEASE_TIME is in the parameter request list,
1584 which won't be true for ordinary clients, but will be true for the
1585 dhcp_lease_time utility. */
1586 if (lease && in_list(req_options, OPTION_LEASE_TIME))
1588 if (lease->expires == 0)
1591 time = (unsigned int)difftime(lease->expires, now);
1592 option_put(mess, end, OPTION_LEASE_TIME, 4, time);
1595 do_options(context, mess, end, req_options, hostname, get_domain(mess->ciaddr),
1596 netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now, 0xffffffff, 0, pxevendor);
1598 *is_inform = 1; /* handle reply differently */
1599 return dhcp_packet_size(mess, agent_id, real_end);
1605 /* find a good value to use as MAC address for logging and address-allocation hashing.
1606 This is normally just the chaddr field from the DHCP packet,
1607 but eg Firewire will have hlen == 0 and use the client-id instead.
1608 This could be anything, but will normally be EUI64 for Firewire.
1609 We assume that if the first byte of the client-id equals the htype byte
1610 then the client-id is using the usual encoding and use the rest of the
1611 client-id: if not we can use the whole client-id. This should give
1612 sane MAC address logs. */
1613 unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr,
1614 int clid_len, unsigned char *clid, int *len_out)
1616 if (hwlen == 0 && clid && clid_len > 3)
1618 if (clid[0] == hwtype)
1620 *len_out = clid_len - 1 ;
1624 #if defined(ARPHRD_EUI64) && defined(ARPHRD_IEEE1394)
1625 if (clid[0] == ARPHRD_EUI64 && hwtype == ARPHRD_IEEE1394)
1627 *len_out = clid_len - 1 ;
1632 *len_out = clid_len;
1640 static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config *config, unsigned char *opt)
1642 unsigned int time = have_config(config, CONFIG_TIME) ? config->lease_time : context->lease_time;
1646 unsigned int req_time = option_uint(opt, 0, 4);
1647 if (req_time < 120 )
1648 req_time = 120; /* sanity */
1649 if (time == 0xffffffff || (req_time != 0xffffffff && req_time < time))
1656 static struct in_addr server_id(struct dhcp_context *context, struct in_addr override, struct in_addr fallback)
1658 if (override.s_addr != 0)
1660 else if (context && context->local.s_addr != 0)
1661 return context->local;
1666 static int sanitise(unsigned char *opt, char *buf)
1676 p = option_ptr(opt, 0);
1678 for (i = option_len(opt); i > 0; i--)
1681 if (isprint((int)c))
1684 *buf = 0; /* add terminator */
1690 static void add_extradata_opt(struct dhcp_lease *lease, unsigned char *opt)
1693 lease_add_extradata(lease, NULL, 0, 0);
1695 lease_add_extradata(lease, option_ptr(opt, 0), option_len(opt), 0);
1699 static void log_packet(char *type, void *addr, unsigned char *ext_mac,
1700 int mac_len, char *interface, char *string, char *err, u32 xid)
1702 if (!err && !option_bool(OPT_LOG_OPTS) && option_bool(OPT_QUIET_DHCP))
1705 daemon->addrbuff[0] = 0;
1707 inet_ntop(AF_INET, addr, daemon->addrbuff, ADDRSTRLEN);
1709 print_mac(daemon->namebuff, ext_mac, mac_len);
1711 if (option_bool(OPT_LOG_OPTS))
1712 my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s%s%s %s%s",
1719 string ? string : "",
1722 my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s%s%s %s%s",
1728 string ? string : "",
1732 if (!strcmp(type, "DHCPACK"))
1733 ubus_event_bcast("dhcp.ack", daemon->namebuff, addr ? daemon->addrbuff : NULL, string, interface);
1734 else if (!strcmp(type, "DHCPRELEASE"))
1735 ubus_event_bcast("dhcp.release", daemon->namebuff, addr ? daemon->addrbuff : NULL, string, interface);
1739 static void log_options(unsigned char *start, u32 xid)
1741 while (*start != OPTION_END)
1743 char *optname = option_string(AF_INET, start[0], option_ptr(start, 0), option_len(start), daemon->namebuff, MAXDNAME);
1745 my_syslog(MS_DHCP | LOG_INFO, "%u sent size:%3d option:%3d %s %s",
1746 ntohl(xid), option_len(start), start[0], optname, daemon->namebuff);
1747 start += start[1] + 2;
1751 static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize)
1757 else if (*p == OPTION_END)
1758 return opt == OPTION_END ? p : NULL;
1759 else if (*p == OPTION_PAD)
1765 return NULL; /* malformed packet */
1766 opt_len = option_len(p);
1767 if (p > end - (2 + opt_len))
1768 return NULL; /* malformed packet */
1769 if (*p == opt && opt_len >= minsize)
1776 static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize)
1778 unsigned char *ret, *overload;
1780 /* skip over DHCP cookie; */
1781 if ((ret = option_find1(&mess->options[0] + sizeof(u32), ((unsigned char *)mess) + size, opt_type, minsize)))
1784 /* look for overload option. */
1785 if (!(overload = option_find1(&mess->options[0] + sizeof(u32), ((unsigned char *)mess) + size, OPTION_OVERLOAD, 1)))
1788 /* Can we look in filename area ? */
1789 if ((overload[2] & 1) &&
1790 (ret = option_find1(&mess->file[0], &mess->file[128], opt_type, minsize)))
1793 /* finally try sname area */
1794 if ((overload[2] & 2) &&
1795 (ret = option_find1(&mess->sname[0], &mess->sname[64], opt_type, minsize)))
1801 static struct in_addr option_addr(unsigned char *opt)
1803 /* this worries about unaligned data in the option. */
1804 /* struct in_addr is network byte order */
1807 memcpy(&ret, option_ptr(opt, 0), INADDRSZ);
1812 static unsigned int option_uint(unsigned char *opt, int offset, int size)
1814 /* this worries about unaligned data and byte order */
1815 unsigned int ret = 0;
1817 unsigned char *p = option_ptr(opt, offset);
1819 for (i = 0; i < size; i++)
1820 ret = (ret << 8) | *p++;
1825 static unsigned char *dhcp_skip_opts(unsigned char *start)
1828 start += start[1] + 2;
1832 /* only for use when building packet: doesn't check for bad data. */
1833 static unsigned char *find_overload(struct dhcp_packet *mess)
1835 unsigned char *p = &mess->options[0] + sizeof(u32);
1839 if (*p == OPTION_OVERLOAD)
1846 static size_t dhcp_packet_size(struct dhcp_packet *mess, unsigned char *agent_id, unsigned char *real_end)
1848 unsigned char *p = dhcp_skip_opts(&mess->options[0] + sizeof(u32));
1849 unsigned char *overload;
1852 /* move agent_id back down to the end of the packet */
1855 memmove(p, agent_id, real_end - agent_id);
1856 p += real_end - agent_id;
1857 memset(p, 0, real_end - p); /* in case of overlap */
1860 /* add END options to the regions. */
1861 overload = find_overload(mess);
1863 if (overload && (option_uint(overload, 0, 1) & 1))
1865 *dhcp_skip_opts(mess->file) = OPTION_END;
1866 if (option_bool(OPT_LOG_OPTS))
1867 log_options(mess->file, mess->xid);
1869 else if (option_bool(OPT_LOG_OPTS) && strlen((char *)mess->file) != 0)
1870 my_syslog(MS_DHCP | LOG_INFO, _("%u bootfile name: %s"), ntohl(mess->xid), (char *)mess->file);
1872 if (overload && (option_uint(overload, 0, 1) & 2))
1874 *dhcp_skip_opts(mess->sname) = OPTION_END;
1875 if (option_bool(OPT_LOG_OPTS))
1876 log_options(mess->sname, mess->xid);
1878 else if (option_bool(OPT_LOG_OPTS) && strlen((char *)mess->sname) != 0)
1879 my_syslog(MS_DHCP | LOG_INFO, _("%u server name: %s"), ntohl(mess->xid), (char *)mess->sname);
1884 if (option_bool(OPT_LOG_OPTS))
1886 if (mess->siaddr.s_addr != 0)
1888 inet_ntop(AF_INET, &mess->siaddr, daemon->addrbuff, ADDRSTRLEN);
1889 my_syslog(MS_DHCP | LOG_INFO, _("%u next server: %s"), ntohl(mess->xid), daemon->addrbuff);
1892 if ((mess->flags & htons(0x8000)) && mess->ciaddr.s_addr == 0)
1893 my_syslog(MS_DHCP | LOG_INFO, _("%u broadcast response"), ntohl(mess->xid));
1895 log_options(&mess->options[0] + sizeof(u32), mess->xid);
1898 ret = (size_t)(p - (unsigned char *)mess);
1900 if (ret < MIN_PACKETSZ)
1906 static unsigned char *free_space(struct dhcp_packet *mess, unsigned char *end, int opt, int len)
1908 unsigned char *p = dhcp_skip_opts(&mess->options[0] + sizeof(u32));
1910 if (p + len + 3 >= end)
1911 /* not enough space in options area, try and use overload, if poss */
1913 unsigned char *overload;
1915 if (!(overload = find_overload(mess)) &&
1916 (mess->file[0] == 0 || mess->sname[0] == 0))
1918 /* attempt to overload fname and sname areas, we've reserved space for the
1919 overflow option previuously. */
1921 *(p++) = OPTION_OVERLOAD;
1927 /* using filename field ? */
1930 if (mess->file[0] == 0)
1933 if (overload[2] & 1)
1935 p = dhcp_skip_opts(mess->file);
1936 if (p + len + 3 >= mess->file + sizeof(mess->file))
1942 /* try to bring sname into play (it may be already) */
1943 if (mess->sname[0] == 0)
1946 if (overload[2] & 2)
1948 p = dhcp_skip_opts(mess->sname);
1949 if (p + len + 3 >= mess->sname + sizeof(mess->sname))
1956 my_syslog(MS_DHCP | LOG_WARNING, _("cannot send DHCP/BOOTP option %d: no space left in packet"), opt);
1968 static void option_put(struct dhcp_packet *mess, unsigned char *end, int opt, int len, unsigned int val)
1971 unsigned char *p = free_space(mess, end, opt, len);
1974 for (i = 0; i < len; i++)
1975 *(p++) = val >> (8 * (len - (i + 1)));
1978 static void option_put_string(struct dhcp_packet *mess, unsigned char *end, int opt,
1979 const char *string, int null_term)
1982 size_t len = strlen(string);
1984 if (null_term && len != 255)
1987 if ((p = free_space(mess, end, opt, len)))
1988 memcpy(p, string, len);
1991 /* return length, note this only does the data part */
1992 static int do_opt(struct dhcp_opt *opt, unsigned char *p, struct dhcp_context *context, int null_term)
1996 if ((opt->flags & DHOPT_STRING) && null_term && len != 255)
2001 if (context && (opt->flags & DHOPT_ADDR))
2004 struct in_addr *a = (struct in_addr *)opt->val;
2005 for (j = 0; j < opt->len; j+=INADDRSZ, a++)
2007 /* zero means "self" (but not in vendorclass options.) */
2009 memcpy(p, &context->local, INADDRSZ);
2011 memcpy(p, a, INADDRSZ);
2016 /* empty string may be extended to "\0" by null_term */
2017 memcpy(p, opt->val ? opt->val : (unsigned char *)"", len);
2022 static int in_list(unsigned char *list, int opt)
2026 /* If no requested options, send everything, not nothing. */
2030 for (i = 0; list[i] != OPTION_END; i++)
2037 static struct dhcp_opt *option_find2(int opt)
2039 struct dhcp_opt *opts;
2041 for (opts = daemon->dhcp_opts; opts; opts = opts->next)
2042 if (opts->opt == opt && (opts->flags & DHOPT_TAGOK))
2048 /* mark vendor-encapsulated options which match the client-supplied or
2049 config-supplied vendor class */
2050 static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt)
2052 for (; dopt; dopt = dopt->next)
2054 dopt->flags &= ~DHOPT_VENDOR_MATCH;
2055 if (opt && (dopt->flags & DHOPT_VENDOR))
2057 const struct dhcp_pxe_vendor *pv;
2058 struct dhcp_pxe_vendor dummy_vendor = {
2059 .data = (char *)dopt->u.vendor_class,
2062 if (dopt->flags & DHOPT_VENDOR_PXE)
2063 pv = daemon->dhcp_pxe_vendors;
2066 for (; pv; pv = pv->next)
2068 int i, len = 0, matched = 0;
2070 len = strlen(pv->data);
2071 for (i = 0; i <= (option_len(opt) - len); i++)
2072 if (len == 0 || memcmp(pv->data, option_ptr(opt, i), len) == 0)
2079 dopt->flags |= DHOPT_VENDOR_MATCH;
2087 static int do_encap_opts(struct dhcp_opt *opt, int encap, int flag,
2088 struct dhcp_packet *mess, unsigned char *end, int null_term)
2090 int len, enc_len, ret = 0;
2091 struct dhcp_opt *start;
2094 /* find size in advance */
2095 for (enc_len = 0, start = opt; opt; opt = opt->next)
2096 if (opt->flags & flag)
2098 int new = do_opt(opt, NULL, NULL, null_term) + 2;
2100 if (enc_len + new <= 255)
2104 p = free_space(mess, end, encap, enc_len);
2105 for (; start && start != opt; start = start->next)
2106 if (p && (start->flags & flag))
2108 len = do_opt(start, p + 2, NULL, null_term);
2109 *(p++) = start->opt;
2119 (p = free_space(mess, end, encap, enc_len + 1)))
2121 for (; start; start = start->next)
2122 if (start->flags & flag)
2124 len = do_opt(start, p + 2, NULL, null_term);
2125 *(p++) = start->opt;
2135 static void pxe_misc(struct dhcp_packet *mess, unsigned char *end, unsigned char *uuid, const char *pxevendor)
2140 pxevendor="PXEClient";
2141 option_put_string(mess, end, OPTION_VENDOR_ID, pxevendor, 0);
2142 if (uuid && (p = free_space(mess, end, OPTION_PXE_UUID, 17)))
2143 memcpy(p, uuid, 17);
2146 static int prune_vendor_opts(struct dhcp_netid *netid)
2149 struct dhcp_opt *opt;
2151 /* prune vendor-encapsulated options based on netid, and look if we're forcing them to be sent */
2152 for (opt = daemon->dhcp_opts; opt; opt = opt->next)
2153 if (opt->flags & DHOPT_VENDOR_MATCH)
2155 if (!match_netid(opt->netid, netid, 1))
2156 opt->flags &= ~DHOPT_VENDOR_MATCH;
2157 else if (opt->flags & DHOPT_FORCE)
2164 /* Many UEFI PXE implementations have badly broken menu code.
2165 If there's exactly one relevant menu item, we abandon the menu system,
2166 and jamb the data direct into the DHCP file, siaddr and sname fields.
2167 Note that in this case, we have to assume that layer zero would be requested
2168 by the client PXE stack. */
2169 static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid, struct dhcp_packet *mess, struct in_addr local, time_t now, int pxe)
2171 struct pxe_service *service, *found;
2173 /* Only workaround UEFI archs. */
2177 for (found = NULL, service = daemon->pxe_services; service; service = service->next)
2178 if (pxe_arch == service->CSA && service->basename && match_netid(service->netid, netid, 1))
2181 return 0; /* More than one relevant menu item */
2187 return 0; /* No relevant menu items. */
2194 mess->siaddr = a_record_from_hosts(found->sname, now);
2195 snprintf((char *)mess->sname, sizeof(mess->sname), "%s", found->sname);
2199 if (found->server.s_addr != 0)
2200 mess->siaddr = found->server;
2202 mess->siaddr = local;
2204 inet_ntop(AF_INET, &mess->siaddr, (char *)mess->sname, INET_ADDRSTRLEN);
2207 if (found->basename)
2208 snprintf((char *)mess->file, sizeof(mess->file),
2209 strchr(found->basename, '.') ? "%s" : "%s.0", found->basename);
2214 static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct in_addr local, time_t now)
2218 unsigned char *p, *q;
2219 struct pxe_service *service;
2220 static struct dhcp_opt *o, *ret;
2221 int i, j = NUM_OPTS - 1;
2222 struct in_addr boot_server;
2224 /* We pass back references to these, hence they are declared static */
2225 static unsigned char discovery_control;
2226 static unsigned char fake_prompt[] = { 0, 'P', 'X', 'E' };
2227 static struct dhcp_opt *fake_opts = NULL;
2229 /* Disable multicast, since we don't support it, and broadcast
2230 unless we need it */
2231 discovery_control = 3;
2233 ret = daemon->dhcp_opts;
2235 if (!fake_opts && !(fake_opts = whine_malloc(NUM_OPTS * sizeof(struct dhcp_opt))))
2238 for (i = 0; i < NUM_OPTS; i++)
2240 fake_opts[i].flags = DHOPT_VENDOR_MATCH;
2241 fake_opts[i].netid = NULL;
2242 fake_opts[i].next = i == (NUM_OPTS - 1) ? ret : &fake_opts[i+1];
2245 /* create the data for the PXE_MENU and PXE_SERVERS options. */
2246 p = (unsigned char *)daemon->dhcp_buff;
2247 q = (unsigned char *)daemon->dhcp_buff3;
2249 for (i = 0, service = daemon->pxe_services; service; service = service->next)
2250 if (pxe_arch == service->CSA && match_netid(service->netid, netid, 1))
2252 size_t len = strlen(service->menu);
2253 /* opt 43 max size is 255. encapsulated option has type and length
2254 bytes, so its max size is 253. */
2255 if (p - (unsigned char *)daemon->dhcp_buff + len + 3 < 253)
2257 *(p++) = service->type >> 8;
2258 *(p++) = service->type;
2260 memcpy(p, service->menu, len);
2267 my_syslog(MS_DHCP | LOG_ERR, _("PXE menu too large"));
2268 return daemon->dhcp_opts;
2271 boot_server = service->basename ? local :
2272 (service->sname ? a_record_from_hosts(service->sname, now) : service->server);
2274 if (boot_server.s_addr != 0)
2276 if (q - (unsigned char *)daemon->dhcp_buff3 + 3 + INADDRSZ >= 253)
2279 /* Boot service with known address - give it */
2280 *(q++) = service->type >> 8;
2281 *(q++) = service->type;
2283 /* dest misaligned */
2284 memcpy(q, &boot_server.s_addr, INADDRSZ);
2287 else if (service->type != 0)
2288 /* We don't know the server for a service type, so we'll
2289 allow the client to broadcast for it */
2290 discovery_control = 2;
2293 /* if no prompt, wait forever if there's a choice */
2294 fake_prompt[0] = (i > 1) ? 255 : 0;
2297 discovery_control = 8; /* no menu - just use use mess->filename */
2300 ret = &fake_opts[j--];
2301 ret->len = p - (unsigned char *)daemon->dhcp_buff;
2302 ret->val = (unsigned char *)daemon->dhcp_buff;
2303 ret->opt = SUBOPT_PXE_MENU;
2305 if (q - (unsigned char *)daemon->dhcp_buff3 != 0)
2307 ret = &fake_opts[j--];
2308 ret->len = q - (unsigned char *)daemon->dhcp_buff3;
2309 ret->val = (unsigned char *)daemon->dhcp_buff3;
2310 ret->opt = SUBOPT_PXE_SERVERS;
2314 for (o = daemon->dhcp_opts; o; o = o->next)
2315 if ((o->flags & DHOPT_VENDOR_MATCH) && o->opt == SUBOPT_PXE_MENU_PROMPT)
2320 ret = &fake_opts[j--];
2321 ret->len = sizeof(fake_prompt);
2322 ret->val = fake_prompt;
2323 ret->opt = SUBOPT_PXE_MENU_PROMPT;
2326 ret = &fake_opts[j--];
2328 ret->opt = SUBOPT_PXE_DISCOVERY;
2329 ret->val= &discovery_control;
2334 static void clear_packet(struct dhcp_packet *mess, unsigned char *end)
2336 memset(mess->sname, 0, sizeof(mess->sname));
2337 memset(mess->file, 0, sizeof(mess->file));
2338 memset(&mess->options[0] + sizeof(u32), 0, end - (&mess->options[0] + sizeof(u32)));
2339 mess->siaddr.s_addr = 0;
2342 struct dhcp_boot *find_boot(struct dhcp_netid *netid)
2344 struct dhcp_boot *boot;
2346 /* decide which dhcp-boot option we're using */
2347 for (boot = daemon->boot_config; boot; boot = boot->next)
2348 if (match_netid(boot->netid, netid, 0))
2351 /* No match, look for one without a netid */
2352 for (boot = daemon->boot_config; boot; boot = boot->next)
2353 if (match_netid(boot->netid, netid, 1))
2359 static int is_pxe_client(struct dhcp_packet *mess, size_t sz, const char **pxe_vendor)
2361 const unsigned char *opt = NULL;
2362 ssize_t conf_len = 0;
2363 const struct dhcp_pxe_vendor *conf = daemon->dhcp_pxe_vendors;
2364 opt = option_find(mess, sz, OPTION_VENDOR_ID, 0);
2367 for (; conf; conf = conf->next)
2369 conf_len = strlen(conf->data);
2370 if (option_len(opt) < conf_len)
2372 if (strncmp(option_ptr(opt, 0), conf->data, conf_len) == 0)
2375 *pxe_vendor = conf->data;
2382 static void do_options(struct dhcp_context *context,
2383 struct dhcp_packet *mess,
2385 unsigned char *req_options,
2388 struct dhcp_netid *netid,
2389 struct in_addr subnet_addr,
2390 unsigned char fqdn_flags,
2391 int null_term, int pxe_arch,
2392 unsigned char *uuid,
2393 int vendor_class_len,
2395 unsigned int lease_time,
2396 unsigned short fuzz,
2397 const char *pxevendor)
2399 struct dhcp_opt *opt, *config_opts = daemon->dhcp_opts;
2400 struct dhcp_boot *boot;
2402 int i, len, force_encap = 0;
2403 unsigned char f0 = 0, s0 = 0;
2404 int done_file = 0, done_server = 0;
2405 int done_vendor_class = 0;
2406 struct dhcp_netid *tagif;
2407 struct dhcp_netid_list *id_list;
2409 /* filter options based on tags, those we want get DHOPT_TAGOK bit set */
2411 context->netid.next = NULL;
2412 tagif = option_filter(netid, context && context->netid.net ? &context->netid : NULL, config_opts);
2415 if (option_bool(OPT_LOG_OPTS) && req_options)
2417 char *q = daemon->namebuff;
2418 for (i = 0; req_options[i] != OPTION_END; i++)
2420 char *s = option_string(AF_INET, req_options[i], NULL, 0, NULL, 0);
2421 q += snprintf(q, MAXDNAME - (q - daemon->namebuff),
2424 strlen(s) != 0 ? ":" : "",
2426 req_options[i+1] == OPTION_END ? "" : ", ");
2427 if (req_options[i+1] == OPTION_END || (q - daemon->namebuff) > 40)
2429 q = daemon->namebuff;
2430 my_syslog(MS_DHCP | LOG_INFO, _("%u requested options: %s"), ntohl(mess->xid), daemon->namebuff);
2435 for (id_list = daemon->force_broadcast; id_list; id_list = id_list->next)
2436 if ((!id_list->list) || match_netid(id_list->list, netid, 0))
2439 mess->flags |= htons(0x8000); /* force broadcast */
2442 mess->siaddr = context->local;
2444 /* See if we can send the boot stuff as options.
2445 To do this we need a requested option list, BOOTP
2446 and very old DHCP clients won't have this, we also
2447 provide a manual option to disable it.
2448 Some PXE ROMs have bugs (surprise!) and need zero-terminated
2449 names, so we always send those. */
2450 if ((boot = find_boot(tagif)))
2454 if (!option_bool(OPT_NO_OVERRIDE) &&
2456 in_list(req_options, OPTION_SNAME))
2457 option_put_string(mess, end, OPTION_SNAME, boot->sname, 1);
2459 safe_strncpy((char *)mess->sname, boot->sname, sizeof(mess->sname));
2464 if (!option_bool(OPT_NO_OVERRIDE) &&
2466 in_list(req_options, OPTION_FILENAME))
2467 option_put_string(mess, end, OPTION_FILENAME, boot->file, 1);
2469 safe_strncpy((char *)mess->file, boot->file, sizeof(mess->file));
2472 if (boot->next_server.s_addr)
2473 mess->siaddr = boot->next_server;
2474 else if (boot->tftp_sname)
2475 mess->siaddr = a_record_from_hosts(boot->tftp_sname, now);
2478 /* Use the values of the relevant options if no dhcp-boot given and
2479 they're not explicitly asked for as options. OPTION_END is used
2480 as an internal way to specify siaddr without using dhcp-boot, for use in
2483 if ((!req_options || !in_list(req_options, OPTION_FILENAME)) &&
2484 (opt = option_find2(OPTION_FILENAME)) && !(opt->flags & DHOPT_FORCE))
2486 safe_strncpy((char *)mess->file, (char *)opt->val, sizeof(mess->file));
2490 if ((!req_options || !in_list(req_options, OPTION_SNAME)) &&
2491 (opt = option_find2(OPTION_SNAME)) && !(opt->flags & DHOPT_FORCE))
2493 safe_strncpy((char *)mess->sname, (char *)opt->val, sizeof(mess->sname));
2497 if ((opt = option_find2(OPTION_END)))
2498 mess->siaddr.s_addr = ((struct in_addr *)opt->val)->s_addr;
2501 /* We don't want to do option-overload for BOOTP, so make the file and sname
2502 fields look like they are in use, even when they aren't. This gets restored
2503 at the end of this function. */
2505 if (!req_options || option_bool(OPT_NO_OVERRIDE))
2509 s0 = mess->sname[0];
2513 /* At this point, if mess->sname or mess->file are zeroed, they are available
2514 for option overload, reserve space for the overload option. */
2515 if (mess->file[0] == 0 || mess->sname[0] == 0)
2518 /* rfc3011 says this doesn't need to be in the requested options list. */
2519 if (subnet_addr.s_addr)
2520 option_put(mess, end, OPTION_SUBNET_SELECT, INADDRSZ, ntohl(subnet_addr.s_addr));
2522 if (lease_time != 0xffffffff)
2524 unsigned int t1val = lease_time/2;
2525 unsigned int t2val = (lease_time*7)/8;
2528 /* If set by user, sanity check, so not longer than lease. */
2529 if ((opt = option_find2(OPTION_T1)))
2531 hval = ntohl(*((unsigned int *)opt->val));
2532 if (hval < lease_time && hval > 2)
2536 if ((opt = option_find2(OPTION_T2)))
2538 hval = ntohl(*((unsigned int *)opt->val));
2539 if (hval < lease_time && hval > 2)
2543 /* ensure T1 is still < T2 */
2547 while (fuzz > (t1val/8))
2553 option_put(mess, end, OPTION_T1, 4, t1val);
2554 option_put(mess, end, OPTION_T2, 4, t2val);
2557 /* replies to DHCPINFORM may not have a valid context */
2560 if (!option_find2(OPTION_NETMASK))
2561 option_put(mess, end, OPTION_NETMASK, INADDRSZ, ntohl(context->netmask.s_addr));
2563 /* May not have a "guessed" broadcast address if we got no packets via a relay
2564 from this net yet (ie just unicast renewals after a restart */
2565 if (context->broadcast.s_addr &&
2566 !option_find2(OPTION_BROADCAST))
2567 option_put(mess, end, OPTION_BROADCAST, INADDRSZ, ntohl(context->broadcast.s_addr));
2569 /* Same comments as broadcast apply, and also may not be able to get a sensible
2570 default when using subnet select. User must configure by steam in that case. */
2571 if (context->router.s_addr &&
2572 in_list(req_options, OPTION_ROUTER) &&
2573 !option_find2(OPTION_ROUTER))
2574 option_put(mess, end, OPTION_ROUTER, INADDRSZ, ntohl(context->router.s_addr));
2576 if (daemon->port == NAMESERVER_PORT &&
2577 in_list(req_options, OPTION_DNSSERVER) &&
2578 !option_find2(OPTION_DNSSERVER))
2579 option_put(mess, end, OPTION_DNSSERVER, INADDRSZ, ntohl(context->local.s_addr));
2582 if (domain && in_list(req_options, OPTION_DOMAINNAME) &&
2583 !option_find2(OPTION_DOMAINNAME))
2584 option_put_string(mess, end, OPTION_DOMAINNAME, domain, null_term);
2586 /* Note that we ignore attempts to set the fqdn using --dhc-option=81,<name> */
2589 if (in_list(req_options, OPTION_HOSTNAME) &&
2590 !option_find2(OPTION_HOSTNAME))
2591 option_put_string(mess, end, OPTION_HOSTNAME, hostname, null_term);
2593 if (fqdn_flags != 0)
2595 len = strlen(hostname) + 3;
2597 if (fqdn_flags & 0x04)
2603 len += strlen(domain) + 1;
2604 else if (fqdn_flags & 0x04)
2607 if ((p = free_space(mess, end, OPTION_CLIENT_FQDN, len)))
2609 *(p++) = fqdn_flags & 0x0f; /* MBZ bits to zero */
2613 if (fqdn_flags & 0x04)
2615 p = do_rfc1035_name(p, hostname, NULL);
2618 p = do_rfc1035_name(p, domain, NULL);
2624 memcpy(p, hostname, strlen(hostname));
2625 p += strlen(hostname);
2629 memcpy(p, domain, strlen(domain));
2630 p += strlen(domain);
2639 for (opt = config_opts; opt; opt = opt->next)
2641 int optno = opt->opt;
2643 /* netids match and not encapsulated? */
2644 if (!(opt->flags & DHOPT_TAGOK))
2647 /* was it asked for, or are we sending it anyway? */
2648 if (!(opt->flags & DHOPT_FORCE) && !in_list(req_options, optno))
2651 /* prohibit some used-internally options. T1 and T2 already handled. */
2652 if (optno == OPTION_CLIENT_FQDN ||
2653 optno == OPTION_MAXMESSAGE ||
2654 optno == OPTION_OVERLOAD ||
2655 optno == OPTION_PAD ||
2656 optno == OPTION_END ||
2657 optno == OPTION_T1 ||
2661 if (optno == OPTION_SNAME && done_server)
2664 if (optno == OPTION_FILENAME && done_file)
2667 /* For the options we have default values on
2668 dhc-option=<optionno> means "don't include this option"
2669 not "include a zero-length option" */
2670 if (opt->len == 0 &&
2671 (optno == OPTION_NETMASK ||
2672 optno == OPTION_BROADCAST ||
2673 optno == OPTION_ROUTER ||
2674 optno == OPTION_DNSSERVER ||
2675 optno == OPTION_DOMAINNAME ||
2676 optno == OPTION_HOSTNAME))
2679 /* vendor-class comes from elsewhere for PXE */
2680 if (pxe_arch != -1 && optno == OPTION_VENDOR_ID)
2683 /* always force null-term for filename and servername - buggy PXE again. */
2684 len = do_opt(opt, NULL, context,
2685 (optno == OPTION_SNAME || optno == OPTION_FILENAME) ? 1 : null_term);
2687 if ((p = free_space(mess, end, optno, len)))
2689 do_opt(opt, p, context,
2690 (optno == OPTION_SNAME || optno == OPTION_FILENAME) ? 1 : null_term);
2692 /* If we send a vendor-id, revisit which vendor-ops we consider
2693 it appropriate to send. */
2694 if (optno == OPTION_VENDOR_ID)
2696 match_vendor_opts(p - 2, config_opts);
2697 done_vendor_class = 1;
2702 /* Now send options to be encapsulated in arbitrary options,
2703 eg dhcp-option=encap:172,17,.......
2704 Also handle vendor-identifying vendor-encapsulated options,
2705 dhcp-option = vi-encap:13,17,.......
2706 The may be more that one "outer" to do, so group
2707 all the options which match each outer in turn. */
2708 for (opt = config_opts; opt; opt = opt->next)
2709 opt->flags &= ~DHOPT_ENCAP_DONE;
2711 for (opt = config_opts; opt; opt = opt->next)
2715 if ((flags = (opt->flags & (DHOPT_ENCAPSULATE | DHOPT_RFC3925))))
2720 if (opt->flags & DHOPT_ENCAP_DONE)
2723 for (len = 0, o = config_opts; o; o = o->next)
2725 int outer = flags & DHOPT_ENCAPSULATE ? o->u.encap : OPTION_VENDOR_IDENT_OPT;
2727 o->flags &= ~DHOPT_ENCAP_MATCH;
2729 if (!(o->flags & flags) || opt->u.encap != o->u.encap)
2732 o->flags |= DHOPT_ENCAP_DONE;
2733 if (match_netid(o->netid, tagif, 1) &&
2734 ((o->flags & DHOPT_FORCE) || in_list(req_options, outer)))
2736 o->flags |= DHOPT_ENCAP_MATCH;
2738 len += do_opt(o, NULL, NULL, 0) + 2;
2744 if (flags & DHOPT_ENCAPSULATE)
2745 do_encap_opts(config_opts, opt->u.encap, DHOPT_ENCAP_MATCH, mess, end, null_term);
2747 my_syslog(MS_DHCP | LOG_WARNING, _("cannot send RFC3925 option: too many options for enterprise number %d"), opt->u.encap);
2748 else if ((p = free_space(mess, end, OPTION_VENDOR_IDENT_OPT, len + 5)))
2750 int swap_ent = htonl(opt->u.encap);
2751 memcpy(p, &swap_ent, 4);
2754 for (o = config_opts; o; o = o->next)
2755 if (o->flags & DHOPT_ENCAP_MATCH)
2757 len = do_opt(o, p + 2, NULL, 0);
2767 force_encap = prune_vendor_opts(tagif);
2769 if (context && pxe_arch != -1)
2771 pxe_misc(mess, end, uuid, pxevendor);
2772 if (!pxe_uefi_workaround(pxe_arch, tagif, mess, context->local, now, 0))
2773 config_opts = pxe_opts(pxe_arch, tagif, context->local, now);
2776 if ((force_encap || in_list(req_options, OPTION_VENDOR_CLASS_OPT)) &&
2777 do_encap_opts(config_opts, OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, null_term) &&
2778 pxe_arch == -1 && !done_vendor_class && vendor_class_len != 0 &&
2779 (p = free_space(mess, end, OPTION_VENDOR_ID, vendor_class_len)))
2780 /* If we send vendor encapsulated options, and haven't already sent option 60,
2781 echo back the value we got from the client. */
2782 memcpy(p, daemon->dhcp_buff3, vendor_class_len);
2784 /* restore BOOTP anti-overload hack */
2785 if (!req_options || option_bool(OPT_NO_OVERRIDE))
2788 mess->sname[0] = s0;
2792 static void apply_delay(u32 xid, time_t recvtime, struct dhcp_netid *netid)
2794 struct delay_config *delay_conf;
2796 /* Decide which delay_config option we're using */
2797 for (delay_conf = daemon->delay_conf; delay_conf; delay_conf = delay_conf->next)
2798 if (match_netid(delay_conf->netid, netid, 0))
2802 /* No match, look for one without a netid */
2803 for (delay_conf = daemon->delay_conf; delay_conf; delay_conf = delay_conf->next)
2804 if (match_netid(delay_conf->netid, netid, 1))
2809 if (!option_bool(OPT_QUIET_DHCP))
2810 my_syslog(MS_DHCP | LOG_INFO, _("%u reply delay: %d"), ntohl(xid), delay_conf->delay);
2811 delay_dhcp(recvtime, delay_conf->delay, -1, 0, 0);
2815 #endif /* HAVE_DHCP */