Coverage Report

Created: 2025-07-11 07:47

/src/PcapPlusPlus/Packet++/header/SomeIpSdLayer.h
Line
Count
Source (jump to first uncovered line)
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
1.28k
        : m_DataContainer(dataContainer), m_Offset(offset), m_ShadowData(nullptr), m_DataLen(0)
108
1.28k
    {}
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
  private:
159
    /// @struct someipsdhdroptionsipv4
160
    /// Represents the IPv4 option types for the SOME/IP-SD header
161
#pragma pack(push, 1)
162
    struct someipsdhdroptionsipv4 : someipsdhdroptionsbase
163
    {
164
      /// IPv4-Address field
165
      uint32_t ipv4Address;
166
      // cppcheck-suppress duplInheritedMember
167
      /// Reserved
168
      uint8_t reserved;
169
      /// Layer 4 Protocol field (L4-Proto) - Either UDP or TCP
170
      SomeIpSdProtocolType l4Protocol;
171
      /// Port number of UDP or TCP
172
      uint16_t portNumber;
173
    };
174
#pragma pack(pop)
175
    static_assert(sizeof(someipsdhdroptionsipv4) == 12, "someipsdhdroptionsipv4 size is not 12 bytes");
176
  };
177
178
  /// @class SomeIpSdIPv6Option
179
  /// Implements the following SOME/IP-SD Options: IPv6 Endpoint, IPv6 Multicast, IPv6 SD Endpoint
180
  class SomeIpSdIPv6Option : public SomeIpSdOption
181
  {
182
  public:
183
    friend class SomeIpSdLayer;
184
185
    /// Types of options which are implemented with this class
186
    enum IPv6OptionType
187
    {
188
      /// IPv6 Endpoint Option
189
      IPv6Endpoint,
190
      /// IPv6 Multicast Option
191
      IPv6Multicast,
192
      /// IPv6 SD Endpoint Option
193
      IPv6SdEndpoint,
194
    };
195
196
    /// Construct a new SomeIpSdIPv6 Option object
197
    /// @param[in] type IPv6 Option type
198
    /// @param[in] ipAddress Ipv6 address to use
199
    /// @param[in] port Port to use
200
    /// @param[in] l4Protocol Protocol to use
201
    SomeIpSdIPv6Option(IPv6OptionType type, IPv6Address ipAddress, uint16_t port, SomeIpSdProtocolType l4Protocol);
202
203
    /// Construct a new SomeIpSdIPv6 Option object from already existing memory
204
    /// @param[in] dataContainer Data containing the SomeIpSdIPv6 Option object
205
    /// @param[in] offset Offset for dataContainer
206
    SomeIpSdIPv6Option(const IDataContainer* dataContainer, size_t offset);
207
208
    /// Get the Ip Address
209
    /// @return IPv6Address
210
    IPv6Address getIpAddress() const;
211
212
    /// Get the Port
213
    /// @return uint16_t
214
    uint16_t getPort() const;
215
216
    /// Get the Protocol
217
    /// @return SomeIpSdProtocolType
218
    SomeIpSdProtocolType getProtocol() const;
219
220
  private:
221
    /// @struct someipsdhdroptionsipv6
222
    /// Represents the IPv6 option types for the SOME/IP-SD header
223
#pragma pack(push, 1)
224
    struct someipsdhdroptionsipv6 : someipsdhdroptionsbase
225
    {
226
      /// IPv6-Address field
227
      uint8_t ipv6Address[16];
228
      // cppcheck-suppress duplInheritedMember
229
      /// Reserved
230
      uint8_t reserved;
231
      /// Layer 4 Protocol field (L4-Proto) - Either UDP or TCP
232
      SomeIpSdProtocolType l4Protocol;
233
      /// Port number of UDP or TCP
234
      uint16_t portNumber;
235
    };
236
#pragma pack(pop)
237
    static_assert(sizeof(someipsdhdroptionsipv6) == 24, "someipsdhdroptionsipv6 size is not 24 bytes");
238
  };
239
240
  /// @class SomeIpSdConfigurationOption
241
  /// Implements the Configuration option of SOME/IP-SD protocol
