Skip to content

Commit

Permalink
Add COTP layer (seladb#1146)
Browse files Browse the repository at this point in the history
* create COTP

* create COTP tests

* Add COTP to README.md

* small changes

* add override

* add comment to cotphdr

* add comment to cotp

* fix type

* create COTP

* create COTP tests

* small changes

* add override

* add comment to cotphdr

* add comment to cotp

* fix type

* Changed COTP value

* Renaming to camel case (in parameters, constructor, ...)

* Remove unnecessary elements, modify to check the values (type, length), modify the values in tests

* add explicit to constructor and override to getOsiModellLayer

* Update README.md with COTP

* create COTP

* create COTP tests

* Add COTP to README.md

* small changes

* add override

* add comment to cotphdr

* add comment to cotp

* fix type

* create COTP

* create COTP tests

* small changes

* add override

* add comment to cotphdr

* add comment to cotp

* fix type

* Changed COTP value

* Renaming to camel case (in parameters, constructor, ...)

* Remove unnecessary elements, modify to check the values (type, length), modify the values in tests

* add explicit to constructor and override to getOsiModellLayer

* Update README.md with COTP

* create COTP

* create COTP tests

* create COTP

* Changed COTP value

* Remove unnecessary elements, modify to check the values (type, length), modify the values in tests

* add explicit to constructor and override to getOsiModellLayer

* add back new lines at the end of the files

* added new lines, renaming and delete unnecessary things.

* remove static keyword

* remove static keyword

* static keyword

* delete unused parameters from TpktLayer.cpp

* delete unused variables

* modify test

* rename cotp

* rename tpkt_cotp files

* modify comment

* modify test

---------

Co-authored-by: Vörös Vivien <[email protected]>
  • Loading branch information
wivien19 and Vörös Vivien authored Jul 19, 2023
1 parent 694c65d commit 886dedc
Show file tree
Hide file tree
Showing 14 changed files with 262 additions and 23 deletions.
2 changes: 2 additions & 0 deletions Packet++/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ add_library(
$<TARGET_OBJECTS:hash-library>
src/ArpLayer.cpp
src/BgpLayer.cpp
src/CotpLayer.cpp
src/DhcpLayer.cpp
src/DhcpV6Layer.cpp
src/DnsLayer.cpp
Expand Down Expand Up @@ -64,6 +65,7 @@ add_library(
set(public_headers
header/ArpLayer.h
header/BgpLayer.h
header/CotpLayer.h
header/DhcpLayer.h
header/DhcpV6Layer.h
header/DnsLayerEnums.h
Expand Down
120 changes: 120 additions & 0 deletions Packet++/header/CotpLayer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#ifndef PCAPPLUSPLUS_COTPLAYER_H
#define PCAPPLUSPLUS_COTPLAYER_H

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

namespace pcpp
{

/**
* @struct cotphdr
* Represents a COTP protocol header
*/
#pragma pack(push, 1)
typedef struct
{
/** length */
uint8_t length;
/** PDU type identifier */
uint8_t pduType ;
/** TPDU number sequence*/
uint8_t tpduNumber;
} cotphdr;
#pragma pack(pop)

/**
* @class CotpLayer
* Represents a COTP (Connection Oriented Transport Protocol)
*/
class CotpLayer : public Layer
{
public:
/**
* 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 cotphdr)
* @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
*/
CotpLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
: Layer(data, dataLen, prevLayer, packet)
{
m_Protocol = COTP;
}

/**
* A constructor that allocates a new COTP header
* @param[in] tpduNumber Protocol TPDU number
*/
explicit CotpLayer(uint8_t tpduNumber);

virtual ~CotpLayer() {}

/**
* @return COTP length
*/
uint8_t getLength() const;

/**
* @return COTP PDU type
*/
uint8_t getPduType() const;

/**
* @return COTP TPDU number
*/
uint8_t getTpduNumber() const;

/**
* @return Size of @ref cotphdr
*/
size_t getHeaderLen() const override { return sizeof(cotphdr); }

/**
* Set the value of the length
* @param[in] length The value of the length
*/
void setLength(uint8_t length) const;

/**
* Set the value of the version
* @param[in] pduType The number of the PDU type
*/
void setPduType(uint8_t pduType) const;

/**
* Set the value of the version
* @param[in] tpduNumber The value of the TPDU number
*/
void setTpduNumber(uint8_t tpduNumber) const;

/**
* Does nothing for this layer
*/
void computeCalculateFields() override {}

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

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

std::string toString() const override;

OsiModelLayer getOsiModelLayer() const override { return OsiModelTransportLayer; }

private:
cotphdr *getCotpHeader() const { return (cotphdr *)m_Data; }
};

} // namespace pcpp

#endif // PCAPPLUSPLUS_COTPLAYER_H
5 changes: 5 additions & 0 deletions Packet++/header/ProtocolType.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,11 @@ namespace pcpp
*/
const ProtocolType VRRPv3 = 0x2000000000000;

/**
* COTP protocol
*/
const ProtocolType COTP = 0x900000000000;

/**
* An enum representing OSI model layers
*/
Expand Down
2 changes: 1 addition & 1 deletion Packet++/header/TpktLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,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 COTP protocol or generic payload (PayloadLayer)
*/
void parseNextLayer() override;

Expand Down
60 changes: 60 additions & 0 deletions Packet++/src/CotpLayer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include "../header/CotpLayer.h"
#include "EndianPortable.h"
#include <PayloadLayer.h>
#include <cstring>
#include <iostream>
#include <sstream>

namespace pcpp
{

pcpp::CotpLayer::CotpLayer(uint8_t tpduNumber)
{
const size_t headerLen = sizeof(cotphdr);
m_DataLen = headerLen;
m_Data = new uint8_t[headerLen];
memset(m_Data, 0, headerLen);
cotphdr *cotpHdr = (cotphdr *)m_Data;
cotpHdr->length = 0x02;
cotpHdr->pduType = 0x0f;
cotpHdr->tpduNumber = tpduNumber;
m_Protocol = COTP;
}

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

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

uint8_t CotpLayer::getPduType() const { return getCotpHeader()->pduType; }

uint8_t CotpLayer::getTpduNumber() const { return getCotpHeader()->tpduNumber; }

void CotpLayer::setLength(uint8_t length) const { getCotpHeader()->length = length; }

void CotpLayer::setPduType(uint8_t pduType) const { getCotpHeader()->pduType = pduType; }

void CotpLayer::setTpduNumber(uint8_t tpduNumber) const { getCotpHeader()->tpduNumber = tpduNumber; }

bool CotpLayer::isDataValid(const uint8_t *data, size_t dataSize)
{
if (!data || dataSize < sizeof(cotphdr))
return false;

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

void CotpLayer::parseNextLayer()
{
size_t headerLen = getHeaderLen();
if (m_DataLen <= headerLen)
return;

uint8_t *payload = m_Data + headerLen;
size_t payloadLen = m_DataLen - headerLen;

m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet);
}
} // namespace pcpp
7 changes: 6 additions & 1 deletion Packet++/src/TpktLayer.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "TpktLayer.h"
#include "EndianPortable.h"
#include "TcpLayer.h"
#include "CotpLayer.h"
#include "PayloadLayer.h"
#include <iostream>
#include <sstream>
Expand Down Expand Up @@ -48,7 +49,11 @@ namespace pcpp

uint8_t *payload = m_Data + headerLen;
size_t payloadLen = m_DataLen - headerLen;
m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet);

if (CotpLayer::isDataValid(payload, payloadLen)) {
m_NextLayer = new CotpLayer(payload, payloadLen, this, m_Packet);
} else
m_NextLayer = new PayloadLayer(payload, payloadLen, this, m_Packet);
}

} // namespace pcpp
41 changes: 21 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,35 +230,36 @@ PcapPlusPlus currently supports parsing, editing and creation of packets of the
### Transport Layer (L4)
24. GTP (v1)
25. IPSec AH & ESP - parsing only (no editing capabilities)
26. TCP
27. TPKT
28. UDP
24. COTP
25. GTP (v1)
26. IPSec AH & ESP - parsing only (no editing capabilities)
27. TCP
28. TPKT
29. UDP
### Session Layer (L5)
29. SDP
30. SIP
30. SDP
31. SIP
### Presentation Layer (L6)
31. SSL/TLS - parsing only (no editing capabilities)
32. SSL/TLS - parsing only (no editing capabilities)
### Application Layer (L7)
32. BGP (v4)
33. DHCP
34. DHCPv6
35. DNS
36. FTP
37. HTTP headers (request & response)
38. NTP (v3, v4)
39. Radius
40. SOME/IP
41. SSH - parsing only (no editing capabilities)
42. Telnet - parsing only (no editing capabilities)
43. Generic payload
33. BGP (v4)
34. DHCP
35. DHCPv6
36. DNS
37. FTP
38. HTTP headers (request & response)
39. NTP (v3, v4)
40. Radius
41. SOME/IP
42. SSH - parsing only (no editing capabilities)
43. Telnet - parsing only (no editing capabilities)
44. Generic payload
## DPDK And PF_RING Support
Expand Down
1 change: 1 addition & 0 deletions Tests/Packet++Test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ add_executable(
Packet++Test
main.cpp
Tests/BgpTests.cpp
Tests/CotpTests.cpp
Tests/DhcpTests.cpp
Tests/DhcpV6Tests.cpp
Tests/DnsTests.cpp
Expand Down
File renamed without changes.
File renamed without changes.
3 changes: 3 additions & 0 deletions Tests/Packet++Test/TestDefinition.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,6 @@ PTF_TEST_CASE(TpktLayerTest);
// Implemented in VrrpTests.cpp
PTF_TEST_CASE(VrrpParsingTest);
PTF_TEST_CASE(VrrpCreateAndEditTest);

//Implemented in CotpTests.cpp
PTF_TEST_CASE(CotpLayerTest);
40 changes: 40 additions & 0 deletions Tests/Packet++Test/Tests/CotpTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "../TestDefinition.h"
#include "../Utils/TestUtils.h"
#include "CotpLayer.h"
#include "Packet.h"
#include "SystemUtils.h"

using namespace std;

PTF_TEST_CASE(CotpLayerTest)
{
timeval time;
gettimeofday(&time, nullptr);

READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/tpkt_cotp.dat");

pcpp::Packet cotpPacket(&rawPacket1);
PTF_ASSERT_TRUE(cotpPacket.isPacketOfType(pcpp::COTP));
auto cotpLayer = cotpPacket.getLayerOfType<pcpp::CotpLayer>();
PTF_ASSERT_NOT_NULL(cotpLayer);
PTF_ASSERT_EQUAL(cotpLayer->getNextLayer()->getProtocol(), pcpp::GenericPayload, enum);
PTF_ASSERT_EQUAL(cotpLayer->getHeaderLen(), 3);
PTF_ASSERT_EQUAL(cotpLayer->getLength(), 0x02);
PTF_ASSERT_EQUAL(cotpLayer->getPduType(), 0xf0);
PTF_ASSERT_EQUAL(cotpLayer->getTpduNumber(), 0x80);
PTF_ASSERT_EQUAL(cotpLayer->toString(), "Cotp Layer");

pcpp::CotpLayer newCotpPacket(120);
PTF_ASSERT_EQUAL(newCotpPacket.getHeaderLen(), 3);
PTF_ASSERT_EQUAL(newCotpPacket.getLength(), 0x02);
PTF_ASSERT_EQUAL(newCotpPacket.getPduType(), 0x0f);
PTF_ASSERT_EQUAL(newCotpPacket.getTpduNumber(), 0x78);

newCotpPacket.setLength((uint8_t)4);
newCotpPacket.setPduType((uint8_t)210);
newCotpPacket.setTpduNumber((uint8_t)125);
PTF_ASSERT_EQUAL(newCotpPacket.getLength(), 0x04);
PTF_ASSERT_EQUAL(newCotpPacket.getPduType(), 0xd2);
PTF_ASSERT_EQUAL(newCotpPacket.getTpduNumber(), 0x7d);

} // CotpLayerTest
2 changes: 1 addition & 1 deletion Tests/Packet++Test/Tests/TpktTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ PTF_TEST_CASE(TpktLayerTest)
timeval time;
gettimeofday(&time, nullptr);

READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/tpkt.dat");
READ_FILE_AND_CREATE_PACKET(1, "PacketExamples/tpkt_cotp.dat");

pcpp::Packet TpktPacketNoOptions(&rawPacket1);
PTF_ASSERT_TRUE(TpktPacketNoOptions.isPacketOfType(pcpp::TPKT));
Expand Down
2 changes: 2 additions & 0 deletions Tests/Packet++Test/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,5 +309,7 @@ int main(int argc, char* argv[])
PTF_RUN_TEST(VrrpParsingTest, "vrrp");
PTF_RUN_TEST(VrrpCreateAndEditTest, "vrrp");

PTF_RUN_TEST(CotpLayerTest, "cotp");

PTF_END_RUNNING_TESTS;
}

0 comments on commit 886dedc

Please sign in to comment.