Skip to content

Instantly share code, notes, and snippets.

@Mic92
Forked from anonymous/borrow-mac
Last active August 17, 2017 22:04
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Mic92/c59490b092c15fe5e31ee7c0222fd20c to your computer and use it in GitHub Desktop.
Save Mic92/c59490b092c15fe5e31ee7c0222fd20c to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
def assert_command_exists(cmd)
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
exe = File.join(path, cmd)
return exe if File.executable?(exe) && File.file?(exe)
end
abort "#{cmd} not found"
end
def sh(*args)
puts("$ #{args.join(" ")}")
system(*args)
end
def process_tcpdump(iface, stream)
stats = Hash.new(0)
top5 = []
begin
stream.each do |line|
fields = line.split(/\s+/)
next unless fields.size > 1
mac = fields[1]
next unless mac =~ /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/
stats[mac] += 1
top5 = stats.sort_by {|_, v| v}[0, 5]
system("clear")
puts("Least commonly used mac addresses")
top5.each_with_index do |p, i|
puts("#{i + 1}. #{p[0]} : #{p[1]} packets")
end
puts("\nReceived packets: #{stats.values.inject(:+)}")
puts("Seen devices: #{stats.size}")
end
rescue IOError, Interrupt
return if top5.size < 1
print "apply address (1-#{top5.size}) "
num = STDIN.gets.to_i
if 1 <= num && num <= top5.size
sh("ip", "link", "set", "dev", iface, "down")
sh("ip", "link", "set", "dev", iface, "address", top5[num - 1][0])
sh("ip", "link", "set", "dev", iface, "up")
end
end
end
def main(args)
tcpdump = assert_command_exists("tcpdump")
assert_command_exists("ip")
ping = assert_command_exists("ping")
if args.size < 1
$stderr.puts "USAGE: #{$0} <interface>"
exit(1)
end
iface = args[0]
IO.popen([tcpdump, "-n", "-l", "-e", "-i", iface]) do |stream|
# lets find all devices pretty quickly by using multicast ping
IO.popen ([ping, "-c", "6", "-6", "ff02::1%#{iface}"]) do |stdout|
# discard output
stdout.read
end
abort "ping failed" unless $? != 2
process_tcpdump(iface, stream)
end
rescue Interrupt
end
main(ARGV)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment