提交 310b2d1c 编写于 作者: 丁劲犇's avatar 丁劲犇 😸

删除PCAP源、宿。统一引用PCAPHub项目。

上级 311faa37
......@@ -5,7 +5,6 @@ SUBDIRS += \
pannel/control_pannel \
sources/source_plutosdr \
sources/source_files \
sources/source_pcap \
transforms/transform_fft \
transforms/mod_fm \
transforms/mod_fm_dem \
......@@ -13,7 +12,6 @@ SUBDIRS += \
transforms/resample_pqfraction \
sinks/sink_file \
sinks/sink_plutosdr \
sinks/sink_pcap \
sinks/sink_SQL \
network/network_p2p \
wrappers/wrapper_scripts \
......
......@@ -3,7 +3,6 @@ add_subdirectory(sink_file)
add_subdirectory(sink_plots)
add_subdirectory(sink_SQL)
add_subdirectory(sink_soundcard)
add_subdirectory(sink_pcap)
if (TB_PLUTO)
add_subdirectory(sink_plutosdr)
endif()
cmake_minimum_required(VERSION 3.5)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt5 COMPONENTS Core Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Widgets REQUIRED)
include_directories(${TASKBUS_INTERFACEDIR})
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
include_directories(${TASKBUS_THIRDIR}/win32/npcap/Include)
set(PCAP_LIB wpcap)
if(TB64BIT)
link_directories(${TASKBUS_THIRDIR}/win32/npcap/lib/x64)
else()
link_directories(${TASKBUS_THIRDIR}/win32/npcap/lib)
endif()
else()
set(PCAP_LIB pcap)
endif()
set(PRJ_HEADERS
dialogsinkpcap.h
pcapio.h
)
set(PRJ_SOURCES
main.cpp
dialogsinkpcap.cpp
pcapio.cpp
)
set(PRJ_FORMS
dialogsinkpcap.ui
)
set(PRJ_RESOURCES
sink_pcap.qrc
)
#############Target======================
add_executable(sink_pcap
${PRJ_HEADERS}
${PRJ_SOURCES}
${PRJ_FORMS}
${PRJ_RESOURCES}
)
target_link_libraries(sink_pcap PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
${PCAP_LIB}
)
set_target_properties(sink_pcap PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER taskBus.modules.sink_pcap
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
# PCAP Source and Sink
为了保证收发数据的唯一性和去重,需要在一个公共队列里完成包的收发。原有分离的源、宿,在配置不正确时,会导致重发风暴。
目前,PCAP源和宿整合为 [PCAPHub 项目](https://gitcode.net/coloreaglestdio/pcaphub),直接单独编译后可引入taskBus。 PCAPHub项目已经兼容taskBus。
#include "dialogsinkpcap.h"
#include "ui_dialogsinkpcap.h"
#include <QLayout>
#include <QDebug>
#include <QTimer>
#include <QFileDialog>
#include <QMessageBox>
#include "pcapio.h"
DialogSinkPcap::DialogSinkPcap(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogSinkPcap),
m_devInputModule(new QStandardItemModel(this)),
cap_thread(new pcap_sink(this))
{
ui->setupUi(this);
std::string errstring = PCAPIO::pcapio_interfaces(m_devmap);
if (errstring.size())
ui->label_count->setText(QString::fromLocal8Bit(errstring.c_str()));
for (auto & p : m_devmap)
{
m_names.push_back(p.first);
m_devInputModule->appendRow(new QStandardItem(QString::fromLocal8Bit(p.second.c_str())));
}
ui->comboBox_Devices->setModel(m_devInputModule);
ui->btn_stop->setDisabled(true);
connect(ui->btn_start, SIGNAL(clicked()), this,SLOT(OnRecordStart()));
connect(ui->btn_stop, SIGNAL(clicked()), this,SLOT(OnRecordStop()));
connect(cap_thread,&pcap_sink::sig_message,ui->label_msg,&QLabel::setText);
m_nTimerID = startTimer(1000);
}
DialogSinkPcap::DialogSinkPcap(const TASKBUS::cmdlineParser * pline,QWidget *parent ):
DialogSinkPcap(parent)
{
m_cmdline = pline;
if (m_cmdline)
{
setInstance(m_cmdline->toInt("instance",0));
cap_thread->setCmdLine(m_cmdline);
//Listen thread to recieve messages from platform
connect(cap_thread,&pcap_sink::quit_app,this,&DialogSinkPcap::close);
m_n_device = m_cmdline->toInt("device",0);
m_n_subject = m_cmdline->toInt("package",0);
//ui->lineEdit_filter->setText(QString::fromLocal8Bit(m_filter.c_str()));
ui->comboBox_Devices->setCurrentIndex(m_n_device);
int hiden = m_cmdline->toInt("hide",0);
int autostart = m_cmdline->toInt("autostart",0);
if (hiden || autostart)
OnRecordStart();
}
}
DialogSinkPcap::~DialogSinkPcap()
{
if (cap_thread->isRunning())
{
cap_thread->stopCap();
}
delete ui;
}
void DialogSinkPcap::timerEvent(QTimerEvent *event)
{
if (event->timerId()==m_nTimerID)
{
if (cap_thread->isRunning())
{
QString str = QString("%1").arg((unsigned long long)cap_thread->m_tx);
ui->label_count->setText(str);
}
}
}
void DialogSinkPcap::OnRecordStart()
{
ui->btn_start->setDisabled(true);
ui->btn_stop->setDisabled(false);
cap_thread->m_nInstance = m_n_instance;
int nDev = ui->comboBox_Devices->currentIndex();
if (nDev < 0 || nDev >= m_names.size() )
{
return;
}
cap_thread->m_device = m_names[nDev];
cap_thread->m_nSubject = m_n_subject;
cap_thread->startCap();
}
void DialogSinkPcap::OnRecordStop()
{
ui->btn_start->setDisabled(false);
ui->btn_stop->setDisabled(true);
cap_thread->stopCap();
}
#ifndef DIALOGSINKPCAP_H
#define DIALOGSINKPCAP_H
#include <QDialog>
#include <QList>
#include <QStandardItemModel>
#include "cmdlineparser.h"
#include "tb_interface.h"
#include "pcapio.h"
namespace Ui {
class DialogSinkPcap;
}
class DialogSinkPcap : public QDialog
{
Q_OBJECT
public:
explicit DialogSinkPcap(QWidget *parent = nullptr);
explicit DialogSinkPcap(const TASKBUS::cmdlineParser * pline,QWidget *parent = nullptr);
~DialogSinkPcap();
public:
void setInstance(const int i){m_n_instance = i;}
void timerEvent(QTimerEvent *event);
private:
Ui::DialogSinkPcap *ui;
QStandardItemModel * m_devInputModule = nullptr;
protected:
int m_n_instance = 0;
int m_n_subject = 0;
int m_n_device = 0;
std::string m_filter;
private slots:
void OnRecordStart();
void OnRecordStop();
private:
const TASKBUS::cmdlineParser * m_cmdline = nullptr;
pcap_sink * cap_thread = 0;
int m_nTimerID = -1;
protected:
std::map<std::string,std::string > m_devmap;
std::vector<std::string> m_names;
};
#endif // DIALOGSINKPCAP_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DialogSinkPcap</class>
<widget class="QDialog" name="DialogSinkPcap">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>128</height>
</rect>
</property>
<property name="windowTitle">
<string>DialogSinkPcap</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>devices</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_Devices">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>1024</width>
<height>16777215</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_msg">
<property name="text">
<string>Ok</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_count">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_start">
<property name="text">
<string>开始</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_stop">
<property name="text">
<string>停止</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
#include "dialogsinkpcap.h"
#include <QApplication>
#include <QFile>
#include <QByteArray>
#include "cmdlineparser.h"
#include "tb_interface.h"
const bool TASKBUSDBG = false;
using namespace TASKBUS;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
init_client();
cmdlineParser args;
//Debug
if (TASKBUSDBG)
{
auto cmdline = TASKBUS::debug("d:/log/pid2837",0,0);
args.parser(cmdline);
}
else
args.parser(argc,argv);
int ret = 0;
//Arg--information参数,打印自己的功能定义字符串。
if (args.contains("information"))
{
QFile fp(":/json/sink_pcap.json");
if (fp.open(QIODevice::ReadOnly))
{
QByteArray arr = fp.readAll();
arr.push_back('\0');
puts(arr.constData());
fflush(stdout);
}
}
else
{
DialogSinkPcap w(&args);
int hiden = args.toInt("hide",0);
if (hiden==0)
w.show();
//用于接收消息的线程
ret = a.exec();
}
return ret;
}
#include "pcapio.h"
#include <pcap.h>
#include <string.h>
#include "tb_interface.h"
namespace PCAPIO{
std::string ifaddresses(pcap_if_t *d);
std::string pcapio_interfaces(std::map<std::string,std::string> & devmap)
{
std::string res;
pcap_if_t *alldevs;
char errbuf[PCAP_ERRBUF_SIZE];
if(pcap_findalldevs(&alldevs, errbuf) == -1){
res = errbuf;
return res;
}
for(auto d = alldevs; d != NULL; d = d->next){
std::string d_name = d->name;
std::string d_des = ifaddresses(d);
devmap[d_name] = d_des;
}
pcap_freealldevs(alldevs);
return res;
}
std::string address_print(unsigned char * v)
{
std::string res;
char buf[1024];
int left_start = 0, right_end = sizeof(sockaddr::sa_data) - 1;
while (left_start + 3 < right_end && v[left_start]==0)
++left_start;
while (left_start + 3< right_end && v[right_end]==0)
--right_end;
res += "HEX(";
for (unsigned char i =left_start; i<=right_end;++i)
{
if (i-left_start) res += ":";
snprintf(buf,1024,"%02X", (unsigned int)v[i]);
res += buf;
}
res += ")";
res += "DEC(";
for (unsigned char i =left_start; i<=right_end;++i)
{
if (i-left_start) res += ":";
snprintf(buf,1024,"%u", (unsigned int)v[i] );
res += buf;
}
res += ")";
return res;
}
/* Print all the available information on the given interface */
std::string ifaddresses(pcap_if_t *d)
{
char buf[1024];
pcap_addr_t *a;
std::string res ;
res+=d->name;
res += ":";
if(d->description)
{
res += d->description;
res += ":";
}
for(a=d->addresses;a;a=a->next) {
snprintf(buf,1024,"\nAF_0x%02X",(unsigned int)a->addr->sa_family);
res += buf;
if (a->addr)
{
snprintf(buf,1024,"_%s",address_print((unsigned char *)a->addr->sa_data).c_str());
res += buf;
}
if (a->netmask)
{
snprintf(buf,1024,"/%s ",address_print((unsigned char *)a->netmask->sa_data).c_str());
res += buf;
}
}
return res;
}
}
pcap_sink::pcap_sink (QObject * parent)
:QThread(parent)
{
m_bStop = true;
}
void pcap_sink::startCap()
{
if (this->isRunning())
stopCap();
m_bStop =false;
start(QThread::TimeCriticalPriority);
}
void pcap_sink::stopCap()
{
m_bStop = true;
if (this->isRunning())
{
this->wait(2000);
this->terminate();
}
}
void pcap_sink::run()
{
if (m_bStop)
return;
bool bQuit = false;
using namespace TASKBUS;
while (false==m_bStop)
{
pcap_t *handle = NULL;
char errbuf[PCAP_ERRBUF_SIZE];
handle = pcap_open_live(m_device.c_str(), 65535, 1, 10, errbuf);
if(handle == NULL)
{
QString err = QString("pcap_open_live return err,errbuf:%1...").arg(errbuf);
emit sig_message(err);
return ;
}
m_tx = 0;
while (false==m_bStop)
{
subject_package_header header;
std::vector<unsigned char> packagedta = pull_subject(&header);
if (!is_valid_header(header))
{
msleep(100);
continue;
}
if (!packagedta.empty())
{
if ( is_control_subject(header))
{
//收到命令进程退出的广播消息,退出
if (strstr((const char *)packagedta.data(),"function=quit;")!=nullptr)
{
fprintf(stderr,"Recived Quit Command.");
fflush(stderr);
m_bStop = true;
bQuit = true;
}
}
else if (header.subject_id==m_nSubject)
{
if (PCAP_ERROR ==pcap_sendpacket(handle,packagedta.data(),packagedta.size()))
{
fprintf(stderr,pcap_geterr(handle));
fprintf(stderr,"\n");
fflush(stderr);
break;
}
++m_tx;
}
}
}
pcap_close(handle);
}
emit sig_message("Stopped");
if (bQuit)
emit quit_app();
}
#ifndef PCAPIO_H
#define PCAPIO_H
#include <string>
#include <map>
#include <QThread>
#include <atomic>
#include <QAtomicInteger>
#include "cmdlineparser.h"
namespace PCAPIO{
std::string pcapio_interfaces(std::map<std::string,std::string> & devmap);
}
class pcap_sink : public QThread{
Q_OBJECT
public:
explicit pcap_sink (QObject * parent = nullptr);
void startCap();
void stopCap();
void setCmdLine(const TASKBUS::cmdlineParser * cmdline)
{
m_cmd = cmdline;
}
protected:
void run() override;
protected:
std::atomic<bool> m_bStop;
static QAtomicInteger<quint64> m_refTms;
const TASKBUS::cmdlineParser * m_cmd = nullptr;
public:
std::string m_device;
std::atomic<unsigned long long> m_tx;
int m_nInstance;
int m_nSubject;
signals:
void sig_message(QString msg);
void quit_app();
};
#endif // PCAPIO_H
{
"sink_pcap":{
"name":"pcap_sink",
"parameters":{
"device":{
"type":"string",
"tooltip":"device list index",
"default":"0"
},
"hide":{
"type":"int",
"tooltip":"hide window when start",
"default":0
},
"autostart":{
"type":"int",
"tooltip":"auto start",
"default":0
}
},
"input_subjects":
{
"package":{
"type":"bytes",
"tooltip":"Package"
}
},
"output_subjects":{
}
}
}
#-------------------------------------------------
#
# Project created by QtCreator 2018-10-26T07:14:47
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
INCLUDEPATH += ../../../tb_interface
DESTDIR = $$OUT_PWD/../../../bin/modules
TARGET = sink_pcap
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++17
SOURCES += \
main.cpp \
dialogsinkpcap.cpp \
pcapio.cpp
HEADERS += \
dialogsinkpcap.h \
pcapio.h
FORMS += \
dialogsinkpcap.ui
win32{
INCLUDEPATH +="$$PWD/../../3rdlibs/win32/npcap/Include"
contains(QT_ARCH, i386) {
LIBS+=-L"$$PWD/../../3rdlibs/win32/npcap/lib" -lwpcap
} else {
LIBS+=-L"$$PWD/../../3rdlibs/win32/npcap/lib/x64" -lwpcap
}
}else: LIBS+=-lpcap
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
sink_pcap.qrc
<RCC>
<qresource prefix="/json">
<file>sink_pcap.json</file>
</qresource>
</RCC>
......@@ -2,7 +2,6 @@ cmake_minimum_required(VERSION 3.5)
add_subdirectory(source_files)
add_subdirectory(source_soundcard)
add_subdirectory(source_pcap)
if (TB_PLUTO)
add_subdirectory(source_plutosdr)
endif()
cmake_minimum_required(VERSION 3.5)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt5 COMPONENTS Core Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Widgets REQUIRED)
include_directories(${TASKBUS_INTERFACEDIR})
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
include_directories(${TASKBUS_THIRDIR}/win32/npcap/Include)
set(PCAP_LIB wpcap)
if(TB64BIT)
link_directories(${TASKBUS_THIRDIR}/win32/npcap/lib/x64)
else()
link_directories(${TASKBUS_THIRDIR}/win32/npcap/lib)
endif()
else()
set(PCAP_LIB pcap)
endif()
set(PRJ_HEADERS
dialogsourcepcap.h
listen_thread.h
pcapio.h
)
set(PRJ_SOURCES
main.cpp
dialogsourcepcap.cpp
listen_thread.cpp
pcapio.cpp
)
set(PRJ_FORMS
dialogsourcepcap.ui
)
set(PRJ_RESOURCES
source_pcap.qrc
)
#############Target======================
add_executable(source_pcap
${PRJ_HEADERS}
${PRJ_SOURCES}
${PRJ_FORMS}
${PRJ_RESOURCES}
)
target_link_libraries(source_pcap PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
${PCAP_LIB}
)
set_target_properties(source_pcap PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER taskBus.modules.source_pcap
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
# PCAP Source and Sink
为了保证收发数据的唯一性和去重,需要在一个公共队列里完成包的收发。原有分离的源、宿,在配置不正确时,会导致重发风暴。
目前,PCAP源和宿整合为 [PCAPHub 项目](https://gitcode.net/coloreaglestdio/pcaphub),直接单独编译后可引入taskBus。 PCAPHub项目已经兼容taskBus。
#include "dialogsourcepcap.h"
#include "ui_dialogsourcepcap.h"
#include <QLayout>
#include <QDebug>
#include <QTimer>
#include <QFileDialog>
#include <QMessageBox>
#include "pcapio.h"
DialogSourcePcap::DialogSourcePcap(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogSourcePcap),
m_devInputModule(new QStandardItemModel(this)),
cap_thread(new pcap_source(this))
{
ui->setupUi(this);
std::string errstring = PCAPIO::pcapio_interfaces(m_devmap);
if (errstring.size())
ui->label_count->setText(QString::fromLocal8Bit(errstring.c_str()));
for (auto & p : m_devmap)
{
m_names.push_back(p.first);
m_devInputModule->appendRow(new QStandardItem(QString::fromLocal8Bit(p.second.c_str())));
}
ui->comboBox_Devices->setModel(m_devInputModule);
ui->btn_stop->setDisabled(true);
connect(ui->btn_start, SIGNAL(clicked()), this,SLOT(OnRecordStart()));
connect(ui->btn_stop, SIGNAL(clicked()), this,SLOT(OnRecordStop()));
connect(cap_thread,&pcap_source::sig_message,ui->label_msg,&QLabel::setText);
m_nTimerID = startTimer(1000);
}
DialogSourcePcap::DialogSourcePcap(const TASKBUS::cmdlineParser * pline,QWidget *parent ):
DialogSourcePcap(parent)
{
m_cmdline = pline;
if (m_cmdline)
{
setInstance(m_cmdline->toInt("instance",0));
//Listen thread to recieve messages from platform
m_pListenThread = new listen_thread(m_cmdline,this);
connect(m_pListenThread,&listen_thread::quit_app,this,&DialogSourcePcap::close);
m_pListenThread->start();
m_n_device = m_cmdline->toInt("device",0);
m_n_subject = m_cmdline->toInt("package",0);
m_filter = m_cmdline->toString("filter","");
ui->lineEdit_filter->setText(QString::fromLocal8Bit(m_filter.c_str()));
ui->comboBox_Devices->setCurrentIndex(m_n_device);
int hiden = m_cmdline->toInt("hide",0);
int autostart = m_cmdline->toInt("autostart",0);
if (hiden || autostart)
OnRecordStart();
}
}
DialogSourcePcap::~DialogSourcePcap()
{
if (m_pListenThread)
m_pListenThread->terminate();
if (cap_thread->isRunning())
{
cap_thread->stopCap();
}
delete ui;
}
void DialogSourcePcap::timerEvent(QTimerEvent *event)
{
if (event->timerId()==m_nTimerID)
{
if (cap_thread->isRunning())
{
QString str = QString("%1").arg((unsigned long long)cap_thread->m_rx);
ui->label_count->setText(str);
}
}
}
void DialogSourcePcap::OnRecordStart()
{
ui->btn_start->setDisabled(true);
ui->btn_stop->setDisabled(false);
cap_thread->m_nInstance = m_n_instance;
int nDev = ui->comboBox_Devices->currentIndex();
if (nDev < 0 || nDev >= m_names.size() )
{
return;
}
cap_thread->m_device = m_names[nDev];
cap_thread->m_filter = ui->lineEdit_filter->text().toStdString();
cap_thread->m_nSubject = m_n_subject;
cap_thread->startCap();
}
void DialogSourcePcap::OnRecordStop()
{
ui->btn_start->setDisabled(false);
ui->btn_stop->setDisabled(true);
cap_thread->stopCap();
}
#ifndef DIALOGSOURCEPCAP_H
#define DIALOGSOURCEPCAP_H
#include <QDialog>
#include <QList>
#include <QStandardItemModel>
#include "cmdlineparser.h"
#include "tb_interface.h"
#include "listen_thread.h"
#include "pcapio.h"
namespace Ui {
class DialogSourcePcap;
}
class DialogSourcePcap : public QDialog
{
Q_OBJECT
public:
explicit DialogSourcePcap(QWidget *parent = nullptr);
explicit DialogSourcePcap(const TASKBUS::cmdlineParser * pline,QWidget *parent = nullptr);
~DialogSourcePcap();
public:
void setInstance(const int i){m_n_instance = i;}
void timerEvent(QTimerEvent *event);
private:
Ui::DialogSourcePcap *ui;
QStandardItemModel * m_devInputModule = nullptr;
protected:
int m_n_instance = 0;
int m_n_subject = 0;
int m_n_device = 0;
std::string m_filter;
private slots:
void OnRecordStart();
void OnRecordStop();
private:
const TASKBUS::cmdlineParser * m_cmdline = nullptr;
listen_thread * m_pListenThread = nullptr;
pcap_source * cap_thread = 0;
int m_nTimerID = -1;
protected:
std::map<std::string,std::string > m_devmap;
std::vector<std::string> m_names;
};
#endif // DIALOGSOURCEPCAP_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DialogSourcePcap</class>
<widget class="QDialog" name="DialogSourcePcap">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>128</height>
</rect>
</property>
<property name="windowTitle">
<string>DialogSourcePcap</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>devices</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_Devices">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>1024</width>
<height>16777215</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>filter</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_filter"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_msg">
<property name="text">
<string>Ok</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_count">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_start">
<property name="text">
<string>开始</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_stop">
<property name="text">
<string>停止</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
#include "listen_thread.h"
#include "tb_interface.h"
listen_thread::listen_thread(
const TASKBUS::cmdlineParser * cmdline,
QObject * parent)
:QThread(parent)
,m_cmd(cmdline)
{
}
QAtomicInteger<quint64> listen_thread::m_refTms = 0;
void listen_thread::run()
{
using namespace TASKBUS;
bool bfinished = false;
while (false==bfinished)
{
subject_package_header header;
std::vector<unsigned char> packagedta = pull_subject(&header);
if (!is_valid_header(header))
{
fprintf(stderr,"Recived BAD Command.");
fflush(stderr);
msleep(100);
continue;
}
if (!packagedta.empty())
{
if ( is_control_subject(header))
{
//收到命令进程退出的广播消息,退出
if (strstr((const char *)packagedta.data(),"function=quit;")!=nullptr)
{
fprintf(stderr,"Recived Quit Command.");
fflush(stderr);
bfinished = true;
}
}
}
}
emit quit_app();
}
#ifndef LISTEN_THREAD_H
#define LISTEN_THREAD_H
#include <QThread>
#include <QAtomicInteger>
#include "cmdlineparser.h"
class listen_thread: public QThread
{
Q_OBJECT
public:
explicit listen_thread(const TASKBUS::cmdlineParser * cmdline, QObject * parent);
static QAtomicInteger<quint64> m_refTms;
protected:
const TASKBUS::cmdlineParser * m_cmd = nullptr;
void run() override;
signals:
void quit_app();
};
#endif // LISTEN_THREAD_H
#include "dialogsourcepcap.h"
#include <QApplication>
#include <QFile>
#include <QByteArray>
#include "cmdlineparser.h"
#include "tb_interface.h"
const bool TASKBUSDBG = false;
using namespace TASKBUS;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
init_client();
cmdlineParser args;
//Debug
if (TASKBUSDBG)
{
auto cmdline = TASKBUS::debug("d:/log/pid2837",0,0);
args.parser(cmdline);
}
else
args.parser(argc,argv);
int ret = 0;
//Arg--information参数,打印自己的功能定义字符串。
if (args.contains("information"))
{
QFile fp(":/json/source_pcap.json");
if (fp.open(QIODevice::ReadOnly))
{
QByteArray arr = fp.readAll();
arr.push_back('\0');
puts(arr.constData());
fflush(stdout);
}
}
else
{
DialogSourcePcap w(&args);
int hiden = args.toInt("hide",0);
if (hiden==0)
w.show();
//用于接收消息的线程
ret = a.exec();
}
return ret;
}
#include "pcapio.h"
#include <pcap.h>
#include <string.h>
#include "tb_interface.h"
namespace PCAPIO{
std::string ifaddresses(pcap_if_t *d);
std::string pcapio_interfaces(std::map<std::string,std::string> & devmap)
{
std::string res;
pcap_if_t *alldevs;
char errbuf[PCAP_ERRBUF_SIZE];
if(pcap_findalldevs(&alldevs, errbuf) == -1){
res = errbuf;
return res;
}
for(auto d = alldevs; d != NULL; d = d->next){
std::string d_name = d->name;
std::string d_des = ifaddresses(d);
devmap[d_name] = d_des;
}
pcap_freealldevs(alldevs);
return res;
}
std::string address_print(unsigned char * v)
{
std::string res;
char buf[1024];
int left_start = 0, right_end = sizeof(sockaddr::sa_data) - 1;
while (left_start + 3 < right_end && v[left_start]==0)
++left_start;
while (left_start + 3< right_end && v[right_end]==0)
--right_end;
res += "HEX(";
for (unsigned char i =left_start; i<=right_end;++i)
{
if (i-left_start) res += ":";
snprintf(buf,1024,"%02X", (unsigned int)v[i]);
res += buf;
}
res += ")";
res += "DEC(";
for (unsigned char i =left_start; i<=right_end;++i)
{
if (i-left_start) res += ":";
snprintf(buf,1024,"%u", (unsigned int)v[i] );
res += buf;
}
res += ")";
return res;
}
/* Print all the available information on the given interface */
std::string ifaddresses(pcap_if_t *d)
{
char buf[1024];
pcap_addr_t *a;
std::string res ;
res+=d->name;
res += ":";
if(d->description)
{
res += d->description;
res += ":";
}
for(a=d->addresses;a;a=a->next) {
snprintf(buf,1024,"\nAF_0x%02X",(unsigned int)a->addr->sa_family);
res += buf;
if (a->addr)
{
snprintf(buf,1024,"_%s",address_print((unsigned char *)a->addr->sa_data).c_str());
res += buf;
}
if (a->netmask)
{
snprintf(buf,1024,"/%s ",address_print((unsigned char *)a->netmask->sa_data).c_str());
res += buf;
}
}
return res;
}
}
pcap_source::pcap_source (QObject * parent)
:QThread(parent)
{
m_bStop = true;
}
void pcap_source::startCap()
{
if (this->isRunning())
stopCap();
m_bStop =false;
start(QThread::TimeCriticalPriority);
}
void pcap_source::stopCap()
{
m_bStop = true;
if (this->isRunning())
{
this->wait(2000);
this->terminate();
}
}
void pcap_source::run()
{
if (m_bStop)
return;
while (!m_bStop)
{
pcap_t *handle = NULL;
char errbuf[PCAP_ERRBUF_SIZE];
handle = pcap_open_live(m_device.c_str(), 65535, 1, 10, errbuf);
if(handle == NULL)
{
QString err = QString("pcap_open_live return err,errbuf:%1...").arg(errbuf);
emit sig_message(err);
return ;
}
struct bpf_program filter;
bpf_u_int32 net = 0;
int ret32 = pcap_compile(handle, &filter, m_filter.c_str(), 0, net);
if(ret32 < 0)
{
QString err = QString("pcap_compile return %1, errbuf:%2").arg(ret32).arg(errbuf);
emit sig_message(err);
pcap_close(handle);
return ;
}
ret32 = pcap_setfilter(handle, &filter);
if(ret32 < 0)
{
QString err = QString("pcap_setfilter return %1, errbuf:%2").arg(ret32).arg(errbuf);
emit sig_message(err);
pcap_close(handle);
return ;
}
const u_char *packet;
struct pcap_pkthdr header;
//注意,要设置较大的缓存
pcap_set_buffer_size(handle,256*1024*1024);
emit sig_message("Cap Started");
while (!m_bStop)
{
packet = pcap_next(handle, &header);
if(packet)
{
++m_rx;
if (m_nSubject)
TASKBUS::push_subject(m_nSubject,m_nInstance,
header.len,(unsigned char *)packet);
}
else
{
fprintf(stderr,pcap_geterr(handle));
fprintf(stderr,"\n");
fflush(stderr);
break;
}
}
pcap_close(handle);
}
emit sig_message("Cap Stopped");
}
#ifndef PCAPIO_H
#define PCAPIO_H
#include <string>
#include <map>
#include <QThread>
#include <atomic>
namespace PCAPIO{
std::string pcapio_interfaces(std::map<std::string,std::string> & devmap);
}
class pcap_source : public QThread{
Q_OBJECT
public:
explicit pcap_source (QObject * parent = nullptr);
void startCap();
void stopCap();
protected:
void run() override;
protected:
std::atomic<bool> m_bStop;
public:
std::string m_filter;
std::string m_device;
std::atomic<unsigned long long> m_rx = 0;
int m_nInstance = 0;
int m_nSubject = 0;
signals:
void sig_message(QString msg);
};
#endif // PCAPIO_H
{
"source_pcap":{
"name":"pcap_src",
"parameters":{
"device":{
"type":"string",
"tooltip":"device list index",
"default":"0"
},
"filter":{
"type":"string",
"tooltip":"filter of cap",
"default":"icmp and ip host 127.0.0.1"
},
"hide":{
"type":"int",
"tooltip":"hide window when start",
"default":0
},
"autostart":{
"type":"int",
"tooltip":"auto start",
"default":0
}
},
"input_subjects":
{
},
"output_subjects":{
"package":{
"type":"bytes",
"tooltip":"Package"
}
}
}
}
#-------------------------------------------------
#
# Project created by QtCreator 2018-10-26T07:14:47
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
INCLUDEPATH += ../../../tb_interface
DESTDIR = $$OUT_PWD/../../../bin/modules
TARGET = source_pcap
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++17
SOURCES += \
main.cpp \
dialogsourcepcap.cpp \
listen_thread.cpp \
pcapio.cpp
HEADERS += \
dialogsourcepcap.h \
listen_thread.h \
pcapio.h
FORMS += \
dialogsourcepcap.ui
win32{
INCLUDEPATH +="$$PWD/../../3rdlibs/win32/npcap/Include"
contains(QT_ARCH, i386) {
LIBS+=-L"$$PWD/../../3rdlibs/win32/npcap/lib" -lwpcap
} else {
LIBS+=-L"$$PWD/../../3rdlibs/win32/npcap/lib/x64" -lwpcap
}
}else: LIBS+=-lpcap
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
source_pcap.qrc
<RCC>
<qresource prefix="/json">
<file>source_pcap.json</file>
</qresource>
</RCC>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册