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

# User Rev Content
1 pcg 1.1 /*
2     device.c -- Interaction with Solaris tun device
3 pcg 1.2 Copyright (C) 2001-2004 Ivo Timmermans <ivo@tinc-vpn.org>,
4     2001-2004 Guus Sliepen <guus@tinc-vpn.org>
5 pcg 1.1
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 pcg 1.2 $Id: device.c 1412 2004-11-10 21:14:08Z guus $
21 pcg 1.1 */
22    
23    
24 pcg 1.2 #include "system.h"
25 pcg 1.1
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 pcg 1.2 static int device_total_in = 0;
38     static int device_total_out = 0;
39 pcg 1.1
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 pcg 1.2 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 pcg 1.1
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     }