|
Radcli library 2.0.0
A simple radius library -- new API reference
|
Building a request's attributes and reading back a reply's, through the radcli_avp_list/radcli_avp opaque types rather than radcli.h's VALUE_PAIR linked list. More...
Topics | |
| radcli_avp_add_*_by_num() – lookup-and-add in one call | |
| Convenience wrappers over radcli_dict_lookup_num() + the matching radcli_avp_add_*(), for the common case of a well-known attribute a caller already has a legacy PW_* constant for. | |
| radcli_avp_get_*_by_num() – lookup-and-get in one call | |
| Receive-side mirror of radcli2-avp-by-num: fold radcli_dict_lookup_num() + radcli_avp_get() + the matching typed getter into one call, for the common case of a well-known, single-occurrence attribute a caller already has a legacy PW_* constant for. | |
| radcli_avp_concat_str()/_by_num() – join every occurrence of a text attribute | |
| Concatenate every occurrence of an attribute into a bounded buffer, following snprintf()'s buffer-sizing contract (buf may be NULL/buflen may be 0 to size a buffer first; the return value is always the number of bytes the joined result would occupy, whether or not it fit). | |
Data Structures | |
| struct | radcli_avp_iter |
Typedefs | |
| typedef struct radcli_avp_st | radcli_avp |
| typedef struct radcli_avp_list_st | radcli_avp_list |
Functions | |
| radcli_avp_list * | radcli_avp_list_new (void) |
| Create an empty attribute-value pair list. | |
| void | radcli_avp_list_free (radcli_avp_list *list) |
| Free a list and every attribute it holds. | |
| int | radcli_avp_add_bytes (radcli_avp_list *list, const radcli_attr_def *def, const void *value, size_t len) |
| Append an attribute holding an arbitrary byte string. | |
| int | radcli_avp_add_str (radcli_avp_list *list, const radcli_attr_def *def, const char *value) |
| Append a string- or text-typed attribute. | |
| int | radcli_avp_add_uint32 (radcli_avp_list *list, const radcli_attr_def *def, uint32_t value) |
| Append an integer/IPv4-address/date-typed attribute. | |
| int | radcli_avp_add_uint64 (radcli_avp_list *list, const radcli_attr_def *def, uint64_t value) |
| Append a 64-bit integer- or ifid-typed attribute. | |
| int | radcli_avp_add_ip4 (radcli_avp_list *list, const radcli_attr_def *def, struct in_addr value) |
| Append an IPv4-address-typed attribute from a struct in_addr. | |
| int | radcli_avp_add_ip6 (radcli_avp_list *list, const radcli_attr_def *def, const struct in6_addr *value, unsigned prefix) |
| Append an IPv6-address or IPv6-prefix-typed attribute. | |
| int | radcli_avp_add_ip4prefix (radcli_avp_list *list, const radcli_attr_def *def, struct in_addr value, unsigned prefix) |
| Append an IPv4-prefix-typed attribute. | |
| int | radcli_avp_add_bytes_by_num (radcli_avp_list *list, const radcli_ctx *ctx, uint32_t attrid, uint32_t vendor, const void *value, size_t len) |
| Look up an attribute by legacy numeric ID and append its bytes. | |
| int | radcli_avp_add_str_by_num (radcli_avp_list *list, const radcli_ctx *ctx, uint32_t attrid, uint32_t vendor, const char *value) |
| Look up a string-typed attribute by legacy numeric ID and append it. | |
| int | radcli_avp_add_uint32_by_num (radcli_avp_list *list, const radcli_ctx *ctx, uint32_t attrid, uint32_t vendor, uint32_t value) |
| Look up an integer/IPv4-address/date-typed attribute by legacy numeric ID and append it. | |
| int | radcli_avp_add_uint64_by_num (radcli_avp_list *list, const radcli_ctx *ctx, uint32_t attrid, uint32_t vendor, uint64_t value) |
| Look up a 64-bit integer-typed attribute by legacy numeric ID and append it. | |
| int | radcli_avp_add_ip4_by_num (radcli_avp_list *list, const radcli_ctx *ctx, uint32_t attrid, uint32_t vendor, struct in_addr value) |
| Look up an IPv4-address-typed attribute by legacy numeric ID and append it. | |
| int | radcli_avp_add_ip6_by_num (radcli_avp_list *list, const radcli_ctx *ctx, uint32_t attrid, uint32_t vendor, const struct in6_addr *value, unsigned prefix) |
| Look up an IPv6-address or IPv6-prefix-typed attribute by legacy numeric ID and append it. | |
| int | radcli_avp_add_ip4prefix_by_num (radcli_avp_list *list, const radcli_ctx *ctx, uint32_t attrid, uint32_t vendor, struct in_addr value, unsigned prefix) |
| Look up an IPv4-prefix-typed attribute by legacy numeric ID and append it. | |
| int | radcli_avp_add_username (radcli_avp_list *list, const radcli_ctx *ctx, const char *username, const char *realm) |
| Append a User-Name AVP, appending a realm as "username@realm" unless username already contains one. | |
| const radcli_avp * | radcli_avp_get (const radcli_avp_list *list, const radcli_attr_def *def, unsigned idx) |
| Find the idx-th occurrence of an attribute in a list. | |
| radcli_avp_iter | radcli_avp_list_iter (const radcli_avp_list *list) |
| Begin iterating list. | |
| const radcli_avp * | radcli_avp_iter_next (radcli_avp_iter *it) |
| Return the current attribute and advance. | |
| const radcli_attr_def * | radcli_avp_def (const radcli_avp *a) |
| Return the attribute definition of a. | |
| int | radcli_avp_get_uint32 (const radcli_avp *a, uint32_t *out) |
| Read an attribute's value as an integer/IPv4-address/date. | |
| int | radcli_avp_get_uint64 (const radcli_avp *a, uint64_t *out) |
| Read an attribute's value as a 64-bit integer or ifid. | |
| int | radcli_avp_get_ip6 (const radcli_avp *a, struct in6_addr *out, unsigned *prefix) |
| Read an attribute's value as an IPv6 address or prefix. | |
| int | radcli_avp_get_ip4prefix (const radcli_avp *a, struct in_addr *out, unsigned *prefix) |
| Read an attribute's value as an IPv4 prefix. | |
| int | radcli_avp_get_bytes (const radcli_avp *a, const void **out, size_t *len) |
| Read an attribute's value as raw bytes. | |
| const char * | radcli_avp_get_cstr (const radcli_avp *a) |
| Read an attribute's value as a NUL-terminated string, with no allocation or copy. | |
| const radcli_avp * | radcli_avp_get_by_num (const radcli_avp_list *list, const radcli_ctx *ctx, uint32_t attrid, uint32_t vendor, unsigned idx) |
| Look up the idx-th occurrence of an attribute by legacy numeric ID. | |
| int | radcli_avp_get_uint32_by_num (const radcli_avp_list *list, const radcli_ctx *ctx, uint32_t attrid, uint32_t vendor, uint32_t *out) |
| Look up an integer/IPv4-address/date-typed attribute by legacy numeric ID and read its first occurrence. | |
| int | radcli_avp_get_uint64_by_num (const radcli_avp_list *list, const radcli_ctx *ctx, uint32_t attrid, uint32_t vendor, uint64_t *out) |
| Look up a 64-bit integer-typed attribute by legacy numeric ID and read its first occurrence. | |
| int | radcli_avp_get_ip6_by_num (const radcli_avp_list *list, const radcli_ctx *ctx, uint32_t attrid, uint32_t vendor, struct in6_addr *out, unsigned *prefix) |
| Look up an IPv6-address or IPv6-prefix-typed attribute by legacy numeric ID and read its first occurrence. | |
| int | radcli_avp_get_ip4prefix_by_num (const radcli_avp_list *list, const radcli_ctx *ctx, uint32_t attrid, uint32_t vendor, struct in_addr *out, unsigned *prefix) |
| Look up an IPv4-prefix-typed attribute by legacy numeric ID and read its first occurrence. | |
| int | radcli_avp_get_bytes_by_num (const radcli_avp_list *list, const radcli_ctx *ctx, uint32_t attrid, uint32_t vendor, const void **out, size_t *len) |
| Look up an attribute by legacy numeric ID and read its first occurrence's raw bytes. | |
| const char * | radcli_avp_get_cstr_by_num (const radcli_avp_list *list, const radcli_ctx *ctx, uint32_t attrid, uint32_t vendor) |
| Look up an attribute by legacy numeric ID and read its first occurrence as a NUL-terminated string. | |
| int | radcli_avp_concat_str (char *buf, size_t buflen, const radcli_avp_list *list, const radcli_attr_def *def, const char *sep) |
| Concatenate every occurrence of an attribute into a bounded buffer. | |
| int | radcli_avp_concat_str_by_num (char *buf, size_t buflen, const radcli_avp_list *list, const radcli_ctx *ctx, uint32_t attrid, uint32_t vendor, const char *sep) |
| Look up an attribute by legacy numeric ID and concatenate every occurrence into a bounded buffer. | |
| int | radcli_avp_list_error (const radcli_avp_list *list) |
| Check whether any radcli_avp_add_*()/_by_num() call on list has ever failed. | |
| int | radcli_avp_add_gigawords64 (radcli_ctx *ctx, radcli_avp_list *list, const radcli_attr_def *octets, uint64_t value) |
| Append a 64-bit counter as an Octets/Gigawords attribute pair. | |
| int | radcli_avp_get_gigawords64 (const radcli_ctx *ctx, const radcli_avp_list *list, const radcli_attr_def *octets, uint64_t *out) |
| Reassemble a 64-bit counter from an Octets/Gigawords attribute pair. | |
| int | radcli_avp_add_gigawords64_by_num (radcli_ctx *ctx, radcli_avp_list *list, uint32_t attrid, uint32_t vendor, uint64_t value) |
| Look up the octets attribute by legacy numeric ID and append a 64-bit counter as an Octets/Gigawords pair. | |
| int | radcli_avp_get_gigawords64_by_num (const radcli_ctx *ctx, const radcli_avp_list *list, uint32_t attrid, uint32_t vendor, uint64_t *out) |
| Look up the octets attribute by legacy numeric ID and reassemble a 64-bit counter from an Octets/Gigawords pair. | |
Building a request's attributes and reading back a reply's, through the radcli_avp_list/radcli_avp opaque types rather than radcli.h's VALUE_PAIR linked list.
| int radcli_avp_add_bytes | ( | radcli_avp_list * | list, |
| const radcli_attr_def * | def, | ||
| const void * | value, | ||
| size_t | len ) |
Append an attribute holding an arbitrary byte string.
The primitive every other radcli_avp_add_*() function is defined in terms of; valid for any attribute type, since the underlying representation is always length-carrying bytes.
| list | destination list. |
| def | the attribute, from radcli_dict_lookup() or a sibling. |
| value | the bytes to copy in; may be NULL only if len is 0. |
| len | number of bytes at value. |
| int radcli_avp_add_bytes_by_num | ( | radcli_avp_list * | list, |
| const radcli_ctx * | ctx, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor, | ||
| const void * | value, | ||
| size_t | len ) |
Look up an attribute by legacy numeric ID and append its bytes.
| list | destination list. |
| ctx | a context with a dictionary loaded. |
| attrid | the attribute ID (a PW_* constant, or a vendor type ID when vendor is non-zero). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| value | the bytes to copy in; may be NULL only if len is 0. |
| len | number of bytes at value. |
| int radcli_avp_add_gigawords64 | ( | radcli_ctx * | ctx, |
| radcli_avp_list * | list, | ||
| const radcli_attr_def * | octets, | ||
| uint64_t | value ) |
Append a 64-bit counter as an Octets/Gigawords attribute pair.
No standard RADIUS attribute counts octets as a 64-bit integer; real 64-bit accounting is done with a pair of 32-bit attributes – e.g. Acct-Input-Octets (the low 32 bits) and Acct-Input-Gigawords (the high 32 bits) – which is what every deployed server actually implements. This is the one call an accounting caller needs instead of computing and adding both halves by hand.
Implements the Acct-Input/Output-Octets (RFC 2866 SS5.3/5.4) plus Acct-Input/Output-Gigawords (RFC 2869 SS5.1/5.2) pairing: Gigawords holds the number of times its Octets counterpart has wrapped past 2^32, so the pair together give a 64-bit octet count. Not RADCLI_TYPE_INTEGER64/RFC 8044 – no standard accounting attribute uses that type.
octets' Gigawords counterpart is looked up from the dictionary (an ATTRIBUTE line's "gigawords=" option, etc/dictionary), not derived from its name, so passing an attribute with no such counterpart configured is an error rather than a silent truncation to 32 bits. The gigawords attribute is omitted from list when it would be zero (value fits in 32 bits), matching how a real NAS sends it.
| ctx | the context octets was looked up from – the gigawords= pairing is recorded per dictionary, not on radcli_attr_def itself (that would need a public struct field, and the struct is frozen ABI), so finding it means searching ctx's loaded dictionary. |
| list | destination list. |
| octets | the octets attribute (e.g. Acct-Input-Octets); its dictionary entry must declare a gigawords= counterpart. |
| value | the full 64-bit count. |
| int radcli_avp_add_gigawords64_by_num | ( | radcli_ctx * | ctx, |
| radcli_avp_list * | list, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor, | ||
| uint64_t | value ) |
Look up the octets attribute by legacy numeric ID and append a 64-bit counter as an Octets/Gigawords pair.
The _by_num() wrapper for radcli_avp_add_gigawords64(): unlike the other _by_num() wrappers, only one attribute ID is needed here, not two – the Gigawords counterpart is resolved from octets' own dictionary entry (its gigawords= option), the same way radcli_avp_add_gigawords64() resolves it from a radcli_attr_def *.
| ctx | a context with a dictionary loaded. |
| list | destination list. |
| attrid | the octets attribute's ID (e.g. PW_ACCT_INPUT_OCTETS). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| value | the full 64-bit count. |
| int radcli_avp_add_ip4 | ( | radcli_avp_list * | list, |
| const radcli_attr_def * | def, | ||
| struct in_addr | value ) |
Append an IPv4-address-typed attribute from a struct in_addr.
| list | destination list. |
| def | the attribute; must be RADCLI_TYPE_IPADDR. |
| value | the address, in the usual network byte order struct in_addr carries. |
| int radcli_avp_add_ip4_by_num | ( | radcli_avp_list * | list, |
| const radcli_ctx * | ctx, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor, | ||
| struct in_addr | value ) |
Look up an IPv4-address-typed attribute by legacy numeric ID and append it.
| list | destination list. |
| ctx | a context with a dictionary loaded. |
| attrid | the attribute ID (a PW_* constant, or a vendor type ID when vendor is non-zero). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| value | the address, in the usual network byte order struct in_addr carries. |
| int radcli_avp_add_ip4prefix | ( | radcli_avp_list * | list, |
| const radcli_attr_def * | def, | ||
| struct in_addr | value, | ||
| unsigned | prefix ) |
Append an IPv4-prefix-typed attribute.
The RFC 8044 SS3.9 wire format is built internally: a reserved zero octet, the prefix length, and the 4-octet address.
A dedicated function rather than a prefix parameter on radcli_avp_add_ip4(): unlike radcli_avp_add_ip6() (which took a prefix parameter from its introduction), radcli_avp_add_ip4() already shipped without one, with real callers; adding one now would force every existing caller to update for a type most of them don't use.
| list | destination list. |
| def | the attribute; must be RADCLI_TYPE_IPV4PREFIX. |
| value | the address. |
| prefix | the prefix length (0-32). |
| int radcli_avp_add_ip4prefix_by_num | ( | radcli_avp_list * | list, |
| const radcli_ctx * | ctx, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor, | ||
| struct in_addr | value, | ||
| unsigned | prefix ) |
Look up an IPv4-prefix-typed attribute by legacy numeric ID and append it.
| list | destination list. |
| ctx | a context with a dictionary loaded. |
| attrid | the attribute ID (a PW_* constant, or a vendor type ID when vendor is non-zero). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| value | the address. |
| prefix | the prefix length (0-32). |
| int radcli_avp_add_ip6 | ( | radcli_avp_list * | list, |
| const radcli_attr_def * | def, | ||
| const struct in6_addr * | value, | ||
| unsigned | prefix ) |
Append an IPv6-address or IPv6-prefix-typed attribute.
For RADCLI_TYPE_IPV6ADDR, prefix MUST be 0 (a plain address has no prefix). For RADCLI_TYPE_IPV6PREFIX, the RFC 3162 wire format is built internally: a reserved zero octet, the prefix length, and the full 16-octet address.
| list | destination list. |
| def | the attribute; must be RADCLI_TYPE_IPV6ADDR or RADCLI_TYPE_IPV6PREFIX. |
| value | the address. |
| prefix | the prefix length (0-128); ignored/must be 0 for RADCLI_TYPE_IPV6ADDR. |
| int radcli_avp_add_ip6_by_num | ( | radcli_avp_list * | list, |
| const radcli_ctx * | ctx, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor, | ||
| const struct in6_addr * | value, | ||
| unsigned | prefix ) |
Look up an IPv6-address or IPv6-prefix-typed attribute by legacy numeric ID and append it.
| list | destination list. |
| ctx | a context with a dictionary loaded. |
| attrid | the attribute ID (a PW_* constant, or a vendor type ID when vendor is non-zero). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| value | the address. |
| prefix | the prefix length (0-128); ignored/must be 0 for RADCLI_TYPE_IPV6ADDR. |
| int radcli_avp_add_str | ( | radcli_avp_list * | list, |
| const radcli_attr_def * | def, | ||
| const char * | value ) |
Append a string- or text-typed attribute.
Accepts both RADCLI_TYPE_STRING and RADCLI_TYPE_TEXT attributes. For RADCLI_TYPE_STRING, value's bytes are copied verbatim (opaque octets, no validation) – unchanged from this function's original behavior, so that a caller already using it against an attribute later retagged from "string" to "text" (RFC 8044 SS3.1) in the dictionary keeps working rather than starting to fail with the retag. For RADCLI_TYPE_TEXT, value must additionally be valid UTF-8; invalid UTF-8 is rejected rather than stored.
| list | destination list. |
| def | the attribute; must be RADCLI_TYPE_STRING or RADCLI_TYPE_TEXT. |
| value | a null-terminated string. |
| int radcli_avp_add_str_by_num | ( | radcli_avp_list * | list, |
| const radcli_ctx * | ctx, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor, | ||
| const char * | value ) |
Look up a string-typed attribute by legacy numeric ID and append it.
| list | destination list. |
| ctx | a context with a dictionary loaded. |
| attrid | the attribute ID (a PW_* constant, or a vendor type ID when vendor is non-zero). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| value | a null-terminated string. |
| int radcli_avp_add_uint32 | ( | radcli_avp_list * | list, |
| const radcli_attr_def * | def, | ||
| uint32_t | value ) |
Append an integer/IPv4-address/date-typed attribute.
| list | destination list. |
| def | the attribute; must be RADCLI_TYPE_INTEGER, RADCLI_TYPE_IPADDR, or RADCLI_TYPE_DATE. |
| value | the value; an IPv4 address is given in host byte order. |
| int radcli_avp_add_uint32_by_num | ( | radcli_avp_list * | list, |
| const radcli_ctx * | ctx, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor, | ||
| uint32_t | value ) |
Look up an integer/IPv4-address/date-typed attribute by legacy numeric ID and append it.
| list | destination list. |
| ctx | a context with a dictionary loaded. |
| attrid | the attribute ID (a PW_* constant, or a vendor type ID when vendor is non-zero). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| value | the value; an IPv4 address is given in host byte order. |
| int radcli_avp_add_uint64 | ( | radcli_avp_list * | list, |
| const radcli_attr_def * | def, | ||
| uint64_t | value ) |
Append a 64-bit integer- or ifid-typed attribute.
| list | destination list. |
| def | the attribute; must be RADCLI_TYPE_INTEGER64 or RADCLI_TYPE_IFID (RFC 8044 SS3.7's "ifid" data type – an opaque 8-octet value, but identical in wire shape to RADCLI_TYPE_INTEGER64, so it shares this setter rather than getting its own). |
| value | the value; for RADCLI_TYPE_IFID, the raw 8 octets read as a big-endian uint64_t. |
| int radcli_avp_add_uint64_by_num | ( | radcli_avp_list * | list, |
| const radcli_ctx * | ctx, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor, | ||
| uint64_t | value ) |
Look up a 64-bit integer-typed attribute by legacy numeric ID and append it.
| list | destination list. |
| ctx | a context with a dictionary loaded. |
| attrid | the attribute ID (a PW_* constant, or a vendor type ID when vendor is non-zero). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| value | the value. |
| int radcli_avp_add_username | ( | radcli_avp_list * | list, |
| const radcli_ctx * | ctx, | ||
| const char * | username, | ||
| const char * | realm ) |
Append a User-Name AVP, appending a realm as "username@realm" unless username already contains one.
Written for callers (e.g. an application reading its own "default_realm" config knob) that need to send "username@realm" only when the caller- supplied username didn't already come with a realm attached. Passing realm as NULL reaches for ctx's own "default_realm" configuration option, so an application whose realm policy is just "whatever this ctx's config file says" never needs to read that option out itself.
| list | destination list. |
| ctx | a context with a dictionary defining User-Name (any radcli_ctx_new()/radcli_ctx_read_config() context qualifies). |
| username | the username; used as-is if it already contains '@'. |
| realm | realm to append if username has no '@': NULL uses ctx's own "default_realm" configuration option (no realm appended if that option is unset or empty); "" explicitly suppresses appending a realm even if "default_realm" is configured; any other string is used verbatim. |
| int radcli_avp_concat_str | ( | char * | buf, |
| size_t | buflen, | ||
| const radcli_avp_list * | list, | ||
| const radcli_attr_def * | def, | ||
| const char * | sep ) |
Concatenate every occurrence of an attribute into a bounded buffer.
Generalizes the one convenience legacy radcli.h's rc_aaa() folded into its own call signature (its msg parameter: "will contain the concatenation of any PW_REPLY_MESSAGE received", lib/buildreq.c) to any attribute, since the pattern – walk every occurrence of one attribute in a reply, join as text – is not specific to Reply-Message. A caller wanting rc_aaa()'s old convenience no longer needs to hand-roll the radcli_avp_get()-in-a-loop this replaces.
If no occurrence of def is present in list, buf is set to an empty string and 0 is returned – this is not a failure, the same way rc_aaa()'s msg started as '\0' and simply stayed that way when no Reply-Message arrived. An attribute whose value contains an embedded NUL byte, or (for a RADCLI_TYPE_TEXT attribute) invalid UTF-8, is skipped (radcli_avp_get_cstr()'s policy), not treated as a failure either.
Follows snprintf()'s buffer-sizing contract exactly: buf may be NULL and/or buflen may be 0 to size a buffer before allocating one (nothing is written in that case), and the return value is always the number of bytes the joined result would occupy, whether or not it fit – a return >= buflen means the result was truncated, and buf (if non-NULL and buflen > 0) then holds only a valid NUL-terminated prefix of what fits, never garbage and never unterminated.
| buf | destination buffer, or NULL to only compute the needed size; always left NUL-terminated on return (including on truncation, containing whatever fit), whenever buf is non-NULL and buflen > 0. |
| buflen | size of buf, in bytes; may be 0. |
| list | the list to search. |
| def | the attribute to concatenate occurrences of. |
| sep | separator inserted between occurrences; NULL or "" for none. |
| int radcli_avp_concat_str_by_num | ( | char * | buf, |
| size_t | buflen, | ||
| const radcli_avp_list * | list, | ||
| const radcli_ctx * | ctx, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor, | ||
| const char * | sep ) |
Look up an attribute by legacy numeric ID and concatenate every occurrence into a bounded buffer.
The _by_num() wrapper for radcli_avp_concat_str(): equivalent to radcli_avp_concat_str(buf, buflen, l, radcli_dict_lookup_num(ctx, attrid, vendor), sep), except that an unresolvable attribute ID is not itself a failure here – it is treated the same as "no occurrence present" (buf set to an empty string, 0 returned), matching this function's legacy-ID convenience role: a caller passing a well-known PW_* constant should not have to separately handle "not in this dictionary" as an error case, the same way rc_aaa()'s msg never failed just because a reply had no Reply-Message.
| buf | destination buffer, or NULL to only compute the needed size; see radcli_avp_concat_str(). |
| buflen | size of buf, in bytes; may be 0. |
| list | the list to search. |
| ctx | a context with a dictionary loaded. |
| attrid | the attribute ID (a PW_* constant, or a vendor type ID when vendor is non-zero). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| sep | separator inserted between occurrences; NULL or "" for none. |
| const radcli_attr_def * radcli_avp_def | ( | const radcli_avp * | a | ) |
| const radcli_avp * radcli_avp_get | ( | const radcli_avp_list * | list, |
| const radcli_attr_def * | def, | ||
| unsigned | idx ) |
| const radcli_avp * radcli_avp_get_by_num | ( | const radcli_avp_list * | list, |
| const radcli_ctx * | ctx, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor, | ||
| unsigned | idx ) |
Look up the idx-th occurrence of an attribute by legacy numeric ID.
| list | the list to search. |
| ctx | a context with a dictionary loaded. |
| attrid | the attribute ID (a PW_* constant, or a vendor type ID when vendor is non-zero). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| idx | 0 for the first occurrence, 1 for the second, and so on. |
| int radcli_avp_get_bytes | ( | const radcli_avp * | a, |
| const void ** | out, | ||
| size_t * | len ) |
Read an attribute's value as raw bytes.
Valid for every attribute type, since the underlying representation is always length-carrying bytes; the interpretation of those bytes for integer/IPv4/date-typed attributes matches radcli_avp_get_uint32()'s.
| a | the attribute. |
| out | where to write a pointer to the value; valid for a's lifetime. May be NULL. |
| len | where to write the value's length in bytes. May be NULL. |
| int radcli_avp_get_bytes_by_num | ( | const radcli_avp_list * | list, |
| const radcli_ctx * | ctx, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor, | ||
| const void ** | out, | ||
| size_t * | len ) |
Look up an attribute by legacy numeric ID and read its first occurrence's raw bytes.
| list | the list to search. |
| ctx | a context with a dictionary loaded. |
| attrid | the attribute ID (a PW_* constant, or a vendor type ID when vendor is non-zero). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| out | where to write a pointer to the value; valid for list's lifetime. May be NULL. |
| len | where to write the value's length in bytes. May be NULL. |
| const char * radcli_avp_get_cstr | ( | const radcli_avp * | a | ) |
Read an attribute's value as a NUL-terminated string, with no allocation or copy.
Meaningful for RADCLI_TYPE_STRING and RADCLI_TYPE_TEXT attributes, but callable on any type, like radcli_avp_get_bytes() – every attribute is stored with a trailing NUL one byte past its real length, so this never allocates. Returns NULL, rather than a silently short string, if the value contains an embedded NUL byte before its real end (logged at LOG_WARNING): a server-supplied value of e.g. "admin\0attacker" must not be readable back as the trusted string "admin" by any caller that treats this return value as the whole attribute. Use radcli_avp_get_bytes() instead for an attribute where an embedded NUL is expected and meaningful (e.g. one whose dictionary type is not RADCLI_TYPE_STRING or RADCLI_TYPE_TEXT).
For a RADCLI_TYPE_TEXT attribute specifically, this also returns NULL (logged at LOG_WARNING) if the value is not valid UTF-8 (RFC 8044 SS3.1) – checked here as well as in radcli_avp_add_str(), since an attribute can also be populated by radcli_avp_decode() from a received packet, whose bytes never went through add-side validation. RADCLI_TYPE_STRING attributes have no such requirement: NUL-checked only, like every other type.
| a | the attribute. |
| const char * radcli_avp_get_cstr_by_num | ( | const radcli_avp_list * | list, |
| const radcli_ctx * | ctx, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor ) |
Look up an attribute by legacy numeric ID and read its first occurrence as a NUL-terminated string.
| list | the list to search. |
| ctx | a context with a dictionary loaded. |
| attrid | the attribute ID (a PW_* constant, or a vendor type ID when vendor is non-zero). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| int radcli_avp_get_gigawords64 | ( | const radcli_ctx * | ctx, |
| const radcli_avp_list * | list, | ||
| const radcli_attr_def * | octets, | ||
| uint64_t * | out ) |
Reassemble a 64-bit counter from an Octets/Gigawords attribute pair.
| ctx | the context octets was looked up from; see radcli_avp_add_gigawords64(). |
| list | the list to search (via radcli_avp_get()). |
| octets | the octets attribute; its dictionary entry must declare a gigawords= counterpart, as for radcli_avp_add_gigawords64(). |
| out | where to write the reassembled value; may be NULL to just check validity. |
| int radcli_avp_get_gigawords64_by_num | ( | const radcli_ctx * | ctx, |
| const radcli_avp_list * | list, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor, | ||
| uint64_t * | out ) |
Look up the octets attribute by legacy numeric ID and reassemble a 64-bit counter from an Octets/Gigawords pair.
| ctx | a context with a dictionary loaded. |
| list | the list to search. |
| attrid | the octets attribute's ID (e.g. PW_ACCT_INPUT_OCTETS). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| out | where to write the reassembled value; may be NULL to just check validity. |
| int radcli_avp_get_ip4prefix | ( | const radcli_avp * | a, |
| struct in_addr * | out, | ||
| unsigned * | prefix ) |
Read an attribute's value as an IPv4 prefix.
| a | the attribute; radcli_avp_def(a) must be RADCLI_TYPE_IPV4PREFIX. |
| out | where to write the address (zero-padded beyond the prefix length); may be NULL. |
| prefix | where to write the prefix length; may be NULL. |
| int radcli_avp_get_ip4prefix_by_num | ( | const radcli_avp_list * | list, |
| const radcli_ctx * | ctx, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor, | ||
| struct in_addr * | out, | ||
| unsigned * | prefix ) |
Look up an IPv4-prefix-typed attribute by legacy numeric ID and read its first occurrence.
| list | the list to search. |
| ctx | a context with a dictionary loaded. |
| attrid | the attribute ID (a PW_* constant, or a vendor type ID when vendor is non-zero). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| out | where to write the address. May be NULL. |
| prefix | where to write the prefix length. May be NULL. |
| int radcli_avp_get_ip6 | ( | const radcli_avp * | a, |
| struct in6_addr * | out, | ||
| unsigned * | prefix ) |
Read an attribute's value as an IPv6 address or prefix.
| a | the attribute; radcli_avp_def(a) must be RADCLI_TYPE_IPV6ADDR or RADCLI_TYPE_IPV6PREFIX. |
| out | where to write the address (zero-padded beyond the prefix length for RADCLI_TYPE_IPV6PREFIX); may be NULL. |
| prefix | where to write the prefix length (128 for RADCLI_TYPE_IPV6ADDR); may be NULL. |
| int radcli_avp_get_ip6_by_num | ( | const radcli_avp_list * | list, |
| const radcli_ctx * | ctx, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor, | ||
| struct in6_addr * | out, | ||
| unsigned * | prefix ) |
Look up an IPv6-address or IPv6-prefix-typed attribute by legacy numeric ID and read its first occurrence.
| list | the list to search. |
| ctx | a context with a dictionary loaded. |
| attrid | the attribute ID (a PW_* constant, or a vendor type ID when vendor is non-zero). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| out | where to write the address. May be NULL. |
| prefix | where to write the prefix length. May be NULL. |
| int radcli_avp_get_uint32 | ( | const radcli_avp * | a, |
| uint32_t * | out ) |
Read an attribute's value as an integer/IPv4-address/date.
| a | the attribute; radcli_avp_def(a) must be RADCLI_TYPE_INTEGER, RADCLI_TYPE_IPADDR, or RADCLI_TYPE_DATE. An IPv4 address is returned in host byte order. |
| out | where to write the value; may be NULL to just check validity. |
| int radcli_avp_get_uint32_by_num | ( | const radcli_avp_list * | list, |
| const radcli_ctx * | ctx, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor, | ||
| uint32_t * | out ) |
Look up an integer/IPv4-address/date-typed attribute by legacy numeric ID and read its first occurrence.
| list | the list to search. |
| ctx | a context with a dictionary loaded. |
| attrid | the attribute ID (a PW_* constant, or a vendor type ID when vendor is non-zero). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| out | where to write the value; an IPv4 address is returned in host byte order. May be NULL. |
| int radcli_avp_get_uint64 | ( | const radcli_avp * | a, |
| uint64_t * | out ) |
Read an attribute's value as a 64-bit integer or ifid.
| a | the attribute; radcli_avp_def(a) must be RADCLI_TYPE_INTEGER64 or RADCLI_TYPE_IFID – see radcli_avp_add_uint64() for why the two types share this getter. |
| out | where to write the value (a big-endian uint64_t for RADCLI_TYPE_IFID); may be NULL to just check validity. |
| int radcli_avp_get_uint64_by_num | ( | const radcli_avp_list * | list, |
| const radcli_ctx * | ctx, | ||
| uint32_t | attrid, | ||
| uint32_t | vendor, | ||
| uint64_t * | out ) |
Look up a 64-bit integer-typed attribute by legacy numeric ID and read its first occurrence.
| list | the list to search. |
| ctx | a context with a dictionary loaded. |
| attrid | the attribute ID (a PW_* constant, or a vendor type ID when vendor is non-zero). |
| vendor | the vendor PEN, or 0 for a standard attribute. |
| out | where to write the value. May be NULL. |
| const radcli_avp * radcli_avp_iter_next | ( | radcli_avp_iter * | it | ) |
Return the current attribute and advance.
| it | an iterator from radcli_avp_list_iter(). |
| int radcli_avp_list_error | ( | const radcli_avp_list * | list | ) |
Check whether any radcli_avp_add_*()/_by_num() call on list has ever failed.
Once any add call on a given list fails, the list remembers it (sticky – the first failure, not just the most recent). This lets a caller build a whole request as a flat sequence of add calls with no per-call check, then check once, here, before sending – instead of the ~6-line "if (radcli_avp_add_...(...) != 0) { log; abort; }" block repeated at every call site, which has only one realistic recovery action (abort the whole request) regardless of which attribute failed to add.
Purely observational: it does not change any radcli_avp_add_*()'s own behavior. Every add call is attempted and returns its own 0/-1 exactly as it would without this function existing, even after an earlier add on the same list has already failed – a caller checking each call individually (or deliberately testing that one bad attribute is rejected before adding others, as tests/avp.c does) sees no difference. This function only adds a second, aggregate way to notice a failure that already happened, for a caller that would rather check once than at every call site.
| list | the list to check; NULL counts as an error (nothing to build onto), matching how every radcli_avp_add_*() already treats a NULL list as failure – so a caller does not need a separate if (list == NULL) check right after radcli_avp_list_new() before relying on this. |
| void radcli_avp_list_free | ( | radcli_avp_list * | list | ) |
Free a list and every attribute it holds.
| list | a list from radcli_avp_list_new(); NULL is accepted and ignored. |
| radcli_avp_iter radcli_avp_list_iter | ( | const radcli_avp_list * | list | ) |
| radcli_avp_list * radcli_avp_list_new | ( | void | ) |
Create an empty attribute-value pair list.