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;