OpenVPN
proto.h
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2002-2025 OpenVPN Inc <sales@openvpn.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, see <https://www.gnu.org/licenses/>.
21 */
22
23#ifndef PROTO_H
24#define PROTO_H
25
26#include "common.h"
27#include "buffer.h"
28
29#pragma pack(1)
30
31/*
32 * Tunnel types
33 */
34#define DEV_TYPE_UNDEF 0
35#define DEV_TYPE_TUN 2 /* point-to-point IP tunnel */
36#define DEV_TYPE_TAP 3 /* ethernet (802.3) tunnel */
37
38/* TUN topologies */
39
40#define TOP_UNDEF 0
41#define TOP_NET30 1
42#define TOP_P2P 2
43#define TOP_SUBNET 3
44
45/*
46 * IP and Ethernet protocol structs. For portability,
47 * OpenVPN needs its own definitions of these structs, and
48 * names have been adjusted to avoid collisions with
49 * native structs.
50 */
51
52#define OPENVPN_ETH_ALEN 6 /* ethernet address length */
54{
55 uint8_t dest[OPENVPN_ETH_ALEN]; /* destination ethernet addr */
56 uint8_t source[OPENVPN_ETH_ALEN]; /* source ethernet addr */
57
58#define OPENVPN_ETH_P_IPV4 0x0800 /* IPv4 protocol */
59#define OPENVPN_ETH_P_IPV6 0x86DD /* IPv6 protocol */
60#define OPENVPN_ETH_P_ARP 0x0806 /* ARP protocol */
61#define OPENVPN_ETH_P_8021Q 0x8100 /* 802.1Q protocol */
62 uint16_t proto; /* packet type ID field */
63};
64
66{
67 uint8_t dest[OPENVPN_ETH_ALEN]; /* destination ethernet addr */
68 uint8_t source[OPENVPN_ETH_ALEN]; /* source ethernet addr */
69
70 uint16_t tpid; /* 802.1Q Tag Protocol Identifier */
71#define OPENVPN_8021Q_MASK_PCP htons(0xE000) /* mask PCP out of pcp_cfi_vid */
72#define OPENVPN_8021Q_MASK_CFI htons(0x1000) /* mask CFI out of pcp_cfi_vid */
73#define OPENVPN_8021Q_MASK_VID htons(0x0FFF) /* mask VID out of pcp_cfi_vid */
74 uint16_t pcp_cfi_vid; /* bit fields, see IEEE 802.1Q */
75 uint16_t proto; /* contained packet type ID field */
76};
77
78/*
79 * Size difference between a regular Ethernet II header and an Ethernet II
80 * header with additional IEEE 802.1Q tagging.
81 */
82#define SIZE_ETH_TO_8021Q_HDR (sizeof(struct openvpn_8021qhdr) - sizeof(struct openvpn_ethhdr))
83
87#define OPENVPN_IN6_ARE_ADDR_EQUAL(a, b) (memcmp(a, b, sizeof(struct in6_addr)) == 0)
88
90{
91#define OPENVPN_IPH_GET_VER(v) (((v) >> 4) & 0x0F)
92#define OPENVPN_IPH_GET_LEN(v) (((v) & 0x0F) << 2)
93 uint8_t version_len;
94
95 uint8_t tos;
96 uint16_t tot_len;
97 uint16_t id;
98
99#define OPENVPN_IP_OFFMASK 0x1fff
100 uint16_t frag_off;
101
102 uint8_t ttl;
103
104#define OPENVPN_IPPROTO_IGMP 2 /* IGMP protocol */
105#define OPENVPN_IPPROTO_TCP 6 /* TCP protocol */
106#define OPENVPN_IPPROTO_UDP 17 /* UDP protocol */
107#define OPENVPN_IPPROTO_ICMPV6 58 /* ICMPV6 protocol */
108 uint8_t protocol;
109
110 uint16_t check;
111 uint32_t saddr;
112 uint32_t daddr;
113 /*The options start here. */
114};
115
116/*
117 * IPv6 header
118 */
120{
122 uint8_t flow_lbl[3];
123 uint16_t payload_len;
124 uint8_t nexthdr;
125 uint8_t hop_limit;
126
127 struct in6_addr saddr;
128 struct in6_addr daddr;
129};
130
131/*
132 * ICMPv6 header
133 */
135{
136#define OPENVPN_ICMP6_DESTINATION_UNREACHABLE 1
137#define OPENVPN_ND_ROUTER_SOLICIT 133
138#define OPENVPN_ND_ROUTER_ADVERT 134
139#define OPENVPN_ND_NEIGHBOR_SOLICIT 135
140#define OPENVPN_ND_NEIGHBOR_ADVERT 136
141#define OPENVPN_ND_INVERSE_SOLICIT 141
142#define OPENVPN_ND_INVERSE_ADVERT 142
143 uint8_t icmp6_type;
144#define OPENVPN_ICMP6_DU_NOROUTE 0
145#define OPENVPN_ICMP6_DU_COMMUNICATION_PROHIBTED 1
146 uint8_t icmp6_code;
147 uint16_t icmp6_cksum;
148 uint8_t icmp6_dataun[4];
149};
150
151/*
152 * UDP header
153 */
161
162/*
163 * TCP header, per RFC 793.
164 */
166{
167 uint16_t source; /* source port */
168 uint16_t dest; /* destination port */
169 uint32_t seq; /* sequence number */
170 uint32_t ack_seq; /* acknowledgement number */
171
172#define OPENVPN_TCPH_GET_DOFF(d) (((d) & 0xF0) >> 2)
173 uint8_t doff_res;
174
175#define OPENVPN_TCPH_FIN_MASK (1 << 0)
176#define OPENVPN_TCPH_SYN_MASK (1 << 1)
177#define OPENVPN_TCPH_RST_MASK (1 << 2)
178#define OPENVPN_TCPH_PSH_MASK (1 << 3)
179#define OPENVPN_TCPH_ACK_MASK (1 << 4)
180#define OPENVPN_TCPH_URG_MASK (1 << 5)
181#define OPENVPN_TCPH_ECE_MASK (1 << 6)
182#define OPENVPN_TCPH_CWR_MASK (1 << 7)
183 uint8_t flags;
184
185 uint16_t window;
186 uint16_t check;
187 uint16_t urg_ptr;
188};
189
190#define OPENVPN_TCPOPT_EOL 0
191#define OPENVPN_TCPOPT_NOP 1
192#define OPENVPN_TCPOPT_MAXSEG 2
193#define OPENVPN_TCPOLEN_MAXSEG 4
194
196{
198 union
199 {
202 } u;
203};
204
205#pragma pack()
206
207/*
208 * The following macro is used to update an
209 * internet checksum. "acc" is a 32-bit
210 * accumulation of all the changes to the
211 * checksum (adding in old 16-bit words and
212 * subtracting out new words), and "cksum"
213 * is the checksum value to be updated.
214 */
215#define ADJUST_CHECKSUM(acc, cksum) \
216 { \
217 int _acc = acc; \
218 _acc += (cksum); \
219 if (_acc < 0) \
220 { \
221 _acc = -_acc; \
222 _acc = (_acc >> 16) + (_acc & 0xffff); \
223 _acc += _acc >> 16; \
224 (cksum) = (uint16_t)~_acc; \
225 } \
226 else \
227 { \
228 _acc = (_acc >> 16) + (_acc & 0xffff); \
229 _acc += _acc >> 16; \
230 (cksum) = (uint16_t)_acc; \
231 } \
232 }
233
234#define ADD_CHECKSUM_32(acc, u32) \
235 { \
236 acc += (u32) & 0xffff; \
237 acc += (u32) >> 16; \
238 }
239
240#define SUB_CHECKSUM_32(acc, u32) \
241 { \
242 acc -= (u32) & 0xffff; \
243 acc -= (u32) >> 16; \
244 }
245
246/*
247 * This returns an ip protocol version of packet inside tun
248 * and offset of IP header (via parameter).
249 */
250static inline int
252{
253 int ip_ver = -1;
254
255 /* for tun get ip version from ip header */
257 {
258 *ip_hdr_offset = 0;
259 if (likely(BLEN(buf) >= (int)sizeof(struct openvpn_iphdr)))
260 {
262 }
263 }
264 else if (tunnel_type == DEV_TYPE_TAP)
265 {
266 *ip_hdr_offset = (int)(sizeof(struct openvpn_ethhdr));
267 /* for tap get ip version from eth header */
268 if (likely(BLEN(buf) >= *ip_hdr_offset))
269 {
270 const struct openvpn_ethhdr *eh = (const struct openvpn_ethhdr *)BPTR(buf);
271 uint16_t proto = ntohs(eh->proto);
273 {
274 ip_ver = 6;
275 }
276 else if (proto == OPENVPN_ETH_P_IPV4)
277 {
278 ip_ver = 4;
279 }
280 }
281 }
282
283 return ip_ver;
284}
285
286/*
287 * If raw tunnel packet is IPv4 or IPv6, return true and increment
288 * buffer offset to start of IP header.
289 */
290bool is_ipv4(int tunnel_type, struct buffer *buf);
291
292bool is_ipv6(int tunnel_type, struct buffer *buf);
293
307uint16_t ip_checksum(const sa_family_t af, const uint8_t *payload, const int len_payload,
308 const uint8_t *src_addr, const uint8_t *dest_addr, const int proto);
309
310#ifdef PACKET_TRUNCATION_CHECK
311void ipv4_packet_size_verify(const uint8_t *data, const int size, const int tunnel_type,
312 const char *prefix, counter_type *errors);
313
314#endif
315
316#define OPENVPN_8021Q_MIN_VID 1
317#define OPENVPN_8021Q_MAX_VID 4094
318
319#endif /* ifndef PROTO_H */
#define BPTR(buf)
Definition buffer.h:123
#define BLEN(buf)
Definition buffer.h:126
uint64_t counter_type
Definition common.h:29
static int get_tun_ip_ver(int tunnel_type, struct buffer *buf, int *ip_hdr_offset)
Definition proto.h:251
#define DEV_TYPE_TAP
Definition proto.h:36
bool is_ipv4(int tunnel_type, struct buffer *buf)
Definition proto.c:108
bool is_ipv6(int tunnel_type, struct buffer *buf)
Definition proto.c:113
#define OPENVPN_ETH_ALEN
Definition proto.h:52
#define OPENVPN_ETH_P_IPV6
Definition proto.h:59
#define DEV_TYPE_TUN
Definition proto.h:35
#define OPENVPN_ETH_P_IPV4
Definition proto.h:58
uint16_t ip_checksum(const sa_family_t af, const uint8_t *payload, const int len_payload, const uint8_t *src_addr, const uint8_t *dest_addr, const int proto)
Calculates an IP or IPv6 checksum with a pseudo header as required by TCP, UDP and ICMPv6.
Definition proto.c:120
#define OPENVPN_IPH_GET_VER(v)
Definition proto.h:91
Wrapper structure for dynamically allocated memory.
Definition buffer.h:60
union ip_tcp_udp_hdr::@23 u
struct openvpn_iphdr ip
Definition proto.h:197
struct openvpn_udphdr udp
Definition proto.h:201
struct openvpn_tcphdr tcp
Definition proto.h:200
uint16_t tpid
Definition proto.h:70
uint8_t source[OPENVPN_ETH_ALEN]
Definition proto.h:68
uint16_t pcp_cfi_vid
Definition proto.h:74
uint16_t proto
Definition proto.h:75
uint8_t dest[OPENVPN_ETH_ALEN]
Definition proto.h:67
uint8_t dest[OPENVPN_ETH_ALEN]
Definition proto.h:55
uint16_t proto
Definition proto.h:62
uint8_t source[OPENVPN_ETH_ALEN]
Definition proto.h:56
uint8_t icmp6_type
Definition proto.h:143
uint16_t icmp6_cksum
Definition proto.h:147
uint8_t icmp6_code
Definition proto.h:146
uint8_t icmp6_dataun[4]
Definition proto.h:148
uint32_t saddr
Definition proto.h:111
uint16_t frag_off
Definition proto.h:100
uint32_t daddr
Definition proto.h:112
uint16_t id
Definition proto.h:97
uint8_t tos
Definition proto.h:95
uint8_t protocol
Definition proto.h:108
uint16_t tot_len
Definition proto.h:96
uint16_t check
Definition proto.h:110
uint8_t ttl
Definition proto.h:102
uint8_t version_len
Definition proto.h:93
uint8_t version_prio
Definition proto.h:121
uint8_t hop_limit
Definition proto.h:125
struct in6_addr saddr
Definition proto.h:127
struct in6_addr daddr
Definition proto.h:128
uint8_t flow_lbl[3]
Definition proto.h:122
uint8_t nexthdr
Definition proto.h:124
uint16_t payload_len
Definition proto.h:123
uint16_t source
Definition proto.h:167
uint16_t window
Definition proto.h:185
uint8_t doff_res
Definition proto.h:173
uint16_t check
Definition proto.h:186
uint8_t flags
Definition proto.h:183
uint32_t ack_seq
Definition proto.h:170
uint32_t seq
Definition proto.h:169
uint16_t urg_ptr
Definition proto.h:187
uint16_t dest
Definition proto.h:168
uint16_t check
Definition proto.h:159
uint16_t source
Definition proto.h:156
uint16_t dest
Definition proto.h:157
uint16_t len
Definition proto.h:158
#define likely(x)
Definition syshead.h:34
unsigned short sa_family_t
Definition syshead.h:396