2 * Copyright (C) 2012-2014 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 #include "ietf_attr_attr_request.h"
19 #include <pa_tnc/pa_tnc_msg.h>
20 #include <bio/bio_writer.h>
21 #include <bio/bio_reader.h>
22 #include <collections/linked_list.h>
24 #include <utils/debug.h>
26 typedef struct private_ietf_attr_attr_request_t private_ietf_attr_attr_request_t
;
29 * PA-TNC Attribute Request type (see section 4.2.1 of RFC 5792)
32 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
33 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34 * | Reserved | PA-TNC Attribute Vendor ID |
35 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36 * | PA-TNC Attribute Type |
37 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38 * | Reserved | PA-TNC Attribute Vendor ID |
39 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40 * | PA-TNC Attribute Type |
41 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 #define ATTR_REQUEST_ENTRY_SIZE 8
47 * Private data of an ietf_attr_attr_request_t object.
49 struct private_ietf_attr_attr_request_t
{
52 * Public members of ietf_attr_attr_request_t
54 ietf_attr_attr_request_t
public;
57 * Vendor-specific attribute type
62 * Length of attribute value
67 * Attribute value or segment
77 * List of requested attribute types
87 METHOD(pa_tnc_attr_t
, get_type
, pen_type_t
,
88 private_ietf_attr_attr_request_t
*this)
93 METHOD(pa_tnc_attr_t
, get_value
, chunk_t
,
94 private_ietf_attr_attr_request_t
*this)
99 METHOD(pa_tnc_attr_t
, get_noskip_flag
, bool,
100 private_ietf_attr_attr_request_t
*this)
102 return this->noskip_flag
;
105 METHOD(pa_tnc_attr_t
, set_noskip_flag
,void,
106 private_ietf_attr_attr_request_t
*this, bool noskip
)
108 this->noskip_flag
= noskip
;
111 METHOD(pa_tnc_attr_t
, build
, void,
112 private_ietf_attr_attr_request_t
*this)
114 bio_writer_t
*writer
;
115 enumerator_t
*enumerator
;
122 writer
= bio_writer_create(ATTR_REQUEST_ENTRY_SIZE
*
123 this->list
->get_count(this->list
));
125 enumerator
= this->list
->create_enumerator(this->list
);
126 while (enumerator
->enumerate(enumerator
, &entry
))
128 writer
->write_uint32(writer
, entry
->vendor_id
);
129 writer
->write_uint32(writer
, entry
->type
);
131 enumerator
->destroy(enumerator
);
133 this->value
= writer
->extract_buf(writer
);
134 this->length
= this->value
.len
;
135 writer
->destroy(writer
);
138 METHOD(ietf_attr_attr_request_t
, add
, void,
139 private_ietf_attr_attr_request_t
*this, pen_t vendor_id
, u_int32_t type
)
143 entry
= malloc_thing(pen_type_t
);
144 entry
->vendor_id
= vendor_id
;
146 this->list
->insert_last(this->list
, entry
);
149 METHOD(pa_tnc_attr_t
, process
, status_t
,
150 private_ietf_attr_attr_request_t
*this, u_int32_t
*offset
)
152 bio_reader_t
*reader
;
153 enum_name_t
*pa_attr_names
;
161 if (this->value
.len
< this->length
)
166 count
= this->value
.len
/ ATTR_REQUEST_ENTRY_SIZE
;
167 if (this->value
.len
!= ATTR_REQUEST_ENTRY_SIZE
* count
)
169 DBG1(DBG_TNC
, "incorrect attribute length for IETF attribute request");
173 reader
= bio_reader_create(this->value
);
176 reader
->read_uint8 (reader
, &reserved
);
177 reader
->read_uint24(reader
, &vendor_id
);
178 reader
->read_uint32(reader
, &type
);
180 pa_attr_names
= imcv_pa_tnc_attributes
->get_names(imcv_pa_tnc_attributes
,
184 DBG2(DBG_TNC
, " 0x%06x/0x%08x '%N/%N'", vendor_id
, type
,
185 pen_names
, vendor_id
, pa_attr_names
, type
);
189 DBG2(DBG_TNC
, " 0x%06x/0x%08x '%N'", vendor_id
, type
,
190 pen_names
, vendor_id
);
192 add(this, vendor_id
, type
);
194 reader
->destroy(reader
);
199 METHOD(pa_tnc_attr_t
, get_ref
, pa_tnc_attr_t
*,
200 private_ietf_attr_attr_request_t
*this)
203 return &this->public.pa_tnc_attribute
;
206 METHOD(pa_tnc_attr_t
, destroy
, void,
207 private_ietf_attr_attr_request_t
*this)
209 if (ref_put(&this->ref
))
211 this->list
->destroy_function(this->list
, free
);
212 free(this->value
.ptr
);
217 METHOD(ietf_attr_attr_request_t
, create_enumerator
, enumerator_t
*,
218 private_ietf_attr_attr_request_t
*this)
220 return this->list
->create_enumerator(this->list
);
224 * Described in header.
226 pa_tnc_attr_t
*ietf_attr_attr_request_create(pen_t vendor_id
, u_int32_t type
)
228 private_ietf_attr_attr_request_t
*this;
232 .pa_tnc_attribute
= {
233 .get_type
= _get_type
,
234 .get_value
= _get_value
,
235 .get_noskip_flag
= _get_noskip_flag
,
236 .set_noskip_flag
= _set_noskip_flag
,
243 .create_enumerator
= _create_enumerator
,
245 .type
= { PEN_IETF
, IETF_ATTR_ATTRIBUTE_REQUEST
},
246 .list
= linked_list_create(),
250 if (vendor_id
!= PEN_RESERVED
)
252 add(this, vendor_id
, type
);
255 return &this->public.pa_tnc_attribute
;
259 * Described in header.
261 pa_tnc_attr_t
*ietf_attr_attr_request_create_from_data(size_t length
,
264 private_ietf_attr_attr_request_t
*this;
268 .pa_tnc_attribute
= {
269 .get_type
= _get_type
,
270 .get_value
= _get_value
,
271 .get_noskip_flag
= _get_noskip_flag
,
272 .set_noskip_flag
= _set_noskip_flag
,
279 .create_enumerator
= _create_enumerator
,
281 .type
= { PEN_IETF
, IETF_ATTR_ATTRIBUTE_REQUEST
},
283 .value
= chunk_clone(data
),
284 .list
= linked_list_create(),
288 return &this->public.pa_tnc_attribute
;