OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / lib / pfkey_v2_build.c
1 /*
2  * RFC2367 PF_KEYv2 Key management API message parser
3  * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs.
4  * 
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>.
9  * 
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
13  * for more details.
14  *
15  * RCSID $Id: pfkey_v2_build.c,v 1.31 2002/01/29 22:25:35 rgb Exp $
16  */
17
18 /*
19  *              Template from klips/net/ipsec/ipsec/ipsec_parser.c.
20  */
21
22 char pfkey_v2_build_c_version[] = "$Id: pfkey_v2_build.c,v 1.31 2002/01/29 22:25:35 rgb Exp $";
23
24 /*
25  * Some ugly stuff to allow consistent debugging code for use in the
26  * kernel and in user space
27 */
28
29 #ifdef __KERNEL__
30
31 # include <linux/kernel.h>  /* for printk */
32
33 # include "ipsec_kversion.h" /* for malloc switch */
34 # ifdef MALLOC_SLAB
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 */
42
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) */
49
50 # define MALLOC(size) kmalloc(size, GFP_ATOMIC)
51 # define FREE(obj) kfree(obj)
52 # include <freeswan.h>
53 #else /* __KERNEL__ */
54
55 # include <sys/types.h>
56 # include <linux/types.h>
57 # include <linux/errno.h>
58 # include <malloc.h>
59 # include <string.h> /* memset */
60
61 # include <freeswan.h>
62 # include "../pluto/constants.h" 
63 # include "../pluto/defs.h"  /* for PRINTF_LIKE */
64 # include "../pluto/log.h"  /* for debugging and DBG_log */
65
66 extern unsigned int debugging;  /* bits selecting what to report */
67 unsigned int pfkey_lib_debug = 0;
68
69 /* #define PLUTO */
70
71 # ifdef PLUTO
72 #  define DEBUGGING(args...)  { DBG_log("pfkey_lib_debug:" args);  }
73 # else
74 #  define DEBUGGING(args...)  if(pfkey_lib_debug) { printf("pfkey_lib_debug:" args); } else { ; }
75 # endif
76 # define MALLOC(size) malloc(size)
77 # define FREE(obj) free(obj)
78 #endif /* __KERNEL__ */
79
80 #include <pfkeyv2.h>
81 #include <pfkey.h>
82
83 #ifdef __KERNEL__
84 # include "radij.h"  /* rd_nodes */
85 # include "ipsec_encap.h"  /* sockaddr_encap */
86 # include "ipsec_netlink.h"  /* KLIPS_PRINT */
87 # define DEBUGGING(args...) \
88          KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
89 /*         ((debug_pfkey) ? printk(KERN_INFO "klips_debug:" format , ## args) : 0) */
90 #endif /* __KERNEL__ */
91
92
93 #define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
94
95 void
96 pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
97 {
98         int i;
99         
100         for (i = 0; i != SADB_EXT_MAX + 1; i++) {
101                 extensions[i] = NULL;
102         }
103 }
104
105 void
106 pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
107 {
108         int i;
109         
110         if(!extensions) {
111                 return;
112         }
113
114         if(extensions[0]) {
115                 memset(extensions[0], 0, sizeof(struct sadb_msg));
116                 FREE(extensions[0]);
117                 extensions[0] = NULL;
118         }
119         
120         for (i = 1; i != SADB_EXT_MAX + 1; i++) {
121                 if(extensions[i]) {
122                         memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
123                         FREE(extensions[i]);
124                         extensions[i] = NULL;
125                 }
126         }
127 }
128
129 void
130 pfkey_msg_free(struct sadb_msg **pfkey_msg)
131 {
132         if(*pfkey_msg) {
133                 memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
134                 FREE(*pfkey_msg);
135                 *pfkey_msg = NULL;
136         }
137 }
138
139 /* Default extension builders taken from the KLIPS code */
140
141 int
142 pfkey_msg_hdr_build(struct sadb_ext**   pfkey_ext,
143                     uint8_t             msg_type,
144                     uint8_t             satype,
145                     uint8_t             msg_errno,
146                     uint32_t            seq,
147                     uint32_t            pid)
148 {
149         int error = 0;
150         struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext;
151
152         DEBUGGING(
153                 "pfkey_msg_hdr_build:\n");
154         DEBUGGING(
155                 "pfkey_msg_hdr_build: "
156                 "on_entry &pfkey_ext=%p pfkey_ext=%p *pfkey_ext=%p.\n",
157                 &pfkey_ext,
158                 pfkey_ext,
159                 *pfkey_ext);
160         /* sanity checks... */
161         if(pfkey_msg) {
162                 DEBUGGING(
163                         "pfkey_msg_hdr_build: "
164                         "why is pfkey_msg already pointing to something?\n");
165                 SENDERR(EINVAL);
166         }
167
168         if(!msg_type) {
169                 DEBUGGING(
170                         "pfkey_msg_hdr_build: "
171                         "msg type not set, must be non-zero..\n");
172                 SENDERR(EINVAL);
173         }
174
175         if(msg_type > SADB_MAX) {
176                 DEBUGGING(
177                         "pfkey_msg_hdr_build: "
178                         "msg type too large:%d.\n",
179                         msg_type);
180                 SENDERR(EINVAL);
181         }
182
183         if(satype > SADB_SATYPE_MAX) {
184                 DEBUGGING(
185                         "pfkey_msg_hdr_build: "
186                         "satype %d > max %d\n", 
187                         satype, SADB_SATYPE_MAX);
188                 SENDERR(EINVAL);
189         }
190
191         pfkey_msg = (struct sadb_msg*)
192              MALLOC(sizeof(struct sadb_msg));
193         if(!pfkey_msg) {
194                 DEBUGGING(
195                         "pfkey_msg_hdr_build: "
196                         "memory allocation failed\n");
197                 SENDERR(ENOMEM);
198         }
199         *pfkey_ext = (struct sadb_ext*)pfkey_msg;
200         memset(pfkey_msg, 0, sizeof(struct sadb_msg));
201
202         pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
203
204         pfkey_msg->sadb_msg_type = msg_type;
205         pfkey_msg->sadb_msg_satype = satype;
206
207         pfkey_msg->sadb_msg_version = PF_KEY_V2;
208         pfkey_msg->sadb_msg_errno = msg_errno;
209         pfkey_msg->sadb_msg_reserved = 0;
210         pfkey_msg->sadb_msg_seq = seq;
211         pfkey_msg->sadb_msg_pid = pid;
212         DEBUGGING(
213                 "pfkey_msg_hdr_build: "
214                 "on_exit &pfkey_ext=%p pfkey_ext=%p *pfkey_ext=%p.\n",
215                 &pfkey_ext,
216                 pfkey_ext,
217                 *pfkey_ext);
218 errlab:
219         return error;
220 }       
221
222 int
223 pfkey_sa_build(struct sadb_ext **       pfkey_ext,
224                uint16_t                 exttype,
225                uint32_t                 spi, /* in network order */
226                uint8_t                  replay_window,
227                uint8_t                  sa_state,
228                uint8_t                  auth,
229                uint8_t                  encrypt,
230                uint32_t                 flags)
231 {
232         int error = 0;
233         struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext;
234
235         DEBUGGING(
236                     "pfkey_sa_build: "
237                     "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n",
238                     ntohl(spi), /* in network order */
239                     replay_window,
240                     sa_state,
241                     auth,
242                     encrypt,
243                     flags);
244         /* sanity checks... */
245         if(pfkey_sa) {
246                 DEBUGGING(
247                         "pfkey_sa_build: "
248                         "why is pfkey_sa already pointing to something?\n");
249                 SENDERR(EINVAL);
250         }
251
252         if(exttype != SADB_EXT_SA &&
253            exttype != SADB_X_EXT_SA2) {
254                 DEBUGGING(
255                         "pfkey_sa_build: "
256                         "invalid exttype=%d.\n",
257                         exttype);
258                 SENDERR(EINVAL);
259         }
260
261         if(replay_window > 64) {
262                 DEBUGGING(
263                         "pfkey_sa_build: "
264                         "replay window size: %d -- must be 0 <= size <= 64\n",
265                         replay_window);
266                 SENDERR(EINVAL);
267         }
268
269         if(auth > SADB_AALG_MAX) {
270                 DEBUGGING(
271                         "pfkey_sa_build: "
272                         "auth=%d > SADB_AALG_MAX=%d.\n",
273                         auth,
274                         SADB_AALG_MAX);
275                 SENDERR(EINVAL);
276         }
277
278         if(encrypt > SADB_EALG_MAX) {
279                 DEBUGGING(
280                         "pfkey_sa_build: "
281                         "encrypt=%d > SADB_EALG_MAX=%d.\n",
282                         encrypt,
283                         SADB_EALG_MAX);
284                 SENDERR(EINVAL);
285         }
286
287         if(sa_state > SADB_SASTATE_MAX) {
288                 DEBUGGING(
289                         "pfkey_sa_build: "
290                         "sa_state=%d exceeds MAX=%d.\n",
291                         sa_state,
292                         SADB_SASTATE_MAX);
293                 SENDERR(EINVAL);
294         }
295
296         if(sa_state == SADB_SASTATE_DEAD) {
297                 DEBUGGING(
298                         "pfkey_sa_build: "
299                         "sa_state=%d is DEAD=%d is not allowed.\n",
300                         sa_state,
301                         SADB_SASTATE_DEAD);
302                 SENDERR(EINVAL);
303         }
304         
305         pfkey_sa = (struct sadb_sa*)
306              MALLOC(sizeof(struct sadb_sa));
307         if(!pfkey_sa) {
308                 DEBUGGING(
309                         "pfkey_sa_build: "
310                         "memory allocation failed\n");
311                 SENDERR(ENOMEM);
312         }
313         *pfkey_ext = (struct sadb_ext*)pfkey_sa;
314         memset(pfkey_sa, 0, sizeof(struct sadb_sa));
315         
316         pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN;
317         pfkey_sa->sadb_sa_exttype = exttype;
318         pfkey_sa->sadb_sa_spi = spi;
319         pfkey_sa->sadb_sa_replay = replay_window;
320         pfkey_sa->sadb_sa_state = sa_state;
321         pfkey_sa->sadb_sa_auth = auth;
322         pfkey_sa->sadb_sa_encrypt = encrypt;
323         pfkey_sa->sadb_sa_flags = flags;
324
325 errlab:
326         return error;
327 }       
328
329 int
330 pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
331                      uint16_t           exttype,
332                      uint32_t           allocations,
333                      uint64_t           bytes,
334                      uint64_t           addtime,
335                      uint64_t           usetime,
336                      uint32_t           packets)
337 {
338         int error = 0;
339         struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext;
340
341         DEBUGGING(
342                 "pfkey_lifetime_build:\n");
343         /* sanity checks... */
344         if(pfkey_lifetime) {
345                 DEBUGGING(
346                         "pfkey_lifetime_build: "
347                         "why is pfkey_lifetime already pointing to something?\n");
348                 SENDERR(EINVAL);
349         }
350
351         if(exttype != SADB_EXT_LIFETIME_CURRENT &&
352            exttype != SADB_EXT_LIFETIME_HARD &&
353            exttype != SADB_EXT_LIFETIME_SOFT) {
354                 DEBUGGING(
355                         "pfkey_lifetime_build: "
356                         "invalid exttype=%d.\n",
357                         exttype);
358                 SENDERR(EINVAL);
359         }
360
361         pfkey_lifetime = (struct sadb_lifetime*)
362              MALLOC(sizeof(struct sadb_lifetime));
363         if(!pfkey_lifetime) {
364                 DEBUGGING(
365                         "pfkey_lifetime_build: "
366                         "memory allocation failed\n");
367                 SENDERR(ENOMEM);
368         }
369         *pfkey_ext = (struct sadb_ext*)pfkey_lifetime;
370         memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime));
371
372         pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN;
373         pfkey_lifetime->sadb_lifetime_exttype = exttype;
374         pfkey_lifetime->sadb_lifetime_allocations = allocations;
375         pfkey_lifetime->sadb_lifetime_bytes = bytes;
376         pfkey_lifetime->sadb_lifetime_addtime = addtime;
377         pfkey_lifetime->sadb_lifetime_usetime = usetime;
378         pfkey_lifetime->sadb_x_lifetime_packets = packets;
379
380 errlab:
381         return error;
382 }
383
384 int
385 pfkey_address_build(struct sadb_ext**   pfkey_ext,
386                     uint16_t            exttype,
387                     uint8_t             proto,
388                     uint8_t             prefixlen,
389                     struct sockaddr*    address)
390 {
391         int error = 0;
392         int saddr_len = 0;
393         char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/];
394         struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext;
395         
396         DEBUGGING(
397                 "pfkey_address_build: "
398                 "exttype=%d proto=%d prefixlen=%d\n",
399                 exttype,
400                 proto,
401                 prefixlen);
402         /* sanity checks... */
403         if(pfkey_address) {
404                 DEBUGGING(
405                         "pfkey_address_build: "
406                         "why is pfkey_address already pointing to something?\n");
407                 SENDERR(EINVAL);
408         }
409
410         if (!address)  {
411                         DEBUGGING("pfkey_address_build: "
412                                   "address is NULL\n");
413                         SENDERR(EINVAL);
414         }
415         
416         switch(exttype) {       
417         case SADB_EXT_ADDRESS_SRC:
418         case SADB_EXT_ADDRESS_DST:
419         case SADB_EXT_ADDRESS_PROXY:
420         case SADB_X_EXT_ADDRESS_DST2:
421         case SADB_X_EXT_ADDRESS_SRC_FLOW:
422         case SADB_X_EXT_ADDRESS_DST_FLOW:
423         case SADB_X_EXT_ADDRESS_SRC_MASK:
424         case SADB_X_EXT_ADDRESS_DST_MASK:
425 #if defined(CONFIG_IPSEC_NAT_TRAVERSAL) || defined(NAT_TRAVERSAL)
426         case SADB_X_EXT_NAT_T_OA:
427 #endif
428                 break;
429         default:
430                 DEBUGGING( 
431                         "pfkey_address_build: "
432                         "unrecognised ext_type=%d.\n", 
433                         exttype); 
434                 SENDERR(EINVAL); 
435         }
436
437         switch(address->sa_family) {
438         case AF_INET:
439                 DEBUGGING(
440                         "pfkey_address_build: "
441                         "found address family AF_INET.\n");
442                 saddr_len = sizeof(struct sockaddr_in);
443                 sprintf(ipaddr_txt, "%d.%d.%d.%d:%d"
444                         , (((struct sockaddr_in*)address)->sin_addr.s_addr >>  0) & 0xFF
445                         , (((struct sockaddr_in*)address)->sin_addr.s_addr >>  8) & 0xFF
446                         , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF
447                         , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF
448                         , ntohs(((struct sockaddr_in*)address)->sin_port));
449                 break;
450         case AF_INET6:
451                 DEBUGGING(
452                         "pfkey_address_build: "
453                         "found address family AF_INET6.\n");
454                 saddr_len = sizeof(struct sockaddr_in6);
455                 sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x"
456                         , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0])
457                         , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1])
458                         , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2])
459                         , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3])
460                         , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4])
461                         , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5])
462                         , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6])
463                         , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7])
464                         , ntohs(((struct sockaddr_in6*)address)->sin6_port));
465                 break;
466         default:
467                 DEBUGGING(
468                         "pfkey_address_build: "
469                         "address->sa_family=%d not supported.\n",
470                         address->sa_family);
471                 SENDERR(EPFNOSUPPORT);
472         }
473
474         DEBUGGING(
475                 "pfkey_address_build: "
476                 "found address=%s.\n",
477                 ipaddr_txt);
478         if(prefixlen != 0) {
479                 DEBUGGING(
480                         "pfkey_address_build: "
481                         "address prefixes not supported yet.\n");
482                 SENDERR(EAFNOSUPPORT); /* not supported yet */
483         }
484
485          pfkey_address = (struct sadb_address*)
486              MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN) );
487         if(!pfkey_address) {
488                 DEBUGGING(
489                         "pfkey_lifetime_build: "
490                         "memory allocation failed\n");
491                 SENDERR(ENOMEM);
492         }
493         *pfkey_ext = (struct sadb_ext*)pfkey_address;
494         memset(pfkey_address,
495                0,
496                ALIGN_N(sizeof(struct sadb_address) + saddr_len,
497                      IPSEC_PFKEYv2_ALIGN));
498                
499         pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len,
500                                                 IPSEC_PFKEYv2_ALIGN);
501         
502         pfkey_address->sadb_address_exttype = exttype;
503         pfkey_address->sadb_address_proto = proto;
504         pfkey_address->sadb_address_prefixlen = prefixlen;
505         pfkey_address->sadb_address_reserved = 0;
506
507         memcpy((char*)pfkey_address + sizeof(struct sadb_address),
508                address,
509                saddr_len);
510
511 #if 0
512         for(i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) {
513                 pfkey_address_s_ska.sin_zero[i] = 0;
514         }
515 #endif
516         DEBUGGING(
517                 "pfkey_address_build: "
518                 "successful.\n");
519
520  errlab:
521         return error;
522 }
523
524 int
525 pfkey_key_build(struct sadb_ext**       pfkey_ext,
526                 uint16_t                exttype,
527                 uint16_t                key_bits,
528                 char*                   key)
529 {
530         int error = 0;
531         struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext;
532
533         DEBUGGING(
534                 "pfkey_key_build:\n");
535         /* sanity checks... */
536         if(pfkey_key) {
537                 DEBUGGING(
538                         "pfkey_key_build: "
539                         "why is pfkey_key already pointing to something?\n");
540                 SENDERR(EINVAL);
541         }
542
543         if(!key_bits) {
544                 DEBUGGING(
545                         "pfkey_key_build: "
546                         "key_bits is zero, it must be non-zero.\n");
547                 SENDERR(EINVAL);
548         }
549
550         if( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) {
551                 DEBUGGING(
552                         "pfkey_key_build: "
553                         "unsupported extension type=%d.\n",
554                         exttype);
555                 SENDERR(EINVAL);
556         }
557
558          pfkey_key = (struct sadb_key*)
559              MALLOC(sizeof(struct sadb_key) +
560                                     DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
561         if(!pfkey_key) {
562                 DEBUGGING(
563                         "pfkey_key_build: "
564                         "memory allocation failed\n");
565                 SENDERR(ENOMEM);
566         }
567         *pfkey_ext = (struct sadb_ext*) pfkey_key;
568         memset(pfkey_key,
569                0,
570                sizeof(struct sadb_key) +
571                DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
572         
573         pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits,
574                                         64);
575         pfkey_key->sadb_key_exttype = exttype;
576         pfkey_key->sadb_key_bits = key_bits;
577         pfkey_key->sadb_key_reserved = 0;
578         memcpy((char*)pfkey_key + sizeof(struct sadb_key),
579                key,
580                DIVUP(key_bits, 8));
581
582 errlab:
583         return error;
584 }
585
586 int
587 pfkey_ident_build(struct sadb_ext**     pfkey_ext,
588                   uint16_t              exttype,
589                   uint16_t              ident_type,
590                   uint64_t              ident_id,
591                   uint8_t               ident_len,
592                   char*                 ident_string)
593 {
594         int error = 0;
595         struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext;
596         int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
597
598         DEBUGGING(
599                 "pfkey_ident_build:\n");
600         /* sanity checks... */
601         if(pfkey_ident) {
602                 DEBUGGING(
603                         "pfkey_ident_build: "
604                         "why is pfkey_ident already pointing to something?\n");
605                 SENDERR(EINVAL);
606         }
607
608         if( ! ((exttype == SADB_EXT_IDENTITY_SRC) ||
609                (exttype == SADB_EXT_IDENTITY_DST))) {
610                 DEBUGGING(
611                         "pfkey_ident_build: "
612                         "unsupported extension type=%d.\n",
613                         exttype);
614                 SENDERR(EINVAL);
615         }
616
617         if((ident_type == SADB_IDENTTYPE_RESERVED)) {
618                 DEBUGGING(
619                         "pfkey_ident_build: "
620                         "ident_type must be non-zero.\n");
621                 SENDERR(EINVAL);
622         }
623
624         if(ident_type > SADB_IDENTTYPE_MAX) {
625                 DEBUGGING(
626                         "pfkey_ident_build: "
627                         "identtype=%d out of range.\n",
628                         ident_type);
629                 SENDERR(EINVAL);
630         }
631
632         if(((ident_type == SADB_IDENTTYPE_PREFIX) ||
633             (ident_type == SADB_IDENTTYPE_FQDN)) &&
634            !ident_string) {
635                 DEBUGGING(
636                         "pfkey_ident_build: "
637                         "string required to allocate size of extension.\n");
638                 SENDERR(EINVAL);
639         }
640         
641 #if 0
642         if((ident_type == SADB_IDENTTYPE_USERFQDN) ) {
643         }
644 #endif
645             
646         pfkey_ident = (struct sadb_ident*)
647              MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN);
648         if(!pfkey_ident) {
649                 DEBUGGING(
650                         "pfkey_ident_build: "
651                         "memory allocation failed\n");
652                 SENDERR(ENOMEM);
653         }
654         *pfkey_ext = (struct sadb_ext*)pfkey_ident;
655         memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN);
656         
657         pfkey_ident->sadb_ident_len = ident_len;
658         pfkey_ident->sadb_ident_exttype = exttype;
659         pfkey_ident->sadb_ident_type = ident_type;
660         pfkey_ident->sadb_ident_reserved = 0;
661         pfkey_ident->sadb_ident_id = ident_id;
662         memcpy((char*)pfkey_ident + sizeof(struct sadb_ident),
663                ident_string,
664                data_len);
665
666 errlab:
667         return error;
668 }
669
670 int
671 pfkey_sens_build(struct sadb_ext**      pfkey_ext,
672                  uint32_t               dpd,
673                  uint8_t                sens_level,
674                  uint8_t                sens_len,
675                  uint64_t*              sens_bitmap,
676                  uint8_t                integ_level,
677                  uint8_t                integ_len,
678                  uint64_t*              integ_bitmap)
679 {
680         int error = 0;
681         struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext;
682         int i;
683         uint64_t* bitmap;
684
685         DEBUGGING(
686                 "pfkey_sens_build:\n");
687         /* sanity checks... */
688         if(pfkey_sens) {
689                 DEBUGGING(
690                         "pfkey_sens_build: "
691                         "why is pfkey_sens already pointing to something?\n");
692                 SENDERR(EINVAL);
693         }
694
695         DEBUGGING(
696                 "pfkey_sens_build: "
697                 "Sorry, I can't build exttype=%d yet.\n",
698                 (*pfkey_ext)->sadb_ext_type);
699         SENDERR(EINVAL); /* don't process these yet */
700
701          pfkey_sens = (struct sadb_sens*)
702              MALLOC(sizeof(struct sadb_sens) +
703                     (sens_len + integ_len) * sizeof(uint64_t));
704         if(!pfkey_sens) {
705                 DEBUGGING(
706                         "pfkey_sens_build: "
707                         "memory allocation failed\n");
708                 SENDERR(ENOMEM);
709         }
710         *pfkey_ext = (struct sadb_ext*)pfkey_sens;
711         memset(pfkey_sens,
712                0,
713                sizeof(struct sadb_sens) +
714                (sens_len + integ_len) * sizeof(uint64_t));
715         
716         pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) +
717                     (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN;
718         pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY;
719         pfkey_sens->sadb_sens_dpd = dpd;
720         pfkey_sens->sadb_sens_sens_level = sens_level;
721         pfkey_sens->sadb_sens_sens_len = sens_len;
722         pfkey_sens->sadb_sens_integ_level = integ_level;
723         pfkey_sens->sadb_sens_integ_len = integ_len;
724         pfkey_sens->sadb_sens_reserved = 0;
725
726         bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens));
727         for(i = 0; i < sens_len; i++) {
728                 *bitmap = sens_bitmap[i];
729                 bitmap++;
730         }
731         for(i = 0; i < integ_len; i++) {
732                 *bitmap = integ_bitmap[i];
733                 bitmap++;
734         }
735
736 errlab:
737         return error;
738 }
739
740 int
741 pfkey_prop_build(struct sadb_ext**      pfkey_ext,
742                  uint8_t                replay,
743                  unsigned int           comb_num,
744                  struct sadb_comb*      comb)
745 {
746         int error = 0;
747         int i;
748         struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext;
749         struct sadb_comb *combp;
750
751         DEBUGGING(
752                 "pfkey_prop_build:\n");
753         /* sanity checks... */
754         if(pfkey_prop) {
755                 DEBUGGING(
756                         "pfkey_prop_build: "
757                         "why is pfkey_prop already pointing to something?\n");
758                 SENDERR(EINVAL);
759         }
760
761         pfkey_prop = (struct sadb_prop*)
762         MALLOC(sizeof(struct sadb_prop) +
763                 comb_num * sizeof(struct sadb_comb));
764         if(!pfkey_prop) {
765                 DEBUGGING(
766                         "pfkey_prop_build: "
767                         "memory allocation failed\n");
768                 SENDERR(ENOMEM);
769         }
770         *pfkey_ext = (struct sadb_ext*)pfkey_prop;
771         memset(pfkey_prop,
772                0,
773                sizeof(struct sadb_prop) +
774                     comb_num * sizeof(struct sadb_comb));
775         
776         pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
777                     comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN;
778
779         pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
780         pfkey_prop->sadb_prop_replay = replay;
781
782         for(i=0; i<3; i++) {
783                 pfkey_prop->sadb_prop_reserved[i] = 0;
784         }
785
786         combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop));
787         for(i = 0; i < comb_num; i++) {
788                 memcpy (combp, &(comb[i]), sizeof(struct sadb_comb));
789                 combp++;
790         }
791
792 #if 0
793   uint8_t sadb_comb_auth;
794   uint8_t sadb_comb_encrypt;
795   uint16_t sadb_comb_flags;
796   uint16_t sadb_comb_auth_minbits;
797   uint16_t sadb_comb_auth_maxbits;
798   uint16_t sadb_comb_encrypt_minbits;
799   uint16_t sadb_comb_encrypt_maxbits;
800   uint32_t sadb_comb_reserved;
801   uint32_t sadb_comb_soft_allocations;
802   uint32_t sadb_comb_hard_allocations;
803   uint64_t sadb_comb_soft_bytes;
804   uint64_t sadb_comb_hard_bytes;
805   uint64_t sadb_comb_soft_addtime;
806   uint64_t sadb_comb_hard_addtime;
807   uint64_t sadb_comb_soft_usetime;
808   uint64_t sadb_comb_hard_usetime;
809   uint32_t sadb_comb_soft_packets;
810   uint32_t sadb_comb_hard_packets;
811 #endif
812 errlab:
813         return error;
814 }
815
816 int
817 pfkey_supported_build(struct sadb_ext** pfkey_ext,
818                       uint16_t          exttype,
819                       unsigned int      alg_num,
820                       struct sadb_alg*  alg)
821 {
822         int error = 0;
823         unsigned int i;
824         struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext;
825         struct sadb_alg *pfkey_alg;
826
827         /* sanity checks... */
828         if(pfkey_supported) {
829                 DEBUGGING(
830                         "pfkey_supported_build: "
831                         "why is pfkey_supported already pointing to something?\n");
832                 SENDERR(EINVAL);
833         }
834
835         if( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) {
836                 DEBUGGING(
837                         "pfkey_supported_build: "
838                         "unsupported extension type=%d.\n",
839                         exttype);
840                 SENDERR(EINVAL);
841         }
842
843          pfkey_supported = (struct sadb_supported*)
844          MALLOC(sizeof(struct sadb_supported) +
845                                            alg_num *
846                                            sizeof(struct sadb_alg));
847         if(!pfkey_supported) {
848                 DEBUGGING(
849                         "pfkey_supported_build: "
850                         "memory allocation failed\n");
851                 SENDERR(ENOMEM);
852         }
853         *pfkey_ext = (struct sadb_ext*)pfkey_supported;
854         memset(pfkey_supported,
855                0,
856                sizeof(struct sadb_supported) +
857                                                alg_num *
858                                                sizeof(struct sadb_alg));
859         
860         pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) +
861                                                alg_num *
862                                                sizeof(struct sadb_alg)) /
863                                                 IPSEC_PFKEYv2_ALIGN;
864         pfkey_supported->sadb_supported_exttype = exttype;
865         pfkey_supported->sadb_supported_reserved = 0;
866
867         pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported));
868         for(i = 0; i < alg_num; i++) {
869                 memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg));
870                 pfkey_alg->sadb_alg_reserved = 0;
871                 pfkey_alg++;
872         }
873         
874 #if 0
875         DEBUGGING(
876                 "pfkey_supported_build: "
877                 "Sorry, I can't build exttype=%d yet.\n",
878                 (*pfkey_ext)->sadb_ext_type);
879         SENDERR(EINVAL); /* don't process these yet */
880
881   uint8_t sadb_alg_id;
882   uint8_t sadb_alg_ivlen;
883   uint16_t sadb_alg_minbits;
884   uint16_t sadb_alg_maxbits;
885   uint16_t sadb_alg_reserved;
886 #endif
887 errlab:
888         return error;
889 }
890
891 int
892 pfkey_spirange_build(struct sadb_ext**  pfkey_ext,
893                      uint16_t           exttype,
894                      uint32_t           min, /* in network order */
895                      uint32_t           max) /* in network order */
896 {
897         int error = 0;
898         struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext;
899         
900         /* sanity checks... */
901         if(pfkey_spirange) {
902                 DEBUGGING(
903                         "pfkey_spirange_build: "
904                         "why is pfkey_spirange already pointing to something?\n");
905                 SENDERR(EINVAL);
906         }
907         
908         if(ntohl(max) < ntohl(min)) {
909                 DEBUGGING(
910                         "pfkey_spirange_build: "
911                         "minspi=%08x must be < maxspi=%08x.\n",
912                         ntohl(min),
913                         ntohl(max));
914                 SENDERR(EINVAL);
915         }
916         
917         if(ntohl(min) <= 255) {
918                 DEBUGGING(
919                         "pfkey_spirange_build: "
920                         "minspi=%08x must be > 255.\n",
921                         ntohl(min));
922                 SENDERR(EEXIST);
923         }
924         
925         pfkey_spirange = (struct sadb_spirange*)MALLOC(sizeof(struct sadb_spirange));
926         if(!pfkey_spirange) {
927                 DEBUGGING(
928                         "pfkey_spirange_build: "
929                         "memory allocation failed\n");
930                 SENDERR(ENOMEM);
931         }
932         *pfkey_ext = (struct sadb_ext*)pfkey_spirange;
933         memset(pfkey_spirange,
934                0,
935                sizeof(struct sadb_spirange));
936         
937         pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN;
938
939         pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
940         pfkey_spirange->sadb_spirange_min = min;
941         pfkey_spirange->sadb_spirange_max = max;
942         pfkey_spirange->sadb_spirange_reserved = 0;
943  errlab:
944         return error;
945 }
946
947 int
948 pfkey_x_kmprivate_build(struct sadb_ext**       pfkey_ext)
949 {
950         int error = 0;
951         struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext;
952
953         /* sanity checks... */
954         if(pfkey_x_kmprivate) {
955                 DEBUGGING(
956                         "pfkey_x_kmprivate_build: "
957                         "why is pfkey_x_kmprivate already pointing to something?\n");
958                 SENDERR(EINVAL);
959         }
960         
961         pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
962
963         DEBUGGING(
964                 "pfkey_x_kmprivate_build: "
965                 "Sorry, I can't build exttype=%d yet.\n",
966                 (*pfkey_ext)->sadb_ext_type);
967         SENDERR(EINVAL); /* don't process these yet */
968
969         pfkey_x_kmprivate = (struct sadb_x_kmprivate*)
970          MALLOC(sizeof(struct sadb_x_kmprivate));
971         if(!pfkey_x_kmprivate) {
972                 DEBUGGING(
973                         "pfkey_x_kmprivate_build: "
974                         "memory allocation failed\n");
975                 SENDERR(ENOMEM);
976         }
977         *pfkey_ext = (struct sadb_ext*)pfkey_x_kmprivate;
978         memset(pfkey_x_kmprivate,
979                0,
980                sizeof(struct sadb_x_kmprivate));
981         
982         pfkey_x_kmprivate->sadb_x_kmprivate_len =
983                 sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN;
984
985         pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE;
986         pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
987 errlab:
988         return error;
989 }
990
991 int
992 pfkey_x_satype_build(struct sadb_ext**  pfkey_ext,
993                      uint8_t            satype)
994 {
995         int error = 0;
996         int i;
997         struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext;
998
999         DEBUGGING(
1000                 "pfkey_x_satype_build:\n");
1001         /* sanity checks... */
1002         if(pfkey_x_satype) {
1003                 DEBUGGING(
1004                         "pfkey_x_satype_build: "
1005                         "why is pfkey_x_satype already pointing to something?\n");
1006                 SENDERR(EINVAL);
1007         }
1008         
1009         if(!satype) {
1010                 DEBUGGING(
1011                         "pfkey_x_satype_build: "
1012                         "SA type not set, must be non-zero.\n");
1013                 SENDERR(EINVAL);
1014         }
1015
1016         if(satype > SADB_SATYPE_MAX) {
1017                 DEBUGGING(
1018                         "pfkey_x_satype_build: "
1019                         "satype %d > max %d\n", 
1020                         satype, SADB_SATYPE_MAX);
1021                 SENDERR(EINVAL);
1022         }
1023
1024         pfkey_x_satype = (struct sadb_x_satype*)MALLOC(sizeof(struct sadb_x_satype));
1025         if(!pfkey_x_satype) {
1026                 DEBUGGING(
1027                         "pfkey_x_satype_build: "
1028                         "memory allocation failed\n");
1029                 SENDERR(ENOMEM);
1030         }
1031         *pfkey_ext = (struct sadb_ext*)pfkey_x_satype;
1032         memset(pfkey_x_satype,
1033                0,
1034                sizeof(struct sadb_x_satype));
1035         
1036         pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN;
1037
1038         pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2;
1039         pfkey_x_satype->sadb_x_satype_satype = satype;
1040         for(i=0; i<3; i++) {
1041                 pfkey_x_satype->sadb_x_satype_reserved[i] = 0;
1042         }
1043
1044 errlab:
1045         return error;
1046 }
1047
1048 int
1049 pfkey_x_debug_build(struct sadb_ext**   pfkey_ext,
1050                     uint32_t            tunnel,
1051                     uint32_t            netlink,
1052                     uint32_t            xform,
1053                     uint32_t            eroute,
1054                     uint32_t            spi,
1055                     uint32_t            radij,
1056                     uint32_t            esp,
1057                     uint32_t            ah,
1058                     uint32_t            rcv,
1059                     uint32_t            pfkey,
1060                     uint32_t            ipcomp,
1061                     uint32_t            verbose)
1062 {
1063         int error = 0;
1064         int i;
1065         struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext;
1066
1067         DEBUGGING(
1068                 "pfkey_x_debug_build:\n");
1069         /* sanity checks... */
1070         if(pfkey_x_debug) {
1071                 DEBUGGING(
1072                         "pfkey_x_debug_build: "
1073                         "why is pfkey_x_debug already pointing to something?\n");
1074                 SENDERR(EINVAL);
1075         }
1076         
1077         DEBUGGING(
1078                 "pfkey_x_debug_build: "
1079                 "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",
1080                 tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose);
1081
1082         pfkey_x_debug = (struct sadb_x_debug*)MALLOC(sizeof(struct sadb_x_debug));
1083         if(!pfkey_x_debug) {
1084                 DEBUGGING(
1085                         "pfkey_x_debug_build: "
1086                         "memory allocation failed\n");
1087                 SENDERR(ENOMEM);
1088         }
1089         *pfkey_ext = (struct sadb_ext*)pfkey_x_debug;
1090 #if 0
1091         memset(pfkey_x_debug,
1092                0,
1093                sizeof(struct sadb_x_debug));
1094 #endif
1095         
1096         pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN;
1097         pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG;
1098
1099         pfkey_x_debug->sadb_x_debug_tunnel = tunnel;
1100         pfkey_x_debug->sadb_x_debug_netlink = netlink;
1101         pfkey_x_debug->sadb_x_debug_xform = xform;
1102         pfkey_x_debug->sadb_x_debug_eroute = eroute;
1103         pfkey_x_debug->sadb_x_debug_spi = spi;
1104         pfkey_x_debug->sadb_x_debug_radij = radij;
1105         pfkey_x_debug->sadb_x_debug_esp = esp;
1106         pfkey_x_debug->sadb_x_debug_ah = ah;
1107         pfkey_x_debug->sadb_x_debug_rcv = rcv;
1108         pfkey_x_debug->sadb_x_debug_pfkey = pfkey;
1109         pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp;
1110         pfkey_x_debug->sadb_x_debug_verbose = verbose;
1111
1112         for(i=0; i<4; i++) {
1113                 pfkey_x_debug->sadb_x_debug_reserved[i] = 0;
1114         }
1115
1116 errlab:
1117         return error;
1118 }
1119
1120 #if defined(CONFIG_IPSEC_NAT_TRAVERSAL) || defined(NAT_TRAVERSAL)
1121 int
1122 pfkey_x_nat_t_type_build(struct sadb_ext**      pfkey_ext,
1123                     uint8_t         type)
1124 {
1125         int error = 0;
1126         int i;
1127         struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)*pfkey_ext;
1128
1129         DEBUGGING(
1130                 "pfkey_x_nat_t_type_build:\n");
1131         /* sanity checks... */
1132         if(pfkey_x_nat_t_type) {
1133                 DEBUGGING(
1134                         "pfkey_x_nat_t_type_build: "
1135                         "why is pfkey_x_nat_t_type already pointing to something?\n");
1136                 SENDERR(EINVAL);
1137         }
1138         
1139         DEBUGGING(
1140                 "pfkey_x_nat_t_type_build: "
1141                 "type=%d\n", type);
1142
1143         pfkey_x_nat_t_type = (struct sadb_x_nat_t_type*)MALLOC(sizeof(struct sadb_x_nat_t_type));
1144         if(!pfkey_x_nat_t_type) {
1145                 DEBUGGING(
1146                         "pfkey_x_nat_t_type_build: "
1147                         "memory allocation failed\n");
1148                 SENDERR(ENOMEM);
1149         }
1150         *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_type;
1151         
1152         pfkey_x_nat_t_type->sadb_x_nat_t_type_len = sizeof(struct sadb_x_nat_t_type) / IPSEC_PFKEYv2_ALIGN;
1153         pfkey_x_nat_t_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
1154         pfkey_x_nat_t_type->sadb_x_nat_t_type_type = type;
1155         for(i=0; i<3; i++) {
1156                 pfkey_x_nat_t_type->sadb_x_nat_t_type_reserved[i] = 0;
1157         }
1158
1159 errlab:
1160         return error;
1161 }
1162 int
1163 pfkey_x_nat_t_port_build(struct sadb_ext**      pfkey_ext,
1164                     uint16_t         exttype,
1165                     uint16_t         port)
1166 {
1167         int error = 0;
1168         struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)*pfkey_ext;
1169
1170         DEBUGGING(
1171                 "pfkey_x_nat_t_port_build:\n");
1172         /* sanity checks... */
1173         if(pfkey_x_nat_t_port) {
1174                 DEBUGGING(
1175                         "pfkey_x_nat_t_port_build: "
1176                         "why is pfkey_x_nat_t_port already pointing to something?\n");
1177                 SENDERR(EINVAL);
1178         }
1179         
1180         switch(exttype) {       
1181         case SADB_X_EXT_NAT_T_SPORT:
1182         case SADB_X_EXT_NAT_T_DPORT:
1183                 break;
1184         default:
1185                 DEBUGGING( 
1186                         "pfkey_nat_t_port_build: "
1187                         "unrecognised ext_type=%d.\n", 
1188                         exttype); 
1189                 SENDERR(EINVAL); 
1190         }
1191
1192         DEBUGGING(
1193                 "pfkey_x_nat_t_port_build: "
1194                 "ext=%d, port=%d\n", exttype, port);
1195
1196         pfkey_x_nat_t_port = (struct sadb_x_nat_t_port*)MALLOC(sizeof(struct sadb_x_nat_t_port));
1197         if(!pfkey_x_nat_t_port) {
1198                 DEBUGGING(
1199                         "pfkey_x_nat_t_port_build: "
1200                         "memory allocation failed\n");
1201                 SENDERR(ENOMEM);
1202         }
1203         *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_port;
1204         
1205         pfkey_x_nat_t_port->sadb_x_nat_t_port_len = sizeof(struct sadb_x_nat_t_port) / IPSEC_PFKEYv2_ALIGN;
1206         pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype = exttype;
1207         pfkey_x_nat_t_port->sadb_x_nat_t_port_port = port;
1208         pfkey_x_nat_t_port->sadb_x_nat_t_port_reserved = 0;
1209
1210 errlab:
1211         return error;
1212 }
1213 #endif
1214
1215 #if I_DONT_THINK_THIS_WILL_BE_USEFUL
1216 int (*ext_default_builders[SADB_EXT_MAX +1])(struct sadb_msg*, struct sadb_ext*)
1217  =
1218 {
1219         NULL, /* pfkey_msg_build, */
1220         pfkey_sa_build,
1221         pfkey_lifetime_build,
1222         pfkey_lifetime_build,
1223         pfkey_lifetime_build,
1224         pfkey_address_build,
1225         pfkey_address_build,
1226         pfkey_address_build,
1227         pfkey_key_build,
1228         pfkey_key_build,
1229         pfkey_ident_build,
1230         pfkey_ident_build,
1231         pfkey_sens_build,
1232         pfkey_prop_build,
1233         pfkey_supported_build,
1234         pfkey_supported_build,
1235         pfkey_spirange_build,
1236         pfkey_x_kmprivate_build,
1237         pfkey_x_satype_build,
1238         pfkey_sa_build,
1239         pfkey_address_build,
1240         pfkey_address_build,
1241         pfkey_address_build,
1242         pfkey_address_build,
1243         pfkey_address_build,
1244         pfkey_x_ext_debug_build
1245 };
1246 #endif
1247
1248 int
1249 pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir)
1250 {
1251         int error = 0;
1252         int ext;
1253         int total_size;
1254         struct sadb_ext *pfkey_ext;
1255         int extensions_seen = 0;
1256         struct sadb_ext *extensions_check[SADB_EXT_MAX + 1];
1257         
1258         if(!extensions[0]) {
1259                 DEBUGGING(
1260                         "pfkey_msg_build: "
1261                         "extensions[0] must be specified (struct sadb_msg).\n");
1262                 SENDERR(EINVAL);
1263         }
1264
1265         total_size = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
1266         for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
1267                 if(extensions[ext]) {
1268                         total_size += (extensions[ext])->sadb_ext_len;
1269                 }
1270         }                
1271
1272         if(!(*pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN))) {
1273                 DEBUGGING(
1274                         "pfkey_msg_build: "
1275                         "memory allocation failed\n");
1276                 SENDERR(ENOMEM);
1277         }
1278
1279         DEBUGGING(
1280                 "pfkey_msg_build: "
1281                 "pfkey_msg=%p allocated %ld bytes, &(extensions[0])=%p\n",
1282                 *pfkey_msg,
1283                 total_size * IPSEC_PFKEYv2_ALIGN,
1284                 &(extensions[0]));
1285         memcpy(*pfkey_msg,
1286                extensions[0],
1287                sizeof(struct sadb_msg));
1288         (*pfkey_msg)->sadb_msg_len = total_size;
1289         (*pfkey_msg)->sadb_msg_reserved = 0;
1290         extensions_seen =  1 ;
1291
1292         pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg));
1293
1294         for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
1295                 /* copy from extension[ext] to buffer */
1296                 if(extensions[ext]) {    
1297                         /* Is this type of extension permitted for this type of message? */
1298                         if(!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] &
1299                              1<<ext)) {
1300                                 DEBUGGING(
1301                                         "pfkey_msg_build: "
1302                                         "ext type %d not permitted, exts_perm=%08x, 1<<type=%08x\n", 
1303                                         ext, 
1304                                         extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
1305                                         1<<ext);
1306                                 SENDERR(EINVAL);
1307                         }
1308                         DEBUGGING(
1309                                 "pfkey_msg_build: "
1310                                 "copying %ld bytes from extensions[%d]=%p to=%p\n",
1311                                 (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN,
1312                                 ext,
1313                                 (extensions[ext]),
1314                                 pfkey_ext);
1315                         memcpy(pfkey_ext,
1316                                extensions[ext],
1317                                (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
1318                         pfkey_ext = (char *)pfkey_ext + (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN;
1319                         /* Mark that we have seen this extension and remember the header location */
1320                         extensions_seen |= ( 1 << ext );
1321                 }
1322         }
1323
1324         /* check required extensions */
1325         DEBUGGING(
1326                 "pfkey_msg_build: "
1327                 "extensions permitted=%08x, seen=%08x, required=%08x.\n",
1328                 extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
1329                 extensions_seen,
1330                 extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]);
1331         
1332         if((extensions_seen &
1333             extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) !=
1334            extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) {
1335                 DEBUGGING(
1336                         "pfkey_msg_build: "
1337                         "required extensions missing:%08x.\n",
1338                         extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] -
1339                         (extensions_seen &
1340                          extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) );
1341                 SENDERR(EINVAL);
1342         }
1343         
1344         if((error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir))) {
1345                 DEBUGGING(
1346                         "pfkey_msg_build: "
1347                         "Trouble parsing newly built pfkey message, error=%d.\n",
1348                         error);
1349                 SENDERR(-error);
1350         }
1351
1352 errlab:
1353
1354         return error;
1355 }
1356
1357 /*
1358  * $Log: pfkey_v2_build.c,v $
1359  * Revision 1.31  2002/01/29 22:25:35  rgb
1360  * Re-add ipsec_kversion.h to keep MALLOC happy.
1361  *
1362  * Revision 1.30  2002/01/29 01:59:09  mcr
1363  *      removal of kversions.h - sources that needed it now use ipsec_param.h.
1364  *      updating of IPv6 structures to match latest in6.h version.
1365  *      removed dead code from freeswan.h that also duplicated kversions.h
1366  *      code.
1367  *
1368  * Revision 1.29  2001/12/19 21:06:09  rgb
1369  * Added port numbers to pfkey_address_build() debugging.
1370  *
1371  * Revision 1.28  2001/11/06 19:47:47  rgb
1372  * Added packet parameter to lifetime and comb structures.
1373  *
1374  * Revision 1.27  2001/10/18 04:45:24  rgb
1375  * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
1376  * lib/freeswan.h version macros moved to lib/kversions.h.
1377  * Other compiler directive cleanups.
1378  *
1379  * Revision 1.26  2001/09/08 21:13:34  rgb
1380  * Added pfkey ident extension support for ISAKMPd. (NetCelo)
1381  *
1382  * Revision 1.25  2001/06/14 19:35:16  rgb
1383  * Update copyright date.
1384  *
1385  * Revision 1.24  2001/03/20 03:49:45  rgb
1386  * Ditch superfluous debug_pfkey declaration.
1387  * Move misplaced freeswan.h inclusion for kernel case.
1388  *
1389  * Revision 1.23  2001/03/16 07:41:50  rgb
1390  * Put freeswan.h include before pluto includes.
1391  *
1392  * Revision 1.22  2001/02/27 22:24:56  rgb
1393  * Re-formatting debug output (line-splitting, joining, 1arg/line).
1394  * Check for satoa() return codes.
1395  *
1396  * Revision 1.21  2000/11/17 18:10:30  rgb
1397  * Fixed bugs mostly relating to spirange, to treat all spi variables as
1398  * network byte order since this is the way PF_KEYv2 stored spis.
1399  *
1400  * Revision 1.20  2000/10/12 00:02:39  rgb
1401  * Removed 'format, ##' nonsense from debug macros for RH7.0.
1402  *
1403  * Revision 1.19  2000/10/10 20:10:20  rgb
1404  * Added support for debug_ipcomp and debug_verbose to klipsdebug.
1405  *
1406  * Revision 1.18  2000/09/12 18:59:54  rgb
1407  * Added Gerhard's IPv6 support to pfkey parts of libfreeswan.
1408  *
1409  * Revision 1.17  2000/09/12 03:27:00  rgb
1410  * Moved DEBUGGING definition to compile kernel with debug off.
1411  *
1412  * Revision 1.16  2000/09/08 19:22:12  rgb
1413  * Fixed pfkey_prop_build() parameter to be only single indirection.
1414  * Fixed struct alg copy.
1415  *
1416  * Revision 1.15  2000/08/20 21:40:01  rgb
1417  * Added an address parameter sanity check to pfkey_address_build().
1418  *
1419  * Revision 1.14  2000/08/15 17:29:23  rgb
1420  * Fixes from SZI to untested pfkey_prop_build().
1421  *
1422  * Revision 1.13  2000/06/02 22:54:14  rgb
1423  * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
1424  *
1425  * Revision 1.12  2000/05/10 19:24:01  rgb
1426  * Fleshed out sensitivity, proposal and supported extensions.
1427  *
1428  * Revision 1.11  2000/03/16 14:07:23  rgb
1429  * Renamed ALIGN macro to avoid fighting with others in kernel.
1430  *
1431  * Revision 1.10  2000/01/24 21:14:35  rgb
1432  * Added disabled pluto pfkey lib debug flag.
1433  *
1434  * Revision 1.9  2000/01/21 06:27:32  rgb
1435  * Added address cases for eroute flows.
1436  * Removed unused code.
1437  * Dropped unused argument to pfkey_x_satype_build().
1438  * Indented compiler directives for readability.
1439  * Added klipsdebug switching capability.
1440  * Fixed SADB_EXT_MAX bug not permitting last extension access.
1441  *
1442  * Revision 1.8  1999/12/29 21:17:41  rgb
1443  * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
1444  * parameter for cleaner manipulation of extensions[] and to guard
1445  * against potential memory leaks.
1446  * Changed the I/F to pfkey_msg_free() for the same reason.
1447  *
1448  * Revision 1.7  1999/12/09 23:12:20  rgb
1449  * Removed unused cruft.
1450  * Added argument to pfkey_sa_build() to do eroutes.
1451  * Fixed exttype check in as yet unused pfkey_lifetime_build().
1452  *
1453  * Revision 1.6  1999/12/07 19:54:29  rgb
1454  * Removed static pluto debug flag.
1455  * Added functions for pfkey message and extensions initialisation
1456  * and cleanup.
1457  *
1458  * Revision 1.5  1999/12/01 22:20:06  rgb
1459  * Changed pfkey_sa_build to accept an SPI in network byte order.
1460  * Added <string.h> to quiet userspace compiler.
1461  * Moved pfkey_lib_debug variable into the library.
1462  * Removed SATYPE check from pfkey_msg_hdr_build so FLUSH will work.
1463  * Added extension assembly debugging.
1464  * Isolated assignment with brackets to be sure of scope.
1465  *
1466  * Revision 1.4  1999/11/27 11:57:35  rgb
1467  * Added ipv6 headers.
1468  * Remove over-zealous algorithm sanity checkers from pfkey_sa_build.
1469  * Debugging error messages added.
1470  * Fixed missing auth and encrypt assignment bug.
1471  * Add argument to pfkey_msg_parse() for direction.
1472  * Move parse-after-build check inside pfkey_msg_build().
1473  * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
1474  * Add CVS log entry to bottom of file.
1475  *
1476  */