OpenVPN 3 Core Library
Loading...
Searching...
No Matches
ping4.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12#pragma once
13
14#include <string>
15#include <cstring>
16#include <utility>
17
22#include <openvpn/addr/ipv4.hpp>
24#include <openvpn/ip/icmp4.hpp>
25#include <openvpn/ip/csum.hpp>
26
28
29namespace openvpn::Ping4 {
30
32 const IPv4::Addr &src,
33 const IPv4::Addr &dest,
34 const void *extra_data,
35 const size_t extra_data_size,
36 const uint16_t id,
37 const uint16_t seq_num,
38 const size_t total_size,
39 std::string *log_info)
40{
41 const unsigned int data_size = std::max(int(extra_data_size), int(total_size) - int(sizeof(ICMPv4)));
42
43 if (log_info)
44 *log_info = "PING4 " + 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);
45
46 const auto total_length = clamp_to_typerange<uint16_t>(sizeof(ICMPv4) + data_size);
47 std::uint8_t *b = buf.write_alloc(total_length);
48 ICMPv4 *icmp = (ICMPv4 *)b;
49
50 // IP Header
51 icmp->head.version_len = IPv4Header::ver_len(4, static_cast<int>(sizeof(IPv4Header)));
52 icmp->head.tos = 0;
53 icmp->head.tot_len = htons(total_length);
54 icmp->head.id = 0;
55 icmp->head.frag_off = 0;
56 icmp->head.ttl = 64;
58 icmp->head.check = 0;
59 icmp->head.saddr = src.to_uint32_net();
60 icmp->head.daddr = dest.to_uint32_net();
61 icmp->head.check = IPChecksum::checksum(b, sizeof(IPv4Header));
62
63 // ICMP header
65 icmp->code = 0;
66 icmp->checksum = 0;
67 icmp->id = ntohs(id);
68 icmp->seq_num = ntohs(seq_num);
69
70 // Data
71 std::uint8_t *data = b + sizeof(ICMPv4);
72 for (size_t i = 0; i < data_size; ++i)
73 data[i] = (std::uint8_t)i;
74
75 // Extra data
76 std::memcpy(data, extra_data, extra_data_size);
77
78 // ICMP checksum
79 icmp->checksum = IPChecksum::checksum(b + sizeof(IPv4Header),
80 sizeof(ICMPv4) - sizeof(IPv4Header) + data_size);
81
82 // std::cout << dump_hex(buf);
83}
84
85// assumes that buf is a validated ECHO_REQUEST
86inline void generate_echo_reply(Buffer &buf,
87 std::string *log_info)
88{
89 if (buf.size() < sizeof(ICMPv4))
90 {
91 if (log_info)
92 *log_info = "Invalid ECHO4_REQUEST";
93 return;
94 }
95
96 ICMPv4 *icmp = (ICMPv4 *)buf.c_data();
97 std::swap(icmp->head.saddr, icmp->head.daddr);
98 const std::uint16_t old_type_code = icmp->type_code;
101
102 if (log_info)
103 *log_info = "ECHO4_REPLY size=" + std::to_string(buf.size()) + ' ' + IPv4::Addr::from_uint32_net(icmp->head.saddr).to_string() + " -> " + IPv4::Addr::from_uint32_net(icmp->head.daddr).to_string();
104}
105} // namespace openvpn::Ping4
const T * c_data() const
Returns a const pointer to the start of the buffer.
Definition buffer.hpp:1194
T * write_alloc(const size_t size)
Allocate space for writing data to the buffer.
Definition buffer.hpp:1587
size_t size() const
Returns the size of the buffer in T objects.
Definition buffer.hpp:1242
static Addr from_uint32_net(const base_type addr)
Definition ipv4.hpp:112
std::uint32_t to_uint32_net() const
Definition ipv4.hpp:124
std::string to_string() const
Definition ipv4.hpp:232
std::uint32_t cunfold(const std::uint16_t sum)
Definition csum.hpp:41
std::uint16_t cfold(const std::uint32_t sum)
Definition csum.hpp:31
std::uint32_t diff2(const std::uint16_t old, const std::uint16_t new_, const std::uint32_t oldsum)
Definition csum.hpp:150
std::uint16_t checksum(const void *data, const size_t size)
Definition csum.hpp:158
void generate_echo_request(Buffer &buf, const IPv4::Addr &src, const IPv4::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)
Definition ping4.hpp:31
void generate_echo_reply(Buffer &buf, std::string *log_info)
Definition ping4.hpp:86
OutT clamp_to_typerange(InT inVal)
Clamps the input value to the legal range for the output type.
std::uint8_t type
Definition icmp4.hpp:40
std::uint16_t id
Definition icmp4.hpp:50
std::uint16_t checksum
Definition icmp4.hpp:45
std::uint8_t code
Definition icmp4.hpp:41
std::uint16_t seq_num
Definition icmp4.hpp:51
std::uint16_t type_code
Definition icmp4.hpp:43
struct IPv4Header head
Definition icmp4.hpp:35
std::uint8_t tos
Definition ip4.hpp:44
std::uint8_t ttl
Definition ip4.hpp:55
std::uint8_t protocol
Definition ip4.hpp:57
std::uint32_t daddr
Definition ip4.hpp:61
std::uint8_t version_len
Definition ip4.hpp:42
std::uint16_t check
Definition ip4.hpp:59
std::uint16_t frag_off
Definition ip4.hpp:53
std::uint16_t id
Definition ip4.hpp:46
static std::uint8_t ver_len(const unsigned int version, const unsigned int len)
Definition ip4.hpp:30
std::uint16_t tot_len
Definition ip4.hpp:45
std::uint32_t saddr
Definition ip4.hpp:60