Now that we do VMPS, support ethernet types natively.
authoraland <aland>
Tue, 29 May 2007 14:33:25 +0000 (14:33 +0000)
committeraland <aland>
Tue, 29 May 2007 14:33:25 +0000 (14:33 +0000)
share/dictionary.vqp
src/include/radius.h
src/lib/dict.c
src/lib/print.c
src/lib/valuepair.c

index 7276f63..0eafc5a 100644 (file)
@@ -43,9 +43,9 @@ ATTRIBUTE     VQP-Domain-Name                         0x2c04  string
 
 # 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
@@ -88,9 +88,9 @@ ATTRIBUTE     VMPS-Domain-Name                        0x2c04  string
 
 # 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
index 9ab51d8..eebbc3d 100644 (file)
@@ -17,6 +17,7 @@
 #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
index 62d06d4..a7d4f51 100644 (file)
@@ -89,6 +89,7 @@ static const LRAD_NAME_NUMBER type_table[] = {
        { "ipv6prefix", PW_TYPE_IPV6PREFIX },
        { "byte",       PW_TYPE_BYTE },
        { "short",      PW_TYPE_SHORT },
+       { "ether",      PW_TYPE_ETHERNET },
        { NULL, 0 }
 };
 
index 611bf02..f2245f2 100644 (file)
@@ -215,6 +215,14 @@ int vp_prints_value(char * out, int outlen, VALUE_PAIR *vp, int delimitst)
                }
                        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;
index d27525e..88db674 100644 (file)
@@ -88,6 +88,10 @@ static VALUE_PAIR *pairalloc(DICT_ATTR *da)
                        vp->length = sizeof(vp->vp_ipv6prefix);
                        break;
 
+               case PW_TYPE_ETHERNET:
+                       vp->length = sizeof(vp->vp_ether);
+                       break;
+
                default:
                        vp->length = 0;
                        break;
@@ -111,6 +115,7 @@ VALUE_PAIR *paircreate(int attr, int type)
                return NULL;
        }
        vp->operator = T_OP_EQ;
+       vp->type = type;
 
        /*
         *      Update the name...
@@ -747,6 +752,7 @@ static int gettime(const char *valstr, uint32_t *lvalue)
        return 0;
 }
 
+static const char *hextab = "0123456789abcdef";
 
 /*
  *  Parse a string value into a given VALUE_PAIR
@@ -760,6 +766,7 @@ VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
 {
        char            *p, *s=0;
        const char      *cp, *cs;
+       int             length, x;
        DICT_VALUE      *dval;
 
        /*
@@ -772,8 +779,61 @@ VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
        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:
@@ -973,9 +1033,7 @@ VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
                        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)) {
@@ -1007,6 +1065,40 @@ VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
                        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;