Initial support for integer64 data type
authorAlan T. DeKok <aland@freeradius.org>
Tue, 9 Aug 2011 13:36:50 +0000 (09:36 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 9 Aug 2011 13:36:50 +0000 (09:36 -0400)
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

src/include/libradius.h
src/include/missing.h
src/include/radius.h
src/lib/dict.c
src/lib/print.c
src/lib/radius.c
src/lib/valuepair.c

index bca96c0..b22544d 100644 (file)
@@ -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
index 679d7f2..b9333d6 100644 (file)
@@ -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
index 8020fd5..3d9c221 100644 (file)
@@ -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)
 
index 0a5638c..065adca 100644 (file)
@@ -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;
index db47e3a..63e54e4 100644 (file)
@@ -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) {
index 6c09b4f..7b7fb7d 100644 (file)
@@ -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;
 
index 4075c59..5a37116 100644 (file)
@@ -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:
                        {
                                /*