Сканер локальной сети для получения списка IP и MAC адресов на Python

есть вопросы к решению, которое описано выше.

поэтому и возник вопрос: разве нет такого в стандартных модулях языка? зачем городить забор и изобретать велосипед?
Так посмотрите стандартные модули языка, для чего они, если это возможно, вы найдете информацию. Чем не нравиться socket? И какой вопрос есть к решению?)
 
Последнее редактирование:
Так посмотрите стандартные модели языка, для чего они, если это возможно, вы найдете информацию. Чем не нравиться socket?
вы вообще читали всю ветку? там написано, что не так в решении со стэк оферфлоу. я даже процитировал его в прошлом ответе. ведите себя немного адекватнее, не нужно наезжать. мы здесь общаемся и обсуждаем важную тему. я искал решения со стандартными модулями и не через пень колоду. читал документацию по нескольким вроде бы подходящим модулям, искал в поисковиках
 
вы вообще читали всю ветку? там написано, что не так в решении со стэк оферфлоу. я даже процитировал его в прошлом ответе. ведите себя немного адекватнее, не нужно наезжать. мы здесь общаемся и обсуждаем важную тему. я искал решения со стандартными модулями и не через пень колоду. читал документацию по нескольким вроде бы подходящим модулям, искал в поисковиках

Если вы нашли решение помимо сокета, может быть поделитесь, на полном серьезе? Просто это было бы очень полезно. Я тут нашел решение для Linux, но оно такое же костыльное как и для Windows, через subprocess, если интересно, конечно:

Python:
import subprocess

com_run = subprocess.check_output('ip -h -br a | grep UP', shell=True).decode()
default_interface = com_run.split()[0].strip()
local_ipv4 = com_run.split()[2].strip().split("/")[0]
local_ipv6 = com_run.split()[3].strip().split("/")[0]
print(f'Default interface: {default_interface}\nLocal IPv4: {local_ipv4}\nLocal IPv6: {local_ipv6}')
 
вы вообще читали всю ветку? там написано, что не так в решении со стэк оферфлоу. я даже процитировал его в прошлом ответе. ведите себя немного адекватнее, не нужно наезжать. мы здесь общаемся и обсуждаем важную тему. я искал решения со стандартными модулями и не через пень колоду. читал документацию по нескольким вроде бы подходящим модулям, искал в поисковиках
Очень разочарован что вы находите мои ответы - наездом. Это не так, я просто упорно не могу понять и добиться от вас ответа на вопрос, чем вам не нравиться socket?) Потому что лично я не знаю решения со стандартными либами, кроме изобретения велосипеда. Может вы просветите, если найдете.

Если вы нашли решение помимо сокета, может быть поделитесь, на полном серьезе? Просто это было бы очень полезно. Я тут нашел решение для Linux, но оно такое же костыльное как и для Windows, через subprocess, если интересно, конечно:

Python:
import subprocess

com_run = subprocess.check_output('ip -h -br a | grep UP', shell=True).decode()
default_interface = com_run.split()[0].strip()
local_ipv4 = com_run.split()[2].strip().split("/")[0]
local_ipv6 = com_run.split()[3].strip().split("/")[0]
print(f'Default interface: {default_interface}\nLocal IPv4: {local_ipv4}\nLocal IPv6: {local_ipv6}')
Это тоже что я имел в виду, сделать в терминале ifconfig с помощью питона, и спарсить нужный ответ - айпишник.
 
Это тоже что я имел в виду, сделать в терминале ifconfig с помощью питона, и спарсить нужный ответ - айпишник.

Ну да. Я так и сделал. Просто команда поновее )) Если честно, то про нее не знал. Всегда пользовался ifconfig. А тут узнал, что она устарела.
 
если найду ответ обязательно поделюсь
меня интересует именно стандартный модуль языка. решение типа такого.

Python:
import os
os.get_local_ip()

к сожалению, мои исследования завершились неудачей. нет такого решения. возможно, в новых версиях языка что-то добавят.

кстати, кто какой версией питона пользуется?
 
если найду ответ обязательно поделюсь
меня интересует именно стандартный модуль языка. решение типа такого.

Python:
import os
os.get_local_ip()

к сожалению, мои исследования завершились неудачей. нет такого решения. возможно, в новых версиях языка что-то добавят.

