Wireshark-dev: Re: [Wireshark-dev] Has anyone created an XDR to Dissector tool?
From: Richard Sharpe <realrichardsharpe@xxxxxxxxx>
Date: Fri, 2 Sep 2016 08:03:27 -0700
For those following along at home, here is a WIP patch against the glibc master version of rpcgen. It builds and runs and generates an incomplete dissector at this stage, but it shows where I think I am headed. I am sure I can do with some feedback even at this early stage, and will likely have something that generates a complete dissector by Monday some time. Of course, whether or not the glibc folks want it is another matter. -- Regards, Richard Sharpe (何以解憂?唯有杜康。--曹操)
From 62fa23aa3571fb6578e1c27b702bde1bcfdfd078 Mon Sep 17 00:00:00 2001
From: Richard Sharpe <rsharpe@xxxxxxxxx>
Date: Fri, 2 Sep 2016 07:59:34 -0700
Subject: [PATCH] WIP of the Wireshark dissector for XDR etc.
---
sunrpc/Makefile | 2 +-
sunrpc/rpc_main.c | 63 ++++++++++++++++++--
sunrpc/rpc_wireshark.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++
sunrpc/rpc_wireshark.h | 10 ++++
4 files changed, 226 insertions(+), 7 deletions(-)
create mode 100644 sunrpc/rpc_wireshark.c
create mode 100644 sunrpc/rpc_wireshark.h
diff --git a/sunrpc/Makefile b/sunrpc/Makefile
index 789ef42..ed5e9f0 100644
--- a/sunrpc/Makefile
+++ b/sunrpc/Makefile
@@ -92,7 +92,7 @@ endif
install-bin := rpcgen
rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \
rpc_scan.o rpc_util.o rpc_svcout.o rpc_clntout.o \
- rpc_tblout.o rpc_sample.o
+ rpc_tblout.o rpc_sample.o rpc_wireshark.o
extra-objs = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs))
others += rpcgen
diff --git a/sunrpc/rpc_main.c b/sunrpc/rpc_main.c
index 0a51e2c..214f6b2 100644
--- a/sunrpc/rpc_main.c
+++ b/sunrpc/rpc_main.c
@@ -49,6 +49,7 @@
#include "rpc_parse.h"
#include "rpc_util.h"
#include "rpc_scan.h"
+#include "rpc_wireshark.h"
#include "proto.h"
#include "../version.h"
@@ -68,6 +69,7 @@ struct commandline
int tflag; /* dispatch Table file */
int Ssflag; /* produce server sample code */
int Scflag; /* produce client sample code */
+ int Wflag; /* Produce a wireshark dissector */
int makefileflag; /* Generate a template Makefile */
const char *infile; /* input module name */
const char *outfile; /* output module name */
@@ -125,6 +127,8 @@ static void svc_output (const char *infile, const char *define,
int extend, const char *outfile);
static void clnt_output (const char *infile, const char *define,
int extend, const char *outfile);
+static void wireshark_output (const char *infile, const char *define,
+ int extend, const char *outfile);
static void mkfile_output (struct commandline *cmd);
static int do_registers (int argc, const char *argv[]);
static void addarg (const char *cp);
@@ -183,7 +187,7 @@ main (int argc, const char *argv[])
usage (stderr, 1);
if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag ||
- cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag)
+ cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag || cmd.Wflag)
{
checkfiles (cmd.infile, cmd.outfile);
}
@@ -205,6 +209,8 @@ main (int argc, const char *argv[])
svc_output (cmd.infile, "-DRPC_SERVER", DONT_EXTEND, cmd.outfile);
else if (cmd.Scflag)
clnt_output (cmd.infile, "-DRPC_CLIENT", DONT_EXTEND, cmd.outfile);
+ else if (cmd.Wflag)
+ wireshark_output (cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile);
else if (cmd.makefileflag)
mkfile_output (&cmd);
else
@@ -364,7 +370,7 @@ open_input (const char *infile, const char *define)
putarg (1, CPPFLAGS);
addarg (define);
if (infile)
- addarg (infile);
+ addarg (infilename);
addarg ((char *) NULL);
close (1);
dup2 (pd[1], 1);
@@ -389,6 +395,7 @@ open_input (const char *infile, const char *define)
perror (infilename);
crash ();
}
+ printf("execvp'ing %s %s %s %s\n", CPP, CPPFLAGS, define, infilename);
}
/* Close the connection to the C-preprocessor and check for successfull
@@ -909,6 +916,47 @@ clnt_output (const char *infile, const char *define, int extend,
close_output (outfilename);
}
+/*
+ * generate wireshark dissector
+ *
+ * Pass over the list of definitions as many times as needed to
+ * generate the following:
+ *
+ * 1. The Preamble containing includes, the program define and the
+ * forward declarations needed.
+ * 2. The ett values
+ * 3. The hf values needed.
+ * 4. The value strings needed.
+ * 5. The structure dissections.
+ * 6. The program dissections.
+ * 7. The epilog containing initialization of the hf and ett values
+ * and etc.
+ *
+ * We can do that because we have all we need in the list.
+ */
+static void
+wireshark_output (const char *infile, const char *define, int extend,
+ const char *outfile)
+{
+ definition *def;
+ const char *outfilename;
+
+ open_input (infile, define);
+ outfilename = extend ? extendfile (infile, outfile) : outfile;
+ open_output (infile, outfilename);
+ checkfiles (infile, outfilename);
+
+ while ((def = get_definition ()) != NULL)
+ {
+
+ }
+
+ write_wireshark();
+
+ close_input ();
+ close_output (outfilename);
+}
+
static const char space[] = " ";
static char *
@@ -1131,9 +1179,9 @@ checkfiles (const char *infile, const char *outfile)
fprintf (stderr,
/* TRANS: the file will not be removed; this is an
TRANS: informative message. */
- _("file `%s' already exists and may be overwritten\n"),
- outfile);
- crash ();
+ _("file `%s' already exists and may be overwritten: %s\n"),
+ outfile, strerror(errno));
+ /*crash ();*/
}
}
}
@@ -1200,6 +1248,7 @@ parseargs (int argc, const char *argv[], struct commandline *cmd)
case 'l':
case 'm':
case 't':
+ case 'W':
if (flag[c])
return 0;
flag[c] = 1;
@@ -1339,6 +1388,7 @@ parseargs (int argc, const char *argv[], struct commandline *cmd)
cmd->tflag = flag['t'];
cmd->Ssflag = flag['S'];
cmd->Scflag = flag['C'];
+ cmd->Wflag = flag['W'];
cmd->makefileflag = flag['M'];
#ifndef _RPC_THREAD_SAFE_
@@ -1377,7 +1427,8 @@ parseargs (int argc, const char *argv[], struct commandline *cmd)
/* check no conflicts with file generation flags */
nflags = cmd->cflag + cmd->hflag + cmd->lflag + cmd->mflag +
- cmd->sflag + cmd->nflag + cmd->tflag + cmd->Ssflag + cmd->Scflag;
+ cmd->sflag + cmd->nflag + cmd->tflag + cmd->Ssflag + cmd->Scflag +
+ cmd->Wflag;
if (nflags == 0)
{
diff --git a/sunrpc/rpc_wireshark.c b/sunrpc/rpc_wireshark.c
new file mode 100644
index 0000000..8677d14
--- /dev/null
+++ b/sunrpc/rpc_wireshark.c
@@ -0,0 +1,158 @@
+/* @(#)rpc_wireshark.c 1.0 16/09/01
+ *
+ * Copyright to be determined ...
+ *
+ * rpc_wireshark.h, Definitions for the generation of a wireshark
+ * dissector in rpcgen
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "rpc/types.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+static void write_wireshark_boilerplate(definition *def);
+
+void write_wireshark(void)
+{
+ list *l;
+ definition *def, *prog = NULL;
+
+ /* Handle the prelude ... */
+ for (l = defined; l != NULL; l = l->next)
+ {
+ def = (definition *) l->val;
+ if (def->def_kind == DEF_PROGRAM)
+ {
+ prog = def;
+ write_wireshark_boilerplate (def);
+ }
+ }
+
+ /*
+ * Now, do all the forward declarations we need.
+ * We need one for each data structure and
+ * one for each function in version defs.
+ *
+ * If there is no program definition, the structure names
+ * do not need qualification as they have to be unique anyway.
+ */
+ for (l = defined; l != NULL; l = l->next)
+ {
+ version_list *v = NULL;
+ proc_list *p = NULL;
+
+ def = (definition *) l->val;
+ switch (def->def_kind) {
+ case DEF_STRUCT:
+ case DEF_UNION:
+ fprintf(fout, "%sdissect_%s(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);\n",
+ (prog ? "static " : ""), def->def_name);
+ break;
+
+ case DEF_PROGRAM:
+ for (v = def->def.pr.versions; v != NULL; v = v->next)
+ {
+ for (p = v->procs; p != NULL; p = p->next)
+ {
+ const char * tplt = "static dissect_%s_%s(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data);\n";
+ fprintf(fout, tplt, p->proc_name, "call");
+ fprintf(fout, tplt, p->proc_name, "reply");
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* Insert the ett fields */
+ fprintf(fout, "\n");
+ if (prog)
+ fprintf(fout, "static gint ett_%s\n", prog->def_name);
+
+ for (l = defined; l != NULL; l = l->next)
+ {
+ version_list *v = NULL;
+ proc_list *p = NULL;
+
+ def = (definition *) l->val;
+ switch (def->def_kind) {
+ case DEF_STRUCT:
+ case DEF_UNION:
+ fprintf(fout, "static gint ett_%s;\n", def->def_name);
+ break;
+
+ /* Not clear we need these */
+ case DEF_PROGRAM:
+ for (v = def->def.pr.versions; v != NULL; v = v->next)
+ {
+ for (p = v->procs; p != NULL; p = p->next)
+ {
+ fprintf(fout, "static gint ett_%s;\n", p->proc_name);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+static void write_wireshark_boilerplate(definition *def)
+{
+ fprintf(fout,
+"/* packet-%s.c\n"
+" * Routines for %s dissection\n"
+" * Copyright %s, %s\n"
+" *\n"
+" * Wireshark - Network traffic analyzer\n"
+" * By Gerald Combs <gerald@xxxxxxxxxxxxx>\n"
+" * Copyright 1998 Gerald Combs\n"
+" *\n"
+" * Portions copied shamelessly from packet-nfs.c\n"
+" *\n"
+" * This program is free software; you can redistribute it and/or\n"
+" * modify it under the terms of the GNU General Public License\n"
+" * as published by the Free Software Foundation; either version 2\n"
+" * of the License, or (at your option) any later version.\n"
+" *\n"
+" * This program is distributed in the hope that it will be useful,\n"
+" * but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+" * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+" * GNU General Public License for more details.\n"
+" *\n"
+" * You should have received a copy of the GNU General Public License\n"
+" * along with this program; if not, write to the Free Software\n"
+" * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n"
+" *\n"
+" * GENERATED BY RPCGEN. DO NOT DO SERIOUS EDITS.\n"
+" */\n"
+"\n"
+"#include \"config.h\"\n"
+"\n"
+"#include <stdio.h>\n"
+"\n"
+"#include <epan/packet.h>\n"
+"#include <epan/prefs.h>\n"
+"#include <epan/exceptions.h>\n"
+"#include <epan/expert.h>\n"
+"#include <epan/to_str.h>\n"
+"#include <epan/decode_as.h>\n"
+"#include <wsutil/crc16.h>\n"
+"#include <wsutil/crc32.h>\n"
+"#include \"packet-rpc.h\"\n"
+"\n"
+"#define %s %s\n\n"
+"void proto_register_%s(void);\n"
+"void proto_reg_handoff_%s(void);\n\n",
+ def->def_name, def->def_name, "2016", "SomeDude",
+ def->def_name, def->def.pr.prog_num,
+ def->def_name, def->def_name);
+
+ /* TODO: Fix the year and pickyp the copyright somehow. */
+}
diff --git a/sunrpc/rpc_wireshark.h b/sunrpc/rpc_wireshark.h
new file mode 100644
index 0000000..713f7cb
--- /dev/null
+++ b/sunrpc/rpc_wireshark.h
@@ -0,0 +1,10 @@
+/* @(#)rpc_wireshark.h 1.0 16/09/01
+ *
+ * Copyright to be determined ...
+ *
+ * rpc_wireshark.h, Definitions for the generation of a wireshark
+ * dissector in rpcgen
+ */
+
+
+void write_wireshark (void);
--
2.4.3
- Follow-Ups:
- Re: [Wireshark-dev] Has anyone created an XDR to Dissector tool?
- From: Richard Sharpe
- Re: [Wireshark-dev] Has anyone created an XDR to Dissector tool?
- References:
- Re: [Wireshark-dev] Has anyone created an XDR to Dissector tool?
- From: Guy Harris
- Re: [Wireshark-dev] Has anyone created an XDR to Dissector tool?
- From: Richard Sharpe
- Re: [Wireshark-dev] Has anyone created an XDR to Dissector tool?
- From: Richard Sharpe
- Re: [Wireshark-dev] Has anyone created an XDR to Dissector tool?
- Prev by Date: Re: [Wireshark-dev] TRANSUM C Port
- Next by Date: Re: [Wireshark-dev] How can I download Wireshark?
- Previous by thread: Re: [Wireshark-dev] Has anyone created an XDR to Dissector tool?
- Next by thread: Re: [Wireshark-dev] Has anyone created an XDR to Dissector tool?
- Index(es):