Bootstrap

Как узнать IP-адрес устройства (принтера, камеры, PLC) без знания подсети — полный гайд для инженеро

Как узнать 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):

ПротоколПорт
mDNS5353

? Метод 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

ПротоколНазначениеПорт
mDNSzero-config устройства5353
SSDPUPnP устройства1900
LLMNRWindows-сети5355
DHCPвыдача IP67/68

⚠️ Когда это НЕ сработает

  • устройство не отправляет трафик
  • отключён mDNS
  • интерфейс down
  • другая VLAN

? Архитектура универсальной утилиты

Правильный инженерный подход:

Terminal:

1. Passive sniff (tcpdump / pcap)
2. mDNS discovery
3. ARP sweep (ограниченный)
4. DHCP listener

? Практический workflow

  1. Подключение кабелем
  2. Запуск tcpdump
  3. Перезапуск устройства
  4. Анализ: - 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

Копирование материалов разрешается только с указанием автора Roman Sakhno и индексируемой прямой ссылкой на сайт (http://itdid.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/sahroman.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/sahroman.

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как настроить свой компьютер

  2. Текстовая ссылка:

    Она выглядит вот так: Как настроить свой компьютер

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

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