blockchain-access-control

git clone git://git.codymlewis.com/blockchain-access-control.git
Log | Files | Refs | README

network_controller.py (3470B)


      1 #!/usr/bin/env python3
      2 # -*- coding: utf-8 -*-
      3 
      4 '''
      5 Controller for the SDN
      6 '''
      7 
      8 import sys
      9 
     10 import pox3.lib.packet as pac
     11 from pox3.boot import boot
     12 from pox3.core import core
     13 
     14 import pox3.openflow.libopenflow_01 as of
     15 
     16 from Blockchain import Blockchain
     17 
     18 
     19 if __name__ != "__main__":
     20     LOG = core.getLogger()
     21 
     22 
     23 class Controller(object):
     24     '''A controller that can detect attacks or generate data on flows'''
     25     def __init__(self, connection):
     26         self.connection = connection
     27         connection.addListeners(self)
     28         self.mac_to_port = {}
     29         self.blockchain = Blockchain()
     30 
     31     def resend_packet(self, packet_in, out_port):
     32         '''
     33         Pass the packet from this switch on to the next port
     34         :param packet_in: Packet to pass
     35         :param out_port: Port to pass to
     36         '''
     37         msg = of.ofp_packet_out()
     38         msg.data = packet_in
     39         action = of.ofp_action_output(port=out_port)
     40         msg.actions.append(action)
     41         self.connection.send(msg)
     42 
     43     def flow_is_allowed(self, flow):
     44         for b in self.blockchain.chain:
     45             if b.transactions == flow:
     46                 return True
     47         return False
     48 
     49     def act_like_switch(self, packet, packet_in):
     50         '''
     51         Act like a switch by learning the mappings between the MACs and ports
     52         :param packet The packet processed at this point
     53         :param packet_in The packet to pass
     54         '''
     55         pl = packet.payload
     56         if len(packet_in.data) == packet_in.total_len:
     57             self.mac_to_port[packet.src] = packet_in.in_port
     58             if isinstance(pl, pac.ipv4):
     59                 if pl.protocol == pac.ipv4.TCP_PROTOCOL:
     60                     src = pl.srcip
     61                     dst = pl.dstip
     62                     flow = f"{src} -> {dst}"
     63                     tcp_pl = pl.next.payload.decode()
     64                     if tcp_pl.find("GET") == 0:
     65                         route = tcp_pl[4:tcp_pl.find("HTTP") - 1]
     66                         if "data" in route:
     67                             if not self.flow_is_allowed(flow):
     68                                 LOG.debug("Flow %s is not allowed", flow)
     69                                 return
     70                         elif "add" in route:
     71                             if self.blockchain.mine(flow):
     72                                 LOG.debug("Added acceptable flow %s", flow)
     73                             else:
     74                                 return
     75             if self.mac_to_port.get(packet.dst):
     76                 self.resend_packet(packet_in, self.mac_to_port[packet.dst])
     77             else:
     78                 self.resend_packet(packet_in, of.OFPP_ALL)
     79 
     80     def _handle_PacketIn(self, event):
     81         '''
     82         Handle a packet in
     83         :param event Event that triggered this
     84         '''
     85         packet = event.parsed
     86         if not packet.parsed:
     87             LOG.warning("Ignoring incomplete packet")
     88         else:
     89             packet_in = event.ofp
     90             self.act_like_switch(packet, packet_in)
     91 
     92 
     93 def launch():
     94     '''
     95     Launch this controller
     96     '''
     97     def start_switch(event):
     98         '''
     99         Start up the switch
    100         :param event Event that triggered this
    101         '''
    102         LOG.debug("Controlling %s with this", (event.connection,))
    103         Controller(event.connection,)
    104     core.openflow.addListenerByName("ConnectionUp", start_switch)
    105 
    106 
    107 if __name__ == '__main__':
    108     boot(
    109         (["log.level", "--DEBUG"] if "--debug" in sys.argv else []) +
    110         ["network_controller"]
    111     )