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: c4147e70659426c81e86665e69690318fc3e6a09 $
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 */
108
109/** Records fields from the original relay-request so we have a known good copy
110 */
117
118static fr_dict_t const *dict_dhcpv6;
120
123 { .out = &dict_dhcpv6, .proto = "dhcpv6" },
124 { .out = &dict_freeradius, .proto = "freeradius" },
125 { NULL }
126};
127
138
140
143 { .out = &attr_client_id, .name = "Client-ID", .type = FR_TYPE_STRUCT, .dict = &dict_dhcpv6 },
144 { .out = &attr_hop_count, .name = "Hop-Count", .type = FR_TYPE_UINT8, .dict = &dict_dhcpv6 },
145 { .out = &attr_interface_id, .name = "Interface-ID", .type = FR_TYPE_OCTETS, .dict = &dict_dhcpv6 },
146 { .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_dhcpv6 },
147 { .out = &attr_relay_link_address, .name = "Relay-Link-Address", .type = FR_TYPE_IPV6_ADDR, .dict = &dict_dhcpv6 },
148 { .out = &attr_relay_peer_address, .name = "Relay-Peer-Address", .type = FR_TYPE_IPV6_ADDR, .dict = &dict_dhcpv6 },
149 { .out = &attr_server_id, .name = "Server-ID", .type = FR_TYPE_STRUCT, .dict = &dict_dhcpv6 },
150 { .out = &attr_status_code_value, .name = "Status-Code.Value", .type = FR_TYPE_UINT16, .dict = &dict_dhcpv6 },
151 { .out = &attr_status_code_message, .name = "Status-Code.Message", .type = FR_TYPE_STRING, .dict = &dict_dhcpv6 },
152 { .out = &attr_transaction_id, .name = "Transaction-Id", .type = FR_TYPE_OCTETS, .dict = &dict_dhcpv6 },
153
154 { .out = &attr_module_failure_message, .name = "Module-Failure-Message", .type = FR_TYPE_STRING, .dict = &dict_freeradius },
155 { NULL }
156};
157
162
165 { .out = &enum_status_code_success, .name = "success", .attr = &attr_status_code_value },
166 { .out = &enum_status_code_unspec_fail, .name = "UnspecFail", .attr = &attr_status_code_value },
167 { .out = &enum_status_code_not_on_link, .name = "NotOnLink", .attr = &attr_status_code_value },
168 { .out = &enum_status_code_no_binding, .name = "NoBinding", .attr = &attr_status_code_value },
169 { NULL }
170};
171
172#define FR_DHCPV6_PROCESS_CODE_VALID(_x) (FR_DHCPV6_PACKET_CODE_VALID(_x) || (_x == FR_DHCPV6_DO_NOT_RESPOND))
173
174#define PROCESS_PACKET_TYPE fr_dhcpv6_packet_code_t
175#define PROCESS_CODE_MAX FR_DHCPV6_CODE_MAX
176#define PROCESS_CODE_DO_NOT_RESPOND FR_DHCPV6_DO_NOT_RESPOND
177#define PROCESS_PACKET_CODE_VALID FR_DHCPV6_PROCESS_CODE_VALID
178#define PROCESS_INST process_dhcpv6_t
179#define PROCESS_RCTX process_dhcpv6_rctx_t
180#define PROCESS_CODE_DYNAMIC_CLIENT FR_DHCPV6_REPLY
181
182/*
183 * DHCPv6 is nonstandard in that we reply
184 * to the majority of requests, but include a
185 * status code to indicate failures.
186 */
187#define PROCESS_STATE_EXTRA_FIELDS fr_value_box_t const **status_codes[RLM_MODULE_NUMCODES];
188#include <freeradius-devel/server/process.h>
189
191 { FR_CONF_OFFSET("status_code_on_success", process_dhcpv6_t, status_code_on_success), .dflt = "no" },
192 { FR_CONF_OFFSET("send_failure_message", process_dhcpv6_t, send_failure_message), .dflt = "no" },
193 { FR_CONF_OFFSET("move_failure_message_to_parent", process_dhcpv6_t, move_failure_message_to_parent), .dflt = "yes" },
195};
196
198 {
199 .section = SECTION_NAME("recv", "Solicit"),
200 .actions = &mod_actions_postauth,
201 .offset = PROCESS_CONF_OFFSET(recv_solicit)
202 },
203 {
204 .section = SECTION_NAME("recv", "Request"),
206 .offset = PROCESS_CONF_OFFSET(recv_request)
207 },
208 {
209 .section = SECTION_NAME("recv", "Confirm"),
211 .offset = PROCESS_CONF_OFFSET(recv_confirm)
212 },
213 {
214 .section = SECTION_NAME("recv", "Renew"),
216 .offset = PROCESS_CONF_OFFSET(recv_renew)
217 },
218 {
219 .section = SECTION_NAME("recv", "Rebind"),
221 .offset = PROCESS_CONF_OFFSET(recv_rebind)
222 },
223 {
224 .section = SECTION_NAME("recv", "Release"),
226 .offset = PROCESS_CONF_OFFSET(recv_release)
227 },
228 {
229 .section = SECTION_NAME("recv", "Decline"),
231 .offset = PROCESS_CONF_OFFSET(recv_decline)
232 },
233 {
234 .section = SECTION_NAME("recv", "Reconfigure"),
236 .offset = PROCESS_CONF_OFFSET(recv_reconfigure)
237 },
238 {
239 .section = SECTION_NAME("recv", "Information-Request"),
241 .offset = PROCESS_CONF_OFFSET(recv_information_request)
242 },
243 {
244 .section = SECTION_NAME("recv", "Relay-Forward"),
246 .offset = PROCESS_CONF_OFFSET(recv_relay_forward)
247 },
248
249 {
250 .section = SECTION_NAME("send", "Advertise"),
252 .offset = PROCESS_CONF_OFFSET(send_advertise)
253 },
254 {
255 .section = SECTION_NAME("send", "Reply"),
258 },
259 {
260 .section = SECTION_NAME("send", "Relay-Reply"),
262 .offset = PROCESS_CONF_OFFSET(send_relay_reply)
263 },
264 {
265 .section = SECTION_NAME("send", "Do-Not-Respond"),
267 .offset = PROCESS_CONF_OFFSET(do_not_respond)
268 },
269
270 DYNAMIC_CLIENT_SECTIONS,
271
273};
274
275/*
276 * Debug the packet if requested.
277 */
278static void dhcpv6_packet_debug(request_t *request, fr_packet_t const *packet, fr_pair_list_t const *list, bool received)
279{
280#ifdef WITH_IFINDEX_NAME_RESOLUTION
281 char if_name[IFNAMSIZ];
282#endif
283 char const *module;
284
285 if (!packet) return;
286 if (!RDEBUG_ENABLED) return;
287
288 /*
289 * Looks better without module prefix
290 */
291 module = request->module;
292 request->module = NULL;
293
294 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 "
295#ifdef WITH_IFINDEX_NAME_RESOLUTION
296 "%s%s%s"
297#endif
298 "",
299 received ? "Received" : "Sending",
301 packet->id,
302 packet->socket.inet.src_ipaddr.af == AF_INET6 ? "[" : "",
303 fr_box_ipaddr(packet->socket.inet.src_ipaddr),
304 packet->socket.inet.src_ipaddr.af == AF_INET6 ? "]" : "",
305 packet->socket.inet.src_port,
306 packet->socket.inet.dst_ipaddr.af == AF_INET6 ? "[" : "",
307 fr_box_ipaddr(packet->socket.inet.dst_ipaddr),
308 packet->socket.inet.dst_ipaddr.af == AF_INET6 ? "]" : "",
309 packet->socket.inet.dst_port
310#ifdef WITH_IFINDEX_NAME_RESOLUTION
311 , packet->socket.inet.ifindex ? "via " : "",
312 packet->socket.inet.ifindex ? fr_ifname_from_ifindex(if_name, packet->socket.inet.ifindex) : "",
313 packet->socket.inet.ifindex ? " " : ""
314#endif
315 );
316
317 if (received || request->parent) {
318 log_request_pair_list(L_DBG_LVL_1, request, NULL, list, NULL);
319 } else {
320 log_request_proto_pair_list(L_DBG_LVL_1, request, NULL, list, NULL);
321 }
322
323 request->module = module;
324}
325
326/** Keep a copy of header fields to prevent them being tampered with
327 *
328 */
329static inline CC_HINT(always_inline)
330int dhcpv6_client_fields_store(request_t *request, process_dhcpv6_rctx_t *rctx, bool expect_server_id)
331{
332 fr_pair_t *transaction_id;
333
334 transaction_id = fr_pair_find_by_da(&request->request_pairs, NULL, attr_transaction_id);
335 if (!transaction_id) {
336 REDEBUG("Missing Transaction-ID");
337 return -1;
338 }
339
340 if (transaction_id->vp_length != DHCPV6_TRANSACTION_ID_LEN) {
341 REDEBUG("Invalid Transaction-ID, expected len %u, got len %zu",
342 DHCPV6_TRANSACTION_ID_LEN, transaction_id->vp_length);
343 return -1;
344 }
345
346 rctx->transaction_id = fr_pair_copy(rctx, transaction_id);
347
348 fr_pair_list_init(&rctx->client_id);
349 fr_pair_list_init(&rctx->server_id);
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 -1;
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 0;
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;
406 process_dhcpv6_rctx_t *rctx = talloc_get_type_abort(mctx->rctx, process_dhcpv6_rctx_t);
407
409
410 if (dhcpv6_client_fields_store(request, rctx, false) < 0) RETURN_UNLANG_INVALID;
411
412 UPDATE_STATE_CS(packet);
413
414 return unlang_module_yield_to_section(RESULT_P, request,
415 cs, state->default_rcode, state->resume,
416 NULL, 0, rctx);
417}
418
419/** Validate a request/renew/decline/release
420 *
421 * Servers MUST discard any received Request message that meet any of
422 * the following conditions:
423 *
424 * - the message does not include a Server Identifier option.
425 *
426 * - the contents of the Server Identifier option do not match the
427 * server's DUID.
428 *
429 * - the message does not include a Client Identifier option.
430 *
431 * Servers MUST discard any received Confirm messages that do not
432 * include a Client Identifier option or that do include a Server
433 * Identifier option.
434 */
435RECV(for_this_server)
436{
437 CONF_SECTION *cs;
438 fr_process_state_t const *state;
439 process_dhcpv6_t const *inst = mctx->mi->data;
440 process_dhcpv6_rctx_t *rctx = talloc_get_type_abort(mctx->rctx, process_dhcpv6_rctx_t);
441
443
444 if (dhcpv6_client_fields_store(request, rctx, true) < 0) RETURN_UNLANG_INVALID;
445
446 UPDATE_STATE_CS(packet);
447
448 return unlang_module_yield_to_section(RESULT_P, request,
449 cs, state->default_rcode, state->resume,
450 NULL, 0, rctx);
451}
452
453/** Copy a reply pair back into the response
454 *
455 */
456static inline CC_HINT(always_inline)
457int restore_field(request_t *request, fr_pair_t **to_restore)
458{
459 fr_pair_t *vp;
460 int ret = 0;
461
462 PAIR_VERIFY(*to_restore);
463
464 vp = fr_pair_find_by_da(&request->reply_pairs, NULL, (*to_restore)->da);
465 if (vp) {
466 if (fr_pair_cmp(vp, *to_restore) != 0) {
467 RWDEBUG("reply.%pP does not match request.%pP", vp, *to_restore);
468 free:
469 talloc_free(*to_restore);
470 *to_restore = NULL;
471 return ret;
472 }
473 } else if (fr_pair_steal_append(request->reply_ctx, &request->reply_pairs, *to_restore) < 0) {
474 RPERROR("Failed adding %s", (*to_restore)->da->name);
475 ret = -1;
476 goto free;
477 }
478 *to_restore = NULL;
479
480 return 0;
481}
482
483static inline CC_HINT(always_inline)
485{
486 fr_pair_t *vp;
487
488 while ((vp = fr_pair_list_head(to_restore))) {
489 fr_pair_remove(to_restore, vp);
490 if (restore_field(request, &vp) < 0) return -1;
491 }
492
493 return 0;
494}
495
496/** Add a status code if one doesn't already exist
497 *
498 */
499static inline CC_HINT(always_inline)
501{
502 fr_pair_t *vp, *failure_message = NULL;
503 fr_value_box_t const *vb;
504 bool moved_failure_message = false;
505
506 if (!code || !*code) return;
507
508 vb = *code;
509
510 /*
511 * If it's a success save some bytes
512 * in the packet and don't bother
513 * adding the success code unless
514 * explicitly requested to.
515 */
516 if ((vb->vb_uint16 == 0) && !inst->status_code_on_success) return;
517
518 /*
519 * Don't override the user status
520 * code.
521 */
523
524 /*
525 * Move the module failure messages upwards
526 * if requested to by the user.
527 */
528 if (inst->move_failure_message_to_parent && request->parent && (request->parent->proto_dict == request->proto_dict)) {
529 fr_pair_t const *prev = NULL;
530
531 while ((failure_message = fr_pair_find_by_da(&request->request_pairs,
533 MEM(vp = fr_pair_copy(request->parent->request_ctx, failure_message));
534 fr_pair_append(&request->parent->request_pairs, vp);
535
536 prev = fr_pair_remove(&request->request_pairs, failure_message);
537 talloc_free(failure_message);
538 }
539
540 moved_failure_message = true;
541 }
542
543 /*
544 * Concat all the module failure messages
545 * and place them in the status code
546 * message.
547 */
548 if (inst->send_failure_message && !moved_failure_message &&
549 (failure_message = fr_pair_find_by_da(&request->request_pairs, NULL, attr_module_failure_message)) &&
552 fr_sbuff_t sbuff;
553
554 do {
555 /*
556 * Create an aggregation buffer up to
557 * the maximum length of a status
558 * message.
559 */
560 fr_sbuff_init_talloc(vp, &sbuff, &tctx, 1024, UINT16_MAX - 2);
561
562 /*
563 * Best effort... it's probably OK
564 * if we truncate really long messages.
565 */
566 if (unlikely(fr_sbuff_in_bstrncpy(&sbuff, failure_message->vp_strvalue,
567 failure_message->vp_length) < 0)) break;
568 } while ((failure_message = fr_pair_find_by_da(&request->request_pairs, failure_message,
570 (fr_sbuff_in_strcpy_literal(&sbuff, ". ") == 2));
571 fr_sbuff_trim_talloc(&sbuff, SIZE_MAX); /* Fix size */
573 }
574}
575
576/** Restore our copy of the header fields into the reply list
577 *
578 */
579RESUME(send_to_client)
580{
581 process_dhcpv6_t *inst = talloc_get_type_abort(mctx->mi->data, process_dhcpv6_t);
582 process_dhcpv6_rctx_t *fields = talloc_get_type_abort(mctx->rctx, process_dhcpv6_rctx_t);
583 fr_process_state_t const *state;
584
585
586 UPDATE_STATE(reply);
587
588 /*
589 * Don't bother adding VPs if we're not going
590 * be responding to the client.
591 */
592 if (state->packet_type[RESULT_RCODE] == FR_DHCPV6_DO_NOT_RESPOND) return CALL_RESUME(send_generic);
593
594 /*
595 * Add a status code if we have one
596 */
597 status_code_add(inst, request, state->status_codes[RESULT_RCODE]);
598
599 /*
600 * If we have a status code entry then we'll
601 * be returning something to the client and
602 * need to fill in all these fields
603 */
604 if (unlikely(restore_field(request, &fields->transaction_id) < 0)) {
605 fail:
606 p_result->rcode = RLM_MODULE_FAIL;
607 return CALL_RESUME(send_generic);
608 }
609 if (unlikely(restore_field_list(request, &fields->client_id) < 0)) goto fail;
610 if (unlikely(restore_field_list(request, &fields->server_id) < 0)) goto fail;
611
612 dhcpv6_packet_debug(request, request->reply, &request->reply_pairs, false);
613
614 return CALL_RESUME(send_generic);
615}
616
617/** Record the original hop-count, link-address, peer-address etc...
618 *
619 */
620static inline CC_HINT(always_inline)
622{
623 fr_pair_t *hop_count, *link_address, *peer_address, *interface_id;
625
626 hop_count = fr_pair_find_by_da(&request->request_pairs, NULL, attr_hop_count);
627 if (!hop_count) {
628 REDEBUG("Missing Hop-Count");
629 return NULL;
630 }
631
632 link_address = fr_pair_find_by_da(&request->request_pairs, NULL, attr_relay_link_address);
633 if (!link_address) {
634 REDEBUG("Missing Link-Address");
635 return NULL;
636 }
637
638 peer_address = fr_pair_find_by_da(&request->request_pairs, NULL, attr_relay_peer_address);
639 if (!peer_address) {
640 REDEBUG("Missing Peer-Address");
641 return NULL;
642 }
643
644 interface_id = fr_pair_find_by_da(&request->request_pairs, NULL, attr_interface_id);
645
646 /*
647 * Remember the relay fields
648 */
649 MEM(rctx = talloc_zero(unlang_interpret_frame_talloc_ctx(request), process_dhcpv6_relay_fields_t)); /* Safer to zero the whole thing */
650 MEM(rctx->hop_count = fr_pair_copy(rctx, hop_count));
651 MEM(rctx->link_address = fr_pair_copy(rctx, link_address));
652 MEM(rctx->peer_address = fr_pair_copy(rctx, peer_address));
653 if (interface_id) MEM(rctx->interface_id = fr_pair_copy(rctx, interface_id)); /* Optional */
654
655 return rctx;
656}
657
658/** Ensure we have the necessary pairs from the relay
659 *
660 */
661RECV(from_relay)
662{
663 CONF_SECTION *cs;
664 fr_process_state_t const *state;
665 process_dhcpv6_t const *inst = mctx->mi->data;
667
668 rctx = dhcpv6_relay_fields_store(request);
669 if (!rctx) RETURN_UNLANG_INVALID;
670
671 UPDATE_STATE_CS(packet);
672
673 return unlang_module_yield_to_section(RESULT_P, request,
674 cs, state->default_rcode, state->resume,
675 NULL, 0, rctx);
676}
677
678/** Restore our copy of the header fields into the reply list
679 *
680 */
681RESUME(send_to_relay)
682{
683 process_dhcpv6_t *inst = talloc_get_type_abort(mctx->mi->data, process_dhcpv6_t);
684 process_dhcpv6_relay_fields_t *fields = talloc_get_type_abort(mctx->rctx, process_dhcpv6_relay_fields_t);
685 fr_process_state_t const *state;
686
687 UPDATE_STATE(reply);
688
689 /*
690 * Add a status code if we have one
691 */
692 status_code_add(inst, request, state->status_codes[RESULT_RCODE]);
693
694 /*
695 * Restore relay fields
696 */
697 if (unlikely(restore_field(request, &fields->hop_count) < 0)) {
698 fail:
699 p_result->rcode = RLM_MODULE_FAIL;
700 return CALL_RESUME(send_generic);
701 }
702 if (unlikely(restore_field(request, &fields->link_address) < 0)) goto fail;
703 if (unlikely(restore_field(request, &fields->peer_address) < 0)) goto fail;
704 if (fields->interface_id && unlikely(restore_field(request, &fields->interface_id) < 0)) goto fail;
705
706 dhcpv6_packet_debug(request, request->reply, &request->reply_pairs, false);
707
708 return CALL_RESUME(send_generic);
709}
710
711/** Main dispatch function
712 *
713 */
714static unlang_action_t mod_process(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
715{
716 fr_process_state_t const *state;
717
719
721 fr_assert(PROCESS_PACKET_CODE_VALID(request->packet->code));
722
723 request->component = "dhcpv6";
724 request->module = NULL;
725 fr_assert(request->proto_dict == dict_dhcpv6);
726
727 UPDATE_STATE(packet);
728
729 if (!state->recv) {
730 REDEBUG("Invalid packet type (%u)", request->packet->code);
732 }
733
734 dhcpv6_packet_debug(request, request->packet, &request->request_pairs, true);
735
736 if (unlikely(request_is_dynamic_client(request))) {
737 return new_client(p_result, mctx, request);
738 }
739
740 return state->recv(p_result, mctx, request);
741}
742
743static int mod_instantiate(module_inst_ctx_t const *mctx)
744{
745 process_dhcpv6_t *inst = talloc_get_type_abort(mctx->mi->data, process_dhcpv6_t);
746
747 inst->server_cs = cf_item_to_section(cf_parent(mctx->mi->conf));
748
749 return 0;
750}
751
752static fr_process_state_t const process_state[] = {
753 /*
754 * A client sends a Solicit message to locate
755 * servers.
756 */
757 [ FR_DHCPV6_SOLICIT ] = {
758 .recv = recv_for_any_server,
759 .resume = resume_recv_generic,
760 .packet_type = {
764 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
765
772 },
773 .status_codes = {
774 /* RLM_MODULE_NOOP - No response */
777 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
778
779 /* RLM_MODULE_FAIL - No response */
780 /* RLM_MODULE_INVALID - No response */
781 /* RLM_MODULE_REJECT - No response */
782 /* RLM_MODULE_DISALLOW - No response */
783 /* RLM_MODULE_NOTFOUND - No response */
784 },
785 .default_rcode = RLM_MODULE_NOOP,
786 .section_offset = offsetof(process_dhcpv6_sections_t, recv_solicit),
787 },
788
789 /*
790 * A client sends a Request message to request
791 * configuration parameters, including IP
792 * addresses, from a specific server.
793 */
794 [ FR_DHCPV6_REQUEST ] = {
795 .recv = recv_for_this_server,
796 .resume = resume_recv_generic,
797 .packet_type = {
801 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
802
809 },
810 .status_codes = {
814 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
815
821 },
822 .default_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
847 },
848
849 /*
850 * When the server receives a Confirm message, the server determines
851 * whether the addresses in the Confirm message are appropriate for the
852 * link to which the client is attached. If all of the addresses in the
853 * Confirm message pass this test, the server returns a status of
854 * Success. If any of the addresses do not pass this test, the server
855 * returns a status of NotOnLink. If the server is unable to perform
856 * this test (for example, the server does not have information about
857 * prefixes on the link to which the client is connected), or there were
858 * no addresses in any of the IAs sent by the client, the server MUST
859 * NOT send a reply to the client.
860 */
861 .status_codes = {
862 /* RLM_MODULE_NOOP - No response */
865 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
866
867 /* RLM_MODULE_FAIL - No response */
868 /* RLM_MODULE_INVALID - No response */
870 /* RLM_MODULE_DISALLOW - No response */
871 /* RLM_MODULE_NOTFOUND - No response */
872 },
873 .default_rcode = RLM_MODULE_NOOP,
874 .section_offset = offsetof(process_dhcpv6_sections_t, recv_confirm),
875 },
876
877 /*
878 * A client sends a Renew message to the server
879 * that originally provided the client's addresses
880 * and configuration parameters to extend the
881 * lifetimes on the addresses assigned to the
882 * client and to update other configuration
883 * parameters.
884 */
885 [ FR_DHCPV6_RENEW ] = {
886 .recv = recv_for_this_server,
887 .resume = resume_recv_generic,
888 .packet_type = {
892 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
893
900 },
901
902 /*
903 * If the server cannot find a client entry for the IA the server
904 * returns the IA containing no addresses with a Status Code option set
905 * to NoBinding in the Reply message.
906 */
907 .status_codes = {
911 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
912
914 /* RLM_MODULE_INVALID - No response */
918 },
919 .default_rcode = RLM_MODULE_NOOP,
920 .section_offset = offsetof(process_dhcpv6_sections_t, recv_renew),
921 },
922
923 /*
924 * A client sends a Rebind message to any
925 * available server to extend the lifetimes on the
926 * addresses assigned to the client and to update
927 * other configuration parameters; this message is
928 * sent after a client receives no response to a
929 * Renew message.
930 */
931 [ FR_DHCPV6_REBIND ] = {
932 .recv = recv_for_any_server,
933 .resume = resume_recv_generic,
934 .packet_type = {
938 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
939
946 },
947 .status_codes = {
951 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
952
954 /* RLM_MODULE_INVALID - No response */
958 },
959 .default_rcode = RLM_MODULE_NOOP,
960 .section_offset = offsetof(process_dhcpv6_sections_t, recv_rebind),
961 },
962 /*
963 * A client sends an Information-request
964 * message to a server to request configuration
965 * parameters without the assignment of any IP
966 * addresses to the client.
967 */
969 .recv = recv_for_any_server,
970 .resume = resume_recv_generic,
971 .packet_type = {
975 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
976
983 },
984 .status_codes = {
988 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
989
991 /* RLM_MODULE_INVALID - No response */
995 },
996 .default_rcode = RLM_MODULE_NOOP,
997 .section_offset = offsetof(process_dhcpv6_sections_t, recv_information_request),
998 },
999 /*
1000 * A client sends a Release message to the server
1001 * that assigned addresses to the client to
1002 * indicate that the client will no longer use one
1003 * or more of the assigned addresses.
1004 */
1005 [ FR_DHCPV6_RELEASE ] = {
1006 .recv = recv_for_this_server,
1007 .resume = resume_recv_generic,
1008 .packet_type = {
1012 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
1013
1020 },
1021 .status_codes = {
1025 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
1026
1028 /* RLM_MODULE_INVALID - No response */
1032 },
1033 .default_rcode = RLM_MODULE_NOOP,
1034
1035 .section_offset = offsetof(process_dhcpv6_sections_t, recv_release),
1036 },
1037 /*
1038 *
1039 * A client sends a Decline message to a server to
1040 * indicate that the client has determined that
1041 * one or more addresses assigned by the server
1042 * are already in use on the link to which the
1043 * client is connected.
1044 */
1045 [ FR_DHCPV6_DECLINE ] = {
1046 .recv = recv_for_this_server, /* Need to check for attributes */
1047 .resume = resume_recv_generic,
1048 .packet_type = {
1052 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
1053
1060 },
1061 .status_codes = {
1065 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
1066
1068 /* RLM_MODULE_INVALID - No response */
1072 },
1073 .default_rcode = RLM_MODULE_NOOP,
1074 .result_rcode = RLM_MODULE_REJECT,
1075 .section_offset = offsetof(process_dhcpv6_sections_t, recv_decline),
1076 },
1077 /*
1078 * A relay agent sends a Relay-forward message
1079 * to relay messages to servers, either directly
1080 * or through another relay agent. The received
1081 * message, either a client message or a
1082 * Relay-forward message from another relay
1083 * agent, is encapsulated in an option in the
1084 * Relay-forward message.
1085 */
1087 .recv = recv_from_relay,
1088 .resume = resume_recv_generic,
1089 .packet_type = {
1093 /* RLM_MODULE_HANDLED - Requires the user to set packet-type */
1094
1101 },
1102 .status_codes = {
1106 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
1107
1109 /* RLM_MODULE_INVALID - No response */
1113 },
1114 .default_rcode = RLM_MODULE_NOOP,
1115 .section_offset = offsetof(process_dhcpv6_sections_t, recv_relay_forward),
1116 },
1117 /*
1118 * A server sends an Advertise message to indicate
1119 * that it is available for DHCP service, in
1120 * response to a Solicit message received from a
1121 * client.
1122 */
1123 [ FR_DHCPV6_ADVERTISE ] = {
1124 .send = send_generic,
1125 .resume = resume_send_to_client,
1126 .packet_type = {
1133 },
1134 .status_codes = {
1138 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
1139
1140 /* RLM_MODULE_FAIL - No response */
1141 /* RLM_MODULE_INVALID - No response */
1142 /* RLM_MODULE_REJECT - No response */
1143 /* RLM_MODULE_DISALLOW - No response */
1144 /* RLM_MODULE_NOTFOUND - No response */
1145 },
1146 .default_rcode = RLM_MODULE_NOOP,
1147 .result_rcode = RLM_MODULE_OK,
1148 .section_offset = offsetof(process_dhcpv6_sections_t, send_advertise),
1149 },
1150 /*
1151 * A server sends a Reply message containing
1152 * assigned addresses and configuration parameters
1153 * in response to a Solicit, Request, Renew,
1154 * Rebind message received from a client. A
1155 * server sends a Reply message containing
1156 * configuration parameters in response to an
1157 * Information-request message. A server sends a
1158 * Reply message in response to a Confirm message
1159 * confirming or denying that the addresses
1160 * assigned to the client are appropriate to the
1161 * link to which the client is connected. A
1162 * server sends a Reply message to acknowledge
1163 * receipt of a Release or Decline message.
1164 */
1165 [ FR_DHCPV6_REPLY ] = {
1166 .send = send_generic,
1167 .resume = resume_send_to_client,
1168 .packet_type = {
1169
1176 },
1177 .status_codes = {
1181 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
1182
1184 /* RLM_MODULE_INVALID - No response */
1188 },
1189 .default_rcode = RLM_MODULE_NOOP,
1190 .result_rcode = RLM_MODULE_OK,
1191 .section_offset = offsetof(process_dhcpv6_sections_t, send_reply),
1192 },
1193 /*
1194 * A server sends a Relay-reply message to a relay
1195 * agent containing a message that the relay
1196 * agent delivers to a client. The Relay-reply
1197 * message may be relayed by other relay agents
1198 * for delivery to the destination relay agent.
1199 * The server encapsulates the client message as
1200 * an option in the Relay-reply message, which the
1201 * relay agent extracts and relays to the client.
1202 */
1203 [ FR_DHCPV6_RELAY_REPLY ] = {
1204 .send = send_generic,
1205 .resume = resume_send_to_relay,
1206 .packet_type = {
1213 },
1214 .status_codes = {
1218 /* RLM_MODULE_HANDLED - Requires the user to set status-code */
1219
1221 /* RLM_MODULE_INVALID - No response */
1225 },
1226 .default_rcode = RLM_MODULE_NOOP,
1227 .result_rcode = RLM_MODULE_OK,
1228 .section_offset = offsetof(process_dhcpv6_sections_t, send_relay_reply),
1229 },
1230
1232 .send = send_generic,
1233 .resume = resume_send_generic,
1234 .packet_type = {
1239
1246 },
1247 .default_rcode = RLM_MODULE_NOOP,
1248 .result_rcode = RLM_MODULE_HANDLED,
1249 .section_offset = offsetof(process_dhcpv6_sections_t, do_not_respond),
1250 }
1251};
1252
1255 .common = {
1256 .magic = MODULE_MAGIC_INIT,
1257 .name = "dhcpv6",
1261
1262 .instantiate = mod_instantiate
1263 },
1264 .process = mod_process,
1265 .compile_list = compile_list,
1266 .dict = &dict_dhcpv6,
1267 .packet_type = &attr_packet_type
1268};
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:383
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:658
#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:284
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:595
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:683
#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:263
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:274
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:287
Specifies an attribute which must be present for the module to function.
Definition dict.h:273
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:286
Specifies a value which must be present for the module to function.
Definition dict.h:262
#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:1661
static fr_dict_t const * dict_freeradius
Definition base.c:37
fr_dict_attr_t const * attr_packet_type
Definition base.c:93
static fr_dict_attr_t const * attr_module_failure_message
Definition log.c:206
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:852
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:610
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:828
#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:93
unlang_mod_action_t actions[RLM_MODULE_NUMCODES]
Definition mod_action.h:64
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:697
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:1966
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:2837
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:1342
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:2456
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:550
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:493
static unlang_action_t mod_process(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition base.c:188
static const virtual_server_compile_t compile_list[]
Definition base.c:214
static fr_process_state_t const process_state[]
Definition base.c:69
#define PROCESS_PACKET_CODE_VALID
Definition base.c:65
CONF_SECTION * send_advertise
Definition base.c:58
CONF_SECTION * recv_information_request
Definition base.c:55
static fr_dict_attr_t const * attr_hop_count
Definition base.c:130
CONF_SECTION * send_reply
Definition base.c:59
static fr_dict_attr_t const * attr_status_code_message
Definition base.c:137
CONF_SECTION * recv_solicit
Definition base.c:46
static fr_dict_attr_t const * attr_status_code_value
Definition base.c:136
static fr_dict_attr_t const * attr_relay_link_address
Definition base.c:133
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:484
fr_dict_autoload_t process_dhcpv6_dict[]
Definition base.c:122
fr_dict_enum_autoload_t process_dhcpv6_dict_enum[]
Definition base.c:164
static fr_value_box_t const * enum_status_code_success
Definition base.c:158
fr_pair_list_t server_id
Definition base.c:105
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:500
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:457
CONF_SECTION * do_not_respond
Definition base.c:62
static fr_value_box_t const * enum_status_code_no_binding
Definition base.c:161
fr_pair_list_t client_id
Definition base.c:104
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:131
static fr_dict_attr_t const * attr_server_id
Definition base.c:129
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:159
CONF_SECTION * recv_rebind
Definition base.c:50
static conf_parser_t dhcpv6_process_config[]
Definition base.c:190
CONF_SECTION * recv_release
Definition base.c:51
static int dhcpv6_client_fields_store(request_t *request, process_dhcpv6_rctx_t *rctx, bool expect_server_id)
Keep a copy of header fields to prevent them being tampered with.
Definition base.c:330
fr_pair_t * transaction_id
Definition base.c:103
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:278
CONF_SECTION * new_client
Definition base.c:64
fr_dict_attr_autoload_t process_dhcpv6_dict_attr[]
Definition base.c:142
unlang_result_t result
Definition base.c:106
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:118
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:621
static fr_dict_attr_t const * attr_transaction_id
Definition base.c:135
static fr_dict_attr_t const * attr_client_id
Definition base.c:128
static fr_value_box_t const * enum_status_code_not_on_link
Definition base.c:160
CONF_SECTION * recv_confirm
Definition base.c:48
static int mod_instantiate(module_inst_ctx_t const *mctx)
Definition base.c:743
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:134
RECV(for_any_server)
Validate a solicit/rebind/confirm message.
Definition base.c:401
fr_process_module_t process_dhcpv6
Definition base.c:1254
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:111
#define PROCESS_TRACE
Trace each state function as it's entered.
Definition process.h:55
#define PROCESS_CONF_OFFSET(_x)
Definition process.h:79
module_t common
Common fields for all loadable modules.
Common public symbol definition for all process modules.
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_UNLANG_INVALID
Definition rcode.h:60
#define RETURN_UNLANG_FAIL
Definition rcode.h:57
@ 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_TIMEOUT
Module (or section) timed out.
Definition rcode.h:50
@ 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:188
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:421
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:1482
#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:349
void * data
Module's instance data.
Definition module.h:291
#define MODULE_RCTX(_ctype)
Definition module.h:257
#define MODULE_INST(_ctype)
Definition module.h:255
conf_parser_t const * config
How to convert a CONF_SECTION to a module instance.
Definition module.h:206
#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(unlang_result_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:249
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:287
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:93
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
Definition pair_inline.c:42
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:3962
#define fr_box_ipaddr(_val)
Definition value.h:313
section_name_t const * section
Identifier for the section.
#define COMPILE_TERMINATOR
Processing sections which are allowed in this virtual server.