File Coverage

blib/lib/Linux/TunTap.pm
Criterion Covered Total %
statement 84 113 74.3
branch 0 10 0.0
condition 0 2 0.0
subroutine 28 32 87.5
pod 3 3 100.0
total 115 160 71.8


line stmt bran cond sub pod time code
1             # Copyright (C) 2004 Peter Corlett. All Rights Reserved.
2              
3             # This program is free software; you can redistribute it and/or modify it
4             # under the terms of the GNU General Public License as published by the Free
5             # Software Foundation; either version 2 of the License, or (at your option)
6             # any later version.
7              
8             # This program is distributed in the hope that it will be useful, but
9             # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10             # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11             # for more details.
12              
13             # You should have received a copy of the GNU General Public License along
14             # with this program; if not, write to the Free Software Foundation, Inc., 59
15             # Temple Place, Suite 330, Boston, MA 02111-1307 USA
16              
17             package Linux::TunTap;
18             require 5.005;
19 1     1   13154 use fields qw( interface _fh );
  1         2289  
  1         7  
20 1     1   71 use strict;
  1         2  
  1         33  
21 1     1   4 use vars qw( $VERSION );
  1         6  
  1         84  
22             # $Id: TunTap.pm,v 1.1 2004/07/15 11:20:11 abuse Exp $
23             $VERSION = do { my @r=(q$Revision: 1.1 $=~/\d+/g); sprintf "%d."."%03d"x$#r,@r };
24              
25 1     1   6 use Carp;
  1         2  
  1         301  
26 1     1   2595 use IO::File;
  1         14565  
  1         162  
27              
28             # Magic Linux kernel constants:
29              
30             # These came from /usr/include/linux/if_tun.h on a Debian system
31             # Package containing that is linux-kernel-headers 2.5.999-test7-bk-15
32              
33             # Number of devices
34 1     1   10 use constant TUN_MAX_DEV => 255;
  1         3  
  1         89  
35             # TX queue size
36 1     1   6 use constant TUN_TXQ_SIZE => 10;
  1         2  
  1         41  
37             # Max frame size
38 1     1   6 use constant TUN_MAX_FRAME => 4096;
  1         2  
  1         51  
39             # TUN device flags
40 1     1   6 use constant TUN_TUN_DEV => 0x0001;
  1         3  
  1         4189  
41 1     1   21 use constant TUN_TAP_DEV => 0x0002;
  1         4  
  1         119  
42 1     1   5 use constant TUN_TYPE_MASK => 0x000f;
  1         2  
  1         61  
43 1     1   6 use constant TUN_FASYNC => 0x0010;
  1         2  
  1         62  
44 1     1   6 use constant TUN_NOCHECKSUM => 0x0020;
  1         2  
  1         37  
45 1     1   17 use constant TUN_NO_PI => 0x0040;
  1         2  
  1         31  
46 1     1   5 use constant TUN_ONE_QUEUE => 0x0080;
  1         1  
  1         40  
47 1     1   4 use constant TUN_PERSIST => 0x0100;
  1         16  
  1         31  
48             # Ioctl defines
49 1     1   4 use constant TUNSETNOCSUM => 0x400454c8;
  1         2  
  1         32  
50 1     1   5 use constant TUNSETDEBUG => 0x400454c9;
  1         1  
  1         34  
51 1     1   5 use constant TUNSETIFF => 0x400454ca;
  1         11  
  1         35  
52 1     1   4 use constant TUNSETPERSIST => 0x400454cb;
  1         2  
  1         32  
53 1     1   3 use constant TUNSETOWNER => 0x400454cc;
  1         2  
  1         28  
54             # TUNSETIFF ifr flags
55 1     1   3 use constant IFF_TUN => 0x0001;
  1         1  
  1         37  
56 1     1   4 use constant IFF_TAP => 0x0002;
  1         1  
  1         33  
57 1     1   4 use constant IFF_NO_PI => 0x1000;
  1         6  
  1         43  
58 1     1   4 use constant IFF_ONE_QUEUE => 0x2000;
  1         2  
  1         43  
59 1     1   5 use constant TUN_PKT_STRIP => 0x0001;
  1         2  
  1         35  
60              
61             # The kernel headers are a horror of #defines and nested structs and unions,
62             # but this is the edited highlight:
63             # struct ifreq { char ifrn_name[16]; short ifru_flags; };
64 1     1   4 use constant STRUCT_IFREQ => 'Z16 s';
  1         1  
  1         37  
65              
66             # Where the tunnel device appears in Linux 2.4.
67 1     1   4 use constant TUNNEL_DEVICE => '/dev/net/tun';
  1         1  
  1         669  
68              
69             =head1 NAME
70              
71             Linux::TunTap - Userspace network device
72              
73             =head1 SYNOPSIS
74              
75             use Linux::TunTap;
76              
77             my $tap=new Linux::TunTap;
78              
79             while(my $packet=get_raw()) {
80             # do something with the data, e.g. send it down a tunnel
81             }
82              
83             =head1 DESCRIPTION
84              
85             This is an object-oriented Perl module that interfaces with the Linux tuntap
86             driver. tuntap is a virtual network device that sends and receives packets
87             to and from userspace rather than a physical interface.
88              
89             The normal use of the tuntap device is to write tunnels and bridges between
90             networks. This would tend to imply that you have two hosts on separate
91             networks as the endpoints, and some means of passing data between the tunnel
92             endpoints, e.g. by wrapping the unsupported or firewalled data in a protocol
93             that may pass.
94              
95             Configuration of a tunnel and the security implications of doing so are out
96             of the scope of this document.
97              
98             If your problem is more one of wanting to inspect passing packets, rather
99             than receiving packets and sending replies, you may find that
100             L suits your needs better.
101              
102             =head1 ATTRIBUTES
103              
104             =over 2
105              
106             =item interface
107              
108             my $if=$tun->{interface};
109              
110             Retrieves the name of the tuntap interface, e.g. "tun0".
111              
112             =back
113              
114             =head1 METHODS
115              
116             =over 2
117              
118             =item new( I<< [ PARAM => value, ... ] >> )
119              
120             This creates a new tuntap interface and returns a handle to it.
121              
122             Parameters: NAME.
123              
124             my $tap=new Linux::TunTap;
125             my $tap2=new Linux::TunTap(NAME => 'tap%d');
126              
127             If you specify NAME, it will attempt to create a tuntap device with that
128             name. You may put a C<%d> format specifier into the name, to ensure
129             uniqueness.
130              
131             It will throw an exception if the tuntap interface could not be created.
132             Your attention is drawn to L which discusses what is
133             required for successful creation of an interface.
134              
135             =cut
136              
137             sub new {
138 0     0 1   my($class, %args)=@_;
139              
140             # create new object
141 0           my Linux::TunTap $self;
142 0           $self=fields::new($class);
143              
144             # FIXME BUG: Only tries Linux 2.4 style device
145 0 0         my $fh=new IO::File(TUNNEL_DEVICE, 'r+')
146             or croak "Can't open ".TUNNEL_DEVICE.": $!";
147              
148             # FIXME: we've hardwired IFF_TUN - we get packet type (i.e. IPv4, IPv6,
149             # possibly ARP, etc) and payload, but not the Ethernet header
150 0   0       my $ifr=pack(STRUCT_IFREQ, $args{NAME}||'', IFF_TUN);
151 0 0         ioctl $fh, TUNSETIFF, $ifr
152             or croak "Can't ioctl() tunnel: $!";
153 0           $self->{interface}=unpack STRUCT_IFREQ, $ifr;
154 0           $self->{_fh}=$fh;
155              
156 0           return $self;
157             }
158              
159             sub DESTROY {
160 0     0     my Linux::TunTap $self=shift;
161              
162 0 0         $self->{_fh}->close
163             if $self->{_fh};
164             }
165              
166             =item get_raw( I<< [ timeout ] >> )
167              
168             my $packet=$tun->get_raw();
169              
170             This reads a raw packet from the tunnel, with an optional timeout. If the
171             timeout is omitted, this will block until data is available. Otherwise, the
172             timeout value is the maximum time in seconds to wait. If there is a timeout,
173             an empty string is returned.
174              
175             The raw packet is returned if it could be read, otherwise undef will be
176             returned to indicate an I/O error (use $! to find out what that error was.)
177              
178             In this context, raw means the raw output of tuntap, which includes a four
179             byte header prepended to the IP (or whatever) packet. The output of
180             get_raw() is suitable for using as an argument for put_raw() to reinject the
181             packet.
182              
183             =cut
184              
185             sub get_raw {
186 0     0 1   my Linux::TunTap $self=shift;
187 0           my($timeout)=@_;
188              
189 0           my($rin, $win, $ein);
190 0           my($rout, $wout, $eout);
191 0           $rin = $win = $ein = '';
192 0           vec($rin,fileno($self->{_fh}),1) = 1;
193             #vec($win,fileno(STDOUT),1) = 1;
194 0           $ein = $rin | $win;
195              
196 0           my($nfound,$timeleft) =
197             select($rout=$rin, $wout=$win, $eout=$ein, $timeout);
198              
199 0 0         if($nfound==0) {
200 0           return '';
201             }
202 0           my $iobuf;
203 0           my $ret=sysread $self->{_fh}, $iobuf, TUN_MAX_FRAME;
204             # a failed read() returns undef.
205 0 0         return undef unless defined $ret;
206             # EOF will return an empty string (although I'm not quite sure when we'd
207             # see that)
208 0           return $iobuf;
209             }
210              
211             =item put_raw( I<< packet >> )
212              
213             $tun->get_raw($packet)
214             or die "Failed to send to network: $!";
215              
216             This write a raw packet to the tunnel. A false value will be returned if the
217             write failed, if it was undef, $! will say what the error was.
218              
219             =cut
220              
221             # returns undef on error
222             sub put_raw {
223 0     0 1   my Linux::TunTap $self=shift;
224 0           my($iobuf)=@_;
225              
226 0           my $ret=syswrite $self->{_fh}, $iobuf;
227 0           return $ret;
228             }
229              
230             =back
231              
232             =head1 SYSTEM REQUIREMENTS
233              
234             You need a kernel with tuntap, either compiled in, or as a module. The
235             module's name is F. Currently, only Linux 2.4 is supported. Linux 2.2
236             tuntap has a different API and is currently I supported by this module.
237             Linux 2.6 is untested.
238              
239             You also need the tuntap device node, a character special file with the name
240             F with major number 10 and minor number 200. You can create it
241             like this:
242              
243             # mkdir /dev/net
244             # mknod /dev/net/tun c 10 200
245             # chmod 0700 /dev/net/tun
246              
247             Your script needs to have appropriate permissions to access F.
248             If created as described, you will need to run as root.
249              
250             =head1 WARNINGS
251              
252             Because Linux will not generally allow you to run commands such as
253             L as a non-root user, you will usually find that your script
254             will need to run as root unless you make special arrangements.
255              
256             You are playing with raw network packets in the kernel. This means that you
257             have somewhat more low-level access to the network than is normally allowed
258             by mere mortals. It might be possible (although unlikely) to cause a kernel
259             panic through careless use.
260              
261             Creating tunnels to bypass firewalls may be a violation of your terms of
262             service and/or a criminal offence.
263              
264             As you are running as root, taking arbitrary unchecked data from the public
265             Internet, and creating a weak spot in the security infrastructure, now is an
266             excellent time to read up on taint mode.
267              
268             =head1 SEE ALSO
269              
270             The Linux documentation on tuntap in the kernel source:
271             F<.../Documentation/networking/tuntap.txt>.
272              
273             The many RFCs on IP networking: L.
274              
275             Hall, Eric A. I Sebastopol, CA: O'Reilly &
276             Associates Inc., 2000. ISBN 1-56592-572-6.
277              
278             =head1 BUGS
279              
280             Only Linux 2.4 style tuntap devices are supported.
281              
282             No means to inspect Ethernet frames is provided.
283              
284             =head1 COPYRIGHT
285              
286             Copyright (c) 2004 Peter Corlett . All Rights Reserved.
287              
288             This program is free software; you can redistribute it and/or modify it
289             under the terms of the GNU General Public License as published by the Free
290             Software Foundation; either version 2 of the License, or (at your option)
291             any later version.
292              
293             This program is distributed in the hope that it will be useful, but WITHOUT
294             ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
295             FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
296             more details.
297              
298             You should have received a copy of the GNU General Public License along with
299             this program; if not, write to the Free Software Foundation, Inc., 675 Mass
300             Ave, Cambridge, MA 02139, USA.
301              
302             =cut
303              
304             1;