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.
pull/35/head
Paul Hollinsky 2021-05-04 23:25:36 -04:00
parent eca1110305
commit 72bc5914a6
3 changed files with 12 additions and 9 deletions

View File

@ -24,7 +24,7 @@ uint64_t Decoder::GetUInt64FromLEBytes(const uint8_t* bytes) {
bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Packet>& 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

View File

@ -4,7 +4,7 @@
using namespace icsneo;
std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const std::vector<uint8_t>& 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<EthernetMessage> 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>();
EthernetMessage& message = *messagePtr;
@ -47,7 +50,7 @@ std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const s
// Network ID is also not set, this will be fixed in the Decoder as well
const std::vector<uint8_t>::const_iterator databegin = bytestream.begin() + (sizeof(HardwareEthernetPacket) - (sizeof(uint16_t) * 2));
const std::vector<uint8_t>::const_iterator dataend = databegin + bytesOnWire;
const std::vector<uint8_t>::const_iterator dataend = databegin + ethernetFrameSize;
message.data.insert(message.data.begin(), databegin, dataend);
return messagePtr;

View File

@ -13,8 +13,8 @@ namespace icsneo {
typedef uint16_t icscm_bitfield;
struct HardwareEthernetPacket {
static std::shared_ptr<EthernetMessage> DecodeToMessage(const std::vector<uint8_t>& bytestream);
static bool EncodeFromMessage(const EthernetMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& err);
static std::shared_ptr<EthernetMessage> DecodeToMessage(const std::vector<uint8_t>& bytestream, const device_eventhandler_t& report);
static bool EncodeFromMessage(const EthernetMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& report);
struct {
icscm_bitfield FCS_AVAIL : 1;