summaryrefslogtreecommitdiffstats
path: root/fnet/ethereal
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /fnet/ethereal
Publish
Diffstat (limited to 'fnet/ethereal')
-rw-r--r--fnet/ethereal/Makefile.am26
-rw-r--r--fnet/ethereal/Makefile.nmake27
-rw-r--r--fnet/ethereal/moduleinfo.h18
-rw-r--r--fnet/ethereal/packet-fnetrpc.c389
4 files changed, 460 insertions, 0 deletions
diff --git a/fnet/ethereal/Makefile.am b/fnet/ethereal/Makefile.am
new file mode 100644
index 00000000000..7f169f25afa
--- /dev/null
+++ b/fnet/ethereal/Makefile.am
@@ -0,0 +1,26 @@
+# Makefile.am
+# Automake file for plugin
+
+INCLUDES = -I$(top_srcdir)
+
+plugindir = @plugindir@
+
+plugin_LTLIBRARIES = fnetrpc.la
+fnetrpc_la_SOURCES = packet-fnetrpc.c moduleinfo.h
+fnetrpc_la_LDFLAGS = -module -avoid-version
+fnetrpc_la_LIBADD = @PLUGIN_LIBS@
+
+# Libs must be cleared, or else libtool won't create a shared module.
+# If your module needs to be linked against any particular libraries,
+# add them here.
+LIBS =
+
+CLEANFILES = \
+ fnetrpc \
+ *~
+
+MAINTAINERCLEANFILES = \
+ Makefile.in
+
+EXTRA_DIST = \
+ Makefile.nmake
diff --git a/fnet/ethereal/Makefile.nmake b/fnet/ethereal/Makefile.nmake
new file mode 100644
index 00000000000..c743e4c011b
--- /dev/null
+++ b/fnet/ethereal/Makefile.nmake
@@ -0,0 +1,27 @@
+include ..\..\config.nmake
+
+############### no need to modify below this line #########
+
+CFLAGS=/DHAVE_CONFIG_H /I../.. /I../../wiretap $(GLIB_CFLAGS) \
+ /I$(PCAP_DIR)\include -D_U_="" $(LOCAL_CFLAGS)
+
+LDFLAGS = /NOLOGO /INCREMENTAL:no /MACHINE:I386 $(LOCAL_LDFLAGS)
+
+!IFDEF ENABLE_LIBETHEREAL
+LINK_PLUGIN_WITH=..\..\epan\libethereal.lib
+CFLAGS=/DHAVE_WIN32_LIBETHEREAL_LIB /D_NEED_VAR_IMPORT_ $(CFLAGS)
+
+OBJECTS=packet-fnetrpc.obj
+
+fnetrpc.dll fnetrpc.exp fnetrpc.lib : $(OBJECTS) $(LINK_PLUGIN_WITH)
+ link -dll /out:fnetrpc.dll $(LDFLAGS) $(OBJECTS) $(LINK_PLUGIN_WITH) \
+ $(GLIB_LIBS)
+
+!ENDIF
+
+clean:
+ rm -f $(OBJECTS) fnetrpc.dll fnetrpc.exp fnetrpc.lib *.pdb
+
+distclean: clean
+
+maintainer-clean: distclean
diff --git a/fnet/ethereal/moduleinfo.h b/fnet/ethereal/moduleinfo.h
new file mode 100644
index 00000000000..de49ef89a67
--- /dev/null
+++ b/fnet/ethereal/moduleinfo.h
@@ -0,0 +1,18 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+/* Included *after* config.h, in order to re-define these macros */
+
+#ifdef PACKAGE
+#undef PACKAGE
+#endif
+
+/* Name of package */
+#define PACKAGE "fnetrpc"
+
+
+#ifdef VERSION
+#undef VERSION
+#endif
+
+/* Version number of package */
+#define VERSION "0.0.1"
+
diff --git a/fnet/ethereal/packet-fnetrpc.c b/fnet/ethereal/packet-fnetrpc.c
new file mode 100644
index 00000000000..370b5e29e70
--- /dev/null
+++ b/fnet/ethereal/packet-fnetrpc.c
@@ -0,0 +1,389 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+/* packet-fnetrpc.c */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gmodule.h>
+#include <epan/packet.h>
+#include <epan/prefs.h>
+#include <string.h>
+
+/* forward reference */
+void proto_register_fnetrpc();
+void proto_reg_handoff_fnetrpc();
+static void dissect_fnetrpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+
+static void decode_params_bigend(proto_tree *tree, tvbuff_t *tvb, int offset, int len);
+static void decode_params_litend(proto_tree *tree, tvbuff_t *tvb, int offset, int len);
+
+/* Define version if we are not building ethereal statically */
+#ifndef ENABLE_STATIC
+G_MODULE_EXPORT const gchar version[] = "0.0";
+#endif
+
+static int proto_fnetrpc = -1;
+static int global_fnetrpc_port = 10101;
+static dissector_handle_t fnetrpc_handle;
+
+#ifndef ENABLE_STATIC
+G_MODULE_EXPORT void
+plugin_register(void)
+{
+ /* register the new protocol, protocol fields, and subtrees */
+ if (proto_fnetrpc == -1) { /* execute protocol initialization only once */
+ proto_register_fnetrpc();
+ }
+}
+
+G_MODULE_EXPORT void
+plugin_reg_handoff(void){
+ proto_reg_handoff_fnetrpc();
+}
+#endif
+
+#define FRT_LITTLE_ENDIAN_FLAG 0x01
+#define FRT_NOREPLY_FLAG 0x02
+
+static int hf_fnetrpc_packet_type = -1;
+static int hf_fnetrpc_packet_flags = -1;
+static int hf_fnetrpc_packet_len = -1;
+static int hf_fnetrpc_packet_reqid = -1;
+static int hf_fnetrpc_req_method = -1;
+
+static int hf_fnetrpc_typestring = -1;
+static int hf_fnetrpc_val_int32 = -1;
+static int hf_fnetrpc_val_array = -1;
+static int hf_fnetrpc_val_string = -1;
+
+static int hf_fnetrpc_noreply_flag = -1;
+static int hf_fnetrpc_litend_flag = -1;
+
+static gint ett_fnetrpc = -1;
+static gint ett_fnetrpc_params = -1;
+static gint ett_fnetrpc_retval = -1;
+
+static const value_string packettypenames[] = {
+ { 100, "RPC Request" },
+ { 101, "RPC Reply" },
+ { 102, "RPC Error" },
+ { 0, NULL },
+};
+
+static hf_register_info hf[] = {
+ { &hf_fnetrpc_packet_len,
+ { "FRT Packet length", "fnetrpc.packetlen",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }
+ },
+ { &hf_fnetrpc_packet_flags,
+ { "FRT Packet flags", "fnetrpc.packetflags",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ "", HFILL }
+ },
+ { &hf_fnetrpc_packet_type,
+ { "FRT Packet type", "fnetrpc.packettype",
+ FT_UINT16, BASE_HEX, VALS(packettypenames), 0x0,
+ "", HFILL }
+ },
+ { &hf_fnetrpc_noreply_flag,
+ { "FRT noreply flag", "fnetrpc.flags.noreply",
+ FT_BOOLEAN, 8, NULL, FRT_NOREPLY_FLAG,
+ "", HFILL }
+ },
+ { &hf_fnetrpc_litend_flag,
+ { "FRT little-endian flag", "fnetrpc.flags.littleendian",
+ FT_BOOLEAN, 8, NULL, FRT_LITTLE_ENDIAN_FLAG,
+ "", HFILL }
+ },
+ { &hf_fnetrpc_packet_reqid,
+ { "FRT Request id", "fnetrpc.requestid",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }
+ },
+ { &hf_fnetrpc_req_method,
+ { "FRT name of called method", "fnetrpc.request.method",
+ FT_STRING, 0, NULL, 0x0,
+ "", HFILL }
+ },
+
+ { &hf_fnetrpc_typestring,
+ { "FRT value typestring", "fnetrpc.value.typestring",
+ FT_STRING, 0, NULL, 0x0,
+ "", HFILL }
+ },
+ { &hf_fnetrpc_val_int32,
+ { "FRT int32 value", "fnetrpc.value.int32",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }
+ },
+ { &hf_fnetrpc_val_array,
+ { "FRT array length", "fnetrpc.value.array",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "", HFILL }
+ },
+ { &hf_fnetrpc_val_string,
+ { "FRT string value", "fnetrpc.value.string",
+ FT_STRING, 0, NULL, 0x0,
+ "", HFILL }
+ },
+
+};
+
+/* Setup protocol subtree array */
+static gint *ett[] = {
+ &ett_fnetrpc,
+ &ett_fnetrpc_params,
+ &ett_fnetrpc_retval,
+};
+
+
+void
+proto_register_fnetrpc(void)
+{
+ module_t *fnetrpc_module;
+
+ if (proto_fnetrpc == -1) {
+ proto_fnetrpc = proto_register_protocol (
+ "FNET Remote Tools Protocol", /* name */
+ "FRT", /* short name */
+ "frt" /* abbrev */
+ );
+ }
+ fnetrpc_module = prefs_register_protocol(proto_fnetrpc, proto_reg_handoff_fnetrpc);
+
+ proto_register_field_array(proto_fnetrpc, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+}
+
+
+void
+proto_reg_handoff_fnetrpc(void)
+{
+ static int Initialized=FALSE;
+
+ if (!Initialized) {
+ fnetrpc_handle = create_dissector_handle(dissect_fnetrpc, proto_fnetrpc);
+ dissector_add("tcp.port", global_fnetrpc_port, fnetrpc_handle);
+ }
+}
+
+static void
+decode_rpc(int packet_type, proto_tree *tree, tvbuff_t *tvb, int offset, int iplen)
+{
+ int islitend = 0;
+ proto_tree *my_tree = NULL;
+ proto_item *ti = proto_tree_add_item(tree, proto_fnetrpc, tvb, offset, iplen, FALSE);
+
+ proto_item_append_text(ti, ", %s", val_to_str(packet_type, packettypenames, "Unknown type (%d)"));
+
+ my_tree = proto_item_add_subtree(ti, ett_fnetrpc);
+
+ proto_tree_add_item(my_tree, hf_fnetrpc_packet_flags, tvb, offset, 2, FALSE);
+ proto_tree_add_item(my_tree, hf_fnetrpc_noreply_flag, tvb, offset+1, 1, FALSE);
+ proto_tree_add_item(my_tree, hf_fnetrpc_litend_flag, tvb, offset+1, 1, FALSE);
+ proto_tree_add_item(my_tree, hf_fnetrpc_packet_type, tvb, offset+2, 2, FALSE);
+ proto_tree_add_item(my_tree, hf_fnetrpc_packet_reqid, tvb, offset+4, 4, FALSE);
+
+ islitend = (tvb_get_guint8(tvb, offset+1) & FRT_LITTLE_ENDIAN_FLAG);
+
+ iplen -= 8; // consumed as headers
+ offset += 8;
+
+ // fprintf(stderr, "type %d / iplen %d\n", packet_type, iplen);
+ if (packet_type == 101) {
+ proto_tree *retval_tree = NULL;
+ retval_tree = proto_item_add_subtree(my_tree, ett_fnetrpc_retval);
+ if (islitend) {
+ decode_params_litend(retval_tree, tvb, offset, iplen);
+ } else {
+ decode_params_bigend(retval_tree, tvb, offset, iplen);
+ }
+ }
+
+ if (packet_type == 100) {
+ gint slen = 0;
+ int ssz = 0;
+ guint8 buf[256];
+
+ // 4 bytes integer for length of method name
+ if (iplen < 4) return;
+
+ if (islitend) {
+ ssz = tvb_get_letohl(tvb, offset);
+ } else {
+ ssz = tvb_get_ntohl(tvb, offset);
+ }
+ offset += 4;
+ iplen -= 4;
+
+ // fprintf(stderr, "ssz %d\n", ssz);
+
+ // ssz bytes of method name
+ if (iplen >= ssz) {
+ proto_tree *param_tree = NULL;
+
+ // max 255 bytes displayed
+ slen = tvb_get_nstringz0(tvb, offset, 1 + ( ssz > 255 ? 255 : ssz), buf);
+ proto_tree_add_string(my_tree, hf_fnetrpc_req_method, tvb, offset, ssz, buf);
+ offset += ssz;
+ iplen -= ssz;
+ // fprintf(stderr, "slen %d\n", slen);
+
+ proto_item_append_text(ti, ": %s()", buf);
+
+ param_tree = proto_item_add_subtree(my_tree, ett_fnetrpc_params);
+ if (islitend) {
+ decode_params_litend(param_tree, tvb, offset, iplen);
+ } else {
+ decode_params_bigend(param_tree, tvb, offset, iplen);
+ }
+ }
+ }
+}
+
+static void
+dissect_fnetrpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ int plen = tvb_length(tvb);
+ guint16 packet_type = 0;
+
+ /* if displaying protocol name, set to our name */
+ if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "FRT");
+ }
+ /* Clear out stuff in the info column */
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_clear(pinfo->cinfo,COL_INFO);
+ }
+
+ if (plen < 12) {
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_add_str(pinfo->cinfo, COL_INFO, "Too short packet");
+ }
+ return;
+ }
+
+ packet_type = tvb_get_ntohs(tvb, 6);
+
+ /* Clear out stuff in the info column */
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_clear(pinfo->cinfo,COL_INFO);
+ col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
+ val_to_str(packet_type, packettypenames,
+ "Unknown type (%d)"));
+ }
+
+ if (tree) { /* being asked for details */
+ int offset = 0;
+
+ while (offset + 4 < plen) {
+ int iplen = tvb_get_ntohl(tvb, offset);
+ proto_item *itlen =
+ proto_tree_add_item(tree, hf_fnetrpc_packet_len, tvb, offset, 4, FALSE);
+
+ offset += 4;
+ if (offset + iplen > plen) {
+ proto_item_append_text(itlen, " (%d bytes missing)", offset + iplen - plen);
+ iplen = plen - offset;
+ }
+ if (iplen < 8)
+ break;
+
+ decode_rpc(packet_type, tree, tvb, offset, iplen);
+ // if (offset + iplen < plen) {
+ // fprintf(stderr, "decoded %d bytes at %d, of total %d\n", iplen, offset, plen);;
+ // }
+ offset += iplen;
+
+ }
+ if (plen > offset) {
+ proto_item *extra = proto_tree_add_item(tree, hf_fnetrpc_packet_len, tvb, offset, plen - offset, FALSE);
+ proto_item_append_text(extra, " (%d undecoded bytes)", plen - offset);
+ }
+ }
+}
+
+void
+decode_params_litend(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
+{
+ proto_item *tsit = NULL;
+ int i;
+ int ssz;
+ guint8 typestring[256];
+ guint8 buf[256];
+ gint slen = 0;
+
+ if (len < 4) return;
+
+ ssz = tvb_get_letohl(tvb, offset);
+
+ offset += 4;
+ len -= 4;
+ if (ssz > len) return;
+
+ slen = tvb_get_nstringz0(tvb, offset, 1 + ( ssz > 255 ? 255 : ssz), typestring);
+ tsit= proto_tree_add_string(tree, hf_fnetrpc_typestring, tvb, offset, ssz, typestring);
+
+ offset += ssz;
+ len -= ssz;
+
+ for (i = 0; i < (int)strlen(typestring); i++) {
+ int j = 0;
+ int narr = 0;
+
+ switch (typestring[i]) {
+
+ case 'i':
+ if (len < 4) return;
+ proto_tree_add_item(tree, hf_fnetrpc_val_int32, tvb, offset, 4, TRUE);
+ offset += 4;
+ len -= 4;
+ break;
+
+ case 's':
+ if (len < 4) return;
+ ssz = tvb_get_letohl(tvb, offset);
+ offset += 4;
+ len -= 4;
+ if (ssz > len) return;
+ slen = tvb_get_nstringz0(tvb, offset, 1 + ( ssz > 255 ? 255 : ssz), buf);
+ proto_tree_add_string(tree, hf_fnetrpc_val_string, tvb, offset, ssz, buf);
+ offset += ssz;
+ len -= ssz;
+ break;
+
+ case 'S':
+ if (len < 4) return;
+ narr = tvb_get_letohl(tvb, offset);
+ proto_tree_add_item(tree, hf_fnetrpc_val_array, tvb, offset, 4, TRUE);
+ offset += 4;
+ len -= 4;
+ for (j = 0; j < narr; j++) {
+ if (len < 4) return;
+ ssz = tvb_get_letohl(tvb, offset);
+ offset += 4;
+ len -= 4;
+ if (ssz > len) return;
+ slen = tvb_get_nstringz0(tvb, offset, 1 + ( ssz > 255 ? 255 : ssz), buf);
+ proto_tree_add_string(tree, hf_fnetrpc_val_string, tvb, offset, ssz, buf);
+ offset += ssz;
+ len -= ssz;
+ }
+ break;
+
+ default:
+ proto_item_append_text(tsit, " unknown value type '%c' (0x%02x)",
+ (int)typestring[i], (int)typestring[i]);
+ }
+ }
+}
+
+
+
+void
+decode_params_bigend(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
+{
+ abort();
+}