Simplify/fix ip_header layout

ip_header wasn't 20 bytes on windows compilations for some unholy
reason.  This restructures it to avoid the template and just use two
different structs for le/be with a condition_t for the ifdef, which
resolves it (and *also* apparently avoids the need for the pack).

Also add a static_assert to check the size.

Also do the same for ipv6.
pull/1969/head
Jason Rhinelander 2 years ago
parent 58eec9ed11
commit 4065413977
No known key found for this signature in database
GPG Key ID: C4992CE7A88D4262

@ -17,22 +17,6 @@ namespace llarp::net
{
constexpr uint32_t ipv6_flowlabel_mask = 0b0000'0000'0000'1111'1111'1111'1111'1111;
template <bool little>
struct ipv6_header_preamble
{
unsigned char pad_small : 4;
unsigned char version : 4;
uint8_t pad[3];
};
template <>
struct ipv6_header_preamble<false>
{
unsigned char version : 4;
unsigned char pad_small : 4;
uint8_t pad[3];
};
/// get 20 bit truncated flow label in network order
llarp::nuint32_t
ipv6_header::FlowLabel() const

@ -1,5 +1,6 @@
#pragma once
#include <oxenc/endian.h>
#include <llarp/ev/ev.hpp>
#include "net.hpp"
#include <llarp/util/buffer.hpp>
@ -10,12 +11,10 @@
namespace llarp::net
{
#pragma pack(push, 1)
template <bool is_little_endian>
struct ip_header_le
{
unsigned int ihl : 4;
unsigned int version : 4;
uint8_t ihl : 4;
uint8_t version : 4;
uint8_t tos;
uint16_t tot_len;
uint16_t id;
@ -27,11 +26,10 @@ namespace llarp::net
uint32_t daddr;
};
template <>
struct ip_header_le<false>
struct ip_header_be
{
unsigned int version : 4;
unsigned int ihl : 4;
uint8_t version : 4;
uint8_t ihl : 4;
uint8_t tos;
uint16_t tot_len;
uint16_t id;
@ -42,11 +40,11 @@ namespace llarp::net
uint32_t saddr;
uint32_t daddr;
};
#pragma pack(pop)
using ip_header = ip_header_le<oxenc::little_endian>;
using ip_header = std::conditional_t<oxenc::little_endian, ip_header_le, ip_header_be>;
static_assert(sizeof(ip_header) == 20);
template <bool little>
struct ipv6_header_preamble_le
{
unsigned char pad_small : 4;
@ -54,19 +52,23 @@ namespace llarp::net
uint8_t pad[3];
};
template <>
struct ipv6_header_preamble_le<false>
struct ipv6_header_preamble_be
{
unsigned char version : 4;
unsigned char pad_small : 4;
uint8_t pad[3];
};
using ipv6_header_preamble =
std::conditional_t<oxenc::little_endian, ipv6_header_preamble_le, ipv6_header_preamble_be>;
static_assert(sizeof(ipv6_header_preamble) == 4);
struct ipv6_header
{
union
{
ipv6_header_preamble_le<oxenc::little_endian> preamble;
ipv6_header_preamble preamble;
uint32_t flowlabel;
} preamble;
@ -83,6 +85,8 @@ namespace llarp::net
FlowLabel(llarp::nuint32_t label);
};
static_assert(sizeof(ipv6_header) == 40);
/// "well known" ip protocols
/// TODO: extend this to non "well known values"
enum class IPProtocol : uint8_t

Loading…
Cancel
Save