当前位置: 技术问答>linux和unix
如何在linux下编一个网络抓包的程序,不能用libcap
来源: 互联网 发布时间:2015-08-16
本文导语: 想利用linux的源代码的一部分来实现这个功能,但是不知道怎么做,在源代码的那个部分能找到这个功能,而且对协议栈的原理不大熟; 请指教,谢谢!!! | gcc -c test3.c -o test3~.o -I/usr...
想利用linux的源代码的一部分来实现这个功能,但是不知道怎么做,在源代码的那个部分能找到这个功能,而且对协议栈的原理不大熟;
请指教,谢谢!!!
请指教,谢谢!!!
|
gcc -c test3.c -o test3~.o -I/usr/src/linux-2.4.20-8/include -Wall -D__KERNEL__
ld -r -o test3.o test3~.o -L/usr/lib -lc
这样编译如下模块test3.o
然后用root就可以insmod它到内核模块,就可以截取网络包,具体实现按你的想法改
我这个做的事拒绝来至 192.168.8.201的所有数据包
#define MODULE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static struct nf_hook_ops nfho;
unsigned char* ip = "x7fx00x00x01";
unsigned char* drop_ip = "xC0xA8x08xC9";
unsigned int hook_func(unsigned int hooknum,
struct sk_buff **skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct sk_buff* sb = *skb;
struct tcphdr *tcp = NULL;
unsigned int d_ip ,s_ip = 0;
unsigned int d_port = 0,s_port = 0;
if( sb->nh.iph->protocol == IPPROTO_TCP )
tcp = (struct tcphdr *)((sb->data) + (sb->nh.iph->ihl * 4));
d_ip = sb->nh.iph->daddr;
s_ip = sb->nh.iph->saddr;
if( tcp )
{
d_port = tcp->source;
s_port = tcp->dest;
}
if( sb->nh.iph->saddr == *(unsigned int*)drop_ip )
{
printk( "Droped packet from ... %d.%d.%d.%d:%dn", NIPQUAD(s_ip), s_port );
return NF_DROP;
}
// printk( "FROM:%d.%d.%d.%d:%d TO:%d.%d.%d.%d:%d ETH:%sn",
// NIPQUAD(s_ip), s_port, NIPQUAD(d_ip), d_port, in->name );
return NF_ACCEPT;
}
int init_module()
{
printk( "begin init module test2n" );
nfho.hook = hook_func;
nfho.hooknum = NF_IP_PRE_ROUTING;
nfho.pf = PF_INET;
nfho.priority = NF_IP_PRI_FIRST;
nf_register_hook(&nfho);
printk("init module test2n");
return 0;
}
void cleanup_module()
{
nf_unregister_hook(&nfho);
printk("cleanup module test2n");
}
MODULE_LICENSE("GPL");
ld -r -o test3.o test3~.o -L/usr/lib -lc
这样编译如下模块test3.o
然后用root就可以insmod它到内核模块,就可以截取网络包,具体实现按你的想法改
我这个做的事拒绝来至 192.168.8.201的所有数据包
#define MODULE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static struct nf_hook_ops nfho;
unsigned char* ip = "x7fx00x00x01";
unsigned char* drop_ip = "xC0xA8x08xC9";
unsigned int hook_func(unsigned int hooknum,
struct sk_buff **skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct sk_buff* sb = *skb;
struct tcphdr *tcp = NULL;
unsigned int d_ip ,s_ip = 0;
unsigned int d_port = 0,s_port = 0;
if( sb->nh.iph->protocol == IPPROTO_TCP )
tcp = (struct tcphdr *)((sb->data) + (sb->nh.iph->ihl * 4));
d_ip = sb->nh.iph->daddr;
s_ip = sb->nh.iph->saddr;
if( tcp )
{
d_port = tcp->source;
s_port = tcp->dest;
}
if( sb->nh.iph->saddr == *(unsigned int*)drop_ip )
{
printk( "Droped packet from ... %d.%d.%d.%d:%dn", NIPQUAD(s_ip), s_port );
return NF_DROP;
}
// printk( "FROM:%d.%d.%d.%d:%d TO:%d.%d.%d.%d:%d ETH:%sn",
// NIPQUAD(s_ip), s_port, NIPQUAD(d_ip), d_port, in->name );
return NF_ACCEPT;
}
int init_module()
{
printk( "begin init module test2n" );
nfho.hook = hook_func;
nfho.hooknum = NF_IP_PRE_ROUTING;
nfho.pf = PF_INET;
nfho.priority = NF_IP_PRI_FIRST;
nf_register_hook(&nfho);
printk("init module test2n");
return 0;
}
void cleanup_module()
{
nf_unregister_hook(&nfho);
printk("cleanup module test2n");
}
MODULE_LICENSE("GPL");
|
首先你要确定你要在内核层抓包还是应用层.内核抓包用添加模块了,linux在内核网络栈上留了5个点就是用来扩展的.应用层抓包用raw socket,就是fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
man 7 socket有详细介绍.
前面一个方法比较复杂一点,一天两天也写不好的.后面一个就是套接字编程了.
man 7 socket有详细介绍.
前面一个方法比较复杂一点,一天两天也写不好的.后面一个就是套接字编程了.
|
linux平台下捕获数据包的程序,分为两个,一个是capture.c,另一个是handle.c。前一个是用于捕获数据包的,按CTRL+C退出。捕获的数据包存储在packet.dat文件中,供分析用。后一个是输出数据包中内容的。
// capture.c
// gcc -W -Wall -Wno-unused -ggdb -o capture capture.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DEFAULT_DEVICE_NAME "eth0"
#define DEFAULT_RECORD_FILENAME "packet.dat"
typedef unsigned char uchar;
int RecordFile;
int Packet;
int PacketCount = 0;
char *RecordFileName = DEFAULT_RECORD_FILENAME;
char *DeviceName = DEFAULT_DEVICE_NAME;
short int DefaultFlag;
struct ifreq ifr;
void ArgInit( int argc, char **argv )
{
}
void Shutdown( int signum )
{
fdatasync( RecordFile );
close( RecordFile );
ifr.ifr_flags = DefaultFlag;
ioctl( Packet, SIOCSIFFLAGS, &ifr );
close( Packet );
fprintf( stdout, "Capture %d packetsn", PacketCount );
exit( 0 );
}
void AppInit( void )
{
RecordFile = open( RecordFileName, O_RDWR | O_CREAT | O_TRUNC );
if ( RecordFile
// capture.c
// gcc -W -Wall -Wno-unused -ggdb -o capture capture.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DEFAULT_DEVICE_NAME "eth0"
#define DEFAULT_RECORD_FILENAME "packet.dat"
typedef unsigned char uchar;
int RecordFile;
int Packet;
int PacketCount = 0;
char *RecordFileName = DEFAULT_RECORD_FILENAME;
char *DeviceName = DEFAULT_DEVICE_NAME;
short int DefaultFlag;
struct ifreq ifr;
void ArgInit( int argc, char **argv )
{
}
void Shutdown( int signum )
{
fdatasync( RecordFile );
close( RecordFile );
ifr.ifr_flags = DefaultFlag;
ioctl( Packet, SIOCSIFFLAGS, &ifr );
close( Packet );
fprintf( stdout, "Capture %d packetsn", PacketCount );
exit( 0 );
}
void AppInit( void )
{
RecordFile = open( RecordFileName, O_RDWR | O_CREAT | O_TRUNC );
if ( RecordFile