#include "pcapwin.h" #include #include #include #include #include #include #include #include "globalfunc.h" PcapWin *PcapWin::newIns(QByteArray &name, QWidget *parent) { if(name.isEmpty()) return 0; char errbuf[PCAP_ERRBUF_SIZE]{'\0'}; auto pcapRe = pcap_open_live(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS, 50, errbuf); if(pcapRe == 0) { QMessageBox::critical(parent, "Error", QString(tr("打开网卡失败"))+errbuf); return 0; } auto pcapSend = pcap_open_live(name.data(), 65536, 0, 50, errbuf); if(pcapSend == 0) { QMessageBox::critical(parent, "Error", QString(tr("打开网卡失败"))+errbuf); return 0; } return new PcapWin(pcapRe, pcapSend, parent); } PcapWin::PcapWin(pcap_t *pcapRece, pcap_t *pcapSend, QWidget *parent) : BaseWin{parent}, pcap(pcapSend) { setWindowModality(Qt::WindowModal); setAttribute(Qt::WA_DeleteOnClose); setWindowTitle(tr("网口通信")); resize(1024, 720); auto vBox = new QVBoxLayout(center); vBox->setContentsMargins(0,0,0,0); vBox->setSpacing(3); vBox->addLayout(addBtns(new QHBoxLayout())); auto fdReceive = new QTextEdit; fdReceive->setFontFamily("Consolas"); fdReceive->setReadOnly(true); fdReceive->document()->setMaximumBlockCount(200); auto hBox = new QHBoxLayout; { auto vBox = new QVBoxLayout; auto hBox2 = new QHBoxLayout; hBox2->addWidget(new QLabel(tr("接收:"))); hBox2->addStretch(); auto fdStart = new QRadioButton(tr("开始")); fdStart->setChecked(true); connect(fdStart, &QPushButton::toggled, this, [this](bool checked) { thd->status = checked ? 0 : 1; }); hBox2->addWidget(fdStart); hBox2->addSpacing(20); auto fdEnd = new QRadioButton(tr("暂停")); hBox2->addWidget(fdEnd); hBox2->addStretch(); auto btnClear = new QPushButton(tr("清除")); btnClear->setMinimumWidth(120); connect(btnClear, &QPushButton::clicked, fdReceive, &QTextEdit::clear); hBox2->addWidget(btnClear); hBox2->addStretch(); vBox->addLayout(hBox2); vBox->addWidget(fdReceive); hBox->addLayout(vBox); } { auto wgt = new QWidget; wgt->setMaximumWidth(400); auto vBox = new QVBoxLayout(wgt); vBox->setContentsMargins(0,0,0,0); vBox->setSpacing(3); auto hBox2 = new QHBoxLayout; hBox2->addStretch(); auto btnSend = new QPushButton(tr("发送")); btnSend->setMinimumWidth(120); hBox2->addWidget(btnSend); hBox2->addStretch(); auto btnClear = new QPushButton(tr("清除")); btnClear->setMinimumWidth(120); hBox2->addWidget(btnClear); hBox2->addStretch(); vBox->addLayout(hBox2); auto fdSend = new QTextEdit; fdSend->setFontFamily("Consolas"); vBox->addWidget(fdSend); connect(btnSend, &QPushButton::clicked, this, [this, fdSend] { auto text = fdSend->toPlainText(); auto len = text.size(); QByteArray bytes; for(int i=0; i='0' && ch<='9') || (ch>='A' && ch<='F') || (ch>='a' && ch<='f')) bytes.append(ch); } if(bytes.size() % 2) bytes.append('0'); bytes = QByteArray::fromHex(bytes); if(pcap_sendpacket(pcap, (u_char*)bytes.data(), bytes.size())) { QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+pcap_geterr(pcap)); return; } }); connect(btnClear, &QPushButton::clicked, fdSend, &QTextEdit::clear); hBox->addWidget(wgt); } vBox->addLayout(hBox); thd = new PcapThread(pcapRece); connect(thd, &PcapThread::onMsg, fdReceive, &QTextEdit::append); thd->start(); } PcapThread::PcapThread(pcap_t *pcap) : pcap(pcap) { connect(this, &QThread::finished, this, &QThread::deleteLater); } void PcapThread::run() { pcap_pkthdr *header; const u_char *data; int res; while((res = pcap_next_ex(pcap, &header, &data)) >= 0) { if(status==2) return; if(status==1 || res == 0) continue; //超时 if(data[0]!=0x55 || data[1]!=0x55) continue; QString data_str; data_str.append(QDateTime::fromSecsSinceEpoch(header->ts.tv_sec).toString("yy-MM-dd HH:mm:ss.")+QString::number(header->ts.tv_usec)); data_str.append(" len:").append(QString::number(header->caplen)).append("/").append(QString::number(header->len)).append("\n"); char line[LINE_LEN + 1]; int l = 0; for(uint i=0; icaplen; i++) { data_str.append(QString::asprintf("%.2x ", data[i])); if(i > 13) { if(isgraph(data[i]) || data[i] == ' ') line[l] = data[i]; else line[l] = '.'; if(l==15) { line[16] = 0; data_str.append(" ").append(line).append("\n"); l = 0; } else l++; } else if(i == 13) { data_str.append("\n"); } } line[l] = 0; data_str.append(" ").append(line).append("\n\n"); emit onMsg(data_str); } emit onError(pcap_geterr(pcap)); }