1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
|
from pox.core import core
import pox.openflow.libopenflow_01 as of
from pox.lib.util import dpid_to_str
from pox.lib.util import str_to_bool
from pox.lib.addresses import EthAddr
from pox.lib.addresses import IPAddr
from pox.lib.packet.ethernet import ethernet
import time
import re
import sys
import os
log = core.getLogger()
# Lorsque le switch est connecte,On ne va pas innonder le paquet immidiatement
delai = 0
global src
class SystemeDetection (object):
def __init__ (self, connection, transparent):
# Gardez une trace de la connexion pour que le switch communique avc le controleur
self.connection = connection
self.transparent = transparent
# La table de conversion de l'adresse mac au port dest
self.macToPort = {}
# Ecouter les message In
connection.addListeners(self)
# Quand enregistrer un message utile
self.hold_down_expired = delai == 0
log.debug("Initialiser le Systemedetection, transparent=%s", str(self.transparent))
# quand un commutateur contacte le controleur lorsqu il recoit un paque auquel il n a pas d entrees dans sa table
def _handle_PacketIn (self, event):
"""
Traitement des paquets
"""
#Analyser le paquet d'entree
packet = event.parsed
if not packet.parsed:
log.warning("Ingnorer ce paquet")
return
def innonder (message = None):
""" innonder le packet """
# le controleur cree un msg paquet out
msg = of.ofp_packet_out()
if time.time() - self.connection.connect_time >= delai:
# innonder apres un moment
if self.hold_down_expired is False:
self.hold_down_expired = True
if message is not None: log.debug(message)
#log.debug("%i: innonder %s -> %s", event.dpid,packet.src,packet.dst)
# OFPP_FLOOD si on a un seul switch sinon OFPP_ALL.
msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL))
else:
pass
#log.info("Innondation pour %s", dpid_to_str(event.dpid))
msg.data = event.ofp
msg.in_port = event.port
self.connection.send(msg)
def Supprimer (duration = None):
"""
Supprime ce paquet et installe eventuellement un flux pr continuer a supp les paquets similaire
"""
if duration is not None:
if not isinstance(duration, tuple):
duration = (duration,duration)
msg = of.ofp_flow_mod()
msg.match = of.ofp_match.from_packet(packet)
msg.idle_timeout = duration[0]
msg.hard_timeout = duration[1]
msg.buffer_id = event.ofp.buffer_id
self.connection.send(msg)
elif event.ofp.buffer_id is not None:
msg = of.ofp_packet_out()
msg.buffer_id = event.ofp.buffer_id
msg.in_port = event.port
self.connection.send(msg) #
self.macToPort[packet.src] = event.port # utiliser l@ src, port swi pr mettre a jour
if not self.transparent: # si trasparent=faux et le type de paquet est ethertype(LLDP)ou L adresse de destination est-elle une adresse filtree de pont?
if packet.type == packet.LLDP_TYPE or packet.dst.isBridgeFiltered() :
supprimer() # supp le paquet
return
if packet.dst.is_multicast:
innonder() # innonder le paquet
else:
if packet.dst not in self.macToPort: # si l adresse mac dest n est dans la table de conversion (adresse / port)
innonder("Port de %s Non reconnu -- innondation" % (packet.dst,))
else:
port = self.macToPort[packet.dst]
if port == event.port: # port de sortie = port darriver
# supprimer dans situation similaire
log.warning("Le meme port pour le paquet de %s -> %s dans %s.%s. Supprimer."
% (packet.src, packet.dst, dpid_to_str(event.dpid), port))
supprimer(10)
return
# instaler les flux et creer un msg flowmod
log.debug("installation des flux pour %s.%i -> %s.%i" % (packet.src, event.port, packet.dst, port))
msg = of.ofp_flow_mod()
# la methode "ofp_match.from_packet" elle cree des champs de correspondance avec des donnees copiees a partir de champs de paquets
msg.match = of.ofp_match.from_packet(packet, event.port)
#analyse
myfile = open("/home/mininet/pox/ext/signature.txt", "r")
for line in myfile.readlines():
res = re.search('^rule\s*=\s*[\'\"](.+?)\s*[\'\"]\s*$', line)
if res :
# chercher par groupe
header = res.group(1)
#print (header)
# convertit la chaine en sous chaine, sep=vide
headers = header.split()
#print(headers)
rule = {
'action':headers[0],
'protocol':headers[1],
'srcaddresses':headers[2],
'srcports':headers[3],
'direction':headers[4],
'dstaddresses':headers[5],
'dstports':headers[6],
}
if headers[1] == 'icmp':
p_code = 1
elif headers[1] == 'tcp':
p_code = 6
elif headers[1] == 'udp':
p_code = 17
if msg.match.dl_type == 0x0800 and msg.match.nw_proto == p_code and msg.match.nw_src == headers[2] and msg.match.nw_dst == headers[5]:
print("*********************************** ALERTE *************************************")
print("**************************** - UN PAQUET SUSPECT - *****************************")
print "* - Source:"+str(msg.match.nw_src )
print "* - Destination:" +str(msg.match.nw_dst)
print("********************************** ALERTE **************************************")
print("********************************************************************************")
with open ('outfile.log',"a") as a :
b = time.strftime('Date %D Heure %H:%M.',time.localtime())
a.write(b)
a.write("protocole : %s, source : %s, destination : %s, port-source : %s, port-destination : %s \n" % (msg.match.nw_proto ,msg.match.nw_src ,msg.match.nw_dst, msg.match.tp_src, msg.match.tp_dst))
a.close()
/////////////////////// le probléme est la ///////////////////////////////
# ofp_match : decrire les champs dentetes d un paquet correspond
match = of.ofp_match()
# creer une entete de coresspondance avec l adresse src
match.nw_src = src
# Construire un msg FLOW MOD pour modifier le flux
msg = of.ofp_flow_mod()
msg.match = match
# envoyer le msg au switch
event.connection.send(msg)
msg.idle_timeout = 10 # nb de seconde # pas de delai dinondation
msg.hard_timeout = 30 # nb de seconde # pas de delai dattente
msg.actions.append(of.ofp_action_output(port = port)) # ajouter une action a envoyer(ou tu dois acheminer ce paquet)
msg.data = event.ofp #
self.connection.send(msg)# envoyer le msg au switch
class ids (object):
def __init__ (self, transparent):
# enregistrer la classe ids dans of et ecouter plusieurs events dans lobjet openflow
core.openflow.addListeners(self)
self.transparent = transparent
# etablir la conexion de switch
def _handle_ConnectionUp (self, event):
log.debug("Connection %s, Switch %s" % (event.connection,event.dpid))
SystemeDetection(event.connection, self.transparent)
def launch (transparent=False, hold_down=delai):
"""
commencer le pg ids
"""
try:
global delai
delai = int(str(hold_down), 10)
assert delai >= 0
except:
raise RuntimeError("Exception hold-down est un nombre entier")
core.registerNew(ids, str_to_bool(transparent)) |
Partager