Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create S7COMM protocol and tests #1185

Merged
merged 32 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
6791f63
create S7COMM protocol and tests
wivien19 Aug 21, 2023
17c1e4e
add missing override to toString
wivien19 Aug 21, 2023
0bdb8d3
change null to nullptr
wivien19 Aug 21, 2023
4482c6a
systemutils
wivien19 Aug 21, 2023
2ba6f6d
imports in test
wivien19 Aug 21, 2023
d85e738
edit the value of the S7COMM
wivien19 Aug 22, 2023
81d4434
modify toString and add test
wivien19 Aug 22, 2023
f34c2cf
Merge branch 'dev' into S7COMM
wivien19 Sep 5, 2023
46706e9
modify small changes
wivien19 Sep 5, 2023
c8d14f8
Merge remote-tracking branch 'origin/S7COMM' into S7COMM
wivien19 Sep 16, 2023
d9efe40
S7COMM Ack-data header modify and test
wivien19 Sep 18, 2023
32c7558
Merge branch 'dev' into S7COMM
seladb Sep 22, 2023
75238d4
Modify GetHeaderLen
wivien19 Sep 22, 2023
c2f1f2c
Parameter
wivien19 Sep 22, 2023
aed4a41
Parameter length
wivien19 Sep 25, 2023
a5f1533
Parameter length
wivien19 Sep 25, 2023
9ffc140
Merge remote-tracking branch 'origin/S7COMM' into S7COMM
wivien19 Sep 26, 2023
6502dcb
Fix `getParameter()`
seladb Oct 3, 2023
9b76c38
Merge branch 'dev' into S7COMM
seladb Oct 3, 2023
4cd7d02
add error pcap and small modify
wivien19 Oct 11, 2023
0dc3f4d
Merge branch 'dev' into S7COMM
wivien19 Oct 15, 2023
89e04f4
renaming, remove unneccessary elements
wivien19 Oct 18, 2023
a4a30d5
Few fixes
seladb Oct 20, 2023
8e2636f
Few more fixes
seladb Oct 20, 2023
2f01981
Merge branch 'dev' into S7COMM
seladb Oct 20, 2023
43ecad1
renaming, small fixes
wivien19 Oct 24, 2023
f1153d3
Remove spaces
seladb Oct 31, 2023
f702af7
renaming, remove unneccessary element
wivien19 Oct 31, 2023
50640bb
modify the header length and the toString method
wivien19 Nov 3, 2023
e738133
Few more fixes
seladb Nov 6, 2023
3972220
Merge branch 'dev' into S7COMM
seladb Nov 6, 2023
9564367
Add to README
seladb Nov 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Packet++/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ add_library(
src/PPPoELayer.cpp
src/RadiusLayer.cpp
src/RawPacket.cpp
src/S7CommLayer.cpp
src/SdpLayer.cpp
src/SingleCommandTextProtocol.cpp
src/SipLayer.cpp
Expand Down Expand Up @@ -103,6 +104,7 @@ set(public_headers
header/ProtocolType.h
header/RadiusLayer.h
header/RawPacket.h
header/S7CommLayer.h
header/SdpLayer.h
header/SingleCommandTextProtocol.h
header/SipLayer.h
Expand Down
2 changes: 1 addition & 1 deletion Packet++/header/CotpLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ namespace pcpp
void computeCalculateFields() override {}

/**
* Currently parses the rest of the packet as a generic payload (PayloadLayer)
* Currently parses the rest of the packet as a S7COMM or generic payload (PayloadLayer)
*/
void parseNextLayer() override;

Expand Down
5 changes: 5 additions & 0 deletions Packet++/header/ProtocolType.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,11 @@ namespace pcpp
*/
const ProtocolType SLL2 = 0x8000000000000;

/**
* S7COMM protocol
*/
const ProtocolType S7COMM = 0x10000000000000;

/**
* An enum representing OSI model layers
*/
Expand Down
220 changes: 220 additions & 0 deletions Packet++/header/S7CommLayer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
#ifndef PACKETPP_S7COMM_LAYER
#define PACKETPP_S7COMM_LAYER

#include "EthLayer.h"
#include "Layer.h"

namespace pcpp
{
/**
* @struct s7commhdr
* Represents a S7COMM protocol header
*/
#pragma pack(push, 1)
typedef struct
{
/** protocol id */
uint8_t protocolId;
/** message type */
uint8_t msgType;
/** redundancy identification (reserved) */
uint16_t reserved;
/** protocol data unit reference */
uint16_t pduRef;
/** parameter length */
uint16_t paramLength;
/** data length */
uint16_t dataLength;
} s7commhdr;
#pragma pack(pop)

/**
* @struct s7comm_ack_data_hdr
* Represents a S7COMM protocol header with Ack-Data header
*/
#pragma pack(push, 1)
struct s7comm_ack_data_hdr : s7commhdr
{
/** error class */
uint8_t errorClass;
/** error code */
uint8_t errorCode;
};
#pragma pack(pop)

/**
* @class S7CommParameter
* Represents a S7COMM (S7 Communication) protocol Parameter
*/
class S7CommParameter
{
friend class S7CommLayer;

public:
S7CommParameter() {}

virtual ~S7CommParameter() {}

/**
* @return The data of the Parameter
*/
uint8_t *getData() const { return m_Data; }
/**
* @return The length of the Parameter data
*/
size_t getDataLength() const { return m_DataLen; }

private:
S7CommParameter(uint8_t *data, size_t dataLen) : m_Data(data), m_DataLen(dataLen) {}
uint8_t *m_Data;
size_t m_DataLen;
};
/**
* @class S7CommLayer
* Represents a S7COMM (S7 Communication) protocol
*/
class S7CommLayer : public Layer
{
public:
/**
* A constructor that allocates a new S7comm header
* @param[in] msgType The general type of the message
* @param[in] pduRef Link responses to their requests
* @param[in] paramLength The length of the parameter field
* @param[in] dataLength The length of the data field
* @param[in] errorClass The value of the error class
* @param[in] errorCode The value of the error code
*/
S7CommLayer(uint8_t msgType, uint16_t pduRef, uint16_t paramLength, uint16_t dataLength, uint8_t errorClass = 0,
uint8_t errorCode = 0);

/**
* A constructor that creates the layer from an existing packet raw data
* @param[in] data A pointer to the raw data (will be casted to @ref s7commhdr)
* @param[in] dataLen Size of the data in bytes
* @param[in] prevLayer A pointer to the previous layer
* @param[in] packet A pointer to the Packet instance where layer will be stored in
*/
S7CommLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
: Layer(data, dataLen, prevLayer, packet)
{
m_Protocol = S7COMM;
m_Parameter = nullptr;
}

virtual ~S7CommLayer()
{
if (m_Parameter)
delete m_Parameter;
}

/**
* @return S7comm protocol id
*/
uint8_t getProtocolId() const;

/**
* @return S7comm message type
*/
uint8_t getMsgType() const;

/**
* @return S7comm PDU ref
*/
uint16_t getPduRef() const;

/**
* @return S7comm parameter length
*/
uint16_t getParamLength() const;

/**
* @return S7comm data length
*/
uint16_t getDataLength() const;

/**
* @return S7comm error code
*/
uint8_t getErrorCode() const;

/**
* @return S7comm error class
*/
uint8_t getErrorClass() const;

/**
* @return S7comm parameter
*/
const S7CommParameter *getParameter();

/**
* Set the value of the message type
* @param[in] msgType The value of the message type
*/
void setMsgType(uint8_t msgType) const;

/**
* Set the value of the PDU ref
* @param[in] pduRef The value of the PDU ref
*/
void setPduRef(uint16_t pduRef) const;

/**
* Set the value of the error code
* @param[in] errorCode The value of the error code
*/
void setErrorCode(uint8_t errorCode) const;
/**
* Set the value of the error class
* @param[in] errorClass The value of the error class
*/
void setErrorClass(uint8_t errorClass) const;

/**
* @return Size of S7CommLayer
*/
size_t getHeaderLen() const override { return m_DataLen; }

/**
* Does nothing for this layer (S7CommLayer is always last)
*/
void computeCalculateFields() override {}

/**
* Does nothing for this layer (S7CommLayer is always last)
*/
void parseNextLayer() override {}

/**
* A static method that takes a byte array and detects whether it is a S7COMM
* @param[in] data A byte array
* @param[in] dataSize The byte array size (in bytes)
* @return True if the data looks like a valid S7COMM layer
*/
static bool isDataValid(const uint8_t *data, size_t dataSize);

std::string toString() const override;

OsiModelLayer getOsiModelLayer() const override { return OsiModelApplicationLayer; }

private:
s7commhdr *getS7commHeader() const { return (s7commhdr *)m_Data; }

s7comm_ack_data_hdr *getS7commAckDataHeader() const
{
if (getS7commHeader()->msgType == 0x03)
{
return (s7comm_ack_data_hdr *)m_Data;
}
return nullptr;
}

size_t getS7commHeaderLength() const;

S7CommParameter *m_Parameter;
};

} // namespace pcpp

#endif // PACKETPP_S7COMM_LAYER
13 changes: 7 additions & 6 deletions Packet++/src/CotpLayer.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "../header/CotpLayer.h"
#include "EndianPortable.h"
#include "S7CommLayer.h"
#include <PayloadLayer.h>
#include <cstring>
#include <iostream>
Expand All @@ -21,10 +22,7 @@ namespace pcpp
m_Protocol = COTP;
}

std::string CotpLayer::toString() const
{
return "Cotp Layer";
}
std::string CotpLayer::toString() const { return "Cotp Layer"; }

uint8_t CotpLayer::getLength() const { return getCotpHeader()->length; }

Expand All @@ -43,7 +41,7 @@ namespace pcpp
if (!data || dataSize < sizeof(cotphdr))
return false;

return data[1] == 0xf0 && data[0] == 2;
return data[1] == 0xf0 && data[0] == 2;
}

void CotpLayer::parseNextLayer()
Expand All @@ -55,6 +53,9 @@ namespace pcpp
uint8_t *payload = m_Data + headerLen;
size_t payloadLen = m_DataLen - headerLen;

m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet);
if (S7CommLayer::isDataValid(payload, payloadLen))
m_NextLayer = new S7CommLayer(payload, payloadLen, this, m_Packet);
else
m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet);
}
} // namespace pcpp
Loading