📄 548.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://apue.dhs.org"><font face="黑体"><big><big>apue</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center"> ● UNIX网络编程 (BM: clown) </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="index.htm">回到开始</a>][<a href="537.htm">上一层</a>][<a href="549.htm">下一篇</a>]
<hr><p align="left"><small>发信人: guru (好读书,不求甚解), 信区: UNP <br>
标 题: Packet Capture With libpcap and other (3) <br>
发信站: UNIX编程 (2001年08月04日11:17:05 星期六), 站内信件 <br>
<br>
Writing a Basic Packet Capture Engine <br>
<br>
-------------------------------------------------------------------------------- <br>
<br>
Hi :-), this section consists of a discussion on how to write a simple packet ca <br>
pture engine. The goal is to demonstrate methods of capturing and filtering mult <br>
iple packets to aid in packet analysis. All the juicy info on disecting IP packe <br>
ts and <br>
forging new ones are reserved for later sections.. Yes I can see your dissapoint <br>
ment, but you must admit that a program that captures a single packet at a time <br>
is pretty much useless. <br>
<br>
Consider the following pcap method: <br>
<br>
int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) <br>
We will use this to provide the core functionality of our engine. When pcap_loop <br>
(..) is called it will grab cnt packets (it will loop infinitely when cnt is -1) <br>
and pass them to the callback function which is of type pcap_handler.. and what <br>
is pcap <br>
is pcap <br>
handler?? well lets go to the handy dandy header file.. <br>
<br>
<br>
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, const u_char <br>
*); <br>
<br>
We are interested in arguments 2 and 3, the pcap packet header and a const u_cha <br>
r consisting of the packet. <br>
<br>
So for just a primer, lets write a q&d program that will loop and get n packets, <br>
then exit. <br>
<br>
Download testpcap2.c Here or just cut and paste from below <br>
/********************************************************************** <br>
* file: testpcap2.c <br>
* date: 2001-Mar-14 12:14:19 AM <br>
* Author: Martin Casado <br>
* Last Modified:2001-Mar-14 12:14:11 AM <br>
* <br>
* Description: Q&D proggy to demonstrate the use of pcap_loop <br>
* <br>
**********************************************************************/ <br>
<br>
#include <pcap.h> <br>
#include <stdio.h> <br>
#include <stdlib.h> <br>
#include <errno.h> <br>
#include <sys/socket.h> <br>
#include <netinet/in.h> <br>
#include <arpa/inet.h> <br>
#include <netinet/if_ether.h> <br>
<br>
/* callback function that is passed to pcap_loop(..) and called each time <br>
* a packet is recieved */ <br>
void my_callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char* <br>
packet) <br>
{ <br>
static int count = 1; <br>
fprintf(stdout,"%d, ",count); <br>
if(count == 4) <br>
fprintf(stdout,"Come on baby sayyy you love me!!! "); <br>
if(count == 7) <br>
fprintf(stdout,"Tiiimmmeesss!! "); <br>
fflush(stdout); <br>
count++; <br>
} <br>
<br>
int main(int argc,char **argv) <br>
{ <br>
int i; <br>
char *dev; <br>
char errbuf[PCAP_ERRBUF_SIZE]; <br>
pcap_t* descr; <br>
const u_char *packet; <br>
struct pcap_pkthdr hdr; /* pcap.h */ <br>
struct ether_header *eptr; /* net/ethernet.h */ <br>
<br>
if(argc != 2){ fprintf(stdout,"Usage: %s numpackets\n",argv[0]);return 0;} <br>
<br>
/* grab a device to peak into... */ <br>
dev = pcap_lookupdev(errbuf); <br>
if(dev == NULL) <br>
{ printf("%s\n",errbuf); exit(1); } <br>
/* open device for reading */ <br>
descr = pcap_open_live(dev,BUFSIZ,0,-1,errbuf); <br>
if(descr == NULL) <br>
{ printf("pcap_open_live(): %s\n",errbuf); exit(1); } <br>
<br>
/* allright here we call pcap_loop(..) and pass in our callback function */ <br>
/* int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)*/ <br>
/* If you are wondering what the user argument is all about, so am I!! */ <br>
pcap_loop(descr,atoi(argv[1]),my_callback,NULL); <br>
<br>
fprintf(stdout,"\nDone processing packets... wheew!\n"); <br>
return 0; <br>
} <br>
<br>
Allright then, lets give her a whirl! <br>
<br>
[root@pepe libpcap]# gcc testpcap2.c -lpcap <br>
[root@pepe libpcap]# ./a.out 7 <br>
1, 2, 3, 4, Come on baby sayyy you love me!!! 5, 6, 7, Tiiimmmeesss!! <br>
Done processing packets... wheew! <br>
[root@pepe libpcap]# <br>
<br>
So as you can see, my_callback(...) was actually called 7 times before exiting. <br>
If you are testing your program by pinging an external machine the packets come <br>
slow enough to see them arrive in real time.. cooolll! Ohh THE RAWWW POWER!!!! S <br>
o at the <br>
most primitive level we could certainly put all of our packet analysis code in m <br>
y_callback(..) and call it is done deal. But as good little coders we certainly <br>
aren't satisfied with such an easy and straightforward solution! The first probl <br>
em is that <br>
pcap_loop(..) blocks indefinatly if no packet can be read. While this may be the <br>
desired behaviour it would be nice to timeout on the reads. Remember way back w <br>
hen we talked about pcap_open_live(..)? One of the arguments you can specify is <br>
a timeout <br>
value in miliseconds. pcap_loop actually ignores this argument, but pcap_dispatc <br>
h(..) doesn't! So if we want our main looping mechanism to time-out replace pcap <br>
_loop() with pcap_dispatch(). Here is a description of pcap_dispatch(..) shamele <br>
ssly <br>
stripped from the man page <br>
<br>
<br>
************ <br>
pcap_dispatch() is used to collect and process packets. cnt specifies the maximu <br>
m number of packets to process before returning. A cnt of -1 processes all the p <br>
ackets received in one buffer. A cnt of 0 processes all packets until an error o <br>
ccurs, EOF <br>
is reached, or the read times out (when doing live reads and a non-zero read tim <br>
eout is specified). callback specifies a routine to be called with three argumen <br>
ts: a u_char pointer which is passed in from pcap_dispatch(), a pointer to the p <br>
cap_pkthdr <br>
struct (which precede the actual network headers and data), and a u_char pointer <br>
to the packet data. The number of packets read is returned. Zero is returned wh <br>
en EOF is reached in a ``savefile.'' A return of -1 indicates an error in which <br>
case <br>
pcap_perror() or pcap_geterr() may be used to display the error text. <br>
************ <br>
<br>
<br>
In many applications using packet capture, you are not going to be interested in <br>
every packet on your network. Take the following scenario. Little Johny just bo <br>
ught the coolest new internet game to hit the markets. Little Johny wants to be <br>
the first <br>
kid to hack up a bot for the game, but unlike all other little kiddies, Johny is <br>
going to write his own packet capture engine instead of using something canned. <br>
Little Johnny notices that when the game starts up and he connects to the serve <br>
r.. it is <br>
connecting to 216.148.0.87 on port 26112. What should little Johnny do to only c <br>
apture packets with destination of 216.148.0.87 port 26112? Enter... pcap_compil <br>
e(..) and pcap_setfilter(...) !!! <br>
<br>
Now in all actuality we could certainly read in all packets and sort threw them <br>
one by one to pick out the subset we are interested in. However, given heavy tra <br>
ffic this could be expensive!! luckily libpcap provides an interface where you c <br>
an specify <br>
exactly which packets you are interested in. In brief, to do this you need to pa <br>
ss a filter program as a string to pcap_compile() and then set it as a filter... <br>
. the problem is that the pcap man page doesn't provide any detail of what the f <br>
ilter <br>
program should look like (at least mine doesn't). Is all lost!? No! because we h <br>
ave the handy dandy program tcpdump and its man page. You should have tcpdump al <br>
ready installed on your machine (which tcpdump) but if you don't I highly sugges <br>
t you put <br>
it on. Tcpdump is pretty much a program wrapper of libpcap, in fact it is so sim <br>
ilar?it accepts filter programs from the command line! Aha! a reference. The tcp <br>
dump man page explicitly describes the syntax and semantics of the filter langua <br>
ge, which <br>
is (of course) pretty straight forward. Here are the pertinent sections from my <br>
man pages... note that when referring to "the expression" it is talking about th <br>
e progrm <br>
<br>
The expression consists of one or more primitives. Primitives usu <br>
? ally consist of an id (name or number) preceded by one or mo <br>
re <br>
qualifiers. There are three different kinds of qualifier: <br>
<br>
type qualifiers say what kind of thing the id name or numbe <br>
r <br>
refers to. Possible types are host, net and port. E.g. <br>
, <br>
`host foo', `net 128.3', `port 20'. If there is no typ <br>
e <br>
qualifier, host is assumed. <br>
<br>
dir qualifiers specify a particular transfer direction to and/o <br>
r <br>
from id. Possible directions are src, dst, src or dst an <br>
d <br>
src and dst. E.g., `src foo', `dst net 128.3', `src or ds <br>
t <br>
port ftp-data'. If there is no dir qualifier, src or dst i <br>
s <br>
assumed. For `null' link layers (i.e. point to point proto <br>
? cols such as slip) the inbound and outbound qualifiers c <br>
an <br>
be used to specify a desired direction. <br>
<br>
proto qualifiers restrict the match to a particular protocol <br>
. <br>
Possible protos are: ether, fddi, ip, arp, rarp, decnet <br>
, <br>
lat, sca, moprc, mopdl, tcp and udp. E.g., `ether src foo' <br>
, <br>
`arp net 128.3', `tcp port 21'. If there is no proto quali <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -