2 * RFC2367 PF_KEYv2 Key management API message parser
3 * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * RCSID $Id: pfkey_v2_build.c,v 1.4 2005/04/07 19:43:52 as Exp $
19 * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
22 char pfkey_v2_build_c_version
[] = "$Id: pfkey_v2_build.c,v 1.4 2005/04/07 19:43:52 as Exp $";
25 * Some ugly stuff to allow consistent debugging code for use in the
26 * kernel and in user space
31 # include <linux/kernel.h> /* for printk */
33 # include "freeswan/ipsec_kversion.h" /* for malloc switch */
35 # include <linux/slab.h> /* kmalloc() */
36 # else /* MALLOC_SLAB */
37 # include <linux/malloc.h> /* kmalloc() */
38 # endif /* MALLOC_SLAB */
39 # include <linux/errno.h> /* error codes */
40 # include <linux/types.h> /* size_t */
41 # include <linux/interrupt.h> /* mark_bh */
43 # include <linux/netdevice.h> /* struct device, and other headers */
44 # include <linux/etherdevice.h> /* eth_type_trans */
45 # include <linux/ip.h> /* struct iphdr */
46 # if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
47 # include <linux/ipv6.h> /* struct ipv6hdr */
48 # endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
50 # define MALLOC(size) kmalloc(size, GFP_ATOMIC)
51 # define FREE(obj) kfree(obj)
52 # include <freeswan.h>
53 #else /* __KERNEL__ */
55 # include <sys/types.h>
56 # include <linux/types.h>
57 # include <linux/errno.h>
59 # include <string.h> /* memset */
61 # include <freeswan.h>
62 unsigned int pfkey_lib_debug
= 0;
64 void (*pfkey_debug_func
)(const char *message
, ...) PRINTF_LIKE(1);
68 #define DEBUGGING(args...) if(pfkey_lib_debug) { \
69 if(pfkey_debug_func != NULL) { \
70 (*pfkey_debug_func)("pfkey_lib_debug:" args); \
72 printf("pfkey_lib_debug:" args); \
74 # define MALLOC(size) malloc(size)
75 # define FREE(obj) free(obj)
76 #endif /* __KERNEL__ */
83 #include "freeswan/radij.h" /* rd_nodes */
84 #include "freeswan/ipsec_encap.h" /* sockaddr_encap */
86 # define DEBUGGING(args...) \
87 KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
88 #endif /* __KERNEL__ */
90 #include "freeswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
92 #define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
95 pfkey_extensions_init(struct sadb_ext
*extensions
[SADB_EXT_MAX
+ 1])
99 for (i
= 0; i
!= SADB_EXT_MAX
+ 1; i
++) {
100 extensions
[i
] = NULL
;
105 pfkey_extensions_free(struct sadb_ext
*extensions
[SADB_EXT_MAX
+ 1])
114 memset(extensions
[0], 0, sizeof(struct sadb_msg
));
116 extensions
[0] = NULL
;
119 for (i
= 1; i
!= SADB_EXT_MAX
+ 1; i
++) {
121 memset(extensions
[i
], 0, extensions
[i
]->sadb_ext_len
* IPSEC_PFKEYv2_ALIGN
);
123 extensions
[i
] = NULL
;
129 pfkey_msg_free(struct sadb_msg
**pfkey_msg
)
132 memset(*pfkey_msg
, 0, (*pfkey_msg
)->sadb_msg_len
* IPSEC_PFKEYv2_ALIGN
);
138 /* Default extension builders taken from the KLIPS code */
141 pfkey_msg_hdr_build(struct sadb_ext
** pfkey_ext
,
149 struct sadb_msg
*pfkey_msg
= (struct sadb_msg
*)*pfkey_ext
;
152 "pfkey_msg_hdr_build:\n");
154 "pfkey_msg_hdr_build: "
155 "on_entry &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
159 /* sanity checks... */
162 "pfkey_msg_hdr_build: "
163 "why is pfkey_msg already pointing to something?\n");
169 "pfkey_msg_hdr_build: "
170 "msg type not set, must be non-zero..\n");
174 if (msg_type
> SADB_MAX
) {
176 "pfkey_msg_hdr_build: "
177 "msg type too large:%d.\n",
182 if (satype
> SADB_SATYPE_MAX
) {
184 "pfkey_msg_hdr_build: "
185 "satype %d > max %d\n",
186 satype
, SADB_SATYPE_MAX
);
190 pfkey_msg
= (struct sadb_msg
*)MALLOC(sizeof(struct sadb_msg
));
191 *pfkey_ext
= (struct sadb_ext
*)pfkey_msg
;
193 if (pfkey_msg
== NULL
) {
195 "pfkey_msg_hdr_build: "
196 "memory allocation failed\n");
199 memset(pfkey_msg
, 0, sizeof(struct sadb_msg
));
201 pfkey_msg
->sadb_msg_len
= sizeof(struct sadb_msg
) / IPSEC_PFKEYv2_ALIGN
;
203 pfkey_msg
->sadb_msg_type
= msg_type
;
204 pfkey_msg
->sadb_msg_satype
= satype
;
206 pfkey_msg
->sadb_msg_version
= PF_KEY_V2
;
207 pfkey_msg
->sadb_msg_errno
= msg_errno
;
208 pfkey_msg
->sadb_msg_reserved
= 0;
209 pfkey_msg
->sadb_msg_seq
= seq
;
210 pfkey_msg
->sadb_msg_pid
= pid
;
212 "pfkey_msg_hdr_build: "
213 "on_exit &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
222 pfkey_sa_ref_build(struct sadb_ext
** pfkey_ext
,
225 uint8_t replay_window
,
230 uint32_t/*IPsecSAref_t*/ ref
)
233 struct sadb_sa
*pfkey_sa
= (struct sadb_sa
*)*pfkey_ext
;
237 "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n",
238 ntohl(spi
), /* in network order */
244 /* sanity checks... */
248 "why is pfkey_sa already pointing to something?\n");
252 if (exttype
!= SADB_EXT_SA
253 && exttype
!= SADB_X_EXT_SA2
) {
256 "invalid exttype=%d.\n",
261 if (replay_window
> 64) {
264 "replay window size: %d -- must be 0 <= size <= 64\n",
269 if (auth
> SADB_AALG_MAX
) {
272 "auth=%d > SADB_AALG_MAX=%d.\n",
278 if (encrypt
> SADB_EALG_MAX
) {
281 "encrypt=%d > SADB_EALG_MAX=%d.\n",
287 if (sa_state
> SADB_SASTATE_MAX
) {
290 "sa_state=%d exceeds MAX=%d.\n",
296 if (sa_state
== SADB_SASTATE_DEAD
) {
299 "sa_state=%d is DEAD=%d is not allowed.\n",
305 if ((IPSEC_SAREF_NULL
!= ref
) && (ref
>= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH
))) {
308 "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
311 IPSEC_SA_REF_TABLE_NUM_ENTRIES
);
315 pfkey_sa
= (struct sadb_sa
*)MALLOC(sizeof(struct sadb_sa
));
316 *pfkey_ext
= (struct sadb_ext
*)pfkey_sa
;
318 if (pfkey_sa
== NULL
) {
321 "memory allocation failed\n");
324 memset(pfkey_sa
, 0, sizeof(struct sadb_sa
));
326 pfkey_sa
->sadb_sa_len
= sizeof(*pfkey_sa
) / IPSEC_PFKEYv2_ALIGN
;
327 pfkey_sa
->sadb_sa_exttype
= exttype
;
328 pfkey_sa
->sadb_sa_spi
= spi
;
329 pfkey_sa
->sadb_sa_replay
= replay_window
;
330 pfkey_sa
->sadb_sa_state
= sa_state
;
331 pfkey_sa
->sadb_sa_auth
= auth
;
332 pfkey_sa
->sadb_sa_encrypt
= encrypt
;
333 pfkey_sa
->sadb_sa_flags
= flags
;
334 pfkey_sa
->sadb_x_sa_ref
= ref
;
341 pfkey_sa_build(struct sadb_ext
** pfkey_ext
,
344 uint8_t replay_window
,
350 return pfkey_sa_ref_build(pfkey_ext
,
362 pfkey_lifetime_build(struct sadb_ext
** pfkey_ext
,
364 uint32_t allocations
,
371 struct sadb_lifetime
*pfkey_lifetime
= (struct sadb_lifetime
*)*pfkey_ext
;
374 "pfkey_lifetime_build:\n");
375 /* sanity checks... */
376 if (pfkey_lifetime
) {
378 "pfkey_lifetime_build: "
379 "why is pfkey_lifetime already pointing to something?\n");
383 if (exttype
!= SADB_EXT_LIFETIME_CURRENT
384 && exttype
!= SADB_EXT_LIFETIME_HARD
385 && exttype
!= SADB_EXT_LIFETIME_SOFT
) {
387 "pfkey_lifetime_build: "
388 "invalid exttype=%d.\n",
393 pfkey_lifetime
= (struct sadb_lifetime
*)MALLOC(sizeof(struct sadb_lifetime
));
394 *pfkey_ext
= (struct sadb_ext
*)pfkey_lifetime
;
396 if (pfkey_lifetime
== NULL
) {
398 "pfkey_lifetime_build: "
399 "memory allocation failed\n");
402 memset(pfkey_lifetime
, 0, sizeof(struct sadb_lifetime
));
404 pfkey_lifetime
->sadb_lifetime_len
= sizeof(struct sadb_lifetime
) / IPSEC_PFKEYv2_ALIGN
;
405 pfkey_lifetime
->sadb_lifetime_exttype
= exttype
;
406 pfkey_lifetime
->sadb_lifetime_allocations
= allocations
;
407 pfkey_lifetime
->sadb_lifetime_bytes
= bytes
;
408 pfkey_lifetime
->sadb_lifetime_addtime
= addtime
;
409 pfkey_lifetime
->sadb_lifetime_usetime
= usetime
;
410 pfkey_lifetime
->sadb_x_lifetime_packets
= packets
;
417 pfkey_address_build(struct sadb_ext
** pfkey_ext
,
421 struct sockaddr
* address
)
425 char ipaddr_txt
[ADDRTOT_BUF
+ 6/*extra for port number*/];
426 struct sadb_address
*pfkey_address
= (struct sadb_address
*)*pfkey_ext
;
429 "pfkey_address_build: "
430 "exttype=%d proto=%d prefixlen=%d\n",
434 /* sanity checks... */
437 "pfkey_address_build: "
438 "why is pfkey_address already pointing to something?\n");
443 DEBUGGING("pfkey_address_build: "
444 "address is NULL\n");
449 case SADB_EXT_ADDRESS_SRC
:
450 case SADB_EXT_ADDRESS_DST
:
451 case SADB_EXT_ADDRESS_PROXY
:
452 case SADB_X_EXT_ADDRESS_DST2
:
453 case SADB_X_EXT_ADDRESS_SRC_FLOW
:
454 case SADB_X_EXT_ADDRESS_DST_FLOW
:
455 case SADB_X_EXT_ADDRESS_SRC_MASK
:
456 case SADB_X_EXT_ADDRESS_DST_MASK
:
458 case SADB_X_EXT_NAT_T_OA
:
463 "pfkey_address_build: "
464 "unrecognised ext_type=%d.\n",
469 switch (address
->sa_family
) {
472 "pfkey_address_build: "
473 "found address family AF_INET.\n");
474 saddr_len
= sizeof(struct sockaddr_in
);
475 sprintf(ipaddr_txt
, "%d.%d.%d.%d:%d"
476 , (((struct sockaddr_in
*)address
)->sin_addr
.s_addr
>> 0) & 0xFF
477 , (((struct sockaddr_in
*)address
)->sin_addr
.s_addr
>> 8) & 0xFF
478 , (((struct sockaddr_in
*)address
)->sin_addr
.s_addr
>> 16) & 0xFF
479 , (((struct sockaddr_in
*)address
)->sin_addr
.s_addr
>> 24) & 0xFF
480 , ntohs(((struct sockaddr_in
*)address
)->sin_port
));
484 "pfkey_address_build: "
485 "found address family AF_INET6.\n");
486 saddr_len
= sizeof(struct sockaddr_in6
);
487 sprintf(ipaddr_txt
, "%x:%x:%x:%x:%x:%x:%x:%x-%x"
488 , ntohs(((struct sockaddr_in6
*)address
)->sin6_addr
.s6_addr16
[0])
489 , ntohs(((struct sockaddr_in6
*)address
)->sin6_addr
.s6_addr16
[1])
490 , ntohs(((struct sockaddr_in6
*)address
)->sin6_addr
.s6_addr16
[2])
491 , ntohs(((struct sockaddr_in6
*)address
)->sin6_addr
.s6_addr16
[3])
492 , ntohs(((struct sockaddr_in6
*)address
)->sin6_addr
.s6_addr16
[4])
493 , ntohs(((struct sockaddr_in6
*)address
)->sin6_addr
.s6_addr16
[5])
494 , ntohs(((struct sockaddr_in6
*)address
)->sin6_addr
.s6_addr16
[6])
495 , ntohs(((struct sockaddr_in6
*)address
)->sin6_addr
.s6_addr16
[7])
496 , ntohs(((struct sockaddr_in6
*)address
)->sin6_port
));
500 "pfkey_address_build: "
501 "address->sa_family=%d not supported.\n",
503 SENDERR(EPFNOSUPPORT
);
507 "pfkey_address_build: "
508 "found address=%s.\n",
510 if (prefixlen
!= 0) {
512 "pfkey_address_build: "
513 "address prefixes not supported yet.\n");
514 SENDERR(EAFNOSUPPORT
); /* not supported yet */
517 pfkey_address
= (struct sadb_address
*)
518 MALLOC(ALIGN_N(sizeof(struct sadb_address
) + saddr_len
, IPSEC_PFKEYv2_ALIGN
));
519 *pfkey_ext
= (struct sadb_ext
*)pfkey_address
;
521 if (pfkey_address
== NULL
) {
523 "pfkey_lifetime_build: "
524 "memory allocation failed\n");
527 memset(pfkey_address
,
529 ALIGN_N(sizeof(struct sadb_address
) + saddr_len
,
530 IPSEC_PFKEYv2_ALIGN
));
532 pfkey_address
->sadb_address_len
= DIVUP(sizeof(struct sadb_address
) + saddr_len
,
533 IPSEC_PFKEYv2_ALIGN
);
535 pfkey_address
->sadb_address_exttype
= exttype
;
536 pfkey_address
->sadb_address_proto
= proto
;
537 pfkey_address
->sadb_address_prefixlen
= prefixlen
;
538 pfkey_address
->sadb_address_reserved
= 0;
540 memcpy((char*)pfkey_address
+ sizeof(struct sadb_address
),
545 for (i
= 0; i
< sizeof(struct sockaddr_in
) - offsetof(struct sockaddr_in
, sin_zero
); i
++) {
546 pfkey_address_s_ska
.sin_zero
[i
] = 0;
550 "pfkey_address_build: "
558 pfkey_key_build(struct sadb_ext
** pfkey_ext
,
564 struct sadb_key
*pfkey_key
= (struct sadb_key
*)*pfkey_ext
;
567 "pfkey_key_build:\n");
568 /* sanity checks... */
572 "why is pfkey_key already pointing to something?\n");
579 "key_bits is zero, it must be non-zero.\n");
583 if ( !((exttype
== SADB_EXT_KEY_AUTH
) || (exttype
== SADB_EXT_KEY_ENCRYPT
))) {
586 "unsupported extension type=%d.\n",
591 pfkey_key
= (struct sadb_key
*)
592 MALLOC(sizeof(struct sadb_key
) +
593 DIVUP(key_bits
, 64) * IPSEC_PFKEYv2_ALIGN
);
594 *pfkey_ext
= (struct sadb_ext
*)pfkey_key
;
596 if (pfkey_key
== NULL
) {
599 "memory allocation failed\n");
604 sizeof(struct sadb_key
) +
605 DIVUP(key_bits
, 64) * IPSEC_PFKEYv2_ALIGN
);
607 pfkey_key
->sadb_key_len
= DIVUP(sizeof(struct sadb_key
) * IPSEC_PFKEYv2_ALIGN
+ key_bits
,
609 pfkey_key
->sadb_key_exttype
= exttype
;
610 pfkey_key
->sadb_key_bits
= key_bits
;
611 pfkey_key
->sadb_key_reserved
= 0;
612 memcpy((char*)pfkey_key
+ sizeof(struct sadb_key
),
621 pfkey_ident_build(struct sadb_ext
** pfkey_ext
,
629 struct sadb_ident
*pfkey_ident
= (struct sadb_ident
*)*pfkey_ext
;
630 int data_len
= ident_len
* IPSEC_PFKEYv2_ALIGN
- sizeof(struct sadb_ident
);
633 "pfkey_ident_build:\n");
634 /* sanity checks... */
637 "pfkey_ident_build: "
638 "why is pfkey_ident already pointing to something?\n");
642 if ( !((exttype
== SADB_EXT_IDENTITY_SRC
) ||
643 (exttype
== SADB_EXT_IDENTITY_DST
))) {
645 "pfkey_ident_build: "
646 "unsupported extension type=%d.\n",
651 if (ident_type
== SADB_IDENTTYPE_RESERVED
) {
653 "pfkey_ident_build: "
654 "ident_type must be non-zero.\n");
658 if (ident_type
> SADB_IDENTTYPE_MAX
) {
660 "pfkey_ident_build: "
661 "identtype=%d out of range.\n",
666 if ((ident_type
== SADB_IDENTTYPE_PREFIX
||
667 ident_type
== SADB_IDENTTYPE_FQDN
) &&
670 "pfkey_ident_build: "
671 "string required to allocate size of extension.\n");
676 if (ident_type
== SADB_IDENTTYPE_USERFQDN
) {
680 pfkey_ident
= (struct sadb_ident
*)
681 MALLOC(ident_len
* IPSEC_PFKEYv2_ALIGN
);
682 *pfkey_ext
= (struct sadb_ext
*)pfkey_ident
;
684 if (pfkey_ident
== NULL
) {
686 "pfkey_ident_build: "
687 "memory allocation failed\n");
690 memset(pfkey_ident
, 0, ident_len
* IPSEC_PFKEYv2_ALIGN
);
692 pfkey_ident
->sadb_ident_len
= ident_len
;
693 pfkey_ident
->sadb_ident_exttype
= exttype
;
694 pfkey_ident
->sadb_ident_type
= ident_type
;
695 pfkey_ident
->sadb_ident_reserved
= 0;
696 pfkey_ident
->sadb_ident_id
= ident_id
;
697 memcpy((char*)pfkey_ident
+ sizeof(struct sadb_ident
),
706 pfkey_sens_build(struct sadb_ext
** pfkey_ext
,
710 uint64_t* sens_bitmap
,
713 uint64_t* integ_bitmap
)
716 struct sadb_sens
*pfkey_sens
= (struct sadb_sens
*)*pfkey_ext
;
721 "pfkey_sens_build:\n");
722 /* sanity checks... */
726 "why is pfkey_sens already pointing to something?\n");
732 "Sorry, I can't build exttype=%d yet.\n",
733 (*pfkey_ext
)->sadb_ext_type
);
734 SENDERR(EINVAL
); /* don't process these yet */
736 pfkey_sens
= (struct sadb_sens
*)
737 MALLOC(sizeof(struct sadb_sens
) +
738 (sens_len
+ integ_len
) * sizeof(uint64_t));
739 *pfkey_ext
= (struct sadb_ext
*)pfkey_sens
;
741 if (pfkey_sens
== NULL
) {
744 "memory allocation failed\n");
749 sizeof(struct sadb_sens
) +
750 (sens_len
+ integ_len
) * sizeof(uint64_t));
752 pfkey_sens
->sadb_sens_len
= (sizeof(struct sadb_sens
) +
753 (sens_len
+ integ_len
) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN
;
754 pfkey_sens
->sadb_sens_exttype
= SADB_EXT_SENSITIVITY
;
755 pfkey_sens
->sadb_sens_dpd
= dpd
;
756 pfkey_sens
->sadb_sens_sens_level
= sens_level
;
757 pfkey_sens
->sadb_sens_sens_len
= sens_len
;
758 pfkey_sens
->sadb_sens_integ_level
= integ_level
;
759 pfkey_sens
->sadb_sens_integ_len
= integ_len
;
760 pfkey_sens
->sadb_sens_reserved
= 0;
762 bitmap
= (uint64_t*)((char*)pfkey_ext
+ sizeof(struct sadb_sens
));
763 for (i
= 0; i
< sens_len
; i
++) {
764 *bitmap
= sens_bitmap
[i
];
767 for (i
= 0; i
< integ_len
; i
++) {
768 *bitmap
= integ_bitmap
[i
];
777 pfkey_prop_build(struct sadb_ext
** pfkey_ext
,
779 unsigned int comb_num
,
780 struct sadb_comb
* comb
)
784 struct sadb_prop
*pfkey_prop
= (struct sadb_prop
*)*pfkey_ext
;
785 struct sadb_comb
*combp
;
788 "pfkey_prop_build:\n");
789 /* sanity checks... */
793 "why is pfkey_prop already pointing to something?\n");
797 pfkey_prop
= (struct sadb_prop
*)
798 MALLOC(sizeof(struct sadb_prop
) +
799 comb_num
* sizeof(struct sadb_comb
));
801 *pfkey_ext
= (struct sadb_ext
*)pfkey_prop
;
803 if (pfkey_prop
== NULL
) {
806 "memory allocation failed\n");
811 sizeof(struct sadb_prop
) +
812 comb_num
* sizeof(struct sadb_comb
));
814 pfkey_prop
->sadb_prop_len
= (sizeof(struct sadb_prop
) +
815 comb_num
* sizeof(struct sadb_comb
)) / IPSEC_PFKEYv2_ALIGN
;
817 pfkey_prop
->sadb_prop_exttype
= SADB_EXT_PROPOSAL
;
818 pfkey_prop
->sadb_prop_replay
= replay
;
820 for (i
=0; i
<3; i
++) {
821 pfkey_prop
->sadb_prop_reserved
[i
] = 0;
824 combp
= (struct sadb_comb
*)((char*)*pfkey_ext
+ sizeof(struct sadb_prop
));
825 for (i
= 0; i
< comb_num
; i
++) {
826 memcpy (combp
, &(comb
[i
]), sizeof(struct sadb_comb
));
831 uint8_t sadb_comb_auth
;
832 uint8_t sadb_comb_encrypt
;
833 uint16_t sadb_comb_flags
;
834 uint16_t sadb_comb_auth_minbits
;
835 uint16_t sadb_comb_auth_maxbits
;
836 uint16_t sadb_comb_encrypt_minbits
;
837 uint16_t sadb_comb_encrypt_maxbits
;
838 uint32_t sadb_comb_reserved
;
839 uint32_t sadb_comb_soft_allocations
;
840 uint32_t sadb_comb_hard_allocations
;
841 uint64_t sadb_comb_soft_bytes
;
842 uint64_t sadb_comb_hard_bytes
;
843 uint64_t sadb_comb_soft_addtime
;
844 uint64_t sadb_comb_hard_addtime
;
845 uint64_t sadb_comb_soft_usetime
;
846 uint64_t sadb_comb_hard_usetime
;
847 uint32_t sadb_comb_soft_packets
;
848 uint32_t sadb_comb_hard_packets
;
855 pfkey_supported_build(struct sadb_ext
** pfkey_ext
,
857 unsigned int alg_num
,
858 struct sadb_alg
* alg
)
862 struct sadb_supported
*pfkey_supported
= (struct sadb_supported
*)*pfkey_ext
;
863 struct sadb_alg
*pfkey_alg
;
865 /* sanity checks... */
866 if (pfkey_supported
) {
868 "pfkey_supported_build: "
869 "why is pfkey_supported already pointing to something?\n");
873 if ( !((exttype
== SADB_EXT_SUPPORTED_AUTH
) || (exttype
== SADB_EXT_SUPPORTED_ENCRYPT
))) {
875 "pfkey_supported_build: "
876 "unsupported extension type=%d.\n",
881 pfkey_supported
= (struct sadb_supported
*)
882 MALLOC(sizeof(struct sadb_supported
) +
883 alg_num
* sizeof(struct sadb_alg
));
885 *pfkey_ext
= (struct sadb_ext
*)pfkey_supported
;
887 if (pfkey_supported
== NULL
) {
889 "pfkey_supported_build: "
890 "memory allocation failed\n");
893 memset(pfkey_supported
,
895 sizeof(struct sadb_supported
) +
897 sizeof(struct sadb_alg
));
899 pfkey_supported
->sadb_supported_len
= (sizeof(struct sadb_supported
) +
901 sizeof(struct sadb_alg
)) /
903 pfkey_supported
->sadb_supported_exttype
= exttype
;
904 pfkey_supported
->sadb_supported_reserved
= 0;
906 pfkey_alg
= (struct sadb_alg
*)((char*)pfkey_supported
+ sizeof(struct sadb_supported
));
907 for(i
= 0; i
< alg_num
; i
++) {
908 memcpy (pfkey_alg
, &(alg
[i
]), sizeof(struct sadb_alg
));
909 pfkey_alg
->sadb_alg_reserved
= 0;
915 "pfkey_supported_build: "
916 "Sorry, I can't build exttype=%d yet.\n",
917 (*pfkey_ext
)->sadb_ext_type
);
918 SENDERR(EINVAL
); /* don't process these yet */
921 uint8_t sadb_alg_ivlen
;
922 uint16_t sadb_alg_minbits
;
923 uint16_t sadb_alg_maxbits
;
924 uint16_t sadb_alg_reserved
;
931 pfkey_spirange_build(struct sadb_ext
** pfkey_ext
,
933 uint32_t min
, /* in network order */
934 uint32_t max
) /* in network order */
937 struct sadb_spirange
*pfkey_spirange
= (struct sadb_spirange
*)*pfkey_ext
;
939 /* sanity checks... */
940 if (pfkey_spirange
) {
942 "pfkey_spirange_build: "
943 "why is pfkey_spirange already pointing to something?\n");
947 if (ntohl(max
) < ntohl(min
)) {
949 "pfkey_spirange_build: "
950 "minspi=%08x must be < maxspi=%08x.\n",
956 if (ntohl(min
) <= 255) {
958 "pfkey_spirange_build: "
959 "minspi=%08x must be > 255.\n",
964 pfkey_spirange
= (struct sadb_spirange
*)
965 MALLOC(sizeof(struct sadb_spirange
));
966 *pfkey_ext
= (struct sadb_ext
*)pfkey_spirange
;
968 if (pfkey_spirange
== NULL
) {
970 "pfkey_spirange_build: "
971 "memory allocation failed\n");
974 memset(pfkey_spirange
,
976 sizeof(struct sadb_spirange
));
978 pfkey_spirange
->sadb_spirange_len
= sizeof(struct sadb_spirange
) / IPSEC_PFKEYv2_ALIGN
;
980 pfkey_spirange
->sadb_spirange_exttype
= SADB_EXT_SPIRANGE
;
981 pfkey_spirange
->sadb_spirange_min
= min
;
982 pfkey_spirange
->sadb_spirange_max
= max
;
983 pfkey_spirange
->sadb_spirange_reserved
= 0;
989 pfkey_x_kmprivate_build(struct sadb_ext
** pfkey_ext
)
992 struct sadb_x_kmprivate
*pfkey_x_kmprivate
= (struct sadb_x_kmprivate
*)*pfkey_ext
;
994 /* sanity checks... */
995 if (pfkey_x_kmprivate
) {
997 "pfkey_x_kmprivate_build: "
998 "why is pfkey_x_kmprivate already pointing to something?\n");
1002 pfkey_x_kmprivate
->sadb_x_kmprivate_reserved
= 0;
1005 "pfkey_x_kmprivate_build: "
1006 "Sorry, I can't build exttype=%d yet.\n",
1007 (*pfkey_ext
)->sadb_ext_type
);
1008 SENDERR(EINVAL
); /* don't process these yet */
1010 pfkey_x_kmprivate
= (struct sadb_x_kmprivate
*)
1011 MALLOC(sizeof(struct sadb_x_kmprivate
));
1012 *pfkey_ext
= (struct sadb_ext
*)pfkey_x_kmprivate
;
1014 if (pfkey_x_kmprivate
== NULL
) {
1016 "pfkey_x_kmprivate_build: "
1017 "memory allocation failed\n");
1020 memset(pfkey_x_kmprivate
,
1022 sizeof(struct sadb_x_kmprivate
));
1024 pfkey_x_kmprivate
->sadb_x_kmprivate_len
=
1025 sizeof(struct sadb_x_kmprivate
) / IPSEC_PFKEYv2_ALIGN
;
1027 pfkey_x_kmprivate
->sadb_x_kmprivate_exttype
= SADB_X_EXT_KMPRIVATE
;
1028 pfkey_x_kmprivate
->sadb_x_kmprivate_reserved
= 0;
1034 pfkey_x_satype_build(struct sadb_ext
** pfkey_ext
,
1039 struct sadb_x_satype
*pfkey_x_satype
= (struct sadb_x_satype
*)*pfkey_ext
;
1042 "pfkey_x_satype_build:\n");
1043 /* sanity checks... */
1044 if (pfkey_x_satype
) {
1046 "pfkey_x_satype_build: "
1047 "why is pfkey_x_satype already pointing to something?\n");
1053 "pfkey_x_satype_build: "
1054 "SA type not set, must be non-zero.\n");
1058 if (satype
> SADB_SATYPE_MAX
) {
1060 "pfkey_x_satype_build: "
1061 "satype %d > max %d\n",
1062 satype
, SADB_SATYPE_MAX
);
1066 pfkey_x_satype
= (struct sadb_x_satype
*)
1067 MALLOC(sizeof(struct sadb_x_satype
));
1069 *pfkey_ext
= (struct sadb_ext
*)pfkey_x_satype
;
1071 if (pfkey_x_satype
== NULL
) {
1073 "pfkey_x_satype_build: "
1074 "memory allocation failed\n");
1077 memset(pfkey_x_satype
,
1079 sizeof(struct sadb_x_satype
));
1081 pfkey_x_satype
->sadb_x_satype_len
= sizeof(struct sadb_x_satype
) / IPSEC_PFKEYv2_ALIGN
;
1083 pfkey_x_satype
->sadb_x_satype_exttype
= SADB_X_EXT_SATYPE2
;
1084 pfkey_x_satype
->sadb_x_satype_satype
= satype
;
1085 for (i
=0; i
<3; i
++) {
1086 pfkey_x_satype
->sadb_x_satype_reserved
[i
] = 0;
1094 pfkey_x_debug_build(struct sadb_ext
** pfkey_ext
,
1110 struct sadb_x_debug
*pfkey_x_debug
= (struct sadb_x_debug
*)*pfkey_ext
;
1113 "pfkey_x_debug_build:\n");
1114 /* sanity checks... */
1115 if (pfkey_x_debug
) {
1117 "pfkey_x_debug_build: "
1118 "why is pfkey_x_debug already pointing to something?\n");
1123 "pfkey_x_debug_build: "
1124 "tunnel=%x netlink=%x xform=%x eroute=%x spi=%x radij=%x esp=%x ah=%x rcv=%x pfkey=%x ipcomp=%x verbose=%x?\n",
1125 tunnel
, netlink
, xform
, eroute
, spi
, radij
, esp
, ah
, rcv
, pfkey
, ipcomp
, verbose
);
1127 pfkey_x_debug
= (struct sadb_x_debug
*)
1128 MALLOC(sizeof(struct sadb_x_debug
));
1129 *pfkey_ext
= (struct sadb_ext
*)pfkey_x_debug
;
1131 if (pfkey_x_debug
== NULL
) {
1133 "pfkey_x_debug_build: "
1134 "memory allocation failed\n");
1138 memset(pfkey_x_debug
,
1140 sizeof(struct sadb_x_debug
));
1143 pfkey_x_debug
->sadb_x_debug_len
= sizeof(struct sadb_x_debug
) / IPSEC_PFKEYv2_ALIGN
;
1144 pfkey_x_debug
->sadb_x_debug_exttype
= SADB_X_EXT_DEBUG
;
1146 pfkey_x_debug
->sadb_x_debug_tunnel
= tunnel
;
1147 pfkey_x_debug
->sadb_x_debug_netlink
= netlink
;
1148 pfkey_x_debug
->sadb_x_debug_xform
= xform
;
1149 pfkey_x_debug
->sadb_x_debug_eroute
= eroute
;
1150 pfkey_x_debug
->sadb_x_debug_spi
= spi
;
1151 pfkey_x_debug
->sadb_x_debug_radij
= radij
;
1152 pfkey_x_debug
->sadb_x_debug_esp
= esp
;
1153 pfkey_x_debug
->sadb_x_debug_ah
= ah
;
1154 pfkey_x_debug
->sadb_x_debug_rcv
= rcv
;
1155 pfkey_x_debug
->sadb_x_debug_pfkey
= pfkey
;
1156 pfkey_x_debug
->sadb_x_debug_ipcomp
= ipcomp
;
1157 pfkey_x_debug
->sadb_x_debug_verbose
= verbose
;
1159 for (i
=0; i
<4; i
++) {
1160 pfkey_x_debug
->sadb_x_debug_reserved
[i
] = 0;
1167 #ifdef NAT_TRAVERSAL
1169 pfkey_x_nat_t_type_build(struct sadb_ext
** pfkey_ext
,
1174 struct sadb_x_nat_t_type
*pfkey_x_nat_t_type
= (struct sadb_x_nat_t_type
*)*pfkey_ext
;
1177 "pfkey_x_nat_t_type_build:\n");
1178 /* sanity checks... */
1179 if (pfkey_x_nat_t_type
) {
1181 "pfkey_x_nat_t_type_build: "
1182 "why is pfkey_x_nat_t_type already pointing to something?\n");
1187 "pfkey_x_nat_t_type_build: "
1190 pfkey_x_nat_t_type
= (struct sadb_x_nat_t_type
*)
1191 MALLOC(sizeof(struct sadb_x_nat_t_type
));
1193 *pfkey_ext
= (struct sadb_ext
*)pfkey_x_nat_t_type
;
1194 if (pfkey_x_nat_t_type
== NULL
) {
1196 "pfkey_x_nat_t_type_build: "
1197 "memory allocation failed\n");
1201 pfkey_x_nat_t_type
->sadb_x_nat_t_type_len
= sizeof(struct sadb_x_nat_t_type
) / IPSEC_PFKEYv2_ALIGN
;
1202 pfkey_x_nat_t_type
->sadb_x_nat_t_type_exttype
= SADB_X_EXT_NAT_T_TYPE
;
1203 pfkey_x_nat_t_type
->sadb_x_nat_t_type_type
= type
;
1204 for (i
=0; i
<3; i
++) {
1205 pfkey_x_nat_t_type
->sadb_x_nat_t_type_reserved
[i
] = 0;
1212 pfkey_x_nat_t_port_build(struct sadb_ext
** pfkey_ext
,
1217 struct sadb_x_nat_t_port
*pfkey_x_nat_t_port
= (struct sadb_x_nat_t_port
*)*pfkey_ext
;
1220 "pfkey_x_nat_t_port_build:\n");
1221 /* sanity checks... */
1222 if (pfkey_x_nat_t_port
) {
1224 "pfkey_x_nat_t_port_build: "
1225 "why is pfkey_x_nat_t_port already pointing to something?\n");
1230 case SADB_X_EXT_NAT_T_SPORT
:
1231 case SADB_X_EXT_NAT_T_DPORT
:
1235 "pfkey_nat_t_port_build: "
1236 "unrecognised ext_type=%d.\n",
1242 "pfkey_x_nat_t_port_build: "
1243 "ext=%d, port=%d\n", exttype
, port
);
1245 pfkey_x_nat_t_port
= (struct sadb_x_nat_t_port
*)
1246 MALLOC(sizeof(struct sadb_x_nat_t_port
));
1247 *pfkey_ext
= (struct sadb_ext
*)pfkey_x_nat_t_port
;
1249 if (pfkey_x_nat_t_port
== NULL
) {
1251 "pfkey_x_nat_t_port_build: "
1252 "memory allocation failed\n");
1256 pfkey_x_nat_t_port
->sadb_x_nat_t_port_len
= sizeof(struct sadb_x_nat_t_port
) / IPSEC_PFKEYv2_ALIGN
;
1257 pfkey_x_nat_t_port
->sadb_x_nat_t_port_exttype
= exttype
;
1258 pfkey_x_nat_t_port
->sadb_x_nat_t_port_port
= port
;
1259 pfkey_x_nat_t_port
->sadb_x_nat_t_port_reserved
= 0;
1266 int pfkey_x_protocol_build(struct sadb_ext
**pfkey_ext
,
1270 struct sadb_protocol
* p
= (struct sadb_protocol
*)*pfkey_ext
;
1271 DEBUGGING("pfkey_x_protocol_build: protocol=%u\n", protocol
);
1272 /* sanity checks... */
1274 DEBUGGING("pfkey_x_protocol_build: bogus protocol pointer\n");
1277 if ((p
= (struct sadb_protocol
*)MALLOC(sizeof(*p
))) == 0) {
1278 DEBUGGING("pfkey_build: memory allocation failed\n");
1281 *pfkey_ext
= (struct sadb_ext
*)p
;
1282 p
->sadb_protocol_len
= sizeof(*p
) / sizeof(uint64_t);
1283 p
->sadb_protocol_exttype
= SADB_X_EXT_PROTOCOL
;
1284 p
->sadb_protocol_proto
= protocol
;
1285 p
->sadb_protocol_flags
= 0;
1286 p
->sadb_protocol_reserved2
= 0;
1292 #if I_DONT_THINK_THIS_WILL_BE_USEFUL
1293 int (*ext_default_builders
[SADB_EXT_MAX
+1])(struct sadb_msg
*, struct sadb_ext
*)
1296 NULL
, /* pfkey_msg_build, */
1298 pfkey_lifetime_build
,
1299 pfkey_lifetime_build
,
1300 pfkey_lifetime_build
,
1301 pfkey_address_build
,
1302 pfkey_address_build
,
1303 pfkey_address_build
,
1310 pfkey_supported_build
,
1311 pfkey_supported_build
,
1312 pfkey_spirange_build
,
1313 pfkey_x_kmprivate_build
,
1314 pfkey_x_satype_build
,
1316 pfkey_address_build
,
1317 pfkey_address_build
,
1318 pfkey_address_build
,
1319 pfkey_address_build
,
1320 pfkey_address_build
,
1321 pfkey_x_ext_debug_build
1326 pfkey_msg_build(struct sadb_msg
**pfkey_msg
, struct sadb_ext
*extensions
[], int dir
)
1330 unsigned total_size
;
1331 struct sadb_ext
*pfkey_ext
;
1332 int extensions_seen
= 0;
1333 struct sadb_ext
*extensions_check
[SADB_EXT_MAX
+ 1];
1335 if (!extensions
[0]) {
1338 "extensions[0] must be specified (struct sadb_msg).\n");
1342 total_size
= sizeof(struct sadb_msg
) / IPSEC_PFKEYv2_ALIGN
;
1343 for (ext
= 1; ext
<= SADB_EXT_MAX
; ext
++) {
1344 if(extensions
[ext
]) {
1345 total_size
+= (extensions
[ext
])->sadb_ext_len
;
1349 if (!(*pfkey_msg
= (struct sadb_msg
*)MALLOC(total_size
* IPSEC_PFKEYv2_ALIGN
))) {
1352 "memory allocation failed\n");
1358 "pfkey_msg=0p%p allocated %lu bytes, &(extensions[0])=0p%p\n",
1360 (unsigned long)(total_size
* IPSEC_PFKEYv2_ALIGN
),
1364 sizeof(struct sadb_msg
));
1365 (*pfkey_msg
)->sadb_msg_len
= total_size
;
1366 (*pfkey_msg
)->sadb_msg_reserved
= 0;
1367 extensions_seen
= 1 ;
1369 pfkey_ext
= (struct sadb_ext
*)(((char*)(*pfkey_msg
)) + sizeof(struct sadb_msg
));
1371 for (ext
= 1; ext
<= SADB_EXT_MAX
; ext
++) {
1372 /* copy from extension[ext] to buffer */
1373 if (extensions
[ext
]) {
1374 /* Is this type of extension permitted for this type of message? */
1375 if (!(extensions_bitmaps
[dir
][EXT_BITS_PERM
][(*pfkey_msg
)->sadb_msg_type
] &
1379 "ext type %d not permitted, exts_perm=%08x, 1<<type=%08x\n",
1381 extensions_bitmaps
[dir
][EXT_BITS_PERM
][(*pfkey_msg
)->sadb_msg_type
],
1387 "copying %lu bytes from extensions[%u]=0p%p to=0p%p\n",
1388 (unsigned long)(extensions
[ext
]->sadb_ext_len
* IPSEC_PFKEYv2_ALIGN
),
1394 (extensions
[ext
])->sadb_ext_len
* IPSEC_PFKEYv2_ALIGN
);
1396 char *pfkey_ext_c
= (char *)pfkey_ext
;
1398 pfkey_ext_c
+= (extensions
[ext
])->sadb_ext_len
* IPSEC_PFKEYv2_ALIGN
;
1399 pfkey_ext
= (struct sadb_ext
*)pfkey_ext_c
;
1401 /* Mark that we have seen this extension and remember the header location */
1402 extensions_seen
|= ( 1 << ext
);
1406 /* check required extensions */
1409 "extensions permitted=%08x, seen=%08x, required=%08x.\n",
1410 extensions_bitmaps
[dir
][EXT_BITS_PERM
][(*pfkey_msg
)->sadb_msg_type
],
1412 extensions_bitmaps
[dir
][EXT_BITS_REQ
][(*pfkey_msg
)->sadb_msg_type
]);
1414 if ((extensions_seen
&
1415 extensions_bitmaps
[dir
][EXT_BITS_REQ
][(*pfkey_msg
)->sadb_msg_type
]) !=
1416 extensions_bitmaps
[dir
][EXT_BITS_REQ
][(*pfkey_msg
)->sadb_msg_type
]) {
1419 "required extensions missing:%08x.\n",
1420 extensions_bitmaps
[dir
][EXT_BITS_REQ
][(*pfkey_msg
)->sadb_msg_type
] -
1422 extensions_bitmaps
[dir
][EXT_BITS_REQ
][(*pfkey_msg
)->sadb_msg_type
]) );
1426 error
= pfkey_msg_parse(*pfkey_msg
, NULL
, extensions_check
, dir
);
1430 "Trouble parsing newly built pfkey message, error=%d.\n",