The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
base.c
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: fd2117bb6f0e1b583bcfb8001e454a82ef1cd4af $
19 * @file src/process/dhcpv6/base.c
20 * @brief Base DHCPV6 processing.
21 *
22 * This code was originally written under contract for Network RADIUS
23 * but has been substantially modified from its original form outside
24 * of the project that required its creation.
25 *
26 * @copyright 2021 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
27 * @copyright 2020 Network RADIUS SAS (legal@networkradius.com)
28 */
29#define LOG_PREFIX "process_dhcpv6 - "
30
31#include <freeradius-devel/io/application.h>
32#include <freeradius-devel/server/protocol.h>
33#include <freeradius-devel/server/pair.h>
34#include <freeradius-devel/unlang/interpret.h>
35#include <freeradius-devel/util/dict.h>
36#include <freeradius-devel/util/debug.h>
37#include <freeradius-devel/dhcpv6/dhcpv6.h>
38#include <freeradius-devel/protocol/dhcpv6/freeradius.internal.h>
39
40/*
41 * DHCPV6 state machine configuration
42 */
68
69typedef struct {
70 CONF_SECTION *server_cs; //!< Our virtual server.
71 process_dhcpv6_sections_t sections; //!< Pointers to various config sections
72 ///< we need to execute.
73 bool status_code_on_success; //!< Controls whether we add a status-code
74 ///< option to outbound packets if the status
75 ///< code would be 0.
76 ///< This is allowed by RFC 3315, but seems
77 ///< to cause issues with some clients.
78
79 bool send_failure_message; //!< If true, all instances of
80 ///< Module-Failure-Message in the request
81 ///< are concatenated and returned in the
82 ///< status-message field of the status-code
83 ///< option if the status-code is anything
84 ///< other than success.
85 ///< This may leak information about the
86 ///< internal state of the server, so is
87 ///< disabled by default.
88
89 bool move_failure_message_to_parent; //!< If true, and a parent exists, and the
90 ///< parent is a DHCPv6 request, all module
91 ///< failure messages will get copied to the
92 ///< parent and then freed.
93 ///< When combined with send_failure_message
94 ///< this ensures only the outer relay message
95 ///< contains failure data. The outer relay
96 ///< typically being controlled by the admin
97 ///< and not the end user.
99
100/** Records fields from the original request so we have a known good copy
101 */
107
108/** Records fields from the original relay-request so we have a known good copy
109 */
116
117static fr_dict_t const *dict_dhcpv6;
119
122 { .out = &dict_dhcpv6, .proto = "dhcpv6" },
123 { .out = &dict_freeradius, .proto = "freeradius" },
124 { NULL }
125};
126
137
139
142 { .out = &attr_client_id, .name = "Client-ID", .type = FR_TYPE_STRUCT, .dict = &dict_dhcpv6 },
143 { .out = &attr_hop_count, .name = "Hop-Count", .type = FR_TYPE_UINT8, .dict = &dict_dhcpv6 },
144 { .out = &attr_interface_id, .name = "Interface-ID", .type = FR_TYPE_OCTETS, .dict = &dict_dhcpv6 },
145 { .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_dhcpv6 },
146 { .out = &attr_relay_link_address, .name = "Relay-Link-Address", .type = FR_TYPE_IPV6_ADDR, .dict = &dict_dhcpv6 },
147 { .out = &attr_relay_peer_address, .name = "Relay-Peer-Address", .type = FR_TYPE_IPV6_ADDR, .dict = &dict_dhcpv6 },
148 { .out = &attr_server_id, .name = "Server-ID", .type = FR_TYPE_STRUCT, .dict = &dict_dhcpv6 },
149 { .out = &attr_status_code_value, .name = "Status-Code.Value", .type = FR_TYPE_UINT16, .dict = &dict_dhcpv6 },
150 { .out = &attr_status_code_message, .name = "Status-Code.Message", .type = FR_TYPE_STRING, .dict = &dict_dhcpv6 },
151 { .out = &attr_transaction_id, .name = "Transaction-Id", .type = FR_TYPE_OCTETS, .dict = &dict_dhcpv6 },
152
153 { .out = &attr_module_failure_message, .name = "Module-Failure-Message", .type = FR_TYPE_STRING, .dict = &dict_freeradius },
154 { NULL }
155};
156
161
164 { .out = &enum_status_code_success, .name = "success", .attr = &attr_status_code_value },
165 { .out = &enum_status_code_unspec_fail, .name = "UnspecFail", .attr = &attr_status_code_value },
166 { .out = &enum_status_code_not_on_link, .name = "NotOnLink", .attr = &attr_status_code_value },
167 { .out = &enum_status_code_no_binding, .name = "NoBinding", .attr = &attr_status_code_value },
168 { NULL }
169};
170
171#define FR_DHCPV6_PROCESS_CODE_VALID(_x) (FR_DHCPV6_PACKET_CODE_VALID(_x) || (_x == FR_DHCPV6_DO_NOT_RESPOND))
172
173#define PROCESS_PACKET_TYPE fr_dhcpv6_packet_code_t
174#define PROCESS_CODE_MAX FR_DHCPV6_CODE_MAX
175#define PROCESS_CODE_DO_NOT_RESPOND FR_DHCPV6_DO_NOT_RESPOND
176#define PROCESS_PACKET_CODE_VALID FR_DHCPV6_PROCESS_CODE_VALID
177#define PROCESS_INST process_dhcpv6_t
178#define PROCESS_CODE_DYNAMIC_CLIENT FR_DHCPV6_REPLY
179
180/*
181 * DHCPv6 is nonstandard in that we reply
182 * to the majority of requests, but include a
183 * status code to indicate failures.
184 */
185#define PROCESS_STATE_EXTRA_FIELDS fr_value_box_t const **status_codes[RLM_MODULE_NUMCODES];
186#include <freeradius-devel/server/process.h>
187
189 { FR_CONF_OFFSET("status_code_on_success", process_dhcpv6_t, status_code_on_success), .dflt = "no" },
190 { FR_CONF_OFFSET("send_failure_message", process_dhcpv6_t, send_failure_message), .dflt = "no" },
191 { FR_CONF_OFFSET("move_failure_message_to_parent", process_dhcpv6_t, move_failure_message_to_parent), .dflt = "yes" },
193};
194
196 {
197 .section = SECTION_NAME("recv", "Solicit"),
198 .actions = &mod_actions_postauth,
199 .offset = PROCESS_CONF_OFFSET(recv_solicit)
200 },
201 {
202 .section = SECTION_NAME("recv", "Request"),
204 .offset = PROCESS_CONF_OFFSET(recv_request)
205 },
206 {
207 .section = SECTION_NAME("recv", "Confirm"),
209 .offset = PROCESS_CONF_OFFSET(recv_confirm)
210 },
211 {
212 .section = SECTION_NAME("recv", "Renew"),
214 .offset = PROCESS_CONF_OFFSET(recv_renew)
215 },
216 {
217 .section = SECTION_NAME("recv", "Rebind"),
219 .offset = PROCESS_CONF_OFFSET(recv_rebind)
220 },
221 {
222 .section = SECTION_NAME("recv", "Release"),
224 .offset = PROCESS_CONF_OFFSET(recv_release)
225 },
226 {
227 .section = SECTION_NAME("recv", "Decline"),
229 .offset = PROCESS_CONF_OFFSET(recv_decline)
230 },
231 {
232 .section = SECTION_NAME("recv", "Reconfigure"),
234 .offset = PROCESS_CONF_OFFSET(recv_reconfigure)
235 },
236 {
237 .section = SECTION_NAME("recv", "Information-Request"),
239 .offset = PROCESS_CONF_OFFSET(recv_information_request)
240 },
241 {
242 .section = SECTION_NAME("recv", "Relay-Forward"),
244 .offset = PROCESS_CONF_OFFSET(recv_relay_forward)
245 },
246
247 {
248 .section = SECTION_NAME("send", "Advertise"),
250 .offset = PROCESS_CONF_OFFSET(send_advertise)
251 },
252 {
253 .section = SECTION_NAME("send", "Reply"),
255 .offset = PROCESS_CONF_OFFSET(send_reply)
256 },
257 {
258 .section = SECTION_NAME("send", "Relay-Reply"),
260 .offset = PROCESS_CONF_OFFSET(send_relay_reply)
261 },
262 {
263 .section = SECTION_NAME("send", "Do-Not-Respond"),
265 .offset = PROCESS_CONF_OFFSET(do_not_respond)
266 },
267
268 DYNAMIC_CLIENT_SECTIONS,
269
271};
272
273/*
274 * Debug the packet if requested.
275 */
276static void dhcpv6_packet_debug(request_t *request, fr_packet_t const *packet, fr_pair_list_t const *list, bool received)
277{
278#ifdef WITH_IFINDEX_NAME_RESOLUTION
279 char if_name[IFNAMSIZ];
280#endif
281 char const *module;
282
283 if (!packet) return;
284 if (!RDEBUG_ENABLED) return;
285
286 /*
287 * Looks better without module prefix
288 */
289 module = request->module;
290 request->module = NULL;
291
292 log_request(L_DBG, L_DBG_LVL_1, request, __FILE__, __LINE__, "%s %s XID %08x from %s%pV%s:%i to %s%pV%s:%i "
293#ifdef WITH_IFINDEX_NAME_RESOLUTION
294 "%s%s%s"
295#endif
296 "",
297 received ? "Received" : "Sending",
299 packet->id,
300 packet->socket.inet.src_ipaddr.af == AF_INET6 ? "[" : "",
301 fr_box_ipaddr(packet->socket.inet.src_ipaddr),
302 packet->socket.inet.src_ipaddr.af == AF_INET6 ? "]" : "",
303 packet->socket.inet.src_port,
304 packet->socket.inet.dst_ipaddr.af == AF_INET6 ? "[" : "",
305 fr_box_ipaddr(packet->socket.inet.dst_ipaddr),
306 packet->socket.inet.dst_ipaddr.af == AF_INET6 ? "]" : "",
307 packet->socket.inet.dst_port
308#ifdef WITH_IFINDEX_NAME_RESOLUTION
309 , packet->socket.inet.ifindex ? "via " : "",
310 packet->socket.inet.ifindex ? fr_ifname_from_ifindex(if_name, packet->socket.inet.ifindex) : "",
311 packet->socket.inet.ifindex ? " " : ""
312#endif
313 );
314
315 if (received || request->parent) {
316 log_request_pair_list(L_DBG_LVL_1, request, NULL, list, NULL);
317 } else {
318 log_request_proto_pair_list(L_DBG_LVL_1, request, NULL, list, NULL);
319 }
320
321 request->module = module;
322}
323
324/** Keep a copy of header fields to prevent them being tampered with
325 *
326 */
327static inline CC_HINT(always_inline)
329{
330 fr_pair_t *transaction_id;
332
333 transaction_id = fr_pair_find_by_da(&request->request_pairs, NULL, attr_transaction_id);
334 if (!transaction_id) {
335 REDEBUG("Missing Transaction-ID");
336 return NULL;
337 }
338
339 if (transaction_id->vp_length != DHCPV6_TRANSACTION_ID_LEN) {
340 REDEBUG("Invalid Transaction-ID, expected len %u, got len %zu",
341 DHCPV6_TRANSACTION_ID_LEN, transaction_id->vp_length);
342 return NULL;
343 }
344
346 rctx->transaction_id = fr_pair_copy(rctx, transaction_id);
347
350
351 /*
352 * These should just become straight copies
353 * when the structure pairs are nested.
354 */
355 switch (fr_pair_list_copy_by_ancestor(rctx, &rctx->client_id,
356 &request->request_pairs, attr_client_id)) {
357 case -1:
358 REDEBUG("Error copying Client-ID");
359 error:
360 talloc_free(rctx);
361 return NULL;
362
363 case 0:
364 REDEBUG("Missing Client-ID");
365 goto error;
366
367 default:
368 break;
369 }
370
371 switch (fr_pair_list_copy_by_ancestor(rctx, &rctx->server_id,
372 &request->request_pairs, attr_server_id)) {
373 case -1:
374 REDEBUG("Error copying Server-ID");
375 goto error;
376
377 case 0:
378 if (expect_server_id) {
379 REDEBUG("Missing Server-ID");
380 goto error;
381 }
382 break;
383
384 default:
385 if (!expect_server_id) {
386 REDEBUG("Server-ID should not be present");
387 goto error;
388 }
389 break;
390 }
391
392 return rctx;
393}
394
395/** Validate a solicit/rebind/confirm message
396 *
397 * Servers MUST discard any solicit/rebind/confirm messages that
398 * do not include a Client Identifier option or that do include a
399 * Server Identifier option.
400 */
401RECV(for_any_server)
402{
403 CONF_SECTION *cs;
404 fr_process_state_t const *state;
405 process_dhcpv6_t const *inst = mctx->mi->data;
407
409
410 rctx = dhcpv6_client_fields_store(request, false);
411 if (!rctx) RETURN_MODULE_INVALID;
412
413 UPDATE_STATE_CS(packet);
414
415 return unlang_module_yield_to_section(p_result, request,
416 cs, state->rcode, state->resume,
417 NULL, 0, rctx);
418}
419
420/** Validate a request/renew/decline/release
421 *
422 * Servers MUST discard any received Request message that meet any of
423 * the following conditions:
424 *
425 * - the message does not include a Server Identifier option.
426 *
427 * - the contents of the Server Identifier option do not match the
428 * server's DUID.
429 *
430 * - the message does not include a Client Identifier option.
431 *
432 * Servers MUST discard any received Confirm messages that do not
433 * include a Client Identifier option or that do include a Server
434 * Identifier option.
435 */
436RECV(for_this_server)
437{
438 CONF_SECTION *cs;
439 fr_process_state_t const *state;
440 process_dhcpv6_t const *inst = mctx->mi->data;
442
444
445 rctx = dhcpv6_client_fields_store(request, true);
446 if (!rctx) RETURN_MODULE_INVALID;
447
448 UPDATE_STATE_CS(packet);
449
450 return unlang_module_yield_to_section(p_result, request,
451 cs, state->rcode, state->resume,
452 NULL, 0, rctx);
453}
454
455/** Copy a reply pair back into the response
456 *
457 */
458static inline CC_HINT(always_inline)
459int restore_field(request_t *request, fr_pair_t **to_restore)
460{
461 fr_pair_t *vp;
462 int ret = 0;
463
464 PAIR_VERIFY(*to_restore);
465
466 vp = fr_pair_find_by_da(&request->reply_pairs, NULL, (*to_restore)->da);
467 if (vp) {
468 if (fr_pair_cmp(vp, *to_restore) != 0) {
469 RWDEBUG("&reply.%pP does not match &request.%pP", vp, *to_restore);
470 free:
471 talloc_free(*to_restore);
472 *to_restore = NULL;
473 return ret;
474 }
475 } else if (fr_pair_steal_append(request->reply_ctx, &request->reply_pairs, *to_restore) < 0) {
476 RPERROR("Failed adding %s", (*to_restore)->da->name);
477 ret = -1;
478 goto free;
479 }
480 *to_restore = NULL;
481
482 return 0;
483}
484
485static inline CC_HINT(always_inline)
487{
488 fr_pair_t *vp;
489
490 while ((vp = fr_pair_list_head(to_restore))) {
491 fr_pair_remove(to_restore, vp);
492 if (restore_field(request, &vp) < 0) return -1;
493 }
494
495 return 0;
496}
497
498/** Add a status code if one doesn't already exist
499 *
500 */
501static inline CC_HINT(always_inline)
503{
504 fr_pair_t *vp, *failure_message = NULL;
505 fr_value_box_t const *vb;
506 bool moved_failure_message = false;
507
508 if (!code || !*code) return;
509
510 vb = *code;
511
512 /*
513 * If it's a success save some bytes
514 * in the packet and don't bother
515 * adding the success code unless
516 * explicitly requested to.
517 */
518 if ((vb->vb_uint16 == 0) && !inst->status_code_on_success) return;
519
520 /*
521 * Don't override the user status
522 * code.
523 */
525
526 /*
527 * Move the module failure messages upwards
528 * if requested to by the user.
529 */
530 if (inst->move_failure_message_to_parent && request->parent && (request->parent->dict == request->dict)) {
531 fr_pair_t const *prev = NULL;
532
533 while ((failure_message = fr_pair_find_by_da(&request->request_pairs,
535 MEM(vp = fr_pair_copy(request->parent->request_ctx, failure_message));
536 fr_pair_append(&request->parent->request_pairs, vp);
537
538 prev = fr_pair_remove(&request->request_pairs, failure_message);
539 talloc_free(failure_message);
540 }
541
542 moved_failure_message = true;
543 }
544
545 /*
546 * Concat all the module failure messages
547 * and place them in the status code
548 * message.
549 */
550 if (inst->send_failure_message && !moved_failure_message &&
551 (failure_message = fr_pair_find_by_da(&request->request_pairs, NULL, attr_module_failure_message)) &&
554 fr_sbuff_t sbuff;
555
556 do {
557 /*
558 * Create an aggregation buffer up to
559 * the maximum length of a status
560 * message.
561 */
562 fr_sbuff_init_talloc(vp, &sbuff, &tctx, 1024, UINT16_MAX - 2);
563
564 /*
565 * Best effort... it's probably OK
566 * if we truncate really long messages.
567 */
568 if (unlikely(fr_sbuff_in_bstrncpy(&sbuff, failure_message->vp_strvalue,
569 failure_message->vp_length) < 0)) break;
570 } while ((failure_message = fr_pair_find_by_da(&request->request_pairs, failure_message,
572 (fr_sbuff_in_strcpy_literal(&sbuff, ". ") == 2));
573 fr_sbuff_trim_talloc(&sbuff, SIZE_MAX); /* Fix size */
575 }
576}
577
578/** Restore our copy of the header fields into the reply list
579 *
580 */
581RESUME(send_to_client)
582{
583 process_dhcpv6_t *inst = talloc_get_type_abort(mctx->mi->data, process_dhcpv6_t);
584 process_dhcpv6_client_fields_t *fields = talloc_get_type_abort(mctx->rctx, process_dhcpv6_client_fields_t);
585 fr_process_state_t const *state;
586
587
588 UPDATE_STATE(reply);
589
590 /*
591 * Don't bother adding VPs if we're not going
592 * be responding to the client.
593 */
594 if (state->packet_type[*p_result] == FR_DHCPV6_DO_NOT_RESPOND) return CALL_RESUME(send_generic);
595
596 /*
597 * Add a status code if we have one
598 */
599 status_code_add(inst, request, state->status_codes[*p_result]);
600
601 /*
602 * If we have a status code entry then we'll
603 * be returning something to the client and
604 * need to fill in all these fields
605 */
606 if (unlikely(restore_field(request, &fields->transaction_id) < 0)) {
607 fail:
608 *p_result = RLM_MODULE_FAIL;
609 return CALL_RESUME(send_generic);
610 }
611 if (unlikely(restore_field_list(request, &fields->client_id) < 0)) goto fail;
612 if (unlikely(restore_field_list(request, &fields->server_id) < 0)) goto fail;
613
614 dhcpv6_packet_debug(request, request->reply, &request->reply_pairs, false);
615
616 return CALL_RESUME(send_generic);
617}
618
619/** Record the original hop-count, link-address, peer-address etc...
620 *
621 */
622static inline CC_HINT(always_inline)
624{
625 fr_pair_t *hop_count, *link_address, *peer_address, *interface_id;
627
628 hop_count = fr_pair_find_by_da(&request->request_pairs, NULL, attr_hop_count);
629 if (!hop_count) {
630 REDEBUG("Missing Hop-Count");
631 return NULL;
632 }
633
634 link_address = fr_pair_find_by_da(&request->request_pairs, NULL, attr_relay_link_address);
635 if (!link_address) {
636 REDEBUG("Missing Link-Address");
637 return NULL;
638 }
639
640 peer_address = fr_pair_find_by_da(&request->request_pairs, NULL, attr_relay_peer_address);
641 if (!peer_address) {
642 REDEBUG("Missing Peer-Address");
643 return NULL;
644 }
645
646 interface_id = fr_pair_find_by_da(&request->request_pairs, NULL, attr_interface_id);
647
648 /*
649 * Remember the relay fields
650 */
651 MEM(rctx = talloc_zero(unlang_interpret_frame_talloc_ctx(request), process_dhcpv6_relay_fields_t)); /* Safer to zero the whole thing */
652 MEM(rctx->hop_count = fr_pair_copy(rctx, hop_count));
653 MEM(rctx->link_address = fr_pair_copy(rctx, link_address));
654 MEM(rctx->peer_address = fr_pair_copy(rctx, peer_address));
655 if (interface_id) MEM(rctx->interface_id = fr_pair_copy(rctx, interface_id)); /* Optional */
656
657 return rctx;
658}
659
660/** Ensure we have the necessary pairs from the relay
661 *
662 */
663RECV(from_relay)
664{
665 CONF_SECTION *cs;
666 fr_process_state_t const *state;
667 process_dhcpv6_t const *inst = mctx->mi->data;
669
670 rctx = dhcpv6_relay_fields_store(request);
671 if (!rctx) RETURN_MODULE_INVALID;
672
673 UPDATE_STATE_CS(packet);
674
675 return unlang_module_yield_to_section(p_result, request,
676 cs, state->rcode, state->resume,
677 NULL, 0, rctx);
678}
679
680/** Restore our copy of the header fields into the reply list
681 *
682 */
683RESUME(send_to_relay)
684{
685 process_dhcpv6_t *inst = talloc_get_type_abort(mctx->mi->data, process_dhcpv6_t);
686 process_dhcpv6_relay_fields_t *fields = talloc_get_type_abort(mctx->rctx, process_dhcpv6_relay_fields_t);
687 fr_process_state_t const *state;
688
689 UPDATE_STATE(reply);
690
691 /*
692 * Add a status code if we have one
693 */
694 status_code_add(inst, request, state->status_codes[*p_result]);
695
696 /*
697 * Restore relay fields
698 */
699 if (unlikely(restore_field(request, &fields->hop_count) < 0)) {
700 fail:
701 *p_result = RLM_MODULE_FAIL;
702 return CALL_RESUME(send_generic);
703 }
704 if (unlikely(restore_field(request, &fields->link_address) < 0)) goto fail;
705 if (unlikely(restore_field(request, &fields->peer_address) < 0)) goto fail;
706 if (fields->interface_id && unlikely(restore_field(request, &fields->interface_id) < 0)) goto fail;
707
708 dhcpv6_packet_debug(request, request->reply, &request->reply_pairs, false);
709
710 return CALL_RESUME(send_generic);
711}
712
713/** Main dispatch function
714 *
715 */
716static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
717{
718 fr_process_state_t const *state;
719
721
723 fr_assert(PROCESS_PACKET_CODE_VALID(request->packet->code));
724
725 request->component = "dhcpv6";
726 request->module = NULL;
727 fr_assert(request->dict == dict_dhcpv6);
728
729 UPDATE_STATE(packet);
730
731 if (!state->recv) {
732 REDEBUG("Invalid packet type (%u)", request->packet->code);
734 }
735
736 dhcpv6_packet_debug(request, request->packet, &request->request_pairs, true);
737
738 if (unlikely(request_is_dynamic_client(request))) {
739 return new_client(p_result, mctx, request);
740 }
741
742 return state->recv(p_result, mctx, request);
743}
744
745static int mod_instantiate(module_inst_ctx_t const *mctx)
746{
747 process_dhcpv6_t *inst = talloc_get_type_abort(mctx->mi->data, process_dhcpv6_t);
748
749 inst->server_cs = cf_item_to_section(cf_parent(mctx->mi->conf));
750
751 return 0;
752}
753
754static fr_process_state_t const process_state[] = {
755 /*
756 * A client sends a Solicit message to locate
757 * servers.
758 */
759 [ FR_DHCPV6_SOLICIT ] = {
760 .recv = recv_for_any_server,
761 .resume = resume_recv_generic,
762 .packet_type = {
766 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
767
773 },
774 .status_codes = {
775 /* RLM_MODULE_NOOP - No response */
778 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
779
780 /* RLM_MODULE_FAIL - No response */
781 /* RLM_MODULE_INVALID - No response */
782 /* RLM_MODULE_REJECT - No response */
783 /* RLM_MODULE_DISALLOW - No response */
784 /* RLM_MODULE_NOTFOUND - No response */
785 },
786 .rcode = RLM_MODULE_NOOP,
787 .section_offset = offsetof(process_dhcpv6_sections_t, recv_solicit),
788 },
789
790 /*
791 * A client sends a Request message to request
792 * configuration parameters, including IP
793 * addresses, from a specific server.
794 */
795 [ FR_DHCPV6_REQUEST ] = {
796 .recv = recv_for_this_server,
797 .resume = resume_recv_generic,
798 .packet_type = {
802 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
803
809 },
810 .status_codes = {
814 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
815
821 },
822 .rcode = RLM_MODULE_NOOP,
823 .section_offset = offsetof(process_dhcpv6_sections_t, recv_request),
824 },
825
826 /*
827 * A client sends a Confirm message to any
828 * available server to determine whether the
829 * addresses it was assigned are still appropriate
830 * to the link to which the client is connected.
831 */
832 [ FR_DHCPV6_CONFIRM ] = {
833 .recv = recv_for_any_server,
834 .resume = resume_recv_generic,
835 .packet_type = {
839 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
840
846 },
847
848 /*
849 * When the server receives a Confirm message, the server determines
850 * whether the addresses in the Confirm message are appropriate for the
851 * link to which the client is attached. If all of the addresses in the
852 * Confirm message pass this test, the server returns a status of
853 * Success. If any of the addresses do not pass this test, the server
854 * returns a status of NotOnLink. If the server is unable to perform
855 * this test (for example, the server does not have information about
856 * prefixes on the link to which the client is connected), or there were
857 * no addresses in any of the IAs sent by the client, the server MUST
858 * NOT send a reply to the client.
859 */
860 .status_codes = {
861 /* RLM_MODULE_NOOP - No response */
864 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
865
866 /* RLM_MODULE_FAIL - No response */
867 /* RLM_MODULE_INVALID - No response */
869 /* RLM_MODULE_DISALLOW - No response */
870 /* RLM_MODULE_NOTFOUND - No response */
871 },
872 .rcode = RLM_MODULE_NOOP,
873 .section_offset = offsetof(process_dhcpv6_sections_t, recv_confirm),
874 },
875
876 /*
877 * A client sends a Renew message to the server
878 * that originally provided the client's addresses
879 * and configuration parameters to extend the
880 * lifetimes on the addresses assigned to the
881 * client and to update other configuration
882 * parameters.
883 */
884 [ FR_DHCPV6_RENEW ] = {
885 .recv = recv_for_this_server,
886 .resume = resume_recv_generic,
887 .packet_type = {
891 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
892
898 },
899
900 /*
901 * If the server cannot find a client entry for the IA the server
902 * returns the IA containing no addresses with a Status Code option set
903 * to NoBinding in the Reply message.
904 */
905 .status_codes = {
909 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
910
912 /* RLM_MODULE_INVALID - No response */
916 },
917 .rcode = RLM_MODULE_NOOP,
918 .section_offset = offsetof(process_dhcpv6_sections_t, recv_renew),
919 },
920
921 /*
922 * A client sends a Rebind message to any
923 * available server to extend the lifetimes on the
924 * addresses assigned to the client and to update
925 * other configuration parameters; this message is
926 * sent after a client receives no response to a
927 * Renew message.
928 */
929 [ FR_DHCPV6_REBIND ] = {
930 .recv = recv_for_any_server,
931 .resume = resume_recv_generic,
932 .packet_type = {
936 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
937
943 },
944 .status_codes = {
948 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
949
951 /* RLM_MODULE_INVALID - No response */
955 },
956 .rcode = RLM_MODULE_NOOP,
957 .section_offset = offsetof(process_dhcpv6_sections_t, recv_rebind),
958 },
959 /*
960 * A client sends an Information-request
961 * message to a server to request configuration
962 * parameters without the assignment of any IP
963 * addresses to the client.
964 */
966 .recv = recv_for_any_server,
967 .resume = resume_recv_generic,
968 .packet_type = {
972 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
973
979 },
980 .status_codes = {
984 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
985
987 /* RLM_MODULE_INVALID - No response */
991 },
992 .rcode = RLM_MODULE_NOOP,
993 .section_offset = offsetof(process_dhcpv6_sections_t, recv_information_request),
994 },
995 /*
996 * A client sends a Release message to the server
997 * that assigned addresses to the client to
998 * indicate that the client will no longer use one
999 * or more of the assigned addresses.
1000 */
1001 [ FR_DHCPV6_RELEASE ] = {
1002 .recv = recv_for_this_server,
1003 .resume = resume_recv_generic,
1004 .packet_type = {
1008 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
1009
1015 },
1016 .status_codes = {
1020 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
1021
1023 /* RLM_MODULE_INVALID - No response */
1027 },
1028 .rcode = RLM_MODULE_NOOP,
1029
1030 .section_offset = offsetof(process_dhcpv6_sections_t, recv_release),
1031 },
1032 /*
1033 *
1034 * A client sends a Decline message to a server to
1035 * indicate that the client has determined that
1036 * one or more addresses assigned by the server
1037 * are already in use on the link to which the
1038 * client is connected.
1039 */
1040 [ FR_DHCPV6_DECLINE ] = {
1041 .recv = recv_for_this_server, /* Need to check for attributes */
1042 .resume = resume_recv_generic,
1043 .packet_type = {
1047 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
1048
1054 },
1055 .status_codes = {
1059 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
1060
1062 /* RLM_MODULE_INVALID - No response */
1066 },
1067 .rcode = RLM_MODULE_NOOP,
1068 .section_offset = offsetof(process_dhcpv6_sections_t, recv_decline),
1069 },
1070 /*
1071 * A relay agent sends a Relay-forward message
1072 * to relay messages to servers, either directly
1073 * or through another relay agent. The received
1074 * message, either a client message or a
1075 * Relay-forward message from another relay
1076 * agent, is encapsulated in an option in the
1077 * Relay-forward message.
1078 */
1080 .recv = recv_from_relay,
1081 .resume = resume_recv_generic,
1082 .packet_type = {
1086 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
1087
1093 },
1094 .status_codes = {
1098 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
1099
1101 /* RLM_MODULE_INVALID - No response */
1105 },
1106 .rcode = RLM_MODULE_NOOP,
1107 .section_offset = offsetof(process_dhcpv6_sections_t, recv_relay_forward),
1108 },
1109 /*
1110 * A server sends an Advertise message to indicate
1111 * that it is available for DHCP service, in
1112 * response to a Solicit message received from a
1113 * client.
1114 */
1115 [ FR_DHCPV6_ADVERTISE ] = {
1116 .send = send_generic,
1117 .resume = resume_send_to_client,
1118 .packet_type = {
1124 },
1125 .status_codes = {
1129 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
1130
1131 /* RLM_MODULE_FAIL - No response */
1132 /* RLM_MODULE_INVALID - No response */
1133 /* RLM_MODULE_REJECT - No response */
1134 /* RLM_MODULE_DISALLOW - No response */
1135 /* RLM_MODULE_NOTFOUND - No response */
1136 },
1137 .rcode = RLM_MODULE_NOOP,
1138 .section_offset = offsetof(process_dhcpv6_sections_t, send_advertise),
1139 },
1140 /*
1141 * A server sends a Reply message containing
1142 * assigned addresses and configuration parameters
1143 * in response to a Solicit, Request, Renew,
1144 * Rebind message received from a client. A
1145 * server sends a Reply message containing
1146 * configuration parameters in response to an
1147 * Information-request message. A server sends a
1148 * Reply message in response to a Confirm message
1149 * confirming or denying that the addresses
1150 * assigned to the client are appropriate to the
1151 * link to which the client is connected. A
1152 * server sends a Reply message to acknowledge
1153 * receipt of a Release or Decline message.
1154 */
1155 [ FR_DHCPV6_REPLY ] = {
1156 .send = send_generic,
1157 .resume = resume_send_to_client,
1158 .packet_type = {
1159
1165 },
1166 .status_codes = {
1170 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
1171
1173 /* RLM_MODULE_INVALID - No response */
1177 },
1178 .rcode = RLM_MODULE_NOOP,
1179 .section_offset = offsetof(process_dhcpv6_sections_t, send_reply),
1180 },
1181 /*
1182 * A server sends a Relay-reply message to a relay
1183 * agent containing a message that the relay
1184 * agent delivers to a client. The Relay-reply
1185 * message may be relayed by other relay agents
1186 * for delivery to the destination relay agent.
1187 * The server encapsulates the client message as
1188 * an option in the Relay-reply message, which the
1189 * relay agent extracts and relays to the client.
1190 */
1191 [ FR_DHCPV6_RELAY_REPLY ] = {
1192 .send = send_generic,
1193 .resume = resume_send_to_relay,
1194 .packet_type = {
1200 },
1201 .status_codes = {
1205 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
1206
1208 /* RLM_MODULE_INVALID - No response */
1212 },
1213 .rcode = RLM_MODULE_NOOP,
1214 .section_offset = offsetof(process_dhcpv6_sections_t, send_relay_reply),
1215 },
1216
1218 .send = send_generic,
1219 .resume = resume_send_generic,
1220 .packet_type = {
1225
1231 },
1232 .rcode = RLM_MODULE_NOOP,
1233 .section_offset = offsetof(process_dhcpv6_sections_t, do_not_respond),
1234 }
1235};
1236
1239 .common = {
1240 .magic = MODULE_MAGIC_INIT,
1241 .name = "dhcpv6",
1243 .inst_size = sizeof(process_dhcpv6_t),
1244
1246 },
1247 .process = mod_process,
1248 .compile_list = compile_list,
1249 .dict = &dict_dhcpv6
1250};
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
#define unlikely(_x)
Definition build.h:381
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:642
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:268
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:579
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition cf_util.c:684
#define cf_parent(_cf)
Definition cf_util.h:101
#define MEM(x)
Definition debug.h:36
@ FR_DHCPV6_RELEASE
Definition dhcpv6.h:75
@ FR_DHCPV6_DECLINE
Definition dhcpv6.h:76
@ FR_DHCPV6_ADVERTISE
Definition dhcpv6.h:69
@ FR_DHCPV6_DO_NOT_RESPOND
Definition dhcpv6.h:104
@ FR_DHCPV6_REBIND
Definition dhcpv6.h:73
@ FR_DHCPV6_REPLY
Definition dhcpv6.h:74
@ FR_DHCPV6_CONFIRM
Definition dhcpv6.h:71
@ FR_DHCPV6_SOLICIT
Definition dhcpv6.h:68
@ FR_DHCPV6_RENEW
Definition dhcpv6.h:72
@ FR_DHCPV6_INFORMATION_REQUEST
Definition dhcpv6.h:78
@ FR_DHCPV6_REQUEST
Definition dhcpv6.h:70
@ FR_DHCPV6_RELAY_FORWARD
Definition dhcpv6.h:79
@ FR_DHCPV6_RELAY_REPLY
Definition dhcpv6.h:80
#define DHCPV6_TRANSACTION_ID_LEN
Definition dhcpv6.h:37
fr_value_box_t const ** out
Enumeration value.
Definition dict.h:257
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:268
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:281
Specifies an attribute which must be present for the module to function.
Definition dict.h:267
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:280
Specifies a value which must be present for the module to function.
Definition dict.h:256
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
free(array)
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
Definition interpret.c:1403
static fr_dict_t const * dict_freeradius
Definition base.c:37
fr_dict_attr_t const * attr_packet_type
Definition base.c:93
void log_request_proto_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a list of protocol fr_pair_ts.
Definition log.c:854
void log_request(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Marshal variadic log arguments into a va_list and pass to normal logging functions.
Definition log.c:612
void log_request_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a fr_pair_list_t.
Definition log.c:830
#define RWDEBUG(fmt,...)
Definition log.h:361
#define RPERROR(fmt,...)
Definition log.h:302
talloc_free(reap)
@ L_DBG_LVL_1
Highest priority debug messages (-x).
Definition log.h:70
@ L_DBG
Only displayed when debugging is enabled.
Definition log.h:59
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_STRUCT
like TLV, but without T or L, and fixed-width children
@ FR_TYPE_IPV6_ADDR
128 Bit IPv6 Address.
@ FR_TYPE_OCTETS
Raw octets.
unlang_mod_actions_t const mod_actions_postauth
Definition mod_action.c:88
unlang_mod_action_t actions[RLM_MODULE_NUMCODES]
Definition mod_action.h:62
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
module_instance_t * mi
Instance of the module being instantiated.
Definition module_ctx.h:51
Temporary structure to hold arguments for module calls.
Definition module_ctx.h:41
Temporary structure to hold arguments for instantiation calls.
Definition module_ctx.h:50
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
Definition pair.c:693
int fr_pair_cmp(fr_pair_t const *a, fr_pair_t const *b)
Compare two pairs, using the operator from "a".
Definition pair.c:1969
int fr_pair_value_bstrndup_shallow(fr_pair_t *vp, char const *src, size_t len, bool tainted)
Assign a string to a "string" type value pair.
Definition pair.c:2835
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
Definition pair.c:1345
int fr_pair_list_copy_by_ancestor(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from, fr_dict_attr_t const *parent_da)
Duplicate pairs in a list where the da is a descendant of parent_da.
Definition pair.c:2455
int fr_pair_steal_append(TALLOC_CTX *list_ctx, fr_pair_list_t *list, fr_pair_t *vp)
Change a vp's talloc ctx and insert it into a new list.
Definition pair.c:546
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
Definition pair.c:46
fr_pair_t * fr_pair_copy(TALLOC_CTX *ctx, fr_pair_t const *vp)
Copy a single valuepair.
Definition pair.c:489
static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition base.c:179
static const virtual_server_compile_t compile_list[]
Definition base.c:205
static fr_process_state_t const process_state[]
Definition base.c:68
#define PROCESS_PACKET_CODE_VALID
Definition base.c:64
static fr_dict_attr_t const * attr_module_failure_message
Definition base.c:36
CONF_SECTION * send_advertise
Definition base.c:58
CONF_SECTION * recv_information_request
Definition base.c:55
fr_pair_list_t client_id
Definition base.c:104
static fr_dict_attr_t const * attr_hop_count
Definition base.c:129
CONF_SECTION * send_reply
Definition base.c:59
static fr_dict_attr_t const * attr_status_code_message
Definition base.c:136
CONF_SECTION * recv_solicit
Definition base.c:46
static fr_dict_attr_t const * attr_status_code_value
Definition base.c:135
static fr_dict_attr_t const * attr_relay_link_address
Definition base.c:132
static process_dhcpv6_client_fields_t * dhcpv6_client_fields_store(request_t *request, bool expect_server_id)
Keep a copy of header fields to prevent them being tampered with.
Definition base.c:328
bool move_failure_message_to_parent
If true, and a parent exists, and the parent is a DHCPv6 request, all module failure messages will ge...
Definition base.c:89
CONF_SECTION * recv_request
Definition base.c:47
static int restore_field_list(request_t *request, fr_pair_list_t *to_restore)
Definition base.c:486
fr_dict_autoload_t process_dhcpv6_dict[]
Definition base.c:121
fr_dict_enum_autoload_t process_dhcpv6_dict_enum[]
Definition base.c:163
static fr_value_box_t const * enum_status_code_success
Definition base.c:157
static void status_code_add(process_dhcpv6_t const *inst, request_t *request, fr_value_box_t const **code)
Add a status code if one doesn't already exist.
Definition base.c:502
CONF_SECTION * server_cs
Our virtual server.
Definition base.c:70
static int restore_field(request_t *request, fr_pair_t **to_restore)
Copy a reply pair back into the response.
Definition base.c:459
CONF_SECTION * do_not_respond
Definition base.c:62
static fr_value_box_t const * enum_status_code_no_binding
Definition base.c:160
bool status_code_on_success
Controls whether we add a status-code option to outbound packets if the status code would be 0.
Definition base.c:73
CONF_SECTION * recv_decline
Definition base.c:52
static fr_dict_attr_t const * attr_interface_id
Definition base.c:130
static fr_dict_attr_t const * attr_server_id
Definition base.c:128
CONF_SECTION * recv_relay_forward
Definition base.c:56
CONF_SECTION * deny_client
Definition base.c:66
static fr_value_box_t const * enum_status_code_unspec_fail
Definition base.c:158
CONF_SECTION * recv_rebind
Definition base.c:50
static conf_parser_t dhcpv6_process_config[]
Definition base.c:188
CONF_SECTION * recv_release
Definition base.c:51
CONF_SECTION * recv_renew
Definition base.c:49
static void dhcpv6_packet_debug(request_t *request, fr_packet_t const *packet, fr_pair_list_t const *list, bool received)
Definition base.c:276
CONF_SECTION * new_client
Definition base.c:64
fr_dict_attr_autoload_t process_dhcpv6_dict_attr[]
Definition base.c:141
CONF_SECTION * add_client
Definition base.c:65
bool send_failure_message
If true, all instances of Module-Failure-Message in the request are concatenated and returned in the ...
Definition base.c:79
CONF_SECTION * recv_reconfigure
Definition base.c:53
static fr_dict_t const * dict_dhcpv6
Definition base.c:117
static process_dhcpv6_relay_fields_t * dhcpv6_relay_fields_store(request_t *request)
Record the original hop-count, link-address, peer-address etc...
Definition base.c:623
fr_pair_list_t server_id
Definition base.c:105
static fr_dict_attr_t const * attr_transaction_id
Definition base.c:134
static fr_dict_attr_t const * attr_client_id
Definition base.c:127
static fr_value_box_t const * enum_status_code_not_on_link
Definition base.c:159
CONF_SECTION * recv_confirm
Definition base.c:48
static int mod_instantiate(module_inst_ctx_t const *mctx)
Definition base.c:745
process_dhcpv6_sections_t sections
Pointers to various config sections we need to execute.
Definition base.c:71
CONF_SECTION * send_relay_reply
Definition base.c:60
static fr_dict_attr_t const * attr_relay_peer_address
Definition base.c:133
RECV(for_any_server)
Validate a solicit/rebind/confirm message.
Definition base.c:401
fr_process_module_t process_dhcpv6
Definition base.c:1238
Records fields from the original request so we have a known good copy.
Definition base.c:102
Records fields from the original relay-request so we have a known good copy.
Definition base.c:110
#define PROCESS_TRACE
Trace each state function as it's entered.
Definition process.h:65
module_t common
Common fields for all loadable modules.
Definition process.h:55
Common public symbol definition for all process modules.
Definition process.h:54
char const * fr_dhcpv6_packet_names[FR_DHCPV6_CODE_MAX]
Definition base.c:71
#define fr_assert(_expr)
Definition rad_assert.h:38
#define REDEBUG(fmt,...)
Definition radclient.h:52
#define RDEBUG_ENABLED()
Definition radclient.h:49
static void send_reply(int sockfd, fr_channel_data_t *reply)
#define RETURN_MODULE_INVALID
Definition rcode.h:59
#define RETURN_MODULE_FAIL
Definition rcode.h:56
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:40
@ RLM_MODULE_INVALID
The module considers the request invalid.
Definition rcode.h:45
@ RLM_MODULE_OK
The module is OK, continue.
Definition rcode.h:43
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition rcode.h:42
@ RLM_MODULE_DISALLOW
Reject the request (user is locked out).
Definition rcode.h:46
@ RLM_MODULE_REJECT
Immediately reject the request.
Definition rcode.h:41
@ RLM_MODULE_NOTFOUND
User not found.
Definition rcode.h:47
@ RLM_MODULE_UPDATED
OK (pairs modified).
Definition rcode.h:49
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
Definition rcode.h:48
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
Definition rcode.h:44
#define request_is_dynamic_client(_x)
Definition request.h:162
static int instantiate(module_inst_ctx_t const *mctx)
Definition rlm_rest.c:1310
int fr_sbuff_trim_talloc(fr_sbuff_t *sbuff, size_t len)
Trim a talloced sbuff to the minimum length required to represent the contained string.
Definition sbuff.c:419
ssize_t fr_sbuff_in_bstrncpy(fr_sbuff_t *sbuff, char const *str, size_t len)
Copy bytes into the sbuff up to the first \0.
Definition sbuff.c:1480
#define fr_sbuff_start(_sbuff_or_marker)
#define fr_sbuff_used(_sbuff_or_marker)
#define fr_sbuff_in_strcpy_literal(_sbuff, _str)
Talloc sbuff extension structure.
Definition sbuff.h:139
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
Definition section.h:40
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:329
void * data
Module's instance data.
Definition module.h:271
conf_parser_t const * config
How to convert a CONF_SECTION to a module instance.
Definition module.h:198
#define pair_update_reply(_attr, _da)
Return or allocate a fr_pair_t in the reply list.
Definition pair.h:129
unlang_action_t unlang_module_yield_to_section(rlm_rcode_t *p_result, request_t *request, CONF_SECTION *subcs, rlm_rcode_t default_rcode, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
Definition module.c:248
eap_aka_sim_process_conf_t * inst
#define RESUME(_x)
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
#define talloc_get_type_abort_const
Definition talloc.h:282
unsigned int code
Packet code (type).
Definition packet.h:61
fr_socket_t socket
This packet was received on.
Definition packet.h:57
int id
Packet ID (used to link requests/responses).
Definition packet.h:60
#define PAIR_VERIFY(_x)
Definition pair.h:191
fr_pair_t * fr_pair_remove(fr_pair_list_t *list, fr_pair_t *vp)
Remove fr_pair_t from a list without freeing.
Definition pair_inline.c:94
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
Definition pair_inline.c:43
int af
AF_INET, AF_INET6, or AF_UNIX.
Definition socket.h:78
int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src)
Copy value data verbatim duplicating any buffers.
Definition value.c:3740
#define fr_box_ipaddr(_val)
Definition value.h:294
#define COMPILE_TERMINATOR
section_name_t const * section
Identifier for the section.
Processing sections which are allowed in this virtual server.