]>
git.ipfire.org Git - people/ms/dnsmasq.git/blob - src/rfc2131.c
1 /* dnsmasq is Copyright (c) 2000-2012 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 void do_options(struct dhcp_context
*context
,
43 struct dhcp_packet
*mess
,
44 unsigned char *real_end
,
45 unsigned char *req_options
,
48 struct dhcp_netid
*netid
,
49 struct in_addr subnet_addr
,
50 unsigned char fqdn_flags
,
51 int null_term
, int pxearch
,
57 static void match_vendor_opts(unsigned char *opt
, struct dhcp_opt
*dopt
);
58 static int do_encap_opts(struct dhcp_opt
*opts
, int encap
, int flag
, struct dhcp_packet
*mess
, unsigned char *end
, int null_term
);
59 static void pxe_misc(struct dhcp_packet
*mess
, unsigned char *end
, unsigned char *uuid
);
60 static int prune_vendor_opts(struct dhcp_netid
*netid
);
61 static struct dhcp_opt
*pxe_opts(int pxe_arch
, struct dhcp_netid
*netid
, struct in_addr local
, time_t now
);
62 struct dhcp_boot
*find_boot(struct dhcp_netid
*netid
);
65 size_t dhcp_reply(struct dhcp_context
*context
, char *iface_name
, int int_index
,
66 size_t sz
, time_t now
, int unicast_dest
, int *is_inform
, int pxe
, struct in_addr fallback
)
68 unsigned char *opt
, *clid
= NULL
;
69 struct dhcp_lease
*ltmp
, *lease
= NULL
;
70 struct dhcp_vendor
*vendor
;
72 struct dhcp_netid_list
*id_list
;
73 int clid_len
= 0, ignore
= 0, do_classes
= 0, selecting
= 0, pxearch
= -1;
74 struct dhcp_packet
*mess
= (struct dhcp_packet
*)daemon
->dhcp_packet
.iov_base
;
75 unsigned char *end
= (unsigned char *)(mess
+ 1);
76 unsigned char *real_end
= (unsigned char *)(mess
+ 1);
77 char *hostname
= NULL
, *offer_hostname
= NULL
, *client_hostname
= NULL
, *domain
= NULL
;
78 int hostname_auth
= 0, borken_opt
= 0;
79 unsigned char *req_options
= NULL
;
82 struct dhcp_config
*config
;
83 struct dhcp_netid
*netid
, *tagif_netid
;
84 struct in_addr subnet_addr
, override
;
85 unsigned short fuzz
= 0;
86 unsigned int mess_type
= 0;
87 unsigned char fqdn_flags
= 0;
88 unsigned char *agent_id
= NULL
, *uuid
= NULL
;
89 unsigned char *emac
= NULL
;
90 int vendor_class_len
= 0, emac_len
= 0;
91 struct dhcp_netid known_id
, iface_id
, cpewan_id
;
93 unsigned char pxe_uuid
[17];
94 unsigned char *oui
= NULL
, *serial
= NULL
, *class = NULL
;
96 subnet_addr
.s_addr
= override
.s_addr
= 0;
98 /* set tag with name == interface */
99 iface_id
.net
= iface_name
;
100 iface_id
.next
= NULL
;
103 if (mess
->op
!= BOOTREQUEST
|| mess
->hlen
> DHCP_CHADDR_MAX
)
106 if (mess
->htype
== 0 && mess
->hlen
!= 0)
109 /* check for DHCP rather than BOOTP */
110 if ((opt
= option_find(mess
, sz
, OPTION_MESSAGE_TYPE
, 1)))
112 u32 cookie
= htonl(DHCP_COOKIE
);
114 /* only insist on a cookie for DHCP. */
115 if (memcmp(mess
->options
, &cookie
, sizeof(u32
)) != 0)
118 mess_type
= option_uint(opt
, 0, 1);
120 /* two things to note here: expand_buf may move the packet,
121 so reassign mess from daemon->packet. Also, the size
122 sent includes the IP and UDP headers, hence the magic "-28" */
123 if ((opt
= option_find(mess
, sz
, OPTION_MAXMESSAGE
, 2)))
125 size_t size
= (size_t)option_uint(opt
, 0, 2) - 28;
127 if (size
> DHCP_PACKET_MAX
)
128 size
= DHCP_PACKET_MAX
;
129 else if (size
< sizeof(struct dhcp_packet
))
130 size
= sizeof(struct dhcp_packet
);
132 if (expand_buf(&daemon
->dhcp_packet
, size
))
134 mess
= (struct dhcp_packet
*)daemon
->dhcp_packet
.iov_base
;
135 real_end
= end
= ((unsigned char *)mess
) + size
;
139 /* Some buggy clients set ciaddr when they shouldn't, so clear that here since
140 it can affect the context-determination code. */
141 if ((option_find(mess
, sz
, OPTION_REQUESTED_IP
, INADDRSZ
) || mess_type
== DHCPDISCOVER
))
142 mess
->ciaddr
.s_addr
= 0;
144 /* search for device identity from CPEWAN devices, we pass this through to the script */
145 if ((opt
= option_find(mess
, sz
, OPTION_VENDOR_IDENT_OPT
, 5)))
147 unsigned int elen
, offset
, len
= option_len(opt
);
149 for (offset
= 0; offset
< (len
- 5); offset
+= elen
+ 5)
151 elen
= option_uint(opt
, offset
+ 4 , 1);
152 if (option_uint(opt
, offset
, 4) == BRDBAND_FORUM_IANA
)
154 unsigned char *x
= option_ptr(opt
, offset
+ 5);
155 unsigned char *y
= option_ptr(opt
, offset
+ elen
+ 5);
156 oui
= option_find1(x
, y
, 1, 1);
157 serial
= option_find1(x
, y
, 2, 1);
158 class = option_find1(x
, y
, 3, 1);
160 /* If TR069-id is present set the tag "cpewan-id" to facilitate echoing
161 the gateway id back. Note that the device class is optional */
164 cpewan_id
.net
= "cpewan-id";
165 cpewan_id
.next
= netid
;
173 if ((opt
= option_find(mess
, sz
, OPTION_AGENT_ID
, 1)))
175 /* Any agent-id needs to be copied back out, verbatim, as the last option
176 in the packet. Here, we shift it to the very end of the buffer, if it doesn't
177 get overwritten, then it will be shuffled back at the end of processing.
178 Note that the incoming options must not be overwritten here, so there has to
179 be enough free space at the end of the packet to copy the option. */
181 unsigned int total
= option_len(opt
) + 2;
182 unsigned char *last_opt
= option_find(mess
, sz
, OPTION_END
, 0);
183 if (last_opt
&& last_opt
< end
- total
)
187 memcpy(agent_id
, opt
, total
);
190 /* look for RFC3527 Link selection sub-option */
191 if ((sopt
= option_find1(option_ptr(opt
, 0), option_ptr(opt
, option_len(opt
)), SUBOPT_SUBNET_SELECT
, INADDRSZ
)))
192 subnet_addr
= option_addr(sopt
);
194 /* look for RFC5107 server-identifier-override */
195 if ((sopt
= option_find1(option_ptr(opt
, 0), option_ptr(opt
, option_len(opt
)), SUBOPT_SERVER_OR
, INADDRSZ
)))
196 override
= option_addr(sopt
);
198 /* if a circuit-id or remote-is option is provided, exact-match to options. */
199 for (vendor
= daemon
->dhcp_vendors
; vendor
; vendor
= vendor
->next
)
203 if (vendor
->match_type
== MATCH_CIRCUIT
)
204 search
= SUBOPT_CIRCUIT_ID
;
205 else if (vendor
->match_type
== MATCH_REMOTE
)
206 search
= SUBOPT_REMOTE_ID
;
207 else if (vendor
->match_type
== MATCH_SUBSCRIBER
)
208 search
= SUBOPT_SUBSCR_ID
;
212 if ((sopt
= option_find1(option_ptr(opt
, 0), option_ptr(opt
, option_len(opt
)), search
, 1)) &&
213 vendor
->len
== option_len(sopt
) &&
214 memcmp(option_ptr(sopt
, 0), vendor
->data
, vendor
->len
) == 0)
216 vendor
->netid
.next
= netid
;
217 netid
= &vendor
->netid
;
222 /* Check for RFC3011 subnet selector - only if RFC3527 one not present */
223 if (subnet_addr
.s_addr
== 0 && (opt
= option_find(mess
, sz
, OPTION_SUBNET_SELECT
, INADDRSZ
)))
224 subnet_addr
= option_addr(opt
);
226 /* If there is no client identifier option, use the hardware address */
227 if ((opt
= option_find(mess
, sz
, OPTION_CLIENT_ID
, 1)))
229 clid_len
= option_len(opt
);
230 clid
= option_ptr(opt
, 0);
233 /* do we have a lease in store? */
234 lease
= lease_find_by_client(mess
->chaddr
, mess
->hlen
, mess
->htype
, clid
, clid_len
);
236 /* If this request is missing a clid, but we've seen one before,
237 use it again for option matching etc. */
238 if (lease
&& !clid
&& lease
->clid
)
240 clid_len
= lease
->clid_len
;
244 /* find mac to use for logging and hashing */
245 emac
= extended_hwaddr(mess
->htype
, mess
->hlen
, mess
->chaddr
, clid_len
, clid
, &emac_len
);
248 for (mac
= daemon
->dhcp_macs
; mac
; mac
= mac
->next
)
249 if (mac
->hwaddr_len
== mess
->hlen
&&
250 (mac
->hwaddr_type
== mess
->htype
|| mac
->hwaddr_type
== 0) &&
251 memcmp_masked(mac
->hwaddr
, mess
->chaddr
, mess
->hlen
, mac
->mask
))
253 mac
->netid
.next
= netid
;
257 /* Determine network for this packet. Our caller will have already linked all the
258 contexts which match the addresses of the receiving interface but if the
259 machine has an address already, or came via a relay, or we have a subnet selector,
260 we search again. If we don't have have a giaddr or explicit subnet selector,
261 use the ciaddr. This is necessary because a machine which got a lease via a
262 relay won't use the relay to renew. If matching a ciaddr fails but we have a context
263 from the physical network, continue using that to allow correct DHCPNAK generation later. */
264 if (mess
->giaddr
.s_addr
|| subnet_addr
.s_addr
|| mess
->ciaddr
.s_addr
)
266 struct dhcp_context
*context_tmp
, *context_new
= NULL
;
270 if (subnet_addr
.s_addr
)
275 else if (mess
->giaddr
.s_addr
)
282 /* If ciaddr is in the hardware derived set of contexts, leave that unchanged */
284 for (context_tmp
= context
; context_tmp
; context_tmp
= context_tmp
->current
)
285 if (context_tmp
->netmask
.s_addr
&&
286 is_same_net(addr
, context_tmp
->start
, context_tmp
->netmask
) &&
287 is_same_net(addr
, context_tmp
->end
, context_tmp
->netmask
))
289 context_new
= context
;
295 for (context_tmp
= daemon
->dhcp
; context_tmp
; context_tmp
= context_tmp
->next
)
297 struct in_addr netmask
= context_tmp
->netmask
;
299 /* guess the netmask for relayed networks */
300 if (!(context_tmp
->flags
& CONTEXT_NETMASK
) && context_tmp
->netmask
.s_addr
== 0)
302 if (IN_CLASSA(ntohl(context_tmp
->start
.s_addr
)) && IN_CLASSA(ntohl(context_tmp
->end
.s_addr
)))
303 netmask
.s_addr
= htonl(0xff000000);
304 else if (IN_CLASSB(ntohl(context_tmp
->start
.s_addr
)) && IN_CLASSB(ntohl(context_tmp
->end
.s_addr
)))
305 netmask
.s_addr
= htonl(0xffff0000);
306 else if (IN_CLASSC(ntohl(context_tmp
->start
.s_addr
)) && IN_CLASSC(ntohl(context_tmp
->end
.s_addr
)))
307 netmask
.s_addr
= htonl(0xffffff00);
310 /* This section fills in context mainly when a client which is on a remote (relayed)
311 network renews a lease without using the relay, after dnsmasq has restarted. */
312 if (netmask
.s_addr
!= 0 &&
313 is_same_net(addr
, context_tmp
->start
, netmask
) &&
314 is_same_net(addr
, context_tmp
->end
, netmask
))
316 context_tmp
->netmask
= netmask
;
317 if (context_tmp
->local
.s_addr
== 0)
318 context_tmp
->local
= fallback
;
319 if (context_tmp
->router
.s_addr
== 0)
320 context_tmp
->router
= mess
->giaddr
;
322 /* fill in missing broadcast addresses for relayed ranges */
323 if (!(context_tmp
->flags
& CONTEXT_BRDCAST
) && context_tmp
->broadcast
.s_addr
== 0 )
324 context_tmp
->broadcast
.s_addr
= context_tmp
->start
.s_addr
| ~context_tmp
->netmask
.s_addr
;
326 context_tmp
->current
= context_new
;
327 context_new
= context_tmp
;
331 if (context_new
|| force
)
332 context
= context_new
;
337 my_syslog(MS_DHCP
| LOG_WARNING
, _("no address range available for DHCP request %s %s"),
338 subnet_addr
.s_addr
? _("with subnet selector") : _("via"),
339 subnet_addr
.s_addr
? inet_ntoa(subnet_addr
) : (mess
->giaddr
.s_addr
? inet_ntoa(mess
->giaddr
) : iface_name
));
343 if (option_bool(OPT_LOG_OPTS
))
345 struct dhcp_context
*context_tmp
;
346 for (context_tmp
= context
; context_tmp
; context_tmp
= context_tmp
->current
)
348 strcpy(daemon
->namebuff
, inet_ntoa(context_tmp
->start
));
349 if (context_tmp
->flags
& (CONTEXT_STATIC
| CONTEXT_PROXY
))
350 my_syslog(MS_DHCP
| LOG_INFO
, _("%u available DHCP subnet: %s/%s"),
351 ntohl(mess
->xid
), daemon
->namebuff
, inet_ntoa(context_tmp
->netmask
));
353 my_syslog(MS_DHCP
| LOG_INFO
, _("%u available DHCP range: %s -- %s"),
354 ntohl(mess
->xid
), daemon
->namebuff
, inet_ntoa(context_tmp
->end
));
358 mess
->op
= BOOTREPLY
;
360 config
= find_config(daemon
->dhcp_conf
, context
, clid
, clid_len
,
361 mess
->chaddr
, mess
->hlen
, mess
->htype
, NULL
);
363 /* set "known" tag for known hosts */
366 known_id
.net
= "known";
367 known_id
.next
= netid
;
371 if (mess_type
== 0 && !pxe
)
374 struct dhcp_netid id
, bootp_id
;
375 struct in_addr
*logaddr
= NULL
;
377 /* must have a MAC addr for bootp */
378 if (mess
->htype
== 0 || mess
->hlen
== 0 || (context
->flags
& CONTEXT_PROXY
))
381 if (have_config(config
, CONFIG_DISABLE
))
382 message
= _("disabled");
384 end
= mess
->options
+ 64; /* BOOTP vend area is only 64 bytes */
386 if (have_config(config
, CONFIG_NAME
))
388 hostname
= config
->hostname
;
389 domain
= config
->domain
;
394 struct dhcp_netid_list
*list
;
396 for (list
= config
->netid
; list
; list
= list
->next
)
398 list
->list
->next
= netid
;
403 /* Match incoming filename field as a netid. */
406 memcpy(daemon
->dhcp_buff2
, mess
->file
, sizeof(mess
->file
));
407 daemon
->dhcp_buff2
[sizeof(mess
->file
) + 1] = 0; /* ensure zero term. */
408 id
.net
= (char *)daemon
->dhcp_buff2
;
413 /* Add "bootp" as a tag to allow different options, address ranges etc
415 bootp_id
.net
= "bootp";
416 bootp_id
.next
= netid
;
419 tagif_netid
= run_tag_if(netid
);
421 for (id_list
= daemon
->dhcp_ignore
; id_list
; id_list
= id_list
->next
)
422 if (match_netid(id_list
->list
, tagif_netid
, 0))
423 message
= _("ignored");
429 if (have_config(config
, CONFIG_ADDR
))
432 logaddr
= &config
->addr
;
433 mess
->yiaddr
= config
->addr
;
434 if ((lease
= lease_find_by_addr(config
->addr
)) &&
435 (lease
->hwaddr_len
!= mess
->hlen
||
436 lease
->hwaddr_type
!= mess
->htype
||
437 memcmp(lease
->hwaddr
, mess
->chaddr
, lease
->hwaddr_len
) != 0))
438 message
= _("address in use");
442 if (!(lease
= lease_find_by_client(mess
->chaddr
, mess
->hlen
, mess
->htype
, NULL
, 0)) ||
443 !address_available(context
, lease
->addr
, tagif_netid
))
447 /* lease exists, wrong network. */
448 lease_prune(lease
, now
);
451 if (!address_allocate(context
, &mess
->yiaddr
, mess
->chaddr
, mess
->hlen
, tagif_netid
, now
))
452 message
= _("no address available");
455 mess
->yiaddr
= lease
->addr
;
458 if (!message
&& !(context
= narrow_context(context
, mess
->yiaddr
, netid
)))
459 message
= _("wrong network");
460 else if (context
->netid
.net
)
462 context
->netid
.next
= netid
;
463 tagif_netid
= run_tag_if(&context
->netid
);
466 log_tags(tagif_netid
, ntohl(mess
->xid
));
468 if (!message
&& !nailed
)
470 for (id_list
= daemon
->bootp_dynamic
; id_list
; id_list
= id_list
->next
)
471 if ((!id_list
->list
) || match_netid(id_list
->list
, tagif_netid
, 0))
474 message
= _("no address configured");
479 (!(lease
= lease4_allocate(mess
->yiaddr
))))
480 message
= _("no leases left");
484 logaddr
= &mess
->yiaddr
;
486 lease_set_hwaddr(lease
, mess
->chaddr
, NULL
, mess
->hlen
, mess
->htype
, 0, now
);
488 lease_set_hostname(lease
, hostname
, 1, get_domain(lease
->addr
), domain
);
489 /* infinite lease unless nailed in dhcp-host line. */
490 lease_set_expires(lease
,
491 have_config(config
, CONFIG_TIME
) ? config
->lease_time
: 0xffffffff,
493 lease_set_interface(lease
, int_index
, now
);
495 clear_packet(mess
, end
);
496 do_options(context
, mess
, end
, NULL
, hostname
, get_domain(mess
->yiaddr
),
497 netid
, subnet_addr
, 0, 0, 0, NULL
, 0, now
);
501 log_packet("BOOTP", logaddr
, mess
->chaddr
, mess
->hlen
, iface_name
, message
, mess
->xid
);
503 return message
? 0 : dhcp_packet_size(mess
, agent_id
, real_end
);
506 if ((opt
= option_find(mess
, sz
, OPTION_CLIENT_FQDN
, 4)))
508 /* http://tools.ietf.org/wg/dhc/draft-ietf-dhc-fqdn-option/draft-ietf-dhc-fqdn-option-10.txt */
509 int len
= option_len(opt
);
510 char *pq
= daemon
->dhcp_buff
;
511 unsigned char *pp
, *op
= option_ptr(opt
, 0);
518 /* Always force update, since the client has no way to do it itself. */
519 if (!option_bool(OPT_FQDN_UPDATE
) && !(fqdn_flags
& 0x01))
524 if (fqdn_flags
& 0x04)
525 while (*op
!= 0 && ((op
+ (*op
) + 1) - pp
) < len
)
527 memcpy(pq
, op
+1, *op
);
535 if (len
> 0 && op
[len
-1] == 0)
540 if (pq
!= daemon
->dhcp_buff
)
545 if (legal_hostname(daemon
->dhcp_buff
))
546 offer_hostname
= client_hostname
= daemon
->dhcp_buff
;
548 else if ((opt
= option_find(mess
, sz
, OPTION_HOSTNAME
, 1)))
550 int len
= option_len(opt
);
551 memcpy(daemon
->dhcp_buff
, option_ptr(opt
, 0), len
);
552 /* Microsoft clients are broken, and need zero-terminated strings
553 in options. We detect this state here, and do the same in
554 any options we send */
555 if (len
> 0 && daemon
->dhcp_buff
[len
-1] == 0)
558 daemon
->dhcp_buff
[len
] = 0;
559 if (legal_hostname(daemon
->dhcp_buff
))
560 client_hostname
= daemon
->dhcp_buff
;
563 if (client_hostname
&& option_bool(OPT_LOG_OPTS
))
564 my_syslog(MS_DHCP
| LOG_INFO
, _("%u client provides name: %s"), ntohl(mess
->xid
), client_hostname
);
566 if (have_config(config
, CONFIG_NAME
))
568 hostname
= config
->hostname
;
569 domain
= config
->domain
;
571 /* be careful not to send an OFFER with a hostname not matching the DISCOVER. */
572 if (fqdn_flags
!= 0 || !client_hostname
|| hostname_isequal(hostname
, client_hostname
))
573 offer_hostname
= hostname
;
575 else if (client_hostname
)
577 domain
= strip_hostname(client_hostname
);
579 if (strlen(client_hostname
) != 0)
581 hostname
= client_hostname
;
584 /* Search again now we have a hostname.
585 Only accept configs without CLID and HWADDR here, (they won't match)
586 to avoid impersonation by name. */
587 struct dhcp_config
*new = find_config(daemon
->dhcp_conf
, context
, NULL
, 0,
588 mess
->chaddr
, mess
->hlen
,
589 mess
->htype
, hostname
);
590 if (new && !have_config(new, CONFIG_CLID
) && !new->hwaddr
)
593 /* set "known" tag for known hosts */
594 known_id
.net
= "known";
595 known_id
.next
= netid
;
604 struct dhcp_netid_list
*list
;
606 for (list
= config
->netid
; list
; list
= list
->next
)
608 list
->list
->next
= netid
;
613 /* dhcp-match. If we have hex-and-wildcards, look for a left-anchored match.
614 Otherwise assume the option is an array, and look for a matching element.
615 If no data given, existance of the option is enough. This code handles
616 rfc3925 V-I classes too. */
617 for (o
= daemon
->dhcp_match
; o
; o
= o
->next
)
619 unsigned int len
, elen
, match
= 0;
622 if (o
->flags
& DHOPT_RFC3925
)
624 if (!(opt
= option_find(mess
, sz
, OPTION_VENDOR_IDENT
, 5)))
627 for (offset
= 0; offset
< (option_len(opt
) - 5u); offset
+= len
+ 5)
629 len
= option_uint(opt
, offset
+ 4 , 1);
630 /* Need to take care that bad data can't run us off the end of the packet */
631 if ((offset
+ len
+ 5 <= (option_len(opt
))) &&
632 (option_uint(opt
, offset
, 4) == (unsigned int)o
->u
.encap
))
633 for (o2
= offset
+ 5; o2
< offset
+ len
+ 5; o2
+= elen
+ 1)
635 elen
= option_uint(opt
, o2
, 1);
636 if ((o2
+ elen
+ 1 <= option_len(opt
)) &&
637 (match
= match_bytes(o
, option_ptr(opt
, o2
+ 1), elen
)))
646 if (!(opt
= option_find(mess
, sz
, o
->opt
, 1)))
649 match
= match_bytes(o
, option_ptr(opt
, 0), option_len(opt
));
654 o
->netid
->next
= netid
;
659 /* user-class options are, according to RFC3004, supposed to contain
660 a set of counted strings. Here we check that this is so (by seeing
661 if the counts are consistent with the overall option length) and if
662 so zero the counts so that we don't get spurious matches between
663 the vendor string and the counts. If the lengths don't add up, we
664 assume that the option is a single string and non RFC3004 compliant
665 and just do the substring match. dhclient provides these broken options.
666 The code, later, which sends user-class data to the lease-change script
667 relies on the transformation done here.
670 if ((opt
= option_find(mess
, sz
, OPTION_USER_CLASS
, 1)))
672 unsigned char *ucp
= option_ptr(opt
, 0);
674 for (j
= 0; j
< option_len(opt
); j
+= ucp
[j
] + 1);
675 if (j
== option_len(opt
))
676 for (j
= 0; j
< option_len(opt
); j
= tmp
)
678 tmp
= j
+ ucp
[j
] + 1;
683 for (vendor
= daemon
->dhcp_vendors
; vendor
; vendor
= vendor
->next
)
687 if (vendor
->match_type
== MATCH_VENDOR
)
688 mopt
= OPTION_VENDOR_ID
;
689 else if (vendor
->match_type
== MATCH_USER
)
690 mopt
= OPTION_USER_CLASS
;
694 if ((opt
= option_find(mess
, sz
, mopt
, 1)))
697 for (i
= 0; i
<= (option_len(opt
) - vendor
->len
); i
++)
698 if (memcmp(vendor
->data
, option_ptr(opt
, i
), vendor
->len
) == 0)
700 vendor
->netid
.next
= netid
;
701 netid
= &vendor
->netid
;
707 /* mark vendor-encapsulated options which match the client-supplied vendor class,
708 save client-supplied vendor class */
709 if ((opt
= option_find(mess
, sz
, OPTION_VENDOR_ID
, 1)))
711 memcpy(daemon
->dhcp_buff3
, option_ptr(opt
, 0), option_len(opt
));
712 vendor_class_len
= option_len(opt
);
714 match_vendor_opts(opt
, daemon
->dhcp_opts
);
716 if (option_bool(OPT_LOG_OPTS
))
718 if (sanitise(opt
, daemon
->namebuff
))
719 my_syslog(MS_DHCP
| LOG_INFO
, _("%u vendor class: %s"), ntohl(mess
->xid
), daemon
->namebuff
);
720 if (sanitise(option_find(mess
, sz
, OPTION_USER_CLASS
, 1), daemon
->namebuff
))
721 my_syslog(MS_DHCP
| LOG_INFO
, _("%u user class: %s"), ntohl(mess
->xid
), daemon
->namebuff
);
724 tagif_netid
= run_tag_if(netid
);
726 /* if all the netids in the ignore list are present, ignore this client */
727 for (id_list
= daemon
->dhcp_ignore
; id_list
; id_list
= id_list
->next
)
728 if (match_netid(id_list
->list
, tagif_netid
, 0))
731 /* If configured, we can override the server-id to be the address of the relay,
732 so that all traffic goes via the relay and can pick up agent-id info. This can be
733 configured for all relays, or by address. */
734 if (daemon
->override
&& mess
->giaddr
.s_addr
!= 0 && override
.s_addr
== 0)
736 if (!daemon
->override_relays
)
737 override
= mess
->giaddr
;
741 for (l
= daemon
->override_relays
; l
; l
= l
->next
)
742 if (l
->addr
.s_addr
== mess
->giaddr
.s_addr
)
745 override
= mess
->giaddr
;
749 /* Can have setting to ignore the client ID for a particular MAC address or hostname */
750 if (have_config(config
, CONFIG_NOCLID
))
753 /* Check if client is PXE client. */
754 if (daemon
->enable_pxe
&&
755 (opt
= option_find(mess
, sz
, OPTION_VENDOR_ID
, 9)) &&
756 strncmp(option_ptr(opt
, 0), "PXEClient", 9) == 0)
758 if ((opt
= option_find(mess
, sz
, OPTION_PXE_UUID
, 17)))
760 memcpy(pxe_uuid
, option_ptr(opt
, 0), 17);
764 /* Check if this is really a PXE bootserver request, and handle specially if so. */
765 if ((mess_type
== DHCPREQUEST
|| mess_type
== DHCPINFORM
) &&
766 (opt
= option_find(mess
, sz
, OPTION_VENDOR_CLASS_OPT
, 1)) &&
767 (opt
= option_find1(option_ptr(opt
, 0), option_ptr(opt
, option_len(opt
)), SUBOPT_PXE_BOOT_ITEM
, 4)))
769 struct pxe_service
*service
;
770 int type
= option_uint(opt
, 0, 2);
771 int layer
= option_uint(opt
, 2, 2);
772 unsigned char save71
[4];
773 struct dhcp_opt opt71
;
780 my_syslog(MS_DHCP
| LOG_ERR
, _("PXE BIS not supported"));
784 memcpy(save71
, option_ptr(opt
, 0), 4);
786 for (service
= daemon
->pxe_services
; service
; service
= service
->next
)
787 if (service
->type
== type
)
790 if (!service
|| !service
->basename
)
793 clear_packet(mess
, end
);
795 mess
->yiaddr
= mess
->ciaddr
;
796 mess
->ciaddr
.s_addr
= 0;
798 mess
->siaddr
= a_record_from_hosts(service
->sname
, now
);
799 else if (service
->server
.s_addr
!= 0)
800 mess
->siaddr
= service
->server
;
802 mess
->siaddr
= context
->local
;
804 snprintf((char *)mess
->file
, sizeof(mess
->file
), "%s.%d", service
->basename
, layer
);
805 option_put(mess
, end
, OPTION_MESSAGE_TYPE
, 1, DHCPACK
);
806 option_put(mess
, end
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
, htonl(context
->local
.s_addr
));
807 pxe_misc(mess
, end
, uuid
);
809 prune_vendor_opts(tagif_netid
);
811 opt71
.opt
= SUBOPT_PXE_BOOT_ITEM
;
813 opt71
.flags
= DHOPT_VENDOR_MATCH
;
815 opt71
.next
= daemon
->dhcp_opts
;
816 do_encap_opts(&opt71
, OPTION_VENDOR_CLASS_OPT
, DHOPT_VENDOR_MATCH
, mess
, end
, 0);
818 log_packet("PXE", &mess
->yiaddr
, emac
, emac_len
, iface_name
, (char *)mess
->file
, mess
->xid
);
819 log_tags(tagif_netid
, ntohl(mess
->xid
));
820 return dhcp_packet_size(mess
, agent_id
, real_end
);
823 if ((opt
= option_find(mess
, sz
, OPTION_ARCH
, 2)))
825 pxearch
= option_uint(opt
, 0, 2);
827 /* proxy DHCP here. */
828 if ((mess_type
== DHCPDISCOVER
|| (pxe
&& mess_type
== DHCPREQUEST
)))
830 struct dhcp_context
*tmp
;
832 for (tmp
= context
; tmp
; tmp
= tmp
->current
)
833 if ((tmp
->flags
& CONTEXT_PROXY
) &&
834 match_netid(tmp
->filter
, tagif_netid
, 1))
839 struct dhcp_boot
*boot
= find_boot(tagif_netid
);
841 mess
->yiaddr
.s_addr
= 0;
842 if (mess_type
== DHCPDISCOVER
|| mess
->ciaddr
.s_addr
== 0)
844 mess
->ciaddr
.s_addr
= 0;
845 mess
->flags
|= htons(0x8000); /* broadcast */
848 clear_packet(mess
, end
);
850 /* Provide the bootfile here, for gPXE, and in case we have no menu items
851 and set discovery_control = 8 */
854 if (boot
->next_server
.s_addr
)
855 mess
->siaddr
= boot
->next_server
;
856 else if (boot
->tftp_sname
)
857 mess
->siaddr
= a_record_from_hosts(boot
->tftp_sname
, now
);
860 strncpy((char *)mess
->file
, boot
->file
, sizeof(mess
->file
)-1);
863 option_put(mess
, end
, OPTION_MESSAGE_TYPE
, 1,
864 mess_type
== DHCPDISCOVER
? DHCPOFFER
: DHCPACK
);
865 option_put(mess
, end
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
, htonl(context
->local
.s_addr
));
866 pxe_misc(mess
, end
, uuid
);
867 prune_vendor_opts(tagif_netid
);
868 do_encap_opts(pxe_opts(pxearch
, tagif_netid
, context
->local
, now
), OPTION_VENDOR_CLASS_OPT
, DHOPT_VENDOR_MATCH
, mess
, end
, 0);
870 log_packet("PXE", NULL
, emac
, emac_len
, iface_name
, ignore
? "proxy-ignored" : "proxy", mess
->xid
);
871 log_tags(tagif_netid
, ntohl(mess
->xid
));
872 return ignore
? 0 : dhcp_packet_size(mess
, agent_id
, real_end
);
878 /* if we're just a proxy server, go no further */
879 if ((context
->flags
& CONTEXT_PROXY
) || pxe
)
882 if ((opt
= option_find(mess
, sz
, OPTION_REQUESTED_OPTIONS
, 0)))
884 req_options
= (unsigned char *)daemon
->dhcp_buff2
;
885 memcpy(req_options
, option_ptr(opt
, 0), option_len(opt
));
886 req_options
[option_len(opt
)] = OPTION_END
;
892 if (!(opt
= option_find(mess
, sz
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
)) ||
893 option_addr(opt
).s_addr
!= server_id(context
, override
, fallback
).s_addr
)
896 /* sanitise any message. Paranoid? Moi? */
897 sanitise(option_find(mess
, sz
, OPTION_MESSAGE
, 1), daemon
->dhcp_buff
);
899 if (!(opt
= option_find(mess
, sz
, OPTION_REQUESTED_IP
, INADDRSZ
)))
902 log_packet("DHCPDECLINE", option_ptr(opt
, 0), emac
, emac_len
, iface_name
, daemon
->dhcp_buff
, mess
->xid
);
904 if (lease
&& lease
->addr
.s_addr
== option_addr(opt
).s_addr
)
905 lease_prune(lease
, now
);
907 if (have_config(config
, CONFIG_ADDR
) &&
908 config
->addr
.s_addr
== option_addr(opt
).s_addr
)
910 prettyprint_time(daemon
->dhcp_buff
, DECLINE_BACKOFF
);
911 my_syslog(MS_DHCP
| LOG_WARNING
, _("disabling DHCP static address %s for %s"),
912 inet_ntoa(config
->addr
), daemon
->dhcp_buff
);
913 config
->flags
|= CONFIG_DECLINED
;
914 config
->decline_time
= now
;
917 /* make sure this host gets a different address next time. */
918 for (; context
; context
= context
->current
)
919 context
->addr_epoch
++;
924 if (!(context
= narrow_context(context
, mess
->ciaddr
, tagif_netid
)) ||
925 !(opt
= option_find(mess
, sz
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
)) ||
926 option_addr(opt
).s_addr
!= server_id(context
, override
, fallback
).s_addr
)
929 if (lease
&& lease
->addr
.s_addr
== mess
->ciaddr
.s_addr
)
930 lease_prune(lease
, now
);
932 message
= _("unknown lease");
934 log_packet("DHCPRELEASE", &mess
->ciaddr
, emac
, emac_len
, iface_name
, message
, mess
->xid
);
939 if (ignore
|| have_config(config
, CONFIG_DISABLE
))
941 message
= _("ignored");
946 struct in_addr addr
, conf
;
948 addr
.s_addr
= conf
.s_addr
= 0;
950 if ((opt
= option_find(mess
, sz
, OPTION_REQUESTED_IP
, INADDRSZ
)))
951 addr
= option_addr(opt
);
953 if (have_config(config
, CONFIG_ADDR
))
955 char *addrs
= inet_ntoa(config
->addr
);
957 if ((ltmp
= lease_find_by_addr(config
->addr
)) &&
959 !config_has_mac(config
, ltmp
->hwaddr
, ltmp
->hwaddr_len
, ltmp
->hwaddr_type
))
962 unsigned char *mac
= extended_hwaddr(ltmp
->hwaddr_type
, ltmp
->hwaddr_len
,
963 ltmp
->hwaddr
, ltmp
->clid_len
, ltmp
->clid
, &len
);
964 my_syslog(MS_DHCP
| LOG_WARNING
, _("not using configured address %s because it is leased to %s"),
965 addrs
, print_mac(daemon
->namebuff
, mac
, len
));
969 struct dhcp_context
*tmp
;
970 for (tmp
= context
; tmp
; tmp
= tmp
->current
)
971 if (context
->router
.s_addr
== config
->addr
.s_addr
)
974 my_syslog(MS_DHCP
| LOG_WARNING
, _("not using configured address %s because it is in use by the server or relay"), addrs
);
975 else if (have_config(config
, CONFIG_DECLINED
) &&
976 difftime(now
, config
->decline_time
) < (float)DECLINE_BACKOFF
)
977 my_syslog(MS_DHCP
| LOG_WARNING
, _("not using configured address %s because it was previously declined"), addrs
);
986 address_available(context
, lease
->addr
, tagif_netid
) &&
987 !config_find_by_address(daemon
->dhcp_conf
, lease
->addr
))
988 mess
->yiaddr
= lease
->addr
;
989 else if (opt
&& address_available(context
, addr
, tagif_netid
) && !lease_find_by_addr(addr
) &&
990 !config_find_by_address(daemon
->dhcp_conf
, addr
))
992 else if (emac_len
== 0)
993 message
= _("no unique-id");
994 else if (!address_allocate(context
, &mess
->yiaddr
, emac
, emac_len
, tagif_netid
, now
))
995 message
= _("no address available");
998 log_packet("DHCPDISCOVER", opt
? option_ptr(opt
, 0) : NULL
, emac
, emac_len
, iface_name
, message
, mess
->xid
);
1000 if (message
|| !(context
= narrow_context(context
, mess
->yiaddr
, tagif_netid
)))
1003 if (context
->netid
.net
)
1005 context
->netid
.next
= netid
;
1006 tagif_netid
= run_tag_if(&context
->netid
);
1009 log_tags(tagif_netid
, ntohl(mess
->xid
));
1011 log_packet("DHCPOFFER" , &mess
->yiaddr
, emac
, emac_len
, iface_name
, NULL
, mess
->xid
);
1013 time
= calc_time(context
, config
, option_find(mess
, sz
, OPTION_LEASE_TIME
, 4));
1014 clear_packet(mess
, end
);
1015 option_put(mess
, end
, OPTION_MESSAGE_TYPE
, 1, DHCPOFFER
);
1016 option_put(mess
, end
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
, ntohl(server_id(context
, override
, fallback
).s_addr
));
1017 option_put(mess
, end
, OPTION_LEASE_TIME
, 4, time
);
1018 /* T1 and T2 are required in DHCPOFFER by HP's wacky Jetdirect client. */
1019 if (time
!= 0xffffffff)
1021 option_put(mess
, end
, OPTION_T1
, 4, (time
/2));
1022 option_put(mess
, end
, OPTION_T2
, 4, (time
*7)/8);
1024 do_options(context
, mess
, end
, req_options
, offer_hostname
, get_domain(mess
->yiaddr
),
1025 netid
, subnet_addr
, fqdn_flags
, borken_opt
, pxearch
, uuid
, vendor_class_len
, now
);
1027 return dhcp_packet_size(mess
, agent_id
, real_end
);
1030 if (ignore
|| have_config(config
, CONFIG_DISABLE
))
1032 if ((opt
= option_find(mess
, sz
, OPTION_REQUESTED_IP
, INADDRSZ
)))
1034 /* SELECTING or INIT_REBOOT */
1035 mess
->yiaddr
= option_addr(opt
);
1037 /* send vendor and user class info for new or recreated lease */
1040 if ((opt
= option_find(mess
, sz
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
)))
1045 if (override
.s_addr
!= 0)
1047 if (option_addr(opt
).s_addr
!= override
.s_addr
)
1052 for (; context
; context
= context
->current
)
1053 if (context
->local
.s_addr
== option_addr(opt
).s_addr
)
1058 /* Handle very strange configs where clients have more than one route to the server.
1059 If a clients idea of its server-id matches any of our DHCP interfaces, we let it pass.
1060 Have to set override to make sure we echo back the correct server-id */
1063 enumerate_interfaces();
1065 for (intr
= daemon
->interfaces
; intr
; intr
= intr
->next
)
1066 if (intr
->addr
.sa
.sa_family
== AF_INET
&&
1067 intr
->addr
.in
.sin_addr
.s_addr
== option_addr(opt
).s_addr
&&
1072 override
= intr
->addr
.in
.sin_addr
;
1075 /* In auth mode, a REQUEST sent to the wrong server
1076 should be faulted, so that the client establishes
1077 communication with us, otherwise, silently ignore. */
1078 if (!option_bool(OPT_AUTHORITATIVE
))
1080 message
= _("wrong server-ID");
1085 /* If a lease exists for this host and another address, squash it. */
1086 if (lease
&& lease
->addr
.s_addr
!= mess
->yiaddr
.s_addr
)
1088 lease_prune(lease
, now
);
1095 if (!lease
&& !option_bool(OPT_AUTHORITATIVE
))
1098 if (lease
&& lease
->addr
.s_addr
!= mess
->yiaddr
.s_addr
)
1099 message
= _("wrong address");
1104 /* RENEWING or REBINDING */
1105 /* Check existing lease for this address.
1106 We allow it to be missing if dhcp-authoritative mode
1107 as long as we can allocate the lease now - checked below.
1108 This makes for a smooth recovery from a lost lease DB */
1109 if ((lease
&& mess
->ciaddr
.s_addr
!= lease
->addr
.s_addr
) ||
1110 (!lease
&& !option_bool(OPT_AUTHORITATIVE
)))
1112 /* A client rebinding will broadcast the request, so we may see it even
1113 if the lease is held by another server. Just ignore it in that case.
1114 If the request is unicast to us, then somethings wrong, NAK */
1117 message
= _("lease not found");
1118 /* ensure we broadcast NAK */
1122 /* desynchronise renewals */
1124 mess
->yiaddr
= mess
->ciaddr
;
1127 log_packet("DHCPREQUEST", &mess
->yiaddr
, emac
, emac_len
, iface_name
, NULL
, mess
->xid
);
1131 struct dhcp_config
*addr_config
;
1132 struct dhcp_context
*tmp
= NULL
;
1134 if (have_config(config
, CONFIG_ADDR
))
1135 for (tmp
= context
; tmp
; tmp
= tmp
->current
)
1136 if (context
->router
.s_addr
== config
->addr
.s_addr
)
1139 if (!(context
= narrow_context(context
, mess
->yiaddr
, tagif_netid
)))
1141 /* If a machine moves networks whilst it has a lease, we catch that here. */
1142 message
= _("wrong network");
1143 /* ensure we broadcast NAK */
1147 /* Check for renewal of a lease which is outside the allowed range. */
1148 else if (!address_available(context
, mess
->yiaddr
, tagif_netid
) &&
1149 (!have_config(config
, CONFIG_ADDR
) || config
->addr
.s_addr
!= mess
->yiaddr
.s_addr
))
1150 message
= _("address not available");
1152 /* Check if a new static address has been configured. Be very sure that
1153 when the client does DISCOVER, it will get the static address, otherwise
1154 an endless protocol loop will ensue. */
1155 else if (!tmp
&& !selecting
&&
1156 have_config(config
, CONFIG_ADDR
) &&
1157 (!have_config(config
, CONFIG_DECLINED
) ||
1158 difftime(now
, config
->decline_time
) > (float)DECLINE_BACKOFF
) &&
1159 config
->addr
.s_addr
!= mess
->yiaddr
.s_addr
&&
1160 (!(ltmp
= lease_find_by_addr(config
->addr
)) || ltmp
== lease
))
1161 message
= _("static lease available");
1163 /* Check to see if the address is reserved as a static address for another host */
1164 else if ((addr_config
= config_find_by_address(daemon
->dhcp_conf
, mess
->yiaddr
)) && addr_config
!= config
)
1165 message
= _("address reserved");
1167 else if (!lease
&& (ltmp
= lease_find_by_addr(mess
->yiaddr
)))
1169 /* If a host is configured with more than one MAC address, it's OK to 'nix
1170 a lease from one of it's MACs to give the address to another. */
1171 if (config
&& config_has_mac(config
, ltmp
->hwaddr
, ltmp
->hwaddr_len
, ltmp
->hwaddr_type
))
1173 my_syslog(MS_DHCP
| LOG_INFO
, _("abandoning lease to %s of %s"),
1174 print_mac(daemon
->namebuff
, ltmp
->hwaddr
, ltmp
->hwaddr_len
),
1175 inet_ntoa(ltmp
->addr
));
1179 message
= _("address in use");
1185 message
= _("no unique-id");
1189 if ((lease
= lease4_allocate(mess
->yiaddr
)))
1192 message
= _("no leases left");
1199 log_packet("DHCPNAK", &mess
->yiaddr
, emac
, emac_len
, iface_name
, message
, mess
->xid
);
1201 mess
->yiaddr
.s_addr
= 0;
1202 clear_packet(mess
, end
);
1203 option_put(mess
, end
, OPTION_MESSAGE_TYPE
, 1, DHCPNAK
);
1204 option_put(mess
, end
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
, ntohl(server_id(context
, override
, fallback
).s_addr
));
1205 option_put_string(mess
, end
, OPTION_MESSAGE
, message
, borken_opt
);
1206 /* This fixes a problem with the DHCP spec, broadcasting a NAK to a host on
1207 a distant subnet which unicast a REQ to us won't work. */
1208 if (!unicast_dest
|| mess
->giaddr
.s_addr
!= 0 ||
1209 mess
->ciaddr
.s_addr
== 0 || is_same_net(context
->local
, mess
->ciaddr
, context
->netmask
))
1211 mess
->flags
|= htons(0x8000); /* broadcast */
1212 mess
->ciaddr
.s_addr
= 0;
1217 if (context
->netid
.net
)
1219 context
->netid
.next
= netid
;
1220 tagif_netid
= run_tag_if( &context
->netid
);
1223 log_tags(tagif_netid
, ntohl(mess
->xid
));
1226 if (do_classes
&& daemon
->lease_change_command
)
1228 struct dhcp_netid
*n
;
1230 if (mess
->giaddr
.s_addr
)
1231 lease
->giaddr
= mess
->giaddr
;
1233 lease
->flags
|= LEASE_CHANGED
;
1234 free(lease
->extradata
);
1235 lease
->extradata
= NULL
;
1236 lease
->extradata_size
= lease
->extradata_len
= 0;
1238 add_extradata_opt(lease
, option_find(mess
, sz
, OPTION_VENDOR_ID
, 1));
1239 add_extradata_opt(lease
, option_find(mess
, sz
, OPTION_HOSTNAME
, 1));
1240 add_extradata_opt(lease
, oui
);
1241 add_extradata_opt(lease
, serial
);
1242 add_extradata_opt(lease
, class);
1244 /* space-concat tag set */
1246 add_extradata_opt(lease
, NULL
);
1248 for (n
= tagif_netid
; n
; n
= n
->next
)
1250 struct dhcp_netid
*n1
;
1252 for (n1
= n
->next
; n1
; n1
= n1
->next
)
1253 if (strcmp(n
->net
, n1
->net
) == 0)
1256 lease_add_extradata(lease
, (unsigned char *)n
->net
, strlen(n
->net
), n
->next
? ' ' : 0);
1259 if ((opt
= option_find(mess
, sz
, OPTION_USER_CLASS
, 1)))
1261 int len
= option_len(opt
);
1262 unsigned char *ucp
= option_ptr(opt
, 0);
1263 /* If the user-class option started as counted strings, the first byte will be zero. */
1264 if (len
!= 0 && ucp
[0] == 0)
1266 lease_add_extradata(lease
, ucp
, len
, 0);
1271 if (!hostname_auth
&& (client_hostname
= host_from_dns(mess
->yiaddr
)))
1273 domain
= get_domain(mess
->yiaddr
);
1274 hostname
= client_hostname
;
1278 time
= calc_time(context
, config
, option_find(mess
, sz
, OPTION_LEASE_TIME
, 4));
1279 lease_set_hwaddr(lease
, mess
->chaddr
, clid
, mess
->hlen
, mess
->htype
, clid_len
, now
);
1281 /* if all the netids in the ignore_name list are present, ignore client-supplied name */
1284 for (id_list
= daemon
->dhcp_ignore_names
; id_list
; id_list
= id_list
->next
)
1285 if ((!id_list
->list
) || match_netid(id_list
->list
, tagif_netid
, 0))
1291 /* Last ditch, if configured, generate hostname from mac address */
1292 if (!hostname
&& emac_len
!= 0)
1294 for (id_list
= daemon
->dhcp_gen_names
; id_list
; id_list
= id_list
->next
)
1295 if ((!id_list
->list
) || match_netid(id_list
->list
, tagif_netid
, 0))
1301 hostname
= daemon
->dhcp_buff
;
1302 /* buffer is 256 bytes, 3 bytes per octet */
1303 for (i
= 0; (i
< emac_len
) && (i
< 80); i
++)
1304 hostname
+= sprintf(hostname
, "%.2x%s", emac
[i
], (i
== emac_len
- 1) ? "" : "-");
1305 hostname
= daemon
->dhcp_buff
;
1310 lease_set_hostname(lease
, hostname
, hostname_auth
, get_domain(lease
->addr
), domain
);
1312 lease_set_expires(lease
, time
, now
);
1313 lease_set_interface(lease
, int_index
, now
);
1315 if (override
.s_addr
!= 0)
1316 lease
->override
= override
;
1318 override
= lease
->override
;
1320 log_packet("DHCPACK", &mess
->yiaddr
, emac
, emac_len
, iface_name
, hostname
, mess
->xid
);
1322 clear_packet(mess
, end
);
1323 option_put(mess
, end
, OPTION_MESSAGE_TYPE
, 1, DHCPACK
);
1324 option_put(mess
, end
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
, ntohl(server_id(context
, override
, fallback
).s_addr
));
1325 option_put(mess
, end
, OPTION_LEASE_TIME
, 4, time
);
1326 if (time
!= 0xffffffff)
1328 while (fuzz
> (time
/16))
1330 option_put(mess
, end
, OPTION_T1
, 4, (time
/2) - fuzz
);
1331 option_put(mess
, end
, OPTION_T2
, 4, ((time
/8)*7) - fuzz
);
1333 do_options(context
, mess
, end
, req_options
, hostname
, get_domain(mess
->yiaddr
),
1334 netid
, subnet_addr
, fqdn_flags
, borken_opt
, pxearch
, uuid
, vendor_class_len
, now
);
1337 return dhcp_packet_size(mess
, agent_id
, real_end
);
1340 if (ignore
|| have_config(config
, CONFIG_DISABLE
))
1341 message
= _("ignored");
1343 log_packet("DHCPINFORM", &mess
->ciaddr
, emac
, emac_len
, iface_name
, message
, mess
->xid
);
1345 if (message
|| mess
->ciaddr
.s_addr
== 0)
1348 /* For DHCPINFORM only, cope without a valid context */
1349 context
= narrow_context(context
, mess
->ciaddr
, tagif_netid
);
1351 /* Find a least based on IP address if we didn't
1352 get one from MAC address/client-d */
1354 (lease
= lease_find_by_addr(mess
->ciaddr
)) &&
1356 hostname
= lease
->hostname
;
1358 if (!hostname
&& (hostname
= host_from_dns(mess
->ciaddr
)))
1359 domain
= get_domain(mess
->ciaddr
);
1361 if (context
&& context
->netid
.net
)
1363 context
->netid
.next
= netid
;
1364 tagif_netid
= run_tag_if(&context
->netid
);
1367 log_tags(tagif_netid
, ntohl(mess
->xid
));
1369 log_packet("DHCPACK", &mess
->ciaddr
, emac
, emac_len
, iface_name
, hostname
, mess
->xid
);
1373 if (override
.s_addr
!= 0)
1374 lease
->override
= override
;
1376 override
= lease
->override
;
1379 clear_packet(mess
, end
);
1380 option_put(mess
, end
, OPTION_MESSAGE_TYPE
, 1, DHCPACK
);
1381 option_put(mess
, end
, OPTION_SERVER_IDENTIFIER
, INADDRSZ
, ntohl(server_id(context
, override
, fallback
).s_addr
));
1385 if (lease
->expires
== 0)
1388 time
= (unsigned int)difftime(lease
->expires
, now
);
1389 option_put(mess
, end
, OPTION_LEASE_TIME
, 4, time
);
1390 lease_set_interface(lease
, int_index
, now
);
1393 do_options(context
, mess
, end
, req_options
, hostname
, get_domain(mess
->ciaddr
),
1394 netid
, subnet_addr
, fqdn_flags
, borken_opt
, pxearch
, uuid
, vendor_class_len
, now
);
1396 *is_inform
= 1; /* handle reply differently */
1397 return dhcp_packet_size(mess
, agent_id
, real_end
);
1403 /* find a good value to use as MAC address for logging and address-allocation hashing.
1404 This is normally just the chaddr field from the DHCP packet,
1405 but eg Firewire will have hlen == 0 and use the client-id instead.
1406 This could be anything, but will normally be EUI64 for Firewire.
1407 We assume that if the first byte of the client-id equals the htype byte
1408 then the client-id is using the usual encoding and use the rest of the
1409 client-id: if not we can use the whole client-id. This should give
1410 sane MAC address logs. */
1411 unsigned char *extended_hwaddr(int hwtype
, int hwlen
, unsigned char *hwaddr
,
1412 int clid_len
, unsigned char *clid
, int *len_out
)
1414 if (hwlen
== 0 && clid
&& clid_len
> 3)
1416 if (clid
[0] == hwtype
)
1418 *len_out
= clid_len
- 1 ;
1422 #if defined(ARPHRD_EUI64) && defined(ARPHRD_IEEE1394)
1423 if (clid
[0] == ARPHRD_EUI64
&& hwtype
== ARPHRD_IEEE1394
)
1425 *len_out
= clid_len
- 1 ;
1430 *len_out
= clid_len
;
1438 static unsigned int calc_time(struct dhcp_context
*context
, struct dhcp_config
*config
, unsigned char *opt
)
1440 unsigned int time
= have_config(config
, CONFIG_TIME
) ? config
->lease_time
: context
->lease_time
;
1444 unsigned int req_time
= option_uint(opt
, 0, 4);
1445 if (req_time
< 120 )
1446 req_time
= 120; /* sanity */
1447 if (time
== 0xffffffff || (req_time
!= 0xffffffff && req_time
< time
))
1454 static struct in_addr
server_id(struct dhcp_context
*context
, struct in_addr override
, struct in_addr fallback
)
1456 if (override
.s_addr
!= 0)
1458 else if (context
&& context
->local
.s_addr
!= 0)
1459 return context
->local
;
1464 static int sanitise(unsigned char *opt
, char *buf
)
1474 p
= option_ptr(opt
, 0);
1476 for (i
= option_len(opt
); i
> 0; i
--)
1479 if (isprint((int)c
))
1482 *buf
= 0; /* add terminator */
1488 static void add_extradata_opt(struct dhcp_lease
*lease
, unsigned char *opt
)
1491 lease_add_extradata(lease
, NULL
, 0, 0);
1493 lease_add_extradata(lease
, option_ptr(opt
, 0), option_len(opt
), 0);
1497 static void log_packet(char *type
, void *addr
, unsigned char *ext_mac
,
1498 int mac_len
, char *interface
, char *string
, u32 xid
)
1502 /* addr may be misaligned */
1504 memcpy(&a
, addr
, sizeof(a
));
1506 print_mac(daemon
->namebuff
, ext_mac
, mac_len
);
1508 if(option_bool(OPT_LOG_OPTS
))
1509 my_syslog(MS_DHCP
| LOG_INFO
, "%u %s(%s) %s%s%s %s",
1513 addr
? inet_ntoa(a
) : "",
1516 string
? string
: "");
1518 my_syslog(MS_DHCP
| LOG_INFO
, "%s(%s) %s%s%s %s",
1521 addr
? inet_ntoa(a
) : "",
1524 string
? string
: "");
1527 static void log_options(unsigned char *start
, u32 xid
)
1529 while (*start
!= OPTION_END
)
1531 char *optname
= option_string(AF_INET
, start
[0], option_ptr(start
, 0), option_len(start
), daemon
->namebuff
, MAXDNAME
);
1533 my_syslog(MS_DHCP
| LOG_INFO
, "%u sent size:%3d option:%3d %s %s",
1534 ntohl(xid
), option_len(start
), start
[0], optname
, daemon
->namebuff
);
1535 start
+= start
[1] + 2;
1539 static unsigned char *option_find1(unsigned char *p
, unsigned char *end
, int opt
, int minsize
)
1545 else if (*p
== OPTION_END
)
1546 return opt
== OPTION_END
? p
: NULL
;
1547 else if (*p
== OPTION_PAD
)
1553 return NULL
; /* malformed packet */
1554 opt_len
= option_len(p
);
1555 if (p
> end
- (2 + opt_len
))
1556 return NULL
; /* malformed packet */
1557 if (*p
== opt
&& opt_len
>= minsize
)
1564 static unsigned char *option_find(struct dhcp_packet
*mess
, size_t size
, int opt_type
, int minsize
)
1566 unsigned char *ret
, *overload
;
1568 /* skip over DHCP cookie; */
1569 if ((ret
= option_find1(&mess
->options
[0] + sizeof(u32
), ((unsigned char *)mess
) + size
, opt_type
, minsize
)))
1572 /* look for overload option. */
1573 if (!(overload
= option_find1(&mess
->options
[0] + sizeof(u32
), ((unsigned char *)mess
) + size
, OPTION_OVERLOAD
, 1)))
1576 /* Can we look in filename area ? */
1577 if ((overload
[2] & 1) &&
1578 (ret
= option_find1(&mess
->file
[0], &mess
->file
[128], opt_type
, minsize
)))
1581 /* finally try sname area */
1582 if ((overload
[2] & 2) &&
1583 (ret
= option_find1(&mess
->sname
[0], &mess
->sname
[64], opt_type
, minsize
)))
1589 static struct in_addr
option_addr(unsigned char *opt
)
1591 /* this worries about unaligned data in the option. */
1592 /* struct in_addr is network byte order */
1595 memcpy(&ret
, option_ptr(opt
, 0), INADDRSZ
);
1600 static unsigned int option_uint(unsigned char *opt
, int offset
, int size
)
1602 /* this worries about unaligned data and byte order */
1603 unsigned int ret
= 0;
1605 unsigned char *p
= option_ptr(opt
, offset
);
1607 for (i
= 0; i
< size
; i
++)
1608 ret
= (ret
<< 8) | *p
++;
1613 static unsigned char *dhcp_skip_opts(unsigned char *start
)
1616 start
+= start
[1] + 2;
1620 /* only for use when building packet: doesn't check for bad data. */
1621 static unsigned char *find_overload(struct dhcp_packet
*mess
)
1623 unsigned char *p
= &mess
->options
[0] + sizeof(u32
);
1627 if (*p
== OPTION_OVERLOAD
)
1634 static size_t dhcp_packet_size(struct dhcp_packet
*mess
, unsigned char *agent_id
, unsigned char *real_end
)
1636 unsigned char *p
= dhcp_skip_opts(&mess
->options
[0] + sizeof(u32
));
1637 unsigned char *overload
;
1640 /* move agent_id back down to the end of the packet */
1643 memmove(p
, agent_id
, real_end
- agent_id
);
1644 p
+= real_end
- agent_id
;
1645 memset(p
, 0, real_end
- p
); /* in case of overlap */
1648 /* add END options to the regions. */
1649 overload
= find_overload(mess
);
1651 if (overload
&& (option_uint(overload
, 0, 1) & 1))
1653 *dhcp_skip_opts(mess
->file
) = OPTION_END
;
1654 if (option_bool(OPT_LOG_OPTS
))
1655 log_options(mess
->file
, mess
->xid
);
1657 else if (option_bool(OPT_LOG_OPTS
) && strlen((char *)mess
->file
) != 0)
1658 my_syslog(MS_DHCP
| LOG_INFO
, _("%u bootfile name: %s"), ntohl(mess
->xid
), (char *)mess
->file
);
1660 if (overload
&& (option_uint(overload
, 0, 1) & 2))
1662 *dhcp_skip_opts(mess
->sname
) = OPTION_END
;
1663 if (option_bool(OPT_LOG_OPTS
))
1664 log_options(mess
->sname
, mess
->xid
);
1666 else if (option_bool(OPT_LOG_OPTS
) && strlen((char *)mess
->sname
) != 0)
1667 my_syslog(MS_DHCP
| LOG_INFO
, _("%u server name: %s"), ntohl(mess
->xid
), (char *)mess
->sname
);
1672 if (option_bool(OPT_LOG_OPTS
))
1674 if (mess
->siaddr
.s_addr
!= 0)
1675 my_syslog(MS_DHCP
| LOG_INFO
, _("%u next server: %s"), ntohl(mess
->xid
), inet_ntoa(mess
->siaddr
));
1677 if ((mess
->flags
& htons(0x8000)) && mess
->ciaddr
.s_addr
== 0)
1678 my_syslog(MS_DHCP
| LOG_INFO
, _("%u broadcast response"), ntohl(mess
->xid
));
1680 log_options(&mess
->options
[0] + sizeof(u32
), mess
->xid
);
1683 ret
= (size_t)(p
- (unsigned char *)mess
);
1685 if (ret
< MIN_PACKETSZ
)
1691 static unsigned char *free_space(struct dhcp_packet
*mess
, unsigned char *end
, int opt
, int len
)
1693 unsigned char *p
= dhcp_skip_opts(&mess
->options
[0] + sizeof(u32
));
1695 if (p
+ len
+ 3 >= end
)
1696 /* not enough space in options area, try and use overload, if poss */
1698 unsigned char *overload
;
1700 if (!(overload
= find_overload(mess
)) &&
1701 (mess
->file
[0] == 0 || mess
->sname
[0] == 0))
1703 /* attempt to overload fname and sname areas, we've reserved space for the
1704 overflow option previuously. */
1706 *(p
++) = OPTION_OVERLOAD
;
1712 /* using filename field ? */
1715 if (mess
->file
[0] == 0)
1718 if (overload
[2] & 1)
1720 p
= dhcp_skip_opts(mess
->file
);
1721 if (p
+ len
+ 3 >= mess
->file
+ sizeof(mess
->file
))
1727 /* try to bring sname into play (it may be already) */
1728 if (mess
->sname
[0] == 0)
1731 if (overload
[2] & 2)
1733 p
= dhcp_skip_opts(mess
->sname
);
1734 if (p
+ len
+ 3 >= mess
->sname
+ sizeof(mess
->file
))
1741 my_syslog(MS_DHCP
| LOG_WARNING
, _("cannot send DHCP/BOOTP option %d: no space left in packet"), opt
);
1753 static void option_put(struct dhcp_packet
*mess
, unsigned char *end
, int opt
, int len
, unsigned int val
)
1756 unsigned char *p
= free_space(mess
, end
, opt
, len
);
1759 for (i
= 0; i
< len
; i
++)
1760 *(p
++) = val
>> (8 * (len
- (i
+ 1)));
1763 static void option_put_string(struct dhcp_packet
*mess
, unsigned char *end
, int opt
,
1764 char *string
, int null_term
)
1767 size_t len
= strlen(string
);
1769 if (null_term
&& len
!= 255)
1772 if ((p
= free_space(mess
, end
, opt
, len
)))
1773 memcpy(p
, string
, len
);
1776 /* return length, note this only does the data part */
1777 static int do_opt(struct dhcp_opt
*opt
, unsigned char *p
, struct dhcp_context
*context
, int null_term
)
1781 if ((opt
->flags
& DHOPT_STRING
) && null_term
&& len
!= 255)
1786 if (context
&& (opt
->flags
& DHOPT_ADDR
))
1789 struct in_addr
*a
= (struct in_addr
*)opt
->val
;
1790 for (j
= 0; j
< opt
->len
; j
+=INADDRSZ
, a
++)
1792 /* zero means "self" (but not in vendorclass options.) */
1794 memcpy(p
, &context
->local
, INADDRSZ
);
1796 memcpy(p
, a
, INADDRSZ
);
1801 memcpy(p
, opt
->val
, len
);
1806 static int in_list(unsigned char *list
, int opt
)
1810 /* If no requested options, send everything, not nothing. */
1814 for (i
= 0; list
[i
] != OPTION_END
; i
++)
1821 static struct dhcp_opt
*option_find2(int opt
)
1823 struct dhcp_opt
*opts
;
1825 for (opts
= daemon
->dhcp_opts
; opts
; opts
= opts
->next
)
1826 if (opts
->opt
== opt
&& (opts
->flags
& DHOPT_TAGOK
))
1832 /* mark vendor-encapsulated options which match the client-supplied or
1833 config-supplied vendor class */
1834 static void match_vendor_opts(unsigned char *opt
, struct dhcp_opt
*dopt
)
1836 for (; dopt
; dopt
= dopt
->next
)
1838 dopt
->flags
&= ~DHOPT_VENDOR_MATCH
;
1839 if (opt
&& (dopt
->flags
& DHOPT_VENDOR
))
1842 if (dopt
->u
.vendor_class
)
1843 len
= strlen((char *)dopt
->u
.vendor_class
);
1844 for (i
= 0; i
<= (option_len(opt
) - len
); i
++)
1845 if (len
== 0 || memcmp(dopt
->u
.vendor_class
, option_ptr(opt
, i
), len
) == 0)
1847 dopt
->flags
|= DHOPT_VENDOR_MATCH
;
1854 static int do_encap_opts(struct dhcp_opt
*opt
, int encap
, int flag
,
1855 struct dhcp_packet
*mess
, unsigned char *end
, int null_term
)
1857 int len
, enc_len
, ret
= 0;
1858 struct dhcp_opt
*start
;
1861 /* find size in advance */
1862 for (enc_len
= 0, start
= opt
; opt
; opt
= opt
->next
)
1863 if (opt
->flags
& flag
)
1865 int new = do_opt(opt
, NULL
, NULL
, null_term
) + 2;
1867 if (enc_len
+ new <= 255)
1871 p
= free_space(mess
, end
, encap
, enc_len
);
1872 for (; start
&& start
!= opt
; start
= start
->next
)
1873 if (p
&& (start
->flags
& flag
))
1875 len
= do_opt(start
, p
+ 2, NULL
, null_term
);
1876 *(p
++) = start
->opt
;
1886 (p
= free_space(mess
, end
, encap
, enc_len
+ 1)))
1888 for (; start
; start
= start
->next
)
1889 if (start
->flags
& flag
)
1891 len
= do_opt(start
, p
+ 2, NULL
, null_term
);
1892 *(p
++) = start
->opt
;
1902 static void pxe_misc(struct dhcp_packet
*mess
, unsigned char *end
, unsigned char *uuid
)
1906 option_put_string(mess
, end
, OPTION_VENDOR_ID
, "PXEClient", 0);
1907 if (uuid
&& (p
= free_space(mess
, end
, OPTION_PXE_UUID
, 17)))
1908 memcpy(p
, uuid
, 17);
1911 static int prune_vendor_opts(struct dhcp_netid
*netid
)
1914 struct dhcp_opt
*opt
;
1916 /* prune vendor-encapsulated options based on netid, and look if we're forcing them to be sent */
1917 for (opt
= daemon
->dhcp_opts
; opt
; opt
= opt
->next
)
1918 if (opt
->flags
& DHOPT_VENDOR_MATCH
)
1920 if (!match_netid(opt
->netid
, netid
, 1))
1921 opt
->flags
&= ~DHOPT_VENDOR_MATCH
;
1922 else if (opt
->flags
& DHOPT_FORCE
)
1928 static struct dhcp_opt
*pxe_opts(int pxe_arch
, struct dhcp_netid
*netid
, struct in_addr local
, time_t now
)
1932 unsigned char *p
, *q
;
1933 struct pxe_service
*service
;
1934 static struct dhcp_opt
*o
, *ret
;
1935 int i
, j
= NUM_OPTS
- 1;
1936 struct in_addr boot_server
;
1938 /* We pass back references to these, hence they are declared static */
1939 static unsigned char discovery_control
;
1940 static unsigned char fake_prompt
[] = { 0, 'P', 'X', 'E' };
1941 static struct dhcp_opt
*fake_opts
= NULL
;
1943 /* Disable multicast, since we don't support it, and broadcast
1944 unless we need it */
1945 discovery_control
= 3;
1947 ret
= daemon
->dhcp_opts
;
1949 if (!fake_opts
&& !(fake_opts
= whine_malloc(NUM_OPTS
* sizeof(struct dhcp_opt
))))
1952 for (i
= 0; i
< NUM_OPTS
; i
++)
1954 fake_opts
[i
].flags
= DHOPT_VENDOR_MATCH
;
1955 fake_opts
[i
].netid
= NULL
;
1956 fake_opts
[i
].next
= i
== (NUM_OPTS
- 1) ? ret
: &fake_opts
[i
+1];
1959 /* create the data for the PXE_MENU and PXE_SERVERS options. */
1960 p
= (unsigned char *)daemon
->dhcp_buff
;
1961 q
= (unsigned char *)daemon
->dhcp_buff3
;
1963 for (i
= 0, service
= daemon
->pxe_services
; service
; service
= service
->next
)
1964 if (pxe_arch
== service
->CSA
&& match_netid(service
->netid
, netid
, 1))
1966 size_t len
= strlen(service
->menu
);
1967 /* opt 43 max size is 255. encapsulated option has type and length
1968 bytes, so its max size is 253. */
1969 if (p
- (unsigned char *)daemon
->dhcp_buff
+ len
+ 3 < 253)
1971 *(p
++) = service
->type
>> 8;
1972 *(p
++) = service
->type
;
1974 memcpy(p
, service
->menu
, len
);
1981 my_syslog(MS_DHCP
| LOG_ERR
, _("PXE menu too large"));
1982 return daemon
->dhcp_opts
;
1985 boot_server
= service
->basename
? local
:
1986 (service
->sname
? a_record_from_hosts(service
->sname
, now
) : service
->server
);
1988 if (boot_server
.s_addr
!= 0)
1990 if (q
- (unsigned char *)daemon
->dhcp_buff3
+ 3 + INADDRSZ
>= 253)
1993 /* Boot service with known address - give it */
1994 *(q
++) = service
->type
>> 8;
1995 *(q
++) = service
->type
;
1997 /* dest misaligned */
1998 memcpy(q
, &boot_server
.s_addr
, INADDRSZ
);
2001 else if (service
->type
!= 0)
2002 /* We don't know the server for a service type, so we'll
2003 allow the client to broadcast for it */
2004 discovery_control
= 2;
2007 /* if no prompt, wait forever if there's a choice */
2008 fake_prompt
[0] = (i
> 1) ? 255 : 0;
2011 discovery_control
= 8; /* no menu - just use use mess->filename */
2014 ret
= &fake_opts
[j
--];
2015 ret
->len
= p
- (unsigned char *)daemon
->dhcp_buff
;
2016 ret
->val
= (unsigned char *)daemon
->dhcp_buff
;
2017 ret
->opt
= SUBOPT_PXE_MENU
;
2019 if (q
- (unsigned char *)daemon
->dhcp_buff3
!= 0)
2021 ret
= &fake_opts
[j
--];
2022 ret
->len
= q
- (unsigned char *)daemon
->dhcp_buff3
;
2023 ret
->val
= (unsigned char *)daemon
->dhcp_buff3
;
2024 ret
->opt
= SUBOPT_PXE_SERVERS
;
2028 for (o
= daemon
->dhcp_opts
; o
; o
= o
->next
)
2029 if ((o
->flags
& DHOPT_VENDOR_MATCH
) && o
->opt
== SUBOPT_PXE_MENU_PROMPT
)
2034 ret
= &fake_opts
[j
--];
2035 ret
->len
= sizeof(fake_prompt
);
2036 ret
->val
= fake_prompt
;
2037 ret
->opt
= SUBOPT_PXE_MENU_PROMPT
;
2040 ret
= &fake_opts
[j
--];
2042 ret
->opt
= SUBOPT_PXE_DISCOVERY
;
2043 ret
->val
= &discovery_control
;
2048 static void clear_packet(struct dhcp_packet
*mess
, unsigned char *end
)
2050 memset(mess
->sname
, 0, sizeof(mess
->sname
));
2051 memset(mess
->file
, 0, sizeof(mess
->file
));
2052 memset(&mess
->options
[0] + sizeof(u32
), 0, end
- (&mess
->options
[0] + sizeof(u32
)));
2053 mess
->siaddr
.s_addr
= 0;
2056 struct dhcp_boot
*find_boot(struct dhcp_netid
*netid
)
2058 struct dhcp_boot
*boot
;
2060 /* decide which dhcp-boot option we're using */
2061 for (boot
= daemon
->boot_config
; boot
; boot
= boot
->next
)
2062 if (match_netid(boot
->netid
, netid
, 0))
2065 /* No match, look for one without a netid */
2066 for (boot
= daemon
->boot_config
; boot
; boot
= boot
->next
)
2067 if (match_netid(boot
->netid
, netid
, 1))
2073 static void do_options(struct dhcp_context
*context
,
2074 struct dhcp_packet
*mess
,
2076 unsigned char *req_options
,
2079 struct dhcp_netid
*netid
,
2080 struct in_addr subnet_addr
,
2081 unsigned char fqdn_flags
,
2082 int null_term
, int pxe_arch
,
2083 unsigned char *uuid
,
2084 int vendor_class_len
,
2087 struct dhcp_opt
*opt
, *config_opts
= daemon
->dhcp_opts
;
2088 struct dhcp_boot
*boot
;
2090 int i
, len
, force_encap
= 0;
2091 unsigned char f0
= 0, s0
= 0;
2092 int done_file
= 0, done_server
= 0;
2093 int done_vendor_class
= 0;
2094 struct dhcp_netid
*tagif
;
2095 struct dhcp_netid_list
*id_list
;
2097 /* filter options based on tags, those we want get DHOPT_TAGOK bit set */
2099 context
->netid
.next
= NULL
;
2100 tagif
= option_filter(netid
, context
&& context
->netid
.net
? &context
->netid
: NULL
, config_opts
);
2103 if (option_bool(OPT_LOG_OPTS
) && req_options
)
2105 char *q
= daemon
->namebuff
;
2106 for (i
= 0; req_options
[i
] != OPTION_END
; i
++)
2108 char *s
= option_string(AF_INET
, req_options
[i
], NULL
, 0, NULL
, 0);
2109 q
+= snprintf(q
, MAXDNAME
- (q
- daemon
->namebuff
),
2112 strlen(s
) != 0 ? ":" : "",
2114 req_options
[i
+1] == OPTION_END
? "" : ", ");
2115 if (req_options
[i
+1] == OPTION_END
|| (q
- daemon
->namebuff
) > 40)
2117 q
= daemon
->namebuff
;
2118 my_syslog(MS_DHCP
| LOG_INFO
, _("%u requested options: %s"), ntohl(mess
->xid
), daemon
->namebuff
);
2123 for (id_list
= daemon
->force_broadcast
; id_list
; id_list
= id_list
->next
)
2124 if ((!id_list
->list
) || match_netid(id_list
->list
, netid
, 0))
2127 mess
->flags
|= htons(0x8000); /* force broadcast */
2130 mess
->siaddr
= context
->local
;
2132 /* See if we can send the boot stuff as options.
2133 To do this we need a requested option list, BOOTP
2134 and very old DHCP clients won't have this, we also
2135 provide an manual option to disable it.
2136 Some PXE ROMs have bugs (surprise!) and need zero-terminated
2137 names, so we always send those. */
2138 if ((boot
= find_boot(tagif
)))
2142 if (!option_bool(OPT_NO_OVERRIDE
) &&
2144 in_list(req_options
, OPTION_SNAME
))
2145 option_put_string(mess
, end
, OPTION_SNAME
, boot
->sname
, 1);
2147 strncpy((char *)mess
->sname
, boot
->sname
, sizeof(mess
->sname
)-1);
2152 if (!option_bool(OPT_NO_OVERRIDE
) &&
2154 in_list(req_options
, OPTION_FILENAME
))
2155 option_put_string(mess
, end
, OPTION_FILENAME
, boot
->file
, 1);
2157 strncpy((char *)mess
->file
, boot
->file
, sizeof(mess
->file
)-1);
2160 if (boot
->next_server
.s_addr
)
2161 mess
->siaddr
= boot
->next_server
;
2162 else if (boot
->tftp_sname
)
2163 mess
->siaddr
= a_record_from_hosts(boot
->tftp_sname
, now
);
2166 /* Use the values of the relevant options if no dhcp-boot given and
2167 they're not explicitly asked for as options. OPTION_END is used
2168 as an internal way to specify siaddr without using dhcp-boot, for use in
2171 if ((!req_options
|| !in_list(req_options
, OPTION_FILENAME
)) &&
2172 (opt
= option_find2(OPTION_FILENAME
)) && !(opt
->flags
& DHOPT_FORCE
))
2174 strncpy((char *)mess
->file
, (char *)opt
->val
, sizeof(mess
->file
)-1);
2178 if ((!req_options
|| !in_list(req_options
, OPTION_SNAME
)) &&
2179 (opt
= option_find2(OPTION_SNAME
)) && !(opt
->flags
& DHOPT_FORCE
))
2181 strncpy((char *)mess
->sname
, (char *)opt
->val
, sizeof(mess
->sname
)-1);
2185 if ((opt
= option_find2(OPTION_END
)))
2186 mess
->siaddr
.s_addr
= ((struct in_addr
*)opt
->val
)->s_addr
;
2189 /* We don't want to do option-overload for BOOTP, so make the file and sname
2190 fields look like they are in use, even when they aren't. This gets restored
2191 at the end of this function. */
2193 if (!req_options
|| option_bool(OPT_NO_OVERRIDE
))
2197 s0
= mess
->sname
[0];
2201 /* At this point, if mess->sname or mess->file are zeroed, they are available
2202 for option overload, reserve space for the overload option. */
2203 if (mess
->file
[0] == 0 || mess
->sname
[0] == 0)
2206 /* rfc3011 says this doesn't need to be in the requested options list. */
2207 if (subnet_addr
.s_addr
)
2208 option_put(mess
, end
, OPTION_SUBNET_SELECT
, INADDRSZ
, ntohl(subnet_addr
.s_addr
));
2210 /* replies to DHCPINFORM may not have a valid context */
2213 if (!option_find2(OPTION_NETMASK
))
2214 option_put(mess
, end
, OPTION_NETMASK
, INADDRSZ
, ntohl(context
->netmask
.s_addr
));
2216 /* May not have a "guessed" broadcast address if we got no packets via a relay
2217 from this net yet (ie just unicast renewals after a restart */
2218 if (context
->broadcast
.s_addr
&&
2219 !option_find2(OPTION_BROADCAST
))
2220 option_put(mess
, end
, OPTION_BROADCAST
, INADDRSZ
, ntohl(context
->broadcast
.s_addr
));
2222 /* Same comments as broadcast apply, and also may not be able to get a sensible
2223 default when using subnet select. User must configure by steam in that case. */
2224 if (context
->router
.s_addr
&&
2225 in_list(req_options
, OPTION_ROUTER
) &&
2226 !option_find2(OPTION_ROUTER
))
2227 option_put(mess
, end
, OPTION_ROUTER
, INADDRSZ
, ntohl(context
->router
.s_addr
));
2229 if (in_list(req_options
, OPTION_DNSSERVER
) &&
2230 !option_find2(OPTION_DNSSERVER
))
2231 option_put(mess
, end
, OPTION_DNSSERVER
, INADDRSZ
, ntohl(context
->local
.s_addr
));
2234 if (domain
&& in_list(req_options
, OPTION_DOMAINNAME
) &&
2235 !option_find2(OPTION_DOMAINNAME
))
2236 option_put_string(mess
, end
, OPTION_DOMAINNAME
, domain
, null_term
);
2238 /* Note that we ignore attempts to set the fqdn using --dhc-option=81,<name> */
2241 if (in_list(req_options
, OPTION_HOSTNAME
) &&
2242 !option_find2(OPTION_HOSTNAME
))
2243 option_put_string(mess
, end
, OPTION_HOSTNAME
, hostname
, null_term
);
2245 if (fqdn_flags
!= 0)
2247 len
= strlen(hostname
) + 3;
2249 if (fqdn_flags
& 0x04)
2255 len
+= strlen(domain
) + 1;
2257 if ((p
= free_space(mess
, end
, OPTION_CLIENT_FQDN
, len
)))
2259 *(p
++) = fqdn_flags
;
2263 if (fqdn_flags
& 0x04)
2265 p
= do_rfc1035_name(p
, hostname
);
2267 p
= do_rfc1035_name(p
, domain
);
2272 memcpy(p
, hostname
, strlen(hostname
));
2273 p
+= strlen(hostname
);
2277 memcpy(p
, domain
, strlen(domain
));
2278 p
+= strlen(domain
);
2287 for (opt
= config_opts
; opt
; opt
= opt
->next
)
2289 int optno
= opt
->opt
;
2291 /* netids match and not encapsulated? */
2292 if (!(opt
->flags
& DHOPT_TAGOK
))
2295 /* was it asked for, or are we sending it anyway? */
2296 if (!(opt
->flags
& DHOPT_FORCE
) && !in_list(req_options
, optno
))
2299 /* prohibit some used-internally options */
2300 if (optno
== OPTION_CLIENT_FQDN
||
2301 optno
== OPTION_MAXMESSAGE
||
2302 optno
== OPTION_OVERLOAD
||
2303 optno
== OPTION_PAD
||
2304 optno
== OPTION_END
)
2307 if (optno
== OPTION_SNAME
&& done_server
)
2310 if (optno
== OPTION_FILENAME
&& done_file
)
2313 /* For the options we have default values on
2314 dhc-option=<optionno> means "don't include this option"
2315 not "include a zero-length option" */
2316 if (opt
->len
== 0 &&
2317 (optno
== OPTION_NETMASK
||
2318 optno
== OPTION_BROADCAST
||
2319 optno
== OPTION_ROUTER
||
2320 optno
== OPTION_DNSSERVER
||
2321 optno
== OPTION_DOMAINNAME
||
2322 optno
== OPTION_HOSTNAME
))
2325 /* vendor-class comes from elsewhere for PXE */
2326 if (pxe_arch
!= -1 && optno
== OPTION_VENDOR_ID
)
2329 /* always force null-term for filename and servername - buggy PXE again. */
2330 len
= do_opt(opt
, NULL
, context
,
2331 (optno
== OPTION_SNAME
|| optno
== OPTION_FILENAME
) ? 1 : null_term
);
2333 if ((p
= free_space(mess
, end
, optno
, len
)))
2335 do_opt(opt
, p
, context
,
2336 (optno
== OPTION_SNAME
|| optno
== OPTION_FILENAME
) ? 1 : null_term
);
2338 /* If we send a vendor-id, revisit which vendor-ops we consider
2339 it appropriate to send. */
2340 if (optno
== OPTION_VENDOR_ID
)
2342 match_vendor_opts(p
- 2, config_opts
);
2343 done_vendor_class
= 1;
2348 /* Now send options to be encapsulated in arbitrary options,
2349 eg dhcp-option=encap:172,17,.......
2350 Also handle vendor-identifying vendor-encapsulated options,
2351 dhcp-option = vi-encap:13,17,.......
2352 The may be more that one "outer" to do, so group
2353 all the options which match each outer in turn. */
2354 for (opt
= config_opts
; opt
; opt
= opt
->next
)
2355 opt
->flags
&= ~DHOPT_ENCAP_DONE
;
2357 for (opt
= config_opts
; opt
; opt
= opt
->next
)
2361 if ((flags
= (opt
->flags
& (DHOPT_ENCAPSULATE
| DHOPT_RFC3925
))))
2366 if (opt
->flags
& DHOPT_ENCAP_DONE
)
2369 for (len
= 0, o
= config_opts
; o
; o
= o
->next
)
2371 int outer
= flags
& DHOPT_ENCAPSULATE
? o
->u
.encap
: OPTION_VENDOR_IDENT_OPT
;
2373 o
->flags
&= ~DHOPT_ENCAP_MATCH
;
2375 if (!(o
->flags
& flags
) || opt
->u
.encap
!= o
->u
.encap
)
2378 o
->flags
|= DHOPT_ENCAP_DONE
;
2379 if (match_netid(o
->netid
, tagif
, 1) &&
2380 ((o
->flags
& DHOPT_FORCE
) || in_list(req_options
, outer
)))
2382 o
->flags
|= DHOPT_ENCAP_MATCH
;
2384 len
+= do_opt(o
, NULL
, NULL
, 0) + 2;
2390 if (flags
& DHOPT_ENCAPSULATE
)
2391 do_encap_opts(config_opts
, opt
->u
.encap
, DHOPT_ENCAP_MATCH
, mess
, end
, null_term
);
2393 my_syslog(MS_DHCP
| LOG_WARNING
, _("cannot send RFC3925 option: too many options for enterprise number %d"), opt
->u
.encap
);
2394 else if ((p
= free_space(mess
, end
, OPTION_VENDOR_IDENT_OPT
, len
+ 5)))
2396 int swap_ent
= htonl(opt
->u
.encap
);
2397 memcpy(p
, &swap_ent
, 4);
2400 for (o
= config_opts
; o
; o
= o
->next
)
2401 if (o
->flags
& DHOPT_ENCAP_MATCH
)
2403 len
= do_opt(o
, p
+ 2, NULL
, 0);
2413 force_encap
= prune_vendor_opts(tagif
);
2415 if (context
&& pxe_arch
!= -1)
2417 pxe_misc(mess
, end
, uuid
);
2418 config_opts
= pxe_opts(pxe_arch
, tagif
, context
->local
, now
);
2421 if ((force_encap
|| in_list(req_options
, OPTION_VENDOR_CLASS_OPT
)) &&
2422 do_encap_opts(config_opts
, OPTION_VENDOR_CLASS_OPT
, DHOPT_VENDOR_MATCH
, mess
, end
, null_term
) &&
2423 pxe_arch
== -1 && !done_vendor_class
&& vendor_class_len
!= 0 &&
2424 (p
= free_space(mess
, end
, OPTION_VENDOR_ID
, vendor_class_len
)))
2425 /* If we send vendor encapsulated options, and haven't already sent option 60,
2426 echo back the value we got from the client. */
2427 memcpy(p
, daemon
->dhcp_buff3
, vendor_class_len
);
2429 /* restore BOOTP anti-overload hack */
2430 if (!req_options
|| option_bool(OPT_NO_OVERRIDE
))
2433 mess
->sname
[0] = s0
;