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