Move debugStats() from PcapRx to base PcapSession

With this change, other classes that use PcapSession as base can also
use debugStats(), if required
This commit is contained in:
Srivats P 2023-03-23 15:42:41 +05:30
parent 47325c38b0
commit 3060701386
7 changed files with 91 additions and 71 deletions

View File

@ -504,7 +504,7 @@ void PcapPort::PortCapturer::stop()
{ {
if (state_ == kRunning) { if (state_ == kRunning) {
stop_ = true; stop_ = true;
PcapSession::stop(handle_); PcapSession::stop();
while (state_ == kRunning) while (state_ == kRunning)
QThread::msleep(10); QThread::msleep(10);
} }
@ -728,7 +728,7 @@ void PcapPort::EmulationTransceiver::stop()
{ {
if (state_ == kRunning) { if (state_ == kRunning) {
stop_ = true; stop_ = true;
PcapSession::stop(handle_); PcapSession::stop();
while (state_ == kRunning) while (state_ == kRunning)
QThread::msleep(10); QThread::msleep(10);
} }

View File

@ -135,7 +135,6 @@ protected:
QString device_; QString device_;
volatile bool stop_; volatile bool stop_;
QTemporaryFile capFile_; QTemporaryFile capFile_;
pcap_t *handle_;
pcap_dumper_t *dumpHandle_; pcap_dumper_t *dumpHandle_;
volatile State state_; volatile State state_;
}; };
@ -162,7 +161,6 @@ protected:
QString device_; QString device_;
DeviceManager *deviceManager_; DeviceManager *deviceManager_;
volatile bool stop_; volatile bool stop_;
pcap_t *handle_;
volatile State state_; volatile State state_;
}; };

View File

