netfilter 求救
大家好,小弟最近学习netfilter遇到问题,希望CU的兄弟可以帮到我,先谢谢大家了。先贴代码,原文可以在:http://hi.baidu.com/widebright/item/0c6c94b44e749c9619469784看到
下面的代码仅仅在原文进行修改测试。
运行测试环境:rehl5.4虚拟机内核2.6.32/*
* widebright.c
*
*Created on: 2009-10-13
* Author: widebright
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <net/tcp.h>
#include <net/udp.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <net/sock.h>
#include <net/netfilter/nf_nat.h>
#include <net/netfilter/nf_nat_helper.h>
#include <net/netfilter/nf_nat_rule.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_expect.h>
MODULE_LICENSE("GPL"); //用了nf_conntrack_tcp_update 函数要用这个遵守GPL开放协议才能编译通
typedef unsigned int uint32;
typedef unsigned char uchar8;
typedef struct app_detection_module_struct {
uint32 sport;
uint32 dport;
uint32 saddr;
uint32 daddr;
uint32 plen;//the len not include ip header and (tcp/udp)header
uchar8* payload;//packet not include ip header and (tcp/udp)header
} APP_DATA;
static void hex_dump(const unsigned char *buf, size_t len) {
size_t i;
for (i = 0; i < len; i++) {
if (i && !(i % 16))
printk("\n");
printk("%02x ", *(buf + i));
}
printk("\n");
}
char * is_mp3_request(char * start) {
char data = ".mp3";
char * i = start;
i += 4; //跳过 GET
while (*i != ' ' && *i != '\n')
i++; //查找网络地址最后的位置
if (*(int *) (i - 4) == *(int *) data)
return i;
else
return NULL;
}
unsigned int check_link_address(unsigned int hooknum, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, int(*okfn)(
struct sk_buff *)) {
struct iphdr *iph = NULL;
struct tcphdr *tcph = NULL;
struct tcphdr *udph = NULL;
uint32 i = 0;
APP_DATA* app_data = NULL;
int oldlen, datalen;
struct rtable *rt = skb->rtable;
enum ip_conntrack_info ctinfo;
iph = ip_hdr(skb);
app_data = (APP_DATA* )kmalloc(sizeof(APP_DATA), GFP_ATOMIC);
if(app_data == NULL)
return NF_ACCEPT;
app_data->saddr = iph->saddr;
app_data->daddr = iph->daddr;
//Note that the connection tracking subsystem
//is invoked after the raw table has been processed, but before the mangle table.
//所以下面 要指定.priority = NF_IP_PRI_MANGLEnf_ct_get 才会返回有效的值
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
if (iph->protocol == IPPROTO_TCP) {
tcph = (void *) iph + iph->ihl * 4;
app_data->sport = ntohs(tcph->source); //Src端口
app_data->dport = ntohs(tcph->dest); //Dest端口
app_data->payload = (char*)iph+(iph->ihl*4) + tcph->doff*4; //从data里面偏移出前面的ip包头和tcp包头
app_data->plen = ntohs(iph->tot_len)-(iph->ihl*4) - tcph->doff*4; //TCP包长度
if(ntohs(app_data->dport) == 80)
{
printk("src: %u.%u.%u.%u:%u<===> dst: %u.%u.%u.%u:%u \n",NIPQUAD(app_data->saddr),ntohs(app_data->sport),NIPQUAD(app_data->daddr),ntohs(app_data->dport));
return NF_ACCEPT;
}
// printk("tcp packet to : %u.%u.%u.%u:%u\n",NIPQUAD(daddr),ntohs(dport));
// printk("---------ip total len =%d--------\n", ntohs(iph->tot_len));
// printk("---------tcph->doff =%d--------\n", tcph->doff*4);
/* skb_linearize - convert paged skb to linear one
* If there is no free memory -ENOMEM is returned, otherwise zero
* is returned and the old skb data released.
* 这一步很关键,否则后面根据 包头偏移计算出来payload 得到东西不是正确的包结构
*2.6内核需要这么做。因为新的系统可能为了提高性能,一个网络包的内容是分成几个fragments来保存的
*这时 单单根据 skb->data得到的只是包的第一个 fragments的东西。我见到我系统上的就是tcp头部和 tcp的payload
*是分开保存在不同的地方的。可能ip,tcp头部等是后面系统层才加上的,和应用程序的payload来源不一样,使用不同的fragments就
*可以避免复制数据到新缓冲区的操作提高性能。skb_shinfo(skb)->nr_frags属性指明了这个skb网络包里面包含了多少块 fragment了。
*具体可以看《Linux Device Drivers, 3rd Editio》一书的17.5.3. Scatter/Gather I/O小节
* 《Understanding_Linux_Network_Internals》 一书 Chapter 21. Internet Protocol Version 4 (IPv4): Transmission 一章有非常详细的介绍
*下面使用的skb_linearize 函数则可以简单的把 多个的frag合并到一起了,我为了简单就用了它。
*/
/*
if (0 != skb_linearize(skb)) {
return NF_ACCEPT;
}
*/
// payload = (void *)tcph + tcph->doff*4; skb_linearize(skb) 调用之后,skb被重新构建了,之前的tcp指向的不是正确的地址了。
//payload = (void *) skb->data + 40; //我的机器上tcph->doff*4 + iph->ihl*4等于40, 就是从data里面偏移出前面的ip包头和tcp包头
//tcp 包长度 ntohs(iph->tot_len) - iph->ihl*4 - tcph->doff*4
app_data->payload = (void *) skb->data + 40;
app_data->plen = ntohs(iph->tot_len)-(iph->ihl*4) - tcph->doff*4;
//hex_dump(app_data->payload ,app_data->plen);
/*
if((app_data->plen)<10)
{
//printk("plen <10\n");
return 0;
}
*/
if(memcmp(app_data->payload, "GET ", 4) == 0)
{
printk("%s\n", "HTTP GET FOUND");
char * head = is_mp3_request(app_data->payload);
if (head) {
printk("%s\n", head);
//刚刚发现把 http://www.google.cn/1.mp3 改成 http://www.google.cn/1.%6D%70%33 就可以跳过网关的检测了,%6D%70%33 是mp3的html编码
//nf_nat_mangle_tcp_packet 是netfilter nat模块里面的导出函数,所以需要nat模块加载之后才能进行的。
//如果你没有配置内核自动加载这个模块,好像执行一下“sudo iptables -t nat --list” 命令就会加载起来。
if (ct && nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
(char*) head - (char *)app_data->payload -3 , 3,
(char *) "%6D%70%33", sizeof("%6D%70%33")-1 )) {
printk("-----------------nf_nat_mangle_tcp_packet--------------------\n%20s\n",
app_data->payload);
return NF_ACCEPT;
}
//wineshark 抓包说明后续tcp包的序号依然不对,原因是修改后,tcp的需要加上 增加的字节,但系统不知道这个改变,所以下次还是用以前的 序号来发送数据,
//所以后面的包的序号就不对了. 在/net/ipv4/tcp_output.c 中的tcp_transmit_skb函数中,可以看到系统是如何填写这个数据的。但在hook的时候无法
//得到tcp层的信息,本来想一劳永逸的把初始序号改正确的但无法做到。只好hook没个包的时候都把序号改正过来了。
//nf_nat_mangle_tcp_packet修改tcp包后,会记录下需要调整的seq的序列(参考内核源代码/net/ipv4/netfilter/nf_nat_helper.c 文件爱你里面的
//adjust_tcp_sequence函数,他把需要调整的信息记录在两个 struct nf_nat_seq结构里面了。)但没有看到自动对后续的网络国包进行处理了。
//所以需要在另外的hook里面把标识出来的需要修复序号的包都,调用一下seq修复函数nf_nat_seq_adjust,把后面所有tcp包的seq都进行修复。
//这个工作如果你的修改导致包的长度改变的都需要作。conntrack模块里面会调用helper module的
//nf_nat_seq_adjust_hook函数来作这个工作的。参考 内核源代码的 /net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c 中的ipv4_confirm函数
//但没看到调用nf_nat_seq_adjust 函数的地方,所以我自己又加了两个hook来捕获后续网络包,显示的调用nf_nat_seq_adjust 函数。
//nf_nat_seq_adjust 函数在net/ipv4/netfilter/nf_nat_helper.c 文件的里面有,但没有导出,所以我把他复制过来了,不过 注意不同的内核扳本有所不同
//如果编译有问题,就去把对应的内核源代码中的几个函数复制出来吧。
return NF_ACCEPT;
//不用 nf_nat_mangle_tcp_packet 函数来修改感到话,虽然下面修改办法没有问题,但计算tcp校验和和序列号的结果不对。
char *end = skb_put(skb, 9); //希望skb的buffer的容两可以继续在尾部加上9个字节的数据,不然这个会导致BUG()触发,http请求数据不会太大吧。
//memmove(
while (end > head) {
end--;
*(end + 9) = *end;
}
memcpy(head, "%6D%70%33", 9);
/* fix IP hdr checksum information */
ip_hdr(skb)->tot_len = htons(skb->len);
ip_send_check(ip_hdr(skb));
//计算校验和,参考内核源码 的net/ipv4/tcp_ipv4.c tcp_v4_send_check函数
//和net/ipv4/netfilter/nf_nat_helper.c nf_nat_mangle_tcp_packet 函数
//和net/netfilter/xt_TCPMSS.c 的 tcpmss_mangle_packet 函数
datalen = skb->len - iph->ihl * 4;
oldlen = datalen - 9;
if (skb->ip_summed != CHECKSUM_PARTIAL) {
if (!(rt->rt_flags & RTCF_LOCAL) && skb->dev->features
& NETIF_F_V4_CSUM) {
skb->ip_summed = CHECKSUM_PARTIAL;
skb->csum_start = skb_headroom(skb)
+ skb_network_offset(skb) + iph->ihl * 4;
skb->csum_offset = offsetof(struct tcphdr, check);
tcph->check = ~tcp_v4_check(datalen, iph->saddr,
iph->daddr, 0);
} else {
tcph->check = 0;
tcph->check = tcp_v4_check(datalen, iph->saddr,
iph->daddr, csum_partial(tcph, datalen, 0));
}
} else
inet_proto_csum_replace2(&tcph->check, skb, htons(oldlen),
htons(datalen), 1);
printk("---------------------------------------\n%20s\n",
app_data->payload);
}
}
return NF_ACCEPT;
//return NF_DROP; /*丢掉这个包*/
}
else
{
return NF_ACCEPT;/*这个包传给下一个hook函数另有NF_QUEUE, it's queued. */
}
kfree(app_data);
app_data = NULL;
return NF_ACCEPT;
}
//一下3个函数是内核源代码的net/ipv4/netfilter/nf_nat_helper.c 里面的,没有导出。需要找到对应的内核扳本的才能编译通过
//在http://lxr.linux.no/上看到2.6.31 和2.6.28用到的其他函数有点变化了。下面是
/* Adjust one found SACK option including checksum correction */
static void
sack_adjust(struct sk_buff *skb,
struct tcphdr *tcph,
unsigned int sackoff,
unsigned int sackend,
struct nf_nat_seq *natseq)
{
while (sackoff < sackend) {
struct tcp_sack_block_wire *sack;
__be32 new_start_seq, new_end_seq;
sack = (void *)skb->data + sackoff;
if (after(ntohl(sack->start_seq) - natseq->offset_before,
natseq->correction_pos))
new_start_seq = htonl(ntohl(sack->start_seq)
- natseq->offset_after);
else
new_start_seq = htonl(ntohl(sack->start_seq)
- natseq->offset_before);
if (after(ntohl(sack->end_seq) - natseq->offset_before,
natseq->correction_pos))
new_end_seq = htonl(ntohl(sack->end_seq)
- natseq->offset_after);
else
new_end_seq = htonl(ntohl(sack->end_seq)
- natseq->offset_before);
printk("sack_adjust: start_seq: %d->%d, end_seq: %d->%d\n",
ntohl(sack->start_seq), new_start_seq,
ntohl(sack->end_seq), new_end_seq);
inet_proto_csum_replace4(&tcph->check, skb,
sack->start_seq, new_start_seq, 0);
inet_proto_csum_replace4(&tcph->check, skb,
sack->end_seq, new_end_seq, 0);
sack->start_seq = new_start_seq;
sack->end_seq = new_end_seq;
sackoff += sizeof(*sack);
}
}
/* TCP SACK sequence number adjustment */
static inline unsigned int
nf_nat_sack_adjust(struct sk_buff *skb,
struct tcphdr *tcph,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
{
unsigned int dir, optoff, optend;
struct nf_conn_nat *nat = nfct_nat(ct);
nat = nfct_nat(ct);
if (!nat) {
/* NAT module was loaded late. */
if (nf_ct_is_confirmed(ct))
return NF_ACCEPT;
nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
if (nat == NULL) {
pr_debug("failed to add NAT extension\n");
return NF_ACCEPT;
}
}
optoff = ip_hdrlen(skb) + sizeof(struct tcphdr);
optend = ip_hdrlen(skb) + tcph->doff * 4;
if (!skb_make_writable(skb, optend))
return 0;
dir = CTINFO2DIR(ctinfo);
while (optoff < optend) {
/* Usually: option, length. */
unsigned char *op = skb->data + optoff;
switch (op) {
case TCPOPT_EOL:
return 1;
case TCPOPT_NOP:
optoff++;
continue;
default:
/* no partial options */
if (optoff + 1 == optend ||
optoff + op > optend ||
op < 2)
return 0;
if (op == TCPOPT_SACK &&
op >= 2+TCPOLEN_SACK_PERBLOCK &&
((op - 2) % TCPOLEN_SACK_PERBLOCK) == 0)
sack_adjust(skb, tcph, optoff+2,
optoff+op, &nat->seq[!dir]);
optoff += op;
}
}
return 1;
}
/* TCP sequence number adjustment.Returns 1 on success, 0 on failure */
int
nf_nat_seq_adjust(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
{
struct tcphdr *tcph;
int dir;
__be32 newseq, newack;
s16 seqoff, ackoff;
struct nf_conn_nat *nat = nfct_nat(ct);
struct nf_nat_seq *this_way, *other_way;
dir = CTINFO2DIR(ctinfo);
this_way = &nat->seq;
other_way = &nat->seq[!dir];
if (!skb_make_writable(skb, ip_hdrlen(skb) + sizeof(*tcph)))
return 0;
tcph = (void *)skb->data + ip_hdrlen(skb);
if (after(ntohl(tcph->seq), this_way->correction_pos))
seqoff = this_way->offset_after;
else
seqoff = this_way->offset_before;
if (after(ntohl(tcph->ack_seq) - other_way->offset_before,
other_way->correction_pos))
ackoff = other_way->offset_after;
else
ackoff = other_way->offset_before;
newseq = htonl(ntohl(tcph->seq) + seqoff);
newack = htonl(ntohl(tcph->ack_seq) - ackoff);
inet_proto_csum_replace4(&tcph->check, skb, tcph->seq, newseq, 0);
inet_proto_csum_replace4(&tcph->check, skb, tcph->ack_seq, newack, 0);
printk("Adjusting sequence number from %u->%u, ack from %u->%u\n",
ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq),
ntohl(newack));
tcph->seq = newseq;
tcph->ack_seq = newack;
return nf_nat_sack_adjust(skb, tcph, ct, ctinfo);
}
unsigned int fix_seq(unsigned int hooknum, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, int(*okfn)(
struct sk_buff *))
{
enum ip_conntrack_info ctinfo;
//Note that the connection tracking subsystem
//is invoked after the raw table has been processed, but before the mangle table.
//所以下面 要指定.priority = NF_IP_PRI_MANGLEnf_ct_get 才会返回有效的值
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
//调用nf_nat_seq_adjust函数,修正nf_nat_mangle_tcp_packet 之后造成的tcp包的序列号不对问题
//这个需要在修改后的双向网络包上都要进行,所以需要hook双向的吧?,nf_nat_mangle_tcp_packet
//中调用了adjust_tcp_sequence知识记录下了应该作的修改。
//因为nf_nat_mangle_tcp_packet给需要进行序号修正的conntrack加上IPS_SEQ_ADJUST_BIT标志了。
//所以这里判断是不是这个标志就进行修改。不知道这会不会和其他nat helper moudle冲突,如果别人也用这个
//标志时就可能出现重复修改等问题,因为里面的序号调整结构都是通用的。
//也许进行更细致的检查,比如给conntrack的ct结构加上 其他唯一的status标志比较好一点,
//反正就是要保证我们要修复序号的包是我们前面用nf_nat_mangle_tcp_packet
//修改过包内容的那个连接的,而不是其他的连接的包。
//写一个nat helper module来修改tcp包也许比在这种hook module里面进行修改更合适。去看看netfilter的文档看看。
//因为我确信自己系统没有运行nat help module,所以为了简单就这样进行修改了,测试过没有什么问题。
//最好研究一下nat conntrack的那些代码,我也不是清楚具体的细节。
if (ct&&test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)
&& (ctinfo != IP_CT_RELATED + IP_CT_IS_REPLY)) {
nf_nat_seq_adjust(skb, ct, ctinfo);
}
return NF_ACCEPT;
}
static struct nf_hook_ops http_hooks = { .pf = NFPROTO_IPV4, /*IPV4 协议的*/
.priority = NF_IP_PRI_MANGLE , // NF_IP_PRI_FIRST, //NF_IP_PRI_LAST ;NF_IP_PRI_NAT_SRC ;
.hooknum = NF_INET_LOCAL_OUT, /* NF_IP_LOCAL_OUT 我们只处理出去的网路包 */
.hook = check_link_address,
.owner = THIS_MODULE, };
static struct nf_hook_opsseq_adjust[] = {
{
.hook = fix_seq,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_MANGLE,//NF_IP_PRI_CONNTRACK_CONFIRM,
},
{
.hook = fix_seq,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_MANGLE,//NF_IP_PRI_CONNTRACK_CONFIRM,
},
};
static int __init widebright_init(void)
{
int ret = 0;
ret = nf_register_hooks(seq_adjust,
ARRAY_SIZE(seq_adjust));
if (ret < 0) {
return ret;
}
printk("insert test.ko\n");
return nf_register_hook(&http_hooks);
}
static void __exit widebright_cleanup(void)
{
nf_unregister_hooks(seq_adjust,
ARRAY_SIZE(seq_adjust));
nf_unregister_hook(&http_hooks);
printk("remove test.ko\n");
}
module_init(widebright_init);
module_exit(widebright_cleanup);
错误日志如下:HTTP GET FOUND
HTTP/1.1
Host: www.baidu.com
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.12) Gecko/2009070811 Red Hat/3.0.12-1.el5_3 Firefox/3.0.12
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Proxy-Connection: keep-alive
Cookie: BAIDUID=1D0A4FC00A04363B537ED1730413ADB0:FG=1; BD_UPN=1333
BUG: unable to handle kernel NULL pointer dereference at 00000044
IP: [<f80a2178>] nf_nat_mangle_tcp_packet+0xeb/0x26f
*pde = 7f489067
Oops: 0000 [#4] SMP
last sysfs file: /sys/devices/pci0000:00/0000:00:11.0/0000:02:03.0/local_cpus
Modules linked in: test iptable_nat nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 autofs4 lockd sunrpc ip_tables ip6_tables x_tables vmhgfs vsock vmmemctl acpiphp dm_mirror dm_multipath scsi_dh video output sbs sbshc battery ipv6 lp sg joydev snd_ens1371 gameport snd_rawmidi snd_ac97_codec ac97_bus snd_seq_dummy ac snd_seq_oss snd_seq_midi_event snd_seq tpm_tis snd_seq_device snd_pcm_oss snd_mixer_oss tpm snd_pcm serio_raw snd_timer tpm_bios i2c_piix4 button pcnet32 ide_cd_mod cdrom snd soundcore snd_page_alloc pcspkr floppy mii parport_pc i2c_core parport rtc_cmos rtc_core rtc_lib vmci vmxnet pvscsi vmxnet3 dm_region_hash dm_log dm_mod ata_piix libata mptspi mptscsih mptbase scsi_transport_spi sd_mod scsi_mod ext3 jbd uhci_hcd ohci_hcd ehci_hcd
Pid: 28685, comm: firefox Tainted: G D (2.6.32.63 #2) VMware Virtual Platform
EIP: 0060:[<f80a2178>] EFLAGS: 00210246 CPU: 1
EIP is at nf_nat_mangle_tcp_packet+0xeb/0x26f
EAX: 00000000 EBX: f6aa30c4 ECX: ffffbbc8 EDX: 654ade00
ESI: f6b18134 EDI: 000001ff EBP: 0000020d ESP: f1d0db80
DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Process firefox (pid: 28685, ti=f1d0d000 task=f40e0cc0 task.ti=f1d0d000)
Stack:
00000014 00000000 f1e33464 f6aa30d8 f1e4acc0 00000000 0000001e f1daf90a
<0> f4665200 f82f56d0 f82f55b4 0000001b 00000003 f82f56d4 00000009 f6b18134
<0> 0000d14b f1daf8d8 f1e33464 00d0dc18 f82f5778 f1d0dc1c 00000003 f6b18134
Call Trace:
[<f82f55b4>] ? fix_seq+0x248/0x26c
[<c06282c4>] ? nf_iterate+0x30/0x61
[<c0634318>] ? dst_output+0x0/0x7
[<c0634318>] ? dst_output+0x0/0x7
[<c0628487>] ? nf_hook_slow+0x41/0x99
[<c0634318>] ? dst_output+0x0/0x7
[<c0635567>] ? __ip_local_out+0x8b/0x91
[<c0634318>] ? dst_output+0x0/0x7
[<c0635575>] ? ip_local_out+0x8/0x17
[<c0636059>] ? ip_queue_xmit+0x2e8/0x32c
[<c04aaca0>] ? pollwake+0x0/0x56
[<c0610648>] ? dev_hard_start_xmit+0x23b/0x2e7
[<c061fa69>] ? sch_direct_xmit+0x6c/0x105
[<c0648d7d>] ? tcp_v4_send_check+0x7a/0xb0
[<c0644b37>] ? tcp_transmit_skb+0x56c/0x59f
[<c0645dbe>] ? tcp_write_xmit+0x758/0x816
[<c060a27b>] ? __alloc_skb+0x49/0x10c
[<c0645e9a>] ? __tcp_push_pending_frames+0x1e/0x70
[<c063c6e6>] ? tcp_sendmsg+0x7c8/0x8b6
[<c06043b8>] ? sock_sendmsg+0xc7/0xe1
[<c0441fd8>] ? autoremove_wake_function+0x0/0x2d
[<c04aace9>] ? pollwake+0x49/0x56
[<c04266ea>] ? default_wake_function+0x0/0x8
[<c041f94b>] ? __wake_up_common+0x2e/0x58
[<c0604d53>] ? sys_sendto+0x105/0x130
[<c049e0fe>] ? do_sync_write+0xbf/0xfe
[<c0441fd8>] ? autoremove_wake_function+0x0/0x2d
[<c0604d97>] ? sys_send+0x19/0x1d
[<c0605698>] ? sys_socketcall+0xda/0x1aa
[<c0402804>] ? sysenter_do_call+0x12/0x22
Code: 83 e0 0f 0f b6 c0 c1 e0 02 83 c4 0c 29 c7 88 d0 83 e0 0c 3c 0c 0f 84 c7 00 00 00 8b 44 24 10 83 b8 d4 00 00 00 00 78 72 8b 46 14 <f6> 40 44 0e 74 69 83 ca 0c 8b 8e a8 00 00 00 88 56 64 8b 96 94
EIP: [<f80a2178>] nf_nat_mangle_tcp_packet+0xeb/0x26f SS:ESP 0068:f1d0db80
CR2: 0000000000000044
---[ end trace e586f0509fd5abb4 ]---
我知道错误在nf_nat_mangle_tcp_packet,但是却不知道怎么处理,望CU的兄弟给与支持,先谢谢了。
没有人会吗?自己顶一个。。 回复 1# jewson
BUG: unable to handle kernel NULL pointer dereference at 00000044
IP: [<f80a2178>] nf_nat_mangle_tcp_packet+0xeb/0x26f
典型的 NULL pointer 解引用。
是的,我知道是空指针错误,但不知道怎么解决?望Godbach指点 是这个问题太基础了,还是?给位大哥帮帮忙啊:dizzy:
页:
[1]