summaryrefslogtreecommitdiffstats
path: root/scripts/automation/trex_control_plane/client_utils
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-02-08 06:08:14 -0500
committerimarom <imarom@cisco.com>2016-02-08 06:08:14 -0500
commit995267db77f5554d5228697b8b2a862b51859fe6 (patch)
tree1a44007a59d8cabacab0690da515a68c3c25e7ac /scripts/automation/trex_control_plane/client_utils
parent69e5a5c6b94175ece07b247af1b5ca6c0cfdf0e9 (diff)
first refactor
Diffstat (limited to 'scripts/automation/trex_control_plane/client_utils')
-rwxr-xr-xscripts/automation/trex_control_plane/client_utils/jsonrpc_client.py244
-rwxr-xr-xscripts/automation/trex_control_plane/client_utils/packet_builder.py1209
-rw-r--r--scripts/automation/trex_control_plane/client_utils/packet_builder_interface.py43
-rw-r--r--scripts/automation/trex_control_plane/client_utils/scapy_packet_builder.py748
-rw-r--r--scripts/automation/trex_control_plane/client_utils/text_tables.py4
-rwxr-xr-xscripts/automation/trex_control_plane/client_utils/yaml_utils.py1
6 files changed, 1 insertions, 2248 deletions
diff --git a/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py b/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py
deleted file mode 100755
index 9c351175..00000000
--- a/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py
+++ /dev/null
@@ -1,244 +0,0 @@
-#!/router/bin/python
-
-import external_packages
-import zmq
-import json
-import general_utils
-import re
-from time import sleep
-from collections import namedtuple
-from common.trex_types import *
-
-class bcolors:
- BLUE = '\033[94m'
- GREEN = '\033[32m'
- YELLOW = '\033[93m'
- RED = '\033[31m'
- MAGENTA = '\033[35m'
- ENDC = '\033[0m'
- BOLD = '\033[1m'
- UNDERLINE = '\033[4m'
-
-# sub class to describe a batch
-class BatchMessage(object):
- def __init__ (self, rpc_client):
- self.rpc_client = rpc_client
- self.batch_list = []
-
- def add (self, method_name, params={}):
-
- id, msg = self.rpc_client.create_jsonrpc_v2(method_name, params, encode = False)
- self.batch_list.append(msg)
-
- def invoke(self, block = False):
- if not self.rpc_client.connected:
- return RC_ERR("Not connected to server")
-
- msg = json.dumps(self.batch_list)
-
- return self.rpc_client.send_raw_msg(msg)
-
-
-# JSON RPC v2.0 client
-class JsonRpcClient(object):
-
- def __init__ (self, default_server, default_port, logger):
- self.logger = logger
- self.connected = False
-
- # default values
- self.port = default_port
- self.server = default_server
- self.id_gen = general_utils.random_id_gen()
-
-
- def get_connection_details (self):
- rc = {}
- rc['server'] = self.server
- rc['port'] = self.port
-
- return rc
-
- # pretty print for JSON
- def pretty_json (self, json_str, use_colors = True):
- pretty_str = json.dumps(json.loads(json_str), indent = 4, separators=(',', ': '), sort_keys = True)
-
- if not use_colors:
- return pretty_str
-
- try:
- # int numbers
- pretty_str = re.sub(r'([ ]*:[ ]+)(\-?[1-9][0-9]*[^.])',r'\1{0}\2{1}'.format(bcolors.BLUE, bcolors.ENDC), pretty_str)
- # float
- pretty_str = re.sub(r'([ ]*:[ ]+)(\-?[1-9][0-9]*\.[0-9]+)',r'\1{0}\2{1}'.format(bcolors.MAGENTA, bcolors.ENDC), pretty_str)
- # strings
-
- pretty_str = re.sub(r'([ ]*:[ ]+)("[^"]*")',r'\1{0}\2{1}'.format(bcolors.RED, bcolors.ENDC), pretty_str)
- pretty_str = re.sub(r"('[^']*')", r'{0}\1{1}'.format(bcolors.MAGENTA, bcolors.RED), pretty_str)
- except :
- pass
-
- return pretty_str
-
- def verbose_msg (self, msg):
- self.logger.log("\n\n[verbose] " + msg, level = self.logger.VERBOSE_HIGH)
-
-
- # batch messages
- def create_batch (self):
- return BatchMessage(self)
-
- def create_jsonrpc_v2 (self, method_name, params = {}, encode = True):
- msg = {}
- msg["jsonrpc"] = "2.0"
- msg["method"] = method_name
-
- msg["params"] = params
-
- msg["id"] = self.id_gen.next()
-
- if encode:
- return id, json.dumps(msg)
- else:
- return id, msg
-
-
- def invoke_rpc_method (self, method_name, params = {}):
- if not self.connected:
- return RC_ERR("Not connected to server")
-
- id, msg = self.create_jsonrpc_v2(method_name, params)
-
- return self.send_raw_msg(msg)
-
-
- # low level send of string message
- def send_raw_msg (self, msg):
-
- self.verbose_msg("Sending Request To Server:\n\n" + self.pretty_json(msg) + "\n")
-
- tries = 0
- while True:
- try:
- self.socket.send(msg)
- break
- except zmq.Again:
- tries += 1
- if tries > 5:
- self.disconnect()
- return RC_ERR("*** [RPC] - Failed to send message to server")
-
-
- tries = 0
- while True:
- try:
- response = self.socket.recv()
- break
- except zmq.Again:
- tries += 1
- if tries > 5:
- self.disconnect()
- return RC_ERR("*** [RPC] - Failed to get server response at {0}".format(self.transport))
-
-
- self.verbose_msg("Server Response:\n\n" + self.pretty_json(response) + "\n")
-
- # decode
-
- # batch ?
- response_json = json.loads(response)
-
- if isinstance(response_json, list):
- rc_batch = RC()
-
- for single_response in response_json:
- rc = self.process_single_response(single_response)
- rc_batch.add(rc)
-
- return rc_batch
-
- else:
- return self.process_single_response(response_json)
-
-
- def process_single_response (self, response_json):
-
- if (response_json.get("jsonrpc") != "2.0"):
- return RC_ERR("Malformed Response ({0})".format(str(response_json)))
-
- # error reported by server
- if ("error" in response_json):
- if "specific_err" in response_json["error"]:
- return RC_ERR(response_json["error"]["specific_err"])
- else:
- return RC_ERR(response_json["error"]["message"])
-
-
- # if no error there should be a result
- if ("result" not in response_json):
- return RC_ERR("Malformed Response ({0})".format(str(response_json)))
-
- return RC_OK(response_json["result"])
-
-
-
- def disconnect (self):
- if self.connected:
- self.socket.close(linger = 0)
- self.context.destroy(linger = 0)
- self.connected = False
- return RC_OK()
- else:
- return RC_ERR("Not connected to server")
-
-
- def connect(self, server = None, port = None):
- if self.connected:
- self.disconnect()
-
- self.context = zmq.Context()
-
- self.server = (server if server else self.server)
- self.port = (port if port else self.port)
-
- # Socket to talk to server
- self.transport = "tcp://{0}:{1}".format(self.server, self.port)
-
- self.socket = self.context.socket(zmq.REQ)
- try:
- self.socket.connect(self.transport)
- except zmq.error.ZMQError as e:
- return RC_ERR("ZMQ Error: Bad server or port name: " + str(e))
-
- self.socket.setsockopt(zmq.SNDTIMEO, 1000)
- self.socket.setsockopt(zmq.RCVTIMEO, 1000)
-
- self.connected = True
-
- rc = self.invoke_rpc_method('ping')
- if not rc:
- self.connected = False
- return rc
-
- return RC_OK()
-
-
- def reconnect(self):
- # connect using current values
- return self.connect()
-
- if not self.connected:
- return RC_ERR("Not connected to server")
-
- # reconnect
- return self.connect(self.server, self.port)
-
-
- def is_connected(self):
- return self.connected
-
- def __del__(self):
- self.logger.log("Shutting down RPC client\n")
- if hasattr(self, "context"):
- self.context.destroy(linger=0)
-
diff --git a/scripts/automation/trex_control_plane/client_utils/packet_builder.py b/scripts/automation/trex_control_plane/client_utils/packet_builder.py
deleted file mode 100755
index f9031436..00000000
--- a/scripts/automation/trex_control_plane/client_utils/packet_builder.py
+++ /dev/null
@@ -1,1209 +0,0 @@
-#!/router/bin/python
-
-import external_packages
-import dpkt
-import socket
-import binascii
-import copy
-import random
-import string
-import struct
-import re
-import itertools
-from abc import ABCMeta, abstractmethod
-from collections import namedtuple
-import base64
-
-from packet_builder_interface import CTrexPktBuilderInterface
-
-class CTRexPktBuilder(CTrexPktBuilderInterface):
- """
- This class defines the TRex API of building a packet using dpkt package.
- Using this class the user can also define how TRex will handle the packet by specifying the VM setting.
- """
- def __init__(self, max_pkt_size=dpkt.ethernet.ETH_LEN_MAX):
- """
- Instantiate a CTRexPktBuilder object
-
- :parameters:
- None
-
- """
- super(CTRexPktBuilder, self).__init__()
- self._packet = None
- self._pkt_by_hdr = {}
- self._pkt_top_layer = None
- self._max_pkt_size = max_pkt_size
- self.vm = CTRexPktBuilder.CTRexVM()
- self.metadata = ""
-
- def clone (self):
- return copy.deepcopy(self)
-
- def add_pkt_layer(self, layer_name, pkt_layer):
- """
- This method adds additional header to the already existing packet
-
- :parameters:
- layer_name: str
- a string representing the name of the layer.
- Example: "l2", "l4_tcp", etc.
-
- pkt_layer : dpkt.Packet obj
- a dpkt object, generally from higher layer, that will be added on top of existing layer.
-
- :raises:
- + :exc:`ValueError`, in case the desired layer_name already exists.
-
- """
- assert isinstance(pkt_layer, dpkt.Packet)
- if layer_name in self._pkt_by_hdr:
- raise ValueError("Given layer name '{0}' already exists.".format(layer_name))
- else:
- dup_pkt = copy.copy(pkt_layer) # using copy of layer to avoid cyclic packets that may lead to infinite loop
- if not self._pkt_top_layer: # this is the first header added
- self._packet = dup_pkt
- else:
- self._pkt_top_layer.data = dup_pkt
- self._pkt_top_layer = dup_pkt
- self._pkt_by_hdr[layer_name] = dup_pkt
- return
-
- def set_ip_layer_addr(self, layer_name, attr, ip_addr, ip_type="ipv4"):
- """
- This method sets the IP address fields of an IP header (source or destination, for both IPv4 and IPv6)
- using a human readable addressing representation.
-
- :parameters:
- layer_name: str
- a string representing the name of the layer.
- Example: "l3_ip", etc.
-
- attr: str
- a string representation of the sub-field to be set:
-
- + "src" for source
- + "dst" for destination
-
- ip_addr: str
- a string representation of the IP address to be set.
- Example: "10.0.0.1" for IPv4, or "5001::DB8:1:3333:1:1" for IPv6
-
- ip_type : str
- a string representation of the IP version to be set:
-
- + "ipv4" for IPv4
- + "ipv6" for IPv6
-
- Default: **ipv4**
-
- :raises:
- + :exc:`ValueError`, in case the desired layer_name is not an IP layer
- + :exc:`KeyError`, in case the desired layer_name does not exists.
-
- """
- try:
- layer = self._pkt_by_hdr[layer_name.lower()]
- if not (isinstance(layer, dpkt.ip.IP) or isinstance(layer, dpkt.ip6.IP6)):
- raise ValueError("The specified layer '{0}' is not of IPv4/IPv6 type.".format(layer_name))
- else:
- decoded_ip = CTRexPktBuilder._decode_ip_addr(ip_addr, ip_type)
- setattr(layer, attr, decoded_ip)
- except KeyError:
- raise KeyError("Specified layer '{0}' doesn't exist on packet.".format(layer_name))
-
- def set_ipv6_layer_addr(self, layer_name, attr, ip_addr):
- """
- This method sets the IPv6 address fields of an IP header (source or destination)
-
- :parameters:
- layer_name: str
- a string representing the name of the layer.
- Example: "l3_ip", etc.
-
- attr: str
- a string representation of the sub-field to be set:
-
- + "src" for source
- + "dst" for destination
-
- ip_addr: str
- a string representation of the IP address to be set.
- Example: "5001::DB8:1:3333:1:1"
-
- :raises:
- + :exc:`ValueError`, in case the desired layer_name is not an IPv6 layer
- + :exc:`KeyError`, in case the desired layer_name does not exists.
-
- """
- self.set_ip_layer_addr(layer_name, attr, ip_addr, ip_type="ipv6")
-
- def set_eth_layer_addr(self, layer_name, attr, mac_addr):
- """
- This method sets the ethernet address fields of an Ethernet header (source or destination)
- using a human readable addressing representation.
-
- :parameters:
- layer_name: str
- a string representing the name of the layer.
- Example: "l2", etc.
-
- attr: str
- a string representation of the sub-field to be set:
- + "src" for source
- + "dst" for destination
-
- mac_addr: str
- a string representation of the MAC address to be set.
- Example: "00:de:34:ef:2e:f4".
-
- :raises:
- + :exc:`ValueError`, in case the desired layer_name is not an Ethernet layer
- + :exc:`KeyError`, in case the desired layer_name does not exists.
-
- """
- try:
- layer = self._pkt_by_hdr[layer_name.lower()]
- if not isinstance(layer, dpkt.ethernet.Ethernet):
- raise ValueError("The specified layer '{0}' is not of Ethernet type.".format(layer_name))
- else:
- decoded_mac = CTRexPktBuilder._decode_mac_addr(mac_addr)
- setattr(layer, attr, decoded_mac)
- except KeyError:
- raise KeyError("Specified layer '{0}' doesn't exist on packet.".format(layer_name))
-
- def set_layer_attr(self, layer_name, attr, val, toggle_bit=False):
- """
- This method enables the user to change a value of a previously defined packet layer.
- This method isn't to be used to set the data attribute of a packet with payload.
- Use :func:`packet_builder.CTRexPktBuilder.set_payload` instead.
-
- :parameters:
- layer_name: str
- a string representing the name of the layer.
- Example: "l2", "l4_tcp", etc.
-
- attr : str
- a string representing the attribute to be changed on desired layer
-
- val :
- value of attribute.
-
- toggle_bit : bool
- Indicating if trying to set a specific bit of a field, such as "do not fragment" bit of IP layer.
-
- Default: **False**
-
- :raises:
- + :exc:`KeyError`, in case of missing layer (the desired layer isn't part of packet)
- + :exc:`ValueError`, in case invalid attribute to the specified layer.
-
- """
- try:
- layer = self._pkt_by_hdr[layer_name.lower()]
- if attr == 'data' and not isinstance(val, dpkt.Packet):
- # Don't allow setting 'data' attribute
- raise ValueError("Set a data attribute with object that is not dpkt.Packet is not allowed using "
- "set_layer_attr method.\nUse set_payload method instead.")
- if hasattr(layer, attr):
- if toggle_bit:
- setattr(layer, attr, val | getattr(layer, attr, 0))
- else:
- setattr(layer, attr, val)
- if attr == 'data':
- # re-evaluate packet from the start, possible broken link between layers
- self._reevaluate_packet(layer_name.lower())
- else:
- raise ValueError("Given attr name '{0}' doesn't exists on specified layer ({1}).".format(layer_name,
- attr))
- except KeyError:
- raise KeyError("Specified layer '{0}' doesn't exist on packet.".format(layer_name))
-
- def set_layer_bit_attr(self, layer_name, attr, val):
- """
- This method enables the user to set the value of a field smaller that 1 Byte in size.
- This method isn't used to set full-sized fields value (>= 1 byte).
- Use :func:`packet_builder.CTRexPktBuilder.set_layer_attr` instead.
-
- :parameters:
- layer_name: str
- a string representing the name of the layer.
- Example: "l2", "l4_tcp", etc.
-
- attr : str
- a string representing the attribute to be set on desired layer
-
- val : int
- value of attribute.
- This value will be set "ontop" of the existing value using bitwise "OR" operation.
-
- .. tip:: It is very useful to use dpkt constants to define the values of these fields.
-
- :raises:
- + :exc:`KeyError`, in case of missing layer (the desired layer isn't part of packet)
- + :exc:`ValueError`, in case invalid attribute to the specified layer.
-
- """
- return self.set_layer_attr(layer_name, attr, val, True)
-
- def set_pkt_payload(self, payload):
- """
- This method sets a payload to the topmost layer of the generated packet.
- This method isn't to be used to set another networking layer to the packet.
- Use :func:`packet_builder.CTRexPktBuilder.set_layer_attr` instead.
-
-
- :parameters:
- payload:
- a payload to be added to the packet at the topmost layer.
- this object cannot be of type dpkt.Packet.
-
- :raises:
- + :exc:`AttributeError`, in case no underlying header to host the payload.
-
- """
- assert isinstance(payload, str)
- try:
- self._pkt_top_layer.data = payload
- except AttributeError:
- raise AttributeError("The so far built packet doesn't contain an option for payload attachment.\n"
- "Make sure to set appropriate underlying header before adding payload")
-
- def load_packet(self, packet):
- """
- This method enables the user to change a value of a previously defined packet layer.
-
- :parameters:
- packet: dpkt.Packet obj
- a dpkt object that represents a packet.
-
-
- :raises:
- + :exc:`CTRexPktBuilder.IPAddressError`, in case invalid ip type option specified.
-
- """
- assert isinstance(packet, dpkt.Packet)
- self._packet = copy.copy(packet)
-
- self._pkt_by_hdr.clear()
- self._pkt_top_layer = self._packet
- # analyze packet to layers
- tmp_layer = self._packet
- while True:
- if isinstance(tmp_layer, dpkt.Packet):
- layer_name = self._gen_layer_name(type(tmp_layer).__name__)
- self._pkt_by_hdr[layer_name] = tmp_layer
- self._pkt_top_layer = tmp_layer
- try:
- # check existence of upper layer
- tmp_layer = tmp_layer.data
- except AttributeError:
- # this is the most upper header
- self._pkt_by_hdr['pkt_final_payload'] = tmp_layer.data
- break
- else:
- self._pkt_by_hdr['pkt_final_payload'] = tmp_layer
- break
- return
-
- def load_packet_from_pcap(self, pcap_path):
- """
- This method loads a pcap file into a parsed packet builder object.
-
- :parameters:
- pcap_path: str
- a path to a pcap file, containing a SINGLE packet.
-
- :raises:
- + :exc:`IOError`, in case provided path doesn't exists.
-
- """
- with open(pcap_path, 'r') as f:
- pcap = dpkt.pcap.Reader(f)
- first_packet = True
- for _, buf in pcap:
- # this is an iterator, can't evaluate the number of files in advance
- if first_packet:
- self.load_packet(dpkt.ethernet.Ethernet(buf))
- else:
- raise ValueError("Provided pcap file contains more than single packet.")
- # arrive here ONLY if pcap contained SINGLE packet
- return
-
- def load_from_stream_obj(self, stream_obj):
- self.load_packet_from_byte_list(stream_obj['packet']['binary'])
-
-
- def load_packet_from_byte_list(self, byte_list):
-
- buf = base64.b64decode(byte_list)
- # thn, load it based on dpkt parsing
- self.load_packet(dpkt.ethernet.Ethernet(buf))
-
- def get_packet(self, get_ptr=False):
- """
- This method provides access to the built packet, as an instance or as a pointer to packet itself.
-
- :parameters:
- get_ptr : bool
- indicate whether to get a reference to packet or a copy.
- Use only in advanced modes
- if set to true, metadata for packet is cleared, and any further modification is not guaranteed.
-
- default value : False
-
- :return:
- + the current packet built by CTRexPktBuilder object.
- + None if packet is empty
-
- """
- if get_ptr:
- self._pkt_by_hdr = {}
- self._pkt_top_layer = None
- return self._packet
- else:
- return copy.copy(self._packet)
-
- def get_packet_length(self):
- return len(self._packet)
-
- def get_layer(self, layer_name):
- """
- This method provides access to a specific layer of the packet, as a **copy of the layer instance**.
-
- :parameters:
- layer_name : str
- the name given to desired layer
-
- :return:
- + a copy of the desired layer of the current packet if exists.
- + None if no such layer
-
- """
- layer = self._pkt_by_hdr.get(layer_name)
- return copy.copy(layer) if layer else None
-
-
- # VM access methods
- def set_vm_ip_range(self, ip_layer_name, ip_field,
- ip_start, ip_end, operation,
- ip_init = None, add_value = 0,
- is_big_endian=True, val_size=4,
- ip_type="ipv4", add_checksum_inst=True,
- split = False):
-
- if ip_field not in ["src", "dst"]:
- raise ValueError("set_vm_ip_range only available for source ('src') or destination ('dst') ip addresses")
- # set differences between IPv4 and IPv6
- if ip_type == "ipv4":
- ip_class = dpkt.ip.IP
- ip_addr_size = val_size if val_size <= 4 else 4
- elif ip_type == "ipv6":
- ip_class = dpkt.ip6.IP6
- ip_addr_size = val_size if val_size <= 8 else 4
- else:
- raise CTRexPktBuilder.IPAddressError()
-
- self._verify_layer_prop(ip_layer_name, ip_class)
- trim_size = ip_addr_size*2
- start_val = int(binascii.hexlify(CTRexPktBuilder._decode_ip_addr(ip_start, ip_type))[-trim_size:], 16)
- end_val = int(binascii.hexlify(CTRexPktBuilder._decode_ip_addr(ip_end, ip_type))[-trim_size:], 16)
-
- if ip_init == None:
- init_val = start_val
- else:
- init_val = int(binascii.hexlify(CTRexPktBuilder._decode_ip_addr(ip_init, ip_type))[-trim_size:], 16)
-
-
- # All validations are done, start adding VM instructions
- flow_var_name = "{layer}__{field}".format(layer=ip_layer_name, field=ip_field)
-
- hdr_offset, field_abs_offset = self._calc_offset(ip_layer_name, ip_field, ip_addr_size)
- self.vm.add_flow_man_inst(flow_var_name, size=ip_addr_size, operation=operation,
- init_value=init_val,
- min_value=start_val,
- max_value=end_val)
- self.vm.add_write_flow_inst(flow_var_name, field_abs_offset)
- self.vm.set_vm_off_inst_field(flow_var_name, "add_value", add_value)
- self.vm.set_vm_off_inst_field(flow_var_name, "is_big_endian", is_big_endian)
- if ip_type == "ipv4" and add_checksum_inst:
- self.vm.add_fix_checksum_inst(self._pkt_by_hdr.get(ip_layer_name), hdr_offset)
-
- if split:
- self.vm.set_split_by_var(flow_var_name)
-
-
- def set_vm_eth_range(self, eth_layer_name, eth_field,
- mac_init, mac_start, mac_end, add_value,
- operation, val_size=4, is_big_endian=False):
- if eth_field not in ["src", "dst"]:
- raise ValueError("set_vm_eth_range only available for source ('src') or destination ('dst') eth addresses")
- self._verify_layer_prop(eth_layer_name, dpkt.ethernet.Ethernet)
- eth_addr_size = val_size if val_size <= 4 else 4
- trim_size = eth_addr_size*2
- init_val = int(binascii.hexlify(CTRexPktBuilder._decode_mac_addr(mac_init))[-trim_size:], 16)
- start_val = int(binascii.hexlify(CTRexPktBuilder._decode_mac_addr(mac_start))[-trim_size:], 16)
- end_val = int(binascii.hexlify(CTRexPktBuilder._decode_mac_addr(mac_end))[-trim_size:], 16)
- # All validations are done, start adding VM instructions
- flow_var_name = "{layer}__{field}".format(layer=eth_layer_name, field=eth_field)
- hdr_offset, field_abs_offset = self._calc_offset(eth_layer_name, eth_field, eth_addr_size)
- self.vm.add_flow_man_inst(flow_var_name, size=8, operation=operation,
- init_value=init_val,
- min_value=start_val,
- max_value=end_val)
- self.vm.add_write_flow_inst(flow_var_name, field_abs_offset)
- self.vm.set_vm_off_inst_field(flow_var_name, "add_value", add_value)
- self.vm.set_vm_off_inst_field(flow_var_name, "is_big_endian", is_big_endian)
-
- def set_vm_custom_range(self, layer_name, hdr_field,
- init_val, start_val, end_val, add_val, val_size,
- operation, is_big_endian=True, range_name="",
- add_checksum_inst=True):
- # verify input validity for init/start/end values
- for val in [init_val, start_val, end_val]:
- if not isinstance(val, int):
- raise ValueError("init/start/end values are expected integers, but received type '{0}'".
- format(type(val)))
- self._verify_layer_prop(layer_name=layer_name, field_name=hdr_field)
- if not range_name:
- range_name = "{layer}__{field}".format(layer=layer_name, field=hdr_field)
- trim_size = val_size*2
- hdr_offset, field_abs_offset = self._calc_offset(layer_name, hdr_field, val_size)
- self.vm.add_flow_man_inst(range_name, size=val_size, operation=operation,
- init_value=init_val,
- min_value=start_val,
- max_value=end_val)
- self.vm.add_write_flow_inst(range_name, field_abs_offset)
- self.vm.set_vm_off_inst_field(range_name, "add_value", add_val)
- self.vm.set_vm_off_inst_field(range_name, "is_big_endian", is_big_endian)
- if isinstance(self._pkt_by_hdr.get(layer_name), dpkt.ip.IP) and add_checksum_inst:
- self.vm.add_fix_checksum_inst(self._pkt_by_hdr.get(layer_name), hdr_offset)
-
- def get_vm_data(self):
- return self.vm.dump()
-
- def compile (self):
- pass
-
- def dump_pkt(self, encode = True):
- """
- Dumps the packet as a decimal array of bytes (each item x gets value between 0-255)
-
- :parameters:
- encode : bool
- Encode using base64. (disable for debug)
-
- Default: **True**
-
- :return:
- + packet representation as array of bytes
-
- :raises:
- + :exc:`CTRexPktBuilder.EmptyPacketError`, in case packet is empty.
-
- """
- if self._packet is None:
- raise CTRexPktBuilder.EmptyPacketError()
-
- if encode:
- return {"binary": base64.b64encode(str(self._packet)),
- "meta": self.metadata}
- return {"binary": str(self._packet),
- "meta": self.metadata}
-
-
- def dump_pkt_to_pcap(self, file_path, ts=None):
- """
- Dumps the packet as a decimal array of bytes (each item x gets value between 0-255)
-
- :parameters:
- file_path : str
- a path (including filename) to which to write to pcap file to.
-
- ts : int
- a timestamp to attach to the packet when dumped to pcap file.
- if ts in None, then time.time() is used to set the timestamp.
-
- Default: **None**
-
- :return:
- None
-
- :raises:
- + :exc:`CTRexPktBuilder.EmptyPacketError`, in case packet is empty.
-
- """
- if self._packet is None:
- raise CTRexPktBuilder.EmptyPacketError()
- try:
- with open(file_path, 'wb') as f:
- pcap_wr = dpkt.pcap.Writer(f)
- pcap_wr.writepkt(self._packet, ts)
- return
- except IOError:
- raise IOError(2, "The provided path could not be accessed")
-
- def get_packet_layers(self, depth_limit=Ellipsis):
- if self._packet is None:
- raise CTRexPktBuilder.EmptyPacketError()
- cur_layer = self._packet
- layer_types = []
- if depth_limit == Ellipsis:
- iterator = itertools.count(1)
- else:
- iterator = xrange(depth_limit)
- for _ in iterator:
- # append current layer type
- if isinstance(cur_layer, dpkt.Packet):
- layer_types.append(type(cur_layer).__name__)
- else:
- # if not dpkt layer, refer as payload
- layer_types.append("PLD")
- # advance to next layer
- if not hasattr(cur_layer, "data"):
- break
- else:
- cur_layer = cur_layer.data
- return layer_types
-
- def export_pkt(self, file_path, link_pcap=False, pcap_name=None, pcap_ts=None):
- pass
-
- # ----- internal methods ----- #
- def _reevaluate_packet(self, layer_name):
- cur_layer = self._packet
- known_layers = set(self._pkt_by_hdr.keys())
- found_layers = set()
- while True:
- pointing_layer_name = self._find_pointing_layer(known_layers, cur_layer)
- found_layers.add(pointing_layer_name)
- if self._pkt_by_hdr[layer_name] is cur_layer:
- self._pkt_top_layer = cur_layer
- disconnected_layers = known_layers.difference(found_layers)
- # remove disconnected layers
- for layer in disconnected_layers:
- self._pkt_by_hdr.pop(layer)
- break
- else:
- cur_layer = cur_layer.data
-
- def _gen_layer_name(self, layer_class_name):
- assert isinstance(layer_class_name, str)
- layer_name = layer_class_name.lower()
- idx = 1
- while True:
- tmp_name = "{name}_{id}".format(name=layer_name, id=idx)
- if tmp_name not in self._pkt_by_hdr:
- return tmp_name
- else:
- idx += 1
-
- def _find_pointing_layer(self, known_layers, layer_obj):
- assert isinstance(known_layers, set)
- for layer in known_layers:
- if self._pkt_by_hdr[layer] is layer_obj:
- return layer
-
- def _calc_offset(self, layer_name, hdr_field, hdr_field_size):
- pkt_header = self._pkt_by_hdr.get(layer_name)
- hdr_offset = len(self._packet) - len(pkt_header)
- inner_hdr_offsets = []
- for field in pkt_header.__hdr__:
- if field[0] == hdr_field:
- field_size = struct.calcsize(field[1])
- if field_size == hdr_field_size:
- break
- elif field_size < hdr_field_size:
- raise CTRexPktBuilder.PacketLayerError(layer_name,
- "The specified field '{0}' size is smaller than given range"
- " size ('{1}')".format(hdr_field, hdr_field_size))
- else:
- inner_hdr_offsets.append(field_size - hdr_field_size)
- break
- else:
- inner_hdr_offsets.append(struct.calcsize(field[1]))
- return hdr_offset, hdr_offset + sum(inner_hdr_offsets)
-
- def _verify_layer_prop(self, layer_name, layer_type=None, field_name=None):
- if layer_name not in self._pkt_by_hdr:
- raise CTRexPktBuilder.PacketLayerError(layer_name)
- pkt_layer = self._pkt_by_hdr.get(layer_name)
- if layer_type:
- # check for layer type
- if not isinstance(pkt_layer, layer_type):
- raise CTRexPktBuilder.PacketLayerTypeError(layer_name, type(pkt_layer), layer_type)
- if field_name and not hasattr(pkt_layer, field_name):
- # check if field exists on certain header
- raise CTRexPktBuilder.PacketLayerError(layer_name, "The specified field '{0}' does not exists on "
- "given packet layer ('{1}')".format(field_name,
- layer_name))
- return
-
- @property
- def payload_gen(self):
- return CTRexPktBuilder.CTRexPayloadGen(self._packet, self._max_pkt_size)
-
- @staticmethod
- def _decode_mac_addr(mac_addr):
- """
- Static method to test for MAC address validity.
-
- :parameters:
- mac_addr : str
- a string representing an MAC address, separated by ':' or '-'.
-
- examples: '00:de:34:ef:2e:f4', '00-de-34-ef-2e-f4
-
- :return:
- + an hex-string representation of the MAC address.
- for example, ip 00:de:34:ef:2e:f4 will return '\x00\xdeU\xef.\xf4'
-
- :raises:
- + :exc:`CTRexPktBuilder.MACAddressError`, in case invalid ip type option specified.
-
- """
- tmp_mac = mac_addr.lower().replace('-', ':')
- if re.match("[0-9a-f]{2}([-:])[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$", tmp_mac):
- return binascii.unhexlify(tmp_mac.replace(':', ''))
- # another option for both Python 2 and 3:
- # codecs.decode(tmp_mac.replace(':', ''), 'hex')
- else:
- raise CTRexPktBuilder.MACAddressError()
-
- @staticmethod
- def _decode_ip_addr(ip_addr, ip_type):
- """
- Static method to test for IPv4/IPv6 address validity.
-
- :parameters:
- ip_addr : str
- a string representing an IP address (IPv4/IPv6)
-
- ip_type : str
- The type of IP to be checked.
- Valid types: "ipv4", "ipv6".
-
- :return:
- + an hex-string representation of the ip address.
- for example, ip 1.2.3.4 will return '\x01\x02\x03\x04'
-
- :raises:
- + :exc:`CTRexPktBuilder.IPAddressError`, in case invalid ip type option specified.
-
- """
- if ip_type == "ipv4":
- try:
- return socket.inet_pton(socket.AF_INET, ip_addr)
- except AttributeError: # no inet_pton here, sorry
- # try:
- return socket.inet_aton(ip_addr)
- # except socket.error:
- # return False
- # return ip_addr.count('.') == 3
- except socket.error: # not a valid address
- raise CTRexPktBuilder.IPAddressError()
- elif ip_type == "ipv6":
- try:
- return socket.inet_pton(socket.AF_INET6, ip_addr)
- except socket.error: # not a valid address
- raise CTRexPktBuilder.IPAddressError()
- else:
- raise CTRexPktBuilder.IPAddressError()
-
- # ------ private classes ------ #
- class CTRexPayloadGen(object):
-
- def __init__(self, packet_ref, max_pkt_size):
- self._pkt_ref = packet_ref
- self._max_pkt_size = max_pkt_size
-
- def gen_random_str(self):
- gen_length = self._calc_gen_length()
- # return a string of size gen_length bytes, to pad the packet to its max_size
- return ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits)
- for _ in range(gen_length))
-
- def gen_repeat_ptrn(self, ptrn_to_repeat):
- gen_length = self._calc_gen_length()
- if isinstance(ptrn_to_repeat, str):
- # generate repeated string
- return (ptrn_to_repeat * (gen_length/len(ptrn_to_repeat) + 1))[:gen_length]
- elif isinstance(ptrn_to_repeat, int):
- ptrn = binascii.unhexlify(hex(ptrn_to_repeat)[2:])
- return (ptrn * (gen_length/len(ptrn) + 1))[:gen_length]
- elif isinstance(ptrn_to_repeat, tuple):
- if not all((isinstance(x, int) and (x < 255) and (x >= 0))
- for x in ptrn_to_repeat):
- raise ValueError("All numbers in tuple must be in range 0 <= number <= 255 ")
- # generate repeated sequence
- to_pack = (ptrn_to_repeat * (gen_length/len(ptrn_to_repeat) + 1))[:gen_length]
- return struct.pack('B'*gen_length, *to_pack)
- else:
- raise ValueError("Given ptrn_to_repeat argument type ({0}) is illegal.".
- format(type(ptrn_to_repeat)))
-
- def _calc_gen_length(self):
- return self._max_pkt_size - len(self._pkt_ref)
-
- class CTRexVM(object):
- """
- This class defines the TRex VM which represents how TRex will regenerate packets.
- The packets will be regenerated based on the built packet containing this class.
- """
- InstStore = namedtuple('InstStore', ['type', 'inst'])
-
- def __init__(self):
- """
- Instantiate a CTRexVM object
-
- :parameters:
- None
- """
- super(CTRexPktBuilder.CTRexVM, self).__init__()
- self.vm_variables = {}
- self._inst_by_offset = {} # this data structure holds only offset-related instructions, ordered in tuples
- self._off_inst_by_name = {}
- self.split_by_var = ''
-
- def set_vm_var_field(self, var_name, field_name, val, offset_inst=False):
- """
- Set VM variable field. Only existing variables are allowed to be changed.
-
- :parameters:
- var_name : str
- a string representing the name of the VM variable to be changed.
- field_name : str
- a string representing the field name of the VM variable to be changed.
- val :
- a value to be applied to field_name field of the var_name VM variable.
-
- :raises:
- + :exc:`KeyError`, in case invalid var_name has been specified.
- + :exc:`CTRexPktBuilder.VMVarFieldTypeError`, in case mismatch between `val` and allowed type.
- + :exc:`CTRexPktBuilder.VMVarValueError`, in case val isn't one of allowed options of field_name.
-
- """
- if offset_inst:
- return self._off_inst_by_name[var_name].inst.set_field(field_name, val)
- else:
- return self.vm_variables[var_name].set_field(field_name, val)
-
- def set_vm_off_inst_field(self, var_name, field_name, val):
- return self.set_vm_var_field(var_name, field_name, val, True)
-
- def add_flow_man_inst(self, name, **kwargs):
- """
- Adds a new flow manipulation object to the VM instance.
-
- :parameters:
- name : str
- name of the manipulation, must be distinct.
- Example: 'source_ip_change'
-
- **kwargs** : dict
- optional, set flow_man fields on initialization (key = field_name, val = field_val).
- Must be used with legit fields, see :func:`CTRexPktBuilder.CTRexVM.CTRexVMVariable.set_field`.
-
- :return:
- None
-
- :raises:
- + :exc:`CTRexPktBuilder.VMVarNameExistsError`, in case of desired flow_man name already taken.
- + Exceptions from :func:`CTRexPktBuilder.CTRexVM.CTRexVMVariable.set_field` method.
- Will rise when VM variables were misconfiguration.
- """
- if name not in self.vm_variables:
- self.vm_variables[name] = self.CTRexVMFlowVariable(name)
- # try configuring VM instruction attributes
- for (field, value) in kwargs.items():
- self.vm_variables[name].set_field(field, value)
- else:
- raise CTRexPktBuilder.VMVarNameExistsError(name)
-
- def add_fix_checksum_inst(self, linked_ipv4_obj, offset_to_obj=14, name=None):
- # check if specified linked_ipv4_obj is indeed an ipv4 object
- if not (isinstance(linked_ipv4_obj, dpkt.ip.IP)):
- raise ValueError("The provided layer object is not of IPv4.")
- if not name:
- name = "checksum_{off}".format(off=offset_to_obj) # name will override previous checksum inst, OK
- new_checksum_inst = self.CTRexVMChecksumInst(name, offset_to_obj)
- # store the checksum inst in the end of the IP header (20 Bytes long)
- inst = self.InstStore('checksum', new_checksum_inst)
- self._inst_by_offset[offset_to_obj + 20] = inst
- self._off_inst_by_name[name] = inst
-
- def add_write_flow_inst(self, name, pkt_offset, **kwargs):
- if name not in self.vm_variables:
- raise KeyError("Trying to add write_flow_var instruction to a not-exists VM flow variable ('{0}')".
- format(name))
- else:
- new_write_inst = self.CTRexVMWrtFlowVarInst(name, pkt_offset)
- # try configuring VM instruction attributes
- for (field, value) in kwargs.items():
- new_write_inst.set_field(field, value)
- # add the instruction to the date-structure
- inst = self.InstStore('write', new_write_inst)
- self._inst_by_offset[pkt_offset] = inst
- self._off_inst_by_name[name] = inst
-
- def load_flow_man(self, flow_obj):
- """
- Loads an outer VM variable (instruction) into current VM.
- The outer VM variable must contain different name than existing VM variables currently registered on VM.
-
- :parameters:
- flow_obj : CTRexVMVariable
- a CTRexVMVariable to be loaded into VM variable sets.
-
- :return:
- list holds variables data of VM
-
- """
- assert isinstance(flow_obj, CTRexPktBuilder.CTRexVM.CTRexVMFlowVariable)
- if flow_obj.name not in self.vm_variables.keys():
- self.vm_variables[flow_obj.name] = flow_obj
- else:
- raise CTRexPktBuilder.VMVarNameExistsError(flow_obj.name)
-
- def set_split_by_var (self, var_name):
- if var_name not in self.vm_variables:
- raise KeyError("cannot set split by var to an unknown VM var ('{0}')".
- format(var_name))
-
- self.split_by_var = var_name
-
- def dump(self):
- """
- dumps a VM variables (instructions) and split_by_var into a dict data structure.
-
- :parameters:
- None
-
- :return:
- dict with VM instructions as list and split_by_var as str
-
- """
-
- # at first, dump all CTRexVMFlowVariable instructions
- inst_array = [var.dump() if hasattr(var, 'dump') else var
- for key, var in self.vm_variables.items()]
- # then, dump all the CTRexVMWrtFlowVarInst and CTRexVMChecksumInst instructions
- inst_array += [self._inst_by_offset.get(key).inst.dump()
- for key in sorted(self._inst_by_offset)]
- return {'instructions': inst_array, 'split_by_var': self.split_by_var}
-
- class CVMAbstractInstruction(object):
- __metaclass__ = ABCMeta
-
- def __init__(self, name):
- """
- Instantiate a CTRexVMVariable object
-
- :parameters:
- name : str
- a string representing the name of the VM variable.
- """
- super(CTRexPktBuilder.CTRexVM.CVMAbstractInstruction, self).__init__()
- self.name = name
-
- def set_field(self, field_name, val):
- if not hasattr(self, field_name):
- raise CTRexPktBuilder.VMFieldNameError(field_name)
- setattr(self, field_name, val)
-
- @abstractmethod
- def dump(self):
- pass
-
- class CTRexVMFlowVariable(CVMAbstractInstruction):
- """
- This class defines a single VM variable to be used as part of CTRexVar object.
- """
- VALID_SIZE = [1, 2, 4, 8] # size in Bytes
- VALID_OPERATION = ["inc", "dec", "random"]
-
- def __init__(self, name):
- """
- Instantiate a CTRexVMVariable object
-
- :parameters:
- name : str
- a string representing the name of the VM variable.
- """
- super(CTRexPktBuilder.CTRexVM.CTRexVMFlowVariable, self).__init__(name)
- # self.name = name
- self.size = 4
- self.big_endian = True
- self.operation = "inc"
- # self.split_by_core = False
- self.init_value = 1
- self.min_value = self.init_value
- self.max_value = self.init_value
-
- def set_field(self, field_name, val):
- """
- Set VM variable field. Only existing variables are allowed to be changed.
-
- :parameters:
- field_name : str
- a string representing the field name of the VM variable to be changed.
- val :
- a value to be applied to field_name field of the var_name VM variable.
-
- :return:
- None
-
- :raises:
- + :exc:`CTRexPktBuilder.VMVarNameError`, in case of illegal field name.
- + :exc:`CTRexPktBuilder.VMVarFieldTypeError`, in case mismatch between `val` and allowed type.
- + :exc:`CTRexPktBuilder.VMVarValueError`, in case val isn't one of allowed options of field_name.
-
- """
- if not hasattr(self, field_name):
- raise CTRexPktBuilder.VMFieldNameError(field_name)
- elif field_name == "size":
- if type(val) != int:
- raise CTRexPktBuilder.VMFieldTypeError("size", int)
- elif val not in self.VALID_SIZE:
- raise CTRexPktBuilder.VMFieldValueError("size", self.VALID_SIZE)
- elif field_name in ["init_value", "min_value", "max_value"]:
- if type(val) != int:
- raise CTRexPktBuilder.VMFieldTypeError(field_name, int)
- elif field_name == "operation":
- if type(val) != str:
- raise CTRexPktBuilder.VMFieldTypeError("operation", str)
- elif val not in self.VALID_OPERATION:
- raise CTRexPktBuilder.VMFieldValueError("operation", self.VALID_OPERATION)
- # elif field_name == "split_by_core":
- # val = bool(val)
- # update field value on success
- setattr(self, field_name, val)
-
- def dump(self):
- """
- dumps a variable fields in a dictionary data structure.
-
- :parameters:
- None
-
- :return:
- dictionary holds variable data of VM variable
-
- """
- return {"type": "flow_var", # VM variable dump always refers to manipulate instruction.
- "name": self.name,
- "size": self.size,
- "op": self.operation,
- # "split_by_core": self.split_by_core,
- "init_value": self.init_value,
- "min_value": self.min_value,
- "max_value": self.max_value}
-
- class CTRexVMChecksumInst(CVMAbstractInstruction):
-
- def __init__(self, name, offset):
- """
- Instantiate a CTRexVMChecksumInst object
-
- :parameters:
- name : str
- a string representing the name of the VM variable.
- """
- super(CTRexPktBuilder.CTRexVM.CTRexVMChecksumInst, self).__init__(name)
- self.pkt_offset = offset
-
- def dump(self):
- return {"type": "fix_checksum_ipv4",
- "pkt_offset": int(self.pkt_offset)}
-
- class CTRexVMWrtFlowVarInst(CVMAbstractInstruction):
-
- def __init__(self, name, pkt_offset):
- """
- Instantiate a CTRexVMWrtFlowVarInst object
-
- :parameters:
- name : str
- a string representing the name of the VM variable.
- """
- super(CTRexPktBuilder.CTRexVM.CTRexVMWrtFlowVarInst, self).__init__(name)
- self.pkt_offset = int(pkt_offset)
- self.add_value = 0
- self.is_big_endian = False
-
- def set_field(self, field_name, val):
- if not hasattr(self, field_name):
- raise CTRexPktBuilder.VMFieldNameError(field_name)
- elif field_name == 'pkt_offset':
- raise ValueError("pkt_offset value cannot be changed")
- cur_attr_type = type(getattr(self, field_name))
- if cur_attr_type == type(val):
- setattr(self, field_name, val)
- else:
- CTRexPktBuilder.VMFieldTypeError(field_name, cur_attr_type)
-
- def dump(self):
- return {"type": "write_flow_var",
- "name": self.name,
- "pkt_offset": self.pkt_offset,
- "add_value": int(self.add_value),
- "is_big_endian": bool(self.is_big_endian)
- }
-
- class CTRexVMChecksumInst(CVMAbstractInstruction):
-
- def __init__(self, name, offset):
- """
- Instantiate a CTRexVMChecksumInst object
-
- :parameters:
- name : str
- a string representing the name of the VM variable.
- """
- super(CTRexPktBuilder.CTRexVM.CTRexVMChecksumInst, self).__init__(name)
- self.pkt_offset = offset
-
- def dump(self):
- return {"type": "fix_checksum_ipv4",
- "pkt_offset": int(self.pkt_offset)}
-
- class CTRexVMWrtFlowVarInst(CVMAbstractInstruction):
-
- def __init__(self, name, pkt_offset):
- """
- Instantiate a CTRexVMWrtFlowVarInst object
-
- :parameters:
- name : str
- a string representing the name of the VM variable.
- """
- super(CTRexPktBuilder.CTRexVM.CTRexVMWrtFlowVarInst, self).__init__(name)
- self.pkt_offset = int(pkt_offset)
- self.add_value = 0
- self.is_big_endian = False
-
- def set_field(self, field_name, val):
- if not hasattr(self, field_name):
- raise CTRexPktBuilder.VMFieldNameError(field_name)
- elif field_name == 'pkt_offset':
- raise ValueError("pkt_offset value cannot be changed")
- cur_attr_type = type(getattr(self, field_name))
- if cur_attr_type == type(val):
- setattr(self, field_name, val)
- else:
- CTRexPktBuilder.VMFieldTypeError(field_name, cur_attr_type)
-
- def dump(self):
- return {"type": "write_flow_var",
- "name": self.name,
- "pkt_offset": self.pkt_offset,
- "add_value": int(self.add_value),
- "is_big_endian": bool(self.is_big_endian)
- }
-
- class CPacketBuildException(Exception):
- """
- This is the general Packet Building error exception class.
- """
- def __init__(self, code, message):
- self.code = code
- self.message = message
-
- def __str__(self):
- return self.__repr__()
-
- def __repr__(self):
- return u"[errcode:%r] %r" % (self.code, self.message)
-
- class EmptyPacketError(CPacketBuildException):
- """
- This exception is used to indicate an error caused by operation performed on an empty packet.
- """
- def __init__(self, message=''):
- self._default_message = 'Illegal operation on empty packet.'
- self.message = message or self._default_message
- super(CTRexPktBuilder.EmptyPacketError, self).__init__(-10, self.message)
-
- class IPAddressError(CPacketBuildException):
- """
- This exception is used to indicate an error on the IP addressing part of the packet.
- """
- def __init__(self, message=''):
- self._default_message = 'Illegal type or value of IP address has been provided.'
- self.message = message or self._default_message
- super(CTRexPktBuilder.IPAddressError, self).__init__(-11, self.message)
-
- class MACAddressError(CPacketBuildException):
- """
- This exception is used to indicate an error on the MAC addressing part of the packet.
- """
- def __init__(self, message=''):
- self._default_message = 'Illegal MAC address has been provided.'
- self.message = message or self._default_message
- super(CTRexPktBuilder.MACAddressError, self).__init__(-12, self.message)
-
- class PacketLayerError(CPacketBuildException):
- """
- This exception is used to indicate an error caused by operation performed on an non-exists layer of the packet.
- """
- def __init__(self, name, message=''):
- self._default_message = "The given packet layer name ({0}) does not exists.".format(name)
- self.message = message or self._default_message
- super(CTRexPktBuilder.PacketLayerError, self).__init__(-13, self.message)
-
- class PacketLayerTypeError(CPacketBuildException):
- """
- This exception is used to indicate an error caused by operation performed on an non-exists layer of the packet.
- """
- def __init__(self, name, layer_type, ok_type, message=''):
- self._default_message = "The type of packet layer {layer_name} is of type {layer_type}, " \
- "and not of the expected {allowed_type}.".format(layer_name=name,
- layer_type=layer_type,
- allowed_type=ok_type.__name__)
- self.message = message or self._default_message
- super(CTRexPktBuilder.PacketLayerTypeError, self).__init__(-13, self.message)
-
- class VMVarNameExistsError(CPacketBuildException):
- """
- This exception is used to indicate a duplicate usage of VM variable.
- """
- def __init__(self, name, message=''):
- self._default_message = 'The given VM name ({0}) already exists as part of the stream.'.format(name)
- self.message = message or self._default_message
- super(CTRexPktBuilder.VMVarNameExistsError, self).__init__(-21, self.message)
-
- class VMFieldNameError(CPacketBuildException):
- """
- This exception is used to indicate that an undefined VM var field name has been accessed.
- """
- def __init__(self, name, message=''):
- self._default_message = "The given VM field name ({0}) is not defined and isn't legal.".format(name)
- self.message = message or self._default_message
- super(CTRexPktBuilder.VMFieldNameError, self).__init__(-22, self.message)
-
- class VMFieldTypeError(CPacketBuildException):
- """
- This exception is used to indicate an illegal value has type has been given to VM variable field.
- """
- def __init__(self, name, ok_type, message=''):
- self._default_message = "The desired value of field {field_name} is of type {field_type}, " \
- "and not of the allowed {allowed_type}.".format(field_name=name,
- field_type=type(name).__name__,
- allowed_type=ok_type.__name__)
- self.message = message or self._default_message
- super(CTRexPktBuilder.VMFieldTypeError, self).__init__(-31, self.message)
-
- class VMFieldValueError(CPacketBuildException):
- """
- This exception is used to indicate an error an illegal value has been assigned to VM variable field.
- """
- def __init__(self, name, ok_opts, message=''):
- self._default_message = "The desired value of field {field_name} is illegal.\n" \
- "The only allowed options are: {allowed_opts}.".format(field_name=name,
- allowed_opts=ok_opts)
- self.message = message or self._default_message
- super(CTRexPktBuilder.VMFieldValueError, self).__init__(-32, self.message)
-
-
-if __name__ == "__main__":
- pass
diff --git a/scripts/automation/trex_control_plane/client_utils/packet_builder_interface.py b/scripts/automation/trex_control_plane/client_utils/packet_builder_interface.py
deleted file mode 100644
index b6e7c026..00000000
--- a/scripts/automation/trex_control_plane/client_utils/packet_builder_interface.py
+++ /dev/null
@@ -1,43 +0,0 @@
-
-# base object class for a packet builder
-class CTrexPktBuilderInterface(object):
-
- def compile (self):
- """
- Compiles the packet and VM
- """
- raise Exception("implement me")
-
-
- def dump_pkt(self):
- """
- Dumps the packet as a decimal array of bytes (each item x gets value between 0-255)
-
- :parameters:
- None
-
- :return:
- + packet representation as array of bytes
-
- :raises:
- + :exc:`CTRexPktBuilder.EmptyPacketError`, in case packet is empty.
-
- """
-
- raise Exception("implement me")
-
-
- def get_vm_data(self):
- """
- Dumps the instructions
-
- :parameters:
- None
-
- :return:
- + json object of instructions
-
- """
-
- raise Exception("implement me")
-
diff --git a/scripts/automation/trex_control_plane/client_utils/scapy_packet_builder.py b/scripts/automation/trex_control_plane/client_utils/scapy_packet_builder.py
deleted file mode 100644
index b1b181c6..00000000
--- a/scripts/automation/trex_control_plane/client_utils/scapy_packet_builder.py
+++ /dev/null
@@ -1,748 +0,0 @@
-import external_packages
-import random
-import string
-import struct
-import socket
-import json
-import yaml
-import binascii
-import base64
-
-from packet_builder_interface import CTrexPktBuilderInterface
-
-from scapy.all import *
-
-
-
-class CTRexPacketBuildException(Exception):
- """
- This is the general Packet Building error exception class.
- """
- def __init__(self, code, message):
- self.code = code
- self.message = message
-
- def __str__(self):
- return self.__repr__()
-
- def __repr__(self):
- return u"[errcode:%r] %r" % (self.code, self.message)
-
-################################################################################################
-
-def ipv4_str_to_num (ipv4_buffer):
-
- assert type(ipv4_buffer)==str, 'type of ipv4_buffer is not str'
- assert len(ipv4_buffer)==4, 'size of ipv4_buffer is not 4'
- res=0
- shift=24
- for i in ipv4_buffer:
- res = res + (ord(i)<<shift);
- shift =shift -8
- return res
-
-
-
-def is_valid_ipv4(ip_addr):
- """
- return buffer in network order
- """
- if type(ip_addr)==str and len(ip_addr) == 4:
- return ip_addr
-
- if type(ip_addr)==int :
- ip_addr = socket.inet_ntoa(struct.pack("!I", ip_addr))
-
- try:
- return socket.inet_pton(socket.AF_INET, ip_addr)
- except AttributeError: # no inet_pton here, sorry
- return socket.inet_aton(ip_addr)
- except socket.error: # not a valid address
- raise CTRexPacketBuildException(-10,"not valid ipv4 format");
-
-
-class CTRexScriptsBase(object):
- """
- VM Script base class
- """
- def clone (self):
- return copy.deepcopy(self)
-
-
-class CTRexScFieldRangeBase(CTRexScriptsBase):
-
- FILED_TYPES = ['inc', 'dec', 'rand']
-
- def __init__(self, field_name,
- field_type
- ):
- super(CTRexScFieldRangeBase, self).__init__()
- self.field_name =field_name
- self.field_type =field_type
- if not self.field_type in CTRexScFieldRangeBase.FILED_TYPES :
- raise CTRexPacketBuildException(-12, 'field type should be in %s' % FILED_TYPES);
-
-
-class CTRexScFieldRangeValue(CTRexScFieldRangeBase):
- """
- range of field value
- """
- def __init__(self, field_name,
- field_type,
- min_value,
- max_value
- ):
- super(CTRexScFieldRangeValue, self).__init__(field_name,field_type)
- self.min_value =min_value;
- self.max_value =max_value;
- if min_value > max_value:
- raise CTRexPacketBuildException(-12, 'min is greater than max');
- if min_value == max_value:
- raise CTRexPacketBuildException(-13, "min value is equal to max value, you can't use this type of range");
-
-
-class CTRexScIpv4SimpleRange(CTRexScFieldRangeBase):
- """
- range of ipv4 ip
- """
- def __init__(self, field_name, field_type, min_ip, max_ip):
- super(CTRexScIpv4SimpleRange, self).__init__(field_name,field_type)
- self.min_ip = min_ip
- self.max_ip = max_ip
- mmin=ipv4_str_to_num (is_valid_ipv4(min_ip))
- mmax=ipv4_str_to_num (is_valid_ipv4(max_ip))
- if mmin > mmax :
- raise CTRexPacketBuildException(-11, 'CTRexScIpv4SimpleRange m_min ip is bigger than max');
-
-
-class CTRexScIpv4TupleGen(CTRexScriptsBase):
- """
- range tuple
- """
- FLAGS_ULIMIT_FLOWS =1
-
- def __init__(self, min_ipv4, max_ipv4, num_flows=100000, min_port=1025, max_port=65535, flags=0):
- super(CTRexScIpv4TupleGen, self).__init__()
- self.min_ip = min_ipv4
- self.max_ip = max_ipv4
- mmin=ipv4_str_to_num (is_valid_ipv4(min_ipv4))
- mmax=ipv4_str_to_num (is_valid_ipv4(max_ipv4))
- if mmin > mmax :
- raise CTRexPacketBuildException(-11, 'CTRexScIpv4SimpleRange m_min ip is bigger than max');
-
- self.num_flows=num_flows;
-
- self.min_port =min_port
- self.max_port =max_port
- self.flags = flags
-
-
-class CTRexScTrimPacketSize(CTRexScriptsBase):
- """
- trim packet size. field type is CTRexScFieldRangeBase.FILED_TYPES = ["inc","dec","rand"]
- """
- def __init__(self,field_type="rand",min_pkt_size=None, max_pkt_size=None):
- super(CTRexScTrimPacketSize, self).__init__()
- self.field_type = field_type
- self.min_pkt_size = min_pkt_size
- self.max_pkt_size = max_pkt_size
- if max_pkt_size != None and min_pkt_size !=None :
- if min_pkt_size == max_pkt_size:
- raise CTRexPacketBuildException(-11, 'CTRexScTrimPacketSize min_pkt_size is the same as max_pkt_size ');
-
- if min_pkt_size > max_pkt_size:
- raise CTRexPacketBuildException(-11, 'CTRexScTrimPacketSize min_pkt_size is bigger than max_pkt_size ');
-
-class CTRexScRaw(CTRexScriptsBase):
- """
- raw instructions
- """
- def __init__(self,list_of_commands=None):
- super(CTRexScRaw, self).__init__()
- if list_of_commands==None:
- self.commands =[]
- else:
- self.commands = list_of_commands
-
- def add_cmd (self,cmd):
- self.commands.append(cmd)
-
-
-
-################################################################################################
-# VM raw instructions
-################################################################################################
-
-class CTRexVmInsBase(object):
- """
- instruction base
- """
- def __init__(self, ins_type):
- self.type = ins_type
- assert type(ins_type)==str, 'type of ins_type is not str'
-
-class CTRexVmInsFixIpv4(CTRexVmInsBase):
- def __init__(self, offset):
- super(CTRexVmInsFixIpv4, self).__init__("fix_checksum_ipv4")
- self.pkt_offset = offset
- assert type(offset)==int, 'type of offset is not int'
-
-
-class CTRexVmInsFlowVar(CTRexVmInsBase):
- #TBD add more validation tests
-
- OPERATIONS =['inc', 'dec', 'random']
- VALID_SIZES =[1, 2, 4, 8]
-
- def __init__(self, fv_name, size, op, init_value, min_value, max_value):
- super(CTRexVmInsFlowVar, self).__init__("flow_var")
- self.name = fv_name;
- assert type(fv_name)==str, 'type of fv_name is not str'
- self.size = size
- self.op = op
- self.init_value = init_value
- assert type(init_value)==int, 'type of init_value is not int'
- self.min_value=min_value
- assert type(min_value)==int, 'type of min_value is not int'
- self.max_value=max_value
- assert type(max_value)==int, 'type of min_value is not int'
-
-class CTRexVmInsWrFlowVar(CTRexVmInsBase):
- def __init__(self, fv_name, pkt_offset, add_value=0, is_big_endian=True):
- super(CTRexVmInsWrFlowVar, self).__init__("write_flow_var")
- self.name = fv_name
- assert type(fv_name)==str, 'type of fv_name is not str'
- self.pkt_offset = pkt_offset
- assert type(pkt_offset)==int, 'type of pkt_offset is not int'
- self.add_value = add_value
- assert type(add_value)==int, 'type of add_value is not int'
- self.is_big_endian = is_big_endian
- assert type(is_big_endian)==bool, 'type of is_big_endian is not bool'
-
-class CTRexVmInsTrimPktSize(CTRexVmInsBase):
- def __init__(self,fv_name):
- super(CTRexVmInsTrimPktSize, self).__init__("trim_pkt_size")
- self.name = fv_name
- assert type(fv_name)==str, 'type of fv_name is not str'
-
-class CTRexVmInsTupleGen(CTRexVmInsBase):
- def __init__(self, fv_name, ip_min, ip_max, port_min, port_max, limit_flows, flags=0):
- super(CTRexVmInsTupleGen, self).__init__("tuple_flow_var")
- self.name =fv_name
- assert type(fv_name)==str, 'type of fv_name is not str'
- self.ip_min = ip_min;
- self.ip_max = ip_max;
- self.port_min = port_min;
- self.port_max = port_max;
- self.limit_flows = limit_flows;
- self.flags =flags;
-
-
-################################################################################################
-#
-class CTRexVmEngine(object):
-
- def __init__(self):
- """
- inlcude list of instruction
- """
- super(CTRexVmEngine, self).__init__()
- self.ins=[]
- self.split_by_var = ''
-
- # return as json
- def get_json (self):
- inst_array = [];
- # dump it as dict
- for obj in self.ins:
- inst_array.append(obj.__dict__);
-
- return {'instructions': inst_array, 'split_by_var': self.split_by_var}
-
- def add_ins (self,ins):
- #assert issubclass(ins, CTRexVmInsBase)
- self.ins.append(ins);
-
- def dump (self):
- cnt=0;
- for obj in self.ins:
- print "ins",cnt
- cnt = cnt +1
- print obj.__dict__
-
- def dump_bjson (self):
- print json.dumps(self.get_json(), sort_keys=True, indent=4)
-
- def dump_as_yaml (self):
- print yaml.dump(self.get_json(), default_flow_style=False)
-
-
-
-################################################################################################
-
-class CTRexScapyPktUtl(object):
-
- def __init__(self, scapy_pkt):
- self.pkt = scapy_pkt
-
- def pkt_iter (self):
- p=self.pkt;
- while True:
- yield p
- p=p.payload
- if p ==None or isinstance(p,NoPayload):
- break;
-
- def get_list_iter(self):
- l=list(self.pkt_iter())
- return l
-
-
- def get_pkt_layers(self):
- """
- return string 'IP:UDP:TCP'
- """
- l=self.get_list_iter ();
- l1=map(lambda p: p.name,l );
- return ":".join(l1);
-
- def _layer_offset(self, name, cnt = 0):
- """
- return offset of layer e.g 'IP',1 will return offfset of layer ip:1
- """
- save_cnt=cnt
- for pkt in self.pkt_iter ():
- if pkt.name == name:
- if cnt==0:
- return (pkt, pkt.offset)
- else:
- cnt=cnt -1
-
- raise CTRexPacketBuildException(-11,("no layer %s-%d" % (name, save_cnt)));
-
-
- def layer_offset(self, name, cnt = 0):
- """
- return offset of layer e.g 'IP',1 will return offfset of layer ip:1
- """
- save_cnt=cnt
- for pkt in self.pkt_iter ():
- if pkt.name == name:
- if cnt==0:
- return pkt.offset
- else:
- cnt=cnt -1
-
- raise CTRexPacketBuildException(-11,("no layer %s-%d" % (name, save_cnt)));
-
- def get_field_offet(self, layer, layer_cnt, field_name):
- """
- return offset of layer e.g 'IP',1 will return offfset of layer ip:1
- """
- t=self._layer_offset(layer,layer_cnt);
- l_offset=t[1];
- layer_pkt=t[0]
-
- #layer_pkt.dump_fields_offsets ()
-
- for f in layer_pkt.fields_desc:
- if f.name == field_name:
- return (l_offset+f.offset,f.get_size_bytes ());
-
- raise CTRexPacketBuildException(-11, "no layer %s-%d." % (name, save_cnt, field_name));
-
- def get_layer_offet_by_str(self, layer_des):
- """
- return layer offset by string
-
- :parameters:
-
- IP:0
- IP:1
- return offset
-
-
- """
- l1=layer_des.split(":")
- layer=""
- layer_cnt=0;
-
- if len(l1)==1:
- layer=l1[0];
- else:
- layer=l1[0];
- layer_cnt=int(l1[1]);
-
- return self.layer_offset(layer, layer_cnt)
-
-
-
- def get_field_offet_by_str(self, field_des):
- """
- return field_des (offset,size) layer:cnt.field
- for example
- 802|1Q.vlan get 802.1Q->valn replace | with .
- IP.src
- IP:0.src (first IP.src like IP.src)
- for example IP:1.src for internal IP
-
- return (offset, size) as tuple
-
-
- """
-
- s=field_des.split(".");
- if len(s)!=2:
- raise CTRexPacketBuildException(-11, ("field desription should be layer:cnt.field e.g IP.src or IP:1.src"));
-
-
- layer_ex = s[0].replace("|",".")
- field = s[1]
-
- l1=layer_ex.split(":")
- layer=""
- layer_cnt=0;
-
- if len(l1)==1:
- layer=l1[0];
- else:
- layer=l1[0];
- layer_cnt=int(l1[1]);
-
- return self.get_field_offet(layer,layer_cnt,field)
-
- def has_IPv4 (self):
- return self.pkt.has_layer("IP");
-
- def has_IPv6 (self):
- return self.pkt.has_layer("IPv6");
-
- def has_UDP (self):
- return self.pkt.has_layer("UDP");
-
-################################################################################################
-
-class CTRexVmDescBase(object):
- """
- instruction base
- """
- def __init__(self):
- pass;
-
- def get_obj(self):
- return self;
-
- def get_json(self):
- return self.get_obj().__dict__
-
- def dump_bjson(self):
- print json.dumps(self.get_json(), sort_keys=True, indent=4)
-
- def dump_as_yaml(self):
- print yaml.dump(self.get_json(), default_flow_style=False)
-
-
- def get_var_ref (self):
- '''
- virtual function return a ref var name
- '''
- return None
-
- def get_var_name(self):
- '''
- virtual function return the varible name if exists
- '''
- return None
-
- def compile(self,parent):
- '''
- virtual function to take parent than has function name_to_offset
- '''
- pass;
-
-
-def valid_fv_size (size):
- if not (size in CTRexVmInsFlowVar.VALID_SIZES):
- raise CTRexPacketBuildException(-11,("flow var has not valid size %d ") % size );
-
-def valid_fv_ops (op):
- if not (op in CTRexVmInsFlowVar.OPERATIONS):
- raise CTRexPacketBuildException(-11,("flow var does not have a valid op %s ") % op );
-
-def convert_val (val):
- if type(val) == int:
- return val
- else:
- if type(val) == str:
- return ipv4_str_to_num (is_valid_ipv4(val))
- else:
- raise CTRexPacketBuildException(-11,("init val not valid %s ") % val );
-
-def check_for_int (val):
- assert type(val)==int, 'type of vcal is not int'
-
-
-class CTRexVmDescFlowVar(CTRexVmDescBase):
- def __init__(self, name, init_value=None, min_value=0, max_value=255, size=4, op="inc"):
- super(CTRexVmDescFlowVar, self).__init__()
- self.name = name;
- assert type(name)==str, 'type of name is not str'
- self.size =size
- valid_fv_size(size)
- self.op =op
- valid_fv_ops (op)
-
- # choose default value for init val
- if init_value == None:
- init_value = max_value if op == "dec" else min_value
-
- self.init_value = convert_val (init_value)
- self.min_value = convert_val (min_value);
- self.max_value = convert_val (max_value)
-
- if self.min_value > self.max_value :
- raise CTRexPacketBuildException(-11,("max %d is lower than min %d ") % (self.max_value,self.min_value) );
-
- def get_obj (self):
- return CTRexVmInsFlowVar(self.name,self.size,self.op,self.init_value,self.min_value,self.max_value);
-
- def get_var_name(self):
- return [self.name]
-
-
-class CTRexVmDescFixIpv4(CTRexVmDescBase):
- def __init__(self, offset):
- super(CTRexVmDescFixIpv4, self).__init__()
- self.offset = offset; # could be a name of offset
-
- def get_obj (self):
- return CTRexVmInsFixIpv4(self.offset);
-
- def compile(self,parent):
- if type(self.offset)==str:
- self.offset = parent._pkt_layer_offset(self.offset);
-
-class CTRexVmDescWrFlowVar(CTRexVmDescBase):
- def __init__(self, fv_name, pkt_offset, offset_fixup=0, add_val=0, is_big=True):
- super(CTRexVmDescWrFlowVar, self).__init__()
- self.name =fv_name
- assert type(fv_name)==str, 'type of fv_name is not str'
- self.offset_fixup =offset_fixup
- assert type(offset_fixup)==int, 'type of offset_fixup is not int'
- self.pkt_offset =pkt_offset
- self.add_val =add_val
- assert type(add_val)==int,'type of add_val is not int'
- self.is_big =is_big;
- assert type(is_big)==bool,'type of is_big_endian is not bool'
-
- def get_var_ref (self):
- return self.name
-
- def get_obj (self):
- return CTRexVmInsWrFlowVar(self.name,self.pkt_offset+self.offset_fixup,self.add_val,self.is_big)
-
- def compile(self,parent):
- if type(self.pkt_offset)==str:
- t=parent._name_to_offset(self.pkt_offset)
- self.pkt_offset = t[0]
-
-
-class CTRexVmDescTrimPktSize(CTRexVmDescBase):
- def __init__(self,fv_name):
- super(CTRexVmDescTrimPktSize, self).__init__()
- self.name = fv_name
- assert type(fv_name)==str, 'type of fv_name is not str'
-
- def get_var_ref (self):
- return self.name
-
- def get_obj (self):
- return CTRexVmInsTrimPktSize(self.name)
-
-
-
-class CTRexVmDescTupleGen(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__()
- self.name = name
- assert type(name)==str, 'type of fv_name is not str'
- self.ip_min = convert_val(ip_min);
- self.ip_max = convert_val(ip_max);
- self.port_min = port_min;
- check_for_int (port_min)
- self.port_max = port_max;
- check_for_int(port_max)
- self.limit_flows = limit_flows;
- check_for_int(limit_flows)
- self.flags =flags;
- check_for_int(flags)
-
- def get_var_name(self):
- return [self.name+".ip",self.name+".port"]
-
- def get_obj (self):
- return CTRexVmInsTupleGen(self.name, self.ip_min, self.ip_max, self.port_min, self.port_max, self.limit_flows, self.flags);
-
-
-################################################################################################
-
-
-class CScapyTRexPktBuilder(CTrexPktBuilderInterface):
-
- """
- This class defines the TRex API of building a packet using dpkt package.
- Using this class the user can also define how TRex will handle the packet by specifying the VM setting.
- """
- def __init__(self, pkt = None, vm = None):
- """
- Instantiate a CTRexPktBuilder object
-
- :parameters:
- None
-
- """
- super(CScapyTRexPktBuilder, self).__init__()
-
- self.pkt = None
- self.vm_scripts = [] # list of high level instructions
- self.vm_low_level = None
- self.metadata=""
-
-
- # process packet
- if pkt != None:
- if not isinstance(pkt, Packet):
- raise CTRexPacketBuildException(-14, "bad value for variable pkt")
- self.set_packet(pkt)
-
- # process VM
- if vm != None:
- if not isinstance(vm, (CTRexScRaw, list)):
- raise CTRexPacketBuildException(-14, "bad value for variable vm")
-
- self.add_command(vm if isinstance(vm, CTRexScRaw) else CTRexScRaw(vm))
-
-
- def dump_vm_data_as_yaml(self):
- print yaml.dump(self.get_vm_data(), default_flow_style=False)
-
- def get_vm_data(self):
- """
- Dumps the instructions
-
- :parameters:
- None
-
- :return:
- + json object of instructions
-
- :raises:
- + :exc:`AssertionError`, in case VM is not compiled (is None).
- """
-
- assert self.vm_low_level is not None, 'vm_low_level is None, please use compile()'
-
- return self.vm_low_level.get_json()
-
- def dump_pkt(self, encode = True):
- """
- Dumps the packet as a decimal array of bytes (each item x gets value between 0-255)
-
- :parameters:
- encode : bool
- Encode using base64. (disable for debug)
-
- Default: **True**
-
- :return:
- + packet representation as array of bytes
-
- :raises:
- + :exc:`AssertionError`, in case packet is empty.
-
- """
-
- assert self.pkt, 'empty packet'
-
- return {'binary': base64.b64encode(str(self.pkt)) if encode else str(self.pkt),
- 'meta': self.metadata}
-
- def dump_pkt_to_pcap(self, file_path):
- wrpcap(file_path, self.pkt)
-
- def add_command (self, script):
- self.vm_scripts.append(script.clone());
-
- def dump_scripts (self):
- self.vm_low_level.dump_as_yaml()
-
- def set_packet (self, pkt):
- """
- Scapy packet Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025)/IP()/"A"*10
- """
- self.pkt = pkt;
-
-
- def compile (self):
- self.vm_low_level=CTRexVmEngine()
- assert self.pkt, 'empty packet'
- self.pkt.build();
-
-
- for sc in self.vm_scripts:
- if isinstance(sc, CTRexScRaw):
- self._compile_raw(sc)
-
- #for obj in self.vm_scripts:
- # # tuple gen script
- # if isinstance(obj, CTRexScIpv4TupleGen)
- # self._add_tuple_gen(tuple_gen)
-
- ####################################################
- # private
-
- def _compile_raw (self,obj):
-
- # make sure we have varibles once
- vars={};
-
- # add it add var to dit
- for desc in obj.commands:
- var_names = desc.get_var_name()
-
- if var_names :
- for var_name in var_names:
- if vars.has_key(var_name):
- raise CTRexPacketBuildException(-11,("variable %s define twice ") % (var_name) );
- else:
- vars[var_name]=1
-
- # check that all write exits
- for desc in obj.commands:
- var_name = desc.get_var_ref()
- if var_name :
- if not vars.has_key(var_name):
- raise CTRexPacketBuildException(-11,("variable %s does not exists ") % (var_name) );
- desc.compile(self);
-
- for desc in obj.commands:
- self.vm_low_level.add_ins(desc.get_obj());
-
-
- def _pkt_layer_offset (self,layer_name):
- assert self.pkt != None, 'empty packet'
- p_utl=CTRexScapyPktUtl(self.pkt);
- return p_utl.get_layer_offet_by_str(layer_name)
-
- def _name_to_offset(self,field_name):
- assert self.pkt != None, 'empty packet'
- p_utl=CTRexScapyPktUtl(self.pkt);
- return p_utl.get_field_offet_by_str(field_name)
-
- def _add_tuple_gen(self,tuple_gen):
-
- pass;
-
-
-
-
diff --git a/scripts/automation/trex_control_plane/client_utils/text_tables.py b/scripts/automation/trex_control_plane/client_utils/text_tables.py
index d8928da8..6b52a4a9 100644
--- a/scripts/automation/trex_control_plane/client_utils/text_tables.py
+++ b/scripts/automation/trex_control_plane/client_utils/text_tables.py
@@ -1,7 +1,5 @@
-
-import external_packages
from texttable import Texttable
-from common.text_opts import format_text
+from trex_control_plane.common.text_opts import format_text
class TRexTextTable(Texttable):
diff --git a/scripts/automation/trex_control_plane/client_utils/yaml_utils.py b/scripts/automation/trex_control_plane/client_utils/yaml_utils.py
index 825d6fc9..776a51a7 100755
--- a/scripts/automation/trex_control_plane/client_utils/yaml_utils.py
+++ b/scripts/automation/trex_control_plane/client_utils/yaml_utils.py
@@ -16,7 +16,6 @@ limitations under the License.
"""
import traceback
import sys
-import external_packages
import yaml