VBVX 0.1.0
Header-only C++23 library for safe, zero-copy parsing of packet buffers.
Loading...
Searching...
No Matches
ip4_header.hxx
Go to the documentation of this file.
1#pragma once
2
3#include <bit>
4#include <cstdint>
5#include <type_traits>
6#include <utility>
7
8#include "utils.hxx"
9#include "ip_protocol.hxx"
10#include "flags_view.hxx"
11
12namespace vbvx {
13
14static constexpr uint16_t FRAG_FLAGS_MASK = 0xE000u;
15static constexpr uint16_t FRAG_OFFSET_MASK = 0x1FFFu;
16
18enum class IPv4Flags : uint16_t {
19 None = 0,
20 MF = 0x2000, // More Fragments
21 DF = 0x4000, // Don't Fragment
22 RFU = 0x8000 // Reserved (must be zero)
23};
24
25template <> struct enable_bitmask_operators<IPv4Flags> : std::true_type {};
26
35struct [[gnu::packed]] IPv4Header {
36 uint8_t version_ihl;
37 uint8_t tos;
39 uint16_t id_be;
40 uint16_t frag_off_be;
41 uint8_t ttl;
42 uint8_t protocol;
43 uint16_t checksum_be;
44 uint32_t src_addr_be;
45 uint32_t dst_addr_be;
46
47 constexpr auto version() const noexcept -> uint8_t {
48 return (version_ihl >> 4) & 0x0Fu;
49 }
50
51 constexpr auto ihl_words() const noexcept -> uint16_t {
52 return version_ihl & 0x0Fu;
53 }
54
55 constexpr auto ihl_bytes() const noexcept -> uint16_t {
56 return ihl_words() * 4u;
57 }
58
59 constexpr auto dscp() const noexcept -> uint8_t { return (tos >> 2) & 0x3Fu; }
60 constexpr auto ecn() const noexcept -> uint8_t { return tos & 0x03u; }
61
62 constexpr auto total_length() const noexcept -> uint16_t {
64 }
65
66 constexpr auto id() const noexcept -> uint16_t { return autoswap(id_be); }
67
68 constexpr auto frag_off() const noexcept -> uint16_t {
69 return autoswap(frag_off_be);
70 }
71
72 constexpr auto frag_flags() const noexcept -> IPv4Flags {
73 return static_cast<IPv4Flags>(frag_off() & FRAG_FLAGS_MASK);
74 }
75
76 constexpr bool has_flag(IPv4Flags flag) const noexcept {
77 return (frag_flags() & flag) != IPv4Flags::None;
78 }
79
80 constexpr auto frag_offset_units8() const noexcept -> uint16_t {
81 return static_cast<uint16_t>(frag_off() & FRAG_OFFSET_MASK);
82 }
83
84 constexpr auto frag_offset_bytes() const noexcept -> uint16_t {
85 return static_cast<uint16_t>(frag_offset_units8() * 8u);
86 }
87
88 constexpr bool is_fragmented() const noexcept {
90 }
91
92 constexpr void set_frag_flags(IPv4Flags flags) noexcept {
93 auto raw = frag_off();
94 raw &= FRAG_OFFSET_MASK;
95 raw |= static_cast<uint16_t>(std::to_underlying(flags) & FRAG_FLAGS_MASK);
96 frag_off_be = autoswap(raw);
97 }
98
99 constexpr void set_frag_offset_units8(uint16_t units8) noexcept {
100 auto raw = frag_off();
101 raw &= FRAG_FLAGS_MASK;
102 raw |= static_cast<uint16_t>(units8 & FRAG_OFFSET_MASK);
103 frag_off_be = autoswap(raw);
104 }
105
106 constexpr void set_frag_offset_bytes(uint16_t bytes) noexcept {
107 set_frag_offset_units8(static_cast<uint16_t>(bytes >> 3));
108 }
109
110 constexpr void set_df(bool enabled) noexcept {
111 set_flag(IPv4Flags::DF, enabled);
112 }
113
114 constexpr void set_mf(bool enabled) noexcept {
115 set_flag(IPv4Flags::MF, enabled);
116 }
117
118 constexpr auto l4_protocol() const noexcept -> IpProtocol {
119 return static_cast<IpProtocol>(protocol);
120 }
121
122 constexpr auto checksum() const noexcept -> uint16_t {
123 return autoswap(checksum_be);
124 }
125
126 constexpr void set_checksum(uint16_t v) noexcept {
128 }
129
130 constexpr auto src_addr() const noexcept -> uint32_t {
131 return autoswap(src_addr_be);
132 }
133
134 constexpr auto dst_addr() const noexcept -> uint32_t {
135 return autoswap(dst_addr_be);
136 }
137
138 constexpr void set_src(uint32_t v) noexcept { src_addr_be = autoswap(v); }
139 constexpr void set_dst(uint32_t v) noexcept { dst_addr_be = autoswap(v); }
140 constexpr bool valid_min_size() const noexcept { return ihl_bytes() >= 20; }
141
142private:
143 constexpr void set_flag(IPv4Flags flag, bool enabled) noexcept {
144 auto raw = frag_off();
145 const auto mask = std::to_underlying(flag);
146 if (enabled)
147 raw |= static_cast<uint16_t>(mask);
148 else
149 raw &= static_cast<uint16_t>(~mask);
150 frag_off_be = autoswap(raw);
151 }
152};
153
154static_assert(sizeof(IPv4Header) == 20, "Wrong IPv4 header size");
155static_assert(alignof(IPv4Header) == 1, "Wrong IPv4 header alignment");
156
157} // namespace vbvx
Definition arp.hxx:11
IPv4Flags
IPv4 fragmentation flags.
Definition ip4_header.hxx:18
@ MF
Definition ip4_header.hxx:20
@ None
Definition ip4_header.hxx:19
@ DF
Definition ip4_header.hxx:21
@ RFU
Definition ip4_header.hxx:22
constexpr _Tp autoswap(_Tp tp)
Byte-swap a value if the host is little-endian.
Definition utils.hxx:13
IpProtocol
IP protocol (Next Header) numbers.
Definition ip_protocol.hxx:13
IPv4 header (minimum 20 bytes).
Definition ip4_header.hxx:35
uint8_t ttl
Definition ip4_header.hxx:41
constexpr auto frag_offset_units8() const noexcept -> uint16_t
Definition ip4_header.hxx:80
constexpr void set_df(bool enabled) noexcept
Definition ip4_header.hxx:110
constexpr void set_src(uint32_t v) noexcept
Definition ip4_header.hxx:138
constexpr auto checksum() const noexcept -> uint16_t
Definition ip4_header.hxx:122
constexpr void set_checksum(uint16_t v) noexcept
Definition ip4_header.hxx:126
uint16_t total_length_be
Definition ip4_header.hxx:38
constexpr auto frag_off() const noexcept -> uint16_t
Definition ip4_header.hxx:68
constexpr bool valid_min_size() const noexcept
Definition ip4_header.hxx:140
constexpr auto id() const noexcept -> uint16_t
Definition ip4_header.hxx:66
constexpr auto frag_flags() const noexcept -> IPv4Flags
Definition ip4_header.hxx:72
constexpr void set_frag_offset_units8(uint16_t units8) noexcept
Definition ip4_header.hxx:99
constexpr void set_frag_flags(IPv4Flags flags) noexcept
Definition ip4_header.hxx:92
constexpr auto total_length() const noexcept -> uint16_t
Definition ip4_header.hxx:62
constexpr auto ihl_bytes() const noexcept -> uint16_t
Definition ip4_header.hxx:55
constexpr void set_mf(bool enabled) noexcept
Definition ip4_header.hxx:114
constexpr auto dst_addr() const noexcept -> uint32_t
Definition ip4_header.hxx:134
uint32_t src_addr_be
Definition ip4_header.hxx:44
uint8_t tos
Definition ip4_header.hxx:37
uint16_t checksum_be
Definition ip4_header.hxx:43
constexpr auto ecn() const noexcept -> uint8_t
Definition ip4_header.hxx:60
constexpr auto version() const noexcept -> uint8_t
Definition ip4_header.hxx:47
uint16_t frag_off_be
Definition ip4_header.hxx:40
constexpr void set_frag_offset_bytes(uint16_t bytes) noexcept
Definition ip4_header.hxx:106
uint16_t id_be
Definition ip4_header.hxx:39
constexpr auto src_addr() const noexcept -> uint32_t
Definition ip4_header.hxx:130
constexpr auto frag_offset_bytes() const noexcept -> uint16_t
Definition ip4_header.hxx:84
uint8_t protocol
Definition ip4_header.hxx:42
uint32_t dst_addr_be
Definition ip4_header.hxx:45
uint8_t version_ihl
Definition ip4_header.hxx:36
constexpr bool has_flag(IPv4Flags flag) const noexcept
Definition ip4_header.hxx:76
constexpr auto l4_protocol() const noexcept -> IpProtocol
Definition ip4_header.hxx:118
constexpr auto ihl_words() const noexcept -> uint16_t
Definition ip4_header.hxx:51
constexpr auto dscp() const noexcept -> uint8_t
Definition ip4_header.hxx:59
constexpr bool is_fragmented() const noexcept
Definition ip4_header.hxx:88
constexpr void set_dst(uint32_t v) noexcept
Definition ip4_header.hxx:139
Enable bitwise operators for an enum class.
Definition flags_view.hxx:25