CID 1135410
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 22 Mar 2014 09:37:55 +0000 (09:37 +0000)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 22 Mar 2014 09:56:51 +0000 (09:56 +0000)
src/include/libradius.h
src/lib/valuepair.c

index 1f6757e..2e3677d 100644 (file)
@@ -585,6 +585,8 @@ void                pairmove(TALLOC_CTX *ctx, VALUE_PAIR **to, VALUE_PAIR **from);
 void           pairfilter(TALLOC_CTX *ctx, VALUE_PAIR **to, VALUE_PAIR **from,
                                           unsigned int attr, unsigned int vendor, int8_t tag);
 bool           pairparsevalue(VALUE_PAIR *vp, char const *value);
+VALUE_PAIR     *pairmake_ip(TALLOC_CTX *ctx, char const *value, DICT_ATTR *ipv4, DICT_ATTR *ipv6,
+                            DICT_ATTR *ipv4_prefix, DICT_ATTR *ipv6_prefix);
 VALUE_PAIR     *pairmake(TALLOC_CTX *ctx, VALUE_PAIR **vps, char const *attribute, char const *value, FR_TOKEN op);
 int            pairmark_xlat(VALUE_PAIR *vp, char const *value);
 FR_TOKEN       pairread(char const **ptr, VALUE_PAIR_RAW *raw);
index 43c1557..b7586ad 100644 (file)
@@ -97,7 +97,10 @@ VALUE_PAIR *pairalloc(TALLOC_CTX *ctx, DICT_ATTR const *da)
        /*
         *      Caller must specify a da else we don't know what the attribute type is.
         */
-       if (!da) return NULL;
+       if (!da) {
+               fr_strerror_printf("Invalid arguments");
+               return NULL;
+       }
 
        vp = talloc_zero(ctx, VALUE_PAIR);
        if (!vp) {
@@ -528,10 +531,7 @@ VALUE_PAIR *paircopyvp(TALLOC_CTX *ctx, VALUE_PAIR const *vp)
        VERIFY_VP(vp);
 
        n = pairalloc(ctx, vp->da);
-       if (!n) {
-               fr_strerror_printf("out of memory");
-               return NULL;
-       }
+       if (!n) return NULL;
 
        memcpy(n, vp, sizeof(*n));
 
@@ -649,9 +649,7 @@ VALUE_PAIR *paircopyvpdata(TALLOC_CTX *ctx, DICT_ATTR const *da, VALUE_PAIR cons
        }
 
        n = pairalloc(ctx, da);
-       if (!n) {
-               return NULL;
-       }
+       if (!n) return NULL;
 
        memcpy(n, vp, sizeof(*n));
        n->da = da;
@@ -1558,6 +1556,62 @@ bool pairparsevalue(VALUE_PAIR *vp, char const *value)
        return true;
 }
 
+/** Use simple heuristics to create an VALUE_PAIR from an unknown address string
+ *
+ * If a DICT_ATTR is not provided for the address type, parsing will fail with
+ * and error.
+ *
+ * @param ctx to allocate VP in.
+ * @param value IPv4/IPv6 address/prefix string.
+ * @param ipv4 dictionary attribute to use for an IPv4 address.
+ * @param ipv6 dictionary attribute to use for an IPv6 address.
+ * @param ipv4_prefix dictionary attribute to use for an IPv4 prefix.
+ * @param ipv6_prefix dictionary attribute to use for an IPv6 prefix.
+ * @return NULL on error, or new VALUE_PAIR.
+ */
+VALUE_PAIR *pairmake_ip(TALLOC_CTX *ctx, char const *value, DICT_ATTR *ipv4, DICT_ATTR *ipv6,
+                       DICT_ATTR *ipv4_prefix, DICT_ATTR *ipv6_prefix)
+{
+       VALUE_PAIR *vp;
+       DICT_ATTR *da;
+
+       if (!fr_assert(ipv4 || ipv6 || ipv4_prefix || ipv6_prefix)) {
+               return NULL;
+       }
+
+       /* No point in repeating the work of pairparsevalue */
+       if (strchr(value, ':')) {
+               if (strchr(value, '/')) {
+                       da = ipv6_prefix;
+                       goto finish;
+               }
+
+               da = ipv6;
+               goto finish;
+       }
+
+       if (strchr(value, '/')) {
+               da = ipv4_prefix;
+               goto finish;
+       }
+       da = ipv4;
+
+       if (!da) {
+               fr_strerror_printf("Invalid IP value specified, allowed types are %s%s%s%s",
+                                  ipv4 ? "ipaddr " : "", ipv6 ? "ipv6addr " : "",
+                                  ipv4_prefix ? "ipv4prefix " : "", ipv6_prefix ? "ipv6prefix" : "");
+       }
+       finish:
+       vp = pairalloc(ctx, da);
+       if (!vp) return NULL;
+       if (!pairparsevalue(vp, value)) {
+               talloc_free(vp);
+               return NULL;
+       }
+
+       return vp;
+}
+
 /** Create a valuepair from an ASCII attribute and value
  *
  * Where the attribute name is in the form:
@@ -1728,10 +1782,7 @@ VALUE_PAIR *pairmake(TALLOC_CTX *ctx, VALUE_PAIR **vps,
        }
 
        vp = pairalloc(ctx, da);
-       if (!vp) {
-               return NULL;
-       }
-
+       if (!vp) return NULL;
        vp->op = (op == 0) ? T_OP_EQ : op;
        vp->tag = tag;