From 2b53a88bf8b9190055c43a9c3e045af7ad39fcf9 Mon Sep 17 00:00:00 2001 From: Gerald Combs Date: Tue, 6 Jul 2004 19:01:32 +0000 Subject: From Dinesh Dutt: - conversation.[ch] - To support not setting port2 on matching a conversation. This is used by protocols such as iSNS in which the client registers a TCP/UDP port with the server for notifications and the server sends notifications to this port from different source ports. - packet-isns.c - Added support for handling zero-length TLVs and ESI & SCN frames (when registering an SCN/ESI port, a conversation dissector is setup). svn path=/trunk/; revision=11320 --- epan/conversation.c | 8 +++--- epan/conversation.h | 4 ++- packet-isns.c | 77 ++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 66 insertions(+), 23 deletions(-) diff --git a/epan/conversation.c b/epan/conversation.c index f5ad54b4f1..96ec73999a 100644 --- a/epan/conversation.c +++ b/epan/conversation.c @@ -1,7 +1,7 @@ /* conversation.c * Routines for building lists of packets that are part of a "conversation" * - * $Id: conversation.c,v 1.24 2004/01/09 00:57:48 guy Exp $ + * $Id: conversation.c,v 1.25 2004/07/06 19:01:31 gerald Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -464,7 +464,7 @@ conversation_new(address *addr1, address *addr2, port_type ptype, new_index++; if (options & NO_ADDR2) { - if (options & NO_PORT2) { + if (options & (NO_PORT2|NO_PORT2_FORCE)) { g_hash_table_insert(conversation_hashtable_no_addr2_or_port2, new_key, conversation); } else { @@ -472,7 +472,7 @@ conversation_new(address *addr1, address *addr2, port_type ptype, new_key, conversation); } } else { - if (options & NO_PORT2) { + if (options & (NO_PORT2|NO_PORT2_FORCE)) { g_hash_table_insert(conversation_hashtable_no_port2, new_key, conversation); } else { @@ -493,7 +493,7 @@ conversation_set_port2(conversation_t *conv, guint32 port) /* * If the port 2 value is not wildcarded, don't set it. */ - if (!(conv->options & NO_PORT2)) + if ((!(conv->options & NO_PORT2)) || (conv->options & NO_PORT2_FORCE)) return; if (conv->options & NO_ADDR2) { diff --git a/epan/conversation.h b/epan/conversation.h index acc16165bb..fedb5d5ffe 100644 --- a/epan/conversation.h +++ b/epan/conversation.h @@ -1,7 +1,7 @@ /* conversation.h * Routines for building lists of packets that are part of a "conversation" * - * $Id: conversation.h,v 1.10 2002/08/28 20:40:44 jmayer Exp $ + * $Id: conversation.h,v 1.11 2004/07/06 19:01:32 gerald Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -31,6 +31,7 @@ */ #define NO_ADDR2 0x01 #define NO_PORT2 0x02 +#define NO_PORT2_FORCE 0x04 /* * Flags to pass to "find_conversation()" to indicate that the address B @@ -38,6 +39,7 @@ */ #define NO_ADDR_B 0x01 #define NO_PORT_B 0x02 +#define NO_PORT_B_FORCE 0x04 #include "packet.h" /* for conversation dissector type */ diff --git a/packet-isns.c b/packet-isns.c index 3bf4d79812..243d9a9808 100644 --- a/packet-isns.c +++ b/packet-isns.c @@ -7,7 +7,7 @@ * Copyright 2003, Elipsan, Gareth Bushell * (c) 2004 Ronnie Sahlberg updates * - * $Id: packet-isns.c,v 1.8 2004/05/27 08:33:22 sahlberg Exp $ + * $Id: packet-isns.c,v 1.9 2004/07/06 19:01:31 gerald Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -51,6 +51,7 @@ #endif #include +#include #include "packet-tcp.h" #include "prefs.h" @@ -61,13 +62,22 @@ #define ISNS_TCP_PORT 3205 #define ISNS_UDP_PORT 3205 +#define ISNS_OTHER_PORT 0 +#define ISNS_ESI_PORT 1 +#define ISNS_SCN_PORT 2 + + +dissector_handle_t isns_tcp_handle; +dissector_handle_t isns_udp_handle; + static gint ett_isns_flags = -1; static gint ett_isns_payload = -1; static gint ett_isns_attribute = -1; static gint ett_isns_port = -1; static gint ett_isns_isnt = -1; -static guint AddAttribute(tvbuff_t *tvb, proto_tree *tree, guint offset, guint16 function_id); +static guint AddAttribute(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree, + guint offset, guint16 function_id); /* Initialize the protocol and registered fields */ static int proto_isns = -1; @@ -740,7 +750,7 @@ dissect_isns_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) while( offset < packet_len ) { - offset = AddAttribute(tvb, tt, offset, function_id); + offset = AddAttribute(pinfo, tvb, tt, offset, function_id); } } } @@ -748,7 +758,6 @@ dissect_isns_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) return; } - static guint get_isns_pdu_len(tvbuff_t *tvb, int offset) { @@ -861,23 +870,46 @@ dissect_isns_attr_integer(tvbuff_t *tvb, guint offset, proto_tree *parent_tree, } static guint -dissect_isns_attr_port(tvbuff_t *tvb, guint offset, proto_tree *parent_tree, int hf_index, guint32 tag, guint32 len) +dissect_isns_attr_port(tvbuff_t *tvb, guint offset, proto_tree *parent_tree, int hf_index, guint32 tag, guint32 len, + guint16 port_type, packet_info *pinfo) { proto_item *tree=NULL; proto_item *item=NULL; guint16 port = tvb_get_ntohs(tvb, offset + 10); - guint16 port_type = tvb_get_ntohs(tvb, offset + 8)&0x01; + guint16 isudp = tvb_get_ntohs(tvb, offset + 8)&0x01; + conversation_t *conversation; if(parent_tree){ - item = proto_tree_add_uint(parent_tree, hf_index, tvb, offset+8, 4, port); - tree = proto_item_add_subtree(item, ett_isns_port); + item = proto_tree_add_uint(parent_tree, hf_index, tvb, offset+8, 4, port); + tree = proto_item_add_subtree(item, ett_isns_port); } - proto_tree_add_boolean(tree, hf_isns_port_type, tvb, offset+8, 2, port_type); + proto_tree_add_boolean(tree, hf_isns_port_type, tvb, offset+8, 2, isudp); proto_tree_add_uint(tree, hf_isns_attr_tag, tvb, offset, 4, tag); proto_tree_add_uint(tree, hf_isns_attr_len, tvb, offset+4, 4, len); + if ((port_type == ISNS_ESI_PORT) || (port_type == ISNS_SCN_PORT)) { + if (isudp) { + conversation = find_conversation (&pinfo->src, &pinfo->dst, PT_UDP, + port, 0, NO_PORT_B); + if (conversation == NULL) { + conversation = conversation_new (&pinfo->src, &pinfo->dst, + PT_UDP, port, 0, NO_PORT2_FORCE); + conversation_set_dissector (conversation, isns_udp_handle); + } + } + else { + conversation = find_conversation (&pinfo->src, &pinfo->dst, PT_TCP, + port, 0, NO_PORT_B); + if (conversation == NULL) { + conversation = conversation_new (&pinfo->src, &pinfo->dst, + PT_TCP, port, 0, NO_PORT2_FORCE); + conversation_set_dissector (conversation, isns_tcp_handle); + } + } + } + return offset+8+len; } @@ -1018,7 +1050,8 @@ dissect_isns_attr_scn_bitmap(tvbuff_t *tvb, guint offset, proto_tree *parent_tre static guint -AddAttribute(tvbuff_t *tvb, proto_tree *tree, guint offset, guint16 function_id) +AddAttribute(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree, guint offset, + guint16 function_id) { guint32 tag,len; @@ -1028,6 +1061,14 @@ AddAttribute(tvbuff_t *tvb, proto_tree *tree, guint offset, guint16 function_id) /* Now the Length */ len = tvb_get_ntohl(tvb, offset + 4); + + if (!len) { + if (tree) { + proto_tree_add_uint(tree, hf_isns_attr_tag, tvb, offset, 4, tag); + proto_tree_add_uint(tree, hf_isns_attr_len, tvb, offset+4, 4, len); + } + return (offset+8); + } switch( tag ) { @@ -1068,7 +1109,7 @@ AddAttribute(tvbuff_t *tvb, proto_tree *tree, guint offset, guint16 function_id) offset = dissect_isns_attr_ip_address(tvb, offset, tree, hf_isns_portal_ip_addr, tag, len); break; case ISNS_ATTR_TAG_PORTAL_PORT: - offset = dissect_isns_attr_port(tvb, offset, tree, hf_isns_portal_port, tag, len); + offset = dissect_isns_attr_port(tvb, offset, tree, hf_isns_portal_port, tag, len, ISNS_OTHER_PORT, pinfo); break; case ISNS_ATTR_TAG_PORTAL_SYMBOLIC_NAME: offset = dissect_isns_attr_string(tvb, offset, tree, hf_isns_portal_symbolic_name, tag, len); @@ -1077,7 +1118,7 @@ AddAttribute(tvbuff_t *tvb, proto_tree *tree, guint offset, guint16 function_id) offset = dissect_isns_attr_integer(tvb, offset, tree, hf_isns_esi_interval, tag, len, function_id); break; case ISNS_ATTR_TAG_ESI_PORT: - offset = dissect_isns_attr_port(tvb, offset, tree, hf_isns_esi_port, tag, len); + offset = dissect_isns_attr_port(tvb, offset, tree, hf_isns_esi_port, tag, len, ISNS_ESI_PORT, pinfo); break; case ISNS_ATTR_TAG_PORTAL_GROUP: offset = dissect_isns_attr_not_decoded_yet(tvb, offset, tree, hf_isns_not_decoded_yet, tag, len); @@ -1086,7 +1127,7 @@ AddAttribute(tvbuff_t *tvb, proto_tree *tree, guint offset, guint16 function_id) offset = dissect_isns_attr_integer(tvb, offset, tree, hf_isns_portal_index, tag, len, function_id); break; case ISNS_ATTR_TAG_SCN_PORT: - offset = dissect_isns_attr_port(tvb, offset, tree, hf_isns_scn_port, tag, len); + offset = dissect_isns_attr_port(tvb, offset, tree, hf_isns_scn_port, tag, len, ISNS_SCN_PORT, pinfo); break; case ISNS_ATTR_TAG_PORTAL_NEXT_INDEX: offset = dissect_isns_attr_integer(tvb, offset, tree, hf_isns_portal_next_index, tag, len, function_id); @@ -1107,7 +1148,7 @@ AddAttribute(tvbuff_t *tvb, proto_tree *tree, guint offset, guint16 function_id) offset = dissect_isns_attr_string(tvb, offset, tree, hf_isns_iscsi_name, tag, len); break; case ISNS_ATTR_TAG_ISCSI_NODE_TYPE: - offset = dissect_isns_attr_iscsi_node_type(tvb, offset, tree, hf_isns_iscsi_node_type, tag, len); + offset = dissect_isns_attr_iscsi_node_type(tvb, offset, tree, hf_isns_iscsi_node_type, tag, len); break; case ISNS_ATTR_TAG_ISCSI_ALIAS: offset = dissect_isns_attr_string(tvb, offset, tree, hf_isns_iscsi_alias, tag, len); @@ -1134,7 +1175,7 @@ AddAttribute(tvbuff_t *tvb, proto_tree *tree, guint offset, guint16 function_id) offset = dissect_isns_attr_ip_address(tvb, offset, tree, hf_isns_pg_portal_ip_addr, tag, len); break; case ISNS_ATTR_TAG_PG_PORTAL_PORT: - offset = dissect_isns_attr_port(tvb, offset, tree, hf_isns_pg_portal_port, tag, len); + offset = dissect_isns_attr_port(tvb, offset, tree, hf_isns_pg_portal_port, tag, len, ISNS_OTHER_PORT, pinfo); break; case ISNS_ATTR_TAG_PORTAL_GROUP_TAG: offset = dissect_isns_attr_integer(tvb, offset, tree, hf_isns_portal_group_tag, tag, len, function_id); @@ -1284,7 +1325,8 @@ AddAttribute(tvbuff_t *tvb, proto_tree *tree, guint offset, guint16 function_id) offset = dissect_isns_attr_ip_address(tvb, offset, tree, hf_isns_dd_member_portal_ip_addr, tag, len); break; case ISNS_ATTR_TAG_DD_MEMBER_PORTAL_PORT: - offset = dissect_isns_attr_port(tvb, offset, tree, hf_isns_dd_member_portal_port, tag, len); + offset = dissect_isns_attr_port(tvb, offset, tree, hf_isns_dd_member_portal_port, + tag, len, ISNS_OTHER_PORT, pinfo); break; case ISNS_ATTR_TAG_DD_FEATURES: offset = dissect_isns_attr_not_decoded_yet(tvb, offset, tree, hf_isns_not_decoded_yet, tag, len); @@ -1872,10 +1914,9 @@ void proto_register_isns(void) void proto_reg_handoff_isns(void) { - dissector_handle_t isns_tcp_handle; - dissector_handle_t isns_udp_handle; isns_tcp_handle = create_dissector_handle(dissect_isns_tcp,proto_isns); isns_udp_handle = create_dissector_handle(dissect_isns_udp,proto_isns); + dissector_add("tcp.port",ISNS_TCP_PORT,isns_tcp_handle); dissector_add("udp.port",ISNS_UDP_PORT,isns_udp_handle); } -- cgit v1.2.3