用netfilter_queue在用户态实现NAT

合集下载

netfilter queue例子

netfilter queue例子

一、概述netfilter是Linux内核提供的一个功能强大的网络数据包过滤框架,它可以让用户对网络数据包进行分析和过滤。

netfilter queue是netfilter框架中的一个重要组件,可以让用户将数据包放入队列中,进行进一步处理。

本文将通过介绍netfilter queue的基本概念、工作原理和实际例子,帮助读者更好地理解和应用netfilter queue。

二、netfilter queue的基本概念netfilter queue是一个允许用户空间程序对数据包进行处理的接口。

当数据包经过netfilter时,可以选择将数据包放入netfilter queue中,然后用户空间程序可以从队列中取出数据包进行处理。

这种机制使得用户可以编写自定义的程序来处理数据包,实现更加灵活和个性化的数据包过滤和处理。

三、netfilter queue的工作原理1. 数据包经过netfilter当数据包经过netfilter时,netfilter会根据预先定义的规则对数据包进行处理,包括检查、修改以及丢弃等操作。

2. 数据包放入netfilter queue如果数据包符合某些条件,用户可以选择将数据包放入netfilterqueue中,而不是直接进行后续的处理。

3. 用户空间程序处理数据包用户空间程序可以通过netlink接口来监听netfilter queue,一旦有数据包进入队列,用户空间程序即可获取数据包并进行处理,可以根据自身需求来对数据包进行分析、修改以及决定是否将数据包继续投递给网络协议栈。

四、netfilter queue的实际例子为了更好地理解netfilter queue的使用,接下来通过一个实际例子来说明。

假设我们需要在Linux系统上对传入的数据包进行监控,并统计其中包含特定关键词的数据包数量,可以通过netfilter queue来实现此需求。

1. 编写用户空间程序我们需要编写一个用户空间程序,用来监听netfilter queue,并对接收到的数据包进行分析。

netfilter 连接追踪 原理

netfilter 连接追踪 原理

netfilter 连接追踪原理Netfilter是Linux内核的一个关键组件,主要用于网络数据包的过滤与处理。

它可以在内核层面对数据包进行处理,从而提供网络安全,网络流量控制,网络地址转换等多种服务。

其中netfilter连接跟踪是一个极为重要的组件,本文将深入探讨其原理。

一、什么是netfilter连接跟踪Netfilter连接跟踪是netfilter的一个模块,主要目的是在内核层面跟踪网络连接,记录连接状态,保存连接信息。

当网络数据包通过网卡接口进入内核时,netfilter连接跟踪模块会首先检查数据包,然后将其与已存在的连接进行匹配,最终决策是否要转发或丢弃数据包。

Netfilter连接跟踪模块是实现状态ful firewall的关键组件,与stateless firewall相比,它可以更为精确地识别数据包的状态,实现更为复杂的防火墙策略与NAT 转换等。

二、netfilter连接跟踪的原理1. 连接跟踪状态表netfilter连接跟踪通过状态表记录已有的连接信息。

状态表是一个内存结构,保存了所有已建立的连接信息,其中包括源地址,目标地址,源端口,目标端口等元数据信息。

当一个新的数据包到达时,它必须与状态表中的连接信息进行匹配,从而确定它是否属于已经存在的连接。

状态表是由多个hash桶组成的,每个桶都维护了一个连接列表。

在新接收到一个数据包时,netfilter连接跟踪首先使用四元组(源IP,源端口,目标IP,目标端口)查询状态表中已有的连接,并将数据包分配给匹配到的连接。

2. 数据包流转当一个数据包通过网卡接口进入内核时,内核会先将其送到协议栈的网络层。

在网络层中,数据包会进行路由选择并将目标地址与本地地址进行比较,从而决定是否将数据包直接传递到目标主机内。

在进行路由选择时,可能会进行NAT转换。

如果数据包的目标地址不是本地地址,那么它将被发送到下一跳路由器。

在这个过程中,数据包可能会通过多个路由器进行传递,每个路由器会再次检查数据包的目标地址并进行路由选择。

linux nat实现方式

linux nat实现方式

linux nat实现方式在Linux系统中,Network Address Translation(网络地址转换)是一种常用的网络技术,它允许将内部网络中的私有IP地址与外部网络中的公有IP地址进行映射。

通过NAT,内部网络中的主机可以与外部网络进行通信,而外部网络无法直接访问内部网络中的主机。

实现NAT的方式有多种,其中一种常见的方式是使用iptables命令。

iptables是Linux系统中的一个工具集,用于配置Linux内核的网络层防火墙规则。

要实现NAT,首先需要配置iptables的转发规则。

可以通过以下命令来配置转发规则:```iptables -t nat -A POSTROUTING -o 外部网络接口 -j MASQUERADE```其中,外部网络接口指的是连接到外部网络的网络接口,例如eth0。

这条规则的作用是将从内部网络发出的数据包的源IP地址替换为外部网络接口的IP地址,从而实现地址转换。

除了配置转发规则,还需要配置iptables的过滤规则,以允许内部网络中的主机与外部网络进行通信。

可以使用以下命令来配置过滤规则:```iptables -A FORWARD -i 内部网络接口 -o 外部网络接口 -j ACCEPT iptables -A FORWARD -i 外部网络接口-o 内部网络接口-m state --state RELATED,ESTABLISHED -j ACCEPT```其中,内部网络接口指的是连接到内部网络的网络接口,例如eth1。

第一条规则的作用是允许从内部网络到外部网络的数据包通过,第二条规则的作用是允许从外部网络到内部网络的已建立或相关的数据包通过。

在配置完iptables规则后,还需要开启IP转发功能,以使Linux系统能够实现NAT。

可以通过修改/sys文件系统中的配置文件来开启IP转发功能:```echo 1 > /proc/sys/net/ipv4/ip_forward```这样,就完成了Linux系统中NAT的实现。

Linux命令高级技巧使用iptables进行端口转发和NAT

Linux命令高级技巧使用iptables进行端口转发和NAT

Linux命令高级技巧使用iptables进行端口转发和NAT在Linux系统中,iptables是一个非常强大的工具,用于配置和管理网络包过滤规则。

除了基本的网络包过滤功能,iptables还可以用于端口转发和网络地址转换(NAT)。

本文将介绍如何使用iptables进行端口转发和NAT,以及一些高级技巧。

1. 端口转发端口转发是一种将网络流量从一个端口转发到另一个端口的技术。

它在网络中广泛应用于代理服务器、端口映射、负载均衡等场景。

