lib/packetgen/utils.rb in packetgen-2.6.0 vs lib/packetgen/utils.rb in packetgen-2.7.0
- old
+ new
@@ -2,84 +2,76 @@
# See https://github.com/sdaubert/packetgen for more informations
# Copyright (C) 2016 Sylvain Daubert <sylvain.daubert@laposte.net>
# This program is published under MIT license.
# frozen_string_literal: true
+
require_relative 'config'
require_relative 'utils/arp_spoofer'
module PacketGen
-
# Collection of some network utilities.
#
# This module is not enabled by default. You need to:
# require 'packetgen/utils'
# @author Sylvain Daubert
# @since 2.1.3
module Utils
-
# Get local ARP cache
# @return [Hash] key: IP address, value: array containing MAC address and
# interface name
def self.arp_cache
- raw_cache = %x(/usr/sbin/arp -an)
+ raw_cache = `/usr/sbin/arp -an`
cache = {}
raw_cache.split(/\n/).each do |line|
match = line.match(/\((\d+\.\d+\.\d+\.\d+)\) at (([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2})(?: \[ether\])? on (\w+)/)
- if match
- cache[match[1]] = [match[2], match[4]]
- end
+ cache[match[1]] = [match[2], match[4]] if match
end
-
+
cache
end
-
+
# Get MAC address from an IP address, or nil if this IP address is unknown
# on local network.
# @param [String] ipaddr dotted-octet IP address
# @param [Hash] options
- # @option options [String] :iface interface name. Default to
+ # @option options [String] :iface interface name. Default to
# {PacketGen.default_iface}
# @option options [Boolean] :no_cache if +true+, do not query local ARP
# cache and always send an ARP request on wire. Default to +false+
# @option options [Integer] :timeout timeout in seconds before stopping
# request. Default to 2.
# @return [String,nil]
def self.arp(ipaddr, options={})
unless options[:no_cache]
local_cache = self.arp_cache
- return local_cache[ipaddr].first if local_cache.has_key? ipaddr
+ return local_cache[ipaddr].first if local_cache.key? ipaddr
end
iface = options[:iface] || PacketGen.default_iface
timeout = options[:timeout] || 1
my_hwaddr = Config.instance.hwaddr(iface)
arp_pkt = Packet.gen('Eth', dst: 'ff:ff:ff:ff:ff:ff', src: my_hwaddr)
arp_pkt.add('ARP', sha: Config.instance.hwaddr, spa: Config.instance.ipaddr,
- tpa: ipaddr)
-
+ tpa: ipaddr)
+
capture = Capture.new(iface: iface, timeout: timeout, max: 1,
filter: "arp src #{ipaddr} and ether dst #{my_hwaddr}")
cap_thread = Thread.new do
capture.start
end
arp_pkt.to_w(iface)
cap_thread.join
-
- if capture.packets.size > 0
- capture.packets.each do |pkt|
- if pkt.arp.spa.to_s == ipaddr
- break pkt.arp.sha.to_s
- end
- end
- else
- nil
+
+ return if capture.packets.empty?
+ capture.packets.each do |pkt|
+ break pkt.arp.sha.to_s if pkt.arp.spa.to_s == ipaddr
end
end
-
+
# Do ARP spoofing on given IP address. Call to this method blocks.
# @note This method is provided for test purpose.
# For more control, see {ARPSpoofer} class.
# @param [String] target_ip target IP address
# @param [String] spoofed_ip IP address to spoofed_ip
@@ -131,10 +123,10 @@
options = { iface: PacketGen.default_iface }.merge(options)
spoofer = Utils::ARPSpoofer.new(options)
spoofer.add target1, target2, options
spoofer.add target2, target1, options
-
+
my_mac = Config.instance.hwaddr(options[:iface])
my_ip = Config.instance.ipaddr(options[:iface])
capture = Capture.new(iface: options[:iface],
filter: "((ip src #{target1} and not ip dst #{my_ip}) or" \
" (ip src #{target2} and not ip dst #{my_ip}) or" \