libpcap packet capture library multiple network adapters

Install libpcap library

First, install the associated support environment

sudo apt get install flex
sudo apt get install bison

Then download the latest version of libpcap, Download:http://www.tcpdump.org/

Decompression, enter the following command in the unzipped folder

./configure
make
make install

Single card capture DEMO

Single card packet capture library libpcap is very basic functions, here released a demo as a reference to facilitate comparison with the multi-card expansion.

The main function of a single card demo is input card heard by the user. When the user does not enter the card, the program will print all device names can listen, to be selected by the user monitor card, when (10000) monitor a certain number of the card, the program terminates.

//demo=single   
#include "pcap.h"   
#include "stdlib.h"
#include <time.h>
#include <arpa/inet.h>
#define SNAP_LEN 65536

//prototype of the packet handler 
void dispatcher_handler(u_char *temp1,
    const struct pcap_pkthdr *header, const u_char *pkt_data);
    
int main(int argc, char **argv)
{
    char *dev = NULL;            /* capture device name */
    char errbuf[PCAP_ERRBUF_SIZE];        /* error buffer */
    pcap_t *handle;                /* packet capture handle */
    pcap_if_t *alldev, *p;
    char filter_exp[] = "tcp";        /* filter expression [3] */
    struct bpf_program fp;            /* compiled filter program (expression) */
    bpf_u_int32 mask;            /* subnet mask */
    bpf_u_int32 net;            /* ip */
    int num_packets = 10000;            /* number of packets to capture */   
    /* check for capture device name on command-line */
    if (argc == 2) {
        dev = argv[1];
    }
    else if (argc > 2) {
        fprintf(stderr, "error: unrecognized command-line options\n\n");
        exit(EXIT_FAILURE);
    }
    else {
        /* find a capture device if not specified on command-line */ 
        int i=0,num;  
        if(pcap_findalldevs(&alldev,errbuf)==-1)  
        {  
            printf("find all devices is error\n");  
            return 0;  
        }  
        for(p=alldev;p;p=p->next)  
        {  
            printf("%d:%s\n",++i,p->name);  
            if(p->description)  
            {  
                printf("%s\n",p->description);  
            }  
        }  
        printf("please input which interface you want to use\n");  
        scanf("%d",&num);  
        if(num<1||num>i)  
        {  
            printf("interface is unavillible\n");  
            return 0;  
        }  
        for(p=alldev,i=1;i<=num;p=p->next,i++)  
            dev=p->name;  
        if (dev == NULL) {
            fprintf(stderr, "Couldn't find default device: %s\n",
             errbuf);
            exit(EXIT_FAILURE);
        }
    }
    /* print capture info */
    printf("Device: %s\n", dev);
    printf("Number of packets: %d\n", num_packets);
    printf("Filter expression: %s\n", filter_exp);
    /* open capture device */
    handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf);
    if (handle == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
        exit(EXIT_FAILURE);
    }
    /* make sure we're capturing on an Ethernet device [2] */
    if (pcap_datalink(handle) != DLT_EN10MB) {
        fprintf(stderr, "%s is not an Ethernet\n", dev);
        exit(EXIT_FAILURE);
    }
    /* compile the filter expression */
    if (pcap_compile(handle, &fp, filter_exp, 0, 24) == -1) {
        fprintf(stderr, "Couldn't parse filter %s: %s\n",
         filter_exp, pcap_geterr(handle));
        exit(EXIT_FAILURE);
    }
    /* apply the compiled filter */
    if (pcap_setfilter(handle, &fp) == -1) {
        fprintf(stderr, "Couldn't install filter %s: %s\n",
         filter_exp, pcap_geterr(handle));
        exit(EXIT_FAILURE);
    }
    /* now we can set our callback function */
    pcap_loop(handle, num_packets, dispatcher_handler, NULL);
    /* cleanup */
    pcap_freecode(&fp);
    pcap_close(handle);
    printf("\nCapture complete.\n");
return 0;
}

void dispatcher_handler(u_char *temp1,
    const struct pcap_pkthdr *header, const u_char *pkt_data)
{
    printf("I get one packet!\n");
}

Multi-card expansion

Since no libpcap library card can monitor multiple functions at the same time, according to the recommendations of friends, I decided to use a multi-threaded approach to open multiple threads are listening more than one card to resolve this problem. Here, for example to monitor dual-card will be given solutions, inadequacies also please the reader pointed out:

  • Similarly, the user can enter the name of the first two cards is to listen,sudo ./demo eth0 wlan0
  • When the user does not input parameters to listen on the card, the program name can be given to all listening devices, sequentially input by the user, to the two parameters are two processes used to monitor packets.
  • Termination condition regarding the program, the number of packets to the original decision is clearly unreasonable for the multi-card scene, listening instead to time decision: On the third execution threads sleep () function, the end of the third process, the front end of two a packet capture process.

