Use libpcap for packet capture and package settlement on Ubuntu 14.04 64-bit

Source: Internet
Author: User

Use libpcap for packet capture and package settlement on Ubuntu 14.04 64-bit

For development purposes, I decided to use the latest libpcap source code package for installation. To install the libpcap library in a Unix environment, you must
C compiler, flex, bison, etc. These packages are not available when Ubuntu is installed. To install flex, the m4 compiling environment is required. Otherwise, the error "GNU M4 is required" is prompted.

1. Install the system dependency package
Sudo apt-get install gcc libc6-dev
Sudo apt-get install m4
Sudo apt-get install flex bison

2. Download and install libpcap source code
Download the latest libpcapversion from the official website http://www.tcpdump.org/
Cd/usr/local/src
Wget http://www.tcpdump.org/release/libpcap-1.5.3.tar.gz
Tar zxvf libpcap-1.5.3.tar.gz
Cd libpcap-1.5.3
./Configure
Make
Sudo make install

3. Install the dependent libraries required for development
Sudo apt-get install libpcap-dev

4. Test the libpcap applet named pcap_demo.c to check whether the environment is correctly configured.
# Include <pcap. h>
# Include <stdio. h>

Int main (int argc, char * argv [])
{
Pcap_t * handle;/* Session handle */
Char * dev;/* The device to sniff on */
Char errbuf [PCAP_ERRBUF_SIZE];/* Error string */
Struct bpf_program fp;/* The compiled filter */
Char filter_exp [] = "port 80";/* The filter expression */
Bpf_u_int32 mask;/* Our netmask */
Bpf_u_int32 net;/* Our IP */
Struct pcap_pkthdr header;/* The header that pcap gives us */
Const u_char * packet;/* The actual packet */


/* Define the device */
Dev = pcap_lookupdev (errbuf );
If (dev = NULL ){
Fprintf (stderr, "Couldn't find default device: % s \ n", errbuf );
Return (2 );
}
/* Find the properties for the device */
If (pcap_lookupnet (dev, & net, & mask, errbuf) =-1 ){
Fprintf (stderr, "Couldn't get netmask for device % s: % s \ n", dev, errbuf );
Net = 0;
Mask = 0;
}
/* Open the session in promiscuous mode */
Handle = pcap_open_live (dev, BUFSIZ, 1, 1000, errbuf );
If (handle = NULL ){
Fprintf (stderr, "Couldn't open device % s: % s \ n", dev, errbuf );
Return (2 );
}
/* Compile and apply the filter */
If (pcap_compile (handle, & fp, filter_exp, 0, net) =-1 ){
Fprintf (stderr, "Couldn't parse filter % s: % s \ n", filter_exp, pcap_geterr (handle ));
Return (2 );
}
If (pcap_setfilter (handle, & fp) =-1 ){
Fprintf (stderr, "Couldn't install filter % s: % s \ n", filter_exp, pcap_geterr (handle ));
Return (2 );
}
/* Grab a packet */
Packet = pcap_next (handle, & header );
/* Print its length */
Printf ("Jacked a packet with length of [% d] \ n", header. len );
/* And close the session */
Pcap_close (handle );
Return (0 );
}
Start Compilation:
Gcc-g pcap_demo.c-o pcap_demo-lpcap
Start execution
./Pcap_demo

5. Notes
. Be sure to use the root user for execution, or use sudo for common users to improve Permissions
Sudo pcap_demo
. Have a comprehensive understanding of some pcap api functions and update documents at any time. For example, the pcap_loop function. below is the man page address on the official website.
Http://www.tcpdump.org/manpages/pcap.3pcap.html
5.3. Understanding of some functions:
The difference between pcap_loop and pcap_dispatch is that the former will not return timeout, but will try to read more packets until an error occurs. The normal return value is 0, otherwise it is a negative value. I need to capture packets continuously, so I should use pcap_loop. Pcap_dispatch calls pcap_loop internally. The fourth parameter in pcap_loop is useful in some applications, but is usually set to NULL. This definition is very useful. For example, if you want to pass some additional parameters to the callback function of pcap_loop, you can use a u_char pointer (string ), upload the user to the callback function and then perform specific processing. Pcap_dispatch only processes the first packet it receives.
After returning from pcap_loop, we should explicitly call pcap_close to close pcap to release resources. To capture packets continuously, use-1 instead of 0 in pcap_loop. The callback function contains three parameters. The first parameter "user" is the last parameter in pcap_loop. It indicates an unimportant information, which can be ignored. The second parameter is the packet header information, which contains the packet Timestamp and length, the third parameter is the package data. Starting from the link layer header, it will not be released in the callback function. However, when the callback returns, it will not be legal to pack the data, so to use them again, copy them in advance.

