186 lines
4.8 KiB
Python
186 lines
4.8 KiB
Python
|
import socket
|
||
|
import struct
|
||
|
|
||
|
class Interface:
|
||
|
def __init__(self):
|
||
|
self.name = ''
|
||
|
self.ip = ''
|
||
|
self.mask = ''
|
||
|
|
||
|
@property
|
||
|
def broadcast(self):
|
||
|
if self.name == 'FALLBACK': return '<broadcast>'
|
||
|
if not self.ip or not self.mask: return None
|
||
|
return calcBroadcast(self.ip,self.mask)
|
||
|
|
||
|
def getInterfaces():
|
||
|
try:
|
||
|
return _getInterfaces()
|
||
|
except:
|
||
|
pass
|
||
|
|
||
|
try:
|
||
|
return _getInterfacesBSD()
|
||
|
except:
|
||
|
pass
|
||
|
|
||
|
try:
|
||
|
return _getInterfacesWin()
|
||
|
except:
|
||
|
pass
|
||
|
|
||
|
i = Interface()
|
||
|
i.name = 'FALLBACK'
|
||
|
return [i]
|
||
|
|
||
|
def _getInterfaces():
|
||
|
vals = all_interfaces()
|
||
|
interfaces = []
|
||
|
for name,ip in vals:
|
||
|
i = Interface()
|
||
|
i.name = name
|
||
|
i.ip = ip
|
||
|
try:
|
||
|
mask = getSubnetMask(i.name)
|
||
|
i.mask = mask
|
||
|
except:
|
||
|
i.mask = ''
|
||
|
interfaces.append(i)
|
||
|
return interfaces
|
||
|
|
||
|
def _getInterfacesBSD():
|
||
|
#name flags family address netmask
|
||
|
interfaces = []
|
||
|
import getifaddrs
|
||
|
for info in getifaddrs.getifaddrs():
|
||
|
if info.family == 2:
|
||
|
i = Interface()
|
||
|
i.name = info.name
|
||
|
i.ip = info.address
|
||
|
i.mask = info.netmask
|
||
|
interfaces.append(i)
|
||
|
return interfaces
|
||
|
|
||
|
def _getInterfacesWin():
|
||
|
import ipconfig
|
||
|
interfaces = []
|
||
|
adapters = ipconfig.parse()
|
||
|
for a in adapters:
|
||
|
if not 'IPv4 Address' in a: continue
|
||
|
if not 'Subnet Mask' in a: continue
|
||
|
i = Interface()
|
||
|
i.name = a.get('name','UNKNOWN')
|
||
|
i.ip = a['IPv4 Address']
|
||
|
i.mask = a['Subnet Mask']
|
||
|
interfaces.append(i)
|
||
|
return interfaces
|
||
|
|
||
|
def all_interfaces():
|
||
|
import sys
|
||
|
import array
|
||
|
import fcntl
|
||
|
|
||
|
is_64bits = sys.maxsize > 2**32
|
||
|
struct_size = 40 if is_64bits else 32
|
||
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||
|
max_possible = 8 # initial value
|
||
|
while True:
|
||
|
bytes = max_possible * struct_size
|
||
|
names = array.array('B', '\0' * bytes)
|
||
|
outbytes = struct.unpack('iL', fcntl.ioctl(
|
||
|
s.fileno(),
|
||
|
0x8912, # SIOCGIFCONF
|
||
|
struct.pack('iL', bytes, names.buffer_info()[0])
|
||
|
))[0]
|
||
|
if outbytes == bytes:
|
||
|
max_possible *= 2
|
||
|
else:
|
||
|
break
|
||
|
namestr = names.tostring()
|
||
|
return [(namestr[i:i+16].split('\0', 1)[0],
|
||
|
socket.inet_ntoa(namestr[i+20:i+24]))
|
||
|
for i in range(0, outbytes, struct_size)]
|
||
|
|
||
|
def getSubnetMask(name):
|
||
|
import fcntl
|
||
|
return socket.inet_ntoa(fcntl.ioctl(socket.socket(socket.AF_INET, socket.SOCK_DGRAM), 35099, struct.pack('256s', name))[20:24])
|
||
|
|
||
|
def calcIPValue(ipaddr):
|
||
|
"""
|
||
|
Calculates the binary
|
||
|
value of the ip addresse
|
||
|
"""
|
||
|
ipaddr = ipaddr.split('.')
|
||
|
value = 0
|
||
|
for i in range(len(ipaddr)):
|
||
|
value = value | (int(ipaddr[i]) << ( 8*(3-i) ))
|
||
|
return value
|
||
|
|
||
|
def calcIPNotation(value):
|
||
|
"""
|
||
|
Calculates the notation
|
||
|
of the ip addresse given its value
|
||
|
"""
|
||
|
notat = []
|
||
|
for i in range(4):
|
||
|
shift = 255 << ( 8*(3-i) )
|
||
|
part = value & shift
|
||
|
part = part >> ( 8*(3-i) )
|
||
|
notat.append(str(part))
|
||
|
notat = '.'.join(notat)
|
||
|
return notat
|
||
|
|
||
|
def calcSubnet(cidr):
|
||
|
"""
|
||
|
Calculates the Subnet
|
||
|
based on the CIDR
|
||
|
"""
|
||
|
subn = 4294967295 << (32-cidr) # 4294967295 = all bits set to 1
|
||
|
subn = subn % 4294967296 # round it back to be 4 bytes
|
||
|
subn = calcIPNotation(subn)
|
||
|
return subn
|
||
|
|
||
|
def calcCIDR(subnet):
|
||
|
"""
|
||
|
Calculates the CIDR
|
||
|
based on the SUbnet
|
||
|
"""
|
||
|
cidr = 0
|
||
|
subnet = calcIPValue(subnet)
|
||
|
while subnet != 0:
|
||
|
subnet = subnet << 1
|
||
|
subnet = subnet % 4294967296
|
||
|
cidr += 1
|
||
|
return cidr
|
||
|
|
||
|
def calcNetpart(ipaddr,subnet):
|
||
|
ipaddr = calcIPValue(ipaddr)
|
||
|
subnet = calcIPValue(subnet)
|
||
|
netpart = ipaddr & subnet
|
||
|
netpart = calcIPNotation(netpart)
|
||
|
return netpart
|
||
|
|
||
|
def calcMacpart(subnet):
|
||
|
macpart = ~calcIPValue(subnet)
|
||
|
macpart = calcIPNotation(macpart)
|
||
|
return macpart
|
||
|
|
||
|
def calcBroadcast(ipaddr,subnet):
|
||
|
netpart = calcNetpart(ipaddr,subnet)
|
||
|
macpart = calcMacpart(subnet)
|
||
|
netpart = calcIPValue(netpart)
|
||
|
macpart = calcIPValue(macpart)
|
||
|
broadcast = netpart | macpart
|
||
|
broadcast = calcIPNotation(broadcast)
|
||
|
return broadcast
|
||
|
|
||
|
def calcDefaultGate(ipaddr,subnet):
|
||
|
defaultgw = calcNetpart(ipaddr,subnet)
|
||
|
defaultgw = calcIPValue(defaultgw) + 1
|
||
|
defaultgw = calcIPNotation(defaultgw)
|
||
|
return defaultgw
|
||
|
|
||
|
def calcHostNum(subnet):
|
||
|
macpart = calcMacpart(subnet)
|
||
|
hostnum = calcIPValue(macpart) - 1
|
||
|
return hostnum
|