xref: /openbsd-src/sbin/ipsecctl/pfkey.c (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
1 /*	$OpenBSD: pfkey.c,v 1.53 2012/06/30 14:51:31 naddy Exp $	*/
2 /*
3  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
4  * Copyright (c) 2003, 2004 Markus Friedl <markus@openbsd.org>
5  * Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/types.h>
21 #include <sys/queue.h>
22 #include <sys/uio.h>
23 #include <sys/socket.h>
24 #include <netinet/in.h>
25 #include <netinet/ip_ipsp.h>
26 #include <net/pfkeyv2.h>
27 
28 #include <err.h>
29 #include <errno.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 
35 #include "ipsecctl.h"
36 #include "pfkey.h"
37 
38 #define ROUNDUP(x) (((x) + (PFKEYV2_CHUNK - 1)) & ~(PFKEYV2_CHUNK - 1))
39 #define IOV_CNT 20
40 
41 static int	fd;
42 static u_int32_t sadb_msg_seq = 1;
43 
44 static int	pfkey_flow(int, u_int8_t, u_int8_t, u_int8_t, u_int8_t,
45 		    struct ipsec_addr_wrap *, u_int16_t,
46 		    struct ipsec_addr_wrap *, u_int16_t,
47 		    struct ipsec_addr_wrap *, struct ipsec_addr_wrap *,
48 		    struct ipsec_auth *, u_int8_t);
49 static int	pfkey_sa(int, u_int8_t, u_int8_t, u_int32_t,
50 		    struct ipsec_addr_wrap *, struct ipsec_addr_wrap *,
51 		    struct ipsec_transforms *, struct ipsec_key *,
52 		    struct ipsec_key *, u_int8_t);
53 static int	pfkey_sagroup(int, u_int8_t, u_int8_t, u_int8_t,
54 		    struct ipsec_addr_wrap *, u_int32_t,
55 		    struct ipsec_addr_wrap *, u_int32_t);
56 static int	pfkey_reply(int, u_int8_t **, ssize_t *);
57 int		pfkey_parse(struct sadb_msg *, struct ipsec_rule *);
58 int		pfkey_ipsec_flush(void);
59 int		pfkey_ipsec_establish(int, struct ipsec_rule *);
60 int		pfkey_init(void);
61 
62 static int
63 pfkey_flow(int sd, u_int8_t satype, u_int8_t action, u_int8_t direction,
64     u_int8_t proto, struct ipsec_addr_wrap *src, u_int16_t sport,
65     struct ipsec_addr_wrap *dst, u_int16_t dport,
66     struct ipsec_addr_wrap *local, struct ipsec_addr_wrap *peer,
67     struct ipsec_auth *auth, u_int8_t flowtype)
68 {
69 	struct sadb_msg		 smsg;
70 	struct sadb_address	 sa_src, sa_dst, sa_local, sa_peer, sa_smask,
71 				 sa_dmask;
72 	struct sadb_protocol	 sa_flowtype, sa_protocol;
73 	struct sadb_ident	*sa_srcid, *sa_dstid;
74 	struct sockaddr_storage	 ssrc, sdst, slocal, speer, smask, dmask;
75 	struct iovec		 iov[IOV_CNT];
76 	ssize_t			 n;
77 	int			 iov_cnt, len, ret = 0;
78 
79 	sa_srcid = sa_dstid = NULL;
80 
81 	bzero(&ssrc, sizeof(ssrc));
82 	bzero(&smask, sizeof(smask));
83 	ssrc.ss_family = smask.ss_family = src->af;
84 	switch (src->af) {
85 	case AF_INET:
86 		((struct sockaddr_in *)&ssrc)->sin_addr = src->address.v4;
87 		ssrc.ss_len = sizeof(struct sockaddr_in);
88 		((struct sockaddr_in *)&smask)->sin_addr = src->mask.v4;
89 		if (sport) {
90 			((struct sockaddr_in *)&ssrc)->sin_port = sport;
91 			((struct sockaddr_in *)&smask)->sin_port = 0xffff;
92 		}
93 		break;
94 	case AF_INET6:
95 		((struct sockaddr_in6 *)&ssrc)->sin6_addr = src->address.v6;
96 		ssrc.ss_len = sizeof(struct sockaddr_in6);
97 		((struct sockaddr_in6 *)&smask)->sin6_addr = src->mask.v6;
98 		if (sport) {
99 			((struct sockaddr_in6 *)&ssrc)->sin6_port = sport;
100 			((struct sockaddr_in6 *)&smask)->sin6_port = 0xffff;
101 		}
102 		break;
103 	default:
104 		warnx("unsupported address family %d", src->af);
105 		return -1;
106 	}
107 	smask.ss_len = ssrc.ss_len;
108 
109 	bzero(&sdst, sizeof(sdst));
110 	bzero(&dmask, sizeof(dmask));
111 	sdst.ss_family = dmask.ss_family = dst->af;
112 	switch (dst->af) {
113 	case AF_INET:
114 		((struct sockaddr_in *)&sdst)->sin_addr = dst->address.v4;
115 		sdst.ss_len = sizeof(struct sockaddr_in);
116 		((struct sockaddr_in *)&dmask)->sin_addr = dst->mask.v4;
117 		if (dport) {
118 			((struct sockaddr_in *)&sdst)->sin_port = dport;
119 			((struct sockaddr_in *)&dmask)->sin_port = 0xffff;
120 		}
121 		break;
122 	case AF_INET6:
123 		((struct sockaddr_in6 *)&sdst)->sin6_addr = dst->address.v6;
124 		sdst.ss_len = sizeof(struct sockaddr_in6);
125 		((struct sockaddr_in6 *)&dmask)->sin6_addr = dst->mask.v6;
126 		if (dport) {
127 			((struct sockaddr_in6 *)&sdst)->sin6_port = dport;
128 			((struct sockaddr_in6 *)&dmask)->sin6_port = 0xffff;
129 		}
130 		break;
131 	default:
132 		warnx("unsupported address family %d", dst->af);
133 		return -1;
134 	}
135 	dmask.ss_len = sdst.ss_len;
136 
137 	bzero(&slocal, sizeof(slocal));
138 	if (local) {
139 		slocal.ss_family = local->af;
140 		switch (local->af) {
141 		case AF_INET:
142 			((struct sockaddr_in *)&slocal)->sin_addr =
143 			    local->address.v4;
144 			slocal.ss_len = sizeof(struct sockaddr_in);
145 			break;
146 		case AF_INET6:
147 			((struct sockaddr_in6 *)&slocal)->sin6_addr =
148 			    local->address.v6;
149 			slocal.ss_len = sizeof(struct sockaddr_in6);
150 			break;
151 		default:
152 			warnx("unsupported address family %d", local->af);
153 			return -1;
154 		}
155 	}
156 
157 	bzero(&speer, sizeof(speer));
158 	if (peer) {
159 		speer.ss_family = peer->af;
160 		switch (peer->af) {
161 		case AF_INET:
162 			((struct sockaddr_in *)&speer)->sin_addr =
163 			    peer->address.v4;
164 			speer.ss_len = sizeof(struct sockaddr_in);
165 			break;
166 		case AF_INET6:
167 			((struct sockaddr_in6 *)&speer)->sin6_addr =
168 			    peer->address.v6;
169 			speer.ss_len = sizeof(struct sockaddr_in6);
170 			break;
171 		default:
172 			warnx("unsupported address family %d", peer->af);
173 			return -1;
174 		}
175 	}
176 
177 	bzero(&smsg, sizeof(smsg));
178 	smsg.sadb_msg_version = PF_KEY_V2;
179 	smsg.sadb_msg_seq = sadb_msg_seq++;
180 	smsg.sadb_msg_pid = getpid();
181 	smsg.sadb_msg_len = sizeof(smsg) / 8;
182 	smsg.sadb_msg_type = action;
183 	smsg.sadb_msg_satype = satype;
184 
185 	bzero(&sa_flowtype, sizeof(sa_flowtype));
186 	sa_flowtype.sadb_protocol_exttype = SADB_X_EXT_FLOW_TYPE;
187 	sa_flowtype.sadb_protocol_len = sizeof(sa_flowtype) / 8;
188 	sa_flowtype.sadb_protocol_direction = direction;
189 
190 	switch (flowtype) {
191 	case TYPE_USE:
192 		sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_USE;
193 		break;
194 	case TYPE_ACQUIRE:
195 		sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_ACQUIRE;
196 		break;
197 	case TYPE_REQUIRE:
198 		sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE;
199 		break;
200 	case TYPE_DENY:
201 		sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_DENY;
202 		break;
203 	case TYPE_BYPASS:
204 		sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_BYPASS;
205 		break;
206 	case TYPE_DONTACQ:
207 		sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_DONTACQ;
208 		break;
209 	default:
210 		warnx("unsupported flowtype %d", flowtype);
211 		return -1;
212 	}
213 
214 	bzero(&sa_protocol, sizeof(sa_protocol));
215 	sa_protocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
216 	sa_protocol.sadb_protocol_len = sizeof(sa_protocol) / 8;
217 	sa_protocol.sadb_protocol_direction = 0;
218 	sa_protocol.sadb_protocol_proto = proto;
219 
220 	bzero(&sa_src, sizeof(sa_src));
221 	sa_src.sadb_address_exttype = SADB_X_EXT_SRC_FLOW;
222 	sa_src.sadb_address_len = (sizeof(sa_src) + ROUNDUP(ssrc.ss_len)) / 8;
223 
224 	bzero(&sa_smask, sizeof(sa_smask));
225 	sa_smask.sadb_address_exttype = SADB_X_EXT_SRC_MASK;
226 	sa_smask.sadb_address_len =
227 	    (sizeof(sa_smask) + ROUNDUP(smask.ss_len)) / 8;
228 
229 	bzero(&sa_dst, sizeof(sa_dst));
230 	sa_dst.sadb_address_exttype = SADB_X_EXT_DST_FLOW;
231 	sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8;
232 
233 	bzero(&sa_dmask, sizeof(sa_dmask));
234 	sa_dmask.sadb_address_exttype = SADB_X_EXT_DST_MASK;
235 	sa_dmask.sadb_address_len =
236 	    (sizeof(sa_dmask) + ROUNDUP(dmask.ss_len)) / 8;
237 
238 	if (local) {
239 		bzero(&sa_local, sizeof(sa_local));
240 		sa_local.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
241 		sa_local.sadb_address_len =
242 		    (sizeof(sa_local) + ROUNDUP(slocal.ss_len)) / 8;
243 	}
244 	if (peer) {
245 		bzero(&sa_peer, sizeof(sa_peer));
246 		sa_peer.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
247 		sa_peer.sadb_address_len =
248 		    (sizeof(sa_peer) + ROUNDUP(speer.ss_len)) / 8;
249 	}
250 
251 	if (auth && auth->srcid) {
252 		len = ROUNDUP(strlen(auth->srcid) + 1) + sizeof(*sa_srcid);
253 
254 		sa_srcid = calloc(len, sizeof(u_int8_t));
255 		if (sa_srcid == NULL)
256 			err(1, "pfkey_flow: calloc");
257 
258 		sa_srcid->sadb_ident_type = auth->srcid_type;
259 		sa_srcid->sadb_ident_len = len / 8;
260 		sa_srcid->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC;
261 
262 		strlcpy((char *)(sa_srcid + 1), auth->srcid,
263 		    ROUNDUP(strlen(auth->srcid) + 1));
264 	}
265 	if (auth && auth->dstid) {
266 		len = ROUNDUP(strlen(auth->dstid) + 1) + sizeof(*sa_dstid);
267 
268 		sa_dstid = calloc(len, sizeof(u_int8_t));
269 		if (sa_dstid == NULL)
270 			err(1, "pfkey_flow: calloc");
271 
272 		sa_dstid->sadb_ident_type = auth->dstid_type;
273 		sa_dstid->sadb_ident_len = len / 8;
274 		sa_dstid->sadb_ident_exttype = SADB_EXT_IDENTITY_DST;
275 
276 		strlcpy((char *)(sa_dstid + 1), auth->dstid,
277 		    ROUNDUP(strlen(auth->dstid) + 1));
278 	}
279 
280 	iov_cnt = 0;
281 
282 	/* header */
283 	iov[iov_cnt].iov_base = &smsg;
284 	iov[iov_cnt].iov_len = sizeof(smsg);
285 	iov_cnt++;
286 
287 	/* add flow type */
288 	iov[iov_cnt].iov_base = &sa_flowtype;
289 	iov[iov_cnt].iov_len = sizeof(sa_flowtype);
290 	smsg.sadb_msg_len += sa_flowtype.sadb_protocol_len;
291 	iov_cnt++;
292 
293 	/* local ip */
294 	if (local) {
295 		iov[iov_cnt].iov_base = &sa_local;
296 		iov[iov_cnt].iov_len = sizeof(sa_local);
297 		iov_cnt++;
298 		iov[iov_cnt].iov_base = &slocal;
299 		iov[iov_cnt].iov_len = ROUNDUP(slocal.ss_len);
300 		smsg.sadb_msg_len += sa_local.sadb_address_len;
301 		iov_cnt++;
302 	}
303 
304 	/* remote peer */
305 	if (peer) {
306 		iov[iov_cnt].iov_base = &sa_peer;
307 		iov[iov_cnt].iov_len = sizeof(sa_peer);
308 		iov_cnt++;
309 		iov[iov_cnt].iov_base = &speer;
310 		iov[iov_cnt].iov_len = ROUNDUP(speer.ss_len);
311 		smsg.sadb_msg_len += sa_peer.sadb_address_len;
312 		iov_cnt++;
313 	}
314 
315 	/* src addr */
316 	iov[iov_cnt].iov_base = &sa_src;
317 	iov[iov_cnt].iov_len = sizeof(sa_src);
318 	iov_cnt++;
319 	iov[iov_cnt].iov_base = &ssrc;
320 	iov[iov_cnt].iov_len = ROUNDUP(ssrc.ss_len);
321 	smsg.sadb_msg_len += sa_src.sadb_address_len;
322 	iov_cnt++;
323 
324 	/* src mask */
325 	iov[iov_cnt].iov_base = &sa_smask;
326 	iov[iov_cnt].iov_len = sizeof(sa_smask);
327 	iov_cnt++;
328 	iov[iov_cnt].iov_base = &smask;
329 	iov[iov_cnt].iov_len = ROUNDUP(smask.ss_len);
330 	smsg.sadb_msg_len += sa_smask.sadb_address_len;
331 	iov_cnt++;
332 
333 	/* dest addr */
334 	iov[iov_cnt].iov_base = &sa_dst;
335 	iov[iov_cnt].iov_len = sizeof(sa_dst);
336 	iov_cnt++;
337 	iov[iov_cnt].iov_base = &sdst;
338 	iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len);
339 	smsg.sadb_msg_len += sa_dst.sadb_address_len;
340 	iov_cnt++;
341 
342 	/* dst mask */
343 	iov[iov_cnt].iov_base = &sa_dmask;
344 	iov[iov_cnt].iov_len = sizeof(sa_dmask);
345 	iov_cnt++;
346 	iov[iov_cnt].iov_base = &dmask;
347 	iov[iov_cnt].iov_len = ROUNDUP(dmask.ss_len);
348 	smsg.sadb_msg_len += sa_dmask.sadb_address_len;
349 	iov_cnt++;
350 
351 	/* add protocol */
352 	iov[iov_cnt].iov_base = &sa_protocol;
353 	iov[iov_cnt].iov_len = sizeof(sa_protocol);
354 	smsg.sadb_msg_len += sa_protocol.sadb_protocol_len;
355 	iov_cnt++;
356 
357 	if (sa_srcid) {
358 		/* src identity */
359 		iov[iov_cnt].iov_base = sa_srcid;
360 		iov[iov_cnt].iov_len = sa_srcid->sadb_ident_len * 8;
361 		smsg.sadb_msg_len += sa_srcid->sadb_ident_len;
362 		iov_cnt++;
363 	}
364 	if (sa_dstid) {
365 		/* dst identity */
366 		iov[iov_cnt].iov_base = sa_dstid;
367 		iov[iov_cnt].iov_len = sa_dstid->sadb_ident_len * 8;
368 		smsg.sadb_msg_len += sa_dstid->sadb_ident_len;
369 		iov_cnt++;
370 	}
371 	len = smsg.sadb_msg_len * 8;
372 
373 	do {
374 		n = writev(sd, iov, iov_cnt);
375 	} while (n == -1 && (errno == EAGAIN || errno == EINTR));
376 	if (n == -1) {
377 		warn("writev failed");
378 		ret = -1;
379 	}
380 
381 	if (sa_srcid)
382 		free(sa_srcid);
383 	if (sa_dstid)
384 		free(sa_dstid);
385 
386 	return ret;
387 }
388 
389 static int
390 pfkey_sa(int sd, u_int8_t satype, u_int8_t action, u_int32_t spi,
391     struct ipsec_addr_wrap *src, struct ipsec_addr_wrap *dst,
392     struct ipsec_transforms *xfs, struct ipsec_key *authkey,
393     struct ipsec_key *enckey, u_int8_t tmode)
394 {
395 	struct sadb_msg		smsg;
396 	struct sadb_sa		sa;
397 	struct sadb_address	sa_src, sa_dst;
398 	struct sadb_key		sa_authkey, sa_enckey;
399 	struct sockaddr_storage	ssrc, sdst;
400 	struct iovec		iov[IOV_CNT];
401 	ssize_t			n;
402 	int			iov_cnt, len, ret = 0;
403 
404 	bzero(&ssrc, sizeof(ssrc));
405 	ssrc.ss_family = src->af;
406 	switch (src->af) {
407 	case AF_INET:
408 		((struct sockaddr_in *)&ssrc)->sin_addr = src->address.v4;
409 		ssrc.ss_len = sizeof(struct sockaddr_in);
410 		break;
411 	case AF_INET6:
412 		((struct sockaddr_in6 *)&ssrc)->sin6_addr = src->address.v6;
413 		ssrc.ss_len = sizeof(struct sockaddr_in6);
414 		break;
415 	default:
416 		warnx("unsupported address family %d", src->af);
417 		return -1;
418 	}
419 
420 	bzero(&sdst, sizeof(sdst));
421 	sdst.ss_family = dst->af;
422 	switch (dst->af) {
423 	case AF_INET:
424 		((struct sockaddr_in *)&sdst)->sin_addr = dst->address.v4;
425 		sdst.ss_len = sizeof(struct sockaddr_in);
426 		break;
427 	case AF_INET6:
428 		((struct sockaddr_in6 *)&sdst)->sin6_addr = dst->address.v6;
429 		sdst.ss_len = sizeof(struct sockaddr_in6);
430 		break;
431 	default:
432 		warnx("unsupported address family %d", dst->af);
433 		return -1;
434 	}
435 
436 	bzero(&smsg, sizeof(smsg));
437 	smsg.sadb_msg_version = PF_KEY_V2;
438 	smsg.sadb_msg_seq = sadb_msg_seq++;
439 	smsg.sadb_msg_pid = getpid();
440 	smsg.sadb_msg_len = sizeof(smsg) / 8;
441 	smsg.sadb_msg_type = action;
442 	smsg.sadb_msg_satype = satype;
443 
444 	bzero(&sa, sizeof(sa));
445 	sa.sadb_sa_len = sizeof(sa) / 8;
446 	sa.sadb_sa_exttype = SADB_EXT_SA;
447 	sa.sadb_sa_spi = htonl(spi);
448 	sa.sadb_sa_state = SADB_SASTATE_MATURE;
449 
450 	if (satype != SADB_X_SATYPE_IPIP && tmode == IPSEC_TUNNEL)
451 		sa.sadb_sa_flags |= SADB_X_SAFLAGS_TUNNEL;
452 
453 	if (xfs && xfs->authxf) {
454 		switch (xfs->authxf->id) {
455 		case AUTHXF_NONE:
456 			break;
457 		case AUTHXF_HMAC_MD5:
458 			sa.sadb_sa_auth = SADB_AALG_MD5HMAC;
459 			break;
460 		case AUTHXF_HMAC_RIPEMD160:
461 			sa.sadb_sa_auth = SADB_X_AALG_RIPEMD160HMAC;
462 			break;
463 		case AUTHXF_HMAC_SHA1:
464 			sa.sadb_sa_auth = SADB_AALG_SHA1HMAC;
465 			break;
466 		case AUTHXF_HMAC_SHA2_256:
467 			sa.sadb_sa_auth = SADB_X_AALG_SHA2_256;
468 			break;
469 		case AUTHXF_HMAC_SHA2_384:
470 			sa.sadb_sa_auth = SADB_X_AALG_SHA2_384;
471 			break;
472 		case AUTHXF_HMAC_SHA2_512:
473 			sa.sadb_sa_auth = SADB_X_AALG_SHA2_512;
474 			break;
475 		default:
476 			warnx("unsupported authentication algorithm %d",
477 			    xfs->authxf->id);
478 		}
479 	}
480 	if (xfs && xfs->encxf) {
481 		switch (xfs->encxf->id) {
482 		case ENCXF_NONE:
483 			break;
484 		case ENCXF_3DES_CBC:
485 			sa.sadb_sa_encrypt = SADB_EALG_3DESCBC;
486 			break;
487 		case ENCXF_DES_CBC:
488 			sa.sadb_sa_encrypt = SADB_EALG_DESCBC;
489 			break;
490 		case ENCXF_AES:
491 		case ENCXF_AES_128:
492 		case ENCXF_AES_192:
493 		case ENCXF_AES_256:
494 			sa.sadb_sa_encrypt = SADB_X_EALG_AES;
495 			break;
496 		case ENCXF_AESCTR:
497 		case ENCXF_AES_128_CTR:
498 		case ENCXF_AES_192_CTR:
499 		case ENCXF_AES_256_CTR:
500 			sa.sadb_sa_encrypt = SADB_X_EALG_AESCTR;
501 			break;
502 		case ENCXF_AES_128_GCM:
503 		case ENCXF_AES_192_GCM:
504 		case ENCXF_AES_256_GCM:
505 			sa.sadb_sa_encrypt = SADB_X_EALG_AESGCM16;
506 			break;
507 		case ENCXF_AES_128_GMAC:
508 		case ENCXF_AES_192_GMAC:
509 		case ENCXF_AES_256_GMAC:
510 			sa.sadb_sa_encrypt = SADB_X_EALG_AESGMAC;
511 			break;
512 		case ENCXF_BLOWFISH:
513 			sa.sadb_sa_encrypt = SADB_X_EALG_BLF;
514 			break;
515 		case ENCXF_CAST128:
516 			sa.sadb_sa_encrypt = SADB_X_EALG_CAST;
517 			break;
518 		case ENCXF_NULL:
519 			sa.sadb_sa_encrypt = SADB_EALG_NULL;
520 			break;
521 		default:
522 			warnx("unsupported encryption algorithm %d",
523 			    xfs->encxf->id);
524 		}
525 	}
526 	if (xfs && xfs->compxf) {
527 		switch (xfs->compxf->id) {
528 		case COMPXF_DEFLATE:
529 			sa.sadb_sa_encrypt = SADB_X_CALG_DEFLATE;
530 			break;
531 		case COMPXF_LZS:
532 			sa.sadb_sa_encrypt = SADB_X_CALG_LZS;
533 			break;
534 		default:
535 			warnx("unsupported compression algorithm %d",
536 			    xfs->compxf->id);
537 		}
538 	}
539 
540 	bzero(&sa_src, sizeof(sa_src));
541 	sa_src.sadb_address_len = (sizeof(sa_src) + ROUNDUP(ssrc.ss_len)) / 8;
542 	sa_src.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
543 
544 	bzero(&sa_dst, sizeof(sa_dst));
545 	sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8;
546 	sa_dst.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
547 
548 	if (action == SADB_ADD && !authkey && !enckey && satype !=
549 	    SADB_X_SATYPE_IPCOMP && satype != SADB_X_SATYPE_IPIP) { /* XXX ENCNULL */
550 		warnx("no key specified");
551 		return -1;
552 	}
553 	if (authkey) {
554 		bzero(&sa_authkey, sizeof(sa_authkey));
555 		sa_authkey.sadb_key_len = (sizeof(sa_authkey) +
556 		    ((authkey->len + 7) / 8) * 8) / 8;
557 		sa_authkey.sadb_key_exttype = SADB_EXT_KEY_AUTH;
558 		sa_authkey.sadb_key_bits = 8 * authkey->len;
559 	}
560 	if (enckey) {
561 		bzero(&sa_enckey, sizeof(sa_enckey));
562 		sa_enckey.sadb_key_len = (sizeof(sa_enckey) +
563 		    ((enckey->len + 7) / 8) * 8) / 8;
564 		sa_enckey.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
565 		sa_enckey.sadb_key_bits = 8 * enckey->len;
566 	}
567 
568 	iov_cnt = 0;
569 
570 	/* header */
571 	iov[iov_cnt].iov_base = &smsg;
572 	iov[iov_cnt].iov_len = sizeof(smsg);
573 	iov_cnt++;
574 
575 	/* sa */
576 	iov[iov_cnt].iov_base = &sa;
577 	iov[iov_cnt].iov_len = sizeof(sa);
578 	smsg.sadb_msg_len += sa.sadb_sa_len;
579 	iov_cnt++;
580 
581 	/* src addr */
582 	iov[iov_cnt].iov_base = &sa_src;
583 	iov[iov_cnt].iov_len = sizeof(sa_src);
584 	iov_cnt++;
585 	iov[iov_cnt].iov_base = &ssrc;
586 	iov[iov_cnt].iov_len = ROUNDUP(ssrc.ss_len);
587 	smsg.sadb_msg_len += sa_src.sadb_address_len;
588 	iov_cnt++;
589 
590 	/* dst addr */
591 	iov[iov_cnt].iov_base = &sa_dst;
592 	iov[iov_cnt].iov_len = sizeof(sa_dst);
593 	iov_cnt++;
594 	iov[iov_cnt].iov_base = &sdst;
595 	iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len);
596 	smsg.sadb_msg_len += sa_dst.sadb_address_len;
597 	iov_cnt++;
598 
599 	if (authkey) {
600 		/* authentication key */
601 		iov[iov_cnt].iov_base = &sa_authkey;
602 		iov[iov_cnt].iov_len = sizeof(sa_authkey);
603 		iov_cnt++;
604 		iov[iov_cnt].iov_base = authkey->data;
605 		iov[iov_cnt].iov_len = ((authkey->len + 7) / 8) * 8;
606 		smsg.sadb_msg_len += sa_authkey.sadb_key_len;
607 		iov_cnt++;
608 	}
609 	if (enckey) {
610 		/* encryption key */
611 		iov[iov_cnt].iov_base = &sa_enckey;
612 		iov[iov_cnt].iov_len = sizeof(sa_enckey);
613 		iov_cnt++;
614 		iov[iov_cnt].iov_base = enckey->data;
615 		iov[iov_cnt].iov_len = ((enckey->len + 7) / 8) * 8;
616 		smsg.sadb_msg_len += sa_enckey.sadb_key_len;
617 		iov_cnt++;
618 	}
619 
620 	len = smsg.sadb_msg_len * 8;
621 	if ((n = writev(sd, iov, iov_cnt)) == -1) {
622 		warn("writev failed");
623 		ret = -1;
624 	} else if (n != len) {
625 		warnx("short write");
626 		ret = -1;
627 	}
628 
629 	return ret;
630 }
631 
632 static int
633 pfkey_sagroup(int sd, u_int8_t satype, u_int8_t satype2, u_int8_t action,
634     struct ipsec_addr_wrap *dst, u_int32_t spi, struct ipsec_addr_wrap *dst2,
635     u_int32_t spi2)
636 {
637 	struct sadb_msg		smsg;
638 	struct sadb_sa		sa1, sa2;
639 	struct sadb_address	sa_dst, sa_dst2;
640 	struct sockaddr_storage	sdst, sdst2;
641 	struct sadb_protocol	sa_proto;
642 	struct iovec		iov[IOV_CNT];
643 	ssize_t			n;
644 	int			iov_cnt, len, ret = 0;
645 
646 	bzero(&sdst, sizeof(sdst));
647 	sdst.ss_family = dst->af;
648 	switch (dst->af) {
649 	case AF_INET:
650 		((struct sockaddr_in *)&sdst)->sin_addr = dst->address.v4;
651 		sdst.ss_len = sizeof(struct sockaddr_in);
652 		break;
653 	case AF_INET6:
654 		((struct sockaddr_in6 *)&sdst)->sin6_addr = dst->address.v6;
655 		sdst.ss_len = sizeof(struct sockaddr_in6);
656 		break;
657 	default:
658 		warnx("unsupported address family %d", dst->af);
659 		return -1;
660 	}
661 
662 	bzero(&sdst2, sizeof(sdst2));
663 	sdst2.ss_family = dst2->af;
664 	switch (dst2->af) {
665 	case AF_INET:
666 		((struct sockaddr_in *)&sdst2)->sin_addr = dst2->address.v4;
667 		sdst2.ss_len = sizeof(struct sockaddr_in);
668 		break;
669 	case AF_INET6:
670 		((struct sockaddr_in6 *)&sdst2)->sin6_addr = dst2->address.v6;
671 		sdst2.ss_len = sizeof(struct sockaddr_in6);
672 		break;
673 	default:
674 		warnx("unsupported address family %d", dst2->af);
675 		return -1;
676 	}
677 
678 	bzero(&smsg, sizeof(smsg));
679 	smsg.sadb_msg_version = PF_KEY_V2;
680 	smsg.sadb_msg_seq = sadb_msg_seq++;
681 	smsg.sadb_msg_pid = getpid();
682 	smsg.sadb_msg_len = sizeof(smsg) / 8;
683 	smsg.sadb_msg_type = action;
684 	smsg.sadb_msg_satype = satype;
685 
686 	bzero(&sa1, sizeof(sa1));
687 	sa1.sadb_sa_len = sizeof(sa1) / 8;
688 	sa1.sadb_sa_exttype = SADB_EXT_SA;
689 	sa1.sadb_sa_spi = htonl(spi);
690 	sa1.sadb_sa_state = SADB_SASTATE_MATURE;
691 
692 	bzero(&sa2, sizeof(sa2));
693 	sa2.sadb_sa_len = sizeof(sa2) / 8;
694 	sa2.sadb_sa_exttype = SADB_X_EXT_SA2;
695 	sa2.sadb_sa_spi = htonl(spi2);
696 	sa2.sadb_sa_state = SADB_SASTATE_MATURE;
697 	iov_cnt = 0;
698 
699 	bzero(&sa_dst, sizeof(sa_dst));
700 	sa_dst.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
701 	sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8;
702 
703 	bzero(&sa_dst2, sizeof(sa_dst2));
704 	sa_dst2.sadb_address_exttype = SADB_X_EXT_DST2;
705 	sa_dst2.sadb_address_len = (sizeof(sa_dst2) + ROUNDUP(sdst2.ss_len)) / 8;
706 
707 	bzero(&sa_proto, sizeof(sa_proto));
708 	sa_proto.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
709 	sa_proto.sadb_protocol_len = sizeof(sa_proto) / 8;
710 	sa_proto.sadb_protocol_direction = 0;
711 	sa_proto.sadb_protocol_proto = satype2;
712 
713 	/* header */
714 	iov[iov_cnt].iov_base = &smsg;
715 	iov[iov_cnt].iov_len = sizeof(smsg);
716 	iov_cnt++;
717 
718 	/* sa */
719 	iov[iov_cnt].iov_base = &sa1;
720 	iov[iov_cnt].iov_len = sizeof(sa1);
721 	smsg.sadb_msg_len += sa1.sadb_sa_len;
722 	iov_cnt++;
723 
724 	/* dst addr */
725 	iov[iov_cnt].iov_base = &sa_dst;
726 	iov[iov_cnt].iov_len = sizeof(sa_dst);
727 	iov_cnt++;
728 	iov[iov_cnt].iov_base = &sdst;
729 	iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len);
730 	smsg.sadb_msg_len += sa_dst.sadb_address_len;
731 	iov_cnt++;
732 
733 	/* second sa */
734 	iov[iov_cnt].iov_base = &sa2;
735 	iov[iov_cnt].iov_len = sizeof(sa2);
736 	smsg.sadb_msg_len += sa2.sadb_sa_len;
737 	iov_cnt++;
738 
739 	/* second dst addr */
740 	iov[iov_cnt].iov_base = &sa_dst2;
741 	iov[iov_cnt].iov_len = sizeof(sa_dst2);
742 	iov_cnt++;
743 	iov[iov_cnt].iov_base = &sdst2;
744 	iov[iov_cnt].iov_len = ROUNDUP(sdst2.ss_len);
745 	smsg.sadb_msg_len += sa_dst2.sadb_address_len;
746 	iov_cnt++;
747 
748 	/* SA type */
749 	iov[iov_cnt].iov_base = &sa_proto;
750 	iov[iov_cnt].iov_len = sizeof(sa_proto);
751 	smsg.sadb_msg_len += sa_proto.sadb_protocol_len;
752 	iov_cnt++;
753 
754 	len = smsg.sadb_msg_len * 8;
755 	if ((n = writev(sd, iov, iov_cnt)) == -1) {
756 		warn("writev failed");
757 		ret = -1;
758 	} else if (n != len) {
759 		warnx("short write");
760 		ret = -1;
761 	}
762 
763 	return (ret);
764 }
765 
766 static int
767 pfkey_reply(int sd, u_int8_t **datap, ssize_t *lenp)
768 {
769 	struct sadb_msg	 hdr;
770 	ssize_t		 len;
771 	u_int8_t	*data;
772 
773 	if (recv(sd, &hdr, sizeof(hdr), MSG_PEEK) != sizeof(hdr)) {
774 		warnx("short read");
775 		return -1;
776 	}
777 	len = hdr.sadb_msg_len * PFKEYV2_CHUNK;
778 	if ((data = malloc(len)) == NULL)
779 		err(1, "pfkey_reply: malloc");
780 	if (read(sd, data, len) != len) {
781 		warn("PF_KEY short read");
782 		bzero(data, len);
783 		free(data);
784 		return -1;
785 	}
786 	if (datap) {
787 		*datap = data;
788 		if (lenp)
789 			*lenp = len;
790 	} else {
791 		bzero(data, len);
792 		free(data);
793 	}
794 	if (datap == NULL && hdr.sadb_msg_errno != 0) {
795 		errno = hdr.sadb_msg_errno;
796 		if (errno != EEXIST) {
797 			warn("PF_KEY failed");
798 			return -1;
799 		}
800 	}
801 	return 0;
802 }
803 
804 int
805 pfkey_parse(struct sadb_msg *msg, struct ipsec_rule *rule)
806 {
807 	struct sadb_ext		*ext;
808 	struct sadb_address	*saddr;
809 	struct sadb_protocol	*sproto;
810 	struct sadb_ident	*sident;
811 	struct sockaddr		*sa;
812 	struct sockaddr_in	*sa_in;
813 	struct sockaddr_in6	*sa_in6;
814 	int			 len;
815 
816 	switch (msg->sadb_msg_satype) {
817 	case SADB_SATYPE_ESP:
818 		rule->satype = IPSEC_ESP;
819 		break;
820 	case SADB_SATYPE_AH:
821 		rule->satype = IPSEC_AH;
822 		break;
823 	case SADB_X_SATYPE_IPCOMP:
824 		rule->satype = IPSEC_IPCOMP;
825 		break;
826 	case SADB_X_SATYPE_IPIP:
827 		rule->satype = IPSEC_IPIP;
828 		break;
829 	default:
830 		return (1);
831 	}
832 
833 	for (ext = (struct sadb_ext *)(msg + 1);
834 	    (size_t)((u_int8_t *)ext - (u_int8_t *)msg) <
835 	    msg->sadb_msg_len * PFKEYV2_CHUNK && ext->sadb_ext_len > 0;
836 	    ext = (struct sadb_ext *)((u_int8_t *)ext +
837 	    ext->sadb_ext_len * PFKEYV2_CHUNK)) {
838 		switch (ext->sadb_ext_type) {
839 		case SADB_EXT_ADDRESS_SRC:
840 			saddr = (struct sadb_address *)ext;
841 			sa = (struct sockaddr *)(saddr + 1);
842 
843 			rule->local = calloc(1, sizeof(struct ipsec_addr_wrap));
844 			if (rule->local == NULL)
845 				err(1, "pfkey_parse: calloc");
846 
847 			rule->local->af = sa->sa_family;
848 			switch (sa->sa_family) {
849 			case AF_INET:
850 				bcopy(&((struct sockaddr_in *)sa)->sin_addr,
851 				    &rule->local->address.v4,
852 				    sizeof(struct in_addr));
853 				set_ipmask(rule->local, 32);
854 				break;
855 			case AF_INET6:
856 				bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr,
857 				    &rule->local->address.v6,
858 				    sizeof(struct in6_addr));
859 				set_ipmask(rule->local, 128);
860 				break;
861 			default:
862 				return (1);
863 			}
864 			break;
865 
866 
867 		case SADB_EXT_ADDRESS_DST:
868 			saddr = (struct sadb_address *)ext;
869 			sa = (struct sockaddr *)(saddr + 1);
870 
871 			rule->peer = calloc(1, sizeof(struct ipsec_addr_wrap));
872 			if (rule->peer == NULL)
873 				err(1, "pfkey_parse: calloc");
874 
875 			rule->peer->af = sa->sa_family;
876 			switch (sa->sa_family) {
877 			case AF_INET:
878 				bcopy(&((struct sockaddr_in *)sa)->sin_addr,
879 				    &rule->peer->address.v4,
880 				    sizeof(struct in_addr));
881 				set_ipmask(rule->peer, 32);
882 				break;
883 			case AF_INET6:
884 				bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr,
885 				    &rule->peer->address.v6,
886 				    sizeof(struct in6_addr));
887 				set_ipmask(rule->peer, 128);
888 				break;
889 			default:
890 				return (1);
891 			}
892 			break;
893 
894 		case SADB_EXT_IDENTITY_SRC:
895 			sident = (struct sadb_ident *)ext;
896 			len = (sident->sadb_ident_len * sizeof(uint64_t)) -
897 			    sizeof(struct sadb_ident);
898 
899 			if (rule->auth == NULL) {
900 				rule->auth = calloc(1, sizeof(struct
901 				    ipsec_auth));
902 				if (rule->auth == NULL)
903 					err(1, "pfkey_parse: calloc");
904 			}
905 
906 			rule->auth->srcid = calloc(1, len);
907 			if (rule->auth->srcid == NULL)
908 				err(1, "pfkey_parse: calloc");
909 
910 			strlcpy(rule->auth->srcid, (char *)(sident + 1), len);
911 			break;
912 
913 		case SADB_EXT_IDENTITY_DST:
914 			sident = (struct sadb_ident *)ext;
915 			len = (sident->sadb_ident_len * sizeof(uint64_t)) -
916 			    sizeof(struct sadb_ident);
917 
918 			if (rule->auth == NULL) {
919 				rule->auth = calloc(1, sizeof(struct
920 				    ipsec_auth));
921 				if (rule->auth == NULL)
922 					err(1, "pfkey_parse: calloc");
923 			}
924 
925 			rule->auth->dstid = calloc(1, len);
926 			if (rule->auth->dstid == NULL)
927 				err(1, "pfkey_parse: calloc");
928 
929 			strlcpy(rule->auth->dstid, (char *)(sident + 1), len);
930 			break;
931 
932 		case SADB_X_EXT_PROTOCOL:
933 			sproto = (struct sadb_protocol *)ext;
934 			if (sproto->sadb_protocol_direction == 0)
935 				rule->proto = sproto->sadb_protocol_proto;
936 			break;
937 
938 		case SADB_X_EXT_FLOW_TYPE:
939 			sproto = (struct sadb_protocol *)ext;
940 
941 			switch (sproto->sadb_protocol_direction) {
942 			case IPSP_DIRECTION_IN:
943 				rule->direction = IPSEC_IN;
944 				break;
945 			case IPSP_DIRECTION_OUT:
946 				rule->direction = IPSEC_OUT;
947 				break;
948 			default:
949 				return (1);
950 			}
951 			switch (sproto->sadb_protocol_proto) {
952 			case SADB_X_FLOW_TYPE_USE:
953 				rule->flowtype = TYPE_USE;
954 				break;
955 			case SADB_X_FLOW_TYPE_ACQUIRE:
956 				rule->flowtype = TYPE_ACQUIRE;
957 				break;
958 			case SADB_X_FLOW_TYPE_REQUIRE:
959 				rule->flowtype = TYPE_REQUIRE;
960 				break;
961 			case SADB_X_FLOW_TYPE_DENY:
962 				rule->flowtype = TYPE_DENY;
963 				break;
964 			case SADB_X_FLOW_TYPE_BYPASS:
965 				rule->flowtype = TYPE_BYPASS;
966 				break;
967 			case SADB_X_FLOW_TYPE_DONTACQ:
968 				rule->flowtype = TYPE_DONTACQ;
969 				break;
970 			default:
971 				rule->flowtype = TYPE_UNKNOWN;
972 				break;
973 			}
974 			break;
975 
976 		case SADB_X_EXT_SRC_FLOW:
977 			saddr = (struct sadb_address *)ext;
978 			sa = (struct sockaddr *)(saddr + 1);
979 
980 			if (rule->src == NULL) {
981 				rule->src = calloc(1,
982 				    sizeof(struct ipsec_addr_wrap));
983 				if (rule->src == NULL)
984 					err(1, "pfkey_parse: calloc");
985 			}
986 
987 			rule->src->af = sa->sa_family;
988 			switch (sa->sa_family) {
989 			case AF_INET:
990 				bcopy(&((struct sockaddr_in *)sa)->sin_addr,
991 				    &rule->src->address.v4,
992 				    sizeof(struct in_addr));
993 				rule->sport =
994 				    ((struct sockaddr_in *)sa)->sin_port;
995 				break;
996 			case AF_INET6:
997 				bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr,
998 				    &rule->src->address.v6,
999 				    sizeof(struct in6_addr));
1000 				rule->sport =
1001 				    ((struct sockaddr_in6 *)sa)->sin6_port;
1002 				break;
1003 			default:
1004 				return (1);
1005 			}
1006 			break;
1007 
1008 		case SADB_X_EXT_DST_FLOW:
1009 			saddr = (struct sadb_address *)ext;
1010 			sa = (struct sockaddr *)(saddr + 1);
1011 
1012 			if (rule->dst == NULL) {
1013 				rule->dst = calloc(1,
1014 				    sizeof(struct ipsec_addr_wrap));
1015 				if (rule->dst == NULL)
1016 					err(1, "pfkey_parse: calloc");
1017 			}
1018 
1019 			rule->dst->af = sa->sa_family;
1020 			switch (sa->sa_family) {
1021 			case AF_INET:
1022 				bcopy(&((struct sockaddr_in *)sa)->sin_addr,
1023 				    &rule->dst->address.v4,
1024 				    sizeof(struct in_addr));
1025 				rule->dport =
1026 				    ((struct sockaddr_in *)sa)->sin_port;
1027 				break;
1028 			case AF_INET6:
1029 				bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr,
1030 				    &rule->dst->address.v6,
1031 				    sizeof(struct in6_addr));
1032 				rule->dport =
1033 				    ((struct sockaddr_in6 *)sa)->sin6_port;
1034 				break;
1035 			default:
1036 				return (1);
1037 			}
1038 			break;
1039 
1040 
1041 		case SADB_X_EXT_SRC_MASK:
1042 			saddr = (struct sadb_address *)ext;
1043 			sa = (struct sockaddr *)(saddr + 1);
1044 
1045 			if (rule->src == NULL) {
1046 				rule->src = calloc(1,
1047 				    sizeof(struct ipsec_addr_wrap));
1048 				if (rule->src == NULL)
1049 					err(1, "pfkey_parse: calloc");
1050 			}
1051 
1052 			rule->src->af = sa->sa_family;
1053 			switch (sa->sa_family) {
1054 			case AF_INET:
1055 				sa_in = (struct sockaddr_in *)sa;
1056 				bcopy(&sa_in->sin_addr, &rule->src->mask.v4,
1057 				    sizeof(struct in_addr));
1058 				break;
1059 			case AF_INET6:
1060 				sa_in6 = (struct sockaddr_in6 *)sa;
1061 				bcopy(&sa_in6->sin6_addr, &rule->src->mask.v6,
1062 				    sizeof(struct in6_addr));
1063 				break;
1064 
1065 			default:
1066 				return (1);
1067 			}
1068 			break;
1069 
1070 		case SADB_X_EXT_DST_MASK:
1071 			saddr = (struct sadb_address *)ext;
1072 			sa = (struct sockaddr *)(saddr + 1);
1073 
1074 			if (rule->dst == NULL) {
1075 				rule->dst = calloc(1,
1076 				    sizeof(struct ipsec_addr_wrap));
1077 				if (rule->dst == NULL)
1078 					err(1, "pfkey_parse: calloc");
1079 			}
1080 
1081 			rule->dst->af = sa->sa_family;
1082 			switch (sa->sa_family) {
1083 			case AF_INET:
1084 				sa_in = (struct sockaddr_in *)sa;
1085 				bcopy(&sa_in->sin_addr, &rule->dst->mask.v4,
1086 				    sizeof(struct in_addr));
1087 				break;
1088 			case AF_INET6:
1089 				sa_in6 = (struct sockaddr_in6 *)sa;
1090 				bcopy(&sa_in6->sin6_addr, &rule->dst->mask.v6,
1091 				    sizeof(struct in6_addr));
1092 				break;
1093 			default:
1094 				return (1);
1095 			}
1096 			break;
1097 
1098 		default:
1099 			return (1);
1100 		}
1101 	}
1102 
1103 	return (0);
1104 }
1105 
1106 int
1107 pfkey_ipsec_establish(int action, struct ipsec_rule *r)
1108 {
1109 	int		ret;
1110 	u_int8_t	satype, satype2, direction;
1111 
1112 	if (r->type == RULE_FLOW) {
1113 		switch (r->satype) {
1114 		case IPSEC_ESP:
1115 			satype = SADB_SATYPE_ESP;
1116 			break;
1117 		case IPSEC_AH:
1118 			satype = SADB_SATYPE_AH;
1119 			break;
1120 		case IPSEC_IPCOMP:
1121 			satype = SADB_X_SATYPE_IPCOMP;
1122 			break;
1123 		case IPSEC_IPIP:
1124 			satype = SADB_X_SATYPE_IPIP;
1125 			break;
1126 		default:
1127 			return -1;
1128 		}
1129 
1130 		switch (r->direction) {
1131 		case IPSEC_IN:
1132 			direction = IPSP_DIRECTION_IN;
1133 			break;
1134 		case IPSEC_OUT:
1135 			direction = IPSP_DIRECTION_OUT;
1136 			break;
1137 		default:
1138 			return -1;
1139 		}
1140 
1141 		switch (action) {
1142 		case ACTION_ADD:
1143 			ret = pfkey_flow(fd, satype, SADB_X_ADDFLOW, direction,
1144 			    r->proto, r->src, r->sport, r->dst, r->dport,
1145 			    r->local, r->peer, r->auth, r->flowtype);
1146 			break;
1147 		case ACTION_DELETE:
1148 			/* No peer for flow deletion. */
1149 			ret = pfkey_flow(fd, satype, SADB_X_DELFLOW, direction,
1150 			    r->proto, r->src, r->sport, r->dst, r->dport,
1151 			    NULL, NULL, NULL, r->flowtype);
1152 			break;
1153 		default:
1154 			return -1;
1155 		}
1156 	} else if (r->type == RULE_SA) {
1157 		switch (r->satype) {
1158 		case IPSEC_AH:
1159 			satype = SADB_SATYPE_AH;
1160 			break;
1161 		case IPSEC_ESP:
1162 			satype = SADB_SATYPE_ESP;
1163 			break;
1164 		case IPSEC_IPCOMP:
1165 			satype = SADB_X_SATYPE_IPCOMP;
1166 			break;
1167 		case IPSEC_TCPMD5:
1168 			satype = SADB_X_SATYPE_TCPSIGNATURE;
1169 			break;
1170 		case IPSEC_IPIP:
1171 			satype = SADB_X_SATYPE_IPIP;
1172 			break;
1173 		default:
1174 			return -1;
1175 		}
1176 		switch (action) {
1177 		case ACTION_ADD:
1178 			ret = pfkey_sa(fd, satype, SADB_ADD, r->spi,
1179 			    r->src, r->dst, r->xfs, r->authkey, r->enckey,
1180 			    r->tmode);
1181 			break;
1182 		case ACTION_DELETE:
1183 			ret = pfkey_sa(fd, satype, SADB_DELETE, r->spi,
1184 			    r->src, r->dst, r->xfs, NULL, NULL, r->tmode);
1185 			break;
1186 		default:
1187 			return -1;
1188 		}
1189 	} else if (r->type == RULE_GROUP) {
1190 		switch (r->satype) {
1191 		case IPSEC_AH:
1192 			satype = SADB_SATYPE_AH;
1193 			break;
1194 		case IPSEC_ESP:
1195 			satype = SADB_SATYPE_ESP;
1196 			break;
1197 		case IPSEC_IPCOMP:
1198 			satype = SADB_X_SATYPE_IPCOMP;
1199 			break;
1200 		case IPSEC_TCPMD5:
1201 			satype = SADB_X_SATYPE_TCPSIGNATURE;
1202 			break;
1203 		case IPSEC_IPIP:
1204 			satype = SADB_X_SATYPE_IPIP;
1205 			break;
1206 		default:
1207 			return -1;
1208 		}
1209 		switch (r->proto2) {
1210 		case IPSEC_AH:
1211 			satype2 = SADB_SATYPE_AH;
1212 			break;
1213 		case IPSEC_ESP:
1214 			satype2 = SADB_SATYPE_ESP;
1215 			break;
1216 		case IPSEC_IPCOMP:
1217 			satype2 = SADB_X_SATYPE_IPCOMP;
1218 			break;
1219 		case IPSEC_TCPMD5:
1220 			satype2 = SADB_X_SATYPE_TCPSIGNATURE;
1221 			break;
1222 		case IPSEC_IPIP:
1223 			satype2 = SADB_X_SATYPE_IPIP;
1224 			break;
1225 		default:
1226 			return -1;
1227 		}
1228 		switch (action) {
1229 		case ACTION_ADD:
1230 			ret = pfkey_sagroup(fd, satype, satype2,
1231 			    SADB_X_GRPSPIS, r->dst, r->spi, r->dst2, r->spi2);
1232 			break;
1233 		case ACTION_DELETE:
1234 			return 0;
1235 		default:
1236 			return -1;
1237 		}
1238 	} else
1239 		return -1;
1240 
1241 	if (ret < 0)
1242 		return -1;
1243 	if (pfkey_reply(fd, NULL, NULL) < 0)
1244 		return -1;
1245 
1246 	return 0;
1247 }
1248 
1249 int
1250 pfkey_ipsec_flush(void)
1251 {
1252 	struct sadb_msg smsg;
1253 	struct iovec	iov[IOV_CNT];
1254 	ssize_t		n;
1255 	int		iov_cnt, len;
1256 
1257 	bzero(&smsg, sizeof(smsg));
1258 	smsg.sadb_msg_version = PF_KEY_V2;
1259 	smsg.sadb_msg_seq = sadb_msg_seq++;
1260 	smsg.sadb_msg_pid = getpid();
1261 	smsg.sadb_msg_len = sizeof(smsg) / 8;
1262 	smsg.sadb_msg_type = SADB_FLUSH;
1263 	smsg.sadb_msg_satype = SADB_SATYPE_UNSPEC;
1264 
1265 	iov_cnt = 0;
1266 
1267 	iov[iov_cnt].iov_base = &smsg;
1268 	iov[iov_cnt].iov_len = sizeof(smsg);
1269 	iov_cnt++;
1270 
1271 	len = smsg.sadb_msg_len * 8;
1272 	if ((n = writev(fd, iov, iov_cnt)) == -1) {
1273 		warn("writev failed");
1274 		return -1;
1275 	}
1276 	if (n != len) {
1277 		warnx("short write");
1278 		return -1;
1279 	}
1280 	if (pfkey_reply(fd, NULL, NULL) < 0)
1281 		return -1;
1282 
1283 	return 0;
1284 }
1285 
1286 static int
1287 pfkey_promisc(void)
1288 {
1289 	struct sadb_msg msg;
1290 
1291 	memset(&msg, 0, sizeof(msg));
1292 	msg.sadb_msg_version = PF_KEY_V2;
1293 	msg.sadb_msg_seq = sadb_msg_seq++;
1294 	msg.sadb_msg_pid = getpid();
1295 	msg.sadb_msg_len = sizeof(msg) / PFKEYV2_CHUNK;
1296 	msg.sadb_msg_type = SADB_X_PROMISC;
1297 	msg.sadb_msg_satype = 1;	/* enable */
1298 	if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
1299 		warn("pfkey_promisc: write failed");
1300 		return -1;
1301 	}
1302 	if (pfkey_reply(fd, NULL, NULL) < 0)
1303 		return -1;
1304 	return 0;
1305 }
1306 
1307 int
1308 pfkey_monitor(int opts)
1309 {
1310 	fd_set *rset;
1311 	u_int8_t *data;
1312 	struct sadb_msg *msg;
1313 	ssize_t len, set_size;
1314 	int n;
1315 
1316 	if (pfkey_init() < 0)
1317 		return -1;
1318 	if (pfkey_promisc() < 0)
1319 		return -1;
1320 
1321 	set_size = howmany(fd + 1, NFDBITS) * sizeof(fd_mask);
1322 	if ((rset = malloc(set_size)) == NULL) {
1323 		warn("malloc");
1324 		return -1;
1325 	}
1326 	for (;;) {
1327 		memset(rset, 0, set_size);
1328 		FD_SET(fd, rset);
1329 		if ((n = select(fd+1, rset, NULL, NULL, NULL)) < 0)
1330 			err(2, "select");
1331 		if (n == 0)
1332 			break;
1333 		if (!FD_ISSET(fd, rset))
1334 			continue;
1335 		if (pfkey_reply(fd, &data, &len) < 0)
1336 			continue;
1337 		msg = (struct sadb_msg *)data;
1338 		if (msg->sadb_msg_type == SADB_X_PROMISC) {
1339 			/* remove extra header from promisc messages */
1340 			if ((msg->sadb_msg_len * PFKEYV2_CHUNK) >=
1341 			    2 * sizeof(struct sadb_msg)) {
1342 				msg++;
1343 			}
1344 		}
1345 		pfkey_monitor_sa(msg, opts);
1346 		if (opts & IPSECCTL_OPT_VERBOSE)
1347 			pfkey_print_raw(data, len);
1348 		memset(data, 0, len);
1349 		free(data);
1350 	}
1351 	close(fd);
1352 	free(rset);
1353 	return 0;
1354 }
1355 
1356 int
1357 pfkey_init(void)
1358 {
1359 	if ((fd = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) == -1)
1360 		err(1, "pfkey_init: failed to open PF_KEY socket");
1361 
1362 	return 0;
1363 }
1364