кстати, кто какой версией питона пользуется?
Интересный вариант) Тогда знаете, есть вариант ещё круче. Предлагаю:

import hucker
hucker.huck(" Pentagon")

Готово, Америка в шоке :D
 
если найду ответ обязательно поделюсь
меня интересует именно стандартный модуль языка. решение типа такого.

Python:
import os
os.get_local_ip()

к сожалению, мои исследования завершились неудачей. нет такого решения. возможно, в новых версиях языка что-то добавят.

кстати, кто какой версией питона пользуется?

Я на данный момент 3.9. Больше совместимости с разными модулями. А для того, чтобы найти решение, мне кажется, надо покопаться в тех модулях, которые находят ip по имени сетевого интерфейса. К примеру тот же netifaces. Но тогда надо будет покопаться в модулях, которые получают этот дефолтный интерфейс ))

Кстати, одним глазком глянул в getmac. Там они тоже пользуются socket. Не везде, конечно, но пользуют.

если найду ответ обязательно поделюсь
меня интересует именно стандартный модуль языка. решение типа такого.

Python:
import os
os.get_local_ip()

к сожалению, мои исследования завершились неудачей. нет такого решения. возможно, в новых версиях языка что-то добавят.

кстати, кто какой версией питона пользуется?

Залез сейчас в функцию getmac, которая получает сетевой интерфейс по дефолту. Там все довольно просто и интересно:

Python:
data = _read_file("/proc/net/route")
    if data is not None and len(data) > 1:
        for line in data.split("\n")[1:-1]:
            iface_name, dest = line.split("\t")[:2]
            if dest == "00000000":
                return iface_name
    return None

А в описании написано буквально вот что:

Код:
"""Получите интерфейс по умолчанию, прочитав /proc/net/route.

    Это тот же источник, что и команда `route`, однако гораздо быстрее
    быстрее прочитать этот файл, чем вызывать `route`. Если это не удается по какой-либо
    причине, мы можем вернуться к системным командам (например, для платформы.
    которая имеет команду route, но, возможно, не использует /proc?).
    """

Это для Linux соответственно. В Windows такой функции у данной библиотеки нет, почему-то.
То есть, по сути, ничего замудренного. Либо тот же парсинг route, либо чтение из файла.
 
Последнее редактирование:
Интересный вариант) Тогда знаете, есть вариант ещё круче. Предлагаю:

import hucker
hucker.huck(" Pentagon")

Готово, Америка в шоке :D
опять вы ёрничаете. нормально не можете общаться?
это вполне нормальное желание иметь в языке инструменты для работы с сетью. есть же там socket. почему бы не сделать получение локального адреса простым способом?

хотя бы написать обертку для описанных выше способов и включить в состав стандартных модулей.
 
Залез сейчас в функцию getmac, которая получает сетевой интерфейс по дефолту. Там все довольно просто и интересно:

Python:
data = _read_file("/proc/net/route")
    if data is not None and len(data) > 1:
        for line in data.split("\n")[1:-1]:
            iface_name, dest = line.split("\t")[:2]
            if dest == "00000000":
                return iface_name
    return None

А в описании написано буквально вот что:

Код:
"""Получите интерфейс по умолчанию, прочитав /proc/net/route.

    Это тот же источник, что и команда `route`, однако гораздо быстрее
    быстрее прочитать этот файл, чем вызывать `route`. Если это не удается по какой-либо
    причине, мы можем вернуться к системным командам (например, для платформы.
    которая имеет команду route, но, возможно, не использует /proc?).
    """

Это для Linux соответственно. В Windows такой функции у данной библиотеки нет, почему-то.
То есть, по сути, ничего замудренного. Либо тот же парсинг route, либо чтение из файла.

А дальше идет еще одна функция, которая вызывается, если нет интерфейса в файле:

Python:
def _hunt_linux_default_iface():
    # type: () -> Optional[str]
    # NOTE: for now, we check the default interface for WSL using the
    # same methods as POSIX, since those parts of the net stack work fine.
    methods = [
        _get_default_iface_linux,
        lambda: _popen("route", "-n")
        .partition("0.0.0.0")[2]
        .partition("\n")[0]
        .split()[-1],
        lambda: _popen("ip", "route list 0/0")
        .partition("dev")[2]
        .partition("proto")[0]
        .strip(),
    ]
    return _try_methods(methods)

