-
Notifications
You must be signed in to change notification settings - Fork 674
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
308 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
#ifndef PCAPPLUSPLUS_S7COMMLAYER_H | ||
#define PCAPPLUSPLUS_S7COMMLAYER_H | ||
|
||
#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 protocol_id; | ||
/** message type */ | ||
uint8_t msg_type; | ||
/** redundancy identification (reserved) */ | ||
uint16_t reserved; | ||
/** protocol data unit reference */ | ||
uint16_t pdu_ref; | ||
/** parameter length */ | ||
uint16_t param_length; | ||
/** data length */ | ||
uint16_t data_length; | ||
} s7commhdr; | ||
#pragma pack(pop) | ||
|
||
/** | ||
* @class S7commLayer | ||
* Represents a S7COMM (S7 Communication7) protocol | ||
*/ | ||
class S7commLayer : public Layer | ||
{ | ||
public: | ||
/** | ||
* A constructor that allocates a new S7comm header | ||
* @param[in] msg_type The general type of the message | ||
* @param[in] pdu_ref Link responses to their requests | ||
* @param[in] param_length The length of the parameter field | ||
* @param[in] data_length The length of the data field | ||
*/ | ||
S7commLayer(uint8_t msg_type, uint16_t pdu_ref, uint16_t param_length, uint16_t data_length); | ||
|
||
/** | ||
* 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; | ||
} | ||
|
||
virtual ~S7commLayer() {} | ||
|
||
/** | ||
* @return S7comm protocol id | ||
*/ | ||
uint8_t getProtocolId() const; | ||
|
||
/** | ||
* @return S7comm message type | ||
*/ | ||
uint8_t getMsgType() const; | ||
|
||
/** | ||
* @return S7comm reserved | ||
*/ | ||
uint16_t getReserved() 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; | ||
|
||
/** | ||
* Set the value of the message type | ||
* @param[in] msg_type The value of the message type | ||
*/ | ||
void setMsgType(uint8_t msg_type) const; | ||
|
||
/** | ||
* Set the value of the PDU ref | ||
* @param[in] pdu_ref The value of the PDU ref | ||
*/ | ||
void setPduRef(uint16_t pdu_ref) const; | ||
|
||
/** | ||
* Set the value of the parameter length | ||
* @param[in] param_length The value of the parameter length | ||
*/ | ||
void setParamLength(uint16_t param_length) const; | ||
|
||
/** | ||
* Set the value of the data length | ||
* @param[in] data_length The value of the data length | ||
*/ | ||
void setDataLength(uint16_t data_length) const; | ||
|
||
/** | ||
* @return Size of @ref s7commhdr | ||
*/ | ||
size_t getHeaderLen() const override { return sizeof(s7commhdr); } | ||
|
||
/** | ||
* Does nothing for this layer | ||
*/ | ||
void computeCalculateFields() override {} | ||
|
||
/** | ||
* Does nothing for this layer | ||
*/ | ||
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; | ||
|
||
OsiModelLayer getOsiModelLayer() const override { return OsiModelApplicationLayer; } | ||
|
||
|
||
private: | ||
s7commhdr *getS7commHeader() const { return (s7commhdr *)m_Data; } | ||
}; | ||
|
||
} // namespace pcpp | ||
#endif // PCAPPLUSPLUS_S7COMMLAYER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
#include "EndianPortable.h" | ||
#include "TpktLayer.h" | ||
|
||
#include <iostream> | ||
#include "TcpLayer.h" | ||
#include "S7commLayer.h" | ||
|
||
#include <cstring> | ||
#include <sstream> | ||
|
||
namespace pcpp { | ||
|
||
S7commLayer::S7commLayer(uint8_t msg_type, uint16_t pdu_ref, | ||
uint16_t param_length, uint16_t data_length) { | ||
const size_t headerLen = sizeof(s7commhdr); | ||
m_DataLen = headerLen; | ||
m_Data = new uint8_t[headerLen]; | ||
memset(m_Data, 0, headerLen); | ||
s7commhdr *s7commHdr = (s7commhdr *) m_Data; | ||
s7commHdr->protocol_id = 0x32; | ||
s7commHdr->msg_type = msg_type; | ||
s7commHdr->reserved = 0x0000; | ||
s7commHdr->pdu_ref = htobe16(pdu_ref); | ||
s7commHdr->param_length = htobe16(param_length); | ||
s7commHdr->data_length = htobe16(data_length); | ||
m_Protocol = S7COMM; | ||
} | ||
|
||
std::string S7commLayer::toString() const { | ||
std::ostringstream msgTypeStream; | ||
msgTypeStream << getMsgType(); | ||
std::ostringstream pduRefStream; | ||
pduRefStream << getPduRef(); | ||
std::ostringstream paramLengthStream; | ||
paramLengthStream << getParamLength(); | ||
std::ostringstream dataLengthStream; | ||
dataLengthStream << getDataLength(); | ||
|
||
return "S7comm Layer, msg_type: " + msgTypeStream.str() + | ||
", pdu_ref: " + pduRefStream.str() + | ||
", param_length: " + paramLengthStream.str() + | ||
", data_length: " + dataLengthStream.str(); | ||
|
||
} | ||
|
||
bool S7commLayer::isDataValid(const uint8_t *data, size_t dataSize) | ||
{ | ||
if (!data || dataSize < sizeof(s7commhdr)) | ||
return false; | ||
|
||
return data[0] == 0x32; | ||
} | ||
|
||
uint8_t S7commLayer::getProtocolId() const { | ||
return getS7commHeader()->protocol_id; | ||
} | ||
|
||
uint8_t S7commLayer::getMsgType() const { | ||
return getS7commHeader()->msg_type; | ||
} | ||
|
||
uint16_t S7commLayer::getReserved() const { | ||
return htobe16(getS7commHeader()->reserved); | ||
} | ||
|
||
uint16_t S7commLayer::getParamLength() const { | ||
return htobe16(getS7commHeader()->param_length); | ||
} | ||
|
||
uint16_t S7commLayer::getPduRef() const { | ||
return htobe16(getS7commHeader()->pdu_ref);; | ||
} | ||
|
||
uint16_t S7commLayer::getDataLength() const { | ||
return htobe16(getS7commHeader()->data_length); | ||
} | ||
|
||
void S7commLayer::setMsgType(uint8_t msg_type) const { | ||
getS7commHeader()->msg_type = msg_type; | ||
} | ||
|
||
void S7commLayer::setParamLength(uint16_t param_length) const { | ||
getS7commHeader()->param_length = htobe16(param_length); | ||
} | ||
|
||
void S7commLayer::setPduRef(uint16_t pdu_ref) const { | ||
getS7commHeader()->pdu_ref = htobe16(pdu_ref); | ||
} | ||
|
||
void S7commLayer::setDataLength(uint16_t data_length) const { | ||
getS7commHeader()->data_length = htobe16(data_length); | ||
} | ||
} // namespace pcpp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
005056b837d1000e8cd0f9cb0800450001190fc400001e0676970a4900d30a4900200066f0480072171153f0fa9950181000bc050000030000f102f08032070000fd0b000c00d4000112081284010100000000ff0900d000a000000014000a4302ff68c70000000814771421090815333765641381fe64c77200000814771421090815333765544301ff46c7720000081477142109081533375274430eff23000000000000000021073117382880074546ff32c0c08ffe0000000021073117382409174300fff3000000000000000021073117382409176522ff030000000100018ffe21073117382409174580fff200000002000000002107302334535946494eff8fc00000000000000021073023345359264302ff68c7000000001477142104271604011663 |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#include "../TestDefinition.h" | ||
#include "../Utils/TestUtils.h" | ||
#include "EndianPortable.h" | ||
#include "Packet.h" | ||
#include "S7commLayer.h" | ||
#include <stdio.h> | ||
|
||
PTF_TEST_CASE(S7commLayerTest) { | ||
timeval time; | ||
gettimeofday(&time, NULL); | ||
|
||
READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/S7comm.dat"); | ||
|
||
pcpp::Packet S7commLayerTest(&rawPacket1); | ||
PTF_ASSERT_TRUE(S7commLayerTest.isPacketOfType(pcpp::S7COMM)); | ||
auto *s7commLayer = S7commLayerTest.getLayerOfType<pcpp::S7commLayer>(); | ||
PTF_ASSERT_NOT_NULL(s7commLayer); | ||
|
||
PTF_ASSERT_EQUAL(s7commLayer->getProtocolId(), 0x32); | ||
PTF_ASSERT_EQUAL(s7commLayer->getMsgType(), 0x07); | ||
PTF_ASSERT_EQUAL(s7commLayer->getReserved(), htobe16(0)); | ||
PTF_ASSERT_EQUAL(s7commLayer->getPduRef(), 0xfd0b); | ||
PTF_ASSERT_EQUAL(s7commLayer->getParamLength(), 12); | ||
PTF_ASSERT_EQUAL(s7commLayer->getDataLength(), 212); | ||
|
||
pcpp::S7commLayer newS7commPacket(0x09, 0xfd0c, 13, 213); | ||
|
||
PTF_ASSERT_EQUAL(newS7commPacket.getMsgType(), 0x09); | ||
PTF_ASSERT_EQUAL(newS7commPacket.getPduRef(), 0xfd0c); | ||
PTF_ASSERT_EQUAL(newS7commPacket.getParamLength(), 13); | ||
PTF_ASSERT_EQUAL(newS7commPacket.getDataLength(), 213); | ||
|
||
|
||
newS7commPacket.setMsgType(0x06); | ||
newS7commPacket.setPduRef(0xfd0a); | ||
newS7commPacket.setParamLength(15); | ||
newS7commPacket.setDataLength(215); | ||
|
||
PTF_ASSERT_EQUAL(newS7commPacket.getMsgType(), 0x06); | ||
PTF_ASSERT_EQUAL(newS7commPacket.getPduRef(), 0xfd0a); | ||
PTF_ASSERT_EQUAL(newS7commPacket.getParamLength(), 15); | ||
PTF_ASSERT_EQUAL(newS7commPacket.getDataLength(), 215); | ||
|
||
} // S7commLayerTest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters