Merge branch 'master' of github.com:collin80/SavvyCAN
This commit is contained in:
@@ -32,6 +32,7 @@ of this program. It can load and save in several formats:
|
|||||||
9. Vehicle Spy log files
|
9. Vehicle Spy log files
|
||||||
10. CANDump / Kayak (Read only)
|
10. CANDump / Kayak (Read only)
|
||||||
11. PCAN Viewer (Read Only)
|
11. PCAN Viewer (Read Only)
|
||||||
|
12. Wireshark socketcan PCAP file (Read only)
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
@@ -47,9 +48,9 @@ to download it separately.
|
|||||||
|
|
||||||
This project requires 5.14.0 or higher because of a dependency on QtSerialBus and other new additions to Qt.
|
This project requires 5.14.0 or higher because of a dependency on QtSerialBus and other new additions to Qt.
|
||||||
|
|
||||||
NOTE: As the code in this master branch sits, it will not properly compile with QT6.
|
NOTE: As the code in this master branch sits, it does compile with QT6. Support for QT6 is approximately "beta" quality. Most all functions should work, please send issues if found.
|
||||||
However, there is a QT6WIP branch that should successfully compile. The QT6WIP branch may not
|
|
||||||
function entirely properly yet.
|
It appears that the current binary build for MacOS requires at least MacOS 10.15
|
||||||
|
|
||||||
## Instructions for compiling:
|
## Instructions for compiling:
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,10 @@
|
|||||||
#
|
#
|
||||||
#-------------------------------------------------
|
#-------------------------------------------------
|
||||||
|
|
||||||
|
!versionAtLeast(QT_VERSION, 5.14.0) {
|
||||||
|
error("Current version of Qt ($${QT_VERSION}) is too old, this project requires Qt 5.14 or newer")
|
||||||
|
}
|
||||||
|
|
||||||
QT = core gui printsupport qml serialbus serialport widgets help network opengl
|
QT = core gui printsupport qml serialbus serialport widgets help network opengl
|
||||||
|
|
||||||
CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG_OUTPUT
|
CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG_OUTPUT
|
||||||
|
|||||||
@@ -491,7 +491,26 @@ void LAWICELSerial::readSerialData()
|
|||||||
{
|
{
|
||||||
qDebug() << "Got CR!";
|
qDebug() << "Got CR!";
|
||||||
|
|
||||||
buildFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, QDateTime::currentMSecsSinceEpoch() * 1000l));
|
if (useSystemTime)
|
||||||
|
{
|
||||||
|
buildTimestamp = QDateTime::currentMSecsSinceEpoch() * 1000l;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//If total length is greater than command, header and data, timestamps must be enabled.
|
||||||
|
if (data.length() > (5 + mBuildLine.mid(4, 1).toInt() * 2 + 1))
|
||||||
|
{
|
||||||
|
//Four bytes after the end of the data bytes.
|
||||||
|
buildTimestamp = mBuildLine.mid(5 + mBuildLine.mid(4, 1).toInt() * 2, 4).toInt(nullptr, 16) * 1000l;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Default to system time if timestamps are disabled.
|
||||||
|
buildTimestamp = QDateTime::currentMSecsSinceEpoch() * 1000l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buildFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, buildTimestamp));
|
||||||
|
|
||||||
switch (mBuildLine[0].toLatin1())
|
switch (mBuildLine[0].toLatin1())
|
||||||
{
|
{
|
||||||
case 't': //standard frame
|
case 't': //standard frame
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ protected:
|
|||||||
QSerialPort *serial;
|
QSerialPort *serial;
|
||||||
int framesRapid;
|
int framesRapid;
|
||||||
CANFrame buildFrame;
|
CANFrame buildFrame;
|
||||||
|
qint64 buildTimestamp;
|
||||||
bool can0Enabled;
|
bool can0Enabled;
|
||||||
bool can0ListenOnly;
|
bool can0ListenOnly;
|
||||||
bool canFd;
|
bool canFd;
|
||||||
|
|||||||
+2
-2
@@ -214,12 +214,12 @@ QString DBC_SIGNAL::makePrettyOutput(double floatVal, int64_t intVal, bool outpu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!foundVal) outputString += QString::number(intVal);
|
if (!foundVal) outputString += QString::number(intVal);
|
||||||
if (outputUnit) outputString += unitName;
|
if (outputUnit) outputString += " " + unitName;
|
||||||
}
|
}
|
||||||
else //otherwise display the actual number and unit (if it exists)
|
else //otherwise display the actual number and unit (if it exists)
|
||||||
{
|
{
|
||||||
outputString += (isInteger ? QString::number(intVal) : QString::number(floatVal));
|
outputString += (isInteger ? QString::number(intVal) : QString::number(floatVal));
|
||||||
if (outputUnit) outputString += unitName;
|
if (outputUnit) outputString += " " + unitName;
|
||||||
}
|
}
|
||||||
return outputString;
|
return outputString;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -674,6 +674,44 @@ bool DBCFile::parseSignalMultiplexValueLine(QString line)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DBCFile::parseSignalValueTypeLine(QString line)
|
||||||
|
{
|
||||||
|
QRegularExpression regex;
|
||||||
|
QRegularExpressionMatch match;
|
||||||
|
qDebug() << "Found a signal valtype line";
|
||||||
|
regex.setPattern("^SIG\\_VALTYPE\\_ *(\\d+) *([-\\w]+) *: *(\\d+);");
|
||||||
|
match = regex.match(line);
|
||||||
|
|
||||||
|
// captured 1 is the message id
|
||||||
|
// captured 2 is the signal name
|
||||||
|
// captured 3 is the valtype
|
||||||
|
if (!match.hasMatch()) { return false; }
|
||||||
|
uint32_t id = match.captured(1).toULong() & 0x1FFFFFFFUL;
|
||||||
|
|
||||||
|
DBC_MESSAGE *msg = messageHandler->findMsgByID(match.captured(1).toULong() & 0x1FFFFFFFUL);
|
||||||
|
if (msg == nullptr) { return false; }
|
||||||
|
|
||||||
|
DBC_SIGNAL *thisSignal = msg->sigHandler->findSignalByName(match.captured(2));
|
||||||
|
if (thisSignal == nullptr) { return false; }
|
||||||
|
int valType = match.captured(3).toInt();
|
||||||
|
|
||||||
|
switch (valType) {
|
||||||
|
case 1: {
|
||||||
|
thisSignal->valType = SP_FLOAT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
thisSignal->valType = DP_FLOAT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DBCFile::parseValueLine(QString line)
|
bool DBCFile::parseValueLine(QString line)
|
||||||
{
|
{
|
||||||
QRegularExpression regex;
|
QRegularExpression regex;
|
||||||
@@ -941,6 +979,11 @@ bool DBCFile::loadFile(QString fileName)
|
|||||||
if (!parseSignalMultiplexValueLine(line)) numSigFaults++;
|
if (!parseSignalMultiplexValueLine(line)) numSigFaults++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (line.startsWith("SIG_VALTYPE_ ")) //defines a signal value type
|
||||||
|
{
|
||||||
|
if (!parseSignalValueTypeLine(line)) numSigFaults++;
|
||||||
|
}
|
||||||
|
|
||||||
if (line.startsWith("BU_:")) //line specifies the nodes on this canbus
|
if (line.startsWith("BU_:")) //line specifies the nodes on this canbus
|
||||||
{
|
{
|
||||||
qDebug() << "Found a BU line";
|
qDebug() << "Found a BU line";
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ private:
|
|||||||
bool parseSignalMultiplexValueLine(QString line);
|
bool parseSignalMultiplexValueLine(QString line);
|
||||||
DBC_MESSAGE* parseMessageLine(QString line);
|
DBC_MESSAGE* parseMessageLine(QString line);
|
||||||
bool parseValueLine(QString line);
|
bool parseValueLine(QString line);
|
||||||
|
bool parseSignalValueTypeLine(QString line);
|
||||||
bool parseAttributeLine(QString line);
|
bool parseAttributeLine(QString line);
|
||||||
bool parseDefaultAttrLine(QString line);
|
bool parseDefaultAttrLine(QString line);
|
||||||
};
|
};
|
||||||
|
|||||||
+126
-15
@@ -191,6 +191,7 @@ bool FrameFileIO::loadFrameFile(QString &fileName, QVector<CANFrame>* frameCache
|
|||||||
filters.append(QString(tr("CLX000 (*.txt *.TXT)")));
|
filters.append(QString(tr("CLX000 (*.txt *.TXT)")));
|
||||||
filters.append(QString(tr("CANServer Binary Log (*.log *.LOG)")));
|
filters.append(QString(tr("CANServer Binary Log (*.log *.LOG)")));
|
||||||
filters.append(QString(tr("Wireshark (*.pcap *.PCAP *.pcapng *.PCAPNG)")));
|
filters.append(QString(tr("Wireshark (*.pcap *.PCAP *.pcapng *.PCAPNG)")));
|
||||||
|
filters.append(QString(tr("Wireshark SocketCAN (*.pcap *.PCAP")));
|
||||||
|
|
||||||
dialog.setDirectory(settings.value("FileIO/LoadSaveDirectory", dialog.directory().path()).toString());
|
dialog.setDirectory(settings.value("FileIO/LoadSaveDirectory", dialog.directory().path()).toString());
|
||||||
dialog.setFileMode(QFileDialog::ExistingFile);
|
dialog.setFileMode(QFileDialog::ExistingFile);
|
||||||
@@ -237,6 +238,7 @@ bool FrameFileIO::loadFrameFile(QString &fileName, QVector<CANFrame>* frameCache
|
|||||||
if (selectedNameFilter == filters[22]) result = loadCLX000File(filename, frameCache);
|
if (selectedNameFilter == filters[22]) result = loadCLX000File(filename, frameCache);
|
||||||
if (selectedNameFilter == filters[23]) result = loadCANServerFile(filename, frameCache);
|
if (selectedNameFilter == filters[23]) result = loadCANServerFile(filename, frameCache);
|
||||||
if (selectedNameFilter == filters[24]) result = loadWiresharkFile(filename, frameCache);
|
if (selectedNameFilter == filters[24]) result = loadWiresharkFile(filename, frameCache);
|
||||||
|
if (selectedNameFilter == filters[25]) result = loadWiresharkSocketCANFile(filename, frameCache);
|
||||||
|
|
||||||
|
|
||||||
progress.cancel();
|
progress.cancel();
|
||||||
@@ -288,6 +290,28 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector<CANFrame>* frames
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attempt to load socket CAN first to avoid generic wireshark logic catching it
|
||||||
|
qDebug() << "Attempting Wireshark Socket CAN Log";
|
||||||
|
if (isWiresharkSocketCANFile(filename))
|
||||||
|
{
|
||||||
|
if (loadWiresharkSocketCANFile(filename, frames))
|
||||||
|
{
|
||||||
|
qDebug() << "Loaded as Wireshark SocketCAN Log successfully!";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This and the decoder above were both moved above TeslaAPFile as they match based on magic numbers and sometimes these files were falling into the TeslaAP decoder
|
||||||
|
qDebug() << "Attempting Wireshark Log";
|
||||||
|
if (isWiresharkFile(filename))
|
||||||
|
{
|
||||||
|
if (loadWiresharkFile(filename, frames))
|
||||||
|
{
|
||||||
|
qDebug() << "Loaded as Wireshark Log successfully!";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qDebug() << "Attempting Tesla AP Snapshot";
|
qDebug() << "Attempting Tesla AP Snapshot";
|
||||||
if (isTeslaAPFile(filename))
|
if (isTeslaAPFile(filename))
|
||||||
{
|
{
|
||||||
@@ -308,16 +332,6 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector<CANFrame>* frames
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "Attempting Wireshark Log";
|
|
||||||
if (isWiresharkFile(filename))
|
|
||||||
{
|
|
||||||
if (loadWiresharkFile(filename, frames))
|
|
||||||
{
|
|
||||||
qDebug() << "Loaded as Wireshark Log successfully!";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << "Attempting canalyzer ASC";
|
qDebug() << "Attempting canalyzer ASC";
|
||||||
if (isCanalyzerASC(filename))
|
if (isCanalyzerASC(filename))
|
||||||
{
|
{
|
||||||
@@ -5023,7 +5037,7 @@ bool FrameFileIO::loadWiresharkFile(QString filename, QVector<CANFrame>* frames)
|
|||||||
|
|
||||||
QByteArray ba = filename.toLocal8Bit();
|
QByteArray ba = filename.toLocal8Bit();
|
||||||
|
|
||||||
pcap_data_file = pcap_open_offline(ba.data(), errbuf);
|
pcap_data_file = pcap_open_offline(ba.data(), errbuf, PCAP_LINKTYPE_ANY);
|
||||||
if (!pcap_data_file) {
|
if (!pcap_data_file) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -5050,9 +5064,13 @@ bool FrameFileIO::loadWiresharkFile(QString filename, QVector<CANFrame>* frames)
|
|||||||
thisFrame.isReceived = true; // TODO: check if tx detection is possible
|
thisFrame.isReceived = true; // TODO: check if tx detection is possible
|
||||||
|
|
||||||
thisFrame.setFrameType(QCanBusFrame::DataFrame);
|
thisFrame.setFrameType(QCanBusFrame::DataFrame);
|
||||||
thisFrame.setFrameId((0xff & *(packetData+17)) << 8 | (0xff & *(packetData+16)));
|
if ((0x80 & *(packetData+19))) {
|
||||||
if (thisFrame.frameId() <= 0x7FF) thisFrame.setExtendedFrameFormat(false);
|
thisFrame.setExtendedFrameFormat(true);
|
||||||
else thisFrame.setExtendedFrameFormat(true);
|
thisFrame.setFrameId((0x3f & *(packetData+19))<<24 | (0xff & *(packetData+18)) << 16 | (0xff & *(packetData+17)) << 8 | (0xff & *(packetData+16)));
|
||||||
|
} else {
|
||||||
|
thisFrame.setExtendedFrameFormat(false);
|
||||||
|
thisFrame.setFrameId((0xff & *(packetData+17)) << 8 | (0xff & *(packetData+16)));
|
||||||
|
}
|
||||||
thisFrame.bus = 0;
|
thisFrame.bus = 0;
|
||||||
int numBytes = *(packetData+20);
|
int numBytes = *(packetData+20);
|
||||||
QByteArray bytes(numBytes, 0);
|
QByteArray bytes(numBytes, 0);
|
||||||
@@ -5079,7 +5097,7 @@ bool FrameFileIO::isWiresharkFile(QString filename)
|
|||||||
char errbuf[PCAP_ERRBUF_SIZE];
|
char errbuf[PCAP_ERRBUF_SIZE];
|
||||||
QByteArray ba = filename.toLocal8Bit();
|
QByteArray ba = filename.toLocal8Bit();
|
||||||
|
|
||||||
pcap_data_file = pcap_open_offline(ba.data(), errbuf);
|
pcap_data_file = pcap_open_offline(ba.data(), errbuf, PCAP_LINKTYPE_ANY);
|
||||||
if (!pcap_data_file) {
|
if (!pcap_data_file) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -5089,3 +5107,96 @@ bool FrameFileIO::isWiresharkFile(QString filename)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FrameFileIO::loadWiresharkSocketCANFile(QString filename, QVector<CANFrame>* frames)
|
||||||
|
{
|
||||||
|
pcap_t *pcap_data_file;
|
||||||
|
CANFrame thisFrame;
|
||||||
|
long long startTimestamp = 0;
|
||||||
|
long long timeStamp;
|
||||||
|
int lineCounter = 0;
|
||||||
|
bool foundErrors = false;
|
||||||
|
pcap_pkthdr packetHeader;
|
||||||
|
const char *packetData = NULL;
|
||||||
|
char errbuf[PCAP_ERRBUF_SIZE];
|
||||||
|
|
||||||
|
QByteArray ba = filename.toLocal8Bit();
|
||||||
|
|
||||||
|
pcap_data_file = pcap_open_offline(ba.data(), errbuf, PCAP_LINKTYPE_SOCKETCAN);
|
||||||
|
if (!pcap_data_file) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetData = (const char*)pcap_next(pcap_data_file, &packetHeader);
|
||||||
|
while (packetData) {
|
||||||
|
lineCounter++;
|
||||||
|
if (lineCounter > 100) {
|
||||||
|
qApp->processEvents();
|
||||||
|
lineCounter = 0;
|
||||||
|
}
|
||||||
|
thisFrame.bus = 0;
|
||||||
|
|
||||||
|
// Timestamp
|
||||||
|
timeStamp = packetHeader.ts.tv_sec * 1000000 + packetHeader.ts.tv_usec;
|
||||||
|
if (0 == startTimestamp) {
|
||||||
|
startTimestamp = timeStamp;
|
||||||
|
}
|
||||||
|
timeStamp -= startTimestamp;
|
||||||
|
thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, timeStamp));
|
||||||
|
|
||||||
|
// ID and extended frame format
|
||||||
|
const quint32 can_id = qFromBigEndian<quint32>(packetData);
|
||||||
|
if (can_id & 0x80000000) {
|
||||||
|
thisFrame.setExtendedFrameFormat(true);
|
||||||
|
thisFrame.setFrameId(0x1fffffff & can_id);
|
||||||
|
} else {
|
||||||
|
thisFrame.setExtendedFrameFormat(false);
|
||||||
|
thisFrame.setFrameId(0x7ff & can_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Frame type
|
||||||
|
if (can_id & 0x20000000U) {
|
||||||
|
thisFrame.setFrameType(QCanBusFrame::ErrorFrame);
|
||||||
|
} else if (can_id & 0x40000000U) {
|
||||||
|
thisFrame.setFrameType(QCanBusFrame::RemoteRequestFrame);
|
||||||
|
} else {
|
||||||
|
thisFrame.setFrameType(QCanBusFrame::DataFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Direction - This isn't actually officially supported, but CAN Bus Debugger device logs set this byte to 1 to indicate a TX frame and 0 for RX
|
||||||
|
quint8 direction = (quint8) *(packetData + 6);
|
||||||
|
thisFrame.isReceived = (direction != 1);
|
||||||
|
|
||||||
|
// Data
|
||||||
|
quint8 numBytes = (quint8) *(packetData + 4);
|
||||||
|
if (numBytes > 8) {
|
||||||
|
numBytes = 8;
|
||||||
|
}
|
||||||
|
QByteArray bytes(numBytes, 0);
|
||||||
|
for (int d = 0; d < numBytes; d++) {
|
||||||
|
bytes[d] = *(packetData + 8 + d);
|
||||||
|
}
|
||||||
|
thisFrame.setPayload(bytes);
|
||||||
|
frames->append(thisFrame);
|
||||||
|
|
||||||
|
packetData = (const char*) pcap_next(pcap_data_file, &packetHeader);
|
||||||
|
}
|
||||||
|
pcap_close(pcap_data_file);
|
||||||
|
pcap_data_file = NULL;
|
||||||
|
return !foundErrors;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FrameFileIO::isWiresharkSocketCANFile(QString filename)
|
||||||
|
{
|
||||||
|
pcap_t *pcap_data_file;
|
||||||
|
char errbuf[PCAP_ERRBUF_SIZE];
|
||||||
|
QByteArray ba = filename.toLocal8Bit();
|
||||||
|
|
||||||
|
pcap_data_file = pcap_open_offline(ba.data(), errbuf, PCAP_LINKTYPE_SOCKETCAN);
|
||||||
|
if (!pcap_data_file) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pcap_close(pcap_data_file);
|
||||||
|
pcap_data_file = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public:
|
|||||||
static bool loadCLX000File(QString filename, QVector<CANFrame>* frames);
|
static bool loadCLX000File(QString filename, QVector<CANFrame>* frames);
|
||||||
static bool loadCANServerFile(QString filename, QVector<CANFrame>* frames);
|
static bool loadCANServerFile(QString filename, QVector<CANFrame>* frames);
|
||||||
static bool loadWiresharkFile(QString filename, QVector<CANFrame>* frames);
|
static bool loadWiresharkFile(QString filename, QVector<CANFrame>* frames);
|
||||||
|
static bool loadWiresharkSocketCANFile(QString filename, QVector<CANFrame>* frames);
|
||||||
|
|
||||||
//functions that pre-scan a file to try to figure out if they could read it. Used to automatically determine
|
//functions that pre-scan a file to try to figure out if they could read it. Used to automatically determine
|
||||||
//file type and load it.
|
//file type and load it.
|
||||||
@@ -80,6 +81,7 @@ public:
|
|||||||
static bool isCLX000File(QString filename);
|
static bool isCLX000File(QString filename);
|
||||||
static bool isCANServerFile(QString filename);
|
static bool isCANServerFile(QString filename);
|
||||||
static bool isWiresharkFile(QString filename);
|
static bool isWiresharkFile(QString filename);
|
||||||
|
static bool isWiresharkSocketCANFile(QString filename);
|
||||||
|
|
||||||
static bool saveCRTDFile(QString, const QVector<CANFrame>*);
|
static bool saveCRTDFile(QString, const QVector<CANFrame>*);
|
||||||
static bool saveNativeCSVFile(QString, const QVector<CANFrame>*);
|
static bool saveNativeCSVFile(QString, const QVector<CANFrame>*);
|
||||||
|
|||||||
+18
-3
@@ -19,7 +19,7 @@
|
|||||||
static unsigned char pcap_buffer[MAX_CAN_PACKET_SIZE];
|
static unsigned char pcap_buffer[MAX_CAN_PACKET_SIZE];
|
||||||
static pcap_t p;
|
static pcap_t p;
|
||||||
|
|
||||||
pcap *pcap_open_offline(const char *filename, char *error_text) {
|
pcap *pcap_open_offline(const char *filename, char *error_text, int expected_link_type) {
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
|
||||||
snprintf(error_text, PCAP_ERRBUF_SIZE, "OK");
|
snprintf(error_text, PCAP_ERRBUF_SIZE, "OK");
|
||||||
@@ -48,6 +48,23 @@ pcap *pcap_open_offline(const char *filename, char *error_text) {
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int link_type;
|
||||||
|
fseek(file, PCAP_FILE_HEADER_LENGTH - 4, SEEK_SET);
|
||||||
|
bytes_read = fread(&link_type, 1, sizeof(link_type), file);
|
||||||
|
if (bytes_read != sizeof(link_type)) {
|
||||||
|
snprintf(error_text, PCAP_ERRBUF_SIZE, "Cannot read linktype word");
|
||||||
|
fclose(file);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if (expected_link_type >= 0) {
|
||||||
|
// Check the link type
|
||||||
|
if ((int) link_type != expected_link_type) {
|
||||||
|
snprintf(error_text, PCAP_ERRBUF_SIZE, "This link type is not supported by this decoder");
|
||||||
|
fclose(file);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// set the format
|
// set the format
|
||||||
// and seek past file header
|
// and seek past file header
|
||||||
if (MAGIC_NG == magic) {
|
if (MAGIC_NG == magic) {
|
||||||
@@ -61,14 +78,12 @@ pcap *pcap_open_offline(const char *filename, char *error_text) {
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
fseek(file, section_length, SEEK_SET);
|
fseek(file, section_length, SEEK_SET);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
p.is_ng = 0;
|
p.is_ng = 0;
|
||||||
fseek(file, PCAP_FILE_HEADER_LENGTH, SEEK_SET);
|
fseek(file, PCAP_FILE_HEADER_LENGTH, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.file = file;
|
p.file = file;
|
||||||
|
|
||||||
return(&p);
|
return(&p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -8,7 +8,9 @@
|
|||||||
#include <winsock.h>
|
#include <winsock.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PCAP_ERRBUF_SIZE 256
|
#define PCAP_ERRBUF_SIZE (256)
|
||||||
|
#define PCAP_LINKTYPE_SOCKETCAN (227)
|
||||||
|
#define PCAP_LINKTYPE_ANY (-1)
|
||||||
|
|
||||||
struct pcap_pkthdr {
|
struct pcap_pkthdr {
|
||||||
struct timeval ts; /* time stamp */
|
struct timeval ts; /* time stamp */
|
||||||
@@ -23,7 +25,7 @@ struct pcap {
|
|||||||
|
|
||||||
typedef struct pcap pcap_t;
|
typedef struct pcap pcap_t;
|
||||||
|
|
||||||
pcap *pcap_open_offline(const char *, char *);
|
pcap *pcap_open_offline(const char *, char *, int);
|
||||||
|
|
||||||
const unsigned char *pcap_next(pcap_t *, struct pcap_pkthdr *);
|
const unsigned char *pcap_next(pcap_t *, struct pcap_pkthdr *);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user