Untitled
unknown
plain_text
a year ago
13 kB
7
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