VBVX 0.1.0
Header-only C++23 library for safe, zero-copy parsing of packet buffers.
Loading...
Searching...
No Matches
srv6_header.hxx
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <span>
5
6#include "utils.hxx"
7
8namespace vbvx {
9
11enum class SRv6TlvType : uint8_t { Pad1 = 0u, PadN = 4u, Hmac = 5u };
12
21struct [[gnu::packed]] SRv6Header {
22 uint8_t next_header;
23 uint8_t hdr_ext_len;
24 uint8_t routing_type;
26 uint8_t last_entry;
27 uint8_t flags;
28 uint16_t tag_be;
29
30 constexpr auto header_length_bytes() const noexcept -> uint16_t {
31 return ((static_cast<uint16_t>(hdr_ext_len) + 1u) * 8u);
32 }
33
34 constexpr auto last_entry_index() const noexcept -> uint8_t {
35 return last_entry;
36 }
37
38 constexpr auto segments_count() const noexcept -> uint8_t {
39 return static_cast<uint8_t>(static_cast<uint8_t>(last_entry) + 1u);
40 }
41
42 constexpr auto tag() const noexcept -> uint16_t { return autoswap(tag_be); }
43
44 constexpr auto routing_type_value() const noexcept -> uint8_t {
45 return routing_type;
46 }
47
48 constexpr bool is_valid_routing_type() const noexcept {
49 return routing_type == 4u;
50 }
51
52 constexpr auto segment_list_ptr() const noexcept -> const uint8_t* {
53 return reinterpret_cast<const uint8_t*>(this) + 8u;
54 }
55
56 constexpr auto segment_at(uint8_t idx) const noexcept
57 -> std::span<const uint8_t, 16> {
58 return std::span<const uint8_t, 16>{
59 segment_list_ptr() + (static_cast<uint16_t>(idx) * 16u), 16u};
60 }
61
62 constexpr auto segment_list_bytes_len() const noexcept -> uint16_t {
63 return static_cast<uint16_t>(segments_count()) * 16u;
64 }
65
66 constexpr auto tlv_offset() const noexcept -> uint16_t {
67 return 8u + segment_list_bytes_len();
68 }
69
70 constexpr auto tlv_bytes_len() const noexcept -> uint16_t {
71 auto total = header_length_bytes();
72 if (total <= tlv_offset()) {
73 return 0u;
74 }
75 return total - tlv_offset();
76 }
77
78 constexpr auto tlv_first_ptr() const noexcept -> const uint8_t* {
79 return reinterpret_cast<const uint8_t*>(this) + tlv_offset();
80 }
81};
82
84struct SRv6Tlv {
85 uint8_t type;
86 uint8_t length;
87 const uint8_t* value;
88 uint16_t total_len;
89};
90
93public:
94 constexpr SRv6TlvIterator(const uint8_t* ptr, uint16_t len) noexcept
95 : ptr_{ptr}, len_{len}, pos_{0} {}
96
97 constexpr bool next(SRv6Tlv& out) noexcept {
98 if (pos_ >= len_) {
99 return false;
100 }
101
102 const uint8_t t = ptr_[pos_];
103 if (t == static_cast<uint8_t>(SRv6TlvType::Pad1)) {
104 out = SRv6Tlv{t, 0, nullptr, 1u};
105 pos_ += 1u;
106 return true;
107 }
108
109 // Need at least type + length
110 if (pos_ + 2u > len_) {
111 return false;
112 }
113
114 const uint8_t len = ptr_[pos_ + 1u];
115 if (static_cast<uint16_t>(pos_ + 2u + len) > len_) {
116 return false;
117 }
118
119 out = SRv6Tlv{t, len, ptr_ + pos_ + 2u, static_cast<uint16_t>(2u + len)};
120 pos_ += out.total_len;
121 return true;
122 }
123
124private:
125 const uint8_t* ptr_;
126 uint16_t len_;
127 uint16_t pos_;
128};
129
136 const uint8_t* value;
137 uint8_t length;
138
139 constexpr bool valid() const noexcept { return value && (length >= 6u); }
140
141 constexpr bool d_bit() const noexcept {
142 if (!valid())
143 return false;
144
145 uint16_t b = read_from_bytes<uint16_t>(value);
146 return ((autoswap(b) >> 15) & 0x1u) != 0u;
147 }
148
149 constexpr auto key_id() const noexcept -> uint32_t {
150 if (!valid())
151 return 0u;
152
153 uint32_t v = read_from_bytes<uint32_t>(value + 2u);
154 return autoswap(v);
155 }
156
157 constexpr auto hmac() const noexcept -> std::span<const uint8_t> {
158 if (!valid())
159 return {};
160 const uint8_t* p = value + 6u;
161 return std::span<const uint8_t>{p, static_cast<uint16_t>(length - 6u)};
162 }
163};
164
165static_assert(sizeof(SRv6Header) == 8, "Wrong SRH header size");
166static_assert(alignof(SRv6Header) == 1, "Wrong SRH header alignment");
167
168} // namespace vbvx
constexpr SRv6TlvIterator(const uint8_t *ptr, uint16_t len) noexcept
Definition srv6_header.hxx:94
constexpr bool next(SRv6Tlv &out) noexcept
Definition srv6_header.hxx:97
Definition arp.hxx:11
SRv6TlvType
SRv6 Segment Routing Header (SRH) TLV types.
Definition srv6_header.hxx:11
@ Hmac
Definition srv6_header.hxx:11
@ PadN
Definition srv6_header.hxx:11
@ Pad1
Definition srv6_header.hxx:11
constexpr _Tp read_from_bytes(const uint8_t *src)
Read a trivially copyable type from a byte array.
Definition utils.hxx:24
constexpr _Tp autoswap(_Tp tp)
Byte-swap a value if the host is little-endian.
Definition utils.hxx:13
IPv6 Segment Routing Header (SRH) as defined in RFC 8754.
Definition srv6_header.hxx:21
constexpr auto tag() const noexcept -> uint16_t
Definition srv6_header.hxx:42
constexpr auto segments_count() const noexcept -> uint8_t
Definition srv6_header.hxx:38
constexpr auto routing_type_value() const noexcept -> uint8_t
Definition srv6_header.hxx:44
uint8_t flags
Definition srv6_header.hxx:27
constexpr auto tlv_bytes_len() const noexcept -> uint16_t
Definition srv6_header.hxx:70
uint8_t next_header
Definition srv6_header.hxx:22
constexpr auto last_entry_index() const noexcept -> uint8_t
Definition srv6_header.hxx:34
uint16_t tag_be
Definition srv6_header.hxx:28
uint8_t hdr_ext_len
Definition srv6_header.hxx:23
uint8_t last_entry
Definition srv6_header.hxx:26
constexpr auto tlv_offset() const noexcept -> uint16_t
Definition srv6_header.hxx:66
uint8_t segments_left
Definition srv6_header.hxx:25
constexpr auto segment_list_ptr() const noexcept -> const uint8_t *
Definition srv6_header.hxx:52
constexpr auto segment_list_bytes_len() const noexcept -> uint16_t
Definition srv6_header.hxx:62
constexpr bool is_valid_routing_type() const noexcept
Definition srv6_header.hxx:48
constexpr auto segment_at(uint8_t idx) const noexcept -> std::span< const uint8_t, 16 >
Definition srv6_header.hxx:56
uint8_t routing_type
Definition srv6_header.hxx:24
constexpr auto header_length_bytes() const noexcept -> uint16_t
Definition srv6_header.hxx:30
constexpr auto tlv_first_ptr() const noexcept -> const uint8_t *
Definition srv6_header.hxx:78
HMAC TLV view for type==5 (HMAC). The 'value' pointer is the TLV variable data where the first two by...
Definition srv6_header.hxx:135
uint8_t length
Definition srv6_header.hxx:137
constexpr bool valid() const noexcept
Definition srv6_header.hxx:139
const uint8_t * value
Definition srv6_header.hxx:136
constexpr bool d_bit() const noexcept
Definition srv6_header.hxx:141
constexpr auto key_id() const noexcept -> uint32_t
Definition srv6_header.hxx:149
constexpr auto hmac() const noexcept -> std::span< const uint8_t >
Definition srv6_header.hxx:157
TLV view returned by the iterator.
Definition srv6_header.hxx:84
uint16_t total_len
Definition srv6_header.hxx:88
uint8_t type
Definition srv6_header.hxx:85
const uint8_t * value
Definition srv6_header.hxx:87
uint8_t length
Definition srv6_header.hxx:86