Продолжим мучать наш сканер локальной сети. В прошлой статье мы реализовали пинг. Давайте теперь добавим отображение MAC адреса.
Что такое вообще MAC и зачем он ? Допустим у нас есть устройство А которое хочет отправит данные устройству Б. Для этого на нужно IP адрес устройства и обязательно его физический адрес. Так вот сложилось.
MAC-адрес (Media Access Control — управление доступом к среде, также Hardware Address, также физический адрес) — уникальный идентификатор, присваиваемый каждой единице активного оборудования или некоторым их интерфейсам в компьютерных сетях Ethernet.
ru.wikipedia.org
Что бы его узнать есть специальный протокол ARP . То есть устройство A кричит в сеть всем (бруткастит) : Алеее, устройство Б с IP 10.10.10.10 какой у тебя MAC ?
ARP (.Address Resolution Protocol — протокол определения адреса) — протокол в компьютерных сетях, предназначенный для определения MAC-адреса по IP-адресу другого компьютера.
ru.wikipedia.org
Что бы не засорять эфир, ответы кэшируются в таблицу ARP ( в Windows это по моему 4 минуты). Вот от туда мы и будем брать MAC после пинга IP адреса. Для этого есть специальная утилита в операционной системе — ARP ))))

Парсим таблицу :
response_arp = os.popen('arp -a -N '+ net)
data_arp = response_arp.readlines()
for line_arp in data_arp:
flag = line_arp.split()
if len(flag) > 0 and flag[0] == addr:
print(addr, "--> Ping Ok", ' МАС:', flag[1])
Ну и модифицированная функция сканирования :
def scan_Ip(ip):
addr = net + str(ip)
comm = ping_com + addr
response = os.popen(comm)
data = response.readlines()
for line in data:
if 'TTL' in line:
response_art = os.popen('arp -a')
data_arp = response_art.readlines()
for line_arp in data_arp:
flag = line_arp.split()
if len(flag) > 0 and flag[0] == addr:
print(addr, "--> Ping Ok", ' МАС:', flag[1])
break

Еще немного красоты и доделки.
Ну и последним штрихом захотелось добавить доменные имена компов если они есть. В Windows это может быть имена компов по протоколу NetBIOC если включено сетевое обнаружение. Для этого добавим всего лишь параметр -a в команду ping.
Весь код целиком:
import os
import platform
import threading
import socket
from datetime import datetime
global strin
strin = []
def getMyIp():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #Создаем сокет (UDP)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # Настраиваем сокет на BROADCAST вещание.
s.connect(('<broadcast>', 0))
return s.getsockname()[0]
def scan_Ip(ip):
addr = net + str(ip)
comm = ping_com + addr
response = os.popen(comm)
data = response.readlines()
name = data[1].split(' ')
for line in data:
if 'TTL' in line:
response_art = os.popen('arp -a')
data_arp = response_art.readlines()
for line_arp in data_arp:
flag = line_arp.split()
if len(flag) > 0 and flag[0] == addr:
tmp =(addr+"--> Ping Ok"+ ' '+ name[3]+' '+flag[1])
strin.append(tmp)
break
net = getMyIp()
print('You IP :',net)
net_split = net.split('.')
a = '.'
net = net_split[0] + a + net_split[1] + a + net_split[2] + a
start_point = int(input("Enter the Starting Number: "))
end_point = int(input("Enter the Last Number: "))
oс = platform.system()
if (oс == "Windows"):
ping_com = "ping -n 1 -a "
else:
ping_com = "ping -c 1 "
t1 = datetime.now()
print("Scanning in Progress:")
print('IP Status Name MAC')
for ip in range(start_point, end_point):
if ip == int(net_split[3]):
continue
potoc = threading.Thread(target=scan_Ip, args=[ip])
potoc.start()
#potoc.join()
potoc.join()
t2 = datetime.now()
total = t2 - t1
for i in strin:
print(i)
print ('Find ip :',len(strin))
print("Scanning completed in: ", total)

P.S Если у кого будут мысли по более интересной(практично) реализации пишите в комментариях ))))
Отличный код, спасибо!
А как сделать, чтобы можно было выбирать ip целиком (к примеру 193.169.1.100-105)?
Добрый день, очень жду 3 часть.
А именно интересует Vendor и порты.
Сканер портов вы можете добавить сами( пример кода на Питон есть на нашем сайте)…
Подскажите как к коду добавить сканирование Vendor?
Если в двух словах, каждому производителю выдаются пул MAC. Найти табличку пула популярных производителей и сделать проверку MAC.
Добрый день! Спасибо за статью и код соответственно. Добавил метод ljust для более красивого отображения таблицы и сохранение информации в файл и уже использую программу для своих нужд. Вопрос — можно ли таким же образом получать шлюз, через который локальный ПК подключен к сети и прокси?
Прокси хз, а шлюз можно взять например их ifconfig
\Спасибо. Я тоже пока ничего не нашел про прокси, копаю дальше. Может даже вообще его нельзя определить.