示例#1
0
        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
示例#2
0
    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))
示例#3
0
 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)
示例#4
0
    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)