chiark / gitweb /
Remove buf, and add Ethereal analysis.
[tripe] / tun-unet.c
CommitLineData
410c8acf 1/* -*-c-*-
2 *
60a837d8 3 * $Id: tun-unet.c,v 1.5 2002/01/13 14:57:05 mdw Exp $
410c8acf 4 *
5 * Tunnel interface based on Linux Usernet
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-unet.c,v $
60a837d8 32 * Revision 1.5 2002/01/13 14:57:05 mdw
33 * Make @t_read@ be static, as it always should have been.
34 *
a368bfbc 35 * Revision 1.4 2001/02/19 19:10:45 mdw
36 * Set unet devices to be point-to-point.
37 *
e78f24a2 38 * Revision 1.3 2001/02/05 19:55:00 mdw
39 * Guard against inappropriate compilation.
40 *
650a6624 41 * Revision 1.2 2001/02/04 17:10:58 mdw
42 * Make file descriptors be nonblocking and close-on-exec.
43 *
410c8acf 44 * Revision 1.1 2001/02/03 20:26:37 mdw
45 * Initial checkin.
46 *
47 */
48
49/*----- Header files ------------------------------------------------------*/
50
51#include "tripe.h"
52
53#include <sys/ioctl.h>
a368bfbc 54#include <net/if.h>
410c8acf 55#include <unet.h>
56
57/*----- Main code ---------------------------------------------------------*/
58
e78f24a2 59#if TUN_TYPE != TUN_UNET
60# error "Tunnel type mismatch: fix the Makefile"
61#endif
62
410c8acf 63/* --- @t_read@ --- *
64 *
65 * Arguments: @int fd@ = file descriptor to read
66 * @unsigned mode@ = what's happened
67 * @void *v@ = pointer to tunnel block
68 *
69 * Returns: ---
70 *
71 * Use: Reads data from the tunnel.
72 */
73
60a837d8 74static void t_read(int fd, unsigned mode, void *v)
410c8acf 75{
76 tunnel *t = v;
77 ssize_t n;
78 buf b;
79
80 n = read(fd, buf_i, sizeof(buf_i));
81 if (n < 0) {
82 a_warn("tunnel read failed (%s): %s", tun_ifname(t), strerror(errno));
83 return;
84 }
85 IF_TRACING(T_TUNNEL, {
86 trace(T_TUNNEL, "tunnel: packet arrived");
87 trace_block(T_PACKET, "tunnel: packet contents", buf_i, n);
88 })
89 buf_init(&b, buf_i, n);
90 p_tun(t->p, &b);
91}
92
93/* --- @tun_init@ --- *
94 *
95 * Arguments: ---
96 *
97 * Returns: ---
98 *
99 * Use: Initializes the tunneling system. Maybe this will require
100 * opening file descriptors or something.
101 */
102
103void tun_init(void)
104{
105 return;
106}
107
108/* --- @tun_create@ --- *
109 *
110 * Arguments: @tunnel *t@ = pointer to tunnel block
111 * @peer *p@ = pointer to peer block
112 *
113 * Returns: Zero if it worked, nonzero on failure.
114 *
115 * Use: Initializes a new tunnel.
116 */
117
118int tun_create(tunnel *t, peer *p)
119{
120 int fd;
a368bfbc 121 int f;
410c8acf 122
123 if ((fd = open("/dev/unet", O_RDWR)) < 0) {
124 a_warn("open `/dev/unet' failed: %s", strerror(errno));
125 return (-1);
126 }
650a6624 127 fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
a368bfbc 128 if ((f = ioctl(fd, UNIOCGIFFLAGS)) < 0 ||
129 ioctl(fd, UNIOCSIFFLAGS, f | IFF_POINTOPOINT)) {
130 a_warn("couldn't set point-to-point flag: %s", strerror(errno));
131 close(fd);
132 return (-1);
133 }
410c8acf 134 t->p = p;
135 sel_initfile(&sel, &t->f, fd, SEL_READ, t_read, t);
136 sel_addfile(&t->f);
137 T( trace(T_TUNNEL, "tunnel: attached interface %s to peer `%s'",
138 tun_ifname(t), p_name(p)); )
139 return (0);
140}
141
142/* --- @tun_ifname@ --- *
143 *
144 * Arguments: @tunnel *t@ = pointer to tunnel block
145 *
146 * Returns: A pointer to the tunnel's interface name.
147 */
148
149const char *tun_ifname(tunnel *t)
150{
151 static char b[UNET_NAMEMAX];
152 struct unet_info uni;
153 if (ioctl(t->f.fd, UNIOCGINFO, &uni)) {
154 a_warn("ioctl(UNIOCGINFO) failed: %s", strerror(errno));
155 return ("<error>");
156 }
157 if (strlen(uni.uni_ifname) + 1 > sizeof(b)) {
158 a_warn("interface name too long!");
159 return ("<error>");
160 }
161 strcpy(b, uni.uni_ifname);
162 return (b);
163}
164
165/* --- @tun_inject@ --- *
166 *
167 * Arguments: @tunnel *t@ = pointer to tunnel block
168 * @buf *b@ = buffer to send
169 *
170 * Returns: ---
171 *
172 * Use: Injects a packet into the local network stack.
173 */
174
175void tun_inject(tunnel *t, buf *b)
176{
177 IF_TRACING(T_TUNNEL, {
178 trace(T_TUNNEL, "tunnel: inject decrypted packet");
179 trace_block(T_PACKET, "tunnel: packet contents", BBASE(b), BLEN(b));
180 })
181 write(t->f.fd, BBASE(b), BLEN(b));
182}
183
184/* --- @tun_destroy@ --- *
185 *
186 * Arguments: @tunnel *t@ = pointer to tunnel block
187 *
188 * Returns: ---
189 *
190 * Use: Destroys a tunnel.
191 */
192
193void tun_destroy(tunnel *t)
194{
195 sel_rmfile(&t->f);
196 close(t->f.fd);
197}
198
199/*----- That's all, folks -------------------------------------------------*/