code show as below:

//demo
#include "pcap.h"
#include <pthread.h>
#include "stdlib.h"
#include <time.h>
#include <arpa/inet.h>
#include "unistd.h"
#define SNAP_LEN 65535

/* prototype of the packet handler */
void dispatcher_handler(u_char *temp1,
    const struct pcap_pkthdr *header, const u_char *pkt_data);
void *thr_fn1(void *arg);
void *thr_fn2(void *arg);
void *thr_fn3(void *arg);

pcap_t *handle1, *handle2;                /* packet capture handle */
int CAP_TIME = 600;
pthread_t t1, t2, t3;

int main(int argc, char **argv)
{
    char *dev1 = NULL;
    char *dev2 = NULL;
    char errbuf[PCAP_ERRBUF_SIZE];        /* error buffer */
    pcap_if_t *alldev, *p;
    char filter_exp[] = "tcp";        /* filter expression [3] */
    struct bpf_program fp1,fp2;            /* compiled filter program (expression) */
    bpf_u_int32 mask;            /* subnet mask */
    bpf_u_int32 net;            /* ip */
     /* check for capture device name on command-line */
    if (argc == 3) {    //pre-define the two device's names to be captured
        dev1 = argv[1];
        dev2 = argv[2];
    }
    else if (argc > 3 || argc == 2) {
        fprintf(stderr, "error: unrecognized command-line options\n\n");        
        exit(EXIT_FAILURE);
    }
    else {
        /* find all capture device and tell the users to choose 2 if not specified on command-line */
        int i=0,num1,num2;  
        if(pcap_findalldevs(&alldev,errbuf)==-1)  
        {  
            printf("find all devices is error\n");  
            return 0;  
        }  
        for(p=alldev;p;p=p->next)  
        {  
            printf("%d:%s\n",++i,p->name);  
            if(p->description)  
            {  
                printf("%s\n",p->description);  
            }  
        }  
        printf("please input the 1st interface you want to use\n");  
        scanf("%d",&num1);  
        if(num1<1||num1>i)  
        {  
            printf("interface is unavillible\n");  
            return 0;  
        }  
        for(p=alldev,i=1;i<=num1;p=p->next,i++)  
            dev1=p->name; 

        printf("please input the 2nd interface you want to use\n");  
        scanf("%d",&num2);  
        if(num2<1 || num2>i || num2==num1)  
        {  
            printf("interface is unavillible\n");  
            return 0;  
        }  
        for(p=alldev,i=1;i<=num2;p=p->next,i++)  
            dev2=p->name; 
    }
    printf("please input the capture time\n");  
    scanf("%d",&CAP_TIME);    
    /* print capture info */
    printf("1st device: %s\n", dev1);
    /* open capture device */
    handle1 = pcap_open_live(dev1, SNAP_LEN, 1, 1000, errbuf);
    if (handle1 == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev1, errbuf);
        exit(EXIT_FAILURE);
    }
    /* make sure we're capturing on an Ethernet device [2] */
    if (pcap_datalink(handle1) != DLT_EN10MB) {
        fprintf(stderr, "%s is not an Ethernet\n", dev1);
        exit(EXIT_FAILURE);
    }
    /* compile the filter expression */
    if (pcap_compile(handle1, &fp1, filter_exp, 0, 24) == -1) {
        fprintf(stderr, "Couldn't parse filter %s: %s\n",
         filter_exp, pcap_geterr(handle1));
        exit(EXIT_FAILURE);
    }
    /* apply the compiled filter */
    if (pcap_setfilter(handle1, &fp1) == -1) {
        fprintf(stderr, "Couldn't install filter %s: %s\n",
         filter_exp, pcap_geterr(handle1));
        exit(EXIT_FAILURE);
    }
   /* print capture info */
    printf("2nd device: %s\n", dev2);
    printf("Filter expression: %s\n", filter_exp);  
    printf("Caputre time: %d\n", CAP_TIME);
    /* open capture device */
    handle2 = pcap_open_live(dev2, SNAP_LEN, 1, 1000, errbuf);
    if (handle2 == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev2, errbuf);
        exit(EXIT_FAILURE);
    }
    /* make sure we're capturing on an Ethernet device [2] */
    if (pcap_datalink(handle2) != DLT_EN10MB) {
        fprintf(stderr, "%s is not an Ethernet\n", dev2);
        exit(EXIT_FAILURE);
    }
    /* compile the filter expression */
    if (pcap_compile(handle2, &fp2, filter_exp, 0, 24) == -1) {
        fprintf(stderr, "Couldn't parse filter %s: %s\n",
         filter_exp, pcap_geterr(handle2));
        exit(EXIT_FAILURE);
    }
    /* apply the compiled filter */
    if (pcap_setfilter(handle2, &fp2) == -1) {
        fprintf(stderr, "Couldn't install filter %s: %s\n",
         filter_exp, pcap_geterr(handle2));
        exit(EXIT_FAILURE);
    }
    pthread_create(&t1, NULL, thr_fn1, NULL);  
    pthread_create(&t2, NULL, thr_fn2, NULL); 
    pthread_create(&t3, NULL, thr_fn3, NULL);       
    pthread_join(t1, NULL);  
    pthread_join(t2, NULL); 
    pthread_join(t3, NULL); 
    pcap_freecode(&fp1);
    pcap_freecode(&fp2);
    pcap_close(handle1);
    pcap_close(handle2);
    printf("\nCapture complete.\n");
