/src/PcapPlusPlus/Packet++/src/S7CommLayer.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | #include "EndianPortable.h" |
2 | | |
3 | | #include "S7CommLayer.h" |
4 | | #include <iostream> |
5 | | #include <cstring> |
6 | | #include <sstream> |
7 | | |
8 | | namespace pcpp |
9 | | { |
10 | | |
11 | | S7CommLayer::S7CommLayer(uint8_t msgType, uint16_t pduRef, uint16_t paramLength, uint16_t dataLength, |
12 | | uint8_t errorClass, uint8_t errorCode) |
13 | 0 | { |
14 | 0 | size_t basicHeaderLen = msgType == 0x03 ? sizeof(s7comm_ack_data_hdr) : sizeof(s7commhdr); |
15 | 0 | size_t headerLen = basicHeaderLen + paramLength + dataLength; |
16 | 0 | m_DataLen = headerLen; |
17 | 0 | m_Data = new uint8_t[headerLen]; |
18 | 0 | memset(m_Data, 0, headerLen); |
19 | |
|
20 | 0 | if (msgType == 0x03) |
21 | 0 | { |
22 | 0 | auto* ack_d = (s7comm_ack_data_hdr*)m_Data; |
23 | 0 | ack_d->protocolId = 0x32; |
24 | 0 | ack_d->msgType = msgType; |
25 | 0 | ack_d->reserved = 0x0000; |
26 | 0 | ack_d->pduRef = htobe16(pduRef); |
27 | 0 | ack_d->paramLength = htobe16(paramLength); |
28 | 0 | ack_d->dataLength = htobe16(dataLength); |
29 | 0 | ack_d->errorClass = errorClass; |
30 | 0 | ack_d->errorCode = errorCode; |
31 | 0 | } |
32 | 0 | else |
33 | 0 | { |
34 | 0 | auto* s7commHdr = (s7commhdr*)m_Data; |
35 | 0 | s7commHdr->protocolId = 0x32; |
36 | 0 | s7commHdr->msgType = msgType; |
37 | 0 | s7commHdr->reserved = 0x0000; |
38 | 0 | s7commHdr->pduRef = htobe16(pduRef); |
39 | 0 | s7commHdr->paramLength = htobe16(paramLength); |
40 | 0 | s7commHdr->dataLength = htobe16(dataLength); |
41 | 0 | } |
42 | |
|
43 | 0 | m_Parameter = nullptr; |
44 | 0 | m_Protocol = S7COMM; |
45 | 0 | } |
46 | | |
47 | | std::string S7CommLayer::toString() const |
48 | 0 | { |
49 | 0 | std::ostringstream str; |
50 | 0 | str << "S7Comm Layer, "; |
51 | |
|
52 | 0 | switch (getS7commHeader()->msgType) |
53 | 0 | { |
54 | 0 | case 0x01: |
55 | 0 | str << "Job Request"; |
56 | 0 | break; |
57 | 0 | case 0x02: |
58 | 0 | str << "Ack"; |
59 | 0 | break; |
60 | 0 | case 0x03: |
61 | 0 | str << "Ack-Data"; |
62 | 0 | break; |
63 | 0 | case 0x07: |
64 | 0 | str << "Userdata"; |
65 | 0 | break; |
66 | 0 | default: |
67 | 0 | str << "Unknown message"; |
68 | 0 | } |
69 | | |
70 | 0 | return str.str(); |
71 | 0 | } |
72 | | |
73 | | bool S7CommLayer::isDataValid(const uint8_t* data, size_t dataSize) |
74 | 0 | { |
75 | 0 | if (!data || dataSize < sizeof(s7commhdr)) |
76 | 0 | return false; |
77 | | |
78 | 0 | return data[0] == 0x32; |
79 | 0 | } |
80 | | |
81 | | uint8_t S7CommLayer::getProtocolId() const |
82 | 0 | { |
83 | 0 | return getS7commHeader()->protocolId; |
84 | 0 | } |
85 | | |
86 | | uint8_t S7CommLayer::getMsgType() const |
87 | 0 | { |
88 | 0 | return getS7commHeader()->msgType; |
89 | 0 | } |
90 | | |
91 | | uint16_t S7CommLayer::getParamLength() const |
92 | 0 | { |
93 | 0 | return be16toh(getS7commHeader()->paramLength); |
94 | 0 | } |
95 | | |
96 | | uint16_t S7CommLayer::getPduRef() const |
97 | 0 | { |
98 | 0 | return be16toh(getS7commHeader()->pduRef); |
99 | 0 | } |
100 | | |
101 | | uint16_t S7CommLayer::getDataLength() const |
102 | 0 | { |
103 | 0 | return be16toh(getS7commHeader()->dataLength); |
104 | 0 | } |
105 | | |
106 | | void S7CommLayer::setMsgType(uint8_t msgType) const |
107 | 0 | { |
108 | 0 | getS7commHeader()->msgType = msgType; |
109 | 0 | } |
110 | | |
111 | | uint8_t S7CommLayer::getErrorCode() const |
112 | 0 | { |
113 | 0 | return getS7commAckDataHeader()->errorCode; |
114 | 0 | } |
115 | | |
116 | | uint8_t S7CommLayer::getErrorClass() const |
117 | 0 | { |
118 | 0 | return getS7commAckDataHeader()->errorClass; |
119 | 0 | } |
120 | | |
121 | | void S7CommLayer::setPduRef(uint16_t pduRef) const |
122 | 0 | { |
123 | 0 | getS7commHeader()->pduRef = htobe16(pduRef); |
124 | 0 | } |
125 | | |
126 | | void S7CommLayer::setErrorCode(uint8_t errorCode) const |
127 | 0 | { |
128 | 0 | getS7commAckDataHeader()->errorCode = errorCode; |
129 | 0 | } |
130 | | |
131 | | void S7CommLayer::setErrorClass(uint8_t errorClass) const |
132 | 0 | { |
133 | 0 | getS7commAckDataHeader()->errorClass = errorClass; |
134 | 0 | } |
135 | | |
136 | | const S7CommParameter* S7CommLayer::getParameter() |
137 | 0 | { |
138 | 0 | if (!m_Parameter) |
139 | 0 | { |
140 | 0 | uint8_t* payload = m_Data + getS7commHeaderLength(); |
141 | 0 | m_Parameter = new S7CommParameter(payload, getParamLength()); |
142 | 0 | } |
143 | |
|
144 | 0 | return m_Parameter; |
145 | 0 | } |
146 | | |
147 | | size_t S7CommLayer::getS7commHeaderLength() const |
148 | 0 | { |
149 | 0 | if (getS7commHeader()->msgType == 0x03) |
150 | 0 | { |
151 | 0 | return sizeof(s7comm_ack_data_hdr); |
152 | 0 | } |
153 | 0 | return sizeof(s7commhdr); |
154 | 0 | } |
155 | | |
156 | | } // namespace pcpp |