Exemplo n.º 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
Exemplo n.º 2
0
	def _findSwitchNameAndNetworkOfDest(self, destIp):
		dest = IPAddr(destIp)
		ans = []
		for entry in self.routingTable:
			if dest.inNetwork(entry.network):
				ans.append( (entry.name, entry.network) )
		return ans
Exemplo n.º 3
0
    def parse(self, raw):
        assert isinstance(raw, bytes)
        self.next = None # In case of unfinished parsing
        self.raw = raw
        dlen = len(raw)
        if dlen < ipv4.MIN_LEN:
            self.msg('warning IP packet data too short to parse header: data len %u' % (dlen,))
            return

        (vhl, self.tos, self.iplen, self.id, self.frag, self.ttl,
            self.protocol, self.csum, self.srcip, self.dstip) \
             = struct.unpack('!BBHHHBBHII', raw[:ipv4.MIN_LEN])

        self.v = vhl >> 4
        self.hl = vhl & 0x0f

        self.flags = self.frag >> 13
        self.frag  = self.frag & 0x1fff

        self.dstip = IPAddr(self.dstip)
        self.srcip = IPAddr(self.srcip)

        if self.v != ipv4.IPv4:
            self.msg('(ip parse) warning IP version %u not IPv4' % self.v)
            return
        elif self.hl < 5:
            self.msg('(ip parse) warning IP header %u longer than len %u' \
                        % (self.hl, self.iplen))
            return
        elif self.iplen < ipv4.MIN_LEN:
            self.msg('(ip parse) warning invalid IP len %u' % self.iplen)
            return
        elif (self.hl * 4) >= self.iplen or (self.hl * 4) > dlen:
            self.msg('(ip parse) warning IP header %u longer than len %u' \
                        % (self.hl, self.iplen))
            return

        # At this point, we are reasonably certain that we have an IP
        # packet
        self.parsed = True

        length = self.iplen
        if length > dlen:
            length = dlen # Clamp to what we've got
        if self.protocol == ipv4.UDP_PROTOCOL:
            self.next = udp(raw=raw[self.hl*4:length], prev=self)
        elif self.protocol == ipv4.TCP_PROTOCOL:
            self.next = tcp(raw=raw[self.hl*4:length], prev=self)
        elif self.protocol == ipv4.ICMP_PROTOCOL:
            self.next = icmp(raw=raw[self.hl*4:length], prev=self)
        elif self.protocol == ipv4.IGMP_PROTOCOL:
            self.next = igmp(raw=raw[self.hl*4:length], prev=self)
        elif dlen < self.iplen:
            self.msg('(ip parse) warning IP packet data shorter than IP len: %u < %u' % (dlen, self.iplen))
        else:
            self.next =  raw[self.hl*4:length]

        if isinstance(self.next, packet_base) and not self.next.parsed:
            self.next = raw[self.hl*4:length]
Exemplo n.º 4
0
	def getOutPortForIp(self, switch, destIp):
		if DEBUG:
			print '*** _getOutPortForIp:'
			print switch, destIp
		dest = IPAddr(destIp)
		for entry in self.routingTable:
			if dest.inNetwork(entry.network) and \
						switch.name == entry.name:
				return entry.port	# port number
		return None
Exemplo n.º 5
0
 def __contains__ (self, item):
   item = IPAddr(item)
   if item in self.removed: return False
   n = item.toUnsigned()
   mask = (1<<self.host_size)-1
   nm = (n & mask) | self.network.toUnsigned()
   if nm != n: return False
   if (n & mask) == mask: return False
   if (n & mask) < self.first: return False
   if (n & mask) > self.last: return False
   return True
Exemplo n.º 6
0
 def __init__ (self, device = None, promiscuous = True, period = 10,
               start = True, callback = None, filter = None):
   if filter is not None:
     self.deferred_filter = (filter,)
   else:
     self.deferred_filter = None
   self.packets_received = 0
   self.packets_dropped = 0
   self._thread = None
   self.pcap = None
   self.promiscuous = promiscuous
   self.device = None
   self.period = period
   self.netmask = IPAddr("0.0.0.0")
   self._quitting = False
   self.addresses = {}
   if callback is None:
     self.callback = self.__class__._handle_rx
   else:
     self.callback = callback
   if device is not None:
     self.open(device)
   if self.pcap is not None:
     if start:
       self.start()
Exemplo n.º 7
0
class MTDIPPrefix(object):
    def __init__(self, pattern):
        parts = pattern.split("/")
        if len(parts) != 2:
            raise TypeError
        
        self.masklen = int(parts[1])
        self.pattern = IPAddr(parts[0])

        bits = bitarray()
        bits.frombytes(self.pattern.toRaw())
        self.prefix = bits[:self.masklen]

    def rand_ip_addr(self):
        rbitslen = 32 - self.masklen
        rbits = bin(random.getrandbits(rbitslen))[2:]
        return IPAddr((self.prefix + rbits.zfill(rbitslen)).tobytes())

    def __repr__(self):
        return "%s/%d" % (repr(self.pattern), self.masklen)

    def __contains__(self, ipaddr):
        if not isinstance(ipaddr, IPAddr):
            raise TypeError
        
        ipaddr_bits = bitarray()
        ipaddr_bits.frombytes(ipaddr.toRaw())

        return self.prefix == ipaddr_bits[:self.masklen]
Exemplo n.º 8
0
    def __init__(self, pattern):
        parts = pattern.split("/")
        if len(parts) != 2:
            raise TypeError
        
        self.masklen = int(parts[1])
        self.pattern = IPAddr(parts[0])

        bits = bitarray()
        bits.frombytes(self.pattern.toRaw())
        self.prefix = bits[:self.masklen]
Exemplo n.º 9
0
 def ip (self):
     ip = IPAddr("192.168.1.1")
     print str(ip)
     print ip.toUnsignedN() # converts to network-order unsigned integer 16885952
     print ip.toRaw() # returns a length-four bytes object 
     print "*****"
     ip = IPAddr(16885952, networkOrder=True)
     print str(ip)
    def __init__(
        self,
        device=None,
        promiscuous=True,
        period=10,
        start=True,
        callback=None,
        filter=None,
        use_bytearray=False,
        **kw
    ):
        """
    Initialize this instance

    use_bytearray: specifies capturing to bytearray buffers instead of bytes
    """

        if filter is not None:
            self.deferred_filter = (filter,)
        else:
            self.deferred_filter = None
        self.packets_received = 0
        self.packets_dropped = 0
        self._thread = None
        self.pcap = None
        self.promiscuous = promiscuous
        self.device = None
        self.use_bytearray = use_bytearray
        self.period = period
        self.netmask = IPAddr("0.0.0.0")
        self._quitting = False
        self.addresses = {}
        if callback is None:
            self.callback = self.__class__._handle_rx
        else:
            self.callback = callback

        for k, v in kw.items():
            assert not hasattr(self, k)
            setattr(self, k, v)

        if device is not None:
            self.open(device)
        if self.pcap is not None:
            if start:
                self.start()
 def open(self, device, promiscuous=None, period=None, incoming=True, outgoing=False):
     assert self.device is None
     self.addresses = self.get_devices()[device]["addrs"]
     if "AF_INET" in self.addresses:
         self.netmask = self.addresses["AF_INET"].get("netmask")
         if self.netmask is None:
             self.netmask = IPAddr("0.0.0.0")
     # print "NM:",self.netmask
     # print self.addresses['AF_LINK']['addr']
     self.device = device
     if period is not None:
         self.period = period
     if promiscuous is not None:
         self.promiscuous = promiscuous
     self.pcap = pcapc.open_live(device, 65535, 1 if self.promiscuous else 0, self.period)
     pcapc.setdirection(self.pcap, incoming, outgoing)
     self.packets_received = 0
     self.packets_dropped = 0
     if self.deferred_filter is not None:
         self.set_filter(*self.deferred_filter)
         self.deferred_filter = None
Exemplo n.º 12
0
  def __init__ (self, network = "192.168.1.0/24", first = 2, last = None,
                count = None):
    """
    Simple subnet-based address pool

    Allocates count IP addresses out of network/network_size, starting
    with the first'th.  You may specify the end of the range with either
    last (to specify the last'th address to use) or count to specify the
    number to use.  If both are None, use up to the end of all
    legal addresses.

    Example for all of 192.168.x.x/16:
      SimpleAddressPool("192.168.0.0/16", 1, 65534)
    """
    network,network_size = parse_cidr(network)

    self.first = first
    self.network_size = network_size
    self.host_size = 32-network_size
    self.network = IPAddr(network)


    if last is None and count is None:
      self.last = (1 << self.host_size) - 2
    elif last is not None:
      self.last = last
    elif count is not None:
      self.last = self.first + count - 1
    else:
      raise RuntimeError("Cannot specify both last and count")

    self.removed = set()

    if self.count <= 0: raise RuntimeError("Bad first/last range")
    if first == 0: raise RuntimeError("Can't allocate 0th address")
    if self.host_size < 0 or self.host_size > 32:
      raise RuntimeError("Bad network")
    if IPAddr(self.last | self.network.toUnsigned()) not in self:
      raise RuntimeError("Bad first/last range")
Exemplo n.º 13
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
Exemplo n.º 14
0
class SimpleAddressPool (AddressPool):
  """
  Simple AddressPool for simple subnet based pools.
  """
  def __init__ (self, network = "192.168.0.0/24", first = 1, last = None,
                count = None):
    """
    Simple subnet-based address pool

    Allocates count IP addresses out of network/network_size, starting
    with the first'th.  You may specify the end of the range with either
    last (to specify the last'th address to use) or count to specify the
    number to use.  If both are None, use up to the end of all
    legal addresses.

    Example for all of 192.168.x.x/16:
      SimpleAddressPool("192.168.0.0/16", 1, 65534)
    """
    network,network_size = parse_cidr(network)

    self.first = first
    self.network_size = network_size
    self.host_size = 32-network_size
    self.network = IPAddr(network)

    if last is None and count is None:
      self.last = (1 << self.host_size) - 2
    elif last is not None:
      self.last = last
    elif count is not None:
      self.last = self.first + count - 1
    else:
      raise RuntimeError("Cannot specify both last and count")

    self.removed = set()

    if self.count <= 0: raise RuntimeError("Bad first/last range")
    if first == 0: raise RuntimeError("Can't allocate 0th address")
    if self.host_size < 0 or self.host_size > 32:
      raise RuntimeError("Bad network")
    if IPAddr(self.last | self.network.toUnsigned()) not in self:
      raise RuntimeError("Bad first/last range")

  def __repr__ (self):
    return str(self)

  def __str__ (self):
    t = self.network.toUnsigned()
    t = (IPAddr(t|self.first),IPAddr(t|self.last))
    return "<Addresses from %s to %s>" % t

  @property
  def subnet_mask (self):
    return IPAddr(((1<<self.network_size)-1) << self.host_size)

  @property
  def count (self):
    return self.last - self.first + 1

  def __contains__ (self, item):
    item = IPAddr(item)
    if item in self.removed: return False
    n = item.toUnsigned()
    mask = (1<<self.host_size)-1
    nm = (n & mask) | self.network.toUnsigned()
    if nm != n: return False
    if (n & mask) == mask: return False
    if (n & mask) < self.first: return False
    if (n & mask) > self.last: return False
    return True

  def append (self, item):
    item = IPAddr(item)
    if item not in self.removed:
      if item in self:
        raise RuntimeError("%s is already in this pool" % (item,))
      else:
        raise RuntimeError("%s does not belong in this pool" % (item,))
    self.removed.remove(item)

  def remove (self, item):
    item = IPAddr(item)
    if item not in self:
      raise RuntimeError("%s not in this pool" % (item,))
    self.removed.add(item)

  def __len__ (self):
    return (self.last-self.first+1) - len(self.removed)

  def __getitem__ (self, index):
    if index < 0:
      raise RuntimeError("Negative indices not allowed")
    if index >= len(self):
      raise IndexError("Item does not exist")
    c = self.first

    # Use a heuristic to find the first element faster (we hope)
    # Note this means that removing items changes the order of
    # our "list".
    c += len(self.removed)
    while c > self.last:
      c -= self.count

    while True:
      addr = IPAddr(c | self.network.toUnsigned())
      if addr not in self.removed:
        assert addr in self
        index -= 1
        if index < 0: return addr
      c += 1
      if c > self.last: c -= self.count
Exemplo n.º 15
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)
Exemplo n.º 16
0
class PCap (object):
  @staticmethod
  def get_devices ():
    def ip (addr):
      if addr is None: return None
      return IPAddr(addr, networkOrder=True)
    def link (addr):
      if addr is None: return None
      if len(addr) != 6: return None
      return EthAddr(addr)
    devs = pcapc.findalldevs()
    out = {}
    for d in devs:
      addrs = {}
      n = {'desc':d[1],'addrs':addrs}
      out[d[0]] = n
      for a in d[2]:
        if a[0] == 'AF_INET':
          na = {}
          addrs[a[0]] = na
          na['addr'] = ip(a[1])
          na['netmask'] = ip(a[2])
          na['broadaddr'] = ip(a[3])
          na['dstaddr'] = ip(a[4])
        elif a[0] == 'AF_LINK':
          na = {}
          addrs[a[0]] = na
          na['addr'] = link(a[1])
          na['netmask'] = link(a[2])
          na['broadaddr'] = link(a[3])
          na['dstaddr'] = link(a[4])
        elif a[0] == 'AF_PACKET':
          addrs[a[0]] = {'addr':link(a[1])}
        elif a[0] == 'ethernet':
          addrs[a[0]] = {'addr':link(a[1])}
    return out

  @staticmethod
  def get_device_names ():
    return [d[0] for d in pcapc.findalldevs()]

  def __init__ (self, device = None, promiscuous = True, period = 10,
                start = True, callback = None, filter = None):
    if filter is not None:
      self.deferred_filter = (filter,)
    else:
      self.deferred_filter = None
    self.packets_received = 0
    self.packets_dropped = 0
    self._thread = None
    self.pcap = None
    self.promiscuous = promiscuous
    self.device = None
    self.period = period
    self.netmask = IPAddr("0.0.0.0")
    self._quitting = False
    self.addresses = {}
    if callback is None:
      self.callback = self.__class__._handle_rx
    else:
      self.callback = callback
    if device is not None:
      self.open(device)
    if self.pcap is not None:
      if start:
        self.start()

  def _handle_rx (self, data, sec, usec, length):
    pass

  def open (self, device, promiscuous = None, period = None,
            incoming = True, outgoing = False):
    assert self.device is None
    self.addresses = self.get_devices()[device]['addrs']
    if 'AF_INET' in self.addresses:
      self.netmask = self.addresses['AF_INET'].get('netmask')
      if self.netmask is None: self.netmask = IPAddr("0.0.0.0")
    #print "NM:",self.netmask
    #print self.addresses['AF_LINK']['addr']
    self.device = device
    if period is not None:
      self.period = period
    if promiscuous is not None:
      self.promiscuous = promiscuous
    self.pcap = pcapc.open_live(device, 65535,
                                1 if self.promiscuous else 0, self.period)
    pcapc.setdirection(self.pcap, incoming, outgoing)
    self.packets_received = 0
    self.packets_dropped = 0
    if self.deferred_filter is not None:
      self.set_filter(*self.deferred_filter)
      self.deferred_filter = None

  def set_direction (self, incoming, outgoing):
    pcapc.setdirection(self.pcap, incoming, outgoing)

  def _thread_func (self):
    while not self._quitting:
      pcapc.dispatch(self.pcap,100,self.callback,self)
      self.packets_received,self.packets_dropped = pcapc.stats(self.pcap)

    self._quitting = False
    self._thread = None

  def _handle_GoingDownEvent (self, event):
    self.close()

  def start (self):
    assert self._thread is None
    from pox.core import core
    core.addListeners(self, weak=True)
    self._thread = Thread(target=self._thread_func)
    #self._thread.daemon = True
    self._thread.start()

  def stop (self):
    t = self._thread
    if t is not None:
      self._quitting = True
      pcapc.breakloop(self.pcap)
      t.join()

  def close (self):
    if self.pcap is None: return
    self.stop()
    pcapc.close(self.pcap)
    self.pcap = None

  def __del__ (self):
    self.close()

  def inject (self, data):
    if isinstance(data, pkt.ethernet):
      data = data.pack()
    if not isinstance(data, bytes):
      data = bytes(data) # Give it a try...
    return pcapc.inject(self.pcap, data)

  def set_filter (self, filter, optimize = True):
    if self.pcap is None:
      self.deferred_filter = (filter, optimize)
      return

    if isinstance(filter, str):
      filter = Filter(filter, optimize, self.netmask.toSignedN(),
                      pcap_obj=self)
    elif isinstance(filter, Filter):
      pass
    else:
      raise RuntimeError("Filter must be string or Filter object")

    pcapc.setfilter(self.pcap, filter._pprogram)
Exemplo n.º 17
0
    def _handle_openflow_PacketIn(self, event):
        #def _handle_PacketIn (self, event):
        dpid = event.dpid
        inport = event.port
        packet = event.parsed
        #log.info('Pacote de '+ str(self.dpid_to_mac(dpid)))

        net = packet.next  # Camada de rede
        transp = packet.next.next  # Camada de transporte
        if not packet.parsed:
            log.info("Pacote not Parsed")
            return
        #if packet.type == ethernet.LLDPTYPE:
        #.info("Pacote LLDPTYPE")
        #return
        if isinstance(net, ipv4):
            #log.info("Pacote IPv4")
            #log.info("Evento gerado na porta ="+str(inport))
            if (inport == 1 or inport == 2):
                #if()
                lista = []
                for i in self.arpTableServidores:
                    lista.append(i)

                if str(net.dstip) not in lista:
                    #Faz nada
                    return
                else:
                    #if (str(transp.dstport) == '1234'): #Eventos foram gerados por hosts conectados ao swtich
                    if str(net.dstip) in lista and str(
                            transp.dstport) != '12320':
                        if str(
                                self.dpid_to_mac(dpid)
                        ) == '00:00:00:00:00:03':  # Switch onde esta os servidores S3
                            msg = of.ofp_flow_mod()
                            #msg.match.dl_src = EthAddr('00:00:00:00:01:01')
                            #msg.match.dl_dst = EthAddr('00:00:00:00:03:11')
                            msg.match.dl_type = 0x800
                            msg.match.nw_src = IPAddr("10.0.0.11")
                            msg.match.nw_dst = IPAddr(str(net.dstip))
                            msg.priority = 50001  #seta uma prioridade maior para regra
                            msg.actions.append(
                                of.ofp_action_output(port=17)
                            )  #Nao tem ninguem conectado a essa porta
                            event.connection.send(msg)
                            log.info("Regra de Drop Adicionada!!"
                                     )  # Supoe que drop o pacote
                            '''
                            Adiciona o IP do servidor multicast a tabela
                            '''
                            lista_Portas = []
                            if str(net.dstip) not in self.tableIPServidores:
                                self.tableIPServidores.append(str(net.dstip))
                                lista_Portas = [17]
                                info = {str(net.dstip): lista_Portas}
                                self.tableSwtichFluxo[str(
                                    self.dpid_to_mac(dpid)
                                )].append(
                                    info
                                )  #Adiciona o IP e a porta que ele esta saido na tabela de Fluxo do Switch
                            else:
                                log.info("IP Servidor ja registrado!!")
                            return

                        elif str(self.dpid_to_mac(
                                dpid)) == '00:00:00:00:00:01':  # Swithc s1
                            '''
                            Fazer as regras aqui!!
                            '''
                            log.debug(
                                "Chegou pacote do S1 para o grupo multicast")
                            #Verificar se o swtich ja possui o fluxo requerido
                            l = self.tableSwtichFluxo[str(
                                self.dpid_to_mac(dpid))]
                            k = {}
                            for i in l:
                                for j in i:
                                    if str(j) == str(net.dstip):
                                        k = i
                            a = []
                            if len(k) != 0:
                                a = k[str(
                                    net.dstip
                                )]  #lista de portas que estao com fluxo swtich
                            if len(a) != 0:
                                #Levar o fluxo para a porta entao
                                log.debug('Switch ja possui o Fluxo')
                                p = self.retornaStringListaPortas(
                                    str(self.dpid_to_mac(dpid)), net.dstip
                                )  #Lista de portas que contem o fluxo
                                if inport == 1:
                                    comando2 = 'ovs-ofctl mod-flows s1 priority=50002,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.2,mod_dl_dst:00:00:00:00:01:02,output:' + p + ',1'
                                    self.executaComandosOVS(comando2)
                                    a.append(1)
                                else:
                                    comando2 = 'ovs-ofctl mod-flows s1 priority=50002,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.1,mod_dl_dst:00:00:00:00:01:01,output:' + p + ',2'
                                    self.executaComandosOVS(comando2)
                                    a.append(2)
                                return
                            else:
                                log.debug('Switch ainda nao possui o Fluxo')
                                #Trazer o fluxo para o switch
                                #comando = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst='+str(net.dstip)+',actions=output:11'
                                #comando = 'ovs-ofctl mod-flows s3 priority=50001,dl_type=0x800,nw_src=10.0.0.11,nw_dst='+str(net.dstip)+',actions=output:11'
                                #self.executaComandosOVS(comando)
                                #p = self.retornaStringListaPortas(str(self.dpid_to_mac(dpid)),net.dstip)
                                p = self.retornaStringListaPortas(
                                    '00:00:00:00:00:03', net.dstip
                                )  #Lista de portas que contem o fluxo
                                comando = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst=' + str(
                                    net.dstip) + ',actions=output:' + p + ',11'
                                self.executaComandosOVS(comando)

                                l = self.tableSwtichFluxo['00:00:00:00:00:03']
                                k = {}
                                for i in l:
                                    for j in i:
                                        if str(j) == str(net.dstip):
                                            k = i
                                #log.info(k)
                                lista_portas = k[str(
                                    net.dstip
                                )]  #lista de portas que estao com fluxo swtich
                                lista_portas.append(
                                    11)  #Porta que vai para o S1

                                #Verifico de qual porta veio para fazer a rescrita de cabecalho
                                if inport == 1:
                                    comando2 = 'ovs-ofctl mod-flows s1 priority=5001,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.1,mod_dl_dst:00:00:00:00:01:01,output:1'
                                    self.executaComandosOVS(comando2)
                                    lista_Portas = [1]
                                    info = {str(net.dstip): lista_Portas}
                                    self.tableSwtichFluxo[str(
                                        self.dpid_to_mac(dpid)
                                    )].append(
                                        info
                                    )  #Adiciona o IP e a porta que ele esta saido na tabela de Fluxo do Switch
                                else:
                                    comando2 = 'ovs-ofctl mod-flows s1 priority=5001,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.2,mod_dl_dst:00:00:00:00:01:02,output:2'
                                    self.executaComandosOVS(comando2)
                                    lista_Portas = [2]
                                    info = {str(net.dstip): lista_Portas}
                                    self.tableSwtichFluxo[str(
                                        self.dpid_to_mac(dpid)
                                    )].append(
                                        info
                                    )  #Adiciona o IP e a porta que ele esta saido na tabela de Fluxo do Switch
                                return

                            #comando2 = 'ovs-ofctl mod-flows s1 priority=50010,dl_type=0x800,nw_dst='+str(net.dstip)+',actions=mod_nw_dst:10.0.0.1,mod_dl_dst:00:00:00:00:01:01,output:1'
                            #comando3 = 'ovs-ofctl add-flow s1 priority=5001,dl_type=0x800,nw_src=10.0.0.11,tp_dst=1236,actions=mod_nw_dst:10.0.0.1,mod_dl_dst:00:00:00:00:01:01,output:1'
                            #self.executaComandosOVS(comando2)
                            #self.executaComandosOVS(comando3)

                        elif str(self.dpid_to_mac(
                                dpid)) == '00:00:00:00:00:02':  #Switch s2
                            '''
                            Fazer as regras aqui!!
                            '''
                            log.debug(
                                "Chegou pacote do S2 para o grupo multicast")
                            #Verificar se o swtich ja possui o fluxo requerido
                            l = self.tableSwtichFluxo[str(
                                self.dpid_to_mac(dpid))]
                            k = {}
                            for i in l:
                                for j in i:
                                    if str(j) == str(net.dstip):
                                        k = i
                            a = []
                            if len(k) != 0:
                                a = k[str(
                                    net.dstip
                                )]  #lista de portas que estao com fluxo swtich
                            if len(a) != 0:
                                log.debug('Switch ja possui o Fluxo')
                                #Levar o fluxo para a porta entao
                                p = self.retornaStringListaPortas(
                                    str(self.dpid_to_mac(dpid)), net.dstip
                                )  #Lista de portas que contem o fluxo
                                if inport == 1:
                                    comando2 = 'ovs-ofctl mod-flows s2 priority=50002,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.4,mod_dl_dst:00:00:00:00:02:04,output:' + p + ',1'
                                    self.executaComandosOVS(comando2)
                                    a.append(1)
                                else:
                                    comando2 = 'ovs-ofctl mod-flows s2 priority=50002,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.3,mod_dl_dst:00:00:00:00:02:03,output:' + p + ',2'
                                    self.executaComandosOVS(comando2)
                                    a.append(2)
                                return
                            else:
                                log.debug('Switch ainda nao possui o Fluxo')
                                #Trazer o fluxo para o switch
                                #comando = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst='+str(net.dstip)+',actions=output:11'
                                #comando = 'ovs-ofctl mod-flows s3 priority=50001,dl_type=0x800,nw_src=10.0.0.11,nw_dst='+str(net.dstip)+',actions=output:11'
                                #self.executaComandosOVS(comando)
                                #p = self.retornaStringListaPortas(str(self.dpid_to_mac(dpid)),net.dstip)
                                p = self.retornaStringListaPortas(
                                    '00:00:00:00:00:03', net.dstip
                                )  #Lista de portas que contem o fluxo
                                comando = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst=' + str(
                                    net.dstip) + ',actions=output:' + p + ',12'
                                self.executaComandosOVS(comando)

                                l = self.tableSwtichFluxo['00:00:00:00:00:03']
                                k = {}
                                for i in l:
                                    for j in i:
                                        if str(j) == str(net.dstip):
                                            k = i
                                #log.info(k)
                                lista_portas = k[str(
                                    net.dstip
                                )]  #lista de portas que estao com fluxo swtich
                                lista_portas.append(
                                    12)  #Porta que vai para o S2

                                #Verifico de qual porta veio para fazer a rescrita de cabecalho
                                if inport == 1:
                                    comando2 = 'ovs-ofctl mod-flows s2 priority=49999,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.3,mod_dl_dst:00:00:00:00:02:03,output:1'
                                    self.executaComandosOVS(comando2)
                                    lista_Portas = [1]
                                    info = {str(net.dstip): lista_Portas}
                                    self.tableSwtichFluxo[str(
                                        self.dpid_to_mac(dpid)
                                    )].append(
                                        info
                                    )  #Adiciona o IP e a porta que ele esta saido na tabela de Fluxo do Switch
                                else:
                                    comando2 = 'ovs-ofctl mod-flows s2 priority=49999,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.4,mod_dl_dst:00:00:00:00:02:04,output:2'
                                    self.executaComandosOVS(comando2)
                                    lista_Portas = [2]
                                    info = {str(net.dstip): lista_Portas}
                                    self.tableSwtichFluxo[str(
                                        self.dpid_to_mac(dpid)
                                    )].append(
                                        info
                                    )  #Adiciona o IP e a porta que ele esta saido na tabela de Fluxo do Switch
                                return

                        elif str(self.dpid_to_mac(
                                dpid)) == '00:00:00:00:00:04':  #Swtich s4
                            '''
                            Fazer as regras aqui!!
                            '''
                            log.debug(
                                "Chegou pacote do S4 para o grupo multicast")
                            #Verificar se o swtich ja possui o fluxo requerido
                            l = self.tableSwtichFluxo[str(
                                self.dpid_to_mac(dpid))]
                            k = {}
                            for i in l:
                                for j in i:
                                    if str(j) == str(net.dstip):
                                        k = i
                            a = []
                            if len(k) != 0:
                                a = k[str(
                                    net.dstip
                                )]  #lista de portas que estao com fluxo swtich
                            if len(a) != 0:
                                log.debug('Switch ja possui o Fluxo')
                                #Levar o fluxo para a porta entao
                                p = self.retornaStringListaPortas(
                                    str(self.dpid_to_mac(dpid)), net.dstip
                                )  #Lista de portas que contem o fluxo
                                if inport == 1:
                                    comando2 = 'ovs-ofctl mod-flows s4 priority=50002,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.6,mod_dl_dst:00:00:00:00:04:06,output:' + p + ',1'
                                    self.executaComandosOVS(comando2)
                                    a.append(1)
                                else:
                                    comando2 = 'ovs-ofctl mod-flows s4 priority=50002,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.3,mod_dl_dst:00:00:00:00:04:05,output:' + p + ',2'
                                    self.executaComandosOVS(comando2)
                                    a.append(2)
                                return
                            else:
                                log.debug('Switch ainda nao possui o Fluxo')
                                #Trazer o fluxo para o switch
                                #comando = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst='+str(net.dstip)+',actions=output:11'
                                #comando = 'ovs-ofctl mod-flows s3 priority=50001,dl_type=0x800,nw_src=10.0.0.11,nw_dst='+str(net.dstip)+',actions=output:11'
                                #self.executaComandosOVS(comando)
                                #p = self.retornaStringListaPortas(str(self.dpid_to_mac(dpid)),net.dstip)
                                p = self.retornaStringListaPortas(
                                    '00:00:00:00:00:03', net.dstip
                                )  #Lista de portas que contem o fluxo
                                comando = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst=' + str(
                                    net.dstip) + ',actions=output:' + p + ',14'
                                self.executaComandosOVS(comando)

                                l = self.tableSwtichFluxo['00:00:00:00:00:03']
                                k = {}
                                for i in l:
                                    for j in i:
                                        if str(j) == str(net.dstip):
                                            k = i
                                #log.info(k)
                                lista_portas = k[str(
                                    net.dstip
                                )]  #lista de portas que estao com fluxo swtich
                                lista_portas.append(
                                    14)  #Porta que vai para o S4

                                #Verifico de qual porta veio para fazer a rescrita de cabecalho
                                if inport == 1:
                                    comando2 = 'ovs-ofctl mod-flows s4 priority=49999,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.5,mod_dl_dst:00:00:00:00:04:05,output:1'
                                    self.executaComandosOVS(comando2)
                                    lista_Portas = [1]
                                    info = {str(net.dstip): lista_Portas}
                                    self.tableSwtichFluxo[str(
                                        self.dpid_to_mac(dpid)
                                    )].append(
                                        info
                                    )  #Adiciona o IP e a porta que ele esta saido na tabela de Fluxo do Switch
                                else:
                                    comando2 = 'ovs-ofctl mod-flows s4 priority=49999,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.6,mod_dl_dst:00:00:00:00:04:06,output:2'
                                    self.executaComandosOVS(comando2)
                                    lista_Portas = [2]
                                    info = {str(net.dstip): lista_Portas}
                                    self.tableSwtichFluxo[str(
                                        self.dpid_to_mac(dpid)
                                    )].append(
                                        info
                                    )  #Adiciona o IP e a porta que ele esta saido na tabela de Fluxo do Switch
                                return
                    else:  #Pedido para sair do Grupo Multicast
                        '''
                        Pedido para sair do Grupo Multicast
                        '''
                        log.info('IP = ' + str(net.srcip) +
                                 ' quer sair do Grupo Multicast ' +
                                 str(net.dstip))

                        ip_fluxo = net.dstip
                        l = self.tableSwtichFluxo[str(self.dpid_to_mac(dpid))]
                        k = {}
                        for i in l:
                            for j in i:
                                if str(j) == str(ip_fluxo):
                                    k = i
                        #log.info(k)
                        t = k[
                            str(ip_fluxo
                                )]  #lista de portas que estao com fluxo swtich
                        log.debug(t)

                        if str(self.dpid_to_mac(
                                dpid)) == '00:00:00:00:00:01':  # Swithc s1
                            '''
                            Fazer as regras aqui!!
                            '''
                            p = self.retornaStringListaPortas(
                                str(self.dpid_to_mac(dpid)),
                                net.dstip)  #Lista de portas que contem o fluxo
                            if len(t) == 1:  #Tem somente um fluno no switch
                                #Retiro o fluxo da porta em s3
                                l = self.tableSwtichFluxo['00:00:00:00:00:03']
                                k = {}
                                for i in l:
                                    for j in i:
                                        if str(j) == str(ip_fluxo):
                                            k = i
                                #log.info(k)
                                lista_portas = k[str(
                                    ip_fluxo
                                )]  #lista de portas que estao com fluxo swtich
                                lista_portas.remove(11)
                                b = self.retornaStringListaPortas(
                                    '00:00:00:00:00:03', net.dstip
                                )  #Lista de portas que contem o fluxo
                                comando2 = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst=' + str(
                                    net.dstip) + ',actions=output:' + b
                                self.executaComandosOVS(comando2)
                                del t[:]  #Apaga lista de portas do fluxo no swtich

                            else:
                                #Retiro somente o fluxo da porta
                                if inport == 1:
                                    l = self.tableSwtichFluxo[
                                        '00:00:00:00:00:01']
                                    k = {}
                                    for i in l:
                                        for j in i:
                                            if str(j) == str(ip_fluxo):
                                                k = i
                                    #log.info(k)
                                    lista_portas = k[str(
                                        ip_fluxo
                                    )]  #lista de portas que estao com fluxo swtich
                                    lista_portas.remove(1)
                                    b = self.retornaStringListaPortas(
                                        str(self.dpid_to_mac(dpid)), net.dstip
                                    )  #Lista de portas que contem o fluxo
                                    comando2 = 'ovs-ofctl mod-flows s1 priority=49999,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.1,mod_dl_dst:00:00:00:00:01:02,output:' + b
                                    #comando2 = 'ovs-ofctl mod-flows s1 priority=49999,dl_type=0x800,nw_dst='+str(net.dstip)+',actions=output:'+b
                                    log.debug(comando2)
                                    self.executaComandosOVS(comando2)
                                else:
                                    l = self.tableSwtichFluxo[
                                        '00:00:00:00:00:01']
                                    k = {}
                                    for i in l:
                                        for j in i:
                                            if str(j) == str(ip_fluxo):
                                                k = i
                                    #log.info(k)
                                    lista_portas = k[str(
                                        ip_fluxo
                                    )]  #lista de portas que estao com fluxo swtich
                                    lista_portas.remove(2)
                                    b = self.retornaStringListaPortas(
                                        str(self.dpid_to_mac(dpid)), net.dstip
                                    )  #Lista de portas que contem o fluxo
                                    comando2 = 'ovs-ofctl mod-flows s1 priority=49999,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.1,mod_dl_dst:00:00:00:00:01:01,output:' + b
                                    #comando2 = 'ovs-ofctl mod-flows s1 priority=49999,dl_type=0x800,nw_dst='+str(net.dstip)+',actions=output:'+b
                                    log.debug(comando2)
                                    self.executaComandosOVS(comando2)
                                return
                            return
                        elif str(self.dpid_to_mac(
                                dpid)) == '00:00:00:00:00:02':  # Swithc s2
                            '''
                            Fazer as regras aqui!!
                            '''
                            p = self.retornaStringListaPortas(
                                str(self.dpid_to_mac(dpid)),
                                net.dstip)  #Lista de portas que contem o fluxo
                            if len(t) == 1:  #Tem somente um fluno no switch
                                #Retiro o fluxo da porta em s3
                                l = self.tableSwtichFluxo['00:00:00:00:00:03']
                                k = {}
                                for i in l:
                                    for j in i:
                                        if str(j) == str(ip_fluxo):
                                            k = i
                                #log.info(k)
                                lista_portas = k[str(
                                    ip_fluxo
                                )]  #lista de portas que estao com fluxo swtich
                                lista_portas.remove(12)
                                b = self.retornaStringListaPortas(
                                    '00:00:00:00:00:03', net.dstip
                                )  #Lista de portas que contem o fluxo
                                comando2 = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst=' + str(
                                    net.dstip) + ',actions=output:' + b
                                self.executaComandosOVS(comando2)
                                del t[:]  #Apaga lista de portas do fluxo no swtich
                            else:
                                #Retiro somente o fluxo da porta
                                if inport == 1:
                                    l = self.tableSwtichFluxo[
                                        '00:00:00:00:00:02']
                                    k = {}
                                    for i in l:
                                        for j in i:
                                            if str(j) == str(ip_fluxo):
                                                k = i
                                    #log.info(k)
                                    lista_portas = k[str(
                                        ip_fluxo
                                    )]  #lista de portas que estao com fluxo swtich
                                    lista_portas.remove(1)
                                    b = self.retornaStringListaPortas(
                                        str(self.dpid_to_mac(dpid)), net.dstip
                                    )  #Lista de portas que contem o fluxo
                                    comando2 = 'ovs-ofctl mod-flows s2 priority=49999,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.4,mod_dl_dst:00:00:00:00:02:04,output:' + b
                                    #comando2 = 'ovs-ofctl mod-flows s2 priority=49999,dl_type=0x800,nw_dst='+str(net.dstip)+',actions=output:'+b
                                    self.executaComandosOVS(comando2)
                                else:
                                    l = self.tableSwtichFluxo[
                                        '00:00:00:00:00:02']
                                    k = {}
                                    for i in l:
                                        for j in i:
                                            if str(j) == str(ip_fluxo):
                                                k = i
                                    #log.info(k)
                                    lista_portas = k[str(
                                        ip_fluxo
                                    )]  #lista de portas que estao com fluxo swtich
                                    lista_portas.remove(2)
                                    b = self.retornaStringListaPortas(
                                        str(self.dpid_to_mac(dpid)), net.dstip
                                    )  #Lista de portas que contem o fluxo
                                    comando2 = 'ovs-ofctl mod-flows s2 priority=49999,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.3,mod_dl_dst:00:00:00:00:02:03,output:' + b
                                    #comando2 = 'ovs-ofctl mod-flows s2 priority=49999,dl_type=0x800,nw_dst='+str(net.dstip)+',actions=output:'+b
                                    self.executaComandosOVS(comando2)
                                return
                            return
                        elif str(self.dpid_to_mac(
                                dpid)) == '00:00:00:00:00:04':  # Swithc s4
                            '''
                            Fazer as regras aqui!!
                            '''
                            p = self.retornaStringListaPortas(
                                str(self.dpid_to_mac(dpid)),
                                net.dstip)  #Lista de portas que contem o fluxo
                            if len(t) == 1:  #Tem somente um fluno no switch
                                #Retiro o fluxo da porta em s3
                                l = self.tableSwtichFluxo['00:00:00:00:00:03']
                                k = {}
                                for i in l:
                                    for j in i:
                                        if str(j) == str(ip_fluxo):
                                            k = i
                                #log.info(k)
                                lista_portas = k[str(
                                    ip_fluxo
                                )]  #lista de portas que estao com fluxo swtich
                                lista_portas.remove(14)
                                b = self.retornaStringListaPortas(
                                    '00:00:00:00:00:03', net.dstip
                                )  #Lista de portas que contem o fluxo
                                comando2 = 'ovs-ofctl mod-flows s3 priority=5001,dl_type=0x800,nw_src=10.0.0.11,nw_dst=' + str(
                                    net.dstip) + ',actions=output:' + b
                                #comando2 = 'ovs-ofctl mod-flows s3 priority=49999,dl_type=0x800,nw_dst='+str(net.dstip)+',actions=output:'+b
                                self.executaComandosOVS(comando2)
                                del t[:]  #Apaga lista de portas do fluxo no swtich
                            else:
                                #Retiro somente o fluxo da porta
                                if inport == 1:
                                    l = self.tableSwtichFluxo[
                                        '00:00:00:00:00:04']
                                    k = {}
                                    for i in l:
                                        for j in i:
                                            if str(j) == str(ip_fluxo):
                                                k = i
                                    #log.info(k)
                                    lista_portas = k[str(
                                        ip_fluxo
                                    )]  #lista de portas que estao com fluxo swtich
                                    lista_portas.remove(1)
                                    b = self.retornaStringListaPortas(
                                        str(self.dpid_to_mac(dpid)), net.dstip
                                    )  #Lista de portas que contem o fluxo
                                    comando2 = 'ovs-ofctl mod-flows s4 priority=49999,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.6,mod_dl_dst:00:00:00:00:04:06,output:' + b
                                    #comando2 = 'ovs-ofctl mod-flows s4 priority=49999,dl_type=0x800,nw_dst='+str(net.dstip)+',actions=output:'+b
                                    self.executaComandosOVS(comando2)
                                else:
                                    l = self.tableSwtichFluxo[
                                        '00:00:00:00:00:04']
                                    k = {}
                                    for i in l:
                                        for j in i:
                                            if str(j) == str(ip_fluxo):
                                                k = i
                                    #log.info(k)
                                    lista_portas = k[str(
                                        ip_fluxo
                                    )]  #lista de portas que estao com fluxo swtich
                                    lista_portas.remove(2)
                                    b = self.retornaStringListaPortas(
                                        str(self.dpid_to_mac(dpid)), net.dstip
                                    )  #Lista de portas que contem o fluxo
                                    comando2 = 'ovs-ofctl mod-flows s4 priority=49999,dl_type=0x800,nw_dst=' + str(
                                        net.dstip
                                    ) + ',actions=mod_nw_dst:10.0.0.5,mod_dl_dst:00:00:00:00:04:05,output:' + b
                                    #comando2 = 'ovs-ofctl mod-flows s4 priority=49999,dl_type=0x800,nw_dst='+str(net.dstip)+',actions=output:'+b

                                    self.executaComandosOVS(comando2)
                                return

                            return
                        else:
                            return
                        return

        elif isinstance(net, arp):
            log.info("Protocolo ARP")
            mac_resp = self.arpTableServidores[str(net.protodst)]
            arp_helper.send_arp_reply(event, mac_resp)
            return
        else:
            #log.info("Aconteceu nada!!")
            return
Exemplo n.º 18
0
    def install_mapping(self,
                        priv_mac1,
                        priv_ip1,
                        virt_mac1,
                        virt_ip1,
                        priv_mac2,
                        priv_ip2,
                        virt_mac2,
                        virt_ip2,
                        expiry=None):
        self.installed_rules.append(locals())
        log.debug("Installing rule: {}".format(locals()))

        # We have to install 4 rules to handle the mapping. Note that this assumes the two hosts are on different
        # switches; rules would need to be merged to handle the case where both endpoints are on the same switch.
        # In the comments below, "A" is the first address and "B" the second, and ".p" indicates a (true) private
        # address, ".v" a client-specific virtual address, and ".m" a (true) private MAC address. Also "S1" indicates
        # the switch where host A (priv_ip1) is connected, and "S2" for host B.
        msg = of.ofp_flow_mod()
        msg.priority = of.OFP_DEFAULT_PRIORITY + 42
        msg.match.dl_type = 0x0800  # EtherType IPv4

        # S1: if src=A.p and dst=B.v, then set dst=B.p and dl_dst=B.m, forward to the same port that has B.p
        # TODO: for expediency, hard-coding the switch DPIDs here; should really use something like the host_tracker
        # functionality so we can determine this dynamically
        msg.match.nw_src = priv_ip1
        msg.match.nw_dst = virt_ip2
        msg.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(priv_ip2)))
        msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(priv_mac2)))
        msg.actions.append(
            of.ofp_action_output(port=self.port_for_mac(1, priv_mac2)))
        SdnsMapper.send_msg(msg, 1)
        msg.actions = []

        # S2: if src=A.p and dst=B.p, then set src=A.v and dl_src=A.v
        msg.match.nw_dst = priv_ip2
        msg.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(virt_ip1)))
        msg.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(virt_mac1)))
        msg.actions.append(
            of.ofp_action_output(port=self.port_for_mac(2, priv_mac2)))
        SdnsMapper.send_msg(msg, 2)
        msg.actions = []

        # S2: if src=B.p and dst=A.v, then set dst=A.p
        msg.match.nw_src = priv_ip2
        msg.match.nw_dst = virt_ip1
        msg.actions.append(of.ofp_action_nw_addr.set_dst(IPAddr(priv_ip1)))
        msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(priv_mac1)))
        msg.actions.append(
            of.ofp_action_output(port=self.port_for_mac(2, priv_mac1)))
        SdnsMapper.send_msg(msg, 2)
        msg.actions = []

        # S1: if src=B.p and dst=A.p, then set src=B.v
        msg.match.nw_dst = priv_ip1
        msg.actions.append(of.ofp_action_nw_addr.set_src(IPAddr(virt_ip2)))
        msg.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(virt_mac2)))
        msg.actions.append(
            of.ofp_action_output(port=self.port_for_mac(1, priv_mac1)))
        SdnsMapper.send_msg(msg, 1)

        # Have the switches respond to ARP requests for virtual IPs directly
        timeout = float('inf') if expiry is None else expiry
        self.install_arp_rule(virt_mac1, virt_ip1, timeout)
        self.install_arp_rule(virt_mac2, virt_ip2, timeout)
