这个程序最开始是我在学习绿盟的文章时写的:
6 F' W+ |- c3 A8 ?0 chttp://magazine.nsfocus.com/detail.asp?id=636
$ F& n3 z9 [4 Z9 h
$ F1 M) z) T1 `7 m4 u" e看完这篇文章,我就写了一个自己的小防火墙。我在内核版本为 2.2.14 和 2.4.2 上可以成功编译运行。这个程序的主要作用是:阻挡别人ping你的IP包,你ping别人的IP包却可以通过。这样别人就无法ping到你,你却可以ping到别人!
( K; I$ U9 G9 F如下:
/ i+ @( r* K6 e! C/*
2 h1 ~; v. l( G6 u * File : li_filter.c writen by kunlong
* D* Y, I; i3 q2 v! U, q * Kernel : 2.2.16 or 2.2.14 or 2.4.2
( K6 q% m$ w7 `! s8 ?; v$ H) C
* Complie : gcc -O3 -c li_filter.c
( D6 Y7 N. } H" _) m0 o- D3 K
* Usage : insmod li_filter.o -f
( Q3 K% g1 n ~: y, J
* Date : 2001-06-28
$ ~9 `& J* f: ^; x */
4 ]! o9 H+ D+ j#ifndef __KERNEL__
4 _5 C0 o4 t( w9 R' z* s. ~6 \ #define __KERNEL__
0 h2 b% F. M, x* x% Q$ ]#endif
8 [& S* p7 l; N# G7 ~
#ifndef MODULE
/ n: C% Y( t; ?0 f
#define MODULE
+ n6 q- e1 t E% ]. L7 m#endif
9 g( W" ~- [4 j) X% y#include <linux/config.h>
9 b t1 Z6 b; _; H! [# |#include <linux/module.h>
' T- l3 j% H o/ p G3 Q% P. ?( j#include <linux/kernel.h>
% y5 `0 `' @1 }" [% ~
#include <linux/version.h>
5 G8 l" W' M d0 E#include <linux/netdevice.h>
0 w& I/ ]1 w7 f U0 A3 g# \. N+ L
#include <linux/if_ether.h>
9 r5 Q- C4 g, a7 x9 n1 z* T
#include <linux/if_packet.h>
$ e; y. |2 D/ c U8 L
#include <linux/skbuff.h>
! D$ [- s! n5 t( _) B; h+ S#include <linux/ip.h>
- g$ }0 L9 l+ ]: Z4 P7 ?#include <linux/icmp.h>
8 k% A6 M2 D( \. P% Q#include <linux/in.h>
' K) W- V a7 i; g8 {7 Y! H/ l9 ^#ifndef KERNEL_VERSION
8 w$ I* j! J7 E
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
1 i1 r! x# y' _0 i' A) L# n
#endif
4 f5 Z" Z; r9 M9 n+ ^: H( R. o) |% r
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)
0 t( y( G0 l- v#include <asm/uaccess.h>
7 t9 c |4 A( Q4 ]! m6 _ B
#endif
+ |$ x7 {2 j- j4 v+ t4 F, A' \0 Z+ u1 A: {! ~9 j' R
static struct device * filter_dev = NULL;
" C9 x: [4 \5 d. c. lstatic char * dev = NULL;
+ _: ?- V3 N* `, p
& W* p! _5 l3 u
/* 定义insmod命令行参数 */
; Q; ]4 Q: c- Z5 u& b2 U#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)
3 k2 c, P8 P7 x3 u
MODULE_PARM( dev, "s" );
0 ~1 f8 [# g0 {0 @#endif
0 A5 n. ^. G/ p5 d3 d
) T" {2 R7 X; P8 L4 {
int filter_rcv ( struct sk_buff * skb, struct device * dv, struct packet_type * pt )
7 h7 _( k/ V! ~, K. Z; [6 }$ j{
5 V H* C+ l* T0 v* I4 o
/* 注意pkt_type是什么 */
5 A- `, b4 E! b
if ( ( skb->pkt_type == PACKET_HOST ) && ( skb->protocol == __constant_htons( ETH_P_IP) ) )
& v2 q* K+ y; }1 R
{
& w7 ?$ ~$ E( K' P( \. l
if ( ( skb->nh.iph->version == 4 ) && ( skb->nh.iph->protocol == IPPROTO_ICMP ) ) /* 不考虑ipv6 */
7 ]$ ^, D2 l* T; ]) I+ _: t9 i {
+ W6 z( ]- m0 i( A! i
skb->h.raw = skb->nh.raw + ( skb->nh.iph->ihl << 2 );
; b1 [- v+ j" e9 U% C
if ( skb->h.icmph->type == 8 )
: r! ]; B# ^ e r) a1 o+ c {
" |) @; h/ B. x% Z) F+ R5 D5 U
unsigned char *saddr = &(skb->nh.iph->saddr);
3 X; Q0 i4 S& v2 @* K) w, ~3 G- B printk("<1>--- ping from: %d.%d.%d.%d ---\n", *saddr,*(saddr+1),*(saddr+2),*(saddr+3));
+ X: J2 r" y+ l# e- ^0 U' K- H8 L, g
$ V. ]' T7 W' I; R4 a
skb->h.icmph->checksum += 1; // Change the checksum, then this IP packet will be Ignored.
0 V0 T' [$ W7 \( J# _
}
$ Q' v* {8 r- A8 w) T4 D }
/ l, G1 Y: x9 n2 _
}
2 m& `* {1 A) J) i2 ~, y V9 }
kfree_skb( skb );
7 y% ?1 v; C, G, O6 T+ P return( 0 );
" z/ o0 Z- k3 H+ I! i
} /* end of filter_rcv */
- ~; R! @$ x f0 J3 ]! U
# W) D5 A! Y8 H; M; q/ H# Qstatic struct packet_type filter_packet_type =
2 X; G% W# m: n{
; x/ O& _( H9 ~) K, P
__constant_htons( ETH_P_ALL ), /* 此时可以接收到来自lo的回送报文,比如本机发送出去的 */
; b& ^" _; Y. E
NULL, /* All devices */
( i0 Y% s5 w3 h9 \8 G. j* j
filter_rcv,
, @ e8 t- v( @& d. _" J
NULL, /* 如果是2.4内核,这里可以考虑设置成非零,但是filter_rcv需要改变 */
0 w" r( ?% n1 n Q/ p/ h& ~
NULL,
r5 D z( W* u" o+ G, ?};
1 X9 o! M) q$ i) h
. z8 C% X% Z7 W1 j6 S! eint init_module ( void ) /* 模块初始化 */
^4 K& t7 A3 p" y+ {- \
{
4 G+ W; G5 k. ?# g2 g9 p: A6 ` if ( dev != NULL )
* h/ C4 W/ }; e9 K {
; t; h6 I* Z$ I% }4 x$ p ? filter_dev = dev_get( dev );
9 r2 ~8 i6 U2 a
if ( filter_dev != NULL )
3 M I* N' F* Q# h* m+ Z% s+ Z$ G
{
5 L( s# e' P8 C* M" [ filter_packet_type.dev = filter_dev;
: S% r9 i+ V" M0 ]" n, Y
}
1 B; F3 }- i, d8 r9 y" K
}
" F; C! E ^1 x+ [" {5 Y J0 e
dev_add_pack( &filter_packet_type );
k7 V8 U# t% b, U+ B e7 ?: a
EXPORT_NO_SYMBOLS;
# ]4 u) ~4 k5 E0 Q; f" z9 w+ O
return( 0 );
1 W. T% Y3 I) [8 Q0 |6 r+ f# W
} /* end of init_module */
, k" E: u3 t) |' e) Z
( l' G8 g& A; y* \void cleanup_module ( void ) /* 模块卸载 */
/ n+ J3 e" I( h/ V7 L# S
{
( P* [, O0 k$ `3 c+ y5 A dev_remove_pack( &filter_packet_type );
9 v" ~1 W& V; Y- }; F return;
{% H. v9 ~* e/ u. y: T$ B8 |1 [} /* end of cleanup_module */
& H! U1 d0 n/ i+ f/ ~" V