CAR/wly_experiment/dta_codes/translator/inject_dta.py
2025-04-14 22:25:58 +08:00

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)