Some of the pcap source code, entry-level

Source: Internet
Author: User
/* Pcap_1.c */# include <stdio. h>
# Include <stdlib. h>
# Include <pcap. h>/* if there is no pcap system, you need to download one by yourself */
# Include <errno. h>
# Include <sys/socket. h>
# Include <netinet/in. h>
# Include <ARPA/inet. h>

Int main (INT argc, char ** argv)
{
Char * dev;/* Name of the device to use */
Char * Net;/* dot notation of the network address */
Char * mask;/* dot notation of the network mask */
Int ret;/* return code */
Char errbuf [pcap_errbuf_size];
Bpf_u_int32 netp;/* IP */
Bpf_u_int32 maskp;/* subnet mask */
Struct in_addr ADDR;

/* Ask pcap to find a valid device for use to sniff on */
Dev = pcap_lookupdev (errbuf );

/* Error checking */
If (Dev = NULL)
{
Printf ("% s/n", errbuf );
Exit (1 );
}

/* Print out device name */
Printf ("Dev: % s/n", Dev );

/* Ask pcap for the network address and mask of the device */
Ret = pcap_lookupnet (Dev, & netp, & maskp, errbuf );

If (ret =-1)
{
Printf ("% s/n", errbuf );
Exit (1 );
}

/* Get the network address in a human readable form */
ADDR. s_addr = netp;
Net = inet_ntoa (ADDR );

If (net = NULL)/* Thanks SCOTT:-p */
{
Perror ("inet_ntoa ");
Exit (1 );
}

Printf ("Net: % s/n", net );

/* Do the same as above for the device's mask */
ADDR. s_addr = maskp;
Mask = inet_ntoa (ADDR );

If (mask = NULL)
{
Perror ("inet_ntoa ");
Exit (1 );
}

Printf ("Mask: % s/n", mask );

Return 0;
}
Then, compile the GCC-O pcap_1 pcap_1.c-lpcap (must be the-lpcap parameter) to OK ~, Run./pcap_1. You can see Dev: eth0.
Net: 192.168.12.0
Mask: 255.255.255.0 is good. The first pcap program is released ..... But (of course, but what else I will write later), the above program did nothing except show us pcap_lookupdev and pcap_lookupnet. Well, let's continue, write our first packet capture program. /* Pcap_2.c */# include <stdio. h>
# Include <stdlib. h>
# Include <pcap. h>/* If this gives you an error try pcap/pcap. H */
# Include <errno. h>
# Include <sys/socket. h>
# Include <netinet/in. h>
# Include <ARPA/inet. h>
# Include <netinet/if_ether.h>/* Includes net/Ethernet. H */

Int main (INT argc, char ** argv)
{
Int I;
Char * dev;
Char errbuf [pcap_errbuf_size];
Pcap_t * descr;/* You can man It */
Const u_char * packet;
Struct pcap_pkthdr HDR;/* pcap. H */
Struct ether_header * eptr;/* Net/Ethernet. H */

U_char * PTR;/* printing out hardware header info */

/* Grab a device to peak ...*/
Dev = pcap_lookupdev (errbuf );

If (Dev = NULL)
{
Printf ("% s/n", errbuf );
Exit (1 );
}

Printf ("Dev: % s/n", Dev );

/* Open the device for sniffing.

Pcap_t * pcap_open_live (char * device, int snaplen, int prmisc, int to_ms,
Char * ebuf)

Snaplen-maximum size of packets to capture in bytes
Promisc-set card in promiscuous mode?
To_ms-time to wait for packets in miliseconds before read
Times out
Errbuf-if something happens, Place Error string here

Note if you change "prmisc" Param to anything other than zero, you will
Get all packets your device sees, whether they are intendeed for you or
Not !! Be sure you know the rules of the network you are running on
Before you set your card in promiscuous mode !! */

Descr = pcap_open_live (Dev, bufsiz, 0,-1, errbuf );

If (descr = NULL)
{
Printf ("pcap_open_live (): % s/n", errbuf );
Exit (1 );
}


/*
Grab a packet from descr (yay !)
U_char * pcap_next (pcap_t * P, struct pcap_pkthdr * H)
So just pass in the descriptor we got from
Our call to pcap_open_live and an allocated
Struct pcap_pkthdr */

Packet = pcap_next (descr, & HDR );

If (packet = NULL)
{/* Dinna work * sob **/
Printf ("didn't grab packet/N ");
Exit (1 );
}

/* Struct pcap_pkthdr {
Struct timeval ts; Time Stamp
Bpf_u_int32 caplen; length of portion present
Bpf_u_int32; lebgth this packet (Off wire)
}
*/

Printf ("grabbed packet of length % d/N", HDR. Len );
Printf ("Recieved at... % s/n", ctime (const time_t *) & HDR. Ts. TV _sec ));
Printf ("ethernet address length is % d/N", ether_hdr_len );

