Split the PCAP callback into 2 - one for Rx and one for Tx using pcap_setdirection()
This commit is contained in:
parent
9ac311f80f
commit
0c70668e56
@ -482,33 +482,57 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n)
|
|||||||
// ------------------ PortInfo --------------------
|
// ------------------ PortInfo --------------------
|
||||||
//
|
//
|
||||||
PortInfo::PortInfo(uint id, pcap_if_t *dev)
|
PortInfo::PortInfo(uint id, pcap_if_t *dev)
|
||||||
: monitor(this)
|
: monitorRx(this), monitorTx(this)
|
||||||
{
|
{
|
||||||
char errbuf[PCAP_ERRBUF_SIZE];
|
char errbuf[PCAP_ERRBUF_SIZE];
|
||||||
|
|
||||||
this->dev = dev;
|
this->dev = dev;
|
||||||
devHandle = pcap_open_live(dev->name, 0, PCAP_OPENFLAG_PROMISCUOUS ,
|
|
||||||
|
/*
|
||||||
|
* Get 2 device handles - one for rx and one for tx. If we use only
|
||||||
|
* one handle for both rx and tx anythin that we tx using the single
|
||||||
|
* handle is not received back to us
|
||||||
|
*/
|
||||||
|
devHandleRx = pcap_open_live(dev->name, 0, PCAP_OPENFLAG_PROMISCUOUS ,
|
||||||
1000 /*ms*/, errbuf);
|
1000 /*ms*/, errbuf);
|
||||||
if (devHandle == NULL)
|
if (devHandleRx == NULL)
|
||||||
{
|
{
|
||||||
qDebug("Error opening port %s: %s\n",
|
qDebug("Error opening port %s: %s\n",
|
||||||
dev->name, pcap_geterr(devHandle));
|
dev->name, pcap_geterr(devHandleRx));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
if (pcap_setdirection(devHandleRx, PCAP_D_IN)<0)
|
||||||
if (pcap_setdirection(devHandle, PCAP_D_IN)<0)
|
|
||||||
{
|
{
|
||||||
qDebug("[%s] Error setting direction inbound only\n", dev->name);
|
qDebug("[%s] Error setting direction inbound only\n", dev->name);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* By default, put the interface in statistics mode */
|
/* By default, put the interface in statistics mode */
|
||||||
if (pcap_setmode(devHandle, MODE_STAT)<0)
|
if (pcap_setmode(devHandleRx, MODE_STAT)<0)
|
||||||
|
{
|
||||||
|
qDebug("Error setting statistics mode.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
devHandleTx = pcap_open_live(dev->name, 0, PCAP_OPENFLAG_PROMISCUOUS ,
|
||||||
|
1000 /*ms*/, errbuf);
|
||||||
|
if (devHandleTx == NULL)
|
||||||
|
{
|
||||||
|
qDebug("Error opening port %s: %s\n",
|
||||||
|
dev->name, pcap_geterr(devHandleTx));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pcap_setdirection(devHandleTx, PCAP_D_OUT)<0)
|
||||||
|
{
|
||||||
|
qDebug("[%s] Error setting direction outbound only\n", dev->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* By default, put the interface in statistics mode */
|
||||||
|
if (pcap_setmode(devHandleTx, MODE_STAT)<0)
|
||||||
{
|
{
|
||||||
qDebug("Error setting statistics mode.\n");
|
qDebug("Error setting statistics mode.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
d.mutable_port_id()->set_id(id);
|
d.mutable_port_id()->set_id(id);
|
||||||
|
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
d.set_name(QString("if%1").arg(id).toAscii().constData());
|
d.set_name(QString("if%1").arg(id).toAscii().constData());
|
||||||
#else
|
#else
|
||||||
@ -517,6 +541,8 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev)
|
|||||||
else
|
else
|
||||||
d.set_name(QString("if%1").arg(id).toAscii().constData());
|
d.set_name(QString("if%1").arg(id).toAscii().constData());
|
||||||
#endif
|
#endif
|
||||||
|
d.set_name(d.name()+pcap_datalink_val_to_name(pcap_datalink(devHandleRx)));
|
||||||
|
|
||||||
if (dev->description)
|
if (dev->description)
|
||||||
d.set_description(dev->description);
|
d.set_description(dev->description);
|
||||||
d.set_is_enabled(true); // FIXME(MED):check
|
d.set_is_enabled(true); // FIXME(MED):check
|
||||||
@ -534,7 +560,8 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev)
|
|||||||
isSendQueueDirty=true;
|
isSendQueueDirty=true;
|
||||||
|
|
||||||
// Start the monitor thread
|
// Start the monitor thread
|
||||||
monitor.start();
|
monitorRx.start();
|
||||||
|
monitorTx.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PortInfo::update()
|
void PortInfo::update()
|
||||||
@ -612,11 +639,13 @@ void PortInfo::startTransmit()
|
|||||||
uint bytes, pkts;
|
uint bytes, pkts;
|
||||||
|
|
||||||
// TODO(HI): Stream Mode - one pass/continuous
|
// TODO(HI): Stream Mode - one pass/continuous
|
||||||
bytes = pcap_sendqueue_transmit(devHandle, sendQueue, false);
|
// NOTE: Transmit on the Rx Handle so that we can receive it back
|
||||||
|
// on the Tx Handle to do stats
|
||||||
|
bytes = pcap_sendqueue_transmit(devHandleRx, sendQueue, false);
|
||||||
if (bytes < sendQueue->len)
|
if (bytes < sendQueue->len)
|
||||||
{
|
{
|
||||||
qDebug("port %d: sent (%d/%d) error %s. TxStats may be inconsistent",
|
qDebug("port %d: sent (%d/%d) error %s. TxStats may be inconsistent",
|
||||||
id(), bytes, sendQueue->len, pcap_geterr(devHandle));
|
id(), bytes, sendQueue->len, pcap_geterr(devHandleTx));
|
||||||
|
|
||||||
// parse sendqueue using 'bytes' to get actual pkts sent
|
// parse sendqueue using 'bytes' to get actual pkts sent
|
||||||
#if 0
|
#if 0
|
||||||
@ -649,11 +678,6 @@ void PortInfo::startTransmit()
|
|||||||
// together
|
// together
|
||||||
pcapExtra.txPkts += pkts;
|
pcapExtra.txPkts += pkts;
|
||||||
pcapExtra.txBytes += bytes;
|
pcapExtra.txBytes += bytes;
|
||||||
#else
|
|
||||||
// We don't have a regular stats callback function here, so update
|
|
||||||
// Port TxStats directly here
|
|
||||||
stats.txPkts += pkts;
|
|
||||||
stats.txBytes += bytes;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,7 +694,27 @@ void PortInfo::resetStats()
|
|||||||
// ------------------ PortMonitor -------------------
|
// ------------------ PortMonitor -------------------
|
||||||
//
|
//
|
||||||
|
|
||||||
PortInfo::PortMonitor::PortMonitor(PortInfo *port)
|
PortInfo::PortMonitorRx::PortMonitorRx(PortInfo *port)
|
||||||
|
{
|
||||||
|
this->port = port;
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
{
|
||||||
|
int sz = sizeof(PACKET_OID_DATA) + sizeof(quint64) + 4;
|
||||||
|
//oidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,
|
||||||
|
//sizeof(PACKET_OID_DATA) + sizeof(quint64) - 1);
|
||||||
|
oidData = (PPACKET_OID_DATA) malloc(sz);
|
||||||
|
if (oidData)
|
||||||
|
{
|
||||||
|
memset(oidData, 0, sz);
|
||||||
|
oidData->Length=sizeof(quint64);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
qFatal("failed to alloc oidData");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
PortInfo::PortMonitorTx::PortMonitorTx(PortInfo *port)
|
||||||
{
|
{
|
||||||
this->port = port;
|
this->port = port;
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
@ -691,7 +735,60 @@ PortInfo::PortMonitor::PortMonitor(PortInfo *port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
void PortInfo::PortMonitor::callback(u_char *state,
|
void PortInfo::PortMonitorRx::callbackRx(u_char *state,
|
||||||
|
const struct pcap_pkthdr *header, const u_char *pkt_data)
|
||||||
|
{
|
||||||
|
// This is the WinPcap Callback - which is a 'stats mode' callback
|
||||||
|
|
||||||
|
uint usec;
|
||||||
|
PortInfo *port = (PortInfo*) state;
|
||||||
|
|
||||||
|
quint64 pkts;
|
||||||
|
quint64 bytes;
|
||||||
|
|
||||||
|
// Update RxStats and RxRates using PCAP data
|
||||||
|
pkts = *((quint64*)(pkt_data + 0));
|
||||||
|
bytes = *((quint64*)(pkt_data + 8));
|
||||||
|
|
||||||
|
// Note: PCAP reported bytes includes ETH_FRAME_HDR_SIZE - adjust for it
|
||||||
|
bytes -= pkts * ETH_FRAME_HDR_SIZE;
|
||||||
|
|
||||||
|
usec = (header->ts.tv_sec - port->lastTsRx.tv_sec) * 1000000 +
|
||||||
|
(header->ts.tv_usec - port->lastTsRx.tv_usec);
|
||||||
|
port->stats.rxPps = (pkts * 1000000) / usec;
|
||||||
|
port->stats.rxBps = (bytes * 1000000) / usec;
|
||||||
|
|
||||||
|
port->stats.rxPkts += pkts;
|
||||||
|
port->stats.rxBytes += bytes;
|
||||||
|
|
||||||
|
// Store curr timestamp as last timestamp
|
||||||
|
port->lastTsRx.tv_sec = header->ts.tv_sec;
|
||||||
|
port->lastTsRx.tv_usec = header->ts.tv_usec;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
for (int i=0; i < 16; i++)
|
||||||
|
{
|
||||||
|
qDebug("%02x ", pkt_data[i]);
|
||||||
|
}
|
||||||
|
qDebug("{%d: %llu, %llu}\n", port->id(),
|
||||||
|
pkts, bytes);
|
||||||
|
qDebug("[%d: pkts : %llu]\n", port->id(), port->stats.rxPkts);
|
||||||
|
qDebug("[%d: bytes: %llu]\n", port->id(), port->stats.rxBytes);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Retreive NIC stats
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
port->monitorRx.oidData->Oid = OID_GEN_RCV_OK;
|
||||||
|
if (PacketRequest(port->devHandleRx->adapter, 0, port->monitorRx.oidData))
|
||||||
|
{
|
||||||
|
if (port->monitorRx.oidData->Length <= sizeof(port->stats.rxPktsNic))
|
||||||
|
memcpy((void*)&port->stats.rxPktsNic,
|
||||||
|
(void*)port->monitorRx.oidData->Data,
|
||||||
|
port->monitorRx.oidData->Length);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void PortInfo::PortMonitorTx::callbackTx(u_char *state,
|
||||||
const struct pcap_pkthdr *header, const u_char *pkt_data)
|
const struct pcap_pkthdr *header, const u_char *pkt_data)
|
||||||
{
|
{
|
||||||
// This is the WinPcap Callback - which is a 'stats mode' callback
|
// This is the WinPcap Callback - which is a 'stats mode' callback
|
||||||
@ -717,15 +814,25 @@ void PortInfo::PortMonitor::callback(u_char *state,
|
|||||||
port->stats.rxPkts += pkts;
|
port->stats.rxPkts += pkts;
|
||||||
port->stats.rxBytes += bytes;
|
port->stats.rxBytes += bytes;
|
||||||
|
|
||||||
// Update TxStats from PcapExtra
|
// Since WinPCAP (due to NDIS limitation) cannot distinguish between
|
||||||
|
// rx/tx packets, pcap stats are not of much use - for the tx stats
|
||||||
|
// update from PcapExtra
|
||||||
|
|
||||||
|
pkts = port->pcapExtra.txPkts - port->stats.txPkts;
|
||||||
|
bytes = port->pcapExtra.txBytes - port->stats.txBytes;
|
||||||
|
|
||||||
|
// Use the pcap timestamp for rate calculation though
|
||||||
|
usec = (header->ts.tv_sec - port->lastTs.tv_sec) * 1000000 +
|
||||||
|
(header->ts.tv_usec - port->lastTs.tv_usec);
|
||||||
|
port->stats.txPps = (pkts * 1000000) / usec;
|
||||||
|
port->stats.txBps = (bytes * 1000000) / usec;
|
||||||
|
|
||||||
port->stats.txPkts = port->pcapExtra.txPkts;
|
port->stats.txPkts = port->pcapExtra.txPkts;
|
||||||
port->stats.txBytes = port->pcapExtra.txBytes;
|
port->stats.txBytes = port->pcapExtra.txBytes;
|
||||||
|
|
||||||
//! \TODO TxRates
|
|
||||||
|
|
||||||
// Store curr timestamp as last timestamp
|
// Store curr timestamp as last timestamp
|
||||||
port->lastTs.tv_sec = header->ts.tv_sec;
|
port->lastTsTx.tv_sec = header->ts.tv_sec;
|
||||||
port->lastTs.tv_usec = header->ts.tv_usec;
|
port->lastTsTx.tv_usec = header->ts.tv_usec;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
for (int i=0; i < 16; i++)
|
for (int i=0; i < 16; i++)
|
||||||
@ -740,26 +847,18 @@ void PortInfo::PortMonitor::callback(u_char *state,
|
|||||||
|
|
||||||
// Retreive NIC stats
|
// Retreive NIC stats
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
port->monitor.oidData->Oid = OID_GEN_RCV_OK;
|
port->monitorTx.oidData->Oid = OID_GEN_XMIT_OK;
|
||||||
if (PacketRequest(port->devHandle->adapter, 0, port->monitor.oidData))
|
if (PacketRequest(port->devHandleTx->adapter, 0, port->monitorTx.oidData))
|
||||||
{
|
{
|
||||||
if (port->monitor.oidData->Length <= sizeof(port->stats.rxPktsNic))
|
if (port->monitorTx.oidData->Length <= sizeof(port->stats.txPktsNic))
|
||||||
memcpy((void*)&port->stats.rxPktsNic,
|
|
||||||
(void*)port->monitor.oidData->Data,
|
|
||||||
port->monitor.oidData->Length);
|
|
||||||
}
|
|
||||||
port->monitor.oidData->Oid = OID_GEN_XMIT_OK;
|
|
||||||
if (PacketRequest(port->devHandle->adapter, 0, port->monitor.oidData))
|
|
||||||
{
|
|
||||||
if (port->monitor.oidData->Length <= sizeof(port->stats.txPktsNic))
|
|
||||||
memcpy((void*)&port->stats.txPktsNic,
|
memcpy((void*)&port->stats.txPktsNic,
|
||||||
(void*)port->monitor.oidData->Data,
|
(void*)port->monitorTx.oidData->Data,
|
||||||
port->monitor.oidData->Length);
|
port->monitorTx.oidData->Length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void PortInfo::PortMonitor::callback(u_char *state,
|
void PortInfo::PortMonitorRx::callbackRx(u_char *state,
|
||||||
const struct pcap_pkthdr *header, const u_char *pkt_data)
|
const struct pcap_pkthdr *header, const u_char *pkt_data)
|
||||||
{
|
{
|
||||||
// This is the LibPcap Callback - which is a 'capture mode' callback
|
// This is the LibPcap Callback - which is a 'capture mode' callback
|
||||||
@ -772,8 +871,8 @@ void PortInfo::PortMonitor::callback(u_char *state,
|
|||||||
quint64 bytes;
|
quint64 bytes;
|
||||||
|
|
||||||
// Update RxStats and RxRates using PCAP data
|
// Update RxStats and RxRates using PCAP data
|
||||||
usec = (header->ts.tv_sec - port->lastTs.tv_sec) * 1000000 +
|
usec = (header->ts.tv_sec - port->lastTsRx.tv_sec) * 1000000 +
|
||||||
(header->ts.tv_usec - port->lastTs.tv_usec);
|
(header->ts.tv_usec - port->lastTsRx.tv_usec);
|
||||||
// TODO(rate)
|
// TODO(rate)
|
||||||
#if 0
|
#if 0
|
||||||
port->stats.rxPps = (pkts * 1000000) / usec;
|
port->stats.rxPps = (pkts * 1000000) / usec;
|
||||||
@ -785,25 +884,78 @@ void PortInfo::PortMonitor::callback(u_char *state,
|
|||||||
port->stats.rxPkts++;
|
port->stats.rxPkts++;
|
||||||
port->stats.rxBytes += header->len;
|
port->stats.rxBytes += header->len;
|
||||||
|
|
||||||
// NOTE: Port TxStats are updated by Port Transmit Function itself
|
// Store curr timestamp as last timestamp
|
||||||
// since this callback is called only when a packet is received
|
port->lastTsRx.tv_sec = header->ts.tv_sec;
|
||||||
|
port->lastTsRx.tv_usec = header->ts.tv_usec;
|
||||||
|
}
|
||||||
|
|
||||||
//! \TODO TxRates
|
void PortInfo::PortMonitorTx::callbackTx(u_char *state,
|
||||||
|
const struct pcap_pkthdr *header, const u_char *pkt_data)
|
||||||
|
{
|
||||||
|
// This is the LibPcap Callback - which is a 'capture mode' callback
|
||||||
|
// This callback is called once for EVERY packet
|
||||||
|
|
||||||
|
uint usec;
|
||||||
|
PortInfo *port = (PortInfo*) state;
|
||||||
|
|
||||||
|
quint64 pkts;
|
||||||
|
quint64 bytes;
|
||||||
|
|
||||||
|
// Update TxStats and TxRates using PCAP data
|
||||||
|
usec = (header->ts.tv_sec - port->lastTsTx.tv_sec) * 1000000 +
|
||||||
|
(header->ts.tv_usec - port->lastTsTx.tv_usec);
|
||||||
|
// TODO(rate)
|
||||||
|
#if 0
|
||||||
|
port->stats.txPps = (pkts * 1000000) / usec;
|
||||||
|
port->stats.txBps = (bytes * 1000000) / usec;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Note: For a 'capture callback' PCAP reported bytes DOES NOT include
|
||||||
|
// ETH_FRAME_HDR_SIZE - so don't adjust for it
|
||||||
|
|
||||||
|
port->stats.txPkts++;
|
||||||
|
port->stats.txBytes += header->len;
|
||||||
|
|
||||||
// Store curr timestamp as last timestamp
|
// Store curr timestamp as last timestamp
|
||||||
port->lastTs.tv_sec = header->ts.tv_sec;
|
port->lastTsTx.tv_sec = header->ts.tv_sec;
|
||||||
port->lastTs.tv_usec = header->ts.tv_usec;
|
port->lastTsTx.tv_usec = header->ts.tv_usec;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
void PortInfo::PortMonitor::run()
|
void PortInfo::PortMonitorRx::run()
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
qDebug("before pcap_loop\n");
|
qDebug("before pcap_loop rx \n");
|
||||||
|
|
||||||
/* Start the main loop */
|
/* Start the main loop */
|
||||||
ret = pcap_loop(port->devHandle, -1, &PortInfo::PortMonitor::callback,
|
ret = pcap_loop(port->devHandleRx, -1,
|
||||||
(u_char*) port);
|
&PortInfo::PortMonitorRx::callbackRx, (u_char*) port);
|
||||||
|
|
||||||
|
switch(ret)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
qDebug("Unexpected return from pcap_loop()\n");
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
qDebug("Unsolicited (error) return from pcap_loop()\n");
|
||||||
|
break;
|
||||||
|
case -2:
|
||||||
|
qDebug("Solicited return from pcap_loop()\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qDebug("Unknown return value from pcap_loop()\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PortInfo::PortMonitorTx::run()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
qDebug("before pcap_loopTx\n");
|
||||||
|
|
||||||
|
/* Start the main loop */
|
||||||
|
ret = pcap_loop(port->devHandleTx, -1,
|
||||||
|
&PortInfo::PortMonitorTx::callbackTx, (u_char*) port);
|
||||||
|
|
||||||
switch(ret)
|
switch(ret)
|
||||||
{
|
{
|
||||||
|
@ -53,7 +53,7 @@ class PortInfo
|
|||||||
{
|
{
|
||||||
friend class MyService;
|
friend class MyService;
|
||||||
|
|
||||||
class PortMonitor: public QThread
|
class PortMonitorRx: public QThread
|
||||||
{
|
{
|
||||||
friend class PortInfo;
|
friend class PortInfo;
|
||||||
|
|
||||||
@ -62,8 +62,23 @@ class PortInfo
|
|||||||
PPACKET_OID_DATA oidData;
|
PPACKET_OID_DATA oidData;
|
||||||
#endif
|
#endif
|
||||||
public:
|
public:
|
||||||
PortMonitor(PortInfo *port);
|
PortMonitorRx(PortInfo *port);
|
||||||
static void callback(u_char *state,
|
static void callbackRx(u_char *state,
|
||||||
|
const struct pcap_pkthdr *header, const u_char *pkt_data);
|
||||||
|
void run();
|
||||||
|
};
|
||||||
|
|
||||||
|
class PortMonitorTx: public QThread
|
||||||
|
{
|
||||||
|
friend class PortInfo;
|
||||||
|
|
||||||
|
PortInfo *port;
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
PPACKET_OID_DATA oidData;
|
||||||
|
#endif
|
||||||
|
public:
|
||||||
|
PortMonitorTx(PortInfo *port);
|
||||||
|
static void callbackTx(u_char *state,
|
||||||
const struct pcap_pkthdr *header, const u_char *pkt_data);
|
const struct pcap_pkthdr *header, const u_char *pkt_data);
|
||||||
void run();
|
void run();
|
||||||
};
|
};
|
||||||
@ -104,15 +119,18 @@ class PortInfo
|
|||||||
};
|
};
|
||||||
|
|
||||||
pcap_if_t *dev;
|
pcap_if_t *dev;
|
||||||
pcap_t *devHandle;
|
pcap_t *devHandleRx;
|
||||||
|
pcap_t *devHandleTx;
|
||||||
pcap_send_queue *sendQueue;
|
pcap_send_queue *sendQueue;
|
||||||
bool isSendQueueDirty;
|
bool isSendQueueDirty;
|
||||||
PcapExtra pcapExtra;
|
PcapExtra pcapExtra;
|
||||||
PortMonitor monitor;
|
PortMonitorRx monitorRx;
|
||||||
|
PortMonitorTx monitorTx;
|
||||||
|
|
||||||
struct PortStats epochStats;
|
struct PortStats epochStats;
|
||||||
struct PortStats stats;
|
struct PortStats stats;
|
||||||
struct timeval lastTs; //! used for Rate Stats calculations
|
struct timeval lastTsRx; //! used for Rate Stats calculations
|
||||||
|
struct timeval lastTsTx; //! used for Rate Stats calculations
|
||||||
|
|
||||||
/*! StreamInfo::d::stream_id and index into streamList[] are NOT same! */
|
/*! StreamInfo::d::stream_id and index into streamList[] are NOT same! */
|
||||||
QList<StreamInfo> streamList;
|
QList<StreamInfo> streamList;
|
||||||
|
Loading…
Reference in New Issue
Block a user