* 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;
#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;
#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)
{
* 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;
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);
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)
{
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);
}
{
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);
+ }
}