ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/device-linux.C
Revision: 1.5
Committed: Thu Oct 16 02:41:21 2003 UTC (20 years, 7 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.4: +1 -0 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 device-linux.C -- Interaction with Linux tun/tap device
3 Copyright (C) 2003 Marc Lehmann <pcg@goof.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 #include "config.h"
21
22 #include <cstdio>
23 #include <cstring>
24 #include <cstdlib>
25
26 #include <errno.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <net/if.h>
31 #include <unistd.h>
32 #include <sys/ioctl.h>
33
34 #include <net/if.h>
35
36 #ifdef LINUX_IF_TUN_H
37 # include LINUX_IF_TUN_H
38 #else
39 #include <linux/if_tun.h>
40 #endif
41 #define DEFAULT_DEVICE "/dev/net/tun"
42
43 #include "gettext.h"
44
45 #include "conf.h"
46
47 #if TEST_ETHEREMU
48 # include "ether_emu.C"
49 #endif
50
51 const char *
52 tap_device::info ()
53 {
54 return _("Linux tun/tap device");
55 }
56
57 tap_device::tap_device ()
58 {
59 struct ifreq ifr;
60
61 device = DEFAULT_DEVICE;
62
63 fd = open (device, O_RDWR);
64
65 if (fd < 0)
66 {
67 slog (L_ERR, _("could not open device %s: %s"), device, strerror (errno));
68 exit (1);
69 }
70
71 memset (&ifr, 0, sizeof (ifr));
72 #if TEST_ETHEREMU
73 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
74 #else
75 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
76 #endif
77
78 if (conf.ifname)
79 strncpy (ifr.ifr_name, conf.ifname, IFNAMSIZ);
80 else
81 ifr.ifr_name[0] = 0;
82
83 if (!ioctl (fd, TUNSETIFF, &ifr))
84 {
85 strncpy (ifrname, ifr.ifr_name, IFNAMSIZ);
86 ifrname [IFNAMSIZ] = 0;
87 }
88 else
89 {
90 slog (L_CRIT, _("unable to configure tun/tap interface: %s"), strerror (errno));
91 exit (1);
92 }
93
94 if (ioctl (fd, TUNSETPERSIST, conf.ifpersist ? 1 : 0))
95 slog (L_WARN, _("cannot set persistency mode for device %s: %s"), ifrname, strerror (errno));
96
97 slog (L_DEBUG, _("%s is a %s"), device, info ());
98 }
99
100 tap_device::~tap_device ()
101 {
102 close (fd);
103 }
104
105 tap_packet *
106 tap_device::recv ()
107 {
108 tap_packet *pkt = new tap_packet;
109
110 #if TEST_ETHEREMU
111 pkt->len = read (fd, &((*pkt)[14]), MAX_MTU - 14);
112 #else
113 pkt->len = read (fd, &((*pkt)[0]), MAX_MTU);
114 #endif
115
116 if (pkt->len <= 0)
117 {
118 delete pkt;
119 slog (L_ERR, _("error while reading from %s %s: %s"),
120 info (), DEFAULT_DEVICE, strerror (errno));
121 return 0;
122 }
123
124 #if TEST_ETHEREMU
125 pkt->len += 14;
126
127 // assume ipv4
128 (*pkt)[12] = 0x08;
129 (*pkt)[13] = 0x00;
130
131 if (!ether_emu.tun_to_tap (pkt))
132 {
133 delete pkt;
134 return 0;
135 }
136 #endif
137
138 return pkt;
139 }
140
141 void
142 tap_device::send (tap_packet *pkt)
143 {
144 #if TEST_ETHEREMU
145 if (ether_emu.tap_to_tun (pkt) &&
146 write (fd, &((*pkt)[14]), pkt->len - 14) < 0)
147 #else
148 if (write (fd, &((*pkt)[0]), pkt->len) < 0)
149 #endif
150 slog (L_ERR, _("can't write to %s %s: %s"), info (), DEFAULT_DEVICE,
151 strerror (errno));
152 }
153