Преглед изворни кода

pcap packet capture

develop
Robin Thoni пре 8 година
родитељ
комит
c1f6f04b51
2 измењених фајлова са 110 додато и 0 уклоњено
  1. 84
    0
      src/DataAccess/Pcap.cpp
  2. 26
    0
      src/DataAccess/Pcap.h

+ 84
- 0
src/DataAccess/Pcap.cpp Прегледај датотеку

@@ -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
 }

+ 26
- 0
src/DataAccess/Pcap.h Прегледај датотеку

@@ -6,12 +6,38 @@
6 6
 #define ROZITM_PCAP_H
7 7
 
8 8
 #include <string>
9
+#include <functional>
10
+#include <pcap.h>
9 11
 #include "DBO/Result.h"
10 12
 
13
+typedef std::function<bool(void* userData, unsigned int len, const char* data)> PcapCallback;
14
+
11 15
 class Pcap
12 16
 {
13 17
 public:
14 18
     Pcap(const std::string& device);
19
+    ~Pcap();
20
+
21
+    ResultBool init(int snaplen = BUFSIZ, bool promisc = true, int timeout = 1000);
22
+
23
+    ResultBool run(PcapCallback callback, void* data = 0, int count = -1);
24
+
25
+    void stop();
26
+
27
+    void close();
28
+
29
+    std::string getPcapLastError() const;
30
+
31
+    static ResultString getDefaultDevice();
32
+
33
+protected:
34
+    const std::string _device;
35
+
36
+    pcap_t* _pcap;
37
+
38
+    bool _isInLoop;
39
+
40
+    void onPacket(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
15 41
 };
16 42
 
17 43
 

Loading…
Откажи
Сачувај