2 * Copyright (C) 2012 Tobias Brunner
3 * Copyright (C) 2012 Giuliano Grassi
4 * Copyright (C) 2012 Ralf Sager
5 * Hochschule fuer Technik Rapperswil
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>.
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
18 #include "ipsec_policy.h"
20 #include <utils/debug.h>
22 typedef struct private_ipsec_policy_t private_ipsec_policy_t
;
25 * Private additions to ipsec_policy_t.
27 struct private_ipsec_policy_t
{
32 ipsec_policy_t
public;
40 * SA destination address
45 * Source traffic selector
47 traffic_selector_t
*src_ts
;
50 * Destination traffic selector
52 traffic_selector_t
*dst_ts
;
55 * If any of the two TS has a protocol selector we cache it here
62 policy_dir_t direction
;
82 policy_priority_t priority
;
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
)
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
));
105 * Match the port of the given host against the given traffic selector.
107 static inline bool match_port(traffic_selector_t
*ts
, host_t
*host
)
109 uint16_t from
, to
, port
;
111 from
= ts
->get_from_port(ts
);
112 to
= ts
->get_to_port(ts
);
113 if ((from
== 0 && to
== 0xffff) ||
114 (from
== 0xffff && to
== 0))
118 port
= host
->get_port(host
);
119 return from
<= port
&& port
<= to
;
122 METHOD(ipsec_policy_t
, match_packet
, bool,
123 private_ipsec_policy_t
*this, ip_packet_t
*packet
)
125 uint8_t proto
= packet
->get_next_header(packet
);
126 host_t
*src
= packet
->get_source(packet
),
127 *dst
= packet
->get_destination(packet
);
129 return (!this->protocol
|| this->protocol
== proto
) &&
130 this->src_ts
->includes(this->src_ts
, src
) &&
131 match_port(this->src_ts
, src
) &&
132 this->dst_ts
->includes(this->dst_ts
, dst
) &&
133 match_port(this->dst_ts
, dst
);
136 METHOD(ipsec_policy_t
, get_source_ts
, traffic_selector_t
*,
137 private_ipsec_policy_t
*this)
142 METHOD(ipsec_policy_t
, get_destination_ts
, traffic_selector_t
*,
143 private_ipsec_policy_t
*this)
148 METHOD(ipsec_policy_t
, get_reqid
, uint32_t,
149 private_ipsec_policy_t
*this)
151 return this->sa
.reqid
;
154 METHOD(ipsec_policy_t
, get_direction
, policy_dir_t
,
155 private_ipsec_policy_t
*this)
157 return this->direction
;
160 METHOD(ipsec_policy_t
, get_priority
, policy_priority_t
,
161 private_ipsec_policy_t
*this)
163 return this->priority
;
166 METHOD(ipsec_policy_t
, get_type
, policy_type_t
,
167 private_ipsec_policy_t
*this)
172 METHOD(ipsec_policy_t
, get_ref
, ipsec_policy_t
*,
173 private_ipsec_policy_t
*this)
175 ref_get(&this->refcount
);
176 return &this->public;
179 METHOD(ipsec_policy_t
, destroy
, void,
180 private_ipsec_policy_t
*this)
182 if (ref_put(&this->refcount
))
184 this->src
->destroy(this->src
);
185 this->dst
->destroy(this->dst
);
186 this->src_ts
->destroy(this->src_ts
);
187 this->dst_ts
->destroy(this->dst_ts
);
193 * Described in header.
195 ipsec_policy_t
*ipsec_policy_create(host_t
*src
, host_t
*dst
,
196 traffic_selector_t
*src_ts
,
197 traffic_selector_t
*dst_ts
,
198 policy_dir_t direction
, policy_type_t type
,
199 ipsec_sa_cfg_t
*sa
, mark_t mark
,
200 policy_priority_t priority
)
202 private_ipsec_policy_t
*this;
207 .match_packet
= _match_packet
,
208 .get_source_ts
= _get_source_ts
,
209 .get_destination_ts
= _get_destination_ts
,
210 .get_direction
= _get_direction
,
211 .get_priority
= _get_priority
,
212 .get_reqid
= _get_reqid
,
213 .get_type
= _get_type
,
217 .src
= src
->clone(src
),
218 .dst
= dst
->clone(dst
),
219 .src_ts
= src_ts
->clone(src_ts
),
220 .dst_ts
= dst_ts
->clone(dst_ts
),
221 .protocol
= max(src_ts
->get_protocol(src_ts
),
222 dst_ts
->get_protocol(dst_ts
)),
223 .direction
= direction
,
227 .priority
= priority
,
231 return &this->public;