def generate_trace_pkt(entries, color, r_id, my_domain, interdomain=False): ''' Receives the REST/PUT to generate a PacketOut data needs to be serialized template_trace.json is an example ''' trace = {} switch = {} eth = {} ip = {} tp = {} # TODO Validate for dl_vlan. If empty, return error. dpid, in_port = 0, 65532 if interdomain: dl_src = color else: dl_src = "ee:ee:ee:ee:ee:%s" % int(color,2) dl_dst = "ca:fe:ca:fe:ca:fe" dl_vlan, dl_type = 100, 2048 nw_src, nw_dst, nw_tos = '127.0.0.1', '127.0.0.1', 0 tp_src, tp_dst = 1, 1 try: trace = entries['trace'] switch = trace['switch'] eth = trace['eth'] except: pass try: ip = trace['ip'] except: pass try: tp = trace['tp'] except: pass if len(switch) > 0: dpid, in_port = prepare_switch(switch, dpid, in_port) if len(eth) > 0: dl_src, dl_dst, dl_vlan, dl_type = prepare_ethernet(eth, dl_src, dl_dst, dl_vlan, dl_type) # if len(ip) > 0: nw_src, nw_dst, nw_tos = prepare_ip(ip, nw_src, nw_dst, nw_tos) # if len(tp) > 0: tp_src, tp_dst = prepare_tp(tp, tp_src, tp_dst) pkt = packet.Packet() eth_pkt = ethernet.ethernet(dst=dl_dst, src=dl_src, ethertype=33024) vlan_pkt = vlan.vlan(vid=dl_vlan, ethertype=int(dl_type)) pkt.add_protocol(eth_pkt) pkt.add_protocol(vlan_pkt) if int(dl_type) == 2048: ip_pkt = ipv4.ipv4(dst=str(nw_dst), src=str(nw_src), tos=nw_tos, proto=6) pkt.add_protocol(ip_pkt) tp_pkt = tcp.tcp(dst_port=int(tp_dst), src_port=int(tp_src)) pkt.add_protocol(tp_pkt) msg = TraceMsg(r_id, my_domain) if interdomain: msg.set_interdomain() pkt.add_protocol(msg.data()) pkt.serialize() return in_port, pkt
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'] pkt = packet.Packet(msg.data) # self.logger.info("packet info - %s" , pkt) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether_types.ETH_TYPE_LLDP: # 忽略 LLDP 包 return dst = eth.dst src = eth.src dpid = datapath.id # 检查ARP包和DHCP包 pkt_arp = pkt.get_protocol(arp.arp) pkt_dhcp = pkt.get_protocol(dhcp.dhcp) # ARP 包, 调用 arp_handler if pkt_arp: self._arp_handler(pkt_arp, msg) return # DHCP 包, 调用 dhcp_handler if pkt_dhcp: self._dhcp_handler(pkt_dhcp, msg) self.mac_to_port.setdefault(dpid, {}) # 学习一个mac地址,以避免下次洪范。 self.mac_to_port[dpid][src] = in_port # 目标 MAC 是否在 MAC-IP 映射表中 if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time # if out_port != ofproto.OFPP_FLOOD: # match = parser.OFPMatch(in_port=in_port, eth_dst=dst, eth_src=src) # # verify if we have a valid buffer_id, if yes avoid to send both # # flow_mod & packet_out # if msg.buffer_id != ofproto.OFP_NO_BUFFER: # self.add_flow(datapath, 1, match, actions, msg.buffer_id) # return # else: # self.add_flow(datapath, 1, match, actions) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
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'] pkt = packet.Packet(msg.data) eth = pkt.get_protocol(ethernet.ethernet) dst = eth.dst src = eth.src dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) #print "nodes" #print self.net.nodes() #print "edges" #print self.net.edges() #self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) if src not in self.net: self.net.add_node(src) self.net.add_edge(dpid, src, {'port': in_port}) self.net.add_edge(src, dpid) if dst in self.net: #print (src in self.net) #print nx.shortest_path(self.net,1,4) #print nx.shortest_path(self.net,4,1) #print nx.shortest_path(self.net,src,4) path = nx.shortest_path(self.net, src, dst) next = path[path.index(dpid) + 1] out_port = self.net[dpid][next]['port'] else: out_port = ofproto.OFPP_FLOOD actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: self.add_flow(datapath, in_port, dst, actions) out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions) datapath.send_msg(out)
def _packet_in_handler(self, ev): # If you hit this you might want to increase # the "miss_send_length" of your switch if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] igmp_in = pkt.get_protocol(igmp.igmp) #udp = pkt.get_protocol(udp.udp) udp = pkt.protocols[2] print(self.grp_to_mac) print("\n") print(pkt) print(udp) print("\n") print(igmp_in) eth_type = eth.ethertype dst = eth.dst src = eth.src print("Ethertype", eth_type) dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) if (igmp_in): #Check if pkt is IGMP control #grp_record = igmp_in.records[0] #grp_addr = grp_record.address grp_addr = igmp_in.address print(grp_addr) #mc = addrconv.ipv4.text_to_bin(grp_addr) #print(mc) #mac_grp_addr = get_mac_address(ip=grp_addr) #print(mac_grp_addr) #match = parser.OFPMatch(eth_dst=dst, eth_type=0x0800,ip_proto=17) actions = [] #if(src=='00:00:00:00:00:01'): # print("IGMPv2 query") # return #if(igmp_in.msgtype==0x22 and grp_record.type_==4): if (igmp_in.msgtype == 0x16): print("IGMPv3 Report - Join") #Add in_port to grp_to_mac table if in_port not in self.grp_to_mac[grp_addr]: self.grp_to_mac[grp_addr].append(in_port) for port in self.grp_to_mac[grp_addr]: #match = datapath.ofproto_parser.OFPMatch(ipv4_dst=grp_addr) actions.append(parser.OFPActionOutput(port)) print(actions) match = parser.OFPMatch(eth_type=0x0800, ipv4_dst=grp_addr) print(match) self.add_flow(datapath, 1, match, actions, msg.buffer_id) print("Flow added") print(self.grp_to_mac) else: print("Flow already added - duplicate message") #elif(igmp_in.msgtype==0x22 and grp_record.type_==3): elif (igmp_in.msgtype == 0x17): print("IGMPv3 Report - Leave") if in_port in self.grp_to_mac[grp_addr]: #match = datapath.ofproto_parser.OFPMatch(in_port=in_port) #actions.append(parser.OFPActionOutput(in_port)) match = datapath.ofproto_parser.OFPMatch(eth_type=0x0800, ipv4_dst=grp_addr) print(actions) self.del_flow(datapath, 1, match, actions, msg.buffer_id) print(actions) #self.del_flow(datapath, 1, actions) self.grp_to_mac[grp_addr].remove(in_port) print(self.grp_to_mac.values()) if len(self.grp_to_mac[grp_addr]) == 0: print("Empty") del self.grp_to_mac[grp_addr] else: print("Still other clients") print("Flow updated") print(self.grp_to_mac) elif (not igmp_in and dst[:8] == '01:00:5e'): #Check if pkt is IGMP data print("IGMP DATA!") else: #Normal l2 switching #learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port print(self.mac_to_port) if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: match = parser.OFPMatch(in_port=in_port, eth_dst=dst, eth_src=src) # verify if we have a valid buffer_id, if yes avoid to send both # flow_mod & packet_out if msg.buffer_id != ofproto.OFP_NO_BUFFER: self.add_flow(datapath, 1, match, actions, msg.buffer_id) return else: self.add_flow(datapath, 1, match, actions) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
def _packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath dpid = datapath.id parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] arp_pkt = pkt.get_protocol(arp.arp) ip_pkt = pkt.get_protocol(ipv4.ipv4) ip_pkt_6 = pkt.get_protocol(ipv6.ipv6) if isinstance(ip_pkt_6, ipv6.ipv6): actions = [] match = parser.OFPMatch(eth_type=ether.ETH_TYPE_IPV6) self.add_flow(datapath, 0, 1, match, actions) return if isinstance(arp_pkt, arp.arp): self.logger.debug("ARP processing") if self.mac_learning(dpid, eth.src, in_port) is False: self.logger.debug("ARP packet enter in different ports") return self.arp_forwarding(msg, arp_pkt.src_ip, arp_pkt.dst_ip, eth) if isinstance(ip_pkt, ipv4.ipv4): self.logger.debug("IPV4 processing") mac_to_port_table = self.mac_to_port.get(dpid) if mac_to_port_table is None: self.logger.info("Dpid is not in mac_to_port") return out_port = None if eth.dst in mac_to_port_table: if dpid == 1 and in_port == 1: if self.FLAGS is True: self.send_group_mod(datapath) self.logger.info("send_group_mod") self.FLAGS = False actions = [parser.OFPActionGroup(group_id=50)] match = parser.OFPMatch(in_port=in_port, eth_type=eth.ethertype, ipv4_src=ip_pkt.src) self.add_flow(datapath, 0, 3, match, actions) # asign output at 2 self.send_packet_out(datapath, msg.buffer_id, in_port, 2, msg.data) else: #Normal flows out_port = mac_to_port_table[eth.dst] actions = [parser.OFPActionOutput(out_port)] match = parser.OFPMatch(in_port=in_port, eth_dst=eth.dst, eth_type=eth.ethertype) self.add_flow(datapath, 0, 1, match, actions) self.send_packet_out(datapath, msg.buffer_id, in_port, out_port, msg.data) else: if self.mac_learning(dpid, eth.src, in_port) is False: self.logger.debug("IPV4 packet enter in different ports") return else: self.flood(msg)
def _packet_in_handler(self, ev): # If you hit this you might want to increase # the "miss_send_length" of your switch if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether_types.ETH_TYPE_LLDP: return dst = eth.dst src = eth.src dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: # check IP Protocol and create a match for IP if eth.ethertype == ether_types.ETH_TYPE_IP: ip = pkt.get_protocol(ipv4.ipv4) srcip = ip.src dstip = ip.dst protocol = ip.proto # if ICMP Protocol if protocol == in_proto.IPPROTO_ICMP: t = pkt.get_protocol(icmp.icmp) match = parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, ipv4_src=srcip, ipv4_dst=dstip, ip_proto=protocol, icmpv4_code=t.code, icmpv4_type=t.type) # if TCP Protocol elif protocol == in_proto.IPPROTO_TCP: t = pkt.get_protocol(tcp.tcp) match = parser.OFPMatch( eth_type=ether_types.ETH_TYPE_IP, ipv4_src=srcip, ipv4_dst=dstip, ip_proto=protocol, tcp_src=t.src_port, tcp_dst=t.dst_port, ) # If UDP Protocol elif protocol == in_proto.IPPROTO_UDP: u = pkt.get_protocol(udp.udp) match = parser.OFPMatch( eth_type=ether_types.ETH_TYPE_IP, ipv4_src=srcip, ipv4_dst=dstip, ip_proto=protocol, udp_src=u.src_port, udp_dst=u.dst_port, ) # verify if we have a valid buffer_id, if yes avoid to send both # flow_mod & packet_out if msg.buffer_id != ofproto.OFP_NO_BUFFER: self.add_flow(datapath, 1, match, actions, msg.buffer_id, idle=20, hard=100) return else: self.add_flow(datapath, 1, match, actions, idle=20, hard=100) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
def switch_features_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) ip = pkt.get_protocols(ipv4.ipv4) eth = pkt.get_protocol(ethernet.ethernet) mac_dst = eth.dst mac_src = eth.src dpid = format(datapath.id, "d").zfill(16) self.mac_to_port.setdefault(dpid, {}) self.logger.info("packet in %s %s %s %s", dpid, mac_src, mac_dst, in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][mac_src] = in_port pod = int(ip.dst[4]) switch_no = int(ip.dst[6]) host_no = int(ip.dst[8]) switch_pod = int(dpid[11]) switch_no_dpid = int(dpid[13]) if mac_dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][mac_dst] else: if switch_pod == k: # determine if it is core switch out_port = pod else: if switch_no_dpid == 2 or switch_no_dpid == 3: # determine if it is aggregation switch if switch_pod == pod: # host in same pod out_port = switch_no else: # host in different pod out_port = ((host_no - 2 + switch_no_dpid) % (k / 2)) + (k / 2) else: # it is edge switch if switch_pod == pod: # host in same pod if switch_no == switch_no_dpid: # host under same switch out_port = switch_no else: # host under different switch out_port = ((host_no - 2 + switch_no_dpid + (k / 2)) % (k / 2)) + (k / 2) else: # host in different pod out_port = ((host_no - 2 + switch_no_dpid + (k / 2)) % (k / 2)) + (k / 2) actions = [parser.OFPActionOutput(out_port)] if out_port != ofproto.OFPP_FLOOD: match = parser.OFPMatch(in_port=in_port, eth_dst=mac_dst, eth_src=mac_src) # verify if we have a valid buffer_id, if yes avoid to send both # flow_mod & packet_out if msg.buffer_id != ofproto.OFP_NO_BUFFER: self.add_flow(datapath, 1, match, actions, msg.buffer_id) return else: self.add_flow(datapath, 1, match, actions) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
def _packet_in_handler(self, ev): # If you hit this you might want to increase # the "miss_send_length" of your switch if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] #@Thien - testing #ipv4_test = pkt.get_protocols(ipv4.ipv4) if eth.ethertype == ether_types.ETH_TYPE_LLDP: # ignore lldp packet return dst = eth.dst src = eth.src #@Thien - testing #ipv4_src_addr = ipv4_test.src #ipv4_dst_addr = ipv4_test.dst # dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) #self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) #@Thien - testing #self.logger.info("packet in %s %s %s %s", dpid, ipv4_src_addr, ipv4_dst_addr, in_port) # # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: #@Thien: 2016-05-22 match = None #nw_tos=None nw_src = None nw_dst = None nw_proto = None tp_src = None tp_dst = None ip = pkt.get_protocol(ipv4.ipv4) if ip is not None: nw_src = ip.src nw_dst = ip.dst nw_proto = ip.proto #self.logger.info("ip_src=%s", nw_src) #self.logger.info("ip_dst=%s", nw_dst) #self.logger.info("ip_proto=%s", nw_proto) #nw_tos = ip.tos t = pkt.get_protocol(tcp.tcp) if t is not None: tp_src = t.src_port tp_dst = t.dst_port match = parser.OFPMatch( ipv4_src=nw_src, ipv4_dst=nw_dst, ip_proto=nw_proto, tcp_src=tp_src, tcp_dst=tp_dst, eth_type=ether_types.ETH_TYPE_IP) #eth.ethertype) #self.logger.info("Added flow entry - IPv4 packet - TCP: %s %s %s %s %s", nw_src, nw_dst, nw_proto, tp_src, tp_dst) #self.logger.info("Inserted flow entry: %s %s %s %s %s", nw_src, nw_dst, nw_proto, tp_src, tp_dst) u = pkt.get_protocol(udp.udp) if u is not None: tp_src = u.src_port tp_dst = u.dst_port match = parser.OFPMatch( ipv4_src=nw_src, ipv4_dst=nw_dst, ip_proto=nw_proto, udp_src=tp_src, udp_dst=tp_dst, eth_type=ether_types.ETH_TYPE_IP) #eth.ethertype) #self.logger.info("Added flow entry - IPv4 packet - UDP: %s %s %s %s %s", nw_src, nw_dst, nw_proto, tp_src, tp_dst) #self.logger.info("Inserted flow entry: %s %s %s %s %s", nw_src, nw_dst, nw_proto, tp_src, tp_dst) s = pkt.get_protocol(sctp.sctp) if s is not None: tp_src = s.src_port tp_dst = s.dst_port match = parser.OFPMatch( ipv4_src=nw_src, ipv4_dst=nw_dst, ip_proto=nw_proto, udp_src=tp_src, udp_dst=tp_dst, eth_type=ether_types.ETH_TYPE_IP) #eth.ethertype) #self.logger.info("Added flow entry - IPv4 packet - SCTP: %s %s %s %s %s", nw_src, nw_dst, nw_proto, tp_src, tp_dst) #self.logger.info("Inserted flow entry: %s %s %s %s %s", nw_src, nw_dst, nw_proto, tp_src, tp_dst) ic = pkt.get_protocol(icmp.icmp) if ic is not None: tp_src = ic.type tp_dst = ic.code match = parser.OFPMatch( ipv4_src=nw_src, ipv4_dst=nw_dst, ip_proto=nw_proto, icmpv4_type=tp_src, icmpv4_code=tp_dst, eth_type=ether_types.ETH_TYPE_IP) #eth.ethertype) #self.logger.info("Added flow entry for IPv4 packet - ICMP: %s %s %s %s %s", nw_src, nw_dst, nw_proto, tp_src, tp_dst) #self.logger.info("Inserted flow entry: %s %s %s %s %s", nw_src, nw_dst, nw_proto, tp_src, tp_dst) #------- #match = parser.OFPMatch(ipv4_src=nw_src, ipv4_dst=nw_dst, ip_proto=nw_proto, eth_type=eth.ethertype) #match = parser.OFPMatch(in_port=in_port, ipv4_src=nw_src, ipv4_dst=nw_dst, ip_proto=nw_proto, eth_type=eth.ethertype) #tcp_src=tp.src_port, tcp_dst=tp.dst_port) #match = parser.OFPMatch(in_port=in_port, ipv4_dst='192.168.1.101')#in_port=in_port, eth_src=src, eth_dst=dst if match is not None: #self.logger.info("IPv4 packet:") self.n_flows += 1 #number of flow entries increased by 1. if (self.n_flows % 100 == 0): self.logger.info("#flow-entries installed: %d", self.n_flows) ### if msg.buffer_id != ofproto.OFP_NO_BUFFER: self.add_flow(datapath, 2, match, actions, msg.buffer_id) return else: self.add_flow(datapath, 2, match, actions) #self.logger.info("New flow entry added to switch") else: self.non_ipv4_packet_count += 1 if (self.non_ipv4_packet_count % 10 == 0): self.logger.info("Non-IPv4 packets (ignored): %d", self.non_ipv4_packet_count) #return #match = parser.OFPMatch(in_port=in_port, eth_src=src, eth_dst=dst) #Thien-testing #match = self.getFullMatch(msg) #match = self.getFullMatch(msg, in_port) # verify if we have a valid buffer_id, if yes avoid to send both # flow_mod & packet_out #if msg.buffer_id != ofproto.OFP_NO_BUFFER: # self.add_flow(datapath, 1, match, actions, msg.buffer_id) # return #else: # self.add_flow(datapath, 1, match, actions) #self.logger.info("New flow entry added to switch") data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
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'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether_types.ETH_TYPE_LLDP: # ignore lldp packet return dst = eth.dst src = eth.src pkt_arp = pkt.get_protocols(arp.arp) pkt_ipv4 = pkt.get_protocol(ipv4.ipv4) print "pkt_ip####", pkt_ipv4 ipProto = None dstIp = None srcIp = None if pkt_ipv4: # ip_str = pkt_ipv4[0] ipProto = pkt_ipv4.proto dstIp = pkt_ipv4.dst srcIp = pkt_ipv4.src self.logger.info("packet IP info %s %s %s", dstIp, srcIp, ipProto) dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] actions_drop = [] actions_forward = [parser.OFPActionOutput(out_port)] if pkt_ipv4: #matched_rule = self.comparison.compare(PROTOCOLS[ipProto], srcIp, dstIp) #print "matched_rule: ", matched_rule if ipProto == 2: # for igmp message pass elif ipProto == 6: #tcp pkt pkt_tcp = pkt.get_protocol(tcp.tcp) print "####pkt_tcp", pkt_tcp tcp_sport = pkt_tcp.src_port tcp_dport = pkt_tcp.dst_port matched_rule = self.comparison.compare(PROTOCOLS[ipProto], srcIp, dstIp, tcp_sport, tcp_dport) print "matched_rule: ", matched_rule if not matched_rule: return if matched_rule['target'] == 'ACCEPT': match = parser.OFPMatch(ipv4_src=srcIp, ipv4_dst=dstIp, ip_proto=ipProto, tcp_src=tcp_sport, tcp_dst=tcp_dport, eth_type=0x800) self.add_flow(datapath, 1, match, actions_forward, LIFETIME_ROUTE) # accept, forward action elif matched_rule['target'] == 'DROP': match = parser.OFPMatch(ipv4_src=srcIp, ipv4_dst=dstIp, ip_proto=ipProto, tcp_src=tcp_sport, tcp_dst=tcp_dport, eth_type=0x800) self.add_flow(datapath, 1, match, actions_drop, LIFETIME_ROUTE) else: # for pkts without a matched rule return elif ipProto == 17: #tcp pkt pkt_tcp = pkt.get_protocol(udp.udp) print "####pkt_udp", pkt_udp udp_sport = pkt_udp.src_port udp_dport = pkt_udp.dst_port matched_rule = self.comparison.compare(PROTOCOLS[ipProto], srcIp, dstIp, udp_sport, tcp_dport) print "matched_rule: ", matched_rule if not matched_rule: return if matched_rule['target'] == 'ACCEPT': match = parser.OFPMatch(ipv4_src=srcIp, ipv4_dst=dstIp, ip_proto=ipProto, udp_src=udp_sport, udp_dst=tcp_dport, eth_type=0x800) self.add_flow(datapath, 1, match, actions_forward, LIFETIME_ROUTE) # accept, forward action elif matched_rule['target'] == 'DROP': match = parser.OFPMatch(ipv4_src=srcIp, ipv4_dst=dstIp, ip_proto=ipProto, udp_src=udp_sport, udp_dst=udp_dport, eth_type=0x800) self.add_flow(datapath, 1, match, actions_drop, LIFETIME_ROUTE) else: # for pkts without a matched rule return else: matched_rule = self.comparison.compare(PROTOCOLS[ipProto], srcIp, dstIp) print "matched_rule: ", matched_rule if matched_rule['target'] == 'ACCEPT': match = parser.OFPMatch(ipv4_src=srcIp, ipv4_dst=dstIp, ip_proto=ipProto, eth_type=0x800) self.add_flow(datapath, 1, match, actions_forward, LIFETIME_ROUTE) # accept, forward action elif matched_rule['target'] == 'DROP': match = parser.OFPMatch(ipv4_src=srcIp, ipv4_dst=dstIp, ip_proto=ipProto, eth_type=0x800) self.add_flow(datapath, 1, match, actions_drop, LIFETIME_ROUTE) else: # for pkts without a matched rule return data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
def _packet_in_handler(self, ev): """ Hanle the packet in packet, and register the access info. """ if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) # print "myapp" msg = ev.msg datapath = msg.datapath # ofproto = datapath.ofproto # parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[ 0] # pkt.get_protocols(ethernet.ethernet)是个列表,列表里只有一个元素,用[0]直接取出元素 # 所有的包都有以太网头部,所以能直接get,但是ip等协议需要判断是否存在 # 包过滤开始 if eth.ethertype == ether_types.ETH_TYPE_LLDP or eth.ethertype == ether_types.ETH_TYPE_IPV6: # ignore lldp packet return dst = eth.dst src = eth.src # dpid = datapath.id if dst == ETHERNET_GROUP_MULTICAST: # ignore mDNS packet return if eth.ethertype == ether_types.ETH_TYPE_IP and dst == ETHERNET_MULTICAST: # DHCP广播包, IP=0x0800 # drop DHCP packet self.logger.debug("Drop ip_type and eth_dst == ff:ff:ff:ff:ff:ff") out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=datapath.ofproto.OFP_NO_BUFFER, in_port=in_port, actions=[], data=None) datapath.send_msg(out) return header_list = dict( (p.protocol_name, p) for p in pkt.protocols if type(p) != str) # print "header_list:", header_list if IPv4 in header_list: ipv4_packet = pkt.get_protocols(ipv4.ipv4)[0] # print "pkt.get_protocols(ipv4.ipv4)[0]:", pkt.get_protocols(ipv4.ipv4)[0], '\n' if ipv4_packet.src == "0.0.0.0" or ipv4_packet.dst == "255.255.255.255": # DHCP广播包 self.logger.debug( "Drop ip_src == 0.0.0.0 or ip_dst == 255.255.255.255") out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=datapath.ofproto.OFP_NO_BUFFER, in_port=in_port, actions=[], data=None) datapath.send_msg(out) return # 包过滤结束 # 获取access info arp_pkt = pkt.get_protocol(arp.arp) ip_pkt = pkt.get_protocol(ipv4.ipv4) # 如果没有这个包就赋值None # print "ip_pkt:", ip_pkt, '\n' if arp_pkt: # print 'arp' arp_src_ip = arp_pkt.src_ip # arp_dst_ip = arp_pkt.dst_ip mac = arp_pkt.src_mac # Record the access info self.register_access_info(datapath.id, in_port, arp_src_ip, mac) elif ip_pkt: # print 'ipv4' src_ip = ip_pkt.src # dst_ip = ip_pkt.dst mac = src # Record the access info self.register_access_info(datapath.id, in_port, src_ip, mac)
def getFullMatch(self, msg, in_port): datapath = msg.datapath parser = datapath.ofproto_parser #in_port=None dl_src = None dl_dst = None dl_vlan = None dl_vlan_pcp = None dl_type = None nw_tos = None nw_proto = None nw_src = None nw_dst = None tp_src = None tp_dst = None #in_port = msg.in_port #in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) #eth = pkt.get_protocol(ethernet.ethernet) eth = pkt.get_protocols(ethernet.ethernet) dl_src = eth.src dl_dst = eth.dst #dl_type = eth.ethertype vl = pkt.get_protocol(vlan.vlan) if vl is not None: dl_vlan = vl.vid dl_vlan_pcp = vl.pcp #dl_type = vl.ethertype ip = pkt.get_protocol(ipv4.ipv4) if ip is not None: nw_src = ip.src nw_dst = ip.dst nw_proto = ip.proto nw_tos = ip.tos t = pkt.get_protocol(tcp.tcp) if t is not None: tp_src = t.src_port tp_dst = t.dst_port u = pkt.get_protocol(udp.udp) if u is not None: tp_src = u.src_port tp_dst = u.dst_port ic = pkt.get_protocol(icmp.icmp) if ic is not None: tp_src = ic.type tp_dst = ic.code a = pkt.get_protocol(arp.arp) if a is not None: nw_src = a.src_ip nw_dst = a.dst_ip nw_proto = a.opcode match = parser.OFPMatch( dl_src=mac.haddr_to_bin(dl_src), #dl_src, dl_dst=mac.haddr_to_bin(dl_dst), # dl_dst, #dl_vlan=dl_vlan, #dl_vlan_pcp=dl_vlan_pcp, #dl_type=dl_type, #nw_tos=nw_tos, #nw_proto=nw_proto, #nw_src=self.ipv4_to_int(nw_src), #nw_dst=self.ipv4_to_int(nw_dst), #tp_src=tp_src, #tp_dst=tp_dst, in_port=in_port) return match
def arp_forwarding(self, msg, arp_header, from_datapath, ether, ethernet_src, ethernet_dst, in_port): ofproto = from_datapath.ofproto arp_src_ip = arp_header.src_ip arp_dst_ip = arp_header.dst_ip arp_src_mac = arp_header.src_mac arp_dst_mac = arp_header.dst_mac if ethernet_dst == mac.BROADCAST_STR: # Handle ARP broadcast self.logger.info( 'This is ARP broadcast received at port {} of switch {} from IP {}, ARP Src Mac {}, ethernet src {} to IP {}, ARP Destn Mac {}, ethernet dst {}' .format(in_port, from_datapath.id, arp_src_ip, arp_src_mac, ethernet_src, arp_dst_ip, arp_dst_mac, ethernet_dst)) if self.ip_mac_table.get( arp_src_ip ) == None: # No src ip found, so storing it in the table self.logger.info( "****No mac entry found for IP. adding entry.....****") self._register_host_entry(arp_src_ip, arp_src_mac, from_datapath.id, in_port) if self.ip_mac_table.get( arp_dst_ip ) != None: #dst_ip exist in ip_mac_table, so proxy it ARP_Reply = packet.Packet() mac_from_table = self.ip_mac_table.get(arp_dst_ip) ARP_Reply.add_protocol( ethernet.ethernet(ethertype=ether.ethertype, dst=ethernet_src, src=mac_from_table)) ARP_Reply.add_protocol( arp.arp(opcode=arp.ARP_REPLY, src_mac=mac_from_table, src_ip=arp_dst_ip, dst_mac=arp_src_mac, dst_ip=arp_src_ip)) ARP_Reply.serialize() from_datapath.send_msg( self._build_packet_out(from_datapath, ofproto.OFP_NO_BUFFER, ofproto.OFPP_CONTROLLER, in_port, ARP_Reply.data)) self.logger.info("****Found mac entry for IP. Proxy-ing****") else: #no dst_ip in ip_mac_table, flood for dpid_port_tup in self.dpid_port_set: if dpid_port_tup not in self.ip_dpidport.values(): self.logger.info( "********Flooding {}***********".format( dpid_port_tup)) datapath = self.datapath_list[dpid_port_tup[0]] datapath.send_msg( self._build_packet_out(datapath, ofproto.OFP_NO_BUFFER, ofproto.OFPP_CONTROLLER, dpid_port_tup[1], msg.data)) else: # if ARP packet and its a reply self.logger.info( 'This is ARP reply received at port {} of switch {} from IP {}, ARP Src Mac {}, ethernet src {} to IP {}, ARP Destn Mac {}, ethernet dst {}' .format(in_port, from_datapath.id, arp_src_ip, arp_src_mac, ethernet_src, arp_dst_ip, arp_dst_mac, ethernet_dst)) self._register_host_entry(arp_src_ip, arp_src_mac, from_datapath.id, in_port) dpid_inport = self.ip_dpidport.get(arp_dst_ip) datapath = self.datapath_list[dpid_inport[0]] datapath.send_msg( self._build_packet_out(datapath, ofproto.OFP_NO_BUFFER, ofproto.OFPP_CONTROLLER, dpid_inport[1], msg.data)) self.logger.info( "*********************************************************************************************" ) return
def _packet_in_handler(self, ev): """ Called every time, when the controller receives a PACKET_IN message :type ev: ryu.controller.ofp_event.EventOFPPacketIn :return: None :rtype: None """ msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto dpid = datapath.id parser = datapath.ofproto_parser in_port = msg.match['in_port'] # create a Packet object out of the payload # TODO: 1) Create a Packet from the message data pkt = packet.Packet(msg.data) # TODO: 1) Why do we need obtain the information for four different protocols? eth = pkt.get_protocols(ethernet.ethernet)[0] ip_pkt = pkt.get_protocol(ipv4.ipv4) ip_pkt_6 = pkt.get_protocol(ipv6.ipv6) arp_pkt = pkt.get_protocol(arp.arp) # Don't do anything with IPV6 packets. if isinstance(ip_pkt_6, ipv6.ipv6): actions = [] match = parser.OFPMatch(ether_types.ETH_TYPE_IPV6) self.add_flow(datapath, 0, 1, actions) return # ARP Protcol if isinstance(arp_pkt, arp.arp): if self.mac_learning(dpid, eth.src, in_port) is False: self.logger.debug("ARP packet enter in different ports") return # Complete ARP protocol self.arp_forwarding(msg, arp_pkt.src_ip, arp_pkt.dst_ip, eth) # This is the focus of this workshop -> Process the IPv4 message if isinstance(ip_pkt, ipv4.ipv4): # find the switch in the mac_to_port table mac_to_port_table = self.mac_to_port.get(dpid) if mac_to_port_table is None: self.logger.info("Dpid is not in mac_to_port") return # source and destination mac address of the ethernet packet dst = eth.dst src = eth.src out_port = None # "Known destination MAC address" -> We have seen this before if dst in mac_to_port_table: #TODO: Final Questions - Why do we need the foolowing special cases? if dpid == 1 and in_port == 1: # This is the special case for host 1 only do create create the group the first time if self.FLAGS is True: self.send_group_mod(datapath) self.FLAGS = False #TODO: Final Questions - Where is this group defined? actions = [parser.OFPActionGroup(group_id=7)] #TODO: Final Questions - Why do we need to create groups and flows in different steps? match = parser.OFPMatch(in_port=in_port, eth_type=eth.ethertype, ipv4_src=ip_pkt.src) self.add_flow(datapath, 0, 3, actions) # asign output at 2 self.send_packet_out(datapath, msg.buffer_id, in_port, 2, msg.data) else: #Normal flows # "Install a flow to avoid packet_in next time"> out_port = mac_to_port_table[eth.dst] actions = [parser.OFPActionOutput(out_port)] match = parser.OFPMatch(in_port=in_port, eth_dst=eth.dst, eth_type=eth.ethertype) #Add the flow to the switch self.add_flow(datapath, 0, 1, actions) #Send packet to its destination self.send_packet_out(datapath, msg.buffer_id, in_port, out_port, msg.data) # "Unknown destination MAC address" else: # MAC is not Known if self.mac_learning(dpid, eth.src, in_port) is False: self.logger.debug("IPV4 packet enter in different ports") return else: # we don't know anything, so flood the network self.flood(msg)
def packet_in(self, event): """Process a packet-in event from the controller. :param event: The OpenFlow event. """ msg = event.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] if msg.table_id != self._table_id_l2: # print "l2switch packet " + str( packet.Packet(msg.data)) print( "l2switch not dealing with packet in messages from other tables. table id: " + str(msg.table_id)) return pkt = packet.Packet(msg.data) eth_head = pkt.get_protocols(ethernet.ethernet)[0] eth_dst = eth_head.dst eth_src = eth_head.src dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) print("{0}: Packet in\t-\tData-path ID: {1}, Source Ethernet: " "{2}, Destination Ethernet: {3}, Ingress switch port: " "{4}".format(self._APP_NAME, dpid, eth_src, eth_dst, in_port)) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][eth_src] = in_port if eth_dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][eth_dst] else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] inst = [ parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions) ] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: match = parser.OFPMatch(in_port=in_port, eth_dst=eth_dst) print("{0}: New flow\t-\t{1}".format(self._APP_NAME, pkt)) priority = 1000 # ofproto_v1_3.OFP_DEFAULT_PRIORITY # verify if we have a valid buffer_id, if yes avoid to send # both flow_mod & packet_out if msg.buffer_id != ofproto.OFP_NO_BUFFER: self._contr.add_flow(datapath, priority, match, inst, 0, self._table_id_l2, msg.buffer_id) return else: self._contr.add_flow(datapath, priority, match, inst, 0, self._table_id_l2) pass data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) self._contr.packet_out(datapath, out) print("l2switch packet out src: eth_src " + eth_src + ". eth_dst " + eth_dst)
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'] pkt = packet.Packet(msg.data) eth = pkt.get_protocol(ethernet.ethernet) arp_pkt = pkt.get_protocol(arp.arp) ip_pkt = pkt.get_protocol(ipv4.ipv4) if eth.ethertype == ether_types.ETH_TYPE_LLDP: return if pkt.get_protocol(ipv6.ipv6): match = parser.OFPMatch(eth_type=eth.ethertype) actions = [] self.add_flow(datapath, 1, match, actions) return None dst = eth.dst src = eth.src dpid = datapath.id if src not in self.hosts: self.hosts[src] = (dpid, in_port) out_port = ofproto.OFPP_FLOOD if eth.ethertype == ether_types.ETH_TYPE_IP: nw = pkt.get_protocol(ipv4.ipv4) if nw.proto == inet.IPPROTO_UDP: l4 = pkt.get_protocol(udp.udp) elif nw.proto == inet.IPPROTO_TCP: l4 = pkt.get_protocol(tcp.tcp) if eth.ethertype == ether_types.ETH_TYPE_IP and nw.proto == inet.IPPROTO_UDP: src_ip = nw.src dst_ip = nw.dst self.arp_table[src_ip] = src h1 = self.hosts[src] h2 = self.hosts[dst] self.logger.info(f" IP Proto UDP from: {nw.src} to: {nw.dst}") out_port = self.install_paths(h1[0], h1[1], h2[0], h2[1], src_ip, dst_ip, 'UDP', pkt) self.install_paths(h2[0], h2[1], h1[0], h1[1], dst_ip, src_ip, 'UDP', pkt) elif eth.ethertype == ether_types.ETH_TYPE_IP and nw.proto == inet.IPPROTO_TCP: src_ip = nw.src dst_ip = nw.dst self.arp_table[src_ip] = src h1 = self.hosts[src] h2 = self.hosts[dst] self.logger.info(f" IP Proto TCP from: {nw.src} to: {nw.dst}") out_port = self.install_paths(h1[0], h1[1], h2[0], h2[1], src_ip, dst_ip, 'TCP', pkt) self.install_paths(h2[0], h2[1], h1[0], h1[1], dst_ip, src_ip, 'TCP', pkt) elif eth.ethertype == ether_types.ETH_TYPE_IP and nw.proto == inet.IPPROTO_ICMP: src_ip = nw.src dst_ip = nw.dst self.arp_table[src_ip] = src h1 = self.hosts[src] h2 = self.hosts[dst] self.logger.info(f" IP Proto ICMP from: {nw.src} to: {nw.dst}") out_port = self.install_paths(h1[0], h1[1], h2[0], h2[1], src_ip, dst_ip, 'ICMP', pkt) self.install_paths(h2[0], h2[1], h1[0], h1[1], dst_ip, src_ip, 'ICMP', pkt) elif eth.ethertype == ether_types.ETH_TYPE_ARP: src_ip = arp_pkt.src_ip dst_ip = arp_pkt.dst_ip if arp_pkt.opcode == arp.ARP_REPLY: self.arp_table[src_ip] = src h1 = self.hosts[src] h2 = self.hosts[dst] self.logger.info( f" ARP Reply from: {src_ip} to: {dst_ip} H1: {h1} H2: {h2}" ) out_port = self.install_paths(h1[0], h1[1], h2[0], h2[1], src_ip, dst_ip, 'ARP', pkt) self.install_paths(h2[0], h2[1], h1[0], h1[1], dst_ip, src_ip, 'ARP', pkt) elif arp_pkt.opcode == arp.ARP_REQUEST: if dst_ip in self.arp_table: self.arp_table[src_ip] = src dst_mac = self.arp_table[dst_ip] h1 = self.hosts[src] h2 = self.hosts[dst_mac] self.logger.info( f" ARP Reply from: {src_ip} to: {dst_ip} H1: {h1} H2: {h2}" ) out_port = self.install_paths(h1[0], h1[1], h2[0], h2[1], src_ip, dst_ip, 'ARP', pkt) self.install_paths(h2[0], h2[1], h1[0], h1[1], dst_ip, src_ip, 'ARP', pkt) actions = [parser.OFPActionOutput(out_port)] data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
def packet_in_handler(self, ev): if self.virtual_ip == None or self.servers == None: return msg = ev.msg datapath = msg.datapath ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser in_port = msg.match['in_port'] dpid = datapath.id pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether.ETH_TYPE_ARP: arp_hdr = pkt.get_protocols(arp.arp)[0] if arp_hdr.dst_ip == self.virtual_ip and arp_hdr.opcode == arp.ARP_REQUEST: reply_pkt = self.formulate_arp_reply(arp_hdr.src_mac, arp_hdr.src_ip) actions = [ofp_parser.OFPActionOutput(in_port)] out = ofp_parser.OFPPacketOut(datapath=datapath, in_port=ofp.OFPP_ANY, data=reply_pkt.data, actions=actions, buffer_id=UINT32_MAX) datapath.send_msg(out) return # Only handle IPv4 traffic going forward elif eth.ethertype != ether.ETH_TYPE_IP: return iphdr = pkt.get_protocols(ipv4.ipv4)[0] # Only handle traffic destined to virtual IP if (iphdr.dst != self.virtual_ip): return # Only handle TCP traffic if iphdr.proto != inet.IPPROTO_TCP: return tcphdr = pkt.get_protocols(tcp.tcp)[0] valid_servers = [] for server in self.servers: outport = self.learning_switch.get_attachment_port( dpid, server['mac']) if outport != None: server['outport'] = outport valid_servers.append(server) total_servers = len(valid_servers) # If we there are no servers with location known, then skip if total_servers == 0: return # Round robin selection of servers index = self.server_index % total_servers selected_server_ip = valid_servers[index]['ip'] selected_server_mac = valid_servers[index]['mac'] selected_server_outport = valid_servers[index]['outport'] self.server_index += 1 print("Selected server %s" % selected_server_ip) ########### Setup route to server match = ofp_parser.OFPMatch(in_port=in_port, eth_type=eth.ethertype, eth_src=eth.src, eth_dst=eth.dst, ip_proto=iphdr.proto, ipv4_src=iphdr.src, ipv4_dst=iphdr.dst, tcp_src=tcphdr.src_port, tcp_dst=tcphdr.dst_port) if self.rewrite_ip_header: actions = [ ofp_parser.OFPActionSetField(eth_dst=selected_server_mac), ofp_parser.OFPActionSetField(ipv4_dst=selected_server_ip), ofp_parser.OFPActionOutput(selected_server_outport) ] else: actions = [ ofp_parser.OFPActionSetField(eth_dst=selected_server_mac), ofp_parser.OFPActionOutput(selected_server_outport) ] inst = [ ofp_parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions) ] cookie = random.randint(0, 0xffffffffffffffff) mod = ofp_parser.OFPFlowMod(datapath=datapath, match=match, idle_timeout=10, instructions=inst, buffer_id=msg.buffer_id, cookie=cookie) datapath.send_msg(mod) ########### Setup reverse route from server match = ofp_parser.OFPMatch(in_port=selected_server_outport, eth_type=eth.ethertype, eth_src=selected_server_mac, eth_dst=eth.src, ip_proto=iphdr.proto, ipv4_src=selected_server_ip, ipv4_dst=iphdr.src, tcp_src=tcphdr.dst_port, tcp_dst=tcphdr.src_port) if self.rewrite_ip_header: actions = ([ ofp_parser.OFPActionSetField(eth_src=self.virtual_mac), ofp_parser.OFPActionSetField(ipv4_src=self.virtual_ip), ofp_parser.OFPActionOutput(in_port) ]) else: actions = ([ ofp_parser.OFPActionSetField(eth_src=self.virtual_mac), ofp_parser.OFPActionOutput(in_port) ]) inst = [ ofp_parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions) ] cookie = random.randint(0, 0xffffffffffffffff) mod = ofp_parser.OFPFlowMod(datapath=datapath, match=match, idle_timeout=10, instructions=inst, cookie=cookie) datapath.send_msg(mod)
def _packet_in_handler(self, ev): # If you hit this you might want to increase # the "miss_send_length" of your switch if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] dst = eth.dst src = eth.src #self.pcap_writer.write_pkt(ev.msg.data) #Tamanho Janela TCP if eth.ethertype == ether_types.ETH_TYPE_IP: ipv4_temp = pkt.get_protocol(ipv4.ipv4) tcp_temp = pkt.get_protocol(tcp.tcp) udp_temp = pkt.get_protocol(udp.udp) #Clinte-To-Server self.logger.debug("*** Desencaplusando... ") # Tamanho Payloada payload = sys.getsizeof(pkt.data) self.logger.debug("(PKT) Tamanho Payload Pacote : %s ", payload) self.logger.debug("(IP): %s ", ipv4_temp) self.logger.debug("(IP) Code Protocol: %s ", ipv4_temp.proto) #comprimento Pacote Ip self.logger.debug("(IP) Comprimento : %s ", ipv4_temp.total_length) #Comprimento comp_cabecalho TCP self.logger.debug("(IP) Comprimento Cabecalho : %s ", ipv4_temp.header_length) self.logger.debug("============== /// ==============") self.logger.debug("(TCP): %s ", tcp_temp) self.logger.debug("(UDP): %s ", udp_temp) header_length_bytes = (ipv4_temp.header_length * 32) / 8 #Web if tcp_temp != None and self.hasFlagsClientToServerTCP( tcp_temp.bits, [TCP_SYN, TCP_ACK]) and ipv4_temp.proto == 6: self.logger.debug( "*** Info Extracting Attributes Choosen... ") self.logger.debug("(TCP) porta Origem: %s ", tcp_temp.src_port) self.logger.debug("(TCP) Porta Destino : %s ", tcp_temp.dst_port) self.logger.debug("(TCP) Tamanho Janela : %s ", tcp_temp.window_size) #dpid = datapath.id #self.host2host_instance.setdefault(dpid, {}) h2h = None key = src + dst if len(self.host2host_instance) > 0: if key in self.host2host_instance: h2h = self.host2host_instance[key] h2h.updateStateHostToHostByPacket( ipv4_temp.total_length, header_length_bytes) else: #self.host2host_instance.setdefault(src + dst, {}) h2h = host2host(tcp_temp.src_port, tcp_temp.dst_port, ipv4_temp.total_length, header_length_bytes, 6) self.host2host_instance[key] = h2h else: #self.host2host_instance.setdefault(src + dst, {}) h2h = host2host(tcp_temp.src_port, tcp_temp.dst_port, ipv4_temp.total_length, header_length_bytes, 6) self.host2host_instance[key] = h2h self.printInstanceH2H() #Classificador J48 Tree #host2host = host2host(tcp_temp.src_port, tcp_temp.dst_port,payload,ipv4_temp.total_length,6 ) #srcporta,dstporta, tamtotal_pacote_menor,tamtotal_pacote_maior,codigo_protocolo fluxo_classe = self.weka_decision_tree(h2h.src_port, h2h.dst_port, h2h.smaller_packet_size, h2h.bigger_packet_size, h2h.protocol_code) self.logger.debug("(Class): %s", fluxo_classe) if udp_temp != None and ipv4_temp.proto == UDP_CODE: self.logger.debug( "*** Info Extracting Attributes (UDP) Choosen... ") self.logger.debug("(UDP) porta Origem: %s ", udp_temp.src_port) self.logger.debug("(UDP) Porta Destino : %s ", udp_temp.dst_port) self.logger.debug("============== /// ==============") #dpid = datapath.id #self.host2host_instance.setdefault(dpid, {}) h2h = None key = src + dst if len(self.host2host_instance) > 0: if key in self.host2host_instance: h2h = self.host2host_instance[key] h2h.updateStateHostToHostByPacket( ipv4_temp.total_length, header_length_bytes) else: #self.host2host_instance.setdefault(src + dst, {}) h2h = host2host(udp_temp.src_port, udp_temp.dst_port, ipv4_temp.total_length, header_length_bytes, UDP_CODE) self.host2host_instance[key] = h2h else: #self.host2host_instance.setdefault(src + dst, {}) h2h = host2host(udp_temp.src_port, udp_temp.dst_port, ipv4_temp.total_length, header_length_bytes, UDP_CODE) self.host2host_instance[key] = h2h self.printInstanceH2H() #Classificador J48 Tree #host2host = host2host(tcp_temp.src_port, tcp_temp.dst_port,payload,ipv4_temp.total_length,6 ) #srcporta,dstporta, tamtotal_pacote_menor,tamtotal_pacote_maior,codigo_protocolo fluxo_classe = self.weka_decision_tree(h2h.src_port, h2h.dst_port, h2h.smaller_packet_size, h2h.bigger_packet_size, h2h.protocol_code) self.logger.debug("(Class): %s", fluxo_classe) dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) #self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: match = parser.OFPMatch(in_port=in_port, eth_dst=dst) # verify if we have a valid buffer_id, if yes avoid to send both # flow_mod & packet_out if msg.buffer_id != ofproto.OFP_NO_BUFFER: self.add_flow(datapath, 1, match, actions, msg.buffer_id) return else: self.add_flow(datapath, 1, match, actions) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
def _packet_in_handler(self, ev): if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether_types.ETH_TYPE_LLDP: # ignore lldp packet return dst = eth.dst src = eth.src dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: # check IP Protocol and create a match for IP if eth.ethertype == ether_types.ETH_TYPE_IP: ip = pkt.get_protocol(ipv4.ipv4) srcip = ip.src dstip = ip.dst match = parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, ipv4_src=srcip, ipv4_dst=dstip) # verify if we have a valid buffer_id, if yes avoid to send both # flow_mod & packet_out if msg.buffer_id != ofproto.OFP_NO_BUFFER: self.add_flow(datapath, 1, match, actions, msg.buffer_id) return else: self.add_flow(datapath, 1, match, actions, 0) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
def _packet_in_handler(self, ev): if ev.msg.msg_len < ev.msg.total_len: self.logger.info("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) incrcounterIn(1) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] dst = eth.dst src = eth.src pkt_ip = pkt.get_protocol(ipv4.ipv4) pkt_tcp = pkt.get_protocol(tcp.tcp) dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] if out_port != ofproto.OFPP_FLOOD: match = parser.OFPMatch(in_port=in_port,eth_dst=dst) if pkt_tcp is not None: #self.logger.info("Teste 2 - tcp packet") if msg.buffer_id != ofproto.OFP_NO_BUFFER: incrcounterInR(1) self.logger.info("Existe buffer_id %s", msg.buffer_id) self.caracterizar_flow(datapath, in_port, out_port, actions, pkt_ip, eth, pkt_tcp=pkt_tcp, buffer_id = msg.buffer_id) return else: incrcounterInR(1) self.logger.info("Nao existe buffer_id") self.caracterizar_flow(datapath, in_port, out_port, actions, pkt_ip, eth, pkt_tcp=pkt_tcp) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: print "buffer_id == OFP_NO_BUFFER" data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) if out is None: self.logger.info("out is None") else: self.logger.info("out is not None") datapath.send_msg(out)
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'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether_types.ETH_TYPE_LLDP: # ignore lldp packet return dst = eth.dst src = eth.src pkt_arp = pkt.get_protocols(arp.arp) pkt_ipv4 = pkt.get_protocols(ipv4.ipv4) print "pkt_ip####", pkt_ipv4 ipProto = None dstIp = None srcIp = None if pkt_ipv4: ip_str = pkt_ipv4[0] ipProto = ip_str.proto dstIp = ip_str.dst srcIp = ip_str.src self.logger.info("packet IP info %s %s %s", dstIp, srcIp, ipProto) dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD match1 = parser.OFPMatch(ipv4_dst='10.3.255.242', eth_type=0x800) match3 = parser.OFPMatch(ipv4_dst='10.3.255.244', eth_type=0x800) match2 = parser.OFPMatch(ipv4_dst='10.3.255.243', eth_type=0x800) ##actions_forward = [parser.OFPActionOutput(45)] actions_drop = [] actions = [parser.OFPActionOutput(out_port)] action1 = [parser.OFPActionOutput(45)] action2 = [parser.OFPActionOutput(46)] # install a flow to avoid packet_in next time #if out_port != ofproto.OFPP_FLOOD: if dstIp == '10.3.255.242': self.add_flow(datapath, 1, match1, action2) self.add_flow(datapath, 1, match3, action1) self.add_flow(datapath, 1, match2, actions_drop) #self.add_flow(datapath, 1, match2, actions_drop) #match = parser.OFPMatch(in_port=in_port, eth_dst=dst) #self.add_flo w(datapath, 1, match, actions) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
def _packet_in_handler(self, ev): # get information msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocol(ethernet.ethernet) if eth.ethertype == ether_types.ETH_TYPE_IPV6: # ignore IPV6 packet return if eth.dst == "ff:ff:ff:ff:ff:ff": # ignore broadcast packet return if eth.ethertype == ether_types.ETH_TYPE_LLDP: # ignore LLDP packet return # DEBUG # monitor the packet sent to the controller. dst = eth.dst src = eth.src dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) self.logger.info("%s packet in %s %s %s %s", eth.ethertype, dpid, src, dst, in_port) # learn a mac address to avoid FLOOD next time. # self.mac_to_port[dpid][src] = in_port # DEBUG : for debug , not userd in this app # topo learning # if src not in self.net: # self.net.add_node(src) # self.net.add_edge(dpid,src,{'port':in_port}) # self.net.add_edge(src,dpid) """ if dst in self.net: path=nx.shortest_path(self.net,src,dst) next=path[path.index(dpid)+1] out_port=self.net[dpid][next]['port'] else: out_port = ofproto.OFPP_FLOOD """ # actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] for tem_datapath in self.datapath_registered: tem_id = tem_datapath.id # add flow and group table1, 2 to all Aggregations & Edge layer switches. if list(str(tem_id))[0] == '2' or list(str(tem_id))[0] == '3': self.send_group_mod(tem_datapath) # print "send_group_mod to %d"%tem_id actions = [parser.OFPActionGroup(group_id=1)] match = parser.OFPMatch(in_port=3, eth_dst=dst) self.add_flow(tem_datapath, 4, match, actions) match = parser.OFPMatch(in_port=4, eth_dst=dst) self.add_flow(tem_datapath, 4, match, actions) actions = [parser.OFPActionGroup(group_id=2)] match = parser.OFPMatch(in_port=1, eth_dst=dst) self.add_flow(tem_datapath, 1, match, actions) match = parser.OFPMatch(in_port=2, eth_dst=dst) self.add_flow(tem_datapath, 1, match, actions) # send packet back to what it come from actions = [] self.send_packet_out(msg, actions)
def _packet_in_handler(self, ev): if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype != ether_types.ETH_TYPE_LLDP: # print("Message") # print(msg) print( "##################################################################################################################################################################################" ) print("Datapath") print(datapath.id) # print("Negotiated Protocol") # print(ofproto) # print("Parser") # print(parser) print("in_port") print("Message Match ") print(msg.match) print(in_port) # print("Message Data") # print(msg.data) print("Packet") print(pkt) print("Packet Type") print(type(pkt)) print("Eth") print(eth) if (pkt.get_protocols(arp.arp)): print("This is an ARP Message") pkt_arp = pkt.get_protocols(arp.arp)[0] arp_dst_ip = pkt_arp.dst_ip arp_src_ip = pkt_arp.src_ip arp_hlen = pkt_arp.hlen arp_hwtype = pkt_arp.hwtype arp_plen = pkt_arp.plen arp_proto = pkt_arp.proto arp_opcode = pkt_arp.opcode arp_src_mac = pkt_arp.src_mac if (eth.src not in self.topo.nodes()): self.topo.add_node(eth.src, ip=arp_src_ip) print("Chec############") self.arp_list.append(self.topo.node[eth.src]['ip']) self.topo.add_edge(datapath.id, eth.src) self.list_link.append((datapath.id, eth.src, { 'out': in_port })) print("Destined for ARP") print(arp_dst_ip) print(self.topo.nodes()) print(self.topo.edges()) print(self.list_link) if (eth.dst not in self.topo.nodes()): out_port = ofproto.OFPP_FLOOD actions_arp = [parser.OFPActionOutput(out_port)] match_arp = parser.OFPMatch(in_port=in_port, eth_type=eth.ethertype, eth_dst=eth.dst, eth_src=eth.src) ipInst_arp = [ parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, actions_arp) ] cookie_arp = random.randint(0, 0xffffffffffffffff) flowMod_arp = parser.OFPFlowMod(datapath=datapath, match=match_arp, hard_timeout=3, instructions=ipInst_arp, cookie=cookie_arp) datapath.send_msg(flowMod_arp) if ((pkt.get_protocols(arp.arp)) or (pkt.get_protocols(ipv4.ipv4))): if ((eth.dst in self.topo.nodes()) and (eth.src in self.topo.nodes())): print("Calculate Shortest Path on the Fly") sp = nx.shortest_path(self.topo, source=eth.src, target=eth.dst) print(sp) if (datapath.id in sp): tem = sp[sp.index(datapath.id) + 1] sd = [(k[0], k[1]) for k in self.list_link] temp = sd.index((datapath.id, tem)) out_port = self.list_link[temp][2]['out'] print("We are going to add flows ") print("From " + str(datapath.id) + " To " + str(tem) + " Through " + str(out_port)) actions = [parser.OFPActionOutput(out_port)] match = parser.OFPMatch(in_port=in_port, eth_dst=eth.dst, eth_src=eth.src) # match = parser.OFPMatch(in_port=in_port, eth_type=eth.ethertype, eth_dst=eth.dst, eth_src=eth.src) ipInst = [ parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, actions) ] cookie = random.randint(0, 0xffffffffffffffff) flowMod = parser.OFPFlowMod(datapath=datapath, priority=100, match=match, idle_timeout=10, instructions=ipInst, cookie=cookie) datapath.send_msg(flowMod)
def _packet_in_handler(self, ev): # If you hit this you might want to increase # the "miss_send_length" of your switch if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) # paths = [0, 0, 0, 0, 0] # nextLoad = 5 global paths global nextLoad msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype != ether_types.ETH_TYPE_ARP: return thisArp = pkt.get_protocols(arp.arp)[0] dst = eth.dst src = eth.src dstIP = thisArp.dst_ip srcIP = thisArp.src_ip if(dstIP != '10.0.0.10' or (in_port != 1 and in_port != 2 and in_port != 3 and in_port != 4)): #handle arps from 5 and 6 if dstIP == '10.0.0.1': mac = '00:00:00:00:00:01' elif dstIP == '10.0.0.2': mac = '00:00:00:00:00:02' elif dstIP == '10.0.0.3': mac = '00:00:00:00:00:03' else: mac = '00:00:00:00:00:04' e = ethernet.ethernet(dst=src, src=mac, ethertype=ether_types.ETH_TYPE_ARP) a = arp.arp(hwtype=1, proto=0x0800, hlen=6, plen=4, opcode=2, src_mac=mac, src_ip=dstIP, dst_mac=src, dst_ip=srcIP) p = packet.Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() actions = [parser.OFPActionOutput(ofproto.OFPP_IN_PORT)] out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=in_port, actions=actions, data=p.data) datapath.send_msg(out) return dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) print(dpid, src, dst, in_port, srcIP, dstIP) if paths[in_port] != 0: out_port = paths[in_port] else: out_port = nextLoad if nextLoad == 5: nextLoad = 6 else: nextLoad = 5 # out_port = 5 # targIP = '10.0.0.5' targIP = '10.0.0.{}'.format(out_port) actions = [parser.OFPActionSetField(ipv4_dst=targIP)] actions += [parser.OFPActionOutput(out_port)] match = parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, in_port=in_port, ipv4_dst='10.0.0.10') self.add_flow(datapath, 1, match, actions) actions = [parser.OFPActionSetField(ipv4_src='10.0.0.10')] actions += [parser.OFPActionOutput(in_port)] match = parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, in_port=out_port, ipv4_dst=srcIP) self.add_flow(datapath, 1, match, actions) # targEth = '00:00:00:00:00:05' targEth = '00:00:00:00:00:0{}'.format(out_port) e = ethernet.ethernet(dst=src, src=targEth, ethertype=ether_types.ETH_TYPE_ARP) a = arp.arp(hwtype=1, proto=0x0800, hlen=6, plen=4, opcode=2, src_mac=targEth, src_ip='10.0.0.10', dst_mac=src, dst_ip=srcIP) p = packet.Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() actions = [parser.OFPActionOutput(ofproto.OFPP_IN_PORT)] out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=in_port, actions=actions, data=p.data) datapath.send_msg(out)
def _packet_in_handler(self, ev): if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath reason = msg.reason ofproto = datapath.ofproto dpid = datapath.id parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) #self.logger.info("packet-in %s" % (pkt,)) pkt_ethernet = pkt.get_protocols(ethernet.ethernet)[0] if not pkt_ethernet: return if pkt_ethernet.ethertype == ether_types.ETH_TYPE_LLDP: # ignore lldp packet return if reason != ofproto.OFPR_INVALID_TTL: #self.logger.info("INVALID TTL %s" % (pkt)) # self.logger.info("INVALID TTL") if(msg.cookie<10000): return dst = pkt_ethernet.dst src = pkt_ethernet.src loss = msg.cookie-10000 random.seed(random.random()) loss_test = random.randint(0,10000) pkt_ipv4 = pkt.get_protocol(ipv4.ipv4) pkt_icmp = pkt.get_protocol(icmp.icmp) if(loss_test < loss): if pkt_icmp: # only print icmp pkt loss self.logger.info("packet loss test [dpid 0x%x inport %d] rate %d/10000 test %d", dpid, in_port, loss, loss_test) return if pkt_icmp: ip_dst = pkt_ipv4.dst ip_ecn = (pkt_icmp.type-20)&0x3 ips = ip_dst.split('.') pod = int(ips[1]) lr = int(ips[2]) if_no = 0 if dpid < 0x200 : # core, ip if_no = pod +1 elif dpid < 0x300 : # aggr spod = (dpid&0xFF)/2 if pod == spod: if_no = 1+lr else : if_no = 3+ ip_ecn%2 else : if in_port <3 : if_no = 3+ ip_ecn/2 else : if_no = 1 actions = [parser.OFPActionOutput(if_no, 1000)] data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=data) datapath.send_msg(out) return pkt_ipv4 = pkt.get_protocol(ipv4.ipv4) pkt_icmp = pkt.get_protocol(icmp.icmp) if pkt_icmp: self._handle_icmp(datapath, in_port, pkt_ethernet, pkt_ipv4, pkt_icmp) return
def _arp_handler(self, pkt_arp, msg): # 解码数据包以获得 MAC 和 IP 地址 # 源主机 arp_src_ip = pkt_arp.src_ip arp_src_mac = pkt_arp.src_mac # 目的主机 arp_dst_ip = pkt_arp.dst_ip arp_dst_mac = pkt_arp.dst_mac # 接入位置 # 交换机 ID dpid = msg.datapath.id # 交换机的端口号 port = msg.match['in_port'] # 如果是 ARP 响应,并且,目的主机是自己 if str(pkt_arp.opcode) == str(arp.ARP_REPLY): # 打印 ARP 包内容 self.logger.info( "\033[1;34m" + "捕获到 ARP 响应数据包:\t 源 IP:%s\tMAC:%s\t目的 IP:%s\tMAC:%s\tSID:%s\tPORT:%s" + "\033[0m", arp_src_ip, arp_src_mac, arp_dst_ip, arp_dst_mac, dpid, port) if arp_src_mac in send_arp_table and arp_dst_mac == self.mac_addr and arp_dst_ip == self.ip_addr: # TODO pkt = packet.Packet(msg.data) data = pkt.data # self.logger.info("\033[1;31m" + "data:%s" + "\033[0m", data) try: # 解密的验证数据 data = validation.aesdecrypt(data, host_v[arp_src_mac]["seed"]) if data == validation.hash_key(host_v[arp_src_mac]["seed"], host_v[arp_src_mac]["len"]): # 解密完成后将哈希次数减 1 host_v[arp_src_mac][ "len"] = host_v[arp_src_mac]["len"] - 1 if host_c[str(arp_src_mac)][str("port")] == port: # 攻击 self.handle_spoof(arp_src_mac, send_arp_table[arp_src_mac]) else: # 更新主机物理信息表 host_c[arp_src_mac][str("sid")] = dpid host_c[arp_src_mac][str("port")] = port else: # 攻击 self.handle_spoof(arp_src_mac, msg) return except BaseException: self.logger.info("\033[1;31m" + "验证失败" + "\033[0m") # 攻击 self.handle_spoof(arp_src_mac, msg) send_arp_table.pop(arp_src_mac) return # 打印 ARP 包内容 self.logger.info( "\033[1;34m" + "捕获到 ARP 请求数据包:\t 源 IP:%s\tMAC:%s\t目的 IP:%s\tMAC:%s\tSID:%s\tPORT:%s" + "\033[0m", arp_src_ip, arp_src_mac, arp_dst_ip, arp_dst_mac, dpid, port) if str(self.dhcp_ip) == str(arp_src_ip): self.dhcp_mac = arp_src_mac for key in host_c.keys(): if str('ip') in host_c[key] and host_c[key][str('ip')] == str( arp_dst_ip): # 发送 ARP 回应数据包 self._send_arp_reply_handler(msg, arp_dst_ip, key, self.dhcp_ip, self.dhcp_mac) return if str(self.dhcp_ip) == str(arp_dst_ip): # 发送 ARP 回应数据包 self._send_arp_reply_handler(msg, self.dhcp_ip, self.dhcp_mac, arp_src_ip, arp_src_mac) return # 已发送 ARP 请求,等待回应,对该主机的 ARP 请求数据包做丢弃处理 if arp_src_mac in send_arp_table and host_c[str(arp_src_mac)][str( "port")] != port: self.logger.info("已为该主机发送验证信息,丢弃该 ARP 请求数据包!") return # 检查每个端口的 ARP 包的数量 # if port not in PortCount: # PortCount.update({port: 1}) # else: # if PortCount[port] > 40: # self.logger.info("\033[1;31m" + "\n 检测到 ARP 洪泛攻击 !!!" + "\033[0m") # # 在特定时间内阻塞攻击者 # self.handle_spoof(arp_src_mac, msg) # return # elif str(pkt_arp.opcode) == str(arp.ARP_REQUEST): # PortCount[port] += 1 # 源主机的 MAC-IP 映射是否真实, MAC 不在主机物理信息表中直接丢弃 if arp_src_mac in host_c.keys(): if str(host_c[arp_src_mac]['ip']) != str( arp_src_ip): # 源主机的 MAC-IP 映射是否和主机物理信息表中一样 self.logger.info("\033[1;31m" + "\n****** ARP 欺骗检测: MAC 和 IP 映射不匹配 *****" + "\033[0m") self.handle_spoof(arp_src_mac, msg) # 盗用 IP 或者 MAC 的攻击方式 return self.logger.info("\033[1;34m" + "源主机的 MAC-IP 映射真实" + "\033[0m") # MAC 地址是否真实 if arp_src_mac in host_c.keys(): # 源主机 MAC 是否在配置验证信息表中 if str(host_c[arp_src_mac]['sid']) != str(dpid) or str( host_c[arp_src_mac]['port']) != str(port): # MAC 对应的接入位置和配置验证信息表中接入位置不一样,进一步验 # 向主机发送待验证的 ICMP 请求包 self.logger.info("源主机的 MAC 地址真实性待进步一验证,发送验证信息!") self._send_arp_handler(msg, self.ip_addr, self.mac_addr, arp_src_ip, arp_src_mac) send_arp_table.update({arp_src_mac: msg}) return self.logger.info("\033[1;34m" + "源主机的 MAC 地址真实" + "\033[0m") for key in host_c.keys(): if str('ip') in host_c[key] and host_c[key][str('ip')] == str( arp_dst_ip): # 发送 ARP 回应数据包 self._send_arp_reply_handler(msg, arp_dst_ip, key, arp_src_ip, arp_src_mac) return return
def packet_in_handler(self, ev): # Blehhhh self.logger.info("") self.logger.info("Begin the packet_in_handler") msg = ev.msg # instance of OpenFlow messages # self.logger.info("Got message: " + str(msg)) # represent a datapath(switch) which corresponding to OpenFlow that issued the message dp = msg.datapath # self.logger.info("Got datapath: " + str(dp)) ofp = dp.ofproto # the protocol that Openflow version in use ofp_parser = dp.ofproto_parser pkt = packet.Packet(msg.data) eth = pkt.get_protocol(ethernet.ethernet) # print(pkt) src_mac = eth.src dst_mac = eth.dst # self.logger.info("Packet is flowing from %s to %s", src, dst) in_port = msg.match['in_port'] # self.logger.info("Packet is coming in on port: " + str(in_port)) self.remember_mac(src_mac, in_port) # Try to figure out what port to send the packet out on if self.do_we_know_mac(dst_mac): # self.logger.info("We already knew this port") out_port = self.get_macs_port(dst_mac) else: self.logger.info("Didn't know where " + dst_mac + " is plugged in; Will flood") out_port = ofp.OFPP_FLOOD # construct packet_out message and send it. actions = [ofp_parser.OFPActionOutput(out_port)] # switch already knew this port, modify table flow to avoid packet_in next time if out_port != ofp.OFPP_FLOOD: self.logger.info("Didn't flood; Trying to modify the table flow to avoid packet_in next time") self.logger.info("Packet is flowing from %s to %s", src_mac, dst_mac) # match = ofp_parser.OFPMatch(in_port=in_port, eth_dst=dst_mac) # self.send_flow_mod(dp, match, actions, 1) # pkt = packet.Packet(array.array('B', ev.msg.data)) # self.logger.info(pkt) # print(pkt.get_protocol(ipv6)) # self.logger.info(pkt.get_protocol(ipv6)) # ip6 = pkt.get_protocol(ipv6.ipv6) # self.logger.info('ipv6 %s', ip6) # self.logger.info(ip6.nxt) # eth = pkt.get_protocols(ethernet.ethernet) # self.logger.info('ethernet %s', eth) # ip4 = pkt.get_protocol(ipv4.ipv4) # self.logger.info('ipv4: %s', ip4) # tcp_pkt = tcp.tcp(bits=(tcp.TCP_SYN | tcp.TCP_ACK)) # self.logger.info(tcp_pkt) # x = pkt.get_protocol(tcp.tcp) # self.logger.info(x) # eth = pkt.get_protocol(ethernet.ethernet) # self.logger.info(eth) # self.logger.info('Ethernet Type: %s', eth.ethertype) # self.logger.info('IP Type: %s', ether_types.ETH_TYPE_IP) # inspired from https://github.com/knetsolutions/learn-sdn-with-ryu/blob/master/ryu-exercises/ex3_L4Match_switch.py if eth.ethertype == ether_types.ETH_TYPE_IP: self.logger.info("Got an IP type of ether packet") ip4 = pkt.get_protocol(ipv4.ipv4) self.logger.info('ipv4: %s', ip4) ip4_scr = ip4.src ip4_dst = ip4.dst protocol = ip4.proto # self.logger.info(in_proto) t = u = None if protocol == in_proto.IPPROTO_TCP: self.logger.info('This packet is using TCP!') t = pkt.get_protocol(tcp.tcp) match = ofp_parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, ipv4_src=ip4.src, ipv4_dst=ip4.dst, ip_proto=protocol, tcp_src=t.src_port, tcp_dst=t.dst_port) elif protocol == in_proto.IPPROTO_ICMP: match = ofp_parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, ipv4_src=ip4.src, ipv4_dst=ip4.dst, ip_proto=protocol) elif protocol == in_proto.IPPROTO_UDP: self.logger.info('This packet is using UDP!') u = pkt.get_protocol(udp.udp) match = ofp_parser.OFPMatch(eth_type=ether_types.ETH_TYPE_IP, ipv4_src=ip4.src, ipv4_dst=ip4.dst, ip_proto=protocol, udp_src=u.src_port, udp_dst=u.dst_port) else: self.logger.info("Don't know how to handle protocol: " + str(protocol) + "; Won't add any rules") match = None # self.logger.info(pkt.get_protocol(tcp.tcp)) # if pkt.get_protocol(tcp.tcp): # self.logger.info('TCP!') if msg.buffer_id == ofp.OFP_NO_BUFFER: self.logger.info("This message doesn't reference a buffer") else: self.logger.info('Buffer ID: %s', msg.buffer_id) if match is not None: self.logger.info("Match was not none; Proceeding to possibly add flow") # set priority for tcp and udp if t: priority = 1 elif u: priority = 2 else: priority = 3 # Debug priority = 1 self.send_flow_mod( dp, match, actions, new_priority=priority ) """ if msg.buffer_id != ofp.OFP_NO_BUFFER: self.logger.info("Message buffer ID was not \"no buffer\"; Proceeding to add a flow") self.send_flow_mod( dp, match, actions, new_priority=priority, new_buffer_id=msg.buffer_id ) else: self.logger.info( "Message buffer ID was \"no buffer\"; Proceeding to add flow without specifying buffer" ) self.send_flow_mod( dp, match, actions, new_priority=priority ) """ # for p in pkt: # # print(p.protocol_name, p) # self.logger.info(p) # Switch didn't already know this port else: pass # out = ofp_parser.OFPPacketOut( # datapath=dp, # buffer_id=ofp.OFP_NO_BUFFER, # in_port=in_port, actions=actions, # data=msg.data # ) # dp.send_msg(out) data = None if msg.buffer_id == ofp.OFP_NO_BUFFER: data = msg.data out = ofp_parser.OFPPacketOut( datapath=dp, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data ) dp.send_msg(out) self.logger.info("End packet_in_handler")
def _block_packet(self, data): data_packet = packet.Packet(data) for protocol in data_packet.protocols: if (protocol.protocol_name == 'ipv4' and ((ipv4_to_str(protocol.src) == SimpleSwitch.ipv4_host2 and ipv4_to_str(protocol.dst) == SimpleSwitch.ipv4_host3) or (ipv4_to_str(protocol.src) == SimpleSwitch.ipv4_host3 and ipv4_to_str(protocol.dst) == SimpleSwitch.ipv4_host2))): return True return False
def _packet_in_handler(self, ev): # If you hit this you might want to increase # the "miss_send_length" of your switch if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] # print "_packet_in_handler" if eth.ethertype == ether_types.ETH_TYPE_LLDP: # ignore lldp packet return dst = eth.dst src = eth.src dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: match = parser.OFPMatch(in_port=in_port, eth_dst=dst) # verify if we have a valid buffer_id, if yes avoid to send both # flow_mod & packet_out if msg.buffer_id != ofproto.OFP_NO_BUFFER: self.add_flow(datapath, 1, match, actions, msg.buffer_id) return else: self.add_flow(datapath, 1, match, actions) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out) tmp = (int(time_linger.time()) % 3) if (tmp == 0): if (self.abc == 0): try: ftmp = open('tree.csv', 'rb') tree = ftmp.readline() # print tree except Exception: print 'tree.csv open failed' if tree != "": self.abc = -1 print "------------------------------------------------------------------" print tree self.install_experimental_flow(tree, ev) else: self.abc = 0
def _packet_in_handler(self, ev): if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) etherFrame = pkt.get_protocol(ethernet.ethernet) eth = pkt.get_protocols(ethernet.ethernet)[0] pkt_arp = pkt.get_protocol(arp.arp) pkt_ipv4 = pkt.get_protocol(ipv4.ipv4) # pkt_tcp = pkt.get_protocol(tcp.tcp) if etherFrame.ethertype == ether_types.ETH_TYPE_LLDP: return dst = eth.dst src = eth.src dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) self.mac_to_port[dpid][src] = in_port # arp handle if pkt_arp and pkt_arp.opcode == arp.ARP_REQUEST: if pkt_arp.src_ip not in self.ip_to_mac: self.ip_to_mac[pkt_arp.src_ip] = src self.mac_to_dpid[src] = (dpid, in_port) self.ip_to_port[pkt_arp.src_ip] = (dpid, in_port) if pkt_arp.dst_ip in self.ip_to_mac: self.logger.info("[PACKET] ARP packet_in.") self.handle_arpre(datapath=datapath, port=in_port, src_mac=self.ip_to_mac[pkt_arp.dst_ip], dst_mac=src, src_ip=pkt_arp.dst_ip, dst_ip=pkt_arp.src_ip) else: # to avoid flood when the dst ip not in the network if datapath.id not in self.check_ip_dpid[pkt_arp.dst_ip]: self.check_ip_dpid[pkt_arp.dst_ip].append(datapath.id) out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out) return elif pkt_arp and pkt_arp.opcode == arp.ARP_REPLY: if pkt_arp.src_ip not in self.ip_to_mac: self.ip_to_mac[pkt_arp.src_ip] = src self.mac_to_dpid[src] = (dpid, in_port) self.ip_to_port[pkt_arp.src_ip] = (dpid, in_port) dst_mac = self.ip_to_mac[pkt_arp.dst_ip] (dst_dpid, dst_port) = self.mac_to_dpid[dst_mac] self.logger.info("[PACKET] ARP packet_in.") self.handle_arpre(datapath=self.datapaths[dst_dpid], port=dst_port, src_mac=src, dst_mac=dst_mac, src_ip=pkt_arp.src_ip, dst_ip=pkt_arp.dst_ip) return if etherFrame.ethertype == ether.ETH_TYPE_IP: self.logger.info("[PACKET] IPv4 packet_in.") self.handle_ping_ipv4(datapath, pkt, etherFrame, in_port) return
def get_vlan_from_pkt(data): pkt = packet.Packet(data) pkt_vlan = pkt.get_protocols(vlan.vlan)[0] return pkt_vlan.vid