Make the lib directory use vp->da
authorAlan T. DeKok <aland@freeradius.org>
Sat, 16 Feb 2013 18:53:38 +0000 (13:53 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 16 Feb 2013 18:53:38 +0000 (13:53 -0500)
src/lib/dhcp.c
src/lib/print.c
src/lib/radius.c
src/lib/valuepair.c
src/lib/vqp.c

index ef95180..76ac3a7 100644 (file)
@@ -493,7 +493,7 @@ make_tlv:
  */
 static int fr_dhcp_attr2vp(VALUE_PAIR *vp, const uint8_t *p, size_t alen)
 {
-       switch (vp->type) {
+       switch (vp->da->type) {
        case PW_TYPE_BYTE:
                if (alen != 1) goto raw;
                vp->vp_integer = p[0];
@@ -534,7 +534,7 @@ static int fr_dhcp_attr2vp(VALUE_PAIR *vp, const uint8_t *p, size_t alen)
                return decode_tlv(vp, p, alen);
                
        default:
-               fr_strerror_printf("Internal sanity check %d %d", vp->type, __LINE__);
+               fr_strerror_printf("Internal sanity check %d %d", vp->da->type, __LINE__);
                return -1;
        } /* switch over type */
 
@@ -628,14 +628,7 @@ ssize_t fr_dhcp_decode_options(uint8_t *data, size_t len, VALUE_PAIR **head)
                        /*
                         *      Hack for ease of use.
                         */
-                       if ((da->attr == 0x3d) &&
-                           !da->flags.array &&
-                           (alen == 7) && (*p == 1) && (num_entries == 1)) {
-                               vp->type = PW_TYPE_ETHERNET;
-                               memcpy(vp->vp_octets, p + 1, 6);
-                               vp->length = alen;
-
-                       } else if (fr_dhcp_attr2vp(vp, p, alen) < 0) {
+                       if (fr_dhcp_attr2vp(vp, p, alen) < 0) {
                                pairfree(&vp);
                                pairfree(head);
                                return -1;
@@ -655,7 +648,7 @@ ssize_t fr_dhcp_decode_options(uint8_t *data, size_t len, VALUE_PAIR **head)
 
 int fr_dhcp_decode(RADIUS_PACKET *packet)
 {
-       ssize_t i;
+       size_t i;
        uint8_t *p;
        uint32_t giaddr;
        VALUE_PAIR *head, *vp, **tail;
@@ -693,11 +686,11 @@ int fr_dhcp_decode(RADIUS_PACKET *packet)
 
                if ((i == 11) && 
                    (packet->data[1] == 1) &&
-                   (packet->data[2] == 6)) {
-                       vp->type = PW_TYPE_ETHERNET;
+                   (packet->data[2] != 6)) {
+                       fr_strerror_printf("chaddr of incorrect length for ethernet");
                }
 
-               switch (vp->type) {
+               switch (vp->da->type) {
                case PW_TYPE_BYTE:
                        vp->vp_integer = p[0];
                        vp->length = 1;
@@ -739,7 +732,7 @@ int fr_dhcp_decode(RADIUS_PACKET *packet)
                        break;
                        
                default:
-                       fr_strerror_printf("BAD TYPE %d", vp->type);
+                       fr_strerror_printf("BAD TYPE %d", vp->da->type);
                        pairfree(&vp);
                        break;
                }
@@ -844,16 +837,16 @@ static int attr_cmp(const void *one, const void *two)
        /*
         *      DHCP-Message-Type is first, for simplicity.
         */
-       if (((*a)->attribute == 53) &&
-           (*b)->attribute != 53) return -1;
+       if (((*a)->da->attr == 53) &&
+           (*b)->da->attr != 53) return -1;
 
        /*
         *      Relay-Agent is last
         */
-       if (((*a)->attribute == 82) &&
-           (*b)->attribute != 82) return +1;
+       if (((*a)->da->attr == 82) &&
+           (*b)->da->attr != 82) return +1;
 
-       return ((*a)->attribute - (*b)->attribute);
+       return ((*a)->da->attr - (*b)->da->attr);
 }
 
 
@@ -872,7 +865,7 @@ static size_t fr_dhcp_vp2attr(VALUE_PAIR *vp, uint8_t *p, size_t room)
         *      type, and pack them into the same
         *      attribute.
         */
-       switch (vp->type) {
+       switch (vp->da->type) {
        case PW_TYPE_BYTE:
                length = 1;
                *p = vp->vp_integer & 0xff;
@@ -916,7 +909,7 @@ static size_t fr_dhcp_vp2attr(VALUE_PAIR *vp, uint8_t *p, size_t room)
                break;
                
        default:
-               fr_strerror_printf("BAD TYPE2 %d", vp->type);
+               fr_strerror_printf("BAD TYPE2 %d", vp->da->type);
                length = 0;
                break;
        }
@@ -931,7 +924,7 @@ static VALUE_PAIR *fr_dhcp_vp2suboption(VALUE_PAIR *vps)
        uint8_t *ptr;
        VALUE_PAIR *vp, *tlv;
 
-       attribute = vps->attribute & 0xffff00ff;
+       attribute = vps->da->attr & 0xffff00ff;
 
        tlv = paircreate(attribute, DHCP_MAGIC_VENDOR, PW_TYPE_TLV);
        if (!tlv) return NULL;
@@ -942,9 +935,9 @@ static VALUE_PAIR *fr_dhcp_vp2suboption(VALUE_PAIR *vps)
                 *      Group the attributes ONLY until we see a
                 *      non-TLV attribute.
                 */
-               if (!vp->flags.is_tlv ||
-                   vp->flags.extended ||
-                   ((vp->attribute & 0xffff00ff) != attribute)) {
+               if (!vp->da->flags.is_tlv ||
+                   vp->da->flags.extended ||
+                   ((vp->da->attr & 0xffff00ff) != attribute)) {
                        break;
                }
 
@@ -964,9 +957,9 @@ static VALUE_PAIR *fr_dhcp_vp2suboption(VALUE_PAIR *vps)
 
        ptr = tlv->vp_tlv;
        for (vp = vps; vp != NULL; vp = vp->next) {
-               if (!vp->flags.is_tlv ||
-                   vp->flags.extended ||
-                   ((vp->attribute & 0xffff00ff) != attribute)) {
+               if (!vp->da->flags.is_tlv ||
+                   vp->da->flags.extended ||
+                   ((vp->da->attr & 0xffff00ff) != attribute)) {
                        break;
                }
 
@@ -977,11 +970,10 @@ static VALUE_PAIR *fr_dhcp_vp2suboption(VALUE_PAIR *vps)
                /*
                 *      Pack the attribute.
                 */
-               ptr[0] = (vp->attribute & 0xff00) >> 8;
+               ptr[0] = (vp->da->attr & 0xff00) >> 8;
                ptr[1] = length;
 
                ptr += length + 2;
-               vp->flags.extended = 1;
        }
 
        return tlv;
@@ -990,7 +982,7 @@ static VALUE_PAIR *fr_dhcp_vp2suboption(VALUE_PAIR *vps)
 
 int fr_dhcp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original)
 {
-       int i, num_vps;
+       unsigned int i, num_vps;
        uint8_t *p;
        VALUE_PAIR *vp;
        uint32_t lvalue, mms;
@@ -1321,7 +1313,7 @@ int fr_dhcp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original)
                                return -1;
                        }
                        
-                       switch (vp->type) {
+                       switch (vp->da->type) {
                        case PW_TYPE_BYTE:
                                vp->vp_integer = p[0];
                                vp->length = 1;
@@ -1360,7 +1352,7 @@ int fr_dhcp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original)
                                break;
                                
                        default:
-                               fr_strerror_printf("Internal sanity check failed %d %d", vp->type, __LINE__);
+                               fr_strerror_printf("Internal sanity check failed %d %d", vp->da->type, __LINE__);
                                pairfree(&vp);
                                break;
                        }
@@ -1425,41 +1417,43 @@ int fr_dhcp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original)
                VALUE_PAIR *same;
                uint8_t *plength, *pattr;
 
-               if (vp->vendor != DHCP_MAGIC_VENDOR) goto next;
-               if (vp->attribute == 53) goto next; /* already done */
-               if ((vp->attribute > 255) &&
-                   (DHCP_BASE_ATTR(vp->attribute) != PW_DHCP_OPTION_82)) goto next;
+               if (vp->da->vendor != DHCP_MAGIC_VENDOR) goto next;
+               if (vp->da->attr == 53) goto next; /* already done */
+               if ((vp->da->attr > 255) &&
+                   (DHCP_BASE_ATTR(vp->da->attr) != PW_DHCP_OPTION_82)) goto next;
 
                debug_pair(vp);
-               if (vp->flags.extended) goto next;
+               if (vp->da->flags.extended) goto next;
 
                length = vp->length;
 
                for (same = vp->next; same != NULL; same = same->next) {
-                       if (same->attribute != vp->attribute) break;
+                       if (same->da->attr != vp->da->attr) break;
                        num_entries++;
                }
 
                /*
                 *      For client-identifier
+                * @fixme What's this meant to be doing?!
                 */
-               if ((vp->type == PW_TYPE_ETHERNET) &&
+#if 0
+               if ((vp->da->type == PW_TYPE_ETHERNET) &&
                    (vp->length == 6) &&
                    (num_entries == 1)) {
-                       vp->type = PW_TYPE_OCTETS;
+                       vp->da->type = PW_TYPE_OCTETS;
                        memmove(vp->vp_octets + 1, vp->vp_octets, 6);
                        vp->vp_octets[0] = 1;
                }
-
+#endif
                pattr = p;
-               *(p++) = vp->attribute & 0xff;
+               *(p++) = vp->da->attr & 0xff;
                plength = p;
                *(p++) = 0;     /* header isn't included in attr length */
 
                for (i = 0; i < num_entries; i++) {
                        debug_pair(vp);
 
-                       if (vp->flags.is_tlv) {
+                       if (vp->da->flags.is_tlv) {
                                VALUE_PAIR *tlv;
 
                                /*
@@ -1485,7 +1479,7 @@ int fr_dhcp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original)
                         *      limitations: sizeof(vp->vp_octets) < 255
                         */
                        if (length > 255) {
-                               fr_strerror_printf("WARNING Ignoring too long attribute %s!", vp->name);
+                               fr_strerror_printf("WARNING Ignoring too long attribute %s!", vp->da->name);
                                break;
                        }
 
@@ -1496,7 +1490,7 @@ int fr_dhcp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original)
                         *      go bananas!
                         */
                        if ((*plength + length) > 255) {
-                               fr_strerror_printf("WARNING Ignoring too long attribute %s!", vp->name);
+                               fr_strerror_printf("WARNING Ignoring too long attribute %s!", vp->da->name);
                                break;
                        }
                        
@@ -1504,7 +1498,7 @@ int fr_dhcp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original)
                        p += length;
 
                        if (vp->next &&
-                           (vp->next->attribute == vp->attribute))
+                           (vp->next->da->attr == vp->da->attr))
                                vp = vp->next;
                } /* loop over num_entries */
 
index faa9170..de0ab82 100644 (file)
@@ -215,15 +215,16 @@ int vp_prints_value(char * out, size_t outlen, const VALUE_PAIR *vp, int delimit
        out[0] = '\0';
        if (!vp) return 0;
 
-       if ((vp->type & PW_FLAG_LONG) != 0) goto do_tlv;
+       if ((vp->da->type & PW_FLAG_LONG) != 0) goto do_tlv;
 
-       switch (vp->type) {
+       switch (vp->da->type) {
                case PW_TYPE_STRING:
-                       if ((delimitst == 1) && vp->flags.has_tag) {
+                       if ((delimitst == 1) && vp->da->flags.has_tag) {
                                /* Tagged attribute: print delimter and ignore tag */
                                buf[0] = '"';
                                fr_print_string(vp->vp_strvalue,
-                                                vp->length, buf + 1, sizeof(buf) - 2);
+                                               vp->length, buf + 1,
+                                               sizeof(buf) - 2);
                                strcat(buf, "\"");
                        } else if (delimitst == 1) {
                                /* Non-tagged attribute: print delimter */
@@ -244,9 +245,9 @@ int vp_prints_value(char * out, size_t outlen, const VALUE_PAIR *vp, int delimit
                        a = buf;
                        break;
                case PW_TYPE_INTEGER:
-                       if ( vp->flags.has_tag ) {
+                       if (vp->da->flags.has_tag) {
                                /* Attribute value has a tag, need to ignore it */
-                               if ((v = dict_valbyattr(vp->attribute, vp->vendor, (vp->vp_integer & 0xffffff)))
+                               if ((v = dict_valbyattr(vp->da->attr, vp->da->vendor, (vp->vp_integer & 0xffffff)))
                                    != NULL)
                                        a = v->name;
                                else {
@@ -257,7 +258,7 @@ int vp_prints_value(char * out, size_t outlen, const VALUE_PAIR *vp, int delimit
                case PW_TYPE_BYTE:
                case PW_TYPE_SHORT:
                                /* Normal, non-tagged attribute */
-                               if ((v = dict_valbyattr(vp->attribute, vp->vendor, vp->vp_integer))
+                               if ((v = dict_valbyattr(vp->da->attr, vp->da->vendor, vp->vp_integer))
                                    != NULL)
                                        a = v->name;
                                else {
@@ -396,16 +397,13 @@ int vp_prints_value_json(char *buffer, size_t bufsize, const VALUE_PAIR *vp)
        char *p = buffer;
        const char *q;
  
-       if (!vp->flags.has_tag) {
-               switch (vp->type) {
+       if (!vp->da->flags.has_tag) {
+               switch (vp->da->type) {
                        case PW_TYPE_INTEGER:
                        case PW_TYPE_BYTE:
                        case PW_TYPE_SHORT:
-                               if (dict_valbyattr(vp->attribute, vp->vendor,
-                                   vp->vp_integer)) {
-                                       break;
-                               }
-                               
+                               if (vp->da->flags.has_value) break;
+
                                len = snprintf(buffer, bufsize, "%u", vp->vp_integer);
                                return ((unsigned) len >= (bufsize - 1)) ? -1 : len;
 
@@ -421,7 +419,7 @@ int vp_prints_value_json(char *buffer, size_t bufsize, const VALUE_PAIR *vp)
        if(bufsize < 3) return -1;
        *p++ = '"';
 
-       switch (vp->type) {
+       switch (vp->da->type) {
                case PW_TYPE_STRING:
                        for (q = vp->vp_strvalue; q < vp->vp_strvalue + vp->length; q++) {
                                s = bufsize - (p - buffer);
@@ -615,15 +613,15 @@ int vp_prints(char *out, size_t outlen, const VALUE_PAIR *vp)
                token = "<INVALID-TOKEN>";
        }
 
-       if( vp->flags.has_tag ) {
+       if(vp->da->flags.has_tag) {
                snprintf(out, outlen, "%s:%d %s ",
-                        vp->name, vp->flags.tag, token);
+                        vp->da->name, vp->flags.tag, token);
 
                len = strlen(out);
                vp_prints_value(out + len, outlen - len, vp, 1);
 
        } else {
-               snprintf(out, outlen, "%s %s ", vp->name, token);
+               snprintf(out, outlen, "%s %s ", vp->da->name, token);
                len = strlen(out);
                vp_prints_value(out + len, outlen - len, vp, 1);
 
index b7febaa..1b55522 100644 (file)
@@ -42,8 +42,23 @@ RCSID("$Id$")
 
 #if 0
 #define VP_TRACE if (fr_debug_flag) printf
+
+static void VP_HEXDUMP(const char *msg, const uint8_t *data, size_t len)
+{
+       size_t i;
+
+       printf("--- %s ---\n", msg);
+       for (i = 0; i < len; i++) {
+               if ((i & 0x0f) == 0) printf("%04x: ", (unsigned int) i);
+               printf("%02x ", data[i]);
+               if ((i & 0x0f) == 0x0f) printf("\n");
+       }
+       if ((len == 0x0f) || ((len & 0x0f) != 0x0f)) printf("\n");
+}
+
 #else
 #define VP_TRACE(_x, ...)
+#define VP_HEXDUMP(_x, _y, _z)
 #endif
 
 
@@ -701,13 +716,13 @@ static int do_next_tlv(const VALUE_PAIR *vp, const VALUE_PAIR *next, int nest)
        /*
         *      Not from the same vendor, skip it.
         */
-       if (vp->vendor != next->vendor) return 0;
+       if (vp->da->vendor != next->da->vendor) return 0;
 
        /*
         *      In a different TLV space, skip it.
         */
-       tlv1 = vp->attribute;
-       tlv2 = next->attribute;
+       tlv1 = vp->da->attr;
+       tlv2 = next->da->attr;
        
        tlv1 &= ((1 << fr_attr_shift[nest]) - 1);
        tlv2 &= ((1 << fr_attr_shift[nest]) - 1);
@@ -758,7 +773,7 @@ static ssize_t vp2data_tlvs(const RADIUS_PACKET *packet,
        while (vp) {
                if (room < 2) return ptr - start;
                
-               ptr[0] = (vp->attribute >> fr_attr_shift[nest]) & fr_attr_mask[nest];
+               ptr[0] = (vp->da->attr >> fr_attr_shift[nest]) & fr_attr_mask[nest];
                ptr[1] = 2;
                
                my_room = room;
@@ -790,7 +805,7 @@ static ssize_t vp2data_tlvs(const RADIUS_PACKET *packet,
        if ((fr_debug_flag > 3) && fr_log_fp) {
                const DICT_ATTR *da;
                
-               da = dict_attrbyvalue(svp->attribute & ((1 << fr_attr_shift[nest ]) - 1), svp->vendor);
+               da = dict_attrbyvalue(svp->da->attr & ((1 << fr_attr_shift[nest ]) - 1), svp->da->vendor);
                if (da) fprintf(fr_log_fp, "\t%s = ...\n", da->name);
        }
 #endif
@@ -824,8 +839,8 @@ static ssize_t vp2data_any(const RADIUS_PACKET *packet,
         *
         *      If we cared about the stack, we could unroll the loop.
         */
-       if (vp->flags.is_tlv && (nest < fr_attr_max_tlv) &&
-           ((vp->attribute >> fr_attr_shift[nest + 1]) != 0)) {
+       if (vp->da->flags.is_tlv && (nest < fr_attr_max_tlv) &&
+           ((vp->da->attr >> fr_attr_shift[nest + 1]) != 0)) {
                return vp2data_tlvs(packet, original, secret, nest + 1, pvp,
                                    start, room);
        }
@@ -842,9 +857,9 @@ static ssize_t vp2data_any(const RADIUS_PACKET *packet,
         *      Short-circuit it for long attributes.  They can't be
         *      encrypted, tagged, etc.
         */
-       if ((vp->type & PW_FLAG_LONG) != 0) goto do_tlv;
+       if ((vp->da->type & PW_FLAG_LONG) != 0) goto do_tlv;
 
-       switch(vp->type) {
+       switch(vp->da->type) {
        case PW_TYPE_STRING:
        case PW_TYPE_OCTETS:
        case PW_TYPE_IFID:
@@ -915,7 +930,8 @@ static ssize_t vp2data_any(const RADIUS_PACKET *packet,
                break;
 
        default:                /* unknown type: ignore it */
-               fr_strerror_printf("ERROR: Unknown attribute type %d", vp->type);
+               fr_strerror_printf("ERROR: Unknown attribute type %d",
+                                  vp->da->type);
                return -1;
        }
 
@@ -938,7 +954,7 @@ static ssize_t vp2data_any(const RADIUS_PACKET *packet,
         *      Attributes with encrypted values MUST be less than
         *      128 bytes long.
         */
-       switch (vp->flags.encrypt) {
+       switch (vp->da->flags.encrypt) {
        case FLAG_ENCRYPT_USER_PASSWORD:
                make_passwd(ptr, &len, data, len,
                            secret, packet->vector);
@@ -946,7 +962,7 @@ static ssize_t vp2data_any(const RADIUS_PACKET *packet,
 
        case FLAG_ENCRYPT_TUNNEL_PASSWORD:
                lvalue = 0;
-               if (vp->flags.has_tag) lvalue = 1;
+               if (vp->da->flags.has_tag) lvalue = 1;
 
                /*
                 *      Check if there's enough room.  If there isn't,
@@ -963,7 +979,7 @@ static ssize_t vp2data_any(const RADIUS_PACKET *packet,
                case PW_ACCESS_CHALLENGE:
                default:
                        if (!original) {
-                               fr_strerror_printf("ERROR: No request packet, cannot encrypt %s attribute in the vp.", vp->name);
+                               fr_strerror_printf("ERROR: No request packet, cannot encrypt %s attribute in the vp.", vp->da->name);
                                return -1;
                        }
 
@@ -993,12 +1009,12 @@ static ssize_t vp2data_any(const RADIUS_PACKET *packet,
 
 
        default:
-               if (vp->flags.has_tag && TAG_VALID(vp->flags.tag)) {
-                       if (vp->type == PW_TYPE_STRING) {
+               if (vp->da->flags.has_tag && TAG_VALID(vp->flags.tag)) {
+                       if (vp->da->type == PW_TYPE_STRING) {
                                if (len > ((ssize_t) (room - 1))) len = room - 1;
                                ptr[0] = vp->flags.tag;
                                ptr++;
-                       } else if (vp->type == PW_TYPE_INTEGER) {
+                       } else if (vp->da->type == PW_TYPE_INTEGER) {
                                array[0] = vp->flags.tag;
                        } /* else it can't be any other type */
                }
@@ -1083,7 +1099,7 @@ int rad_vp2extended(const RADIUS_PACKET *packet,
        uint8_t *start = ptr;
        const VALUE_PAIR *vp = *pvp;
 
-       if (!vp->flags.extended) {
+       if (!vp->da->flags.extended) {
                fr_strerror_printf("rad_vp2extended called for non-extended attribute");
                return -1;
        }
@@ -1092,19 +1108,19 @@ int rad_vp2extended(const RADIUS_PACKET *packet,
         *      The attribute number is encoded into the upper 8 bits
         *      of the vendor ID.
         */
-       ptr[0] = (vp->vendor / FR_MAX_VENDOR) & 0xff;
+       ptr[0] = (vp->da->vendor / FR_MAX_VENDOR) & 0xff;
 
-       if (!vp->flags.long_extended) {
+       if (!vp->da->flags.long_extended) {
                if (room < 3) return 0;
        
                ptr[1] = 3;
-               ptr[2] = vp->attribute & fr_attr_mask[0];
+               ptr[2] = vp->da->attr & fr_attr_mask[0];
 
        } else {
                if (room < 4) return 0;
 
                ptr[1] = 4;
-               ptr[2] = vp->attribute & fr_attr_mask[0];
+               ptr[2] = vp->da->attr & fr_attr_mask[0];
                ptr[3] = 0;
        }
 
@@ -1112,14 +1128,14 @@ int rad_vp2extended(const RADIUS_PACKET *packet,
         *      Only "flagged" attributes can be longer than one
         *      attribute.
         */
-       if (!vp->flags.long_extended && (room > 255)) {
+       if (!vp->da->flags.long_extended && (room > 255)) {
                room = 255;
        }
 
        /*
         *      Handle EVS VSAs.
         */
-       if (vp->flags.evs) {
+       if (vp->da->flags.evs) {
                uint8_t *evs = ptr + ptr[1];
 
                if (room < (size_t) (ptr[1] + 5)) return 0;
@@ -1127,10 +1143,10 @@ int rad_vp2extended(const RADIUS_PACKET *packet,
                ptr[2] = 26;
 
                evs[0] = 0;     /* always zero */
-               evs[1] = (vp->vendor >> 16) & 0xff;
-               evs[2] = (vp->vendor >> 8) & 0xff;
-               evs[3] = vp->vendor & 0xff;
-               evs[4] = vp->attribute & fr_attr_mask[0];               
+               evs[1] = (vp->da->vendor >> 16) & 0xff;
+               evs[2] = (vp->da->vendor >> 8) & 0xff;
+               evs[3] = vp->da->vendor & 0xff;
+               evs[4] = vp->da->attr & fr_attr_mask[0];                
 
                ptr[1] += 5;
        }
@@ -1146,7 +1162,7 @@ int rad_vp2extended(const RADIUS_PACKET *packet,
         *      and copy the existing header over.  Set the "M" flag ONLY
         *      after copying the rest of the data.
         */
-       if (vp->flags.long_extended && (len > (255 - ptr[1]))) {
+       if (vp->da->flags.long_extended && (len > (255 - ptr[1]))) {
                return attr_shift(start, start + room, ptr, 4, len, 3, 0);
        }
 
@@ -1157,7 +1173,7 @@ int rad_vp2extended(const RADIUS_PACKET *packet,
                int jump = 3;
 
                fprintf(fr_log_fp, "\t\t%02x %02x  ", ptr[0], ptr[1]);
-               if (!vp->flags.long_extended) {
+               if (!vp->da->flags.long_extended) {
                        fprintf(fr_log_fp, "%02x  ", ptr[2]);
                        
                } else {
@@ -1165,7 +1181,7 @@ int rad_vp2extended(const RADIUS_PACKET *packet,
                        jump = 4;
                }
 
-               if (vp->flags.evs) {
+               if (vp->da->flags.evs) {
                        fprintf(fr_log_fp, "%02x%02x%02x%02x (%u)  %02x  ",
                                ptr[jump], ptr[jump + 1],
                                ptr[jump + 2], ptr[jump + 3],
@@ -1201,7 +1217,7 @@ int rad_vp2wimax(const RADIUS_PACKET *packet,
        /*
         *      Double-check for WiMAX format.
         */
-       if (!vp->flags.wimax) {
+       if (!vp->da->flags.wimax) {
                fr_strerror_printf("rad_vp2wimax called for non-WIMAX VSA");
                return -1;
        }
@@ -1218,9 +1234,9 @@ int rad_vp2wimax(const RADIUS_PACKET *packet,
        ptr = start;
        ptr[0] = PW_VENDOR_SPECIFIC;
        ptr[1] = 9;
-       lvalue = htonl(vp->vendor);
+       lvalue = htonl(vp->da->vendor);
        memcpy(ptr + 2, &lvalue, 4);
-       ptr[6] = (vp->attribute & fr_attr_mask[1]);
+       ptr[6] = (vp->da->attr & fr_attr_mask[1]);
        ptr[7] = 3;
        ptr[8] = 0;             /* continuation byte */
 
@@ -1262,7 +1278,7 @@ int rad_vp2wimax(const RADIUS_PACKET *packet,
  *
  *     This could be a standard attribute,
  *     or a TLV data type.  If it's a standard attribute, then
- *     vp->attribute == attribute.  Otherwise, attribute may be
+ *     vp->da->attr == attribute.  Otherwise, attribute may be
  *     something else.
  */
 static ssize_t vp2attr_rfc(const RADIUS_PACKET *packet,
@@ -1315,7 +1331,7 @@ static ssize_t vp2attr_vsa(const RADIUS_PACKET *packet,
         */
        dv = dict_vendorbyvalue(vendor);
        if (!dv ||
-           (!vp->flags.is_tlv && (dv->type == 1) && (dv->length == 1))) {
+           (!vp->da->flags.is_tlv && (dv->type == 1) && (dv->length == 1))) {
                return vp2attr_rfc(packet, original, secret, pvp,
                                   attribute, ptr, room);
        }
@@ -1438,12 +1454,12 @@ int rad_vp2vsa(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
        /*
         *      Double-check for WiMAX format.
         */
-       if (vp->flags.wimax) {
+       if (vp->da->flags.wimax) {
                return rad_vp2wimax(packet, original, secret, pvp,
                                    ptr, room);
        }
 
-       if (vp->vendor > FR_MAX_VENDOR) {
+       if (vp->da->vendor > FR_MAX_VENDOR) {
                fr_strerror_printf("rad_vp2vsa: Invalid arguments");
                return -1;
        }
@@ -1459,13 +1475,13 @@ int rad_vp2vsa(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
         */
        ptr[0] = PW_VENDOR_SPECIFIC;
        ptr[1] = 6;
-       lvalue = htonl(vp->vendor);
+       lvalue = htonl(vp->da->vendor);
        memcpy(ptr + 2, &lvalue, 4);
 
        if (room > ((unsigned) 255 - ptr[1])) room = 255 - ptr[1];
 
        len = vp2attr_vsa(packet, original, secret, pvp,
-                         vp->attribute, vp->vendor,
+                         vp->da->attr, vp->da->vendor,
                          ptr + ptr[1], room);
        if (len < 0) return len;
 
@@ -1495,13 +1511,13 @@ int rad_vp2rfc(const RADIUS_PACKET *packet,
 {
        const VALUE_PAIR *vp = *pvp;
 
-       if (vp->vendor != 0) {
+       if (vp->da->vendor != 0) {
                fr_strerror_printf("rad_vp2rfc called with VSA");
                return -1;
        }
 
-       if ((vp->attribute == 0) || (vp->attribute > 255)) {
-               fr_strerror_printf("rad_vp2rfc called with non-standard attribute %u", vp->attribute);
+       if ((vp->da->attr == 0) || (vp->da->attr > 255)) {
+               fr_strerror_printf("rad_vp2rfc called with non-standard attribute %u", vp->da->attr);
                return -1;
        }
 
@@ -1510,7 +1526,7 @@ int rad_vp2rfc(const RADIUS_PACKET *packet,
         *      Thank you, WiMAX!
         */
        if ((vp->length == 0) &&
-           (vp->attribute == PW_CHARGEABLE_USER_IDENTITY)) {
+           (vp->da->attr == PW_CHARGEABLE_USER_IDENTITY)) {
                ptr[0] = PW_CHARGEABLE_USER_IDENTITY;
                ptr[1] = 2;
 
@@ -1521,7 +1537,7 @@ int rad_vp2rfc(const RADIUS_PACKET *packet,
        /*
         *      Message-Authenticator is hard-coded.
         */
-       if (vp->attribute == PW_MESSAGE_AUTHENTICATOR) {
+       if (vp->da->attr == PW_MESSAGE_AUTHENTICATOR) {
                if (room < 18) return -1;
                
                debug_pair(vp);
@@ -1538,7 +1554,7 @@ int rad_vp2rfc(const RADIUS_PACKET *packet,
                return 18;
        }
 
-       return vp2attr_rfc(packet, original, secret, pvp, vp->attribute,
+       return vp2attr_rfc(packet, original, secret, pvp, vp->da->attr,
                           ptr, room);
 }
 
@@ -1550,12 +1566,12 @@ static ssize_t rad_vp2rfctlv(const RADIUS_PACKET *packet,
        ssize_t len;
        const VALUE_PAIR *vp = *pvp;
 
-       if (!vp->flags.is_tlv) {
+       if (!vp->da->flags.is_tlv) {
                fr_strerror_printf("rad_vp2rfctlv: attr is not a TLV");
                return -1;
        }
 
-       if ((vp->vendor & (FR_MAX_VENDOR - 1)) != 0) {
+       if ((vp->da->vendor & (FR_MAX_VENDOR - 1)) != 0) {
                fr_strerror_printf("rad_vp2rfctlv: attr is not an RFC TLV");
                return -1;
        }
@@ -1565,9 +1581,9 @@ static ssize_t rad_vp2rfctlv(const RADIUS_PACKET *packet,
        /*
         *      Encode the first level of TLVs
         */
-       start[0] = (vp->vendor / FR_MAX_VENDOR) & 0xff;
+       start[0] = (vp->da->vendor / FR_MAX_VENDOR) & 0xff;
        start[1] = 4;
-       start[2] = vp->attribute & fr_attr_mask[0];
+       start[2] = vp->da->attr & fr_attr_mask[0];
        start[3] = 2;
 
        len = vp2data_any(packet, original, secret, 0, pvp,
@@ -1601,14 +1617,14 @@ int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
        /*
         *      RFC format attributes take the fast path.
         */
-       if (!vp->vendor) {
-               if (vp->attribute > 255) return 0;
+       if (!vp->da->vendor) {
+               if (vp->da->attr > 255) return 0;
 
                return rad_vp2rfc(packet, original, secret, pvp,
                                  start, room);
        }
 
-       if (vp->flags.extended) {
+       if (vp->da->flags.extended) {
                return rad_vp2extended(packet, original, secret, pvp,
                                       start, room);
        }
@@ -1617,12 +1633,12 @@ int rad_vp2attr(const RADIUS_PACKET *packet, const RADIUS_PACKET *original,
         *      The upper 8 bits of the vendor number are the standard
         *      space attribute which is a TLV.
         */
-       if ((vp->vendor & (FR_MAX_VENDOR - 1)) == 0) {
+       if ((vp->da->vendor & (FR_MAX_VENDOR - 1)) == 0) {
                return rad_vp2rfctlv(packet, original, secret, pvp,
                                     start, room);
        }
 
-       if (vp->flags.wimax) {
+       if (vp->da->flags.wimax) {
                return rad_vp2wimax(packet, original, secret, pvp,
                                    start, room);
        }
@@ -1738,15 +1754,15 @@ int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                 *      Ignore non-wire attributes, but allow extended
                 *      attributes.
                 */
-               if ((reply->vendor == 0) &&
-                   ((reply->attribute & 0xFFFF) >= 256) &&
-                   !reply->flags.extended && !reply->flags.long_extended) {
+               if ((reply->da->vendor == 0) &&
+                   ((reply->da->attr & 0xFFFF) >= 256) &&
+                   !reply->da->flags.extended && !reply->da->flags.long_extended) {
 #ifndef NDEBUG
                        /*
                         *      Permit the admin to send BADLY formatted
                         *      attributes with a debug build.
                         */
-                       if (reply->attribute == PW_RAW_ATTRIBUTE) {
+                       if (reply->da->attr == PW_RAW_ATTRIBUTE) {
                                memcpy(ptr, reply->vp_octets, reply->length);
                                len = reply->length;
                                reply = reply->next;
@@ -1761,7 +1777,7 @@ int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                 *      Set the Message-Authenticator to the correct
                 *      length and initial value.
                 */
-               if (reply->attribute == PW_MESSAGE_AUTHENTICATOR) {
+               if (reply->da->attr == PW_MESSAGE_AUTHENTICATOR) {
                        /*
                         *      Cache the offset to the
                         *      Message-Authenticator
@@ -1771,7 +1787,7 @@ int rad_encode(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                } else {
                        last_len = reply->length;
                }
-               last_name = reply->name;
+               last_name = reply->da->name;
 
                len = rad_vp2attr(packet, original, secret, &reply, ptr,
                                  ((uint8_t *) data) + sizeof(data) - ptr);
@@ -2000,8 +2016,8 @@ int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                      packet->dst_port);
 
                for (reply = packet->vps; reply; reply = reply->next) {
-                       if ((reply->vendor == 0) &&
-                           ((reply->attribute & 0xFFFF) > 0xff)) continue;
+                       if ((reply->da->vendor == 0) &&
+                           ((reply->da->attr & 0xFFFF) > 0xff)) continue;
                        debug_pair(reply);
                }
        }
@@ -2252,7 +2268,7 @@ int rad_packet_ok(RADIUS_PACKET *packet, int flags)
         */
        if ((hdr->code == 0) ||
            (hdr->code >= FR_MAX_PACKET_CODE)) {
-               fr_strerror_printf("WARNING: Bad RADIUS packet from host %s: unknown packet code%d ",
+               fr_strerror_printf("WARNING: Bad RADIUS packet from host %s: unknown packet code %d",
                           inet_ntop(packet->src_ipaddr.af,
                                     &packet->src_ipaddr.ipaddr,
                                     host_ipaddr, sizeof(host_ipaddr)),
@@ -3950,9 +3966,9 @@ ssize_t rad_vp2data(const VALUE_PAIR *vp, uint8_t *out, size_t outlen)
        /*
         *      Short-circuit it for long attributes.
         */
-       if ((vp->type & PW_FLAG_LONG) != 0) goto do_raw;
+       if ((vp->da->type & PW_FLAG_LONG) != 0) goto do_raw;
 
-       switch(vp->type) {
+       switch(vp->da->type) {
                case PW_TYPE_STRING:
                case PW_TYPE_OCTETS:
                case PW_TYPE_IFID:
@@ -4000,7 +4016,7 @@ ssize_t rad_vp2data(const VALUE_PAIR *vp, uint8_t *out, size_t outlen)
                /* unknown type: ignore it */
                default:                
                        fr_strerror_printf("ERROR: Unknown attribute type %d",
-                                          vp->type);
+                                          vp->da->type);
                        return -1;
        }
        
index 8343743..557558a 100644 (file)
@@ -272,9 +272,9 @@ void pairdelete(VALUE_PAIR **first, unsigned int attr, unsigned int vendor,
 
        for(i = *first; i; i = next) {
                next = i->next;
-               if ((i->attribute == attr) && (i->vendor == vendor) &&
+               if ((i->da->attr == attr) && (i->da->vendor == vendor) &&
                    ((tag == TAG_ANY) ||
-                    (i->flags.has_tag && (i->flags.tag == tag)))) {
+                    (i->da->flags.has_tag && (i->flags.tag == tag)))) {
                        *last = next;
                        pairbasicfree(i);
                } else {
@@ -338,9 +338,8 @@ void pairreplace(VALUE_PAIR **first, VALUE_PAIR *replace)
                 *      Found the first attribute, replace it,
                 *      and return.
                 */
-               if ((i->attribute == replace->attribute) &&
-                   (i->vendor == replace->vendor) &&
-                   (!i->flags.has_tag || (i->flags.tag == replace->flags.tag))
+               if ((i->da == replace->da) &&
+                   (!i->da->flags.has_tag || (i->flags.tag == replace->flags.tag))
                ) {
                        *prev = replace;
 
@@ -468,10 +467,10 @@ VALUE_PAIR *paircopy2(VALUE_PAIR *vp, unsigned int attr, unsigned int vendor,
 
        while (vp) {
                if ((attr > 0) &&
-                   ((vp->attribute != attr) || (vp->vendor != vendor)))
+                   ((vp->da->attr != attr) || (vp->da->vendor != vendor)))
                        goto skip;
                        
-               if ((tag != TAG_ANY) && vp->flags.has_tag &&
+               if ((tag != TAG_ANY) && vp->da->flags.has_tag &&
                    (vp->flags.tag != tag)) {
                        goto skip;
                }
@@ -529,8 +528,8 @@ void pairmove(VALUE_PAIR **to, VALUE_PAIR **from)
         */
        tailto = to;
        for(i = *to; i; i = i->next) {
-               if (i->attribute == PW_USER_PASSWORD ||
-                   i->attribute == PW_CRYPT_PASSWORD)
+               if (i->da->attr == PW_USER_PASSWORD ||
+                   i->da->attr == PW_CRYPT_PASSWORD)
                        has_password = 1;
                tailto = &i->next;
        }
@@ -547,8 +546,8 @@ void pairmove(VALUE_PAIR **to, VALUE_PAIR **from)
                 *      "from" to the "to" list.
                 */
                if (has_password &&
-                   (i->attribute == PW_USER_PASSWORD ||
-                    i->attribute == PW_CRYPT_PASSWORD)) {
+                   (i->da->attr == PW_USER_PASSWORD ||
+                    i->da->attr == PW_CRYPT_PASSWORD)) {
                        tailfrom = i;
                        continue;
                }
@@ -582,11 +581,13 @@ void pairmove(VALUE_PAIR **to, VALUE_PAIR **from)
                 *      an exception for "Hint" which can appear multiple
                 *      times, and we never move "Fall-Through".
                 */
-               if (i->attribute == PW_FALL_THROUGH ||
-                   (i->attribute != PW_HINT && i->attribute != PW_FRAMED_ROUTE)) {
+               if (i->da->attr == PW_FALL_THROUGH ||
+                   (i->da->attr != PW_HINT && i->da->attr != PW_FRAMED_ROUTE)) {
 
 
-                       found = pairfind(*to, i->attribute, i->vendor, TAG_ANY);
+                       found = pairfind(*to, i->da->attr, i->da->vendor,
+                                        TAG_ANY);
+                                        
                        switch (i->op) {
 
                        /*
@@ -598,7 +599,10 @@ void pairmove(VALUE_PAIR **to, VALUE_PAIR **from)
                                        if (!i->vp_strvalue[0] ||
                                            (strcmp((char *)found->vp_strvalue,
                                                    (char *)i->vp_strvalue) == 0)){
-                                               pairdelete(to, found->attribute, found->vendor, TAG_ANY);
+                                               pairdelete(to,
+                                                          found->da->attr,
+                                                          found->da->vendor,
+                                                          TAG_ANY);
 
                                                /*
                                                 *      'tailto' may have been
@@ -649,7 +653,9 @@ void pairmove(VALUE_PAIR **to, VALUE_PAIR **from)
                                        memcpy(found, i, sizeof(*found));
                                        found->next = mynext;
 
-                                       pairdelete(&found->next, found->attribute, found->vendor, TAG_ANY);
+                                       pairdelete(&found->next,
+                                                  found->da->attr,
+                                                  found->da->vendor, TAG_ANY);
 
                                        /*
                                         *      'tailto' may have been
@@ -726,7 +732,7 @@ void pairmove2(VALUE_PAIR **to, VALUE_PAIR **from, unsigned int attr,
        for(i = *from; i; i = next) {
                next = i->next;
 
-               if ((tag != TAG_ANY) && i->flags.has_tag &&
+               if ((tag != TAG_ANY) && i->da->flags.has_tag &&
                    (i->flags.tag != tag)) {
                        continue;
                }
@@ -739,12 +745,12 @@ void pairmove2(VALUE_PAIR **to, VALUE_PAIR **from, unsigned int attr,
                        /*
                         *      It's a VSA: move it over.
                         */
-                       if (i->vendor != 0) goto move;
+                       if (i->da->vendor != 0) goto move;
 
                        /*
                         *      It's Vendor-Specific: move it over.
                         */
-                       if (i->attribute == attr) goto move;
+                       if (i->da->attr == attr) goto move;
 
                        /*
                         *      It's not a VSA: ignore it.
@@ -756,7 +762,7 @@ void pairmove2(VALUE_PAIR **to, VALUE_PAIR **from, unsigned int attr,
                /*
                 *      If it isn't an exact match, ignore it.
                 */
-               if (!((i->vendor == vendor) && (i->attribute == attr))) {
+               if (!((i->da->vendor == vendor) && (i->da->attr == attr))) {
                        iprev = i;
                        continue;
                }
@@ -987,12 +993,12 @@ VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
         *      Even for integers, dates and ip addresses we
         *      keep the original string in vp->vp_strvalue.
         */
-       if (vp->type != PW_TYPE_TLV) {
+       if (vp->da->type != PW_TYPE_TLV) {
                strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
                vp->length = strlen(vp->vp_strvalue);
        }
 
-       switch(vp->type) {
+       switch(vp->da->type) {
        case PW_TYPE_STRING:
                /*
                 *      Do escaping here
@@ -1151,7 +1157,7 @@ VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
                p = vp->vp_strvalue;
                if (sscanf(p, "%llu", &y) != 1) {
                        fr_strerror_printf("Invalid value %s for attribute %s",
-                                          value, vp->name);
+                                          value, vp->da->name);
                        return NULL;
                }
                vp->vp_integer64 = y;
@@ -1763,9 +1769,9 @@ VALUE_PAIR *pairmake(const char *attribute, const char *value, FR_TOKEN op)
                /* If we already found a tag, this is invalid */
                if(found_tag) {
                        fr_strerror_printf("Duplicate tag %s for attribute %s",
-                                  value, vp->name);
+                                  value, vp->da->name);
                        DEBUG("Duplicate tag %s for attribute %s\n",
-                                  value, vp->name);
+                                  value, vp->da->name);
                        pairbasicfree(vp);
                        return NULL;
                }
@@ -2239,13 +2245,15 @@ int paircmp(VALUE_PAIR *one, VALUE_PAIR *two)
        /*
         *      Can't compare two attributes of differing types
         */
-       if (one->type != two->type) return one->type - two->type;
-
+       if (one->da->type != two->da->type) {
+               return one->da->type - two->da->type;
+       }
+       
        /*
         *      After doing the previous check for special comparisons,
         *      do the per-type comparison here.
         */
-       switch (one->type) {
+       switch (one->da->type) {
        case PW_TYPE_ABINARY:
        case PW_TYPE_OCTETS:
        {
index 4eaeb83..e6f0f7f 100644 (file)
@@ -493,14 +493,21 @@ int vqp_decode(RADIUS_PACKET *packet)
                        return -1;
                }
 
-               switch (vp->type) {
+               switch (vp->da->type) {
                case PW_TYPE_IPADDR:
                        if (length == 4) {
                                memcpy(&vp->vp_ipaddr, ptr, 4);
                                vp->length = 4;
                                break;
                        }
-                       vp->type = PW_TYPE_OCTETS;
+                       
+                       /*
+                        *      Value doesn't match the type we have for the
+                        *      valuepair so we must change it's da to an
+                        *      unknown attr.
+                        */
+                       vp->da = dict_attrunknown(vp->da->attr, vp->da->vendor,
+                                                 TRUE);
                        /* FALL-THROUGH */
 
                default:
@@ -665,7 +672,7 @@ int vqp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original)
                ptr[0] = 0;
                ptr[1] = 0;
                ptr[2] = 0x0c;
-               ptr[3] = vp->attribute & 0xff;
+               ptr[3] = vp->da->attr & 0xff;
 
                /* Length */
                ptr[4] = 0;
@@ -674,7 +681,7 @@ int vqp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original)
                ptr += 6;
 
                /* Data */
-               switch (vp->type) {
+               switch (vp->da->type) {
                case PW_TYPE_IPADDR:
                        memcpy(ptr, &vp->vp_ipaddr, 4);
                        break;