242
  class SomeIpSdConfigurationOption : public SomeIpSdOption
243
  {
244
  public:
245
    friend class SomeIpSdLayer;
246
247
    /// Construct a new Configuration Option object
248
    /// @param[in] configurationString the configuration string
249
    explicit SomeIpSdConfigurationOption(const std::string& configurationString);
250
251
    /// Construct a new Configuration Option object from already existing memory
252
    /// @param[in] dataContainer Data containing the Configuration Option object
253
    /// @param[in] offset Offset for dataContainer
254
    SomeIpSdConfigurationOption(const IDataContainer* dataContainer, size_t offset);
255
256
    /// Get the configuration string
257
    /// @return std::string
258
    std::string getConfigurationString() const;
259
  };
260
261
  /// @class SomeIpSdLoadBalancingOption
262
  /// Implements the Load Balancing option of SOME/IP-SD protocol
263
  class SomeIpSdLoadBalancingOption : public SomeIpSdOption
264
  {
265
  public:
266
    friend class SomeIpSdLayer;
267
268
    /// Construct a new Load Balancing object
269
    /// @param[in] priority Priority of this instance
270
    /// @param[in] weight Weight of this instance
271
    SomeIpSdLoadBalancingOption(uint16_t priority, uint16_t weight);
272
273
    /// Construct a new Option object from already existing memory
274
    /// @param[in] dataContainer Data containing the option object
275
    /// @param[in] offset Offset for dataContainer
276
    SomeIpSdLoadBalancingOption(const IDataContainer* dataContainer, size_t offset);
277
278
    /// Get the priority fild
279
    /// @return uint16_t
280
    uint16_t getPriority() const;
281
282
    /// Get the weight field
283
    /// @return uint16_t
284
    uint16_t getWeight() const;
285
286
  private:
287
    /// @struct someipsdhdroptionsload
288
    /// Represents the Load Balancing option header for SOME/IP-SD
289
#pragma pack(push, 1)
290
    struct someipsdhdroptionsload : someipsdhdroptionsbase
291
    {
292
      /// Priority field
293
      uint16_t priority;
294
      /// Weight field
295
      uint16_t weight;
296
    };
297
#pragma pack(pop)
298
    static_assert(sizeof(someipsdhdroptionsload) == 8, "someipsdhdroptionsload size is not 8 bytes");
299
  };
300
301
  /// @class SomeIpSdEntry
302
  /// Implementation of the SOME/IP-SD Service Entry and Eventgroup Entry Type
303
  class SomeIpSdEntry
