# Encapsulates an Ethernet frame...
ATTRIBUTE VQP-Ethernet-Frame 0x2c05 octets
-ATTRIBUTE VQP-MAC 0x2c06 octets # 6-byte MAC address
+ATTRIBUTE VQP-MAC 0x2c06 ether
ATTRIBUTE VQP-Unknown 0x2c07 octets
-ATTRIBUTE VQP-Cookie 0x2c08 octets # 6-byte MAC address
+ATTRIBUTE VQP-Cookie 0x2c08 ether
#
# VQP integer mappings
# Encapsulates an Ethernet frame...
ATTRIBUTE VMPS-Ethernet-Frame 0x2c05 octets
-ATTRIBUTE VMPS-MAC 0x2c06 octets # 6-byte MAC address
+ATTRIBUTE VMPS-MAC 0x2c06 ether
ATTRIBUTE VMPS-Unknown 0x2c07 octets
-ATTRIBUTE VMPS-Cookie 0x2c08 octets # 6-byte MAC address
+ATTRIBUTE VMPS-Cookie 0x2c08 ether
#
# VMPS integer mappings
#define PW_TYPE_IPV6PREFIX 8
#define PW_TYPE_BYTE 9
#define PW_TYPE_SHORT 10
+#define PW_TYPE_ETHERNET 11
#define PW_AUTHENTICATION_REQUEST 1
#define PW_AUTHENTICATION_ACK 2
{ "ipv6prefix", PW_TYPE_IPV6PREFIX },
{ "byte", PW_TYPE_BYTE },
{ "short", PW_TYPE_SHORT },
+ { "ether", PW_TYPE_ETHERNET },
{ NULL, 0 }
};
}
break;
+ case PW_TYPE_ETHERNET:
+ snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
+ vp->vp_ether[0], vp->vp_ether[1],
+ vp->vp_ether[2], vp->vp_ether[3],
+ vp->vp_ether[4], vp->vp_ether[5]);
+ a = buf;
+ break;
+
default:
a = "UNKNOWN-TYPE";
break;
vp->length = sizeof(vp->vp_ipv6prefix);
break;
+ case PW_TYPE_ETHERNET:
+ vp->length = sizeof(vp->vp_ether);
+ break;
+
default:
vp->length = 0;
break;
return NULL;
}
vp->operator = T_OP_EQ;
+ vp->type = type;
/*
* Update the name...
return 0;
}
+static const char *hextab = "0123456789abcdef";
/*
* Parse a string value into a given VALUE_PAIR
{
char *p, *s=0;
const char *cp, *cs;
+ int length, x;
DICT_VALUE *dval;
/*
switch(vp->type) {
case PW_TYPE_STRING:
/*
- * Already handled above.
+ * Do escaping here
*/
+ p = vp->vp_strvalue;
+ cp = value;
+ length = 0;
+
+ while (*cp && (length < sizeof(vp->vp_strvalue))) {
+ char c = *cp++;
+
+ if (c == '\\') {
+ switch (*cp) {
+ case 'r':
+ c = '\r';
+ cp++;
+ break;
+ case 'n':
+ c = '\n';
+ cp++;
+ break;
+ case 't':
+ c = '\t';
+ cp++;
+ break;
+ case '"':
+ c = '"';
+ cp++;
+ break;
+ case '\'':
+ c = '\'';
+ cp++;
+ break;
+ case '`':
+ c = '`';
+ cp++;
+ break;
+ case '\0':
+ c = '\\'; /* no cp++ */
+ break;
+ default:
+ if ((cp[0] >= '0') &&
+ (cp[0] <= '9') &&
+ (cp[1] >= '0') &&
+ (cp[1] <= '9') &&
+ (cp[2] >= '0') &&
+ (cp[2] <= '9') &&
+ (sscanf(cp, "%3o", &x) == 1)) {
+ c = x;
+ cp += 3;
+ } /* else just do '\\' */
+ }
+ }
+ *p++ = c;
+ length++;
+ }
+ vp->length = length;
break;
case PW_TYPE_IPADDR:
vp->length = 16; /* length of IPv6 address */
vp->vp_strvalue[vp->length] = '\0';
break;
- /*
- * Anything else.
- */
+
case PW_TYPE_IPV6PREFIX:
p = strchr(value, '/');
if (!p || ((p - value) >= 256)) {
vp->length = 16 + 2;
break;
+ case PW_TYPE_ETHERNET:
+ {
+ int i = 0;
+ const char *c1, *c2;
+
+ cp = value;
+ while (*cp) {
+ if (cp[1] == ':') {
+ c1 = hextab;
+ c2 = memchr(hextab, tolower((int) cp[0]), 16);
+ cp += 2;
+ } else if ((cp[1] != '\0') &&
+ ((cp[2] == ':') ||
+ (cp[2] == '\0'))) {
+ c1 = memchr(hextab, tolower((int) cp[0]), 16);
+ c2 = memchr(hextab, tolower((int) cp[1]), 16);
+ cp += 3;
+ } else {
+ c1 = c2 = NULL;
+ }
+ if (!c1 || !c2 || (i >= sizeof(vp->vp_ether))) {
+ librad_log("failed to parse Ethernet address \"%s\"", value);
+ return NULL;
+ }
+ vp->vp_ether[i] = ((c1-hextab)<<4) + (c2-hextab);
+ i++;
+ }
+ }
+ vp->length = 6;
+ break;
+
+ /*
+ * Anything else.
+ */
default:
librad_log("unknown attribute type %d", vp->type);
return NULL;