mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 01:18:36 +02:00
C2: Add Ethernet message support
This commit is contained in:
committed by
Kyle Schwarz
parent
87f45e060e
commit
9ae3e115fc
@@ -4,63 +4,89 @@
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/communication/message/message.h"
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <cstring>
|
||||
#include <optional>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
struct MACAddress {
|
||||
uint8_t data[6];
|
||||
|
||||
std::string toString() const {
|
||||
std::stringstream ss;
|
||||
for(size_t i = 0; i < 6; i++) {
|
||||
ss << std::hex << std::setw(2) << std::setfill('0') << (int)data[i];
|
||||
if(i != 5)
|
||||
ss << ':';
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const MACAddress& mac) {
|
||||
os << mac.toString();
|
||||
return os;
|
||||
}
|
||||
};
|
||||
using MACAddress = std::array<uint8_t, 6>;
|
||||
|
||||
class EthernetMessage : public Frame {
|
||||
public:
|
||||
// Standard Ethernet fields
|
||||
bool preemptionEnabled = false;
|
||||
uint8_t preemptionFlags = 0;
|
||||
// Frame Check Sequence
|
||||
std::optional<uint32_t> fcs;
|
||||
bool frameTooShort = false;
|
||||
bool noPadding = false;
|
||||
bool fcsVerified = false;
|
||||
bool txAborted = false;
|
||||
bool crcError = false;
|
||||
bool isT1S = false;
|
||||
|
||||
|
||||
bool isT1SSymbol = false;
|
||||
bool isT1SBurst = false;
|
||||
bool txCollision = false;
|
||||
bool isT1SWake = false;
|
||||
uint8_t t1sNodeId = 0;
|
||||
uint8_t t1sBurstCount = 0;
|
||||
uint8_t t1sSymbolType = 0;
|
||||
// T1S-specific fields
|
||||
struct T1S {
|
||||
T1S() {}
|
||||
|
||||
// Accessors
|
||||
const MACAddress& getDestinationMAC() const { return *(const MACAddress*)(data.data() + 0); }
|
||||
const MACAddress& getSourceMAC() const { return *(const MACAddress*)(data.data() + 6); }
|
||||
uint16_t getEtherType() const { return (data[12] << 8) | data[13]; }
|
||||
bool isSymbol = false;
|
||||
bool isBurst = false;
|
||||
bool txCollision = false;
|
||||
bool isWake = false;
|
||||
uint8_t nodeId = 0;
|
||||
uint8_t burstCount = 0;
|
||||
uint8_t symbolType = 0;
|
||||
};
|
||||
std::optional<T1S> t1s;
|
||||
|
||||
// TSN-specific fields
|
||||
// If we expand TSN we should probably do something similar to what we did above with T1S.
|
||||
// IEEE 802.1Qbu frame preemption
|
||||
std::optional<uint8_t> preemptionFlags;
|
||||
|
||||
// Helper functions to extract Destination MAC from the data payload
|
||||
// returns std::nullopt if the data payload is not large enough
|
||||
std::optional<MACAddress> getDestinationMAC() const {
|
||||
if(data.size() < 6) {
|
||||
return std::nullopt;
|
||||
}
|
||||
MACAddress mac;
|
||||
std::copy(data.begin(), data.begin() + 6, mac.begin());
|
||||
return mac;
|
||||
}
|
||||
|
||||
// Helper functions to extract Source MAC from the data payload
|
||||
// returns std::nullopt if the data payload is not large enough
|
||||
std::optional<MACAddress> getSourceMAC() const {
|
||||
if(data.size() < 12) {
|
||||
return std::nullopt;
|
||||
}
|
||||
MACAddress mac;
|
||||
std::copy(data.begin() + 6, data.begin() + 12, mac.begin());
|
||||
return mac;
|
||||
}
|
||||
|
||||
// Helper function to extract EtherType from the data payload
|
||||
//
|
||||
// EtherType is a two-octet field in an Ethernet frame (big-endian).
|
||||
// It is used to indicate which protocol is encapsulated in the payload of the frame
|
||||
// and is used at the receiving end by the data link layer to determine how the payload is processed.
|
||||
// For example, an EtherType of 0x0800 indicates that the payload is an IPv4 packet, while 0x86DD indicates an IPv6 packet.
|
||||
//
|
||||
// returns std::nullopt if the data payload is not large enough
|
||||
std::optional<uint16_t> getEtherType() const {
|
||||
if(data.size() < 14) {
|
||||
return std::nullopt;
|
||||
}
|
||||
// EtherType is stored in a 2-byte network byte order (big-endian)
|
||||
return static_cast<uint16_t>((uint16_t(data[12]) << 8) | uint16_t(data[13]));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
#endif // __ETHERNETMESSAGE_H_
|
||||
|
||||
Reference in New Issue
Block a user