179 lines
5.7 KiB
Python
179 lines
5.7 KiB
Python
#!/usr/bin/env python3
|
|
# Written by Jonatan Langlet for Direct Telemetry Access
|
|
# 用于向 Translator 注入合成的 DTA Report 数据包,但是速度太慢,不太适合基准测试,但比较适合测试转换能力
|
|
|
|
#from scapy.all import send, IP, ICMP
|
|
from scapy.all import *
|
|
import random
|
|
import sys
|
|
import binascii
|
|
import struct
|
|
import argparse
|
|
import time
|
|
|
|
parser = argparse.ArgumentParser(description='Inject a DTA Key-Write packet into the Tofino ASIC.')
|
|
parser.add_argument('operation', type=str, nargs='+', choices=["keywrite", "append"], help='The DTA operation')
|
|
parser.add_argument('--data', type=int, nargs='+', help='The telemetry data')
|
|
parser.add_argument('--key', type=int, nargs='+', help='The telemetry key for KeyWrite operations')
|
|
parser.add_argument('--redundancy', type=int, nargs='+', help='The telemetry redundancy for KeyWrite operations')
|
|
parser.add_argument('--listID', type=int, nargs='+', help='The telemetry list ID for Append operations')
|
|
parser.add_argument('--loop', action='store_true', help='Indicates that the script should loop, generating traffic continuously')
|
|
parser.add_argument('--increment_data', action='store_true', help='Indicates that the data value should increment, if looping is enabled')
|
|
parser.add_argument('--increment_key', action='store_true', help='Indicates that the key-write key should increment, if looping is enabled')
|
|
parser.add_argument('--ipg', type=float, default=0.0, help='The IPG to replay traffic at, if emitting multiple packets simultaneously')
|
|
parser.add_argument('--batchsize', type=int, default=1, help='The batch size to use when --loop is enabled')
|
|
|
|
#args = vars(parser.parse_args())
|
|
args = parser.parse_args()
|
|
print(args)
|
|
|
|
|
|
class dta_base(Packet):
|
|
name = "dtaBase"
|
|
fields_desc = [
|
|
XByteField("opcode", 0x01),
|
|
XByteField("seqnum", 0), # DTA sequence number
|
|
BitField("immediate", 0, 1),
|
|
BitField("retransmitable", 0, 1),
|
|
BitField("reserved", 0, 6)
|
|
]
|
|
|
|
class dta_keyWrite(Packet):
|
|
name = "dtaKeyWrite"
|
|
fields_desc = [
|
|
ByteField("redundancy", 0x02),
|
|
# IntField("key", 0),
|
|
IntField("key", 0),
|
|
IntField("data", 0)
|
|
]
|
|
|
|
class dta_append(Packet):
|
|
name = "dtaAppend"
|
|
fields_desc = [
|
|
IntField("listID", 0),
|
|
IntField("data", 0)
|
|
]
|
|
|
|
def craft_dta_keywrite(key, data, redundancy):
|
|
''' 使用 key, data, redundancy 创建一个 DTA Key-Write 数据包 '''
|
|
|
|
print("Crafting a keywrite packet with key:%i data:%i, redundancy:%i" %(key,data,redundancy))
|
|
|
|
key_bin = struct.pack(">I", key)
|
|
|
|
pkt = Ether(dst="08:c0:eb:58:92:89")\
|
|
/IP(src="192.168.1.91", dst="192.168.4.3")\
|
|
/UDP(sport=40041, dport=40040)\
|
|
/dta_base(opcode=0x01)\
|
|
/dta_keyWrite(redundancy=redundancy, key=RawVal(key_bin), data=data)
|
|
#/dta_keyWrite(redundancy=redundancy, key=key, data=data)
|
|
|
|
return pkt
|
|
|
|
|
|
def craft_dta_append(listID, data):
|
|
''' 使用 listID, data 创建一个 DTA Append 数据包 '''
|
|
|
|
print("Crafting an append packet with listID:%i data:%i" %(listID,data))
|
|
|
|
pkt = Ether(dst="08:c0:eb:58:92:89")\
|
|
/IP(src="192.168.1.91", dst="192.168.4.3")\
|
|
/UDP(sport=40041, dport=40040)\
|
|
/dta_base(opcode=0x02)\
|
|
/dta_append(listID=listID, data=data)
|
|
|
|
return pkt
|
|
|
|
|
|
def emitPacket(pkts):
|
|
''' 以 IPG(Inter Packet Gap)(如果定义了的话) 为时间间隔来发送传入的数据包 '''
|
|
|
|
ipg = args.ipg
|
|
print("Sending %i DTA packet(s) at ipg:%.3f" % (len(pkts), ipg))
|
|
sendp(pkts, inter=ipg, iface="ma1")
|
|
|
|
|
|
# DTA Key-Write 数据包测试
|
|
if args.operation[0] == "keywrite":
|
|
print("Crafting a DTA KeyWrite packet...")
|
|
|
|
assert args.key, "No telemetry key specified!"
|
|
assert args.redundancy, "No telemetry redundancy specified!"
|
|
assert args.data, "No telemetry data specified!"
|
|
|
|
# 首先传入 Key-Write 数据包制作所需的参数
|
|
key = args.key[0]
|
|
data = args.data[0]
|
|
redundancy = args.redundancy[0]
|
|
doLoop = args.loop
|
|
increment_data = args.increment_data
|
|
increment_key = args.increment_key
|
|
|
|
# 如果启用循环的话,则持续递增,用于一次性的可靠性测试
|
|
if doLoop:
|
|
# 单个批次中元素的数量
|
|
batchSize = args.batchsize
|
|
print("Looping enabled with batchsize %i" % batchSize)
|
|
|
|
# 依次制作 batchSize 个 Key-Write 数据包并一起发送
|
|
pkts = []
|
|
while True:
|
|
pkt = craft_dta_keywrite(key=key, data=data, redundancy=redundancy)
|
|
|
|
pkts.append(pkt)
|
|
|
|
if len(pkts) >= batchSize:
|
|
emitPacket(pkts)
|
|
pkts = []
|
|
print("sleeping 1 sec before next batch...")
|
|
time.sleep(1)
|
|
|
|
# 对 key 和 data 进行依次递增操作
|
|
if increment_key:
|
|
key = key + 1
|
|
if increment_data:
|
|
data = data + 1
|
|
print("Incremented key:%i and data:%i" %(key,data))
|
|
# 这是默认功能,用于制作和发送单个数据包
|
|
else:
|
|
print("Looping disabled, sending single packet")
|
|
pkt = craft_dta_keywrite(key=key, data=data, redundancy=redundancy)
|
|
emitPacket(pkt)
|
|
|
|
# DTA Append 数据包测试
|
|
if args.operation[0] == "append":
|
|
print("Crafting a DTA Append packet...")
|
|
|
|
assert args.listID, "No telemetry list ID specified!"
|
|
assert args.data, "No telemetry data specified!"
|
|
|
|
# 首先传入 Append 数据包制作所需的参数
|
|
doLoop = args.loop
|
|
listID = args.listID[0]
|
|
data = args.data[0]
|
|
increment_data = args.increment_data
|
|
|
|
# 如果启用循环的话,则持续递增,用于一次性的可靠性测试
|
|
if doLoop:
|
|
batchSize = args.batchsize
|
|
print("Looping enabled with batchsize %i" %batchSize)
|
|
|
|
pkts = []
|
|
while True:
|
|
pkt = craft_dta_append(listID=listID, data=data)
|
|
|
|
pkts.append(pkt)
|
|
|
|
if len(pkts) >= batchSize:
|
|
emitPacket(pkts)
|
|
pkts = []
|
|
|
|
if increment_data:
|
|
data = data + 1
|
|
print("Incremented data:%i" %(data))
|
|
# 这是默认功能,用于制作和发送单个数据包
|
|
else:
|
|
pkt = craft_dta_append(listID=listID, data=data)
|
|
emitPacket(pkt)
|
|
|