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