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

# User Rev Content
1 pcg 1.1 /*
2     device-linux.C -- Interaction with Linux tun/tap device
3 pcg 1.18 Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de>
4 pcg 1.1
5 pcg 1.9 This file is part of GVPE.
6    
7 pcg 1.18 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 "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 pcg 1.3 #include <net/if.h>
47    
48 pcg 1.1 #ifdef LINUX_IF_TUN_H
49 pcg 1.3 # include LINUX_IF_TUN_H
50 pcg 1.1 #else
51     #include <linux/if_tun.h>
52     #endif
53     #define DEFAULT_DEVICE "/dev/net/tun"
54    
55 pcg 1.11 #include "gettext.h"
56    
57 pcg 1.1 #include "conf.h"
58    
59 pcg 1.4 #if TEST_ETHEREMU
60 pcg 1.6 # define IF_istun
61 pcg 1.4 # include "ether_emu.C"
62     #endif
63    
64 pcg 1.3 const char *
65     tap_device::info ()
66     {
67     return _("Linux tun/tap device");
68     }
69    
70 pcg 1.12 const char *
71     tap_device::if_up ()
72     {
73 pcg 1.13 return "/sbin/ifconfig $IFNAME hw ether $MAC mtu $MTU";
74 pcg 1.12 }
75    
76 pcg 1.1 tap_device::tap_device ()
77     {
78     struct ifreq ifr;
79    
80 pcg 1.17 device = (char *)DEFAULT_DEVICE;
81 pcg 1.1
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 pcg 1.8 exit (EXIT_FAILURE);
88 pcg 1.1 }
89    
90     memset (&ifr, 0, sizeof (ifr));
91 pcg 1.4 #if TEST_ETHEREMU
92     ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
93     #else
94 pcg 1.1 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
95 pcg 1.4 #endif
96 pcg 1.1
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 pcg 1.14 slog (L_CRIT, _("unable to configure tun/tap interface, exiting: %s"), strerror (errno));
110 pcg 1.8 exit (EXIT_FAILURE);
111 pcg 1.1 }
112    
113 pcg 1.14 #if 0
114 pcg 1.15 does not work
115 pcg 1.14 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 pcg 1.2 if (ioctl (fd, TUNSETPERSIST, conf.ifpersist ? 1 : 0))
124     slog (L_WARN, _("cannot set persistency mode for device %s: %s"), ifrname, strerror (errno));
125 pcg 1.1
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 pcg 1.4 #if TEST_ETHEREMU
140     pkt->len = read (fd, &((*pkt)[14]), MAX_MTU - 14);
141     #else
142 pcg 1.1 pkt->len = read (fd, &((*pkt)[0]), MAX_MTU);
143 pcg 1.4 #endif
144 pcg 1.1
145     if (pkt->len <= 0)
146     {
147 pcg 1.3 delete pkt;
148 pcg 1.1 slog (L_ERR, _("error while reading from %s %s: %s"),
149     info (), DEFAULT_DEVICE, strerror (errno));
150     return 0;
151     }
152    
153 pcg 1.4 #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 pcg 1.1 return pkt;
168     }
169    
170     void
171     tap_device::send (tap_packet *pkt)
172     {
173 pcg 1.4 #if TEST_ETHEREMU
174     if (ether_emu.tap_to_tun (pkt) &&
175     write (fd, &((*pkt)[14]), pkt->len - 14) < 0)
176     #else
177 pcg 1.1 if (write (fd, &((*pkt)[0]), pkt->len) < 0)
178 pcg 1.4 #endif
179 root 1.19 slog (L_ERR, _("can't write %d byte packet to %s %s: %s"), pkt->len, info (), DEFAULT_DEVICE,
180 pcg 1.1 strerror (errno));
181     }
182