ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/device-tincd.C
Revision: 1.22
Committed: Tue Feb 8 23:11:35 2011 UTC (13 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-3_0, rel-2_25, HEAD
Changes since 1.21: +0 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 /*
2     device-tincd.C -- include one of the tincd low level implementations.
3 pcg 1.21 Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de>
4 pcg 1.1
5 pcg 1.12 This file is part of GVPE.
6    
7 pcg 1.21 GVPE is free software; you can redistribute it and/or modify it
8     under the terms of the GNU General Public License as published by the
9     Free Software Foundation; either version 3 of the License, or (at your
10     option) any later version.
11    
12     This program is distributed in the hope that it will be useful, but
13     WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15     Public License for more details.
16    
17     You should have received a copy of the GNU General Public License along
18     with this program; if not, see <http://www.gnu.org/licenses/>.
19    
20     Additional permission under GNU GPL version 3 section 7
21    
22     If you modify this Program, or any covered work, by linking or
23     combining it with the OpenSSL project's OpenSSL library (or a modified
24     version of that library), containing parts covered by the terms of the
25     OpenSSL or SSLeay licenses, the licensors of this Program grant you
26     additional permission to convey the resulting work. Corresponding
27     Source for a non-source form of such a combination shall include the
28     source code for the parts of OpenSSL used as well as that of the
29     covered work.
30 pcg 1.1 */
31    
32     #include <cstdio>
33     #include <cstring>
34     #include <cerrno>
35    
36     #include <sys/types.h>
37     #include <sys/stat.h>
38     #include <sys/ioctl.h>
39     #include <unistd.h>
40     #include <syslog.h>
41     #include <fcntl.h>
42    
43     #include "conf.h"
44    
45 pcg 1.3 // following headers used by cygwin (maybe others)
46     #include "netcompat.h"
47     #include <signal.h>
48    
49     #define xstrdup(strd) strdup(str)
50    
51 pcg 1.2 /* make the tincd sources feel comfortable in our environment. */
52     /* this was reasonably easy to do. */
53 pcg 1.1 #define routing_mode 1
54     #define RMODE_ROUTER 0
55    
56 pcg 1.2 #define LOG_TO_L(level) \
57 pcg 1.1 (level) == LOG_ERR ? L_ERR \
58     : (level) == LOG_DEBUG ? L_DEBUG \
59     : (level) == LOG_WARNING ? L_WARN \
60     : (level) == LOG_INFO ? L_INFO \
61 pcg 1.2 : L_NOTICE
62    
63     #if __STDC_VERSION__ > 199900
64     # define logger(level, ...) slog (LOG_TO_L(level), __VA_ARGS__)
65     #elif __GNUC__
66     # define logger(level, args...) slog (LOG_TO_L(level), ## args)
67     #else
68     # error either need ISO-C 99 compliant compiler or gcc.
69     #endif
70 pcg 1.1
71     #define ifdebug(subsys) if (0)
72    
73     #define cp()
74     #define lookup_config(config_tree,key) (key)
75    
76 pcg 1.14 #define MTU MAX_MTU
77 pcg 1.1
78     // BIGGEST hack of 'em all
79     // will be casted to data_packet, due to structural similarity
80 pcg 1.20 struct vpn_packet_t : net_packet
81     {
82 pcg 1.1 u8 data[MAXSIZE];
83     };
84    
85     static bool overwrite_mac;
86    
87     static bool
88     get_config_string(const char *key, char **res)
89     {
90     if (!strcmp (key, "Interface"))
91     *res = conf.ifname;
92     else if (!strcmp (key, "Device"))
93     *res = 0;
94 pcg 1.18 else if (!strcmp (key, "DeviceType"))
95     *res = "tap";
96 pcg 1.1 else
97     {
98     slog (L_ERR, _("tincd layer asking for unknown config '%s'"), key);
99     *res = 0;
100     }
101    
102     return *res;
103     }
104    
105     #define netname conf.ifname
106    
107     #if IF_linux
108     # include "tincd/linux/device.c"
109 pcg 1.17 const char * tap_device::if_up () { return "/sbin/ifconfig $IFNAME hw ether $MAC mtu $MTU"; }
110 pcg 1.6
111 pcg 1.18 #elif IF_bsd
112     # include "tincd/bsd/device.c"
113     const char * tap_device::if_up () { return "/sbin/ifconfig $IFNAME ether $MAC mtu $MTU"; }
114    
115 pcg 1.1 #elif IF_freebsd
116     # include "tincd/freebsd/device.c"
117 pcg 1.17 const char * tap_device::if_up () { return "/sbin/ifconfig $IFNAME ether $MAC mtu $MTU"; }
118 pcg 1.6
119 pcg 1.1 #elif IF_netbsd
120 pcg 1.11 # define IF_istun 1
121 pcg 1.1 # include "tincd/netbsd/device.c"
122 pcg 1.17 const char * tap_device::if_up () { return "/sbin/ifconfig $IFNAME mtu $MTU"; }
123 pcg 1.6
124     #elif IF_openbsd
125 pcg 1.11 # define IF_istun 1
126 pcg 1.6 # include "tincd/openbsd/device.c"
127 pcg 1.17 const char * tap_device::if_up () { return "/sbin/ifconfig $IFNAME mtu $MTU"; }
128 pcg 1.6
129 pcg 1.1 #elif IF_solaris
130 pcg 1.11 # define IF_istun 1
131 pcg 1.1 # include "tincd/solaris/device.c"
132 pcg 1.15 const char * tap_device::if_up () { return ""; }
133 pcg 1.6
134 pcg 1.1 #elif IF_cygwin
135     # include "tincd/cygwin/device.c"
136 pcg 1.15 const char * tap_device::if_up () { return ""; }
137 pcg 1.6
138 pcg 1.1 #elif IF_mingw
139     # include "tincd/mingw/device.c"
140 pcg 1.15 const char * tap_device::if_up () { return ""; }
141 pcg 1.6
142 pcg 1.1 #elif IF_darwin
143 pcg 1.11 # define IF_istun 1
144 pcg 1.1 # include "tincd/darwin/device.c"
145 pcg 1.17 const char * tap_device::if_up () { return "/sbin/ifconfig $IFNAME ether $MAC mtu $MTU"; }
146 pcg 1.6
147 pcg 1.1 #elif IF_raw_socket
148     # include "tincd/raw_socket/device.c"
149 pcg 1.17 const char * tap_device::if_up () { return "/sbin/ifconfig $IFNAME ether $MAC mtu $MTU"; }
150 pcg 1.6
151 pcg 1.13 #elif IF_uml_socket
152     # include "tincd/uml_socket/device.c"
153 pcg 1.15 const char * tap_device::if_up () { return 0; }
154 pcg 1.13
155 pcg 1.1 #else
156     # error No interface implementation for your IFTYPE/IFSUBTYPE combination.
157     #endif
158    
159 pcg 1.5 #if IF_istun
160     # include "ether_emu.C"
161     #endif
162    
163 pcg 1.1 const char *
164     tap_device::info ()
165     {
166     return _("tincd compatibility layer");
167     }
168    
169     tap_device::tap_device ()
170     {
171 pcg 1.8 device = "(null)";
172    
173 pcg 1.13 bool ok = setup_device ();
174    
175     if (device_info)
176     device = device_info;
177    
178     if (ok)
179 pcg 1.1 {
180 pcg 1.8 slog (L_DEBUG, _("interface %s on %s initialized"), info (), device);
181 pcg 1.1 fd = device_fd;
182     strcpy (ifrname, iface);
183     }
184     else
185     {
186 pcg 1.8 slog (L_ERR, _("error while configuring tincd device %s on %s"), info (), device);
187 pcg 1.10 exit (EXIT_FAILURE);
188 pcg 1.1 }
189     }
190    
191     tap_device::~tap_device ()
192     {
193     close_device ();
194     }
195    
196     tap_packet *
197     tap_device::recv ()
198     {
199     tap_packet *pkt = new tap_packet;
200    
201     if (!read_packet (reinterpret_cast<vpn_packet_t *>(pkt)))
202     {
203     delete pkt;
204 pcg 1.13 slog (L_ERR, _("can't read from to %s %s: %s"), info (), device,
205 pcg 1.1 strerror (errno));
206     return 0;
207     }
208    
209 pcg 1.5 #if IF_istun
210     // assume ipv4
211     (*pkt)[12] = 0x08;
212     (*pkt)[13] = 0x00;
213    
214     if (!ether_emu.tun_to_tap (pkt))
215     {
216     delete pkt;
217     return 0;
218     }
219     #endif
220    
221 pcg 1.1 return pkt;
222     }
223    
224     void
225     tap_device::send (tap_packet *pkt)
226     {
227 pcg 1.5 if (
228     #if IF_istun
229     ether_emu.tap_to_tun (pkt) &&
230     #endif
231     !write_packet (reinterpret_cast<vpn_packet_t *>(pkt)))
232 pcg 1.13 slog (L_ERR, _("can't write to %s %s: %s"), info (), device,
233 pcg 1.1 strerror (errno));
234     }
235