Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/traffic_selector_substructure.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2005-2010 Martin Willi
3: * Copyright (C) 2010 revosec AG
4: * Copyright (C) 2005 Jan Hutter
5: * HSR Hochschule fuer Technik Rapperswil
6: *
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>.
11: *
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
15: * for more details.
16: */
17:
18: #include "traffic_selector_substructure.h"
19:
20: #include <encoding/payloads/encodings.h>
21: #include <collections/linked_list.h>
22:
23: typedef struct private_traffic_selector_substructure_t private_traffic_selector_substructure_t;
24:
25: /**
26: * Private data of an traffic_selector_substructure_t object.
27: */
28: struct private_traffic_selector_substructure_t {
29:
30: /**
31: * Public traffic_selector_substructure_t interface.
32: */
33: traffic_selector_substructure_t public;
34:
35: /**
36: * Type of traffic selector.
37: */
38: uint8_t ts_type;
39:
40: /**
41: * IP Protocol ID.
42: */
43: uint8_t ip_protocol_id;
44:
45: /**
46: * Length of this payload.
47: */
48: uint16_t payload_length;
49:
50: /**
51: * Start port number.
52: */
53: uint16_t start_port;
54:
55: /**
56: * End port number.
57: */
58: uint16_t end_port;
59:
60: /**
61: * Starting address.
62: */
63: chunk_t starting_address;
64:
65: /**
66: * Ending address.
67: */
68: chunk_t ending_address;
69: };
70:
71: /**
72: * Encoding rules to parse or generate a TS payload
73: *
74: * The defined offsets are the positions in a object of type
75: * private_traffic_selector_substructure_t.
76: */
77: static encoding_rule_t encodings[] = {
78: /* 1 Byte next ts type*/
79: { TS_TYPE, offsetof(private_traffic_selector_substructure_t, ts_type) },
80: /* 1 Byte IP protocol id*/
81: { U_INT_8, offsetof(private_traffic_selector_substructure_t, ip_protocol_id) },
82: /* Length of the whole payload*/
83: { PAYLOAD_LENGTH,offsetof(private_traffic_selector_substructure_t, payload_length) },
84: /* 2 Byte start port*/
85: { U_INT_16, offsetof(private_traffic_selector_substructure_t, start_port) },
86: /* 2 Byte end port*/
87: { U_INT_16, offsetof(private_traffic_selector_substructure_t, end_port) },
88: /* starting address is either 4 or 16 byte */
89: { ADDRESS, offsetof(private_traffic_selector_substructure_t, starting_address) },
90: /* ending address is either 4 or 16 byte */
91: { ADDRESS, offsetof(private_traffic_selector_substructure_t, ending_address) }
92: };
93:
94: /*
95: 1 2 3
96: 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
97: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
98: ! TS Type !IP Protocol ID*| Selector Length |
99: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
100: | Start Port* | End Port* |
101: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
102: ! !
103: ~ Starting Address* ~
104: ! !
105: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
106: ! !
107: ~ Ending Address* ~
108: ! !
109: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
110: */
111:
112: METHOD(payload_t, verify, status_t,
113: private_traffic_selector_substructure_t *this)
114: {
115: if (this->start_port > this->end_port)
116: {
117: /* OPAQUE ports are the only exception */
118: if (this->start_port != 0xffff && this->end_port != 0)
119: {
120: return FAILED;
121: }
122: }
123: switch (this->ts_type)
124: {
125: case TS_IPV4_ADDR_RANGE:
126: {
127: if ((this->starting_address.len != 4) ||
128: (this->ending_address.len != 4))
129: {
130: /* ipv4 address must be 4 bytes long */
131: return FAILED;
132: }
133: break;
134: }
135: case TS_IPV6_ADDR_RANGE:
136: {
137: if ((this->starting_address.len != 16) ||
138: (this->ending_address.len != 16))
139: {
140: /* ipv6 address must be 16 bytes long */
141: return FAILED;
142: }
143: break;
144: }
145: default:
146: {
147: /* not supported ts type */
148: return FAILED;
149: }
150: }
151:
152: return SUCCESS;
153: }
154:
155: METHOD(payload_t, get_encoding_rules, int,
156: private_traffic_selector_substructure_t *this, encoding_rule_t **rules)
157: {
158: *rules = encodings;
159: return countof(encodings);
160: }
161:
162: METHOD(payload_t, get_header_length, int,
163: private_traffic_selector_substructure_t *this)
164: {
165: return 8;
166: }
167:
168: METHOD(payload_t, get_type, payload_type_t,
169: private_traffic_selector_substructure_t *this)
170: {
171: return PLV2_TRAFFIC_SELECTOR_SUBSTRUCTURE;
172: }
173:
174: METHOD(payload_t, get_next_type, payload_type_t,
175: private_traffic_selector_substructure_t *this)
176: {
177: return PL_NONE;
178: }
179:
180: METHOD(payload_t, set_next_type, void,
181: private_traffic_selector_substructure_t *this,payload_type_t type)
182: {
183: }
184:
185: METHOD(payload_t, get_length, size_t,
186: private_traffic_selector_substructure_t *this)
187: {
188: return this->payload_length;
189: }
190:
191: METHOD(traffic_selector_substructure_t, get_traffic_selector, traffic_selector_t*,
192: private_traffic_selector_substructure_t *this)
193: {
194: return traffic_selector_create_from_bytes(
195: this->ip_protocol_id, this->ts_type,
196: this->starting_address, this->start_port,
197: this->ending_address, this->end_port);
198: }
199:
200: METHOD2(payload_t, traffic_selector_substructure_t, destroy, void,
201: private_traffic_selector_substructure_t *this)
202: {
203: free(this->starting_address.ptr);
204: free(this->ending_address.ptr);
205: free(this);
206: }
207:
208: /*
209: * Described in header
210: */
211: traffic_selector_substructure_t *traffic_selector_substructure_create()
212: {
213: private_traffic_selector_substructure_t *this;
214:
215: INIT(this,
216: .public = {
217: .payload_interface = {
218: .verify = _verify,
219: .get_encoding_rules = _get_encoding_rules,
220: .get_header_length = _get_header_length,
221: .get_length = _get_length,
222: .get_next_type = _get_next_type,
223: .set_next_type = _set_next_type,
224: .get_type = _get_type,
225: .destroy = _destroy,
226: },
227: .get_traffic_selector = _get_traffic_selector,
228: .destroy = _destroy,
229: },
230: .payload_length = get_header_length(this),
231: /* must be set to be valid */
232: .ts_type = TS_IPV4_ADDR_RANGE,
233: );
234: return &this->public;
235: }
236:
237: /*
238: * Described in header
239: */
240: traffic_selector_substructure_t *traffic_selector_substructure_create_from_traffic_selector(
241: traffic_selector_t *ts)
242: {
243: private_traffic_selector_substructure_t *this;
244:
245: this = (private_traffic_selector_substructure_t*)traffic_selector_substructure_create();
246: this->ts_type = ts->get_type(ts);
247: this->ip_protocol_id = ts->get_protocol(ts);
248: this->start_port = ts->get_from_port(ts);
249: this->end_port = ts->get_to_port(ts);
250: this->starting_address = chunk_clone(ts->get_from_address(ts));
251: this->ending_address = chunk_clone(ts->get_to_address(ts));
252: this->payload_length = get_header_length(this) +
253: this->ending_address.len + this->starting_address.len;
254:
255: return &this->public;
256: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>