From: Alan T. DeKok Date: Tue, 9 Aug 2011 13:36:50 +0000 (-0400) Subject: Initial support for integer64 data type X-Git-Tag: release_3_0_0_beta0~690 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5bccc8674b8dd61854add09f2ee68db53719487d;p=thirdparty%2Ffreeradius-server.git Initial support for integer64 data type Can print/parse encode/decode them, and read them from dictionaries The rest of the code (unlang, eval, etc) needs to be audited to support the new data type --- diff --git a/src/include/libradius.h b/src/include/libradius.h index bca96c03a84..b22544d18f1 100644 --- a/src/include/libradius.h +++ b/src/include/libradius.h @@ -155,6 +155,7 @@ typedef union value_pair_data { uint32_t date; uint32_t integer; int32_t sinteger; + uint64_t integer64; uint8_t filter[32]; uint8_t ifid[8]; /* struct? */ uint8_t ipv6prefix[18]; /* struct? */ @@ -192,6 +193,7 @@ typedef struct value_pair { #define vp_ether data.ether #define vp_signed data.sinteger #define vp_tlv data.tlv +#define vp_integer64 data.integer64 #if 0 #define vp_ipaddr data.ipaddr.s_addr diff --git a/src/include/missing.h b/src/include/missing.h index 679d7f2b8be..b9333d6800c 100644 --- a/src/include/missing.h +++ b/src/include/missing.h @@ -412,6 +412,11 @@ int gettimeofday (struct timeval *tv, void *tz); void timeval2ntp(const struct timeval *tv, uint8_t *ntp); void ntp2timeval(struct timeval *tv, const char *ntp); +#define ntohll(x) (((uint64_t)(ntohl((uint32_t)((x << 32) >> 32))) << 32) | \ + (uint64_t)ntohl(((uint32_t)(x >> 32)))) + +#define htonll(x) ntohll(x) + #ifdef __cplusplus } #endif diff --git a/src/include/radius.h b/src/include/radius.h index 8020fd5a883..3d9c221af85 100644 --- a/src/include/radius.h +++ b/src/include/radius.h @@ -24,6 +24,7 @@ #define PW_TYPE_EXTENDED 15 #define PW_TYPE_EXTENDED_FLAGS 16 #define PW_TYPE_EVS 17 +#define PW_TYPE_INTEGER64 18 #define PW_FLAG_LONG (1 << 8) diff --git a/src/lib/dict.c b/src/lib/dict.c index 0a5638cd88f..065adca125d 100644 --- a/src/lib/dict.c +++ b/src/lib/dict.c @@ -106,6 +106,8 @@ static const FR_NAME_NUMBER type_table[] = { { "uint16", PW_TYPE_SHORT }, { "uint32", PW_TYPE_INTEGER }, { "int32", PW_TYPE_SIGNED }, + { "integer64", PW_TYPE_INTEGER64 }, + { "uint64", PW_TYPE_INTEGER64 }, { NULL, 0 } }; @@ -843,6 +845,7 @@ int dict_addvalue(const char *namestr, const char *attrstr, int value) case PW_TYPE_INTEGER: break; + case PW_TYPE_INTEGER64: default: fr_pool_free(dval); fr_strerror_printf("dict_addvalue: VALUEs cannot be defined for attributes of type '%s'", @@ -1194,6 +1197,10 @@ static int process_attribute(const char* fn, const int line, length = 4; break; + case PW_TYPE_INTEGER64: + length = 8; + break; + case PW_TYPE_ETHERNET: length = 6; break; diff --git a/src/lib/print.c b/src/lib/print.c index db47e3ad339..63e54e43858 100644 --- a/src/lib/print.c +++ b/src/lib/print.c @@ -266,6 +266,10 @@ int vp_prints_value(char * out, size_t outlen, const VALUE_PAIR *vp, int delimit } } break; + case PW_TYPE_INTEGER64: + snprintf(buf, sizeof(buf), "%llu", vp->vp_integer64); + a = buf; + break; case PW_TYPE_DATE: t = vp->vp_date; if (delimitst == 1) { diff --git a/src/lib/radius.c b/src/lib/radius.c index 6c09b4fda6a..7b7fb7d60a7 100644 --- a/src/lib/radius.c +++ b/src/lib/radius.c @@ -808,6 +808,7 @@ static ssize_t vp2data_any(const RADIUS_PACKET *packet, const uint8_t *data; uint8_t *ptr = start; uint8_t array[4]; + uint64_t lvalue64; const VALUE_PAIR *vp = *pvp; /* @@ -868,6 +869,12 @@ static ssize_t vp2data_any(const RADIUS_PACKET *packet, data = array; break; + case PW_TYPE_INTEGER64: + len = 8; /* just in case */ + lvalue64 = htonll(vp->vp_integer64); + data = &lvalue64; + break; + case PW_TYPE_IPADDR: data = (const uint8_t *) &vp->vp_ipaddr; len = 4; /* just in case */ @@ -3007,6 +3014,12 @@ static ssize_t data2vp_any(const RADIUS_PACKET *packet, } break; + case PW_TYPE_INTEGER64: + if (vp->length != 8) goto raw; + + vp->vp_integer64 = ntohll(*(uint64_t *)(vp->vp_octets)); + break; + case PW_TYPE_DATE: if (vp->length != 4) goto raw; diff --git a/src/lib/valuepair.c b/src/lib/valuepair.c index 4075c590c7b..5a37116e5bd 100644 --- a/src/lib/valuepair.c +++ b/src/lib/valuepair.c @@ -112,6 +112,10 @@ VALUE_PAIR *pairalloc(DICT_ATTR *da) vp->length = 4; break; + case PW_TYPE_INTEGER64: + vp->length = 8; + break; + case PW_TYPE_IFID: vp->length = sizeof(vp->vp_ifid); break; @@ -891,6 +895,7 @@ VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value) char *p, *s=0; const char *cp, *cs; int x; + unsigned long long y; size_t length; DICT_VALUE *dval; @@ -1065,6 +1070,22 @@ VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value) vp->vp_integer = dval->value; break; + case PW_TYPE_INTEGER64: + /* + * Note that ALL integers are unsigned! + */ + p = vp->vp_strvalue; + if (sscanf(p, "%llu", &y) != 1) { + fr_strerror_printf("Invalid value %s for attribute %s", + value, vp->name); + return NULL; + } + vp->vp_integer64 = y; + vp->length = 8; + p += strspn(p, "0123456789"); + if (check_for_whitespace(p)) break; + break; + case PW_TYPE_DATE: { /*