Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nothing shows in Layer XXX_RAW when calling pretty_print with include_raw=True #587

Open
miaotony opened this issue Aug 19, 2022 · 2 comments
Labels

Comments

@miaotony
Copy link
Contributor

miaotony commented Aug 19, 2022

Describe the bug
No matter use_ek=True, include_raw=True or use_json=True, include_raw=True, nothing shows in Layer XXX_RAW when calling pretty_print.

To Reproduce

import pyshark

def tshark_callback(packet):
    packet.pretty_print()
    # print(packet.__str__())

cap = pyshark.LiveCapture(use_ek=True, include_raw=True, interface='wlan')
cap.set_debug()
cap.apply_on_packets(tshark_callback)

图片

Replace use_ek with use_json, and as the same nothing shows in xxx_raw layer.

图片

Expected behavior
Show the raw hex data in the specific xxx_raw fields.

Versions (please complete the following information):

  • OS: Windows 10
  • pyshark version: v0.5.3
  • tshark version: TShark (Wireshark) 3.6.6 (v3.6.6-0-g7d96674e2a30)

The bug also occurs on Linux (Ubuntu 20.04) with pyshark v0.5.3 and TShark (Wireshark) 3.2.3 (Git v3.2.3 packaged as 3.2.3-1).

@miaotony miaotony added the bug label Aug 19, 2022
@miaotony
Copy link
Contributor Author

sudo tshark -l -n -T ek -x -P -V  -i eth0 -c 1

Using ek mode, tshark return a JSON object which the type of xxx_raw layers (just like frame_raw) is str rather than dict.

图片

However, in the source code the author parses it as dict.

def __init__(self, layer_name, layer_dict):
super().__init__(layer_name)
self._fields_dict = layer_dict

The function pretty_print gets all keys in the dict, and in detail it gets field_names...

def _pretty_print_layer_fields(self, terminal_writer: py.io.TerminalWriter):
for field_name in self.field_names:
field = self.get_field(field_name)
self._pretty_print_field(field_name, field, terminal_writer, indent=1)
def _pretty_print_field(self, field_name, field, terminal_writer, indent=0):
prefix = "\t" * indent
if isinstance(field, EkMultiField):
terminal_writer.write(f"{prefix}{field_name}: ", green=True, bold=True)
if field.value is not None:
terminal_writer.write(str(field.value))
terminal_writer.write(os.linesep)
for subfield in field.subfields:
self._pretty_print_field(subfield, field.get_field(subfield), terminal_writer,
indent=indent + 1)
else:
terminal_writer.write(f"{prefix}{field_name}: ", green=True, bold=True)
terminal_writer.write(f"{field}{os.linesep}")

@property
def field_names(self):
return list({field_name.split("_", 1)[0] for field_name in self.all_field_names})
@property
def all_field_names(self):
"""Gets all field names, including subfields"""
names = set()
for field_name in self._fields_dict:
for prefix in self._get_possible_layer_prefixes():
if field_name.startswith(prefix):
names.add(_remove_ek_prefix(prefix, field_name))
break
return list(names)

The raw layers belong to str type, which have no keys.
So maybe you have to judge the type first before processing it...

It seems that another issue #586 is also caused by this problem.

@chrisawad
Copy link

This is still a problem today. This function that's in packet doesn't work either. The assert checks that FRAME_RAW is in the packet, which it is, but self.frame_raw.value isn't valid.

def get_raw_packet(self) -> bytes:
        assert "FRAME_RAW" in self, "Packet contains no raw data. In order to contains it, " \
                                    "make sure that use_json and include_raw are set to True " \
                                    "in the Capture object"
        raw_packet = b''
        byte_values = [''.join(x) for x in zip(self.frame_raw.value[0::2], self.frame_raw.value[1::2])]
        for value in byte_values:
            raw_packet += binascii.unhexlify(value)
        return raw_packet

I've tried updating the code to put frame_raw into the frame dictionary so that the EkLayer can access it that way, but that didn't work either. There must be some lookup table indicating what the valid fields are.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants