197 lines
5.6 KiB
Python
Executable file
197 lines
5.6 KiB
Python
Executable file
#!/bin/bash /usr/scripts/python.sh
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
Manipulation d'IPv4
|
|
|
|
Copyright (C) Frédéric Pauget
|
|
Licence : GPLv2
|
|
"""
|
|
|
|
import re, netaddr
|
|
from config import NETs_regexp, prefix
|
|
|
|
# Pour accélérer QuadToDec...
|
|
__QuadToDecDone = {}
|
|
|
|
def QuadToDec(ip) :
|
|
"""
|
|
Retourne la représentation décimale d'une ip
|
|
ip est de la forme xxx.xxx.xxx.xxx
|
|
"""
|
|
if ip in __QuadToDecDone:
|
|
return __QuadToDecDone[ip]
|
|
test = ip.split('.')
|
|
if len(test)!=4 : raise ValueError('IP Invalide')
|
|
ip_dec = 0
|
|
for z in range(0,4) :
|
|
n = int(test[z])
|
|
if n<0 or n>255 : raise ValueError('IP Invalide')
|
|
ip_dec += n * ( 256**(3-z) )
|
|
|
|
__QuadToDecDone[ip] = ip_dec
|
|
return ip_dec
|
|
|
|
# Pour accélérer DecToQuad
|
|
__DecToQuadDone = {}
|
|
|
|
def DecToQuad(ip_dec) :
|
|
"""
|
|
Retourne la représentation habituelle d'une ip (xxx.xxx.xxx.xxx)
|
|
ip_dec est l'IP en base 10
|
|
"""
|
|
if ip_dec in __DecToQuadDone:
|
|
return __DecToQuadDone[ip_dec]
|
|
try :
|
|
result = "%d.%d.%d.%d" % ( \
|
|
ip_dec/(256**3) ,
|
|
(ip_dec%(256**3)) / (256**2) ,
|
|
( (ip_dec%(256**3)) % (256**2) ) / 256 ,
|
|
( (ip_dec%(256**3)) % (256**2) ) % 256 )
|
|
__DecToQuadDone[ip_dec] = result
|
|
return result
|
|
except :
|
|
raise ValueError('IP Invalide')
|
|
|
|
__paramDone = {}
|
|
|
|
def param(net, raw=False) :
|
|
"""
|
|
net est un résau fourni sous la forme xxx.xxx.xxx.xxx/yy
|
|
si donnée valide retourne un dictionnaire :
|
|
{ 'network' : xxx.xxx.xxx.xxx ,
|
|
'netmask' : yyy.yyy.yyy.yyy ,
|
|
'broadcast' : zzz.zzz.zzz.zzz }
|
|
sinon retourne {}
|
|
|
|
Si raw = False, alors, on ne convertit pas les résultats sous forme pointée.
|
|
Ils restent sous forme d'un entier.
|
|
"""
|
|
if raw and net in __paramDone:
|
|
return __paramDone[net]
|
|
reseau = {}
|
|
ip, mask = net.split('/')
|
|
|
|
try :
|
|
mask = int(mask)
|
|
dec_ip = QuadToDec(ip)
|
|
if dec_ip == -1 : raise
|
|
except :
|
|
return {}
|
|
|
|
# Calcul du netmask
|
|
non_dec_netmask = netmask(mask, dec=False)
|
|
dec_netmask = netmask(mask)
|
|
|
|
reseau = { 'netmask' : dec_netmask,
|
|
'network' : dec_ip & dec_netmask,
|
|
'broadcast' : dec_ip | non_dec_netmask }
|
|
if not raw:
|
|
for i in reseau.keys():
|
|
reseau[i] = DecToQuad(reseau[i])
|
|
else:
|
|
__paramDone[net] = reseau
|
|
return reseau
|
|
|
|
def AddrInNet(ip,net) :
|
|
"""
|
|
ip est de la forme xxx.xxx.xxx.xxx
|
|
net est de la forme xxx.xxx.xxx.xxx/yy
|
|
net peut être une liste de chaînes ci-dessus
|
|
Retourne True si l'ip est dans un des réseaux.
|
|
Note : retourne False si l'IP est une adresse de réseau ou broadcast
|
|
"""
|
|
if type(net)==str : net = [ net ]
|
|
r = False
|
|
ip = QuadToDec(ip)
|
|
for ne in net :
|
|
n = param(ne, raw=True)
|
|
if ip == n['broadcast'] or ip == n['network'] :
|
|
return False
|
|
r = r or n['netmask'] & ip == n['network']
|
|
|
|
return r
|
|
|
|
def AddrInNets(ip,nets) :
|
|
""" Vérifie si l'ip est au moins dans un des réseaux
|
|
de la liste nets (voir AddrInNet) """
|
|
for net in nets :
|
|
if AddrInNet(ip,net) :
|
|
return net
|
|
return ''
|
|
|
|
def NetInNet(net1, net2) :
|
|
"""
|
|
net1 est de la forme xxx.xxx.xxx.xxx/yy
|
|
net2 est de la forme xxx.xxx.xxx.xxx/yy
|
|
Retourne True si net1 est un sous-réseaux de net2
|
|
"""
|
|
n1 = param(net1, raw=True)
|
|
n2 = param(net2, raw=True)
|
|
s1 = net1.split('/')[1]
|
|
s2 = net1.split('/')[1]
|
|
return s1<=s2 and (n1['network'] == n2['network'] or AddrInNet(DecToQuad(n1['network']), net2))
|
|
|
|
def NetInNets(net1, nets):
|
|
""" Vérifie si le premier paramètre est un sous-réseau des réseaux de la liste du second paramètre"""
|
|
for net in nets:
|
|
if NetInNet(net1, net) :
|
|
return net
|
|
return ''
|
|
|
|
def is_crans(ip):
|
|
""" Vérifie que l'ip est dans le réseau CRANS
|
|
"""
|
|
# Pour titanic
|
|
ip = netaddr.IPAddress(ip)
|
|
if str(ip) in [ '138.231.136.14', '2a01:240:fe3d:4:a873:65ff:fe63:6f75']:
|
|
return False
|
|
if re.match(NETs_regexp['all'], str(ip)) or ip in netaddr.IPNetwork(prefix['subnet'][0]):
|
|
return True
|
|
return False
|
|
|
|
def netmask(mask, dec=True) :
|
|
""" On génère le sous réseau /bits
|
|
"""
|
|
non_dec_netmask = (1L<<(32-mask)) - 1
|
|
dec_netmask = (1L<<32) - 1 - non_dec_netmask
|
|
if dec :
|
|
return dec_netmask
|
|
else :
|
|
return non_dec_netmask
|
|
|
|
def IpSubnet(ip, mask) :
|
|
dec_mask = netmask(mask)
|
|
dec_ip = QuadToDec(ip)
|
|
start_ip = DecToQuad(dec_ip & dec_mask)
|
|
subnet = start_ip + "/%s" % mask
|
|
return subnet
|
|
|
|
def NetSubnets(net, subnet_mask) :
|
|
""" On construit une liste des sous réseaux /subnet_mask
|
|
compris dans le sous réseau /mask comprenant l'ip ip
|
|
"""
|
|
subnets = []
|
|
# On récupère une ip du réseau indiqué
|
|
ip = net.split('/')[0]
|
|
# On récupère la valeur du masque
|
|
mask = int(net.split('/')[1])
|
|
# On transforme les valeurs d'entrées en valeurs décimales
|
|
# On définit la valeur du sous réseau initial
|
|
dec_netmask = netmask(mask)
|
|
dec_ip = QuadToDec(ip)
|
|
dec_subnet_netmask = netmask(subnet_mask)
|
|
# On calcule la première ip du sous réseau indiqué
|
|
start_ip = dec_ip & dec_netmask
|
|
seq_ip = start_ip
|
|
# On fait une itération sur toutes les ip du sous réseau
|
|
while (seq_ip & dec_netmask) == start_ip:
|
|
# On récupère le sous réseau de la taille demandée
|
|
subnet = DecToQuad(seq_ip & dec_subnet_netmask) + "/%s" % subnet_mask
|
|
if not subnets.count(subnet) :
|
|
subnets.append(subnet)
|
|
seq_ip += 1
|
|
return subnets
|
|
|
|
if __name__ == '__main__' :
|
|
import sys
|
|
print param(sys.argv[1])
|