5

In order to sniff from multiple interfaces using pcap, I would do the following (in pseudocode):

foreach interface:
    open a file descriptor using pcap_open_live()
    set the file descriptor to non-blocking

while true:
    check for a ready file descriptor using select() or an equivalent I/O multiplexer
    read data from every ready file descriptor using pcap_dispatch()
    handle EndOfStream or Errors and break out of loop if needed

Is this enough or are there some particular caveats to take into account ?

ziu
  • 2,634
  • 2
  • 24
  • 39

4 Answers4

2

Here is small C-Program snippet to use PCAP library to capture (sniff) network packets in promiscus (stealth) mode in the network.

#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>  /* GIMME a libpcap plz! */
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>  

void callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char* packet)
{
  static int count = 1;
  printf("\nPacket number [%d], length of this packet is: %d\n", count++, pkthdr->len);
}

void pktinit(char *dev) /*function: for individual interface packet capturing*/
{
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t* descr;
    struct bpf_program fp;        /* to hold compiled program */
    bpf_u_int32 pMask;            /* subnet mask */
    bpf_u_int32 pNet;             /* ip address*/
    pcap_if_t *alldevs, *d;
    char dev_buff[64] = {0};
    int i =0;
    pcap_lookupnet(dev, &pNet, &pMask, errbuf);
    descr = pcap_open_live(dev, BUFSIZ, 0,-1, errbuf);
    if(descr == NULL)
    {
        printf("pcap_open_live() failed due to [%s]\n", errbuf);
        return -1;
    }
    return 0;
}

int main(int argc, char **argv)
{
    int pid,i;
    if(argc < 2) /*command <eth0> [eth1]...*/
    {
        fprintf(strerr,"command needs ethernet name")
        return 0;
    }
    for(i = 1; i < argc; i++)
    {
        if((pid=fork()) != -1)
        {
            pktinit(argv[i])
        }
        else
        {
            fprintf(stderr,"pacp failed for: %s\n", argv[i]);
        }
    }
    return 0;
}

gcc file.c -lpcap

./file eth0 eth1 wlan0

Rahul Raina
  • 3,322
  • 25
  • 30
1

I ran into some issues trying to capture from particular interfaces with pcap and asked about it here. It seemed few were familiar with pcap. My issues, and an answer I finally got pointing out very helpful details, can be found here in the below link which you might find useful:

Confused by libcap (pcap) and wireless

Community
  • 1
  • 1
gnometorule
  • 2,151
  • 2
  • 20
  • 29
  • This doesn't address sniffing simultaneously from a certain set of interfaces, but select() (as you mention) should handle that as usual. – gnometorule Oct 27 '11 at 14:55
0

Man page of pcap_open_live(3) says:

pcap_open_live() is used to obtain a packet capture handle to look at packets on the network. device is a string that specifies the network device to open; on Linux systems with 2.2 or later kernels, a device argument of "any" or NULL can be used to capture packets from all interfaces.

The answer is in the last line.

So, use "any" or NULL in device parameter of pcap_open_live() call to capture from all interfaces.

SKi
  • 8,007
  • 2
  • 26
  • 57
  • I think that the question is about capturing from a sub-set of network interfaces. At least this is my case reading this question. "any"/"null" unfortunately does not help unless you can also use "en0|utun2". – Adrian Maire Jul 30 '21 at 12:04
-1

To capture packets from multiple network interfaces you need to call fork() new child process and then do pcap_lookupnet() and then pcap_open_live().

Note: You cannot use thread instead of create child process for each network interface.

Rahul Raina
  • 3,322
  • 25
  • 30