Remove all $Id$ from top of file
[metze/wireshark/wip.git] / epan / dissectors / packet-ipsec-tcp.c
index b0235667bf5d8048eacb6ea233a49ab690e5729f..8178594748a9135ee49b5c4601ce19a39dfb1078 100644 (file)
@@ -2,8 +2,6 @@
  * Routines for the disassembly of the proprietary Cisco IPSEC in
  * TCP encapsulation protocol
  *
- * $Id$
- *
  * Copyright 2007 Joerg Mayer (see AUTHORS file)
  *
  * Wireshark - Network traffic analyzer
  * - Currently doesn't handle AH (lack of sample trace)
  */
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
 
 #include <glib.h>
 #include <epan/packet.h>
 #include <epan/prefs.h>
 #include "packet-ndmp.h"
 
+void proto_register_tcpencap(void);
+void proto_reg_handoff_tcpencap(void);
+
 static int hf_tcpencap_unknown = -1;
 static int hf_tcpencap_zero = -1;
 static int hf_tcpencap_seq = -1;
@@ -69,7 +68,11 @@ static const value_string tcpencap_proto_vals[] = {
 
 #define TRAILERLENGTH 16
 #define TCP_CISCO_IPSEC 10000
-static guint global_tcpencap_tcp_port = TCP_CISCO_IPSEC;
+/* Another case of several companies creating protocols and
+   choosing an easy-to-remember port. Playing tonight: Cisco vs NDMP.
+   Since NDMP has officially registered port 10000 with IANA, it should be the default
+*/
+static guint global_tcpencap_tcp_port = 0;
 
 static dissector_handle_t esp_handle;
 static dissector_handle_t udp_handle;
@@ -78,9 +81,6 @@ static dissector_handle_t udp_handle;
 #define TCP_ENCAP_P_UDP 2
 
 
-/* Another case of several companies creating protocols and
-   choosing an easy-to-remember port. Playing tonight: Cisco vs NDMP.
-*/
 static int
 packet_is_tcpencap(tvbuff_t *tvb, packet_info *pinfo, guint32 offset)
 {
@@ -107,7 +107,7 @@ packet_is_tcpencap(tvbuff_t *tvb, packet_info *pinfo, guint32 offset)
  * as supported by the cisco vpn3000 concentrator series
  */
 static int
-dissect_tcpencap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+dissect_tcpencap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
 {
        proto_tree *tcpencap_tree = NULL;
        proto_tree *tcpencap_unknown_tree = NULL;
@@ -119,12 +119,6 @@ dissect_tcpencap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        guint32 offset;
        guint8  protocol;
 
-       /* verify that this looks like a tcpencap packet */
-       if (reported_length <= TRAILERLENGTH + 8 ||
-          !packet_is_tcpencap(tvb, pinfo, reported_length - TRAILERLENGTH) ) {
-               return 0;
-       }
-
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCPENCAP");
        col_clear(pinfo->cinfo, COL_INFO);
 
@@ -170,6 +164,23 @@ dissect_tcpencap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        return tvb_length(tvb);
 }
 
+static gboolean
+dissect_tcpencap_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+{
+       guint32 reported_length = tvb_reported_length(tvb);
+       guint32 length = tvb_length(tvb);
+
+       if (reported_length <= TRAILERLENGTH + 8 ||
+               /* Ensure we have enough bytes for packet_is_tcpencap analysis */
+               (reported_length - length) > (TRAILERLENGTH - 13) ||
+               !packet_is_tcpencap(tvb, pinfo, reported_length - TRAILERLENGTH) ) {
+               return FALSE;
+       }
+
+       dissect_tcpencap(tvb, pinfo, tree, data);
+       return TRUE;
+}
+
 void
 proto_register_tcpencap(void)
 {
@@ -216,16 +227,13 @@ proto_register_tcpencap(void)
 
        module_t *tcpencap_module;
 
-       void proto_reg_handoff_tcpencap(void);
-
        proto_tcpencap = proto_register_protocol(
                "TCP Encapsulation of IPsec Packets", "TCPENCAP", "tcpencap");
        proto_register_field_array(proto_tcpencap, hf, array_length(hf));
        proto_register_subtree_array(ett, array_length(ett));
        tcpencap_module = prefs_register_protocol(proto_tcpencap, proto_reg_handoff_tcpencap);
        prefs_register_uint_preference(tcpencap_module, "tcp.port", "IPSEC TCP Port",
-               "Set the port for IPSEC/ISAKMP messages"
-               "If other than the default of 10000)",
+               "Set the port for IPSEC/ISAKMP messages (typically 10000)",
                10, &global_tcpencap_tcp_port);
 }
 
@@ -234,18 +242,25 @@ proto_reg_handoff_tcpencap(void)
 {
        static dissector_handle_t tcpencap_handle;
        static gboolean initialized = FALSE;
-       static guint tcpencap_tcp_port;
+       static guint tcpencap_tcp_port = 0;
 
        if (!initialized) {
                tcpencap_handle = new_create_dissector_handle(dissect_tcpencap, proto_tcpencap);
                esp_handle = find_dissector("esp");
                udp_handle = find_dissector("udp");
+
+               heur_dissector_add("tcp", dissect_tcpencap_heur, proto_tcpencap);
+
                initialized = TRUE;
-       } else {
+       }
+
+       /* Register TCP port for dissection */
+       if(tcpencap_tcp_port != 0 && tcpencap_tcp_port != global_tcpencap_tcp_port){
                dissector_delete_uint("tcp.port", tcpencap_tcp_port, tcpencap_handle);
        }
 
-       tcpencap_tcp_port = global_tcpencap_tcp_port;
-       dissector_add_uint("tcp.port", global_tcpencap_tcp_port, tcpencap_handle);
+       if(global_tcpencap_tcp_port != 0 && tcpencap_tcp_port != global_tcpencap_tcp_port) {
+               dissector_add_uint("tcp.port", global_tcpencap_tcp_port, tcpencap_handle);
+       }
 }