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