almost...
authorStefan Metzmacher <metze@samba.org>
Fri, 24 Nov 2017 16:26:45 +0000 (17:26 +0100)
committerStefan Metzmacher <metze@samba.org>
Sun, 20 Jan 2019 22:14:58 +0000 (23:14 +0100)
Change-Id: I27490e60a7d9f8db68dc3364b423b1837ff4d797

epan/dissectors/packet-nmf.c

index 08e28b8..44710e3 100644 (file)
@@ -34,6 +34,9 @@
 void proto_register_nmf(void);
 void proto_reg_handoff_nmf(void);
 
+static dissector_handle_t gssapi_handle;
+static dissector_handle_t gssapi_wrap_handle;
+
 static int proto_nmf = -1;
 
 static gint ett_nmf = -1;
@@ -48,6 +51,9 @@ static int hf_nmf_via_value = -1;
 static int hf_nmf_known_mode_value = -1;
 static int hf_nmf_upgrade_length = -1;
 static int hf_nmf_upgrade_protocol = -1;
+static int hf_nmf_negotiate_type = -1;
+static int hf_nmf_negotiate_length = -1;
+static int hf_nmf_protect_length = -1;
 
 static gboolean nmf_reassemble = TRUE;
 
@@ -106,6 +112,7 @@ static const value_string known_mode_values[] = {
 
 typedef struct nmf_conv_info_t {
        guint32 fnum_upgraded;
+       guint32 fnum_negotiated;
 } nmf_conv_info_t;
 
 static int
@@ -256,8 +263,38 @@ nmf_get_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *_info)
        guint32 size = 0;
        int start_offset = offset;
 
+       if (pinfo->fd->num > nmf_info->fnum_negotiated) {
+               guint remaining = tvb_captured_length_remaining(tvb, offset);
+               guint len = 0;
+               guint needed = 0;
+
+               if (remaining < 4) {
+                       return 0;
+               }
+
+               len = tvb_get_guint32(tvb, offset, ENC_LITTLE_ENDIAN);
+               offset += 4;
+
+               needed = 4 + len;
+               return needed;
+       }
+
        if (pinfo->fd->num > nmf_info->fnum_upgraded) {
-               return tvb_captured_length_remaining(tvb, offset);
+               guint remaining = tvb_captured_length_remaining(tvb, offset);
+               guint len = 0;
+               guint needed = 0;
+
+               if (remaining < 5) {
+                       return 0;
+               }
+
+               offset += 3;
+
+               len = tvb_get_guint16(tvb, offset, ENC_BIG_ENDIAN);
+               offset += 2;
+
+               needed = 5 + len;
+               return needed;
        }
 
        record_type = (enum nmf_record_type)tvb_get_guint8(tvb, offset);
