2 * Copyright (C) 2005-2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 #include "transform_attribute.h"
23 #include <encoding/payloads/encodings.h>
26 typedef struct private_transform_attribute_t private_transform_attribute_t
;
29 * Private data of an transform_attribute_t object.
31 struct private_transform_attribute_t
{
34 * Public transform_attribute_t interface.
36 transform_attribute_t
public;
39 * Attribute Format Flag.
41 * - TRUE means value is stored in attribute_length_or_value
42 * - FALSE means value is stored in attribute_value
44 bool attribute_format
;
47 * Type of the attribute.
49 u_int16_t attribute_type
;
52 * Attribute Length if attribute_format is 0, attribute Value otherwise.
54 u_int16_t attribute_length_or_value
;
57 * Attribute value as chunk if attribute_format is 0 (FALSE).
59 chunk_t attribute_value
;
63 ENUM_BEGIN(transform_attribute_type_name
, ATTRIBUTE_UNDEFINED
, ATTRIBUTE_UNDEFINED
,
64 "ATTRIBUTE_UNDEFINED");
65 ENUM_NEXT(transform_attribute_type_name
, KEY_LENGTH
, KEY_LENGTH
, ATTRIBUTE_UNDEFINED
,
67 ENUM_END(transform_attribute_type_name
, KEY_LENGTH
);
70 * Encoding rules to parse or generate a Transform attribute.
72 * The defined offsets are the positions in a object of type
73 * private_transform_attribute_t.
75 encoding_rule_t transform_attribute_encodings
[] = {
76 /* Flag defining the format of this payload */
77 { ATTRIBUTE_FORMAT
, offsetof(private_transform_attribute_t
, attribute_format
) },
78 /* type of the attribute as 15 bit unsigned integer */
79 { ATTRIBUTE_TYPE
, offsetof(private_transform_attribute_t
, attribute_type
) },
80 /* Length or value, depending on the attribute format flag */
81 { ATTRIBUTE_LENGTH_OR_VALUE
,offsetof(private_transform_attribute_t
, attribute_length_or_value
) },
82 /* Value of attribute if attribute format flag is zero */
83 { ATTRIBUTE_VALUE
, offsetof(private_transform_attribute_t
, attribute_value
) }
88 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
89 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
90 !A! Attribute Type ! AF=0 Attribute Length !
91 !F! ! AF=1 Attribute Value !
92 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
93 ! AF=0 Attribute Value !
94 ! AF=1 Not Transmitted !
95 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
98 METHOD(payload_t
, verify
, status_t
,
99 private_transform_attribute_t
*this)
104 METHOD(payload_t
, get_encoding_rules
, void,
105 private_transform_attribute_t
*this, encoding_rule_t
**rules
,
108 *rules
= transform_attribute_encodings
;
109 *rule_count
= countof(transform_attribute_encodings
);
112 METHOD(payload_t
, get_type
, payload_type_t
,
113 private_transform_attribute_t
*this)
115 return TRANSFORM_ATTRIBUTE
;
118 METHOD(payload_t
, get_next_type
, payload_type_t
,
119 private_transform_attribute_t
*this)
124 METHOD(payload_t
, set_next_type
, void,
125 private_transform_attribute_t
*this, payload_type_t type
)
129 METHOD(payload_t
, get_length
, size_t,
130 private_transform_attribute_t
*this)
132 if (this->attribute_format
)
136 return this->attribute_length_or_value
+ 4;
139 METHOD(transform_attribute_t
, set_value_chunk
, void,
140 private_transform_attribute_t
*this, chunk_t value
)
142 chunk_free(&this->attribute_value
);
146 this->attribute_value
= chunk_clone(value
);
147 this->attribute_length_or_value
= value
.len
;
148 this->attribute_format
= FALSE
;
152 memcpy(&this->attribute_length_or_value
, value
.ptr
, value
.len
);
156 METHOD(transform_attribute_t
, set_value
, void,
157 private_transform_attribute_t
*this, u_int16_t value
)
159 chunk_free(&this->attribute_value
);
160 this->attribute_length_or_value
= value
;
161 this->attribute_format
= TRUE
;
164 METHOD(transform_attribute_t
, get_value_chunk
, chunk_t
,
165 private_transform_attribute_t
*this)
167 if (this->attribute_format
)
169 return chunk_from_thing(this->attribute_length_or_value
);
171 return this->attribute_value
;
174 METHOD(transform_attribute_t
, get_value
, u_int16_t
,
175 private_transform_attribute_t
*this)
177 return this->attribute_length_or_value
;
180 METHOD(transform_attribute_t
, set_attribute_type
, void,
181 private_transform_attribute_t
*this, u_int16_t type
)
183 this->attribute_type
= type
& 0x7FFF;
186 METHOD(transform_attribute_t
, get_attribute_type
, u_int16_t
,
187 private_transform_attribute_t
*this)
189 return this->attribute_type
;
192 METHOD(transform_attribute_t
, clone_
, transform_attribute_t
*,
193 private_transform_attribute_t
*this)
195 private_transform_attribute_t
*new_clone
;
197 new_clone
= (private_transform_attribute_t
*)transform_attribute_create();
199 new_clone
->attribute_format
= this->attribute_format
;
200 new_clone
->attribute_type
= this->attribute_type
;
201 new_clone
->attribute_length_or_value
= this->attribute_length_or_value
;
203 if (!new_clone
->attribute_format
)
205 new_clone
->attribute_value
= chunk_clone(this->attribute_value
);
207 return &new_clone
->public;
210 METHOD2(payload_t
, transform_attribute_t
, destroy
, void,
211 private_transform_attribute_t
*this)
213 free(this->attribute_value
.ptr
);
218 * Described in header.
220 transform_attribute_t
*transform_attribute_create()
222 private_transform_attribute_t
*this;
226 .payload_interface
= {
228 .get_encoding_rules
= _get_encoding_rules
,
229 .get_length
= _get_length
,
230 .get_next_type
= _get_next_type
,
231 .set_next_type
= _set_next_type
,
232 .get_type
= _get_type
,
235 .set_value_chunk
= _set_value_chunk
,
236 .set_value
= _set_value
,
237 .get_value_chunk
= _get_value_chunk
,
238 .get_value
= _get_value
,
239 .set_attribute_type
= _set_attribute_type
,
240 .get_attribute_type
= _get_attribute_type
,
244 .attribute_format
= TRUE
,
246 return &this->public;
250 * Described in header.
252 transform_attribute_t
*transform_attribute_create_key_length(u_int16_t key_length
)
254 transform_attribute_t
*attribute
= transform_attribute_create();
255 attribute
->set_attribute_type(attribute
, KEY_LENGTH
);
256 attribute
->set_value(attribute
, key_length
);