2 * Copyright (c) 2003-2007 Apple Computer, Inc. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 /* $FreeBSD: src/lib/libipsec/pfkey.c,v 1.1.2.2 2001/07/03 11:01:14 ume Exp $ */
17 /* $KAME: pfkey.c,v 1.39 2001/03/05 18:22:17 thorpej Exp $ */
20 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
21 * All rights reserved.
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
26 * 1. Redistributions of source code must retain the above copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. Neither the name of the project nor the names of its contributors
32 * may be used to endorse or promote products derived from this software
33 * without specific prior written permission.
35 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
36 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
39 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 #include <sys/types.h>
49 #include <sys/param.h>
50 #include <sys/socket.h>
51 #include <net/pfkeyv2.h>
52 #include <netinet/in.h>
53 #include <netinet6/ipsec.h>
60 #include <TargetConditionals.h>
62 #include "ipsec_strerror.h"
64 #include "ipsec_options.h"
66 #if TARGET_OS_EMBEDDED
68 #define MDNS_NO_IPSEC 1
74 #define CALLOC(size, cast) (cast)calloc(1, (size))
76 static int findsupportedmap
__P((int));
77 static int setsupportedmap
__P((struct sadb_supported
*));
78 static struct sadb_alg
*findsupportedalg
__P((u_int
, u_int
));
79 static int pfkey_send_x1
__P((int, u_int
, u_int
, u_int
, struct sockaddr
*,
80 struct sockaddr
*, u_int32_t
, u_int32_t
, u_int
, caddr_t
,
81 u_int
, u_int
, u_int
, u_int
, u_int
, u_int32_t
, u_int32_t
,
82 u_int32_t
, u_int32_t
, u_int32_t
));
83 static int pfkey_send_x2
__P((int, u_int
, u_int
, u_int
,
84 struct sockaddr
*, struct sockaddr
*, u_int32_t
));
85 static int pfkey_send_x3
__P((int, u_int
, u_int
));
86 static int pfkey_send_x4
__P((int, u_int
, struct sockaddr
*, u_int
,
87 struct sockaddr
*, u_int
, u_int
, u_int64_t
, u_int64_t
,
88 char *, int, u_int32_t
));
89 static int pfkey_send_x5
__P((int, u_int
, u_int32_t
));
91 static caddr_t pfkey_setsadbmsg
__P((caddr_t
, caddr_t
, u_int
, u_int
,
92 u_int
, u_int32_t
, pid_t
));
93 static caddr_t pfkey_setsadbsa
__P((caddr_t
, caddr_t
, u_int32_t
, u_int
,
94 u_int
, u_int
, u_int32_t
));
95 static caddr_t pfkey_setsadbaddr
__P((caddr_t
, caddr_t
, u_int
,
96 struct sockaddr
*, u_int
, u_int
));
97 static caddr_t pfkey_setsadbkey
__P((caddr_t
, caddr_t
, u_int
, caddr_t
, u_int
));
98 static caddr_t pfkey_setsadblifetime
__P((caddr_t
, caddr_t
, u_int
, u_int32_t
,
99 u_int32_t
, u_int32_t
, u_int32_t
));
100 static caddr_t pfkey_setsadbxsa2
__P((caddr_t
, caddr_t
, u_int32_t
, u_int32_t
));
103 * make and search supported algorithm structure.
105 static struct sadb_supported
*ipsec_supported
[] = { NULL
, NULL
, NULL
, };
107 static int supported_map
[] = {
110 SADB_X_SATYPE_IPCOMP
,
114 findsupportedmap(satype
)
119 for (i
= 0; (unsigned int)i
< sizeof(supported_map
)/sizeof(supported_map
[0]); i
++)
120 if (supported_map
[i
] == satype
)
125 static struct sadb_alg
*
126 findsupportedalg(satype
, alg_id
)
127 u_int satype
, alg_id
;
134 algno
= findsupportedmap(satype
);
136 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
139 if (ipsec_supported
[algno
] == NULL
) {
140 __ipsec_errcode
= EIPSEC_DO_GET_SUPP_LIST
;
144 tlen
= ipsec_supported
[algno
]->sadb_supported_len
145 - sizeof(struct sadb_supported
);
146 p
= (caddr_t
)(ipsec_supported
[algno
] + 1);
148 if ((unsigned int)tlen
< sizeof(struct sadb_alg
)) {
152 if (((struct sadb_alg
*)p
)->sadb_alg_id
== alg_id
)
153 return (struct sadb_alg
*)p
;
155 tlen
-= sizeof(struct sadb_alg
);
156 p
+= sizeof(struct sadb_alg
);
159 __ipsec_errcode
= EIPSEC_NOT_SUPPORTED
;
165 struct sadb_supported
*sup
;
167 struct sadb_supported
**ipsup
;
169 switch (sup
->sadb_supported_exttype
) {
170 case SADB_EXT_SUPPORTED_AUTH
:
171 ipsup
= &ipsec_supported
[findsupportedmap(SADB_SATYPE_AH
)];
173 case SADB_EXT_SUPPORTED_ENCRYPT
:
174 ipsup
= &ipsec_supported
[findsupportedmap(SADB_SATYPE_ESP
)];
177 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
184 *ipsup
= malloc(sup
->sadb_supported_len
);
186 __ipsec_set_strerror(strerror(errno
));
189 memcpy(*ipsup
, sup
, sup
->sadb_supported_len
);
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.
204 ipsec_check_keylen(supported
, alg_id
, keylen
)
213 case SADB_EXT_SUPPORTED_AUTH
:
214 satype
= SADB_SATYPE_AH
;
216 case SADB_EXT_SUPPORTED_ENCRYPT
:
217 satype
= SADB_SATYPE_ESP
;
220 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
224 return ipsec_check_keylen2(satype
, alg_id
, keylen
);
228 * check key length against algorithm specified.
229 * satype is one of satype defined at pfkeyv2.h.
230 * keylen is the unit of bit.
236 ipsec_check_keylen2(satype
, alg_id
, keylen
)
241 struct sadb_alg
*alg
;
243 alg
= findsupportedalg(satype
, alg_id
);
247 if (keylen
< alg
->sadb_alg_minbits
|| keylen
> alg
->sadb_alg_maxbits
) {
248 __ipsec_errcode
= EIPSEC_INVAL_KEYLEN
;
252 __ipsec_errcode
= EIPSEC_NO_ERROR
;
257 * get max/min key length against algorithm specified.
258 * satype is one of satype defined at pfkeyv2.h.
259 * keylen is the unit of bit.
265 ipsec_get_keylen(supported
, alg_id
, alg0
)
266 u_int supported
, alg_id
;
267 struct sadb_alg
*alg0
;
269 struct sadb_alg
*alg
;
274 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
279 case SADB_EXT_SUPPORTED_AUTH
:
280 satype
= SADB_SATYPE_AH
;
282 case SADB_EXT_SUPPORTED_ENCRYPT
:
283 satype
= SADB_SATYPE_ESP
;
286 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
290 alg
= findsupportedalg(satype
, alg_id
);
294 memcpy(alg0
, alg
, sizeof(*alg0
));
296 __ipsec_errcode
= EIPSEC_NO_ERROR
;
301 * set the rate for SOFT lifetime against HARD one.
302 * If rate is more than 100 or equal to zero, then set to 100.
304 static u_int soft_lifetime_allocations_rate
= PFKEY_SOFT_LIFETIME_RATE
;
305 static u_int soft_lifetime_bytes_rate
= PFKEY_SOFT_LIFETIME_RATE
;
306 static u_int soft_lifetime_addtime_rate
= PFKEY_SOFT_LIFETIME_RATE
;
307 static u_int soft_lifetime_usetime_rate
= PFKEY_SOFT_LIFETIME_RATE
;
310 pfkey_set_softrate(type
, rate
)
313 __ipsec_errcode
= EIPSEC_NO_ERROR
;
315 if (rate
> 100 || rate
== 0)
319 case SADB_X_LIFETIME_ALLOCATIONS
:
320 soft_lifetime_allocations_rate
= rate
;
322 case SADB_X_LIFETIME_BYTES
:
323 soft_lifetime_bytes_rate
= rate
;
325 case SADB_X_LIFETIME_ADDTIME
:
326 soft_lifetime_addtime_rate
= rate
;
328 case SADB_X_LIFETIME_USETIME
:
329 soft_lifetime_usetime_rate
= rate
;
333 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
338 * get current rate for SOFT lifetime against HARD one.
339 * ATTENTION: ~0 is returned if invalid type was passed.
342 pfkey_get_softrate(type
)
346 case SADB_X_LIFETIME_ALLOCATIONS
:
347 return soft_lifetime_allocations_rate
;
348 case SADB_X_LIFETIME_BYTES
:
349 return soft_lifetime_bytes_rate
;
350 case SADB_X_LIFETIME_ADDTIME
:
351 return soft_lifetime_addtime_rate
;
352 case SADB_X_LIFETIME_USETIME
:
353 return soft_lifetime_usetime_rate
;
360 * sending SADB_GETSPI message to the kernel.
362 * positive: success and return length sent.
363 * -1 : error occured, and set errno.
366 pfkey_send_getspi(so
, satype
, mode
, src
, dst
, min
, max
, reqid
, seq
)
369 struct sockaddr
*src
, *dst
;
370 u_int32_t min
, max
, reqid
, seq
;
372 struct sadb_msg
*newmsg
;
375 int need_spirange
= 0;
380 if (src
== NULL
|| dst
== NULL
) {
381 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
384 if (src
->sa_family
!= dst
->sa_family
) {
385 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
388 if (min
> max
|| (min
> 0 && min
<= 255)) {
389 __ipsec_errcode
= EIPSEC_INVAL_SPI
;
392 switch (src
->sa_family
) {
394 plen
= sizeof(struct in_addr
) << 3;
397 plen
= sizeof(struct in6_addr
) << 3;
400 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
404 /* create new sadb_msg to send. */
405 len
= sizeof(struct sadb_msg
)
406 + sizeof(struct sadb_x_sa2
)
407 + sizeof(struct sadb_address
)
408 + PFKEY_ALIGN8(src
->sa_len
)
409 + sizeof(struct sadb_address
)
410 + PFKEY_ALIGN8(dst
->sa_len
);
412 if (min
> (u_int32_t
)255 && max
< (u_int32_t
)~0) {
414 len
+= sizeof(struct sadb_spirange
);
417 if ((newmsg
= CALLOC(len
, struct sadb_msg
*)) == NULL
) {
418 __ipsec_set_strerror(strerror(errno
));
421 ep
= ((caddr_t
)newmsg
) + len
;
423 p
= pfkey_setsadbmsg((caddr_t
)newmsg
, ep
, SADB_GETSPI
,
424 len
, satype
, seq
, getpid());
430 p
= pfkey_setsadbxsa2(p
, ep
, mode
, reqid
);
436 /* set sadb_address for source */
437 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, plen
,
444 /* set sadb_address for destination */
445 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, plen
,
452 /* proccessing spi range */
454 struct sadb_spirange spirange
;
456 if (p
+ sizeof(spirange
) > ep
) {
461 memset(&spirange
, 0, sizeof(spirange
));
462 spirange
.sadb_spirange_len
= PFKEY_UNIT64(sizeof(spirange
));
463 spirange
.sadb_spirange_exttype
= SADB_EXT_SPIRANGE
;
464 spirange
.sadb_spirange_min
= min
;
465 spirange
.sadb_spirange_max
= max
;
467 memcpy(p
, &spirange
, sizeof(spirange
));
469 p
+= sizeof(spirange
);
477 len
= pfkey_send(so
, newmsg
, len
);
483 __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
)
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
;
509 if ((len
= pfkey_send_x1(so
, SADB_UPDATE
, satype
, mode
, src
, dst
, spi
,
511 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
512 l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
)) < 0)
519 * sending SADB_ADD message to the kernel.
520 * The length of key material is a_keylen + e_keylen.
522 * positive: success and return length sent.
523 * -1 : error occured, and set errno.
526 pfkey_send_add(so
, satype
, mode
, src
, dst
, spi
, reqid
, wsize
,
527 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
528 l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
)
530 u_int satype
, mode
, wsize
;
531 struct sockaddr
*src
, *dst
;
532 u_int32_t spi
, reqid
;
534 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
536 u_int64_t l_bytes
, l_addtime
, l_usetime
;
540 if ((len
= pfkey_send_x1(so
, SADB_ADD
, satype
, mode
, src
, dst
, spi
,
542 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
543 l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
)) < 0)
550 * sending SADB_DELETE message to the kernel.
552 * positive: success and return length sent.
553 * -1 : error occured, and set errno.
556 pfkey_send_delete(so
, satype
, mode
, src
, dst
, spi
)
559 struct sockaddr
*src
, *dst
;
563 if ((len
= pfkey_send_x2(so
, SADB_DELETE
, satype
, mode
, src
, dst
, spi
)) < 0)
570 * sending SADB_DELETE without spi to the kernel. This is
571 * the "delete all" request (an extension also present in
575 * positive: success and return length sent
576 * -1 : error occured, and set errno
579 pfkey_send_delete_all(so
, satype
, mode
, src
, dst
)
582 struct sockaddr
*src
, *dst
;
584 struct sadb_msg
*newmsg
;
593 if (src
== NULL
|| dst
== NULL
) {
594 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
597 if (src
->sa_family
!= dst
->sa_family
) {
598 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
601 switch (src
->sa_family
) {
603 plen
= sizeof(struct in_addr
) << 3;
606 plen
= sizeof(struct in6_addr
) << 3;
609 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
613 /* create new sadb_msg to reply. */
614 len
= sizeof(struct sadb_msg
)
615 + sizeof(struct sadb_address
)
616 + PFKEY_ALIGN8(src
->sa_len
)
617 + sizeof(struct sadb_address
)
618 + PFKEY_ALIGN8(dst
->sa_len
);
620 if ((newmsg
= CALLOC(len
, struct sadb_msg
*)) == NULL
) {
621 __ipsec_set_strerror(strerror(errno
));
624 ep
= ((caddr_t
)newmsg
) + len
;
626 p
= pfkey_setsadbmsg((caddr_t
)newmsg
, ep
, SADB_DELETE
, len
, satype
, 0,
632 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, plen
,
638 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, plen
,
646 len
= pfkey_send(so
, newmsg
, len
);
652 __ipsec_errcode
= EIPSEC_NO_ERROR
;
657 * sending SADB_GET message to the kernel.
659 * positive: success and return length sent.
660 * -1 : error occured, and set errno.
663 pfkey_send_get(so
, satype
, mode
, src
, dst
, spi
)
666 struct sockaddr
*src
, *dst
;
670 if ((len
= pfkey_send_x2(so
, SADB_GET
, satype
, mode
, src
, dst
, spi
)) < 0)
677 * sending SADB_REGISTER message to the kernel.
679 * positive: success and return length sent.
680 * -1 : error occured, and set errno.
683 pfkey_send_register(so
, satype
)
689 if (satype
== PF_UNSPEC
) {
691 (unsigned int)algno
< sizeof(supported_map
)/sizeof(supported_map
[0]);
693 if (ipsec_supported
[algno
]) {
694 free(ipsec_supported
[algno
]);
695 ipsec_supported
[algno
] = NULL
;
699 algno
= findsupportedmap(satype
);
701 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
705 if (ipsec_supported
[algno
]) {
706 free(ipsec_supported
[algno
]);
707 ipsec_supported
[algno
] = NULL
;
711 if ((len
= pfkey_send_x3(so
, SADB_REGISTER
, satype
)) < 0)
718 * receiving SADB_REGISTER message from the kernel, and copy buffer for
719 * sadb_supported returned into ipsec_supported.
721 * 0: success and return length sent.
722 * -1: error occured, and set errno.
725 pfkey_recv_register(so
)
728 pid_t pid
= getpid();
729 struct sadb_msg
*newmsg
;
732 /* receive message */
734 if ((newmsg
= pfkey_recv(so
)) == NULL
)
736 } while (newmsg
->sadb_msg_type
!= SADB_REGISTER
737 || (pid_t
)newmsg
->sadb_msg_pid
!= pid
);
740 newmsg
->sadb_msg_len
= PFKEY_UNUNIT64(newmsg
->sadb_msg_len
);
742 error
= pfkey_set_supported(newmsg
, newmsg
->sadb_msg_len
);
746 __ipsec_errcode
= EIPSEC_NO_ERROR
;
752 * receiving SADB_REGISTER message from the kernel, and copy buffer for
753 * sadb_supported returned into ipsec_supported.
754 * NOTE: sadb_msg_len must be host order.
756 * tlen: msg length, it's to makeing sure.
758 * 0: success and return length sent.
759 * -1: error occured, and set errno.
762 pfkey_set_supported(msg
, tlen
)
763 struct sadb_msg
*msg
;
766 struct sadb_supported
*sup
;
771 if (msg
->sadb_msg_len
!= tlen
) {
772 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
779 p
+= sizeof(struct sadb_msg
);
782 sup
= (struct sadb_supported
*)p
;
783 if (ep
< p
+ sizeof(*sup
) ||
784 (size_t)PFKEY_EXTLEN(sup
) < sizeof(*sup
) ||
785 ep
< p
+ sup
->sadb_supported_len
) {
790 switch (sup
->sadb_supported_exttype
) {
791 case SADB_EXT_SUPPORTED_AUTH
:
792 case SADB_EXT_SUPPORTED_ENCRYPT
:
795 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
800 sup
->sadb_supported_len
= PFKEY_EXTLEN(sup
);
802 /* set supported map */
803 if (setsupportedmap(sup
) != 0)
806 p
+= sup
->sadb_supported_len
;
810 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
814 __ipsec_errcode
= EIPSEC_NO_ERROR
;
820 * sending SADB_FLUSH message to the kernel.
822 * positive: success and return length sent.
823 * -1 : error occured, and set errno.
826 pfkey_send_flush(so
, satype
)
832 if ((len
= pfkey_send_x3(so
, SADB_FLUSH
, satype
)) < 0)
839 * sending SADB_DUMP message to the kernel.
841 * positive: success and return length sent.
842 * -1 : error occured, and set errno.
845 pfkey_send_dump(so
, satype
)
851 if ((len
= pfkey_send_x3(so
, SADB_DUMP
, satype
)) < 0)
858 * sending SADB_X_PROMISC message to the kernel.
859 * NOTE that this function handles promisc mode toggle only.
861 * flag: set promisc off if zero, set promisc on if non-zero.
863 * positive: success and return length sent.
864 * -1 : error occured, and set errno.
865 * 0 : error occured, and set errno.
866 * others: a pointer to new allocated buffer in which supported
870 pfkey_send_promisc_toggle(so
, flag
)
876 if ((len
= pfkey_send_x3(so
, SADB_X_PROMISC
, (flag
? 1 : 0))) < 0)
883 * sending SADB_X_SPDADD message to the kernel.
885 * positive: success and return length sent.
886 * -1 : error occured, and set errno.
889 pfkey_send_spdadd(so
, src
, prefs
, dst
, prefd
, proto
, policy
, policylen
, seq
)
891 struct sockaddr
*src
, *dst
;
892 u_int prefs
, prefd
, proto
;
899 if ((len
= pfkey_send_x4(so
, SADB_X_SPDADD
,
900 src
, prefs
, dst
, prefd
, proto
,
902 policy
, policylen
, seq
)) < 0)
909 * sending SADB_X_SPDADD message to the kernel.
911 * positive: success and return length sent.
912 * -1 : error occured, and set errno.
915 pfkey_send_spdadd2(so
, src
, prefs
, dst
, prefd
, proto
, ltime
, vtime
,
916 policy
, policylen
, seq
)
918 struct sockaddr
*src
, *dst
;
919 u_int prefs
, prefd
, proto
;
920 u_int64_t ltime
, vtime
;
927 if ((len
= pfkey_send_x4(so
, SADB_X_SPDADD
,
928 src
, prefs
, dst
, prefd
, proto
,
930 policy
, policylen
, seq
)) < 0)
937 * sending SADB_X_SPDUPDATE message to the kernel.
939 * positive: success and return length sent.
940 * -1 : error occured, and set errno.
943 pfkey_send_spdupdate(so
, src
, prefs
, dst
, prefd
, proto
, policy
, policylen
, seq
)
945 struct sockaddr
*src
, *dst
;
946 u_int prefs
, prefd
, proto
;
953 if ((len
= pfkey_send_x4(so
, SADB_X_SPDUPDATE
,
954 src
, prefs
, dst
, prefd
, proto
,
956 policy
, policylen
, seq
)) < 0)
963 * sending SADB_X_SPDUPDATE message to the kernel.
965 * positive: success and return length sent.
966 * -1 : error occured, and set errno.
969 pfkey_send_spdupdate2(so
, src
, prefs
, dst
, prefd
, proto
, ltime
, vtime
,
970 policy
, policylen
, seq
)
972 struct sockaddr
*src
, *dst
;
973 u_int prefs
, prefd
, proto
;
974 u_int64_t ltime
, vtime
;
981 if ((len
= pfkey_send_x4(so
, SADB_X_SPDUPDATE
,
982 src
, prefs
, dst
, prefd
, proto
,
984 policy
, policylen
, seq
)) < 0)
991 * sending SADB_X_SPDDELETE message to the kernel.
993 * positive: success and return length sent.
994 * -1 : error occured, and set errno.
997 pfkey_send_spddelete(so
, src
, prefs
, dst
, prefd
, proto
, policy
, policylen
, seq
)
999 struct sockaddr
*src
, *dst
;
1000 u_int prefs
, prefd
, proto
;
1007 if (policylen
!= sizeof(struct sadb_x_policy
)) {
1008 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1012 if ((len
= pfkey_send_x4(so
, SADB_X_SPDDELETE
,
1013 src
, prefs
, dst
, prefd
, proto
,
1015 policy
, policylen
, seq
)) < 0)
1022 * sending SADB_X_SPDDELETE message to the kernel.
1024 * positive: success and return length sent.
1025 * -1 : error occured, and set errno.
1028 pfkey_send_spddelete2(so
, spid
)
1034 if ((len
= pfkey_send_x5(so
, SADB_X_SPDDELETE2
, spid
)) < 0)
1041 * sending SADB_X_SPDGET message to the kernel.
1043 * positive: success and return length sent.
1044 * -1 : error occured, and set errno.
1047 pfkey_send_spdget(so
, spid
)
1053 if ((len
= pfkey_send_x5(so
, SADB_X_SPDGET
, spid
)) < 0)
1060 * sending SADB_X_SPDSETIDX message to the kernel.
1062 * positive: success and return length sent.
1063 * -1 : error occured, and set errno.
1066 pfkey_send_spdsetidx(so
, src
, prefs
, dst
, prefd
, proto
, policy
, policylen
, seq
)
1068 struct sockaddr
*src
, *dst
;
1069 u_int prefs
, prefd
, proto
;
1076 if (policylen
!= sizeof(struct sadb_x_policy
)) {
1077 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1081 if ((len
= pfkey_send_x4(so
, SADB_X_SPDSETIDX
,
1082 src
, prefs
, dst
, prefd
, proto
,
1084 policy
, policylen
, seq
)) < 0)
1091 * sending SADB_SPDFLUSH message to the kernel.
1093 * positive: success and return length sent.
1094 * -1 : error occured, and set errno.
1097 pfkey_send_spdflush(so
)
1102 if ((len
= pfkey_send_x3(so
, SADB_X_SPDFLUSH
, SADB_SATYPE_UNSPEC
)) < 0)
1109 * sending SADB_SPDDUMP message to the kernel.
1111 * positive: success and return length sent.
1112 * -1 : error occured, and set errno.
1115 pfkey_send_spddump(so
)
1120 if ((len
= pfkey_send_x3(so
, SADB_X_SPDDUMP
, SADB_SATYPE_UNSPEC
)) < 0)
1126 /* sending SADB_ADD or SADB_UPDATE message to the kernel */
1128 pfkey_send_x1(so
, type
, satype
, mode
, src
, dst
, spi
, reqid
, wsize
,
1129 keymat
, e_type
, e_keylen
, a_type
, a_keylen
, flags
,
1130 l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
)
1132 u_int type
, satype
, mode
;
1133 struct sockaddr
*src
, *dst
;
1134 u_int32_t spi
, reqid
;
1137 u_int e_type
, e_keylen
, a_type
, a_keylen
, flags
;
1138 u_int32_t l_alloc
, l_bytes
, l_addtime
, l_usetime
, seq
;
1140 struct sadb_msg
*newmsg
;
1146 /* validity check */
1147 if (src
== NULL
|| dst
== NULL
) {
1148 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1151 if (src
->sa_family
!= dst
->sa_family
) {
1152 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1155 switch (src
->sa_family
) {
1157 plen
= sizeof(struct in_addr
) << 3;
1160 plen
= sizeof(struct in6_addr
) << 3;
1163 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1168 case SADB_SATYPE_ESP
:
1169 if (e_type
== SADB_EALG_NONE
) {
1170 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1174 case SADB_SATYPE_AH
:
1175 if (e_type
!= SADB_EALG_NONE
) {
1176 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1179 if (a_type
== SADB_AALG_NONE
) {
1180 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1184 case SADB_X_SATYPE_IPCOMP
:
1185 if (e_type
== SADB_X_CALG_NONE
) {
1186 __ipsec_errcode
= EIPSEC_INVAL_ALGS
;
1189 if (a_type
!= SADB_AALG_NONE
) {
1190 __ipsec_errcode
= EIPSEC_NO_ALGS
;
1195 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1199 /* create new sadb_msg to reply. */
1200 len
= sizeof(struct sadb_msg
)
1201 + sizeof(struct sadb_sa
)
1202 + sizeof(struct sadb_x_sa2
)
1203 + sizeof(struct sadb_address
)
1204 + PFKEY_ALIGN8(src
->sa_len
)
1205 + sizeof(struct sadb_address
)
1206 + PFKEY_ALIGN8(dst
->sa_len
)
1207 + sizeof(struct sadb_lifetime
)
1208 + sizeof(struct sadb_lifetime
);
1210 if (e_type
!= SADB_EALG_NONE
)
1211 len
+= (sizeof(struct sadb_key
) + PFKEY_ALIGN8(e_keylen
));
1212 if (a_type
!= SADB_AALG_NONE
)
1213 len
+= (sizeof(struct sadb_key
) + PFKEY_ALIGN8(a_keylen
));
1215 if ((newmsg
= CALLOC(len
, struct sadb_msg
*)) == NULL
) {
1216 __ipsec_set_strerror(strerror(errno
));
1219 ep
= ((caddr_t
)newmsg
) + len
;
1221 p
= pfkey_setsadbmsg((caddr_t
)newmsg
, ep
, type
, len
,
1222 satype
, seq
, getpid());
1227 p
= pfkey_setsadbsa(p
, ep
, spi
, wsize
, a_type
, e_type
, flags
);
1232 p
= pfkey_setsadbxsa2(p
, ep
, mode
, reqid
);
1237 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, plen
,
1243 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, plen
,
1250 if (e_type
!= SADB_EALG_NONE
) {
1251 p
= pfkey_setsadbkey(p
, ep
, SADB_EXT_KEY_ENCRYPT
,
1258 if (a_type
!= SADB_AALG_NONE
) {
1259 p
= pfkey_setsadbkey(p
, ep
, SADB_EXT_KEY_AUTH
,
1260 keymat
+ e_keylen
, a_keylen
);
1267 /* set sadb_lifetime for destination */
1268 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_HARD
,
1269 l_alloc
, l_bytes
, l_addtime
, l_usetime
);
1274 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_SOFT
,
1275 l_alloc
, l_bytes
, l_addtime
, l_usetime
);
1276 if (!p
|| p
!= ep
) {
1282 len
= pfkey_send(so
, newmsg
, len
);
1288 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1292 /* sending SADB_DELETE or SADB_GET message to the kernel */
1294 pfkey_send_x2(so
, type
, satype
, mode
, src
, dst
, spi
)
1296 u_int type
, satype
, mode
;
1297 struct sockaddr
*src
, *dst
;
1300 struct sadb_msg
*newmsg
;
1308 /* validity check */
1309 if (src
== NULL
|| dst
== NULL
) {
1310 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1313 if (src
->sa_family
!= dst
->sa_family
) {
1314 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1317 switch (src
->sa_family
) {
1319 plen
= sizeof(struct in_addr
) << 3;
1322 plen
= sizeof(struct in6_addr
) << 3;
1325 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1329 /* create new sadb_msg to reply. */
1330 len
= sizeof(struct sadb_msg
)
1331 + sizeof(struct sadb_sa
)
1332 + sizeof(struct sadb_address
)
1333 + PFKEY_ALIGN8(src
->sa_len
)
1334 + sizeof(struct sadb_address
)
1335 + PFKEY_ALIGN8(dst
->sa_len
);
1337 if ((newmsg
= CALLOC(len
, struct sadb_msg
*)) == NULL
) {
1338 __ipsec_set_strerror(strerror(errno
));
1341 ep
= ((caddr_t
)newmsg
) + len
;
1343 p
= pfkey_setsadbmsg((caddr_t
)newmsg
, ep
, type
, len
, satype
, 0,
1349 p
= pfkey_setsadbsa(p
, ep
, spi
, 0, 0, 0, 0);
1354 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, plen
,
1360 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, plen
,
1362 if (!p
|| p
!= ep
) {
1368 len
= pfkey_send(so
, newmsg
, len
);
1374 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1379 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message
1383 pfkey_send_x3(so
, type
, satype
)
1387 struct sadb_msg
*newmsg
;
1392 /* validity check */
1394 case SADB_X_PROMISC
:
1395 if (satype
!= 0 && satype
!= 1) {
1396 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1402 case SADB_SATYPE_UNSPEC
:
1403 case SADB_SATYPE_AH
:
1404 case SADB_SATYPE_ESP
:
1405 case SADB_X_SATYPE_IPCOMP
:
1408 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1413 /* create new sadb_msg to send. */
1414 len
= sizeof(struct sadb_msg
);
1416 if ((newmsg
= CALLOC(len
, struct sadb_msg
*)) == NULL
) {
1417 __ipsec_set_strerror(strerror(errno
));
1420 ep
= ((caddr_t
)newmsg
) + len
;
1422 p
= pfkey_setsadbmsg((caddr_t
)newmsg
, ep
, type
, len
, satype
, 0,
1424 if (!p
|| p
!= ep
) {
1430 len
= pfkey_send(so
, newmsg
, len
);
1436 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1440 /* sending SADB_X_SPDADD message to the kernel */
1442 pfkey_send_x4(so
, type
, src
, prefs
, dst
, prefd
, proto
,
1443 ltime
, vtime
, policy
, policylen
, seq
)
1445 struct sockaddr
*src
, *dst
;
1446 u_int type
, prefs
, prefd
, proto
;
1447 u_int64_t ltime
, vtime
;
1452 struct sadb_msg
*newmsg
;
1458 /* validity check */
1459 if (src
== NULL
|| dst
== NULL
) {
1460 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1463 if (src
->sa_family
!= dst
->sa_family
) {
1464 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1468 switch (src
->sa_family
) {
1470 plen
= sizeof(struct in_addr
) << 3;
1473 plen
= sizeof(struct in6_addr
) << 3;
1476 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1479 if (prefs
> (u_int
)plen
|| prefd
> (u_int
)plen
) {
1480 __ipsec_errcode
= EIPSEC_INVAL_PREFIXLEN
;
1484 /* create new sadb_msg to reply. */
1485 len
= sizeof(struct sadb_msg
)
1486 + sizeof(struct sadb_address
)
1487 + PFKEY_ALIGN8(src
->sa_len
)
1488 + sizeof(struct sadb_address
)
1489 + PFKEY_ALIGN8(src
->sa_len
)
1490 + sizeof(struct sadb_lifetime
)
1493 if ((newmsg
= CALLOC(len
, struct sadb_msg
*)) == NULL
) {
1494 __ipsec_set_strerror(strerror(errno
));
1497 ep
= ((caddr_t
)newmsg
) + len
;
1499 p
= pfkey_setsadbmsg((caddr_t
)newmsg
, ep
, type
, len
,
1500 SADB_SATYPE_UNSPEC
, seq
, getpid());
1505 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_SRC
, src
, prefs
, proto
);
1510 p
= pfkey_setsadbaddr(p
, ep
, SADB_EXT_ADDRESS_DST
, dst
, prefd
, proto
);
1515 p
= pfkey_setsadblifetime(p
, ep
, SADB_EXT_LIFETIME_HARD
,
1516 0, 0, ltime
, vtime
);
1517 if (!p
|| p
+ policylen
!= ep
) {
1521 memcpy(p
, policy
, policylen
);
1524 len
= pfkey_send(so
, newmsg
, len
);
1530 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1534 /* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */
1536 pfkey_send_x5(so
, type
, spid
)
1541 struct sadb_msg
*newmsg
;
1542 struct sadb_x_policy xpl
;
1547 /* create new sadb_msg to reply. */
1548 len
= sizeof(struct sadb_msg
)
1551 if ((newmsg
= CALLOC(len
, struct sadb_msg
*)) == NULL
) {
1552 __ipsec_set_strerror(strerror(errno
));
1555 ep
= ((caddr_t
)newmsg
) + len
;
1557 p
= pfkey_setsadbmsg((caddr_t
)newmsg
, ep
, type
, len
,
1558 SADB_SATYPE_UNSPEC
, 0, getpid());
1564 if (p
+ sizeof(xpl
) != ep
) {
1568 memset(&xpl
, 0, sizeof(xpl
));
1569 xpl
.sadb_x_policy_len
= PFKEY_UNUNIT64(sizeof(xpl
));
1570 xpl
.sadb_x_policy_exttype
= SADB_X_EXT_POLICY
;
1571 xpl
.sadb_x_policy_id
= spid
;
1572 memcpy(p
, &xpl
, sizeof(xpl
));
1575 len
= pfkey_send(so
, newmsg
, len
);
1581 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1589 * others : success and return value of socket.
1595 const int bufsiz
= 128 * 1024; /*is 128K enough?*/
1597 if ((so
= socket(PF_KEY
, SOCK_RAW
, PF_KEY_V2
)) < 0) {
1598 __ipsec_set_strerror(strerror(errno
));
1603 * This is a temporary workaround for KAME PR 154.
1604 * Don't really care even if it fails.
1606 (void)setsockopt(so
, SOL_SOCKET
, SO_SNDBUF
, &bufsiz
, sizeof(bufsiz
));
1607 (void)setsockopt(so
, SOL_SOCKET
, SO_RCVBUF
, &bufsiz
, sizeof(bufsiz
));
1609 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1625 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1630 * receive sadb_msg data, and return pointer to new buffer allocated.
1631 * Must free this buffer later.
1633 * NULL : error occured.
1634 * others : a pointer to sadb_msg structure.
1636 * XXX should be rewritten to pass length explicitly
1642 struct sadb_msg buf
, *newmsg
;
1645 while ((len
= recv(so
, (caddr_t
)&buf
, sizeof(buf
), MSG_PEEK
)) < 0) {
1648 __ipsec_set_strerror(strerror(errno
));
1652 if ((size_t)len
< sizeof(buf
)) {
1653 recv(so
, (caddr_t
)&buf
, sizeof(buf
), 0);
1654 __ipsec_errcode
= EIPSEC_MAX
;
1658 /* read real message */
1659 reallen
= PFKEY_UNUNIT64(buf
.sadb_msg_len
);
1660 if ((newmsg
= CALLOC(reallen
, struct sadb_msg
*)) == 0) {
1661 __ipsec_set_strerror(strerror(errno
));
1665 while ((len
= recv(so
, (caddr_t
)newmsg
, reallen
, 0)) < 0) {
1668 __ipsec_set_strerror(strerror(errno
));
1673 if (len
!= reallen
) {
1674 __ipsec_errcode
= EIPSEC_SYSTEM_ERROR
;
1679 /* don't trust what the kernel says, validate! */
1680 if (PFKEY_UNUNIT64(newmsg
->sadb_msg_len
) != len
) {
1681 __ipsec_errcode
= EIPSEC_SYSTEM_ERROR
;
1686 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1691 * send message to a socket.
1693 * others: success and return length sent.
1697 pfkey_send(so
, msg
, len
)
1699 struct sadb_msg
*msg
;
1702 if ((len
= send(so
, (caddr_t
)msg
, len
, 0)) < 0) {
1703 __ipsec_set_strerror(strerror(errno
));
1707 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1713 * NOTE: These functions are derived from netkey/key.c in KAME.
1716 * set the pointer to each header in this message buffer.
1717 * IN: msg: pointer to message buffer.
1718 * mhp: pointer to the buffer initialized like below:
1719 * caddr_t mhp[SADB_EXT_MAX + 1];
1723 * XXX should be rewritten to obtain length explicitly
1726 pfkey_align(msg
, mhp
)
1727 struct sadb_msg
*msg
;
1730 struct sadb_ext
*ext
;
1733 caddr_t ep
; /* XXX should be passed from upper layer */
1735 /* validity check */
1736 if (msg
== NULL
|| mhp
== NULL
) {
1737 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1742 for (i
= 0; i
< SADB_EXT_MAX
+ 1; i
++)
1745 mhp
[0] = (caddr_t
)msg
;
1749 ep
= p
+ PFKEY_UNUNIT64(msg
->sadb_msg_len
);
1751 /* skip base header */
1752 p
+= sizeof(struct sadb_msg
);
1755 ext
= (struct sadb_ext
*)p
;
1756 if (ep
< p
+ sizeof(*ext
) || (size_t)PFKEY_EXTLEN(ext
) < sizeof(*ext
) ||
1757 ep
< p
+ PFKEY_EXTLEN(ext
)) {
1758 /* invalid format */
1762 /* duplicate check */
1763 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/
1764 if (mhp
[ext
->sadb_ext_type
] != NULL
) {
1765 __ipsec_errcode
= EIPSEC_INVAL_EXTTYPE
;
1770 switch (ext
->sadb_ext_type
) {
1772 case SADB_EXT_LIFETIME_CURRENT
:
1773 case SADB_EXT_LIFETIME_HARD
:
1774 case SADB_EXT_LIFETIME_SOFT
:
1775 case SADB_EXT_ADDRESS_SRC
:
1776 case SADB_EXT_ADDRESS_DST
:
1777 case SADB_EXT_ADDRESS_PROXY
:
1778 case SADB_EXT_KEY_AUTH
:
1779 /* XXX should to be check weak keys. */
1780 case SADB_EXT_KEY_ENCRYPT
:
1781 /* XXX should to be check weak keys. */
1782 case SADB_EXT_IDENTITY_SRC
:
1783 case SADB_EXT_IDENTITY_DST
:
1784 case SADB_EXT_SENSITIVITY
:
1785 case SADB_EXT_PROPOSAL
:
1786 case SADB_EXT_SUPPORTED_AUTH
:
1787 case SADB_EXT_SUPPORTED_ENCRYPT
:
1788 case SADB_EXT_SPIRANGE
:
1789 case SADB_X_EXT_POLICY
:
1790 case SADB_X_EXT_SA2
:
1791 mhp
[ext
->sadb_ext_type
] = (caddr_t
)ext
;
1794 __ipsec_errcode
= EIPSEC_INVAL_EXTTYPE
;
1798 p
+= PFKEY_EXTLEN(ext
);
1802 __ipsec_errcode
= EIPSEC_INVAL_SADBMSG
;
1806 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1811 * check basic usage for sadb_msg,
1812 * NOTE: This routine is derived from netkey/key.c in KAME.
1813 * IN: msg: pointer to message buffer.
1814 * mhp: pointer to the buffer initialized like below:
1816 * caddr_t mhp[SADB_EXT_MAX + 1];
1825 struct sadb_msg
*msg
;
1827 /* validity check */
1828 if (mhp
== NULL
|| mhp
[0] == NULL
) {
1829 __ipsec_errcode
= EIPSEC_INVAL_ARGUMENT
;
1833 msg
= (struct sadb_msg
*)mhp
[0];
1836 if (msg
->sadb_msg_version
!= PF_KEY_V2
) {
1837 __ipsec_errcode
= EIPSEC_INVAL_VERSION
;
1842 if (msg
->sadb_msg_type
> SADB_MAX
) {
1843 __ipsec_errcode
= EIPSEC_INVAL_MSGTYPE
;
1848 switch (msg
->sadb_msg_satype
) {
1849 case SADB_SATYPE_UNSPEC
:
1850 switch (msg
->sadb_msg_type
) {
1858 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1862 case SADB_SATYPE_ESP
:
1863 case SADB_SATYPE_AH
:
1864 case SADB_X_SATYPE_IPCOMP
:
1865 switch (msg
->sadb_msg_type
) {
1867 case SADB_X_SPDDELETE
:
1869 case SADB_X_SPDDUMP
:
1870 case SADB_X_SPDFLUSH
:
1871 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1875 case SADB_SATYPE_RSVP
:
1876 case SADB_SATYPE_OSPFV2
:
1877 case SADB_SATYPE_RIPV2
:
1878 case SADB_SATYPE_MIP
:
1879 __ipsec_errcode
= EIPSEC_NOT_SUPPORTED
;
1881 case 1: /* XXX: What does it do ? */
1882 if (msg
->sadb_msg_type
== SADB_X_PROMISC
)
1886 __ipsec_errcode
= EIPSEC_INVAL_SATYPE
;
1890 /* check field of upper layer protocol and address family */
1891 if (mhp
[SADB_EXT_ADDRESS_SRC
] != NULL
1892 && mhp
[SADB_EXT_ADDRESS_DST
] != NULL
) {
1893 struct sadb_address
*src0
, *dst0
;
1895 src0
= (struct sadb_address
*)(mhp
[SADB_EXT_ADDRESS_SRC
]);
1896 dst0
= (struct sadb_address
*)(mhp
[SADB_EXT_ADDRESS_DST
]);
1898 if (src0
->sadb_address_proto
!= dst0
->sadb_address_proto
) {
1899 __ipsec_errcode
= EIPSEC_PROTO_MISMATCH
;
1903 if (PFKEY_ADDR_SADDR(src0
)->sa_family
1904 != PFKEY_ADDR_SADDR(dst0
)->sa_family
) {
1905 __ipsec_errcode
= EIPSEC_FAMILY_MISMATCH
;
1909 switch (PFKEY_ADDR_SADDR(src0
)->sa_family
) {
1914 __ipsec_errcode
= EIPSEC_INVAL_FAMILY
;
1919 * prefixlen == 0 is valid because there must be the case
1920 * all addresses are matched.
1924 __ipsec_errcode
= EIPSEC_NO_ERROR
;
1929 * set data into sadb_msg.
1930 * `buf' must has been allocated sufficiently.
1933 pfkey_setsadbmsg(buf
, lim
, type
, tlen
, satype
, seq
, pid
)
1944 p
= (struct sadb_msg
*)buf
;
1945 len
= sizeof(struct sadb_msg
);
1947 if (buf
+ len
> lim
)
1951 p
->sadb_msg_version
= PF_KEY_V2
;
1952 p
->sadb_msg_type
= type
;
1953 p
->sadb_msg_errno
= 0;
1954 p
->sadb_msg_satype
= satype
;
1955 p
->sadb_msg_len
= PFKEY_UNIT64(tlen
);
1956 p
->sadb_msg_reserved
= 0;
1957 p
->sadb_msg_seq
= seq
;
1958 p
->sadb_msg_pid
= (u_int32_t
)pid
;
1964 * copy secasvar data into sadb_address.
1965 * `buf' must has been allocated sufficiently.
1968 pfkey_setsadbsa(buf
, lim
, spi
, wsize
, auth
, enc
, flags
)
1971 u_int32_t spi
, flags
;
1972 u_int wsize
, auth
, enc
;
1977 p
= (struct sadb_sa
*)buf
;
1978 len
= sizeof(struct sadb_sa
);
1980 if (buf
+ len
> lim
)
1984 p
->sadb_sa_len
= PFKEY_UNIT64(len
);
1985 p
->sadb_sa_exttype
= SADB_EXT_SA
;
1986 p
->sadb_sa_spi
= spi
;
1987 p
->sadb_sa_replay
= wsize
;
1988 p
->sadb_sa_state
= SADB_SASTATE_LARVAL
;
1989 p
->sadb_sa_auth
= auth
;
1990 p
->sadb_sa_encrypt
= enc
;
1991 p
->sadb_sa_flags
= flags
;
1997 * set data into sadb_address.
1998 * `buf' must has been allocated sufficiently.
1999 * prefixlen is in bits.
2002 pfkey_setsadbaddr(buf
, lim
, exttype
, saddr
, prefixlen
, ul_proto
)
2006 struct sockaddr
*saddr
;
2010 struct sadb_address
*p
;
2013 p
= (struct sadb_address
*)buf
;
2014 len
= sizeof(struct sadb_address
) + PFKEY_ALIGN8(saddr
->sa_len
);
2016 if (buf
+ len
> lim
)
2020 p
->sadb_address_len
= PFKEY_UNIT64(len
);
2021 p
->sadb_address_exttype
= exttype
& 0xffff;
2022 p
->sadb_address_proto
= ul_proto
& 0xff;
2023 p
->sadb_address_prefixlen
= prefixlen
;
2024 p
->sadb_address_reserved
= 0;
2026 memcpy(p
+ 1, saddr
, saddr
->sa_len
);
2032 * set sadb_key structure after clearing buffer with zero.
2033 * OUT: the pointer of buf + len.
2036 pfkey_setsadbkey(buf
, lim
, type
, key
, keylen
)
2045 p
= (struct sadb_key
*)buf
;
2046 len
= sizeof(struct sadb_key
) + PFKEY_ALIGN8(keylen
);
2048 if (buf
+ len
> lim
)
2052 p
->sadb_key_len
= PFKEY_UNIT64(len
);
2053 p
->sadb_key_exttype
= type
;
2054 p
->sadb_key_bits
= keylen
<< 3;
2055 p
->sadb_key_reserved
= 0;
2057 memcpy(p
+ 1, key
, keylen
);
2063 * set sadb_lifetime structure after clearing buffer with zero.
2064 * OUT: the pointer of buf + len.
2067 pfkey_setsadblifetime(buf
, lim
, type
, l_alloc
, l_bytes
, l_addtime
, l_usetime
)
2071 u_int32_t l_alloc
, l_bytes
, l_addtime
, l_usetime
;
2073 struct sadb_lifetime
*p
;
2076 p
= (struct sadb_lifetime
*)buf
;
2077 len
= sizeof(struct sadb_lifetime
);
2079 if (buf
+ len
> lim
)
2083 p
->sadb_lifetime_len
= PFKEY_UNIT64(len
);
2084 p
->sadb_lifetime_exttype
= type
;
2087 case SADB_EXT_LIFETIME_SOFT
:
2088 p
->sadb_lifetime_allocations
2089 = (l_alloc
* soft_lifetime_allocations_rate
) /100;
2090 p
->sadb_lifetime_bytes
2091 = (l_bytes
* soft_lifetime_bytes_rate
) /100;
2092 p
->sadb_lifetime_addtime
2093 = (l_addtime
* soft_lifetime_addtime_rate
) /100;
2094 p
->sadb_lifetime_usetime
2095 = (l_usetime
* soft_lifetime_usetime_rate
) /100;
2097 case SADB_EXT_LIFETIME_HARD
:
2098 p
->sadb_lifetime_allocations
= l_alloc
;
2099 p
->sadb_lifetime_bytes
= l_bytes
;
2100 p
->sadb_lifetime_addtime
= l_addtime
;
2101 p
->sadb_lifetime_usetime
= l_usetime
;
2109 * copy secasvar data into sadb_address.
2110 * `buf' must has been allocated sufficiently.
2113 pfkey_setsadbxsa2(buf
, lim
, mode0
, reqid
)
2119 struct sadb_x_sa2
*p
;
2120 u_int8_t mode
= mode0
& 0xff;
2123 p
= (struct sadb_x_sa2
*)buf
;
2124 len
= sizeof(struct sadb_x_sa2
);
2126 if (buf
+ len
> lim
)
2130 p
->sadb_x_sa2_len
= PFKEY_UNIT64(len
);
2131 p
->sadb_x_sa2_exttype
= SADB_X_EXT_SA2
;
2132 p
->sadb_x_sa2_mode
= mode
;
2133 p
->sadb_x_sa2_reqid
= reqid
;
2138 #endif /* ndef MDNS_NO_IPSEC */