parsing of captured KMP traffic#12
Conversation
I'm writing a KMP protocol sniffer, and for that I need a function which looks at the captured communication log, and returns parsed commands/responses.
The input format is the same as what `socat` produces, e.g.:
> 2026/01/24 23:37:36.000562669 length=9 from=29553 to=29561
80 3f 10 01 03 e9 7c d4 0d
< 2026/01/24 23:37:36.000658765 length=1 from=127635 to=127635
40
< 2026/01/24 23:37:36.000667759 length=1 from=127636 to=127636
3f
< 2026/01/24 23:37:36.000676940 length=1 from=127637 to=127637
10
< 2026/01/24 23:37:36.000686033 length=1 from=127638 to=127638
03
< 2026/01/24 23:37:36.000695251 length=1 from=127639 to=127639
e9
< 2026/01/24 23:37:36.000704439 length=1 from=127640 to=127640
33
< 2026/01/24 23:37:36.000713505 length=1 from=127641 to=127641
04
< 2026/01/24 23:37:36.000722680 length=1 from=127642 to=127642
00
< 2026/01/24 23:37:36.000732096 length=1 from=127643 to=127643
04
< 2026/01/24 23:37:36.000741146 length=1 from=127644 to=127644
cf
< 2026/01/24 23:37:36.000750320 length=1 from=127645 to=127645
95
< 2026/01/24 23:37:36.000759528 length=1 from=127646 to=127646
76
< 2026/01/24 23:37:36.000768603 length=1 from=127647 to=127647
5a
< 2026/01/24 23:37:36.000777851 length=1 from=127648 to=127648
1b
< 2026/01/24 23:37:36.000787020 length=1 from=127649 to=127649
bf
< 2026/01/24 23:37:36.000796300 length=1 from=127650 to=127650
0d
The log can be produced by, e.g.:
socat -d -d -x UNIX-CONNECT:path/to/libvirt-serial-pty GOPEN:/dev/real-serial-tty,b1200,rawer,cs8,cstopb=2
The output of that looks like:
>>> GetRegisterRequest(data_raw=b'\x01\x03\xe9', registers=[1001])
<<< GetRegisterResponse(data_raw=b'\x03\xe93\x04\x00\x04\xcf\x95v', registers={1001: RegisterData(id_=1001, unit=51, value=b'\x04\x00\x04\xcf\x95v')})
| 1001 → Fabrication No = 80713078 no unit (number)
|
Thanks for sharing! I really like the idea of a sniffer tool and it makes sense on what you need here. Having that together with the hardware and vendor toolkit can be very powerful! I don't really like the style/layout as-is, but I've got some ideas. What first comes to mind that I would like to see/try:
Let me think about it the coming days and I can rework this if you want. |
|
Yup, feel free to adjust it as you see fit. The class/registry lookup was, I think, inspired by some other projects like (iirc) openswitcher or python-dali, but if you have a more idiomatic alternative, that’s ok with me. I also have some pending patches for the actual log readout which depend on this one. Would you like me to push them as-is, or should I wait? |
Push as-is, I would say. No need to wait. I can imagine there are quite a few iterations while reverse-engineering this, so please don’t spend too much effort upfront on polishing of the structure of commits if that slows you down. I’m happy to do that lifting on my side: picking things apart into bite-sized changes, cleaning up commit history, polishing commit messages, and adding or adjusting documentation where needed. So feel free to push the work in whatever shape is easiest for you. |
|
The full work is pushed at https://github.com/jktjkt/PyKMP/commits/83d85ace2f586049897650a7813a34c095c4a02c, please feel free to slice & dice it as you see fit. |
The first patch adds support for "context-free" decoding of KMP commands and responses, that is, without actually sending the command first. The second command then adds a very simple sniffer which can work with the output of
socat. I used this to analyze traffic captured from the vendor's LogView application which was running in a libvirt/KVM VM. Here's a simple log:And the corresponding output:
I think that you might not take the CLI script as-is, please feel free to convert it to a click interface and a proper entrypoint and what not. I won't be doing that because this one suits my needs well enough.
If you decided to not want the sniffer at all, please consider merging the first commit which implements the actual decoding, I'm OK with carrying the sniffer as an out-of tree patch locally.