def parse(self, raw): assert isinstance(raw, bytes) self.raw = raw dlen = len(raw) if dlen < arp.MIN_LEN: self.msg("(arp parse) warning IP packet data too short to parse header: data len %u" % dlen) return (self.hwtype, self.prototype, self.hwlen, self.protolen, self.opcode) = struct.unpack("!HHBBH", raw[:8]) if self.hwtype != arp.HW_TYPE_ETHERNET: self.msg("(arp parse) hw type unknown %u" % self.hwtype) if self.hwlen != 6: self.msg("(arp parse) unknown hw len %u" % self.hwlen) else: self.hwsrc = EthAddr(raw[8:14]) self.hwdst = EthAddr(raw[18:24]) if self.prototype != arp.PROTO_TYPE_IP: self.msg("(arp parse) proto type unknown %u" % self.prototype) if self.protolen != 4: self.msg("(arp parse) unknown proto len %u" % self.protolen) else: self.protosrc = IPAddr(struct.unpack("!I", raw[14:18])[0]) self.protodst = IPAddr(struct.unpack("!I", raw[24:28])[0]) self.next = raw[28:] self.parsed = True
def _findSwitchNameAndNetworkOfDest(self, destIp): dest = IPAddr(destIp) ans = [] for entry in self.routingTable: if dest.inNetwork(entry.network): ans.append( (entry.name, entry.network) ) return ans
def parse(self, raw): assert isinstance(raw, bytes) self.next = None # In case of unfinished parsing self.raw = raw dlen = len(raw) if dlen < ipv4.MIN_LEN: self.msg('warning IP packet data too short to parse header: data len %u' % (dlen,)) return (vhl, self.tos, self.iplen, self.id, self.frag, self.ttl, self.protocol, self.csum, self.srcip, self.dstip) \ = struct.unpack('!BBHHHBBHII', raw[:ipv4.MIN_LEN]) self.v = vhl >> 4 self.hl = vhl & 0x0f self.flags = self.frag >> 13 self.frag = self.frag & 0x1fff self.dstip = IPAddr(self.dstip) self.srcip = IPAddr(self.srcip) if self.v != ipv4.IPv4: self.msg('(ip parse) warning IP version %u not IPv4' % self.v) return elif self.hl < 5: self.msg('(ip parse) warning IP header %u longer than len %u' \ % (self.hl, self.iplen)) return elif self.iplen < ipv4.MIN_LEN: self.msg('(ip parse) warning invalid IP len %u' % self.iplen) return elif (self.hl * 4) >= self.iplen or (self.hl * 4) > dlen: self.msg('(ip parse) warning IP header %u longer than len %u' \ % (self.hl, self.iplen)) return # At this point, we are reasonably certain that we have an IP # packet self.parsed = True length = self.iplen if length > dlen: length = dlen # Clamp to what we've got if self.protocol == ipv4.UDP_PROTOCOL: self.next = udp(raw=raw[self.hl*4:length], prev=self) elif self.protocol == ipv4.TCP_PROTOCOL: self.next = tcp(raw=raw[self.hl*4:length], prev=self) elif self.protocol == ipv4.ICMP_PROTOCOL: self.next = icmp(raw=raw[self.hl*4:length], prev=self) elif self.protocol == ipv4.IGMP_PROTOCOL: self.next = igmp(raw=raw[self.hl*4:length], prev=self) elif dlen < self.iplen: self.msg('(ip parse) warning IP packet data shorter than IP len: %u < %u' % (dlen, self.iplen)) else: self.next = raw[self.hl*4:length] if isinstance(self.next, packet_base) and not self.next.parsed: self.next = raw[self.hl*4:length]
def getOutPortForIp(self, switch, destIp): if DEBUG: print '*** _getOutPortForIp:' print switch, destIp dest = IPAddr(destIp) for entry in self.routingTable: if dest.inNetwork(entry.network) and \ switch.name == entry.name: return entry.port # port number return None
def __contains__ (self, item): item = IPAddr(item) if item in self.removed: return False n = item.toUnsigned() mask = (1<<self.host_size)-1 nm = (n & mask) | self.network.toUnsigned() if nm != n: return False if (n & mask) == mask: return False if (n & mask) < self.first: return False if (n & mask) > self.last: return False return True
def __init__ (self, device = None, promiscuous = True, period = 10, start = True, callback = None, filter = None): if filter is not None: self.deferred_filter = (filter,) else: self.deferred_filter = None self.packets_received = 0 self.packets_dropped = 0 self._thread = None self.pcap = None self.promiscuous = promiscuous self.device = None self.period = period self.netmask = IPAddr("0.0.0.0") self._quitting = False self.addresses = {} if callback is None: self.callback = self.__class__._handle_rx else: self.callback = callback if device is not None: self.open(device) if self.pcap is not None: if start: self.start()
class MTDIPPrefix(object): def __init__(self, pattern): parts = pattern.split("/") if len(parts) != 2: raise TypeError self.masklen = int(parts[1]) self.pattern = IPAddr(parts[0]) bits = bitarray() bits.frombytes(self.pattern.toRaw()) self.prefix = bits[:self.masklen] def rand_ip_addr(self): rbitslen = 32 - self.masklen rbits = bin(random.getrandbits(rbitslen))[2:] return IPAddr((self.prefix + rbits.zfill(rbitslen)).tobytes()) def __repr__(self): return "%s/%d" % (repr(self.pattern), self.masklen) def __contains__(self, ipaddr): if not isinstance(ipaddr, IPAddr): raise TypeError ipaddr_bits = bitarray() ipaddr_bits.frombytes(ipaddr.toRaw()) return self.prefix == ipaddr_bits[:self.masklen]
def __init__(self, pattern): parts = pattern.split("/") if len(parts) != 2: raise TypeError self.masklen = int(parts[1]) self.pattern = IPAddr(parts[0]) bits = bitarray() bits.frombytes(self.pattern.toRaw()) self.prefix = bits[:self.masklen]
def ip (self): ip = IPAddr("192.168.1.1") print str(ip) print ip.toUnsignedN() # converts to network-order unsigned integer 16885952 print ip.toRaw() # returns a length-four bytes object print "*****" ip = IPAddr(16885952, networkOrder=True) print str(ip)
def __init__( self, device=None, promiscuous=True, period=10, start=True, callback=None, filter=None, use_bytearray=False, **kw ): """ Initialize this instance use_bytearray: specifies capturing to bytearray buffers instead of bytes """ if filter is not None: self.deferred_filter = (filter,) else: self.deferred_filter = None self.packets_received = 0 self.packets_dropped = 0 self._thread = None self.pcap = None self.promiscuous = promiscuous self.device = None self.use_bytearray = use_bytearray self.period = period self.netmask = IPAddr("0.0.0.0") self._quitting = False self.addresses = {} if callback is None: self.callback = self.__class__._handle_rx else: self.callback = callback for k, v in kw.items(): assert not hasattr(self, k) setattr(self, k, v) if device is not None: self.open(device) if self.pcap is not None: if start: self.start()
def open(self, device, promiscuous=None, period=None, incoming=True, outgoing=False): assert self.device is None self.addresses = self.get_devices()[device]["addrs"] if "AF_INET" in self.addresses: self.netmask = self.addresses["AF_INET"].get("netmask") if self.netmask is None: self.netmask = IPAddr("0.0.0.0") # print "NM:",self.netmask # print self.addresses['AF_LINK']['addr'] self.device = device if period is not None: self.period = period if promiscuous is not None: self.promiscuous = promiscuous self.pcap = pcapc.open_live(device, 65535, 1 if self.promiscuous else 0, self.period) pcapc.setdirection(self.pcap, incoming, outgoing) self.packets_received = 0 self.packets_dropped = 0 if self.deferred_filter is not None: self.set_filter(*self.deferred_filter) self.deferred_filter = None
def __init__ (self, network = "192.168.1.0/24", first = 2, last = None, count = None): """ Simple subnet-based address pool Allocates count IP addresses out of network/network_size, starting with the first'th. You may specify the end of the range with either last (to specify the last'th address to use) or count to specify the number to use. If both are None, use up to the end of all legal addresses. Example for all of 192.168.x.x/16: SimpleAddressPool("192.168.0.0/16", 1, 65534) """ network,network_size = parse_cidr(network) self.first = first self.network_size = network_size self.host_size = 32-network_size self.network = IPAddr(network) if last is None and count is None: self.last = (1 << self.host_size) - 2 elif last is not None: self.last = last elif count is not None: self.last = self.first + count - 1 else: raise RuntimeError("Cannot specify both last and count") self.removed = set() if self.count <= 0: raise RuntimeError("Bad first/last range") if first == 0: raise RuntimeError("Can't allocate 0th address") if self.host_size < 0 or self.host_size > 32: raise RuntimeError("Bad network") if IPAddr(self.last | self.network.toUnsigned()) not in self: raise RuntimeError("Bad first/last range")
class arp(packet_base): "ARP/RARP packet struct" MIN_LEN = 28 HW_TYPE_ETHERNET = 1 PROTO_TYPE_IP = 0x0800 # OPCODES REQUEST = 1 # ARP REPLY = 2 # ARP REV_REQUEST = 3 # RARP REV_REPLY = 4 # RARP def __init__(self, raw=None, prev=None, **kw): packet_base.__init__(self) self.prev = prev self.hwtype = arp.HW_TYPE_ETHERNET self.prototype = arp.PROTO_TYPE_IP self.hwsrc = ETHER_ANY self.hwdst = ETHER_ANY self.hwlen = 6 self.opcode = 0 self.protolen = 4 self.protosrc = IP_ANY self.protodst = IP_ANY self.next = b"" if raw is not None: self.parse(raw) self._init(kw) def parse(self, raw): assert isinstance(raw, bytes) self.raw = raw dlen = len(raw) if dlen < arp.MIN_LEN: self.msg("(arp parse) warning IP packet data too short to parse header: data len %u" % dlen) return (self.hwtype, self.prototype, self.hwlen, self.protolen, self.opcode) = struct.unpack("!HHBBH", raw[:8]) if self.hwtype != arp.HW_TYPE_ETHERNET: self.msg("(arp parse) hw type unknown %u" % self.hwtype) if self.hwlen != 6: self.msg("(arp parse) unknown hw len %u" % self.hwlen) else: self.hwsrc = EthAddr(raw[8:14]) self.hwdst = EthAddr(raw[18:24]) if self.prototype != arp.PROTO_TYPE_IP: self.msg("(arp parse) proto type unknown %u" % self.prototype) if self.protolen != 4: self.msg("(arp parse) unknown proto len %u" % self.protolen) else: self.protosrc = IPAddr(struct.unpack("!I", raw[14:18])[0]) self.protodst = IPAddr(struct.unpack("!I", raw[24:28])[0]) self.next = raw[28:] self.parsed = True def hdr(self, payload): buf = struct.pack("!HHBBH", self.hwtype, self.prototype, self.hwlen, self.protolen, self.opcode) if type(self.hwsrc) == bytes: buf += self.hwsrc else: buf += self.hwsrc.toRaw() if type(self.protosrc) is IPAddr: buf += struct.pack("!I", self.protosrc.toUnsigned()) else: buf += struct.pack("!I", self.protosrc) if type(self.hwdst) == bytes: buf += self.hwdst else: buf += self.hwdst.toRaw() if type(self.protodst) is IPAddr: buf += struct.pack("!I", self.protodst.toUnsigned()) else: buf += struct.pack("!I", self.protodst) return buf def __str__(self): op = str(self.opcode) eth_type = None # Ethernet if hasattr(self.prev, "type"): eth_type = self.prev.type # Vlan elif hasattr(self.prev, "eth_type"): eth_type = self.prev.eth_type else: self.err("(arp) unknown datalink type") eth_type = ethernet.ARP_TYPE if eth_type == ethernet.ARP_TYPE: if self.opcode == arp.REQUEST: op = "REQUEST" elif self.opcode == arp.REPLY: op = "REPLY" elif eth_type == ethernet.RARP_TYPE: if self.opcode == arp.REV_REQUEST: op = "REV_REQUEST" elif self.opcode == arp.REV_REPLY: op = "REV_REPLY" s = "{0} hw:{1} p:{2} {3}>{4} {5}>{6}".format( op, self.hwtype, self.prototype, EthAddr(self.hwsrc), EthAddr(self.hwdst), IPAddr(self.protosrc), IPAddr(self.protodst), ) return s
class SimpleAddressPool (AddressPool): """ Simple AddressPool for simple subnet based pools. """ def __init__ (self, network = "192.168.0.0/24", first = 1, last = None, count = None): """ Simple subnet-based address pool Allocates count IP addresses out of network/network_size, starting with the first'th. You may specify the end of the range with either last (to specify the last'th address to use) or count to specify the number to use. If both are None, use up to the end of all legal addresses. Example for all of 192.168.x.x/16: SimpleAddressPool("192.168.0.0/16", 1, 65534) """ network,network_size = parse_cidr(network) self.first = first self.network_size = network_size self.host_size = 32-network_size self.network = IPAddr(network) if last is None and count is None: self.last = (1 << self.host_size) - 2 elif last is not None: self.last = last elif count is not None: self.last = self.first + count - 1 else: raise RuntimeError("Cannot specify both last and count") self.removed = set() if self.count <= 0: raise RuntimeError("Bad first/last range") if first == 0: raise RuntimeError("Can't allocate 0th address") if self.host_size < 0 or self.host_size > 32: raise RuntimeError("Bad network") if IPAddr(self.last | self.network.toUnsigned()) not in self: raise RuntimeError("Bad first/last range") def __repr__ (self): return str(self) def __str__ (self): t = self.network.toUnsigned() t = (IPAddr(t|self.first),IPAddr(t|self.last)) return "<Addresses from %s to %s>" % t @property def subnet_mask (self): return IPAddr(((1<<self.network_size)-1) << self.host_size) @property def count (self): return self.last - self.first + 1 def __contains__ (self, item): item = IPAddr(item) if item in self.removed: return False n = item.toUnsigned() mask = (1<<self.host_size)-1 nm = (n & mask) | self.network.toUnsigned() if nm != n: return False if (n & mask) == mask: return False if (n & mask) < self.first: return False if (n & mask) > self.last: return False return True def append (self, item): item = IPAddr(item) if item not in self.removed: if item in self: raise RuntimeError("%s is already in this pool" % (item,)) else: raise RuntimeError("%s does not belong in this pool" % (item,)) self.removed.remove(item) def remove (self, item): item = IPAddr(item) if item not in self: raise RuntimeError("%s not in this pool" % (item,)) self.removed.add(item) def __len__ (self): return (self.last-self.first+1) - len(self.removed) def __getitem__ (self, index): if index < 0: raise RuntimeError("Negative indices not allowed") if index >= len(self): raise IndexError("Item does not exist") c = self.first # Use a heuristic to find the first element faster (we hope) # Note this means that removing items changes the order of # our "list". c += len(self.removed) while c > self.last: c -= self.count while True: addr = IPAddr(c | self.network.toUnsigned()) if addr not in self.removed: assert addr in self index -= 1 if index < 0: return addr c += 1 if c > self.last: c -= self.count
def configureRules(self, event, lruleset): """ Configure initial rules """ print "Ready for configure init rules in SW: " + dpidToStr( event.dpid) + " " + str(event.dpid) of_fib = parse_of_file(lruleset) #print of_fib of_list = [] try: of_list = of_fib[dpidToStr(event.dpid)] except KeyError: print "Oops! There is no information about the Sw " + dpidToStr( event.dpid) + " in the configuration file" #f = open('/tmp/' + dpidToStr(event.dpid), 'wa') #f.write( dpidToStr(event.dpid) + " begin " + str(time.time())) #of_entry = of_list[0] #print of_entry for of_entry in of_list: msg = of.ofp_flow_mod() #print "writing OpenFlow entry:", of_entry #msg.priority = 42 if "dl_type" in of_entry.keys(): msg.match.dl_type = int(of_entry["dl_type"], 16) if "nw_proto" in of_entry.keys(): msg.match.nw_proto = int(of_entry["nw_proto"], 10) #ETH if "dl_src" in of_entry.keys(): msg.match.dl_src = EthAddr(of_entry["dl_src"]) if "dl_dst" in of_entry.keys(): msg.match.dl_dst = EthAddr(of_entry["dl_dst"]) #IP if "nw_src" in of_entry.keys(): msg.match.nw_src = IPAddr(of_entry["nw_src"]) if "nw_dst" in of_entry.keys(): msg.match.nw_dst = IPAddr(of_entry["nw_dst"]) if "nw_tos" in of_entry.keys(): msg.match.nw_tos = int(of_entry["nw_tos"], 10) #UDP if "tp_dst" in of_entry.keys(): msg.match.tp_dst = int(of_entry["tp_dst"], 10) if "tp_src" in of_entry.keys(): msg.match.tp_src = int(of_entry["tp_src"], 10) #OTHERS if "in_port" in of_entry.keys(): msg.match.in_port = int(of_entry["in_port"], 10) if "dl_vlan" in of_entry.keys(): msg.match.dl_vlan = int(of_entry["dl_vlan"], 16) if "vlan_tci" in of_entry.keys(): msg.match.vlan_tci = int(of_entry["vlan_tci"], 16) #msg.match.tp_dst = 80 # iterate list of actions #output #vlan if "mod_nw_tos" in of_entry["actions"].keys(): msg.actions.append( of.ofp_action_nw_tos( nw_tos=int(of_entry["actions"]["mod_nw_tos"], 10))) if "mod_vlan_vid" in of_entry["actions"].keys(): msg.actions.append( of.ofp_action_vlan_vid( vlan_vid=int(of_entry["actions"]["mod_vlan_vid"], 16))) if "mod_dl_src" in of_entry["actions"].keys(): msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr(of_entry["actions"]["mod_dl_src"]))) if "mod_dl_dst" in of_entry["actions"].keys(): print "mod_dl_dst: %s " % of_entry["actions"]["mod_dl_dst"] msg.actions.append( of.ofp_action_dl_addr.set_dst( EthAddr(of_entry["actions"]["mod_dl_dst"]))) if "output" in of_entry["actions"].keys(): msg.actions.append( of.ofp_action_output( port=int(of_entry["actions"]["output"], 10))) #print "set the output port" self.connection.send(msg) #f.write(" ending " + str(time.time()) + "\n") #f.close() print "Init rules configured, allow traffic for " + dpidToStr( event.dpid)
class PCap (object): @staticmethod def get_devices (): def ip (addr): if addr is None: return None return IPAddr(addr, networkOrder=True) def link (addr): if addr is None: return None if len(addr) != 6: return None return EthAddr(addr) devs = pcapc.findalldevs() out = {} for d in devs: addrs = {} n = {'desc':d[1],'addrs':addrs} out[d[0]] = n for a in d[2]: if a[0] == 'AF_INET': na = {} addrs[a[0]] = na na['addr'] = ip(a[1]) na['netmask'] = ip(a[2]) na['broadaddr'] = ip(a[3]) na['dstaddr'] = ip(a[4]) elif a[0] == 'AF_LINK': na = {} addrs[a[0]] = na na['addr'] = link(a[1]) na['netmask'] = link(a[2]) na['broadaddr'] = link(a[3]) na['dstaddr'] = link(a[4]) elif a[0] == 'AF_PACKET': addrs[a[0]] = {'addr':link(a[1])} elif a[0] == 'ethernet': addrs[a[0]] = {'addr':link(a[1])} return out @staticmethod def get_device_names (): return [d[0] for d in pcapc.findalldevs()] def __init__ (self, device = None, promiscuous = True, period = 10, start = True, callback = None, filter = None): if filter is not None: self.deferred_filter = (filter,) else: self.deferred_filter = None self.packets_received = 0 self.packets_dropped = 0 self._thread = None self.pcap = None self.promiscuous = promiscuous self.device = None self.period = period self.netmask = IPAddr("0.0.0.0") self._quitting = False self.addresses = {} if callback is None: self.callback = self.__class__._handle_rx else: self.callback = callback if device is not None: self.open(device) if self.pcap is not None: if start: self.start() def _handle_rx (self, data, sec, usec, length): pass def open (self, device, promiscuous = None, period = None, incoming = True, outgoing = False): assert self.device is None self.addresses = self.get_devices()[device]['addrs'] if 'AF_INET' in self.addresses: self.netmask = self.addresses['AF_INET'].get('netmask') if self.netmask is None: self.netmask = IPAddr("0.0.0.0") #print "NM:",self.netmask #print self.addresses['AF_LINK']['addr'] self.device = device if period is not None: self.period = period if promiscuous is not None: self.promiscuous = promiscuous self.pcap = pcapc.open_live(device, 65535, 1 if self.promiscuous else 0, self.period) pcapc.setdirection(self.pcap, incoming, outgoing) self.packets_received = 0 self.packets_dropped = 0 if self.deferred_filter is not None: self.set_filter(*self.deferred_filter) self.deferred_filter = None def set_direction (self, incoming, outgoing): pcapc.setdirection(self.pcap, incoming, outgoing) def _thread_func (self): while not self._quitting: pcapc.dispatch(self.pcap,100,self.callback,self) self.packets_received,self.packets_dropped = pcapc.stats(self.pcap) self._quitting = False self._thread = None def _handle_GoingDownEvent (self, event): self.close() def start (self): assert self._thread is None from pox.core import core core.addListeners(self, weak=True) self._thread = Thread(target=self._thread_func) #self._thread.daemon = True self._thread.start() def stop (self): t = self._thread if t is not None: self._quitting = True pcapc.breakloop(self.pcap) t.join() def close (self): if self.pcap is None: return self.stop() pcapc.close(self.pcap) self.pcap = None def __del__ (self): self.close() def inject (self, data): if isinstance(data, pkt.ethernet): data = data.pack() if not isinstance(data, bytes): data = bytes(data) # Give it a try... return pcapc.inject(self.pcap, data) def set_filter (self, filter, optimize = True): if self.pcap is None: self.deferred_filter = (filter, optimize) return if isinstance(filter, str): filter = Filter(filter, optimize, self.netmask.toSignedN(), pcap_obj=self) elif isinstance(filter, Filter): pass else: raise RuntimeError("Filter must be string or Filter object") pcapc.setfilter(self.pcap, filter._pprogram)
def _handle_openflow_PacketIn(self, event): #def _handle_PacketIn (self, event): dpid = event.dpid inport = event.port packet = event.parsed #log.info('Pacote de '+ str(self.dpid_to_mac(dpid))) net = packet.next # Camada de rede transp = packet.next.next # Camada de transporte if not packet.parsed: log.info("Pacote not Parsed") return #if packet.type == ethernet.LLDPTYPE: #.info("Pacote LLDPTYPE") #return if isinstance(net, ipv4): #log.info("Pacote IPv4") #log.info("Evento gerado na porta ="+str(inport)) if (inport == 1 or inport == 2): #if() lista = [] for i in self.arpTableServidores: lista.append(i) if str(net.dstip) not in lista: #Faz nada return else: #if (str(transp.dstport) == '1234'): #Eventos foram gerados por hosts conectados ao swtich if str(net.dstip) in lista and str( transp.dstport) != '12320': if str( self.dpid_to_mac(dpid) ) == '00:00:00:00:00:03': # Switch onde esta os servidores S3 msg = of.ofp_flow_mod() #msg.match.dl_src = EthAddr('00:00:00:00:01:01') #msg.match.dl_dst = EthAddr('00:00:00:00:03:11') msg.match.dl_type = 0x800 msg.match.nw_src = IPAddr("10.0.0.11") msg.match.nw_dst = IPAddr(str(net.dstip)) msg.priority = 50001 #seta uma prioridade maior para regra msg.actions.append( of.ofp_action_output(port=17) ) #Nao tem ninguem conectado a essa porta event.connection.send(msg) log.info("Regra de Drop Adicionada!!" ) # Supoe que drop o pacote ''' Adiciona o IP do servidor multicast a tabela ''' lista_Portas = [] if str(net.dstip) not in self.tableIPServidores: self.tableIPServidores.append(str(net.dstip)) lista_Portas = [17] info = {str(net.dstip): lista_Portas} self.tableSwtichFluxo[str( self.dpid_to_mac(dpid) )].append( info ) #Adiciona o IP e a porta que ele esta saido na tabela de Fluxo do Switch else: log.info("IP Servidor ja registrado!!") return elif str(self.dpid_to_mac( dpid)) == '00:00:00:00:00:01': # Swithc s1 ''' Fazer as regras aqui!! ''' log.debug( "Chegou pacote do S1 para o grupo multicast") #Verificar se o swtich ja possui o fluxo requerido l = self.tableSwtichFluxo[str( self.dpid_to_mac(dpid))] k = {} for i in l: for j in i: if str(j) == str(net.dstip): k = i a = [] if len(k) != 0: a = k[str( net.dstip )] #lista de portas que estao com fluxo swtich if len(a) != 0: #Levar o fluxo para a porta entao log.debug('Switch ja possui o Fluxo') p = self.retornaStringListaPortas( str(self.dpid_to_mac(dpid)), net.dstip ) #Lista de portas que contem o fluxo if inport == 1: comando2 = 'ovs-ofctl mod-flows s1 priority=50002,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.2,mod_dl_dst:00:00:00:00:01:02,output:' + p + ',1' self.executaComandosOVS(comando2) a.append(1) else: comando2 = 'ovs-ofctl mod-flows s1 priority=50002,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.1,mod_dl_dst:00:00:00:00:01:01,output:' + p + ',2' self.executaComandosOVS(comando2) a.append(2) return else: log.debug('Switch ainda nao possui o Fluxo') #Trazer o fluxo para o switch #comando = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst='+str(net.dstip)+',actions=output:11' #comando = 'ovs-ofctl mod-flows s3 priority=50001,dl_type=0x800,nw_src=10.0.0.11,nw_dst='+str(net.dstip)+',actions=output:11' #self.executaComandosOVS(comando) #p = self.retornaStringListaPortas(str(self.dpid_to_mac(dpid)),net.dstip) p = self.retornaStringListaPortas( '00:00:00:00:00:03', net.dstip ) #Lista de portas que contem o fluxo comando = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst=' + str( net.dstip) + ',actions=output:' + p + ',11' self.executaComandosOVS(comando) l = self.tableSwtichFluxo['00:00:00:00:00:03'] k = {} for i in l: for j in i: if str(j) == str(net.dstip): k = i #log.info(k) lista_portas = k[str( net.dstip )] #lista de portas que estao com fluxo swtich lista_portas.append( 11) #Porta que vai para o S1 #Verifico de qual porta veio para fazer a rescrita de cabecalho if inport == 1: comando2 = 'ovs-ofctl mod-flows s1 priority=5001,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.1,mod_dl_dst:00:00:00:00:01:01,output:1' self.executaComandosOVS(comando2) lista_Portas = [1] info = {str(net.dstip): lista_Portas} self.tableSwtichFluxo[str( self.dpid_to_mac(dpid) )].append( info ) #Adiciona o IP e a porta que ele esta saido na tabela de Fluxo do Switch else: comando2 = 'ovs-ofctl mod-flows s1 priority=5001,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.2,mod_dl_dst:00:00:00:00:01:02,output:2' self.executaComandosOVS(comando2) lista_Portas = [2] info = {str(net.dstip): lista_Portas} self.tableSwtichFluxo[str( self.dpid_to_mac(dpid) )].append( info ) #Adiciona o IP e a porta que ele esta saido na tabela de Fluxo do Switch return #comando2 = 'ovs-ofctl mod-flows s1 priority=50010,dl_type=0x800,nw_dst='+str(net.dstip)+',actions=mod_nw_dst:10.0.0.1,mod_dl_dst:00:00:00:00:01:01,output:1' #comando3 = 'ovs-ofctl add-flow s1 priority=5001,dl_type=0x800,nw_src=10.0.0.11,tp_dst=1236,actions=mod_nw_dst:10.0.0.1,mod_dl_dst:00:00:00:00:01:01,output:1' #self.executaComandosOVS(comando2) #self.executaComandosOVS(comando3) elif str(self.dpid_to_mac( dpid)) == '00:00:00:00:00:02': #Switch s2 ''' Fazer as regras aqui!! ''' log.debug( "Chegou pacote do S2 para o grupo multicast") #Verificar se o swtich ja possui o fluxo requerido l = self.tableSwtichFluxo[str( self.dpid_to_mac(dpid))] k = {} for i in l: for j in i: if str(j) == str(net.dstip): k = i a = [] if len(k) != 0: a = k[str( net.dstip )] #lista de portas que estao com fluxo swtich if len(a) != 0: log.debug('Switch ja possui o Fluxo') #Levar o fluxo para a porta entao p = self.retornaStringListaPortas( str(self.dpid_to_mac(dpid)), net.dstip ) #Lista de portas que contem o fluxo if inport == 1: comando2 = 'ovs-ofctl mod-flows s2 priority=50002,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.4,mod_dl_dst:00:00:00:00:02:04,output:' + p + ',1' self.executaComandosOVS(comando2) a.append(1) else: comando2 = 'ovs-ofctl mod-flows s2 priority=50002,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.3,mod_dl_dst:00:00:00:00:02:03,output:' + p + ',2' self.executaComandosOVS(comando2) a.append(2) return else: log.debug('Switch ainda nao possui o Fluxo') #Trazer o fluxo para o switch #comando = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst='+str(net.dstip)+',actions=output:11' #comando = 'ovs-ofctl mod-flows s3 priority=50001,dl_type=0x800,nw_src=10.0.0.11,nw_dst='+str(net.dstip)+',actions=output:11' #self.executaComandosOVS(comando) #p = self.retornaStringListaPortas(str(self.dpid_to_mac(dpid)),net.dstip) p = self.retornaStringListaPortas( '00:00:00:00:00:03', net.dstip ) #Lista de portas que contem o fluxo comando = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst=' + str( net.dstip) + ',actions=output:' + p + ',12' self.executaComandosOVS(comando) l = self.tableSwtichFluxo['00:00:00:00:00:03'] k = {} for i in l: for j in i: if str(j) == str(net.dstip): k = i #log.info(k) lista_portas = k[str( net.dstip )] #lista de portas que estao com fluxo swtich lista_portas.append( 12) #Porta que vai para o S2 #Verifico de qual porta veio para fazer a rescrita de cabecalho if inport == 1: comando2 = 'ovs-ofctl mod-flows s2 priority=49999,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.3,mod_dl_dst:00:00:00:00:02:03,output:1' self.executaComandosOVS(comando2) lista_Portas = [1] info = {str(net.dstip): lista_Portas} self.tableSwtichFluxo[str( self.dpid_to_mac(dpid) )].append( info ) #Adiciona o IP e a porta que ele esta saido na tabela de Fluxo do Switch else: comando2 = 'ovs-ofctl mod-flows s2 priority=49999,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.4,mod_dl_dst:00:00:00:00:02:04,output:2' self.executaComandosOVS(comando2) lista_Portas = [2] info = {str(net.dstip): lista_Portas} self.tableSwtichFluxo[str( self.dpid_to_mac(dpid) )].append( info ) #Adiciona o IP e a porta que ele esta saido na tabela de Fluxo do Switch return elif str(self.dpid_to_mac( dpid)) == '00:00:00:00:00:04': #Swtich s4 ''' Fazer as regras aqui!! ''' log.debug( "Chegou pacote do S4 para o grupo multicast") #Verificar se o swtich ja possui o fluxo requerido l = self.tableSwtichFluxo[str( self.dpid_to_mac(dpid))] k = {} for i in l: for j in i: if str(j) == str(net.dstip): k = i a = [] if len(k) != 0: a = k[str( net.dstip )] #lista de portas que estao com fluxo swtich if len(a) != 0: log.debug('Switch ja possui o Fluxo') #Levar o fluxo para a porta entao p = self.retornaStringListaPortas( str(self.dpid_to_mac(dpid)), net.dstip ) #Lista de portas que contem o fluxo if inport == 1: comando2 = 'ovs-ofctl mod-flows s4 priority=50002,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.6,mod_dl_dst:00:00:00:00:04:06,output:' + p + ',1' self.executaComandosOVS(comando2) a.append(1) else: comando2 = 'ovs-ofctl mod-flows s4 priority=50002,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.3,mod_dl_dst:00:00:00:00:04:05,output:' + p + ',2' self.executaComandosOVS(comando2) a.append(2) return else: log.debug('Switch ainda nao possui o Fluxo') #Trazer o fluxo para o switch #comando = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst='+str(net.dstip)+',actions=output:11' #comando = 'ovs-ofctl mod-flows s3 priority=50001,dl_type=0x800,nw_src=10.0.0.11,nw_dst='+str(net.dstip)+',actions=output:11' #self.executaComandosOVS(comando) #p = self.retornaStringListaPortas(str(self.dpid_to_mac(dpid)),net.dstip) p = self.retornaStringListaPortas( '00:00:00:00:00:03', net.dstip ) #Lista de portas que contem o fluxo comando = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst=' + str( net.dstip) + ',actions=output:' + p + ',14' self.executaComandosOVS(comando) l = self.tableSwtichFluxo['00:00:00:00:00:03'] k = {} for i in l: for j in i: if str(j) == str(net.dstip): k = i #log.info(k) lista_portas = k[str( net.dstip )] #lista de portas que estao com fluxo swtich lista_portas.append( 14) #Porta que vai para o S4 #Verifico de qual porta veio para fazer a rescrita de cabecalho if inport == 1: comando2 = 'ovs-ofctl mod-flows s4 priority=49999,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.5,mod_dl_dst:00:00:00:00:04:05,output:1' self.executaComandosOVS(comando2) lista_Portas = [1] info = {str(net.dstip): lista_Portas} self.tableSwtichFluxo[str( self.dpid_to_mac(dpid) )].append( info ) #Adiciona o IP e a porta que ele esta saido na tabela de Fluxo do Switch else: comando2 = 'ovs-ofctl mod-flows s4 priority=49999,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.6,mod_dl_dst:00:00:00:00:04:06,output:2' self.executaComandosOVS(comando2) lista_Portas = [2] info = {str(net.dstip): lista_Portas} self.tableSwtichFluxo[str( self.dpid_to_mac(dpid) )].append( info ) #Adiciona o IP e a porta que ele esta saido na tabela de Fluxo do Switch return else: #Pedido para sair do Grupo Multicast ''' Pedido para sair do Grupo Multicast ''' log.info('IP = ' + str(net.srcip) + ' quer sair do Grupo Multicast ' + str(net.dstip)) ip_fluxo = net.dstip l = self.tableSwtichFluxo[str(self.dpid_to_mac(dpid))] k = {} for i in l: for j in i: if str(j) == str(ip_fluxo): k = i #log.info(k) t = k[ str(ip_fluxo )] #lista de portas que estao com fluxo swtich log.debug(t) if str(self.dpid_to_mac( dpid)) == '00:00:00:00:00:01': # Swithc s1 ''' Fazer as regras aqui!! ''' p = self.retornaStringListaPortas( str(self.dpid_to_mac(dpid)), net.dstip) #Lista de portas que contem o fluxo if len(t) == 1: #Tem somente um fluno no switch #Retiro o fluxo da porta em s3 l = self.tableSwtichFluxo['00:00:00:00:00:03'] k = {} for i in l: for j in i: if str(j) == str(ip_fluxo): k = i #log.info(k) lista_portas = k[str( ip_fluxo )] #lista de portas que estao com fluxo swtich lista_portas.remove(11) b = self.retornaStringListaPortas( '00:00:00:00:00:03', net.dstip ) #Lista de portas que contem o fluxo comando2 = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst=' + str( net.dstip) + ',actions=output:' + b self.executaComandosOVS(comando2) del t[:] #Apaga lista de portas do fluxo no swtich else: #Retiro somente o fluxo da porta if inport == 1: l = self.tableSwtichFluxo[ '00:00:00:00:00:01'] k = {} for i in l: for j in i: if str(j) == str(ip_fluxo): k = i #log.info(k) lista_portas = k[str( ip_fluxo )] #lista de portas que estao com fluxo swtich lista_portas.remove(1) b = self.retornaStringListaPortas( str(self.dpid_to_mac(dpid)), net.dstip ) #Lista de portas que contem o fluxo comando2 = 'ovs-ofctl mod-flows s1 priority=49999,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.1,mod_dl_dst:00:00:00:00:01:02,output:' + b #comando2 = 'ovs-ofctl mod-flows s1 priority=49999,dl_type=0x800,nw_dst='+str(net.dstip)+',actions=output:'+b log.debug(comando2) self.executaComandosOVS(comando2) else: l = self.tableSwtichFluxo[ '00:00:00:00:00:01'] k = {} for i in l: for j in i: if str(j) == str(ip_fluxo): k = i #log.info(k) lista_portas = k[str( ip_fluxo )] #lista de portas que estao com fluxo swtich lista_portas.remove(2) b = self.retornaStringListaPortas( str(self.dpid_to_mac(dpid)), net.dstip ) #Lista de portas que contem o fluxo comando2 = 'ovs-ofctl mod-flows s1 priority=49999,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.1,mod_dl_dst:00:00:00:00:01:01,output:' + b #comando2 = 'ovs-ofctl mod-flows s1 priority=49999,dl_type=0x800,nw_dst='+str(net.dstip)+',actions=output:'+b log.debug(comando2) self.executaComandosOVS(comando2) return return elif str(self.dpid_to_mac( dpid)) == '00:00:00:00:00:02': # Swithc s2 ''' Fazer as regras aqui!! ''' p = self.retornaStringListaPortas( str(self.dpid_to_mac(dpid)), net.dstip) #Lista de portas que contem o fluxo if len(t) == 1: #Tem somente um fluno no switch #Retiro o fluxo da porta em s3 l = self.tableSwtichFluxo['00:00:00:00:00:03'] k = {} for i in l: for j in i: if str(j) == str(ip_fluxo): k = i #log.info(k) lista_portas = k[str( ip_fluxo )] #lista de portas que estao com fluxo swtich lista_portas.remove(12) b = self.retornaStringListaPortas( '00:00:00:00:00:03', net.dstip ) #Lista de portas que contem o fluxo comando2 = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst=' + str( net.dstip) + ',actions=output:' + b self.executaComandosOVS(comando2) del t[:] #Apaga lista de portas do fluxo no swtich else: #Retiro somente o fluxo da porta if inport == 1: l = self.tableSwtichFluxo[ '00:00:00:00:00:02'] k = {} for i in l: for j in i: if str(j) == str(ip_fluxo): k = i #log.info(k) lista_portas = k[str( ip_fluxo )] #lista de portas que estao com fluxo swtich lista_portas.remove(1) b = self.retornaStringListaPortas( str(self.dpid_to_mac(dpid)), net.dstip ) #Lista de portas que contem o fluxo comando2 = 'ovs-ofctl mod-flows s2 priority=49999,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.4,mod_dl_dst:00:00:00:00:02:04,output:' + b #comando2 = 'ovs-ofctl mod-flows s2 priority=49999,dl_type=0x800,nw_dst='+str(net.dstip)+',actions=output:'+b self.executaComandosOVS(comando2) else: l = self.tableSwtichFluxo[ '00:00:00:00:00:02'] k = {} for i in l: for j in i: if str(j) == str(ip_fluxo): k = i #log.info(k) lista_portas = k[str( ip_fluxo )] #lista de portas que estao com fluxo swtich lista_portas.remove(2) b = self.retornaStringListaPortas( str(self.dpid_to_mac(dpid)), net.dstip ) #Lista de portas que contem o fluxo comando2 = 'ovs-ofctl mod-flows s2 priority=49999,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.3,mod_dl_dst:00:00:00:00:02:03,output:' + b #comando2 = 'ovs-ofctl mod-flows s2 priority=49999,dl_type=0x800,nw_dst='+str(net.dstip)+',actions=output:'+b self.executaComandosOVS(comando2) return return elif str(self.dpid_to_mac( dpid)) == '00:00:00:00:00:04': # Swithc s4 ''' Fazer as regras aqui!! ''' p = self.retornaStringListaPortas( str(self.dpid_to_mac(dpid)), net.dstip) #Lista de portas que contem o fluxo if len(t) == 1: #Tem somente um fluno no switch #Retiro o fluxo da porta em s3 l = self.tableSwtichFluxo['00:00:00:00:00:03'] k = {} for i in l: for j in i: if str(j) == str(ip_fluxo): k = i #log.info(k) lista_portas = k[str( ip_fluxo )] #lista de portas que estao com fluxo swtich lista_portas.remove(14) b = self.retornaStringListaPortas( '00:00:00:00:00:03', net.dstip ) #Lista de portas que contem o fluxo comando2 = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst=' + str( net.dstip) + ',actions=output:' + b #comando2 = 'ovs-ofctl mod-flows s3 priority=49999,dl_type=0x800,nw_dst='+str(net.dstip)+',actions=output:'+b self.executaComandosOVS(comando2) del t[:] #Apaga lista de portas do fluxo no swtich else: #Retiro somente o fluxo da porta if inport == 1: l = self.tableSwtichFluxo[ '00:00:00:00:00:04'] k = {} for i in l: for j in i: if str(j) == str(ip_fluxo): k = i #log.info(k) lista_portas = k[str( ip_fluxo )] #lista de portas que estao com fluxo swtich lista_portas.remove(1) b = self.retornaStringListaPortas( str(self.dpid_to_mac(dpid)), net.dstip ) #Lista de portas que contem o fluxo comando2 = 'ovs-ofctl mod-flows s4 priority=49999,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.6,mod_dl_dst:00:00:00:00:04:06,output:' + b #comando2 = 'ovs-ofctl mod-flows s4 priority=49999,dl_type=0x800,nw_dst='+str(net.dstip)+',actions=output:'+b self.executaComandosOVS(comando2) else: l = self.tableSwtichFluxo[ '00:00:00:00:00:04'] k = {} for i in l: for j in i: if str(j) == str(ip_fluxo): k = i #log.info(k) lista_portas = k[str( ip_fluxo )] #lista de portas que estao com fluxo swtich lista_portas.remove(2) b = self.retornaStringListaPortas( str(self.dpid_to_mac(dpid)), net.dstip ) #Lista de portas que contem o fluxo comando2 = 'ovs-ofctl mod-flows s4 priority=49999,dl_type=0x800,nw_dst=' + str( net.dstip ) + ',actions=mod_nw_dst:10.0.0.5,mod_dl_dst:00:00:00:00:04:05,output:' + b #comando2 = 'ovs-ofctl mod-flows s4 priority=49999,dl_type=0x800,nw_dst='+str(net.dstip)+',actions=output:'+b self.executaComandosOVS(comando2) return return else: return return elif isinstance(net, arp): log.info("Protocolo ARP") mac_resp = self.arpTableServidores[str(net.protodst)] arp_helper.send_arp_reply(event, mac_resp) return else: #log.info("Aconteceu nada!!") return
def install_mapping(self, priv_mac1, priv_ip1, virt_mac1, virt_ip1, priv_mac2, priv_ip2, virt_mac2, virt_ip2, expiry=None): self.installed_rules.append(locals()) log.debug("Installing rule: {}".format(locals())) # We have to install 4 rules to handle the mapping. Note that this assumes the two hosts are on different # switches; rules would need to be merged to handle the case where both endpoints are on the same switch. # In the comments below, "A" is the first address and "B" the second, and ".p" indicates a (true) private # address, ".v" a client-specific virtual address, and ".m" a (true) private MAC address. Also "S1" indicates # the switch where host A (priv_ip1) is connected, and "S2" for host B. msg = of.ofp_flow_mod() msg.priority = of.OFP_DEFAULT_PRIORITY + 42 msg.match.dl_type = 0x0800 # EtherType IPv4 # S1: if src=A.p and dst=B.v, then set dst=B.p and dl_dst=B.m, forward to the same port that has B.p # TODO: for expediency, hard-coding the switch DPIDs here; should really use something like the host_tracker # functionality so we can determine this dynamically msg.match.nw_src = priv_ip1 msg.match.nw_dst = virt_ip2 msg.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(priv_ip2))) msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(priv_mac2))) msg.actions.append( of.ofp_action_output(port=self.port_for_mac(1, priv_mac2))) SdnsMapper.send_msg(msg, 1) msg.actions = [] # S2: if src=A.p and dst=B.p, then set src=A.v and dl_src=A.v msg.match.nw_dst = priv_ip2 msg.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(virt_ip1))) msg.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(virt_mac1))) msg.actions.append( of.ofp_action_output(port=self.port_for_mac(2, priv_mac2))) SdnsMapper.send_msg(msg, 2) msg.actions = [] # S2: if src=B.p and dst=A.v, then set dst=A.p msg.match.nw_src = priv_ip2 msg.match.nw_dst = virt_ip1 msg.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(priv_ip1))) msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(priv_mac1))) msg.actions.append( of.ofp_action_output(port=self.port_for_mac(2, priv_mac1))) SdnsMapper.send_msg(msg, 2) msg.actions = [] # S1: if src=B.p and dst=A.p, then set src=B.v msg.match.nw_dst = priv_ip1 msg.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(virt_ip2))) msg.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(virt_mac2))) msg.actions.append( of.ofp_action_output(port=self.port_for_mac(1, priv_mac1))) SdnsMapper.send_msg(msg, 1) # Have the switches respond to ARP requests for virtual IPs directly timeout = float('inf') if expiry is None else expiry self.install_arp_rule(virt_mac1, virt_ip1, timeout) self.install_arp_rule(virt_mac2, virt_ip2, timeout)
def _handle_openflow_PacketIn (self, event): dpid = event.connection.dpid inport = event.port packet = event.parsed global set_Timer global defendDDOS global blockPort timerSet =False global diction def preventing(): global diction global set_Timer if not set_Timer: set_Timer =True #Timer(1, _timer_func(), recurring=True) #print"\n\n*********new packetIN************" if len(diction) == 0: print("Enpty diction ",str(event.connection.dpid), str(event.port)) diction[event.connection.dpid] = {} diction[event.connection.dpid][event.port] = 1 elif event.connection.dpid not in diction: diction[event.connection.dpid] = {} diction[event.connection.dpid][event.port] = 1 #print "ERROR" else: if event.connection.dpid in diction: # temp = diction[event.connection.dpid] #print(temp) #print "error check " , str(diction[event.connection.dpid][event.port]) if event.port in diction[event.connection.dpid]: temp_count=0 temp_count =diction[event.connection.dpid][event.port] temp_count = temp_count+1 diction[event.connection.dpid][event.port]=temp_count #print "printting dpid port number and its packet count: ", str(event.connection.dpid), str(diction[event.connection.dpid]), str(diction[event.connection.dpid][event.port]) else: diction[event.connection.dpid][event.port] = 1 print "\n",datetime.datetime.now(gst), ": printing diction ",str(diction),"\n" def _timer_func (): global diction global set_Timer if set_Timer==True: #print datetime.datetime.now(),": calling timer fucntion now!!!!!" for k,v in diction.iteritems(): for i,j in v.iteritems(): if j >=50: print "_____________________________________________________________________________________________" print "\n",datetime.datetime.now(gst),"******* DDOS DETECTED ********" print "\n",str(diction) print "\n",datetime.datetime.now(gst),": BLOCKED PORT NUMBER : ", str(i), " OF SWITCH ID: ", str(k) print "\n_____________________________________________________________________________________________" #self.dropDDOS () dpid = k msg = of.ofp_packet_out(in_port=i) #msg.priority=42 #msg.in_port = event.port #po = of.ofp_packet_out(buffer_id = buffer_id, in_port = in_port) core.openflow.sendToDPID(dpid,msg) diction={} if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return if dpid not in self.arpTable: # New switch -- create an empty table self.arpTable[dpid] = {} for fake in self.fakeways: self.arpTable[dpid][IPAddr(fake)] = Entry(of.OFPP_NONE, dpid_to_mac(dpid)) if packet.type == ethernet.LLDP_TYPE: # Ignore LLDP packets return if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", dpid,inport, packet.next.srcip,packet.next.dstip) ent_obj.statcolect(event.parsed.next.dstip)#editing print "\n***** Entropy Value = ",str(ent_obj.value),"*****\n" if ent_obj.value <0.5: preventing() if timerSet is not True: Timer(2, _timer_func, recurring=True) timerSet=False else: timerSet=False # Send any waiting packets... self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport) # Learn or update port/MAC info if packet.next.srcip in self.arpTable[dpid]: if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid,inport,packet.next.srcip) if self.wide: # Make sure we don't have any entries with the old info... msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.match.nw_dst = packet.next.srcip msg.match.dl_type = ethernet.IP_TYPE event.connection.send(msg) else: log.debug("%i %i learned %s", dpid,inport,packet.next.srcip) self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src) #nandan: getting source ip address from the packetIn #myPacketInSrcIP= packet.next.srcip #myPacketInSrcEth= packet.src #myPacketInDstIP= packet.next.dstip #myPacketInDstEth= packet.dst #print "switcID: "+str(dpid)+" ,Port: "+str(event.port)+" ,MAC address: "+str(myPacketInSrcEth)+" ,SrcIP: "+ str(myPacketInSrcIP)+", Dst Mac: "+str(myPacketInDstEth)+", Dst IP: "+str(myPacketInDstEth) # Try to forward dstaddr = packet.next.dstip if dstaddr in self.arpTable[dpid]: # We have info about what port to send it out on... prt = self.arpTable[dpid][dstaddr].port mac = self.arpTable[dpid][dstaddr].mac if prt == inport: log.warning("%i %i not sending packet for %s back out of the " "input port" % (dpid, inport, dstaddr)) else: log.debug("%i %i installing flow for %s => %s out port %i" % (dpid, inport, packet.next.srcip, dstaddr, prt)) actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port = prt)) if self.wide: match = of.ofp_match(dl_type = packet.type, nw_dst = dstaddr) else: match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=match) event.connection.send(msg.pack()) elif self.arp_for_unknowns: # We don't know this destination. # First, we track this buffer so that we can try to resend it later # if we learn the destination, second we ARP for the destination, # which should ultimately result in it responding and us learning # where it is # Add to tracked buffers if (dpid,dstaddr) not in self.lost_buffers: self.lost_buffers[(dpid,dstaddr)] = [] bucket = self.lost_buffers[(dpid,dstaddr)] entry = (time.time() + MAX_BUFFER_TIME,event.ofp.buffer_id,inport) bucket.append(entry) while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0] # Expire things from our outstanding ARP list... self.outstanding_arps = {k:v for k,v in self.outstanding_arps.iteritems() if v > time.time()} # Check if we've already ARPed recently if (dpid,dstaddr) in self.outstanding_arps: # Oop, we've already done this one recently. return # And ARP... self.outstanding_arps[(dpid,dstaddr)] = time.time() + 4 r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.hwlen = 6 r.protolen = r.protolen r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = packet.src r.protosrc = packet.next.srcip e = ethernet(type=ethernet.ARP_TYPE, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport, r.protodst, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) elif isinstance(packet.next, arp): a = packet.next log.debug("%i %i ARP %s %s => %s", dpid, inport, {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), a.protosrc, a.protodst) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: # Learn or update port/MAC info if a.protosrc in self.arpTable[dpid]: if self.arpTable[dpid][a.protosrc] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid,inport,a.protosrc) if self.wide: # Make sure we don't have any entries with the old info... msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.match.dl_type = ethernet.IP_TYPE msg.match.nw_dst = a.protosrc event.connection.send(msg) else: log.debug("%i %i learned %s", dpid,inport,a.protosrc) self.arpTable[dpid][a.protosrc] = Entry(inport, packet.src) # Send any waiting packets... self._send_lost_buffers(dpid, a.protosrc, packet.src, inport) if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in self.arpTable[dpid]: # We have an answer... if not self.arpTable[dpid][a.protodst].isExpired(): # .. and it's relatively current, so we'll reply ourselves r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.arpTable[dpid][a.protodst].mac e = ethernet(type=packet.type, src=dpid_to_mac(dpid), dst=a.hwsrc) e.set_payload(r) log.debug("%i %i answering ARP for %s" % (dpid, inport, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return # Didn't know how to answer or otherwise handle this ARP, so just flood it log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode, 'op:%i' % (a.opcode,)), a.protosrc, a.protodst)) msg = of.ofp_packet_out(in_port = inport, data = event.ofp, action = of.ofp_action_output(port = of.OFPP_FLOOD)) event.connection.send(msg)
def _handle_PacketIn(self, event): log.debug("FUNCTION: _handle_PacketIn") packet = event.parsed connection = event.connection inport = event.port # Handle LLDP or Ipv6 packets if packet.type == packet.LLDP_TYPE or packet.type == packet.IPV6_TYPE: log.info("Received LLDP or IPv6 Packet...") # Handle ARP packets elif packet.type == packet.ARP_TYPE: log.debug("Received ARP Packet") response = packet.payload # Handle ARP reply if response.opcode == response.REPLY: log.debug("ARP REPLY Received") if response.protosrc not in self.SERVERS.keys(): # Adding the servers' MAC addresses and port numbers to the SERVERS dictionary if they're not # there already self.SERVERS[IPAddr(response.protosrc)] = {'server_mac': EthAddr(response.hwsrc), 'port': inport} # Handle ARP request elif response.opcode == response.REQUEST: log.debug("ARP REQUEST Received") if response.protosrc not in self.SERVERS.keys() and response.protosrc not in self.CLIENTS.keys(): # Indexing the client IP, mac and port number in a forwarding table self.CLIENTS[response.protosrc] = {'client_mac': EthAddr(packet.payload.hwsrc), 'port': inport} if response.protosrc in self.CLIENTS.keys() and response.protodst == self.LOADBALANCER_IP: log.info("Client %s sent ARP req to LB %s" % (response.protosrc, response.protodst)) self.send_arp_reply(packet, connection, inport) elif response.protosrc in self.SERVERS.keys() and response.protodst in self.CLIENTS.keys(): log.info("Server %s sent ARP req to client" % response.protosrc) self.send_arp_reply(packet, connection, inport) else: log.info("Invalid ARP request") # Handle IPv4 packets elif packet.type == packet.IP_TYPE: log.debug("Received IP Packet from %s" % packet.next.srcip) # Handle Requests from Clients to Servers # Install flow rule Client -> Server if (packet.next.dstip == self.LOADBALANCER_IP) and (packet.next.srcip not in self.SERVERS.keys()): self.update_lb_mapping(packet.next.srcip) client_ip = packet.payload.srcip server_ip = self.LOADBALANCER_MAP.get(packet.next.srcip) outport = self.SERVERS[server_ip].get('port') self.install_flow_rule_client_to_server(event, connection, outport, client_ip, server_ip) eth = ethernet() #Creating ethernet frame eth.type = eth.IP_TYPE eth.dst = self.SERVERS[server_ip].get('server_mac') eth.src = LOADBALANCER_MAC eth.set_payload(packet.next) # Send the first packet (which was sent to the controller from the switch) # to the chosen server, so there is no packetloss msg = of.ofp_packet_out() msg.data = eth.pack() msg.in_port = inport msg.actions.append(of.ofp_action_dl_addr.set_src(LOADBALANCER_MAC)) msg.actions.append(of.ofp_action_dl_addr.set_dst(self.SERVERS[server_ip].get('server_mac'))) msg.actions.append(of.ofp_action_nw_addr.set_src(client_ip)) msg.actions.append(of.ofp_action_nw_addr.set_dst(server_ip)) msg.actions.append(of.ofp_action_output(port=outport)) connection.send(msg) # Handle traffic from Server to Client # Install flow rule Client <- Server elif packet.next.dstip in self.CLIENTS.keys(): # server to client log.info("Installing flow rule from Server -> Client") if packet.next.srcip in self.SERVERS.keys(): server_ip = packet.next.srcip client_ip = self.LOADBALANCER_MAP.keys()[ list(self.LOADBALANCER_MAP.values()).index(packet.next.srcip)] outport = self.CLIENTS[client_ip].get('port') self.install_flow_rule_server_to_client(connection, outport, server_ip, client_ip) eth = ethernet() #Creating ethernet frame eth.type = eth.IP_TYPE eth.dst = self.SERVERS[server_ip].get('server_mac') eth.src = LOADBALANCER_MAC eth.set_payload(packet.next) # Send the first packet (which was sent to the controller from the switch) # to the chosen server, so there is no packetloss msg = of.ofp_packet_out() msg.data = eth.pack() msg.in_port = inport msg.actions.append(of.ofp_action_dl_addr.set_src(LOADBALANCER_MAC)) msg.actions.append(of.ofp_action_dl_addr.set_dst(self.CLIENTS[client_ip].get('client_mac'))) msg.actions.append(of.ofp_action_nw_addr.set_src(self.LOADBALANCER_IP)) msg.actions.append(of.ofp_action_nw_addr.set_dst(client_ip)) msg.actions.append(of.ofp_action_output(port=outport)) self.connection.send(msg) else: log.info("Unknown Packet type: %s" % packet.type) return return
class arp(packet_base): "ARP/RARP packet struct" MIN_LEN = 28 HW_TYPE_ETHERNET = 1 PROTO_TYPE_IP = 0x0800 # OPCODES REQUEST = 1 # ARP REPLY = 2 # ARP REV_REQUEST = 3 # RARP REV_REPLY = 4 # RARP def __init__(self, raw=None, prev=None, **kw): packet_base.__init__(self) self.prev = prev self.hwtype = arp.HW_TYPE_ETHERNET self.prototype = arp.PROTO_TYPE_IP self.hwsrc = ETHER_ANY self.hwdst = ETHER_ANY self.hwlen = 6 self.opcode = 0 self.protolen = 4 self.protosrc = IP_ANY self.protodst = IP_ANY self.next = b'' if raw is not None: self.parse(raw) self._init(kw) def parse(self, raw): assert isinstance(raw, bytes) self.next = None # In case of unfinished parsing self.raw = raw dlen = len(raw) if dlen < arp.MIN_LEN: self.msg( '(arp parse) warning IP packet data too short to parse header: data len %u' % dlen) return (self.hwtype, self.prototype, self.hwlen, self.protolen,self.opcode) =\ struct.unpack('!HHBBH', raw[:8]) if self.hwtype != arp.HW_TYPE_ETHERNET: self.msg('(arp parse) hw type unknown %u' % self.hwtype) if self.hwlen != 6: self.msg('(arp parse) unknown hw len %u' % self.hwlen) else: self.hwsrc = EthAddr(raw[8:14]) self.hwdst = EthAddr(raw[18:24]) if self.prototype != arp.PROTO_TYPE_IP: self.msg('(arp parse) proto type unknown %u' % self.prototype) if self.protolen != 4: self.msg('(arp parse) unknown proto len %u' % self.protolen) else: self.protosrc = IPAddr(struct.unpack('!I', raw[14:18])[0]) self.protodst = IPAddr(struct.unpack('!I', raw[24:28])[0]) self.next = raw[28:] self.parsed = True def hdr(self, payload): buf = struct.pack('!HHBBH', self.hwtype, self.prototype, self.hwlen, self.protolen, self.opcode) if type(self.hwsrc) == bytes: buf += self.hwsrc else: buf += self.hwsrc.toRaw() if type(self.protosrc) is IPAddr: buf += struct.pack('!I', self.protosrc.toUnsigned()) else: buf += struct.pack('!I', self.protosrc) if type(self.hwdst) == bytes: buf += self.hwdst else: buf += self.hwdst.toRaw() if type(self.protodst) is IPAddr: buf += struct.pack('!I', self.protodst.toUnsigned()) else: buf += struct.pack('!I', self.protodst) return buf def _to_str(self): op = str(self.opcode) eth_type = None # Ethernet if hasattr(self.prev, 'type'): eth_type = self.prev.type # Vlan elif hasattr(self.prev, 'eth_type'): eth_type = self.prev.eth_type else: self.err('(arp) unknown datalink type') eth_type = ethernet.ARP_TYPE if eth_type == ethernet.ARP_TYPE: if self.opcode == arp.REQUEST: op = "REQUEST" elif self.opcode == arp.REPLY: op = "REPLY" elif eth_type == ethernet.RARP_TYPE: if self.opcode == arp.REV_REQUEST: op = "REV_REQUEST" elif self.opcode == arp.REV_REPLY: op = "REV_REPLY" s = "[ARP {0} hw:{1} p:{2} {3}>{4} {5}>{6}]".format( op, self.hwtype, self.prototype, EthAddr(self.hwsrc), EthAddr(self.hwdst), IPAddr(self.protosrc), IPAddr(self.protodst)) return s
def match_dst_ip(msg, ip_string): msg.match.dl_type = 0x800 msg.match.nw_dst = IPAddr(ip_string)
log = core.getLogger() #flow3: switch2 = 0000000000000003 flow2msg = of.ofp_flow_mod() flow2msg.cookie = 0 flow2msg.match.in_port = 2 flow2msg.match.dl_type = 0x0800 flow2msg.match.nw_src = IPAddr("192.168.1.10") # ACTIONS--------------------------------- flow2out = of.ofp_action_output(port=1) flow2srcIP = of.ofp_action_nw_addr.set_src(IPAddr("10.0.0.2")) flow2srcMAC = of.ofp_action_dl_addr.set_src(EthAddr("00:00:00:00:00:04")) flow2dstMAC = of.ofp_action_dl_addr.set_dst(EthAddr("00:00:00:00:00:01")) flow2msg.actions = [flow2srcIP, flow2srcMAC, flow2dstMAC, flow2out] #flow4:
def __init__(self, ip, mac, port): self.ip = IPAddr(ip) self.mac = EthAddr(mac) self.port = port self.conn = 0 self.cliList = []
from pox.lib.addresses import IPAddr, EthAddr import time import hashlib import re import sys log = core.getLogger() IDLE_TOUT = 5 #seconds HARD_TOUT = 1000 #seconds #Redirect stdout to controller_results.txt #sys.stdout = open("controller_results.txt", "w") #HS load balancer LB_IP = IPAddr('10.1.0.254') LB_MAC = EthAddr('00:00:00:00:FE:00') #HS load balancer class LoadBalancer(EventMixin): class Server: def __init__(self, ip, mac, port): self.ip = IPAddr(ip) self.mac = EthAddr(mac) self.port = port self.conn = 0 self.cliList = [] def __str__(self): return ','.join(
class ipv4(packet_base): "IP packet struct" MIN_LEN = 20 IPv4 = 4 ICMP_PROTOCOL = 1 TCP_PROTOCOL = 6 UDP_PROTOCOL = 17 IGMP_PROTOCOL = 2 SINE_PROTOCOL = 160 #DJ++ 20131204 10100000 DF_FLAG = 0x02 MF_FLAG = 0x01 ip_id = int(time.time()) def __init__(self, raw=None, prev=None, **kw): packet_base.__init__(self) self.prev = prev self.v = 4 self.hl = ipv4.MIN_LEN / 4 self.tos = 0 self.iplen = ipv4.MIN_LEN ipv4.ip_id = (ipv4.ip_id + 1) & 0xffff self.id = ipv4.ip_id self.flags = 0 self.frag = 0 self.ttl = 64 self.protocol = 0 self.csum = 0 self.srcip = IP_ANY self.dstip = IP_ANY self.next = b'' if raw is not None: self.parse(raw) self._init(kw) #for what? DJ 20131218 def __str__(self): s = "[IP+%s %s>%s (cs:%02x v:%s hl:%s l:%s t:%s)]" % ( ipproto_to_str(self.protocol), self.srcip, self.dstip, self.csum, self.v, self.hl, self.iplen, self.ttl) return s def parse(self, raw): assert isinstance(raw, bytes) self.raw = raw dlen = len(raw) if dlen < ipv4.MIN_LEN: self.msg('warning IP packet data too short to parse header: data len %u' % (dlen,)) return (vhl, self.tos, self.iplen, self.id, self.frag, self.ttl, self.protocol, self.csum, self.srcip, self.dstip) \ = struct.unpack('!BBHHHBBHII', raw[:ipv4.MIN_LEN]) self.v = vhl >> 4 self.hl = vhl & 0x0f self.flags = self.frag >> 13 self.frag = self.frag & 0x1fff if self.v != ipv4.IPv4: self.msg('(ip parse) warning IP version %u not IPv4' % self.v) return elif self.hl < 5: self.msg('(ip parse) warning IP header %u longer than len %u' \ % (self.hl, self.iplen)) return elif self.iplen < ipv4.MIN_LEN: self.msg('(ip parse) warning invalid IP len %u' % self.iplen) return elif (self.hl * 4) >= self.iplen or (self.hl * 4) > dlen: self.msg('(ip parse) warning IP header %u longer than len %u' \ % (self.hl, self.iplen)) return self.dstip = IPAddr(self.dstip) self.srcip = IPAddr(self.srcip) # At this point, we are reasonably certain that we have an IP # packet self.parsed = True length = self.iplen if length > dlen: length = dlen # Clamp to what we've got if self.protocol == ipv4.UDP_PROTOCOL: self.next = udp(raw=raw[self.hl*4:length], prev=self) elif self.protocol == ipv4.TCP_PROTOCOL: self.next = tcp(raw=raw[self.hl*4:length], prev=self) elif self.protocol == ipv4.ICMP_PROTOCOL: self.next = icmp(raw=raw[self.hl*4:length], prev=self) elif self.protocol == ipv4.IGMP_PROTOCOL: self.next = igmp(raw=raw[self.hl*4:length], prev=self) #DJ++ 20131204 elif self.protocol == ipv4.SINE_PROTOCOL: self.next = sine(raw=raw[self.hl*4:length], prev=self) elif dlen < self.iplen: self.msg('(ip parse) warning IP packet data shorter than IP len: %u < %u' % (dlen, self.iplen)) else: self.next = raw[self.hl*4:length] if isinstance(self.next, packet_base) and not self.next.parsed: self.next = raw[self.hl*4:length] def checksum(self): data = struct.pack('!BBHHHBBHII', (self.v << 4) + self.hl, self.tos, self.iplen, self.id, (self.flags << 13) | self.frag, self.ttl, self.protocol, 0, self.srcip.toUnsigned(), self.dstip.toUnsigned()) return checksum(data, 0) def hdr(self, payload): self.iplen = self.hl * 4 + len(payload) self.csum = self.checksum() return struct.pack('!BBHHHBBHII', (self.v << 4) + self.hl, self.tos, self.iplen, self.id, (self.flags << 13) | self.frag, self.ttl, self.protocol, self.csum, self.srcip.toUnsigned(), self.dstip.toUnsigned())
def _handle_openflow_PacketIn(self, event): dpid = event.connection.dpid inport = event.port packet = event.parsed global set_Timer global defendDDOS global blockPort timerSet = False global diction def preventing(): global diction global set_Timer if not set_Timer: set_Timer = True if len(diction) == 0: print("Empty diction ", str(event.connection.dpid), str(event.port)) diction[event.connection.dpid] = {} diction[event.connection.dpid][event.port] = 1 elif event.connection.dpid not in diction: diction[event.connection.dpid] = {} diction[event.connection.dpid][event.port] = 1 else: if event.connection.dpid in diction: if event.port in diction[event.connection.dpid]: temp_count = 0 temp_count = diction[event.connection.dpid][event.port] temp_count = temp_count + 1 diction[event.connection.dpid][event.port] = temp_count #print "*****************************************************************************************************************************************************************************" print "dpid port and its packet count: ", str( event.connection.dpid), str( diction[event.connection.dpid]), str( diction[event.connection.dpid][event.port]) #print "*****************************************************************************************************************************************************************************" else: diction[event.connection.dpid][event.port] = 1 def _timer_func(): global diction global set_Timer if set_Timer == True: for k, v in diction.iteritems(): for i, j in v.iteritems(): if j >= 5: print "_____________________________________________________________________________________________" print "\n DDOS DETECTED \n" print "\n", str(diction) print "\n", datetime.datetime.now( ), ": BLOCKED PORT NUMBER : ", str( i), " OF SWITCH ID: ", str(k) print "\n___________________________________________________________________________________________" os._exit(0) dpid = k msg = of.ofp_packet_out(in_port=i) core.openflow.sendToDPID(dpid, msg) diction = {} if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return if dpid not in self.arpTable: self.arpTable[dpid] = {} for fake in self.fakeways: self.arpTable[dpid][IPAddr(fake)] = Entry( of.OFPP_NONE, dpid_to_mac(dpid)) if packet.type == ethernet.LLDP_TYPE: return if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip, packet.next.dstip) ent_obj.collectStats(event.parsed.next.dstip) print "Entropy : ", str(ent_obj.value) if ent_obj.value < 1.0: preventing() if timerSet is not True: Timer(1, _timer_func, recurring=True) timerSet = False else: timerSet = False self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport) if packet.next.srcip in self.arpTable[dpid]: if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, packet.next.srcip) if self.wide: msg = of.ofp_flow_mod(command=of.OFPFC_DELETE) msg.match.nw_dst = packet.next.srcip msg.match.dl_type = ethernet.IP_TYPE event.connection.send(msg) else: log.debug("%i %i learned %s", dpid, inport, packet.next.srcip) self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src) dstaddr = packet.next.dstip if dstaddr in self.arpTable[dpid]: prt = self.arpTable[dpid][dstaddr].port mac = self.arpTable[dpid][dstaddr].mac if prt == inport: log.warning( "%i %i not sending packet for %s back out of the " "input port" % (dpid, inport, dstaddr)) else: log.debug( "%i %i installing flow for %s => %s out port %i" % (dpid, inport, packet.next.srcip, dstaddr, prt)) actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port=prt)) if self.wide: match = of.ofp_match(dl_type=packet.type, nw_dst=dstaddr) else: match = of.ofp_match.from_packet(packet, inport) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=match) event.connection.send(msg.pack()) elif self.arp_for_unknowns: if (dpid, dstaddr) not in self.lost_buffers: self.lost_buffers[(dpid, dstaddr)] = [] bucket = self.lost_buffers[(dpid, dstaddr)] entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id, inport) bucket.append(entry) while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0] self.outstanding_arps = { k: v for k, v in self.outstanding_arps.iteritems() if v > time.time() } if (dpid, dstaddr) in self.outstanding_arps: return self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4 r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.hwlen = 6 r.protolen = r.protolen r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = packet.src r.protosrc = packet.next.srcip e = ethernet(type=ethernet.ARP_TYPE, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport, r.protodst, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) elif isinstance(packet.next, arp): a = packet.next log.debug("%i %i ARP %s %s => %s", dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: if a.protosrc in self.arpTable[dpid]: if self.arpTable[dpid][a.protosrc] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, a.protosrc) if self.wide: msg = of.ofp_flow_mod( command=of.OFPFC_DELETE) msg.match.dl_type = ethernet.IP_TYPE msg.match.nw_dst = a.protosrc event.connection.send(msg) else: log.debug("%i %i learned %s", dpid, inport, a.protosrc) self.arpTable[dpid][a.protosrc] = Entry( inport, packet.src) self._send_lost_buffers(dpid, a.protosrc, packet.src, inport) if a.opcode == arp.REQUEST: if a.protodst in self.arpTable[dpid]: if not self.arpTable[dpid][ a.protodst].isExpired(): r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.arpTable[dpid][ a.protodst].mac e = ethernet(type=packet.type, src=dpid_to_mac(dpid), dst=a.hwsrc) e.set_payload(r) log.debug("%i %i answering ARP for %s" % (dpid, inport, r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output( port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst)) msg = of.ofp_packet_out( in_port=inport, data=event.ofp, action=of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(msg)
def _handle_PacketIn(self, event): dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return if dpid not in self.ip_mac_port: self.ip_mac_port[dpid] = {} for fake in self.fakeways: self.ip_mac_port[dpid][IPAddr(fake)] = Entry( of.OFPP_NONE, dpid_to_mac(dpid)) if packet.type == ethernet.LLDP_TYPE: return if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip, packet.next.dstip) self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport) if packet.next.srcip in self.ip_mac_port[dpid]: if self.ip_mac_port[dpid][packet.next.srcip] != (inport, packet.src): log.debug("%i %i RE-learned %s", dpid, inport, packet.next.srcip) else: #log.info("%i %i learned %s", dpid,inport,str(packet.next.srcip)) log.info("switch %i learned %s from input port %i", dpid, str(packet.next.srcip), inport) self.ip_mac_port[dpid][packet.next.srcip] = Entry( inport, packet.src) dstaddr = packet.next.dstip if dstaddr in self.ip_mac_port[dpid]: prt = self.ip_mac_port[dpid][dstaddr].port mac = self.ip_mac_port[dpid][dstaddr].mac print dstaddr if prt == inport: log.warning( "%i %i not sending packet for %s back out of the " + "input port" % (dpid, inport, str(dstaddr))) else: log.debug( "%i %i installing flow for %s => %s out port %i" % (dpid, inport, packet.next.srcip, dstaddr, prt)) if event.ofp.buffer_id == None: bid = None else: bid = event.ofp.buffer_id ip_packet = packet.find("ipv4") if ip_packet != None: if ip_packet.protocol == 1: actions3 = [] actions3.append(of.ofp_action_dl_addr.set_dst(mac)) #actions3.append(of.ofp_action_output(port = prt)) actions3.append( of.ofp_action_enqueue(port=prt, queue_id=1)) match3 = of.ofp_match.from_packet(packet, inport) match3.dl_type = 0x800 match3.nw_proto = 1 match3.dl_src = None msg3 = of.ofp_flow_mod( command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=bid, actions=actions3, priority=30, match=match3) event.connection.send(msg3.pack()) print "into queue 1" elif ip_packet.protocol == 17 or ip_packet.protocol == 6: udp_packet = packet.find("udp") if udp_packet == None: udp_packet = packet.find("tcp") if ip_packet.dstip == IPAddr( "172.16.0.3" ) and udp_packet.dstport == 5001: actions5 = [] actions5.append( of.ofp_action_dl_addr.set_dst(mac)) #actions5.append(of.ofp_action_output(port = prt)) actions5.append( of.ofp_action_enqueue(port=prt, queue_id=3)) match5 = of.ofp_match.from_packet( packet, inport) match5.dl_type = 0x800 match5.nw_proto = 17 match5.nw_dst = IPAddr("172.16.0.3") match5.tp_dst = 5001 match5.dl_src = None msg5 = of.ofp_flow_mod( command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=bid, actions=actions5, priority=43, match=match5) event.connection.send(msg5.pack()) print "privillaged user into queue 3" elif ip_packet.tos == 0: actions2 = [] actions2.append( of.ofp_action_dl_addr.set_dst(mac)) #actions2.append(of.ofp_action_output(port = prt)) actions2.append(of.ofp_action_nw_tos(224)) actions2.append( of.ofp_action_enqueue(port=prt, queue_id=2)) match2 = of.ofp_match.from_packet( packet, inport) match2.dl_type = 0x800 if udp_packet != None: match2.nw_proto = 17 else: match2.nw_proto = 6 match2.dl_src = None msg2 = of.ofp_flow_mod( command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=bid, actions=actions2, priority=42, match=match2) event.connection.send(msg2.pack()) print "into queue 2" else: actions1 = [] actions1.append( of.ofp_action_dl_addr.set_dst(mac)) #actions1.append(of.ofp_action_output(port = prt)) actions1.append( of.ofp_action_enqueue(port=prt, queue_id=2)) match1 = of.ofp_match.from_packet( packet, inport) match1.dl_type = 0x800 match1.nw_tos = 224 match1.dl_src = None msg1 = of.ofp_flow_mod( command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=bid, actions=actions1, priority=42, match=match1) event.connection.send(msg1.pack()) print "into queue 2 dscp tagged" else: actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port=prt)) match4 = of.ofp_match.from_packet(packet, inport) match4.dl_src = None # Wildcard source MAC msg = of.ofp_flow_mod( command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=bid, actions=actions, priority=20, match=match4) event.connection.send(msg.pack()) elif self.arp_for_unknowns: if (dpid, dstaddr) not in self.lost_buffers: self.lost_buffers[(dpid, dstaddr)] = [] bucket = self.lost_buffers[(dpid, dstaddr)] entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id, inport) bucket.append(entry) while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0] self.outstanding_arps = { k: v for k, v in self.outstanding_arps.iteritems() if v > time.time() } if (dpid, dstaddr) in self.outstanding_arps: return self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4 r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.hwlen = 6 r.protolen = r.protolen r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = packet.src r.protosrc = packet.next.srcip e = ethernet(type=ethernet.ARP_TYPE, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport, str(r.protodst), str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) elif isinstance(packet.next, arp): a = packet.next log.debug("%i %i ARP %s %s => %s", dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc), str(a.protodst)) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: # Learn or update port/MAC info if a.protosrc in self.ip_mac_port[dpid]: if self.ip_mac_port[dpid][a.protosrc] != ( inport, packet.src): log.debug("%i %i RE-learned %s", dpid, inport, str(a.protosrc)) else: log.info("switch %i learned %s from input port %i", dpid, str(a.protosrc), inport) self.ip_mac_port[dpid][a.protosrc] = Entry( inport, packet.src) # Send any waiting packets... self._send_lost_buffers(dpid, a.protosrc, packet.src, inport) if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in self.ip_mac_port[dpid]: # We have an answer... if not self.ip_mac_port[dpid][ a.protodst].isExpired(): # .. and it's relatively current, so we'll reply ourselves r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.ip_mac_port[dpid][ a.protodst].mac e = ethernet(type=packet.type, src=dpid_to_mac(dpid), dst=a.hwsrc) e.set_payload(r) #log.debug("%i %i answering ARP for %s" % (dpid, inport,str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output( port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return # Didn't know how to answer or otherwise handle this ARP, so just flood it log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc), str(a.protodst))) msg = of.ofp_packet_out( in_port=inport, data=event.ofp, action=of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(msg)
class PCap(object): use_select = False # Falls back to non-select @staticmethod def get_devices(): def ip(addr): if addr is None: return None return IPAddr(addr, networkOrder=True) def ip6(addr): if addr is None: return None return IPAddr6.from_raw(addr) def link(addr): if addr is None: return None if len(addr) != 6: return None return EthAddr(addr) devs = pcapc.findalldevs() out = {} for d in devs: addrs = {} n = {"desc": d[1], "addrs": addrs} out[d[0]] = n for a in d[2]: if a[0] == "AF_INET": na = {} addrs[a[0]] = na na["addr"] = ip(a[1]) na["netmask"] = ip(a[2]) na["broadaddr"] = ip(a[3]) na["dstaddr"] = ip(a[4]) elif a[0] == "AF_INET6": na = {} addrs[a[0]] = na na["addr"] = ip6(a[1]) na["netmask"] = ip6(a[2]) na["broadaddr"] = ip6(a[3]) na["dstaddr"] = ip6(a[4]) elif a[0] == "AF_LINK": na = {} addrs[a[0]] = na na["addr"] = link(a[1]) na["netmask"] = link(a[2]) na["broadaddr"] = link(a[3]) na["dstaddr"] = link(a[4]) elif a[0] == "AF_PACKET": addrs[a[0]] = {"addr": link(a[1])} elif a[0] == "ethernet": addrs[a[0]] = {"addr": link(a[1])} return out @staticmethod def get_device_names(): return [d[0] for d in pcapc.findalldevs()] def __init__( self, device=None, promiscuous=True, period=10, start=True, callback=None, filter=None, use_bytearray=False, **kw ): """ Initialize this instance use_bytearray: specifies capturing to bytearray buffers instead of bytes """ if filter is not None: self.deferred_filter = (filter,) else: self.deferred_filter = None self.packets_received = 0 self.packets_dropped = 0 self._thread = None self.pcap = None self.promiscuous = promiscuous self.device = None self.use_bytearray = use_bytearray self.period = period self.netmask = IPAddr("0.0.0.0") self._quitting = False self.addresses = {} if callback is None: self.callback = self.__class__._handle_rx else: self.callback = callback for k, v in kw.items(): assert not hasattr(self, k) setattr(self, k, v) if device is not None: self.open(device) if self.pcap is not None: if start: self.start() def _handle_rx(self, data, sec, usec, length): pass def open(self, device, promiscuous=None, period=None, incoming=True, outgoing=False): assert self.device is None self.addresses = self.get_devices()[device]["addrs"] if "AF_INET" in self.addresses: self.netmask = self.addresses["AF_INET"].get("netmask") if self.netmask is None: self.netmask = IPAddr("0.0.0.0") # print "NM:",self.netmask # print self.addresses['AF_LINK']['addr'] self.device = device if period is not None: self.period = period if promiscuous is not None: self.promiscuous = promiscuous self.pcap = pcapc.open_live(device, 65535, 1 if self.promiscuous else 0, self.period) pcapc.setdirection(self.pcap, incoming, outgoing) self.packets_received = 0 self.packets_dropped = 0 if self.deferred_filter is not None: self.set_filter(*self.deferred_filter) self.deferred_filter = None def set_direction(self, incoming, outgoing): pcapc.setdirection(self._pcap, incoming, outgoing) def set_nonblocking(self, nonblocking=True): pcapc.setnonblock(self._pcap, 1 if nonblocking else 0) def set_blocking(self, blocking=True): self.set_nonblocking(nonblocking=not blocking) @property def blocking(self): return False if pcapc.getnonblock(self._pcap) else True @blocking.setter def blocking(self, value): self.set_blocking(value) def next_packet(self, allow_threads=True): """ Get next packet Returns tuple with: data, timestamp_seconds, timestamp_useconds, total length, and the pcap_next_ex return value -- 1 is success """ return pcapc.next_ex(self._pcap, bool(self.use_bytearray), allow_threads) def _select_thread_func(self): try: import select fd = [self.fileno()] except: # Fall back self._thread_func() return self.blocking = False while not self._quitting: rr, ww, xx = select.select(fd, [], fd, 2) if xx: # Apparently we're done here. break if rr: r = self.next_packet(allow_threads=False) if r[-1] == 0: continue if r[-1] == 1: self.callback(self, r[0], r[1], r[2], r[3]) else: break self._quitting = False self._thread = None def _thread_func(self): while not self._quitting: pcapc.dispatch(self.pcap, 100, self.callback, self, bool(self.use_bytearray), True) self.packets_received, self.packets_dropped = pcapc.stats(self.pcap) self._quitting = False self._thread = None def _handle_GoingDownEvent(self, event): self.close() def start(self): assert self._thread is None from pox.core import core core.addListeners(self, weak=True) if self.use_select: self._thread = Thread(target=self._select_thread_func) else: self._thread = Thread(target=self._thread_func) # self._thread.daemon = True self._thread.start() def stop(self): t = self._thread if t is not None: self._quitting = True pcapc.breakloop(self.pcap) t.join() def close(self): if self.pcap is None: return self.stop() pcapc.close(self.pcap) self.pcap = None def __del__(self): self.close() @property def _pcap(self): if self.pcap is None: raise RuntimeError("PCap object not open") return self.pcap def inject(self, data): if isinstance(data, pkt.ethernet): data = data.pack() if not isinstance(data, (bytes, bytearray)): data = bytes(data) # Give it a try... return pcapc.inject(self.pcap, data) def set_filter(self, filter, optimize=True): if self.pcap is None: self.deferred_filter = (filter, optimize) return if isinstance(filter, str): filter = Filter(filter, optimize, self.netmask.toSignedN(), pcap_obj=self) elif isinstance(filter, Filter): pass else: raise RuntimeError("Filter must be string or Filter object") pcapc.setfilter(self.pcap, filter._pprogram) def fileno(self): if self.pcap is None: raise RuntimeError("PCap object not open") r = pcapc.get_selectable_fd(self.pcap) if r == -1: raise RuntimeError("Selectable FD not available") return r def __str__(self): return "PCap(device=%s)" % (self.device)
from pox.core import core import pox.openflow.libopenflow_01 as of from pox.lib.packet.ethernet import ethernet, ETHER_BROADCAST from pox.lib.packet.ipv4 import ipv4 from pox.lib.packet.arp import arp from pox.lib.packet.icmp import icmp import pox.lib.packet as pkt from pox.lib.addresses import IPAddr, EthAddr import struct import time log = core.getLogger() DEFAULT_GATEWAY = 1 validIP = [IPAddr('10.0.1.1'), IPAddr('10.0.1.2'), IPAddr('10.0.1.3'), IPAddr('10.0.2.1'), IPAddr('10.0.2.2'), IPAddr('10.0.2.3'), IPAddr('10.0.2.4')] subnet1 = ['10.0.1.1', '10.0.1.2', '10.0.1.3'] subnet2 = ['10.0.2.1', '10.0.2.2', '10.0.2.3', '10.0.2.4'] class router(object): def __init__(self): log.debug('router registered') # The dict for all routers, desginated by dpid # In each dict, each component is also a dict indexed by dpid self.arpTable = {} self.arpWait = {} self.routingTable = {} self.connections = {} self.routerIP = {} core.openflow.addListeners(self) def _handle_GoingUpEvent(self, event): self.listenTo(core.openflow)
def handle_IPPacket(self, event): is_src_router = (event.ofp.in_port == of.OFPP_LOCAL) if event.parsed.next.srcip.inNetwork(NON_ROUTABLE_SUBNET, NON_ROUTABLE_NETMASK): print "source ip is not routable" return if event.parsed.src != self.bridge_mac and not self.check_access( event.parsed.src): print "%s is not permmited" % (str(event.parsed.src)) return if event.parsed.next.dstip.inNetwork(NON_ROUTABLE_SUBNET, NON_ROUTABLE_NETMASK): print "destination is not routable" return is_src_local = event.parsed.next.srcip.inNetwork( ROUTABLE_SUBNET, ROUTABLE_NETMASK) or event.parsed.next.srcip.inNetwork( INIT_SUBNET, INIT_NETMASK) if is_src_local and (event.parsed.next.srcip.toUnsigned( networkOrder=False) & 0x3) == 1: if not self.get_DHCP_mapping().is_valid_mapping( event.parsed.next.srcip, event.parsed.src) and event.parsed.src != self.bridge_mac: print "received packet from unrecorded mac address" return if event.parsed.next.dstip.inNetwork(MULTICAST_SUBNET, MULTICAST_NETMASK): print "multicast" if event.parsed.next.dstip in self.multicast_ip: action = of.ofp_action_output(port=of.OFPP_FLOOD) command = of.OFPFC_ADD self.send_flow_modification(event, command, [action], timeout=30) # check if broadcast. Change nw_dst to 10.2.255.255 if event.parsed.next.dstip.inNetwork( ROUTABLE_SUBNET, ROUTABLE_NETMASK) and ( (event.parsed.next.dstip.toUnsigned(networkOrder=False) & 0x3) == 0x3): print "broadcast IP" nw_new = of.ofp_action_nw_addr() nw_new.type = of.OFPAT_SET_NW_DST nw_new.nw_addr = IPAddr("10.2.255.255") out = of.ofp_action_output( port=of.OFPP_IN_PORT if event.ofp.in_port == 0 else 0) actions = [out, nw_new] command = of.OFPFC_ADD self.send_flow_modification(event, command, actions, timeout=30) dst_port = 0 if event.parsed.next.dstip.inNetwork( ROUTABLE_SUBNET, ROUTABLE_NETMASK) and ( (event.parsed.next.dstip.toUnsigned(networkOrder=False) & 0x01) == 0x01): dst_port = 1 else: dst_port = 0 actions = [] is_dst_local = event.parsed.next.dstip.inNetwork( ROUTABLE_SUBNET, ROUTABLE_NETMASK) or event.parsed.next.dstip.inNetwork( INIT_SUBNET, INIT_NETMASK) if is_dst_local and is_src_local and (dst_port != 0) and (not is_src_router): dst_mac = self.get_DHCP_mapping().get_mac(event.parsed.next.dstip) new_dl_src = of.ofp_action_dl_addr() new_dl_src.type = of.OFPAT_SET_DL_SRC new_dl_src.set_src(self.bridge_mac) actions.append(new_dl_src) new_dl_dst = of.ofp_action_dl_addr() new_dl_dst.type = of.OFPAT_SET_DL_DST new_dl_dst.set_dst(dst_mac) actions.append(new_dl_dst) out = of.ofp_action_output(port=of.OFPP_FLOOD) actions.append(out) if 0 < event.ofp.in_port and event.ofp.in_port < of.OFPP_MAX: out_of_in = of.ofp_action_output(port=of.OFPP_IN_PORT) actions.append(out_of_in) command = of.OFPFC_ADD self.send_flow_modification(event, command, actions, timeout=30)
def sql_flow(event, query): dbmgr = DBManager(":memory:") #dbmgr = DBManager("testdb.db") #dbmgr.query("INSERT INTO person VALUES ('kamran','ali',30)") #dbmgr.query("INSERT INTO person VALUES ('yousaf','akhtar',50)") #dbmgr.query('INSERT INTO OF_table (MAC_src, MAC_dst, Action) VALUES ("00:00:00:00:00:05","00:00:00:00:00:01", "drop" )') dbmgr.query1(query) for row in dbmgr.query1("SELECT * FROM OF_table"): msg = of.ofp_flow_mod() if row[0] != None: msg.match.in_port = int(row[0]) # 2 if row[1] != None: msg.match.dl_src = EthAddr(row[1]) # EthAddr("01:02:03:04:05:06") if row[2] != None: msg.match.dl_dst = EthAddr(row[2]) # EthAddr("01:02:03:04:05:06") if row[3] != None: msg.match.dl_type = int(row[3]) # 0x800 if row[4] != None: msg.match.dl_vlan = int(row[4]) # 10 if row[5] != None: msg.match.dl_vlan_pcp = int( row[5]) # 100 value may vary from 0~255 if row[6] != None: msg.match.nw_src = IPAddr(row[6]) # "192.168.66.0/24" if row[7] != None: msg.match.nw_dst = IPAddr(row[7]) # "192.168.66.0/24" if row[8] != None: msg.match.nw_proto = int(row[8]) # 6 is for tcp if row[9] != None: msg.match.nw_tos = int(row[9]) # 3 # quality of service class if row[10] != None: msg.match.tp_src = int(row[10]) # 80 if row[11] != None: msg.match.tp_dst = int(row[11]) # 80 if row[12] != None: if row[12] == "flood" or row[12] == "FLOOD": msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) elif row[12] == "drop" or row[12] == "DROP": pass else: msg.actions.append(of.ofp_action_output(port=int(row[12]))) if row[13] == None: msg.idle_timeout = 1000 else: msg.idle_timeout = int(row[13]) # 1000 int if row[14] == None: msg.hard_timeout = 1000 else: msg.hard_timeout = int(row[14]) # 0 int if row[15] != None: msg.buffer_id = int(row[15]) # 2870 int if row[16] != None: msg.priority = int( row[16] ) # uint16_t priority, Priority level of flow entry 0 is highest priority event.connection.send(msg) #print "Flow is being deployed" log.info("SQL Flow Mode Query from sql module %s", dpidToStr(event.dpid))
def install_arp_rule(self, mac, ip, timeout): """Updates the ARP Responder with a new rule""" entry = arp.Entry(mac, static=True, flood=False) entry.timeout = timeout self.arp_table[IPAddr(ip)] = entry
def _handle_PacketIn(self, event): """ Handles packet in messages from the switch. """ etherFrame = event.parsed # This is the parsed packet data. if not etherFrame.parsed: log.warning("!LOG WARN! S1 : Ignoring incomplete packet") return packet_in = event.ofp # The actual ofp_packet_in message. # Add the new MAC into CAM table if str(etherFrame.src) not in self.mac_to_port: log.debug('!LOG! S1 : Adding %s into CAM, recv from %s' % (str(etherFrame.src), str(packet_in.in_port))) self.mac_to_port[str(etherFrame.src)] = packet_in.in_port # ARP if etherFrame.type == ethernet.ARP_TYPE: log.debug('!LOG! S1 : RECEIVED: EtherType -> ARP') self.ARP_Handler(etherFrame, packet_in) # IP elif etherFrame.type == ethernet.IP_TYPE: log.debug('!LOG! S1 : RECEIVED: EtherType -> IP') # Extract IP Packet from Ethernet Frame ip_packet = etherFrame.payload # Routable? destination_ip = str(ip_packet.dstip) routable = False for netaddr in self.routing_table: destination_network = netaddr if IPAddress(destination_ip) in IPNetwork(destination_network): log.debug('!LOG! S1 : PACKET IS ROUTABLE!') routable = True break if routable: # Destined for router if self.routing_table[str(destination_network)][ 'RouterInterface'] == destination_ip: if ip_packet.protocol == ipv4.ICMP_PROTOCOL: log.debug('!LOG! S1 : ICMP ECHO -> ROUTER INTERFACE') self.ICMP_Handler(etherFrame, packet_in) # Check if any there's any routable networks for the destination IP elif routable: # Route the packet to it's respective ports output_port = self.routing_table[destination_network][ 'Port'] # ARP if host MAC Address is not present if destination_ip not in self.arp_table: # Push frame to buffer self.buffer[destination_ip] = { 'IP_Packet': ip_packet, 'DestinationNetwork': destination_network } # Construct ARP Packet arp_request = arp() arp_request.opcode = arp.REQUEST arp_request.protosrc = IPAddr( self.routing_table[destination_network] ['RouterInterface']) arp_request.protodst = IPAddr(destination_ip) arp_request.hwsrc = EthAddr(self.arp_table[ self.routing_table[destination_network] ['RouterInterface']]) arp_request.hwdst = EthAddr('00:00:00:00:00:00') ether = ethernet() ether.type = ether.ARP_TYPE ether.src = EthAddr(self.arp_table[self.routing_table[ destination_network]['RouterInterface']]) ether.dst = EthAddr('FF:FF:FF:FF:FF:FF') ether.payload = arp_request self.resend_packet(ether, output_port) if destination_ip in self.arp_table: etherFrame.src = EthAddr(self.arp_table[ self.routing_table[destination_network] ['RouterInterface']]) etherFrame.dst = EthAddr( self.arp_table[destination_ip]) self.resend_packet(etherFrame, output_port) # ICMP Destination Unreachable for non-routable networks else: log.debug('!LOG! S1 : PACKET IS NOT ROUTABLE!') ethernet_frame = etherFrame ip_packet = etherFrame.payload icmp_request_packet = ip_packet.payload icmp_echo_reply_packet = icmp() icmp_echo_reply_packet.code = 0 icmp_echo_reply_packet.type = 3 icmp_echo_reply_packet.payload = icmp_request_packet.payload ip = ipv4() ip.srcip = ip_packet.dstip ip.dstip = ip_packet.srcip ip.protocol = ipv4.ICMP_PROTOCOL ip.payload = icmp_echo_reply_packet ether = ethernet() ether.type = ethernet.IP_TYPE ether.src = ethernet_frame.dst ether.dst = ethernet_frame.src ether.payload = ip self.resend_packet(ether, packet_in.in_port) log.debug("!LOG! S1 : ICMP DESTINATION UNREACHABLE SENT")
from pox.lib.packet.tcp import tcp from pox.lib.revent.pretend import pretend from pox.lib.packet.arp import arp #from pox.lib.revent.Anti_broadcast import Anti_broadcast from pox.lib.packet.icmp import icmp import time log = core.getLogger() # We don't want to flood immediately when a switch connects. FLOOD_DELAY = 5 special_sw=4 special_cache=9 CACHE_IP=IPAddr('172.16.0.1') CACHE_MAC=EthAddr('00:22:19:12:37:1b') class LearningSwitch (EventMixin): def __init__ (self, connection, transparent): # Switch we'll be adding L2 learning switch capabilities to self.connection = connection self.transparent = transparent # Our table self.macToPort = {} #USE THIS TABLE TO RECORD THE MUTICAST PACKET'S IP AND INPORT #our table match specified arp packet{srcMac:[dstip,port,time]} self.packetToPort={}
def connect(self, connection): if connection is None: self.log.warn("Can't connect to nothing") return if self.dpid is None: self.dpid = connection.dpid assert self.dpid == connection.dpid if self.ports is None: self.ports = connection.features.ports self.disconnect() self.connection = connection self._listeners = self.listenTo(connection) self._connected_at = time.time() label = dpid_to_str(connection.dpid) self.log = log.getChild(label) self.log.debug("Connect %s" % (connection, )) if self._id is None: if self.dpid not in switches_by_id and self.dpid <= 254: self._id = self.dpid else: self._id = TopoSwitch._next_id TopoSwitch._next_id += 1 switches_by_id[self._id] = self self.network = IPAddr("10.%s.0.0" % (self._id, )) self.mac = dpid_to_mac(self.dpid) # Disable flooding con = connection log.debug("Disabling flooding for %i ports", len(con.ports)) for p in con.ports.itervalues(): if p.port_no >= of.OFPP_MAX: continue pm = of.ofp_port_mod(port_no=p.port_no, hw_addr=p.hw_addr, config=of.OFPPC_NO_FLOOD, mask=of.OFPPC_NO_FLOOD) con.send(pm) con.send(of.ofp_barrier_request()) con.send(of.ofp_features_request()) # Some of this is copied from DHCPD's __init__(). self.send_table() def fix_addr(addr, backup): if addr is None: return None if addr is (): return IPAddr(backup) return IPAddr(addr) self.ip_addr = IPAddr("10.%s.0.1" % (self._id, )) #self.router_addr = self.ip_addr self.router_addr = None self.dns_addr = None #fix_addr(dns_address, self.router_addr) self.subnet = IPAddr("255.0.0.0") self.pools = {} for p in connection.ports: if p < 0 or p >= of.OFPP_MAX: continue self.pools[p] = [ IPAddr("10.%s.%s.%s" % (self._id, p, n)) for n in range(1, 255) ] self.lease_time = 60 * 60 # An hour #TODO: Actually make them expire :) self.offers = {} # Eth -> IP we offered self.leases = {} # Eth -> IP we leased
def __str__(self): t = self.network.toUnsigned() t = (IPAddr(t | self.first), IPAddr(t | self.last)) return "<Addresses from %s to %s>" % t
def _handle_PacketIn(self, event): dpid = event.connection.dpid inport = event.port packet = event.parsed if not packet.parsed: log.warning("%i %i ignoring unparsed packet", dpid, inport) return if dpid not in self.arpTable: # New switch -- create an empty table self.arpTable[dpid] = {} for fake in self.fakeways: self.arpTable[dpid][IPAddr(fake)] = Entry( of.OFPP_NONE, dpid_to_mac(dpid)) if packet.type == ethernet.LLDP_TYPE: # Ignore LLDP packets return if isinstance(packet.next, ipv4): log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip, packet.next.dstip) # Send any waiting packets... self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport) # Learn or update port/MAC info if packet.next.srcip in self.arpTable[dpid]: if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, packet.next.srcip) else: log.debug("%i %i learned %s", dpid, inport, str(packet.next.srcip)) self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src) # Try to forward dstaddr = packet.next.dstip if dstaddr in self.arpTable[dpid]: # We have info about what port to send it out on... prt = self.arpTable[dpid][dstaddr].port mac = self.arpTable[dpid][dstaddr].mac if prt == inport: log.warning( "%i %i not sending packet for %s back out of the " + "input port" % (dpid, inport, str(dstaddr))) else: log.debug( "%i %i installing flow for %s => %s out port %i" % (dpid, inport, packet.next.srcip, dstaddr, prt)) actions = [] actions.append(of.ofp_action_dl_addr.set_dst(mac)) actions.append(of.ofp_action_output(port=prt)) match = of.ofp_match.from_packet(packet, inport) match.dl_src = None # Wildcard source MAC msg = of.ofp_flow_mod(command=of.OFPFC_ADD, idle_timeout=FLOW_IDLE_TIMEOUT, hard_timeout=of.OFP_FLOW_PERMANENT, buffer_id=event.ofp.buffer_id, actions=actions, match=of.ofp_match.from_packet( packet, inport)) event.connection.send(msg.pack()) elif self.arp_for_unknowns: # We don't know this destination. # First, we track this buffer so that we can try to resend it later # if we learn the destination, second we ARP for the destination, # which should ultimately result in it responding and us learning # where it is # Add to tracked buffers if (dpid, dstaddr) not in self.lost_buffers: self.lost_buffers[(dpid, dstaddr)] = [] bucket = self.lost_buffers[(dpid, dstaddr)] entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id, inport) bucket.append(entry) while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0] # Expire things from our outstanding ARP list... self.outstanding_arps = { k: v for k, v in self.outstanding_arps.iteritems() if v > time.time() } # Check if we've already ARPed recently if (dpid, dstaddr) in self.outstanding_arps: # Oop, we've already done this one recently. return # And ARP... self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4 r = arp() r.hwtype = r.HW_TYPE_ETHERNET r.prototype = r.PROTO_TYPE_IP r.hwlen = 6 r.protolen = r.protolen r.opcode = r.REQUEST r.hwdst = ETHER_BROADCAST r.protodst = dstaddr r.hwsrc = packet.src r.protosrc = packet.next.srcip e = ethernet(type=ethernet.ARP_TYPE, src=packet.src, dst=ETHER_BROADCAST) e.set_payload(r) log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport, str(r.protodst), str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) msg.in_port = inport event.connection.send(msg) elif isinstance(packet.next, arp): a = packet.next log.debug("%i %i ARP %s %s => %s", dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc), str(a.protodst)) if a.prototype == arp.PROTO_TYPE_IP: if a.hwtype == arp.HW_TYPE_ETHERNET: if a.protosrc != 0: # Learn or update port/MAC info if a.protosrc in self.arpTable[dpid]: if self.arpTable[dpid][a.protosrc] != (inport, packet.src): log.info("%i %i RE-learned %s", dpid, inport, str(a.protosrc)) else: log.debug("%i %i learned %s", dpid, inport, str(a.protosrc)) self.arpTable[dpid][a.protosrc] = Entry( inport, packet.src) # Send any waiting packets... self._send_lost_buffers(dpid, a.protosrc, packet.src, inport) if a.opcode == arp.REQUEST: # Maybe we can answer if a.protodst in self.arpTable[dpid]: # We have an answer... if not self.arpTable[dpid][ a.protodst].isExpired(): # .. and it's relatively current, so we'll reply ourselves r = arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = arp.REPLY r.hwdst = a.hwsrc r.protodst = a.protosrc r.protosrc = a.protodst r.hwsrc = self.arpTable[dpid][ a.protodst].mac e = ethernet(type=packet.type, src=dpid_to_mac(dpid), dst=a.hwsrc) e.set_payload(r) log.debug("%i %i answering ARP for %s" % (dpid, inport, str(r.protosrc))) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append( of.ofp_action_output( port=of.OFPP_IN_PORT)) msg.in_port = inport event.connection.send(msg) return # Didn't know how to answer or otherwise handle this ARP, so just flood it log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc), str(a.protodst))) msg = of.ofp_packet_out( in_port=inport, data=event.ofp, action=of.ofp_action_output(port=of.OFPP_FLOOD)) event.connection.send(msg)
def subnet_mask(self): return IPAddr(((1 << self.network_size) - 1) << self.host_size)
class atp_events(EventMixin): _eventMixin_events = set([addFlowEntry,]) totalRequestCount = 0 minPacketThreshold = 4 minRequestThreshold = 2 maxRequestThreshold = 15 newIPTable = {} validIPTable = {IPAddr('10.0.0.2') : [0,0], IPAddr('10.0.0.3') : [0,0]} totalIP = len(newIPTable.keys()) + len(validIPTable.keys()) regularIPCount = len(validIPTable) ddos = False def __init__(self): self.listenTo(core) self.requestPackets = 0 self.dataPackets = 1 self.idleTimeoutAttacker = 30 self.hardTimeoutAttacker = 3600 self.regularTimeouts = [10,30] self.newTimeouts = [5,30] self.regReq = 3 #Function to drop and block suspected IP. def dropIP (self,event): packet = event.parsed msg = of.ofp_flow_mod() msg.command = of.OFPFC_DELETE msg.match.nw_src = packet.next.srcip msg.match.nw_dst = packet.next.dstip msg.match.dl_type = ethernet.IP_TYPE event.connection.send(msg) msg = of.ofp_flow_mod() msg.priority = 1000 msg.command = of.OFPFC_ADD msg.match.nw_src = packet.next.srcip msg.match.dl_type = ethernet.IP_TYPE msg.actions = [] msg.idle_timeout = self.idleTimeoutAttacker msg.hard_timeout = self.hardTimeoutAttacker msg.flags=of.OFPFF_SEND_FLOW_REM event.connection.send(msg) #update minRequestThreshold and MaxRequestThreshold on timely manner. #Update avarage packet count as well. def updateThreshold(self): self.totalIP = len(self.validIPTable.keys() + self.newIPTable.keys()) for i in self.validIPTable.keys(): self.validIPTable[i] = [0,0] if(len(self.newIPTable) > 15): self.ddos = True print("DDoS detected") else: self.ddos = False lmda = self.totalRequestCount/self.totalIP self.totalRequestCount = 0 print(str(lmda) + " " + str(self.totalIP)) #start when event goes up. def _handle_GoingUpEvent(self,event): self.listenTo(core.openflow) self.listenTo(core.adaptiveThreatPrevention) Timer(10,self.updateThreshold, recurring=True) #Handle PacketIn Requests coming from switches. def _handle_PacketIn(self,event): #parsing the pakcet to get necessary data. packet = event.parsed if isinstance(packet.next, ipv4): srcIP = packet.next.srcip if(srcIP == HOST_IP): self.raiseEvent(addFlowEntry,event,self.regularTimeouts) return if(srcIP in self.validIPTable.keys()): ''' #src is registered as regular IP. 1. Issue a normal entry. 2. srcIP reqPacketcount ++. ''' self.raiseEvent(addFlowEntry,event,self.regularTimeouts) self.totalRequestCount += 1 self.validIPTable[srcIP][self.requestPackets] += 1 ''' #Check its reqPacket count. 1. If reqPacket count > maxReqCount It's DoS attacker. ''' if(self.validIPTable[srcIP][self.requestPackets] > self.maxRequestThreshold): #It will be considered as a DoS attacker. #check data packets. if(self.validIPTable[srcIP][self.dataPackets] < (3*self.validIPTable[srcIP][self.requestPackets])): #definately DoS attacker. #remove from database. del self.validIPTable[srcIP] #issues drop for long time. self.dropIP(event) else: if(srcIP not in self.newIPTable.keys()): self.newIPTable[srcIP] = [0,0] #issue new short entry. self.raiseEvent(addFlowEntry,event,self.newTimeouts) self.totalRequestCount += 1 self.newIPTable[srcIP][self.requestPackets] += 1 if(self.newIPTable[srcIP][self.requestPackets] > self.minRequestThreshold): #get status from the switch. if(self.newIPTable[srcIP][self.dataPackets] < (3*self.newIPTable[srcIP][self.requestPackets])): #Its a DDoS attacker. #issue drop for long time #remove from database. print("Dropped %s" % srcIP) del self.newIPTable[srcIP] self.dropIP(event) else: #add to reg database. self.validIPTable[srcIP] = self.newIPTable[srcIP] del self.newIPTable[srcIP] else : #Normal packets self.raiseEvent(addFlowEntry,event,self.regularTimeouts) #Sending flow state messages to switch. def _handle_flowStatsEvent(self,event): for connection in core.openflow._connections.values(): connection.send(of.ofp_stats_request(body=of.ofp_flow_stats_request())) #Handling flow states received event. def _handle_FlowStatsReceived(self,event): stats = flow_stats_to_list(event.stats) packet_count = 0 flow_count = 0 for f in event.stats: flow_count += 1 packet_count += f.packet_count log.info("Flow: %s, Data packets: %s, Total Requestpackets: %s" % (flow_count,packet_count,self.totalRequestCount)) #To get the packet count from a given IP address. def _handle_FlowRemoved(self,event): msg = event.ofp f_ip = msg.match.nw_src if(f_ip in self.newIPTable.keys()): self.newIPTable[f_ip][self.dataPackets] = self.newIPTable[f_ip][self.dataPackets] + msg.packet_count elif (f_ip in self.validIPTable.keys()): self.validIPTable[f_ip][self.dataPackets] = self.validIPTable[f_ip][self.dataPackets] + msg.packet_count
def remove(self, item): item = IPAddr(item) if item not in self: raise RuntimeError("%s not in this pool" % (item, )) self.removed.add(item)
import pox import pox.openflow.libopenflow_01 as of from pox.core import core from pox.lib.revent import * from pox.lib.packet.ethernet import ethernet, ETHER_BROADCAST from pox.lib.packet.ipv4 import ipv4 from pox.lib.packet.arp import arp from pox.lib.addresses import IPAddr, EthAddr from pox.lib.util import str_to_bool, dpid_to_str from pox.lib.recoco import Timer from pox.openflow.of_json import * log = core.getLogger() HOST_IP = IPAddr('10.0.0.5') ''' This module has all the necessary event handling functions of ATP algorithm. This modules does following tasks. 1. _handle_GoingUpEvent : This event will start listing to various events coming from openflow and pox core. 2. _handle_check_packetIn : This is check_packetIn event handler. This will handle check_packetIn event raised by atp module. Basically, this will create entries in new and reg lists. 3. _handle_flowStatsEvent : This will handle flowStates events called by the atp module. This module will send flow stats reqest to open flow switches. 4. _handle_FlowStatsReceived : This will handle FlowStatsReceived event raised by the open flow switch.
def __init__(self, ip_address="192.168.0.254", router_address=(), dns_address=(), pool=None, subnet=None, install_flow=True, dpid=None, ports=None): def fix_addr(addr, backup): if addr is None: return None if addr is (): return IPAddr(backup) return IPAddr(addr) self._install_flow = install_flow self.ip_addr = IPAddr(ip_address) self.router_addr = fix_addr(router_address, ip_address) self.dns_addr = fix_addr(dns_address, self.router_addr) if dpid is None: self.dpid = None else: try: dpid = long(dpid) except: dpid = util.str_to_dpid(dpid) self.dpid = dpid if ports is None: self.ports = None else: self.ports = set(ports) if self.ports: assert self.dpid is not None # Doesn't make sense self._servers.append(self) if pool is None: self.pool = [ IPAddr("192.168.0." + str(x)) for x in range(100, 199) ] self.subnet = IPAddr(subnet or "255.255.255.0") else: self.pool = pool self.subnet = subnet if hasattr(pool, 'subnet_mask'): self.subnet = pool.subnet_mask if self.subnet is None: raise RuntimeError("You must specify a subnet mask or use a " "pool with a subnet hint") self.lease_time = 60 * 60 # An hour #TODO: Actually make them expire :) self.offers = {} # Eth -> IP we offered self.leases = {} # Eth -> IP we leased if self.ip_addr in self.pool: log.debug("Removing my own IP (%s) from address pool", self.ip_addr) self.pool.remove(self.ip_addr) core.openflow.addListeners(self)
def gestisciPacketIn(self, packet, packet_in, dpid, event): #eseguendo una gestione manuale delle ARP, bisogna salvane le info importanti if packet.type == packet.ARP_TYPE: self.registraHost(packet.src, event.connection.dpid, event.port, packet.payload.protosrc) ipSource = str(packet.payload.protosrc) ipDest = str(packet.payload.protodst) macSource = str(packet.src) #se non e' presente il mittente in tabella, viene aggiunto if ipSource not in self.tabellaC.keys(): self.tabellaC[ipSource] = (macSource, dpid) #se e' un arp request if packet.payload.opcode == pkt.arp.REQUEST: if ipDest in self.tabellaC.keys( ): #trovato destinatario nella tabella, rispondi direttamente con arp reply arp_reply = pkt.arp() coppia = self.tabellaC[ ipDest] #ottieni coppia (MAC, SWITCH) del destinatario macDest = coppia[0] #prendi MAC del destinatario arp_reply.hwsrc = EthAddr(macDest) arp_reply.hwdst = EthAddr(macSource) arp_reply.opcode = pkt.arp.REPLY arp_reply.protosrc = IPAddr(ipDest) arp_reply.protodst = IPAddr(ipSource) ether = pkt.ethernet() ether.type = pkt.ethernet.ARP_TYPE ether.src = EthAddr(macDest) ether.dst = EthAddr(macSource) ether.payload = arp_reply self.sendPacketToDPID(ether, dpid) else: #non c'e in tabella manda una arp request a tutti gli switch arp_request = pkt.arp() arp_request.hwsrc = EthAddr(macSource) arp_request.opcode = pkt.arp.REQUEST arp_request.protosrc = IPAddr(ipSource) arp_request.protodst = IPAddr(ipDest) ether = pkt.ethernet() ether.type = pkt.ethernet.ARP_TYPE ether.src = EthAddr(macSource) ether.dst = pkt.ETHER_BROADCAST ether.payload = arp_request self.sendPacketAll(ether) else: # e' una arp reply, viene inoltrata al destinatario arp_reply = pkt.arp() coppia = self.tabellaC[ ipDest] #ottieni coppia (MAC, SWITCH) del destinatario macDest = coppia[0] #prendi MAC del destinatario arp_reply.hwsrc = EthAddr(macDest) arp_reply.hwdst = EthAddr(macSource) arp_reply.opcode = pkt.arp.REPLY arp_reply.protosrc = IPAddr(ipDest) arp_reply.protodst = IPAddr(ipSource) ether = pkt.ethernet() ether.type = pkt.ethernet.ARP_TYPE ether.src = EthAddr(macDest) ether.dst = EthAddr(macSource) ether.payload = arp_reply self.sendPacketToDPID(ether, coppia[1]) #il pacchetto non e' un ARP else: #prende le info dal pacchetto ipDest = str(packet.payload.dstip) ipSrc = str(packet.payload.srcip) coppia_dst = self.tabellaC[ ipDest] #ottieni lo coppia (MAC, DPID) del destinatario dpid_dst = coppia_dst[ 1] #ottieni il dpid dello switch destinatario mac_dst = coppia_dst[0] coppia_src = self.tabellaC[ipSrc] mac_src = coppia_src[0] #calcola il percorso per la destinazione con dijkstra percorso = self.dijkstra(dpid, dpid_dst) #avvia l'installazione negli switch del percorso self.avvia_instal(percorso, ipDest, ipSrc) #riesegui il procedimento, ma sul percorso inverso percorso.reverse() self.avvia_instal(percorso, ipSrc, ipDest) print percorso #dato che si conosce il dpid destinatario, inoltra direttamente il pacchetto, senza passare per la rete self.sendPacketToDPID(packet, dpid_dst)
def fix_addr(addr, backup): if addr is None: return None if addr is (): return IPAddr(backup) return IPAddr(addr)
class SimpleAddressPool(AddressPool): """ Simple AddressPool for simple subnet based pools. """ def __init__(self, network="192.168.0.0/24", first=1, last=None, count=None): """ Simple subnet-based address pool Allocates count IP addresses out of network/network_size, starting with the first'th. You may specify the end of the range with either last (to specify the last'th address to use) or count to specify the number to use. If both are None, use up to the end of all legal addresses. Example for all of 192.168.x.x/16: SimpleAddressPool("192.168.0.0/16", 1, 65534) """ network, network_size = parse_cidr(network) self.first = first self.network_size = network_size self.host_size = 32 - network_size self.network = IPAddr(network) if last is None and count is None: self.last = (1 << self.host_size) - 2 elif last is not None: self.last = last elif count is not None: self.last = self.first + count - 1 else: raise RuntimeError("Cannot specify both last and count") self.removed = set() if self.count <= 0: raise RuntimeError("Bad first/last range") if first == 0: raise RuntimeError("Can't allocate 0th address") if self.host_size < 0 or self.host_size > 32: raise RuntimeError("Bad network") if IPAddr(self.last | self.network.toUnsigned()) not in self: raise RuntimeError("Bad first/last range") def __repr__(self): return str(self) def __str__(self): t = self.network.toUnsigned() t = (IPAddr(t | self.first), IPAddr(t | self.last)) return "<Addresses from %s to %s>" % t @property def subnet_mask(self): return IPAddr(((1 << self.network_size) - 1) << self.host_size) @property def count(self): return self.last - self.first + 1 def __contains__(self, item): item = IPAddr(item) if item in self.removed: return False n = item.toUnsigned() mask = (1 << self.host_size) - 1 nm = (n & mask) | self.network.toUnsigned() if nm != n: return False if (n & mask) == mask: return False if (n & mask) < self.first: return False if (n & mask) > self.last: return False return True def append(self, item): item = IPAddr(item) if item not in self.removed: if item in self: raise RuntimeError("%s is already in this pool" % (item, )) else: raise RuntimeError("%s does not belong in this pool" % (item, )) self.removed.remove(item) def remove(self, item): item = IPAddr(item) if item not in self: raise RuntimeError("%s not in this pool" % (item, )) self.removed.add(item) def __len__(self): return (self.last - self.first + 1) - len(self.removed) def __getitem__(self, index): if index < 0: raise RuntimeError("Negative indices not allowed") if index >= len(self): raise IndexError("Item does not exist") c = self.first # Use a heuristic to find the first element faster (we hope) # Note this means that removing items changes the order of # our "list". c += len(self.removed) while c > self.last: c -= self.count while True: addr = IPAddr(c | self.network.toUnsigned()) if addr not in self.removed: assert addr in self index -= 1 if index < 0: return addr c += 1 if c > self.last: c -= self.count
def glob_gateways_obj(): buffer = [] for gw in glob_gateways: buffer.append(IPAddr(gw)) return buffer