def __init__ (self, stream_pack): if not isinstance(stream_pack, StreamPack): raise Exception("internal error") packet = CTRexPktBuilder() packet.load_from_stream_obj(stream_pack.stream) super(HACKSTLStream, self).__init__(packet, stream_id = stream_pack.stream_id) self.fields = stream_pack.stream
def __init__(self, stream_pack): if not isinstance(stream_pack, StreamPack): raise Exception("internal error") packet = CTRexPktBuilder() packet.load_from_stream_obj(stream_pack.stream) super(HACKSTLStream, self).__init__(packet, stream_id=stream_pack.stream_id) self.fields = stream_pack.stream
def __init__(self): self.is_loaded = False self._is_compiled = False self._pkt_bld_obj = CTRexPktBuilder() for field in CStream.FIELDS: setattr(self, field, None)
class CStream(object): """docstring for CStream""" FIELDS = ["enabled", "self_start", "next_stream_id", "isg", "mode", "rx_stats", "packet", "vm"] def __init__(self): self.is_loaded = False self._is_compiled = False self._pkt_bld_obj = CTRexPktBuilder() for field in CStream.FIELDS: setattr(self, field, None) def load_data(self, **kwargs): try: for k in CStream.FIELDS: if k == "rx_stats": rx_stats_data = kwargs[k] if isinstance(rx_stats_data, dict): setattr(self, k, CRxStats(**rx_stats_data)) elif isinstance(rx_stats_data, CRxStats): setattr(self, k, rx_stats_data) elif k == "mode": tx_mode = kwargs[k] if isinstance(tx_mode, dict): setattr(self, k, CTxMode(**tx_mode)) elif isinstance(tx_mode, CTxMode): setattr(self, k, tx_mode) elif k == "packet": if isinstance(kwargs[k], CTRexPktBuilder): if "vm" not in kwargs: self.load_packet_obj(kwargs[k]) break # vm field check is skipped else: raise ValueError("When providing packet object with a CTRexPktBuilder, vm parameter " "should not be supplied") else: binary = kwargs[k]["binary"] if isinstance(binary, str): # TODO: load to _pkt_bld_obj also when passed as byte array! if binary.endswith(".pcap"): self._pkt_bld_obj.load_packet_from_pcap(binary) self._pkt_bld_obj.metadata = kwargs[k]["meta"] self.packet = self._pkt_bld_obj.dump_pkt() else: self.packet = {} self.packet['binary'] = binary self.packet['meta'] = "" else: raise ValueError("Packet binary attribute has been loaded with unsupported value." "Supported values are reference to pcap file with SINGLE packet, " "or a list of unsigned-byte integers") else: setattr(self, k, kwargs[k]) self.is_loaded = True except KeyError as e: cause = e.args[0] raise KeyError("The attribute '{0}' is missing as a field of the CStream object.\n" "Loaded data must contain all of the following fields: {1}".format(cause, CStream.FIELDS)) def load_packet_obj(self, packet_obj): assert isinstance(packet_obj, CTRexPktBuilder) self.packet = packet_obj.dump_pkt() self.vm = packet_obj.get_vm_data() def load_packet_from_pcap(self, pcap_path, metadata=''): 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.packet = {"binary": [struct.unpack('B', buf[i:i+1])[0] # represent data as list of 0-255 ints for i in range(0, len(buf))], "meta": metadata} # meta data continues without a change. first_packet = False else: raise ValueError("Provided pcap file contains more than single packet.") # arrive here ONLY if pcap contained SINGLE packet return def dump(self): if self.is_loaded: dump = {} for key in CStream.FIELDS: try: dump[key] = getattr(self, key).dump() # use dump() method of compound object, such TxMode except AttributeError: dump[key] = getattr(self, key) return dump else: raise RuntimeError("CStream object isn't loaded with data. Use 'load_data' method.") def get_stream_layers(self, depth_limit=Ellipsis): stream_layers = self._pkt_bld_obj.get_packet_layers(depth_limit) return "/".join(stream_layers)
def generate_stream(l2_encap, mac_src, mac_dst, l3_protocol, ip_src_addr, ip_dst_addr, l3_length): ALLOWED_L3_PROTOCOL = { "ipv4": dpkt.ethernet.ETH_TYPE_IP, "ipv6": dpkt.ethernet.ETH_TYPE_IP6, "arp": dpkt.ethernet.ETH_TYPE_ARP } ALLOWED_L4_PROTOCOL = { "tcp": dpkt.ip.IP_PROTO_TCP, "udp": dpkt.ip.IP_PROTO_UDP, "icmp": dpkt.ip.IP_PROTO_ICMP, "icmpv6": dpkt.ip.IP_PROTO_ICMP6, "igmp": dpkt.ip.IP_PROTO_IGMP, "rtp": dpkt.ip.IP_PROTO_IRTP, "isis": dpkt.ip.IP_PROTO_ISIS, "ospf": dpkt.ip.IP_PROTO_OSPF } pkt_bld = CTRexPktBuilder() if l2_encap == "ethernet_ii": pkt_bld.add_pkt_layer("l2", dpkt.ethernet.Ethernet()) # set Ethernet layer attributes pkt_bld.set_eth_layer_addr("l2", "src", mac_src) pkt_bld.set_eth_layer_addr("l2", "dst", mac_dst) else: raise NotImplementedError( "l2_encap does not support the desired encapsulation '{0}'". format(l2_encap)) # set l3 on l2 if l3_protocol not in ALLOWED_L3_PROTOCOL: raise ValueError( "l3_protocol must be one of the following: {0}".format( ALLOWED_L3_PROTOCOL)) pkt_bld.set_layer_attr("l2", "type", ALLOWED_L3_PROTOCOL[l3_protocol]) # set l3 attributes if l3_protocol == "ipv4": pkt_bld.add_pkt_layer("l3", dpkt.ip.IP()) pkt_bld.set_ip_layer_addr("l3", "src", ip_src_addr) pkt_bld.set_ip_layer_addr("l3", "dst", ip_dst_addr) pkt_bld.set_layer_attr("l3", "len", l3_length) else: raise NotImplementedError( "l3_protocol '{0}' is not supported by TRex yet.".format( l3_protocol)) pkt_bld.dump_pkt_to_pcap("stream_test.pcap") return pkt_bld
class CStream(object): """docstring for CStream""" FIELDS = [ "enabled", "self_start", "next_stream_id", "isg", "mode", "rx_stats", "packet", "vm" ] def __init__(self): self.is_loaded = False self._is_compiled = False self._pkt_bld_obj = CTRexPktBuilder() for field in CStream.FIELDS: setattr(self, field, None) def load_data(self, **kwargs): try: for k in CStream.FIELDS: if k == "rx_stats": rx_stats_data = kwargs[k] if isinstance(rx_stats_data, dict): setattr(self, k, CRxStats(**rx_stats_data)) elif isinstance(rx_stats_data, CRxStats): setattr(self, k, rx_stats_data) elif k == "mode": tx_mode = kwargs[k] if isinstance(tx_mode, dict): setattr(self, k, CTxMode(**tx_mode)) elif isinstance(tx_mode, CTxMode): setattr(self, k, tx_mode) elif k == "packet": if isinstance(kwargs[k], CTRexPktBuilder): if "vm" not in kwargs: self.load_packet_obj(kwargs[k]) break # vm field check is skipped else: raise ValueError( "When providing packet object with a CTRexPktBuilder, vm parameter " "should not be supplied") else: binary = kwargs[k]["binary"] if isinstance(binary, str): # TODO: load to _pkt_bld_obj also when passed as byte array! if binary.endswith(".pcap"): self._pkt_bld_obj.load_packet_from_pcap(binary) self._pkt_bld_obj.metadata = kwargs[k]["meta"] self.packet = self._pkt_bld_obj.dump_pkt() else: self.packet = {} self.packet['binary'] = binary self.packet['meta'] = "" else: raise ValueError( "Packet binary attribute has been loaded with unsupported value." "Supported values are reference to pcap file with SINGLE packet, " "or a list of unsigned-byte integers") else: setattr(self, k, kwargs[k]) self.is_loaded = True except KeyError as e: cause = e.args[0] raise KeyError( "The attribute '{0}' is missing as a field of the CStream object.\n" "Loaded data must contain all of the following fields: {1}". format(cause, CStream.FIELDS)) def load_packet_obj(self, packet_obj): assert isinstance(packet_obj, CTRexPktBuilder) self.packet = packet_obj.dump_pkt() self.vm = packet_obj.get_vm_data() def load_packet_from_pcap(self, pcap_path, metadata=''): 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.packet = { "binary": [ struct.unpack('B', buf[i:i + 1])[ 0] # represent data as list of 0-255 ints for i in range(0, len(buf)) ], "meta": metadata } # meta data continues without a change. first_packet = False else: raise ValueError( "Provided pcap file contains more than single packet.") # arrive here ONLY if pcap contained SINGLE packet return def dump(self): if self.is_loaded: dump = {} for key in CStream.FIELDS: try: dump[key] = getattr(self, key).dump( ) # use dump() method of compound object, such TxMode except AttributeError: dump[key] = getattr(self, key) return dump else: raise RuntimeError( "CStream object isn't loaded with data. Use 'load_data' method." ) def get_stream_layers(self, depth_limit=Ellipsis): stream_layers = self._pkt_bld_obj.get_packet_layers(depth_limit) return "/".join(stream_layers)
def generate_stream(l2_encap, mac_src, mac_dst, l3_protocol, ip_src_addr, ip_dst_addr, l3_length): ALLOWED_L3_PROTOCOL = { "ipv4": dpkt.ethernet.ETH_TYPE_IP, "ipv6": dpkt.ethernet.ETH_TYPE_IP6, "arp": dpkt.ethernet.ETH_TYPE_ARP, } ALLOWED_L4_PROTOCOL = { "tcp": dpkt.ip.IP_PROTO_TCP, "udp": dpkt.ip.IP_PROTO_UDP, "icmp": dpkt.ip.IP_PROTO_ICMP, "icmpv6": dpkt.ip.IP_PROTO_ICMP6, "igmp": dpkt.ip.IP_PROTO_IGMP, "rtp": dpkt.ip.IP_PROTO_IRTP, "isis": dpkt.ip.IP_PROTO_ISIS, "ospf": dpkt.ip.IP_PROTO_OSPF, } pkt_bld = CTRexPktBuilder() if l2_encap == "ethernet_ii": pkt_bld.add_pkt_layer("l2", dpkt.ethernet.Ethernet()) # set Ethernet layer attributes pkt_bld.set_eth_layer_addr("l2", "src", mac_src) pkt_bld.set_eth_layer_addr("l2", "dst", mac_dst) else: raise NotImplementedError("l2_encap does not support the desired encapsulation '{0}'".format(l2_encap)) # set l3 on l2 if l3_protocol not in ALLOWED_L3_PROTOCOL: raise ValueError("l3_protocol must be one of the following: {0}".format(ALLOWED_L3_PROTOCOL)) pkt_bld.set_layer_attr("l2", "type", ALLOWED_L3_PROTOCOL[l3_protocol]) # set l3 attributes if l3_protocol == "ipv4": pkt_bld.add_pkt_layer("l3", dpkt.ip.IP()) pkt_bld.set_ip_layer_addr("l3", "src", ip_src_addr) pkt_bld.set_ip_layer_addr("l3", "dst", ip_dst_addr) pkt_bld.set_layer_attr("l3", "len", l3_length) else: raise NotImplementedError("l3_protocol '{0}' is not supported by TRex yet.".format(l3_protocol)) pkt_bld.dump_pkt_to_pcap("stream_test.pcap") return pkt_bld