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-2018 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  uint16_t proto; /* packet type ID field */
64 };
65 
66 struct openvpn_arp {
67 #define ARP_MAC_ADDR_TYPE 0x0001
68  uint16_t mac_addr_type; /* 0x0001 */
69 
70  uint16_t proto_addr_type; /* 0x0800 */
71  uint8_t mac_addr_size; /* 0x06 */
73 
74 #define ARP_REQUEST 0x0001
75 #define ARP_REPLY 0x0002
76  uint16_t arp_command; /* 0x0001 for ARP request, 0x0002 for ARP reply */
77 
82 };
83 
84 struct openvpn_iphdr {
85 #define OPENVPN_IPH_GET_VER(v) (((v) >> 4) & 0x0F)
86 #define OPENVPN_IPH_GET_LEN(v) (((v) & 0x0F) << 2)
88 
92 
93 #define OPENVPN_IP_OFFMASK 0x1fff
95 
97 
98 #define OPENVPN_IPPROTO_IGMP 2 /* IGMP protocol */
99 #define OPENVPN_IPPROTO_TCP 6 /* TCP protocol */
100 #define OPENVPN_IPPROTO_UDP 17 /* UDP protocol */
101 #define OPENVPN_IPPROTO_ICMPV6 58 /* ICMPV6 protocol */
103 
107  /*The options start here. */
108 };
109 
110 /*
111  * IPv6 header
112  */
115  uint8_t flow_lbl[3];
119 
120  struct in6_addr saddr;
121  struct in6_addr daddr;
122 };
123 
124 /*
125  * ICMPv6 header
126  */
128 #define OPENVPN_ICMP6_DESTINATION_UNREACHABLE 1
129 #define OPENVPN_ND_ROUTER_SOLICIT 133
130 #define OPENVPN_ND_ROUTER_ADVERT 134
131 #define OPENVPN_ND_NEIGHBOR_SOLICIT 135
132 #define OPENVPN_ND_NEIGHBOR_ADVERT 136
133 #define OPENVPN_ND_INVERSE_SOLICIT 141
134 #define OPENVPN_ND_INVERSE_ADVERT 142
136 #define OPENVPN_ICMP6_DU_NOROUTE 0
137 #define OPENVPN_ICMP6_DU_COMMUNICATION_PROHIBTED 1
140  uint8_t icmp6_dataun[4];
141 };
142 
143 /*
144  * UDP header
145  */
151 };
152 
153 /*
154  * TCP header, per RFC 793.
155  */
157  uint16_t source; /* source port */
158  uint16_t dest; /* destination port */
159  uint32_t seq; /* sequence number */
160  uint32_t ack_seq; /* acknowledgement number */
161 
162 #define OPENVPN_TCPH_GET_DOFF(d) (((d) & 0xF0) >> 2)
164 
165 #define OPENVPN_TCPH_FIN_MASK (1<<0)
166 #define OPENVPN_TCPH_SYN_MASK (1<<1)
167 #define OPENVPN_TCPH_RST_MASK (1<<2)
168 #define OPENVPN_TCPH_PSH_MASK (1<<3)
169 #define OPENVPN_TCPH_ACK_MASK (1<<4)
170 #define OPENVPN_TCPH_URG_MASK (1<<5)
171 #define OPENVPN_TCPH_ECE_MASK (1<<6)
172 #define OPENVPN_TCPH_CWR_MASK (1<<7)
174 
178 };
179 
180 #define OPENVPN_TCPOPT_EOL 0
181 #define OPENVPN_TCPOPT_NOP 1
182 #define OPENVPN_TCPOPT_MAXSEG 2
183 #define OPENVPN_TCPOLEN_MAXSEG 4
184 
186  struct openvpn_iphdr ip;
187  union {
188  struct openvpn_tcphdr tcp;
189  struct openvpn_udphdr udp;
190  } u;
191 };
192 
193 #pragma pack()
194 
195 /*
196  * The following macro is used to update an
197  * internet checksum. "acc" is a 32-bit
198  * accumulation of all the changes to the
199  * checksum (adding in old 16-bit words and
200  * subtracting out new words), and "cksum"
201  * is the checksum value to be updated.
202  */
203 #define ADJUST_CHECKSUM(acc, cksum) { \
204  int _acc = acc; \
205  _acc += (cksum); \
206  if (_acc < 0) { \
207  _acc = -_acc; \
208  _acc = (_acc >> 16) + (_acc & 0xffff); \
209  _acc += _acc >> 16; \
210  (cksum) = (uint16_t) ~_acc; \
211  } else { \
212  _acc = (_acc >> 16) + (_acc & 0xffff); \
213  _acc += _acc >> 16; \
214  (cksum) = (uint16_t) _acc; \
215  } \
216 }
217 
218 #define ADD_CHECKSUM_32(acc, u32) { \
219  acc += (u32) & 0xffff; \
220  acc += (u32) >> 16; \
221 }
222 
223 #define SUB_CHECKSUM_32(acc, u32) { \
224  acc -= (u32) & 0xffff; \
225  acc -= (u32) >> 16; \
226 }
227 
228 /*
229  * We are in a "liberal" position with respect to MSS,
230  * i.e. we assume that MSS can be calculated from MTU
231  * by subtracting out only the IP and TCP header sizes
232  * without options.
233  *
234  * (RFC 879, section 7).
235  */
236 #define MTU_TO_MSS(mtu) (mtu - sizeof(struct openvpn_iphdr) \
237  - sizeof(struct openvpn_tcphdr))
238 
239 /*
240  * This returns an ip protocol version of packet inside tun
241  * and offset of IP header (via parameter).
242  */
243 inline static int
244 get_tun_ip_ver(int tunnel_type, struct buffer *buf, int *ip_hdr_offset)
245 {
246  int ip_ver = -1;
247 
248  /* for tun get ip version from ip header */
249  if (tunnel_type == DEV_TYPE_TUN)
250  {
251  *ip_hdr_offset = 0;
252  if (likely(BLEN(buf) >= (int) sizeof(struct openvpn_iphdr)))
253  {
254  ip_ver = OPENVPN_IPH_GET_VER(*BPTR(buf));
255  }
256  }
257  else if (tunnel_type == DEV_TYPE_TAP)
258  {
259  *ip_hdr_offset = (int)(sizeof(struct openvpn_ethhdr));
260  /* for tap get ip version from eth header */
261  if (likely(BLEN(buf) >= *ip_hdr_offset))
262  {
263  const struct openvpn_ethhdr *eh = (const struct openvpn_ethhdr *) BPTR(buf);
264  uint16_t proto = ntohs(eh->proto);
265  if (proto == OPENVPN_ETH_P_IPV6)
266  {
267  ip_ver = 6;
268  }
269  else if (proto == OPENVPN_ETH_P_IPV4)
270  {
271  ip_ver = 4;
272  }
273  }
274  }
275 
276  return ip_ver;
277 }
278 
279 /*
280  * If raw tunnel packet is IPv4 or IPv6, return true and increment
281  * buffer offset to start of IP header.
282  */
283 bool is_ipv4(int tunnel_type, struct buffer *buf);
284 
285 bool is_ipv6(int tunnel_type, struct buffer *buf);
286 
300 uint16_t
301 ip_checksum(const sa_family_t af, const uint8_t *payload, const int len_payload,
302  const uint8_t *src_addr, const uint8_t *dest_addr, const int proto);
303 
304 #ifdef PACKET_TRUNCATION_CHECK
305 void ipv4_packet_size_verify(const uint8_t *data,
306  const int size,
307  const int tunnel_type,
308  const char
309  *prefix,
310  counter_type *errors);
311 
312 #endif
313 
314 #endif /* ifndef PROTO_H */
uint8_t version_len
Definition: proto.h:87
uint32_t daddr
Definition: proto.h:106
uint16_t check
Definition: proto.h:176
uint8_t flags
Definition: proto.h:173
uint8_t protocol
Definition: proto.h:102
#define OPENVPN_ETH_P_IPV6
Definition: proto.h:61
uint16_t frag_off
Definition: proto.h:94
uint32_t seq
Definition: proto.h:159
uint8_t tos
Definition: proto.h:89
uint8_t icmp6_type
Definition: proto.h:135
uint32_t ack_seq
Definition: proto.h:160
unsigned short sa_family_t
Definition: syshead.h:447
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:103
uint8_t version_prio
Definition: proto.h:114
#define in_addr_t
Definition: config-msvc.h:104
uint16_t window
Definition: proto.h:175
uint8_t hop_limit
Definition: proto.h:118
uint8_t icmp6_code
Definition: proto.h:138
uint8_t mac_addr_size
Definition: proto.h:71
#define OPENVPN_IPH_GET_VER(v)
Definition: proto.h:85
uint16_t proto
Definition: proto.h:63
uint16_t dest
Definition: proto.h:158
in_addr_t ip_src
Definition: proto.h:79
uint16_t id
Definition: proto.h:91
#define BPTR(buf)
Definition: buffer.h:124
#define OPENVPN_ETH_P_IPV4
Definition: proto.h:60
uint16_t len
Definition: proto.h:149
uint16_t source
Definition: proto.h:157
#define DEV_TYPE_TUN
Definition: proto.h:37
bool is_ipv6(int tunnel_type, struct buffer *buf)
Definition: proto.c:96
unsigned __int32 uint32_t
Definition: config-msvc.h:121
#define likely(x)
Definition: syshead.h:35
static int get_tun_ip_ver(int tunnel_type, struct buffer *buf, int *ip_hdr_offset)
Definition: proto.h:244
uint8_t nexthdr
Definition: proto.h:117
unsigned int counter_type
Definition: common.h:38
uint16_t check
Definition: proto.h:150
uint8_t proto_addr_size
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:81
uint16_t proto_addr_type
Definition: proto.h:70
unsigned __int8 uint8_t
Definition: config-msvc.h:123
uint32_t saddr
Definition: proto.h:105
uint16_t tot_len
Definition: proto.h:90
uint16_t icmp6_cksum
Definition: proto.h:139
bool is_ipv4(int tunnel_type, struct buffer *buf)
Definition: proto.c:91
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
uint16_t check
Definition: proto.h:104
uint16_t mac_addr_type
Definition: proto.h:68
uint8_t ttl
Definition: proto.h:96
uint16_t arp_command
Definition: proto.h:76
unsigned __int16 uint16_t
Definition: config-msvc.h:122
#define OPENVPN_ETH_ALEN
Definition: proto.h:54
uint16_t dest
Definition: proto.h:148
uint16_t urg_ptr
Definition: proto.h:177
uint8_t doff_res
Definition: proto.h:163
uint16_t source
Definition: proto.h:147
uint16_t payload_len
Definition: proto.h:116
#define DEV_TYPE_TAP
Definition: proto.h:38