@@ -324,16 +361,66 @@ dissect_nmf_pdu(tvbuff_t *tvb, packet_info *pinfo,
 {
        nmf_conv_info_t *nmf_info = (nmf_conv_info_t *)_info;
 
-       if (pinfo->fd->num > nmf_info->fnum_upgraded) {
+       pinfo->fragmented = TRUE;
+
+       if (pinfo->fd->num > nmf_info->fnum_negotiated) {
                proto_item *item = proto_tree_get_parent(tree);
-               guint len = tvb_reported_length(tvb);
+               guint32 len = 0;
+               int offset = 0;
 
+               len = tvb_get_guint32(tvb, offset, ENC_LITTLE_ENDIAN);
+               proto_tree_add_item(tree, hf_nmf_negotiate_length,
+                                   tvb, offset, 4, ENC_LITTLE_ENDIAN);
+               offset += 4;
+
+               col_set_str(pinfo->cinfo, COL_INFO, "NMF Protected");
                col_add_fstr(pinfo->cinfo, COL_INFO,
-                            "Upgraded Packet len: %u (0x%x)",
+                            "Protected Packet len: %u (0x%x)",
                             (unsigned)len, (unsigned)len);
-               proto_item_append_text(item, ", Upgraded Packet len: %u (0x%x)",
+               proto_item_append_text(item, ", Protected Packet len: %u (0x%x)",
                                (unsigned)len, (unsigned)len);
-               return len;
+
+               offset += len;
+               return offset;
+       }
+
+       if (pinfo->fd->num > nmf_info->fnum_upgraded) {
+               proto_item *item = proto_tree_get_parent(tree);
+               guint rlen = tvb_reported_length(tvb);
+               guint16 len = 0;
+               guint8 type;
+               int offset = 0;
+               tvbuff_t *negotiate_tvb = NULL;
+
+               col_set_str(pinfo->cinfo, COL_INFO, "NMF Upgrade");
+
+               type = tvb_get_guint8(tvb, offset);
+               proto_tree_add_item(tree, hf_nmf_negotiate_type,
+                                   tvb, offset, 1, ENC_NA);
+               offset += 1;
+               if (type == 0x14) {
+                       nmf_info->fnum_negotiated = pinfo->fd->num;
+               }
+
+               offset += 2;
+
+               len = tvb_get_guint16(tvb, offset, ENC_BIG_ENDIAN);
+               proto_tree_add_item(tree, hf_nmf_negotiate_length,
+                                   tvb, offset, 2, ENC_BIG_ENDIAN);
+               offset += 2;
+
+               col_add_fstr(pinfo->cinfo, COL_INFO,
+                            "Upgraded Packet rlen: %u (0x%x)",
+                            (unsigned)rlen, (unsigned)rlen);
+               proto_item_append_text(item, ", Upgraded Packet rlen: %u (0x%x) len: %u (0x%x) type: 0x%02x",
+                               (unsigned)rlen, (unsigned)rlen,
+                               (unsigned)len, (unsigned)len,
+                               (unsigned)type);
+               negotiate_tvb = tvb_new_subset_length(tvb, offset, len);
+
+               call_dissector(gssapi_handle, negotiate_tvb, pinfo, tree);
+               offset += len;
+               return offset;
        }
 
        return dissect_nmf_record(tvb, pinfo, nmf_info, tree, 0);
@@ -353,6 +440,7 @@ dissect_nmf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, _U_ void
        if (nmf_info == NULL) {
                nmf_info = wmem_new0(wmem_file_scope(), nmf_conv_info_t);
                nmf_info->fnum_upgraded = 0xffffffff;
+               nmf_info->fnum_negotiated = 0xffffffff;
                conversation_add_proto_data(conv, proto_nmf, nmf_info);
        }
 
@@ -364,10 +452,6 @@ dissect_nmf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, _U_ void
                tree = proto_item_add_subtree(item, ett_nmf);
        }
 
-       if (tree == NULL) {
-               return -1;
-       }
-
        tcp_dissect_pdus(tvb, pinfo, tree, nmf_reassemble,
                         1, /* fixed_length */
                         nmf_get_pdu_len,
@@ -412,6 +496,15 @@ void proto_register_nmf(void)
        { &hf_nmf_upgrade_protocol,
                { "Upgrade Protocol", "nmf.upgrade.protocol",
                FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+       { &hf_nmf_negotiate_type,
+               { "Negotiate Type", "nmf.negotiate.type",
+               FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+       { &hf_nmf_negotiate_length,
+               { "Negotiate Length", "nmf.negotiate.length",
+               FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+       { &hf_nmf_protect_length,
+               { "Protect Length", "nmf.protect.length",
+               FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
        };
        module_t *nmf_module = NULL;
 
@@ -436,4 +529,7 @@ proto_reg_handoff_nmf(void)
 
        nmf_handle = create_dissector_handle(dissect_nmf, proto_nmf);
        dissector_add_uint_with_preference("tcp.port", NMF_PORT, nmf_handle);
+
+       gssapi_handle = find_dissector_add_dependency("gssapi", proto_nmf);
+       gssapi_wrap_handle = find_dissector_add_dependency("gssapi_verf", proto_nmf);
 }