ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/tincd/solaris/device.c
Revision: 1.2
Committed: Thu Mar 17 23:59:38 2005 UTC (19 years, 3 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: rel-1_9, rel-1_8, rel-2_01, rel-3_0, rel-2_2, rel-2_0, rel-2_21, rel-2_22, rel-2_25, HEAD
Changes since 1.1: +21 -9 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 device.c -- Interaction with Solaris tun device
3 Copyright (C) 2001-2004 Ivo Timmermans <ivo@tinc-vpn.org>,
4 2001-2004 Guus Sliepen <guus@tinc-vpn.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 $Id: device.c 1412 2004-11-10 21:14:08Z guus $
21 */
22
23
24 #include "system.h"
25
26 #include <sys/stropts.h>
27 #include <sys/sockio.h>
28 #include <net/if_tun.h>
29
30 #define DEFAULT_DEVICE "/dev/tun"
31
32 int device_fd = -1;
33 char *device = NULL;
34 char *iface = NULL;
35 char *device_info = NULL;
36
37 static int device_total_in = 0;
38 static int device_total_out = 0;
39
40 bool setup_device(void)
41 {
42 int ip_fd = -1, if_fd = -1;
43 int ppa;
44 char *ptr;
45
46 cp();
47
48 if(!get_config_string(lookup_config(config_tree, "Device"), &device))
49 device = DEFAULT_DEVICE;
50
51 if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) {
52 logger(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno));
53 return false;
54 }
55
56 ppa = 0;
57
58 ptr = device;
59 while(*ptr && !isdigit((int) *ptr))
60 ptr++;
61 ppa = atoi(ptr);
62
63 if((ip_fd = open("/dev/ip", O_RDWR, 0)) < 0) {
64 logger(LOG_ERR, _("Could not open /dev/ip: %s"), strerror(errno));
65 return false;
66 }
67
68 /* Assign a new PPA and get its unit number. */
69 if((ppa = ioctl(device_fd, TUNNEWPPA, ppa)) < 0) {
70 logger(LOG_ERR, _("Can't assign new interface: %s"), strerror(errno));
71 return false;
72 }
73
74 if((if_fd = open(device, O_RDWR, 0)) < 0) {
75 logger(LOG_ERR, _("Could not open %s twice: %s"), device,
76 strerror(errno));
77 return false;
78 }
79
80 if(ioctl(if_fd, I_PUSH, "ip") < 0) {
81 logger(LOG_ERR, _("Can't push IP module: %s"), strerror(errno));
82 return false;
83 }
84
85 /* Assign ppa according to the unit number returned by tun device */
86 if(ioctl(if_fd, IF_UNITSEL, (char *) &ppa) < 0) {
87 logger(LOG_ERR, _("Can't set PPA %d: %s"), ppa, strerror(errno));
88 return false;
89 }
90
91 if(ioctl(ip_fd, I_LINK, if_fd) < 0) {
92 logger(LOG_ERR, _("Can't link TUN device to IP: %s"), strerror(errno));
93 return false;
94 }
95
96 if(!get_config_string(lookup_config(config_tree, "Interface"), &iface))
97 asprintf(&iface, "tun%d", ppa);
98
99 device_info = _("Solaris tun device");
100
101 logger(LOG_INFO, _("%s is a %s"), device, device_info);
102
103 return true;
104 }
105
106 void close_device(void)
107 {
108 cp();
109
110 close(device_fd);
111 }
112
113 bool read_packet(vpn_packet_t *packet)
114 {
115 int lenin;
116
117 cp();
118
119 if((lenin = read(device_fd, packet->data + 14, MTU - 14)) <= 0) {
120 logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info,
121 device, strerror(errno));
122 return false;
123 }
124
125 switch(packet->data[14] >> 4) {
126 case 4:
127 packet->data[12] = 0x08;
128 packet->data[13] = 0x00;
129 break;
130 case 6:
131 packet->data[12] = 0x86;
132 packet->data[13] = 0xDD;
133 break;
134 default:
135 ifdebug(TRAFFIC) logger(LOG_ERR,
136 _ ("Unknown IP version %d while reading packet from %s %s"),
137 packet->data[14] >> 4, device_info, device);
138 return false;
139 }
140
141 packet->len = lenin + 14;
142
143 device_total_in += packet->len;
144
145 ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len,
146 device_info);
147
148 return true;
149 }
150
151 bool write_packet(vpn_packet_t *packet)
152 {
153 cp();
154
155 ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Writing packet of %d bytes to %s"),
156 packet->len, device_info);
157
158 if(write(device_fd, packet->data + 14, packet->len - 14) < 0) {
159 logger(LOG_ERR, _("Can't write to %s %s: %s"), device_info,
160 device, strerror(errno));
161 return false;
162 }
163
164 device_total_out += packet->len;
165
166 return true;
167 }
168
169 void dump_device_stats(void)
170 {
171 cp();
172
173 logger(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
174 logger(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in);
175 logger(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out);
176 }