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 do_l2_learning(self, con, inport, packet): """Given a packet, learn the source and peg to a switch/inport """ # learn MAC on incoming port srcaddr = EthAddr(packet.src) #if ord(srcaddr[0]) & 1: # return if self.st[con].has_key(srcaddr.toStr()): # change to raw? # we had already heard from this switch dst = self.st[con][srcaddr.toStr()] # raw? if dst[0] != inport: # but from a different port log.info('MAC has moved from '+str(dst)+'to'+str(inport)) else: return else: log.info('learned MAC '+srcaddr.toStr()+' on Switch %s, Port %d'% (con.dpid,inport)) # learn or update timestamp of entry self.st[con][srcaddr.toStr()] = (inport, time(), packet) # raw?
def forward_l2_packet(self, con, inport, packet, buf, bufid): """If we've learned the destination MAC set up a flow and send only out of its inport. Else, flood. """ dstaddr = EthAddr(packet.dst) #if not ord(dstaddr[0]) & 1 and # what did this do? if self.st[con].has_key(dstaddr.toStr()): # raw? prt = self.st[con][dstaddr.toStr()] # raw? if prt[0] == inport: log.warning('**warning** learned port = inport') ofcommand.floodPacket(con, inport, packet, buf, bufid) else: # We know the outport, set up a flow log.info('installing flow for ' + str(packet)) match = ofcommand.extractMatch(packet) actions = [ofcommand.Output(prt[0])] ofcommand.addFlowEntry(con, inport, match, actions, bufid) # Separate bufid, make addFlowEntry() only ADD the entry # send/wait for Barrier # sendBufferedPacket(bufid) else: # haven't learned destination MAC. Flood ofcommand.floodPacket(con, inport, packet, buf, bufid)
def act_like_lswitch (self, packet, packet_in): """ Implement switch-like behavior. """ # Learn the port for the source MAC if necessary srcaddr = EthAddr(packet.src) if not self.macStore.has_key(srcaddr.toStr()): self.macStore[srcaddr.toStr()] = packet_in.in_port log.debug("New Host detected with MAC %s on Port %s" % (srcaddr.toStr(), packet_in.in_port)) # Check if we have the destination in our store dstaddr = EthAddr(packet.dst) if self.macStore.has_key(dstaddr.toStr()): # Yes, it might bee a good idea to install a flowtable entry, # otherwise we have to ask the controller every time fm = of.ofp_flow_mod() fm.match.in_port = packet_in.in_port fm.match.dl_dst = dstaddr fm.actions.append(of.ofp_action_output(port = self.macStore[dstaddr.toStr()])) #fm.idle_timeout = 10 #fm.hard_timeout = 30 log.debug("Installing FlowTable entry") self.connection.send(fm) # We wont loose this package, so we forward it # to its destination self.send_packet(packet_in.buffer_id, packet_in.data, self.macStore[dstaddr.toStr()], packet_in.in_port) log.debug("Package <"+str(packet_in.buffer_id)+"> forwarded by controller over Port "+str(self.macStore[dstaddr.toStr()])) else: # Flood the packet out everything but the input port. # We are here, because we just put the source MAC and port # in our store and don't no the destination Port, # thus the Flood is the only thing we can do. self.act_like_hub(packet, packet_in) log.debug("Package <"+str(packet_in.buffer_id)+"> flooded by controller")
def _init(self, *args, **kw): a = kw.pop('address', None) if a is None: self.address = None else: self.address = EthAddr(a)
def __init__ (self, ip, mac, port): self.ip = IPAddr(ip) self.mac = EthAddr(mac) self.port = port
def handle_packet(self, packet, packet_in): global matching_flow srcmac = EthAddr(packet.src) dstmac = EthAddr(packet.dst) print(packet) arpp = packet.find('arp') icmpp = packet.find('icmp') ipp = packet.find('ipv4') ip6p = packet.find('ipv6') tcpp = packet.find('tcp') udpp = packet.find('udp') l4p = tcpp if tcpp else udpp # MAC-Adresse -> Port lernen if srcmac.toStr() not in self.mac_table: self.mac_table[srcmac.toStr()] = packet_in.in_port # ARP und ICMP blind weiterleiten if arpp or icmpp: self.send_packet(packet, dstmac.toStr(), packet_in.in_port) return # IPv6 ignorieren if ip6p: return # Treffer? match = False # TCP-IP-Paket if ipp and l4p: srcip = ipp.srcip dstip = ipp.dstip srcport = l4p.srcport dstport = l4p.dstport for flow in flows: matching_flow = flow srcip_matches = True if flow.src_ip is None else srcip == flow.src_ip dstip_matches = True if flow.dst_ip is None else dstip == flow.dst_ip srcport_matches = True if flow.src_port is None else srcport == flow.src_port dstport_matches = True if flow.dst_port is None else dstport == flow.dst_port # @formatter:off if ( srcip_matches and dstip_matches and srcport_matches and dstport_matches ): match = True break else: match = False # @formatter:on if match: log.info('Paket {0} passt zu {1}'.format(packet, matching_flow)) self.send_packet(packet, dstmac.toStr(), packet_in.in_port) else: log.warning('Keine passenden Flows, Paket {0} wird verworfen'.format(packet))
def _unpack_new(cls, raw, offset, t, length, prev): return offset + length, cls(address=EthAddr(raw[offset:offset + length]), prev=prev)
def dpid_port_to_mac(dpid, port): msb = port & 0xff lsbs = int(dpid) & 0x00FFffFFffFF eth_addr = (msb << 40) | lsbs return EthAddr("%012x" % eth_addr)
Depends on openflow.discovery Works with openflow.spanning_tree """ from pox.core import core import pox.openflow.libopenflow_01 as of from pox.lib.revent import * from pox.lib.recoco import Timer from collections import defaultdict from pox.lib.addresses import IPAddr, EthAddr from pox.openflow.discovery import Discovery from pox.lib.util import dpid_to_str import time log = core.getLogger() e1 = EthAddr('00:00:00:00:00:01') e2 = EthAddr('00:00:00:00:00:02') e3 = EthAddr('00:00:00:00:00:03') e4 = EthAddr('00:00:00:00:00:04') e5 = EthAddr('00:00:00:00:00:05') e6 = EthAddr('00:00:00:00:00:06') num_mac = {1: e1, 2: e2, 3: e3, 4: e4, 5: e5, 6: e6} mac_to_number = {e1: 1, e2: 2, e3: 3, e4: 4, e5: 5, e6: 6} print EthAddr('00:00:00:00:00:01') switch1_all_right = { #host 1 send (3, num_mac[2]): 4, (3, num_mac[3]): 1, (3, num_mac[4]): 1, (3, num_mac[5]): 1,
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)
def __init__(self): self.listenTo(core.openflow) core.openflow_discovery.addListeners(self) # Adjacency map. [sw1][sw2] -> port from sw1 to sw2 self.adjacency = defaultdict(lambda: defaultdict(lambda: None)) ''' The structure of self.portmap is a four-tuple key and a string value. The type is: (dpid string, src MAC addr, dst MAC addr, port (int)) -> dpid of next switch ''' self.portmap = { # h1 <-- port 80 --> h3 ('00-00-00-00-00-01', EthAddr('00:00:00:00:00:01'), EthAddr('00:00:00:00:00:03'), 80): '00-00-00-00-00-03', # """ Add your mapping logic here""" ('00-00-00-00-00-03', EthAddr('00:00:00:00:00:01'), EthAddr('00:00:00:00:00:03'), 80): '00-00-00-00-00-04', ('00-00-00-00-00-03', EthAddr('00:00:00:00:00:03'), EthAddr('00:00:00:00:00:01'), 80): '00-00-00-00-00-01', ('00-00-00-00-00-04', EthAddr('00:00:00:00:00:03'), EthAddr('00:00:00:00:00:01'), 80): '00-00-00-00-00-03', # h2 <-- port 22 --> h4 ('00-00-00-00-00-01', EthAddr('00:00:00:00:00:02'), EthAddr('00:00:00:00:00:04'), 22): '00-00-00-00-00-02', ('00-00-00-00-00-02', EthAddr('00:00:00:00:00:02'), EthAddr('00:00:00:00:00:04'), 22): '00-00-00-00-00-04', ('00-00-00-00-00-02', EthAddr('00:00:00:00:00:04'), EthAddr('00:00:00:00:00:02'), 22): '00-00-00-00-00-01', ('00-00-00-00-00-04', EthAddr('00:00:00:00:00:04'), EthAddr('00:00:00:00:00:02'), 22): '00-00-00-00-00-02', }
def handle(client_sock, client_addr): dic = {} dicc = {} c = [] d = [] e = [] global file while 1: msg = client_sock.recv(1024) #print msg if len(msg) == 0: break c = msg.split('\n') for i in c: d.append(i) #print d print 'recv finish' for i in d: if i is '': continue e.append(i) dpid = e[0].split('#')[0] batmac = e[0].split('#')[1] mesh_bat0_mac[int(dpid)] = EthAddr(batmac) print mesh_bat0_mac for i in range(1, len(e)): if int(e[i].split('#')[1]) < 0: dic[e[i].split('#')[0]] = -int(e[i].split('#')[1]) else: dic[e[i].split('#')[0]] = int(e[i].split('#')[1]) dicc = {} dicc = mesh_point(dic) global channel, temp_channel, switches ''' ######ycj for i in dicc.keys():##change channel with channel[int(dpid[0])][i],when a sw not in dicc.keys(),means it not within the scope of dpid[0].then it will remain init value 100 channel[int(dpid)][i] = dicc[i] #channel[int(dpid[0])] = dicc ''' ######ycj ######ycj for i in switches.keys(): if i in dicc.keys(): channel[int(dpid)][i] = dicc[i] elif i != int(dpid): channel[int(dpid)][i] = 100 ######ycj print 'The number of channels: ' + str(len(channel.keys())) print 'The number of switches: ' + str(len(switches.keys())) file.write('The number of channels: ' + str(len(channel.keys())) + '\n') file.write('The number of switches: ' + str(len(switches.keys())) + '\n') ##when a sw disconnect to or join in controller pox,the switches.keys() change ,reinit channel ;!!!!the situation a sw disconnect to controller,the len(switches.keys()) cant change , initial_channel() ######ycj cha_socinited[int(dpid)] = 1 # marks that the switch has been communicated with the controller after the initialization # that means the channels of the switch have been set to the real value if len(cha_socinited) == sum(cha_socinited.values( )): # if all the channels have been set to the real value cha_reverse = channelreverse( channel) # dpid : channel[], reverse the meaning of channel for i in cha_reverse: if cha_reverse[i].count(100) == len( cha_reverse[i] ): # all the channels connected to the switch is 100, means the switch is down print "*******************************************" print dpidToStr(i) + " is going down...deleting paths..." print "*******************************************" file.write("*******************************************\n") file.write( dpidToStr(i) + " is going down...deleting paths...\n") file.write("*******************************************\n") temp = {} for m in paths_map: for n in paths_map[m]: if i in paths_map[m][n]: temp[m] = n for m in temp: path = paths_map[m].pop( temp[m]) # delete the relating existed paths print path if switches.has_key(i): del switches[i] # delete the switch if channel.has_key(i): del channel[i] # delete the channels of the switch for j in channel: if channel[j].has_key(i): del channel[j][ i] # delete the channels connected to the switch ######ycj global adjacency adjacency = channeltoadj(channel) #print '***************************************************************************' #print 'adjacency'+str(adjacency) #print '***************************************************************************' #print 'switches'+str(switches) print '***************************************************************************' print 'channel:' + str(channel) print '***************************************************************************' print 'clients:' + str(iptomac) print '***************************************************************************' #file.write('***************************************************************************\n') #file.write('adjacency'+str(adjacency)+'\n') #file.write('***************************************************************************\n') #file.write('switches'+str(switches)+'\n') file.write( '***************************************************************************\n' ) file.write('channel:' + str(channel) + '\n') file.write( '***************************************************************************\n' ) file.write('clients:' + str(iptomac) + '\n') file.write( '***************************************************************************\n' )
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)
from pox.core import core import pox.openflow.libopenflow_01 as of from pox.lib.revent import * from pox.lib.util import dpidToStr from pox.lib.packet.ethernet import ethernet from pox.lib.packet.arp import arp from pox.lib.addresses import IPAddr, EthAddr import time log = core.getLogger() IDLE_TIMEOUT = 10 # in seconds HARD_TIMEOUT = 0 # infinity LOAD_BALANCER_IP = IPAddr('10.0.0.254') LOAD_BALANCER_MAC = EthAddr('00:00:00:00:00:FE') H1_IP = IPAddr('10.0.0.1') H2_IP = IPAddr('10.0.0.2') H3_IP = IPAddr('10.0.0.3') H3_MAC = EthAddr('00:00:00:00:00:03') class LoadBalancer (EventMixin): class Server: def __init__ (self, ip, mac, port): self.ip = IPAddr(ip) self.mac = EthAddr(mac) self.port = port def __str__(self): return','.join([str(self.ip), str(self.mac), str(self.port)]) def __init__ (self, connection): self.connection = connection
import pox.openflow.libopenflow_01 as of import pox.openflow.discovery import pox.openflow.spanning_tree from pox.lib.revent import * from pox.lib.util import dpid_to_str from pox.lib.util import dpidToStr from pox.lib.addresses import IPAddr, EthAddr from collections import namedtuple import os log = core.getLogger() h1 = EthAddr("00-00-00-00-00-01") h2 = EthAddr("00-00-00-00-00-02") h3 = EthAddr("00-00-00-00-00-03") h4 = EthAddr("00-00-00-00-00-04") broadcast = EthAddr("ff-ff-ff-ff-ff-ff") class TopologySlice (EventMixin): def __init__(self): self.listenTo(core.openflow) log.debug("Enabling Slicing Module")
import time import os, sys, getopt import numpy as np import re import random from collections import defaultdict #sys.path.append('/home/Sdn_src/exp/src/') #print sys.path #print os.environ["PYTHONPATH"] import utils.read_topo as rt from utils.l2_learning_arp import LearningSwitch TYPE_IP = 0x0800 TYPE_ARP = 0x0806 ARP_CONTROL_PRIORITY = 0x0007 # Pretty high DUMMY_MAC = EthAddr('F0:F0:F0:F0:F0:F0') log = core.getLogger() topo_file = "%s/Sdn_src/exp/src/topo_config/nat.csv" % os.environ['HOME'] class L3_switch(EventMixin): # (object): # def __init__(self, switchVlan_obj): self.static_config_finished = False self.event = None self.packet_event = None self.connection = None self.ports = None #??????????????? self.dpid = None self._listeners = None
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 _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 attach(self, entity, packet=None): if entity.title in self.entities: return False self.entities[entity.title] = entity entity.workspaces[self.title] = self self.switches2 += [entity.switch_dpid] try: s = self.switches[entity.switch_dpid] except KeyError: s = self.WPSwitch(entity.switch_dpid) self.switches[s.dpid] = s s.used_ports.add(entity.port) #print 'self.switches.keys', self.switches.keys() #print graph.nodes() if self.qos: path = nx.shortest_path (graph, self.switches2[-1], self.switches2[0], weight='cost') log.info(' -> path with minimum QoS cost between {} and {} is: {}'.format(self.switches2[-1], self.switches2[0], path)) else: path = nx.shortest_path (graph, self.switches2[-1], self.switches2[0]) log.info(' -> shortest path between {} and {} is: {}'.format(self.switches2[-1], self.switches2[0], path)) if not self.wifi: msg = of.ofp_flow_mod() #msg.match.dl_type = 0x0880 # Causes conflicts with user-space switchs msg.command = of.OFPFC_MODIFY_STRICT # of.OFPFC_MODIFY || of.OFPFC_ADD msg.match.dl_dst = self.title_hash[:6] msg.match.dl_src = self.title_hash[6:] bw = int(self.bw) self.bw = int(self.bw) if self.bw and self.cos: try: #log.info('PEDIDO recebidos, bw {} cos {}'.format(self.bw, self.cos)) print 'PEDIDO recebidos, bw', self.bw, 'cos', self.cos, if (cos[self.cos] + self.bw) < lim[self.cos]: cos[self.cos] += int(bw+bw*0.2) print 'total', cos[self.cos] log.info('PEDIDO recebidos, bw {} cos {} total {}'.format(self.bw, self.cos, cos[self.cos])) else: #log.info('Reajuste! {}', (cos[self.cos]/lim[self.cos])*(lim[self.cos]-cos[self.cos]-self.bw)) #log.info('READJJJJ {}'.format(cos[self.cos]/lim[self.cos])*(lim[self.cos]-cos[self.cos]-self.bw)) if (lim[self.cos] + abs(cos[self.cos]/lim[self.cos])*(lim[self.cos]-cos[self.cos]-bw)) < maxi: print 'sum', abs((float(cos[self.cos])/float(maxi))*(maxi-cos[self.cos]-self.bw)) lim[self.cos] += abs((float(cos[self.cos])/float(maxi))*(maxi-cos[self.cos]-self.bw)) print '\nREADJJJJ, new limit',lim[self.cos] log.info('READJJJJ, new limit {}'.format(lim[self.cos])) else: print 'BLOCKED' except KeyError: if self.bw < lim[self.cos]: cos[self.cos] = int(self.bw+self.bw*0.2) else: log.info('READJuste2! {}'.format(cos[self.cos]/lim[self.cos])*(lim[self.cos]-cos[self.cos]-self.bw)) print 'PEDIDO2 recebidos, bw', self.bw, 'cos', self.cos, 'total', cos[self.cos] log.info(' -> Class of Service {} equals {} after receiving {}'.format(self.cos, cos[self.cos], self.bw)) if path.__len__() > 1: if self.bw and self.cos: log.info(' -> enqueuing in queue 1, corresponding to CoS silver') for i in path: if i == path[-1]: self.switches[i].used_ports.add(graph[i][path[path.index(i)-1]]['ports'][i]) elif i == path[0]: self.switches[i].used_ports.add(graph[i][path[path.index(i)+1]]['ports'][i]) else: try: s = self.switches[i] except KeyError: s = self.WPSwitch(i) self.switches[i] = s self.switches[i].used_ports.add(graph[i][path[path.index(i)+1]]['ports'][i]) self.switches[i].used_ports.add(graph[i][path[path.index(i)-1]]['ports'][i]) if self.bw and self.cos: msg.actions = [of.ofp_action_enqueue(port=p, queue_id=0) for p in self.switches[i].used_ports] # ofp_action_enqueue(port=0, queue_id=0) else: msg.actions = [of.ofp_action_enqueue(port=p, queue_id=1) for p in self.switches[i].used_ports] core.openflow.sendToDPID(i, msg) else: #print 'output:', s.used_ports, 'dpid:', s.dpid #msg.actions = [of.ofp_action_output(port=p) for p in s.used_ports] if self.bw and self.cos: msg.actions = [of.ofp_action_enqueue(port=p, queue_id=0) for p in s.used_ports] else: msg.actions = [of.ofp_action_enqueue(port=p, queue_id=1) for p in s.used_ports] core.openflow.sendToDPID(s.dpid, msg) else: # ============================================================================================================================== wifi rule1 = of.ofp_flow_mod() rule1.match.dl_dst = self.title_hash[:6] #rule1.match.dl_type = 0x0880 # Causes conflicts with user-space switch rule1.command = of.OFPFC_MODIFY_STRICT rule1.actions.append(of.ofp_action_dl_addr.set_src(self.title_hash[:6])) rule1.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr("FF:FF:FF:FF:FF:FF"))) rule2 = of.ofp_flow_mod() rule2.match.dl_dst = EthAddr("FF:FF:FF:FF:FF:FF") rule2.match.dl_src = self.title_hash[6:] #rule2.match.dl_type = 0x0880 rule2.command = of.OFPFC_MODIFY_STRICT if path.__len__() > 1: for i in path: if i == path[-1]: self.switches[i].used_ports.add(graph[i][path[path.index(i)-1]]['ports'][i]) elif i == path[0]: self.switches[i].used_ports.add(graph[i][path[path.index(i)+1]]['ports'][i]) for p in self.switches[i].used_ports: rule1.actions.append(of.ofp_action_output(port=p)) core.openflow.sendToDPID(i, rule1) else: try: s = self.switches[i] except KeyError: s = self.WPSwitch(i) self.switches[i] = s self.switches[i].used_ports.add(graph[i][path[path.index(i)+1]]['ports'][i]) self.switches[i].used_ports.add(graph[i][path[path.index(i)-1]]['ports'][i]) if self.bw and self.cos: # print 'enqueue' rule2.actions = [of.ofp_action_enqueue(port=p) for p in self.switches[i].used_ports] # ofp_action_enqueue(port=0, queue_id=0) else: rule2.actions = [of.ofp_action_output(port=p) for p in self.switches[i].used_ports] core.openflow.sendToDPID(i, rule2) else: for p in s.used_ports: rule1.actions.append(of.ofp_action_output(port=p)) core.openflow.sendToDPID(s.dpid, rule1) rule2.actions = [of.ofp_action_output(port=p) for p in s.used_ports] core.openflow.sendToDPID(s.dpid, rule2) #print 'self.switches', self.switches # for debug return True
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 GetMACForLoadBalancing(): value = GetMACForLoadBalancing.nextvalue GetMACForLoadBalancing.nextvalue += 1 return EthAddr("031337%06x" % (value & 0xFFFFFF))
def eth_addr(self): dpid = self.dpid if self.dpid is None: raise RuntimeError("eth_addr not available") return EthAddr("%012x" % (dpid & 0xffFFffFFffFF, ))
def link (addr): if addr is None: return None if len(addr) != 6: return None return EthAddr(addr)
from collections import defaultdict import pox.openflow.libopenflow_01 as of import pox.openflow.discovery import pox.openflow.spanning_tree from pox.lib.revent import * from pox.lib.util import dpid_to_str from pox.lib.util import dpidToStr from pox.lib.addresses import IPAddr, EthAddr from collections import namedtuple import os log = core.getLogger() h1 = EthAddr("00-00-00-00-00-01") h2 = EthAddr("00-00-00-00-00-02") h3 = EthAddr("00-00-00-00-00-03") h4 = EthAddr("00-00-00-00-00-04") h5 = EthAddr("00-00-00-00-00-05") h6 = EthAddr("00-00-00-00-00-06") h7 = EthAddr("00-00-00-00-00-07") h8 = EthAddr("00-00-00-00-00-08") broadcast = EthAddr("ff-ff-ff-ff-ff-ff") class DTCurrentRules(EventMixin): def __init__(self): self.listenTo(core.openflow) core.openflow_discovery.addListeners(self)
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("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('Adding %s into CAM' % str(etherFrame.src)) self.mac_to_port[str(etherFrame.src)] = packet_in.in_port # ARP if etherFrame.type == ethernet.ARP_TYPE: log.debug('RECEIVED: EtherType -> ARP') self.ARP_Handler(etherFrame, packet_in) # IP elif etherFrame.type == ethernet.IP_TYPE: log.debug('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('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('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('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("ICMP DESTINATION UNREACHABLE SENT")
def dpid_to_mac(dpid): return EthAddr("%012x" % (dpid & 0xffFFffFFffFF, ))
def ARP_Handler(self, packet, packet_in): log.debug("ARP FRAME RECEIVED FROM %s" % packet_in.in_port) if packet.payload.opcode == arp.REQUEST: log.debug("IT'S AN ARP REQUEST!") arp_payload = packet.payload arp_request_ip = str(arp_payload.protodst) if arp_request_ip in self.arp_table: arp_reply = arp() arp_reply.opcode = arp.REPLY arp_reply.hwsrc = EthAddr(self.arp_table[arp_request_ip]) arp_reply.hwdst = arp_payload.hwsrc arp_reply.protosrc = arp_payload.protodst arp_reply.protodst = arp_payload.protosrc ether = ethernet() ether.type = ether.ARP_TYPE ether.src = EthAddr(self.arp_table[arp_request_ip]) ether.dst = arp_payload.hwsrc ether.payload = arp_reply self.resend_packet(ether, packet_in.in_port) log.debug("ARP REPLY SENT!") elif packet.payload.opcode == arp.REPLY: log.debug("IT'S AN ARP REPLY!") arp_payload = packet.payload hwsrc = str(arp_payload.hwsrc) srcip = str(arp_payload.protosrc) if srcip not in self.arp_table: self.arp_table[srcip] = hwsrc self.mac_to_port[hwsrc] = packet_in.in_port log.debug("%s %s INSTALLED TO CAM TABLE" % (srcip, hwsrc)) # If there are packets in buffer waiting to be sent out if srcip in self.buffer.keys(): print 'YES!' out_port = self.routing_table[self.buffer[srcip]['DestinationNetwork']]['Port'] ip_packet = self.buffer[srcip]['IP_Packet'] etherFrame = ethernet() etherFrame.type = etherFrame.IP_TYPE etherFrame.src = EthAddr(self.arp_table[self.routing_table[self.buffer[srcip]['DestinationNetwork']]['RouterInterface']]) etherFrame.dst = EthAddr(self.arp_table[srcip]) etherFrame.payload = ip_packet self.resend_packet(etherFrame, out_port) msg = of.ofp_flow_mod() print self.buffer[srcip]['DestinationNetwork'] msg.priority = 10 msg.match.dl_type = ethernet.IP_TYPE msg.match.nw_proto = ipv4.ICMP_PROTOCOL msg.match.set_nw_dst(self.buffer[srcip]['DestinationNetwork']) # msg.match.nw_dst = IPAddr(srcip) msg.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(self.arp_table[self.routing_table[self.buffer[srcip]['DestinationNetwork']]['RouterInterface']]))) msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(self.arp_table[srcip]))) msg.actions.append(of.ofp_action_output(port=out_port)) self.connection.send(msg) log.debug("Flow mod for destination network %s sent!", self.buffer[srcip]['DestinationNetwork']) self.buffer.pop(srcip)
def install_path(self, dst_sw, last_port, match, event): """ Attempts to install a path between this switch and some destination """ p = _get_path(self, dst_sw, event.port, last_port, event) if p is None: log.warning("Can't get from %s to %s", match.dl_src, match.dl_dst) import pox.lib.packet as pkt if (match.dl_type == pkt.ethernet.IP_TYPE and event.parsed.find('ipv4')): # It's IP -- let's send a destination unreachable log.debug("Dest unreachable (%s -> %s)", match.dl_src, match.dl_dst) from pox.lib.addresses import EthAddr e = pkt.ethernet() e.src = EthAddr(dpid_to_str(self.dpid)) #FIXME: Hmm... e.dst = match.dl_src e.type = e.IP_TYPE ipp = pkt.ipv4() ipp.protocol = ipp.ICMP_PROTOCOL ipp.srcip = match.nw_dst #FIXME: Ridiculous ipp.dstip = match.nw_src #Seems to work with UDP and TCP too. Weird but ok. icmp = pkt.icmp() icmp.type = pkt.ICMP.TYPE_DEST_UNREACH icmp.code = pkt.ICMP.CODE_UNREACH_HOST orig_ip = event.parsed.find('ipv4') d = orig_ip.pack() d = d[:orig_ip.hl * 4 + 8] import struct d = struct.pack("!HH", 0, 0) + d #FIXME: MTU icmp.payload = d ipp.payload = icmp e.payload = ipp msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port=event.port)) msg.data = e.pack() self.connection.send(msg) print "Installing path for %s -> %s %04x (%i hops)", match.dl_src, match.dl_dst, match.dl_type, len( p) return log.debug("Installing path for %s -> %s %04x (%i hops)", match.dl_src, match.dl_dst, match.dl_type, len(p)) # We have a path -- install it self._install_path(p, match, event.ofp) # Now reverse it and install it backwards # (we'll just assume that will work) p = [(sw, out_port, in_port) for sw, in_port, out_port in p] self._install_path(p, match.flip())
def _handle_PacketIn(self, event): balancer_ip = IPAddr("10.0.0.99") balancer_eth = EthAddr("00:00:00:00:00:99") packet = event.parsed packet_in = event.ofp flow = of.ofp_flow_mod() flow.match = of.ofp_match.from_packet(packet) flow.match.in_port = packet_in.in_port if flow.match.nw_src not in self.dicts: self.dicts[flow.match.nw_src] = packet_in.in_port if flow.match.nw_dst == balancer_ip: # if the request is to balancer print("[Request]: From " + str(flow.match.nw_src) + " to " + str(flow.match.nw_dst)) if flow.match.in_port == self.ind + 1: # if the chosen server is the same as the client self.ind = (self.ind + 1) % self.N # shift the server id ethnum = str(hex(self.ind + 1)) if self.ind < 15: ethnum = "0" + ethnum[2:len(ethnum)] else: ethnum = ethnum[2:len(ethnum)] ipnum = str(self.ind + 1) server_port = self.ind + 1 server_ip = IPAddr("10.0.0." + ipnum) server_eth = EthAddr("00:00:00:00:00:" + ethnum) print("The chosen server is " + str(server_ip)) print(server_eth) flow.buffer_id = packet_in.buffer_id new_ip_dst = of.ofp_action_nw_addr(7, server_ip) new_eth_dst = of.ofp_action_dl_addr(5, server_eth) action = of.ofp_action_output(port=server_port) flow.actions.append(new_ip_dst) flow.actions.append(new_eth_dst) self.ind = (self.ind + 1) % self.N flow.idle_timeout = of.OFP_FLOW_PERMANENT flow.hard_timeout = of.OFP_FLOW_PERMANENT flow.priority = 65535 flow.actions.append(action) event.connection.send(flow) flow.command = of.OFPFC_DELETE event.connection.send(flow) # indicate the current server and client info self.cur_client = packet_in.in_port self.cur_ser = server_port self.request = 1 else: if flow.match.nw_dst in self.dicts: outport = self.dicts[flow.match.nw_dst] else: outport = of.OFPP_ALL if outport == self.cur_client and self.request == 1: #response message new_ip_src = of.ofp_action_nw_addr(6, balancer_ip) new_eth_src = of.ofp_action_dl_addr(4, balancer_eth) action = of.ofp_action_output(port=outport) flow.buffer_id = packet_in.buffer_id flow.idle_timeout = of.OFP_FLOW_PERMANENT flow.hard_timeout = of.OFP_FLOW_PERMANENT flow.priority = 65535 flow.actions.append(new_ip_src) flow.actions.append(new_eth_src) flow.actions.append(action) event.connection.send(flow) flow.command = of.OFPFC_DELETE event.connection.send(flow) print("[Response]: Server " + str(self.cur_ser) + " response") self.cur_ser = -1 self.cur_client = -1 self.request = 0 else: action = of.ofp_action_output(port=outport) flow.idle_timeout = of.OFP_FLOW_PERMANENT flow.hard_timeout = of.OFP_FLOW_PERMANENT flow.priority = 65535 flow.actions.append(action) if event.ofp.buffer_id != -1: flow.buffer_id = event.ofp.buffer_id event.connection.send(flow) print("Normal Message from " + str(flow.match.nw_src) + " to " + str(flow.match.nw_dst)) flow.command = of.OFPFC_DELETE event.connection.send(flow) return
def launch_namespace(cmd, guest_ip_addr_str, iface_number, prefix_length=24, host_ip_addr_str="", guest_hw_addr=None, cwd=None, env=None): ''' Set up and launch cmd in a new network namespace. Returns a pair: (raw socket bound to host veth interface, Popen object for communicating with guest namespace) This method uses functionality that requires CAP_NET_ADMIN capabilites. This means that the calling method should check that the python process was launched as admin/superuser. Parameters: - cmd: the string to launch, in a separate namespace - ip_addr_str: the ip address to assign to the namespace's interace. Must be a string! not a IPAddr object - iface_number: unique integer for the namespace and host virtual interfaces. - guest_hw_addr: mac address for the guest (auto generated if None) ''' if system() != 'Linux': raise EnvironmentError('network namespace functionality requires a Linux environment') uid = os.geteuid() if uid != 0: # user must have CAP_NET_ADMIN, which doesn't have to be su, but most often is raise EnvironmentError("superuser privileges required to launch network namespace") host_device = "heth%s" % str(iface_number) guest_device = "geth%s" % str(iface_number) try: # Clean up previous network namespaces # (Delete the device if it already exists) with open(os.devnull, 'wb') as null: for dev in (host_device, guest_device): if subprocess.call(['ip', 'link', 'show', dev], stdout=null, stderr=null) == 0: subprocess.check_call(['ip', 'link', 'del', dev]) # create a veth pair and set the host end to be promiscuous add_cmd = ['ip','link','add','name',host_device,'type','veth','peer', 'name',guest_device] if guest_hw_addr: guest_hw_addr = EthAddr(guest_hw_addr) add_cmd.append('address') add_cmd.append(guest_hw_addr.toStr()) subprocess.check_call(add_cmd) guest_eth_addr = get_eth_address_for_interface(guest_device) log.debug("Guest ETH %s" % guest_eth_addr) host_eth_addr = get_eth_address_for_interface(host_device) log.debug("Host ETH %s" % host_eth_addr) subprocess.check_call(['ip','link','set',host_device,'promisc','on']) # Our end of the veth pair subprocess.check_call(['ip','link','set',host_device,'up']) if host_ip_addr_str != "": # Set a host IP on the same subnet as the guest so that host sockets automatically get # bound to the correct virtual interface. subprocess.check_call(['ip', 'addr', 'add', "%s/%d" % (host_ip_addr_str, prefix_length), 'dev', host_device]) except subprocess.CalledProcessError: raise # TODO raise a more informative exception # all else should have succeeded, so now we fork and unshare for the guest # TODO(cs): use popen_filtered here? guest = subprocess.Popen(["unshare", "-n", "--", "/bin/bash"], stdin=subprocess.PIPE, env=env, cwd=cwd) # push down the guest device into the netns try: subprocess.check_call(['ip', 'link', 'set', guest_device, 'netns', str(guest.pid)]) except subprocess.CalledProcessError: raise # TODO raise a more informative exception # Bring up the interface on the guest. guest.stdin.write("ip link set %s up\n" % guest_device) # Set the IP address of the virtual interface. Note that this has the nice # side effect that the host can open sockets to the IP address (since the # guest will begin responding to ARPs). guest.stdin.write("ip addr add %s/%d dev %s\n" % (guest_ip_addr_str, prefix_length, guest_device)) # Send the command. guest.stdin.write(cmd + "\n") return (guest, guest_eth_addr, host_device)
#print (data) f.close() i=0 for line in data: columns=line.split() if (columns.__len__()==0): break serverList[i]={'ip':IPAddr(columns[0]), 'mac':EthAddr(columns[1]), 'port': int(columns[2])} #serverList[i]={'ip':columns[0], 'mac':columns[1], 'outport': columns[2]} print (serverList[i]) i=i+1 print (i) server_virtual_ip = IPAddr(virtual_ip) server_virtual_mac = EthAddr(virtual_mac) print (server_virtual_ip) print (server_virtual_mac) #Round Robin ServerUsed = 0 def _handle_PacketIn (event): #Round_Robin(event) global ServerUsed global server_virtual_ip global server_virtual_mac packet = event.parsed msg_to_server = of.ofp_flow_mod() msg_to_server.match = of.ofp_match.from_packet(packet) if (event.parsed.find("ipv4")) and (msg_to_server.match.nw_dst == server_virtual_ip):
def _fix_eth(n): if n is None: return None return EthAddr(n)
from pox.lib.revent import event_cont,EventHalt import pox.openflow.libopenflow_01 as of from pox.core import core from pox.lib.addresses import IPAddr,EthAddr,parse_cidr from pox.lib.util import dpidToStr import sys log = core.getLogger() #global variables #ip and mac for load balancer load_balancer_hardcoded_ip = IPAddr("10.0.0.5") load_balancer_hardcoded_mac = EthAddr("00:00:00:00:00:05") #assigning ip and weights for the other 3 servers topology_server = {} topology_server[0] = {'ip':IPAddr("10.0.0.2"), 'mac':EthAddr("00:00:00:00:00:02"), 'outport': 2,'weight':int(3)} topology_server[1] = {'ip':IPAddr("10.0.0.3"), 'mac':EthAddr("00:00:00:00:00:03"), 'outport': 3,'weight':int(2)} topology_server[2] = {'ip':IPAddr("10.0.0.4"), 'mac':EthAddr("00:00:00:00:00:04"), 'outport': 4,'weight':int(1)} count_server = len(topology_server) count_server = 0 #handlers def packet_handler (event): global count_server packet = event.parsed
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
from pox.core import core import pox.openflow.libopenflow_01 as of from pox.lib.addresses import IPAddr from pox.lib.addresses import EthAddr from pox.lib.util import dpid_to_str, str_to_bool from pox.lib.packet.arp import arp from pox.lib.packet.ethernet import ethernet, ETHER_BROADCAST from pox.lib.packet.icmp import * from pox.lib.packet.ipv4 import * log = core.getLogger() _arp_cache = { IPAddr('10.0.1.1'): EthAddr('00:00:00:00:00:04'), IPAddr('10.0.2.1'): EthAddr('00:00:00:00:00:07'), '1': EthAddr('00:00:00:00:00:05'), '2': EthAddr('00:00:00:00:00:06'), EthAddr('00:00:00:00:00:05'): IPAddr('10.0.3.1'), EthAddr('00:00:00:00:00:06'): IPAddr('10.0.3.2'), EthAddr('00:00:00:00:00:04'): IPAddr('10.0.1.1'), EthAddr('00:00:00:00:00:07'): IPAddr('10.0.2.1') } _route1 = ([(IPAddr('10.0.1.2'), IPAddr('10.0.1.1'), 2, '10.0.1.0/24', EthAddr('00:00:00:00:00:04')), (IPAddr('10.0.1.3'), IPAddr('10.0.1.1'), 3, '10.0.1.0/24', EthAddr('00:00:00:00:00:04')), (IPAddr('10.0.2.2'), IPAddr('10.0.2.1'), 1, '10.0.2.0/24', EthAddr('00:00:00:00:00:05'))]) _route2 = ([(IPAddr('10.0.1.2'), IPAddr('10.0.1.1'), 1, '10.0.1.0/24', EthAddr('00:00:00:00:00:06')), (IPAddr('10.0.1.3'), IPAddr('10.0.1.1'), 1, '10.0.1.0/24',
def get_mac(self, dpid_string): e = EthAddr(int(dpid_string)) if not e in self.mac_map: self.mac_map[e.toInt()] = dpid_string return e.toInt()
def _handle_PacketIn(self, event): log.info('Start main funciton') dpid = event.connection.dpid #log.info('dpid is %s ' %dpid) packet = event.parsed # This is the parsed packet data. inport = event.port if not packet.parsed: log.warning("%s: ignoring unparsed packet", dpid_to_str(dpid)) return packet_in = event.ofp # The actual ofp_packet_in message. #log.info("Installing flow...") # Maybe the log statement should have source/destination/port? #log.debug('the source MAC is %s' %packet.src) #log.debug('the dist MAC is %s' %packet.dst) #log.debug('the source port is %s' %packet_in.in_port) if dpid == 1: _route = _route1 else: _route = _route2 '***********************ARP**********************************' if packet.find("arp"): a = packet.find('arp') if not a: return log.debug("ARP %s %s => %s", { arp.REQUEST: "request", arp.REPLY: "reply" }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc), str(a.protodst)) _ip_to_port[IPAddr(a.protosrc)] = inport #Deal with ARP REQUEST then ARP REPLY to hosts if a.prototype == arp.PROTO_TYPE_IP and a.hwtype == arp.HW_TYPE_ETHERNET and a.opcode == arp.REQUEST: _arp_cache[IPAddr(a.protosrc)] = EthAddr(a.hwsrc) #log.info('store to cache %s' %_arp_cache) #log.info('self._arp_cache[a.protosrc] = %s protosrc is %s' %(self._arp_cache[IPAddr(a.protosrc)],IPAddr(a.protosrc))) if dpid == 2 and inport == 1: p = arp() p.hwtype = arp.HW_TYPE_ETHERNET p.prototype = arp.PROTO_TYPE_IP p.hwlen = 6 p.protolen = 4 p.opcode = arp.REQUEST p.hwdst = EthAddr('ff:ff:ff:ff:ff:ff') p.hwsrc = EthAddr('00:00:00:00:00:07') p.protodst = _route[2][0] p.protosrc = _route[2][1] E = ethernet(type=ethernet.ARP_TYPE, src=p.hwsrc, dst=p.hwdst) E.payload = p self.resend_packet(E, 2) elif dpid == 1 and inport == 1: pp = arp() pp.hwtype = arp.HW_TYPE_ETHERNET pp.prototype = arp.PROTO_TYPE_IP pp.hwlen = 6 pp.protolen = 4 pp.opcode = arp.REQUEST pp.hwdst = EthAddr('ff:ff:ff:ff:ff:ff') pp.hwsrc = EthAddr('00:00:00:00:00:04') pp.protodst = a.protodst pp.protosrc = IPAddr('10.0.1.1') EE = ethernet(type=ethernet.ARP_TYPE, src=pp.hwsrc, dst=pp.hwdst) EE.payload = pp self.resend_packet(EE, 2) self.resend_packet(EE, 3) else: 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 if str(a.protodst) == '10.0.1.1': r.hwsrc = EthAddr('00:00:00:00:00:04') if str(a.protodst) == '10.0.2.1': r.hwsrc = EthAddr('00:00:00:00:00:07') e = ethernet(type=packet.type, src=r.hwsrc, dst=a.hwsrc) e.payload = r log.info("Answering ARP for %s" % (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) msg1 = of.ofp_flow_mod() msg1.match = of.ofp_match() msg1.match.dl_type = 0x800 msg1.match.nw_dst = a.protosrc msg1.actions.append(of.ofp_action_dl_addr.set_src(r.hwsrc)) msg1.actions.append(of.ofp_action_dl_addr.set_dst(r.hwdst)) msg1.actions.append(of.ofp_action_output(port=inport)) self.connection.send(msg1) #Deal with ARP REPLY and store ARP cache #Prepare to send buffered ICMP REQUEST packets with new MAC address if a.prototype == arp.PROTO_TYPE_IP and a.hwtype == arp.HW_TYPE_ETHERNET and a.opcode == arp.REPLY: _arp_cache[IPAddr(a.protosrc)] = EthAddr(a.hwsrc) msg2 = of.ofp_flow_mod() msg2.match = of.ofp_match() msg2.match.dl_type = 0x800 msg2.match.nw_dst = a.protosrc msg2.actions.append(of.ofp_action_dl_addr.set_src(a.hwdst)) msg2.actions.append(of.ofp_action_dl_addr.set_dst(a.hwsrc)) msg2.actions.append(of.ofp_action_output(port=inport)) self.connection.send(msg2) self.msg_send(_buff[IPAddr(a.protosrc)], a.hwdst, a.hwsrc, inport) #self.icmp_forward(_buff[IPAddr(a.protosrc)],TYPE_ECHO_REQUEST,_ip_bf[IPAddr(a.protosrc)].srcip,_ip_bf[IPAddr(a.protosrc)].dstip,a.hwdst,a.hwsrc,inport) log.info('forward dic %s' % _buff[IPAddr(a.protosrc)]) '****************************ICMP***********************' if packet.find("icmp"): log.info('ICMP occurs') _ip_to_port[IPAddr(packet.payload.srcip)] = inport #intall the packet and get information of the packet #rqt_src: router interface IP addr; rqt_port: router port; rqt_pfx: network prefix; rqt_hwsrc: router interface MAC addr. payload_bf = packet.payload.payload.payload icmp_bf = packet.payload.payload #log.info('icmp type =%s'%packet.payload.payload.type) global rqtsrc, rqtdst, rqtport, rqtpfx, rqthwsrc global rplsrc, rpldst, rplport, rplpfx, rplhwsrc #log.debug('before loop:') #log.info('icmp cache is %s' %_arp_cache) target = 0 for j in range(0, 5): for i in range(0, 3): if str(_route[i][j]) == str(packet.payload.dstip): if j == 0: rqtsrc = _route[i][1] rqtdst = _route[i][0] rqtport = _route[i][2] rqtpfx = _route[i][3] rqthwsrc = _route[i][4] #target = 1 means the icmp packet is to host target = 1 break elif j == 1: #router reply to host rplsrc = _route[i][1] rpldst = _route[i][0] rplport = _route[i][2] rplpfx = _route[i][3] rplhwsrc = _route[i][4] #target = 2 means the icmp packet is to router interface target = 2 flagd = i break for k in range(0, 3): if str(_route[k][0]) == str(packet.payload.srcip): interfaceip = _route[k][1] interfacedst = _route[k][0] flags = _route[k][2] break '*********ICMP REQUEST***' if target == 0: log.info('unknown') self.icmp_unknownhost(packet, interfaceip, inport) log.info('unknown from %s' % interfaceip) elif packet.payload.payload.type == 8 and target != 0: #If we do not have IP_MAC in routing table, create ARP Request if packet.payload.dstip not in _arp_cache: self.arp_request(packet, _arp_cache[rqthwsrc], rqthwsrc, rqtport) _buff[IPAddr(packet.payload.dstip)] = packet _ip_bf[IPAddr(packet.payload.dstip)] = packet.payload #log.info('buff %s' %_buff) #If we have IP_MAC in routing table, forward packet directly elif packet.payload.dstip in _arp_cache: if target == 1: if dpid == 1: if rqtport != 1: #h3 ICMP request forward to h4 self.icmp_forward( packet.payload.payload.payload, TYPE_ECHO_REQUEST, packet.payload.srcip, packet.payload.dstip, rqthwsrc, _arp_cache[IPAddr(packet.payload.dstip)], rqtport) else: #s1 ICMP request forward to s2 self.msg_send(packet, packet.src, packet.dst, 1) else: if inport == 1: #s2 have to forward it to h5 self.icmp_forward( packet.payload.payload.payload, TYPE_ECHO_REQUEST, packet.payload.srcip, packet.payload.dstip, _arp_cache[rqtsrc], _arp_cache[IPAddr(packet.payload.dstip)], rqtport) else: #s2 give it to s1 self.msg_send(packet, packet.src, packet.dst, 1) elif target == 2: #log.debug('icmp cache %s' %_arp_cache) #log.info('flags is %s' %flags) #log.info('dpid is %s, rplport is %s, dstinterface is %s' %(dpid, rplport,interfaceip)) if dpid == 1: if rplport != inport: #ping other gateway self.icmp_forward(payload_bf, TYPE_ECHO_REPLY, rplsrc, interfacedst, packet.dst, packet.src, inport) else: #ping default gateway self.icmp_forward(payload_bf, TYPE_ECHO_REPLY, rplsrc, rpldst, rplhwsrc, _arp_cache[IPAddr(rpldst)], rplport) else: if flags == flagd: #ping default gateway self.icmp_forward(payload_bf, TYPE_ECHO_REPLY, rplsrc, rpldst, rplhwsrc, _arp_cache[IPAddr(rpldst)], rplport) else: #ping other gateway self.icmp_forward(payload_bf, TYPE_ECHO_REPLY, interfaceip, interfacedst, packet.dst, packet.src, inport) ############ICMP REPLY############### #Receive ICPM Reply, we need forward the the reply elif packet.payload.payload.type == 0: if dpid == 2: #h5 reply to h3 if inport == 2: log.info('flow mod starts 1') msg0 = of.ofp_flow_mod() msg0.match = of.ofp_match() msg0.match.dl_type = 0x800 msg0.match.nw_dst = packet.payload.dstip msg0.actions.append( of.ofp_action_dl_addr.set_src(_port_to_mac_2['1'])) msg0.actions.append( of.ofp_action_dl_addr.set_dst(_port_to_mac_1['1'])) msg0.actions.append(of.ofp_action_output(port=1)) log.info('flow mod ends 1') self.connection.send(msg0) self.msg_send(packet, packet.src, packet.dst, 1) else: self.msg_send(packet, rqthwsrc, _arp_cache[packet.payload.dstip], rqtport) elif dpid == 1 and rqtport != 1: #h3 and h4 want to receive if inport != 1: self.icmp_forward( packet.payload.payload.payload, TYPE_ECHO_REPLY, packet.payload.srcip, packet.payload.dstip, rqthwsrc, _arp_cache[IPAddr(packet.payload.dstip)], rqtport) else: self.msg_send(packet, rqthwsrc, _arp_cache[packet.payload.dstip], rqtport) else: log.info('flow mod starts 2') msg3 = of.ofp_flow_mod() msg3.match = of.ofp_match() msg3.match.dl_type = 0x800 msg3.match.nw_dst = packet.payload.dstip msg3.actions.append( of.ofp_action_dl_addr.set_src(_port_to_mac_1['1'])) msg3.actions.append( of.ofp_action_dl_addr.set_dst(_port_to_mac_2['1'])) msg3.actions.append(of.ofp_action_output(port=1)) log.info('flow mod end 2') self.connection.send(msg3) self.msg_send(packet, packet.src, packet.dst, 1) #log.info('ICMP reply for h5 from s1 to s2') #########TCP+UDP############ elif packet.find("ipv4"): log.info('TCP occurs') for i in range(0, 3): if str(_route[i][0]) == str(packet.payload.dstip): tcpsrc = _route[i][1] tcpdst = _route[i][0] tcpport = _route[i][2] tcppfx = _route[i][3] tcphwsrc = _route[i][4] break if packet.payload.dstip in _arp_cache: if dpid == 1: if tcpport == 1: #s1 send the request to s2 self.msg_send(packet, _port_to_mac_1['1'], _port_to_mac_2['1'], 1) else: #s1 send the request to h4 self.msg_send(packet, tcphwsrc, _arp_cache[tcpdst], tcpport) else: #s2 received a request if inport == 1: #s2 send the request to h5 self.msg_send(packet, tcphwsrc, _arp_cache[tcpdst], tcpport) else: #s2 send to s1 self.msg_send(packet, _port_to_mac_2['1'], _port_to_mac_1['1'], 1) else: #not in cache _buff[IPAddr(packet.payload.dstip)] = packet if dpid == 1: if tcpport == 1: #s1 send the arp request to s2 self.arp_request(packet, _arp_cache[_port_to_mac_1['1']], _port_to_mac_1['1'], 1) else: #s1 broadcast arp request self.arp_request(packet, tcpsrc, tcphwsrc, 2) self.arp_request(packet, tcpsrc, tcphwsrc, 3) else: #s2 send the arp request to s1 self.arp_request(packet, _arp_cache[_port_to_mac_2['1']], _port_to_mac_2['1'], 1)
def _handle_PacketIn (self, event): global foo """ Handles packet in messages from the switch. """ packet = event.parsed # This is the parsed packet data. log.debug("here") #self.check_migration() log.debug(packet) log.debug(packet.__dict__) log.debug("there") if(foo==[] or foo[0] == '\n'): foo = filter(None,open("/home/mininet/migrationVaribles","r").read().split(' ')) log.debug("there2") log.debug(foo) log.debug("there1") srcaddr = EthAddr(packet.src) dstaddr = EthAddr(packet.dst) if countDictionary.has_key(srcaddr.toStr()): countDictionary[srcaddr] = countDictionary[srcaddr] + 1 else: countDictionary[srcaddr] = 0 if countDictionary.has_key(dstaddr.toStr()): countDictionary[dstaddr] = countDictionary[dstaddr] + 1 else: countDictionary[dstaddr] = 0 if not packet.parsed: log.warning("Ignoring incomplete packet") return packet_in = event.ofp # The actual ofp_packet_in message. if(foo!=[]): if(foo[0]!='\n'): log.debug("yaha aayaa ") if srcaddr.toStr() == foo[0]: log.debug("yaha 1") self.update(foo[1], packet, packet_in) elif dstaddr.toStr() == foo[0]: log.debug("yaha 2") self.update(foo[1], packet, packet_in) if dstaddr.toStr() == foo[0]: log.debug("yaha 3") self.update(foo[1], packet, packet_in) elif srcaddr.toStr() == foo[1]: log.debug("yaha 1") self.update(foo[0], packet, packet_in) # This line calls the function act_like_lswitch and passes # the parsed package and the openflow packet message to our # learning switch self.act_like_lswitch(packet, packet_in)
def ip_for_event(event): """ Use a switch's DPID as an EthAddr """ eth = dpid_to_str(event.dpid, True).split("|")[0].replace("-", ":") return EthAddr(eth)