下面是使用iptables进行端口转发的示例命令:```iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.0.100:80```在上述命令中,`-t nat`表示我们要操作的是`nat`表,`-A PREROUTING`表示将规则添加到`PREROUTING`链中,`-p tcp --dport 8080`表示匹配TCP协议和目标端口号8080,`-j DNAT`表示采取目标网络地址转换,`--to-destination 192.168.0.100:80`表示将数据包转发到目标IP地址192.168.0.100的80端口。

2. 网络地址转换(NAT)网络地址转换(NAT)是一种将私有网络中的IP地址转换为公共网络中的IP地址的技术。

它广泛应用于家庭网络和企业网络中,允许多台设备共享一个公共IP地址。

下面是使用iptables进行NAT的示例命令:```iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE```在上述命令中,`-t nat`表示我们要操作的是`nat`表,`-A POSTROUTING`表示将规则添加到`POSTROUTING`链中,`-s192.168.0.0/24`表示源IP地址为192.168.0.0/24的网络,`-o eth0`表示出去的网络接口为eth0,`-j MASQUERADE`表示使用动态地址转换。

防火墙软件Netfilter之NAT技术

防火墙软件Netfilter之NAT技术

防火墙软件Netfilter之NAT技术ZDNet 网络频道频道更新时间:2008-06-10 作者:来源:路由器技术资讯网本文关键词:NAT网络地址转换什么是nat本文档主要描述怎样进行IP伪装(masquerading)、透明代理(transparent proxying)、端口转发(port forwarding)和其他形式的网络地址翻译技术。

1.什么是网络地址翻译NAT(Network Address Translation)?当一个包在网络上传输时,从它的源地址(例如你自己的主机)到达目的地址(例如),中间经过很多节点和网络。

这些节点通常不会改变你的包。

他们仅仅转发你的包。

如果一个节点执行NAT,他将会修改包的源或目的地址。

通常这个节点会记住他怎样修改了这个包,因此当相应的应答包从另一个方向到达时,他知道如何反向修改这个应答包。

2.为什么要使用NAT?l 用modem上网大多数的ISPs只给你提供一个IP地址。

你可以以任何源地址发出包,但是只有包含这个IP地址的包的应答包才会到达你的网络。

如果你想使用多台机器(比如有个自己的网络)利用这个IP地址上网。

需要NAT。

这是NAT使用得最为常见的情况,在linux的世界里称为IP伪装(masquerading)。

又称之为SNAT,因为你要改变包的源地址。

l Multiple Servers有时候你想改变到达你的网络的包的去向。

通常因为你只有一个IP地址,但是你又想用户到达这个真实IP地址之后的各个机器。

方法是修改这些包的目的地址,让他们到达不同的机器。

还有就是用于负载均衡。

这种类型的NAT在linux上叫做端口转发(port-forwarding)。

l Transparent Proxying(透明代理)透明代理是在你的网络和外部世界之间的程序,所有的进或出都要经过这个代理。

之所以叫做“透明”,因为你的网络无需考虑他的存在。

例如,squid软件能够配置为透明代理。

思科路由器如何配置NAT功能

思科路由器如何配置NAT功能

思科路由器如何配置NAT功能很多网络技术上的新手,还不知道如何配置思科路由器的NAT功能。

不过没关系,看完小编这个文章应该对你帮助会很大。

那么接下来就让小编来教你如何配置思科路由器NAT功能吧。

首先,小编必须要介绍下什么是NAT。

NAT,英文全称为Network Address Translation,是指网络IP 地址转换。

NAT的出现是为了解决IP日益短缺的问题,将多个内部地址映射为少数几个甚至一个公网地址。

这样,就可以让我们内部网中的计算机通过伪IP访问INTERNET的资源。

如我们局域网中的192.168.1.1地址段属私网地址,就是通过NAT转换过来的。

NAT分为静态地址转换、动态地址转换、复用动态地址转换。

下面是小编将列出思科路由器NAT配置实例,希望对您有所帮助。

Current configuration:!version 12.0service timestamps debug uptimeservice timestamps log uptimeno service password-encryption!hostname 2611!enable secret 5 $JIeG$UZJNjKhcptJXHPc/BP5GG0enable password 2323ipro!ip subnet-zerono ip source-routeno ip finger!!!interface Ethernet0/0ip address 192.168.10.254 255.255.255.0 secondary ip address 218.27.84.249 255.255.255.248no ip directed-broadcastip accounting output-packetsno ip mroute-cacheno cdp enable!interface Serial0/0ip unnumbered Ethernet0/0no ip directed-broadcastip accounting output-packetsip nat outsideno ip mroute-cacheno fair-queueno cdp enable!interface Ethernet0/1ip address 192.168.2.254 255.255.255.0no ip directed-broadcastip nat insideno ip mroute-cacheno cdp enable!interface Virtual-T okenRing35no ip addressno ip directed-broadcastno ip mroute-cacheshutdownring-speed 16!router ripredistribute connectednetwork 192.168.2.0network 192.168.10.0network 218.27.84.0!ip default-gateway 218.27.127.217ip nat pool nat-pool 218.27.84.252 218.27.84.254 netmask 255.255.255.248ip nat inside source list 1 pool nat-pool overloadip nat inside source static 192.168.2.254 218.27.84.249ip classlessip route 0.0.0.0 0.0.0.0 Serial0/0ip http serverip http port 9091ip ospf name-lookup!ip access-list extended filterinpermit tcp any host 218.27.84.249 eq www reflect httpfilter access-list 1 permit 192.168.2.0 0.0.0.255no cdp run!line con 0transport input noneline aux 0line vty 0 4password routrlogin!end按照步骤敲完这些代码,那么你应该就会了解到如何配置思科路由器NAT功能了。

思科交换机NAT配置介绍及实例

思科交换机NAT配置介绍及实例

思科交换机NAT配置介绍及实例CISCONAT 配置一、NAT简介NAT(Network Address Translation)的功能,就是指在一个网络内部,根据需要可以随意自定义的IP地址,而不需要经过申请。

在网络内部,各计算机间通过内部的IP地址进行通讯。

而当内部的计算机要与外部internet网络进行通讯时,具有NAT功能的设备(比如:路由器)负责将其内部的IP地址转换为合法的IP地址(即经过申请的IP地址)进行通信。

二、NAT的应用环境:情况1:一个企业不想让外部网络用户知道自己的网络内部结构,可以通过NAT将内部网络与外部Internet隔离开,则外部用户根本不知道通过NAT设置的内部IP地址。

