def __init__(self, platforms): """Create a new delegator instance. 'platforms' is a set of all platforms to support """ super().__init__('luastructs', Platform.mappings['default'], None) self.platforms = platforms self.field_var = 'f.' self.description = 'Lua C Structs' self.dissectors = {self.platform.name: self} self.var = create_lua_var('delegator') self.table_var = create_lua_var('dissector_table') self.id_table = create_lua_var('message_ids') self.sizes_table = create_lua_var('dissector_sizes') self.msg_var = create_lua_var('msg_node') # Add fields, don't change sizes! endian = Platform.big self.add_field(Field('Version', 'uint8', 1, 0, endian)) values = {p.flag: p.name for name, p in self.platforms.items()} field = Field('Flags', 'uint8', 1, 0, endian) field.set_list_validation(values) self.add_field(field) self.add_field(Field('Message', 'uint16', 2, 0, endian)) self.add_field(Field('Message length', 'uint32', 4, 0, endian)) self.version, self.flags, self.msg_id, self.length = self.children
def __init__(self, name, id=None, description=None): """Create a Protocol, for generating a dissector. 'name' is the name of the Protocol to dissect 'id' a list of message id's 'description' the description of the protocol to dissect """ if description is None: description = 'struct %s' % name self.name = name self.id = id self.description = description self.dissectors = {} # Map platform names to dissectors self.var = create_lua_var('proto_%s' % name)
def _dissector_func(self): """Add the code for the dissector function for the protocol.""" data = ['-- Delegator dissector function for %s' % self.name] # Add dissector function data.append('function delegator.dissector(buffer, pinfo, tree)') data.append('\tlocal subtree = tree:add(delegator, buffer())') data.append('\tpinfo.cols.protocol = delegator.name') data.append('\tpinfo.cols.info = delegator.description\n') # Fields code data.append(self.version.get_code(0)) data.append(self.flags.get_code(1)) t = '\tpinfo.private.platform_flag = {flag}' data.append(t.format(flag=self.flags._value_var)) data.append(self.msg_id.get_code(2, store=self.msg_var)) t = '\tsubtree:add(f.messagelength, buffer(4):len()):set_generated()' data.extend([t, '']) # Find message id and flag msg_var = create_lua_var('id_value') data.append(self.msg_id._store_value(msg_var)) data.append(self.length._store_value('length_value', offset=4)) data.append('') # Call the right dissector data.append('\t-- Call the correct dissector, or try and guess which') data.append('''\ if {ids}[{msg}] then {node}:append_text(" (" .. {ids}[{msg}] ..")") {table}:try({ids}[{msg}], buffer(4):tvb(), pinfo, tree) else {node}:add_expert_info(PI_MALFORMED, PI_WARN, "Unknown message id") if {sizes}[{flag}] and {sizes}[{flag}][{length}] then for key, value in pairs({sizes}[{flag}][{length}]) do {table}:try(value, buffer(4):tvb(), pinfo, tree) end end end\nend\n\n'''.format(ids=self.id_table, msg=msg_var, node=self.msg_var, sizes=self.sizes_table, flag=self.flags._value_var, table=self.table_var, length=self.length._value_var)) return '\n'.join(i for i in data if i is not None)
def match(self, name, code, definition=False, field=None): """Modify fields code if a cnf file demands it.""" # Handle extra code rules if name is None and code is None: if definition: token = self.t_def_extra else: token = self.t_func_extra return self.rules.get((name, token), '') if definition: tokens = self.def_tokens else: tokens = self.func_tokens # Modify code if field match any rules, body first for token in sorted(tokens): content = self.rules.get((name, token), '') if not content: continue if not definition and field is not None: # Insert field offset into content content = content.replace('{OFFSET}', str(field.offset)) # Insert value into content and code if '{VALUE}' in content: variable = create_lua_var('field_value_var') code = field.get_code(field.offset, store=variable) content = content.replace('{VALUE}', variable) if token.endswith('_HEADER'): code = '%s\n%s' % (content, code) elif token.endswith('_FOOTER'): code = '%s\n%s' % (code, content) elif token.endswith('_BODY'): content = content.replace('%(DEFAULT_BODY)s', code) content = content.replace('{DEFAULT_BODY}', code) code = content return code
def __init__(self, name, platform, conf=None): """Create a new dissector instance. 'name' is the protocol name 'platform' is the platform dissecting messages from 'conf' is an optional config object """ self.name = name self.platform = platform self.endian = platform.endian self.conf = conf self.field_var = 'f.' from config import Options if len(Options.platforms) > 1: self.field_var += create_lua_var(platform.name) self.children = [] # List of all child fields self._pushed = False self._increase_offset = True
def _dissector_func(self): """Add the code for the dissector function for the protocol.""" data = ['-- Dissector function for: %s' % self.name] def retrieve_pinfo(): data.append('\tif pinfo.private.field_name then') t = '\t\tsubtree:set_text(pinfo.private.field_name .. ": {name}")' data.append(t.format(name=child.name)) data.append('\t\tpinfo.private.field_name = nil\n\telse') t = '\t\tpinfo.cols.info:append("({desc})")' data.append(t.format(desc=self.description)) data.append('\tend') # Dissector function func_diss = 'function {var}.dissector(buffer, pinfo, tree)' data.append(func_diss.format(var=self.var)) # Retrieve flag value from private info table flag_var = create_lua_var('flag') flag = '\tlocal {var} = tonumber(pinfo.private.platform_flag)' data.append(flag.format(var=flag_var)) # If only 1 or less dissectors, insert dissector code directly if len(self.dissectors) < 2: if self.dissectors: child = list(self.dissectors.values())[0] sub_tree = '\tlocal subtree = tree:{add}({var}, buffer())' data.append(sub_tree.format(add=child.add_var, var=self.var)) retrieve_pinfo() data.append(child.get_code(0)) data.extend(['end', '']) return '\n'.join(i for i in data if i is not None) # Get flags and call the platform specific function table = {} for child in self.dissectors.values(): child._func_name = create_lua_var( '%s_%s' % (self.var, child.platform.name)) table[child.platform.flag] = child._func_name table = create_lua_valuestring(table, wrap=False) data.append('\tlocal func_mapping = {table}'.format(table=table)) data.append('\tif func_mapping[{var}] then'.format(var=flag_var)) call = '\t\t func_mapping[{var}](buffer, pinfo, tree)' data.append(call.format(var=flag_var)) data.extend(['\tend', 'end', '']) # Modify name if sub-dissector pinfo_func = create_lua_var('%s_pinfo_magic' % self.var) data.append('-- Function for retrieving parent dissector name') data.append('function {func}(pinfo, subtree)'.format(func=pinfo_func)) retrieve_pinfo() data.extend(['end', '']) # Create dissector function for each dissector for child in self.dissectors.values(): data.append('-- Dissector function for: %s (platform: %s)' % ( child.name, child.platform.name)) func = 'function {name}(buffer, pinfo, tree)' data.append(func.format(name=child._func_name)) # Add subtree sub_tree = '\tlocal subtree = tree:{add}({var}, buffer())' data.append(sub_tree.format(add=child.add_var, var=self.var)) data.append('\t{func}(pinfo, subtree)'.format(func=pinfo_func)) # Add the actual field code for each field data.append(child.get_code(0)) data.extend(['end', '']) return '\n'.join(i for i in data if i is not None)