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/>.
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
, 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 i
, int size
);
36 static void log_packet(char *type
, void *addr
, unsigned char *ext_mac
,
37 int mac_len
, char *interface
, char *string
, 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
,
45 unsigned char *real_end
,
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 pxearch
,
58 static void match_vendor_opts(unsigned char *opt
, struct dhcp_opt
*dopt
);
59 static int do_encap_opts(struct dhcp_opt
*opts
, int encap
, int flag
, struct dhcp_packet
*mess
, unsigned char *end
, int null_term
);
60 static void pxe_misc(struct dhcp_packet
*mess
, unsigned char *end
, unsigned char *uuid
);
61 static int prune_vendor_opts(struct dhcp_netid
*netid
);
62 static struct dhcp_opt
*pxe_opts(int pxe_arch
, struct dhcp_netid
*netid
, struct in_addr local
, time_t now
);
63 struct dhcp_boot
*find_boot(struct dhcp_netid
*netid
);
66 size_t dhcp_reply(struct dhcp_context
*context
, char *iface_name
, int int_index
,
67 size_t sz
, time_t now
, int unicast_dest
, int *is_inform
, int pxe
, struct in_addr fallback
)
69 unsigned char *opt
, *clid
= NULL
;
70 struct dhcp_lease
*ltmp
, *lease
= NULL
;
71 struct dhcp_vendor
*vendor
;
73 struct dhcp_netid_list
*id_list
;
74 int clid_len
= 0, ignore
= 0, do_classes
= 0, selecting
= 0, pxearch
= -1;
75 struct dhcp_packet
*mess
= (struct dhcp_packet
*)daemon
->dhcp_packet
.iov_base
;
76 unsigned char *end
= (unsigned char *)(mess
+ 1);
77 unsigned char *real_end
= (unsigned char *)(mess
+ 1);
78 char *hostname
= NULL
, *offer_hostname
= NULL
, *client_hostname
= NULL
, *domain
= NULL
;
79 int hostname_auth
= 0, borken_opt
= 0;
80 unsigned char *req_options
= NULL
;
83 struct dhcp_config
*config
;
84 struct dhcp_netid
*netid
, *tagif_netid
;
85 struct in_addr subnet_addr
, override
;
86 unsigned short fuzz
= 0;
87 unsigned int mess_type
= 0;
88 unsigned char fqdn_flags
= 0;
89 unsigned char *agent_id
= NULL
, *uuid
= NULL
;
90 unsigned char *emac
= NULL
;
91 int vendor_class_len
= 0, emac_len
= 0;
92 struct dhcp_netid known_id
, iface_id
, cpewan_id
;
94 unsigned char pxe_uuid
[17];
95 unsigned char *oui
= NULL
, *serial
= NULL
, *class = NULL
;
97 subnet_addr
.s_addr
= override
.s_addr
= 0;
99 /* set tag with name == interface */
100 iface_id
.net
= iface_name
;
101 iface_id
.next
= NULL
;
104 if (mess
->op
!= BOOTREQUEST
|| mess
->hlen
> DHCP_CHADDR_MAX
)
107 if (mess
->htype
== 0 && mess
->hlen
!= 0)
110 /* check for DHCP rather than BOOTP */
111 if ((opt
= option_find(mess
, sz
, OPTION_MESSAGE_TYPE
, 1)))
113 u32 cookie
= htonl(DHCP_COOKIE
);
115 /* only insist on a cookie for DHCP. */
116 if (memcmp(mess
->options
, &cookie
, sizeof(u32
)) != 0)
119 mess_type
= option_uint(opt
, 0, 1);
121 /* two things to note here: expand_buf may move the packet,
122 so reassign mess from daemon->packet. Also, the size
123 sent includes the IP and UDP headers, hence the magic "-28" */
124 if ((opt
= option_find(mess
, sz
, OPTION_MAXMESSAGE
, 2)))
126 size_t size
= (size_t)option_uint(opt
, 0, 2) - 28;
128 if (size
> DHCP_PACKET_MAX
)
129 size
= DHCP_PACKET_MAX
;
130 else if (size
< sizeof(struct dhcp_packet
))
131 size
= sizeof(struct dhcp_packet
);
133 if (expand_buf(&daemon
->dhcp_packet
, size
))
135 mess
= (struct dhcp_packet
*)daemon
->dhcp_packet
.iov_base
;
136 real_end
= end
= ((unsigned char *)mess
) + size
;
140 /* Some buggy clients set ciaddr when they shouldn't, so clear that here since
141 it can affect the context-determination code. */
142 if ((option_find(mess
, sz
, OPTION_REQUESTED_IP
, INADDRSZ
) || mess_type
== DHCPDISCOVER
))
143 mess
->ciaddr
.s_addr
= 0;
145 /* search for device identity from CPEWAN devices, we pass this through to the script */
146 if ((opt
= option_find(mess
, sz
, OPTION_VENDOR_IDENT_OPT
, 5)))
148 unsigned int elen
, offset
, len
= option_len(opt
);
150 for (offset
= 0; offset
< (len
- 5); offset
+= elen
+ 5)
152 elen
= option_uint(opt
, offset
+ 4 , 1);
153 if (option_uint(opt
, offset
, 4) == BRDBAND_FORUM_IANA
)
155 unsigned char *x
= option_ptr(opt
, offset
+ 5);
156 unsigned char *y
= option_ptr(opt
, offset
+ elen
+ 5);
157 oui
= option_find1(x
, y
, 1, 1);
158 serial
= option_find1(x
, y
, 2, 1);
159 class = option_find1(x
, y
, 3, 1);
161 /* If TR069-id is present set the tag "cpewan-id" to facilitate echoing
162 the gateway id back. Note that the device class is optional */
165 cpewan_id
.net
= "cpewan-id";
166 cpewan_id
.next
= netid
;
174 if ((opt
= option_find(mess
, sz
, OPTION_AGENT_ID
, 1)))
176 /* Any agent-id needs to be copied back out, verbatim, as the last option
177 in the packet. Here, we shift it to the very end of the buffer, if it doesn't
178 get overwritten, then it will be shuffled back at the end of processing.
179 Note that the incoming options must not be overwritten here, so there has to
180 be enough free space at the end of the packet to copy the option. */
182 unsigned int total
= option_len(opt
) + 2;
183 unsigned char *last_opt
= option_find(mess
, sz
, OPTION_END
, 0);
184 if (last_opt
&& last_opt
< end
- total
)
188 memcpy(agent_id
, opt
, total
);
191 /* look for RFC3527 Link selection sub-option */
192 if ((sopt
= option_find1(option_ptr(opt
, 0), option_ptr(opt
, option_len(opt
)), SUBOPT_SUBNET_SELECT
, INADDRSZ
)))
193 subnet_addr
= option_addr(sopt
);
195 /* look for RFC5107 server-identifier-override */
196 if ((sopt
= option_find1(option_ptr(opt
, 0), option_ptr(opt
, option_len(opt
)), SUBOPT_SERVER_OR
, INADDRSZ
)))
197 override
= option_addr(sopt
);
199 /* if a circuit-id or remote-is option is provided, exact-match to options. */
200 for (vendor
= daemon
->dhcp_vendors
; vendor
; vendor
= vendor
->next
)
204 if (vendor
->match_type
== MATCH_CIRCUIT
)
205 search
= SUBOPT_CIRCUIT_ID
;
206 else if (vendor
->match_type
== MATCH_REMOTE
)
207 search
= SUBOPT_REMOTE_ID
;
208 else if (vendor
->match_type
== MATCH_SUBSCRIBER
)
209 search
= SUBOPT_SUBSCR_ID
;
213 if ((sopt
= option_find1(option_ptr(opt
, 0), option_ptr(opt
, option_len(opt
)), search
, 1)) &&
214 vendor
->len
== option_len(sopt
) &&
215 memcmp(option_ptr(sopt
, 0), vendor
->data
, vendor
->len
) == 0)
217 vendor
->netid
.next
= netid
;
218 netid
= &vendor
->netid
;
223 /* Check for RFC3011 subnet selector - only if RFC3527 one not present */
224 if (subnet_addr
.s_addr
== 0 && (opt
= option_find(mess
, sz
, OPTION_SUBNET_SELECT
, INADDRSZ
)))
225 subnet_addr
= option_addr(opt
);
227 /* If there is no client identifier option, use the hardware address */
228 if ((opt
= option_find(mess
, sz
, OPTION_CLIENT_ID
, 1)))
230 clid_len
= option_len(opt
);
231 clid
= option_ptr(opt
, 0);
234 /* do we have a lease in store? */
235 lease
= lease_find_by_client(mess
->chaddr
, mess
->hlen
, mess
->htype
, clid
, clid_len
);
237 /* If this request is missing a clid, but we've seen one before,
238 use it again for option matching etc. */
239 if (lease
&& !clid
&& lease
->clid
)
241 clid_len
= lease
->clid_len
;
245 /* find mac to use for logging and hashing */
246 emac
= extended_hwaddr(mess
->htype
, mess
->hlen
, mess
->chaddr
, clid_len
, clid
, &emac_len
);
249 for (mac
= daemon
->dhcp_macs
; mac
; mac
= mac
->next
)
250 if (mac
->hwaddr_len
== mess
->hlen
&&
251 (mac
->hwaddr_type
== mess
->htype
|| mac
->hwaddr_type
== 0) &&
252 memcmp_masked(mac
->hwaddr
, mess
->chaddr
, mess
->hlen
, mac
->mask
))
254 mac
->netid
.next
= netid
;
258 /* Determine network for this packet. Our caller will have already linked all the
259 contexts which match the addresses of the receiving interface but if the
260 machine has an address already, or came via a relay, or we have a subnet selector,
261 we search again. If we don't have have a giaddr or explicit subnet selector,
262 use the ciaddr. This is necessary because a machine which got a lease via a
263 relay won't use the relay to renew. If matching a ciaddr fails but we have a context
264 from the physical network, continue using that to allow correct DHCPNAK generation later. */
265 if (mess
->giaddr
.s_addr
|| subnet_addr
.s_addr
|| mess
->ciaddr
.s_addr
)
267 struct dhcp_context
*context_tmp
, *context_new
= NULL
;
271 if (subnet_addr
.s_addr
)
276 else if (mess
->giaddr
.s_addr
)
283 /* If ciaddr is in the hardware derived set of contexts, leave that unchanged */
285 for (context_tmp
= context
; context_tmp
; context_tmp
= context_tmp
->current
)
286 if (context_tmp
->netmask
.s_addr
&&
287 is_same_net(addr
, context_tmp
->start
, context_tmp
->netmask
) &&
288 is_same_net(addr
, context_tmp
->end
, context_tmp
->netmask
))
290 context_new
= context
;
296 for (context_tmp
= daemon
->dhcp
; context_tmp
; context_tmp
= context_tmp
->next
)
298 struct in_addr netmask
= context_tmp
->netmask
;
300 /* guess the netmask for relayed networks */
301 if (!(context_tmp
->flags
& CONTEXT_NETMASK
) && context_tmp
->netmask
.s_addr
== 0)
303 if (IN_CLASSA(ntohl(context_tmp
->start
.s_addr
)) && IN_CLASSA(ntohl(context_tmp
->end
.s_addr
)))
304 netmask
.s_addr
= htonl(0xff000000);
305 else if (IN_CLASSB(ntohl(context_tmp
->start
.s_addr
)) && IN_CLASSB(ntohl(context_tmp
->end
.s_addr
)))
306 netmask
.s_addr
= htonl(0xffff0000);
307 else if (IN_CLASSC(ntohl(context_tmp
->start
.s_addr
)) && IN_CLASSC(ntohl(context_tmp
->end
.s_addr
)))
308 netmask
.s_addr
= htonl(0xffffff00);
311 /* This section fills in context mainly when a client which is on a remote (relayed)
312 network renews a lease without using the relay, after dnsmasq has restarted. */
313 if (netmask
.s_addr
!= 0 &&
314 is_same_net(addr
, context_tmp
->start
, netmask
) &&
315 is_same_net(addr
, context_tmp
->end
, netmask
))
317 context_tmp
->netmask
= netmask
;
318 if (context_tmp
->local
.s_addr
== 0)
319 context_tmp
->local
= fallback
;
320 if (context_tmp
->router
.s_addr
== 0)
321 context_tmp
->router
= mess
->giaddr
;
323 /* fill in missing broadcast addresses for relayed ranges */
324 if (!(context_tmp
->flags
& CONTEXT_BRDCAST
) && context_tmp
->broadcast
.s_addr
== 0 )
325 context_tmp
->broadcast
.s_addr
= context_tmp
->start
.s_addr
| ~context_tmp
->netmask
.s_addr
;
327 context_tmp
->current
= context_new
;
328 context_new
= context_tmp
;
332 if (context_new
|| force
)
333 context
= context_new
;
338 my_syslog(MS_DHCP
| LOG_WARNING
, _("no address range available for DHCP request %s %s"),
339 subnet_addr
.s_addr
? _("with subnet selector") : _("via"),
340 subnet_addr
.s_addr
? inet_ntoa(subnet_addr
) : (mess
->giaddr
.s_addr
? inet_ntoa(mess
->giaddr
) : iface_name
));
344 if (option_bool(OPT_LOG_OPTS
))
346 struct dhcp_context
*context_tmp
;
347 for (context_tmp
= context
; context_tmp
; context_tmp
= context_tmp
->current
)
349 strcpy(daemon
->namebuff
, inet_ntoa(context_tmp
->start
));
350 if (context_tmp
->flags
& (CONTEXT_STATIC
| CONTEXT_PROXY
))
351 my_syslog(MS_DHCP
| LOG_INFO
, _("%u available DHCP subnet: %s/%s"),
352 ntohl(mess
->xid
), daemon
->namebuff
, inet_ntoa(context_tmp
->netmask
));
354 my_syslog(MS_DHCP
| LOG_INFO
, _("%u available DHCP range: %s -- %s"),
355 ntohl(mess
->xid
), daemon
->namebuff
, inet_ntoa(context_tmp
->end
));
359 /* dhcp-match. If we have hex-and-wildcards, look for a left-anchored match.
360 Otherwise assume the option is an array, and look for a matching element.
361 If no data given, existance of the option is enough. This code handles
362 rfc3925 V-I classes too. */
363 for (o
= daemon
->dhcp_match
; o
; o
= o
->next
)
365 unsigned int len
, elen
, match
= 0;
368 if (o
->flags
& DHOPT_RFC3925
)
370 if (!(opt
= option_find(mess
, sz
, OPTION_VENDOR_IDENT
, 5)))
373 for (offset
= 0; offset
< (option_len(opt
) - 5u); offset
+= len
+ 5)
375 len
= option_uint(opt
, offset
+ 4 , 1);
376 /* Need to take care that bad data can't run us off the end of the packet */
377 if ((offset
+ len
+ 5 <= (option_len(opt
))) &&
378 (option_uint(opt
, offset
, 4) == (unsigned int)o
->u
.encap
))
379 for (o2
= offset
+ 5; o2
< offset
+ len
+ 5; o2
+= elen
+ 1)
381 elen
= option_uint(opt
, o2
, 1);
382 if ((o2
+ elen
+ 1 <= option_len(opt
)) &&
383 (match
= match_bytes(o
, option_ptr(opt
, o2
+ 1), elen
)))
392 if (!(opt
= option_find(mess
, sz
, o
->opt
, 1)))
395 match
= match_bytes(o
, option_ptr(opt
, 0), option_len(opt
));
400 o
->netid
->next
= netid
;
405 /* user-class options are, according to RFC3004, supposed to contain
406 a set of counted strings. Here we check that this is so (by seeing
407 if the counts are consistent with the overall option length) and if
408 so zero the counts so that we don't get spurious matches between
409 the vendor string and the counts. If the lengths don't add up, we
410 assume that the option is a single string and non RFC3004 compliant
411 and just do the substring match. dhclient provides these broken options.
412 The code, later, which sends user-class data to the lease-change script
413 relies on the transformation done here.
416 if ((opt
= option_find(mess
, sz
, OPTION_USER_CLASS
, 1)))
418 unsigned char *ucp
= option_ptr(opt
, 0);
420 for (j
= 0; j
< option_len(opt
); j
+= ucp
[j
] + 1);
421 if (j
== option_len(opt
))
422 for (j
= 0; j
< option_len(opt
); j
= tmp
)
424 tmp
= j
+ ucp
[j
] + 1;
429 for (vendor
= daemon
->dhcp_vendors
; vendor
; vendor
= vendor
->next
)
433 if (vendor
->match_type
== MATCH_VENDOR
)
434 mopt
= OPTION_VENDOR_ID
;
435 else if (vendor
->match_type
== MATCH_USER
)
436 mopt
= OPTION_USER_CLASS
;
440 if ((opt
= option_find(mess
, sz
, mopt
, 1)))
443 for (i
= 0; i
<= (option_len(opt
) - vendor
->len
); i
++)
444 if (memcmp(vendor
->data
, option_ptr(opt
, i
), vendor
->len
) == 0)
446 vendor
->netid
.next
= netid
;
447 netid
= &vendor
->netid
;
453 /* mark vendor-encapsulated options which match the client-supplied vendor class,
454 save client-supplied vendor class */
455 if ((opt
= option_find(mess
, sz
, OPTION_VENDOR_ID
, 1)))
457 memcpy(daemon
->dhcp_buff3
, option_ptr(opt
, 0), option_len(opt
));
458 vendor_class_len
= option_len(opt
);
460 match_vendor_opts(opt
, daemon
->dhcp_opts
);
462 if (option_bool(OPT_LOG_OPTS
))
464 if (sanitise(opt
, daemon
->namebuff
))
465 my_syslog(MS_DHCP
| LOG_INFO
, _("%u vendor class: %s"), ntohl(mess
->xid
), daemon
->namebuff
);
466 if (sanitise(option_find(mess
, sz
, OPTION_USER_CLASS
, 1), daemon
->namebuff
))
467 my_syslog(MS_DHCP
| LOG_INFO
, _("%u user class: %s"), ntohl(mess
->xid
), daemon
->namebuff
);
470 mess
->op
= BOOTREPLY
;
472 config
= find_config(daemon
->dhcp_conf
, context
, clid
, clid_len
,
473 mess
->chaddr
, mess
->hlen
, mess
->htype
, NULL
);
475 /* set "known" tag for known hosts */
478 known_id
.net
= "known";
479 known_id
.next
= netid
;
483 if (mess_type
== 0 && !pxe
)
486 struct dhcp_netid id
, bootp_id
;
487 struct in_addr
*logaddr
= NULL
;
489 /* must have a MAC addr for bootp */
490 if (mess
->htype
== 0 || mess
->hlen
== 0 || (context
->flags
& CONTEXT_PROXY
))
493 if (have_config(config
, CONFIG_DISABLE
))
494 message
= _("disabled");
496 end
= mess
->options
+ 64; /* BOOTP vend area is only 64 bytes */
498 if (have_config(config
, CONFIG_NAME
))
500 hostname
= config
->hostname
;
501 domain
= config
->domain
;
506 struct dhcp_netid_list
*list
;
508 for (list
= config
->netid
; list
; list
= list
->next
)
510 list
->list
->next
= netid
;
515 /* Match incoming filename field as a netid. */
518 memcpy(daemon
->dhcp_buff2
, mess
->file
, sizeof(mess
->file
));
519 daemon
->dhcp_buff2
[sizeof(mess
->file
) + 1] = 0; /* ensure zero term. */
520 id
.net
= (char *)daemon
->dhcp_buff2
;
525 /* Add "bootp" as a tag to allow different options, address ranges etc
527 bootp_id
.net
= "bootp";
528 bootp_id
.next
= netid
;
531 tagif_netid
= run_tag_if(netid
);
533 for (id_list
= daemon
->dhcp_ignore
; id_list
; id_list
= id_list
->next
)
534 if (match_netid(id_list
->list
, tagif_netid
, 0))
535 message
= _("ignored");
541 if (have_config(config
, CONFIG_ADDR
))
544 logaddr
= &config
->addr
;
545 mess
->yiaddr
= config
->addr
;
546 if ((lease
= lease_find_by_addr(config
->addr
)) &&
547 (lease
->hwaddr_len
!= mess
->hlen
||
548 lease
->hwaddr_type
!= mess
->htype
||
549 memcmp(lease
->hwaddr
, mess
->chaddr
, lease
->hwaddr_len
) != 0))
550 message
= _("address in use");
554 if (!(lease
= lease_find_by_client(mess
->chaddr
, mess
->hlen
, mess
->htype
, NULL
, 0)) ||
555 !address_available(context
, lease
->addr
, tagif_netid
))
559 /* lease exists, wrong network. */
560 lease_prune(lease
, now
);
563 if (!address_allocate(context
, &mess
->yiaddr
, mess
->chaddr
, mess
->hlen
, tagif_netid
, now
))
564 message
= _("no address available");
567 mess
->yiaddr
= lease
->addr
;
570 if (!message
&& !(context
= narrow_context(context
, mess
->yiaddr
, netid
)))
571 message
= _("wrong network");
572 else if (context
->netid
.net
)
574 context
->netid
.next
= netid
;
575 tagif_netid
= run_tag_if(&context
->netid
);
578 log_tags(tagif_netid
, ntohl(mess
->xid
));
580 if (!message
&& !nailed
)
582 for (id_list
= daemon
->bootp_dynamic
; id_list
; id_list
= id_list
->next
)
583 if ((!id_list
->list
) || match_netid(id_list
->list
, tagif_netid
, 0))
586 message
= _("no address configured");
591 (!(lease
= lease4_allocate(mess
->yiaddr
))))
592 message
= _("no leases left");
596 logaddr
= &mess
->yiaddr
;
598 lease_set_hwaddr(lease
, mess
->chaddr
, NULL
, mess
->hlen
, mess
->htype
, 0, now
, 1);
600 lease_set_hostname(lease
, hostname
, 1, get_domain(lease
->addr
), domain
);
601 /* infinite lease unless nailed in dhcp-host line. */
602 lease_set_expires(lease
,
603 have_config(config
, CONFIG_TIME
) ? config
->lease_time
: 0xffffffff,
605 lease_set_interface(lease
, int_index
, now
);
607 clear_packet(mess
, end
);
608 do_options(context
, mess
, end
, NULL
, hostname
, get_domain(mess
->yiaddr
),
609 netid
, subnet_addr
, 0, 0, -1, NULL
, vendor_class_len
, now
);
613 log_packet("BOOTP", logaddr
, mess
->chaddr
, mess
->hlen
, iface_name
, message
, mess
->xid
);
615 return message
? 0 : dhcp_packet_size(mess
, agent_id
, real_end
);
618 if ((opt
= option_find(mess
, sz
, OPTION_CLIENT_FQDN
, 4)))
620 /* http://tools.ietf.org/wg/dhc/draft-ietf-dhc-fqdn-option/draft-ietf-dhc-fqdn-option-10.txt */
621 int len
= option_len(opt
);
622 char *pq
= daemon
->dhcp_buff
;
623 unsigned char *pp
, *op
= option_ptr(opt
, 0);
630 /* NB, the following always sets at least one bit */
631 if (option_bool(OPT_FQDN_UPDATE
))
633 if (fqdn_flags
& 0x01)
635 fqdn_flags
|= 0x02; /* set O */
636 fqdn_flags
&= ~0x01; /* clear S */
638 fqdn_flags
|= 0x08; /* set N */
642 if (!(fqdn_flags
& 0x01))
643 fqdn_flags
|= 0x03; /* set S and O */
644 fqdn_flags
&= ~0x08; /* clear N */
647 if (fqdn_flags
& 0x04)
648 while (*op
!= 0 && ((op
+ (*op
) + 1) - pp
) < len
)
650 memcpy(pq
, op
+1, *op
);
658 if (len
> 0 && op
[len
-1] == 0)
663 if (pq
!= daemon
->dhcp_buff
)
668 if (legal_hostname(daemon
->dhcp_buff
))
669 offer_hostname
= client_hostname
= daemon
->dhcp_buff
;
671 else if ((opt
= option_find(mess
, sz
, OPTION_HOSTNAME
, 1)))
673 int len
= option_len(opt
);
674 memcpy(daemon
->dhcp_buff
, option_ptr(opt
, 0), len
);
675 /* Microsoft clients are broken, and need zero-terminated strings
676 in options. We detect this state here, and do the same in
677 any options we send */
678 if (len
> 0 && daemon
->dhcp_buff
[len
-1] == 0)
681 daemon
->dhcp_buff
[len
] = 0;
682 if (legal_hostname(daemon
->dhcp_buff
))
683 client_hostname
= daemon
->dhcp_buff
;
686 if (client_hostname
&& option_bool(OPT_LOG_OPTS
))
687 my_syslog(MS_DHCP
| LOG_INFO
, _("%u client provides name: %s"), ntohl(mess
->xid
), client_hostname
);
689 if (have_config(config
, CONFIG_NAME
))
691 hostname
= config
->hostname
;
692 domain
= config
->domain
;
694 /* be careful not to send an OFFER with a hostname not matching the DISCOVER. */
695 if (fqdn_flags
!= 0 || !client_hostname
|| hostname_isequal(hostname
, client_hostname
))
696 offer_hostname
= hostname
;
698 else if (client_hostname
)
700 domain
= strip_hostname(client_hostname
);
702 if (strlen(client_hostname
) != 0)
704 hostname
= client_hostname
;
707 /* Search again now we have a hostname.
708 Only accept configs without CLID and HWADDR here, (they won't match)
709 to avoid impersonation by name. */
710 struct dhcp_config
*new = find_config(daemon
->dhcp_conf
, context
, NULL
, 0,
711 mess
->chaddr
, mess
->hlen
,
712 mess
->htype
, hostname
);
713 if (new && !have_config(new, CONFIG_CLID
) && !new->hwaddr
)
716 /* set "known" tag for known hosts */
717 known_id
.net
= "known";
718 known_id
.next
= netid
;
727 struct dhcp_netid_list
*list
;
729 for (list
= config
->netid
; list
; list
= list
->next
)
731 list
->list
->next
= netid
;
736 tagif_netid
= run_tag_if(netid
);
738 /* if all the netids in the ignore list are present, ignore this client */
739 for (id_list
= daemon
->dhcp_ignore
; id_list
; id_list
= id_list
->next
)
740 if (match_netid(id_list
->list
, tagif_netid
, 0))
743 /* If configured, we can override the server-id to be the address of the relay,
744 so that all traffic goes via the relay and can pick up agent-id info. This can be
745 configured for all relays, or by address. */
746 if (daemon
->override
&& mess
->giaddr
.s_addr
!= 0 && override
.s_addr
== 0)
748 if (!daemon
->override_relays
)
749 override
= mess
->giaddr
;
753 for (l
= daemon
->override_relays
; l
; l
= l
->next
)
754 if (l
->addr
.s_addr
== mess
->giaddr
.s_addr
)
757 override
= mess
->giaddr
;
761 /* Can have setting to ignore the client ID for a particular MAC address or hostname */
762 if (have_config(config
, CONFIG_NOCLID
))
765 /* Check if client is PXE client. */
766 if (daemon
->enable_pxe
&&
767 (opt
= option_find(mess
, sz
, OPTION_VENDOR_ID
, 9)) &&
768 strncmp(option_ptr(opt
, 0), "PXEClient", 9) == 0)
770 if ((opt
= option_find(mess
, sz
, OPTION_PXE_UUID
, 17)))
772 memcpy(pxe_uuid
, option_ptr(opt
, 0), 17);
776 /* Check if this is really a PXE bootserver request, and handle specially if so. */
777 if ((mess_type
== DHCPREQUEST
|| mess_type
== DHCPINFORM
) &&
778 (opt
= option_find(mess
, sz
, OPTION_VENDOR_CLASS_OPT
, 1)) &&
779 (opt
= option_find1(option_ptr(opt
, 0), option_ptr(opt
, option_len(opt
)), SUBOPT_PXE_BOOT_ITEM
, 4)))
781 struct pxe_service
*service
;
782 int type
= option_uint(opt
, 0, 2);
783 int layer
= option_uint(opt
, 2, 2);
784 unsigned char save71
[4];
785 struct dhcp_opt opt71
;
792 my_syslog(MS_DHCP
| LOG_ERR
, _("PXE BIS not supported"));
796 memcpy(save71
, option_ptr(opt
, 0), 4);
798 for (service
= daemon
->pxe_services
; service
; service
= service
->next
)
799 if (service
->type
== type
)
802 if (!service
|| !service
->basename
)
805 clear_packet(mess
, end
);
807 mess
->yiaddr
= mess
->ciaddr
;
808 mess
->ciaddr
.s_addr
= 0;
810 mess
->siaddr
= a_record_from_hosts(service
->sname
, now
);
811 else if (service
->server
.s_addr
!= 0)
812 mess
->siaddr
= service
->server
;
814 mess
->siaddr
= context
->local
;
816 snprintf((char *)mess
->file
, sizeof(mess
->file
), "%s.%d", service
->basename
, layer
);
817 option_put(mess
, end
, OPTION_MESSAGE_TYPE
, 1, DHCPACK
);
818 option_put(mess
, end
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
, htonl(context
->local
.s_addr
));
819 pxe_misc(mess
, end
, uuid
);
821 prune_vendor_opts(tagif_netid
);
823 opt71
.opt
= SUBOPT_PXE_BOOT_ITEM
;
825 opt71
.flags
= DHOPT_VENDOR_MATCH
;
827 opt71
.next
= daemon
->dhcp_opts
;
828 do_encap_opts(&opt71
, OPTION_VENDOR_CLASS_OPT
, DHOPT_VENDOR_MATCH
, mess
, end
, 0);
830 log_packet("PXE", &mess
->yiaddr
, emac
, emac_len
, iface_name
, (char *)mess
->file
, mess
->xid
);
831 log_tags(tagif_netid
, ntohl(mess
->xid
));
832 return dhcp_packet_size(mess
, agent_id
, real_end
);
835 if ((opt
= option_find(mess
, sz
, OPTION_ARCH
, 2)))
837 pxearch
= option_uint(opt
, 0, 2);
839 /* proxy DHCP here. */
840 if ((mess_type
== DHCPDISCOVER
|| (pxe
&& mess_type
== DHCPREQUEST
)))
842 struct dhcp_context
*tmp
;
844 for (tmp
= context
; tmp
; tmp
= tmp
->current
)
845 if ((tmp
->flags
& CONTEXT_PROXY
) &&
846 match_netid(tmp
->filter
, tagif_netid
, 1))
851 struct dhcp_boot
*boot
= find_boot(tagif_netid
);
853 mess
->yiaddr
.s_addr
= 0;
854 if (mess_type
== DHCPDISCOVER
|| mess
->ciaddr
.s_addr
== 0)
856 mess
->ciaddr
.s_addr
= 0;
857 mess
->flags
|= htons(0x8000); /* broadcast */
860 clear_packet(mess
, end
);
862 /* Provide the bootfile here, for gPXE, and in case we have no menu items
863 and set discovery_control = 8 */
866 if (boot
->next_server
.s_addr
)
867 mess
->siaddr
= boot
->next_server
;
868 else if (boot
->tftp_sname
)
869 mess
->siaddr
= a_record_from_hosts(boot
->tftp_sname
, now
);
872 strncpy((char *)mess
->file
, boot
->file
, sizeof(mess
->file
)-1);
875 option_put(mess
, end
, OPTION_MESSAGE_TYPE
, 1,
876 mess_type
== DHCPDISCOVER
? DHCPOFFER
: DHCPACK
);
877 option_put(mess
, end
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
, htonl(context
->local
.s_addr
));
878 pxe_misc(mess
, end
, uuid
);
879 prune_vendor_opts(tagif_netid
);
880 do_encap_opts(pxe_opts(pxearch
, tagif_netid
, context
->local
, now
), OPTION_VENDOR_CLASS_OPT
, DHOPT_VENDOR_MATCH
, mess
, end
, 0);
882 log_packet("PXE", NULL
, emac
, emac_len
, iface_name
, ignore
? "proxy-ignored" : "proxy", mess
->xid
);
883 log_tags(tagif_netid
, ntohl(mess
->xid
));
884 return ignore
? 0 : dhcp_packet_size(mess
, agent_id
, real_end
);
890 /* if we're just a proxy server, go no further */
891 if ((context
->flags
& CONTEXT_PROXY
) || pxe
)
894 if ((opt
= option_find(mess
, sz
, OPTION_REQUESTED_OPTIONS
, 0)))
896 req_options
= (unsigned char *)daemon
->dhcp_buff2
;
897 memcpy(req_options
, option_ptr(opt
, 0), option_len(opt
));
898 req_options
[option_len(opt
)] = OPTION_END
;
904 if (!(opt
= option_find(mess
, sz
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
)) ||
905 option_addr(opt
).s_addr
!= server_id(context
, override
, fallback
).s_addr
)
908 /* sanitise any message. Paranoid? Moi? */
909 sanitise(option_find(mess
, sz
, OPTION_MESSAGE
, 1), daemon
->dhcp_buff
);
911 if (!(opt
= option_find(mess
, sz
, OPTION_REQUESTED_IP
, INADDRSZ
)))
914 #ifdef HAVE_QUIET_DHCP //originally a TOMATO option
915 if (!option_bool(OPT_QUIET_DHCP
))
917 log_packet("DHCPDECLINE", option_ptr(opt
, 0), emac
, emac_len
, iface_name
, daemon
->dhcp_buff
, mess
->xid
);
919 if (lease
&& lease
->addr
.s_addr
== option_addr(opt
).s_addr
)
920 lease_prune(lease
, now
);
922 if (have_config(config
, CONFIG_ADDR
) &&
923 config
->addr
.s_addr
== option_addr(opt
).s_addr
)
925 prettyprint_time(daemon
->dhcp_buff
, DECLINE_BACKOFF
);
926 my_syslog(MS_DHCP
| LOG_WARNING
, _("disabling DHCP static address %s for %s"),
927 inet_ntoa(config
->addr
), daemon
->dhcp_buff
);
928 config
->flags
|= CONFIG_DECLINED
;
929 config
->decline_time
= now
;
932 /* make sure this host gets a different address next time. */
933 for (; context
; context
= context
->current
)
934 context
->addr_epoch
++;
939 if (!(context
= narrow_context(context
, mess
->ciaddr
, tagif_netid
)) ||
940 !(opt
= option_find(mess
, sz
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
)) ||
941 option_addr(opt
).s_addr
!= server_id(context
, override
, fallback
).s_addr
)
944 if (lease
&& lease
->addr
.s_addr
== mess
->ciaddr
.s_addr
)
945 lease_prune(lease
, now
);
947 message
= _("unknown lease");
949 #ifdef HAVE_QUIET_DHCP //originally a TOMATO option
950 if (!option_bool(OPT_QUIET_DHCP
))
952 log_packet("DHCPRELEASE", &mess
->ciaddr
, emac
, emac_len
, iface_name
, message
, mess
->xid
);
957 if (ignore
|| have_config(config
, CONFIG_DISABLE
))
959 message
= _("ignored");
964 struct in_addr addr
, conf
;
966 addr
.s_addr
= conf
.s_addr
= 0;
968 if ((opt
= option_find(mess
, sz
, OPTION_REQUESTED_IP
, INADDRSZ
)))
969 addr
= option_addr(opt
);
971 if (have_config(config
, CONFIG_ADDR
))
973 char *addrs
= inet_ntoa(config
->addr
);
975 if ((ltmp
= lease_find_by_addr(config
->addr
)) &&
977 !config_has_mac(config
, ltmp
->hwaddr
, ltmp
->hwaddr_len
, ltmp
->hwaddr_type
))
980 unsigned char *mac
= extended_hwaddr(ltmp
->hwaddr_type
, ltmp
->hwaddr_len
,
981 ltmp
->hwaddr
, ltmp
->clid_len
, ltmp
->clid
, &len
);
982 my_syslog(MS_DHCP
| LOG_WARNING
, _("not using configured address %s because it is leased to %s"),
983 addrs
, print_mac(daemon
->namebuff
, mac
, len
));
987 struct dhcp_context
*tmp
;
988 for (tmp
= context
; tmp
; tmp
= tmp
->current
)
989 if (context
->router
.s_addr
== config
->addr
.s_addr
)
992 my_syslog(MS_DHCP
| LOG_WARNING
, _("not using configured address %s because it is in use by the server or relay"), addrs
);
993 else if (have_config(config
, CONFIG_DECLINED
) &&
994 difftime(now
, config
->decline_time
) < (float)DECLINE_BACKOFF
)
995 my_syslog(MS_DHCP
| LOG_WARNING
, _("not using configured address %s because it was previously declined"), addrs
);
1002 mess
->yiaddr
= conf
;
1004 address_available(context
, lease
->addr
, tagif_netid
) &&
1005 !config_find_by_address(daemon
->dhcp_conf
, lease
->addr
))
1006 mess
->yiaddr
= lease
->addr
;
1007 else if (opt
&& address_available(context
, addr
, tagif_netid
) && !lease_find_by_addr(addr
) &&
1008 !config_find_by_address(daemon
->dhcp_conf
, addr
))
1009 mess
->yiaddr
= addr
;
1010 else if (emac_len
== 0)
1011 message
= _("no unique-id");
1012 else if (!address_allocate(context
, &mess
->yiaddr
, emac
, emac_len
, tagif_netid
, now
))
1013 message
= _("no address available");
1016 #ifdef HAVE_QUIET_DHCP //originally a TOMATO option
1017 if (!option_bool(OPT_QUIET_DHCP
))
1019 log_packet("DHCPDISCOVER", opt
? option_ptr(opt
, 0) : NULL
, emac
, emac_len
, iface_name
, message
, mess
->xid
);
1021 if (message
|| !(context
= narrow_context(context
, mess
->yiaddr
, tagif_netid
)))
1024 if (context
->netid
.net
)
1026 context
->netid
.next
= netid
;
1027 tagif_netid
= run_tag_if(&context
->netid
);
1030 log_tags(tagif_netid
, ntohl(mess
->xid
));
1032 #ifdef HAVE_QUIET_DHCP //originally a TOMATO option
1033 if (!option_bool(OPT_QUIET_DHCP
))
1035 log_packet("DHCPOFFER" , &mess
->yiaddr
, emac
, emac_len
, iface_name
, NULL
, mess
->xid
);
1037 time
= calc_time(context
, config
, option_find(mess
, sz
, OPTION_LEASE_TIME
, 4));
1038 clear_packet(mess
, end
);
1039 option_put(mess
, end
, OPTION_MESSAGE_TYPE
, 1, DHCPOFFER
);
1040 option_put(mess
, end
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
, ntohl(server_id(context
, override
, fallback
).s_addr
));
1041 option_put(mess
, end
, OPTION_LEASE_TIME
, 4, time
);
1042 /* T1 and T2 are required in DHCPOFFER by HP's wacky Jetdirect client. */
1043 if (time
!= 0xffffffff)
1045 option_put(mess
, end
, OPTION_T1
, 4, (time
/2));
1046 option_put(mess
, end
, OPTION_T2
, 4, (time
*7)/8);
1048 do_options(context
, mess
, end
, req_options
, offer_hostname
, get_domain(mess
->yiaddr
),
1049 netid
, subnet_addr
, fqdn_flags
, borken_opt
, pxearch
, uuid
, vendor_class_len
, now
);
1051 return dhcp_packet_size(mess
, agent_id
, real_end
);
1054 if (ignore
|| have_config(config
, CONFIG_DISABLE
))
1056 if ((opt
= option_find(mess
, sz
, OPTION_REQUESTED_IP
, INADDRSZ
)))
1058 /* SELECTING or INIT_REBOOT */
1059 mess
->yiaddr
= option_addr(opt
);
1061 /* send vendor and user class info for new or recreated lease */
1064 if ((opt
= option_find(mess
, sz
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
)))
1069 if (override
.s_addr
!= 0)
1071 if (option_addr(opt
).s_addr
!= override
.s_addr
)
1076 for (; context
; context
= context
->current
)
1077 if (context
->local
.s_addr
== option_addr(opt
).s_addr
)
1082 /* Handle very strange configs where clients have more than one route to the server.
1083 If a clients idea of its server-id matches any of our DHCP interfaces, we let it pass.
1084 Have to set override to make sure we echo back the correct server-id */
1087 enumerate_interfaces(0);
1089 for (intr
= daemon
->interfaces
; intr
; intr
= intr
->next
)
1090 if (intr
->addr
.sa
.sa_family
== AF_INET
&&
1091 intr
->addr
.in
.sin_addr
.s_addr
== option_addr(opt
).s_addr
&&
1096 override
= intr
->addr
.in
.sin_addr
;
1099 /* In auth mode, a REQUEST sent to the wrong server
1100 should be faulted, so that the client establishes
1101 communication with us, otherwise, silently ignore. */
1102 if (!option_bool(OPT_AUTHORITATIVE
))
1104 message
= _("wrong server-ID");
1109 /* If a lease exists for this host and another address, squash it. */
1110 if (lease
&& lease
->addr
.s_addr
!= mess
->yiaddr
.s_addr
)
1112 lease_prune(lease
, now
);
1119 if (!lease
&& !option_bool(OPT_AUTHORITATIVE
))
1122 if (lease
&& lease
->addr
.s_addr
!= mess
->yiaddr
.s_addr
)
1123 message
= _("wrong address");
1128 /* RENEWING or REBINDING */
1129 /* Check existing lease for this address.
1130 We allow it to be missing if dhcp-authoritative mode
1131 as long as we can allocate the lease now - checked below.
1132 This makes for a smooth recovery from a lost lease DB */
1133 if ((lease
&& mess
->ciaddr
.s_addr
!= lease
->addr
.s_addr
) ||
1134 (!lease
&& !option_bool(OPT_AUTHORITATIVE
)))
1136 /* A client rebinding will broadcast the request, so we may see it even
1137 if the lease is held by another server. Just ignore it in that case.
1138 If the request is unicast to us, then somethings wrong, NAK */
1141 message
= _("lease not found");
1142 /* ensure we broadcast NAK */
1146 /* desynchronise renewals */
1148 mess
->yiaddr
= mess
->ciaddr
;
1151 #ifdef HAVE_QUIET_DHCP //originally a TOMATO option
1152 if (!option_bool(OPT_QUIET_DHCP
))
1154 log_packet("DHCPREQUEST", &mess
->yiaddr
, emac
, emac_len
, iface_name
, NULL
, mess
->xid
);
1158 struct dhcp_config
*addr_config
;
1159 struct dhcp_context
*tmp
= NULL
;
1161 if (have_config(config
, CONFIG_ADDR
))
1162 for (tmp
= context
; tmp
; tmp
= tmp
->current
)
1163 if (context
->router
.s_addr
== config
->addr
.s_addr
)
1166 if (!(context
= narrow_context(context
, mess
->yiaddr
, tagif_netid
)))
1168 /* If a machine moves networks whilst it has a lease, we catch that here. */
1169 message
= _("wrong network");
1170 /* ensure we broadcast NAK */
1174 /* Check for renewal of a lease which is outside the allowed range. */
1175 else if (!address_available(context
, mess
->yiaddr
, tagif_netid
) &&
1176 (!have_config(config
, CONFIG_ADDR
) || config
->addr
.s_addr
!= mess
->yiaddr
.s_addr
))
1177 message
= _("address not available");
1179 /* Check if a new static address has been configured. Be very sure that
1180 when the client does DISCOVER, it will get the static address, otherwise
1181 an endless protocol loop will ensue. */
1182 else if (!tmp
&& !selecting
&&
1183 have_config(config
, CONFIG_ADDR
) &&
1184 (!have_config(config
, CONFIG_DECLINED
) ||
1185 difftime(now
, config
->decline_time
) > (float)DECLINE_BACKOFF
) &&
1186 config
->addr
.s_addr
!= mess
->yiaddr
.s_addr
&&
1187 (!(ltmp
= lease_find_by_addr(config
->addr
)) || ltmp
== lease
))
1188 message
= _("static lease available");
1190 /* Check to see if the address is reserved as a static address for another host */
1191 else if ((addr_config
= config_find_by_address(daemon
->dhcp_conf
, mess
->yiaddr
)) && addr_config
!= config
)
1192 message
= _("address reserved");
1194 else if (!lease
&& (ltmp
= lease_find_by_addr(mess
->yiaddr
)))
1196 /* If a host is configured with more than one MAC address, it's OK to 'nix
1197 a lease from one of it's MACs to give the address to another. */
1198 if (config
&& config_has_mac(config
, ltmp
->hwaddr
, ltmp
->hwaddr_len
, ltmp
->hwaddr_type
))
1200 my_syslog(MS_DHCP
| LOG_INFO
, _("abandoning lease to %s of %s"),
1201 print_mac(daemon
->namebuff
, ltmp
->hwaddr
, ltmp
->hwaddr_len
),
1202 inet_ntoa(ltmp
->addr
));
1206 message
= _("address in use");
1212 message
= _("no unique-id");
1216 if ((lease
= lease4_allocate(mess
->yiaddr
)))
1219 message
= _("no leases left");
1226 #ifdef HAVE_QUIET_DHCP //originally a TOMATO option
1227 if (!option_bool(OPT_QUIET_DHCP
))
1229 log_packet("DHCPNAK", &mess
->yiaddr
, emac
, emac_len
, iface_name
, message
, mess
->xid
);
1231 mess
->yiaddr
.s_addr
= 0;
1232 clear_packet(mess
, end
);
1233 option_put(mess
, end
, OPTION_MESSAGE_TYPE
, 1, DHCPNAK
);
1234 option_put(mess
, end
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
, ntohl(server_id(context
, override
, fallback
).s_addr
));
1235 option_put_string(mess
, end
, OPTION_MESSAGE
, message
, borken_opt
);
1236 /* This fixes a problem with the DHCP spec, broadcasting a NAK to a host on
1237 a distant subnet which unicast a REQ to us won't work. */
1238 if (!unicast_dest
|| mess
->giaddr
.s_addr
!= 0 ||
1239 mess
->ciaddr
.s_addr
== 0 || is_same_net(context
->local
, mess
->ciaddr
, context
->netmask
))
1241 mess
->flags
|= htons(0x8000); /* broadcast */
1242 mess
->ciaddr
.s_addr
= 0;
1247 if (context
->netid
.net
)
1249 context
->netid
.next
= netid
;
1250 tagif_netid
= run_tag_if( &context
->netid
);
1253 log_tags(tagif_netid
, ntohl(mess
->xid
));
1257 /* pick up INIT-REBOOT events. */
1258 lease
->flags
|= LEASE_CHANGED
;
1261 if (daemon
->lease_change_command
)
1263 struct dhcp_netid
*n
;
1265 if (mess
->giaddr
.s_addr
)
1266 lease
->giaddr
= mess
->giaddr
;
1268 free(lease
->extradata
);
1269 lease
->extradata
= NULL
;
1270 lease
->extradata_size
= lease
->extradata_len
= 0;
1272 add_extradata_opt(lease
, option_find(mess
, sz
, OPTION_VENDOR_ID
, 1));
1273 add_extradata_opt(lease
, option_find(mess
, sz
, OPTION_HOSTNAME
, 1));
1274 add_extradata_opt(lease
, oui
);
1275 add_extradata_opt(lease
, serial
);
1276 add_extradata_opt(lease
, class);
1278 if ((opt
= option_find(mess
, sz
, OPTION_AGENT_ID
, 1)))
1280 add_extradata_opt(lease
, option_find1(option_ptr(opt
, 0), option_ptr(opt
, option_len(opt
)), SUBOPT_CIRCUIT_ID
, 1));
1281 add_extradata_opt(lease
, option_find1(option_ptr(opt
, 0), option_ptr(opt
, option_len(opt
)), SUBOPT_SUBSCR_ID
, 1));
1282 add_extradata_opt(lease
, option_find1(option_ptr(opt
, 0), option_ptr(opt
, option_len(opt
)), SUBOPT_REMOTE_ID
, 1));
1286 add_extradata_opt(lease
, NULL
);
1287 add_extradata_opt(lease
, NULL
);
1288 add_extradata_opt(lease
, NULL
);
1291 /* space-concat tag set */
1293 add_extradata_opt(lease
, NULL
);
1295 for (n
= tagif_netid
; n
; n
= n
->next
)
1297 struct dhcp_netid
*n1
;
1299 for (n1
= n
->next
; n1
; n1
= n1
->next
)
1300 if (strcmp(n
->net
, n1
->net
) == 0)
1303 lease_add_extradata(lease
, (unsigned char *)n
->net
, strlen(n
->net
), n
->next
? ' ' : 0);
1306 if ((opt
= option_find(mess
, sz
, OPTION_USER_CLASS
, 1)))
1308 int len
= option_len(opt
);
1309 unsigned char *ucp
= option_ptr(opt
, 0);
1310 /* If the user-class option started as counted strings, the first byte will be zero. */
1311 if (len
!= 0 && ucp
[0] == 0)
1313 lease_add_extradata(lease
, ucp
, len
, 0);
1319 if (!hostname_auth
&& (client_hostname
= host_from_dns(mess
->yiaddr
)))
1321 domain
= get_domain(mess
->yiaddr
);
1322 hostname
= client_hostname
;
1326 time
= calc_time(context
, config
, option_find(mess
, sz
, OPTION_LEASE_TIME
, 4));
1327 lease_set_hwaddr(lease
, mess
->chaddr
, clid
, mess
->hlen
, mess
->htype
, clid_len
, now
, do_classes
);
1329 /* if all the netids in the ignore_name list are present, ignore client-supplied name */
1332 for (id_list
= daemon
->dhcp_ignore_names
; id_list
; id_list
= id_list
->next
)
1333 if ((!id_list
->list
) || match_netid(id_list
->list
, tagif_netid
, 0))
1339 /* Last ditch, if configured, generate hostname from mac address */
1340 if (!hostname
&& emac_len
!= 0)
1342 for (id_list
= daemon
->dhcp_gen_names
; id_list
; id_list
= id_list
->next
)
1343 if ((!id_list
->list
) || match_netid(id_list
->list
, tagif_netid
, 0))
1349 hostname
= daemon
->dhcp_buff
;
1350 /* buffer is 256 bytes, 3 bytes per octet */
1351 for (i
= 0; (i
< emac_len
) && (i
< 80); i
++)
1352 hostname
+= sprintf(hostname
, "%.2x%s", emac
[i
], (i
== emac_len
- 1) ? "" : "-");
1353 hostname
= daemon
->dhcp_buff
;
1358 lease_set_hostname(lease
, hostname
, hostname_auth
, get_domain(lease
->addr
), domain
);
1360 lease_set_expires(lease
, time
, now
);
1361 lease_set_interface(lease
, int_index
, now
);
1363 if (override
.s_addr
!= 0)
1364 lease
->override
= override
;
1366 override
= lease
->override
;
1368 #ifdef HAVE_QUIET_DHCP //originally a TOMATO option
1369 if (!option_bool(OPT_QUIET_DHCP
))
1371 log_packet("DHCPACK", &mess
->yiaddr
, emac
, emac_len
, iface_name
, hostname
, mess
->xid
);
1373 clear_packet(mess
, end
);
1374 option_put(mess
, end
, OPTION_MESSAGE_TYPE
, 1, DHCPACK
);
1375 option_put(mess
, end
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
, ntohl(server_id(context
, override
, fallback
).s_addr
));
1376 option_put(mess
, end
, OPTION_LEASE_TIME
, 4, time
);
1377 if (time
!= 0xffffffff)
1379 while (fuzz
> (time
/16))
1381 option_put(mess
, end
, OPTION_T1
, 4, (time
/2) - fuzz
);
1382 option_put(mess
, end
, OPTION_T2
, 4, ((time
/8)*7) - fuzz
);
1384 do_options(context
, mess
, end
, req_options
, hostname
, get_domain(mess
->yiaddr
),
1385 netid
, subnet_addr
, fqdn_flags
, borken_opt
, pxearch
, uuid
, vendor_class_len
, now
);
1388 return dhcp_packet_size(mess
, agent_id
, real_end
);
1391 if (ignore
|| have_config(config
, CONFIG_DISABLE
))
1392 message
= _("ignored");
1394 #ifdef HAVE_QUIET_DHCP //originally a TOMATO option
1395 if (!option_bool(OPT_QUIET_DHCP
))
1397 log_packet("DHCPINFORM", &mess
->ciaddr
, emac
, emac_len
, iface_name
, message
, mess
->xid
);
1399 if (message
|| mess
->ciaddr
.s_addr
== 0)
1402 /* For DHCPINFORM only, cope without a valid context */
1403 context
= narrow_context(context
, mess
->ciaddr
, tagif_netid
);
1405 /* Find a least based on IP address if we didn't
1406 get one from MAC address/client-d */
1408 (lease
= lease_find_by_addr(mess
->ciaddr
)) &&
1410 hostname
= lease
->hostname
;
1412 if (!hostname
&& (hostname
= host_from_dns(mess
->ciaddr
)))
1413 domain
= get_domain(mess
->ciaddr
);
1415 if (context
&& context
->netid
.net
)
1417 context
->netid
.next
= netid
;
1418 tagif_netid
= run_tag_if(&context
->netid
);
1421 log_tags(tagif_netid
, ntohl(mess
->xid
));
1423 #ifdef HAVE_QUIET_DHCP //originally a TOMATO option
1424 if (!option_bool(OPT_QUIET_DHCP
))
1426 log_packet("DHCPACK", &mess
->ciaddr
, emac
, emac_len
, iface_name
, hostname
, mess
->xid
);
1430 lease_set_interface(lease
, int_index
, now
);
1431 if (override
.s_addr
!= 0)
1432 lease
->override
= override
;
1434 override
= lease
->override
;
1437 clear_packet(mess
, end
);
1438 option_put(mess
, end
, OPTION_MESSAGE_TYPE
, 1, DHCPACK
);
1439 option_put(mess
, end
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
, ntohl(server_id(context
, override
, fallback
).s_addr
));
1441 /* RFC 2131 says that DHCPINFORM shouldn't include lease-time parameters, but
1442 we supply a utility which makes DHCPINFORM requests to get this information.
1443 Only include lease time if OPTION_LEASE_TIME is in the parameter request list,
1444 which won't be true for ordinary clients, but will be true for the
1445 dhcp_lease_time utility. */
1446 if (lease
&& in_list(req_options
, OPTION_LEASE_TIME
))
1448 if (lease
->expires
== 0)
1451 time
= (unsigned int)difftime(lease
->expires
, now
);
1452 option_put(mess
, end
, OPTION_LEASE_TIME
, 4, time
);
1455 do_options(context
, mess
, end
, req_options
, hostname
, get_domain(mess
->ciaddr
),
1456 netid
, subnet_addr
, fqdn_flags
, borken_opt
, pxearch
, uuid
, vendor_class_len
, now
);
1458 *is_inform
= 1; /* handle reply differently */
1459 return dhcp_packet_size(mess
, agent_id
, real_end
);
1465 /* find a good value to use as MAC address for logging and address-allocation hashing.
1466 This is normally just the chaddr field from the DHCP packet,
1467 but eg Firewire will have hlen == 0 and use the client-id instead.
1468 This could be anything, but will normally be EUI64 for Firewire.
1469 We assume that if the first byte of the client-id equals the htype byte
1470 then the client-id is using the usual encoding and use the rest of the
1471 client-id: if not we can use the whole client-id. This should give
1472 sane MAC address logs. */
1473 unsigned char *extended_hwaddr(int hwtype
, int hwlen
, unsigned char *hwaddr
,
1474 int clid_len
, unsigned char *clid
, int *len_out
)
1476 if (hwlen
== 0 && clid
&& clid_len
> 3)
1478 if (clid
[0] == hwtype
)
1480 *len_out
= clid_len
- 1 ;
1484 #if defined(ARPHRD_EUI64) && defined(ARPHRD_IEEE1394)
1485 if (clid
[0] == ARPHRD_EUI64
&& hwtype
== ARPHRD_IEEE1394
)
1487 *len_out
= clid_len
- 1 ;
1492 *len_out
= clid_len
;
1500 static unsigned int calc_time(struct dhcp_context
*context
, struct dhcp_config
*config
, unsigned char *opt
)
1502 unsigned int time
= have_config(config
, CONFIG_TIME
) ? config
->lease_time
: context
->lease_time
;
1506 unsigned int req_time
= option_uint(opt
, 0, 4);
1507 if (req_time
< 120 )
1508 req_time
= 120; /* sanity */
1509 if (time
== 0xffffffff || (req_time
!= 0xffffffff && req_time
< time
))
1516 static struct in_addr
server_id(struct dhcp_context
*context
, struct in_addr override
, struct in_addr fallback
)
1518 if (override
.s_addr
!= 0)
1520 else if (context
&& context
->local
.s_addr
!= 0)
1521 return context
->local
;
1526 static int sanitise(unsigned char *opt
, char *buf
)
1536 p
= option_ptr(opt
, 0);
1538 for (i
= option_len(opt
); i
> 0; i
--)
1541 if (isprint((int)c
))
1544 *buf
= 0; /* add terminator */
1550 static void add_extradata_opt(struct dhcp_lease
*lease
, unsigned char *opt
)
1553 lease_add_extradata(lease
, NULL
, 0, 0);
1555 lease_add_extradata(lease
, option_ptr(opt
, 0), option_len(opt
), 0);
1559 static void log_packet(char *type
, void *addr
, unsigned char *ext_mac
,
1560 int mac_len
, char *interface
, char *string
, u32 xid
)
1565 /* addr may be misaligned */
1567 memcpy(&a
, addr
, sizeof(a
));
1569 print_mac(daemon
->namebuff
, ext_mac
, mac_len
);
1571 if(option_bool(OPT_LOG_OPTS
))
1572 my_syslog(MS_DHCP
| LOG_INFO
, "%u %s(%s) %s%s%s %s",
1576 addr
? inet_ntoa(a
) : "",
1579 string
? string
: "");
1581 my_syslog(MS_DHCP
| LOG_INFO
, "%s(%s) %s%s%s %s",
1584 addr
? inet_ntoa(a
) : "",
1587 string
? string
: "");
1590 static void log_options(unsigned char *start
, u32 xid
)
1592 while (*start
!= OPTION_END
)
1594 char *optname
= option_string(AF_INET
, start
[0], option_ptr(start
, 0), option_len(start
), daemon
->namebuff
, MAXDNAME
);
1596 my_syslog(MS_DHCP
| LOG_INFO
, "%u sent size:%3d option:%3d %s %s",
1597 ntohl(xid
), option_len(start
), start
[0], optname
, daemon
->namebuff
);
1598 start
+= start
[1] + 2;
1602 static unsigned char *option_find1(unsigned char *p
, unsigned char *end
, int opt
, int minsize
)
1608 else if (*p
== OPTION_END
)
1609 return opt
== OPTION_END
? p
: NULL
;
1610 else if (*p
== OPTION_PAD
)
1616 return NULL
; /* malformed packet */
1617 opt_len
= option_len(p
);
1618 if (p
> end
- (2 + opt_len
))
1619 return NULL
; /* malformed packet */
1620 if (*p
== opt
&& opt_len
>= minsize
)
1627 static unsigned char *option_find(struct dhcp_packet
*mess
, size_t size
, int opt_type
, int minsize
)
1629 unsigned char *ret
, *overload
;
1631 /* skip over DHCP cookie; */
1632 if ((ret
= option_find1(&mess
->options
[0] + sizeof(u32
), ((unsigned char *)mess
) + size
, opt_type
, minsize
)))
1635 /* look for overload option. */
1636 if (!(overload
= option_find1(&mess
->options
[0] + sizeof(u32
), ((unsigned char *)mess
) + size
, OPTION_OVERLOAD
, 1)))
1639 /* Can we look in filename area ? */
1640 if ((overload
[2] & 1) &&
1641 (ret
= option_find1(&mess
->file
[0], &mess
->file
[128], opt_type
, minsize
)))
1644 /* finally try sname area */
1645 if ((overload
[2] & 2) &&
1646 (ret
= option_find1(&mess
->sname
[0], &mess
->sname
[64], opt_type
, minsize
)))
1652 static struct in_addr
option_addr(unsigned char *opt
)
1654 /* this worries about unaligned data in the option. */
1655 /* struct in_addr is network byte order */
1658 memcpy(&ret
, option_ptr(opt
, 0), INADDRSZ
);
1663 static unsigned int option_uint(unsigned char *opt
, int offset
, int size
)
1665 /* this worries about unaligned data and byte order */
1666 unsigned int ret
= 0;
1668 unsigned char *p
= option_ptr(opt
, offset
);
1670 for (i
= 0; i
< size
; i
++)
1671 ret
= (ret
<< 8) | *p
++;
1676 static unsigned char *dhcp_skip_opts(unsigned char *start
)
1679 start
+= start
[1] + 2;
1683 /* only for use when building packet: doesn't check for bad data. */
1684 static unsigned char *find_overload(struct dhcp_packet
*mess
)
1686 unsigned char *p
= &mess
->options
[0] + sizeof(u32
);
1690 if (*p
== OPTION_OVERLOAD
)
1697 static size_t dhcp_packet_size(struct dhcp_packet
*mess
, unsigned char *agent_id
, unsigned char *real_end
)
1699 unsigned char *p
= dhcp_skip_opts(&mess
->options
[0] + sizeof(u32
));
1700 unsigned char *overload
;
1703 /* move agent_id back down to the end of the packet */
1706 memmove(p
, agent_id
, real_end
- agent_id
);
1707 p
+= real_end
- agent_id
;
1708 memset(p
, 0, real_end
- p
); /* in case of overlap */
1711 /* add END options to the regions. */
1712 overload
= find_overload(mess
);
1714 if (overload
&& (option_uint(overload
, 0, 1) & 1))
1716 *dhcp_skip_opts(mess
->file
) = OPTION_END
;
1717 if (option_bool(OPT_LOG_OPTS
))
1718 log_options(mess
->file
, mess
->xid
);
1720 else if (option_bool(OPT_LOG_OPTS
) && strlen((char *)mess
->file
) != 0)
1721 my_syslog(MS_DHCP
| LOG_INFO
, _("%u bootfile name: %s"), ntohl(mess
->xid
), (char *)mess
->file
);
1723 if (overload
&& (option_uint(overload
, 0, 1) & 2))
1725 *dhcp_skip_opts(mess
->sname
) = OPTION_END
;
1726 if (option_bool(OPT_LOG_OPTS
))
1727 log_options(mess
->sname
, mess
->xid
);
1729 else if (option_bool(OPT_LOG_OPTS
) && strlen((char *)mess
->sname
) != 0)
1730 my_syslog(MS_DHCP
| LOG_INFO
, _("%u server name: %s"), ntohl(mess
->xid
), (char *)mess
->sname
);
1735 if (option_bool(OPT_LOG_OPTS
))
1737 if (mess
->siaddr
.s_addr
!= 0)
1738 my_syslog(MS_DHCP
| LOG_INFO
, _("%u next server: %s"), ntohl(mess
->xid
), inet_ntoa(mess
->siaddr
));
1740 if ((mess
->flags
& htons(0x8000)) && mess
->ciaddr
.s_addr
== 0)
1741 my_syslog(MS_DHCP
| LOG_INFO
, _("%u broadcast response"), ntohl(mess
->xid
));
1743 log_options(&mess
->options
[0] + sizeof(u32
), mess
->xid
);
1746 ret
= (size_t)(p
- (unsigned char *)mess
);
1748 if (ret
< MIN_PACKETSZ
)
1754 static unsigned char *free_space(struct dhcp_packet
*mess
, unsigned char *end
, int opt
, int len
)
1756 unsigned char *p
= dhcp_skip_opts(&mess
->options
[0] + sizeof(u32
));
1758 if (p
+ len
+ 3 >= end
)
1759 /* not enough space in options area, try and use overload, if poss */
1761 unsigned char *overload
;
1763 if (!(overload
= find_overload(mess
)) &&
1764 (mess
->file
[0] == 0 || mess
->sname
[0] == 0))
1766 /* attempt to overload fname and sname areas, we've reserved space for the
1767 overflow option previuously. */
1769 *(p
++) = OPTION_OVERLOAD
;
1775 /* using filename field ? */
1778 if (mess
->file
[0] == 0)
1781 if (overload
[2] & 1)
1783 p
= dhcp_skip_opts(mess
->file
);
1784 if (p
+ len
+ 3 >= mess
->file
+ sizeof(mess
->file
))
1790 /* try to bring sname into play (it may be already) */
1791 if (mess
->sname
[0] == 0)
1794 if (overload
[2] & 2)
1796 p
= dhcp_skip_opts(mess
->sname
);
1797 if (p
+ len
+ 3 >= mess
->sname
+ sizeof(mess
->sname
))
1804 my_syslog(MS_DHCP
| LOG_WARNING
, _("cannot send DHCP/BOOTP option %d: no space left in packet"), opt
);
1816 static void option_put(struct dhcp_packet
*mess
, unsigned char *end
, int opt
, int len
, unsigned int val
)
1819 unsigned char *p
= free_space(mess
, end
, opt
, len
);
1822 for (i
= 0; i
< len
; i
++)
1823 *(p
++) = val
>> (8 * (len
- (i
+ 1)));
1826 static void option_put_string(struct dhcp_packet
*mess
, unsigned char *end
, int opt
,
1827 char *string
, int null_term
)
1830 size_t len
= strlen(string
);
1832 if (null_term
&& len
!= 255)
1835 if ((p
= free_space(mess
, end
, opt
, len
)))
1836 memcpy(p
, string
, len
);
1839 /* return length, note this only does the data part */
1840 static int do_opt(struct dhcp_opt
*opt
, unsigned char *p
, struct dhcp_context
*context
, int null_term
)
1844 if ((opt
->flags
& DHOPT_STRING
) && null_term
&& len
!= 255)
1849 if (context
&& (opt
->flags
& DHOPT_ADDR
))
1852 struct in_addr
*a
= (struct in_addr
*)opt
->val
;
1853 for (j
= 0; j
< opt
->len
; j
+=INADDRSZ
, a
++)
1855 /* zero means "self" (but not in vendorclass options.) */
1857 memcpy(p
, &context
->local
, INADDRSZ
);
1859 memcpy(p
, a
, INADDRSZ
);
1864 memcpy(p
, opt
->val
, len
);
1869 static int in_list(unsigned char *list
, int opt
)
1873 /* If no requested options, send everything, not nothing. */
1877 for (i
= 0; list
[i
] != OPTION_END
; i
++)
1884 static struct dhcp_opt
*option_find2(int opt
)
1886 struct dhcp_opt
*opts
;
1888 for (opts
= daemon
->dhcp_opts
; opts
; opts
= opts
->next
)
1889 if (opts
->opt
== opt
&& (opts
->flags
& DHOPT_TAGOK
))
1895 /* mark vendor-encapsulated options which match the client-supplied or
1896 config-supplied vendor class */
1897 static void match_vendor_opts(unsigned char *opt
, struct dhcp_opt
*dopt
)
1899 for (; dopt
; dopt
= dopt
->next
)
1901 dopt
->flags
&= ~DHOPT_VENDOR_MATCH
;
1902 if (opt
&& (dopt
->flags
& DHOPT_VENDOR
))
1905 if (dopt
->u
.vendor_class
)
1906 len
= strlen((char *)dopt
->u
.vendor_class
);
1907 for (i
= 0; i
<= (option_len(opt
) - len
); i
++)
1908 if (len
== 0 || memcmp(dopt
->u
.vendor_class
, option_ptr(opt
, i
), len
) == 0)
1910 dopt
->flags
|= DHOPT_VENDOR_MATCH
;
1917 static int do_encap_opts(struct dhcp_opt
*opt
, int encap
, int flag
,
1918 struct dhcp_packet
*mess
, unsigned char *end
, int null_term
)
1920 int len
, enc_len
, ret
= 0;
1921 struct dhcp_opt
*start
;
1924 /* find size in advance */
1925 for (enc_len
= 0, start
= opt
; opt
; opt
= opt
->next
)
1926 if (opt
->flags
& flag
)
1928 int new = do_opt(opt
, NULL
, NULL
, null_term
) + 2;
1930 if (enc_len
+ new <= 255)
1934 p
= free_space(mess
, end
, encap
, enc_len
);
1935 for (; start
&& start
!= opt
; start
= start
->next
)
1936 if (p
&& (start
->flags
& flag
))
1938 len
= do_opt(start
, p
+ 2, NULL
, null_term
);
1939 *(p
++) = start
->opt
;
1949 (p
= free_space(mess
, end
, encap
, enc_len
+ 1)))
1951 for (; start
; start
= start
->next
)
1952 if (start
->flags
& flag
)
1954 len
= do_opt(start
, p
+ 2, NULL
, null_term
);
1955 *(p
++) = start
->opt
;
1965 static void pxe_misc(struct dhcp_packet
*mess
, unsigned char *end
, unsigned char *uuid
)
1969 option_put_string(mess
, end
, OPTION_VENDOR_ID
, "PXEClient", 0);
1970 if (uuid
&& (p
= free_space(mess
, end
, OPTION_PXE_UUID
, 17)))
1971 memcpy(p
, uuid
, 17);
1974 static int prune_vendor_opts(struct dhcp_netid
*netid
)
1977 struct dhcp_opt
*opt
;
1979 /* prune vendor-encapsulated options based on netid, and look if we're forcing them to be sent */
1980 for (opt
= daemon
->dhcp_opts
; opt
; opt
= opt
->next
)
1981 if (opt
->flags
& DHOPT_VENDOR_MATCH
)
1983 if (!match_netid(opt
->netid
, netid
, 1))
1984 opt
->flags
&= ~DHOPT_VENDOR_MATCH
;
1985 else if (opt
->flags
& DHOPT_FORCE
)
1991 static struct dhcp_opt
*pxe_opts(int pxe_arch
, struct dhcp_netid
*netid
, struct in_addr local
, time_t now
)
1995 unsigned char *p
, *q
;
1996 struct pxe_service
*service
;
1997 static struct dhcp_opt
*o
, *ret
;
1998 int i
, j
= NUM_OPTS
- 1;
1999 struct in_addr boot_server
;
2001 /* We pass back references to these, hence they are declared static */
2002 static unsigned char discovery_control
;
2003 static unsigned char fake_prompt
[] = { 0, 'P', 'X', 'E' };
2004 static struct dhcp_opt
*fake_opts
= NULL
;
2006 /* Disable multicast, since we don't support it, and broadcast
2007 unless we need it */
2008 discovery_control
= 3;
2010 ret
= daemon
->dhcp_opts
;
2012 if (!fake_opts
&& !(fake_opts
= whine_malloc(NUM_OPTS
* sizeof(struct dhcp_opt
))))
2015 for (i
= 0; i
< NUM_OPTS
; i
++)
2017 fake_opts
[i
].flags
= DHOPT_VENDOR_MATCH
;
2018 fake_opts
[i
].netid
= NULL
;
2019 fake_opts
[i
].next
= i
== (NUM_OPTS
- 1) ? ret
: &fake_opts
[i
+1];
2022 /* create the data for the PXE_MENU and PXE_SERVERS options. */
2023 p
= (unsigned char *)daemon
->dhcp_buff
;
2024 q
= (unsigned char *)daemon
->dhcp_buff3
;
2026 for (i
= 0, service
= daemon
->pxe_services
; service
; service
= service
->next
)
2027 if (pxe_arch
== service
->CSA
&& match_netid(service
->netid
, netid
, 1))
2029 size_t len
= strlen(service
->menu
);
2030 /* opt 43 max size is 255. encapsulated option has type and length
2031 bytes, so its max size is 253. */
2032 if (p
- (unsigned char *)daemon
->dhcp_buff
+ len
+ 3 < 253)
2034 *(p
++) = service
->type
>> 8;
2035 *(p
++) = service
->type
;
2037 memcpy(p
, service
->menu
, len
);
2044 my_syslog(MS_DHCP
| LOG_ERR
, _("PXE menu too large"));
2045 return daemon
->dhcp_opts
;
2048 boot_server
= service
->basename
? local
:
2049 (service
->sname
? a_record_from_hosts(service
->sname
, now
) : service
->server
);
2051 if (boot_server
.s_addr
!= 0)
2053 if (q
- (unsigned char *)daemon
->dhcp_buff3
+ 3 + INADDRSZ
>= 253)
2056 /* Boot service with known address - give it */
2057 *(q
++) = service
->type
>> 8;
2058 *(q
++) = service
->type
;
2060 /* dest misaligned */
2061 memcpy(q
, &boot_server
.s_addr
, INADDRSZ
);
2064 else if (service
->type
!= 0)
2065 /* We don't know the server for a service type, so we'll
2066 allow the client to broadcast for it */
2067 discovery_control
= 2;
2070 /* if no prompt, wait forever if there's a choice */
2071 fake_prompt
[0] = (i
> 1) ? 255 : 0;
2074 discovery_control
= 8; /* no menu - just use use mess->filename */
2077 ret
= &fake_opts
[j
--];
2078 ret
->len
= p
- (unsigned char *)daemon
->dhcp_buff
;
2079 ret
->val
= (unsigned char *)daemon
->dhcp_buff
;
2080 ret
->opt
= SUBOPT_PXE_MENU
;
2082 if (q
- (unsigned char *)daemon
->dhcp_buff3
!= 0)
2084 ret
= &fake_opts
[j
--];
2085 ret
->len
= q
- (unsigned char *)daemon
->dhcp_buff3
;
2086 ret
->val
= (unsigned char *)daemon
->dhcp_buff3
;
2087 ret
->opt
= SUBOPT_PXE_SERVERS
;
2091 for (o
= daemon
->dhcp_opts
; o
; o
= o
->next
)
2092 if ((o
->flags
& DHOPT_VENDOR_MATCH
) && o
->opt
== SUBOPT_PXE_MENU_PROMPT
)
2097 ret
= &fake_opts
[j
--];
2098 ret
->len
= sizeof(fake_prompt
);
2099 ret
->val
= fake_prompt
;
2100 ret
->opt
= SUBOPT_PXE_MENU_PROMPT
;
2103 ret
= &fake_opts
[j
--];
2105 ret
->opt
= SUBOPT_PXE_DISCOVERY
;
2106 ret
->val
= &discovery_control
;
2111 static void clear_packet(struct dhcp_packet
*mess
, unsigned char *end
)
2113 memset(mess
->sname
, 0, sizeof(mess
->sname
));
2114 memset(mess
->file
, 0, sizeof(mess
->file
));
2115 memset(&mess
->options
[0] + sizeof(u32
), 0, end
- (&mess
->options
[0] + sizeof(u32
)));
2116 mess
->siaddr
.s_addr
= 0;
2119 struct dhcp_boot
*find_boot(struct dhcp_netid
*netid
)
2121 struct dhcp_boot
*boot
;
2123 /* decide which dhcp-boot option we're using */
2124 for (boot
= daemon
->boot_config
; boot
; boot
= boot
->next
)
2125 if (match_netid(boot
->netid
, netid
, 0))
2128 /* No match, look for one without a netid */
2129 for (boot
= daemon
->boot_config
; boot
; boot
= boot
->next
)
2130 if (match_netid(boot
->netid
, netid
, 1))
2136 static void do_options(struct dhcp_context
*context
,
2137 struct dhcp_packet
*mess
,
2139 unsigned char *req_options
,
2142 struct dhcp_netid
*netid
,
2143 struct in_addr subnet_addr
,
2144 unsigned char fqdn_flags
,
2145 int null_term
, int pxe_arch
,
2146 unsigned char *uuid
,
2147 int vendor_class_len
,
2150 struct dhcp_opt
*opt
, *config_opts
= daemon
->dhcp_opts
;
2151 struct dhcp_boot
*boot
;
2153 int i
, len
, force_encap
= 0;
2154 unsigned char f0
= 0, s0
= 0;
2155 int done_file
= 0, done_server
= 0;
2156 int done_vendor_class
= 0;
2157 struct dhcp_netid
*tagif
;
2158 struct dhcp_netid_list
*id_list
;
2160 /* filter options based on tags, those we want get DHOPT_TAGOK bit set */
2162 context
->netid
.next
= NULL
;
2163 tagif
= option_filter(netid
, context
&& context
->netid
.net
? &context
->netid
: NULL
, config_opts
);
2166 if (option_bool(OPT_LOG_OPTS
) && req_options
)
2168 char *q
= daemon
->namebuff
;
2169 for (i
= 0; req_options
[i
] != OPTION_END
; i
++)
2171 char *s
= option_string(AF_INET
, req_options
[i
], NULL
, 0, NULL
, 0);
2172 q
+= snprintf(q
, MAXDNAME
- (q
- daemon
->namebuff
),
2175 strlen(s
) != 0 ? ":" : "",
2177 req_options
[i
+1] == OPTION_END
? "" : ", ");
2178 if (req_options
[i
+1] == OPTION_END
|| (q
- daemon
->namebuff
) > 40)
2180 q
= daemon
->namebuff
;
2181 my_syslog(MS_DHCP
| LOG_INFO
, _("%u requested options: %s"), ntohl(mess
->xid
), daemon
->namebuff
);
2186 for (id_list
= daemon
->force_broadcast
; id_list
; id_list
= id_list
->next
)
2187 if ((!id_list
->list
) || match_netid(id_list
->list
, netid
, 0))
2190 mess
->flags
|= htons(0x8000); /* force broadcast */
2193 mess
->siaddr
= context
->local
;
2195 /* See if we can send the boot stuff as options.
2196 To do this we need a requested option list, BOOTP
2197 and very old DHCP clients won't have this, we also
2198 provide an manual option to disable it.
2199 Some PXE ROMs have bugs (surprise!) and need zero-terminated
2200 names, so we always send those. */
2201 if ((boot
= find_boot(tagif
)))
2205 if (!option_bool(OPT_NO_OVERRIDE
) &&
2207 in_list(req_options
, OPTION_SNAME
))
2208 option_put_string(mess
, end
, OPTION_SNAME
, boot
->sname
, 1);
2210 strncpy((char *)mess
->sname
, boot
->sname
, sizeof(mess
->sname
)-1);
2215 if (!option_bool(OPT_NO_OVERRIDE
) &&
2217 in_list(req_options
, OPTION_FILENAME
))
2218 option_put_string(mess
, end
, OPTION_FILENAME
, boot
->file
, 1);
2220 strncpy((char *)mess
->file
, boot
->file
, sizeof(mess
->file
)-1);
2223 if (boot
->next_server
.s_addr
)
2224 mess
->siaddr
= boot
->next_server
;
2225 else if (boot
->tftp_sname
)
2226 mess
->siaddr
= a_record_from_hosts(boot
->tftp_sname
, now
);
2229 /* Use the values of the relevant options if no dhcp-boot given and
2230 they're not explicitly asked for as options. OPTION_END is used
2231 as an internal way to specify siaddr without using dhcp-boot, for use in
2234 if ((!req_options
|| !in_list(req_options
, OPTION_FILENAME
)) &&
2235 (opt
= option_find2(OPTION_FILENAME
)) && !(opt
->flags
& DHOPT_FORCE
))
2237 strncpy((char *)mess
->file
, (char *)opt
->val
, sizeof(mess
->file
)-1);
2241 if ((!req_options
|| !in_list(req_options
, OPTION_SNAME
)) &&
2242 (opt
= option_find2(OPTION_SNAME
)) && !(opt
->flags
& DHOPT_FORCE
))
2244 strncpy((char *)mess
->sname
, (char *)opt
->val
, sizeof(mess
->sname
)-1);
2248 if ((opt
= option_find2(OPTION_END
)))
2249 mess
->siaddr
.s_addr
= ((struct in_addr
*)opt
->val
)->s_addr
;
2252 /* We don't want to do option-overload for BOOTP, so make the file and sname
2253 fields look like they are in use, even when they aren't. This gets restored
2254 at the end of this function. */
2256 if (!req_options
|| option_bool(OPT_NO_OVERRIDE
))
2260 s0
= mess
->sname
[0];
2264 /* At this point, if mess->sname or mess->file are zeroed, they are available
2265 for option overload, reserve space for the overload option. */
2266 if (mess
->file
[0] == 0 || mess
->sname
[0] == 0)
2269 /* rfc3011 says this doesn't need to be in the requested options list. */
2270 if (subnet_addr
.s_addr
)
2271 option_put(mess
, end
, OPTION_SUBNET_SELECT
, INADDRSZ
, ntohl(subnet_addr
.s_addr
));
2273 /* replies to DHCPINFORM may not have a valid context */
2276 if (!option_find2(OPTION_NETMASK
))
2277 option_put(mess
, end
, OPTION_NETMASK
, INADDRSZ
, ntohl(context
->netmask
.s_addr
));
2279 /* May not have a "guessed" broadcast address if we got no packets via a relay
2280 from this net yet (ie just unicast renewals after a restart */
2281 if (context
->broadcast
.s_addr
&&
2282 !option_find2(OPTION_BROADCAST
))
2283 option_put(mess
, end
, OPTION_BROADCAST
, INADDRSZ
, ntohl(context
->broadcast
.s_addr
));
2285 /* Same comments as broadcast apply, and also may not be able to get a sensible
2286 default when using subnet select. User must configure by steam in that case. */
2287 if (context
->router
.s_addr
&&
2288 in_list(req_options
, OPTION_ROUTER
) &&
2289 !option_find2(OPTION_ROUTER
))
2290 option_put(mess
, end
, OPTION_ROUTER
, INADDRSZ
, ntohl(context
->router
.s_addr
));
2292 if (daemon
->port
== NAMESERVER_PORT
&&
2293 in_list(req_options
, OPTION_DNSSERVER
) &&
2294 !option_find2(OPTION_DNSSERVER
))
2295 option_put(mess
, end
, OPTION_DNSSERVER
, INADDRSZ
, ntohl(context
->local
.s_addr
));
2298 if (domain
&& in_list(req_options
, OPTION_DOMAINNAME
) &&
2299 !option_find2(OPTION_DOMAINNAME
))
2300 option_put_string(mess
, end
, OPTION_DOMAINNAME
, domain
, null_term
);
2302 /* Note that we ignore attempts to set the fqdn using --dhc-option=81,<name> */
2305 if (in_list(req_options
, OPTION_HOSTNAME
) &&
2306 !option_find2(OPTION_HOSTNAME
))
2307 option_put_string(mess
, end
, OPTION_HOSTNAME
, hostname
, null_term
);
2309 if (fqdn_flags
!= 0)
2311 len
= strlen(hostname
) + 3;
2313 if (fqdn_flags
& 0x04)
2319 len
+= strlen(domain
) + 1;
2321 if ((p
= free_space(mess
, end
, OPTION_CLIENT_FQDN
, len
)))
2323 *(p
++) = fqdn_flags
& 0x0f; /* MBZ bits to zero */
2327 if (fqdn_flags
& 0x04)
2329 p
= do_rfc1035_name(p
, hostname
);
2331 p
= do_rfc1035_name(p
, domain
);
2336 memcpy(p
, hostname
, strlen(hostname
));
2337 p
+= strlen(hostname
);
2341 memcpy(p
, domain
, strlen(domain
));
2342 p
+= strlen(domain
);
2351 for (opt
= config_opts
; opt
; opt
= opt
->next
)
2353 int optno
= opt
->opt
;
2355 /* netids match and not encapsulated? */
2356 if (!(opt
->flags
& DHOPT_TAGOK
))
2359 /* was it asked for, or are we sending it anyway? */
2360 if (!(opt
->flags
& DHOPT_FORCE
) && !in_list(req_options
, optno
))
2363 /* prohibit some used-internally options */
2364 if (optno
== OPTION_CLIENT_FQDN
||
2365 optno
== OPTION_MAXMESSAGE
||
2366 optno
== OPTION_OVERLOAD
||
2367 optno
== OPTION_PAD
||
2368 optno
== OPTION_END
)
2371 if (optno
== OPTION_SNAME
&& done_server
)
2374 if (optno
== OPTION_FILENAME
&& done_file
)
2377 /* For the options we have default values on
2378 dhc-option=<optionno> means "don't include this option"
2379 not "include a zero-length option" */
2380 if (opt
->len
== 0 &&
2381 (optno
== OPTION_NETMASK
||
2382 optno
== OPTION_BROADCAST
||
2383 optno
== OPTION_ROUTER
||
2384 optno
== OPTION_DNSSERVER
||
2385 optno
== OPTION_DOMAINNAME
||
2386 optno
== OPTION_HOSTNAME
))
2389 /* vendor-class comes from elsewhere for PXE */
2390 if (pxe_arch
!= -1 && optno
== OPTION_VENDOR_ID
)
2393 /* always force null-term for filename and servername - buggy PXE again. */
2394 len
= do_opt(opt
, NULL
, context
,
2395 (optno
== OPTION_SNAME
|| optno
== OPTION_FILENAME
) ? 1 : null_term
);
2397 if ((p
= free_space(mess
, end
, optno
, len
)))
2399 do_opt(opt
, p
, context
,
2400 (optno
== OPTION_SNAME
|| optno
== OPTION_FILENAME
) ? 1 : null_term
);
2402 /* If we send a vendor-id, revisit which vendor-ops we consider
2403 it appropriate to send. */
2404 if (optno
== OPTION_VENDOR_ID
)
2406 match_vendor_opts(p
- 2, config_opts
);
2407 done_vendor_class
= 1;
2412 /* Now send options to be encapsulated in arbitrary options,
2413 eg dhcp-option=encap:172,17,.......
2414 Also handle vendor-identifying vendor-encapsulated options,
2415 dhcp-option = vi-encap:13,17,.......
2416 The may be more that one "outer" to do, so group
2417 all the options which match each outer in turn. */
2418 for (opt
= config_opts
; opt
; opt
= opt
->next
)
2419 opt
->flags
&= ~DHOPT_ENCAP_DONE
;
2421 for (opt
= config_opts
; opt
; opt
= opt
->next
)
2425 if ((flags
= (opt
->flags
& (DHOPT_ENCAPSULATE
| DHOPT_RFC3925
))))
2430 if (opt
->flags
& DHOPT_ENCAP_DONE
)
2433 for (len
= 0, o
= config_opts
; o
; o
= o
->next
)
2435 int outer
= flags
& DHOPT_ENCAPSULATE
? o
->u
.encap
: OPTION_VENDOR_IDENT_OPT
;
2437 o
->flags
&= ~DHOPT_ENCAP_MATCH
;
2439 if (!(o
->flags
& flags
) || opt
->u
.encap
!= o
->u
.encap
)
2442 o
->flags
|= DHOPT_ENCAP_DONE
;
2443 if (match_netid(o
->netid
, tagif
, 1) &&
2444 ((o
->flags
& DHOPT_FORCE
) || in_list(req_options
, outer
)))
2446 o
->flags
|= DHOPT_ENCAP_MATCH
;
2448 len
+= do_opt(o
, NULL
, NULL
, 0) + 2;
2454 if (flags
& DHOPT_ENCAPSULATE
)
2455 do_encap_opts(config_opts
, opt
->u
.encap
, DHOPT_ENCAP_MATCH
, mess
, end
, null_term
);
2457 my_syslog(MS_DHCP
| LOG_WARNING
, _("cannot send RFC3925 option: too many options for enterprise number %d"), opt
->u
.encap
);
2458 else if ((p
= free_space(mess
, end
, OPTION_VENDOR_IDENT_OPT
, len
+ 5)))
2460 int swap_ent
= htonl(opt
->u
.encap
);
2461 memcpy(p
, &swap_ent
, 4);
2464 for (o
= config_opts
; o
; o
= o
->next
)
2465 if (o
->flags
& DHOPT_ENCAP_MATCH
)
2467 len
= do_opt(o
, p
+ 2, NULL
, 0);
2477 force_encap
= prune_vendor_opts(tagif
);
2479 if (context
&& pxe_arch
!= -1)
2481 pxe_misc(mess
, end
, uuid
);
2482 config_opts
= pxe_opts(pxe_arch
, tagif
, context
->local
, now
);
2485 if ((force_encap
|| in_list(req_options
, OPTION_VENDOR_CLASS_OPT
)) &&
2486 do_encap_opts(config_opts
, OPTION_VENDOR_CLASS_OPT
, DHOPT_VENDOR_MATCH
, mess
, end
, null_term
) &&
2487 pxe_arch
== -1 && !done_vendor_class
&& vendor_class_len
!= 0 &&
2488 (p
= free_space(mess
, end
, OPTION_VENDOR_ID
, vendor_class_len
)))
2489 /* If we send vendor encapsulated options, and haven't already sent option 60,
2490 echo back the value we got from the client. */
2491 memcpy(p
, daemon
->dhcp_buff3
, vendor_class_len
);
2493 /* restore BOOTP anti-overload hack */
2494 if (!req_options
|| option_bool(OPT_NO_OVERRIDE
))
2497 mess
->sname
[0] = s0
;