情况2:一个企业申请的合法Internet IP地址很少,而内部网络用户很多。

可以通过NAT功能实现多个用户同时公用一个合法IP与外部Internet进行通信。

三、设置NAT所需路由器的硬件配置和软件配置:设置NAT功能的路由器至少要有一个内部端口(Inside),—个外部端口(Outside)。

内部端口连接的网络用户使用的是内部IP地址。

内部端口可以为任意一个路由器端口。

外部端口连接的是外部的网络,如Internet。

外部端口可以为路由器上的任意端口。

设置NAT功能的路由器的IOS应支持NAT功能(本文事例所用路由器为C isco2501,其IOS为11.2版本以上支持NAT功能)。

四、关于NAT的几个概念:内部本地地址(Inside local address ):分配给内部网络中的计算机的内部IP地址。

内部合法地址(Inside global address):对外进入IP通信时,代表一个或多个内部本地地址的合法IP地址。

需要申请才可取得的IP地址。

五、NAT的设置方法:NAT设置可以分为静态地址转换、动态地址转换、复用动态地址转换。

1、静态地址转换适用的环境静态地址转换将内部本地地址与内部合法地址进行一对一的转换,且需要指定和哪个合法地址进行转换。

用netfilter_queue在用户态实现NAT

用netfilter_queue在用户态实现NAT

用netfilter_queue在用户态实现NAT偶尔在网上看到了<<用netfilter_queue 在用户态修改网络数据包的例子程序>>这篇文章,并结合libnetfilter_queue-0.0.17.tar.bz2中的例子,然后修改了一下tcp计算checksum部分,在linux2.6.24上用netfilter_queue在用户态实现NAT程序功能: 将输出端目的地为 220.181.37.55 的包,都改为目的地为 202.118.236.130,输入段反之,达到DNAT的一小半功能,完整的NAT要做状态记录的.直接上代码:nf_queue_test.c/** =====================================================================================** Filename: nf_queue_test.c** Description: 用netfilter_queue 在用户态修改网络数据包的例子程序** Version: 1.0* Created: 04/02/2010 09:49:48 AM* Revision: none* Compiler: gcc** Author: LeiuX (xulei), xulei@* Company: HIT** =====================================================================================*/#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<netdb.h>#include<string.h>#include<netinet/in.h>#include<arpa/inet.h>#include<asm/byteorder.h>#include<linux/netfilter.h>#include<libnetfilter_queue/libnetfilter_queue.h>#include<linux/ip.h>#include<linux/tcp.h>#ifdef__LITTLE_ENDIAN#define IPQUAD(addr)\((unsigned char*)&addr)[0],\((unsigned char*)&addr)[1],\((unsigned char*)&addr)[2],\((unsigned char*)&addr)[3]#else#define IPQUAD(addr)\((unsigned char*)&addr)[3],\((unsigned char*)&addr)[2],\((unsigned char*)&addr)[1],\((unsigned char*)&addr)[0]#endifstruct tcp_pseudo /*the tcp pseudo header*/{__u32 src_addr;__u32 dst_addr;__u8 zero;__u8 proto;__u16 length;}pseudohead;long checksum(unsigned short*addr,unsigned int count){/* Compute Internet Checksum for "count" bytes* beginning at location "addr".*/register long sum =0;while(count> 1 ){/* This is the inner loop */sum +=*addr++;count-=2;}/* Add left-over byte, if any */if(count>0 )sum +=*(unsigned char*)addr;/* Fold 32-bit sum to 16 bits */while(sum>>16)sum =(sum &0xffff)+(sum >>16);return~sum;}/*************************tcp checksum**********************/long get_tcp_checksum(struct iphdr *myip,struct tcphdr *mytcp){__u16 total_len =ntohs(myip->tot_len);int tcpopt_len =mytcp->doff*4 -20;int tcpdatalen =total_len -(mytcp->doff*4)-(myip->ihl*4);pseudohead.src_addr=myip->saddr;pseudohead.dst_addr=myip->daddr;pseudohead.zero=0;pseudohead.proto=IPPROTO_TCP;pseudohead.length=htons(sizeof(struct tcphdr)+tcpopt_len +tcpdatalen);int totaltcp_len =sizeof(struct tcp_pseudo)+sizeof(struct tcphdr)+tcpopt_len +tcpdatalen;//unsigned short * tcp = new unsigned short[totaltcp_len];unsigned short*tcp =malloc(totaltcp_len);memcpy((unsigned char*)tcp,&pseudohead,sizeof(struct tcp_pseudo));memcpy((unsigned char*)tcp+sizeof(struct tcp_pseudo),(unsigned char*)mytcp,sizeof(struct tcphdr));memcpy((unsigned char*)tcp+sizeof(struct tcp_pseudo)+sizeof(struct tcphdr),(unsigned char*)myip+ (myip->ihl*4)+(sizeof(struct tcphdr)),tcpopt_len);memcpy((unsigned char*)tcp+sizeof(struct tcp_pseudo)+sizeof(struct tcphdr)+tcpopt_len,(unsigned ch ar*)mytcp+(mytcp->doff*4),tcpdatalen);/* printf("pseud length: %d\n",pseudohead.length);printf("tcp hdr length: %d\n",mytcp->doff*4);printf("tcp hdr struct length: %d\n",sizeof(struct tcphdr));printf("tcp opt length: %d\n",tcpopt_len);printf("tcp total+psuedo length: %d\n",totaltcp_len);fflush(stdout);printf("tcp data len: %d, data start %u\n", tcpdatalen,mytcp + (mytcp->doff*4));*/return checksum(tcp,totaltcp_len);static u_int16_t tcp_checksum(struct iphdr*iphdrp){struct tcphdr *tcphdrp =(struct tcphdr*)((u_int8_t*)iphdrp +(iphdrp->ihl<<2));return get_tcp_checksum(iphdrp,tcphdrp);}static void set_tcp_checksum(struct iphdr*iphdrp){struct tcphdr *tcphdrp =(struct tcphdr*)((u_int8_t*)iphdrp +(iphdrp->ihl<<2));tcphdrp->check =0;tcphdrp->check =get_tcp_checksum(iphdrp,tcphdrp);}/****************************tcp checksum end****************************//********************************Ip checksum*****************************/ static u_int16_t ip_checksum(struct iphdr*iphdrp){return checksum((unsigned short*)iphdrp,iphdrp->ihl<<2);}static void set_ip_checksum(struct iphdr*iphdrp){iphdrp->check =0;iphdrp->check =checksum((unsigned short*)iphdrp,iphdrp->ihl<<2); }/****************************Ip checksum end******************************/static int cb(struct nfq_q_handle *qh,struct nfgenmsg *nfmsg, struct nfq_data *nfa,void*data){(void)nfmsg;(void)data;u_int32_t id =0;struct nfqnl_msg_packet_hdr *ph;unsigned char*pdata =NULL;int pdata_len;ph =nfq_get_msg_packet_hdr(nfa);if(ph){id =ntohl(ph->packet_id);}pdata_len =nfq_get_payload(nfa,(char**)&pdata);if(pdata_len ==-1){pdata_len =0;}struct iphdr *iphdrp =(struct iphdr *)pdata;printf("len %d iphdr %d %u.%u.%u.%u ->",pdata_len,iphdrp->ihl<<2,IPQUAD(iphdrp->saddr));printf(" %u.%u.%u.%u %s",IPQUAD(iphdrp->daddr),getprotobynumber(iphdrp->protocol)->p_name);printf(" ipsum %hu",ip_checksum(iphdrp));if(iphdrp->protocol ==IPPROTO_TCP){printf(" tcpsum %hu",tcp_checksum(iphdrp));}#define TO "220.181.37.55"#define DNAT_TO "202.118.236.130"if(iphdrp->daddr ==inet_addr(TO)){printf(" !hacked!");iphdrp->daddr =inet_addr(DNAT_TO);set_ip_checksum(iphdrp);if(iphdrp->protocol ==IPPROTO_TCP){set_tcp_checksum(iphdrp);printf(" ipsum+ %hu tcpsum+ %hu",ip_checksum(iphdrp),tcp_checksum(iphdrp));}}if(iphdrp->saddr ==inet_addr(DNAT_TO)){iphdrp->saddr =inet_addr(TO);printf(" !hacked!");set_ip_checksum(iphdrp);if(iphdrp->protocol ==IPPROTO_TCP){set_tcp_checksum(iphdrp);printf(" ipsum+ %hu tcpsum+ %hu",ip_checksum(iphdrp),tcp_checksum(iphdrp));}}printf("\n");return nfq_set_verdict_mark(qh,id,NF_REPEAT,1,(u_int32_t)pdata_len,pdata);}int main(int argc,char**argv){struct nfq_handle *h;struct nfq_q_handle *qh;struct nfnl_handle *nh;int fd;int rv;char buf[4096];h =nfq_open();if(!h){exit(1);}nfq_unbind_pf(h,AF_INET);/*2.6.24 的内核有BUG, nfq_unbind_pf 返回值不正确,见:/gmane.c ... ilter.general/33573*//*if (nfq_unbind_pf(h, AF_INET) < 0){exit(1);}*/if(nfq_bind_pf(h,AF_INET)<0){exit(1);}int qid =0;if(argc ==2){qid =atoi(argv[1]);}printf("binding this socket to queue %d\n",qid);qh =nfq_create_queue(h,qid,&cb,NULL);if(!qh){exit(1);}if(nfq_set_mode(qh,NFQNL_COPY_PACKET,0xffff)<0){load.sh#!/bin/bash#=============================================================================== ##FILE:load.sh##USAGE:./load.sh##DESCRIPTION:##OPTIONS:---#REQUIREMENTS:---#BUGS:---#NOTES:---#AUTHOR:LeiuX (),marksman.xu@#COMPANY:HIT#VERSION:1.0#CREATED:04/02/2010 09:51:36 AM CST#REVISION:---#=============================================================================== #!/bin/shTABLE=manglefunction remove_chain(){echo -n removing chain...{sudo /sbin/iptables -t ${TABLE}-D PREROUTING -j NF_QUEUE_CHAINsudo /sbin/iptables -t ${TABLE}-D OUTPUT -j NF_QUEUE_CHAINsudo /sbin/iptables -t ${TABLE}-F NF_QUEUE_CHAINsudo /sbin/iptables -t ${TABLE}-X NF_QUEUE_CHAIN}&>/dev/nullecho done}function create_chain(){echo -n creating chain...sudo /sbin/iptables -t ${TABLE}-N NF_QUEUE_CHAIN运行loader.sh就好了,如果你没有sudo,那就改改脚本自己用root运行吧要看效果,就ping 220.181.37.55,然后连 220.181.37.55 的80端口试试,并且注意程序的输出. PS: 220.181.37.55 是 baidu 的一个服务器的IP, 另外一个IP是 pact lab 的.reference:<<用netfilter_queue 在用户态修改网络数据包的例子程序>>libnetfilter_queue-0.0.17.tar.bz2tcp计算checksum<<tcp/ip详解卷一:协议>>/woods2001/article/details/8373628。

