Skip to content

Commit

Permalink
better packet detection, version bumped
Browse files Browse the repository at this point in the history
  • Loading branch information
matthutchinson committed Jul 2, 2017
1 parent 1fa0ff2 commit b414cd5
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 15 deletions.
8 changes: 4 additions & 4 deletions README.md
Expand Up @@ -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
Expand Down
21 changes: 11 additions & 10 deletions lib/lifx_dash/capturer.rb
Expand Up @@ -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

Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/lifx_dash/version.rb
@@ -1,3 +1,3 @@
module LifxDash
VERSION = "0.2.2"
VERSION = "0.2.3"
end

0 comments on commit b414cd5

Please sign in to comment.