def _process_outbound(self, pktin, intfs, iport, lointf): """Event handler for outbound ARP packets @param pktin packet in event to handle @param intfs dictionary of interfaces (with ip range) @param iport port no of local interface @param lointf local interface address (ip, mac) @return false """ for portno, ipr in intfs.items(): if (ipr[0] & ipr[1]) == (pktin.match.nw_dst & ipr[1]): flow = flows.exact_entry(pktin.match) if flow.buffer_id != pktin.pktin.buffer_id: output.warn("Buffered outbound ARP packet (cannot be rewritten properly)!", self.__class__.__name__) else: flow.add_output(portno) ofpkt.dl_rewrite(pktin.dpkt, True, ipr[2]) ofpkt.nw_rewrite(pktin.dpkt, True, ipr[0]) self.get_conn().send(flow.get_packet_out().pack() + pktin.dpkt.pack()) output.vdbg( "ARP to " + pu.ip_val2string(pktin.match.nw_dst) + " sent to port " + str(portno), self.__class__.__name__, ) return False output.warn("ARP for " + pu.ip_val2string(pktin.match.nw_dst) + " unknown subnet", self.__class__.__name__) return False
def processevent(self, event): """Process event """ if (isinstance(event, ofevents.pktin)): ##Allow flow to authenticate even when yet authenticated if ((event.match.nw_dst == AUTH_DST_IP and (event.match.tp_dst == AUTH_DST_PORT1 or event.match.tp_dst == AUTH_DST_PORT2)) or (event.match.nw_src == AUTH_DST_IP and (event.match.tp_src == AUTH_DST_PORT1 or event.match.tp_src == AUTH_DST_PORT2))): if (event.match.nw_dst == AUTH_DST_IP and event.match.tp_dst == 8080): owglobal.last_host_redirect = (self.conn.db[event.sock].dpid, event.match.dl_src) output.dbg("Approving "+\ pu.ip_val2string(event.match.nw_src) + ":"+str(event.match.tp_src)+\ "=>"+\ pu.ip_val2string(event.match.nw_dst) + ":"+str(event.match.tp_dst), self.__class__.__name__) return True #Authenticated host if (host_authenticated(event.match.dl_src) or host_authenticated(event.match.dl_dst)): output.vdbg("Authenticated host flow "+\ pu.ip_val2string(event.match.nw_src) + ":"+str(event.match.tp_src)+\ "=>"+\ pu.ip_val2string(event.match.nw_dst) + ":"+str(event.match.tp_dst), self.__class__.__name__) return True ##Allow special website access without authentication if (event.match.nw_dst in BYPASS_IP or event.match.nw_src in BYPASS_IP): output.dbg("Allow bypass for special server", self.__class__.__name__) return True ##Allow # (1) ARP # (2) ICMP # (3) DHCP # (4) DNS if ((event.match.dl_type == dpkt.ethernet.ETH_TYPE_ARP) or (event.match.dl_type == dpkt.ethernet.ETH_TYPE_IP and event.match.nw_proto == dpkt.ip.IP_PROTO_ICMP) or (event.match.dl_type == dpkt.ethernet.ETH_TYPE_IP and event.match.nw_proto == dpkt.ip.IP_PROTO_UDP and (event.match.tp_dst == 67 or event.match.tp_dst == 68)) or (event.match.dl_type == dpkt.ethernet.ETH_TYPE_IP and event.match.nw_proto == dpkt.ip.IP_PROTO_UDP and (event.match.tp_dst == 53 or event.match.tp_src == 53))): return True ##Allow route to OpenID provider (should be in HTTPS) if (event.match.tp_dst == HTTPS_PORT or event.match.tp_dst == 8080 or event.match.tp_dst == 80 or event.match.tp_src == HTTPS_PORT or event.match.tp_src == 8080 or event.match.tp_src == 80): auth_s = None if (event.match.tp_dst == HTTPS_PORT or event.match.tp_dst == 8080 or event.match.tp_dst == 80): auth_s = mcutil.get(host_auth.get_auth_key(event.match.dl_src)) else: auth_s = mcutil.get(host_auth.get_auth_key(event.match.dl_dst)) if (auth_s != None): output.dbg(pu.ip_val2string(event.match.nw_dst)+" associated with "+\ " auth server "+str(auth_s)+" "+str(event.match.dl_src), self.__class__.__name__) return True ##Redirect unauthenticated host if HTTP if (event.match.dl_type == dpkt.ethernet.ETH_TYPE_IP and event.match.nw_proto == dpkt.ip.IP_PROTO_TCP and (event.match.tp_dst == 80 or event.match.tp_dst == 8080)): output.dbg("Redirecting %x to authenticate" % pu.array2val(event.match.dl_src), self.__class__.__name__) #Forward flow flow = flows.exact_entry(event.match) key = swhost.mac2sw_binding.get_key(event.sock, event.match.dl_dst) port = mcutil.get(key) if (port != None): flow.set_buffer(event.pktin.buffer_id) flow.add_nw_rewrite(False, AUTH_DST_IP) flow.add_output(port) self.conn.send(event.sock,flow.get_flow_mod(pyof.OFPFC_MODIFY).pack()) #Reverse flow rflow = flow.reverse(port) rflow.match.nw_src = AUTH_DST_IP rflow.add_nw_rewrite(True, event.match.nw_dst) rflow.add_output(event.pktin.in_port) self.conn.send(event.sock,rflow.get_flow_mod(pyof.OFPFC_MODIFY).pack()) return False #Drop remaining flows flow = flows.exact_entry(event.match) flow.set_buffer(event.pktin.buffer_id) self.conn.send(event.sock,flow.get_flow_mod(pyof.OFPFC_ADD).pack()) output.dbg("Dropping "+\ pu.ip_val2string(event.match.nw_src) + ":"+str(event.match.tp_src)+\ "=>"+pu.ip_val2string(event.match.nw_dst) + ":"+str(event.match.tp_dst), self.__class__.__name__) return False return True
def processevent(self, event): """Process event """ if (isinstance(event, ofevents.pktin)): ##Allow flow to authenticate even when yet authenticated if ((event.match.nw_dst == AUTH_DST_IP and (event.match.tp_dst == AUTH_DST_PORT1 or event.match.tp_dst == AUTH_DST_PORT2)) or (event.match.nw_src == AUTH_DST_IP and (event.match.tp_src == AUTH_DST_PORT1 or event.match.tp_src == AUTH_DST_PORT2))): if (event.match.nw_dst == AUTH_DST_IP and event.match.tp_dst == 8080): owglobal.last_host_redirect = ( self.conn.db[event.sock].dpid, event.match.dl_src) output.dbg("Approving "+\ pu.ip_val2string(event.match.nw_src) + ":"+str(event.match.tp_src)+\ "=>"+\ pu.ip_val2string(event.match.nw_dst) + ":"+str(event.match.tp_dst), self.__class__.__name__) return True #Authenticated host if (host_authenticated(event.match.dl_src) or host_authenticated(event.match.dl_dst)): output.vdbg("Authenticated host flow "+\ pu.ip_val2string(event.match.nw_src) + ":"+str(event.match.tp_src)+\ "=>"+\ pu.ip_val2string(event.match.nw_dst) + ":"+str(event.match.tp_dst), self.__class__.__name__) return True ##Allow special website access without authentication if (event.match.nw_dst in BYPASS_IP or event.match.nw_src in BYPASS_IP): output.dbg("Allow bypass for special server", self.__class__.__name__) return True ##Allow # (1) ARP # (2) ICMP # (3) DHCP # (4) DNS if ((event.match.dl_type == dpkt.ethernet.ETH_TYPE_ARP) or (event.match.dl_type == dpkt.ethernet.ETH_TYPE_IP and event.match.nw_proto == dpkt.ip.IP_PROTO_ICMP) or (event.match.dl_type == dpkt.ethernet.ETH_TYPE_IP and event.match.nw_proto == dpkt.ip.IP_PROTO_UDP and (event.match.tp_dst == 67 or event.match.tp_dst == 68)) or (event.match.dl_type == dpkt.ethernet.ETH_TYPE_IP and event.match.nw_proto == dpkt.ip.IP_PROTO_UDP and (event.match.tp_dst == 53 or event.match.tp_src == 53))): return True ##Allow route to OpenID provider (should be in HTTPS) if (event.match.tp_dst == HTTPS_PORT or event.match.tp_dst == 8080 or event.match.tp_dst == 80 or event.match.tp_src == HTTPS_PORT or event.match.tp_src == 8080 or event.match.tp_src == 80): auth_s = None if (event.match.tp_dst == HTTPS_PORT or event.match.tp_dst == 8080 or event.match.tp_dst == 80): auth_s = mcutil.get( host_auth.get_auth_key(event.match.dl_src)) else: auth_s = mcutil.get( host_auth.get_auth_key(event.match.dl_dst)) if (auth_s != None): output.dbg(pu.ip_val2string(event.match.nw_dst)+" associated with "+\ " auth server "+str(auth_s)+" "+str(event.match.dl_src), self.__class__.__name__) return True ##Redirect unauthenticated host if HTTP if (event.match.dl_type == dpkt.ethernet.ETH_TYPE_IP and event.match.nw_proto == dpkt.ip.IP_PROTO_TCP and (event.match.tp_dst == 80 or event.match.tp_dst == 8080)): output.dbg( "Redirecting %x to authenticate" % pu.array2val(event.match.dl_src), self.__class__.__name__) #Forward flow flow = flows.exact_entry(event.match) key = swhost.mac2sw_binding.get_key(event.sock, event.match.dl_dst) port = mcutil.get(key) if (port != None): flow.set_buffer(event.pktin.buffer_id) flow.add_nw_rewrite(False, AUTH_DST_IP) flow.add_output(port) self.conn.send(event.sock, flow.get_flow_mod(pyof.OFPFC_MODIFY).pack()) #Reverse flow rflow = flow.reverse(port) rflow.match.nw_src = AUTH_DST_IP rflow.add_nw_rewrite(True, event.match.nw_dst) rflow.add_output(event.pktin.in_port) self.conn.send( event.sock, rflow.get_flow_mod(pyof.OFPFC_MODIFY).pack()) return False #Drop remaining flows flow = flows.exact_entry(event.match) flow.set_buffer(event.pktin.buffer_id) self.conn.send(event.sock, flow.get_flow_mod(pyof.OFPFC_ADD).pack()) output.dbg("Dropping "+\ pu.ip_val2string(event.match.nw_src) + ":"+str(event.match.tp_src)+\ "=>"+pu.ip_val2string(event.match.nw_dst) + ":"+str(event.match.tp_dst), self.__class__.__name__) return False return True