From a13cddc1331aa1f5e7dca7d1b44482951d2757bf Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Sun, 13 Nov 2011 17:16:14 +1100 Subject: port to new RADIUS client library --- lib/avp.c | 457 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 457 insertions(+) create mode 100644 lib/avp.c (limited to 'lib/avp.c') diff --git a/lib/avp.c b/lib/avp.c new file mode 100644 index 0000000..1bc1128 --- /dev/null +++ b/lib/avp.c @@ -0,0 +1,457 @@ +/* Copyright 2011 PADL Software Pty Ltd. All rights reserved. + See the file COPYING for licensing information. */ + +#if defined HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define RS_ERR(err) ((err) < 0 ? -err : RSE_OK) + +void +rs_avp_free (rs_avp **vps) +{ + nr_vp_free (vps); +} + +size_t +rs_avp_length (rs_const_avp *vp) +{ + assert (vp != NULL); + return vp->length; +} + +rs_attr_type_t +rs_avp_typeof (rs_const_avp *vp) +{ + return vp ? vp->da->type : RS_TYPE_INVALID; +} + +void +rs_avp_attrid (rs_const_avp *vp, + unsigned int *attr, + unsigned int *vendor) +{ + *attr = vp->da->attr; + *vendor = vp->da->vendor; +} + +const char * +rs_avp_name (rs_const_avp *vp) +{ + return vp ? vp->da->name : NULL; +} + +void +rs_avp_append (rs_avp **head, rs_avp *tail) +{ + return nr_vps_append (head, tail); +} + +rs_avp * +rs_avp_find (rs_avp *vp, unsigned int attr, unsigned int vendor) +{ + if (vp == NULL) + return NULL; + + return nr_vps_find (vp, attr, vendor); +} + +rs_const_avp * +rs_avp_find_const (rs_const_avp *vp, + unsigned int attr, unsigned int vendor) +{ + if (vp == NULL) + return NULL; + + return nr_vps_find ((rs_avp *)vp, attr, vendor); +} + +rs_avp * +rs_avp_alloc (unsigned int attr, unsigned int vendor) +{ + const DICT_ATTR *da; + VALUE_PAIR *vp; + + da = nr_dict_attr_byvalue (attr, vendor); + if (da == NULL) { + vp = nr_vp_alloc_raw (attr, vendor); + } else { + vp = nr_vp_alloc (da); + } + + if (vp == NULL) + return NULL; + + return vp; +} + +rs_avp * +rs_avp_dup (rs_const_avp *vp) +{ + rs_avp *vp2; + + vp2 = nr_vp_alloc (vp->da); + if (vp2 == NULL) + return NULL; + + vp2->length = vp->length; + vp2->tag = vp->tag; + vp2->next = NULL; + +#ifdef RS_TYPE_TLV + if (rs_avp_is_tlv (vp)) { + vp2->vp_tlv = malloc (vp->length); + if (vp2->vp_tlv == NULL) { + rs_avp_free (vp2); + return NULL; + } + memcpy (vp2->vp_tlv, vp->vp_tlv, vp->length); + return vp2; + } +#endif + + memcpy (vp2->vp_strvalue, vp->vp_strvalue, vp->length); + if (rs_avp_is_string (vp)) + vp2->vp_strvalue[vp->length] = '\0'; + + return vp2; +} + +rs_avp * +rs_avp_next (rs_avp *avp) +{ + return avp ? avp->next : NULL; +} + +rs_const_avp * +rs_avp_next_const (rs_const_avp *avp) +{ + return avp ? avp->next : NULL; +} + +int +rs_avp_delete (rs_avp **first, + unsigned int attr, unsigned int vendor) +{ + int found = 0; + rs_avp **p; + + for (p = first; *p != NULL; p++) { + if ((*p)->da->attr == attr && + (*p)->da->vendor == vendor) { + rs_avp *next = (*p)->next; + + (*p)->next = NULL; + rs_avp_free (p); + + *p = next; + found++; + } + } + + return found ? RSE_OK : RSE_ATTR_UNKNOWN; +} + +const char * +rs_avp_string_value (rs_const_avp *vp) +{ + if (!rs_avp_is_string (vp)) + return NULL; + + return vp->vp_strvalue; +} + +int +rs_avp_string_set (rs_avp *vp, const char *str) +{ + int err; + + if (vp == NULL) + return RSE_INVAL; + if (!rs_avp_is_string (vp)) + return RSE_ATTR_INVALID; + + err = nr_vp_set_data (vp, str, strlen (str)); + return RS_ERR(err); +} + +uint32_t +rs_avp_integer_value (rs_const_avp *vp) +{ + if (!rs_avp_is_integer (vp)) + return 0; + return vp->vp_integer; +} + +int +rs_avp_integer_set (rs_avp *vp, uint32_t val) +{ + int err; + + if (vp == NULL) + return RSE_INVAL; + if (!rs_avp_is_integer (vp)) + return RSE_ATTR_INVALID; + + err = nr_vp_set_data (vp, &val, sizeof (val)); + return RS_ERR(err); +} + +uint32_t +rs_avp_ipaddr_value (rs_const_avp *vp) +{ + if (!rs_avp_is_ipaddr (vp)) + return 0; + return vp->vp_ipaddr; +} + +int +rs_avp_ipaddr_set (rs_avp *vp, struct in_addr in) +{ + int err; + + if (vp == NULL) + return RSE_INVAL; + if (!rs_avp_is_ipaddr (vp)) + return RSE_ATTR_INVALID; + + err = nr_vp_set_data (vp, &in, sizeof (in)); + return RS_ERR(err); +} + +time_t +rs_avp_date_value (rs_const_avp *vp) +{ + if (!rs_avp_is_date (vp)) + return 0; + return vp->vp_date; +} + +int +rs_avp_date_set (rs_avp *vp, time_t date) +{ + uint32_t date32; + int err; + + if (vp == NULL) + return RSE_INVAL; + if (!rs_avp_is_date (vp)) + return RSE_ATTR_INVALID; + if (date > 0xFFFFFFFF) + return RSE_ATTR_INVALID; + + date32 = (uint32_t)date; + err = nr_vp_set_data (vp, &date32, sizeof (date32)); + + return RS_ERR(err); +} + +const unsigned char * +rs_avp_octets_value_const_ptr (rs_const_avp *vp) +{ + return rs_avp_octets_value_ptr ((rs_avp *)vp); +} + +unsigned char * +rs_avp_octets_value_ptr (rs_avp *vp) +{ + if (vp == NULL) + return NULL; + +#ifdef RS_TYPE_TLV + if (rs_avp_is_tlv (vp)) + return vp->vp_tlv; +#endif + + return vp->vp_octets; +} + +int +rs_avp_octets_value_byref (rs_avp *vp, + unsigned char **p, + size_t *len) +{ + if (vp == NULL) + return RSE_INVAL; + + *len = vp->length; + *p = (unsigned char *)rs_avp_octets_value_ptr (vp); + + return RSE_OK; +} + +int +rs_avp_octets_value (rs_const_avp *vp, + unsigned char *buf, + size_t *len) +{ + if (vp == NULL) + return RSE_INVAL; + + if (vp->length > *len) { + *len = vp->length; + return RSE_ATTR_TOO_SMALL; + } + + *len = vp->length; + +#ifdef RS_TYPE_TLV + if (rs_avp_is_tlv (vp)) + memcpy (buf, vp->vp_tlv, vp->length); + else +#endif + memcpy (buf, vp->vp_octets, vp->length); + + return RSE_OK; +} + +int +rs_avp_fragmented_value (rs_const_avp *vps, + unsigned char *buf, + size_t *len) +{ + size_t total_len = 0; + unsigned char *p; + rs_const_avp *vp; + + if (vps == NULL) + return RSE_INVAL; + + if (!rs_avp_is_octets (vps) && + !rs_avp_is_string (vps)) + return RSE_ATTR_INVALID; + + for (vp = vps; + vp != NULL; + vp = rs_avp_find_const (vp->next, vp->da->attr, vp->da->vendor)) + total_len += vp->length; + + if (*len < total_len) { + *len = total_len; + return RSE_ATTR_TOO_SMALL; + } + + for (vp = vps, p = buf; + vp != NULL; + vp = rs_avp_find_const (vp->next, vp->da->attr, vp->da->vendor)) { + memcpy (p, vp->vp_octets, vp->length); + p += vp->length; + } + + *len = total_len; + + return RSE_OK; +} + +int +rs_avp_octets_set (rs_avp *vp, + const unsigned char *buf, + size_t len) +{ + int err; + + if (!rs_avp_is_octets (vp)) + return RSE_ATTR_INVALID; + + err = nr_vp_set_data (vp, buf, len); + + return RS_ERR(err); +} + +int +rs_avp_ifid_value (rs_const_avp *vp, uint8_t val[8]) +{ + if (!rs_avp_is_ifid (vp)) + return RSE_ATTR_INVALID; + + memcpy (val, vp->vp_ifid, 8); + + return RSE_OK; +} + +int +rs_avp_ifid_set (rs_avp *vp, const uint8_t val[8]) +{ + int err; + + if (!rs_avp_is_ifid (vp)) + return RSE_ATTR_INVALID; + + err = nr_vp_set_data (vp, val, 8); + return RS_ERR(err); +} + +uint8_t +rs_avp_byte_value (rs_const_avp *vp) +{ + if (!rs_avp_is_byte (vp)) + return 0; + return vp->vp_integer; +} + +int +rs_avp_byte_set (rs_avp *vp, uint8_t val) +{ + int err; + + if (!rs_avp_is_byte (vp)) + return RSE_ATTR_INVALID; + + err = nr_vp_set_data (vp, &val, sizeof (val)); + return RS_ERR(err); +} + +uint16_t +rs_avp_short_value (rs_const_avp *vp) +{ + if (!rs_avp_is_short (vp)) + return 0; + return vp->vp_integer; +} + +int +rs_avp_short_set (rs_avp *vp, uint16_t val) +{ + int err; + + if (!rs_avp_is_short (vp)) + return RSE_ATTR_INVALID; + + err = nr_vp_set_data (vp, &val, sizeof (val)); + return RS_ERR(err); +} + +int +rs_attr_find (const char *name, + unsigned int *attr, + unsigned int *vendor) +{ + const DICT_ATTR *da; + + da = nr_dict_attr_byname (name); + if (da == NULL) + return RSE_ATTR_UNKNOWN; + + *attr = da->attr; + *vendor = da->vendor; + + return RSE_OK; +} + +size_t +rs_avp_display_value (rs_const_avp *vp, + char *buffer, + size_t buflen) +{ + return nr_vp_snprintf_value (buffer, buflen, vp); +} -- cgit v1.1 From 90b5bec53a28b05fb48ecac956310b6a27145090 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Mon, 14 Nov 2011 14:43:24 +1100 Subject: don't return in void function --- lib/avp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/avp.c') diff --git a/lib/avp.c b/lib/avp.c index 1bc1128..4489f66 100644 --- a/lib/avp.c +++ b/lib/avp.c @@ -54,7 +54,7 @@ rs_avp_name (rs_const_avp *vp) void rs_avp_append (rs_avp **head, rs_avp *tail) { - return nr_vps_append (head, tail); + nr_vps_append (head, tail); } rs_avp * -- cgit v1.1 From d6e790ddd52c0aa09af6e515d79d3a676c01fdad Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Mon, 14 Nov 2011 16:51:25 +1100 Subject: don't return in void function Conflicts: lib/NTMakefile --- lib/avp.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/avp.c') diff --git a/lib/avp.c b/lib/avp.c index 4489f66..0de72b1 100644 --- a/lib/avp.c +++ b/lib/avp.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include -- cgit v1.1 From d9ae6534eed05639403584b7b2733ec36c08f1a4 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Mon, 14 Nov 2011 18:54:44 +1100 Subject: add rs_attr_display_name/rs_attr_parse_name --- lib/avp.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'lib/avp.c') diff --git a/lib/avp.c b/lib/avp.c index 0de72b1..5af6129 100644 --- a/lib/avp.c +++ b/lib/avp.c @@ -447,6 +447,79 @@ rs_attr_find (const char *name, return RSE_OK; } +int +rs_attr_display_name (unsigned int attr, + unsigned int vendor, + char *buffer, + size_t bufsize, + int canonical) +{ + const DICT_ATTR *da = NULL; + DICT_ATTR da2; + int err; + + if (!canonical) { + da = nr_dict_attr_byvalue (attr, vendor); + } + if (da == NULL) { + err = nr_dict_attr_2struct(&da2, attr, vendor, + buffer, bufsize); + if (err < 0) + return -err; + } else { + snprintf(buffer, bufsize, "%s", da->name); + } + + return RSE_OK; +} + +int +rs_attr_parse_name (const char *name, + unsigned int *attr, + unsigned int *vendor) +{ + const DICT_ATTR *da; + + if (strncmp(name, "Attr-", 5) == 0) { + char *s = (char *)&name[5]; + unsigned int tmp; + + tmp = strtoul(s, &s, 10); + if (*s == '.') { + s++; + + switch (tmp) { + case PW_VENDOR_SPECIFIC: + *vendor = strtoul(s, &s, 10); + if (*s != '.') + return RSE_ATTR_BAD_NAME; + + s++; + + *attr = strtoul(s, &s, 10); + if (*s != '\0') + return RSE_ATTR_BAD_NAME; + + break; + default: + return RSE_ATTR_BAD_NAME; + } + } else { + *attr = tmp; + *vendor = 0; + } + } else { + da = nr_dict_attr_byname (name); + if (da == NULL) + return RSE_ATTR_UNKNOWN; + + *attr = da->attr; + *vendor = da->vendor; + } + + return RSE_OK; +} + size_t rs_avp_display_value (rs_const_avp *vp, char *buffer, @@ -454,3 +527,4 @@ rs_avp_display_value (rs_const_avp *vp, { return nr_vp_snprintf_value (buffer, buflen, vp); } + -- cgit v1.1 From 53dc68c8a5a3edb904ca937dada67380701f18b0 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Mon, 14 Nov 2011 22:58:53 +1100 Subject: small cleanups --- lib/avp.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'lib/avp.c') diff --git a/lib/avp.c b/lib/avp.c index 5af6129..6f30d4c 100644 --- a/lib/avp.c +++ b/lib/avp.c @@ -25,14 +25,19 @@ rs_avp_free (rs_avp **vps) size_t rs_avp_length (rs_const_avp *vp) { - assert (vp != NULL); + if (vp == NULL) + return 0; + return vp->length; } rs_attr_type_t rs_avp_typeof (rs_const_avp *vp) { - return vp ? vp->da->type : RS_TYPE_INVALID; + if (vp == NULL) + return RS_TYPE_INVALID; + + return vp->da->type; } void @@ -40,6 +45,8 @@ rs_avp_attrid (rs_const_avp *vp, unsigned int *attr, unsigned int *vendor) { + assert (vp != NULL); + *attr = vp->da->attr; *vendor = vp->da->vendor; } @@ -47,7 +54,7 @@ rs_avp_attrid (rs_const_avp *vp, const char * rs_avp_name (rs_const_avp *vp) { - return vp ? vp->da->name : NULL; + return (vp != NULL) ? vp->da->name : NULL; } void @@ -127,15 +134,15 @@ rs_avp_dup (rs_const_avp *vp) } rs_avp * -rs_avp_next (rs_avp *avp) +rs_avp_next (rs_avp *vp) { - return avp ? avp->next : NULL; + return (vp != NULL) ? vp->next : NULL; } rs_const_avp * -rs_avp_next_const (rs_const_avp *avp) +rs_avp_next_const (rs_const_avp *vp) { - return avp ? avp->next : NULL; + return (vp != NULL) ? vp->next : NULL; } int -- cgit v1.1 From b86f31fd4a8ee9394146d8da969c727de819df3b Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Thu, 1 Dec 2011 17:44:10 +1100 Subject: fix dangling reference to dictionary pointer --- lib/avp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/avp.c') diff --git a/lib/avp.c b/lib/avp.c index 6f30d4c..bdc6216 100644 --- a/lib/avp.c +++ b/lib/avp.c @@ -106,7 +106,10 @@ rs_avp_dup (rs_const_avp *vp) { rs_avp *vp2; - vp2 = nr_vp_alloc (vp->da); + if (vp->da->flags.unknown) + vp2 = nr_vp_alloc_raw (vp->da->attr, vp->da->vendor); + else + vp2 = nr_vp_alloc (vp->da); if (vp2 == NULL) return NULL; -- cgit v1.1 From efb18a601811888127be69499cf10891aa3a4c37 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Sat, 31 Mar 2012 09:22:53 +1100 Subject: Update copyright to JANET(UK) --- lib/avp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/avp.c') diff --git a/lib/avp.c b/lib/avp.c index bdc6216..80c6a9d 100644 --- a/lib/avp.c +++ b/lib/avp.c @@ -1,4 +1,4 @@ -/* Copyright 2011 PADL Software Pty Ltd. All rights reserved. +/* Copyright 2011 JANET(UK). All rights reserved. See the file COPYING for licensing information. */ #if defined HAVE_CONFIG_H -- cgit v1.1