То есть, по сути, если брать за основу эту функцию, чтобы с ее помощью получить имя интерфейса, а уже на этом основании получить IP, то тут нет ничего запредельного. Пользуются парсингом, по сути параметров.
 
А дальше идет еще одна функция, которая вызывается, если нет интерфейса в файле:

Python:
def _hunt_linux_default_iface():
    # type: () -> Optional[str]
    # NOTE: for now, we check the default interface for WSL using the
    # same methods as POSIX, since those parts of the net stack work fine.
    methods = [
        _get_default_iface_linux,
        lambda: _popen("route", "-n")
        .partition("0.0.0.0")[2]
        .partition("\n")[0]
        .split()[-1],
        lambda: _popen("ip", "route list 0/0")
        .partition("dev")[2]
        .partition("proto")[0]
        .strip(),
    ]
    return _try_methods(methods)

То есть, по сути, если брать за основу эту функцию, чтобы с ее помощью получить имя интерфейса, а уже на этом основании получить IP, то тут нет ничего запредельного. Пользуются парсингом, по сути параметров.

А немного дальше еще одна функция, которая, в описании которой сказано, что можно еще получить IP и вот так вот:

Python:
def _fetch_ip_using_dns():
    # type: () -> str
    """Determines the IP address of the default network interface.

    Sends a UDP packet to Cloudflare's DNS (1.1.1.1), which should go through
    the default interface. This populates the source address of the socket,
    which we then inspect and return.
    """
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(("1.1.1.1", 53))
    ip = s.getsockname()[0]
    s.close()  # NOTE: sockets don't have context manager in 2.7 :(
    return ip

Код:
""Определяет IP-адрес сетевого интерфейса по умолчанию.

    Отправляет UDP-пакет на DNS Cloudflare (1.1.1.1), который должен пройти через
    интерфейс по умолчанию. Это содержит адрес источника сокета,
    который мы затем проверяем и возвращаем.
    """

я пару дней назад поставил 3.10.4
добавили много интересного

Это да. Интересного там много, не спорю. Я даже когда начал кодить на питоне, поставил его поначалу. И все было замечательно, пока какой-то из модулей сказал, что надо ему другую версию. А точнее я об этом прочитал, когда в терминале ошибки полетели. Потому пока 3.9
 
Последнее редактирование:
ну, у меня сейчас несколько версий на дебиане. 3,7 по дефолту вызывается командой "python3", а остальные 3.8, 3.9 и 3.10 вызываются "python3.x"
 
опять вы ёрничаете. нормально не можете общаться?
это вполне нормальное желание иметь в языке инструменты для работы с сетью. есть же там socket. почему бы не сделать получение локального адреса простым способом?

хотя бы написать обертку для описанных выше способов и включить в состав стандартных модулей.
Не могу сказать, почему разработчики предпочли сделать именно так. Тот же сокет мог бы быть стандартным модулем, но является расширением. Не надо забывать и то, что сам Пайтон давольно старый язык, на момент создания не была так развита сетевая инфраструктура. В последние годы он стал популярным и начали появляться сторонние библиотеки. Может причина и в том, что на момент создания, работа с сетью не была приоритетом.
 
Не могу сказать, почему разработчики предпочли сделать именно так. Тот же сокет мог бы быть стандартным модулем, но является расширением. Не надо забывать и то, что сам Пайтон давольно старый язык, на момент создания не была так развита сетевая инфраструктура. В последние годы он стал популярным и начали появляться сторонние библиотеки. Может причина и в том, что на момент создания, работа с сетью не была приоритетом.
сокет - это стандартный модуль. его не нужно устанавливать с помощью pip install
также как os, platform, http и т.д.

А немного дальше еще одна функция, которая, в описании которой сказано, что можно еще получить IP и вот так вот:

Python:
def _fetch_ip_using_dns():
    # type: () -> str
    """Determines the IP address of the default network interface.

    Sends a UDP packet to Cloudflare's DNS (1.1.1.1), which should go through
    the default interface. This populates the source address of the socket,
    which we then inspect and return.
    """
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(("1.1.1.1", 53))
    ip = s.getsockname()[0]
    s.close()  # NOTE: sockets don't have context manager in 2.7 :(
    return ip

Код:
""Определяет IP-адрес сетевого интерфейса по умолчанию.

    Отправляет UDP-пакет на DNS Cloudflare (1.1.1.1), который должен пройти через
    интерфейс по умолчанию. Это заполняет адрес источника сокета,
    который мы затем проверяем и возвращаем.
    """