return 0;
}
void dispatcher_handler(u_char *temp1,
    const struct pcap_pkthdr *header, const u_char *pkt_data)
{
    printf("I get one packet!\n");
}
void *thr_fn1(void *arg)
{
    pcap_loop(handle1, 0, dispatcher_handler, NULL);
    //pthread_cancel( t2 );
}
void *thr_fn2(void *arg)
{
    pcap_loop(handle2, 0, dispatcher_handler, NULL);
    //pthread_cancel( t1 );
}
void *thr_fn3(void *arg)
{
    sleep(CAP_TIME);
    pthread_cancel( t1 );
    pthread_cancel( t2 );
}

Compiling program needs to connect libpcap library and pthread library, use the commandgcc -g -w demo.cpp -o demo -lpcap -lpthread

Note: the sake of space, only the main loop a print instruction, different functions can be used alternatively other network resources.

Intelligent Recommendation

Linux network packet capture/packet capture technology comparison: napi, libpcap, afpacket, PF_RING, PACKET_MMAP, DPDK, XDP (eXpress Data Path)

Table of Contents 1. Traditional Linux network protocol stack process and performance analysis The main problem of the protocol stack Resource allocation and release for a single packet level Serial a...

Analysis of libpcap packet capture under linux

First, download the libpcap package first.http://www.tcpdump.org/#latest-release Then install, after the installation is complete, go to the tests folder of the installation root directory, compile an...

libpcap packet capture analysis project (2)

In project (1), we successfully captured the data packet and extracted the basic information in the data packet. This time we will output the various protocols used by the data packet and output the m...

libpcap packet capture analysis project (1)

First introduce the usage of libpcap library functions: Here I use two functions, pcap_open_live () and pcap_next (), you can jump through the portal to see the specific usage. The comments in the cod...

libpcap packet capture analysis project (4)

In project three, we completed the parsing of a package in the "hospital mirror stream.pcapng" file. The next thing we need to do is to write the parsed data into the file, so that the TS st...

More Recommendation

Analysis of libpcap packet capture mechanism (3)

At present, the network packet capture system under the Linux operating system is generally built on the libpcap packet capture platform. The English meaning of libpcap is Library of Packet Capture, t...

Analysis of libpcap packet capture mechanism (4)

1. Process and performance analysis of traditional Linux network protocol stack The Linux network protocol stack is a typical system for processing network packets. It includes the entire process from...

Use pf_ring to accelerate libpcap to capture packets on ubuntu16.04, Gigabit network runs smoothly without packet loss

Recently, the project needs to collect packets under the gigabit network, and the bandwidth is about 800Mb. Traditional sockets or raw sockets are easy to lose packets, so use libpcap to capture packe...

Design and implementation of network packet capture and traffic online analysis system-based on libpcap on MacOS Record this happy (DT) week

Design and implementation of network packet capture and traffic online analysis system-based on libpcap on MacOS Record this happy (DT) week Claim: Design and implement a network flow analysis system ...

Network packet capture technology memo - Wireshark/Fiddler/Libpcap/Npcap/WinPcap/SharpPcap

Link to this article:Memo for network packet capture technology - Junge V-CSDN blog 1. Common tools Browser comes with, such as Google Chrome's developer tools. Fiddler: Mainly to capture HTTP and HTT...

Copyright  DMCA © 2018-2026 - All Rights Reserved - www.programmersought.com  User Notice

Top