For Linux added specific code to put interfaces in PROMISC mode, since we no longer use PCAP to do stats (which was indirectly setting PROMISC). Also added signal handlers to do cleanup for SIGTERM and SIGINT. Some code indentation fixes also.
Fixes issue 52
This commit is contained in:
parent
264b446410
commit
e188655e67
@ -21,10 +21,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
|||||||
|
|
||||||
#include "../common/protocolmanager.h"
|
#include "../common/protocolmanager.h"
|
||||||
|
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
#include "signal.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
extern ProtocolManager *OstProtocolManager;
|
extern ProtocolManager *OstProtocolManager;
|
||||||
|
|
||||||
int myport;
|
int myport;
|
||||||
|
|
||||||
|
void cleanup(int /*signum*/)
|
||||||
|
{
|
||||||
|
qApp->exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
@ -39,11 +48,24 @@ int main(int argc, char *argv[])
|
|||||||
if (!drone.init())
|
if (!drone.init())
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
struct sigaction sa;
|
||||||
|
memset(&sa, 0, sizeof(sa));
|
||||||
|
sa.sa_handler = cleanup;
|
||||||
|
if (sigaction(SIGTERM, &sa, NULL))
|
||||||
|
qDebug("Failed to install SIGTERM handler. Cleanup may not happen!!!");
|
||||||
|
if (sigaction(SIGINT, &sa, NULL))
|
||||||
|
qDebug("Failed to install SIGINT handler. Cleanup may not happen!!!");
|
||||||
|
#endif
|
||||||
|
|
||||||
drone.setWindowFlags(drone.windowFlags()
|
drone.setWindowFlags(drone.windowFlags()
|
||||||
| Qt::WindowMaximizeButtonHint
|
| Qt::WindowMaximizeButtonHint
|
||||||
| Qt::WindowMinimizeButtonHint);
|
| Qt::WindowMinimizeButtonHint);
|
||||||
drone.showMinimized();
|
drone.showMinimized();
|
||||||
app.exec();
|
app.exec();
|
||||||
|
|
||||||
|
delete OstProtocolManager;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,9 +23,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
|||||||
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <errno.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
QList<LinuxPort*> LinuxPort::allPorts_;
|
QList<LinuxPort*> LinuxPort::allPorts_;
|
||||||
LinuxPort::StatsMonitor *LinuxPort::monitor_;
|
LinuxPort::StatsMonitor *LinuxPort::monitor_;
|
||||||
@ -33,9 +37,12 @@ LinuxPort::StatsMonitor *LinuxPort::monitor_;
|
|||||||
LinuxPort::LinuxPort(int id, const char *device)
|
LinuxPort::LinuxPort(int id, const char *device)
|
||||||
: PcapPort(id, device)
|
: PcapPort(id, device)
|
||||||
{
|
{
|
||||||
|
clearPromisc_ = false;
|
||||||
|
|
||||||
// We don't need per port Rx/Tx monitors for Linux
|
// We don't need per port Rx/Tx monitors for Linux
|
||||||
delete monitorRx_;
|
delete monitorRx_;
|
||||||
delete monitorTx_;
|
delete monitorTx_;
|
||||||
|
monitorRx_ = monitorTx_ = NULL;
|
||||||
|
|
||||||
// We have one monitor for both Rx/Tx of all ports
|
// We have one monitor for both Rx/Tx of all ports
|
||||||
if (!monitor_)
|
if (!monitor_)
|
||||||
@ -50,6 +57,32 @@ LinuxPort::LinuxPort(int id, const char *device)
|
|||||||
|
|
||||||
LinuxPort::~LinuxPort()
|
LinuxPort::~LinuxPort()
|
||||||
{
|
{
|
||||||
|
qDebug("In %s", __FUNCTION__);
|
||||||
|
|
||||||
|
if (clearPromisc_)
|
||||||
|
{
|
||||||
|
int sd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
struct ifreq ifr;
|
||||||
|
|
||||||
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
|
strncpy(ifr.ifr_name, name(), sizeof(ifr.ifr_name));
|
||||||
|
|
||||||
|
if (ioctl(sd, SIOCGIFFLAGS, &ifr) != -1)
|
||||||
|
{
|
||||||
|
if (ifr.ifr_flags & IFF_PROMISC)
|
||||||
|
{
|
||||||
|
ifr.ifr_flags &= ~IFF_PROMISC;
|
||||||
|
if (ioctl(sd, SIOCSIFFLAGS, &ifr) == -1)
|
||||||
|
qDebug("Failed clearing promisc flag. SIOCSIFFLAGS failed: %s",
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
qDebug("Failed clearing promisc flag. SIOCGIFFLAGS failed: %s",
|
||||||
|
strerror(errno));
|
||||||
|
|
||||||
|
close(sd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinuxPort::init()
|
void LinuxPort::init()
|
||||||
@ -86,7 +119,7 @@ LinuxPort::StatsMonitor::StatsMonitor()
|
|||||||
void LinuxPort::StatsMonitor::run()
|
void LinuxPort::StatsMonitor::run()
|
||||||
{
|
{
|
||||||
PortStats **portStats;
|
PortStats **portStats;
|
||||||
int fd;
|
int fd, sd;
|
||||||
QByteArray buf;
|
QByteArray buf;
|
||||||
int len;
|
int len;
|
||||||
char *p, *end;
|
char *p, *end;
|
||||||
@ -96,6 +129,7 @@ void LinuxPort::StatsMonitor::run()
|
|||||||
"%llu%llu%u%u%u%u%n%n%llu%llu%u%u%u%u%u%n\n",
|
"%llu%llu%u%u%u%u%n%n%llu%llu%u%u%u%u%u%n\n",
|
||||||
};
|
};
|
||||||
const char *fmt;
|
const char *fmt;
|
||||||
|
struct ifreq ifr;
|
||||||
|
|
||||||
//
|
//
|
||||||
// We first setup stuff before we start polling for stats
|
// We first setup stuff before we start polling for stats
|
||||||
@ -143,6 +177,10 @@ void LinuxPort::StatsMonitor::run()
|
|||||||
portStats = (PortStats**) calloc(count, sizeof(PortStats));
|
portStats = (PortStats**) calloc(count, sizeof(PortStats));
|
||||||
Q_ASSERT(portStats != NULL);
|
Q_ASSERT(portStats != NULL);
|
||||||
|
|
||||||
|
sd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
Q_ASSERT(sd >= 0);
|
||||||
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Populate the port stats array
|
// Populate the port stats array
|
||||||
//
|
//
|
||||||
@ -178,6 +216,29 @@ void LinuxPort::StatsMonitor::run()
|
|||||||
if (strncmp(port->name(), p, int(q-p)) == 0)
|
if (strncmp(port->name(), p, int(q-p)) == 0)
|
||||||
{
|
{
|
||||||
portStats[index] = &(port->stats_);
|
portStats[index] = &(port->stats_);
|
||||||
|
|
||||||
|
// Set promisc mode, if not already set
|
||||||
|
strncpy(ifr.ifr_name, port->name(), sizeof(ifr.ifr_name));
|
||||||
|
if (ioctl(sd, SIOCGIFFLAGS, &ifr) != -1)
|
||||||
|
{
|
||||||
|
if ((ifr.ifr_flags & IFF_PROMISC) == 0)
|
||||||
|
{
|
||||||
|
ifr.ifr_flags |= IFF_PROMISC;
|
||||||
|
if (ioctl(sd, SIOCSIFFLAGS, &ifr) != -1)
|
||||||
|
port->clearPromisc_ = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug("%s: failed to set promisc; "
|
||||||
|
"SIOCSIFFLAGS failed (%s)",
|
||||||
|
port->name(), strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug("%s: failed to set promisc; SIOCGIFFLAGS failed (%s)",
|
||||||
|
port->name(), strerror(errno));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,6 +253,8 @@ void LinuxPort::StatsMonitor::run()
|
|||||||
}
|
}
|
||||||
Q_ASSERT(index == count);
|
Q_ASSERT(index == count);
|
||||||
|
|
||||||
|
close(sd);
|
||||||
|
|
||||||
qDebug("stats for %d ports setup", count);
|
qDebug("stats for %d ports setup", count);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -48,6 +48,7 @@ protected:
|
|||||||
static const int kRefreshFreq_ = 1; // in seconds
|
static const int kRefreshFreq_ = 1; // in seconds
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool clearPromisc_;
|
||||||
static QList<LinuxPort*> allPorts_;
|
static QList<LinuxPort*> allPorts_;
|
||||||
static StatsMonitor *monitor_; // rx/tx stats for ALL ports
|
static StatsMonitor *monitor_; // rx/tx stats for ALL ports
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user