memcpy(&vendor, data, sizeof(vendor));
vendor = ntohl(vendor);
+ if (attr > 65535) {
+ RDEBUG2("Cannot handle vendor attributes greater than 65535");
+ return 0;
+ }
+
if (vendor > 65535) {
- RDEBUG2("Vendor codes larger than 65535 are not supported");
+ RDEBUG2("Cannot handle vendor Id greater than 65535");
return 0;
}
memcpy(&vendor, data, sizeof(vendor));
vendor = ntohl(vendor);
- if (attr > 65535) {
- RDEBUG2("Cannot handle vendor attributes greater than 65535");
- pairfree(&first);
- return NULL;
- }
+ data += 4; /* skip the vendor field, it's zero */
+ offset += 4; /* offset to value field */
+ length &= 0x00ffffff;
- if (vendor > 65535) {
- RDEBUG2("Cannot handle vendor Id greater than 65535");
- pairfree(&first);
- return NULL;
- }
+ if (attr > 65535) goto next_attr;
+ if (vendor > 65535) goto next_attr;
attr |= (vendor << 16);
-
- data += 4; /* skip the vendor field, it's zero */
- offset += 4; /* offset to value field */
}
/*
- * Vendor attributes can be larger than 255.
- * Normal attributes cannot be.
+ * Get the length.
*/
- if ((attr > 255) && (VENDOR(attr) == 0)) {
- RDEBUG2("Cannot handle Diameter attributes");
- pairfree(&first);
- return NULL;
- }
+ length &= 0x00ffffff;
/*
* FIXME: Handle the M bit. For now, we assume that
* with the M bit set.
*/
- /*
- * Get the length.
- */
- length &= 0x00ffffff;
-
/*
* Get the size of the value portion of the
* attribute.
size = length - offset;
/*
- * Create it.
+ * Vendor attributes can be larger than 255.
+ * Normal attributes cannot be.
+ */
+ if ((attr > 255) && (VENDOR(attr) == 0)) {
+ RDEBUG2("Cannot handle Diameter attributes");
+ goto next_attr;
+ }
+
+ /*
+ * Create it. If this fails, it's because we're OOM.
*/
vp = paircreate(attr, PW_TYPE_OCTETS);
if (!vp) {
- RDEBUG2("Failure in creating VP");
+ RDEBUG2("diameter2vp: Failed creating attribute %u", attr);
pairfree(&first);
return NULL;
}
case PW_TYPE_INTEGER:
case PW_TYPE_DATE:
if (size != vp->length) {
- RDEBUG2("Invalid length attribute %d",
- attr);
- pairfree(&first);
- pairfree(&vp);
- return NULL;
+ /*
+ * Bad format. Create a "raw"
+ * attribute.
+ */
+ raw:
+ vp = paircreate_raw(vp->attribute,
+ PW_TYPE_OCTETS, vp);
+ vp->length = size;
+ memcpy(vp->vp_octets, data, vp->length);
+ break;
}
memcpy(&vp->vp_integer, data, vp->length);
break;
case PW_TYPE_IPADDR:
- if (size != vp->length) {
- RDEBUG2("Invalid length attribute %d",
- attr);
- pairfree(&first);
- pairfree(&vp);
- return NULL;
- }
- memcpy(&vp->vp_ipaddr, data, vp->length);
-
- /*
- * Stored in network byte order: don't change it.
- */
- break;
-
- /*
- * String, octet, etc. Copy the data from the
- * value field over verbatim.
- *
- * FIXME: Ipv6 attributes ?
- *
- */
+ if (size != vp->length) goto raw;
+ memcpy(&vp->vp_ipaddr, data, vp->length);
+
+ /*
+ * Stored in network byte order: don't change it.
+ */
+ break;
+
+ case PW_TYPE_BYTE:
+ if (size != vp->length) goto raw;
+ vp->vp_integer = data[0];
+ break;
+
+ case PW_TYPE_SHORT:
+ if (size != vp->length) goto raw;
+ vp->vp_integer = (data[0] * 256) + data[1];
+ break;
+
+ case PW_TYPE_SIGNED:
+ if (size != vp->length) goto raw;
+ memcpy(&vp->vp_signed, data, vp->length);
+ vp->vp_signed = ntohl(vp->vp_signed);
+ break;
+
+ case PW_TYPE_IPV6ADDR:
+ if (size != vp->length) goto raw;
+ memcpy(&vp->vp_ipv6addr, data, vp->length);
+ break;
+
+ case PW_TYPE_IPV6PREFIX:
+ if (size != vp->length) goto raw;
+ memcpy(&vp->vp_ipv6prefix, data, vp->length);
+ break;
+
+ /*
+ * String, octet, etc. Copy the data from the
+ * value field over verbatim.
+ *
+ * FIXME: Ipv6 attributes ?
+ *
+ */
case PW_TYPE_OCTETS:
if (attr == PW_EAP_MESSAGE) {
const uint8_t *eap_message = data;
vp = paircreate(attr, PW_TYPE_OCTETS);
if (!vp) {
- RDEBUG2("Failure in creating VP");
+ RDEBUG2("Failed creating EAP-Message");
pairfree(&first);
return NULL;
}
default:
vp->length = size;
- memcpy(vp->vp_strvalue, data, vp->length);
+ memcpy(vp->vp_octets, data, vp->length);
break;
}