aboutsummaryrefslogtreecommitdiffstats
path: root/src/pluto/kernel.h
blob: 01a455941b7904f076e80addfeec4694c51b42b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/* declarations of routines that interface with the kernel's IPsec mechanism
 * Copyright (C) 1998-2001  D. Hugh Redelmeier.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * RCSID $Id$
 */

#include "connections.h"

extern bool no_klips;   /* don't actually use KLIPS */
extern bool can_do_IPcomp;  /* can system actually perform IPCOMP? */

#ifdef KLIPS
/* Declare eroute things early enough for uses.
 *
 * Flags are encoded above the low-order byte of verbs.
 * "real" eroutes are only outbound.  Inbound eroutes don't exist,
 * but an addflow with an INBOUND flag allows IPIP tunnels to be
 * limited to appropriate source and destination addresses.
 */

#define ERO_MASK        0xFF
#define ERO_FLAG_SHIFT  8

#define ERO_DELETE      SADB_X_DELFLOW
#define ERO_ADD SADB_X_ADDFLOW
#define ERO_REPLACE     (SADB_X_ADDFLOW | (SADB_X_SAFLAGS_REPLACEFLOW << ERO_FLAG_SHIFT))
#define ERO_ADD_INBOUND (SADB_X_ADDFLOW | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
#define ERO_DEL_INBOUND (SADB_X_DELFLOW | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))

struct pfkey_proto_info {
		int proto;
		int encapsulation;
		unsigned reqid;
};
struct sadb_msg;

struct kernel_sa {
		const ip_address *src;
		const ip_address *dst;

		const ip_subnet *src_client;
		const ip_subnet *dst_client;

		ipsec_spi_t spi;
		unsigned proto;
		unsigned satype;
		unsigned transport_proto;
		unsigned replay_window;
		unsigned reqid;

		unsigned authalg;
		unsigned authkeylen;
		char *authkey;

		unsigned encalg;
		unsigned enckeylen;
		char *enckey;

		unsigned compalg;

		int encapsulation;

		u_int16_t natt_sport, natt_dport;
		u_int8_t transid, natt_type;
		ip_address *natt_oa;

		const char *text_said;
};

struct kernel_ops {
		enum {
				KERNEL_TYPE_NONE,
				KERNEL_TYPE_KLIPS,
				KERNEL_TYPE_LINUX,
		} type;
		bool inbound_eroute;
		bool policy_lifetime;
		int *async_fdp;

		void (*init)(void);
		void (*pfkey_register)(void);
		void (*pfkey_register_response)(const struct sadb_msg *msg);
		void (*process_queue)(void);
		void (*process_msg)(void);
		bool (*raw_eroute)(const ip_address *this_host,
						   const ip_subnet *this_client,
						   const ip_address *that_host,
						   const ip_subnet *that_client,
						   ipsec_spi_t spi,
						   unsigned int satype,
						   unsigned int transport_proto,
						   const struct pfkey_proto_info *proto_info,
						   time_t use_lifetime,
						   unsigned int op,
						   const char *text_said);
		bool (*get_policy)(const struct kernel_sa *sa, bool inbound,
						   time_t *use_time);
		bool (*add_sa)(const struct kernel_sa *sa, bool replace);
		bool (*grp_sa)(const struct kernel_sa *sa_outer,
					   const struct kernel_sa *sa_inner);
		bool (*del_sa)(const struct kernel_sa *sa);
		bool (*get_sa)(const struct kernel_sa *sa, u_int *bytes);
		ipsec_spi_t (*get_spi)(const ip_address *src,
							   const ip_address *dst,
							   int proto,
							   bool tunnel_mode,
							   unsigned reqid,
							   ipsec_spi_t min,
							   ipsec_spi_t max,
							   const char *text_said);
};


extern const struct kernel_ops *kernel_ops;

/* information from /proc/net/ipsec_eroute */

struct eroute_info {
	unsigned long count;
	ip_subnet ours;
	ip_subnet his;
	ip_address dst;
	ip_said     said;
	int transport_proto;
	struct eroute_info *next;
};

extern struct eroute_info *orphaned_holds;

extern void show_shunt_status(void);
#endif

/* A netlink header defines EM_MAXRELSPIS, the max number of SAs in a group.
 * Is there a PF_KEY equivalent?
 */
#ifndef EM_MAXRELSPIS
# define EM_MAXRELSPIS 4        /* AH ESP IPCOMP IPIP */
#endif

extern void record_and_initiate_opportunistic(const ip_subnet *
											  , const ip_subnet *
											  , int transport_proto
											  , const char *why);

extern void init_kernel(void);

extern void scan_proc_shunts(void);

extern bool trap_connection(struct connection *c);
extern void unroute_connection(struct connection *c);

extern bool has_bare_hold(const ip_address *src, const ip_address *dst
						  , int transport_proto);

extern bool replace_bare_shunt(const ip_address *src, const ip_address *dst
							   , policy_prio_t policy_prio
							   , ipsec_spi_t shunt_spi  /* in host order! */
							   , bool repl
							   , unsigned int transport_proto
							   , const char *why);

extern bool assign_hold(struct connection *c
						, struct spd_route *sr
						, int transport_proto
						, const ip_address *src, const ip_address *dst);

extern ipsec_spi_t shunt_policy_spi(struct connection *c, bool prospective);


struct state;   /* forward declaration of tag */
extern ipsec_spi_t get_ipsec_spi(ipsec_spi_t avoid
								 , int proto
								 , struct spd_route *sr
								 , bool tunnel_mode);
extern ipsec_spi_t get_my_cpi(struct spd_route *sr, bool tunnel_mode);

extern bool install_inbound_ipsec_sa(struct state *st);
extern bool install_ipsec_sa(struct state *st, bool inbound_also);
extern void delete_ipsec_sa(struct state *st, bool inbound_only);
extern bool route_and_eroute(struct connection *c
							 , struct spd_route *sr
							 , struct state *st);
extern bool was_eroute_idle(struct state *st, time_t idle_max
	, time_t *idle_time);
extern bool get_sa_info(struct state *st, bool inbound, u_int *bytes
	, time_t *use_time);

extern bool update_ipsec_sa(struct state *st);