Exemplo n.º 19
0
  def _handle_openflow_PacketIn (self, event):
    dpid = event.connection.dpid
    inport = event.port
    packet = event.parsed
    global set_Timer
    global defendDDOS
    global blockPort
    timerSet =False
    global diction
    def preventing():
      global diction
      global set_Timer
      if not set_Timer:
        set_Timer =True
      #Timer(1, _timer_func(), recurring=True)


      #print"\n\n*********new packetIN************"
      if len(diction) == 0:
        print("Enpty diction ",str(event.connection.dpid), str(event.port))
        diction[event.connection.dpid] = {}
        diction[event.connection.dpid][event.port] = 1
      elif event.connection.dpid not in diction:
        diction[event.connection.dpid] = {}
        diction[event.connection.dpid][event.port] = 1
        #print "ERROR"
      else:
        if event.connection.dpid in diction:
      # temp = diction[event.connection.dpid]
      #print(temp)
      #print "error check " , str(diction[event.connection.dpid][event.port])
          if event.port in diction[event.connection.dpid]:
            temp_count=0
            temp_count =diction[event.connection.dpid][event.port]
            temp_count = temp_count+1
            diction[event.connection.dpid][event.port]=temp_count
            #print "printting dpid port number and its packet count: ",  str(event.connection.dpid), str(diction[event.connection.dpid]), str(diction[event.connection.dpid][event.port])
          else:
            diction[event.connection.dpid][event.port] = 1
   
      print "\n",datetime.datetime.now(gst), ": printing diction ",str(diction),"\n"
    
    
    def _timer_func ():
      global diction
      global set_Timer
      if set_Timer==True:
        #print datetime.datetime.now(),": calling timer fucntion now!!!!!" 
        for k,v in diction.iteritems():
          for i,j in v.iteritems():
            if j >=50:
              print "_____________________________________________________________________________________________"
              print "\n",datetime.datetime.now(gst),"*******    DDOS DETECTED   ********"
              print "\n",str(diction)
              print "\n",datetime.datetime.now(gst),": BLOCKED PORT NUMBER  : ", str(i), " OF SWITCH ID: ", str(k)
              print "\n_____________________________________________________________________________________________"

              #self.dropDDOS ()
              dpid = k
              msg = of.ofp_packet_out(in_port=i)
              #msg.priority=42
              #msg.in_port = event.port
              #po = of.ofp_packet_out(buffer_id = buffer_id, in_port = in_port)
              core.openflow.sendToDPID(dpid,msg)

              
                
      diction={}

    if not packet.parsed:
      log.warning("%i %i ignoring unparsed packet", dpid, inport)
      return

    if dpid not in self.arpTable:
      # New switch -- create an empty table
      self.arpTable[dpid] = {}
      for fake in self.fakeways:
        self.arpTable[dpid][IPAddr(fake)] = Entry(of.OFPP_NONE,
         dpid_to_mac(dpid))

    if packet.type == ethernet.LLDP_TYPE:
      # Ignore LLDP packets
      return

    if isinstance(packet.next, ipv4):
      log.debug("%i %i IP %s => %s", dpid,inport,
                packet.next.srcip,packet.next.dstip)
      ent_obj.statcolect(event.parsed.next.dstip)#editing
      print "\n***** Entropy Value = ",str(ent_obj.value),"*****\n"
      if ent_obj.value <0.5:
        preventing()
        if timerSet is not True:
          Timer(2, _timer_func, recurring=True)
          timerSet=False
      else:
        timerSet=False
          

            
      # Send any waiting packets...
      self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport)

      # Learn or update port/MAC info
      if packet.next.srcip in self.arpTable[dpid]:
        if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src):
          log.info("%i %i RE-learned %s", dpid,inport,packet.next.srcip)
          if self.wide:
            # Make sure we don't have any entries with the old info...
            msg = of.ofp_flow_mod(command=of.OFPFC_DELETE)
            msg.match.nw_dst = packet.next.srcip
            msg.match.dl_type = ethernet.IP_TYPE
            event.connection.send(msg)
      else:
        log.debug("%i %i learned %s", dpid,inport,packet.next.srcip)
      self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)
      #nandan: getting source ip address from the packetIn
      #myPacketInSrcIP= packet.next.srcip
      #myPacketInSrcEth= packet.src
      #myPacketInDstIP= packet.next.dstip
      #myPacketInDstEth= packet.dst

      #print "switcID: "+str(dpid)+" ,Port: "+str(event.port)+" ,MAC address: "+str(myPacketInSrcEth)+" ,SrcIP: "+ str(myPacketInSrcIP)+", Dst Mac: "+str(myPacketInDstEth)+", Dst IP: "+str(myPacketInDstEth)
      # Try to forward
      dstaddr = packet.next.dstip
      if dstaddr in self.arpTable[dpid]:
        # We have info about what port to send it out on...

        prt = self.arpTable[dpid][dstaddr].port
        mac = self.arpTable[dpid][dstaddr].mac
        if prt == inport:
          log.warning("%i %i not sending packet for %s back out of the "
                      "input port" % (dpid, inport, dstaddr))
        else:
          log.debug("%i %i installing flow for %s => %s out port %i"
                    % (dpid, inport, packet.next.srcip, dstaddr, prt))

          actions = []
          actions.append(of.ofp_action_dl_addr.set_dst(mac))
          actions.append(of.ofp_action_output(port = prt))
          if self.wide:
            match = of.ofp_match(dl_type = packet.type, nw_dst = dstaddr)
          else:
            match = of.ofp_match.from_packet(packet, inport)

          msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                idle_timeout=FLOW_IDLE_TIMEOUT,
                                hard_timeout=of.OFP_FLOW_PERMANENT,
                                buffer_id=event.ofp.buffer_id,
                                actions=actions,
                                match=match)
          event.connection.send(msg.pack())
      elif self.arp_for_unknowns:
        # We don't know this destination.
        # First, we track this buffer so that we can try to resend it later
        # if we learn the destination, second we ARP for the destination,
        # which should ultimately result in it responding and us learning
        # where it is

        # Add to tracked buffers
        if (dpid,dstaddr) not in self.lost_buffers:
          self.lost_buffers[(dpid,dstaddr)] = []
        bucket = self.lost_buffers[(dpid,dstaddr)]
        entry = (time.time() + MAX_BUFFER_TIME,event.ofp.buffer_id,inport)
        bucket.append(entry)
        while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0]

        # Expire things from our outstanding ARP list...
        self.outstanding_arps = {k:v for k,v in
         self.outstanding_arps.iteritems() if v > time.time()}

        # Check if we've already ARPed recently
        if (dpid,dstaddr) in self.outstanding_arps:
          # Oop, we've already done this one recently.
          return

        # And ARP...
        self.outstanding_arps[(dpid,dstaddr)] = time.time() + 4

        r = arp()
        r.hwtype = r.HW_TYPE_ETHERNET
        r.prototype = r.PROTO_TYPE_IP
        r.hwlen = 6
        r.protolen = r.protolen
        r.opcode = r.REQUEST
        r.hwdst = ETHER_BROADCAST
        r.protodst = dstaddr
        r.hwsrc = packet.src
        r.protosrc = packet.next.srcip
        e = ethernet(type=ethernet.ARP_TYPE, src=packet.src,
                     dst=ETHER_BROADCAST)
        e.set_payload(r)
        log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport,
         r.protodst, r.protosrc))
        msg = of.ofp_packet_out()
        msg.data = e.pack()
        msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
        msg.in_port = inport
        event.connection.send(msg)

    elif isinstance(packet.next, arp):
      a = packet.next
      log.debug("%i %i ARP %s %s => %s", dpid, inport,
       {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode,
       'op:%i' % (a.opcode,)), a.protosrc, a.protodst)

      if a.prototype == arp.PROTO_TYPE_IP:
        if a.hwtype == arp.HW_TYPE_ETHERNET:
          if a.protosrc != 0:

            # Learn or update port/MAC info
            if a.protosrc in self.arpTable[dpid]:
              if self.arpTable[dpid][a.protosrc] != (inport, packet.src):
                log.info("%i %i RE-learned %s", dpid,inport,a.protosrc)
                if self.wide:
                  # Make sure we don't have any entries with the old info...
                  msg = of.ofp_flow_mod(command=of.OFPFC_DELETE)
                  msg.match.dl_type = ethernet.IP_TYPE
                  msg.match.nw_dst = a.protosrc
                  event.connection.send(msg)
            else:
              log.debug("%i %i learned %s", dpid,inport,a.protosrc)
            self.arpTable[dpid][a.protosrc] = Entry(inport, packet.src)

            # Send any waiting packets...
            self._send_lost_buffers(dpid, a.protosrc, packet.src, inport)

            if a.opcode == arp.REQUEST:
              # Maybe we can answer

              if a.protodst in self.arpTable[dpid]:
                # We have an answer...

                if not self.arpTable[dpid][a.protodst].isExpired():
                  # .. and it's relatively current, so we'll reply ourselves

                  r = arp()
                  r.hwtype = a.hwtype
                  r.prototype = a.prototype
                  r.hwlen = a.hwlen
                  r.protolen = a.protolen
                  r.opcode = arp.REPLY
                  r.hwdst = a.hwsrc
                  r.protodst = a.protosrc
                  r.protosrc = a.protodst
                  r.hwsrc = self.arpTable[dpid][a.protodst].mac
                  e = ethernet(type=packet.type, src=dpid_to_mac(dpid),
                               dst=a.hwsrc)
                  e.set_payload(r)
                  log.debug("%i %i answering ARP for %s" % (dpid, inport,
                   r.protosrc))
                  msg = of.ofp_packet_out()
                  msg.data = e.pack()
                  msg.actions.append(of.ofp_action_output(port =
                                                          of.OFPP_IN_PORT))
                  msg.in_port = inport
                  event.connection.send(msg)
                  return

      # Didn't know how to answer or otherwise handle this ARP, so just flood it
      log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport,
       {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode,
       'op:%i' % (a.opcode,)), a.protosrc, a.protodst))

      msg = of.ofp_packet_out(in_port = inport, data = event.ofp,
          action = of.ofp_action_output(port = of.OFPP_FLOOD))
      event.connection.send(msg)
Exemplo n.º 20
0
    def _handle_PacketIn(self, event):
        log.debug("FUNCTION: _handle_PacketIn")
        packet = event.parsed
        connection = event.connection
        inport = event.port

        # Handle LLDP or Ipv6 packets
        if packet.type == packet.LLDP_TYPE or packet.type == packet.IPV6_TYPE:
            log.info("Received LLDP or IPv6 Packet...")

        # Handle ARP packets
        elif packet.type == packet.ARP_TYPE:
            log.debug("Received ARP Packet")
            response = packet.payload

            # Handle ARP reply
            if response.opcode == response.REPLY:
                log.debug("ARP REPLY Received")
                if response.protosrc not in self.SERVERS.keys():
                    # Adding the servers' MAC addresses and port numbers to the SERVERS dictionary if they're not
                    # there already
                    self.SERVERS[IPAddr(response.protosrc)] = {'server_mac': EthAddr(response.hwsrc), 'port': inport}

            # Handle ARP request
            elif response.opcode == response.REQUEST:
                log.debug("ARP REQUEST Received")
                if response.protosrc not in self.SERVERS.keys() and response.protosrc not in self.CLIENTS.keys():

                    # Indexing the client IP, mac and port number in a forwarding table
                    self.CLIENTS[response.protosrc] = {'client_mac': EthAddr(packet.payload.hwsrc), 'port': inport}

                if response.protosrc in self.CLIENTS.keys() and response.protodst == self.LOADBALANCER_IP:
                    log.info("Client %s sent ARP req to LB %s" % (response.protosrc, response.protodst))
                    self.send_arp_reply(packet, connection, inport)

                elif response.protosrc in self.SERVERS.keys() and response.protodst in self.CLIENTS.keys():
                    log.info("Server %s sent ARP req to client" % response.protosrc)
                    self.send_arp_reply(packet, connection, inport)

                else:
                    log.info("Invalid ARP request")

        # Handle IPv4 packets
        elif packet.type == packet.IP_TYPE:
            log.debug("Received IP Packet from %s" % packet.next.srcip)

            # Handle Requests from Clients to Servers

            # Install flow rule Client -> Server
            if (packet.next.dstip == self.LOADBALANCER_IP) and (packet.next.srcip not in self.SERVERS.keys()):

                self.update_lb_mapping(packet.next.srcip)
                client_ip = packet.payload.srcip
                server_ip = self.LOADBALANCER_MAP.get(packet.next.srcip)
                outport = self.SERVERS[server_ip].get('port')

                self.install_flow_rule_client_to_server(event, connection, outport, client_ip, server_ip)

                eth = ethernet() #Creating ethernet frame
                eth.type = eth.IP_TYPE
                eth.dst = self.SERVERS[server_ip].get('server_mac')
                eth.src = LOADBALANCER_MAC
                eth.set_payload(packet.next)

                # Send the first packet (which was sent to the controller from the switch)
                # to the chosen server, so there is no packetloss
                msg = of.ofp_packet_out()
                msg.data = eth.pack()
                msg.in_port = inport

                msg.actions.append(of.ofp_action_dl_addr.set_src(LOADBALANCER_MAC))
                msg.actions.append(of.ofp_action_dl_addr.set_dst(self.SERVERS[server_ip].get('server_mac')))
                msg.actions.append(of.ofp_action_nw_addr.set_src(client_ip))
                msg.actions.append(of.ofp_action_nw_addr.set_dst(server_ip))
                msg.actions.append(of.ofp_action_output(port=outport))

                connection.send(msg)

            # Handle traffic from Server to Client
            # Install flow rule Client <- Server
            elif packet.next.dstip in self.CLIENTS.keys():  # server to client
                log.info("Installing flow rule from Server -> Client")
                if packet.next.srcip in self.SERVERS.keys():
                    server_ip = packet.next.srcip

                    client_ip = self.LOADBALANCER_MAP.keys()[
                    list(self.LOADBALANCER_MAP.values()).index(packet.next.srcip)]
                    outport = self.CLIENTS[client_ip].get('port')
                    self.install_flow_rule_server_to_client(connection, outport, server_ip, client_ip)


                    eth = ethernet() #Creating ethernet frame
                    eth.type = eth.IP_TYPE
                    eth.dst = self.SERVERS[server_ip].get('server_mac')
                    eth.src = LOADBALANCER_MAC
                    eth.set_payload(packet.next)

                    # Send the first packet (which was sent to the controller from the switch)
                    # to the chosen server, so there is no packetloss
                    msg = of.ofp_packet_out()
                    msg.data = eth.pack()
                    msg.in_port = inport

                    msg.actions.append(of.ofp_action_dl_addr.set_src(LOADBALANCER_MAC))
                    msg.actions.append(of.ofp_action_dl_addr.set_dst(self.CLIENTS[client_ip].get('client_mac')))
                    msg.actions.append(of.ofp_action_nw_addr.set_src(self.LOADBALANCER_IP))
                    msg.actions.append(of.ofp_action_nw_addr.set_dst(client_ip))
                    msg.actions.append(of.ofp_action_output(port=outport))

                    self.connection.send(msg)

        else:
            log.info("Unknown Packet type: %s" % packet.type)
            return
        return
class arp(packet_base):
    "ARP/RARP packet struct"

    MIN_LEN = 28

    HW_TYPE_ETHERNET = 1
    PROTO_TYPE_IP = 0x0800

    # OPCODES
    REQUEST = 1  # ARP
    REPLY = 2  # ARP
    REV_REQUEST = 3  # RARP
    REV_REPLY = 4  # RARP

    def __init__(self, raw=None, prev=None, **kw):
        packet_base.__init__(self)

        self.prev = prev

        self.hwtype = arp.HW_TYPE_ETHERNET
        self.prototype = arp.PROTO_TYPE_IP
        self.hwsrc = ETHER_ANY
        self.hwdst = ETHER_ANY
        self.hwlen = 6
        self.opcode = 0
        self.protolen = 4
        self.protosrc = IP_ANY
        self.protodst = IP_ANY
        self.next = b''

        if raw is not None:
            self.parse(raw)

        self._init(kw)

    def parse(self, raw):
        assert isinstance(raw, bytes)
        self.next = None  # In case of unfinished parsing
        self.raw = raw
        dlen = len(raw)
        if dlen < arp.MIN_LEN:
            self.msg(
                '(arp parse) warning IP packet data too short to parse header: data len %u'
                % dlen)
            return

        (self.hwtype, self.prototype, self.hwlen, self.protolen,self.opcode) =\
        struct.unpack('!HHBBH', raw[:8])

        if self.hwtype != arp.HW_TYPE_ETHERNET:
            self.msg('(arp parse) hw type unknown %u' % self.hwtype)
        if self.hwlen != 6:
            self.msg('(arp parse) unknown hw len %u' % self.hwlen)
        else:
            self.hwsrc = EthAddr(raw[8:14])
            self.hwdst = EthAddr(raw[18:24])
        if self.prototype != arp.PROTO_TYPE_IP:
            self.msg('(arp parse) proto type unknown %u' % self.prototype)
        if self.protolen != 4:
            self.msg('(arp parse) unknown proto len %u' % self.protolen)
        else:
            self.protosrc = IPAddr(struct.unpack('!I', raw[14:18])[0])
            self.protodst = IPAddr(struct.unpack('!I', raw[24:28])[0])

        self.next = raw[28:]
        self.parsed = True

    def hdr(self, payload):
        buf = struct.pack('!HHBBH', self.hwtype, self.prototype, self.hwlen,
                          self.protolen, self.opcode)
        if type(self.hwsrc) == bytes:
            buf += self.hwsrc
        else:
            buf += self.hwsrc.toRaw()
        if type(self.protosrc) is IPAddr:
            buf += struct.pack('!I', self.protosrc.toUnsigned())
        else:
            buf += struct.pack('!I', self.protosrc)
        if type(self.hwdst) == bytes:
            buf += self.hwdst
        else:
            buf += self.hwdst.toRaw()
        if type(self.protodst) is IPAddr:
            buf += struct.pack('!I', self.protodst.toUnsigned())
        else:
            buf += struct.pack('!I', self.protodst)
        return buf

    def _to_str(self):
        op = str(self.opcode)

        eth_type = None
        # Ethernet
        if hasattr(self.prev, 'type'):
            eth_type = self.prev.type
        # Vlan
        elif hasattr(self.prev, 'eth_type'):
            eth_type = self.prev.eth_type
        else:
            self.err('(arp) unknown datalink type')
            eth_type = ethernet.ARP_TYPE

        if eth_type == ethernet.ARP_TYPE:
            if self.opcode == arp.REQUEST:
                op = "REQUEST"
            elif self.opcode == arp.REPLY:
                op = "REPLY"
        elif eth_type == ethernet.RARP_TYPE:
            if self.opcode == arp.REV_REQUEST:
                op = "REV_REQUEST"
            elif self.opcode == arp.REV_REPLY:
                op = "REV_REPLY"

        s = "[ARP {0} hw:{1} p:{2} {3}>{4} {5}>{6}]".format(
            op, self.hwtype, self.prototype, EthAddr(self.hwsrc),
            EthAddr(self.hwdst), IPAddr(self.protosrc), IPAddr(self.protodst))
        return s
Exemplo n.º 22
0
 def match_dst_ip(msg, ip_string):
     msg.match.dl_type = 0x800
     msg.match.nw_dst = IPAddr(ip_string)
Exemplo n.º 23
0
log = core.getLogger()

#flow3:

switch2 = 0000000000000003

flow2msg = of.ofp_flow_mod()

flow2msg.cookie = 0

flow2msg.match.in_port = 2

flow2msg.match.dl_type = 0x0800

flow2msg.match.nw_src = IPAddr("192.168.1.10")

# ACTIONS---------------------------------

flow2out = of.ofp_action_output(port=1)

flow2srcIP = of.ofp_action_nw_addr.set_src(IPAddr("10.0.0.2"))

flow2srcMAC = of.ofp_action_dl_addr.set_src(EthAddr("00:00:00:00:00:04"))

flow2dstMAC = of.ofp_action_dl_addr.set_dst(EthAddr("00:00:00:00:00:01"))

flow2msg.actions = [flow2srcIP, flow2srcMAC, flow2dstMAC, flow2out]

#flow4:
 def __init__(self, ip, mac, port):
     self.ip = IPAddr(ip)
     self.mac = EthAddr(mac)
     self.port = port
     self.conn = 0
     self.cliList = []
from pox.lib.addresses import IPAddr, EthAddr
import time
import hashlib
import re
import sys

log = core.getLogger()

IDLE_TOUT = 5  #seconds
HARD_TOUT = 1000  #seconds

#Redirect stdout to controller_results.txt
#sys.stdout = open("controller_results.txt", "w")

#HS load balancer
LB_IP = IPAddr('10.1.0.254')
LB_MAC = EthAddr('00:00:00:00:FE:00')


