-
Notifications
You must be signed in to change notification settings - Fork 1
/
PacketCatcher.cpp
212 lines (189 loc) · 4.67 KB
/
PacketCatcher.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#include "stdafx.h"
#include "PacketCatcher.h"
#include "Packet.h"
#include "ThreadParam.h"
#define HAVE_REMOTE
#include "pcap.h"
PacketCatcher::PacketCatcher()
{
m_adhandle = NULL;
m_pool = NULL;
m_dumper = NULL;
m_devlist = NULL;
}
PacketCatcher::PacketCatcher(PacketPool * pool)
{
m_adhandle = NULL;
m_pool = pool;
m_dumper = NULL;
m_devlist = NULL;
}
PacketCatcher::~PacketCatcher()
{
m_adhandle = NULL;
m_pool = NULL;
m_dumper = NULL;
if (m_devlist)
{
pcap_freealldevs(m_devlist);
m_devlist = NULL;
}
}
bool PacketCatcher::setPool(PacketPool *pool)
{
if (pool)
{
m_pool = pool;
return true;
}
return false;
}
/**
* @brief Open the specified network card and obtain the network card descriptor adhandle
* @param selItemIndexOfDevList The subscript of the selected item in the network card list
* @return true Open successfully false fail
*/
bool PacketCatcher::openAdapter(int selItemIndexOfDevList, const CTime ¤tTime)
{
if (selItemIndexOfDevList < 0 || m_adhandle)
return false;
int count = 0, selDevIndex = selItemIndexOfDevList - 1;
//pcap_if_t *dev, *allDevs;
//char errbuf[PCAP_ERRBUF_SIZE + 1];
//if (pcap_findalldevs(&allDevs, errbuf) == -1)
//{
// AfxMessageBox(_T("pcap_findalldevsmistake!"), MB_OK);
// return false;
//}
//for (dev = allDevs; count < selDevIndex; dev = dev->next, ++count);
pcap_if_t* dev;
for (dev = m_devlist; count < selDevIndex; dev = dev->next, ++count);
// Network card information copy
m_dev = dev->description + CString(" ( ") + dev->name + " )";
// Open network card
if ((m_adhandle = pcap_open_live(dev->name,
65535, // maximum capture length
PCAP_OPENFLAG_PROMISCUOUS, // Set the network card to promiscuous mode
READ_PACKET_TIMEOUT, // Read timeout
NULL)) == NULL)
{
AfxMessageBox(_T("pcap_open_livemistake!"), MB_OK);
return false;
}
/* Open dump file */
CString file = "kendoUI_" + currentTime.Format("%Y%m%d%H%M%S") + ".pcap";
CString path = ".\\tmp\\" + file;
m_dumper = pcap_dump_open(m_adhandle, path);
//pcap_freealldevs(allDevs);
return true;
}
/**
* @brief Open the specified file and obtain the file descriptor adhandle
* @param path file path
* @return true Open successfully false fail
*/
bool PacketCatcher::openAdapter(CString path)
{
if (path.IsEmpty())
return false;
m_dev = path;
if ( (m_adhandle = pcap_open_offline(path, NULL)) == NULL)
{
AfxMessageBox(_T("pcap_open_offlinemistake!"), MB_OK);
return false;
}
return true;
}
/**
* @brief Close an open network card
* @param -
* @return true Close successfully false Close failed
*/
bool PacketCatcher::closeAdapter()
{
if (m_adhandle)
{
pcap_close(m_adhandle);
m_adhandle = NULL;
if (m_dumper)
{
pcap_dump_close(m_dumper);
m_dumper = NULL;
}
return true;
}
return false;
}
/**
* @brief Start capturing packets
* @param -
* @return -
*/
void PacketCatcher::startCapture(int mode)
{
if (m_adhandle && m_pool)
AfxBeginThread(capture_thread, new ThreadParam(m_adhandle, m_pool, m_dumper, mode));
}
/**
* @brief ͣ Stop capturing packets
* @param -
* @return -
*/
void PacketCatcher::stopCapture()
{
if (m_adhandle)
pcap_breakloop(m_adhandle);
}
CString PacketCatcher::getDevName()
{
return m_dev;
}
void PacketCatcher::setDevList(pcap_if_t *devlist)
{
m_devlist = devlist;
}
/**
* @brief Capture packet thread entry function, global function
* @param pParam Parameters passed to the thread
* @return 0 Indicates that the packet capture was successful -1 indicates that the packet capture failed
*/
UINT capture_thread(LPVOID pParam)
{
ThreadParam *p = (ThreadParam*)pParam;
/* Start capturing packets */
pcap_loop(p->m_adhandle, -1, packet_handler, (unsigned char *)p);
PostMessage(AfxGetMainWnd()->m_hWnd, WM_TEXIT, NULL, NULL);
return 0;
}
/**
* @brief Capture packet processing function, global callback function
* @param param Custom parameters
* @param header Packet header
* @param pkt_data Packet (frame)
* @return
*/
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
ThreadParam *threadParam = (ThreadParam *)param;
// Capture packets according to capture mode
switch (threadParam->m_mode)
{
case MODE_CAPTURE_LIVE:
{
threadParam->m_pool->add(header, pkt_data);
pcap_dump((u_char*)threadParam->m_dumper, header, pkt_data);
break;
}
case MODE_CAPTURE_OFFLINE:
{
threadParam->m_pool->add(header, pkt_data);
break;
}
}
// Send message to main window kendoUIDlg
PostMessage(AfxGetMainWnd()->m_hWnd, WM_PKTCATCH, NULL, (LPARAM)(threadParam->m_pool->getLast().num));
// If the packet is captured online, let the thread sleep for 0.5 seconds to prevent the interface from freezing.
if (threadParam->m_mode == MODE_CAPTURE_LIVE) {
Sleep(500);
}
}