ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/device-linux.C
Revision: 1.6
Committed: Thu Oct 16 13:37:10 2003 UTC (20 years, 7 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: poll-based-iom, VPE_1_2
Changes since 1.5: +1 -0 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.5 Copyright (C) 2003 Marc Lehmann <pcg@goof.com>
4 pcg 1.1
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 pcg 1.3 #include <net/if.h>
35    
36 pcg 1.1 #ifdef LINUX_IF_TUN_H
37 pcg 1.3 # include LINUX_IF_TUN_H
38 pcg 1.1 #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 pcg 1.4 #if TEST_ETHEREMU
48 pcg 1.6 # define IF_istun
49 pcg 1.4 # include "ether_emu.C"
50     #endif
51    
52 pcg 1.3 const char *
53     tap_device::info ()
54     {
55     return _("Linux tun/tap device");
56     }
57    
58 pcg 1.1 tap_device::tap_device ()
59     {
60     struct ifreq ifr;
61    
62     device = DEFAULT_DEVICE;
63    
64     fd = open (device, O_RDWR);
65    
66     if (fd < 0)
67     {
68     slog (L_ERR, _("could not open device %s: %s"), device, strerror (errno));
69     exit (1);
70     }
71    
72     memset (&ifr, 0, sizeof (ifr));
73 pcg 1.4 #if TEST_ETHEREMU
74     ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
75     #else
76 pcg 1.1 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
77 pcg 1.4 #endif
78 pcg 1.1
79     if (conf.ifname)
80     strncpy (ifr.ifr_name, conf.ifname, IFNAMSIZ);
81     else
82     ifr.ifr_name[0] = 0;
83    
84     if (!ioctl (fd, TUNSETIFF, &ifr))
85     {
86     strncpy (ifrname, ifr.ifr_name, IFNAMSIZ);
87     ifrname [IFNAMSIZ] = 0;
88     }
89     else
90     {
91     slog (L_CRIT, _("unable to configure tun/tap interface: %s"), strerror (errno));
92     exit (1);
93     }
94    
95 pcg 1.2 if (ioctl (fd, TUNSETPERSIST, conf.ifpersist ? 1 : 0))
96     slog (L_WARN, _("cannot set persistency mode for device %s: %s"), ifrname, strerror (errno));
97 pcg 1.1
98     slog (L_DEBUG, _("%s is a %s"), device, info ());
99     }
100    
101     tap_device::~tap_device ()
102     {
103     close (fd);
104     }
105    
106     tap_packet *
107     tap_device::recv ()
108     {
109     tap_packet *pkt = new tap_packet;
110    
111 pcg 1.4 #if TEST_ETHEREMU
112     pkt->len = read (fd, &((*pkt)[14]), MAX_MTU - 14);
113     #else
114 pcg 1.1 pkt->len = read (fd, &((*pkt)[0]), MAX_MTU);
115 pcg 1.4 #endif
116 pcg 1.1
117     if (pkt->len <= 0)
118     {
119 pcg 1.3 delete pkt;
120 pcg 1.1 slog (L_ERR, _("error while reading from %s %s: %s"),
121     info (), DEFAULT_DEVICE, strerror (errno));
122     return 0;
123     }
124    
125 pcg 1.4 #if TEST_ETHEREMU
126     pkt->len += 14;
127    
128     // assume ipv4
129     (*pkt)[12] = 0x08;
130     (*pkt)[13] = 0x00;
131    
132     if (!ether_emu.tun_to_tap (pkt))
133     {
134     delete pkt;
135     return 0;
136     }
137     #endif
138    
139 pcg 1.1 return pkt;
140     }
141    
142     void
143     tap_device::send (tap_packet *pkt)
144     {
145 pcg 1.4 #if TEST_ETHEREMU
146     if (ether_emu.tap_to_tun (pkt) &&
147     write (fd, &((*pkt)[14]), pkt->len - 14) < 0)
148     #else
149 pcg 1.1 if (write (fd, &((*pkt)[0]), pkt->len) < 0)
150 pcg 1.4 #endif
151 pcg 1.1 slog (L_ERR, _("can't write to %s %s: %s"), info (), DEFAULT_DEVICE,
152     strerror (errno));
153     }
154