304
  {
305
  public:
306
    friend class SomeIpSdLayer;
307
308
    /// Types of entries that can occur in SOME/IP-SD
309
    enum class EntryType : uint8_t
310
    {
311
      /// Find Service
312
      FindService,
313
      /// Offer Service
314
      OfferService,
315
      /// Stop Offer Service
316
      StopOfferService,
317
      /// Subscribe Eventgroup
318
      SubscribeEventgroup,
319
      /// Stop Subscribe Eventgroup
320
      StopSubscribeEventgroup,
321
      /// Subscribe Eventgroup Acknowledgment
322
      SubscribeEventgroupAck,
323
      /// Subscribe Eventgroup Negative Acknowledgement
324
      SubscribeEventgroupNack,
325
      /// Unknown Entry Type
326
      UnknownEntryType
327
    };
328
329
    /// @struct someipsdhdrentry
330
    /// Represents the Service Entry Type and Eventgroup Entry Type
331
#pragma pack(push, 1)
332
    struct someipsdhdrentry
333
    {
334
      /// Type
335
      uint8_t type;
336
      /// Index 1st option
337
      uint8_t indexFirstOption;
338
      /// Index 2nd option
339
      uint8_t indexSecondOption;
340
#if (BYTE_ORDER == LITTLE_ENDIAN)
341
      uint8_t
342
          /// Numbers of Option #2 (4bit)
343
          nrOpt2 : 4,
344
          /// Numbers of Option #1 (4bit)
345
          nrOpt1 : 4;
346
#else
347
      uint8_t
348
          /// Numbers of Option #1 (4bit)
349
          nrOpt1 : 4,
350
          /// Numbers of Option #2 (4bit)
351
          nrOpt2 : 4;
352
#endif
353
      /// Service ID
354
      uint16_t serviceID;
355
      /// Instance ID
356
      uint16_t instanceID;
357
      /// Major Version (8 bit) + TTL (24 bit)
358
      uint32_t majorVersion_ttl;
359
      /// Minor Version (Service Entry Type) or Counter + Eventgroup ID (Eventgroup Entry Type)
360
      uint32_t data;
361
    };
362
#pragma pack(pop)
363
    static_assert(sizeof(someipsdhdrentry) == 16, "someipsdhdrentry size is not 16 bytes");
364
365
    /// Construct a new SOME/IP-SD Service Entry Type
366
    /// @param[in] type Type to create
367
    /// @param[in] serviceID ServiceID to use
368
    /// @param[in] instanceID InstanceID to use
369
    /// @param[in] majorVersion MajorVersion to use
370
    /// @param[in] TTL TTL to use. Has to be 0 for all Stop* entry types
371
    /// @param[in] minorVersion MinorVersion to use
372
    SomeIpSdEntry(EntryType type, uint16_t serviceID, uint16_t instanceID, uint8_t majorVersion, uint32_t TTL,
373
                  uint32_t minorVersion);
374
375
    /// Construct a new SOME/IP-SD Eventgroup Entry Type
376
    /// @param[in] type Type to create
377
    /// @param[in] serviceID ServiceID to use
378
    /// @param[in] instanceID InstanceID to use
379
    /// @param[in] majorVersion MajorVersion to use
380
    /// @param[in] TTL TTL to use. Has to be 0 for all Stop* entry types
381
    /// @param[in] counter Counter value to use
382
    /// @param[in] eventGroupID EventgroupId to use
383
    SomeIpSdEntry(EntryType type, uint16_t serviceID, uint16_t instanceID, uint8_t majorVersion, uint32_t TTL,
384
                  uint8_t counter, uint16_t eventGroupID);
385
386
    /// Construct a new SomeIpSdEntry object from existing data
387
    /// @param[in] pSomeIpSdLayer Layer that this entry is created for
388
    /// @param[in] offset Offset for pSomeIpSdLayer
389
    SomeIpSdEntry(const SomeIpSdLayer* pSomeIpSdLayer, size_t offset);
390
391
    /// Destroy the SomeIpSd Entry object and delete allocated data if it has been allocated by a constructor
392
    ~SomeIpSdEntry();
393
394
    /// Get the internal data of the SOME/IP-SD Entry
395
    /// @return uint8_t*
396
    uint8_t* getDataPtr() const;
397
398
    /// Get a pointer to the SOME/IP-SD Entry header
399
    /// @return someipsdhdrentry*
400
    someipsdhdrentry* getSomeIpSdEntryHeader() const;
401
402
    /// Get the Entry Type
403
    /// @return EntryType
404
    EntryType getType() const
405
0
    {
406
0
      return m_EntryType;
407
0
    }
408
409
    /// Get the Length of the SomeIpSd Entry
410
    /// @return size_t
411
    size_t getLength() const
412
842
    {
413
842
      return sizeof(someipsdhdrentry);
414
842
    }
415
416
    /// Get the number of Options of this Entry
417
    /// @return uint32_t
418
    uint32_t getNumOptions() const;
419
420
    /// Get the Service Id in host endianness
421
    /// @return uint16_t
422
    uint16_t getServiceId() const;
423
424
    /// Set the Service Id
425
    /// @param[in] serviceId
426
    void setServiceId(uint16_t serviceId);
427
428
    /// Get the Instance Id in host endianness
429
    /// @return uint16_t
430
    uint16_t getInstanceId() const;
431
432
    /// Set the Instance Id
433
    /// @param[in] instanceId
434
    void setInstanceId(uint16_t instanceId);
435
436
    /// Get the Major version field in host endianness
437
    /// @return uint16_t
438
    uint8_t getMajorVersion() const;
439
440
    /// Set the Major Version
441
    /// @param[in] majorVersion
442
    void setMajorVersion(uint8_t majorVersion);
443
444
    /// Get the Ttl field
445
    /// @return uint32_t
446
    uint32_t getTtl() const;
447
448
    /// Set the Ttl field
449
    /// @param[in] ttl
450
    void setTtl(uint32_t ttl);
451
452
    /// Get the minor version
453
    /// @return uint32_t
454
    uint32_t getMinorVersion() const;
455
456
    /// Set the minor version
457
    /// @param[in] minorVersion
458
    void setMinorVersion(uint32_t minorVersion);
459
460
    /// Get the counter value
461
    /// @return uint32_t
462
    uint8_t getCounter() const;
463
464
    /// Set the counter value
465
    /// @param[in] counter
466
    void setCounter(uint8_t counter);
467
468
    /// Get the eventgroup id
469
    /// @return uint32_t
470
    uint16_t getEventgroupId() const;
471
472
    /// Set the eventgroup id
473
    /// @param[in] eventgroupID
474
    void setEventgroupId(uint16_t eventgroupID);
475
476
  private:
477
    /// These are the entry types used by SOME/IP-SD. They cannot be used for parameter passing since the values
478
    /// are not unique.
479
    enum class TypeInternal : uint8_t
480
    {
481
      /// Find Service
482
      FindService_Internal = 0x00,
483
      /// Offer Service / Stop Offer Service
484
      OfferService_Internal = 0x01,
485
      /// Subscribe Eventgroup & Stop Subscribe Eventgroup
486
      SubscribeEventgroup_Internal = 0x06,
487
      /// Subscribe Eventgroup Acknowledgment / Negative Acknowledgement
488
      SubscribeEventgroupAck_Internal = 0x07,
489
    };
490
491
    EntryType m_EntryType;
492
    const SomeIpSdLayer* m_Layer;
493
    size_t m_Offset;
494
    uint8_t* m_ShadowData;
495
496
    void initStdFields(EntryType type, uint16_t serviceID, uint16_t instanceID, uint8_t majorVersion, uint32_t TTL);
497
498
    SomeIpSdEntry(const SomeIpSdEntry&) = delete;
499
    SomeIpSdEntry& operator=(const SomeIpSdEntry&) = delete;
500
501
    static const uint32_t SOMEIPSD_HDR_ENTRY_MASK_TTL = 0x00FFFFFF;
502
  };
