From 2c575880c6b5bd0a6c4f1df91f819118af800699 Mon Sep 17 00:00:00 2001 From: itraviv Date: Mon, 15 Aug 2016 17:52:38 +0300 Subject: scapy_server_test: added cases for testing: GRE, VXML, DNS, IPv6 changed test functions to include only the testted object and created other functions as testing engines. scapy_service: added api class. added documentry for api class changed method functions to include underscore --- .../stl/services/scapy_server/scapy_service.py | 214 ++++++++++++++------- .../stl/services/scapy_server/scapy_zmq_server.py | 8 +- 2 files changed, 149 insertions(+), 73 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl/services/scapy_server') diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_service.py b/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_service.py index 638d35f2..3519bb58 100755 --- a/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_service.py +++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_service.py @@ -2,7 +2,9 @@ import os import sys stl_pathname = os.path.abspath(os.path.join(os.pardir, os.pardir)) +additional_stl_udp_pkts = os.path.abspath(os.path.join(os.pardir, os.pardir,'stl')) sys.path.append(stl_pathname) +sys.path.append(additional_stl_udp_pkts) import trex_stl_lib from trex_stl_lib.api import * from copy import deepcopy @@ -11,32 +13,106 @@ import tempfile import hashlib import binascii from pprint import pprint - +from scapy.layers.dns import * +from udp_1pkt_vxlan import VXLAN +from udp_1pkt_mpls import MPLS try: from cStringIO import StringIO except ImportError: from io import StringIO -""" - **** output redirection template **** -old_stdout = sys.stdout -sys.stdout = mystdout = StringIO() -ls() -sys.stdout = old_stdout -a= mystdout.getvalue() +class Scapy_service_api(): + """ get_all(self) -f = open('scapy_supported_formats.txt','w') -f.write(a) -f.close() -""" + Sends all the protocols and fields that Scapy Service supports. + also sends the md5 of the Protocol DB and Fields DB used to check if the DB's are up to date -class ScapyException(Exception): pass + Parameters + ---------- + None + + Returns + ------- + Dictionary (of protocol DB and scapy fields DB) + + Raises + ------ + Raises an exception when a DB error occurs (i.e a layer is not loaded properly and has missing components) + """ + def get_all(self): + pass + + """ check_update(self,db_md5,field_md5) + Checks if the Scapy Service running on the server has a newer version of the databases that the client has + + Parameters + ---------- + db_md5 - The md5 that was delivered with the protocol database that the client owns, when first received at the client + field_md5 - The md5 that was delivered with the fields database that the client owns, when first received at the client + + Returns + ------- + True/False according the Databases version(determined by their md5) + + Raises + ------ + Raises an exception (ScapyException) when protocol DB/Fields DB is not up to date + + """ -class Scapy_service: + def check_update(self,db_md5,field_md5): + pass + + """ build_pkt(self,pkt_descriptor) -> Dictionary (of Offsets,Show2 and Buffer) + + Performs calculations on the given packet and returns results for that packet. + + Parameters + ---------- + pkt_descriptor - A string describing a network packet, in Scapy Format + + Returns + ------- + - The packets offsets: each field in every layer is mapped inside the Offsets Dictionary + - The Show2: A description of each field and its value in every layer of the packet + - The Buffer: The Hexdump of packet encoded in base64 + + Raises + ------ + will raise an exception when the Scapy string format is illegal, contains syntax error, contains non-supported + protocl, etc. + """ + def build_pkt(self,pkt_descriptor): + pass + + """ get_tree(self) -> Dictionary describing an example of hierarchy in layers + + Scapy service holds a tree of layers that can be stacked to a recommended packet + according to the hierarchy + + Parameters + ---------- + None + + Returns + ------- + Returns an example hierarchy tree of layers that can be stacked to a packet + + Raises + ------ + None + """ + def get_tree(self): + pass + + + +class ScapyException(Exception): pass +class Scapy_service(Scapy_service_api): #---------------------------------------------------------------------------------------------------- class scapyRegex: @@ -55,10 +131,10 @@ class Scapy_service: self.low_level_protocols = { 'Ether': self.network_protocols } self.regexDB= {'MACField' : self.scapyRegex('MACField','^([0-9a-fA-F][0-9a-fA-F]:){5}([0-9a-fA-F][0-9a-fA-F])$'), 'IPField' : self.scapyRegex('IPField','^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$')} - self.all_protocols = self.build_lib() + self.all_protocols = self._build_lib() self.protocol_tree = {'ALL':{'Ether':{'ARP':{},'IP':{'TCP':{'RAW':'payload'},'UDP':{'RAW':'payload'}}}}} - def protocol_struct(self,protocol=''): + def _protocol_struct(self,protocol=''): if '_' in protocol: return [] if not protocol=='': @@ -75,8 +151,8 @@ class Scapy_service: protocol_data= mystdout.getvalue() return protocol_data - def build_lib(self): - lib = self.protocol_struct() + def _build_lib(self): + lib = self._protocol_struct() lib = lib.split('\n') all_protocols=[] for entry in lib: @@ -85,45 +161,39 @@ class Scapy_service: del all_protocols[len(all_protocols)-1] return all_protocols - def parse_description_line(self,line): + def _parse_description_line(self,line): line_arr = [x.strip() for x in re.split(': | = ',line)] return tuple(line_arr) - def parse_entire_description(self,description): + def _parse_entire_description(self,description): description = description.split('\n') - description_list = [self.parse_description_line(x) for x in description] + description_list = [self._parse_description_line(x) for x in description] del description_list[len(description_list)-1] return description_list - def get_protocol_details(self,p_name): - protocol_str = self.protocol_struct(p_name) + def _get_protocol_details(self,p_name): + protocol_str = self._protocol_struct(p_name) if protocol_str=='protocol not supported': return 'protocol not supported' if len(protocol_str) is 0: return [] - tupled_protocol = self.parse_entire_description(protocol_str) + tupled_protocol = self._parse_entire_description(protocol_str) return tupled_protocol - def print_tree(self): + def _print_tree(self): pprint(self.protocol_tree) - def get_all_protocols(self): - return self.all_protocols - - def get_tree(self): - return self.protocol_tree - - def get_all_db(self): + def _get_all_db(self): db = {} for pro in self.all_protocols: - details = self.get_protocol_details(pro) + details = self._get_protocol_details(pro) db[pro] = details return db - def get_all_fields(self): + def _get_all_fields(self): fields = [] for pro in self.all_protocols: - details = self.get_protocol_details(pro) + details = self._get_protocol_details(pro) for i in range(0,len(details),1): if len(details[i]) is 3: fields.append(details[i][1]) @@ -136,7 +206,7 @@ class Scapy_service: fieldDict[f] = self.scapyRegex(f).stringRegex() return fieldDict - def show2_to_dict(self,pkt): + def _show2_to_dict(self,pkt): old_stdout = sys.stdout sys.stdout = mystdout = StringIO() pkt.show2() @@ -160,7 +230,7 @@ class Scapy_service: #pkt_desc as string #dictionary of offsets per protocol. tuple for each field: (name, offset, size) at json format - def get_all_pkt_offsets(self,pkt_desc): + def _get_all_pkt_offsets(self,pkt_desc): pkt_protocols = pkt_desc.split('/') scapy_pkt = eval(pkt_desc) scapy_pkt.build() @@ -181,34 +251,51 @@ class Scapy_service: scapy_pkt=scapy_pkt.payload return res -# pkt_descriptor in string format +#input: container +#output: md5 encoded in base64 + def _get_md5(self,container): + container = json.dumps(container) + m = hashlib.md5() + m.update(container.encode('ascii')) + res_md5 = binascii.b2a_base64(m.digest()) + return res_md5 + def get_version(self): + return {'built_by':'itraviv','version':'v1.0'} + + def supported_methods(self,method_name=''): + if method_name=='': + methods = {} + for f in dir(Scapy_service): + if inspect.ismethod(eval('Scapy_service.'+f)): + methods[f] = inspect.getargspec(eval('Scapy_service.'+f))[0] + return methods + if method_name in dir(Scapy_service): + return True + return False + +#--------------------------------------------API implementation------------- + def get_tree(self): + return self.protocol_tree + +# pkt_descriptor in string format def build_pkt(self,pkt_descriptor): pkt = eval(pkt_descriptor) - show2data = self.show2_to_dict(pkt) + show2data = self._show2_to_dict(pkt) bufferData = str(pkt) #pkt buffer bufferData = binascii.b2a_base64(bufferData) - pkt_offsets = self.get_all_pkt_offsets(pkt_descriptor) + pkt_offsets = self._get_all_pkt_offsets(pkt_descriptor) res = {} res['show2'] = show2data res['buffer'] = bufferData res['offsets'] = pkt_offsets return res -#input: container -#output: md5 encoded in base64 - def get_md5(self,container): - container = json.dumps(container) - m = hashlib.md5() - m.update(container.encode('ascii')) - res_md5 = binascii.b2a_base64(m.digest()) - return res_md5 - def get_all(self): - fields=self.get_all_fields() - db=self.get_all_db() - fields_md5 = self.get_md5(fields) - db_md5 = self.get_md5(db) + fields=self._get_all_fields() + db=self._get_all_db() + fields_md5 = self._get_md5(fields) + db_md5 = self._get_md5(db) res = {} res['db'] = db res['fields'] = fields @@ -218,10 +305,10 @@ class Scapy_service: #input in string encoded base64 def check_update(self,db_md5,field_md5): - fields=self.get_all_fields() - db=self.get_all_db() - current_db_md5 = self.get_md5(db) - current_field_md5 = self.get_md5(fields) + fields=self._get_all_fields() + db=self._get_all_db() + current_db_md5 = self._get_md5(db) + current_field_md5 = self._get_md5(fields) res = [] if (field_md5.decode("base64") == current_field_md5.decode("base64")): if (db_md5.decode("base64") == current_db_md5.decode("base64")): @@ -231,18 +318,7 @@ class Scapy_service: else: raise ScapyException("Fields DB is not up to date") - def get_version(self): - return {'built_by':'itraviv','version':'v1.0'} - def supported_methods(self,method_name=''): - if method_name=='': - methods = {} - for f in dir(Scapy_service): - if inspect.ismethod(eval('Scapy_service.'+f)): - methods[f] = inspect.getargspec(eval('Scapy_service.'+f))[0] - return methods - if method_name in dir(Scapy_service): - return True - return False +#--------------------------------------------------------------------------- diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_zmq_server.py b/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_zmq_server.py index b2f2d526..408f1daf 100755 --- a/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_zmq_server.py +++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_zmq_server.py @@ -106,16 +106,16 @@ class Scapy_server(): self.IP_address = socket.gethostbyname(socket.gethostname()) def activate(self): - print '***Scapy Server Started***\nListening on port: %d' % self.port - print 'Server IP address: %s' % self.IP_address + print ('***Scapy Server Started***\nListening on port: %d' % self.port) + print ('Server IP address: %s' % self.IP_address) try: while True: message = self.socket.recv() try: method,params,req_id = self.scapy_wrapper.parse_req_msg(message) if (method == 'shut_down'): - print 'Shut down by remote user' - result = 'Server shut down command received - server has shut down' + print ('Shut down by remote user') + result = 'Server shut down command received - server had shut down' else: result = self.scapy_wrapper.execute(method,params) response = self.scapy_wrapper.create_success_response(result,req_id) -- cgit 1.2.3-korg