Permalink
Browse files

tunctl: support IPv6 addresses on tun/tap devices

Add support for IPv6 addresses by shelling out to sudo ifconfig.
  • Loading branch information...
1 parent 6375824 commit 34c23c20a7d06652ce29ea7a697c83ed25299f8f @msantos committed Jun 22, 2011
Showing with 61 additions and 54 deletions.
  1. +11 −8 README.md
  2. +43 −3 src/tunctl.erl
  3. +1 −20 src/tunctl_darwin.erl
  4. +1 −20 src/tunctl_freebsd.erl
  5. +5 −3 src/tunctl_linux.erl
View
@@ -213,16 +213,19 @@ 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
- the procket setuid binary for OSes that use the multiplexing dev.
+* Linux:
+ * the TUNSETIFF ioctl request to create the interface requires
+ CAP\_NET\_ADMIN privileges. Look at moving the interface creation
+ into the procket setuid binary for OSes that use the multiplexing
+ dev.
-* make sure tuncer can never leak file descriptors
+ * support setting IPv6 address using ioctl
-* add {active,true} mode using open\_port/2
+ * support setting netmask using ioctl
-* add support for tun filtering
+ * add support for tun filtering
-* support for setting pointopoint
+* make sure tuncer can never leak file descriptors
-* IPv6 addresses on tun devices
+
+* support for setting pointopoint
View
@@ -81,13 +81,26 @@ group(FD, Group) when is_integer(FD), is_integer(Group) ->
%% Configure the interface just like ifconfig except
%% with fewer features and no error checking
%%
-up(Dev, {A,B,C,D}) when byte_size(Dev) < ?IFNAMSIZ ->
+up(Dev, {A,B,C,D}) ->
+ up(Dev, {A,B,C,D}, 24);
+up(Dev, {A,B,C,D,E,F,G,H}) ->
+ up(Dev, {A,B,C,D,E,F,G,H}, 64).
+
+up(Dev, {A,B,C,D}, Mask) when byte_size(Dev) < ?IFNAMSIZ, is_integer(Mask) ->
Module = os(),
- Module:up(Dev, {A,B,C,D}).
+ case Module of
+ tunctl_linux -> tunctl_linux:up(Dev, {A,B,C,D}, Mask);
+ _ -> os_up(Dev, {A,B,C,D}, Mask)
+ end;
+up(Dev, {A,B,C,D,E,F,G,H}, Mask) when byte_size(Dev) < ?IFNAMSIZ, is_integer(Mask) ->
+ os_up(Dev, {A,B,C,D,E,F,G,H}, Mask).
down(Dev) when byte_size(Dev) < ?IFNAMSIZ ->
Module = os(),
- Module:down(Dev).
+ case Module of
+ tunctl_linux -> tunctl_linux:down(Dev);
+ _ -> os_down(Dev)
+ end.
header(<<Flags:?UINT16, Proto:?UINT16, Buf/binary>>) ->
@@ -113,3 +126,30 @@ os() ->
{unix, freebsd} -> tunctl_freebsd;
{unix, _} -> throw({error, unsupported})
end.
+
+
+%% Shell out to ifconfig on systems where ioctl requires
+%% root privs (or native code hasn't been written yet).
+os_up(Dev, {A,B,C,D}, Mask) ->
+ Cmd = "sudo ifconfig " ++ binary_to_list(Dev) ++ " " ++
+ inet_parse:ntoa({A,B,C,D}) ++
+ "/" ++ list_to_integer(Mask) ++ " up",
+ case os:cmd(Cmd) of
+ [] -> ok;
+ Error -> {error, Error}
+ end;
+os_up(Dev, {A,B,C,D,E,F,G,H}, Mask) ->
+ Cmd = "sudo ifconfig " ++ binary_to_list(Dev) ++ " inet6 add" ++
+ inet_parse:ntoa({A,B,C,D,E,F,G,H}) ++
+ "/" ++ list_to_integer(Mask) ++ " up",
+ case os:cmd(Cmd) of
+ [] -> ok;
+ Error -> {error, Error}
+ end.
+
+os_down(Dev) ->
+ Cmd = "sudo ifconfig " ++ binary_to_list(Dev) ++ " down",
+ case os:cmd(Cmd) of
+ [] -> ok;
+ Error -> {error, Error}
+ end.
View
@@ -37,8 +37,7 @@
-export([
create/2,
persist/2,
- owner/2, group/2,
- up/2, down/1
+ owner/2, group/2
]).
-define(TUNSIFHEAD, ?IOW($t, 96, ?SIZEOF_INT)).
@@ -84,24 +83,6 @@ 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
%%--------------------------------------------------------------------
@@ -40,8 +40,7 @@
-export([
create/2,
persist/2,
- owner/2, group/2,
- up/2, down/1
+ owner/2, group/2
]).
@@ -80,24 +79,6 @@ 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
%%--------------------------------------------------------------------
@@ -38,7 +38,7 @@
create/2,
persist/2,
owner/2, group/2,
- up/2, down/1
+ up/3, down/1
]).
@@ -94,9 +94,11 @@ group(FD, Group) when is_integer(FD), is_integer(Group) ->
%%
%% Configure the interface just like ifconfig except
-%% with fewer features and no error checking
+%% with fewer features and no error checking.
%%
-up(Dev, {A,B,C,D}) when byte_size(Dev) < ?IFNAMSIZ ->
+%% Also, we ignore the mask.
+%%
+up(Dev, {A,B,C,D}, _Mask) when byte_size(Dev) < ?IFNAMSIZ ->
{ok, Socket} = procket:socket(inet, dgram, 0),
% struct sockaddr_in

0 comments on commit 34c23c2

Please sign in to comment.