|
|
|
#-*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
# Copyright 2008-2010 Calculate Ltd. http://www.calculate-linux.org
|
|
|
|
#
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
|
# You may obtain a copy of the License at
|
|
|
|
#
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
#
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
# See the License for the specific language governing permissions and
|
|
|
|
# limitations under the License.
|
|
|
|
|
|
|
|
import math
|
|
|
|
from cl_utils import process, checkUtils, readFile, listDirectory, \
|
|
|
|
readLinesFile, getRunCommands
|
|
|
|
import sys
|
|
|
|
import re
|
|
|
|
from os import path
|
|
|
|
|
|
|
|
import cl_lang
|
|
|
|
tr = cl_lang.lang()
|
|
|
|
tr.setLocalDomain('cl_lib')
|
|
|
|
tr.setLanguage(sys.modules[__name__])
|
|
|
|
|
|
|
|
# ip digit from 0|1-255|254 (template)
|
|
|
|
IP_DIG = "[%s-9]|(?:1[0-9]|[1-9])[0-9]|2[0-4][0-9]|25[0-%s]"
|
|
|
|
# ip net 0-32
|
|
|
|
IP_NET_SUFFIX = "[0-9]|[12][0-9]|3[012]"
|
|
|
|
# ip digs 1-254,0-254,0-255
|
|
|
|
IP_DIGS = { 'dig1_254' : IP_DIG % (1,4), 'dig0_254' : IP_DIG % (0,4),
|
|
|
|
'dig0_255' : IP_DIG % (0,5), }
|
|
|
|
# ip addr 10.0.0.12
|
|
|
|
IP_ADDR = "(%(dig1_254)s)\.(%(dig0_254)s)\.(%(dig0_254)s)\.(%(dig1_254)s)"%\
|
|
|
|
IP_DIGS
|
|
|
|
IP_MASK = "(%(dig0_255)s)\.(%(dig0_255)s)\.(%(dig0_255)s)\.(%(dig0_255)s)"%\
|
|
|
|
IP_DIGS
|
|
|
|
# ip addr for net 10.0.0.0
|
|
|
|
IP_NET = "(%(dig1_254)s)\.(%(dig0_254)s)\.(%(dig0_254)s)\.(%(dig0_254)s)"%\
|
|
|
|
IP_DIGS
|
|
|
|
# ip and net 192.168.0.0/16
|
|
|
|
IP_ADDR_NET = "(%(ipaddr)s)/((%(ipnet)s))"%{'ipaddr':IP_NET,
|
|
|
|
'ipnet':IP_NET_SUFFIX}
|
|
|
|
|
|
|
|
reIp = re.compile("^{0}$".format(IP_ADDR))
|
|
|
|
reNetSuffix = re.compile("^{0}$".format(IP_NET_SUFFIX))
|
|
|
|
reNet = re.compile("^{0}$".format(IP_ADDR_NET))
|
|
|
|
reMask = re.compile("^{0}$".format(IP_MASK))
|
|
|
|
|
|
|
|
def checkIp(ip):
|
|
|
|
"""Check ip"""
|
|
|
|
return reIp.match(ip)
|
|
|
|
|
|
|
|
def checkNetSuffix(netSuffix):
|
|
|
|
"""Check net suffix"""
|
|
|
|
return reNetSuffix.match(netSuffix)
|
|
|
|
|
|
|
|
def checkNet(net):
|
|
|
|
"""Check net"""
|
|
|
|
if not reNet.match(net):
|
|
|
|
return False
|
|
|
|
ip,op,cidr = net.partition('/')
|
|
|
|
mask = strIpToIntIp(cidrToMask(int(cidr)))
|
|
|
|
return (strIpToIntIp(ip)&mask) == (strIpToIntIp(ip))
|
|
|
|
|
|
|
|
maskDigs = map(lambda x:str(x),(0b10000000,0b11000000,0b11100000,0b11110000,
|
|
|
|
0b11111000,0b11111100,0b11111110,0b11111111))
|
|
|
|
|
|
|
|
def checkMask(mask):
|
|
|
|
"""Check net"""
|
|
|
|
if mask.count('.') != 3:
|
|
|
|
return False
|
|
|
|
zero = False
|
|
|
|
for dig in mask.split('.'):
|
|
|
|
if zero or not dig in maskDigs:
|
|
|
|
if dig == "0":
|
|
|
|
zero = True
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
|
|
def getIpAndMask(interface="eth0"):
|
|
|
|
"""Get ip and mask from interface"""
|
|
|
|
ipconfigProg = checkUtils('/sbin/ifconfig')
|
|
|
|
ifconfig = process(ipconfigProg,interface)
|
|
|
|
res = re.search(r"inet(?: addr:| )(\S+)\s.*(?:Mask:|netmask )(\S+)",
|
|
|
|
ifconfig.read(),re.S)
|
|
|
|
if res:
|
|
|
|
return res.groups()
|
|
|
|
else:
|
|
|
|
return ("","")
|
|
|
|
|
|
|
|
def strIpToIntIp(addr):
|
|
|
|
"""Convert ip specified by string to integer"""
|
|
|
|
addr = addr.split('.')
|
|
|
|
return ((int(addr[0])<<24)|
|
|
|
|
(int(addr[1])<<16)|
|
|
|
|
(int(addr[2])<<8)|
|
|
|
|
(int(addr[3])))
|
|
|
|
return reduce(lambda x,y:x+(int(y[1])<<(y[0]*8)),
|
|
|
|
enumerate(reversed(addr.split("."))),0)
|
|
|
|
|
|
|
|
def intIpToStrIp(addr):
|
|
|
|
"""Convert ip specified by integer to string"""
|
|
|
|
return "{0}.{1}.{2}.{3}".format(
|
|
|
|
addr>>24,(addr>>16)&0xff,(addr>>8)&0xff,addr&0xff)
|
|
|
|
|
|
|
|
def maskToCidr(mask):
|
|
|
|
"""Convert mask specified by str to net"""
|
|
|
|
mask = strIpToIntIp(mask)
|
|
|
|
return 32-int(math.log(((~mask) & 0xffffffff)+1,2))
|
|
|
|
|
|
|
|
def cidrToMask(cidr):
|
|
|
|
"""Convert net to mask specified by str"""
|
|
|
|
return intIpToStrIp((2**cidr-1)<<(32-cidr))
|
|
|
|
|
|
|
|
def getIpNet(ip,mask=None,cidr=None):
|
|
|
|
"""Get net (xx.xx.xx.xx/xx) by ip address and mask"""
|
|
|
|
ip = strIpToIntIp(ip)
|
|
|
|
if not mask is None:
|
|
|
|
net = maskToCidr(mask)
|
|
|
|
else:
|
|
|
|
net = int(cidr)
|
|
|
|
mask = cidrToMask(net)
|
|
|
|
mask = strIpToIntIp(mask)
|
|
|
|
return "{ip}/{net}".format(ip=intIpToStrIp(ip&mask),
|
|
|
|
net=net)
|
|
|
|
|
|
|
|
def isIpInNet(checkip,*ipnets):
|
|
|
|
"""Check is ip in specified nets"""
|
|
|
|
return map(lambda x:x[0],
|
|
|
|
filter(lambda x:strIpToIntIp(checkip)&x[2] == strIpToIntIp(x[1])&x[2],
|
|
|
|
map(lambda x:(x[0],x[1][0],strIpToIntIp(cidrToMask(int(x[1][1])))),
|
|
|
|
map(lambda x:(x,x.partition('/')[0::2]),
|
|
|
|
ipnets))))
|
|
|
|
|
|
|
|
def receiveMac(interface="eth0"):
|
|
|
|
"""Get MAC from interface"""
|
|
|
|
ipconfigProg = checkUtils('/sbin/ifconfig')
|
|
|
|
ifconfig = process(ipconfigProg,interface)
|
|
|
|
res = re.search(r"(?:HWaddr|ether)\s(\S+)",ifconfig.read(),re.S)
|
|
|
|
if res:
|
|
|
|
return res.group(1)
|
|
|
|
else:
|
|
|
|
return "00:00:00:00:00:00"
|
|
|
|
|
|
|
|
def receiveIpAndMask(interface="eth0"):
|
|
|
|
"""Get ip and mask from interface"""
|
|
|
|
ipconfigProg = checkUtils('/sbin/ifconfig')
|
|
|
|
ifconfig = process(ipconfigProg,interface)
|
|
|
|
res = re.search(r"inet(?: addr:| )(\S+)\s.*(?:Mask:|netmask )(\S+)",
|
|
|
|
ifconfig.read(),re.S)
|
|
|
|
if res:
|
|
|
|
return res.groups()
|
|
|
|
else:
|
|
|
|
return ("","")
|
|
|
|
|
|
|
|
def isDhcpIp(interface="eth0"):
|
|
|
|
"""Get ip by dhcp or static"""
|
|
|
|
# dhclient
|
|
|
|
if filter(lambda x:interface in x and ("dhcpcd" in x or "dhclient" in x),
|
|
|
|
getRunCommands()):
|
|
|
|
return True
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
|
|
|
|
def getRouteTable(onlyIface=[]):
|
|
|
|
"""Get route table, exclude specifed iface"""
|
|
|
|
ipProg = checkUtils('/sbin/ip')
|
|
|
|
routes = process(ipProg,"route")
|
|
|
|
if onlyIface:
|
|
|
|
filterRe = re.compile("|".join(map(lambda x:r"dev %s"%x,onlyIface)))
|
|
|
|
routes = filter(filterRe.search,routes)
|
|
|
|
for line in routes:
|
|
|
|
network,op,line = line.partition(" ")
|
|
|
|
routeParams = map(lambda x:x.strip(),line.split())
|
|
|
|
# (network,{'via':value,'dev':value})
|
|
|
|
if network:
|
|
|
|
yield (network,dict(zip(routeParams[0::2],routeParams[1::2])))
|
|
|
|
|
|
|
|
def getInterfaces():
|
|
|
|
"""Get available interfaces (discard which hasn't device)"""
|
|
|
|
sysNet = "/sys/class/net"
|
|
|
|
return filter(lambda x:path.exists(path.join(sysNet,x,"device")),
|
|
|
|
listDirectory(sysNet))
|