IKEv1 ConfigMode: Added the payload handlers for attribute_payload and data_attribute...
[strongswan.git] / src / libcharon / encoding / payloads / data_attribute_v1.c
1
2 #include <stddef.h>
3
4 #include "data_attribute_v1.h"
5
6 #include <encoding/payloads/encodings.h>
7 #include <library.h>
8 #include <daemon.h>
9
10 typedef struct private_data_attribute_v1_t private_data_attribute_v1_t;
11
12 /**
13 * Private data of an data_attribute_v1_t object.
14 */
15 struct private_data_attribute_v1_t {
16
17 /**
18 * Public data_attribute_v1_t interface.
19 */
20 data_attribute_v1_t public;
21
22 /**
23 * Reserved bit
24 */
25 bool af_flag;
26
27 /**
28 * Type of the attribute.
29 */
30 u_int16_t type;
31
32 /**
33 * Length of the attribute.
34 */
35 u_int16_t length_or_value;
36
37 /**
38 * Attribute value as chunk.
39 */
40 chunk_t value;
41 };
42
43 /**
44 * Encoding rules to parse or generate a configuration attribute.
45 *
46 * The defined offsets are the positions in a object of type
47 * private_data_attribute_v1_t.
48 */
49 encoding_rule_t data_attribute_v1_encodings[] = {
50 /* AF Flag */
51 { FLAG, offsetof(private_data_attribute_v1_t, af_flag)},
52 /* type of the attribute as 15 bit unsigned integer */
53 { ATTRIBUTE_TYPE, offsetof(private_data_attribute_v1_t, type) },
54 /* Length of attribute value */
55 { ATTRIBUTE_LENGTH_OR_VALUE, offsetof(private_data_attribute_v1_t, length_or_value) },
56 /* Value of attribute if attribute format flag is zero */
57 { ATTRIBUTE_VALUE, offsetof(private_data_attribute_v1_t, value) }
58 };
59
60 /*
61 1 2 3
62 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
63 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
64 !R| Attribute Type ! Length |
65 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
66 | |
67 ~ Value ~
68 | |
69 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
70 */
71
72 METHOD(payload_t, verify, status_t,
73 private_data_attribute_v1_t *this)
74 {
75 bool failed = FALSE;
76
77 if (this->length_or_value != this->value.len)
78 {
79 DBG1(DBG_ENC, "invalid attribute length");
80 return FAILED;
81 }
82
83 switch (this->type)
84 {
85 case INTERNAL_IP4_ADDRESS:
86 case INTERNAL_IP4_NETMASK:
87 case INTERNAL_IP4_DNS:
88 case INTERNAL_IP4_NBNS:
89 case INTERNAL_ADDRESS_EXPIRY:
90 case INTERNAL_IP4_DHCP:
91 if (this->length_or_value != 0 && this->length_or_value != 4)
92 {
93 failed = TRUE;
94 }
95 break;
96 case INTERNAL_IP4_SUBNET:
97 if (this->length_or_value != 0 && this->length_or_value != 8)
98 {
99 failed = TRUE;
100 }
101 break;
102 case INTERNAL_IP6_ADDRESS:
103 case INTERNAL_IP6_SUBNET:
104 if (this->length_or_value != 0 && this->length_or_value != 17)
105 {
106 failed = TRUE;
107 }
108 break;
109 case INTERNAL_IP6_DNS:
110 case INTERNAL_IP6_NBNS:
111 case INTERNAL_IP6_DHCP:
112 if (this->length_or_value != 0 && this->length_or_value != 16)
113 {
114 failed = TRUE;
115 }
116 break;
117 case SUPPORTED_ATTRIBUTES:
118 if (this->length_or_value % 2)
119 {
120 failed = TRUE;
121 }
122 break;
123 case APPLICATION_VERSION:
124 /* any length acceptable */
125 break;
126 default:
127 DBG1(DBG_ENC, "unknown attribute type %N",
128 configuration_attribute_type_names, this->type);
129 break;
130 }
131
132 if (failed)
133 {
134 DBG1(DBG_ENC, "invalid attribute length %d for %N",
135 this->length_or_value, configuration_attribute_type_names, this->type);
136 return FAILED;
137 }
138 return SUCCESS;
139 }
140
141 METHOD(payload_t, get_encoding_rules, void,
142 private_data_attribute_v1_t *this, encoding_rule_t **rules,
143 size_t *rule_count)
144 {
145 *rules = data_attribute_v1_encodings;
146 *rule_count = countof(data_attribute_v1_encodings);
147 }
148
149 METHOD(payload_t, get_header_length, int,
150 private_data_attribute_v1_t *this)
151 {
152 return 4;
153 }
154
155 METHOD(payload_t, get_type, payload_type_t,
156 private_data_attribute_v1_t *this)
157 {
158 return DATA_ATTRIBUTE_V1;
159 }
160
161 METHOD(payload_t, get_next_type, payload_type_t,
162 private_data_attribute_v1_t *this)
163 {
164 return NO_PAYLOAD;
165 }
166
167 METHOD(payload_t, set_next_type, void,
168 private_data_attribute_v1_t *this, payload_type_t type)
169 {
170 }
171
172 METHOD(payload_t, get_length, size_t,
173 private_data_attribute_v1_t *this)
174 {
175 return get_header_length(this) + this->value.len;
176 }
177
178 METHOD(data_attribute_v1_t, get_dattr_type, configuration_attribute_type_t,
179 private_data_attribute_v1_t *this)
180 {
181 return this->type;
182 }
183
184 METHOD(data_attribute_v1_t, get_value, u_int16_t,
185 private_data_attribute_v1_t *this)
186 {
187 return this->length_or_value;
188 }
189
190 METHOD(data_attribute_v1_t, get_value_chunk, chunk_t,
191 private_data_attribute_v1_t *this)
192 {
193 return this->value;
194 }
195
196 METHOD2(payload_t, data_attribute_v1_t, destroy, void,
197 private_data_attribute_v1_t *this)
198 {
199 free(this->value.ptr);
200 free(this);
201 }
202
203 /*
204 * Described in header.
205 */
206 data_attribute_v1_t *data_attribute_v1_create()
207 {
208 private_data_attribute_v1_t *this;
209
210 INIT(this,
211 .public = {
212 .payload_interface = {
213 .verify = _verify,
214 .get_encoding_rules = _get_encoding_rules,
215 .get_length = _get_length,
216 .get_next_type = _get_next_type,
217 .set_next_type = _set_next_type,
218 .get_type = _get_type,
219 .destroy = _destroy,
220 },
221 .get_value_chunk = _get_value_chunk,
222 .get_type = _get_dattr_type,
223 .destroy = _destroy,
224 },
225 );
226 return &this->public;
227 }
228
229 /*
230 * Described in header.
231 */
232 data_attribute_v1_t *data_attribute_v1_create_value(
233 configuration_attribute_type_t type, chunk_t value)
234 {
235 private_data_attribute_v1_t *this;
236
237 this = (private_data_attribute_v1_t*)data_attribute_v1_create();
238 this->type = ((u_int16_t)type) & 0x7FFF;
239 this->value = chunk_clone(value);
240 this->length_or_value = value.len;
241 this->af_flag = FALSE;
242
243 return &this->public;
244 }
245
246 /*
247 * Described in header.
248 */
249 data_attribute_v1_t *data_attribute_v1_create_basic(
250 configuration_attribute_type_t type, u_int16_t value)
251 {
252 private_data_attribute_v1_t *this;
253
254 this = (private_data_attribute_v1_t*)data_attribute_v1_create();
255 this->type = ((u_int16_t)type) & 0x7FFF;
256 this->length_or_value = value;
257 this->af_flag = TRUE;
258
259 return &this->public;
260 }