def _process_inbound(self, pktin, intfs, iport, lointf): """Event handler for inbound 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 """ try: ipr = intfs[pktin.match.in_port] except KeyError: output.vdbg("ARP packet received on unknown/uninitialized interface", self.__class__.__name__) return False flow = flows.exact_entry(pktin.match) if flow.buffer_id != pktin.pktin.buffer_id: output.warn("Buffered inbound ARP packet (cannot be rewritten properly)!", self.__class__.__name__) elif flow.match.nw_dst != ipr[0]: output.vdbg("Inbound ARP packet not destined for this host, ignored.", self.__class__.__name__) else: flow.add_output(iport) if pu.array2val(pktin.match.dl_dst) != 0xFFFFFFFFFFFF: ofpkt.dl_rewrite(pktin.dpkt, False, lointf[1]) ofpkt.nw_rewrite(pktin.dpkt, False, lointf[0]) self.get_conn().send(flow.get_packet_out().pack() + pktin.dpkt.pack()) return False
def get_flow_id(ofp_match, ignore_l2=False): """Generate flow id based on ofp_match id has the following properties: * is the same for packets of the same TCP/UDP flow * is the same for packets for the same bidirectional flow """ t1 = ofp_match.dl_type t2 = ofp_match.nw_proto daddr = [pu.array2val(ofp_match.dl_src), pu.array2val(ofp_match.dl_src)] d1 = min(daddr) d2 = max(daddr) naddr = [ofp_match.nw_src, ofp_match.nw_dst] n1 = min(naddr) n2 = max(naddr) taddr = [ofp_match.tp_src, ofp_match.tp_dst] t1 = min(taddr) t2 = max(taddr) if (ignore_l2): return hash((t1,t2,n1,n2,t1,t2)) else: return hash((t1,t2,d1,d2,n1,n2,t1,t2))
def processevent(self, event): """Event handler @param event event to handle """ key = self.get_key(event.sock, event.match.dl_src) #Broadcast mac if (pu.is_multicast_mac(event.match.dl_src)): return True mc.set(key, event.pktin.in_port, mac2sw_binding.TIMEOUT) output.vdbg("Learn that %x " % pu.array2val(event.match.dl_src) +\ "is connected to port " + \ str(event.pktin.in_port)+" of switch with "+\ str(event.sock), self.__class__.__name__) return True
def processevent(self, event): """Event handler @param event event to handle @return false if flow can be installed, else true """ if (isinstance(event, ofevents.pktin)): #Forward packet/flow if (pu.is_multicast_mac(event.match.dl_dst)): return True key = swhost.mac2sw_binding.get_key(event.sock, event.match.dl_dst) port = mc.get(key) if (port != None): self.installflow(event, port) return False else: output.dbg("No binding found for mac %x" % pu.array2val(event.match.dl_dst), self.__class__.__name__) 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
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 get_key(sock, mac): """Get key to retrieve binding between switch and mac """ return mac2sw_binding.MAC2SW_BINDING_PREFIX +\ mc.socket_str(sock) +\ "%x" % pu.array2val(mac)