📄 ipsec_radij.c
字号:
/* * Interface between the IPSEC code and the radix (radij) tree code * Copyright (C) 1996, 1997 John Ioannidis. * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. * * 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. * * RCSID $Id: ipsec_radij.c,v 1.48 2001/06/15 04:12:56 rgb Exp $ */#include <linux/config.h>#include <linux/version.h>#include <linux/kernel.h> /* printk() */#include <linux/malloc.h> /* kmalloc() */#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/skbuff.h>#include <freeswan.h>#ifdef SPINLOCK#ifdef SPINLOCK_23#include <linux/spinlock.h> /* *lock* */#else /* 23_SPINLOCK */#include <asm/spinlock.h> /* *lock* */#endif /* 23_SPINLOCK */#endif /* SPINLOCK */#ifdef NET_21#include <asm/uaccess.h>#include <linux/in6.h>#endif#include <asm/checksum.h>#include <net/ip.h>#include "radij.h"#include "ipsec_encap.h"#include "ipsec_radij.h"#include "ipsec_netlink.h"#include "ipsec_xform.h"#ifdef CONFIG_IPSEC_DEBUGint debug_radij = 0;#endif /* CONFIG_IPSEC_DEBUG */struct radij_node_head *rnh = NULL;#ifdef SPINLOCKspinlock_t eroute_lock = SPIN_LOCK_UNLOCKED;#else /* SPINLOCK */spinlock_t eroute_lock;#endif /* SPINLOCK */intipsec_radijinit(void){ maj_keylen = sizeof (struct sockaddr_encap); rj_init(); if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */ return -1; return 0;}intipsec_radijcleanup(void){ int error; spin_lock_bh(&eroute_lock); error = radijcleanup(); spin_unlock_bh(&eroute_lock); return error;}intipsec_cleareroutes(void){ int error = 0; spin_lock_bh(&eroute_lock); error = radijcleartree(); spin_unlock_bh(&eroute_lock); return error;}intipsec_breakroute(struct sockaddr_encap *eaddr, struct sockaddr_encap *emask){ struct radij_node *rn; int error = 0;#ifdef CONFIG_IPSEC_DEBUG char buf1[64], buf2[64]; if (debug_eroute) { subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1)); subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2)); KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_breakroute: " "attempting to delete eroute for %s->%s\n", buf1, buf2); }#endif /* CONFIG_IPSEC_DEBUG */ spin_lock_bh(&eroute_lock); if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) { spin_unlock_bh(&eroute_lock); KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_breakroute: " "node not found, eroute delete failed.\n"); return error; } spin_unlock_bh(&eroute_lock); if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT)) panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n"); memset((caddr_t)rn, 0, sizeof (struct eroute)); kfree(rn); return 0;}intipsec_makeroute(struct sockaddr_encap *eaddr, struct sockaddr_encap *emask, struct sa_id said, uint32_t pid){ struct eroute *retrt; int error = 0; char sa[SATOA_BUF]; size_t sa_len;#ifdef CONFIG_IPSEC_DEBUG char buf1[64], buf2[64]; if (debug_eroute) { subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1)); subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2)); sa_len = satoa(said, 0, sa, SATOA_BUF); KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_makeroute: " "attempting to insert eroute for %s->%s, SA: %s, PID:%d\n", buf1, buf2, sa_len ? sa : " (error)", pid); }#endif /* CONFIG_IPSEC_DEBUG */ retrt = (struct eroute *)kmalloc(sizeof (struct eroute), GFP_ATOMIC); if (retrt == NULL) { printk("klips_error:ipsec_makeroute: " "not able to allocate kernel memory"); return -ENOMEM; } memset((caddr_t)retrt, 0, sizeof (struct eroute)); retrt->er_eaddr = *eaddr; retrt->er_emask = *emask; retrt->er_said = said; retrt->er_pid = pid; retrt->er_count = 0; retrt->er_lasttime = jiffies/HZ; rd_key((&(retrt->er_rjt))) = &(retrt->er_eaddr); spin_lock_bh(&eroute_lock); error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask), rnh, retrt->er_rjt.rd_nodes); spin_unlock_bh(&eroute_lock); if(error) { sa_len = satoa(said, 0, sa, SATOA_BUF); KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_makeroute: " "rj_addroute not able to insert eroute for SA:%s\n", sa_len ? sa : " (error)"); kfree(retrt); /* XXX -- should we? */ return error; }#ifdef CONFIG_IPSEC_DEBUG if (debug_eroute && 0) {/* subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1)); subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));*/ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1)); subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2)); sa_len = satoa(retrt->er_said, 0, sa, SATOA_BUF); KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_makeroute: " "pid=%05d " "count=%10d " "lasttime=%6d " "%-18s -> %-18s => %s\n", retrt->er_pid, retrt->er_count, (int)(jiffies/HZ - retrt->er_lasttime), buf1, buf2, sa_len ? sa : " (error)"); }#endif /* CONFIG_IPSEC_DEBUG */ KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_makeroute: " "succeeded, I think...\n"); return 0;}struct eroute *ipsec_findroute(struct sockaddr_encap *eaddr){ struct radij_node *rn;#ifdef CONFIG_IPSEC_DEBUG char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF]; if (debug_radij & DB_RJ_FINDROUTE) { addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1)); addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2)); KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_findroute: " "%s->%s\n", buf1, buf2); }#endif /* CONFIG_IPSEC_DEBUG */ rn = rj_match((caddr_t)eaddr, rnh); if(rn) { KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_findroute: " "found, points to proto=%d, spi=%x, dst=%x.\n", ((struct eroute*)rn)->er_said.proto, ntohl(((struct eroute*)rn)->er_said.spi), ntohl(((struct eroute*)rn)->er_said.dst.s_addr)); } return (struct eroute *)rn;} #ifdef CONFIG_PROC_FSintipsec_rj_walker_procprint(struct radij_node *rn, void *w0){ struct eroute *ro = (struct eroute *)rn; struct rjtentry *rd = (struct rjtentry *)rn; struct wsbuf *w = (struct wsbuf *)w0; char buf1[64], buf2[64]; char sa[SATOA_BUF]; size_t sa_len; struct sockaddr_encap *key, *mask; KLIPS_PRINT(debug_radij, "klips_debug:ipsec_rj_walker_procprint: " "rn=%p, w0=%p\n", rn, w0); if (rn == NULL) { return 120; } if (rn->rj_b >= 0) { return 0; } key = rd_key(rd); mask = rd_mask(rd); if ((key == 0) || (mask == 0)) { return 0; } subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1)); subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2)); sa_len = satoa(ro->er_said, 0, sa, SATOA_BUF); w->len += sprintf(w->buffer + w->len,/* "%05d "*/ "%-10d "/* "%6d "*/ "%-18s -> %-18s => %s\n",/* ro->er_pid,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -