summaryrefslogtreecommitdiffstats
path: root/scripts/automation/trex_control_plane/client_utils
diff options
context:
space:
mode:
authorDan Klein <danklei@cisco.com>2015-09-10 13:39:18 +0300
committerDan Klein <danklei@cisco.com>2015-09-10 13:39:18 +0300
commitef520c7e3a18aeefe02ba0d3e6b16fafde3c1b91 (patch)
treee787cc29908a286129dd2134d2150bc56e775a04 /scripts/automation/trex_control_plane/client_utils
parent760710869405dbc3b5dadd6ce06015c72ea2ca44 (diff)
Major progress in Packet building module and VM instruction sets.
added dot1q into dpkt lib First abstractino of HLTAPI layer
Diffstat (limited to 'scripts/automation/trex_control_plane/client_utils')
-rw-r--r--scripts/automation/trex_control_plane/client_utils/packet_builder.py566
1 files changed, 492 insertions, 74 deletions
diff --git a/scripts/automation/trex_control_plane/client_utils/packet_builder.py b/scripts/automation/trex_control_plane/client_utils/packet_builder.py
index 0d31f28e..abe98dbb 100644
--- a/scripts/automation/trex_control_plane/client_utils/packet_builder.py
+++ b/scripts/automation/trex_control_plane/client_utils/packet_builder.py
@@ -5,23 +5,207 @@ import outer_packages
import dpkt
import socket
import binascii
+import copy
+import random
+import string
+import struct
+import re
class CTRexPktBuilder(object):
- """docstring for CTRexPktBuilder"""
- def __init__(self):
+ """
+ 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.vm = CTRexPktBuilder.CTRexVM(self.packet)
+ self._packet = None
+ self._pkt_by_hdr = {}
+ self._pkt_top_layer = None
+ self._max_pkt_size = max_pkt_size
+ self.payload_generator = CTRexPktBuilder.CTRexPayloadGen(self._packet, self._max_pkt_size)
+ self.vm = CTRexPktBuilder.CTRexVM()
+
+ def add_pkt_layer(self, layer_name, pkt_layer):
+ """
+ This method adds additional header to the already existing packet
- def add_l2_header(self):
- pass
+ :parameters:
+ layer_name: str
+ a string representing the name of the layer.
+ Example: "l2", "l4_tcp", etc.
- def add_l3_header(self):
- pass
+ pkt_layer : dpkt.Packet obj
+ a dpkt object, generally from higher layer, that will be added on top of existing layer.
- def add_pkt_payload(self):
- pass
+ """
+ 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"):
+ 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):
+ self.set_ip_layer_addr(self, layer_name, attr, ip_addr, ip_type="ipv6")
+
+ def set_eth_layer_addr(self, layer_name, attr, mac_addr):
+ 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):
+ """
+ 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.
+
+ :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 obejct that is not dpkt.Packet is not allowed using "
+ "set_layer_attr method.\nUse set_payload method instead.")
+ if hasattr(layer, attr):
+ 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_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 get_packet(self, get_ptr=False):
+ """
+ This method enables the user to change a value of a previously defined packet layer.
+
+ :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.
+
+ """
+ if get_ptr:
+ self._pkt_by_hdr = {}
+ self._pkt_top_layer = None
+ return self._packet
+
+ else:
+ return copy.copy(self._packet)
# VM access methods
def set_vm_ip_range(self, ip_start, ip_end, ip_type="ipv4"):
@@ -37,7 +221,7 @@ class CTRexPktBuilder(object):
pass
def dump_pkt(self):
- pkt_in_hex = binascii.hexlify(str(self.packet))
+ pkt_in_hex = binascii.hexlify(str(self._packet))
return [pkt_in_hex[i:i+2] for i in range(0, len(pkt_in_hex), 2)]
# ----- useful shortcut methods ----- #
@@ -45,118 +229,334 @@ class CTRexPktBuilder(object):
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
+
+ @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 _is_valid_ip_addr(ip_addr, ip_type):
+ 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:
- socket.inet_pton(socket.AF_INET, ip_addr)
+ return socket.inet_pton(socket.AF_INET, ip_addr)
except AttributeError: # no inet_pton here, sorry
- try:
- socket.inet_aton(ip_addr)
- except socket.error:
- return False
- return ip_addr.count('.') == 3
+ # try:
+ return socket.inet_aton(ip_addr)
+ # except socket.error:
+ # return False
+ # return ip_addr.count('.') == 3
except socket.error: # not a valid address
- return False
- return True
+ raise CTRexPktBuilder.IPAddressError()
elif ip_type == "ipv6":
try:
- socket.inet_pton(socket.AF_INET6, ip_addr)
+ return socket.inet_pton(socket.AF_INET6, ip_addr)
except socket.error: # not a valid address
- return False
- return True
+ raise CTRexPktBuilder.IPAddressError()
else:
raise CTRexPktBuilder.IPAddressError()
- # ------ private classes ------
+ # ------ 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):
- """docstring for CTRexVM"""
- def __init__(self, packet):
+ """
+ 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.
+ """
+ def __init__(self):
+ """
+ Instantiate a CTRexVM object
+
+ :parameters:
+ None
+ """
super(CTRexPktBuilder.CTRexVM, self).__init__()
- self.packet = packet
self.vm_variables = {}
- def add_vm_variable(self, name):
+ def set_vm_var_field(self, var_name, field_name, val):
+ """
+ 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.
+
+ """
+ return self.vm_variables[var_name].set_field(field_name, val)
+
+ def add_flow_man_simple(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.keys():
self.vm_variables[name] = self.CTRexVMVariable(name)
+ # try configuring VM var attributes
+ for (field, value) in kwargs.items():
+ self.vm_variables[name].set_field(field, value)
else:
raise CTRexPktBuilder.VMVarNameExistsError(name)
- def set_vm_var_field(self, var_name, field_name, val):
- pass
- return self.vm_variables[var_name].set_field(field_name, val)
+ 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.
- def fix_checksum_ipv4(self):
- pass
+ :return:
+ list holds variables data of VM
- def flow_man_simple(self):
- pass
-
- def write_to_pkt(self):
- pass
+ """
+ assert isinstance(flow_obj, CTRexPktBuilder.CTRexVM.CTRexVMVariable)
+ 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 dump(self):
+ """
+ dumps a VM variables (instructions) into an list data structure.
+
+ :parameters:
+ None
+
+ :return:
+ list holds variables data of VM
+
+ """
return [var.dump()
- for var in self.vm_variables]
+ for key, var in self.vm_variables.items()]
class CTRexVMVariable(object):
+ """
+ This class defines a single VM variable to be used as part of CTRexVar object.
+ """
VALID_SIZE = [1, 2, 4, 8]
- VALID_TYPE = ["inc", "dec", "random"]
- VALID_CORE_MASK = ["split", "none"]
+ 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.CTRexVMVariable, self).__init__()
self.name = name
self.size = 4
self.big_endian = True
- self.type = "inc"
- self.core_mask = "none"
- self.init_addr = "10.0.0.1"
- self.min_addr = str(self.init_addr)
- self.max_addr = str(self.init_addr)
+ 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):
- if field_name == "size":
+ """
+ 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.VMVarNameError(field_name)
+ elif field_name == "size":
if type(val) != int:
raise CTRexPktBuilder.VMVarFieldTypeError("size", int)
elif val not in self.VALID_SIZE:
raise CTRexPktBuilder.VMVarValueError("size", self.VALID_SIZE)
- elif field_name == "type":
- if type(val) != str:
- raise CTRexPktBuilder.VMVarFieldTypeError("type", str)
- elif val not in self.VALID_TYPE:
- raise CTRexPktBuilder.VMVarValueError("type", self.VALID_TYPE)
- elif field_name == "core_mask":
+ elif field_name == "init_value":
+ if type(val) != int:
+ raise CTRexPktBuilder.VMVarFieldTypeError("init_value", int)
+ elif field_name == "operation":
if type(val) != str:
- raise CTRexPktBuilder.VMVarFieldTypeError("core_mask", str)
- elif val not in self.VALID_TYPE:
- raise CTRexPktBuilder.VMVarValueError("core_mask", self.VALID_CORE_MASK)
+ raise CTRexPktBuilder.VMVarFieldTypeError("operation", str)
+ elif val not in self.VALID_OPERATION:
+ raise CTRexPktBuilder.VMVarValueError("operation", self.VALID_OPERATION)
+ elif field_name == "split_by_core":
+ val = bool(val)
# update field value on success
setattr(self, field_name, val)
def is_valid(self):
if self.size not in self.VALID_SIZE:
return False
- if self.type not in self.VALID_TYPE:
- return False
- if self.core_mask not in self.VALID_CORE_MASK:
+ if self.type not in self.VALID_OPERATION:
return False
return True
def dump(self):
- return {"name" : self.name,
- "Size" : self.size,
- "big_endian" : self.big_endian,
- "type" : self.type,
- "core_mask" : self.core_mask,
- "init_addr" : self.init_addr,
- "min_addr" : self.min_addr,
- "max_addr" : self.max_addr}
+ """
+ dumps a variable fields in a dictionary data structure.
+
+ :parameters:
+ None
+
+ :return:
+ dictionary holds variable data of VM variable
+
+ """
+ return {"ins_name": "flow_man_simple", # VM variable dump always refers to manipulate instruction.
+ "flow_variable_name": self.name,
+ "object_size": self.size,
+ # "big_endian": self.big_endian,
+ "Operation": 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 CPacketBuildException(Exception):
"""
- This is the general Packet error exception class.
+ This is the general Packet Building error exception class.
"""
def __init__(self, code, message):
self.code = code
@@ -173,22 +573,40 @@ class CTRexPktBuilder(object):
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 of IP addressing has been provided.'
+ 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__(-11, self.message)
+
class VMVarNameExistsError(CPacketBuildException):
"""
- This exception is used to indicate an error on the IP addressing part of the packet.
+ 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._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 VMVarNameError(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.VMVarNameError, self).__init__(-22, self.message)
+
class VMVarFieldTypeError(CPacketBuildException):
"""
- This exception is used to indicate an error on the IP addressing part of the packet.
+ 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}, \
@@ -196,11 +614,11 @@ class CTRexPktBuilder(object):
field_type=type(name).__name__,
allowed_type=ok_type.__name__)
self.message = message or self._default_message
- super(CTRexPktBuilder.VMVarNameExistsError, self).__init__(-31, self.message)
+ super(CTRexPktBuilder.VMVarFieldTypeError, self).__init__(-31, self.message)
class VMVarValueError(CPacketBuildException):
"""
- This exception is used to indicate an error on the IP addressing part of the packet.
+ 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 \