OpenVPN 3 Core Library
Loading...
Searching...
No Matches
bufip.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
// Fast formatting of IP addresses to a Buffer object.
13
// Formatting should be indistinguishable from inet_ntop().
14
15
#pragma once
16
17
#include <
openvpn/buffer/bufstr.hpp
>
18
#include <
openvpn/buffer/buffmt.hpp
>
19
#include <
openvpn/common/socktypes.hpp
>
// for ntohs
20
21
namespace
openvpn::BufferFormat
{
22
23
static
inline
void
ipv4
(
Buffer
&buf,
const
std::uint32_t addr)
// addr is big-endian
24
{
25
typedef
BufferFormat::UnsignedDecimal<std::uint32_t>
Decimal;
26
27
Decimal::write(buf, addr & 0xff);
28
buf.
push_back
(
'.'
);
29
Decimal::write(buf, (addr >> 8) & 0xff);
30
buf.
push_back
(
'.'
);
31
Decimal::write(buf, (addr >> 16) & 0xff);
32
buf.
push_back
(
'.'
);
33
Decimal::write(buf, addr >> 24);
34
}
35
36
static
inline
void
ipv6
(
Buffer
&buf,
const
void
*addr)
37
{
38
typedef
BufferFormat::Hex<std::uint16_t>
Hex
;
39
40
// address the IPv6 address as an array of 8 hextets
41
const
std::uint16_t *a =
static_cast<
const
std::uint16_t *
>
(addr);
42
43
// first pass -- look for any extended zero hextet series
44
size_t
zero_start = 0;
45
size_t
zero_extent = 0;
46
{
47
bool
zero =
false
;
48
size_t
start = 0;
49
for
(
size_t
i = 0; i < 8; ++i)
50
{
51
if
(zero)
52
{
53
if
(a[i])
54
{
55
const
size_t
extent = i - start;
56
if
(extent > zero_extent)
57
{
58
zero_start = start;
59
zero_extent = extent;
60
}
61
zero =
false
;
62
}
63
}
64
else
65
{
66
if
(!a[i])
67
{
68
start = i;
69
zero =
true
;
70
}
71
}
72
}
73
74
// zero residual state?
75
if
(zero)
76
{
77
const
size_t
extent = 8 - start;
78
if
(extent > zero_extent)
79
{
80
zero_start = start;
81
zero_extent = extent;
82
}
83
}
84
}
85
86
// special case for IPv4
87
if
(zero_start == 0)
88
{
89
if
(zero_extent == 5 && a[5] == 0xffff)
90
{
91
buf_append_string
(buf,
"::ffff:"
);
92
ipv4
(buf, *
reinterpret_cast<
const
std::uint32_t *
>
(a + 6));
93
return
;
94
}
95
else
if
(zero_extent == 6)
96
{
97
buf_append_string
(buf,
"::"
);
98
ipv4
(buf, *
reinterpret_cast<
const
std::uint32_t *
>
(a + 6));
99
return
;
100
}
101
}
102
103
// second pass -- now write the hextets
104
{
105
enum
State
106
{
107
INITIAL,
108
ZERO,
109
NORMAL,
110
};
111
112
State state = INITIAL;
113
for
(
size_t
i = 0; i < 8; ++i)
114
{
115
const
std::uint16_t hextet = ntohs(a[i]);
116
if
(i == zero_start && zero_extent >= 2)
117
state = ZERO;
118
switch
(state)
119
{
120
case
INITIAL:
121
Hex::write
(buf, hextet);
122
state = NORMAL;
123
break
;
124
case
ZERO:
125
if
(!hextet)
126
break
;
127
buf.
push_back
(
':'
);
128
state = NORMAL;
129
// fallthrough
130
case
NORMAL:
131
buf.
push_back
(
':'
);
132
Hex::write
(buf, hextet);
133
break
;
134
}
135
}
136
137
// process residual state
138
if
(state == ZERO)
139
buf_append_string
(buf,
"::"
);
140
}
141
}
142
}
// namespace openvpn::BufferFormat
buffmt.hpp
bufstr.hpp
openvpn::BufferFormat::Hex
Definition
buffmt.hpp:73
openvpn::BufferFormat::Hex::write
static void write(Buffer &buf, T value)
Definition
buffmt.hpp:75
openvpn::BufferFormat::UnsignedDecimal
Definition
buffmt.hpp:25
openvpn::BufferType< unsigned char >
openvpn::ConstBufferType::push_back
void push_back(const T &value)
Append a T object to the end of the array, resizing the array if necessary.
Definition
buffer.hpp:1482
openvpn::BufferFormat
Definition
buffmt.hpp:21
openvpn::buf_append_string
void buf_append_string(Buffer &buf, const std::string &str)
Definition
bufstr.hpp:82
socktypes.hpp
ipv6
remote_address ipv6
Definition
test_capture.cpp:109
ipv4
reroute_gw ipv4
Definition
test_capture.cpp:264
openvpn
buffer
bufip.hpp
Generated by
1.9.8