25RCSID(
"$Id: 4ee44d437863a3d5998a3b8151bcbd1a26121ad1 $")
27#include <freeradius-devel/server/base.h>
28#include <freeradius-devel/server/module_rlm.h>
29#include <freeradius-devel/dhcpv4/dhcpv4.h>
30#include <freeradius-devel/util/debug.h>
31#include <freeradius-devel/util/skip.h>
65#define NO_SEMICOLON (0)
66#define YES_SEMICOLON (1)
67#define MAYBE_SEMICOLON (2)
105#define IDEBUG if (state->debug) DEBUG
208#define state_error(_fmt, ...) cf_log_err(state->inst->cs, "Failed parsing %s[%d] - " _fmt, \
209 state->filename, state->lineno, ## __VA_ARGS__)
220 if (
state->eof)
return 0;
233 if (feof(
state->fp)) {
252 if (!*p || (*p ==
'#'))
goto redo;
282 if (ret < 0)
return -1;
290 if (*
state->ptr ==
';')
state->saw_semicolon =
true;
301 char *p =
state->ptr + 1;
302 char *q =
state->string;
318 if ((
size_t) (q -
state->string) >=
sizeof(
state->string) - 1) {
357 if (ret < 0)
return ret;
360 if (!
state->allow_eof) {
376 if (!*
state->ptr)
goto redo;
383 state->saw_semicolon =
false;
388 if (
state->token[0] ==
'"') {
397 for (p =
state->token; *p !=
'\0'; p++) {
409 state->saw_semicolon =
true;
427 if ((*p ==
'{') || (*p ==
'}') || (*p ==
'=')) {
428 if (p ==
state->token) p++;
463 if (
state->token_len == 0) {
468 if (
state->token_len >= 256) {
478 if (*
state->token !=
'{') {
483 if ((
size_t)
state->braces >= (
sizeof(
spaces) - 1)) {
493 if (*
state->token !=
'}') {
507 if (*
state->token ==
'}') {
508 if (!allow_rcbrace) {
522 if (*
state->token ==
'{') {
548 if (!*cmd)
return -1;
554 while (*next && !isspace((
uint8_t) *next) && (*next !=
',')) next++;
562 if (ret <= 0)
return -1;
567 for (p =
state->token; p < (
state->token +
state->token_len); p++, q++) {
570 state_error(
"Expected '%.*s', got unknown text '%.*s'",
572 (
int) (next - cmd), cmd);
604 if (strcmp(q,
"SECTION") == 0) {
605 if (q[7] !=
'\0')
return -1;
608 if (ret <= 0)
return ret;
611 if (ret < 0)
return ret;
627 while (*q && !isspace((
uint8_t) *q) && (*q !=
',')) {
628 if ((p - type_name) >= (
int)
sizeof(type_name))
return -1;
629 *(p++) = tolower((
uint8_t) *(q++));
661 state_error(
"unknown data type '%.*s'", (
int) (next - cmd), cmd);
674 if (ret <= 0)
return ret;
688 (strcmp(
state->token,
"ignore") == 0)) {
700 if (ret < 0)
return ret;
705 if (
state->saw_semicolon)
return 1;
707 if (
info->argc >=
info->cmd->max_argc) {
708 state_error(
"Too many arguments (%d > %d) for command '%s'",
719 if (!*next)
return 1;
735 char const *
name =
info->argv[0]->vb_strvalue;
739 sep = strrchr(
state->filename,
'/');
744 p = pathname + (sep -
state->filename) + 1;
745 strlcpy(p,
name,
sizeof(pathname) - (p - pathname));
755 if (ret < 0)
return ret;
818 state_error(
"please implement 'option space name [ [ code width number ] [ length width number ] [ hash size number ] ]'");
837#define TYPE_CHECK(name, type) if ((state->token_len == (sizeof(name) - 1)) && (memcmp(state->token, name, sizeof(name) - 1) == 0)) return type
867 p = strchr(
name,
'.');
869 state_error(
"cannot (yet) define options in spaces");
876 state_error(
"option definitions cannot be scoped");
893 if (ret < 0)
goto error;
899 if (ret <= 0)
goto error_ret;
901 if ((
state->token_len != 1) || (
state->token[0] !=
'=')) {
906 memset(&flags, 0,
sizeof(flags));
920 if (ret <= 0)
goto error_ret;
923 if ((
state->token_len == 5) && (memcmp(
state->token,
"array", 5) == 0)) {
927 if (ret <= 0)
goto error_ret;
929 if (! ((
state->token_len == 2) && (memcmp(
state->token,
"of", 2) == 0))) {
930 state_error(
"expected 'array of', not 'array %.*s'",
939 if (ret <= 0)
goto error_ret;
942 if ((
state->token_len == 1) && (
state->token[0] ==
'{')) {
943 state_error(
"records are not supported in option definition");
953 if (!
state->saw_semicolon) {
967 ((da->attr != box.vb_uint32) || (da->type !=
type))) {
968 state_error(
"cannot add different code / type for a pre-existing name '%s'",
name);
980 if (da && (da->type !=
type)) {
981 state_error(
"cannot add different type for a pre-existing code %u", box.vb_uint32);
993 if (ret < 0)
return ret;
1012 if (!da->flags.array && !
state->saw_semicolon) {
1038 if (!da->flags.array)
return 2;
1043 while (!
state->saw_semicolon) {
1045 if (ret <= 0)
return ret;
1050 if (ret < 0)
return ret;
1085 while (!
state->saw_semicolon) {
1087 if (ret < 0)
return ret;
1091 if (argc == 2)
break;
1105 if (strcmp(argv[0],
"space") == 0) {
1116 if (
state->saw_semicolon || (
state->ptr[0] ==
',')) {
1128 memcpy(
name,
"DHCP-", 5);
1143 if (strcmp(argv[1],
"code") != 0) {
1157 int start, end, half;
1160 char const *q = NULL;
1164 end = num_tokens - 1;
1170 if (
state->token_len < 4)
goto unknown;
1176 while (start <= end) {
1177 half = (start + end) / 2;
1184 ret =
state->token[0] - tokens[half].
name[0];
1185 if (ret != 0)
goto recurse;
1187 ret =
state->token[1] - tokens[half].
name[1];
1188 if (ret != 0)
goto recurse;
1190 ret =
state->token[2] - tokens[half].
name[2];
1191 if (ret != 0)
goto recurse;
1196 ret = strncmp(
state->token, tokens[half].
name,
state->token_len);
1203 char c = tokens[half].
name[
state->token_len];
1208 if (!c || isspace((
uint8_t) c)) {
1209 q = &(tokens[half].
name[
state->token_len]);
1255 if (
state->inst->pedantic && !tokens[half].
parse) {
1257 ERROR(
"Command '%.*s' is not supported.",
1269 WARN(
"Command '%.*s' is not yet implemented.",
1274 WARN(
"Ignoring command '%.*s'. It is not relevant.",
1286 if (tokens[half].max_argc) {
1294 info->cmd = &tokens[half];
1302 if (
state->saw_semicolon)
goto unexpected;
1305 if (ret <= 0)
return ret;
1335 if (tokens[half].parse) {
1357 if (ret == 2)
return 1;
1393 for (child =
info->child; child != NULL; child = child->
next) {
1396 state_error(
"cannot have two 'hardware ethernet' entries in a 'host'");
1405 state_error(
"host %s does not contain a 'hardware ethernet' entry",
1406 info->argv[0]->vb_strvalue);
1414 memcpy(my_ether->
ether, &(ether->
argv[0]->vb_ether),
sizeof(my_ether->
ether));
1422 state_error(
"'host %s' and 'host %s' contain duplicate 'hardware ethernet' fields",
1423 info->argv[0]->vb_strvalue, old_ether->
host->
argv[0]->vb_strvalue);
1432 state_error(
"Failed inserting 'host %s' into hash table",
1433 info->argv[0]->vb_strvalue);
1449 state_error(
"'host %s' and 'host %s' contain duplicate 'option client-identifier' fields",
1450 info->argv[0]->vb_strvalue, old_uid->host->argv[0]->vb_strvalue);
1458 state_error(
"Failed inserting 'host %s' into hash table",
1459 info->argv[0]->vb_strvalue);
1469 if (!
info->parent)
return 2;
1479 if (!
parent->hosts_by_ether) {
1481 if (!
parent->hosts_by_ether) {
1487 state_error(
"Failed inserting 'host %s' into hash table",
1488 info->argv[0]->vb_strvalue);
1496 if (!
parent->hosts_by_uid) {
1498 if (!
parent->hosts_by_uid) {
1505 state_error(
"Failed inserting 'host %s' into hash table",
1506 info->argv[0]->vb_strvalue);
1532 if (netmask & (~netmask >> 1)) {
1540 if ((
info->argv[0]->vb_ipv4addr & netmask) !=
info->argv[0]->vb_ipv4addr) {
1548 netmask = netmask - ((netmask >> 1) & 0x55555555);
1549 netmask = (netmask & 0x33333333) + ((netmask >> 2) & 0x33333333);
1550 netmask = (netmask + (netmask >> 4)) & 0x0F0F0F0F;
1551 netmask = netmask + (netmask >> 8);
1552 netmask = netmask + (netmask >> 16);
1553 bits = netmask & 0x0000003F;
1564 state_error(
"subnet %pV netmask %pV' overlaps with existing subnet",
info->argv[0],
info->argv[1]);
1570 if (!
parent->subnets)
return -1;
1582 state_error(
"Failed inserting 'subnet %pV netmask %pV' into trie",
1623 host = client->
host;
1630 if (!
vp)
return NULL;
1632 memcpy(&my_ether.
ether,
vp->vp_ether,
sizeof(my_ether.
ether));
1635 if (!ether)
return NULL;
1656 if (!
info->parent)
return -1;
1672#define member_size(type, member) sizeof(((type *)0)->member)
1752 if (yiaddr)
return 0;
1755 if (!host)
return 0;
1761 if (!
info->cmd)
return -1;
1766 if (
info->child)
continue;
1773 RPEDEBUG(
"Failed assigning Your-IP-Address");
1804 if (
head->hosts_by_ether) {
1808 if (!host)
goto subnet;
1814 if (child_ret < 0)
return child_ret;
1815 if (child_ret == 1) ret = 1;
1823 if (
head->subnets && yiaddr) {
1825 if (!
info)
goto recurse;
1828 if (child_ret < 0)
return child_ret;
1829 if (child_ret == 1) ret = 1;
1834 if (!
info->cmd)
return -1;
1836 if (!
info->cmd->apply)
continue;
1839 if (child_ret < 0)
return child_ret;
1840 if (child_ret == 0)
continue;
1877 if (reply)
continue;
1887 if (!copy)
return -1;
1893 if (next->
da !=
vp->
da)
break;
1908#define isc_not_done ISC_NOOP, NULL, NULL
1909#define isc_ignore ISC_IGNORE, NULL, NULL
1910#define isc_invalid ISC_INVALID, NULL, NULL
1918 {
"adaptive-lease-time-threshold INTEGER",
isc_not_done, 1},
1924 {
"bind-local-address6 BOOL",
isc_ignore, 1},
1935 {
"ddns-other-guard-is-dynamic BOOL",
isc_not_done, 1},
1944 {
"dhcpv6-lease-file-name STRING",
isc_ignore, 1},
1945 {
"dhcpv6-pid-file-name STRING",
isc_ignore, 1},
1952 {
"dynamic-bootp-lease-cutoff UINT32",
isc_not_done, 1},
1953 {
"dynamic-bootp-lease-length UINT32",
isc_not_done, 1},
1959 {
"group SECTION",
ISC_GROUP, NULL, NULL, 1},
1973 {
"ldap-dhcp-server-cn STRING",
isc_ignore, 1},
1974 {
"ldap-gssapi-keytab STRING",
isc_ignore, 1},
1975 {
"ldap-gssapi-principal STRING",
isc_ignore, 1},
1985 {
"ldap-TLS-Certificate STRING",
isc_ignore, 1},
1987 {
"ldap-tls-crlcheck STRING,",
isc_ignore, 1},
1989 {
"ldap-tls-randfile STRING",
isc_ignore, 1},
1990 {
"ldap-tls-reqcert STRING,",
isc_ignore, 1},
1997 {
"limited-broadcast-address IPADDR",
isc_not_done, 1},
2002 {
"log-threshold-high UINT8",
isc_ignore, 1},
2014 {
"option STRING STRING,",
ISC_OPTION, NULL, NULL, 16},
2035 {
"use-lease-addr-for-default-route BOOL",
isc_not_done, 1},
2074 state->allow_eof =
false;
2078 if (ret < 0)
return ret;
2079 if (ret == 0)
break;
2084 if (*
state->token ==
'}')
break;
2087 if (ret < 0)
return ret;
2088 if (ret == 0)
break;
2117 fp = fopen(filename,
"r");
2126 state.filename = filename;
2136 state.allow_eof =
true;
2150 if (ret == 0)
break;
2157 if (ret < 0)
goto fail;
2158 if (ret == 0)
break;
2167 if (!*last)
return 0;
2185 if (!
inst->hosts_by_ether)
return -1;
2188 if (!
inst->hosts_by_uid)
return -1;
2191 if (ret < 0)
return -1;
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
static int const char char buffer[256]
#define MEMCMP_RETURN(_a, _b, _field, _len_field)
Return if the contents of the specified field is not identical between the specified structures.
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
#define CONF_PARSER_TERMINATOR
#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
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
@ CONF_FLAG_NOT_EMPTY
CONF_PAIR is required to have a non zero length value.
@ CONF_FLAG_FILE_READABLE
File matching value must exist, and must be readable.
Defines a CONF_PAIR to C data type mapping.
A section grouping multiple CONF_PAIR.
#define cf_log_err(_cf, _fmt,...)
#define cf_log_warn(_cf, _fmt,...)
fr_dict_t * fr_dict_unconst(fr_dict_t const *dict)
Coerce to non-const.
fr_dict_attr_t const * fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *attr))
Locate a fr_dict_attr_t by its name.
unsigned int array
Pack multiples into 1 attr.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, unsigned int attr, fr_type_t type, fr_dict_attr_flags_t const *flags))
Add an attribute to the dictionary.
#define DICT_AUTOLOAD_TERMINATOR
fr_dict_attr_t const * fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr)
Check if a child attribute exists in a parent using an attribute number.
#define FR_DICT_ATTR_MAX_NAME_LEN
Maximum length of a attribute name.
Specifies an attribute which must be present for the module to function.
Values of the encryption flags.
Specifies a dictionary which must be loaded/loadable for the module to function.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
int fr_hash_table_find(void **found, fr_hash_table_t *ht, void const *data)
Find data in a hash table.
uint32_t fr_hash(void const *data, size_t size)
int fr_hash_table_delete(fr_hash_table_t *ht, void const *data)
Remove and free data (if a free function was specified)
int fr_hash_table_remove(void **removed, fr_hash_table_t *ht, void const *data)
Remove an entry from the hash table, without freeing the data.
int fr_hash_table_insert(fr_hash_table_t *ht, void const *data)
Insert data into a hash table.
#define fr_hash_table_alloc(_ctx, _hash_node, _cmp_node, _free_node)
#define DEBUG_ENABLED
True if global debug level 1 messages are enabled.
#define RPEDEBUG(fmt,...)
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_ETHERNET
48 Bit Mac-Address.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_IPV6_ADDR
128 Bit IPv6 Address.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_OCTETS
Raw octets.
fr_cmp_ret_t
Result of an ordering comparison.
module_instance_t const * mi
Instance of the module being instantiated.
module_instance_t * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for module calls.
Temporary structure to hold arguments for instantiation calls.
module_t common
Common fields presented by all modules.
int fr_pair_value_from_str(fr_pair_t *vp, char const *value, size_t inlen, fr_sbuff_unescape_rules_t const *uerules, UNUSED bool tainted)
Convert string value to native attribute value.
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.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
fr_pair_t * fr_pair_copy(TALLOC_CTX *ctx, fr_pair_t const *vp)
Copy a single valuepair.
static const conf_parser_t config[]
#define RETURN_UNLANG_UPDATED
#define RETURN_UNLANG_FAIL
#define RETURN_UNLANG_NOOP
char * ptr
pointer into read buffer
#define state_error(_fmt,...)
static int parse_option(rlm_isc_dhcp_info_t *parent, rlm_isc_dhcp_tokenizer_t *state, fr_dict_attr_t const *da, char *value)
#define TYPE_CHECK(name, type)
Parse one type string.
int(* rlm_isc_dhcp_parse_t)(rlm_isc_dhcp_tokenizer_t *state, rlm_isc_dhcp_info_t *info)
static unlang_action_t mod_post_auth(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
bool allow_eof
do we allow EOF? (i.e. braces == 0)
fr_dict_attr_autoload_t rlm_isc_dhcp_dict_attr[]
static int match_keyword(rlm_isc_dhcp_info_t *parent, rlm_isc_dhcp_tokenizer_t *state, rlm_isc_dhcp_cmd_t const *tokens, int num_tokens)
static int parse_include(rlm_isc_dhcp_tokenizer_t *state, rlm_isc_dhcp_info_t *info)
static int refill(rlm_isc_dhcp_tokenizer_t *state)
Refills the read buffer with one line from the file.
fr_hash_table_t * hosts_by_ether
by MAC address
static int parse_options(rlm_isc_dhcp_info_t *parent, rlm_isc_dhcp_tokenizer_t *state)
Parse "option" command.
size_t token_len
length of the token
int(* rlm_isc_dhcp_apply_t)(rlm_isc_dhcp_t const *inst, request_t *request, rlm_isc_dhcp_info_t *info)
rlm_isc_dhcp_t * inst
module instance
int braces
how many levels deep we are in a { ... }
static int parse_subnet(rlm_isc_dhcp_tokenizer_t *state, rlm_isc_dhcp_info_t *info)
subnet IPADDR netmask MASK { ... }
rlm_isc_dhcp_info_t * host
static int parse_server_identifier(UNUSED rlm_isc_dhcp_tokenizer_t *state, rlm_isc_dhcp_info_t *info)
server-identifier IPADDR
static fr_cmp_ret_t host_ether_cmp(void const *one, void const *two)
rlm_isc_dhcp_info_t * head
char * token
current token that we parsed
rlm_isc_dhcp_parse_t parse
static fr_dict_attr_t const * attr_server_identifier
static int parse_host(rlm_isc_dhcp_tokenizer_t *state, rlm_isc_dhcp_info_t *info)
host NAME { ... }
static int parse_server_name(rlm_isc_dhcp_tokenizer_t *state, rlm_isc_dhcp_info_t *info)
server-name STRING
fr_dict_autoload_t rlm_isc_dhcp_dict[]
static int parse_section(rlm_isc_dhcp_tokenizer_t *state, rlm_isc_dhcp_info_t *info)
Parse a section { ... }.
fr_hash_table_t * hosts_by_uid
by client identifier
static rlm_isc_dhcp_info_t * get_host(request_t *request, fr_hash_table_t *hosts_by_ether, fr_hash_table_t *hosts_by_uid)
fr_hash_table_t * hosts_by_uid
by client identifier
static fr_cmp_ret_t host_uid_cmp(void const *one, void const *two)
static int parse_next_server(UNUSED rlm_isc_dhcp_tokenizer_t *state, rlm_isc_dhcp_info_t *info)
next-server IPADDR
static fr_dict_attr_t const * attr_boot_filename
static uint32_t host_uid_hash(void const *data)
static unlang_action_t mod_authorize(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static int parse_option_definition(rlm_isc_dhcp_info_t *parent, rlm_isc_dhcp_tokenizer_t *state, char *name)
option new-name code new-code = definition ;
rlm_isc_dhcp_info_t ** last
pointer to last child
module_rlm_t rlm_isc_dhcp
static int parse_option_space(UNUSED rlm_isc_dhcp_info_t *parent, rlm_isc_dhcp_tokenizer_t *state, UNUSED char *name)
option space name [ [ code width number ] [ length width number ] [ hash size number ] ] ;
static int skip_spaces(rlm_isc_dhcp_tokenizer_t *state, char *p)
static fr_dict_t const * dict_dhcpv4
bool saw_semicolon
whether we saw a semicolon
static fr_dict_attr_t const * attr_client_hardware_address
static int apply_fixed_ip(rlm_isc_dhcp_t const *inst, request_t *request)
Apply fixed IPs.
static fr_dict_attr_t const * attr_your_ip_address
static const rlm_isc_dhcp_cmd_t commands[]
Table of commands that we allow.
static fr_dict_attr_t const * attr_server_name
char * line
where the current line started
fr_pair_list_t options
DHCP options.
bool debug
internal developer debugging
static int read_file(rlm_isc_dhcp_t *inst, rlm_isc_dhcp_info_t *parent, char const *filename)
Open a file and read it into a parent.
rlm_isc_dhcp_info_t * next
void * data
per-thing parsed data.
static fr_dict_attr_t const * attr_client_identifier
static fr_type_t isc2fr_type(rlm_isc_dhcp_tokenizer_t *state)
size_t bufsize
size of read buffer
static int apply(rlm_isc_dhcp_t const *inst, request_t *request, rlm_isc_dhcp_info_t *head)
Apply all rules except fixed IP.
rlm_isc_dhcp_cmd_t const * cmd
static fr_dict_attr_t const * attr_server_ip_address
static char const * spaces
rlm_isc_dhcp_apply_t apply
static const conf_parser_t module_config[]
fr_hash_table_t * hosts_by_ether
by MAC address
rlm_isc_dhcp_info_t * parent
static int add_option_by_da(rlm_isc_dhcp_info_t *info, fr_dict_attr_t const *da)
static int read_string(rlm_isc_dhcp_tokenizer_t *state)
static uint32_t host_ether_hash(void const *data)
static int mod_instantiate(module_inst_ctx_t const *mctx)
static int read_token(rlm_isc_dhcp_tokenizer_t *state, fr_token_t hint, int semicolon, bool allow_rcbrace)
Reads one token into state->token.
static int parse_filename(rlm_isc_dhcp_tokenizer_t *state, rlm_isc_dhcp_info_t *info)
filename STRING
rlm_isc_dhcp_info_t * child
@ ISC_NOOP
we don't do anything with it
@ ISC_IGNORE
we deliberately ignore it
@ ISC_INVALID
we recognize it, but don't implement it
#define member_size(type, member)
static int match_subword(rlm_isc_dhcp_tokenizer_t *state, char const *cmd, rlm_isc_dhcp_info_t *info)
Recursively match subwords inside of a command string.
rlm_isc_dhcp_info_t * host
Describes the commands that we accept, including it's syntax (i.e.
Holds information about the thing we parsed.
Holds the state of the current tokenizer.
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
CONF_SECTION * conf
Module's instance configuration.
size_t inst_size
Size of the module's instance data.
void * data
Module's instance data.
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Named methods exported by a module.
#define fr_skip_not_whitespace(_p)
Skip everything that's not whitespace ('\t', '\n', '\v', '\f', '\r', ' ')
#define fr_skip_whitespace(_p)
Skip whitespace ('\t', '\n', '\v', '\f', '\r', ' ')
eap_aka_sim_process_conf_t * inst
fr_aka_sim_id_type_t type
size_t strlcpy(char *dst, char const *src, size_t siz)
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
#define talloc_get_type_abort_const
#define talloc_strndup(_ctx, _str, _len)
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
fr_trie_t * fr_trie_alloc(TALLOC_CTX *ctx, fr_trie_key_t get_key, fr_free_t free_data)
Allocate a trie.
void * fr_trie_lookup_by_key(fr_trie_t const *ft, void const *key, size_t keylen)
Lookup a key in a trie and return user ctx, if any.
int fr_trie_insert_by_key(fr_trie_t *ft, void const *key, size_t keylen, void const *data)
Insert a key and user ctx into a trie.
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
fr_pair_t * fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
#define fr_type_is_null(_x)
static fr_type_t fr_type_from_str(char const *type)
Return the constant value representing a type.
fr_slen_t fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, char const *in, size_t inlen, fr_sbuff_unescape_rules_t const *erules)
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.