aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-lsd.c
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2016-10-09 20:01:45 -0400
committerMichael Mann <mmann78@netscape.net>2016-10-11 20:34:04 +0000
commit7cef0cb93cc44ed02cd68caa79d3d97173b0edfe (patch)
tree0fe688ba6dcbd680c882e6f5c58621d8373d070d /epan/dissectors/packet-lsd.c
parent53c20dd179ca60a9cf7bdfffe0af8c1a9b5c1f8b (diff)
Add Local Service Discovery (LSD) protocol
Bug: 12985 Change-Id: Iceacd3d122337091380d56bd7fa9875bf7cb4d47 Reviewed-on: https://code.wireshark.org/review/18134 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/dissectors/packet-lsd.c')
-rw-r--r--epan/dissectors/packet-lsd.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/epan/dissectors/packet-lsd.c b/epan/dissectors/packet-lsd.c
new file mode 100644
index 0000000000..f8a667b2f8
--- /dev/null
+++ b/epan/dissectors/packet-lsd.c
@@ -0,0 +1,207 @@
+/* packet-lsd.c
+ * Local Service Discovery packet dissector
+ *
+ * From http://bittorrent.org/beps/bep_0014.html
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <epan/packet.h>
+#include <epan/expert.h>
+#include <wsutil/strtoi.h>
+
+void proto_register_lsd(void);
+void proto_reg_handoff_lsd(void);
+
+#define LSD_MULTICAST_ADDRESS 0xEFC0988F /* 239.192.152.143 */
+#define LSD_PORT 6771
+
+static int proto_lsd = -1;
+static int hf_lsd_header = -1;
+static int hf_lsd_host = -1;
+static int hf_lsd_port = -1;
+static int hf_lsd_infohash = -1;
+
+static gint ett_lsd = -1;
+
+static expert_field ei_lsd_field = EI_INIT;
+
+static gboolean
+parse_string_field(proto_tree *tree, int hf, packet_info *pinfo, tvbuff_t *tvb, int offset, int* next_offset, int* linelen)
+{
+ guint8 *str;
+ header_field_info* hf_info = proto_registrar_get_nth(hf);
+ gchar **field_and_value;
+ proto_item* ti;
+ gchar *p;
+
+ *linelen = tvb_find_line_end(tvb, offset, -1, next_offset, FALSE);
+ if (*linelen < 0)
+ return FALSE;
+
+ str = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, *linelen, ENC_ASCII);
+ if (g_ascii_strncasecmp(str, hf_info->name, strlen(hf_info->name)) == 0)
+ {
+ field_and_value = wmem_strsplit(wmem_packet_scope(), str, ":", 1);
+ p = field_and_value[1];
+ while(g_ascii_isspace(*p))
+ p++;
+ proto_tree_add_string(tree, hf, tvb, offset, *linelen, p);
+ }
+ else
+ {
+ ti = proto_tree_add_string_format(tree, hf, tvb, offset, *linelen, str, "%s", str);
+ expert_add_info_format(pinfo, ti, &ei_lsd_field, "%s field malformed", hf_info->name);
+ }
+
+ return TRUE;
+}
+
+static int
+dissect_lsd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ proto_item *ti = NULL;
+ proto_tree *lsd_tree;
+ int offset = 0, next_offset = 0, linelen;
+ guint8 *str;
+ gchar **field_and_value;
+ guint16 port;
+ gboolean valid;
+
+ linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
+ if (linelen < 0)
+ return 0;
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "LSD");
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ /* Create display subtree for the protocol */
+ ti = proto_tree_add_item(tree, proto_lsd, tvb, 0, -1, ENC_NA);
+ lsd_tree = proto_item_add_subtree(ti, ett_lsd);
+
+ proto_tree_add_item(lsd_tree, hf_lsd_header, tvb, offset, linelen, ENC_ASCII|ENC_NA);
+
+ offset = next_offset;
+ if (!parse_string_field(lsd_tree, hf_lsd_host, pinfo, tvb, offset, &next_offset, &linelen))
+ return offset+linelen;
+
+ offset = next_offset;
+ linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
+ if (linelen < 0)
+ return offset+linelen;
+ str = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, linelen, ENC_ASCII);
+ if (g_ascii_strncasecmp(str, "Port", strlen("Port")) == 0)
+ {
+ field_and_value = wmem_strsplit(wmem_packet_scope(), str, ":", 1);
+ valid = ws_strtou16(field_and_value[1], NULL, &port);
+ ti = proto_tree_add_uint(lsd_tree, hf_lsd_port, tvb, offset, linelen, port);
+ if (!valid)
+ {
+ expert_add_info_format(pinfo, ti, &ei_lsd_field, "Port value malformed");
+ }
+ }
+ else
+ {
+ ti = proto_tree_add_uint(lsd_tree, hf_lsd_port, tvb, offset, 0, 0xFFFF);
+ expert_add_info_format(pinfo, ti, &ei_lsd_field, "Port field malformed");
+ }
+ proto_item_set_len(ti, linelen);
+
+ offset = next_offset;
+ if (!parse_string_field(lsd_tree, hf_lsd_infohash, pinfo, tvb, offset, &next_offset, &linelen))
+ return offset+linelen;
+
+ return tvb_captured_length(tvb);
+}
+
+static gboolean
+dissect_lsd_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+ if (pinfo->dst.type != AT_IPv4)
+ return FALSE;
+
+ if (g_ntohl((*((const guint32 *)pinfo->dst.data))) != LSD_MULTICAST_ADDRESS)
+ return FALSE;
+
+ if (pinfo->destport != LSD_PORT)
+ return FALSE;
+
+ return (dissect_lsd(tvb, pinfo, tree, data) != 0);
+}
+
+void
+proto_register_lsd(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_lsd_header,
+ { "Header", "lsd.header",
+ FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
+ },
+ { &hf_lsd_host,
+ { "Host", "lsd.host",
+ FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
+ },
+ { &hf_lsd_port,
+ { "Port", "lsd.port",
+ FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
+ },
+ { &hf_lsd_infohash,
+ { "Infohash", "lsd.infohash",
+ FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
+ },
+ };
+
+ static gint *ett[] = {
+ &ett_lsd,
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_lsd_field, { "lsd.malformed_field", PI_MALFORMED, PI_ERROR, "Malformed LDS field", EXPFILL }},
+ };
+
+ expert_module_t* expert_lsd;
+
+ proto_lsd = proto_register_protocol("Local Service Discovery", "LSD", "lsd");
+
+ proto_register_field_array(proto_lsd, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+ expert_lsd = expert_register_protocol(proto_lsd);
+ expert_register_field_array(expert_lsd, ei, array_length(ei));
+}
+
+void
+proto_reg_handoff_lsd(void)
+{
+ heur_dissector_add( "udp", dissect_lsd_heur, "LSD over UDP", "lsd_udp", proto_lsd, HEURISTIC_ENABLE);
+}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local Variables:
+ * c-basic-offset: 2
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=2 tabstop=8 expandtab:
+ * :indentSize=2:tabSize=8:noTabs=true:
+ */