这个程序最开始是我在学习绿盟的文章时写的:
: c6 x& x5 {5 Q" J3 g4 r9 l! B, c, [* U! A
http://magazine.nsfocus.com/detail.asp?id=636
; ~ [+ ~& T! [8 G0 }" ^- v7 X5 a3 G9 c4 H
看完这篇文章,我就写了一个自己的小防火墙。我在内核版本为 2.2.14 和 2.4.2 上可以成功编译运行。这个程序的主要作用是:阻挡别人ping你的IP包,你ping别人的IP包却可以通过。这样别人就无法ping到你,你却可以ping到别人!
/ O& w+ C0 q' T! [; T$ G4 H
如下:
, [& x2 L8 z l9 ~4 n6 ]' G+ B/*
! l5 {$ h. [. [) d0 k * File : li_filter.c writen by kunlong
" w l# K! m( @0 }3 W
* Kernel : 2.2.16 or 2.2.14 or 2.4.2
% C; \* [. F! D8 O- s* C
* Complie : gcc -O3 -c li_filter.c
% Y5 J8 Z1 P' m# a& G( p9 e
* Usage : insmod li_filter.o -f
! L1 f/ i4 ?& ~, |) `; c! v* ?: l
* Date : 2001-06-28
- e. U l" Q, Q; u: |- l2 a
*/
1 _( t/ d1 J; D! S5 V
#ifndef __KERNEL__
8 |1 e% G5 Y3 l: f& f6 e; M #define __KERNEL__
( y2 Y' A8 ? g+ i. i
#endif
7 L" c7 S) ]' G2 o- q! {3 c7 E* U# |7 g
#ifndef MODULE
8 Q' V6 \4 a& `/ P X #define MODULE
! S" _$ _4 d* ~0 O& V9 ~6 m#endif
% P# s3 C' [& w( n0 v#include <linux/config.h>
+ G$ m; y' A x4 `; A1 A- C
#include <linux/module.h>
2 J+ E p4 G5 t- P
#include <linux/kernel.h>
+ Y/ t$ W0 c* O- C' o; X' x#include <linux/version.h>
8 u2 {! t% r/ _% X4 v- R9 W, r#include <linux/netdevice.h>
& z7 W, n# ]! R# a
#include <linux/if_ether.h>
, f- k2 M. n0 ?3 u( x#include <linux/if_packet.h>
. g) R% {5 e/ E8 K+ F8 z#include <linux/skbuff.h>
6 M) y5 E& E& q/ B( \, U
#include <linux/ip.h>
% Y5 Z- {" D1 x N
#include <linux/icmp.h>
6 v1 V2 }) I o$ e8 Y5 i0 D/ [4 `9 T2 L#include <linux/in.h>
9 `' {! U5 }0 r( q6 Y#ifndef KERNEL_VERSION
$ B' e5 s1 K+ S6 V3 j" X! a
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
; t0 P- H8 |4 x3 w: y; H#endif
/ c) e" o" B2 }; E# E! N! O
- I+ ]" @' z2 ^+ t N+ z! j2 h#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)
5 g1 [" x& R6 { k! U8 `
#include <asm/uaccess.h>
' H* z4 U8 l0 E#endif
9 p A: f- F/ B( T! ^4 x/ O; U
0 B; o( N1 n7 ], S' x) P5 ^
static struct device * filter_dev = NULL;
5 {7 I3 ~7 d! A2 Fstatic char * dev = NULL;
. K' _! x8 e" B
* f: ^9 E/ U1 \
/* 定义insmod命令行参数 */
5 X+ D) ]8 X* P5 e: r' n#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)
! a, i1 p* S* T; Q
MODULE_PARM( dev, "s" );
: i' R: Z3 X7 h( M3 |3 A#endif
: H/ U! E: `3 k% c3 T
) @; I3 i3 a4 H9 ]5 m) h
int filter_rcv ( struct sk_buff * skb, struct device * dv, struct packet_type * pt )
" E7 c: X7 Q1 _/ [( e" k) n
{
4 k$ d) g% w1 a /* 注意pkt_type是什么 */
) J5 a3 n2 \$ K3 z) y/ Z/ J
if ( ( skb->pkt_type == PACKET_HOST ) && ( skb->protocol == __constant_htons( ETH_P_IP) ) )
, u. |& X. a4 A7 e {
" O% l5 t' y# W& }; f) k
if ( ( skb->nh.iph->version == 4 ) && ( skb->nh.iph->protocol == IPPROTO_ICMP ) ) /* 不考虑ipv6 */
( p( H, e/ P7 g* }. g2 Y* \
{
* I6 }) N5 B+ N3 {7 N2 W6 j; C7 | skb->h.raw = skb->nh.raw + ( skb->nh.iph->ihl << 2 );
( N" D: B) W d% s) x m
if ( skb->h.icmph->type == 8 )
% k Q5 o# Y4 ^) K0 T8 [. u4 b- k
{
* Y1 ^! A( @2 b' }$ k
unsigned char *saddr = &(skb->nh.iph->saddr);
7 ]# _6 o( N3 j, a" J( c
printk("<1>--- ping from: %d.%d.%d.%d ---\n", *saddr,*(saddr+1),*(saddr+2),*(saddr+3));
& ~6 T+ r% h, h! v& Q, U. Z" |5 e/ H E0 s; v5 U' K$ m
skb->h.icmph->checksum += 1; // Change the checksum, then this IP packet will be Ignored.
0 u/ W4 J: G0 T+ f* ]2 D3 r( W" q% w }
! H2 S; q( n& Z. K. H0 ^
}
% `3 Z2 n# S% s g7 D) h }
) D& e8 V) U; G v$ C2 w) U7 b
kfree_skb( skb );
. v, o( p! u6 g( P6 E return( 0 );
0 v7 }. j0 z6 w7 ~8 F+ @} /* end of filter_rcv */
. ?# M1 k! z& [* |
- ?/ K5 T- J2 }. K& o* T
static struct packet_type filter_packet_type =
( C7 q2 L5 T9 [1 W% Q. S! y
{
; ^3 o, O3 T8 ?3 G( Q+ ? __constant_htons( ETH_P_ALL ), /* 此时可以接收到来自lo的回送报文,比如本机发送出去的 */
& }1 F, T% R8 F; @
NULL, /* All devices */
' |" ~- e% G* T! E5 S" o% s5 A
filter_rcv,
" Q# b& X/ {) w; G1 S; C' r NULL, /* 如果是2.4内核,这里可以考虑设置成非零,但是filter_rcv需要改变 */
5 i Q- [, O" } NULL,
8 w( X( ` S8 ]7 o8 C$ f; p+ n};
2 q; ?0 @4 A2 V: _& g% X% K% d+ P4 G
int init_module ( void ) /* 模块初始化 */
7 X9 i5 r# |( u# w) }( H
{
( {9 V. k( W# E& r* Y7 d3 h if ( dev != NULL )
4 |, R2 ]" g7 d
{
8 P( E! J- d f) h% s
filter_dev = dev_get( dev );
. D3 Z H' g9 _3 Q* Y
if ( filter_dev != NULL )
, }2 K+ }# v- k- m8 I9 ?/ J {
- W) C8 ]1 n5 r0 ^: N filter_packet_type.dev = filter_dev;
& X/ l' a+ z# N* E5 N' u
}
2 ]7 H4 {. V$ u5 B
}
8 ^7 \! Q. R u" J- o8 A
dev_add_pack( &filter_packet_type );
7 }0 j# V! h4 L# V+ C: Q7 K EXPORT_NO_SYMBOLS;
) I1 `' _" ]3 p return( 0 );
" a- _+ b4 h& G% }. B: B9 j/ x
} /* end of init_module */
8 ^+ g# E7 {- ]; T0 @
7 C" S% |3 a p( ^4 g3 H# dvoid cleanup_module ( void ) /* 模块卸载 */
. h% B) G9 w o1 U{
- i' E1 s$ v7 w% r
dev_remove_pack( &filter_packet_type );
8 }4 J0 B" `4 X7 n
return;
! S+ N9 Y8 s, G$ _- }3 O} /* end of cleanup_module */
9 d7 `6 K* h5 n7 n$ ~" n( S