Python Network/cidr Расчеты

Я работаю над созданием встроенного сетевого устройства (на базе Linux) и столкнулся с необходимостью динамического создания файлов конфигурации демона. Таким образом, мне нужно иметь возможность выполнять некоторые вычисления сетевых адресов в коде Python, который будет создавать файлы conf. Я не программист, поэтому я боюсь, что написал модуль, который не будет работать так, как я надеялся, когда устройство поступит в продажу.

Ниже то, что у меня есть на данный момент, оно действительно собрано вместе с тем, что я смог найти на этом сайте и в Google.

Есть ли лучший способ найти сетевой адрес и cidr для сетевого интерфейса? Преобразование сетевой маски в bin str и подсчет единиц кажется довольно неэлегантным.

import socket
import fcntl
import struct

SIOCGIFNETMASK = 0x891b
SIOCGIFADDR = 0x8915

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

def _GetIfaceMask(iface):
    return struct.unpack('L', fcntl.ioctl(s, SIOCGIFNETMASK, struct.pack('256s', iface))[20:24])[0]

def _GetIfaceAddr(iface):
    return struct.unpack('L', fcntl.ioctl(s, SIOCGIFADDR, struct.pack('256s', iface[:15]))[20:24])[0]

def GetIfaceNet(iface):
    net_addr = _GetIfaceAddr(iface) & _GetIfaceMask(iface)
    return socket.inet_ntoa(struct.pack('L', net_addr))

def GetIfaceCidr(iface):
    bin_str = bin(_GetIfaceMask(iface))[2:]
    cidr = 0
    for c in bin_str:
        if c == '1':  cidr += 1
    return cidr

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


person tMC    schedule 06.02.2011    source источник
comment
Вы пробовали модули netaddr или ipaddr?   -  person jfs    schedule 06.02.2011
comment
Ах! Я подумал, что кто-то, должно быть, уже сделал это - спасибо @sebastian   -  person tMC    schedule 06.02.2011


Ответы (2)


Вы можете проверить модуль Python iptools http://code.google.com/p/python-iptools/ он может конвертировать из длинного в точечный формат ip и наоборот.

person Andrey Kuzmin    schedule 06.02.2011

Это можно решить с помощью алгоритма весов Хэмминга. Украдено из Как подсчитать количество установленных битов в 32-битном целом числе? и перевести на Python:

def number_of_set_bits(x):
    x -= (x >> 1) & 0x55555555
    x = ((x >> 2) & 0x33333333) + (x & 0x33333333)
    x = ((x >> 4) + x) & 0x0f0f0f0f
    x += x >> 8
    x += x >> 16
    return x & 0x0000003f

Другое, более читаемое решение (но работающее в O(log x)):

def number_of_set_bits(x):
    n = 0
    while x:
        n += x & 1
        x = x >> 1
    return n
person deleted77    schedule 06.02.2011
comment
O(log(x)), я думаю; вы перебираете количество битов в x, а не сам x. - person DSM; 06.02.2011