Ejemplo n.º 1
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))
Ejemplo n.º 2
0
def get_layer_field(packet: RawPacket, field_uri: str) -> Any:
    """
    Get a given layer field from the packet.

    :param packet: The packet.
    :param field_uri: The layer field URI.

    :return: The specified layer field.
    """
    assert isinstance(packet, RawPacket)
    secs = field_uri.split('.')
    layer_name = secs[0]

    if is_layer_field(field_uri):
        candidate_layers = _get_candidate_layers(packet, layer_name)
        for layer in candidate_layers:
            v = layer.get_field(field_uri)
            if v is not None:
                try:
                    v = _LAYER_FIELDS[field_uri](v)
                    print("[%s = %r] " % (field_uri, v), file=sys.stderr)
                    return v
                except Exception as ex:
                    raise ValueError('can not parse field %s = %r' % (field_uri,
                                                                      (v.get_default_value(), v.raw_value))) from ex

        print("[%s = %s] " % (field_uri, "null"), file=sys.stderr)
        return nullField

    elif is_layer_field_container(field_uri):
        from pktverify.layer_fields_container import LayerFieldsContainer
        return LayerFieldsContainer(packet, field_uri)
    else:
        raise NotImplementedError('Field %s is not valid, please add it to `_LAYER_FIELDS`' % field_uri)
Ejemplo n.º 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)
Ejemplo n.º 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)