Ethereal-dev: Re: [Ethereal-dev] New dissector for Red Hat/Fedora netdump
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Eric Paris <eparis@xxxxxxxxxxxxxx>
Date: Mon, 25 Apr 2005 14:14:03 -0400
Guess I'm supposed to give an svn diff, so here it is. Eric On Mon, 2005-04-25 at 14:10 -0400, Eric Paris wrote: > Attached is a file packet-netdump.c which should dissect netdump > packets. Netdump is the protocol used to send crash information like > the stack and memory contents to a netdump server when a linux machine > panics/opps. > > This is my first attempt at a dissector, so please let me have any > comments on any problems you see. > > Netdump uses port UDP 6666 which is also defined by packet-sigcomp.c. I > don't have any traces which result in parsing these type of packets so > I'm not sure how to make sure it is still picking those up. I found > that just registering port 6666 with dissector_add caused the sigcomp to > still get tried and my netdump to never get tried. So I registered with > heur_dissector_add and it started trying my dissector second. So I can > only assume that it will get those others. I'm not sure what the right > way is to do this. Please comment if this was not right or if there is > a better way. > > I have a netdump capture with netdump traffic but its about 40 megs long > (dumping memory does generate a lot of traffic), please let me know if > access to this is needed. > > Eric > _______________________________________________ > Ethereal-dev mailing list > Ethereal-dev@xxxxxxxxxxxx > http://www.ethereal.com/mailman/listinfo/ethereal-dev
Index: epan/dissectors/Makefile.common
===================================================================
--- epan/dissectors/Makefile.common (revision 14182)
+++ epan/dissectors/Makefile.common (working copy)
@@ -402,6 +402,7 @@
packet-ndmp.c \
packet-ndps.c \
packet-netbios.c \
+ packet-netdump.c \
packet-netflow.c \
packet-netsync.c \
packet-nettl.c \
Index: epan/dissectors/packet-netdump.c
===================================================================
--- epan/dissectors/packet-netdump.c (revision 0)
+++ epan/dissectors/packet-netdump.c (revision 0)
@@ -0,0 +1,323 @@
+/* packet-netdump.c
+ *
+ * Routines for netdump dissection. Netdump is the crash dump
+ * protocol used by Red Hat to write kernel stack trace and
+ * memory contents to a network sever during an opps or panic
+ *
+ * Copyright 2000, Eric_Paris <ethereal-netdump@xxxxxxxxxxxxxx>
+ *
+ * $Id: README.developer 12979 2005-01-07 11:59:05Z guy $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <address.h>
+#include <epan/packet.h>
+#include <epan/conversation.h>
+
+#define UDP_PORT_NETDUMP 6666
+
+static int proto_netdump = -1;
+static int hf_netdump_magicnumber = -1;
+static int hf_netdump_nr = -1;
+static int hf_netdump_command = -1;
+static int hf_netdump_from = -1;
+static int hf_netdump_to = -1;
+static int hf_netdump_code = -1;
+static int hf_netdump_info = -1;
+static int hf_netdump_version = -1;
+
+static gint ett_netdump = -1;
+
+static dissector_handle_t netdump_handle;
+
+enum netdump_commands
+{
+ COMM_NONE = 0,
+ COMM_SEND_MEM = 1,
+ COMM_EXIT = 2,
+ COMM_REBOOT = 3,
+ COMM_HELLO = 4,
+ COMM_GET_NR_PAGES = 5,
+ COMM_GET_PAGE_SIZE = 6,
+ COMM_START_NETDUMP_ACK = 7,
+ COMM_GET_REGS = 8,
+ COMM_SHOW_STATE = 9
+};
+
+static const value_string netdump_command_vals[] = {
+ {COMM_NONE, "COMM_NONE, Unknown to Author"},
+ {COMM_SEND_MEM, "COMM_SEND_MEM, Request to Send Memory"},
+ {COMM_EXIT, "COMM_EXIT, Unknown to Author"},
+ {COMM_REBOOT, "COMM_REBOOT, Request to Reboot Client"},
+ {COMM_HELLO, "COMM_HELLO, Hello Message"},
+ {COMM_GET_NR_PAGES, "COMM_GET_NR_PAGES, Request Number of Pages on Client"},
+ {COMM_GET_PAGE_SIZE, "COMM_GET_PAGE_SIZE, Request the Size of a Page"},
+ {COMM_START_NETDUMP_ACK,
+ "COMM_START_NETDUMP_ACK, Server Responce to REPLY_START_NETDUMP"},
+ {COMM_GET_REGS, "COMM_GET_REGS, Request for All Registers"},
+ {COMM_SHOW_STATE, "COMM_SHOW_STATE, Request to Show Client State"}
+};
+
+enum netdump_replies
+{
+ REPLY_NONE = 0,
+ REPLY_ERROR = 1,
+ REPLY_LOG = 2,
+ REPLY_MEM = 3,
+ REPLY_RESERVED = 4,
+ REPLY_HELLO = 5,
+ REPLY_NR_PAGES = 6,
+ REPLY_PAGE_SIZE = 7,
+ REPLY_START_NETDUMP = 8,
+ REPLY_END_NETDUMP = 9,
+ REPLY_REGS = 10,
+ REPLY_MAGIC = 11,
+ REPLY_SHOW_STATE = 12
+};
+
+static const value_string netdump_reply_vals[] = {
+ {REPLY_NONE, " REPLY_NONE, Unknown to Author"},
+ {REPLY_ERROR, "REPLY_ERROR, Error"},
+ {REPLY_LOG, "REPLY_LOG, Log Dump"},
+ {REPLY_MEM, "REPLY_MEM, Memory Dump"},
+ {REPLY_RESERVED, "REPLY_RESERVED, Unknown to Author"},
+ {REPLY_HELLO,
+ "REPLY_HELLO, Client Responce to COMM_HELLO (complete handshake)"},
+ {REPLY_NR_PAGES, "REPLY_NR_PAGES, Client Number of Pages"},
+ {REPLY_PAGE_SIZE, "REPLY_PAGE_SIZE, Client Page Size"},
+ {REPLY_START_NETDUMP, "REPLY_START_NETDUMP, Request to Start a Netdump"},
+ {REPLY_END_NETDUMP, "REPLY_END_NETDUMP, Unknown to Author"},
+ {REPLY_REGS, "REPLY_REGS, Client Registers"},
+ {REPLY_MAGIC, "REPLY_MAGIC, Magic Number"},
+ {REPLY_SHOW_STATE, "REPLY_SHOW_STATE, Client State"}
+};
+
+struct netdump_conversation_data_t
+{
+ address client;
+ address server;
+};
+
+/* Code to actually dissect the packets */
+static int
+dissect_netdump (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
+{
+
+/* Set up structures needed to add the protocol subtree and manage it */
+ proto_item *ti;
+ proto_tree *netdump_tree;
+ conversation_t *conversation;
+ struct netdump_conversation_data_t *netdump_conversation_data = NULL;
+
+
+ /*
+ * we are not netdump if talking to syslog, that is actually console log and should
+ * be parsed as a standard syslog message
+ */
+ if (pinfo->destport == 514)
+ return 0;
+
+ /* hopefully this will make the conversation match exactly */
+ conversation =
+ find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst, PT_UDP,
+ pinfo->srcport, pinfo->destport, 0);
+ if (conversation == NULL)
+ {
+ /*
+ * The conversation is created matching exactly on the source/dest
+ * address/port. That way we won't accidentally match on other
+ * messages.
+ */
+ guint options = 0;
+ conversation =
+ conversation_new (pinfo->fd->num, &pinfo->src, &pinfo->dst, PT_UDP,
+ pinfo->srcport, pinfo->destport, options);
+ conversation_set_dissector (conversation, netdump_handle);
+ netdump_conversation_data =
+ malloc (sizeof (struct netdump_conversation_data_t));
+ COPY_ADDRESS (&(netdump_conversation_data->client), &(pinfo->net_src));
+ COPY_ADDRESS (&(netdump_conversation_data->server), &(pinfo->net_dst));
+ conversation_add_proto_data (conversation, proto_netdump,
+ netdump_conversation_data);
+ }
+ else
+ {
+ netdump_conversation_data =
+ conversation_get_proto_data (conversation, proto_netdump);
+ }
+
+/* Make entries in Protocol column and Info column on summary display */
+ if (check_col (pinfo->cinfo, COL_PROTOCOL))
+ col_set_str (pinfo->cinfo, COL_PROTOCOL, "NETDUMP");
+
+ if (check_col (pinfo->cinfo, COL_INFO))
+ col_clear (pinfo->cinfo, COL_INFO);
+
+ if (check_col (pinfo->cinfo, COL_INFO))
+ col_add_fstr (pinfo->cinfo, COL_INFO, "Net Dump");
+
+ if (tree)
+ {
+ gint offset = 0;
+ guint16 bytes_remaining = 0;
+
+/* create display subtree for the protocol */
+ ti = proto_tree_add_item (tree, proto_netdump, tvb, 0, -1, FALSE);
+
+ netdump_tree = proto_item_add_subtree (ti, ett_netdump);
+
+ bytes_remaining = tvb_reported_length_remaining (tvb, offset);
+/*
+ * choose which info to display. we pick server/client based on who initiated
+ * the conversions. The initiator information should be stored in the
+ * netdump_conversation_data->server field
+ */
+ if (ADDRESSES_EQUAL (&pinfo->src, &netdump_conversation_data->server))
+ {
+ proto_tree_add_item (netdump_tree,
+ hf_netdump_magicnumber, tvb, offset, 8, FALSE);
+ offset += 8;
+
+ proto_tree_add_item (netdump_tree,
+ hf_netdump_nr, tvb, offset, 4, FALSE);
+ offset += 4;
+
+ proto_tree_add_item (netdump_tree,
+ hf_netdump_command, tvb, offset, 4, FALSE);
+ offset += 4;
+
+ proto_tree_add_item (netdump_tree,
+ hf_netdump_from, tvb, offset, 4, FALSE);
+ offset += 4;
+
+ proto_tree_add_item (netdump_tree,
+ hf_netdump_to, tvb, offset, 4, FALSE);
+ offset += 4;
+ }
+ else
+ {
+
+ proto_tree_add_item (netdump_tree,
+ hf_netdump_version, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item (netdump_tree,
+ hf_netdump_nr, tvb, offset, 4, FALSE);
+ offset += 4;
+
+ proto_tree_add_item (netdump_tree,
+ hf_netdump_code, tvb, offset, 4, FALSE);
+ offset += 4;
+
+ proto_tree_add_item (netdump_tree,
+ hf_netdump_info, tvb, offset, 4, FALSE);
+ offset += 4;
+
+ bytes_remaining = tvb_reported_length_remaining (tvb, offset);
+ if (bytes_remaining)
+ proto_tree_add_text (netdump_tree, tvb, offset, -1,
+ "Data (%d bytes)",
+ tvb_reported_length_remaining (tvb, offset));
+ }
+ return tvb_length (tvb);
+ }
+}
+
+static gboolean
+dissect_netdump_heur (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
+{
+ return dissect_netdump (tvb, pinfo, tree);
+}
+
+/* Register the protocol with Ethereal */
+
+void
+proto_register_netdump (void)
+{
+ static hf_register_info hf[] = {
+ {&hf_netdump_magicnumber,
+ {"magicnumber", "netdump.magicnumber",
+ FT_UINT64, BASE_HEX, NULL, 0x0,
+ "Magic Number", HFILL}
+ },
+ {&hf_netdump_nr,
+ {"nr", "netdump.nr",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "nr Number", HFILL}
+ },
+ {&hf_netdump_command,
+ {"command", "netdump.command",
+ FT_UINT32, BASE_DEC, VALS (netdump_command_vals), 0x0,
+ "Command", HFILL}
+ },
+ {&hf_netdump_from,
+ {"from", "netdump.from",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ "From", HFILL}
+ },
+ {&hf_netdump_to,
+ {"to", "netdump.to",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ "To", HFILL}
+ },
+ {&hf_netdump_version,
+ {"version", "netdump.version",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "Effective Version", HFILL}
+ },
+ {&hf_netdump_code,
+ {"code", "netdump.code",
+ FT_UINT32, BASE_DEC, VALS (netdump_reply_vals), 0x0,
+ "Code", HFILL}
+ },
+ {&hf_netdump_info,
+ {"info", "netdump.info",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "Info", HFILL}
+ },
+ };
+
+ static gint *ett[] = {
+ &ett_netdump,
+ };
+
+ proto_netdump = proto_register_protocol ("Net Dump", "NetDump", "netdump");
+ proto_register_field_array (proto_netdump, hf, array_length (hf));
+ proto_register_subtree_array (ett, array_length (ett));
+ netdump_handle = new_create_dissector_handle (dissect_netdump,
+ proto_netdump);
+}
+
+void
+proto_reg_handoff_netdump (void)
+{
+ dissector_add ("udp.port", UDP_PORT_NETDUMP, netdump_handle);
+ heur_dissector_add ("udp", dissect_netdump_heur, proto_netdump);
+}
- Follow-Ups:
- [Ethereal-dev] Re: New dissector for Red Hat/Fedora netdump
- From: ronnie sahlberg
- [Ethereal-dev] Re: New dissector for Red Hat/Fedora netdump
- References:
- [Ethereal-dev] New dissector for Red Hat/Fedora netdump
- From: Eric Paris
- [Ethereal-dev] New dissector for Red Hat/Fedora netdump
- Prev by Date: [Ethereal-dev] Administrivia: mailing list changes
- Next by Date: [Ethereal-dev] Buildbot crash output
- Previous by thread: [Ethereal-dev] New dissector for Red Hat/Fedora netdump
- Next by thread: [Ethereal-dev] Re: New dissector for Red Hat/Fedora netdump
- Index(es):





