Как узнать IP-адрес устройства (принтера, камеры, PLC) без знания подсети — полный гайд для инженеро
? Определение IP сетевого устройства без знания подсети
(на примере HP LaserJet 1320tn)
Введение
В инженерной практике регулярно возникает задача:
> Есть устройство с Ethernet (принтер, камера, PLC),
> есть физический доступ,
> но IP-адрес и подсеть неизвестны.
Классические инструменты вроде nmap в этом случае бесполезны, так как требуют знания сети уровня L3.
Решение лежит на уровень ниже — L2 (Ethernet).
? Ключевая идея
Если ты подключён напрямую:
- вы на одном L2 сегменте
- IP не важен
- маршрутизация не нужна
? Значит, можно обнаружить устройство через:
- ARP
- broadcast
- multicast (mDNS, SSDP)
? Метод 1 — Passive sniff (tcpdump)
Самый надёжный и быстрый способ.
подключаемся кабелем ethernet к устройству, проверяем название своего интерфейса
☯
Terminal:
⌕
≡
✕
ifconfig
допустим это eth0, значит
Запуск
☯
Terminal:
⌕
≡
✕
ip addr flush dev eth0 ip link set eth0 up tcpdump -e -n -i eth0
И только теперь включаем принтер по питанию!
Что искать
Типичный вывод:
☯
Terminal:
⌕
≡
✕
ARP, Request who-has 192.168.1.1 tell 192.168.1.45
? IP устройства = 192.168.1.45
? Важный момент
IP на интерфейсе НЕ нужен.
Почему:
- tcpdump работает на уровне Ethernet
- ARP не требует IP
- broadcast принимается всегда
? Метод 2 — mDNS тоже самое только
☯
Terminal:
⌕
≡
✕
tcpdump -i eth0 udp port 5353
? Почему порт 5353
Это фиксировано стандартом (RFC 6762):
| Протокол | Порт |
| mDNS | 5353 |
? Метод 3 — Автоматизация через Python (tcpdump)
Подход
- запуск tcpdump через subprocess
- парсинг stdout
- извлечение IP и метаданных
Пример
☯
Terminal:
⌕
≡
✕
import subprocess
import re
devices = {}
cmd = [
"tcpdump",
"-l",
"-n",
"-i", "eth0",
"udp port 5353"
]
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, text=True)
for line in process.stdout:
ip_match = re.search(r'(\d+\.\d+\.\d+\.\d+)\.5353', line)
if not ip_match:
continue
ip = ip_match.group(1)
model_match = re.search(r'ty=([^"]+)', line)
model = model_match.group(1) if model_match else "Unknown"
if ip not in devices:
devices[ip] = model
print(f"[+] {ip} ({model})")? Особенности подхода
Плюсы:
- минимальные зависимости
- работает «везде»
- даёт полный raw-доступ
Минусы:
- требует root
- нужно парсить текст
- менее устойчиво
? Метод 4 — Правильный способ через zeroconf
Используем zeroconf
Установка
☯
Terminal:
⌕
≡
✕
pip install zeroconf
Пример
☯
Terminal:
⌕
≡
✕
from zeroconf import Zeroconf, ServiceBrowser, ServiceListener
import socket
class Listener(ServiceListener):
def add_service(self, zc, type_, name):
info = zc.get_service_info(type_, name)
if info:
ip = socket.inet_ntoa(info.addresses[0])
print(ip, name)
zc = Zeroconf()
ServiceBrowser(zc, "_printer._tcp.local.", Listener())
input("Press Enter to exit...")
zc.close()Что происходит
- подписка на
_printer._tcp.local - автоматическое получение IP
- парсинг DNS-SD записей
Почему это лучше
- не нужен root
- не нужен tcpdump
- корректный парсинг протокола
- production-ready
? Альтернативные протоколы discovery
| Протокол | Назначение | Порт |
| mDNS | zero-config устройства | 5353 |
| SSDP | UPnP устройства | 1900 |
| LLMNR | Windows-сети | 5355 |
| DHCP | выдача IP | 67/68 |
⚠️ Когда это НЕ сработает
- устройство не отправляет трафик
- отключён mDNS
- интерфейс down
- другая VLAN
? Архитектура универсальной утилиты
Правильный инженерный подход:
☯
Terminal:
⌕
≡
✕
1. Passive sniff (tcpdump / pcap) 2. mDNS discovery 3. ARP sweep (ограниченный) 4. DHCP listener
? Практический workflow
- Подключение кабелем
- Запуск tcpdump
- Перезапуск устройства
- Анализ: - ARP → IP - mDNS → IP + hostname - DHCP → MAC → IP
? Ключевые выводы
- ❌ IP не нужен для discovery
- ✅ L2 полностью достаточно
- ✅ MAC не даёт IP напрямую
- ✅ mDNS — самый быстрый источник
- ✅ passive sniff > активного сканирования
Вот рабочий скрипт:
☯
Terminal:
⌕
≡
✕
sudo apt update sudo apt install python3 python3-venv python3-pip python3 -m venv myenv source myenv/bin/activate pip install zeroconf myenv/bin/python3 getIPfromDump.py
содержимое файла getIPfromDump.py
☯
Terminal:
⌕
≡
✕
from zeroconf import Zeroconf, ServiceBrowser, ServiceListener
import socket
import time
class PrinterListener(ServiceListener):
def __init__(self):
self.devices = {}
def add_service(self, zeroconf, service_type, name):
info = zeroconf.get_service_info(service_type, name)
if info:
ip = socket.inet_ntoa(info.addresses[0])
properties = info.properties
model = properties.get(b'ty', b'Unknown').decode()
admin_url = properties.get(b'adminurl', b'').decode()
if ip not in self.devices:
self.devices[ip] = {
"name": name,
"model": model,
"admin_url": admin_url
}
print("\n=== Device Found ===")
print(f"Name: {name}")
print(f"IP: {ip}")
print(f"Model: {model}")
if admin_url:
print(f"Admin URL: {admin_url}")
print()
if __name__ == "__main__":
zeroconf = Zeroconf()
listener = PrinterListener()
print("Listening for printers via mDNS...\n")
# Ищем все принтеры
browser = ServiceBrowser(zeroconf, "_printer._tcp.local.", listener)
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\nStopping...")
zeroconf.close()
нормальный инженерный CLI-инструмент, а не просто скрипт. Ниже — уже архитектура + готовый минимально жизнеспособный инструмент, который можно расширять.
? CLI-инструмент: L2 Device Finder
? Цель
Найти IP устройства (например HP LaserJet 1320tn), если:
* есть физическое подключение
* неизвестна подсеть
* DHCP может отсутствовать
? Архитектура (правильная)
CLI должен работать по слоям:
☯
Terminal:
⌕
≡
✕
[ passive ] ↓ [mDNS sniff] ↓ [ARP scan] ↓ [optional DHCP]
? MVP CLI (реально рабочий)
? Зависимости
☯
Terminal:
⌕
≡
✕
pip install click zeroconf scapy
? Код
☯
Terminal:
⌕
≡
✕
#!/usr/bin/env python3
import click
import socket
import time
from zeroconf import Zeroconf, ServiceBrowser, ServiceListener
from scapy.all import ARP, Ether, srp
# =========================
# mDNS LISTENER
# =========================
class MDNSListener(ServiceListener):
def __init__(self):
self.devices = {}
def add_service(self, zeroconf, service_type, name):
info = zeroconf.get_service_info(service_type, name)
if info:
ip = socket.inet_ntoa(info.addresses[0])
if ip not in self.devices:
self.devices[ip] = name
click.echo(f"[mDNS] {ip} -> {name}")
def mdns_scan(timeout):
click.echo("[*] Listening mDNS...")
zc = Zeroconf()
listener = MDNSListener()
ServiceBrowser(zc, "_services._dns-sd._udp.local.", listener)
time.sleep(timeout)
zc.close()
# =========================
# ARP SCAN
# =========================
def arp_scan(interface):
click.echo("[*] ARP scan (common ranges)...")
ranges = [
"192.168.0.0/24",
"192.168.1.0/24",
"10.0.0.0/24",
"172.16.0.0/24"
]
for net in ranges:
click.echo(f" -> scanning {net}")
pkt = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=net)
result = srp(pkt, timeout=2, iface=interface, verbose=0)[0]
for sent, received in result:
click.echo(f"[ARP] {received.psrc} ({received.hwsrc})")
# =========================
# CLI
# =========================
@click.command()
@click.option("--iface", default="eth0", help="Network interface")
@click.option("--timeout", default=5, help="mDNS listen time")
@click.option("--arp", is_flag=True, help="Enable ARP scan")
def main(iface, timeout, arp):
"""
L2 Device Finder
"""
click.echo(f"[*] Interface: {iface}")
# 1. mDNS
mdns_scan(timeout)
# 2. ARP fallback
if arp:
arp_scan(iface)
click.echo("[*] Done")
if __name__ == "__main__":
main()▶️ Использование
☯
Terminal:
⌕
≡
✕
sudo python3 finder.py --iface eth0 --timeout 5 --arp
? Что делает этот CLI
✅ mDNS
* находит устройства типа:
* принтеры
* AirPlay
* SSH
* HTTP
✅ ARP fallback
* сканирует популярные сети
* возвращает IP + MAC
? Как это работает в твоём кейсе
С принтером:
* он шлёт mDNS
* CLI ловит:
☯
Terminal:
⌕
≡
✕
[mDNS] 10.10.10.124 -> print.local
? дальше:
☯
Terminal:
⌕
≡
✕
http://10.10.10.124
? Как улучшить (production roadmap)
1️⃣ Passive sniff через pcap
Добавить:
* raw capture
* парсинг ARP / DHCP
2️⃣ Фильтрация по MAC (OUI)
Определять:
* HP
* Cisco
* MikroTik
3️⃣ JSON output
☯
Terminal:
⌕
≡
✕
finder --json
4️⃣ Автоназначение IP
Если нашли сеть:
☯
Terminal:
⌕
≡
✕
ip addr add X.X.X.10/24 dev eth0
5️⃣ Параллельный ARP scan
ускорение ×10
⚠️ Ограничения
* нужен root (ARP)
* не работает через VLAN без доступа
* зависит от активности устройства
? Итог
Ты сейчас построил:
? L2 discovery tool
Который:
* не требует знания подсети
* работает через Ethernet
* использует реальные сетевые протоколы
? Финальный инженерный инсайт
Это уже не просто утилита.
Это:
> ? аналог mini-версии discovery из:
>
> * nmap (частично)
> * avahi
> * zeroconf stack
-
Создано 15.01.2026 15:15:39
-
Roman Sakhno

Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.