⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 radij.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 3 页
字号:
char radij_c_version[] = "RCSID $Id: radij.c,v 1.47 2004/07/10 19:11:18 mcr Exp $";/* * This file is defived from ${SRC}/sys/net/radix.c of BSD 4.4lite * * Variable and procedure names have been modified so that they don't * conflict with the original BSD code, as a small number of modifications * have been introduced and we may want to reuse this code in BSD. *  * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek * chi or a German ch sound (as `doch', not as in `milch'), or even a  * spanish j as in Juan.  It is not as far back in the throat like * the corresponding Hebrew sound, nor is it a soft breath like the English h. * It has nothing to do with the Dutch ij sound. *  * Here is the appropriate copyright notice: *//* * Copyright (c) 1988, 1989, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)radix.c	8.2 (Berkeley) 1/4/94 *//* * Routines to build and maintain radix trees for routing lookups. */#include <linux/config.h>#include <linux/version.h>#include <linux/kernel.h> /* printk() */#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/skbuff.h>#ifdef NET_21# include <asm/uaccess.h># include <linux/in6.h>#endif /* NET_21 */#include <asm/checksum.h>#include <net/ip.h>#include <openswan.h>#include "openswan/radij.h"#include "openswan/ipsec_encap.h"#include "openswan/ipsec_radij.h"int	maj_keylen;struct radij_mask *rj_mkfreelist;struct radij_node_head *mask_rjhead;static int gotOddMasks;static char *maskedKey;static char *rj_zeroes, *rj_ones;#define rj_masktop (mask_rjhead->rnh_treetop)#ifdef Bcmp# undef Bcmp#endif /* Bcmp */#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l))/* * The data structure for the keys is a radix tree with one way * branching removed.  The index rj_b at an internal node n represents a bit * position to be tested.  The tree is arranged so that all descendants * of a node n have keys whose bits all agree up to position rj_b - 1. * (We say the index of n is rj_b.) * * There is at least one descendant which has a one bit at position rj_b, * and at least one with a zero there. * * A route is determined by a pair of key and mask.  We require that the * bit-wise logical and of the key and mask to be the key. * We define the index of a route to associated with the mask to be * the first bit number in the mask where 0 occurs (with bit number 0 * representing the highest order bit). *  * We say a mask is normal if every bit is 0, past the index of the mask. * If a node n has a descendant (k, m) with index(m) == index(n) == rj_b, * and m is a normal mask, then the route applies to every descendant of n. * If the index(m) < rj_b, this implies the trailing last few bits of k * before bit b are all 0, (and hence consequently true of every descendant * of n), so the route applies to all descendants of the node as well. * * The present version of the code makes no use of normal routes, * but similar logic shows that a non-normal mask m such that * index(m) <= index(n) could potentially apply to many children of n. * Thus, for each non-host route, we attach its mask to a list at an internal * node as high in the tree as we can go.  */struct radij_node *rj_search(v_arg, head)	void *v_arg;	struct radij_node *head;{	register struct radij_node *x;	register caddr_t v;	for (x = head, v = v_arg; x->rj_b >= 0;) {		if (x->rj_bmask & v[x->rj_off])			x = x->rj_r;		else			x = x->rj_l;	}	return (x);};struct radij_node *rj_search_m(v_arg, head, m_arg)	struct radij_node *head;	void *v_arg, *m_arg;{	register struct radij_node *x;	register caddr_t v = v_arg, m = m_arg;	for (x = head; x->rj_b >= 0;) {		if ((x->rj_bmask & m[x->rj_off]) &&		    (x->rj_bmask & v[x->rj_off]))			x = x->rj_r;		else			x = x->rj_l;	}	return x;};intrj_refines(m_arg, n_arg)	void *m_arg, *n_arg;{	register caddr_t m = m_arg, n = n_arg;	register caddr_t lim, lim2 = lim = n + *(u_char *)n;	int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);	int masks_are_equal = 1;	if (longer > 0)		lim -= longer;	while (n < lim) {		if (*n & ~(*m))			return 0;		if (*n++ != *m++)			masks_are_equal = 0;				}	while (n < lim2)		if (*n++)			return 0;	if (masks_are_equal && (longer < 0))		for (lim2 = m - longer; m < lim2; )			if (*m++)				return 1;	return (!masks_are_equal);}struct radij_node *rj_match(v_arg, head)	void *v_arg;	struct radij_node_head *head;{	caddr_t v = v_arg;	register struct radij_node *t = head->rnh_treetop, *x;	register caddr_t cp = v, cp2, cp3;	caddr_t cplim, mstart;	struct radij_node *saved_t, *top = t;	int off = t->rj_off, vlen = *(u_char *)cp, matched_off;	/*	 * Open code rj_search(v, top) to avoid overhead of extra	 * subroutine call.	 */	for (; t->rj_b >= 0; ) {		if (t->rj_bmask & cp[t->rj_off])			t = t->rj_r;		else			t = t->rj_l;	}	/*	 * See if we match exactly as a host destination	 */	KLIPS_PRINT(debug_radij,		    "klips_debug:rj_match: "		    "* See if we match exactly as a host destination\n");		cp += off; cp2 = t->rj_key + off; cplim = v + vlen;	for (; cp < cplim; cp++, cp2++)		if (*cp != *cp2)			goto on1;	/*	 * This extra grot is in case we are explicitly asked	 * to look up the default.  Ugh!	 */	if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey)		t = t->rj_dupedkey;	return t;on1:	matched_off = cp - v;	saved_t = t;	KLIPS_PRINT(debug_radij,		    "klips_debug:rj_match: "		    "** try to match a leaf, t=0p%p\n", t);	do {	    if (t->rj_mask) {		/*		 * Even if we don't match exactly as a hosts;		 * we may match if the leaf we wound up at is		 * a route to a net.		 */		cp3 = matched_off + t->rj_mask;		cp2 = matched_off + t->rj_key;		for (; cp < cplim; cp++)			if ((*cp2++ ^ *cp) & *cp3++)				break;		if (cp == cplim)			return t;		cp = matched_off + v;	    }	} while ((t = t->rj_dupedkey));	t = saved_t;	/* start searching up the tree */	KLIPS_PRINT(debug_radij,		    "klips_debug:rj_match: "		    "*** start searching up the tree, t=0p%p\n",		    t);	do {		register struct radij_mask *m;				t = t->rj_p;		KLIPS_PRINT(debug_radij,			    "klips_debug:rj_match: "			    "**** t=0p%p\n",			    t);		if ((m = t->rj_mklist)) {			/*			 * After doing measurements here, it may			 * turn out to be faster to open code			 * rj_search_m here instead of always			 * copying and masking.			 */			/* off = min(t->rj_off, matched_off); */			off = t->rj_off;			if (matched_off < off)				off = matched_off;			mstart = maskedKey + off;			do {				cp2 = mstart;				cp3 = m->rm_mask + off;				KLIPS_PRINT(debug_radij,					    "klips_debug:rj_match: "					    "***** cp2=0p%p cp3=0p%p\n",					    cp2, cp3);				for (cp = v + off; cp < cplim;)					*cp2++ =  *cp++ & *cp3++;				x = rj_search(maskedKey, t);				while (x && x->rj_mask != m->rm_mask)					x = x->rj_dupedkey;				if (x &&				    (Bcmp(mstart, x->rj_key + off,					vlen - off) == 0))					    return x;			} while ((m = m->rm_mklist));		}	} while (t != top);	KLIPS_PRINT(debug_radij,		    "klips_debug:rj_match: "		    "***** not found.\n");	return 0;};		#ifdef RJ_DEBUGint	rj_nodenum;struct	radij_node *rj_clist;int	rj_saveinfo;DEBUG_NO_STATIC void traverse(struct radij_node *);#ifdef RJ_DEBUG2int	rj_debug =  1;#elseint	rj_debug =  0;#endif /* RJ_DEBUG2 */#endif /* RJ_DEBUG */struct radij_node *rj_newpair(v, b, nodes)	void *v;	int b;	struct radij_node nodes[2];{	register struct radij_node *tt = nodes, *t = tt + 1;	t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7);	t->rj_l = tt; t->rj_off = b >> 3;	tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t;	tt->rj_flags = t->rj_flags = RJF_ACTIVE;#ifdef RJ_DEBUG	tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;	tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;#endif /* RJ_DEBUG */	return t;}struct radij_node *rj_insert(v_arg, head, dupentry, nodes)	void *v_arg;	struct radij_node_head *head;	int *dupentry;	struct radij_node nodes[2];{	caddr_t v = v_arg;	struct radij_node *top = head->rnh_treetop;	int head_off = top->rj_off, vlen = (int)*((u_char *)v);	register struct radij_node *t = rj_search(v_arg, top);	register caddr_t cp = v + head_off;	register int b;	struct radij_node *tt;    	/*	 *find first bit at which v and t->rj_key differ	 */    {	register caddr_t cp2 = t->rj_key + head_off;	register int cmp_res;	caddr_t cplim = v + vlen;	while (cp < cplim)		if (*cp2++ != *cp++)			goto on1;	*dupentry = 1;	return t;on1:	*dupentry = 0;	cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;	for (b = (cp - v) << 3; cmp_res; b--)		cmp_res >>= 1;    }    {	register struct radij_node *p, *x = top;	cp = v;	do {		p = x;		if (cp[x->rj_off] & x->rj_bmask) 			x = x->rj_r;		else x = x->rj_l;	} while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */#ifdef RJ_DEBUG	if (rj_debug)		printk("klips_debug:rj_insert: Going In:\n"), traverse(p);#endif /* RJ_DEBUG */	t = rj_newpair(v_arg, b, nodes); tt = t->rj_l;	if ((cp[p->rj_off] & p->rj_bmask) == 0)		p->rj_l = t;	else		p->rj_r = t;	x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */	if ((cp[t->rj_off] & t->rj_bmask) == 0) {		t->rj_r = x;	} else {		t->rj_r = tt; t->rj_l = x;	}#ifdef RJ_DEBUG	if (rj_debug)		printk("klips_debug:rj_insert: Coming out:\n"), traverse(p);#endif /* RJ_DEBUG */    }	return (tt);}struct radij_node *rj_addmask(n_arg, search, skip)	int search, skip;	void *n_arg;{	caddr_t netmask = (caddr_t)n_arg;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -