Example #1
0
    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
Example #2
0
 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?
Example #3
0
 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")
Example #5
0
 def _init(self, *args, **kw):
     a = kw.pop('address', None)
     if a is None:
         self.address = None
     else:
         self.address = EthAddr(a)
Example #6
0
		def __init__ (self, ip, mac, port):
			self.ip = IPAddr(ip)
			self.mac = EthAddr(mac)
			self.port = port
Example #7
0
    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))
Example #8
0
 def _unpack_new(cls, raw, offset, t, length, prev):
     return offset + length, cls(address=EthAddr(raw[offset:offset +
                                                     length]),
                                 prev=prev)
Example #9
0
def dpid_port_to_mac(dpid, port):
    msb = port & 0xff
    lsbs = int(dpid) & 0x00FFffFFffFF
    eth_addr = (msb << 40) | lsbs
    return EthAddr("%012x" % eth_addr)
Example #10
0
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,
Example #11
0
    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',
        }
Example #13
0
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'
    )
Example #14
0
 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)
Example #15
0
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
Example #18
0
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
Example #20
0
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={}
Example #21
0
def GetMACForLoadBalancing():
    value = GetMACForLoadBalancing.nextvalue
    GetMACForLoadBalancing.nextvalue += 1
    return EthAddr("031337%06x" % (value & 0xFFFFFF))
Example #22
0
 def eth_addr(self):
     dpid = self.dpid
     if self.dpid is None:
         raise RuntimeError("eth_addr not available")
     return EthAddr("%012x" % (dpid & 0xffFFffFFffFF, ))
Example #23
0
 def link (addr):
   if addr is None: return None
   if len(addr) != 6: return None
   return EthAddr(addr)
Example #24
0
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")
Example #26
0
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)
Example #28
0
    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())
Example #29
0
    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
Example #30
0
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)
Example #31
0
    #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):
Example #32
0
def _fix_eth(n):
    if n is None: return None
    return EthAddr(n)
Example #33
0
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
Example #34
0
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
Example #35
0
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',
Example #36
0
 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()
Example #37
0
    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)
Example #39
0
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)