dnsmasq 2.72+ up to December 9 2014
[tomato.git] / release / src / router / dnsmasq / src / rfc3315.c
blobddb390bf11360081c5ea7d577f34df343f15fe72
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/>.
18 #include "dnsmasq.h"
20 #ifdef HAVE_DHCP6
22 struct state {
23 unsigned char *clid;
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;
29 char *iface_name;
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;
36 #endif
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);
54 #endif
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;
80 int msg_type;
81 struct state state;
83 if (sz <= 4)
84 return 0;
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;
92 save_counter(0);
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;
99 state.mac_len = 0;
100 state.tags = NULL;
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;
107 return 0;
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;
118 void *opt;
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);
134 else
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;
150 state->context = c;
153 if (!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"),
158 daemon->addrbuff);
159 return 0;
163 if (!state->context)
165 my_syslog(MS_DHCP | LOG_WARNING,
166 _("no address range available for DHCPv6 request via %s"), state->iface_name);
167 return 0;
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 */
175 if (sz < 38)
176 return 0;
178 /* copy header stuff into reply message and set type to reply */
179 if (!(outmsgtypep = put_opt6(inbuff, 34)))
180 return 0;
181 *outmsgtypep = DHCP6RELAYREPL;
183 /* look for relay options and set tags if found. */
184 for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
186 int mopt;
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;
192 else
193 continue;
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;
202 break;
206 /* RFC-6939 */
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))
226 return 0;
228 else if (opt6_type(opt) != OPTION6_CLIENT_MAC)
229 put_opt6(opt6_ptr(opt, 0), opt6_len(opt));
230 end_opt6(o);
233 return 1;
236 static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_t sz, int is_unicast, time_t now)
238 void *opt;
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;
252 #endif
254 state->packet_options = inbuff + 4;
255 state->end = inbuff + sz;
256 state->clid = NULL;
257 state->clid_len = 0;
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;
268 #endif
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)))
282 return 0;
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);
299 else
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);
311 end_opt6(o);
313 else if (msg_type != DHCP6IREQ)
314 return 0;
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))
321 return 0;
323 o = new_opt6(OPTION6_SERVER_ID);
324 put_opt6(daemon->duid, daemon->duid_len);
325 end_opt6(o);
327 if (is_unicast &&
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");
335 end_opt6(o1);
336 return 1;
339 /* match vendor and user class options */
340 for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
342 int mopt;
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;
348 else
349 continue;
351 if ((opt = opt6_find(state->packet_options, state->end, mopt, 2)))
353 void *enc_opt, *enc_end = opt6_ptr(opt, opt6_len(opt));
354 int offset = 0;
356 if (mopt == OPTION6_VENDOR_CLASS)
358 if (opt6_len(opt) < 4)
359 continue;
361 if (vendor->enterprise != opt6_uint(opt, 0, 4))
362 continue;
364 offset = 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;
374 break;
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
385 V-I opts too. */
386 for (opt_cfg = daemon->dhcp_match6; opt_cfg; opt_cfg = opt_cfg->next)
388 int match = 0;
390 if (opt_cfg->flags & DHOPT_RFC3925)
392 for (opt = opt6_find(state->packet_options, state->end, OPTION6_VENDOR_OPTS, 4);
393 opt;
394 opt = opt6_find(opt6_next(opt, state->end), state->end, OPTION6_VENDOR_OPTS, 4))
396 void *vopt;
397 void *vend = opt6_ptr(opt, opt6_len(opt));
399 for (vopt = opt6_find(opt6_ptr(opt, 4), vend, opt_cfg->opt, 0);
400 vopt;
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))))
403 break;
405 if (match)
406 break;
408 else
410 if (!(opt = opt6_find(state->packet_options, state->end, opt_cfg->opt, 1)))
411 continue;
413 match = match_bytes(opt_cfg, opt6_ptr(opt, 0), opt6_len(opt));
416 if (match)
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)))
443 /* RFC4704 refers */
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;
459 pp = op;
460 while (*op != 0 && ((op + (*op)) - pp) < len)
462 memcpy(pq, op+1, *op);
463 pq += *op;
464 op += (*op)+1;
465 *(pq++) = '.';
468 if (pq != daemon->dhcp_buff)
469 pq--;
470 *pq = 0;
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);
481 if (state->clid)
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;
498 if (!config)
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)
505 config = new;
511 if (config)
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))
527 ignore = 1;
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))
534 void *oro;
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;
541 break;
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;
553 #endif
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))
564 ignore = 1;
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))
574 break;
575 if (id_list)
576 state->hostname = NULL;
580 switch (msg_type)
582 default:
583 return 0;
586 case DHCP6SOLICIT:
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);
600 end_opt6(o);
603 log6_quiet(state, "DHCPSOLICIT", NULL, ignore ? _("ignored") : NULL);
605 request_no_address:
606 solicit_tags = tagif;
608 if (ignore)
609 return 0;
611 /* reset USED bits in leases */
612 lease6_reset();
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;
622 int t1cntr;
623 int ia_counter;
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. */
626 int plain_range = 1;
627 u32 lease_time;
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))
633 continue;
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)
642 void *prefix_opt;
643 int prefix_class;
645 if (dump_all_prefix_classes)
646 /* OPTION_PREFIX_CLASS in ORO, send addresses in all prefix classes */
647 plain_range = 0;
648 else
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)
657 break;
659 if (!p)
660 my_syslog(MS_DHCP | LOG_WARNING, _("unknown prefix-class %d"), prefix_class);
661 else
663 /* add tag to list, and exclude undecorated dhcp-ranges */
664 p->tag.next = state->tags;
665 solicit_tags = run_tag_if(&p->tag);
666 plain_range = 0;
667 state->send_prefix_class = p;
670 else
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)
675 p->tag.next = NULL;
676 if (match_netid(&p->tag, solicit_tags, 1))
677 break;
680 if (p)
682 plain_range = 0;
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);
691 #endif
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))
709 req_addr = &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);
723 #endif
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;
741 else
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);
747 #endif
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 */
755 ltmp = NULL;
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 = &ltmp->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);
764 #endif
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);
779 #endif
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)
793 save_counter(o);
794 continue;
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"));
804 end_opt6(o1);
807 end_ia(t1cntr, min_time, 0);
808 end_opt6(o);
811 if (address_assigned)
813 o1 = new_opt6(OPTION6_STATUS_CODE);
814 put_opt6_short(DHCP6SUCCESS);
815 put_opt6_string(_("success"));
816 end_opt6(o1);
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);
822 end_opt6(o);
823 tagif = add_options(state, 0);
825 else
827 /* no address, return error */
828 o1 = new_opt6(OPTION6_STATUS_CODE);
829 put_opt6_short(DHCP6NOADDRS);
830 put_opt6_string(_("no addresses available"));
831 end_opt6(o1);
832 log6_packet(state, state->lease_allocate ? "DHCPREPLY" : "DHCPADVERTISE", NULL, _("no addresses available"));
835 break;
838 case DHCP6REQUEST:
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);
849 if (ignore)
850 return 0;
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;
856 int t1cntr;
858 if (!check_ia(state, opt, &ia_end, &ia_option))
859 continue;
861 if (!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. */
865 save_counter(start);
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;
877 int config_ok = 0;
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"));
890 end_opt6(o1);
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"));
898 end_opt6(o1);
900 else
902 if (!dynamic)
903 dynamic = c;
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);
913 #endif
914 add_address(state, dynamic, lease_time, ia_option, &min_time, req_addr, now);
915 get_context_tag(state, dynamic);
916 address_assigned = 1;
919 else
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"));
925 end_opt6(o1);
929 end_ia(t1cntr, min_time, 0);
930 end_opt6(o);
933 if (address_assigned)
935 o1 = new_opt6(OPTION6_STATUS_CODE);
936 put_opt6_short(DHCP6SUCCESS);
937 put_opt6_string(_("success"));
938 end_opt6(o1);
940 else
942 /* no address, return error */
943 o1 = new_opt6(OPTION6_STATUS_CODE);
944 put_opt6_short(DHCP6NOADDRS);
945 put_opt6_string(_("no addresses available"));
946 end_opt6(o1);
947 log6_packet(state, "DHCPREPLY", NULL, _("no addresses available"));
950 tagif = add_options(state, 0);
951 break;
955 case DHCP6RENEW:
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;
966 int t1cntr, iacntr;
968 if (!check_ia(state, opt, &ia_end, &ia_option))
969 continue;
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);
991 t1cntr = 0;
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"));
998 end_opt6(o1);
1000 preferred_time = valid_time = 0;
1001 break;
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;
1015 else
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");
1037 else
1039 preferred_time = valid_time = 0;
1040 message = _("address invalid");
1043 if (message)
1044 log6_packet(state, "DHCPREPLY", req_addr, message);
1045 else
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);
1052 end_opt6(o1);
1055 end_ia(t1cntr, min_time, 1);
1056 end_opt6(o);
1059 tagif = add_options(state, 0);
1060 break;
1064 case DHCP6CONFIRM:
1066 int good_addr = 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);
1078 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"));
1088 end_opt6(o1);
1089 return 1;
1092 good_addr = 1;
1093 log6_quiet(state, "DHCPREPLY", req_addr, state->hostname);
1097 /* No addresses, no reply: RFC 3315 18.2.2 */
1098 if (!good_addr)
1099 return 0;
1101 o1 = new_opt6(OPTION6_STATUS_CODE);
1102 put_opt6_short(DHCP6SUCCESS );
1103 put_opt6_string(_("all addresses still on link"));
1104 end_opt6(o1);
1105 break;
1108 case DHCP6IREQ:
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;
1123 else
1124 state->send_domain = get_domain6(NULL);
1126 log6_quiet(state, "DHCPINFORMATION-REQUEST", NULL, ignore ? _("ignored") : state->hostname);
1127 if (ignore)
1128 return 0;
1129 *outmsgtypep = DHCP6REPLY;
1130 tagif = add_options(state, 1);
1131 break;
1135 case DHCP6RELEASE:
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;
1145 int made_ia = 0;
1147 for (check_ia(state, opt, &ia_end, &ia_option);
1148 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);
1156 else
1158 if (!made_ia)
1160 o = new_opt6(state->ia_type);
1161 put_opt6_long(state->iaid);
1162 if (state->ia_type == OPTION6_IA_NA)
1164 put_opt6_long(0);
1165 put_opt6_long(0);
1167 made_ia = 1;
1170 o1 = new_opt6(OPTION6_IAADDR);
1171 put_opt6(opt6_ptr(ia_option, 0), IN6ADDRSZ);
1172 put_opt6_long(0);
1173 put_opt6_long(0);
1174 end_opt6(o1);
1178 if (made_ia)
1180 o1 = new_opt6(OPTION6_STATUS_CODE);
1181 put_opt6_short(DHCP6NOBINDING);
1182 put_opt6_string(_("no binding found"));
1183 end_opt6(o1);
1185 end_opt6(o);
1189 o1 = new_opt6(OPTION6_STATUS_CODE);
1190 put_opt6_short(DHCP6SUCCESS);
1191 put_opt6_string(_("release received"));
1192 end_opt6(o1);
1194 break;
1197 case DHCP6DECLINE:
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;
1207 int made_ia = 0;
1209 for (check_ia(state, opt, &ia_end, &ia_option);
1210 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;
1225 else
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);
1233 else
1235 if (!made_ia)
1237 o = new_opt6(state->ia_type);
1238 put_opt6_long(state->iaid);
1239 if (state->ia_type == OPTION6_IA_NA)
1241 put_opt6_long(0);
1242 put_opt6_long(0);
1244 made_ia = 1;
1247 o1 = new_opt6(OPTION6_IAADDR);
1248 put_opt6(opt6_ptr(ia_option, 0), IN6ADDRSZ);
1249 put_opt6_long(0);
1250 put_opt6_long(0);
1251 end_opt6(o1);
1255 if (made_ia)
1257 o1 = new_opt6(OPTION6_STATUS_CODE);
1258 put_opt6_short(DHCP6NOBINDING);
1259 put_opt6_string(_("no binding found"));
1260 end_opt6(o1);
1262 end_opt6(o);
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"));
1271 end_opt6(o1);
1272 break;
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));
1280 return 1;
1284 static struct dhcp_netid *add_options(struct state *state, int do_refresh)
1286 void *oro;
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;
1291 int i, o, o1;
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))
1299 continue;
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)
1305 break;
1307 /* option not requested */
1308 if (i >= opt6_len(oro) - 1)
1309 continue;
1312 if (opt_cfg->opt == OPTION6_REFRESH_TIME)
1313 done_refresh = 1;
1315 if (opt_cfg->flags & DHOPT_ADDR6)
1317 int len, j;
1318 struct in6_addr *a;
1320 if (opt_cfg->opt == OPTION6_DNS_SERVER)
1321 done_dns = 1;
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)))
1327 len -= IN6ADDRSZ;
1329 if (len != 0)
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);
1351 else
1352 put_opt6(a, IN6ADDRSZ);
1355 end_opt6(o);
1358 else
1360 o = new_opt6(opt_cfg->opt);
1361 if (opt_cfg->val)
1362 put_opt6(opt_cfg->val, opt_cfg->len);
1363 end_opt6(o);
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);
1372 end_opt6(o);
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)
1387 lease_time = 600;
1388 else
1389 lease_time = c->lease_time;
1392 o = new_opt6(OPTION6_REFRESH_TIME);
1393 put_opt6_long(lease_time);
1394 end_opt6(o);
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;
1402 if (oro)
1403 for (i = 0; i < opt6_len(oro) - 1; i += 2)
1404 if (opt6_uint(oro, i, 2) == OPTION6_VENDOR_OPTS)
1405 do_encap = 1;
1407 for (opt_cfg = daemon->dhcp_opts6; opt_cfg; opt_cfg = opt_cfg->next)
1409 if (opt_cfg->flags & DHOPT_RFC3925)
1411 int found = 0;
1412 struct dhcp_opt *oc;
1414 if (opt_cfg->flags & DHOPT_ENCAP_DONE)
1415 continue;
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)
1422 continue;
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;
1431 found = 1;
1436 if (found)
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);
1446 end_opt6(o1);
1448 end_opt6(o);
1454 if (state->hostname)
1456 unsigned char *p;
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);
1470 *p = 0;
1473 end_opt6(o);
1477 /* logging */
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),
1485 "%d%s%s%s",
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);
1498 return tagif;
1501 static int add_local_addrs(struct dhcp_context *context)
1503 int done = 0;
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))
1513 break;
1515 if (!c)
1517 done = 1;
1518 put_opt6(&context->local6, IN6ADDRSZ);
1522 return done;
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))
1539 break;
1540 if (id_list)
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)
1555 return p;
1557 return NULL;
1559 #endif
1561 static int check_ia(struct state *state, void *opt, void **endp, void **ia_option)
1563 state->ia_type = opt6_type(opt);
1564 *ia_option = NULL;
1566 if (state->ia_type != OPTION6_IA_NA && state->ia_type != OPTION6_IA_TA)
1567 return 0;
1569 if (state->ia_type == OPTION6_IA_NA && opt6_len(opt) < 12)
1570 return 0;
1572 if (state->ia_type == OPTION6_IA_TA && opt6_len(opt) < 4)
1573 return 0;
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);
1579 return 1;
1583 static int build_ia(struct state *state, int *t1cntr)
1585 int o = new_opt6(state->ia_type);
1587 put_opt6_long(state->iaid);
1588 *t1cntr = 0;
1590 if (state->ia_type == OPTION6_IA_NA)
1592 /* save pointer */
1593 *t1cntr = save_counter(-1);
1594 /* so we can fill these in later */
1595 put_opt6_long(0);
1596 put_opt6_long(0);
1599 return o;
1602 static void end_ia(int t1cntr, unsigned int min_time, int do_fuzz)
1604 if (t1cntr != 0)
1606 /* go back an fill in fields in IA_NA option */
1607 int sav = save_counter(t1cntr);
1608 unsigned int t1, t2, fuzz = 0;
1610 if (do_fuzz)
1612 fuzz = rand16();
1614 while (fuzz > (min_time/16))
1615 fuzz = fuzz/2;
1618 t1 = (min_time == 0xffffffff) ? 0xffffffff : min_time/2 - fuzz;
1619 t2 = (min_time == 0xffffffff) ? 0xffffffff : ((min_time/8)*7) - fuzz;
1620 put_opt6_long(t1);
1621 put_opt6_long(t2);
1622 save_counter(sav);
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 */
1634 if (ia_option)
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);
1651 end_opt6(o1);
1653 #endif
1655 end_opt6(o);
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))
1675 break;
1676 if (id_list)
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;
1695 #else
1696 for (context = state->context; context; context = context->current)
1697 if (is_same_net6(addr, &context->start6, context->prefix))
1698 context->flags |= CONTEXT_USED;
1699 #endif
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)))
1715 return 1;
1717 if (lease->clid_len != state->clid_len ||
1718 memcmp(lease->clid, state->clid, state->clid_len) != 0 ||
1719 lease->iaid != state->iaid)
1720 return 0;
1722 return 1;
1726 /* Calculate valid and preferred times to send in leases/renewals.
1728 Inputs are:
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.
1736 Outputs are :
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
1750 lifetime. */
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;
1763 if (req_valid != 0)
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
1775 is deprecated */
1776 if ((context->flags & CONTEXT_DEPRECATE) || context->preferred == 0)
1777 preferred_time = 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);
1792 #ifdef HAVE_SCRIPT
1793 struct dhcp_netid *tagif = run_tag_if(state->tags);
1794 #endif
1796 (void)context;
1798 if (!lease)
1799 lease = lease6_allocate(addr, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA);
1801 if (lease)
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);
1815 #ifdef HAVE_SCRIPT
1816 if (daemon->lease_change_command)
1818 void *class_opt;
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);
1847 else
1849 if (context->netid.net)
1850 lease_add_extradata(lease, (unsigned char *)context->netid.net, strlen(context->netid.net), tagif ? ' ' : 0);
1852 if (tagif)
1854 struct dhcp_netid *n;
1855 for (n = tagif; n; n = n->next)
1857 struct dhcp_netid *n1;
1858 /* kill dupes */
1859 for (n1 = n->next; n1; n1 = n1->next)
1860 if (strcmp(n->net, n1->net) == 0)
1861 break;
1862 if (!n1)
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);
1880 #endif
1887 static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_opts)
1889 void *opt;
1890 char *desc = nest ? "nest" : "sent";
1892 if (!option_bool(OPT_LOG_OPTS) || start_opts == end_opts)
1893 return;
1895 for (opt = start_opts; opt; opt = opt6_next(opt, end_opts))
1897 int type = opt6_type(opt);
1898 void *ia_options = NULL;
1899 char *optname;
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));
1905 optname = "ia-na";
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));
1911 optname = "ia-ta";
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));
1919 optname = "iaaddr";
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));
1928 #endif
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;
1934 optname = "status";
1936 else
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);
1946 if (ia_options)
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 */
1962 if (clid_len > 100)
1963 clid_len = 100;
1965 print_mac(daemon->namebuff, state->clid, clid_len);
1967 if (addr)
1969 inet_ntop(AF_INET6, addr, daemon->dhcp_buff2, 255);
1970 strcat(daemon->dhcp_buff2, " ");
1972 else
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",
1977 state->xid,
1978 type,
1979 state->iface_name,
1980 daemon->dhcp_buff2,
1981 daemon->namebuff,
1982 string ? string : "");
1983 else
1984 my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s%s %s",
1985 type,
1986 state->iface_name,
1987 daemon->dhcp_buff2,
1988 daemon->namebuff,
1989 string ? string : "");
1992 static void *opt6_find (void *opts, void *end, unsigned int search, unsigned int minsize)
1994 u16 opt, opt_len;
1995 void *start;
1997 if (!opts)
1998 return NULL;
2000 while (1)
2002 if (end - opts < 4)
2003 return NULL;
2005 start = opts;
2006 GETSHORT(opt, opts);
2007 GETSHORT(opt_len, opts);
2009 if (opt_len > (end - opts))
2010 return NULL;
2012 if (opt == search && (opt_len >= minsize))
2013 return start;
2015 opts += opt_len;
2019 static void *opt6_next(void *opts, void *end)
2021 u16 opt_len;
2023 if (end - opts < 4)
2024 return NULL;
2026 opts += 2;
2027 GETSHORT(opt_len, opts);
2029 if (opt_len >= (end - opts))
2030 return NULL;
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;
2039 int i;
2040 unsigned char *p = opt6_ptr(opt, offset);
2042 for (i = 0; i < size; i++)
2043 ret = (ret << 8) | *p++;
2045 return ret;
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;
2056 int hopcount;
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;
2070 else
2071 hopcount = 0;
2073 /* RFC 3315 HOP_COUNT_LIMIT */
2074 if (hopcount > 32)
2075 return;
2077 save_counter(0);
2079 if ((header = put_opt6(NULL, 34)))
2081 int o;
2083 header[0] = DHCP6RELAYFORW;
2084 header[1] = hopcount;
2085 memcpy(&header[2], &relay->local.addr.addr6, IN6ADDRSZ);
2086 memcpy(&header[18], peer_address, IN6ADDRSZ);
2088 /* RFC-6939 */
2089 if (maclen != 0)
2091 o = new_opt6(OPTION6_CLIENT_MAC);
2092 put_opt6_short(mactype);
2093 put_opt6(mac, maclen);
2094 end_opt6(o);
2097 o = new_opt6(OPTION6_RELAY_MSG);
2098 put_opt6(inbuff, sz);
2099 end_opt6(o);
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)
2145 return 0;
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)))
2152 break;
2154 save_counter(0);
2156 if (relay)
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;
2171 return 0;
2174 #endif