1 /* $KAME: pfkey.c,v 1.47 2003/10/02 19:52:12 itojun Exp $ */
4 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
39 #include <System/net/pfkeyv2.h>
40 #include <netinet/in.h>
41 #ifdef HAVE_NETINET6_IPSEC
42 # include <netinet6/ipsec.h>
44 # include <netinet/ipsec.h>
53 #include "ipsec_strerror.h"
56 #define CALLOC(size, cast) (cast)calloc(1, (size))
58 static int findsupportedmap
__P((int));
59 static int setsupportedmap
__P((struct sadb_supported
*));
60 static struct sadb_alg
*findsupportedalg
__P((u_int
, u_int
));
61 static int pfkey_send_x1
__P((int, u_int
, u_int
, u_int
, struct sockaddr
*,
62 struct sockaddr
*, u_int32_t
, u_int32_t
, u_int
, caddr_t
,
63 u_int
, u_int
, u_int
, u_int
, u_int
, u_int32_t
, u_int32_t
,
64 u_int32_t
, u_int32_t
, u_int32_t
, u_int16_t
));
65 static int pfkey_send_x2
__P((int, u_int
, u_int
, u_int
,
66 struct sockaddr
*, struct sockaddr
*, u_int32_t
));
67 static int pfkey_send_x3
__P((int, u_int
, u_int
));
68 static int pfkey_send_x4
__P((int, u_int
, struct sockaddr
*, u_int
,
69 struct sockaddr
*, u_int
, u_int
, u_int64_t
, u_int64_t
,
70 char *, int, u_int32_t
));
71 static int pfkey_send_x5
__P((int, u_int
, u_int32_t
));
73 static caddr_t pfkey_setsadbmsg
__P((caddr_t
, caddr_t
, u_int
, u_int
,
74 u_int
, u_int32_t
, pid_t
));
75 static caddr_t pfkey_setsadbsa
__P((caddr_t
, caddr_t
, u_int32_t
, u_int
,
76 u_int
, u_int
, u_int32_t
, u_int16_t
));
77 static caddr_t pfkey_setsadbaddr
__P((caddr_t
, caddr_t
, u_int
,
78 struct sockaddr
*, u_int
, u_int
));
79 static caddr_t pfkey_setsadbkey
__P((caddr_t
, caddr_t
, u_int
, caddr_t
, u_int
));
80 static caddr_t pfkey_setsadblifetime
__P((caddr_t
, caddr_t
, u_int
, u_int32_t
,
81 u_int32_t
, u_int32_t
, u_int32_t
));
82 static caddr_t pfkey_setsadbxsa2
__P((caddr_t
, caddr_t
, u_int32_t
, u_int32_t
));
84 #ifdef SADB_X_EXT_NAT_T_TYPE
85 static caddr_t pfkey_set_natt_type
__P((caddr_t
, caddr_t
, u_int
, u_int8_t
));
86 static caddr_t pfkey_set_natt_port
__P((caddr_t
, caddr_t
, u_int
, u_int16_t
));
88 #ifdef SADB_X_EXT_NAT_T_FRAG
89 static caddr_t pfkey_set_natt_frag
__P((caddr_t
, caddr_t
, u_int
, u_int16_t
));
93 * make and search supported algorithm structure.
95 static struct sadb_supported
*ipsec_supported
[] = { NULL
, NULL
, NULL
,
96 #ifdef SADB_X_SATYPE_TCPSIGNATURE
101 static int supported_map
[] = {
104 SADB_X_SATYPE_IPCOMP
,
105 #ifdef SADB_X_SATYPE_TCPSIGNATURE
106 SADB_X_SATYPE_TCPSIGNATURE
,
111 findsupportedmap(satype
)
116 for (i
= 0; i
< sizeof(supported_map
)/sizeof(supported_map
[0]); i
++)
117 if (supported_map
[i
] == satype
)
122 static struct sadb_alg
*
123 findsupportedalg(satype
, alg_id
)
124 u_int satype
, alg_id
;
131 algno
= findsupportedmap((int)satype
);
133 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
136 if (ipsec_supported
[algno
] == NULL
) {
137 __ipsec_errcode
= EIPSEC_DO_GET_SUPP_LIST
;
141 tlen
= ipsec_supported
[algno
]->sadb_supported_len
142 - sizeof(struct sadb_supported
);
143 p
= (void *)(ipsec_supported
[algno
] + 1);
145 if (tlen
< sizeof(struct sadb_alg
)) {
149 if (((struct sadb_alg
*)(void *)p
)->sadb_alg_id
== alg_id
)
152 tlen
-= sizeof(struct sadb_alg
);
153 p
+= sizeof(struct sadb_alg
);
156 __ipsec_errcode
= EIPSEC_NOT_SUPPORTED
;
162 struct sadb_supported
*sup
;
164 struct sadb_supported
**ipsup
;
166 switch (sup
->sadb_supported_exttype
) {
167 case SADB_EXT_SUPPORTED_AUTH
:
168 ipsup
= &ipsec_supported
[findsupportedmap(SADB_SATYPE_AH
)];
170 case SADB_EXT_SUPPORTED_ENCRYPT
:
171 ipsup
= &ipsec_supported
[findsupportedmap(SADB_SATYPE_ESP
)];
174 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
181 *ipsup
= malloc((size_t)sup
->sadb_supported_len
);
183 __ipsec_set_strerror(strerror(errno
));
186 memcpy(*ipsup
, sup
, (size_t)sup
->sadb_supported_len
);
192 * check key length against algorithm specified.
193 * This function is called with SADB_EXT_SUPPORTED_{AUTH,ENCRYPT} as the
194 * augument, and only calls to ipsec_check_keylen2();
195 * keylen is the unit of bit.
201 ipsec_check_keylen(supported
, alg_id
, keylen
)
210 case SADB_EXT_SUPPORTED_AUTH
:
211 satype
= SADB_SATYPE_AH
;
213 case SADB_EXT_SUPPORTED_ENCRYPT
:
214 satype
= SADB_SATYPE_ESP
;
217 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
221 return ipsec_check_keylen2(satype
, alg_id
, keylen
);
225 * check key length against algorithm specified.
226 * satype is one of satype defined at pfkeyv2.h.
227 * keylen is the unit of bit.
233 ipsec_check_keylen2(satype
, alg_id
, keylen
)
238 struct sadb_alg
*alg
;
240 alg
= findsupportedalg(satype
, alg_id
);
244 if (keylen
< alg
->sadb_alg_minbits
|| keylen
> alg
->sadb_alg_maxbits
) {
245 fprintf(stderr
, "%d %d %d\n", keylen
, alg
->sadb_alg_minbits
,
246 alg
->sadb_alg_maxbits
);
247 __ipsec_errcode
= EIPSEC_INVAL_KEYLEN
;
251 __ipsec_errcode
= EIPSEC_NO_ERROR
;
256 * get max/min key length against algorithm specified.
257 * satype is one of satype defined at pfkeyv2.h.
258 * keylen is the unit of bit.
264 ipsec_get_keylen(supported
, alg_id
, alg0
)
265 u_int supported
, alg_id
;
266 struct sadb_alg
*alg0
;
268 struct sadb_alg
*alg
;
273 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
278 case SADB_EXT_SUPPORTED_AUTH
:
279 satype
= SADB_SATYPE_AH
;
281 case SADB_EXT_SUPPORTED_ENCRYPT
:
282 satype
= SADB_SATYPE_ESP
;
285 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
289 alg
= findsupportedalg(satype
, alg_id
);
293 memcpy(alg0
, alg
, sizeof(*alg0
));
295 __ipsec_errcode
= EIPSEC_NO_ERROR
;
300 * set the rate for SOFT lifetime against HARD one.
301 * If rate is more than 100 or equal to zero, then set to 100.
303 static u_int soft_lifetime_allocations_rate
= PFKEY_SOFT_LIFETIME_RATE
;
304 static u_int soft_lifetime_bytes_rate
= PFKEY_SOFT_LIFETIME_RATE
;
305 static u_int soft_lifetime_addtime_rate
= PFKEY_SOFT_LIFETIME_RATE
;
306 static u_int soft_lifetime_usetime_rate
= PFKEY_SOFT_LIFETIME_RATE
;
309 pfkey_set_softrate(type
, rate
)
312 __ipsec_errcode
= EIPSEC_NO_ERROR
;
314 if (rate
> 100 || rate
== 0)
318 case SADB_X_LIFETIME_ALLOCATIONS
:
319 soft_lifetime_allocations_rate
= rate
;
321 case SADB_X_LIFETIME_BYTES
:
322 soft_lifetime_bytes_rate
= rate
;
324 case SADB_X_LIFETIME_ADDTIME
:
325 soft_lifetime_addtime_rate
= rate
;
327 case SADB_X_LIFETIME_USETIME
:
328 soft_lifetime_usetime_rate
= rate
;
332 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
337 * get current rate for SOFT lifetime against HARD one.
338 * ATTENTION: ~0 is returned if invalid type was passed.
341 pfkey_get_softrate(type
)
345 case SADB_X_LIFETIME_ALLOCATIONS
:
346 return soft_lifetime_allocations_rate
;
347 case SADB_X_LIFETIME_BYTES
:
348 return soft_lifetime_bytes_rate
;
349 case SADB_X_LIFETIME_ADDTIME
:
350 return soft_lifetime_addtime_rate
;
351 case SADB_X_LIFETIME_USETIME
:
352 return soft_lifetime_usetime_rate
;
359 * sending SADB_GETSPI message to the kernel.
361 * positive: success and return length sent.
362 * -1 : error occured, and set errno.
365 pfkey_send_getspi(so
, satype
, mode
, src
, dst
, min
, max
, reqid
, seq
)
368 struct sockaddr
*src
, *dst
;
369 u_int32_t min
, max
, reqid
, seq
;
371 struct sadb_msg
*newmsg
;
374 int need_spirange
= 0;
379 if (src
== NULL
|| dst
== NULL
) {
380 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
383 if (src
->sa_family
!= dst
->sa_family
) {
384 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
387 if (min
> max
|| (min
> 0 && min
<= 255)) {
388 __ipsec_errcode
= EIPSEC_INVAL_SPI
;
391 switch (src
->sa_family
) {
393 plen
= sizeof(struct in_addr
) << 3;
396 plen
= sizeof(struct in6_addr
) << 3;
399 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
403 /* create new sadb_msg to send. */
404 len
= sizeof(struct sadb_msg
)
405 + sizeof(struct sadb_x_sa2
)
406 + sizeof(struct sadb_address
)
407 + PFKEY_ALIGN8(sysdep_sa_len(src
))
408 + sizeof(struct sadb_address
)
409 + PFKEY_ALIGN8(sysdep_sa_len(dst
));
411 if (min
> 255 && max
< (u_int
)~0) {
413 len
+= sizeof(struct sadb_spirange
);
416 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
417 __ipsec_set_strerror(strerror(errno
));
420 ep
= ((caddr_t
)(void *)newmsg
) + len
;
422 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, SADB_GETSPI
,
423 (u_int
)len
, satype
, seq
, getpid());
429 p
= pfkey_setsadbxsa2(p
, ep
, mode
, reqid
);
435 /* set sadb_address for source */
436 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
443 /* set sadb_address for destination */
444 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
451 /* proccessing spi range */
453 struct sadb_spirange spirange
;
455 if (p
+ sizeof(spirange
) > ep
) {
460 memset(&spirange
, 0, sizeof(spirange
));
461 spirange
.sadb_spirange_len
= PFKEY_UNIT64(sizeof(spirange
));
462 spirange
.sadb_spirange_exttype
= SADB_EXT_SPIRANGE
;
463 spirange
.sadb_spirange_min
= min
;
464 spirange
.sadb_spirange_max
= max
;
466 memcpy(p
, &spirange
, sizeof(spirange
));
468 p
+= sizeof(spirange
);
476 len
= pfkey_send(so
, newmsg
, len
);
482 __ipsec_errcode
= EIPSEC_NO_ERROR
;
488 * sending SADB_UPDATE message to the kernel.
489 * The length of key material is a_keylen + e_keylen.
491 * positive: success and return length sent.
492 * -1 : error occured, and set errno.
495 pfkey_send_update(so
, satype
, mode
, src
, dst
, spi
, reqid
, wsize
,
496 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
497 l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
, port
)
499 u_int satype
, mode
, wsize
;
500 struct sockaddr
*src
, *dst
;
501 u_int32_t spi
, reqid
;
503 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
505 u_int64_t l_bytes
, l_addtime
, l_usetime
;
510 if ((len
= pfkey_send_x1(so
, SADB_UPDATE
, satype
, mode
, src
, dst
, spi
,
512 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
513 l_alloc
, (u_int
)l_bytes
, (u_int
)l_addtime
,
514 (u_int
)l_usetime
, seq
, port
)) < 0)
522 * sending SADB_ADD message to the kernel.
523 * The length of key material is a_keylen + e_keylen.
525 * positive: success and return length sent.
526 * -1 : error occured, and set errno.
529 pfkey_send_add(so
, satype
, mode
, src
, dst
, spi
, reqid
, wsize
,
530 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
531 l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
, port
)
533 u_int satype
, mode
, wsize
;
534 struct sockaddr
*src
, *dst
;
535 u_int32_t spi
, reqid
;
537 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
539 u_int64_t l_bytes
, l_addtime
, l_usetime
;
544 if ((len
= pfkey_send_x1(so
, SADB_ADD
, satype
, mode
, src
, dst
, spi
,
546 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
547 l_alloc
, (u_int
)l_bytes
, (u_int
)l_addtime
,
548 (u_int
)l_usetime
, seq
, port
)) < 0)
556 * sending SADB_DELETE message to the kernel.
558 * positive: success and return length sent.
559 * -1 : error occured, and set errno.
562 pfkey_send_delete(so
, satype
, mode
, src
, dst
, spi
)
565 struct sockaddr
*src
, *dst
;
569 if ((len
= pfkey_send_x2(so
, SADB_DELETE
, satype
, mode
, src
, dst
, spi
)) < 0)
576 * sending SADB_DELETE without spi to the kernel. This is
577 * the "delete all" request (an extension also present in
581 * positive: success and return length sent
582 * -1 : error occured, and set errno
586 pfkey_send_delete_all(so
, satype
, mode
, src
, dst
)
589 struct sockaddr
*src
, *dst
;
591 struct sadb_msg
*newmsg
;
598 if (src
== NULL
|| dst
== NULL
) {
599 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
602 if (src
->sa_family
!= dst
->sa_family
) {
603 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
606 switch (src
->sa_family
) {
608 plen
= sizeof(struct in_addr
) << 3;
611 plen
= sizeof(struct in6_addr
) << 3;
614 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
618 /* create new sadb_msg to reply. */
619 len
= sizeof(struct sadb_msg
)
620 + sizeof(struct sadb_address
)
621 + PFKEY_ALIGN8(sysdep_sa_len(src
))
622 + sizeof(struct sadb_address
)
623 + PFKEY_ALIGN8(sysdep_sa_len(dst
));
625 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
626 __ipsec_set_strerror(strerror(errno
));
629 ep
= ((caddr_t
)(void *)newmsg
) + len
;
631 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, SADB_DELETE
, (u_int
)len
,
632 satype
, 0, getpid());
637 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
643 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
651 len
= pfkey_send(so
, newmsg
, len
);
657 __ipsec_errcode
= EIPSEC_NO_ERROR
;
662 * sending SADB_GET message to the kernel.
664 * positive: success and return length sent.
665 * -1 : error occured, and set errno.
668 pfkey_send_get(so
, satype
, mode
, src
, dst
, spi
)
671 struct sockaddr
*src
, *dst
;
675 if ((len
= pfkey_send_x2(so
, SADB_GET
, satype
, mode
, src
, dst
, spi
)) < 0)
682 * sending SADB_REGISTER message to the kernel.
684 * positive: success and return length sent.
685 * -1 : error occured, and set errno.
688 pfkey_send_register(so
, satype
)
694 if (satype
== PF_UNSPEC
) {
696 algno
< sizeof(supported_map
)/sizeof(supported_map
[0]);
698 if (ipsec_supported
[algno
]) {
699 free(ipsec_supported
[algno
]);
700 ipsec_supported
[algno
] = NULL
;
704 algno
= findsupportedmap((int)satype
);
706 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
710 if (ipsec_supported
[algno
]) {
711 free(ipsec_supported
[algno
]);
712 ipsec_supported
[algno
] = NULL
;
716 if ((len
= pfkey_send_x3(so
, SADB_REGISTER
, satype
)) < 0)
723 * receiving SADB_REGISTER message from the kernel, and copy buffer for
724 * sadb_supported returned into ipsec_supported.
726 * 0: success and return length sent.
727 * -1: error occured, and set errno.
730 pfkey_recv_register(so
)
733 pid_t pid
= getpid();
734 struct sadb_msg
*newmsg
;
737 /* receive message */
739 if ((newmsg
= pfkey_recv(so
)) == NULL
)
741 if (newmsg
->sadb_msg_type
== SADB_REGISTER
&&
742 newmsg
->sadb_msg_pid
== pid
)
748 newmsg
->sadb_msg_len
= PFKEY_UNUNIT64(newmsg
->sadb_msg_len
);
750 error
= pfkey_set_supported(newmsg
, newmsg
->sadb_msg_len
);
754 __ipsec_errcode
= EIPSEC_NO_ERROR
;
760 * receiving SADB_REGISTER message from the kernel, and copy buffer for
761 * sadb_supported returned into ipsec_supported.
762 * NOTE: sadb_msg_len must be host order.
764 * tlen: msg length, it's to makeing sure.
766 * 0: success and return length sent.
767 * -1: error occured, and set errno.
770 pfkey_set_supported(msg
, tlen
)
771 struct sadb_msg
*msg
;
774 struct sadb_supported
*sup
;
779 if (msg
->sadb_msg_len
!= tlen
) {
780 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
787 p
+= sizeof(struct sadb_msg
);
791 if (ep
< p
+ sizeof(*sup
) ||
792 PFKEY_EXTLEN(sup
) < sizeof(*sup
) ||
793 ep
< p
+ sup
->sadb_supported_len
) {
798 switch (sup
->sadb_supported_exttype
) {
799 case SADB_EXT_SUPPORTED_AUTH
:
800 case SADB_EXT_SUPPORTED_ENCRYPT
:
803 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
808 sup
->sadb_supported_len
= PFKEY_EXTLEN(sup
);
810 /* set supported map */
811 if (setsupportedmap(sup
) != 0)
814 p
+= sup
->sadb_supported_len
;
818 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
822 __ipsec_errcode
= EIPSEC_NO_ERROR
;
828 * sending SADB_FLUSH message to the kernel.
830 * positive: success and return length sent.
831 * -1 : error occured, and set errno.
834 pfkey_send_flush(so
, satype
)
840 if ((len
= pfkey_send_x3(so
, SADB_FLUSH
, satype
)) < 0)
847 * sending SADB_DUMP message to the kernel.
849 * positive: success and return length sent.
850 * -1 : error occured, and set errno.
853 pfkey_send_dump(so
, satype
)
859 if ((len
= pfkey_send_x3(so
, SADB_DUMP
, satype
)) < 0)
866 * sending SADB_X_PROMISC message to the kernel.
867 * NOTE that this function handles promisc mode toggle only.
869 * flag: set promisc off if zero, set promisc on if non-zero.
871 * positive: success and return length sent.
872 * -1 : error occured, and set errno.
873 * 0 : error occured, and set errno.
874 * others: a pointer to new allocated buffer in which supported
878 pfkey_send_promisc_toggle(so
, flag
)
884 if ((len
= pfkey_send_x3(so
, SADB_X_PROMISC
,
885 (u_int
)(flag
? 1 : 0))) < 0)
892 * sending SADB_X_SPDADD message to the kernel.
894 * positive: success and return length sent.
895 * -1 : error occured, and set errno.
898 pfkey_send_spdadd(so
, src
, prefs
, dst
, prefd
, proto
, policy
, policylen
, seq
)
900 struct sockaddr
*src
, *dst
;
901 u_int prefs
, prefd
, proto
;
908 if ((len
= pfkey_send_x4(so
, SADB_X_SPDADD
,
909 src
, prefs
, dst
, prefd
, proto
,
910 (u_int64_t
)0, (u_int64_t
)0,
911 policy
, policylen
, seq
)) < 0)
918 * sending SADB_X_SPDADD message to the kernel.
920 * positive: success and return length sent.
921 * -1 : error occured, and set errno.
924 pfkey_send_spdadd2(so
, src
, prefs
, dst
, prefd
, proto
, ltime
, vtime
,
925 policy
, policylen
, seq
)
927 struct sockaddr
*src
, *dst
;
928 u_int prefs
, prefd
, proto
;
929 u_int64_t ltime
, vtime
;
936 if ((len
= pfkey_send_x4(so
, SADB_X_SPDADD
,
937 src
, prefs
, dst
, prefd
, proto
,
939 policy
, policylen
, seq
)) < 0)
946 * sending SADB_X_SPDUPDATE message to the kernel.
948 * positive: success and return length sent.
949 * -1 : error occured, and set errno.
952 pfkey_send_spdupdate(so
, src
, prefs
, dst
, prefd
, proto
, policy
, policylen
, seq
)
954 struct sockaddr
*src
, *dst
;
955 u_int prefs
, prefd
, proto
;
962 if ((len
= pfkey_send_x4(so
, SADB_X_SPDUPDATE
,
963 src
, prefs
, dst
, prefd
, proto
,
964 (u_int64_t
)0, (u_int64_t
)0,
965 policy
, policylen
, seq
)) < 0)
972 * sending SADB_X_SPDUPDATE message to the kernel.
974 * positive: success and return length sent.
975 * -1 : error occured, and set errno.
978 pfkey_send_spdupdate2(so
, src
, prefs
, dst
, prefd
, proto
, ltime
, vtime
,
979 policy
, policylen
, seq
)
981 struct sockaddr
*src
, *dst
;
982 u_int prefs
, prefd
, proto
;
983 u_int64_t ltime
, vtime
;
990 if ((len
= pfkey_send_x4(so
, SADB_X_SPDUPDATE
,
991 src
, prefs
, dst
, prefd
, proto
,
993 policy
, policylen
, seq
)) < 0)
1000 * sending SADB_X_SPDDELETE message to the kernel.
1002 * positive: success and return length sent.
1003 * -1 : error occured, and set errno.
1006 pfkey_send_spddelete(so
, src
, prefs
, dst
, prefd
, proto
, policy
, policylen
, seq
)
1008 struct sockaddr
*src
, *dst
;
1009 u_int prefs
, prefd
, proto
;
1016 if (policylen
!= sizeof(struct sadb_x_policy
)) {
1017 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1021 if ((len
= pfkey_send_x4(so
, SADB_X_SPDDELETE
,
1022 src
, prefs
, dst
, prefd
, proto
,
1023 (u_int64_t
)0, (u_int64_t
)0,
1024 policy
, policylen
, seq
)) < 0)
1031 * sending SADB_X_SPDDELETE message to the kernel.
1033 * positive: success and return length sent.
1034 * -1 : error occured, and set errno.
1037 pfkey_send_spddelete2(so
, spid
)
1043 if ((len
= pfkey_send_x5(so
, SADB_X_SPDDELETE2
, spid
)) < 0)
1050 * sending SADB_X_SPDGET message to the kernel.
1052 * positive: success and return length sent.
1053 * -1 : error occured, and set errno.
1056 pfkey_send_spdget(so
, spid
)
1062 if ((len
= pfkey_send_x5(so
, SADB_X_SPDGET
, spid
)) < 0)
1069 * sending SADB_X_SPDSETIDX message to the kernel.
1071 * positive: success and return length sent.
1072 * -1 : error occured, and set errno.
1075 pfkey_send_spdsetidx(so
, src
, prefs
, dst
, prefd
, proto
, policy
, policylen
, seq
)
1077 struct sockaddr
*src
, *dst
;
1078 u_int prefs
, prefd
, proto
;
1085 if (policylen
!= sizeof(struct sadb_x_policy
)) {
1086 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1090 if ((len
= pfkey_send_x4(so
, SADB_X_SPDSETIDX
,
1091 src
, prefs
, dst
, prefd
, proto
,
1092 (u_int64_t
)0, (u_int64_t
)0,
1093 policy
, policylen
, seq
)) < 0)
1100 * sending SADB_SPDFLUSH message to the kernel.
1102 * positive: success and return length sent.
1103 * -1 : error occured, and set errno.
1106 pfkey_send_spdflush(so
)
1111 if ((len
= pfkey_send_x3(so
, SADB_X_SPDFLUSH
, SADB_SATYPE_UNSPEC
)) < 0)
1118 * sending SADB_SPDDUMP message to the kernel.
1120 * positive: success and return length sent.
1121 * -1 : error occured, and set errno.
1124 pfkey_send_spddump(so
)
1129 if ((len
= pfkey_send_x3(so
, SADB_X_SPDDUMP
, SADB_SATYPE_UNSPEC
)) < 0)
1136 /* sending SADB_ADD or SADB_UPDATE message to the kernel */
1138 pfkey_send_x1(so
, type
, satype
, mode
, src
, dst
, spi
, reqid
, wsize
,
1139 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
1140 l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
, port
)
1142 u_int type
, satype
, mode
;
1143 struct sockaddr
*src
, *dst
;
1144 u_int32_t spi
, reqid
;
1147 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
1148 u_int32_t l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
;
1151 struct sadb_msg
*newmsg
;
1157 /* validity check */
1158 if (src
== NULL
|| dst
== NULL
) {
1159 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1162 if (src
->sa_family
!= dst
->sa_family
) {
1163 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1166 switch (src
->sa_family
) {
1168 plen
= sizeof(struct in_addr
) << 3;
1171 plen
= sizeof(struct in6_addr
) << 3;
1174 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1179 case SADB_SATYPE_ESP
:
1180 if (e_type
== SADB_EALG_NONE
) {
1181 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1185 case SADB_SATYPE_AH
:
1186 if (e_type
!= SADB_EALG_NONE
) {
1187 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1190 if (a_type
== SADB_AALG_NONE
) {
1191 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1195 case SADB_X_SATYPE_IPCOMP
:
1196 if (e_type
== SADB_X_CALG_NONE
) {
1197 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1200 if (a_type
!= SADB_AALG_NONE
) {
1201 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1205 #ifdef SADB_X_AALG_TCP_MD5
1206 case SADB_X_SATYPE_TCPSIGNATURE
:
1207 if (e_type
!= SADB_EALG_NONE
) {
1208 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1211 if (a_type
!= SADB_X_AALG_TCP_MD5
) {
1212 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1218 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1222 /* create new sadb_msg to reply. */
1223 len
= sizeof(struct sadb_msg
)
1224 + sizeof(struct sadb_sa_2
)
1225 + sizeof(struct sadb_x_sa2
)
1226 + sizeof(struct sadb_address
)
1227 + PFKEY_ALIGN8(sysdep_sa_len(src
))
1228 + sizeof(struct sadb_address
)
1229 + PFKEY_ALIGN8(sysdep_sa_len(dst
))
1230 + sizeof(struct sadb_lifetime
)
1231 + sizeof(struct sadb_lifetime
);
1233 if (e_type
!= SADB_EALG_NONE
&& satype
!= SADB_X_SATYPE_IPCOMP
)
1234 len
+= (sizeof(struct sadb_key
) + PFKEY_ALIGN8(e_keylen
));
1235 if (a_type
!= SADB_AALG_NONE
)
1236 len
+= (sizeof(struct sadb_key
) + PFKEY_ALIGN8(a_keylen
));
1238 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1239 __ipsec_set_strerror(strerror(errno
));
1242 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1244 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
,
1245 satype
, seq
, getpid());
1250 p
= pfkey_setsadbsa(p
, ep
, spi
, wsize
, a_type
, e_type
, flags
, port
);
1255 p
= pfkey_setsadbxsa2(p
, ep
, mode
, reqid
);
1260 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
1266 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
1273 if (e_type
!= SADB_EALG_NONE
&& satype
!= SADB_X_SATYPE_IPCOMP
) {
1274 p
= pfkey_setsadbkey(p
, ep
, SADB_EXT_KEY_ENCRYPT
,
1281 if (a_type
!= SADB_AALG_NONE
) {
1282 p
= pfkey_setsadbkey(p
, ep
, SADB_EXT_KEY_AUTH
,
1283 keymat
+ e_keylen
, a_keylen
);
1290 /* set sadb_lifetime for destination */
1291 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_HARD
,
1292 l_alloc
, l_bytes
, l_addtime
, l_usetime
);
1297 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_SOFT
,
1298 l_alloc
, l_bytes
, l_addtime
, l_usetime
);
1310 len
= pfkey_send(so
, newmsg
, len
);
1316 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1321 /* sending SADB_DELETE or SADB_GET message to the kernel */
1324 pfkey_send_x2(so
, type
, satype
, mode
, src
, dst
, spi
)
1326 u_int type
, satype
, mode
;
1327 struct sockaddr
*src
, *dst
;
1330 struct sadb_msg
*newmsg
;
1336 /* validity check */
1337 if (src
== NULL
|| dst
== NULL
) {
1338 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1341 if (src
->sa_family
!= dst
->sa_family
) {
1342 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1345 switch (src
->sa_family
) {
1347 plen
= sizeof(struct in_addr
) << 3;
1350 plen
= sizeof(struct in6_addr
) << 3;
1353 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1357 /* create new sadb_msg to reply. */
1358 len
= sizeof(struct sadb_msg
)
1359 + sizeof(struct sadb_sa_2
)
1360 + sizeof(struct sadb_address
)
1361 + PFKEY_ALIGN8(sysdep_sa_len(src
))
1362 + sizeof(struct sadb_address
)
1363 + PFKEY_ALIGN8(sysdep_sa_len(dst
));
1365 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1366 __ipsec_set_strerror(strerror(errno
));
1369 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1371 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
, satype
, 0,
1377 p
= pfkey_setsadbsa(p
, ep
, spi
, 0, 0, 0, 0, 0);
1382 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, (u_int
)plen
,
1388 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, (u_int
)plen
,
1390 if (!p
|| p
!= ep
) {
1396 len
= pfkey_send(so
, newmsg
, len
);
1402 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1407 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message
1411 pfkey_send_x3(so
, type
, satype
)
1415 struct sadb_msg
*newmsg
;
1420 /* validity check */
1422 case SADB_X_PROMISC
:
1423 if (satype
!= 0 && satype
!= 1) {
1424 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1430 case SADB_SATYPE_UNSPEC
:
1431 case SADB_SATYPE_AH
:
1432 case SADB_SATYPE_ESP
:
1433 case SADB_X_SATYPE_IPCOMP
:
1434 #ifdef SADB_X_SATYPE_TCPSIGNATURE
1435 case SADB_X_SATYPE_TCPSIGNATURE
:
1439 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1444 /* create new sadb_msg to send. */
1445 len
= sizeof(struct sadb_msg
);
1447 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1448 __ipsec_set_strerror(strerror(errno
));
1451 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1453 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
, satype
, 0,
1455 if (!p
|| p
!= ep
) {
1461 len
= pfkey_send(so
, newmsg
, len
);
1467 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1471 /* sending SADB_X_SPDADD message to the kernel */
1473 pfkey_send_x4(so
, type
, src
, prefs
, dst
, prefd
, proto
,
1474 ltime
, vtime
, policy
, policylen
, seq
)
1476 struct sockaddr
*src
, *dst
;
1477 u_int type
, prefs
, prefd
, proto
;
1478 u_int64_t ltime
, vtime
;
1483 struct sadb_msg
*newmsg
;
1489 /* validity check */
1490 if (src
== NULL
|| dst
== NULL
) {
1491 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1494 if (src
->sa_family
!= dst
->sa_family
) {
1495 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1499 switch (src
->sa_family
) {
1501 plen
= sizeof(struct in_addr
) << 3;
1504 plen
= sizeof(struct in6_addr
) << 3;
1507 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1510 if (prefs
> plen
|| prefd
> plen
) {
1511 __ipsec_errcode
= EIPSEC_INVAL_PREFIXLEN
;
1515 /* create new sadb_msg to reply. */
1516 len
= sizeof(struct sadb_msg
)
1517 + sizeof(struct sadb_address
)
1518 + PFKEY_ALIGN8(sysdep_sa_len(src
))
1519 + sizeof(struct sadb_address
)
1520 + PFKEY_ALIGN8(sysdep_sa_len(src
))
1521 + sizeof(struct sadb_lifetime
)
1524 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1525 __ipsec_set_strerror(strerror(errno
));
1528 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1530 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
,
1531 SADB_SATYPE_UNSPEC
, seq
, getpid());
1536 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, prefs
, proto
);
1541 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, prefd
, proto
);
1546 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_HARD
,
1547 0, 0, (u_int
)ltime
, (u_int
)vtime
);
1548 if (!p
|| p
+ policylen
!= ep
) {
1552 memcpy(p
, policy
, (size_t)policylen
);
1555 len
= pfkey_send(so
, newmsg
, len
);
1561 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1565 /* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */
1567 pfkey_send_x5(so
, type
, spid
)
1572 struct sadb_msg
*newmsg
;
1573 struct sadb_x_policy xpl
;
1578 /* create new sadb_msg to reply. */
1579 len
= sizeof(struct sadb_msg
)
1582 if ((newmsg
= CALLOC((size_t)len
, struct sadb_msg
*)) == NULL
) {
1583 __ipsec_set_strerror(strerror(errno
));
1586 ep
= ((caddr_t
)(void *)newmsg
) + len
;
1588 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, type
, (u_int
)len
,
1589 SADB_SATYPE_UNSPEC
, 0, getpid());
1595 if (p
+ sizeof(xpl
) != ep
) {
1599 memset(&xpl
, 0, sizeof(xpl
));
1600 xpl
.sadb_x_policy_len
= PFKEY_UNIT64(sizeof(xpl
));
1601 xpl
.sadb_x_policy_exttype
= SADB_X_EXT_POLICY
;
1602 xpl
.sadb_x_policy_id
= spid
;
1603 memcpy(p
, &xpl
, sizeof(xpl
));
1606 len
= pfkey_send(so
, newmsg
, len
);
1612 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1620 * others : success and return value of socket.
1626 int bufsiz
= 0; /* Max allowed by default */
1627 const unsigned long newbufk
= 1536;
1628 unsigned long oldmax
;
1629 size_t oldmaxsize
= sizeof(oldmax
);
1630 unsigned long newmax
= newbufk
* (1024 + 128);
1632 if ((so
= socket(PF_KEY
, SOCK_RAW
, PF_KEY_V2
)) < 0) {
1633 __ipsec_set_strerror(strerror(errno
));
1638 * This is a temporary workaround for KAME PR 154.
1639 * Don't really care even if it fails.
1641 if (sysctlbyname("kern.ipc.maxsockbuf", &oldmax
, &oldmaxsize
, &newmax
, sizeof(newmax
)) != 0)
1642 bufsiz
= 233016; /* Max allowed by default */
1644 bufsiz
= newbufk
* 1024;
1646 setsockopt(so
, SOL_SOCKET
, SO_SNDBUF
, &bufsiz
, sizeof(bufsiz
));
1647 setsockopt(so
, SOL_SOCKET
, SO_RCVBUF
, &bufsiz
, sizeof(bufsiz
));
1649 if (bufsiz
== newbufk
* 1024)
1650 sysctlbyname("kern.ipc.maxsockbuf", NULL
, NULL
, &oldmax
, oldmaxsize
);
1652 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1668 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1673 * receive sadb_msg data, and return pointer to new buffer allocated.
1674 * Must free this buffer later.
1676 * NULL : error occured.
1677 * others : a pointer to sadb_msg structure.
1679 * XXX should be rewritten to pass length explicitly
1685 struct sadb_msg buf
, *newmsg
;
1688 while ((len
= recv(so
, (void *)&buf
, sizeof(buf
), MSG_PEEK
)) < 0) {
1691 __ipsec_set_strerror(strerror(errno
));
1695 if (len
< sizeof(buf
)) {
1696 recv(so
, (void *)&buf
, sizeof(buf
), 0);
1697 __ipsec_errcode
= EIPSEC_MAX
;
1701 /* read real message */
1702 reallen
= PFKEY_UNUNIT64(buf
.sadb_msg_len
);
1703 if ((newmsg
= CALLOC((size_t)reallen
, struct sadb_msg
*)) == 0) {
1704 __ipsec_set_strerror(strerror(errno
));
1708 while ((len
= recv(so
, (void *)newmsg
, (socklen_t
)reallen
, 0)) < 0) {
1711 __ipsec_set_strerror(strerror(errno
));
1716 if (len
!= reallen
) {
1717 __ipsec_errcode
= EIPSEC_SYSTEM_ERROR
;
1722 /* don't trust what the kernel says, validate! */
1723 if (PFKEY_UNUNIT64(newmsg
->sadb_msg_len
) != len
) {
1724 __ipsec_errcode
= EIPSEC_SYSTEM_ERROR
;
1729 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1734 * send message to a socket.
1736 * others: success and return length sent.
1740 pfkey_send(so
, msg
, len
)
1742 struct sadb_msg
*msg
;
1745 if ((len
= send(so
, (void *)msg
, (socklen_t
)len
, 0)) < 0) {
1746 __ipsec_set_strerror(strerror(errno
));
1750 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1756 * NOTE: These functions are derived from netkey/key.c in KAME.
1759 * set the pointer to each header in this message buffer.
1760 * IN: msg: pointer to message buffer.
1761 * mhp: pointer to the buffer initialized like below:
1762 * caddr_t mhp[SADB_EXT_MAX + 1];
1766 * XXX should be rewritten to obtain length explicitly
1769 pfkey_align(msg
, mhp
)
1770 struct sadb_msg
*msg
;
1773 struct sadb_ext
*ext
;
1776 caddr_t ep
; /* XXX should be passed from upper layer */
1778 /* validity check */
1779 if (msg
== NULL
|| mhp
== NULL
) {
1780 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1785 for (i
= 0; i
< SADB_EXT_MAX
+ 1; i
++)
1788 mhp
[0] = (void *)msg
;
1792 ep
= p
+ PFKEY_UNUNIT64(msg
->sadb_msg_len
);
1794 /* skip base header */
1795 p
+= sizeof(struct sadb_msg
);
1799 if (ep
< p
+ sizeof(*ext
) || PFKEY_EXTLEN(ext
) < sizeof(*ext
) ||
1800 ep
< p
+ PFKEY_EXTLEN(ext
)) {
1801 /* invalid format */
1805 /* duplicate check */
1806 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/
1807 if (mhp
[ext
->sadb_ext_type
] != NULL
) {
1808 __ipsec_errcode
= EIPSEC_INVAL_EXTTYPE
;
1813 switch (ext
->sadb_ext_type
) {
1815 case SADB_EXT_LIFETIME_CURRENT
:
1816 case SADB_EXT_LIFETIME_HARD
:
1817 case SADB_EXT_LIFETIME_SOFT
:
1818 case SADB_EXT_ADDRESS_SRC
:
1819 case SADB_EXT_ADDRESS_DST
:
1820 case SADB_EXT_ADDRESS_PROXY
:
1821 case SADB_EXT_KEY_AUTH
:
1822 /* XXX should to be check weak keys. */
1823 case SADB_EXT_KEY_ENCRYPT
:
1824 /* XXX should to be check weak keys. */
1825 case SADB_EXT_IDENTITY_SRC
:
1826 case SADB_EXT_IDENTITY_DST
:
1827 case SADB_EXT_SENSITIVITY
:
1828 case SADB_EXT_PROPOSAL
:
1829 case SADB_EXT_SUPPORTED_AUTH
:
1830 case SADB_EXT_SUPPORTED_ENCRYPT
:
1831 case SADB_EXT_SPIRANGE
:
1832 case SADB_X_EXT_POLICY
:
1833 case SADB_X_EXT_SA2
:
1834 case SADB_EXT_SESSION_ID
:
1835 case SADB_EXT_SASTAT
:
1836 #ifdef SADB_X_EXT_NAT_T_TYPE
1837 case SADB_X_EXT_NAT_T_TYPE
:
1838 case SADB_X_EXT_NAT_T_SPORT
:
1839 case SADB_X_EXT_NAT_T_DPORT
:
1840 case SADB_X_EXT_NAT_T_OA
:
1842 #ifdef SADB_X_EXT_TAG
1843 case SADB_X_EXT_TAG
:
1845 #ifdef SADB_X_EXT_PACKET
1846 case SADB_X_EXT_PACKET
:
1849 mhp
[ext
->sadb_ext_type
] = (void *)ext
;
1852 __ipsec_errcode
= EIPSEC_INVAL_EXTTYPE
;
1856 p
+= PFKEY_EXTLEN(ext
);
1860 __ipsec_errcode
= EIPSEC_INVAL_SADBMSG
;
1864 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1869 * check basic usage for sadb_msg,
1870 * NOTE: This routine is derived from netkey/key.c in KAME.
1871 * IN: msg: pointer to message buffer.
1872 * mhp: pointer to the buffer initialized like below:
1874 * caddr_t mhp[SADB_EXT_MAX + 1];
1883 struct sadb_msg
*msg
;
1885 /* validity check */
1886 if (mhp
== NULL
|| mhp
[0] == NULL
) {
1887 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1891 msg
= (void *)mhp
[0];
1894 if (msg
->sadb_msg_version
!= PF_KEY_V2
) {
1895 __ipsec_errcode
= EIPSEC_INVAL_VERSION
;
1900 if (msg
->sadb_msg_type
> SADB_MAX
) {
1901 __ipsec_errcode
= EIPSEC_INVAL_MSGTYPE
;
1906 switch (msg
->sadb_msg_satype
) {
1907 case SADB_SATYPE_UNSPEC
:
1908 switch (msg
->sadb_msg_type
) {
1916 #ifdef SADB_X_NAT_T_NEW_MAPPING
1917 case SADB_X_NAT_T_NEW_MAPPING
:
1919 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1923 case SADB_SATYPE_ESP
:
1924 case SADB_SATYPE_AH
:
1925 case SADB_X_SATYPE_IPCOMP
:
1926 #ifdef SADB_X_SATYPE_TCPSIGNATURE
1927 case SADB_X_SATYPE_TCPSIGNATURE
:
1929 switch (msg
->sadb_msg_type
) {
1931 case SADB_X_SPDDELETE
:
1933 case SADB_X_SPDDUMP
:
1934 case SADB_X_SPDFLUSH
:
1935 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1938 #ifdef SADB_X_NAT_T_NEW_MAPPING
1939 if (msg
->sadb_msg_type
== SADB_X_NAT_T_NEW_MAPPING
&&
1940 msg
->sadb_msg_satype
!= SADB_SATYPE_ESP
) {
1941 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1946 case SADB_SATYPE_RSVP
:
1947 case SADB_SATYPE_OSPFV2
:
1948 case SADB_SATYPE_RIPV2
:
1949 case SADB_SATYPE_MIP
:
1950 __ipsec_errcode
= EIPSEC_NOT_SUPPORTED
;
1952 case 1: /* XXX: What does it do ? */
1953 if (msg
->sadb_msg_type
== SADB_X_PROMISC
)
1957 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1961 /* check field of upper layer protocol and address family */
1962 if (mhp
[SADB_EXT_ADDRESS_SRC
] != NULL
1963 && mhp
[SADB_EXT_ADDRESS_DST
] != NULL
) {
1964 struct sadb_address
*src0
, *dst0
;
1966 src0
= (void *)(mhp
[SADB_EXT_ADDRESS_SRC
]);
1967 dst0
= (void *)(mhp
[SADB_EXT_ADDRESS_DST
]);
1969 if (src0
->sadb_address_proto
!= dst0
->sadb_address_proto
) {
1970 __ipsec_errcode
= EIPSEC_PROTO_MISMATCH
;
1974 if (PFKEY_ADDR_SADDR(src0
)->sa_family
1975 != PFKEY_ADDR_SADDR(dst0
)->sa_family
) {
1976 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1980 switch (PFKEY_ADDR_SADDR(src0
)->sa_family
) {
1985 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1990 * prefixlen == 0 is valid because there must be the case
1991 * all addresses are matched.
1995 __ipsec_errcode
= EIPSEC_NO_ERROR
;
2000 * set data into sadb_msg.
2001 * `buf' must has been allocated sufficiently.
2004 pfkey_setsadbmsg(buf
, lim
, type
, tlen
, satype
, seq
, pid
)
2016 len
= sizeof(struct sadb_msg
);
2018 if (buf
+ len
> lim
)
2022 p
->sadb_msg_version
= PF_KEY_V2
;
2023 p
->sadb_msg_type
= type
;
2024 p
->sadb_msg_errno
= 0;
2025 p
->sadb_msg_satype
= satype
;
2026 p
->sadb_msg_len
= PFKEY_UNIT64(tlen
);
2027 p
->sadb_msg_reserved
= 0;
2028 p
->sadb_msg_seq
= seq
;
2029 p
->sadb_msg_pid
= (u_int32_t
)pid
;
2035 * copy secasvar data into sadb_address.
2036 * `buf' must has been allocated sufficiently.
2039 pfkey_setsadbsa(buf
, lim
, spi
, wsize
, auth
, enc
, flags
, port
)
2042 u_int32_t spi
, flags
;
2043 u_int wsize
, auth
, enc
;
2046 struct sadb_sa_2
*p
;
2050 len
= sizeof(struct sadb_sa_2
);
2052 if (buf
+ len
> lim
)
2056 p
->sa
.sadb_sa_len
= PFKEY_UNIT64(len
);
2057 p
->sa
.sadb_sa_exttype
= SADB_EXT_SA
;
2058 p
->sa
.sadb_sa_spi
= spi
;
2059 p
->sa
.sadb_sa_replay
= wsize
;
2060 p
->sa
.sadb_sa_state
= SADB_SASTATE_LARVAL
;
2061 p
->sa
.sadb_sa_auth
= auth
;
2062 p
->sa
.sadb_sa_encrypt
= enc
;
2063 p
->sa
.sadb_sa_flags
= flags
;
2064 p
->sadb_sa_natt_port
= port
;
2070 * set data into sadb_address.
2071 * `buf' must has been allocated sufficiently.
2072 * prefixlen is in bits.
2075 pfkey_setsadbaddr(buf
, lim
, exttype
, saddr
, prefixlen
, ul_proto
)
2079 struct sockaddr
*saddr
;
2083 struct sadb_address
*p
;
2087 len
= sizeof(struct sadb_address
) + PFKEY_ALIGN8(sysdep_sa_len(saddr
));
2089 if (buf
+ len
> lim
)
2093 p
->sadb_address_len
= PFKEY_UNIT64(len
);
2094 p
->sadb_address_exttype
= exttype
& 0xffff;
2095 p
->sadb_address_proto
= ul_proto
& 0xff;
2096 p
->sadb_address_prefixlen
= prefixlen
;
2097 p
->sadb_address_reserved
= 0;
2099 memcpy(p
+ 1, saddr
, (size_t)sysdep_sa_len(saddr
));
2105 * set sadb_key structure after clearing buffer with zero.
2106 * OUT: the pointer of buf + len.
2109 pfkey_setsadbkey(buf
, lim
, type
, key
, keylen
)
2119 len
= sizeof(struct sadb_key
) + PFKEY_ALIGN8(keylen
);
2121 if (buf
+ len
> lim
)
2125 p
->sadb_key_len
= PFKEY_UNIT64(len
);
2126 p
->sadb_key_exttype
= type
;
2127 p
->sadb_key_bits
= keylen
<< 3;
2128 p
->sadb_key_reserved
= 0;
2130 memcpy(p
+ 1, key
, keylen
);
2136 * set sadb_lifetime structure after clearing buffer with zero.
2137 * OUT: the pointer of buf + len.
2140 pfkey_setsadblifetime(buf
, lim
, type
, l_alloc
, l_bytes
, l_addtime
, l_usetime
)
2144 u_int32_t l_alloc
, l_bytes
, l_addtime
, l_usetime
;
2146 struct sadb_lifetime
*p
;
2150 len
= sizeof(struct sadb_lifetime
);
2152 if (buf
+ len
> lim
)
2156 p
->sadb_lifetime_len
= PFKEY_UNIT64(len
);
2157 p
->sadb_lifetime_exttype
= type
;
2160 case SADB_EXT_LIFETIME_SOFT
:
2161 p
->sadb_lifetime_allocations
2162 = (l_alloc
* soft_lifetime_allocations_rate
) /100;
2163 p
->sadb_lifetime_bytes
2164 = (l_bytes
* soft_lifetime_bytes_rate
) /100;
2165 p
->sadb_lifetime_addtime
2166 = (l_addtime
* soft_lifetime_addtime_rate
) /100;
2167 p
->sadb_lifetime_usetime
2168 = (l_usetime
* soft_lifetime_usetime_rate
) /100;
2170 case SADB_EXT_LIFETIME_HARD
:
2171 p
->sadb_lifetime_allocations
= l_alloc
;
2172 p
->sadb_lifetime_bytes
= l_bytes
;
2173 p
->sadb_lifetime_addtime
= l_addtime
;
2174 p
->sadb_lifetime_usetime
= l_usetime
;
2182 * copy secasvar data into sadb_address.
2183 * `buf' must has been allocated sufficiently.
2186 pfkey_setsadbxsa2(buf
, lim
, mode0
, reqid
)
2192 struct sadb_x_sa2
*p
;
2193 u_int8_t mode
= mode0
& 0xff;
2197 len
= sizeof(struct sadb_x_sa2
);
2199 if (buf
+ len
> lim
)
2203 p
->sadb_x_sa2_len
= PFKEY_UNIT64(len
);
2204 p
->sadb_x_sa2_exttype
= SADB_X_EXT_SA2
;
2205 p
->sadb_x_sa2_mode
= mode
;
2206 p
->sadb_x_sa2_reqid
= reqid
;
2211 #ifdef SADB_X_EXT_NAT_T_TYPE
2213 pfkey_set_natt_type(buf
, lim
, type
, l_natt_type
)
2217 u_int8_t l_natt_type
;
2219 struct sadb_x_nat_t_type
*p
;
2223 len
= sizeof(struct sadb_x_nat_t_type
);
2225 if (buf
+ len
> lim
)
2229 p
->sadb_x_nat_t_type_len
= PFKEY_UNIT64(len
);
2230 p
->sadb_x_nat_t_type_exttype
= type
;
2231 p
->sadb_x_nat_t_type_type
= l_natt_type
;
2237 pfkey_set_natt_port(buf
, lim
, type
, l_natt_port
)
2241 u_int16_t l_natt_port
;
2243 struct sadb_x_nat_t_port
*p
;
2247 len
= sizeof(struct sadb_x_nat_t_port
);
2249 if (buf
+ len
> lim
)
2253 p
->sadb_x_nat_t_port_len
= PFKEY_UNIT64(len
);
2254 p
->sadb_x_nat_t_port_exttype
= type
;
2255 p
->sadb_x_nat_t_port_port
= htons(l_natt_port
);
2261 #ifdef SADB_X_EXT_NAT_T_FRAG
2263 pfkey_set_natt_frag(buf
, lim
, type
, l_natt_frag
)
2267 u_int16_t l_natt_frag
;
2269 struct sadb_x_nat_t_frag
*p
;
2273 len
= sizeof(struct sadb_x_nat_t_frag
);
2275 if (buf
+ len
> lim
)
2279 p
->sadb_x_nat_t_frag_len
= PFKEY_UNIT64(len
);
2280 p
->sadb_x_nat_t_frag_exttype
= type
;
2281 p
->sadb_x_nat_t_frag_fraglen
= l_natt_frag
;
2288 pfkey_setsadbsession_id (caddr_t buf
,
2290 u_int64_t session_ids
[],
2291 u_int32_t max_session_ids
)
2293 struct sadb_session_id
*p
;
2296 if (!max_session_ids
)
2302 if (buf
+ len
> lim
)
2306 p
->sadb_session_id_len
= PFKEY_UNIT64(len
);
2307 p
->sadb_session_id_exttype
= SADB_EXT_SESSION_ID
;
2308 p
->sadb_session_id_v
[0] = session_ids
[0];
2309 if (max_session_ids
> 1)
2310 p
->sadb_session_id_v
[1] = session_ids
[1];
2316 pfkey_setsadbsastats (caddr_t buf
,
2319 struct sastat
*stats
,
2320 u_int32_t max_stats
)
2322 struct sadb_sastat
*p
;
2323 u_int len
, list_len
;
2325 if (!stats
|| !max_stats
)
2328 p
= (__typeof__(p
))buf
;
2329 list_len
= sizeof(*stats
) * max_stats
;
2330 len
= sizeof(*p
) + PFKEY_ALIGN8(list_len
);
2332 if (buf
+ len
> lim
)
2336 p
->sadb_sastat_len
= PFKEY_UNIT64(len
);
2337 p
->sadb_sastat_exttype
= SADB_EXT_SASTAT
;
2338 p
->sadb_sastat_dir
= dir
;
2339 p
->sadb_sastat_list_len
= max_stats
;
2340 bcopy(stats
, p
+ 1, list_len
);
2346 pfkey_send_getsastats (int so
,
2348 u_int64_t
*session_ids
,
2349 u_int32_t max_session_ids
,
2351 struct sastat
*stats
,
2352 u_int32_t max_stats
)
2354 struct sadb_msg
*newmsg
;
2356 int list_len
, out_len
, len
;
2359 if (!session_ids
|| !stats
|| !max_stats
) {
2363 list_len
= sizeof(*stats
) * max_stats
;
2364 /* create new sadb_msg to send. */
2365 out_len
= sizeof(struct sadb_msg
) + sizeof(struct sadb_session_id
) + sizeof(struct sadb_sastat
) + PFKEY_ALIGN8(list_len
);
2367 if ((newmsg
= CALLOC((size_t)out_len
, struct sadb_msg
*)) == NULL
) {
2368 __ipsec_set_strerror(strerror(errno
));
2371 ep
= ((caddr_t
)(void *)newmsg
) + out_len
;
2373 p
= pfkey_setsadbmsg((void *)newmsg
, ep
, SADB_GETSASTAT
, (u_int
)out_len
, SADB_SATYPE_UNSPEC
, seq
, getpid());
2379 p
= pfkey_setsadbsession_id(p
, ep
, session_ids
, max_session_ids
);
2385 p
= pfkey_setsadbsastats(p
, ep
, dir
, stats
, max_stats
);
2392 len
= pfkey_send(so
, newmsg
, out_len
);
2398 __ipsec_errcode
= EIPSEC_NO_ERROR
;