@ -106,7 +106,7 @@ void PcapRxStats::run()
} }
_skip_filter: _skip_filter:
memset(&lastPcapStats_, 0, sizeof(lastPcapStats_)); clearDebugStats();
PcapSession::preRun(); PcapSession::preRun();
state_ = kRunning; state_ = kRunning;
while (1) { while (1) {
@ -174,7 +174,7 @@ bool PcapRxStats::stop()
{ {
if (state_ == kRunning) { if (state_ == kRunning) {
stop_ = true; stop_ = true;
PcapSession::stop(handle_); PcapSession::stop();
while (state_ == kRunning) while (state_ == kRunning)
QThread::msleep(10); QThread::msleep(10);
} }
@ -193,57 +193,3 @@ bool PcapRxStats::isDirectional()
{ {
return isDirectional_; return isDirectional_;
} }
// XXX: Implemented as reset on read
QString PcapRxStats::debugStats()
{
QString dbgStats;
#ifdef Q_OS_WIN32
static_assert(sizeof(struct pcap_stat) == 6*sizeof(uint),
"pcap_stat has less or more than 6 values");
int size;
struct pcap_stat incPcapStats;
struct pcap_stat *pcapStats = pcap_stats_ex(handle_, &size);
if (pcapStats && (uint(size) >= 6*sizeof(uint))) {
incPcapStats.ps_recv = pcapStats->ps_recv - lastPcapStats_.ps_recv;
incPcapStats.ps_drop = pcapStats->ps_drop - lastPcapStats_.ps_drop;
incPcapStats.ps_ifdrop = pcapStats->ps_ifdrop - lastPcapStats_.ps_ifdrop;
incPcapStats.ps_capt = pcapStats->ps_capt - lastPcapStats_.ps_capt;
incPcapStats.ps_sent = pcapStats->ps_sent - lastPcapStats_.ps_sent;
incPcapStats.ps_netdrop = pcapStats->ps_netdrop - lastPcapStats_.ps_netdrop;
dbgStats = QString("recv: %1 drop: %2 ifdrop: %3 "
"capt: %4 sent: %5 netdrop: %6")
.arg(incPcapStats.ps_recv)
.arg(incPcapStats.ps_drop)
.arg(incPcapStats.ps_ifdrop)
.arg(incPcapStats.ps_capt)
.arg(incPcapStats.ps_sent)
.arg(incPcapStats.ps_netdrop);
lastPcapStats_ = *pcapStats;
} else {
dbgStats = QString("error reading pcap stats: %1")
.arg(pcap_geterr(handle_));
}
#else
struct pcap_stat pcapStats;
struct pcap_stat incPcapStats;
int ret = pcap_stats(handle_, &pcapStats);
if (ret == 0) {
incPcapStats.ps_recv = pcapStats.ps_recv - lastPcapStats_.ps_recv;
incPcapStats.ps_drop = pcapStats.ps_drop - lastPcapStats_.ps_drop;
incPcapStats.ps_ifdrop = pcapStats.ps_ifdrop - lastPcapStats_.ps_ifdrop;
dbgStats = QString("recv: %1 drop: %2 ifdrop: %3")
.arg(incPcapStats.ps_recv)
.arg(incPcapStats.ps_drop)
.arg(incPcapStats.ps_ifdrop);
lastPcapStats_ = pcapStats;
} else {
dbgStats = QString("error reading pcap stats: %1")
.arg(pcap_geterr(handle_));
}
#endif
return dbgStats;
}

View File

@ -35,8 +35,6 @@ public:
bool isRunning(); bool isRunning();
bool isDirectional(); bool isDirectional();
QString debugStats();
private: private:
enum State { enum State {
kNotStarted, kNotStarted,
@ -47,12 +45,10 @@ private:
QString device_; QString device_;
StreamStats &streamStats_; StreamStats &streamStats_;
volatile bool stop_; volatile bool stop_;
pcap_t *handle_;
volatile State state_; volatile State state_;
bool isDirectional_; bool isDirectional_;
int id_; int id_;
struct pcap_stat lastPcapStats_;
}; };
#endif #endif

View File

@ -19,6 +19,66 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "pcapsession.h" #include "pcapsession.h"
// XXX: Implemented as reset on read
QString PcapSession::debugStats()
{
QString dbgStats;
#ifdef Q_OS_WIN32
static_assert(sizeof(struct pcap_stat) == 6*sizeof(uint),
"pcap_stat has less or more than 6 values");
int size;
struct pcap_stat incPcapStats;
struct pcap_stat *pcapStats = pcap_stats_ex(handle_, &size);
if (pcapStats && (uint(size) >= 6*sizeof(uint))) {
incPcapStats.ps_recv = pcapStats->ps_recv - lastPcapStats_.ps_recv;
incPcapStats.ps_drop = pcapStats->ps_drop - lastPcapStats_.ps_drop;
incPcapStats.ps_ifdrop = pcapStats->ps_ifdrop - lastPcapStats_.ps_ifdrop;
incPcapStats.ps_capt = pcapStats->ps_capt - lastPcapStats_.ps_capt;
incPcapStats.ps_sent = pcapStats->ps_sent - lastPcapStats_.ps_sent;
incPcapStats.ps_netdrop = pcapStats->ps_netdrop - lastPcapStats_.ps_netdrop;
dbgStats = QString("recv: %1 drop: %2 ifdrop: %3 "
"capt: %4 sent: %5 netdrop: %6")
.arg(incPcapStats.ps_recv)
.arg(incPcapStats.ps_drop)
.arg(incPcapStats.ps_ifdrop)
.arg(incPcapStats.ps_capt)
.arg(incPcapStats.ps_sent)
.arg(incPcapStats.ps_netdrop);
lastPcapStats_ = *pcapStats;
} else {
dbgStats = QString("error reading pcap stats: %1")
.arg(pcap_geterr(handle_));
}
#else
struct pcap_stat pcapStats;
struct pcap_stat incPcapStats;
int ret = pcap_stats(handle_, &pcapStats);
if (ret == 0) {
incPcapStats.ps_recv = pcapStats.ps_recv - lastPcapStats_.ps_recv;
incPcapStats.ps_drop = pcapStats.ps_drop - lastPcapStats_.ps_drop;
incPcapStats.ps_ifdrop = pcapStats.ps_ifdrop - lastPcapStats_.ps_ifdrop;
dbgStats = QString("recv: %1 drop: %2 ifdrop: %3")
.arg(incPcapStats.ps_recv)
.arg(incPcapStats.ps_drop)
.arg(incPcapStats.ps_ifdrop);
lastPcapStats_ = pcapStats;
} else {
dbgStats = QString("error reading pcap stats: %1")
.arg(pcap_geterr(handle_));
}
#endif
return dbgStats;
}
bool PcapSession::clearDebugStats()
{
memset(&lastPcapStats_, 0, sizeof(lastPcapStats_));
return true;
}
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
#include <signal.h> #include <signal.h>
#include <typeinfo> #include <typeinfo>
@ -66,7 +126,7 @@ void PcapSession::postRun()
qDebug("Signal seen and handled"); qDebug("Signal seen and handled");
} }
void PcapSession::stop(pcap_t *handle) void PcapSession::stop()
{ {
// Should be called OUTSIDE the thread's context // Should be called OUTSIDE the thread's context
// XXX: As per the man page for pcap_breakloop, we need both // XXX: As per the man page for pcap_breakloop, we need both
@ -74,7 +134,7 @@ void PcapSession::stop(pcap_t *handle)
// we use a signal for the latter // we use a signal for the latter
// TODO: If the signal mechanism doesn't work, we could try // TODO: If the signal mechanism doesn't work, we could try
// pthread_cancel(thread_); // pthread_cancel(thread_);
pcap_breakloop(handle); pcap_breakloop(handle_);
pthread_kill(thread_.nativeId(), MY_BREAK_SIGNAL); pthread_kill(thread_.nativeId(), MY_BREAK_SIGNAL);
} }

View File

@ -55,27 +55,46 @@ inline uint qHash(const ThreadId &key)
class PcapSession: public QThread class PcapSession: public QThread
{ {
public:
QString debugStats();
protected: protected:
bool clearDebugStats();
void preRun(); void preRun();
void postRun(); void postRun();
void stop(pcap_t *handle); void stop();
pcap_t *handle_{nullptr};
private: private:
static void signalBreakHandler(int /*signum*/); static void signalBreakHandler(int /*signum*/);
ThreadId thread_; ThreadId thread_;
static QHash<ThreadId, bool> signalSeen_; static QHash<ThreadId, bool> signalSeen_;
struct pcap_stat lastPcapStats_;
}; };
#else #else
class PcapSession: public QThread class PcapSession: public QThread
{ {
public:
QString debugStats();
protected: protected:
bool clearDebugStats();
void preRun() {}; void preRun() {};
void postRun() {}; void postRun() {};
void stop(pcap_t *handle) { void stop() {
qDebug("calling breakloop with handle %p", handle); qDebug("calling breakloop with handle %p", handle_);
pcap_breakloop(handle); pcap_breakloop(handle_);
} }
pcap_t *handle_{nullptr};
private:
struct pcap_stat lastPcapStats_;
}; };
#endif #endif

View File

@ -87,6 +87,7 @@ void PcapTxTtagStats::run()
} }
_skip_filter: _skip_filter:
clearDebugStats();
PcapSession::preRun(); PcapSession::preRun();
state_ = kRunning; state_ = kRunning;
while (1) { while (1) {
@ -158,7 +159,7 @@ bool PcapTxTtagStats::stop()
{ {
if (state_ == kRunning) { if (state_ == kRunning) {
stop_ = true; stop_ = true;
PcapSession::stop(handle_); PcapSession::stop();
while (state_ == kRunning) while (state_ == kRunning)
QThread::msleep(10); QThread::msleep(10);
} }