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