def POST(self): uname = str(web.input()['userName']) a = owevent.authenticated(owglobal.session.datapath, owglobal.session.host, "Facebook:"+uname) owglobal.server.post_event(a) output.dbg(str(owglobal.session.host)+\ " is authenticated with %s" % uname, self.__class__.__name__) return ''' <html><head><title>Open WiFi: Towards Access Everywhere...</title></head> <body> <center> <h2>Welcome to OpenWiFi<sup>beta</sup>!</h2> <h4>A Stanford Research Project</h4> <table align=centerwidth=600 border=0> <td><tr>Hi %s, hope you will enjoy OpenWiFi! </td></tr> <tr><td> </td></tr> <tr><td> </td></tr> <tr><td> <a href="about">About OpenWiFi</a>   <a href="tos">Terms of Service</a>. </td></tr> </table> </center> </body> </html> ''' % uname
def _processglobal(self, event): """Process mode related JSON messages @param event yapc.jsoncomm.message event """ reply = {} reply["type"] = "coin" if (event.message["command"] == "get_all_config"): reply["subtype"] = "config" reply["value"] = self.config elif (event.message["command"] == "get_config"): reply["subtype"] = "config" reply["value"] = self.get_config(event.message["name"]) elif (event.message["command"] == "set_config"): reply["subtype"] = "config" reply["previous value"] = self.get_config(event.message["name"]) self.set_config(event.message["name"], event.message["value"]) reply["current value"] = str(self.get_config(event.message["name"])) elif (event.message["command"] == "get_eth_interfaces"): reply["subtype"] = "interfaces" reply["interfaces"] = self.ifmgr.ethernet_ipv4_addresses() else: output.dbg("Receive message "+str(event.message), self.__class__.__name__) return None return reply
def processevent(self, event): """Process events @param event event """ if (isinstance(event, jsoncomm.message) and event.message["type"] == "coin" and event.message["command"] == "query"): output.dbg("Received query "+str(event.message), self.__class__.__name__) q = query(event.message["name"], event.message["selection"], event.message["condition"]) self.server.post_event(q) self.__q[q] = event.sock elif (isinstance(event, queryresponse)): reply = {} reply["type"] = "coin" reply["subtype"] = "query response" reply["reply"] = event.response self.jsonconnections.db[self.__q[event.query]].send(reply) del self.__q[event.query] return True
def _handle_change(self, flow_stats): """Handle flows to be changed based on flow stats reply @param flow_stats flow_stats event """ self.check_timeout() for f in flow_stats.flows: for (new, old) in self.ip_change.items(): if f.match.nw_src == old[0]: flow = flows.exact_entry( f.match, priority=f.priority, idle_timeout=f.idle_timeout, hard_timeout=f.hard_timeout ) flow.set_nw_src(new) flow.add_nw_rewrite(True, old) flow.actions.extend(f.actions) self.get_conn().send(flow.get_flow_mod(pyof.OFPFC_MODIFY, f.cookie).pack()) output.dbg(str(f) + " has old source IP (flow rule is added)", self.__class__.__name__) elif f.match.nw_dst == old[0]: flow = flows.exact_entry( f.match, priority=f.priority, idle_timeout=f.idle_timeout, hard_timeout=f.hard_timeout ) flow.add_nw_rewrite(False, new) flow.actions.extend(f.actions) self.get_conn().send(flow.get_flow_mod(pyof.OFPFC_MODIFY, f.cookie).pack()) output.dbg(str(f) + " has old destination IP (flow rule is modified)", self.__class__.__name__)
def POST(self): uname = str(web.input()['userName']) a = owevent.authenticated(owglobal.session.datapath, owglobal.session.host, "Facebook:" + uname) owglobal.server.post_event(a) output.dbg(str(owglobal.session.host)+\ " is authenticated with %s" % uname, self.__class__.__name__) return ''' <html><head><title>Open WiFi: Towards Access Everywhere...</title></head> <body> <center> <h2>Welcome to OpenWiFi<sup>beta</sup>!</h2> <h4>A Stanford Research Project</h4> <table align=centerwidth=600 border=0> <td><tr>Hi %s, hope you will enjoy OpenWiFi! </td></tr> <tr><td> </td></tr> <tr><td> </td></tr> <tr><td> <a href="about">About OpenWiFi</a>   <a href="tos">Terms of Service</a>. </td></tr> </table> </center> </body> </html> ''' % uname
def POST(self): # unlike the usual scheme of things, the POST is actually called # first here i = web.input(return_to='/') if i.get('action') == 'logout': web.webopenid.logout() return web.redirect(i.return_to) i = web.input('openid', return_to='/') going = owevent.going_to_auth(owglobal.session.datapath, owglobal.session.host, i['openid']) owglobal.server.post_event(going) output.dbg(str(owglobal.session.host)+\ " is going to "+going.server()+" to authenticate", self.__class__.__name__) n = web.webopenid._random_session() web.webopenid.sessions[n] = {'webpy_return_to': i.return_to} c = openid.consumer.consumer.Consumer(web.webopenid.sessions[n], web.webopenid.store) a = c.begin(i.openid) f = a.redirectURL(web.ctx.home, web.ctx.home + web.ctx.fullpath) web.setcookie('openid_session_id', n) return web.redirect(f)
def processevent(self, event): """Process all the events registered for Check for packet-in and : create packet out with FLOOD action send it (oops.. do check the buffer id to see if buffered) @param event event to handle """ if (isinstance(event, ofevents.pktin)): output.dbg("Receive an OpenFLow packet in :\n"+\ event.pktin.show(), self.__class__.__name__) flow = flows.exact_entry(event.match) flow.set_buffer(event.pktin.buffer_id) flow.add_output(pyof.OFPP_FLOOD) if (event.pktin.buffer_id == flows.UNBUFFERED_ID): ##Not buffered self.conn.send(event.sock, flow.get_packet_out().pack()+event.pkt) output.vdbg("Flood unbuffered packet with match "+\ event.match.show().replace('\n',';')) else: ##Buffered packet self.conn.send(event.sock,flow.get_packet_out().pack()) output.vdbg("Flood buffered packet with match "+\ event.match.show().replace('\n',';')) return True
def __process_switch_json(self, event): """Process JSON messages for switch @param event JSON message event for switch """ reply = {} reply["type"] = "coin" reply["subtype"] = "ovs" if event.message["command"] == "add_if": self.add_if(event.message["name"]) reply["executed"] = True elif event.message["command"] == "del_if": self.datapaths[COIN_DP_NAME].del_if(event.message["name"]) reply["executed"] = True elif event.message["command"] == "get_interfaces": dpidsl = mc.get(swstate.dp_features.DP_SOCK_LIST) if dpidsl != None: reply["interfaces"] = [] if len(dpidsl) > 1: output.warn(str(len(dpidsl)) + " datapaths connected to COIN", self.__class__.__name__) f = mc.get(dpidsl[0]) output.dbg("Updated switch features:\n" + f.show("\t"), self.__class__.__name__) for p in f.ports: reply["interfaces"].append(p.name) else: output.warn("No datapaths connected to COIN", self.__class__.__name__) reply["error"] = "No datapath connected" else: reply["error"] = "Unknown command" return reply
def add_interfaces(self, interfaces): """Add interfaces (plus mirror port) @param interfaces list of interfaces """ for i in interfaces: self.switch.add_if(i) self.ifmgr.set_ipv4_addr(i, "0.0.0.0") # Add mirror interface self.mirror[i] = self.add_loif(i) ieth = self.ifmgr.ethernet_addr(i) self.ifmgr.set_eth_addr(self.mirror[i].client_intf, ieth) np = self.switch.get_ports() port1 = np[i] port2 = np[self.mirror[i].switch_intf] # Set perm DHCP rules for mirror dreq = flows.udp_entry(portno=68, priority=ofutil.PRIORITY["LOW"]) dreq.set_in_port(port1) dreq.add_output(port2, 65535) self.default.add_perm(dreq) drep = flows.udp_entry(portno=67, priority=ofutil.PRIORITY["LOW"]) drep.set_in_port(port2) drep.add_output(port1, 65535) self.default.add_perm(drep) output.dbg( "Set " + self.mirror[i].client_intf + " to " + self.ifmgr.ethernet_addr(i), self.__class__.__name__ )
def cleanup(self): """Clean up """ output.dbg("Cleaning up database", self.__class__.__name__) self.flush() self.close()
def cleanup(self): """Clean up interfaces """ output.dbg("Cleaning up veth interfaces", self.__class__.__name__) for v in self.veth: v.__del__()
def __init__(self, sock, msg): """Initialize @param sock reference to socket @param msg message """ ofcomm.message.__init__(self, sock, msg) ##Features struct self.features = None if (self.header.type == pyof.OFPT_FEATURES_REPLY): self.features = pyof.ofp_switch_features() r = self.features.unpack(msg) while (len(r) >= pyof.OFP_PHY_PORT_BYTES): p = pyof.ofp_phy_port() r = p.unpack(r) self.features.ports.append(p) if (len(r) > 0): output.warn("Features reply is of irregular length with "+\ str(len(r))+" bytes remaining.", self.__class__.__name__) output.dbg("Received switch features:\n"+\ self.features.show("\t"), self.__class__.__name__)
def __del__(self): """Clean up all datapath """ output.dbg("Cleaning up datapaths", self.__class__.__name__) for name,dp in self.datapaths.items(): self.del_dp(name)
def send(self, msg): """Send dictionary as JSON message """ try: self.sock.send(simplejson.dumps(msg)) output.dbg("Send message " + simplejson.dumps(msg), self.__class__.__name__) except socket.error: output.warn(str(self.sock) + " is broken, message is dropped!", self.__class__.__name__)
def random_select_intf(self, intfs): """Get which interface to send (random choice) @return port no to send flow on and None if nothing to choose from """ c = random.choice(intfs.keys()) output.dbg("Port " + str(c) + " " + str(intfs[c]) + " randomly selected", self.__class__.__name__) return c
def get_null_terminated_str(s): """Get null terminated string @param s referenence to string """ output.dbg(str(struct.unpack("B"*len(s), s)), "parse utility") return s[:s.find('\x00')]
def GET(self): going = owevent.going_to_auth(owglobal.session.datapath, owglobal.session.host, "facebook") owglobal.server.post_event(going) output.dbg(str(owglobal.session.host)+\ " is going to "+going.server()+" to authenticate", self.__class__.__name__) return fb.login.GET(self)
def add_dp(self, name): """Add datapath with name @param name name of datapath """ output.dbg("Add datapath "+name, self.__class__.__name__) self.datapaths[name] = datapath(name)
def addconnection(self, sock, manager): """Add socket and manager """ if (sock not in self.__sockets): self.__sockets.append(sock) self.__sockDictionary[sock] = manager output.dbg("Adding "+str(sock)+" to select list", self.__class__.__name__)
def print_event_handlers(self): """Output event and handlers for it """ for e,handles in self._processors.items(): output.dbg("Event "+e+" in order handled by:", self.__class__.__name__) for h in handles: output.dbg("\t"+h.__class__.__name__, self.__class__.__name__)
def removeconnection(self, sock): """Remove socket """ if (sock in self.__sockDictionary): del self.__sockDictionary[sock] if (sock in self.__sockets): self.__sockets.remove(sock) output.dbg("Removing "+str(sock)+" to select list", self.__class__.__name__)
def check_timeout(self): """Check and timeout host move ip changes """ if int(time.time()) > int(self.__lastcheck): self.__lastcheck = time.time() for from_m, to_m in self.m2m.items(): if to_m[1] + self.timeout < time.time(): del self.m2m[from_m] output.dbg("Timeout " + str(from_m) + "->" + str(to_m[0]), self.__class__.__name__)
def receive(self, sock, recvthread): """Receive new connection """ client, address = sock.accept() if not comm.BLOCKING: client.setblocking(0) recvthread.addconnection(client, jsonsockmanager(client, self.scheduler)) self.scheduler.post_event(comm.event(client, comm.event.SOCK_OPEN)) output.dbg("Connection to " + str(address) + " added", self.__class__.__name__)
def check_timeout(self): """Check and timeout host move ip changes """ if int(time.time()) > int(self.__lastcheck): self.__lastcheck = time.time() for new, old in self.ip_change.items(): if old[1] + self.timeout < time.time(): del self.ip_change[new] output.dbg("Timeout " + str(old[0]) + "->" + str(new), self.__class__.__name__)
def processevent(self, event): """Process OpenFlow message for switch status @param event OpenFlow message event to process @return True """ if isinstance(event, ofevents.features_reply): # Maintain list of datapath socket key = self.get_key(event.sock) dpidsl = mc.get(dp_features.DP_SOCK_LIST) if dpidsl == None: dpidsl = [] if key not in dpidsl: dpidsl.append(key) mc.set(dp_features.DP_SOCK_LIST, dpidsl) # Maintain dp features in memcache mc.set(key, event.features) elif isinstance(event, ofevents.port_status): # Port status if event.header.type == pyof.OFPT_PORT_STATUS: key = self.get_key(event.sock) sw = mc.get(key) if sw == None: output.warn("Port status from unknown datapath", self.__class__.__name__) else: output.dbg("Received port status:\n" + event.port.show("\t"), self.__class__.__name__) if event.port.reason == pyof.OFPPR_DELETE or event.port.reason == pyof.OFPPR_MODIFY: for p in sw.ports: if p.port_no == event.port.desc.port_no: sw.ports.remove(p) if event.port.reason == pyof.OFPPR_ADD or event.port.reason == pyof.OFPPR_MODIFY: sw.ports.append(event.port.desc) output.dbg("Updated switch features:\n" + sw.show("\t"), self.__class__.__name__) mc.set(key, sw) elif isinstance(event, comm.event): # Socket close if event.event == comm.event.SOCK_CLOSE: key = self.get_key(event.sock) sw = mc.get(key) if sw != None: output.info("Datapath %x leaves" % sw.datapath_id, self.__class__.__name__) # Maintain list of datapath socket dpidsl = mc.get(dp_features.DP_SOCK_LIST) if dpidsl != None: if key in dpidsl: dpidsl.remove(key) mc.set(dp_features.DP_SOCK_LIST, dpidsl) # Remove features mc.delete(key) return True
def del_dp(self, name): """Delete datapath with name @param name name of datapath """ if (name in self.datapaths): output.dbg("Delete datapath "+name, self.__class__.__name__) self.datapaths.pop(name) else: output.err("No datapath of name "+name)
def __del__(self): """Clean up datapath """ output.dbg("Clean up datapath "+self.name, self.__class__.__name__) if (self.connected): self.disconnect() for i in self.interfaces[:]: self.del_if(i) cmd.run_cmd(DPCTL+" del-dp "+self.name, self.__class__.__name__)
def __process_json(self, event): """Process JSON messages @param event JSON message event to process """ if event.message["type"] == "coin" and event.message["subtype"] == "ovs": reply = self.__process_switch_json(event) if reply != None: self.jsonconn.db[event.sock].send(reply) else: output.dbg("Receive JSON message " + simplejson.dumps(event.message), self.__class__.__name__)
def bandwidth_select_intf(self, intfs): """Get which interface to send (largest bandwidth) @return port no to send flow on and None if nothing to choose from """ c = self.max_bw_port if c == None: c = random.choice(intfs.keys()) output.dbg("Port " + str(c) + " " + str(intfs[c]) + " randomly selected", self.__class__.__name__) else: output.dbg("Port " + str(c) + " " + str(intfs[c]) + " selected as max bandwidth", self.__class__.__name__) return c
def receive(self, sock, recvthread): """Receive new connection """ client, address = sock.accept() if (not comm.BLOCKING): client.setblocking(0) if (not self.nagle): client.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) recvthread.addconnection(client, ofsockmanager(client, self.scheduler)) self.scheduler.post_event(comm.event(client, comm.event.SOCK_OPEN)) output.dbg("Connection to "+str(address)+" added", self.__class__.__name__)
def _process_inbound(self, pktin, intfs, iport, lointf): """Event handler for inbound packet @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("IP packet received on unknown/uninitialized interface", self.__class__.__name__) return False if ipr[2] != pktin.match.dl_dst: return False flow = flows.exact_entry(pktin.match) flow.add_nw_rewrite(False, lointf[0]) flow.add_dl_rewrite(False, lointf[1]) flow.add_output(iport) if pktin.pktin.buffer_id != flow.buffer_id: flow.set_buffer(pktin.pktin.buffer_id) self.get_conn().send(flow.get_flow_mod(pyof.OFPFC_ADD, cookie=self.cookie).pack()) self.cookie += 1 else: self.get_conn().send(flow.get_flow_mod(pyof.OFPFC_ADD, cookie=self.cookie).pack()) self.cookie += 1 ofpkt.nw_rewrite(pktin.dpkt, False, lointf[0]) ofpkt.dl_rewrite(pktin.dpkt, False, lointf[1]) self.get_conn().send(flow.get_packet_out(pyof.OFPFC_ADD).pack() + pktin.dpkt.pack()) gw = mc.get(nat.get_gw_key(flow.match.in_port)) gwmac = mc.get(nat.get_gw_mac_key(gw)) if gwmac == None: return False if (ipr[0] & ipr[1]) != (pktin.match.nw_src & ipr[1]): # Global address rflow = flow.reverse(iport) rflow.match.nw_src = lointf[0] rflow.match.dl_src = lointf[1] rflow.add_nw_rewrite(True, ipr[0]) rflow.add_dl_rewrite(True, ipr[2]) rflow.add_dl_rewrite(False, pu.hex_str2array(gwmac)) rflow.add_output(flow.match.in_port) if (rflow.match.wildcards & pyof.OFPFW_DL_TYPE) != 0: output.dbg(rflow.match.show(), self.__class__.__name__) self.get_conn().send(rflow.get_flow_mod(pyof.OFPFC_ADD, cookie=self.cookie).pack()) self.cookie += 1 return False
def GET(self): """Response to get """ oid = web.webopenid.status() body = ''' <html><head><title>Open WiFi: Towards Access Everywhere...</title></head> <body> <center> <h2>Welcome to OpenWiFi<sup>beta</sup>!</h2> <h4>A Stanford Research Project</h4> ''' if oid: body += self.get_logout() a = owevent.authenticated(owglobal.session.datapath, owglobal.session.host, oid) owglobal.server.post_event(a) output.dbg(str(owglobal.session.host)+\ " is authenticated with %s" % oid, self.__class__.__name__) else: if (owglobal.session.datapath == None or (not isinstance(owglobal.session.datapath, list))): owglobal.session.datapath = owglobal.last_host_redirect[0] owglobal.session.host = owglobal.last_host_redirect[1] body += self.get_login() u = owevent.unauthenticated(owglobal.session.datapath, owglobal.session.host) owglobal.server.post_event(u) body += ''' <br> </td></tr> <tr><td> <a href="about">About OpenWiFi</a>   <a href="tos">Terms of Service</a>. </td></tr> </table> </center> </body> </html> ''' return body
def processevent(self, event): """Process event @return True for accepted traffic, else False """ if (isinstance(event, ofevents.pktin)): if (event.match.dl_type == dpkt.ethernet.ETH_TYPE_ARP): return True if (event.match.nw_proto == dpkt.ip.IP_PROTO_ICMP): return True for p in [22, 25, 53, 67, 68, 80, 110, 143, \ 443, 465, 585, 993, 995, 8080]: if ((event.match.tp_src == p) or (event.match.tp_dst == p)): return True output.dbg("Reject flow" + event.match.show(), self.__class__.__name__) return False return True
def processevent(self, event): """Process authentication event """ if (event.host == None): return True if (isinstance(event, owevent.authenticated)): output.dbg( pu.array2hex_str(event.host) + " is authenticated", self.__class__.__name__) mcutil.set(host_auth.get_key(event.host), event.openid, MAX_AUTH_TIMEOUT) elif (isinstance(event, owevent.unauthenticated)): output.dbg( pu.array2hex_str(event.host) + " is unauthenticated", self.__class__.__name__) mcutil.delete(host_auth.get_key(event.host)) mcutil.delete(host_auth.get_auth_key(event.host)) elif (isinstance(event, owevent.going_to_auth)): output.dbg( pu.array2hex_str(event.host) + " is going to authenticate", self.__class__.__name__) mcutil.set(host_auth.get_auth_key(event.host), event.server(), AUTH_TIMEOUT) return True
def processevent(self, event): """Process event """ if (isinstance(event, owevent.authenticated)): h = None if (event.host != None): h = pu.array2hex_str(event.host) i = [time.time(), "auth", event.datapathid, h, event.openid] output.dbg("Authentication of "+str(h)+" recorded"+\ " with ID "+event.openid, self.__class__.__name__) self.table.add_row(tuple(i)) elif (isinstance(event, owevent.unauthenticated)): h = None if (event.host != None): h = pu.array2hex_str(event.host) i = [time.time(), "unauth", event.datapathid, h, None] output.dbg("Unauthentication of "+str(h)+" recorded", self.__class__.__name__) self.table.add_row(tuple(i)) elif (isinstance(event, owevent.going_to_auth)): h = None if (event.host != None): h = pu.array2hex_str(event.host) i = [time.time(), "tryauth", event.datapathid, h, event.url] output.dbg("Attempt authentication of "+str(h)+" recorded", self.__class__.__name__) self.table.add_row(tuple(i)) 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 cleanup(self): """Stop webpy through keyboard interrupt """ output.dbg("Cleanup webpy", self.__class__.__name__) raise KeyboardInterrupt