2023-03-20 11:30:19 +08:00
|
|
|
#include "pcaprethread.h"
|
2023-06-06 12:13:33 +08:00
|
|
|
#include "pcap.h"
|
|
|
|
#include "globalfunc.h"
|
2023-03-20 11:30:19 +08:00
|
|
|
|
|
|
|
PcapReThread::PcapReThread(pcap_t *pcap) : pcap(pcap) {
|
2023-06-06 12:13:33 +08:00
|
|
|
qRegisterMetaType<FuncIntByte>("FuncIntByte");
|
2023-03-20 11:30:19 +08:00
|
|
|
connect(this, &QThread::finished, this, &QThread::deleteLater);
|
2023-06-06 12:13:33 +08:00
|
|
|
connect(this, &PcapReThread::onMsg, this, [](FuncIntByte callback, int code, const QByteArray data) {
|
|
|
|
callback(code, data);
|
2023-03-20 11:30:19 +08:00
|
|
|
});
|
|
|
|
}
|
2023-06-06 12:13:33 +08:00
|
|
|
PcapReThread::~PcapReThread() {
|
|
|
|
pcap_close(pcap);
|
|
|
|
}
|
|
|
|
|
|
|
|
int PcapReThread::sendMsgNet(const byte *msg, int size, int id, qint64 timeout, FuncIntByte callback, WaitingDlg *waitingDlg) {
|
|
|
|
int res;
|
|
|
|
PcapResp *resp;
|
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> lock(mtx);
|
|
|
|
res = pcap_sendpacket(pcapSend, msg, size);
|
|
|
|
if(res==0) {
|
|
|
|
if(timeout==0) timeout = 30000;
|
|
|
|
timeout += std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
|
|
|
|
resps.append(resp = new PcapResp{callback, id, timeout});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(waitingDlg) {
|
|
|
|
if(res) waitingDlg->close();
|
|
|
|
else {
|
|
|
|
QObject::connect(waitingDlg, &WaitingDlg::rejected, [=] {
|
|
|
|
std::lock_guard<std::mutex> lock(mtx);
|
|
|
|
for(int i=resps.size()-1; i>=0; i--) if(resps[i]==resp) {
|
|
|
|
resp->notCancelled = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
waitingDlg->showLater();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
2023-03-20 11:30:19 +08:00
|
|
|
|
|
|
|
void PcapReThread::run() {
|
|
|
|
pcap_pkthdr *header;
|
|
|
|
const u_char *data;
|
2023-06-06 12:13:33 +08:00
|
|
|
int cnt;
|
|
|
|
while((cnt = pcap_next_ex(pcap, &header, &data)) >= 0) {
|
2023-03-20 11:30:19 +08:00
|
|
|
if(status==2) return;
|
2023-05-27 17:43:57 +08:00
|
|
|
if(resps.isEmpty()) continue;
|
2023-03-20 11:30:19 +08:00
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> lock(mtx);
|
2023-06-06 12:13:33 +08:00
|
|
|
if(status==0 && cnt && data[0]==0x55 && data[1]==0x55) {
|
2023-05-27 17:43:57 +08:00
|
|
|
int id = data[2]<<8 | data[3];
|
2023-06-06 12:13:33 +08:00
|
|
|
for(int i=0; i<resps.size(); i++) if(resps[i]->id==id) {
|
2023-05-27 17:43:57 +08:00
|
|
|
auto resp = resps.takeAt(i);
|
2023-06-06 12:13:33 +08:00
|
|
|
if(resp->notCancelled) emit onMsg(resp->callback, 0, QByteArray((char*)data, header->caplen));
|
|
|
|
delete resp;
|
2023-05-27 17:43:57 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
auto now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
|
2023-06-06 12:13:33 +08:00
|
|
|
for(int i=0; i<resps.size(); i++) if(resps[i]->timeout <= now && resps[i]->timeout > 0) {
|
2023-03-20 11:30:19 +08:00
|
|
|
auto resp = resps.takeAt(i);
|
2023-06-06 12:13:33 +08:00
|
|
|
if(resp->notCancelled) emit onMsg(resp->callback, 5, QByteArray());
|
|
|
|
delete resp;
|
2023-03-20 11:30:19 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
emit onError(pcap_geterr(pcap));
|
|
|
|
}
|
|
|
|
|
|
|
|
|