On Mon, Oct 10, 2011 at 11:54:16AM +0200, Michal Privoznik wrote:
This patch creates basic dissector for Libvirt RPC. The protocol
description can be found here:
http://libvirt.org/internals/rpc.html
Currently, only packet head dissecting is written. To fully dissect
packet payloads a more effort is needed, as each function has
different arguments (in general). However, this can be good
stepping stone for later expansion. Ideally, a script that
will generate this dissector from libvirt RPC file would be written.
---
Okay, this patch obviously belongs to wireshark mailing list,
but before I'll send it there, I guess we should decide if we
want it there. I mean there are 2 modes/ways for wireshark
dissectors:
1) Place it into wireshark repo as many others.
Advantage: wireshark will be shipped with support for libvirt RPC
Disadvantage: wireshark will be shipped with support for libvirt RPC
In other words, if you look at wireshark releases, they are not
as often as ours, so in the end, this dissector will be always one
or more step behind current libvirt. But many users will be able
to use it right after box open.
2) Dissector as plugin
Advantage: we can update it as often as we want
Disadvantage: users needs to install a plugin
Personally, I prefer 2) as libvirt RPC is expanded pretty often,
and I expect this dissector to be used by libvirt developer mainly,
for who installing a plugin into wireshark can't be a real problem :)
Yeah, option 2) is the one I'd like to see us focus on.
As Dave says, if Wireshark want to include the libvirt plugin
themselves too, that's great, but we need to make sure we ship
one that is guarenteed up2date for it to be most useful to us.
+static void
+dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ gint offset = 0;
+ /* Okay, these are magic constants, but
+ * they are just offsets where requested
+ * info is to be found */
+ guint32 prog = tvb_get_ntohl(tvb, 4);
Although all our version numbers are currently '1', we should
still include the version field for completeness.
+ guint32 proc = tvb_get_ntohl(tvb, 12);
+ guint32 type = tvb_get_ntohl(tvb, 16);
+ guint32 serial = tvb_get_ntohl(tvb, 20);
+ guint32 status = tvb_get_ntohl(tvb, 24);
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "Libvirt");
+ col_clear(pinfo->cinfo,COL_INFO);
+ if (prog == REMOTE_PROGRAM)
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Proc=%s ", val_to_str(proc,
remote_procedure_strings, "%d"));
+ else if (prog == QEMU_PROGRAM)
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Proc=%s ", val_to_str(proc,
qemu_procedure_strings, "%d"));
+ else
+ /* unhandeld program */
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Proc=%u ", proc);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, "Type=%s Status=%s Prog=%s
Serial=%u",
+ val_to_str(type, type_strings, "%d"),
+ val_to_str(status, status_strings, "%d"),
+ val_to_str(prog, program_strings, "%x"),
+ serial);
+
+ if (tree) {
+ proto_item *ti = NULL;
+ proto_tree *libvirt_tree = NULL;
+
+ ti = proto_tree_add_item(tree, proto_libvirt, tvb, 0, -1, FALSE);
+ libvirt_tree = proto_item_add_subtree(ti, ett_libvirt);
+ proto_tree_add_item(libvirt_tree, hf_libvirt_length, tvb, offset, 4, FALSE);
offset += 4;
+ proto_tree_add_item(libvirt_tree, hf_libvirt_program, tvb, offset, 4, FALSE);
offset += 4;
+ proto_tree_add_item(libvirt_tree, hf_libvirt_version, tvb, offset, 4, FALSE);
offset += 4;
+ if (prog == REMOTE_PROGRAM)
+ proto_tree_add_item(libvirt_tree, hf_libvirt_procedure, tvb, offset, 4,
FALSE);
+ else if (prog == QEMU_PROGRAM)
+ proto_tree_add_item(libvirt_tree, hf_qemu_procedure, tvb, offset, 4,
FALSE);
+ else
+ /* unhandeld program */
+ proto_tree_add_none_format(libvirt_tree, -1, tvb, offset, 4, "Unknown
proc: %u", proc);
+ offset += 4;
+ proto_tree_add_item(libvirt_tree, hf_libvirt_type, tvb, offset, 4, FALSE);
offset += 4;
+ proto_tree_add_item(libvirt_tree, hf_libvirt_serial, tvb, offset, 4, FALSE);
offset += 4;
+ proto_tree_add_item(libvirt_tree, hf_libvirt_status, tvb, offset, 4, FALSE);
offset += 4;
+ }
+}
+
+static guint32 get_message_len(packet_info *pinfo __attribute__((unused)), tvbuff_t
*tvb, int offset)
+{
+ return tvb_get_ntohl(tvb, offset);
+}
+
+static void
+dissect_libvirt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ /* Another magic const - 4; simply, how much bytes
+ * is needed to tell the length of libvirt packet. */
+ tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 4, get_message_len,
dissect_libvirt_message);
+}
+
+
+void
+proto_register_libvirt(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_libvirt_length,
+ { "length", "libvirt.length",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ { &hf_libvirt_program,
+ { "program", "libvirt.program",
+ FT_UINT32, BASE_HEX,
+ VALS(program_strings), 0x0,
+ NULL, HFILL}
+ },
+ { &hf_libvirt_version,
+ { "version", "libvirt.version",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ { &hf_libvirt_procedure,
+ { "procedure", "libvirt.procedure",
+ FT_INT32, BASE_DEC,
+ VALS(remote_procedure_strings), 0x0,
+ NULL, HFILL}
+ },
+ { &hf_libvirt_type,
+ { "type", "libvirt.type",
+ FT_INT32, BASE_DEC,
+ VALS(type_strings), 0x0,
+ NULL, HFILL}
+ },
+ { &hf_libvirt_serial,
+ { "serial", "libvirt.serial",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL}
+ },
+ { &hf_libvirt_status,
+ { "status", "libvirt.status",
+ FT_INT32, BASE_DEC,
+ VALS(status_strings), 0x0,
+ NULL, HFILL}
+ },
+ { &hf_qemu_procedure,
+ { "procedure", "libvirt.procedure",
+ FT_INT32, BASE_DEC,
+ VALS(qemu_procedure_strings), 0x0,
+ NULL, HFILL}
+ }
+ };
+
+ static gint *ett[] = {
+ &ett_libvirt
+ };
+
+ proto_libvirt = proto_register_protocol (
+ "Libvirt", /* name */
+ "libvirt", /* short name */
+ "libvirt" /* abbrev */
+ );
+
+ proto_register_field_array(proto_libvirt, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+}
+
+void
+proto_reg_handoff_foo(void)
+{
+ static dissector_handle_t libvirt_handle;
+
+ libvirt_handle = create_dissector_handle(dissect_libvirt, proto_libvirt);
+ dissector_add_uint("tcp.port", LIBVIRT_PORT, libvirt_handle);
+}
I'm surprised at just how little code is required todo this !
Daniel
--
|:
http://berrange.com -o-
http://www.flickr.com/photos/dberrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|:
http://entangle-photo.org -o-
http://live.gnome.org/gtk-vnc :|