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-2021 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 
100  uint8_t mac_src[OPENVPN_ETH_ALEN];
102  uint8_t mac_dest[OPENVPN_ETH_ALEN];
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 
208  struct openvpn_iphdr ip;
209  union {
210  struct openvpn_tcphdr tcp;
211  struct openvpn_udphdr udp;
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  * We are in a "liberal" position with respect to MSS,
252  * i.e. we assume that MSS can be calculated from MTU
253  * by subtracting out only the IP and TCP header sizes
254  * without options.
255  *
256  * (RFC 879, section 7).
257  */
258 #define MTU_TO_MSS(mtu) (mtu - sizeof(struct openvpn_iphdr) \
259  - sizeof(struct openvpn_tcphdr))
260 
261 /*
262  * This returns an ip protocol version of packet inside tun
263  * and offset of IP header (via parameter).
264  */
265 inline static int
266 get_tun_ip_ver(int tunnel_type, struct buffer *buf, int *ip_hdr_offset)
267 {
268  int ip_ver = -1;
269 
270  /* for tun get ip version from ip header */
271  if (tunnel_type == DEV_TYPE_TUN)
272  {
273  *ip_hdr_offset = 0;
274  if (likely(BLEN(buf) >= (int) sizeof(struct openvpn_iphdr)))
275  {
276  ip_ver = OPENVPN_IPH_GET_VER(*BPTR(buf));
277  }
278  }
279  else if (tunnel_type == DEV_TYPE_TAP)
280  {
281  *ip_hdr_offset = (int)(sizeof(struct openvpn_ethhdr));
282  /* for tap get ip version from eth header */
283  if (likely(BLEN(buf) >= *ip_hdr_offset))
284  {
285  const struct openvpn_ethhdr *eh = (const struct openvpn_ethhdr *) BPTR(buf);
286  uint16_t proto = ntohs(eh->proto);
287  if (proto == OPENVPN_ETH_P_IPV6)
288  {
289  ip_ver = 6;
290  }
291  else if (proto == OPENVPN_ETH_P_IPV4)
292  {
293  ip_ver = 4;
294  }
295  }
296  }
297 
298  return ip_ver;
299 }
300 
301 /*
302  * If raw tunnel packet is IPv4 or IPv6, return true and increment
303  * buffer offset to start of IP header.
304  */
305 bool is_ipv4(int tunnel_type, struct buffer *buf);
306 
307 bool is_ipv6(int tunnel_type, struct buffer *buf);
308 
322 uint16_t
323 ip_checksum(const sa_family_t af, const uint8_t *payload, const int len_payload,
324  const uint8_t *src_addr, const uint8_t *dest_addr, const int proto);
325 
326 #ifdef PACKET_TRUNCATION_CHECK
327 void ipv4_packet_size_verify(const uint8_t *data,
328  const int size,
329  const int tunnel_type,
330  const char
331  *prefix,
332  counter_type *errors);
333 
334 #endif
335 
336 #define OPENVPN_8021Q_MIN_VID 1
337 #define OPENVPN_8021Q_MAX_VID 4094
338 
339 #endif /* ifndef PROTO_H */
uint8_t version_len
Definition: proto.h:109
uint32_t daddr
Definition: proto.h:128
uint16_t check
Definition: proto.h:198
uint8_t flags
Definition: proto.h:195
uint8_t protocol
Definition: proto.h:124
#define OPENVPN_ETH_P_IPV6
Definition: proto.h:61
uint16_t proto
Definition: proto.h:77
uint16_t frag_off
Definition: proto.h:116
uint32_t seq
Definition: proto.h:181
uint8_t tos
Definition: proto.h:111
uint8_t icmp6_type
Definition: proto.h:157
uint32_t ack_seq
Definition: proto.h:182
unsigned short sa_family_t
Definition: syshead.h:402
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:125
uint8_t version_prio
Definition: proto.h:136
#define in_addr_t
Definition: config-msvc.h:103
uint16_t window
Definition: proto.h:197
uint8_t hop_limit
Definition: proto.h:140
uint8_t icmp6_code
Definition: proto.h:160
uint8_t mac_addr_size
Definition: proto.h:93
#define OPENVPN_IPH_GET_VER(v)
Definition: proto.h:107
uint16_t proto
Definition: proto.h:64
uint16_t dest
Definition: proto.h:180
in_addr_t ip_src
Definition: proto.h:101
uint16_t id
Definition: proto.h:113
#define BPTR(buf)
Definition: buffer.h:124
#define OPENVPN_ETH_P_IPV4
Definition: proto.h:60
uint16_t len
Definition: proto.h:171
uint16_t source
Definition: proto.h:179
#define DEV_TYPE_TUN
Definition: proto.h:37
uint64_t counter_type
Definition: common.h:30
bool is_ipv6(int tunnel_type, struct buffer *buf)
Definition: proto.c:118
#define likely(x)
Definition: syshead.h:35
uint16_t pcp_cfi_vid
Definition: proto.h:76
static int get_tun_ip_ver(int tunnel_type, struct buffer *buf, int *ip_hdr_offset)
Definition: proto.h:266
uint8_t nexthdr
Definition: proto.h:139
uint16_t check
Definition: proto.h:172
uint8_t proto_addr_size
Definition: proto.h:94
uint16_t tpid
Definition: proto.h:72
uint8_t source[OPENVPN_ETH_ALEN]
Definition: proto.h:58
uint8_t dest[OPENVPN_ETH_ALEN]
Definition: proto.h:57
#define BLEN(buf)
Definition: buffer.h:127
in_addr_t ip_dest
Definition: proto.h:103
uint16_t proto_addr_type
Definition: proto.h:92
uint32_t saddr
Definition: proto.h:127
uint16_t tot_len
Definition: proto.h:112
uint16_t icmp6_cksum
Definition: proto.h:161
bool is_ipv4(int tunnel_type, struct buffer *buf)
Definition: proto.c:113
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
uint16_t check
Definition: proto.h:126
uint16_t mac_addr_type
Definition: proto.h:90
uint8_t ttl
Definition: proto.h:118
uint16_t arp_command
Definition: proto.h:98
#define OPENVPN_ETH_ALEN
Definition: proto.h:54
uint16_t dest
Definition: proto.h:170
uint16_t urg_ptr
Definition: proto.h:199
uint8_t doff_res
Definition: proto.h:185
uint16_t source
Definition: proto.h:169
uint16_t payload_len
Definition: proto.h:138
#define DEV_TYPE_TAP
Definition: proto.h:38