-
Notifications
You must be signed in to change notification settings - Fork 0
/
Filter.cpp
103 lines (95 loc) · 1.7 KB
/
Filter.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include "Filter.h"
Filter::Filter(QObject* parent)
{
}
Filter::~Filter()
{}
void Filter::setDev(QString path)
{
char source[PCAP_BUF_SIZE];
char errbuf[PCAP_ERRBUF_SIZE];
if (pcap_createsrcstr(
source,
PCAP_SRC_FILE,
NULL,
NULL,
path.toLatin1(),
errbuf
) != 0)
{
return;
}
dev = DevMsg{
QString(source),
path,
0xffffff
};
}
void Filter::setFilter(QString f)
{
filter = f;
}
bool Filter::validateFilter(QString filter)
{
struct bpf_program fcode;
return pcap_compile_nopcap(65536, 0, &fcode, filter.toLatin1(), 1, dev.netmask) >= 0;
}
bool Filter::openAdapter()
{
// open adaptor
char errbuf[PCAP_ERRBUF_SIZE];
char source[PCAP_BUF_SIZE];
if ((adhandle = pcap_open(
(const char*)(dev.name.toLatin1()),
65536,
PCAP_OPENFLAG_PROMISCUOUS,
READ_PACKET_TIMEOUT,
NULL,
errbuf
)) == NULL) {
return false;
}
return true;
}
void Filter::closeAdapter()
{
if (adhandle)
{
pcap_close(adhandle);
adhandle = NULL;
}
}
void Filter::startFilter()
{
// open adaptor
if (!openAdapter())
{
emit filterStopped();
return;
}
// compile filter
if (pcap_compile(adhandle, &fcode, filter.toLatin1(), 1, dev.netmask) < 0 ||
pcap_setfilter(adhandle, &fcode) < 0)
{
emit filterStopped();
return;
}
// start catch
int res;
struct pcap_pkthdr* header;
const u_char* pkt_data;
int num = 0;
StreamPool streams;
filtering = true;
while (filtering && (res = pcap_next_ex(adhandle, &header, &pkt_data)) >= 0) {
if (res == 0) continue;
Packet* pkt = new Packet(header, pkt_data, num++, &streams);
// process signals and events
emit newPacketFiltered(pkt);
}
// stopped with an error or EOF
if (filtering && (res == -1 || res == -2)) {
emit filterStopped();
return;
}
}