Permalink
Browse files

Merge branch 'ipv6-icmp'

  • Loading branch information...
2 parents 0a42cd3 + 7b0ccf4 commit 81dad4668c31e85bf0a635bdea889943e664d4d2 @msantos msantos committed May 24, 2012
Showing with 103 additions and 2 deletions.
  1. +4 −1 README.md
  2. +30 −0 include/pkt.hrl
  3. +69 −1 src/pkt.erl
View
@@ -35,10 +35,13 @@ types.
sctp(Packet) -> {#sctp{}, Payload} | binary()
udp(Packet) -> {#udp{}, Payload} | binary()
icmp(Packet) -> {#icmp{}, Payload} | binary()
+ icmp6(Packet) -> {#icmp6{}, Payload} | binary()
Types Packet = Header | binary()
Header = #ether{} | #null{} | #linux_cooked{} | #arp{} |
- #ipv4{} | #ipv6{} | #tcp{} | #sctp{} | #upd{} | #icmp{}
+ #ipv4{} | #ipv6{} | #tcp{} | #sctp{} | #udp{} |
+ #icmp{} | #icmp6{}
+
makesum(Packet) -> integer()
View
@@ -99,6 +99,25 @@
-define(ICMP_ADDRESS, 17).
-define(ICMP_ADDRESSREPLY, 18).
+-define(ICMP6_DST_UNREACH, 1).
+-define(ICMP6_PACKET_TOO_BIG, 2).
+-define(ICMP6_TIME_EXCEEDED, 3).
+-define(ICMP6_PARAM_PROB, 4).
+-define(ICMP6_INFOMSG_MASK, 16#80). % all informational messages
+-define(ICMP6_ECHO_REQUEST, 128).
+-define(ICMP6_ECHO_REPLY, 129).
+-define(ICMP6_DST_UNREACH_NOROUTE, 0). % no route to destination
+-define(ICMP6_DST_UNREACH_ADMIN, 1). % communication with destination
+-define(ICMP6_DST_UNREACH_BEYONDSCOPE, 2). % beyond scope of source address
+-define(ICMP6_DST_UNREACH_ADDR, 3). % address unreachable
+-define(ICMP6_DST_UNREACH_NOPORT, 4). % bad port
+-define(ICMP6_TIME_EXCEED_TRANSIT, 0). % Hop Limit == 0 in transit
+-define(ICMP6_TIME_EXCEED_REASSEMBLY, 1). % Reassembly time out
+-define(ICMP6_PARAMPROB_HEADER, 0). % erroneous header field
+-define(ICMP6_PARAMPROB_NEXTHEADER, 1). % unrecognized Next Header
+-define(ICMP6_PARAMPROB_OPTION, 2). % unrecognized IPv6 option
+-define(ICMP6_ROUTER_RENUMBERING, 138).
+
-record(linux_cooked, {
packet_type,
hrd = ?ARPHRD_ETHER,
@@ -170,6 +189,17 @@
ts_orig = 0, ts_recv = 0, ts_tx = 0
}).
+-record(icmp6, {
+ type = ?ICMP6_ECHO_REQUEST, code = 0, checksum = 0,
+
+ un = <<0:32>>,
+ pptr = 0,
+ mtu = 0,
+ id = 0,
+ seq = 0,
+ maxdelay = 0
+ }).
+
-record(sctp, {
sport = 0, dport = 0, vtag = 0, sum = 0,
chunks = []
View
@@ -1,4 +1,4 @@
-%% Copyright (c) 2009-2010, Michael Santos <michael.santos@gmail.com>
+%% Copyright (c) 2009-2012, Michael Santos <michael.santos@gmail.com>
%% All rights reserved.
%%
%% Redistribution and use in source and binary forms, with or without
@@ -38,6 +38,7 @@
-define(TCPHDRLEN, 20).
-define(UDPHDRLEN, 8).
-define(ICMPHDRLEN, 8).
+-define(ICMP6HDRLEN, 8).
-define(GREHDRLEN, 4).
-export([
@@ -53,6 +54,7 @@
null/1,
linux_cooked/1,
icmp/1,
+ icmp6/1,
ipv4/1,
ipv6/1,
proto/1,
@@ -115,6 +117,9 @@ decapsulate({sctp, Data}, Packet) when byte_size(Data) >= 12 ->
decapsulate({icmp, Data}, Packet) when byte_size(Data) >= ?ICMPHDRLEN ->
{Hdr, Payload} = icmp(Data),
decapsulate(stop, [Payload, Hdr|Packet]);
+decapsulate({icmp6, Data}, Packet) when byte_size(Data) >= ?ICMP6HDRLEN ->
+ {Hdr, Payload} = icmp6(Data),
+ decapsulate(stop, [Payload, Hdr|Packet]);
decapsulate({_, Data}, Packet) ->
decapsulate(stop, [{truncated, Data}|Packet]).
@@ -135,6 +140,7 @@ family(_) -> unsupported.
proto(?IPPROTO_IP) -> ip;
proto(?IPPROTO_ICMP) -> icmp;
+proto(?IPPROTO_ICMPV6) -> icmp6;
proto(?IPPROTO_TCP) -> tcp;
proto(?IPPROTO_UDP) -> udp;
proto(?IPPROTO_IPV6) -> ipv6;
@@ -496,6 +502,68 @@ icmp(#icmp{type = Type, code = Code, checksum = Checksum, un = Un}) ->
%%
+%% ICMPv6
+%%
+
+% ICMPv6 Error Messages
+
+% Destination Unreachable Message
+icmp6(<<?ICMP6_DST_UNREACH:8, Code:8, Checksum:16, Unused:32/bits, Payload/binary>>) ->
+ {#icmp6{
+ type = ?ICMP6_DST_UNREACH, code = Code, checksum = Checksum, un = Unused
+ }, Payload};
+icmp6(#icmp6{
+ type = ?ICMP6_DST_UNREACH, code = Code, checksum = Checksum, un = Unused
+ }) ->
+ <<?ICMP6_DST_UNREACH:8, Code:8, Checksum:16, Unused:32/bits>>;
+
+% Packet too big
+icmp6(<<?ICMP6_PACKET_TOO_BIG:8, Code:8, Checksum:16, MTU:32, Payload/binary>>) ->
+ {#icmp6{
+ type = ?ICMP6_PACKET_TOO_BIG, code = Code, checksum = Checksum, mtu = MTU
+ }, Payload};
+icmp6(#icmp6{
+ type = ?ICMP6_PACKET_TOO_BIG, code = Code, checksum = Checksum, mtu = MTU
+ }) ->
+ <<?ICMP6_PACKET_TOO_BIG:8, Code:8, Checksum:16, MTU:32>>;
+
+% Time Exceeded Message
+icmp6(<<?ICMP6_TIME_EXCEEDED:8, Code:8, Checksum:16, Unused:32/bits, Payload/binary>>) ->
+ {#icmp6{
+ type = ?ICMP6_TIME_EXCEEDED, code = Code, checksum = Checksum, un = Unused
+ }, Payload};
+icmp6(#icmp6{
+ type = ?ICMP6_TIME_EXCEEDED, code = Code, checksum = Checksum, un = Unused
+ }) ->
+ <<?ICMP6_TIME_EXCEEDED:8, Code:8, Checksum:16, Unused:32/bits>>;
+
+% Parameter Problem Message
+icmp6(<<?ICMP6_PARAM_PROB:8, Code:8, Checksum:16, Ptr:32, Payload/binary>>) ->
+ {#icmp6{
+ type = ?ICMP6_PARAM_PROB, code = Code, checksum = Checksum, pptr = Ptr
+ }, Payload};
+icmp6(#icmp6{
+ type = ?ICMP6_PARAM_PROB, code = Code, checksum = Checksum, pptr = Ptr
+ }) ->
+ <<?ICMP6_PARAM_PROB:8, Code:8, Checksum:16, Ptr:32>>;
+
+% ICMPv6 Informational Messages
+
+% Echo Request Message/Echo Reply Message
+icmp6(<<Type:8, Code:8, Checksum:16, Id:16, Seq:16, Payload/binary>>)
+ when Type =:= ?ICMP6_ECHO_REQUEST; Type =:= ?ICMP6_ECHO_REPLY ->
+ {#icmp6{
+ type = Type, code = Code, checksum = Checksum,
+ id = Id, seq = Seq
+ }, Payload};
+icmp6(#icmp6{
+ type = Type, code = Code, checksum = Checksum,
+ id = Id, seq = Seq
+ }) when Type =:= ?ICMP6_ECHO_REQUEST; Type =:= ?ICMP6_ECHO_REPLY ->
+ <<Type:8, Code:8, Checksum:16, Id:16, Seq:16>>.
+
+
+%%
%% Utility functions
%%

0 comments on commit 81dad46

Please sign in to comment.