- 论坛徽章:
- 0
|
- 以下的一些代码只是用于实验,目的是用来在NetBSD中桥转发时进行简单的包过滤,该代码已经到现在为止运行了10多天,保护了我的重要数据库和一些重要的数据服务器,目前状况良好。涉及的文件只有一个/sys/net/if_ethersubr.c,比较简单。
- 首先在140多行加入以下一些结构的定义
- struct pfip { /*考虑到不能硬加入:#include <netinet/ip.h>;,只有自己来定义一个IP头部结构*/
- #if BYTE_ORDER==LITTLE_ENDIAN /*小头字节顺序*/
- u_int8_t ip_hl:4, /*协议头长度和版本号合为一个字节*/
- ip_v:4;
- #endif
- #if BYTE_ORDER==BIG_ENDIAN /*大头字节顺序*/
- u_int8_t ip_v:4,
- ip_hl:4;
- #endif
- u_int8_t ip_x1[8]; /*此处跳过我们不用的8个字节什么TTL,TOS等等*/
- u_int8_t ip_p; /*协议,如TCP,UDP等*/
- u_int16_t ip_x2; /*又跳过两个我们不用的字节*/
- struct in_addr ip_src,ip_dst;/*IP包的源和目的地址*/
- } __attribute__((__packed__)); /*NETBSD特有的,OPENBSD中没看到*/
- struct udptcphdr { /*紧接到IP头后面的TCP,UDP头部的四个字节*/
- u_int16_t h_sport; /*代表源端口号*/
- u_int16_t h_dport; /*代表目的端口号*/
- };
- 在660多行的ether_input函数中加入以下临时变量的定义
- struct pfip *myip=NULL;
- struct udptcphdr *myhdr=NULL;
- u_int16_t mysrcport;
- u_int16_t mydstport;
- int hlen=0;
- 在代码部分先找到这一句,1.6版本在730行左右
- if (ifp->;if_bridge) {
- /* printf("%s will forward %u\n",ifp->;if_xname,ifp->;if_index);*/
- /* */
- if (ifp->;if_index==1) { /* 我的1号设备是Internet接入网卡。当然也有其他的判断方法,但比较费时 */
- /*此处说明如果包进来的方向是从Internet进来的,就开始过滤。*/
- if (etype==ETHERTYPE_IP) { /*我只对IP包过滤*/
- myip=(struct pfip *)(m->;m_data+sizeof(struct ether_header));/*m->;m_data是网卡得到数据后放入缓冲(mbuf结构)中指向数据的部分*/
- /*数据开始的部分当然是以太网桢的开头部分,要指向IP头部就要去掉以太网头部,既指针向后移动*/
- if (myip->;ip_v != 4) {/*这时myip已经指向IP头部,看看版本号是4吗?我们只支持IPV4*/
- goto freeit;/*不是4版本就释放缓冲(mbuf)*/
- }
- hlen=myip->;ip_hl<<2;/*得到IP头部的长度,注意是IP头部,不是IP包的整个长度。*/
- if (hlen < sizeof(struct pfip)) {/*如果IP头部长度小于规定的最小IP头部长度(20字节)*/
- goto freeit; /*是一个错误的IP包,释放掉他*/
- }
- myhdr=(struct udptcphdr *)((caddr_t)myip+hlen);/*从IP头开始向后移动IP包头部长度个字节,即指向了UDP或TCP协议的头部。*/
- mydstport=ntohs(myhdr->;h_dport); /*取得源端口地址备用*/
- mysrcport=ntohs(myhdr->;d_dport); /*取得目的端口地址备用*/
- if (myip->;ip_p==IPPROTO_TCP) { /*如果是TCP协议*/
- if ((myip->;ip_dst.s_addr==0x070723d2) && (mydstport==80 || mydstport==21 )){
- /*上面的意思是:如果是访问210.35.7.7(即0x070723d2,地址可自己算)的80或21端口。*/
- printf("TCP %x=>;%x, sport:%x=>;dport:%x\n",myip->;ip_src.s_addr,myip->;ip_dst.s_addr,myhdr->;h_sport,myhdr->;h_dport);
- /*算是调试吧。显示源地址,目的地址,源端口,目的端口*/
- goto gotoit;/*跳到转发处*/
- }
- }
- if (myip->;ip_p==IPPROTO_UDP) {/*对UDP包进行过滤*/
- if (mysrcport==0x35) {/*如果对方的源端口是DNS回应,即被保护机已发了一个DNS查询*/
- goto gotoit;/*放他通过*/
- }
- }
- freeit: m_freem(m);/*其他包都丢弃,不过在此之前你可以加入其他包的过滤等等。*/
- return;
- }
- }
- gotoit: m = bridge_input(ifp, m);
- if (m == NULL)
- return;
- 在完成后进行编译核心:
- cd /sys/arch/i386/你的配置文件名
- config 你的配置文件名
- cd ../compile/你的配置文件名
- make depend
- make
- mv /netbsd /netbsd.old
- mv netbsd /netbsd
- 重新启动后打开桥,不过他的方式和OpenBSD不太一样,用以下命令:
- ifconfig bridge0 create
- brconfig bridge0 add fxp0 add fxp1 up
- fxp0和fxp1是你的两块inter的网络卡,如果是8139的就用rtk0,rtk1
复制代码 |
|