возможно, что-то типа этого добавят в стандартные модули. когда-нибудь
 
сокет - это стандартный модуль. его не нужно устанавливать с помощью pip install
также как os, platform, http и т.д.
Хм, странно, я почему то подумал что он с пип ставиться. Тогда ваш вопрос разве не отпадает автоматом?
Вопрос риторический)
 
Хм, странно, я почему то подумал что он с пип ставиться. Тогда ваш вопрос разве не отпадает автоматом?
Вопрос риторический)

В принципе да. Тот код, что я использовал в скрипте сканирования сети, в принципе и является универсальным для обеих ОС. Вернее не так, для всех ОС, так как будет работать везде одинаково. И более универсален, чем получение IP с помощью DNS Cloudflare, как в getmac. Ну, по крайней мере, по моему скромному мнению.
 
  • Нравится
Реакции: Архонт
@zverb ну я же объяснял, почему этот способ не очень. он выглядит как костыль. ведь можно же написать для самого языка модуль на С который будет работать под капотом с самой ОС и определять айпи средствами ОС
или хотя бы обертку для разных ОС с использованием описанных выше способов. Чтобы было красиво, чтобы не надо было думать, как оно там работает. Это так же как работает например
Код:
os.getcwd()
или типа того
 
@zverb ну я же объяснял, почему этот способ не очень. он выглядит как костыль. ведь можно же написать для самого языка модуль на С который будет работать под капотом с самой ОС и определять айпи средствами ОС
или хотя бы обертку для разных ОС с использованием описанных выше способов. Чтобы было красиво, чтобы не надо было думать, как оно там работает. Это так же как работает например
Код:
os.getcwd()
или типа того

Ну, как идея, это хорошо. Но, очевидно у разработчиков свои мотивы так не делать. Или просто не успели.

ну, у меня сейчас несколько версий на дебиане. 3,7 по дефолту вызывается командой "python3", а остальные 3.8, 3.9 и 3.10 вызываются "python3.x"

Я пользуюсь пока Windows, а все остальное на виртуалках. Почему-то из всего многообразия мне зашел только Mint. Ubuntu, когда то, еще когда была версия 16.04, нравилась. Теперь плакать хочется. Не особо что-то у меня она работает. Кальку ставить на рабочую машину пока желания нет, хоть и хочется попробовать. Если только обеспечить себе, с непривычки, ночку замечательных мгновений... ))) Mint на кодовой базе Debian тоже что-то не зашел. А чистый Debian пока не решаюсь. Мне одно время Free BSD понравилась. Очень уж отзывчивая система )) Но, все же пока винда. Я больше с ней проработал. И не все мне еще в Linux удобно. Хотя, понемногу привыкаю. По функционалу и прочим фишкам линукс-системы мне нравятся больше.

По крайней мере, у них "нескучные обои" :LOL:

Ну, как идея, это хорошо. Но, очевидно у разработчиков свои мотивы так не делать. Или просто не успели.

Хотел глянуть netifaces, но понял, что эта библиотека мне пока не по зубам. Она на C писана, а я в нем пока не в зуб ногой. Так что, тут пока приостановился я )) Но это пока я С не начну учить. Хоть и не скоро, но начну. Вот эту библиотеку можно было бы включить в стандартную комплектацию питона. Вроде бы раньше, до версии 3.7, что ли, в питона даже scapy включена была по умолчанию. Но это не точно. Я просто на форк наткнулся данной библиотеки. И там что-то подобное упоминалось, вроде.
 
Хотел глянуть netifaces, но понял, что эта библиотека мне пока не по зубам. Она на C писана, а я в нем пока не в зуб ногой. Так что, тут пока приостановился я )) Но это пока я С не начну учить. Хоть и не скоро, но начну. Вот эту библиотеку можно было бы включить в стандартную комплектацию питона. Вроде бы раньше, до версии 3.7, что ли, в питона даже scapy включена была по умолчанию. Но это не точно. Я просто на форк наткнулся данной библиотеки. И там что-то подобное упоминалось, вроде.
если не начинал с С и это не универовский предмет, а самостоятельное изучение, возможно стоит начать учить Rust вместо С. Думаю, на нем тоже можно написать модули для питона, но еще и много всего другого
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!