#HS load balancer
class LoadBalancer(EventMixin):
    class Server:
        def __init__(self, ip, mac, port):
            self.ip = IPAddr(ip)
            self.mac = EthAddr(mac)
            self.port = port
            self.conn = 0
            self.cliList = []

        def __str__(self):
            return ','.join(
Exemplo n.º 26
0
class ipv4(packet_base):
    "IP packet struct"

    MIN_LEN = 20

    IPv4 = 4
    ICMP_PROTOCOL = 1
    TCP_PROTOCOL  = 6
    UDP_PROTOCOL  = 17
    IGMP_PROTOCOL = 2
    SINE_PROTOCOL = 160 #DJ++ 20131204 10100000


    DF_FLAG = 0x02
    MF_FLAG = 0x01

    ip_id = int(time.time())

    def __init__(self, raw=None, prev=None, **kw):
        packet_base.__init__(self)

        self.prev = prev

        self.v     = 4
        self.hl    = ipv4.MIN_LEN / 4
        self.tos   = 0
        self.iplen = ipv4.MIN_LEN
        ipv4.ip_id = (ipv4.ip_id + 1) & 0xffff
        self.id    = ipv4.ip_id
        self.flags = 0
        self.frag  = 0
        self.ttl   = 64
        self.protocol = 0
        self.csum  = 0
        self.srcip = IP_ANY
        self.dstip = IP_ANY
        self.next  = b''

        if raw is not None:
            self.parse(raw)

        self._init(kw) #for what? DJ 20131218

    def __str__(self):
        s = "[IP+%s %s>%s (cs:%02x v:%s hl:%s l:%s t:%s)]" % (
            ipproto_to_str(self.protocol),
            self.srcip, self.dstip,
            self.csum,
            self.v, self.hl, self.iplen, self.ttl)

        return s

    def parse(self, raw):
        assert isinstance(raw, bytes)
        self.raw = raw
        dlen = len(raw)
        if dlen < ipv4.MIN_LEN:
            self.msg('warning IP packet data too short to parse header: data len %u' % (dlen,))
            return

        (vhl, self.tos, self.iplen, self.id, self.frag, self.ttl,
            self.protocol, self.csum, self.srcip, self.dstip) \
             = struct.unpack('!BBHHHBBHII', raw[:ipv4.MIN_LEN])

        self.v = vhl >> 4
        self.hl = vhl & 0x0f

        self.flags = self.frag >> 13
        self.frag  = self.frag & 0x1fff

        if self.v != ipv4.IPv4:
            self.msg('(ip parse) warning IP version %u not IPv4' % self.v)
            return
        elif self.hl < 5:
            self.msg('(ip parse) warning IP header %u longer than len %u' \
                        % (self.hl, self.iplen))
            return
        elif self.iplen < ipv4.MIN_LEN:
            self.msg('(ip parse) warning invalid IP len %u' % self.iplen)
            return
        elif (self.hl * 4) >= self.iplen or (self.hl * 4) > dlen:
            self.msg('(ip parse) warning IP header %u longer than len %u' \
                        % (self.hl, self.iplen))
            return

        self.dstip = IPAddr(self.dstip)
        self.srcip = IPAddr(self.srcip)

        # At this point, we are reasonably certain that we have an IP
        # packet
        self.parsed = True

        length = self.iplen
        if length > dlen:
            length = dlen # Clamp to what we've got
        if self.protocol == ipv4.UDP_PROTOCOL:
            self.next = udp(raw=raw[self.hl*4:length], prev=self)
        elif self.protocol == ipv4.TCP_PROTOCOL:
            self.next = tcp(raw=raw[self.hl*4:length], prev=self)
        elif self.protocol == ipv4.ICMP_PROTOCOL:
            self.next = icmp(raw=raw[self.hl*4:length], prev=self)
        elif self.protocol == ipv4.IGMP_PROTOCOL:
            self.next = igmp(raw=raw[self.hl*4:length], prev=self)
        #DJ++ 20131204
        elif self.protocol == ipv4.SINE_PROTOCOL:
            self.next = sine(raw=raw[self.hl*4:length], prev=self)
        elif dlen < self.iplen:
            self.msg('(ip parse) warning IP packet data shorter than IP len: %u < %u' % (dlen, self.iplen))
        else:
            self.next =  raw[self.hl*4:length]

        if isinstance(self.next, packet_base) and not self.next.parsed:
            self.next = raw[self.hl*4:length]

    def checksum(self):
        data = struct.pack('!BBHHHBBHII', (self.v << 4) + self.hl, self.tos,
                                 self.iplen, self.id,
                                 (self.flags << 13) | self.frag, self.ttl,
                                 self.protocol, 0, self.srcip.toUnsigned(),
                                 self.dstip.toUnsigned())
        return checksum(data, 0)


    def hdr(self, payload):
        self.iplen = self.hl * 4 + len(payload)
        self.csum = self.checksum()
        return struct.pack('!BBHHHBBHII', (self.v << 4) + self.hl, self.tos,
                           self.iplen, self.id,
                           (self.flags << 13) | self.frag, self.ttl,
                           self.protocol, self.csum, self.srcip.toUnsigned(),
                           self.dstip.toUnsigned())
    def _handle_openflow_PacketIn(self, event):
        dpid = event.connection.dpid
        inport = event.port
        packet = event.parsed
        global set_Timer
        global defendDDOS
        global blockPort
        timerSet = False
        global diction

        def preventing():
            global diction
            global set_Timer
            if not set_Timer:
                set_Timer = True

            if len(diction) == 0:
                print("Empty diction ", str(event.connection.dpid),
                      str(event.port))
                diction[event.connection.dpid] = {}
                diction[event.connection.dpid][event.port] = 1
            elif event.connection.dpid not in diction:
                diction[event.connection.dpid] = {}
                diction[event.connection.dpid][event.port] = 1
            else:
                if event.connection.dpid in diction:
                    if event.port in diction[event.connection.dpid]:
                        temp_count = 0
                        temp_count = diction[event.connection.dpid][event.port]
                        temp_count = temp_count + 1
                        diction[event.connection.dpid][event.port] = temp_count
                        #print "*****************************************************************************************************************************************************************************"
                        print "dpid port and its packet count: ", str(
                            event.connection.dpid), str(
                                diction[event.connection.dpid]), str(
                                    diction[event.connection.dpid][event.port])
                        #print "*****************************************************************************************************************************************************************************"
                    else:
                        diction[event.connection.dpid][event.port] = 1

        def _timer_func():
            global diction
            global set_Timer

            if set_Timer == True:
                for k, v in diction.iteritems():
                    for i, j in v.iteritems():
                        if j >= 5:
                            print "_____________________________________________________________________________________________"
                            print "\n                               DDOS DETECTED                                              \n"
                            print "\n", str(diction)
                            print "\n", datetime.datetime.now(
                            ), ": BLOCKED PORT NUMBER  : ", str(
                                i), " OF SWITCH ID: ", str(k)
                            print "\n___________________________________________________________________________________________"
                            os._exit(0)
                            dpid = k
                            msg = of.ofp_packet_out(in_port=i)
                            core.openflow.sendToDPID(dpid, msg)
            diction = {}

        if not packet.parsed:
            log.warning("%i %i ignoring unparsed packet", dpid, inport)
            return

        if dpid not in self.arpTable:
            self.arpTable[dpid] = {}
            for fake in self.fakeways:
                self.arpTable[dpid][IPAddr(fake)] = Entry(
                    of.OFPP_NONE, dpid_to_mac(dpid))

        if packet.type == ethernet.LLDP_TYPE:
            return

        if isinstance(packet.next, ipv4):
            log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip,
                      packet.next.dstip)
            ent_obj.collectStats(event.parsed.next.dstip)
            print "Entropy : ", str(ent_obj.value)
            if ent_obj.value < 1.0:
                preventing()
                if timerSet is not True:
                    Timer(1, _timer_func, recurring=True)
                    timerSet = False
            else:
                timerSet = False

            self._send_lost_buffers(dpid, packet.next.srcip, packet.src,
                                    inport)

            if packet.next.srcip in self.arpTable[dpid]:
                if self.arpTable[dpid][packet.next.srcip] != (inport,
                                                              packet.src):
                    log.info("%i %i RE-learned %s", dpid, inport,
                             packet.next.srcip)
                    if self.wide:
                        msg = of.ofp_flow_mod(command=of.OFPFC_DELETE)
                        msg.match.nw_dst = packet.next.srcip
                        msg.match.dl_type = ethernet.IP_TYPE
                        event.connection.send(msg)
            else:
                log.debug("%i %i learned %s", dpid, inport, packet.next.srcip)
            self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)

            dstaddr = packet.next.dstip
            if dstaddr in self.arpTable[dpid]:

                prt = self.arpTable[dpid][dstaddr].port
                mac = self.arpTable[dpid][dstaddr].mac
                if prt == inport:
                    log.warning(
                        "%i %i not sending packet for %s back out of the "
                        "input port" % (dpid, inport, dstaddr))
                else:
                    log.debug(
                        "%i %i installing flow for %s => %s out port %i" %
                        (dpid, inport, packet.next.srcip, dstaddr, prt))

                    actions = []
                    actions.append(of.ofp_action_dl_addr.set_dst(mac))
                    actions.append(of.ofp_action_output(port=prt))
                    if self.wide:
                        match = of.ofp_match(dl_type=packet.type,
                                             nw_dst=dstaddr)
                    else:
                        match = of.ofp_match.from_packet(packet, inport)

                    msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                          idle_timeout=FLOW_IDLE_TIMEOUT,
                                          hard_timeout=of.OFP_FLOW_PERMANENT,
                                          buffer_id=event.ofp.buffer_id,
                                          actions=actions,
                                          match=match)
                    event.connection.send(msg.pack())
            elif self.arp_for_unknowns:
                if (dpid, dstaddr) not in self.lost_buffers:
                    self.lost_buffers[(dpid, dstaddr)] = []
                bucket = self.lost_buffers[(dpid, dstaddr)]
                entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id,
                         inport)
                bucket.append(entry)
                while len(bucket) > MAX_BUFFERED_PER_IP:
                    del bucket[0]

                self.outstanding_arps = {
                    k: v
                    for k, v in self.outstanding_arps.iteritems()
                    if v > time.time()
                }

                if (dpid, dstaddr) in self.outstanding_arps:
                    return

                self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4

                r = arp()
                r.hwtype = r.HW_TYPE_ETHERNET
                r.prototype = r.PROTO_TYPE_IP
                r.hwlen = 6
                r.protolen = r.protolen
                r.opcode = r.REQUEST
                r.hwdst = ETHER_BROADCAST
                r.protodst = dstaddr
                r.hwsrc = packet.src
                r.protosrc = packet.next.srcip
                e = ethernet(type=ethernet.ARP_TYPE,
                             src=packet.src,
                             dst=ETHER_BROADCAST)
                e.set_payload(r)
                log.debug("%i %i ARPing for %s on behalf of %s" %
                          (dpid, inport, r.protodst, r.protosrc))
                msg = of.ofp_packet_out()
                msg.data = e.pack()
                msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
                msg.in_port = inport
                event.connection.send(msg)

        elif isinstance(packet.next, arp):
            a = packet.next
            log.debug("%i %i ARP %s %s => %s", dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst)

            if a.prototype == arp.PROTO_TYPE_IP:
                if a.hwtype == arp.HW_TYPE_ETHERNET:
                    if a.protosrc != 0:

                        if a.protosrc in self.arpTable[dpid]:
                            if self.arpTable[dpid][a.protosrc] != (inport,
                                                                   packet.src):
                                log.info("%i %i RE-learned %s", dpid, inport,
                                         a.protosrc)
                                if self.wide:
                                    msg = of.ofp_flow_mod(
                                        command=of.OFPFC_DELETE)
                                    msg.match.dl_type = ethernet.IP_TYPE
                                    msg.match.nw_dst = a.protosrc
                                    event.connection.send(msg)
                        else:
                            log.debug("%i %i learned %s", dpid, inport,
                                      a.protosrc)
                        self.arpTable[dpid][a.protosrc] = Entry(
                            inport, packet.src)

                        self._send_lost_buffers(dpid, a.protosrc, packet.src,
                                                inport)

                        if a.opcode == arp.REQUEST:

                            if a.protodst in self.arpTable[dpid]:

                                if not self.arpTable[dpid][
                                        a.protodst].isExpired():

                                    r = arp()
                                    r.hwtype = a.hwtype
                                    r.prototype = a.prototype
                                    r.hwlen = a.hwlen
                                    r.protolen = a.protolen
                                    r.opcode = arp.REPLY
                                    r.hwdst = a.hwsrc
                                    r.protodst = a.protosrc
                                    r.protosrc = a.protodst
                                    r.hwsrc = self.arpTable[dpid][
                                        a.protodst].mac
                                    e = ethernet(type=packet.type,
                                                 src=dpid_to_mac(dpid),
                                                 dst=a.hwsrc)
                                    e.set_payload(r)
                                    log.debug("%i %i answering ARP for %s" %
                                              (dpid, inport, r.protosrc))
                                    msg = of.ofp_packet_out()
                                    msg.data = e.pack()
                                    msg.actions.append(
                                        of.ofp_action_output(
                                            port=of.OFPP_IN_PORT))
                                    msg.in_port = inport
                                    event.connection.send(msg)
                                    return

            log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst))

            msg = of.ofp_packet_out(
                in_port=inport,
                data=event.ofp,
                action=of.ofp_action_output(port=of.OFPP_FLOOD))
            event.connection.send(msg)
