testing: Start charon before Apache in tnc/tnccs-20-pdp-pt-tls
[strongswan.git] / src / libipsec / ipsec_policy.c
1 /*
2 * Copyright (C) 2012 Tobias Brunner
3 * Copyright (C) 2012 Giuliano Grassi
4 * Copyright (C) 2012 Ralf Sager
5 * 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 "ipsec_policy.h"
19
20 #include <utils/debug.h>
21
22 typedef struct private_ipsec_policy_t private_ipsec_policy_t;
23
24 /**
25 * Private additions to ipsec_policy_t.
26 */
27 struct private_ipsec_policy_t {
28
29 /**
30 * Public members
31 */
32 ipsec_policy_t public;
33
34 /**
35 * SA source address
36 */
37 host_t *src;
38
39 /**
40 * SA destination address
41 */
42 host_t *dst;
43
44 /**
45 * Source traffic selector
46 */
47 traffic_selector_t *src_ts;
48
49 /**
50 * Destination traffic selector
51 */
52 traffic_selector_t *dst_ts;
53
54 /**
55 * If any of the two TS has a protocol selector we cache it here
56 */
57 uint8_t protocol;
58
59 /**
60 * Traffic direction
61 */
62 policy_dir_t direction;
63
64 /**
65 * Policy type
66 */
67 policy_type_t type;
68
69 /**
70 * SA configuration
71 */
72 ipsec_sa_cfg_t sa;
73
74 /**
75 * Mark
76 */
77 mark_t mark;
78
79 /**
80 * Policy priority
81 */
82 policy_priority_t priority;
83
84 /**
85 * Reference counter
86 */
87 refcount_t refcount;
88
89 };
90
91 METHOD(ipsec_policy_t, match, bool,
92 private_ipsec_policy_t *this, traffic_selector_t *src_ts,
93 traffic_selector_t *dst_ts, policy_dir_t direction, uint32_t reqid,
94 mark_t mark, policy_priority_t priority)
95 {
96 return (this->direction == direction &&
97 this->priority == priority &&
98 this->sa.reqid == reqid &&
99 memeq(&this->mark, &mark, sizeof(mark_t)) &&
100 this->src_ts->equals(this->src_ts, src_ts) &&
101 this->dst_ts->equals(this->dst_ts, dst_ts));
102 }
103
104 METHOD(ipsec_policy_t, match_packet, bool,
105 private_ipsec_policy_t *this, ip_packet_t *packet)
106 {
107 uint8_t proto = packet->get_next_header(packet);
108 host_t *src = packet->get_source(packet),
109 *dst = packet->get_destination(packet);
110
111 return (!this->protocol || this->protocol == proto) &&
112 this->src_ts->includes(this->src_ts, src) &&
113 this->dst_ts->includes(this->dst_ts, dst);
114 }
115
116 METHOD(ipsec_policy_t, get_source_ts, traffic_selector_t*,
117 private_ipsec_policy_t *this)
118 {
119 return this->src_ts;
120 }
121
122 METHOD(ipsec_policy_t, get_destination_ts, traffic_selector_t*,
123 private_ipsec_policy_t *this)
124 {
125 return this->dst_ts;
126 }
127
128 METHOD(ipsec_policy_t, get_reqid, uint32_t,
129 private_ipsec_policy_t *this)
130 {
131 return this->sa.reqid;
132 }
133
134 METHOD(ipsec_policy_t, get_direction, policy_dir_t,
135 private_ipsec_policy_t *this)
136 {
137 return this->direction;
138 }
139
140 METHOD(ipsec_policy_t, get_priority, policy_priority_t,
141 private_ipsec_policy_t *this)
142 {
143 return this->priority;
144 }
145
146 METHOD(ipsec_policy_t, get_type, policy_type_t,
147 private_ipsec_policy_t *this)
148 {
149 return this->type;
150 }
151
152 METHOD(ipsec_policy_t, get_ref, ipsec_policy_t*,
153 private_ipsec_policy_t *this)
154 {
155 ref_get(&this->refcount);
156 return &this->public;
157 }
158
159 METHOD(ipsec_policy_t, destroy, void,
160 private_ipsec_policy_t *this)
161 {
162 if (ref_put(&this->refcount))
163 {
164 this->src->destroy(this->src);
165 this->dst->destroy(this->dst);
166 this->src_ts->destroy(this->src_ts);
167 this->dst_ts->destroy(this->dst_ts);
168 free(this);
169 }
170 }
171
172 /**
173 * Described in header.
174 */
175 ipsec_policy_t *ipsec_policy_create(host_t *src, host_t *dst,
176 traffic_selector_t *src_ts,
177 traffic_selector_t *dst_ts,
178 policy_dir_t direction, policy_type_t type,
179 ipsec_sa_cfg_t *sa, mark_t mark,
180 policy_priority_t priority)
181 {
182 private_ipsec_policy_t *this;
183
184 INIT(this,
185 .public = {
186 .match = _match,
187 .match_packet = _match_packet,
188 .get_source_ts = _get_source_ts,
189 .get_destination_ts = _get_destination_ts,
190 .get_direction = _get_direction,
191 .get_priority = _get_priority,
192 .get_reqid = _get_reqid,
193 .get_type = _get_type,
194 .get_ref = _get_ref,
195 .destroy = _destroy,
196 },
197 .src = src->clone(src),
198 .dst = dst->clone(dst),
199 .src_ts = src_ts->clone(src_ts),
200 .dst_ts = dst_ts->clone(dst_ts),
201 .protocol = max(src_ts->get_protocol(src_ts),
202 dst_ts->get_protocol(dst_ts)),
203 .direction = direction,
204 .type = type,
205 .sa = *sa,
206 .mark = mark,
207 .priority = priority,
208 .refcount = 1,
209 );
210
211 return &this->public;
212 }