xref: /netbsd-src/crypto/dist/ipsec-tools/src/libipsec/pfkey.c (revision aaf4ece63a859a04e37cf3a7229b5fab0157cc06)
1 /*	$NetBSD: pfkey.c,v 1.9 2005/11/21 14:20:28 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 
60 static int findsupportedmap __P((int));
61 static int setsupportedmap __P((struct sadb_supported *));
62 static struct sadb_alg *findsupportedalg __P((u_int, u_int));
63 static 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));
68 static int pfkey_send_x2 __P((int, u_int, u_int, u_int,
69 	struct sockaddr *, struct sockaddr *, u_int32_t));
70 static int pfkey_send_x3 __P((int, u_int, u_int));
71 static 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));
74 static int pfkey_send_x5 __P((int, u_int, u_int32_t));
75 
76 static caddr_t pfkey_setsadbmsg __P((caddr_t, caddr_t, u_int, u_int,
77 	u_int, u_int32_t, pid_t));
78 static caddr_t pfkey_setsadbsa __P((caddr_t, caddr_t, u_int32_t, u_int,
79 	u_int, u_int, u_int32_t));
80 static caddr_t pfkey_setsadbaddr __P((caddr_t, caddr_t, u_int,
81 	struct sockaddr *, u_int, u_int));
82 static caddr_t pfkey_setsadbkey __P((caddr_t, caddr_t, u_int, caddr_t, u_int));
83 static caddr_t pfkey_setsadblifetime __P((caddr_t, caddr_t, u_int, u_int32_t,
84 	u_int32_t, u_int32_t, u_int32_t));
85 static caddr_t pfkey_setsadbxsa2 __P((caddr_t, caddr_t, u_int32_t, u_int32_t));
86 
87 #ifdef SADB_X_EXT_NAT_T_TYPE
88 static caddr_t pfkey_set_natt_type __P((caddr_t, caddr_t, u_int, u_int8_t));
89 static 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
92 static 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  */
98 static struct sadb_supported *ipsec_supported[] = { NULL, NULL, NULL,
99 #ifdef SADB_X_SATYPE_TCPSIGNATURE
100     NULL,
101 #endif
102 };
103 
104 static 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 
113 static int
114 findsupportedmap(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 
125 static struct sadb_alg *
126 findsupportedalg(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 
163 static int
164 setsupportedmap(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  */
203 int
204 ipsec_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  */
235 int
236 ipsec_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  */
266 int
267 ipsec_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  */
306 static u_int soft_lifetime_allocations_rate = PFKEY_SOFT_LIFETIME_RATE;
307 static u_int soft_lifetime_bytes_rate = PFKEY_SOFT_LIFETIME_RATE;
308 static u_int soft_lifetime_addtime_rate = PFKEY_SOFT_LIFETIME_RATE;
309 static u_int soft_lifetime_usetime_rate = PFKEY_SOFT_LIFETIME_RATE;
310 
311 u_int
312 pfkey_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  */
343 u_int
344 pfkey_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  */
367 int
368 pfkey_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  */
496 int
497 pfkey_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
522 int
523 pfkey_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  */
562 int
563 pfkey_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
588 int
589 pfkey_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  */
627 int
628 pfkey_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*/
651 int
652 pfkey_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 = ((caddr_t)(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  */
733 int
734 pfkey_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  */
753 int
754 pfkey_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  */
795 int
796 pfkey_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  */
835 int
836 pfkey_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  */
899 int
900 pfkey_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  */
918 int
919 pfkey_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  */
943 int
944 pfkey_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  */
963 int
964 pfkey_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  */
989 int
990 pfkey_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  */
1017 int
1018 pfkey_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  */
1043 int
1044 pfkey_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  */
1071 int
1072 pfkey_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  */
1102 int
1103 pfkey_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  */
1121 int
1122 pfkey_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  */
1140 int
1141 pfkey_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  */
1171 int
1172 pfkey_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  */
1189 int
1190 pfkey_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 */
1202 static int
1203 pfkey_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, (u_int)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*/
1463 static int
1464 pfkey_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, (u_int)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  */
1550 static int
1551 pfkey_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, (u_int)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 */
1612 static int
1613 pfkey_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((void *)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 */
1706 static int
1707 pfkey_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  */
1762 int
1763 pfkey_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  */
1790 void
1791 pfkey_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  */
1809 struct sadb_msg *
1810 pfkey_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  */
1867 int
1868 pfkey_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  */
1896 int
1897 pfkey_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 #ifdef SADB_X_EXT_PACKET
1972 		case SADB_X_EXT_PACKET:
1973 #endif
1974 
1975 			mhp[ext->sadb_ext_type] = (void *)ext;
1976 			break;
1977 		default:
1978 			__ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
1979 			return -1;
1980 		}
1981 
1982 		p += PFKEY_EXTLEN(ext);
1983 	}
1984 
1985 	if (p != ep) {
1986 		__ipsec_errcode = EIPSEC_INVAL_SADBMSG;
1987 		return -1;
1988 	}
1989 
1990 	__ipsec_errcode = EIPSEC_NO_ERROR;
1991 	return 0;
1992 }
1993 
1994 /*
1995  * check basic usage for sadb_msg,
1996  * NOTE: This routine is derived from netkey/key.c in KAME.
1997  * IN:	msg: pointer to message buffer.
1998  *	mhp: pointer to the buffer initialized like below:
1999  *
2000  *		caddr_t mhp[SADB_EXT_MAX + 1];
2001  *
2002  * OUT:	-1: invalid.
2003  *	 0: valid.
2004  */
2005 int
2006 pfkey_check(mhp)
2007 	caddr_t *mhp;
2008 {
2009 	struct sadb_msg *msg;
2010 
2011 	/* validity check */
2012 	if (mhp == NULL || mhp[0] == NULL) {
2013 		__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
2014 		return -1;
2015 	}
2016 
2017 	msg = (void *)mhp[0];
2018 
2019 	/* check version */
2020 	if (msg->sadb_msg_version != PF_KEY_V2) {
2021 		__ipsec_errcode = EIPSEC_INVAL_VERSION;
2022 		return -1;
2023 	}
2024 
2025 	/* check type */
2026 	if (msg->sadb_msg_type > SADB_MAX) {
2027 		__ipsec_errcode = EIPSEC_INVAL_MSGTYPE;
2028 		return -1;
2029 	}
2030 
2031 	/* check SA type */
2032 	switch (msg->sadb_msg_satype) {
2033 	case SADB_SATYPE_UNSPEC:
2034 		switch (msg->sadb_msg_type) {
2035 		case SADB_GETSPI:
2036 		case SADB_UPDATE:
2037 		case SADB_ADD:
2038 		case SADB_DELETE:
2039 		case SADB_GET:
2040 		case SADB_ACQUIRE:
2041 		case SADB_EXPIRE:
2042 #ifdef SADB_X_NAT_T_NEW_MAPPING
2043 		case SADB_X_NAT_T_NEW_MAPPING:
2044 #endif
2045 			__ipsec_errcode = EIPSEC_INVAL_SATYPE;
2046 			return -1;
2047 		}
2048 		break;
2049 	case SADB_SATYPE_ESP:
2050 	case SADB_SATYPE_AH:
2051 	case SADB_X_SATYPE_IPCOMP:
2052 #ifdef SADB_X_SATYPE_TCPSIGNATURE
2053 	case SADB_X_SATYPE_TCPSIGNATURE:
2054 #endif
2055 		switch (msg->sadb_msg_type) {
2056 		case SADB_X_SPDADD:
2057 		case SADB_X_SPDDELETE:
2058 		case SADB_X_SPDGET:
2059 		case SADB_X_SPDDUMP:
2060 		case SADB_X_SPDFLUSH:
2061 			__ipsec_errcode = EIPSEC_INVAL_SATYPE;
2062 			return -1;
2063 		}
2064 #ifdef SADB_X_NAT_T_NEW_MAPPING
2065 		if (msg->sadb_msg_type == SADB_X_NAT_T_NEW_MAPPING &&
2066 		    msg->sadb_msg_satype != SADB_SATYPE_ESP) {
2067 			__ipsec_errcode = EIPSEC_INVAL_SATYPE;
2068 			return -1;
2069 		}
2070 #endif
2071 		break;
2072 	case SADB_SATYPE_RSVP:
2073 	case SADB_SATYPE_OSPFV2:
2074 	case SADB_SATYPE_RIPV2:
2075 	case SADB_SATYPE_MIP:
2076 		__ipsec_errcode = EIPSEC_NOT_SUPPORTED;
2077 		return -1;
2078 	case 1:	/* XXX: What does it do ? */
2079 		if (msg->sadb_msg_type == SADB_X_PROMISC)
2080 			break;
2081 		/*FALLTHROUGH*/
2082 	default:
2083 		__ipsec_errcode = EIPSEC_INVAL_SATYPE;
2084 		return -1;
2085 	}
2086 
2087 	/* check field of upper layer protocol and address family */
2088 	if (mhp[SADB_EXT_ADDRESS_SRC] != NULL
2089 	 && mhp[SADB_EXT_ADDRESS_DST] != NULL) {
2090 		struct sadb_address *src0, *dst0;
2091 
2092 		src0 = (void *)(mhp[SADB_EXT_ADDRESS_SRC]);
2093 		dst0 = (void *)(mhp[SADB_EXT_ADDRESS_DST]);
2094 
2095 		if (src0->sadb_address_proto != dst0->sadb_address_proto) {
2096 			__ipsec_errcode = EIPSEC_PROTO_MISMATCH;
2097 			return -1;
2098 		}
2099 
2100 		if (PFKEY_ADDR_SADDR(src0)->sa_family
2101 		 != PFKEY_ADDR_SADDR(dst0)->sa_family) {
2102 			__ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
2103 			return -1;
2104 		}
2105 
2106 		switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
2107 		case AF_INET:
2108 		case AF_INET6:
2109 			break;
2110 		default:
2111 			__ipsec_errcode = EIPSEC_INVAL_FAMILY;
2112 			return -1;
2113 		}
2114 
2115 		/*
2116 		 * prefixlen == 0 is valid because there must be the case
2117 		 * all addresses are matched.
2118 		 */
2119 	}
2120 
2121 	__ipsec_errcode = EIPSEC_NO_ERROR;
2122 	return 0;
2123 }
2124 
2125 /*
2126  * set data into sadb_msg.
2127  * `buf' must has been allocated sufficiently.
2128  */
2129 static caddr_t
2130 pfkey_setsadbmsg(buf, lim, type, tlen, satype, seq, pid)
2131 	caddr_t buf;
2132 	caddr_t lim;
2133 	u_int type, satype;
2134 	u_int tlen;
2135 	u_int32_t seq;
2136 	pid_t pid;
2137 {
2138 	struct sadb_msg *p;
2139 	u_int len;
2140 
2141 	p = (void *)buf;
2142 	len = sizeof(struct sadb_msg);
2143 
2144 	if (buf + len > lim)
2145 		return NULL;
2146 
2147 	memset(p, 0, len);
2148 	p->sadb_msg_version = PF_KEY_V2;
2149 	p->sadb_msg_type = type;
2150 	p->sadb_msg_errno = 0;
2151 	p->sadb_msg_satype = satype;
2152 	p->sadb_msg_len = PFKEY_UNIT64(tlen);
2153 	p->sadb_msg_reserved = 0;
2154 	p->sadb_msg_seq = seq;
2155 	p->sadb_msg_pid = (u_int32_t)pid;
2156 
2157 	return(buf + len);
2158 }
2159 
2160 /*
2161  * copy secasvar data into sadb_address.
2162  * `buf' must has been allocated sufficiently.
2163  */
2164 static caddr_t
2165 pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags)
2166 	caddr_t buf;
2167 	caddr_t lim;
2168 	u_int32_t spi, flags;
2169 	u_int wsize, auth, enc;
2170 {
2171 	struct sadb_sa *p;
2172 	u_int len;
2173 
2174 	p = (void *)buf;
2175 	len = sizeof(struct sadb_sa);
2176 
2177 	if (buf + len > lim)
2178 		return NULL;
2179 
2180 	memset(p, 0, len);
2181 	p->sadb_sa_len = PFKEY_UNIT64(len);
2182 	p->sadb_sa_exttype = SADB_EXT_SA;
2183 	p->sadb_sa_spi = spi;
2184 	p->sadb_sa_replay = wsize;
2185 	p->sadb_sa_state = SADB_SASTATE_LARVAL;
2186 	p->sadb_sa_auth = auth;
2187 	p->sadb_sa_encrypt = enc;
2188 	p->sadb_sa_flags = flags;
2189 
2190 	return(buf + len);
2191 }
2192 
2193 /*
2194  * set data into sadb_address.
2195  * `buf' must has been allocated sufficiently.
2196  * prefixlen is in bits.
2197  */
2198 static caddr_t
2199 pfkey_setsadbaddr(buf, lim, exttype, saddr, prefixlen, ul_proto)
2200 	caddr_t buf;
2201 	caddr_t lim;
2202 	u_int exttype;
2203 	struct sockaddr *saddr;
2204 	u_int prefixlen;
2205 	u_int ul_proto;
2206 {
2207 	struct sadb_address *p;
2208 	u_int len;
2209 
2210 	p = (void *)buf;
2211 	len = sizeof(struct sadb_address) + PFKEY_ALIGN8(sysdep_sa_len(saddr));
2212 
2213 	if (buf + len > lim)
2214 		return NULL;
2215 
2216 	memset(p, 0, len);
2217 	p->sadb_address_len = PFKEY_UNIT64(len);
2218 	p->sadb_address_exttype = exttype & 0xffff;
2219 	p->sadb_address_proto = ul_proto & 0xff;
2220 	p->sadb_address_prefixlen = prefixlen;
2221 	p->sadb_address_reserved = 0;
2222 
2223 	memcpy(p + 1, saddr, (size_t)sysdep_sa_len(saddr));
2224 
2225 	return(buf + len);
2226 }
2227 
2228 /*
2229  * set sadb_key structure after clearing buffer with zero.
2230  * OUT: the pointer of buf + len.
2231  */
2232 static caddr_t
2233 pfkey_setsadbkey(buf, lim, type, key, keylen)
2234 	caddr_t buf;
2235 	caddr_t lim;
2236 	caddr_t key;
2237 	u_int type, keylen;
2238 {
2239 	struct sadb_key *p;
2240 	u_int len;
2241 
2242 	p = (void *)buf;
2243 	len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen);
2244 
2245 	if (buf + len > lim)
2246 		return NULL;
2247 
2248 	memset(p, 0, len);
2249 	p->sadb_key_len = PFKEY_UNIT64(len);
2250 	p->sadb_key_exttype = type;
2251 	p->sadb_key_bits = keylen << 3;
2252 	p->sadb_key_reserved = 0;
2253 
2254 	memcpy(p + 1, key, keylen);
2255 
2256 	return buf + len;
2257 }
2258 
2259 /*
2260  * set sadb_lifetime structure after clearing buffer with zero.
2261  * OUT: the pointer of buf + len.
2262  */
2263 static caddr_t
2264 pfkey_setsadblifetime(buf, lim, type, l_alloc, l_bytes, l_addtime, l_usetime)
2265 	caddr_t buf;
2266 	caddr_t lim;
2267 	u_int type;
2268 	u_int32_t l_alloc, l_bytes, l_addtime, l_usetime;
2269 {
2270 	struct sadb_lifetime *p;
2271 	u_int len;
2272 
2273 	p = (void *)buf;
2274 	len = sizeof(struct sadb_lifetime);
2275 
2276 	if (buf + len > lim)
2277 		return NULL;
2278 
2279 	memset(p, 0, len);
2280 	p->sadb_lifetime_len = PFKEY_UNIT64(len);
2281 	p->sadb_lifetime_exttype = type;
2282 
2283 	switch (type) {
2284 	case SADB_EXT_LIFETIME_SOFT:
2285 		p->sadb_lifetime_allocations
2286 			= (l_alloc * soft_lifetime_allocations_rate) /100;
2287 		p->sadb_lifetime_bytes
2288 			= (l_bytes * soft_lifetime_bytes_rate) /100;
2289 		p->sadb_lifetime_addtime
2290 			= (l_addtime * soft_lifetime_addtime_rate) /100;
2291 		p->sadb_lifetime_usetime
2292 			= (l_usetime * soft_lifetime_usetime_rate) /100;
2293 		break;
2294 	case SADB_EXT_LIFETIME_HARD:
2295 		p->sadb_lifetime_allocations = l_alloc;
2296 		p->sadb_lifetime_bytes = l_bytes;
2297 		p->sadb_lifetime_addtime = l_addtime;
2298 		p->sadb_lifetime_usetime = l_usetime;
2299 		break;
2300 	}
2301 
2302 	return buf + len;
2303 }
2304 
2305 /*
2306  * copy secasvar data into sadb_address.
2307  * `buf' must has been allocated sufficiently.
2308  */
2309 static caddr_t
2310 pfkey_setsadbxsa2(buf, lim, mode0, reqid)
2311 	caddr_t buf;
2312 	caddr_t lim;
2313 	u_int32_t mode0;
2314 	u_int32_t reqid;
2315 {
2316 	struct sadb_x_sa2 *p;
2317 	u_int8_t mode = mode0 & 0xff;
2318 	u_int len;
2319 
2320 	p = (void *)buf;
2321 	len = sizeof(struct sadb_x_sa2);
2322 
2323 	if (buf + len > lim)
2324 		return NULL;
2325 
2326 	memset(p, 0, len);
2327 	p->sadb_x_sa2_len = PFKEY_UNIT64(len);
2328 	p->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
2329 	p->sadb_x_sa2_mode = mode;
2330 	p->sadb_x_sa2_reqid = reqid;
2331 
2332 	return(buf + len);
2333 }
2334 
2335 #ifdef SADB_X_EXT_NAT_T_TYPE
2336 static caddr_t
2337 pfkey_set_natt_type(buf, lim, type, l_natt_type)
2338 	caddr_t buf;
2339 	caddr_t lim;
2340 	u_int type;
2341 	u_int8_t l_natt_type;
2342 {
2343 	struct sadb_x_nat_t_type *p;
2344 	u_int len;
2345 
2346 	p = (void *)buf;
2347 	len = sizeof(struct sadb_x_nat_t_type);
2348 
2349 	if (buf + len > lim)
2350 		return NULL;
2351 
2352 	memset(p, 0, len);
2353 	p->sadb_x_nat_t_type_len = PFKEY_UNIT64(len);
2354 	p->sadb_x_nat_t_type_exttype = type;
2355 	p->sadb_x_nat_t_type_type = l_natt_type;
2356 
2357 	return(buf + len);
2358 }
2359 
2360 static caddr_t
2361 pfkey_set_natt_port(buf, lim, type, l_natt_port)
2362 	caddr_t buf;
2363 	caddr_t lim;
2364 	u_int type;
2365 	u_int16_t l_natt_port;
2366 {
2367 	struct sadb_x_nat_t_port *p;
2368 	u_int len;
2369 
2370 	p = (void *)buf;
2371 	len = sizeof(struct sadb_x_nat_t_port);
2372 
2373 	if (buf + len > lim)
2374 		return NULL;
2375 
2376 	memset(p, 0, len);
2377 	p->sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
2378 	p->sadb_x_nat_t_port_exttype = type;
2379 	p->sadb_x_nat_t_port_port = htons(l_natt_port);
2380 
2381 	return(buf + len);
2382 }
2383 #endif
2384 
2385 #ifdef SADB_X_EXT_NAT_T_FRAG
2386 static caddr_t
2387 pfkey_set_natt_frag(buf, lim, type, l_natt_frag)
2388 	caddr_t buf;
2389 	caddr_t lim;
2390 	u_int type;
2391 	u_int16_t l_natt_frag;
2392 {
2393 	struct sadb_x_nat_t_frag *p;
2394 	u_int len;
2395 
2396 	p = (void *)buf;
2397 	len = sizeof(struct sadb_x_nat_t_frag);
2398 
2399 	if (buf + len > lim)
2400 		return NULL;
2401 
2402 	memset(p, 0, len);
2403 	p->sadb_x_nat_t_frag_len = PFKEY_UNIT64(len);
2404 	p->sadb_x_nat_t_frag_exttype = type;
2405 	p->sadb_x_nat_t_frag_fraglen = l_natt_frag;
2406 
2407 	return(buf + len);
2408 }
2409 #endif
2410