为什么在 C++ 中使用 libpcap 捕获的所有数据包的长度都为零?
Why all the captured packet with libpcap in C++ have a length of zero?
我按照提到的步骤 here 编写了一个示例 CPP 程序来捕获我的网络适配器流量,我编译并 运行 成功的最终程序如下所示:
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 }
问题是,虽然在程序中正确选择了我的网络适配器,但我只捕获了 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]
我的网络配置:
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)
您使用 "port 23"
编译过滤器,这是 telnet 端口。您只读取了 30 个数据包,中间有 100 毫秒的暂停。这总计只有 3 秒。而且你不检查 pcap_next()
的 return 代码,这很可能是 returns NULL
,请参阅 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
所以,我猜,在这 3 秒内根本没有任何 telnet 流量,如果你检查 packet
,没有输出,例如
/* 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);
我按照提到的步骤 here 编写了一个示例 CPP 程序来捕获我的网络适配器流量,我编译并 运行 成功的最终程序如下所示:
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 }
问题是,虽然在程序中正确选择了我的网络适配器,但我只捕获了 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]
我的网络配置:
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)
您使用 "port 23"
编译过滤器,这是 telnet 端口。您只读取了 30 个数据包,中间有 100 毫秒的暂停。这总计只有 3 秒。而且你不检查 pcap_next()
的 return 代码,这很可能是 returns NULL
,请参阅 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
所以,我猜,在这 3 秒内根本没有任何 telnet 流量,如果你检查 packet
,没有输出,例如
/* 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);