Skip to content

Commit

Permalink
Add RFC2890 for GRE packets
Browse files Browse the repository at this point in the history
Decoding previously did not honor RFC2890 (Key and Sequence Number Extensions to GRE), it now does.

Also, the completely wrong GRE packet binary has been fixed in pkt_gre_tests.
  • Loading branch information
ned-jm committed May 17, 2018
1 parent 892ecdd commit b2da5bf
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 21 deletions.
6 changes: 4 additions & 2 deletions include/pkt_gre.hrl
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
%% RFC 2784 - Generic Routing Encapsulation (GRE)
-record(gre, {
c = 0 :: pkt:bit(), res0 = 0 :: 0..2#111111111111, ver = 0 :: 0..2#111,
c = 0 :: pkt:bit(), r = 0 :: pkt:bit(), k = 0 :: pkt:bit(), s = 0 :: pkt:bit(),
res0 = 0 :: 0..2#111111111, ver = 0 :: 0..2#111,
type = ?ETH_P_IP :: pkt:uint16_t(),
chksum = 0 :: pkt:uint16_t(), res1 = 0 :: pkt:uint16_t()
chksum = 0 :: pkt:uint16_t(), res1 = 0 :: pkt:uint16_t(),
key = 0 :: pkt:uint16_t(), sequence = 0 :: pkt:uint16_t()
}).
36 changes: 23 additions & 13 deletions src/pkt_gre.erl
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,27 @@

-export([codec/1]).

codec(<<0:1,Res0:12,Ver:3,Type:16,Rest/binary>>) ->
{#gre{c = 0, res0 = Res0, ver = Ver, type = Type
},Rest
codec(<<C:1,R:1,K:1,S:1,Res0:9,Ver:3,Type:16,Bin/binary>>) ->
{[Chksum, Res1, Key, Sequence], Payload} = unpack([C, K, S], Bin),
{#gre{c = C, r = R, k = K, s = S, res0 = Res0, ver = Ver, type = Type, chksum = Chksum,
res1 = Res1, key = Key, sequence = Sequence
},Payload
};
codec(<<1:1,Res0:12,Ver:3,Type:16,Chksum:16,Res1:16,Rest/binary>>) ->
{#gre{c = 1, res0 = Res0, ver = Ver, type = Type,
chksum = Chksum, res1 = Res1
},Rest
};
codec(#gre{c = 0, res0 = Res0, ver = Ver, type = Type}) ->
<<0:1,Res0:12,Ver:3,Type:16>>;
codec(#gre{c = 1, res0 = Res0, ver = Ver, type = Type,
chksum = Chksum, res1 = Res1}) ->
<<1:1,Res0:12,Ver:3,Type:16,Chksum:16,Res1:16>>.

codec(#gre{c = C, r = R, k = K, s = S, res0 = Res0, ver = Ver, type = Type, chksum = Chksum,
res1 = Res1, key = Key, sequence = Sequence
}) ->
ChecksumLength = C*16,
Res1Length = ChecksumLength,
KeyLength = K*32,
SequenceLength = S*32,
<<C:1,R:1,K:1,S:1,Res0:9,Ver:3,Type:16,Chksum:ChecksumLength,Res1:Res1Length,Key:KeyLength,Sequence:SequenceLength>>.

unpack([0, 0, 0], Bin) -> {[0, 0, 0, 0], Bin};
unpack([C, K, S], Bin) ->
ChecksumLength = C*16,
Res1Length = ChecksumLength,
KeyLength = K*32,
SequenceLength = S*32,
<<Chksum:ChecksumLength,Res1:Res1Length,Key:KeyLength,Sequence:SequenceLength,Payload/binary>> = Bin,
{[Chksum, Res1, Key, Sequence], Payload}.
10 changes: 4 additions & 6 deletions test/pkt_gre_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,14 @@ codec_test_() ->
].

packet() ->
% https://pcapr.net/view/mu/2009/8/3/21/gre-keepalive.pcap.html
<<255,0,8,0,119,128,0,0,69,0,0,35,148,47,0,0,64,1,238,215,
127,0,0,1,127,0,0,1,8,0,165,38,217,147,0,1>>.
<<48,0,8,0,0,0,48,57,0,0,0,1,
69,0,0,20,0,0,0,0,64,6,0,0,127,0,0,1,127,0,0,1>>.

decode() ->
{Header, Payload} = pkt:gre(packet()),
?_assertEqual(
{{gre,1,4064,0,2048,30592,0},
<<69,0,0,35,148,47,0,0,64,1,238,215,127,0,0,1,127,0,0,1,
8,0,165,38,217,147,0,1>>},
{{gre,0,0,1,1,0,0,2048,0,0,12345,1},
<<69,0,0,20,0,0,0,0,64,6,0,0,127,0,0,1,127,0,0,1>>},
{Header, Payload}
).

Expand Down

0 comments on commit b2da5bf

Please sign in to comment.