]> git.ipfire.org Git - thirdparty/strongswan.git/blob - programs/charon/charon/encoding/payloads/traffic_selector_substructure.c
- import of strongswan-2.7.0
[thirdparty/strongswan.git] / programs / charon / charon / encoding / payloads / traffic_selector_substructure.c
1 /**
2 * @file traffic_selector_substructure.c
3 *
4 * @brief Interface of traffic_selector_substructure_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include "traffic_selector_substructure.h"
24
25 #include <encoding/payloads/encodings.h>
26 #include <utils/linked_list.h>
27
28 /**
29 * String mappings for ts_type_t.
30 */
31 mapping_t ts_type_m[] = {
32 {TS_IPV4_ADDR_RANGE, "TS_IPV4_ADDR_RANGE"},
33 {TS_IPV6_ADDR_RANGE, "TS_IPV6_ADDR_RANGE"},
34 {MAPPING_END, NULL}
35 };
36
37
38 typedef struct private_traffic_selector_substructure_t private_traffic_selector_substructure_t;
39
40 /**
41 * Private data of an traffic_selector_substructure_t object.
42 *
43 */
44 struct private_traffic_selector_substructure_t {
45 /**
46 * Public traffic_selector_substructure_t interface.
47 */
48 traffic_selector_substructure_t public;
49
50 /**
51 * Type of traffic selector.
52 */
53 u_int8_t ts_type;
54
55 /**
56 * IP Protocol ID.
57 */
58 u_int8_t ip_protocol_id;
59
60 /**
61 * Length of this payload.
62 */
63 u_int16_t payload_length;
64
65 /**
66 * Start port number.
67 */
68 u_int16_t start_port;
69
70 /**
71 * End port number.
72 */
73 u_int16_t end_port;
74
75 /**
76 * Starting address.
77 */
78 chunk_t starting_address;
79
80 /**
81 * Ending address.
82 */
83 chunk_t ending_address;
84
85 /**
86 * update length
87 */
88 void (*compute_length) (private_traffic_selector_substructure_t *this);
89 };
90
91 /**
92 * Encoding rules to parse or generate a TS payload
93 *
94 * The defined offsets are the positions in a object of type
95 * private_traffic_selector_substructure_t.
96 *
97 */
98 encoding_rule_t traffic_selector_substructure_encodings[] = {
99 /* 1 Byte next ts type*/
100 { TS_TYPE, offsetof(private_traffic_selector_substructure_t, ts_type) },
101 /* 1 Byte IP protocol id*/
102 { U_INT_8, offsetof(private_traffic_selector_substructure_t, ip_protocol_id) },
103 /* Length of the whole payload*/
104 { PAYLOAD_LENGTH, offsetof(private_traffic_selector_substructure_t, payload_length) },
105 /* 2 Byte start port*/
106 { U_INT_16, offsetof(private_traffic_selector_substructure_t, start_port) },
107 /* 2 Byte end port*/
108 { U_INT_16, offsetof(private_traffic_selector_substructure_t, end_port) },
109 /* starting address is either 4 or 16 byte */
110 { ADDRESS, offsetof(private_traffic_selector_substructure_t, starting_address) },
111 /* ending address is either 4 or 16 byte */
112 { ADDRESS, offsetof(private_traffic_selector_substructure_t, ending_address) }
113
114 };
115
116 /*
117 1 2 3
118 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
119 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
120 ! TS Type !IP Protocol ID*| Selector Length |
121 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
122 | Start Port* | End Port* |
123 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
124 ! !
125 ~ Starting Address* ~
126 ! !
127 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
128 ! !
129 ~ Ending Address* ~
130 ! !
131 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
132 */
133
134 /**
135 * Implementation of payload_t.verify.
136 */
137 static status_t verify(private_traffic_selector_substructure_t *this)
138 {
139
140 if (this->start_port > this->end_port)
141 {
142 return FAILED;
143 }
144 switch (this->ts_type)
145 {
146 case TS_IPV4_ADDR_RANGE:
147 {
148 if ((this->starting_address.len != 4) ||
149 (this->ending_address.len != 4))
150 {
151 /* ipv4 address must be 4 bytes long */
152 return FAILED;
153 }
154 break;
155 }
156 case TS_IPV6_ADDR_RANGE:
157 default:
158 {
159 /* not supported ts type */
160 return FAILED;
161 }
162 }
163
164
165 return SUCCESS;
166 }
167
168 /**
169 * Implementation of traffic_selector_substructure_t.get_encoding_rules.
170 */
171 static void get_encoding_rules(private_traffic_selector_substructure_t *this, encoding_rule_t **rules, size_t *rule_count)
172 {
173 *rules = traffic_selector_substructure_encodings;
174 *rule_count = sizeof(traffic_selector_substructure_encodings) / sizeof(encoding_rule_t);
175 }
176
177 /**
178 * Implementation of payload_t.get_type.
179 */
180 static payload_type_t get_payload_type(private_traffic_selector_substructure_t *this)
181 {
182 return TRAFFIC_SELECTOR_SUBSTRUCTURE;
183 }
184
185 /**
186 * Implementation of payload_t.get_next_type.
187 */
188 static payload_type_t get_next_type(private_traffic_selector_substructure_t *this)
189 {
190 return 0;
191 }
192
193 /**
194 * Implementation of payload_t.set_next_type.
195 */
196 static void set_next_type(private_traffic_selector_substructure_t *this,payload_type_t type)
197 {
198 }
199
200 /**
201 * Implementation of payload_t.get_length.
202 */
203 static size_t get_length(private_traffic_selector_substructure_t *this)
204 {
205 return this->payload_length;
206 }
207
208 /**
209 * Implementation of traffic_selector_substructure_t.get_ts_type.
210 */
211 static ts_type_t get_ts_type (private_traffic_selector_substructure_t *this)
212 {
213 return this->ts_type;
214 }
215
216 /**
217 * Implementation of traffic_selector_substructure_t.set_ts_type.
218 */
219 static void set_ts_type (private_traffic_selector_substructure_t *this,ts_type_t ts_type)
220 {
221 this->ts_type = ts_type;
222 }
223
224 /**
225 * Implementation of traffic_selector_substructure_t.get_protocol_id.
226 */
227 static u_int8_t get_protocol_id (private_traffic_selector_substructure_t *this)
228 {
229 return this->ip_protocol_id;
230 }
231
232 /**
233 * Implementation of traffic_selector_substructure_t.set_protocol_id.
234 */
235 static void set_protocol_id (private_traffic_selector_substructure_t *this,u_int8_t protocol_id)
236 {
237 this->ip_protocol_id = protocol_id;
238 }
239
240 /**
241 * Implementation of traffic_selector_substructure_t.get_start_host.
242 */
243 static host_t * get_start_host (private_traffic_selector_substructure_t *this)
244 {
245 return (host_create_from_chunk(AF_INET,this->starting_address, this->start_port));
246 }
247
248 /**
249 * Implementation of traffic_selector_substructure_t.set_start_host.
250 */
251 static void set_start_host (private_traffic_selector_substructure_t *this,host_t *start_host)
252 {
253 this->start_port = start_host->get_port(start_host);
254 if (this->starting_address.ptr != NULL)
255 {
256 chunk_free(&(this->starting_address));
257 }
258 this->starting_address = start_host->get_address_as_chunk(start_host);
259 this->compute_length(this);
260 }
261
262 /**
263 * Implementation of traffic_selector_substructure_t.get_end_host.
264 */
265 static host_t *get_end_host (private_traffic_selector_substructure_t *this)
266 {
267 return (host_create_from_chunk(AF_INET,this->ending_address, this->end_port));
268 }
269
270 /**
271 * Implementation of traffic_selector_substructure_t.set_end_host.
272 */
273 static void set_end_host (private_traffic_selector_substructure_t *this,host_t *end_host)
274 {
275 this->end_port = end_host->get_port(end_host);
276 if (this->ending_address.ptr != NULL)
277 {
278 chunk_free(&(this->ending_address));
279 }
280 this->ending_address = end_host->get_address_as_chunk(end_host);
281 this->compute_length(this);
282 }
283
284 /**
285 * Implementation of traffic_selector_substructure_t.get_traffic_selector.
286 */
287 static traffic_selector_t *get_traffic_selector(private_traffic_selector_substructure_t *this)
288 {
289 traffic_selector_t *ts;
290 ts = traffic_selector_create_from_bytes(this->ip_protocol_id, this->ts_type,
291 this->starting_address, this->start_port,
292 this->ending_address, this->end_port);
293 return ts;
294 }
295
296 /**
297 * Implementation of private_ts_payload_t.compute_length
298 */
299 void compute_length(private_traffic_selector_substructure_t *this)
300 {
301 this->payload_length = TRAFFIC_SELECTOR_HEADER_LENGTH + this->ending_address.len + this->starting_address.len;
302 }
303
304 /**
305 * Implementation of payload_t.destroy and traffic_selector_substructure_t.destroy.
306 */
307 static void destroy(private_traffic_selector_substructure_t *this)
308 {
309 free(this->starting_address.ptr);
310 free(this->ending_address.ptr);
311 free(this);
312 }
313
314 /*
315 * Described in header
316 */
317 traffic_selector_substructure_t *traffic_selector_substructure_create()
318 {
319 private_traffic_selector_substructure_t *this = malloc_thing(private_traffic_selector_substructure_t);
320
321 /* interface functions */
322 this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
323 this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
324 this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
325 this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
326 this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
327 this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type;
328 this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
329
330 /* public functions */
331 this->public.destroy = (void (*) (traffic_selector_substructure_t *)) destroy;
332 this->public.get_ts_type = (ts_type_t (*) (traffic_selector_substructure_t *)) get_ts_type;
333 this->public.set_ts_type = (void (*) (traffic_selector_substructure_t *,ts_type_t)) set_ts_type;
334 this->public.get_protocol_id = (u_int8_t (*) (traffic_selector_substructure_t *)) get_protocol_id;
335 this->public.set_protocol_id = (void (*) (traffic_selector_substructure_t *,u_int8_t)) set_protocol_id;
336 this->public.get_start_host = (host_t * (*) (traffic_selector_substructure_t *))get_start_host;
337 this->public.set_start_host = (void (*) (traffic_selector_substructure_t *, host_t *))set_start_host;
338 this->public.get_end_host = (host_t * (*) (traffic_selector_substructure_t *))get_end_host;
339 this->public.set_end_host = (void (*) (traffic_selector_substructure_t *, host_t *))set_end_host;
340 this->public.get_traffic_selector = (traffic_selector_t* (*)(traffic_selector_substructure_t*))get_traffic_selector;
341
342 /* private functions */
343 this->compute_length = compute_length;
344
345 /* private variables */
346 this->payload_length = TRAFFIC_SELECTOR_HEADER_LENGTH;
347 this->start_port = 0;
348 this->end_port = 0;
349 this->starting_address = CHUNK_INITIALIZER;
350 this->ending_address = CHUNK_INITIALIZER;
351 this->ip_protocol_id = 0;
352 /* must be set to be valid */
353 this->ts_type = TS_IPV4_ADDR_RANGE;
354
355 return (&(this->public));
356 }
357
358 /*
359 * Described in header
360 */
361 traffic_selector_substructure_t *traffic_selector_substructure_create_from_traffic_selector(traffic_selector_t *traffic_selector)
362 {
363 private_traffic_selector_substructure_t *this = (private_traffic_selector_substructure_t*)traffic_selector_substructure_create();
364 this->ts_type = traffic_selector->get_type(traffic_selector);
365 this->ip_protocol_id = traffic_selector->get_protocol(traffic_selector);
366 this->start_port = traffic_selector->get_from_port(traffic_selector);
367 this->end_port = traffic_selector->get_to_port(traffic_selector);
368 this->starting_address = traffic_selector->get_from_address(traffic_selector);
369 this->ending_address = traffic_selector->get_to_address(traffic_selector);
370
371 this->compute_length(this);
372
373 return &(this->public);
374 }