Feature/marine dissect all packet fields#59
Conversation
4cb6a4c to
20c0291
Compare
yehonatanz
left a comment
There was a problem hiding this comment.
Great work here, and in marine-core too.
marine/marine.py
Outdated
| self, | ||
| packet: bytes, | ||
| encapsulation_type: Optional[int] = encap_consts.ENCAP_ETHERNET, | ||
| ) -> dict: |
There was a problem hiding this comment.
Dict[str, WhateverTheValueCanBe]
marine/marine.py
Outdated
| return bool(value.bool_value) | ||
|
|
||
| if value_type == MarinePacketFieldValueType.STR: | ||
| return value.str_value.decode() |
There was a problem hiding this comment.
Specify encoding explicitly please.
Is the encoding identical for fields?
| } | ||
|
|
||
|
|
||
| def test_parse_all_fields_int_value(tcp_packet_fields): |
There was a problem hiding this comment.
From what I've seen, nearly no built-in dissector utilizes float values.
I would remove this value type, and make it fall back to string.
|
Rebase this one too, make each commit atomic, meaningful and blacked |
20c0291 to
4c0415d
Compare
Done |
c4a078e to
9a71adc
Compare
tomlegkov
left a comment
There was a problem hiding this comment.
Very nice feature!
The main thing that worries me here is reducing the amount of consts we duplicate from the C to the Python, so that writing clients in new languages won't be too annoying :)
| def test_parse_all_fields_list_value(tcp_packet_fields): | ||
| ip_addr = tcp_packet_fields["ip"]["ip.addr"] | ||
| assert isinstance(ip_addr, list) | ||
| assert "10.0.0.255" in ip_addr |
There was a problem hiding this comment.
If you know exactly what the list looks like, consider comparing it directly to the list
assert ["10.0.0.255", "21.53.78.255"] == ip_addrThere was a problem hiding this comment.
I cannot know ahead of time the order of the list produced by the dissector, So I though checking it that way would be safer.
There was a problem hiding this comment.
Isn't it always src, dst?
| def test_parse_all_fields_bool_value(tcp_packet_fields): | ||
| tcp_ack_flag = tcp_packet_fields["tcp"]["tcp.flags_tree"]["tcp.flags.ack"] | ||
| assert isinstance(tcp_ack_flag, bool) | ||
| assert tcp_ack_flag |
There was a problem hiding this comment.
For safety, maybe add another assert here for a flag that is 0?
There was a problem hiding this comment.
As in - the bit extracted from the dissector is 0?
Doesn't isn't the assert on line 1052 enough? it would fail if the flag is False.
There was a problem hiding this comment.
I meant checking that a different tcp flag is 0
| } | ||
|
|
||
|
|
||
| def test_parse_all_fields_int_value(tcp_packet_fields): |
marine/marine.py
Outdated
| def _load_child_fields(cls, children): | ||
| child_fields = {} | ||
| for child in children.data[: children.len]: | ||
| name = child.name.decode("ascii") |
There was a problem hiding this comment.
Is it really always ascii? Probably yes, but let's make sure :)
Maybe going for utf-8 is safer?
There was a problem hiding this comment.
Changed to utf-8.
There was a problem hiding this comment.
If this is slow in benchmarks, consider adding a cache :)
marine/marine.py
Outdated
|
|
||
| @classmethod | ||
| def _load_marine_packet(cls, field): | ||
| children = field.children |
| ] | ||
|
|
||
|
|
||
| class MarinePacketFieldValueType: |
There was a problem hiding this comment.
Can you use the enum that is defined in marine.h for this? Similar to how we use MARINE_ALREADY_INITIALIZED_ERROR_CODE for example.
There was a problem hiding this comment.
Sadly, this doesn't seem to be very trivial :(
The value you referenced, MARINE_ALREADY_INITIALIZED_ERROR_CODE is an int const, while marine_value_type is an enum, and I would prefer it to remain that way (separate type, automatic index generation etc).
I didn't find a simple way to expose all values of this enum from the shared library (I even found some resources that outright suggest duplicating the enum), So doing this would most likely be the lesser evil in this situation.
9a71adc to
1aebd7a
Compare
|
|
||
| if value_type == MarinePacketFieldValueType.LIST: | ||
| return [cls._load_field_value(v) for v in value.list_value[:value_len]] | ||
|
|
There was a problem hiding this comment.
Do we want an else here to throw an exception or something?
| def test_parse_all_fields_bool_value(tcp_packet_fields): | ||
| tcp_ack_flag = tcp_packet_fields["tcp"]["tcp.flags_tree"]["tcp.flags.ack"] | ||
| assert isinstance(tcp_ack_flag, bool) | ||
| assert tcp_ack_flag |
There was a problem hiding this comment.
I meant checking that a different tcp flag is 0
d1e7919 to
b854ead
Compare
yehonatanz
left a comment
There was a problem hiding this comment.
Looks good, I had some more notes but nothing serious.
I'm worried about the CI, not running, so when you're done fixing stuff can you please attach a screenshot of the linter and tests pass?
| def test_parse_all_fields_list_value(tcp_packet_fields): | ||
| ip_addr = tcp_packet_fields["ip"]["ip.addr"] | ||
| assert isinstance(ip_addr, list) | ||
| assert "10.0.0.255" in ip_addr |
There was a problem hiding this comment.
Isn't it always src, dst?
| + ip.IP(src_s="10.0.0.255", dst_s="21.53.78.255") | ||
| + tcp.TCP(sport=16424, dport=41799) | ||
| + tcp.TCP( | ||
| sport=16424, dport=41799, flags=0b00010000, body_bytes=tcp_payload |
There was a problem hiding this comment.
There's some tcp.ACK const somewhere in pypacker, use it and remove the comment
marine/marine_pool.py
Outdated
|
|
||
| def parse_all_fields( | ||
| self, packets: List[bytes], encapsulation_type: Optional[int] = None | ||
| ) -> List[Dict[str, Any]]: |
There was a problem hiding this comment.
Can't you use ParsedPacket here too?
marine/marine_pool.py
Outdated
| @classmethod | ||
| def _parse_all_fields( | ||
| cls, packet: bytes, encapsulation_type: Optional[int] = None | ||
| ) -> Dict[str, Any]: |
marine/simple_marine.py
Outdated
|
|
||
| def parse_all_packet_fields( | ||
| packet: bytes, encapsulation_type: Optional[int] = None | ||
| ) -> Dict[str, Any]: |
b854ead to
30f7da3
Compare
30f7da3 to
5bdb79e
Compare
|
@yehonatanz regarding your qusetion about |
Should add
parse_all_fieldstosimple_marineby tomorrow.Please review the rest, as it would just be a small wrapper around
Marine.parse_all_fields.