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 packets\n", PacketCount );
exit( 0 );
}
void AppInit( void )
{
RecordFile = open( RecordFileName, O_RDWR | O_CREAT | O_TRUNC );
if ( RecordFile < 0 )
{
fprintf( stderr, "can't open record file : [%s]\n", strerror(errno) );
exit( 1 );
}
strcpy( ifr.ifr_name, DeviceName );
fchmod( RecordFile, 0644 );
signal( SIGINT, Shutdown );
signal( SIGTERM, Shutdown );
}
void PacketInit( void )
{
int r, flag;
Packet = socket( PF_PACKET, SOCK_RAW, htons(ETH_P_ALL) );
if ( Packet < 0 )
{
fprintf( stderr, "socket failed : [%s]\n", strerror(errno) );
exit( 1 );
}
r = ioctl( Packet, SIOCGIFFLAGS, &ifr );
if ( r < 0 )
{
fprintf( stderr, "ioctl failed : [%s]\n", strerror(errno) );
close( Packet );
exit( 1 );
}
DefaultFlag = ifr.ifr_flags;
ifr.ifr_flags |= IFF_PROMISC;
r = ioctl( Packet, SIOCSIFFLAGS, &ifr );
if ( r < 0 )
{
fprintf( stderr, "ioctl failed : [%s]\n", strerror(errno) );
close( Packet );
exit( 1 );
}
}
void CaptureLoop( void )
{
int n;
uchar buf[2048];
while( 1 )
{
n = recvfrom( Packet, buf, sizeof(buf), 0, NULL, NULL );
if ( n <= 0 )
{
fprintf( stderr, "recvfrom error : [%s]\n", strerror(errno) );
break;
}
write( RecordFile, &n, sizeof(n) );
write( RecordFile, buf, n );
PacketCount++;
}
fprintf( stdout, "Capture %d packets\n", PacketCount );
fdatasync( RecordFile );
close( RecordFile );
ifr.ifr_flags = DefaultFlag;
ioctl( Packet, SIOCSIFFLAGS, &ifr );
close( Packet );
}
int main( int argc, char **argv )
{
ArgInit( argc, argv );
AppInit();
PacketInit();
CaptureLoop();
return 0;
}
//handle.c
// gcc -W -Wall -Wno-unused -ggdb -o handle handle.c
//usage: ./handle | more;用more分屏看输出信息,也可把输出信息重定向到另一临时文件中:./handle > packet.txt
#include
#include
#include
#include
#include
#include
#include
#include
typedef unsigned char uchar;
int main()
{
int fd, n, t = 0;
fd = open( "packet.dat", O_RDONLY );
if ( fd < 0 ) return -1;
while( read( fd, &n, sizeof(n) ) )
{
uchar buf[2048];
t = 0;
bzero( buf, sizeof(buf) );
read( fd, buf, n );
while( (n-t) >= 16 )
{
int i;
printf( "[ " );
for ( i = 0; i < 16; i++ )
printf("%02x ",buf[t+i]);
printf( "]\t[" );
for ( i = 0; i < 16; i++ )
{
char ch = buf[t+i];
if ( isalnum(ch) )
printf( "%c", ch );
else
printf(".");
}
printf("]\n");
t += 16;
}
if ( n > t )
{
int i = t;
printf( "[ " );
while( i < n )
printf( "%02x ", buf[i++] );
printf("]");
i = n - t;
i = 16 - i;
while( i-- ) printf( " " );
printf( "\t[" );
i = t;
while(i {
char ch = buf[i++];
if ( isalnum(ch) )
printf( "%c", ch );
else
printf(".");
}
printf( "]\n" );
}
printf( "\n" );
}
close( fd );
return 0;
}
阅读(2629) | 评论(0) | 转发(0) |