netfilter编程

netfilter编程

netfilter编程Netfilter 是Linux 内核中的一个框架,用于实现包过滤和网络地址转换(NAT)等功能。

Netfilter 提供了一种在内核空间中拦截、修改和处理网络数据包的机制。

你可以通过使用Netfilter 提供的API 进行编程,实现自定义的网络包处理逻辑。

以下是一个简单的基于Netfilter 的例子,使用C 语言编写:1. 编写Netfilter 模块:```c#include <linux/kernel.h>#include <linux/module.h>#include <linux/netfilter.h>#include <linux/netfilter_ipv4.h>#include <linux/ip.h>static struct nf_hook_ops nfho;// Netfilter 处理函数static unsigned int my_hook_function(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) {struct iphdr *ip_header;// 获取IP 头ip_header = ip_hdr(skb);// 在此处添加你的自定义逻辑,例如修改IP 地址、丢弃包等// 打印原始IP 地址pr_info("Original Source IP: %pI4\n", &ip_header->saddr);return NF_ACCEPT; // 允许数据包通过}// 模块初始化函数static int __init my_netfilter_init(void) {pr_info("My Netfilter Module Loaded\n");// 初始化Netfilter 钩子nfho.hook = my_hook_function;nfho.pf = PF_INET;nfho.hooknum = NF_INET_PRE_ROUTING;nfho.priority = NF_IP_PRI_FIRST;nf_register_hook(&nfho);return 0;}// 模块退出函数static void __exit my_netfilter_exit(void) {pr_info("My Netfilter Module Unloaded\n");// 注销Netfilter 钩子nf_unregister_hook(&nfho);}module_init(my_netfilter_init);module_exit(my_netfilter_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("Your Name");MODULE_DESCRIPTION("Netfilter Module");```在这个例子中,我们创建了一个简单的Netfilter 模块,它注册了一个钩子函数`my_hook_function`,用于处理IPv4 数据包。

