return vp;
}
+/*
+ * Create a new valuepair.
+ */
+VALUE_PAIR *paircreate_raw(int attr, int vendor, int type, VALUE_PAIR *vp)
+{
+ char *p = (char *) (vp + 1);
+
+ if (!vp->flags.unknown_attr) {
+ pairfree(&vp);
+ return NULL;
+ }
+
+ vp->vendor = vendor;
+ vp->attribute = attr;
+ vp->operator = T_OP_EQ;
+ vp->name = p;
+ vp->type = type;
+ vp->length = 0;
+ memset(&vp->flags, 0, sizeof(vp->flags));
+ vp->flags.unknown_attr = 1;
+
+ if (!vp_print_name(p, FR_VP_NAME_LEN, vp->attribute, vp->vendor)) {
+ free(vp);
+ return NULL;
+ }
+
+ return vp;
+}
/*
* Create a new valuepair.
/*
* It isn't in the dictionary: update the name.
*/
- if (!da) {
- char *p = (char *) (vp + 1);
-
- vp->vendor = vendor;
- vp->attribute = attr;
- vp->name = p;
- vp->type = type; /* be forgiving */
-
- if (!vp_print_name(p, FR_VP_NAME_LEN, attr, vendor)) {
- free(vp);
- return NULL;
- }
- }
+ if (!da) return paircreate_raw(attr, vendor, type, vp);
return vp;
}
/*
* Find the pair with the matching attribute
*/
-VALUE_PAIR * pairfind(VALUE_PAIR *first, int attr, int vendor)
+VALUE_PAIR * pairfind(VALUE_PAIR *first, unsigned int attr, unsigned int vendor)
{
while (first) {
if ((first->attribute == attr) && (first->vendor == vendor)) {
/*
* Delete the pair(s) with the matching attribute
*/
-void pairdelete(VALUE_PAIR **first, int attr, int vendor)
+void pairdelete(VALUE_PAIR **first, unsigned int attr, unsigned int vendor)
{
VALUE_PAIR *i, *next;
VALUE_PAIR **last = first;
return NULL;
}
memcpy(n, vp, sizeof(*n) + name_len);
+
+ /*
+ * Reset the name field to point to the NEW attribute,
+ * rather than to the OLD one.
+ */
+ if (vp->flags.unknown_attr) n->name = (char *) (n + 1);
+
n->next = NULL;
if ((n->type == PW_TYPE_TLV) &&
/*
* Copy just a certain type of pairs.
*/
-VALUE_PAIR *paircopy2(VALUE_PAIR *vp, int attr, int vendor)
+VALUE_PAIR *paircopy2(VALUE_PAIR *vp, unsigned int attr, unsigned int vendor)
{
VALUE_PAIR *first, *n, **last;
last = &first;
while (vp) {
- if ((attr >= 0) &&
+ if ((attr > 0) &&
!((vp->attribute == attr) && (vp->vendor == vendor))) {
vp = vp->next;
continue;
*/
VALUE_PAIR *paircopy(VALUE_PAIR *vp)
{
- return paircopy2(vp, -1, 0);
+ return paircopy2(vp, 0, 0);
}
/*
* Move one kind of attributes from one list to the other
*/
-void pairmove2(VALUE_PAIR **to, VALUE_PAIR **from, int attr, int vendor)
+void pairmove2(VALUE_PAIR **to, VALUE_PAIR **from, unsigned int attr, unsigned int vendor)
{
VALUE_PAIR *to_tail, *i, *next;
VALUE_PAIR *iprev = NULL;
/*
* vendor=0, attr = PW_VENDOR_SPECIFIC means
- * "match any vendor attribute". Otherwise, do
- * an exact match
+ * "match any vendor attribute".
*/
- if (((vendor != 0) || (attr != PW_VENDOR_SPECIFIC)) &&
- (i->attribute != attr) && (i->vendor != vendor)) {
+ if ((vendor == 0) && (attr == PW_VENDOR_SPECIFIC)) {
+ /*
+ * It's a VSA: move it over.
+ */
+ if (i->vendor != 0) goto move;
+
+ /*
+ * It's Vendor-Specific: move it over.
+ */
+ if (i->attribute == attr) goto move;
+
+ /*
+ * It's not a VSA: ignore it.
+ */
iprev = i;
continue;
}
/*
- * If the attribute to move IS a VSA, then it ignores
- * any non-VSA attribute.
+ * If it isn't an exact match, ignore it.
*/
- if ((vendor == 0) && (attr == PW_VENDOR_SPECIFIC) &&
- (i->vendor == 0)) {
+ if (!((i->vendor == vendor) && (i->attribute == attr))) {
iprev = i;
continue;
}
+ move:
/*
* Remove the attribute from the "from" list.
*/
f[2] = strchr(f[1], ':'); /* find : separator */
if (f[2]) {
*(f[2]++) = '\0'; /* nuke it, and point to SS */
- } else {
- strcpy(f[2], "0"); /* assignment would discard const */
- }
+ tm->tm_sec = atoi(f[2]);
+ } /* else leave it as zero */
tm->tm_hour = atoi(f[0]);
tm->tm_min = atoi(f[1]);
- tm->tm_sec = atoi(f[2]);
}
/*
c = '\'';
cp++;
break;
+ case '\\':
+ c = '\\';
+ cp++;
+ break;
case '`':
c = '`';
cp++;
*p++ = c;
length++;
}
+ vp->vp_strvalue[length] = '\0';
vp->length = length;
break;
break;
case PW_TYPE_IPV6ADDR:
- if (inet_pton(AF_INET6, value, &vp->vp_ipv6addr) <= 0) {
- fr_strerror_printf("failed to parse IPv6 address "
- "string \"%s\"", value);
- return NULL;
+ {
+ fr_ipaddr_t ipaddr;
+
+ if (ip_hton(value, AF_INET6, &ipaddr) < 0) {
+ char buffer[1024];
+
+ strlcpy(buffer, fr_strerror(), sizeof(buffer));
+
+ fr_strerror_printf("failed to parse IPv6 address "
+ "string \"%s\": %s", value, buffer);
+ return NULL;
+ }
+ vp->vp_ipv6addr = ipaddr.ipaddr.ip6addr;
+ vp->length = 16; /* length of IPv6 address */
}
- vp->length = 16; /* length of IPv6 address */
break;
case PW_TYPE_IPV6PREFIX:
if (strncasecmp(p, "Attr-", 5) != 0) {
if (strncasecmp(p, "Vendor-", 7) == 0) {
vendor = (int) strtol(p + 7, &q, 10);
- if ((vendor == 0) || (vendor > 65535)) {
+ if ((vendor == 0) || (vendor > FR_MAX_VENDOR)) {
fr_strerror_printf("Invalid vendor value in attribute name \"%s\"", attribute);
return NULL;
}
if (attr > 65535) goto attr_error;
break;
- case 4: /* Internal limitations! */
- if (attr > 65535) goto attr_error;
+ case 4:
break;
default: