1/*
2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/*	$FreeBSD: src/lib/libipsec/pfkey.c,v 1.1.2.2 2001/07/03 11:01:14 ume Exp $	*/
24/*	$KAME: pfkey.c,v 1.39 2001/03/05 18:22:17 thorpej Exp $	*/
25
26/*
27 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
28 * All rights reserved.
29 *
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
32 * are met:
33 * 1. Redistributions of source code must retain the above copyright
34 *    notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 *    notice, this list of conditions and the following disclaimer in the
37 *    documentation and/or other materials provided with the distribution.
38 * 3. Neither the name of the project nor the names of its contributors
39 *    may be used to endorse or promote products derived from this software
40 *    without specific prior written permission.
41 *
42 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
43 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
46 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52 * SUCH DAMAGE.
53 */
54
55#include <sys/types.h>
56#include <sys/param.h>
57#include <sys/socket.h>
58#include <net/pfkeyv2.h>
59#include <netinet/in.h>
60#include <netinet6/ipsec.h>
61
62#include <stdlib.h>
63#include <unistd.h>
64#include <string.h>
65#include <errno.h>
66#include <stdio.h>
67
68#include "ipsec_strerror.h"
69#include "libpfkey.h"
70
71#define CALLOC(size, cast) (cast)calloc(1, (size))
72
73/* Wcast-align fix - cast away alignment warning when buffer is aligned */
74#define ALIGNED_CAST(type)	(type)(void *)
75
76static int findsupportedmap __P((int));
77static int setsupportedmap __P((struct sadb_supported *));
78static struct sadb_alg *findsupportedalg __P((u_int, u_int));
79static int pfkey_send_x1 __P((int, u_int, u_int, u_int, struct sockaddr *,
80	struct sockaddr *, u_int32_t, u_int32_t, u_int, caddr_t,
81	u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int32_t,
82	u_int32_t, u_int32_t, u_int32_t));
83static int pfkey_send_x2 __P((int, u_int, u_int, u_int,
84	struct sockaddr *, struct sockaddr *, u_int32_t));
85static int pfkey_send_x3 __P((int, u_int, u_int));
86static int pfkey_send_x4 __P((int, u_int, struct sockaddr *, u_int,
87	struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t,
88	char *, int, u_int32_t));
89static int pfkey_send_x5 __P((int, u_int, u_int32_t));
90
91static caddr_t pfkey_setsadbmsg __P((caddr_t, caddr_t, u_int, u_int,
92	u_int, u_int32_t, pid_t));
93static caddr_t pfkey_setsadbsa __P((caddr_t, caddr_t, u_int32_t, u_int,
94	u_int, u_int, u_int32_t));
95static caddr_t pfkey_setsadbaddr __P((caddr_t, caddr_t, u_int,
96	struct sockaddr *, u_int, u_int));
97static caddr_t pfkey_setsadbkey __P((caddr_t, caddr_t, u_int, caddr_t, u_int));
98static caddr_t pfkey_setsadblifetime __P((caddr_t, caddr_t, u_int, u_int32_t,
99	u_int32_t, u_int32_t, u_int32_t));
100static caddr_t pfkey_setsadbxsa2 __P((caddr_t, caddr_t, u_int32_t, u_int32_t));
101
102/*
103 * make and search supported algorithm structure.
104 */
105static struct sadb_supported *ipsec_supported[] = { NULL, NULL, NULL, };
106
107static int supported_map[] = {
108	SADB_SATYPE_AH,
109	SADB_SATYPE_ESP,
110	SADB_X_SATYPE_IPCOMP,
111};
112
113static int
114findsupportedmap(satype)
115	int satype;
116{
117	int i;
118
119	for (i = 0; i < sizeof(supported_map)/sizeof(supported_map[0]); i++)
120		if (supported_map[i] == satype)
121			return i;
122	return -1;
123}
124
125static struct sadb_alg *
126findsupportedalg(satype, alg_id)
127	u_int satype, alg_id;
128{
129	int algno;
130	int tlen;
131	caddr_t p;
132
133	/* validity check */
134	algno = findsupportedmap(satype);
135	if (algno == -1) {
136		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
137		return NULL;
138	}
139	if (ipsec_supported[algno] == NULL) {
140		__ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST;
141		return NULL;
142	}
143
144	tlen = ipsec_supported[algno]->sadb_supported_len
145		- sizeof(struct sadb_supported);
146	p = (caddr_t)(ipsec_supported[algno] + 1);
147	while (tlen > 0) {
148		if (tlen < sizeof(struct sadb_alg)) {
149			/* invalid format */
150			break;
151		}
152		if ((ALIGNED_CAST(struct sadb_alg *)p)->sadb_alg_id == alg_id)
153			return ALIGNED_CAST(struct sadb_alg *)p;
154
155		tlen -= sizeof(struct sadb_alg);
156		p += sizeof(struct sadb_alg);
157	}
158
159	__ipsec_errcode = EIPSEC_NOT_SUPPORTED;
160	return NULL;
161}
162
163static int
164setsupportedmap(sup)
165	struct sadb_supported *sup;
166{
167	struct sadb_supported **ipsup;
168
169	switch (sup->sadb_supported_exttype) {
170	case SADB_EXT_SUPPORTED_AUTH:
171		ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_AH)];
172		break;
173	case SADB_EXT_SUPPORTED_ENCRYPT:
174		ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_ESP)];
175		break;
176	default:
177		__ipsec_errcode = EIPSEC_INVAL_SATYPE;
178		return -1;
179	}
180
181	if (*ipsup)
182		free(*ipsup);
183
184	*ipsup = malloc(sup->sadb_supported_len);
185	if (!*ipsup) {
186		__ipsec_set_strerror(strerror(errno));
187		return -1;
188	}
189	memcpy(*ipsup, sup, sup->sadb_supported_len);
190
191	return 0;
192}
193
194/*
195 * check key length against algorithm specified.
196 * This function is called with SADB_EXT_SUPPORTED_{AUTH,ENCRYPT} as the
197 * augument, and only calls to ipsec_check_keylen2();
198 * keylen is the unit of bit.
199 * OUT:
200 *	-1: invalid.
201 *	 0: valid.
202 */
203int
204ipsec_check_keylen(supported, alg_id, keylen)
205	u_int supported;
206	u_int alg_id;
207	u_int keylen;
208{
209	int satype;
210
211	/* validity check */
212	switch (supported) {
213	case SADB_EXT_SUPPORTED_AUTH:
214		satype = SADB_SATYPE_AH;
215		break;
216	case SADB_EXT_SUPPORTED_ENCRYPT:
217		satype = SADB_SATYPE_ESP;
218		break;
219	default:
220		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
221		return -1;
222	}
223
224	return ipsec_check_keylen2(satype, alg_id, keylen);
225}
226
227/*
228 * check key length against algorithm specified.
229 * satype is one of satype defined at pfkeyv2.h.
230 * keylen is the unit of bit.
231 * OUT:
232 *	-1: invalid.
233 *	 0: valid.
234 */
235int
236ipsec_check_keylen2(satype, alg_id, keylen)
237	u_int satype;
238	u_int alg_id;
239	u_int keylen;
240{
241	struct sadb_alg *alg;
242
243	alg = findsupportedalg(satype, alg_id);
244	if (!alg)
245		return -1;
246
247	if (keylen < alg->sadb_alg_minbits || keylen > alg->sadb_alg_maxbits) {
248		__ipsec_errcode = EIPSEC_INVAL_KEYLEN;
249		return -1;
250	}
251
252	__ipsec_errcode = EIPSEC_NO_ERROR;
253	return 0;
254}
255
256/*
257 * get max/min key length against algorithm specified.
258 * satype is one of satype defined at pfkeyv2.h.
259 * keylen is the unit of bit.
260 * OUT:
261 *	-1: invalid.
262 *	 0: valid.
263 */
264int
265ipsec_get_keylen(supported, alg_id, alg0)
266	u_int supported, alg_id;
267	struct sadb_alg *alg0;
268{
269	struct sadb_alg *alg;
270	u_int satype;
271
272	/* validity check */
273	if (!alg0) {
274		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
275		return -1;
276	}
277
278	switch (supported) {
279	case SADB_EXT_SUPPORTED_AUTH:
280		satype = SADB_SATYPE_AH;
281		break;
282	case SADB_EXT_SUPPORTED_ENCRYPT:
283		satype = SADB_SATYPE_ESP;
284		break;
285	default:
286		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
287		return -1;
288	}
289
290	alg = findsupportedalg(satype, alg_id);
291	if (!alg)
292		return -1;
293
294	memcpy(alg0, alg, sizeof(*alg0));
295
296	__ipsec_errcode = EIPSEC_NO_ERROR;
297	return 0;
298}
299
300/*
301 * set the rate for SOFT lifetime against HARD one.
302 * If rate is more than 100 or equal to zero, then set to 100.
303 */
304static u_int soft_lifetime_allocations_rate = PFKEY_SOFT_LIFETIME_RATE;
305static u_int soft_lifetime_bytes_rate = PFKEY_SOFT_LIFETIME_RATE;
306static u_int soft_lifetime_addtime_rate = PFKEY_SOFT_LIFETIME_RATE;
307static u_int soft_lifetime_usetime_rate = PFKEY_SOFT_LIFETIME_RATE;
308
309u_int
310pfkey_set_softrate(type, rate)
311	u_int type, rate;
312{
313	__ipsec_errcode = EIPSEC_NO_ERROR;
314
315	if (rate > 100 || rate == 0)
316		rate = 100;
317
318	switch (type) {
319	case SADB_X_LIFETIME_ALLOCATIONS:
320		soft_lifetime_allocations_rate = rate;
321		return 0;
322	case SADB_X_LIFETIME_BYTES:
323		soft_lifetime_bytes_rate = rate;
324		return 0;
325	case SADB_X_LIFETIME_ADDTIME:
326		soft_lifetime_addtime_rate = rate;
327		return 0;
328	case SADB_X_LIFETIME_USETIME:
329		soft_lifetime_usetime_rate = rate;
330		return 0;
331	}
332
333	__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
334	return 1;
335}
336
337/*
338 * get current rate for SOFT lifetime against HARD one.
339 * ATTENTION: ~0 is returned if invalid type was passed.
340 */
341u_int
342pfkey_get_softrate(type)
343	u_int type;
344{
345	switch (type) {
346	case SADB_X_LIFETIME_ALLOCATIONS:
347		return soft_lifetime_allocations_rate;
348	case SADB_X_LIFETIME_BYTES:
349		return soft_lifetime_bytes_rate;
350	case SADB_X_LIFETIME_ADDTIME:
351		return soft_lifetime_addtime_rate;
352	case SADB_X_LIFETIME_USETIME:
353		return soft_lifetime_usetime_rate;
354	}
355
356	return ~0;
357}
358
359/*
360 * sending SADB_GETSPI message to the kernel.
361 * OUT:
362 *	positive: success and return length sent.
363 *	-1	: error occured, and set errno.
364 */
365int
366pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq)
367	int so;
368	u_int satype, mode;
369	struct sockaddr *src, *dst;
370	u_int32_t min, max, reqid, seq;
371{
372	struct sadb_msg *newmsg;
373	caddr_t ep;
374	int len;
375	int need_spirange = 0;
376	caddr_t p;
377	int plen;
378
379	/* validity check */
380	if (src == NULL || dst == NULL) {
381		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
382		return -1;
383	}
384	if (src->sa_family != dst->sa_family) {
385		__ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
386		return -1;
387	}
388	if (min > max || (min > 0 && min <= 255)) {
389		__ipsec_errcode = EIPSEC_INVAL_SPI;
390		return -1;
391	}
392	switch (src->sa_family) {
393	case AF_INET:
394		plen = sizeof(struct in_addr) << 3;
395		break;
396	case AF_INET6:
397		plen = sizeof(struct in6_addr) << 3;
398		break;
399	default:
400		__ipsec_errcode = EIPSEC_INVAL_FAMILY;
401		return -1;
402	}
403
404	/* create new sadb_msg to send. */
405	len = sizeof(struct sadb_msg)
406		+ sizeof(struct sadb_x_sa2)
407		+ sizeof(struct sadb_address)
408		+ PFKEY_ALIGN8(src->sa_len)
409		+ sizeof(struct sadb_address)
410		+ PFKEY_ALIGN8(dst->sa_len);
411
412	if (min > 255 && max < ~0) {
413		need_spirange++;
414		len += sizeof(struct sadb_spirange);
415	}
416
417	if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
418		__ipsec_set_strerror(strerror(errno));
419		return -1;
420	}
421	ep = ((caddr_t)newmsg) + len;
422
423	p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_GETSPI,
424	    len, satype, seq, getpid());
425	if (!p) {
426		free(newmsg);
427		return -1;
428	}
429
430	p = pfkey_setsadbxsa2(p, ep, mode, reqid);
431	if (!p) {
432		free(newmsg);
433		return -1;
434	}
435
436	/* set sadb_address for source */
437	p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
438	    IPSEC_ULPROTO_ANY);
439	if (!p) {
440		free(newmsg);
441		return -1;
442	}
443
444	/* set sadb_address for destination */
445	p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
446	    IPSEC_ULPROTO_ANY);
447	if (!p) {
448		free(newmsg);
449		return -1;
450	}
451
452	/* proccessing spi range */
453	if (need_spirange) {
454		struct sadb_spirange spirange;
455
456		if (p + sizeof(spirange) > ep) {
457			free(newmsg);
458			return -1;
459		}
460
461		memset(&spirange, 0, sizeof(spirange));
462		spirange.sadb_spirange_len = PFKEY_UNIT64(sizeof(spirange));
463		spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE;
464		spirange.sadb_spirange_min = min;
465		spirange.sadb_spirange_max = max;
466
467		memcpy(p, &spirange, sizeof(spirange));
468
469		p += sizeof(spirange);
470	}
471	if (p != ep) {
472		free(newmsg);
473		return -1;
474	}
475
476	/* send message */
477	len = pfkey_send(so, newmsg, len);
478	free(newmsg);
479
480	if (len < 0)
481		return -1;
482
483	__ipsec_errcode = EIPSEC_NO_ERROR;
484	return len;
485}
486
487/*
488 * sending SADB_UPDATE message to the kernel.
489 * The length of key material is a_keylen + e_keylen.
490 * OUT:
491 *	positive: success and return length sent.
492 *	-1	: error occured, and set errno.
493 */
494int
495pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize,
496		keymat, e_type, e_keylen, a_type, a_keylen, flags,
497		l_alloc, l_bytes, l_addtime, l_usetime, seq)
498	int so;
499	u_int satype, mode, wsize;
500	struct sockaddr *src, *dst;
501	u_int32_t spi, reqid;
502	caddr_t keymat;
503	u_int e_type, e_keylen, a_type, a_keylen, flags;
504	u_int32_t l_alloc;
505	u_int64_t l_bytes, l_addtime, l_usetime;
506	u_int32_t seq;
507{
508	int len;
509	if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi,
510			reqid, wsize,
511			keymat, e_type, e_keylen, a_type, a_keylen, flags,
512			l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0)
513		return -1;
514
515	return len;
516}
517
518/*
519 * sending SADB_ADD message to the kernel.
520 * The length of key material is a_keylen + e_keylen.
521 * OUT:
522 *	positive: success and return length sent.
523 *	-1	: error occured, and set errno.
524 */
525int
526pfkey_send_add(so, satype, mode, src, dst, spi, reqid, wsize,
527		keymat, e_type, e_keylen, a_type, a_keylen, flags,
528		l_alloc, l_bytes, l_addtime, l_usetime, seq)
529	int so;
530	u_int satype, mode, wsize;
531	struct sockaddr *src, *dst;
532	u_int32_t spi, reqid;
533	caddr_t keymat;
534	u_int e_type, e_keylen, a_type, a_keylen, flags;
535	u_int32_t l_alloc;
536	u_int64_t l_bytes, l_addtime, l_usetime;
537	u_int32_t seq;
538{
539	int len;
540	if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi,
541			reqid, wsize,
542			keymat, e_type, e_keylen, a_type, a_keylen, flags,
543			l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0)
544		return -1;
545
546	return len;
547}
548
549/*
550 * sending SADB_DELETE message to the kernel.
551 * OUT:
552 *	positive: success and return length sent.
553 *	-1	: error occured, and set errno.
554 */
555int
556pfkey_send_delete(so, satype, mode, src, dst, spi)
557	int so;
558	u_int satype, mode;
559	struct sockaddr *src, *dst;
560	u_int32_t spi;
561{
562	int len;
563	if ((len = pfkey_send_x2(so, SADB_DELETE, satype, mode, src, dst, spi)) < 0)
564		return -1;
565
566	return len;
567}
568
569/*
570 * sending SADB_DELETE without spi to the kernel.  This is
571 * the "delete all" request (an extension also present in
572 * Solaris).
573 *
574 * OUT:
575 *	positive: success and return length sent
576 *	-1	: error occured, and set errno
577 */
578int
579pfkey_send_delete_all(so, satype, mode, src, dst)
580	int so;
581	u_int satype, mode;
582	struct sockaddr *src, *dst;
583{
584	struct sadb_msg *newmsg;
585	int len;
586	caddr_t p;
587	int plen;
588	caddr_t ep;
589
590	/* validity check */
591	if (src == NULL || dst == NULL) {
592		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
593		return -1;
594	}
595	if (src->sa_family != dst->sa_family) {
596		__ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
597		return -1;
598	}
599	switch (src->sa_family) {
600	case AF_INET:
601		plen = sizeof(struct in_addr) << 3;
602		break;
603	case AF_INET6:
604		plen = sizeof(struct in6_addr) << 3;
605		break;
606	default:
607		__ipsec_errcode = EIPSEC_INVAL_FAMILY;
608		return -1;
609	}
610
611	/* create new sadb_msg to reply. */
612	len = sizeof(struct sadb_msg)
613		+ sizeof(struct sadb_address)
614		+ PFKEY_ALIGN8(src->sa_len)
615		+ sizeof(struct sadb_address)
616		+ PFKEY_ALIGN8(dst->sa_len);
617
618	if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
619		__ipsec_set_strerror(strerror(errno));
620		return -1;
621	}
622	ep = ((caddr_t)newmsg) + len;
623
624	p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_DELETE, len, satype, 0,
625	    getpid());
626	if (!p) {
627		free(newmsg);
628		return -1;
629	}
630	p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
631	    IPSEC_ULPROTO_ANY);
632	if (!p) {
633		free(newmsg);
634		return -1;
635	}
636	p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
637	    IPSEC_ULPROTO_ANY);
638	if (!p || p != ep) {
639		free(newmsg);
640		return -1;
641	}
642
643	/* send message */
644	len = pfkey_send(so, newmsg, len);
645	free(newmsg);
646
647	if (len < 0)
648		return -1;
649
650	__ipsec_errcode = EIPSEC_NO_ERROR;
651	return len;
652}
653
654/*
655 * sending SADB_GET message to the kernel.
656 * OUT:
657 *	positive: success and return length sent.
658 *	-1	: error occured, and set errno.
659 */
660int
661pfkey_send_get(so, satype, mode, src, dst, spi)
662	int so;
663	u_int satype, mode;
664	struct sockaddr *src, *dst;
665	u_int32_t spi;
666{
667	int len;
668	if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0)
669		return -1;
670
671	return len;
672}
673
674/*
675 * sending SADB_REGISTER message to the kernel.
676 * OUT:
677 *	positive: success and return length sent.
678 *	-1	: error occured, and set errno.
679 */
680int
681pfkey_send_register(so, satype)
682	int so;
683	u_int satype;
684{
685	int len, algno;
686
687	if (satype == PF_UNSPEC) {
688		for (algno = 0;
689		     algno < sizeof(supported_map)/sizeof(supported_map[0]);
690		     algno++) {
691			if (ipsec_supported[algno]) {
692				free(ipsec_supported[algno]);
693				ipsec_supported[algno] = NULL;
694			}
695		}
696	} else {
697		algno = findsupportedmap(satype);
698		if (algno == -1) {
699			__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
700			return -1;
701		}
702
703		if (ipsec_supported[algno]) {
704			free(ipsec_supported[algno]);
705			ipsec_supported[algno] = NULL;
706		}
707	}
708
709	if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0)
710		return -1;
711
712	return len;
713}
714
715/*
716 * receiving SADB_REGISTER message from the kernel, and copy buffer for
717 * sadb_supported returned into ipsec_supported.
718 * OUT:
719 *	 0: success and return length sent.
720 *	-1: error occured, and set errno.
721 */
722int
723pfkey_recv_register(so)
724	int so;
725{
726	pid_t pid = getpid();
727	struct sadb_msg *newmsg;
728	int error = -1;
729
730	/* receive message */
731	do {
732		if ((newmsg = pfkey_recv(so)) == NULL)
733			return -1;
734	} while (newmsg->sadb_msg_type != SADB_REGISTER
735	    || newmsg->sadb_msg_pid != pid);
736
737	/* check and fix */
738	newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len);
739
740	error = pfkey_set_supported(newmsg, newmsg->sadb_msg_len);
741	free(newmsg);
742
743	if (error == 0)
744		__ipsec_errcode = EIPSEC_NO_ERROR;
745
746	return error;
747}
748
749/*
750 * receiving SADB_REGISTER message from the kernel, and copy buffer for
751 * sadb_supported returned into ipsec_supported.
752 * NOTE: sadb_msg_len must be host order.
753 * IN:
754 *	tlen: msg length, it's to makeing sure.
755 * OUT:
756 *	 0: success and return length sent.
757 *	-1: error occured, and set errno.
758 */
759int
760pfkey_set_supported(msg, tlen)
761	struct sadb_msg *msg;
762	int tlen;
763{
764	struct sadb_supported *sup;
765	caddr_t p;
766	caddr_t ep;
767
768	/* validity */
769	if (msg->sadb_msg_len != tlen) {
770		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
771		return -1;
772	}
773
774	p = (caddr_t)msg;
775	ep = p + tlen;
776
777	p += sizeof(struct sadb_msg);
778
779	while (p < ep) {
780		sup = ALIGNED_CAST(struct sadb_supported *)p;
781		if (ep < p + sizeof(*sup) ||
782		    PFKEY_EXTLEN(sup) < sizeof(*sup) ||
783		    ep < p + sup->sadb_supported_len) {
784			/* invalid format */
785			break;
786		}
787
788		switch (sup->sadb_supported_exttype) {
789		case SADB_EXT_SUPPORTED_AUTH:
790		case SADB_EXT_SUPPORTED_ENCRYPT:
791			break;
792		default:
793			__ipsec_errcode = EIPSEC_INVAL_SATYPE;
794			return -1;
795		}
796
797		/* fixed length */
798		sup->sadb_supported_len = PFKEY_EXTLEN(sup);
799
800		/* set supported map */
801		if (setsupportedmap(sup) != 0)
802			return -1;
803
804		p += sup->sadb_supported_len;
805	}
806
807	if (p != ep) {
808		__ipsec_errcode = EIPSEC_INVAL_SATYPE;
809		return -1;
810	}
811
812	__ipsec_errcode = EIPSEC_NO_ERROR;
813
814	return 0;
815}
816
817/*
818 * sending SADB_FLUSH message to the kernel.
819 * OUT:
820 *	positive: success and return length sent.
821 *	-1	: error occured, and set errno.
822 */
823int
824pfkey_send_flush(so, satype)
825	int so;
826	u_int satype;
827{
828	int len;
829
830	if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0)
831		return -1;
832
833	return len;
834}
835
836/*
837 * sending SADB_DUMP message to the kernel.
838 * OUT:
839 *	positive: success and return length sent.
840 *	-1	: error occured, and set errno.
841 */
842int
843pfkey_send_dump(so, satype)
844	int so;
845	u_int satype;
846{
847	int len;
848
849	if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0)
850		return -1;
851
852	return len;
853}
854
855/*
856 * sending SADB_X_PROMISC message to the kernel.
857 * NOTE that this function handles promisc mode toggle only.
858 * IN:
859 *	flag:	set promisc off if zero, set promisc on if non-zero.
860 * OUT:
861 *	positive: success and return length sent.
862 *	-1	: error occured, and set errno.
863 *	0     : error occured, and set errno.
864 *	others: a pointer to new allocated buffer in which supported
865 *	        algorithms is.
866 */
867int
868pfkey_send_promisc_toggle(so, flag)
869	int so;
870	int flag;
871{
872	int len;
873
874	if ((len = pfkey_send_x3(so, SADB_X_PROMISC, (flag ? 1 : 0))) < 0)
875		return -1;
876
877	return len;
878}
879
880/*
881 * sending SADB_X_SPDADD message to the kernel.
882 * OUT:
883 *	positive: success and return length sent.
884 *	-1	: error occured, and set errno.
885 */
886int
887pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
888	int so;
889	struct sockaddr *src, *dst;
890	u_int prefs, prefd, proto;
891	caddr_t policy;
892	int policylen;
893	u_int32_t seq;
894{
895	int len;
896
897	if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
898				src, prefs, dst, prefd, proto,
899				0, 0,
900				policy, policylen, seq)) < 0)
901		return -1;
902
903	return len;
904}
905
906/*
907 * sending SADB_X_SPDADD message to the kernel.
908 * OUT:
909 *	positive: success and return length sent.
910 *	-1	: error occured, and set errno.
911 */
912int
913pfkey_send_spdadd2(so, src, prefs, dst, prefd, proto, ltime, vtime,
914		policy, policylen, seq)
915	int so;
916	struct sockaddr *src, *dst;
917	u_int prefs, prefd, proto;
918	u_int64_t ltime, vtime;
919	caddr_t policy;
920	int policylen;
921	u_int32_t seq;
922{
923	int len;
924
925	if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
926				src, prefs, dst, prefd, proto,
927				ltime, vtime,
928				policy, policylen, seq)) < 0)
929		return -1;
930
931	return len;
932}
933
934/*
935 * sending SADB_X_SPDUPDATE message to the kernel.
936 * OUT:
937 *	positive: success and return length sent.
938 *	-1	: error occured, and set errno.
939 */
940int
941pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
942	int so;
943	struct sockaddr *src, *dst;
944	u_int prefs, prefd, proto;
945	caddr_t policy;
946	int policylen;
947	u_int32_t seq;
948{
949	int len;
950
951	if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
952				src, prefs, dst, prefd, proto,
953				0, 0,
954				policy, policylen, seq)) < 0)
955		return -1;
956
957	return len;
958}
959
960/*
961 * sending SADB_X_SPDUPDATE message to the kernel.
962 * OUT:
963 *	positive: success and return length sent.
964 *	-1	: error occured, and set errno.
965 */
966int
967pfkey_send_spdupdate2(so, src, prefs, dst, prefd, proto, ltime, vtime,
968		policy, policylen, seq)
969	int so;
970	struct sockaddr *src, *dst;
971	u_int prefs, prefd, proto;
972	u_int64_t ltime, vtime;
973	caddr_t policy;
974	int policylen;
975	u_int32_t seq;
976{
977	int len;
978
979	if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
980				src, prefs, dst, prefd, proto,
981				ltime, vtime,
982				policy, policylen, seq)) < 0)
983		return -1;
984
985	return len;
986}
987
988/*
989 * sending SADB_X_SPDDELETE message to the kernel.
990 * OUT:
991 *	positive: success and return length sent.
992 *	-1	: error occured, and set errno.
993 */
994int
995pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
996	int so;
997	struct sockaddr *src, *dst;
998	u_int prefs, prefd, proto;
999	caddr_t policy;
1000	int policylen;
1001	u_int32_t seq;
1002{
1003	int len;
1004
1005	if (policylen != sizeof(struct sadb_x_policy)) {
1006		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1007		return -1;
1008	}
1009
1010	if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE,
1011				src, prefs, dst, prefd, proto,
1012				0, 0,
1013				policy, policylen, seq)) < 0)
1014		return -1;
1015
1016	return len;
1017}
1018
1019/*
1020 * sending SADB_X_SPDDELETE message to the kernel.
1021 * OUT:
1022 *	positive: success and return length sent.
1023 *	-1	: error occured, and set errno.
1024 */
1025int
1026pfkey_send_spddelete2(so, spid)
1027	int so;
1028	u_int32_t spid;
1029{
1030	int len;
1031
1032	if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0)
1033		return -1;
1034
1035	return len;
1036}
1037
1038/*
1039 * sending SADB_X_SPDGET message to the kernel.
1040 * OUT:
1041 *	positive: success and return length sent.
1042 *	-1	: error occured, and set errno.
1043 */
1044int
1045pfkey_send_spdget(so, spid)
1046	int so;
1047	u_int32_t spid;
1048{
1049	int len;
1050
1051	if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0)
1052		return -1;
1053
1054	return len;
1055}
1056
1057/*
1058 * sending SADB_X_SPDSETIDX message to the kernel.
1059 * OUT:
1060 *	positive: success and return length sent.
1061 *	-1	: error occured, and set errno.
1062 */
1063int
1064pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
1065	int so;
1066	struct sockaddr *src, *dst;
1067	u_int prefs, prefd, proto;
1068	caddr_t policy;
1069	int policylen;
1070	u_int32_t seq;
1071{
1072	int len;
1073
1074	if (policylen != sizeof(struct sadb_x_policy)) {
1075		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1076		return -1;
1077	}
1078
1079	if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX,
1080				src, prefs, dst, prefd, proto,
1081				0, 0,
1082				policy, policylen, seq)) < 0)
1083		return -1;
1084
1085	return len;
1086}
1087
1088/*
1089 * sending SADB_SPDFLUSH message to the kernel.
1090 * OUT:
1091 *	positive: success and return length sent.
1092 *	-1	: error occured, and set errno.
1093 */
1094int
1095pfkey_send_spdflush(so)
1096	int so;
1097{
1098	int len;
1099
1100	if ((len = pfkey_send_x3(so, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC)) < 0)
1101		return -1;
1102
1103	return len;
1104}
1105
1106/*
1107 * sending SADB_SPDDUMP message to the kernel.
1108 * OUT:
1109 *	positive: success and return length sent.
1110 *	-1	: error occured, and set errno.
1111 */
1112int
1113pfkey_send_spddump(so)
1114	int so;
1115{
1116	int len;
1117
1118	if ((len = pfkey_send_x3(so, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC)) < 0)
1119		return -1;
1120
1121	return len;
1122}
1123
1124/* sending SADB_ADD or SADB_UPDATE message to the kernel */
1125static int
1126pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize,
1127		keymat, e_type, e_keylen, a_type, a_keylen, flags,
1128		l_alloc, l_bytes, l_addtime, l_usetime, seq)
1129	int so;
1130	u_int type, satype, mode;
1131	struct sockaddr *src, *dst;
1132	u_int32_t spi, reqid;
1133	u_int wsize;
1134	caddr_t keymat;
1135	u_int e_type, e_keylen, a_type, a_keylen, flags;
1136	u_int32_t l_alloc, l_bytes, l_addtime, l_usetime, seq;
1137{
1138	struct sadb_msg *newmsg;
1139	int len;
1140	caddr_t p;
1141	int plen;
1142	caddr_t ep;
1143
1144	/* validity check */
1145	if (src == NULL || dst == NULL) {
1146		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1147		return -1;
1148	}
1149	if (src->sa_family != dst->sa_family) {
1150		__ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1151		return -1;
1152	}
1153	switch (src->sa_family) {
1154	case AF_INET:
1155		plen = sizeof(struct in_addr) << 3;
1156		break;
1157	case AF_INET6:
1158		plen = sizeof(struct in6_addr) << 3;
1159		break;
1160	default:
1161		__ipsec_errcode = EIPSEC_INVAL_FAMILY;
1162		return -1;
1163	}
1164
1165	switch (satype) {
1166	case SADB_SATYPE_ESP:
1167		if (e_type == SADB_EALG_NONE) {
1168			__ipsec_errcode = EIPSEC_NO_ALGS;
1169			return -1;
1170		}
1171		break;
1172	case SADB_SATYPE_AH:
1173		if (e_type != SADB_EALG_NONE) {
1174			__ipsec_errcode = EIPSEC_INVAL_ALGS;
1175			return -1;
1176		}
1177		if (a_type == SADB_AALG_NONE) {
1178			__ipsec_errcode = EIPSEC_NO_ALGS;
1179			return -1;
1180		}
1181		break;
1182	case SADB_X_SATYPE_IPCOMP:
1183		if (e_type == SADB_X_CALG_NONE) {
1184			__ipsec_errcode = EIPSEC_INVAL_ALGS;
1185			return -1;
1186		}
1187		if (a_type != SADB_AALG_NONE) {
1188			__ipsec_errcode = EIPSEC_NO_ALGS;
1189			return -1;
1190		}
1191		break;
1192	default:
1193		__ipsec_errcode = EIPSEC_INVAL_SATYPE;
1194		return -1;
1195	}
1196
1197	/* create new sadb_msg to reply. */
1198	len = sizeof(struct sadb_msg)
1199		+ sizeof(struct sadb_sa)
1200		+ sizeof(struct sadb_x_sa2)
1201		+ sizeof(struct sadb_address)
1202		+ PFKEY_ALIGN8(src->sa_len)
1203		+ sizeof(struct sadb_address)
1204		+ PFKEY_ALIGN8(dst->sa_len)
1205		+ sizeof(struct sadb_lifetime)
1206		+ sizeof(struct sadb_lifetime);
1207
1208	if (e_type != SADB_EALG_NONE)
1209		len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen));
1210	if (a_type != SADB_AALG_NONE)
1211		len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(a_keylen));
1212
1213	if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1214		__ipsec_set_strerror(strerror(errno));
1215		return -1;
1216	}
1217	ep = ((caddr_t)newmsg) + len;
1218
1219	p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len,
1220	                     satype, seq, getpid());
1221	if (!p) {
1222		free(newmsg);
1223		return -1;
1224	}
1225	p = pfkey_setsadbsa(p, ep, spi, wsize, a_type, e_type, flags);
1226	if (!p) {
1227		free(newmsg);
1228		return -1;
1229	}
1230	p = pfkey_setsadbxsa2(p, ep, mode, reqid);
1231	if (!p) {
1232		free(newmsg);
1233		return -1;
1234	}
1235	p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
1236	    IPSEC_ULPROTO_ANY);
1237	if (!p) {
1238		free(newmsg);
1239		return -1;
1240	}
1241	p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
1242	    IPSEC_ULPROTO_ANY);
1243	if (!p) {
1244		free(newmsg);
1245		return -1;
1246	}
1247
1248	if (e_type != SADB_EALG_NONE) {
1249		p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_ENCRYPT,
1250		                   keymat, e_keylen);
1251		if (!p) {
1252			free(newmsg);
1253			return -1;
1254		}
1255	}
1256	if (a_type != SADB_AALG_NONE) {
1257		p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_AUTH,
1258		                   keymat + e_keylen, a_keylen);
1259		if (!p) {
1260			free(newmsg);
1261			return -1;
1262		}
1263	}
1264
1265	/* set sadb_lifetime for destination */
1266	p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD,
1267			l_alloc, l_bytes, l_addtime, l_usetime);
1268	if (!p) {
1269		free(newmsg);
1270		return -1;
1271	}
1272	p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_SOFT,
1273			l_alloc, l_bytes, l_addtime, l_usetime);
1274	if (!p || p != ep) {
1275		free(newmsg);
1276		return -1;
1277	}
1278
1279	/* send message */
1280	len = pfkey_send(so, newmsg, len);
1281	free(newmsg);
1282
1283	if (len < 0)
1284		return -1;
1285
1286	__ipsec_errcode = EIPSEC_NO_ERROR;
1287	return len;
1288}
1289
1290/* sending SADB_DELETE or SADB_GET message to the kernel */
1291static int
1292pfkey_send_x2(so, type, satype, mode, src, dst, spi)
1293	int so;
1294	u_int type, satype, mode;
1295	struct sockaddr *src, *dst;
1296	u_int32_t spi;
1297{
1298	struct sadb_msg *newmsg;
1299	int len;
1300	caddr_t p;
1301	int plen;
1302	caddr_t ep;
1303
1304	/* validity check */
1305	if (src == NULL || dst == NULL) {
1306		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1307		return -1;
1308	}
1309	if (src->sa_family != dst->sa_family) {
1310		__ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1311		return -1;
1312	}
1313	switch (src->sa_family) {
1314	case AF_INET:
1315		plen = sizeof(struct in_addr) << 3;
1316		break;
1317	case AF_INET6:
1318		plen = sizeof(struct in6_addr) << 3;
1319		break;
1320	default:
1321		__ipsec_errcode = EIPSEC_INVAL_FAMILY;
1322		return -1;
1323	}
1324
1325	/* create new sadb_msg to reply. */
1326	len = sizeof(struct sadb_msg)
1327		+ sizeof(struct sadb_sa)
1328		+ sizeof(struct sadb_address)
1329		+ PFKEY_ALIGN8(src->sa_len)
1330		+ sizeof(struct sadb_address)
1331		+ PFKEY_ALIGN8(dst->sa_len);
1332
1333	if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1334		__ipsec_set_strerror(strerror(errno));
1335		return -1;
1336	}
1337	ep = ((caddr_t)newmsg) + len;
1338
1339	p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, satype, 0,
1340	    getpid());
1341	if (!p) {
1342		free(newmsg);
1343		return -1;
1344	}
1345	p = pfkey_setsadbsa(p, ep, spi, 0, 0, 0, 0);
1346	if (!p) {
1347		free(newmsg);
1348		return -1;
1349	}
1350	p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
1351	    IPSEC_ULPROTO_ANY);
1352	if (!p) {
1353		free(newmsg);
1354		return -1;
1355	}
1356	p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
1357	    IPSEC_ULPROTO_ANY);
1358	if (!p || p != ep) {
1359		free(newmsg);
1360		return -1;
1361	}
1362
1363	/* send message */
1364	len = pfkey_send(so, newmsg, len);
1365	free(newmsg);
1366
1367	if (len < 0)
1368		return -1;
1369
1370	__ipsec_errcode = EIPSEC_NO_ERROR;
1371	return len;
1372}
1373
1374/*
1375 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message
1376 * to the kernel
1377 */
1378static int
1379pfkey_send_x3(so, type, satype)
1380	int so;
1381	u_int type, satype;
1382{
1383	struct sadb_msg *newmsg;
1384	int len;
1385	caddr_t p;
1386	caddr_t ep;
1387
1388	/* validity check */
1389	switch (type) {
1390	case SADB_X_PROMISC:
1391		if (satype != 0 && satype != 1) {
1392			__ipsec_errcode = EIPSEC_INVAL_SATYPE;
1393			return -1;
1394		}
1395		break;
1396	default:
1397		switch (satype) {
1398		case SADB_SATYPE_UNSPEC:
1399		case SADB_SATYPE_AH:
1400		case SADB_SATYPE_ESP:
1401		case SADB_X_SATYPE_IPCOMP:
1402			break;
1403		default:
1404			__ipsec_errcode = EIPSEC_INVAL_SATYPE;
1405			return -1;
1406		}
1407	}
1408
1409	/* create new sadb_msg to send. */
1410	len = sizeof(struct sadb_msg);
1411
1412	if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1413		__ipsec_set_strerror(strerror(errno));
1414		return -1;
1415	}
1416	ep = ((caddr_t)newmsg) + len;
1417
1418	p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, satype, 0,
1419	    getpid());
1420	if (!p || p != ep) {
1421		free(newmsg);
1422		return -1;
1423	}
1424
1425	/* send message */
1426	len = pfkey_send(so, newmsg, len);
1427	free(newmsg);
1428
1429	if (len < 0)
1430		return -1;
1431
1432	__ipsec_errcode = EIPSEC_NO_ERROR;
1433	return len;
1434}
1435
1436/* sending SADB_X_SPDADD message to the kernel */
1437static int
1438pfkey_send_x4(so, type, src, prefs, dst, prefd, proto,
1439		ltime, vtime, policy, policylen, seq)
1440	int so;
1441	struct sockaddr *src, *dst;
1442	u_int type, prefs, prefd, proto;
1443	u_int64_t ltime, vtime;
1444	char *policy;
1445	int policylen;
1446	u_int32_t seq;
1447{
1448	struct sadb_msg *newmsg;
1449	int len;
1450	caddr_t p;
1451	int plen;
1452	caddr_t ep;
1453
1454	/* validity check */
1455	if (src == NULL || dst == NULL) {
1456		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1457		return -1;
1458	}
1459	if (src->sa_family != dst->sa_family) {
1460		__ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1461		return -1;
1462	}
1463
1464	switch (src->sa_family) {
1465	case AF_INET:
1466		plen = sizeof(struct in_addr) << 3;
1467		break;
1468	case AF_INET6:
1469		plen = sizeof(struct in6_addr) << 3;
1470		break;
1471	default:
1472		__ipsec_errcode = EIPSEC_INVAL_FAMILY;
1473		return -1;
1474	}
1475	if (prefs > plen || prefd > plen) {
1476		__ipsec_errcode = EIPSEC_INVAL_PREFIXLEN;
1477		return -1;
1478	}
1479
1480	/* create new sadb_msg to reply. */
1481	len = sizeof(struct sadb_msg)
1482		+ sizeof(struct sadb_address)
1483		+ PFKEY_ALIGN8(src->sa_len)
1484		+ sizeof(struct sadb_address)
1485		+ PFKEY_ALIGN8(src->sa_len)
1486		+ sizeof(struct sadb_lifetime)
1487		+ policylen;
1488
1489	if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1490		__ipsec_set_strerror(strerror(errno));
1491		return -1;
1492	}
1493	ep = ((caddr_t)newmsg) + len;
1494
1495	p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len,
1496	    SADB_SATYPE_UNSPEC, seq, getpid());
1497	if (!p) {
1498		free(newmsg);
1499		return -1;
1500	}
1501	p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto);
1502	if (!p) {
1503		free(newmsg);
1504		return -1;
1505	}
1506	p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto);
1507	if (!p) {
1508		free(newmsg);
1509		return -1;
1510	}
1511	p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD,
1512			0, 0, ltime, vtime);
1513	if (!p || p + policylen != ep) {
1514		free(newmsg);
1515		return -1;
1516	}
1517	memcpy(p, policy, policylen);
1518
1519	/* send message */
1520	len = pfkey_send(so, newmsg, len);
1521	free(newmsg);
1522
1523	if (len < 0)
1524		return -1;
1525
1526	__ipsec_errcode = EIPSEC_NO_ERROR;
1527	return len;
1528}
1529
1530/* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */
1531static int
1532pfkey_send_x5(so, type, spid)
1533	int so;
1534	u_int type;
1535	u_int32_t spid;
1536{
1537	struct sadb_msg *newmsg;
1538	struct sadb_x_policy xpl;
1539	int len;
1540	caddr_t p;
1541	caddr_t ep;
1542
1543	/* create new sadb_msg to reply. */
1544	len = sizeof(struct sadb_msg)
1545		+ sizeof(xpl);
1546
1547	if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1548		__ipsec_set_strerror(strerror(errno));
1549		return -1;
1550	}
1551	ep = ((caddr_t)newmsg) + len;
1552
1553	p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len,
1554	    SADB_SATYPE_UNSPEC, 0, getpid());
1555	if (!p) {
1556		free(newmsg);
1557		return -1;
1558	}
1559
1560	if (p + sizeof(xpl) != ep) {
1561		free(newmsg);
1562		return -1;
1563	}
1564	memset(&xpl, 0, sizeof(xpl));
1565	xpl.sadb_x_policy_len = PFKEY_UNUNIT64(sizeof(xpl));
1566	xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
1567	xpl.sadb_x_policy_id = spid;
1568	memcpy(p, &xpl, sizeof(xpl));
1569
1570	/* send message */
1571	len = pfkey_send(so, newmsg, len);
1572	free(newmsg);
1573
1574	if (len < 0)
1575		return -1;
1576
1577	__ipsec_errcode = EIPSEC_NO_ERROR;
1578	return len;
1579}
1580
1581/*
1582 * open a socket.
1583 * OUT:
1584 *	-1: fail.
1585 *	others : success and return value of socket.
1586 */
1587int
1588pfkey_open()
1589{
1590	int so;
1591	const int bufsiz = 128 * 1024;	/*is 128K enough?*/
1592
1593	if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) {
1594		__ipsec_set_strerror(strerror(errno));
1595		return -1;
1596	}
1597
1598	/*
1599	 * This is a temporary workaround for KAME PR 154.
1600	 * Don't really care even if it fails.
1601	 */
1602	(void)setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz));
1603	(void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz));
1604
1605	__ipsec_errcode = EIPSEC_NO_ERROR;
1606	return so;
1607}
1608
1609/*
1610 * close a socket.
1611 * OUT:
1612 *	 0: success.
1613 *	-1: fail.
1614 */
1615void
1616pfkey_close(so)
1617	int so;
1618{
1619	(void)close(so);
1620
1621	__ipsec_errcode = EIPSEC_NO_ERROR;
1622	return;
1623}
1624
1625/*
1626 * receive sadb_msg data, and return pointer to new buffer allocated.
1627 * Must free this buffer later.
1628 * OUT:
1629 *	NULL	: error occured.
1630 *	others	: a pointer to sadb_msg structure.
1631 *
1632 * XXX should be rewritten to pass length explicitly
1633 */
1634struct sadb_msg *
1635pfkey_recv(so)
1636	int so;
1637{
1638	struct sadb_msg buf, *newmsg;
1639	int len, reallen;
1640
1641	while ((len = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK)) < 0) {
1642		if (errno == EINTR)
1643			continue;
1644		__ipsec_set_strerror(strerror(errno));
1645		return NULL;
1646	}
1647
1648	if (len < sizeof(buf)) {
1649		recv(so, (caddr_t)&buf, sizeof(buf), 0);
1650		__ipsec_errcode = EIPSEC_MAX;
1651		return NULL;
1652	}
1653
1654	/* read real message */
1655	reallen = PFKEY_UNUNIT64(buf.sadb_msg_len);
1656	if ((newmsg = CALLOC(reallen, struct sadb_msg *)) == 0) {
1657		__ipsec_set_strerror(strerror(errno));
1658		return NULL;
1659	}
1660
1661	while ((len = recv(so, (caddr_t)newmsg, reallen, 0)) < 0) {
1662		if (errno == EINTR)
1663			continue;
1664		__ipsec_set_strerror(strerror(errno));
1665		free(newmsg);
1666		return NULL;
1667	}
1668
1669	if (len != reallen) {
1670		__ipsec_errcode = EIPSEC_SYSTEM_ERROR;
1671		free(newmsg);
1672		return NULL;
1673	}
1674
1675	/* don't trust what the kernel says, validate! */
1676	if (PFKEY_UNUNIT64(newmsg->sadb_msg_len) != len) {
1677		__ipsec_errcode = EIPSEC_SYSTEM_ERROR;
1678		free(newmsg);
1679		return NULL;
1680	}
1681
1682	__ipsec_errcode = EIPSEC_NO_ERROR;
1683	return newmsg;
1684}
1685
1686/*
1687 * send message to a socket.
1688 * OUT:
1689 *	 others: success and return length sent.
1690 *	-1     : fail.
1691 */
1692int
1693pfkey_send(so, msg, len)
1694	int so;
1695	struct sadb_msg *msg;
1696	int len;
1697{
1698	if ((len = send(so, (caddr_t)msg, len, 0)) < 0) {
1699		__ipsec_set_strerror(strerror(errno));
1700		return -1;
1701	}
1702
1703	__ipsec_errcode = EIPSEC_NO_ERROR;
1704	return len;
1705}
1706
1707/*
1708 * %%% Utilities
1709 * NOTE: These functions are derived from netkey/key.c in KAME.
1710 */
1711/*
1712 * set the pointer to each header in this message buffer.
1713 * IN:	msg: pointer to message buffer.
1714 *	mhp: pointer to the buffer initialized like below:
1715 *		caddr_t mhp[SADB_EXT_MAX + 1];
1716 * OUT:	-1: invalid.
1717 *	 0: valid.
1718 *
1719 * XXX should be rewritten to obtain length explicitly
1720 */
1721int
1722pfkey_align(msg, mhp)
1723	struct sadb_msg *msg;
1724	caddr_t *mhp;
1725{
1726	struct sadb_ext *ext;
1727	int i;
1728	caddr_t p;
1729	caddr_t ep;	/* XXX should be passed from upper layer */
1730
1731	/* validity check */
1732	if (msg == NULL || mhp == NULL) {
1733		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1734		return -1;
1735	}
1736
1737	/* initialize */
1738	for (i = 0; i < SADB_EXT_MAX + 1; i++)
1739		mhp[i] = NULL;
1740
1741	mhp[0] = (caddr_t)msg;
1742
1743	/* initialize */
1744	p = (caddr_t) msg;
1745	ep = p + PFKEY_UNUNIT64(msg->sadb_msg_len);
1746
1747	/* skip base header */
1748	p += sizeof(struct sadb_msg);
1749
1750	while (p < ep) {
1751		ext = ALIGNED_CAST(struct sadb_ext *)p;
1752		if (ep < p + sizeof(*ext) || PFKEY_EXTLEN(ext) < sizeof(*ext) ||
1753		    ep < p + PFKEY_EXTLEN(ext)) {
1754			/* invalid format */
1755			break;
1756		}
1757
1758		/* duplicate check */
1759		/* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/
1760		if (mhp[ext->sadb_ext_type] != NULL) {
1761			__ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
1762			return -1;
1763		}
1764
1765		/* set pointer */
1766		switch (ext->sadb_ext_type) {
1767		case SADB_EXT_SA:
1768		case SADB_EXT_LIFETIME_CURRENT:
1769		case SADB_EXT_LIFETIME_HARD:
1770		case SADB_EXT_LIFETIME_SOFT:
1771		case SADB_EXT_ADDRESS_SRC:
1772		case SADB_EXT_ADDRESS_DST:
1773		case SADB_EXT_ADDRESS_PROXY:
1774		case SADB_EXT_KEY_AUTH:
1775			/* XXX should to be check weak keys. */
1776		case SADB_EXT_KEY_ENCRYPT:
1777			/* XXX should to be check weak keys. */
1778		case SADB_EXT_IDENTITY_SRC:
1779		case SADB_EXT_IDENTITY_DST:
1780		case SADB_EXT_SENSITIVITY:
1781		case SADB_EXT_PROPOSAL:
1782		case SADB_EXT_SUPPORTED_AUTH:
1783		case SADB_EXT_SUPPORTED_ENCRYPT:
1784		case SADB_EXT_SPIRANGE:
1785		case SADB_X_EXT_POLICY:
1786		case SADB_X_EXT_SA2:
1787			mhp[ext->sadb_ext_type] = (caddr_t)ext;
1788			break;
1789		default:
1790			__ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
1791			return -1;
1792		}
1793
1794		p += PFKEY_EXTLEN(ext);
1795	}
1796
1797	if (p != ep) {
1798		__ipsec_errcode = EIPSEC_INVAL_SADBMSG;
1799		return -1;
1800	}
1801
1802	__ipsec_errcode = EIPSEC_NO_ERROR;
1803	return 0;
1804}
1805
1806/*
1807 * check basic usage for sadb_msg,
1808 * NOTE: This routine is derived from netkey/key.c in KAME.
1809 * IN:	msg: pointer to message buffer.
1810 *	mhp: pointer to the buffer initialized like below:
1811 *
1812 *		caddr_t mhp[SADB_EXT_MAX + 1];
1813 *
1814 * OUT:	-1: invalid.
1815 *	 0: valid.
1816 */
1817int
1818pfkey_check(mhp)
1819	caddr_t *mhp;
1820{
1821	struct sadb_msg *msg;
1822
1823	/* validity check */
1824	if (mhp == NULL || mhp[0] == NULL) {
1825		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1826		return -1;
1827	}
1828
1829	msg = ALIGNED_CAST(struct sadb_msg *)mhp[0];
1830
1831	/* check version */
1832	if (msg->sadb_msg_version != PF_KEY_V2) {
1833		__ipsec_errcode = EIPSEC_INVAL_VERSION;
1834		return -1;
1835	}
1836
1837	/* check type */
1838	if (msg->sadb_msg_type > SADB_MAX) {
1839		__ipsec_errcode = EIPSEC_INVAL_MSGTYPE;
1840		return -1;
1841	}
1842
1843	/* check SA type */
1844	switch (msg->sadb_msg_satype) {
1845	case SADB_SATYPE_UNSPEC:
1846		switch (msg->sadb_msg_type) {
1847		case SADB_GETSPI:
1848		case SADB_UPDATE:
1849		case SADB_ADD:
1850		case SADB_DELETE:
1851		case SADB_GET:
1852		case SADB_ACQUIRE:
1853		case SADB_EXPIRE:
1854			__ipsec_errcode = EIPSEC_INVAL_SATYPE;
1855			return -1;
1856		}
1857		break;
1858	case SADB_SATYPE_ESP:
1859	case SADB_SATYPE_AH:
1860	case SADB_X_SATYPE_IPCOMP:
1861		switch (msg->sadb_msg_type) {
1862		case SADB_X_SPDADD:
1863		case SADB_X_SPDDELETE:
1864		case SADB_X_SPDGET:
1865		case SADB_X_SPDDUMP:
1866		case SADB_X_SPDFLUSH:
1867			__ipsec_errcode = EIPSEC_INVAL_SATYPE;
1868			return -1;
1869		}
1870		break;
1871	case SADB_SATYPE_RSVP:
1872	case SADB_SATYPE_OSPFV2:
1873	case SADB_SATYPE_RIPV2:
1874	case SADB_SATYPE_MIP:
1875		__ipsec_errcode = EIPSEC_NOT_SUPPORTED;
1876		return -1;
1877	case 1:	/* XXX: What does it do ? */
1878		if (msg->sadb_msg_type == SADB_X_PROMISC)
1879			break;
1880		/*FALLTHROUGH*/
1881	default:
1882		__ipsec_errcode = EIPSEC_INVAL_SATYPE;
1883		return -1;
1884	}
1885
1886	/* check field of upper layer protocol and address family */
1887	if (mhp[SADB_EXT_ADDRESS_SRC] != NULL
1888	 && mhp[SADB_EXT_ADDRESS_DST] != NULL) {
1889		struct sadb_address *src0, *dst0;
1890
1891		src0 = ALIGNED_CAST(struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]);
1892		dst0 = ALIGNED_CAST(struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]);
1893
1894		if (src0->sadb_address_proto != dst0->sadb_address_proto) {
1895			__ipsec_errcode = EIPSEC_PROTO_MISMATCH;
1896			return -1;
1897		}
1898
1899		if (PFKEY_ADDR_SADDR(src0)->sa_family
1900		 != PFKEY_ADDR_SADDR(dst0)->sa_family) {
1901			__ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1902			return -1;
1903		}
1904
1905		switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
1906		case AF_INET:
1907		case AF_INET6:
1908			break;
1909		default:
1910			__ipsec_errcode = EIPSEC_INVAL_FAMILY;
1911			return -1;
1912		}
1913
1914		/*
1915		 * prefixlen == 0 is valid because there must be the case
1916		 * all addresses are matched.
1917		 */
1918	}
1919
1920	__ipsec_errcode = EIPSEC_NO_ERROR;
1921	return 0;
1922}
1923
1924/*
1925 * set data into sadb_msg.
1926 * `buf' must has been allocated sufficiently.
1927 */
1928static caddr_t
1929pfkey_setsadbmsg(buf, lim, type, tlen, satype, seq, pid)
1930	caddr_t buf;
1931	caddr_t lim;
1932	u_int type, satype;
1933	u_int tlen;
1934	u_int32_t seq;
1935	pid_t pid;
1936{
1937	struct sadb_msg *p;
1938	u_int len;
1939
1940	p = ALIGNED_CAST(struct sadb_msg *)buf;
1941	len = sizeof(struct sadb_msg);
1942
1943	if (buf + len > lim)
1944		return NULL;
1945
1946	memset(p, 0, len);
1947	p->sadb_msg_version = PF_KEY_V2;
1948	p->sadb_msg_type = type;
1949	p->sadb_msg_errno = 0;
1950	p->sadb_msg_satype = satype;
1951	p->sadb_msg_len = PFKEY_UNIT64(tlen);
1952	p->sadb_msg_reserved = 0;
1953	p->sadb_msg_seq = seq;
1954	p->sadb_msg_pid = (u_int32_t)pid;
1955
1956	return(buf + len);
1957}
1958
1959/*
1960 * copy secasvar data into sadb_address.
1961 * `buf' must has been allocated sufficiently.
1962 */
1963static caddr_t
1964pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags)
1965	caddr_t buf;
1966	caddr_t lim;
1967	u_int32_t spi, flags;
1968	u_int wsize, auth, enc;
1969{
1970	struct sadb_sa *p;
1971	u_int len;
1972
1973	p = ALIGNED_CAST(struct sadb_sa *)buf;
1974	len = sizeof(struct sadb_sa);
1975
1976	if (buf + len > lim)
1977		return NULL;
1978
1979	memset(p, 0, len);
1980	p->sadb_sa_len = PFKEY_UNIT64(len);
1981	p->sadb_sa_exttype = SADB_EXT_SA;
1982	p->sadb_sa_spi = spi;
1983	p->sadb_sa_replay = wsize;
1984	p->sadb_sa_state = SADB_SASTATE_LARVAL;
1985	p->sadb_sa_auth = auth;
1986	p->sadb_sa_encrypt = enc;
1987	p->sadb_sa_flags = flags;
1988
1989	return(buf + len);
1990}
1991
1992/*
1993 * set data into sadb_address.
1994 * `buf' must has been allocated sufficiently.
1995 * prefixlen is in bits.
1996 */
1997static caddr_t
1998pfkey_setsadbaddr(buf, lim, exttype, saddr, prefixlen, ul_proto)
1999	caddr_t buf;
2000	caddr_t lim;
2001	u_int exttype;
2002	struct sockaddr *saddr;
2003	u_int prefixlen;
2004	u_int ul_proto;
2005{
2006	struct sadb_address *p;
2007	u_int len;
2008
2009	p = ALIGNED_CAST(struct sadb_address *)buf;
2010	len = sizeof(struct sadb_address) + PFKEY_ALIGN8(saddr->sa_len);
2011
2012	if (buf + len > lim)
2013		return NULL;
2014
2015	memset(p, 0, len);
2016	p->sadb_address_len = PFKEY_UNIT64(len);
2017	p->sadb_address_exttype = exttype & 0xffff;
2018	p->sadb_address_proto = ul_proto & 0xff;
2019	p->sadb_address_prefixlen = prefixlen;
2020	p->sadb_address_reserved = 0;
2021
2022	memcpy(p + 1, saddr, saddr->sa_len);
2023
2024	return(buf + len);
2025}
2026
2027/*
2028 * set sadb_key structure after clearing buffer with zero.
2029 * OUT: the pointer of buf + len.
2030 */
2031static caddr_t
2032pfkey_setsadbkey(buf, lim, type, key, keylen)
2033	caddr_t buf;
2034	caddr_t lim;
2035	caddr_t key;
2036	u_int type, keylen;
2037{
2038	struct sadb_key *p;
2039	u_int len;
2040
2041	p = ALIGNED_CAST(struct sadb_key *)buf;
2042	len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen);
2043
2044	if (buf + len > lim)
2045		return NULL;
2046
2047	memset(p, 0, len);
2048	p->sadb_key_len = PFKEY_UNIT64(len);
2049	p->sadb_key_exttype = type;
2050	p->sadb_key_bits = keylen << 3;
2051	p->sadb_key_reserved = 0;
2052
2053	memcpy(p + 1, key, keylen);
2054
2055	return buf + len;
2056}
2057
2058/*
2059 * set sadb_lifetime structure after clearing buffer with zero.
2060 * OUT: the pointer of buf + len.
2061 */
2062static caddr_t
2063pfkey_setsadblifetime(buf, lim, type, l_alloc, l_bytes, l_addtime, l_usetime)
2064	caddr_t buf;
2065	caddr_t lim;
2066	u_int type;
2067	u_int32_t l_alloc, l_bytes, l_addtime, l_usetime;
2068{
2069	struct sadb_lifetime *p;
2070	u_int len;
2071
2072	p = ALIGNED_CAST(struct sadb_lifetime *)buf;
2073	len = sizeof(struct sadb_lifetime);
2074
2075	if (buf + len > lim)
2076		return NULL;
2077
2078	memset(p, 0, len);
2079	p->sadb_lifetime_len = PFKEY_UNIT64(len);
2080	p->sadb_lifetime_exttype = type;
2081
2082	switch (type) {
2083	case SADB_EXT_LIFETIME_SOFT:
2084		p->sadb_lifetime_allocations
2085			= (l_alloc * soft_lifetime_allocations_rate) /100;
2086		p->sadb_lifetime_bytes
2087			= (l_bytes * soft_lifetime_bytes_rate) /100;
2088		p->sadb_lifetime_addtime
2089			= (l_addtime * soft_lifetime_addtime_rate) /100;
2090		p->sadb_lifetime_usetime
2091			= (l_usetime * soft_lifetime_usetime_rate) /100;
2092		break;
2093	case SADB_EXT_LIFETIME_HARD:
2094		p->sadb_lifetime_allocations = l_alloc;
2095		p->sadb_lifetime_bytes = l_bytes;
2096		p->sadb_lifetime_addtime = l_addtime;
2097		p->sadb_lifetime_usetime = l_usetime;
2098		break;
2099	}
2100
2101	return buf + len;
2102}
2103
2104/*
2105 * copy secasvar data into sadb_address.
2106 * `buf' must has been allocated sufficiently.
2107 */
2108static caddr_t
2109pfkey_setsadbxsa2(buf, lim, mode0, reqid)
2110	caddr_t buf;
2111	caddr_t lim;
2112	u_int32_t mode0;
2113	u_int32_t reqid;
2114{
2115	struct sadb_x_sa2 *p;
2116	u_int8_t mode = mode0 & 0xff;
2117	u_int len;
2118
2119	p = ALIGNED_CAST(struct sadb_x_sa2 *)buf;
2120	len = sizeof(struct sadb_x_sa2);
2121
2122	if (buf + len > lim)
2123		return NULL;
2124
2125	memset(p, 0, len);
2126	p->sadb_x_sa2_len = PFKEY_UNIT64(len);
2127	p->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
2128	p->sadb_x_sa2_mode = mode;
2129	p->sadb_x_sa2_reqid = reqid;
2130
2131	return(buf + len);
2132}
2133