📄 ipsec_proc.c
字号:
/* * @(#) /proc file system interface code. * * Copyright (C) 1996, 1997 John Ioannidis. * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org> * 2001 Michael Richardson <mcr@freeswan.org> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * Split out from ipsec_init.c version 1.70. */char ipsec_proc_c_version[] = "RCSID $Id: ipsec_proc.c,v 1.34 2004/12/03 21:25:57 mcr Exp $";#include <linux/config.h>#include <linux/version.h>#define __NO_VERSION__#include <linux/module.h>#include <linux/kernel.h> /* printk() */#include "openswan/ipsec_kversion.h"#include "openswan/ipsec_param.h"#ifdef MALLOC_SLAB# include <linux/slab.h> /* kmalloc() */#else /* MALLOC_SLAB */# include <linux/malloc.h> /* kmalloc() */#endif /* MALLOC_SLAB */#include <linux/errno.h> /* error codes */#include <linux/types.h> /* size_t */#include <linux/interrupt.h> /* mark_bh */#include <linux/netdevice.h> /* struct device, and other headers */#include <linux/etherdevice.h> /* eth_type_trans */#include <linux/ip.h> /* struct iphdr */#include <linux/in.h> /* struct sockaddr_in */#include <linux/skbuff.h>#include <openswan.h>#ifdef SPINLOCK#ifdef SPINLOCK_23#include <linux/spinlock.h> /* *lock* */#else /* SPINLOCK_23 */#include <asm/spinlock.h> /* *lock* */#endif /* SPINLOCK_23 */#endif /* SPINLOCK */#ifdef NET_21#include <asm/uaccess.h>#include <linux/in6.h>#endif /* NET_21 */#include <asm/checksum.h>#include <net/ip.h>#ifdef CONFIG_PROC_FS#include <linux/proc_fs.h>#endif /* CONFIG_PROC_FS */#ifdef NETLINK_SOCK#include <linux/netlink.h>#else#include <net/netlink.h>#endif#include "openswan/radij.h"#include "openswan/ipsec_life.h"#include "openswan/ipsec_stats.h"#include "openswan/ipsec_sa.h"#include "openswan/ipsec_encap.h"#include "openswan/ipsec_radij.h"#include "openswan/ipsec_xform.h"#include "openswan/ipsec_tunnel.h"#include "openswan/ipsec_xmit.h"#include "openswan/ipsec_rcv.h"#include "openswan/ipsec_ah.h"#include "openswan/ipsec_esp.h"#include "openswan/ipsec_kern24.h"#ifdef CONFIG_KLIPS_IPCOMP#include "openswan/ipcomp.h"#endif /* CONFIG_KLIPS_IPCOMP */#include "openswan/ipsec_proto.h"#include <pfkeyv2.h>#include <pfkey.h>#ifdef CONFIG_PROC_FS#ifdef IPSEC_PROC_SUBDIRSstatic struct proc_dir_entry *proc_net_ipsec_dir = NULL;static struct proc_dir_entry *proc_eroute_dir = NULL;static struct proc_dir_entry *proc_spi_dir = NULL;static struct proc_dir_entry *proc_spigrp_dir = NULL;static struct proc_dir_entry *proc_birth_dir = NULL;static struct proc_dir_entry *proc_stats_dir = NULL;#endifstruct ipsec_birth_reply ipsec_ipv4_birth_packet;struct ipsec_birth_reply ipsec_ipv6_birth_packet;#ifdef CONFIG_KLIPS_DEBUGint debug_esp = 0;int debug_ah = 0;#endif /* CONFIG_KLIPS_DEBUG */#define DECREMENT_UNSIGNED(X, amount) ((amount < (X)) ? (X)-amount : 0)extern int ipsec_xform_get_info(char *buffer, char **start, off_t offset, int length IPSEC_PROC_LAST_ARG);/* ipsec_snprintf: like snprintf except * - size is signed and a negative value is treated as if it were 0 * - the returned result is never negative -- * an error generates a "?" or null output (depending on space). * (Our callers are too lazy to check for an error return.) * * @param buf String buffer * @param size Size of the string * @param fmt printf string * @param ... Variables to be displayed in fmt * @return int Return code */int ipsec_snprintf(char *buf, ssize_t size, const char *fmt, ...){ va_list args; int i; size_t possize = size < 0? 0 : size; va_start(args, fmt); i = vsnprintf(buf,possize,fmt,args); va_end(args); if (i < 0) { /* create empty output in place of error */ i = 0; if (size > 0) { *buf = '\0'; } } return i;}IPSEC_PROCFS_DEBUG_NO_STATICintipsec_eroute_get_info(char *buffer, char **start, off_t offset, int length IPSEC_PROC_LAST_ARG){ struct wsbuf w = {buffer, length, offset, 0, 0};#ifdef CONFIG_KLIPS_DEBUG if (debug_radij & DB_RJ_DUMPTREES) rj_dumptrees(); /* XXXXXXXXX */#endif /* CONFIG_KLIPS_DEBUG */ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, "klips_debug:ipsec_eroute_get_info: " "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", buffer, *start, (int)offset, length); spin_lock_bh(&eroute_lock); rj_walktree(rnh, ipsec_rj_walker_procprint, &w);/* rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */ spin_unlock_bh(&eroute_lock); *start = buffer + (offset - w.begin); /* Start of wanted data */ return w.len - (offset - w.begin);}IPSEC_PROCFS_DEBUG_NO_STATICintipsec_spi_get_info(char *buffer, char **start, off_t offset, int length IPSEC_PROC_LAST_ARG){ const int max_content = length > 0? length-1 : 0; int len = 0; off_t begin = 0; int i; struct ipsec_sa *sa_p; char sa[SATOT_BUF]; char buf_s[SUBNETTOA_BUF]; char buf_d[SUBNETTOA_BUF]; size_t sa_len; KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, "klips_debug:ipsec_spi_get_info: " "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n", buffer, *start, (int)offset, length); spin_lock_bh(&tdb_lock); for (i = 0; i < SADB_HASHMOD; i++) { for (sa_p = ipsec_sadb_hash[i]; sa_p; sa_p = sa_p->ips_hnext) { atomic_inc(&sa_p->ips_refcount); sa_len = satot(&sa_p->ips_said, 'x', sa, sizeof(sa)); len += ipsec_snprintf(buffer+len, length-len, "%s ", sa_len ? sa : " (error)"); len += ipsec_snprintf(buffer+len, length-len, "%s%s%s", IPS_XFORM_NAME(sa_p)); len += ipsec_snprintf(buffer+len, length-len, ": dir=%s", (sa_p->ips_flags & EMT_INBOUND) ? "in " : "out"); if(sa_p->ips_addr_s) { addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr, 0, buf_s, sizeof(buf_s)); len += ipsec_snprintf(buffer+len, length-len, " src=%s", buf_s); } if((sa_p->ips_said.proto == IPPROTO_IPIP) && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) { subnettoa(sa_p->ips_flow_s.u.v4.sin_addr, sa_p->ips_mask_s.u.v4.sin_addr, 0, buf_s, sizeof(buf_s)); subnettoa(sa_p->ips_flow_d.u.v4.sin_addr, sa_p->ips_mask_d.u.v4.sin_addr, 0, buf_d, sizeof(buf_d)); len += ipsec_snprintf(buffer+len, length-len, " policy=%s->%s", buf_s, buf_d); } if(sa_p->ips_iv_bits) { int j; len += ipsec_snprintf(buffer+len, length-len, " iv_bits=%dbits iv=0x", sa_p->ips_iv_bits); for(j = 0; j < sa_p->ips_iv_bits / 8; j++) { len += ipsec_snprintf(buffer+len, length-len, "%02x", (__u32)((__u8*)(sa_p->ips_iv))[j]); } } if(sa_p->ips_encalg || sa_p->ips_authalg) { if(sa_p->ips_replaywin) { len += ipsec_snprintf(buffer+len, length-len, " ooowin=%d", sa_p->ips_replaywin); } if(sa_p->ips_errs.ips_replaywin_errs) { len += ipsec_snprintf(buffer+len, length-len, " ooo_errs=%d", sa_p->ips_errs.ips_replaywin_errs); } if(sa_p->ips_replaywin_lastseq) { len += ipsec_snprintf(buffer+len, length-len, " seq=%d", sa_p->ips_replaywin_lastseq); } if(sa_p->ips_replaywin_bitmap) {#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) len += ipsec_snprintf(buffer+len, length-len, " bit=0x%Lx", sa_p->ips_replaywin_bitmap);#else len += ipsec_snprintf(buffer+len, length-len, " bit=0x%x%08x", (__u32)(sa_p->ips_replaywin_bitmap >> 32), (__u32)sa_p->ips_replaywin_bitmap);#endif } if(sa_p->ips_replaywin_maxdiff) { len += ipsec_snprintf(buffer+len, length-len, " max_seq_diff=%d", sa_p->ips_replaywin_maxdiff); } } if(sa_p->ips_flags & ~EMT_INBOUND) { len += ipsec_snprintf(buffer+len, length-len, " flags=0x%x", sa_p->ips_flags & ~EMT_INBOUND); len += ipsec_snprintf(buffer+len, length-len, "<"); /* flag printing goes here */ len += ipsec_snprintf(buffer+len, length-len, ">"); } if(sa_p->ips_auth_bits) { len += ipsec_snprintf(buffer+len, length-len, " alen=%d", sa_p->ips_auth_bits); } if(sa_p->ips_key_bits_a) { len += ipsec_snprintf(buffer+len, length-len, " aklen=%d", sa_p->ips_key_bits_a); } if(sa_p->ips_errs.ips_auth_errs) { len += ipsec_snprintf(buffer+len, length-len, " auth_errs=%d", sa_p->ips_errs.ips_auth_errs); } if(sa_p->ips_key_bits_e) { len += ipsec_snprintf(buffer+len, length-len, " eklen=%d", sa_p->ips_key_bits_e); } if(sa_p->ips_errs.ips_encsize_errs) { len += ipsec_snprintf(buffer+len, length-len, " encr_size_errs=%d", sa_p->ips_errs.ips_encsize_errs); } if(sa_p->ips_errs.ips_encpad_errs) { len += ipsec_snprintf(buffer+len, length-len, " encr_pad_errs=%d", sa_p->ips_errs.ips_encpad_errs); } len += ipsec_snprintf(buffer+len, length-len, " life(c,s,h)="); len += ipsec_lifetime_format(buffer + len, length - len, "alloc", ipsec_life_countbased, &sa_p->ips_life.ipl_allocations); len += ipsec_lifetime_format(buffer + len, length - len, "bytes", ipsec_life_countbased, &sa_p->ips_life.ipl_bytes); len += ipsec_lifetime_format(buffer + len, length - len, "addtime", ipsec_life_timebased, &sa_p->ips_life.ipl_addtime); len += ipsec_lifetime_format(buffer + len, length - len, "usetime", ipsec_life_timebased, &sa_p->ips_life.ipl_usetime); len += ipsec_lifetime_format(buffer + len, length - len, "packets", ipsec_life_countbased, &sa_p->ips_life.ipl_packets); if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) len += ipsec_snprintf(buffer+len, length-len, " idle=%Ld", jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last);#else len += ipsec_snprintf(buffer+len, length-len, " idle=%lu", jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last);#endif }#ifdef CONFIG_KLIPS_IPCOMP if(sa_p->ips_said.proto == IPPROTO_COMP && (sa_p->ips_comp_ratio_dbytes || sa_p->ips_comp_ratio_cbytes)) {#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) len += ipsec_snprintf(buffer+len, length-len, " ratio=%Ld:%Ld", sa_p->ips_comp_ratio_dbytes, sa_p->ips_comp_ratio_cbytes);#else len += ipsec_snprintf(buffer+len, length-len, " ratio=%lu:%lu", (unsigned long)sa_p->ips_comp_ratio_dbytes, (unsigned long)sa_p->ips_comp_ratio_cbytes);#endif }#endif /* CONFIG_KLIPS_IPCOMP */#ifdef CONFIG_KLIPS_NAT_TRAVERSAL if(sa_p->ips_natt_type != 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -