def __reset_switch(self,dp): assert (dp is not None),"Datapath Object is Not set. " ofproto = dp.ofproto parser = dp.ofproto_parser flow_mod = dp.ofproto_parser.OFPFlowMod(dp,0,0,0, ofproto.OFPFC_DELETE, 0,0,1, ofproto.OFPCML_NO_BUFFER, ofproto.OFPP_ANY, ofproto.OFPG_ANY, ) logging.info("Deleting all Flow Table entries..." ) dp.send_msg(flow_mod) # install table-miss flow entry # # We specify NO BUFFER to max_len of the output action due to # OVS bug. At this moment, if we specify a lesser number, e.g., # 128, OVS will send Packet-In with invalid buffer_id and # truncated packet data. In that case, we cannot output packets # correctly. const = Construct() actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)] const.add_flow(datapath = dp, actions = actions, priority=0) actions = [parser.OFPActionOutput(ofproto.OFPPC_NO_FWD)] const.add_flow(datapath = dp, actions = actions, priority=10000, eth_type=ETH_TYPE_LLDP)
def __reset_switch(self, dp): assert (dp is not None), "Datapath Object is Not set. " ofproto = dp.ofproto parser = dp.ofproto_parser flow_mod = dp.ofproto_parser.OFPFlowMod( dp, 0, 0, 0, ofproto.OFPFC_DELETE, 0, 0, 1, ofproto.OFPCML_NO_BUFFER, ofproto.OFPP_ANY, ofproto.OFPG_ANY, ) logging.info("deleting all flow table entries in the tables :") dp.send_msg(flow_mod) const = Construct() actions = [ parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER) ] const.add_flow(datapath=dp, actions=actions, priority=0) actions = [parser.OFPActionOutput(ofproto.OFPPC_NO_FWD)] const.add_flow(datapath=dp, actions=actions, priority=10000, eth_type=ETH_TYPE_LLDP)
def __reset_switch(self,dp): assert (dp is not None),"Datapath Object is Not set. " ofproto = dp.ofproto parser = dp.ofproto_parser flow_mod = dp.ofproto_parser.OFPFlowMod(dp,0,0,0, ofproto.OFPFC_DELETE, 0,0,1, ofproto.OFPCML_NO_BUFFER, ofproto.OFPP_ANY, ofproto.OFPG_ANY, ) logging.info("deleting all flow table entries in the tables :" ) dp.send_msg(flow_mod) const = Construct() actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)] const.add_flow(datapath = dp, actions = actions, priority=0) actions = [parser.OFPActionOutput(ofproto.OFPPC_NO_FWD)] const.add_flow(datapath = dp, actions = actions, priority=10000, eth_type=ETH_TYPE_LLDP)
def __reset_switch(self, dp): assert (dp is not None), "Datapath Object is Not set. " ofproto = dp.ofproto parser = dp.ofproto_parser flow_mod = dp.ofproto_parser.OFPFlowMod( dp, 0, 0, 0, ofproto.OFPFC_DELETE, 0, 0, 1, ofproto.OFPCML_NO_BUFFER, ofproto.OFPP_ANY, ofproto.OFPG_ANY, ) logging.info("Deleting all Flow Table entries...") dp.send_msg(flow_mod) # install table-miss flow entry # # We specify NO BUFFER to max_len of the output action due to # OVS bug. At this moment, if we specify a lesser number, e.g., # 128, OVS will send Packet-In with invalid buffer_id and # truncated packet data. In that case, we cannot output packets # correctly. const = Construct() actions = [ parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER) ] const.add_flow(datapath=dp, actions=actions, priority=0) actions = [parser.OFPActionOutput(ofproto.OFPPC_NO_FWD)] const.add_flow(datapath=dp, actions=actions, priority=10000, eth_type=ETH_TYPE_LLDP)
class SecureFirewall(app_manager.RyuApp): OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] inner_policy = {} sendpkt = SendPacket() flow = Construct() current_time = Incoming_packet_time() def __init__(self, *args, **kwargs): super(SecureFirewall, self).__init__(*args, **kwargs) self.mac_to_port = {} parser = parse_firewall() self.inner_policy = parser.parse() self.logger.info("dict is ready") @set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER) def handler_datapath(self, ev): SwitchInfo(ev) """ Handles incoming packets. Decode them and check for suitable Firewall Rules. """ @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] try: pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] ethtype = eth.ethertype out_port = self.port_learn(datapath, eth, in_port) action_fwd_to_out_port = [parser.OFPActionOutput(out_port)] action_drop = [parser.OFPActionOutput(ofproto.OFPPC_NO_FWD)] actions_default = action_fwd_to_out_port if (out_port != ofproto.OFPP_FLOOD) and (ethtype == ETH_TYPE_IP): ipo = pkt.get_protocols(ipv4.ipv4)[0] # Check for ICMP if (ipo.proto == IPPROTO_ICMP): flag1 = 0 icmpob = pkt.get_protocol(icmp.icmp) # Check if this is PING if ((icmpob.type == ICMP_PING) and self.inner_policy.has_key(ipo.src)): temp = self.inner_policy.get(ipo.src) for i in range(0, len(temp)): if temp[i][0] == ipo.dst: xyz = temp[i] if ((xyz[1] == 'ICMP') and (xyz[4] == 'PING') and (xyz[5] == 'ALLOW')): flag1 = 1 actions_default = action_fwd_to_out_port self.logger.info( "%s -> %s : PING PACKET ALLOWED" % (ipo.src, ipo.dst)) self.flow.add_flow(datapath=datapath, actions=actions_default, priority=1001, in_port=in_port, eth_type=ETH_TYPE_IP, ip_proto=IPPROTO_ICMP, icmpv4_type=ICMP_PING, ipv4_src=ipo.src, ipv4_dst=ipo.dst) break # Check if it is PONG elif ((icmpob.type == ICMP_PONG) and (self.inner_policy.has_key(ipo.src))): temp = self.inner_policy.get(ipo.src) for i in range(0, len(temp)): if temp[i][0] == ipo.dst: xyz = temp[i] if ((xyz[1] == 'ICMP') and (xyz[4] == 'PONG') and (xyz[5] == 'ALLOW')): flag1 = 1 actions_default = action_fwd_to_out_port self.logger.info( "%s -> %s : PONG PACKET ALLOWED" % (ipo.src, ipo.dst)) self.flow.add_flow(datapath=datapath, actions=actions_default, priority=1001, in_port=in_port, eth_type=ETH_TYPE_IP, ip_proto=IPPROTO_ICMP, icmpv4_type=ICMP_PONG, ipv4_src=ipo.src, ipv4_dst=ipo.dst) self.current_time.time() self.logger.info("\n") break # What if no match found ? if (flag1 == 0): actions_default = action_drop self.logger.info("%s -> %s : ICMP BLOCKED" % (ipo.src, ipo.dst)) self.flow.add_flow(datapath=datapath, actions=actions_default, priority=1001, in_port=in_port, eth_type=ETH_TYPE_IP, ip_proto=IPPROTO_ICMP, icmpv4_type=icmpob.type, ipv4_src=ipo.src, ipv4_dst=ipo.dst) # Check for TCP elif (ipo.proto == IPPROTO_TCP): tcpo = pkt.get_protocol(tcp.tcp) flag2 = 0 # TCP packet and Firewall rule if self.inner_policy.has_key(ipo.src): temp = self.inner_policy.get(ipo.src) for i in range(0, len(temp)): if ((temp[i][0] == ipo.dst) and (temp[i][1] == 'TCP') and (int(temp[i][2]) == tcpo.src_port) and (int(temp[i][3]) == tcpo.dst_port) and (temp[i][4].upper() == 'ANY') and (temp[i][5] == 'ALLOW')): flag2 = 1 actions_default = action_fwd_to_out_port self.logger.info( "%s -> %s : TCP PACKET ALLOWED" % (ipo.src, ipo.dst)) self.current_time.time() self.logger.info("\n") break elif (((tcpo.bits & TCP_ACK) == TCP_ACK) and (temp[i][0] == ipo.dst) and (temp[i][1] == 'TCP') and (int(temp[i][2]) == tcpo.src_port) and (int(temp[i][3]) == tcpo.dst_port) and (temp[i][4].upper() == 'ACK') and (temp[i][5] == 'ALLOW')): flag2 = 1 actions_default = action_fwd_to_out_port self.logger.info( "%s -> %s : TCP PACKET ALLOWED" % (ipo.src, ipo.dst)) self.current_time.time() self.logger.info("\n") break # If match found then add Flow Table rules if (flag2 != 0): self.flow.add_flow(datapath=datapath, actions=actions_default, priority=1001, in_port=in_port, eth_type=ETH_TYPE_IP, ip_proto=IPPROTO_TCP, ipv4_src=ipo.src, ipv4_dst=ipo.dst, tcp_src=tcpo.src_port, tcp_dst=tcpo.dst_port) # What if no match found ? else: actions_default = action_drop self.logger.info("%s -> %s : BLOCKED" % (ipo.src, ipo.dst)) # Check for UDP elif (ipo.proto == IPPROTO_UDP): udpo = pkt.get_protocol(udp.udp) flag3 = 0 if self.inner_policy.has_key(ipo.src): temp3 = self.inner_policy.get(ipo.src) for i in range(0, len(temp3)): if temp3[i][0] == ipo.dst: xyz = temp3[i] if ((xyz[1] == 'UDP') and (int(xyz[2]) == udpo.src_port) and (int(xyz[3]) == udpo.dst_port) and (xyz[5] == 'ALLOW')): flag3 = 1 actions_default = action_fwd_to_out_port self.logger.info( "%s -> %s: UDP ALLOWED" % (ipo.src, ipo.dst)) self.flow.add_flow(datapath=datapath, actions=actions_default, priority=1001, in_port=in_port, eth_type=ETH_TYPE_IP, ip_proto=IPPROTO_UDP, ipv4_src=ipo.src, ipv4_dst=ipo.dst, udp_src=udpo.src_port, udp_dst=udpo.dst_port) self.current_time.time() self.logger.info("\n") break # What if no match found ? if (flag3 == 0): actions_default = action_drop self.logger.info("%s -> %s : BLOCKED" % (ipo.src, ipo.dst)) self.flow.add_flow(datapath=datapath, actions=actions_default, priority=1001, in_port=in_port, eth_type=ETH_TYPE_IP, ip_proto=IPPROTO_UDP, ipv4_src=ipo.src, ipv4_dst=ipo.dst, udp_src=udpo.src_port, udp_dst=udpo.dst_port) # If not ICMP, TCP or UDP then drop..! else: self.logger.info("Wrong IP protocol found") actions_default = action_drop # Handling ARP Rules. elif (ethtype == ETH_TYPE_ARP): self.arp_handling(datapath, out_port, eth, in_port) actions_default = action_fwd_to_out_port # If packet is not IP or ARP then drop..! else: actions_default = action_drop except Exception as err: self.logger.info("MYERROR: %s", err.message) action_drop = [parser.OFPActionOutput(ofproto.OFPPC_NO_FWD)] actions_default = action_drop finally: self.sendpkt.send(datapath, msg, in_port, actions_default) """ Add ARP rules on Flow Tables """ def arp_handling(self, datapath, out_port, eth_obj, in_port): if (out_port != datapath.ofproto.OFPP_FLOOD): actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] self.flow.add_flow(datapath=datapath, actions=actions, priority=1000, in_port=in_port, eth_type=ETH_TYPE_ARP, eth_src=eth_obj.src, eth_dst=eth_obj.dst) """ Learn Switch port associated with a MAC address here """ def port_learn(self, datapath, eth_obj, in_port): try: self.mac_to_port.setdefault(datapath.id, { '90:e2:ba:1c:55:54': 1, '90:e2:ba:1c:55:55': 2 }) self.mac_to_port[datapath.id][eth_obj.src] = in_port if (eth_obj.ethertype == ETH_TYPE_IP) or (eth_obj.ethertype == ETH_TYPE_ARP): if eth_obj.dst in self.mac_to_port[datapath.id]: out_port = self.mac_to_port[datapath.id][eth_obj.dst] else: out_port = datapath.ofproto.OFPP_FLOOD except Exception as err: self.info(err.message) out_port = datapath.ofproto.OFPP_FLOOD finally: return out_port
class SecureFirewall(app_manager.RyuApp): OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] inner_policy = {} icmp_conn_track = {} tcp_conn_track = {} udp_conn_track = {} sendpkt = SendPacket() flow = Construct() track = TrackConnection() def __init__(self, *args, **kwargs): super(SecureFirewall, self).__init__(*args, **kwargs) self.mac_to_port = {} parser = parse_firewall() self.inner_policy = parser.parse() self.logger.info("dict is ready") @set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER) def handler_datapath(self, ev): SwitchInfo(ev) """ Handles incoming packets. Decode them and check for suitable Firewall Rules. """ @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] try: pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] ethtype = eth.ethertype out_port = self.port_learn(datapath, eth, in_port) action_fwd_to_out_port = [parser.OFPActionOutput(out_port)] action_drop = [parser.OFPActionOutput(ofproto.OFPPC_NO_FWD)] action_fwd_to_in_port = [parser.OFPActionOutput(in_port)] actions_default = action_fwd_to_out_port if (out_port != ofproto.OFPP_FLOOD) and (ethtype == ETH_TYPE_IP): ipo = pkt.get_protocols(ipv4.ipv4)[0] #Check for ICMP if (ipo.proto == IPPROTO_ICMP): icmpob = pkt.get_protocol(icmp.icmp) flag1 = 0 #Check if this is PING or PONG if ((icmpob.type == ICMP_PING) and self.inner_policy.has_key(ipo.src)): temp = self.inner_policy.get(ipo.src) for i in range(0, len(temp)): if temp[i][0] == ipo.dst: xyz = temp[i] if ((xyz[1] == 'ICMP') and (xyz[5] == 'ALLOW')): flag1 = 1 actions_default = action_fwd_to_out_port self.icmp_conn_track = self.track.conn_track_dict( self.icmp_conn_track, ipo.src, ipo.dst, "PING", "PONG", xyz[5], 2) self.flow.add_flow(datapath=datapath, actions=actions_default, priority=1001, in_port=in_port, eth_type=ETH_TYPE_IP, ip_proto=IPPROTO_ICMP, icmpv4_type=ICMP_PING, ipv4_src=ipo.src, ipv4_dst=ipo.dst) self.flow.add_flow( datapath=datapath, actions=action_fwd_to_in_port, priority=1000, in_port=out_port, eth_type=ETH_TYPE_IP, ip_proto=IPPROTO_ICMP, icmpv4_type=ICMP_PONG, ipv4_src=ipo.dst, ipv4_dst=ipo.src) break if (flag1 == 0): actions_default = action_drop self.flow.add_flow(datapath=datapath, actions=actions_default, priority=1001, in_port=in_port, eth_type=ETH_TYPE_IP, ip_proto=IPPROTO_ICMP, icmpv4_type=icmpob.type, ipv4_src=ipo.src, ipv4_dst=ipo.dst) #Check for TCP. elif (ipo.proto == IPPROTO_TCP): tcpo = pkt.get_protocol(tcp.tcp) flag2 = 0 # TCP SYN packet if (((tcpo.bits & TCP_SYN) == TCP_SYN) & ((tcpo.bits & TCP_BOGUS_FLAGS) == 0x00)): if self.inner_policy.has_key(ipo.src): temp = self.inner_policy.get(ipo.src) for i in range(0, len(temp)): if ((temp[i][0] == ipo.dst) and (temp[i][1] == 'TCP') and (int(temp[i][2]) == tcpo.src_port) and (int(temp[i][3]) == tcpo.dst_port) and (temp[i][5] == 'ALLOW')): flag2 = 1 actions_default = action_fwd_to_out_port self.tcp_conn_track = self.track.conn_track_dict( self.tcp_conn_track, ipo.src, ipo.dst, tcpo.src_port, tcpo.dst_port, tcpo.seq, 1) self.flow.add_flow(datapath=datapath, actions=actions_default, priority=1001, in_port=in_port, eth_type=ETH_TYPE_IP, ip_proto=IPPROTO_TCP, ipv4_src=ipo.src, ipv4_dst=ipo.dst, tcp_src=tcpo.src_port, tcp_dst=tcpo.dst_port) break # TCP SYN ACK packet elif ((tcpo.bits & TCP_SYN_ACK) == TCP_SYN_ACK): if self.tcp_conn_track.has_key(ipo.dst): temp2 = self.tcp_conn_track.get(ipo.dst) for i in range(0, len(temp2)): if ((temp2[i][0] == ipo.src) and (int(temp2[i][1]) == tcpo.dst_port) and (int(temp2[i][2]) == tcpo.src_port)): flag2 = 1 actions_default = action_fwd_to_out_port self.tcp_conn_track = self.track.conn_track_dict( self.tcp_conn_track, ipo.src, ipo.dst, tcpo.src_port, tcpo.dst_port, tcpo.seq, 1) self.flow.add_flow(datapath=datapath, actions=actions_default, priority=1001, in_port=in_port, eth_type=ETH_TYPE_IP, ip_proto=IPPROTO_TCP, ipv4_src=ipo.src, ipv4_dst=ipo.dst, tcp_src=tcpo.src_port, tcp_dst=tcpo.dst_port) break # All remaining TCP packets, like, ACK, PUSH, FIN etc. else: if self.tcp_conn_track.has_key(ipo.src): temp3 = self.tcp_conn_track.get(ipo.src) for i in range(0, len(temp3)): if ((temp3[i][0] == ipo.dst) and (int(temp3[i][1]) == tcpo.src_port) and (int(temp3[i][2]) == tcpo.dst_port)): flag2 = 1 actions_default = action_fwd_to_out_port break if (flag2 == 0): actions_default = action_drop #Check for UDP elif (ipo.proto == IPPROTO_UDP): udpo = pkt.get_protocol(udp.udp) flag3 = 0 if self.inner_policy.has_key(ipo.src): temp = self.inner_policy.get(ipo.src) for i in range(0, len(temp)): if temp[i][0] == ipo.dst: xyz = temp[i] if ((xyz[1] == 'UDP') and (int(xyz[2]) == udpo.src_port) and (int(xyz[3]) == udpo.dst_port) and (xyz[5] == 'ALLOW')): flag3 = 1 actions_default = action_fwd_to_out_port self.udp_conn_track = self.track.conn_track_dict( self.udp_conn_track, ipo.src, ipo.dst, udpo.src_port, udpo.dst_port, xyz[5], 2) self.flow.add_flow(datapath=datapath, actions=actions_default, priority=1001, in_port=in_port, eth_type=ETH_TYPE_IP, ip_proto=IPPROTO_UDP, ipv4_src=ipo.src, ipv4_dst=ipo.dst, udp_src=udpo.src_port, udp_dst=udpo.dst_port) self.flow.add_flow( datapath=datapath, actions=action_fwd_to_in_port, priority=1000, in_port=out_port, eth_type=ETH_TYPE_IP, ip_proto=IPPROTO_UDP, ipv4_src=ipo.dst, ipv4_dst=ipo.src, udp_src=udpo.dst_port, udp_dst=udpo.src_port) break if (flag3 == 0): actions_default = action_drop else: self.logger.info("Wrong IP protocol found") actions_default = action_drop # Handling ARP Rules. elif (ethtype == ETH_TYPE_ARP): self.arp_handling(datapath, out_port, eth, in_port) actions_default = action_fwd_to_out_port else: actions_default = action_drop except Exception as err: self.logger.info("ERROR: %s", err.message) action_drop = [parser.OFPActionOutput(ofproto.OFPPC_NO_FWD)] actions_default = action_drop finally: self.sendpkt.send(datapath, msg, in_port, actions_default) """ Add ARP rules on flow tables """ def arp_handling(self, datapath, out_port, eth_obj, in_port): if (out_port != datapath.ofproto.OFPP_FLOOD): actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] self.flow.add_flow(datapath=datapath, actions=actions, priority=1000, in_port=in_port, eth_type=ETH_TYPE_ARP, eth_src=eth_obj.src, eth_dst=eth_obj.dst) """ Learn Switch port associated with a MAC address here """ def port_learn(self, datapath, eth_obj, in_port): try: self.mac_to_port.setdefault(datapath.id, { '90:e2:ba:1c:55:54': 1, '90:e2:ba:1c:55:55': 2 }) self.mac_to_port[datapath.id][eth_obj.src] = in_port if (eth_obj.ethertype == ETH_TYPE_IP) or (eth_obj.ethertype == ETH_TYPE_ARP): if eth_obj.dst in self.mac_to_port[datapath.id]: out_port = self.mac_to_port[datapath.id][eth_obj.dst] else: out_port = datapath.ofproto.OFPP_FLOOD except Exception as err: self.info(err.message) out_port = datapath.ofproto.OFPP_FLOOD finally: return out_port
class InefficientFirewall(app_manager.RyuApp): OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] inner_policy = {} icmp_conn_track = {} tcp_conn_track = {} udp_conn_track = {} sendpkt = SendPacket() flow = Construct() track = TrackConnection() current_time = Incoming_packet_time() def __init__(self, *args, **kwargs): super(InefficientFirewall, self).__init__(*args, **kwargs) self.mac_to_port = {} parser = parse_firewall() self.inner_policy = parser.parse() @set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER) def handler_datapath(self, ev): SwitchInfo(ev) """ Handles incoming packets. Decodes them and checks for suitable Firewall rules. """ @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] try: pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] ethtype = eth.ethertype out_port = self.port_learn(datapath, eth, in_port) action_fwd_to_out_port = [parser.OFPActionOutput(out_port)] action_drop = [parser.OFPActionOutput(ofproto.OFPPC_NO_FWD)] actions_default = action_fwd_to_out_port if (out_port != ofproto.OFPP_FLOOD) and (ethtype == ETH_TYPE_IP): ipo = pkt.get_protocols(ipv4.ipv4)[0] # Check for ICMP if (ipo.proto == IPPROTO_ICMP): flag1 = 0 icmpob = pkt.get_protocol(icmp.icmp) # Check if this is PING if ((icmpob.type == ICMP_PING) and self.inner_policy.has_key(ipo.src)): temp = self.inner_policy.get(ipo.src) for i in range(0, len(temp)): if temp[i][0] == ipo.dst: xyz = temp[i] if ((xyz[1] == 'ICMP') and (xyz[5] == 'ALLOW')): flag1 = 1 actions_default = action_fwd_to_out_port self.icmp_conn_track = self.track.conn_track_dict( self.icmp_conn_track, ipo.src, ipo.dst, "PING", "PONG", xyz[5], 2) self.logger.info( "%s -> %s : ECHO REQUEST ALLOWED" % (ipo.src, ipo.dst)) break # Otherwise, PONG...! elif ((icmpob.type == ICMP_PONG) and (self.icmp_conn_track.has_key(ipo.src))): temp2 = self.icmp_conn_track.get(ipo.src) for i in range(0, len(temp2)): if temp2[i][0] == ipo.dst: xyz = temp2[i] if ((xyz[1] == 'PONG') and (xyz[3] == 'ALLOW')): flag1 = 1 actions_default = action_fwd_to_out_port self.logger.info( "%s -> %s : ECHO REPLY ALLOWED" % (ipo.src, ipo.dst)) self.logger.info( "\n%s -> %s action= %s state= ESTABLISHED \n" % (xyz[0], ipo.src, xyz[2])) self.current_time.time() self.logger.info("\n") break # What about no match ?? if (flag1 == 0): actions_default = action_drop self.logger.info("%s -> %s : BLOCKED" % (ipo.src, ipo.dst)) # Check for TCP elif (ipo.proto == IPPROTO_TCP): tcpo = pkt.get_protocol(tcp.tcp) flag2 = 0 # TCP SYN packet if (((tcpo.bits & TCP_SYN) == TCP_SYN) & ((tcpo.bits & TCP_BOGUS_FLAGS) == 0x00)): if self.inner_policy.has_key(ipo.src): temp = self.inner_policy.get(ipo.src) for i in range(0, len(temp)): if ((temp[i][0] == ipo.dst) and (temp[i][1] == 'TCP') and (int(temp[i][2]) == tcpo.src_port) and (int(temp[i][3]) == tcpo.dst_port) and (temp[i][5] == 'ALLOW')): flag2 = 1 actions_default = action_fwd_to_out_port self.tcp_conn_track = self.track.conn_track_dict( self.tcp_conn_track, ipo.src, ipo.dst, tcpo.src_port, tcpo.dst_port, tcpo.seq, 1) self.logger.info( "%s -> %s : SYN ALLOWED" % (ipo.src, ipo.dst)) break # TCP SYN ACK packet elif ((tcpo.bits & TCP_SYN_ACK) == TCP_SYN_ACK): if self.tcp_conn_track.has_key(ipo.dst): temp2 = self.tcp_conn_track.get(ipo.dst) for i in range(0, len(temp2)): if ((temp2[i][0] == ipo.src) and (int(temp2[i][1]) == tcpo.dst_port) and (int(temp2[i][2]) == tcpo.src_port)): flag2 = 1 actions_default = action_fwd_to_out_port self.tcp_conn_track = self.track.conn_track_dict( self.tcp_conn_track, ipo.src, ipo.dst, tcpo.src_port, tcpo.dst_port, tcpo.seq, 1) self.logger.info( "%s -> %s : SYN ACK ALLOWED" % (ipo.src, ipo.dst)) self.logger.info( "\n%s -> %s src_port= %s dst_port= %s state= ESTABLISHED \n" % (ipo.dst, ipo.src, temp2[i][1], temp2[i][2])) self.current_time.time() self.logger.info("\n") break # All remaining TCP packets, like, ACK, PUSH, FIN etc. else: if self.tcp_conn_track.has_key(ipo.src): temp3 = self.tcp_conn_track.get(ipo.src) for i in range(0, len(temp3)): if ((temp3[i][0] == ipo.dst) and (int(temp3[i][1]) == tcpo.src_port) and (int(temp3[i][2]) == tcpo.dst_port)): flag2 = 1 actions_default = action_fwd_to_out_port self.logger.info( "%s -> %s : TRANSMISSION ALLOWED" % (ipo.src, ipo.dst)) break # What if no match found ? if (flag2 == 0): actions_default = action_drop self.logger.info("%s -> %s : SYN BLOCKED" % (ipo.src, ipo.dst)) # Check for UDP elif (ipo.proto == IPPROTO_UDP): flag3 = 0 udpo = pkt.get_protocol(udp.udp) # Check for tracked UDP if self.udp_conn_track.has_key(ipo.dst): tmp_tpl = self.udp_conn_track.get(ipo.dst) tmp = list(tmp_tpl) for i in range(0, len(tmp)): if (tmp[i][0] == ipo.src): xyz = tmp[i] if ((int(xyz[1]) == udpo.dst_port) and (int(xyz[2]) == udpo.src_port) and (xyz[3] == 'UNREPLIED')): flag3 = 1 self.logger.info( "%s -> %s : UDP PACKET ALLOWED" % (ipo.src, ipo.dst)) actions_default = action_fwd_to_out_port del tmp[ i] ### We need to remove this state entry to keep this packet 'REPLIED' self.logger.info( "\n%s -> %s src_port= %s dst_port= %s state= ASSURED\n" % (ipo.src, ipo.dst, udpo.src_port, udpo.dst_port)) break tmp_tpl = tuple(tmp) if len(tmp_tpl) != 0: self.udp_conn_track[ipo.dst] = tmp_tpl else: self.udp_conn_track.pop(ipo.dst, None) # Check for first UDP packet elif self.inner_policy.has_key(ipo.src): temp = self.inner_policy.get(ipo.src) for i in range(0, len(temp)): if temp[i][0] == ipo.dst: xyz = temp[i] if ((xyz[1] == 'UDP') and (int(xyz[2]) == udpo.src_port) and (int(xyz[3]) == udpo.dst_port) and (xyz[5] == 'ALLOW')): flag3 = 1 actions_default = action_fwd_to_out_port self.udp_conn_track = self.track.conn_track_dict( self.udp_conn_track, ipo.src, ipo.dst, udpo.src_port, udpo.dst_port, "UNREPLIED", 1) self.logger.info( "%s -> %s : UDP PACKET ALLOWED" % (ipo.src, ipo.dst)) self.logger.info( "\n%s -> %s src_port= %s dst_port= %s state= UNREPLIED\n" % (ipo.src, ipo.dst, udpo.src_port, udpo.dst_port)) self.current_time.time() self.logger.info("\n") break # what if no match found ? if (flag3 == 0): actions_default = action_drop self.logger.info("%s -> %s : UDP BLOCKED" % (ipo.src, ipo.dst)) # If not ICMP, TCP or UDP then drop..! else: self.logger.info("Wrong IP protocol found") actions_default = action_drop # Handling ARP Rules. elif (ethtype == ETH_TYPE_ARP): self.arp_handling(datapath, out_port, eth, in_port) actions_default = action_fwd_to_out_port # If packet is not IP or ARP then drop..! else: actions_default = action_drop except Exception as err: self.logger.info("MYERROR: %s", err.message) action_drop = [parser.OFPActionOutput(ofproto.OFPPC_NO_FWD)] actions_default = action_drop finally: self.sendpkt.send(datapath, msg, in_port, actions_default) """ Add ARP rules on Flow Tables """ def arp_handling(self, datapath, out_port, eth_obj, in_port): if (out_port != datapath.ofproto.OFPP_FLOOD): actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] self.flow.add_flow(datapath=datapath, actions=actions, priority=1000, in_port=in_port, eth_type=ETH_TYPE_ARP, eth_src=eth_obj.src, eth_dst=eth_obj.dst) """ Learn Switch port associated with a MAC address here """ def port_learn(self, datapath, eth_obj, in_port): try: self.mac_to_port.setdefault(datapath.id, {}) self.mac_to_port[datapath.id][eth_obj.src] = in_port if (eth_obj.ethertype == ETH_TYPE_IP) or (eth_obj.ethertype == ETH_TYPE_ARP): if eth_obj.dst in self.mac_to_port[datapath.id]: out_port = self.mac_to_port[datapath.id][eth_obj.dst] else: out_port = datapath.ofproto.OFPP_FLOOD except Exception as err: self.info(err.message) out_port = datapath.ofproto.OFPP_FLOOD finally: return out_port