Skip to content
Browse files

tunctl: add support for FreeBSD

Add support for the tun/tap interface on FreeBSD, using the legacy
interface.
  • Loading branch information...
1 parent d6af185 commit a2150ac672f9838757fd9904def08331ba92af57 @msantos committed
Showing with 134 additions and 4 deletions.
  1. +30 −4 README.md
  2. +1 −0 src/tunctl.erl
  3. +103 −0 src/tunctl_freebsd.erl
View
34 README.md
@@ -8,7 +8,7 @@ tunctl is an Erlang API for creating and using TUN/TAP interfaces.
beam needs to have privileges to configure interfaces.
-To add cap_net_admin capabilities:
+To add cap\_net\_admin capabilities:
sudo setcap cap_net_admin=ep /path/to/bin/beam # or beam.smp
@@ -31,6 +31,32 @@ Allow the user running tunctl to call ifconfig using sudo:
sudo visudo
youruser ALL=NOPASSWD: /sbin/ifconfig tap0 *
+### FreeBSD
+
+tunctl uses the FreeBSD tuntap legacy interface.
+
+1. Ensure the tap device kernel module is loaded:
+
+ $ kldstat
+ $ kldload if_tap
+
+ If you want the tap driver loaded on boot, add to /boot/loader.conf:
+
+ if_tap_load="YES"
+
+2. Check cloning is enabled:
+
+ $ sysctl net.link.tun.devfs_cloning
+ net.link.tun.devfs_cloning: 1
+
+ $ sysctl net.link.tap.devfs_cloning
+ net.link.tap.devfs_cloning: 1
+
+3. Allow the user running tunctl to call ifconfig using sudo:
+
+ sudo visudo
+ youruser ALL=NOPASSWD: /sbin/ifconfig tap0 *
+
## EXPORTS
@@ -160,7 +186,7 @@ the fd is closed if the device is not persistent).
up(Device, IPv4Address) -> ok
Types Device = binary()
- IPv$Address = tuple()
+ IPv4Address = tuple()
down(Device) -> ok
@@ -188,7 +214,7 @@ the fd is closed if the device is not persistent).
## TODO
* on Linux, the TUNSETIFF ioctl request to create the interface requires
- CAP_NET_ADMIN privileges. Look at moving the interface creation into
+ CAP\_NET\_ADMIN privileges. Look at moving the interface creation into
the procket setuid binary for OSes that use the multiplexing dev.
* compat for other BSDs: /dev/tun multiplex dev, probably the same issue
@@ -196,7 +222,7 @@ the fd is closed if the device is not persistent).
* make sure tuncer can never leak file descriptors
-* add {active,true} mode using open_port/2
+* add {active,true} mode using open\_port/2
* add support for tun filtering
View
1 src/tunctl.erl
@@ -110,5 +110,6 @@ os() ->
case os:type() of
{unix, linux} -> tunctl_linux;
{unix, darwin} -> tunctl_darwin;
+ {unix, freebsd} -> tunctl_freebsd;
{unix, _} -> throw({error, unsupported})
end.
View
103 src/tunctl_freebsd.erl
@@ -0,0 +1,103 @@
+%% Copyright (c) 2011, Michael Santos <michael.santos@gmail.com>
+%% All rights reserved.
+%%
+%% Redistribution and use in source and binary forms, with or without
+%% modification, are permitted provided that the following conditions
+%% are met:
+%%
+%% Redistributions of source code must retain the above copyright
+%% notice, this list of conditions and the following disclaimer.
+%%
+%% Redistributions in binary form must reproduce the above copyright
+%% notice, this list of conditions and the following disclaimer in the
+%% documentation and/or other materials provided with the distribution.
+%%
+%% Neither the name of the author nor the names of its contributors
+%% may be used to endorse or promote products derived from this software
+%% without specific prior written permission.
+%%
+%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+%% "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+%% LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+%% FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+%% COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+%% INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+%% BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+%% LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+%% CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+%% LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+%% ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+%% POSSIBILITY OF SUCH DAMAGE.
+-module(tunctl_freebsd).
+
+%% Uses the legacy tun/tap interface (rather than interface cloning)
+%% net.link.(tun|tap).devfs_cloning must be non-zero to use.
+
+-include("tuntap.hrl").
+-include("ioctl.hrl").
+-include("procket.hrl").
+
+-export([
+ create/2,
+ persist/2,
+ owner/2, group/2,
+ up/2, down/1
+ ]).
+
+
+-define(SIZEOF_STRUCT_IFALIASREQ, 64).
+-define(SIOCAIFADDR, ?IOW($i, 26, ?SIZEOF_STRUCT_IFALIASREQ)).
+
+-define(TAPGIFNAME, ?IOR('t', 93, ?SIZEOF_STRUCT_IFREQ)).
+
+-define(TUNDEV, "tap").
+
+
+%%--------------------------------------------------------------------
+%%% Exports
+%%--------------------------------------------------------------------
+create(<<>>, Opt) ->
+ create(<<"tap0">>, Opt);
+
+%% Ignore the options for now
+create(Ifname, _Opt) when byte_size(Ifname) < ?IFNAMSIZ ->
+ case procket:dev(binary_to_list(Ifname)) of
+ {ok, FD} ->
+ {ok, FD, Ifname};
+ Error ->
+ Error
+ end.
+
+
+%% N/A
+persist(_FD, _Status) ->
+ ok.
+
+owner(_FD, _Owner) ->
+ ok.
+
+group(__FD, _Group) ->
+ ok.
+
+
+%% Calling SIOCAIFADDR requires beam runs with root
+%% privs. For now, shell out to ifconfig.
+up(Dev, {A,B,C,D}) ->
+ Cmd = "sudo ifconfig " ++ binary_to_list(Dev) ++ " " ++
+ inet_parse:ntoa({A,B,C,D}) ++ " up",
+ case os:cmd(Cmd) of
+ [] -> ok;
+ Error -> Error
+ end.
+
+down(Dev) when byte_size(Dev) < ?IFNAMSIZ ->
+ Cmd = "sudo ifconfig " ++ binary_to_list(Dev) ++ " down",
+ case os:cmd(Cmd) of
+ [] -> ok;
+ Error -> Error
+ end.
+
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------

0 comments on commit a2150ac

Please sign in to comment.
Something went wrong with that request. Please try again.