scripts/gestion/iptools.py
Antoine Durand-Gasselin fd7d0849d9 darcs rollback fail
darcs-hash:20090709135112-bd074-6a5ed06a4182b35a02cbcef1baedcefb2a50a546.gz
2009-07-09 15:51:12 +02:00

177 lines
4.8 KiB
Python

#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""
Manipulation d'IPv4
Copyright (C) Frédéric Pauget
Licence : GPLv2
"""
import re
from config import NETs_regexp
# 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 True
return False
def is_crans(ip):
""" Vérifie que l'ip est dans le réseau CRANS
"""
# Pour titanic
if ip == '138.231.136.14' :
return False
if re.match(NETs_regexp['all'], ip):
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])