⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 548.htm

📁 unix高级编程原吗
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<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 + -