Exemplo n.º 28
0
    def _handle_PacketIn(self, event):
        dpid = event.connection.dpid
        inport = event.port
        packet = event.parsed
        if not packet.parsed:
            log.warning("%i %i ignoring unparsed packet", dpid, inport)
            return

        if dpid not in self.ip_mac_port:
            self.ip_mac_port[dpid] = {}
            for fake in self.fakeways:
                self.ip_mac_port[dpid][IPAddr(fake)] = Entry(
                    of.OFPP_NONE, dpid_to_mac(dpid))

        if packet.type == ethernet.LLDP_TYPE:
            return

        if isinstance(packet.next, ipv4):
            log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip,
                      packet.next.dstip)

            self._send_lost_buffers(dpid, packet.next.srcip, packet.src,
                                    inport)

            if packet.next.srcip in self.ip_mac_port[dpid]:
                if self.ip_mac_port[dpid][packet.next.srcip] != (inport,
                                                                 packet.src):
                    log.debug("%i %i RE-learned %s", dpid, inport,
                              packet.next.srcip)
            else:
                #log.info("%i %i learned %s", dpid,inport,str(packet.next.srcip))
                log.info("switch %i learned %s from input port %i", dpid,
                         str(packet.next.srcip), inport)
            self.ip_mac_port[dpid][packet.next.srcip] = Entry(
                inport, packet.src)

            dstaddr = packet.next.dstip
            if dstaddr in self.ip_mac_port[dpid]:

                prt = self.ip_mac_port[dpid][dstaddr].port
                mac = self.ip_mac_port[dpid][dstaddr].mac
                print dstaddr
                if prt == inport:
                    log.warning(
                        "%i %i not sending packet for %s back out of the " +
                        "input port" % (dpid, inport, str(dstaddr)))
                else:
                    log.debug(
                        "%i %i installing flow for %s => %s out port %i" %
                        (dpid, inport, packet.next.srcip, dstaddr, prt))

                    if event.ofp.buffer_id == None:
                        bid = None
                    else:
                        bid = event.ofp.buffer_id

                    ip_packet = packet.find("ipv4")
                    if ip_packet != None:

                        if ip_packet.protocol == 1:
                            actions3 = []
                            actions3.append(of.ofp_action_dl_addr.set_dst(mac))
                            #actions3.append(of.ofp_action_output(port = prt))
                            actions3.append(
                                of.ofp_action_enqueue(port=prt, queue_id=1))
                            match3 = of.ofp_match.from_packet(packet, inport)
                            match3.dl_type = 0x800
                            match3.nw_proto = 1
                            match3.dl_src = None
                            msg3 = of.ofp_flow_mod(
                                command=of.OFPFC_ADD,
                                idle_timeout=FLOW_IDLE_TIMEOUT,
                                hard_timeout=of.OFP_FLOW_PERMANENT,
                                buffer_id=bid,
                                actions=actions3,
                                priority=30,
                                match=match3)
                            event.connection.send(msg3.pack())
                            print "into queue 1"
                        elif ip_packet.protocol == 17 or ip_packet.protocol == 6:
                            udp_packet = packet.find("udp")
                            if udp_packet == None:
                                udp_packet = packet.find("tcp")
                            if ip_packet.dstip == IPAddr(
                                    "172.16.0.3"
                            ) and udp_packet.dstport == 5001:
                                actions5 = []
                                actions5.append(
                                    of.ofp_action_dl_addr.set_dst(mac))
                                #actions5.append(of.ofp_action_output(port = prt))
                                actions5.append(
                                    of.ofp_action_enqueue(port=prt,
                                                          queue_id=3))
                                match5 = of.ofp_match.from_packet(
                                    packet, inport)
                                match5.dl_type = 0x800
                                match5.nw_proto = 17
                                match5.nw_dst = IPAddr("172.16.0.3")
                                match5.tp_dst = 5001
                                match5.dl_src = None
                                msg5 = of.ofp_flow_mod(
                                    command=of.OFPFC_ADD,
                                    idle_timeout=FLOW_IDLE_TIMEOUT,
                                    hard_timeout=of.OFP_FLOW_PERMANENT,
                                    buffer_id=bid,
                                    actions=actions5,
                                    priority=43,
                                    match=match5)
                                event.connection.send(msg5.pack())
                                print "privillaged user into queue 3"
                            elif ip_packet.tos == 0:
                                actions2 = []
                                actions2.append(
                                    of.ofp_action_dl_addr.set_dst(mac))
                                #actions2.append(of.ofp_action_output(port = prt))
                                actions2.append(of.ofp_action_nw_tos(224))
                                actions2.append(
                                    of.ofp_action_enqueue(port=prt,
                                                          queue_id=2))
                                match2 = of.ofp_match.from_packet(
                                    packet, inport)
                                match2.dl_type = 0x800
                                if udp_packet != None:
                                    match2.nw_proto = 17
                                else:
                                    match2.nw_proto = 6
                                match2.dl_src = None
                                msg2 = of.ofp_flow_mod(
                                    command=of.OFPFC_ADD,
                                    idle_timeout=FLOW_IDLE_TIMEOUT,
                                    hard_timeout=of.OFP_FLOW_PERMANENT,
                                    buffer_id=bid,
                                    actions=actions2,
                                    priority=42,
                                    match=match2)
                                event.connection.send(msg2.pack())
                                print "into queue 2"
                            else:
                                actions1 = []
                                actions1.append(
                                    of.ofp_action_dl_addr.set_dst(mac))
                                #actions1.append(of.ofp_action_output(port = prt))
                                actions1.append(
                                    of.ofp_action_enqueue(port=prt,
                                                          queue_id=2))
                                match1 = of.ofp_match.from_packet(
                                    packet, inport)
                                match1.dl_type = 0x800
                                match1.nw_tos = 224
                                match1.dl_src = None
                                msg1 = of.ofp_flow_mod(
                                    command=of.OFPFC_ADD,
                                    idle_timeout=FLOW_IDLE_TIMEOUT,
                                    hard_timeout=of.OFP_FLOW_PERMANENT,
                                    buffer_id=bid,
                                    actions=actions1,
                                    priority=42,
                                    match=match1)
                                event.connection.send(msg1.pack())
                                print "into queue 2 dscp tagged"
                    else:
                        actions = []
                        actions.append(of.ofp_action_dl_addr.set_dst(mac))
                        actions.append(of.ofp_action_output(port=prt))
                        match4 = of.ofp_match.from_packet(packet, inport)
                        match4.dl_src = None  # Wildcard source MAC

                        msg = of.ofp_flow_mod(
                            command=of.OFPFC_ADD,
                            idle_timeout=FLOW_IDLE_TIMEOUT,
                            hard_timeout=of.OFP_FLOW_PERMANENT,
                            buffer_id=bid,
                            actions=actions,
                            priority=20,
                            match=match4)
                        event.connection.send(msg.pack())

            elif self.arp_for_unknowns:
                if (dpid, dstaddr) not in self.lost_buffers:
                    self.lost_buffers[(dpid, dstaddr)] = []
                bucket = self.lost_buffers[(dpid, dstaddr)]
                entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id,
                         inport)
                bucket.append(entry)
                while len(bucket) > MAX_BUFFERED_PER_IP:
                    del bucket[0]

                self.outstanding_arps = {
                    k: v
                    for k, v in self.outstanding_arps.iteritems()
                    if v > time.time()
                }

                if (dpid, dstaddr) in self.outstanding_arps:
                    return

                self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4

                r = arp()
                r.hwtype = r.HW_TYPE_ETHERNET
                r.prototype = r.PROTO_TYPE_IP
                r.hwlen = 6
                r.protolen = r.protolen
                r.opcode = r.REQUEST
                r.hwdst = ETHER_BROADCAST
                r.protodst = dstaddr
                r.hwsrc = packet.src
                r.protosrc = packet.next.srcip
                e = ethernet(type=ethernet.ARP_TYPE,
                             src=packet.src,
                             dst=ETHER_BROADCAST)
                e.set_payload(r)
                log.debug("%i %i ARPing for %s on behalf of %s" %
                          (dpid, inport, str(r.protodst), str(r.protosrc)))
                msg = of.ofp_packet_out()
                msg.data = e.pack()
                msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
                msg.in_port = inport
                event.connection.send(msg)

        elif isinstance(packet.next, arp):
            a = packet.next
            log.debug("%i %i ARP %s %s => %s", dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc),
                      str(a.protodst))

            if a.prototype == arp.PROTO_TYPE_IP:
                if a.hwtype == arp.HW_TYPE_ETHERNET:
                    if a.protosrc != 0:

                        # Learn or update port/MAC info
                        if a.protosrc in self.ip_mac_port[dpid]:
                            if self.ip_mac_port[dpid][a.protosrc] != (
                                    inport, packet.src):
                                log.debug("%i %i RE-learned %s", dpid, inport,
                                          str(a.protosrc))
                        else:
                            log.info("switch %i learned %s from input port %i",
                                     dpid, str(a.protosrc), inport)
                        self.ip_mac_port[dpid][a.protosrc] = Entry(
                            inport, packet.src)

                        # Send any waiting packets...
                        self._send_lost_buffers(dpid, a.protosrc, packet.src,
                                                inport)

                        if a.opcode == arp.REQUEST:
                            # Maybe we can answer

                            if a.protodst in self.ip_mac_port[dpid]:
                                # We have an answer...

                                if not self.ip_mac_port[dpid][
                                        a.protodst].isExpired():
                                    # .. and it's relatively current, so we'll reply ourselves

                                    r = arp()
                                    r.hwtype = a.hwtype
                                    r.prototype = a.prototype
                                    r.hwlen = a.hwlen
                                    r.protolen = a.protolen
                                    r.opcode = arp.REPLY
                                    r.hwdst = a.hwsrc
                                    r.protodst = a.protosrc
                                    r.protosrc = a.protodst
                                    r.hwsrc = self.ip_mac_port[dpid][
                                        a.protodst].mac
                                    e = ethernet(type=packet.type,
                                                 src=dpid_to_mac(dpid),
                                                 dst=a.hwsrc)
                                    e.set_payload(r)
                                    #log.debug("%i %i answering ARP for %s" % (dpid, inport,str(r.protosrc)))
                                    msg = of.ofp_packet_out()
                                    msg.data = e.pack()
                                    msg.actions.append(
                                        of.ofp_action_output(
                                            port=of.OFPP_IN_PORT))
                                    msg.in_port = inport
                                    event.connection.send(msg)
                                    return

            # Didn't know how to answer or otherwise handle this ARP, so just flood it
            log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' %
                  (a.opcode, )), str(a.protosrc), str(a.protodst)))

            msg = of.ofp_packet_out(
                in_port=inport,
                data=event.ofp,
                action=of.ofp_action_output(port=of.OFPP_FLOOD))
            event.connection.send(msg)
class PCap(object):
    use_select = False  # Falls back to non-select

    @staticmethod
    def get_devices():
        def ip(addr):
            if addr is None:
                return None
            return IPAddr(addr, networkOrder=True)

        def ip6(addr):
            if addr is None:
                return None
            return IPAddr6.from_raw(addr)

        def link(addr):
            if addr is None:
                return None
            if len(addr) != 6:
                return None
            return EthAddr(addr)

        devs = pcapc.findalldevs()
        out = {}
        for d in devs:
            addrs = {}
            n = {"desc": d[1], "addrs": addrs}
            out[d[0]] = n
            for a in d[2]:
                if a[0] == "AF_INET":
                    na = {}
                    addrs[a[0]] = na
                    na["addr"] = ip(a[1])
                    na["netmask"] = ip(a[2])
                    na["broadaddr"] = ip(a[3])
                    na["dstaddr"] = ip(a[4])
                elif a[0] == "AF_INET6":
                    na = {}
                    addrs[a[0]] = na
                    na["addr"] = ip6(a[1])
                    na["netmask"] = ip6(a[2])
                    na["broadaddr"] = ip6(a[3])
                    na["dstaddr"] = ip6(a[4])
                elif a[0] == "AF_LINK":
                    na = {}
                    addrs[a[0]] = na
                    na["addr"] = link(a[1])
                    na["netmask"] = link(a[2])
                    na["broadaddr"] = link(a[3])
                    na["dstaddr"] = link(a[4])
                elif a[0] == "AF_PACKET":
                    addrs[a[0]] = {"addr": link(a[1])}
                elif a[0] == "ethernet":
                    addrs[a[0]] = {"addr": link(a[1])}
        return out

    @staticmethod
    def get_device_names():
        return [d[0] for d in pcapc.findalldevs()]

    def __init__(
        self,
        device=None,
        promiscuous=True,
        period=10,
        start=True,
        callback=None,
        filter=None,
        use_bytearray=False,
        **kw
    ):
        """
    Initialize this instance

    use_bytearray: specifies capturing to bytearray buffers instead of bytes
    """

        if filter is not None:
            self.deferred_filter = (filter,)
        else:
            self.deferred_filter = None
        self.packets_received = 0
        self.packets_dropped = 0
        self._thread = None
        self.pcap = None
        self.promiscuous = promiscuous
        self.device = None
        self.use_bytearray = use_bytearray
        self.period = period
        self.netmask = IPAddr("0.0.0.0")
        self._quitting = False
        self.addresses = {}
        if callback is None:
            self.callback = self.__class__._handle_rx
        else:
            self.callback = callback

        for k, v in kw.items():
            assert not hasattr(self, k)
            setattr(self, k, v)

        if device is not None:
            self.open(device)
        if self.pcap is not None:
            if start:
                self.start()

    def _handle_rx(self, data, sec, usec, length):
        pass

    def open(self, device, promiscuous=None, period=None, incoming=True, outgoing=False):
        assert self.device is None
        self.addresses = self.get_devices()[device]["addrs"]
        if "AF_INET" in self.addresses:
            self.netmask = self.addresses["AF_INET"].get("netmask")
            if self.netmask is None:
                self.netmask = IPAddr("0.0.0.0")
        # print "NM:",self.netmask
        # print self.addresses['AF_LINK']['addr']
        self.device = device
        if period is not None:
            self.period = period
        if promiscuous is not None:
            self.promiscuous = promiscuous
        self.pcap = pcapc.open_live(device, 65535, 1 if self.promiscuous else 0, self.period)
        pcapc.setdirection(self.pcap, incoming, outgoing)
        self.packets_received = 0
        self.packets_dropped = 0
        if self.deferred_filter is not None:
            self.set_filter(*self.deferred_filter)
            self.deferred_filter = None

    def set_direction(self, incoming, outgoing):
        pcapc.setdirection(self._pcap, incoming, outgoing)

    def set_nonblocking(self, nonblocking=True):
        pcapc.setnonblock(self._pcap, 1 if nonblocking else 0)

    def set_blocking(self, blocking=True):
        self.set_nonblocking(nonblocking=not blocking)

    @property
    def blocking(self):
        return False if pcapc.getnonblock(self._pcap) else True

    @blocking.setter
    def blocking(self, value):
        self.set_blocking(value)

    def next_packet(self, allow_threads=True):
        """
    Get next packet

    Returns tuple with:
      data, timestamp_seconds, timestamp_useconds, total length, and
      the pcap_next_ex return value -- 1 is success
    """
        return pcapc.next_ex(self._pcap, bool(self.use_bytearray), allow_threads)

    def _select_thread_func(self):
        try:
            import select

            fd = [self.fileno()]
        except:
            # Fall back
            self._thread_func()
            return

        self.blocking = False

        while not self._quitting:
            rr, ww, xx = select.select(fd, [], fd, 2)

            if xx:
                # Apparently we're done here.
                break
            if rr:
                r = self.next_packet(allow_threads=False)
                if r[-1] == 0:
                    continue
                if r[-1] == 1:
                    self.callback(self, r[0], r[1], r[2], r[3])
                else:
                    break

        self._quitting = False
        self._thread = None

    def _thread_func(self):
        while not self._quitting:
            pcapc.dispatch(self.pcap, 100, self.callback, self, bool(self.use_bytearray), True)
            self.packets_received, self.packets_dropped = pcapc.stats(self.pcap)

        self._quitting = False
        self._thread = None

    def _handle_GoingDownEvent(self, event):
        self.close()

    def start(self):
        assert self._thread is None
        from pox.core import core

        core.addListeners(self, weak=True)

        if self.use_select:
            self._thread = Thread(target=self._select_thread_func)
        else:
            self._thread = Thread(target=self._thread_func)
        # self._thread.daemon = True
        self._thread.start()

    def stop(self):
        t = self._thread
        if t is not None:
            self._quitting = True
            pcapc.breakloop(self.pcap)
            t.join()

    def close(self):
        if self.pcap is None:
            return
        self.stop()
        pcapc.close(self.pcap)
        self.pcap = None

    def __del__(self):
        self.close()

    @property
    def _pcap(self):
        if self.pcap is None:
            raise RuntimeError("PCap object not open")
        return self.pcap

    def inject(self, data):
        if isinstance(data, pkt.ethernet):
            data = data.pack()
        if not isinstance(data, (bytes, bytearray)):
            data = bytes(data)  # Give it a try...
        return pcapc.inject(self.pcap, data)

    def set_filter(self, filter, optimize=True):
        if self.pcap is None:
            self.deferred_filter = (filter, optimize)
            return

        if isinstance(filter, str):
            filter = Filter(filter, optimize, self.netmask.toSignedN(), pcap_obj=self)
        elif isinstance(filter, Filter):
            pass
        else:
            raise RuntimeError("Filter must be string or Filter object")

        pcapc.setfilter(self.pcap, filter._pprogram)

    def fileno(self):
        if self.pcap is None:
            raise RuntimeError("PCap object not open")
        r = pcapc.get_selectable_fd(self.pcap)
        if r == -1:
            raise RuntimeError("Selectable FD not available")
        return r

    def __str__(self):
        return "PCap(device=%s)" % (self.device)
Exemplo n.º 30
0
from pox.core import core
import pox.openflow.libopenflow_01 as of
from pox.lib.packet.ethernet import ethernet, ETHER_BROADCAST
from pox.lib.packet.ipv4 import ipv4
from pox.lib.packet.arp import arp
from pox.lib.packet.icmp import icmp
import pox.lib.packet as pkt
from pox.lib.addresses import IPAddr, EthAddr
import struct
import time

log = core.getLogger()
DEFAULT_GATEWAY = 1
validIP = [IPAddr('10.0.1.1'), IPAddr('10.0.1.2'), IPAddr('10.0.1.3'), IPAddr('10.0.2.1'), IPAddr('10.0.2.2'), IPAddr('10.0.2.3'), IPAddr('10.0.2.4')]
subnet1 = ['10.0.1.1', '10.0.1.2', '10.0.1.3']
subnet2 = ['10.0.2.1', '10.0.2.2', '10.0.2.3', '10.0.2.4']

class router(object):
  def __init__(self):
    log.debug('router registered')
    # The dict for all routers, desginated by dpid
    # In each dict, each component is also a dict indexed by dpid
    self.arpTable = {}
    self.arpWait = {}
    self.routingTable = {}
    self.connections = {}
    self.routerIP = {}
    core.openflow.addListeners(self)

  def _handle_GoingUpEvent(self, event):
    self.listenTo(core.openflow)
