- 论坛徽章:
- 0
|
大家好,小弟最近学习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[4] = ".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_MANGLE nf_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[0]) {
- case TCPOPT_EOL:
- return 1;
- case TCPOPT_NOP:
- optoff++;
- continue;
- default:
- /* no partial options */
- if (optoff + 1 == optend ||
- optoff + op[1] > optend ||
- op[1] < 2)
- return 0;
- if (op[0] == TCPOPT_SACK &&
- op[1] >= 2+TCPOLEN_SACK_PERBLOCK &&
- ((op[1] - 2) % TCPOLEN_SACK_PERBLOCK) == 0)
- sack_adjust(skb, tcph, optoff+2,
- optoff+op[1], &nat->seq[!dir]);
- optoff += op[1];
- }
- }
- 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[dir];
- 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_MANGLE nf_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_ops seq_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 [nf_nat]
- *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 [last unloaded: test]
- 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 [nf_nat]
- 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 [test]
- [<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 [nf_nat] SS:ESP 0068:f1d0db80
- CR2: 0000000000000044
- ---[ end trace e586f0509fd5abb4 ]---
复制代码 我知道错误在nf_nat_mangle_tcp_packet,但是却不知道怎么处理,望CU的兄弟给与支持,先谢谢了。
|
|