/* Lets start with the ether header ...*/
Eptr = (struct ether_header *) packet;

/* Do a couple of checks to see what packet type we have ..*/
If (ntohs (eptr-> ether_type) = ethertype_ip)
{
Printf ("Ethernet Type HEX: % x dec: % d is an IP packet/N ",
Ntohs (eptr-> ether_type ),
Ntohs (eptr-> ether_type ));
} Else if (ntohs (eptr-> ether_type) = ethertype_arp)
{
Printf ("Ethernet Type HEX: % x dec: % d is an ARP packet/N ",
Ntohs (eptr-> ether_type ),
Ntohs (eptr-> ether_type ));
} Else {
Printf ("Ethernet Type % x not IP", ntohs (eptr-> ether_type ));
Exit (1 );
}

/* Thank you Richard Steven s !!! Rip */
PTR = eptr-> ether_dhost;
I = ether_addr_len;
Printf ("Destination Address :");
Do {
Printf ("% S % x", (I = ether_addr_len )? "": ":", * PTR ++ );
} While (-- I> 0 );
Printf ("/N ");

PTR = eptr-> ether_shost;
I = ether_addr_len;
Printf ("Source Address :");
Do {
Printf ("% S % x", (I = ether_addr_len )? "": ":", * PTR ++ );
} While (-- I> 0 );
Printf ("/N ");

Return 0;
}
All right, compile and run it! [[Email protected] libpcap] #./pcap_2dev: eth0
Grabbed packet of length 76
Recieved at time... mon Mar 12 22:23:29 2001

Ethernet address length is 14
Ethernet Type HEX: 800 dec: 2048 is an IP packet
Destination Address: 0: 20: 78: D1: E8: 1
Source Address: 0: A0: CC: 56: C2: 91
[[Email protected] libpcap] # Someone may have waited for half a day without a package. There is a good way to open another console and ping a website, such as Google ~~, Haha, there will be a response immediately ~~ This program is written by a foreigner. Let's see if there is no problem with the annotations ~ But we also found a problem, that is, the above program can only capture one package. What should we do if we keep capturing the package? What should we do with loops ?? Libpcap provides a better method: int pcap_loop (pcap_t * P, int CNT, pcap_handler callback, u_char * User). This function can continuously capture Ethernet packets, CNT is the number of captures, and callback is the processing function. How to Write this processing function? You can see pcap_3.c. What is the USER parameter? Don't ask me. I don't know either. /* Pcap_3.c */# include <pcap. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <errno. h>
# Include <sys/socket. h>
# Include <netinet/in. h>
# Include <ARPA/inet. h>
# Include <netinet/if_ether.h>

/* Callback function that is passed to pcap_loop (...) and called each time
* A packet is recieved */
Void my_callback (u_char * useless, const struct pcap_pkthdr * pkthdr, const u_char *
Packet)
{
Static int COUNT = 1;
Fprintf (stdout, "% d,", count );
If (COUNT = 4)
Fprintf (stdout, "Come on baby sayyy you love me !!! ");
If (COUNT = 7)
Fprintf (stdout, "tiiimmmeesss !! ");
Fflush (stdout );
Count ++;
}

