Author: tpot
Date: 2005-03-13 02:57:35 +0000 (Sun, 13 Mar 2005)
New Revision: 246

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=lorikeet&rev=246

Log:
Ethereal plugin to use the output of ndrdump to generate parser output.

Needs a patch to ndrdump to accept data from stdin.

Added:
   trunk/ethereal/ndrdump/
   trunk/ethereal/ndrdump/Makefile
   trunk/ethereal/ndrdump/moduleinfo.c
   trunk/ethereal/ndrdump/moduleinfo.h
   trunk/ethereal/ndrdump/ndrdump.c


Changeset:
Added: trunk/ethereal/ndrdump/Makefile
===================================================================
--- trunk/ethereal/ndrdump/Makefile     2005-03-13 00:34:15 UTC (rev 245)
+++ trunk/ethereal/ndrdump/Makefile     2005-03-13 02:57:35 UTC (rev 246)
@@ -0,0 +1,9 @@
+PLUGIN = ndrdump.so
+
+CFLAGS = -I ../include $(shell pkg-config --cflags glib-2.0) -g
+LDFLAGS= -shared -Wl,--export-dynamic -Wl,-soname -Wl,$(PLUGIN)
+
+OBJS = moduleinfo.o ndrdump.o
+
+ndrdump.so: $(OBJS)
+       $(CC) -o $(PLUGIN) $(OBJS) $(LDFLAGS)

Copied: trunk/ethereal/ndrdump/moduleinfo.c (from rev 244, 
trunk/ethereal/pidl/moduleinfo.c)

Copied: trunk/ethereal/ndrdump/moduleinfo.h (from rev 244, 
trunk/ethereal/pidl/moduleinfo.h)

Added: trunk/ethereal/ndrdump/ndrdump.c
===================================================================
--- trunk/ethereal/ndrdump/ndrdump.c    2005-03-13 00:34:15 UTC (rev 245)
+++ trunk/ethereal/ndrdump/ndrdump.c    2005-03-13 02:57:35 UTC (rev 246)
@@ -0,0 +1,172 @@
+#include "config.h"
+
+#include <gmodule.h>
+#include "plugins/plugin_api.h"
+#include "epan/packet.h"
+#include "epan/dissectors/packet-dcerpc.h"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+static int proto_dcerpc_samr = -1;
+
+static gint ett_dcerpc_samr = -1;
+
+static int hf_samr_opnum = -1;
+
+static e_uuid_t uuid_dcerpc_samr = {
+        0x12345778, 0x1234, 0xabcd,
+        { 0xef, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xac }
+};
+
+static guint16 ver_dcerpc_samr = 1.0;
+
+static void process_data(char *data, int data_len, proto_tree *tree,
+                        tvbuff_t *tvb, int offset)
+{
+       gchar **lines = g_strsplit(data, "\n", 0);
+
+       if (*lines) {           /* skip opcode */
+               proto_tree_add_text(tree, tvb, offset, 0, *lines);
+               lines++;
+       }
+
+       if (*lines) {           /* skip in/out */
+               proto_tree_add_text(tree, tvb, offset, 0, *lines);
+               lines++;
+       }
+
+#define END_TOKEN "pull returned"
+
+       while (*lines) {
+               if (strncmp(*lines, END_TOKEN, strlen(END_TOKEN)) == 0) {
+                       proto_tree_add_text(tree, tvb, offset, 0, 
+                                           *lines + strlen(END_TOKEN));
+                       break;
+               }
+               
+               proto_tree_add_text(tree, tvb, offset, 0, *lines);
+               lines++;
+       }
+}
+
+static int
+ndrdump_dissect_packet(tvbuff_t *tvb, int offset, packet_info *pinfo,
+                      proto_tree *tree, guint8 *drep)
+{
+       dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+       dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
+       int read_pipe[2], write_pipe[2];
+       pid_t child_pid;
+       int status;
+
+       /* Create pipe to ndrdump */
+
+       if (pipe(read_pipe) == -1 || pipe(write_pipe) == -1) {
+               perror("pipe");
+               return 1;
+       }
+
+       if ((child_pid = fork()) == -1) {
+               perror("fork");
+               return 1;
+       }
+
+#define        PARENT_READ     read_pipe[0]
+#define        CHILD_WRITE     read_pipe[1]
+#define CHILD_READ     write_pipe[0]
+#define PARENT_WRITE   write_pipe[1]
+
+       if (child_pid == 0) {
+
+               close(PARENT_WRITE);
+               close(PARENT_READ);
+               
+               dup2(CHILD_READ, fileno(stdin));
+               dup2(CHILD_WRITE, fileno(stdout));
+
+               char *opnum;
+               asprintf(&opnum, "%d", dcv->opnum);
+
+               execlp("ndrdump", "ndrdump", "samr", opnum, 
+                      (di->ptype == PDU_REQ) ? "in" : "out", NULL);
+               exit(1);
+       }
+
+       close(CHILD_READ);
+       close(CHILD_WRITE);
+
+       /* Write data */
+
+       char *tvb_data = (char *)tvb_get_ptr(tvb, offset, -1);
+
+       int result = write(PARENT_WRITE, tvb_data, 
+                          tvb_length_remaining(tvb, offset));
+       
+       close(PARENT_WRITE);
+
+       /* Read ndrdump output */
+
+       char *data = NULL, buf[255];
+       int num_read, data_len = 0;
+
+       while((num_read = read(PARENT_READ, buf, 255)) > 0) {
+               data = realloc(data, data_len + num_read);
+               memcpy(data + data_len, buf, num_read);
+               data_len += num_read;
+       }
+
+       if (data && data_len) 
+               process_data(data, data_len, tree, tvb, offset);
+
+       waitpid(child_pid, &status, 0);
+
+       if (WIFSIGNALED(status)) {
+               g_warning("ndrdump caught signal %d\n", WTERMSIG(status));
+       }
+
+       if (WEXITSTATUS(status) != 0) {
+       }       
+
+       return offset + tvb_length_remaining(tvb, offset);
+}
+
+static dcerpc_sub_dissector ndrdump_dissectors[] = {
+        { 0, "Opnum 0", ndrdump_dissect_packet, ndrdump_dissect_packet },
+        { 1, "Opnum 1", ndrdump_dissect_packet, ndrdump_dissect_packet },
+        { 2, "Opnum 2", ndrdump_dissect_packet, ndrdump_dissect_packet },
+        { 3, "Opnum 3", ndrdump_dissect_packet, ndrdump_dissect_packet },
+        { 4, "Opnum 4", ndrdump_dissect_packet, ndrdump_dissect_packet },
+        {0, NULL, NULL,  NULL }
+};
+
+G_MODULE_EXPORT void
+plugin_reg_handoff(void)
+{
+       dcerpc_init_uuid(proto_dcerpc_samr, ett_dcerpc_samr,
+                        &uuid_dcerpc_samr, ver_dcerpc_samr,
+                        ndrdump_dissectors, hf_samr_opnum);
+}
+
+G_MODULE_EXPORT void
+plugin_init(plugin_address_table_t *pat)
+{
+       static gint *ett[] = {
+               &ett_dcerpc_samr,
+       };
+
+        static hf_register_info hf[] = {
+               { &hf_samr_opnum,
+                 { "Operation", "samr.opnum", FT_UINT16, BASE_DEC, NULL, 0x0, 
"Operation", HFILL }},
+       };
+
+       plugin_address_table_init(pat);
+
+       proto_dcerpc_samr = 
+               proto_register_protocol("ndrdump_samr", "ndrdump_samr", 
+                                       "ndrdump_samr");
+
+       proto_register_subtree_array(ett, array_length(ett));
+
+       proto_register_field_array(proto_dcerpc_samr, hf, array_length(hf));
+}

Reply via email to