From b414cd585376f42ecae1a180352262a9d8b1bfda Mon Sep 17 00:00:00 2001 From: Matthew Hutchinson Date: Sun, 2 Jul 2017 21:51:02 +0100 Subject: [PATCH] better packet detection, version bumped --- README.md | 8 ++++---- lib/lifx_dash/capturer.rb | 21 +++++++++++---------- lib/lifx_dash/version.rb | 2 +- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 0878f08..aa67bc7 100644 --- a/README.md +++ b/README.md @@ -152,10 +152,10 @@ take a moment and check it hasn't already been raised (and possibly closed). This gem uses the [PacketFu](https://rubygems.org/gems/packetfu) gem (and [libpcap](https://sourceforge.net/projects/libpcap/) under the hood) to monitor -data packets on your network. This packet stream filters -[ARP](https://en.wikipedia.org/wiki/Address_Resolution_Protocol) packets and -DHCP packets (sent from 0.0.0.0). Older buttons use the ARP method, while newer -buttons issue DHCP packets. +data packets on your network. This packet stream filters for +[DHCP](https://wiki.wireshark.org/DHCP) packets (sent from 0.0.0.0). Older dash +buttons sent both DHCP and [ARP](https://wiki.wireshark.org/ARP) packets but +detecting ARP reliably was problematic. When a valid packet is detected with a known source MAC address, the LIFX HTTP API [toggle-power](https://api.developer.lifx.com/docs/toggle-power) endpoint is diff --git a/lib/lifx_dash/capturer.rb b/lib/lifx_dash/capturer.rb index 9f52e9f..867a7a8 100644 --- a/lib/lifx_dash/capturer.rb +++ b/lib/lifx_dash/capturer.rb @@ -5,13 +5,10 @@ class Capturer # Berkeley Packet filter for Amazon Dash buttons # - # - older dash buttons issue an ARP packet from 0.0.0.0 - # - newer buttons broadcast a DHCP request from 0.0.0.0 - # - use the following bfp in WireShark to snoop for raw packets - # - (arp or (udp.srcport == 68 and udp.dstport == 67)) and ip.src == 0.0.0.0 + # - most dash buttons broadcast a DHCP request from 0.0.0.0 # - for more details see https://github.com/ide/dash-button/issues/36 # - PACKET_FILTER = "(arp or (udp and src port 68 and dst port 67)) and src host 0.0.0.0" + PACKET_FILTER = "udp and src port 68 and dst port 67 and udp[247:4] == 0x63350103 and src host 0.0.0.0" attr_reader :iface @@ -22,11 +19,15 @@ def initialize(network_iface_id) def listen(&block) # examine packets on the stream capturer.stream.each do |packet| - pkt = PacketFu::IPPacket.parse(packet) - # only consider the first packet sent - if pkt && pkt.ip_id == 1 - mac = PacketFu::EthHeader.str2mac(pkt.eth_src) - block.call(pkt, mac) if block + if PacketFu::IPPacket.can_parse?(packet) + pkt = PacketFu::IPPacket.parse(packet) + # only consider the first (early ip ids) even packet sent + # since dhcp often sends 2 packets in a quick burst + if pkt && pkt.ip_id < 5 && (pkt.ip_id % 2) == 0 + puts pkt.inspect + mac = PacketFu::EthHeader.str2mac(pkt.eth_src) + block.call(pkt, mac) if block + end end end end diff --git a/lib/lifx_dash/version.rb b/lib/lifx_dash/version.rb index 5185111..7656e10 100644 --- a/lib/lifx_dash/version.rb +++ b/lib/lifx_dash/version.rb @@ -1,3 +1,3 @@ module LifxDash - VERSION = "0.2.2" + VERSION = "0.2.3" end