2 * @(#) /proc file system interface code.
4 * Copyright (C) 1996, 1997 John Ioannidis.
5 * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
6 * 2001 Michael Richardson <mcr@freeswan.org>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 * Split out from ipsec_init.c version 1.70.
21 char ipsec_proc_c_version[] = "RCSID $Id: ipsec_proc.c,v 1.8 2002/01/29 17:17:55 mcr Exp $";
23 #include <linux/config.h>
24 #include <linux/version.h>
25 #define __NO_VERSION__
26 #include <linux/module.h>
27 #include <linux/kernel.h> /* printk() */
29 #include "ipsec_param.h"
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 */
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/in.h> /* struct sockaddr_in */
44 #include <linux/skbuff.h>
48 #include <linux/spinlock.h> /* *lock* */
49 #else /* SPINLOCK_23 */
50 #include <asm/spinlock.h> /* *lock* */
51 #endif /* SPINLOCK_23 */
54 #include <asm/uaccess.h>
55 #include <linux/in6.h>
57 #include <asm/checksum.h>
60 #include <linux/proc_fs.h>
61 #endif /* CONFIG_PROC_FS */
63 #include <linux/netlink.h>
65 #include <net/netlink.h>
70 #include "ipsec_life.h"
71 #include "ipsec_stats.h"
74 #include "ipsec_encap.h"
75 #include "ipsec_radij.h"
76 #include "ipsec_netlink.h"
77 #include "ipsec_xform.h"
78 #include "ipsec_tunnel.h"
80 #include "ipsec_rcv.h"
82 #include "ipsec_esp.h"
84 #ifdef CONFIG_IPSEC_IPCOMP
86 #endif /* CONFIG_IPSEC_IPCOMP */
88 #include "ipsec_proto.h"
96 static struct proc_dir_entry *proc_net_ipsec_dir;
99 IPSEC_PROCFS_DEBUG_NO_STATIC
101 ipsec_eroute_get_info(char *buffer,
104 int length IPSEC_PROC_LAST_ARG)
106 struct wsbuf w = {buffer, length, offset, 0, 0, 0, 0};
108 #ifdef CONFIG_IPSEC_DEBUG
109 if (debug_radij & DB_RJ_DUMPTREES)
110 rj_dumptrees(); /* XXXXXXXXX */
111 #endif /* CONFIG_IPSEC_DEBUG */
113 KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
114 "klips_debug:ipsec_eroute_get_info: "
115 "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n",
121 spin_lock_bh(&eroute_lock);
123 rj_walktree(rnh, ipsec_rj_walker_procprint, &w);
124 /* rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */
126 spin_unlock_bh(&eroute_lock);
128 *start = buffer + (offset - w.begin); /* Start of wanted data */
129 w.len -= (offset - w.begin); /* Start slop */
135 IPSEC_PROCFS_DEBUG_NO_STATIC
137 ipsec_spi_get_info(char *buffer,
140 int length IPSEC_PROC_LAST_ARG)
143 off_t pos = 0, begin = 0;
145 struct ipsec_sa *sa_p;
147 char buf_s[SUBNETTOA_BUF];
148 char buf_d[SUBNETTOA_BUF];
149 char buf_l[LIFETIMETOA_BUF];
152 KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
153 "klips_debug:ipsec_spi_get_info: "
154 "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n",
160 spin_lock_bh(&tdb_lock);
164 for (i = 0; i < SADB_HASHMOD; i++) {
165 for (sa_p = ipsec_sadb_hash[i];
167 sa_p = sa_p->ips_hnext) {
168 sa_len = satoa(sa_p->ips_said, 0, sa, SATOA_BUF);
169 len += sprintf(buffer + len, "%s ",
170 sa_len ? sa : " (error)");
172 len += sprintf(buffer + len, "%s%s%s",
173 IPS_XFORM_NAME(sa_p));
175 len += sprintf(buffer + len, ": dir=%s",
176 (sa_p->ips_flags & EMT_INBOUND) ?
179 if(sa_p->ips_addr_s) {
180 addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr,
181 0, buf_s, sizeof(buf_s));
182 len += sprintf(buffer + len, " src=%s",
186 if((sa_p->ips_said.proto == IPPROTO_IPIP)
187 && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) {
188 subnettoa(sa_p->ips_flow_s.u.v4.sin_addr,
189 sa_p->ips_mask_s.u.v4.sin_addr,
194 subnettoa(sa_p->ips_flow_d.u.v4.sin_addr,
195 sa_p->ips_mask_d.u.v4.sin_addr,
200 len += sprintf(buffer + len, " policy=%s->%s",
204 if(sa_p->ips_iv_bits) {
206 len += sprintf(buffer + len, " iv_bits=%dbits iv=0x",
209 for(j = 0; j < sa_p->ips_iv_bits / 8; j++) {
210 len += sprintf(buffer + len, "%02x",
211 (__u32)((__u8*)(sa_p->ips_iv))[j]);
215 if(sa_p->ips_encalg || sa_p->ips_authalg) {
216 if(sa_p->ips_replaywin) {
217 len += sprintf(buffer + len, " ooowin=%d",
218 sa_p->ips_replaywin);
220 if(sa_p->ips_errs.ips_replaywin_errs) {
221 len += sprintf(buffer + len, " ooo_errs=%d",
222 sa_p->ips_errs.ips_replaywin_errs);
224 if(sa_p->ips_replaywin_lastseq) {
225 len += sprintf(buffer + len, " seq=%d",
226 sa_p->ips_replaywin_lastseq);
228 if(sa_p->ips_replaywin_bitmap) {
229 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
230 len += sprintf(buffer + len, " bit=0x%Lx",
231 sa_p->ips_replaywin_bitmap);
233 len += sprintf(buffer + len, " bit=0x%x%08x",
234 (__u32)(sa_p->ips_replaywin_bitmap >> 32),
235 (__u32)sa_p->ips_replaywin_bitmap);
238 if(sa_p->ips_replaywin_maxdiff) {
239 len += sprintf(buffer + len, " max_seq_diff=%d",
240 sa_p->ips_replaywin_maxdiff);
243 if(sa_p->ips_flags & ~EMT_INBOUND) {
244 len += sprintf(buffer + len, " flags=0x%x",
245 sa_p->ips_flags & ~EMT_INBOUND);
246 len += sprintf(buffer + len, "<");
247 /* flag printing goes here */
248 len += sprintf(buffer + len, ">");
250 if(sa_p->ips_auth_bits) {
251 len += sprintf(buffer + len, " alen=%d",
252 sa_p->ips_auth_bits);
254 if(sa_p->ips_key_bits_a) {
255 len += sprintf(buffer + len, " aklen=%d",
256 sa_p->ips_key_bits_a);
258 if(sa_p->ips_errs.ips_auth_errs) {
259 len += sprintf(buffer + len, " auth_errs=%d",
260 sa_p->ips_errs.ips_auth_errs);
262 if(sa_p->ips_key_bits_e) {
263 len += sprintf(buffer + len, " eklen=%d",
264 sa_p->ips_key_bits_e);
266 if(sa_p->ips_errs.ips_encsize_errs) {
267 len += sprintf(buffer + len, " encr_size_errs=%d",
268 sa_p->ips_errs.ips_encsize_errs);
270 if(sa_p->ips_errs.ips_encpad_errs) {
271 len += sprintf(buffer + len, " encr_pad_errs=%d",
272 sa_p->ips_errs.ips_encpad_errs);
275 len += sprintf(buffer + len, " life(c,s,h)=");
277 if (ipsec_lifetime_format(buf_l,
280 ipsec_life_countbased,
281 &sa_p->ips_life.ipl_allocations)) {
282 len += snprintf(buffer + len, sizeof(buf_l), "%s", buf_l);
285 if (ipsec_lifetime_format(buf_l,
288 ipsec_life_countbased,
289 &sa_p->ips_life.ipl_bytes)) {
290 len += snprintf(buffer + len, sizeof(buf_l), "%s", buf_l);
293 if (ipsec_lifetime_format(buf_l,
296 ipsec_life_timebased,
297 &sa_p->ips_life.ipl_addtime)) {
298 len += snprintf(buffer + len, sizeof(buf_l), "%s", buf_l);
301 if (ipsec_lifetime_format(buf_l,
304 ipsec_life_timebased,
305 &sa_p->ips_life.ipl_usetime)) {
306 len += snprintf(buffer + len, sizeof(buf_l), "%s", buf_l);
309 if (ipsec_lifetime_format(buf_l,
312 ipsec_life_countbased,
313 &sa_p->ips_life.ipl_packets)) {
314 len += snprintf(buffer + len, sizeof(buf_l), "%s", buf_l);
317 if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */
318 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
319 len += sprintf(buffer + len, " idle=%Ld",
320 jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last);
322 len += sprintf(buffer + len, " idle=%lu",
323 jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last);
327 #ifdef CONFIG_IPSEC_IPCOMP
328 if(sa_p->ips_said.proto == IPPROTO_COMP &&
329 (sa_p->ips_comp_ratio_dbytes ||
330 sa_p->ips_comp_ratio_cbytes)) {
331 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
332 len += sprintf(buffer + len, " ratio=%Ld:%Ld",
333 sa_p->ips_comp_ratio_dbytes,
334 sa_p->ips_comp_ratio_cbytes);
336 len += sprintf(buffer + len, " ratio=%lu:%lu",
337 (unsigned long)sa_p->ips_comp_ratio_dbytes,
338 (unsigned long)sa_p->ips_comp_ratio_cbytes);
341 #endif /* CONFIG_IPSEC_IPCOMP */
343 len += sprintf(buffer + len, "\n");
350 if (pos > offset + length) {
357 spin_unlock_bh(&tdb_lock);
359 *start = buffer + (offset - begin); /* Start of wanted data */
360 len -= (offset - begin); /* Start slop */
366 IPSEC_PROCFS_DEBUG_NO_STATIC
368 ipsec_spigrp_get_info(char *buffer,
371 int length IPSEC_PROC_LAST_ARG)
374 off_t pos = 0, begin = 0;
376 struct ipsec_sa *sa_p, *sa_p2;
380 KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
381 "klips_debug:ipsec_spigrp_get_info: "
382 "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n",
388 spin_lock_bh(&tdb_lock);
390 for (i = 0; i < SADB_HASHMOD; i++) {
391 for (sa_p = ipsec_sadb_hash[i];
393 sa_p = sa_p->ips_hnext)
399 sa_len = satoa(sa_p2->ips_said,
402 len += sprintf(buffer + len, "%s ",
403 sa_len ? sa : " (error)");
404 sa_p2 = sa_p2->ips_onext;
406 len += sprintf(buffer + len, "\n");
412 if (pos > offset + length) {
420 spin_unlock_bh(&tdb_lock);
422 *start = buffer + (offset - begin); /* Start of wanted data */
423 len -= (offset - begin); /* Start slop */
429 IPSEC_PROCFS_DEBUG_NO_STATIC
431 ipsec_tncfg_get_info(char *buffer,
434 int length IPSEC_PROC_LAST_ARG)
437 off_t pos = 0, begin = 0;
440 struct device *dev, *privdev;
441 struct ipsecpriv *priv;
443 KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
444 "klips_debug:ipsec_tncfg_get_info: "
445 "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n",
451 for(i = 0; i < IPSEC_NUM_IF; i++) {
452 sprintf(name, "ipsec%d", i);
453 dev = ipsec_dev_get(name);
455 priv = (struct ipsecpriv *)(dev->priv);
456 len += sprintf(buffer + len, "%s",
459 privdev = (struct device *)(priv->dev);
460 len += sprintf(buffer + len, " -> %s",
461 privdev ? privdev->name : "NULL");
462 len += sprintf(buffer + len, " mtu=%d(%d) -> %d",
465 privdev ? privdev->mtu : 0);
467 KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
468 "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n",
471 len += sprintf(buffer + len, "\n");
478 else if (pos > offset + length) {
483 *start = buffer + (offset - begin); /* Start of wanted data */
484 len -= (offset - begin); /* Start slop */
490 IPSEC_PROCFS_DEBUG_NO_STATIC
492 ipsec_version_get_info(char *buffer,
495 int length IPSEC_PROC_LAST_ARG)
500 KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
501 "klips_debug:ipsec_version_get_info: "
502 "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n",
508 len += sprintf(buffer + len, "FreeS/WAN version: %s\n",
509 ipsec_version_code());
511 KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
512 "klips_debug:ipsec_version_get_info: "
513 "ipsec_init version: %s\n",
514 ipsec_init_c_version);
515 KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
516 "klips_debug:ipsec_version_get_info: "
517 "ipsec_tunnel version: %s\n",
518 ipsec_tunnel_c_version);
519 KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
520 "klips_debug:ipsec_version_get_info: "
521 "ipsec_netlink version: %s\n",
522 ipsec_netlink_c_version);
523 KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
524 "klips_debug:ipsec_version_get_info: "
525 "radij_c_version: %s\n",
529 *start = buffer + (offset - begin); /* Start of wanted data */
530 len -= (offset - begin); /* Start slop */
536 #ifdef CONFIG_IPSEC_DEBUG
537 IPSEC_PROCFS_DEBUG_NO_STATIC
539 ipsec_klipsdebug_get_info(char *buffer,
542 int length IPSEC_PROC_LAST_ARG)
547 KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
548 "klips_debug:ipsec_klipsdebug_get_info: "
549 "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n",
555 len += sprintf(buffer + len, "debug_tunnel=%08x.\n", debug_tunnel);
556 len += sprintf(buffer + len, "debug_netlink=%08x.\n", debug_netlink);
557 len += sprintf(buffer + len, "debug_xform=%08x.\n", debug_xform);
558 len += sprintf(buffer + len, "debug_eroute=%08x.\n", debug_eroute);
559 len += sprintf(buffer + len, "debug_spi=%08x.\n", debug_spi);
560 len += sprintf(buffer + len, "debug_radij=%08x.\n", debug_radij);
561 len += sprintf(buffer + len, "debug_esp=%08x.\n", debug_esp);
562 len += sprintf(buffer + len, "debug_ah=%08x.\n", debug_ah);
563 len += sprintf(buffer + len, "debug_rcv=%08x.\n", debug_rcv);
564 len += sprintf(buffer + len, "debug_pfkey=%08x.\n", debug_pfkey);
566 *start = buffer + (offset - begin); /* Start of wanted data */
567 len -= (offset - begin); /* Start slop */
572 #endif /* CONFIG_IPSEC_DEBUG */
575 struct proc_dir_entry ipsec_eroute =
579 S_IFREG | S_IRUGO, 1, 0, 0, 0,
580 &proc_net_inode_operations,
581 ipsec_eroute_get_info,
582 NULL, NULL, NULL, NULL, NULL
585 struct proc_dir_entry ipsec_spi =
589 S_IFREG | S_IRUGO, 1, 0, 0, 0,
590 &proc_net_inode_operations,
592 NULL, NULL, NULL, NULL, NULL
595 struct proc_dir_entry ipsec_spigrp =
599 S_IFREG | S_IRUGO, 1, 0, 0, 0,
600 &proc_net_inode_operations,
601 ipsec_spigrp_get_info,
602 NULL, NULL, NULL, NULL, NULL
605 struct proc_dir_entry ipsec_tncfg =
609 S_IFREG | S_IRUGO, 1, 0, 0, 0,
610 &proc_net_inode_operations,
611 ipsec_tncfg_get_info,
612 NULL, NULL, NULL, NULL, NULL
615 struct proc_dir_entry ipsec_version =
619 S_IFREG | S_IRUGO, 1, 0, 0, 0,
620 &proc_net_inode_operations,
621 ipsec_version_get_info,
622 NULL, NULL, NULL, NULL, NULL
625 #ifdef CONFIG_IPSEC_DEBUG
626 struct proc_dir_entry ipsec_klipsdebug =
629 16, "ipsec_klipsdebug",
630 S_IFREG | S_IRUGO, 1, 0, 0, 0,
631 &proc_net_inode_operations,
632 ipsec_klipsdebug_get_info,
633 NULL, NULL, NULL, NULL, NULL
635 #endif /* CONFIG_IPSEC_DEBUG */
636 #endif /* !PROC_FS_2325 */
637 #endif /* CONFIG_PROC_FS */
644 /* compile a dummy function if no /proc/-fs */
646 /* XXX-mcr probably should just complain because pluto won't
650 #ifdef CONFIG_PROC_FS
651 # ifndef PROC_FS_2325
653 error |= proc_register(proc_net, &ipsec_eroute);
654 error |= proc_register(proc_net, &ipsec_spi);
655 error |= proc_register(proc_net, &ipsec_spigrp);
656 error |= proc_register(proc_net, &ipsec_tncfg);
657 error |= proc_register(proc_net, &ipsec_version);
658 # ifdef CONFIG_IPSEC_DEBUG
659 error |= proc_register(proc_net, &ipsec_klipsdebug);
660 # endif /* CONFIG_IPSEC_DEBUG */
661 # else /* PROC_FS_21 */
662 error |= proc_register_dynamic(&proc_net, &ipsec_eroute);
663 error |= proc_register_dynamic(&proc_net, &ipsec_spi);
664 error |= proc_register_dynamic(&proc_net, &ipsec_spigrp);
665 error |= proc_register_dynamic(&proc_net, &ipsec_tncfg);
666 error |= proc_register_dynamic(&proc_net, &ipsec_version);
667 # ifdef CONFIG_IPSEC_DEBUG
668 error |= proc_register_dynamic(&proc_net, &ipsec_klipsdebug);
669 # endif /* CONFIG_IPSEC_DEBUG */
670 # endif /* PROC_FS_21 */
671 # else /* !PROC_FS_2325 */
672 /* create /proc/net/ipsec */
674 proc_net_ipsec_dir = proc_mkdir("ipsec", proc_net);
675 if(proc_net_ipsec_dir == NULL) {
678 error |= proc_register();
682 proc_net_create ("ipsec_eroute", 0, ipsec_eroute_get_info);
683 proc_net_create ("ipsec_spi", 0, ipsec_spi_get_info);
684 proc_net_create ("ipsec_spigrp", 0, ipsec_spigrp_get_info);
685 proc_net_create ("ipsec_tncfg", 0, ipsec_tncfg_get_info);
686 proc_net_create ("ipsec_version", 0, ipsec_version_get_info);
687 # ifdef CONFIG_IPSEC_DEBUG
688 proc_net_create ("ipsec_klipsdebug", 0, ipsec_klipsdebug_get_info);
689 # endif /* CONFIG_IPSEC_DEBUG */
690 # endif /* !PROC_FS_2325 */
691 #endif /* CONFIG_PROC_FS */
699 #ifdef CONFIG_PROC_FS
700 # ifndef PROC_FS_2325
701 # ifdef CONFIG_IPSEC_DEBUG
702 if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0)
703 printk("klips_debug:ipsec_cleanup: "
704 "cannot unregister /proc/net/ipsec_klipsdebug\n");
705 # endif /* CONFIG_IPSEC_DEBUG */
706 if (proc_net_unregister(ipsec_version.low_ino) != 0)
707 printk("klips_debug:ipsec_cleanup: "
708 "cannot unregister /proc/net/ipsec_version\n");
709 if (proc_net_unregister(ipsec_eroute.low_ino) != 0)
710 printk("klips_debug:ipsec_cleanup: "
711 "cannot unregister /proc/net/ipsec_eroute\n");
712 if (proc_net_unregister(ipsec_spi.low_ino) != 0)
713 printk("klips_debug:ipsec_cleanup: "
714 "cannot unregister /proc/net/ipsec_spi\n");
715 if (proc_net_unregister(ipsec_spigrp.low_ino) != 0)
716 printk("klips_debug:ipsec_cleanup: "
717 "cannot unregister /proc/net/ipsec_spigrp\n");
718 if (proc_net_unregister(ipsec_tncfg.low_ino) != 0)
719 printk("klips_debug:ipsec_cleanup: "
720 "cannot unregister /proc/net/ipsec_tncfg\n");
721 # else /* !PROC_FS_2325 */
722 # ifdef CONFIG_IPSEC_DEBUG
723 proc_net_remove ("ipsec_klipsdebug");
724 # endif /* CONFIG_IPSEC_DEBUG */
725 proc_net_remove ("ipsec_eroute");
726 proc_net_remove ("ipsec_spi");
727 proc_net_remove ("ipsec_spigrp");
728 proc_net_remove ("ipsec_tncfg");
729 proc_net_remove ("ipsec_version");
730 # endif /* !PROC_FS_2325 */
731 #endif /* CONFIG_PROC_FS */
735 * $Log: ipsec_proc.c,v $
736 * Revision 1.8 2002/01/29 17:17:55 mcr
737 * moved include of ipsec_param.h to after include of linux/kernel.h
738 * otherwise, it seems that some option that is set in ipsec_param.h
739 * screws up something subtle in the include path to kernel.h, and
740 * it complains on the snprintf() prototype.
742 * Revision 1.7 2002/01/29 04:00:52 mcr
743 * more excise of kversions.h header.
745 * Revision 1.6 2002/01/29 02:13:17 mcr
746 * introduction of ipsec_kversion.h means that include of
747 * ipsec_param.h must preceed any decisions about what files to
748 * include to deal with differences in kernel source.
750 * Revision 1.5 2002/01/12 02:54:30 mcr
751 * beginnings of /proc/net/ipsec dir.
753 * Revision 1.4 2001/12/11 02:21:05 rgb
754 * Don't include module version here, fixing 2.2 compile bug.
756 * Revision 1.3 2001/12/05 07:19:44 rgb
757 * Fixed extraneous #include "version.c" bug causing modular KLIPS failure.
759 * Revision 1.2 2001/11/26 09:16:14 rgb
760 * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
762 * Revision 1.74 2001/11/22 05:44:11 henry
765 * Revision 1.1.2.1 2001/09/25 02:19:40 mcr
766 * /proc manipulation code moved to new ipsec_proc.c
770 * c-file-style: "linux"