- 論壇徽章:
- 0
|
代碼如下:
#include <linux/bootmem.h>
#include <linux/slab.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/list.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/inet.h>
#include <linux/in.h>
#include <linux/hash.h>
#include <net/ip.h>
#include <net/tcp.h>
#include <net/xfrm.h>
static spinlock_t g_lock;
/******************************************************************
* show_mem_ascii
* show a mem area in ASCII, in order to DEBUG
******************************************************************/
static void
show_mem_ascii(char *prompt, char *data, int len)
{
char buff[128];
char *pbuff, ch;
int i, j, col, lines;
col = 56;
lines = len / col;
printk("%s:\n", prompt);
if(data == NULL) return;
for(i = 0; i < lines; i ++)
{
pbuff = &buff[0];
for(j = 0; j < col; j ++)
{
ch = *(data + i * col + j);
if(ch > 20) sprintf(pbuff, "%c", ch);
else sprintf(pbuff, " ");
pbuff ++;
}
*pbuff = 0;
printk(" %s\n", buff);
}
if(len % col != 0)
{
pbuff = &buff[0];
for(j = 0; j < (len - lines * col); j ++)
{
ch = *(data + lines * col + j);
if(ch > 20) sprintf(pbuff, "%c", ch);
else sprintf(pbuff, " ");
pbuff ++;
}
*pbuff = 0;
printk(" %s\n", buff);
}
}
/******************************************************************
* show_mem_hex
* show a mem area in HEX, in order to DEBUG
******************************************************************/
static void
show_mem_hex(char *prompt, unsigned char *data, int len)
{
char buff[128];
char *pbuff;
int i, j, lines = len / 16;
printk("%s:\n", prompt);
for(i = 0; i < lines; i ++)
{
pbuff = &buff[0];
for(j = 0; j < 16; j ++)
{
sprintf(pbuff, "%02X ", *(data + i * 16 + j));
pbuff += 3;
if(j == 7)
{
*pbuff = ' ';
pbuff ++;
}
}
*pbuff = 0;
printk(" %s\n", buff);
}
if(len % 16 != 0)
{
pbuff = &buff[0];
for(j = 0; j < (len - lines * 16); j ++)
{
sprintf(pbuff, "%02X ", *(data + lines * 16 + j));
pbuff += 3;
if(j == 7)
{
*pbuff = ' ';
pbuff ++;
}
}
*pbuff = 0;
printk(" %s\n", buff);
}
}
/******************************************************************
* show_skb_content
*
******************************************************************/
static void
show_skb_content(struct sk_buff *skb)
{
int i;
char *t_h, *n_h, *m_h;
struct skb_shared_info *skb_sh;
skb_linearize(skb);
//char flags[8];
//unsigned char *ips, *ipd;
//int tcp_data_len, packet_len;
//struct iphdr *iph = (struct iphdr *)skb->transport_header;
//struct tcphdr *tcph = (struct tcphdr *)(skb->data + (iph->ihl << 2));
t_h = skb_transport_header(skb);
n_h = skb_network_header(skb);
m_h = skb_mac_header(skb);
printk("--------------------SKB CONTENT----------------------\n");
printk("len:%d, data_len:%d, mac_len:%d, hdr_len:%d\n", skb->len, skb->data_len, skb->mac_len, skb->hdr_len);
printk("head:%p; data:%p\n", skb->head, skb->data);
printk("tail:%p; end:%p\n", skb->tail, skb->end);
printk("transport_header:%p, network_header:%p, mac_header:%p\n", t_h, n_h, m_h);
printk("pkt type:%d, protocol:%d, local_df:%d\n", skb->pkt_type, skb->protocol, skb->local_df);
skb_sh = skb_shinfo(skb);
printk("frag count:%d\n", skb_sh->nr_frags);
if(skb_sh->nr_frags > 0)
{
for(i = 0; i < skb_sh->nr_frags; i ++)
{
show_mem_hex("", skb_sh->frags.page + skb_sh->frags.page_offset, skb_sh->frags.size);
}
}
else
{
show_mem_hex("data", skb->data, skb->data_len);
}
}
static unsigned int
hook_ip_forward(unsigned int hook, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *))
{
if(in == NULL) return NF_ACCEPT;
if(in->name == NULL) return NF_ACCEPT;
if(out == NULL) return NF_ACCEPT;
if(out->name == NULL) return NF_ACCEPT;
if (skb == NULL) return NF_ACCEPT;
printk("net_device names, in:%s, out %s\n", in->name, out->name);
spin_lock_irq(&g_lock);
show_skb_content(skb);
spin_unlock_irq(&g_lock);
return NF_ACCEPT;
}
static struct nf_hook_ops ops_ip_forward =
{
.hook = hook_ip_forward,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_INET_FORWARD,
.priority = NF_IP_PRI_FIRST,
};
static int __init t4ipf_init(void)
{
int ret;
printk(KERN_EMERG"begin initializing\n");
spin_lock_init(&g_lock);
ret = nf_register_hook(&ops_ip_forward);
printk("nf_register_hook return %d\n", ret);
printk(KERN_EMERG"initialized\n");
return ret;
}
static void __exit t4ipf_fini(void)
{
printk(KERN_EMERG"begin finishing\n");
nf_unregister_hook(&ops_ip_forward);
printk(KERN_EMERG"finished\n");
}
module_init(t4ipf_init);
module_exit(t4ipf_fini);
MODULE_AUTHOR("ZhengYong, zy_ball@yahoo.com.cn");
MODULE_DESCRIPTION("");
MODULE_LICENSE("GPL");
=====================================================================
帖個struct sk_buff*包:
len:-2085642495, 0x83AF9F01; data_len:52, mac_len:0, hdr_len:0
head:-2104835932, 0x828AC0A4; data:-2104834400, 0x828AC6A0
tail:-2104835984, 0x828AC070; end:-2104835998, 0x828AC062
transport_header:0xA, network_header:0x0, mac_header:0x828AC070
pkt type:0, protocol:0
data_len的長度是對的,除此之外好像都不太對,
特別是data竟然比head大很多,也還可以接受,但是data比tail和end都大,就不對了
len怎么這么大? |
|