def local_get_field_tree(local_field: LayerField) -> PcapLayerField: """ :param local_field: The LayerField to insert in dict """ try: parent_poss = (int(local_field.pos), int(local_field.pos) - int(local_field.size)) except TypeError: parent_poss = () local_field.pos = 0 local_field.size = 0 if local_field.name is None: local_field.name = '' field_tree_keys = local_field.name.split('.') family, node = update_field_tree_keys(field_tree_keys) def find_pcap_layer_field_parent(local_member: dict, only_hex: bool = False) -> PcapLayerField or None: """ If exists, found the big brother of local_field, otherwise, the parent :param local_member: The family tree of local_field (as dict) :param only_hex: True if the member_parent of local_field should has an hexadecimal value :return: If exits, the big brother of local_field, otherwise, the parent or None """ parent = None for key, member_parent in local_member.items(): member_parent: PcapLayerField or dict if not only_hex and isinstance(member_parent, dict): # Check brothers member_brother = find_pcap_layer_field_parent(member_parent, True) if member_brother is not None: return member_brother # brother if key in parent_poss and member_parent.name != local_field.name: member_parent: PcapLayerField if not only_hex: parent = member_parent # parent (but the preferred is brother) elif is_hex(member_parent.value) and \ member_parent.pos == int(local_field.pos) and \ not PcapSniffer._field_is_binary(member_parent): return member_parent # brother return parent pcap_layer_field_parent = None for member in family: pcap_layer_field_parent = find_pcap_layer_field_parent(member) if pcap_layer_field_parent is not None: break if pcap_layer_field_parent is None: pcap_layer_field_parent = pcap_layer_field_root local_field_sanitized_name = layer._sanitize_field_name(local_field.name) local_pcap_layer_field = PcapLayerField( local_field, local_field_sanitized_name, pcap_layer_field_parent ) node[int(local_field.pos)] = local_pcap_layer_field # Update dictionary tree return local_pcap_layer_field
def _make_wrapped_field(self, name, field, is_fake=False, full_name=None): """Creates the field lazily. If it's a simple field, wraps it in a container that adds extra features. If it's a nested layer, creates a layer for it. If it's an intermediate layer, copies over the relevant fields and creates a new layer for it. """ if not full_name: full_name = '%s.%s' % (self._full_name, name) if is_fake: # Populate with all fields that are supposed to be inside of it field = { key: value for key, value in self._all_fields.items() if key.startswith(full_name) } if isinstance(field, dict): if name.endswith('_tree'): name = name.replace('_tree', '') full_name = '%s.%s' % (self._full_name, name) return JsonLayer(name, field, full_name=full_name, is_intermediate=is_fake) elif isinstance(field, list): # For whatever reason in list-type object it goes back to using the original parent name return [ self._make_wrapped_field( name, field_part, full_name=self._full_name.split('.')[0]) for field_part in field ] return LayerFieldsContainer(LayerField(name=name, value=field))
def _add_field(self, key: str, val: str): logging.debug("layer %s add field: %s = %s", self.layer_name, key, val) field = LayerField(name=key, value=val) all_fields = self._layer._all_fields if key not in all_fields: all_fields[key] = LayerFieldsContainer(main_field=field) else: all_fields[key].fields.append(field)
def __init__(self, xml_obj=None, raw_mode=False): self.raw_mode = raw_mode self._layer_name = xml_obj.attrib['name'] self._all_fields = {} # We copy over all the fields from the XML object # Note: we don't read lazily from the XML because the lxml objects are very memory-inefficient # so we'd rather not save them. for field in xml_obj.findall('.//field'): attributes = dict(field.attrib) field_obj = LayerField(**attributes) if attributes['name'] in self._all_fields: # Field name already exists, add this field to the container. self._all_fields[attributes['name']].add_field(field_obj) else: self._all_fields[attributes['name']] = LayerFieldsContainer(field_obj)