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

# 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     # include "ether_emu.C"
49     #endif
50    
51 pcg 1.3 const char *
52     tap_device::info ()
53     {
54     return _("Linux tun/tap device");
55     }
56    
57 pcg 1.1 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 pcg 1.4 #if TEST_ETHEREMU
73     ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
74     #else
75 pcg 1.1 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
76 pcg 1.4 #endif
77 pcg 1.1
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 pcg 1.2 if (ioctl (fd, TUNSETPERSIST, conf.ifpersist ? 1 : 0))
95     slog (L_WARN, _("cannot set persistency mode for device %s: %s"), ifrname, strerror (errno));
96 pcg 1.1
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 pcg 1.4 #if TEST_ETHEREMU
111     pkt->len = read (fd, &((*pkt)[14]), MAX_MTU - 14);
112     #else
113 pcg 1.1 pkt->len = read (fd, &((*pkt)[0]), MAX_MTU);
114 pcg 1.4 #endif
115 pcg 1.1
116     if (pkt->len <= 0)
117     {
118 pcg 1.3 delete pkt;
119 pcg 1.1 slog (L_ERR, _("error while reading from %s %s: %s"),
120     info (), DEFAULT_DEVICE, strerror (errno));
121     return 0;
122     }
123    
124 pcg 1.4 #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 pcg 1.1 return pkt;
139     }
140    
141     void
142     tap_device::send (tap_packet *pkt)
143     {
144 pcg 1.4 #if TEST_ETHEREMU
145     if (ether_emu.tap_to_tun (pkt) &&
146     write (fd, &((*pkt)[14]), pkt->len - 14) < 0)
147     #else
148 pcg 1.1 if (write (fd, &((*pkt)[0]), pkt->len) < 0)
149 pcg 1.4 #endif
150 pcg 1.1 slog (L_ERR, _("can't write to %s %s: %s"), info (), DEFAULT_DEVICE,
151     strerror (errno));
152     }
153