Permalink
Browse files

Add IPv6 firewall rules

  • Loading branch information...
1 parent 2d1b7b7 commit 3a5111ec9be7ddd49a74441eff5b64e0b3f64022 @msantos committed Apr 1, 2012
Showing with 170 additions and 83 deletions.
  1. +53 −0 include/sut.hrl
  2. +13 −82 src/sut.erl
  3. +103 −0 src/sut_fw.erl
  4. +1 −1 start.sh
View
53 include/sut.hrl
@@ -0,0 +1,53 @@
+%% Copyright (c) 2012, 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.
+-define(IPPROTO_IPV6, 41).
+
+-define(PROPLIST_TO_RECORD(Record),
+ fun(Proplist) ->
+ Fields = record_info(fields, Record),
+ [Tag| Values] = tuple_to_list(#Record{}),
+ Defaults = lists:zip(Fields, Values),
+ L = lists:map(fun ({K,V}) -> proplists:get_value(K, Proplist, V) end, Defaults),
+ list_to_tuple([Tag|L])
+ end).
+
+-record(sut_state, {
+ ifname = <<"sut-ipv6">>,
+ serverv4,
+ clientv4,
+ clientv6,
+ out = fun(_Packet, _State) -> ok end,
+ in = fun(_Packet, _State) -> ok end,
+
+ s,
+ fd,
+ dev
+ }).
View
95 src/sut.erl
@@ -29,6 +29,7 @@
%% ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
%% POSSIBILITY OF SUCH DAMAGE.
-module(sut).
+-include("sut.hrl").
-behaviour(gen_server).
-export([
@@ -40,45 +41,22 @@
terminate/2, code_change/3]).
--define(IPPROTO_IPV6, 41).
-
--define(PROPLIST_TO_RECORD(Record),
- fun(Proplist) ->
- Fields = record_info(fields, Record),
- [Tag| Values] = tuple_to_list(#Record{}),
- Defaults = lists:zip(Fields, Values),
- L = lists:map(fun ({K,V}) -> proplists:get_value(K, Proplist, V) end, Defaults),
- list_to_tuple([Tag|L])
- end).
-
--record(state, {
- ifname = <<"sut-ipv6">>,
- serverv4,
- clientv4,
- clientv6,
-
- s,
- fd,
- dev
- }).
-
-
%%--------------------------------------------------------------------
%%% Exports
%%--------------------------------------------------------------------
destroy(Ref) when is_pid(Ref) ->
gen_server:call(Ref, destroy).
start_link(Opt) when is_list(Opt) ->
- Fun = ?PROPLIST_TO_RECORD(state),
+ Fun = ?PROPLIST_TO_RECORD(sut_state),
State = Fun(Opt),
gen_server:start_link(?MODULE, [State], []).
%%--------------------------------------------------------------------
%%% Callbacks
%%--------------------------------------------------------------------
-init([#state{serverv4 = Server,
+init([#sut_state{serverv4 = Server,
clientv4 = Client4,
clientv6 = Client6,
ifname = Ifname} = State]) ->
@@ -103,7 +81,7 @@ init([#state{serverv4 = Server,
ok = tuncer:up(Dev, Client6),
- {ok, State#state{
+ {ok, State#sut_state{
fd = FD,
s = Socket,
dev = Dev,
@@ -128,24 +106,19 @@ handle_info({udp, Socket, {SA1,SA2,SA3,SA4}, 0,
_Off:13, _TTL:8, ?IPPROTO_IPV6:8, _Sum:16,
SA1:8, SA2:8, SA3:8, SA4:8,
DA1:8, DA2:8, DA3:8, DA4:8,
- Data/binary>>}, #state{
+ Data/binary>>}, #sut_state{
s = Socket,
clientv4 = {DA1,DA2,DA3,DA4},
- serverv4 = {SA1,SA2,SA3,SA4},
- dev = Dev} = State) ->
+ serverv4 = {SA1,SA2,SA3,SA4}
+ } = State) ->
Opt = case (HL-5)*4 of
N when N > 0 -> N;
_ -> 0
end,
<<_:Opt/bits, Payload/bits>> = Data,
- ok = case valid(Payload) of
- true ->
- tuncer:send(Dev, Payload);
- false ->
- ok
- end,
+ spawn(sut_fw, in, [Payload, State]),
{noreply, State};
% Invalid packet
@@ -158,19 +131,18 @@ handle_info({udp, _Socket, Src, 0, Pkt}, State) ->
{noreply, State};
% Data from the tun device
-handle_info({tuntap, Dev, Data}, #state{
- dev = Dev,
- s = Socket,
- serverv4 = Server} = State) ->
- ok = gen_udp:send(Socket, Server, 0, Data),
+handle_info({tuntap, Dev, Data}, #sut_state{
+ dev = Dev
+ } = State) ->
+ spawn(sut_fw, out, [Data, State]),
{noreply, State};
% WTF?
handle_info(Info, State) ->
error_logger:error_report([wtf, Info]),
{noreply, State}.
-terminate(_Reason, #state{fd = FD}) ->
+terminate(_Reason, #sut_state{fd = FD}) ->
procket:close(FD),
ok.
@@ -186,44 +158,3 @@ aton(Address) when is_list(Address) ->
N;
aton(Address) when is_tuple(Address) ->
Address.
-
-
-% loopback
-valid(<<6:4, _Class:8, _Flow:20,
- _Len:16, _Next:8, _Hop:8,
- _SA1:16, _SA2:16, _SA3:16, _SA4:16, _SA5:16, _SA6:16, _SA7:16, _SA8:16,
- 0:16, 0:16, 0:16, 0:16, 0:16, 0:16, 0:16, 1:16,
- _Payload/binary>>) ->
- false;
-% unspecified address
-valid(<<6:4, _Class:8, _Flow:20,
- _Len:16, _Next:8, _Hop:8,
- _SA1:16, _SA2:16, _SA3:16, _SA4:16, _SA5:16, _SA6:16, _SA7:16, _SA8:16,
- 0:16, 0:16, 0:16, 0:16, 0:16, 0:16, 0:16, 0:16,
- _Payload/binary>>) ->
- false;
-% Multicast
-valid(<<6:4, _Class:8, _Flow:20,
- _Len:16, _Next:8, _Hop:8,
- _SA1:16, _SA2:16, _SA3:16, _SA4:16, _SA5:16, _SA6:16, _SA7:16, _SA8:16,
- 16#FF00:16, _:16, _:16, _:16, _:16, _:16, _:16, _:16,
- _Payload/binary>>) ->
- false;
-% IPv6 Addresses with Embedded IPv4 Addresses
-valid(<<6:4, _Class:8, _Flow:20,
- _Len:16, _Next:8, _Hop:8,
- _SA1:16, _SA2:16, _SA3:16, _SA4:16, _SA5:16, _SA6:16, _SA7:16, _SA8:16,
- 0:16, 0:16, 0:16, 0:16, 0:16, 0:16, _:16, _:16,
- _Payload/binary>>) ->
- false;
-valid(<<6:4, _Class:8, _Flow:20,
- _Len:16, _Next:8, _Hop:8,
- _SA1:16, _SA2:16, _SA3:16, _SA4:16, _SA5:16, _SA6:16, _SA7:16, _SA8:16,
- 0:16, 0:16, 0:16, 0:16, 0:16, 16#FFFF:16, _:16, _:16,
- _Payload/binary>>) ->
- false;
-valid(<<6:4, _/binary>>) ->
- true;
-% Invalid protocol
-valid(_Packet) ->
- false.
View
103 src/sut_fw.erl
@@ -0,0 +1,103 @@
+%% Copyright (c) 2012, 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(sut_fw).
+-include("sut.hrl").
+
+-export([
+ out/2,
+ in/2
+ ]).
+
+
+%% XXX send failures are ignored
+
+%% tun device -> socket
+out(Packet, #sut_state{
+ out = Fun,
+ s = Socket,
+ serverv4 = Server
+ } = State) ->
+ ok = Fun(Packet, State),
+ ok = gen_udp:send(Socket, Server, 0, Packet).
+
+%% socket -> tun device
+in(Packet, #sut_state{
+ in = Fun,
+ dev = Dev
+ } = State) ->
+ ok = valid(Packet),
+ ok = Fun(Packet, State),
+ ok = tuncer:send(Dev, Packet).
+
+
+%%
+%% Check for valid IPv6 packet
+%%
+
+% loopback
+valid(<<6:4, _Class:8, _Flow:20,
+ _Len:16, _Next:8, _Hop:8,
+ _SA1:16, _SA2:16, _SA3:16, _SA4:16, _SA5:16, _SA6:16, _SA7:16, _SA8:16,
+ 0:16, 0:16, 0:16, 0:16, 0:16, 0:16, 0:16, 1:16,
+ _Payload/binary>>) ->
+ {invalid, loopback};
+% unspecified address
+valid(<<6:4, _Class:8, _Flow:20,
+ _Len:16, _Next:8, _Hop:8,
+ _SA1:16, _SA2:16, _SA3:16, _SA4:16, _SA5:16, _SA6:16, _SA7:16, _SA8:16,
+ 0:16, 0:16, 0:16, 0:16, 0:16, 0:16, 0:16, 0:16,
+ _Payload/binary>>) ->
+ {invalid, unspecified_address};
+% Multicast
+valid(<<6:4, _Class:8, _Flow:20,
+ _Len:16, _Next:8, _Hop:8,
+ _SA1:16, _SA2:16, _SA3:16, _SA4:16, _SA5:16, _SA6:16, _SA7:16, _SA8:16,
+ 16#FF00:16, _:16, _:16, _:16, _:16, _:16, _:16, _:16,
+ _Payload/binary>>) ->
+ {invalid, multicast};
+% IPv6 Addresses with Embedded IPv4 Addresses
+valid(<<6:4, _Class:8, _Flow:20,
+ _Len:16, _Next:8, _Hop:8,
+ _SA1:16, _SA2:16, _SA3:16, _SA4:16, _SA5:16, _SA6:16, _SA7:16, _SA8:16,
+ 0:16, 0:16, 0:16, 0:16, 0:16, 0:16, _:16, _:16,
+ _Payload/binary>>) ->
+ {invalid, ipv4_compatible_ipv6_address};
+valid(<<6:4, _Class:8, _Flow:20,
+ _Len:16, _Next:8, _Hop:8,
+ _SA1:16, _SA2:16, _SA3:16, _SA4:16, _SA5:16, _SA6:16, _SA7:16, _SA8:16,
+ 0:16, 0:16, 0:16, 0:16, 0:16, 16#FFFF:16, _:16, _:16,
+ _Payload/binary>>) ->
+ {invalid, ipv4_mapped_ipv6_address};
+valid(<<6:4, _:4, _/binary>>) ->
+ ok;
+% Invalid protocol
+valid(_Packet) ->
+ {invalid, invalid_protocol}.
View
2 start.sh
@@ -1,3 +1,3 @@
#!/bin/sh
-erl $@ -pa deps/*/ebin ebin
+erl $@ -boot start_sasl -pa deps/*/ebin ebin

0 comments on commit 3a5111e

Please sign in to comment.