The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
base.c
Go to the documentation of this file.
1/*
2 * This program is 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 (at
5 * 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 * @file src/lib/eap_aka_sim/base.c
19 * @brief Code common to EAP-SIM/AKA/AKA' clients and servers.
20 *
21 * The development of the EAP-SIM support was funded by Internet Foundation
22 * Austria (http://www.nic.at/ipa).
23 *
24 * @copyright 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
25 * @copyright 2003-2016 The FreeRADIUS server project
26 */
27
28RCSID("$Id: 8fc2cb43c5c0c41c73b6152456e8a7c6f90c5acb $")
29
30#include <freeradius-devel/util/sha1.h>
31
32#include <freeradius-devel/util/debug.h>
33#include <freeradius-devel/server/module.h>
34
35#include <freeradius-devel/tls/base.h>
36
37#include <freeradius-devel/eap/types.h>
38
39#include <freeradius-devel/eap_aka_sim/base.h>
40#include <freeradius-devel/eap_aka_sim/attrs.h>
41
42#include "crypto_priv.h"
43
45
49
52 { .out = &dict_freeradius, .proto = "freeradius" },
53 { .out = &dict_radius, .proto = "radius" },
54 { .out = &dict_eap_aka_sim, .base_dir = "eap/aka-sim", .proto = "eap-aka-sim" },
55
56 { NULL }
57};
58
104
107
116
119 { .out = &attr_eap_aka_sim_ak, .name = "AK", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
120 { .out = &attr_eap_aka_sim_any_id_req, .name = "Any-ID-Req", .type = FR_TYPE_BOOL, .dict = &dict_eap_aka_sim },
121 { .out = &attr_eap_aka_sim_autn, .name = "AUTN", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
122 { .out = &attr_eap_aka_sim_auts, .name = "AUTS", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
123 { .out = &attr_eap_aka_sim_bidding, .name = "Bidding", .type = FR_TYPE_UINT16, .dict = &dict_eap_aka_sim },
124 { .out = &attr_eap_aka_sim_checkcode, .name = "Checkcode", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
125 { .out = &attr_eap_aka_sim_ck, .name = "CK", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
126 { .out = &attr_eap_aka_sim_client_error_code, .name = "Client-Error-Code", .type = FR_TYPE_UINT16, .dict = &dict_eap_aka_sim },
127 { .out = &attr_eap_aka_sim_fullauth_id_req, .name = "Fullauth-ID-Req", .type = FR_TYPE_BOOL, .dict = &dict_eap_aka_sim },
128 { .out = &attr_eap_aka_sim_hmac_extra_request, .name = "HMAC-Extra-Request", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
129 { .out = &attr_eap_aka_sim_hmac_extra_response, .name = "HMAC-Extra-Response", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
130 { .out = &attr_eap_aka_sim_identity, .name = "Identity", .type = FR_TYPE_STRING, .dict = &dict_eap_aka_sim },
131 { .out = &attr_eap_aka_sim_identity_type, .name = "Identity-Type", .type = FR_TYPE_UINT32, .dict = &dict_eap_aka_sim },
132 { .out = &attr_eap_aka_sim_ik, .name = "IK", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
133 { .out = &attr_eap_aka_sim_iv, .name = "IV", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
134 { .out = &attr_eap_aka_sim_k_aut, .name = "K-Aut", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
135 { .out = &attr_eap_aka_sim_k_encr, .name = "K-Encr", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
136 { .out = &attr_eap_aka_sim_k_re, .name = "K-Re", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
137 { .out = &attr_eap_aka_sim_kc, .name = "KC", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
138 { .out = &attr_eap_aka_sim_kdf, .name = "KDF", .type = FR_TYPE_UINT16, .dict = &dict_eap_aka_sim },
139 { .out = &attr_eap_aka_sim_kdf_identity, .name = "KDF-Identity", .type = FR_TYPE_STRING, .dict = &dict_eap_aka_sim },
140 { .out = &attr_eap_aka_sim_kdf_input, .name = "KDF-Input", .type = FR_TYPE_STRING, .dict = &dict_eap_aka_sim },
141 { .out = &attr_eap_aka_sim_mac, .name = "MAC", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
142 { .out = &attr_eap_aka_sim_method_hint, .name = "Method-Hint", .type = FR_TYPE_UINT32, .dict = &dict_eap_aka_sim },
143 { .out = &attr_eap_aka_sim_mk, .name = "MK", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
144 { .out = &attr_eap_aka_sim_nonce_mt, .name = "Nonce-MT", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
145 { .out = &attr_eap_aka_sim_notification, .name = "Notification", .type = FR_TYPE_UINT16, .dict = &dict_eap_aka_sim },
146 { .out = &attr_eap_aka_sim_permanent_id_req, .name = "Permanent-Id-Req", .type = FR_TYPE_BOOL, .dict = &dict_eap_aka_sim },
147 { .out = &attr_eap_aka_sim_permanent_identity, .name = "Permanent-Identity", .type = FR_TYPE_STRING, .dict = &dict_eap_aka_sim },
148 { .out = &attr_eap_aka_sim_rand, .name = "RAND", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
149 { .out = &attr_eap_aka_sim_res, .name = "RES", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
150 { .out = &attr_eap_aka_sim_result_ind, .name = "Result-Ind", .type = FR_TYPE_BOOL, .dict = &dict_eap_aka_sim },
151 { .out = &attr_eap_aka_sim_selected_version, .name = "Selected-Version", .type = FR_TYPE_UINT16, .dict = &dict_eap_aka_sim },
152 { .out = &attr_eap_aka_sim_sres, .name = "SRES", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
153 { .out = &attr_eap_aka_sim_subtype, .name = "Subtype", .type = FR_TYPE_UINT32, .dict = &dict_eap_aka_sim },
154 { .out = &attr_eap_aka_sim_version_list, .name = "Version-List", .type = FR_TYPE_UINT16, .dict = &dict_eap_aka_sim },
155 { .out = &attr_eap_aka_sim_xres, .name = "XRES", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
156 { .out = &attr_session_data, .name = "Session-Data", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
157 { .out = &attr_session_id, .name = "Session-Id", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
158
159 { .out = &attr_eap_aka_sim_encr_data, .name = "Encr-Data", .type = FR_TYPE_TLV, .dict = &dict_eap_aka_sim },
160 { .out = &attr_eap_aka_sim_counter, .name = "Encr-Data.Counter", .type = FR_TYPE_UINT16, .dict = &dict_eap_aka_sim },
161 { .out = &attr_eap_aka_sim_nonce_s, .name = "Encr-Data.Nonce-S", .type = FR_TYPE_OCTETS, .dict = &dict_eap_aka_sim },
162 { .out = &attr_eap_aka_sim_next_pseudonym, .name = "Encr-Data.Next-Pseudonym", .type = FR_TYPE_STRING, .dict = &dict_eap_aka_sim },
163 { .out = &attr_eap_aka_sim_next_reauth_id, .name = "Encr-Data.Next-Reauth-ID", .type = FR_TYPE_STRING, .dict = &dict_eap_aka_sim },
164 { .out = &attr_eap_aka_sim_counter_too_small, .name = "Encr-Data.Counter-Too-Small", .type = FR_TYPE_BOOL, .dict = &dict_eap_aka_sim },
165
166 { .out = &attr_ms_mppe_send_key, .name = "Vendor-Specific.Microsoft.MPPE-Send-Key", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
167 { .out = &attr_ms_mppe_recv_key, .name = "Vendor-Specific.Microsoft.MPPE-Recv-Key", .type = FR_TYPE_OCTETS, .dict = &dict_radius },
168
169 /*
170 * Separate from the EAP-AKA-AND-SIM dictionary
171 * as they're outside the notional numberspace.
172 */
173 { .out = &attr_eap_identity, .name = "EAP-Identity", .type = FR_TYPE_STRING, .dict = &dict_freeradius },
174 { .out = &attr_eap_type, .name = "EAP-Type", .type = FR_TYPE_UINT32, .dict = &dict_freeradius },
175
176 { .out = &attr_sim_algo_version, .name = "SIM-Algo-Version", .type = FR_TYPE_UINT32, .dict = &dict_freeradius },
177 { .out = &attr_sim_amf, .name = "SIM-AMF", .type = FR_TYPE_OCTETS, .dict = &dict_freeradius },
178 { .out = &attr_sim_ki, .name = "SIM-Ki", .type = FR_TYPE_OCTETS, .dict = &dict_freeradius },
179 { .out = &attr_sim_op, .name = "SIM-OP", .type = FR_TYPE_OCTETS, .dict = &dict_freeradius },
180 { .out = &attr_sim_opc, .name = "SIM-OPc", .type = FR_TYPE_OCTETS, .dict = &dict_freeradius },
181 { .out = &attr_sim_sqn, .name = "SIM-SQN", .type = FR_TYPE_UINT64, .dict = &dict_freeradius },
182 { NULL }
183};
184
188
190
193 { .out = &enum_eap_type_sim, .name = "SIM", .attr = &attr_eap_type },
194 { .out = &enum_eap_type_aka, .name = "AKA", .attr = &attr_eap_type },
195 { .out = &enum_eap_type_aka_prime, .name = "AKA-Prime", .attr = &attr_eap_type },
196
197 { .out = &enum_kdf_prime_with_ck_prime_ik_prime, .name = "Prime-With-CK-Prime-IK-Prime", .attr = &attr_eap_aka_sim_kdf },
198
199 { NULL }
200};
201
202/** SIM AT on-the-wire format attribute sizes
203 *
204 * Holds the min/max sizes of all supported SIM AT attribute values as they
205 * would be found in a SIM AT packet.
206 *
207 * These sizes may be different than the sizes of INTERNAL formats, PRESENTATION
208 * formats and generic NETWORK formats.
209 */
210size_t const fr_aka_sim_attr_sizes[FR_TYPE_MAX + 1][2] = {
211 [FR_TYPE_NULL] = {~0, 0},
212
213 [FR_TYPE_STRING] = {0, ~0},
214 [FR_TYPE_OCTETS] = {0, ~0},
215
216 [FR_TYPE_BOOL] = {2, 2},
217 [FR_TYPE_UINT8] = {1, 1},
218 [FR_TYPE_UINT16] = {2, 2},
219 [FR_TYPE_UINT32] = {4, 4},
220 [FR_TYPE_UINT64] = {8, 8},
221
222 [FR_TYPE_TLV] = {2, ~0},
223
224 [FR_TYPE_MAX] = {~0, 0} //!< Ensure array covers all types.
225};
226
227static int dict_flag_encrypt(fr_dict_attr_t **da_p, char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)
228{
229 static fr_table_num_sorted_t const encrypted[] = {
230 { L("aes-cbc"), AKA_SIM_FLAG_ENCRYPT_AES_CBC }
231 };
232 static size_t encrypted_len = NUM_ELEMENTS(encrypted);
233
236
238 if (encrypt == AKA_SIM_FLAG_ENCRYPT_INVALID) {
239 fr_strerror_printf("Unknown encryption type '%s'", value);
240 return -1;
241 }
242
243 flags->encrypt = encrypt;
244
245 return 0;
246}
247
249 { L("encrypt"), { .func = dict_flag_encrypt, .needs_value = true} }
250};
251
252/** Return the on-the-wire length of an attribute value
253 *
254 * @param[in] vp to return the length of.
255 * @return the length of the attribute.
256 */
258{
259 switch (vp->vp_type) {
261 return vp->vp_length;
262
264 if (!fr_cond_assert(0)) return 0;
265
266 default:
267 break;
268 }
269
270 return fr_aka_sim_attr_sizes[vp->vp_type][0];
271}
272
273/** Return the number of bytes before the octets value
274 *
275 */
277{
278 if (da->flags.array) return 0; /* Array elements have no padding */
279 if (!da->flags.length) return 2; /* Variable length attributes need length field */
280 if (!(da->flags.length % 4)) return 2; /* Values that are multiples of four have 2 reserved bytes */
281 return 0; /* Everything else has zero padding bytes */
282}
283
285{
286 if (instance_count > 0) {
288 return 0;
289 }
290
292 PERROR("Failed loading libfreeradius-eap-aka-sim dictionaries");
293 return -1;
294 }
296 PERROR("Failed loading libfreeradius-eap-aka-sim attributes");
298 return -1;
299 }
301 PERROR("Failed loading libfreeradius-eap-aka-sim enumerations");
302 return -1;
303 }
304
305 if (fr_openssl_init() < 0) {
306 PERROR("Failed setting up OpenSSL");
307 return -1;
308 }
309
311
312 return 0;
313}
314
316{
317 if (--instance_count > 0) return;
318
320
322
323 fr_openssl_free();
324}
325
328 .name = "eap_aka_sim",
329 .default_type_size = 1,
330 .default_type_length = 1,
331 .attr = {
332 .flags = {
333 .table = eap_aka_sim_flags,
334 .table_len = NUM_ELEMENTS(eap_aka_sim_flags),
335 .len = sizeof(fr_aka_sim_attr_flags_t)
336 }
337 }
338};
#define RCSID(id)
Definition build.h:483
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:209
#define UNUSED
Definition build.h:315
#define NUM_ELEMENTS(_t)
Definition build.h:337
EAP-SIM/EAP-AKA Private crypto functions.
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition debug.h:139
int fr_dict_enum_autoload(fr_dict_enum_autoload_t const *to_load)
Process a dict_attr_autoload element to load/verify a dictionary attribute.
Definition dict_util.c:4051
#define fr_dict_autofree(_to_free)
Definition dict.h:853
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
int fr_dict_attr_autoload(fr_dict_attr_autoload_t const *to_load)
Process a dict_attr_autoload element to load/verify a dictionary attribute.
Definition dict_util.c:4090
@ FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC
Protocol specific extensions.
Definition dict.h:171
#define fr_dict_autoload(_to_load)
Definition dict.h:850
char const * name
name of this protocol
Definition dict.h:430
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
Protocol specific custom flag definitnion.
Definition dict.h:398
Protocol-specific callbacks in libfreeradius-PROTOCOL.
Definition dict.h:429
static void * fr_dict_attr_ext(fr_dict_attr_t const *da, fr_dict_attr_ext_t ext)
Definition dict_ext.h:140
Test enumeration values.
Definition dict_test.h:92
fr_aka_sim_attr_flags_encrypt_t
Definition base.h:255
@ AKA_SIM_FLAG_ENCRYPT_AES_CBC
Encrypt attribute RFC 2865 style.
Definition base.h:258
@ AKA_SIM_FLAG_ENCRYPT_INVALID
Invalid encryption flag.
Definition base.h:256
fr_aka_sim_attr_flags_encrypt_t encrypt
Attribute has a tag and is encrypted.
Definition base.h:262
void aka_sim_crypto_cipher_ctx_free(void)
Explicitly free all thread load cipher ctxs.
Definition crypto.c:87
static fr_dict_t const * dict_freeradius
Definition base.c:37
fr_dict_attr_t const * attr_eap_identity
Definition base.c:91
fr_dict_attr_t const * attr_eap_type
Definition base.c:92
fr_dict_t const * dict_radius
Definition base.c:78
fr_dict_attr_t const * attr_ms_mppe_send_key
Definition base.c:101
fr_dict_attr_t const * attr_ms_mppe_recv_key
Definition base.c:102
fr_dict_attr_t const * attr_eap_aka_sim_subtype
Definition base.c:99
fr_dict_attr_t const * attr_eap_aka_sim_permanent_identity
Definition base.c:93
fr_dict_attr_t const * attr_eap_aka_sim_k_aut
Definition base.c:77
fr_dict_attr_t const * attr_eap_aka_sim_next_pseudonym
Definition base.c:87
fr_dict_attr_t const * attr_sim_amf
Definition base.c:111
fr_dict_attr_t const * attr_eap_aka_sim_mk
Definition base.c:86
size_t fr_aka_sim_attr_len(fr_pair_t const *vp)
Return the on-the-wire length of an attribute value.
Definition base.c:257
fr_dict_attr_t const * attr_session_id
Definition base.c:103
fr_dict_attr_t const * attr_eap_aka_sim_hmac_extra_request
Definition base.c:71
fr_dict_protocol_t libfreeradius_eap_aka_sim_dict_protocol
Definition base.c:327
static int dict_flag_encrypt(fr_dict_attr_t **da_p, char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)
Definition base.c:227
fr_dict_attr_t const * attr_eap_aka_sim_counter_too_small
Definition base.c:68
fr_dict_attr_t const * attr_eap_aka_sim_next_reauth_id
Definition base.c:88
fr_dict_attr_t const * attr_eap_aka_sim_ak
Definition base.c:59
fr_dict_attr_t const * attr_sim_op
Definition base.c:113
fr_dict_attr_t const * attr_eap_aka_sim_kdf
Definition base.c:81
fr_dict_attr_t const * attr_eap_aka_sim_ik
Definition base.c:75
void fr_aka_sim_free(void)
Definition base.c:315
fr_dict_attr_t const * attr_eap_aka_sim_xres
Definition base.c:101
fr_dict_attr_t const * attr_eap_aka_sim_ck
Definition base.c:65
fr_value_box_t const * enum_kdf_prime_with_ck_prime_ik_prime
Definition base.c:189
fr_dict_attr_t const * attr_eap_aka_sim_permanent_id_req
Definition base.c:92
fr_dict_attr_t const * attr_session_data
Definition base.c:102
static uint32_t instance_count
Definition base.c:44
fr_dict_attr_t const * attr_sim_ki
Definition base.c:112
int fr_aka_sim_init(void)
Definition base.c:284
fr_value_box_t const * enum_eap_type_aka
Definition base.c:186
size_t fr_aka_sim_octets_prefix_len(fr_dict_attr_t const *da)
Return the number of bytes before the octets value.
Definition base.c:276
fr_dict_attr_t const * attr_eap_aka_sim_sres
Definition base.c:98
fr_dict_attr_t const * attr_eap_aka_sim_iv
Definition base.c:76
fr_dict_attr_t const * attr_eap_aka_sim_kc
Definition base.c:80
fr_value_box_t const * enum_eap_type_sim
Definition base.c:185
fr_dict_attr_t const * attr_eap_aka_sim_notification
Definition base.c:91
fr_dict_attr_t const * attr_eap_aka_sim_client_error_code
Definition base.c:66
fr_dict_attr_t const * attr_eap_aka_sim_hmac_extra_response
Definition base.c:72
fr_dict_attr_t const * attr_eap_aka_sim_auts
Definition base.c:62
fr_dict_attr_t const * attr_eap_aka_sim_k_re
Definition base.c:79
fr_dict_attr_t const * attr_eap_aka_sim_identity_type
Definition base.c:74
fr_dict_attr_t const * attr_eap_aka_sim_any_id_req
Definition base.c:60
fr_dict_attr_t const * attr_eap_aka_sim_k_encr
Definition base.c:78
fr_dict_attr_t const * attr_sim_sqn
Definition base.c:115
fr_dict_attr_t const * attr_eap_aka_sim_autn
Definition base.c:61
fr_dict_attr_t const * attr_eap_aka_sim_nonce_mt
Definition base.c:89
fr_dict_attr_t const * attr_eap_aka_sim_result_ind
Definition base.c:96
fr_dict_enum_autoload_t libfreeradius_aka_sim_dict_enum[]
Definition base.c:192
fr_dict_attr_t const * attr_eap_aka_sim_bidding
Definition base.c:63
fr_dict_t const * dict_eap_aka_sim
Definition base.c:48
fr_dict_attr_t const * attr_sim_opc
Definition base.c:114
fr_value_box_t const * enum_eap_type_aka_prime
Definition base.c:187
fr_dict_attr_t const * attr_sim_algo_version
Definition base.c:110
fr_dict_attr_t const * attr_eap_aka_sim_version_list
Definition base.c:100
fr_dict_attr_t const * attr_eap_aka_sim_mac
Definition base.c:84
static fr_dict_flag_parser_t const eap_aka_sim_flags[]
Definition base.c:248
fr_dict_autoload_t libfreeradius_aka_sim_dict[]
Definition base.c:51
fr_dict_attr_t const * attr_eap_aka_sim_res
Definition base.c:95
fr_dict_attr_t const * attr_eap_aka_sim_identity
Definition base.c:73
fr_dict_attr_t const * attr_eap_aka_sim_nonce_s
Definition base.c:90
fr_dict_attr_t const * attr_eap_aka_sim_encr_data
Definition base.c:69
fr_dict_attr_t const * attr_eap_aka_sim_counter
Definition base.c:67
fr_dict_attr_t const * attr_eap_aka_sim_selected_version
Definition base.c:97
fr_dict_attr_t const * attr_eap_aka_sim_method_hint
Definition base.c:85
fr_dict_attr_t const * attr_eap_aka_sim_kdf_identity
Definition base.c:82
fr_dict_attr_t const * attr_eap_aka_sim_kdf_input
Definition base.c:83
fr_dict_attr_t const * attr_eap_aka_sim_checkcode
Definition base.c:64
fr_dict_attr_autoload_t libfreeradius_aka_sim_dict_attr[]
Definition base.c:118
fr_dict_attr_t const * attr_eap_aka_sim_rand
Definition base.c:94
fr_dict_attr_t const * attr_eap_aka_sim_fullauth_id_req
Definition base.c:70
size_t const fr_aka_sim_attr_sizes[FR_TYPE_MAX+1][2]
SIM AT on-the-wire format attribute sizes.
Definition base.c:210
#define PERROR(_fmt,...)
Definition log.h:228
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_MAX
Number of defined data types.
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_UINT64
64 Bit unsigned integer.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_OCTETS
Raw octets.
unsigned int uint32_t
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
Definition table.h:653
An element in a lexicographically sorted array of name to num mappings.
Definition table.h:49
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition strerror.h:64
#define FR_TYPE_VARIABLE_SIZE
Definition types.h:291
#define FR_TYPE_STRUCTURAL
Definition types.h:296