From 10ee1bef8cf13c28ecd98aa361fd6eb181a267a5 Mon Sep 17 00:00:00 2001 From: Diego Torres Date: Mon, 16 Feb 2026 23:01:48 +0000 Subject: [PATCH 1/2] extracting source IP from GPS format packet header --- src/asterix/DataBlock.cpp | 7 ++++--- src/asterix/DataBlock.h | 3 ++- src/asterix/DataRecord.cpp | 22 ++++++++++++++-------- src/asterix/DataRecord.h | 3 ++- src/asterix/InputParser.cpp | 8 ++++---- src/asterix/InputParser.h | 4 ++-- src/asterix/asterixformatdescriptor.hxx | 17 ++++++++++++++++- src/asterix/asterixgpssubformat.cxx | 6 +++++- 8 files changed, 49 insertions(+), 21 deletions(-) diff --git a/src/asterix/DataBlock.cpp b/src/asterix/DataBlock.cpp index e815439f..4244a041 100644 --- a/src/asterix/DataBlock.cpp +++ b/src/asterix/DataBlock.cpp @@ -28,8 +28,8 @@ extern bool gFiltering; -DataBlock::DataBlock(Category *cat, unsigned long len, const unsigned char *data, double nTimestamp) - : m_pCategory(cat), m_nLength(len), m_nTimestamp(nTimestamp), m_bFormatOK(false) { +DataBlock::DataBlock(Category *cat, unsigned long len, const unsigned char *data, double nTimestamp, unsigned int nIP) + : m_pCategory(cat), m_nLength(len), m_nTimestamp(nTimestamp), m_nIP(nIP), m_bFormatOK(false) { const unsigned char *m_pItemDataStart = data; long nUnparsed = len; int counter = 1; @@ -40,7 +40,7 @@ DataBlock::DataBlock(Category *cat, unsigned long len, const unsigned char *data } while (nUnparsed > 0) { - DataRecord *dr = new DataRecord(cat, counter++, nUnparsed, m_pItemDataStart, nTimestamp); + DataRecord *dr = new DataRecord(cat, counter++, nUnparsed, m_pItemDataStart, nTimestamp, nIP); if (!dr) { Tracer::Error("Error DataBlock format."); @@ -87,6 +87,7 @@ bool DataBlock::getText(std::string &strResult, const unsigned int formatType) { strResult += format("\nLen: %ld", m_nLength); strResult += format("\nTimestamp: %lf", m_nTimestamp); strResult += format("\nHexData: %02X%02X%02X", m_pCategory->m_id, ((m_nLength + 3) >> 8) & 0xff, (m_nLength + 3) & 0xff); + strResult += format("\nSrc IP: %lu", m_nIP); break; case CAsterixFormat::EOut: strHeader = format("Asterix.CAT%03d", m_pCategory->m_id); diff --git a/src/asterix/DataBlock.h b/src/asterix/DataBlock.h index 24585fe4..4f2a2e2a 100644 --- a/src/asterix/DataBlock.h +++ b/src/asterix/DataBlock.h @@ -28,7 +28,7 @@ class DataBlock { public: - DataBlock(Category *cat, unsigned long len, const unsigned char *data, double nTimestamp = 0.0); + DataBlock(Category *cat, unsigned long len, const unsigned char *data, double nTimestamp = 0.0, unsigned int nIP = 0); virtual ~DataBlock(); @@ -36,6 +36,7 @@ class DataBlock { Category *m_pCategory; unsigned long m_nLength; double m_nTimestamp; // Date and time when this packet was captured. This value is in seconds since January 1, 1970 00:00:00 GMT + unsigned int m_nIP; // source ip when reading GPS files bool m_bFormatOK; std::list m_lDataRecords; diff --git a/src/asterix/DataRecord.cpp b/src/asterix/DataRecord.cpp index 958fd8e9..78b08f52 100644 --- a/src/asterix/DataRecord.cpp +++ b/src/asterix/DataRecord.cpp @@ -27,9 +27,9 @@ #include "Utils.h" #include "asterixformat.hxx" -DataRecord::DataRecord(Category *cat, int nID, unsigned long len, const unsigned char *data, double nTimestamp) +DataRecord::DataRecord(Category *cat, int nID, unsigned long len, const unsigned char *data, double nTimestamp, unsigned int nIP) : m_pCategory(cat), m_nID(nID), m_nLength(len), m_nFSPECLength(0), m_pFSPECData(NULL), m_nTimestamp(nTimestamp), - m_nCrc(0), m_pHexData(NULL), m_bFormatOK(false) { + m_nIP(nIP), m_nCrc(0), m_pHexData(NULL), m_bFormatOK(false) { const unsigned char *m_pItemDataStart = data; long nUnparsed = len; @@ -164,6 +164,11 @@ bool DataRecord::getText(std::string &strResult, std::string &strHeader, const u Tracer::Error("Record not parsed properly. CAT%03d len=%ld", m_pCategory->m_id, m_nLength); return false; } + unsigned char ip[4]; + ip[0] = (unsigned char)(m_nIP >> 24); + ip[1] = (unsigned char)(m_nIP >> 16); + ip[2] = (unsigned char)(m_nIP >> 8); + ip[3] = (unsigned char)(m_nIP); std::string strNewResult; @@ -172,25 +177,26 @@ bool DataRecord::getText(std::string &strResult, std::string &strHeader, const u strNewResult = format("\n-------------------------\nData Record %d", m_nID); strNewResult += format("\nLen: %ld", m_nLength); strNewResult += format("\nCRC: %08X", m_nCrc); + strNewResult += format("\nSRC IP: %u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); strNewResult += format("\nHexData: %s", m_pHexData); break; case CAsterixFormat::EJSON: strNewResult = format( - "{\"id\":%d,\"cat\":%d,\"length\":%ld,\"crc\":\"%08X\",\"timestamp\":%lf,\"hexdata\":\"%s\",\"CAT%03d\":{", - m_nID, m_pCategory->m_id, m_nLength, m_nCrc, m_nTimestamp, m_pHexData, m_pCategory->m_id); + "{\"id\":%d,\"cat\":%d,\"length\":%ld,\"crc\":\"%08X\",\"timestamp\":%lf,\"srcip\":\"%u.%u.%u.%u\",\"hexdata\":\"%s\",\"CAT%03d\":{", + m_nID, m_pCategory->m_id, m_nLength, m_nCrc, m_nTimestamp, ip[0], ip[1], ip[2], ip[3], m_pHexData, m_pCategory->m_id); break; case CAsterixFormat::EJSONH: case CAsterixFormat::EJSONE: strNewResult = format( - "{\"id\":%d,\n\"cat\":%d,\n\"length\":%ld,\n\"crc\":\"%08X\",\n\"timestamp\":%lf,\n\"hexdata\":\"%s\",\n\"CAT%03d\":{\n", - m_nID, m_pCategory->m_id, m_nLength, m_nCrc, m_nTimestamp, m_pHexData, m_pCategory->m_id); + "{\"id\":%d,\n\"cat\":%d,\n\"length\":%ld,\n\"crc\":\"%08X\",\n\"timestamp\":%lf,\n\"srcip\":\"%u.%u.%u.%u\",\n\"hexdata\":\"%s\",\n\"CAT%03d\":{\n", + m_nID, m_pCategory->m_id, m_nLength, m_nCrc, m_nTimestamp, ip[0], ip[1], ip[2], ip[3], m_pHexData, m_pCategory->m_id); break; case CAsterixFormat::EXML: case CAsterixFormat::EXMLH: { const int nXIDEFv = 1; strNewResult = format( - "", - nXIDEFv, m_pCategory->m_id, m_nLength, m_nCrc, m_nTimestamp, m_pHexData); + "", + nXIDEFv, m_pCategory->m_id, m_nLength, m_nCrc, m_nTimestamp, ip[0], ip[1], ip[2], ip[3], m_pHexData); break; } } diff --git a/src/asterix/DataRecord.h b/src/asterix/DataRecord.h index 58f6e1ce..f31732d6 100644 --- a/src/asterix/DataRecord.h +++ b/src/asterix/DataRecord.h @@ -28,7 +28,7 @@ class DataRecord { public: - DataRecord(Category *cat, int id, unsigned long len, const unsigned char *data, double nTimestamp); + DataRecord(Category *cat, int id, unsigned long len, const unsigned char *data, double nTimestamp, unsigned int nIP); virtual ~DataRecord(); @@ -39,6 +39,7 @@ class DataRecord { unsigned long m_nFSPECLength; unsigned char *m_pFSPECData; double m_nTimestamp; // Date and time when this packet was captured. This value is in seconds since January 1, 1970 00:00:00 GMT + unsigned m_nIP; // source ip when reading from GPS uint32_t m_nCrc; char *m_pHexData; // hexa conversion of data to display bool m_bFormatOK; diff --git a/src/asterix/InputParser.cpp b/src/asterix/InputParser.cpp index 9c40b7e6..9b63f6ae 100644 --- a/src/asterix/InputParser.cpp +++ b/src/asterix/InputParser.cpp @@ -35,7 +35,7 @@ InputParser::InputParser(AsterixDefinition *pDefinition) * Parse data */ AsterixData * -InputParser::parsePacket(const unsigned char *m_pBuffer, unsigned int m_nBufferSize, double nTimestamp) { +InputParser::parsePacket(const unsigned char *m_pBuffer, unsigned int m_nBufferSize, double nTimestamp, unsigned int nIP) { AsterixData *pAsterixData = new AsterixData(); unsigned int m_nPos = 0; unsigned int m_nDataLength = 0; @@ -100,7 +100,7 @@ InputParser::parsePacket(const unsigned char *m_pBuffer, unsigned int m_nBufferS hexString.erase(hexString.size() - 1); LOGDEBUG(1, "[%s]\n", hexString.c_str()); #endif - DataBlock *db = new DataBlock(m_pDefinition->getCategory(nCategory), dataLen, m_pData, nTimestamp); + DataBlock *db = new DataBlock(m_pDefinition->getCategory(nCategory), dataLen, m_pData, nTimestamp, nIP); m_pData += dataLen; m_nPos += dataLen; pAsterixData->m_lDataBlocks.push_back(db); @@ -116,7 +116,7 @@ InputParser::parsePacket(const unsigned char *m_pBuffer, unsigned int m_nBufferS DataBlock * InputParser::parse_next_data_block(const unsigned char *m_pData, unsigned int &m_nPos, unsigned int m_nBufferSize, - double nTimestamp, unsigned int &m_nDataLength) + double nTimestamp, unsigned int nIP, unsigned int &m_nDataLength) /* parse next data block * AUTHOR: Krzysztof Rutkowski, ICM UW, krutk@icm.edu.pl */ @@ -170,7 +170,7 @@ InputParser::parse_next_data_block(const unsigned char *m_pData, unsigned int &m hexString.erase(hexString.size() - 1); LOGDEBUG(1, "[%s]\n", hexString.c_str()); #endif - DataBlock *db = new DataBlock(m_pDefinition->getCategory(nCategory), dataLen, m_pData, nTimestamp); + DataBlock *db = new DataBlock(m_pDefinition->getCategory(nCategory), dataLen, m_pData, nTimestamp, nIP); m_pData += dataLen; m_nPos += dataLen; m_nDataLength -= dataLen; diff --git a/src/asterix/InputParser.h b/src/asterix/InputParser.h index bb619ff0..8d6d1fc6 100644 --- a/src/asterix/InputParser.h +++ b/src/asterix/InputParser.h @@ -38,10 +38,10 @@ class InputParser { ~InputParser() { if (m_pDefinition) delete m_pDefinition; } - AsterixData *parsePacket(const unsigned char *m_pBuffer, unsigned int m_nBufferSize, double nTimestamp = 0.0); + AsterixData *parsePacket(const unsigned char *m_pBuffer, unsigned int m_nBufferSize, double nTimestamp = 0.0, unsigned int nIP = 0); DataBlock *parse_next_data_block(const unsigned char *m_pData, unsigned int &m_nPos, unsigned int m_nBufferSize, - double nTimestamp, unsigned int &m_nDataLength); + double nTimestamp, unsigned int nIP, unsigned int &m_nDataLength); std::string printDefinition(); diff --git a/src/asterix/asterixformatdescriptor.hxx b/src/asterix/asterixformatdescriptor.hxx index 92c67288..0e627cc9 100644 --- a/src/asterix/asterixformatdescriptor.hxx +++ b/src/asterix/asterixformatdescriptor.hxx @@ -51,7 +51,8 @@ public: m_pBuffer(NULL), m_nBufferSize(0), m_nDataSize(0), - m_nTimeStamp(0) { + m_nTimeStamp(0), + m_nIP(0) { } /** @@ -110,6 +111,19 @@ public: m_nTimeStamp = ts; } + void SetIP(unsigned char ip0, unsigned char ip1, unsigned char ip2, unsigned char ip3) { + uint32_t v = + ((uint32_t)ip0 << 24) | + ((uint32_t)ip1 << 16) | + ((uint32_t)ip2 << 8) | + ((uint32_t)ip3 ); + m_nIP = v; + } + + unsigned int GetIP() { + return m_nIP; + } + // used only in PCAP (TODO) typedef enum { NET_ETHERNET = 0, @@ -132,6 +146,7 @@ private: unsigned int m_nBufferSize; // input buffer size unsigned int m_nDataSize; // size of data in buffer double m_nTimeStamp; // Date and time when this packet was captured. This value is in seconds since January 1, 1970 00:00:00 GMT + uint32_t m_nIP; // src ip of packet }; #endif diff --git a/src/asterix/asterixgpssubformat.cxx b/src/asterix/asterixgpssubformat.cxx index f467bf96..a3502855 100644 --- a/src/asterix/asterixgpssubformat.cxx +++ b/src/asterix/asterixgpssubformat.cxx @@ -172,8 +172,10 @@ bool CAsterixGPSSubformat::ReadPacket(CBaseFormatDescriptor &formatDescriptor, C GPSPost[2], GPSPost[3], GPSPost[4], GPSPost[5], GPSPost[6], GPSPost[7], GPSPost[8], GPSPost[9]); LOGDEBUG(1, "GPS Timestamp [%lf]\n", dTimeStamp); + LOGDEBUG(1, "SRC IP [%u.%u.%u.%u]\n", GPSPost[3], GPSPost[2], GPSPost[1], GPSPost[0]); #endif Descriptor.SetTimeStamp(dTimeStamp); + Descriptor.SetIP(GPSPost[3], GPSPost[2], GPSPost[1], GPSPost[0]); } } @@ -252,8 +254,10 @@ bool CAsterixGPSSubformat::ProcessPacket(CBaseFormatDescriptor &formatDescriptor } } else { double dTimeStamp = Descriptor.GetTimeStamp(); + unsigned int nIP = Descriptor.GetIP(); Descriptor.m_pAsterixData = Descriptor.m_InputParser.parsePacket(Descriptor.GetBuffer(), - Descriptor.GetBufferLen(), dTimeStamp); + Descriptor.GetBufferLen(), + dTimeStamp, nIP); } return true; From bf7f4398aec2c8f1d2d898a1545a59d99658ffcc Mon Sep 17 00:00:00 2001 From: Diego Torres Date: Wed, 25 Mar 2026 10:52:30 +0000 Subject: [PATCH 2/2] make available the source ip of network data --- src/asterix/DataRecord.cpp | 2 +- src/asterix/asterixformatdescriptor.hxx | 4 ++++ src/asterix/asterixrawsubformat.cxx | 3 ++- src/engine/basedevice.hxx | 2 ++ src/engine/channelfactory.cxx | 2 +- src/engine/udpdevice.cxx | 2 +- src/engine/udpdevice.hxx | 6 +++++- 7 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/asterix/DataRecord.cpp b/src/asterix/DataRecord.cpp index 78b08f52..e6ff25ec 100644 --- a/src/asterix/DataRecord.cpp +++ b/src/asterix/DataRecord.cpp @@ -177,7 +177,7 @@ bool DataRecord::getText(std::string &strResult, std::string &strHeader, const u strNewResult = format("\n-------------------------\nData Record %d", m_nID); strNewResult += format("\nLen: %ld", m_nLength); strNewResult += format("\nCRC: %08X", m_nCrc); - strNewResult += format("\nSRC IP: %u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); + strNewResult += format("\nSource IP: %u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); strNewResult += format("\nHexData: %s", m_pHexData); break; case CAsterixFormat::EJSON: diff --git a/src/asterix/asterixformatdescriptor.hxx b/src/asterix/asterixformatdescriptor.hxx index 0e627cc9..7c16472c 100644 --- a/src/asterix/asterixformatdescriptor.hxx +++ b/src/asterix/asterixformatdescriptor.hxx @@ -120,6 +120,10 @@ public: m_nIP = v; } + void SetIP(unsigned int ip) { + m_nIP = ip; + } + unsigned int GetIP() { return m_nIP; } diff --git a/src/asterix/asterixrawsubformat.cxx b/src/asterix/asterixrawsubformat.cxx index 41f7c668..9848c2e7 100644 --- a/src/asterix/asterixrawsubformat.cxx +++ b/src/asterix/asterixrawsubformat.cxx @@ -204,7 +204,8 @@ bool CAsterixRawSubformat::ProcessPacket(CBaseFormatDescriptor &formatDescriptor } } else { Descriptor.m_pAsterixData = Descriptor.m_InputParser.parsePacket(Descriptor.GetBuffer(), - Descriptor.GetBufferLen(), dTimestamp); + Descriptor.GetBufferLen(), + dTimestamp, device.getLastSourceIP()); } return true; diff --git a/src/engine/basedevice.hxx b/src/engine/basedevice.hxx index ba6dd7e5..c5017883 100644 --- a/src/engine/basedevice.hxx +++ b/src/engine/basedevice.hxx @@ -102,6 +102,8 @@ public: ResetErrors(true); } + virtual unsigned int getLastSourceIP() { return false; } + protected: // to be used by derived class for error counting virtual void CountReadError() { _nReadErrors++; diff --git a/src/engine/channelfactory.cxx b/src/engine/channelfactory.cxx index 70e836e9..cdba03e4 100644 --- a/src/engine/channelfactory.cxx +++ b/src/engine/channelfactory.cxx @@ -237,7 +237,7 @@ bool CChannelFactory::ReadPacket() { return false; } - // Get thr format descriptor and number + // Get the format descriptor and number CBaseFormatDescriptor *formatDescriptor = _inputChannel->GetFormatDescriptor(); if (formatDescriptor == NULL) { LOGERROR(1, "ReadPacket() - Cannot get the format descriptor.\n"); diff --git a/src/engine/udpdevice.cxx b/src/engine/udpdevice.cxx index f29b61d5..d2d60e7d 100644 --- a/src/engine/udpdevice.cxx +++ b/src/engine/udpdevice.cxx @@ -184,7 +184,7 @@ bool CUdpDevice::Read(void *data, size_t *len) { inet_ntoa(_mcastAddr.sin_addr), lenread); - + setLastSourceIP(ntohl(clientAddr.sin_addr.s_addr)); ResetReadErrors(true); return true; } diff --git a/src/engine/udpdevice.hxx b/src/engine/udpdevice.hxx index d9bc9749..8edcdc03 100644 --- a/src/engine/udpdevice.hxx +++ b/src/engine/udpdevice.hxx @@ -57,7 +57,8 @@ private: bool _server; struct sockaddr_in _mcastAddr; struct in_addr _interfaceAddr; - struct in_addr _sourceAddr; + struct in_addr _sourceAddr; // from the subscribe command line option + uint32_t _nSrcIP; // IP from the recvfrom syscall int _port; std::vector _socketDesc; fd_set _descToRead; @@ -97,6 +98,9 @@ public: MaxPacketSize() { return MAX_UDP_PACKET_SIZE; } // return maximal packet size (only for packet devices) virtual unsigned int BytesLeftToRead() { return 0; } // return number of bytes left to read or 0 if unknown + unsigned int getLastSourceIP() { return this->_nSrcIP; } + void setLastSourceIP(uint32_t nIP) { this->_nSrcIP = nIP; } + private: void Init(const char *mcastAddress, const char *interfaceAddress, const char *srcAddress, const int port, const bool server);