chiark / gitweb /
Upgrade licence to GPLv3+.
[tripe] / server / tun-std.c
1 /* -*-c-*-
2  *
3  * Tunnel interface for Linux-tun-shaped arrangements
4  *
5  * (c) 2003 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of Trivial IP Encryption (TrIPE).
11  *
12  * TrIPE is free software: you can redistribute it and/or modify it under
13  * the terms of the GNU General Public License as published by the Free
14  * Software Foundation; either version 3 of the License, or (at your
15  * option) any later version.
16  *
17  * TrIPE is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20  * for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with TrIPE.  If not, see <https://www.gnu.org/licenses/>.
24  */
25
26 /*----- Header files ------------------------------------------------------*/
27
28 #define TUN_INTERNALS
29
30 #include "tripe.h"
31
32 /*----- Main code ---------------------------------------------------------*/
33
34 #if defined(TUN_LINUX) || defined(TUN_BSD) || defined(TUN_UNET)
35
36 struct tunnel {
37   const tunnel_ops *ops;                /* Pointer to operations */
38   sel_file f;                           /* Selector for TUN/TAP device */
39   struct peer *p;                       /* Pointer to my peer */
40 };
41
42 /* --- @t_read@ --- *
43  *
44  * Arguments:   @int fd@ = file descriptor to read
45  *              @unsigned mode@ = what's happened
46  *              @void *v@ = pointer to tunnel block
47  *
48  * Returns:     ---
49  *
50  * Use:         Reads data from the tunnel.
51  */
52
53 static void t_read(int fd, unsigned mode, void *v)
54 {
55   tunnel *t = v;
56   ssize_t n;
57   buf b;
58
59   n = read(fd, buf_i, sizeof(buf_i));
60   if (n < 0) {
61     a_warn("TUN", "%s", p_ifname(t->p), "%s", t->ops->name,
62            "read-error", "?ERRNO", A_END);
63     return;
64   }
65   IF_TRACING(T_TUNNEL, {
66     trace(T_TUNNEL, "tun-%s: packet arrived", t->ops->name);
67     trace_block(T_PACKET, "tunnel: packet contents", buf_i, n);
68   })
69   buf_init(&b, buf_i, n);
70   p_tun(t->p, &b);
71 }
72
73 /* --- @t_init@ --- *
74  *
75  * Arguments:   ---
76  *
77  * Returns:     ---
78  *
79  * Use:         Initializes the tunneling system.  Maybe this will require
80  *              opening file descriptors or something.
81  */
82
83 static void t_init(void) { return; }
84
85 /* --- @t_create@ --- *
86  *
87  * Arguments:   @peer *p@ = pointer to peer block
88  *              @int fd@ = file descriptor of tunnel device
89  *              @char **ifn@ = where to put the interface name
90  *
91  * Returns:     A tunnel block if it worked, or null on failure.
92  *
93  * Use:         Initializes a new tunnel.
94  */
95
96 static tunnel *t_create(peer *p, int fd, char **ifn, const tunnel_ops *ops)
97 {
98   tunnel *t;
99
100   fdflags(fd, O_NONBLOCK, O_NONBLOCK, FD_CLOEXEC, FD_CLOEXEC);
101   t = CREATE(tunnel);
102   t->ops = ops;
103   t->p = p;
104   sel_initfile(&sel, &t->f, fd, SEL_READ, t_read, t);
105   sel_addfile(&t->f);
106   return (t);
107 }
108
109 /* --- @t_inject@ --- *
110  *
111  * Arguments:   @tunnel *t@ = pointer to tunnel block
112  *              @buf *b@ = buffer to send
113  *
114  * Returns:     ---
115  *
116  * Use:         Injects a packet into the local network stack.
117  */
118
119 static void t_inject(tunnel *t, buf *b)
120 {
121   IF_TRACING(T_TUNNEL, {
122     trace(T_TUNNEL, "tun-%s: inject decrypted packet", t->ops->name);
123     trace_block(T_PACKET, "tunnel: packet contents", BBASE(b), BLEN(b));
124   })
125   DISCARD(write(t->f.fd, BBASE(b), BLEN(b)));
126 }
127
128 /* --- @t_destroy@ --- *
129  *
130  * Arguments:   @tunnel *t@ = pointer to tunnel block
131  *
132  * Returns:     ---
133  *
134  * Use:         Destroys a tunnel.
135  */
136
137 static void t_destroy(tunnel *t)
138   { sel_rmfile(&t->f); close(t->f.fd); DESTROY(t); }
139
140 #define DEFOPS(name)                                                    \
141                                                                         \
142 static tunnel *t_create_##name(peer *p, int fd, char **ifn);            \
143                                                                         \
144 const tunnel_ops tun_##name = {                                         \
145   #name, TUNF_PRIVOPEN,                                                 \
146   t_init, t_create_##name, 0, t_inject, t_destroy                       \
147 };                                                                      \
148                                                                         \
149 static tunnel *t_create_##name(peer *p, int fd, char **ifn)             \
150   { return t_create(p, fd, ifn, &tun_##name); }
151
152 #ifdef TUN_LINUX
153   DEFOPS(linux)
154 #endif
155
156 #ifdef TUN_BSD
157   DEFOPS(bsd)
158 #endif
159
160 #ifdef TUN_UNET
161   DEFOPS(unet)
162 #endif
163
164 #endif
165
166 /*----- That's all, folks -------------------------------------------------*/