From 72bc5914a6da5306d1d423ce840bac64c31cd857 Mon Sep 17 00:00:00 2001 From: Paul Hollinsky Date: Tue, 4 May 2021 23:25:36 -0400 Subject: [PATCH] EthernetPacket: Allow 1 extra byte at the end of the packet ValueCAN 4-2EL sends an extra byte to pad the message to an even byte count. --- communication/decoder.cpp | 2 +- communication/packet/ethernetpacket.cpp | 15 +++++++++------ .../icsneo/communication/packet/ethernetpacket.h | 4 ++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/communication/decoder.cpp b/communication/decoder.cpp index b34e16b..1e76ecc 100644 --- a/communication/decoder.cpp +++ b/communication/decoder.cpp @@ -24,7 +24,7 @@ uint64_t Decoder::GetUInt64FromLEBytes(const uint8_t* bytes) { bool Decoder::decode(std::shared_ptr& result, const std::shared_ptr& packet) { switch(packet->network.getType()) { case Network::Type::Ethernet: - result = HardwareEthernetPacket::DecodeToMessage(packet->data); + result = HardwareEthernetPacket::DecodeToMessage(packet->data, report); if(!result) { report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error); return false; // A nullptr was returned, the packet was not long enough to decode diff --git a/communication/packet/ethernetpacket.cpp b/communication/packet/ethernetpacket.cpp index 7d935d3..e3dd59f 100644 --- a/communication/packet/ethernetpacket.cpp +++ b/communication/packet/ethernetpacket.cpp @@ -4,7 +4,7 @@ using namespace icsneo; -std::shared_ptr HardwareEthernetPacket::DecodeToMessage(const std::vector& bytestream) { +std::shared_ptr HardwareEthernetPacket::DecodeToMessage(const std::vector& bytestream, const device_eventhandler_t& report) { const HardwareEthernetPacket* packet = (const HardwareEthernetPacket*)((const void*)bytestream.data()); const uint16_t* rawWords = (const uint16_t*)bytestream.data(); @@ -16,12 +16,15 @@ std::shared_ptr HardwareEthernetPacket::DecodeToMessage(const s if(packet->Length < 4) return nullptr; - size_t bytesOnWire = packet->Length - (sizeof(uint16_t) * 2); - if(bytestream.size() < sizeof(HardwareEthernetPacket) + bytesOnWire) + const size_t ethernetFrameSize = packet->Length - (sizeof(uint16_t) * 2); + const size_t bytestreamExpectedSize = sizeof(HardwareEthernetPacket) + ethernetFrameSize; + const size_t bytestreamActualSize = bytestream.size(); + if(bytestreamActualSize < bytestreamExpectedSize) return nullptr; - if(bytestream.size() > sizeof(HardwareEthernetPacket) + bytesOnWire) - std::cout << "There is an extra " << (sizeof(HardwareEthernetPacket) + bytesOnWire) << " bytes at the end" << std::endl; + // Check for oversized packets, noting that some devices will send an extra byte to have an even number of bytes + if(bytestreamActualSize > bytestreamExpectedSize + 1) + report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning); auto messagePtr = std::make_shared(); EthernetMessage& message = *messagePtr; @@ -47,7 +50,7 @@ std::shared_ptr HardwareEthernetPacket::DecodeToMessage(const s // Network ID is also not set, this will be fixed in the Decoder as well const std::vector::const_iterator databegin = bytestream.begin() + (sizeof(HardwareEthernetPacket) - (sizeof(uint16_t) * 2)); - const std::vector::const_iterator dataend = databegin + bytesOnWire; + const std::vector::const_iterator dataend = databegin + ethernetFrameSize; message.data.insert(message.data.begin(), databegin, dataend); return messagePtr; diff --git a/include/icsneo/communication/packet/ethernetpacket.h b/include/icsneo/communication/packet/ethernetpacket.h index 7eee8a1..3696fa0 100644 --- a/include/icsneo/communication/packet/ethernetpacket.h +++ b/include/icsneo/communication/packet/ethernetpacket.h @@ -13,8 +13,8 @@ namespace icsneo { typedef uint16_t icscm_bitfield; struct HardwareEthernetPacket { - static std::shared_ptr DecodeToMessage(const std::vector& bytestream); - static bool EncodeFromMessage(const EthernetMessage& message, std::vector& bytestream, const device_eventhandler_t& err); + static std::shared_ptr DecodeToMessage(const std::vector& bytestream, const device_eventhandler_t& report); + static bool EncodeFromMessage(const EthernetMessage& message, std::vector& bytestream, const device_eventhandler_t& report); struct { icscm_bitfield FCS_AVAIL : 1;