ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/device-linux.C
Revision: 1.19
Committed: Thu Jan 29 00:21:39 2015 UTC (9 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-3_0, HEAD
Changes since 1.18: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 device-linux.C -- Interaction with Linux tun/tap device
3 Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de>
4
5 This file is part of GVPE.
6
7 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 */
31
32 #include "config.h"
33
34 #include <cstdio>
35 #include <cstring>
36 #include <cstdlib>
37
38 #include <errno.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <fcntl.h>
42 #include <net/if.h>
43 #include <unistd.h>
44 #include <sys/ioctl.h>
45
46 #include <net/if.h>
47
48 #ifdef LINUX_IF_TUN_H
49 # include LINUX_IF_TUN_H
50 #else
51 #include <linux/if_tun.h>
52 #endif
53 #define DEFAULT_DEVICE "/dev/net/tun"
54
55 #include "gettext.h"
56
57 #include "conf.h"
58
59 #if TEST_ETHEREMU
60 # define IF_istun
61 # include "ether_emu.C"
62 #endif
63
64 const char *
65 tap_device::info ()
66 {
67 return _("Linux tun/tap device");
68 }
69
70 const char *
71 tap_device::if_up ()
72 {
73 return "/sbin/ifconfig $IFNAME hw ether $MAC mtu $MTU";
74 }
75
76 tap_device::tap_device ()
77 {
78 struct ifreq ifr;
79
80 device = (char *)DEFAULT_DEVICE;
81
82 fd = open (device, O_RDWR);
83
84 if (fd < 0)
85 {
86 slog (L_ERR, _("could not open device %s: %s"), device, strerror (errno));
87 exit (EXIT_FAILURE);
88 }
89
90 memset (&ifr, 0, sizeof (ifr));
91 #if TEST_ETHEREMU
92 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
93 #else
94 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
95 #endif
96
97 if (conf.ifname)
98 strncpy (ifr.ifr_name, conf.ifname, IFNAMSIZ);
99 else
100 ifr.ifr_name[0] = 0;
101
102 if (!ioctl (fd, TUNSETIFF, &ifr))
103 {
104 strncpy (ifrname, ifr.ifr_name, IFNAMSIZ);
105 ifrname [IFNAMSIZ] = 0;
106 }
107 else
108 {
109 slog (L_CRIT, _("unable to configure tun/tap interface, exiting: %s"), strerror (errno));
110 exit (EXIT_FAILURE);
111 }
112
113 #if 0
114 does not work
115 id2mac (THISNODE->id, &ifr.ifr_hwaddr.sa_data);
116 if (ioctl (fd, SIOCSIFHWADDR, &ifr))
117 {
118 slog (L_ERR, _("cannot set MAC address for device %s, exiting: %s"), ifrname, strerror (errno));
119 exit (EXIT_FAILURE);
120 }
121 #endif
122
123 if (ioctl (fd, TUNSETPERSIST, conf.ifpersist ? 1 : 0))
124 slog (L_WARN, _("cannot set persistency mode for device %s: %s"), ifrname, strerror (errno));
125
126 slog (L_DEBUG, _("%s is a %s"), device, info ());
127 }
128
129 tap_device::~tap_device ()
130 {
131 close (fd);
132 }
133
134 tap_packet *
135 tap_device::recv ()
136 {
137 tap_packet *pkt = new tap_packet;
138
139 #if TEST_ETHEREMU
140 pkt->len = read (fd, &((*pkt)[14]), MAX_MTU - 14);
141 #else
142 pkt->len = read (fd, &((*pkt)[0]), MAX_MTU);
143 #endif
144
145 if (pkt->len <= 0)
146 {
147 delete pkt;
148 slog (L_ERR, _("error while reading from %s %s: %s"),
149 info (), DEFAULT_DEVICE, strerror (errno));
150 return 0;
151 }
152
153 #if TEST_ETHEREMU
154 pkt->len += 14;
155
156 // assume ipv4
157 (*pkt)[12] = 0x08;
158 (*pkt)[13] = 0x00;
159
160 if (!ether_emu.tun_to_tap (pkt))
161 {
162 delete pkt;
163 return 0;
164 }
165 #endif
166
167 return pkt;
168 }
169
170 void
171 tap_device::send (tap_packet *pkt)
172 {
173 #if TEST_ETHEREMU
174 if (ether_emu.tap_to_tun (pkt) &&
175 write (fd, &((*pkt)[14]), pkt->len - 14) < 0)
176 #else
177 if (write (fd, &((*pkt)[0]), pkt->len) < 0)
178 #endif
179 slog (L_ERR, _("can't write %d byte packet to %s %s: %s"), pkt->len, info (), DEFAULT_DEVICE,
180 strerror (errno));
181 }
182