Abraham Abraham - 2 months ago 10
C++ Question

Why all the captured packet with libpcap in C++ have a length of zero?

I followed the steps mentioned here to write a sample CPP program to capture my network adapter traffic and the final program that I compiled and run successfully is as below:

1 #include <pcap.h>
2 #include <stdio.h>
3 #include <chrono>
4 #include <thread>
5
6 int main(int argc, char *argv[])
7 {
8 pcap_t *handle; /* Session handle */
9 char *dev; /* The device to sniff on */
10 char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */
11 struct bpf_program fp; /* The compiled filter */
12 char filter_exp[] = "port 23"; /* The filter expression */
13 bpf_u_int32 mask; /* Our netmask */
14 bpf_u_int32 net; /* Our IP */
15 struct pcap_pkthdr header; /* The header that pcap gives us */
16 const u_char *packet; /* The actual packet */
17
18 /* Define the device */
19 dev = pcap_lookupdev(errbuf);
20 if (dev == NULL) {
21 fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
22 return(2);
23 }
24
25 fprintf(stderr, "%s\n", dev);
26
27 /* Find the properties for the device */
28 if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
29 fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf);
30 net = 0;
31 mask = 0;
32 }
33 /* Open the session in promiscuous mode */
34 handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
35 if (handle == NULL) {
36 fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
37 return(2);
38 }
39 /* Compile and apply the filter */
40 if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
41 fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
42 return(2);
43 }
44 if (pcap_setfilter(handle, &fp) == -1) {
45 fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
46 return(2);
47 }
48
49 int x = 100;
50 for(int i=0; i<30; i++){
51 /* Grab a packet */
52 packet = pcap_next(handle, &header);
53 /* Print its length */
54 printf("Jacked a packet with length of [%d]\n", header.len);
55
56 std::this_thread::sleep_for(std::chrono::milliseconds(x));
57 }
58 /* And close the session */
59 pcap_close(handle);
60
61 return(0);
62 }


The problem is that, while my network adapter is selected correctly in the program, I only capture packets with len == 0!

ghasemi@ghasemi-MS-7693:~/Desktop/cpp_1$ g++ main.cpp -lpcap -std=gnu++11
ghasemi@ghasemi-MS-7693:~/Desktop/cpp_1$ sudo ./a.out
enp5s0
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]
Jacked a packet with length of [0]


My network configuration:

ghasemi@ghasemi-MS-7693:~/Desktop/cpp_1$ ifconfig
enp5s0 Link encap:Ethernet HWaddr 4c:cc:6a:0d:30:91
inet addr:192.168.1.170 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::fcb0:4105:1c21:4214/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:7377903 errors:0 dropped:0 overruns:0 frame:0
TX packets:5250371 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:10572328217 (10.5 GB) TX bytes:363236585 (363.2 MB)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:7403 errors:0 dropped:0 overruns:0 frame:0
TX packets:7403 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:2404900 (2.4 MB) TX bytes:2404900 (2.4 MB)

vmnet1 Link encap:Ethernet HWaddr 00:50:56:c0:00:01
inet addr:172.16.66.1 Bcast:172.16.66.255 Mask:255.255.255.0
inet6 addr: fe80::250:56ff:fec0:1/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:252 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

vmnet8 Link encap:Ethernet HWaddr 00:50:56:c0:00:08
inet addr:192.168.18.1 Bcast:192.168.18.255 Mask:255.255.255.0
inet6 addr: fe80::250:56ff:fec0:8/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:253 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

Answer

You compile a filter with "port 23", which is the telnet port. You read just 30 packets with 100 ms pause in between. This amounts to only 3 seconds. And you don't check the return code of pcap_next(), which most likely returns NULL, see pcap_next(3)

Return Value
...
pcap_next() returns a pointer to the packet data on success, and returns NULL if an error occured, or if no packets were read from a live capture

So, I would guess, there is no traffic at all to telnet in these 3 seconds, and if you would check packet, there were no output, e.g.

/* Grab a packet */
packet = pcap_next(handle, &header);
/* Print its length */
if (packet != NULL)
    printf("Jacked a packet with length of [%d]\n", header.len);