1 /*
2  *  Copyright (C) 2015 Adrien Vergé
3  *
4  *  This program is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef OPENFORTIVPN_IPV4_H
19 #define OPENFORTIVPN_IPV4_H
20 
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <net/route.h>
25 
26 #if !HAVE_RT_ENTRY_WITH_RT_DST
27 /*
28  * On Mac OS X and FreeBSD struct rtentry_ofvpn is not directly available.
29  * On FreeBSD one could #define _WANT_RTENTRY but the struct does not
30  * contain rt_dst for instance. The entries for mask and destination
31  * are maintained in a separate radix_tree structure by the routing
32  * table instance. We can not simply copy rtentry_ofvpn structures.
33  */
34 
35 /* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */
36 struct rtentry_ofvpn {
37 	unsigned long   rt_hash;        /* hash key for lookups         */
38 	struct sockaddr rt_dst;         /* target address               */
39 	struct sockaddr rt_gateway;     /* gateway addr (RTF_GATEWAY)   */
40 	struct sockaddr rt_genmask;     /* target network mask (IP)     */
41 	short           rt_flags;
42 	short           rt_refcnt;
43 	unsigned long   rt_use_ofvpn;
44 	struct ifnet    *rt_ifp;
45 	short           rt_metric;      /* +1 for binary compatibility! */
46 	char            *rt_dev;        /* forcing the device at add    */
47 	unsigned long   rt_mss;         /* per route MTU/Window         */
48 	unsigned long   rt_mtu;         /* compatibility                */
49 	unsigned long   rt_window;      /* Window clamping              */
50 	unsigned short  rt_irtt;        /* Initial RTT                  */
51 };
52 #endif
53 
54 #define ROUTE_IFACE_LEN 32
55 #define MAX_SPLIT_ROUTES 65535
56 #define STEP_SPLIT_ROUTES 32
57 
58 struct ipv4_config {
59 	struct in_addr	ip_addr;
60 
61 	struct in_addr	ns1_addr;
62 	struct in_addr	ns2_addr;
63 	char		*dns_suffix;
64 	int		ns1_was_there;  // were ns1 already in /etc/resolv.conf?
65 	int		ns2_was_there;  // were ns2 already in /etc/resolv.conf?
66 	int		dns_suffix_was_there; // was the dns suffix already there?
67 	int		split_routes;
68 	int		route_to_vpn_is_added;
69 
70 	struct rtentry_ofvpn	def_rt; // default route
71 	struct rtentry_ofvpn	gtw_rt; // route to access VPN gateway
72 	struct rtentry_ofvpn	ppp_rt; // new default route through VPN
73 	struct rtentry_ofvpn	*split_rt; // split VPN routes
74 };
75 
76 // Dummy function to make gcc 6 happy
cast_addr(struct sockaddr * addr)77 static inline struct sockaddr_in *cast_addr(struct sockaddr *addr)
78 {
79 	return (struct sockaddr_in *) addr;
80 }
81 #define route_dest(route)  (cast_addr(&(route)->rt_dst)->sin_addr)
82 #define route_mask(route)  (cast_addr(&(route)->rt_genmask)->sin_addr)
83 #define route_gtw(route)   (cast_addr(&(route)->rt_gateway)->sin_addr)
84 #define route_iface(route) ((route)->rt_dev)
85 
86 struct tunnel;
87 
88 int ipv4_add_split_vpn_route(struct tunnel *tunnel, char *dest, char *mask,
89                              char *gateway);
90 int ipv4_set_tunnel_routes(struct tunnel *tunnel);
91 int ipv4_restore_routes(struct tunnel *tunnel);
92 
93 int ipv4_add_nameservers_to_resolv_conf(struct tunnel *tunnel);
94 int ipv4_del_nameservers_from_resolv_conf(struct tunnel *tunnel);
95 
96 #endif
97