def send_frame(self, frame_body): PACKET = Ether() PACKET.length = 64 PACKET.dst = self.dst PACKET.src = self.getHwAddr(self.interface) if self.stag: # WARNING: September/2016: This should be 0x88a8, but the Intel 10G # hardware I am currently using does not support receiving a TPID of # 0x88a8. So, I send double CTAGs, and I usually set this to 0x8100. # (NOTE: The Intel hardware can send a TPID of 0x88a8) PACKET.type = 0x8100 if self.ctag: PACKET/=Dot1Q(type=0x8100,vlan=int(self.stag)) PACKET/=Dot1Q(type=self.etype,vlan=int(self.ctag)) else: PACKET/=Dot1Q(type=self.etype,vlan=int(self.stag)) else: if self.ctag: PACKET.type = 0x8100 PACKET/=Dot1Q(type=self.etype,vlan=int(self.ctag)) else: PACKET.type = self.etype # PACKET/=Dot1Q(type=self.etype, vlan=int(self.ctag)) PACKET/=SlowProtocolsSubtype()/FlagsBytes()/OAMPDU() PACKET/=frame_body PACKET/=EndOfPDU() if (self.verbose == True): PACKET.show() print '###[ Frame Length %d (before padding) ]###' % len(PACKET) if (self.hexdump == True): print hexdump(PACKET) if (self.dryrun != True): sendp(PACKET, iface=self.interface, verbose=self.verbose) time.sleep(self.sleep) return PACKET
def create_packet_header_IPv6_SRH_L2(self, srcaddr, sidlist, segleft, vlan=0): """Create packet header: L2 encapsulated in SRv6: IPv6 header with SRH, L2 :param int srcaddr: IPv6 source address :param list sidlist: segment list of outer IPv6 SRH :param int segleft: segments-left field of outer IPv6 SRH :param vlan: L2 vlan; if vlan!=0 then add 802.1q header IPv6 source address is set to srcaddr IPv6 destination address is set to sidlist[segleft] """ eth = Ether(src='00:11:22:33:44:55', dst='00:55:44:33:22:11') etype = 0x8137 # IPX if vlan: # add 802.1q layer eth /= Dot1Q(vlan=vlan, type=etype) else: eth.type = etype p = IPv6(src=srcaddr, dst=sidlist[segleft]) / \ IPv6ExtHdrSegmentRouting(addresses=sidlist, segleft=segleft, nh=59) / \ eth return p
def create_lldp_packet(mac_addr, switch_name, port_id): # indicate the swith name chassis_tlv = Chassis_Id() chassis_tlv.subtype = 0x07 chassis_tlv.length = len(switch_name) + 1 chassis_tlv.locallyAssigned = switch_name # indicate the port ID port_tlv = Port_Id() port_tlv.subtype = 0x7 port_tlv.length = len(port_id) + 1 port_tlv.locallyAssigned = port_id # TTL ttl_tlv = TTL() ttl_tlv.length = 2 ttl_tlv.seconds = 0 # The end end_tlv = EndOfPDU() # Create the frame frame = Ether() frame.src = mac_addr frame.dst = '01:80:c2:00:00:0e' frame.type = 0x88cc packet = frame / chassis_tlv / port_tlv / ttl_tlv / end_tlv return packet
async def recv(self): rx_header = await self.header_sink.recv() rx_payload = await self.payload_sink.recv() assert not rx_payload.tuser eth = Ether() eth.dst = rx_header.dest_mac.integer.to_bytes(6, 'big') eth.src = rx_header.src_mac.integer.to_bytes(6, 'big') eth.type = rx_header.type.integer rx_pkt = eth / bytes(rx_payload.tdata) return Ether(bytes(rx_pkt))
async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=None, backpressure_inserter=None): tb = TB(dut) await tb.reset() tb.set_idle_generator(idle_inserter) tb.set_backpressure_generator(backpressure_inserter) test_pkts = [] test_frames = [] for payload in [payload_data(x) for x in payload_lengths()]: eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5', type=0x8000) test_pkt = eth / payload test_pkts.append(test_pkt.copy()) test_frame = AxiStreamFrame(test_pkt.build()) test_frames.append(test_frame) await tb.source.send(test_frame) for test_pkt, test_frame in zip(test_pkts, test_frames): rx_header = await tb.header_sink.recv() rx_payload = await tb.payload_sink.recv() eth = Ether() eth.dst = rx_header.dest_mac.integer.to_bytes(6, 'big') eth.src = rx_header.src_mac.integer.to_bytes(6, 'big') eth.type = rx_header.type.integer rx_pkt = eth / bytes(rx_payload.tdata) tb.log.info("RX packet: %s", repr(rx_pkt)) assert rx_pkt.build() == test_pkt.build() assert not rx_payload.tuser assert tb.header_sink.empty() assert tb.payload_sink.empty() await RisingEdge(dut.clk) await RisingEdge(dut.clk)
def create_packet_header_L2(self, vlan=0): """Create packet header: L2 header :param vlan: if vlan!=0 then add 802.1q header """ # Note: the dst addr ('00:55:44:33:22:11') is used in # the compare function compare_rx_tx_packet_T_Encaps_L2 # to detect presence of L2 in SRH payload p = Ether(src='00:11:22:33:44:55', dst='00:55:44:33:22:11') etype = 0x8137 # IPX if vlan: # add 802.1q layer p /= Dot1Q(vlan=vlan, type=etype) else: p.type = etype return p
async def recv(self): rx_frame = await self.sink.recv() eth = Ether() eth.dst = rx_frame.eth_dest_mac.integer.to_bytes(6, 'big') eth.src = rx_frame.eth_src_mac.integer.to_bytes(6, 'big') eth.type = rx_frame.eth_type.integer arp = ARP() arp.hwtype = rx_frame.arp_htype.integer arp.ptype = rx_frame.arp_ptype.integer arp.hwlen = rx_frame.arp_hlen.integer arp.plen = rx_frame.arp_plen.integer arp.op = rx_frame.arp_oper.integer arp.hwsrc = rx_frame.arp_sha.integer.to_bytes(6, 'big') arp.psrc = rx_frame.arp_spa.integer arp.hwdst = rx_frame.arp_tha.integer.to_bytes(6, 'big') arp.pdst = rx_frame.arp_tpa.integer rx_pkt = eth / arp return Ether(bytes(rx_pkt))
def main(): """Send IP/IPv6 packet from one traffic generator interface to the other.""" args = TrafficScriptArg([ u"tg_src_mac", u"tg_dst_mac", u"src_ip", u"dst_ip", u"dut_if1_mac", u"dut_if2_mac" ], [ u"encaps_tx", u"vlan_tx", u"vlan_outer_tx", u"encaps_rx", u"vlan_rx", u"vlan_outer_rx" ]) tx_src_mac = args.get_arg(u"tg_src_mac") tx_dst_mac = args.get_arg(u"dut_if1_mac") rx_dst_mac = args.get_arg(u"tg_dst_mac") rx_src_mac = args.get_arg(u"dut_if2_mac") src_ip = args.get_arg(u"src_ip") dst_ip = args.get_arg(u"dst_ip") tx_if = args.get_arg(u"tx_if") rx_if = args.get_arg(u"rx_if") encaps_tx = args.get_arg(u"encaps_tx") vlan_tx = args.get_arg(u"vlan_tx") vlan_outer_tx = args.get_arg(u"vlan_outer_tx") encaps_rx = args.get_arg(u"encaps_rx") vlan_rx = args.get_arg(u"vlan_rx") vlan_outer_rx = args.get_arg(u"vlan_outer_rx") rxq = RxQueue(rx_if) txq = TxQueue(tx_if) sent_packets = list() pkt_raw = Ether(src=tx_src_mac, dst=tx_dst_mac) if encaps_tx == u"Dot1q": pkt_raw /= Dot1Q(vlan=int(vlan_tx)) elif encaps_tx == u"Dot1ad": pkt_raw.type = 0x88a8 pkt_raw /= Dot1Q(vlan=vlan_outer_tx) pkt_raw /= Dot1Q(vlan=vlan_tx) if valid_ipv4(src_ip) and valid_ipv4(dst_ip): pkt_raw /= IP(src=src_ip, dst=dst_ip, proto=61) ip_format = IP elif valid_ipv6(src_ip) and valid_ipv6(dst_ip): pkt_raw /= IPv6(src=src_ip, dst=dst_ip) ip_format = IPv6 else: raise ValueError(u"IP not in correct format") pkt_raw /= Raw() sent_packets.append(pkt_raw) txq.send(pkt_raw) while True: if tx_if == rx_if: ether = rxq.recv(2, ignore=sent_packets) else: ether = rxq.recv(2) if ether is None: raise RuntimeError(u"IP packet Rx timeout") if ether.haslayer(ICMPv6ND_NS): # read another packet in the queue if the current one is ICMPv6ND_NS continue else: # otherwise process the current packet break if rx_dst_mac == ether[Ether].dst and rx_src_mac == ether[Ether].src: logger.trace(u"MAC matched") else: raise RuntimeError(f"Matching packet unsuccessful: {ether!r}") if encaps_rx == u"Dot1q": if ether[Dot1Q].vlan == int(vlan_rx): logger.trace(u"VLAN matched") else: raise RuntimeError(f"Ethernet frame with wrong VLAN tag " f"({ether[Dot1Q].vlan}-received, " f"{vlan_rx}-expected):\n{ether!r}") ip = ether[Dot1Q].payload elif encaps_rx == u"Dot1ad": raise NotImplementedError() else: ip = ether.payload if not isinstance(ip, ip_format): raise RuntimeError(f"Not an IP packet received {ip!r}") # Compare data from packets if src_ip == ip.src: logger.trace(u"Src IP matched") else: raise RuntimeError( f"Matching Src IP unsuccessful: {src_ip} != {ip.src}") if dst_ip == ip.dst: logger.trace(u"Dst IP matched") else: raise RuntimeError( f"Matching Dst IP unsuccessful: {dst_ip} != {ip.dst}") sys.exit(0)
def extract_one_packet(buf): """Extract one packet from the incoming buf buffer. Takes string as input and looks for first whole packet in it. If it finds one, it returns substring from the buf parameter. :param buf: String representation of incoming packet buffer. :type buf: str :returns: String representation of first packet in buf. :rtype: str """ pkt_len = 0 if len(buf) < 60: return None try: ether_type = Ether(buf[0:14]).type except AttributeError: raise RuntimeError(f"No EtherType in packet {buf!r}") if ether_type == ETH_P_IP: # 14 is Ethernet fame header size. # 4 bytes is just enough to look for length in ip header. # ip total length contains just the IP packet length so add the Ether # header. pkt_len = Ether(buf[0:14 + 4]).len + 14 if len(buf) < 60: return None elif ether_type == ETH_P_IPV6: if not Ether(buf[0:14 + 6]).haslayer(IPv6): raise RuntimeError(f"Invalid IPv6 packet {buf!r}") # ... to add to the above, 40 bytes is the length of IPV6 header. # The ipv6.len only contains length of the payload and not the header pkt_len = Ether(buf)[u"IPv6"].plen + 14 + 40 if len(buf) < 60: return None elif ether_type == ETH_P_ARP: pkt = Ether(buf[:20]) if not pkt.haslayer(ARP): raise RuntimeError(u"Incomplete ARP packet") # len(eth) + arp(2 hw addr type + 2 proto addr type # + 1b len + 1b len + 2b operation) pkt_len = 14 + 8 pkt_len += 2 * pkt.getlayer(ARP).hwlen pkt_len += 2 * pkt.getlayer(ARP).plen del pkt elif ether_type == 32821: # RARP (Reverse ARP) pkt = Ether(buf[:20]) pkt.type = ETH_P_ARP # Change to ARP so it works with scapy pkt = Ether(pkt) if not pkt.haslayer(ARP): pkt.show() raise RuntimeError(u"Incomplete RARP packet") # len(eth) + arp(2 hw addr type + 2 proto addr type # + 1b len + 1b len + 2b operation) pkt_len = 14 + 8 pkt_len += 2 * pkt.getlayer(ARP).hwlen pkt_len += 2 * pkt.getlayer(ARP).plen del pkt else: raise RuntimeError(f"Unknown protocol {ether_type}") if pkt_len < 60: pkt_len = 60 if len(buf) < pkt_len: return None return buf[0:pkt_len]
def main(): """Send IP ICMP packet from one traffic generator interface to the other.""" args = TrafficScriptArg([ 'tg_src_mac', 'tg_dst_mac', 'src_ip', 'dst_ip', 'dut_if1_mac', 'dut_if2_mac' ], [ 'encaps_tx', 'vlan_tx', 'vlan_outer_tx', 'encaps_rx', 'vlan_rx', 'vlan_outer_rx' ]) tx_src_mac = args.get_arg('tg_src_mac') tx_dst_mac = args.get_arg('dut_if1_mac') rx_dst_mac = args.get_arg('tg_dst_mac') rx_src_mac = args.get_arg('dut_if2_mac') src_ip = args.get_arg('src_ip') dst_ip = args.get_arg('dst_ip') tx_if = args.get_arg('tx_if') rx_if = args.get_arg('rx_if') encaps_tx = args.get_arg('encaps_tx') vlan_tx = args.get_arg('vlan_tx') vlan_outer_tx = args.get_arg('vlan_outer_tx') encaps_rx = args.get_arg('encaps_rx') vlan_rx = args.get_arg('vlan_rx') vlan_outer_rx = args.get_arg('vlan_outer_rx') rxq = RxQueue(rx_if) txq = TxQueue(tx_if) sent_packets = [] ip_format = '' pkt_raw = Ether(src=tx_src_mac, dst=tx_dst_mac) if encaps_tx == 'Dot1q': pkt_raw /= Dot1Q(vlan=int(vlan_tx)) elif encaps_tx == 'Dot1ad': pkt_raw.type = 0x88a8 pkt_raw /= Dot1Q(vlan=vlan_outer_tx) pkt_raw /= Dot1Q(vlan=vlan_tx) if valid_ipv4(src_ip) and valid_ipv4(dst_ip): pkt_raw /= IP(src=src_ip, dst=dst_ip) pkt_raw /= ICMP() ip_format = IP elif valid_ipv6(src_ip) and valid_ipv6(dst_ip): pkt_raw /= IPv6(src=src_ip, dst=dst_ip) pkt_raw /= ICMPv6EchoRequest() ip_format = IPv6 else: raise ValueError("IP not in correct format") sent_packets.append(pkt_raw) txq.send(pkt_raw) if tx_if == rx_if: ether = rxq.recv(2, ignore=sent_packets) else: ether = rxq.recv(2) if ether is None: raise RuntimeError("ICMP echo Rx timeout") if rx_dst_mac == ether[Ether].dst and rx_src_mac == ether[Ether].src: logger.trace("MAC matched") else: raise RuntimeError("Matching packet unsuccessful: {0}".format( ether.__repr__())) if encaps_rx == 'Dot1q': if ether[Dot1Q].vlan == int(vlan_rx): logger.trace("VLAN matched") else: raise RuntimeError('Ethernet frame with wrong VLAN tag ({}-' 'received, {}-expected):\n{}'.format( ether[Dot1Q].vlan, vlan_rx, ether.__repr__())) ip = ether[Dot1Q].payload elif encaps_rx == 'Dot1ad': raise NotImplementedError() else: ip = ether.payload if not isinstance(ip, ip_format): raise RuntimeError("Not an IP packet received {0}".format( ip.__repr__())) # Compare data from packets if src_ip == ip.src: logger.trace("Src IP matched") else: raise RuntimeError("Matching Src IP unsuccessful: {} != {}".format( src_ip, ip.src)) if dst_ip == ip.dst: logger.trace("Dst IP matched") else: raise RuntimeError("Matching Dst IP unsuccessful: {} != {}".format( dst_ip, ip.dst)) sys.exit(0)
def main(): """Send packet from one traffic generator interface to the other.""" args = TrafficScriptArg([ u"tg_if1_mac", u"dut_if1_mac", u"flow_type", u"proto", ], [u"src_ip", u"dst_ip", u"src_port", u"dst_port", u"value"]) tx_if = args.get_arg(u"tx_if") tx_src_mac = args.get_arg(u"tg_if1_mac") tx_dst_mac = args.get_arg(u"dut_if1_mac") flow_type = args.get_arg(u"flow_type") proto = args.get_arg(u"proto") src = args.get_arg(u"src_ip") dst = args.get_arg(u"dst_ip") sport = eval(args.get_arg(u"src_port")) dport = eval(args.get_arg(u"dst_port")) value = eval(args.get_arg(u"value")) txq = TxQueue(tx_if) if flow_type == u"IP4": pkt_raw = (Ether(src=tx_src_mac, dst=tx_dst_mac) / IP(src=src, dst=dst)) elif flow_type == u"IP6": pkt_raw = (Ether(src=tx_src_mac, dst=tx_dst_mac) / IPv6(src=src, dst=dst)) elif flow_type == u"ETHER": pkt_raw = Ether(src=tx_src_mac, dst=tx_dst_mac) else: raise ValueError(f"Flow type error: {flow_type}") if proto == u"TCP": pkt_raw /= TCP(sport=sport, dport=dport) elif proto == u"UDP": pkt_raw /= UDP(sport=sport, dport=dport) elif proto == u"AH": pkt_raw /= AH(spi=value) elif proto == u"ESP": pkt_raw /= ESP(spi=value) elif proto == u"GTPU": pkt_raw /= (UDP() / GTP_U_Header(teid=value) / IP(src=u"192.168.10.20")) elif proto == u"L2TPV3": value_hex = hex(value).replace('0x', (8 - len(hex(value)) + 2) * '0') session_id = binascii.a2b_hex(value_hex) pkt_raw.proto = 115 pkt_raw /= Raw(session_id) elif proto == u"VXLAN": pkt_raw /= (UDP() / VXLAN(vni=value)) elif proto == u"ARP": pkt_raw.type = value pkt_raw /= ARP() else: raise ValueError(f"Flow proto error: {proto}") pkt_raw /= Raw() txq.send(pkt_raw) sys.exit(0)
def getIPPacket(self): """ 构造IP数据包 :return: """ # chksum = self.entries[9].get() try: eth = Ether() eth.src = self.entries[0].get() eth.dst = self.entries[1].get() eth.type = int(self.entries[2].get()) ip_packet = IP() ip_packet.versionion = int(self.entries[3].get()) ip_packet.ihl = int(self.entries[4].get()) ip_packet.tos = int(self.entries[5].get()) ip_packet.len = int(self.entries[6].get()) ip_packet.id = int(self.entries[7].get()) ip_packet.flags = int(self.entries[8].get()) ip_packet.frag = int(self.entries[9].get()) ip_packet.ttl = int(self.entries[10].get()) ip_packet.proto = int(self.entries[11].get()) payload = self.entries[16].get() ip_packet.src = self.entries[13].get() ip_packet.dst = self.entries[14].get() # 不含payload计算首部校验和 if payload == '': print("无payload的IP报文") ip_packet.show() checksum_scapy = IP(raw(ip_packet)).chksum # 自主计算验证IP首部检验和并进行填充 print("scapy自动计算的IP首部检验和是:%04x (%s)" % (checksum_scapy, str(checksum_scapy))) # 1.将IP首部和自动设置为0 ip_packet.chksum = 0 # 2.生成ip首部的数据字符串 x = raw(ip_packet) ipString = "".join("%02x" % orb(x) for x in x) # 3.将ip首部的数据字符串转换成字节数组 ipbytes = bytearray.fromhex(ipString) # 4.调用校验和计算函数计算校验和 checksum_self = self.IP_headchecksum(ipbytes) # 5.进行校验和验证 print("验证计算IP首部的检验和是:%04x (%s)" % (checksum_self, str(checksum_self))) # 含payload计算首部校验和 else: print("含有payload的IP报文") ip_packet = ip_packet / payload ip_packet.show() ip_packet.len = 20 + len(payload) checksum_scapy = IP(raw(ip_packet)).chksum print("scapy自动计算的IP首部检验和是:%04x (%s)" % (checksum_scapy, str(checksum_scapy))) ip_packet.chksum = 0 ip_packet.ihl = 5 print('\n 报文长度是:%s' % str(ip_packet.len)) x = raw(ip_packet) ipString = "".join("%02x" % orb(x) for x in x) ipbytes = bytearray.fromhex(ipString) checksum_self = self.IP_headchecksum(ipbytes[0:ip_packet.ihl * 4]) print("验证计算IP首部的检验和是:%04x (%s)" % (checksum_self, str(checksum_self))) if checksum_self == checksum_scapy: print("检验和正确") else: print("检验和不正确") ip_packet.chksum = checksum_self self.entries[12].delete(0, END) self.entries[12].insert(0, hex(ip_packet.chksum)) ip_packet.show() self.resultText.insert('end', ip_packet.summary() + '\n') self.resultText.insert('end', str(ip_packet) + '\n') return eth / ip_packet except Exception as e: print(e.with_traceback()) finally: pass