netfilter与用户空间通信二法

netfilter与用户空间通信二法

Linux内核态与用户态进程通信方法的提出与实现。

分为用户上下文环境、硬中断和软中断环境两种情况。

3.1 用户上下文环境运行在用户上下文环境中的代码是可以阻塞的,这样,便可以使用消息队列和UNIX 域套接字来实现内核态与用户态的通信。

但这些方法的数据传输效率较低,Linux 内核提供copy_from_user()/copy_to_user() 函数来实现内核态与用户态数据的拷贝,但这两个函数会引发阻塞,所以不能用在硬、软中断中。

一般将这两个特殊拷贝函数用在类似于系统调用一类的函数中,此类函数在使用中往往"穿梭"于内核态与用户态。

3.2 硬、软中断环境比起用户上下文环境,硬中断和软中断环境与用户态进程无丝毫关系,而且运行过程不能阻塞。

在Linux 2.4 版以后版本的内核中,几乎全部的中断过程与用户态进程的通信都是使用netlink 套接字实现的,netlink 套接字的最大特点是对中断过程的支持,同时还使用netlink 实现了ip queue 工具,但ip queue 的使用有其局限性,不能自由地用于各种中断过程。

还有重要的一点:netlink 套接字是不用经过TCP/IP协议栈处理的,效率方面没的说。

赞。

说了这么多,都是别人的东西。

但是磨刀不误砍柴工,没有前面的知识铺垫,只怕你对怎么样,为什么这样用也是一知半解,这可是工程技术人员的大忌。

4 netfilter与用户空间通信二法法1:nf_sockopt_ops通信方式此法在内核模块中注册nf_register_sockopt一个 nf_sockopt_ops结构体。