503
504
  /// @class SomeIpSdLayer
505
  /// Implementation of the SOME/IP-SD protocol
506
  class SomeIpSdLayer : public SomeIpLayer
507
  {
508
  public:
509
    friend class SomeIpSdEntry;
510
511
    typedef SomeIpSdEntry* EntryPtr;
512
    typedef std::vector<EntryPtr> EntriesVec;
513
    typedef SomeIpSdOption* OptionPtr;
514
    typedef std::vector<OptionPtr> OptionsVec;
515
516
    /// A constructor that creates the layer from an existing packet raw data
517
    /// @param[in] data A pointer to the raw data
518
    /// @param[in] dataLen Size of the data in bytes
519
    /// @param[in] prevLayer A pointer to the previous layer
520
    /// @param[in] packet A pointer to the Packet instance where layer will be stored in
521
    SomeIpSdLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
522
523
    /// Construct a new SomeIpSdLayer object
524
    /// @param[in] serviceID Service ID
525
    /// @param[in] methodID Method ID
526
    /// @param[in] clientID Client ID
527
    /// @param[in] sessionID Session ID
528
    /// @param[in] interfaceVersion Interface Version
529
    /// @param[in] type Type of the message
530
    /// @param[in] returnCode Return Code
531
    /// @param[in] flags Flags that shall be used in the header
532
    SomeIpSdLayer(uint16_t serviceID, uint16_t methodID, uint16_t clientID, uint16_t sessionID,
533
                  uint8_t interfaceVersion, MsgType type, uint8_t returnCode, uint8_t flags);
534
535
    /// Destroy the layer object
536
    ~SomeIpSdLayer() override = default;
537
538
    /// Checks if given port is a SOME/IP-SD protocol port
539
    /// @param[in] port Port to check
540
    /// @return true if SOME/IP-SD protocol port, false if not
541
    static bool isSomeIpSdPort(uint16_t port)
542
146k
    {
543
146k
      return port == 30490;
544
146k
    }
545
546
    /// The static method makes validation of input data
547
    /// @param[in] data The pointer to the beginning of byte stream of IP packet
548
    /// @param[in] dataLen The length of byte stream
549
    /// @return True if the data is valid and can represent the packet
550
    static bool isDataValid(const uint8_t* data, size_t dataLen);
551
552
    /// Get the Flags of the layer
553
    /// @return uint8_t Flags
554
    uint8_t getFlags() const;
555
556
    /// Set the Flags of the layer
557
    /// @param[in] flags Flags to set
558
    void setFlags(uint8_t flags);
559
560
    /// Get the number of entries in this layer
561
    /// @return uint32_t
562
    uint32_t getNumEntries() const;
563
564
    /// Get the number of options in this layer
565
    /// @return uint32_t
566
    uint32_t getNumOptions() const;
567
568
    /// Get the Entries from this layer
569
    /// @return EntriesVec Vector holding pointers to the options
570
    const EntriesVec getEntries() const;
571
572
    /// Get the Options from this layer
573
    /// @return OptionsVec Vector holding pointers to the options
574
    const OptionsVec getOptions() const;
575
576
    /// Get the Options from a specific Entry
577
    /// @param[in] index Index of the Entry, starting with 0.
578
    /// @return OptionsVec Vector holding pointers to the options
579
    const OptionsVec getOptionsFromEntry(uint32_t index) const;
580
581
    /// Adds a given entry to the layer and returns the index of the entry
582
    /// @param[in] entry Pointer to the entry that shall be added to the layer
583
    /// @return uint32_t Returns the index of the entry starting with 0
584
    uint32_t addEntry(const SomeIpSdEntry& entry);
585
586
    /// Adds an option to an entry that has already been added to the layer by using addEntry(). The option
587
    /// is also added to the layer itself. If the option cannot by assigned to the entry, the option is not
588
    /// copied into the layer.
589
    /// @param[in] indexEntry Index of the entry where the option shall be added. First Entry has index 0
590
    /// @param[in] option Pointer to the option that shall be added
591
    /// @return True if the option could be assigned to the entry and was copied into the layer, false otherwise
592
    bool addOptionTo(uint32_t indexEntry, const SomeIpSdOption& option);
593
594
    /// Does nothing for this layer
595
842
    void computeCalculateFields() override {};
596
597
    /// @return The string representation of the SOME/IP-SD layer
598
    std::string toString() const override;
599
600
  private:
601
    /// @struct someipsdhdr
602
    /// Represents an SOME/IP-SD protocol header
603
#pragma pack(push, 1)
604
    struct someipsdhdr : someiphdr
605
    {
606
      /// Flags (8 bit)
607
      uint8_t flags;
608
      /// Reserved1 field (Bits 0-7 of 24-bits reserved field)
609
      uint8_t reserved1;
610
      /// Reserved2 field (Bits 8-15 of 24-bits reserved field)
611
      uint8_t reserved2;
612
      /// Reserved3 field (Bits 16-23 of 24-bits reserved field)
613
      uint8_t reserved3;
614
    };
615
#pragma pack(pop)
616
    static_assert(sizeof(someipsdhdr) == 20, "someipsdhdr size is not 20 bytes");
617
618
    uint32_t m_NumOptions;
619
620
    static bool countOptions(uint32_t& count, const uint8_t* data);
621
    uint32_t findOption(const SomeIpSdOption& option);
622
    void addOption(const SomeIpSdOption& option);
623
    bool addOptionIndex(uint32_t indexEntry, uint32_t indexOffset);
624
    OptionPtr parseOption(SomeIpSdOption::OptionType type, size_t offset) const;
625
626
    static size_t getLenEntries(const uint8_t* data);
627
    size_t getLenEntries() const;
628
    static size_t getLenOptions(const uint8_t* data);
629
    size_t getLenOptions() const;
630
    void setLenEntries(uint32_t length);
631
    void setLenOptions(uint32_t length);
632
  };
633
}  // namespace pcpp