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:
Srivats P. 2011-10-22 14:55:05 +05:30
parent 264b446410
commit e188655e67
3 changed files with 195 additions and 109 deletions

View File

@ -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;
} }

View File

@ -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);
// //

View File

@ -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
}; };