Untitled
unknown
plain_text
5 months ago
13 kB
6
Indexable
# Lab5 Skeleton from pox.core import core import pox.openflow.libopenflow_01 as of import pox.lib.packet as pkt from time import time import ipaddress log = core.getLogger() class Routing(object): # ROUTING RULES: # RULE 1: ICMP traffic forwarded only between Student Housing LAN, Faculty LAN, and IT Department subnets (or between devices on the same subnet) # RULE 2: TCP traffic forwarded only between the University Data Center, IT Department, Faculty LAN, Student Housing LAN, trustedPC, or between devices on the same subnet, however only the Faculty LAN can access the exam server # RULE 3: UDP traffic is forwarded only between the University Data Center, IT Department, Faculty LAN, Student Housing LAN, or between devices on the same subnet # RULE 4: All other traffic should be dropped def __init__(self, connection): # Keep track of the connection to the switch so that we can # send it messages! self.connection = connection # This binds our PacketIn event listener connection.addListeners(self) # define subnets self.subnets = { 'faculty': ipaddress.ip_network('10.0.1.0/24'), 'student': ipaddress.ip_network('10.0.2.0/24'), 'it_dept': ipaddress.ip_network('10.40.3.0/24'), 'exam_server': ipaddress.ip_network('10.100.100.2/32'), 'data_center': ipaddress.ip_network('10.100.100.0/24'), 'trusted_pc': ipaddress.ip_network('10.0.203.6/32'), 'guest1': ipaddress.ip_network('10.0.198.6/32'), 'guest2': ipaddress.ip_network('10.0.198.10/32') # , # add guest1 and guest2 } # subnet to switch map self.subnet_switch = { 'core': 1, 'faculty': 2, 'student': 3, 'it_dept': 4, 'data_center': 5 } # return what subnet an IP is in def get_subnet(self, ip): ip = ipaddress.ip_address(ip) print("GET_SUBNET IP:", ip) # iterate across subnets and submit name if there's an IP match' for name, subnet in self.subnets.items(): if ip in subnet: print("SUBNET FOUND:", name) return name return None # check if two IP in the same subnet def same_subnet(self, ip1, ip2): ip1 = ipaddress.ip_address(ip1) ip2 = ipaddress.ip_address(ip2) print("SAME_SUBNET:", ip1, " ", ip2) for subnet in self.subnets.values(): if ip1 in subnet and ip2 in subnet: return True return False def do_routing(self, packet, packet_in, port_on_switch, switch_id): # port_on_switch - the port on which this packet was received # switch_id - the switch which received this packet] def accept(out_port, idle_timeout=30): msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = idle_timeout msg.hard_timeout = 300 msg.priority = 1 if packet_in.buffer_id != of.NO_BUFFER and packet_in.buffer_id is not None: msg.buffer_id = packet_in.buffer_id else: msg.data = packet_in # check if there is a list of ports, if there is, we assign multiple actions if isinstance(out_port, list): for port in out_port: msg_copy = msg msg_copy.match = of.ofp_match.from_packet(packet) msg_copy.idle_timeout = idle_timeout msg_copy.hard_timeout = 300 msg_copy.priority = 1 if packet_in.buffer_id != of.NO_BUFFER and packet_in.buffer_id is not None: msg_copy.buffer_id = packet_in.buffer_id else: msg_copy.data = packet_in msg_copy.actions.append(of.ofp_action_output(port=port)) self.connection.send(msg_copy) else: msg.actions.append(of.ofp_action_output(port=out_port)) self.connection.send(msg) print("Packet Accepted") def drop(): msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet_in) msg.idle_timeout = 45 msg.hard_timeout = 600 self.connection.send(msg) print("Packet Dropped - Flow Table Installed on Switches") # PACKET HANDLING BEGINS if packet.find('arp') is not None: msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = 30 msg.hard_timeout = 300 msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD)) self.connection.send(msg) return # print("PACKET BEGINS") # RULE 1: determine if ICMP print("NOT ARP PACKET") print(packet) ip_packet = packet.find('ipv4') if not ip_packet: return src_ip = ip_packet.srcip dst_ip = ip_packet.dstip src_subnet = self.get_subnet(src_ip) dst_subnet = self.get_subnet(dst_ip) print(ip_packet) # switch_ID to check what switch I'm on # if destination is this IP # return this port, or return that port, or return that port # do_routing contains accept and drop and 4 rules # 2 helper functions: 1 of them is same_subnet, and a # rule 1: ICMP # GOAL: if/else tree individually handling ICMP, TCP, UDP # this tree will determine source and destination ports # it will do this based on a source and destination IP to determine a given subnet # #define subnets # self.subnets = { # 'faculty': ipaddress.ip_network('10.0.1.0/24'), # 'student': ipaddress.ip_network('10.0.2.0/24'), # 'it_dept': ipaddress.ip_network('10.40.3.0/24'), # 'exam_server': ipaddress.ip_network('10.100.100.2/32'), # 'data_center': ipaddress.ip_network('10.100.100.0/24'), # 'trusted_pc': ipaddress.ip_network('10.0.203.6/32') # } # switch_id # port_on_switch if ip_packet.protocol == 1: # 1 is ICMP #if an ICMP packet is going to switch 1, it means it must be trying to go to an external (non-source subnet) #therefor, i only need to check the case for external subnets - in this case faculty, student, it_dept #only ICMP packets from the faculty, student, and IT would get here anyway if (switch_id == 's1'): #core switch if (dst_subnet == 'faculty' and (port_on_switch == 3 or port_on_switch == 2 or port_on_switch == 4)): dest_port = 2 accept(dest_port) return if (dst_subnet == 'student' and (port_on_switch == 3 or port_on_switch == 2 or port_on_switch == 4)): dest_port = 3 accept(dest_port) return if (dst_subnet == 'it_dept' and (port_on_switch == 3 or port_on_switch == 2 or port_on_switch == 4)): dest_port = 4 accept(dest_port) return drop() return if (switch_id == 's2'): #faculty switch if (port_on_switch == 1): #means it is coming from subnet #if going to same subnet, route there if (dst_subnet == 'faculty'): if (dst_ip == '10.0.1.2'): dest_port = 3 elif (dst_ip == '10.0.1.3'): dest_port = 4 elif (dst_ip == '10.0.1.4'): dest_port = 5 else: drop() return accept(dest_port) return #otherwise, must either go to student or it_dept to be externally routed to s1 if (dst_subnet == 'student' or dst_subnet == 'it_dept'): dest_port = 1 accept(dest_port) return drop() return #means it is coming from s1 elif (port_on_switch == 2): #route internally or drop if (dst_subnet == 'faculty'): if (dst_ip == '10.0.1.2'): dest_port = 3 elif (dst_ip == '10.0.1.3'): dest_port = 4 elif (dst_ip == '10.0.1.4'): dest_port = 5 else: drop() return accept(dest_port) return drop() return if (switch_id == 's3'): #student switch #means it is coming from subnet if (port_on_switch == 1): if (dst_subnet == 'student'): if (dst_ip == '10.0.2.2'): dest_port = 4 if (dst_ip == '10.0.2.3'): dest_port = 6 if (dst_ip == '10.0.2.40'): dest_port = 5 accept(dest_port) return #only externally route if it_dept or faculty elif (dst_subnet == 'it_dept' or dst_subnet == 'faculty'): dest_port = 1 accept(dest_port) return #3 means its coming from s1 if (port_on_switch == 3): if (dst_subnet == 'student'): if (dst_ip == '10.0.2.2'): dest_port = 4 if (dst_ip == '10.0.2.3'): dest_port = 6 if (dst_ip == '10.0.2.40'): dest_port = 5 accept(dest_port) return drop() return if (switch_id == 's4'): #it switch if (port_on_switch == 1): if (dst_subnet == 'it_dept'): if (dst_ip == '10.40.3.30'): dest_port = 5 if (dst_ip == '10.40.3.254'): dest_port = 6 accept(dest_port) return elif (dst_subnet == 'faculty' or dst_subnet == 'student') #coming from s1 if (port_on_switch == 4): if(dst_subnet == 'it_dept'): if(dst_ip == '10.40.3.30'): dest_port = 5 if (dst_ip == '10.40.3.254'): dest_port = 6 accept(dest_port) return drop() return if (switch_id == 's5'): #datacenter switch if (port_on_switch == 5): #coming from s1 #should not have any input from s1 ever drop() return if (port_on_switch == 1): #coming from subnet if(dst_subnet == 'data_center' or dst_subnet == 'exam_server') if(dst_ip == '10.100.100.2'): dest_port = 6 if(dst_ip == '10.100.100.20'): dest_port = 7 if(dst_ip == '10.100.100.56'): dest=port = 8 accept(dest_port) return #later implement rules 2 and 3 print("PACKET TYPE INVALID") # rule 4 drop() def _handle_PacketIn(self, event): """ Handles packet in messages from the switch. """ packet = event.parsed # This is the parsed packet data. if not packet.parsed: log.warning("Ignoring incomplete packet") return packet_in = event.ofp # The actual ofp_packet_in message. self.do_routing(packet, packet_in, event.port, event.dpid) def launch(): """ Starts the component """ def start_switch(event): log.debug("Controlling %s" % (event.connection,)) Routing(event.connection) core.openflow.addListenerByName("ConnectionUp", start_switch)
Editor is loading...
Leave a Comment