2 * @file traffic_selector_substructure.c
4 * @brief Interface of traffic_selector_substructure_t.
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
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>.
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
23 #include "traffic_selector_substructure.h"
25 #include <encoding/payloads/encodings.h>
26 #include <utils/linked_list.h>
29 * String mappings for ts_type_t.
31 mapping_t ts_type_m
[] = {
32 {TS_IPV4_ADDR_RANGE
, "TS_IPV4_ADDR_RANGE"},
33 {TS_IPV6_ADDR_RANGE
, "TS_IPV6_ADDR_RANGE"},
38 typedef struct private_traffic_selector_substructure_t private_traffic_selector_substructure_t
;
41 * Private data of an traffic_selector_substructure_t object.
44 struct private_traffic_selector_substructure_t
{
46 * Public traffic_selector_substructure_t interface.
48 traffic_selector_substructure_t
public;
51 * Type of traffic selector.
58 u_int8_t ip_protocol_id
;
61 * Length of this payload.
63 u_int16_t payload_length
;
78 chunk_t starting_address
;
83 chunk_t ending_address
;
88 void (*compute_length
) (private_traffic_selector_substructure_t
*this);
92 * Encoding rules to parse or generate a TS payload
94 * The defined offsets are the positions in a object of type
95 * private_traffic_selector_substructure_t.
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
) },
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
) }
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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
125 ~ Starting Address* ~
127 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
131 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
135 * Implementation of payload_t.verify.
137 static status_t
verify(private_traffic_selector_substructure_t
*this)
140 if (this->start_port
> this->end_port
)
144 switch (this->ts_type
)
146 case TS_IPV4_ADDR_RANGE
:
148 if ((this->starting_address
.len
!= 4) ||
149 (this->ending_address
.len
!= 4))
151 /* ipv4 address must be 4 bytes long */
156 case TS_IPV6_ADDR_RANGE
:
159 /* not supported ts type */
169 * Implementation of traffic_selector_substructure_t.get_encoding_rules.
171 static void get_encoding_rules(private_traffic_selector_substructure_t
*this, encoding_rule_t
**rules
, size_t *rule_count
)
173 *rules
= traffic_selector_substructure_encodings
;
174 *rule_count
= sizeof(traffic_selector_substructure_encodings
) / sizeof(encoding_rule_t
);
178 * Implementation of payload_t.get_type.
180 static payload_type_t
get_payload_type(private_traffic_selector_substructure_t
*this)
182 return TRAFFIC_SELECTOR_SUBSTRUCTURE
;
186 * Implementation of payload_t.get_next_type.
188 static payload_type_t
get_next_type(private_traffic_selector_substructure_t
*this)
194 * Implementation of payload_t.set_next_type.
196 static void set_next_type(private_traffic_selector_substructure_t
*this,payload_type_t type
)
201 * Implementation of payload_t.get_length.
203 static size_t get_length(private_traffic_selector_substructure_t
*this)
205 return this->payload_length
;
209 * Implementation of traffic_selector_substructure_t.get_ts_type.
211 static ts_type_t
get_ts_type (private_traffic_selector_substructure_t
*this)
213 return this->ts_type
;
217 * Implementation of traffic_selector_substructure_t.set_ts_type.
219 static void set_ts_type (private_traffic_selector_substructure_t
*this,ts_type_t ts_type
)
221 this->ts_type
= ts_type
;
225 * Implementation of traffic_selector_substructure_t.get_protocol_id.
227 static u_int8_t
get_protocol_id (private_traffic_selector_substructure_t
*this)
229 return this->ip_protocol_id
;
233 * Implementation of traffic_selector_substructure_t.set_protocol_id.
235 static void set_protocol_id (private_traffic_selector_substructure_t
*this,u_int8_t protocol_id
)
237 this->ip_protocol_id
= protocol_id
;
241 * Implementation of traffic_selector_substructure_t.get_start_host.
243 static host_t
* get_start_host (private_traffic_selector_substructure_t
*this)
245 return (host_create_from_chunk(AF_INET
,this->starting_address
, this->start_port
));
249 * Implementation of traffic_selector_substructure_t.set_start_host.
251 static void set_start_host (private_traffic_selector_substructure_t
*this,host_t
*start_host
)
253 this->start_port
= start_host
->get_port(start_host
);
254 if (this->starting_address
.ptr
!= NULL
)
256 chunk_free(&(this->starting_address
));
258 this->starting_address
= start_host
->get_address_as_chunk(start_host
);
259 this->compute_length(this);
263 * Implementation of traffic_selector_substructure_t.get_end_host.
265 static host_t
*get_end_host (private_traffic_selector_substructure_t
*this)
267 return (host_create_from_chunk(AF_INET
,this->ending_address
, this->end_port
));
271 * Implementation of traffic_selector_substructure_t.set_end_host.
273 static void set_end_host (private_traffic_selector_substructure_t
*this,host_t
*end_host
)
275 this->end_port
= end_host
->get_port(end_host
);
276 if (this->ending_address
.ptr
!= NULL
)
278 chunk_free(&(this->ending_address
));
280 this->ending_address
= end_host
->get_address_as_chunk(end_host
);
281 this->compute_length(this);
285 * Implementation of traffic_selector_substructure_t.get_traffic_selector.
287 static traffic_selector_t
*get_traffic_selector(private_traffic_selector_substructure_t
*this)
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
);
297 * Implementation of private_ts_payload_t.compute_length
299 void compute_length(private_traffic_selector_substructure_t
*this)
301 this->payload_length
= TRAFFIC_SELECTOR_HEADER_LENGTH
+ this->ending_address
.len
+ this->starting_address
.len
;
305 * Implementation of payload_t.destroy and traffic_selector_substructure_t.destroy.
307 static void destroy(private_traffic_selector_substructure_t
*this)
309 free(this->starting_address
.ptr
);
310 free(this->ending_address
.ptr
);
315 * Described in header
317 traffic_selector_substructure_t
*traffic_selector_substructure_create()
319 private_traffic_selector_substructure_t
*this = malloc_thing(private_traffic_selector_substructure_t
);
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
;
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
;
342 /* private functions */
343 this->compute_length
= compute_length
;
345 /* private variables */
346 this->payload_length
= TRAFFIC_SELECTOR_HEADER_LENGTH
;
347 this->start_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
;
355 return (&(this->public));
359 * Described in header
361 traffic_selector_substructure_t
*traffic_selector_substructure_create_from_traffic_selector(traffic_selector_t
*traffic_selector
)
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
);
371 this->compute_length(this);
373 return &(this->public);