summaryrefslogtreecommitdiffstats
path: root/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py
diff options
context:
space:
mode:
authorHanoh Haim <hhaim@cisco.com>2016-03-14 13:37:44 +0200
committerHanoh Haim <hhaim@cisco.com>2016-03-14 13:37:44 +0200
commitd82201e2da3beb0e81e0c8ba30600d87f1b8276f (patch)
tree0fadfe1cbedba4c0a56b0aba49cf54c531c4f02e /scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py
parent33386099a94c8940616cdd9c3f674f0ee63d8af6 (diff)
some cleanup for API doc
Diffstat (limited to 'scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py')
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py331
1 files changed, 299 insertions, 32 deletions
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py
index eac12ebb..35326590 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_packet_builder_scapy.py
@@ -172,12 +172,12 @@ class CTRexScTrimPacketSize(CTRexScriptsBase):
raise CTRexPacketBuildException(-11, 'CTRexScTrimPacketSize min_pkt_size is bigger than max_pkt_size ');
-class CTRexScRaw(CTRexScriptsBase):
+class STLScVmRaw(CTRexScriptsBase):
"""
raw instructions
"""
def __init__(self,list_of_commands=None,split_by_field=None):
- super(CTRexScRaw, self).__init__()
+ super(STLScVmRaw, self).__init__()
self.split_by_field = split_by_field
if list_of_commands==None:
self.commands =[]
@@ -526,16 +526,62 @@ def check_for_int (val):
assert type(val)==int, 'type of vcal is not int'
-class CTRexVmDescFlowVar(CTRexVmDescBase):
- """
- flow var instruction
- """
+class STLVmFlowVar(CTRexVmDescBase):
def __init__(self, name, init_value=None, min_value=0, max_value=255, size=4, step=1,op="inc"):
"""
-
+ Flow variable instruction. Allocate a variable on a stream context. The size of the variable could be determined
+ The operation can be inc, dec and random. In case of increment and decrement operation, it is possible to set the "step" size.
+ Initialization value, minimum and maximum value could be set too.
+
+ :parameters:
+ name : string
+ The name of the stream variable
+
+ init_value : int
+ The init value of the variable. in case of None it will be min_value
+
+ min_value : int
+ The min value
+
+ max_value : int
+ The max value
+
+ size : int
+ the number of bytes of the variable. could be 1,2,4,8 for uint8_t, uint16_t, uint32_t, uint64_t
+
+ step : int
+ step in case of "inc","dec" operation
+
+ op : string
+ could be "inc", "dec", "random"
+
+ For example::
+
+ # input
+ STLVmFlowVar(min_value=0, max_value=3, size=1,op="inc")
+
+ # output 0,1,2,3,0,1,2,3 ..
+
+ # input
+ STLVmFlowVar(min_value=0, max_value=3, size=1,op="dec")
+
+ # output 0,3,2,1,0,3,2,1 ..
+
+
+ # input
+ STLVmFlowVar(min_value=0, max_value=3, size=1,op="random")
+
+ # output 1,1,2,3,1,2,1,0 ..
+
+ # input
+ STLVmFlowVar(min_value=0, max_value=10, size=1,op="inc",step=3)
+
+ # output 0,3,6,9,0,3,6,9,0..
+
+
"""
- super(CTRexVmDescFlowVar, self).__init__()
+ super(STLVmFlowVar, self).__init__()
self.name = name;
assert type(name)==str, 'type of name is not str'
self.size =size
@@ -562,9 +608,32 @@ class CTRexVmDescFlowVar(CTRexVmDescBase):
return [self.name]
-class CTRexVmDescFixIpv4(CTRexVmDescBase):
+class STLVmFixIpv4(CTRexVmDescBase):
def __init__(self, offset):
- super(CTRexVmDescFixIpv4, self).__init__()
+ """
+ Fix IPv4 header checksum. should be added if the packet header was changed and there is a need to fix he checksum
+
+ :parameters:
+ offset : uint16_t or string
+ **IPv4 header** offset from packet start. It is **not** the offset of the checksum field itself.
+ in could be string in case of scapy packet. format IP[:[id]]
+
+ For example::
+
+ pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025)
+
+ # by offset
+ STLVmFixIpv4(offset=14)
+
+ # in case of scapy packet can be defined by header name
+ STLVmFixIpv4(offset="IP")
+
+ # string for second "IP" header in the packet is IP:1
+ STLVmFixIpv4(offset="IP:1")
+
+ """
+
+ super(STLVmFixIpv4, self).__init__()
self.offset = offset; # could be a name of offset
def get_obj (self):
@@ -574,9 +643,48 @@ class CTRexVmDescFixIpv4(CTRexVmDescBase):
if type(self.offset)==str:
self.offset = parent._pkt_layer_offset(self.offset);
-class CTRexVmDescWrFlowVar(CTRexVmDescBase):
+class STLVmWrFlowVar(CTRexVmDescBase):
def __init__(self, fv_name, pkt_offset, offset_fixup=0, add_val=0, is_big=True):
- super(CTRexVmDescWrFlowVar, self).__init__()
+ """
+ Write a stream variable into a packet field.
+ The write is done in size of the stream variable.
+ In case there is a need to change the write have a look into the command `STLVmWrMaskFlowVar`.
+ The Field name/offset can be given by name in this format ``header[:id].field``.
+
+
+ :parameters:
+ fv_name : string
+ the stream variable to write to a packet offset
+
+ pkt_offset : string or in
+ the name of the field or offset in byte from packet start.
+
+ offset_fixup : int
+ how many bytes to go forward. In case of a negative value go backward
+
+ add_val : int
+ value to add to stream variable before writing it to packet field. can be used as a constant offset
+
+ is_big : bool
+ how to write the variable to the the packet. is it big-edian or little edian
+
+ For example::
+
+ pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025)
+
+
+ # write to ip.src offset
+ STLVmWrFlowVar (fv_name="tuple", pkt_offset= "IP.src" )
+
+ # packet offset is varible
+ STLVmWrFlowVar (fv_name="tuple", pkt_offset= 26 )
+
+ # add l3_len_fix before writing fv_rand into IP.len field
+ STLVmWrFlowVar(fv_name="fv_rand", pkt_offset= "IP.len", add_val=l3_len_fix)
+
+ """
+
+ super(STLVmWrFlowVar, self).__init__()
self.name =fv_name
assert type(fv_name)==str, 'type of fv_name is not str'
self.offset_fixup =offset_fixup
@@ -598,9 +706,9 @@ class CTRexVmDescWrFlowVar(CTRexVmDescBase):
t=parent._name_to_offset(self.pkt_offset)
self.pkt_offset = t[0]
-class CTRexVmDescWrMaskFlowVar(CTRexVmDescBase):
+class STLVmWrMaskFlowVar(CTRexVmDescBase):
def __init__(self, fv_name, pkt_offset, pkt_cast_size=1, mask=0xff, shift=0, add_value=0, offset_fixup=0, is_big=True):
- super(CTRexVmDescWrMaskFlowVar, self).__init__()
+ super(STLVmWrMaskFlowVar, self).__init__()
self.name =fv_name
assert type(fv_name)==str, 'type of fv_name is not str'
self.offset_fixup =offset_fixup
@@ -633,9 +741,61 @@ class CTRexVmDescWrMaskFlowVar(CTRexVmDescBase):
self.pkt_offset = t[0]
-class CTRexVmDescTrimPktSize(CTRexVmDescBase):
+class STLVmTrimPktSize(CTRexVmDescBase):
+ """
+ Trim packet size by stream variable size. This instruction will only change the total packet size and will not fix up the fields to match the new size.
+
+
+ :parameters:
+ fv_name : string
+ the stream variable name. the value from this variable would be the new total packet size.
+
+
+
+ For example::
+
+ def create_stream (self):
+ # pkt
+ p_l2 = Ether();
+ p_l3 = IP(src="16.0.0.1",dst="48.0.0.1")
+ p_l4 = UDP(dport=12,sport=1025)
+ pyld_size = max(0, self.max_pkt_size_l3 - len(p_l3/p_l4));
+ base_pkt = p_l2/p_l3/p_l4/('\x55'*(pyld_size))
+
+ l3_len_fix =-(len(p_l2));
+ l4_len_fix =-(len(p_l2/p_l3));
+
+
+ # vm
+ vm = STLScVmRaw( [ STLVmFlowVar(name="fv_rand", min_value=64,
+ max_value=len(base_pkt),
+ size=2, op="inc"),
+
+ STLVmTrimPktSize("fv_rand"), # change total packet size <<<
+
+ STLVmWrFlowVar(fv_name="fv_rand",
+ pkt_offset= "IP.len",
+ add_val=l3_len_fix), # fix ip len
+
+ STLVmFixIpv4(offset = "IP"), # fix checksum
+
+ STLVmWrFlowVar(fv_name="fv_rand",
+ pkt_offset= "UDP.len",
+ add_val=l4_len_fix) # fix udp len
+ ]
+ )
+
+ pkt = STLPktBuilder(pkt = base_pkt,
+ vm = vm)
+
+ return STLStream(packet = pkt,
+ mode = STLTXCont())
+
+
+ """
+
def __init__(self,fv_name):
- super(CTRexVmDescTrimPktSize, self).__init__()
+ super(STLVmTrimPktSize, self).__init__()
self.name = fv_name
assert type(fv_name)==str, 'type of fv_name is not str'
@@ -647,9 +807,116 @@ class CTRexVmDescTrimPktSize(CTRexVmDescBase):
-class CTRexVmDescTupleGen(CTRexVmDescBase):
+class STLVmTupleGen(CTRexVmDescBase):
def __init__(self,name, ip_min="0.0.0.1", ip_max="0.0.0.10", port_min=1025, port_max=65535, limit_flows=100000, flags=0):
- super(CTRexVmDescTupleGen, self).__init__()
+ """
+ Generate a struct with two varibles. ``var_name.ip`` as uint32_t and ``var_name.port`` as uint16_t
+ The variable are dependent. When the ip variable is wrapped the port is getting increment.
+
+ For:
+
+ * ip_min = 10.0.0.1
+ * ip_max = 10.0.0.5
+ * port_min = 1025
+ * port_max = 1028
+ * limit_flows = 10
+
+ The result:
+
+ +------------+------------+-----------+
+ | ip | port | flow_id |
+ +============+============+===========+
+ | 10.0.0.1 | 1025 | 1 |
+ +------------+------------+-----------+
+ | 10.0.0.2 | 1025 | 2 |
+ +------------+------------+-----------+
+ | 10.0.0.3 | 1025 | 3 |
+ +------------+------------+-----------+
+ | 10.0.0.4 | 1025 | 4 |
+ +------------+------------+-----------+
+ | 10.0.0.5 | 1025 | 5 |
+ +------------+------------+-----------+
+ | 10.0.0.1 | 1026 | 6 |
+ +------------+------------+-----------+
+ | 10.0.0.2 | 1026 | 7 |
+ +------------+------------+-----------+
+ | 10.0.0.3 | 1026 | 8 |
+ +------------+------------+-----------+
+ | 10.0.0.4 | 1026 | 9 |
+ +------------+------------+-----------+
+ | 10.0.0.5 | 1026 | 10 |
+ +------------+------------+-----------+
+ | 10.0.0.1 | 1025 | 1 |
+ +------------+------------+-----------+
+
+
+ :parameters:
+ name : string
+ The name of the stream struct.
+
+ ip_min : string or int
+ The min value of the ip value. It can be in IPv4 format
+
+ ip_max : string or int
+ The max value of the ip value. It can be in IPv4 format
+
+ port_min : int
+ min value for port variable
+
+ port_max : int
+ max value for port variable
+
+ limit_flows : int
+ The limit of number of flows
+
+ flags : 0
+
+ ="0.0.0.10", port_min=1025, port_max=65535, limit_flows=100000, flags=0
+
+
+ For example::
+
+ def create_stream (self):
+ # pkt
+ p_l2 = Ether();
+ p_l3 = IP(src="16.0.0.1",dst="48.0.0.1")
+ p_l4 = UDP(dport=12,sport=1025)
+ pyld_size = max(0, self.max_pkt_size_l3 - len(p_l3/p_l4));
+ base_pkt = p_l2/p_l3/p_l4/('\x55'*(pyld_size))
+
+ l3_len_fix =-(len(p_l2));
+ l4_len_fix =-(len(p_l2/p_l3));
+
+
+ # vm
+ vm = STLScVmRaw( [ STLVmFlowVar(name="fv_rand", min_value=64,
+ max_value=len(base_pkt),
+ size=2, op="inc"),
+
+ STLVmTrimPktSize("fv_rand"), # change total packet size <<<
+
+ STLVmWrFlowVar(fv_name="fv_rand",
+ pkt_offset= "IP.len",
+ add_val=l3_len_fix), # fix ip len
+
+ STLVmFixIpv4(offset = "IP"), # fix checksum
+
+ STLVmWrFlowVar(fv_name="fv_rand",
+ pkt_offset= "UDP.len",
+ add_val=l4_len_fix) # fix udp len
+ ]
+ )
+
+ pkt = STLPktBuilder(pkt = base_pkt,
+ vm = vm)
+
+ return STLStream(packet = pkt,
+ mode = STLTXCont())
+
+
+ """
+
+ super(STLVmTupleGen, self).__init__()
self.name = name
assert type(name)==str, 'type of fv_name is not str'
self.ip_min = convert_val(ip_min);
@@ -672,22 +939,22 @@ class CTRexVmDescTupleGen(CTRexVmDescBase):
################################################################################################
-class CScapyTRexPktBuilder(CTrexPktBuilderInterface):
- """
- This class defines the TRex API of building a packet and Field engine using scapy package.
- Using this class the user can also define how TRex will handle the packet by specifying the Field engine setting.
- pkt could be Scapy pkt or pcap file name
- When path_relative_to_profile is a True load pcap file from a path relative to the profile
- """
+class STLPktBuilder(CTrexPktBuilderInterface):
def __init__(self, pkt = None, pkt_buffer = None, vm = None, path_relative_to_profile = False, build_raw = False, remove_fcs = True):
"""
+
+ This class defines a way to build a template packet, and Field Engine using scapy package.
+ Using this class the user can also define how TRex will handle the packet by specifying the Field engine setting.
+ pkt could be Scapy pkt or pcap file name
+ When path_relative_to_profile is a True load pcap file from a path relative to the profile
+
Instantiate a CTRexPktBuilder object
:parameters:
- pkt : Scapy or pcap file filename
- a scapy packet
+ pkt : string,
+ Scapy or pcap file filename a scapy packet
pkt_buffer : string
a packet as buffer
@@ -717,7 +984,7 @@ class CScapyTRexPktBuilder(CTrexPktBuilderInterface):
path_relative_to_profile = True)
- vm = CTRexScRaw( [ STLVmTupleGen ( ip_min="16.0.0.1", ip_max="16.0.0.2",
+ vm = STLScVmRaw( [ STLVmTupleGen ( ip_min="16.0.0.1", ip_max="16.0.0.2",
port_min=1025, port_max=65535,
name="tuple"), # define tuple gen
@@ -735,7 +1002,7 @@ class CScapyTRexPktBuilder(CTrexPktBuilderInterface):
"""
- super(CScapyTRexPktBuilder, self).__init__()
+ super(STLPktBuilder, self).__init__()
self.pkt = None # as input
self.pkt_raw = None # from raw pcap file
@@ -760,10 +1027,10 @@ class CScapyTRexPktBuilder(CTrexPktBuilderInterface):
# process VM
if vm != None:
- if not isinstance(vm, (CTRexScRaw, list)):
+ if not isinstance(vm, (STLScVmRaw, list)):
raise CTRexPacketBuildException(-14, "bad value for variable vm")
- self.add_command(vm if isinstance(vm, CTRexScRaw) else CTRexScRaw(vm))
+ self.add_command(vm if isinstance(vm, STLScVmRaw) else STLScVmRaw(vm))
# raw source build to see MAC presence/ fields offset by name in VM
if build_raw and self.pkt_raw and not self.pkt:
@@ -928,7 +1195,7 @@ class CScapyTRexPktBuilder(CTrexPktBuilderInterface):
# compile the VM
for sc in self.vm_scripts:
- if isinstance(sc, CTRexScRaw):
+ if isinstance(sc, STLScVmRaw):
self._compile_raw(sc)
def get_pkt_len (self):