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

📄 kernelenv.c

📁 openswan
💻 C
📖 第 1 页 / 共 2 页
字号:
/*Copyright (c) 2003,2004 Jeremy Kerr & Rusty RussellThis file is part of nfsim.nfsim is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.nfsim is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with nfsim; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#include <kernelenv.h>#include "utils.h"#include "field.h"#if 0#include "tui.h" #endif/* Root of talloc trees for different allocators */void *__skb_ctx, *__vmalloc_ctx, *__kmalloc_ctx, *__kmalloc_atomic_ctx, *__kmem_cache_ctx, *__lock_ctx, *__timer_ctx;unsigned long num_physpages = 1024;unsigned long jiffies = INITIAL_JIFFIES;u32 htonl(u32 hostlong){	return __cpu_to_be32(hostlong);}	u16 htons(u16 hostshort){	return __cpu_to_be16(hostshort);}u32 ntohl(u32 netlong){	return __be32_to_cpu(netlong);}u16 ntohs(u16 netshort){	return __be16_to_cpu(netshort);}/* skbuff */static int nfsim_seq;#if 0/* We hide the shared info in hidden field (kernel puts it after * data).  This way valgrind can spot overruns. */struct skb_shared_info *skb_shinfo(struct sk_buff *skb){	return field_value(skb, "skb_shinfo");}#endifstruct skb_extra_info {	unsigned char *data;	unsigned int len, writable_len;};/* Create an skb: first amount that is linear, then the rest. */struct sk_buff *nfsim_nonlinear_skb(const void *data1,				    unsigned int size1,				    const void *data2,				    unsigned int size2){	struct sk_buff *skb;#ifdef WANT_SKB_SHINFO	struct skb_extra_info *extra;	struct skb_shared_info *sinfo;#endif	/* Skb header. */	skb = talloc_zero(__skb_ctx, struct sk_buff);#ifdef WANT_SKB_SHINFO	/* Save copy of data, all non-writable. */	extra = talloc(skb, struct skb_extra_info);	extra->len = size1 + size2;	extra->writable_len = 0;	extra->data = talloc_size(extra, extra->len);	memcpy(extra->data, data1, size1);	memcpy(extra->data+size1, data2, size2);	field_attach(skb, "extra_data", extra);	/* Place linear data in skb. */	skb->data = talloc_memdup(skb, extra->data, size1);#endif#ifdef WANT_SKB_SHINFO	sinfo = talloc(skb, struct skb_shared_info);	field_attach(skb, "skb_shinfo", sinfo);#endif	atomic_set(&skb->users, 1);	skb->head = skb->data;	skb->end = skb->tail = skb->data + size1;	skb->len = size1 + size2;	skb->seq = ++nfsim_seq;#ifdef WANT_SKB_SHINFO	/* set shinfo fields */	skb_shinfo(skb)->tso_size = 0;#endif	return skb;}/* Normal, linear skb. *//*static*/ struct sk_buff *nfsim_skb(unsigned int size){	struct sk_buff *skb;#ifdef WANT_SKB_SHINFO	struct skb_shared_info *sinfo;#endif	/* Skb header. */	skb = talloc_zero(__skb_ctx, struct sk_buff);	/* Place linear data in skb. */	skb->data = talloc_size(skb, size);#ifdef WANT_SKB_SHINFO	sinfo = talloc(skb, struct skb_shared_info);	field_attach(skb, "skb_shinfo", sinfo);#endif	atomic_set(&skb->users, 1);	skb->head = skb->tail = skb->data;	skb->len = 0;	skb->end = skb->data + size;	skb->seq = ++nfsim_seq;#ifdef WANT_SKB_SHINFO	/* set shinfo fields */	skb_shinfo(skb)->tso_size = 0;#endif	return skb;}#ifdef NFSIM_CHECKvoid nfsim_check_packet(const struct sk_buff *skb){	struct skb_extra_info *extra = field_value(skb, "extra_data");	unsigned int linear_len = skb->end - skb->head;	if (!extra)		return;	/* Packet should not have been changed where not writable. */	if (memcmp(skb->head + extra->writable_len,		   extra->data + extra->writable_len,		   linear_len - extra->writable_len) != 0)		barf("skb modified without being made writable!");}/* Internal routine to say we updated skb. */void nfsim_update_skb(struct sk_buff *skb, void *vp, unsigned int size){	unsigned char *p = (unsigned char *)vp;	struct skb_extra_info *extra = field_value(skb, "extra_data");	unsigned int off = p - (unsigned char *)skb->head;	if (!extra)		return;	if (off + size > extra->len)		barf("Bad nfsim_update_skb %i");	/* If it wasn't already writable, copy update to master. */	if (off + size > extra->writable_len)		memcpy(extra->data + off, p, size);	nfsim_check_packet(skb);}#else#define nfsim_check_packet(skb)#define nfsim_update_skb(skb, vp, size)#endif/* Defined to return a linear skb. */struct sk_buff *alloc_skb(unsigned int size, int priority){	if (should_i_fail(__func__))		return NULL;	return nfsim_skb(size);}void kfree_skb(struct sk_buff *skb){#ifdef CONFIG_NETFILTER	nf_conntrack_put(skb->nfct);#endif	if (skb->dst)		dst_release(skb->dst);	talloc_free(skb);}unsigned char *skb_put(struct sk_buff *skb, unsigned int len){	unsigned char *tmp = skb->tail;	skb->tail += len;	skb->len += len;	if (skb->tail > skb->end)		barf("skb_put will overrun buffer");	return tmp;}unsigned char *skb_push(struct sk_buff *skb, unsigned int len){		skb->data -= len;	skb->len  += len;	if (skb->data < skb->head)		barf("skb_push will underrun buffer");	return skb->data;}unsigned char *skb_pull(struct sk_buff *skb, unsigned int len){		skb->data += len;	skb->len  -= len;	if (skb->data < skb->head)		barf("skb_pull will underrun buffer");	return skb->data;}/* Defined to return a writable, linear skb. */struct sk_buff *skb_copy_expand(const struct sk_buff *skb,				int newheadroom, int newtailroom, int gfp_mask){	struct sk_buff *n;	nfsim_check_packet(skb);	if (should_i_fail(__func__))		return NULL;	n = nfsim_skb(newheadroom + skb->len + newtailroom);	skb_reserve(n, newheadroom);	skb_put(n, skb->len);	if (skb_copy_bits(skb, 0, n->data, skb->len))		barf("skb_copy_bits failed");	copy_skb_header(n, skb);	return n;}unsigned int skb_headroom(const struct sk_buff *skb){	return skb->data - skb->head;}unsigned int skb_tailroom(const struct sk_buff *skb){	return skb_is_nonlinear(skb) ? 0 : skb->end - skb->tail;}unsigned int skb_cow(struct sk_buff *skb, unsigned int headroom){	int delta = (headroom > 16 ? headroom : 16) - skb_headroom(skb);	if (delta < 0)		delta = 0;	if (delta || skb_cloned(skb)) {	  /* XXX not yet written */	  abort();	  //return pskb_expand_head(skb, (delta + 15) & ~15, 0, GFP_ATOMIC);	}	return 0;}void skb_reserve(struct sk_buff *skb, unsigned int len){	skb->data += len;	skb->tail += len;	if (skb->data > skb->end || skb->tail > skb->end)		barf("skb_reserve: too much");}/* careful with this one.. */#define __copy(member) new->member = old->membervoid copy_skb_header(struct sk_buff *new, const struct sk_buff *old){	unsigned long offset = new->data - old->data;		__copy(dev);	__copy(seq);	__copy(local_df);	__copy(len);	__copy(csum);	__copy(ip_summed);	__copy(nfmark);	__copy(nfcache);	__copy(nfct);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)	__copy(nfctinfo);#endif	nf_conntrack_get(new->nfct);		/* dst_clone() ? */	__copy(dst);	new->h.raw  = old->h.raw  + offset;	new->nh.raw = old->nh.raw + offset;#if 0	if (field_exists(old, "dump_flags"))		field_attach(new, "dump_flags",			     talloc_strdup(NULL,					   field_value(old, "dump_flags")));#endif}#undef __copystatic inline int nfsim_linear_length(const struct sk_buff *skb){	return skb->end - skb->data;}int skb_copy_bits(const struct sk_buff *skb, int offset,		  void *vto, int len){	unsigned char *to = (unsigned char *)vto;#ifdef WANT_SKB_SHINFO	struct skb_extra_info *extra = field_value(skb, "extra_data");#endif	nfsim_check_packet(skb);	if (offset > (int)skb->len - len)		return -EFAULT;	/* Can we copy some from linear part of packet? */	if (offset < nfsim_linear_length(skb)) {		int len_from_data = min(len, nfsim_linear_length(skb)-offset);		memcpy(to, skb->data + offset, len_from_data);		offset += len_from_data;		len -= len_from_data;		to += len_from_data;	}#ifdef WANT_SKB_SHINFO	/* Copy from nonlinear part. */	if (extra)		memcpy(to, extra->data + skb_headroom(skb) + offset, len);	else		assert(len == 0);#endif	return 0;}struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom){	int delta = headroom - skb_headroom(skb);	return skb_copy_expand(skb, delta > 0 ? delta : 0, 0, GFP_ATOMIC);}int pskb_may_pull(struct sk_buff *skb, unsigned int len){	return (len <= skb_headroom(skb));}static int __skb_checksum_help(struct sk_buff *skb, int inward){	unsigned int csum;	int ret = 0, offset = skb->h.raw - skb->data;	if (inward) {		skb->ip_summed = CHECKSUM_NONE;		goto out;	}	if (skb_shared(skb)  || skb_cloned(skb)) {		struct sk_buff *newskb = skb_copy(skb, GFP_ATOMIC);		if (!newskb) {			ret = -ENOMEM;			goto out;		}		if (skb->sk)			skb_set_owner_w(newskb, skb->sk);		kfree_skb(skb);		skb = newskb;	}	if (offset > (int)skb->len)		BUG();	csum = skb_checksum(skb, offset, skb->len-offset, 0);	offset = skb->tail - skb->h.raw;	if (offset <= 0)		BUG();	if (skb->csum + 2 > offset)		BUG();	*(u16*)(skb->h.raw + skb->csum) = csum_fold(csum);	skb->ip_summed = CHECKSUM_NONE;out:		return ret;}#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)int skb_checksum_help(struct sk_buff *skb){	return __skb_checksum_help(skb, 0);}#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)int skb_checksum_help(struct sk_buff **pskb, int inward){	return __skb_checksum_help(*pskb, inward);}#elseint skb_checksum_help(struct sk_buff *skb, int inward){	return __skb_checksum_help(skb, inward);}#endifint skb_cloned(const struct sk_buff *skb){	return skb->cloned;}int skb_shared(const struct sk_buff *skb){	return atomic_read(&skb->users) != 1;}unsigned int skb_checksum(const struct sk_buff *skb, int offset,			  int len, unsigned int csum){	char data[len];	if (skb_copy_bits(skb, offset, data, len) != 0)		barf("skb_checksum invalid length");	return csum_partial(data, len, csum);}void __skb_trim(struct sk_buff *skb, unsigned int len){	skb->len  = len;	skb->tail = skb->data + len;}void skb_trim(struct sk_buff *skb, unsigned int len){	if (skb->len > len)		__skb_trim(skb, len);}void skb_orphan(struct sk_buff *skb){        if (skb->destructor)                skb->destructor(skb);        skb->destructor = NULL;        skb->sk         = NULL;}int skb_is_nonlinear(const struct sk_buff *skb){	nfsim_check_packet(skb);	return skb->data + skb->len > skb->end;}int skb_ip_make_writable(struct sk_buff **pskb, unsigned int writable_len){	struct sk_buff *new;	struct skb_extra_info *extra;	char data[(*pskb)->len];	nfsim_check_packet(*pskb);	if (writable_len > (*pskb)->len)		return 0;	if (should_i_fail(__func__))		return 0;	/* Use skb_copy_bits, which handles packet whatever shape. */	skb_copy_bits(*pskb, 0, data, (*pskb)->len);	extra = field_value(*pskb, "extra_data");	if (extra && writable_len < extra->writable_len)		writable_len = extra->writable_len;	/* Always reallocate, to catch cached pointers. */	new = nfsim_nonlinear_skb(data, writable_len,				  data + writable_len,				  (*pskb)->len - writable_len);	copy_skb_header(new, *pskb);	extra = field_value(new, "extra_data");	extra->writable_len = writable_len;	if ((*pskb)->sk)		skb_set_owner_w(new, (*pskb)->sk);	kfree_skb(*pskb);	*pskb = new;	return 1;}int skb_linearize(struct sk_buff *skb, int len){	unsigned char *new_head;	unsigned int headroom = skb_headroom(skb);	nfsim_check_packet(skb);	if (should_i_fail(__func__))		return -ENOMEM;	new_head = talloc_size(skb, skb->len + headroom);	memcpy(new_head, skb->head, headroom);	skb_copy_bits(skb, 0, new_head + headroom, skb->len);	skb->data = new_head + headroom;	skb->tail = skb->end = new_head + headroom + skb->len;	talloc_free(skb->head);	skb->head = new_head;	/* Don't need this on writable, linear packets. */	field_detach(skb, "extra_data");	return 0;}/* Either copy into buffer or give pointer to in-place. */void *skb_header_pointer(const struct sk_buff *skb, int offset,			 int len, void *buffer){	nfsim_check_packet(skb);	if (offset + len > skb->len)		return NULL;	/* We should test copying even if not required. */	if (!should_i_fail_once(__func__)) {		if (offset + len <= nfsim_linear_length(skb))			return skb->data + offset;	}	if (skb_copy_bits(skb, offset, buffer, len) < 0)		barf("skb_header_pointer: logic error");	return buffer;}void sock_hold(struct sock *sk){	atomic_inc(&sk->sk_refcnt);}void sock_put(struct sock *sk){	if (atomic_dec_and_test(&sk->sk_refcnt))		free(sk);}void skb_set_owner_w(struct sk_buff *skb, struct sock *sk){	/*	sock_hold(sk);	skb->sk = sk;	skb->destructor = sock_wfree;	atomic_add(skb->truesize, &sk->sk_wmem_alloc);	*/}#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)void nf_conntrack_put(struct nf_ct_info *nfct){	if (nfct && atomic_dec_and_test(&nfct->master->use))		nfct->master->destroy(nfct->master);}void nf_conntrack_get(struct nf_ct_info *nfct){	if (nfct)		atomic_inc(&nfct->master->use);}#elsevoid nf_conntrack_put(struct nf_conntrack *nfct){	if (nfct && atomic_dec_and_test(&nfct->use))

⌨️ 快捷键说明

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