- latest changes for HEP support

This commit is contained in:
Dmytro Bogovych 2018-09-24 09:45:56 +03:00
parent 8c0f9510e6
commit 2f69f58088
4 changed files with 318 additions and 315 deletions

View File

@ -9,141 +9,143 @@ static const uint32_t HEPID3 = 0x48455033;
bool Packet::parseV3(const ByteBuffer& packet) bool Packet::parseV3(const ByteBuffer& packet)
{ {
if (packet.size() < 30) if (packet.size() < 30)
return false; return false;
BufferReader r(packet); BufferReader r(packet);
char signature[4]; char signature[4];
r.readBuffer(signature, 4); r.readBuffer(signature, 4);
if (signature[0] != 'H' || signature[1] != 'E' || signature[2] != 'P' || signature[3] != '3') if (signature[0] != 'H' || signature[1] != 'E' || signature[2] != 'P' || signature[3] != '3')
return false; return false;
// Total length // Total length
int l = r.readUShort(); int l = r.readUShort();
l -= 6; l -= 6;
InternetAddress sourceAddr4, destAddr4, sourceAddr6, destAddr6; InternetAddress sourceAddr4, destAddr4, sourceAddr6, destAddr6;
uint16_t sourcePort = 0, destPort = 0; uint16_t sourcePort = 0, destPort = 0;
while (r.count() < packet.size()) while (r.count() < packet.size())
{
mVendorId = (VendorId)r.readUShort();
ChunkType chunkType = (ChunkType)r.readUShort();
int chunkLength = r.readUShort();
switch (chunkType)
{ {
case ChunkType::IPProtocolFamily: mVendorId = (VendorId)r.readUShort();
mIpProtocolFamily = r.readUChar(); ChunkType chunkType = (ChunkType)r.readUShort();
break; int chunkLength = r.readUShort();
case ChunkType::IPProtocolID: switch (chunkType)
mIpProtocolId = r.readUChar(); {
break; case ChunkType::IPProtocolFamily:
mIpProtocolFamily = r.readUChar();
break;
case ChunkType::IP4SourceAddress: case ChunkType::IPProtocolID:
sourceAddr4 = r.readIp(AF_INET); mIpProtocolId = r.readUChar();
break; break;
case ChunkType::IP4DestinationAddress: case ChunkType::IP4SourceAddress:
destAddr4 = r.readIp(AF_INET); sourceAddr4 = r.readIp(AF_INET);
break; break;
case ChunkType::IP6SourceAddress: case ChunkType::IP4DestinationAddress:
sourceAddr6 = r.readIp(AF_INET); destAddr4 = r.readIp(AF_INET);
break; break;
case ChunkType::IP6DestinationAddress: case ChunkType::IP6SourceAddress:
destAddr6 = r.readIp(AF_INET6); sourceAddr6 = r.readIp(AF_INET);
break; break;
case ChunkType::SourcePort: case ChunkType::IP6DestinationAddress:
sourcePort = r.readUShort(); destAddr6 = r.readIp(AF_INET6);
break; break;
case ChunkType::DestinationPort: case ChunkType::SourcePort:
destPort = r.readUShort(); sourcePort = r.readUShort();
break; break;
case ChunkType::Timestamp: case ChunkType::DestinationPort:
mTimestamp.tv_sec = r.readUInt(); destPort = r.readUShort();
break; break;
case ChunkType::TimestampMicro: case ChunkType::Timestamp:
mTimestamp.tv_usec = r.readUInt() * 1000; mTimestamp.tv_sec = r.readUInt();
break; break;
case ChunkType::ProtocolType: case ChunkType::TimestampMicro:
mProtocolType = (ProtocolId)r.readUChar(); mTimestamp.tv_usec = r.readUInt() * 1000;
break; break;
case ChunkType::CaptureAgentID: case ChunkType::ProtocolType:
mCaptureAgentId = r.readUInt(); mProtocolType = (ProtocolId)r.readUChar();
break; break;
case ChunkType::KeepAliveTimer: case ChunkType::CaptureAgentID:
mKeepAliveTimer = r.readUShort(); mCaptureAgentId = r.readUInt();
break; break;
case ChunkType::AuthenticationKey: case ChunkType::KeepAliveTimer:
mAuthenticateKey.resize(chunkLength - 6); mKeepAliveTimer = r.readUShort();
r.readBuffer(mAuthenticateKey.mutableData(), mAuthenticateKey.size()); break;
break;
case ChunkType::PacketPayload: case ChunkType::AuthenticationKey:
r.readBuffer(mBody, chunkLength - 6); mAuthenticateKey.resize(chunkLength - 6);
break; r.readBuffer(mAuthenticateKey.mutableData(), mAuthenticateKey.size());
break;
default: case ChunkType::PacketPayload:
r.readBuffer(nullptr, chunkLength - 6); mBodyOffset = r.count();
r.readBuffer(mBody, chunkLength - 6);
break;
default:
r.readBuffer(nullptr, chunkLength - 6);
}
} }
}
if (!sourceAddr4.isEmpty()) if (!sourceAddr4.isEmpty())
mSourceAddress = sourceAddr4; mSourceAddress = sourceAddr4;
else else
if (!sourceAddr6.isEmpty()) if (!sourceAddr6.isEmpty())
mSourceAddress = sourceAddr6; mSourceAddress = sourceAddr6;
if (!mSourceAddress.isEmpty()) if (!mSourceAddress.isEmpty())
mSourceAddress.setPort(sourcePort); mSourceAddress.setPort(sourcePort);
if (!destAddr4.isEmpty()) if (!destAddr4.isEmpty())
mDestinationAddress = destAddr4; mDestinationAddress = destAddr4;
else else
if (!destAddr6.isEmpty()) if (!destAddr6.isEmpty())
mDestinationAddress = destAddr6; mDestinationAddress = destAddr6;
if (!mDestinationAddress.isEmpty()) if (!mDestinationAddress.isEmpty())
mDestinationAddress.setPort(destPort); mDestinationAddress.setPort(destPort);
return true; return true;
} }
bool Packet::parseV2(const ByteBuffer &packet) bool Packet::parseV2(const ByteBuffer &packet)
{ {
if (packet.size() < 31) if (packet.size() < 31)
return false; return false;
if (packet[0] != 0x02) if (packet[0] != 0x02)
return false; return false;
BufferReader r(packet); BufferReader r(packet);
r.readBuffer(nullptr, 4); r.readBuffer(nullptr, 4);
uint16_t sourcePort = r.readUShort(); uint16_t sourcePort = r.readUShort();
uint16_t dstPort = r.readUShort(); uint16_t dstPort = r.readUShort();
mSourceAddress = r.readIp(AF_INET); mSourceAddress = r.readIp(AF_INET);
mSourceAddress.setPort(sourcePort); mSourceAddress.setPort(sourcePort);
mDestinationAddress = r.readIp(AF_INET); mDestinationAddress = r.readIp(AF_INET);
mDestinationAddress.setPort(dstPort); mDestinationAddress.setPort(dstPort);
mTimestamp.tv_sec = r.readUInt(); mTimestamp.tv_sec = r.readUInt();
mTimestamp.tv_usec = r.readUInt() * 1000; mTimestamp.tv_usec = r.readUInt() * 1000;
mCaptureAgentId = r.readUShort(); mCaptureAgentId = r.readUShort();
r.readBuffer(nullptr, 2); r.readBuffer(nullptr, 2);
mBody.clear(); mBody.clear();
r.readBuffer(mBody, 65536 - 28); mBodyOffset = r.count();
return true; r.readBuffer(mBody, 65536 - 28);
return true;
} }
#define WRITE_CHUNK_UCHAR(T, V) {w.writeUShort((uint16_t)mVendorId); w.writeUShort((uint16_t)T); w.writeUShort(1); w.writeUChar((uint8_t)V);} #define WRITE_CHUNK_UCHAR(T, V) {w.writeUShort((uint16_t)mVendorId); w.writeUShort((uint16_t)T); w.writeUShort(1); w.writeUChar((uint8_t)V);}
@ -155,66 +157,66 @@ bool Packet::parseV2(const ByteBuffer &packet)
ByteBuffer Packet::buildV3() ByteBuffer Packet::buildV3()
{ {
ByteBuffer r; r.resize(mBody.size() + 512); ByteBuffer r; r.resize(mBody.size() + 512);
BufferWriter w(r); BufferWriter w(r);
// Signature // Signature
w.writeBuffer("HEP3", 4); w.writeBuffer("HEP3", 4);
// Reserve place for total length // Reserve place for total length
w.writeUShort(0); w.writeUShort(0);
WRITE_CHUNK_UCHAR(ChunkType::IPProtocolFamily, mIpProtocolFamily); WRITE_CHUNK_UCHAR(ChunkType::IPProtocolFamily, mIpProtocolFamily);
WRITE_CHUNK_UCHAR(ChunkType::IPProtocolID, mIpProtocolId); WRITE_CHUNK_UCHAR(ChunkType::IPProtocolID, mIpProtocolId);
// Source address // Source address
if (!mSourceAddress.isEmpty()) if (!mSourceAddress.isEmpty())
{ {
if (mSourceAddress.isV4()) if (mSourceAddress.isV4())
WRITE_CHUNK_IP4(ChunkType::IP4SourceAddress, mSourceAddress) WRITE_CHUNK_IP4(ChunkType::IP4SourceAddress, mSourceAddress)
else else
if (mSourceAddress.isV6()) if (mSourceAddress.isV6())
WRITE_CHUNK_IP6(ChunkType::IP6SourceAddress, mSourceAddress); WRITE_CHUNK_IP6(ChunkType::IP6SourceAddress, mSourceAddress);
WRITE_CHUNK_USHORT(ChunkType::SourcePort, mSourceAddress.port()); WRITE_CHUNK_USHORT(ChunkType::SourcePort, mSourceAddress.port());
} }
// Destination address // Destination address
if (!mDestinationAddress.isEmpty()) if (!mDestinationAddress.isEmpty())
{ {
if (mDestinationAddress.isV4()) if (mDestinationAddress.isV4())
WRITE_CHUNK_IP4(ChunkType::IP4DestinationAddress, mDestinationAddress) WRITE_CHUNK_IP4(ChunkType::IP4DestinationAddress, mDestinationAddress)
else else
if (mDestinationAddress.isV6()) if (mDestinationAddress.isV6())
WRITE_CHUNK_IP6(ChunkType::IP6DestinationAddress, mDestinationAddress); WRITE_CHUNK_IP6(ChunkType::IP6DestinationAddress, mDestinationAddress);
WRITE_CHUNK_USHORT(ChunkType::DestinationPort, mDestinationAddress.port()); WRITE_CHUNK_USHORT(ChunkType::DestinationPort, mDestinationAddress.port());
} }
// Timestamp // Timestamp
WRITE_CHUNK_UINT(ChunkType::Timestamp, mTimestamp.tv_sec); WRITE_CHUNK_UINT(ChunkType::Timestamp, mTimestamp.tv_sec);
// TimestampMicro // TimestampMicro
WRITE_CHUNK_UINT(ChunkType::TimestampMicro, mTimestamp.tv_usec / 1000); WRITE_CHUNK_UINT(ChunkType::TimestampMicro, mTimestamp.tv_usec / 1000);
// Protocol type // Protocol type
WRITE_CHUNK_UINT(ChunkType::ProtocolType, mProtocolType); WRITE_CHUNK_UINT(ChunkType::ProtocolType, mProtocolType);
// Capture agent ID // Capture agent ID
WRITE_CHUNK_UINT(ChunkType::CaptureAgentID, mCaptureAgentId); WRITE_CHUNK_UINT(ChunkType::CaptureAgentID, mCaptureAgentId);
// Keep alive timer value // Keep alive timer value
WRITE_CHUNK_USHORT(ChunkType::KeepAliveTimer, mKeepAliveTimer); WRITE_CHUNK_USHORT(ChunkType::KeepAliveTimer, mKeepAliveTimer);
// Authentication key // Authentication key
WRITE_CHUNK_BUFFER(ChunkType::AuthenticationKey, mAuthenticateKey); WRITE_CHUNK_BUFFER(ChunkType::AuthenticationKey, mAuthenticateKey);
// Payload // Payload
WRITE_CHUNK_BUFFER(ChunkType::PacketPayload, mBody); WRITE_CHUNK_BUFFER(ChunkType::PacketPayload, mBody);
r.resize(w.offset()); r.resize(w.offset());
w.rewind(); w.skip(4); w.writeUShort((uint16_t)r.size()); w.rewind(); w.skip(4); w.writeUShort((uint16_t)r.size());
return r; return r;
} }

