/src/strongswan/src/libstrongswan/selectors/traffic_selector.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2007-2017 Tobias Brunner |
3 | | * Copyright (C) 2005-2006 Martin Willi |
4 | | * Copyright (C) 2005 Jan Hutter |
5 | | * |
6 | | * Copyright (C) secunet Security Networks AG |
7 | | * |
8 | | * This program is free software; you can redistribute it and/or modify it |
9 | | * under the terms of the GNU General Public License as published by the |
10 | | * Free Software Foundation; either version 2 of the License, or (at your |
11 | | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. |
12 | | * |
13 | | * This program is distributed in the hope that it will be useful, but |
14 | | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
15 | | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
16 | | * for more details. |
17 | | */ |
18 | | |
19 | | /** |
20 | | * @defgroup traffic_selector traffic_selector |
21 | | * @{ @ingroup selectors |
22 | | */ |
23 | | |
24 | | #ifndef TRAFFIC_SELECTOR_H_ |
25 | | #define TRAFFIC_SELECTOR_H_ |
26 | | |
27 | | typedef enum ts_type_t ts_type_t; |
28 | | typedef struct traffic_selector_t traffic_selector_t; |
29 | | |
30 | | #include <library.h> |
31 | | #include <networking/host.h> |
32 | | |
33 | | /** |
34 | | * Traffic selector types. |
35 | | */ |
36 | | enum ts_type_t { |
37 | | |
38 | | /** |
39 | | * A range of IPv4 addresses, represented by two four (4) octet |
40 | | * values. The first value is the beginning IPv4 address |
41 | | * (inclusive) and the second value is the ending IPv4 address |
42 | | * (inclusive). All addresses falling between the two specified |
43 | | * addresses are considered to be within the list. |
44 | | */ |
45 | | TS_IPV4_ADDR_RANGE = 7, |
46 | | |
47 | | /** |
48 | | * A range of IPv6 addresses, represented by two sixteen (16) |
49 | | * octet values. The first value is the beginning IPv6 address |
50 | | * (inclusive) and the second value is the ending IPv6 address |
51 | | * (inclusive). All addresses falling between the two specified |
52 | | * addresses are considered to be within the list. |
53 | | */ |
54 | | TS_IPV6_ADDR_RANGE = 8, |
55 | | |
56 | | /** |
57 | | * A security label. |
58 | | */ |
59 | | TS_SECLABEL = 10, |
60 | | }; |
61 | | |
62 | | /** |
63 | | * enum names for ts_type_t |
64 | | */ |
65 | | extern enum_name_t *ts_type_name; |
66 | | |
67 | | /** |
68 | | * Object representing a traffic selector entry. |
69 | | * |
70 | | * A traffic selector defines an range of addresses |
71 | | * and a range of ports. |
72 | | * |
73 | | * If the protocol is ICMP or ICMPv6 the ICMP type and code are stored in the |
74 | | * port field as follows: The message type is placed in the most significant |
75 | | * 8 bits and the code in the least significant 8 bits. Utility functions are |
76 | | * provided to extract the individual values. |
77 | | */ |
78 | | struct traffic_selector_t { |
79 | | |
80 | | /** |
81 | | * Compare two traffic selectors, and create a new one |
82 | | * which is the largest subset of both (subnet & port). |
83 | | * |
84 | | * Resulting traffic_selector is newly created and must be destroyed. |
85 | | * |
86 | | * @param other traffic selector to compare |
87 | | * @return |
88 | | * - created subset of them |
89 | | * - or NULL if no match between this and other |
90 | | */ |
91 | | traffic_selector_t *(*get_subset)(traffic_selector_t *this, |
92 | | traffic_selector_t *other); |
93 | | |
94 | | /** |
95 | | * Clone a traffic selector. |
96 | | * |
97 | | * @return clone of it |
98 | | */ |
99 | | traffic_selector_t *(*clone)(traffic_selector_t *this); |
100 | | |
101 | | /** |
102 | | * Get starting address of this ts as a chunk. |
103 | | * |
104 | | * Chunk is in network order and points to internal data. |
105 | | * |
106 | | * @return chunk containing the address |
107 | | */ |
108 | | chunk_t (*get_from_address)(traffic_selector_t *this); |
109 | | |
110 | | /** |
111 | | * Get ending address of this ts as a chunk. |
112 | | * |
113 | | * Chunk is in network order and points to internal data. |
114 | | * |
115 | | * @return chunk containing the address |
116 | | */ |
117 | | chunk_t (*get_to_address)(traffic_selector_t *this); |
118 | | |
119 | | /** |
120 | | * Get starting port of this ts. |
121 | | * |
122 | | * Port is in host order, since the parser converts it. |
123 | | * |
124 | | * If the protocol is ICMP/ICMPv6 the ICMP type and code are stored in this |
125 | | * field as follows: The message type is placed in the most significant |
126 | | * 8 bits and the code in the least significant 8 bits. Use the utility |
127 | | * functions to extract them. |
128 | | * |
129 | | * @return port |
130 | | */ |
131 | | uint16_t (*get_from_port)(traffic_selector_t *this); |
132 | | |
133 | | /** |
134 | | * Get ending port of this ts. |
135 | | * |
136 | | * Port is in host order, since the parser converts it. |
137 | | * |
138 | | * If the protocol is ICMP/ICMPv6 the ICMP type and code are stored in this |
139 | | * field as follows: The message type is placed in the most significant |
140 | | * 8 bits and the code in the least significant 8 bits. Use the utility |
141 | | * functions to extract them. |
142 | | * |
143 | | * @return port |
144 | | */ |
145 | | uint16_t (*get_to_port)(traffic_selector_t *this); |
146 | | |
147 | | /** |
148 | | * Get the type of the traffic selector. |
149 | | * |
150 | | * @return ts_type_t specifying the type |
151 | | */ |
152 | | ts_type_t (*get_type)(traffic_selector_t *this); |
153 | | |
154 | | /** |
155 | | * Get the protocol id of this ts. |
156 | | * |
157 | | * @return protocol id |
158 | | */ |
159 | | uint8_t (*get_protocol)(traffic_selector_t *this); |
160 | | |
161 | | /** |
162 | | * Check if the traffic selector is for a single host. |
163 | | * |
164 | | * Traffic selector may describe the end of *-to-host tunnel. In this |
165 | | * case, the address range is a single address equal to the hosts |
166 | | * peer address. |
167 | | * |
168 | | * If host is specified, the traffic selector must equal that specific |
169 | | * IP address. If it is not specified, TRUE is also returned for dynamic |
170 | | * traffic selectors. |
171 | | * |
172 | | * @param host IP address to check for, or NULL |
173 | | * @return TRUE if TS is for a single host |
174 | | */ |
175 | | bool (*is_host)(traffic_selector_t *this, host_t* host); |
176 | | |
177 | | /** |
178 | | * Check if this traffic selector was created by |
179 | | * traffic_selector_create_dynamic() but no address has yet been set with |
180 | | * set_address(). |
181 | | * |
182 | | * @return TRUE if TS is dynamic |
183 | | */ |
184 | | bool (*is_dynamic)(traffic_selector_t *this); |
185 | | |
186 | | /** |
187 | | * Set the traffic selector to the given IP address. |
188 | | * |
189 | | * If host is %any or %any6 the traffic selector gets set to 0.0.0.0/0 or |
190 | | * ::/0, respectively. |
191 | | * |
192 | | * Checking is_host(), is_dynamic() or includes() might be appropriate |
193 | | * before calling this. |
194 | | * |
195 | | * is_dynamic() will return FALSE after calling this. |
196 | | * |
197 | | * @param host target IP address |
198 | | */ |
199 | | void (*set_address)(traffic_selector_t *this, host_t* host); |
200 | | |
201 | | /** |
202 | | * Compare two traffic selectors for equality. |
203 | | * |
204 | | * @param other ts to compare with this |
205 | | * @return TRUE if equal, FALSE otherwise |
206 | | */ |
207 | | bool (*equals)(traffic_selector_t *this, traffic_selector_t *other); |
208 | | |
209 | | /** |
210 | | * Check if a traffic selector is contained completely in another. |
211 | | * |
212 | | * contains() allows to check if multiple traffic selectors are redundant. |
213 | | * |
214 | | * @param other ts that contains this |
215 | | * @return TRUE if other contains this completely, FALSE otherwise |
216 | | */ |
217 | | bool (*is_contained_in)(traffic_selector_t *this, traffic_selector_t *other); |
218 | | |
219 | | /** |
220 | | * Check if a specific host is included in the address range of |
221 | | * this traffic selector. |
222 | | * |
223 | | * @param host the host to check |
224 | | */ |
225 | | bool (*includes)(traffic_selector_t *this, host_t *host); |
226 | | |
227 | | /** |
228 | | * Convert a traffic selector address range to a subnet |
229 | | * and its net mask. |
230 | | * If from and to ports of this traffic selector are equal, |
231 | | * the port of the returned host_t is set to that port. |
232 | | * |
233 | | * @param net converted subnet (has to be freed) |
234 | | * @param mask converted net mask |
235 | | * @return TRUE if traffic selector matches exactly to the subnet |
236 | | */ |
237 | | bool (*to_subnet)(traffic_selector_t *this, host_t **net, uint8_t *mask); |
238 | | |
239 | | /** |
240 | | * Create a hash value for the traffic selector. |
241 | | * |
242 | | * @param inc optional value for incremental hashing |
243 | | * @return calculated hash value for the traffic selector |
244 | | */ |
245 | | u_int (*hash)(traffic_selector_t *this, u_int inc); |
246 | | |
247 | | /** |
248 | | * Destroys the ts object |
249 | | */ |
250 | | void (*destroy)(traffic_selector_t *this); |
251 | | }; |
252 | | |
253 | | /** |
254 | | * Extract the ICMP/ICMPv6 message type from a port in host order |
255 | | * |
256 | | * @param port port number in host order |
257 | | * @return ICMP/ICMPv6 message type |
258 | | */ |
259 | | static inline uint8_t traffic_selector_icmp_type(uint16_t port) |
260 | 0 | { |
261 | 0 | return port >> 8; |
262 | 0 | } Unexecuted instantiation: library.c:traffic_selector_icmp_type Unexecuted instantiation: traffic_selector.c:traffic_selector_icmp_type |
263 | | |
264 | | /** |
265 | | * Extract the ICMP/ICMPv6 message code from a port in host order |
266 | | * |
267 | | * @param port port number in host order |
268 | | * @return ICMP/ICMPv6 message code |
269 | | */ |
270 | | static inline uint8_t traffic_selector_icmp_code(uint16_t port) |
271 | 0 | { |
272 | 0 | return port & 0xff; |
273 | 0 | } Unexecuted instantiation: library.c:traffic_selector_icmp_code Unexecuted instantiation: traffic_selector.c:traffic_selector_icmp_code |
274 | | |
275 | | /** |
276 | | * Compare two traffic selectors, usable as sort function |
277 | | * |
278 | | * @param a first selector to compare |
279 | | * @param b second selector to compare |
280 | | * @param opts optional sort options, currently unused |
281 | | * @return > 0 if a > b, 0 if a == b, < 0 if a < b |
282 | | */ |
283 | | int traffic_selector_cmp(traffic_selector_t *a, traffic_selector_t *b, |
284 | | void *opts); |
285 | | |
286 | | /** |
287 | | * Create a new traffic selector using human readable params. |
288 | | * |
289 | | * If protocol is ICMP or ICMPv6 the ports are interpreted as follows: If they |
290 | | * are less than 256 the value is assumed to be a message type, if they are |
291 | | * greater or equal to 256 they are assumed to be type and code as defined |
292 | | * for traffic_selector_t. |
293 | | * |
294 | | * @param protocol protocol for this ts, such as TCP or UDP |
295 | | * @param type type of following addresses, such as TS_IPV4_ADDR_RANGE |
296 | | * @param from_addr start of address range as string |
297 | | * @param from_port port number in host order |
298 | | * @param to_addr end of address range as string |
299 | | * @param to_port port number in host order |
300 | | * @return |
301 | | * - traffic_selector_t object |
302 | | * - NULL if invalid address strings/protocol |
303 | | */ |
304 | | traffic_selector_t *traffic_selector_create_from_string( |
305 | | uint8_t protocol, ts_type_t type, |
306 | | char *from_addr, uint16_t from_port, |
307 | | char *to_addr, uint16_t to_port); |
308 | | |
309 | | |
310 | | |
311 | | /** |
312 | | * Create a traffic selector from a CIDR string. |
313 | | * |
314 | | * If protocol is ICMP or ICMPv6 the ports are interpreted as follows: If they |
315 | | * are less than 256 the value is assumed to be a message type, if they are |
316 | | * greater or equal to 256 they are assumed to be type and code as defined |
317 | | * for traffic_selector_t. |
318 | | * |
319 | | * @param string CIDR string, such as 10.1.0.0/16 |
320 | | * @param protocol protocol for this ts, such as TCP or UDP |
321 | | * @param from_port start of allowed port range |
322 | | * @param to_port end of port range |
323 | | * @return traffic selector, NULL if string invalid |
324 | | */ |
325 | | traffic_selector_t *traffic_selector_create_from_cidr( |
326 | | char *string, uint8_t protocol, |
327 | | uint16_t from_port, uint16_t to_port); |
328 | | |
329 | | /** |
330 | | * Create a new traffic selector using data read from the net. |
331 | | * |
332 | | * There exists a mix of network and host order in the params. |
333 | | * But the parser gives us this data in this format, so we |
334 | | * don't have to convert twice. |
335 | | * |
336 | | * If protocol is ICMP or ICMPv6 the ports are interpreted as follows: If they |
337 | | * are less than 256 the value is assumed to be a message type, if they are |
338 | | * greater or equal to 256 they are assumed to be type and code as defined |
339 | | * for traffic_selector_t. |
340 | | * |
341 | | * @param protocol protocol for this ts, such as TCP or UDP |
342 | | * @param type type of following addresses, such as TS_IPV4_ADDR_RANGE |
343 | | * @param from_address start of address range, network order |
344 | | * @param from_port port number, host order |
345 | | * @param to_address end of address range, network order |
346 | | * @param to_port port number, host order |
347 | | * @return traffic_selector_t object |
348 | | */ |
349 | | traffic_selector_t *traffic_selector_create_from_bytes( |
350 | | uint8_t protocol, ts_type_t type, |
351 | | chunk_t from_address, uint16_t from_port, |
352 | | chunk_t to_address, uint16_t to_port); |
353 | | |
354 | | /** |
355 | | * Create a new traffic selector using the RFC 3779 ASN.1 min/max address format |
356 | | * |
357 | | * @param type type of following addresses, such as TS_IPV4_ADDR_RANGE |
358 | | * @param from_addr start of address range in RFC 3779 ASN.1 BIT STRING format |
359 | | * @param to_addr end of address range in RFC 3779 ASN.1 BIT STRING format |
360 | | * @return traffic_selector_t object |
361 | | */ |
362 | | traffic_selector_t *traffic_selector_create_from_rfc3779_format(ts_type_t type, |
363 | | chunk_t from_addr, chunk_t to_addr); |
364 | | |
365 | | /** |
366 | | * Create a new traffic selector defining a whole subnet. |
367 | | * |
368 | | * In most cases, definition of a traffic selector for full subnets |
369 | | * is sufficient. This constructor creates a traffic selector for |
370 | | * all protocols, all ports and the address range specified by the |
371 | | * subnet. |
372 | | * Additionally, a protocol and ports may be specified. |
373 | | * |
374 | | * If protocol is ICMP or ICMPv6 the ports are interpreted as follows: If they |
375 | | * are less than 256 the value is assumed to be a message type, if they are |
376 | | * greater or equal to 256 they are assumed to be type and code as defined |
377 | | * for traffic_selector_t. |
378 | | * |
379 | | * @param net subnet to use |
380 | | * @param netbits size of the subnet, as used in e.g. 192.168.0.0/24 notation |
381 | | * @param protocol protocol for this ts, such as TCP or UDP |
382 | | * @param from_port start of allowed port range |
383 | | * @param to_port end of port range |
384 | | * @return |
385 | | * - traffic_selector_t object |
386 | | * - NULL if address family of net not supported |
387 | | */ |
388 | | traffic_selector_t *traffic_selector_create_from_subnet( |
389 | | host_t *net, uint8_t netbits, uint8_t protocol, |
390 | | uint16_t from_port, uint16_t to_port); |
391 | | |
392 | | /** |
393 | | * Create a traffic selector for host-to-host cases. |
394 | | * |
395 | | * For host2host or virtual IP setups, the traffic selectors gets |
396 | | * created at runtime using the external/virtual IP. Using this constructor, |
397 | | * a call to set_address() sets this traffic selector to the supplied host. |
398 | | * |
399 | | * If protocol is ICMP or ICMPv6 the ports are interpreted as follows: If they |
400 | | * are less than 256 the value is assumed to be a message type, if they are |
401 | | * greater or equal to 256 they are assumed to be type and code as defined |
402 | | * for traffic_selector_t. |
403 | | * |
404 | | * @param protocol upper layer protocol to allow |
405 | | * @param from_port start of allowed port range |
406 | | * @param to_port end of range |
407 | | * @return |
408 | | * - traffic_selector_t object |
409 | | * - NULL if type not supported |
410 | | */ |
411 | | traffic_selector_t *traffic_selector_create_dynamic(uint8_t protocol, |
412 | | uint16_t from_port, uint16_t to_port); |
413 | | |
414 | | /** |
415 | | * printf hook function for traffic_selector_t. |
416 | | * |
417 | | * Arguments are: |
418 | | * traffic_selector_t *ts |
419 | | * With the #-specifier, arguments are: |
420 | | * linked_list_t *list containing traffic_selector_t* |
421 | | */ |
422 | | int traffic_selector_printf_hook(printf_hook_data_t *data, |
423 | | printf_hook_spec_t *spec, const void *const *args); |
424 | | |
425 | | #endif /** TRAFFIC_SELECTOR_H_ @}*/ |