OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / klips / net / ipsec / pfkey_v2.c
1 /*
2  * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F
3  * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs.
4  * 
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; either version 2 of the License, or (at your
8  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9  * 
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * for more details.
14  *
15  * RCSID $Id: pfkey_v2.c,v 1.68 2002/03/08 01:15:17 mcr Exp $
16  */
17
18 /*
19  *              Template from /usr/src/linux-2.0.36/net/unix/af_unix.c.
20  *              Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c.
21  */
22
23 #define __NO_VERSION__
24 #include <linux/module.h>
25 #include <linux/version.h>
26 #include <linux/config.h>
27 #include <linux/kernel.h>
28
29 #include "ipsec_param.h"
30
31 #include <linux/major.h>
32 #include <linux/signal.h>
33 #include <linux/sched.h>
34 #include <linux/errno.h>
35 #include <linux/string.h>
36 #include <linux/stat.h>
37 #include <linux/socket.h>
38 #include <linux/un.h>
39 #include <linux/fcntl.h>
40 #include <linux/termios.h>
41 #include <linux/socket.h>
42 #include <linux/sockios.h>
43 #include <linux/net.h> /* struct socket */
44 #include <linux/in.h>
45 #include <linux/fs.h>
46 #ifdef MALLOC_SLAB
47 # include <linux/slab.h> /* kmalloc() */
48 #else /* MALLOC_SLAB */
49 # include <linux/malloc.h> /* kmalloc() */
50 #endif /* MALLOC_SLAB */
51 #include <asm/segment.h>
52 #include <linux/skbuff.h>
53 #include <linux/netdevice.h>
54 #include <net/sock.h> /* struct sock */
55 /* #include <net/tcp.h> */
56 #include <net/af_unix.h>
57 #ifdef CONFIG_PROC_FS
58 # include <linux/proc_fs.h>
59 #endif /* CONFIG_PROC_FS */
60
61 #include <linux/types.h>
62  
63 #include <freeswan.h>
64 #ifdef NET_21
65 # include <asm/uaccess.h>
66 # include <linux/in6.h>
67 #endif /* NET_21 */
68
69 #include "radij.h"
70 #include "ipsec_encap.h"
71 #include "ipsec_sa.h"
72 #include "ipsec_netlink.h"
73
74 #include <pfkeyv2.h>
75 #include <pfkey.h>
76
77 #include "ipsec_proto.h"
78
79 #ifdef CONFIG_IPSEC_DEBUG
80 int debug_pfkey = 0;
81 extern int sysctl_ipsec_debug_verbose;
82 #endif /* CONFIG_IPSEC_DEBUG */
83
84 #define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
85
86 #ifndef SOCKOPS_WRAPPED
87 #define SOCKOPS_WRAPPED(name) name
88 #endif /* SOCKOPS_WRAPPED */
89
90 struct proto_ops SOCKOPS_WRAPPED(pfkey_ops);
91 struct sock *pfkey_sock_list = NULL;
92 struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
93
94 struct socket_list *pfkey_open_sockets = NULL;
95 struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
96
97 int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **);
98
99 int
100 pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets)
101 {
102         struct socket_list *socket_listp,*prev;
103
104         if(!socketp) {
105                 KLIPS_PRINT(debug_pfkey,
106                             "klips_debug:pfkey_list_remove_socket: "
107                             "NULL socketp handed in, failed.\n");
108                 return -EINVAL;
109         }
110
111         if(!sockets) {
112                 KLIPS_PRINT(debug_pfkey,
113                             "klips_debug:pfkey_list_remove_socket: "
114                             "NULL sockets list handed in, failed.\n");
115                 return -EINVAL;
116         }
117
118         socket_listp = *sockets;
119         prev = NULL;
120         
121         KLIPS_PRINT(debug_pfkey,
122                     "klips_debug:pfkey_list_remove_socket: "
123                     "removing sock=%p\n",
124                     socketp);
125         
126         while(socket_listp != NULL) {
127                 if(socket_listp->socketp == socketp) {
128                         if(prev != NULL) {
129                                 prev->next = socket_listp->next;
130                         } else {
131                                 *sockets = socket_listp->next;
132                         }
133                         
134                         kfree((void*)socket_listp);
135                         
136                         break;
137                 }
138                 prev = socket_listp;
139                 socket_listp = socket_listp->next;
140         }
141
142         return 0;
143 }
144
145 int
146 pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets)
147 {
148         struct socket_list *socket_listp;
149
150         if(!socketp) {
151                 KLIPS_PRINT(debug_pfkey,
152                             "klips_debug:pfkey_list_insert_socket: "
153                             "NULL socketp handed in, failed.\n");
154                 return -EINVAL;
155         }
156
157         if(!sockets) {
158                 KLIPS_PRINT(debug_pfkey,
159                             "klips_debug:pfkey_list_insert_socket: "
160                             "NULL sockets list handed in, failed.\n");
161                 return -EINVAL;
162         }
163
164         KLIPS_PRINT(debug_pfkey,
165                     "klips_debug:pfkey_list_insert_socket: "
166                     "socketp=%p\n",socketp);
167         
168         if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) {
169                 KLIPS_PRINT(debug_pfkey,
170                             "klips_debug:pfkey_list_insert_socket: "
171                             "memory allocation error.\n");
172                 return -ENOMEM;
173         }
174         
175         socket_listp->socketp = socketp;
176         socket_listp->next = *sockets;
177         *sockets = socket_listp;
178
179         return 0;
180 }
181   
182 int
183 pfkey_list_remove_supported(struct supported *supported, struct supported_list **supported_list)
184 {
185         struct supported_list *supported_listp = *supported_list, *prev = NULL;
186         
187         if(!supported) {
188                 KLIPS_PRINT(debug_pfkey,
189                             "klips_debug:pfkey_list_remove_supported: "
190                             "NULL supported handed in, failed.\n");
191                 return -EINVAL;
192         }
193
194         if(!supported_list) {
195                 KLIPS_PRINT(debug_pfkey,
196                             "klips_debug:pfkey_list_remove_supported: "
197                             "NULL supported_list handed in, failed.\n");
198                 return -EINVAL;
199         }
200
201         KLIPS_PRINT(debug_pfkey,
202                     "klips_debug:pfkey_list_remove_supported: "
203                     "removing supported=%p\n",
204                     supported);
205         
206         while(supported_listp != NULL) {
207                 if(supported_listp->supportedp == supported) {
208                         if(prev != NULL) {
209                                 prev->next = supported_listp->next;
210                         } else {
211                                 *supported_list = supported_listp->next;
212                         }
213                         
214                         kfree((void*)supported_listp);
215                         
216                         break;
217                 }
218                 prev = supported_listp;
219                 supported_listp = supported_listp->next;
220         }
221
222         return 0;
223 }
224
225 int
226 pfkey_list_insert_supported(struct supported *supported, struct supported_list **supported_list)
227 {
228         struct supported_list *supported_listp;
229
230         if(!supported) {
231                 KLIPS_PRINT(debug_pfkey,
232                             "klips_debug:pfkey_list_insert_supported: "
233                             "NULL supported handed in, failed.\n");
234                 return -EINVAL;
235         }
236
237         if(!supported_list) {
238                 KLIPS_PRINT(debug_pfkey,
239                             "klips_debug:pfkey_list_insert_supported: "
240                             "NULL supported_list handed in, failed.\n");
241                 return -EINVAL;
242         }
243
244         KLIPS_PRINT(debug_pfkey,
245                     "klips_debug:pfkey_list_insert_supported: "
246                     "incoming, supported=%p, supported_list=%p\n",
247                     supported,
248                     supported_list);
249         
250         supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL);
251         if(supported_listp == NULL)     {
252                 KLIPS_PRINT(debug_pfkey,
253                             "klips_debug:pfkey_list_insert_supported: "
254                             "memory allocation error.\n");
255                 return -ENOMEM;
256         }
257         
258         supported_listp->supportedp = supported;
259         supported_listp->next = *supported_list;
260         *supported_list = supported_listp;
261         KLIPS_PRINT(debug_pfkey,
262                     "klips_debug:pfkey_list_insert_supported: "
263                     "outgoing, supported=%p, supported_list=%p\n",
264                     supported,
265                     supported_list);
266
267         return 0;
268 }
269   
270 #ifndef NET_21
271 DEBUG_NO_STATIC void
272 pfkey_state_change(struct sock *sk)
273 {
274         KLIPS_PRINT(debug_pfkey,
275                     "klips_debug:pfkey_state_change: .\n");
276         if(!sk->dead) {
277                 wake_up_interruptible(sk->sleep);
278         }
279 }
280 #endif /* !NET_21 */
281
282 #ifndef NET_21
283 DEBUG_NO_STATIC void
284 pfkey_data_ready(struct sock *sk, int len)
285 {
286         KLIPS_PRINT(debug_pfkey,
287                     "klips_debug:pfkey_data_ready: "
288                     "sk=%p len=%d\n",
289                     sk,
290                     len);
291         if(!sk->dead) {
292                 wake_up_interruptible(sk->sleep);
293                 sock_wake_async(sk->socket, 1);
294         }
295 }
296
297 DEBUG_NO_STATIC void
298 pfkey_write_space(struct sock *sk)
299 {
300         KLIPS_PRINT(debug_pfkey,
301                     "klips_debug:pfkey_write_space: .\n");
302         if(!sk->dead) {
303                 wake_up_interruptible(sk->sleep);
304                 sock_wake_async(sk->socket, 2);
305         }
306 }
307 #endif /* !NET_21 */
308
309 DEBUG_NO_STATIC void
310 pfkey_insert_socket(struct sock *sk)
311 {
312         KLIPS_PRINT(debug_pfkey,
313                     "klips_debug:pfkey_insert_socket: "
314                     "sk=%p\n",
315                     sk);
316         cli();
317         sk->next=pfkey_sock_list;
318         pfkey_sock_list=sk;
319         sti();
320 }
321
322 DEBUG_NO_STATIC void
323 pfkey_remove_socket(struct sock *sk)
324 {
325         struct sock **s;
326         
327         KLIPS_PRINT(debug_pfkey,
328                     "klips_debug:pfkey_remove_socket: .\n");
329         cli();
330         s=&pfkey_sock_list;
331
332         while(*s!=NULL) {
333                 if(*s==sk) {
334                         *s=sk->next;
335                         sk->next=NULL;
336                         sti();
337                         KLIPS_PRINT(debug_pfkey,
338                                     "klips_debug:pfkey_remove_socket: "
339                                     "succeeded.\n");
340                         return;
341                 }
342                 s=&((*s)->next);
343         }
344         sti();
345         KLIPS_PRINT(debug_pfkey,
346                     "klips_debug:pfkey_remove_socket: "
347                     "not found.\n");
348         return;
349 }
350
351 DEBUG_NO_STATIC void
352 pfkey_destroy_socket(struct sock *sk)
353 {
354         struct sk_buff *skb;
355
356         KLIPS_PRINT(debug_pfkey,
357                     "klips_debug:pfkey_destroy_socket: .\n");
358         pfkey_remove_socket(sk);
359         KLIPS_PRINT(debug_pfkey,
360                     "klips_debug:pfkey_destroy_socket: "
361                     "pfkey_remove_socket called.\n");
362         
363         KLIPS_PRINT(debug_pfkey,
364                     "klips_debug:pfkey_destroy_socket: "
365                     "sk(%p)->(&%p)receive_queue.{next=%p,prev=%p}.\n",
366                     sk,
367                     &(sk->receive_queue),
368                     sk->receive_queue.next,
369                     sk->receive_queue.prev);
370         while(sk && ((skb=skb_dequeue(&(sk->receive_queue)))!=NULL)) {
371 #ifdef NET_21
372 #ifdef CONFIG_IPSEC_DEBUG
373                 if(debug_pfkey && sysctl_ipsec_debug_verbose) {
374                         KLIPS_PRINT(debug_pfkey,
375                                     "klips_debug:pfkey_destroy_socket: "
376                                     "skb=%p dequeued.\n", skb);
377                         printk(KERN_INFO "klips_debug:pfkey_destroy_socket: "
378                                "pfkey_skb contents:");
379                         printk(" next:%p", skb->next);
380                         printk(" prev:%p", skb->prev);
381                         printk(" list:%p", skb->list);
382                         printk(" sk:%p", skb->sk);
383                         printk(" stamp:%ld.%ld", skb->stamp.tv_sec, skb->stamp.tv_usec);
384                         printk(" dev:%p", skb->dev);
385                         if(skb->dev) {
386                                 if(skb->dev->name) {
387                                         printk(" dev->name:%s", skb->dev->name);
388                                 } else {
389                                         printk(" dev->name:NULL?");
390                                 }
391                         } else {
392                                 printk(" dev:NULL");
393                         }
394                         printk(" h:%p", skb->h.raw);
395                         printk(" nh:%p", skb->nh.raw);
396                         printk(" mac:%p", skb->mac.raw);
397                         printk(" dst:%p", skb->dst);
398                         if(sysctl_ipsec_debug_verbose) {
399                                 int i;
400                                 
401                                 printk(" cb");
402                                 for(i=0; i<48; i++) {
403                                         printk(":%2x", skb->cb[i]);
404                                 }
405                         }
406                         printk(" len:%d", skb->len);
407                         printk(" csum:%d", skb->csum);
408 #ifndef NETDEV_23
409                         printk(" used:%d", skb->used);
410                         printk(" is_clone:%d", skb->is_clone);
411 #endif /* NETDEV_23 */
412                         printk(" cloned:%d", skb->cloned);
413                         printk(" pkt_type:%d", skb->pkt_type);
414                         printk(" ip_summed:%d", skb->ip_summed);
415                         printk(" priority:%d", skb->priority);
416                         printk(" protocol:%d", skb->protocol);
417                         printk(" security:%d", skb->security);
418                         printk(" truesize:%d", skb->truesize);
419                         printk(" head:%p", skb->head);
420                         printk(" data:%p", skb->data);
421                         printk(" tail:%p", skb->tail);
422                         printk(" end:%p", skb->end);
423                         if(sysctl_ipsec_debug_verbose) {
424                                 unsigned int i;
425                                 printk(" data");
426                                 for(i=(unsigned int)(skb->head); i<(unsigned int)(skb->end); i++) {
427                                         printk(":%2x", (unsigned char)(*(char*)(i)));
428                                 }
429                         }
430                         printk(" destructor:%p", skb->destructor);
431                         printk("\n");
432                 }
433 #endif /* CONFIG_IPSEC_DEBUG */
434                 KLIPS_PRINT(debug_pfkey,
435                             "klips_debug:pfkey_destroy_socket: "
436                             "skb=%p freed.\n",
437                             skb);
438                 kfree_skb(skb);
439
440 #else /* NET_21 */
441                 KLIPS_PRINT(debug_pfkey,
442                             "klips_debug:pfkey_destroy_socket: "
443                             "skb=%p dequeued and freed.\n",
444                             skb);
445                 kfree_skb(skb, FREE_WRITE);
446
447 #endif /* NET_21 */
448         }
449
450         sk->dead = 1;
451         sk_free(sk);
452
453         KLIPS_PRINT(debug_pfkey,
454                     "klips_debug:pfkey_destroy_socket: destroyed.\n");
455 }
456
457 int
458 pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg)
459 {
460         int error = 0;
461         struct sk_buff * skb = NULL;
462         struct sock *sk;
463
464         if(sock == NULL) {
465                 KLIPS_PRINT(debug_pfkey,
466                             "klips_debug:pfkey_upmsg: "
467                             "NULL socket passed in.\n");
468                 return -EINVAL;
469         }
470
471         if(pfkey_msg == NULL) {
472                 KLIPS_PRINT(debug_pfkey,
473                             "klips_debug:pfkey_upmsg: "
474                             "NULL pfkey_msg passed in.\n");
475                 return -EINVAL;
476         }
477
478 #ifdef NET_21
479         sk = sock->sk;
480 #else /* NET_21 */
481         sk = sock->data;
482 #endif /* NET_21 */
483
484         if(sk == NULL) {
485                 KLIPS_PRINT(debug_pfkey,
486                             "klips_debug:pfkey_upmsg: "
487                             "NULL sock passed in.\n");
488                 return -EINVAL;
489         }
490
491         KLIPS_PRINT(debug_pfkey,
492                     "klips_debug:pfkey_upmsg: "
493                     "allocating %d bytes...\n",
494                     pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
495         if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) {
496                 KLIPS_PRINT(debug_pfkey,
497                             "klips_debug:pfkey_upmsg: "
498                             "no buffers left to send up a message.\n");
499                 return -ENOBUFS;
500         }
501         KLIPS_PRINT(debug_pfkey,
502                     "klips_debug:pfkey_upmsg: "
503                     "...allocated at %p.\n",
504                     skb);
505         
506         skb->dev = NULL;
507         
508         if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
509                 printk(KERN_WARNING "klips_error:pfkey_upmsg: "
510                        "tried to skb_put %ld, %d available.  This should never happen, please report.\n",
511                        (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN,
512                        skb_tailroom(skb));
513 #ifdef NET_21
514                 kfree_skb(skb);
515 #else /* NET_21 */
516                 kfree_skb(skb, FREE_WRITE);
517 #endif /* NET_21 */
518                 return -ENOBUFS;
519         }
520         skb->h.raw = skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
521         memcpy(skb->h.raw, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
522
523 #ifndef NET_21
524         skb->free = 1;
525 #endif /* !NET_21 */
526
527         if((error = sock_queue_rcv_skb(sk, skb)) < 0) {
528                 skb->sk=NULL;
529 #ifdef NET_21
530                 kfree_skb(skb);
531 #else /* NET_21 */
532                 kfree_skb(skb, FREE_WRITE);
533 #endif /* NET_21 */
534                 KLIPS_PRINT(debug_pfkey,
535                             "klips_debug:pfkey_upmsg: "
536                             "error=%d calling sock_queue_rcv_skb with skb=%p.\n",
537                             error,
538                             skb);
539                 return error;
540         }
541         return error;
542 }
543
544 DEBUG_NO_STATIC int
545 pfkey_create(struct socket *sock, int protocol)
546 {
547         struct sock *sk;
548
549         if(sock == NULL) {
550                 KLIPS_PRINT(debug_pfkey,
551                             "klips_debug:pfkey_create: "
552                             "socket NULL.\n");
553                 return -EINVAL;
554         }
555
556         KLIPS_PRINT(debug_pfkey,
557                     "klips_debug:pfkey_create: "
558                     "sock=%p type:%d state:%d flags:%ld protocol:%d\n",
559                     sock,
560                     sock->type,
561                     (unsigned int)(sock->state),
562                     sock->flags, protocol);
563
564         if(sock->type != SOCK_RAW) {
565                 KLIPS_PRINT(debug_pfkey,
566                             "klips_debug:pfkey_create: "
567                             "only SOCK_RAW supported.\n");
568                 return -ESOCKTNOSUPPORT;
569         }
570
571         if(protocol != PF_KEY_V2) {
572                 KLIPS_PRINT(debug_pfkey,
573                             "klips_debug:pfkey_create: "
574                             "protocol not PF_KEY_V2.\n");
575                 return -EPROTONOSUPPORT;
576         }
577
578         if((current->uid != 0)) {
579                 KLIPS_PRINT(debug_pfkey,
580                             "klips_debug:pfkey_create: "
581                             "must be root to open pfkey sockets.\n");
582                 return -EACCES;
583         }
584
585 #ifdef NET_21
586         sock->state = SS_UNCONNECTED;
587 #endif /* NET_21 */
588         MOD_INC_USE_COUNT;
589 #ifdef NET_21
590         if((sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1)) == NULL)
591 #else /* NET_21 */
592         if((sk=(struct sock *)sk_alloc(GFP_KERNEL)) == NULL)
593 #endif /* NET_21 */
594         {
595                 KLIPS_PRINT(debug_pfkey,
596                             "klips_debug:pfkey_create: "
597                             "Out of memory trying to allocate.\n");
598                 MOD_DEC_USE_COUNT;
599                 return -ENOMEM;
600         }
601
602 #ifndef NET_21
603         memset(sk, 0, sizeof(*sk));
604 #endif /* !NET_21 */
605
606 #ifdef NET_21
607         sock_init_data(sock, sk);
608
609         sk->destruct = NULL;
610         sk->reuse = 1;
611         sock->ops = &SOCKOPS_WRAPPED(pfkey_ops);
612
613         sk->zapped=0;
614         sk->family = PF_KEY;
615 /*      sk->num = protocol; */
616         sk->protocol = protocol;
617         key_pid(sk) = current->pid;
618         KLIPS_PRINT(debug_pfkey,
619                     "klips_debug:pfkey_create: "
620                     "sock->fasync_list=%p sk->sleep=%p.\n",
621                     sock->fasync_list,
622                     sk->sleep);
623 #else /* NET_21 */
624         sk->type=sock->type;
625         init_timer(&sk->timer);
626         skb_queue_head_init(&sk->write_queue);
627         skb_queue_head_init(&sk->receive_queue);
628         skb_queue_head_init(&sk->back_log);
629         sk->rcvbuf=SK_RMEM_MAX;
630         sk->sndbuf=SK_WMEM_MAX;
631         sk->allocation=GFP_KERNEL;
632         sk->state=TCP_CLOSE;
633         sk->priority=SOPRI_NORMAL;
634         sk->state_change=pfkey_state_change;
635         sk->data_ready=pfkey_data_ready;
636         sk->write_space=pfkey_write_space;
637         sk->error_report=pfkey_state_change;
638         sk->mtu=4096;
639         sk->socket=sock;
640         sock->data=(void *)sk;
641         sk->sleep=sock->wait;
642 #endif /* NET_21 */
643
644         pfkey_insert_socket(sk);
645         pfkey_list_insert_socket(sock, &pfkey_open_sockets);
646
647         KLIPS_PRINT(debug_pfkey,
648                     "klips_debug:pfkey_create: "
649                     "Socket sock=%p sk=%p initialised.\n", sock, sk);
650         return 0;
651 }
652
653 #ifndef NET_21
654 DEBUG_NO_STATIC int
655 pfkey_dup(struct socket *newsock, struct socket *oldsock)
656 {
657         struct sock *sk;
658
659         if(newsock==NULL) {
660                 KLIPS_PRINT(debug_pfkey,
661                             "klips_debug:pfkey_dup: "
662                             "No new socket attached.\n");
663                 return -EINVAL;
664         }
665                 
666         if(oldsock==NULL) {
667                 KLIPS_PRINT(debug_pfkey,
668                             "klips_debug:pfkey_dup: "
669                             "No old socket attached.\n");
670                 return -EINVAL;
671         }
672                 
673 #ifdef NET_21
674         sk=oldsock->sk;
675 #else /* NET_21 */
676         sk=oldsock->data;
677 #endif /* NET_21 */
678         
679         /* May not have data attached */
680         if(sk==NULL) {
681                 KLIPS_PRINT(debug_pfkey,
682                             "klips_debug:pfkey_dup: "
683                             "No sock attached to old socket.\n");
684                 return -EINVAL;
685         }
686                 
687         KLIPS_PRINT(debug_pfkey,
688                     "klips_debug:pfkey_dup: .\n");
689
690         return pfkey_create(newsock, sk->protocol);
691 }
692 #endif /* !NET_21 */
693
694 DEBUG_NO_STATIC int
695 #ifdef NETDEV_23
696 pfkey_release(struct socket *sock)
697 #else /* NETDEV_23 */
698 pfkey_release(struct socket *sock, struct socket *peersock)
699 #endif /* NETDEV_23 */
700 {
701         struct sock *sk;
702         int i;
703
704         if(sock==NULL) {
705                 KLIPS_PRINT(debug_pfkey,
706                             "klips_debug:pfkey_release: "
707                             "No socket attached.\n");
708                 return 0; /* -EINVAL; */
709         }
710                 
711 #ifdef NET_21
712         sk=sock->sk;
713 #else /* NET_21 */
714         sk=sock->data;
715 #endif /* NET_21 */
716         
717         /* May not have data attached */
718         if(sk==NULL) {
719                 KLIPS_PRINT(debug_pfkey,
720                             "klips_debug:pfkey_release: "
721                             "No sk attached to sock=%p.\n", sock);
722                 return 0; /* -EINVAL; */
723         }
724                 
725         KLIPS_PRINT(debug_pfkey,
726                     "klips_debug:pfkey_release: "
727                     "sock=%p sk=%p\n", sock, sk);
728
729 #ifdef NET_21
730         if(!sk->dead)
731 #endif /* NET_21 */
732                 if(sk->state_change) {
733                         sk->state_change(sk);
734                 }
735
736 #ifdef NET_21
737         sock->sk = NULL;
738 #else /* NET_21 */
739         sock->data = NULL;
740 #endif /* NET_21 */
741
742         /* Try to flush out this socket. Throw out buffers at least */
743         pfkey_destroy_socket(sk);
744         pfkey_list_remove_socket(sock, &pfkey_open_sockets);
745         for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
746                 pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i]));
747         }
748
749         MOD_DEC_USE_COUNT;
750         KLIPS_PRINT(debug_pfkey,
751                     "klips_debug:pfkey_release: "
752                     "succeeded.\n");
753
754         return 0;
755 }
756
757 #ifndef NET_21
758 DEBUG_NO_STATIC int
759 pfkey_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
760 {
761         KLIPS_PRINT(debug_pfkey,
762                     "klips_debug:pfkey_bind: "
763                     "operation not supported.\n");
764         return -EINVAL;
765 }
766
767 DEBUG_NO_STATIC int
768 pfkey_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags)
769 {
770         KLIPS_PRINT(debug_pfkey,
771                     "klips_debug:pfkey_connect: "
772                     "operation not supported.\n");
773         return -EINVAL;
774 }
775
776 DEBUG_NO_STATIC int
777 pfkey_socketpair(struct socket *a, struct socket *b)
778 {
779         KLIPS_PRINT(debug_pfkey,
780                     "klips_debug:pfkey_socketpair: "
781                     "operation not supported.\n");
782         return -EINVAL;
783 }
784
785 DEBUG_NO_STATIC int
786 pfkey_accept(struct socket *sock, struct socket *newsock, int flags)
787 {
788         KLIPS_PRINT(debug_pfkey,
789                     "klips_debug:pfkey_aaccept: "
790                     "operation not supported.\n");
791         return -EINVAL;
792 }
793
794 DEBUG_NO_STATIC int
795 pfkey_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len,
796                 int peer)
797 {
798         struct sockaddr *ska = (struct sockaddr*)uaddr;
799         
800         KLIPS_PRINT(debug_pfkey,
801                     "klips_debug:pfkey_getname: .\n");
802         ska->sa_family = PF_KEY;
803         *uaddr_len = sizeof(*ska);
804         return 0;
805 }
806
807 DEBUG_NO_STATIC int
808 pfkey_select(struct socket *sock, int sel_type, select_table *wait)
809 {
810         
811         KLIPS_PRINT(debug_pfkey,
812                     "klips_debug:pfkey_select: "
813                     ".sock=%p sk=%p sel_type=%d\n",
814                     sock,
815                     sock->data,
816                     sel_type);
817         if(sock == NULL) {
818                 KLIPS_PRINT(debug_pfkey,
819                             "klips_debug:pfkey_select: "
820                             "Null socket passed in.\n");
821                 return -EINVAL;
822         }
823         return datagram_select(sock->data, sel_type, wait);
824 }
825
826 DEBUG_NO_STATIC int
827 pfkey_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
828 {
829         KLIPS_PRINT(debug_pfkey,
830                     "klips_debug:pfkey_ioctl: "
831                     "not supported.\n");
832         return -EINVAL;
833 }
834
835 DEBUG_NO_STATIC int
836 pfkey_listen(struct socket *sock, int backlog)
837 {
838         KLIPS_PRINT(debug_pfkey,
839                     "klips_debug:pfkey_listen: "
840                     "not supported.\n");
841         return -EINVAL;
842 }
843 #endif /* !NET_21 */
844
845 DEBUG_NO_STATIC int
846 pfkey_shutdown(struct socket *sock, int mode)
847 {
848         struct sock *sk;
849
850         if(sock == NULL) {
851                 KLIPS_PRINT(debug_pfkey,
852                             "klips_debug:pfkey_shutdown: "
853                             "NULL socket passed in.\n");
854                 return -EINVAL;
855         }
856
857 #ifdef NET_21
858         sk=sock->sk;
859 #else /* NET_21 */
860         sk=sock->data;
861 #endif /* NET_21 */
862         
863         if(sk == NULL) {
864                 KLIPS_PRINT(debug_pfkey,
865                             "klips_debug:pfkey_shutdown: "
866                             "No sock attached to socket.\n");
867                 return -EINVAL;
868         }
869
870         KLIPS_PRINT(debug_pfkey,
871                     "klips_debug:pfkey_shutdown: "
872                     "mode=%x.\n", mode);
873         mode++;
874         
875         if(mode&SEND_SHUTDOWN) {
876                 sk->shutdown|=SEND_SHUTDOWN;
877                 sk->state_change(sk);
878         }
879
880         if(mode&RCV_SHUTDOWN) {
881                 sk->shutdown|=RCV_SHUTDOWN;
882                 sk->state_change(sk);
883         }
884         return 0;
885 }
886
887 #ifndef NET_21
888 DEBUG_NO_STATIC int
889 pfkey_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
890 {
891 #ifndef NET_21
892         struct sock *sk;
893
894         if(sock == NULL) {
895                 KLIPS_PRINT(debug_pfkey,
896                             "klips_debug:pfkey_setsockopt: "
897                             "Null socket passed in.\n");
898                 return -EINVAL;
899         }
900         
901         sk=sock->data;
902         
903         if(sk == NULL) {
904                 KLIPS_PRINT(debug_pfkey,
905                             "klips_debug:pfkey_setsockopt: "
906                             "Null sock passed in.\n");
907                 return -EINVAL;
908         }
909 #endif /* !NET_21 */
910         
911         KLIPS_PRINT(debug_pfkey,
912                     "klips_debug:pfkey_setsockopt: .\n");
913         if(level!=SOL_SOCKET) {
914                 return -EOPNOTSUPP;
915         }
916 #ifdef NET_21
917         return sock_setsockopt(sock, level, optname, optval, optlen);
918 #else /* NET_21 */
919         return sock_setsockopt(sk, level, optname, optval, optlen);
920 #endif /* NET_21 */
921 }
922
923 DEBUG_NO_STATIC int
924 pfkey_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
925 {
926 #ifndef NET_21
927         struct sock *sk;
928
929         if(sock == NULL) {
930                 KLIPS_PRINT(debug_pfkey,
931                             "klips_debug:pfkey_setsockopt: "
932                             "Null socket passed in.\n");
933                 return -EINVAL;
934         }
935         
936         sk=sock->data;
937         
938         if(sk == NULL) {
939                 KLIPS_PRINT(debug_pfkey,
940                             "klips_debug:pfkey_setsockopt: "
941                             "Null sock passed in.\n");
942                 return -EINVAL;
943         }
944 #endif /* !NET_21 */
945
946         KLIPS_PRINT(debug_pfkey,
947                     "klips_debug:pfkey_getsockopt: .\n");
948         if(level!=SOL_SOCKET) {
949                 return -EOPNOTSUPP;
950         }
951 #ifdef NET_21
952         return sock_getsockopt(sock, level, optname, optval, optlen);
953 #else /* NET_21 */
954         return sock_getsockopt(sk, level, optname, optval, optlen);
955 #endif /* NET_21 */
956 }
957
958 DEBUG_NO_STATIC int
959 pfkey_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
960 {
961         KLIPS_PRINT(debug_pfkey,
962                     "klips_debug:pfkey_fcntl: "
963                     "not supported.\n");
964         return -EINVAL;
965 }
966 #endif /* !NET_21 */
967
968 /*
969  *      Send PF_KEY data down.
970  */
971                 
972 DEBUG_NO_STATIC int
973 #ifdef NET_21
974 pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
975 #else /* NET_21 */
976 pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags)
977 #endif /* NET_21 */
978 {
979         struct sock *sk;
980         int error = 0;
981         struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL;
982         
983         if(sock == NULL) {
984                 KLIPS_PRINT(debug_pfkey,
985                             "klips_debug:pfkey_sendmsg: "
986                             "Null socket passed in.\n");
987                 SENDERR(EINVAL);
988         }
989         
990 #ifdef NET_21
991         sk = sock->sk;
992 #else /* NET_21 */
993         sk = sock->data;
994 #endif /* NET_21 */
995
996         if(sk == NULL) {
997                 KLIPS_PRINT(debug_pfkey,
998                             "klips_debug:pfkey_sendmsg: "
999                             "Null sock passed in.\n");
1000                 SENDERR(EINVAL);
1001         }
1002         
1003         if(msg == NULL) {
1004                 KLIPS_PRINT(debug_pfkey,
1005                             "klips_debug:pfkey_sendmsg: "
1006                             "Null msghdr passed in.\n");
1007                 SENDERR(EINVAL);
1008         }
1009
1010         KLIPS_PRINT(debug_pfkey,
1011                     "klips_debug:pfkey_sendmsg: .\n");
1012         if(sk->err) {
1013                 error = sock_error(sk);
1014                 KLIPS_PRINT(debug_pfkey,
1015                             "klips_debug:pfkey_sendmsg: "
1016                             "sk->err is non-zero, returns %d.\n",
1017                             error);
1018                 SENDERR(-error);
1019         }
1020
1021         if((current->uid != 0)) {
1022                 KLIPS_PRINT(debug_pfkey,
1023                             "klips_debug:pfkey_sendmsg: "
1024                             "must be root to send messages to pfkey sockets.\n");
1025                 SENDERR(EACCES);
1026         }
1027
1028 #ifdef NET_21
1029         if(msg->msg_control)
1030 #else /* NET_21 */
1031         if(flags || msg->msg_control)
1032 #endif /* NET_21 */
1033         {
1034                 KLIPS_PRINT(debug_pfkey,
1035                             "klips_debug:pfkey_sendmsg: "
1036                             "can't set flags or set msg_control.\n");
1037                 SENDERR(EINVAL);
1038         }
1039                 
1040         if(sk->shutdown & SEND_SHUTDOWN) {
1041                 KLIPS_PRINT(debug_pfkey,
1042                             "klips_debug:pfkey_sendmsg: "
1043                             "shutdown.\n");
1044                 send_sig(SIGPIPE, current, 0);
1045                 SENDERR(EPIPE);
1046         }
1047         
1048         if(len < sizeof(struct sadb_msg)) {
1049                 KLIPS_PRINT(debug_pfkey,
1050                             "klips_debug:pfkey_sendmsg: "
1051                             "bogus msg len of %d, too small.\n", len);
1052                 SENDERR(EMSGSIZE);
1053         }
1054
1055         if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) {
1056                 KLIPS_PRINT(debug_pfkey,
1057                             "klips_debug:pfkey_sendmsg: "
1058                             "memory allocation error.\n");
1059                 SENDERR(ENOBUFS);
1060         }
1061
1062         memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len);
1063
1064         if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
1065                 KLIPS_PRINT(1 || debug_pfkey,
1066                             "klips_debug:pfkey_sendmsg: "
1067                             "not PF_KEY_V2 msg, found %d, should be %d.\n",
1068                             pfkey_msg->sadb_msg_version,
1069                             PF_KEY_V2);
1070                 kfree((void*)pfkey_msg);
1071                 return -EINVAL;
1072         }
1073
1074         if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
1075                 KLIPS_PRINT(debug_pfkey,
1076                             "klips_debug:pfkey_sendmsg: "
1077                             "bogus msg len of %d, not %d byte aligned.\n",
1078                             len, IPSEC_PFKEYv2_ALIGN);
1079                 SENDERR(EMSGSIZE);
1080         }
1081
1082 #if 0
1083         /* This check is questionable, since a downward message could be
1084            the result of an ACQUIRE either from kernel (PID==0) or
1085            userspace (some other PID). */
1086         /* check PID */
1087         if(pfkey_msg->sadb_msg_pid != current->pid) {
1088                 KLIPS_PRINT(debug_pfkey,
1089                             "klips_debug:pfkey_sendmsg: "
1090                             "pid (%d) does not equal sending process pid (%d).\n",
1091                             pfkey_msg->sadb_msg_pid, current->pid);
1092                 SENDERR(EINVAL);
1093         }
1094 #endif
1095
1096         if(pfkey_msg->sadb_msg_reserved) {
1097                 KLIPS_PRINT(debug_pfkey,
1098                             "klips_debug:pfkey_sendmsg: "
1099                             "reserved field must be zero, set to %d.\n",
1100                             pfkey_msg->sadb_msg_reserved);
1101                 SENDERR(EINVAL);
1102         }
1103         
1104         if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){
1105                 KLIPS_PRINT(debug_pfkey,
1106                             "klips_debug:pfkey_sendmsg: "
1107                             "msg type too large or small:%d.\n",
1108                             pfkey_msg->sadb_msg_type);
1109                 SENDERR(EINVAL);
1110         }
1111         
1112         KLIPS_PRINT(debug_pfkey,
1113                     "klips_debug:pfkey_sendmsg: "
1114                     "msg sent for parsing.\n");
1115         
1116         if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) {
1117                 struct socket_list *pfkey_socketsp;
1118
1119                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
1120                             "pfkey_msg_parse returns %d.\n",
1121                             error);
1122
1123                 if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) {
1124                         KLIPS_PRINT(debug_pfkey,
1125                                     "klips_debug:pfkey_sendmsg: "
1126                                     "memory allocation error.\n");
1127                         SENDERR(ENOBUFS);
1128                 }
1129                 memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg));
1130                 pfkey_reply->sadb_msg_errno = -error;
1131                 pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
1132
1133                 for(pfkey_socketsp = pfkey_open_sockets;
1134                     pfkey_socketsp;
1135                     pfkey_socketsp = pfkey_socketsp->next) {
1136                         int error_upmsg = 0;
1137                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
1138                                     "sending up error=%d message=%p to socket=%p.\n",
1139                                     error,
1140                                     pfkey_reply,
1141                                     pfkey_socketsp->socketp);
1142                         if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
1143                                 KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
1144                                             "sending up error message to socket=%p failed with error=%d.\n",
1145                                             pfkey_socketsp->socketp,
1146                                             error_upmsg);
1147                                 /* pfkey_msg_free(&pfkey_reply); */
1148                                 /* SENDERR(-error); */
1149                         }
1150                         KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
1151                                     "sending up error message to socket=%p succeeded.\n",
1152                                     pfkey_socketsp->socketp);
1153                 }
1154                 
1155                 pfkey_msg_free(&pfkey_reply);
1156                 
1157                 SENDERR(-error);
1158         }
1159
1160  errlab:
1161         if (pfkey_msg) {
1162                 kfree((void*)pfkey_msg);
1163         }
1164         
1165         if(error) {
1166                 return error;
1167         } else {
1168                 return len;
1169         }
1170 }
1171
1172 /*
1173  *      Receive PF_KEY data up.
1174  */
1175                 
1176 DEBUG_NO_STATIC int
1177 #ifdef NET_21
1178 pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm)
1179 #else /* NET_21 */
1180 pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock, int flags, int *addr_len)
1181 #endif /* NET_21 */
1182 {
1183         struct sock *sk;
1184 #ifdef NET_21
1185         int noblock = flags & MSG_DONTWAIT;
1186 #endif /* NET_21 */
1187         struct sk_buff *skb;
1188         int error;
1189
1190         if(sock == NULL) {
1191                 KLIPS_PRINT(debug_pfkey,
1192                             "klips_debug:pfkey_recvmsg: "
1193                             "Null socket passed in.\n");
1194                 return -EINVAL;
1195         }
1196
1197 #ifdef NET_21
1198         sk = sock->sk;
1199 #else /* NET_21 */
1200         sk = sock->data;
1201 #endif /* NET_21 */
1202
1203         if(sk == NULL) {
1204                 KLIPS_PRINT(debug_pfkey,
1205                             "klips_debug:pfkey_recvmsg: "
1206                             "Null sock passed in for sock=%p.\n", sock);
1207                 return -EINVAL;
1208         }
1209
1210         if(msg == NULL) {
1211                 KLIPS_PRINT(debug_pfkey,
1212                             "klips_debug:pfkey_recvmsg: "
1213                             "Null msghdr passed in for sock=%p, sk=%p.\n",
1214                             sock, sk);
1215                 return -EINVAL;
1216         }
1217
1218         KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
1219                     "klips_debug:pfkey_recvmsg: sock=%p sk=%p msg=%p size=%d.\n",
1220                     sock, sk, msg, size);
1221         if(flags & ~MSG_PEEK) {
1222                 KLIPS_PRINT(debug_pfkey,
1223                             "klips_debug:pfkey_sendmsg: "
1224                             "flags (%d) other than MSG_PEEK not supported.\n",
1225                             flags);
1226                 return -EOPNOTSUPP;
1227         }
1228                 
1229 #ifdef NET_21
1230         msg->msg_namelen = 0; /* sizeof(*ska); */
1231 #else /* NET_21 */
1232         if(addr_len) {
1233                 *addr_len = 0; /* sizeof(*ska); */
1234         }
1235 #endif /* NET_21 */
1236                 
1237         if(sk->err) {
1238                 KLIPS_PRINT(debug_pfkey,
1239                             "klips_debug:pfkey_sendmsg: "
1240                             "sk->err=%d.\n", sk->err);
1241                 return sock_error(sk);
1242         }
1243
1244         if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) {
1245                 return error;
1246         }
1247
1248         if(size > skb->len) {
1249                 size = skb->len;
1250         }
1251 #ifdef NET_21
1252         else if(size <skb->len) {
1253                 msg->msg_flags |= MSG_TRUNC;
1254         }
1255 #endif /* NET_21 */
1256
1257         skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
1258         sk->stamp=skb->stamp;
1259
1260         skb_free_datagram(sk, skb);
1261         return size;
1262 }
1263
1264 #ifdef NET_21
1265 struct net_proto_family pfkey_family_ops = {
1266         PF_KEY,
1267         pfkey_create
1268 };
1269
1270 struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = {
1271 #ifdef NETDEV_23
1272         family:         PF_KEY,
1273         release:        pfkey_release,
1274         bind:           sock_no_bind,
1275         connect:        sock_no_connect,
1276         socketpair:     sock_no_socketpair,
1277         accept:         sock_no_accept,
1278         getname:        sock_no_getname,
1279         poll:           datagram_poll,
1280         ioctl:          sock_no_ioctl,
1281         listen:         sock_no_listen,
1282         shutdown:       pfkey_shutdown,
1283         setsockopt:     sock_no_setsockopt,
1284         getsockopt:     sock_no_getsockopt,
1285         sendmsg:        pfkey_sendmsg,
1286         recvmsg:        pfkey_recvmsg,
1287         mmap:           sock_no_mmap,
1288 #else /* NETDEV_23 */
1289         PF_KEY,
1290         sock_no_dup,
1291         pfkey_release,
1292         sock_no_bind,
1293         sock_no_connect,
1294         sock_no_socketpair,
1295         sock_no_accept,
1296         sock_no_getname,
1297         datagram_poll,
1298         sock_no_ioctl,
1299         sock_no_listen,
1300         pfkey_shutdown,
1301         sock_no_setsockopt,
1302         sock_no_getsockopt,
1303         sock_no_fcntl,
1304         pfkey_sendmsg,
1305         pfkey_recvmsg
1306 #endif /* NETDEV_23 */
1307 };
1308
1309 #ifdef NETDEV_23
1310 #include <linux/smp_lock.h>
1311 SOCKOPS_WRAP(pfkey, PF_KEY);
1312 #endif /* NETDEV_23 */
1313
1314 #else /* NET_21 */
1315 struct proto_ops pfkey_proto_ops = {
1316         PF_KEY,
1317         pfkey_create,
1318         pfkey_dup,
1319         pfkey_release,
1320         pfkey_bind,
1321         pfkey_connect,
1322         pfkey_socketpair,
1323         pfkey_accept,
1324         pfkey_getname,
1325         pfkey_select,
1326         pfkey_ioctl,
1327         pfkey_listen,
1328         pfkey_shutdown,
1329         pfkey_setsockopt,
1330         pfkey_getsockopt,
1331         pfkey_fcntl,
1332         pfkey_sendmsg,
1333         pfkey_recvmsg
1334 };
1335 #endif /* NET_21 */
1336    
1337 #ifdef CONFIG_PROC_FS
1338 #ifndef PROC_FS_2325
1339 DEBUG_NO_STATIC
1340 #endif /* PROC_FS_2325 */
1341 int
1342 pfkey_get_info(char *buffer, char **start, off_t offset, int length
1343 #ifndef  PROC_NO_DUMMY
1344 , int dummy
1345 #endif /* !PROC_NO_DUMMY */
1346 )
1347 {
1348         off_t pos=0;
1349         off_t begin=0;
1350         int len=0;
1351         struct sock *sk=pfkey_sock_list;
1352         
1353 #ifdef CONFIG_IPSEC_DEBUG
1354         if(!sysctl_ipsec_debug_verbose) {
1355 #endif /* CONFIG_IPSEC_DEBUG */
1356         len+= sprintf(buffer,
1357                       "    sock   pid   socket     next     prev e n p sndbf    Flags     Type St\n");
1358 #ifdef CONFIG_IPSEC_DEBUG
1359         } else {
1360         len+= sprintf(buffer,
1361                       "    sock   pid d    sleep   socket     next     prev e r z n p sndbf    stamp    Flags     Type St\n");
1362         }
1363 #endif /* CONFIG_IPSEC_DEBUG */
1364         
1365         while(sk!=NULL) {
1366 #ifdef CONFIG_IPSEC_DEBUG
1367                 if(!sysctl_ipsec_debug_verbose) {
1368 #endif /* CONFIG_IPSEC_DEBUG */
1369                 len+=sprintf(buffer+len,
1370                              "%8p %5d %8p %8p %8p %d %d %d %5d %08lX %8X %2X\n",
1371                              sk,
1372                              key_pid(sk),
1373                              sk->socket,
1374                              sk->next,
1375                              sk->prev,
1376                              sk->err,
1377                              sk->num,
1378                              sk->protocol,
1379                              sk->sndbuf,
1380                              sk->socket->flags,
1381                              sk->socket->type,
1382                              sk->socket->state);
1383 #ifdef CONFIG_IPSEC_DEBUG
1384                 } else {
1385                 len+=sprintf(buffer+len,
1386                              "%8p %5d %d %8p %8p %8p %8p %d %d %d %d %d %5d %d.%06d %08lX %8X %2X\n",
1387                              sk,
1388                              key_pid(sk),
1389                              sk->dead,
1390                              sk->sleep,
1391                              sk->socket,
1392                              sk->next,
1393                              sk->prev,
1394                              sk->err,
1395                              sk->reuse,
1396                              sk->zapped,
1397                              sk->num,
1398                              sk->protocol,
1399                              sk->sndbuf,
1400                              (unsigned int)sk->stamp.tv_sec,
1401                              (unsigned int)sk->stamp.tv_usec,
1402                              sk->socket->flags,
1403                              sk->socket->type,
1404                              sk->socket->state);
1405                 }
1406 #endif /* CONFIG_IPSEC_DEBUG */
1407                 
1408                 pos=begin+len;
1409                 if(pos<offset)
1410                 {
1411                         len=0;
1412                         begin=pos;
1413                 }
1414                 if(pos>offset+length)
1415                         break;
1416                 sk=sk->next;
1417         }
1418         *start=buffer+(offset-begin);
1419         len-=(offset-begin);
1420         if(len>length)
1421                 len=length;
1422         return len;
1423 }
1424
1425 #ifndef PROC_FS_2325
1426 DEBUG_NO_STATIC
1427 #endif /* PROC_FS_2325 */
1428 int
1429 pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length
1430 #ifndef  PROC_NO_DUMMY
1431 , int dummy
1432 #endif /* !PROC_NO_DUMMY */
1433 )
1434 {
1435         off_t pos=0;
1436         off_t begin=0;
1437         int len=0;
1438         int satype;
1439         struct supported_list *pfkey_supported_p;
1440         
1441         len+= sprintf(buffer,
1442                       "satype exttype alg_id ivlen minbits maxbits\n");
1443         
1444         for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
1445                 pfkey_supported_p = pfkey_supported_list[satype];
1446                 while(pfkey_supported_p) {
1447                         len+=sprintf(buffer+len,
1448                                      "    %2d      %2d     %2d   %3d     %3d     %3d\n",
1449                                      satype,
1450                                      pfkey_supported_p->supportedp->supported_alg_exttype,
1451                                      pfkey_supported_p->supportedp->supported_alg_id,
1452                                      pfkey_supported_p->supportedp->supported_alg_ivlen,
1453                                      pfkey_supported_p->supportedp->supported_alg_minbits,
1454                                      pfkey_supported_p->supportedp->supported_alg_maxbits);
1455                         
1456                         pos=begin+len;
1457                         if(pos<offset) {
1458                                 len=0;
1459                                 begin=pos;
1460                         }
1461                         if(pos>offset+length)
1462                                 break;
1463                         pfkey_supported_p = pfkey_supported_p->next;
1464                 }
1465         }
1466         *start=buffer+(offset-begin);
1467         len-=(offset-begin);
1468         if(len>length)
1469                 len=length;
1470         return len;
1471 }
1472
1473 #ifndef PROC_FS_2325
1474 DEBUG_NO_STATIC
1475 #endif /* PROC_FS_2325 */
1476 int
1477 pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length
1478 #ifndef  PROC_NO_DUMMY
1479 , int dummy
1480 #endif /* !PROC_NO_DUMMY */
1481 )
1482 {
1483         off_t pos=0;
1484         off_t begin=0;
1485         int len=0;
1486         int satype;
1487         struct socket_list *pfkey_sockets;
1488         
1489         len+= sprintf(buffer,
1490                       "satype   socket   pid       sk\n");
1491         
1492         for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
1493                 pfkey_sockets = pfkey_registered_sockets[satype];
1494                 while(pfkey_sockets) {
1495 #ifdef NET_21
1496                         len+=sprintf(buffer+len,
1497                                      "    %2d %8p %5d %8p\n",
1498                                      satype,
1499                                      pfkey_sockets->socketp,
1500                                      key_pid(pfkey_sockets->socketp->sk),
1501                                      pfkey_sockets->socketp->sk);
1502 #else /* NET_21 */
1503                         len+=sprintf(buffer+len,
1504                                      "    %2d %8p   N/A %8p\n",
1505                                      satype,
1506                                      pfkey_sockets->socketp,
1507 #if 0
1508                                      key_pid((pfkey_sockets->socketp)->data),
1509 #endif
1510                                      (pfkey_sockets->socketp)->data);
1511 #endif /* NET_21 */
1512                         
1513                         pos=begin+len;
1514                         if(pos<offset) {
1515                                 len=0;
1516                                 begin=pos;
1517                         }
1518                         if(pos>offset+length)
1519                                 break;
1520                         pfkey_sockets = pfkey_sockets->next;
1521                 }
1522         }
1523         *start=buffer+(offset-begin);
1524         len-=(offset-begin);
1525         if(len>length)
1526                 len=length;
1527         return len;
1528 }
1529
1530 #ifndef PROC_FS_2325
1531 struct proc_dir_entry proc_net_pfkey =
1532 {
1533         0,
1534         6, "pf_key",
1535         S_IFREG | S_IRUGO, 1, 0, 0,
1536         0, &proc_net_inode_operations,
1537         pfkey_get_info
1538 };
1539 struct proc_dir_entry proc_net_pfkey_supported =
1540 {
1541         0,
1542         16, "pf_key_supported",
1543         S_IFREG | S_IRUGO, 1, 0, 0,
1544         0, &proc_net_inode_operations,
1545         pfkey_supported_get_info
1546 };
1547 struct proc_dir_entry proc_net_pfkey_registered =
1548 {
1549         0,
1550         17, "pf_key_registered",
1551         S_IFREG | S_IRUGO, 1, 0, 0,
1552         0, &proc_net_inode_operations,
1553         pfkey_registered_get_info
1554 };
1555 #endif /* !PROC_FS_2325 */
1556 #endif /* CONFIG_PROC_FS */
1557
1558 DEBUG_NO_STATIC int
1559 supported_add_all(int satype, struct supported supported[], int size)
1560 {
1561         int i;
1562         int error = 0;
1563
1564         KLIPS_PRINT(debug_pfkey,
1565                     "klips_debug:init_pfkey: "
1566                     "sizeof(supported_init_<satype=%d>)[%d]/sizeof(struct supported)[%d]=%d.\n",
1567                     satype,
1568                     size,
1569                     sizeof(struct supported),
1570                     size/sizeof(struct supported));
1571
1572         for(i = 0; i < size / sizeof(struct supported); i++) {
1573                 
1574                 KLIPS_PRINT(debug_pfkey,
1575                             "klips_debug:init_pfkey: "
1576                             "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
1577                             i,
1578                             satype,
1579                             supported[i].supported_alg_exttype,
1580                             supported[i].supported_alg_id,
1581                             supported[i].supported_alg_ivlen,
1582                             supported[i].supported_alg_minbits,
1583                             supported[i].supported_alg_maxbits);
1584                             
1585                 error |= pfkey_list_insert_supported(&(supported[i]),
1586                                             &(pfkey_supported_list[satype]));
1587         }
1588         return error;
1589 }
1590
1591 DEBUG_NO_STATIC int
1592 supported_remove_all(int satype)
1593 {
1594         int error = 0;
1595         struct supported*supportedp;
1596
1597         while(pfkey_supported_list[satype]) {
1598                 supportedp = pfkey_supported_list[satype]->supportedp;
1599                 KLIPS_PRINT(debug_pfkey,
1600                             "klips_debug:init_pfkey: "
1601                             "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
1602                             satype,
1603                             supportedp->supported_alg_exttype,
1604                             supportedp->supported_alg_id,
1605                             supportedp->supported_alg_ivlen,
1606                             supportedp->supported_alg_minbits,
1607                             supportedp->supported_alg_maxbits);
1608                             
1609                 error |= pfkey_list_remove_supported(supportedp,
1610                                             &(pfkey_supported_list[satype]));
1611         }
1612         return error;
1613 }
1614
1615 int
1616 pfkey_init(void)
1617 {
1618         int error = 0;
1619         int i;
1620         
1621         static struct supported supported_init_ah[] = {
1622 #ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
1623                 {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
1624 #endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
1625 #ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
1626                 {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160}
1627 #endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
1628         };
1629         static struct supported supported_init_esp[] = {
1630 #ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
1631                 {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
1632 #endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
1633 #ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
1634                 {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160},
1635 #endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
1636 #ifdef CONFIG_IPSEC_ENC_DES
1637                 {SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_DESCBC, 64, 64, 168},
1638 #endif /* CONFIG_IPSEC_ENC_DES */
1639 #ifdef CONFIG_IPSEC_ENC_3DES
1640                 {SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_3DESCBC, 64, 168, 168}
1641 #endif /* CONFIG_IPSEC_ENC_3DES */
1642         };
1643         static struct supported supported_init_ipip[] = {
1644                 {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32}
1645 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1646                 , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32}
1647                 , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128}
1648                 , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128}
1649 #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
1650         };
1651 #ifdef CONFIG_IPSEC_IPCOMP
1652         static struct supported supported_init_ipcomp[] = {
1653                 {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1},
1654 #ifdef CONFIG_IPSEC_IPCOMP_LZS
1655                 {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_LZS, 0, 1, 1}
1656 #endif
1657         };
1658 #endif /* CONFIG_IPSEC_IPCOMP */
1659
1660 #if 0
1661         printk(KERN_INFO
1662                "klips_info:pfkey_init: "
1663                "FreeS/WAN: initialising PF_KEYv2 domain sockets.\n");
1664 #endif
1665
1666         for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
1667                 pfkey_registered_sockets[i] = NULL;
1668                 pfkey_supported_list[i] = NULL;
1669         }
1670
1671         error |= supported_add_all(SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah));
1672         error |= supported_add_all(SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp));
1673 #ifdef CONFIG_IPSEC_IPCOMP
1674         error |= supported_add_all(SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp));
1675 #endif /* CONFIG_IPSEC_IPCOMP */
1676         error |= supported_add_all(SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip));
1677
1678 #ifdef NET_21
1679         error |= sock_register(&pfkey_family_ops);
1680 #else /* NET_21 */
1681         error |= sock_register(pfkey_proto_ops.family, &pfkey_proto_ops);
1682 #endif /* NET_21 */
1683
1684 #ifdef CONFIG_PROC_FS
1685 #  ifndef PROC_FS_2325
1686 #    ifdef PROC_FS_21
1687         error |= proc_register(proc_net, &proc_net_pfkey);
1688         error |= proc_register(proc_net, &proc_net_pfkey_supported);
1689         error |= proc_register(proc_net, &proc_net_pfkey_registered);
1690 #    else /* PROC_FS_21 */
1691         error |= proc_register_dynamic(&proc_net, &proc_net_pfkey);
1692         error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_supported);
1693         error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_registered);
1694 #    endif /* PROC_FS_21 */
1695 #  else /* !PROC_FS_2325 */
1696         proc_net_create ("pf_key", 0, pfkey_get_info);
1697         proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info);
1698         proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info);
1699 #  endif /* !PROC_FS_2325 */
1700 #endif /* CONFIG_PROC_FS */
1701
1702         return error;
1703 }
1704
1705 int
1706 pfkey_cleanup(void)
1707 {
1708         int error = 0;
1709         
1710         printk(KERN_INFO "klips_info:pfkey_cleanup: "
1711                "shutting down PF_KEY domain sockets.\n");
1712 #ifdef NET_21
1713         error |= sock_unregister(PF_KEY);
1714 #else /* NET_21 */
1715         error |= sock_unregister(pfkey_proto_ops.family);
1716 #endif /* NET_21 */
1717
1718         error |= supported_remove_all(SADB_SATYPE_AH);
1719         error |= supported_remove_all(SADB_SATYPE_ESP);
1720 #ifdef CONFIG_IPSEC_IPCOMP
1721         error |= supported_remove_all(SADB_X_SATYPE_COMP);
1722 #endif /* CONFIG_IPSEC_IPCOMP */
1723         error |= supported_remove_all(SADB_X_SATYPE_IPIP);
1724
1725 #ifdef CONFIG_PROC_FS
1726 #  ifndef PROC_FS_2325
1727         if (proc_net_unregister(proc_net_pfkey.low_ino) != 0)
1728                 printk("klips_debug:pfkey_cleanup: "
1729                        "cannot unregister /proc/net/pf_key\n");
1730         if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0)
1731                 printk("klips_debug:pfkey_cleanup: "
1732                        "cannot unregister /proc/net/pf_key_supported\n");
1733         if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0)
1734                 printk("klips_debug:pfkey_cleanup: "
1735                        "cannot unregister /proc/net/pf_key_registered\n");
1736 #  else /* !PROC_FS_2325 */
1737         proc_net_remove ("pf_key");
1738         proc_net_remove ("pf_key_supported");
1739         proc_net_remove ("pf_key_registered");
1740 #  endif /* !PROC_FS_2325 */
1741 #endif /* CONFIG_PROC_FS */
1742
1743         /* other module unloading cleanup happens here */
1744         return error;
1745 }
1746
1747 #ifdef MODULE
1748 #if 0
1749 int
1750 init_module(void)
1751 {
1752         pfkey_init();
1753         return 0;
1754 }
1755
1756 void
1757 cleanup_module(void)
1758 {
1759         pfkey_cleanup();
1760 }
1761 #endif /* 0 */
1762 #else /* MODULE */
1763 void
1764 pfkey_proto_init(struct net_proto *pro)
1765 {
1766         pfkey_init();
1767 }
1768 #endif /* MODULE */
1769
1770 /*
1771  * $Log: pfkey_v2.c,v $
1772  * Revision 1.68  2002/03/08 01:15:17  mcr
1773  *      put some internal structure only debug messages behind
1774  *      && sysctl_ipsec_debug_verbose.
1775  *
1776  * Revision 1.67  2002/01/29 17:17:57  mcr
1777  *      moved include of ipsec_param.h to after include of linux/kernel.h
1778  *      otherwise, it seems that some option that is set in ipsec_param.h
1779  *      screws up something subtle in the include path to kernel.h, and
1780  *      it complains on the snprintf() prototype.
1781  *
1782  * Revision 1.66  2002/01/29 04:00:54  mcr
1783  *      more excise of kversions.h header.
1784  *
1785  * Revision 1.65  2002/01/29 02:13:18  mcr
1786  *      introduction of ipsec_kversion.h means that include of
1787  *      ipsec_param.h must preceed any decisions about what files to
1788  *      include to deal with differences in kernel source.
1789  *
1790  * Revision 1.64  2001/11/26 09:23:51  rgb
1791  * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
1792  *
1793  * Revision 1.61.2.1  2001/09/25 02:28:44  mcr
1794  *      cleaned up includes.
1795  *
1796  * Revision 1.63  2001/11/12 19:38:00  rgb
1797  * Continue trying other sockets even if one fails and return only original
1798  * error.
1799  *
1800  * Revision 1.62  2001/10/18 04:45:22  rgb
1801  * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
1802  * lib/freeswan.h version macros moved to lib/kversions.h.
1803  * Other compiler directive cleanups.
1804  *
1805  * Revision 1.61  2001/09/20 15:32:59  rgb
1806  * Min/max cleanup.
1807  *
1808  * Revision 1.60  2001/06/14 19:35:12  rgb
1809  * Update copyright date.
1810  *
1811  * Revision 1.59  2001/06/13 15:35:48  rgb
1812  * Fixed #endif comments.
1813  *
1814  * Revision 1.58  2001/05/04 16:37:24  rgb
1815  * Remove erroneous checking of return codes for proc_net_* in 2.4.
1816  *
1817  * Revision 1.57  2001/05/03 19:43:36  rgb
1818  * Initialise error return variable.
1819  * Check error return codes in startup and shutdown.
1820  * Standardise on SENDERR() macro.
1821  *
1822  * Revision 1.56  2001/04/21 23:05:07  rgb
1823  * Define out skb->used for 2.4 kernels.
1824  *
1825  * Revision 1.55  2001/02/28 05:03:28  rgb
1826  * Clean up and rationalise startup messages.
1827  *
1828  * Revision 1.54  2001/02/27 22:24:55  rgb
1829  * Re-formatting debug output (line-splitting, joining, 1arg/line).
1830  * Check for satoa() return codes.
1831  *
1832  * Revision 1.53  2001/02/27 06:48:18  rgb
1833  * Fixed pfkey socket unregister log message to reflect type and function.
1834  *
1835  * Revision 1.52  2001/02/26 22:34:38  rgb
1836  * Fix error return code that was getting overwritten by the error return
1837  * code of an upmsg.
1838  *
1839  * Revision 1.51  2001/01/30 23:42:47  rgb
1840  * Allow pfkey msgs from pid other than user context required for ACQUIRE
1841  * and subsequent ADD or UDATE.
1842  *
1843  * Revision 1.50  2001/01/23 20:22:59  rgb
1844  * 2.4 fix to remove removed is_clone member.
1845  *
1846  * Revision 1.49  2000/11/06 04:33:47  rgb
1847  * Changed non-exported functions to DEBUG_NO_STATIC.
1848  *
1849  * Revision 1.48  2000/09/29 19:47:41  rgb
1850  * Update copyright.
1851  *
1852  * Revision 1.47  2000/09/22 04:23:04  rgb
1853  * Added more debugging to pfkey_upmsg() call from pfkey_sendmsg() error.
1854  *
1855  * Revision 1.46  2000/09/21 04:20:44  rgb
1856  * Fixed array size off-by-one error.  (Thanks Svenning!)
1857  *
1858  * Revision 1.45  2000/09/20 04:01:26  rgb
1859  * Changed static functions to DEBUG_NO_STATIC for revealing function names
1860  * in oopsen.
1861  *
1862  * Revision 1.44  2000/09/19 00:33:17  rgb
1863  * 2.0 fixes.
1864  *
1865  * Revision 1.43  2000/09/16 01:28:13  rgb
1866  * Fixed use of 0 in p format warning.
1867  *
1868  * Revision 1.42  2000/09/16 01:09:41  rgb
1869  * Fixed debug format warning for pointers that was expecting ints.
1870  *
1871  * Revision 1.41  2000/09/13 15:54:00  rgb
1872  * Rewrote pfkey_get_info(), added pfkey_{supported,registered}_get_info().
1873  * Moved supported algos add and remove to functions.
1874  *
1875  * Revision 1.40  2000/09/12 18:49:28  rgb
1876  * Added IPIP tunnel and IPCOMP register support.
1877  *
1878  * Revision 1.39  2000/09/12 03:23:49  rgb
1879  * Converted #if0 debugs to sysctl.
1880  * Removed debug_pfkey initialisations that prevented no_debug loading or
1881  * linking.
1882  *
1883  * Revision 1.38  2000/09/09 06:38:02  rgb
1884  * Return positive errno in pfkey_reply error message.
1885  *
1886  * Revision 1.37  2000/09/08 19:19:09  rgb
1887  * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
1888  * Clean-up of long-unused crud...
1889  * Create pfkey error message on on failure.
1890  * Give pfkey_list_{insert,remove}_{socket,supported}() some error
1891  * checking.
1892  *
1893  * Revision 1.36  2000/09/01 18:49:38  rgb
1894  * Reap experimental NET_21_ bits.
1895  * Turned registered sockets list into an array of one list per satype.
1896  * Remove references to deprecated sklist_{insert,remove}_socket.
1897  * Removed leaking socket debugging code.
1898  * Removed duplicate pfkey_insert_socket in pfkey_create.
1899  * Removed all references to pfkey msg->msg_name, since it is not used for
1900  * pfkey.
1901  * Added a supported algorithms array lists, one per satype and registered
1902  * existing algorithms.
1903  * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
1904  * list.
1905  * Only send pfkey_expire() messages to sockets registered for that satype.
1906  *
1907  * Revision 1.35  2000/08/24 17:03:00  rgb
1908  * Corrected message size error return code for PF_KEYv2.
1909  * Removed downward error prohibition.
1910  *
1911  * Revision 1.34  2000/08/21 16:32:26  rgb
1912  * Re-formatted for cosmetic consistency and readability.
1913  *
1914  * Revision 1.33  2000/08/20 21:38:24  rgb
1915  * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
1916  * Extended the upward message initiation of pfkey_sendmsg(). (Momchil)
1917  *
1918  * Revision 1.32  2000/07/28 14:58:31  rgb
1919  * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
1920  *
1921  * Revision 1.31  2000/05/16 03:04:00  rgb
1922  * Updates for 2.3.99pre8 from MB.
1923  *
1924  * Revision 1.30  2000/05/10 19:22:21  rgb
1925  * Use sklist private functions for 2.3.xx compatibility.
1926  *
1927  * Revision 1.29  2000/03/22 16:17:03  rgb
1928  * Fixed SOCKOPS_WRAPPED macro for SMP (MB).
1929  *
1930  * Revision 1.28  2000/02/21 19:30:45  rgb
1931  * Removed references to pkt_bridged for 2.3.47 compatibility.
1932  *
1933  * Revision 1.27  2000/02/14 21:07:00  rgb
1934  * Fixed /proc/net/pf-key legend spacing.
1935  *
1936  * Revision 1.26  2000/01/22 03:46:59  rgb
1937  * Fixed pfkey error return mechanism so that we are able to free the
1938  * local copy of the pfkey_msg, plugging a memory leak and silencing
1939  * the bad object free complaints.
1940  *
1941  * Revision 1.25  2000/01/21 06:19:44  rgb
1942  * Moved pfkey_list_remove_socket() calls to before MOD_USE_DEC_COUNT.
1943  * Added debugging to pfkey_upmsg.
1944  *
1945  * Revision 1.24  2000/01/10 16:38:23  rgb
1946  * MB fixups for 2.3.x.
1947  *
1948  * Revision 1.23  1999/12/09 23:22:16  rgb
1949  * Added more instrumentation for debugging 2.0 socket
1950  * selection/reading.
1951  * Removed erroneous 2.0 wait==NULL check bug in select.
1952  *
1953  * Revision 1.22  1999/12/08 20:32:16  rgb
1954  * Tidied up 2.0.xx support, after major pfkey work, eliminating
1955  * msg->msg_name twiddling in the process, since it is not defined
1956  * for PF_KEYv2.
1957  *
1958  * Revision 1.21  1999/12/01 22:17:19  rgb
1959  * Set skb->dev to zero on new skb in case it is a reused skb.
1960  * Added check for skb_put overflow and freeing to avoid upmsg on error.
1961  * Added check for wrong pfkey version and freeing to avoid upmsg on
1962  * error.
1963  * Shut off content dumping in pfkey_destroy.
1964  * Added debugging message for size of buffer allocated for upmsg.
1965  *
1966  * Revision 1.20  1999/11/27 12:11:00  rgb
1967  * Minor clean-up, enabling quiet operation of pfkey if desired.
1968  *
1969  * Revision 1.19  1999/11/25 19:04:21  rgb
1970  * Update proc_fs code for pfkey to use dynamic registration.
1971  *
1972  * Revision 1.18  1999/11/25 09:07:17  rgb
1973  * Implemented SENDERR macro for propagating error codes.
1974  * Fixed error return code bug.
1975  *
1976  * Revision 1.17  1999/11/23 23:07:20  rgb
1977  * Change name of pfkey_msg_parser to pfkey_msg_interp since it no longer
1978  * parses. (PJO)
1979  * Sort out pfkey and freeswan headers, putting them in a library path.
1980  *
1981  * Revision 1.16  1999/11/20 22:00:22  rgb
1982  * Moved socketlist type declarations and prototypes for shared use.
1983  * Renamed reformatted and generically extended for use by other socket
1984  * lists pfkey_{del,add}_open_socket to pfkey_list_{remove,insert}_socket.
1985  *
1986  * Revision 1.15  1999/11/18 04:15:09  rgb
1987  * Make pfkey_data_ready temporarily available for 2.2.x testing.
1988  * Clean up pfkey_destroy_socket() debugging statements.
1989  * Add Peter Onion's code to send messages up to all listening sockets.
1990  * Changed all occurrences of #include "../../../lib/freeswan.h"
1991  * to #include <freeswan.h> which works due to -Ilibfreeswan in the
1992  * klips/net/ipsec/Makefile.
1993  * Replaced all kernel version macros to shorter, readable form.
1994  * Added CONFIG_PROC_FS compiler directives in case it is shut off.
1995  *
1996  * Revision 1.14  1999/11/17 16:01:00  rgb
1997  * Make pfkey_data_ready temporarily available for 2.2.x testing.
1998  * Clean up pfkey_destroy_socket() debugging statements.
1999  * Add Peter Onion's code to send messages up to all listening sockets.
2000  * Changed #include "../../../lib/freeswan.h" to #include <freeswan.h>
2001  * which works due to -Ilibfreeswan in the klips/net/ipsec/Makefile.
2002  *
2003  * Revision 1.13  1999/10/27 19:59:51  rgb
2004  * Removed af_unix comments that are no longer relevant.
2005  * Added debug prink statements.
2006  * Added to the /proc output in pfkey_get_info.
2007  * Made most functions non-static to enable oops tracing.
2008  * Re-enable skb dequeueing and freeing.
2009  * Fix skb_alloc() and skb_put() size bug in pfkey_upmsg().
2010  *
2011  * Revision 1.12  1999/10/26 17:05:42  rgb
2012  * Complete re-ordering based on proto_ops structure order.
2013  * Separated out proto_ops structures for 2.0.x and 2.2.x for clarity.
2014  * Simplification to use built-in socket ops where possible for 2.2.x.
2015  * Add shorter macros for compiler directives to visually clean-up.
2016  * Add lots of sk skb dequeueing debugging statements.
2017  * Added to the /proc output in pfkey_get_info.
2018  *
2019  * Revision 1.11  1999/09/30 02:55:10  rgb
2020  * Bogus skb detection.
2021  * Fix incorrect /proc/net/ipsec-eroute printk message.
2022  *
2023  * Revision 1.10  1999/09/21 15:22:13  rgb
2024  * Temporary fix while I figure out the right way to destroy sockets.
2025  *
2026  * Revision 1.9  1999/07/08 19:19:44  rgb
2027  * Fix pointer format warning.
2028  * Fix missing member error under 2.0.xx kernels.
2029  *
2030  * Revision 1.8  1999/06/13 07:24:04  rgb
2031  * Add more debugging.
2032  *
2033  * Revision 1.7  1999/06/10 05:24:17  rgb
2034  * Clarified compiler directives.
2035  * Renamed variables to reduce confusion.
2036  * Used sklist_*_socket() kernel functions to simplify 2.2.x socket support.
2037  * Added lots of sanity checking.
2038  *
2039  * Revision 1.6  1999/06/03 18:59:50  rgb
2040  * More updates to 2.2.x socket support.  Almost works, oops at end of call.
2041  *
2042  * Revision 1.5  1999/05/25 22:44:05  rgb
2043  * Start fixing 2.2 sockets.
2044  *
2045  * Revision 1.4  1999/04/29 15:21:34  rgb
2046  * Move log to the end of the file.
2047  * Eliminate min/max redefinition in #include <net/tcp.h>.
2048  * Correct path for pfkey #includes
2049  * Standardise an error return method.
2050  * Add debugging instrumentation.
2051  * Move message type checking to pfkey_msg_parse().
2052  * Add check for errno incorrectly set.
2053  * Add check for valid PID.
2054  * Add check for reserved illegally set.
2055  * Add check for message out of bounds.
2056  *
2057  * Revision 1.3  1999/04/15 17:58:07  rgb
2058  * Add RCSID labels.
2059  *
2060  * Revision 1.2  1999/04/15 15:37:26  rgb
2061  * Forward check changes from POST1_00 branch.
2062  *
2063  * Revision 1.1.2.2  1999/04/13 20:37:12  rgb
2064  * Header Title correction.
2065  *
2066  * Revision 1.1.2.1  1999/03/26 20:58:55  rgb
2067  * Add pfkeyv2 support to KLIPS.
2068  *
2069  *
2070  * RFC 2367
2071  * PF_KEY_v2 Key Management API
2072  */