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