def handle_dns(self, dpid, inport, ofp_reason, total_frame_len, buffer_id, packet): eaddr = util.convert_to_eaddr(packet.src) dnsh = packet.find('dns') if not self.permit_ether_addr(eaddr): print "Dropping DNS Packet - MAC Address not allowed" return STOP if not dnsh: print "Invalid DNS packet:", dnsh, packet return CONTINUE print "DNS Packet:", dnsh for question in dnsh.questions: if eaddr in Homework.st['dnsList'] and question.name in Homework.st['dnsList'][eaddr]: print "DNS Resquest blocked for", question.name return STOP flow = util.extract_flow(packet) Homework.install_datapath_flow( dpid, flow, 3, 10, [[openflow.OFPAT_OUTPUT, [-1, openflow.OFPP_NORMAL]]], buffer_id, openflow.OFP_DEFAULT_PRIORITY, inport, packet.arr ) return CONTINUE
def __forward_l2_packet(self, dpid, inport, packet, buf, bufid): """ Layer 2 forwarding """ dstaddr = packet.dst.tostring() if not ord(dstaddr[0]) & 1 and dstaddr in self.switches[dpid]: prt = self.switches[dpid][dstaddr] if prt[0] == inport: LOG.err("**WARNING** Learned port = inport") self.send_openflow(dpid, bufid, buf, openflow.OFPP_FLOOD, inport) else: # We know the outport, set up a flow LOG.debug("Installing flow for %s" % str(packet)) flow = extract_flow(packet) actions = [[openflow.OFPAT_OUTPUT, [0, prt[0]]]] self.install_datapath_flow(dpid, flow, 5, openflow.OFP_FLOW_PERMANENT, actions, bufid, openflow.OFP_DEFAULT_PRIORITY, inport, buf) LOG.info("New installed flow entry for dpid '%s': %s" % \ (str(dpid), str(flow))) else: # haven't learned destination MAC. Flood self.send_openflow(dpid, bufid, buf, openflow.OFPP_FLOOD, inport) LOG.debug("Flooding received packet...")
def packetIsMatching(self, pkt, inport, attrs): """Checks whether a packet is matching a specific table entry attrs is a dictionary of attributes to match, missing attributes are considered wildcarded """ pkt_attrs = of_util.extract_flow(pkt) pkt_attrs[core.IN_PORT] = inport skip_nw_src = False for a in attrs: if a == "nw_src_n_wild": mask = int( 0xffffffff << attrs[a] ) # see openflow.h in NOX for this definition of mask if pkt_attrs[core.NW_SRC] & mask != attrs["nw_src"] & mask: return False else: skip_nw_src = True elif a == "nw_src" and skip_nw_src: continue elif attrs[a] != pkt_attrs[ a]: # If this throws an exception, we have an usupported attribute return False return True
def packet_in_handler(self, dpid, inport, reason, length, bufid, packet): """ Handler for packet_in event """ assert length is not None assert packet is not None # checks packet consistency if not packet.parsed: LOG.warning("Ignoring incomplete packet") return CONTINUE if packet.type == ethernet.LLDP_TYPE: return CONTINUE dpid_ = dpid_from_host(dpid) if not dpid_: return CONTINUE LOG.debug("dpid=%s, inport=%s, reason=%s, len=%s, bufid=%s, p=%s", dpid_, inport, reason, length, str(bufid), str(packet)) # Handle ARP packets if packet.type == ethernet.ARP_TYPE or\ (packet.type == ethernet.VLAN_TYPE and\ packet.find('vlan').eth_type == ethernet.ARP_TYPE): LOG.debug("Received ARP packet " + str(packet.find('arp'))) if not dpid_ in self.switches: LOG.debug("Registering new switch %s" % dpid_) self.switches[dpid_] = {} self.__do_l2_learning(dpid_, inport, packet) self.__forward_l2_packet(dpid_, inport, packet, packet.arr, bufid) # switch over ethernet type if packet.type == ethernet.IP_TYPE or\ (packet.type == ethernet.VLAN_TYPE and\ packet.find('vlan').eth_type == ethernet.IP_TYPE): ip_addr = packet.find('ipv4') LOG.info("IPv4 packet: " + str(ip_addr)) # XXX FIXME: Remove the following check in order to be generic... if ip_addr.protocol == ipv4.ICMP_PROTOCOL: flow = extract_flow(packet) LOG.debug("Sending path request for flow: %s" % str(flow)) payload = {"dst_port": flow[core.TP_DST], "src_port": flow[core.TP_SRC], "ip_dst" : pkt_utils.ip_to_str(ip_addr.dstip), "ip_src" : pkt_utils.ip_to_str(ip_addr.srcip), "ip_proto": flow[core.NW_PROTO], "vlan_id" : flow[core.DL_VLAN]} LOG.debug("Payload=%s" % str(payload)) if self.allow_ping == 'True': req = requests.post(url=self.url + "pckt_host_path", headers=self.hs, data=json.dumps(payload)) LOG.debug("URL=%s, response=%s", req.url, req.text) return CONTINUE
def pkt_in_handler(self, dp_id, inport, ofp_reason, total_frame_len, buffer_id, packet): attrs = util.extract_flow(packet) print "Pakcet in received "+str(inport)+ " " +packet_utils.ip_to_str(attrs['nw_dst']) # print attrs # print ("type:%s %s > %s %s:%d > %s:%d "%( # packet_utils.ethtype_to_str(attrs['dl_type']), # packet_utils.mac_to_str(attrs['dl_src']), # packet_utils.mac_to_str(attrs['dl_dst']), # packet_utils.ip_to_str(attrs['nw_src']), attrs['tp_src'], # packet_utils.ip_to_str(attrs['nw_dst']), attrs['tp_dst'] # )) return CONTINUE
def __flow_entry_build(self, src_ip, dst_ip, in_port, packet): """ Build OpenFlow entries """ assert(src_ip is not None) assert(dst_ip is not None) assert(in_port is not None) assert(packet is not None) try: attributes = extract_flow(packet) attributes[IN_PORT] = in_port attributes[NW_SRC] = src_ip attributes[NW_DST] = dst_ip return attributes except Exception: raise
def matchFlowTable(self, pkt, inport): pkt_attrs = of_util.extract_flow(pkt) pkt_attrs[core.IN_PORT] = inport self.communicationObjectUsed(self, "flowTable_read", pkt_attrs) matching_entries = [] for entry in self.flow_table: if self.packetIsMatching(pkt, inport, entry.attrs): self.log.debug("*FTE: " + str(entry)) matching_entries.append(entry) else: self.log.debug("FTE: " + str(entry)) if len(matching_entries) == 0: # no match return False elif len(matching_entries) > 1: # multiple matches, select on priority matching_entries.sort(key=lambda x: x.priority, reverse=True) entry = matching_entries[0] self.processActions(pkt, entry.actions, inport) return True
def handle_dns_response(self, dpid, inport, ofp_reason, total_frame_len, buffer_id, packet): eaddr = util.convert_to_eaddr(packet.dst) dnsh = packet.find('dns') if not self.permit_ether_addr(eaddr): print "Dropping DNS Response Packet - MAC Address not allowed" return STOP if not dnsh: print "\n\n +++ +++ Invalid DNS Response packet: ", dnsh print packet print dir(packet) print packet.__dict__ print "\n\n" return CONTINUE print "DNS Response packet:", dnsh print "*******", dir(dnsh) print "*******", dnsh.__dict__ for answer in dnsh.answers: if answer.qtype in dns.rrtype_to_str: domain = answer.name + ":" + dns.rrtype_to_str[answer.qtype] else: domain = answer.name + ":" + str(answer.qtype) if domain not in Homework.st['domains']: Homework.st['domains'][domain] = set([str(answer.rddata)]) else: Homework.st['domains'][domain].add(str(answer.rddata)) flow = util.extract_flow(packet) Homework.install_datapath_flow( dpid, flow, 3, 10, [[openflow.OFPAT_OUTPUT, [-1, openflow.OFPP_NORMAL]]], buffer_id, openflow.OFP_DEFAULT_PRIORITY, inport, dnsh.arr ) return CONTINUE
def packetIsMatching(self, pkt, inport, attrs): """Checks whether a packet is matching a specific table entry attrs is a dictionary of attributes to match, missing attributes are considered wildcarded """ pkt_attrs = of_util.extract_flow(pkt) pkt_attrs[core.IN_PORT] = inport skip_nw_src = False for a in attrs: if a == "nw_src_n_wild": mask = int(0xffffffff << attrs[a]) # see openflow.h in NOX for this definition of mask if pkt_attrs[core.NW_SRC] & mask != attrs["nw_src"] & mask: return False else: skip_nw_src = True elif a == "nw_src" and skip_nw_src: continue elif attrs[a] != pkt_attrs[a]: # If this throws an exception, we have an usupported attribute return False return True
def pkt_in_handler(self, dp_id, inport, ofp_reason, total_frame_len, buffer_id, packet): attrs = util.extract_flow(packet) print "Pakcet in received "+str(inport)+ " " +packet_utils.ip_to_str(attrs['nw_dst']) return CONTINUE