pfkey.c revision 55505
1/*
2 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 *    may be used to endorse or promote products derived from this software
15 *    without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $FreeBSD: head/lib/libipsec/pfkey.c 55505 2000-01-06 12:40:54Z shin $
30 */
31
32#ifndef lint
33static char *rcsid = "@(#) pfkey.c $Revision: 1.10 $";
34#endif
35
36#include <sys/types.h>
37#include <sys/param.h>
38#include <sys/socket.h>
39#include <net/pfkeyv2.h>
40#include <netkey/key_var.h>
41#include <netinet/in.h>
42#include <netinet6/in6.h>
43#include <netinet6/ipsec.h>
44
45#include <stdlib.h>
46#include <unistd.h>
47#include <string.h>
48#include <errno.h>
49
50#include "ipsec_strerror.h"
51
52#define	CALLOC(size, cast) (cast)calloc(1, (size))
53
54static int pfkey_send_x1 __P((int so, u_int type, u_int satype, u_int mode,
55	struct sockaddr *src, struct sockaddr *dst, u_int32_t spi, u_int wsize,
56	caddr_t keymat,
57	u_int e_type, u_int e_keylen, u_int a_type, u_int a_keylen,
58	u_int flags,
59	u_int32_t l_alloc, u_int32_t l_bytes,
60	u_int32_t l_addtime, u_int32_t l_usetime, u_int32_t seq));
61static int pfkey_send_x2 __P((int so, u_int type, u_int satype, u_int mode,
62	struct sockaddr *src, struct sockaddr *dst, u_int32_t spi));
63static int pfkey_send_x3 __P((int so, u_int type, u_int satype));
64
65static caddr_t pfkey_setsadbmsg __P((caddr_t buf, u_int type, u_int tlen,
66	u_int satype, u_int mode, u_int32_t seq, pid_t pid));
67static caddr_t pfkey_setsadbsa __P((caddr_t buf, u_int32_t spi, u_int wsize,
68	u_int auth, u_int enc, u_int32_t flags));
69static caddr_t pfkey_setsadbaddr __P((caddr_t buf, u_int exttype,
70	struct sockaddr *saddr, u_int prefixlen, u_int ul_proto));
71static caddr_t pfkey_setsadbkey(caddr_t buf, u_int type,
72	caddr_t key, u_int keylen);
73static caddr_t pfkey_setsadblifetime(caddr_t buf, u_int type,
74	u_int32_t l_alloc, u_int32_t l_bytes,
75	u_int32_t l_addtime, u_int32_t l_usetime);
76
77/*
78 * check key length against algorithm specified.
79 * supported is either SADB_EXT_SUPPORTED_ENCRYPT or SADB_EXT_SUPPORTED_AUTH.
80 * Refer to keyv2.h to get more info.
81 * keylen is the unit of bit.
82 * OUT:
83 *	-1: invalid.
84 *	 0: valid.
85 */
86struct sadb_msg *ipsec_supported = NULL;
87
88int
89ipsec_check_keylen(supported, alg_id, keylen)
90	u_int supported;
91	u_int alg_id;
92	u_int keylen;
93{
94	u_int tlen;
95	caddr_t p;
96	struct sadb_supported *sup;
97	struct sadb_alg *alg;
98
99	/* validity check */
100	if (ipsec_supported == NULL) {
101		ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST;
102		return -1;
103	}
104	switch (supported) {
105	case SADB_EXT_SUPPORTED_AUTH:
106	case SADB_EXT_SUPPORTED_ENCRYPT:
107		break;
108	default:
109		ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
110		return -1;
111	}
112
113	tlen = ipsec_supported->sadb_msg_len - sizeof(struct sadb_msg);
114	p = (caddr_t)ipsec_supported + sizeof(struct sadb_msg);
115
116	for (;
117	     tlen > 0;
118	     tlen -= sup->sadb_supported_len, p += sup->sadb_supported_len) {
119
120		sup = (struct sadb_supported *)p;
121
122		if (sup->sadb_supported_exttype != supported)
123			continue;
124
125	    {
126		u_int ttlen = sup->sadb_supported_len;
127		caddr_t pp = p + sizeof(*sup);
128
129		for (;
130		     ttlen > 0;
131	     	     ttlen -= sizeof(*alg), pp += sizeof(*alg)) {
132			alg = (struct sadb_alg *)pp;
133
134			if (alg->sadb_alg_id == alg_id)
135				goto found;
136	    	}
137	    }
138	}
139
140	ipsec_errcode = EIPSEC_NOT_SUPPORTED;
141	return -1;
142	/* NOTREACHED */
143
144    found:
145	if (keylen < alg->sadb_alg_minbits
146	 || keylen > alg->sadb_alg_maxbits) {
147		ipsec_errcode = EIPSEC_INVAL_KEYLEN;
148		return -1;
149	}
150
151	ipsec_errcode = EIPSEC_NO_ERROR;
152	return 0;
153}
154
155/*
156 * set the rate for SOFT lifetime against HARD one.
157 * If rate is more than 100 or equal to zero, then set to 100.
158 */
159static u_int soft_lifetime_allocations_rate = PFKEY_SOFT_LIFETIME_RATE;
160static u_int soft_lifetime_bytes_rate = PFKEY_SOFT_LIFETIME_RATE;
161static u_int soft_lifetime_addtime_rate = PFKEY_SOFT_LIFETIME_RATE;
162static u_int soft_lifetime_usetime_rate = PFKEY_SOFT_LIFETIME_RATE;
163
164u_int
165pfkey_set_softrate(type, rate)
166	u_int type, rate;
167{
168	ipsec_errcode = EIPSEC_NO_ERROR;
169
170	if (rate > 100 || rate == 0)
171		rate = 100;
172
173	switch (type) {
174	case SADB_X_LIFETIME_ALLOCATIONS:
175		soft_lifetime_allocations_rate = rate;
176		return 0;
177	case SADB_X_LIFETIME_BYTES:
178		soft_lifetime_bytes_rate = rate;
179		return 0;
180	case SADB_X_LIFETIME_ADDTIME:
181		soft_lifetime_addtime_rate = rate;
182		return 0;
183	case SADB_X_LIFETIME_USETIME:
184		soft_lifetime_usetime_rate = rate;
185		return 0;
186	}
187
188	ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
189	return 1;
190}
191
192/*
193 * get current rate for SOFT lifetime against HARD one.
194 * ATTENTION: ~0 is returned if invalid type was passed.
195 */
196u_int
197pfkey_get_softrate(type)
198	u_int type;
199{
200	switch (type) {
201	case SADB_X_LIFETIME_ALLOCATIONS:
202		return soft_lifetime_allocations_rate;
203	case SADB_X_LIFETIME_BYTES:
204		return soft_lifetime_bytes_rate;
205	case SADB_X_LIFETIME_ADDTIME:
206		return soft_lifetime_addtime_rate;
207	case SADB_X_LIFETIME_USETIME:
208		return soft_lifetime_usetime_rate;
209	}
210
211	return ~0;
212}
213
214/*
215 * sending SADB_GETSPI message to the kernel.
216 * OUT:
217 *	positive: success and return length sent.
218 *	-1	: error occured, and set errno.
219 */
220int
221pfkey_send_getspi(so, satype, mode, src, dst, min, max, seq)
222	int so;
223	u_int satype, mode;
224	struct sockaddr *src, *dst;
225	u_int32_t min, max, seq;
226{
227	struct sadb_msg *newmsg;
228	int len;
229	int need_spirange = 0;
230	caddr_t p;
231
232	/* validity check */
233	if (src == NULL || dst == NULL) {
234		ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
235		return -1;
236	}
237	if (src->sa_family != dst->sa_family) {
238		ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
239		return -1;
240	}
241	if (min > max || (min > 0 && min <= 255)) {
242		ipsec_errcode = EIPSEC_INVAL_SPI;
243		return -1;
244	}
245
246	/* create new sadb_msg to send. */
247	len = sizeof(struct sadb_msg)
248		+ sizeof(struct sadb_address)
249		+ PFKEY_ALIGN8(src->sa_len)
250		+ sizeof(struct sadb_address)
251		+ PFKEY_ALIGN8(dst->sa_len);
252
253	if (min > 255 && max < ~0) {
254		need_spirange++;
255		len += sizeof(struct sadb_spirange);
256	}
257
258	if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
259		ipsec_set_strerror(strerror(errno));
260		return -1;
261	}
262
263	p = pfkey_setsadbmsg((caddr_t)newmsg, SADB_GETSPI,
264	                     len, satype, mode, seq, getpid());
265
266	/* set sadb_address for source */
267	p = pfkey_setsadbaddr(p,
268	                      SADB_EXT_ADDRESS_SRC,
269	                      src,
270	                      _INALENBYAF(src->sa_family) << 3,
271	                      IPSEC_ULPROTO_ANY);
272
273	/* set sadb_address for destination */
274	p = pfkey_setsadbaddr(p,
275	                      SADB_EXT_ADDRESS_DST,
276	                      dst,
277	                      _INALENBYAF(dst->sa_family) << 3,
278	                      IPSEC_ULPROTO_ANY);
279
280	/* proccessing spi range */
281	if (need_spirange) {
282		int _len = sizeof(struct sadb_spirange);
283
284#define	_SADB_SPIRANGE(p) ((struct sadb_spirange *)(p))
285		_SADB_SPIRANGE(p)->sadb_spirange_len = PFKEY_UNIT64(_len);
286		_SADB_SPIRANGE(p)->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
287		_SADB_SPIRANGE(p)->sadb_spirange_min = min;
288		_SADB_SPIRANGE(p)->sadb_spirange_max = max;
289#undef _SADB_SPIRANGE(p)
290		p += _len;
291	}
292
293	/* send message */
294	len = pfkey_send(so, newmsg, len);
295	free(newmsg);
296
297	if (len < 0)
298		return -1;
299
300	ipsec_errcode = EIPSEC_NO_ERROR;
301	return len;
302}
303
304/*
305 * sending SADB_UPDATE message to the kernel.
306 * The length of key material is a_keylen + e_keylen.
307 * OUT:
308 *	positive: success and return length sent.
309 *	-1	: error occured, and set errno.
310 */
311int
312pfkey_send_update(so, satype, mode, src, dst, spi, wsize,
313		keymat, e_type, e_keylen, a_type, a_keylen, flags,
314		l_alloc, l_bytes, l_addtime, l_usetime, seq)
315	int so;
316	u_int satype, mode, wsize;
317	struct sockaddr *src, *dst;
318	u_int32_t spi;
319	caddr_t keymat;
320	u_int e_type, e_keylen, a_type, a_keylen, flags;
321	u_int32_t l_alloc;
322	u_int64_t l_bytes, l_addtime, l_usetime;
323	u_int32_t seq;
324{
325	int len;
326	if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi,
327			wsize, keymat, e_type, e_keylen, a_type, a_keylen, flags,
328			l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0)
329		return -1;
330
331	return len;
332}
333
334/*
335 * sending SADB_ADD message to the kernel.
336 * The length of key material is a_keylen + e_keylen.
337 * OUT:
338 *	positive: success and return length sent.
339 *	-1	: error occured, and set errno.
340 */
341int
342pfkey_send_add(so, satype, mode, src, dst, spi, wsize,
343		keymat, e_type, e_keylen, a_type, a_keylen, flags,
344		l_alloc, l_bytes, l_addtime, l_usetime, seq)
345	int so;
346	u_int satype, mode, wsize;
347	struct sockaddr *src, *dst;
348	u_int32_t spi;
349	caddr_t keymat;
350	u_int e_type, e_keylen, a_type, a_keylen, flags;
351	u_int32_t l_alloc;
352	u_int64_t l_bytes, l_addtime, l_usetime;
353	u_int32_t seq;
354{
355	int len;
356	if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi,
357			wsize, keymat, e_type, e_keylen, a_type, a_keylen, flags,
358			l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0)
359		return -1;
360
361	return len;
362}
363
364/*
365 * sending SADB_DELETE message to the kernel.
366 * OUT:
367 *	positive: success and return length sent.
368 *	-1	: error occured, and set errno.
369 */
370int
371pfkey_send_delete(so, satype, mode, src, dst, spi)
372	int so;
373	u_int satype, mode;
374	struct sockaddr *src, *dst;
375	u_int32_t spi;
376{
377	int len;
378	if ((len = pfkey_send_x2(so, SADB_DELETE, satype, mode, src, dst, spi)) < 0)
379		return -1;
380
381	return len;
382}
383
384/*
385 * sending SADB_GET message to the kernel.
386 * OUT:
387 *	positive: success and return length sent.
388 *	-1	: error occured, and set errno.
389 */
390int
391pfkey_send_get(so, satype, mode, src, dst, spi)
392	int so;
393	u_int satype, mode;
394	struct sockaddr *src, *dst;
395	u_int32_t spi;
396{
397	int len;
398	if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0)
399		return -1;
400
401	return len;
402}
403
404/*
405 * sending SADB_REGISTER message to the kernel.
406 * OUT:
407 *	positive: success and return length sent.
408 *	-1	: error occured, and set errno.
409 */
410int
411pfkey_send_register(so, satype)
412	int so;
413	u_int satype;
414{
415	int len;
416
417	if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0)
418		return -1;
419
420	return len;
421}
422
423/*
424 * receiving SADB_REGISTER message from the kernel, and copy buffer for
425 * sadb_supported returned into ipsec_supported.
426 * OUT:
427 *	 0: success and return length sent.
428 *	-1: error occured, and set errno.
429 */
430int
431pfkey_recv_register(so)
432	int so;
433{
434	pid_t pid = getpid();
435	struct sadb_msg *newmsg;
436	struct sadb_supported *sup;
437	caddr_t p;
438	int tlen;
439
440	/* receive message */
441	do {
442		if ((newmsg = pfkey_recv(so)) == NULL)
443			return -1;
444
445	} while (newmsg->sadb_msg_type != SADB_REGISTER
446	    || newmsg->sadb_msg_pid != pid);
447
448	/* check and fix */
449	newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len);
450
451	tlen = newmsg->sadb_msg_len - sizeof(struct sadb_msg);
452	p = (caddr_t)newmsg + sizeof(struct sadb_msg);
453	while (tlen > 0) {
454		sup = (struct sadb_supported *)p;
455		switch (sup->sadb_supported_exttype) {
456		case SADB_EXT_SUPPORTED_AUTH:
457		case SADB_EXT_SUPPORTED_ENCRYPT:
458			sup->sadb_supported_len = PFKEY_EXTLEN(sup);
459			break;
460		default:
461			ipsec_errcode = EIPSEC_INVAL_SATYPE;
462			free(newmsg);
463			return -1;
464		}
465
466		tlen -= sup->sadb_supported_len;
467		p += sup->sadb_supported_len;
468	}
469
470	if (tlen < 0) {
471		ipsec_errcode = EIPSEC_INVAL_SATYPE;
472		return -1;
473	}
474
475	if (ipsec_supported != NULL)
476		free(ipsec_supported);
477
478	ipsec_supported = newmsg;
479
480	ipsec_errcode = EIPSEC_NO_ERROR;
481	return 0;
482}
483
484/*
485 * sending SADB_FLUSH message to the kernel.
486 * OUT:
487 *	positive: success and return length sent.
488 *	-1	: error occured, and set errno.
489 */
490int
491pfkey_send_flush(so, satype)
492	int so;
493	u_int satype;
494{
495	int len;
496
497	if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0)
498		return -1;
499
500	return len;
501}
502
503/*
504 * sending SADB_DUMP message to the kernel.
505 * OUT:
506 *	positive: success and return length sent.
507 *	-1	: error occured, and set errno.
508 */
509int
510pfkey_send_dump(so, satype)
511	int so;
512	u_int satype;
513{
514	int len;
515
516	if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0)
517		return -1;
518
519	return len;
520}
521
522/*
523 * sending SADB_X_PROMISC message to the kernel.
524 * NOTE that this function handles promisc mode toggle only.
525 * IN:
526 *	flag:	set promisc off if zero, set promisc on if non-zero.
527 * OUT:
528 *	positive: success and return length sent.
529 *	-1	: error occured, and set errno.
530 *	0     : error occured, and set errno.
531 *	others: a pointer to new allocated buffer in which supported
532 *	        algorithms is.
533 */
534int
535pfkey_send_promisc_toggle(so, flag)
536	int so;
537	int flag;
538{
539	int len;
540
541	if ((len = pfkey_send_x3(so, SADB_X_PROMISC, (flag ? 1 : 0))) < 0)
542		return -1;
543
544	return len;
545}
546
547/*
548 * sending SADB_X_SPDADD message to the kernel.
549 * The length of key material is a_keylen + e_keylen.
550 * OUT:
551 *	positive: success and return length sent.
552 *	-1	: error occured, and set errno.
553 */
554int
555pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
556	int so;
557	struct sockaddr *src, *dst;
558	u_int prefs, prefd, proto;
559	char *policy;
560	int policylen;
561	u_int32_t seq;
562{
563	struct sadb_msg *newmsg;
564	int len;
565	caddr_t p;
566
567	/* validity check */
568	if (src == NULL || dst == NULL) {
569		ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
570		return -1;
571	}
572	if (src->sa_family != dst->sa_family) {
573		ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
574		return -1;
575	}
576	if (prefs > (_INALENBYAF(src->sa_family) << 3)
577	 || prefd > (_INALENBYAF(dst->sa_family) << 3)) {
578		ipsec_errcode = EIPSEC_INVAL_PREFIXLEN;
579		return -1;
580	}
581
582	/* create new sadb_msg to reply. */
583	len = sizeof(struct sadb_msg)
584		+ sizeof(struct sadb_address)
585		+ PFKEY_ALIGN8(_SALENBYAF(src->sa_family))
586		+ sizeof(struct sadb_address)
587		+ PFKEY_ALIGN8(_SALENBYAF(src->sa_family))
588		+ policylen;
589
590	if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
591		ipsec_set_strerror(strerror(errno));
592		return -1;
593	}
594
595	p = pfkey_setsadbmsg((caddr_t)newmsg, SADB_X_SPDADD, len,
596	                     SADB_SATYPE_UNSPEC, IPSEC_MODE_ANY, seq, getpid());
597	p = pfkey_setsadbaddr(p,
598	                      SADB_EXT_ADDRESS_SRC,
599	                      src,
600	                      prefs,
601	                      proto);
602	p = pfkey_setsadbaddr(p,
603	                      SADB_EXT_ADDRESS_DST,
604	                      dst,
605	                      prefd,
606	                      proto);
607	memcpy(p, policy, policylen);
608
609	/* send message */
610	len = pfkey_send(so, newmsg, len);
611	free(newmsg);
612
613	if (len < 0)
614		return -1;
615
616	ipsec_errcode = EIPSEC_NO_ERROR;
617	return len;
618}
619
620/*
621 * sending SADB_X_SPDDELETE message to the kernel.
622 * The length of key material is a_keylen + e_keylen.
623 * OUT:
624 *	positive: success and return length sent.
625 *	-1	: error occured, and set errno.
626 */
627int
628pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, seq)
629	int so;
630	struct sockaddr *src, *dst;
631	u_int prefs, prefd, proto;
632	u_int32_t seq;
633{
634	struct sadb_msg *newmsg;
635	int len;
636	caddr_t p;
637
638	/* validity check */
639	if (src == NULL || dst == NULL) {
640		ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
641		return -1;
642	}
643	if (src->sa_family != dst->sa_family) {
644		ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
645		return -1;
646	}
647	if (prefs > (_INALENBYAF(src->sa_family) << 3)
648	 || prefd > (_INALENBYAF(dst->sa_family) << 3)) {
649		ipsec_errcode = EIPSEC_INVAL_PREFIXLEN;
650		return -1;
651	}
652
653	/* create new sadb_msg to reply. */
654	len = sizeof(struct sadb_msg)
655		+ sizeof(struct sadb_address)
656		+ PFKEY_ALIGN8(_SALENBYAF(src->sa_family))
657		+ sizeof(struct sadb_address)
658		+ PFKEY_ALIGN8(_SALENBYAF(src->sa_family));
659
660	if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
661		ipsec_set_strerror(strerror(errno));
662		return -1;
663	}
664
665	p = pfkey_setsadbmsg((caddr_t)newmsg, SADB_X_SPDDELETE, len,
666	                     SADB_SATYPE_UNSPEC, IPSEC_MODE_ANY, seq, getpid());
667	p = pfkey_setsadbaddr(p,
668	                      SADB_EXT_ADDRESS_SRC,
669	                      src,
670	                      prefs,
671	                      proto);
672	p = pfkey_setsadbaddr(p,
673	                      SADB_EXT_ADDRESS_DST,
674	                      dst,
675	                      prefd,
676	                      proto);
677
678	/* send message */
679	len = pfkey_send(so, newmsg, len);
680	free(newmsg);
681
682	if (len < 0)
683		return -1;
684
685	ipsec_errcode = EIPSEC_NO_ERROR;
686	return len;
687}
688
689/*
690 * sending SADB_SPDFLUSH message to the kernel.
691 * OUT:
692 *	positive: success and return length sent.
693 *	-1	: error occured, and set errno.
694 */
695int
696pfkey_send_spdflush(so)
697	int so;
698{
699	int len;
700
701	if ((len = pfkey_send_x3(so, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC)) < 0)
702		return -1;
703
704	return len;
705}
706
707/*
708 * sending SADB_SPDDUMP message to the kernel.
709 * OUT:
710 *	positive: success and return length sent.
711 *	-1	: error occured, and set errno.
712 */
713int
714pfkey_send_spddump(so)
715	int so;
716{
717	int len;
718
719	if ((len = pfkey_send_x3(so, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC)) < 0)
720		return -1;
721
722	return len;
723}
724
725/* sending SADB_ADD or SADB_UPDATE message to the kernel */
726static int
727pfkey_send_x1(so, type, satype, mode, src, dst, spi, wsize,
728		keymat, e_type, e_keylen, a_type, a_keylen, flags,
729		l_alloc, l_bytes, l_addtime, l_usetime, seq)
730	int so;
731	u_int type, satype, mode;
732	struct sockaddr *src, *dst;
733	u_int32_t spi;
734	u_int wsize;
735	caddr_t keymat;
736	u_int e_type, e_keylen, a_type, a_keylen, flags;
737	u_int32_t l_alloc, l_bytes, l_addtime, l_usetime, seq;
738{
739	struct sadb_msg *newmsg;
740	int len;
741	caddr_t p;
742
743	/* validity check */
744	if (src == NULL || dst == NULL) {
745		ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
746		return -1;
747	}
748	if (src->sa_family != dst->sa_family) {
749		ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
750		return -1;
751	}
752
753	switch (satype) {
754	case SADB_SATYPE_ESP:
755		if (e_type == SADB_EALG_NONE) {
756			ipsec_errcode = EIPSEC_NO_ALGS;
757			return -1;
758		}
759		break;
760	case SADB_SATYPE_AH:
761		if (e_type != SADB_EALG_NONE) {
762			ipsec_errcode = EIPSEC_INVAL_ALGS;
763			return -1;
764		}
765		if (a_type == SADB_AALG_NONE) {
766			ipsec_errcode = EIPSEC_NO_ALGS;
767			return -1;
768		}
769		break;
770	case SADB_X_SATYPE_IPCOMP:
771		break;
772	default:
773		ipsec_errcode = EIPSEC_INVAL_SATYPE;
774		return -1;
775	}
776
777	/* create new sadb_msg to reply. */
778	len = sizeof(struct sadb_msg)
779		+ sizeof(struct sadb_sa)
780		+ sizeof(struct sadb_address)
781		+ PFKEY_ALIGN8(src->sa_len)
782		+ sizeof(struct sadb_address)
783		+ PFKEY_ALIGN8(dst->sa_len)
784		+ sizeof(struct sadb_lifetime)
785		+ sizeof(struct sadb_lifetime);
786
787	if (e_type != SADB_EALG_NONE)
788		len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen));
789	if (a_type != SADB_AALG_NONE)
790		len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(a_keylen));
791
792	if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
793		ipsec_set_strerror(strerror(errno));
794		return -1;
795	}
796
797	p = pfkey_setsadbmsg((caddr_t)newmsg, type, len,
798	                     satype, mode, seq, getpid());
799	p = pfkey_setsadbsa(p, spi, wsize, a_type, e_type, flags);
800	p = pfkey_setsadbaddr(p,
801	                      SADB_EXT_ADDRESS_SRC,
802	                      src,
803	                      _INALENBYAF(src->sa_family) << 3,
804	                      IPSEC_ULPROTO_ANY);
805	p = pfkey_setsadbaddr(p,
806	                      SADB_EXT_ADDRESS_DST,
807	                      dst,
808	                      _INALENBYAF(dst->sa_family) << 3,
809	                      IPSEC_ULPROTO_ANY);
810
811	if (e_type != SADB_EALG_NONE)
812		p = pfkey_setsadbkey(p, SADB_EXT_KEY_ENCRYPT,
813		                   keymat, e_keylen);
814	if (a_type != SADB_AALG_NONE)
815		p = pfkey_setsadbkey(p, SADB_EXT_KEY_AUTH,
816		                   keymat + e_keylen, a_keylen);
817
818	/* set sadb_lifetime for destination */
819	p = pfkey_setsadblifetime(p, SADB_EXT_LIFETIME_HARD,
820			l_alloc, l_bytes, l_addtime, l_usetime);
821	p = pfkey_setsadblifetime(p, SADB_EXT_LIFETIME_SOFT,
822			l_alloc, l_bytes, l_addtime, l_usetime);
823
824	/* send message */
825	len = pfkey_send(so, newmsg, len);
826	free(newmsg);
827
828	if (len < 0)
829		return -1;
830
831	ipsec_errcode = EIPSEC_NO_ERROR;
832	return len;
833}
834
835/* sending SADB_DELETE or SADB_GET message to the kernel */
836static int
837pfkey_send_x2(so, type, satype, mode, src, dst, spi)
838	int so;
839	u_int type, satype, mode;
840	struct sockaddr *src, *dst;
841	u_int32_t spi;
842{
843	struct sadb_msg *newmsg;
844	int len;
845	caddr_t p;
846
847	/* validity check */
848	if (src == NULL || dst == NULL) {
849		ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
850		return -1;
851	}
852	if (src->sa_family != dst->sa_family) {
853		ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
854		return -1;
855	}
856
857	/* create new sadb_msg to reply. */
858	len = sizeof(struct sadb_msg)
859		+ sizeof(struct sadb_sa)
860		+ sizeof(struct sadb_address)
861		+ PFKEY_ALIGN8(src->sa_len)
862		+ sizeof(struct sadb_address)
863		+ PFKEY_ALIGN8(dst->sa_len);
864
865	if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
866		ipsec_set_strerror(strerror(errno));
867		return -1;
868	}
869
870	p = pfkey_setsadbmsg((caddr_t)newmsg, type, len, satype, mode, 0, getpid());
871	p = pfkey_setsadbsa(p, spi, 0, 0, 0, 0);
872	p = pfkey_setsadbaddr(p,
873	                      SADB_EXT_ADDRESS_SRC,
874	                      src,
875	                      _INALENBYAF(src->sa_family) << 3,
876	                      IPSEC_ULPROTO_ANY);
877	p = pfkey_setsadbaddr(p,
878	                      SADB_EXT_ADDRESS_DST,
879	                      dst,
880	                      _INALENBYAF(dst->sa_family) << 3,
881	                      IPSEC_ULPROTO_ANY);
882
883	/* send message */
884	len = pfkey_send(so, newmsg, len);
885	free(newmsg);
886
887	if (len < 0)
888		return -1;
889
890	ipsec_errcode = EIPSEC_NO_ERROR;
891	return len;
892}
893
894/*
895 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message
896 * to the kernel
897 */
898static int
899pfkey_send_x3(so, type, satype)
900	int so;
901	u_int type, satype;
902{
903	struct sadb_msg *newmsg;
904	int len;
905
906	/* validity check */
907	switch (type) {
908	case SADB_X_PROMISC:
909		if (satype != 0 && satype != 1) {
910			ipsec_errcode = EIPSEC_INVAL_SATYPE;
911			return -1;
912		}
913		break;
914	default:
915		switch (satype) {
916		case SADB_SATYPE_UNSPEC:
917		case SADB_SATYPE_AH:
918		case SADB_SATYPE_ESP:
919		case SADB_X_SATYPE_IPCOMP:
920			break;
921		default:
922			ipsec_errcode = EIPSEC_INVAL_SATYPE;
923			return -1;
924		}
925	}
926
927	/* create new sadb_msg to send. */
928	len = sizeof(struct sadb_msg);
929
930	if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
931		ipsec_set_strerror(strerror(errno));
932		return -1;
933	}
934
935	(void)pfkey_setsadbmsg((caddr_t)newmsg, type, len, satype, 0, 0, getpid());
936
937	/* send message */
938	len = pfkey_send(so, newmsg, len);
939	free(newmsg);
940
941	if (len < 0)
942		return -1;
943
944	ipsec_errcode = EIPSEC_NO_ERROR;
945	return len;
946}
947
948/*
949 * open a socket.
950 * OUT:
951 *	-1: fail.
952 *	others : success and return value of socket.
953 */
954int
955pfkey_open()
956{
957	int so;
958	const int bufsiz = 128 * 1024;	/*is 128K enough?*/
959
960	if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) {
961		ipsec_set_strerror(strerror(errno));
962		return -1;
963	}
964
965	/*
966	 * This is a temporary workaround for KAME PR 154.
967	 * Don't really care even if it fails.
968	 */
969	(void)setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz));
970	(void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz));
971
972	ipsec_errcode = EIPSEC_NO_ERROR;
973	return so;
974}
975
976/*
977 * close a socket.
978 * OUT:
979 *	 0: success.
980 *	-1: fail.
981 */
982void
983pfkey_close(so)
984	int so;
985{
986	(void)close(so);
987
988	ipsec_errcode = EIPSEC_NO_ERROR;
989	return;
990}
991
992/*
993 * receive sadb_msg data, and return pointer to new buffer allocated.
994 * Must free this buffer later.
995 * OUT:
996 *	NULL	: error occured.
997 *	others	: a pointer to sadb_msg structure.
998 */
999struct sadb_msg *
1000pfkey_recv(so)
1001	int so;
1002{
1003	struct sadb_msg buf, *newmsg;
1004	int len, reallen;
1005
1006	while ((len = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK)) < 0) {
1007		if (errno == EINTR) continue;
1008		ipsec_set_strerror(strerror(errno));
1009		return NULL;
1010	}
1011
1012	if (len < sizeof(buf)) {
1013		recv(so, (caddr_t)&buf, sizeof(buf), 0);
1014		ipsec_errcode = EIPSEC_MAX;
1015		return NULL;
1016	}
1017
1018	/* read real message */
1019	reallen = PFKEY_UNUNIT64(buf.sadb_msg_len);
1020	if ((newmsg = CALLOC(reallen, struct sadb_msg *)) == 0) {
1021		ipsec_set_strerror(strerror(errno));
1022		return NULL;
1023	}
1024
1025	while ((len = recv(so, (caddr_t)newmsg, reallen, 0)) < 0) {
1026		if (errno == EINTR) continue;
1027		ipsec_set_strerror(strerror(errno));
1028		free(newmsg);
1029		return NULL;
1030	}
1031
1032	if (len != reallen) {
1033		ipsec_errcode = EIPSEC_SYSTEM_ERROR;
1034		free(newmsg);
1035		return NULL;
1036	}
1037
1038	ipsec_errcode = EIPSEC_NO_ERROR;
1039	return newmsg;
1040}
1041
1042/*
1043 * send message to a socket.
1044 * OUT:
1045 *	 others: success and return length sent.
1046 *	-1     : fail.
1047 */
1048int
1049pfkey_send(so, msg, len)
1050	int so;
1051	struct sadb_msg *msg;
1052	int len;
1053{
1054	if ((len = send(so, (caddr_t)msg, len, 0)) < 0) {
1055		ipsec_set_strerror(strerror(errno));
1056		return -1;
1057	}
1058
1059	ipsec_errcode = EIPSEC_NO_ERROR;
1060	return len;
1061}
1062
1063/*
1064 * %%% Utilities
1065 * NOTE: These functions are derived from netkey/key.c in KAME.
1066 */
1067/*
1068 * set the pointer to each header in this message buffer.
1069 * IN:	msg: pointer to message buffer.
1070 *	mhp: pointer to the buffer initialized like below:
1071 *		caddr_t mhp[SADB_EXT_MAX + 1];
1072 * OUT:	-1: invalid.
1073 *	 0: valid.
1074 */
1075int
1076pfkey_align(msg, mhp)
1077	struct sadb_msg *msg;
1078	caddr_t *mhp;
1079{
1080	struct sadb_ext *ext;
1081	int tlen, extlen;
1082	int i;
1083
1084	/* validity check */
1085	if (msg == NULL || mhp == NULL) {
1086		ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1087		return -1;
1088	}
1089
1090	/* initialize */
1091	for (i = 0; i < SADB_EXT_MAX + 1; i++)
1092		mhp[i] = NULL;
1093
1094	mhp[0] = (caddr_t)msg;
1095
1096	tlen = PFKEY_UNUNIT64(msg->sadb_msg_len) - sizeof(struct sadb_msg);
1097	ext = (struct sadb_ext *)((caddr_t)msg + sizeof(struct sadb_msg));
1098
1099	while (tlen > 0) {
1100		/* duplicate check */
1101		/* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/
1102		if (mhp[ext->sadb_ext_type] != NULL) {
1103			ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
1104			return -1;
1105		}
1106
1107		/* set pointer */
1108		switch (ext->sadb_ext_type) {
1109		case SADB_EXT_SA:
1110		case SADB_EXT_LIFETIME_CURRENT:
1111		case SADB_EXT_LIFETIME_HARD:
1112		case SADB_EXT_LIFETIME_SOFT:
1113		case SADB_EXT_ADDRESS_SRC:
1114		case SADB_EXT_ADDRESS_DST:
1115		case SADB_EXT_ADDRESS_PROXY:
1116		case SADB_EXT_KEY_AUTH:
1117			/* XXX should to be check weak keys. */
1118		case SADB_EXT_KEY_ENCRYPT:
1119			/* XXX should to be check weak keys. */
1120		case SADB_EXT_IDENTITY_SRC:
1121		case SADB_EXT_IDENTITY_DST:
1122		case SADB_EXT_SENSITIVITY:
1123		case SADB_EXT_PROPOSAL:
1124		case SADB_EXT_SUPPORTED_AUTH:
1125		case SADB_EXT_SUPPORTED_ENCRYPT:
1126		case SADB_EXT_SPIRANGE:
1127		case SADB_X_EXT_POLICY:
1128			mhp[ext->sadb_ext_type] = (caddr_t)ext;
1129			break;
1130		default:
1131			ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
1132			return -1;
1133		}
1134
1135		extlen = PFKEY_EXTLEN(ext);
1136		tlen -= extlen;
1137		ext = (struct sadb_ext *)((caddr_t)ext + extlen);
1138	}
1139
1140	ipsec_errcode = EIPSEC_NO_ERROR;
1141	return 0;
1142}
1143
1144/*
1145 * check basic usage for sadb_msg,
1146 * NOTE: This routine is derived from netkey/key.c in KAME.
1147 * IN:	msg: pointer to message buffer.
1148 *	mhp: pointer to the buffer initialized like below:
1149 *
1150 *		caddr_t mhp[SADB_EXT_MAX + 1];
1151 *
1152 * OUT:	-1: invalid.
1153 *	 0: valid.
1154 */
1155int
1156pfkey_check(mhp)
1157	caddr_t *mhp;
1158{
1159	struct sadb_msg *msg;
1160
1161	/* validity check */
1162	if (mhp == NULL || mhp[0] == NULL) {
1163		ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1164		return -1;
1165	}
1166
1167	msg = (struct sadb_msg *)mhp[0];
1168
1169	/* check version */
1170	if (msg->sadb_msg_version != PF_KEY_V2) {
1171		ipsec_errcode = EIPSEC_INVAL_VERSION;
1172		return -1;
1173	}
1174
1175	/* check type */
1176	if (msg->sadb_msg_type > SADB_MAX) {
1177		ipsec_errcode = EIPSEC_INVAL_MSGTYPE;
1178		return -1;
1179	}
1180
1181	/* check SA type */
1182	switch (msg->sadb_msg_satype) {
1183	case SADB_SATYPE_UNSPEC:
1184		switch (msg->sadb_msg_type) {
1185		case SADB_GETSPI:
1186		case SADB_UPDATE:
1187		case SADB_ADD:
1188		case SADB_DELETE:
1189		case SADB_GET:
1190		case SADB_ACQUIRE:
1191		case SADB_EXPIRE:
1192			ipsec_errcode = EIPSEC_INVAL_SATYPE;
1193			return -1;
1194		}
1195		break;
1196	case SADB_SATYPE_ESP:
1197	case SADB_SATYPE_AH:
1198	case SADB_X_SATYPE_IPCOMP:
1199		switch (msg->sadb_msg_type) {
1200		case SADB_X_SPDADD:
1201		case SADB_X_SPDDELETE:
1202		case SADB_X_SPDGET:
1203		case SADB_X_SPDDUMP:
1204		case SADB_X_SPDFLUSH:
1205			ipsec_errcode = EIPSEC_INVAL_SATYPE;
1206			return -1;
1207		}
1208		break;
1209	case SADB_SATYPE_RSVP:
1210	case SADB_SATYPE_OSPFV2:
1211	case SADB_SATYPE_RIPV2:
1212	case SADB_SATYPE_MIP:
1213		ipsec_errcode = EIPSEC_NOT_SUPPORTED;
1214		return -1;
1215	case 1:	/* XXX: What does it do ? */
1216		if (msg->sadb_msg_type == SADB_X_PROMISC)
1217			break;
1218		/*FALLTHROUGH*/
1219	default:
1220		ipsec_errcode = EIPSEC_INVAL_SATYPE;
1221		return -1;
1222	}
1223
1224	/* check field of upper layer protocol and address family */
1225	if (mhp[SADB_EXT_ADDRESS_SRC] != NULL
1226	 && mhp[SADB_EXT_ADDRESS_DST] != NULL) {
1227		struct sadb_address *src0, *dst0;
1228
1229		src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]);
1230		dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]);
1231
1232		if (src0->sadb_address_proto != dst0->sadb_address_proto) {
1233			ipsec_errcode = EIPSEC_PROTO_MISMATCH;
1234			return -1;
1235		}
1236
1237		if (PFKEY_ADDR_SADDR(src0)->sa_family
1238		 != PFKEY_ADDR_SADDR(dst0)->sa_family) {
1239			ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1240			return -1;
1241		}
1242
1243		switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
1244		case AF_INET:
1245		case AF_INET6:
1246			break;
1247		default:
1248			ipsec_errcode = EIPSEC_INVAL_FAMILY;
1249			return -1;
1250		}
1251
1252		/*
1253		 * prefixlen == 0 is valid because there must be the case
1254		 * all addresses are matched.
1255		 */
1256	}
1257
1258	ipsec_errcode = EIPSEC_NO_ERROR;
1259	return 0;
1260}
1261
1262/*
1263 * set data into sadb_msg.
1264 * `buf' must has been allocated sufficiently.
1265 */
1266static caddr_t
1267pfkey_setsadbmsg(buf, type, tlen, satype, mode, seq, pid)
1268	caddr_t buf;
1269	u_int type, satype, mode;
1270	u_int tlen;
1271	u_int32_t seq;
1272	pid_t pid;
1273{
1274	struct sadb_msg *p;
1275	u_int len;
1276
1277	p = (struct sadb_msg *)buf;
1278	len = sizeof(struct sadb_sa);
1279
1280	memset(p, 0, len);
1281	p->sadb_msg_version = PF_KEY_V2;
1282	p->sadb_msg_type = type;
1283	p->sadb_msg_errno = 0;
1284	p->sadb_msg_satype = satype;
1285	p->sadb_msg_len = PFKEY_UNIT64(tlen);
1286	p->sadb_msg_mode = mode;
1287	p->sadb_msg_reserved = 0;
1288	p->sadb_msg_seq = seq;
1289	p->sadb_msg_pid = (u_int32_t)pid;
1290
1291	return(buf + len);
1292}
1293
1294/*
1295 * copy secasvar data into sadb_address.
1296 * `buf' must has been allocated sufficiently.
1297 */
1298static caddr_t
1299pfkey_setsadbsa(buf, spi, wsize, auth, enc, flags)
1300	caddr_t buf;
1301	u_int32_t spi, flags;
1302	u_int wsize, auth, enc;
1303{
1304	struct sadb_sa *p;
1305	u_int len;
1306
1307	p = (struct sadb_sa *)buf;
1308	len = sizeof(struct sadb_sa);
1309
1310	memset(p, 0, len);
1311	p->sadb_sa_len = PFKEY_UNIT64(len);
1312	p->sadb_sa_exttype = SADB_EXT_SA;
1313	p->sadb_sa_spi = spi;
1314	p->sadb_sa_replay = wsize;
1315	p->sadb_sa_state = SADB_SASTATE_LARVAL;
1316	p->sadb_sa_auth = auth;
1317	p->sadb_sa_encrypt = enc;
1318	p->sadb_sa_flags = flags;
1319
1320	return(buf + len);
1321}
1322
1323/*
1324 * set data into sadb_address.
1325 * `buf' must has been allocated sufficiently.
1326 * prefixlen is in bits.
1327 */
1328static caddr_t
1329pfkey_setsadbaddr(buf, exttype, saddr, prefixlen, ul_proto)
1330	caddr_t buf;
1331	u_int exttype;
1332	struct sockaddr *saddr;
1333	u_int prefixlen;
1334	u_int ul_proto;
1335{
1336	struct sadb_address *p;
1337	u_int len;
1338
1339	p = (struct sadb_address *)buf;
1340	len = sizeof(struct sadb_address) + PFKEY_ALIGN8(saddr->sa_len);
1341
1342	memset(p, 0, len);
1343	p->sadb_address_len = PFKEY_UNIT64(len);
1344	p->sadb_address_exttype = exttype & 0xffff;
1345	p->sadb_address_proto = ul_proto & 0xff;
1346	p->sadb_address_prefixlen = prefixlen;
1347	p->sadb_address_reserved = 0;
1348
1349	memcpy(p + 1, saddr, saddr->sa_len);
1350
1351	return(buf + len);
1352}
1353
1354/*
1355 * set sadb_key structure after clearing buffer with zero.
1356 * OUT: the pointer of buf + len.
1357 */
1358static caddr_t
1359pfkey_setsadbkey(buf, type, key, keylen)
1360	caddr_t buf, key;
1361	u_int type, keylen;
1362{
1363	struct sadb_key *p;
1364	u_int len;
1365
1366	p = (struct sadb_key *)buf;
1367	len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen);
1368
1369	memset(p, 0, len);
1370	p->sadb_key_len = PFKEY_UNIT64(len);
1371	p->sadb_key_exttype = type;
1372	p->sadb_key_bits = keylen << 3;
1373	p->sadb_key_reserved = 0;
1374
1375	memcpy(p + 1, key, keylen);
1376
1377	return buf + len;
1378}
1379
1380/*
1381 * set sadb_lifetime structure after clearing buffer with zero.
1382 * OUT: the pointer of buf + len.
1383 */
1384static caddr_t
1385pfkey_setsadblifetime(buf, type, l_alloc, l_bytes, l_addtime, l_usetime)
1386	caddr_t buf;
1387	u_int type;
1388	u_int32_t l_alloc, l_bytes, l_addtime, l_usetime;
1389{
1390	struct sadb_lifetime *p;
1391	u_int len;
1392
1393	p = (struct sadb_lifetime *)buf;
1394	len = sizeof(struct sadb_lifetime);
1395
1396	memset(p, 0, len);
1397	p->sadb_lifetime_len = PFKEY_UNIT64(len);
1398	p->sadb_lifetime_exttype = type;
1399
1400	switch (type) {
1401	case SADB_EXT_LIFETIME_SOFT:
1402		p->sadb_lifetime_allocations
1403			= (l_alloc * soft_lifetime_allocations_rate) /100;
1404		p->sadb_lifetime_bytes
1405			= ((l_bytes * soft_lifetime_bytes_rate) /100) << 10;
1406		p->sadb_lifetime_addtime
1407			= (l_addtime * soft_lifetime_addtime_rate) /100;
1408		p->sadb_lifetime_usetime
1409			= (l_usetime * soft_lifetime_usetime_rate) /100;
1410		break;
1411	case SADB_EXT_LIFETIME_HARD:
1412		p->sadb_lifetime_allocations = l_alloc;
1413		p->sadb_lifetime_bytes = l_bytes << 10;
1414		p->sadb_lifetime_addtime = l_addtime;
1415		p->sadb_lifetime_usetime = l_usetime;
1416		break;
1417	}
1418
1419	return buf + len;
1420}
1421
1422