def _ping(self, dp, port_out, ip_src=DISCOVERY_IP_SRC, ip_dst=DISCOVERY_IP_DST, eth_src='02:b0:00:00:00:b5', eth_dst='02:bb:bb:bb:bb:bb', icmp_type=8, icmp_code=0): ofp = dp.ofproto parser = dp.ofproto_parser pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=0x0800, dst=eth_dst, src=eth_src)) pkt.add_protocol(ipv4.ipv4(dst=ip_dst, src=ip_src, proto=1)) pkt.add_protocol( icmp.icmp(type_=icmp_type, code=icmp_code, csum=0, data=icmp.echo( 1, 1, "{'dpid' : " + str(dp.id) + ",'port_out' : " + str(port_out) + "}"))) pkt.serialize() data = pkt.data actions = [parser.OFPActionOutput(port_out, 0)] out = parser.OFPPacketOut(datapath=dp, buffer_id=ofp.OFP_NO_BUFFER, in_port=ofp.OFPP_CONTROLLER, actions=actions, data=data) dp.send_msg(out)
def _handle_icmp(self, ev, subname): msg = ev.msg datapath = msg.datapath pkt = packet.Packet(data=msg.data) pkt_ethernet = pkt.get_protocol(ethernet.ethernet) pkt_ipv4 = pkt.get_protocol(ipv4.ipv4) pkt_icmp = pkt.get_protocol(icmp.icmp) in_port = msg.match['in_port'] # ignore icmp of other than icmp_echo_request if pkt_icmp.type != icmp.ICMP_ECHO_REQUEST: return # make packet object to return this_subnet=self.subnet[datapath.id][subname] pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=this_subnet['mac'])) # if vid != None: # pkt.add_protocol(vlan.vlan(vid=vid, ethertype = 0x0800)) pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src, src=this_subnet['ip'], proto=pkt_ipv4.proto)) pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=pkt_icmp.data)) self._send_packet(datapath, in_port, pkt) self.logger.info("icmp reply is sent: %s-%s via port=%s" % (pkt_ethernet.src, pkt_ipv4.src, in_port) )
def test_Packet_in_2_icmpEcho1(self): print "*** Case2: HOST2のMAC未学習の時、HOST1からICMP Echoを受信 ***" sr = SimpleForward() dstMac = ROUTER_MACADDR1 srcMac = HOST_MACADDR1 srcIp = HOST_IPADDR1 dstIp = HOST_IPADDR2 targetMac = dstMac targetIp = dstIp ttl = 64 datapath = _Datapath() e = ethernet(dstMac, srcMac, ether.ETH_TYPE_IP) iph = ipv4(4, 5, 0, 0, 0, 2, 0, ttl, 1, 0, srcIp, dstIp) echo = icmp.echo(1, 1, 'unit test') icmph = icmp.icmp(8, 0, 0, echo) p = Packet() p.add_protocol(e) p.add_protocol(iph) p.add_protocol(icmph) p.serialize() packetIn = OFPPacketIn(datapath, match=OFPMatch(in_port=1), data=buffer(p.data)) ev = ofp_event.EventOFPPacketIn(packetIn) result = sr.packet_in_handler(ev) self.assertEqual(result, 1) print ""
def receive_icmp(self, datapath, packet, port): ip_packet = packet.get_protocol(ipv4.ipv4) icmp_packet = packet.get_protocol(icmp.icmp) if icmp_packet.type == 8: # Echo request dst_mac = self.arpcache.get_mac(ip_packet.src, port) ip_data = self.ports.get_ip(ip_packet.dst) if (ip_data == None): LOG.debug("ICMP not for router") return 0 (ip_addr,mask,mac_addr) = self.ports.get_port(port) # Routing e = ethernet.ethernet(dst_mac, mac_addr, ether.ETH_TYPE_IP) ip = ipv4.ipv4(src= ip_packet.dst, dst=ip_packet.src, proto= inet.IPPROTO_ICMP,ttl=64) echo_new = icmp.echo(icmp_packet.data.id, icmp_packet.data.seq, icmp_packet.data.data) icmp_new = icmp.icmp(type_=0, code=0, data=echo_new) p = Packet() p.add_protocol(e) p.add_protocol(ip) p.add_protocol(icmp_new) self.send_packet(datapath,port, p) LOG.debug("ICMP for router") return 1 return 0
def _ping(self, dp, port_out): ofp = dp.ofproto parser = dp.ofproto_parser pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=0x0800, dst='ff:ff:ff:ff:ff:ff', src='aa:aa:aa:aa:aa:aa')) pkt.add_protocol(ipv4.ipv4(dst='0.0.0.2', src='0.0.0.1', proto=1)) pkt.add_protocol( icmp.icmp(type_=8, code=0, csum=0, data=icmp.echo( 1, 1, "{'dpid' : " + str(dp.id) + ",'port_out' : " + str(port_out) + "}"))) pkt.serialize() data = pkt.data actions = [parser.OFPActionOutput(port_out, 0)] out = parser.OFPPacketOut(datapath=dp, buffer_id=ofp.OFP_NO_BUFFER, in_port=ofp.OFPP_CONTROLLER, actions=actions, data=data) dp.send_msg(out)
def _handle_icmp(self, datapath, port, pkt_ethernet, pkt_ipv4, pkt_icmp): """ 依据传入的 eth, ip, icmp 生成 packet包 :param datapath: :param port: :param pkt_ethernet: :param pkt_ipv4: :param pkt_icmp: :return: """ if pkt_icmp.type != icmp.ICMP_ECHO_REQUEST: return pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=self.hw_addr)) pkt.add_protocol( ipv4.ipv4(dst=pkt_ipv4.src, src=self.ip_addr, proto=pkt_ipv4.proto)) pkt.add_protocol( icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=pkt_icmp.data)) self._send_packet(datapath, port, pkt)
def send_ping_packet(self, switch, ip): datapath = switch.dp dpid = datapath.id mac_dst = self.arp_table[ip] out_port = self.mac_to_port[dpid][mac_dst] actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=ether_types.ETH_TYPE_IP, src=self.controller_mac, dst=self.arp_table[ip])) pkt.add_protocol( ipv4.ipv4(proto=in_proto.IPPROTO_ICMP, src=self.controller_ip, dst=ip)) echo_payload = '%d;%s;%f' % (dpid, ip, time.time()) payload = icmp.echo(data=echo_payload) pkt.add_protocol(icmp.icmp(data=payload)) pkt.serialize() out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=datapath.ofproto.OFP_NO_BUFFER, data=pkt.data, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions) datapath.send_msg(out)
def send_icmp(self, datapath, srcMac, srcIp, dstMac, dstIp, outPort, seq, data, id=1, type=8, ttl=64): e = ethernet(dstMac, srcMac, ether.ETH_TYPE_IP) iph = ipv4(4, 5, 0, 0, 0, 2, 0, ttl, 1, 0, srcIp, dstIp) echo = icmp.echo(id, seq, data) icmph = icmp.icmp(type, 0, 0, echo) p = Packet() p.add_protocol(e) p.add_protocol(iph) p.add_protocol(icmph) p.serialize() actions = [datapath.ofproto_parser.OFPActionOutput(outPort, 0)] out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=p.data) datapath.send_msg(out) return 0
def _handle_icmp(self, datapath, port, pkt_ethernet, pkt_ipv4, pkt_icmp, SrcGroup): # パケットがICMP ECHOリクエストでなかった場合はすぐに返す # 自分のゲートウェイIPアドレスをもっているグループでなかったら終了 print('ICMP : ', pkt_ipv4.src, ' > ', pkt_ipv4.dst) if pkt_icmp.type != icmp.ICMP_ECHO_REQUEST or pkt_ipv4.dst != self.group_mac[ SrcGroup][0][0]: return # ICMPを作成して返す pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=self.gateway_mac)) # ゲートウェイのmac pkt.add_protocol( ipv4.ipv4( dst=pkt_ipv4.src, src=self.group_mac[SrcGroup][0][0], # ゲートウェイのIP proto=pkt_ipv4.proto)) pkt.add_protocol( icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=pkt_icmp.data)) self._send_packet(datapath, port, pkt)
def _handle_icmp(self, msg, port, data): # パケットがICMP ECHOリクエストでなかった場合はすぐに返す # 自分のゲートウェイIPアドレスをもっているグループでなかったら終了 pkt = packet.Packet(data) pkt_icmp = pkt.get_protocol(icmp.icmp) pkt_ethernet = pkt.get_protocol(ethernet.ethernet) pkt_ipv4 = pkt.get_protocol(ipv4.ipv4) if pkt_ipv4: pass else: return if pkt_icmp.type != icmp.ICMP_ECHO_REQUEST or pkt_ipv4.dst != self.gateway_ip: return src_mac = self.gateway_mac src_ip = self.gateway_ip dst_mac = pkt_ethernet.src dst_ip = pkt_ipv4.src print('ICMP : ', src_ip, ' >> ', dst_ip) # ICMPを作成して返す pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=dst_mac, src=src_mac)) # ゲートウェイのmac pkt.add_protocol( ipv4.ipv4( dst=dst_ip, src=src_ip, # ゲートウェイのIP proto=pkt_ipv4.proto)) pkt.add_protocol( icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=pkt_icmp.data)) self._send_packet(port, pkt, self.datapath.ofproto.OFP_NO_BUFFER)
def send_icmp_reply(self, datapath, old_pkt, output): pkt = packet.Packet() for protocol in old_pkt: if protocol.protocol_name == 'ethernet': e = ethernet.ethernet(src=protocol.dst, dst=protocol.src, ethertype=ether_types.ETH_TYPE_IP) pkt.add_protocol(e) elif protocol.protocol_name == 'ipv4': ip = ipv4.ipv4(version=protocol.version, header_length=protocol.header_length, tos=protocol.tos, total_length=0, identification=protocol.identification, flags=protocol.flags, offset=0, ttl=protocol.ttl, proto=protocol.proto, csum=0, src=protocol.dst, dst=protocol.src, option=protocol.option) pkt.add_protocol(ip) dst_ip = ip.dst elif protocol.protocol_name == 'icmp': icm = icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=protocol.data) pkt.add_protocol(icm) pkt.serialize() actions = [datapath.ofproto_parser.OFPActionOutput(output, 0)] ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser res = ofp_parser.OFPPacketOut(datapath=datapath, buffer_id=ofp.OFP_NO_BUFFER, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=pkt.data) LOG.info('Sending ICMP echo response for %s', dst_ip) datapath.send_msg(res)
def send_ping_packet(self, s1, s2): ''' Send a ping/ICMP packet between two switches. Uses ryu's packet library. Uses a fake MAC and IP address only known to controller. ''' datapath = self.datapath_list[int(s1.dpid)] dst_mac = self.ping_mac dst_ip = self.ping_ip out_port = s1.port_no actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=ether_types.ETH_TYPE_IP, src=self.controller_mac, dst=dst_mac)) pkt.add_protocol( ipv4.ipv4(proto=in_proto.IPPROTO_ICMP, src=self.controller_ip, dst=dst_ip)) echo_payload = '%s;%s;%f' % (s1.dpid, s2.dpid, time.time()) payload = icmp.echo(data=echo_payload) pkt.add_protocol(icmp.icmp(data=payload)) pkt.serialize() out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=datapath.ofproto.OFP_NO_BUFFER, data=pkt.data, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions) datapath.send_msg(out)
def _build_pkt(self, fields, ops): pkt_out = packet.Packet() pkt_ipv4 = pkt_out.get_protocol(ipv4.ipv4) pkt_icmp = pkt_out.get_protocol(icmp.icmp) def addIPv4(pkt_out, fields): pkt_out.add_protocol( ipv4.ipv4(dst=fields['dstip'], src=fields['srcip'], proto=fields['proto'])) return pkt_out pkt_out.add_protocol( ethernet.ethernet(ethertype=fields['ethtype'], dst=fields['dstmac'], src=fields['srcmac'])) # Add if ARP if 'arp' in fields['ptype']: pkt_out.add_protocol( arp.arp(opcode=arp.ARP_REPLY, src_mac=fields['srcmac'], src_ip=fields['srcip'], dst_mac=fields['dstmac'], dst_ip=fields['dstip'])) # Add if IPv4 if 'ipv4' in fields['ptype']: pkt_out = addIPv4(pkt_out, fields) # Add if ICMP if 'icmp' in fields['ptype']: pkt_out = addIPv4(pkt_out, fields) pkt_out.add_protocol( icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=None)) # Add if UDP if 'udp' in fields['ptype']: pkt_out = addIPv4(pkt_out, fields) pkt_out.add_protocol( udp.udp(dst_port=fields['dstport'], bits=fields['bits'], option=fields['opt'], src_port=fields['srcport'])) # Add if TCP if 'tcp' in fields['ptype']: pkt_out = addIPv4(pkt_out, fields) pkt_out.add_protocol( tcp.tcp(dst_port=fields['dstport'], bits=fields['bits'], option=fields['opt'], src_port=fields['srcport'])) #Add covert channel information if fields['com'] != None: pkt_out.add_protocol(fields['com']) #Send crafted packet self._send_packet(fields['dp'], ops['newport'], pkt_out)
def icmp_packet_gen(): pkt = packet.Packet() pkt.protocols.append( ethernet.ethernet("ff:ff:ff:ff:ff:ff", "ff:ff:ff:ff:ff:ff", IPV4)) pkt.protocols.append(ipv4.ipv4(proto=ICMP_PROTO)) pkt.protocols.append(icmp.icmp(0, 0, 0)) return pkt
def test_default_args(self): ic = icmp.icmp() buf = ic.serialize(bytearray(), None) res = struct.unpack(icmp.icmp._PACK_STR, six.binary_type(buf[:4])) eq_(res[0], 8) eq_(res[1], 0) eq_(buf[4:], b'\x00\x00\x00\x00') # with data ic = icmp.icmp(type_=icmp.ICMP_DEST_UNREACH, data=icmp.dest_unreach()) buf = ic.serialize(bytearray(), None) res = struct.unpack(icmp.icmp._PACK_STR, six.binary_type(buf[:4])) eq_(res[0], 3) eq_(res[1], 0) eq_(buf[4:], b'\x00\x00\x00\x00')
def _handle_icmp(self, msg, pkt, icmp_pkt): """ reply to ICMP_ECHO_REQUEST(i.e. ping); may handle other types of ICMP msg in the future; return True if send a response """ LOG.debug('Handling ICMP packet %s', icmp_pkt) if icmp_pkt.type != icmp.ICMP_ECHO_REQUEST: return False in_port_no = msg.in_port switch = self.dpid_to_switch[msg.datapath.id] ipv4_layer = self.find_packet(pkt, 'ipv4') ip_src = netaddr.IPAddress(ipv4_layer.src) ip_dst = netaddr.IPAddress(ipv4_layer.dst) if ip_dst == netaddr.IPAddress(util.bgper_config['local_ipv4']): self.write_to_tap(pkt.data, modifyMacAddress=True) LOG.debug('Forward ICMP packet to tap port.') return True need_reply = False for _k, p in switch.ports.iteritems(): if p.gateway and p.gateway.gw_ip == ip_dst: need_reply = True break if not need_reply: return False echo_id = icmp_pkt.data.id echo_seq = icmp_pkt.data.seq echo_data = bytearray(icmp_pkt.data.data) icmp_data = icmp.echo(id_=echo_id, seq=echo_seq, data=echo_data) #send a echo reply packet ether_layer = self.find_packet(pkt, 'ethernet') ether_dst = ether_layer.src ether_src = str(switch.ports[in_port_no].hw_addr) e = ethernet.ethernet(ether_dst, ether_src, ether.ETH_TYPE_IP) #csum calculation should be paid attention to i = ipv4.ipv4(version=4, header_length=5, tos=0, total_length=0, identification=0, flags=0x000, offset=0, ttl=64, proto=1, csum=0, src=str(ip_dst), dst=str(ip_src), option=None) ic = icmp.icmp(type_=0, code=0, csum=0, data=icmp_data) p = packet.Packet() p.add_protocol(e) p.add_protocol(i) p.add_protocol(ic) p.serialize() datapath = msg.datapath datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE, actions=[datapath.ofproto_parser.OFPActionOutput(in_port_no)], data=p.data) LOG.debug('Ping replied %s -> %s', ip_dst, ip_src) return True
def _send_gossip_message_now(self, dp): """being called from GossipMonitor. Sending ICMP messages an measuring RTT. The response is then catched at packet_in_handler to derive the RTT""" if dp.id != self.tables.ovsk_dpid: # only sending gossip messages from ovsk to ovsk_server return dpid = dp.id parser = dp.ofproto_parser ofproto = dp.ofproto # creating the ICMP Request for port in self.tables.datapaths_ports[dpid]: if port == ofproto.OFPP_LOCAL: # omitting OFPP_LOCAL continue ping = packet.Packet() ping.add_protocol( ethernet.ethernet( ethertype=ether_types.ETH_TYPE_IP, dst=self.tables.ovsk_out_port_and_dest_mac[port], src=self.tables.ovsk_mac)) ping.add_protocol( ipv4.ipv4(dst=self.tables.ovsk_server_ip, src=self.tables.ovsk_ip, proto=ip_proto.IPPROTO_ICMP)) ping.add_protocol( icmp.icmp(type_=icmp.ICMP_ECHO_REQUEST, code=self.icmp_codes_per_out_port[port], csum=0, data=icmp.echo( id_=self.icmp_codes_per_out_port[port], seq=0, data=None))) # sending the message ping.serialize() # print "--->[%s] Sending gossip ICMP packet:\n\t--->%s\n" % (dp.id, ping) data = ping.data actions = [parser.OFPActionOutput(port=port)] out = parser.OFPPacketOut(datapath=dp, actions=actions, in_port=ofproto.OFPP_CONTROLLER, buffer_id=ofproto.OFP_NO_BUFFER, data=data) self.request_reply_delay[self.icmp_codes_per_out_port[ port]] = datetime.now().microsecond dp.send_msg(out)
def send_icmp(self, datapath, dst_ip, src_mac, icmp_type, icmp_code, ip_ihl, icmp_data): self.logger.debug("Sending ICMP") proto = datapath.ofproto parser = datapath.ofproto_parser dpid = dpid_to_str(datapath.id) pkt = packet.Packet() out_port, hop_ip = self.get_route(dpid, dst_ip) out_mac = self.mac_from_port(dpid, out_port) dst_mac = src_mac self.logger.debug( "Router {} sending ICMP to {} with target MAC {} (from port {} hopping to {})" .format(dpid, dst_ip, dst_mac, out_port, hop_ip)) for interface in self.interface_table.get(dpid): if interface.get("port") == out_port: src_ip = interface.get("ip") offset = 14 + 8 + (ip_ihl * 4) payload = icmp_data[14:offset] if icmp_type == 3: self.logger.debug("TYPE 3 ICMP") payload = icmp.dest_unreach(data=payload) if icmp_type == 11: self.logger.debug("TYPE 11 ICMP") payload = icmp.TimeExceeded(data=payload) ## pkt.add_protocol(...) ## https://ryu.readthedocs.io/en/latest/library_packet_ref/packet_icmp.html pkt.add_protocol( ethernet.ethernet(dst=dst_mac, src=out_mac, ethertype=ethernet.ether.ETH_TYPE_IP)) pkt.add_protocol( ipv4.ipv4(dst=dst_ip, src=src_ip, ttl=64, proto=ipv4.inet.IPPROTO_ICMP)) pkt.add_protocol( icmp.icmp(type_=icmp_type, code=icmp_code, data=payload)) pkt.serialize() data = pkt.data actions = [datapath.ofproto_parser.OFPActionOutput(port=out_port)] out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=proto.OFP_NO_BUFFER, in_port=proto.OFPP_ANY, actions=actions, data=data) datapath.send_msg(out)
def _handle_icmp(self, datapath, port, pkt_ethernet, pkt_ipv4, pkt_icmp): pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src,src=self.hw_addr)) pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src,src=self.ip_addr,proto=pkt_ipv4.proto)) dpid = datapath.id #pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_TIME_EXCEEDED, pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_TIME_EXCEEDED,code=(10*dpid/256 +dpid%256),csum=0)) self.logger.info("packet-in 0x%x, %d" %(dpid,(10*dpid/256+dpid%256))) #pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,code=icmp.ICMP_ECHO_REPLY_CODE,csum=0)) self._send_packet(datapath, port, pkt)
def _handle_icmp(self, datapath, port, pkt_ethernet, pkt_ipv4, pkt_icmp): if pkt_icmp.type != icmp.ICMP_ECHO_REQUEST: return pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=self.hw_addr)) pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src, src=self.ip_addr, proto=pkt_ipv4.proto)) pkt.add_protocol( icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=pkt_icmp.data) ) self._send_packet(datapath, port, pkt)
def send_icmp(self, in_port, icmp_type, icmp_code, datapath, ipv4_header=None, ethernet_header=None, icmp_data=None, msg_data=None, src_ip=None): # Generate ICMP reply packet csum = 0 offset = ethernet.ethernet._MIN_LEN ether_proto = ether.ETH_TYPE_IP eth = ethernet_header e = ethernet.ethernet(eth.src, eth.dst, ether_proto) if icmp_data is None and msg_data is not None: ip_datagram = msg_data[offset:] if icmp_type == icmp.ICMP_DEST_UNREACH: icmp_data = icmp.dest_unreach(data_len=len(ip_datagram), data=ip_datagram) elif icmp_type == icmp.ICMP_TIME_EXCEEDED: icmp_data = icmp.TimeExceeded(data_len=len(ip_datagram), data=ip_datagram) ic = icmp.icmp(icmp_type, icmp_code, csum, data=icmp_data) ip = ipv4_header if src_ip is None: src_ip = ip.dst ip_total_length = ip.header_length * 4 + ic._MIN_LEN if ic.data is not None: ip_total_length += ic.data._MIN_LEN if ic.data.data is not None: ip_total_length += +len(ic.data.data) i = ipv4.ipv4(ip.version, ip.header_length, ip.tos, ip_total_length, ip.identification, ip.flags, ip.offset, DEFAULT_TTL, inet.IPPROTO_ICMP, csum, src_ip, ip.src) pkt = packet.Packet() pkt.add_protocol(e) pkt.add_protocol(i) pkt.add_protocol(ic) pkt.serialize() # Send packet out self.send_packet_out(datapath, in_port, datapath.ofproto.OFPP_IN_PORT, pkt.data, data_str=str(pkt))
def setUp(self): self.type_ = icmp.ICMP_ECHO_REQUEST self.code = 0 self.csum = 0 self.data = None self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data) self.buf = bytearray(struct.pack(icmp.icmp._PACK_STR, self.type_, self.code, self.csum)) self.csum_calc = packet_utils.checksum(self.buf) struct.pack_into("!H", self.buf, 2, self.csum_calc)
def icmp(self, imsi='001010000000013', src_mac='00:00:00:00:00:00', src_ip='192.168.70.2', dst_mac='ff:ff:ff:ff:ff:ff', dst_ip='192.168.70.3'): """ Send an ICMP packet through the magma switch and display which tabled caused a drop (-1 if the packet wasn't dropped by any table) """ pkt = ethernet.ethernet(src=src_mac, dst=dst_mac) / \ ipv4.ipv4(src=src_ip, dst=dst_ip, proto=1) / \ icmp.icmp() pkt.serialize() self.raw(data=pkt.data, imsi=imsi)
def build_pkt(pkt): """Build and return a packet and eth type from a dict.""" layers = [] assert 'eth_dst' in pkt and 'eth_src' in pkt ethertype = None if 'arp_source_ip' in pkt and 'arp_target_ip' in pkt: ethertype = ether.ETH_TYPE_ARP layers.append( arp.arp(src_ip=pkt['arp_source_ip'], dst_ip=pkt['arp_target_ip'])) elif 'ipv6_src' in pkt and 'ipv6_dst' in pkt: ethertype = ether.ETH_TYPE_IPV6 if 'neighbor_solicit_ip' in pkt: layers.append( icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_SOLICIT, data=icmpv6.nd_neighbor( dst=pkt['neighbor_solicit_ip'], option=icmpv6.nd_option_sla(hw_src=pkt['eth_src'])))) elif 'echo_request_data' in pkt: layers.append( icmpv6.icmpv6(type_=icmpv6.ICMPV6_ECHO_REQUEST, data=icmpv6.echo(id_=1, seq=1, data=pkt['echo_request_data']))) layers.append( ipv6.ipv6(src=pkt['ipv6_src'], dst=pkt['ipv6_dst'], nxt=inet.IPPROTO_ICMPV6)) elif 'ipv4_src' in pkt and 'ipv4_dst' in pkt: ethertype = ether.ETH_TYPE_IP proto = inet.IPPROTO_IP if 'echo_request_data' in pkt: echo = icmp.echo(id_=1, seq=1, data=pkt['echo_request_data']) layers.append(icmp.icmp(type_=icmp.ICMP_ECHO_REQUEST, data=echo)) proto = inet.IPPROTO_ICMP net = ipv4.ipv4(src=pkt['ipv4_src'], dst=pkt['ipv4_dst'], proto=proto) layers.append(net) assert ethertype is not None, pkt if 'vid' in pkt: tpid = ether.ETH_TYPE_8021Q layers.append(vlan.vlan(vid=pkt['vid'], ethertype=ethertype)) else: tpid = ethertype eth = ethernet.ethernet(dst=pkt['eth_dst'], src=pkt['eth_src'], ethertype=tpid) layers.append(eth) layers = [layer for layer in reversed(layers)] result = packet.Packet() for layer in layers: result.add_protocol(layer) result.serialize() return (result, ethertype)
def generate(icmp_type, icmp_code, msg_data, src_ip=None, pkt=None): """Generate ICMP error message :param icmp_type: The icmp type of packet :param icmp_code: The icmp code of packet :param msg_data: The original data that cause this ICMP error packet :param src_ip: The source ip of the packet :param pkt: The original packet that cause this ICMP error :returns: An ryu.lib.packet.packet.Packet instance, which is an ICMP packet """ if not pkt: pkt = packet.Packet(msg_data) e_pkt = pkt.get_protocol(ethernet.ethernet) ipv4_pkt = pkt.get_protocol(ipv4.ipv4) if not src_ip: src_ip = ipv4_pkt.dst # Create ICMP data offset = ethernet.ethernet._MIN_LEN # Copy 128 bytes data according to RFC 4884 end_of_data = offset + len(ipv4_pkt) + 128 ip_datagram = bytearray() ip_datagram += msg_data[offset:end_of_data] data_len = int(len(ip_datagram) / 4) length_modulus = int(len(ip_datagram) % 4) # Zero pad to the next 32 bit boundary, according to RFC 4884 if length_modulus: data_len += 1 ip_datagram += bytearray([0] * (4 - length_modulus)) icmp_data = _create_icmp_data(icmp_type, data_len, ip_datagram) ic_pkt = icmp.icmp(icmp_type, icmp_code, 0, data=icmp_data) # Create IPv4 data ip_total_length = ipv4_pkt.header_length * 4 + ic_pkt._MIN_LEN ip_total_length += ic_pkt.data._MIN_LEN ip_total_length += len(ic_pkt.data.data) ipv4_pkt.total_length = ip_total_length # Default ttl ipv4_pkt.ttl = 64 ipv4_pkt.proto = inet.IPPROTO_ICMP ipv4_pkt.csum = 0 ipv4_pkt.src, ipv4_pkt.dst = src_ip, ipv4_pkt.src # Create ethernet data e_pkt.src, e_pkt.dst = e_pkt.dst, e_pkt.src pkt_reply = packet.Packet() pkt_reply.add_protocol(e_pkt) pkt_reply.add_protocol(ipv4_pkt) pkt_reply.add_protocol(ic_pkt) return pkt_reply
def setUp(self): self.type_ = icmp.ICMP_ECHO_REQUEST self.code = 0 self.csum = 0 self.data = None self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data) self.buf = bytearray( struct.pack(icmp.icmp._PACK_STR, self.type_, self.code, self.csum)) self.csum_calc = packet_utils.checksum(six.binary_type(self.buf)) struct.pack_into('!H', self.buf, 2, self.csum_calc)
def send_several_packet(self, middleware, chain, node): type_pkt = chain['detect_type'] dst_ip = node['manage_ip'] dst_mac = node['set_eth'] src_ip = cm.Communal().randomIP(dst_ip) src_mac = cm.src_mac[0] content = 'abcdefghijklmnopqrstuvwabcdefghi' # detect in port or out port if type_pkt == 'tcp': dport = chain['detect_port'] if middleware.has_key('in_device_id') and middleware['in_device_id']: node_poet = (self.etcd_port[middleware['in_device_id']] if self.etcd_port.has_key(middleware['in_device_id']) else None) if node_poet and self.datapaths.has_key(node_poet['forwarder']): datapath = self.datapaths[node_poet['forwarder']] vlanid = node_poet['vlan_id'] port = node_poet['port'] self.send_tcp_pke(datapath, port, vlanid, dst_ip, src_ip, src_mac, dst_mac, dport) pkt = self.assemble_tcp(content, vlanid, dst_ip, dst_mac, src_ip, src_mac, dport) self._send_packet(datapath, pkt, port) if middleware.has_key('out_device_id') and middleware['out_device_id']: node_poet = (self.etcd_port[middleware['out_device_id']] if self.etcd_port.has_key(middleware['out_device_id']) else None) if node_poet and self.datapaths.has_key(node_poet['forwarder']): datapath = self.datapaths[node_poet['forwarder']] vlanid = node_poet['vlan_id'] port = node_poet['port'] self.send_tcp_pke(datapath, port, vlanid, dst_ip, src_ip, src_mac, dst_mac, dport) pkt = self.assemble_tcp(content, vlanid, dst_ip, dst_mac, src_ip, src_mac, dport) self._send_packet(datapath, pkt, port) elif type_pkt == 'icmp': self._send_packet(datapath, pkt, port) if middleware.has_key('out_device_id') and middleware['out_device_id']: node_poet = (self.etcd_port[middleware['out_device_id']] if self.etcd_port.has_key(middleware['out_device_id']) else None) if node_poet and self.datapaths.has_key(node_poet['forwarder']): datapath = self.datapaths[node_poet['forwarder']] vlanid = node_poet['vlan_id'] port = node_poet['port'] pkt = self.assemble_icmp(vlanid, dst_ip, dst_mac, src_ip, src_mac, (csum + 2), (identification - 1)) pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REQUEST, code=icmp.ICMP_ECHO_REPLY_CODE, data=icmp.echo(id_=1, seq=rand + 2, data=content))) self._send_packet(datapath, pkt, port)
def _handle_icmp(self, datapath, port, pkt_ethernet, pkt_ipv4, pkt_icmp): pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=self.hw_addr)) pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src, src=pkt_ipv4.dst, proto=pkt_ipv4.proto)) pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=pkt_icmp.data)) self._send_packet(datapath, port, pkt)
def send_ping(self, ip_dst): pkt = packet.Packet() if ip_dst in self.arp_table: mac_dst = self.arp_table[ip_dst] else: return pkt.add_protocol(ethernet.ethernet(ethertype=0x800,dst=mac_dst,\ src=self.hw_addr)) pkt.add_protocol(ipv4.ipv4(dst= ip_dst, src=self.ip_addr,proto=1)) pkt.add_protocol(icmp.icmp(type_= 8, code=0, csum=0))#Not sure about echo print("Ping packet sent") self._flood_packet(pkt)
def setUp_with_TimeExceeded(self): self.te_data = b"abc" self.te_data_len = len(self.te_data) self.data = icmp.TimeExceeded(data_len=self.te_data_len, data=self.te_data) self.type_ = icmp.ICMP_TIME_EXCEEDED self.code = 0 self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data) self.buf = bytearray(struct.pack(icmp.icmp._PACK_STR, self.type_, self.code, self.csum)) self.buf += self.data.serialize() self.csum_calc = packet_utils.checksum(self.buf) struct.pack_into("!H", self.buf, 2, self.csum_calc)
def _handle_icmp(self, msg, pkt, icmp_pkt): ''' reply to ICMP_ECHO_REQUEST(i.e. ping); may handle other types of ICMP msg in the future; return True if send a responce ''' #print 'icmp', icmp_pkt if icmp_pkt.type != icmp.ICMP_ECHO_REQUEST: return False in_port_no = msg.in_port switch = self.dpid_to_switch[msg.datapath.id] ipv4_layer = self.find_packet(pkt, 'ipv4') ip_src = ipv4_layer.src ip_dst = ipv4_layer.dst need_reply = False for _k, p in switch.ports.iteritems(): if p.gateway and p.gateway.gw_ip == ip_dst: need_reply = True break if not need_reply: return False echo_id = icmp_pkt.data.id echo_seq = icmp_pkt.data.seq echo_data = bytearray(icmp_pkt.data.data) icmp_data = icmp.echo(id_=echo_id,seq=echo_seq,data=echo_data) #send a echo reply packet ether_layer = self.find_packet(pkt, 'ethernet') ether_dst = ether_layer.src ether_src = switch.ports[in_port_no].hw_addr e = ethernet.ethernet(ether_dst,ether_src,ether.ETH_TYPE_IP) #csum calculation should be paied attention i = ipv4.ipv4(version=4,header_length=5,tos=0,total_length=0, identification=0,flags=0x000,offset=0,ttl=64,proto=1,csum=0, src=ip_dst,dst=ip_src,option=None) ic = icmp.icmp(type_= 0,code=0,csum=0,data=icmp_data) p = packet.Packet() p.add_protocol(e) p.add_protocol(i) p.add_protocol(ic) p.serialize() datapath = msg.datapath datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE, actions=[datapath.ofproto_parser.OFPActionOutput(in_port_no)], data=p.data) print 'send a ping replay' return True
def _build_pkt(self, fields, ops): pkt_out = packet.Packet() pkt_ipv4 = pkt_out.get_protocol(ipv4.ipv4) pkt_icmp = pkt_out.get_protocol(icmp.icmp) def addIPv4(pkt_out, fields): pkt_out.add_protocol(ipv4.ipv4(dst=fields['dstip'], src=fields['srcip'], proto=fields['proto'])) return pkt_out pkt_out.add_protocol(ethernet.ethernet(ethertype=fields['ethtype'], dst=fields['dstmac'], src=fields['srcmac'])) # Add if ARP if 'arp' in fields['ptype']: pkt_out.add_protocol(arp.arp(opcode=arp.ARP_REPLY, src_mac=fields['srcmac'], src_ip=fields['srcip'], dst_mac=fields['dstmac'], dst_ip=fields['dstip'])) # Add if IPv4 if 'ipv4' in fields['ptype']: pkt_out = addIPv4(pkt_out,fields) # Add if ICMP if 'icmp' in fields['ptype']: pkt_out = addIPv4(pkt_out,fields) pkt_out.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=None)) # Add if UDP if 'udp' in fields['ptype']: pkt_out = addIPv4(pkt_out,fields) pkt_out.add_protocol(udp.udp(dst_port=fields['dstport'], bits=fields['bits'],option=fields['opt'], src_port=fields['srcport'])) # Add if TCP if 'tcp' in fields['ptype']: pkt_out = addIPv4(pkt_out,fields) pkt_out.add_protocol(tcp.tcp(dst_port=fields['dstport'], bits=fields['bits'],option=fields['opt'], src_port=fields['srcport'])) #Add covert channel information if fields['com'] != None: pkt_out.add_protocol(fields['com']) #Send crafted packet self._send_packet(fields['dp'], ops['newport'], pkt_out)
def _handle_icmp(self, datapath, port, pkt_ethernet, pkt_ipv4, pkt_icmp): if pkt_icmp.type != icmp.ICMP_ECHO_REQUEST: return if pkt_ipv4.dst in self.arp_table1: # index = self.ip_addr.index(pkt_ipv4.dst) pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=self.arp_table1[pkt_ipv4.dst])) pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src, src=pkt_ipv4.dst, proto=pkt_ipv4.proto)) pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_CODE, csum=0, datapath=pkt_icmp.data)) self._send_packet(datapath, port, pkt)
def _build_echo(self, _type, echo): e = self._build_ether(ether.ETH_TYPE_IP) ip = ipv4.ipv4(version=4, header_length=5, tos=0, total_length=84, identification=0, flags=0, offset=0, ttl=64, proto=inet.IPPROTO_ICMP, csum=0, src=self.RYU_IP, dst=self.HOST_IP) ping = icmp.icmp(_type, code=0, csum=0, data=echo) p = packet.Packet() p.add_protocol(e) p.add_protocol(ip) p.add_protocol(ping) p.serialize() return p
def setUp_with_dest_unreach(self): self.unreach_mtu = 10 self.unreach_data = b"abc" self.unreach_data_len = len(self.unreach_data) self.data = icmp.dest_unreach(data_len=self.unreach_data_len, mtu=self.unreach_mtu, data=self.unreach_data) self.type_ = icmp.ICMP_DEST_UNREACH self.code = icmp.ICMP_HOST_UNREACH_CODE self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data) self.buf = bytearray(struct.pack(icmp.icmp._PACK_STR, self.type_, self.code, self.csum)) self.buf += self.data.serialize() self.csum_calc = packet_utils.checksum(self.buf) struct.pack_into("!H", self.buf, 2, self.csum_calc)
def _handle_icmp(self, datapath, port, pkt_ethernet, pkt_ipv4, pkt_icmp): if pkt_icmp.type != icmp.ICMP_ECHO_REQUEST: return pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=ROUTER_MACADDR1)) pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src, src=ROUTER_IPADDR1, proto=pkt_ipv4.proto)) pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=pkt_icmp.data)) self._send_packet(datapath, port, pkt)
def setUp_with_TimeExceeded(self): self.te_data = 'abc' self.te_data_len = len(self.te_data) self.data = icmp.TimeExceeded(data_len=self.te_data_len, data=self.te_data) self.type_ = icmp.ICMP_TIME_EXCEEDED self.code = 0 self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data) self.buf = struct.pack(icmp.icmp._PACK_STR, self.type_, self.code, self.csum) self.buf += self.data.serialize() self.csum_calc = packet_utils.checksum(str(self.buf)) struct.pack_into('!H', self.buf, 2, self.csum_calc)
def createPacketIpv4(self, datapath, port, pkt_ethernet, pkt_ipv, pkt_icmp): # create send packet sendpkt = packet.Packet() sendpkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.dst, src=pkt_ethernet.src)) sendpkt.add_protocol(ipv4.ipv4(dst=pkt_ipv.src, src=pkt_ethernet.src, proto=pkt_ipv.proto)) sendpkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=pkt_icmp.data)) sendpkt.serialize() return sendpkt
def send_ping(self, datapath, src_mac, dst_mac, src_ip, dst_ip, outport=1, seq=0): ttl = 64 e = ethernet.ethernet(dst_mac, src_mac, ether.ETH_TYPE_IP) iph = ipv4.ipv4(4, 5, 0, 0, 0, 2, 0, ttl, 1, 0, src_ip, dst_ip) echo = icmp.echo(1, seq, data=None) icmph = icmp.icmp(8, 0, 0, echo) pkt = packet.Packet() pkt.add_protocol(e) pkt.add_protocol(iph) pkt.add_protocol(icmph) self._send_packet(datapath, outport, pkt) self.logger.info("icmp echo req is sent: to %s" % (dst_ip,) )
def send_icmp(self, datapath, srcMac, srcIp, dstMac, dstIp, outPort, seq, data, id=1, type=8, ttl=64): e = ethernet.ethernet(dstMac, srcMac, ether.ETH_TYPE_IP) #Construye el protocolo ethernet iph = ipv4.ipv4(4, 5, 0, 0, 0, 2, 0, ttl, 1, 0, srcIp, dstIp) #Construye la parte del protocolo IP echo = icmp.echo(id, seq, data) #Construye la parte del echo que se añadirá al protocolo icmp icmph = icmp.icmp(type, 0, 0, echo) #Construye la parte del icmp p = Packet() #Crea el paquete p.add_protocol(e) #Añade el protocolo ethernet p.add_protocol(iph) #Añade el protocolo ip p.add_protocol(icmph) #Añade el protocolo icmp p.serialize() #Serializa todo actions = [datapath.ofproto_parser.OFPActionOutput(outPort, 0)] #Enviar por el puerto outPort #Mensaje a enviar out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=p.data) datapath.send_msg(out) #Enviar mensaje
def setUp_with_dest_unreach(self): self.unreach_mtu = 10 self.unreach_data = 'abc' self.unreach_data_len = len(self.unreach_data) self.data = icmp.dest_unreach(data_len=self.unreach_data_len, mtu=self.unreach_mtu, data=self.unreach_data) self.type_ = icmp.ICMP_DEST_UNREACH self.code = icmp.ICMP_HOST_UNREACH_CODE self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data) self.buf = struct.pack(icmp.icmp._PACK_STR, self.type_, self.code, self.csum) self.buf += self.data.serialize() self.csum_calc = packet_utils.checksum(str(self.buf)) struct.pack_into('!H', self.buf, 2, self.csum_calc)
class Test_icmp_dest_unreach(unittest.TestCase): type_ = icmp.ICMP_DEST_UNREACH code = icmp.ICMP_HOST_UNREACH_CODE csum = 0 mtu = 10 data = 'abc' data_len = len(data) dst_unreach = icmp.dest_unreach(data_len=data_len, mtu=mtu, data=data) ic = icmp.icmp(type_, code, csum, data=dst_unreach) def setUp(self): pass def tearDown(self): pass def test_to_string(self): data_values = { 'data': self.data, 'data_len': self.data_len, 'mtu': self.mtu } _data_str = ','.join([ '%s=%s' % (k, repr(data_values[k])) for k, v in inspect.getmembers(self.dst_unreach) if k in data_values ]) data_str = '%s(%s)' % (icmp.dest_unreach.__name__, _data_str) icmp_values = { 'type': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': data_str } _ic_str = ','.join([ '%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(self.ic) if k in icmp_values ]) ic_str = '%s(%s)' % (icmp.icmp.__name__, _ic_str) eq_(str(self.ic), ic_str) eq_(repr(self.ic), ic_str)
def control_plane_icmp_handler(self, in_port, vlan, eth_src, ipv4_pkt, icmp_pkt): ofmsgs = [] if icmp_pkt is not None: pkt = self.build_ethernet_pkt( eth_src, in_port, vlan, ether.ETH_TYPE_IP) ipv4_pkt = ipv4.ipv4( dst=ipv4_pkt.src, src=ipv4_pkt.dst, proto=ipv4_pkt.proto) icmp_pkt = icmp.icmp( type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, data=icmp_pkt.data) pkt.add_protocol(ipv4_pkt) pkt.add_protocol(icmp_pkt) pkt.serialize() ofmsgs.append(self.valve_packetout(in_port, pkt.data)) return ofmsgs
def ICMPPacket(self, datapath, in_port, pkt_ethernet, pkt_ipv4, pkt_icmp): if pkt_icmp.type == icmp.ICMP_ECHO_REQUEST: eer=ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=self.ip_mac_port[in_port][1]) iper=ipv4.ipv4(dst=pkt_ipv4.src, src=self.ip_mac_port[in_port][2], proto=pkt_ipv4.proto) icmper=icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=pkt_icmp.data) p = packet.Packet() p.add_protocol(eer) p.add_protocol(iper) p.add_protocol(icmper) self.send_packet(datapath, in_port, p)
def handleIcmpPacket(self, datapath, in_port, pkt_ethernet, pkt_ipv4, pkt_icmp): #This function builds an ICMP echo reply for the echo request received if pkt_icmp.type == icmp.ICMP_ECHO_REQUEST: eer=ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=self.interfaces_virtuales[self.tabla_vlan[in_port]][0]) iper=ipv4.ipv4(dst=pkt_ipv4.src, src=self.interfaces_virtuales[self.tabla_vlan[in_port]][2], proto=pkt_ipv4.proto) icmper=icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=pkt_icmp.data) p = packet.Packet() p.add_protocol(eer) p.add_protocol(iper) p.add_protocol(icmper) self.sendPacket(datapath, in_port, p)
def setUp_with_echo(self): self.echo_id = 13379 self.echo_seq = 1 self.echo_data = b'\x30\x0e\x09\x00\x00\x00\x00\x00' \ + b'\x10\x11\x12\x13\x14\x15\x16\x17' \ + b'\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f' \ + b'\x20\x21\x22\x23\x24\x25\x26\x27' \ + b'\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f' \ + b'\x30\x31\x32\x33\x34\x35\x36\x37' self.data = icmp.echo( id_=self.echo_id, seq=self.echo_seq, data=self.echo_data) self.type_ = icmp.ICMP_ECHO_REQUEST self.code = 0 self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data) self.buf = bytearray(struct.pack( icmp.icmp._PACK_STR, self.type_, self.code, self.csum)) self.buf += self.data.serialize() self.csum_calc = packet_utils.checksum(self.buf) struct.pack_into('!H', self.buf, 2, self.csum_calc)
def _virtual_ip_icmp_reply(self, datapath, in_port, pkt): eth_hd = pkt.get_protocol(ethernet.ethernet) ipv4_hd = pkt.get_protocol(ipv4.ipv4) icmp_hd = pkt.get_protocol(icmp.icmp) if icmp_hd.type == icmp.ICMP_ECHO_REQUEST: vir_ip = ipv4_hd.dst if vir_ip not in self.virtual_ip: print ("WARNING: could be virtual ip routing table config err") return vir_mac = self.virtual_ip[vir_ip] icmp_reply = packet.Packet() icmp_reply.add_protocol(ethernet.ethernet(ethertype=eth_hd.ethertype, dst=eth_hd.src, src=vir_mac)) icmp_reply.add_protocol(ipv4.ipv4(dst=ipv4_hd.src, src=vir_ip, proto=ipv4_hd.proto)) icmp_reply.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, data=icmp_hd.data)) self._send_packet_port(datapath, in_port, icmp_reply)
def _icmp_send(dp, port_out, ip_src=DISCOVERY_IP_SRC, ip_dst=DISCOVERY_IP_DST, eth_src='02:b0:00:00:00:b5', eth_dst='02:bb:bb:bb:bb:bb', icmp_type=8, icmp_code=0): """ Generates ICMP packet and sends it out of 'port_out' on forwarder 'dp' Keyword arguments: dp -- Datapath port_out -- Port on forwarder (dp) used to spit out packet ip_src -- IP address of sender ip_dst -- IP address of recipient eth_src -- Ethernet address of source (Default is 02:b0:00:00:00:b5 because none wanted to have 0xb00b5 as experimenter ID) eth_dst -- Ethernet destiation address (probably to be reworked) icmp_type -- ICMP type, default is 8 which is Echo icmp_code -- ICMP code, default is 0 which is No Code """ ofp = dp.ofproto parser = dp.ofproto_parser pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=0x0800, dst=eth_dst, src=eth_src)) pkt.add_protocol(ipv4.ipv4(dst=ip_dst, src=ip_src, proto=1)) ##TODO: Rework payload and codes to properly work with Fragmentation needed pkt.add_protocol(icmp.icmp(type_=icmp_type, code=icmp_code, csum=0, data=icmp.echo(1,1,"{'dpid' : "+str(dp.id)+",'port_out' : "+str(port_out)+"}"))) pkt.serialize() data=pkt.data actions=[parser.OFPActionOutput(port_out,0)] out=parser.OFPPacketOut(datapath=dp, buffer_id=ofp.OFP_NO_BUFFER, in_port=ofp.OFPP_CONTROLLER, actions=actions, data=data) dp.send_msg(out)
def echo_reply(eth_src, eth_dst, vid, src_ip, dst_ip, data): """Return an ICMP echo reply packet. Args: eth_src (str): Ethernet source address. eth_dst (str): destination Ethernet MAC address. vid (int or None): VLAN VID to use (or None). src_ip (ipaddr.IPv4Address): source IPv4 address. dst_ip (ipaddr.IPv4Address): destination IPv4 address. Returns: ryu.lib.packet.icmp: serialized ICMP echo reply packet. """ pkt = build_pkt_header(eth_src, eth_dst, vid, ether.ETH_TYPE_IP) ipv4_pkt = ipv4.ipv4( dst=dst_ip, src=src_ip, proto=inet.IPPROTO_ICMP) pkt.add_protocol(ipv4_pkt) icmp_pkt = icmp.icmp( type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, data=data) pkt.add_protocol(icmp_pkt) pkt.serialize() return pkt
def _ping(self, dp, port_out): ofp = dp.ofproto parser = dp.ofproto_parser pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=0x0800, dst="ff:ff:ff:ff:ff:ff", src="aa:aa:aa:aa:aa:aa")) pkt.add_protocol(ipv4.ipv4(dst="0.0.0.2", src="0.0.0.1", proto=1)) pkt.add_protocol( icmp.icmp( type_=8, code=0, csum=0, data=icmp.echo(1, 1, "{'dpid' : " + str(dp.id) + ",'port_out' : " + str(port_out) + "}"), ) ) pkt.serialize() data = pkt.data actions = [parser.OFPActionOutput(port_out, 0)] out = parser.OFPPacketOut( datapath=dp, buffer_id=ofp.OFP_NO_BUFFER, in_port=ofp.OFPP_CONTROLLER, actions=actions, data=data ) dp.send_msg(out)
def _ping(self, dp, port_out, ip_src=DISCOVERY_IP_SRC, ip_dst=DISCOVERY_IP_DST, eth_src='02:b0:00:00:00:b5', eth_dst='02:bb:bb:bb:bb:bb', icmp_type=8, icmp_code=0): ofp = dp.ofproto parser = dp.ofproto_parser pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=0x0800, dst=eth_dst, src=eth_src)) pkt.add_protocol(ipv4.ipv4(dst=ip_dst, src=ip_src, proto=1)) pkt.add_protocol(icmp.icmp(type_=icmp_type, code=icmp_code, csum=0, data=icmp.echo(1,1,"{'dpid' : "+str(dp.id)+",'port_out' : "+str(port_out)+"}"))) pkt.serialize() data=pkt.data actions=[parser.OFPActionOutput(port_out,0)] out=parser.OFPPacketOut(datapath=dp, buffer_id=ofp.OFP_NO_BUFFER, in_port=ofp.OFPP_CONTROLLER, actions=actions, data=data) dp.send_msg(out)
def trigger_host_discovery(self): # In order to enable active host discovery # net.ipv4.icmp_echo_ignore_broadcasts should be set to 0 icmp_packet = packet.Packet() icmp_packet.add_protocol(ethernet.ethernet( src=HOST_DIS_ETH_SRC, dst=HOST_DIS_ETH_DST)) icmp_packet.add_protocol(ipv4.ipv4( dst=HOST_DIS_IP_DST, src=HOST_DIS_IP_SRC, proto=inet.IPPROTO_ICMP)) icmp_packet.add_protocol(icmp.icmp(data=icmp.echo())) icmp_packet.serialize() for dpid, out_port in self.get_flood_ports(): dp = self.dpset.get(dpid) actions = [dp.ofproto_parser.OFPActionOutput(out_port)] out = dp.ofproto_parser.OFPPacketOut( datapath=dp, buffer_id=dp.ofproto.OFP_NO_BUFFER, in_port=dp.ofproto.OFPP_CONTROLLER, actions=actions, data=icmp_packet.data) dp.send_msg(out)
def handle_icmp(self,msg,pkt,icmp_pkt): dpid = msg.datapath.id datapath = msg.datapath if icmp_pkt.type != ICMP_ECHO_REQUEST: # need forward packet return eth_layer = self.find_packet(pkt, 'ethernet') print vars(eth_layer) ip_layer = self.find_packet(pkt,'ipv4') ipDestAddr = netaddr.IPAddress(ip_layer.dst) port_in = msg.match['in_port'] if self.routers[dpid].ports[port_in].ip_addr == str(ipDestAddr): pkt = packet.Packet() print self.routers[dpid].ports[port_in].mac_addr print eth_layer.src pkt.add_protocol(ethernet.ethernet(ethertype=eth_layer.ethertype, dst=eth_layer.src, src=self.routers[dpid].ports[port_in].mac_addr)) pkt.add_protocol(ipv4.ipv4(dst=ip_layer.src, src=self.routers[dpid].ports[port_in].ip_addr, proto=ip_layer.proto)) pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=icmp_pkt.data)) pkt.serialize() data = pkt.data actions = [datapath.ofproto_parser.OFPActionOutput(port_in)] out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath, buffer_id=datapath.ofproto.OFP_NO_BUFFER, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=data) datapath.send_msg(out) logger.info('send reply icmp to : %s ',ip_layer.src)
in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=data) datapath.send_msg(out) def ICMPPacket(self, datapath, in_port, pkt_ethernet, pkt_ipv4, pkt_icmp): if pkt_icmp.type == icmp.ICMP_ECHO_REQUEST: eer=ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=self.interfaces_virtuales[self.tabla_vlan[in_port]][0]) iper=ipv4.ipv4(dst=pkt_ipv4.src, src=self.interfaces_virtuales[self.tabla_vlan[in_port]][2], proto=pkt_ipv4.proto) icmper=icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=pkt_icmp.data) p = packet.Packet() p.add_protocol(eer) p.add_protocol(iper) p.add_protocol(icmper) self.send_packet(datapath, in_port, p) def paquete_para_enrutar(self, ev): msg = ev.msg # Objeto que representa la estuctura de datos PacketIn. datapath = msg.datapath # Identificador del datapath correspondiente al switch. ofproto = datapath.ofproto # Protocolo utilizado que se fija en una etapa
def _packet_in_handler(self, ev): msg = ev.msg in_port = msg.in_port datapath = msg.datapath ofproto = datapath.ofproto dpid = datapath.id print 'mac_to_port',self.mac_to_port,'\n' self.mac_to_port.setdefault(dpid, {}) print 'mac_to_port',self.mac_to_port,'\n' dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) LOG.info("packet in %s %s %s %s", dpid, haddr_to_str(src), haddr_to_str(dst), msg.in_port) if _eth_type == ether.ETH_TYPE_ARP: #if dst in self.port_to_switch_mac[dpid]: arp_pkt = self.find_packet(msg,'arp') if arp_pkt != None: dst_ip = arp_pkt.dst_ip src_ip = arp_pkt.src_ip self.port_to_ip.setdefault(dpid,{}) self.port_to_ip[dpid][in_port] = (src_ip & 0Xffffff00) + 0xfe if dst_ip == self.port_to_ip[dpid][in_port]: src_mac = self.port_to_switch_mac[dpid][in_port] e = ethernet.ethernet(src,self.port_to_switch_mac[dpid][in_port],ether.ETH_TYPE_ARP) if arp_pkt.opcode == arp.ARP_REQUEST: opcode = arp.ARP_REPLY #else: #opcode = arp.ARP_REV_REPLY a = arp.arp(hwtype = 1,proto = 0x0800, hlen = 6, plen = 4, opcode = opcode, src_mac = src_mac,src_ip = arp_pkt.dst_ip, dst_mac = arp_pkt.src_mac, dst_ip = arp_pkt.src_ip) p = Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE,actions=[datapath.ofproto_parser.OFPActionOutput(in_port)],data=p.data) print "arp request packet's dst_mac is ",haddr_to_str(self.port_to_switch_mac[dpid][in_port]) if _eth_type == ether.ETH_TYPE_IP: ip_pkt = self.find_packet(msg,'ipv4') #to judge if the ip packet contains icmp protocol #print 'lee 0' if ip_pkt.proto == 1: icmp_pkt = self.find_packet(msg,'icmp') if icmp_pkt.type == icmp.ICMP_ECHO_REQUEST: ip_src = ip_pkt.src ip_dst = ip_pkt.dst echo_id = icmp_pkt.data.id echo_seq = icmp_pkt.data.seq echo_data = bytearray(icmp_pkt.data.data) icmp_data = icmp.echo(id_=echo_id,seq=echo_seq,data=echo_data) self.port_to_ip.setdefault(dpid, {}) #mask is 24 bit self.port_to_ip[dpid][in_port] = (ip_src & 0Xffffff00) + 0xfe #print 'lee 1' if self.port_to_ip[dpid][in_port] == ip_dst: #send a echo reply packet ether_dst = src ether_src = self.port_to_switch_mac[dpid][in_port] e = ethernet.ethernet(ether_dst,ether_src,ether.ETH_TYPE_IP) #csum calculation should be paied attention #ic = icmp.icmp(type_= 0,code=0,csum=0,data=icmp_pkt.data) i = ipv4.ipv4(version=4,header_length=5,tos=0,total_length=0, identification=0,flags=0x000,offset=0,ttl=64,proto=1,csum=0,src=ip_dst, dst=ip_src,option=None) ic = icmp.icmp(type_= 0,code=0,csum=0,data=icmp_data) p = Packet() p.add_protocol(e) p.add_protocol(i) p.add_protocol(ic) p.serialize() datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE,actions=[datapath.ofproto_parser.OFPActionOutput(in_port)],data=p.data) print 'send a ping replay' else: pass if _eth_type == ether.ETH_TYPE_IPV6: ipv6_pkt = self.find_packet(msg,'ipv6') #don't care about ipv6's extention header icmpv6_pkt = self.find_packet(msg,'icmpv6') if icmpv6_pkt != None: if icmpv6_pkt.type_ == icmpv6.ND_NEIGHBOR_SOLICIT: self.port_to_ipv6.setdefault(dpid,{}) #self.port_to_ipv6[dpid][in_port]=hexlify(((ipv6_pkt.src & (1<<128))-(1<<64)) + (1<<64) - 2) self.port_to_ipv6[dpid][in_port]=struct.pack('!4I',0x100000,0x0,0xffffffff,0xfffffffd) if icmpv6_pkt.data.dst == self.port_to_ipv6[dpid][in_port]: #send a ND_NEIGHBOR_REPLY packet ether_dst = src ether_src = self.port_to_switch_mac[dpid][in_port] e = ethernet.ethernet(ether_dst,ether_src,ether.ETH_TYPE_IPV6) ic6_data_data = icmpv6.nd_option_la(hw_src=self.port_to_switch_mac[dpid][in_port],data=None) #res = 3 or 7 ic6_data = icmpv6.nd_neighbor(res=3,dst=icmpv6_pkt.data.dst,type_=icmpv6.nd_neighbor.ND_OPTION_TLA,length=1,data=ic6_data_data) ic6 = icmpv6.icmpv6(type_=icmpv6.ND_NEIGHBOR_ADVERT,code=0,csum=0,data=ic6_data) #payload_length i6 = ipv6.ipv6(version= 6,traffic_class=0,flow_label=0,payload_length=32,nxt=58,hop_limit=255, src=icmpv6_pkt.data.dst,dst=ipv6_pkt.src) p = Packet() p.add_protocol(e) p.add_protocol(i6) p.add_protocol(ic6) p.serialize() datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE,actions=[datapath.ofproto_parser.OFPActionOutput(in_port)],data=p.data) print 'send a NA packet' if icmpv6_pkt.type_ == icmpv6.ICMPV6_ECHO_REQUEST: if self.port_to_ipv6[dpid].has_key(in_port): #print hexlify(self.port_to_ipv6[dpid][in_port]) #print 'ipv6_pkt.dst is',hexlify(ipv6_pkt.dst) #print 'ipv6_pkt.dst is',hexlify(ipv6_pkt.dst) if ipv6_pkt.dst == self.port_to_ipv6[dpid][in_port]: ether_dst = src ether_src = self.port_to_switch_mac[dpid][in_port] e = ethernet.ethernet(ether_dst,ether_src,ether.ETH_TYPE_IPV6) ic6_data = icmpv6_pkt.data ic6 = icmpv6.icmpv6(type_=icmpv6.ICMPV6_ECHO_REPLY,code=0,csum=0,data=ic6_data) i6 = ipv6.ipv6(version= 6,traffic_class=0,flow_label=0,payload_length=64,nxt=58,hop_limit=64, src=ipv6_pkt.dst,dst=ipv6_pkt.src) p = Packet() p.add_protocol(e) p.add_protocol(i6) p.add_protocol(ic6) p.serialize() datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE,actions=[datapath.ofproto_parser.OFPActionOutput(in_port)],data=p.data) print 'send a ping6 reply packet' # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = msg.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 = [datapath.ofproto_parser.OFPActionOutput(out_port)] if out_port != ofproto.OFPP_FLOOD: if _eth_type == ether.ETH_TYPE_IP: self.add_flow(datapath, msg.in_port, dst, actions) #add a ipv6 flow table pay attention ipv6_flow entry only be added once when ipv4 flow entry is added elif _eth_type == ether.ETH_TYPE_IPV6: ''' # judge if src and dst addr is special # eg: src [0,0,0,0] dst begin with 0xff01 or 0x ff02 if ipv6_src == [0,0,0,0] or ipv6_dst[0]&0xff010000 == 0xff010000 or ipv6_dst[0]&0xff020000 == 0xff020000: print 'ipv6 reserved address\n' #elif ipv6_dst[0]&0xfe800000 == 0xfe800000: # print 'ipv6 dst address is Link-Local address' else: ''' ipv6_pkt = self.find_packet(msg,'ipv6') #ipv6_src=struct.pack('!4I',self._binary_to_ipv6_format(ipv6_packet.src)) #ipv6_dst=struct.pack('!4I',self._binary_to_ipv6_format(ipv6_packet.dst)) ipv6_src = convert.bin_to_ipv6_arg_list(ipv6_pkt.src) ipv6_dst = convert.bin_to_ipv6_arg_list(ipv6_pkt.dst) """ ipv6_src = struct.pack('!4I',int(hexlify(ipv6_pkt.src)[0:8],16),int(hexlify(ipv6_pkt.src)[8:16],16),int(hexlify(ipv6_pkt.src)[16:24],16),int(hexlify(ipv6_pkt.src)[24:32],16)) ipv6_dst = struct.pack('!4I',int(hexlify(ipv6_pkt.dst)[0:8],16),int(hexlify(ipv6_pkt.dst)[8:16],16),int(hexlify(ipv6_pkt.dst)[16:24],16),int(hexlify(ipv6_pkt.dst)[24:32],16)) """ rule={'ipv6_src':ipv6_src,'ipv6_dst':ipv6_dst} self.nx_ipv6_add_flow(datapath,rule,actions) print 'add a ipv6 flow entry' else: pass out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port, actions=actions) datapath.send_msg(out)