📄 541.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="516.htm">上一层</a>][<a href="542.htm">下一篇</a>]
<hr><p align="left"><small>函数库 libpcap(+SCO) 的安装及使用(转载) <br>
---------------------------------------------------------------------------- <br>
---- <br>
backend 于 2000-9-2 23:45:07 加贴在 绿盟科技论坛(bbs.nsfocus.com)--UNIX系统 <br>
安全: <br>
函数库 libpcap(+SCO) 的安装及使用 <br>
作者:bobdai, <bobdai@sohu.com> <br>
写在前面 <br>
我最近修改了 libpcap 函数库,使之能够支持 SCO OpenServer ,现将其文档放在 <br>
主页上供大家参考,请多指教! <br>
一、安装前的准备(仅SCO系统需要此步骤) <br>
首先应准备一个支持混杂模式(Promiscuous Mode)的网卡,如 3C509。按正常步骤 <br>
安装到系统中,然后按下列步骤做:1)、在/etc/default/boot文件中,将“ksl.disab <br>
le”加在“DEFBOOTSTR”串后;2)、在/var/opt/K/SCO/lli/5.0.4d/llimdi文件中,删 <br>
除或注释与相关网卡有关的相应行;3)、将/etc/rc2.d/S85tcp改名为/etc/rc2.d/S83t <br>
cp;4)、重新引导系统。 <br>
二、安装 libpcap <br>
1、解压、解包 libpcap+sco.tar.Z,进入 libpcap+sco 目录; <br>
2、进入 install-bpf 目录,输入 ./installbpf 安装BPF内核过滤器;(仅SCO系统需要 <br>
此步骤) <br>
3、返回 libpcap+sco 目录,输入 ./configure 生成 Makefile;(仅SCO系统需要此步 <br>
骤) <br>
4、输入 make 编译 <br>
5、输入 make install将生成的库安装到系统默认目录中。此目录为 /usr/lib ,如果 <br>
需要修改,可以修改文件 Makefile 的 prefix。 <br>
6、输入 make install-incl ,将头文件安装至系统默认目录,/usr/include,修改同 <br>
上。 <br>
7、安装完毕,如果以上任意一步出错,libpcap 将无法正常使用。 <br>
三、libpcap 的使用 <br>
1、头文件:#include <pcap.h> <br>
2、编译选项: cc .. -lpcap –lsocket .. <br>
3、主要数据结构及函数 <br>
pcap_t <br>
这个结构是我们使用 libpcap 库的核心数据结构,在程序的开始,调用 pcap_open_li <br>
ve() 将返回一个指向这个结构的指针,以后几乎调用库里的每一个函数都需要这个结构 <br>
作为参数。我们编程时需要涉及到的成员有:int fd; 打开设备的描述符;u_char *bu <br>
ffer; 是指向所捕获到数据的缓冲区指针。 <br>
struct pcap_stat <br>
包含两个可用成员:u_int ps_recv, u_int ps_drop 。调用函数 pcap_stats() 可以返 <br>
回一个该结构。两个成员分别为内核过滤器收到的包和丢弃的包。 <br>
struct bpf_hdr <br>
内核过滤器每输出一个包,将在输出的数据前加了20字节的数据,这就是 struct bpf_ <br>
hdr 。这个结构包含了三个可用成员:struct timeval bh_tstamp,接收此包的时间戳 <br>
;u_long bh_caplen,返回数据长度;u_long bh_datalen,实际包长度。 <br>
struct bpf_program <br>
此结构如果使用 tcpdump 表达式,则不用关心其内部结构。但如果要使用 BPF 程序, <br>
就需要知道其成员:struct bpf_insn *bf_insns,指向BPF指令所在空间;u_int bf_l <br>
en,BPF程序长度。 <br>
pcap_t *pcap_open_live() <br>
功能:打开监听设备 <br>
输入:第一个参数为 char *,指定要打开设备的名称。在SCO下这一参数设置为 NULL <br>
,SCO的这个函数能自动寻找可用设备。在别的系统下,必须调用函数 char *pcap_loo <br>
kupdev( char *errbuf );这个函数返回可用设备名,将其在传给 pcap_open_live 即 <br>
可。第二个参数为 int,指定从每个包返回数据的长度,例如,如果指定1000,那么长 <br>
度小于1000的包将返回其实际长度的全部数据;如果包长度大于1000,则返回包的前10 <br>
00字节。第三个参数为混杂标志,如果设定为1,将把网卡设置为混杂模式,监听全网段 <br>
。第四个参数为以毫秒计超时时限。第五个参数为出错消息字符串指针。 <br>
输出:指向结构 pcap_t 的指针 <br>
char *pcap_lookupdev() <br>
功能:获取可用监听设备。 <br>
输入:出错消息可用监听设备。 <br>
输出:可用监听设备字符串指针。 <br>
说明:由于SCO和其他系统在监听机制上的差异,SCO下这个函数返回的设备仅用于获取 <br>
子网掩码所用,并非我们真正要使用的设备。 <br>
int *pcap_lookupnet() <br>
功能:获取网络相关参数 <br>
输入:第一个参数为指向监听设备的字符串。第二、三个参数为指向bpf_u_int32 的指 <br>
针,分别为网络地址 localnet 和 子网掩码 netmask。第四个参数为出错消息字符串指 <br>
针。 <br>
输出:返回-1表示出错。 <br>
int pcap_compile() <br>
功能:编译 tcpdump 表达式为BPF程序。 <br>
输入:第一个参数为指向 pcap_t 的指针。第二个参数为指向结构 struct bpf_progra <br>
m 的指针,用于存放编译后的BPF程序。第三个参数为 tcpdump 表达式字符串指针。第 <br>
四个参数为优化编译标志。第五个参数为 bpf_u_int32 类型的子网掩码,要获得子网掩 <br>
码,可调用 pcap_lookupnet 函数。、 <br>
输出:返回-1表示出错。 <br>
int pcap_setfilter() <br>
功能:设置BPF内核过滤器。 <br>
输入:第一个参数为指向 pcap_t 的指针。第二个参数为指向结构 struct bpf_progra <br>
m 的指针,一般为 pcap_compile 编译后的结果,也可以手编BPF代码,详情参见 << B <br>
PF 程序的编写 >>。 <br>
输出:返回-1表示出错。 <br>
const u_char *pcap_next() <br>
功能:获取下一个包。 <br>
输入:第一个参数为指向 pcap_t 的指针。第二个参数为指向结构 struct pcap_pkthd <br>
r 的指针,与 struct bpf_hdr 几乎完全一样。例程序里我没有用他。返回的数据都放 <br>
在 pcap_t 的 buffer 中。 <br>
int pcap_stats() <br>
功能:获取BPF内核过滤器的状态。 <br>
输入:第一个参数为指向 pcap_t 的指针。第二个参数为指向结构struct pcap_stat 的 <br>
指针,返回的状态数据将存放在这个结构里。 <br>
int pcap_geterr() <br>
功能:获取上一条出错消息 <br>
输入:一个指向 pcap_t 的指针。 <br>
输出:出错消息字符串指针。 <br>
4、基本运行模式 <br>
打开设备 <br>
在SCO下直接使用pcap_open_live(),在其他系统下先调用 pcap_lookupdev(),获取可 <br>
用设备,再调用 pcap_open_live()。在SCO下,如果想取得子网掩码,供 pcap_compil <br>
e 使用,也需要调用pcap_lookupdev(),再调用 pcap_lookupnet()。 <br>
设置过滤规则 <br>
给定 tcpdump 表达式字符串,调用 pcap_compile() 编译他,再调用 pcap_setfilter <br>
() 设置BPF内核过滤器。关于 tcpdump 表达式字符串的编写方法,请参看附录B。 <br>
获取数据 <br>
不断调用 pcap_next() 函数即可一个一个的获取过滤器输出的包。 <br>
状态及出错消息 <br>
pcap_stats() 可获取过滤器当前状态,pcap_geterr() 可获取上一次的出错消息。 <br>
5、一个例子 <br>
libpcap+sco.tar.Z 解开后,主目录下会有一个 pcap0.c 文件,是使用 libpcap 库的 <br>
例程序,读一读这些源码对理解、使用会很有帮助。附录A里有这个程序的全部源码,并 <br>
加入了一些中文注释。 <br>
四、兼容性 <br>
1、SCO系统下的打开设备方式与别的系统不完全相同。别的系统,也就是库的原来设计 <br>
者设计的打开过程是:调用 pcap_lookupdev() 获得可用监听设备 char *dev,然后将 <br>
其作为参数传递给 pcap_open_live() 打开设备。而在SCO下不用先调用 pcap_lookupd <br>
ev() ,直接传递 NULL 的 char *dev 给pcap_open_live() 即可。 <br>
2、原来的库支持脱机方式监听网络( pcap_open_offline() ),即支持将截获的数据先 <br>
存入磁盘文件,再使用这些磁盘文件进行脱机监听。我对这一机制没有更深的研究,也 <br>
没有测试过,建议不使用。 <br>
附录A 例程序 pcap0.c <br>
/* <br>
* A sample program using libpcap for SCO <br>
* <br>
* Author bobdai, May 2000 <br>
*/ <br>
/* cc a.c -lpcap -lsocket */ <br>
#include <stdio.h> <br>
#include <string.h> <br>
#include <pcap.h> <br>
main() <br>
{ <br>
int i; <br>
int i; <br>
char exp[8192], errbuf[PCAP_ERRBUF_SIZE]; <br>
pcap_t *p; <br>
char *dev; <br>
struct pcap_pkthdr h; <br>
struct pcap_stat ps; <br>
struct bpf_program bp; <br>
struct bpf_hdr *bh; <br>
bpf_u_int32 localnet, netmask; <br>
if( (p=pcap_open_live(NULL, 1000, 1, 1000, errbuf)) == NULL ) <br>
{ <br>
printf( "pcap_open_live: %s\n", errbuf ); <br>
exit(0); <br>
} <br>
if( (dev=pcap_lookupdev(errbuf)) == NULL) <br>
printf( "%s\n", errbuf ); <br>
if( pcap_lookupnet(dev, &localnet, &netmask, errbuf) <0 ) <br>
printf( "%s\n", errbuf ); <br>
printf( "localnet=%.8x netmask=%.8x\n", localnet, netmask ); <br>
/* set BPF filter */ <br>
/* 下面这句 tcpdump 过滤规则表达式的含义是:接收源IP地址为 192.168.0.1 且设置 <br>
了 SYN 标志的 TCP 分节。从 TCP 头部开始处偏移为13字节的值为2,即SYN 标志。tc <br>
pdump 过滤表达式的写法见附录B。 <br>
*/ <br>
strcpy( exp, "src host 192.168.0.1 and tcp[13:1] & 2 != 0" ); <br>
if( pcap_compile(p, &bp, exp, 1, netmask ) <0 ) <br>
printf( "%s\n", pcap_geterr(p) ), exit(0); <br>
if( pcap_setfilter(p, &bp) <0 ) <br>
printf( "%s\n", pcap_geterr(p) ), exit(0); <br>
for(;;){ /* Begin ... @!@ */ <br>
pcap_next( p, &h ); /* Get next packet */ <br>
bh = ( struct bpf_hdr *)p->buffer; /* The first 20 bytes is the bpf_h <br>
dr */ <br>
pcap_stats( p, &ps ); /* Get stats of BPF module */ <br>
printf( "caplen=%d datalen=%d recv=%d drop=%d\n", <br>
bh->bh_caplen, bh->bh_datalen, <br>
ps.ps_recv, ps.ps_drop ); <br>
for( i=0; i<(int)bh->bh_caplen; i++ ) /* Display the data */ <br>
{ <br>
/* Real data is begin at buffer+20 */ <br>
printf( "%.2x ", *((p->buffer+20)+i) ); <br>
if( (i+1)%16 == 0 ) printf( "\n" ); <br>
} <br>
printf( "\n" ); <br>
} /* end of for(;;) */ <br>
} <br>
=== 说难不难,说易不易。=== <br>
</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="516.htm">上一层</a>][<a href="542.htm">下一篇</a>]
<p align="center"><a href="http://cterm.163.net">欢迎访问Cterm主页</a></p>
</table>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -