Skip to content

Commit

Permalink
Merge pull request #21 from maxlapshin/master
Browse files Browse the repository at this point in the history
IGMPv3 type 0x22 support
  • Loading branch information
msantos committed Apr 23, 2014
2 parents cffe0a0 + 2df7419 commit 2c71e02
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
8 changes: 8 additions & 0 deletions include/pkt_igmp.hrl
Expand Up @@ -4,3 +4,11 @@
csum = 0,
group
}).


-record(igmp_group, {
type = 0,
addr,
sources = [],
aux = <<>>
}).
33 changes: 33 additions & 0 deletions src/pkt_igmp.erl
Expand Up @@ -34,15 +34,48 @@

-export([codec/1]).


% IGMPv3 message, http://tools.ietf.org/html/rfc3376#page-12
codec(<<Type:8, _:8, Checksum:16, _:16, GroupCount:16, Bin/binary>>) when Type == 16#22 ->
{Groups, Payload} = unpack_groups(GroupCount, Bin),
{#igmp{
type = Type, csum = Checksum,
group = Groups
}, Payload};

% IGMPv2 messages
codec(<<Type:8, Code:8, Checksum:16,
DA1:8, DA2:8, DA3:8, DA4:8, Payload/binary>>) ->
{#igmp{
type = Type, code = Code, csum = Checksum,
group = {DA1,DA2,DA3,DA4}
}, Payload};

codec(#igmp{
type = Type, csum = Checksum,
group = Groups
}) when Type == 16#22 andalso is_list(Groups) ->
GroupBin = [pack_group(Group) || Group <- Groups],
iolist_to_binary([<<Type:8, 0:8, Checksum:16, 0:16, (length(Groups)):16>>, GroupBin]);

codec(#igmp{
type = Type, code = Code, csum = Checksum,
group = {DA1,DA2,DA3,DA4}
}) ->
<<Type:8, Code:8, Checksum:16, DA1:8, DA2:8, DA3:8, DA4:8>>.



unpack_groups(0, Bin) -> {[], Bin};
unpack_groups(Count, <<Type, Len, SourceCount:16, I1,I2,I3,I4, Bin/binary>>) ->
SourceLength = SourceCount*4,
<<SourceBin:SourceLength/binary, Aux:Len/binary, Rest/binary>> = Bin,
Sources = [{S1,S2,S3,S4} || <<S1,S2,S3,S4>> <= SourceBin],
{Groups, Payload} = unpack_groups(Count - 1, Rest),
{[#igmp_group{type = Type, addr = {I1,I2,I3,I4}, sources = Sources, aux = Aux}|Groups], Payload}.


pack_group(#igmp_group{type = Type, aux = Aux, addr = {I1,I2,I3,I4}, sources = Sources}) ->
SourcesBin = [<<S1,S2,S3,S4>> || {S1,S2,S3,S4} <- Sources],
[<<Type, (size(Aux)), (length(Sources)):16, I1,I2,I3,I4>>, SourcesBin, Aux].

20 changes: 19 additions & 1 deletion test/pkt_igmp_tests.erl
Expand Up @@ -6,7 +6,9 @@
codec_test_() ->
[
decode(),
encode()
encode(),
decode_igmpv3_22(),
encode_igmpv3_22()
].

packet() ->
Expand All @@ -24,3 +26,19 @@ encode() ->
Packet = packet(),
{Header, Payload} = pkt:igmp(Packet),
?_assertEqual(Packet, <<(pkt:igmp(Header))/binary, Payload/binary>>).


packet_igmp_22() ->
<<16#22, 0, 235,252, 0,0,0,1, 3,0,0,0,239,0,0,1>>.

decode_igmpv3_22() ->
{Header, Payload} = pkt:igmp(packet_igmp_22()),
?_assertEqual({
#igmp{type = 34, code = 0, csum = 60412, group = [#igmp_group{type = 3, addr = {239,0,0,1}} ]},
<<>>
}, {Header, Payload}).

encode_igmpv3_22() ->
Packet = packet_igmp_22(),
{Header, Payload} = pkt:igmp(Packet),
?_assertEqual(Packet, <<(pkt:igmp(Header))/binary, Payload/binary>>).

0 comments on commit 2c71e02

Please sign in to comment.