Exemplo n.º 31
0
    def handle_IPPacket(self, event):
        is_src_router = (event.ofp.in_port == of.OFPP_LOCAL)
        if event.parsed.next.srcip.inNetwork(NON_ROUTABLE_SUBNET,
                                             NON_ROUTABLE_NETMASK):
            print "source ip is not routable"
            return
        if event.parsed.src != self.bridge_mac and not self.check_access(
                event.parsed.src):
            print "%s is not permmited" % (str(event.parsed.src))
            return
        if event.parsed.next.dstip.inNetwork(NON_ROUTABLE_SUBNET,
                                             NON_ROUTABLE_NETMASK):
            print "destination is not routable"
            return
        is_src_local = event.parsed.next.srcip.inNetwork(
            ROUTABLE_SUBNET,
            ROUTABLE_NETMASK) or event.parsed.next.srcip.inNetwork(
                INIT_SUBNET, INIT_NETMASK)
        if is_src_local and (event.parsed.next.srcip.toUnsigned(
                networkOrder=False) & 0x3) == 1:
            if not self.get_DHCP_mapping().is_valid_mapping(
                    event.parsed.next.srcip,
                    event.parsed.src) and event.parsed.src != self.bridge_mac:
                print "received packet from unrecorded mac address"
                return

        if event.parsed.next.dstip.inNetwork(MULTICAST_SUBNET,
                                             MULTICAST_NETMASK):
            print "multicast"
            if event.parsed.next.dstip in self.multicast_ip:
                action = of.ofp_action_output(port=of.OFPP_FLOOD)
                command = of.OFPFC_ADD
                self.send_flow_modification(event,
                                            command, [action],
                                            timeout=30)
        # check if broadcast. Change nw_dst to 10.2.255.255
        if event.parsed.next.dstip.inNetwork(
                ROUTABLE_SUBNET, ROUTABLE_NETMASK) and (
                    (event.parsed.next.dstip.toUnsigned(networkOrder=False)
                     & 0x3) == 0x3):
            print "broadcast IP"
            nw_new = of.ofp_action_nw_addr()
            nw_new.type = of.OFPAT_SET_NW_DST
            nw_new.nw_addr = IPAddr("10.2.255.255")
            out = of.ofp_action_output(
                port=of.OFPP_IN_PORT if event.ofp.in_port == 0 else 0)
            actions = [out, nw_new]
            command = of.OFPFC_ADD
            self.send_flow_modification(event, command, actions, timeout=30)
        dst_port = 0
        if event.parsed.next.dstip.inNetwork(
                ROUTABLE_SUBNET, ROUTABLE_NETMASK) and (
                    (event.parsed.next.dstip.toUnsigned(networkOrder=False)
                     & 0x01) == 0x01):
            dst_port = 1
        else:
            dst_port = 0
        actions = []
        is_dst_local = event.parsed.next.dstip.inNetwork(
            ROUTABLE_SUBNET,
            ROUTABLE_NETMASK) or event.parsed.next.dstip.inNetwork(
                INIT_SUBNET, INIT_NETMASK)
        if is_dst_local and is_src_local and (dst_port !=
                                              0) and (not is_src_router):
            dst_mac = self.get_DHCP_mapping().get_mac(event.parsed.next.dstip)

            new_dl_src = of.ofp_action_dl_addr()
            new_dl_src.type = of.OFPAT_SET_DL_SRC
            new_dl_src.set_src(self.bridge_mac)
            actions.append(new_dl_src)

            new_dl_dst = of.ofp_action_dl_addr()
            new_dl_dst.type = of.OFPAT_SET_DL_DST
            new_dl_dst.set_dst(dst_mac)
            actions.append(new_dl_dst)

        out = of.ofp_action_output(port=of.OFPP_FLOOD)
        actions.append(out)
        if 0 < event.ofp.in_port and event.ofp.in_port < of.OFPP_MAX:
            out_of_in = of.ofp_action_output(port=of.OFPP_IN_PORT)
            actions.append(out_of_in)

        command = of.OFPFC_ADD
        self.send_flow_modification(event, command, actions, timeout=30)
Exemplo n.º 32
0
def sql_flow(event, query):
    dbmgr = DBManager(":memory:")
    #dbmgr = DBManager("testdb.db")
    #dbmgr.query("INSERT INTO person VALUES ('kamran','ali',30)")
    #dbmgr.query("INSERT INTO person VALUES ('yousaf','akhtar',50)")
    #dbmgr.query('INSERT INTO OF_table (MAC_src, MAC_dst, Action) VALUES ("00:00:00:00:00:05","00:00:00:00:00:01", "drop" )')

    dbmgr.query1(query)

    for row in dbmgr.query1("SELECT * FROM OF_table"):
        msg = of.ofp_flow_mod()
        if row[0] != None:
            msg.match.in_port = int(row[0])  # 2
        if row[1] != None:
            msg.match.dl_src = EthAddr(row[1])  # EthAddr("01:02:03:04:05:06")
        if row[2] != None:
            msg.match.dl_dst = EthAddr(row[2])  # EthAddr("01:02:03:04:05:06")
        if row[3] != None:
            msg.match.dl_type = int(row[3])  # 0x800
        if row[4] != None:
            msg.match.dl_vlan = int(row[4])  # 10
        if row[5] != None:
            msg.match.dl_vlan_pcp = int(
                row[5])  # 100 value may vary from 0~255
        if row[6] != None:
            msg.match.nw_src = IPAddr(row[6])  # "192.168.66.0/24"
        if row[7] != None:
            msg.match.nw_dst = IPAddr(row[7])  # "192.168.66.0/24"
        if row[8] != None:
            msg.match.nw_proto = int(row[8])  # 6 is for tcp
        if row[9] != None:
            msg.match.nw_tos = int(row[9])  # 3 # quality of service class
        if row[10] != None:
            msg.match.tp_src = int(row[10])  # 80
        if row[11] != None:
            msg.match.tp_dst = int(row[11])  # 80
        if row[12] != None:
            if row[12] == "flood" or row[12] == "FLOOD":
                msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
            elif row[12] == "drop" or row[12] == "DROP":
                pass
            else:
                msg.actions.append(of.ofp_action_output(port=int(row[12])))
        if row[13] == None:
            msg.idle_timeout = 1000
        else:
            msg.idle_timeout = int(row[13])  # 1000 int
        if row[14] == None:
            msg.hard_timeout = 1000
        else:
            msg.hard_timeout = int(row[14])  # 0 int
        if row[15] != None:
            msg.buffer_id = int(row[15])  # 2870 int
        if row[16] != None:
            msg.priority = int(
                row[16]
            )  # uint16_t priority, Priority level of flow entry 0 is highest priority

        event.connection.send(msg)
        #print "Flow is being deployed"
        log.info("SQL Flow Mode Query from sql module %s",
                 dpidToStr(event.dpid))
Exemplo n.º 33
0
 def install_arp_rule(self, mac, ip, timeout):
     """Updates the ARP Responder with a new rule"""
     entry = arp.Entry(mac, static=True, flood=False)
     entry.timeout = timeout
     self.arp_table[IPAddr(ip)] = entry
Exemplo n.º 34
0
    def _handle_PacketIn(self, event):
        """
        Handles packet in messages from the switch.
        """
        etherFrame = event.parsed  # This is the parsed packet data.

        if not etherFrame.parsed:
            log.warning("!LOG WARN! S1 : Ignoring incomplete packet")
            return

        packet_in = event.ofp  # The actual ofp_packet_in message.

        # Add the new MAC into CAM table
        if str(etherFrame.src) not in self.mac_to_port:
            log.debug('!LOG! S1 : Adding %s into CAM, recv from %s' %
                      (str(etherFrame.src), str(packet_in.in_port)))
            self.mac_to_port[str(etherFrame.src)] = packet_in.in_port

        # ARP
        if etherFrame.type == ethernet.ARP_TYPE:
            log.debug('!LOG! S1 : RECEIVED: EtherType -> ARP')
            self.ARP_Handler(etherFrame, packet_in)
        # IP
        elif etherFrame.type == ethernet.IP_TYPE:
            log.debug('!LOG! S1 : RECEIVED: EtherType -> IP')

            # Extract IP Packet from Ethernet Frame
            ip_packet = etherFrame.payload

            # Routable?
            destination_ip = str(ip_packet.dstip)

            routable = False
            for netaddr in self.routing_table:
                destination_network = netaddr
                if IPAddress(destination_ip) in IPNetwork(destination_network):
                    log.debug('!LOG! S1 : PACKET IS ROUTABLE!')
                    routable = True
                    break

            if routable:
                # Destined for router
                if self.routing_table[str(destination_network)][
                        'RouterInterface'] == destination_ip:
                    if ip_packet.protocol == ipv4.ICMP_PROTOCOL:
                        log.debug('!LOG! S1 : ICMP ECHO -> ROUTER INTERFACE')
                        self.ICMP_Handler(etherFrame, packet_in)

                # Check if any there's any routable networks for the destination IP
                elif routable:
                    # Route the packet to it's respective ports
                    output_port = self.routing_table[destination_network][
                        'Port']

                    # ARP if host MAC Address is not present
                    if destination_ip not in self.arp_table:
                        # Push frame to buffer
                        self.buffer[destination_ip] = {
                            'IP_Packet': ip_packet,
                            'DestinationNetwork': destination_network
                        }

                        # Construct ARP Packet
                        arp_request = arp()
                        arp_request.opcode = arp.REQUEST
                        arp_request.protosrc = IPAddr(
                            self.routing_table[destination_network]
                            ['RouterInterface'])
                        arp_request.protodst = IPAddr(destination_ip)

                        arp_request.hwsrc = EthAddr(self.arp_table[
                            self.routing_table[destination_network]
                            ['RouterInterface']])
                        arp_request.hwdst = EthAddr('00:00:00:00:00:00')

                        ether = ethernet()
                        ether.type = ether.ARP_TYPE
                        ether.src = EthAddr(self.arp_table[self.routing_table[
                            destination_network]['RouterInterface']])
                        ether.dst = EthAddr('FF:FF:FF:FF:FF:FF')
                        ether.payload = arp_request
                        self.resend_packet(ether, output_port)

                    if destination_ip in self.arp_table:
                        etherFrame.src = EthAddr(self.arp_table[
                            self.routing_table[destination_network]
                            ['RouterInterface']])
                        etherFrame.dst = EthAddr(
                            self.arp_table[destination_ip])
                        self.resend_packet(etherFrame, output_port)
            # ICMP Destination Unreachable for non-routable networks
            else:
                log.debug('!LOG! S1 : PACKET IS NOT ROUTABLE!')
                ethernet_frame = etherFrame
                ip_packet = etherFrame.payload
                icmp_request_packet = ip_packet.payload
                icmp_echo_reply_packet = icmp()
                icmp_echo_reply_packet.code = 0
                icmp_echo_reply_packet.type = 3
                icmp_echo_reply_packet.payload = icmp_request_packet.payload

                ip = ipv4()
                ip.srcip = ip_packet.dstip
                ip.dstip = ip_packet.srcip
                ip.protocol = ipv4.ICMP_PROTOCOL
                ip.payload = icmp_echo_reply_packet

                ether = ethernet()
                ether.type = ethernet.IP_TYPE
                ether.src = ethernet_frame.dst
                ether.dst = ethernet_frame.src
                ether.payload = ip

                self.resend_packet(ether, packet_in.in_port)
                log.debug("!LOG! S1 : ICMP DESTINATION UNREACHABLE SENT")
Exemplo n.º 35
0
from pox.lib.packet.tcp import tcp
from pox.lib.revent.pretend import pretend
from pox.lib.packet.arp import arp
#from pox.lib.revent.Anti_broadcast import Anti_broadcast
from pox.lib.packet.icmp import icmp
import time

log = core.getLogger()

# We don't want to flood immediately when a switch connects.
FLOOD_DELAY = 5


special_sw=4
special_cache=9
CACHE_IP=IPAddr('172.16.0.1')
CACHE_MAC=EthAddr('00:22:19:12:37:1b')


class LearningSwitch (EventMixin):
  
  def __init__ (self, connection, transparent):
    # Switch we'll be adding L2 learning switch capabilities to
    self.connection = connection
    self.transparent = transparent

    # Our table
    self.macToPort = {}
      #USE THIS TABLE TO RECORD THE MUTICAST PACKET'S IP AND INPORT
    #our table match specified arp packet{srcMac:[dstip,port,time]}
    self.packetToPort={}
Exemplo n.º 36
0
    def connect(self, connection):
        if connection is None:
            self.log.warn("Can't connect to nothing")
            return
        if self.dpid is None:
            self.dpid = connection.dpid
        assert self.dpid == connection.dpid
        if self.ports is None:
            self.ports = connection.features.ports
        self.disconnect()
        self.connection = connection
        self._listeners = self.listenTo(connection)
        self._connected_at = time.time()

        label = dpid_to_str(connection.dpid)
        self.log = log.getChild(label)
        self.log.debug("Connect %s" % (connection, ))

        if self._id is None:
            if self.dpid not in switches_by_id and self.dpid <= 254:
                self._id = self.dpid
            else:
                self._id = TopoSwitch._next_id
                TopoSwitch._next_id += 1
            switches_by_id[self._id] = self

        self.network = IPAddr("10.%s.0.0" % (self._id, ))
        self.mac = dpid_to_mac(self.dpid)

        # Disable flooding
        con = connection
        log.debug("Disabling flooding for %i ports", len(con.ports))
        for p in con.ports.itervalues():
            if p.port_no >= of.OFPP_MAX: continue
            pm = of.ofp_port_mod(port_no=p.port_no,
                                 hw_addr=p.hw_addr,
                                 config=of.OFPPC_NO_FLOOD,
                                 mask=of.OFPPC_NO_FLOOD)
            con.send(pm)
        con.send(of.ofp_barrier_request())
        con.send(of.ofp_features_request())

        # Some of this is copied from DHCPD's __init__().
        self.send_table()

        def fix_addr(addr, backup):
            if addr is None: return None
            if addr is (): return IPAddr(backup)
            return IPAddr(addr)

        self.ip_addr = IPAddr("10.%s.0.1" % (self._id, ))
        #self.router_addr = self.ip_addr
        self.router_addr = None
        self.dns_addr = None  #fix_addr(dns_address, self.router_addr)

        self.subnet = IPAddr("255.0.0.0")
        self.pools = {}
        for p in connection.ports:
            if p < 0 or p >= of.OFPP_MAX: continue
            self.pools[p] = [
                IPAddr("10.%s.%s.%s" % (self._id, p, n))
                for n in range(1, 255)
            ]

        self.lease_time = 60 * 60  # An hour
        #TODO: Actually make them expire :)

        self.offers = {}  # Eth -> IP we offered
        self.leases = {}  # Eth -> IP we leased
Exemplo n.º 37
0
 def __str__(self):
     t = self.network.toUnsigned()
     t = (IPAddr(t | self.first), IPAddr(t | self.last))
     return "<Addresses from %s to %s>" % t