Int main (INT argc, char ** argv)
{
Int I;
Char * dev;
Char errbuf [pcap_errbuf_size];
Pcap_t * descr;
Const u_char * packet;
Struct pcap_pkthdr HDR;/* pcap. H */
Struct ether_header * eptr;/* Net/Ethernet. H */

If (argc! = 2) {fprintf (stdout, "Usage: % s numpackets/N", argv [0]); Return 0 ;}

/* Grab a device to peak ...*/
Dev = pcap_lookupdev (errbuf );
If (Dev = NULL)
{Printf ("% s/n", errbuf); exit (1 );}
/* Open device for reading */
Descr = pcap_open_live (Dev, bufsiz, 0,-1, errbuf );
If (descr = NULL)
{Printf ("pcap_open_live (): % s/n", errbuf); exit (1 );}

/* Allright here we call pcap_loop (...) and pass in our callback function */
/* Int pcap_loop (pcap_t * P, int CNT, pcap_handler callback, u_char * User )*/
Pcap_loop (descr, atoi (argv [1]), my_callback, null );

Fprintf (stdout, "/ndone processing packets... wheew! /N ");
Return 0;
} Run./pcap_3 7
1, 2, 3, 4, come on baby sayyy you love me !!! 5, 6, 7, tiiimmmeesss !!
Done processing packets... wheew! Pcap_loop is really easy to use, but if there is no package, just wait there, pcap_dispatch contains a timeout function. The following is a passage in Man: pcap_dispatch () is used to collect and process packets. CNT specifies the maximum number of packets to process before returning. a cnt of-1 processes all the packets passed ed in one buffer. a cnt of 0 processes all packets until an error occurs, EOF is reached, or the read times out (when doing live reads and a non-zero read T Imeout is specified ). callback specifies a routine to be called with three arguments: A u_char pointer which is passed in from pcap_dispatch (), a pointer to the specified struct (which precede the actual network headers and data ), and a u_char pointer to the packet data. the number of packets read is returned. zero is returned when EOF is reached in a'' SaveFile. 'A return of-1 indicates an ER Ror in which case pcap_perror () or pcap_geterr () may be used to display the error text. another problem is that we may have a headache for grabbing too many bags. Many of them may not be the ones we are interested in. Don't worry. pcap_compile and pcap_setfilter can help us solve the problem. /* Pcap_4.c */# include <pcap. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <errno. h>
# Include <sys/socket. h>
# Include <netinet/in. h>
# Include <ARPA/inet. h>
# Include <netinet/if_ether.h>

/* Just print a count every time we have a packet ...*/
Void my_callback (u_char * useless, const struct pcap_pkthdr * pkthdr, const u_char *
Packet)
{
Static int COUNT = 1;
Fprintf (stdout, "% d,", count );
Fflush (stdout );
Count ++;
}

Int main (INT argc, char ** argv)
{
Int I;
Char * dev;
Char errbuf [pcap_errbuf_size];
Pcap_t * descr;
Const u_char * packet;
Struct pcap_pkthdr HDR;/* pcap. H */
Struct ether_header * eptr;/* Net/Ethernet. H */
Struct bpf_program FP;/* Hold compiled program */
Bpf_u_int32 maskp;/* subnet mask */
Bpf_u_int32 netp;/* IP */


If (argc! = 2) {fprintf (stdout, "Usage: % S/" filter program/"/N"
, Argv [0]); Return 0 ;}

/* Grab a device to peak ...*/
Dev = pcap_lookupdev (errbuf );
If (Dev = NULL)
{Fprintf (stderr, "% s/n", errbuf); exit (1 );}

/* Ask pcap for the network address and mask of the device */
Pcap_lookupnet (Dev, & netp, & maskp, errbuf );

/* Open device for reading this time lets set it in promiscuous
* Mode so we can monitor traffic to another machine */
Descr = pcap_open_live (Dev, bufsiz, 1,-1, errbuf );
If (descr = NULL)
{Printf ("pcap_open_live (): % s/n", errbuf); exit (1 );}

/* Lets try and compile the program .. non-optimized */
If (pcap_compile (descr, & FP, argv [1], 0, netp) =-1)
{Fprintf (stderr, "error calling pcap_compile/N"); exit (1 );}

/* Set the compiled program as the filter */
If (pcap_setfilter (descr, & FP) =-1)
{Fprintf (stderr, "error setting filter/N"); exit (1 );}

/*... And loop */
Pcap_loop (descr,-1, my_callback, null );

Return 0;
}

Run./pcap_4.c "host www.google.com" and Ping www.baidu.com in another console. Haha, no response. Then ping www.google.com.
We can see 1, 2, 3, 4, 5, 6, okyou got it !!

Some of the pcap source code, entry-level

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.