2 * RADIUS tlv construction and parsing utilites
3 * Copyright (c) 2012, Painless Security, LLC
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
19 #include "radius/radius.h"
20 #include "radius_utils.h"
23 int radius_add_tlv(struct wpabuf **buf, u32 type, u32 vendor, u8 *data,
29 if (len + 6 > RADIUS_MAX_ATTR_LEN)
32 base_type = RADIUS_ATTR_VENDOR_SPECIFIC;
34 if (len > RADIUS_MAX_ATTR_LEN)
40 /* ensure buffer has enough space */
41 if (wpabuf_resize(buf, total))
44 /* write into buffer */
45 wpabuf_put_u8(*buf, base_type);
46 wpabuf_put_u8(*buf, total);
48 wpabuf_put_be32(*buf, vendor);
49 wpabuf_put_u8(*buf, (u8 )type);
50 wpabuf_put_u8(*buf, (u8 )len+2);
52 wpabuf_put_data(*buf, data, len);
56 struct radius_parser_struct
63 radius_parser radius_parser_start(void *tlvdata, size_t len)
65 radius_parser parser = malloc(sizeof(struct radius_parser_struct));
67 parser->data = (u8 *)tlvdata;
74 void radius_parser_finish(radius_parser parser)
79 int radius_parser_parse_tlv(radius_parser parser, u8 *type, u32 *vendor_id,
80 void **value, size_t *len)
85 if (parser->len < parser->pos + 3)
87 rawtype = parser->data[parser->pos];
88 rawlen = parser->data[parser->pos+1];
89 if (parser->len < parser->pos + rawlen)
92 if (rawtype == RADIUS_ATTR_VENDOR_SPECIFIC) {
95 *vendor_id = WPA_GET_BE24(&parser->data[parser->pos + 3]);
96 *value = &parser->data[parser->pos + 6];
102 *value = &parser->data[parser->pos + 2];
107 parser->pos += rawlen;
111 int radius_parser_parse_vendor_specific(radius_parser parser, u8 *vendor_type,
112 void **value, size_t *len)
117 if (parser->len < parser->pos + 3)
119 rawtype = parser->data[parser->pos];
120 rawlen = parser->data[parser->pos+1];
121 if (parser->len < parser->pos + rawlen)
127 *value = &parser->data[parser->pos + 2];
129 *vendor_type = rawtype;
131 parser->pos += rawlen;