OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / klips / net / ipsec / pfkey_v2_parser.c
1 /*
2  * @(#) RFC2367 PF_KEYv2 Key management API message parser
3  * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs <rgb@freeswan.org>
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_parser.c,v 1.102 2002/03/08 01:15:17 mcr Exp $
16  */
17
18 /*
19  *              Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
20  */
21
22 char pfkey_v2_parser_c_version[] = "$Id: pfkey_v2_parser.c,v 1.102 2002/03/08 01:15:17 mcr Exp $";
23
24 #include <linux/config.h>
25 #include <linux/version.h>
26 #include <linux/kernel.h> /* printk() */
27
28 #define IPSEC_KLIPS1_COMPAT
29 #include "ipsec_param.h"
30
31 #ifdef MALLOC_SLAB
32 # include <linux/slab.h> /* kmalloc() */
33 #else /* MALLOC_SLAB */
34 # include <linux/malloc.h> /* kmalloc() */
35 #endif /* MALLOC_SLAB */
36 #include <linux/errno.h>  /* error codes */
37 #include <linux/types.h>  /* size_t */
38 #include <linux/interrupt.h> /* mark_bh */
39
40 #include <linux/netdevice.h>   /* struct device, and other headers */
41 #include <linux/etherdevice.h> /* eth_type_trans */
42 #include <linux/ip.h>          /* struct iphdr */
43 #include <linux/skbuff.h>
44 #include <freeswan.h>
45 #include <des.h>
46 #ifdef SPINLOCK
47 # ifdef SPINLOCK_23
48 #  include <linux/spinlock.h> /* *lock* */
49 # else /* SPINLOCK_23 */
50 #  include <asm/spinlock.h> /* *lock* */
51 # endif /* SPINLOCK_23 */
52 #endif /* SPINLOCK */
53 #ifdef NET_21
54 # include <asm/uaccess.h>
55 # include <linux/in6.h>
56 # define ip_chk_addr inet_addr_type
57 # define IS_MYADDR RTN_LOCAL
58 #ifndef USE_IXP4XX_CRYPTO
59 # undef dev_kfree_skb
60 # define dev_kfree_skb(a,b) kfree_skb(a)
61 #endif /* USE_IXP4XX_CRYPTO */
62 #endif
63 #include <asm/checksum.h>
64 #include <net/ip.h>
65 #ifdef NETLINK_SOCK
66 # include <linux/netlink.h>
67 #else
68 # include <net/netlink.h>
69 #endif
70
71 #include <linux/random.h>       /* get_random_bytes() */
72
73 #include "radij.h"
74 #include "ipsec_encap.h"
75 #include "ipsec_sa.h"
76
77 #include "ipsec_radij.h"
78 #include "ipsec_netlink.h"
79 #include "ipsec_xform.h"
80 #include "ipsec_ah.h"
81 #include "ipsec_esp.h"
82 #include "ipsec_tunnel.h"       /* ..., ipsec_tunnel_start_xmit() */
83 #include "ipsec_rcv.h"
84 #include "ipcomp.h"
85
86 #include <pfkeyv2.h>
87 #include <pfkey.h>
88
89 #include "ipsec_proto.h"
90
91 #include "ipsec_alg.h"
92
93 #ifdef USE_IXP4XX_CRYPTO
94 #include "ipsec_glue.h"
95 #endif
96 #define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
97
98 struct sklist_t {
99         struct socket *sk;
100         struct sklist_t* next;
101 } pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev;
102
103 __u32 pfkey_msg_seq = 0;
104
105 DEBUG_NO_STATIC int
106 pfkey_alloc_ipsec_sa(struct ipsec_sa** tdb)
107 {
108         int error = 0;
109         if(*tdb) {
110                 KLIPS_PRINT(debug_pfkey,
111                             "klips_debug:pfkey_alloc_ipsec_sa: "
112                             "tdb struct already allocated\n");
113                 SENDERR(EEXIST);
114         }
115
116         if((*tdb = kmalloc(sizeof(**tdb), GFP_ATOMIC) ) == NULL) {
117                 KLIPS_PRINT(debug_pfkey,
118                             "klips_debug:pfkey_alloc_ipsec_sa: "
119                             "memory allocation error\n");
120                 SENDERR(ENOMEM);
121         }
122         KLIPS_PRINT(debug_pfkey,
123                     "klips_debug:pfkey_alloc_ipsec_sa: "
124                     "allocated tdb struct=%p.\n", tdb);
125
126         memset((caddr_t)*tdb, 0, sizeof(**tdb));
127  errlab:
128         return(error);
129 }
130
131 DEBUG_NO_STATIC int
132 pfkey_alloc_eroute(struct eroute** eroute)
133 {
134         int error = 0;
135         if(*eroute) {
136                 KLIPS_PRINT(debug_pfkey,
137                             "klips_debug:pfkey_alloc_eroute: "
138                             "eroute struct already allocated\n");
139                 SENDERR(EEXIST);
140         }
141
142         if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) {
143                 KLIPS_PRINT(debug_pfkey,
144                             "klips_debug:pfkey_alloc_eroute: "
145                             "memory allocation error\n");
146                 SENDERR(ENOMEM);
147         }
148         KLIPS_PRINT(debug_pfkey,
149                     "klips_debug:pfkey_alloc_eroute: "
150                     "allocated eroute struct=%p.\n", eroute);
151         memset((caddr_t)*eroute, 0, sizeof(**eroute));
152         (*eroute)->er_eaddr.sen_len =
153                 (*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap);
154         (*eroute)->er_eaddr.sen_family =
155                 (*eroute)->er_emask.sen_family = AF_ENCAP;
156         (*eroute)->er_eaddr.sen_type = SENT_IP4;
157         (*eroute)->er_emask.sen_type = 255;
158         (*eroute)->er_pid = 0;
159         (*eroute)->er_count = 0;
160         (*eroute)->er_lasttime = jiffies/HZ;
161
162  errlab:
163         return(error);
164 }
165
166 DEBUG_NO_STATIC int
167 pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
168 {
169         struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
170         int error = 0;
171         struct ipsec_sa* tdbp;
172         
173         KLIPS_PRINT(debug_pfkey,
174                     "klips_debug:pfkey_sa_process: .\n");
175
176         if(!extr || !extr->tdb) {
177                 KLIPS_PRINT(debug_pfkey,
178                             "klips_debug:pfkey_sa_process: "
179                             "extr or extr->tdb is NULL, fatal\n");
180                 SENDERR(EINVAL);
181         }
182
183         switch(pfkey_ext->sadb_ext_type) {
184         case SADB_EXT_SA:
185                 tdbp = extr->tdb;
186                 break;
187         case SADB_X_EXT_SA2:
188                 if(pfkey_alloc_ipsec_sa(&(extr->tdb2)) == ENOMEM) {
189                         SENDERR(ENOMEM);
190                 }
191                 tdbp = extr->tdb2;
192                 break;
193         default:
194                 KLIPS_PRINT(debug_pfkey,
195                             "klips_debug:pfkey_sa_process: "
196                             "invalid exttype=%d.\n",
197                             pfkey_ext->sadb_ext_type);
198                 SENDERR(EINVAL);
199         }
200
201         tdbp->tdb_said.spi = pfkey_sa->sadb_sa_spi;
202         tdbp->tdb_replaywin = pfkey_sa->sadb_sa_replay;
203         tdbp->tdb_state = pfkey_sa->sadb_sa_state;
204         tdbp->tdb_flags = pfkey_sa->sadb_sa_flags;
205         tdbp->tdb_replaywin_lastseq = tdbp->tdb_replaywin_bitmap = 0;
206         
207         switch(tdbp->tdb_said.proto) {
208         case IPPROTO_AH:
209                 tdbp->tdb_authalg = pfkey_sa->sadb_sa_auth;
210                 tdbp->tdb_encalg = SADB_EALG_NONE;
211                 break;
212         case IPPROTO_ESP:
213                 tdbp->tdb_authalg = pfkey_sa->sadb_sa_auth;
214                 tdbp->tdb_encalg = pfkey_sa->sadb_sa_encrypt;
215 #ifdef CONFIG_IPSEC_ALG
216                 ipsec_alg_sa_init(tdbp);
217 #endif /* CONFIG_IPSEC_ALG */
218                 break;
219         case IPPROTO_IPIP:
220                 tdbp->tdb_authalg = AH_NONE;
221                 tdbp->tdb_encalg = ESP_NONE;
222                 break;
223 #ifdef CONFIG_IPSEC_IPCOMP
224         case IPPROTO_COMP:
225                 tdbp->tdb_authalg = AH_NONE;
226                 tdbp->tdb_encalg = pfkey_sa->sadb_sa_encrypt;
227                 break;
228 #endif /* CONFIG_IPSEC_IPCOMP */
229         case IPPROTO_INT:
230                 tdbp->tdb_authalg = AH_NONE;
231                 tdbp->tdb_encalg = ESP_NONE;
232                 break;
233         case 0:
234                 break;
235         default:
236                 KLIPS_PRINT(debug_pfkey,
237                             "klips_debug:pfkey_sa_process: "
238                             "unknown proto=%d.\n",
239                             tdbp->tdb_said.proto);
240                 SENDERR(EINVAL);
241         }
242
243 errlab:
244         return error;
245 }
246
247 DEBUG_NO_STATIC int
248 pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
249 {
250         int error = 0;
251         struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
252
253         KLIPS_PRINT(debug_pfkey,
254                     "klips_debug:pfkey_lifetime_process: .\n");
255
256         if(!extr || !extr->tdb) {
257                 KLIPS_PRINT(debug_pfkey,
258                             "klips_debug:pfkey_lifetime_process: "
259                             "extr or extr->tdb is NULL, fatal\n");
260                 SENDERR(EINVAL);
261         }
262
263         switch(pfkey_lifetime->sadb_lifetime_exttype) {
264         case SADB_EXT_LIFETIME_CURRENT:
265                 KLIPS_PRINT(debug_pfkey,
266                             "klips_debug:pfkey_lifetime_process: "
267                             "lifetime_current not supported yet.\n");
268                 SENDERR(EINVAL);
269                 break;
270         case SADB_EXT_LIFETIME_HARD:
271                 ipsec_lifetime_update_hard(&extr->tdb->ips_life.ipl_allocations,
272                                           pfkey_lifetime->sadb_lifetime_allocations);
273
274                 ipsec_lifetime_update_hard(&extr->tdb->ips_life.ipl_bytes,
275                                           pfkey_lifetime->sadb_lifetime_bytes);
276
277                 ipsec_lifetime_update_hard(&extr->tdb->ips_life.ipl_addtime,
278                                           pfkey_lifetime->sadb_lifetime_addtime);
279
280                 ipsec_lifetime_update_hard(&extr->tdb->ips_life.ipl_usetime,
281                                           pfkey_lifetime->sadb_lifetime_usetime);
282
283                 break;
284
285         case SADB_EXT_LIFETIME_SOFT:
286                 ipsec_lifetime_update_soft(&extr->tdb->ips_life.ipl_allocations,
287                                            pfkey_lifetime->sadb_lifetime_allocations);
288
289                 ipsec_lifetime_update_soft(&extr->tdb->ips_life.ipl_bytes,
290                                            pfkey_lifetime->sadb_lifetime_bytes);
291
292                 ipsec_lifetime_update_soft(&extr->tdb->ips_life.ipl_addtime,
293                                            pfkey_lifetime->sadb_lifetime_addtime);
294
295                 ipsec_lifetime_update_soft(&extr->tdb->ips_life.ipl_usetime,
296                                            pfkey_lifetime->sadb_lifetime_usetime);
297
298                 break;
299         default:
300                 KLIPS_PRINT(debug_pfkey,
301                             "klips_debug:pfkey_lifetime_process: "
302                             "invalid exttype=%d.\n",
303                             pfkey_ext->sadb_ext_type);
304                 SENDERR(EINVAL);
305         }
306
307 errlab:
308         return error;
309 }
310
311 DEBUG_NO_STATIC int
312 pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
313 {
314         int error = 0;
315         int saddr_len = 0;
316         char ipaddr_txt[ADDRTOA_BUF];
317         unsigned char **sap;
318         struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
319         struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
320         struct ipsec_sa* tdbp;
321         
322         KLIPS_PRINT(debug_pfkey,
323                     "klips_debug:pfkey_address_process:\n");
324         
325         if(!extr || !extr->tdb) {
326                 KLIPS_PRINT(debug_pfkey,
327                             "klips_debug:pfkey_address_process: "
328                             "extr or extr->tdb is NULL, fatal\n");
329                 SENDERR(EINVAL);
330         }
331
332         switch(s->sa_family) {
333         case AF_INET:
334                 saddr_len = sizeof(struct sockaddr_in);
335                 addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt));
336                 KLIPS_PRINT(debug_pfkey,
337                             "klips_debug:pfkey_address_process: "
338                             "found address family=%d, AF_INET, %s.\n",
339                             s->sa_family,
340                             ipaddr_txt);
341                 break;
342 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
343         case AF_INET6:
344                 saddr_len = sizeof(struct sockaddr_in6);
345                 break;
346 #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
347         default:
348                 KLIPS_PRINT(debug_pfkey,
349                             "klips_debug:pfkey_address_process: "
350                             "s->sa_family=%d not supported.\n",
351                             s->sa_family);
352                 SENDERR(EPFNOSUPPORT);
353         }
354         
355         switch(pfkey_address->sadb_address_exttype) {
356         case SADB_EXT_ADDRESS_SRC:
357                 KLIPS_PRINT(debug_pfkey,
358                             "klips_debug:pfkey_address_process: "
359                             "found src address.\n");
360                 sap = (unsigned char **)&(extr->tdb->tdb_addr_s);
361                 extr->tdb->tdb_addr_s_size = saddr_len;
362                 break;
363         case SADB_EXT_ADDRESS_DST:
364                 KLIPS_PRINT(debug_pfkey,
365                             "klips_debug:pfkey_address_process: "
366                             "found dst address.\n");
367                 sap = (unsigned char **)&(extr->tdb->tdb_addr_d);
368                 extr->tdb->tdb_addr_d_size = saddr_len;
369                 break;
370         case SADB_EXT_ADDRESS_PROXY:
371                 KLIPS_PRINT(debug_pfkey,
372                             "klips_debug:pfkey_address_process: "
373                             "found proxy address.\n");
374                 sap = (unsigned char **)&(extr->tdb->tdb_addr_p);
375                 extr->tdb->tdb_addr_p_size = saddr_len;
376                 break;
377         case SADB_X_EXT_ADDRESS_DST2:
378                 KLIPS_PRINT(debug_pfkey,
379                             "klips_debug:pfkey_address_process: "
380                             "found 2nd dst address.\n");
381                 if(pfkey_alloc_ipsec_sa(&(extr->tdb2)) == ENOMEM) {
382                         SENDERR(ENOMEM);
383                 }
384                 sap = (unsigned char **)&(extr->tdb2->tdb_addr_d);
385                 extr->tdb2->tdb_addr_d_size = saddr_len;
386                 break;
387         case SADB_X_EXT_ADDRESS_SRC_FLOW:
388                 KLIPS_PRINT(debug_pfkey,
389                             "klips_debug:pfkey_address_process: "
390                             "found src flow address.\n");
391                 if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
392                         SENDERR(ENOMEM);
393                 }
394                 sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src);
395                 break;
396         case SADB_X_EXT_ADDRESS_DST_FLOW:
397                 KLIPS_PRINT(debug_pfkey,
398                             "klips_debug:pfkey_address_process: "
399                             "found dst flow address.\n");
400                 if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
401                         SENDERR(ENOMEM);
402                 }
403                 sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst);
404                 break;
405         case SADB_X_EXT_ADDRESS_SRC_MASK:
406                 KLIPS_PRINT(debug_pfkey,
407                             "klips_debug:pfkey_address_process: "
408                             "found src mask address.\n");
409                 if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
410                         SENDERR(ENOMEM);
411                 }
412                 sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src);
413                 break;
414         case SADB_X_EXT_ADDRESS_DST_MASK:
415                 KLIPS_PRINT(debug_pfkey,
416                             "klips_debug:pfkey_address_process: "
417                             "found dst mask address.\n");
418                 if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
419                         SENDERR(ENOMEM);
420                 }
421                 sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst);
422                 break;
423 #ifdef CONFIG_IPSEC_NAT_TRAVERSAL
424         case SADB_X_EXT_NAT_T_OA:
425                 KLIPS_PRINT(debug_pfkey,
426                             "klips_debug:pfkey_address_process: "
427                             "found NAT-OA address.\n");
428                 sap = (unsigned char **)&(extr->tdb->ips_natt_oa);
429                 extr->tdb->ips_natt_oa_size = saddr_len;
430                 break;
431 #endif
432         default:
433                 KLIPS_PRINT(debug_pfkey,
434                             "klips_debug:pfkey_address_process: "
435                             "unrecognised ext_type=%d.\n",
436                             pfkey_address->sadb_address_exttype);
437                 SENDERR(EINVAL);
438         }
439         
440         switch(pfkey_address->sadb_address_exttype) {
441         case SADB_EXT_ADDRESS_SRC:
442         case SADB_EXT_ADDRESS_DST:
443         case SADB_EXT_ADDRESS_PROXY:
444         case SADB_X_EXT_ADDRESS_DST2:
445 #ifdef CONFIG_IPSEC_NAT_TRAVERSAL
446         case SADB_X_EXT_NAT_T_OA:
447 #endif
448                 if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) {
449                         SENDERR(ENOMEM);
450                 }
451                 memcpy(*sap, s, saddr_len);
452                 break;
453         default:
454                 if(s->sa_family != AF_INET) {
455                         KLIPS_PRINT(debug_pfkey,
456                                     "klips_debug:pfkey_address_process: "
457                                     "s->sa_family=%d not supported.\n",
458                                     s->sa_family);
459                         SENDERR(EPFNOSUPPORT);
460                 }
461                 *(struct in_addr *)sap = ((struct sockaddr_in *)s)->sin_addr;
462 #ifdef CONFIG_IPSEC_DEBUG
463                 if(extr->eroute) {
464                         char buf1[64], buf2[64];
465                         if (debug_pfkey) {
466                                 subnettoa(extr->eroute->er_eaddr.sen_ip_src,
467                                           extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
468                                 subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
469                                           extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
470                                 KLIPS_PRINT(debug_pfkey,
471                                             "klips_debug:pfkey_address_parse: "
472                                             "extr->eroute set to %s->%s\n",
473                                             buf1, buf2);
474                         }
475                 }
476 #endif /* CONFIG_IPSEC_DEBUG */
477         }
478
479         tdbp = extr->tdb;
480         switch(pfkey_address->sadb_address_exttype) {
481         case SADB_X_EXT_ADDRESS_DST2:
482                 tdbp = extr->tdb2;
483         case SADB_EXT_ADDRESS_DST:
484                 if(s->sa_family == AF_INET) {
485                         tdbp->tdb_said.dst.s_addr = ((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr.s_addr;
486                         addrtoa(((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr,
487                                 0,
488                                 ipaddr_txt,
489                                 sizeof(ipaddr_txt));
490                         KLIPS_PRINT(debug_pfkey,
491                                     "klips_debug:pfkey_address_process: "
492                                     "tdb_said.dst set to %s.\n",
493                                     ipaddr_txt);
494                 } else {
495                         KLIPS_PRINT(debug_pfkey,
496                                     "klips_debug:pfkey_address_process: "
497                                     "uh, tdb_said.dst doesn't do address family=%d yet, said will be invalid.\n",
498                                     s->sa_family);
499                 }
500         default:
501                 break;
502         }
503         
504         /* XXX check if port!=0 */
505         
506         KLIPS_PRINT(debug_pfkey,
507                     "klips_debug:pfkey_address_process: successful.\n");
508  errlab:
509         return error;
510 }
511
512 DEBUG_NO_STATIC int
513 pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
514 {
515         int error = 0;
516         struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
517         
518         KLIPS_PRINT(debug_pfkey,
519                     "klips_debug:pfkey_key_process: .\n");
520
521         if(!extr || !extr->tdb) {
522                 KLIPS_PRINT(debug_pfkey,
523                             "klips_debug:pfkey_key_process: "
524                             "extr or extr->tdb is NULL, fatal\n");
525                 SENDERR(EINVAL);
526         }
527
528         switch(pfkey_key->sadb_key_exttype) {
529         case SADB_EXT_KEY_AUTH:
530                 if(!(extr->tdb->tdb_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
531                         KLIPS_PRINT(debug_pfkey,
532                                     "klips_debug:pfkey_key_process: "
533                                     "memory allocation error.\n");
534                         SENDERR(ENOMEM);
535                 }
536                 extr->tdb->tdb_key_bits_a = pfkey_key->sadb_key_bits;
537                 extr->tdb->tdb_key_a_size = DIVUP(pfkey_key->sadb_key_bits, 8);
538                 memcpy(extr->tdb->tdb_key_a,
539                        (char*)pfkey_key + sizeof(struct sadb_key),
540                        extr->tdb->tdb_key_a_size);
541                 break;
542         case SADB_EXT_KEY_ENCRYPT: /* Key(s) */
543                 if(!(extr->tdb->tdb_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
544                         KLIPS_PRINT(debug_pfkey,
545                                     "klips_debug:pfkey_key_process: "
546                                     "memory allocation error.\n");
547                         SENDERR(ENOMEM);
548                 }
549                 extr->tdb->tdb_key_bits_e = pfkey_key->sadb_key_bits;
550                 extr->tdb->tdb_key_e_size = DIVUP(pfkey_key->sadb_key_bits, 8);
551                 memcpy(extr->tdb->tdb_key_e,
552                        (char*)pfkey_key + sizeof(struct sadb_key),
553                        extr->tdb->tdb_key_e_size);
554                 break;
555         default:
556                 SENDERR(EINVAL);
557         }
558
559         KLIPS_PRINT(debug_pfkey,
560                     "klips_debug:pfkey_key_process: "
561                     "success.\n");
562 errlab:
563         return error;
564 }
565
566 DEBUG_NO_STATIC int
567 pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
568 {
569         int error = 0;
570         struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
571         int data_len;
572
573         KLIPS_PRINT(debug_pfkey,
574                     "klips_debug:pfkey_ident_process: .\n");
575
576         if(!extr || !extr->tdb) {
577                 KLIPS_PRINT(debug_pfkey,
578                             "klips_debug:pfkey_ident_process: "
579                             "extr or extr->tdb is NULL, fatal\n");
580                 SENDERR(EINVAL);
581         }
582
583         switch(pfkey_ident->sadb_ident_exttype) {
584         case SADB_EXT_IDENTITY_SRC:
585                 data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
586                 
587                 extr->tdb->tdb_ident_s.type = pfkey_ident->sadb_ident_type;
588                 extr->tdb->tdb_ident_s.id = pfkey_ident->sadb_ident_id;
589                 extr->tdb->tdb_ident_s.len = pfkey_ident->sadb_ident_len;
590                 if(data_len) {
591                         if(!(extr->tdb->tdb_ident_s.data
592                              = kmalloc(data_len, GFP_KERNEL))) {
593                                 SENDERR(ENOMEM);
594                         }
595                         memcpy(extr->tdb->tdb_ident_s.data,
596                                (char*)pfkey_ident + sizeof(struct sadb_ident),
597                                data_len);
598                 } else {
599                         extr->tdb->tdb_ident_s.data = NULL;
600                 }
601                 break;
602         case SADB_EXT_IDENTITY_DST: /* Identity(ies) */
603                 data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
604                 
605                 extr->tdb->tdb_ident_d.type = pfkey_ident->sadb_ident_type;
606                 extr->tdb->tdb_ident_d.id = pfkey_ident->sadb_ident_id;
607                 extr->tdb->tdb_ident_d.len = pfkey_ident->sadb_ident_len;
608                 if(data_len) {
609                         if(!(extr->tdb->tdb_ident_d.data
610                              = kmalloc(data_len, GFP_KERNEL))) {
611                                 SENDERR(ENOMEM);
612                         }
613                         memcpy(extr->tdb->tdb_ident_d.data,
614                                (char*)pfkey_ident + sizeof(struct sadb_ident),
615                                data_len);
616                 } else {
617                         extr->tdb->tdb_ident_d.data = NULL;
618                 }
619                 break;
620         default:
621                 SENDERR(EINVAL);
622         }
623 errlab:
624         return error;
625 }
626
627 DEBUG_NO_STATIC int
628 pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
629 {
630         int error = 0;
631         
632         KLIPS_PRINT(debug_pfkey,
633                     "klips_debug:pfkey_sens_process: "
634                     "Sorry, I can't process exttype=%d yet.\n",
635                     pfkey_ext->sadb_ext_type);
636         SENDERR(EINVAL); /* don't process these yet */
637  errlab:
638         return error;
639 }
640
641 DEBUG_NO_STATIC int
642 pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
643 {
644         int error = 0;
645         
646         KLIPS_PRINT(debug_pfkey,
647                     "klips_debug:pfkey_prop_process: "
648                     "Sorry, I can't process exttype=%d yet.\n",
649                     pfkey_ext->sadb_ext_type);
650         SENDERR(EINVAL); /* don't process these yet */
651         
652  errlab:
653         return error;
654 }
655
656 DEBUG_NO_STATIC int
657 pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
658 {
659         int error = 0;
660
661         KLIPS_PRINT(debug_pfkey,
662                     "klips_debug:pfkey_supported_process: "
663                     "Sorry, I can't process exttype=%d yet.\n",
664                     pfkey_ext->sadb_ext_type);
665         SENDERR(EINVAL); /* don't process these yet */
666
667 errlab:
668         return error;
669 }
670
671 DEBUG_NO_STATIC int
672 pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
673 {
674         int error = 0;
675
676         KLIPS_PRINT(debug_pfkey,
677                     "klips_debug:pfkey_spirange_process: .\n");
678 /* errlab: */
679         return error;
680 }
681
682 DEBUG_NO_STATIC int
683 pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
684 {
685         int error = 0;
686
687         KLIPS_PRINT(debug_pfkey,
688                     "klips_debug:pfkey_x_kmprivate_process: "
689                     "Sorry, I can't process exttype=%d yet.\n",
690                     pfkey_ext->sadb_ext_type);
691         SENDERR(EINVAL); /* don't process these yet */
692
693 errlab:
694         return error;
695 }
696
697 DEBUG_NO_STATIC int
698 pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
699 {
700         int error = 0;
701         struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
702
703         KLIPS_PRINT(debug_pfkey,
704                     "klips_debug:pfkey_x_satype_process: .\n");
705
706         if(!extr || !extr->tdb) {
707                 KLIPS_PRINT(debug_pfkey,
708                             "klips_debug:pfkey_x_satype_process: "
709                             "extr or extr->tdb is NULL, fatal\n");
710                 SENDERR(EINVAL);
711         }
712
713         if(pfkey_alloc_ipsec_sa(&(extr->tdb2)) == ENOMEM) {
714                 SENDERR(ENOMEM);
715         }
716         if(!(extr->tdb2->tdb_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
717                 KLIPS_PRINT(debug_pfkey,
718                             "klips_debug:pfkey_x_satype_process: "
719                             "proto lookup from satype=%d failed.\n",
720                             pfkey_x_satype->sadb_x_satype_satype);
721                 SENDERR(EINVAL);
722         }
723         KLIPS_PRINT(debug_pfkey,
724                     "klips_debug:pfkey_x_satype_process: "
725                     "protocol==%d decoded from satype==%d(%s).\n",
726                     extr->tdb2->tdb_said.proto,
727                     pfkey_x_satype->sadb_x_satype_satype,
728                     satype2name(pfkey_x_satype->sadb_x_satype_satype));
729
730 errlab:
731         return error;
732 }
733
734 DEBUG_NO_STATIC int
735 pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
736 {
737         int error = 0;
738         struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
739
740         if(!pfkey_x_debug) {
741                 printk("klips_debug:pfkey_x_debug_process: "
742                        "null pointer passed in\n");
743                 SENDERR(EINVAL);
744         }
745
746         KLIPS_PRINT(debug_pfkey,
747                     "klips_debug:pfkey_x_debug_process: .\n");
748
749 #ifdef CONFIG_IPSEC_DEBUG
750                 if(pfkey_x_debug->sadb_x_debug_netlink >>
751                    (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) {
752                         pfkey_x_debug->sadb_x_debug_netlink &=
753                                 ~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1));
754                         debug_tunnel  |= pfkey_x_debug->sadb_x_debug_tunnel;
755                         debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink;
756                         debug_xform   |= pfkey_x_debug->sadb_x_debug_xform;
757                         debug_eroute  |= pfkey_x_debug->sadb_x_debug_eroute;
758                         debug_spi     |= pfkey_x_debug->sadb_x_debug_spi;
759                         debug_radij   |= pfkey_x_debug->sadb_x_debug_radij;
760                         debug_esp     |= pfkey_x_debug->sadb_x_debug_esp;
761                         debug_ah      |= pfkey_x_debug->sadb_x_debug_ah;
762                         debug_rcv     |= pfkey_x_debug->sadb_x_debug_rcv;
763                         debug_pfkey   |= pfkey_x_debug->sadb_x_debug_pfkey;
764 #ifdef CONFIG_IPSEC_IPCOMP
765                         sysctl_ipsec_debug_ipcomp  |= pfkey_x_debug->sadb_x_debug_ipcomp;
766 #endif /* CONFIG_IPSEC_IPCOMP */
767                         sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose;
768                         KLIPS_PRINT(debug_pfkey,
769                                     "klips_debug:pfkey_x_debug_process: "
770                                     "set\n");
771                 } else {
772                         KLIPS_PRINT(debug_pfkey,
773                                     "klips_debug:pfkey_x_debug_process: "
774                                     "unset\n");
775                         debug_tunnel  &= pfkey_x_debug->sadb_x_debug_tunnel;
776                         debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink;
777                         debug_xform   &= pfkey_x_debug->sadb_x_debug_xform;
778                         debug_eroute  &= pfkey_x_debug->sadb_x_debug_eroute;
779                         debug_spi     &= pfkey_x_debug->sadb_x_debug_spi;
780                         debug_radij   &= pfkey_x_debug->sadb_x_debug_radij;
781                         debug_esp     &= pfkey_x_debug->sadb_x_debug_esp;
782                         debug_ah      &= pfkey_x_debug->sadb_x_debug_ah;
783                         debug_rcv     &= pfkey_x_debug->sadb_x_debug_rcv;
784                         debug_pfkey   &= pfkey_x_debug->sadb_x_debug_pfkey;
785 #ifdef CONFIG_IPSEC_IPCOMP
786                         sysctl_ipsec_debug_ipcomp  &= pfkey_x_debug->sadb_x_debug_ipcomp;
787 #endif /* CONFIG_IPSEC_IPCOMP */
788                         sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose;
789                 }
790 #else /* CONFIG_IPSEC_DEBUG */
791                 printk("klips_debug:pfkey_x_debug_process: "
792                        "debugging not enabled\n");
793                 SENDERR(EINVAL);
794 #endif /* CONFIG_IPSEC_DEBUG */
795         
796 errlab:
797         return error;
798 }
799
800 #ifdef CONFIG_IPSEC_NAT_TRAVERSAL
801 DEBUG_NO_STATIC int
802 pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
803 {
804         int error = 0;
805         struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)pfkey_ext;
806
807         if(!pfkey_x_nat_t_type) {
808                 printk("klips_debug:pfkey_x_nat_t_type_process: "
809                        "null pointer passed in\n");
810                 SENDERR(EINVAL);
811         }
812
813         KLIPS_PRINT(debug_pfkey,
814                     "klips_debug:pfkey_x_nat_t_type_process: %d.\n",
815                         pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
816
817         if(!extr || !extr->tdb) {
818                 KLIPS_PRINT(debug_pfkey,
819                             "klips_debug:pfkey_nat_t_type_process: "
820                             "extr or extr->tdb is NULL, fatal\n");
821                 SENDERR(EINVAL);
822         }
823
824         switch(pfkey_x_nat_t_type->sadb_x_nat_t_type_type) {
825                 case ESPINUDP_WITH_NON_IKE: /* with Non-IKE */
826                 case ESPINUDP_WITH_NON_ESP: /* with Non-ESP */
827                         extr->tdb->ips_natt_type = pfkey_x_nat_t_type->sadb_x_nat_t_type_type;
828                         break;
829                 default:
830                         KLIPS_PRINT(debug_pfkey,
831                             "klips_debug:pfkey_x_nat_t_type_process: "
832                             "unknown type %d.\n",
833                             pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
834                         SENDERR(EINVAL);
835                         break;
836         }
837
838 errlab:
839         return error;
840 }
841 DEBUG_NO_STATIC int
842 pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
843 {
844         int error = 0;
845         struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)pfkey_ext;
846
847         if(!pfkey_x_nat_t_port) {
848                 printk("klips_debug:pfkey_x_nat_t_port_process: "
849                        "null pointer passed in\n");
850                 SENDERR(EINVAL);
851         }
852
853         KLIPS_PRINT(debug_pfkey,
854                     "klips_debug:pfkey_x_nat_t_port_process: %d/%d.\n",
855                         pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype,
856                         pfkey_x_nat_t_port->sadb_x_nat_t_port_port);
857
858         if(!extr || !extr->tdb) {
859                 KLIPS_PRINT(debug_pfkey,
860                             "klips_debug:pfkey_nat_t_type_process: "
861                             "extr or extr->tdb is NULL, fatal\n");
862                 SENDERR(EINVAL);
863         }
864
865         switch(pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype) {
866                 case SADB_X_EXT_NAT_T_SPORT:
867                         extr->tdb->ips_natt_sport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
868                         break;
869                 case SADB_X_EXT_NAT_T_DPORT:
870                         extr->tdb->ips_natt_dport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
871                         break;
872                 default:
873                         KLIPS_PRINT(debug_pfkey,
874                             "klips_debug:pfkey_x_nat_t_port_process: "
875                             "unknown exttype %d.\n",
876                             pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype);
877                         SENDERR(EINVAL);
878                         break;
879         }
880
881 errlab:
882         return error;
883 }
884 #endif
885
886 DEBUG_NO_STATIC int
887 pfkey_ipsec_sa_init(struct ipsec_sa *tdbp, struct sadb_ext **extensions)
888 {
889         int i;
890         int error = 0;
891         char sa[SATOA_BUF];
892         size_t sa_len;
893         char ipaddr_txt[ADDRTOA_BUF];
894         char ipaddr2_txt[ADDRTOA_BUF];
895         unsigned char kb[AHMD596_BLKLEN];
896 #ifdef CONFIG_IPSEC_ALG
897         struct ipsec_alg_enc *ixt_e = NULL;
898         struct ipsec_alg_auth *ixt_a = NULL;
899 #endif /* CONFIG_IPSEC_ALG */
900
901         if(!tdbp) {
902                 KLIPS_PRINT(debug_pfkey,
903                             "klips_debug:pfkey_ipsec_sa_init: "
904                             "tdbp is NULL, fatal\n");
905                 SENDERR(EINVAL);
906         }
907
908 #ifdef USE_IXP4XX_CRYPTO
909         tdbp->ips_crypto_state = IPSEC_GLUE_INIT_CTXID;
910 #endif
911         sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
912
913         KLIPS_PRINT(debug_pfkey,
914                     "klips_debug:pfkey_ipsec_sa_init: "
915                     "(pfkey defined) called for SA:%s\n",
916                     sa_len ? sa : " (error)");
917
918         KLIPS_PRINT(debug_pfkey,
919                     "klips_debug:pfkey_ipsec_sa_init: "
920                     "calling init routine of %s%s%s\n",
921                     IPS_XFORM_NAME(tdbp));
922         
923         switch(tdbp->tdb_said.proto) {
924                 
925 #ifdef CONFIG_IPSEC_IPIP
926         case IPPROTO_IPIP: {
927                 addrtoa(((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr,
928                         0,
929                         ipaddr_txt, sizeof(ipaddr_txt));
930                 addrtoa(((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr,
931                         0,
932                         ipaddr2_txt, sizeof(ipaddr_txt));
933                 KLIPS_PRINT(debug_pfkey,
934                             "klips_debug:pfkey_ipsec_sa_init: "
935                             "(pfkey defined) IPIP tdb set for %s->%s.\n",
936                             ipaddr_txt,
937                             ipaddr2_txt);
938         }
939         break;
940 #endif /* !CONFIG_IPSEC_IPIP */
941 #ifdef CONFIG_IPSEC_AH
942         case IPPROTO_AH:
943                 switch(tdbp->tdb_authalg) {
944 # ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
945                 case AH_MD5: {
946 #ifndef USE_IXP4XX_CRYPTO
947                         unsigned char *akp;
948                         unsigned int aks;
949                         MD5_CTX *ictx;
950                         MD5_CTX *octx;
951                         
952 #endif /*USE_IXP4XX_CRYPTO */
953                         if(tdbp->tdb_key_bits_a != (AHMD596_KLEN * 8)) {
954                                 KLIPS_PRINT(debug_pfkey,
955                                             "klips_debug:pfkey_ipsec_sa_init: "
956                                             "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
957                                             tdbp->tdb_key_bits_a, AHMD596_KLEN * 8);
958                                 SENDERR(EINVAL);
959                         }
960                         
961 #  if 0 /* we don't really want to print these unless there are really big problems */
962                         KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
963                                     "klips_debug:pfkey_ipsec_sa_init: "
964                                     "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
965                                     ntohl(*(((__u32 *)tdbp->tdb_key_a)+0)),
966                                     ntohl(*(((__u32 *)tdbp->tdb_key_a)+1)),
967                                     ntohl(*(((__u32 *)tdbp->tdb_key_a)+2)),
968                                     ntohl(*(((__u32 *)tdbp->tdb_key_a)+3)));
969 #  endif
970                         
971                         tdbp->tdb_auth_bits = AHMD596_ALEN * 8;
972                         
973 #ifndef USE_IXP4XX_CRYPTO
974                         /* save the pointer to the key material */
975                         akp = tdbp->tdb_key_a;
976                         aks = tdbp->tdb_key_a_size;
977                         
978                         if((tdbp->tdb_key_a = (caddr_t)
979                             kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
980                                 tdbp->tdb_key_a = akp;
981                                 SENDERR(ENOMEM);
982                         }
983                         tdbp->tdb_key_a_size = sizeof(struct md5_ctx);
984
985                         for (i = 0; i < DIVUP(tdbp->tdb_key_bits_a, 8); i++) {
986                                 kb[i] = akp[i] ^ HMAC_IPAD;
987                         }
988                         for (; i < AHMD596_BLKLEN; i++) {
989                                 kb[i] = HMAC_IPAD;
990                         }
991
992                         ictx = &(((struct md5_ctx*)(tdbp->tdb_key_a))->ictx);
993                         MD5Init(ictx);
994                         MD5Update(ictx, kb, AHMD596_BLKLEN);
995
996                         for (i = 0; i < AHMD596_BLKLEN; i++) {
997                                 kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
998                         }
999
1000                         octx = &(((struct md5_ctx*)(tdbp->tdb_key_a))->octx);
1001                         MD5Init(octx);
1002                         MD5Update(octx, kb, AHMD596_BLKLEN);
1003                         
1004 #  if 0 /* we don't really want to print these unless there are really big problems */
1005                         KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
1006                                     "klips_debug:pfkey_ipsec_sa_init: "
1007                                     "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
1008                                     ((__u32*)ictx)[0],
1009                                     ((__u32*)ictx)[1],
1010                                     ((__u32*)ictx)[2],
1011                                     ((__u32*)ictx)[3],
1012                                     ((__u32*)octx)[0],
1013                                     ((__u32*)octx)[1],
1014                                     ((__u32*)octx)[2],
1015                                     ((__u32*)octx)[3] );
1016 #  endif
1017                         
1018                         /* zero key buffer -- paranoid */
1019                         memset(akp, 0, aks);
1020                         kfree(akp);
1021 #endif /* USE_IXP4XX_CRYPTO */
1022                 }
1023                 break;
1024 # endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
1025 # ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
1026                 case AH_SHA: {
1027 #ifndef USE_IXP4XX_CRYPTO
1028                         unsigned char *akp;
1029                         unsigned int aks;
1030                         SHA1_CTX *ictx;
1031                         SHA1_CTX *octx;
1032 #endif /* USE_IXP4XX_CRYPTO */
1033                         
1034                         if(tdbp->tdb_key_bits_a != (AHSHA196_KLEN * 8)) {
1035                                 KLIPS_PRINT(debug_pfkey,
1036                                             "klips_debug:pfkey_ipsec_sa_init: "
1037                                             "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
1038                                             tdbp->tdb_key_bits_a, AHSHA196_KLEN * 8);
1039                                 SENDERR(EINVAL);
1040                         }
1041                         
1042 #  if 0 /* we don't really want to print these unless there are really big problems */
1043                         KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
1044                                     "klips_debug:pfkey_ipsec_sa_init: "
1045                                     "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
1046                                     ntohl(*(((__u32 *)tdbp->tdb_key_a)+0)),
1047                                     ntohl(*(((__u32 *)tdbp->tdb_key_a)+1)),
1048                                     ntohl(*(((__u32 *)tdbp->tdb_key_a)+2)),
1049                                     ntohl(*(((__u32 *)tdbp->tdb_key_a)+3)));
1050 #  endif
1051                         
1052                         tdbp->tdb_auth_bits = AHSHA196_ALEN * 8;
1053                         
1054 #ifndef USE_IXP4XX_CRYPTO
1055                         /* save the pointer to the key material */
1056                         akp = tdbp->tdb_key_a;
1057                         aks = tdbp->tdb_key_a_size;
1058                         
1059                         if((tdbp->tdb_key_a = (caddr_t)
1060                             kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
1061                                 tdbp->tdb_key_a = akp;
1062                                 SENDERR(ENOMEM);
1063                         }
1064                         tdbp->tdb_key_a_size = sizeof(struct sha1_ctx);
1065
1066                         for (i = 0; i < DIVUP(tdbp->tdb_key_bits_a, 8); i++) {
1067                                 kb[i] = akp[i] ^ HMAC_IPAD;
1068                         }
1069                         for (; i < AHMD596_BLKLEN; i++) {
1070                                 kb[i] = HMAC_IPAD;
1071                         }
1072
1073                         ictx = &(((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx);
1074                         SHA1Init(ictx);
1075                         SHA1Update(ictx, kb, AHSHA196_BLKLEN);
1076
1077                         for (i = 0; i < AHSHA196_BLKLEN; i++) {
1078                                 kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
1079                         }
1080
1081                         octx = &(((struct sha1_ctx*)(tdbp->tdb_key_a))->octx);
1082                         SHA1Init(octx);
1083                         SHA1Update(octx, kb, AHSHA196_BLKLEN);
1084                         
1085 #  if 0 /* we don't really want to print these unless there are really big problems */
1086                         KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
1087                                     "klips_debug:pfkey_ipsec_sa_init: "
1088                                     "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", 
1089                                     ((__u32*)ictx)[0],
1090                                     ((__u32*)ictx)[1],
1091                                     ((__u32*)ictx)[2],
1092                                     ((__u32*)ictx)[3],
1093                                     ((__u32*)octx)[0],
1094                                     ((__u32*)octx)[1],
1095                                     ((__u32*)octx)[2],
1096                                     ((__u32*)octx)[3] );
1097 #  endif                        
1098                         /* zero key buffer -- paranoid */
1099                         memset(akp, 0, aks);
1100                         kfree(akp);
1101 #endif /* USE_IXP4XX_CRYPTO */
1102                 }
1103                 break;
1104 # endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
1105                 default:
1106                         KLIPS_PRINT(debug_pfkey,
1107                                     "klips_debug:pfkey_ipsec_sa_init: "
1108                                     "authalg=%d support not available in the kernel",
1109                                     tdbp->tdb_authalg);
1110                         SENDERR(EINVAL);
1111                 }
1112         break;
1113 #endif /* CONFIG_IPSEC_AH */
1114 #ifdef CONFIG_IPSEC_ESP
1115         case IPPROTO_ESP: {
1116 #ifndef USE_IXP4XX_CRYPTO
1117                 unsigned char *akp, *ekp;
1118                 unsigned int aks, eks;
1119 #endif /* USE_IXP4XX_CRYPTO */
1120
1121                 tdbp->tdb_iv_size = 0;
1122 #ifdef CONFIG_IPSEC_ALG
1123                 if ((ixt_e=IPSEC_ALG_SA_ESP_ENC(tdbp))) {
1124                         tdbp->tdb_iv_size = ixt_e->ixt_blocksize;
1125                 } else  
1126 #endif /* CONFIG_IPSEC_ALG */           
1127                 switch(tdbp->tdb_encalg) {
1128 # ifdef CONFIG_IPSEC_ENC_DES
1129                 case ESP_DES:
1130 # endif /* CONFIG_IPSEC_ENC_DES */
1131 # ifdef CONFIG_IPSEC_ENC_3DES
1132                 case ESP_3DES:
1133 # endif /* CONFIG_IPSEC_ENC_3DES */
1134 # if defined(CONFIG_IPSEC_ENC_DES) || defined(CONFIG_IPSEC_ENC_3DES)
1135                         tdbp->tdb_iv_size = EMT_ESPDES_IV_SZ;
1136 #ifdef USE_IXP4XX_CRYPTO
1137                         tdbp->ips_enc_blksize = ESP_DESCBC_BLKLEN;
1138 #endif /* USE_IXP4XX_CRYPTO */
1139 # endif /* defined(CONFIG_IPSEC_ENC_DES) || defined(CONFIG_IPSEC_ENC_3DES) */
1140                 case ESP_NONE:
1141                         break;
1142                 default:
1143                         KLIPS_PRINT(debug_pfkey,
1144                                     "klips_debug:pfkey_ipsec_sa_init: "
1145                                     "encalg=%d support not available in the kernel",
1146                                     tdbp->tdb_encalg);
1147                         SENDERR(EINVAL);
1148                 }
1149
1150                 /* Create IV */
1151                 if (tdbp->tdb_iv_size) {
1152                         if((tdbp->tdb_iv = (caddr_t)
1153                             kmalloc(tdbp->tdb_iv_size, GFP_ATOMIC)) == NULL) {
1154                                 SENDERR(ENOMEM);
1155                         }
1156                         get_random_bytes((void *)tdbp->tdb_iv, tdbp->tdb_iv_size);
1157                         tdbp->tdb_iv_bits = tdbp->tdb_iv_size * 8;
1158                 }
1159                 
1160 #ifdef CONFIG_IPSEC_ALG
1161                 if (ixt_e) {
1162 #ifdef USE_IXP4XX_CRYPTO
1163                         ipsec_alg_enc_blksize_create(tdbp);
1164 #endif /* USE_IXP4XX_CRYPTO */
1165                         if ((error=ipsec_alg_enc_key_create(tdbp)) < 0)
1166                                 SENDERR(-error);
1167                 } else
1168 #endif /* CONFIG_IPSEC_ALG */
1169                 switch(tdbp->tdb_encalg) {
1170 # ifdef CONFIG_IPSEC_ENC_DES
1171                 case ESP_DES:
1172                         if(tdbp->tdb_key_bits_e != (EMT_ESPDES_KEY_SZ * 8)) {
1173                                 KLIPS_PRINT(debug_pfkey,
1174                                             "klips_debug:pfkey_tdb_init: incorrect encryption"
1175                                             "key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
1176                                             tdbp->tdb_key_bits_e, EMT_ESPDES_KEY_SZ * 8);
1177                                 SENDERR(EINVAL);
1178                         }
1179
1180 #ifndef USE_IXP4XX_CRYPTO
1181                         /* save encryption key pointer */
1182                         ekp = tdbp->tdb_key_e;
1183
1184                         if((tdbp->tdb_key_e = (caddr_t)
1185                             kmalloc((tdbp->tdb_key_e_size = sizeof(struct des_eks)),
1186                                     GFP_ATOMIC)) == NULL) {
1187                                 SENDERR(ENOMEM);
1188                         }
1189 #  if 0 /* we don't really want to print these unless there are really big problems */
1190                         KLIPS_PRINT(debug_pfkey,
1191                                     "klips_debug:pfkey_tdb_init: des key is 0x%08lx%08lx\n",
1192                                     ntohl(*((__u32 *)ed->eme_key)),
1193                                     ntohl(*((__u32 *)ed->eme_key + 1)));
1194 #  endif
1195                         error = des_set_key((caddr_t)ekp, (caddr_t)(tdbp->tdb_key_e));
1196                         if (error == -1)
1197                                 printk("klips_debug:pfkey_tdb_init: parity error in des key\n");
1198                         else if (error == -2)
1199                                 printk("klips_debug:pfkey_tdb_init: illegal weak des key\n");
1200                         if (error) {
1201                                 memset(tdbp->tdb_key_e, 0, sizeof(struct des_eks));
1202                                 kfree(tdbp->tdb_key_e);
1203                                 memset(ekp, 0, DIVUP(tdbp->tdb_key_bits_e, BITS_PER_OCTET));
1204                                 SENDERR(EINVAL);
1205                         }
1206
1207                         /* paranoid */
1208                         memset(ekp, 0, DIVUP(tdbp->tdb_key_bits_e, BITS_PER_OCTET));
1209 #endif /*  USE_IXP4XX_CRYPTO    */
1210
1211                         break;
1212 # endif /* CONFIG_IPSEC_ENC_DES */
1213 # ifdef CONFIG_IPSEC_ENC_3DES
1214                 case ESP_3DES:
1215                         if(tdbp->tdb_key_bits_e != (EMT_ESP3DES_KEY_SZ * 8)) {
1216                                 KLIPS_PRINT(debug_pfkey,
1217                                             "klips_debug:pfkey_ipsec_sa_init: "
1218                                             "incorrect encryption key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
1219                                             tdbp->tdb_key_bits_e, EMT_ESP3DES_KEY_SZ * 8);
1220                                 SENDERR(EINVAL);
1221                         }
1222                         
1223 #ifndef USE_IXP4XX_CRYPTO
1224                         /* save encryption key pointer */
1225                         ekp = tdbp->tdb_key_e;
1226                         eks = tdbp->tdb_key_e_size;
1227                         
1228                         if((tdbp->tdb_key_e = (caddr_t)
1229                             kmalloc(3 * sizeof(struct des_eks), GFP_ATOMIC)) == NULL) {
1230                                 tdbp->tdb_key_e = ekp;
1231                                 SENDERR(ENOMEM);
1232                         }
1233                         tdbp->tdb_key_e_size = 3 * sizeof(struct des_eks);
1234
1235                         for(i = 0; i < 3; i++) {
1236 #if KLIPS_DIVULGE_CYPHER_KEY
1237                                 KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
1238                                             "klips_debug:pfkey_ipsec_sa_init: "
1239                                             "3des key %d/3 is 0x%08x%08x\n",
1240                                             i + 1,
1241                                             ntohl(*((__u32 *)ekp + i * 2)),
1242                                             ntohl(*((__u32 *)ekp + i * 2 + 1)));
1243 #  endif
1244 #if KLIPS_FIXES_DES_PARITY                              
1245                                 /* force parity */
1246                                 des_set_odd_parity((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i));
1247 #endif
1248                                 error = des_set_key((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i),
1249                                                     ((struct des_eks *)(tdbp->tdb_key_e))[i].ks);
1250                                 if (error == -1)
1251                                         printk("klips_debug:pfkey_ipsec_sa_init: "
1252                                                "parity error in des key %d/3\n",
1253                                                i + 1);
1254                                 else if (error == -2)
1255                                         printk("klips_debug:pfkey_ipsec_sa_init: "
1256                                                "illegal weak des key %d/3\n", i + 1);
1257                                 if (error) {
1258                                         memset(ekp, 0, eks);
1259                                         kfree(ekp);
1260                                         SENDERR(EINVAL);
1261                                 }
1262                         }
1263
1264                         /* paranoid */
1265                         memset(ekp, 0, eks);
1266                         kfree(ekp);
1267 #endif /*  USE_IXP4XX_CRYPTO    */
1268                         break;
1269 # endif /* CONFIG_IPSEC_ENC_3DES */
1270                 case ESP_NONE:
1271                         break;
1272                 default:
1273                         KLIPS_PRINT(debug_pfkey,
1274                                     "klips_debug:pfkey_ipsec_sa_init: "
1275                                     "encalg=%d support not available in the kernel",
1276                                     tdbp->tdb_encalg);
1277                         SENDERR(EINVAL);
1278                 }
1279
1280 #ifdef CONFIG_IPSEC_ALG
1281                 if ((ixt_a=IPSEC_ALG_SA_ESP_AUTH(tdbp))) {
1282                         if ((error=ipsec_alg_auth_key_create(tdbp)) < 0)
1283                                 SENDERR(-error);
1284                 } else  
1285 #endif /* CONFIG_IPSEC_ALG */
1286                 
1287                 switch(tdbp->tdb_authalg) {
1288 # ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
1289                 case AH_MD5: {
1290 #ifndef USE_IXP4XX_CRYPTO
1291                         MD5_CTX *ictx;
1292                         MD5_CTX *octx;
1293 #endif /* USE_IXP4XX_CRYPTO */  
1294
1295                         if(tdbp->tdb_key_bits_a != (AHMD596_KLEN * 8)) {
1296                                 KLIPS_PRINT(debug_pfkey,
1297                                             "klips_debug:pfkey_ipsec_sa_init: "
1298                                             "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
1299                                             tdbp->tdb_key_bits_a,
1300                                             AHMD596_KLEN * 8);
1301                                 SENDERR(EINVAL);
1302                         }
1303                         
1304 #  if 0 /* we don't really want to print these unless there are really big problems */
1305                         KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
1306                                     "klips_debug:pfkey_ipsec_sa_init: "
1307                                     "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
1308                                     ntohl(*(((__u32 *)(tdbp->tdb_key_a))+0)),
1309                                     ntohl(*(((__u32 *)(tdbp->tdb_key_a))+1)),
1310                                     ntohl(*(((__u32 *)(tdbp->tdb_key_a))+2)),
1311                                     ntohl(*(((__u32 *)(tdbp->tdb_key_a))+3)));
1312 #  endif
1313                         tdbp->tdb_auth_bits = AHMD596_ALEN * 8;
1314                         
1315 #ifndef USE_IXP4XX_CRYPTO
1316                         /* save the pointer to the key material */
1317                         akp = tdbp->tdb_key_a;
1318                         aks = tdbp->tdb_key_a_size;
1319                         
1320                         if((tdbp->tdb_key_a = (caddr_t)
1321                             kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
1322                                 tdbp->tdb_key_a = akp;
1323                                 SENDERR(ENOMEM);
1324                         }
1325                         tdbp->tdb_key_a_size = sizeof(struct md5_ctx);
1326
1327                         for (i = 0; i < DIVUP(tdbp->tdb_key_bits_a, 8); i++) {
1328                                 kb[i] = akp[i] ^ HMAC_IPAD;
1329                         }
1330                         for (; i < AHMD596_BLKLEN; i++) {
1331                                 kb[i] = HMAC_IPAD;
1332                         }
1333
1334                         ictx = &(((struct md5_ctx*)(tdbp->tdb_key_a))->ictx);
1335                         MD5Init(ictx);
1336                         MD5Update(ictx, kb, AHMD596_BLKLEN);
1337
1338                         for (i = 0; i < AHMD596_BLKLEN; i++) {
1339                                 kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
1340                         }
1341
1342                         octx = &(((struct md5_ctx*)(tdbp->tdb_key_a))->octx);
1343                         MD5Init(octx);
1344                         MD5Update(octx, kb, AHMD596_BLKLEN);
1345                         
1346 #  if 0 /* we don't really want to print these unless there are really big problems */
1347                         KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
1348                                     "klips_debug:pfkey_ipsec_sa_init: "
1349                                     "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
1350                                     ((__u32*)ictx)[0],
1351                                     ((__u32*)ictx)[1],
1352                                     ((__u32*)ictx)[2],
1353                                     ((__u32*)ictx)[3],
1354                                     ((__u32*)octx)[0],
1355                                     ((__u32*)octx)[1],
1356                                     ((__u32*)octx)[2],
1357                                     ((__u32*)octx)[3] );
1358 #  endif
1359                         /* paranoid */
1360                         memset(akp, 0, aks);
1361                         kfree(akp);
1362 #endif /* USE_IXP4XX_CRYPTO*/
1363                         break;
1364                 }
1365 # endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
1366 # ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
1367                 case AH_SHA: {
1368 #ifndef USE_IXP4XX_CRYPTO
1369                         SHA1_CTX *ictx;
1370                         SHA1_CTX *octx;
1371 #endif /* USE_IXP4XX_CRYPTO */
1372
1373                         if(tdbp->tdb_key_bits_a != (AHSHA196_KLEN * 8)) {
1374                                 KLIPS_PRINT(debug_pfkey,
1375                                             "klips_debug:pfkey_ipsec_sa_init: "
1376                                             "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
1377                                             tdbp->tdb_key_bits_a,
1378                                             AHSHA196_KLEN * 8);
1379                                 SENDERR(EINVAL);
1380                         }
1381                         
1382 #  if 0 /* we don't really want to print these unless there are really big problems */
1383                         KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
1384                                     "klips_debug:pfkey_ipsec_sa_init: "
1385                                     "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
1386                                     ntohl(*(((__u32 *)tdbp->tdb_key_a)+0)),
1387                                     ntohl(*(((__u32 *)tdbp->tdb_key_a)+1)),
1388                                     ntohl(*(((__u32 *)tdbp->tdb_key_a)+2)),
1389                                     ntohl(*(((__u32 *)tdbp->tdb_key_a)+3)));
1390 #  endif
1391                         tdbp->tdb_auth_bits = AHSHA196_ALEN * 8;
1392                         
1393 #ifndef USE_IXP4XX_CRYPTO
1394                         /* save the pointer to the key material */
1395                         akp = tdbp->tdb_key_a;
1396                         aks = tdbp->tdb_key_a_size;
1397
1398                         if((tdbp->tdb_key_a = (caddr_t)
1399                             kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
1400                                 tdbp->tdb_key_a = akp;
1401                                 SENDERR(ENOMEM);
1402                         }
1403                         tdbp->tdb_key_a_size = sizeof(struct sha1_ctx);
1404
1405                         for (i = 0; i < DIVUP(tdbp->tdb_key_bits_a, 8); i++) {
1406                                 kb[i] = akp[i] ^ HMAC_IPAD;
1407                         }
1408                         for (; i < AHMD596_BLKLEN; i++) {
1409                                 kb[i] = HMAC_IPAD;
1410                         }
1411
1412                         ictx = &(((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx);
1413                         SHA1Init(ictx);
1414                         SHA1Update(ictx, kb, AHSHA196_BLKLEN);
1415
1416                         for (i = 0; i < AHSHA196_BLKLEN; i++) {
1417                                 kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
1418                         }
1419
1420                         octx = &((struct sha1_ctx*)(tdbp->tdb_key_a))->octx;
1421                         SHA1Init(octx);
1422                         SHA1Update(octx, kb, AHSHA196_BLKLEN);
1423                         
1424 #  if 0 /* we don't really want to print these unless there are really big problems */
1425                         KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
1426                                     "klips_debug:pfkey_ipsec_sa_init: "
1427                                     "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
1428                                     ((__u32*)ictx)[0],
1429                                     ((__u32*)ictx)[1],
1430                                     ((__u32*)ictx)[2],
1431                                     ((__u32*)ictx)[3],
1432                                     ((__u32*)octx)[0],
1433                                     ((__u32*)octx)[1],
1434                                     ((__u32*)octx)[2],
1435                                     ((__u32*)octx)[3] );
1436 #  endif
1437                         memset(akp, 0, aks);
1438                         kfree(akp);
1439 #endif /* USE_IXP4XX_CRYPTO */
1440                         break;
1441                 }
1442 # endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
1443                 case AH_NONE:
1444                         break;
1445                 default:
1446                         KLIPS_PRINT(debug_pfkey,
1447                                     "klips_debug:pfkey_ipsec_sa_init: "
1448                                     "authalg=%d support not available in the kernel.\n",
1449                                     tdbp->tdb_authalg);
1450                         SENDERR(EINVAL);
1451                 }
1452         }
1453                         break;
1454 #endif /* !CONFIG_IPSEC_ESP */
1455 #ifdef CONFIG_IPSEC_IPCOMP
1456         case IPPROTO_COMP:
1457                 tdbp->tdb_comp_adapt_tries = 0;
1458                 tdbp->tdb_comp_adapt_skip = 0;
1459                 tdbp->tdb_comp_ratio_cbytes = 0;
1460                 tdbp->tdb_comp_ratio_dbytes = 0;
1461                 break;
1462 #endif /* CONFIG_IPSEC_IPCOMP */
1463         default:
1464                 KLIPS_PRINT(debug_pfkey,
1465                             "klips_debug:pfkey_ipsec_sa_init: "
1466                             "proto=%d unknown.\n",
1467                             tdbp->tdb_said.proto);
1468                 SENDERR(EINVAL);
1469         }
1470         
1471  errlab:
1472         return(error);
1473 }
1474
1475
1476 int
1477 pfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1])
1478 {
1479         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: "
1480                     "error=%d\n",
1481                     error);
1482         if (!error) {
1483                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
1484                             "success.\n");
1485                 return 1;
1486         } else {
1487                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
1488                             "caught error %d\n",
1489                             error);
1490                 pfkey_extensions_free(extensions);
1491                 return 0;
1492         }
1493 }
1494
1495
1496 DEBUG_NO_STATIC int
1497 pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
1498 {
1499         int error = 0;
1500         ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L);
1501         int found_avail = 0;
1502         struct ipsec_sa *tdbq;
1503         char sa[SATOA_BUF];
1504         size_t sa_len;
1505         struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
1506         struct sadb_msg *pfkey_reply = NULL;
1507         struct socket_list *pfkey_socketsp;
1508         uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
1509
1510         KLIPS_PRINT(debug_pfkey,
1511                     "klips_debug:pfkey_getspi_parse: .\n");
1512
1513         pfkey_extensions_init(extensions_reply);
1514
1515         if(!extr || !extr->tdb) {
1516                 KLIPS_PRINT(debug_pfkey,
1517                             "klips_debug:pfkey_getspi_parse: "
1518                             "error, extr or extr->tdb pointer NULL\n");
1519                 SENDERR(EINVAL);
1520         }
1521
1522         if(extensions[SADB_EXT_SPIRANGE]) {
1523                 minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min;
1524                 maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max;
1525         }
1526
1527         if(maxspi == minspi) {
1528                 extr->tdb->tdb_said.spi = maxspi;
1529                 if((tdbq = ipsec_sa_getbyid(&(extr->tdb->tdb_said)))) {
1530                         sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF);
1531                         KLIPS_PRINT(debug_pfkey,
1532                                     "klips_debug:pfkey_getspi_parse: "
1533                                     "EMT_GETSPI found an old Tunnel Descriptor Block for SA: %s, delete it first.\n",
1534                                     sa_len ? sa : " (error)");
1535                         SENDERR(EEXIST);
1536                 } else {
1537                         found_avail = 1;
1538                 }
1539         } else {
1540                 int i = 0;
1541                 __u32 rand_val;
1542                 __u32 spi_diff;
1543                 while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) {
1544                         get_random_bytes((void*) &(rand_val),
1545                                          /* sizeof(extr->tdb->tdb_said.spi) */
1546                                          ( (spi_diff < (2^8))  ? 1 :
1547                                            ( (spi_diff < (2^16)) ? 2 :
1548                                              ( (spi_diff < (2^24)) ? 3 :
1549                                            4 ) ) ) );
1550                         extr->tdb->tdb_said.spi = htonl(ntohl(minspi) +
1551                                               (rand_val %
1552                                               (spi_diff + 1)));
1553                         i++;
1554                         tdbq = ipsec_sa_getbyid(&(extr->tdb->tdb_said));
1555                         if(!tdbq) {
1556                                 found_avail = 1;
1557                         }
1558                 }
1559         }
1560
1561         sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF);
1562
1563         if (!found_avail) {
1564                 KLIPS_PRINT(debug_pfkey,
1565                             "klips_debug:pfkey_getspi_parse: "
1566                             "found an old Tunnel Descriptor Block for SA: %s, delete it first.\n",
1567                             sa_len ? sa : " (error)");
1568                 SENDERR(EEXIST);
1569         }
1570
1571         if(ip_chk_addr((unsigned long)extr->tdb->tdb_said.dst.s_addr) == IS_MYADDR) {
1572                 extr->tdb->tdb_flags |= EMT_INBOUND;
1573         }
1574         
1575         KLIPS_PRINT(debug_pfkey,
1576                     "klips_debug:pfkey_getspi_parse: "
1577                     "existing Tunnel Descriptor Block not found (this is good) for SA: %s, %s-bound, allocating.\n",
1578                     sa_len ? sa : " (error)",
1579                     extr->tdb->tdb_flags & EMT_INBOUND ? "in" : "out");
1580         
1581         /* XXX extr->tdb->tdb_rcvif = &(enc_softc[em->em_if].enc_if);*/
1582         extr->tdb->tdb_rcvif = NULL;
1583         extr->tdb->ips_life.ipl_addtime.ipl_count = jiffies/HZ;
1584
1585         extr->tdb->tdb_state = SADB_SASTATE_LARVAL;
1586
1587         if(!extr->tdb->ips_life.ipl_allocations.ipl_count) {
1588                 extr->tdb->ips_life.ipl_allocations.ipl_count += 1;
1589         }
1590
1591         if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
1592                                                           SADB_GETSPI,
1593                                                           satype,
1594                                                           0,
1595                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
1596                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
1597                               extensions_reply)
1598              && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA],
1599                                                 SADB_EXT_SA,
1600                                                 extr->tdb->tdb_said.spi,
1601                                                 0,
1602                                                 SADB_SASTATE_LARVAL,
1603                                                 0,
1604                                                 0,
1605                                                 0),
1606                                  extensions_reply)
1607              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
1608                                                      SADB_EXT_ADDRESS_SRC,
1609                                                      0, /*extr->tdb->tdb_said.proto,*/
1610                                                      0,
1611                                                      extr->tdb->tdb_addr_s),
1612                                  extensions_reply)
1613              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
1614                                                      SADB_EXT_ADDRESS_DST,
1615                                                      0, /*extr->tdb->tdb_said.proto,*/
1616                                                      0,
1617                                                      extr->tdb->tdb_addr_d),
1618                                  extensions_reply) )) {
1619                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
1620                             "failed to build the getspi reply message extensions\n");
1621                 goto errlab;
1622         }
1623         
1624         if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
1625                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
1626                             "failed to build the getspi reply message\n");
1627                 SENDERR(-error);
1628         }
1629         for(pfkey_socketsp = pfkey_open_sockets;
1630             pfkey_socketsp;
1631             pfkey_socketsp = pfkey_socketsp->next) {
1632                 if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
1633                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
1634                                     "sending up getspi reply message for satype=%d(%s) to socket=%p failed with error=%d.\n",
1635                                     satype,
1636                                     satype2name(satype),
1637                                     pfkey_socketsp->socketp,
1638                                     error);
1639                         SENDERR(-error);
1640                 }
1641                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
1642                             "sending up getspi reply message for satype=%d(%s) to socket=%p succeeded.\n",
1643                             satype,
1644                             satype2name(satype),
1645                             pfkey_socketsp->socketp);
1646         }
1647         
1648         if((error = ipsec_sa_put(extr->tdb))) {
1649                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
1650                             "failed to add the larval SA=%s with error=%d.\n",
1651                             sa_len ? sa : " (error)",
1652                             error);
1653                 SENDERR(-error);
1654         }
1655         extr->tdb = NULL;
1656         
1657         KLIPS_PRINT(debug_pfkey,
1658                     "klips_debug:pfkey_getspi_parse: "
1659                     "successful for SA: %s\n",
1660                     sa_len ? sa : " (error)");
1661         
1662  errlab:
1663         if (pfkey_reply) {
1664                 pfkey_msg_free(&pfkey_reply);
1665         }
1666         pfkey_extensions_free(extensions_reply);
1667         return error;
1668 }
1669
1670 DEBUG_NO_STATIC int
1671 pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
1672 {
1673         int error = 0;
1674         struct ipsec_sa* tdbq;
1675         char sa[SATOA_BUF];
1676         size_t sa_len;
1677         struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
1678         struct sadb_msg *pfkey_reply = NULL;
1679         struct socket_list *pfkey_socketsp;
1680         uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
1681 #ifdef CONFIG_IPSEC_NAT_TRAVERSAL
1682         struct ipsec_sa *nat_t_tdb_saved = NULL;
1683 #endif
1684
1685         KLIPS_PRINT(debug_pfkey,
1686                     "klips_debug:pfkey_update_parse: .\n");
1687
1688         pfkey_extensions_init(extensions_reply);
1689
1690         if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
1691                 KLIPS_PRINT(debug_pfkey,
1692                             "klips_debug:pfkey_update_parse: "
1693                             "error, sa_state=%d must be MATURE=%d\n",
1694                             ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
1695                             SADB_SASTATE_MATURE);
1696                 SENDERR(EINVAL);
1697         }
1698
1699         if(!extr || !extr->tdb) {
1700                 KLIPS_PRINT(debug_pfkey,
1701                             "klips_debug:pfkey_update_parse: "
1702                             "error, extr or extr->tdb pointer NULL\n");
1703                 SENDERR(EINVAL);
1704         }
1705
1706         sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF);
1707
1708         spin_lock_bh(&tdb_lock);
1709
1710         tdbq = ipsec_sa_getbyid(&(extr->tdb->tdb_said));
1711         if (!tdbq) {
1712                 spin_unlock_bh(&tdb_lock);
1713                 KLIPS_PRINT(debug_pfkey,
1714                             "klips_debug:pfkey_update_parse: "
1715                             "reserved Tunnel Descriptor Block for SA: %s not found.  Call SADB_GETSPI first or call SADB_ADD instead.\n",
1716                             sa_len ? sa : " (error)");
1717                 SENDERR(ENOENT);
1718         }
1719
1720         if(ip_chk_addr((unsigned long)extr->tdb->tdb_said.dst.s_addr) == IS_MYADDR) {
1721                 extr->tdb->tdb_flags |= EMT_INBOUND;
1722         }
1723
1724         KLIPS_PRINT(debug_pfkey,
1725                     "klips_debug:pfkey_update_parse: "
1726                     "existing Tunnel Descriptor Block found (this is good) for SA: %s, %s-bound, updating.\n",
1727                     sa_len ? sa : " (error)",
1728                     extr->tdb->tdb_flags & EMT_INBOUND ? "in" : "out");
1729         
1730 #ifdef CONFIG_IPSEC_NAT_TRAVERSAL
1731         if (extr->tdb->ips_natt_sport || extr->tdb->ips_natt_dport) {
1732                 KLIPS_PRINT(debug_pfkey,
1733                         "klips_debug:pfkey_update_parse: only updating NAT-T ports "
1734                         "(%u:%u -> %u:%u)\n", 
1735                         tdbq->ips_natt_sport, tdbq->ips_natt_dport,
1736                         extr->tdb->ips_natt_sport, extr->tdb->ips_natt_dport);
1737
1738                 if (extr->tdb->ips_natt_sport) {
1739                         tdbq->ips_natt_sport = extr->tdb->ips_natt_sport;
1740                         if (tdbq->ips_addr_s->sa_family == AF_INET) {
1741                                 ((struct sockaddr_in *)(tdbq->ips_addr_s))->sin_port = htons(extr->tdb->ips_natt_sport);
1742                         }
1743                 }
1744
1745                 if (extr->tdb->ips_natt_dport) {
1746                         tdbq->ips_natt_dport = extr->tdb->ips_natt_dport;
1747                         if (tdbq->ips_addr_d->sa_family == AF_INET) {
1748                                 ((struct sockaddr_in *)(tdbq->ips_addr_d))->sin_port = htons(extr->tdb->ips_natt_dport);
1749                         }
1750                 }
1751
1752                 nat_t_tdb_saved = extr->tdb;
1753                 extr->tdb = tdbq;
1754         }
1755         else {
1756 #endif
1757         /* XXX extr->tdb->tdb_rcvif = &(enc_softc[em->em_if].enc_if);*/
1758         extr->tdb->tdb_rcvif = NULL;
1759         if ((error = pfkey_ipsec_sa_init(extr->tdb, extensions))) {
1760                 spin_unlock_bh(&tdb_lock);
1761                 KLIPS_PRINT(debug_pfkey,
1762                             "klips_debug:pfkey_update_parse: "
1763                             "not successful for SA: %s, deleting.\n",
1764                             sa_len ? sa : " (error)");
1765                 SENDERR(-error);
1766         }
1767
1768         extr->tdb->ips_life.ipl_addtime.ipl_count = tdbq->ips_life.ipl_addtime.ipl_count;
1769         if((error = ipsec_sa_delchain(tdbq))) {
1770                 spin_unlock_bh(&tdb_lock);
1771                 KLIPS_PRINT(debug_pfkey,
1772                             "klips_debug:pfkey_update_parse: "
1773                             "error=%d, trouble deleting intermediate tdb for SA=%s.\n",
1774                             error,
1775                             sa_len ? sa : " (error)");
1776                 SENDERR(-error);
1777         }
1778 #ifdef CONFIG_IPSEC_NAT_TRAVERSAL
1779         }
1780 #endif
1781
1782         spin_unlock_bh(&tdb_lock);
1783         
1784         if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
1785                                                           SADB_UPDATE,
1786                                                           satype,
1787                                                           0,
1788                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
1789                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
1790                               extensions_reply)
1791              && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA],
1792                                                         SADB_EXT_SA,
1793                                                         extr->tdb->tdb_said.spi,
1794                                                         extr->tdb->tdb_replaywin,
1795                                                         extr->tdb->tdb_state,
1796                                                         extr->tdb->tdb_authalg,
1797                                                         extr->tdb->tdb_encalg,
1798                                                         extr->tdb->tdb_flags),
1799                                  extensions_reply)
1800              /* The 3 lifetime extentions should only be sent if non-zero. */
1801              && (extensions[SADB_EXT_LIFETIME_HARD]
1802                  ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
1803                                                                  SADB_EXT_LIFETIME_HARD,
1804                                                                  extr->tdb->ips_life.ipl_allocations.ipl_hard,
1805                                                                  extr->tdb->ips_life.ipl_bytes.ipl_hard,
1806                                                                  extr->tdb->ips_life.ipl_addtime.ipl_hard,
1807                                                                  extr->tdb->ips_life.ipl_usetime.ipl_hard,
1808                                                                  extr->tdb->ips_life.ipl_packets.ipl_hard),
1809                                     extensions_reply) : 1)
1810              && (extensions[SADB_EXT_LIFETIME_SOFT]
1811                  ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
1812                                                                  SADB_EXT_LIFETIME_SOFT,
1813                                                                  extr->tdb->ips_life.ipl_allocations.ipl_count,
1814                                                                  extr->tdb->ips_life.ipl_bytes.ipl_count,
1815                                                                  extr->tdb->ips_life.ipl_addtime.ipl_count,
1816                                                                  extr->tdb->ips_life.ipl_usetime.ipl_count,
1817                                                                  extr->tdb->ips_life.ipl_packets.ipl_count),
1818                                     extensions_reply) : 1)
1819              && (extr->tdb->ips_life.ipl_allocations.ipl_count
1820                  || extr->tdb->ips_life.ipl_bytes.ipl_count
1821                  || extr->tdb->ips_life.ipl_addtime.ipl_count
1822                  || extr->tdb->ips_life.ipl_usetime.ipl_count
1823                  || extr->tdb->ips_life.ipl_packets.ipl_count
1824
1825                  ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
1826                                                                  SADB_EXT_LIFETIME_CURRENT,
1827                                                                  extr->tdb->ips_life.ipl_allocations.ipl_count,
1828                                                                  extr->tdb->ips_life.ipl_bytes.ipl_count,
1829                                                                  extr->tdb->ips_life.ipl_addtime.ipl_count,
1830                                                                  extr->tdb->ips_life.ipl_usetime.ipl_count,
1831                                                                  extr->tdb->ips_life.ipl_packets.ipl_count),
1832                                     extensions_reply) : 1)
1833              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
1834                                                              SADB_EXT_ADDRESS_SRC,
1835                                                              0, /*extr->tdb->tdb_said.proto,*/
1836                                                              0,
1837                                                              extr->tdb->tdb_addr_s),
1838                                  extensions_reply)
1839              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
1840                                                              SADB_EXT_ADDRESS_DST,
1841                                                              0, /*extr->tdb->tdb_said.proto,*/
1842                                                              0,
1843                                                              extr->tdb->tdb_addr_d),
1844                                  extensions_reply)
1845              && (extr->tdb->tdb_ident_s.data
1846                  ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
1847                                                               SADB_EXT_IDENTITY_SRC,
1848                                                               extr->tdb->tdb_ident_s.type,
1849                                                               extr->tdb->tdb_ident_s.id,
1850                                                               extr->tdb->tdb_ident_s.len,
1851                                                               extr->tdb->tdb_ident_s.data),
1852                                     extensions_reply) : 1)
1853              && (extr->tdb->tdb_ident_d.data
1854                  ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
1855                                                               SADB_EXT_IDENTITY_DST,
1856                                                               extr->tdb->tdb_ident_d.type,
1857                                                               extr->tdb->tdb_ident_d.id,
1858                                                               extr->tdb->tdb_ident_d.len,
1859                                                               extr->tdb->tdb_ident_d.data),
1860                                     extensions_reply) : 1)
1861 #if 0
1862              /* FIXME: This won't work yet because I have not finished
1863                 it. */
1864              && (extr->tdb->tdb_sens_
1865                  ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
1866                                                              extr->tdb->tdb_sens_dpd,
1867                                                              extr->tdb->tdb_sens_sens_level,
1868                                                              extr->tdb->tdb_sens_sens_len,
1869                                                              extr->tdb->tdb_sens_sens_bitmap,
1870                                                              extr->tdb->tdb_sens_integ_level,
1871                                                              extr->tdb->tdb_sens_integ_len,
1872                                                              extr->tdb->tdb_sens_integ_bitmap),
1873                                     extensions_reply) : 1)
1874 #endif
1875                 )) {
1876                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
1877                             "failed to build the update reply message extensions\n");
1878                 SENDERR(-error);
1879         }
1880                 
1881         if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
1882                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
1883                             "failed to build the update reply message\n");
1884                 SENDERR(-error);
1885         }
1886         for(pfkey_socketsp = pfkey_open_sockets;
1887             pfkey_socketsp;
1888             pfkey_socketsp = pfkey_socketsp->next) {
1889                 if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
1890                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
1891                                     "sending up update reply message for satype=%d(%s) to socket=%p failed with error=%d.\n",
1892                                     satype,
1893                                     satype2name(satype),
1894                                     pfkey_socketsp->socketp,
1895                                     error);
1896                         SENDERR(-error);
1897                 }
1898                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
1899                             "sending up update reply message for satype=%d(%s) to socket=%p succeeded.\n",
1900                             satype,
1901                             satype2name(satype),
1902                             pfkey_socketsp->socketp);
1903         }
1904
1905 #ifdef CONFIG_IPSEC_NAT_TRAVERSAL
1906         if (nat_t_tdb_saved) {
1907                 /**
1908                  * As we _really_ update existing SA, we keep tdbq and need to delete
1909                  * parsed tdb (nat_t_tdb_saved, was extr->tdb).
1910                  *
1911                  * goto errlab with extr->tdb = nat_t_tdb_saved will free it.
1912                  */
1913
1914                 extr->tdb = nat_t_tdb_saved;
1915
1916                 error = 0;
1917                 KLIPS_PRINT(debug_pfkey,
1918                     "klips_debug:pfkey_update_parse (NAT-T ports): "
1919                     "successful for SA: %s\n",
1920                     sa_len ? sa : " (error)");
1921
1922                 goto errlab;
1923         }
1924 #endif
1925
1926         if((error = ipsec_sa_put(extr->tdb))) {
1927                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
1928                             "failed to update the mature SA=%s with error=%d.\n",
1929                             sa_len ? sa : " (error)",
1930                             error);
1931                 SENDERR(-error);
1932         }
1933         extr->tdb = NULL;
1934         
1935         KLIPS_PRINT(debug_pfkey,
1936                     "klips_debug:pfkey_update_parse: "
1937                     "successful for SA: %s\n",
1938                     sa_len ? sa : " (error)");
1939         
1940  errlab:
1941         if (pfkey_reply) {
1942                 pfkey_msg_free(&pfkey_reply);
1943         }
1944         pfkey_extensions_free(extensions_reply);
1945         return error;
1946 }
1947
1948 DEBUG_NO_STATIC int
1949 pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
1950 {
1951         int error = 0;
1952         struct ipsec_sa* tdbq;
1953         char sa[SATOA_BUF];
1954         size_t sa_len;
1955         struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
1956         struct sadb_msg *pfkey_reply = NULL;
1957         struct socket_list *pfkey_socketsp;
1958         uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
1959
1960         KLIPS_PRINT(debug_pfkey,
1961                     "klips_debug:pfkey_add_parse: .\n");
1962
1963         pfkey_extensions_init(extensions_reply);
1964
1965         if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
1966                 KLIPS_PRINT(debug_pfkey,
1967                             "klips_debug:pfkey_add_parse: "
1968                             "error, sa_state=%d must be MATURE=%d\n",
1969                             ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
1970                             SADB_SASTATE_MATURE);
1971                 SENDERR(EINVAL);
1972         }
1973
1974         if(!extr || !extr->tdb) {
1975                 KLIPS_PRINT(debug_pfkey,
1976                             "klips_debug:pfkey_add_parse: "
1977                             "extr or extr->tdb pointer NULL\n");
1978                 SENDERR(EINVAL);
1979         }
1980
1981         sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF);
1982
1983         tdbq = ipsec_sa_getbyid(&(extr->tdb->tdb_said));
1984         if (tdbq) {
1985                 KLIPS_PRINT(debug_pfkey,
1986                             "klips_debug:pfkey_add_parse: "
1987                             "found an old Tunnel Descriptor Block for SA%s, delete it first.\n",
1988                             sa_len ? sa : " (error)");
1989                 SENDERR(EEXIST);
1990         }
1991
1992         if(ip_chk_addr((unsigned long)extr->tdb->tdb_said.dst.s_addr) == IS_MYADDR) {
1993                 extr->tdb->tdb_flags |= EMT_INBOUND;
1994         }
1995
1996         KLIPS_PRINT(debug_pfkey,
1997                     "klips_debug:pfkey_add_parse: "
1998                     "existing Tunnel Descriptor Block not found (this is good) for SA%s, %s-bound, allocating.\n",
1999                     sa_len ? sa : " (error)",
2000                     extr->tdb->tdb_flags & EMT_INBOUND ? "in" : "out");
2001         
2002         /* XXX extr->tdb->tdb_rcvif = &(enc_softc[em->em_if].enc_if);*/
2003         extr->tdb->tdb_rcvif = NULL;
2004         
2005         if ((error = pfkey_ipsec_sa_init(extr->tdb, extensions))) {
2006                 KLIPS_PRINT(debug_pfkey,
2007                             "klips_debug:pfkey_add_parse: "
2008                             "not successful for SA: %s, deleting.\n",
2009                             sa_len ? sa : " (error)");
2010                 SENDERR(-error);
2011         }
2012
2013         extr->tdb->ips_life.ipl_addtime.ipl_count = jiffies / HZ;
2014         if(!extr->tdb->ips_life.ipl_allocations.ipl_count) {
2015                 extr->tdb->ips_life.ipl_allocations.ipl_count += 1;
2016         }
2017
2018         if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
2019                                                           SADB_ADD,
2020                                                           satype,
2021                                                           0,
2022                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
2023                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
2024                               extensions_reply)
2025              && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA],
2026                                                         SADB_EXT_SA,
2027                                                         extr->tdb->tdb_said.spi,
2028                                                         extr->tdb->tdb_replaywin,
2029                                                         extr->tdb->tdb_state,
2030                                                         extr->tdb->tdb_authalg,
2031                                                         extr->tdb->tdb_encalg,
2032                                                         extr->tdb->tdb_flags),
2033                                  extensions_reply)
2034              /* The 3 lifetime extentions should only be sent if non-zero. */
2035              && (extensions[SADB_EXT_LIFETIME_HARD]
2036                  ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
2037                                                                  SADB_EXT_LIFETIME_HARD,
2038                                                                  extr->tdb->ips_life.ipl_allocations.ipl_hard,
2039                                                                  extr->tdb->ips_life.ipl_bytes.ipl_hard,
2040                                                                  extr->tdb->ips_life.ipl_addtime.ipl_hard,
2041                                                                  extr->tdb->ips_life.ipl_usetime.ipl_hard,
2042                                                                  extr->tdb->ips_life.ipl_packets.ipl_hard),
2043                                     extensions_reply) : 1)
2044              && (extensions[SADB_EXT_LIFETIME_SOFT]
2045                  ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
2046                                                                  SADB_EXT_LIFETIME_SOFT,
2047                                                                  extr->tdb->ips_life.ipl_allocations.ipl_soft,
2048                                                                  extr->tdb->ips_life.ipl_bytes.ipl_soft,
2049                                                                  extr->tdb->ips_life.ipl_addtime.ipl_soft,
2050                                                                  extr->tdb->ips_life.ipl_usetime.ipl_soft,
2051                                                                  extr->tdb->ips_life.ipl_packets.ipl_soft),
2052                                     extensions_reply) : 1)
2053              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
2054                                                              SADB_EXT_ADDRESS_SRC,
2055                                                              0, /*extr->tdb->tdb_said.proto,*/
2056                                                              0,
2057                                                              extr->tdb->tdb_addr_s),
2058                                  extensions_reply)
2059              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
2060                                                              SADB_EXT_ADDRESS_DST,
2061                                                              0, /*extr->tdb->tdb_said.proto,*/
2062                                                              0,
2063                                                              extr->tdb->tdb_addr_d),
2064                                  extensions_reply)
2065             && (extr->tdb->tdb_ident_s.data
2066                  ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
2067                                                               SADB_EXT_IDENTITY_SRC,
2068                                                               extr->tdb->tdb_ident_s.type,
2069                                                               extr->tdb->tdb_ident_s.id,
2070                                                               extr->tdb->tdb_ident_s.len,
2071                                                               extr->tdb->tdb_ident_s.data),
2072                                     extensions_reply) : 1)
2073             && (extr->tdb->tdb_ident_d.data
2074                  ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
2075                                                               SADB_EXT_IDENTITY_DST,
2076                                                               extr->tdb->tdb_ident_d.type,
2077                                                               extr->tdb->tdb_ident_d.id,
2078                                                               extr->tdb->tdb_ident_d.len,
2079                                                               extr->tdb->tdb_ident_d.data),
2080                                     extensions_reply) : 1)
2081 #if 0
2082              /* FIXME: This won't work yet because I have not finished
2083                 it. */
2084              && (extr->tdb->tdb_sens_
2085                  ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
2086                                                              extr->tdb->tdb_sens_dpd,
2087                                                              extr->tdb->tdb_sens_sens_level,
2088                                                              extr->tdb->tdb_sens_sens_len,
2089                                                              extr->tdb->tdb_sens_sens_bitmap,
2090                                                              extr->tdb->tdb_sens_integ_level,
2091                                                              extr->tdb->tdb_sens_integ_len,
2092                                                              extr->tdb->tdb_sens_integ_bitmap),
2093                                     extensions_reply) : 1)
2094 #endif
2095                 )) {
2096                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
2097                             "failed to build the add reply message extensions\n");
2098                 SENDERR(-error);
2099         }
2100                 
2101         if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
2102                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
2103                             "failed to build the add reply message\n");
2104                 SENDERR(-error);
2105         }
2106         for(pfkey_socketsp = pfkey_open_sockets;
2107             pfkey_socketsp;
2108             pfkey_socketsp = pfkey_socketsp->next) {
2109                 if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
2110                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
2111                                     "sending up add reply message for satype=%d(%s) to socket=%p failed with error=%d.\n",
2112                                     satype,
2113                                     satype2name(satype),
2114                                     pfkey_socketsp->socketp,
2115                                     error);
2116                         SENDERR(-error);
2117                 }
2118                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
2119                             "sending up add reply message for satype=%d(%s) to socket=%p succeeded.\n",
2120                             satype,
2121                             satype2name(satype),
2122                             pfkey_socketsp->socketp);
2123         }
2124
2125         if((error = ipsec_sa_put(extr->tdb))) {
2126                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
2127                             "failed to add the mature SA=%s with error=%d.\n",
2128                             sa_len ? sa : " (error)",
2129                             error);
2130                 SENDERR(-error);
2131         }
2132         extr->tdb = NULL;
2133         
2134         KLIPS_PRINT(debug_pfkey,
2135                     "klips_debug:pfkey_add_parse: "
2136                     "successful for SA: %s\n",
2137                     sa_len ? sa : " (error)");
2138         
2139  errlab:
2140         if (pfkey_reply) {
2141                 pfkey_msg_free(&pfkey_reply);
2142         }
2143         pfkey_extensions_free(extensions_reply);
2144         return error;
2145 }
2146
2147 DEBUG_NO_STATIC int
2148 pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
2149 {
2150         struct ipsec_sa *tdbp;
2151         char sa[SATOA_BUF];
2152         size_t sa_len;
2153         int error = 0;
2154         struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
2155         struct sadb_msg *pfkey_reply = NULL;
2156         struct socket_list *pfkey_socketsp;
2157         uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
2158
2159         KLIPS_PRINT(debug_pfkey,
2160                     "klips_debug:pfkey_delete_parse: .\n");
2161
2162         pfkey_extensions_init(extensions_reply);
2163
2164         if(!extr || !extr->tdb) {
2165                 KLIPS_PRINT(debug_pfkey,
2166                             "klips_debug:pfkey_delete_parse: "
2167                             "extr or extr->tdb pointer NULL, fatal\n");
2168                 SENDERR(EINVAL);
2169         }
2170
2171         sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF);
2172
2173         spin_lock_bh(&tdb_lock);
2174
2175         tdbp = ipsec_sa_getbyid(&(extr->tdb->tdb_said));
2176         if (tdbp == NULL) {
2177                 spin_unlock_bh(&tdb_lock);
2178                 KLIPS_PRINT(debug_pfkey,
2179                             "klips_debug:pfkey_delete_parse: "
2180                             "Tunnel Descriptor Block not found for SA:%s, could not delete.\n",
2181                             sa_len ? sa : " (error)");
2182                 SENDERR(ESRCH);
2183         }
2184
2185         if((error = ipsec_sa_delchain(tdbp))) {
2186                 spin_unlock_bh(&tdb_lock);
2187                 KLIPS_PRINT(debug_pfkey,
2188                             "klips_debug:pfkey_delete_parse: "
2189                             "error=%d returned trying to delete Tunnel Descriptor Block for SA:%s.\n",
2190                             error,
2191                             sa_len ? sa : " (error)");
2192                 SENDERR(-error);
2193         }
2194         spin_unlock_bh(&tdb_lock);
2195
2196         if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
2197                                                           SADB_DELETE,
2198                                                           satype,
2199                                                           0,
2200                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
2201                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
2202                               extensions_reply)
2203              && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA],
2204                                                         SADB_EXT_SA,
2205                                                         extr->tdb->tdb_said.spi,
2206                                                         0,
2207                                                         0,
2208                                                         0,
2209                                                         0,
2210                                                         0),
2211                                  extensions_reply)
2212              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
2213                                                              SADB_EXT_ADDRESS_SRC,
2214                                                              0, /*extr->tdb->tdb_said.proto,*/
2215                                                              0,
2216                                                              extr->tdb->tdb_addr_s),
2217                                  extensions_reply)
2218              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
2219                                                              SADB_EXT_ADDRESS_DST,
2220                                                              0, /*extr->tdb->tdb_said.proto,*/
2221                                                              0,
2222                                                              extr->tdb->tdb_addr_d),
2223                                  extensions_reply)
2224                 )) {
2225                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
2226                             "failed to build the delete reply message extensions\n");
2227                 SENDERR(-error);
2228         }
2229         
2230         if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
2231                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
2232                             "failed to build the delete reply message\n");
2233                 SENDERR(-error);
2234         }
2235         for(pfkey_socketsp = pfkey_open_sockets;
2236             pfkey_socketsp;
2237             pfkey_socketsp = pfkey_socketsp->next) {
2238                 if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
2239                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
2240                                     "sending up delete reply message for satype=%d(%s) to socket=%p failed with error=%d.\n",
2241                                     satype,
2242                                     satype2name(satype),
2243                                     pfkey_socketsp->socketp,
2244                                     error);
2245                         SENDERR(-error);
2246                 }
2247                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
2248                             "sending up delete reply message for satype=%d(%s) to socket=%p succeeded.\n",
2249                             satype,
2250                             satype2name(satype),
2251                             pfkey_socketsp->socketp);
2252         }
2253         
2254  errlab:
2255         if (pfkey_reply) {
2256                 pfkey_msg_free(&pfkey_reply);
2257         }
2258         pfkey_extensions_free(extensions_reply);
2259         return error;
2260 }
2261
2262 DEBUG_NO_STATIC int
2263 pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
2264 {
2265         int error = 0;
2266         struct ipsec_sa *tdbp;
2267         char sa[SATOA_BUF];
2268         size_t sa_len;
2269         struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
2270         struct sadb_msg *pfkey_reply = NULL;
2271
2272         KLIPS_PRINT(debug_pfkey,
2273                     "klips_debug:pfkey_get_parse: .\n");
2274
2275         pfkey_extensions_init(extensions_reply);
2276
2277         if(!extr || !extr->tdb) {
2278                 KLIPS_PRINT(debug_pfkey,
2279                             "klips_debug:pfkey_get_parse: "
2280                             "extr or extr->tdb pointer NULL, fatal\n");
2281                 SENDERR(EINVAL);
2282         }
2283
2284         sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF);
2285
2286         spin_lock_bh(&tdb_lock);
2287
2288         tdbp = ipsec_sa_getbyid(&(extr->tdb->tdb_said));
2289         if (tdbp == NULL) {
2290                 spin_unlock_bh(&tdb_lock);
2291                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
2292                             "Tunnel Descriptor Block not found for SA=%s, could not get.\n",
2293                             sa_len ? sa : " (error)");
2294                 SENDERR(ESRCH);
2295         }
2296         
2297         if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
2298                                                           SADB_GET,
2299                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype,
2300                                                           0,
2301                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
2302                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
2303                               extensions_reply)
2304              && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA],
2305                                                         SADB_EXT_SA,
2306                                                         extr->tdb->tdb_said.spi,
2307                                                         extr->tdb->tdb_replaywin,
2308                                                         extr->tdb->tdb_state,
2309                                                         extr->tdb->tdb_authalg,
2310                                                         extr->tdb->tdb_encalg,
2311                                                         extr->tdb->tdb_flags),
2312                                  extensions_reply)
2313              /* The 3 lifetime extentions should only be sent if non-zero. */
2314              && (tdbp->ips_life.ipl_allocations.ipl_count
2315                  || tdbp->ips_life.ipl_bytes.ipl_count
2316                  || tdbp->ips_life.ipl_addtime.ipl_count
2317                  || tdbp->ips_life.ipl_usetime.ipl_count
2318                  || tdbp->ips_life.ipl_packets.ipl_count
2319                  ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
2320                                                                  SADB_EXT_LIFETIME_CURRENT,
2321                                                                  tdbp->ips_life.ipl_allocations.ipl_count,
2322                                                                  tdbp->ips_life.ipl_bytes.ipl_count,
2323                                                                  tdbp->ips_life.ipl_addtime.ipl_count,
2324                                                                  tdbp->ips_life.ipl_usetime.ipl_count,
2325                                                                  tdbp->ips_life.ipl_packets.ipl_count),
2326                                     extensions_reply) : 1)
2327              && (tdbp->ips_life.ipl_allocations.ipl_hard
2328                  || tdbp->ips_life.ipl_bytes.ipl_hard
2329                  || tdbp->ips_life.ipl_addtime.ipl_hard
2330                  || tdbp->ips_life.ipl_usetime.ipl_hard
2331                  || tdbp->ips_life.ipl_packets.ipl_hard
2332                  ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
2333                                                                  SADB_EXT_LIFETIME_HARD,
2334                                                                  tdbp->ips_life.ipl_allocations.ipl_hard,
2335                                                                  tdbp->ips_life.ipl_bytes.ipl_hard,
2336                                                                  tdbp->ips_life.ipl_addtime.ipl_hard,
2337                                                                  tdbp->ips_life.ipl_usetime.ipl_hard,
2338                                                                  tdbp->ips_life.ipl_packets.ipl_hard),
2339                                     extensions_reply) : 1)
2340              && (tdbp->ips_life.ipl_allocations.ipl_soft
2341                  || tdbp->ips_life.ipl_bytes.ipl_soft
2342                  || tdbp->ips_life.ipl_addtime.ipl_soft
2343                  || tdbp->ips_life.ipl_usetime.ipl_soft
2344                  || tdbp->ips_life.ipl_packets.ipl_soft
2345                  ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
2346                                                                  SADB_EXT_LIFETIME_SOFT,
2347                                                                  tdbp->ips_life.ipl_allocations.ipl_soft,
2348                                                                  tdbp->ips_life.ipl_bytes.ipl_soft,
2349                                                                  tdbp->ips_life.ipl_addtime.ipl_soft,
2350                                                                  tdbp->ips_life.ipl_usetime.ipl_soft,
2351                                                                  tdbp->ips_life.ipl_packets.ipl_soft),
2352                                     extensions_reply) : 1)
2353              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
2354                                                              SADB_EXT_ADDRESS_SRC,
2355                                                              0, /*extr->tdb->tdb_said.proto,*/
2356                                                              0,
2357                                                              extr->tdb->tdb_addr_s),
2358                                  extensions_reply)
2359              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
2360                                                              SADB_EXT_ADDRESS_DST,
2361                                                              0, /*extr->tdb->tdb_said.proto,*/
2362                                                              0,
2363                                                              extr->tdb->tdb_addr_d),
2364                                  extensions_reply)
2365              && (extr->tdb->tdb_addr_p
2366                  ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_PROXY],
2367                                                                 SADB_EXT_ADDRESS_PROXY,
2368                                                                 0, /*extr->tdb->tdb_said.proto,*/
2369                                                                 0,
2370                                                                 extr->tdb->tdb_addr_p),
2371                                     extensions_reply) : 1)
2372 #if 0
2373              /* FIXME: This won't work yet because the keys are not
2374                 stored directly in the tdb.  They are stored as
2375                 contexts. */
2376              && (extr->tdb->tdb_key_a_size
2377                  ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_AUTH],
2378                                                             SADB_EXT_KEY_AUTH,
2379                                                             extr->tdb->tdb_key_a_size * 8,
2380                                                             extr->tdb->tdb_key_a),
2381                                     extensions_reply) : 1)
2382              /* FIXME: This won't work yet because the keys are not
2383                 stored directly in the tdb.  They are stored as
2384                 key schedules. */
2385              && (extr->tdb->tdb_key_e_size
2386                  ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_ENCRYPT],
2387                                                             SADB_EXT_KEY_ENCRYPT,
2388                                                             extr->tdb->tdb_key_e_size * 8,
2389                                                             extr->tdb->tdb_key_e),
2390                                     extensions_reply) : 1)
2391 #endif
2392              && (extr->tdb->tdb_ident_s.data
2393                  ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
2394                                                               SADB_EXT_IDENTITY_SRC,
2395                                                               extr->tdb->tdb_ident_s.type,
2396                                                               extr->tdb->tdb_ident_s.id,
2397                                                               extr->tdb->tdb_ident_s.len,
2398                                                               extr->tdb->tdb_ident_s.data),
2399                                     extensions_reply) : 1)
2400              && (extr->tdb->tdb_ident_d.data
2401                  ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
2402                                                               SADB_EXT_IDENTITY_DST,
2403                                                               extr->tdb->tdb_ident_d.type,
2404                                                               extr->tdb->tdb_ident_d.id,
2405                                                               extr->tdb->tdb_ident_d.len,
2406                                                               extr->tdb->tdb_ident_d.data),
2407                                     extensions_reply) : 1)
2408 #if 0
2409              /* FIXME: This won't work yet because I have not finished
2410                 it. */
2411              && (extr->tdb->tdb_sens_
2412                  ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
2413                                                              extr->tdb->tdb_sens_dpd,
2414                                                              extr->tdb->tdb_sens_sens_level,
2415                                                              extr->tdb->tdb_sens_sens_len,
2416                                                              extr->tdb->tdb_sens_sens_bitmap,
2417                                                              extr->tdb->tdb_sens_integ_level,
2418                                                              extr->tdb->tdb_sens_integ_len,
2419                                                              extr->tdb->tdb_sens_integ_bitmap),
2420                                     extensions_reply) : 1)
2421 #endif
2422                      )) {
2423                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
2424                             "failed to build the get reply message extensions\n");
2425                 spin_unlock_bh(&tdb_lock);
2426                 SENDERR(-error);
2427         }
2428                 
2429         spin_unlock_bh(&tdb_lock);
2430         
2431         if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
2432                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
2433                             "failed to build the get reply message\n");
2434                 SENDERR(-error);
2435         }
2436         
2437         if((error = pfkey_upmsg(sk->socket, pfkey_reply))) {
2438                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
2439                             "failed to send the get reply message\n");
2440                 SENDERR(-error);
2441         }
2442         
2443         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
2444                     "succeeded in sending get reply message.\n");
2445         
2446  errlab:
2447         if (pfkey_reply) {
2448                 pfkey_msg_free(&pfkey_reply);
2449         }
2450         pfkey_extensions_free(extensions_reply);
2451         return error;
2452 }
2453
2454 DEBUG_NO_STATIC int
2455 pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
2456 {
2457         int error = 0;
2458         struct socket_list *pfkey_socketsp;
2459         uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
2460
2461         KLIPS_PRINT(debug_pfkey,
2462                     "klips_debug:pfkey_acquire_parse: .\n");
2463
2464         /* XXX I don't know if we want an upper bound, since userspace may
2465            want to register itself for an satype > SADB_SATYPE_MAX. */
2466         if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
2467                 KLIPS_PRINT(debug_pfkey,
2468                             "klips_debug:pfkey_acquire_parse: "
2469                             "SATYPE=%d invalid.\n",
2470                             satype);
2471                 SENDERR(EINVAL);
2472         }
2473
2474         if(!(pfkey_registered_sockets[satype])) {
2475                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
2476                             "no sockets registered for SAtype=%d(%s).\n",
2477                             satype,
2478                             satype2name(satype));
2479                 SENDERR(EPROTONOSUPPORT);
2480         }
2481
2482         for(pfkey_socketsp = pfkey_registered_sockets[satype];
2483             pfkey_socketsp;
2484             pfkey_socketsp = pfkey_socketsp->next) {
2485                 if((error = pfkey_upmsg(pfkey_socketsp->socketp,
2486                                         ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
2487                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
2488                                     "sending up acquire reply message for satype=%d(%s) to socket=%p failed with error=%d.\n",
2489                                     satype,
2490                                     satype2name(satype),
2491                                     pfkey_socketsp->socketp,
2492                                     error);
2493                         SENDERR(-error);
2494                 }
2495                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
2496                             "sending up acquire reply message for satype=%d(%s) to socket=%p succeeded.\n",
2497                             satype,
2498                             satype2name(satype),
2499                             pfkey_socketsp->socketp);
2500         }
2501         
2502  errlab:
2503         return error;
2504 }
2505
2506 DEBUG_NO_STATIC int
2507 pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
2508 {
2509         int error = 0;
2510         uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
2511
2512         KLIPS_PRINT(debug_pfkey,
2513                     "klips_debug:pfkey_register_parse: .\n");
2514
2515         /* XXX I don't know if we want an upper bound, since userspace may
2516            want to register itself for an satype > SADB_SATYPE_MAX. */
2517         if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
2518                 KLIPS_PRINT(debug_pfkey,
2519                             "klips_debug:pfkey_register_parse: "
2520                             "SATYPE=%d invalid.\n",
2521                             satype);
2522                 SENDERR(EINVAL);
2523         }
2524
2525         if(!pfkey_list_insert_socket(sk->socket,
2526                                  &(pfkey_registered_sockets[satype]))) {
2527                 KLIPS_PRINT(debug_pfkey,
2528                             "klips_debug:pfkey_register_parse: "
2529                             "SATYPE=%02d(%s) successfully registered by KMd (pid=%d).\n",
2530                             satype,
2531                             satype2name(satype),
2532                             key_pid(sk));
2533         };
2534         
2535         /* send up register msg with supported SATYPE algos */
2536
2537         error=pfkey_register_reply(satype, (struct sadb_msg*)extensions[SADB_EXT_RESERVED]);
2538  errlab:
2539         return error;
2540 }
2541 #ifdef USE_IXP4XX_CRYPTO
2542 DEBUG_NO_STATIC 
2543 #endif /* USE_IXP4XX_CRYPTO */
2544 int
2545 pfkey_register_reply(int satype, struct sadb_msg *sadb_msg)
2546 {
2547         struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
2548         struct sadb_msg *pfkey_reply = NULL;
2549         struct socket_list *pfkey_socketsp;
2550         struct supported_list *pfkey_supported_listp;
2551         unsigned int alg_num_a = 0, alg_num_e = 0;
2552         struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL;
2553         int error = 0;
2554
2555         pfkey_extensions_init(extensions_reply);
2556
2557         if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
2558                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
2559                             "SAtype=%d unspecified or unknown.\n",
2560                             satype);
2561                 SENDERR(EINVAL);
2562         }
2563         if(!(pfkey_registered_sockets[satype])) {
2564                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
2565                             "no sockets registered for SAtype=%d(%s).\n",
2566                             satype,
2567                             satype2name(satype));
2568                 SENDERR(EPROTONOSUPPORT);
2569         }
2570         /* send up register msg with supported SATYPE algos */
2571         pfkey_supported_listp = pfkey_supported_list[satype];
2572         KLIPS_PRINT(debug_pfkey,
2573                     "klips_debug:pfkey_register_reply: "
2574                     "pfkey_supported_list[%d]=%p\n",
2575                     satype,
2576                     pfkey_supported_list[satype]);
2577         while(pfkey_supported_listp) {
2578                 KLIPS_PRINT(debug_pfkey,
2579                             "klips_debug:pfkey_register_reply: "
2580                             "checking supported=%p\n",
2581                             pfkey_supported_listp);
2582                 if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) {
2583                         KLIPS_PRINT(debug_pfkey,
2584                                     "klips_debug:pfkey_register_reply: "
2585                                     "adding auth alg.\n");
2586                         alg_num_a++;
2587                 }
2588                 if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
2589                         KLIPS_PRINT(debug_pfkey,
2590                                     "klips_debug:pfkey_register_reply: "
2591                                     "adding encrypt alg.\n");
2592                         alg_num_e++;
2593                 }
2594                 pfkey_supported_listp = pfkey_supported_listp->next;
2595         }
2596
2597         if(alg_num_a) {
2598                 if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
2599                         KLIPS_PRINT(debug_pfkey,
2600                                     "klips_debug:pfkey_register_reply: "
2601                                     "auth alg memory allocation error\n");
2602                         SENDERR(ENOMEM);
2603                 }
2604                 alg_ap = alg_a;
2605         }
2606         
2607         if(alg_num_e) {
2608                 if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
2609                         KLIPS_PRINT(debug_pfkey,
2610                                     "klips_debug:pfkey_register_reply: "
2611                                     "enc alg memory allocation error\n");
2612                         SENDERR(ENOMEM);
2613                 }
2614                 alg_ep = alg_e;
2615         }
2616         
2617         pfkey_supported_listp = pfkey_supported_list[satype];
2618         while(pfkey_supported_listp) {
2619                 if(alg_num_a) {
2620                         if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) {
2621                                 alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id;
2622                                 alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen;
2623                                 alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits;
2624                                 alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits;
2625                                 alg_ap->sadb_alg_reserved = 0;
2626                                 KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
2627                                             "klips_debug:pfkey_register_reply: "
2628                                             "adding auth=%p\n",
2629                                             alg_ap);
2630                                 alg_ap++;
2631                         }
2632                 }
2633                 if(alg_num_e) {
2634                         if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
2635                                 alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id;
2636                                 alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen;
2637                                 alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits;
2638                                 alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits;
2639                                 alg_ep->sadb_alg_reserved = 0;
2640                                 KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
2641                                             "klips_debug:pfkey_register_reply: "
2642                                             "adding encrypt=%p\n",
2643                                             alg_ep);
2644                                 alg_ep++;
2645                         }
2646                 }
2647                 KLIPS_PRINT(debug_pfkey,
2648                             "klips_debug:pfkey_register_reply: "
2649                             "found satype=%d(%s) exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
2650                             satype,
2651                             satype2name(satype),
2652                             pfkey_supported_listp->supportedp->supported_alg_exttype,
2653                             pfkey_supported_listp->supportedp->supported_alg_id,
2654                             pfkey_supported_listp->supportedp->supported_alg_ivlen,
2655                             pfkey_supported_listp->supportedp->supported_alg_minbits,
2656                             pfkey_supported_listp->supportedp->supported_alg_maxbits);
2657                 pfkey_supported_listp = pfkey_supported_listp->next;
2658         }
2659         if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
2660                                                           SADB_REGISTER,
2661                                                           satype,
2662                                                           0,
2663                                                           sadb_msg? sadb_msg->sadb_msg_seq : ++pfkey_msg_seq,
2664                                                           sadb_msg? sadb_msg->sadb_msg_pid: current->pid),
2665                               extensions_reply) &&
2666              (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_AUTH],
2667                                                                         SADB_EXT_SUPPORTED_AUTH,
2668                                                                         alg_num_a,
2669                                                                         alg_a),
2670                                           extensions_reply) : 1) &&
2671              (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_ENCRYPT],
2672                                                                         SADB_EXT_SUPPORTED_ENCRYPT,
2673                                                                         alg_num_e,
2674                                                                         alg_e),
2675                                           extensions_reply) : 1))) {
2676                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
2677                             "failed to build the register message extensions_reply\n");
2678                 SENDERR(-error);
2679         }
2680         
2681         if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
2682                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
2683                             "failed to build the register message\n");
2684                 SENDERR(-error);
2685         }
2686         /* this should go to all registered sockets for that satype only */
2687         for(pfkey_socketsp = pfkey_registered_sockets[satype];
2688             pfkey_socketsp;
2689             pfkey_socketsp = pfkey_socketsp->next) {
2690                 if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
2691                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
2692                                     "sending up acquire message for satype=%d(%s) to socket=%p failed with error=%d.\n",
2693                                     satype,
2694                                     satype2name(satype),
2695                                     pfkey_socketsp->socketp,
2696                                     error);
2697                         SENDERR(-error);
2698                 }
2699                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
2700                             "sending up register message for satype=%d(%s) to socket=%p succeeded.\n",
2701                             satype,
2702                             satype2name(satype),
2703                             pfkey_socketsp->socketp);
2704         }
2705         
2706  errlab:
2707         if(alg_a) {
2708                 kfree(alg_a);
2709         }
2710         if(alg_e) {
2711                 kfree(alg_e);
2712         }
2713         if (pfkey_reply) {
2714                 pfkey_msg_free(&pfkey_reply);
2715         }
2716         pfkey_extensions_free(extensions_reply);
2717         return error;
2718 }
2719
2720 DEBUG_NO_STATIC int
2721 pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
2722 {
2723         int error = 0;
2724         struct socket_list *pfkey_socketsp;
2725 #ifdef CONFIG_IPSEC_DEBUG
2726         uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
2727 #endif /* CONFIG_IPSEC_DEBUG */
2728
2729         KLIPS_PRINT(debug_pfkey,
2730                     "klips_debug:pfkey_expire_parse: .\n");
2731
2732         if(pfkey_open_sockets) {
2733                 for(pfkey_socketsp = pfkey_open_sockets;
2734                     pfkey_socketsp;
2735                     pfkey_socketsp = pfkey_socketsp->next) {
2736                         if((error = pfkey_upmsg(pfkey_socketsp->socketp,
2737                                                 ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
2738                                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
2739                                             "sending up expire reply message for satype=%d(%s) to socket=%p failed with error=%d.\n",
2740                                             satype,
2741                                             satype2name(satype),
2742                                             pfkey_socketsp->socketp,
2743                                             error);
2744                                 SENDERR(-error);
2745                         }
2746                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
2747                                     "sending up expire reply message for satype=%d(%s) to socket=%p succeeded.\n",
2748                                     satype,
2749                                     satype2name(satype),
2750                                     pfkey_socketsp->socketp);
2751                 }
2752         }
2753
2754  errlab:
2755         return error;
2756 }
2757
2758 DEBUG_NO_STATIC int
2759 pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
2760 {
2761         int error = 0;
2762         struct socket_list *pfkey_socketsp;
2763         uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
2764         uint8_t proto = 0;
2765
2766         KLIPS_PRINT(debug_pfkey,
2767                     "klips_debug:pfkey_flush_parse: "
2768                     "flushing type %d SAs\n",
2769                     satype);
2770
2771         if(satype && !(proto = satype2proto(satype))) {
2772                 KLIPS_PRINT(debug_pfkey,
2773                             "klips_debug:pfkey_flush_parse: "
2774                             "satype %d lookup failed.\n", 
2775                             ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
2776                 SENDERR(EINVAL);
2777         }
2778
2779         if ((error = ipsec_sadb_cleanup(proto))) {
2780                 SENDERR(-error);
2781         }
2782
2783         if(pfkey_open_sockets) {
2784                 for(pfkey_socketsp = pfkey_open_sockets;
2785                     pfkey_socketsp;
2786                     pfkey_socketsp = pfkey_socketsp->next) {
2787                         if((error = pfkey_upmsg(pfkey_socketsp->socketp,
2788                                                 ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
2789                                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
2790                                             "sending up flush reply message for satype=%d(%s) (proto=%d) to socket=%p failed with error=%d.\n",
2791                                             satype,
2792                                             satype2name(satype),
2793                                             proto,
2794                                             pfkey_socketsp->socketp,
2795                                             error);
2796                                 SENDERR(-error);
2797                         }
2798                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
2799                                     "sending up flush reply message for satype=%d(%s) to socket=%p succeeded.\n",
2800                                     satype,
2801                                     satype2name(satype),
2802                                     pfkey_socketsp->socketp);
2803                 }
2804         }
2805
2806  errlab:
2807         return error;
2808 }
2809
2810 DEBUG_NO_STATIC int
2811 pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
2812 {
2813         int error = 0;
2814
2815         KLIPS_PRINT(debug_pfkey,
2816                     "klips_debug:pfkey_dump_parse: .\n");
2817
2818         SENDERR(ENOSYS);
2819  errlab:
2820         return error;
2821 }
2822
2823 DEBUG_NO_STATIC int
2824 pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
2825 {
2826         int error = 0;
2827
2828         KLIPS_PRINT(debug_pfkey,
2829                     "klips_debug:pfkey_promisc_parse: .\n");
2830
2831         SENDERR(ENOSYS);
2832  errlab:
2833         return error;
2834 }
2835
2836 DEBUG_NO_STATIC int
2837 pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
2838 {
2839         int error = 0;
2840
2841         KLIPS_PRINT(debug_pfkey,
2842                     "klips_debug:pfkey_x_pchange_parse: .\n");
2843
2844         SENDERR(ENOSYS);
2845  errlab:
2846         return error;
2847 }
2848
2849 DEBUG_NO_STATIC int
2850 pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
2851 {
2852         struct ipsec_sa *tdb1p, *tdb2p, *tdbp;
2853         struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
2854         struct sadb_msg *pfkey_reply = NULL;
2855         struct socket_list *pfkey_socketsp;
2856         uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
2857         char sa1[SATOA_BUF], sa2[SATOA_BUF];
2858         size_t sa_len1, sa_len2 = 0;
2859         int error = 0;
2860
2861         KLIPS_PRINT(debug_pfkey,
2862                     "klips_debug:pfkey_x_grpsa_parse: .\n");
2863
2864         pfkey_extensions_init(extensions_reply);
2865
2866         if(!extr || !extr->tdb) {
2867                 KLIPS_PRINT(debug_pfkey,
2868                             "klips_debug:pfkey_x_grpsa_parse: "
2869                             "extr or extr->tdb is NULL, fatal.\n");
2870                 SENDERR(EINVAL);
2871         }
2872
2873         sa_len1 = satoa(extr->tdb->tdb_said, 0, sa1, SATOA_BUF);
2874         if(extr->tdb2) {
2875                 sa_len2 = satoa(extr->tdb2->tdb_said, 0, sa2, SATOA_BUF);
2876         }
2877
2878         spin_lock_bh(&tdb_lock);
2879
2880         if(!(tdb1p = ipsec_sa_getbyid(&(extr->tdb->tdb_said)))) {
2881                 spin_unlock_bh(&tdb_lock);
2882                 KLIPS_PRINT(debug_pfkey,
2883                             "klips_debug:pfkey_x_grpsa_parse: "
2884                             "reserved Tunnel Descriptor Block for SA: %s not found.  Call SADB_ADD/UPDATE first.\n",
2885                             sa_len1 ? sa1 : " (error)");
2886                 SENDERR(ENOENT);
2887         }
2888         if(extr->tdb2) { /* GRPSA */
2889                 if(!(tdb2p = ipsec_sa_getbyid(&(extr->tdb2->tdb_said)))) {
2890                         spin_unlock_bh(&tdb_lock);
2891                         KLIPS_PRINT(debug_pfkey,
2892                                     "klips_debug:pfkey_x_grpsa_parse: "
2893                                     "reserved Tunnel Descriptor Block for SA: %s not found.  Call SADB_ADD/UPDATE first.\n",
2894                                     sa_len2 ? sa2 : " (error)");
2895                         SENDERR(ENOENT);
2896                 }
2897
2898                 /* Is either one already linked? */
2899                 if(tdb1p->tdb_onext) {
2900                         spin_unlock_bh(&tdb_lock);
2901                         KLIPS_PRINT(debug_pfkey,
2902                                     "klips_debug:pfkey_x_grpsa_parse: "
2903                                     "Tunnel Descriptor Block for SA: %s is already linked.\n",
2904                                     sa_len1 ? sa1 : " (error)");
2905                         SENDERR(EEXIST);
2906                 }
2907                 if(tdb2p->tdb_inext) {
2908                         spin_unlock_bh(&tdb_lock);
2909                         KLIPS_PRINT(debug_pfkey,
2910                                     "klips_debug:pfkey_x_grpsa_parse: "
2911                                     "Tunnel Descriptor Block for SA: %s is already linked.\n",
2912                                     sa_len2 ? sa2 : " (error)");
2913                         SENDERR(EEXIST);
2914                 }
2915                 
2916                 /* Is extr->tdb already linked to extr->tdb2? */
2917                 tdbp = tdb2p;
2918                 while(tdbp) {
2919                         if(tdbp == tdb1p) {
2920                                 spin_unlock_bh(&tdb_lock);
2921                                 KLIPS_PRINT(debug_pfkey,
2922                                             "klips_debug:pfkey_x_grpsa_parse: "
2923                                             "Tunnel Descriptor Block for SA: %s is already linked to %s.\n",
2924                                             sa_len1 ? sa1 : " (error)",
2925                                             sa_len2 ? sa2 : " (error)");
2926                                 SENDERR(EEXIST);
2927                         }
2928                         tdbp = tdb2p->tdb_onext;
2929                 }
2930                 
2931                 /* link 'em */
2932                 tdb1p->tdb_onext = tdb2p;
2933                 tdb2p->tdb_inext = tdb1p;
2934         } else { /* UNGRPSA */
2935                 while(tdb1p->tdb_onext) {
2936                         tdb1p = tdb1p->tdb_onext;
2937                 }
2938                 while(tdb1p->tdb_inext) {
2939                         tdbp = tdb1p;
2940                         tdb1p = tdb1p->tdb_inext;
2941                         tdbp->tdb_inext = NULL;
2942                         tdb1p->tdb_onext = NULL;
2943                 }
2944         }
2945
2946         spin_unlock_bh(&tdb_lock);
2947
2948         if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
2949                                                           SADB_X_GRPSA,
2950                                                           satype,
2951                                                           0,
2952                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
2953                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
2954                               extensions_reply)
2955              && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA],
2956                                                         SADB_EXT_SA,
2957                                                         extr->tdb->tdb_said.spi,
2958                                                         extr->tdb->tdb_replaywin,
2959                                                         extr->tdb->tdb_state,
2960                                                         extr->tdb->tdb_authalg,
2961                                                         extr->tdb->tdb_encalg,
2962                                                         extr->tdb->tdb_flags),
2963                                  extensions_reply)
2964              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
2965                                                              SADB_EXT_ADDRESS_DST,
2966                                                              0, /*extr->tdb->tdb_said.proto,*/
2967                                                              0,
2968                                                              extr->tdb->tdb_addr_d),
2969                                  extensions_reply)
2970              && (extr->tdb2
2971                  ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[SADB_X_EXT_SATYPE2],
2972                                                                   ((struct sadb_x_satype*)extensions[SADB_X_EXT_SATYPE2])->sadb_x_satype_satype
2973                                                                   /* proto2satype(extr->tdb2->tdb_said.proto) */),
2974                                                                   extensions_reply)
2975                                      && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_X_EXT_SA2],
2976                                                                                 SADB_X_EXT_SA2,
2977                                                                                 extr->tdb2->tdb_said.spi,
2978                                                                                 extr->tdb2->tdb_replaywin,
2979                                                                                 extr->tdb2->tdb_state,
2980                                                                                 extr->tdb2->tdb_authalg,
2981                                                                                 extr->tdb2->tdb_encalg,
2982                                                                                 extr->tdb2->tdb_flags),
2983                                                          extensions_reply)
2984                                      && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST2],
2985                                                                                      SADB_X_EXT_ADDRESS_DST2,
2986                                                                                      0, /*extr->tdb->tdb_said.proto,*/
2987                                                                                      0,
2988                                                                                      extr->tdb2->tdb_addr_d),
2989                                                          extensions_reply) ) : 1 )
2990                      )) {
2991                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
2992                             "failed to build the x_grpsa reply message extensions\n");
2993                 SENDERR(-error);
2994         }
2995            
2996         if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
2997                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
2998                             "failed to build the x_grpsa reply message\n");
2999                 SENDERR(-error);
3000         }
3001         
3002         for(pfkey_socketsp = pfkey_open_sockets;
3003             pfkey_socketsp;
3004             pfkey_socketsp = pfkey_socketsp->next) {
3005                 if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
3006                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
3007                                     "sending up x_grpsa reply message for satype=%d(%s) to socket=%p failed with error=%d.\n",
3008                                     satype,
3009                                     satype2name(satype),
3010                                     pfkey_socketsp->socketp,
3011                                     error);
3012                         SENDERR(-error);
3013                 }
3014                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
3015                             "sending up x_grpsa reply message for satype=%d(%s) to socket=%p succeeded.\n",
3016                             satype,
3017                             satype2name(satype),
3018                             pfkey_socketsp->socketp);
3019         }
3020         
3021         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
3022                     "succeeded in sending x_grpsa reply message.\n");
3023         
3024  errlab:
3025         if (pfkey_reply) {
3026                 pfkey_msg_free(&pfkey_reply);
3027         }
3028         pfkey_extensions_free(extensions_reply);
3029         return error;
3030 }
3031
3032 DEBUG_NO_STATIC int
3033 pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
3034 {
3035         int error = 0;
3036 #ifdef CONFIG_IPSEC_DEBUG
3037         char buf1[64], buf2[64];
3038 #endif /* CONFIG_IPSEC_DEBUG */
3039         struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
3040         struct sadb_msg *pfkey_reply = NULL;
3041         struct socket_list *pfkey_socketsp;
3042         uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
3043         ip_address srcflow, dstflow, srcmask, dstmask;
3044
3045         KLIPS_PRINT(debug_pfkey,
3046                     "klips_debug:pfkey_x_addflow_parse: .\n");
3047
3048         pfkey_extensions_init(extensions_reply);
3049
3050         memset((caddr_t)&srcflow, 0, sizeof(srcflow));
3051         memset((caddr_t)&dstflow, 0, sizeof(dstflow));
3052         memset((caddr_t)&srcmask, 0, sizeof(srcmask));
3053         memset((caddr_t)&dstmask, 0, sizeof(dstmask));
3054
3055         if(!extr || !(extr->tdb) || !(extr->eroute)) {
3056                 KLIPS_PRINT(debug_pfkey,
3057                             "klips_debug:pfkey_x_addflow_parse: "
3058                             "missing extr, tdb or eroute data.\n");
3059                 SENDERR(EINVAL);
3060         }
3061
3062         srcflow.u.v4.sin_family = AF_INET;
3063         dstflow.u.v4.sin_family = AF_INET;
3064         srcmask.u.v4.sin_family = AF_INET;
3065         dstmask.u.v4.sin_family = AF_INET;
3066         srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
3067         dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
3068         srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
3069         dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
3070
3071 #ifdef CONFIG_IPSEC_DEBUG
3072         if (debug_pfkey) {
3073                 subnettoa(extr->eroute->er_eaddr.sen_ip_src,
3074                           extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
3075                 subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
3076                           extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
3077                 KLIPS_PRINT(debug_pfkey,
3078                             "klips_debug:pfkey_x_addflow_parse: "
3079                             "calling breakeroute and/or makeroute for %s->%s\n",
3080                             buf1, buf2);
3081         }
3082 #endif /* CONFIG_IPSEC_DEBUG */
3083         if(extr->tdb->tdb_flags & SADB_X_SAFLAGS_INFLOW) {
3084 /*      if(ip_chk_addr((unsigned long)extr->tdb->tdb_said.dst.s_addr) == IS_MYADDR) */ 
3085                 struct ipsec_sa *tdbp;
3086                 char sa[SATOA_BUF];
3087                 size_t sa_len;
3088
3089                 if((tdbp = ipsec_sa_getbyid(&(extr->tdb->tdb_said))) == NULL) {
3090                         KLIPS_PRINT(debug_pfkey,
3091                                     "klips_debug:pfkey_x_addflow_parse: "
3092                                     "tdb not found, cannot set incoming policy.\n");
3093                         SENDERR(ENOENT);
3094                 }
3095
3096                 while(tdbp && tdbp->tdb_said.proto != IPPROTO_IPIP) {
3097                         tdbp = tdbp->tdb_inext;
3098                 }
3099
3100                 if(tdbp == NULL) {
3101                         KLIPS_PRINT(debug_pfkey,
3102                                     "klips_debug:pfkey_x_addflow_parse: "
3103                                     "SA chain does not have an IPIP SA, cannot set incoming policy.\n");
3104                         SENDERR(ENOENT);
3105                 }
3106
3107                 sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF);
3108
3109 /*              tdbp->tdb_flow_s.u.v4.sin_addr = srcflow.u.v4.sin_addr;
3110                 tdbp->tdb_flow_d.u.v4.sin_addr = dstflow.u.v4.sin_addr;
3111                 tdbp->tdb_mask_s.u.v4.sin_addr = srcmask.u.v4.sin_addr;
3112                 tdbp->tdb_mask_d.u.v4.sin_addr = dstmask.u.v4.sin_addr; */
3113
3114                 tdbp->tdb_flags |= SADB_X_SAFLAGS_INFLOW;
3115                 tdbp->tdb_flow_s = srcflow;
3116                 tdbp->tdb_flow_d = dstflow;
3117                 tdbp->tdb_mask_s = srcmask;
3118                 tdbp->tdb_mask_d = dstmask;
3119
3120                 KLIPS_PRINT(debug_pfkey,
3121                             "klips_debug:pfkey_x_addflow_parse: "
3122                             "inbound eroute, setting incoming policy information in IPIP Tunnel Descriptor Block for SA: %s.\n",
3123                             sa_len ? sa : " (error)");
3124         } else {
3125                 struct sk_buff *first = NULL, *last = NULL;
3126
3127                 if(extr->tdb->tdb_flags & SADB_X_SAFLAGS_REPLACEFLOW) {
3128                         KLIPS_PRINT(debug_pfkey,
3129                                     "klips_debug:pfkey_x_addflow_parse: "
3130                                     "REPLACEFLOW flag set, calling breakeroute.\n");
3131                         if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr),
3132                                                       &(extr->eroute->er_emask),
3133                                                       &first, &last))) {
3134                                 KLIPS_PRINT(debug_pfkey,
3135                                             "klips_debug:pfkey_x_addflow_parse: "
3136                                             "breakeroute returned %d.  first=%p, last=%p\n",
3137                                             error,
3138                                             first,
3139                                             last);
3140                                 if(first != NULL) {
3141 #ifdef USE_IXP4XX_CRYPTO
3142                                         kfree_skb(first);
3143 #else
3144                                         dev_kfree_skb(first, FREE_WRITE);
3145 #endif /* USE_IXP4XX_CRYPTO */
3146                                 }
3147                                 if(last != NULL) {
3148 #ifdef USE_IXP4XX_CRYPTO
3149                                         kfree_skb(last);
3150 #else
3151                                         dev_kfree_skb(last, FREE_WRITE);
3152 #endif /* USE_IXP4XX_CRYPTO */
3153                                 }
3154                                 SENDERR(-error);
3155                         }
3156                 }
3157                 
3158                 KLIPS_PRINT(debug_pfkey,
3159                             "klips_debug:pfkey_x_addflow_parse: "
3160                             "calling makeroute.\n");
3161                 
3162                 if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr),
3163                                              &(extr->eroute->er_emask),
3164                                              extr->tdb->tdb_said,
3165                                              ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid,
3166                                              NULL,
3167                                              &(extr->tdb->tdb_ident_s),
3168                                              &(extr->tdb->tdb_ident_d)))) {
3169                         KLIPS_PRINT(debug_pfkey,
3170                                     "klips_debug:pfkey_x_addflow_parse: "
3171                                     "makeroute returned %d.\n", error);
3172                         SENDERR(-error);
3173                 }
3174                 if(first != NULL) {
3175                         KLIPS_PRINT(debug_pfkey,
3176                                     "klips_debug:pfkey_x_addflow_parse: "
3177                                     "first=%p HOLD packet re-injected.\n",
3178                                     first);
3179                         /* ipsec_tunnel_start_xmit(first, first->dev); */
3180                         DEV_QUEUE_XMIT(first, first->dev, SOPRI_NORMAL);
3181                 }
3182                 if(last != NULL) {
3183                         KLIPS_PRINT(debug_pfkey,
3184                                     "klips_debug:pfkey_x_addflow_parse: "
3185                                     "last=%p HOLD packet re-injected.\n",
3186                                     last);
3187                         /* ipsec_tunnel_start_xmit(last, last->dev); */
3188                         DEV_QUEUE_XMIT(last, last->dev, SOPRI_NORMAL);
3189                 }
3190         }
3191
3192         KLIPS_PRINT(debug_pfkey,
3193                     "klips_debug:pfkey_x_addflow_parse: "
3194                     "makeroute call successful.\n");
3195
3196         if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
3197                                                           SADB_X_ADDFLOW,
3198                                                           satype,
3199                                                           0,
3200                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
3201                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
3202                               extensions_reply)
3203              && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA],
3204                                                         SADB_EXT_SA,
3205                                                         extr->tdb->tdb_said.spi,
3206                                                         extr->tdb->tdb_replaywin,
3207                                                         extr->tdb->tdb_state,
3208                                                         extr->tdb->tdb_authalg,
3209                                                         extr->tdb->tdb_encalg,
3210                                                         extr->tdb->tdb_flags),
3211                                  extensions_reply)
3212              && (extensions[SADB_EXT_ADDRESS_SRC]
3213                  ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
3214                                                                 SADB_EXT_ADDRESS_SRC,
3215                                                                 0, /*extr->tdb->tdb_said.proto,*/
3216                                                                 0,
3217                                                                 extr->tdb->tdb_addr_s),
3218                                     extensions_reply) : 1)
3219              && (extensions[SADB_EXT_ADDRESS_DST]
3220                  ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
3221                                                                 SADB_EXT_ADDRESS_DST,
3222                                                                 0, /*extr->tdb->tdb_said.proto,*/
3223                                                                 0,
3224                                                                 extr->tdb->tdb_addr_d),
3225                                     extensions_reply) : 1)
3226              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
3227                                                              SADB_X_EXT_ADDRESS_SRC_FLOW,
3228                                                              0, /*extr->tdb->tdb_said.proto,*/
3229                                                              0,
3230                                                              (struct sockaddr*)&srcflow),
3231                                  extensions_reply)
3232              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
3233                                                              SADB_X_EXT_ADDRESS_DST_FLOW,
3234                                                              0, /*extr->tdb->tdb_said.proto,*/
3235                                                              0,
3236                                                              (struct sockaddr*)&dstflow),
3237                                  extensions_reply)
3238              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
3239                                                              SADB_X_EXT_ADDRESS_SRC_MASK,
3240                                                              0, /*extr->tdb->tdb_said.proto,*/
3241                                                              0,
3242                                                              (struct sockaddr*)&srcmask),
3243                                  extensions_reply)
3244              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
3245                                                              SADB_X_EXT_ADDRESS_DST_MASK,
3246                                                              0, /*extr->tdb->tdb_said.proto,*/
3247                                                              0,
3248                                                              (struct sockaddr*)&dstmask),
3249                                  extensions_reply)
3250                 )) {
3251                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
3252                             "failed to build the x_addflow reply message extensions\n");
3253                 SENDERR(-error);
3254         }
3255                 
3256         if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
3257                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
3258                             "failed to build the x_addflow reply message\n");
3259                 SENDERR(-error);
3260         }
3261         
3262         for(pfkey_socketsp = pfkey_open_sockets;
3263             pfkey_socketsp;
3264             pfkey_socketsp = pfkey_socketsp->next) {
3265                 if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
3266                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
3267                                     "sending up x_addflow reply message for satype=%d(%s) to socket=%p failed with error=%d.\n",
3268                                     satype,
3269                                     satype2name(satype),
3270                                     pfkey_socketsp->socketp,
3271                                     error);
3272                         SENDERR(-error);
3273                 }
3274                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
3275                             "sending up x_addflow reply message for satype=%d(%s) (proto=%d) to socket=%p succeeded.\n",
3276                             satype,
3277                             satype2name(satype),
3278                             extr->tdb->tdb_said.proto,
3279                             pfkey_socketsp->socketp);
3280         }
3281         
3282         KLIPS_PRINT(debug_pfkey,
3283                     "klips_debug:pfkey_x_addflow_parse: "
3284                     "extr->tdb cleaned up and freed.\n");
3285
3286  errlab:
3287         if (pfkey_reply) {
3288                 pfkey_msg_free(&pfkey_reply);
3289         }
3290         pfkey_extensions_free(extensions_reply);
3291         return error;
3292 }
3293
3294 DEBUG_NO_STATIC int
3295 pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
3296 {
3297         int error = 0;
3298 #ifdef CONFIG_IPSEC_DEBUG
3299         char buf1[64], buf2[64];
3300 #endif /* CONFIG_IPSEC_DEBUG */
3301         struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
3302         struct sadb_msg *pfkey_reply = NULL;
3303         struct socket_list *pfkey_socketsp;
3304         uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
3305         ip_address srcflow, dstflow, srcmask, dstmask;
3306
3307         KLIPS_PRINT(debug_pfkey,
3308                     "klips_debug:pfkey_x_delflow_parse: .\n");
3309
3310         pfkey_extensions_init(extensions_reply);
3311
3312         memset((caddr_t)&srcflow, 0, sizeof(srcflow));
3313         memset((caddr_t)&dstflow, 0, sizeof(dstflow));
3314         memset((caddr_t)&srcmask, 0, sizeof(srcmask));
3315         memset((caddr_t)&dstmask, 0, sizeof(dstmask));
3316
3317         if(!extr || !(extr->tdb)) {
3318                 KLIPS_PRINT(debug_pfkey,
3319                             "klips_debug:pfkey_x_delflow_parse: "
3320                             "extr, or extr->tdb is NULL, fatal\n");
3321                 SENDERR(EINVAL);
3322         }
3323
3324         if(extr->tdb->tdb_flags & SADB_X_SAFLAGS_CLEARFLOW) {
3325                 KLIPS_PRINT(debug_pfkey,
3326                             "klips_debug:pfkey_x_delflow_parse: "
3327                             "CLEARFLOW flag set, calling cleareroutes.\n");
3328                 if ((error = ipsec_cleareroutes()))
3329                         KLIPS_PRINT(debug_pfkey,
3330                                     "klips_debug:pfkey_x_delflow_parse: "
3331                                     "cleareroutes returned %d.\n", error);
3332                         SENDERR(-error);
3333         } else {
3334                 struct sk_buff *first = NULL, *last = NULL;
3335
3336                 if(!(extr->eroute)) {
3337                         KLIPS_PRINT(debug_pfkey,
3338                                     "klips_debug:pfkey_x_delflow_parse: "
3339                                     "extr->eroute is NULL, fatal.\n");
3340                         SENDERR(EINVAL);
3341                 }
3342                 
3343                 srcflow.u.v4.sin_family = AF_INET;
3344                 dstflow.u.v4.sin_family = AF_INET;
3345                 srcmask.u.v4.sin_family = AF_INET;
3346                 dstmask.u.v4.sin_family = AF_INET;
3347                 srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
3348                 dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
3349                 srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
3350                 dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
3351
3352 #ifdef CONFIG_IPSEC_DEBUG
3353                 if (debug_pfkey) {
3354                         subnettoa(extr->eroute->er_eaddr.sen_ip_src,
3355                                   extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
3356                         subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
3357                                   extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
3358                         KLIPS_PRINT(debug_pfkey,
3359                                     "klips_debug:pfkey_x_delflow_parse: "
3360                                     "calling breakeroute for %s->%s\n",
3361                                     buf1, buf2);
3362                 }
3363 #endif /* CONFIG_IPSEC_DEBUG */
3364                 if((error = ipsec_breakroute(&(extr->eroute->er_eaddr),
3365                                              &(extr->eroute->er_emask),
3366                                              &first, &last))) {
3367                         KLIPS_PRINT(debug_pfkey,
3368                                     "klips_debug:pfkey_x_delflow_parse: "
3369                                     "breakeroute returned %d.  first=%p, last=%p\n",
3370                                     error,
3371                                     first,
3372                                     last);
3373                         if(first != NULL) {
3374 #ifdef USE_IXP4XX_CRYPTO
3375                                 kfree_skb(first);
3376 #else
3377                                 dev_kfree_skb(first, FREE_WRITE);
3378 #endif /* USE_IXP4XX_CRYPTO */
3379                         }
3380                         if(last != NULL) {
3381 #ifdef USE_IXP4XX_CRYPTO
3382                                 kfree_skb(last);
3383 #else
3384                                 dev_kfree_skb(last, FREE_WRITE);
3385 #endif /* USE_IXP4XX_CRYPTO */
3386                         }
3387                         SENDERR(-error);
3388                 }
3389                 if(first != NULL) {
3390 #ifdef USE_IXP4XX_CRYPTO
3391                         kfree_skb(first);
3392 #else
3393                         dev_kfree_skb(first, FREE_WRITE);
3394 #endif /* USE_IXP4XX_CRYPTO */
3395                 }
3396                 if(last != NULL) {
3397 #ifdef USE_IXP4XX_CRYPTO
3398                         kfree_skb(last);
3399 #else
3400                         dev_kfree_skb(last, FREE_WRITE);
3401 #endif /* USE_IXP4XX_CRYPTO */
3402                 }
3403         }
3404         
3405         if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
3406                                                           SADB_X_DELFLOW,
3407                                                           satype,
3408                                                           0,
3409                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
3410                                                           ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
3411                               extensions_reply)
3412              && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA],
3413                                                         SADB_EXT_SA,
3414                                                         extr->tdb->tdb_said.spi,
3415                                                         extr->tdb->tdb_replaywin,
3416                                                         extr->tdb->tdb_state,
3417                                                         extr->tdb->tdb_authalg,
3418                                                         extr->tdb->tdb_encalg,
3419                                                         extr->tdb->tdb_flags),
3420                                  extensions_reply)
3421              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
3422                                                              SADB_X_EXT_ADDRESS_SRC_FLOW,
3423                                                              0, /*extr->tdb->tdb_said.proto,*/
3424                                                              0,
3425                                                              (struct sockaddr*)&srcflow),
3426                                  extensions_reply)
3427              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
3428                                                              SADB_X_EXT_ADDRESS_DST_FLOW,
3429                                                              0, /*extr->tdb->tdb_said.proto,*/
3430                                                              0,
3431                                                              (struct sockaddr*)&dstflow),
3432                                  extensions_reply)
3433              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
3434                                                              SADB_X_EXT_ADDRESS_SRC_MASK,
3435                                                              0, /*extr->tdb->tdb_said.proto,*/
3436                                                              0,
3437                                                              (struct sockaddr*)&srcmask),
3438                                  extensions_reply)
3439              && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
3440                                                              SADB_X_EXT_ADDRESS_DST_MASK,
3441                                                              0, /*extr->tdb->tdb_said.proto,*/
3442                                                              0,
3443                                                              (struct sockaddr*)&dstmask),
3444                                  extensions_reply)
3445                 )) {
3446                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
3447                             "failed to build the x_delflow reply message extensions\n");
3448                 SENDERR(-error);
3449         }
3450                 
3451         if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
3452                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
3453                             "failed to build the x_delflow reply message\n");
3454                 SENDERR(-error);
3455         }
3456         
3457         for(pfkey_socketsp = pfkey_open_sockets;
3458             pfkey_socketsp;
3459             pfkey_socketsp = pfkey_socketsp->next) {
3460                 if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
3461                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
3462                                     "sending up x_delflow reply message for satype=%d(%s) to socket=%p failed with error=%d.\n",
3463                                     satype,
3464                                     satype2name(satype),
3465                                     pfkey_socketsp->socketp,
3466                                     error);
3467                         SENDERR(-error);
3468                 }
3469                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
3470                             "sending up x_delflow reply message for satype=%d(%s) to socket=%p succeeded.\n",
3471                             satype,
3472                             satype2name(satype),
3473                             pfkey_socketsp->socketp);
3474         }
3475         
3476         KLIPS_PRINT(debug_pfkey,
3477                     "klips_debug:pfkey_x_delflow_parse: "
3478                     "extr->tdb cleaned up and freed.\n");
3479
3480  errlab:
3481         if (pfkey_reply) {
3482                 pfkey_msg_free(&pfkey_reply);
3483         }
3484         pfkey_extensions_free(extensions_reply);
3485         return error;
3486 }
3487
3488 DEBUG_NO_STATIC int
3489 pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
3490 {
3491         int error = 0;
3492
3493         KLIPS_PRINT(debug_pfkey,
3494                     "klips_debug:pfkey_x_msg_debug_parse: .\n");
3495
3496 /* errlab:*/
3497         return error;
3498 }
3499
3500 /* pfkey_expire expects the tdb table to be locked before being called. */
3501 int
3502 pfkey_expire(struct ipsec_sa *tdbp, int hard)
3503 {
3504         struct sadb_ext *extensions[SADB_EXT_MAX+1];
3505         struct sadb_msg *pfkey_msg = NULL;
3506         struct socket_list *pfkey_socketsp;
3507         int error = 0;
3508         uint8_t satype;
3509
3510         pfkey_extensions_init(extensions);
3511
3512         if(!(satype = proto2satype(tdbp->tdb_said.proto))) {
3513                 KLIPS_PRINT(debug_pfkey,
3514                             "klips_debug:pfkey_expire: "
3515                             "satype lookup for protocol %d lookup failed.\n", 
3516                             tdbp->tdb_said.proto);
3517                 SENDERR(EINVAL);
3518         }
3519         
3520         if(!pfkey_open_sockets) {
3521                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
3522                             "no sockets listening.\n");
3523                 SENDERR(EPROTONOSUPPORT);
3524         }
3525
3526         if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
3527                                                            SADB_EXPIRE,
3528                                                            satype,
3529                                                            0,
3530                                                            ++pfkey_msg_seq,
3531                                                            0),
3532                                extensions)
3533               && pfkey_safe_build(error = pfkey_sa_build(&extensions[SADB_EXT_SA],
3534                                                          SADB_EXT_SA,
3535                                                          tdbp->tdb_said.spi,
3536                                                          tdbp->tdb_replaywin,
3537                                                          tdbp->tdb_state,
3538                                                          tdbp->tdb_authalg,
3539                                                          tdbp->tdb_encalg,
3540                                                          tdbp->tdb_flags),
3541                                   extensions)
3542               && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT],
3543                                                                SADB_EXT_LIFETIME_CURRENT,
3544                                                                tdbp->ips_life.ipl_allocations.ipl_count,
3545                                                                tdbp->ips_life.ipl_bytes.ipl_count,
3546                                                                tdbp->ips_life.ipl_addtime.ipl_count,
3547                                                                tdbp->ips_life.ipl_usetime.ipl_count,
3548                                                                tdbp->ips_life.ipl_packets.ipl_count),
3549                                   extensions)
3550               && (hard ? 
3551                   pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD],
3552                                                                 SADB_EXT_LIFETIME_HARD,
3553                                                                 tdbp->ips_life.ipl_allocations.ipl_hard,
3554                                                                 tdbp->ips_life.ipl_bytes.ipl_hard,
3555                                                                 tdbp->ips_life.ipl_addtime.ipl_hard,
3556                                                                 tdbp->ips_life.ipl_usetime.ipl_hard,
3557                                                                 tdbp->ips_life.ipl_packets.ipl_hard),
3558                                    extensions)
3559                   : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT],
3560                                                                   SADB_EXT_LIFETIME_SOFT,
3561                                                                   tdbp->ips_life.ipl_allocations.ipl_soft,
3562                                                                   tdbp->ips_life.ipl_bytes.ipl_soft,
3563                                                                   tdbp->ips_life.ipl_addtime.ipl_soft,
3564                                                                   tdbp->ips_life.ipl_usetime.ipl_soft,
3565                                                                   tdbp->ips_life.ipl_packets.ipl_soft),
3566                                      extensions))
3567               && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
3568                                                               SADB_EXT_ADDRESS_SRC,
3569                                                               0, /* tdbp->tdb_said.proto, */
3570                                                               0,
3571                                                               tdbp->tdb_addr_s),
3572                                   extensions)
3573               && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
3574                                                               SADB_EXT_ADDRESS_DST,
3575                                                               0, /* tdbp->tdb_said.proto, */
3576                                                               0,
3577                                                               tdbp->tdb_addr_d),
3578                                   extensions))) {
3579                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
3580                             "failed to build the expire message extensions\n");
3581                 spin_unlock(&tdb_lock);
3582                 goto errlab;
3583         }
3584         
3585         if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
3586                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
3587                             "failed to build the expire message\n");
3588                 SENDERR(-error);
3589         }
3590         
3591         for(pfkey_socketsp = pfkey_open_sockets;
3592             pfkey_socketsp;
3593             pfkey_socketsp = pfkey_socketsp->next) {
3594                 if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
3595                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
3596                                     "sending up expire message for satype=%d(%s) to socket=%p failed with error=%d.\n",
3597                                     satype,
3598                                     satype2name(satype),
3599                                     pfkey_socketsp->socketp,
3600                                     error);
3601                         SENDERR(-error);
3602                 }
3603                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
3604                             "sending up expire message for satype=%d(%s) (proto=%d) to socket=%p succeeded.\n",
3605                             satype,
3606                             satype2name(satype),
3607                             tdbp->tdb_said.proto,
3608                             pfkey_socketsp->socketp);
3609         }
3610         
3611  errlab:
3612         if (pfkey_msg) {
3613                 pfkey_msg_free(&pfkey_msg);
3614         }
3615         pfkey_extensions_free(extensions);
3616         return error;
3617 }
3618
3619 int
3620 pfkey_acquire(struct ipsec_sa *tdbp)
3621 {
3622         struct sadb_ext *extensions[SADB_EXT_MAX+1];
3623         struct sadb_msg *pfkey_msg = NULL;
3624         struct socket_list *pfkey_socketsp;
3625         int error = 0;
3626         struct sadb_comb comb[] = {
3627                 /* auth; encrypt; flags; */
3628                 /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */
3629                 /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */
3630                 /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */
3631                 { SADB_AALG_MD5HMAC,  SADB_EALG_DESCBC, SADB_SAFLAGS_PFS,
3632                   128, 128, 168, 168,
3633                   0, 0, 0, 0, 0,
3634                   57600, 86400, 57600, 86400 },
3635                 { SADB_AALG_SHA1HMAC, SADB_EALG_DESCBC, SADB_SAFLAGS_PFS,
3636                   160, 160, 168, 168,
3637                   0, 0, 0, 0, 0,
3638                   57600, 86400, 57600, 86400 },
3639                 /* soft_packets; hard_packets; */
3640                 { SADB_AALG_MD5HMAC,  SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
3641                   128, 128, 168, 168,
3642                   0, 0, 0, 0, 0,
3643                   57600, 86400, 57600, 86400,
3644                   0, 0 },
3645                 { SADB_AALG_SHA1HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
3646                   160, 160, 168, 168,
3647                   0, 0, 0, 0, 0,
3648                   57600, 86400, 57600, 86400,
3649                   0, 0 }
3650         };
3651        
3652         /* XXX This should not be hard-coded.  It should be taken from the spdb */
3653         uint8_t satype = SADB_SATYPE_ESP;
3654
3655         pfkey_extensions_init(extensions);
3656
3657         if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
3658                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
3659                             "SAtype=%d unspecified or unknown.\n",
3660                             satype);
3661                 SENDERR(EINVAL);
3662         }
3663
3664         if(!(pfkey_registered_sockets[satype])) {
3665                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
3666                             "no sockets registered for SAtype=%d(%s).\n",
3667                             satype,
3668                             satype2name(satype));
3669                 SENDERR(EPROTONOSUPPORT);
3670         }
3671         
3672         if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
3673                                                           SADB_ACQUIRE,
3674                                                           satype,
3675                                                           0,
3676                                                           ++pfkey_msg_seq,
3677                                                           0),
3678                               extensions)
3679               && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
3680                                                               SADB_EXT_ADDRESS_SRC,
3681                                                               tdbp->tdb_said.proto,
3682                                                               0,
3683                                                               tdbp->tdb_addr_s),
3684                                   extensions)
3685               && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
3686                                                               SADB_EXT_ADDRESS_DST,
3687                                                               tdbp->tdb_said.proto,
3688                                                               0,
3689                                                               tdbp->tdb_addr_d),
3690                                   extensions)
3691 #if 0
3692               && (tdbp->tdb_addr_p
3693                   ? pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY],
3694                                                                  SADB_EXT_ADDRESS_PROXY,
3695                                                                  tdbp->tdb_said.proto,
3696                                                                  0,
3697                                                                  tdbp->tdb_addr_p),
3698                                      extensions) : 1)
3699 #endif
3700               && (tdbp->tdb_ident_s.type != SADB_IDENTTYPE_RESERVED
3701                   ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC],
3702                                                                SADB_EXT_IDENTITY_SRC,
3703                                                                tdbp->tdb_ident_s.type,
3704                                                                tdbp->tdb_ident_s.id,
3705                                                                tdbp->tdb_ident_s.len,
3706                                                                tdbp->tdb_ident_s.data),
3707                                      extensions) : 1)
3708
3709               && (tdbp->tdb_ident_d.type != SADB_IDENTTYPE_RESERVED
3710                   ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST],
3711                                                                SADB_EXT_IDENTITY_DST,
3712                                                                tdbp->tdb_ident_d.type,
3713                                                                tdbp->tdb_ident_d.id,
3714                                                                tdbp->tdb_ident_d.len,
3715                                                                tdbp->tdb_ident_d.data),
3716                                      extensions) : 1)
3717 #if 0
3718               /* FIXME: This won't work yet because I have not finished
3719                  it. */
3720               && (tdbp->tdb_sens_
3721                   ? pfkey_safe_build(error = pfkey_sens_build(&extensions[SADB_EXT_SENSITIVITY],
3722                                                               tdbp->tdb_sens_dpd,
3723                                                               tdbp->tdb_sens_sens_level,
3724                                                               tdbp->tdb_sens_sens_len,
3725                                                               tdbp->tdb_sens_sens_bitmap,
3726                                                               tdbp->tdb_sens_integ_level,
3727                                                               tdbp->tdb_sens_integ_len,
3728                                                               tdbp->tdb_sens_integ_bitmap),
3729                                      extensions) : 1)
3730 #endif
3731               && pfkey_safe_build(error = pfkey_prop_build(&extensions[SADB_EXT_PROPOSAL],
3732                                                            64, /* replay */
3733                                                            sizeof(comb)/sizeof(struct sadb_comb),
3734                                                            &(comb[0])),
3735                                   extensions)
3736                 )) {
3737                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
3738                             "failed to build the acquire message extensions\n");
3739                 SENDERR(-error);
3740         }
3741         
3742         if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
3743                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
3744                             "failed to build the acquire message\n");
3745                 SENDERR(-error);
3746         }
3747
3748 #if KLIPS_PFKEY_ACQUIRE_LOSSAGE > 0
3749         if(sysctl_ipsec_regress_pfkey_lossage) {
3750                 return(0);
3751         }
3752 #endif  
3753         
3754         /* this should go to all registered sockets for that satype only */
3755         for(pfkey_socketsp = pfkey_registered_sockets[satype];
3756             pfkey_socketsp;
3757             pfkey_socketsp = pfkey_socketsp->next) {
3758                 if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
3759                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
3760                                     "sending up acquire message for satype=%d(%s) to socket=%p failed with error=%d.\n",
3761                                     satype,
3762                                     satype2name(satype),
3763                                     pfkey_socketsp->socketp,
3764                                     error);
3765                         SENDERR(-error);
3766                 }
3767                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
3768                             "sending up acquire message for satype=%d(%s) to socket=%p succeeded.\n",
3769                             satype,
3770                             satype2name(satype),
3771                             pfkey_socketsp->socketp);
3772         }
3773         
3774  errlab:
3775         if (pfkey_msg) {
3776                 pfkey_msg_free(&pfkey_msg);
3777         }
3778         pfkey_extensions_free(extensions);
3779         return error;
3780 }
3781
3782 #ifdef CONFIG_IPSEC_NAT_TRAVERSAL
3783 int
3784 pfkey_nat_t_new_mapping(struct ipsec_sa *tdbp, struct sockaddr *ipaddr,
3785         __u16 sport)
3786 {
3787         struct sadb_ext *extensions[SADB_EXT_MAX+1];
3788         struct sadb_msg *pfkey_msg = NULL;
3789         struct socket_list *pfkey_socketsp;
3790         int error = 0;
3791         uint8_t satype = (tdbp->tdb_said.proto==IPPROTO_ESP) ? SADB_SATYPE_ESP : 0;
3792
3793         /* Construct SADB_X_NAT_T_NEW_MAPPING message */
3794
3795         pfkey_extensions_init(extensions);
3796
3797         if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
3798                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
3799                             "SAtype=%d unspecified or unknown.\n",
3800                             satype);
3801                 SENDERR(EINVAL);
3802         }
3803
3804         if(!(pfkey_registered_sockets[satype])) {
3805                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
3806                             "no sockets registered for SAtype=%d(%s).\n",
3807                             satype,
3808                             satype2name(satype));
3809                 SENDERR(EPROTONOSUPPORT);
3810         }
3811
3812         if (!(pfkey_safe_build
3813                 (error = pfkey_msg_hdr_build(&extensions[0], SADB_X_NAT_T_NEW_MAPPING,
3814                         satype, 0, ++pfkey_msg_seq, 0), extensions)
3815                 /* SA */
3816                 && pfkey_safe_build
3817                 (error = pfkey_sa_build(&extensions[SADB_EXT_SA],
3818                         SADB_EXT_SA, tdbp->tdb_said.spi, 0, 0, 0, 0, 0), extensions)
3819                 /* ADDRESS_SRC = old addr */
3820                 && pfkey_safe_build
3821                 (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
3822                         SADB_EXT_ADDRESS_SRC, tdbp->tdb_said.proto, 0, tdbp->tdb_addr_s),
3823                         extensions)
3824                 /* NAT_T_SPORT = old port */
3825             && pfkey_safe_build
3826                 (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_SPORT],
3827                         SADB_X_EXT_NAT_T_SPORT, tdbp->ips_natt_sport), extensions)
3828                 /* ADDRESS_DST = new addr */
3829                 && pfkey_safe_build
3830                 (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
3831                         SADB_EXT_ADDRESS_DST, tdbp->tdb_said.proto, 0, ipaddr), extensions)
3832                 /* NAT_T_DPORT = new port */
3833             && pfkey_safe_build
3834                 (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_DPORT],
3835                         SADB_X_EXT_NAT_T_DPORT, sport), extensions)
3836                 )) {
3837                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
3838                             "failed to build the nat_t_new_mapping message extensions\n");
3839                 SENDERR(-error);
3840         }
3841         
3842         if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
3843                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
3844                             "failed to build the nat_t_new_mapping message\n");
3845                 SENDERR(-error);
3846         }
3847
3848         /* this should go to all registered sockets for that satype only */
3849         for(pfkey_socketsp = pfkey_registered_sockets[satype];
3850             pfkey_socketsp;
3851             pfkey_socketsp = pfkey_socketsp->next) {
3852                 if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
3853                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
3854                                     "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p failed with error=%d.\n",
3855                                     satype,
3856                                     satype2name(satype),
3857                                     pfkey_socketsp->socketp,
3858                                     error);
3859                         SENDERR(-error);
3860                 }
3861                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
3862                             "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p succeeded.\n",
3863                             satype,
3864                             satype2name(satype),
3865                             pfkey_socketsp->socketp);
3866         }
3867         
3868  errlab:
3869         if (pfkey_msg) {
3870                 pfkey_msg_free(&pfkey_msg);
3871         }
3872         pfkey_extensions_free(extensions);
3873         return error;
3874 }
3875
3876 DEBUG_NO_STATIC int
3877 pfkey_x_nat_t_new_mapping_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
3878 {
3879         /* SADB_X_NAT_T_NEW_MAPPING not used in kernel */
3880         return -EINVAL;
3881 }
3882 #endif
3883
3884 DEBUG_NO_STATIC int (*ext_processors[SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) =
3885 {
3886   NULL, /* pfkey_msg_process, */
3887         pfkey_sa_process,
3888         pfkey_lifetime_process,
3889         pfkey_lifetime_process,
3890         pfkey_lifetime_process,
3891         pfkey_address_process,
3892         pfkey_address_process,
3893         pfkey_address_process,
3894         pfkey_key_process,
3895         pfkey_key_process,
3896         pfkey_ident_process,
3897         pfkey_ident_process,
3898         pfkey_sens_process,
3899         pfkey_prop_process,
3900         pfkey_supported_process,
3901         pfkey_supported_process,
3902         pfkey_spirange_process,
3903         pfkey_x_kmprivate_process,
3904         pfkey_x_satype_process,
3905         pfkey_sa_process,
3906         pfkey_address_process,
3907         pfkey_address_process,
3908         pfkey_address_process,
3909         pfkey_address_process,
3910         pfkey_address_process,
3911         pfkey_x_debug_process
3912 #ifdef CONFIG_IPSEC_NAT_TRAVERSAL
3913         ,
3914         pfkey_x_nat_t_type_process,
3915         pfkey_x_nat_t_port_process,
3916         pfkey_x_nat_t_port_process,
3917         pfkey_address_process
3918 #endif
3919 };
3920
3921
3922 DEBUG_NO_STATIC int (*msg_parsers[SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr)
3923  =
3924 {
3925         NULL, /* RESERVED */
3926         pfkey_getspi_parse,
3927         pfkey_update_parse,
3928         pfkey_add_parse,
3929         pfkey_delete_parse,
3930         pfkey_get_parse,
3931         pfkey_acquire_parse,
3932         pfkey_register_parse,
3933         pfkey_expire_parse,
3934         pfkey_flush_parse,
3935         pfkey_dump_parse,
3936         pfkey_x_promisc_parse,
3937         pfkey_x_pchange_parse,
3938         pfkey_x_grpsa_parse,
3939         pfkey_x_addflow_parse,
3940         pfkey_x_delflow_parse,
3941         pfkey_x_msg_debug_parse
3942 #ifdef CONFIG_IPSEC_NAT_TRAVERSAL
3943         , pfkey_x_nat_t_new_mapping_parse
3944 #endif
3945 };
3946
3947 int
3948 pfkey_build_reply(struct sadb_msg *pfkey_msg, struct pfkey_extracted_data *extr,
3949                                 struct sadb_msg **pfkey_reply)
3950 {
3951         struct sadb_ext *extensions[SADB_EXT_MAX+1];
3952         int error = 0;
3953         int msg_type = pfkey_msg->sadb_msg_type;
3954         int seq = pfkey_msg->sadb_msg_seq;
3955
3956         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
3957                     "building reply with type: %d\n",
3958                     msg_type);
3959         pfkey_extensions_init(extensions);
3960         if (!extr || !extr->tdb) {
3961                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
3962                                     "bad TDB passed\n");
3963                         return EINVAL;
3964         }
3965         error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0],
3966                                                      msg_type,
3967                                                      proto2satype(extr->tdb->tdb_said.proto),
3968                                                      0,
3969                                                      seq,
3970                                                      pfkey_msg->sadb_msg_pid),
3971                                  extensions) &&
3972                 (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
3973                    1 << SADB_EXT_SA)
3974                  || pfkey_safe_build(pfkey_sa_build(&extensions[SADB_EXT_SA],
3975                                                     SADB_EXT_SA,
3976                                                     extr->tdb->tdb_said.spi,
3977                                                     extr->tdb->tdb_replaywin,
3978                                                     extr->tdb->tdb_state,
3979                                                     extr->tdb->tdb_authalg,
3980                                                     extr->tdb->tdb_encalg,
3981                                                     extr->tdb->tdb_flags),
3982                                      extensions)) &&
3983                 (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
3984                    1 << SADB_EXT_LIFETIME_CURRENT)
3985                  || pfkey_safe_build(pfkey_lifetime_build(&extensions
3986                                                           [SADB_EXT_LIFETIME_CURRENT],
3987                                                           SADB_EXT_LIFETIME_CURRENT,
3988                                                           extr->tdb->ips_life.ipl_allocations.ipl_count,
3989                                                           extr->tdb->ips_life.ipl_bytes.ipl_count,
3990                                                           extr->tdb->ips_life.ipl_addtime.ipl_count,
3991                                                           extr->tdb->ips_life.ipl_usetime.ipl_count,
3992                                                           extr->tdb->ips_life.ipl_packets.ipl_count),
3993                                      extensions)) &&
3994                 (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
3995                    1 << SADB_EXT_ADDRESS_SRC)
3996                  || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
3997                                                          SADB_EXT_ADDRESS_SRC,
3998                                                          extr->tdb->tdb_said.proto,
3999                                                          0,
4000                                                          extr->tdb->tdb_addr_s),
4001                                      extensions)) &&
4002                 (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
4003                    1 << SADB_EXT_ADDRESS_DST)
4004                  || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
4005                                                          SADB_EXT_ADDRESS_DST,
4006                                                          extr->tdb->tdb_said.proto,
4007                                                          0,
4008                                                          extr->tdb->tdb_addr_d),
4009                                      extensions));
4010
4011         if (error == 0) {
4012                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
4013                             "building extensions failed\n");
4014                 return EINVAL;
4015         }
4016
4017         KLIPS_PRINT(debug_pfkey,
4018                     "klips_debug:pfkey_build_reply: "
4019                     "built extensions, proceed to build the message\n");
4020         KLIPS_PRINT(debug_pfkey,
4021                     "klips_debug:pfkey_build_reply: "
4022                     "extensions[1]= %p\n",
4023                     extensions[1]);
4024         error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT);
4025         pfkey_extensions_free(extensions);
4026
4027         return error;
4028 }
4029
4030 int
4031 pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg,
4032                                 struct sadb_msg **pfkey_reply)
4033 {
4034         int error = 0;
4035         int i;
4036         struct sadb_ext *extensions[SADB_EXT_MAX+1];
4037         struct pfkey_extracted_data extr = {NULL, NULL, NULL};
4038         
4039         pfkey_extensions_init(extensions);
4040         KLIPS_PRINT(debug_pfkey,
4041                     "klips_debug:pfkey_msg_interp: "
4042                     "parsing message ver=%d, type=%d, errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n", 
4043                     pfkey_msg->sadb_msg_version,
4044                     pfkey_msg->sadb_msg_type,
4045                     pfkey_msg->sadb_msg_errno,
4046                     pfkey_msg->sadb_msg_satype,
4047                     satype2name(pfkey_msg->sadb_msg_satype),
4048                     pfkey_msg->sadb_msg_len,
4049                     pfkey_msg->sadb_msg_reserved,
4050                     pfkey_msg->sadb_msg_seq,
4051                     pfkey_msg->sadb_msg_pid);
4052         
4053         if((error = pfkey_alloc_ipsec_sa(&(extr.tdb)))) {
4054                 KLIPS_PRINT(debug_pfkey,
4055                             "klips_debug:pfkey_msg_interp: "
4056                             "something's really wrong, extr.tdb=%p should be NULL.\n",
4057                             extr.tdb);
4058                 SENDERR(-error);
4059         }
4060
4061         KLIPS_PRINT(debug_pfkey,
4062                     "klips_debug:pfkey_msg_interp: "
4063                     "allocated extr->tdb=%p.\n",
4064                     extr.tdb);
4065         
4066         if(pfkey_msg->sadb_msg_satype > SADB_SATYPE_MAX) {
4067                 KLIPS_PRINT(debug_pfkey,
4068                             "klips_debug:pfkey_msg_interp: "
4069                             "satype %d > max %d\n", 
4070                             pfkey_msg->sadb_msg_satype,
4071                             SADB_SATYPE_MAX);
4072                 SENDERR(EINVAL);
4073         }
4074         
4075         switch(pfkey_msg->sadb_msg_type) {
4076         case SADB_GETSPI:
4077         case SADB_UPDATE:
4078         case SADB_ADD:
4079         case SADB_DELETE:
4080         case SADB_X_GRPSA:
4081         case SADB_X_ADDFLOW:
4082                 if(!(extr.tdb->tdb_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) {
4083                         KLIPS_PRINT(debug_pfkey,
4084                                     "klips_debug:pfkey_msg_interp: "
4085                                     "satype %d lookup failed.\n", 
4086                                     pfkey_msg->sadb_msg_satype);
4087                         SENDERR(EINVAL);
4088                 } else {
4089                         KLIPS_PRINT(debug_pfkey,
4090                                     "klips_debug:pfkey_msg_interp: "
4091                                     "satype %d lookups to proto=%d.\n", 
4092                                     pfkey_msg->sadb_msg_satype,
4093                                     extr.tdb->tdb_said.proto);
4094                 }
4095                 break;
4096         default:
4097                 break;
4098         }
4099         
4100         /* The NULL below causes the default extension parsers to be used */
4101         /* Parse the extensions */
4102         if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN)))
4103         {
4104                 KLIPS_PRINT(debug_pfkey,
4105                             "klips_debug:pfkey_msg_interp: "
4106                             "message parsing failed with error %d.\n",
4107                             error); 
4108                 SENDERR(-error);
4109         }
4110         
4111         /* Process the extensions */
4112         for(i=1; i <= SADB_EXT_MAX;i++) {
4113                 if(extensions[i] != NULL) {
4114                         KLIPS_PRINT(debug_pfkey,
4115                                     "klips_debug:pfkey_msg_interp: "
4116                                     "processing ext %d %p with processor %p.\n", 
4117                                     i, extensions[i], ext_processors[i]);
4118                         if((error = ext_processors[i](extensions[i], &extr))) {
4119                                 KLIPS_PRINT(debug_pfkey,
4120                                             "klips_debug:pfkey_msg_interp: "
4121                                             "extension processing for type %d failed with error %d.\n",
4122                                             i,
4123                                             error); 
4124                                 SENDERR(-error);
4125                         }
4126                         
4127                 }
4128                 
4129         }
4130         
4131         /* Parse the message types */
4132         KLIPS_PRINT(debug_pfkey,
4133                     "klips_debug:pfkey_msg_interp: "
4134                     "parsing message type %d with msg_parser %p.\n",
4135                     pfkey_msg->sadb_msg_type,
4136                     msg_parsers[pfkey_msg->sadb_msg_type]); 
4137         if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) {
4138                 KLIPS_PRINT(debug_pfkey,
4139                             "klips_debug:pfkey_msg_interp: "
4140                             "message parsing failed with error %d.\n",
4141                             error); 
4142                 SENDERR(-error);
4143         }
4144
4145 #if 0
4146         error = pfkey_build_reply(pfkey_msg, &extr, pfkey_reply);
4147         if (error) {
4148                 *pfkey_reply = NULL;
4149         }
4150 #endif  
4151  errlab:
4152         if(extr.tdb != NULL) {
4153                 ipsec_sa_wipe(extr.tdb);
4154         }
4155         if(extr.tdb2 != NULL) {
4156                 ipsec_sa_wipe(extr.tdb2);
4157         }
4158         if (extr.eroute != NULL) {
4159                 kfree(extr.eroute);
4160         }
4161         return(error);
4162 }
4163
4164 /*
4165  * $Log: pfkey_v2_parser.c,v $
4166  * Revision 1.102  2002/03/08 01:15:17  mcr
4167  *      put some internal structure only debug messages behind
4168  *      && sysctl_ipsec_debug_verbose.
4169  *
4170  * Revision 1.101  2002/01/29 17:17:57  mcr
4171  *      moved include of ipsec_param.h to after include of linux/kernel.h
4172  *      otherwise, it seems that some option that is set in ipsec_param.h
4173  *      screws up something subtle in the include path to kernel.h, and
4174  *      it complains on the snprintf() prototype.
4175  *
4176  * Revision 1.100  2002/01/29 04:00:54  mcr
4177  *      more excise of kversions.h header.
4178  *
4179  * Revision 1.99  2002/01/29 02:13:19  mcr
4180  *      introduction of ipsec_kversion.h means that include of
4181  *      ipsec_param.h must preceed any decisions about what files to
4182  *      include to deal with differences in kernel source.
4183  *
4184  * Revision 1.98  2002/01/12 02:57:57  mcr
4185  *      first regression test causes acquire messages to be lost
4186  *      100% of the time. This is to help testing of pluto.
4187  *
4188  * Revision 1.97  2001/11/26 09:23:52  rgb
4189  * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
4190  *
4191  * Revision 1.93.2.4  2001/10/23 04:20:27  mcr
4192  *      parity was forced on wrong structure! prototypes help here.
4193  *
4194  * Revision 1.93.2.3  2001/10/22 21:14:59  mcr
4195  *      include des.h, removed phony prototypes and fixed calling
4196  *      conventions to match real prototypes.
4197  *
4198  * Revision 1.93.2.2  2001/10/15 05:39:03  mcr
4199  *      %08lx is not the right format for u32. Use %08x. 64-bit safe? ha.
4200  *
4201  * Revision 1.93.2.1  2001/09/25 02:30:14  mcr
4202  *      struct tdb -> struct ipsec_sa.
4203  *      use new lifetime structure. common format routines for debug.
4204  *
4205  * Revision 1.96  2001/11/06 20:47:54  rgb
4206  * Fixed user context call to ipsec_dev_start_xmit() bug.  Call
4207  * dev_queue_xmit() instead.
4208  *
4209  * Revision 1.95  2001/11/06 19:47:46  rgb
4210  * Added packet parameter to lifetime and comb structures.
4211  *
4212  * Revision 1.94  2001/10/18 04:45:23  rgb
4213  * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
4214  * lib/freeswan.h version macros moved to lib/kversions.h.
4215  * Other compiler directive cleanups.
4216  *
4217  * Revision 1.93  2001/09/20 15:32:59  rgb
4218  * Min/max cleanup.
4219  *
4220  * Revision 1.92  2001/09/19 16:35:48  rgb
4221  * PF_KEY ident fix for getspi from NetCelo (puttdb duplication).
4222  *
4223  * Revision 1.91  2001/09/15 16:24:06  rgb
4224  * Re-inject first and last HOLD packet when an eroute REPLACE is done.
4225  *
4226  * Revision 1.90  2001/09/14 16:58:38  rgb
4227  * Added support for storing the first and last packets through a HOLD.
4228  *
4229  * Revision 1.89  2001/09/08 21:14:07  rgb
4230  * Added pfkey ident extension support for ISAKMPd. (NetCelo)
4231  * Better state coherency (error management) between pf_key and IKE daemon.
4232  * (NetCelo)
4233  *
4234  * Revision 1.88  2001/08/27 19:42:44  rgb
4235  * Fix memory leak of encrypt and auth structs in pfkey register.
4236  *
4237  * Revision 1.87  2001/07/06 19:50:46  rgb
4238  * Removed unused debugging code.
4239  * Added inbound policy checking code for IPIP SAs.
4240  *
4241  * Revision 1.86  2001/06/20 06:26:04  rgb
4242  * Changed missing SA errors from EEXIST to ENOENT and added debug output
4243  * for already linked SAs.
4244  *
4245  * Revision 1.85  2001/06/15 04:57:02  rgb
4246  * Remove single error return condition check and check for all errors in
4247  * the case of a replace eroute delete operation.  This means that
4248  * applications must expect to be deleting something before replacing it
4249  * and if nothing is found, complain.
4250  *
4251  * Revision 1.84  2001/06/14 19:35:12  rgb
4252  * Update copyright date.
4253  *
4254  * Revision 1.83  2001/06/12 00:03:19  rgb
4255  * Silence debug set/unset under normal conditions.
4256  *
4257  * Revision 1.82  2001/05/30 08:14:04  rgb
4258  * Removed vestiges of esp-null transforms.
4259  *
4260  * Revision 1.81  2001/05/27 06:12:12  rgb
4261  * Added structures for pid, packet count and last access time to eroute.
4262  * Added packet count to beginning of /proc/net/ipsec_eroute.
4263  *
4264  * Revision 1.80  2001/05/03 19:43:59  rgb
4265  * Check error return codes for all build function calls.
4266  * Standardise on SENDERR() macro.
4267  *
4268  * Revision 1.79  2001/04/20 21:09:16  rgb
4269  * Cleaned up fixed tdbwipes.
4270  * Free pfkey_reply and clean up extensions_reply for grpsa, addflow and
4271  * delflow (Per Cederqvist) plugging memleaks.
4272  *
4273  * Revision 1.78  2001/04/19 19:02:39  rgb
4274  * Fixed extr.tdb freeing, stealing it for getspi, update and add.
4275  * Refined a couple of spinlocks, fixed the one in update.
4276  *
4277  * Revision 1.77  2001/04/18 20:26:16  rgb
4278  * Wipe/free eroute and both tdbs from extr at end of pfkey_msg_interp()
4279  * instead of inside each message type parser.  This fixes two memleaks.
4280  *
4281  * Revision 1.76  2001/04/17 23:51:18  rgb
4282  * Quiet down pfkey_x_debug_process().
4283  *
4284  * Revision 1.75  2001/03/29 01:55:05  rgb
4285  * Fixed pfkey key init memleak.
4286  * Fixed pfkey encryption key debug output.
4287  *
4288  * Revision 1.74  2001/03/27 05:29:14  rgb
4289  * Debug output cleanup/silencing.
4290  *
4291  * Revision 1.73  2001/02/28 05:03:28  rgb
4292  * Clean up and rationalise startup messages.
4293  *
4294  * Revision 1.72  2001/02/27 22:24:56  rgb
4295  * Re-formatting debug output (line-splitting, joining, 1arg/line).
4296  * Check for satoa() return codes.
4297  *
4298  * Revision 1.71  2001/02/27 06:59:30  rgb
4299  * Added satype2name() conversions most places satype is debug printed.
4300  *
4301  * Revision 1.70  2001/02/26 22:37:08  rgb
4302  * Fixed 'unknown proto' INT bug in new code.
4303  * Added satype to protocol debugging instrumentation.
4304  *
4305  * Revision 1.69  2001/02/26 19:57:51  rgb
4306  * Re-formatted debug output (split lines, consistent spacing).
4307  * Fixed as yet undetected FLUSH bug which called ipsec_tdbcleanup()
4308  * with an satype instead of proto.
4309  * Checked for satype consistency and fixed minor bugs.
4310  * Fixed undetected ungrpspi bug that tried to upmsg a second tdb.
4311  * Check for satype sanity in pfkey_expire().
4312  * Added satype sanity check to addflow.
4313  *
4314  * Revision 1.68  2001/02/12 23:14:40  rgb
4315  * Remove double spin lock in pfkey_expire().
4316  *
4317  * Revision 1.67  2001/01/31 19:23:40  rgb
4318  * Fixed double-unlock bug introduced by grpsa upmsg (found by Lars Heete).
4319  *
4320  * Revision 1.66  2001/01/29 22:20:04  rgb
4321  * Fix minor add upmsg lifetime bug.
4322  *
4323  * Revision 1.65  2001/01/24 06:12:33  rgb
4324  * Fixed address extension compile bugs just introduced.
4325  *
4326  * Revision 1.64  2001/01/24 00:31:15  rgb
4327  * Added upmsg for addflow/delflow.
4328  *
4329  * Revision 1.63  2001/01/23 22:02:55  rgb
4330  * Added upmsg to x_grpsa.
4331  * Fixed lifetimes extentions to add/update/get upmsg.
4332  *
4333  * Revision 1.62  2000/11/30 21:47:51  rgb
4334  * Fix error return bug after returning from pfkey_tdb_init().
4335  *
4336  * Revision 1.61  2000/11/17 18:10:29  rgb
4337  * Fixed bugs mostly relating to spirange, to treat all spi variables as
4338  * network byte order since this is the way PF_KEYv2 stored spis.
4339  *
4340  * Revision 1.60  2000/11/06 04:34:53  rgb
4341  * Changed non-exported functions to DEBUG_NO_STATIC.
4342  * Add Svenning's adaptive content compression.
4343  * Ditched spin_lock_irqsave in favour of spin_lock/_bh.
4344  * Fixed double unlock bug (Svenning).
4345  * Fixed pfkey_msg uninitialized bug in pfkey_{expire,acquire}().
4346  * Fixed incorrect extension type (prop) in pfkey)acquire().
4347  *
4348  * Revision 1.59  2000/10/11 15:25:12  rgb
4349  * Fixed IPCOMP disabled compile bug.
4350  *
4351  * Revision 1.58  2000/10/11 14:54:03  rgb
4352  * Fixed pfkey_acquire() satype to SADB_SATYPE_ESP and removed pfkey
4353  * protocol violations of setting pfkey_address_build() protocol parameter
4354  * to non-zero except in the case of pfkey_acquire().
4355  *
4356  * Revision 1.57  2000/10/10 20:10:18  rgb
4357  * Added support for debug_ipcomp and debug_verbose to klipsdebug.
4358  *
4359  * Revision 1.56  2000/10/06 20:24:36  rgb
4360  * Fixes to pfkey_acquire to initialize extensions[] and use correct
4361  * ipproto.
4362  *
4363  * Revision 1.55  2000/10/03 03:20:57  rgb
4364  * Added brackets to get a?b:c scope right for pfkey_register reply.
4365  *
4366  * Revision 1.54  2000/09/29 19:49:30  rgb
4367  * As-yet-unused-bits cleanup.
4368  *
4369  * Revision 1.53  2000/09/28 00:35:45  rgb
4370  * Padded SATYPE printout in pfkey_register for vertical alignment.
4371  *
4372  * Revision 1.52  2000/09/20 16:21:58  rgb
4373  * Cleaned up ident string alloc/free.
4374  *
4375  * Revision 1.51  2000/09/20 04:04:20  rgb
4376  * Changed static functions to DEBUG_NO_STATIC to reveal function names in
4377  * oopsen.
4378  *
4379  * Revision 1.50  2000/09/16 01:10:53  rgb
4380  * Fixed unused var warning with debug off.
4381  *
4382  * Revision 1.49  2000/09/15 11:37:02  rgb
4383  * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
4384  * IPCOMP zlib deflate code.
4385  *
4386  * Revision 1.48  2000/09/15 04:57:57  rgb
4387  * Cleaned up existing IPCOMP code before svenning addition.
4388  * Initialize pfkey_reply and extensions_reply in case of early error in
4389  * message parsing functions (thanks Kai!).
4390  *
4391  * Revision 1.47  2000/09/13 08:02:56  rgb
4392  * Added KMd registration notification.
4393  *
4394  * Revision 1.46  2000/09/12 22:35:36  rgb
4395  * Restructured to remove unused extensions from CLEARFLOW messages.
4396  *
4397  * Revision 1.45  2000/09/12 03:24:23  rgb
4398  * Converted #if0 debugs to sysctl.
4399  *
4400  * Revision 1.44  2000/09/09 06:38:39  rgb
4401  * Correct SADB message type for update, add and delete.
4402  *
4403  * Revision 1.43  2000/09/08 19:19:56  rgb
4404  * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
4405  * Removed all references to CONFIG_IPSEC_PFKEYv2.
4406  * Put in sanity checks in most msg type parsers to catch invalid satypes
4407  * and empty socket lists.
4408  * Moved spin-locks in pfkey_get_parse() to simplify.
4409  * Added pfkey_acquire().
4410  * Added upwards messages to update, add, delete, acquire_parse,
4411  * expire_parse and flush.
4412  * Fix pfkey_prop_build() parameter to be only single indirection.
4413  * Changed all replies to use pfkey_reply.
4414  * Check return code on puttdb() and deltdbchain() in getspi, update,
4415  * add, delete.
4416  * Fixed up all pfkey replies to open and registered sockets.
4417  *
4418  * Revision 1.42  2000/09/01 18:50:26  rgb
4419  * Added a supported algorithms array lists, one per satype and registered
4420  * existing algorithms.
4421  * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
4422  * list.
4423  * Only send pfkey_expire() messages to sockets registered for that satype.
4424  * Added reply to pfkey_getspi_parse().
4425  * Added reply to pfkey_get_parse().
4426  * Fixed debug output label bug in pfkey_lifetime_process().
4427  * Cleaned up pfkey_sa_process a little.
4428  * Moved pfkey_safe_build() above message type parsers to make it available
4429  * for creating replies.
4430  * Added comments for future work in pfkey_acquire_parse().
4431  * Fleshed out guts of pfkey_register_parse().
4432  *
4433  * Revision 1.41  2000/08/24 16:58:11  rgb
4434  * Fixed key debugging variables.
4435  * Fixed error return code for a failed search.
4436  * Changed order of pfkey_get operations.
4437  *
4438  * Revision 1.40  2000/08/21 16:32:27  rgb
4439  * Re-formatted for cosmetic consistency and readability.
4440  *
4441  * Revision 1.39  2000/08/20 21:38:57  rgb
4442  * Bugfixes to as-yet-unused pfkey_update_parse() and
4443  * pfkey_register_parse(). (Momchil)
4444  * Added functions pfkey_safe_build(), pfkey_expire() and
4445  * pfkey_build_reply(). (Momchil)
4446  * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
4447  *
4448  * Revision 1.38  2000/08/18 21:30:41  rgb
4449  * Purged all tdb_spi, tdb_proto and tdb_dst macros.  They are unclear.
4450  *
4451  * Revision 1.37  2000/08/18 18:18:02  rgb
4452  * Cosmetic and descriptive changes made to debug test.
4453  * getspi and update fixes from Momchil.
4454  *
4455  * Revision 1.36  2000/08/15 15:41:55  rgb
4456  * Fixed the (as yet unused and untested) pfkey_getspi() routine.
4457  *
4458  * Revision 1.35  2000/08/01 14:51:52  rgb
4459  * Removed _all_ remaining traces of DES.
4460  *
4461  * Revision 1.34  2000/07/28 14:58:32  rgb
4462  * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
4463  *
4464  * Revision 1.33  2000/06/28 05:50:11  rgb
4465  * Actually set iv_bits.
4466  *
4467  * Revision 1.32  2000/05/30 18:36:56  rgb
4468  * Fix AH auth hash setup bug.  This breaks interop with previous PF_KEY
4469  * FreeS/WAN, but fixes interop with other implementations.
4470  *
4471  * Revision 1.31  2000/03/16 14:05:48  rgb
4472  * Fixed brace scope preventing non-debug compile.
4473  * Added null parameter check for pfkey_x_debug().
4474  *
4475  * Revision 1.30  2000/01/22 23:21:13  rgb
4476  * Use new function satype2proto().
4477  *
4478  * Revision 1.29  2000/01/22 08:40:21  rgb
4479  * Invert condition to known value to avoid AF_INET6 in 2.0.36.
4480  *
4481  * Revision 1.28  2000/01/22 07:58:57  rgb
4482  * Fixed REPLACEFLOW bug, missing braces around KLIPS_PRINT *and* SENDERR.
4483  *
4484  * Revision 1.27  2000/01/22 03:48:01  rgb
4485  * Added extr pointer component debugging.
4486  *
4487  * Revision 1.26  2000/01/21 09:41:25  rgb
4488  * Changed a (void*) to (char*) cast to do proper pointer math.
4489  * Don't call tdbwipe if tdb2 is NULL.
4490  *
4491  * Revision 1.25  2000/01/21 06:21:01  rgb
4492  * Added address cases for eroute flows.
4493  * Tidied up compiler directive indentation for readability.
4494  * Added ictx,octx vars for simplification.
4495  * Added macros for HMAC padding magic numbers.
4496  * Converted from double tdb arguments to one structure (extr)
4497  * containing pointers to all temporary information structures
4498  * and checking for valid arguments to all ext processors and
4499  * msg type parsers.
4500  * Added spiungrp'ing.
4501  * Added klipsdebug switching capability.
4502  * Removed sa_process() check for zero protocol.
4503  * Added address case for DST2 for grouping.
4504  * Added/changed minor debugging instrumentation.
4505  * Fixed spigrp for single said, ungrouping case.
4506  * Added code to parse addflow and delflow messages.
4507  * Removed redundant statements duplicating tdbwipe() functionality
4508  * and causing double kfrees.
4509  * Permit addflow to have a protocol of 0.
4510  *
4511  * Revision 1.24  1999/12/09 23:23:00  rgb
4512  * Added check to pfkey_sa_process() to do eroutes.
4513  * Converted to DIVUP() macro.
4514  * Converted if() to switch() in pfkey_register_parse().
4515  * Use new pfkey_extensions_init() instead of memset().
4516  *
4517  * Revision 1.23  1999/12/01 22:18:13  rgb
4518  * Preset minspi and maxspi values in case and spirange extension is not
4519  * included and check for the presence of an spirange extension before
4520  * using it.  Initialise tdb_sastate to LARVAL.
4521  * Fixed debugging output typo.
4522  * Fixed authentication context initialisation bugs (4 places).
4523  *
4524  * Revision 1.22  1999/11/27 11:53:08  rgb
4525  * Moved pfkey_msg_parse prototype to pfkey.h
4526  * Moved exts_permitted/required prototype to pfkey.h.
4527  * Moved sadb_satype2proto protocol lookup table to lib/pfkey_v2_parse.c.
4528  * Deleted SADB_X_EXT_SA2 code from pfkey_sa_process() since it will never
4529  * be called.
4530  * Moved protocol/algorithm checks to lib/pfkey_v2_parse.c
4531  * Debugging error messages added.
4532  * Enable lifetime_current checking.
4533  * Remove illegal requirement for SA extension to be present in an
4534  * originating GETSPI call.
4535  * Re-instate requirement for UPDATE or ADD message to be MATURE.
4536  * Add argument to pfkey_msg_parse() for direction.
4537  * Fixed IPIP dst address bug and purged redundant, leaky code.
4538  *
4539  * Revision 1.21  1999/11/24 05:24:20  rgb
4540  * hanged 'void*extensions' to 'struct sadb_ext*extensions'.
4541  * Fixed indention.
4542  * Ditched redundant replay check.
4543  * Fixed debug message text from 'parse' to 'process'.
4544  * Added more debug output.
4545  * Forgot to zero extensions array causing bug, fixed.
4546  *
4547  * Revision 1.20  1999/11/23 23:08:13  rgb
4548  * Move all common parsing code to lib/pfkey_v2_parse.c and rename
4549  * remaining bits to *_process. (PJO)
4550  * Add macros for dealing with alignment and rounding up more opaquely.
4551  * Use provided macro ADDRTOA_BUF instead of hardcoded value.
4552  * Sort out pfkey and freeswan headers, putting them in a library path.
4553  * Corrected a couple of bugs in as-yet-inactive code.
4554  *
4555  * Revision 1.19  1999/11/20 22:01:10  rgb
4556  * Add more descriptive error messages for non-zero reserved fields.
4557  * Add more descriptive error message for spirange parsing.
4558  * Start on supported extension parsing.
4559  * Start on register and get message parsing.
4560  *
4561  * Revision 1.18  1999/11/18 04:09:20  rgb
4562  * Replaced all kernel version macros to shorter, readable form.
4563  *
4564  * Revision 1.17  1999/11/17 15:53:41  rgb
4565  * Changed all occurrences of #include "../../../lib/freeswan.h"
4566  * to #include <freeswan.h> which works due to -Ilibfreeswan in the
4567  * klips/net/ipsec/Makefile.
4568  *
4569  * Revision 1.16  1999/10/26 16:57:43  rgb
4570  * Add shorter macros for compiler directives to visually clean-up.
4571  * Give ipv6 code meaningful compiler directive.
4572  * Add comments to other #if 0 debug code.
4573  * Remove unused *_bh_atomic() calls.
4574  * Fix mis-placed spinlock.
4575  *
4576  * Revision 1.15  1999/10/16 18:27:10  rgb
4577  * Clean-up unused cruft.
4578  * Fix-up lifetime_allocations_c and lifetime_addtime_c initialisations.
4579  *
4580  * Revision 1.14  1999/10/08 18:37:34  rgb
4581  * Fix end-of-line spacing to sate whining PHMs.
4582  *
4583  * Revision 1.13  1999/10/03 18:49:12  rgb
4584  * Spinlock fixes for 2.0.xx and 2.3.xx.
4585  *
4586  * Revision 1.12  1999/10/01 15:44:54  rgb
4587  * Move spinlock header include to 2.1> scope.
4588  *
4589  * Revision 1.11  1999/10/01 00:05:45  rgb
4590  * Added tdb structure locking.
4591  * Use 'jiffies' instead of do_get_timeofday().
4592  * Fix lifetime assignments.
4593  *
4594  * Revision 1.10  1999/09/21 15:24:45  rgb
4595  * Rework spirange code to save entropy and prevent endless loops.
4596  *
4597  * Revision 1.9  1999/09/16 12:10:21  rgb
4598  * Minor fixes to random spi selection for correctness and entropy conservation.
4599  *
4600  * Revision 1.8  1999/05/25 22:54:46  rgb
4601  * Fix comparison that should be an assignment in an if.
4602  *
4603  * Revision 1.7  1999/05/09 03:25:37  rgb
4604  * Fix bug introduced by 2.2 quick-and-dirty patch.
4605  *
4606  * Revision 1.6  1999/05/08 21:32:30  rgb
4607  * Fix error return reporting.
4608  *
4609  * Revision 1.5  1999/05/05 22:02:33  rgb
4610  * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
4611  *
4612  * Revision 1.4  1999/04/29 15:22:40  rgb
4613  * Standardise an error return method.
4614  * Add debugging instrumentation.
4615  * Add check for existence of macros min/max.
4616  * Add extensions permitted/required in/out filters.
4617  * Add satype-to-protocol table.
4618  * Add a second tdb pointer to each parser to accomodate GRPSA.
4619  * Move AH & no_algo_set to GETSPI, UPDATE and ADD.
4620  * Add OOO window check.
4621  * Add support for IPPROTO_IPIP and hooks for IPPROTO_COMP.
4622  * Add timestamp to lifetime parse.
4623  * Fix address structure length checking bug.
4624  * Fix address structure allocation bug (forgot to kmalloc!).
4625  * Add checks for extension lengths.
4626  * Add checks for extension reserved illegal values.
4627  * Add check for spirange legal values.
4628  * Add an extension type for parsing a second satype, SA and
4629  * DST_ADDRESS.
4630  * Make changes to tdb_init() template to get pfkey_tdb_init(),
4631  * eliminating any mention of xformsw.
4632  * Implement getspi, update and grpsa (not tested).
4633  * Add stubs for as yet unimplemented message types.
4634  * Add table of message parsers to substitute for msg_parse switch.
4635  *
4636  * Revision 1.3  1999/04/15 17:58:07  rgb
4637  * Add RCSID labels.
4638  *
4639  * Revision 1.2  1999/04/15 15:37:26  rgb
4640  * Forward check changes from POST1_00 branch.
4641  *
4642  * Revision 1.1.2.1  1999/03/26 20:58:56  rgb
4643  * Add pfkeyv2 support to KLIPS.
4644  *
4645  * Local variables:
4646  * c-file-style: "linux"
4647  * End:
4648  *
4649  */