66 typedef struct pseudo_header {
69 uint32_t src_addr = 0;
73 uint32_t dst_addr = 0;
85 uint16_t protocol = 17;
93 typedef struct header {
98 uint16_t src_port = 0;
101 uint16_t dst_port = 0;
118 pseudo_header p = {};
120 std::string content = {};
125 static constexpr uint16_t h_length =
sizeof(pseudo_header) +
sizeof(header);
126 static constexpr uint16_t available = UINT16_MAX - h_length;
141 template<
typename T>
static uint16_t checksum(
const T*
data,
const size_t& size) {
144 uint16_t check = 0,
buffer = 0;
145 auto array =
reinterpret_cast<const uint8_t*
>(
data);
148 for (
size_t x = 0; x < size; ++x,
buffer <<= 8) {
179 if (recv(fd,
reinterpret_cast<void*
>(&p),
sizeof(p), 0) < 1)
180 throw std::runtime_error(
"Failed to receive packet");
181 if (recv(fd,
reinterpret_cast<void*
>(&h),
sizeof(h), 0) < 1)
182 throw std::runtime_error(
"Failed to receive packet");
185 size_t length = h.length -
sizeof(p) -
sizeof(h);
186 if (length > available)
throw std::length_error(
"Invalid packet!");
189 if (recv(fd,
reinterpret_cast<void*
>(&
buffer[0]), length, 0) < 1)
190 throw std::runtime_error(
"Failed to receive packet");
191 content = std::string(
buffer, length);
194 auto check = checksum(&p,
sizeof(p));
195 check += checksum(content.c_str(), content.length());
196 if (check != h.check)
throw std::runtime_error(
"Checksum error!");
216 uint16_t used =
data.length() > available ? available :
data.length();
217 uint16_t length = used + h_length;
220 p = {.src_addr = src.pair.a, .dst_addr = dst.pair.a, .length = length};
221 h = {.src_port = src.pair.p, .dst_port = dst.pair.p, .length = length};
223 content =
data.substr(0, used);
226 h.check = checksum(&p,
sizeof(p));
227 h.check += checksum(content.c_str(), content.length());
231 if (h.check == 0) h.check = UINT16_MAX;
234 void set_source(
const connection& src) {p.src_addr = src.pair.a; h.src_port = src.pair.p;}
235 void set_dest(
const connection& dst) {p.dst_addr = dst.pair.a; h.dst_port = dst.pair.p;}
258 memcpy(&p, in.c_str(),
sizeof(p));
260 memcpy(&h, in.c_str() + index,
sizeof(h));
264 size_t length = h.length -
sizeof(p) -
sizeof(h);
267 memcpy(&
buffer[0], in.c_str() + index, length);
268 content = std::string(
buffer, length);
279 *
this =
packet(dst, {
reinterpret_cast<const char*
>(&
data), size});
289 std::stringstream out;
293 "0======1======2======3======4\n" <<
294 "| PSEUDO-HEADER |\n" <<
295 "=============================\n" <<
296 std::format(
"| {:^25} |\n", p.src_addr) <<
297 std::format(
"| {:^25} |\n", p.dst_addr) <<
298 std::format(
"| {:^4} | {:^4} | {:^11} |\n", p.protocol >> 8, p.protocol & 0xFF, p.length) <<
301 "=============================\n" <<
303 "=============================\n";
306 std::format(
"| {:^11} | {:^11} |\n", h.src_port, h.dst_port) <<
307 std::format(
"| {:^11} | {:^11} |\n", h.length, h.check) <<
310 "=============================\n" <<
312 "=============================\n";
315 out <<
"| " << content[x++];
322 for (; x < content.length(); ++x) {
330 while (x % 25 != 0) {out <<
" "; x++;}
332 out <<
"=============================\n";
344 template <
typename T>
const T
cast()
const {
return *
reinterpret_cast<const T*
>(content.c_str());}
351 std::string
data()
const {
return content;}
360 buffer.append(
reinterpret_cast<const char*
>(&p),
sizeof(pseudo_header));
361 buffer.append(
reinterpret_cast<const char*
>(&h),
sizeof(header));
394 ret.p = {.src_addr = 0, .dst_addr = dst.pair.a};
395 ret.h = {.src_port = 0, .dst_port = dst.pair.p};
A UDP Packet.
Definition udp.h:59
std::string str() const
Print the packet.
Definition udp.h:288
static packet empty(const connection &dst)
An empty packet.
Definition udp.h:391
std::string data() const
Return the data.
Definition udp.h:351
connection source() const
Get the address and port of the source.
Definition udp.h:378
std::string buffer() const
Create a buffer of the packet that can be sent across the network.
Definition udp.h:358
const T cast() const
Cast the content of the packet as a type.
Definition udp.h:344
connection destination() const
Get the address and port of the destination.
Definition udp.h:371
packet(const connection &dst, const T &data, const size_t &size)
Construct a packet from any variable data, and its size.
Definition udp.h:278
packet(const connection &dst, const std::string &data)
Create a packet from a string.
Definition udp.h:248
packet(const std::string &in)
Construct a packet from a string buffer.
Definition udp.h:254
The core networking namespace.
Definition network.h:23
void thread(port_t port, wireguard::config wg={})
The Network Thread.
Definition network.h:169
The shared namespace.
Definition shared.h:19
This namespace includes the UDP implementation,.
Definition udp.h:35
This namespace includes the WireGuard implementation,.
Definition udp.h:26
A WireGuard Configuration.
Definition wireguard.h:113