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 2004/04/28 08:06:22 as 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 "freeswan/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>
68 #include "freeswan/radij.h"
70 #include "freeswan/ipsec_life.h"
71 #include "freeswan/ipsec_stats.h"
72 #include "freeswan/ipsec_sa.h"
74 #include "freeswan/ipsec_encap.h"
75 #include "freeswan/ipsec_radij.h"
76 #include "freeswan/ipsec_xform.h"
77 #include "freeswan/ipsec_tunnel.h"
78 #include "freeswan/ipsec_xmit.h"
80 #include "freeswan/ipsec_rcv.h"
81 #include "freeswan/ipsec_ah.h"
82 #include "freeswan/ipsec_esp.h"
84 #ifdef CONFIG_IPSEC_IPCOMP
85 #include "freeswan/ipcomp.h"
86 #endif /* CONFIG_IPSEC_IPCOMP */
88 #include "freeswan/ipsec_proto.h"
95 #ifdef IPSEC_PROC_SUBDIRS
96 static struct proc_dir_entry
*proc_net_ipsec_dir
= NULL
;
97 static struct proc_dir_entry
*proc_eroute_dir
= NULL
;
98 static struct proc_dir_entry
*proc_spi_dir
= NULL
;
99 static struct proc_dir_entry
*proc_spigrp_dir
= NULL
;
100 static struct proc_dir_entry
*proc_birth_dir
= NULL
;
101 static struct proc_dir_entry
*proc_stats_dir
= NULL
;
104 struct ipsec_birth_reply ipsec_ipv4_birth_packet
;
105 struct ipsec_birth_reply ipsec_ipv6_birth_packet
;
107 extern int ipsec_xform_get_info(char *buffer
, char **start
,
108 off_t offset
, int length IPSEC_PROC_LAST_ARG
);
111 /* ipsec_snprintf: like snprintf except
112 * - size is signed and a negative value is treated as if it were 0
113 * - the returned result is never negative --
114 * an error generates a "?" or null output (depending on space).
115 * (Our callers are too lazy to check for an error return.)
117 * @param buf String buffer
118 * @param size Size of the string
119 * @param fmt printf string
120 * @param ... Variables to be displayed in fmt
121 * @return int Return code
123 int ipsec_snprintf(char *buf
, ssize_t size
, const char *fmt
, ...)
127 size_t possize
= size
< 0? 0 : size
;
129 i
= vsnprintf(buf
,possize
,fmt
,args
);
132 /* create empty output in place of error */
142 IPSEC_PROCFS_DEBUG_NO_STATIC
144 ipsec_eroute_get_info(char *buffer
,
147 int length IPSEC_PROC_LAST_ARG
)
149 struct wsbuf w
= {buffer
, length
, offset
, 0, 0};
151 #ifdef CONFIG_IPSEC_DEBUG
152 if (debug_radij
& DB_RJ_DUMPTREES
)
153 rj_dumptrees(); /* XXXXXXXXX */
154 #endif /* CONFIG_IPSEC_DEBUG */
156 KLIPS_PRINT(debug_tunnel
& DB_TN_PROCFS
,
157 "klips_debug:ipsec_eroute_get_info: "
158 "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
164 spin_lock_bh(&eroute_lock
);
166 rj_walktree(rnh
, ipsec_rj_walker_procprint
, &w
);
167 /* rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */
169 spin_unlock_bh(&eroute_lock
);
171 *start
= buffer
+ (offset
- w
.begin
); /* Start of wanted data */
172 return w
.len
- (offset
- w
.begin
);
175 IPSEC_PROCFS_DEBUG_NO_STATIC
177 ipsec_spi_get_info(char *buffer
,
180 int length IPSEC_PROC_LAST_ARG
)
182 /* Limit of useful snprintf output */
183 const int max_content
= length
> 0? length
-1 : 0;
188 struct ipsec_sa
*sa_p
;
190 char buf_s
[SUBNETTOA_BUF
];
191 char buf_d
[SUBNETTOA_BUF
];
194 KLIPS_PRINT(debug_tunnel
& DB_TN_PROCFS
,
195 "klips_debug:ipsec_spi_get_info: "
196 "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
202 spin_lock_bh(&tdb_lock
);
206 for (i
= 0; i
< SADB_HASHMOD
; i
++) {
207 for (sa_p
= ipsec_sadb_hash
[i
];
209 sa_p
= sa_p
->ips_hnext
) {
210 atomic_inc(&sa_p
->ips_refcount
);
211 sa_len
= satoa(sa_p
->ips_said
, 0, sa
, SATOA_BUF
);
212 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "%s ",
213 sa_len
? sa
: " (error)");
215 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "%s%s%s",
216 IPS_XFORM_NAME(sa_p
));
218 len
+= ipsec_snprintf(buffer
+len
, length
-len
, ": dir=%s",
219 (sa_p
->ips_flags
& EMT_INBOUND
) ?
222 if(sa_p
->ips_addr_s
) {
223 addrtoa(((struct sockaddr_in
*)(sa_p
->ips_addr_s
))->sin_addr
,
224 0, buf_s
, sizeof(buf_s
));
225 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " src=%s",
229 if((sa_p
->ips_said
.proto
== IPPROTO_IPIP
)
230 && (sa_p
->ips_flags
& SADB_X_SAFLAGS_INFLOW
)) {
231 subnettoa(sa_p
->ips_flow_s
.u
.v4
.sin_addr
,
232 sa_p
->ips_mask_s
.u
.v4
.sin_addr
,
237 subnettoa(sa_p
->ips_flow_d
.u
.v4
.sin_addr
,
238 sa_p
->ips_mask_d
.u
.v4
.sin_addr
,
243 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " policy=%s->%s",
247 if(sa_p
->ips_iv_bits
) {
249 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " iv_bits=%dbits iv=0x",
252 for(j
= 0; j
< sa_p
->ips_iv_bits
/ 8; j
++) {
253 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "%02x",
254 (__u32
)((__u8
*)(sa_p
->ips_iv
))[j
]);
258 if(sa_p
->ips_encalg
|| sa_p
->ips_authalg
) {
259 if(sa_p
->ips_replaywin
) {
260 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " ooowin=%d",
261 sa_p
->ips_replaywin
);
263 if(sa_p
->ips_errs
.ips_replaywin_errs
) {
264 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " ooo_errs=%d",
265 sa_p
->ips_errs
.ips_replaywin_errs
);
267 if(sa_p
->ips_replaywin_lastseq
) {
268 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " seq=%d",
269 sa_p
->ips_replaywin_lastseq
);
271 if(sa_p
->ips_replaywin_bitmap
) {
272 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
273 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " bit=0x%Lx",
274 sa_p
->ips_replaywin_bitmap
);
276 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " bit=0x%x%08x",
277 (__u32
)(sa_p
->ips_replaywin_bitmap
>> 32),
278 (__u32
)sa_p
->ips_replaywin_bitmap
);
281 if(sa_p
->ips_replaywin_maxdiff
) {
282 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " max_seq_diff=%d",
283 sa_p
->ips_replaywin_maxdiff
);
286 if(sa_p
->ips_flags
& ~EMT_INBOUND
) {
287 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " flags=0x%x",
288 sa_p
->ips_flags
& ~EMT_INBOUND
);
289 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "<");
290 /* flag printing goes here */
291 len
+= ipsec_snprintf(buffer
+len
, length
-len
, ">");
293 if(sa_p
->ips_auth_bits
) {
294 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " alen=%d",
295 sa_p
->ips_auth_bits
);
297 if(sa_p
->ips_key_bits_a
) {
298 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " aklen=%d",
299 sa_p
->ips_key_bits_a
);
301 if(sa_p
->ips_errs
.ips_auth_errs
) {
302 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " auth_errs=%d",
303 sa_p
->ips_errs
.ips_auth_errs
);
305 if(sa_p
->ips_key_bits_e
) {
306 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " eklen=%d",
307 sa_p
->ips_key_bits_e
);
309 if(sa_p
->ips_errs
.ips_encsize_errs
) {
310 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " encr_size_errs=%d",
311 sa_p
->ips_errs
.ips_encsize_errs
);
313 if(sa_p
->ips_errs
.ips_encpad_errs
) {
314 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " encr_pad_errs=%d",
315 sa_p
->ips_errs
.ips_encpad_errs
);
318 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " life(c,s,h)=");
320 len
+= ipsec_lifetime_format(buffer
+ len
,
323 ipsec_life_countbased
,
324 &sa_p
->ips_life
.ipl_allocations
);
326 len
+= ipsec_lifetime_format(buffer
+ len
,
329 ipsec_life_countbased
,
330 &sa_p
->ips_life
.ipl_bytes
);
332 len
+= ipsec_lifetime_format(buffer
+ len
,
335 ipsec_life_timebased
,
336 &sa_p
->ips_life
.ipl_addtime
);
338 len
+= ipsec_lifetime_format(buffer
+ len
,
341 ipsec_life_timebased
,
342 &sa_p
->ips_life
.ipl_usetime
);
344 len
+= ipsec_lifetime_format(buffer
+ len
,
347 ipsec_life_countbased
,
348 &sa_p
->ips_life
.ipl_packets
);
350 if(sa_p
->ips_life
.ipl_usetime
.ipl_last
) { /* XXX-MCR should be last? */
351 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
352 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " idle=%Ld",
353 jiffies
/ HZ
- sa_p
->ips_life
.ipl_usetime
.ipl_last
);
355 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " idle=%lu",
356 jiffies
/ HZ
- (unsigned long)sa_p
->ips_life
.ipl_usetime
.ipl_last
);
360 #ifdef CONFIG_IPSEC_IPCOMP
361 if(sa_p
->ips_said
.proto
== IPPROTO_COMP
&&
362 (sa_p
->ips_comp_ratio_dbytes
||
363 sa_p
->ips_comp_ratio_cbytes
)) {
364 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
365 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " ratio=%Ld:%Ld",
366 sa_p
->ips_comp_ratio_dbytes
,
367 sa_p
->ips_comp_ratio_cbytes
);
369 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " ratio=%lu:%lu",
370 (unsigned long)sa_p
->ips_comp_ratio_dbytes
,
371 (unsigned long)sa_p
->ips_comp_ratio_cbytes
);
374 #endif /* CONFIG_IPSEC_IPCOMP */
376 #ifdef CONFIG_IPSEC_NAT_TRAVERSAL
377 if(sa_p
->ips_natt_type
!= 0) {
380 switch(sa_p
->ips_natt_type
)
382 case ESPINUDP_WITH_NON_IKE
:
383 natttype_name
="nonike";
385 case ESPINUDP_WITH_NON_ESP
:
386 natttype_name
="nonesp";
389 natttype_name
="unknown";
393 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " natencap=%s",
396 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " natsport=%d",
397 sa_p
->ips_natt_sport
);
399 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " natdport=%d",
400 sa_p
->ips_natt_dport
);
402 #endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
404 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " refcount=%d",
405 atomic_read(&sa_p
->ips_refcount
));
407 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " ref=%d",
409 #ifdef CONFIG_IPSEC_DEBUG
411 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " reftable=%lu refentry=%lu",
412 (unsigned long)IPsecSAref2table(sa_p
->ips_ref
),
413 (unsigned long)IPsecSAref2entry(sa_p
->ips_ref
));
415 #endif /* CONFIG_IPSEC_DEBUG */
417 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "\n");
419 atomic_dec(&sa_p
->ips_refcount
);
421 if (len
>= max_content
) {
422 /* we've done all that can fit -- stop loops */
423 len
= max_content
; /* truncate crap */
426 const off_t pos
= begin
+ len
;
429 /* all is before first interesting character:
430 * discard, but note where we are.
440 spin_unlock_bh(&tdb_lock
);
442 *start
= buffer
+ (offset
- begin
); /* Start of wanted data */
443 return len
- (offset
- begin
);
446 IPSEC_PROCFS_DEBUG_NO_STATIC
448 ipsec_spigrp_get_info(char *buffer
,
451 int length IPSEC_PROC_LAST_ARG
)
453 /* limit of useful snprintf output */
454 const int max_content
= length
> 0? length
-1 : 0;
459 struct ipsec_sa
*sa_p
, *sa_p2
;
463 KLIPS_PRINT(debug_tunnel
& DB_TN_PROCFS
,
464 "klips_debug:ipsec_spigrp_get_info: "
465 "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
471 spin_lock_bh(&tdb_lock
);
473 for (i
= 0; i
< SADB_HASHMOD
; i
++) {
474 for (sa_p
= ipsec_sadb_hash
[i
];
476 sa_p
= sa_p
->ips_hnext
)
478 atomic_inc(&sa_p
->ips_refcount
);
479 if(sa_p
->ips_inext
== NULL
) {
481 while(sa_p2
!= NULL
) {
482 atomic_inc(&sa_p2
->ips_refcount
);
483 sa_len
= satoa(sa_p2
->ips_said
,
486 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "%s ",
487 sa_len
? sa
: " (error)");
488 atomic_dec(&sa_p2
->ips_refcount
);
489 sa_p2
= sa_p2
->ips_onext
;
491 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "\n");
494 atomic_dec(&sa_p
->ips_refcount
);
496 if (len
>= max_content
) {
497 /* we've done all that can fit -- stop loops */
498 len
= max_content
; /* truncate crap */
501 const off_t pos
= begin
+ len
;
504 /* all is before first interesting character:
505 * discard, but note where we are.
515 spin_unlock_bh(&tdb_lock
);
517 *start
= buffer
+ (offset
- begin
); /* Start of wanted data */
518 return len
- (offset
- begin
);
521 IPSEC_PROCFS_DEBUG_NO_STATIC
523 ipsec_tncfg_get_info(char *buffer
,
526 int length IPSEC_PROC_LAST_ARG
)
528 /* limit of useful snprintf output */
529 const int max_content
= length
> 0? length
-1 : 0;
535 struct device
*dev
, *privdev
;
536 struct ipsecpriv
*priv
;
538 KLIPS_PRINT(debug_tunnel
& DB_TN_PROCFS
,
539 "klips_debug:ipsec_tncfg_get_info: "
540 "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
546 for(i
= 0; i
< IPSEC_NUM_IF
; i
++) {
547 ipsec_snprintf(name
, (ssize_t
) sizeof(name
), IPSEC_DEV_FORMAT
, i
);
548 dev
= __ipsec_dev_get(name
);
550 priv
= (struct ipsecpriv
*)(dev
->priv
);
551 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "%s",
554 privdev
= (struct device
*)(priv
->dev
);
555 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " -> %s",
556 privdev
? privdev
->name
: "NULL");
557 len
+= ipsec_snprintf(buffer
+len
, length
-len
, " mtu=%d(%d) -> %d",
560 privdev
? privdev
->mtu
: 0);
562 KLIPS_PRINT(debug_tunnel
& DB_TN_PROCFS
,
563 "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n",
566 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "\n");
568 if (len
>= max_content
) {
569 /* we've done all that can fit -- stop loop */
570 len
= max_content
; /* truncate crap */
573 const off_t pos
= begin
+ len
;
581 *start
= buffer
+ (offset
- begin
); /* Start of wanted data */
582 len
-= (offset
- begin
); /* Start slop */
588 IPSEC_PROCFS_DEBUG_NO_STATIC
590 ipsec_version_get_info(char *buffer
,
593 int length IPSEC_PROC_LAST_ARG
)
598 KLIPS_PRINT(debug_tunnel
& DB_TN_PROCFS
,
599 "klips_debug:ipsec_version_get_info: "
600 "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
606 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "strongSwan version: %s\n",
607 ipsec_version_code());
609 KLIPS_PRINT(debug_tunnel
& DB_TN_PROCFS
,
610 "klips_debug:ipsec_version_get_info: "
611 "ipsec_init version: %s\n",
612 ipsec_init_c_version
);
613 KLIPS_PRINT(debug_tunnel
& DB_TN_PROCFS
,
614 "klips_debug:ipsec_version_get_info: "
615 "ipsec_tunnel version: %s\n",
616 ipsec_tunnel_c_version
);
617 KLIPS_PRINT(debug_tunnel
& DB_TN_PROCFS
,
618 "klips_debug:ipsec_version_get_info: "
619 "ipsec_netlink version: %s\n",
620 ipsec_netlink_c_version
);
621 KLIPS_PRINT(debug_tunnel
& DB_TN_PROCFS
,
622 "klips_debug:ipsec_version_get_info: "
623 "radij_c_version: %s\n",
627 *start
= buffer
+ (offset
- begin
); /* Start of wanted data */
628 len
-= (offset
- begin
); /* Start slop */
634 IPSEC_PROCFS_DEBUG_NO_STATIC
636 ipsec_birth_info(char *page
,
643 struct ipsec_birth_reply
*ibr
= (struct ipsec_birth_reply
*)data
;
646 if(offset
>= ibr
->packet_template_len
) {
653 len
= ibr
->packet_template_len
;
658 memcpy(page
+ offset
, ibr
->packet_template
+offset
, len
);
663 IPSEC_PROCFS_DEBUG_NO_STATIC
665 ipsec_birth_set(struct file
*file
, const char *buffer
,
666 unsigned long count
, void *data
)
668 struct ipsec_birth_reply
*ibr
= (struct ipsec_birth_reply
*)data
;
672 if(count
> IPSEC_BIRTH_TEMPLATE_MAXLEN
) {
673 len
= IPSEC_BIRTH_TEMPLATE_MAXLEN
;
678 if(copy_from_user(ibr
->packet_template
, buffer
, len
)) {
682 ibr
->packet_template_len
= len
;
690 #ifdef CONFIG_IPSEC_DEBUG
691 IPSEC_PROCFS_DEBUG_NO_STATIC
693 ipsec_klipsdebug_get_info(char *buffer
,
696 int length IPSEC_PROC_LAST_ARG
)
701 KLIPS_PRINT(debug_tunnel
& DB_TN_PROCFS
,
702 "klips_debug:ipsec_klipsdebug_get_info: "
703 "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
709 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "debug_tunnel=%08x.\n", debug_tunnel
);
710 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "debug_xform=%08x.\n", debug_xform
);
711 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "debug_eroute=%08x.\n", debug_eroute
);
712 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "debug_spi=%08x.\n", debug_spi
);
713 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "debug_radij=%08x.\n", debug_radij
);
714 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "debug_esp=%08x.\n", debug_esp
);
715 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "debug_ah=%08x.\n", debug_ah
);
716 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "debug_rcv=%08x.\n", debug_rcv
);
717 len
+= ipsec_snprintf(buffer
+len
, length
-len
, "debug_pfkey=%08x.\n", debug_pfkey
);
719 *start
= buffer
+ (offset
- begin
); /* Start of wanted data */
720 len
-= (offset
- begin
); /* Start slop */
725 #endif /* CONFIG_IPSEC_DEBUG */
727 IPSEC_PROCFS_DEBUG_NO_STATIC
729 ipsec_stats_get_int_info(char *buffer
,
736 /* Limit of useful snprintf output */
737 const int max_content
= length
> 0? length
-1 : 0;
744 len
= ipsec_snprintf(buffer
+len
, length
-len
, "%08x\n", *thing
);
746 if (len
>= max_content
)
747 len
= max_content
; /* truncate crap */
749 *start
= buffer
+ offset
; /* Start of wanted data */
750 return len
> offset
? len
- offset
: 0;
754 struct proc_dir_entry ipsec_eroute
=
758 S_IFREG
| S_IRUGO
, 1, 0, 0, 0,
759 &proc_net_inode_operations
,
760 ipsec_eroute_get_info
,
761 NULL
, NULL
, NULL
, NULL
, NULL
764 struct proc_dir_entry ipsec_spi
=
768 S_IFREG
| S_IRUGO
, 1, 0, 0, 0,
769 &proc_net_inode_operations
,
771 NULL
, NULL
, NULL
, NULL
, NULL
774 struct proc_dir_entry ipsec_spigrp
=
778 S_IFREG
| S_IRUGO
, 1, 0, 0, 0,
779 &proc_net_inode_operations
,
780 ipsec_spigrp_get_info
,
781 NULL
, NULL
, NULL
, NULL
, NULL
784 struct proc_dir_entry ipsec_tncfg
=
788 S_IFREG
| S_IRUGO
, 1, 0, 0, 0,
789 &proc_net_inode_operations
,
790 ipsec_tncfg_get_info
,
791 NULL
, NULL
, NULL
, NULL
, NULL
794 struct proc_dir_entry ipsec_version
=
798 S_IFREG
| S_IRUGO
, 1, 0, 0, 0,
799 &proc_net_inode_operations
,
800 ipsec_version_get_info
,
801 NULL
, NULL
, NULL
, NULL
, NULL
804 #ifdef CONFIG_IPSEC_DEBUG
805 struct proc_dir_entry ipsec_klipsdebug
=
808 16, "ipsec_klipsdebug",
809 S_IFREG
| S_IRUGO
, 1, 0, 0, 0,
810 &proc_net_inode_operations
,
811 ipsec_klipsdebug_get_info
,
812 NULL
, NULL
, NULL
, NULL
, NULL
814 #endif /* CONFIG_IPSEC_DEBUG */
815 #endif /* !PROC_FS_2325 */
816 #endif /* CONFIG_PROC_FS */
818 #if defined(PROC_FS_2325)
819 struct ipsec_proc_list
{
821 struct proc_dir_entry
**parent
;
822 struct proc_dir_entry
**dir
;
823 read_proc_t
*readthing
;
824 write_proc_t
*writething
;
827 static struct ipsec_proc_list proc_items
[]={
828 #ifdef CONFIG_IPSEC_DEBUG
829 {"klipsdebug", &proc_net_ipsec_dir
, NULL
, ipsec_klipsdebug_get_info
, NULL
, NULL
},
831 {"eroute", &proc_net_ipsec_dir
, &proc_eroute_dir
, NULL
, NULL
, NULL
},
832 {"all", &proc_eroute_dir
, NULL
, ipsec_eroute_get_info
, NULL
, NULL
},
833 {"spi", &proc_net_ipsec_dir
, &proc_spi_dir
, NULL
, NULL
, NULL
},
834 {"all", &proc_spi_dir
, NULL
, ipsec_spi_get_info
, NULL
, NULL
},
835 {"spigrp", &proc_net_ipsec_dir
, &proc_spigrp_dir
, NULL
, NULL
, NULL
},
836 {"all", &proc_spigrp_dir
, NULL
, ipsec_spigrp_get_info
, NULL
, NULL
},
837 {"birth", &proc_net_ipsec_dir
, &proc_birth_dir
, NULL
, NULL
, NULL
},
838 {"ipv4", &proc_birth_dir
, NULL
, ipsec_birth_info
, ipsec_birth_set
, (void *)&ipsec_ipv4_birth_packet
},
839 {"ipv6", &proc_birth_dir
, NULL
, ipsec_birth_info
, ipsec_birth_set
, (void *)&ipsec_ipv6_birth_packet
},
840 {"xforms", &proc_net_ipsec_dir
, NULL
, ipsec_xform_get_info
, NULL
, NULL
},
841 {"tncfg", &proc_net_ipsec_dir
, NULL
, ipsec_tncfg_get_info
, NULL
, NULL
},
842 {"stats", &proc_net_ipsec_dir
, &proc_stats_dir
, NULL
, NULL
, NULL
},
843 {"trap_count", &proc_stats_dir
, NULL
, ipsec_stats_get_int_info
, NULL
, &ipsec_xmit_trap_count
},
844 {"trap_sendcount", &proc_stats_dir
, NULL
, ipsec_stats_get_int_info
, NULL
, &ipsec_xmit_trap_sendcount
},
845 {"version", &proc_net_ipsec_dir
, NULL
, ipsec_version_get_info
, NULL
, NULL
},
846 {NULL
, NULL
, NULL
, NULL
, NULL
, NULL
}
854 #ifdef IPSEC_PROC_SUBDIRS
855 struct proc_dir_entry
*item
;
859 * just complain because pluto won't run without /proc!
861 #ifndef CONFIG_PROC_FS
862 #error You must have PROC_FS built in to use KLIPS
865 /* for 2.0 kernels */
866 #if !defined(PROC_FS_2325) && !defined(PROC_FS_21)
867 error
|= proc_register_dynamic(&proc_net
, &ipsec_eroute
);
868 error
|= proc_register_dynamic(&proc_net
, &ipsec_spi
);
869 error
|= proc_register_dynamic(&proc_net
, &ipsec_spigrp
);
870 error
|= proc_register_dynamic(&proc_net
, &ipsec_tncfg
);
871 error
|= proc_register_dynamic(&proc_net
, &ipsec_version
);
872 #ifdef CONFIG_IPSEC_DEBUG
873 error
|= proc_register_dynamic(&proc_net
, &ipsec_klipsdebug
);
874 #endif /* CONFIG_IPSEC_DEBUG */
877 /* for 2.2 kernels */
878 #if !defined(PROC_FS_2325) && defined(PROC_FS_21)
879 error
|= proc_register(proc_net
, &ipsec_eroute
);
880 error
|= proc_register(proc_net
, &ipsec_spi
);
881 error
|= proc_register(proc_net
, &ipsec_spigrp
);
882 error
|= proc_register(proc_net
, &ipsec_tncfg
);
883 error
|= proc_register(proc_net
, &ipsec_version
);
884 #ifdef CONFIG_IPSEC_DEBUG
885 error
|= proc_register(proc_net
, &ipsec_klipsdebug
);
886 #endif /* CONFIG_IPSEC_DEBUG */
889 /* for 2.4 kernels */
890 #if defined(PROC_FS_2325)
891 /* create /proc/net/ipsec */
893 /* zero these out before we initialize /proc/net/ipsec/birth/stuff */
894 memset(&ipsec_ipv4_birth_packet
, 0, sizeof(struct ipsec_birth_reply
));
895 memset(&ipsec_ipv6_birth_packet
, 0, sizeof(struct ipsec_birth_reply
));
897 proc_net_ipsec_dir
= proc_mkdir("ipsec", proc_net
);
898 if(proc_net_ipsec_dir
== NULL
) {
899 /* no point in continuing */
904 struct ipsec_proc_list
*it
;
907 while(it
->name
!=NULL
) {
909 /* make a dir instead */
910 item
= proc_mkdir(it
->name
, *it
->parent
);
913 item
= create_proc_entry(it
->name
, 0400, *it
->parent
);
916 item
->read_proc
= it
->readthing
;
917 item
->write_proc
= it
->writething
;
918 item
->data
= it
->data
;
920 item
->owner
= THIS_MODULE
;
929 /* now create some symlinks to provide compatibility */
930 proc_symlink("ipsec_eroute", proc_net
, "ipsec/eroute/all");
931 proc_symlink("ipsec_spi", proc_net
, "ipsec/spi/all");
932 proc_symlink("ipsec_spigrp", proc_net
, "ipsec/spigrp/all");
933 proc_symlink("ipsec_tncfg", proc_net
, "ipsec/tncfg");
934 proc_symlink("ipsec_version",proc_net
, "ipsec/version");
935 proc_symlink("ipsec_klipsdebug",proc_net
,"ipsec/klipsdebug");
937 #endif /* !PROC_FS_2325 */
946 /* for 2.0 and 2.2 kernels */
947 #if !defined(PROC_FS_2325)
949 #ifdef CONFIG_IPSEC_DEBUG
950 if (proc_net_unregister(ipsec_klipsdebug
.low_ino
) != 0)
951 printk("klips_debug:ipsec_cleanup: "
952 "cannot unregister /proc/net/ipsec_klipsdebug\n");
953 #endif /* CONFIG_IPSEC_DEBUG */
955 if (proc_net_unregister(ipsec_version
.low_ino
) != 0)
956 printk("klips_debug:ipsec_cleanup: "
957 "cannot unregister /proc/net/ipsec_version\n");
958 if (proc_net_unregister(ipsec_eroute
.low_ino
) != 0)
959 printk("klips_debug:ipsec_cleanup: "
960 "cannot unregister /proc/net/ipsec_eroute\n");
961 if (proc_net_unregister(ipsec_spi
.low_ino
) != 0)
962 printk("klips_debug:ipsec_cleanup: "
963 "cannot unregister /proc/net/ipsec_spi\n");
964 if (proc_net_unregister(ipsec_spigrp
.low_ino
) != 0)
965 printk("klips_debug:ipsec_cleanup: "
966 "cannot unregister /proc/net/ipsec_spigrp\n");
967 if (proc_net_unregister(ipsec_tncfg
.low_ino
) != 0)
968 printk("klips_debug:ipsec_cleanup: "
969 "cannot unregister /proc/net/ipsec_tncfg\n");
972 /* for 2.4 kernels */
973 #if defined(PROC_FS_2325)
975 struct ipsec_proc_list
*it
;
977 /* find end of list */
979 while(it
->name
!=NULL
) {
985 remove_proc_entry(it
->name
, *it
->parent
);
987 } while(it
> proc_items
);
991 #ifdef CONFIG_IPSEC_DEBUG
992 remove_proc_entry("ipsec_klipsdebug", proc_net
);
993 #endif /* CONFIG_IPSEC_DEBUG */
994 remove_proc_entry("ipsec_eroute", proc_net
);
995 remove_proc_entry("ipsec_spi", proc_net
);
996 remove_proc_entry("ipsec_spigrp", proc_net
);
997 remove_proc_entry("ipsec_tncfg", proc_net
);
998 remove_proc_entry("ipsec_version", proc_net
);
999 remove_proc_entry("ipsec", proc_net
);
1000 #endif /* 2.4 kernel */