msantos / pkt

Erlang network protocol library
http://blog.listincomprehension.com/search/label/epcap
BSD 3-Clause "New" or "Revised" License
150 stars 44 forks source link

Support for 0x886c #40

Open pmontrasio opened 7 years ago

pmontrasio commented 7 years ago

I was running epcap inside an Elixir program on a Raspberry PI 3 when I run into this error

** (FunctionClauseError) no function clause matching in :pkt_ether.type/1
    src/pkt_ether.erl:37: :pkt_ether.type(34924)
    src/pkt.erl:120: :pkt.decapsulate_next/2

34924 is 0x886c. I googled and found https://www.raspberrypi.org/forums/viewtopic.php?t=146246&p=963226 If I understood that correctly, it's the builtin wifi card of the PI that is sending those packets. I don't know what a LARQ is and I don't really now what I've been doing, but this fixed that:

diff --git a/include/pkt_ether.hrl b/include/pkt_ether.hrl
index 2412165..71107ba 100644
--- a/include/pkt_ether.hrl
+++ b/include/pkt_ether.hrl
@@ -7,6 +7,7 @@
 -define(ETH_P_LLDP, 16#88CC).
 -define(ETH_P_MPLS_UNI, 16#8847).
 -define(ETH_P_MPLS_MULTI, 16#8848).
+-define(ETH_P_LARQ, 16#886C).

 -record(ether, {
     dhost = <<0,0,0,0,0,0>> :: <<_:48>>,
diff --git a/src/pkt.erl b/src/pkt.erl
index a75519a..05e28df 100644
--- a/src/pkt.erl
+++ b/src/pkt.erl
@@ -191,7 +191,10 @@ decapsulate_next({vrrp, Data}, Headers) ->
     lists:reverse([Payload, Header | Headers]);
 % IPv6 NONE pseudo-header
 decapsulate_next({ipv6_none, Data}, Headers) ->
-    lists:reverse([Data|Headers]).
+    lists:reverse([Data|Headers]);
+% LARQ
+decapsulate_next({larq, _}, Headers) ->
+    Headers.

 decode(Data) when is_binary(Data) ->
     decode(ether, Data).
diff --git a/src/pkt_ether.erl b/src/pkt_ether.erl
index c00a955..512d063 100644
--- a/src/pkt_ether.erl
+++ b/src/pkt_ether.erl
@@ -46,7 +46,9 @@ type(?ETH_P_802_1Q) -> '802.1q';
 type(?ETH_P_802_1QinQ) -> '802.1qinq';
 %% MPLS_
 type(?ETH_P_MPLS_UNI) -> mpls;
-type(?ETH_P_MPLS_MULTI) -> mpls.
+type(?ETH_P_MPLS_MULTI) -> mpls;
+%% LARQ
+type(?ETH_P_LARQ) -> larq.

 codec(<<Dhost:6/bytes, Shost:6/bytes, Type:16, Payload/binary>>) ->
 %    Len = byte_size(Packet) - 4,

It's probably a hack but I hope it helps adding proper support for these packets.

decapsulate now returns something like

[{:ether, <<184, 39, 235, 46, 32, 156>>, <<186, 39, 235, 46, 32, 156>>, 34924, 0}]

Maybe it's not the Erlang way, but it could return unknown instead of failing when it doesn't know how to decapsulate something. The client would fail anyway if it doesn't handle that, or could decide to keep going on.

msantos commented 7 years ago

Hey Paolo!

I was running epcap inside an Elixir program on a Raspberry PI 3 when I run into this error

** (FunctionClauseError) no function clause matching in :pkt_ether.type/1
    src/pkt_ether.erl:37: :pkt_ether.type(34924)
    src/pkt.erl:120: :pkt.decapsulate_next/2

34924 is 0x886c. I googled and found https://www.raspberrypi.org/forums/viewtopic.php?t=146246&p=963226 If I understood that correctly, it's the builtin wifi card of the PI that is sending those packets. I don't know what a LARQ is and I don't really now what I've been doing, but this fixed that:

diff --git a/include/pkt_ether.hrl b/include/pkt_ether.hrl
index 2412165..71107ba 100644
Thanks for figuring this out! That looks great.

The first binary is the destination MAC address, the second binary is the source MAC address and it looks like the next two terms could be the LARQ header followed by a pad.

The raspberry pi thread you linked to has the protocol details:

https://www.google.ch/patents/US20070263631

The header format:

https://patentimages.storage.googleapis.com/US20070263631A1/US20070263631A1-20071115-D00005.png https://patentimages.storage.googleapis.com/US20070263631A1/US20070263631A1-20071115-D00006.png

Could you provide a packet dump in pcap format? Feel free to anonymize it. You can email it directly or attach it to this issue:

michael.santos@gmail.com

Maybe it's not the Erlang way, but it could return unknown instead of failing when it doesn't know how to decapsulate something. The client would fail anyway if it doesn't handle that, or could decide to keep going on.

See pkt:decode/1,2. They'll return the decoded headers and the remaining binary on error.

pmontrasio commented 7 years ago

I'm not very familiar with these tools and I'm not sure if I got any 0x886c packet in a dump I made with tshark -i wlan1 -w test.pcap -F libpcap, nor I could find a way to create a capture filter for only those packets.

Running out of time I googled for them and I found this issue of Wireshark. There is a link to a pcap file with a 0x886c packet. Would that be good enough?

Thanks for the reference to pkt:decode/1,2. I didn't notice that. Maybe I was cargo culting from some page that decoded packets using decapsulate.

msantos commented 7 years ago

Thanks for trying! I'll have a look at the links, they look like a good start. I have to order an rpi3 anyway so I'll be able to add support for the other frames types then.

If you run into any more issues or have any questions, please feel free to let me know!