|
##############################################################################
|
|
# -*- coding: utf-8 -*-
|
|
# Project: Controlaula
|
|
# Module: NetworkUtils.py
|
|
# Purpose: Several network utilities to be used in Python
|
|
# Language: Python 2.5
|
|
# Date: 17-Jan-2010.
|
|
# Ver: 17-Jan-2010.
|
|
# Author: José L. Redrejo Rodríguez
|
|
# Copyright: 2009 - José L. Redrejo Rodríguez <jredrejo @nospam@ debian.org>
|
|
#
|
|
# ControlAula is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
# ControlAula is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with ControlAula. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
##############################################################################
|
|
|
|
|
|
import array,fcntl,socket,struct,os,re
|
|
import logging,subprocess
|
|
|
|
gateway='0'
|
|
ltspGateway='0'
|
|
essid=''
|
|
bssid=''
|
|
IFNAMSIZE = 16
|
|
IW_ESSID_MAX_SIZE = 16
|
|
SIOCGIWESSID = 0x8B1B
|
|
SIOCGIWAP = 0x8B15
|
|
|
|
def get_ip_address(ifname):
|
|
"""Returns the ip address of the interface ifname"""
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
try:
|
|
ip= socket.inet_ntoa(fcntl.ioctl(
|
|
s.fileno(),
|
|
0x8915, # SIOCGIFADDR
|
|
struct.pack('256s', ifname[:15]) )[20:24]
|
|
)
|
|
except:
|
|
ip=''
|
|
return ip
|
|
|
|
def get_ip_inet_address(connection_ip='198.41.0.4'):
|
|
"""Returns the ip address of the interface used to connect to the given ip
|
|
|
|
198.41.0.4 is a DNS ROOT Server, so it's the default value to connect to Internet
|
|
"""
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
try:
|
|
s.connect((connection_ip, 0))
|
|
inet_address= s.getsockname()[0]
|
|
except:
|
|
inet_address=''
|
|
s.close()
|
|
logging.getLogger().debug("Inet Address:" + inet_address)
|
|
return inet_address
|
|
|
|
|
|
def get_inet_HwAddr(connection_ip='192.168.0.254'):
|
|
"""Returns the mac address of the interface used to connect to the given ip"""
|
|
interfaces=all_interfaces()
|
|
rightIP=get_ip_inet_address(connection_ip)
|
|
mac=''
|
|
ifname=''
|
|
for i in interfaces:
|
|
if rightIP== get_ip_address(i[0]):
|
|
ifname=i[0]
|
|
break
|
|
if ifname !='':
|
|
mac=get_HwAddr(ifname)
|
|
|
|
return mac
|
|
|
|
|
|
|
|
def get_HwAddr(ifname):
|
|
"""Returns the mac of the ifname network card"""
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
info = fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', ifname[:15]))
|
|
try:
|
|
mac= ''.join(['%02x:' % ord(char) for char in info[18:24]])[:-1]
|
|
except:
|
|
mac=''
|
|
|
|
return mac
|
|
|
|
|
|
def getWirelessNICnames():
|
|
""" return list of wireless device names """
|
|
device = re.compile('[a-z]{3,4}[0-9]')
|
|
ifnames = []
|
|
|
|
f = open('/proc/net/wireless', 'r')
|
|
data = f.readlines()
|
|
for line in data:
|
|
try:
|
|
ifnames.append(device.search(line).group())
|
|
except AttributeError:
|
|
pass
|
|
|
|
return ifnames
|
|
|
|
|
|
def all_interfaces():
|
|
"""Returns all the available network interfaces in a linux machine"""
|
|
max_possible = 128 # arbitrary. raise if needed.
|
|
bytes = max_possible * 32
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
names = array.array('B', '\0' * bytes)
|
|
outbytes = struct.unpack('iL', fcntl.ioctl( s.fileno(), 0x8912, struct.pack('iL', bytes, names.buffer_info()[0]) ))[0]
|
|
namestr = names.tostring()
|
|
#return [namestr[i:i+32].split('\0', 1)[0] for i in range(0, outbytes, 32)]
|
|
lst = []
|
|
arch64=(os.uname()[4]=='x86_64')
|
|
if arch64:
|
|
totalStruct=40
|
|
else:
|
|
totalStruct=32
|
|
for i in range(0, outbytes, totalStruct):
|
|
if arch64:
|
|
name = namestr[i:i+16].split('\0', 1)[0]
|
|
else:
|
|
name = namestr[i:i+32].split('\0', 1)[0]
|
|
ip = namestr[i+20:i+24]
|
|
lst.append((name, socket.inet_ntoa(ip)))
|
|
|
|
|
|
return lst
|
|
|
|
def getESSID( ifname):
|
|
|
|
sockfd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
essid = ""
|
|
|
|
buff = array.array('c', '\0'*32)
|
|
caddr_t, length = buff.buffer_info()
|
|
s = struct.pack('Pi', caddr_t, length)
|
|
|
|
buff2 = IFNAMSIZE-len(ifname)
|
|
ifreq = ifname + '\0'*buff2
|
|
ifreq = ifreq + s
|
|
try:
|
|
result = fcntl.ioctl(sockfd.fileno(), SIOCGIWESSID, ifreq)
|
|
i=0
|
|
result=result[16:]
|
|
except IOError, (i, e):
|
|
i=i
|
|
result=e
|
|
|
|
if i > 0:
|
|
return (i, result)
|
|
str = buff.tostring()
|
|
return (0,str.strip('\x00'))
|
|
|
|
|
|
def getHostName():
|
|
return socket.gethostname()
|
|
|
|
def getFreeTCPPort():
|
|
"""Returns a random free port provided by the Operative System"""
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
sock.bind(('localhost', 0))
|
|
newPort= sock.getsockname()[1]
|
|
sock.close()
|
|
return newPort
|
|
|
|
|
|
def getWirelessData():
|
|
global essid
|
|
global bssid
|
|
wifiNICs=getWirelessNICnames()
|
|
if len(wifiNICs)>0:
|
|
for i in wifiNICs:
|
|
value,nessid=getESSID(i)
|
|
if value==0:
|
|
essid=nessid
|
|
value2,nbssid=getAPaddr(i)
|
|
if value2==0:
|
|
bssid=nbssid
|
|
|
|
def getAPaddr(ifname):
|
|
sockfd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
|
|
buff = array.array('c', '\0'*32)
|
|
caddr_t, length = buff.buffer_info()
|
|
s = struct.pack('Pi', caddr_t, length)
|
|
|
|
|
|
buff2 = IFNAMSIZE-len(ifname)
|
|
ifreq = ifname + '\0'*buff2
|
|
ifreq = ifreq + s
|
|
try:
|
|
result = fcntl.ioctl(sockfd.fileno(), SIOCGIWAP, ifreq)
|
|
i=0
|
|
result=result[16:]
|
|
except IOError, (i, e):
|
|
i=i
|
|
result=e
|
|
|
|
|
|
if i > 0:
|
|
return (i, result)
|
|
else:
|
|
mac_addr = struct.unpack('xxBBBBBB',result[:8])
|
|
return (0,"%02X:%02X:%02X:%02X:%02X:%02X" % mac_addr)
|
|
|
|
def scan_server(address, port):
|
|
"""Returns true if a port is open at address, or false otherwise"""
|
|
s = socket.socket()
|
|
#print "Attempting to connect to %s on port %s." %(address, port)
|
|
try:
|
|
s.connect((address, port))
|
|
#print "Connected to server %s on port %s." %(address, port)
|
|
s.close()
|
|
return True
|
|
except socket.error, e:
|
|
logging.getLogger().debug("Connecting to %s on port %s failed with the following error: %s" %(address, port, e))
|
|
return False
|
|
|
|
|
|
def getUsableTCPPort(address,port):
|
|
"""Returns the first free port between port and port +10"""
|
|
freeport=port
|
|
for x in range(port,port+10):
|
|
check = scan_server(address, x)
|
|
if check==False :
|
|
freeport=x
|
|
break
|
|
|
|
|
|
return freeport
|
|
|
|
|
|
def startup(address):
|
|
|
|
addr_byte = address.split(':')
|
|
hw_addr = struct.pack('BBBBBB', int(addr_byte[0], 16),
|
|
int(addr_byte[1], 16),
|
|
int(addr_byte[2], 16),
|
|
int(addr_byte[3], 16),
|
|
int(addr_byte[4], 16),
|
|
int(addr_byte[5], 16))
|
|
|
|
msg = '\xff' * 6 + hw_addr * 16
|
|
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
|
try:
|
|
s.sendto(msg, ('<broadcast>', 9))
|
|
s.sendto(msg, ('<broadcast>', 7))
|
|
s.sendto(msg, ('192.168.0.255', 9))
|
|
s.sendto(msg, ('192.168.0.255', 7))
|
|
except:
|
|
s.sendto(msg, ('<broadcast>', 2000))
|
|
s.sendto(msg, ('192.168.0.255', 2000))
|
|
s.close()
|
|
|
|
def defaultGW():
|
|
global gateway
|
|
if gateway=='0':
|
|
try:
|
|
s=subprocess.Popen('/sbin/route -n|grep "0.0.0.0"|grep UG',shell=True,stdout=subprocess.PIPE).communicate()[0]
|
|
gateway=s.splitlines()[0].split()[1]
|
|
except:
|
|
gateway='0'
|
|
return gateway
|
|
|
|
def ltspGW():
|
|
global ltspGateway
|
|
if ltspGateway=='0':
|
|
try:
|
|
externalIP=get_ip_inet_address()
|
|
internalIP=get_ip_inet_address('192.168.0.2')
|
|
|
|
if externalIP==internalIP or externalIP=='':
|
|
ltspGateway=defaultGW()
|
|
else:
|
|
ltspGateway=internalIP
|
|
except:
|
|
ltspGateway='0'
|
|
return ltspGateway
|
|
|
|
def cleanRoutes():
|
|
s=subprocess.Popen(['route','-n'],stdout=subprocess.PIPE).communicate()[0]
|
|
l=s.splitlines()
|
|
for route in l:
|
|
target=route.split()[0]
|
|
if target[:4]=='239.':
|
|
subprocess.Popen(['route','del','-net',target + '/24'])
|
|
|
|
def addRoute(net,gw=''):
|
|
if gw=='':
|
|
newgw=defaultGW()
|
|
else:
|
|
newgw=gw
|
|
subprocess.Popen(['route','add','-net',net+ '/24','gw',newgw])
|