|
@@ -2,8 +2,92 @@
|
2
|
2
|
// Created by robin on 5/10/16.
|
3
|
3
|
//
|
4
|
4
|
|
|
5
|
+#include <pcap.h>
|
5
|
6
|
#include "Pcap.h"
|
6
|
7
|
|
|
8
|
+struct CustomPcapData {
|
|
9
|
+ Pcap* pcap;
|
|
10
|
+ void* data;
|
|
11
|
+ PcapCallback callback;
|
|
12
|
+};
|
|
13
|
+
|
7
|
14
|
Pcap::Pcap(const std::string &device)
|
|
15
|
+ : _device(device)
|
|
16
|
+ , _pcap(0)
|
|
17
|
+ , _isInLoop(false)
|
|
18
|
+{
|
|
19
|
+}
|
|
20
|
+
|
|
21
|
+Pcap::~Pcap()
|
|
22
|
+{
|
|
23
|
+ close();
|
|
24
|
+}
|
|
25
|
+
|
|
26
|
+ResultBool Pcap::init(int snaplen, bool promisc, int timeout)
|
|
27
|
+{
|
|
28
|
+ char errbuf[PCAP_ERRBUF_SIZE];
|
|
29
|
+ _pcap = pcap_open_live(_device.c_str(), snaplen, promisc, timeout, errbuf);
|
|
30
|
+ if (!_pcap) {
|
|
31
|
+ return ResultBool::error(errbuf);
|
|
32
|
+ }
|
|
33
|
+ return ResultBool::ok(true);
|
|
34
|
+}
|
|
35
|
+
|
|
36
|
+ResultString Pcap::getDefaultDevice()
|
|
37
|
+{
|
|
38
|
+ char errbuf[PCAP_ERRBUF_SIZE];
|
|
39
|
+ char* dev = pcap_lookupdev(errbuf);
|
|
40
|
+ if (!dev) {
|
|
41
|
+ return ResultString::error(errbuf);
|
|
42
|
+ }
|
|
43
|
+ return ResultString::ok(dev);
|
|
44
|
+}
|
|
45
|
+
|
|
46
|
+ResultBool Pcap::run(PcapCallback callback, void* data, int count)
|
|
47
|
+{
|
|
48
|
+ if (!_pcap) {
|
|
49
|
+ return ResultBool::error("Pcap has not been initialized");
|
|
50
|
+ }
|
|
51
|
+ CustomPcapData customData;
|
|
52
|
+ customData.pcap = this;
|
|
53
|
+ customData.data = data;
|
|
54
|
+ customData.callback = callback;
|
|
55
|
+ _isInLoop = true;
|
|
56
|
+ int res = pcap_loop(_pcap, count, [](u_char *args, const struct pcap_pkthdr *header, const u_char *packet) {
|
|
57
|
+ CustomPcapData* customData = (CustomPcapData*)args;
|
|
58
|
+ customData->pcap->onPacket(args, header, packet);
|
|
59
|
+ }, (u_char*)&customData);
|
|
60
|
+ _isInLoop = false;
|
|
61
|
+ if (res == -1) {
|
|
62
|
+ return ResultBool::error(getPcapLastError());
|
|
63
|
+ }
|
|
64
|
+ return ResultBool::ok(true);
|
|
65
|
+}
|
|
66
|
+
|
|
67
|
+void Pcap::onPacket(u_char* args, const struct pcap_pkthdr* header, const u_char* packet)
|
|
68
|
+{
|
|
69
|
+ CustomPcapData* customData = (CustomPcapData*)args;
|
|
70
|
+ if (!customData->callback(customData->data, header->caplen, (const char*)packet)) {
|
|
71
|
+ stop();
|
|
72
|
+ }
|
|
73
|
+}
|
|
74
|
+
|
|
75
|
+std::string Pcap::getPcapLastError() const
|
|
76
|
+{
|
|
77
|
+ return pcap_geterr(_pcap);
|
|
78
|
+}
|
|
79
|
+
|
|
80
|
+void Pcap::stop()
|
|
81
|
+{
|
|
82
|
+ if (_pcap && _isInLoop) {
|
|
83
|
+ pcap_breakloop(_pcap);
|
|
84
|
+ }
|
|
85
|
+}
|
|
86
|
+
|
|
87
|
+void Pcap::close()
|
8
|
88
|
{
|
|
89
|
+ if (_pcap) {
|
|
90
|
+ pcap_close(_pcap);
|
|
91
|
+ _pcap = 0;
|
|
92
|
+ }
|
9
|
93
|
}
|