Coverage Report

Created: 2026-08-31 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/header/SomeIpSdLayer.h
Line
Count
Source
1
#pragma once
2
3
#include "IpAddress.h"
4
#include "Layer.h"
5
#include "SomeIpLayer.h"
6
#include <cstring>
7
#include <iterator>
8
#include <unordered_map>
9
#include <memory>
10
#include <stdexcept>
11
#include <vector>
12
13
/// @file
14
15
/// @namespace pcpp
16
/// @brief The main namespace for the PcapPlusPlus lib
17
namespace pcpp
18
{
19
  /// Types of protocols that can be referenced in SOME/IP-SD
20
  enum SomeIpSdProtocolType : uint8_t
21
  {
22
    /// TCP
23
    SD_TCP = 0x06,
24
    /// UDP
25
    SD_UDP = 0x11
26
  };
27
28
  class SomeIpSdLayer;
29
30
  /// @class SomeIpSdOption
31
  /// Base class of the SOME/IP-SD options. Cannot be instantiated.
32
  class SomeIpSdOption
33
  {
34
  public:
35
    friend class SomeIpSdLayer;
36
37
    /// Types of options currently available for the SOME/IP-SD protocol
38
    enum class OptionType : uint8_t
39
    {
40
      /// Unknown Option Type
41
      Unknown = 0x00,
42
      /// Configuration Option
43
      ConfigurationString = 0x01,
44
      /// Load Balancing Option
45
      LoadBalancing = 0x02,
46
      /// IPv4 Endpoint Option
47
      IPv4Endpoint = 0x04,
48
      /// IPv6 Endpoint Option
49
      IPv6Endpoint = 0x06,
50
      /// IPv4 Multicast Option
51
      IPv4Multicast = 0x14,
52
      /// IPv6 Multicast Option
53
      IPv6Multicast = 0x16,
54
      /// IPv4 SD Endpoint Option
55
      IPv4SdEndpoint = 0x24,
56
      /// IPv6 SD Endpoint Option
57
      IPv6SdEndpoint = 0x26
58
    };
59
60
    /// @struct someipsdhdroptionsbase
61
    /// Represents the common base for SOME/IP-SD header options
62
#pragma pack(push, 1)
63
    struct someipsdhdroptionsbase
64
    {
65
      /// Length - excluding the 16 bit Length field and the 8 bit type flag
66
      uint16_t length;
67
      /// Type
68
      uint8_t type;
69
      /// Reserved
70
      uint8_t reserved;
71
    };
72
#pragma pack(pop)
73
    static_assert(sizeof(someipsdhdroptionsbase) == 4, "someipsdhdroptionsbase size is not 4 bytes");
74
75
    /// Destroy the SOME/IP-SD Option object and delete allocated data if it has been allocated by a constructor
76
    virtual ~SomeIpSdOption();
77
78
    /// Get the Option Type
79
    /// @return OptionType
80
    OptionType getType() const;
81
82
    /// Get the Length of the SOME/IP-SD option
83
    /// @return size_t
84
    size_t getLength() const
85
0
    {
86
0
      return m_DataLen;
87
0
    }
88
89
    /// Get the internal data of the SOME/IP-SD Option
90
    /// @return uint8_t*
91
    uint8_t* getDataPtr() const;
92
93
    /// Get a pointer to the SOME/IP-SD Option base header
94
    /// @return someipsdhdroptionsbase*
95
    someipsdhdroptionsbase* getSomeIpSdOptionHeader() const;
96
97
  protected:
98
    const IDataContainer* m_DataContainer;
99
    size_t m_Offset;
100
    uint8_t* m_ShadowData;
101
    size_t m_DataLen;
102
103
    SomeIpSdOption() : m_DataContainer(nullptr), m_Offset(0), m_ShadowData(nullptr), m_DataLen(0)
104
0
    {}
105
106
    SomeIpSdOption(const IDataContainer* dataContainer, size_t offset)
107
4.01k
        : m_DataContainer(dataContainer), m_Offset(offset), m_ShadowData(nullptr), m_DataLen(0)
108
4.01k
    {}
109
110
    void initStdFields(OptionType type);
111
112
    SomeIpSdOption(const SomeIpSdOption&) = delete;
113
    SomeIpSdOption& operator=(const SomeIpSdOption&) = delete;
114
  };
115
116
  /// @class SomeIpSdIPv4Option
117
  /// Implements the following SOME/IP-SD Options: IPv4 Endpoint, IPv4 Multicast, IPv4 SD Endpoint
118
  class SomeIpSdIPv4Option : public SomeIpSdOption
119
  {
120
  public:
121
    friend class SomeIpSdLayer;
122
123
    /// Types of options which are implemented with this class
124
    enum IPv4OptionType
125
    {
126
      /// IPv4 Endpoint Option
127
      IPv4Endpoint,
128
      /// IPv4 Multicast Option
129
      IPv4Multicast,
130
      /// IPv4 SD Endpoint Option
131
      IPv4SdEndpoint,
132
    };
133
134
    /// Construct a new SomeIpSdIPv4 Option object
135
    /// @param[in] type IPv4 Option type
136
    /// @param[in] ipAddress Ipv4 address to use
137
    /// @param[in] port Port to use
138
    /// @param[in] l4Protocol Protocol to use
139
    SomeIpSdIPv4Option(IPv4OptionType type, IPv4Address ipAddress, uint16_t port, SomeIpSdProtocolType l4Protocol);
140
141
    /// Construct a new SomeIpSdIPv4 Option object from already existing memory
142
    /// @param[in] dataContainer Data containing the SomeIpSdIPv4 Option object
143
    /// @param[in] offset Offset for dataContainer
144
    SomeIpSdIPv4Option(const IDataContainer* dataContainer, size_t offset);
145
146
    /// Get the Ip Address
147
    /// @return IPv4Address
148
    IPv4Address getIpAddress() const;
149
150
    /// Get the Port
151
    /// @return uint16_t
152
    uint16_t getPort() const;
153
154
    /// Get the Protocol
155
    /// @return SomeIpSdProtocolType
156
    SomeIpSdProtocolType getProtocol() const;
157
158
    /// Checks whether data is valid or not
159
    /// @return True if data is valid
160
    static bool isDataValid(const IDataContainer* data, size_t dataLen)
161
1.52k
    {
162
1.52k
      return data && dataLen >= sizeof(someipsdhdroptionsipv4);
163
1.52k
    }
164
165
  private:
166
    /// @struct someipsdhdroptionsipv4
167
    /// Represents the IPv4 option types for the SOME/IP-SD header
168
#pragma pack(push, 1)
169
    struct someipsdhdroptionsipv4 : someipsdhdroptionsbase
170
    {
171
      /// IPv4-Address field
172
      uint32_t ipv4Address;
173
      // cppcheck-suppress duplInheritedMember
174
      /// Reserved
175
      uint8_t reserved;
176
      /// Layer 4 Protocol field (L4-Proto) - Either UDP or TCP
177
      SomeIpSdProtocolType l4Protocol;
178
      /// Port number of UDP or TCP
179
      uint16_t portNumber;
180
    };
181
#pragma pack(pop)
182
    static_assert(sizeof(someipsdhdroptionsipv4) == 12, "someipsdhdroptionsipv4 size is not 12 bytes");
183
  };
184
185
  /// @class SomeIpSdIPv6Option
186
  /// Implements the following SOME/IP-SD Options: IPv6 Endpoint, IPv6 Multicast, IPv6 SD Endpoint
187
  class SomeIpSdIPv6Option : public SomeIpSdOption
188
  {
189
  public:
190
    friend class SomeIpSdLayer;
191
192
    /// Types of options which are implemented with this class
193
    enum IPv6OptionType
194
    {
195
      /// IPv6 Endpoint Option
196
      IPv6Endpoint,
197
      /// IPv6 Multicast Option
198
      IPv6Multicast,
199
      /// IPv6 SD Endpoint Option
200
      IPv6SdEndpoint,
201
    };
202
203
    /// Construct a new SomeIpSdIPv6 Option object
204
    /// @param[in] type IPv6 Option type
205
    /// @param[in] ipAddress Ipv6 address to use
206
    /// @param[in] port Port to use
207
    /// @param[in] l4Protocol Protocol to use
208
    SomeIpSdIPv6Option(IPv6OptionType type, IPv6Address ipAddress, uint16_t port, SomeIpSdProtocolType l4Protocol);
209
210
    /// Construct a new SomeIpSdIPv6 Option object from already existing memory
211
    /// @param[in] dataContainer Data containing the SomeIpSdIPv6 Option object
212
    /// @param[in] offset Offset for dataContainer
213
    SomeIpSdIPv6Option(const IDataContainer* dataContainer, size_t offset);
214
215
    /// Get the Ip Address
216
    /// @return IPv6Address
217
    IPv6Address getIpAddress() const;
218
219
    /// Get the Port
220
    /// @return uint16_t
221
    uint16_t getPort() const;
222
223
    /// Get the Protocol
224
    /// @return SomeIpSdProtocolType
225
    SomeIpSdProtocolType getProtocol() const;
226
227
    /// Checks whether data is valid or not
228
    /// @return True if data is valid
229
    static bool isDataValid(const IDataContainer* data, size_t dataLen)
230
956
    {
231
956
      return data && dataLen >= sizeof(someipsdhdroptionsipv6);
232
956
    }
233
234
  private:
235
    /// @struct someipsdhdroptionsipv6
236
    /// Represents the IPv6 option types for the SOME/IP-SD header
237
#pragma pack(push, 1)
238
    struct someipsdhdroptionsipv6 : someipsdhdroptionsbase
239
    {
240
      /// IPv6-Address field
241
      uint8_t ipv6Address[16];
242
      // cppcheck-suppress duplInheritedMember
243
      /// Reserved
244
      uint8_t reserved;
245
      /// Layer 4 Protocol field (L4-Proto) - Either UDP or TCP
246
      SomeIpSdProtocolType l4Protocol;
247
      /// Port number of UDP or TCP
248
      uint16_t portNumber;
249
    };
250
#pragma pack(pop)
251
    static_assert(sizeof(someipsdhdroptionsipv6) == 24, "someipsdhdroptionsipv6 size is not 24 bytes");
252
  };
253
254
  /// @class SomeIpSdConfigurationOption
255
  /// Implements the Configuration option of SOME/IP-SD protocol
256
  class SomeIpSdConfigurationOption : public SomeIpSdOption
257
  {
258
  public:
259
    friend class SomeIpSdLayer;
260
261
    /// Construct a new Configuration Option object
262
    /// @param[in] configurationString the configuration string
263
    explicit SomeIpSdConfigurationOption(const std::string& configurationString);
264
265
    /// Construct a new Configuration Option object from already existing memory
266
    /// @param[in] dataContainer Data containing the Configuration Option object
267
    /// @param[in] offset Offset for dataContainer
268
    SomeIpSdConfigurationOption(const IDataContainer* dataContainer, size_t offset);
269
270
    /// Get the configuration string
271
    /// @return std::string
272
    std::string getConfigurationString() const;
273
274
    /// Checks whether data is valid or not
275
    /// @return True if data is valid
276
    static bool isDataValid(const IDataContainer* data, size_t dataLen)
277
456
    {
278
456
      return data && dataLen >= (sizeof(someipsdhdroptionsbase) - 1);
279
456
    }
280
  };
281
282
  /// @class SomeIpSdLoadBalancingOption
283
  /// Implements the Load Balancing option of SOME/IP-SD protocol
284
  class SomeIpSdLoadBalancingOption : public SomeIpSdOption
285
  {
286
  public:
287
    friend class SomeIpSdLayer;
288
289
    /// Construct a new Load Balancing object
290
    /// @param[in] priority Priority of this instance
291
    /// @param[in] weight Weight of this instance
292
    SomeIpSdLoadBalancingOption(uint16_t priority, uint16_t weight);
293
294
    /// Construct a new Option object from already existing memory
295
    /// @param[in] dataContainer Data containing the option object
296
    /// @param[in] offset Offset for dataContainer
297
    SomeIpSdLoadBalancingOption(const IDataContainer* dataContainer, size_t offset);
298
299
    /// Get the priority fild
300
    /// @return uint16_t
301
    uint16_t getPriority() const;
302
303
    /// Get the weight field
304
    /// @return uint16_t
305
    uint16_t getWeight() const;
306
307
    /// Checks whether data is valid or not
308
    /// @return True if data is valid
309
    static bool isDataValid(const IDataContainer* data, size_t dataLen)
310
1.07k
    {
311
1.07k
      return data && dataLen >= sizeof(someipsdhdroptionsload);
312
1.07k
    }
313
314
  private:
315
    /// @struct someipsdhdroptionsload
316
    /// Represents the Load Balancing option header for SOME/IP-SD
317
#pragma pack(push, 1)
318
    struct someipsdhdroptionsload : someipsdhdroptionsbase
319
    {
320
      /// Priority field
321
      uint16_t priority;
322
      /// Weight field
323
      uint16_t weight;
324
    };
325
#pragma pack(pop)
326
    static_assert(sizeof(someipsdhdroptionsload) == 8, "someipsdhdroptionsload size is not 8 bytes");
327
  };
328
329
  /// @class SomeIpSdEntry
330
  /// Implementation of the SOME/IP-SD Service Entry and Eventgroup Entry Type
331
  class SomeIpSdEntry
332
  {
333
  public:
334
    friend class SomeIpSdLayer;
335
336
    /// Types of entries that can occur in SOME/IP-SD
337
    enum class EntryType : uint8_t
338
    {
339
      /// Find Service
340
      FindService,
341
      /// Offer Service
342
      OfferService,
343
      /// Stop Offer Service
344
      StopOfferService,
345
      /// Subscribe Eventgroup
346
      SubscribeEventgroup,
347
      /// Stop Subscribe Eventgroup
348
      StopSubscribeEventgroup,
349
      /// Subscribe Eventgroup Acknowledgment
350
      SubscribeEventgroupAck,
351
      /// Subscribe Eventgroup Negative Acknowledgement
352
      SubscribeEventgroupNack,
353
      /// Unknown Entry Type
354
      UnknownEntryType
355
    };
356
357
    /// @struct someipsdhdrentry
358
    /// Represents the Service Entry Type and Eventgroup Entry Type
359
#pragma pack(push, 1)
360
    struct someipsdhdrentry
361
    {
362
      /// Type
363
      uint8_t type;
364
      /// Index 1st option
365
      uint8_t indexFirstOption;
366
      /// Index 2nd option
367
      uint8_t indexSecondOption;
368
#if (BYTE_ORDER == LITTLE_ENDIAN)
369
      uint8_t
370
          /// Numbers of Option #2 (4bit)
371
          nrOpt2 : 4,
372
          /// Numbers of Option #1 (4bit)
373
          nrOpt1 : 4;
374
#else
375
      uint8_t
376
          /// Numbers of Option #1 (4bit)
377
          nrOpt1 : 4,
378
          /// Numbers of Option #2 (4bit)
379
          nrOpt2 : 4;
380
#endif
381
      /// Service ID
382
      uint16_t serviceID;
383
      /// Instance ID
384
      uint16_t instanceID;
385
      /// Major Version (8 bit) + TTL (24 bit)
386
      uint32_t majorVersion_ttl;
387
      /// Minor Version (Service Entry Type) or Counter + Eventgroup ID (Eventgroup Entry Type)
388
      uint32_t data;
389
    };
390
#pragma pack(pop)
391
    static_assert(sizeof(someipsdhdrentry) == 16, "someipsdhdrentry size is not 16 bytes");
392
393
    /// Construct a new SOME/IP-SD Service Entry Type
394
    /// @param[in] type Type to create
395
    /// @param[in] serviceID ServiceID to use
396
    /// @param[in] instanceID InstanceID to use
397
    /// @param[in] majorVersion MajorVersion to use
398
    /// @param[in] TTL TTL to use. Has to be 0 for all Stop* entry types
399
    /// @param[in] minorVersion MinorVersion to use
400
    SomeIpSdEntry(EntryType type, uint16_t serviceID, uint16_t instanceID, uint8_t majorVersion, uint32_t TTL,
401
                  uint32_t minorVersion);
402
403
    /// Construct a new SOME/IP-SD Eventgroup Entry Type
404
    /// @param[in] type Type to create
405
    /// @param[in] serviceID ServiceID to use
406
    /// @param[in] instanceID InstanceID to use
407
    /// @param[in] majorVersion MajorVersion to use
408
    /// @param[in] TTL TTL to use. Has to be 0 for all Stop* entry types
409
    /// @param[in] counter Counter value to use
410
    /// @param[in] eventGroupID EventgroupId to use
411
    SomeIpSdEntry(EntryType type, uint16_t serviceID, uint16_t instanceID, uint8_t majorVersion, uint32_t TTL,
412
                  uint8_t counter, uint16_t eventGroupID);
413
414
    /// Construct a new SomeIpSdEntry object from existing data
415
    /// @param[in] pSomeIpSdLayer Layer that this entry is created for
416
    /// @param[in] offset Offset for pSomeIpSdLayer
417
    SomeIpSdEntry(const SomeIpSdLayer* pSomeIpSdLayer, size_t offset);
418
419
    /// Destroy the SomeIpSd Entry object and delete allocated data if it has been allocated by a constructor
420
    ~SomeIpSdEntry();
421
422
    /// Get the internal data of the SOME/IP-SD Entry
423
    /// @return uint8_t*
424
    uint8_t* getDataPtr() const;
425
426
    /// Get a pointer to the SOME/IP-SD Entry header
427
    /// @return someipsdhdrentry*
428
    someipsdhdrentry* getSomeIpSdEntryHeader() const;
429
430
    /// Get the Entry Type
431
    /// @return EntryType
432
    EntryType getType() const
433
0
    {
434
0
      return m_EntryType;
435
0
    }
436
437
    /// Get the Length of the SomeIpSd Entry
438
    /// @return size_t
439
    size_t getLength() const
440
3.37k
    {
441
3.37k
      return sizeof(someipsdhdrentry);
442
3.37k
    }
443
444
    /// Get the number of Options of this Entry
445
    /// @return uint32_t
446
    uint32_t getNumOptions() const;
447
448
    /// Get the Service Id in host endianness
449
    /// @return uint16_t
450
    uint16_t getServiceId() const;
451
452
    /// Set the Service Id
453
    /// @param[in] serviceId
454
    void setServiceId(uint16_t serviceId);
455
456
    /// Get the Instance Id in host endianness
457
    /// @return uint16_t
458
    uint16_t getInstanceId() const;
459
460
    /// Set the Instance Id
461
    /// @param[in] instanceId
462
    void setInstanceId(uint16_t instanceId);
463
464
    /// Get the Major version field in host endianness
465
    /// @return uint16_t
466
    uint8_t getMajorVersion() const;
467
468
    /// Set the Major Version
469
    /// @param[in] majorVersion
470
    void setMajorVersion(uint8_t majorVersion);
471
472
    /// Get the Ttl field
473
    /// @return uint32_t
474
    uint32_t getTtl() const;
475
476
    /// Set the Ttl field
477
    /// @param[in] ttl
478
    void setTtl(uint32_t ttl);
479
480
    /// Get the minor version
481
    /// @return uint32_t
482
    uint32_t getMinorVersion() const;
483
484
    /// Set the minor version
485
    /// @param[in] minorVersion
486
    void setMinorVersion(uint32_t minorVersion);
487
488
    /// Get the counter value
489
    /// @return uint32_t
490
    uint8_t getCounter() const;
491
492
    /// Set the counter value
493
    /// @param[in] counter
494
    void setCounter(uint8_t counter);
495
496
    /// Get the eventgroup id
497
    /// @return uint32_t
498
    uint16_t getEventgroupId() const;
499
500
    /// Set the eventgroup id
501
    /// @param[in] eventgroupID
502
    void setEventgroupId(uint16_t eventgroupID);
503
504
  private:
505
    /// These are the entry types used by SOME/IP-SD. They cannot be used for parameter passing since the values
506
    /// are not unique.
507
    enum class TypeInternal : uint8_t
508
    {
509
      /// Find Service
510
      FindService_Internal = 0x00,
511
      /// Offer Service / Stop Offer Service
512
      OfferService_Internal = 0x01,
513
      /// Subscribe Eventgroup & Stop Subscribe Eventgroup
514
      SubscribeEventgroup_Internal = 0x06,
515
      /// Subscribe Eventgroup Acknowledgment / Negative Acknowledgement
516
      SubscribeEventgroupAck_Internal = 0x07,
517
    };
518
519
    EntryType m_EntryType;
520
    const SomeIpSdLayer* m_Layer;
521
    size_t m_Offset;
522
    uint8_t* m_ShadowData;
523
524
    void initStdFields(EntryType type, uint16_t serviceID, uint16_t instanceID, uint8_t majorVersion, uint32_t TTL);
525
526
    SomeIpSdEntry(const SomeIpSdEntry&) = delete;
527
    SomeIpSdEntry& operator=(const SomeIpSdEntry&) = delete;
528
529
    static const uint32_t SOMEIPSD_HDR_ENTRY_MASK_TTL = 0x00FFFFFF;
530
  };
531
532
  /// @class SomeIpSdLayer
533
  /// Implementation of the SOME/IP-SD protocol
534
  class SomeIpSdLayer : public SomeIpLayer
535
  {
536
  public:
537
    friend class SomeIpSdEntry;
538
539
    using EntryPtr = SomeIpSdEntry*;
540
    using EntriesVec = std::vector<EntryPtr>;
541
    using OptionPtr = SomeIpSdOption*;
542
    using OptionsVec = std::vector<OptionPtr>;
543
544
    /// A constructor that creates the layer from an existing packet raw data
545
    /// @param[in] data A pointer to the raw data
546
    /// @param[in] dataLen Size of the data in bytes
547
    /// @param[in] prevLayer A pointer to the previous layer
548
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
549
    SomeIpSdLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
550
551
    /// Construct a new SomeIpSdLayer object
552
    /// @param[in] serviceID Service ID
553
    /// @param[in] methodID Method ID
554
    /// @param[in] clientID Client ID
555
    /// @param[in] sessionID Session ID
556
    /// @param[in] interfaceVersion Interface Version
557
    /// @param[in] type Type of the message
558
    /// @param[in] returnCode Return Code
559
    /// @param[in] flags Flags that shall be used in the header
560
    SomeIpSdLayer(uint16_t serviceID, uint16_t methodID, uint16_t clientID, uint16_t sessionID,
561
                  uint8_t interfaceVersion, MsgType type, uint8_t returnCode, uint8_t flags);
562
563
    /// Destroy the layer object
564
    ~SomeIpSdLayer() override = default;
565
566
    /// Checks if given port is a SOME/IP-SD protocol port
567
    /// @param[in] port Port to check
568
    /// @return true if SOME/IP-SD protocol port, false if not
569
    static bool isSomeIpSdPort(uint16_t port)
570
412k
    {
571
412k
      return port == 30490;
572
412k
    }
573
574
    /// The static method makes validation of input data
575
    /// @param[in] data The pointer to the beginning of byte stream of IP packet
576
    /// @param[in] dataLen The length of byte stream
577
    /// @return True if the data is valid and can represent the packet
578
    static bool isDataValid(const uint8_t* data, size_t dataLen);
579
580
    /// Get the Flags of the layer
581
    /// @return uint8_t Flags
582
    uint8_t getFlags() const;
583
584
    /// Set the Flags of the layer
585
    /// @param[in] flags Flags to set
586
    void setFlags(uint8_t flags);
587
588
    /// Get the number of entries in this layer
589
    /// @return uint32_t
590
    uint32_t getNumEntries() const;
591
592
    /// Get the number of options in this layer
593
    /// @return uint32_t
594
    uint32_t getNumOptions() const;
595
596
    /// Get the Entries from this layer
597
    /// @return EntriesVec Vector holding pointers to the options
598
    const EntriesVec getEntries() const;
599
600
    /// Get the Options from this layer
601
    /// @return OptionsVec Vector holding pointers to the options
602
    const OptionsVec getOptions() const;
603
604
    /// Get the Options from a specific Entry
605
    /// @param[in] index Index of the Entry, starting with 0.
606
    /// @return OptionsVec Vector holding pointers to the options
607
    const OptionsVec getOptionsFromEntry(uint32_t index) const;
608
609
    /// Adds a given entry to the layer and returns the index of the entry
610
    /// @param[in] entry Pointer to the entry that shall be added to the layer
611
    /// @return uint32_t Returns the index of the entry starting with 0
612
    uint32_t addEntry(const SomeIpSdEntry& entry);
613
614
    /// Adds an option to an entry that has already been added to the layer by using addEntry(). The option
615
    /// is also added to the layer itself. If the option cannot by assigned to the entry, the option is not
616
    /// copied into the layer.
617
    /// @param[in] indexEntry Index of the entry where the option shall be added. First Entry has index 0
618
    /// @param[in] option Pointer to the option that shall be added
619
    /// @return True if the option could be assigned to the entry and was copied into the layer, false otherwise
620
    bool addOptionTo(uint32_t indexEntry, const SomeIpSdOption& option);
621
622
    /// Does nothing for this layer
623
3.45k
    void computeCalculateFields() override {};
624
625
    /// @return The string representation of the SOME/IP-SD layer
626
    std::string toString() const override;
627
628
  private:
629
    /// @struct someipsdhdr
630
    /// Represents an SOME/IP-SD protocol header
631
#pragma pack(push, 1)
632
    struct someipsdhdr : someiphdr
633
    {
634
      /// Flags (8 bit)
635
      uint8_t flags;
636
      /// Reserved1 field (Bits 0-7 of 24-bits reserved field)
637
      uint8_t reserved1;
638
      /// Reserved2 field (Bits 8-15 of 24-bits reserved field)
639
      uint8_t reserved2;
640
      /// Reserved3 field (Bits 16-23 of 24-bits reserved field)
641
      uint8_t reserved3;
642
    };
643
#pragma pack(pop)
644
    static_assert(sizeof(someipsdhdr) == 20, "someipsdhdr size is not 20 bytes");
645
646
    uint32_t m_NumOptions;
647
648
    static bool countOptions(uint32_t& count, const uint8_t* data);
649
    uint32_t findOption(const SomeIpSdOption& option);
650
    void addOption(const SomeIpSdOption& option);
651
    bool addOptionIndex(uint32_t indexEntry, uint32_t indexOffset);
652
    OptionPtr parseOption(SomeIpSdOption::OptionType type, size_t offset, size_t remainingLength) const;
653
654
    static size_t getLenEntries(const uint8_t* data);
655
    size_t getLenEntries() const;
656
    static size_t getLenOptions(const uint8_t* data);
657
    size_t getLenOptions() const;
658
    void setLenEntries(uint32_t length);
659
    void setLenOptions(uint32_t length);
660
  };
661
}  // namespace pcpp