Next, let's take a deeper look at the definition of the callback function pcap_loop:
First, note that the return value of the function is of the void type, which is fully logical, because pcap_loop does not know how to handle the return value of the callback function, that is, it does not make sense to output the return value to the callback function. Then, the first parameter of the callback function corresponds to the last parameter in pcap_loop. No matter what value you pass to the last parameter of pcap_loop, when the callback function is called, it will be passed to the callback function as the first parameter, and the second parameter is the pcap header. It contains information such as the packet capture time, package size, and so on. This structure is in the pcap. h is defined as follows:
Struct pcap_pkthdr {
Struct timeval ts;/* time stamp */
Bpf_u_int32 caplen;/* length of portion present */
Bpf_u_int32 len;/* length this packet (off wire )*/
};

There are two methods to capture packets. One is to capture one packet each time, and the other is to capture packets cyclically by a limited number or infinitely. The pcap_next function is used to capture a package each time. Pcap_next () indicates that only one packet is captured. The first parameter is session handle, the second parameter is the packet header, and the return value is the packet data. The function prototype is as follows:
U_char * pcap_next (pcap_t * p, struct pcap_pkthdr * h)
Another way to capture packets cyclically is to use pcap_loop and callback functions. for sample code, see the two examples I have compiled.


. There are two methods to set the NIC device. The first method is to directly specify the NIC name (which must be truly available) and pass it through the command line parameters. For example:
# Include <stdio. h>
# Include <pcap. h>


Int main (int argc, char * argv [])
{
Char * dev = argv [1];


Printf ("Device: % s \ n", dev );
Return (0 );
}
Another method is to allow the pcap to detect the NIC device by itself. If an error occurs, an error message is displayed. However, this method is not reliable in many cases, let pcap detect all Nic devices and let the user area select the network device to capture packets. See the following code
# Include <stdio. h>
# Include <pcap. h>


Int main (int argc, char * argv [])
{
Char * dev, errbuf [PCAP_ERRBUF_SIZE];


Dev = pcap_lookupdev (errbuf );
If (dev = NULL ){
Fprintf (stderr, "Couldn't find default device: % s \ n", errbuf );
Return (2 );
}
Printf ("Device: % s \ n", dev );
Return (0 );
}

5. 5. the structure of the captured data packet is roughly divided into Ethernet header, IP header, TCP header, and so on, corresponding to, 20 bytes respectively, and IP header at least 20 bytes, the TCP Header must contain at least 20 bytes.
Data = recv_data [42:] The reason for this is that recv_data caught is raw packet, TCP/IP is divided into five layers, a udp packet, it will carry the header of the 14Bytes Ethenet_II Frame, followed by the ip header of 20 bytes, And the udp header has 8 bytes, so the actual content of udp is after the offset of 42
The header size of a tcp packet is 20 Bytes, so the actual content is after the offset of 54.


5. 6. the definitions of common data structures such as Ethernet header, IP header, TCP header, and UDP header are required for packet unpacket and group packets. We do not need to redefine these headers, you can directly reference the relevant header file definition.
# Include <netinet/in. h>
# Include <netinet/if_ether.h>
# Include <netinet/ip. h>
# Include <netinet/tcp. h>
# Include <netinet/udp. h>
# Include <netinet/ip_icmp.h>

. For our current program, we usually need to pass the following parameter information from the command line:
Name of the network card to be captured in wlan0
Tcp port 80 filter expression
In the 10000 or-1 packet capture mode, whether to capture a specified number of packets (10000 packets here) or unlimited packet capture
Of course, you can also write these parameters to the program.

References
Http://www.tcpdump.org/pcap.html.

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.