View File

@ -77,6 +77,7 @@ namespace HEP
ByteBuffer mAuthenticateKey; ByteBuffer mAuthenticateKey;
ByteBuffer mBody; ByteBuffer mBody;
VendorId mVendorId; VendorId mVendorId;
uint32_t mBodyOffset = 0;
}; };
} }

View File

@ -13,23 +13,23 @@
NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForEthernet(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination) NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForEthernet(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination)
{ {
PacketData result(packet); PacketData result(packet);
const EthernetHeader* ethernet = reinterpret_cast<const EthernetHeader*>(packet.mData);
// Skip ethernet header const EthernetHeader* ethernet = reinterpret_cast<const EthernetHeader*>(packet.mData);
packet.mData += sizeof(EthernetHeader);
packet.mLength -= sizeof(EthernetHeader);
// See if there is Vlan header // Skip ethernet header
uint16_t proto = 0; packet.mData += sizeof(EthernetHeader);
if (ethernet->mEtherType == 129) packet.mLength -= sizeof(EthernetHeader);
{
const VlanHeader* vlan = reinterpret_cast<const VlanHeader*>(packet.mData); // See if there is Vlan header
packet.mData += sizeof(VlanHeader); uint16_t proto = 0;
packet.mLength -= sizeof(VlanHeader); if (ethernet->mEtherType == 129)
proto = ntohs(vlan->mData); {
} const VlanHeader* vlan = reinterpret_cast<const VlanHeader*>(packet.mData);
packet.mData += sizeof(VlanHeader);
packet.mLength -= sizeof(VlanHeader);
proto = ntohs(vlan->mData);
}
// Skip MPLS headers // Skip MPLS headers
switch (proto) switch (proto)
@ -38,7 +38,7 @@ NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForEthernet(NetworkFrame::Pa
case ETHERTYPE_MPLS_MC: case ETHERTYPE_MPLS_MC:
// Parse MPLS here until marker "bottom of mpls stack" // Parse MPLS here until marker "bottom of mpls stack"
for(bool bottomOfStack = false; !bottomOfStack; for(bool bottomOfStack = false; !bottomOfStack;
bottomOfStack = ((ntohl(*(uint32_t*)(packet.mData - 4)) & MPLS_STACK_MASK) >> MPLS_STACK_SHIFT) != 0) bottomOfStack = ((ntohl(*(uint32_t*)(packet.mData - 4)) & MPLS_STACK_MASK) >> MPLS_STACK_SHIFT) != 0)
{ {
packet.mData += 4; packet.mData += 4;
packet.mLength -=4; packet.mLength -=4;
@ -54,93 +54,93 @@ NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForEthernet(NetworkFrame::Pa
break; break;
} }
const Ip4Header* ip4 = reinterpret_cast<const Ip4Header*>(packet.mData); const Ip4Header* ip4 = reinterpret_cast<const Ip4Header*>(packet.mData);
if (ip4->mProtocol != IPPROTO_UDP && ip4->mProtocol != 0) if (ip4->mProtocol != IPPROTO_UDP && ip4->mProtocol != 0)
return PacketData(); return PacketData();
switch (ip4->version()) switch (ip4->version())
{ {
case 4: case 4:
return GetUdpPayloadForIp4(packet, source, destination); return GetUdpPayloadForIp4(packet, source, destination);
case 6: case 6:
return GetUdpPayloadForIp6(packet, source, destination); return GetUdpPayloadForIp6(packet, source, destination);
default: default:
return PacketData(); return PacketData();
} }
} }
NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForSLL(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination) NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForSLL(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination)
{ {
PacketData result(packet); PacketData result(packet);
if (packet.mLength < 16) if (packet.mLength < 16)
return PacketData(); return PacketData();
const LinuxSllHeader* sll = reinterpret_cast<const LinuxSllHeader*>(packet.mData); const LinuxSllHeader* sll = reinterpret_cast<const LinuxSllHeader*>(packet.mData);
packet.mData += sizeof(LinuxSllHeader); packet.mData += sizeof(LinuxSllHeader);
packet.mLength -= sizeof(LinuxSllHeader); packet.mLength -= sizeof(LinuxSllHeader);
switch (ntohs(sll->mProtocolType)) switch (ntohs(sll->mProtocolType))
{ {
case 0x0800: case 0x0800:
return GetUdpPayloadForIp4(packet, source, destination); return GetUdpPayloadForIp4(packet, source, destination);
case 0x86DD: case 0x86DD:
return GetUdpPayloadForIp6(packet, source, destination); return GetUdpPayloadForIp6(packet, source, destination);
default: default:
return PacketData(); return PacketData();
} }
} }
NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForIp4(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination) NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForIp4(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination)
{ {
PacketData result(packet); PacketData result(packet);
const Ip4Header* ip4 = reinterpret_cast<const Ip4Header*>(packet.mData); const Ip4Header* ip4 = reinterpret_cast<const Ip4Header*>(packet.mData);
if (ip4->mProtocol != IPPROTO_UDP && ip4->mProtocol != 0) if (ip4->mProtocol != IPPROTO_UDP && ip4->mProtocol != 0)
return PacketData(nullptr, 0); return PacketData(nullptr, 0);
result.mData += ip4->headerLength(); result.mData += ip4->headerLength();
result.mLength -= ip4->headerLength(); result.mLength -= ip4->headerLength();
const UdpHeader* udp = reinterpret_cast<const UdpHeader*>(result.mData); const UdpHeader* udp = reinterpret_cast<const UdpHeader*>(result.mData);
result.mData += sizeof(UdpHeader); result.mData += sizeof(UdpHeader);
result.mLength -= sizeof(UdpHeader); result.mLength -= sizeof(UdpHeader);
// Check if UDP payload length is smaller than full packet length. It can be VLAN trailer data - we need to skip it
size_t length = ntohs(udp->mDatagramLength);
if (length - sizeof(UdpHeader) < (size_t)result.mLength)
result.mLength = length - sizeof(UdpHeader);
source.setIp(ip4->mSource); // Check if UDP payload length is smaller than full packet length. It can be VLAN trailer data - we need to skip it
source.setPort(ntohs(udp->mSourcePort)); size_t length = ntohs(udp->mDatagramLength);
if (length - sizeof(UdpHeader) < (size_t)result.mLength)
destination.setIp(ip4->mDestination); result.mLength = length - sizeof(UdpHeader);
destination.setPort(ntohs(udp->mDestinationPort));
return result; source.setIp(ip4->mSource);
source.setPort(ntohs(udp->mSourcePort));
destination.setIp(ip4->mDestination);
destination.setPort(ntohs(udp->mDestinationPort));
return result;
} }
struct Ip6Header struct Ip6Header
{ {
#if __BYTE_ORDER == __LITTLE_ENDIAN #if __BYTE_ORDER == __LITTLE_ENDIAN
uint8_t traffic_class_hi:4, uint8_t traffic_class_hi:4,
version:4; version:4;
uint8_t flow_label_hi:4, uint8_t flow_label_hi:4,
traffic_class_lo:4; traffic_class_lo:4;
uint16_t flow_label_lo; uint16_t flow_label_lo;
#elif __BYTE_ORDER == __BIG_ENDIAN #elif __BYTE_ORDER == __BIG_ENDIAN
uint8_t version:4, uint8_t version:4,
traffic_class_hi:4; traffic_class_hi:4;
uint8_t traffic_class_lo:4, uint8_t traffic_class_lo:4,
flow_label_hi:4; flow_label_hi:4;
uint16_t flow_label_lo; uint16_t flow_label_lo;
#else #else
# error "Please fix endianness defines" # error "Please fix endianness defines"
@ -156,31 +156,31 @@ struct Ip6Header
NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForIp6(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination) NetworkFrame::PacketData NetworkFrame::GetUdpPayloadForIp6(NetworkFrame::PacketData& packet, InternetAddress& source, InternetAddress& destination)
{ {
PacketData result(packet); PacketData result(packet);
const Ip6Header* ip6 = reinterpret_cast<const Ip6Header*>(packet.mData); const Ip6Header* ip6 = reinterpret_cast<const Ip6Header*>(packet.mData);
/*if (ip6->mProtocol != IPPROTO_UDP && ip4->mProtocol != 0) /*if (ip6->mProtocol != IPPROTO_UDP && ip4->mProtocol != 0)
return PacketData(nullptr, 0); return PacketData(nullptr, 0);
*/ */
result.mData += sizeof(Ip6Header); result.mData += sizeof(Ip6Header);
result.mLength -= sizeof(Ip6Header); result.mLength -= sizeof(Ip6Header);
//std::cout << sizeof(Ip6Header) << std::endl; //std::cout << sizeof(Ip6Header) << std::endl;
const UdpHeader* udp = reinterpret_cast<const UdpHeader*>(result.mData); const UdpHeader* udp = reinterpret_cast<const UdpHeader*>(result.mData);
result.mData += sizeof(UdpHeader); result.mData += sizeof(UdpHeader);
result.mLength -= sizeof(UdpHeader); result.mLength -= sizeof(UdpHeader);
/* /*
if (result.mLength != ntohs(udp->mDatagramLength)) if (result.mLength != ntohs(udp->mDatagramLength))
return PacketData(nullptr, 0); return PacketData(nullptr, 0);
*/ */
source.setIp(ip6->src_ip); source.setIp(ip6->src_ip);
source.setPort(ntohs(udp->mSourcePort)); source.setPort(ntohs(udp->mSourcePort));
//std::cout << source.toStdString() << " - "; //std::cout << source.toStdString() << " - ";
destination.setIp(ip6->dst_ip); destination.setIp(ip6->dst_ip);
destination.setPort(ntohs(udp->mDestinationPort)); destination.setPort(ntohs(udp->mDestinationPort));
//std::cout << destination.toStdString() << std::endl; //std::cout << destination.toStdString() << std::endl;
return result; return result;
} }

View File

@ -7,104 +7,104 @@
class NetworkFrame class NetworkFrame
{ {
public: public:
struct PacketData struct PacketData
{ {
const uint8_t* mData; const uint8_t* mData;
int mLength; int mLength;
PacketData(const uint8_t* data, int length) PacketData(const uint8_t* data, int length)
:mData(data), mLength(length) :mData(data), mLength(length)
{} {}
PacketData() PacketData()
:mData(nullptr), mLength(0) :mData(nullptr), mLength(0)
{} {}
}; };
static PacketData GetUdpPayloadForEthernet(PacketData& packet, InternetAddress& source, InternetAddress& destination); static PacketData GetUdpPayloadForEthernet(PacketData& packet, InternetAddress& source, InternetAddress& destination);
static PacketData GetUdpPayloadForIp4(PacketData& packet, InternetAddress& source, InternetAddress& destination); static PacketData GetUdpPayloadForIp4(PacketData& packet, InternetAddress& source, InternetAddress& destination);
static PacketData GetUdpPayloadForIp6(PacketData& packet, InternetAddress& source, InternetAddress& destination); static PacketData GetUdpPayloadForIp6(PacketData& packet, InternetAddress& source, InternetAddress& destination);
static PacketData GetUdpPayloadForSLL(PacketData& packet, InternetAddress& source, InternetAddress& destination); static PacketData GetUdpPayloadForSLL(PacketData& packet, InternetAddress& source, InternetAddress& destination);
struct EthernetHeader struct EthernetHeader
{ {
/* Ethernet addresses are 6 bytes */ /* Ethernet addresses are 6 bytes */
static const int AddressLength = 6; static const int AddressLength = 6;
uint8_t mEtherDHost[AddressLength]; /* Destination host address */ uint8_t mEtherDHost[AddressLength]; /* Destination host address */
uint8_t mEtherSHost[AddressLength]; /* Source host address */ uint8_t mEtherSHost[AddressLength]; /* Source host address */
uint16_t mEtherType; /* IP? ARP? RARP? etc */ uint16_t mEtherType; /* IP? ARP? RARP? etc */
}; };
#if defined(TARGET_WIN) #if defined(TARGET_WIN)
struct /*__attribute__((packed))*/ LinuxSllHeader struct /*__attribute__((packed))*/ LinuxSllHeader
#else #else
struct __attribute__((packed)) LinuxSllHeader struct __attribute__((packed)) LinuxSllHeader
#endif #endif
{ {
uint16_t mPacketType; uint16_t mPacketType;
uint16_t mARPHRD; uint16_t mARPHRD;
uint16_t mAddressLength; uint16_t mAddressLength;
uint64_t mAddress; uint64_t mAddress;
uint16_t mProtocolType; uint16_t mProtocolType;
}; };
struct VlanHeader struct VlanHeader
{ {
uint16_t mMagicId; uint16_t mMagicId;
uint16_t mData; uint16_t mData;
}; };
struct Ip4Header struct Ip4Header
{ {
uint8_t mVhl; /* version << 4 | header length >> 2 */ uint8_t mVhl; /* version << 4 | header length >> 2 */
uint8_t mTos; /* type of service */ uint8_t mTos; /* type of service */
uint16_t mLen; /* total length */ uint16_t mLen; /* total length */
uint16_t mId; /* identification */ uint16_t mId; /* identification */
uint16_t mOffset; /* fragment offset field */ uint16_t mOffset; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */ #define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */ #define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */ #define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
uint8_t mTtl; /* time to live */ uint8_t mTtl; /* time to live */
uint8_t mProtocol; /* protocol */ uint8_t mProtocol; /* protocol */
uint16_t mChecksum; /* checksum */ uint16_t mChecksum; /* checksum */
in_addr mSource, in_addr mSource,
mDestination; /* source and dest address */ mDestination; /* source and dest address */
int headerLength() const int headerLength() const
{
return (mVhl & 0x0f) * 4;
}
int version() const
{
return mVhl >> 4;
}
const in_addr& source4() const { return mSource; }
const in_addr& dest4() const { return mDestination; }
const in6_addr& source6() const { return (const in6_addr&)mSource; }
const in6_addr& dest6() const { return (const in6_addr&)mDestination; }
};
struct UdpHeader
{ {
return (mVhl & 0x0f) * 4; uint16_t mSourcePort; /* source port */
} uint16_t mDestinationPort;
uint16_t mDatagramLength; /* datagram length */
uint16_t mDatagramChecksum; /* datagram checksum */
};
int version() const
struct TcpHeader
{ {
return mVhl >> 4; uint16_t mSourcePort; /* source port */
} uint16_t mDestinationPort; /* destination port */
uint32_t mSeqNo; /* sequence number */
const in_addr& source4() const { return mSource; } uint32_t mAckNo; /* acknowledgement number */
const in_addr& dest4() const { return mDestination; } uint32_t mDataOffset; /* data offset, rsvd */
const in6_addr& source6() const { return (const in6_addr&)mSource; }
const in6_addr& dest6() const { return (const in6_addr&)mDestination; }
};
struct UdpHeader
{
uint16_t mSourcePort; /* source port */
uint16_t mDestinationPort;
uint16_t mDatagramLength; /* datagram length */
uint16_t mDatagramChecksum; /* datagram checksum */
};
struct TcpHeader
{
uint16_t mSourcePort; /* source port */
uint16_t mDestinationPort; /* destination port */
uint32_t mSeqNo; /* sequence number */
uint32_t mAckNo; /* acknowledgement number */
uint32_t mDataOffset; /* data offset, rsvd */
#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4) #define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
uint8_t mFlags; uint8_t mFlags;
#define TH_FIN 0x01 #define TH_FIN 0x01
#define TH_SYN 0x02 #define TH_SYN 0x02
#define TH_RST 0x04 #define TH_RST 0x04
@ -114,10 +114,10 @@ public:
#define TH_ECE 0x40 #define TH_ECE 0x40
#define TH_CWR 0x80 #define TH_CWR 0x80
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR) #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
uint16_t mWindow; /* window */ uint16_t mWindow; /* window */
uint16_t mChecksum; /* checksum */ uint16_t mChecksum; /* checksum */
uint16_t mUrgentPointer; /* urgent pointer */ uint16_t mUrgentPointer; /* urgent pointer */
}; };
}; };
#endif #endif