Skip to content

Instantly share code, notes, and snippets.

@msantos
Created June 20, 2010 19:55
Show Gist options
  • Save msantos/446057 to your computer and use it in GitHub Desktop.
Save msantos/446057 to your computer and use it in GitHub Desktop.
%% Copyright (c) 2010, Michael Santos <[email protected]>
%% 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(rst).
-export([
start/2
]).
-include("epcap_net.hrl").
-define(SIOCGIFINDEX, 16#8933).
-define(PF_PACKET, 17).
-record(state, {
s, % socket
i, % ifindex
addr % IP to exclude
}).
start(Device, IP) when length(Device) < 16 ->
{ok, FD} = packet:socket(),
Interface = packet:ifindex(FD, Device),
loop(#state{
s = FD,
i = Interface,
addr = IP
}).
loop(#state{s = S} = State) ->
case procket:recvfrom(S, 65535) of
nodata ->
timer:sleep(10);
{ok, Data} ->
P = epcap_net:decapsulate(Data),
filter(State, P);
Error ->
error_logger:error_report(Error)
end,
loop(State).
filter(#state{addr = IP}, [
#ether{},
#ipv4{
saddr = Saddr,
daddr = Daddr
},
#tcp{},
_Payload
]) when Saddr =:= IP; Daddr =:= IP ->
ok;
filter(#state{
s = Socket,
i = Ifindex
}, [
#ether{
shost = DM,
dhost = SM
},
#ipv4{
saddr = {DA1,DA2,DA3,DA4},
daddr = {SA1,SA2,SA3,SA4}
},
#tcp{
sport = DP,
dport = SP,
seqno = AckNo,
ackno = SeqNo,
syn = S,
ack = A
},
_Payload
]) when S =:= 1; A =:= 1 ->
Id = 0,
TTL = 64,
IPLen = 40,
IPsum = packet:makesum(
<<
% IPv4 header
4:4, 5:4, 0:8, IPLen:16,
Id:16, 0:1, 1:1, 0:1,
0:13, TTL:8, 6:8, 0:16,
SA1:8, SA2:8, SA3:8, SA4:8,
DA1:8, DA2:8, DA3:8, DA4:8
>>
),
TCPoff = 5,
Win = 1024,
PSH = 0,
TCPsum = packet:makesum(
<<
% IP Pseudoheader
SA1:8,SA2:8,SA3:8,SA4:8,
DA1:8,DA2:8,DA3:8,DA4:8,
0:8,
6:8, % Protocol: TCP
(TCPoff * 4):16,
% TCP Header
SP:16, DP:16,
SeqNo:32,
AckNo:32,
TCPoff:4, 0:4, 0:1, 0:1, 0:1, 0:1,
PSH:1, 1:1, 0:1, 0:1, Win:16,
0:16, 0:16
>>
),
packet:send(Socket, Ifindex, <<
% Ethernet header
DM:6/bytes,
SM:6/bytes,
16#08, 16#00,
% IPv4 header
4:4, 5:4, 0:8, IPLen:16,
Id:16, 0:1, 1:1, 0:1,
0:13, TTL:8, 6:8, IPsum:16,
SA1:8, SA2:8, SA3:8, SA4:8,
DA1:8, DA2:8, DA3:8, DA4:8,
% TCP Header
SP:16, DP:16,
SeqNo:32,
AckNo:32,
TCPoff:4, 0:4, 0:1, 0:1, 0:1, 0:1,
PSH:1, 1:1, 0:1, 0:1, Win:16,
TCPsum:16, 0:16
>>);
filter(_,_) ->
ok.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment