Решая задачку раздачи инета на второй комп, наткнулся на необходимость получения IP адреса по MAC. Сначала использовал какой-то скрипт на вижуалбейсике, но при даунгрейде Windows XP до Windows 2000 способ отвалился. Тогда я плюнул на тот скрипт и пару bat-ников обвязки и соединил всё в скрипт на Ruby


Собственно имеем:



  1. Комп с линухом и сквидом, раздающий инет. Внутренний IP — динамический

  2. Комп с Windows, на котором нужен инет. IP — динамический, подсеть та же

  3. Нежелание свзяваться с роутером, чтобы избавиться от этого безобразия =)


Наш алгоритм



  1. Пингуем всю подсеть (да, в винде пинг не умеет броадкасты)

  2. Ищем нужный мак в кэше

  3. Пишем в хостс нужный адрес


Сам код:


require 'fileutils'


# мак-адрес жертвы. в windows через чёрточки, в linux через двоеточия

mac = '00-12-34-56-78-9a'

# имя хоста для нашего адреса

host = 'proxy'

# файл hosts, у нас Windows 2000, напоминаю

hosts_file = 'c:/winnt/system32/drivers/etc/hosts'


# задаём диапазон айпишников. мне так было удобнее =)

class_a = (127..127)

class_b = (0..0)

class_c = (0..255)

class_d = (1..254)


# запускаем наши пинги

puts 'Running pings...'

class_a.each do |a|

  class_b.each do |b|

    class_c.each do |c|

      class_d.each do |d|

        cmd = "start /b ping #{a}.#{b}.#{c}.#{d} -n 1 > nul"

          # раз у нас не работают всякие форки и бэкграунды,

          # используем для этих целей утилиту start

        system(cmd)

        print '.' # чтобы юзер не скучал

      end

    end

  end

end

print "\n"


puts 'Waiting for pings to finish...'

sleep(5) # ждём. на самом деле можно меньше


puts 'Checking arp cache for MAC...' # теперь все жвые компы должны осесть в кэше arp

arp_cache = `arp -a`

ip = nil

arp_cache.split("\n").each do |s|

  if(s[mac])

    ip = s.split[0]

  end

end


if(ip == nil) # не нашли. облом

  puts 'Error: IP address not found'

  STDIN.getc

  quit

end


puts "IP is #{ip}. Setting hosts file..." # пишем наш результат в хостс

tmp_file = hosts_file + ".tmp"

tf = File.new(tmp_file, "w")

hf = File.new(hosts_file, "r")


append = 1

hf.readlines.each do |line|

  if line[host]

    append = 0

    tf.puts("#{ip}\t#{host}")

  else

    tf.puts(line)

  end

end


if(append == 1)

  tf.puts("#{ip}\t#{host}")

end


hf.close

tf.close



FileUtils.rm(hosts_file)

FileUtils.mv(tmp_file,hosts_file)


файлом


К сожалению, работает далеко не мгновенно, а так уже недели две стоит на моём втором компе и не вызывает нареканий.


P.S. Подскажите если кто знает как в вордпрессе нормально код выкладывать? Это ж ужосужос, замучился пока форматировал


Originally published at Chase your dream!. You can comment here or there.