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):