/src/PcapPlusPlus/Packet++/src/SomeIpSdLayer.cpp
Line | Count | Source |
1 | | #define LOG_MODULE PacketLogModuleSomeIpSdLayer |
2 | | |
3 | | #include "SomeIpSdLayer.h" |
4 | | #include "EndianPortable.h" |
5 | | #include <algorithm> |
6 | | #include <sstream> |
7 | | #include <stdexcept> |
8 | | |
9 | | namespace pcpp |
10 | | { |
11 | | // -------- Class SomeIpSdOption ----------------- |
12 | | |
13 | | SomeIpSdOption::~SomeIpSdOption() |
14 | 5.26k | { |
15 | 5.26k | if (m_ShadowData != nullptr) |
16 | 0 | delete[] m_ShadowData; |
17 | 5.26k | } |
18 | | |
19 | | SomeIpSdOption::OptionType SomeIpSdOption::getType() const |
20 | 2.90k | { |
21 | 2.90k | return static_cast<OptionType>(getSomeIpSdOptionHeader()->type); |
22 | 2.90k | } |
23 | | |
24 | | uint8_t* SomeIpSdOption::getDataPtr() const |
25 | 8.65k | { |
26 | 8.65k | if (m_DataContainer != nullptr) |
27 | 8.65k | return m_DataContainer->getDataPtr(m_Offset); |
28 | | |
29 | 0 | return m_ShadowData; |
30 | 8.65k | } |
31 | | |
32 | | SomeIpSdOption::someipsdhdroptionsbase* SomeIpSdOption::getSomeIpSdOptionHeader() const |
33 | 3.25k | { |
34 | 3.25k | return (someipsdhdroptionsbase*)getDataPtr(); |
35 | 3.25k | } |
36 | | |
37 | | void SomeIpSdOption::initStdFields(OptionType type) |
38 | 0 | { |
39 | 0 | someipsdhdroptionsbase* optionHdr = getSomeIpSdOptionHeader(); |
40 | |
|
41 | 0 | optionHdr->type = static_cast<uint8_t>(type); |
42 | | // Length field is excluding length field itself and uint8_t type field |
43 | 0 | optionHdr->length = htobe16((uint16_t)(m_DataLen - sizeof(optionHdr->length) - sizeof(optionHdr->type))); |
44 | 0 | } |
45 | | |
46 | | // -------- Class SomeIpSdIPv4Option ----------------- |
47 | | |
48 | | SomeIpSdIPv4Option::SomeIpSdIPv4Option(IPv4OptionType type, IPv4Address ipAddress, uint16_t port, |
49 | | SomeIpSdProtocolType l4Protocol) |
50 | 0 | { |
51 | 0 | m_DataLen = sizeof(someipsdhdroptionsipv4); |
52 | 0 | m_ShadowData = new uint8_t[m_DataLen]; |
53 | 0 | memset(m_ShadowData, 0, m_DataLen); |
54 | |
|
55 | 0 | switch (type) |
56 | 0 | { |
57 | 0 | case IPv4OptionType::IPv4Endpoint: |
58 | 0 | initStdFields(OptionType::IPv4Endpoint); |
59 | 0 | break; |
60 | 0 | case IPv4OptionType::IPv4Multicast: |
61 | 0 | initStdFields(OptionType::IPv4Multicast); |
62 | 0 | break; |
63 | 0 | case IPv4OptionType::IPv4SdEndpoint: |
64 | 0 | initStdFields(OptionType::IPv4SdEndpoint); |
65 | 0 | break; |
66 | 0 | } |
67 | | |
68 | 0 | someipsdhdroptionsipv4* hdr = (someipsdhdroptionsipv4*)getDataPtr(); |
69 | 0 | hdr->ipv4Address = ipAddress.toInt(); |
70 | 0 | hdr->portNumber = htobe16(port); |
71 | 0 | hdr->l4Protocol = l4Protocol; |
72 | 0 | } |
73 | | |
74 | | SomeIpSdIPv4Option::SomeIpSdIPv4Option(const IDataContainer* dataContainer, size_t offset) |
75 | 1.99k | : SomeIpSdOption(dataContainer, offset) |
76 | 1.99k | { |
77 | 1.99k | m_DataLen = sizeof(someipsdhdroptionsipv4); |
78 | 1.99k | } |
79 | | |
80 | | IPv4Address SomeIpSdIPv4Option::getIpAddress() const |
81 | 1.02k | { |
82 | 1.02k | someipsdhdroptionsipv4* hdr = (someipsdhdroptionsipv4*)getDataPtr(); |
83 | 1.02k | IPv4Address ipAddr(hdr->ipv4Address); |
84 | | |
85 | 1.02k | return ipAddr; |
86 | 1.02k | } |
87 | | |
88 | | uint16_t SomeIpSdIPv4Option::getPort() const |
89 | 1.02k | { |
90 | 1.02k | someipsdhdroptionsipv4* hdr = (someipsdhdroptionsipv4*)getDataPtr(); |
91 | 1.02k | return be16toh(hdr->portNumber); |
92 | 1.02k | } |
93 | | |
94 | | SomeIpSdProtocolType SomeIpSdIPv4Option::getProtocol() const |
95 | 1.02k | { |
96 | 1.02k | someipsdhdroptionsipv4* hdr = (someipsdhdroptionsipv4*)getDataPtr(); |
97 | 1.02k | return hdr->l4Protocol; |
98 | 1.02k | } |
99 | | |
100 | | // -------- Class SomeIpSdIPv6Option ----------------- |
101 | | |
102 | | SomeIpSdIPv6Option::SomeIpSdIPv6Option(IPv6OptionType type, IPv6Address ipAddress, uint16_t port, |
103 | | SomeIpSdProtocolType l4Protocol) |
104 | 0 | { |
105 | 0 | m_DataLen = sizeof(someipsdhdroptionsipv6); |
106 | 0 | m_ShadowData = new uint8_t[m_DataLen]; |
107 | 0 | memset(m_ShadowData, 0, m_DataLen); |
108 | |
|
109 | 0 | switch (type) |
110 | 0 | { |
111 | 0 | case IPv6OptionType::IPv6Endpoint: |
112 | 0 | initStdFields(OptionType::IPv6Endpoint); |
113 | 0 | break; |
114 | 0 | case IPv6OptionType::IPv6Multicast: |
115 | 0 | initStdFields(OptionType::IPv6Multicast); |
116 | 0 | break; |
117 | 0 | case IPv6OptionType::IPv6SdEndpoint: |
118 | 0 | initStdFields(OptionType::IPv6SdEndpoint); |
119 | 0 | break; |
120 | 0 | } |
121 | | |
122 | 0 | someipsdhdroptionsipv6* hdr = (someipsdhdroptionsipv6*)getDataPtr(); |
123 | 0 | std::memcpy(hdr->ipv6Address, ipAddress.toBytes(), 16); |
124 | 0 | hdr->portNumber = htobe16(port); |
125 | 0 | hdr->l4Protocol = l4Protocol; |
126 | 0 | } |
127 | | |
128 | | SomeIpSdIPv6Option::SomeIpSdIPv6Option(const IDataContainer* dataContainer, size_t offset) |
129 | 1.31k | : SomeIpSdOption(dataContainer, offset) |
130 | 1.31k | { |
131 | 1.31k | m_DataLen = sizeof(someipsdhdroptionsipv6); |
132 | 1.31k | } |
133 | | |
134 | | IPv6Address SomeIpSdIPv6Option::getIpAddress() const |
135 | 779 | { |
136 | 779 | someipsdhdroptionsipv6* hdr = (someipsdhdroptionsipv6*)getDataPtr(); |
137 | 779 | IPv6Address ipAddr(hdr->ipv6Address); |
138 | | |
139 | 779 | return ipAddr; |
140 | 779 | } |
141 | | |
142 | | uint16_t SomeIpSdIPv6Option::getPort() const |
143 | 779 | { |
144 | 779 | someipsdhdroptionsipv6* hdr = (someipsdhdroptionsipv6*)getDataPtr(); |
145 | 779 | return be16toh(hdr->portNumber); |
146 | 779 | } |
147 | | |
148 | | SomeIpSdProtocolType SomeIpSdIPv6Option::getProtocol() const |
149 | 779 | { |
150 | 779 | someipsdhdroptionsipv6* hdr = (someipsdhdroptionsipv6*)getDataPtr(); |
151 | 779 | return hdr->l4Protocol; |
152 | 779 | } |
153 | | |
154 | | // -------- Class SomeIpSdConfigurationOption ----------------- |
155 | | |
156 | | SomeIpSdConfigurationOption::SomeIpSdConfigurationOption(const std::string& configurationString) |
157 | 0 | { |
158 | 0 | m_DataLen = configurationString.length() + sizeof(someipsdhdroptionsbase); |
159 | 0 | m_ShadowData = new uint8_t[m_DataLen]; |
160 | 0 | memset(m_ShadowData, 0, m_DataLen); |
161 | |
|
162 | 0 | initStdFields(OptionType::ConfigurationString); |
163 | 0 | std::memcpy(getDataPtr() + sizeof(someipsdhdroptionsbase), configurationString.c_str(), |
164 | 0 | configurationString.length()); |
165 | 0 | } |
166 | | |
167 | | SomeIpSdConfigurationOption::SomeIpSdConfigurationOption(const IDataContainer* dataContainer, size_t offset) |
168 | 355 | : SomeIpSdOption(dataContainer, offset) |
169 | 355 | { |
170 | 355 | m_DataLen = sizeof(someipsdhdroptionsbase) - 1 + be16toh(getSomeIpSdOptionHeader()->length); |
171 | 355 | } |
172 | | |
173 | | std::string SomeIpSdConfigurationOption::getConfigurationString() const |
174 | 0 | { |
175 | 0 | return std::string((char*)getDataPtr() + sizeof(someipsdhdroptionsbase), |
176 | 0 | be16toh(getSomeIpSdOptionHeader()->length) - 1); |
177 | 0 | } |
178 | | |
179 | | // -------- Class SomeIpSdLoadBalancingOption ----------------- |
180 | | |
181 | | SomeIpSdLoadBalancingOption::SomeIpSdLoadBalancingOption(uint16_t priority, uint16_t weight) |
182 | 0 | { |
183 | 0 | m_DataLen = sizeof(someipsdhdroptionsload); |
184 | 0 | m_ShadowData = new uint8_t[m_DataLen]; |
185 | 0 | memset(m_ShadowData, 0, m_DataLen); |
186 | |
|
187 | 0 | initStdFields(OptionType::LoadBalancing); |
188 | |
|
189 | 0 | someipsdhdroptionsload* hdr = (someipsdhdroptionsload*)getDataPtr(); |
190 | 0 | hdr->priority = htobe16(priority); |
191 | 0 | hdr->weight = htobe16(weight); |
192 | 0 | } |
193 | | |
194 | | SomeIpSdLoadBalancingOption::SomeIpSdLoadBalancingOption(const IDataContainer* dataContainer, size_t offset) |
195 | 1.59k | : SomeIpSdOption(dataContainer, offset) |
196 | 1.59k | { |
197 | 1.59k | m_DataLen = sizeof(someipsdhdroptionsload); |
198 | 1.59k | } |
199 | | |
200 | | uint16_t SomeIpSdLoadBalancingOption::getPriority() const |
201 | 0 | { |
202 | 0 | someipsdhdroptionsload* hdr = (someipsdhdroptionsload*)getDataPtr(); |
203 | 0 | return be16toh(hdr->priority); |
204 | 0 | } |
205 | | |
206 | | uint16_t SomeIpSdLoadBalancingOption::getWeight() const |
207 | 0 | { |
208 | 0 | someipsdhdroptionsload* hdr = (someipsdhdroptionsload*)getDataPtr(); |
209 | 0 | return be16toh(hdr->weight); |
210 | 0 | } |
211 | | |
212 | | // -------- Class SomeIpSdEntry ----------------- |
213 | | |
214 | | SomeIpSdEntry::SomeIpSdEntry(EntryType type, uint16_t serviceID, uint16_t instanceID, uint8_t majorVersion, |
215 | | uint32_t TTL, uint32_t minorVersion) |
216 | 0 | { |
217 | 0 | initStdFields(type, serviceID, instanceID, majorVersion, TTL); |
218 | 0 | setMinorVersion(minorVersion); |
219 | 0 | } |
220 | | |
221 | | SomeIpSdEntry::SomeIpSdEntry(EntryType type, uint16_t serviceID, uint16_t instanceID, uint8_t majorVersion, |
222 | | uint32_t TTL, uint8_t counter, uint16_t eventGroupID) |
223 | 0 | { |
224 | 0 | initStdFields(type, serviceID, instanceID, majorVersion, TTL); |
225 | 0 | setCounter(counter); |
226 | 0 | setEventgroupId(eventGroupID); |
227 | 0 | } |
228 | | |
229 | | SomeIpSdEntry::SomeIpSdEntry(const SomeIpSdLayer* pSomeIpSdLayer, size_t offset) |
230 | 3.60k | : m_Layer(pSomeIpSdLayer), m_Offset(offset), m_ShadowData(nullptr) |
231 | 3.60k | { |
232 | 3.60k | EntryType entryType; |
233 | | |
234 | 3.60k | someipsdhdrentry* hdr = getSomeIpSdEntryHeader(); |
235 | 3.60k | TypeInternal internalType = static_cast<TypeInternal>(hdr->type); |
236 | 3.60k | auto ttl = getTtl(); |
237 | | |
238 | 3.60k | switch (internalType) |
239 | 3.60k | { |
240 | 354 | case SomeIpSdEntry::TypeInternal::FindService_Internal: |
241 | 354 | entryType = SomeIpSdEntry::EntryType::FindService; |
242 | 354 | break; |
243 | 2.21k | case SomeIpSdEntry::TypeInternal::OfferService_Internal: |
244 | 2.21k | if (ttl == 0) |
245 | 320 | { |
246 | 320 | entryType = EntryType::StopOfferService; |
247 | 320 | } |
248 | 1.89k | else |
249 | 1.89k | { |
250 | 1.89k | entryType = EntryType::OfferService; |
251 | 1.89k | } |
252 | 2.21k | break; |
253 | 14 | case SomeIpSdEntry::TypeInternal::SubscribeEventgroup_Internal: |
254 | 14 | if (ttl == 0) |
255 | 1 | { |
256 | 1 | entryType = EntryType::StopSubscribeEventgroup; |
257 | 1 | } |
258 | 13 | else |
259 | 13 | { |
260 | 13 | entryType = EntryType::SubscribeEventgroup; |
261 | 13 | } |
262 | 14 | break; |
263 | 385 | case SomeIpSdEntry::TypeInternal::SubscribeEventgroupAck_Internal: |
264 | 385 | if (ttl == 0) |
265 | 173 | { |
266 | 173 | entryType = EntryType::SubscribeEventgroupNack; |
267 | 173 | } |
268 | 212 | else |
269 | 212 | { |
270 | 212 | entryType = EntryType::SubscribeEventgroupAck; |
271 | 212 | } |
272 | 385 | break; |
273 | 640 | default: |
274 | 640 | entryType = EntryType::UnknownEntryType; |
275 | 640 | break; |
276 | 3.60k | } |
277 | | |
278 | 3.60k | m_EntryType = entryType; |
279 | 3.60k | } |
280 | | |
281 | | SomeIpSdEntry::~SomeIpSdEntry() |
282 | 3.60k | { |
283 | 3.60k | if (m_ShadowData != nullptr) |
284 | 0 | delete[] m_ShadowData; |
285 | 3.60k | } |
286 | | |
287 | | uint8_t* SomeIpSdEntry::getDataPtr() const |
288 | 32.4k | { |
289 | 32.4k | if (m_Layer != nullptr) |
290 | 32.4k | return m_Layer->getDataPtr(m_Offset); |
291 | | |
292 | 0 | return m_ShadowData; |
293 | 32.4k | } |
294 | | |
295 | | SomeIpSdEntry::someipsdhdrentry* SomeIpSdEntry::getSomeIpSdEntryHeader() const |
296 | 32.4k | { |
297 | 32.4k | return (someipsdhdrentry*)getDataPtr(); |
298 | 32.4k | } |
299 | | |
300 | | uint32_t SomeIpSdEntry::getNumOptions() const |
301 | 3.60k | { |
302 | 3.60k | auto* hdr = getSomeIpSdEntryHeader(); |
303 | 3.60k | return hdr->nrOpt1 + hdr->nrOpt2; |
304 | 3.60k | } |
305 | | |
306 | | uint16_t SomeIpSdEntry::getServiceId() const |
307 | 3.60k | { |
308 | 3.60k | return be16toh(getSomeIpSdEntryHeader()->serviceID); |
309 | 3.60k | } |
310 | | |
311 | | void SomeIpSdEntry::setServiceId(uint16_t serviceId) |
312 | 0 | { |
313 | 0 | getSomeIpSdEntryHeader()->serviceID = htobe16(serviceId); |
314 | 0 | } |
315 | | |
316 | | uint16_t SomeIpSdEntry::getInstanceId() const |
317 | 3.60k | { |
318 | 3.60k | return be16toh(getSomeIpSdEntryHeader()->instanceID); |
319 | 3.60k | } |
320 | | |
321 | | void SomeIpSdEntry::setInstanceId(uint16_t instanceId) |
322 | 0 | { |
323 | 0 | getSomeIpSdEntryHeader()->instanceID = htobe16(instanceId); |
324 | 0 | } |
325 | | |
326 | | uint8_t SomeIpSdEntry::getMajorVersion() const |
327 | 3.60k | { |
328 | 3.60k | return (be32toh(getSomeIpSdEntryHeader()->majorVersion_ttl) & ~SOMEIPSD_HDR_ENTRY_MASK_TTL) >> 24; |
329 | 3.60k | } |
330 | | |
331 | | void SomeIpSdEntry::setMajorVersion(uint8_t majorVersion) |
332 | 0 | { |
333 | 0 | someipsdhdrentry* hdr = getSomeIpSdEntryHeader(); |
334 | 0 | uint32_t val = (majorVersion << 24) | (be32toh(hdr->majorVersion_ttl) & SOMEIPSD_HDR_ENTRY_MASK_TTL); |
335 | 0 | hdr->majorVersion_ttl = htobe32(val); |
336 | 0 | } |
337 | | |
338 | | uint32_t SomeIpSdEntry::getTtl() const |
339 | 3.60k | { |
340 | 3.60k | return be32toh(getSomeIpSdEntryHeader()->majorVersion_ttl) & SOMEIPSD_HDR_ENTRY_MASK_TTL; |
341 | 3.60k | } |
342 | | |
343 | | void SomeIpSdEntry::setTtl(uint32_t ttl) |
344 | 0 | { |
345 | 0 | someipsdhdrentry* hdr = getSomeIpSdEntryHeader(); |
346 | 0 | uint32_t val = |
347 | 0 | (ttl & SOMEIPSD_HDR_ENTRY_MASK_TTL) | (be32toh(hdr->majorVersion_ttl) & ~SOMEIPSD_HDR_ENTRY_MASK_TTL); |
348 | 0 | hdr->majorVersion_ttl = htobe32(val); |
349 | 0 | } |
350 | | |
351 | | uint32_t SomeIpSdEntry::getMinorVersion() const |
352 | 3.60k | { |
353 | 3.60k | return be32toh(getSomeIpSdEntryHeader()->data); |
354 | 3.60k | } |
355 | | |
356 | | void SomeIpSdEntry::setMinorVersion(uint32_t minorVersion) |
357 | 0 | { |
358 | 0 | getSomeIpSdEntryHeader()->data = htobe32(minorVersion); |
359 | 0 | } |
360 | | |
361 | | uint8_t SomeIpSdEntry::getCounter() const |
362 | 3.60k | { |
363 | 3.60k | return (uint8_t)((be32toh(getSomeIpSdEntryHeader()->data) >> 16) & 0x0F); |
364 | 3.60k | } |
365 | | |
366 | | void SomeIpSdEntry::setCounter(uint8_t counter) |
367 | 0 | { |
368 | 0 | someipsdhdrentry* hdr = getSomeIpSdEntryHeader(); |
369 | 0 | hdr->data = htobe32((be32toh(hdr->data) & 0xFFF0FFFF) | ((counter & 0x0F) << 16)); |
370 | 0 | } |
371 | | |
372 | | uint16_t SomeIpSdEntry::getEventgroupId() const |
373 | 3.60k | { |
374 | 3.60k | return (uint16_t)(be32toh(getSomeIpSdEntryHeader()->data) & 0x0000FFFF); |
375 | 3.60k | } |
376 | | |
377 | | void SomeIpSdEntry::setEventgroupId(uint16_t eventgroupID) |
378 | 0 | { |
379 | 0 | someipsdhdrentry* hdr = getSomeIpSdEntryHeader(); |
380 | 0 | hdr->data = htobe32((be32toh(hdr->data) & 0xFFFF0000) | eventgroupID); |
381 | 0 | } |
382 | | |
383 | | void SomeIpSdEntry::initStdFields(EntryType type, uint16_t serviceID, uint16_t instanceID, uint8_t majorVersion, |
384 | | uint32_t TTL) |
385 | 0 | { |
386 | 0 | m_EntryType = type; |
387 | 0 | m_Layer = nullptr; |
388 | 0 | m_Offset = 0; |
389 | |
|
390 | 0 | size_t dataLen = sizeof(someipsdhdrentry); |
391 | 0 | m_ShadowData = new uint8_t[dataLen]; |
392 | 0 | memset(m_ShadowData, 0, dataLen); |
393 | |
|
394 | 0 | someipsdhdrentry* hdr = getSomeIpSdEntryHeader(); |
395 | 0 | setServiceId(serviceID); |
396 | 0 | setInstanceId(instanceID); |
397 | 0 | setMajorVersion(majorVersion); |
398 | 0 | setTtl(TTL); |
399 | |
|
400 | 0 | switch (type) |
401 | 0 | { |
402 | 0 | case EntryType::FindService: |
403 | 0 | { |
404 | 0 | hdr->type = static_cast<uint8_t>(TypeInternal::FindService_Internal); |
405 | 0 | break; |
406 | 0 | } |
407 | 0 | case EntryType::OfferService: |
408 | 0 | case EntryType::StopOfferService: |
409 | 0 | { |
410 | 0 | hdr->type = static_cast<uint8_t>(TypeInternal::OfferService_Internal); |
411 | 0 | break; |
412 | 0 | } |
413 | 0 | case EntryType::SubscribeEventgroup: |
414 | 0 | case EntryType::StopSubscribeEventgroup: |
415 | 0 | { |
416 | 0 | hdr->type = static_cast<uint8_t>(TypeInternal::SubscribeEventgroup_Internal); |
417 | 0 | break; |
418 | 0 | } |
419 | 0 | case EntryType::SubscribeEventgroupAck: |
420 | 0 | case EntryType::SubscribeEventgroupNack: |
421 | 0 | { |
422 | 0 | hdr->type = static_cast<uint8_t>(TypeInternal::SubscribeEventgroupAck_Internal); |
423 | 0 | break; |
424 | 0 | } |
425 | 0 | default: |
426 | 0 | break; |
427 | 0 | } |
428 | 0 | } |
429 | | |
430 | | // -------- Class SomeIpSdLayer ----------------- |
431 | | |
432 | | SomeIpSdLayer::SomeIpSdLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) |
433 | 24.7k | : SomeIpLayer(data, dataLen, prevLayer, packet) |
434 | 24.7k | { |
435 | 24.7k | countOptions(m_NumOptions, data); |
436 | 24.7k | } |
437 | | |
438 | | SomeIpSdLayer::SomeIpSdLayer(uint16_t serviceID, uint16_t methodID, uint16_t clientID, uint16_t sessionID, |
439 | | uint8_t interfaceVersion, MsgType type, uint8_t returnCode, uint8_t flags) |
440 | 0 | { |
441 | 0 | m_Protocol = SomeIP; |
442 | 0 | m_DataLen = sizeof(someipsdhdr) + 2 * sizeof(uint32_t); |
443 | 0 | m_Data = new uint8_t[m_DataLen]; |
444 | 0 | memset(m_Data, 0, m_DataLen); |
445 | |
|
446 | 0 | m_NumOptions = 0; |
447 | |
|
448 | 0 | setServiceID(serviceID); |
449 | 0 | setMethodID(methodID); |
450 | 0 | setPayloadLength(sizeof(uint32_t) * 3); // Flags+Reserved, Length Entries, Length Options |
451 | 0 | setClientID(clientID); |
452 | 0 | setSessionID(sessionID); |
453 | 0 | setProtocolVersion(0x01); |
454 | 0 | setInterfaceVersion(interfaceVersion); |
455 | 0 | setMessageType(type); |
456 | 0 | setReturnCode(returnCode); |
457 | 0 | setFlags(flags); |
458 | 0 | } |
459 | | |
460 | | uint8_t SomeIpSdLayer::getFlags() const |
461 | 3.67k | { |
462 | 3.67k | someipsdhdr* hdr = (someipsdhdr*)m_Data; |
463 | 3.67k | return hdr->flags; |
464 | 3.67k | } |
465 | | |
466 | | void SomeIpSdLayer::setFlags(uint8_t flags) |
467 | 0 | { |
468 | 0 | someipsdhdr* hdr = (someipsdhdr*)m_Data; |
469 | 0 | hdr->flags = flags; |
470 | 0 | } |
471 | | |
472 | | uint32_t SomeIpSdLayer::getNumEntries() const |
473 | 10.9k | { |
474 | 10.9k | return (uint32_t)(getLenEntries() / sizeof(SomeIpSdEntry::someipsdhdrentry)); |
475 | 10.9k | } |
476 | | |
477 | | uint32_t SomeIpSdLayer::getNumOptions() const |
478 | 7.34k | { |
479 | 7.34k | return m_NumOptions; |
480 | 7.34k | } |
481 | | |
482 | | const SomeIpSdLayer::EntriesVec SomeIpSdLayer::getEntries() const |
483 | 3.67k | { |
484 | 3.67k | size_t remainingLen = getLenEntries(); |
485 | 3.67k | size_t offset = sizeof(someipsdhdr) + sizeof(uint32_t); |
486 | | |
487 | 3.67k | EntriesVec vecEntries; |
488 | 3.67k | EntryPtr entry; |
489 | | |
490 | 7.27k | while (remainingLen > 0) |
491 | 3.73k | { |
492 | | // Ensure there is enough remaining length for a new entry |
493 | 3.73k | if (remainingLen < sizeof(SomeIpSdEntry::someipsdhdrentry)) |
494 | 123 | { |
495 | 123 | break; |
496 | 123 | } |
497 | 3.60k | entry = new SomeIpSdEntry(this, offset); |
498 | | |
499 | 3.60k | size_t entryLen = entry->getLength(); |
500 | 3.60k | remainingLen -= entryLen; |
501 | 3.60k | offset += entryLen; |
502 | | |
503 | 3.60k | vecEntries.push_back(entry); |
504 | 3.60k | } |
505 | | |
506 | 3.67k | return vecEntries; |
507 | 3.67k | }; |
508 | | |
509 | | const SomeIpSdLayer::OptionsVec SomeIpSdLayer::getOptions() const |
510 | 3.67k | { |
511 | 3.67k | OptionsVec vecOptions; |
512 | 3.67k | OptionPtr option; |
513 | | |
514 | 3.67k | size_t remainingLen = getLenOptions(); |
515 | 3.67k | size_t offset = sizeof(someipsdhdr) + sizeof(uint32_t) + getLenEntries() + sizeof(uint32_t); |
516 | | |
517 | 7.77k | while (remainingLen > 0) |
518 | 4.10k | { |
519 | 4.10k | SomeIpSdOption::someipsdhdroptionsbase* hdr = (SomeIpSdOption::someipsdhdroptionsbase*)(m_Data + offset); |
520 | 4.10k | SomeIpSdOption::OptionType optionType = static_cast<SomeIpSdOption::OptionType>(hdr->type); |
521 | | |
522 | 4.10k | option = parseOption(optionType, offset); |
523 | | |
524 | 4.10k | if (option != nullptr) |
525 | 2.90k | { |
526 | 2.90k | vecOptions.push_back(std::move(option)); |
527 | 2.90k | } |
528 | | |
529 | 4.10k | size_t optionLen = be16toh(hdr->length) + 3; |
530 | 4.10k | remainingLen -= optionLen; |
531 | 4.10k | offset += optionLen; |
532 | 4.10k | } |
533 | | |
534 | 3.67k | return vecOptions; |
535 | 3.67k | } |
536 | | |
537 | | const SomeIpSdLayer::OptionsVec SomeIpSdLayer::getOptionsFromEntry(uint32_t index) const |
538 | 3.59k | { |
539 | 3.59k | OptionsVec vecOptions; |
540 | 3.59k | OptionPtr option; |
541 | | |
542 | 3.59k | if (index >= getNumEntries()) |
543 | 0 | return vecOptions; |
544 | | |
545 | 3.59k | size_t remainingLen = getLenOptions(); |
546 | 3.59k | size_t offset = sizeof(someipsdhdr) + sizeof(uint32_t) + getLenEntries() + sizeof(uint32_t); |
547 | | |
548 | 3.59k | size_t offsetToEntry = sizeof(someipsdhdr) + sizeof(uint32_t) + index * sizeof(SomeIpSdEntry::someipsdhdrentry); |
549 | 3.59k | SomeIpSdEntry::someipsdhdrentry* hdrEntry = (SomeIpSdEntry::someipsdhdrentry*)(m_Data + offsetToEntry); |
550 | 3.59k | uint8_t startIdxRun1 = hdrEntry->indexFirstOption; |
551 | 3.59k | uint8_t lenRun1 = hdrEntry->nrOpt1; |
552 | 3.59k | uint8_t startIdxRun2 = hdrEntry->indexSecondOption; |
553 | 3.59k | uint8_t lenRun2 = hdrEntry->nrOpt2; |
554 | | |
555 | 3.59k | int idx = 0; |
556 | | |
557 | 7.70k | while (remainingLen > 0) |
558 | 4.10k | { |
559 | 4.10k | SomeIpSdOption::someipsdhdroptionsbase* hdrOption = |
560 | 4.10k | (SomeIpSdOption::someipsdhdroptionsbase*)(m_Data + offset); |
561 | | |
562 | 4.10k | if (((idx >= startIdxRun1) && (idx < (startIdxRun1 + lenRun1))) || |
563 | 1.52k | ((idx >= startIdxRun2) && (idx < (startIdxRun2 + lenRun2)))) |
564 | 2.78k | { |
565 | 2.78k | SomeIpSdOption::OptionType optionType = static_cast<SomeIpSdOption::OptionType>(hdrOption->type); |
566 | | |
567 | 2.78k | option = parseOption(optionType, offset); |
568 | | |
569 | 2.78k | if (option != nullptr) |
570 | 2.35k | { |
571 | 2.35k | vecOptions.push_back(std::move(option)); |
572 | 2.35k | } |
573 | 2.78k | } |
574 | | |
575 | 4.10k | size_t optionLen = be16toh(hdrOption->length) + 3; |
576 | 4.10k | remainingLen -= optionLen; |
577 | 4.10k | offset += optionLen; |
578 | 4.10k | ++idx; |
579 | 4.10k | } |
580 | | |
581 | 3.59k | return vecOptions; |
582 | 3.59k | } |
583 | | |
584 | | bool SomeIpSdLayer::addOptionTo(uint32_t indexEntry, const SomeIpSdOption& option) |
585 | 0 | { |
586 | 0 | if (indexEntry >= getNumEntries()) |
587 | 0 | { |
588 | 0 | return false; |
589 | 0 | } |
590 | | |
591 | 0 | uint32_t indexOption = findOption(option); |
592 | 0 | bool success = addOptionIndex(indexEntry, indexOption); |
593 | |
|
594 | 0 | if (!success) |
595 | 0 | { |
596 | 0 | return false; |
597 | 0 | } |
598 | | |
599 | 0 | if (indexOption == m_NumOptions) |
600 | 0 | { |
601 | 0 | addOption(option); |
602 | 0 | } |
603 | |
|
604 | 0 | return true; |
605 | 0 | } |
606 | | |
607 | | std::string SomeIpSdLayer::toString() const |
608 | 7.34k | { |
609 | 7.34k | std::stringstream dataStream; |
610 | | |
611 | 7.34k | dataStream << "SOME/IP-SD Layer, " << getNumEntries() << " entries, " << getNumOptions() << " options"; |
612 | | |
613 | 7.34k | return dataStream.str(); |
614 | 7.34k | } |
615 | | |
616 | | uint32_t SomeIpSdLayer::addEntry(const SomeIpSdEntry& entry) |
617 | 0 | { |
618 | 0 | size_t lenEntries = getLenEntries(); |
619 | 0 | int offsetToAddAt = sizeof(someipsdhdr) + sizeof(uint32_t) + lenEntries; |
620 | |
|
621 | 0 | extendLayer(offsetToAddAt, entry.getLength()); |
622 | |
|
623 | 0 | setLenEntries(lenEntries + entry.getLength()); |
624 | |
|
625 | 0 | memcpy(m_Data + offsetToAddAt, entry.getDataPtr(), entry.getLength()); |
626 | |
|
627 | 0 | auto hdr = getSomeIpHeader(); |
628 | 0 | hdr->length = htobe32(be32toh(hdr->length) + (uint32_t)entry.getLength()); |
629 | |
|
630 | 0 | return getNumEntries() - 1; |
631 | 0 | } |
632 | | |
633 | | bool SomeIpSdLayer::isDataValid(const uint8_t* data, size_t dataLen) |
634 | 30.6k | { |
635 | 30.6k | uint32_t count; |
636 | 30.6k | if (!data || dataLen < sizeof(someipsdhdr) + sizeof(uint32_t) || |
637 | 30.6k | dataLen < sizeof(someipsdhdr) + sizeof(uint32_t) + getLenEntries(data) + sizeof(uint32_t) || |
638 | 27.6k | dataLen < |
639 | 27.6k | sizeof(someipsdhdr) + sizeof(uint32_t) + getLenEntries(data) + sizeof(uint32_t) + getLenOptions(data) || |
640 | 27.2k | !countOptions(count, data)) |
641 | 5.88k | { |
642 | 5.88k | return false; |
643 | 5.88k | } |
644 | | |
645 | 24.7k | return true; |
646 | 30.6k | } |
647 | | |
648 | | bool SomeIpSdLayer::countOptions(uint32_t& count, const uint8_t* data) |
649 | 51.9k | { |
650 | 51.9k | size_t offsetOption = sizeof(someipsdhdr) + sizeof(uint32_t) + getLenEntries(data) + sizeof(uint32_t); |
651 | 51.9k | size_t lenOptions = getLenOptions(data); |
652 | 51.9k | uint32_t len = 0; |
653 | | |
654 | 51.9k | count = 0; |
655 | 105k | while (len < lenOptions) |
656 | 56.0k | { |
657 | 56.0k | if (len + sizeof(uint16_t) + 3 * sizeof(uint8_t) > lenOptions) |
658 | 73 | return false; |
659 | | |
660 | 56.0k | uint32_t lenOption = be16toh(*((uint16_t*)(data + offsetOption + len))) + 3 * sizeof(uint8_t); |
661 | 56.0k | len += lenOption; |
662 | 56.0k | if (len > lenOptions) // the last one must be equal to lenOptions |
663 | 2.39k | return false; |
664 | | |
665 | 53.6k | ++(count); |
666 | 53.6k | } |
667 | 49.4k | return true; |
668 | 51.9k | } |
669 | | |
670 | | uint32_t SomeIpSdLayer::findOption(const SomeIpSdOption& option) |
671 | 0 | { |
672 | 0 | size_t offsetOption = sizeof(someipsdhdr) + sizeof(uint32_t) + getLenEntries() + sizeof(uint32_t); |
673 | |
|
674 | 0 | uint32_t i = 0; |
675 | 0 | while (i < m_NumOptions) |
676 | 0 | { |
677 | 0 | uint32_t lenOption = be16toh(*((uint16_t*)(m_Data + offsetOption))) + 3 * sizeof(uint8_t); |
678 | |
|
679 | 0 | if (option.getLength() == lenOption) |
680 | 0 | { |
681 | 0 | if (memcmp(m_Data + offsetOption, option.getDataPtr(), option.getLength()) == 0) |
682 | 0 | { |
683 | 0 | return i; |
684 | 0 | } |
685 | 0 | } |
686 | | |
687 | 0 | offsetOption += lenOption; |
688 | 0 | ++i; |
689 | 0 | } |
690 | 0 | return i; |
691 | 0 | } |
692 | | |
693 | | void SomeIpSdLayer::addOption(const SomeIpSdOption& option) |
694 | 0 | { |
695 | 0 | int offsetToAddAt = (int)getHeaderLen(); |
696 | |
|
697 | 0 | extendLayer(offsetToAddAt, option.getLength()); |
698 | 0 | memcpy(m_Data + offsetToAddAt, option.getDataPtr(), option.getLength()); |
699 | |
|
700 | 0 | setLenOptions(uint32_t(getLenOptions() + option.getLength())); |
701 | |
|
702 | 0 | auto hdr = getSomeIpHeader(); |
703 | 0 | hdr->length = htobe32(be32toh(hdr->length) + (uint32_t)option.getLength()); |
704 | |
|
705 | 0 | ++m_NumOptions; |
706 | 0 | } |
707 | | |
708 | | bool SomeIpSdLayer::addOptionIndex(uint32_t indexEntry, uint32_t indexOffset) |
709 | 0 | { |
710 | | // The SOME/IP-SD protocol supports two option runs. Runs meaning that two different starting indices with |
711 | | // differing length can be provided. Of course, this only works if the indices in both runs are consecutive. |
712 | | // |
713 | | // So, indices like this would work: |
714 | | // 1 2 3 ; 7 8 |
715 | | // |
716 | | // What wouldn't work is this: |
717 | | // 1 2 3 ; 7 9 |
718 | | // 1 3 ; 7 8 |
719 | |
|
720 | 0 | const size_t someipsdhdrentrySize = sizeof(SomeIpSdEntry::someipsdhdrentry); |
721 | 0 | size_t offsetToAddAt = sizeof(someipsdhdr) + sizeof(uint32_t) + indexEntry * someipsdhdrentrySize; |
722 | 0 | auto hdrEntry = (SomeIpSdEntry::someipsdhdrentry*)(m_Data + offsetToAddAt); |
723 | |
|
724 | 0 | uint8_t indexFirstOption = hdrEntry->indexFirstOption; |
725 | 0 | uint8_t lenFirstOption = hdrEntry->nrOpt1; |
726 | |
|
727 | 0 | if (lenFirstOption == 0) |
728 | 0 | { |
729 | 0 | hdrEntry->indexFirstOption = indexOffset; |
730 | 0 | ++hdrEntry->nrOpt1; |
731 | 0 | return true; |
732 | 0 | } |
733 | | |
734 | 0 | if (static_cast<uint32_t>(indexFirstOption + lenFirstOption + 1) == indexOffset) |
735 | 0 | { |
736 | 0 | ++hdrEntry->nrOpt1; |
737 | 0 | return true; |
738 | 0 | } |
739 | | |
740 | 0 | uint8_t indexSecondOption = hdrEntry->indexSecondOption; |
741 | 0 | uint8_t lenSecondOption = hdrEntry->nrOpt2; |
742 | |
|
743 | 0 | if (lenSecondOption == 0) |
744 | 0 | { |
745 | 0 | hdrEntry->indexFirstOption = indexOffset; |
746 | 0 | ++hdrEntry->nrOpt1; |
747 | 0 | return true; |
748 | 0 | } |
749 | | |
750 | 0 | if (static_cast<uint32_t>(indexSecondOption + lenSecondOption + 1) == indexOffset) |
751 | 0 | { |
752 | 0 | ++hdrEntry->nrOpt2; |
753 | 0 | return true; |
754 | 0 | } |
755 | | |
756 | 0 | return false; |
757 | 0 | } |
758 | | |
759 | | SomeIpSdLayer::OptionPtr SomeIpSdLayer::parseOption(SomeIpSdOption::OptionType type, size_t offset) const |
760 | 6.89k | { |
761 | 6.89k | switch (type) |
762 | 6.89k | { |
763 | 1.13k | case SomeIpSdOption::OptionType::IPv4Endpoint: |
764 | 1.62k | case SomeIpSdOption::OptionType::IPv4Multicast: |
765 | 1.99k | case SomeIpSdOption::OptionType::IPv4SdEndpoint: |
766 | 1.99k | { |
767 | 1.99k | return new SomeIpSdIPv4Option(this, offset); |
768 | 1.62k | } |
769 | 49 | case SomeIpSdOption::OptionType::IPv6Endpoint: |
770 | 294 | case SomeIpSdOption::OptionType::IPv6Multicast: |
771 | 1.31k | case SomeIpSdOption::OptionType::IPv6SdEndpoint: |
772 | 1.31k | { |
773 | 1.31k | return new SomeIpSdIPv6Option(this, offset); |
774 | 294 | } |
775 | 355 | case SomeIpSdOption::OptionType::ConfigurationString: |
776 | 355 | { |
777 | 355 | return new SomeIpSdConfigurationOption(this, offset); |
778 | 294 | } |
779 | 1.59k | case SomeIpSdOption::OptionType::LoadBalancing: |
780 | 1.59k | { |
781 | 1.59k | return new SomeIpSdLoadBalancingOption(this, offset); |
782 | 294 | } |
783 | 1.63k | default: |
784 | 1.63k | break; |
785 | 6.89k | } |
786 | 1.63k | return nullptr; |
787 | 6.89k | } |
788 | | |
789 | | size_t SomeIpSdLayer::getLenEntries() const |
790 | 21.8k | { |
791 | 21.8k | return getLenEntries(m_Data); |
792 | 21.8k | } |
793 | | |
794 | | size_t SomeIpSdLayer::getLenEntries(const uint8_t* data) |
795 | 218k | { |
796 | 218k | return be32toh(*((uint32_t*)(data + sizeof(someipsdhdr)))); |
797 | 218k | } |
798 | | |
799 | | size_t SomeIpSdLayer::getLenOptions() const |
800 | 7.26k | { |
801 | 7.26k | return getLenOptions(m_Data); |
802 | 7.26k | } |
803 | | |
804 | | size_t SomeIpSdLayer::getLenOptions(const uint8_t* data) |
805 | 86.8k | { |
806 | 86.8k | return be32toh(*((uint32_t*)(data + sizeof(someipsdhdr) + sizeof(uint32_t) + getLenEntries(data)))); |
807 | 86.8k | } |
808 | | |
809 | | void SomeIpSdLayer::setLenEntries(uint32_t length) |
810 | 0 | { |
811 | 0 | *((uint32_t*)(m_Data + sizeof(someipsdhdr))) = htobe32(length); |
812 | 0 | } |
813 | | |
814 | | void SomeIpSdLayer::setLenOptions(uint32_t length) |
815 | 0 | { |
816 | | *((uint32_t*)(m_Data + sizeof(someipsdhdr) + sizeof(uint32_t) + getLenEntries())) = htobe32(length); |
817 | 0 | } |
818 | | } // namespace pcpp |