1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
|
.\" $OpenBSD: tun.4,v 1.7 1998/11/04 16:45:57 mickey Exp $
.Dd March 10, 1996
.Dt TUN 4
.Os OpenBSD 1.2
.Sh NAME
.Nm tun
.Nd Tunnel Network Interface
.Sh SYNOPSIS
.Cd "pseudo-device tun 4"
.Sh DESCRIPTION
The
.Nm tun
interface is a software loopback mechanism that can be loosely
described as the network interface analog of the
.Xr pty 4 ,
that is,
.Nm tun
does for network interfaces what the
.Nm pty
driver does for terminals.
.Pp
The
.Nm tun
driver, like the
.Nm pty
driver, provides two interfaces: an interface like the usual facility
it is simulating (a network interface in the case of
.Nm tun ,
or a terminal for
.Nm pty ) ,
and a character-special device
.Dq control
interface.
.Pp
The network interfaces are named
.Sy tun Ns Ar 0 ,
.Sy tun Ns Ar 1 ,
etc, as many in all as the
.Ar count
figure given on the
.Sy pseudo-device
line. Each one supports the usual network-interface
.Xr ioctl 2 Ns s ,
such as
.Dv SIOCSIFADDR
and
.Dv SIOCSIFNETMASK ,
and thus can be used with
.Xr ifconfig 8
like any other interface. At boot time, they are
.Dv POINTOPOINT
interfaces, but this can be changed; see the description of the control
device, below. When the system chooses to transmit a packet on the
network interface, the packet can be read from the control device (it
appears as
.Dq input
there); writing a packet to the control device generates an input
packet on the network interface, as if the (nonexistent) hardware had
just received it.
.Pp
There are two control interfaces. The
.Em data
interface, normally
.Pa /dev/tun Ns Sy N ,
is exclusive-open (it cannot be opened if it is already open), is
normally restricted to the super-user, and can
.Dq transmit
and
.Dq receive
packets. The
.Em control
interface, normally
.Pa /dev/tunc Ns Sy N ,
cannot send and receive packets, but can be opened by many processes at
once; it is intended for status queries and changes (many of which can
also be implemented with
.Fn ioctl
calls on the data interface). There are a number of status bits that
can be set or cleared via the control interfaces; they are mentioned
below where applicable, and they are all summarized in the discussions
of the control interfaces.
.\" Why isn't .Ss documented in mdoc(7) and mdoc.samples(7)?
.Ss The data interface
The data interface supports
.Xr read 2 ,
.Xr write 2 ,
and
.Xr ioctl 2
calls to, respectively, collect
.Dq output
packets, generate
.Dq input
packets, and perform control functions. As mentioned above, this
interface is exclusive-open; if the
.Dv SUONLY
bit is set (which it is by default), it cannot be opened at all except
by the super-user. By default, a
.Fn read
call will return an error
.Pf ( Er EHOSTDOWN )
if the interface is not
.Dq ready
(which means that the control device is open and the interface's
address has been set); if preferred, the
.Dv RRWAIT
bit can be set, in which case a
.Fn read
call will block (even if non-blocking I/O has been enabled) until the
interface is ready. Once the interface is ready,
.Fn read
will return a packet if one is available; if not, it will either block
until one is or return
.Er EWOULDBLOCK ,
depending on whether non-blocking I/O has been enabled. If the packet
is longer than is allowed for in the buffer passed to
.Fn read ,
the extra data will be silently dropped.
.Pp
The first u_int32_t of data will always be the address family (eg,
.Dv AF_INET )
of the packet in host byte order. By default, the packet data follows
immediately, but if
the
.Dv PREPADDR
bit is set, the address to which the packet is to be sent is placed
after the address family u_int32_t and before the packet data. The size and
layout of the address depends on the address family; for
.Dv AF_INET ,
for example, it is a
.Va struct in_addr .
A
.Xr write 2
call passes a packet in to be
.Dq received
on the pseudo-interface. Each
.Fn write
call supplies exactly one packet; the packet length is taken from the
amount of data provided to
.Fn write .
The first u_int32_t must be the address family of the packet in host byte order,
much as in packets returned by
.Fn read ;
the packet data always follows immediately.
A large number of
.Xr ioctl 2
calls are also supported. They are defined in
.Aq Pa net/if_tun.h Ns .
.Bl -tag -width TUN_PREPADDR
.It Dv TUNSDEBUG
The argument should be a pointer to an
.Va int ;
this sets the internal debugging variable to that value. What, if
anything, this variable controls is not documented here; see the source
code.
.It Dv TUNGDEBUG
The argument should be a pointer to an
.Va int ;
this stores the internal debugging variable's value into it.
.It Dv TUNSMODE
The argument should be a pointer to an
.Va int ;
its value must be
.Dv IFF_POINTOPOINT
or
.Dv IFF_BROADCAST .
The type of the corresponding
.Em tun Ns Sy n
interface is set to the supplied type. If the value is anything else,
an
.Er EINVAL
error occurs. The interface must be down at the time; if it is up, an
.Er EBUSY
error occurs.
.\" X .It Dv TUNSFLAG
.\" X The interface's flag bits are set as specified in the
.\" X .Va int
.\" X argument. Only some of the bits can be modified; the rest are
.\" X read-only. The bits are defined in
.\" X .Aq Pa net/if_tun.h
.\" X with a
.\" X .Dv TUN_
.\" X prefix; for example, the bit called
.\" X .Dv RRWAIT
.\" X in this document would be referred to in source code as
.\" X .Dv TUN_RRWAIT .
.\" X The bits are:
.\" X .\" Why isn't the way to create a table like this documented in mdoc(7)
.\" X .\" or mdoc.samples(7)?!
.\" X .Bl -column "TUN_PREPADDR" "RO/RW" -compact -indent-two
.\" X .It Name Ta RO/RW Ta Meaning
.\" X .It Dv TUN_OPEN Ta RO Ta "Data control device is open."
.\" X .It Dv TUN_INITED Ta RO Ta "Initialized."
.\" X .It Dv TUN_RCOLL Ta RO Ta "Select-for-read collision."
.\" X .It Dv TUN_IASET Ta RO Ta "Address has been set."
.\" X .It Dv TUN_DSTADDR Ta RO Ta "Destination address has been set."
.\" X .It Dv TUN_RWAIT Ta RO Ta "A process is blocked in Fn read Ns ."
.\" X .It Dv TUN_ASYNC Ta RO Ta "Generate Dv SIGIO No for readers."
.\" X .It Dv TUN_NBIO Ta RO Ta "Non-blocking I/O for reads."
.\" X .It Dv TUN_BRDADDR Ta RO Ta "Broadcast address has been set."
.\" X .It Dv TUN_PREPADDR Ta RW Ta "Prepend sent-to address for reads."
.\" X .It Dv TUN_STAYUP Ta RW Ta "Don't take interface down on close."
.\" X .It Dv TUN_SUONLY Ta RW Ta "Data control device is super-user only."
.\" X .It Dv TUN_RRWAIT Ta RW Ta "Wait for ready when reading."
.\" X .El
.\" X .It Dv TUNGFLAG
.\" X The interface's flag bits are fetched into the argument
.\" X .Va int .
.\" X The flags and their meanings are as for
.\" X .Dv TUNSFLAG .
.\" X .It Dv FIONBIO
.\" X Turn non-blocking I/O for reads off or on, according as the argument
.\" X .Va int Ns 's
.\" X value is or isn't zero. (Writes are always nonblocking.)
.\" X .It Dv FIOASYNC
.\" X Turn asynchronous I/O for reads (ie, generation of
.\" X .Dv SIGIO
.\" X when data is available to be read) off or on, according as the argument
.\" X .Va int Ns 's
.\" X value is or isn't zero.
.\" X .It Dv FIONREAD
.\" X If any packets are queued to be read, store the size of the first one
.\" X into the argument
.\" X .Va int ;
.\" X otherwise, store zero.
.\" X .It Dv TIOCSPGRP
.\" X Set the process group to receive
.\" X .Dv SIGIO
.\" X signals, when asynchronous I/O is enabled, to the argument
.\" X .Va int
.\" X value.
.\" X .It Dv TIOCGPGRP
.\" X Retrieve the process group value for
.\" X .Dv SIGIO
.\" X signals into the argument
.\" X .Va int
.\" X value.
.El
The data control device also supports
.Xr select 2
for read; selecting for write is pointless, and always succeeds, since
writes are always nonblocking (if the packet cannot be accepted for a
transient reason (eg, no buffer space available), it is silently
dropped; if the reason is not transient (eg, packet too large), an
error is returned).
.Pp
On the last close of the data device, by default, the interface is
brought down (as if with
.Dq ifconfig tun Ns Sy n down ) ;
if the
.Dv STAYUP
bit is set, this is not done. In either case, all queued packets are
thrown away. (If the interface is up when the data device is not open,
either because of
.Dv STAYUP
or because it was explicitly brought up, output packets are always
thrown away rather than letting them pile up.)
.Ss The control interface
The alternative control interface is a text-based interface designed
for shell-script or human use; it allows control of many of the things
that can be done with
.Fn ioctl
calls on the data interface, and a few more as well.
.Pp
.Fn read Ns s
on the control interface always return a single line of text (or just
the beginning of the line, if the buffer passed to
.Xr read 2
was too small to take the whole line). The line contains items in the
general format
.Do
.Li item=value
.Dc ,
where
.Li item
is a keyword and
.Li value
is a value appropriate to the keyword. This line is intended for human
use; programs should use the
.Fn ioctl
interface. Here is an actual example (broken because of width
restrictions):
.Bd -literal
unit=0 flags=(open,inited,!rcoll,iaset,!dstaddr,!rwait,!async,
!nbio,!brdaddr,prepaddr,stayup,suonly,rrwait) type=broadcast
mtu=1500 coll=0 ipkts=0/0 opkts=0/0 pgrp=0
.Ed
.Pp
Note that the current file offset is ignored for reads, so using a tool like
.Xr cat 1
will result in infinite output. Use something more like
.Dq head\ \&-1
for command-line use. It is possible to
.Xr select 2
for reading on this device, which will indicate that the device is
readable whenever the state is changed.
.Pp
Writes to the control interface are interpreted as modifications to the
state. Each
.Fn write
call is treated separately. The data written is broken at whitespace
(blanks, tabs, newlines); each resulting fragment has its first
character examined. If this character is a
.Ql \&+
or
.Ql \&\- ,
the rest of the fragment is taken as a flag name, and the flag is
turned on (for
.Ql \&+ )
or off (for
.Ql \&\- ) .
(Flag names are as generated on reads; they are the same as the
.Dv TUN_ Ns Em xxx
constants, with the leading
.Dv TUN_
removed and the rest lowercased.) If the first character is
.Ql t ,
the second character must be
.Ql b
or
.Ql p ,
and the interface type is set to
.Dv IFF_BROADCAST
or
.Dv IFF_POINTOPOINT ,
respectively. If the first character is
.Ql g
or
.Ql m ,
the rest of the fragment is taken as a number in decimal (possibly with
a leading \&\- sign) and the result is taken as a new process group,
for
.Ql g
or MTU, for
.Ql m .
(The MTU must not be less than 1; attempts to set it so return
.Er EIO . )
.Sh SEE ALSO
.Xr netintro 4 ,
.Xr inet 4
.Sh BUGS
The
.Dv SUONLY
bit is a botch, especially since the control interface, which is never
restricted by the kernel, can change it. Access control really should
be handled by the permission bits on the
.Pa /dev
entries for the data and control devices; this bit is a historical
artifact.
.Pp
The process-group values for
.Dv SIGIO
signals should be checked; as it stands, the driver can be used (by
anyone who can open the control or data device) to send any desired
signal to an arbitrary process or process group. (Until this is fixed,
you should be careful to set the permisison bits to allow only root to
open the control device, and either do the same for the data device or
leave the
.Dv SUONLY
bit set.)
.Sh NOTES
Very old versions of the tunnel device did not include the address
family at the start of the packet. More recent versions passed the
address family as a single byte, but this caused problems with bpf,
hence the currect version passes a u_int32_t of address family.
|