diff --git a/.gitignore b/.gitignore index 14d024c..dce9c7d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ src/inetvis src/inetvis.pro.user .moc/ qrc_icons.cpp +recorded/* +src/recorded/* diff --git a/README.md b/README.md index b63e6cb..9bcac8b 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,52 @@ This project is based off of the original work by JP van Riel and Barry Irwin of # Notes -This project was originally written in Qt3 and compiled to 32-bit code, it has since been ported to native Qt4, -and been set to compile a 64-bit binary. +This project was originally written in Qt3 and compiled to 32-bit code, it has since been ported to Qt5, +and been updated to compile a 64-bit binary. The instructions below have all been tested on the current version of Ubuntu, 17.04 64-bit. +# Installing InetVis (from release archive) + +A compiled version of InetVis is available under the releases section of https://github.com/yestinj/inetvis. + +In order to install and run the software please do the following: + +1. Download the latest release archive from the releases page. +2. Extract the archive which will be called something like `inetvis-2.0.0.tgz` +3. Change into the extracted directory, something like `inetvis-2.0.0` +4. Run the `install_inetvis.sh` shell script to install the software. + 1. This script will: install the software to `/opt/inetvis-` + 2. Create a symlink directory `/opt/inetvis` for convenience + 3. Copy across the relevant files to the new directory under `/opt`. + 4. Place an icon file in `/usr/share/icons/hicolor/48x48/apps/` + 5. Place a `desktop` file in `/usr/share/applications`, allowing inetvis to be found in the menu on Ubuntu systems. + 6. Create a symlink at `/usr/local/bin/inetvis` pointing to the main binary. + 7. Set the `cap_net_raw`, and `cap_net_admin=eip` capabilities on the inetvis binary allowing for monitoring packets on local host without running as root. +5. If the script completes successfully inetvis should now be in your path, and also be in the menu system of your distribution. + +# Running InetVis + +To run InetVis do the following: + +1. Download the latest InetVis release archive from the releases page. + * Alternatively clone the repository, and follow the build procedure above +2. Install the requirements (if necessary): + * `sudo apt-get install build-essential g++ libc6 libstdc++6 libc6-dev make libpcap-dev libgl1-mesa-dev libqt4-dev libqt4-dev qt4-dev-tools` + * Note: These are also the build requirements, installing them may not be necessary for simply running the application. + +If you installed InetVis as per the instructions, you should simply be able +to run the `inetvis` command from your command line or menu system. + +If you have built the binary yourself, please run it using manually using `./inetvis` from the src directory. + +You will need to run your built binary as root should you wish to monitor local host. + +Have fun! :-) + +# Uninstalling InetVis + +A convenience script is included in the release archive, namely `uninstall_inetvis.sh`, which can be used to completely remove inetvis from your system at any time. # Building InetVis @@ -38,30 +79,13 @@ Finally, build the `inetvis` binary: This should result in a new `inetvis` binary being generated within the source directory. -# Running InetVis - -To run InetVis do the following: - -1. Download the latest InetVis binary from the releases page. - * Alternatively clone the repository and run the `inetvis` binary in the root directory. - * Or simply use the binary generated from the build process, in `src/` -2. Install the requirements (if necessary): - * `sudo apt-get install build-essential g++ libc6 libstdc++6 libc6-dev make libpcap-dev libgl1-mesa-dev libqt4-dev libqt4-dev qt4-dev-tools` - * Note: These are also the build requirements, installing them may not be necessary for simply running. - -Next, locate the binary you downloaded/built and run it as follows: `./inetvis` - -If you would like to monitor your own host for network events, instead of replaying capture files, please ensure that you run as root, i.e. `sudo ./inetvis` - -Have fun! :-) - # Development -Development is currently done using a combination of Atom, vim, and Qt Creator. +Development is currently done using Qt Creator. QT Creator allows for simple editing of source code, as well as graphical form editing, and can be installed in Debian flavours of Linux by installing the `qtcreator` package. # Versioning -This software will make use of Semantic Versioning 2.0.0 (http://semver.org/) once reaching the v1.0.0 release phase. +This software uses Semantic Versioning 2.0.0 (http://semver.org/) as of release v2.0.0. diff --git a/inetvis b/inetvis deleted file mode 100755 index d622d28..0000000 Binary files a/inetvis and /dev/null differ diff --git a/InetVis_GPL2_License.txt b/lic/InetVis_GPL2_License.txt similarity index 100% rename from InetVis_GPL2_License.txt rename to lic/InetVis_GPL2_License.txt diff --git a/Libpcap_BSD_License.txt b/lic/Libpcap_BSD_License.txt similarity index 100% rename from Libpcap_BSD_License.txt rename to lic/Libpcap_BSD_License.txt diff --git a/src/controlpanel.ui b/src/controlpanel.ui index 9f2e362..3544fd1 100644 --- a/src/controlpanel.ui +++ b/src/controlpanel.ui @@ -749,7 +749,7 @@ 0 0 630 - 25 + 22 @@ -810,8 +810,7 @@ - - + .. &New @@ -1158,7 +1157,7 @@ true - true + false Monitor &Local Host @@ -1284,7 +1283,7 @@ fileExitAction - activated() + triggered() ControlPanel close() @@ -1300,7 +1299,7 @@ fileOpenAction - activated() + triggered() ControlPanel fileOpen() @@ -1316,7 +1315,7 @@ helpAboutAction - activated() + triggered() ControlPanel helpAbout() @@ -1332,7 +1331,7 @@ monitorLocalHostAction - activated() + triggered() ControlPanel monitorLocalHostSelected() @@ -1348,7 +1347,7 @@ pauseAction - activated() + triggered() ControlPanel pauseMenuAction() @@ -1364,7 +1363,7 @@ playAction - activated() + triggered() ControlPanel playMenuAction() @@ -1396,7 +1395,7 @@ recordCapture_Current_Frame_to_FileAction - activated() + triggered() ControlPanel takeSnapshot() @@ -1460,7 +1459,7 @@ replayCaptureFileAction - activated() + triggered() ControlPanel replayFileModeSelected() @@ -1524,7 +1523,7 @@ replayReplay_RateNormal_Playback_Speed_1xAction - activated() + triggered() ControlPanel setNormalReplaySpeed() @@ -1556,7 +1555,7 @@ timeScaleLineEdit - lostFocus() + editingFinished() ControlPanel timeScaleLineEditChanged() @@ -1716,7 +1715,7 @@ viewDisplayWindowAction - activated() + triggered() ControlPanel viewVisDisplayPanel() @@ -1732,7 +1731,7 @@ viewPlotterSettingsAction - activated() + triggered() ControlPanel viewPlotterSettings() @@ -1748,7 +1747,7 @@ viewReferenceFrameSettingsAction - activated() + triggered() ControlPanel viewReferenceFrameSettings() @@ -1764,7 +1763,7 @@ helpHelpAction - activated() + triggered() ControlPanel helpDoc() diff --git a/src/controlpanelwidget.cpp b/src/controlpanelwidget.cpp index de0bb41..e96e7d9 100644 --- a/src/controlpanelwidget.cpp +++ b/src/controlpanelwidget.cpp @@ -5,12 +5,10 @@ ControlPanelWidget::ControlPanelWidget(QMainWindow *parent) : QMainWindow(parent) { setupUi(this); - // TODO: I think this would be called here.. need to confirm. init(); } ControlPanelWidget::~ControlPanelWidget() { - // TODO: Ensure this is correct. destroy(); } @@ -48,8 +46,6 @@ void ControlPanelWidget::init() { //init about dialog aboutDialog = new AboutDialogWidget((QWidget*)this); helpDialog = new HelpDocumentationDialogWidget((QWidget*)this); - //aboutDialog->setShown(false); - //helpDialog->setShown(false); //init error message dialog qErrMsg = new QErrorMessage((QWidget*)this); @@ -136,6 +132,11 @@ void ControlPanelWidget::fileOpen() { replayPositionGroupBox->setEnabled(true); ReplaySpeedGroupBox->setEnabled(true); recordToolButton->setEnabled(true); + + // if recording of live captures is disabled, turn this menu item back on now. + if (DISABLE_RECORDING_LIVE_CAPTURE) { + recordDump_to_Pcap_FileAction->setEnabled(true); + } } else { //canceled @@ -160,7 +161,15 @@ void ControlPanelWidget::monitorLocalHostSelected() { //disable editing the replay position and time scale replayPositionGroupBox->setEnabled(false); ReplaySpeedGroupBox->setEnabled(false); - recordToolButton->setEnabled(true); + + // Don't enable the record button if this flag is set. + if (!DISABLE_RECORDING_LIVE_CAPTURE) { + recordToolButton->setEnabled(true); + } else { + recordToolButton->setEnabled(false); + recordDump_to_Pcap_FileAction->setDisabled(true); + } + //TODO: In future may create temp file so that seeking back is possible //while monitoring live @@ -229,7 +238,6 @@ void ControlPanelWidget::captureFramesToFile(bool activate) { { captureFramesSetByUser = false; recordCapture_Frames_to_FileAction->setChecked(false); videoClipToolButton->setChecked(false); - //update UI log if(LogUI::isEnabled()) LogUI::logEvent("[CP] frame capture stoped at replay time: " @@ -241,35 +249,39 @@ void ControlPanelWidget::captureFramesToFile(bool activate) { } void ControlPanelWidget::record(bool buttonOn) { - if (recordToPcapFileSetByUser) - { emit recordToFile(buttonOn); + + if (recordToPcapFileSetByUser) { + emit recordToFile(buttonOn); + //update gui and sync menu with button //recordToPcapFileSetByUser is a hack to avoid retriggering the - //record slot - if (buttonOn) - { recordToPcapFileSetByUser = false; + //record slotf + if (buttonOn) { + recordToPcapFileSetByUser = false; recordDump_to_Pcap_FileAction->setChecked(true); recordToolButton->setChecked(true); recordToPcapFileSetByUser = true; //update UI log - if(LogUI::isEnabled()) + if(LogUI::isEnabled()) { LogUI::logEvent("[CP] packet recording started at replay time: " + strGetRepPos()); + } } - else - { recordToPcapFileSetByUser = false; + else { + + recordToPcapFileSetByUser = false; recordDump_to_Pcap_FileAction->setChecked(false); recordToolButton->setChecked(false); recordToPcapFileSetByUser = true; //update UI log - if(LogUI::isEnabled()) + if(LogUI::isEnabled()) { LogUI::logEvent("[CP] packet recording stoped at replay time: " + strGetRepPos()); + } } } - } void ControlPanelWidget::replayFileModeSelected() { diff --git a/src/controlpanelwidget.h b/src/controlpanelwidget.h index a00703b..2ed0678 100644 --- a/src/controlpanelwidget.h +++ b/src/controlpanelwidget.h @@ -12,6 +12,8 @@ #include "helpdocumentationdialogwidget.h" #include "logui.h" +#define DISABLE_RECORDING_LIVE_CAPTURE true + class ControlPanelWidget : public QMainWindow, public Ui::ControlPanel { Q_OBJECT diff --git a/src/dataproc.cpp b/src/dataproc.cpp index b118291..3d2d4c0 100644 --- a/src/dataproc.cpp +++ b/src/dataproc.cpp @@ -183,7 +183,7 @@ void DataProcessor::DataExtractor::readCaptureFile() TimeUtil::timevalToQDateTime(capEndTm, dataProcessor->captureEndTime); cerr << "DEBUG: replay file end reached at: " - << capEndTm.toString()<< '\n'; + << capEndTm.toString().toLatin1().data() << '\n'; #endif //close file @@ -226,8 +226,7 @@ void DataProcessor::DataExtractor::readCaptureFile() } -void DataProcessor::DataExtractor::monitorLocalHost() -{ +void DataProcessor::DataExtractor::monitorLocalHost() { /* TODO: This method may lend itself to a threaded implimentation given the following warning in the pcap man file: @@ -243,8 +242,8 @@ void DataProcessor::DataExtractor::monitorLocalHost() #ifdef DEBUG_DATA_EXTRACTOR //this method should not be called if a live apture interface has not been //opened - if (liveCaptureInstance == NULL) - { //capture instacnce invalid + if (liveCaptureInstance == NULL) { + //capture instacnce invalid reportError(("capture instance is null, unable to monitor on local interface" + strLocalInterface), "DataExtractor::monitorLocalHost()"); dataProcessor->pause(); @@ -262,52 +261,44 @@ void DataProcessor::DataExtractor::monitorLocalHost() //should be set to non blocking mode, so pcap_dispatch will return if there //are no packets to be read - if (pcapRet >= 0) - { //packets processed no more to be done for now + if (pcapRet >= 0) { + //packets processed no more to be done for now //update the capture end time and buffer position - //Commented out the two below lines, getting value, assigning, but never using. - //PacketEvent *pe; - //pe = &dataProcessor->packetEventBuffer.front(); + PacketEvent *pe; + pe = &dataProcessor->packetEventBuffer.front(); #ifdef DEBUG_DATA_RENDER cerr << "DEBUG: Succefully returning from monitoring interface, with no further packets to process for the moment\n"; #endif - return; - } - if (pcapRet == -2) - { + if (pcapRet == -2) { #ifdef DEBUG_DATA_RENDER cerr << "DEBUG: monitoring was interupted by pcap_breakloop() call before any packets could be processed\n"; #endif - return; } - if (pcapRet == -1) - { strcpy(pcapErrorBuffer, pcap_geterr(liveCaptureInstance)); //copy error into + if (pcapRet == -1) { + strcpy(pcapErrorBuffer, pcap_geterr(liveCaptureInstance)); //copy error into //error buffer reportError(("error monitoring off interface " + strLocalInterface), "libpacp::pcap_dispatch()"); return; } - } -void DataProcessor::DataExtractor::monitorRemoteServer() -{ +void DataProcessor::DataExtractor::monitorRemoteServer() { //TODO: open a socket and recieve data updates from a server capturing //packets - } void DataProcessor::DataExtractor::processPacket(u_char *args, - const struct pcap_pkthdr *header, const u_char *snapshot) -{ + const struct pcap_pkthdr *header, const u_char *snapshot) { + //this method is static to allow access to libpacp and be used as a //pcap_handler callback function. statDataProcessor needs to be correctly //assigned before using this function @@ -323,9 +314,9 @@ void DataProcessor::DataExtractor::processPacket(u_char *args, Plotter::plot(statDataProcessor->packetEventBuffer.front()); //packet recording - if (statDataProcessor->recordToFile) - { //record while within time window start - if (TimeUtil::timevalGreaterThan(header->ts, + if (statDataProcessor->recordToFile) { + //record while within time window start + if (TimeUtil::timevalGreaterThan(header->ts, statDataProcessor->timeWindowEnd)) { //check to ensure value not previously recorded if (TimeUtil::timevalGreaterThan(header->ts, @@ -340,7 +331,7 @@ void DataProcessor::DataExtractor::processPacket(u_char *args, QDateTime timeStamp; TimeUtil::timevalToQDateTime(timeStamp, header->ts); cerr << "DEBUG: write packet to file with timestamp = " - << timeStamp.toString("yyyy/MM/dd - hh:mm:ss:zzz") << '\n'; + << timeStamp.toString("yyyy/MM/dd - hh:mm:ss:zzz").toLatin1().data() << '\n'; #endif } @@ -559,7 +550,7 @@ bool DataProcessor::DataExtractor::lookupNetwork() ret = pcap_lookupnet(device->name, &netAddress , &netMask, pcapErrorBuffer); */ - ret = pcap_lookupnet(strLocalInterface.toAscii(), &netAddress , &netMask, + ret = pcap_lookupnet(strLocalInterface.toLatin1(), &netAddress , &netMask, pcapErrorBuffer); //resolve byte order issue netAddress = (bpf_u_int32)ntohl(netAddress); @@ -595,7 +586,7 @@ bool DataProcessor::DataExtractor::lookupNetwork() //file is currently open, reopen it to scan addresses, using seperate //file read pcap_t *tempCaptureInstance; - tempCaptureInstance = pcap_open_offline(strReplayFileReference.toAscii().data(), + tempCaptureInstance = pcap_open_offline(strReplayFileReference.toLatin1().data(), pcapErrorBuffer); if (tempCaptureInstance == NULL) @@ -770,8 +761,8 @@ void DataProcessor::DataExtractor::setHomeNetwork(unsigned int netAdr, #ifdef DEBUG_DATA_EXTRACTOR cerr << "DEBUG: network address set to: " - << PacketHeaders::ipAdrToDecDotStr(netAdr) << ", mask set to: " - << PacketHeaders::ipAdrToDecDotStr(mask) << endl; + << PacketHeaders::ipAdrToDecDotStr(netAdr).toLatin1().data() << ", mask set to: " + << PacketHeaders::ipAdrToDecDotStr(mask).toLatin1().data() << endl; #endif dataProcessor->reportHomeNetwork(); @@ -857,7 +848,7 @@ bool DataProcessor::DataExtractor::openCaptureFile(const QString file) cerr << "DEBUG: opening capture file to scan for start and end timestamps\n"; #endif - fileCaptureInstance = pcap_open_offline(strReplayFileReference.toAscii().data(), pcapErrorBuffer); + fileCaptureInstance = pcap_open_offline(strReplayFileReference.toLatin1().data(), pcapErrorBuffer); if (fileCaptureInstance == NULL) { //capture file not successfully set @@ -1002,25 +993,25 @@ bool DataProcessor::DataExtractor::openCaptureFile(const QString file) cerr << " Timestamp of first packet = " << dataProcessor->captureStartTime.tv_sec << " sec, " << dataProcessor->captureStartTime.tv_usec << " usec - " - << capSrtTm.date().toString() << ", " - << capSrtTm.time().toString() << ":" + << capSrtTm.date().toString().toLatin1().data() << ", " + << capSrtTm.time().toString().toLatin1().data() << ":" << capSrtTm.time().msec() << endl; cerr << " Timestamp of last packet = " << dataProcessor->captureEndTime.tv_sec << " sec, " << dataProcessor->captureEndTime.tv_usec << " usec - " - << capEndTm.date().toString() << ", " - << capEndTm.time().toString() << ":" + << capEndTm.date().toString().toLatin1().data() << ", " + << capEndTm.time().toString().toLatin1().data() << ":" << capEndTm.time().msec() << endl; cerr << " Replay position = " << dataProcessor->replayPosition.tv_sec << " sec, " << dataProcessor->replayPosition.tv_usec << " usec - " - << dataProcessor->qdt_replayPosition.date().toString() << ", " - << dataProcessor->qdt_replayPosition.time().toString() << ":" + << dataProcessor->qdt_replayPosition.date().toString().toLatin1().data() << ", " + << dataProcessor->qdt_replayPosition.time().toString().toLatin1().data() << ":" << dataProcessor->qdt_replayPosition.time().msec() << endl; cerr << "DEBUG: reopeing file and initialising for file replay\n"; #endif - fileCaptureInstance = pcap_open_offline(strReplayFileReference.toAscii().data(), pcapErrorBuffer); + fileCaptureInstance = pcap_open_offline(strReplayFileReference.toLatin1().data(), pcapErrorBuffer); //reopen to start from beggining again //check for error if (fileCaptureInstance == NULL) @@ -1087,7 +1078,7 @@ bool DataProcessor::DataExtractor::reopenCaptureFile() if (fileCaptureInstance == NULL) { //reopen the file, reapply the filter and seek to the current replay //position, refilling the buffer - fileCaptureInstance = pcap_open_offline(strReplayFileReference.toAscii().data(), + fileCaptureInstance = pcap_open_offline(strReplayFileReference.toLatin1().data(), pcapErrorBuffer); //check for error if (fileCaptureInstance == NULL) @@ -1185,7 +1176,7 @@ bool DataProcessor::DataExtractor::openInterface(const QString netInterface) //dataProcessor->glVisWidget->update(); } - liveCaptureInstance = pcap_open_live(strLocalInterface.toAscii().data(), packetCaptureLength, + liveCaptureInstance = pcap_open_live(strLocalInterface.toLatin1().data(), packetCaptureLength, promiscuousMode, readTimeout, pcapErrorBuffer); if (liveCaptureInstance == NULL) { reportError("error opening network device " + strLocalInterface + @@ -1215,7 +1206,7 @@ bool DataProcessor::DataExtractor::openInterface(const QString netInterface) } #ifdef DEBUG_DATA_EXTRACTOR - cerr << "DEBUG: network device " + strLocalInterface + " oppened for capture" << endl; + cerr << "DEBUG: network device " << strLocalInterface.toLatin1().data() << " oppened for capture" << endl; #endif dataProcessor->setMode(MONITOR_LOCAL); @@ -1232,7 +1223,6 @@ bool DataProcessor::DataExtractor::openInterface(const QString netInterface) dataProcessor->play(); return true; - } @@ -1250,7 +1240,7 @@ bool DataProcessor::DataExtractor::openDefaultInterface() else { #ifdef DEBUG_DATA_EXTRACTOR - cerr << "DEBUG: Default device set: " << strLocalInterface << endl; + cerr << "DEBUG: Default device set: " << strLocalInterface.toLatin1().data() << endl; #endif return openInterface(strLocalInterface); } @@ -1278,7 +1268,7 @@ bool DataProcessor::DataExtractor::openDumpFile(const QString file) if (dumpFileDescriptor != NULL) { #ifdef DEBUG_RECORD_PACKETS - cerr << " previous dump file = \"" << strRecordFileReference + cerr << " previous dump file = \"" << strRecordFileReference.toLatin1().data() << "\" found open, now closing...\n"; #endif @@ -1301,22 +1291,22 @@ bool DataProcessor::DataExtractor::openDumpFile(const QString file) strRecordFileReference = file; #ifdef DEBUG_RECORD_PACKETS - cerr << " new dump file = \"" << strRecordFileReference << "\"\n"; + cerr << " new dump file = \"" << strRecordFileReference.toLatin1().data() << "\"\n"; #endif //open dump file, according to replay mode if (dataProcessor->replayMode == REPLAY_FILE) dumpFileDescriptor = pcap_dump_open(fileCaptureInstance, - strRecordFileReference.toAscii().data()); + strRecordFileReference.toLatin1().data()); else if (dataProcessor->replayMode == MONITOR_LOCAL) dumpFileDescriptor = pcap_dump_open(liveCaptureInstance, - strRecordFileReference.toAscii().data()); + strRecordFileReference.toLatin1().data()); //check that dump file opened correctly - if (dumpFileDescriptor == NULL) - { reportError("failed to open dump file: \"" - + strRecordFileReference + "\"", - "libpcap::pcap_dump_open()"); + if (dumpFileDescriptor == NULL) { + reportError("failed to open dump file: \"" + + strRecordFileReference + "\"", + "libpcap::pcap_dump_open()"); return false; } @@ -1333,21 +1323,20 @@ bool DataProcessor::DataExtractor::openDumpFile(const QString file) } -void DataProcessor::DataExtractor::recordToDumpFile(bool record) -{ +void DataProcessor::DataExtractor::recordToDumpFile(bool record) { #ifdef DEBUG_RECORD_PACKETS cerr << "DEBUG: record state changed:\n"; #endif //assert that we are not trying to set the same state over - if (dataProcessor->recordToFile == record) - { QString strRecordState; - if (dataProcessor->recordToFile) - { strRecordState = "on"; + if (dataProcessor->recordToFile == record) { + QString strRecordState; + if (dataProcessor->recordToFile) { + strRecordState = "on"; } - else - { strRecordState = "off"; + else { + strRecordState = "off"; } reportError("record state already " + strRecordState, "DataExtractor::recordToFile()"); @@ -1355,27 +1344,29 @@ void DataProcessor::DataExtractor::recordToDumpFile(bool record) } //check to see if we're beginnig to record - if (record) //start recording - { //check if dump file already open, and if not, generate auto name per + if (record) { + //start recording + //check if dump file already open, and if not, generate auto name per //record session - a record session is a press and consequent depress //of the button - if (dumpFileDescriptor == NULL) - { //assume session mode + if (dumpFileDescriptor == NULL) { + //assume session mode recMode = SESSION; } - if (recMode == SESSION) - { //create filename bassed on capture mode and file start time + + if (recMode == SESSION) { + //create filename bassed on capture mode and file start time QString dumpFileName; - if (dataProcessor->getMode() == REPLAY_FILE) - { QString replayFileName = dataProcessor->getReplayFileName(); + if (dataProcessor->getMode() == REPLAY_FILE) { + QString replayFileName = dataProcessor->getReplayFileName(); dumpFileName = QString(DEFAULT_PCAPS_DIR) + QString("/") + QString(DEFAULT_REPLAY_SUBDIR) + QString("/") + replayFileName; QDir dir; //need to create sub dir - if (!dir.exists(dumpFileName)) - { if(!dir.mkdir(dumpFileName)) - { reportError("could not create subdirectory for record session file", + if (!dir.exists(dumpFileName)) { + if(!dir.mkdir(dumpFileName)) { + reportError("could not create subdirectory for record session file", "DataExtractor::recordToFile()"); return; } @@ -1384,8 +1375,8 @@ void DataProcessor::DataExtractor::recordToDumpFile(bool record) += QString("/") + dataProcessor->qdt_twEnd.toString("yyyyMMdd-hhmmss"); } - else if (dataProcessor->getMode() == MONITOR_LOCAL) - { dumpFileName = QString(DEFAULT_PCAPS_DIR) + QString("/") + else if (dataProcessor->getMode() == MONITOR_LOCAL) { + dumpFileName = QString(DEFAULT_PCAPS_DIR) + QString("/") + QString(DEFAULT_LIVE_SUBDIR) + QString("/") + dataProcessor->qdt_replayPosition.toString("yyyyMMdd-hhmmss"); //this must be changed to the time window end if the buffer @@ -1393,8 +1384,8 @@ void DataProcessor::DataExtractor::recordToDumpFile(bool record) } //only add extention once closing file //now open session file - if(!openDumpFile(dumpFileName)) - { emit dataProcessor->setRecordButton(false); + if(!openDumpFile(dumpFileName)) { + emit dataProcessor->setRecordButton(false); return; //openDumpFile() will report the error } @@ -1404,25 +1395,27 @@ void DataProcessor::DataExtractor::recordToDumpFile(bool record) dataProcessor->recordToFile = true; #ifdef DEBUG_RECORD_PACKETS - cerr << " started recording pacets to dump file \""; - cerr << strRecordFileReference << "\"\n"; + cerr << " started recording packets to dump file \""; + cerr << strRecordFileReference.toLatin1().data() << "\"\n"; #endif //now process packets - if (dataProcessor->getMode() == REPLAY_FILE) - { //reprocess file to record all packets already in time window + if (dataProcessor->getMode() == REPLAY_FILE) { + + //reprocess file to record all packets already in time window reopenCaptureFile(); //we want to copy from the original file //the packet proccessing function will dump packets during reread //coping data in current buffer } - else if (dataProcessor->getMode() == MONITOR_LOCAL) - { //dump current buffer contents + else if (dataProcessor->getMode() == MONITOR_LOCAL) { + + //dump current buffer contents deque::iterator itr; for (itr = dataProcessor->packetEventBuffer.begin(); itr != dataProcessor->packetEventBuffer.end(); - itr++) - { if (itr->graphicElement != NULL) - { //copy event data in pcap pkyhdr struct + itr++) { + if (itr->graphicElement != NULL) { + //copy event data in pcap pkyhdr struct struct pcap_pkthdr pktHdr; pktHdr.ts.tv_sec = itr->timeStamp.tv_sec; pktHdr.ts.tv_usec = itr->timeStamp.tv_usec; @@ -1438,18 +1431,18 @@ void DataProcessor::DataExtractor::recordToDumpFile(bool record) } } } - else - { //stop recording + else { + //stop recording dataProcessor->recordToFile = false; #ifdef DEBUG_RECORD_PACKETS - cerr << " stoped recording pacets to dump file \""; - cerr << strRecordFileReference << "\"\n"; + cerr << " stopped recording packets to dump file \""; + cerr << strRecordFileReference.toLatin1().data() << "\"\n"; #endif //if in SESSION mode, close and rename file - if (recMode == SESSION) - { closeDumpFile(); + if (recMode == SESSION) { + closeDumpFile(); //setup file references to filename and path QDir fileRef = QDir(strRecordFileReference); QString fileName = fileRef.dirName(); //get file name @@ -1457,39 +1450,37 @@ void DataProcessor::DataExtractor::recordToDumpFile(bool record) filePath = filePath.remove(fileName); //get dir on its own filePath = strRecordFileReference.remove(fileName); //navigate into dir and rename file - if (!fileRef.exists()) - { QString newFileName = fileName + QString(" - ") + if (!fileRef.exists()) { + QString newFileName = fileName + QString(" - ") + dataProcessor->qdt_replayPosition.toString("yyyyMMdd-hhmmss") + QString(".cap"); QDir navDir = QDir(dataProcessor->strAppDir); - if (navDir.cd(filePath)) - { //rename file - if (!navDir.rename(fileName, newFileName)) - { reportError("could not rename record session file", + if (navDir.cd(filePath)) { + //rename file + if (!navDir.rename(fileName, newFileName)) { + reportError("could not rename record session file", "DataExtractor::recordToFile()"); } - else - { + else { #ifdef DEBUG_RECORD_PACKETS cerr << " recording session dump file closed and renamed to\""; - cerr << newFileName << "\"\n"; + cerr << newFileName.toLatin1().data() << "\"\n"; #endif } } - else - { reportError("could not change directory in order to rename record session file", + else { + reportError("could not change directory in order to rename record session file", "DataExtractor::recordToFile()"); } } - else - { reportError("could not rename record session file", + else { + reportError("could not rename record session file", "DataExtractor::recordToFile()"); } } //if in CONTINUOUS mode, leave file open untill recording is reiniated //or file manually closed } - } @@ -1525,7 +1516,7 @@ void DataProcessor::DataExtractor::closeDumpFile() dumpFileDescriptor = NULL; #ifdef DEBUG_RECORD_PACKETS - cerr << " dump file \"" << strRecordFileReference << "\" closed\n"; + cerr << " dump file \"" << strRecordFileReference.toLatin1().data() << "\" closed\n"; #endif } @@ -1597,8 +1588,8 @@ bool DataProcessor::DataExtractor::applyFilter() char filterExpr[MAX_EXPR_LENGTH]; //check that the string will be within bounds of the string buffer - if ((implicit_bpf_FilterExpr.length() + bpfFilterExpr.length()) < MAX_EXPR_LENGTH) - { strcpy(filterExpr, (implicit_bpf_FilterExpr + bpfFilterExpr).toAscii().data()); + if ((implicit_bpf_FilterExpr.length() + bpfFilterExpr.length()) < MAX_EXPR_LENGTH) { + strcpy(filterExpr, (implicit_bpf_FilterExpr + bpfFilterExpr).toLatin1().data()); //QString will cast to const char* } else @@ -1718,7 +1709,7 @@ bool DataProcessor::DataExtractor::applyFilter() if (pcapRet != -1) cerr << "DEBUG: filter compiled and set to: '" << filterExpr << "' (including implicit filter), with net mask of " - << QString::number(netMask) << endl; + << QString::number(netMask).toLatin1().data() << endl; #endif return true; @@ -1871,11 +1862,11 @@ DataProcessor::DataProcessor() << " secs, " << timeWindow.tv_usec << " microsecs\n"; cerr << "DEBUG: replay rate init to default : " << timeFactor << "x\n"; cerr << "DEBUG: replay position init: " - << qdt_replayPosition.date().toString() << ", " - << qdt_replayPosition.time().toString() << ":" + << qdt_replayPosition.date().toString().toLatin1().data() << ", " + << qdt_replayPosition.time().toString().toLatin1().data() << ":" << qdt_replayPosition.time().msec() << endl; - cerr << "DEBUG: time window end init: " << qdt_twEnd.date().toString() - << ", " << qdt_twEnd.time().toString() << ":" + cerr << "DEBUG: time window end init: " << qdt_twEnd.date().toString().toLatin1().data() + << ", " << qdt_twEnd.time().toString().toLatin1().data() << ":" << qdt_twEnd.time().msec() << endl; #endif @@ -2245,7 +2236,7 @@ void DataProcessor::selectReplayFile(const QString file) if(dataExtractor.openCaptureFile(file)) { #ifdef DEBUG_DATA_EXTRACTOR - cerr << "opened \"" + file + "\" for replay" + cerr << "opened \"" << file.toLatin1().data() << "\" for replay" << endl; #endif @@ -2374,7 +2365,7 @@ void DataProcessor::setReplayPosition(const struct timeval newReplayPos) } #ifdef DEBUG_DATA_PROCESSOR - cerr << "DEBUG: replay position set to: " << qdt_replayPosition.toString() + cerr << "DEBUG: replay position set to: " << qdt_replayPosition.toString().toLatin1().data() << endl; #endif @@ -2473,10 +2464,8 @@ void DataProcessor::togglePlayPause() } -void DataProcessor::record(bool rec) -{ +void DataProcessor::record(bool rec) { dataExtractor.recordToDumpFile(rec); - } @@ -2591,7 +2580,7 @@ void DataProcessor::setTimeWindow(double seconds) cerr << "DEBUG: time window set to: " << timeWindow.tv_sec << " seconds, and " << timeWindow.tv_usec << " microsecs\n"; cerr << "DEBUG: time window end adjusted to: " - << twEnd.date().toString() << ", " << twEnd.time().toString() + << twEnd.date().toString().toLatin1().data() << ", " << twEnd.time().toString().toLatin1().data() << ":" << twEnd.time().msec() << endl; #endif @@ -2718,7 +2707,7 @@ void DataProcessor::getBufferStatus() #ifdef DEBUG_DATA_PROCESSOR cerr << "DEBUG: packet event buffer length (time) = " - << TimeUtil::realativeTimevalToQString(timeLength) << ", events = "; + << TimeUtil::realativeTimevalToQString(timeLength).toLatin1().data() << ", events = "; #endif diff --git a/src/dataproc.h b/src/dataproc.h index 47a83b4..10cbb60 100644 --- a/src/dataproc.h +++ b/src/dataproc.h @@ -192,17 +192,12 @@ class GLVisWidget; //CLASS DEFINITIONS ------------------------------------------------------------ -class DataProcessor : public QObject -{ +class DataProcessor : public QObject { Q_OBJECT //macro for use of signals and slots - private: - //DataExtractor subclass ------------------------------------------------- - - class DataExtractor - { + class DataExtractor { /* Internal class to impliment non blocking input into buffer by * extracting data using the libpcap library * - may in future be revised to operate as a seperate thread diff --git a/src/glviswidget.cpp b/src/glviswidget.cpp index 8b04a6c..95a7942 100644 --- a/src/glviswidget.cpp +++ b/src/glviswidget.cpp @@ -356,7 +356,7 @@ void GLVisWidget::paintGL() captureFrameToFile = false; //create filename QString fname_part = "/" + currentTime->toString("/yyyyMMdd-hhmmsszzz") + "_snap%02d.ppm"; - sprintf(&frameFileName[frameDirCharIndex], fname_part.toAscii(), snapshotCount); + sprintf(&frameFileName[frameDirCharIndex], fname_part.toLatin1(), snapshotCount); //check if filename exists - in case of multiple snapshots at same //position in file if (QFile::exists(frameFileName)) @@ -376,7 +376,7 @@ void GLVisWidget::paintGL() { //capturing multiple frames to files recFrameCount++; QString fname_part = "/frame%09d - " + currentTime->toString("yyyyMMdd-hhmmsszzz") + ".ppm"; - sprintf(&frameFileName[frameDirCharIndex], fname_part.toAscii(), recFrameCount); + sprintf(&frameFileName[frameDirCharIndex], fname_part.toLatin1(), recFrameCount); //here we cater for framecount of up to 9 digits } @@ -1382,7 +1382,7 @@ void GLVisWidget::captureFrames(bool on) { { frameCaptureDir = QString(DEFAULT_FRAMES_DIR); } //init frameFileName reference - strcpy(frameFileName, frameCaptureDir.toAscii()); + strcpy(frameFileName, frameCaptureDir.toLatin1()); frameDirCharIndex = frameCaptureDir.length(); //set capture frames flag captureFrameToFile = true; @@ -1451,7 +1451,7 @@ void GLVisWidget::captureCurrentFrame() { { frameCaptureDir = QString(DEFAULT_SNAPSHOTS_DIR); } //init frameFileName reference - strcpy(frameFileName, frameCaptureDir.toAscii()); + strcpy(frameFileName, frameCaptureDir.toLatin1()); frameDirCharIndex = frameCaptureDir.length(); //set flags captureSingleFrameToFile = true; diff --git a/src/icons.qrc b/src/icons.qrc index ab7ed19..30af2c6 100644 --- a/src/icons.qrc +++ b/src/icons.qrc @@ -1,7 +1,7 @@ - + images/editcopy.png - images/editcut.png + images/editcut.png images/editpaste.png images/emblem-pictures.png images/filenew.png @@ -18,5 +18,5 @@ images/stock_media-rew.png images/stock_media-rec.png images/undo.png - + diff --git a/src/images/inetvis.png b/src/images/inetvis.png new file mode 100644 index 0000000..c241e2b Binary files /dev/null and b/src/images/inetvis.png differ diff --git a/src/inetvis.pro b/src/inetvis.pro index 901356b..626a1ea 100644 --- a/src/inetvis.pro +++ b/src/inetvis.pro @@ -46,9 +46,9 @@ RESOURCES += icons.qrc ## CUSTOM SETTINGS ---------------------------------------- ## Build Mode -#CONFIG += debug warn_on +CONFIG += debug warn_on #CONFIG += debug -CONFIG += release +#CONFIG += release ### uncomment one or the other above # Turn off C++ warnings while building @@ -56,7 +56,6 @@ CONFIG += warn_off ## Linking CONFIG += create_prl link_prl static -#QMAKE_LFLAGS_RELEASE = -m32 ## Optimization flags QMAKE_CFLAGS_RELEASE = -O3 -march=native -mfpmath=sse -mmmx -msse -msse2 -mno-sse3 -momit-leaf-frame-pointer -maccumulate-outgoing-args diff --git a/src/main.cpp b/src/main.cpp index 44a7cf9..d74d95d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -69,14 +69,11 @@ int main(int argc, char **argv) { LogUIQuit luiq; //small helper object to ensure UI logging closes gracefully //declare GUI forms/windows - //QMainWindow cp; - //Ui::ControlPanel uicp; - //uicp.setupUi(&cp); ControlPanelWidget cp; VisDisplayWidget vd; //visaulization window GLVisWidget* vdw = vd.displayWidget; - vd.setFocusProxy(vdw); + //vd.setFocusProxy(vdw); Removed, already called in the init class of VisDisplayWidget PlotterSettingsDialogWidget ps; //to set plotting features ReferenceFrameSettingsDialogWidget rfs; //to set reference frame features @@ -208,8 +205,9 @@ int main(int argc, char **argv) { dp.init(); - vd.show(); //show display first so that control panel begins on top - cp.show(); + // Only show the control panel once the main display widget is on screen. + QObject::connect(&vd, SIGNAL(window_loaded()), &cp, SLOT(show()), Qt::ConnectionType(Qt::QueuedConnection | Qt::UniqueConnection)); + vd.show(); return app.exec(); } diff --git a/src/visdisplay.ui b/src/visdisplay.ui index 3646156..eb0e9c0 100644 --- a/src/visdisplay.ui +++ b/src/visdisplay.ui @@ -1,72 +1,64 @@ - - - - - VisDisplay - - - - 0 - 0 - 704 - 576 - - - + + VisDisplay + + + + 0 + 0 + 704 + 576 + + + + + 0 + 0 + + + + + 0 + 0 + + + + InetVis Display + + + + 0 + + + 0 + + + 0 + + + 0 + + + + - 0 - 0 + 704 + 576 - - - - 0 - 0 - - - - InetVis Display - - - - 0 - - - - - - 320 - 240 - - - - - - - - - - GLVisWidget - QWidget - - -1 - -1 - - 0 - - 5 - 5 - - image0 - - - - - 789c534e494dcbcc4b554829cdcdad8c2fcf4c29c95030e0524611cd48cd4ccf28010a1797249664262b2467241641a592324b8aa363156c15aab914146aadb90067111b1f - - - - ../glviswidget.h - + + + + + + + + + GLVisWidget + + + + ../glviswidget.h + + + diff --git a/src/visdisplaywidget.cpp b/src/visdisplaywidget.cpp index 3142ea0..a9fa518 100644 --- a/src/visdisplaywidget.cpp +++ b/src/visdisplaywidget.cpp @@ -1,16 +1,10 @@ #include "visdisplaywidget.h" +#include VisDisplayWidget::VisDisplayWidget(QWidget *parent) : QWidget(parent) { setupUi(this); - // TODO: Check if this is needed - init(); -} - -void VisDisplayWidget::init() { - //init widget flags setFocusProxy(displayWidget); - //displayWidget can get keyboard events } void VisDisplayWidget::updateGLVisWidget() { @@ -20,3 +14,11 @@ void VisDisplayWidget::updateGLVisWidget() { GLVisWidget* VisDisplayWidget::getPtrToVisPane() { return displayWidget; } + +void VisDisplayWidget::showEvent(QShowEvent *ev) { + QWidget::showEvent(ev); + // This is a hack more than anything. Delay so that control panel + // won't overlap the vis display widget + QThread::sleep(1); + emit window_loaded(); +} diff --git a/src/visdisplaywidget.h b/src/visdisplaywidget.h index 82ba86a..5a6cf2b 100644 --- a/src/visdisplaywidget.h +++ b/src/visdisplaywidget.h @@ -10,6 +10,12 @@ class VisDisplayWidget : public QWidget, public Ui::VisDisplay { public: VisDisplayWidget(QWidget *parent = 0); +protected: + void showEvent(QShowEvent *ev); + +signals: + void window_loaded(); + public slots: void updateGLVisWidget(); diff --git a/utils/inetvis.desktop b/utils/inetvis.desktop new file mode 100644 index 0000000..0957c23 --- /dev/null +++ b/utils/inetvis.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Encoding=UTF-8 +Type=Application +Name=inetvis +Comment=Internet Visualiser +Exec=inetvis +Icon=/usr/share/icons/hicolor/48x48/apps/inetvis.png +Terminal=false +Categories=GNOME;Application; +StartupNotify=true diff --git a/utils/install_inetvis.sh b/utils/install_inetvis.sh new file mode 100755 index 0000000..9ae0962 --- /dev/null +++ b/utils/install_inetvis.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +BIN_NAME=inetvis +VER="" + +ICON_PATH=/usr/share/icons/hicolor/48x48/apps/ +APPS_PATH=/usr/share/applications/ +USR_BIN=/usr/local/bin + +echo "Creating directories..." + +OPT_DIR_VER=/opt/${BIN_NAME}-${VER} +if [[ ! -d "${OPT_DIR_VER}" ]]; then + sudo mkdir ${OPT_DIR_VER} +else + echo "Not creating ${OPT_DIR_VER} as it already exists" +fi + +OPT_DIR_SYM=/opt/${BIN_NAME} +if [[ ! -L "${OPT_DIR_SYM}" ]]; then + sudo ln -s /opt/${BIN_NAME}-${VER} /opt/${BIN_NAME} +else + echo "Symlink for ${OPT_DIR_SYM} already exists. Please link manually to ${OPT_DIR_VER} if desired." +fi + +echo "Copying files..." +sudo cp -r bin/ /opt/${BIN_NAME}-${VER} +sudo cp resources/${BIN_NAME}.png ${ICON_PATH} +sudo cp -r doc/ /opt/${BIN_NAME}-${VER} +sudo cp -r lic/ /opt/${BIN_NAME}-${VER} + +echo "Copying menu entry..." +sudo cp resources/${BIN_NAME}.desktop ${APPS_PATH} + +echo "Creating symlink for inetvis..." + +if [[ ! -L "${USR_BIN}/${BIN_NAME}" ]]; then + sudo ln -s /opt/${BIN_NAME}/bin/${BIN_NAME} ${USR_BIN} +else + echo "Symlink at ${USR_BIN}/${BIN_NAME} already exists. Please update if necessary." +fi + +echo "Setting capabilities on binary to allow monitoring interfaces" +sudo setcap cap_net_raw,cap_net_admin=eip /opt/${BIN_NAME}/bin/${BIN_NAME} + +echo "Done" diff --git a/utils/prepare_release.sh b/utils/prepare_release.sh new file mode 100755 index 0000000..7a528cd --- /dev/null +++ b/utils/prepare_release.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +if [ "$#" -ne 1 ]; then + echo "Usage: ${0} " + exit 1 +fi + +VER=$1 +DOC_DIR="../doc" +SRC_DIR="../src" +LIC_DIR="../lic" +BIN_NAME="inetvis" +IMAGE_DIR="images" + +TMP_DIR="inetvis-${VER}" +BIN_DIR="bin" +RES_DIR="resources" + +echo "Preparing archive for ${TMP_DIR}..." + +echo "Creating working directory structure..." +mkdir ${TMP_DIR} +mkdir ${TMP_DIR}/${BIN_DIR} +mkdir ${TMP_DIR}/${RES_DIR} + +echo "Copying binary..." +cp ${SRC_DIR}/${BIN_NAME} ${TMP_DIR}/${BIN_DIR} + +echo "Copying docs..." +cp -r ${DOC_DIR} ${TMP_DIR} + +echo "Copying licenses..." +cp -r ${LIC_DIR} ${TMP_DIR} + +echo "Copying resources..." +cp ${BIN_NAME}.desktop ${TMP_DIR}/${RES_DIR} +cp ${SRC_DIR}/${IMAGE_DIR}/${BIN_NAME}.png ${TMP_DIR}/${RES_DIR} + +echo "Copying scripts and readme..." +sed "s//${VER}/g" install_${BIN_NAME}.sh > ${TMP_DIR}/install_${BIN_NAME}.sh +chmod a+x ${TMP_DIR}/install_${BIN_NAME}.sh +sed "s//${VER}/g" uninstall_${BIN_NAME}.sh > ${TMP_DIR}/uninstall_${BIN_NAME}.sh +chmod a+x ${TMP_DIR}/uninstall_${BIN_NAME}.sh +cp ../README.md ${TMP_DIR} + +echo "Creating archive ${TMP_DIR}.tgz..." +tar -zcf ${TMP_DIR}.tgz ${TMP_DIR} +echo "Removing directory ${TMP_DIR}" +rm -rf ${TMP_DIR} +echo "Done" diff --git a/utils/uninstall_inetvis.sh b/utils/uninstall_inetvis.sh new file mode 100755 index 0000000..4b643cd --- /dev/null +++ b/utils/uninstall_inetvis.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +echo "Uninstalling inetvis..." + +BIN_NAME=inetvis +VER="" +ICON_PATH=/usr/share/icons/hicolor/48x48/apps +APPS_PATH=/usr/share/applications +USR_BIN=/usr/local/bin + + +if [ -f "${APPS_PATH}/${BIN_NAME}" ]; then + echo "Removing desktop file..." + sudo rm ${APPS_PATH}/${BIN_NAME}.desktop +else + echo "Not removing desktop file, it doesn't exist" +fi + +if [ -f "${ICON_PATH}/${BIN_NAME}.png" ]; then + echo "Removing icon..." + sudo rm ${ICON_PATH}/${BIN_NAME}.png +else + echo "Not removing icon, it doesn't exist" +fi + +if [ -L "${USR_BIN}/${BIN_NAME}" ]; then + echo "Removing ${USR_BIN} symlink..." + sudo rm ${USR_BIN}/${BIN_NAME} +else + echo "Not removing symlink ${USR_BIN}/${BIN_NAME}, it doesn't exist" +fi + +if [ -L "/opt/${BIN_NAME}" ]; then + echo "Removing /opt symlink..." + sudo rm /opt/${BIN_NAME} +else + echo "Not removing /opt/${BIN_NAME}, doesn't exist" +fi + +if [ -d "/opt/${BIN_NAME}-${VER}" ]; then + echo "Removing /opt/${BIN_NAME}-${VER} directory..." + sudo rm -rf /opt/${BIN_NAME}-${VER} +else + echo "Not removing /opt/${BIN_NAME}-${VER}, doesn't exist" +fi + +echo "Done!"