Exemplo n.º 38
0
    def _handle_PacketIn(self, event):
        dpid = event.connection.dpid
        inport = event.port
        packet = event.parsed
        if not packet.parsed:
            log.warning("%i %i ignoring unparsed packet", dpid, inport)
            return

        if dpid not in self.arpTable:
            # New switch -- create an empty table
            self.arpTable[dpid] = {}
            for fake in self.fakeways:
                self.arpTable[dpid][IPAddr(fake)] = Entry(
                    of.OFPP_NONE, dpid_to_mac(dpid))

        if packet.type == ethernet.LLDP_TYPE:
            # Ignore LLDP packets
            return

        if isinstance(packet.next, ipv4):
            log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip,
                      packet.next.dstip)

            # Send any waiting packets...
            self._send_lost_buffers(dpid, packet.next.srcip, packet.src,
                                    inport)

            # Learn or update port/MAC info
            if packet.next.srcip in self.arpTable[dpid]:
                if self.arpTable[dpid][packet.next.srcip] != (inport,
                                                              packet.src):
                    log.info("%i %i RE-learned %s", dpid, inport,
                             packet.next.srcip)
            else:
                log.debug("%i %i learned %s", dpid, inport,
                          str(packet.next.srcip))
            self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)

            # Try to forward
            dstaddr = packet.next.dstip
            if dstaddr in self.arpTable[dpid]:
                # We have info about what port to send it out on...

                prt = self.arpTable[dpid][dstaddr].port
                mac = self.arpTable[dpid][dstaddr].mac
                if prt == inport:
                    log.warning(
                        "%i %i not sending packet for %s back out of the " +
                        "input port" % (dpid, inport, str(dstaddr)))
                else:
                    log.debug(
                        "%i %i installing flow for %s => %s out port %i" %
                        (dpid, inport, packet.next.srcip, dstaddr, prt))

                    actions = []
                    actions.append(of.ofp_action_dl_addr.set_dst(mac))
                    actions.append(of.ofp_action_output(port=prt))
                    match = of.ofp_match.from_packet(packet, inport)
                    match.dl_src = None  # Wildcard source MAC

                    msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                          idle_timeout=FLOW_IDLE_TIMEOUT,
                                          hard_timeout=of.OFP_FLOW_PERMANENT,
                                          buffer_id=event.ofp.buffer_id,
                                          actions=actions,
                                          match=of.ofp_match.from_packet(
                                              packet, inport))
                    event.connection.send(msg.pack())
            elif self.arp_for_unknowns:
                # We don't know this destination.
                # First, we track this buffer so that we can try to resend it later
                # if we learn the destination, second we ARP for the destination,
                # which should ultimately result in it responding and us learning
                # where it is

                # Add to tracked buffers
                if (dpid, dstaddr) not in self.lost_buffers:
                    self.lost_buffers[(dpid, dstaddr)] = []
                bucket = self.lost_buffers[(dpid, dstaddr)]
                entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id,
                         inport)
                bucket.append(entry)
                while len(bucket) > MAX_BUFFERED_PER_IP:
                    del bucket[0]

                # Expire things from our outstanding ARP list...
                self.outstanding_arps = {
                    k: v
                    for k, v in self.outstanding_arps.iteritems()
                    if v > time.time()
                }

                # Check if we've already ARPed recently
                if (dpid, dstaddr) in self.outstanding_arps:
                    # Oop, we've already done this one recently.
                    return

                # And ARP...
                self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4

                r = arp()
                r.hwtype = r.HW_TYPE_ETHERNET
                r.prototype = r.PROTO_TYPE_IP
                r.hwlen = 6
                r.protolen = r.protolen
                r.opcode = r.REQUEST
                r.hwdst = ETHER_BROADCAST
                r.protodst = dstaddr
                r.hwsrc = packet.src
                r.protosrc = packet.next.srcip
                e = ethernet(type=ethernet.ARP_TYPE,
                             src=packet.src,
                             dst=ETHER_BROADCAST)
                e.set_payload(r)
                log.debug("%i %i ARPing for %s on behalf of %s" %
                          (dpid, inport, str(r.protodst), str(r.protosrc)))
                msg = of.ofp_packet_out()
                msg.data = e.pack()
                msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
                msg.in_port = inport
                event.connection.send(msg)

        elif isinstance(packet.next, arp):
            a = packet.next
            log.debug("%i %i ARP %s %s => %s", dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc),
                      str(a.protodst))

            if a.prototype == arp.PROTO_TYPE_IP:
                if a.hwtype == arp.HW_TYPE_ETHERNET:
                    if a.protosrc != 0:

                        # Learn or update port/MAC info
                        if a.protosrc in self.arpTable[dpid]:
                            if self.arpTable[dpid][a.protosrc] != (inport,
                                                                   packet.src):
                                log.info("%i %i RE-learned %s", dpid, inport,
                                         str(a.protosrc))
                        else:
                            log.debug("%i %i learned %s", dpid, inport,
                                      str(a.protosrc))
                        self.arpTable[dpid][a.protosrc] = Entry(
                            inport, packet.src)

                        # Send any waiting packets...
                        self._send_lost_buffers(dpid, a.protosrc, packet.src,
                                                inport)

                        if a.opcode == arp.REQUEST:
                            # Maybe we can answer

                            if a.protodst in self.arpTable[dpid]:
                                # We have an answer...

                                if not self.arpTable[dpid][
                                        a.protodst].isExpired():
                                    # .. and it's relatively current, so we'll reply ourselves

                                    r = arp()
                                    r.hwtype = a.hwtype
                                    r.prototype = a.prototype
                                    r.hwlen = a.hwlen
                                    r.protolen = a.protolen
                                    r.opcode = arp.REPLY
                                    r.hwdst = a.hwsrc
                                    r.protodst = a.protosrc
                                    r.protosrc = a.protodst
                                    r.hwsrc = self.arpTable[dpid][
                                        a.protodst].mac
                                    e = ethernet(type=packet.type,
                                                 src=dpid_to_mac(dpid),
                                                 dst=a.hwsrc)
                                    e.set_payload(r)
                                    log.debug("%i %i answering ARP for %s" %
                                              (dpid, inport, str(r.protosrc)))
                                    msg = of.ofp_packet_out()
                                    msg.data = e.pack()
                                    msg.actions.append(
                                        of.ofp_action_output(
                                            port=of.OFPP_IN_PORT))
                                    msg.in_port = inport
                                    event.connection.send(msg)
                                    return

            # Didn't know how to answer or otherwise handle this ARP, so just flood it
            log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' %
                  (a.opcode, )), str(a.protosrc), str(a.protodst)))

            msg = of.ofp_packet_out(
                in_port=inport,
                data=event.ofp,
                action=of.ofp_action_output(port=of.OFPP_FLOOD))
            event.connection.send(msg)
Exemplo n.º 39
0
 def subnet_mask(self):
     return IPAddr(((1 << self.network_size) - 1) << self.host_size)
Exemplo n.º 40
0
class atp_events(EventMixin):

	_eventMixin_events = set([addFlowEntry,])

	totalRequestCount = 0
	minPacketThreshold = 4
	minRequestThreshold = 2
	maxRequestThreshold = 15
	newIPTable = {}
	validIPTable = {IPAddr('10.0.0.2') : [0,0], IPAddr('10.0.0.3') : [0,0]}
	totalIP = len(newIPTable.keys()) + len(validIPTable.keys())
	regularIPCount = len(validIPTable)
	ddos = False

	def __init__(self):
		self.listenTo(core)
		self.requestPackets = 0
		self.dataPackets = 1	
		self.idleTimeoutAttacker = 30
		self.hardTimeoutAttacker = 3600
		self.regularTimeouts = [10,30]
		self.newTimeouts = [5,30]
		self.regReq = 3
	
	#Function to drop and block suspected IP.
	def dropIP (self,event):
		packet = event.parsed
		msg = of.ofp_flow_mod()
		
		msg.command = of.OFPFC_DELETE
		msg.match.nw_src = packet.next.srcip
		msg.match.nw_dst = packet.next.dstip
		msg.match.dl_type = ethernet.IP_TYPE
		event.connection.send(msg)

		msg = of.ofp_flow_mod()
		msg.priority = 1000
		msg.command = of.OFPFC_ADD
		msg.match.nw_src = packet.next.srcip
		msg.match.dl_type = ethernet.IP_TYPE
		msg.actions = []

		msg.idle_timeout = self.idleTimeoutAttacker
		msg.hard_timeout = self.hardTimeoutAttacker

		msg.flags=of.OFPFF_SEND_FLOW_REM
		
		event.connection.send(msg)

	#update minRequestThreshold and MaxRequestThreshold on timely manner.
	#Update avarage packet count as well. 
	def updateThreshold(self):
		self.totalIP = len(self.validIPTable.keys() + self.newIPTable.keys())

		for i in self.validIPTable.keys():
			self.validIPTable[i] = [0,0]
	
		if(len(self.newIPTable) > 15):
			self.ddos = True
			print("DDoS detected")
		else:
			self.ddos = False
		lmda = self.totalRequestCount/self.totalIP
		self.totalRequestCount = 0
		print(str(lmda) + " " + str(self.totalIP))


	#start when event goes up.
	def _handle_GoingUpEvent(self,event):
		self.listenTo(core.openflow)
		self.listenTo(core.adaptiveThreatPrevention)
		Timer(10,self.updateThreshold, recurring=True)

	#Handle PacketIn Requests coming from switches.
	def _handle_PacketIn(self,event):
		#parsing the pakcet to get necessary data.
		packet = event.parsed
		if isinstance(packet.next, ipv4):
			srcIP = packet.next.srcip

			if(srcIP == HOST_IP):
				self.raiseEvent(addFlowEntry,event,self.regularTimeouts)
				return

			if(srcIP in self.validIPTable.keys()):
				'''
				#src is registered as regular IP.
				1. Issue a normal entry.
				2. srcIP reqPacketcount ++.
				'''

				self.raiseEvent(addFlowEntry,event,self.regularTimeouts)
				self.totalRequestCount += 1
				self.validIPTable[srcIP][self.requestPackets] += 1

				'''
				#Check its reqPacket count.
				1. If reqPacket count > maxReqCount
					It's DoS attacker.
				'''

				if(self.validIPTable[srcIP][self.requestPackets] > self.maxRequestThreshold):
					#It will be considered as a DoS attacker.

					#check data packets.
					if(self.validIPTable[srcIP][self.dataPackets] < (3*self.validIPTable[srcIP][self.requestPackets])):
						#definately DoS attacker.

						#remove from database.
						del self.validIPTable[srcIP]

						#issues drop for long time.
						self.dropIP(event)

			else:
				if(srcIP not in self.newIPTable.keys()):
					self.newIPTable[srcIP] = [0,0]

				#issue new short entry.
				self.raiseEvent(addFlowEntry,event,self.newTimeouts)
				self.totalRequestCount += 1
				self.newIPTable[srcIP][self.requestPackets] += 1

				if(self.newIPTable[srcIP][self.requestPackets] > self.minRequestThreshold):

					#get status from the switch.

					if(self.newIPTable[srcIP][self.dataPackets] < (3*self.newIPTable[srcIP][self.requestPackets])):
						#Its a DDoS attacker.
						#issue drop for long time
						#remove from database.
						print("Dropped %s" % srcIP)
						del self.newIPTable[srcIP]
						self.dropIP(event)

					else:
						#add to reg database.
						self.validIPTable[srcIP] = self.newIPTable[srcIP]
						del self.newIPTable[srcIP]
		else :
			#Normal packets
			self.raiseEvent(addFlowEntry,event,self.regularTimeouts)		
		

	#Sending flow state messages to switch.
	def _handle_flowStatsEvent(self,event):
		for connection in core.openflow._connections.values():
			connection.send(of.ofp_stats_request(body=of.ofp_flow_stats_request()))

	#Handling flow states received event.
	def _handle_FlowStatsReceived(self,event):
		stats = flow_stats_to_list(event.stats)
		packet_count = 0
		flow_count = 0

		for f in event.stats:
			flow_count += 1
			packet_count += f.packet_count
		log.info("Flow: %s, Data packets: %s, Total Requestpackets: %s"
			% (flow_count,packet_count,self.totalRequestCount))
	
	#To get the packet count from a given IP address. 
	def _handle_FlowRemoved(self,event):
		msg = event.ofp
		f_ip = msg.match.nw_src
		
		if(f_ip in self.newIPTable.keys()):
			self.newIPTable[f_ip][self.dataPackets] = self.newIPTable[f_ip][self.dataPackets] + msg.packet_count
	
		elif (f_ip in self.validIPTable.keys()):
			self.validIPTable[f_ip][self.dataPackets] = self.validIPTable[f_ip][self.dataPackets] + msg.packet_count
Exemplo n.º 41
0
 def remove(self, item):
     item = IPAddr(item)
     if item not in self:
         raise RuntimeError("%s not in this pool" % (item, ))
     self.removed.add(item)
Exemplo n.º 42
0
import pox  
import pox.openflow.libopenflow_01 as of  
from pox.core import core  
from pox.lib.revent import *
from pox.lib.packet.ethernet import ethernet, ETHER_BROADCAST
from pox.lib.packet.ipv4 import ipv4
from pox.lib.packet.arp import arp
from pox.lib.addresses import IPAddr, EthAddr
from pox.lib.util import str_to_bool, dpid_to_str
from pox.lib.recoco import Timer


from pox.openflow.of_json import *
log = core.getLogger()

HOST_IP = IPAddr('10.0.0.5')

'''
This module has all the necessary event handling functions of ATP algorithm.
This modules does following tasks.

1. _handle_GoingUpEvent : This event will start listing to various events coming 
from openflow and pox core.

2. _handle_check_packetIn : This is check_packetIn event handler. This will handle check_packetIn
event raised by atp module. Basically, this will create entries in new and reg lists.

3. _handle_flowStatsEvent : This will handle flowStates events called by the atp module. This module will
send flow stats reqest to open flow switches.

4. _handle_FlowStatsReceived : This will handle FlowStatsReceived event raised by the open flow switch. 
Exemplo n.º 43
0
    def __init__(self,
                 ip_address="192.168.0.254",
                 router_address=(),
                 dns_address=(),
                 pool=None,
                 subnet=None,
                 install_flow=True,
                 dpid=None,
                 ports=None):
        def fix_addr(addr, backup):
            if addr is None: return None
            if addr is (): return IPAddr(backup)
            return IPAddr(addr)

        self._install_flow = install_flow

        self.ip_addr = IPAddr(ip_address)
        self.router_addr = fix_addr(router_address, ip_address)
        self.dns_addr = fix_addr(dns_address, self.router_addr)

        if dpid is None:
            self.dpid = None
        else:
            try:
                dpid = long(dpid)
            except:
                dpid = util.str_to_dpid(dpid)
            self.dpid = dpid

        if ports is None:
            self.ports = None
        else:
            self.ports = set(ports)
        if self.ports:
            assert self.dpid is not None  # Doesn't make sense
            self._servers.append(self)

        if pool is None:
            self.pool = [
                IPAddr("192.168.0." + str(x)) for x in range(100, 199)
            ]
            self.subnet = IPAddr(subnet or "255.255.255.0")
        else:
            self.pool = pool
            self.subnet = subnet
            if hasattr(pool, 'subnet_mask'):
                self.subnet = pool.subnet_mask
            if self.subnet is None:
                raise RuntimeError("You must specify a subnet mask or use a "
                                   "pool with a subnet hint")

        self.lease_time = 60 * 60  # An hour
        #TODO: Actually make them expire :)

        self.offers = {}  # Eth -> IP we offered
        self.leases = {}  # Eth -> IP we leased

        if self.ip_addr in self.pool:
            log.debug("Removing my own IP (%s) from address pool",
                      self.ip_addr)
            self.pool.remove(self.ip_addr)

        core.openflow.addListeners(self)
Exemplo n.º 44
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)
Exemplo n.º 45
0
 def fix_addr(addr, backup):
     if addr is None: return None
     if addr is (): return IPAddr(backup)
     return IPAddr(addr)
Exemplo n.º 46
0
class SimpleAddressPool(AddressPool):
    """
  Simple AddressPool for simple subnet based pools.
  """
    def __init__(self,
                 network="192.168.0.0/24",
                 first=1,
                 last=None,
                 count=None):
        """
    Simple subnet-based address pool

    Allocates count IP addresses out of network/network_size, starting
    with the first'th.  You may specify the end of the range with either
    last (to specify the last'th address to use) or count to specify the
    number to use.  If both are None, use up to the end of all
    legal addresses.

    Example for all of 192.168.x.x/16:
      SimpleAddressPool("192.168.0.0/16", 1, 65534)
    """
        network, network_size = parse_cidr(network)

        self.first = first
        self.network_size = network_size
        self.host_size = 32 - network_size
        self.network = IPAddr(network)

        if last is None and count is None:
            self.last = (1 << self.host_size) - 2
        elif last is not None:
            self.last = last
        elif count is not None:
            self.last = self.first + count - 1
        else:
            raise RuntimeError("Cannot specify both last and count")

        self.removed = set()

        if self.count <= 0: raise RuntimeError("Bad first/last range")
        if first == 0: raise RuntimeError("Can't allocate 0th address")
        if self.host_size < 0 or self.host_size > 32:
            raise RuntimeError("Bad network")
        if IPAddr(self.last | self.network.toUnsigned()) not in self:
            raise RuntimeError("Bad first/last range")

    def __repr__(self):
        return str(self)

    def __str__(self):
        t = self.network.toUnsigned()
        t = (IPAddr(t | self.first), IPAddr(t | self.last))
        return "<Addresses from %s to %s>" % t

    @property
    def subnet_mask(self):
        return IPAddr(((1 << self.network_size) - 1) << self.host_size)

    @property
    def count(self):
        return self.last - self.first + 1

    def __contains__(self, item):
        item = IPAddr(item)
        if item in self.removed: return False
        n = item.toUnsigned()
        mask = (1 << self.host_size) - 1
        nm = (n & mask) | self.network.toUnsigned()
        if nm != n: return False
        if (n & mask) == mask: return False
        if (n & mask) < self.first: return False
        if (n & mask) > self.last: return False
        return True

    def append(self, item):
        item = IPAddr(item)
        if item not in self.removed:
            if item in self:
                raise RuntimeError("%s is already in this pool" % (item, ))
            else:
                raise RuntimeError("%s does not belong in this pool" %
                                   (item, ))
        self.removed.remove(item)

    def remove(self, item):
        item = IPAddr(item)
        if item not in self:
            raise RuntimeError("%s not in this pool" % (item, ))
        self.removed.add(item)

    def __len__(self):
        return (self.last - self.first + 1) - len(self.removed)

    def __getitem__(self, index):
        if index < 0:
            raise RuntimeError("Negative indices not allowed")
        if index >= len(self):
            raise IndexError("Item does not exist")
        c = self.first

        # Use a heuristic to find the first element faster (we hope)
        # Note this means that removing items changes the order of
        # our "list".
        c += len(self.removed)
        while c > self.last:
            c -= self.count

        while True:
            addr = IPAddr(c | self.network.toUnsigned())
            if addr not in self.removed:
                assert addr in self
                index -= 1
                if index < 0: return addr
            c += 1
            if c > self.last: c -= self.count
Exemplo n.º 47
0
def glob_gateways_obj():
    buffer = []
    for gw in glob_gateways:
        buffer.append(IPAddr(gw))
    return buffer