chiark / gitweb /
Fix logrotate script.
[tripe] / tun-bsd.c
1 /* -*-c-*-
2  *
3  * $Id: tun-bsd.c,v 1.2 2003/11/29 23:49:32 mdw Exp $
4  *
5  * Tunnel interface for 4.4BSD-derived systems
6  *
7  * (c) 2001 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of Trivial IP Encryption (TrIPE).
13  *
14  * TrIPE is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  * 
19  * TrIPE is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * 
24  * You should have received a copy of the GNU General Public License
25  * along with TrIPE; if not, write to the Free Software Foundation,
26  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27  */
28
29 /*----- Revision history --------------------------------------------------* 
30  *
31  * $Log: tun-bsd.c,v $
32  * Revision 1.2  2003/11/29 23:49:32  mdw
33  * Debianization.
34  *
35  * Revision 1.1  2001/02/05 19:48:18  mdw
36  * Initial support for BSD tunnel devices.
37  *
38  */
39
40 /*----- Header files ------------------------------------------------------*/
41
42 #include "tripe.h"
43
44 /*----- Main code ---------------------------------------------------------*/
45
46 #if TUN_TYPE != TUN_BSD
47 #  error "Tunnel type mismatch: fix the Makefile"
48 #endif
49
50 /* --- @t_read@ --- *
51  *
52  * Arguments:   @int fd@ = file descriptor to read
53  *              @unsigned mode@ = what's happened
54  *              @void *v@ = pointer to tunnel block
55  *
56  * Returns:     ---
57  *
58  * Use:         Reads data from the tunnel.
59  */
60
61 void t_read(int fd, unsigned mode, void *v)
62 {
63   tunnel *t = v;
64   ssize_t n;
65   buf b;
66
67   n = read(fd, buf_i, sizeof(buf_i));
68   if (n < 0) {
69     a_warn("tunnel read failed (%s): %s", tun_ifname(t), strerror(errno));
70     return;
71   }
72   IF_TRACING(T_TUNNEL, {
73     trace(T_TUNNEL, "tunnel: packet arrived");
74     trace_block(T_PACKET, "tunnel: packet contents", buf_i, n);
75   })
76   buf_init(&b, buf_i, n);
77   p_tun(t->p, &b);
78 }
79
80 /* --- @tun_init@ --- *
81  *
82  * Arguments:   ---
83  *
84  * Returns:     ---
85  *
86  * Use:         Initializes the tunneling system.  Maybe this will require
87  *              opening file descriptors or something.
88  */
89
90 void tun_init(void)
91 {
92   return;
93 }
94
95 /* --- @tun_create@ --- *
96  *
97  * Arguments:   @tunnel *t@ = pointer to tunnel block
98  *              @peer *p@ = pointer to peer block
99  *
100  * Returns:     Zero if it worked, nonzero on failure.
101  *
102  * Use:         Initializes a new tunnel.
103  */
104
105 int tun_create(tunnel *t, peer *p)
106 {
107   int fd;
108   unsigned n;
109   char buf[16];
110
111   n = 0;
112   for (;;) {
113     sprintf(buf, "/dev/tun%u", n);
114     if ((fd = open(buf, O_RDWR)) >= 0)
115       break;
116     switch (errno) {
117       case EBUSY:
118         T( trace(T_TUNNEL, "tunnel device %u busy: skipping", n); )
119         break;
120       case ENOENT:
121         a_warn("no suitable tunnel devices found");
122         return (-1);
123       default:
124         a_warn("error opening `%s': %s (skipping)", buf, strerror(errno));
125         break;
126     }
127     n++;
128   }
129
130   fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
131   t->p = p;
132   t->n = n;
133   sel_initfile(&sel, &t->f, fd, SEL_READ, t_read, t);
134   sel_addfile(&t->f);
135   T( trace(T_TUNNEL, "tunnel: attached interface %s to peer `%s'",
136            tun_ifname(t), p_name(p)); )
137   return (0);
138 }
139
140 /* --- @tun_ifname@ --- *
141  *
142  * Arguments:   @tunnel *t@ = pointer to tunnel block
143  *
144  * Returns:     A pointer to the tunnel's interface name.
145  */
146
147 const char *tun_ifname(tunnel *t)
148 {
149   static char buf[8];
150   sprintf(buf, "tun%u", t->n);
151   return (buf);
152 }
153
154 /* --- @tun_inject@ --- *
155  *
156  * Arguments:   @tunnel *t@ = pointer to tunnel block
157  *              @buf *b@ = buffer to send
158  *
159  * Returns:     ---
160  *
161  * Use:         Injects a packet into the local network stack.
162  */
163
164 void tun_inject(tunnel *t, buf *b)
165 {
166   IF_TRACING(T_TUNNEL, {
167     trace(T_TUNNEL, "tunnel: inject decrypted packet");
168     trace_block(T_PACKET, "tunnel: packet contents", BBASE(b), BLEN(b));
169   })
170   write(t->f.fd, BBASE(b), BLEN(b));
171 }
172
173 /* --- @tun_destroy@ --- *
174  *
175  * Arguments:   @tunnel *t@ = pointer to tunnel block
176  *
177  * Returns:     ---
178  *
179  * Use:         Destroys a tunnel.
180  */
181
182 void tun_destroy(tunnel *t)
183 {
184   sel_rmfile(&t->f);
185   close(t->f.fd);
186 }
187
188 /*----- That's all, folks -------------------------------------------------*/