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-2023 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, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 #ifndef PROTO_H
25 #define PROTO_H
26 
27 #include "common.h"
28 #include "buffer.h"
29 
30 #pragma pack(1)
31 
32 /*
33  * Tunnel types
34  */
35 #define DEV_TYPE_UNDEF 0
36 #define DEV_TYPE_NULL 1
37 #define DEV_TYPE_TUN 2 /* point-to-point IP tunnel */
38 #define DEV_TYPE_TAP 3 /* ethernet (802.3) tunnel */
39 
40 /* TUN topologies */
41 
42 #define TOP_UNDEF 0
43 #define TOP_NET30 1
44 #define TOP_P2P 2
45 #define TOP_SUBNET 3
46 
47 /*
48  * IP and Ethernet protocol structs. For portability,
49  * OpenVPN needs its own definitions of these structs, and
50  * names have been adjusted to avoid collisions with
51  * native structs.
52  */
53 
54 #define OPENVPN_ETH_ALEN 6 /* ethernet address length */
56 {
57  uint8_t dest[OPENVPN_ETH_ALEN]; /* destination ethernet addr */
58  uint8_t source[OPENVPN_ETH_ALEN]; /* source ethernet addr */
59 
60 #define OPENVPN_ETH_P_IPV4 0x0800 /* IPv4 protocol */
61 #define OPENVPN_ETH_P_IPV6 0x86DD /* IPv6 protocol */
62 #define OPENVPN_ETH_P_ARP 0x0806 /* ARP protocol */
63 #define OPENVPN_ETH_P_8021Q 0x8100 /* 802.1Q protocol */
64  uint16_t proto; /* packet type ID field */
65 };
66 
68 {
69  uint8_t dest[OPENVPN_ETH_ALEN]; /* destination ethernet addr */
70  uint8_t source[OPENVPN_ETH_ALEN]; /* source ethernet addr */
71 
72  uint16_t tpid; /* 802.1Q Tag Protocol Identifier */
73 #define OPENVPN_8021Q_MASK_PCP htons(0xE000) /* mask PCP out of pcp_cfi_vid */
74 #define OPENVPN_8021Q_MASK_CFI htons(0x1000) /* mask CFI out of pcp_cfi_vid */
75 #define OPENVPN_8021Q_MASK_VID htons(0x0FFF) /* mask VID out of pcp_cfi_vid */
76  uint16_t pcp_cfi_vid; /* bit fields, see IEEE 802.1Q */
77  uint16_t proto; /* contained packet type ID field */
78 };
79 
80 /*
81  * Size difference between a regular Ethernet II header and an Ethernet II
82  * header with additional IEEE 802.1Q tagging.
83  */
84 #define SIZE_ETH_TO_8021Q_HDR (sizeof(struct openvpn_8021qhdr) \
85  - sizeof(struct openvpn_ethhdr))
86 
87 
88 struct openvpn_arp {
89 #define ARP_MAC_ADDR_TYPE 0x0001
90  uint16_t mac_addr_type; /* 0x0001 */
91 
92  uint16_t proto_addr_type; /* 0x0800 */
93  uint8_t mac_addr_size; /* 0x06 */
94  uint8_t proto_addr_size; /* 0x04 */
95 
96 #define ARP_REQUEST 0x0001
97 #define ARP_REPLY 0x0002
98  uint16_t arp_command; /* 0x0001 for ARP request, 0x0002 for ARP reply */
99 
101  in_addr_t ip_src;
103  in_addr_t ip_dest;
104 };
105 
107 #define OPENVPN_IPH_GET_VER(v) (((v) >> 4) & 0x0F)
108 #define OPENVPN_IPH_GET_LEN(v) (((v) & 0x0F) << 2)
109  uint8_t version_len;
110 
111  uint8_t tos;
112  uint16_t tot_len;
113  uint16_t id;
114 
115 #define OPENVPN_IP_OFFMASK 0x1fff
116  uint16_t frag_off;
117 
118  uint8_t ttl;
119 
120 #define OPENVPN_IPPROTO_IGMP 2 /* IGMP protocol */
121 #define OPENVPN_IPPROTO_TCP 6 /* TCP protocol */
122 #define OPENVPN_IPPROTO_UDP 17 /* UDP protocol */
123 #define OPENVPN_IPPROTO_ICMPV6 58 /* ICMPV6 protocol */
124  uint8_t protocol;
125 
126  uint16_t check;
127  uint32_t saddr;
128  uint32_t daddr;
129  /*The options start here. */
130 };
131 
132 /*
133  * IPv6 header
134  */
136  uint8_t version_prio;
137  uint8_t flow_lbl[3];
138  uint16_t payload_len;
139  uint8_t nexthdr;
140  uint8_t hop_limit;
141 
142  struct in6_addr saddr;
143  struct in6_addr daddr;
144 };
145 
146 /*
147  * ICMPv6 header
148  */
150 #define OPENVPN_ICMP6_DESTINATION_UNREACHABLE 1
151 #define OPENVPN_ND_ROUTER_SOLICIT 133
152 #define OPENVPN_ND_ROUTER_ADVERT 134
153 #define OPENVPN_ND_NEIGHBOR_SOLICIT 135
154 #define OPENVPN_ND_NEIGHBOR_ADVERT 136
155 #define OPENVPN_ND_INVERSE_SOLICIT 141
156 #define OPENVPN_ND_INVERSE_ADVERT 142
157  uint8_t icmp6_type;
158 #define OPENVPN_ICMP6_DU_NOROUTE 0
159 #define OPENVPN_ICMP6_DU_COMMUNICATION_PROHIBTED 1
160  uint8_t icmp6_code;
161  uint16_t icmp6_cksum;
162  uint8_t icmp6_dataun[4];
163 };
164 
165 /*
166  * UDP header
167  */
169  uint16_t source;
170  uint16_t dest;
171  uint16_t len;
172  uint16_t check;
173 };
174 
175 /*
176  * TCP header, per RFC 793.
177  */
179  uint16_t source; /* source port */
180  uint16_t dest; /* destination port */
181  uint32_t seq; /* sequence number */
182  uint32_t ack_seq; /* acknowledgement number */
183 
184 #define OPENVPN_TCPH_GET_DOFF(d) (((d) & 0xF0) >> 2)
185  uint8_t doff_res;
186 
187 #define OPENVPN_TCPH_FIN_MASK (1<<0)
188 #define OPENVPN_TCPH_SYN_MASK (1<<1)
189 #define OPENVPN_TCPH_RST_MASK (1<<2)
190 #define OPENVPN_TCPH_PSH_MASK (1<<3)
191 #define OPENVPN_TCPH_ACK_MASK (1<<4)
192 #define OPENVPN_TCPH_URG_MASK (1<<5)
193 #define OPENVPN_TCPH_ECE_MASK (1<<6)
194 #define OPENVPN_TCPH_CWR_MASK (1<<7)
195  uint8_t flags;
196 
197  uint16_t window;
198  uint16_t check;
199  uint16_t urg_ptr;
200 };
201 
202 #define OPENVPN_TCPOPT_EOL 0
203 #define OPENVPN_TCPOPT_NOP 1
204 #define OPENVPN_TCPOPT_MAXSEG 2
205 #define OPENVPN_TCPOLEN_MAXSEG 4
206 
209  union {
212  } u;
213 };
214 
215 #pragma pack()
216 
217 /*
218  * The following macro is used to update an
219  * internet checksum. "acc" is a 32-bit
220  * accumulation of all the changes to the
221  * checksum (adding in old 16-bit words and
222  * subtracting out new words), and "cksum"
223  * is the checksum value to be updated.
224  */
225 #define ADJUST_CHECKSUM(acc, cksum) { \
226  int _acc = acc; \
227  _acc += (cksum); \
228  if (_acc < 0) { \
229  _acc = -_acc; \
230  _acc = (_acc >> 16) + (_acc & 0xffff); \
231  _acc += _acc >> 16; \
232  (cksum) = (uint16_t) ~_acc; \
233  } else { \
234  _acc = (_acc >> 16) + (_acc & 0xffff); \
235  _acc += _acc >> 16; \
236  (cksum) = (uint16_t) _acc; \
237  } \
238 }
239 
240 #define ADD_CHECKSUM_32(acc, u32) { \
241  acc += (u32) & 0xffff; \
242  acc += (u32) >> 16; \
243 }
244 
245 #define SUB_CHECKSUM_32(acc, u32) { \
246  acc -= (u32) & 0xffff; \
247  acc -= (u32) >> 16; \
248 }
249 
250 /*
251  * This returns an ip protocol version of packet inside tun
252  * and offset of IP header (via parameter).
253  */
254 static inline int
255 get_tun_ip_ver(int tunnel_type, struct buffer *buf, int *ip_hdr_offset)
256 {
257  int ip_ver = -1;
258 
259  /* for tun get ip version from ip header */
260  if (tunnel_type == DEV_TYPE_TUN)
261  {
262  *ip_hdr_offset = 0;
263  if (likely(BLEN(buf) >= (int) sizeof(struct openvpn_iphdr)))
264  {
265  ip_ver = OPENVPN_IPH_GET_VER(*BPTR(buf));
266  }
267  }
268  else if (tunnel_type == DEV_TYPE_TAP)
269  {
270  *ip_hdr_offset = (int)(sizeof(struct openvpn_ethhdr));
271  /* for tap get ip version from eth header */
272  if (likely(BLEN(buf) >= *ip_hdr_offset))
273  {
274  const struct openvpn_ethhdr *eh = (const struct openvpn_ethhdr *) BPTR(buf);
275  uint16_t proto = ntohs(eh->proto);
276  if (proto == OPENVPN_ETH_P_IPV6)
277  {
278  ip_ver = 6;
279  }
280  else if (proto == OPENVPN_ETH_P_IPV4)
281  {
282  ip_ver = 4;
283  }
284  }
285  }
286 
287  return ip_ver;
288 }
289 
290 /*
291  * If raw tunnel packet is IPv4 or IPv6, return true and increment
292  * buffer offset to start of IP header.
293  */
294 bool is_ipv4(int tunnel_type, struct buffer *buf);
295 
296 bool is_ipv6(int tunnel_type, struct buffer *buf);
297 
311 uint16_t
312 ip_checksum(const sa_family_t af, const uint8_t *payload, const int len_payload,
313  const uint8_t *src_addr, const uint8_t *dest_addr, const int proto);
314 
315 #ifdef PACKET_TRUNCATION_CHECK
316 void ipv4_packet_size_verify(const uint8_t *data,
317  const int size,
318  const int tunnel_type,
319  const char
320  *prefix,
321  counter_type *errors);
322 
323 #endif
324 
325 #define OPENVPN_8021Q_MIN_VID 1
326 #define OPENVPN_8021Q_MAX_VID 4094
327 
328 #endif /* ifndef PROTO_H */
openvpn_udphdr::source
uint16_t source
Definition: proto.h:169
openvpn_icmp6hdr::icmp6_type
uint8_t icmp6_type
Definition: proto.h:157
DEV_TYPE_TUN
#define DEV_TYPE_TUN
Definition: proto.h:37
openvpn_arp::mac_src
uint8_t mac_src[OPENVPN_ETH_ALEN]
Definition: proto.h:100
openvpn_ipv6hdr::payload_len
uint16_t payload_len
Definition: proto.h:138
openvpn_icmp6hdr::icmp6_code
uint8_t icmp6_code
Definition: proto.h:160
openvpn_tcphdr::ack_seq
uint32_t ack_seq
Definition: proto.h:182
ip_tcp_udp_hdr::ip
struct openvpn_iphdr ip
Definition: proto.h:208
openvpn_tcphdr::dest
uint16_t dest
Definition: proto.h:180
openvpn_icmp6hdr::icmp6_dataun
uint8_t icmp6_dataun[4]
Definition: proto.h:162
openvpn_tcphdr::flags
uint8_t flags
Definition: proto.h:195
ip_tcp_udp_hdr::udp
struct openvpn_udphdr udp
Definition: proto.h:211
openvpn_ipv6hdr::version_prio
uint8_t version_prio
Definition: proto.h:136
openvpn_udphdr
Definition: proto.h:168
openvpn_iphdr::daddr
uint32_t daddr
Definition: proto.h:128
openvpn_tcphdr::source
uint16_t source
Definition: proto.h:179
sa_family_t
unsigned short sa_family_t
Definition: syshead.h:385
openvpn_8021qhdr
Definition: proto.h:67
openvpn_ipv6hdr::daddr
struct in6_addr daddr
Definition: proto.h:143
likely
#define likely(x)
Definition: syshead.h:35
openvpn_iphdr::frag_off
uint16_t frag_off
Definition: proto.h:116
counter_type
uint64_t counter_type
Definition: common.h:30
openvpn_icmp6hdr::icmp6_cksum
uint16_t icmp6_cksum
Definition: proto.h:161
openvpn_iphdr::protocol
uint8_t protocol
Definition: proto.h:124
openvpn_iphdr::saddr
uint32_t saddr
Definition: proto.h:127
BLEN
#define BLEN(buf)
Definition: buffer.h:127
openvpn_tcphdr::window
uint16_t window
Definition: proto.h:197
openvpn_tcphdr
Definition: proto.h:178
openvpn_ipv6hdr::hop_limit
uint8_t hop_limit
Definition: proto.h:140
openvpn_ipv6hdr::flow_lbl
uint8_t flow_lbl[3]
Definition: proto.h:137
openvpn_arp::ip_src
in_addr_t ip_src
Definition: proto.h:101
openvpn_iphdr::check
uint16_t check
Definition: proto.h:126
openvpn_udphdr::len
uint16_t len
Definition: proto.h:171
openvpn_udphdr::check
uint16_t check
Definition: proto.h:172
OPENVPN_ETH_P_IPV4
#define OPENVPN_ETH_P_IPV4
Definition: proto.h:60
DEV_TYPE_TAP
#define DEV_TYPE_TAP
Definition: proto.h:38
buffer
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
openvpn_ethhdr::proto
uint16_t proto
Definition: proto.h:64
openvpn_ethhdr::source
uint8_t source[OPENVPN_ETH_ALEN]
Definition: proto.h:58
openvpn_iphdr::tot_len
uint16_t tot_len
Definition: proto.h:112
openvpn_ethhdr::dest
uint8_t dest[OPENVPN_ETH_ALEN]
Definition: proto.h:57
openvpn_8021qhdr::proto
uint16_t proto
Definition: proto.h:77
openvpn_arp::ip_dest
in_addr_t ip_dest
Definition: proto.h:103
buffer.h
BPTR
#define BPTR(buf)
Definition: buffer.h:124
openvpn_arp::proto_addr_type
uint16_t proto_addr_type
Definition: proto.h:92
openvpn_arp::proto_addr_size
uint8_t proto_addr_size
Definition: proto.h:94
openvpn_8021qhdr::source
uint8_t source[OPENVPN_ETH_ALEN]
Definition: proto.h:70
ip_tcp_udp_hdr::tcp
struct openvpn_tcphdr tcp
Definition: proto.h:210
openvpn_8021qhdr::pcp_cfi_vid
uint16_t pcp_cfi_vid
Definition: proto.h:76
openvpn_ipv6hdr
Definition: proto.h:135
openvpn_iphdr::id
uint16_t id
Definition: proto.h:113
openvpn_iphdr::ttl
uint8_t ttl
Definition: proto.h:118
openvpn_ipv6hdr::nexthdr
uint8_t nexthdr
Definition: proto.h:139
common.h
openvpn_ipv6hdr::saddr
struct in6_addr saddr
Definition: proto.h:142
openvpn_8021qhdr::tpid
uint16_t tpid
Definition: proto.h:72
ip_tcp_udp_hdr::u
union ip_tcp_udp_hdr::@12 u
openvpn_ethhdr
Definition: proto.h:55
ip_checksum
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:123
openvpn_arp::mac_addr_size
uint8_t mac_addr_size
Definition: proto.h:93
OPENVPN_ETH_ALEN
#define OPENVPN_ETH_ALEN
Definition: proto.h:54
openvpn_arp::arp_command
uint16_t arp_command
Definition: proto.h:98
get_tun_ip_ver
static int get_tun_ip_ver(int tunnel_type, struct buffer *buf, int *ip_hdr_offset)
Definition: proto.h:255
OPENVPN_IPH_GET_VER
#define OPENVPN_IPH_GET_VER(v)
Definition: proto.h:107
openvpn_iphdr::version_len
uint8_t version_len
Definition: proto.h:109
openvpn_arp::mac_dest
uint8_t mac_dest[OPENVPN_ETH_ALEN]
Definition: proto.h:102
openvpn_tcphdr::check
uint16_t check
Definition: proto.h:198
openvpn_tcphdr::urg_ptr
uint16_t urg_ptr
Definition: proto.h:199
openvpn_icmp6hdr
Definition: proto.h:149
openvpn_arp::mac_addr_type
uint16_t mac_addr_type
Definition: proto.h:90
is_ipv4
bool is_ipv4(int tunnel_type, struct buffer *buf)
Definition: proto.c:111
openvpn_tcphdr::seq
uint32_t seq
Definition: proto.h:181
openvpn_arp
Definition: proto.h:88
openvpn_udphdr::dest
uint16_t dest
Definition: proto.h:170
openvpn_iphdr::tos
uint8_t tos
Definition: proto.h:111
openvpn_iphdr
Definition: proto.h:106
openvpn_8021qhdr::dest
uint8_t dest[OPENVPN_ETH_ALEN]
Definition: proto.h:69
ip_tcp_udp_hdr
Definition: proto.h:207
openvpn_tcphdr::doff_res
uint8_t doff_res
Definition: proto.h:185
is_ipv6
bool is_ipv6(int tunnel_type, struct buffer *buf)
Definition: proto.c:116
OPENVPN_ETH_P_IPV6
#define OPENVPN_ETH_P_IPV6
Definition: proto.h:61