比如view plaincopy to clipboardprint?.........10........20........30........40........50........60........70........80........90........100.......110.......120.......130.......140. (150)1.static struct nf_sockopt_ops nso = {2. .pf = PF_INET, // 协议族3. .set_optmin = 常数, // 定义最小set命令字4. .set_optmax = 常数+N, // 定义最大set命令字5. .set = do_nso_set, // 定义set处理函数6. .get_optmin = 常数, // 定义最小get命令字7. .get_optmax = 常数+N, // 定义最大get命令字8. .get = do_nso_get, // 定义set处理函数9.};其中命令字不能和内核已有的重复,宜大不宜小。

netfilter链接跟踪机制与NAT原理

netfilter链接跟踪机制与NAT原理

netfilter链接跟踪机制与NAT原理内核版本:2.6.121.链接跟踪 conntrackfilter框架5个链:NF_IP_PRE_ROUTING:数据包进⼊路由表之前NF_IP_LOCAL_IN:通过路由表后⽬的地为本机NF_IP_FORWARD:通过路由表后,⽬的地不为本机NF_IP+LOCAL_OUT:由本机产⽣,向外转发NF_IP_POST_ROUTING:发送到⽹卡接⼝之前。

4个表:filter,nat,mangle,raw,默认表是filter(没有指定表的时候就是filter表)。

filter:⼀般的过滤功能nat: ⽤于nat功能(端⼝映射,地址映射等)mangle: ⽤于对特定数据包的修改raw:优先级最⾼,设置raw时⼀般是为了不再让iptables做数据包的链接跟踪处理,提⾼性能表和链的关系:(raw连接跟踪在下⾯单独说明)数据包流程: 当数据包到达防⽕墙时,如果MAC地址符合,就会由内核⾥相应的驱动程序接收,然后会经过⼀系列操作,从⽽决定是发送给本地的程序,还是转发给其他机⼦,还是其他的什么。

⾸先来看⼀个以本地为⽬的的数据包,它要经过以下步骤才能到达要接收它的程序:Step Table Chain Comment1在线路上传输(⽐如,Internet)2进⼊接⼝ (⽐如, eth0)3mangle PREROUTING这个链⽤来mangle数据包,⽐如改变TOS等4nat PREROUTING这个链主要⽤来做DNAT。

不要在这个链做过虑操作,因为某些情况下包会溜过去。

5路由判断,⽐如,包是发往本地的,还是要转发的。

6mangle INPUT在路由之后,被送往本地程序之前,mangle数据包。

7filter INPUT所有以本地为⽬的的包都要经过这个链,不管它们从哪⼉来,对这些包的过滤条件就设在这⾥。

8到达本地程序了(⽐如,服务程序或客户程序)接着看看以以本地为源的数据包,它需要经过下⾯的步骤才能发送出去:Step Table Chain Comment1本地程序(⽐如,服务程序或客户程序)2路由判断,要使⽤源地址,外出接⼝,还有其他⼀些信息。

NAT的3种实现方式配置示范

NAT的3种实现方式配置示范

NAT的3种实现方式配置示范网络地址转换(NAT)是一种网络协议,用于将私有IP地址转换为公共IP地址,以实现多台设备共享一个公共IP地址的功能。

NAT有三种实现方式:静态NAT、动态NAT和PAT(端口地址转换)。

1.静态NAT静态NAT是将一个私有IP地址映射到一个公共IP地址,实现一对一的映射关系。

静态NAT适用于需要固定映射关系的情况,如将内部服务器映射到公共IP地址,以便外部用户可以访问该服务器。

示范配置:1.配置内部接口的IP地址和子网掩码。

2.配置外部接口的IP地址和子网掩码,该接口将使用公共IP地址。

3.创建一个静态NAT转换规则,将内部服务器的IP地址映射到外部接口的公共IP地址。

例如,假设内部服务器的IP地址为192.168.1.10,外部接口的公共IP地址为203.0.113.10,配置如下:```interface fastethernet0/0ip address 192.168.1.1 255.255.255.0interface fastethernet0/1ip address 203.0.113.1 255.255.255.0ip nat inside source static 192.168.1.10 203.0.113.10```2.动态NAT动态NAT是将内部设备的私有IP地址动态映射到可用的公共IP地址,实现一对多的映射关系。

动态NAT适用于多个内部设备共享有限的公共IP地址的情况。

示范配置:1.配置内部接口的IP地址和子网掩码。

2.配置外部接口的IP地址和子网掩码,该接口将使用公共IP地址。

3.配置一个动态NAT池,指定可用的公共IP地址范围。

4.创建一个动态NAT转换规则,将内部设备的IP地址映射到动态NAT池中的公共IP地址。

例如,假设内部子网的IP地址范围为192.168.1.0/24,外部接口的公共IP地址为203.0.113.1,配置如下:```interface fastethernet0/0ip address 192.168.1.1 255.255.255.0interface fastethernet0/1ip address 203.0.113.1 255.255.255.0ip nat pool dynamic-nat-pool 203.0.113.10 203.0.113.20 netmask 255.255.255.0ip nat inside source list 1 pool dynamic-nat-pool overload access-list 1 permit 192.168.1.0 0.0.0.255```3.PAT(端口地址转换)PAT是一种特殊的动态NAT方法,它除了将内部设备的IP地址映射到公共IP地址外,还使用端口号来区分不同的连接。

linux libnetfilter_queue 数据转发的原理

linux libnetfilter_queue 数据转发的原理

linux libnetfilter_queue 数据转发的原理
libnetfilter_queue是Linux系统中一种使用用户空间处理网络
包的工具库。

它允许用户空间接收Linux内核中iptables规则
匹配到的网络数据包,并允许进行修改、丢弃或重新放行。

数据转发的原理如下:
1. 首先,用户程序使用libnetfilter_queue库创建一个netfilter
队列,并告诉Linux内核将匹配到的数据包发送到这个队列中。

2. 当有数据包匹配到iptables规则时,内核将数据包发送到创
建的netfilter队列中,由用户程序接收。

3. 用户程序收到数据包后,可以选择修改数据包的内容,如修改源IP地址、目标IP地址、端口等。

4. 用户程序可以根据自定义的逻辑进行判断,决定是否丢弃该数据包、修改后放行,或重新改写数据包后放行。

5. 最后,用户程序将修改后的数据包放行(通过)。

此时,内核将根据用户程序的操作决定是否将数据包继续传递给下一个规则进行匹配与处理。

值得注意的是,libnetfilter_queue只能在用户空间进行处理,
不能直接修改内核中的iptables规则。

因此,用户程序需要在iptables规则中将数据包发送到libnetfilter_queue中,然后在用
户程序中进行处理。

这样,用户程序可以根据自己的需求对数据包进行处理,而不受内核规则的限制。

netfilter 案例

netfilter 案例

netfilter 案例一、背景介绍netfilter是Linux内核中的一个框架,用于实现数据包过滤和修改。

它提供了iptables命令行工具和用户空间库,可以通过定义规则来过滤和修改数据包。

在Linux系统中,netfilter是非常重要的一个组件,它可以用于防火墙、网络地址转换(NAT)、负载均衡等多种网络应用。

二、案例描述某公司内部网络需要设置防火墙来保护公司的机密信息不被外部攻击者获取。

为此,该公司决定使用netfilter来实现防火墙功能。

下面是该公司使用netfilter实现防火墙的具体步骤:1. 安装iptables命令行工具和用户空间库在Linux系统中安装iptables命令行工具和用户空间库非常简单,在终端中输入以下命令即可:```sudo apt-get install iptables```2. 编写iptables规则该公司需要实现以下几个功能:- 允许内网主机访问外网;- 禁止外部主机访问内网;- 允许特定IP地址访问内网某些服务;- 禁止所有IP地址访问内网某些服务。

根据上述需求,该公司编写了如下iptables规则:```#清除所有已有规则iptables -Fiptables -X#设置默认策略iptables -P INPUT DROPiptables -P OUTPUT ACCEPTiptables -P FORWARD DROP#允许内网主机访问外网iptables -A FORWARD -s 192.168.1.0/24 -j ACCEPT#禁止外部主机访问内网iptables -A FORWARD -d 192.168.1.0/24 -j DROP#允许特定IP地址访问内网某些服务iptables -A INPUT -s 10.0.0.2/32 -p tcp --dport 22 -j ACCEPT#禁止所有IP地址访问内网某些服务iptables -A INPUT ! -s 192.168.1.0/24 -p tcp --dport 80:443 -j DROP```3. 应用iptables规则将上述规则保存在一个文件中,例如firewall.rules,然后使用以下命令应用规则:```sudo iptables-restore < firewall.rules```4. 测试防火墙功能为了测试防火墙功能是否正常,该公司进行了如下测试:- 在内网主机上ping外部主机:能够ping通;- 在外部主机上ping内网主机:无法ping通;- 在特定IP地址上使用SSH连接内网主机的22端口:能够连接成功;- 在除特定IP地址以外的任何IP地址上使用浏览器访问内网主机的80或443端口:无法连接。

linux防火墙iptables配置(Linux下多网段Nat实现与应用)

linux防火墙iptables配置(Linux下多网段Nat实现与应用)

linux防火墙iptables配置(Linux下多网段Nat实现与应用)Linux下多网段Nat实现与应用Iptables/netfilter是一个可以替代价格昂贵的商业防火墙的网络安全保护解决方案,能够实现数据包过滤、数据包重定向和网络地址转换(NAT)等多种功能。

准备:操作系统安装光盘:CentOS-6.1版本硬件要求:dell poweredge 410(需双网卡)实现功能:192.168.11.0/24、192.168.10.0/24网段通过防火墙NAT转换访问外网,并实现数据包过滤。

过程:步骤#1. 安装操作系统(最基本安装即可)步骤#2. 设置网卡地址外网eth0 IP:xx.xx.xx.xx内网eth1 IP:172.16.1.254网卡路径:/etc/sysconfig/network-scriptsDEVICE=eth0HWADDR=00:0e:0c:3a:74:c4NM_CONTROLLED=yesONBOOT=yesTYPE=EthernetBOOTPROTO=noneIPV6INIT=noUSERCTL=noIPADDR=xx.xx.xx.xxNETMASK=255.255.255.252DEVICE=eth1HWADDR=00:0e:0c:3a:74:c4NM_CONTROLLED=yesONBOOT=yesTYPE=EthernetBOOTPROTO=noneIPV6INIT=noUSERCTL=noIPADDR=172.16.1.254NETMASK=255.255.255.0步骤#3. 添加路由把路由写到/etc/rc.d/rc.local文件里,这样每次启动就不用重新设置了。

route add -net 172.16.1.0 netmask 255.255.255.0 gw 172.16.1.1route add -net 192.168.11.0 netmask 255.255.255.0 gw 172.16.1.1route add -net 192.168.10.0 netmask 255.255.255.0 gw 172.16.1.1route add default gw 60.190.103.217172.16.1.1是交换机与Linux的内网网卡接口的地址步骤#3. 打开ip转发功能修改文档:vi /etc/sysctl.confnet.ipv4.ip_forward = 1步骤#4. Iptables相关配置[root@tp ~]# iptables -F清除预设表filter中的所有规则链的规则[root@tp ~]# iptables -X清除预设表filter中使用者自定链中的规[root@tp ~]# iptables -p INPUT DROP[root@tp ~]# iptables -p OUTPUT ACCEPT[root@tp ~]# iptables -p FORWARD DROP设定预设规则[root@tp ~]# iptables -A INPUT -p tcp --dport 22 -j ACCEPT为了能采用远程SSH 登陆,我们要开启22端口.[root@tp ~]# iptables -A INPUT -p icmp -j ACCEPT 允许icmp 包通过,也就是允许ping,IPTABLES -A INPUT -i lo -p all -j ACCEPT (如果是INPUT DROP)允许loopback!(不然会导致DNS无法正常关闭等问题)[root@tp ~]# iptables -A FORWARD -o eth0 -m state --state NEW, ESTABLISHED, RELATED -j ACCEPT[root@tp ~]# iptables -A FORWARD -O eth1 ESTABLISHED, RELATED -j ACCEPT开启转发功能,(在做NAT时,FORWARD默认规则是DROP时,必须做)[root@tp ~]#iptables -A FORWARD -f -m limit --limit 100/s --limit-burst 100 -j ACCEPT处理IP碎片数量,防止攻击,允许每秒100个[root@tp ~]#iptables -A FORWARD -p icmp -m limit --limit 1/s --limit-burst 10 -j ACCEPT设置ICMP包过滤,允许每秒1个包,限制触发条件是10个包.[root@tp ~]#i ptables -t nat -A POSTROUTING -s 172.16.1.0/24-j SNAT --to xx.xx.xx.xx[root@tp ~]#i ptables -t nat -A POSTROUTING -s 192.168.11.0/24 -j SNAT --to xx.xx.xx.xx[root@tp ~]#i ptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT --to xx.xx.xx.xx设置源地址转换步骤#5. 保存配置[root@tp ~]# /etc/rc.d/init.d/iptablessave如果不保存这些重启后就会失去作用。

Linux下NAT功能的实现

Linux下NAT功能的实现

Linux下NAT功能的实现Linux下NAT功能的实现本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝、转载,转载时请保持文档的完整性,严禁用于任何商业用途。

msn:*********************来源:1. 前言在2.4/2.6内核的Linux中的防火墙代码netfilter中支持源NAT(SNAT)和目的NAT(DNAT),基本可以满足各种类型的NAT需求,本文介绍Linux下的NAT的具体实现过程,所引的内核代码版本2.4.26,NAT原理部分不在此介绍,有兴趣者可先看我的另一篇NAT原理介绍的文章。

2. NAT hookNAT操作也是以netfilter节点形式挂接在相应的处理点上的,DNAT挂接在NF_IP_PRE_ROUTING点上,优先级高于FILTER低于MANGLE,表示在mangle表后处理,但在filter表前处理数据包;SNAT挂接在NF_IP_POST_ROUTING点上,优先级低于FILTER,表示在filter表后面处理数据包。

在net/ipv4/netfilter/ip_nat_standalone.c中:目的NAT的hook节点:/* Before packet filtering, change destination */static struct nf_hook_ops ip_nat_in_ops= { { NULL, NULL }, ip_nat_fn, PF_INET, NF_IP_PRE_ROUTING, NF_IP_PRI_NAT_DST };源NAT的hook节点:/* After packet filtering, change source */static struct nf_hook_ops ip_nat_out_ops= { { NULL, NULL }, ip_nat_out, PF_INET, NF_IP_POST_ROUTING, NF_IP_PRI_NAT_SRC};include/linux/netfilter_ipv4.henum nf_ip_hook_priorities {NF_IP_PRI_FIRST = INT_MIN,NF_IP_PRI_CONNTRACK = -200, // 连接跟踪NF_IP_PRI_MANGLE = -150, // mangle tableNF_IP_PRI_NAT_DST = -100, // DNATNF_IP_PRI_FILTER = 0, // filter tableNF_IP_PRI_NAT_SRC = 100, // SNATNF_IP_PRI_LAST = INT_MAX,};ip_nat_fn()是NAT hook的主处理函数,ip_nat_out()函数也是在数据合法性检查后调用ip_nat_fn()函数。

Linux协议栈中UDP数据报从网卡到用户空间流程总结

Linux协议栈中UDP数据报从网卡到用户空间流程总结

Linux协议栈中UDP数据报从网卡到用户空间流程总结Linux协议栈中UDP数据报从网卡到用户空间流程总结NAPI驱动流程:中断发生-->确定中断原因是数据接收完毕(中断原因也可能是发送完毕,DMA完毕,甚至是中断通道上的其他设备中断)-->通过netif_rx_schedule将驱动自己的napi结构加入softnet_data的poll_list链表,禁用网卡中断,并发出软中断-->中断返回时触发软中断net_rx_action,从softnet_data的poll_list上取下刚挂入的napi结构,并且调用其 poll函数,这个poll 函数也是驱动自己提供的,比如rtl8139网卡驱动中的rtl8139_poll等。

-->在poll函数中进行轮询,直到接受完所有的数据或者预算(budget)耗尽。

每接收一个报文要分配skb,用eth_type_trans处理并交给netif_receive_skb。

-->如果数据全部接收完(预算没有用完),则重新使能中断并将napi从链表中取下。

如果数据没接收完,则什么也不作,等待下一次poll函数被调度。

非NAPI流程:中断发生-->确定中断发生的原因是接收完毕。

分配skb,读入数据,用eth_type_trans处理并且将skb交给netif_rx-->在netif_rx中,将packet加入到softnet_data的input_pkt_queue末尾(NAPI驱动不使用这个input_pkt_queue),再通过napi_schedule将softnet_data中的backlog(这也是个napi 结构)加入 softnet_data的poll_list,最后发出软中断-->软中断net_rx_action从poll_list上取下softnet_data的backlog,调用其poll函数,这个poll函数是内核提供的process_backlog-->函数process_backlog从softnet_data的input_pkt_queue末尾取下skb,并且直接交给netif_receive_skb处理。

linux iptables route 工作原理

linux iptables route 工作原理

linux iptables route 工作原理
Linux的iptables通过netfilter组件实现包过滤功能,其工作原理如下:1.当一个数据包进入网卡时,首先进入PREROUTING链。

内核根据数据包的
目的IP判断是否需要转送出去。

2.如果数据包是进入本机的,它会沿着流程向下移动,到达INPUT链。

数据
包到达INPUT链后,任何进程都会收到它。

本机上运行的程序可以发送数据包,这些数据包会经过OUTPUT链,然后到达POSTROUTING链输出。

3.如果数据包是要转发出去的,且内核允许转发,数据包就会向右移动,经
过FORWARD链,然后到达POSTROUTING链输出。

此外,NAT的原理是当内网主机访问外网时,当内网主机的数据包要通过路由器时,路由器将数据包中的源内网IP地址改为路由器上的公网IP地址,同时记录下该数据包的消息。

当外网服务器响应这次由内而外发出的请求或数据交换时,当外网服务器发出的数据包经过路由器时,原本是路由器上的公网IP地址被路由器改为内网IP。

SNAT和DNAT是iptables中使用NAT规则相关的两个重要概念。

如需更多信息,建议咨询计算机专业人士或查阅相关论坛。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/********************************Ip checksum*****************************/ static u_int16_t ip_checksum(struct iphdr* iphdrp){ return checksum((unsigned short*)iphdrp, iphdrp->ihl<<2); } static void set_ip_checksum(struct iphdr* iphdrp){ iphdrp->check = 0; iphdrp->check = checksum((unsigned short*)iphdrp, iphdrp->ihl<<2); } /****************************Ip checksum end******************************/ static int cb(struct nfq_q_handle *qh, struct struct nfq_data *nfa, void *data){ (void)nfmsg; (void)data; u_int32_t id = 0; struct nfqnl_msg_packet_hdr *ph; unsigned char *pdata = NULL; int pdata_len; ph = nfq_get_msg_packet_hdr(nfa); if (ph){ id = ntohl(ph->packet_id); } pdata_len = nfq_get_payload(nfa, if(pdata_len == -1){ pdata_len = 0; } struct iphdr *iphdrp = (struct (char**)&pdata); nfgenmsg *nfmsg,
nf_queue_test.c /* * ===================================================================================== * * Filename: nf_queue_test.c * * Description: 用 netfilter_queue 在用户态修改网络数据包的例子程序 * * Version: 1.0 * Created: 04/02/2010 09:49:48 AM * Revision: none * Compiler: gcc * * Author: LeiuX (xulei), xulei@ * Company: HIT * * ===================================================================================== */ #include #include #include #include #include #include #include #include #include #include #include #include <stdio.h> <stdlib.h> <unistd.h> <netdb.h> <string.h> <netinet/in.h> <arpa/inet.h> <asm/byteorder.h> <linux/netfilter.h> <libnetfilter_queue/libnetfilter_queue.h> <linux/ip.h> <linux/tcp.h>
用 netfilter_queue 在用户态实现 NAT
偶尔在网上看到了<<用 netfilter_queue 在用户态修改网络数据包的例子程序>>这篇文章, 并结合 libnetfilter_queue-0.0.17.tar.bz2 中的例子, 然后修改了一下 tcp 计算 checksum 部分,在 linux2.6.24 上用 netfilter_queue 在用户态实现 NAT 程序功能: 将输出端目的地为 220.181.37.55 的包,都改为目的地为 202.118.236.130,输入段反之,达到 DNAT 的一小半功能,完整的 NAT 要做状 态记录的. 直接上代码:
\ \ \
\ \ \
struct tcp_pseudo /*the tcp pseudo header*/ { __u32 src_addr; __u32 dst_addr; __u8 zero; __u8 proto; __u16 length; } pseudohead;
long checksum(unsigned short *addr, unsigned int /* Compute Internet Checksum for "count" bytes * beginning at location "addr". */ register long sum = 0; while( count > 1 ) { /* This is the inner loop */ sum += * addr++; count -= 2; } /* Add left-over byte, if any */ if( count > 0 ) sum += * (unsigned char *) /* Fold 32-bit sum to 16 bits */ while (sum>>16) sum = (sum & 0xffff) + (sum return ~sum; }
iphdr
*)pdata;
printf("len %d iphdr %d %u.%u.%u.%u ->", pdata_len, iphdrp->ihl<<2, IPQUAD(iphdrp->saddr)); printf(" %u.%u.%u.%u %s", IPQUAD(iphdrp->daddr), getprotobynumber(iphdrp->protocol)->p_name); printf(" ipsum %hu", ip_checksum(iphdrp)); if(iphdrp->protocol == IPPROTO_TCP){ printf(" tcpsum %hu", tcp_checksum(iphdrp)); } #define TO "220.181.37.55" #define DNAT_TO "202.118.236.130" if(iphdrp->daddr == inet_addr(TO)){ printf(" !hacked!");
count)
{
addr;
>>
16);
/*************************tcp checksum**********************/ long get_tcp_checksum(struct iphdr * myip, struct tcphdr __u16 total_len = int tcpopt_len int tcpdatalen = = ntohs(myip->tot_len); mytcp->doff*4 - 20; total_len - (mytcp->doff*4)
#ifdef __LITTLE_ENDIAN #define IPQUAD(addr) \ ((unsigned char *)&addr)[0], ((unsigned char *)&addr)[1], ((unsigned char *)&addr)[2], ((unsigned char *)&addr)[3] #else #define IPQUAD(addr) \ ((unsigned char *)&addr)[3], ((unsigned char *)&addr)[2], ((unsigned char *)&addr)[1], ((unsigned char *)&addr)[0] #endif
*
mytcp)
{
-
(myip->ihl*4);
pseudohead.src_addr=myip->saddr; pseudohead.dst_addr=myip->daddr; pseudohead.zero=0; pseudohead.proto=IPPROTO_TCP; pseudohead.length=htons(sizeof(struct
memcpy((unsigned char memcpy((unsigned char memcpy((unsigned char myip->ihl*4)+(sizeof(struct memcpy((unsigned char r *)mytcp+(mytcp->doff*4),
*)tcp,&pseudohead,sizeof(struct tcp_pseudo)); *)tcp+sizeof(struct tcp_pseudo),(unsigned char*)mytcp,sizeof(struct tcphdr)); *)tcp+sizeof(struct tcp_pseudo)+sizeof(struct tcphdr),(unsigned char *)myip+( tcphdr)), tcpopt_len); *)tcp+sizeof(struct tcp_pseudo)+sizeof(structtcphdr)+tcpopt_len, (unsigned cha tcpdatalen);
相关文档
最新文档