31inline static const std::uint16_t *
get_addr16(
const struct in6_addr *addr)
35#elif defined(__APPLE__) || defined(__FreeBSD__)
36 return addr->__u6_addr.__u6_addr16;
38 return addr->s6_addr16;
43 const struct in6_addr *daddr,
44 const std::uint32_t len,
45 const std::uint16_t proto,
49 std::uint32_t val = 0;
52 for (
int i = 0; i < 4; ++i)
54 val = (std::uint32_t)(addr[i * 2] << 16) + addr[i * 2 + 1];
61 for (
int i = 0; i < 4; ++i)
63 val = (std::uint32_t)(addr[i * 2] << 16) + addr[i * 2 + 1];
69 const std::uint32_t ulen = (std::uint32_t)htonl((std::uint32_t)len);
74 const std::uint32_t uproto = (std::uint32_t)htonl(proto);
76 carry = (sum < uproto);
86 throw std::range_error(
"Argument 'len' too small");
88 if (len >
static_cast<size_t>(std::numeric_limits<uint32_t>::max()))
89 throw std::range_error(
"Argument 'len' too large");
91 auto lenArg =
static_cast<uint32_t
>(len -
sizeof(
IPv6Header));
102 const void *extra_data,
103 const size_t extra_data_size,
105 const uint16_t seq_num,
106 const size_t total_size,
107 std::string *log_info)
109 const auto data_size = std::max(extra_data_size, total_size -
sizeof(
ICMPv6));
112 *log_info =
"PING6 " + src.
to_string() +
" -> " + dest.
to_string() +
" id=" + std::to_string(
id) +
" seq_num=" + std::to_string(seq_num) +
" data_size=" + std::to_string(data_size);
124 icmp->
head.
payload_len = htons(clamp_to_typerange<uint16_t>(payload_len));
134 icmp->
id = ntohs(
id);
135 icmp->
seq_num = ntohs(seq_num);
138 std::uint8_t *data = b +
sizeof(
ICMPv6);
139 for (
size_t i = 0; i < data_size; ++i)
140 data[i] = (std::uint8_t)i;
143 std::memcpy(data, extra_data, extra_data_size);
153 std::string *log_info)
158 *log_info =
"Invalid ECHO6_REQUEST";
164 const std::uint16_t old_type_code = icmp->
type_code;
const T * c_data() const
Returns a const pointer to the start of the buffer.
T * write_alloc(const size_t size)
Allocate space for writing data to the buffer.
size_t size() const
Returns the size of the buffer in T objects.
static Addr from_in6_addr(const in6_addr *in6)
in6_addr to_in6_addr() const
std::string to_string() const
std::uint32_t compute(const std::uint8_t *buf, size_t len)
std::uint32_t cunfold(const std::uint16_t sum)
std::uint16_t cfold(const std::uint32_t sum)
std::uint32_t diff2(const std::uint16_t old, const std::uint16_t new_, const std::uint32_t oldsum)
std::uint16_t csum_ipv6_pseudo(const struct in6_addr *saddr, const struct in6_addr *daddr, const std::uint32_t len, const std::uint16_t proto, std::uint32_t sum)
static const std::uint16_t * get_addr16(const struct in6_addr *addr)
void generate_echo_reply(Buffer &buf, std::string *log_info)
std::uint16_t csum_icmp(const ICMPv6 *icmp, const size_t len)
void generate_echo_request(Buffer &buf, const IPv6::Addr &src, const IPv6::Addr &dest, const void *extra_data, const size_t extra_data_size, const uint16_t id, const uint16_t seq_num, const size_t total_size, std::string *log_info)