1 /* dnsmasq is Copyright (c) 2000-2014 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/>.
24 int clid_len
, iaid
, ia_type
, interface
, hostname_auth
, lease_allocate
;
25 char *client_hostname
, *hostname
, *domain
, *send_domain
;
26 struct dhcp_context
*context
;
27 struct in6_addr
*link_address
, *fallback
, *ll_addr
, *ula_addr
;
28 unsigned int xid
, fqdn_flags
;
30 void *packet_options
, *end
;
31 struct dhcp_netid
*tags
, *context_tags
;
32 unsigned char mac
[DHCP_CHADDR_MAX
];
33 unsigned int mac_len
, mac_type
;
34 #ifdef OPTION6_PREFIX_CLASS
35 struct prefix_class
*send_prefix_class
;
39 static int dhcp6_maybe_relay(struct state
*state
, void *inbuff
, size_t sz
,
40 struct in6_addr
*client_addr
, int is_unicast
, time_t now
);
41 static int dhcp6_no_relay(struct state
*state
, int msg_type
, void *inbuff
, size_t sz
, int is_unicast
, time_t now
);
42 static void log6_opts(int nest
, unsigned int xid
, void *start_opts
, void *end_opts
);
43 static void log6_packet(struct state
*state
, char *type
, struct in6_addr
*addr
, char *string
);
44 static void log6_quiet(struct state
*state
, char *type
, struct in6_addr
*addr
, char *string
);
45 static void *opt6_find (void *opts
, void *end
, unsigned int search
, unsigned int minsize
);
46 static void *opt6_next(void *opts
, void *end
);
47 static unsigned int opt6_uint(unsigned char *opt
, int offset
, int size
);
48 static void get_context_tag(struct state
*state
, struct dhcp_context
*context
);
49 static int check_ia(struct state
*state
, void *opt
, void **endp
, void **ia_option
);
50 static int build_ia(struct state
*state
, int *t1cntr
);
51 static void end_ia(int t1cntr
, unsigned int min_time
, int do_fuzz
);
52 #ifdef OPTION6_PREFIX_CLASS
53 static struct prefix_class
*prefix_class_from_context(struct dhcp_context
*context
);
55 static void mark_context_used(struct state
*state
, struct in6_addr
*addr
);
56 static void mark_config_used(struct dhcp_context
*context
, struct in6_addr
*addr
);
57 static int check_address(struct state
*state
, struct in6_addr
*addr
);
58 static void add_address(struct state
*state
, struct dhcp_context
*context
, unsigned int lease_time
, void *ia_option
,
59 unsigned int *min_time
, struct in6_addr
*addr
, time_t now
);
60 static void update_leases(struct state
*state
, struct dhcp_context
*context
, struct in6_addr
*addr
, unsigned int lease_time
, time_t now
);
61 static int add_local_addrs(struct dhcp_context
*context
);
62 static struct dhcp_netid
*add_options(struct state
*state
, int do_refresh
);
63 static void calculate_times(struct dhcp_context
*context
, unsigned int *min_time
, unsigned int *valid_timep
,
64 unsigned int *preferred_timep
, unsigned int lease_time
);
66 #define opt6_len(opt) ((int)(opt6_uint(opt, -2, 2)))
67 #define opt6_type(opt) (opt6_uint(opt, -4, 2))
68 #define opt6_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[4+(i)]))
70 #define opt6_user_vendor_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[2+(i)]))
71 #define opt6_user_vendor_len(opt) ((int)(opt6_uint(opt, -4, 2)))
72 #define opt6_user_vendor_next(opt, end) (opt6_next(((void *) opt) - 2, end))
75 unsigned short dhcp6_reply(struct dhcp_context
*context
, int interface
, char *iface_name
,
76 struct in6_addr
*fallback
, struct in6_addr
*ll_addr
, struct in6_addr
*ula_addr
,
77 size_t sz
, struct in6_addr
*client_addr
, time_t now
)
79 struct dhcp_vendor
*vendor
;
86 msg_type
= *((unsigned char *)daemon
->dhcp_packet
.iov_base
);
88 /* Mark these so we only match each at most once, to avoid tangled linked lists */
89 for (vendor
= daemon
->dhcp_vendors
; vendor
; vendor
= vendor
->next
)
90 vendor
->netid
.next
= &vendor
->netid
;
93 state
.context
= context
;
94 state
.interface
= interface
;
95 state
.iface_name
= iface_name
;
96 state
.fallback
= fallback
;
97 state
.ll_addr
= ll_addr
;
98 state
.ula_addr
= ula_addr
;
101 state
.link_address
= NULL
;
103 if (dhcp6_maybe_relay(&state
, daemon
->dhcp_packet
.iov_base
, sz
, client_addr
,
104 IN6_IS_ADDR_MULTICAST(client_addr
), now
))
105 return msg_type
== DHCP6RELAYFORW
? DHCPV6_SERVER_PORT
: DHCPV6_CLIENT_PORT
;
110 /* This cost me blood to write, it will probably cost you blood to understand - srk. */
111 static int dhcp6_maybe_relay(struct state
*state
, void *inbuff
, size_t sz
,
112 struct in6_addr
*client_addr
, int is_unicast
, time_t now
)
114 void *end
= inbuff
+ sz
;
115 void *opts
= inbuff
+ 34;
116 int msg_type
= *((unsigned char *)inbuff
);
117 unsigned char *outmsgtypep
;
119 struct dhcp_vendor
*vendor
;
121 /* if not an encaplsulated relayed message, just do the stuff */
122 if (msg_type
!= DHCP6RELAYFORW
)
124 /* if link_address != NULL if points to the link address field of the
125 innermost nested RELAYFORW message, which is where we find the
126 address of the network on which we can allocate an address.
127 Recalculate the available contexts using that information.
129 link_address == NULL means there's no relay in use, so we try and find the client's
130 MAC address from the local ND cache. */
132 if (!state
->link_address
)
133 get_client_mac(client_addr
, state
->interface
, state
->mac
, &state
->mac_len
, &state
->mac_type
);
136 struct dhcp_context
*c
;
137 state
->context
= NULL
;
139 if (!IN6_IS_ADDR_LOOPBACK(state
->link_address
) &&
140 !IN6_IS_ADDR_LINKLOCAL(state
->link_address
) &&
141 !IN6_IS_ADDR_MULTICAST(state
->link_address
))
142 for (c
= daemon
->dhcp6
; c
; c
= c
->next
)
143 if ((c
->flags
& CONTEXT_DHCP
) &&
144 !(c
->flags
& (CONTEXT_TEMPLATE
| CONTEXT_OLD
)) &&
145 is_same_net6(state
->link_address
, &c
->start6
, c
->prefix
) &&
146 is_same_net6(state
->link_address
, &c
->end6
, c
->prefix
))
148 c
->preferred
= c
->valid
= 0xffffffff;
149 c
->current
= state
->context
;
155 inet_ntop(AF_INET6
, state
->link_address
, daemon
->addrbuff
, ADDRSTRLEN
);
156 my_syslog(MS_DHCP
| LOG_WARNING
,
157 _("no address range available for DHCPv6 request from relay at %s"),
165 my_syslog(MS_DHCP
| LOG_WARNING
,
166 _("no address range available for DHCPv6 request via %s"), state
->iface_name
);
170 return dhcp6_no_relay(state
, msg_type
, inbuff
, sz
, is_unicast
, now
);
173 /* must have at least msg_type+hopcount+link_address+peer_address+minimal size option
174 which is 1 + 1 + 16 + 16 + 2 + 2 = 38 */
178 /* copy header stuff into reply message and set type to reply */
179 if (!(outmsgtypep
= put_opt6(inbuff
, 34)))
181 *outmsgtypep
= DHCP6RELAYREPL
;
183 /* look for relay options and set tags if found. */
184 for (vendor
= daemon
->dhcp_vendors
; vendor
; vendor
= vendor
->next
)
188 if (vendor
->match_type
== MATCH_SUBSCRIBER
)
189 mopt
= OPTION6_SUBSCRIBER_ID
;
190 else if (vendor
->match_type
== MATCH_REMOTE
)
191 mopt
= OPTION6_REMOTE_ID
;
195 if ((opt
= opt6_find(opts
, end
, mopt
, 1)) &&
196 vendor
->len
== opt6_len(opt
) &&
197 memcmp(vendor
->data
, opt6_ptr(opt
, 0), vendor
->len
) == 0 &&
198 vendor
->netid
.next
!= &vendor
->netid
)
200 vendor
->netid
.next
= state
->tags
;
201 state
->tags
= &vendor
->netid
;
207 if ((opt
= opt6_find(opts
, end
, OPTION6_CLIENT_MAC
, 3)))
209 state
->mac_type
= opt6_uint(opt
, 0, 2);
210 state
->mac_len
= opt6_len(opt
) - 2;
211 memcpy(&state
->mac
[0], opt6_ptr(opt
, 2), state
->mac_len
);
214 for (opt
= opts
; opt
; opt
= opt6_next(opt
, end
))
216 int o
= new_opt6(opt6_type(opt
));
217 if (opt6_type(opt
) == OPTION6_RELAY_MSG
)
219 struct in6_addr align
;
220 /* the packet data is unaligned, copy to aligned storage */
221 memcpy(&align
, inbuff
+ 2, IN6ADDRSZ
);
222 state
->link_address
= &align
;
223 /* zero is_unicast since that is now known to refer to the
224 relayed packet, not the original sent by the client */
225 if (!dhcp6_maybe_relay(state
, opt6_ptr(opt
, 0), opt6_len(opt
), client_addr
, 0, now
))
228 else if (opt6_type(opt
) != OPTION6_CLIENT_MAC
)
229 put_opt6(opt6_ptr(opt
, 0), opt6_len(opt
));
236 static int dhcp6_no_relay(struct state
*state
, int msg_type
, void *inbuff
, size_t sz
, int is_unicast
, time_t now
)
239 int i
, o
, o1
, start_opts
;
240 struct dhcp_opt
*opt_cfg
;
241 struct dhcp_netid
*tagif
;
242 struct dhcp_config
*config
= NULL
;
243 struct dhcp_netid known_id
, iface_id
, v6_id
;
244 unsigned char *outmsgtypep
;
245 struct dhcp_vendor
*vendor
;
246 struct dhcp_context
*context_tmp
;
247 struct dhcp_mac
*mac_opt
;
248 unsigned int ignore
= 0;
249 #ifdef OPTION6_PREFIX_CLASS
250 struct prefix_class
*p
;
251 int dump_all_prefix_classes
= 0;
254 state
->packet_options
= inbuff
+ 4;
255 state
->end
= inbuff
+ sz
;
258 state
->lease_allocate
= 0;
259 state
->context_tags
= NULL
;
260 state
->domain
= NULL
;
261 state
->send_domain
= NULL
;
262 state
->hostname_auth
= 0;
263 state
->hostname
= NULL
;
264 state
->client_hostname
= NULL
;
265 state
->fqdn_flags
= 0x01; /* default to send if we recieve no FQDN option */
266 #ifdef OPTION6_PREFIX_CLASS
267 state
->send_prefix_class
= NULL
;
270 /* set tag with name == interface */
271 iface_id
.net
= state
->iface_name
;
272 iface_id
.next
= state
->tags
;
273 state
->tags
= &iface_id
;
275 /* set tag "dhcpv6" */
276 v6_id
.net
= "dhcpv6";
277 v6_id
.next
= state
->tags
;
278 state
->tags
= &v6_id
;
280 /* copy over transaction-id, and save pointer to message type */
281 if (!(outmsgtypep
= put_opt6(inbuff
, 4)))
283 start_opts
= save_counter(-1);
284 state
->xid
= outmsgtypep
[3] | outmsgtypep
[2] << 8 | outmsgtypep
[1] << 16;
286 /* We're going to be linking tags from all context we use.
287 mark them as unused so we don't link one twice and break the list */
288 for (context_tmp
= state
->context
; context_tmp
; context_tmp
= context_tmp
->current
)
290 context_tmp
->netid
.next
= &context_tmp
->netid
;
292 if (option_bool(OPT_LOG_OPTS
))
294 inet_ntop(AF_INET6
, &context_tmp
->start6
, daemon
->dhcp_buff
, ADDRSTRLEN
);
295 inet_ntop(AF_INET6
, &context_tmp
->end6
, daemon
->dhcp_buff2
, ADDRSTRLEN
);
296 if (context_tmp
->flags
& (CONTEXT_STATIC
))
297 my_syslog(MS_DHCP
| LOG_INFO
, _("%u available DHCPv6 subnet: %s/%d"),
298 state
->xid
, daemon
->dhcp_buff
, context_tmp
->prefix
);
300 my_syslog(MS_DHCP
| LOG_INFO
, _("%u available DHCP range: %s -- %s"),
301 state
->xid
, daemon
->dhcp_buff
, daemon
->dhcp_buff2
);
305 if ((opt
= opt6_find(state
->packet_options
, state
->end
, OPTION6_CLIENT_ID
, 1)))
307 state
->clid
= opt6_ptr(opt
, 0);
308 state
->clid_len
= opt6_len(opt
);
309 o
= new_opt6(OPTION6_CLIENT_ID
);
310 put_opt6(state
->clid
, state
->clid_len
);
313 else if (msg_type
!= DHCP6IREQ
)
316 /* server-id must match except for SOLICIT, CONFIRM and REBIND messages */
317 if (msg_type
!= DHCP6SOLICIT
&& msg_type
!= DHCP6CONFIRM
&& msg_type
!= DHCP6IREQ
&& msg_type
!= DHCP6REBIND
&&
318 (!(opt
= opt6_find(state
->packet_options
, state
->end
, OPTION6_SERVER_ID
, 1)) ||
319 opt6_len(opt
) != daemon
->duid_len
||
320 memcmp(opt6_ptr(opt
, 0), daemon
->duid
, daemon
->duid_len
) != 0))
323 o
= new_opt6(OPTION6_SERVER_ID
);
324 put_opt6(daemon
->duid
, daemon
->duid_len
);
328 (msg_type
== DHCP6REQUEST
|| msg_type
== DHCP6RENEW
|| msg_type
== DHCP6RELEASE
|| msg_type
== DHCP6DECLINE
))
331 *outmsgtypep
= DHCP6REPLY
;
332 o1
= new_opt6(OPTION6_STATUS_CODE
);
333 put_opt6_short(DHCP6USEMULTI
);
334 put_opt6_string("Use multicast");
339 /* match vendor and user class options */
340 for (vendor
= daemon
->dhcp_vendors
; vendor
; vendor
= vendor
->next
)
344 if (vendor
->match_type
== MATCH_VENDOR
)
345 mopt
= OPTION6_VENDOR_CLASS
;
346 else if (vendor
->match_type
== MATCH_USER
)
347 mopt
= OPTION6_USER_CLASS
;
351 if ((opt
= opt6_find(state
->packet_options
, state
->end
, mopt
, 2)))
353 void *enc_opt
, *enc_end
= opt6_ptr(opt
, opt6_len(opt
));
356 if (mopt
== OPTION6_VENDOR_CLASS
)
358 if (opt6_len(opt
) < 4)
361 if (vendor
->enterprise
!= opt6_uint(opt
, 0, 4))
367 /* Note that format if user/vendor classes is different to DHCP options - no option types. */
368 for (enc_opt
= opt6_ptr(opt
, offset
); enc_opt
; enc_opt
= opt6_user_vendor_next(enc_opt
, enc_end
))
369 for (i
= 0; i
<= (opt6_user_vendor_len(enc_opt
) - vendor
->len
); i
++)
370 if (memcmp(vendor
->data
, opt6_user_vendor_ptr(enc_opt
, i
), vendor
->len
) == 0)
372 vendor
->netid
.next
= state
->tags
;
373 state
->tags
= &vendor
->netid
;
379 if (option_bool(OPT_LOG_OPTS
) && (opt
= opt6_find(state
->packet_options
, state
->end
, OPTION6_VENDOR_CLASS
, 4)))
380 my_syslog(MS_DHCP
| LOG_INFO
, _("%u vendor class: %u"), state
->xid
, opt6_uint(opt
, 0, 4));
382 /* dhcp-match. If we have hex-and-wildcards, look for a left-anchored match.
383 Otherwise assume the option is an array, and look for a matching element.
384 If no data given, existance of the option is enough. This code handles
386 for (opt_cfg
= daemon
->dhcp_match6
; opt_cfg
; opt_cfg
= opt_cfg
->next
)
390 if (opt_cfg
->flags
& DHOPT_RFC3925
)
392 for (opt
= opt6_find(state
->packet_options
, state
->end
, OPTION6_VENDOR_OPTS
, 4);
394 opt
= opt6_find(opt6_next(opt
, state
->end
), state
->end
, OPTION6_VENDOR_OPTS
, 4))
397 void *vend
= opt6_ptr(opt
, opt6_len(opt
));
399 for (vopt
= opt6_find(opt6_ptr(opt
, 4), vend
, opt_cfg
->opt
, 0);
401 vopt
= opt6_find(opt6_next(vopt
, vend
), vend
, opt_cfg
->opt
, 0))
402 if ((match
= match_bytes(opt_cfg
, opt6_ptr(vopt
, 0), opt6_len(vopt
))))
410 if (!(opt
= opt6_find(state
->packet_options
, state
->end
, opt_cfg
->opt
, 1)))
413 match
= match_bytes(opt_cfg
, opt6_ptr(opt
, 0), opt6_len(opt
));
418 opt_cfg
->netid
->next
= state
->tags
;
419 state
->tags
= opt_cfg
->netid
;
423 if (state
->mac_len
!= 0)
425 if (option_bool(OPT_LOG_OPTS
))
427 print_mac(daemon
->dhcp_buff
, state
->mac
, state
->mac_len
);
428 my_syslog(MS_DHCP
| LOG_INFO
, _("%u client MAC address: %s"), state
->xid
, daemon
->dhcp_buff
);
431 for (mac_opt
= daemon
->dhcp_macs
; mac_opt
; mac_opt
= mac_opt
->next
)
432 if ((unsigned)mac_opt
->hwaddr_len
== state
->mac_len
&&
433 ((unsigned)mac_opt
->hwaddr_type
== state
->mac_type
|| mac_opt
->hwaddr_type
== 0) &&
434 memcmp_masked(mac_opt
->hwaddr
, state
->mac
, state
->mac_len
, mac_opt
->mask
))
436 mac_opt
->netid
.next
= state
->tags
;
437 state
->tags
= &mac_opt
->netid
;
441 if ((opt
= opt6_find(state
->packet_options
, state
->end
, OPTION6_FQDN
, 1)))
444 int len
= opt6_len(opt
) - 1;
446 state
->fqdn_flags
= opt6_uint(opt
, 0, 1);
448 /* Always force update, since the client has no way to do it itself. */
449 if (!option_bool(OPT_FQDN_UPDATE
) && !(state
->fqdn_flags
& 0x01))
450 state
->fqdn_flags
|= 0x03;
452 state
->fqdn_flags
&= ~0x04;
454 if (len
!= 0 && len
< 255)
456 unsigned char *pp
, *op
= opt6_ptr(opt
, 1);
457 char *pq
= daemon
->dhcp_buff
;
460 while (*op
!= 0 && ((op
+ (*op
)) - pp
) < len
)
462 memcpy(pq
, op
+1, *op
);
468 if (pq
!= daemon
->dhcp_buff
)
472 if (legal_hostname(daemon
->dhcp_buff
))
474 state
->client_hostname
= daemon
->dhcp_buff
;
475 if (option_bool(OPT_LOG_OPTS
))
476 my_syslog(MS_DHCP
| LOG_INFO
, _("%u client provides name: %s"), state
->xid
, state
->client_hostname
);
483 config
= find_config(daemon
->dhcp_conf
, state
->context
, state
->clid
, state
->clid_len
, state
->mac
, state
->mac_len
, state
->mac_type
, NULL
);
485 if (have_config(config
, CONFIG_NAME
))
487 state
->hostname
= config
->hostname
;
488 state
->domain
= config
->domain
;
489 state
->hostname_auth
= 1;
491 else if (state
->client_hostname
)
493 state
->domain
= strip_hostname(state
->client_hostname
);
495 if (strlen(state
->client_hostname
) != 0)
497 state
->hostname
= state
->client_hostname
;
500 /* Search again now we have a hostname.
501 Only accept configs without CLID here, (it won't match)
502 to avoid impersonation by name. */
503 struct dhcp_config
*new = find_config(daemon
->dhcp_conf
, state
->context
, NULL
, 0, NULL
, 0, 0, state
->hostname
);
504 if (new && !have_config(new, CONFIG_CLID
) && !new->hwaddr
)
513 struct dhcp_netid_list
*list
;
515 for (list
= config
->netid
; list
; list
= list
->next
)
517 list
->list
->next
= state
->tags
;
518 state
->tags
= list
->list
;
521 /* set "known" tag for known hosts */
522 known_id
.net
= "known";
523 known_id
.next
= state
->tags
;
524 state
->tags
= &known_id
;
526 if (have_config(config
, CONFIG_DISABLE
))
530 #ifdef OPTION6_PREFIX_CLASS
531 /* OPTION_PREFIX_CLASS in ORO, send addresses in all prefix classes */
532 if (daemon
->prefix_classes
&& (msg_type
== DHCP6SOLICIT
|| msg_type
== DHCP6REQUEST
))
536 if ((oro
= opt6_find(state
->packet_options
, state
->end
, OPTION6_ORO
, 0)))
537 for (i
= 0; i
< opt6_len(oro
) - 1; i
+= 2)
538 if (opt6_uint(oro
, i
, 2) == OPTION6_PREFIX_CLASS
)
540 dump_all_prefix_classes
= 1;
544 if (msg_type
!= DHCP6SOLICIT
|| dump_all_prefix_classes
)
545 /* Add the tags associated with prefix classes so we can use the DHCP ranges.
546 Not done for SOLICIT as we add them one-at-time. */
547 for (p
= daemon
->prefix_classes
; p
; p
= p
->next
)
549 p
->tag
.next
= state
->tags
;
550 state
->tags
= &p
->tag
;
555 tagif
= run_tag_if(state
->tags
);
557 /* if all the netids in the ignore list are present, ignore this client */
558 if (daemon
->dhcp_ignore
)
560 struct dhcp_netid_list
*id_list
;
562 for (id_list
= daemon
->dhcp_ignore
; id_list
; id_list
= id_list
->next
)
563 if (match_netid(id_list
->list
, tagif
, 0))
567 /* if all the netids in the ignore_name list are present, ignore client-supplied name */
568 if (!state
->hostname_auth
)
570 struct dhcp_netid_list
*id_list
;
572 for (id_list
= daemon
->dhcp_ignore_names
; id_list
; id_list
= id_list
->next
)
573 if ((!id_list
->list
) || match_netid(id_list
->list
, tagif
, 0))
576 state
->hostname
= NULL
;
588 int address_assigned
= 0;
589 /* tags without all prefix-class tags */
590 struct dhcp_netid
*solicit_tags
;
591 struct dhcp_context
*c
;
593 *outmsgtypep
= DHCP6ADVERTISE
;
595 if (opt6_find(state
->packet_options
, state
->end
, OPTION6_RAPID_COMMIT
, 0))
597 *outmsgtypep
= DHCP6REPLY
;
598 state
->lease_allocate
= 1;
599 o
= new_opt6(OPTION6_RAPID_COMMIT
);
603 log6_quiet(state
, "DHCPSOLICIT", NULL
, ignore
? _("ignored") : NULL
);
606 solicit_tags
= tagif
;
611 /* reset USED bits in leases */
614 /* Can use configured address max once per prefix */
615 for (c
= state
->context
; c
; c
= c
->current
)
616 c
->flags
&= ~CONTEXT_CONF_USED
;
618 for (opt
= state
->packet_options
; opt
; opt
= opt6_next(opt
, state
->end
))
620 void *ia_option
, *ia_end
;
621 unsigned int min_time
= 0xffffffff;
624 /* set unless we're sending a particular prefix-class, when we
625 want only dhcp-ranges with the correct tags set and not those without any tags. */
628 struct dhcp_lease
*ltmp
;
629 struct in6_addr
*req_addr
;
630 struct in6_addr addr
;
632 if (!check_ia(state
, opt
, &ia_end
, &ia_option
))
635 /* reset USED bits in contexts - one address per prefix per IAID */
636 for (c
= state
->context
; c
; c
= c
->current
)
637 c
->flags
&= ~CONTEXT_USED
;
639 #ifdef OPTION6_PREFIX_CLASS
640 if (daemon
->prefix_classes
&& state
->ia_type
== OPTION6_IA_NA
)
645 if (dump_all_prefix_classes
)
646 /* OPTION_PREFIX_CLASS in ORO, send addresses in all prefix classes */
650 if ((prefix_opt
= opt6_find(opt6_ptr(opt
, 12), ia_end
, OPTION6_PREFIX_CLASS
, 2)))
653 prefix_class
= opt6_uint(prefix_opt
, 0, 2);
655 for (p
= daemon
->prefix_classes
; p
; p
= p
->next
)
656 if (p
->class == prefix_class
)
660 my_syslog(MS_DHCP
| LOG_WARNING
, _("unknown prefix-class %d"), prefix_class
);
663 /* add tag to list, and exclude undecorated dhcp-ranges */
664 p
->tag
.next
= state
->tags
;
665 solicit_tags
= run_tag_if(&p
->tag
);
667 state
->send_prefix_class
= p
;
672 /* client didn't ask for a prefix class, lets see if we can find one. */
673 for (p
= daemon
->prefix_classes
; p
; p
= p
->next
)
676 if (match_netid(&p
->tag
, solicit_tags
, 1))
683 state
->send_prefix_class
= p
;
687 if (p
&& option_bool(OPT_LOG_OPTS
))
688 my_syslog(MS_DHCP
| LOG_INFO
, "%u prefix class %d tag:%s", state
->xid
, p
->class, p
->tag
.net
);
693 o
= build_ia(state
, &t1cntr
);
694 if (address_assigned
)
695 address_assigned
= 2;
697 for (ia_counter
= 0; ia_option
; ia_counter
++, ia_option
= opt6_find(opt6_next(ia_option
, ia_end
), ia_end
, OPTION6_IAADDR
, 24))
699 req_addr
= opt6_ptr(ia_option
, 0);
701 if ((c
= address6_valid(state
->context
, req_addr
, solicit_tags
, plain_range
)))
703 lease_time
= c
->lease_time
;
704 /* If the client asks for an address on the same network as a configured address,
705 offer the configured address instead, to make moving to newly-configured
706 addresses automatic. */
707 if (!(c
->flags
& CONTEXT_CONF_USED
) && config_valid(config
, c
, &addr
) && check_address(state
, &addr
))
710 mark_config_used(c
, &addr
);
711 if (have_config(config
, CONFIG_TIME
))
712 lease_time
= config
->lease_time
;
714 else if (!(c
= address6_available(state
->context
, req_addr
, solicit_tags
, plain_range
)))
715 continue; /* not an address we're allowed */
716 else if (!check_address(state
, req_addr
))
717 continue; /* address leased elsewhere */
719 /* add address to output packet */
720 #ifdef OPTION6_PREFIX_CLASS
721 if (dump_all_prefix_classes
&& state
->ia_type
== OPTION6_IA_NA
)
722 state
->send_prefix_class
= prefix_class_from_context(c
);
724 add_address(state
, c
, lease_time
, ia_option
, &min_time
, req_addr
, now
);
725 mark_context_used(state
, req_addr
);
726 get_context_tag(state
, c
);
727 address_assigned
= 1;
731 /* Suggest configured address(es) */
732 for (c
= state
->context
; c
; c
= c
->current
)
733 if (!(c
->flags
& CONTEXT_CONF_USED
) &&
734 match_netid(c
->filter
, solicit_tags
, plain_range
) &&
735 config_valid(config
, c
, &addr
) &&
736 check_address(state
, &addr
))
738 mark_config_used(state
->context
, &addr
);
739 if (have_config(config
, CONFIG_TIME
))
740 lease_time
= config
->lease_time
;
742 lease_time
= c
->lease_time
;
743 /* add address to output packet */
744 #ifdef OPTION6_PREFIX_CLASS
745 if (dump_all_prefix_classes
&& state
->ia_type
== OPTION6_IA_NA
)
746 state
->send_prefix_class
= prefix_class_from_context(c
);
748 add_address(state
, c
, lease_time
, NULL
, &min_time
, &addr
, now
);
749 mark_context_used(state
, &addr
);
750 get_context_tag(state
, c
);
751 address_assigned
= 1;
754 /* return addresses for existing leases */
756 while ((ltmp
= lease6_find_by_client(ltmp
, state
->ia_type
== OPTION6_IA_NA
? LEASE_NA
: LEASE_TA
, state
->clid
, state
->clid_len
, state
->iaid
)))
758 req_addr
= <mp
->addr6
;
759 if ((c
= address6_available(state
->context
, req_addr
, solicit_tags
, plain_range
)))
761 #ifdef OPTION6_PREFIX_CLASS
762 if (dump_all_prefix_classes
&& state
->ia_type
== OPTION6_IA_NA
)
763 state
->send_prefix_class
= prefix_class_from_context(c
);
765 add_address(state
, c
, c
->lease_time
, NULL
, &min_time
, req_addr
, now
);
766 mark_context_used(state
, req_addr
);
767 get_context_tag(state
, c
);
768 address_assigned
= 1;
772 /* Return addresses for all valid contexts which don't yet have one */
773 while ((c
= address6_allocate(state
->context
, state
->clid
, state
->clid_len
, state
->ia_type
== OPTION6_IA_TA
,
774 state
->iaid
, ia_counter
, solicit_tags
, plain_range
, &addr
)))
776 #ifdef OPTION6_PREFIX_CLASS
777 if (dump_all_prefix_classes
&& state
->ia_type
== OPTION6_IA_NA
)
778 state
->send_prefix_class
= prefix_class_from_context(c
);
780 add_address(state
, c
, c
->lease_time
, NULL
, &min_time
, &addr
, now
);
781 mark_context_used(state
, &addr
);
782 get_context_tag(state
, c
);
783 address_assigned
= 1;
786 if (address_assigned
!= 1)
788 /* If the server will not assign any addresses to any IAs in a
789 subsequent Request from the client, the server MUST send an Advertise
790 message to the client that doesn't include any IA options. */
791 if (!state
->lease_allocate
)
797 /* If the server cannot assign any addresses to an IA in the message
798 from the client, the server MUST include the IA in the Reply message
799 with no addresses in the IA and a Status Code option in the IA
800 containing status code NoAddrsAvail. */
801 o1
= new_opt6(OPTION6_STATUS_CODE
);
802 put_opt6_short(DHCP6NOADDRS
);
803 put_opt6_string(_("address unavailable"));
807 end_ia(t1cntr
, min_time
, 0);
811 if (address_assigned
)
813 o1
= new_opt6(OPTION6_STATUS_CODE
);
814 put_opt6_short(DHCP6SUCCESS
);
815 put_opt6_string(_("success"));
818 /* If --dhcp-authoritative is set, we can tell client not to wait for
819 other possible servers */
820 o
= new_opt6(OPTION6_PREFERENCE
);
821 put_opt6_char(option_bool(OPT_AUTHORITATIVE
) ? 255 : 0);
823 tagif
= add_options(state
, 0);
827 /* no address, return error */
828 o1
= new_opt6(OPTION6_STATUS_CODE
);
829 put_opt6_short(DHCP6NOADDRS
);
830 put_opt6_string(_("no addresses available"));
832 log6_packet(state
, state
->lease_allocate
? "DHCPREPLY" : "DHCPADVERTISE", NULL
, _("no addresses available"));
840 int address_assigned
= 0;
841 int start
= save_counter(-1);
843 /* set reply message type */
844 *outmsgtypep
= DHCP6REPLY
;
845 state
->lease_allocate
= 1;
847 log6_quiet(state
, "DHCPREQUEST", NULL
, ignore
? _("ignored") : NULL
);
852 for (opt
= state
->packet_options
; opt
; opt
= opt6_next(opt
, state
->end
))
854 void *ia_option
, *ia_end
;
855 unsigned int min_time
= 0xffffffff;
858 if (!check_ia(state
, opt
, &ia_end
, &ia_option
))
863 /* If we get a request with a IA_*A without addresses, treat it exactly like
864 a SOLICT with rapid commit set. */
866 goto request_no_address
;
869 o
= build_ia(state
, &t1cntr
);
871 for (; ia_option
; ia_option
= opt6_find(opt6_next(ia_option
, ia_end
), ia_end
, OPTION6_IAADDR
, 24))
873 struct in6_addr
*req_addr
= opt6_ptr(ia_option
, 0);
874 struct dhcp_context
*dynamic
, *c
;
875 unsigned int lease_time
;
876 struct in6_addr addr
;
879 if ((c
= address6_valid(state
->context
, req_addr
, tagif
, 1)))
880 config_ok
= config_valid(config
, c
, &addr
) && IN6_ARE_ADDR_EQUAL(&addr
, req_addr
);
882 if ((dynamic
= address6_available(state
->context
, req_addr
, tagif
, 1)) || c
)
884 if (!dynamic
&& !config_ok
)
886 /* Static range, not configured. */
887 o1
= new_opt6(OPTION6_STATUS_CODE
);
888 put_opt6_short(DHCP6NOADDRS
);
889 put_opt6_string(_("address unavailable"));
892 else if (!check_address(state
, req_addr
))
894 /* Address leased to another DUID/IAID */
895 o1
= new_opt6(OPTION6_STATUS_CODE
);
896 put_opt6_short(DHCP6UNSPEC
);
897 put_opt6_string(_("address in use"));
905 lease_time
= dynamic
->lease_time
;
907 if (config_ok
&& have_config(config
, CONFIG_TIME
))
908 lease_time
= config
->lease_time
;
910 #ifdef OPTION6_PREFIX_CLASS
911 if (dump_all_prefix_classes
&& state
->ia_type
== OPTION6_IA_NA
)
912 state
->send_prefix_class
= prefix_class_from_context(c
);
914 add_address(state
, dynamic
, lease_time
, ia_option
, &min_time
, req_addr
, now
);
915 get_context_tag(state
, dynamic
);
916 address_assigned
= 1;
921 /* requested address not on the correct link */
922 o1
= new_opt6(OPTION6_STATUS_CODE
);
923 put_opt6_short(DHCP6NOTONLINK
);
924 put_opt6_string(_("not on link"));
929 end_ia(t1cntr
, min_time
, 0);
933 if (address_assigned
)
935 o1
= new_opt6(OPTION6_STATUS_CODE
);
936 put_opt6_short(DHCP6SUCCESS
);
937 put_opt6_string(_("success"));
942 /* no address, return error */
943 o1
= new_opt6(OPTION6_STATUS_CODE
);
944 put_opt6_short(DHCP6NOADDRS
);
945 put_opt6_string(_("no addresses available"));
947 log6_packet(state
, "DHCPREPLY", NULL
, _("no addresses available"));
950 tagif
= add_options(state
, 0);
957 /* set reply message type */
958 *outmsgtypep
= DHCP6REPLY
;
960 log6_quiet(state
, "DHCPRENEW", NULL
, NULL
);
962 for (opt
= state
->packet_options
; opt
; opt
= opt6_next(opt
, state
->end
))
964 void *ia_option
, *ia_end
;
965 unsigned int min_time
= 0xffffffff;
968 if (!check_ia(state
, opt
, &ia_end
, &ia_option
))
971 o
= build_ia(state
, &t1cntr
);
972 iacntr
= save_counter(-1);
974 for (; ia_option
; ia_option
= opt6_find(opt6_next(ia_option
, ia_end
), ia_end
, OPTION6_IAADDR
, 24))
976 struct dhcp_lease
*lease
= NULL
;
977 struct in6_addr
*req_addr
= opt6_ptr(ia_option
, 0);
978 unsigned int preferred_time
= opt6_uint(ia_option
, 16, 4);
979 unsigned int valid_time
= opt6_uint(ia_option
, 20, 4);
980 char *message
= NULL
;
981 struct dhcp_context
*this_context
;
983 if (!(lease
= lease6_find(state
->clid
, state
->clid_len
,
984 state
->ia_type
== OPTION6_IA_NA
? LEASE_NA
: LEASE_TA
,
985 state
->iaid
, req_addr
)))
987 /* If the server cannot find a client entry for the IA the server
988 returns the IA containing no addresses with a Status Code option set
989 to NoBinding in the Reply message. */
990 save_counter(iacntr
);
993 log6_packet(state
, "DHCPREPLY", req_addr
, _("lease not found"));
995 o1
= new_opt6(OPTION6_STATUS_CODE
);
996 put_opt6_short(DHCP6NOBINDING
);
997 put_opt6_string(_("no binding found"));
1000 preferred_time
= valid_time
= 0;
1005 if ((this_context
= address6_available(state
->context
, req_addr
, tagif
, 1)) ||
1006 (this_context
= address6_valid(state
->context
, req_addr
, tagif
, 1)))
1008 struct in6_addr addr
;
1009 unsigned int lease_time
;
1011 get_context_tag(state
, this_context
);
1013 if (config_valid(config
, this_context
, &addr
) && IN6_ARE_ADDR_EQUAL(&addr
, req_addr
) && have_config(config
, CONFIG_TIME
))
1014 lease_time
= config
->lease_time
;
1016 lease_time
= this_context
->lease_time
;
1018 calculate_times(this_context
, &min_time
, &valid_time
, &preferred_time
, lease_time
);
1020 lease_set_expires(lease
, valid_time
, now
);
1021 /* Update MAC record in case it's new information. */
1022 if (state
->mac_len
!= 0)
1023 lease_set_hwaddr(lease
, state
->mac
, state
->clid
, state
->mac_len
, state
->mac_type
, state
->clid_len
, now
, 0);
1024 if (state
->ia_type
== OPTION6_IA_NA
&& state
->hostname
)
1026 char *addr_domain
= get_domain6(req_addr
);
1027 if (!state
->send_domain
)
1028 state
->send_domain
= addr_domain
;
1029 lease_set_hostname(lease
, state
->hostname
, state
->hostname_auth
, addr_domain
, state
->domain
);
1030 message
= state
->hostname
;
1034 if (preferred_time
== 0)
1035 message
= _("deprecated");
1039 preferred_time
= valid_time
= 0;
1040 message
= _("address invalid");
1044 log6_packet(state
, "DHCPREPLY", req_addr
, message
);
1046 log6_quiet(state
, "DHCPREPLY", req_addr
, message
);
1048 o1
= new_opt6(OPTION6_IAADDR
);
1049 put_opt6(req_addr
, sizeof(*req_addr
));
1050 put_opt6_long(preferred_time
);
1051 put_opt6_long(valid_time
);
1055 end_ia(t1cntr
, min_time
, 1);
1059 tagif
= add_options(state
, 0);
1068 /* set reply message type */
1069 *outmsgtypep
= DHCP6REPLY
;
1071 log6_quiet(state
, "DHCPCONFIRM", NULL
, NULL
);
1073 for (opt
= state
->packet_options
; opt
; opt
= opt6_next(opt
, state
->end
))
1075 void *ia_option
, *ia_end
;
1077 for (check_ia(state
, opt
, &ia_end
, &ia_option
);
1079 ia_option
= opt6_find(opt6_next(ia_option
, ia_end
), ia_end
, OPTION6_IAADDR
, 24))
1081 struct in6_addr
*req_addr
= opt6_ptr(ia_option
, 0);
1083 if (!address6_available(state
->context
, req_addr
, tagif
, 1))
1085 o1
= new_opt6(OPTION6_STATUS_CODE
);
1086 put_opt6_short(DHCP6NOTONLINK
);
1087 put_opt6_string(_("confirm failed"));
1093 log6_quiet(state
, "DHCPREPLY", req_addr
, state
->hostname
);
1097 /* No addresses, no reply: RFC 3315 18.2.2 */
1101 o1
= new_opt6(OPTION6_STATUS_CODE
);
1102 put_opt6_short(DHCP6SUCCESS
);
1103 put_opt6_string(_("all addresses still on link"));
1110 /* We can't discriminate contexts based on address, as we don't know it.
1111 If there is only one possible context, we can use its tags */
1112 if (state
->context
&& state
->context
->netid
.net
&& !state
->context
->current
)
1114 state
->context
->netid
.next
= NULL
;
1115 state
->context_tags
= &state
->context
->netid
;
1118 /* Similarly, we can't determine domain from address, but if the FQDN is
1119 given in --dhcp-host, we can use that, and failing that we can use the
1120 unqualified configured domain, if any. */
1121 if (state
->hostname_auth
)
1122 state
->send_domain
= state
->domain
;
1124 state
->send_domain
= get_domain6(NULL
);
1126 log6_quiet(state
, "DHCPINFORMATION-REQUEST", NULL
, ignore
? _("ignored") : state
->hostname
);
1129 *outmsgtypep
= DHCP6REPLY
;
1130 tagif
= add_options(state
, 1);
1137 /* set reply message type */
1138 *outmsgtypep
= DHCP6REPLY
;
1140 log6_quiet(state
, "DHCPRELEASE", NULL
, NULL
);
1142 for (opt
= state
->packet_options
; opt
; opt
= opt6_next(opt
, state
->end
))
1144 void *ia_option
, *ia_end
;
1147 for (check_ia(state
, opt
, &ia_end
, &ia_option
);
1149 ia_option
= opt6_find(opt6_next(ia_option
, ia_end
), ia_end
, OPTION6_IAADDR
, 24))
1151 struct dhcp_lease
*lease
;
1153 if ((lease
= lease6_find(state
->clid
, state
->clid_len
, state
->ia_type
== OPTION6_IA_NA
? LEASE_NA
: LEASE_TA
,
1154 state
->iaid
, opt6_ptr(ia_option
, 0))))
1155 lease_prune(lease
, now
);
1160 o
= new_opt6(state
->ia_type
);
1161 put_opt6_long(state
->iaid
);
1162 if (state
->ia_type
== OPTION6_IA_NA
)
1170 o1
= new_opt6(OPTION6_IAADDR
);
1171 put_opt6(opt6_ptr(ia_option
, 0), IN6ADDRSZ
);
1180 o1
= new_opt6(OPTION6_STATUS_CODE
);
1181 put_opt6_short(DHCP6NOBINDING
);
1182 put_opt6_string(_("no binding found"));
1189 o1
= new_opt6(OPTION6_STATUS_CODE
);
1190 put_opt6_short(DHCP6SUCCESS
);
1191 put_opt6_string(_("release received"));
1199 /* set reply message type */
1200 *outmsgtypep
= DHCP6REPLY
;
1202 log6_quiet(state
, "DHCPDECLINE", NULL
, NULL
);
1204 for (opt
= state
->packet_options
; opt
; opt
= opt6_next(opt
, state
->end
))
1206 void *ia_option
, *ia_end
;
1209 for (check_ia(state
, opt
, &ia_end
, &ia_option
);
1211 ia_option
= opt6_find(opt6_next(ia_option
, ia_end
), ia_end
, OPTION6_IAADDR
, 24))
1213 struct dhcp_lease
*lease
;
1214 struct in6_addr
*addrp
= opt6_ptr(ia_option
, 0);
1216 if (have_config(config
, CONFIG_ADDR6
) && IN6_ARE_ADDR_EQUAL(&config
->addr6
, addrp
))
1218 prettyprint_time(daemon
->dhcp_buff3
, DECLINE_BACKOFF
);
1219 inet_ntop(AF_INET6
, addrp
, daemon
->addrbuff
, ADDRSTRLEN
);
1220 my_syslog(MS_DHCP
| LOG_WARNING
, _("disabling DHCP static address %s for %s"),
1221 daemon
->addrbuff
, daemon
->dhcp_buff3
);
1222 config
->flags
|= CONFIG_DECLINED
;
1223 config
->decline_time
= now
;
1226 /* make sure this host gets a different address next time. */
1227 for (context_tmp
= state
->context
; context_tmp
; context_tmp
= context_tmp
->current
)
1228 context_tmp
->addr_epoch
++;
1230 if ((lease
= lease6_find(state
->clid
, state
->clid_len
, state
->ia_type
== OPTION6_IA_NA
? LEASE_NA
: LEASE_TA
,
1231 state
->iaid
, opt6_ptr(ia_option
, 0))))
1232 lease_prune(lease
, now
);
1237 o
= new_opt6(state
->ia_type
);
1238 put_opt6_long(state
->iaid
);
1239 if (state
->ia_type
== OPTION6_IA_NA
)
1247 o1
= new_opt6(OPTION6_IAADDR
);
1248 put_opt6(opt6_ptr(ia_option
, 0), IN6ADDRSZ
);
1257 o1
= new_opt6(OPTION6_STATUS_CODE
);
1258 put_opt6_short(DHCP6NOBINDING
);
1259 put_opt6_string(_("no binding found"));
1267 /* We must anwser with 'success' in global section anyway */
1268 o1
= new_opt6(OPTION6_STATUS_CODE
);
1269 put_opt6_short(DHCP6SUCCESS
);
1270 put_opt6_string(_("success"));
1277 log_tags(tagif
, state
->xid
);
1278 log6_opts(0, state
->xid
, daemon
->outpacket
.iov_base
+ start_opts
, daemon
->outpacket
.iov_base
+ save_counter(-1));
1284 static struct dhcp_netid
*add_options(struct state
*state
, int do_refresh
)
1287 /* filter options based on tags, those we want get DHOPT_TAGOK bit set */
1288 struct dhcp_netid
*tagif
= option_filter(state
->tags
, state
->context_tags
, daemon
->dhcp_opts6
);
1289 struct dhcp_opt
*opt_cfg
;
1290 int done_dns
= 0, done_refresh
= !do_refresh
, do_encap
= 0;
1293 oro
= opt6_find(state
->packet_options
, state
->end
, OPTION6_ORO
, 0);
1295 for (opt_cfg
= daemon
->dhcp_opts6
; opt_cfg
; opt_cfg
= opt_cfg
->next
)
1297 /* netids match and not encapsulated? */
1298 if (!(opt_cfg
->flags
& DHOPT_TAGOK
))
1301 if (!(opt_cfg
->flags
& DHOPT_FORCE
) && oro
)
1303 for (i
= 0; i
< opt6_len(oro
) - 1; i
+= 2)
1304 if (opt6_uint(oro
, i
, 2) == (unsigned)opt_cfg
->opt
)
1307 /* option not requested */
1308 if (i
>= opt6_len(oro
) - 1)
1312 if (opt_cfg
->opt
== OPTION6_REFRESH_TIME
)
1315 if (opt_cfg
->flags
& DHOPT_ADDR6
)
1320 if (opt_cfg
->opt
== OPTION6_DNS_SERVER
)
1323 for (a
= (struct in6_addr
*)opt_cfg
->val
, len
= opt_cfg
->len
, j
= 0;
1324 j
< opt_cfg
->len
; j
+= IN6ADDRSZ
, a
++)
1325 if ((IN6_IS_ADDR_ULA_ZERO(a
) && IN6_IS_ADDR_UNSPECIFIED(state
->ula_addr
)) ||
1326 (IN6_IS_ADDR_LINK_LOCAL_ZERO(a
) && IN6_IS_ADDR_UNSPECIFIED(state
->ll_addr
)))
1332 o
= new_opt6(opt_cfg
->opt
);
1334 for (a
= (struct in6_addr
*)opt_cfg
->val
, j
= 0; j
< opt_cfg
->len
; j
+=IN6ADDRSZ
, a
++)
1336 if (IN6_IS_ADDR_UNSPECIFIED(a
))
1338 if (!add_local_addrs(state
->context
))
1339 put_opt6(state
->fallback
, IN6ADDRSZ
);
1341 else if (IN6_IS_ADDR_ULA_ZERO(a
))
1343 if (!IN6_IS_ADDR_UNSPECIFIED(state
->ula_addr
))
1344 put_opt6(state
->ula_addr
, IN6ADDRSZ
);
1346 else if (IN6_IS_ADDR_LINK_LOCAL_ZERO(a
))
1348 if (!IN6_IS_ADDR_UNSPECIFIED(state
->ll_addr
))
1349 put_opt6(state
->ll_addr
, IN6ADDRSZ
);
1352 put_opt6(a
, IN6ADDRSZ
);
1360 o
= new_opt6(opt_cfg
->opt
);
1362 put_opt6(opt_cfg
->val
, opt_cfg
->len
);
1367 if (daemon
->port
== NAMESERVER_PORT
&& !done_dns
)
1369 o
= new_opt6(OPTION6_DNS_SERVER
);
1370 if (!add_local_addrs(state
->context
))
1371 put_opt6(state
->fallback
, IN6ADDRSZ
);
1375 if (state
->context
&& !done_refresh
)
1377 struct dhcp_context
*c
;
1378 unsigned int lease_time
= 0xffffffff;
1380 /* Find the smallest lease tie of all contexts,
1381 subjext to the RFC-4242 stipulation that this must not
1382 be less than 600. */
1383 for (c
= state
->context
; c
; c
= c
->next
)
1384 if (c
->lease_time
< lease_time
)
1386 if (c
->lease_time
< 600)
1389 lease_time
= c
->lease_time
;
1392 o
= new_opt6(OPTION6_REFRESH_TIME
);
1393 put_opt6_long(lease_time
);
1397 /* handle vendor-identifying vendor-encapsulated options,
1398 dhcp-option = vi-encap:13,17,....... */
1399 for (opt_cfg
= daemon
->dhcp_opts6
; opt_cfg
; opt_cfg
= opt_cfg
->next
)
1400 opt_cfg
->flags
&= ~DHOPT_ENCAP_DONE
;
1403 for (i
= 0; i
< opt6_len(oro
) - 1; i
+= 2)
1404 if (opt6_uint(oro
, i
, 2) == OPTION6_VENDOR_OPTS
)
1407 for (opt_cfg
= daemon
->dhcp_opts6
; opt_cfg
; opt_cfg
= opt_cfg
->next
)
1409 if (opt_cfg
->flags
& DHOPT_RFC3925
)
1412 struct dhcp_opt
*oc
;
1414 if (opt_cfg
->flags
& DHOPT_ENCAP_DONE
)
1417 for (oc
= daemon
->dhcp_opts6
; oc
; oc
= oc
->next
)
1419 oc
->flags
&= ~DHOPT_ENCAP_MATCH
;
1421 if (!(oc
->flags
& DHOPT_RFC3925
) || opt_cfg
->u
.encap
!= oc
->u
.encap
)
1424 oc
->flags
|= DHOPT_ENCAP_DONE
;
1425 if (match_netid(oc
->netid
, tagif
, 1))
1427 /* option requested/forced? */
1428 if (!oro
|| do_encap
|| (oc
->flags
& DHOPT_FORCE
))
1430 oc
->flags
|= DHOPT_ENCAP_MATCH
;
1438 o
= new_opt6(OPTION6_VENDOR_OPTS
);
1439 put_opt6_long(opt_cfg
->u
.encap
);
1441 for (oc
= daemon
->dhcp_opts6
; oc
; oc
= oc
->next
)
1442 if (oc
->flags
& DHOPT_ENCAP_MATCH
)
1444 o1
= new_opt6(oc
->opt
);
1445 put_opt6(oc
->val
, oc
->len
);
1454 if (state
->hostname
)
1457 size_t len
= strlen(state
->hostname
);
1459 if (state
->send_domain
)
1460 len
+= strlen(state
->send_domain
) + 2;
1462 o
= new_opt6(OPTION6_FQDN
);
1463 if ((p
= expand(len
+ 2)))
1465 *(p
++) = state
->fqdn_flags
;
1466 p
= do_rfc1035_name(p
, state
->hostname
);
1467 if (state
->send_domain
)
1469 p
= do_rfc1035_name(p
, state
->send_domain
);
1478 if (option_bool(OPT_LOG_OPTS
) && oro
)
1480 char *q
= daemon
->namebuff
;
1481 for (i
= 0; i
< opt6_len(oro
) - 1; i
+= 2)
1483 char *s
= option_string(AF_INET6
, opt6_uint(oro
, i
, 2), NULL
, 0, NULL
, 0);
1484 q
+= snprintf(q
, MAXDNAME
- (q
- daemon
->namebuff
),
1486 opt6_uint(oro
, i
, 2),
1487 strlen(s
) != 0 ? ":" : "",
1489 (i
> opt6_len(oro
) - 3) ? "" : ", ");
1490 if ( i
> opt6_len(oro
) - 3 || (q
- daemon
->namebuff
) > 40)
1492 q
= daemon
->namebuff
;
1493 my_syslog(MS_DHCP
| LOG_INFO
, _("%u requested options: %s"), state
->xid
, daemon
->namebuff
);
1501 static int add_local_addrs(struct dhcp_context
*context
)
1505 for (; context
; context
= context
->current
)
1506 if ((context
->flags
& CONTEXT_USED
) && !IN6_IS_ADDR_UNSPECIFIED(&context
->local6
))
1508 /* squash duplicates */
1509 struct dhcp_context
*c
;
1510 for (c
= context
->current
; c
; c
= c
->current
)
1511 if ((c
->flags
& CONTEXT_USED
) &&
1512 IN6_ARE_ADDR_EQUAL(&context
->local6
, &c
->local6
))
1518 put_opt6(&context
->local6
, IN6ADDRSZ
);
1526 static void get_context_tag(struct state
*state
, struct dhcp_context
*context
)
1528 /* get tags from context if we've not used it before */
1529 if (context
->netid
.next
== &context
->netid
&& context
->netid
.net
)
1531 context
->netid
.next
= state
->context_tags
;
1532 state
->context_tags
= &context
->netid
;
1533 if (!state
->hostname_auth
)
1535 struct dhcp_netid_list
*id_list
;
1537 for (id_list
= daemon
->dhcp_ignore_names
; id_list
; id_list
= id_list
->next
)
1538 if ((!id_list
->list
) || match_netid(id_list
->list
, &context
->netid
, 0))
1541 state
->hostname
= NULL
;
1546 #ifdef OPTION6_PREFIX_CLASS
1547 static struct prefix_class
*prefix_class_from_context(struct dhcp_context
*context
)
1549 struct prefix_class
*p
;
1550 struct dhcp_netid
*t
;
1552 for (p
= daemon
->prefix_classes
; p
; p
= p
->next
)
1553 for (t
= context
->filter
; t
; t
= t
->next
)
1554 if (strcmp(p
->tag
.net
, t
->net
) == 0)
1561 static int check_ia(struct state
*state
, void *opt
, void **endp
, void **ia_option
)
1563 state
->ia_type
= opt6_type(opt
);
1566 if (state
->ia_type
!= OPTION6_IA_NA
&& state
->ia_type
!= OPTION6_IA_TA
)
1569 if (state
->ia_type
== OPTION6_IA_NA
&& opt6_len(opt
) < 12)
1572 if (state
->ia_type
== OPTION6_IA_TA
&& opt6_len(opt
) < 4)
1575 *endp
= opt6_ptr(opt
, opt6_len(opt
));
1576 state
->iaid
= opt6_uint(opt
, 0, 4);
1577 *ia_option
= opt6_find(opt6_ptr(opt
, state
->ia_type
== OPTION6_IA_NA
? 12 : 4), *endp
, OPTION6_IAADDR
, 24);
1583 static int build_ia(struct state
*state
, int *t1cntr
)
1585 int o
= new_opt6(state
->ia_type
);
1587 put_opt6_long(state
->iaid
);
1590 if (state
->ia_type
== OPTION6_IA_NA
)
1593 *t1cntr
= save_counter(-1);
1594 /* so we can fill these in later */
1602 static void end_ia(int t1cntr
, unsigned int min_time
, int do_fuzz
)
1606 /* go back an fill in fields in IA_NA option */
1607 int sav
= save_counter(t1cntr
);
1608 unsigned int t1
, t2
, fuzz
= 0;
1614 while (fuzz
> (min_time
/16))
1618 t1
= (min_time
== 0xffffffff) ? 0xffffffff : min_time
/2 - fuzz
;
1619 t2
= (min_time
== 0xffffffff) ? 0xffffffff : ((min_time
/8)*7) - fuzz
;
1626 static void add_address(struct state
*state
, struct dhcp_context
*context
, unsigned int lease_time
, void *ia_option
,
1627 unsigned int *min_time
, struct in6_addr
*addr
, time_t now
)
1629 unsigned int valid_time
= 0, preferred_time
= 0;
1630 int o
= new_opt6(OPTION6_IAADDR
);
1631 struct dhcp_lease
*lease
;
1633 /* get client requested times */
1636 preferred_time
= opt6_uint(ia_option
, 16, 4);
1637 valid_time
= opt6_uint(ia_option
, 20, 4);
1640 calculate_times(context
, min_time
, &valid_time
, &preferred_time
, lease_time
);
1642 put_opt6(addr
, sizeof(*addr
));
1643 put_opt6_long(preferred_time
);
1644 put_opt6_long(valid_time
);
1646 #ifdef OPTION6_PREFIX_CLASS
1647 if (state
->send_prefix_class
)
1649 int o1
= new_opt6(OPTION6_PREFIX_CLASS
);
1650 put_opt6_short(state
->send_prefix_class
->class);
1657 if (state
->lease_allocate
)
1658 update_leases(state
, context
, addr
, valid_time
, now
);
1660 if ((lease
= lease6_find_by_addr(addr
, 128, 0)))
1661 lease
->flags
|= LEASE_USED
;
1663 /* get tags from context if we've not used it before */
1664 if (context
->netid
.next
== &context
->netid
&& context
->netid
.net
)
1666 context
->netid
.next
= state
->context_tags
;
1667 state
->context_tags
= &context
->netid
;
1669 if (!state
->hostname_auth
)
1671 struct dhcp_netid_list
*id_list
;
1673 for (id_list
= daemon
->dhcp_ignore_names
; id_list
; id_list
= id_list
->next
)
1674 if ((!id_list
->list
) || match_netid(id_list
->list
, &context
->netid
, 0))
1677 state
->hostname
= NULL
;
1681 log6_quiet(state
, state
->lease_allocate
? "DHCPREPLY" : "DHCPADVERTISE", addr
, state
->hostname
);
1685 static void mark_context_used(struct state
*state
, struct in6_addr
*addr
)
1687 struct dhcp_context
*context
;
1689 /* Mark that we have an address for this prefix. */
1690 #ifdef OPTION6_PREFIX_CLASS
1691 for (context
= state
->context
; context
; context
= context
->current
)
1692 if (is_same_net6(addr
, &context
->start6
, context
->prefix
) &&
1693 (!state
->send_prefix_class
|| state
->send_prefix_class
== prefix_class_from_context(context
)))
1694 context
->flags
|= CONTEXT_USED
;
1696 for (context
= state
->context
; context
; context
= context
->current
)
1697 if (is_same_net6(addr
, &context
->start6
, context
->prefix
))
1698 context
->flags
|= CONTEXT_USED
;
1702 static void mark_config_used(struct dhcp_context
*context
, struct in6_addr
*addr
)
1704 for (; context
; context
= context
->current
)
1705 if (is_same_net6(addr
, &context
->start6
, context
->prefix
))
1706 context
->flags
|= CONTEXT_CONF_USED
;
1709 /* make sure address not leased to another CLID/IAID */
1710 static int check_address(struct state
*state
, struct in6_addr
*addr
)
1712 struct dhcp_lease
*lease
;
1714 if (!(lease
= lease6_find_by_addr(addr
, 128, 0)))
1717 if (lease
->clid_len
!= state
->clid_len
||
1718 memcmp(lease
->clid
, state
->clid
, state
->clid_len
) != 0 ||
1719 lease
->iaid
!= state
->iaid
)
1726 /* Calculate valid and preferred times to send in leases/renewals.
1730 *valid_timep, *preferred_timep - requested times from IAADDR options.
1731 context->valid, context->preferred - times associated with subnet address on local interface.
1732 context->flags | CONTEXT_DEPRECATE - "deprecated" flag in dhcp-range.
1733 lease_time - configured time for context for individual client.
1734 *min_time - smallest valid time sent so far.
1738 *valid_timep, *preferred_timep - times to be send in IAADDR option.
1739 *min_time - smallest valid time sent so far, to calculate T1 and T2.
1742 static void calculate_times(struct dhcp_context
*context
, unsigned int *min_time
, unsigned int *valid_timep
,
1743 unsigned int *preferred_timep
, unsigned int lease_time
)
1745 unsigned int req_preferred
= *preferred_timep
, req_valid
= *valid_timep
;
1746 unsigned int valid_time
= lease_time
, preferred_time
= lease_time
;
1748 /* RFC 3315: "A server ignores the lifetimes set
1749 by the client if the preferred lifetime is greater than the valid
1751 if (req_preferred
<= req_valid
)
1753 if (req_preferred
!= 0)
1755 /* 0 == "no preference from client" */
1756 if (req_preferred
< 120u)
1757 req_preferred
= 120u; /* sanity */
1759 if (req_preferred
< preferred_time
)
1760 preferred_time
= req_preferred
;
1764 /* 0 == "no preference from client" */
1766 if (req_valid
< 120u)
1767 req_valid
= 120u; /* sanity */
1769 if (req_valid
< valid_time
)
1770 valid_time
= req_valid
;
1774 /* deprecate (preferred == 0) which configured, or when local address
1776 if ((context
->flags
& CONTEXT_DEPRECATE
) || context
->preferred
== 0)
1779 if (preferred_time
!= 0 && preferred_time
< *min_time
)
1780 *min_time
= preferred_time
;
1782 if (valid_time
!= 0 && valid_time
< *min_time
)
1783 *min_time
= valid_time
;
1785 *valid_timep
= valid_time
;
1786 *preferred_timep
= preferred_time
;
1789 static void update_leases(struct state
*state
, struct dhcp_context
*context
, struct in6_addr
*addr
, unsigned int lease_time
, time_t now
)
1791 struct dhcp_lease
*lease
= lease6_find_by_addr(addr
, 128, 0);
1793 struct dhcp_netid
*tagif
= run_tag_if(state
->tags
);
1799 lease
= lease6_allocate(addr
, state
->ia_type
== OPTION6_IA_NA
? LEASE_NA
: LEASE_TA
);
1803 lease_set_expires(lease
, lease_time
, now
);
1804 lease_set_iaid(lease
, state
->iaid
);
1805 lease_set_hwaddr(lease
, state
->mac
, state
->clid
, state
->mac_len
, state
->mac_type
, state
->clid_len
, now
, 0);
1806 lease_set_interface(lease
, state
->interface
, now
);
1807 if (state
->hostname
&& state
->ia_type
== OPTION6_IA_NA
)
1809 char *addr_domain
= get_domain6(addr
);
1810 if (!state
->send_domain
)
1811 state
->send_domain
= addr_domain
;
1812 lease_set_hostname(lease
, state
->hostname
, state
->hostname_auth
, addr_domain
, state
->domain
);
1816 if (daemon
->lease_change_command
)
1819 lease
->flags
|= LEASE_CHANGED
;
1820 free(lease
->extradata
);
1821 lease
->extradata
= NULL
;
1822 lease
->extradata_size
= lease
->extradata_len
= 0;
1823 lease
->vendorclass_count
= 0;
1825 if ((class_opt
= opt6_find(state
->packet_options
, state
->end
, OPTION6_VENDOR_CLASS
, 4)))
1827 void *enc_opt
, *enc_end
= opt6_ptr(class_opt
, opt6_len(class_opt
));
1828 lease
->vendorclass_count
++;
1829 /* send enterprise number first */
1830 sprintf(daemon
->dhcp_buff2
, "%u", opt6_uint(class_opt
, 0, 4));
1831 lease_add_extradata(lease
, (unsigned char *)daemon
->dhcp_buff2
, strlen(daemon
->dhcp_buff2
), 0);
1833 if (opt6_len(class_opt
) >= 6)
1834 for (enc_opt
= opt6_ptr(class_opt
, 4); enc_opt
; enc_opt
= opt6_next(enc_opt
, enc_end
))
1836 lease
->vendorclass_count
++;
1837 lease_add_extradata(lease
, opt6_ptr(enc_opt
, 0), opt6_len(enc_opt
), 0);
1841 lease_add_extradata(lease
, (unsigned char *)state
->client_hostname
,
1842 state
->client_hostname
? strlen(state
->client_hostname
) : 0, 0);
1844 /* space-concat tag set */
1845 if (!tagif
&& !context
->netid
.net
)
1846 lease_add_extradata(lease
, NULL
, 0, 0);
1849 if (context
->netid
.net
)
1850 lease_add_extradata(lease
, (unsigned char *)context
->netid
.net
, strlen(context
->netid
.net
), tagif
? ' ' : 0);
1854 struct dhcp_netid
*n
;
1855 for (n
= tagif
; n
; n
= n
->next
)
1857 struct dhcp_netid
*n1
;
1859 for (n1
= n
->next
; n1
; n1
= n1
->next
)
1860 if (strcmp(n
->net
, n1
->net
) == 0)
1863 lease_add_extradata(lease
, (unsigned char *)n
->net
, strlen(n
->net
), n
->next
? ' ' : 0);
1868 if (state
->link_address
)
1869 inet_ntop(AF_INET6
, state
->link_address
, daemon
->addrbuff
, ADDRSTRLEN
);
1871 lease_add_extradata(lease
, (unsigned char *)daemon
->addrbuff
, state
->link_address
? strlen(daemon
->addrbuff
) : 0, 0);
1873 if ((class_opt
= opt6_find(state
->packet_options
, state
->end
, OPTION6_USER_CLASS
, 2)))
1875 void *enc_opt
, *enc_end
= opt6_ptr(class_opt
, opt6_len(class_opt
));
1876 for (enc_opt
= opt6_ptr(class_opt
, 0); enc_opt
; enc_opt
= opt6_next(enc_opt
, enc_end
))
1877 lease_add_extradata(lease
, opt6_ptr(enc_opt
, 0), opt6_len(enc_opt
), 0);
1887 static void log6_opts(int nest
, unsigned int xid
, void *start_opts
, void *end_opts
)
1890 char *desc
= nest
? "nest" : "sent";
1892 if (!option_bool(OPT_LOG_OPTS
) || start_opts
== end_opts
)
1895 for (opt
= start_opts
; opt
; opt
= opt6_next(opt
, end_opts
))
1897 int type
= opt6_type(opt
);
1898 void *ia_options
= NULL
;
1901 if (type
== OPTION6_IA_NA
)
1903 sprintf(daemon
->namebuff
, "IAID=%u T1=%u T2=%u",
1904 opt6_uint(opt
, 0, 4), opt6_uint(opt
, 4, 4), opt6_uint(opt
, 8, 4));
1906 ia_options
= opt6_ptr(opt
, 12);
1908 else if (type
== OPTION6_IA_TA
)
1910 sprintf(daemon
->namebuff
, "IAID=%u", opt6_uint(opt
, 0, 4));
1912 ia_options
= opt6_ptr(opt
, 4);
1914 else if (type
== OPTION6_IAADDR
)
1916 inet_ntop(AF_INET6
, opt6_ptr(opt
, 0), daemon
->addrbuff
, ADDRSTRLEN
);
1917 sprintf(daemon
->namebuff
, "%s PL=%u VL=%u",
1918 daemon
->addrbuff
, opt6_uint(opt
, 16, 4), opt6_uint(opt
, 20, 4));
1920 ia_options
= opt6_ptr(opt
, 24);
1922 #ifdef OPTION6_PREFIX_CLASS
1923 else if (type
== OPTION6_PREFIX_CLASS
)
1925 optname
= "prefix-class";
1926 sprintf(daemon
->namebuff
, "class=%u", opt6_uint(opt
, 0, 2));
1929 else if (type
== OPTION6_STATUS_CODE
)
1931 int len
= sprintf(daemon
->namebuff
, "%u ", opt6_uint(opt
, 0, 2));
1932 memcpy(daemon
->namebuff
+ len
, opt6_ptr(opt
, 2), opt6_len(opt
)-2);
1933 daemon
->namebuff
[len
+ opt6_len(opt
) - 2] = 0;
1938 /* account for flag byte on FQDN */
1939 int offset
= type
== OPTION6_FQDN
? 1 : 0;
1940 optname
= option_string(AF_INET6
, type
, opt6_ptr(opt
, offset
), opt6_len(opt
) - offset
, daemon
->namebuff
, MAXDNAME
);
1943 my_syslog(MS_DHCP
| LOG_INFO
, "%u %s size:%3d option:%3d %s %s",
1944 xid
, desc
, opt6_len(opt
), type
, optname
, daemon
->namebuff
);
1947 log6_opts(1, xid
, ia_options
, opt6_ptr(opt
, opt6_len(opt
)));
1951 static void log6_quiet(struct state
*state
, char *type
, struct in6_addr
*addr
, char *string
)
1953 if (option_bool(OPT_LOG_OPTS
) || !option_bool(OPT_QUIET_DHCP6
))
1954 log6_packet(state
, type
, addr
, string
);
1957 static void log6_packet(struct state
*state
, char *type
, struct in6_addr
*addr
, char *string
)
1959 int clid_len
= state
->clid_len
;
1961 /* avoid buffer overflow */
1965 print_mac(daemon
->namebuff
, state
->clid
, clid_len
);
1969 inet_ntop(AF_INET6
, addr
, daemon
->dhcp_buff2
, 255);
1970 strcat(daemon
->dhcp_buff2
, " ");
1973 daemon
->dhcp_buff2
[0] = 0;
1975 if(option_bool(OPT_LOG_OPTS
))
1976 my_syslog(MS_DHCP
| LOG_INFO
, "%u %s(%s) %s%s %s",
1982 string
? string
: "");
1984 my_syslog(MS_DHCP
| LOG_INFO
, "%s(%s) %s%s %s",
1989 string
? string
: "");
1992 static void *opt6_find (void *opts
, void *end
, unsigned int search
, unsigned int minsize
)
2006 GETSHORT(opt
, opts
);
2007 GETSHORT(opt_len
, opts
);
2009 if (opt_len
> (end
- opts
))
2012 if (opt
== search
&& (opt_len
>= minsize
))
2019 static void *opt6_next(void *opts
, void *end
)
2027 GETSHORT(opt_len
, opts
);
2029 if (opt_len
>= (end
- opts
))
2032 return opts
+ opt_len
;
2035 static unsigned int opt6_uint(unsigned char *opt
, int offset
, int size
)
2037 /* this worries about unaligned data and byte order */
2038 unsigned int ret
= 0;
2040 unsigned char *p
= opt6_ptr(opt
, offset
);
2042 for (i
= 0; i
< size
; i
++)
2043 ret
= (ret
<< 8) | *p
++;
2048 void relay_upstream6(struct dhcp_relay
*relay
, ssize_t sz
, struct in6_addr
*peer_address
, u32 scope_id
)
2050 /* ->local is same value for all relays on ->current chain */
2052 struct all_addr from
;
2053 unsigned char *header
;
2054 unsigned char *inbuff
= daemon
->dhcp_packet
.iov_base
;
2055 int msg_type
= *inbuff
;
2057 struct in6_addr multicast
;
2058 unsigned int maclen
, mactype
;
2059 unsigned char mac
[DHCP_CHADDR_MAX
];
2061 inet_pton(AF_INET6
, ALL_SERVERS
, &multicast
);
2062 get_client_mac(peer_address
, scope_id
, mac
, &maclen
, &mactype
);
2064 /* source address == relay address */
2065 from
.addr
.addr6
= relay
->local
.addr
.addr6
;
2067 /* Get hop count from nested relayed message */
2068 if (msg_type
== DHCP6RELAYFORW
)
2069 hopcount
= *((unsigned char *)inbuff
+1) + 1;
2073 /* RFC 3315 HOP_COUNT_LIMIT */
2079 if ((header
= put_opt6(NULL
, 34)))
2083 header
[0] = DHCP6RELAYFORW
;
2084 header
[1] = hopcount
;
2085 memcpy(&header
[2], &relay
->local
.addr
.addr6
, IN6ADDRSZ
);
2086 memcpy(&header
[18], peer_address
, IN6ADDRSZ
);
2091 o
= new_opt6(OPTION6_CLIENT_MAC
);
2092 put_opt6_short(mactype
);
2093 put_opt6(mac
, maclen
);
2097 o
= new_opt6(OPTION6_RELAY_MSG
);
2098 put_opt6(inbuff
, sz
);
2101 for (; relay
; relay
= relay
->current
)
2103 union mysockaddr to
;
2105 to
.sa
.sa_family
= AF_INET6
;
2106 to
.in6
.sin6_addr
= relay
->server
.addr
.addr6
;
2107 to
.in6
.sin6_port
= htons(DHCPV6_SERVER_PORT
);
2108 to
.in6
.sin6_flowinfo
= 0;
2109 to
.in6
.sin6_scope_id
= 0;
2111 if (IN6_ARE_ADDR_EQUAL(&relay
->server
.addr
.addr6
, &multicast
))
2113 int multicast_iface
;
2114 if (!relay
->interface
|| strchr(relay
->interface
, '*') ||
2115 (multicast_iface
= if_nametoindex(relay
->interface
)) == 0 ||
2116 setsockopt(daemon
->dhcp6fd
, IPPROTO_IPV6
, IPV6_MULTICAST_IF
, &multicast_iface
, sizeof(multicast_iface
)) == -1)
2117 my_syslog(MS_DHCP
| LOG_ERR
, _("Cannot multicast to DHCPv6 server without correct interface"));
2120 send_from(daemon
->dhcp6fd
, 0, daemon
->outpacket
.iov_base
, save_counter(0), &to
, &from
, 0);
2122 if (option_bool(OPT_LOG_OPTS
))
2124 inet_ntop(AF_INET6
, &relay
->local
, daemon
->addrbuff
, ADDRSTRLEN
);
2125 inet_ntop(AF_INET6
, &relay
->server
, daemon
->namebuff
, ADDRSTRLEN
);
2126 my_syslog(MS_DHCP
| LOG_INFO
, _("DHCP relay %s -> %s"), daemon
->addrbuff
, daemon
->namebuff
);
2129 /* Save this for replies */
2130 relay
->iface_index
= scope_id
;
2135 unsigned short relay_reply6(struct sockaddr_in6
*peer
, ssize_t sz
, char *arrival_interface
)
2137 struct dhcp_relay
*relay
;
2138 struct in6_addr link
;
2139 unsigned char *inbuff
= daemon
->dhcp_packet
.iov_base
;
2141 /* must have at least msg_type+hopcount+link_address+peer_address+minimal size option
2142 which is 1 + 1 + 16 + 16 + 2 + 2 = 38 */
2144 if (sz
< 38 || *inbuff
!= DHCP6RELAYREPL
)
2147 memcpy(&link
, &inbuff
[2], IN6ADDRSZ
);
2149 for (relay
= daemon
->relay6
; relay
; relay
= relay
->next
)
2150 if (IN6_ARE_ADDR_EQUAL(&link
, &relay
->local
.addr
.addr6
) &&
2151 (!relay
->interface
|| wildcard_match(relay
->interface
, arrival_interface
)))
2158 void *opt
, *opts
= inbuff
+ 34;
2159 void *end
= inbuff
+ sz
;
2160 for (opt
= opts
; opt
; opt
= opt6_next(opt
, end
))
2161 if (opt6_type(opt
) == OPTION6_RELAY_MSG
&& opt6_len(opt
) > 0)
2163 int encap_type
= *((unsigned char *)opt6_ptr(opt
, 0));
2164 put_opt6(opt6_ptr(opt
, 0), opt6_len(opt
));
2165 memcpy(&peer
->sin6_addr
, &inbuff
[18], IN6ADDRSZ
);
2166 peer
->sin6_scope_id
= relay
->iface_index
;
2167 return encap_type
== DHCP6RELAYREPL
? DHCPV6_SERVER_PORT
: DHCPV6_CLIENT_PORT
;