Как назначить IP-адрес интерфейсу в python?

у меня есть скрипт python, который устанавливает ip4-адрес для моих беспроводных и проводных интерфейсов. До сих пор я использую как :

subprocess.call(["ip addr add local 192.168.1.2/24 broadcast 192.168.1.255 dev wlan0"])

Как я могу установить ip4-адрес интерфейса с помощью библиотек python? и если есть какой-либо способ получить уже существующие конфигурации IP с помощью библиотек python ?

3 ответов


установить адрес через старый ioctl интерфейс:

import socket, struct, fcntl

SIOCSIFADDR = 0x8916
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


def setIpAddr(iface, ip):
    bin_ip = socket.inet_aton(ip)
    ifreq = struct.pack('16sH2s4s8s', iface, socket.AF_INET, '\x00' * 2, bin_ip, '\x00' * 8)
    fcntl.ioctl(sock, SIOCSIFADDR, ifreq)


setIpAddr('em1', '192.168.0.1')

(настройка маски сети выполняется с помощью SIOCSIFNETMASK = 0x891C)

IP-адреса могут быть получены таким же образом: поиск локальных IP-адресов с помощью stdlib Python

Я считаю, что есть реализация python Netlink, если вы хотите использовать это над ioctl


С pyroute2.IPRoute:

from pyroute2 import IPRoute
ip = IPRoute()
index = ip.link_lookup(ifname='em1')[0]
ip.addr('add', index, address='192.168.0.1', mask=24)
ip.close()

С pyroute2.Ipdb все:

from pyroute2 import IPDB
ip = IPDB()
with ip.interfaces.em1 as em1:
    em1.add_ip('192.168.0.1/24')
ip.release()

У вас есть несколько вариантов, чтобы сделать это из вашей программы python.

можно использовать Как вы показали. Хотя это не лучший вариант вообще, это обычно делает работу, будучи немного медленным и arkward для программирования.

другим способом было бы сделать вещи ip делает самостоятельно, используя интерфейс netlink ядра напрямую. Я знаю это libnl есть некоторые экспериментальные (?) привязки python. Это может сработать, но вам придется иметь дело со многими вещами низкого уровня. Я бы не рекомендовал этот способ для простого "набора и получения" ips, но это самый "правильный" и надежный способ сделать это.

лучшим способом, на мой взгляд (если вы хотите только установить и получить ips), было бы использовать интерфейс dbus NetworkManagers. Хотя это очень ограничено и может иметь свои собственные проблемы (это может вести себя не так, как вы хотели бы), это самый прямой путь, если NetworkManager работает в любом случае.

Итак, выбирайте the libnl подход если вы хотите, чтобы ваши руки грязные, это явно превосходит, но и способ больше работы. Вы также можете уйти с помощью dbus интерфейс, в зависимости от ваших потребностей и общей настройки системы. Иначе вы можете просто оставить все как есть.