blob: 5c2ff97bf278c2b552edb4f6dfbdcb75297705af [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
2
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.
7
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.
12
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/>.
15*/
16
17
18#include "dnsmasq.h"
19
20#ifdef HAVE_DHCP6
21
22struct state {
23 unsigned char *clid;
24 int clid_len, 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, iaid;
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};
35
36static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
37 struct in6_addr *client_addr, int is_unicast, time_t now);
38static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_t sz, int is_unicast, time_t now);
39static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_opts);
40static void log6_packet(struct state *state, char *type, struct in6_addr *addr, char *string);
41static void log6_quiet(struct state *state, char *type, struct in6_addr *addr, char *string);
42static void *opt6_find (void *opts, void *end, unsigned int search, unsigned int minsize);
43static void *opt6_next(void *opts, void *end);
44static unsigned int opt6_uint(unsigned char *opt, int offset, int size);
45static void get_context_tag(struct state *state, struct dhcp_context *context);
46static int check_ia(struct state *state, void *opt, void **endp, void **ia_option);
47static int build_ia(struct state *state, int *t1cntr);
48static void end_ia(int t1cntr, unsigned int min_time, int do_fuzz);
49static void mark_context_used(struct state *state, struct in6_addr *addr);
50static void mark_config_used(struct dhcp_context *context, struct in6_addr *addr);
51static int check_address(struct state *state, struct in6_addr *addr);
52static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state, time_t now);
53static struct addrlist *config_implies(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr);
54static void add_address(struct state *state, struct dhcp_context *context, unsigned int lease_time, void *ia_option,
55 unsigned int *min_time, struct in6_addr *addr, time_t now);
56static void update_leases(struct state *state, struct dhcp_context *context, struct in6_addr *addr, unsigned int lease_time, time_t now);
57static int add_local_addrs(struct dhcp_context *context);
58static struct dhcp_netid *add_options(struct state *state, int do_refresh);
59static void calculate_times(struct dhcp_context *context, unsigned int *min_time, unsigned int *valid_timep,
60 unsigned int *preferred_timep, unsigned int lease_time);
61
62#define opt6_len(opt) ((int)(opt6_uint(opt, -2, 2)))
63#define opt6_type(opt) (opt6_uint(opt, -4, 2))
64#define opt6_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[4+(i)]))
65
66#define opt6_user_vendor_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[2+(i)]))
67#define opt6_user_vendor_len(opt) ((int)(opt6_uint(opt, -4, 2)))
68#define opt6_user_vendor_next(opt, end) (opt6_next(((void *) opt) - 2, end))
69
70
71unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name,
72 struct in6_addr *fallback, struct in6_addr *ll_addr, struct in6_addr *ula_addr,
73 size_t sz, struct in6_addr *client_addr, time_t now)
74{
75 struct dhcp_vendor *vendor;
76 int msg_type;
77 struct state state;
78
79 if (sz <= 4)
80 return 0;
81
82 msg_type = *((unsigned char *)daemon->dhcp_packet.iov_base);
83
84 /* Mark these so we only match each at most once, to avoid tangled linked lists */
85 for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
86 vendor->netid.next = &vendor->netid;
87
88 reset_counter();
89 state.context = context;
90 state.interface = interface;
91 state.iface_name = iface_name;
92 state.fallback = fallback;
93 state.ll_addr = ll_addr;
94 state.ula_addr = ula_addr;
95 state.mac_len = 0;
96 state.tags = NULL;
97 state.link_address = NULL;
98
99 if (dhcp6_maybe_relay(&state, daemon->dhcp_packet.iov_base, sz, client_addr,
100 IN6_IS_ADDR_MULTICAST(client_addr), now))
101 return msg_type == DHCP6RELAYFORW ? DHCPV6_SERVER_PORT : DHCPV6_CLIENT_PORT;
102
103 return 0;
104}
105
106/* This cost me blood to write, it will probably cost you blood to understand - srk. */
107static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
108 struct in6_addr *client_addr, int is_unicast, time_t now)
109{
110 void *end = inbuff + sz;
111 void *opts = inbuff + 34;
112 int msg_type = *((unsigned char *)inbuff);
113 unsigned char *outmsgtypep;
114 void *opt;
115 struct dhcp_vendor *vendor;
116
117 /* if not an encapsulated relayed message, just do the stuff */
118 if (msg_type != DHCP6RELAYFORW)
119 {
120 /* if link_address != NULL if points to the link address field of the
121 innermost nested RELAYFORW message, which is where we find the
122 address of the network on which we can allocate an address.
123 Recalculate the available contexts using that information.
124
125 link_address == NULL means there's no relay in use, so we try and find the client's
126 MAC address from the local ND cache. */
127
128 if (!state->link_address)
129 get_client_mac(client_addr, state->interface, state->mac, &state->mac_len, &state->mac_type, now);
130 else
131 {
132 struct dhcp_context *c;
133 struct shared_network *share = NULL;
134 state->context = NULL;
135
136 if (!IN6_IS_ADDR_LOOPBACK(state->link_address) &&
137 !IN6_IS_ADDR_LINKLOCAL(state->link_address) &&
138 !IN6_IS_ADDR_MULTICAST(state->link_address))
139 for (c = daemon->dhcp6; c; c = c->next)
140 {
141 for (share = daemon->shared_networks; share; share = share->next)
142 {
143 if (share->shared_addr.s_addr != 0)
144 continue;
145
146 if (share->if_index != 0 ||
147 !IN6_ARE_ADDR_EQUAL(state->link_address, &share->match_addr6))
148 continue;
149
150 if ((c->flags & CONTEXT_DHCP) &&
151 !(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
152 is_same_net6(&share->shared_addr6, &c->start6, c->prefix) &&
153 is_same_net6(&share->shared_addr6, &c->end6, c->prefix))
154 break;
155 }
156
157 if (share ||
158 ((c->flags & CONTEXT_DHCP) &&
159 !(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
160 is_same_net6(state->link_address, &c->start6, c->prefix) &&
161 is_same_net6(state->link_address, &c->end6, c->prefix)))
162 {
163 c->preferred = c->valid = 0xffffffff;
164 c->current = state->context;
165 state->context = c;
166 }
167 }
168
169 if (!state->context)
170 {
171 inet_ntop(AF_INET6, state->link_address, daemon->addrbuff, ADDRSTRLEN);
172 my_syslog(MS_DHCP | LOG_WARNING,
173 _("no address range available for DHCPv6 request from relay at %s"),
174 daemon->addrbuff);
175 return 0;
176 }
177 }
178
179 if (!state->context)
180 {
181 my_syslog(MS_DHCP | LOG_WARNING,
182 _("no address range available for DHCPv6 request via %s"), state->iface_name);
183 return 0;
184 }
185
186 return dhcp6_no_relay(state, msg_type, inbuff, sz, is_unicast, now);
187 }
188
189 /* must have at least msg_type+hopcount+link_address+peer_address+minimal size option
190 which is 1 + 1 + 16 + 16 + 2 + 2 = 38 */
191 if (sz < 38)
192 return 0;
193
194 /* copy header stuff into reply message and set type to reply */
195 if (!(outmsgtypep = put_opt6(inbuff, 34)))
196 return 0;
197 *outmsgtypep = DHCP6RELAYREPL;
198
199 /* look for relay options and set tags if found. */
200 for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
201 {
202 int mopt;
203
204 if (vendor->match_type == MATCH_SUBSCRIBER)
205 mopt = OPTION6_SUBSCRIBER_ID;
206 else if (vendor->match_type == MATCH_REMOTE)
207 mopt = OPTION6_REMOTE_ID;
208 else
209 continue;
210
211 if ((opt = opt6_find(opts, end, mopt, 1)) &&
212 vendor->len == opt6_len(opt) &&
213 memcmp(vendor->data, opt6_ptr(opt, 0), vendor->len) == 0 &&
214 vendor->netid.next != &vendor->netid)
215 {
216 vendor->netid.next = state->tags;
217 state->tags = &vendor->netid;
218 break;
219 }
220 }
221
222 /* RFC-6939 */
223 if ((opt = opt6_find(opts, end, OPTION6_CLIENT_MAC, 3)))
224 {
225 if (opt6_len(opt) - 2 > DHCP_CHADDR_MAX) {
226 return 0;
227 }
228 state->mac_type = opt6_uint(opt, 0, 2);
229 state->mac_len = opt6_len(opt) - 2;
230 memcpy(&state->mac[0], opt6_ptr(opt, 2), state->mac_len);
231 }
232
233 for (opt = opts; opt; opt = opt6_next(opt, end))
234 {
235 if (opt6_ptr(opt, 0) + opt6_len(opt) > end)
236 return 0;
237
238 /* Don't copy MAC address into reply. */
239 if (opt6_type(opt) != OPTION6_CLIENT_MAC)
240 {
241 int o = new_opt6(opt6_type(opt));
242 if (opt6_type(opt) == OPTION6_RELAY_MSG)
243 {
244 struct in6_addr align;
245 /* the packet data is unaligned, copy to aligned storage */
246 memcpy(&align, inbuff + 2, IN6ADDRSZ);
247 state->link_address = &align;
248 /* zero is_unicast since that is now known to refer to the
249 relayed packet, not the original sent by the client */
250 if (!dhcp6_maybe_relay(state, opt6_ptr(opt, 0), opt6_len(opt), client_addr, 0, now))
251 return 0;
252 }
253 else
254 put_opt6(opt6_ptr(opt, 0), opt6_len(opt));
255 end_opt6(o);
256 }
257 }
258
259 return 1;
260}
261
262static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_t sz, int is_unicast, time_t now)
263{
264 void *opt;
265 int i, o, o1, start_opts;
266 struct dhcp_opt *opt_cfg;
267 struct dhcp_netid *tagif;
268 struct dhcp_config *config = NULL;
269 struct dhcp_netid known_id, iface_id, v6_id;
270 unsigned char *outmsgtypep;
271 struct dhcp_vendor *vendor;
272 struct dhcp_context *context_tmp;
273 struct dhcp_mac *mac_opt;
274 unsigned int ignore = 0;
275
276 state->packet_options = inbuff + 4;
277 state->end = inbuff + sz;
278 state->clid = NULL;
279 state->clid_len = 0;
280 state->lease_allocate = 0;
281 state->context_tags = NULL;
282 state->domain = NULL;
283 state->send_domain = NULL;
284 state->hostname_auth = 0;
285 state->hostname = NULL;
286 state->client_hostname = NULL;
287 state->fqdn_flags = 0x01; /* default to send if we receive no FQDN option */
288
289 /* set tag with name == interface */
290 iface_id.net = state->iface_name;
291 iface_id.next = state->tags;
292 state->tags = &iface_id;
293
294 /* set tag "dhcpv6" */
295 v6_id.net = "dhcpv6";
296 v6_id.next = state->tags;
297 state->tags = &v6_id;
298
299 /* copy over transaction-id, and save pointer to message type */
300 if (!(outmsgtypep = put_opt6(inbuff, 4)))
301 return 0;
302 start_opts = save_counter(-1);
303 state->xid = outmsgtypep[3] | outmsgtypep[2] << 8 | outmsgtypep[1] << 16;
304
305 /* We're going to be linking tags from all context we use.
306 mark them as unused so we don't link one twice and break the list */
307 for (context_tmp = state->context; context_tmp; context_tmp = context_tmp->current)
308 {
309 context_tmp->netid.next = &context_tmp->netid;
310
311 if (option_bool(OPT_LOG_OPTS))
312 {
313 inet_ntop(AF_INET6, &context_tmp->start6, daemon->dhcp_buff, ADDRSTRLEN);
314 inet_ntop(AF_INET6, &context_tmp->end6, daemon->dhcp_buff2, ADDRSTRLEN);
315 if (context_tmp->flags & (CONTEXT_STATIC))
316 my_syslog(MS_DHCP | LOG_INFO, _("%u available DHCPv6 subnet: %s/%d"),
317 state->xid, daemon->dhcp_buff, context_tmp->prefix);
318 else
319 my_syslog(MS_DHCP | LOG_INFO, _("%u available DHCP range: %s -- %s"),
320 state->xid, daemon->dhcp_buff, daemon->dhcp_buff2);
321 }
322 }
323
324 if ((opt = opt6_find(state->packet_options, state->end, OPTION6_CLIENT_ID, 1)))
325 {
326 state->clid = opt6_ptr(opt, 0);
327 state->clid_len = opt6_len(opt);
328 o = new_opt6(OPTION6_CLIENT_ID);
329 put_opt6(state->clid, state->clid_len);
330 end_opt6(o);
331 }
332 else if (msg_type != DHCP6IREQ)
333 return 0;
334
335 /* server-id must match except for SOLICIT, CONFIRM and REBIND messages */
336 if (msg_type != DHCP6SOLICIT && msg_type != DHCP6CONFIRM && msg_type != DHCP6IREQ && msg_type != DHCP6REBIND &&
337 (!(opt = opt6_find(state->packet_options, state->end, OPTION6_SERVER_ID, 1)) ||
338 opt6_len(opt) != daemon->duid_len ||
339 memcmp(opt6_ptr(opt, 0), daemon->duid, daemon->duid_len) != 0))
340 return 0;
341
342 o = new_opt6(OPTION6_SERVER_ID);
343 put_opt6(daemon->duid, daemon->duid_len);
344 end_opt6(o);
345
346 if (is_unicast &&
347 (msg_type == DHCP6REQUEST || msg_type == DHCP6RENEW || msg_type == DHCP6RELEASE || msg_type == DHCP6DECLINE))
348
349 {
350 *outmsgtypep = DHCP6REPLY;
351 o1 = new_opt6(OPTION6_STATUS_CODE);
352 put_opt6_short(DHCP6USEMULTI);
353 put_opt6_string("Use multicast");
354 end_opt6(o1);
355 return 1;
356 }
357
358 /* match vendor and user class options */
359 for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
360 {
361 int mopt;
362
363 if (vendor->match_type == MATCH_VENDOR)
364 mopt = OPTION6_VENDOR_CLASS;
365 else if (vendor->match_type == MATCH_USER)
366 mopt = OPTION6_USER_CLASS;
367 else
368 continue;
369
370 if ((opt = opt6_find(state->packet_options, state->end, mopt, 2)))
371 {
372 void *enc_opt, *enc_end = opt6_ptr(opt, opt6_len(opt));
373 int offset = 0;
374
375 if (mopt == OPTION6_VENDOR_CLASS)
376 {
377 if (opt6_len(opt) < 4)
378 continue;
379
380 if (vendor->enterprise != opt6_uint(opt, 0, 4))
381 continue;
382
383 offset = 4;
384 }
385
386 /* Note that format if user/vendor classes is different to DHCP options - no option types. */
387 for (enc_opt = opt6_ptr(opt, offset); enc_opt; enc_opt = opt6_user_vendor_next(enc_opt, enc_end))
388 for (i = 0; i <= (opt6_user_vendor_len(enc_opt) - vendor->len); i++)
389 if (memcmp(vendor->data, opt6_user_vendor_ptr(enc_opt, i), vendor->len) == 0)
390 {
391 vendor->netid.next = state->tags;
392 state->tags = &vendor->netid;
393 break;
394 }
395 }
396 }
397
398 if (option_bool(OPT_LOG_OPTS) && (opt = opt6_find(state->packet_options, state->end, OPTION6_VENDOR_CLASS, 4)))
399 my_syslog(MS_DHCP | LOG_INFO, _("%u vendor class: %u"), state->xid, opt6_uint(opt, 0, 4));
400
401 /* dhcp-match. If we have hex-and-wildcards, look for a left-anchored match.
402 Otherwise assume the option is an array, and look for a matching element.
403 If no data given, existence of the option is enough. This code handles
404 V-I opts too. */
405 for (opt_cfg = daemon->dhcp_match6; opt_cfg; opt_cfg = opt_cfg->next)
406 {
407 int match = 0;
408
409 if (opt_cfg->flags & DHOPT_RFC3925)
410 {
411 for (opt = opt6_find(state->packet_options, state->end, OPTION6_VENDOR_OPTS, 4);
412 opt;
413 opt = opt6_find(opt6_next(opt, state->end), state->end, OPTION6_VENDOR_OPTS, 4))
414 {
415 void *vopt;
416 void *vend = opt6_ptr(opt, opt6_len(opt));
417
418 for (vopt = opt6_find(opt6_ptr(opt, 4), vend, opt_cfg->opt, 0);
419 vopt;
420 vopt = opt6_find(opt6_next(vopt, vend), vend, opt_cfg->opt, 0))
421 if ((match = match_bytes(opt_cfg, opt6_ptr(vopt, 0), opt6_len(vopt))))
422 break;
423 }
424 if (match)
425 break;
426 }
427 else
428 {
429 if (!(opt = opt6_find(state->packet_options, state->end, opt_cfg->opt, 1)))
430 continue;
431
432 match = match_bytes(opt_cfg, opt6_ptr(opt, 0), opt6_len(opt));
433 }
434
435 if (match)
436 {
437 opt_cfg->netid->next = state->tags;
438 state->tags = opt_cfg->netid;
439 }
440 }
441
442 if (state->mac_len != 0)
443 {
444 if (option_bool(OPT_LOG_OPTS))
445 {
446 print_mac(daemon->dhcp_buff, state->mac, state->mac_len);
447 my_syslog(MS_DHCP | LOG_INFO, _("%u client MAC address: %s"), state->xid, daemon->dhcp_buff);
448 }
449
450 for (mac_opt = daemon->dhcp_macs; mac_opt; mac_opt = mac_opt->next)
451 if ((unsigned)mac_opt->hwaddr_len == state->mac_len &&
452 ((unsigned)mac_opt->hwaddr_type == state->mac_type || mac_opt->hwaddr_type == 0) &&
453 memcmp_masked(mac_opt->hwaddr, state->mac, state->mac_len, mac_opt->mask))
454 {
455 mac_opt->netid.next = state->tags;
456 state->tags = &mac_opt->netid;
457 }
458 }
459
460 if ((opt = opt6_find(state->packet_options, state->end, OPTION6_FQDN, 1)))
461 {
462 /* RFC4704 refers */
463 int len = opt6_len(opt) - 1;
464
465 state->fqdn_flags = opt6_uint(opt, 0, 1);
466
467 /* Always force update, since the client has no way to do it itself. */
468 if (!option_bool(OPT_FQDN_UPDATE) && !(state->fqdn_flags & 0x01))
469 state->fqdn_flags |= 0x03;
470
471 state->fqdn_flags &= ~0x04;
472
473 if (len != 0 && len < 255)
474 {
475 unsigned char *pp, *op = opt6_ptr(opt, 1);
476 char *pq = daemon->dhcp_buff;
477
478 pp = op;
479 while (*op != 0 && ((op + (*op)) - pp) < len)
480 {
481 memcpy(pq, op+1, *op);
482 pq += *op;
483 op += (*op)+1;
484 *(pq++) = '.';
485 }
486
487 if (pq != daemon->dhcp_buff)
488 pq--;
489 *pq = 0;
490
491 if (legal_hostname(daemon->dhcp_buff))
492 {
493 struct dhcp_match_name *m;
494 size_t nl = strlen(daemon->dhcp_buff);
495
496 state->client_hostname = daemon->dhcp_buff;
497
498 if (option_bool(OPT_LOG_OPTS))
499 my_syslog(MS_DHCP | LOG_INFO, _("%u client provides name: %s"), state->xid, state->client_hostname);
500
501 for (m = daemon->dhcp_name_match; m; m = m->next)
502 {
503 size_t ml = strlen(m->name);
504 char save = 0;
505
506 if (nl < ml)
507 continue;
508 if (nl > ml)
509 {
510 save = state->client_hostname[ml];
511 state->client_hostname[ml] = 0;
512 }
513
514 if (hostname_isequal(state->client_hostname, m->name) &&
515 (save == 0 || m->wildcard))
516 {
517 m->netid->next = state->tags;
518 state->tags = m->netid;
519 }
520
521 if (save != 0)
522 state->client_hostname[ml] = save;
523 }
524 }
525 }
526 }
527
528 if (state->clid &&
529 (config = find_config(daemon->dhcp_conf, state->context, state->clid, state->clid_len,
530 state->mac, state->mac_len, state->mac_type, NULL, run_tag_if(state->tags))) &&
531 have_config(config, CONFIG_NAME))
532 {
533 state->hostname = config->hostname;
534 state->domain = config->domain;
535 state->hostname_auth = 1;
536 }
537 else if (state->client_hostname)
538 {
539 state->domain = strip_hostname(state->client_hostname);
540
541 if (strlen(state->client_hostname) != 0)
542 {
543 state->hostname = state->client_hostname;
544
545 if (!config)
546 {
547 /* Search again now we have a hostname.
548 Only accept configs without CLID here, (it won't match)
549 to avoid impersonation by name. */
550 struct dhcp_config *new = find_config(daemon->dhcp_conf, state->context, NULL, 0, NULL, 0, 0, state->hostname, run_tag_if(state->tags));
551 if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr)
552 config = new;
553 }
554 }
555 }
556
557 if (config)
558 {
559 struct dhcp_netid_list *list;
560
561 for (list = config->netid; list; list = list->next)
562 {
563 list->list->next = state->tags;
564 state->tags = list->list;
565 }
566
567 /* set "known" tag for known hosts */
568 known_id.net = "known";
569 known_id.next = state->tags;
570 state->tags = &known_id;
571
572 if (have_config(config, CONFIG_DISABLE))
573 ignore = 1;
574 }
575 else if (state->clid &&
576 find_config(daemon->dhcp_conf, NULL, state->clid, state->clid_len,
577 state->mac, state->mac_len, state->mac_type, NULL, run_tag_if(state->tags)))
578 {
579 known_id.net = "known-othernet";
580 known_id.next = state->tags;
581 state->tags = &known_id;
582 }
583
584 tagif = run_tag_if(state->tags);
585
586 /* if all the netids in the ignore list are present, ignore this client */
587 if (daemon->dhcp_ignore)
588 {
589 struct dhcp_netid_list *id_list;
590
591 for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
592 if (match_netid(id_list->list, tagif, 0))
593 ignore = 1;
594 }
595
596 /* if all the netids in the ignore_name list are present, ignore client-supplied name */
597 if (!state->hostname_auth)
598 {
599 struct dhcp_netid_list *id_list;
600
601 for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next)
602 if ((!id_list->list) || match_netid(id_list->list, tagif, 0))
603 break;
604 if (id_list)
605 state->hostname = NULL;
606 }
607
608
609 switch (msg_type)
610 {
611 default:
612 return 0;
613
614
615 case DHCP6SOLICIT:
616 {
617 int address_assigned = 0;
618 /* tags without all prefix-class tags */
619 struct dhcp_netid *solicit_tags;
620 struct dhcp_context *c;
621
622 *outmsgtypep = DHCP6ADVERTISE;
623
624 if (opt6_find(state->packet_options, state->end, OPTION6_RAPID_COMMIT, 0))
625 {
626 *outmsgtypep = DHCP6REPLY;
627 state->lease_allocate = 1;
628 o = new_opt6(OPTION6_RAPID_COMMIT);
629 end_opt6(o);
630 }
631
632 log6_quiet(state, "DHCPSOLICIT", NULL, ignore ? _("ignored") : NULL);
633
634 request_no_address:
635 solicit_tags = tagif;
636
637 if (ignore)
638 return 0;
639
640 /* reset USED bits in leases */
641 lease6_reset();
642
643 /* Can use configured address max once per prefix */
644 for (c = state->context; c; c = c->current)
645 c->flags &= ~CONTEXT_CONF_USED;
646
647 for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
648 {
649 void *ia_option, *ia_end;
650 unsigned int min_time = 0xffffffff;
651 int t1cntr;
652 int ia_counter;
653 /* set unless we're sending a particular prefix-class, when we
654 want only dhcp-ranges with the correct tags set and not those without any tags. */
655 int plain_range = 1;
656 u32 lease_time;
657 struct dhcp_lease *ltmp;
658 struct in6_addr req_addr, addr;
659
660 if (!check_ia(state, opt, &ia_end, &ia_option))
661 continue;
662
663 /* reset USED bits in contexts - one address per prefix per IAID */
664 for (c = state->context; c; c = c->current)
665 c->flags &= ~CONTEXT_USED;
666
667 o = build_ia(state, &t1cntr);
668 if (address_assigned)
669 address_assigned = 2;
670
671 for (ia_counter = 0; ia_option; ia_counter++, ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
672 {
673 /* worry about alignment here. */
674 memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
675
676 if ((c = address6_valid(state->context, &req_addr, solicit_tags, plain_range)))
677 {
678 lease_time = c->lease_time;
679 /* If the client asks for an address on the same network as a configured address,
680 offer the configured address instead, to make moving to newly-configured
681 addresses automatic. */
682 if (!(c->flags & CONTEXT_CONF_USED) && config_valid(config, c, &addr, state, now))
683 {
684 req_addr = addr;
685 mark_config_used(c, &addr);
686 if (have_config(config, CONFIG_TIME))
687 lease_time = config->lease_time;
688 }
689 else if (!(c = address6_available(state->context, &req_addr, solicit_tags, plain_range)))
690 continue; /* not an address we're allowed */
691 else if (!check_address(state, &req_addr))
692 continue; /* address leased elsewhere */
693
694 /* add address to output packet */
695 add_address(state, c, lease_time, ia_option, &min_time, &req_addr, now);
696 mark_context_used(state, &req_addr);
697 get_context_tag(state, c);
698 address_assigned = 1;
699 }
700 }
701
702 /* Suggest configured address(es) */
703 for (c = state->context; c; c = c->current)
704 if (!(c->flags & CONTEXT_CONF_USED) &&
705 match_netid(c->filter, solicit_tags, plain_range) &&
706 config_valid(config, c, &addr, state, now))
707 {
708 mark_config_used(state->context, &addr);
709 if (have_config(config, CONFIG_TIME))
710 lease_time = config->lease_time;
711 else
712 lease_time = c->lease_time;
713
714 /* add address to output packet */
715 add_address(state, c, lease_time, NULL, &min_time, &addr, now);
716 mark_context_used(state, &addr);
717 get_context_tag(state, c);
718 address_assigned = 1;
719 }
720
721 /* return addresses for existing leases */
722 ltmp = NULL;
723 while ((ltmp = lease6_find_by_client(ltmp, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, state->clid, state->clid_len, state->iaid)))
724 {
725 req_addr = ltmp->addr6;
726 if ((c = address6_available(state->context, &req_addr, solicit_tags, plain_range)))
727 {
728 add_address(state, c, c->lease_time, NULL, &min_time, &req_addr, now);
729 mark_context_used(state, &req_addr);
730 get_context_tag(state, c);
731 address_assigned = 1;
732 }
733 }
734
735 /* Return addresses for all valid contexts which don't yet have one */
736 while ((c = address6_allocate(state->context, state->clid, state->clid_len, state->ia_type == OPTION6_IA_TA,
737 state->iaid, ia_counter, solicit_tags, plain_range, &addr)))
738 {
739 add_address(state, c, c->lease_time, NULL, &min_time, &addr, now);
740 mark_context_used(state, &addr);
741 get_context_tag(state, c);
742 address_assigned = 1;
743 }
744
745 if (address_assigned != 1)
746 {
747 /* If the server will not assign any addresses to any IAs in a
748 subsequent Request from the client, the server MUST send an Advertise
749 message to the client that doesn't include any IA options. */
750 if (!state->lease_allocate)
751 {
752 save_counter(o);
753 continue;
754 }
755
756 /* If the server cannot assign any addresses to an IA in the message
757 from the client, the server MUST include the IA in the Reply message
758 with no addresses in the IA and a Status Code option in the IA
759 containing status code NoAddrsAvail. */
760 o1 = new_opt6(OPTION6_STATUS_CODE);
761 put_opt6_short(DHCP6NOADDRS);
762 put_opt6_string(_("address unavailable"));
763 end_opt6(o1);
764 }
765
766 end_ia(t1cntr, min_time, 0);
767 end_opt6(o);
768 }
769
770 if (address_assigned)
771 {
772 o1 = new_opt6(OPTION6_STATUS_CODE);
773 put_opt6_short(DHCP6SUCCESS);
774 put_opt6_string(_("success"));
775 end_opt6(o1);
776
777 /* If --dhcp-authoritative is set, we can tell client not to wait for
778 other possible servers */
779 o = new_opt6(OPTION6_PREFERENCE);
780 put_opt6_char(option_bool(OPT_AUTHORITATIVE) ? 255 : 0);
781 end_opt6(o);
782 tagif = add_options(state, 0);
783 }
784 else
785 {
786 /* no address, return error */
787 o1 = new_opt6(OPTION6_STATUS_CODE);
788 put_opt6_short(DHCP6NOADDRS);
789 put_opt6_string(_("no addresses available"));
790 end_opt6(o1);
791
792 /* Some clients will ask repeatedly when we're not giving
793 out addresses because we're in stateless mode. Avoid spamming
794 the log in that case. */
795 for (c = state->context; c; c = c->current)
796 if (!(c->flags & CONTEXT_RA_STATELESS))
797 {
798 log6_packet(state, state->lease_allocate ? "DHCPREPLY" : "DHCPADVERTISE", NULL, _("no addresses available"));
799 break;
800 }
801 }
802
803 break;
804 }
805
806 case DHCP6REQUEST:
807 {
808 int address_assigned = 0;
809 int start = save_counter(-1);
810
811 /* set reply message type */
812 *outmsgtypep = DHCP6REPLY;
813 state->lease_allocate = 1;
814
815 log6_quiet(state, "DHCPREQUEST", NULL, ignore ? _("ignored") : NULL);
816
817 if (ignore)
818 return 0;
819
820 for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
821 {
822 void *ia_option, *ia_end;
823 unsigned int min_time = 0xffffffff;
824 int t1cntr;
825
826 if (!check_ia(state, opt, &ia_end, &ia_option))
827 continue;
828
829 if (!ia_option)
830 {
831 /* If we get a request with an IA_*A without addresses, treat it exactly like
832 a SOLICT with rapid commit set. */
833 save_counter(start);
834 goto request_no_address;
835 }
836
837 o = build_ia(state, &t1cntr);
838
839 for (; ia_option; ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
840 {
841 struct in6_addr req_addr;
842 struct dhcp_context *dynamic, *c;
843 unsigned int lease_time;
844 int config_ok = 0;
845
846 /* align. */
847 memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
848
849 if ((c = address6_valid(state->context, &req_addr, tagif, 1)))
850 config_ok = (config_implies(config, c, &req_addr) != NULL);
851
852 if ((dynamic = address6_available(state->context, &req_addr, tagif, 1)) || c)
853 {
854 if (!dynamic && !config_ok)
855 {
856 /* Static range, not configured. */
857 o1 = new_opt6(OPTION6_STATUS_CODE);
858 put_opt6_short(DHCP6NOADDRS);
859 put_opt6_string(_("address unavailable"));
860 end_opt6(o1);
861 }
862 else if (!check_address(state, &req_addr))
863 {
864 /* Address leased to another DUID/IAID */
865 o1 = new_opt6(OPTION6_STATUS_CODE);
866 put_opt6_short(DHCP6UNSPEC);
867 put_opt6_string(_("address in use"));
868 end_opt6(o1);
869 }
870 else
871 {
872 if (!dynamic)
873 dynamic = c;
874
875 lease_time = dynamic->lease_time;
876
877 if (config_ok && have_config(config, CONFIG_TIME))
878 lease_time = config->lease_time;
879
880 add_address(state, dynamic, lease_time, ia_option, &min_time, &req_addr, now);
881 get_context_tag(state, dynamic);
882 address_assigned = 1;
883 }
884 }
885 else
886 {
887 /* requested address not on the correct link */
888 o1 = new_opt6(OPTION6_STATUS_CODE);
889 put_opt6_short(DHCP6NOTONLINK);
890 put_opt6_string(_("not on link"));
891 end_opt6(o1);
892 }
893 }
894
895 end_ia(t1cntr, min_time, 0);
896 end_opt6(o);
897 }
898
899 if (address_assigned)
900 {
901 o1 = new_opt6(OPTION6_STATUS_CODE);
902 put_opt6_short(DHCP6SUCCESS);
903 put_opt6_string(_("success"));
904 end_opt6(o1);
905 }
906 else
907 {
908 /* no address, return error */
909 o1 = new_opt6(OPTION6_STATUS_CODE);
910 put_opt6_short(DHCP6NOADDRS);
911 put_opt6_string(_("no addresses available"));
912 end_opt6(o1);
913 log6_packet(state, "DHCPREPLY", NULL, _("no addresses available"));
914 }
915
916 tagif = add_options(state, 0);
917 break;
918 }
919
920
921 case DHCP6RENEW:
922 case DHCP6REBIND:
923 {
924 int address_assigned = 0;
925
926 /* set reply message type */
927 *outmsgtypep = DHCP6REPLY;
928
929 log6_quiet(state, msg_type == DHCP6RENEW ? "DHCPRENEW" : "DHCPREBIND", NULL, NULL);
930
931 for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
932 {
933 void *ia_option, *ia_end;
934 unsigned int min_time = 0xffffffff;
935 int t1cntr, iacntr;
936
937 if (!check_ia(state, opt, &ia_end, &ia_option))
938 continue;
939
940 o = build_ia(state, &t1cntr);
941 iacntr = save_counter(-1);
942
943 for (; ia_option; ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
944 {
945 struct dhcp_lease *lease = NULL;
946 struct in6_addr req_addr;
947 unsigned int preferred_time = opt6_uint(ia_option, 16, 4);
948 unsigned int valid_time = opt6_uint(ia_option, 20, 4);
949 char *message = NULL;
950 struct dhcp_context *this_context;
951
952 memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
953
954 if (!(lease = lease6_find(state->clid, state->clid_len,
955 state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA,
956 state->iaid, &req_addr)))
957 {
958 if (msg_type == DHCP6REBIND)
959 {
960 /* When rebinding, we can create a lease if it doesn't exist. */
961 lease = lease6_allocate(&req_addr, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA);
962 if (lease)
963 lease_set_iaid(lease, state->iaid);
964 else
965 break;
966 }
967 else
968 {
969 /* If the server cannot find a client entry for the IA the server
970 returns the IA containing no addresses with a Status Code option set
971 to NoBinding in the Reply message. */
972 save_counter(iacntr);
973 t1cntr = 0;
974
975 log6_packet(state, "DHCPREPLY", &req_addr, _("lease not found"));
976
977 o1 = new_opt6(OPTION6_STATUS_CODE);
978 put_opt6_short(DHCP6NOBINDING);
979 put_opt6_string(_("no binding found"));
980 end_opt6(o1);
981
982 preferred_time = valid_time = 0;
983 break;
984 }
985 }
986
987 if ((this_context = address6_available(state->context, &req_addr, tagif, 1)) ||
988 (this_context = address6_valid(state->context, &req_addr, tagif, 1)))
989 {
990 unsigned int lease_time;
991
992 get_context_tag(state, this_context);
993
994 if (config_implies(config, this_context, &req_addr) && have_config(config, CONFIG_TIME))
995 lease_time = config->lease_time;
996 else
997 lease_time = this_context->lease_time;
998
999 calculate_times(this_context, &min_time, &valid_time, &preferred_time, lease_time);
1000
1001 lease_set_expires(lease, valid_time, now);
1002 /* Update MAC record in case it's new information. */
1003 if (state->mac_len != 0)
1004 lease_set_hwaddr(lease, state->mac, state->clid, state->mac_len, state->mac_type, state->clid_len, now, 0);
1005 if (state->ia_type == OPTION6_IA_NA && state->hostname)
1006 {
1007 char *addr_domain = get_domain6(&req_addr);
1008 if (!state->send_domain)
1009 state->send_domain = addr_domain;
1010 lease_set_hostname(lease, state->hostname, state->hostname_auth, addr_domain, state->domain);
1011 message = state->hostname;
1012 }
1013
1014
1015 if (preferred_time == 0)
1016 message = _("deprecated");
1017
1018 address_assigned = 1;
1019 }
1020 else
1021 {
1022 preferred_time = valid_time = 0;
1023 message = _("address invalid");
1024 }
1025
1026 if (message && (message != state->hostname))
1027 log6_packet(state, "DHCPREPLY", &req_addr, message);
1028 else
1029 log6_quiet(state, "DHCPREPLY", &req_addr, message);
1030
1031 o1 = new_opt6(OPTION6_IAADDR);
1032 put_opt6(&req_addr, sizeof(req_addr));
1033 put_opt6_long(preferred_time);
1034 put_opt6_long(valid_time);
1035 end_opt6(o1);
1036 }
1037
1038 end_ia(t1cntr, min_time, 1);
1039 end_opt6(o);
1040 }
1041
1042 if (!address_assigned && msg_type == DHCP6REBIND)
1043 {
1044 /* can't create lease for any address, return error */
1045 o1 = new_opt6(OPTION6_STATUS_CODE);
1046 put_opt6_short(DHCP6NOADDRS);
1047 put_opt6_string(_("no addresses available"));
1048 end_opt6(o1);
1049 }
1050
1051 tagif = add_options(state, 0);
1052 break;
1053 }
1054
1055 case DHCP6CONFIRM:
1056 {
1057 int good_addr = 0;
1058
1059 /* set reply message type */
1060 *outmsgtypep = DHCP6REPLY;
1061
1062 log6_quiet(state, "DHCPCONFIRM", NULL, NULL);
1063
1064 for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
1065 {
1066 void *ia_option, *ia_end;
1067
1068 for (check_ia(state, opt, &ia_end, &ia_option);
1069 ia_option;
1070 ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
1071 {
1072 struct in6_addr req_addr;
1073
1074 /* alignment */
1075 memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
1076
1077 if (!address6_valid(state->context, &req_addr, tagif, 1))
1078 {
1079 o1 = new_opt6(OPTION6_STATUS_CODE);
1080 put_opt6_short(DHCP6NOTONLINK);
1081 put_opt6_string(_("confirm failed"));
1082 end_opt6(o1);
1083 log6_quiet(state, "DHCPREPLY", &req_addr, _("confirm failed"));
1084 return 1;
1085 }
1086
1087 good_addr = 1;
1088 log6_quiet(state, "DHCPREPLY", &req_addr, state->hostname);
1089 }
1090 }
1091
1092 /* No addresses, no reply: RFC 3315 18.2.2 */
1093 if (!good_addr)
1094 return 0;
1095
1096 o1 = new_opt6(OPTION6_STATUS_CODE);
1097 put_opt6_short(DHCP6SUCCESS );
1098 put_opt6_string(_("all addresses still on link"));
1099 end_opt6(o1);
1100 break;
1101 }
1102
1103 case DHCP6IREQ:
1104 {
1105 /* We can't discriminate contexts based on address, as we don't know it.
1106 If there is only one possible context, we can use its tags */
1107 if (state->context && state->context->netid.net && !state->context->current)
1108 {
1109 state->context->netid.next = NULL;
1110 state->context_tags = &state->context->netid;
1111 }
1112
1113 /* Similarly, we can't determine domain from address, but if the FQDN is
1114 given in --dhcp-host, we can use that, and failing that we can use the
1115 unqualified configured domain, if any. */
1116 if (state->hostname_auth)
1117 state->send_domain = state->domain;
1118 else
1119 state->send_domain = get_domain6(NULL);
1120
1121 log6_quiet(state, "DHCPINFORMATION-REQUEST", NULL, ignore ? _("ignored") : state->hostname);
1122 if (ignore)
1123 return 0;
1124 *outmsgtypep = DHCP6REPLY;
1125 tagif = add_options(state, 1);
1126 break;
1127 }
1128
1129
1130 case DHCP6RELEASE:
1131 {
1132 /* set reply message type */
1133 *outmsgtypep = DHCP6REPLY;
1134
1135 log6_quiet(state, "DHCPRELEASE", NULL, NULL);
1136
1137 for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
1138 {
1139 void *ia_option, *ia_end;
1140 int made_ia = 0;
1141
1142 for (check_ia(state, opt, &ia_end, &ia_option);
1143 ia_option;
1144 ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
1145 {
1146 struct dhcp_lease *lease;
1147 struct in6_addr addr;
1148
1149 /* align */
1150 memcpy(&addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
1151 if ((lease = lease6_find(state->clid, state->clid_len, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA,
1152 state->iaid, &addr)))
1153 lease_prune(lease, now);
1154 else
1155 {
1156 if (!made_ia)
1157 {
1158 o = new_opt6(state->ia_type);
1159 put_opt6_long(state->iaid);
1160 if (state->ia_type == OPTION6_IA_NA)
1161 {
1162 put_opt6_long(0);
1163 put_opt6_long(0);
1164 }
1165 made_ia = 1;
1166 }
1167
1168 o1 = new_opt6(OPTION6_IAADDR);
1169 put_opt6(&addr, IN6ADDRSZ);
1170 put_opt6_long(0);
1171 put_opt6_long(0);
1172 end_opt6(o1);
1173 }
1174 }
1175
1176 if (made_ia)
1177 {
1178 o1 = new_opt6(OPTION6_STATUS_CODE);
1179 put_opt6_short(DHCP6NOBINDING);
1180 put_opt6_string(_("no binding found"));
1181 end_opt6(o1);
1182
1183 end_opt6(o);
1184 }
1185 }
1186
1187 o1 = new_opt6(OPTION6_STATUS_CODE);
1188 put_opt6_short(DHCP6SUCCESS);
1189 put_opt6_string(_("release received"));
1190 end_opt6(o1);
1191
1192 break;
1193 }
1194
1195 case DHCP6DECLINE:
1196 {
1197 /* set reply message type */
1198 *outmsgtypep = DHCP6REPLY;
1199
1200 log6_quiet(state, "DHCPDECLINE", NULL, NULL);
1201
1202 for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
1203 {
1204 void *ia_option, *ia_end;
1205 int made_ia = 0;
1206
1207 for (check_ia(state, opt, &ia_end, &ia_option);
1208 ia_option;
1209 ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
1210 {
1211 struct dhcp_lease *lease;
1212 struct in6_addr addr;
1213 struct addrlist *addr_list;
1214
1215 /* align */
1216 memcpy(&addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
1217
1218 if ((addr_list = config_implies(config, state->context, &addr)))
1219 {
1220 prettyprint_time(daemon->dhcp_buff3, DECLINE_BACKOFF);
1221 inet_ntop(AF_INET6, &addr, daemon->addrbuff, ADDRSTRLEN);
1222 my_syslog(MS_DHCP | LOG_WARNING, _("disabling DHCP static address %s for %s"),
1223 daemon->addrbuff, daemon->dhcp_buff3);
1224 addr_list->flags |= ADDRLIST_DECLINED;
1225 addr_list->decline_time = now;
1226 }
1227 else
1228 /* make sure this host gets a different address next time. */
1229 for (context_tmp = state->context; context_tmp; context_tmp = context_tmp->current)
1230 context_tmp->addr_epoch++;
1231
1232 if ((lease = lease6_find(state->clid, state->clid_len, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA,
1233 state->iaid, &addr)))
1234 lease_prune(lease, now);
1235 else
1236 {
1237 if (!made_ia)
1238 {
1239 o = new_opt6(state->ia_type);
1240 put_opt6_long(state->iaid);
1241 if (state->ia_type == OPTION6_IA_NA)
1242 {
1243 put_opt6_long(0);
1244 put_opt6_long(0);
1245 }
1246 made_ia = 1;
1247 }
1248
1249 o1 = new_opt6(OPTION6_IAADDR);
1250 put_opt6(&addr, IN6ADDRSZ);
1251 put_opt6_long(0);
1252 put_opt6_long(0);
1253 end_opt6(o1);
1254 }
1255 }
1256
1257 if (made_ia)
1258 {
1259 o1 = new_opt6(OPTION6_STATUS_CODE);
1260 put_opt6_short(DHCP6NOBINDING);
1261 put_opt6_string(_("no binding found"));
1262 end_opt6(o1);
1263
1264 end_opt6(o);
1265 }
1266
1267 }
1268
1269 /* We must answer with 'success' in global section anyway */
1270 o1 = new_opt6(OPTION6_STATUS_CODE);
1271 put_opt6_short(DHCP6SUCCESS);
1272 put_opt6_string(_("success"));
1273 end_opt6(o1);
1274 break;
1275 }
1276
1277 }
1278
1279 log_tags(tagif, state->xid);
1280 log6_opts(0, state->xid, daemon->outpacket.iov_base + start_opts, daemon->outpacket.iov_base + save_counter(-1));
1281
1282 return 1;
1283
1284}
1285
1286static struct dhcp_netid *add_options(struct state *state, int do_refresh)
1287{
1288 void *oro;
1289 /* filter options based on tags, those we want get DHOPT_TAGOK bit set */
1290 struct dhcp_netid *tagif = option_filter(state->tags, state->context_tags, daemon->dhcp_opts6);
1291 struct dhcp_opt *opt_cfg;
1292 int done_dns = 0, done_refresh = !do_refresh, do_encap = 0;
1293 int i, o, o1;
1294
1295 oro = opt6_find(state->packet_options, state->end, OPTION6_ORO, 0);
1296
1297 for (opt_cfg = daemon->dhcp_opts6; opt_cfg; opt_cfg = opt_cfg->next)
1298 {
1299 /* netids match and not encapsulated? */
1300 if (!(opt_cfg->flags & DHOPT_TAGOK))
1301 continue;
1302
1303 if (!(opt_cfg->flags & DHOPT_FORCE) && oro)
1304 {
1305 for (i = 0; i < opt6_len(oro) - 1; i += 2)
1306 if (opt6_uint(oro, i, 2) == (unsigned)opt_cfg->opt)
1307 break;
1308
1309 /* option not requested */
1310 if (i >= opt6_len(oro) - 1)
1311 continue;
1312 }
1313
1314 if (opt_cfg->opt == OPTION6_REFRESH_TIME)
1315 done_refresh = 1;
1316
1317 if (opt_cfg->opt == OPTION6_DNS_SERVER)
1318 done_dns = 1;
1319
1320 if (opt_cfg->flags & DHOPT_ADDR6)
1321 {
1322 int len, j;
1323 struct in6_addr *a;
1324
1325 for (a = (struct in6_addr *)opt_cfg->val, len = opt_cfg->len, j = 0;
1326 j < opt_cfg->len; j += IN6ADDRSZ, a++)
1327 if ((IN6_IS_ADDR_ULA_ZERO(a) && IN6_IS_ADDR_UNSPECIFIED(state->ula_addr)) ||
1328 (IN6_IS_ADDR_LINK_LOCAL_ZERO(a) && IN6_IS_ADDR_UNSPECIFIED(state->ll_addr)))
1329 len -= IN6ADDRSZ;
1330
1331 if (len != 0)
1332 {
1333
1334 o = new_opt6(opt_cfg->opt);
1335
1336 for (a = (struct in6_addr *)opt_cfg->val, j = 0; j < opt_cfg->len; j+=IN6ADDRSZ, a++)
1337 {
1338 struct in6_addr *p = NULL;
1339
1340 if (IN6_IS_ADDR_UNSPECIFIED(a))
1341 {
1342 if (!add_local_addrs(state->context))
1343 p = state->fallback;
1344 }
1345 else if (IN6_IS_ADDR_ULA_ZERO(a))
1346 {
1347 if (!IN6_IS_ADDR_UNSPECIFIED(state->ula_addr))
1348 p = state->ula_addr;
1349 }
1350 else if (IN6_IS_ADDR_LINK_LOCAL_ZERO(a))
1351 {
1352 if (!IN6_IS_ADDR_UNSPECIFIED(state->ll_addr))
1353 p = state->ll_addr;
1354 }
1355 else
1356 p = a;
1357
1358 if (!p)
1359 continue;
1360 else if (opt_cfg->opt == OPTION6_NTP_SERVER)
1361 {
1362 if (IN6_IS_ADDR_MULTICAST(p))
1363 o1 = new_opt6(NTP_SUBOPTION_MC_ADDR);
1364 else
1365 o1 = new_opt6(NTP_SUBOPTION_SRV_ADDR);
1366 put_opt6(p, IN6ADDRSZ);
1367 end_opt6(o1);
1368 }
1369 else
1370 put_opt6(p, IN6ADDRSZ);
1371 }
1372
1373 end_opt6(o);
1374 }
1375 }
1376 else
1377 {
1378 o = new_opt6(opt_cfg->opt);
1379 if (opt_cfg->val)
1380 put_opt6(opt_cfg->val, opt_cfg->len);
1381 end_opt6(o);
1382 }
1383 }
1384
1385 if (daemon->port == NAMESERVER_PORT && !done_dns)
1386 {
1387 o = new_opt6(OPTION6_DNS_SERVER);
1388 if (!add_local_addrs(state->context))
1389 put_opt6(state->fallback, IN6ADDRSZ);
1390 end_opt6(o);
1391 }
1392
1393 if (state->context && !done_refresh)
1394 {
1395 struct dhcp_context *c;
1396 unsigned int lease_time = 0xffffffff;
1397
1398 /* Find the smallest lease tie of all contexts,
1399 subject to the RFC-4242 stipulation that this must not
1400 be less than 600. */
1401 for (c = state->context; c; c = c->next)
1402 if (c->lease_time < lease_time)
1403 {
1404 if (c->lease_time < 600)
1405 lease_time = 600;
1406 else
1407 lease_time = c->lease_time;
1408 }
1409
1410 o = new_opt6(OPTION6_REFRESH_TIME);
1411 put_opt6_long(lease_time);
1412 end_opt6(o);
1413 }
1414
1415 /* handle vendor-identifying vendor-encapsulated options,
1416 dhcp-option = vi-encap:13,17,....... */
1417 for (opt_cfg = daemon->dhcp_opts6; opt_cfg; opt_cfg = opt_cfg->next)
1418 opt_cfg->flags &= ~DHOPT_ENCAP_DONE;
1419
1420 if (oro)
1421 for (i = 0; i < opt6_len(oro) - 1; i += 2)
1422 if (opt6_uint(oro, i, 2) == OPTION6_VENDOR_OPTS)
1423 do_encap = 1;
1424
1425 for (opt_cfg = daemon->dhcp_opts6; opt_cfg; opt_cfg = opt_cfg->next)
1426 {
1427 if (opt_cfg->flags & DHOPT_RFC3925)
1428 {
1429 int found = 0;
1430 struct dhcp_opt *oc;
1431
1432 if (opt_cfg->flags & DHOPT_ENCAP_DONE)
1433 continue;
1434
1435 for (oc = daemon->dhcp_opts6; oc; oc = oc->next)
1436 {
1437 oc->flags &= ~DHOPT_ENCAP_MATCH;
1438
1439 if (!(oc->flags & DHOPT_RFC3925) || opt_cfg->u.encap != oc->u.encap)
1440 continue;
1441
1442 oc->flags |= DHOPT_ENCAP_DONE;
1443 if (match_netid(oc->netid, tagif, 1))
1444 {
1445 /* option requested/forced? */
1446 if (!oro || do_encap || (oc->flags & DHOPT_FORCE))
1447 {
1448 oc->flags |= DHOPT_ENCAP_MATCH;
1449 found = 1;
1450 }
1451 }
1452 }
1453
1454 if (found)
1455 {
1456 o = new_opt6(OPTION6_VENDOR_OPTS);
1457 put_opt6_long(opt_cfg->u.encap);
1458
1459 for (oc = daemon->dhcp_opts6; oc; oc = oc->next)
1460 if (oc->flags & DHOPT_ENCAP_MATCH)
1461 {
1462 o1 = new_opt6(oc->opt);
1463 put_opt6(oc->val, oc->len);
1464 end_opt6(o1);
1465 }
1466 end_opt6(o);
1467 }
1468 }
1469 }
1470
1471
1472 if (state->hostname)
1473 {
1474 unsigned char *p;
1475 size_t len = strlen(state->hostname);
1476
1477 if (state->send_domain)
1478 len += strlen(state->send_domain) + 2;
1479
1480 o = new_opt6(OPTION6_FQDN);
1481 if ((p = expand(len + 2)))
1482 {
1483 *(p++) = state->fqdn_flags;
1484 p = do_rfc1035_name(p, state->hostname, NULL);
1485 if (state->send_domain)
1486 {
1487 p = do_rfc1035_name(p, state->send_domain, NULL);
1488 *p = 0;
1489 }
1490 }
1491 end_opt6(o);
1492 }
1493
1494
1495 /* logging */
1496 if (option_bool(OPT_LOG_OPTS) && oro)
1497 {
1498 char *q = daemon->namebuff;
1499 for (i = 0; i < opt6_len(oro) - 1; i += 2)
1500 {
1501 char *s = option_string(AF_INET6, opt6_uint(oro, i, 2), NULL, 0, NULL, 0);
1502 q += snprintf(q, MAXDNAME - (q - daemon->namebuff),
1503 "%d%s%s%s",
1504 opt6_uint(oro, i, 2),
1505 strlen(s) != 0 ? ":" : "",
1506 s,
1507 (i > opt6_len(oro) - 3) ? "" : ", ");
1508 if ( i > opt6_len(oro) - 3 || (q - daemon->namebuff) > 40)
1509 {
1510 q = daemon->namebuff;
1511 my_syslog(MS_DHCP | LOG_INFO, _("%u requested options: %s"), state->xid, daemon->namebuff);
1512 }
1513 }
1514 }
1515
1516 return tagif;
1517}
1518
1519static int add_local_addrs(struct dhcp_context *context)
1520{
1521 int done = 0;
1522
1523 for (; context; context = context->current)
1524 if ((context->flags & CONTEXT_USED) && !IN6_IS_ADDR_UNSPECIFIED(&context->local6))
1525 {
1526 /* squash duplicates */
1527 struct dhcp_context *c;
1528 for (c = context->current; c; c = c->current)
1529 if ((c->flags & CONTEXT_USED) &&
1530 IN6_ARE_ADDR_EQUAL(&context->local6, &c->local6))
1531 break;
1532
1533 if (!c)
1534 {
1535 done = 1;
1536 put_opt6(&context->local6, IN6ADDRSZ);
1537 }
1538 }
1539
1540 return done;
1541}
1542
1543
1544static void get_context_tag(struct state *state, struct dhcp_context *context)
1545{
1546 /* get tags from context if we've not used it before */
1547 if (context->netid.next == &context->netid && context->netid.net)
1548 {
1549 context->netid.next = state->context_tags;
1550 state->context_tags = &context->netid;
1551 if (!state->hostname_auth)
1552 {
1553 struct dhcp_netid_list *id_list;
1554
1555 for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next)
1556 if ((!id_list->list) || match_netid(id_list->list, &context->netid, 0))
1557 break;
1558 if (id_list)
1559 state->hostname = NULL;
1560 }
1561 }
1562}
1563
1564static int check_ia(struct state *state, void *opt, void **endp, void **ia_option)
1565{
1566 state->ia_type = opt6_type(opt);
1567 *ia_option = NULL;
1568
1569 if (state->ia_type != OPTION6_IA_NA && state->ia_type != OPTION6_IA_TA)
1570 return 0;
1571
1572 if (state->ia_type == OPTION6_IA_NA && opt6_len(opt) < 12)
1573 return 0;
1574
1575 if (state->ia_type == OPTION6_IA_TA && opt6_len(opt) < 4)
1576 return 0;
1577
1578 *endp = opt6_ptr(opt, opt6_len(opt));
1579 state->iaid = opt6_uint(opt, 0, 4);
1580 *ia_option = opt6_find(opt6_ptr(opt, state->ia_type == OPTION6_IA_NA ? 12 : 4), *endp, OPTION6_IAADDR, 24);
1581
1582 return 1;
1583}
1584
1585
1586static int build_ia(struct state *state, int *t1cntr)
1587{
1588 int o = new_opt6(state->ia_type);
1589
1590 put_opt6_long(state->iaid);
1591 *t1cntr = 0;
1592
1593 if (state->ia_type == OPTION6_IA_NA)
1594 {
1595 /* save pointer */
1596 *t1cntr = save_counter(-1);
1597 /* so we can fill these in later */
1598 put_opt6_long(0);
1599 put_opt6_long(0);
1600 }
1601
1602 return o;
1603}
1604
1605static void end_ia(int t1cntr, unsigned int min_time, int do_fuzz)
1606{
1607 if (t1cntr != 0)
1608 {
1609 /* go back and fill in fields in IA_NA option */
1610 int sav = save_counter(t1cntr);
1611 unsigned int t1, t2, fuzz = 0;
1612
1613 if (do_fuzz)
1614 {
1615 fuzz = rand16();
1616
1617 while (fuzz > (min_time/16))
1618 fuzz = fuzz/2;
1619 }
1620
1621 t1 = (min_time == 0xffffffff) ? 0xffffffff : min_time/2 - fuzz;
1622 t2 = (min_time == 0xffffffff) ? 0xffffffff : ((min_time/8)*7) - fuzz;
1623 put_opt6_long(t1);
1624 put_opt6_long(t2);
1625 save_counter(sav);
1626 }
1627}
1628
1629static void add_address(struct state *state, struct dhcp_context *context, unsigned int lease_time, void *ia_option,
1630 unsigned int *min_time, struct in6_addr *addr, time_t now)
1631{
1632 unsigned int valid_time = 0, preferred_time = 0;
1633 int o = new_opt6(OPTION6_IAADDR);
1634 struct dhcp_lease *lease;
1635
1636 /* get client requested times */
1637 if (ia_option)
1638 {
1639 preferred_time = opt6_uint(ia_option, 16, 4);
1640 valid_time = opt6_uint(ia_option, 20, 4);
1641 }
1642
1643 calculate_times(context, min_time, &valid_time, &preferred_time, lease_time);
1644
1645 put_opt6(addr, sizeof(*addr));
1646 put_opt6_long(preferred_time);
1647 put_opt6_long(valid_time);
1648 end_opt6(o);
1649
1650 if (state->lease_allocate)
1651 update_leases(state, context, addr, valid_time, now);
1652
1653 if ((lease = lease6_find_by_addr(addr, 128, 0)))
1654 lease->flags |= LEASE_USED;
1655
1656 /* get tags from context if we've not used it before */
1657 if (context->netid.next == &context->netid && context->netid.net)
1658 {
1659 context->netid.next = state->context_tags;
1660 state->context_tags = &context->netid;
1661
1662 if (!state->hostname_auth)
1663 {
1664 struct dhcp_netid_list *id_list;
1665
1666 for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next)
1667 if ((!id_list->list) || match_netid(id_list->list, &context->netid, 0))
1668 break;
1669 if (id_list)
1670 state->hostname = NULL;
1671 }
1672 }
1673
1674 log6_quiet(state, state->lease_allocate ? "DHCPREPLY" : "DHCPADVERTISE", addr, state->hostname);
1675
1676}
1677
1678static void mark_context_used(struct state *state, struct in6_addr *addr)
1679{
1680 struct dhcp_context *context;
1681
1682 /* Mark that we have an address for this prefix. */
1683 for (context = state->context; context; context = context->current)
1684 if (is_same_net6(addr, &context->start6, context->prefix))
1685 context->flags |= CONTEXT_USED;
1686}
1687
1688static void mark_config_used(struct dhcp_context *context, struct in6_addr *addr)
1689{
1690 for (; context; context = context->current)
1691 if (is_same_net6(addr, &context->start6, context->prefix))
1692 context->flags |= CONTEXT_CONF_USED;
1693}
1694
1695/* make sure address not leased to another CLID/IAID */
1696static int check_address(struct state *state, struct in6_addr *addr)
1697{
1698 struct dhcp_lease *lease;
1699
1700 if (!(lease = lease6_find_by_addr(addr, 128, 0)))
1701 return 1;
1702
1703 if (lease->clid_len != state->clid_len ||
1704 memcmp(lease->clid, state->clid, state->clid_len) != 0 ||
1705 lease->iaid != state->iaid)
1706 return 0;
1707
1708 return 1;
1709}
1710
1711
1712/* return true of *addr could have been generated from config. */
1713static struct addrlist *config_implies(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr)
1714{
1715 int prefix;
1716 struct in6_addr wild_addr;
1717 struct addrlist *addr_list;
1718
1719 if (!config || !(config->flags & CONFIG_ADDR6))
1720 return NULL;
1721
1722 for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
1723 {
1724 prefix = (addr_list->flags & ADDRLIST_PREFIX) ? addr_list->prefixlen : 128;
1725 wild_addr = addr_list->addr.addr6;
1726
1727 if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64)
1728 {
1729 wild_addr = context->start6;
1730 setaddr6part(&wild_addr, addr6part(&addr_list->addr.addr6));
1731 }
1732 else if (!is_same_net6(&context->start6, addr, context->prefix))
1733 continue;
1734
1735 if (is_same_net6(&wild_addr, addr, prefix))
1736 return addr_list;
1737 }
1738
1739 return NULL;
1740}
1741
1742static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state, time_t now)
1743{
1744 u64 addrpart, i, addresses;
1745 struct addrlist *addr_list;
1746
1747 if (!config || !(config->flags & CONFIG_ADDR6))
1748 return 0;
1749
1750 for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
1751 if (!(addr_list->flags & ADDRLIST_DECLINED) ||
1752 difftime(now, addr_list->decline_time) >= (float)DECLINE_BACKOFF)
1753 {
1754 addrpart = addr6part(&addr_list->addr.addr6);
1755 addresses = 1;
1756
1757 if (addr_list->flags & ADDRLIST_PREFIX)
1758 addresses = (u64)1<<(128-addr_list->prefixlen);
1759
1760 if ((addr_list->flags & ADDRLIST_WILDCARD))
1761 {
1762 if (context->prefix != 64)
1763 continue;
1764
1765 *addr = context->start6;
1766 }
1767 else if (is_same_net6(&context->start6, &addr_list->addr.addr6, context->prefix))
1768 *addr = addr_list->addr.addr6;
1769 else
1770 continue;
1771
1772 for (i = 0 ; i < addresses; i++)
1773 {
1774 setaddr6part(addr, addrpart+i);
1775
1776 if (check_address(state, addr))
1777 return 1;
1778 }
1779 }
1780
1781 return 0;
1782}
1783
1784/* Calculate valid and preferred times to send in leases/renewals.
1785
1786 Inputs are:
1787
1788 *valid_timep, *preferred_timep - requested times from IAADDR options.
1789 context->valid, context->preferred - times associated with subnet address on local interface.
1790 context->flags | CONTEXT_DEPRECATE - "deprecated" flag in dhcp-range.
1791 lease_time - configured time for context for individual client.
1792 *min_time - smallest valid time sent so far.
1793
1794 Outputs are :
1795
1796 *valid_timep, *preferred_timep - times to be send in IAADDR option.
1797 *min_time - smallest valid time sent so far, to calculate T1 and T2.
1798
1799 */
1800static void calculate_times(struct dhcp_context *context, unsigned int *min_time, unsigned int *valid_timep,
1801 unsigned int *preferred_timep, unsigned int lease_time)
1802{
1803 unsigned int req_preferred = *preferred_timep, req_valid = *valid_timep;
1804 unsigned int valid_time = lease_time, preferred_time = lease_time;
1805
1806 /* RFC 3315: "A server ignores the lifetimes set
1807 by the client if the preferred lifetime is greater than the valid
1808 lifetime. */
1809 if (req_preferred <= req_valid)
1810 {
1811 if (req_preferred != 0)
1812 {
1813 /* 0 == "no preference from client" */
1814 if (req_preferred < 120u)
1815 req_preferred = 120u; /* sanity */
1816
1817 if (req_preferred < preferred_time)
1818 preferred_time = req_preferred;
1819 }
1820
1821 if (req_valid != 0)
1822 /* 0 == "no preference from client" */
1823 {
1824 if (req_valid < 120u)
1825 req_valid = 120u; /* sanity */
1826
1827 if (req_valid < valid_time)
1828 valid_time = req_valid;
1829 }
1830 }
1831
1832 /* deprecate (preferred == 0) which configured, or when local address
1833 is deprecated */
1834 if ((context->flags & CONTEXT_DEPRECATE) || context->preferred == 0)
1835 preferred_time = 0;
1836
1837 if (preferred_time != 0 && preferred_time < *min_time)
1838 *min_time = preferred_time;
1839
1840 if (valid_time != 0 && valid_time < *min_time)
1841 *min_time = valid_time;
1842
1843 *valid_timep = valid_time;
1844 *preferred_timep = preferred_time;
1845}
1846
1847static void update_leases(struct state *state, struct dhcp_context *context, struct in6_addr *addr, unsigned int lease_time, time_t now)
1848{
1849 struct dhcp_lease *lease = lease6_find_by_addr(addr, 128, 0);
1850#ifdef HAVE_SCRIPT
1851 struct dhcp_netid *tagif = run_tag_if(state->tags);
1852#endif
1853
1854 (void)context;
1855
1856 if (!lease)
1857 lease = lease6_allocate(addr, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA);
1858
1859 if (lease)
1860 {
1861 lease_set_expires(lease, lease_time, now);
1862 lease_set_iaid(lease, state->iaid);
1863 lease_set_hwaddr(lease, state->mac, state->clid, state->mac_len, state->mac_type, state->clid_len, now, 0);
1864 lease_set_interface(lease, state->interface, now);
1865 if (state->hostname && state->ia_type == OPTION6_IA_NA)
1866 {
1867 char *addr_domain = get_domain6(addr);
1868 if (!state->send_domain)
1869 state->send_domain = addr_domain;
1870 lease_set_hostname(lease, state->hostname, state->hostname_auth, addr_domain, state->domain);
1871 }
1872
1873#ifdef HAVE_SCRIPT
1874 if (daemon->lease_change_command)
1875 {
1876 void *class_opt;
1877 lease->flags |= LEASE_CHANGED;
1878 free(lease->extradata);
1879 lease->extradata = NULL;
1880 lease->extradata_size = lease->extradata_len = 0;
1881 lease->vendorclass_count = 0;
1882
1883 if ((class_opt = opt6_find(state->packet_options, state->end, OPTION6_VENDOR_CLASS, 4)))
1884 {
1885 void *enc_opt, *enc_end = opt6_ptr(class_opt, opt6_len(class_opt));
1886 lease->vendorclass_count++;
1887 /* send enterprise number first */
1888 sprintf(daemon->dhcp_buff2, "%u", opt6_uint(class_opt, 0, 4));
1889 lease_add_extradata(lease, (unsigned char *)daemon->dhcp_buff2, strlen(daemon->dhcp_buff2), 0);
1890
1891 if (opt6_len(class_opt) >= 6)
1892 for (enc_opt = opt6_ptr(class_opt, 4); enc_opt; enc_opt = opt6_next(enc_opt, enc_end))
1893 {
1894 lease->vendorclass_count++;
1895 lease_add_extradata(lease, opt6_ptr(enc_opt, 0), opt6_len(enc_opt), 0);
1896 }
1897 }
1898
1899 lease_add_extradata(lease, (unsigned char *)state->client_hostname,
1900 state->client_hostname ? strlen(state->client_hostname) : 0, 0);
1901
1902 /* space-concat tag set */
1903 if (!tagif && !context->netid.net)
1904 lease_add_extradata(lease, NULL, 0, 0);
1905 else
1906 {
1907 if (context->netid.net)
1908 lease_add_extradata(lease, (unsigned char *)context->netid.net, strlen(context->netid.net), tagif ? ' ' : 0);
1909
1910 if (tagif)
1911 {
1912 struct dhcp_netid *n;
1913 for (n = tagif; n; n = n->next)
1914 {
1915 struct dhcp_netid *n1;
1916 /* kill dupes */
1917 for (n1 = n->next; n1; n1 = n1->next)
1918 if (strcmp(n->net, n1->net) == 0)
1919 break;
1920 if (!n1)
1921 lease_add_extradata(lease, (unsigned char *)n->net, strlen(n->net), n->next ? ' ' : 0);
1922 }
1923 }
1924 }
1925
1926 if (state->link_address)
1927 inet_ntop(AF_INET6, state->link_address, daemon->addrbuff, ADDRSTRLEN);
1928
1929 lease_add_extradata(lease, (unsigned char *)daemon->addrbuff, state->link_address ? strlen(daemon->addrbuff) : 0, 0);
1930
1931 if ((class_opt = opt6_find(state->packet_options, state->end, OPTION6_USER_CLASS, 2)))
1932 {
1933 void *enc_opt, *enc_end = opt6_ptr(class_opt, opt6_len(class_opt));
1934 for (enc_opt = opt6_ptr(class_opt, 0); enc_opt; enc_opt = opt6_next(enc_opt, enc_end))
1935 lease_add_extradata(lease, opt6_ptr(enc_opt, 0), opt6_len(enc_opt), 0);
1936 }
1937 }
1938#endif
1939
1940 }
1941}
1942
1943
1944
1945static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_opts)
1946{
1947 void *opt;
1948 char *desc = nest ? "nest" : "sent";
1949
1950 if (!option_bool(OPT_LOG_OPTS) || start_opts == end_opts)
1951 return;
1952
1953 for (opt = start_opts; opt; opt = opt6_next(opt, end_opts))
1954 {
1955 int type = opt6_type(opt);
1956 void *ia_options = NULL;
1957 char *optname;
1958
1959 if (type == OPTION6_IA_NA)
1960 {
1961 sprintf(daemon->namebuff, "IAID=%u T1=%u T2=%u",
1962 opt6_uint(opt, 0, 4), opt6_uint(opt, 4, 4), opt6_uint(opt, 8, 4));
1963 optname = "ia-na";
1964 ia_options = opt6_ptr(opt, 12);
1965 }
1966 else if (type == OPTION6_IA_TA)
1967 {
1968 sprintf(daemon->namebuff, "IAID=%u", opt6_uint(opt, 0, 4));
1969 optname = "ia-ta";
1970 ia_options = opt6_ptr(opt, 4);
1971 }
1972 else if (type == OPTION6_IAADDR)
1973 {
1974 struct in6_addr addr;
1975
1976 /* align */
1977 memcpy(&addr, opt6_ptr(opt, 0), IN6ADDRSZ);
1978 inet_ntop(AF_INET6, &addr, daemon->addrbuff, ADDRSTRLEN);
1979 sprintf(daemon->namebuff, "%s PL=%u VL=%u",
1980 daemon->addrbuff, opt6_uint(opt, 16, 4), opt6_uint(opt, 20, 4));
1981 optname = "iaaddr";
1982 ia_options = opt6_ptr(opt, 24);
1983 }
1984 else if (type == OPTION6_STATUS_CODE)
1985 {
1986 int len = sprintf(daemon->namebuff, "%u ", opt6_uint(opt, 0, 2));
1987 memcpy(daemon->namebuff + len, opt6_ptr(opt, 2), opt6_len(opt)-2);
1988 daemon->namebuff[len + opt6_len(opt) - 2] = 0;
1989 optname = "status";
1990 }
1991 else
1992 {
1993 /* account for flag byte on FQDN */
1994 int offset = type == OPTION6_FQDN ? 1 : 0;
1995 optname = option_string(AF_INET6, type, opt6_ptr(opt, offset), opt6_len(opt) - offset, daemon->namebuff, MAXDNAME);
1996 }
1997
1998 my_syslog(MS_DHCP | LOG_INFO, "%u %s size:%3d option:%3d %s %s",
1999 xid, desc, opt6_len(opt), type, optname, daemon->namebuff);
2000
2001 if (ia_options)
2002 log6_opts(1, xid, ia_options, opt6_ptr(opt, opt6_len(opt)));
2003 }
2004}
2005
2006static void log6_quiet(struct state *state, char *type, struct in6_addr *addr, char *string)
2007{
2008 if (option_bool(OPT_LOG_OPTS) || !option_bool(OPT_QUIET_DHCP6))
2009 log6_packet(state, type, addr, string);
2010}
2011
2012static void log6_packet(struct state *state, char *type, struct in6_addr *addr, char *string)
2013{
2014 int clid_len = state->clid_len;
2015
2016 /* avoid buffer overflow */
2017 if (clid_len > 100)
2018 clid_len = 100;
2019
2020 print_mac(daemon->namebuff, state->clid, clid_len);
2021
2022 if (addr)
2023 {
2024 inet_ntop(AF_INET6, addr, daemon->dhcp_buff2, DHCP_BUFF_SZ - 1);
2025 strcat(daemon->dhcp_buff2, " ");
2026 }
2027 else
2028 daemon->dhcp_buff2[0] = 0;
2029
2030 if(option_bool(OPT_LOG_OPTS))
2031 my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s%s %s",
2032 state->xid,
2033 type,
2034 state->iface_name,
2035 daemon->dhcp_buff2,
2036 daemon->namebuff,
2037 string ? string : "");
2038 else
2039 my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s%s %s",
2040 type,
2041 state->iface_name,
2042 daemon->dhcp_buff2,
2043 daemon->namebuff,
2044 string ? string : "");
2045}
2046
2047static void *opt6_find (void *opts, void *end, unsigned int search, unsigned int minsize)
2048{
2049 u16 opt, opt_len;
2050 void *start;
2051
2052 if (!opts)
2053 return NULL;
2054
2055 while (1)
2056 {
2057 if (end - opts < 4)
2058 return NULL;
2059
2060 start = opts;
2061 GETSHORT(opt, opts);
2062 GETSHORT(opt_len, opts);
2063
2064 if (opt_len > (end - opts))
2065 return NULL;
2066
2067 if (opt == search && (opt_len >= minsize))
2068 return start;
2069
2070 opts += opt_len;
2071 }
2072}
2073
2074static void *opt6_next(void *opts, void *end)
2075{
2076 u16 opt_len;
2077
2078 if (end - opts < 4)
2079 return NULL;
2080
2081 opts += 2;
2082 GETSHORT(opt_len, opts);
2083
2084 if (opt_len >= (end - opts))
2085 return NULL;
2086
2087 return opts + opt_len;
2088}
2089
2090static unsigned int opt6_uint(unsigned char *opt, int offset, int size)
2091{
2092 /* this worries about unaligned data and byte order */
2093 unsigned int ret = 0;
2094 int i;
2095 unsigned char *p = opt6_ptr(opt, offset);
2096
2097 for (i = 0; i < size; i++)
2098 ret = (ret << 8) | *p++;
2099
2100 return ret;
2101}
2102
2103void relay_upstream6(struct dhcp_relay *relay, ssize_t sz,
2104 struct in6_addr *peer_address, u32 scope_id, time_t now)
2105{
2106 /* ->local is same value for all relays on ->current chain */
2107
2108 union all_addr from;
2109 unsigned char *header;
2110 unsigned char *inbuff = daemon->dhcp_packet.iov_base;
2111 int msg_type = *inbuff;
2112 int hopcount;
2113 struct in6_addr multicast;
2114 unsigned int maclen, mactype;
2115 unsigned char mac[DHCP_CHADDR_MAX];
2116
2117 inet_pton(AF_INET6, ALL_SERVERS, &multicast);
2118 get_client_mac(peer_address, scope_id, mac, &maclen, &mactype, now);
2119
2120 /* source address == relay address */
2121 from.addr6 = relay->local.addr6;
2122
2123 /* Get hop count from nested relayed message */
2124 if (msg_type == DHCP6RELAYFORW)
2125 hopcount = *((unsigned char *)inbuff+1) + 1;
2126 else
2127 hopcount = 0;
2128
2129 /* RFC 3315 HOP_COUNT_LIMIT */
2130 if (hopcount > 32)
2131 return;
2132
2133 reset_counter();
2134
2135 if ((header = put_opt6(NULL, 34)))
2136 {
2137 int o;
2138
2139 header[0] = DHCP6RELAYFORW;
2140 header[1] = hopcount;
2141 memcpy(&header[2], &relay->local.addr6, IN6ADDRSZ);
2142 memcpy(&header[18], peer_address, IN6ADDRSZ);
2143
2144 /* RFC-6939 */
2145 if (maclen != 0)
2146 {
2147 o = new_opt6(OPTION6_CLIENT_MAC);
2148 put_opt6_short(mactype);
2149 put_opt6(mac, maclen);
2150 end_opt6(o);
2151 }
2152
2153 o = new_opt6(OPTION6_RELAY_MSG);
2154 put_opt6(inbuff, sz);
2155 end_opt6(o);
2156
2157 for (; relay; relay = relay->current)
2158 {
2159 union mysockaddr to;
2160
2161 to.sa.sa_family = AF_INET6;
2162 to.in6.sin6_addr = relay->server.addr6;
2163 to.in6.sin6_port = htons(DHCPV6_SERVER_PORT);
2164 to.in6.sin6_flowinfo = 0;
2165 to.in6.sin6_scope_id = 0;
2166
2167 if (IN6_ARE_ADDR_EQUAL(&relay->server.addr6, &multicast))
2168 {
2169 int multicast_iface;
2170 if (!relay->interface || strchr(relay->interface, '*') ||
2171 (multicast_iface = if_nametoindex(relay->interface)) == 0 ||
2172 setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &multicast_iface, sizeof(multicast_iface)) == -1)
2173 my_syslog(MS_DHCP | LOG_ERR, _("Cannot multicast to DHCPv6 server without correct interface"));
2174 }
2175
2176 send_from(daemon->dhcp6fd, 0, daemon->outpacket.iov_base, save_counter(-1), &to, &from, 0);
2177
2178 if (option_bool(OPT_LOG_OPTS))
2179 {
2180 inet_ntop(AF_INET6, &relay->local, daemon->addrbuff, ADDRSTRLEN);
2181 inet_ntop(AF_INET6, &relay->server, daemon->namebuff, ADDRSTRLEN);
2182 my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay %s -> %s"), daemon->addrbuff, daemon->namebuff);
2183 }
2184
2185 /* Save this for replies */
2186 relay->iface_index = scope_id;
2187 }
2188 }
2189}
2190
2191unsigned short relay_reply6(struct sockaddr_in6 *peer, ssize_t sz, char *arrival_interface)
2192{
2193 struct dhcp_relay *relay;
2194 struct in6_addr link;
2195 unsigned char *inbuff = daemon->dhcp_packet.iov_base;
2196
2197 /* must have at least msg_type+hopcount+link_address+peer_address+minimal size option
2198 which is 1 + 1 + 16 + 16 + 2 + 2 = 38 */
2199
2200 if (sz < 38 || *inbuff != DHCP6RELAYREPL)
2201 return 0;
2202
2203 memcpy(&link, &inbuff[2], IN6ADDRSZ);
2204
2205 for (relay = daemon->relay6; relay; relay = relay->next)
2206 if (IN6_ARE_ADDR_EQUAL(&link, &relay->local.addr6) &&
2207 (!relay->interface || wildcard_match(relay->interface, arrival_interface)))
2208 break;
2209
2210 reset_counter();
2211
2212 if (relay)
2213 {
2214 void *opt, *opts = inbuff + 34;
2215 void *end = inbuff + sz;
2216 for (opt = opts; opt; opt = opt6_next(opt, end))
2217 if (opt6_type(opt) == OPTION6_RELAY_MSG && opt6_len(opt) > 0)
2218 {
2219 int encap_type = *((unsigned char *)opt6_ptr(opt, 0));
2220 put_opt6(opt6_ptr(opt, 0), opt6_len(opt));
2221 memcpy(&peer->sin6_addr, &inbuff[18], IN6ADDRSZ);
2222 peer->sin6_scope_id = relay->iface_index;
2223 return encap_type == DHCP6RELAYREPL ? DHCPV6_SERVER_PORT : DHCPV6_CLIENT_PORT;
2224 }
2225 }
2226
2227 return 0;
2228}
2229
2230#endif