Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Wireshark-dev: Re: [Wireshark-dev] An iSCSI expert system for wireshark

From: jimmy wang <jimmy.tianjin@xxxxxxxxx>
Date: Wed, 20 Jan 2010 17:37:40 +0800
Hi Richard,
We are very glad for your reply. The attached patch is the iscsi analyzing system for wireshark 1.2.2. In this patch the iscsi[E] dissector is implemented as a new file packet-iscsiexpoert.c, you need disable iscsi and enable iscsi[E] to test it. The development platform is MS Windows and No strict testing has been made. Just send it to you for evaluate. Please feel free to give us your suggestion.

BS.
Jimmy

diff -urN wireshark-1.2.2/colorfilters wireshark-1.2.2-iscsie/colorfilters
--- wireshark-1.2.2/colorfilters	2009-09-15 09:50:46.000000000 +0800
+++ wireshark-1.2.2-iscsie/colorfilters	2010-01-12 18:08:05.000000000 +0800
@@ -14,7 +14,10 @@
 @IPX@ipx || spx@[65534,58325,58808][0,0,0]
 @DCERPC@dcerpc@[51199,38706,65533][0,0,0]
 @Routing@hsrp || eigrp || ospf || bgp || cdp || vrrp || gvrp || igmp || ismp@[65534,62325,54808][0,0,0]
+@iscsiexpert@iscsiexpert@[34952,35980,40863][60909,24929,0]
 @TCP SYN/[email protected] & 0x02 || tcp.flags.fin == 1@[41026,41026,41026][0,0,0]
 @TCP@tcp@[59345,58980,65534][0,0,0]
 @UDP@udp@[28834,57427,65533][0,0,0]
 @Broadcast@eth[0] & 1@[65535,65535,65535][32768,32768,32768]
+@[email protected] == 0x2@[65534,45295,45295][0,0,0]
+@No_reply@iscsi and (!iscsi.response_frame and !iscsi.data_in_frame and !iscsi.data_out_frame and !iscsi.request_frame)@[57092,54235,65534][0,0,0]
\ No newline at end of file
diff -urN wireshark-1.2.2/config.nmake wireshark-1.2.2-iscsie/config.nmake
--- wireshark-1.2.2/config.nmake	2009-09-15 09:50:48.000000000 +0800
+++ wireshark-1.2.2-iscsie/config.nmake	2010-01-06 14:12:25.000000000 +0800
@@ -20,7 +20,7 @@
 VERSION_BUILD=29910
 # It's recommended to change VERSION_EXTRA for your own custom builds
 # e.g. "-SVN-12345"
-VERSION_EXTRA=""
+VERSION_EXTRA="-iscsie"
 
 # The version of the wiretap library (recommended: leave unchanged)
 WTAP_VERSION_MAJOR=0
diff -urN wireshark-1.2.2/epan/Makefile.common wireshark-1.2.2-iscsie/epan/Makefile.common
--- wireshark-1.2.2/epan/Makefile.common	2009-09-15 09:50:14.000000000 +0800
+++ wireshark-1.2.2-iscsie/epan/Makefile.common	2009-11-26 16:35:37.000000000 +0800
@@ -39,6 +39,7 @@
 	column.c		\
 	column-utils.c		\
 	conversation.c		\
+	iscsisession.c		\
 	crc10.c			\
 	crc16.c			\
 	crc32.c			\
diff -urN wireshark-1.2.2/epan/conversation.c wireshark-1.2.2-iscsie/epan/conversation.c
--- wireshark-1.2.2/epan/conversation.c	2009-09-15 09:50:17.000000000 +0800
+++ wireshark-1.2.2-iscsie/epan/conversation.c	2009-12-29 16:26:45.000000000 +0800
@@ -37,7 +37,9 @@
 /*
  * Hash table for conversations with no wildcards.
  */
-static GHashTable *conversation_hashtable_exact = NULL;
+//static GHashTable *conversation_hashtable_exact = NULL;
+GHashTable *conversation_hashtable_exact = NULL;
+
 
 /*
  * Hash table for conversations with one wildcard address.
diff -urN wireshark-1.2.2/epan/dissectors/Makefile.common wireshark-1.2.2-iscsie/epan/dissectors/Makefile.common
--- wireshark-1.2.2/epan/dissectors/Makefile.common	2009-09-15 09:50:04.000000000 +0800
+++ wireshark-1.2.2-iscsie/epan/dissectors/Makefile.common	2009-11-26 16:35:37.000000000 +0800
@@ -542,6 +542,7 @@
 	packet-ipxwan.c		\
 	packet-irc.c		\
 	packet-iscsi.c		\
+	packet-iscsiexpert.c	\
 	packet-isdn.c		\
 	packet-isis-clv.c	\
 	packet-isis-hello.c	\
diff -urN wireshark-1.2.2/epan/dissectors/Makefile.in wireshark-1.2.2-iscsie/epan/dissectors/Makefile.in
--- wireshark-1.2.2/epan/dissectors/Makefile.in	2009-09-15 09:51:24.000000000 +0800
+++ wireshark-1.2.2-iscsie/epan/dissectors/Makefile.in	2009-11-26 16:35:37.000000000 +0800
@@ -439,6 +439,7 @@
 	libdissectors_la-packet-ipxwan.lo \
 	libdissectors_la-packet-irc.lo \
 	libdissectors_la-packet-iscsi.lo \
+	libdissectors_la-packet-iscsiexpert.lo \
 	libdissectors_la-packet-isdn.lo \
 	libdissectors_la-packet-isis-clv.lo \
 	libdissectors_la-packet-isis-hello.lo \
@@ -1618,6 +1619,7 @@
 	packet-ipxwan.c		\
 	packet-irc.c		\
 	packet-iscsi.c		\
+	packet-iscsiexpert.c	\
 	packet-isdn.c		\
 	packet-isis-clv.c	\
 	packet-isis-hello.c	\
diff -urN wireshark-1.2.2/epan/dissectors/iscsiexpert-rules.c wireshark-1.2.2-iscsie/epan/dissectors/iscsiexpert-rules.c
--- wireshark-1.2.2/epan/dissectors/iscsiexpert-rules.c	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/epan/dissectors/iscsiexpert-rules.c	2010-01-20 16:47:51.000000000 +0800
@@ -0,0 +1,1845 @@
+/* iscsiexpert_rules.c
+ * Copyright 2009, Ji-dong Wang <Wang.ji-dong@xxxxxxxxxxxxxx>
+ * 				   Qian Zhang <Zhang.qian@xxxxxxxxxxxxxx>
+ * 				   Ying-chao Yang <Yang.ying-chao@xxxxxxxxxxxxxx>
+ * 				   Cang-mou Cao	<Cao.cang-mou@xxxxxxxxxxxxxx>
+ * 				   Xing-jia	Wang <Wang.xing-jia@xxxxxxxxxxxxxx>
+ * 
+ * $Id: iscsiexpert_rules.c 28363 2009-05-14 19:28:07Z etxrab $
+ *
+ * This is temporary file for rules and facts used in iscsiexpert, and it
+ * should be separated into two parts: facts and rules. Facts should be
+ * mergered into packet-iscsiexpert.c, and rules should be abstracted as a new
+ * stand alone file.
+ *
+ * This file was derived from packet-iscsiexpert.c temporaryly to avoid
+ * conflict when update source from svn server.
+ *
+ * Added by Yangyingchao, itc-208024.
+ *
+ * TODO: Updata contexts, see packet-iscsiexpert.h for more into.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/prefs.h>
+#include <epan/conversation.h>
+#include <epan/iscsisession.h>
+#include "packet-iscsiexpert.h"
+#include "epan/nstime.h"
+#include <epan/emem.h>
+#include <epan/crc32.h>
+#include <epan/tap.h>
+#include <epan/dissectors/packet-tcp.h>
+#include <epan/dissectors/packet-scsi-sbc.h>
+#include <epan/expert.h>
+
+#define SNA32_CHECK	0x80000000
+
+/* Standard keys can be used in Login PDUs */
+const char *iscsiexpert_std_keys[] = {
+     "AuthMethod",
+     "DataDigest",
+     "DataPDUInOrder",
+     "DataSequenceInOrder",
+     "DefaultTime2Retain",
+     "DefaultTime2Wait",
+     "ErrorRecoveryLevel",
+     "FirstBurstLength",
+     "HeaderDigest",
+     "ImmediateData",
+     "InitialR2T",
+     "InitiatorAlias",
+     "InitiatorName",
+     "MaxBurstLength",
+     "MaxConnections",
+     "MaxOutstandingR2T",
+     "MaxRecvDataSegmentLength",
+     "SendTargets",
+     "SessionType",
+     "TargetAddress",
+     "TargetAlias",
+     "TargetName",
+     "TargetPortalGroupTag"
+};
+
+cdb_info read_write[]= {
+     {SCSI_SBC_READ6, 4, 1},
+     {SCSI_SBC_READ10, 7, 2},
+     {SCSI_SBC_READ12, 6, 4},
+     {SCSI_SBC_READ16, 10, 4},
+     {SCSI_SBC_READLONG10, 7, 2},
+     {SCSI_SBC_READLONG16, 12, 2},
+     {SCSI_SBC_XDREAD10, 7, 2},
+     {SCSI_SBC_WRITE6, 4, 1},
+     {SCSI_SBC_WRITE10, 7, 2},
+     {SCSI_SBC_WRITE12, 6, 4},
+     {SCSI_SBC_WRITE16, 10, 4},
+     {SCSI_SBC_WRITELONG10, 7, 2},
+     {SCSI_SBC_WRITELONG16, 12, 2},
+     {SCSI_SBC_XDWRITE10, 7, 2},
+     {SCSI_SBC_WRITESAME10, 7, 2},
+     {SCSI_SBC_WRITESAME16, 10, 4},
+     {SCSI_SBC_XPWRITE10, 7, 2},
+     {SCSI_SBC_WRITENVERIFY10, 7, 2},
+     {SCSI_SBC_WRITENVERIFY12, 6, 4},
+     {SCSI_SBC_WRITENVERIFY16, 10, 4},
+     {SCSI_SBC_ORWRITE, 10, 4},
+     {0, 0, 0}
+};
+
+cdb_info non_read_write[] = {
+     {SCSI_SBC_PREFETCH10, 7, 2},
+     {SCSI_SBC_PREFETCH16, 10, 4},
+     {SCSI_SBC_PREFETCH16, 10, 4},
+     {SCSI_SBC_SYNCCACHE10, 7, 2},
+     {SCSI_SBC_SYNCCACHE16, 10, 4},
+     {SCSI_SBC_VERIFY10, 7, 2},
+     {SCSI_SBC_VERIFY12, 6, 4},
+     {SCSI_SBC_VERIFY16, 10, 4},
+     {0, 0, 0}
+};
+
+
+static gboolean PREV_CMD_C_BIT_SET = FALSE;
+static gboolean PREV_RSP_C_BIT_SET = FALSE;
+static gchar *cmd_kv_tmp = NULL;
+static gchar *rsp_kv_tmp = NULL;
+static iscsiexpert_kv_result kv_result;
+
+gint
+generic_sort_func (gconstpointer a, gconstpointer b)
+{
+     guint32 num1, num2;
+     gint ret = 0;
+     num1 = GPOINTER_TO_UINT(a);
+     num2 = GPOINTER_TO_UINT(b);
+
+     if (num1 < num2)
+          ret = -1;
+     else
+          ret = 1;
+
+     return ret;
+}
+
+/* iSCSI Serial Number Arithmatic Fuction.
+ * See RFC 1982 for more information.
+ * When deaing with DataSN and Bufffer offset of Data-In/Out, this function is
+ * also used. DataSN was initialized as 0xffffffff, and 0 is larger than
+ * 0xffffffff when calculated by this function.
+ */
+static gboolean
+iscsiexpert_sna_lt(guint32 n1, guint32 n2)
+{
+	return n1 != n2 && ((n1 < n2 && (n2 - n1 < SNA32_CHECK)) ||
+			    (n1 > n2 && (n2 - n1 < SNA32_CHECK)));
+}
+
+static gboolean
+opcode_is_valid(guint opcode){
+	 if ((opcode >= 0x00 && opcode <= 0x06) || opcode == 0x10 ||\
+         (opcode >= 0x1c && opcode <= 0x1e) || opcode == 0x31 ||\
+         (opcode >= 0x20 && opcode <= 0x26) || opcode == 0x32 ||
+         (opcode >= 0x3c && opcode <= 0x3f))
+          return TRUE;
+     else
+          return FALSE;
+
+}
+
+static gboolean
+iscsiexpert_is_iscsirsp(guint8 opcode){
+	if((opcode & TARGET_OPCODE_BIT) == 0){
+		return FALSE;
+     }else{
+        return TRUE;
+     }
+}
+
+static gboolean is_immediate_iscsi_cmd(guint8 org_opcode){
+	 guint8 opcode = org_opcode & OPCODE_MASK;
+	 if ((opcode < 0x1c) && ((org_opcode & 0x40) >> 6)){
+			return TRUE;
+	 }
+	 return FALSE;
+}
+
+/* Wraped function to chek keys. */
+gboolean iscsiexpert_key_check(const gchar *key)
+{
+     gint i;
+     gint size = sizeof(iscsiexpert_std_keys)/sizeof(iscsiexpert_std_keys[0]);
+     if(key != NULL){
+          for (i = 0; i < size; i++) {
+               if (!strcmp(key, iscsiexpert_std_keys[i])){
+                    return TRUE; /* Return TRUE if it is standard key */
+               }
+          }
+          if (key[0] == 'X' && (key[1] == '-'|| key[1]== '#')){
+               return TRUE; /* Vendor Specific keys */
+          }
+     }
+     return FALSE;
+}
+
+/* Followings are functions to perform fact check, its result will be
+ * used by expert rule to calculate final result.
+ */
+
+/* HeaderDigest */
+static iscsiexpert_fact
+header_digest_good_conclude(tvbuff_t *tvb, guint offset, guint opcode,
+                            packet_info *pinfo,
+                            iscsiexpert_conv_data_t * conv_data,
+                            iscsiexpert_session_t *conn,
+                            iscsiexpert_sessionset_t * sessset)
+{
+     //not implement
+     /* gint32  offset = 0; */
+     gint available_bytes = tvb_length_remaining(tvb, offset);
+     gint32  headerLen = 48;
+
+     //switch(conn->header_digest){
+     //  case ISCSIEXPERT_HEADER_DIGEST_CRC32:
+     if(available_bytes >= (headerLen + 4)) {
+          guint32 crc = ~calculate_crc32c(tvb_get_ptr(tvb, offset, headerLen),
+                                          headerLen, CRC32C_PRELOAD);
+          guint32 sent = tvb_get_ntohl(tvb, offset + headerLen);
+          if(crc == sent) {
+               //header digest is good
+               return FACT_TRUE;
+          } else {
+               //header digest is bad
+               return FACT_FALSE;
+          }
+     }
+     //}
+     //not calculate the digest
+     return FACT_UNKNOWN;
+}
+
+/* DataSN */
+static iscsiexpert_fact
+datasn_mismatch_conclude(tvbuff_t *tvb, guint offset, guint opcode,
+                         packet_info *pinfo,
+                         iscsiexpert_conv_data_t * conv_data,
+                         iscsiexpert_session_t *conn,
+                         iscsiexpert_sessionset_t * sessset)
+{
+     guint32 datasn = tvb_get_ntohl(tvb, offset+36);
+     guint8 f_bit = (tvb_get_guint8(tvb, offset+1) & 0x80) >> 7;
+     iscsiexpert_fact ret = FACT_UNKNOWN;
+	 iscsipacket_conv_context_t *cdata_context = NULL;
+
+	 cdata_context = (iscsipacket_conv_context_t *)\
+          se_tree_lookup32(conv_data->contextq,
+          (((pinfo->fd->num &0xFFFF) << 16) | (tvb->length &0xFFFF)));
+	 DISSECTOR_ASSERT(cdata_context);
+
+     if (opcode == ISCSIEXPERT_OPCODE_SCSI_DATA_IN ||
+         opcode == ISCSIEXPERT_OPCODE_SCSI_DATA_OUT) {
+          if ((cdata_context->lastdatasn == 0xffffffff && datasn == 0)
+              || ((cdata_context->lastdatasn + 1) ==  datasn))
+               ret = FACT_FALSE;
+          else
+               ret = FACT_TRUE;
+     }
+     return ret;
+}
+
+
+/* ExpStatSN */
+static iscsiexpert_fact
+expdatasn_gt_highestdatasn_conclude(tvbuff_t *tvb,guint offset, guint opcode,
+                                    packet_info *pinfo,
+                                    iscsiexpert_conv_data_t *conv_data,
+                                    iscsiexpert_session_t *conn,
+                                    iscsiexpert_sessionset_t * sessset)
+{
+     guint32 expdatasn = tvb_get_ntohl(tvb, offset+38);
+     guint8 response = tvb_get_guint8(tvb, offset+2);
+     iscsiexpert_fact ret = FACT_UNKNOWN;
+
+     if (opcode == ISCSIEXPERT_OPCODE_SCSI_RESPONSE){
+          if (response == 0x00){
+               if (conv_data->maxdatasn + 1 == expdatasn)
+                    ret = FACT_TRUE;
+               else
+                    ret = FACT_FALSE;
+          }
+     }
+     return ret;
+}
+
+/* StatSN */
+static iscsiexpert_fact
+statsn_lt_expstatsn_conclude(tvbuff_t *tvb,guint offset, guint opcode,
+                             packet_info *pinfo,
+                             iscsiexpert_conv_data_t *conv_data,
+                             iscsiexpert_session_t *conn,
+                             iscsiexpert_sessionset_t * sessset)
+{
+	guint32 statsn;
+	iscsipacket_conv_context_t *cdata_context = NULL;
+
+	cdata_context = (iscsipacket_conv_context_t *)se_tree_lookup32(conv_data->contextq, (((pinfo->fd->num &0xFFFF) << 16) | (tvb->length  &0xFFFF)));
+	DISSECTOR_ASSERT(cdata_context);
+
+	if (opcode == ISCSIEXPERT_OPCODE_SCSI_DATA_IN){
+		guint8 s_bit = tvb_get_guint8(tvb, offset+1) & 0x01;
+		if (!s_bit){
+			//RFC10.7.3 The fields StatSN, Status, and Residual Count only have meaningful
+			//content if the S bit is set to 1 and their values are defined in
+			//Section 10.4 SCSI Response.
+			return FACT_FALSE;
+		}
+	}else if(opcode == ISCSIEXPERT_OPCODE_LOGIN_RESPONSE){
+		guint8 status_class = tvb_get_guint8(tvb, offset+36);
+		//For the first Login Response (the response to the first Login
+		//Request), this is the starting status Sequence Number for the
+		//connection. The next response of any kind, including the next Login
+		//Response, if any, in the same Login Phase, will carry this number +
+		//1. This field is only valid if the Status-Class is 0.
+		if (status_class){
+			return FACT_FALSE;
+		}
+
+		if (cdata_context->first_login_response){
+			return FACT_FALSE;
+		}
+	}
+
+	statsn = tvb_get_ntohl(tvb, offset + 24);
+
+     if (iscsiexpert_sna_lt(statsn,cdata_context->lastexpstatsn))
+          return FACT_TRUE;
+     else
+          return FACT_FALSE;
+}
+
+/* CmdSN */
+static iscsiexpert_fact
+cmdsn_gt_maxcmdsn_conclude(tvbuff_t *tvb,guint offset, guint opcode,
+                           packet_info *pinfo,
+                           iscsiexpert_conv_data_t *conv_data,
+                           iscsiexpert_session_t *conn,
+                           iscsiexpert_sessionset_t * sessset)
+{
+     guint32 cmdsn   = tvb_get_ntohl(tvb, offset + 24);
+     if (iscsiexpert_sna_lt(conv_data->lastmaxcmdsn,cmdsn))
+          return FACT_TRUE;
+     else
+          return FACT_FALSE;
+}
+
+/* If CSG was not 0, 1 or 3, return FALSE (ERROR) */
+static iscsiexpert_fact
+csg_not_valid_conclude(tvbuff_t *tvb, guint offset, guint opcode,
+                       packet_info *pinfo,
+                       iscsiexpert_conv_data_t * conv_data,
+                       iscsiexpert_session_t *conn,
+                       iscsiexpert_sessionset_t * sessset)
+{
+     guint res = FACT_UNKNOWN;
+     guint csg;
+     if ((opcode == ISCSIEXPERT_OPCODE_LOGIN_COMMAND) ||
+         (opcode == ISCSIEXPERT_OPCODE_LOGIN_RESPONSE)) {
+          csg = (tvb_get_guint8(tvb,offset+1)&CSG_MASK) >> CSG_SHIFT;
+          if (csg != 0x00 && csg != 0x01 && csg != 0x03)
+               res = FACT_TRUE;
+          else
+               res = FACT_FALSE;
+     }
+     return res;
+}
+
+
+/* If NSG was not 0, 1 or 3, return FALSE (ERROR) */
+static iscsiexpert_fact
+nsg_not_valid_conclude(tvbuff_t *tvb,guint offset,  guint opcode,
+                       packet_info *pinfo,
+                       iscsiexpert_conv_data_t * conv_data,
+                       iscsiexpert_session_t *conn,
+                       iscsiexpert_sessionset_t * sessset)
+{
+     guint res = FACT_UNKNOWN;
+     guint t_bit, nsg;
+     if ((opcode == ISCSIEXPERT_OPCODE_LOGIN_COMMAND) ||
+         (opcode == ISCSIEXPERT_OPCODE_LOGIN_RESPONSE)) {
+          t_bit = (tvb_get_guint8(tvb, offset+1) & 0x80 ) >> 7;
+          nsg = (tvb_get_guint8(tvb, offset+1)) & NSG_MASK;
+          if (t_bit) {
+               if (nsg != 0x00 && nsg != 0x01 && nsg != 0x03)
+                    res = FACT_TRUE;
+               else
+                    res = FACT_FALSE;
+          }
+          else
+               res = FACT_FALSE;
+     }
+     return res;
+}
+
+/* If Tbit was 0, and NSG was not 0, return FALSE (ERROR) */
+static iscsiexpert_fact
+nsg_not_reserved_conclude(tvbuff_t *tvb, guint offset, guint opcode,
+                          packet_info *pinfo,
+                          iscsiexpert_conv_data_t * conv_data,
+                          iscsiexpert_session_t *conn,
+                          iscsiexpert_sessionset_t * sessset)
+{
+     guint res = FACT_UNKNOWN;
+     guint t_bit, nsg;
+     if ((opcode == ISCSIEXPERT_OPCODE_LOGIN_COMMAND) ||
+         (opcode == ISCSIEXPERT_OPCODE_LOGIN_RESPONSE))
+     {
+          t_bit = (tvb_get_guint8(tvb, offset+1) & 0x80 ) >> 7;
+          nsg = tvb_get_guint8(tvb, offset+1) & NSG_MASK;
+          if (t_bit == 0)
+               res = FACT_FALSE;
+     }
+     return res;
+}
+
+/* Generic function to check: Key, Value, and KeyValue Pair */
+static void
+login_keyvalue_generic(tvbuff_t *tvb, guint offset, guint opcode,
+                       packet_info *pinfo,
+                       iscsiexpert_conv_data_t * conv_data,
+                       iscsiexpert_session_t *conn,
+                       iscsiexpert_sessionset_t * sessset)
+{
+     gchar *kv_pair = NULL;
+     gchar *kv_pair_tmp = NULL;
+     gchar *name = NULL;
+     gchar **kv_array = NULL;
+     guint32 dsLen = tvb_get_ntohl(tvb, offset + 4) & 0x00FFFFFF;
+     guint32 dsLen_new = dsLen;
+     guint limit = offset + 48 + dsLen;
+     guint c_bit = (tvb_get_guint8(tvb, offset+1) & 0x40) >> 6;
+     guint offset_new = offset + 48;
+     gboolean *PREV_C_BIT_SET = NULL;
+     gchar *kv_tmp = NULL;
+
+     memset(&kv_result, FACT_INIT, sizeof(kv_result));
+
+     if (opcode == ISCSIEXPERT_OPCODE_LOGIN_COMMAND){
+          PREV_C_BIT_SET = &PREV_CMD_C_BIT_SET;
+          kv_tmp = cmd_kv_tmp;
+     }
+     else if (opcode == ISCSIEXPERT_OPCODE_LOGIN_RESPONSE){
+          PREV_C_BIT_SET = &PREV_RSP_C_BIT_SET;
+          kv_tmp = rsp_kv_tmp;
+     }
+
+     while (offset_new < limit){
+          gint len = tvb_strnlen(tvb, offset_new, dsLen);
+          if(len == -1)
+               len = limit - offset_new;
+          else
+               len = len + 1;
+
+          /* Get KeyValue pair from tvb, if PREV_CMD_C_BIT_SET_KEY, concat
+             former string to make a complete pair */
+          kv_pair = tvb_get_ephemeral_string(tvb, offset_new, len);
+          if (offset_new == offset + 48){ /* The first key of this PDU */
+               if (*PREV_C_BIT_SET){ /* First PDU setted C-bit to 1 */
+                    if (cmd_kv_tmp == NULL){
+                         ; /* cmd_kv_tmp was not filled, should not happen*/
+                    }
+                    else {
+                         kv_pair_tmp = g_strconcat(kv_tmp, kv_pair, NULL);
+                         kv_pair = g_strdup(kv_pair_tmp);
+                    }
+               }
+          }
+
+          if ((offset_new + len >= offset + 48 + dsLen) && c_bit){
+               /* Last KeyValue Pair in PDU, and c bit was set */
+               cmd_kv_tmp = g_strdup(kv_pair);
+          }
+          else {
+               /* Check KeyValue Pair */
+               if (kv_result.keyvalue_result != FACT_TRUE){
+                    if (strchr(kv_pair, '=') == NULL)
+                         kv_result.keyvalue_result = FACT_TRUE;
+                    else
+                         kv_result.keyvalue_result = FACT_FALSE;
+               }
+
+               /* Check Value */
+               kv_array =  g_strsplit(kv_pair, "=", -1);
+               if (kv_result.value_result != FACT_TRUE){
+                    if (!kv_array[1] || !strlen(kv_array[1]))
+                         kv_result.value_result = FACT_TRUE;
+                    else
+                         kv_result.value_result = FACT_FALSE;
+               }
+
+               /* Check Key */
+               if (kv_result.key_result != FACT_TRUE){
+                    name = g_strdup(kv_array[0]);
+                    if (!iscsiexpert_key_check(name))
+                         kv_result.key_result = FACT_TRUE;
+                    else
+                         kv_result.key_result = FACT_FALSE;
+               }
+               g_strfreev(kv_array);
+          }
+          dsLen_new -= len;
+          offset_new += len; /* Start anthor query. */
+
+          /* If all three conditions are meet, stop checking */
+          if (kv_result.key_result == kv_result.keyvalue_result ==\
+              kv_result.value_result == FACT_TRUE)
+               break;
+     }
+
+     if (c_bit)
+          *PREV_C_BIT_SET = TRUE;
+     else {
+          *PREV_C_BIT_SET = FALSE;
+          kv_tmp = NULL;
+     }
+}
+
+/* perform generic check, and get result */
+static iscsiexpert_fact
+login_key_invalid(tvbuff_t *tvb, guint offset, guint opcode,
+                  packet_info *pinfo,
+                  iscsiexpert_conv_data_t * conv_data,
+                  iscsiexpert_session_t *conn,
+                  iscsiexpert_sessionset_t * sessset)
+{
+     login_keyvalue_generic(tvb, offset, opcode, pinfo, conv_data, conn,
+                            sessset);
+     return kv_result.key_result;
+}
+
+/* Get result of KeyValue pair check */
+static iscsiexpert_fact
+login_kv_pair_inavlid(tvbuff_t *tvb, guint offset, guint opcode,
+                      packet_info *pinfo,
+                      iscsiexpert_conv_data_t * conv_data,
+                      iscsiexpert_session_t *conn,
+                      iscsiexpert_sessionset_t * sessset)
+{
+     return kv_result.keyvalue_result;
+}
+
+/* Get result of value check */
+static iscsiexpert_fact
+login_value_inavlid(tvbuff_t *tvb, guint offset, guint opcode,
+                    packet_info *pinfo,
+                    iscsiexpert_conv_data_t * conv_data,
+                    iscsiexpert_session_t *conn,
+                    iscsiexpert_sessionset_t * sessset)
+{
+     return kv_result.value_result;
+}
+
+/* check Reject Reason */
+static iscsiexpert_fact
+reject_bad_reason(tvbuff_t *tvb, guint offset, guint opcode,
+                  packet_info *pinfo,
+                  iscsiexpert_conv_data_t * conv_data,
+                  iscsiexpert_session_t *conn,
+                  iscsiexpert_sessionset_t * sessset)
+{
+     guint8 reason = tvb_get_guint8(tvb, offset+2);
+     if (reason == 0x01)
+          return FACT_TRUE;
+     else
+          return FACT_FALSE;
+}
+
+static iscsiexpert_fact
+task_mgmt_rsp_bad_response(tvbuff_t *tvb, guint offset, guint opcode,
+                           packet_info *pinfo,
+                           iscsiexpert_conv_data_t * conv_data,
+                           iscsiexpert_session_t *conn,
+                           iscsiexpert_sessionset_t * sessset)
+{
+     guint8 response =  tvb_get_guint8(tvb, offset+2);
+     if (response <= 0x06 || response == 0xff)
+          return FACT_FALSE;
+     else
+          return FACT_TRUE;
+}
+
+static iscsiexpert_fact
+task_mgmt_cmd_bad_function(tvbuff_t *tvb, guint offset, guint opcode,
+                           packet_info *pinfo,
+                           iscsiexpert_conv_data_t * conv_data,
+                           iscsiexpert_session_t *conn,
+                           iscsiexpert_sessionset_t * sessset)
+{
+     guint8 function = tvb_get_guint8(tvb, offset+1) & 0x7f;
+     if(function <= 0x08)
+          return FACT_FALSE;
+     else
+          return FACT_TRUE;
+}
+
+static iscsiexpert_fact
+async_msg_bad_event(tvbuff_t *tvb, guint offset, guint opcode,
+                    packet_info *pinfo,
+                    iscsiexpert_conv_data_t * conv_data,
+                    iscsiexpert_session_t *conn,
+                    iscsiexpert_sessionset_t * sessset)
+{
+     guint8 reason = tvb_get_guint8(tvb, offset+1) & 0x7f;
+     if (reason <= 0x08 && reason != 0x00)
+          return FACT_FALSE;
+     else
+          return FACT_TRUE;
+}
+
+static iscsiexpert_fact
+logout_cmd_bad_reason(tvbuff_t *tvb, guint offset, guint opcode,
+                      packet_info *pinfo,
+                      iscsiexpert_conv_data_t * conv_data,
+                      iscsiexpert_session_t *conn,
+                      iscsiexpert_sessionset_t * sessset)
+{
+     guint8 reason = tvb_get_guint8(tvb, offset+1) & 0x7f;
+     if (reason <= 0x02)
+          return FACT_FALSE;
+     else
+          return FACT_TRUE;
+}
+
+static iscsiexpert_fact
+logout_rsp_bad_response(tvbuff_t *tvb, guint offset, guint opcode,
+                        packet_info *pinfo,
+                        iscsiexpert_conv_data_t * conv_data,
+                        iscsiexpert_session_t *conn,
+                        iscsiexpert_sessionset_t * sessset)
+{
+     guint8 response =  tvb_get_guint8(tvb, offset+2);
+     if (response <= 0x03)
+          return FACT_FALSE;
+     else
+          return FACT_TRUE;
+}
+
+static iscsiexpert_fact
+scsi_cmd_r_bit_set(tvbuff_t *tvb, guint offset, guint opcode,
+                   packet_info *pinfo,
+                   iscsiexpert_conv_data_t * conv_data,
+                   iscsiexpert_session_t *conn,
+                   iscsiexpert_sessionset_t * sessset)
+{
+     if ((tvb_get_guint8(tvb, offset+1) & 0x40) >> 6)
+          return FACT_TRUE;
+     else
+          return FACT_FALSE;
+}
+
+static iscsiexpert_fact
+scsi_cmd_w_bit_set(tvbuff_t *tvb, guint offset, guint opcode,
+                   packet_info *pinfo,
+                   iscsiexpert_conv_data_t * conv_data,
+                   iscsiexpert_session_t *conn,
+                   iscsiexpert_sessionset_t * sessset)
+{
+     iscsiexpert_fact ret = FACT_UNKNOWN;
+     if (opcode == ISCSIEXPERT_OPCODE_SCSI_COMMAND) {
+          if ((tvb_get_guint8(tvb, offset+1) & 0x20) >> 5)
+               return FACT_TRUE;
+          else
+               return FACT_FALSE;
+     }
+     return ret;
+}
+
+static iscsiexpert_fact
+scsi_rsp_bad_response(tvbuff_t *tvb, guint offset, guint opcode,
+                      packet_info *pinfo,
+                      iscsiexpert_conv_data_t * conv_data,
+                      iscsiexpert_session_t *conn,
+                      iscsiexpert_sessionset_t * sessset)
+{
+     guint response = tvb_get_guint8(tvb, offset+2);
+     if (response != 0x00 && response != 0x01 && response != 0xff)
+          return FACT_TRUE;
+     else
+          return FACT_FALSE;
+}
+
+static iscsiexpert_fact
+scsi_rsp_status_is_zero(tvbuff_t *tvb, guint offset, guint opcode,
+                        packet_info *pinfo,
+                        iscsiexpert_conv_data_t * conv_data,
+                        iscsiexpert_session_t *conn,
+                        iscsiexpert_sessionset_t * sessset)
+{
+     if (tvb_get_guint8(tvb, offset+3))
+          return FACT_TRUE;
+     else
+          return FACT_FALSE;
+}
+
+static iscsiexpert_fact
+scsi_rsp_resopnse_is_zero(tvbuff_t *tvb, guint offset, guint opcode,
+                          packet_info *pinfo,
+                          iscsiexpert_conv_data_t * conv_data,
+                          iscsiexpert_session_t *conn,
+                          iscsiexpert_sessionset_t * sessset)
+{
+     if (tvb_get_guint8(tvb, offset+2))
+          return FACT_TRUE;
+     else
+          return FACT_FALSE;
+}
+
+static iscsiexpert_fact
+snack_cmd_type_invalid(tvbuff_t *tvb, guint offset, guint opcode,
+                       packet_info *pinfo,
+                       iscsiexpert_conv_data_t * conv_data,
+                       iscsiexpert_session_t *conn,
+                       iscsiexpert_sessionset_t * sessset)
+{
+     guint8 type = tvb_get_guint8(tvb, offset+1)&0x0f;
+     if (type <= 0x03)
+          return FACT_FALSE;
+     else
+          return FACT_TRUE;
+}
+
+static iscsiexpert_fact
+data_in_status_is_zero(tvbuff_t *tvb, guint offset, guint opcode,
+                           packet_info *pinfo,
+                           iscsiexpert_conv_data_t * conv_data,
+                           iscsiexpert_session_t *conn,
+                           iscsiexpert_sessionset_t * sessset)
+{
+     if (tvb_get_guint8(tvb, offset)&0x01){
+          if (!tvb_get_guint8(tvb, offset+3)){
+               return FACT_TRUE;
+          }
+          else
+               return FACT_FALSE;
+     }
+
+     return FACT_UNKNOWN;
+}
+
+static iscsiexpert_fact
+read_write_tl_is_zero(tvbuff_t *tvb, guint offset, guint opcode,
+                      packet_info *pinfo,
+                      iscsiexpert_conv_data_t * conv_data,
+                      iscsiexpert_session_t *conn,
+                      iscsiexpert_sessionset_t * sessset)
+{
+     guint8 scsi_opcode=tvb_get_guint8(tvb, offset+32);
+     if (scsi_opcode == SCSI_SBC_READ6  || scsi_opcode == SCSI_SBC_WRITE6 ||\
+         scsi_opcode == SCSI_SBC_READ10 || scsi_opcode == SCSI_SBC_WRITE10||\
+         scsi_opcode == SCSI_SBC_READ12 || scsi_opcode == SCSI_SBC_WRITE12||\
+         scsi_opcode == SCSI_SBC_READ16 || scsi_opcode == SCSI_SBC_WRITE16){
+          if (tvb_get_ntohl(tvb, offset+20))
+               return FACT_FALSE;
+          else
+               return FACT_TRUE;
+
+     }
+     return FACT_UNKNOWN;
+}
+
+/* type: TRUE to get from Read/Write
+ * 		 FALSE to get from non_read_write*/
+static gboolean
+get_cdb_transfer_length(tvbuff_t *tvb, guint cdb_offset, gboolean check_read_write,
+                        guint32 *scsi_transfer_length)
+{
+     gint i = 0,tmp=-1;
+     guint8 scsi_opcode = tvb_get_guint8(tvb, cdb_offset);
+     cdb_info *check_cdb = NULL;
+     gboolean ret = FALSE;
+
+     if (check_read_write)
+          check_cdb = read_write;
+     else
+          check_cdb = non_read_write;
+
+     while (check_cdb[i].scsi_opcode != 0){
+          if (check_cdb[i].scsi_opcode == scsi_opcode){
+               guint32 tl_offset = cdb_offset + check_cdb[i].offset;
+               switch(check_cdb[i].length) {
+               case 1:
+                    *scsi_transfer_length = (guint32) \
+                         tvb_get_guint8(tvb, tl_offset);
+                    ret = TRUE;
+                    break;
+               case 2:
+                    *scsi_transfer_length = (guint32) \
+                         tvb_get_ntohs(tvb, tl_offset);
+                    ret = TRUE;
+                    break;
+
+               case 4:
+                    *scsi_transfer_length = tvb_get_ntohl(tvb, tl_offset);
+                    ret = TRUE;
+                    break;
+               default:
+                    break;
+               }
+               break;
+          }
+          i += 1;
+     }
+     return ret;
+}
+
+static iscsiexpert_fact
+scsi_cmd_read_write_tl_match_conclude(tvbuff_t *tvb, guint offset,
+                                      guint opcode, packet_info *pinfo,
+                                      iscsiexpert_conv_data_t * conv_data,
+                                      iscsiexpert_session_t *conn,
+                                      iscsiexpert_sessionset_t * sessset)
+{
+     guint32 iscsi_transfer_length, scsi_transfer_length;
+     guint8 scsi_opcode = tvb_get_guint8(tvb, offset+32);
+     iscsi_transfer_length = tvb_get_ntohl(tvb, offset+20);
+     offset += 32;
+     if (!get_cdb_transfer_length(tvb, offset, TRUE, &scsi_transfer_length))
+          return FACT_UNKNOWN;
+
+     if (scsi_transfer_length*512 == iscsi_transfer_length)
+          return FACT_TRUE;
+     else
+          return FACT_FALSE;
+}
+
+static iscsiexpert_fact
+scsi_cmd_non_read_write_tl_match_conclude(tvbuff_t *tvb, guint offset,
+                                          guint opcode, packet_info *pinfo,
+                                          iscsiexpert_conv_data_t * conv_data,
+                                          iscsiexpert_session_t *conn,
+                                          iscsiexpert_sessionset_t * sessset)
+{
+     guint32 iscsi_transfer_length, scsi_transfer_length;
+     guint8 scsi_opcode = tvb_get_guint8(tvb, offset+32);
+     iscsi_transfer_length = tvb_get_ntohl(tvb, offset+20);
+     offset += 32;
+     if (!get_cdb_transfer_length(tvb, offset, FALSE, &scsi_transfer_length))
+          return FACT_UNKNOWN;
+
+     if (scsi_transfer_length*512 == iscsi_transfer_length)
+          return FACT_TRUE;
+     else
+          return FACT_FALSE;
+}
+
+static iscsiexpert_fact
+scsi_cmd_is_write(tvbuff_t *tvb, guint offset, guint opcode,
+                  packet_info *pinfo,
+                  iscsiexpert_conv_data_t * conv_data,
+                  iscsiexpert_session_t *conn,
+                  iscsiexpert_sessionset_t * sessset)
+{
+     guint8 scsi_opcode=tvb_get_guint8(tvb, offset+32);
+     if (scsi_opcode == SCSI_SBC_WRITE6 || scsi_opcode == SCSI_SBC_WRITE10 ||\
+         scsi_opcode == SCSI_SBC_WRITE12 || scsi_opcode == SCSI_SBC_WRITE16)
+          return FACT_TRUE;
+     else
+          return FACT_FALSE;
+}
+
+static iscsiexpert_fact
+scsi_cmd_has_immediate_data(tvbuff_t *tvb, guint offset, guint opcode,
+                            packet_info *pinfo,
+                            iscsiexpert_conv_data_t * conv_data,
+                            iscsiexpert_session_t *conn,
+                            iscsiexpert_sessionset_t * sessset)
+{
+     guint32 dsl = tvb_get_ntoh24(tvb, offset+5);
+     if (dsl)
+          return FACT_TRUE;
+     else
+          return FACT_FALSE;
+}
+
+static iscsiexpert_fact
+scsi_cmd_read_r_bit_set(tvbuff_t *tvb, guint offset, guint opcode,
+                        packet_info *pinfo,
+                        iscsiexpert_conv_data_t * conv_data,
+                        iscsiexpert_session_t *conn,
+                        iscsiexpert_sessionset_t * sessset)
+{
+     guint8 scsi_opcode=tvb_get_guint8(tvb, offset+32);
+     if (scsi_opcode == SCSI_SBC_READ6 || scsi_opcode == SCSI_SBC_READ10 ||\
+         scsi_opcode == SCSI_SBC_READ12 || scsi_opcode == SCSI_SBC_READ16){
+          if (scsi_cmd_r_bit_set(tvb, offset, opcode,pinfo, conv_data, conn,
+                                 sessset))
+               return FACT_TRUE;
+          else
+               return FACT_FALSE;
+     }
+     return FACT_UNKNOWN;
+}
+
+static iscsiexpert_fact
+scsi_cmd_write_w_bit_set(tvbuff_t *tvb, guint offset, guint opcode,
+                         packet_info *pinfo,
+                         iscsiexpert_conv_data_t * conv_data,
+                         iscsiexpert_session_t *conn,
+                         iscsiexpert_sessionset_t * sessset)
+{
+     guint8 scsi_opcode=tvb_get_guint8(tvb, offset+32);
+     if (scsi_opcode == SCSI_SBC_WRITE6 || scsi_opcode == SCSI_SBC_WRITE10 ||\
+         scsi_opcode == SCSI_SBC_WRITE12 || scsi_opcode == SCSI_SBC_WRITE16){
+          if (scsi_cmd_w_bit_set(tvb, offset, opcode,pinfo, conv_data, conn,
+                                 sessset))
+               return FACT_TRUE;
+          else
+               return FACT_FALSE;
+     }
+     return FACT_UNKNOWN;
+}
+
+static iscsiexpert_fact
+data_digest_good(tvbuff_t *tvb, guint offset, guint opcode,
+                 packet_info *pinfo,
+                 iscsiexpert_conv_data_t * conv_data,
+                 iscsiexpert_session_t *conn,
+                 iscsiexpert_sessionset_t * sessset)
+{
+     guint8 ahs_len = 0, header_digest_len = 0;
+     guint32 dataLen = tvb_get_ntoh24(tvb, offset+5);
+     guint32 data_offset, available_bytes;
+     if (opcode == ISCSIEXPERT_OPCODE_SCSI_COMMAND)
+          ahs_len = tvb_get_guint8(tvb, offset+4);
+
+     if (ISCSIEXPERT_HEADER_DIGEST_CRC32 == conn->params.header_digest.value)
+          header_digest_len = 4;
+
+     data_offset = offset + 48 + ahs_len*4 + header_digest_len;
+     available_bytes = tvb_length_remaining(tvb, data_offset);
+
+     if(available_bytes >= (gint32)(dataLen + 4)) {
+          guint32 crc = ~calculate_crc32c(\
+               tvb_get_ptr(tvb, data_offset, dataLen), dataLen,
+               CRC32C_PRELOAD);
+          guint32 sent = tvb_get_ntohl(tvb, data_offset + dataLen);
+          if(crc == sent)
+               return FACT_TRUE;
+
+          else
+               return FACT_FALSE;
+     }
+
+     return FACT_UNKNOWN;
+}
+
+static iscsiexpert_fact
+header_digest_swapped_order_conclude(tvbuff_t *tvb, guint offset,
+                                     guint opcode, packet_info *pinfo,
+                                     iscsiexpert_conv_data_t * conv_data,
+                                     iscsiexpert_session_t *conn,
+                                     iscsiexpert_sessionset_t * sessset)
+{
+     gint available_bytes = tvb_length_remaining(tvb, offset);
+     gint32  headerLen = 48;
+
+     if(available_bytes >= (headerLen + 4)) {
+          guint32 crc = ~calculate_crc32c(tvb_get_ptr(tvb, offset, headerLen),
+                                          headerLen, CRC32C_PRELOAD);
+          guint32 sent = tvb_get_ntohl(tvb, offset + headerLen);
+          if((crc != sent) && (GUINT32_SWAP_LE_BE(sent) == crc)) {
+               return FACT_TRUE;
+          } else {
+               return FACT_FALSE;
+          }
+     }
+
+     return FACT_UNKNOWN;
+}
+
+
+static iscsiexpert_fact
+data_digest_swapped_order_conclude(tvbuff_t *tvb, guint offset, guint opcode,
+                              packet_info *pinfo,
+                              iscsiexpert_conv_data_t * conv_data,
+                              iscsiexpert_session_t *conn,
+                              iscsiexpert_sessionset_t * sessset)
+{
+     guint8 ahs_len = 0, header_digest_len = 0;
+     guint32 dataLen = tvb_get_ntoh24(tvb, offset+5);
+     guint32 data_offset, available_bytes;
+
+     if (opcode == ISCSIEXPERT_OPCODE_SCSI_COMMAND)
+          ahs_len = tvb_get_guint8(tvb, offset+4);
+
+     if (ISCSIEXPERT_HEADER_DIGEST_CRC32 == conn->params.header_digest.value)
+          header_digest_len = 4;
+
+     data_offset = offset + 48 + ahs_len*4 + header_digest_len;
+     available_bytes = tvb_length_remaining(tvb, data_offset);
+
+     if(available_bytes >= (gint32)(dataLen + 4)) {
+          guint32 crc = ~calculate_crc32c(\
+               tvb_get_ptr(tvb, data_offset, dataLen), dataLen,
+               CRC32C_PRELOAD);
+          guint32 sent = tvb_get_ntohl(tvb, data_offset + dataLen);
+          if((crc != sent) && (GUINT32_SWAP_LE_BE(sent) == crc))
+               return FACT_TRUE;
+
+          else
+               return FACT_FALSE;
+     }
+     return FACT_UNKNOWN;
+}
+
+static iscsiexpert_fact
+opcode_is_valid_conclude(tvbuff_t *tvb, guint offset,
+                         guint opcode, packet_info *pinfo,
+                         iscsiexpert_conv_data_t * conv_data,
+                         iscsiexpert_session_t *conn,
+                         iscsiexpert_sessionset_t * sessset)
+{
+     if (TRUE == opcode_is_valid(opcode))
+          return FACT_TRUE;
+     else
+          return FACT_FALSE;
+}
+
+static iscsiexpert_fact
+scsi_rsp_status_is_good_conclude(tvbuff_t *tvb, guint offset,
+                                 guint opcode, packet_info *pinfo,
+                                 iscsiexpert_conv_data_t * conv_data,
+                                 iscsiexpert_session_t *conn,
+                                 iscsiexpert_sessionset_t * sessset)
+{
+     guint8 status = tvb_get_guint8(tvb, offset+3);
+     if (status == 0x00 || status ==  0x02 || status == 0x08 ||
+         status == 0x18 || status == 0x28 || status == 0x30 || status == 0x40)
+          return FACT_TRUE;
+     else
+          return FACT_FALSE;
+}
+
+
+static iscsiexpert_fact
+expdatasn_match_response_conclude(tvbuff_t *tvb, guint offset,
+                                  guint opcode, packet_info *pinfo,
+                                  iscsiexpert_conv_data_t * conv_data,
+                                  iscsiexpert_session_t *conn,
+                                  iscsiexpert_sessionset_t * sessset)
+{
+     guint32 expdatasn = tvb_get_ntohl(tvb, offset+38);
+     guint8 response = tvb_get_guint8(tvb, offset+2);
+     iscsiexpert_fact ret = FACT_UNKNOWN;
+
+     if (response == 0x00 && expdatasn != 0x00)
+          ret = FACT_FALSE;
+     else
+          ret = FACT_TRUE;
+     return ret;
+}
+
+static iscsiexpert_fact
+data_buffer_retransmit_conclude(tvbuff_t *tvb, guint offset,
+                             guint opcode, packet_info *pinfo,
+                             iscsiexpert_conv_data_t * conv_data,
+                             iscsiexpert_session_t *conn,
+                             iscsiexpert_sessionset_t * sessset)
+{
+     guint32 buffer_offset = tvb_get_ntohl(tvb, offset+40);
+     if (opcode != ISCSIEXPERT_OPCODE_SCSI_DATA_IN &&
+         opcode != ISCSIEXPERT_OPCODE_SCSI_DATA_OUT)
+          return FACT_UNKNOWN;
+     else if (sessset->params.data_pdu_inorder.value) {
+          if (iscsiexpert_sna_lt(buffer_offset, conv_data->last_exp_bufferoffset))
+               return FACT_TRUE;
+     }
+     return FACT_FALSE;
+}
+
+static iscsiexpert_fact
+datasn_missing_conclude(tvbuff_t *tvb, guint offset,
+                            guint opcode, packet_info *pinfo,
+                            iscsiexpert_conv_data_t * conv_data,
+                            iscsiexpert_session_t *conn,
+                            iscsiexpert_sessionset_t * sessset)
+{
+     guint32 datasn = tvb_get_ntohl(tvb, offset+36);
+	 iscsipacket_conv_context_t *cdata_context = NULL;
+
+	 cdata_context = (iscsipacket_conv_context_t *)se_tree_lookup32(conv_data->contextq, (((pinfo->fd->num &0xFFFF) << 16) | (tvb->length  &0xFFFF)));
+	 DISSECTOR_ASSERT(cdata_context);
+
+     if (opcode != ISCSIEXPERT_OPCODE_SCSI_DATA_IN &&
+         opcode != ISCSIEXPERT_OPCODE_SCSI_DATA_OUT)
+          return FACT_UNKNOWN;
+     else if (sessset->params.data_pdu_inorder.value) {
+          if (iscsiexpert_sna_lt(datasn, cdata_context->lastdatasn))
+               return FACT_TRUE;
+     }
+     return FACT_FALSE;
+}
+
+static iscsiexpert_fact
+itt_reused_ok_conclude(tvbuff_t *tvb, guint offset,
+                          guint opcode, packet_info *pinfo,
+                          iscsiexpert_conv_data_t * conv_data,
+                          iscsiexpert_session_t *conn,
+                          iscsiexpert_sessionset_t * sessset)
+{
+     /* FIXME:
+      * XXX  PDUs now checked by this fact:
+      * XXX  LOGIN_COMMAND, SCSI_COMMAND, TASK_MANAGEMENT_FUNCTION,
+      * XXX  LOGOUT_COMMAND, SNACK_REQUEST.
+      * XXX  Others may be also needed, can be added later.
+      */
+     if (conv_data->new_created)
+          return FACT_TRUE;
+     else {
+          if (conv_data->task_done)
+               return FACT_TRUE;
+          else
+               return FACT_FALSE;
+     }
+}
+
+static iscsiexpert_fact
+conv_task_type_match_conclude(tvbuff_t *tvb, guint offset,
+                              guint opcode, packet_info *pinfo,
+                              iscsiexpert_conv_data_t * conv_data,
+                              iscsiexpert_session_t *conn,
+                              iscsiexpert_sessionset_t * sessset)
+{
+     switch (opcode) {
+     case ISCSIEXPERT_OPCODE_SCSI_RESPONSE:
+     case ISCSIEXPERT_OPCODE_SCSI_DATA_IN:
+     case ISCSIEXPERT_OPCODE_REJECT:
+          if (conv_data->init_opcode == ISCSIEXPERT_OPCODE_SCSI_COMMAND)
+               return FACT_TRUE;
+          else
+               return FACT_FALSE;
+     case ISCSIEXPERT_OPCODE_LOGIN_RESPONSE:
+          if (conv_data->init_opcode == ISCSIEXPERT_OPCODE_LOGIN_COMMAND)
+               return FACT_TRUE;
+          else
+               return FACT_FALSE;
+     case ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION_RESPONSE:
+          if (conv_data->init_opcode == ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION)
+               return FACT_TRUE;
+          else
+               return FACT_FALSE;
+     case ISCSIEXPERT_OPCODE_TEXT_RESPONSE:
+          if (conv_data->init_opcode == ISCSIEXPERT_OPCODE_TEXT_COMMAND)
+               return FACT_TRUE;
+          else
+               return FACT_FALSE;
+     case ISCSIEXPERT_OPCODE_LOGOUT_RESPONSE:
+          if (conv_data->init_opcode == ISCSIEXPERT_OPCODE_LOGOUT_COMMAND)
+               return FACT_TRUE;
+          else
+               return FACT_FALSE;
+     default:
+          return FACT_UNKNOWN;
+     }
+}
+
+static iscsiexpert_fact
+data_out_total_segmentlength_ok_conclude(tvbuff_t *tvb, guint offset,
+                                         guint opcode, packet_info *pinfo,
+                                         iscsiexpert_conv_data_t * conv_data,
+                                         iscsiexpert_session_t *conn,
+                                         iscsiexpert_sessionset_t * sessset)
+{
+     iscsiexpert_fact ret = FACT_UNKNOWN;
+     if (opcode == ISCSIEXPERT_OPCODE_SCSI_DATA_OUT) {
+          if (conv_data->data_out_total_transfer_leghth >
+              conv_data->r2t_desired_transfer_length)
+               ret = FACT_FALSE;
+          else
+               ret = FACT_TRUE;
+     }
+     return ret;
+}
+
+static iscsiexpert_fact
+data_out_r2t_match_conclude(tvbuff_t *tvb, guint offset,
+                           guint opcode, packet_info *pinfo,
+                           iscsiexpert_conv_data_t * conv_data,
+                           iscsiexpert_session_t *conn,
+                           iscsiexpert_sessionset_t * sessset)
+{
+     iscsiexpert_fact ret = FACT_UNKNOWN;
+     if (sessset->params.initial_r2t.value) {
+          if (conv_data->r2t_received)
+               ret = FACT_TRUE;
+          else
+               ret = FACT_FALSE;
+     }
+     return ret;
+}
+
+static iscsiexpert_fact
+r2t_r2tsn_outof_order_conclude(tvbuff_t *tvb, guint offset,
+                               guint opcode, packet_info *pinfo,
+                               iscsiexpert_conv_data_t * conv_data,
+                               iscsiexpert_session_t *conn,
+                               iscsiexpert_sessionset_t * sessset)
+{
+     iscsiexpert_fact ret = FACT_UNKNOWN;
+     guint32 r2tsn = tvb_get_ntohl(tvb, offset+36);
+     iscsipacket_conv_context_t *cdata_context = NULL;
+	 cdata_context = (iscsipacket_conv_context_t *) \
+          se_tree_lookup32(conv_data->contextq,
+              (((pinfo->fd->num &0xFFFF) << 16) | (tvb->length &0xFFFF)));
+	 DISSECTOR_ASSERT(cdata_context);
+     if ((cdata_context->last_r2tsn == 0xffffffff && r2tsn == 0) ||
+         cdata_context->last_r2tsn + 1 == r2tsn)
+          ret = FACT_FALSE;
+     else
+          ret = FACT_TRUE;
+
+     return ret;
+}
+
+static iscsiexpert_fact
+data_buffer_outof_order_conclude(tvbuff_t *tvb, guint offset,
+                                 guint opcode, packet_info *pinfo,
+                                 iscsiexpert_conv_data_t * conv_data,
+                                 iscsiexpert_session_t *conn,
+                                 iscsiexpert_sessionset_t * sessset)
+{
+     guint32 buffer_offset = tvb_get_ntohl(tvb, offset+40);
+     if (opcode != ISCSIEXPERT_OPCODE_SCSI_DATA_IN &&
+         opcode != ISCSIEXPERT_OPCODE_SCSI_DATA_OUT)
+          return FACT_UNKNOWN;
+     else if (sessset->params.data_pdu_inorder.value) {
+          if (buffer_offset > conv_data->last_exp_bufferoffset)
+               return FACT_TRUE;
+     }
+     return FACT_FALSE;
+}
+
+/* This fact should be applied to Initiator ONLY. */
+static iscsiexpert_fact
+cmdsn_outof_order_conclude(tvbuff_t *tvb, guint offset,
+                           guint opcode, packet_info *pinfo,
+                           iscsiexpert_conv_data_t * conv_data,
+                           iscsiexpert_session_t *conn,
+                           iscsiexpert_sessionset_t * sessset)
+{
+     iscsiexpert_fact ret = FACT_UNKNOWN;
+	 gboolean	i_bit;
+     guint32 cmdsn   = tvb_get_ntohl(tvb, offset + 24);
+     if (opcode > 0x1c)
+          return ret;
+
+	 /* I bit of previous PDU was not Set, CmdSN should be
+	 increased */
+	 i_bit = is_immediate_iscsi_cmd(tvb_get_guint8(tvb, offset + 0));
+
+
+//   if (opcode == ISCSIEXPERT_OPCODE_LOGIN_COMMAND) {
+//        /* Login Command: Leading Login can assign CmdSN as arbitrary
+//         * Number. CmdSN in a complete Login Command should be the same.
+//         */
+//        if ((pinfo->fd->num == sessset->init_fd) ||
+//            (pinfo->fd->num != sessset->init_fd &&
+//             conv_data->lastcmdsn == cmdsn))
+//             ret = FACT_FALSE;
+//        else
+//             ret = FACT_TRUE;
+//   }
+//   else{
+		 /* Other Commands: CmdSN should be increased by 1, if previous PDU did
+			not have I bit set. */
+         if (conv_data->prev_i_bit){
+			   /* I bit of previous PDU was set, CmdSN
+					should be the same with previous*/
+		 
+			   if (conv_data->lastcmdsn == cmdsn)
+					ret = FACT_FALSE;
+			   else{
+					ret = FACT_TRUE;
+			   }
+		  }
+		 else { 
+			   if (i_bit) {
+				    if (conv_data->lastcmdsn == cmdsn)
+						ret = FACT_FALSE;
+					else{
+						ret = FACT_TRUE;
+					}
+			   }else {
+					if (conv_data->lastcmdsn + 1 == cmdsn)
+						ret = FACT_FALSE;
+					else{
+						ret = FACT_TRUE;
+					}
+			   }
+		  }
+	//}
+
+	if (ret == FACT_TRUE) {
+			  ISCSIE_DEBUG("frame number: %d,conv_data->lastcmdsn = %d, cmdsn = %d,prev_i_bit = %s ,i_bit = %s\n",
+								pinfo->fd->num,
+								conv_data->lastcmdsn,
+								cmdsn,
+								conv_data->prev_i_bit?"YES":"No",
+								i_bit?"YES":"No");
+	}
+    return ret;
+}
+
+static iscsiexpert_fact
+login_c_t_both_set_conclude(tvbuff_t *tvb, guint offset,
+                         guint opcode, packet_info *pinfo,
+                         iscsiexpert_conv_data_t * conv_data,
+                         iscsiexpert_session_t *conn,
+                         iscsiexpert_sessionset_t * sessset)
+{
+     iscsiexpert_fact ret = FACT_UNKNOWN;
+     if ((opcode == ISCSIEXPERT_OPCODE_LOGIN_COMMAND) ||
+         (opcode == ISCSIEXPERT_OPCODE_LOGIN_RESPONSE)) {
+          if ((tvb_get_guint8(tvb, offset+1) & 0x80) > 7 &&
+              (tvb_get_guint8(tvb, offset+1) & 0x40) > 6)
+               ret = FACT_TRUE;
+          else
+               ret = FACT_FALSE;
+     }
+     return ret;
+}
+
+static iscsiexpert_fact
+scsi_cmd_f_bit_set_conclude(tvbuff_t *tvb, guint offset,
+                            guint opcode, packet_info *pinfo,
+                            iscsiexpert_conv_data_t * conv_data,
+                            iscsiexpert_session_t *conn,
+                            iscsiexpert_sessionset_t * sessset)
+{
+     iscsiexpert_fact ret = FACT_UNKNOWN;
+     if (opcode == ISCSIEXPERT_OPCODE_SCSI_COMMAND) {
+          if ((tvb_get_guint8(tvb, offset+1) & 0x80) > 7)
+               ret = FACT_TRUE;
+          else
+               ret = FACT_FALSE;
+     }
+     return ret;
+}
+
+static iscsiexpert_fact
+statsn_out_of_order_conclude(tvbuff_t *tvb, guint offset,
+                             guint opcode, packet_info *pinfo,
+                             iscsiexpert_conv_data_t * conv_data,
+                             iscsiexpert_session_t *conn,
+                             iscsiexpert_sessionset_t * sessset)
+{
+     iscsiexpert_fact ret = FACT_UNKNOWN;
+     iscsipacket_conv_context_t *cdata_context = NULL;
+     guint32 statsn;
+
+     cdata_context = (iscsipacket_conv_context_t *)\
+          se_tree_lookup32(conv_data->contextq,
+          (((pinfo->fd->num &0xFFFF) << 16) | (tvb->length &0xFFFF)));
+     DISSECTOR_ASSERT(cdata_context);
+
+    if (opcode == ISCSIEXPERT_OPCODE_SCSI_DATA_IN){
+          if (conv_data->has_snack == TRUE)
+               return FACT_UNKNOWN;
+          else {
+        guint8 s_bit = tvb_get_guint8(tvb, offset+1) & 0x01;
+        if (!s_bit){
+        /*  RFC10.7.3 The fields StatSN, Status, and Residual Count only have
+            meaningful content if the S bit is set to 1 and their values are
+            defined in Section 10.4 SCSI Response. */
+            return FACT_FALSE;
+        }
+          }
+    }else if(opcode == ISCSIEXPERT_OPCODE_LOGIN_RESPONSE){
+        guint8 status_class = tvb_get_guint8(tvb, offset+36);
+        /* For the first Login Response (the response to the first Login
+           Request), this is the starting status Sequence Number for the
+           connection. The next response of any kind, including the next Login
+           Response, if any, in the same Login Phase, will carry this number +
+           1. This field is only valid if the Status-Class is 0.  */
+        if (status_class){
+            return FACT_FALSE;
+        }
+
+        if (cdata_context->first_login_response){
+            return FACT_FALSE;
+        }
+    }
+
+    statsn = tvb_get_ntohl(tvb, offset + 24);
+    if (statsn != cdata_context->laststatsn + 1)
+          return FACT_TRUE;
+     else
+          return FACT_FALSE;
+}
+
+static iscsiexpert_fact
+r2t_number_normal_conclude(tvbuff_t *tvb, guint offset,
+                              guint opcode, packet_info *pinfo,
+                              iscsiexpert_conv_data_t * conv_data,
+                              iscsiexpert_session_t *conn,
+                              iscsiexpert_sessionset_t * sessset)
+{
+     iscsiexpert_fact ret = FACT_UNKNOWN;
+     iscsipacket_conv_context_t *cdata_context = NULL;
+	 cdata_context = (iscsipacket_conv_context_t *)\
+          se_tree_lookup32(conv_data->contextq,
+                 (((pinfo->fd->num &0xFFFF) << 16) | (tvb->length &0xFFFF)));
+	 DISSECTOR_ASSERT(cdata_context);
+
+     if (cdata_context->pending_r2t <= sessset->params.max_outstand_r2t.value)
+          ret = FACT_TRUE;
+     else
+          ret = FACT_FALSE;
+
+     return ret;
+}
+
+
+
+
+
+
+
+/* Fact Base */
+static iscsiexpert_factbase iscsi_factbase[] = {
+     {0, NULL,"good iscsi packet"},
+     {1, &header_digest_good_conclude,"the embedded CRC32 Header Digest for the iSCSI BHS is incorrect for the data in the BHS header"},
+     {2, &datasn_mismatch_conclude,"datasn is not match"},
+     {3, &expdatasn_gt_highestdatasn_conclude,"the Expected DataSN value in the response is one higher than the highest DataSN received"},
+     {4, &statsn_lt_expstatsn_conclude,"the Target sends a PDU with a StatSN value that is less than the last received ExpStatSN value from the Initiator."},
+     {5, &cmdsn_gt_maxcmdsn_conclude,"the Initiator sends a PDU with a CmdSN value that is larger than the last received MaxCmdSN value from the Target"},
+     {6, &csg_not_valid_conclude, " the CSG is not a valid value"},
+     {7, &nsg_not_valid_conclude, " the NSG is not a valid value"},
+     {8, &nsg_not_reserved_conclude, " the NSG is not reserved while T was 0"},
+     {9, &login_key_invalid, "Key used in Login Command is not valid key"},
+     {10, &login_key_invalid, "Key used in Login Response is not valid key"},
+     {11, &login_kv_pair_inavlid, "Key-Value pair used in Login Command is missing \"=\""},
+     {12, &login_kv_pair_inavlid, "Key-Value pair used in Login Response is missing \"=\""},
+     {13, &login_value_inavlid, "Value used in Login Command is null or empty"},
+     {14, &login_value_inavlid, "Value used in Login Response is null or empty"},
+     {15, &reject_bad_reason, "Reason used in Reject PDU is reserved vale (0x01)"},
+     {16, &task_mgmt_rsp_bad_response, "Task management response is reserved value"},
+     {17, &async_msg_bad_event, "Async Event in Async Message is reserved value"},
+     {18, &logout_cmd_bad_reason, "Reason code in Logout Command PDU is reserved"},
+     {19, &logout_rsp_bad_response, "Response code in Logout Response is reserved"},
+     {20, &scsi_cmd_r_bit_set, "Read bit in Command PDU is set"},
+     {21, &scsi_cmd_w_bit_set, "Write bit in Command PDU is set"},
+     {22, &task_mgmt_cmd_bad_function, "Function in Task Management Command is reserved "},
+     {23, &scsi_rsp_bad_response, "Response value in SCSI Response PDU is reserved"},
+     {24, &scsi_rsp_status_is_zero, "Status of iSCSI Response is zero"},
+     {25, &scsi_rsp_resopnse_is_zero, "Response of iSCSI Response is zero"},
+     {26, &snack_cmd_type_invalid, "Type in SNACK Command is not valid"},
+     {27, &data_in_status_is_zero, "Status in Data-In PDU is zero."},
+     {28, &read_write_tl_is_zero, "Length of Expected Data in Write/Read Command is zero"},
+     {29, &scsi_cmd_read_write_tl_match_conclude, "Transfer Length in iSCSI PDU and CDB (Read and Write) are the same"},
+     {30, &scsi_cmd_is_write, "SCSI Command is Write Command"},
+     {31, &scsi_cmd_has_immediate_data, "SCSI Command has Immediate Data associated"},
+     {32, &scsi_cmd_read_r_bit_set, "R-Bit in Read Command is Set"},
+     {33, &scsi_cmd_write_w_bit_set, "W-Bit in Write Command is Set"},
+     {34, &data_digest_good, "Data Digest is good"},
+     {35, &header_digest_swapped_order_conclude, "Head Digest is stored as  Little Endian"},
+     {36, &data_digest_swapped_order_conclude, "Head Digest is stored as  Little Endian"},
+     {37, &scsi_cmd_non_read_write_tl_match_conclude, "Transfer Length in  iSCSI PDU and CDB (Non Read or Write) are the same"},
+     {38, &opcode_is_valid_conclude, "Opcode is valid value"},
+     {39, &scsi_rsp_status_is_good_conclude, "Status in SCSI Response is Good"},
+     {40, &expdatasn_match_response_conclude, "ExpDataSN and resonse in SCSI Response is match"},
+     {41, &data_buffer_retransmit_conclude, "Bufffer of Data-In/Data-Out is larger than the Expected"},
+     {42, &datasn_missing_conclude, "DataSN is missing or out of order"},
+     {43, &itt_reused_ok_conclude, "Task identified by ITT has been finished"},
+     {44, &conv_task_type_match_conclude, "Task Type match in a conversation"},
+     {45, &data_out_total_segmentlength_ok_conclude, "Total transfer leghth of Data-Out smaller than the R2T expected."},
+     {46, &data_out_r2t_match_conclude, "Data Out was sent after R2T received by Initiator"},
+     {47, &r2t_r2tsn_outof_order_conclude, "R2TSN is missing or out of order"},
+     {48, &data_buffer_outof_order_conclude, "Buffer offset of Data-In/Out is missing or out of order"},
+     {49, &cmdsn_outof_order_conclude, "CmdSN in PUD was not increased by its order."},
+     {50, &login_c_t_both_set_conclude, "C bit and T bit are both set in Login PDUs"},
+     {51, &scsi_cmd_f_bit_set_conclude, "SCSI Command has F bit set"},
+     {52, &statsn_out_of_order_conclude, "StatSN was not increased by order"},
+     {53, &r2t_number_normal_conclude, "Number of Outstanding R2T is normal"},
+};
+
+static iscsiexpert_resultbase iscsi_resultbase[] = {
+     {0,0,0, "Good iSCSI Packet"},
+     {1,48,4, "Bad iSCSI Header Digest CRC"},
+     {2,36,4, "Exchange - Missing or Out of Order DataSN"}, /* Deleted */
+     {3,24,4, "StatSN less than ExpStatSN"},
+     {4,24,4, "CmdSN greater than MaxCmdSN"},
+     {5,1,1, "Login Command CSG/NSG Bad Value"},
+     {6,1,1, "Login Response CSG/NSG Bad Value"},
+     {7,0,48, "Login Command Bad Login Key"},
+     {8,0,48, "Login Response Bad Login Key"},
+     {9,0,48, "Login Command Bad Login Key-Value Pair"},
+     {10,0,48, "Login Response Bad Login Key-Value Pair"},
+     {11,0,48, "Login Command Bad Login Value"},
+     {12,0,48, "Login Response Bad Login Value"},
+     {13,2,1, "Bad Reject Reason"},
+     {14,2,1, "Task Management Response Bad Value"},
+     {15,36,2, "Async Message Bad value"},
+     {16,1,1, "Logout Command Bad Reason"},
+     {17,2,1, "Logout Response Bad Response"},
+     {18,2,1, "Command PDU Read and Write bits both set"},
+     {19,1,1, "Task Management Request Bad Value"},
+     {20,2,1, "SCSI Response Bad response value"},
+     {21,0,48, "Illegal Status combined with iSCSI Response"},
+     {22,1,1, "SNACK Request Bad request type"},
+     {23,3,1, "Data-In status is not zero"},
+     {24,20,4, "Expected Data Transfer Length is 0"},
+     {25,20,16, "Transfer Length in iSCSI PDU and CDB (Read/Write) are not the same"},
+     {26,0,48, "Bad Immediate Data Out"},
+     {27,1,1, "Mismatched R/W Bits"},
+     {28,0,0, "Bad iSCSI Data Digest CRC"},
+     {29,48,0, "Incorrectly Swapped iSCSI Header Digest CRC"},
+     {30,0,0, "Incorrectly Swapped iSCSI Data Digest CRC"},
+     {31,0,0, "Byte Length Mismatch in CDB (Non Read/Write) and PDU Transfer Length"},
+     {32,0,1, "Invalid PDU Opcode For Device Type"},
+     {33,3,1, "Target 2 Initiator: Bad Status Value"},
+     {34,36,4, "Mismatched ExpDataSN and SCSI Response code"},
+     {35,40,4, "Retransmitted Data Segment"},  /* Deleted */
+     {36,36,4, "Retransmitted DataSN Sequence"},  /* Deleted */
+     {37,16, 4, "Initiator Task Tag re-used while still pending"},
+     {38,0,1, "Completion Type doesn't match original Task type"},
+     {39,5,3, "Over-Run of allowed bytes in R2T"},
+     {40, 0,48, "Data Out when R2T expected"},
+     {41,36,1, "Missing or Out of Order R2TSN"},
+     {42,40,4, "Missing or Out of Order Data Segment"},  /* Deleted */
+     {43,24,4, "Missing or Out of Order CmdSN"},
+     {44,1,1, " Login: Mismatched C bit and T bit"},
+     {45,1,1, " SCSI Command: Mismatched F bit and W bit"},
+     {46,24,4, "Missing or Out of Order StatSN"},
+     {47,0,48, "R2T when Data Out expected"},
+};
+
+
+static iscsiexpert_knowledgebased iscsi_knowbase[] = {
+     {0,  {0, 0}},
+     {1, {{FACT_FALSE_OR,1}, {0,0}}},
+     {2, {{FACT_TRUE_OR,2}, {FACT_FALSE_OR, 3}, {0,0}}},
+     {3, {{FACT_TRUE_OR,4}, {0,0}}},
+     {4, {{FACT_TRUE_OR,5}, {0,0}}},
+     {5, {{FACT_TRUE_OR,6},{FACT_TRUE_OR,7}, {0,0}}},
+     {6, {{FACT_TRUE_OR,6},{FACT_TRUE_OR,7},{FACT_TRUE_OR,8}, {0,0}}},
+     {7, {{FACT_TRUE_OR,9}, {0,0}}},
+     {8, {{FACT_TRUE_OR,10}, {0,0}}},
+     {9, {{FACT_TRUE_OR,11}, {0,0}}},
+     {10, {{FACT_TRUE_OR,12}, {0,0}}},
+     {11, {{FACT_TRUE_OR,13}, {0,0}}},
+     {12, {{FACT_TRUE_OR,14}, {0,0}}},
+     {13, {{FACT_TRUE_OR,15}, {0,0}}},
+     {14, {{FACT_TRUE_OR,16}, {0,0}}},
+     {15, {{FACT_TRUE_OR,17}, {0,0}}},
+     {16, {{FACT_TRUE_OR,18}, {0,0}}},
+     {17, {{FACT_TRUE_OR,19}, {0,0}}},
+     {18, {{FACT_TRUE_OR,20},{FACT_TRUE_AND,21}, {0,0}}},
+     {19, {{FACT_TRUE_OR,22}, {0,0}}},
+     {20, {{FACT_TRUE_OR,23}, {0,0}}},
+     {21, {{FACT_TRUE_OR,24}, {FACT_TRUE_AND,25}, {0,0}}},
+     {22, {{FACT_TRUE_OR,26}, {0,0}}},
+     {23, {{FACT_FALSE_OR, 27}, {0,0}}},
+     {24, {{FACT_TRUE_OR, 28}, {0,0}}},
+     {25, {{FACT_FALSE_OR, 29}, {0,0}}},
+     {26, {{FACT_FALSE_OR, 30}, {FACT_FALSE_OR,21},{FACT_TRUE_AND,31},{0,0}}},
+     {27, {{FACT_FALSE_OR, 32}, {FACT_FALSE_OR, 33}, {0,0}}},
+     {28, {{FACT_FALSE_OR, 34}, {0,0}}},
+     {29, {{FACT_TRUE_OR, 35}, {0,0}}},
+     {30, {{FACT_TRUE_OR, 36}, {0,0}}},
+     {31, {{FACT_FALSE_OR, 37}, {0,0}}},
+     {32, {{FACT_FALSE_OR, 38}, {0,0}}},
+     {33, {{FACT_FALSE_OR, 39}, {0,0}}},
+     {34, {{FACT_FALSE_OR, 40}, {0,0}}},
+     {35, {{FACT_TRUE_OR, 41}, {0,0}}},
+     {36, {{FACT_TRUE_OR, 42}, {0,0}}},
+     {37, {{FACT_FALSE_OR, 43}, {0,0}}},
+     {38, {{FACT_FALSE_OR, 44}, {0,0}}},
+     {39, {{FACT_FALSE_OR, 45}, {0,0}}},
+     {40, {{FACT_FALSE_OR, 46}, {0,0}}},
+     {41, {{FACT_TRUE_OR, 47}, {0,0}}},
+     {42, {{FACT_TRUE_OR, 48}, {0,0}}},
+     {43, {{FACT_TRUE_OR, 49}, {0,0}}},
+     {44, {{FACT_TRUE_OR, 50}, {0,0}}},
+     {45, {{FACT_FALSE_OR, 51}, {FACT_FALSE_AND, 21}, {0,0}}},
+     {46, {{FACT_TRUE_OR, 52}, {0,0}}},
+     {47, {{FACT_FALSE_OR, 53}, {0,0}}},
+};
+
+#define MAX_FACT_NUM     sizeof(iscsi_factbase)/sizeof(iscsi_factbase[0])
+#define MAX_RULES_NUM    sizeof(iscsi_resultbase)/sizeof(iscsi_resultbase[0])
+
+
+/* Function :get_rule_set
+   Description: classify the rules based on opcode, in order to speed up
+   knowbase_query.
+   Return: classified rule set.
+*/
+GSList *
+get_rule_set(tvbuff_t *tvb, guint opcode, packet_info *pinfo,
+             iscsiexpert_conv_data_t * conv_data,iscsiexpert_session_t *conn,
+             iscsiexpert_sessionset_t * sessset)
+{
+     //header digest
+     GSList  * ruleset_list = NULL;
+     if (ISCSIEXPERT_HEADER_DIGEST_CRC32 == conn->params.header_digest.value) {
+          /* the rule id 1 is header digest and the iscsi packet is not
+             LOGIN CMD or LOGIN RESPONSE */
+          if ((opcode != ISCSIEXPERT_OPCODE_LOGIN_COMMAND)
+              && (opcode != ISCSIEXPERT_OPCODE_LOGIN_RESPONSE))
+          {
+               ruleset_list = g_slist_append (ruleset_list,
+                                              GINT_TO_POINTER (1));
+               ruleset_list = g_slist_append (ruleset_list,
+                                              GINT_TO_POINTER (29));
+          }
+     }
+
+     switch(opcode) {
+     case ISCSIEXPERT_OPCODE_SCSI_DATA_OUT:
+          /* ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (2)); */
+		  if (ISCSIEXPERT_HEADER_DIGEST_CRC32 == conn->params.data_digest.value){
+			  ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (28));
+		  }
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (30));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (33));
+          /* ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (35)); */
+          /* ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (36)); */
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (39));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (40));
+/*           ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (42)); */
+          break;
+     case ISCSIEXPERT_OPCODE_SCSI_DATA_IN:
+          /* ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (2)); */
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (23));
+		  if (ISCSIEXPERT_HEADER_DIGEST_CRC32 == conn->params.data_digest.value){
+			  ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (28));
+		  }
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (30));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (33));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (46));
+/*           ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (35)); */
+          /* ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (36)); */
+/*           ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (42)); */
+          break;
+     case ISCSIEXPERT_OPCODE_LOGIN_COMMAND:
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (5));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (7));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (9));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER(11));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER(43));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER(44));
+          break;
+     case ISCSIEXPERT_OPCODE_LOGIN_RESPONSE:
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (6));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (8));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (10));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (12));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER(44));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (46));
+          break;
+     case ISCSIEXPERT_OPCODE_REJECT:
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (13));
+          break;
+     case ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION:
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (19));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER(43));
+          break;
+     case ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION_RESPONSE:
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (14));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (46));
+          break;
+     case ISCSIEXPERT_OPCODE_ASYNC_MESSAGE:
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (15));
+		  if (ISCSIEXPERT_HEADER_DIGEST_CRC32 == conn->params.data_digest.value){
+			  ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (28));
+		  }
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (30));
+          break;
+     case ISCSIEXPERT_OPCODE_LOGOUT_COMMAND:
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (16));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER(43));
+          break;
+     case ISCSIEXPERT_OPCODE_LOGOUT_RESPONSE:
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (17));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (46));
+          break;
+     case ISCSIEXPERT_OPCODE_SCSI_COMMAND:
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (18));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (24));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (25));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (26));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (27));
+		  if (ISCSIEXPERT_HEADER_DIGEST_CRC32 == conn->params.data_digest.value){
+			  ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (28));
+		  }
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (30));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (31));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER(43));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER(45));
+          break;
+     case ISCSIEXPERT_OPCODE_SCSI_RESPONSE:
+          /* ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (2)); */
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (20));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (21));
+		  if (ISCSIEXPERT_HEADER_DIGEST_CRC32 == conn->params.data_digest.value){
+			  ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (28));
+		  }
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (30));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (33));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (34));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (46));
+          break;
+     case ISCSIEXPERT_OPCODE_SNACK_REQUEST:
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (22));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (37));
+          break;
+     case ISCSIEXPERT_OPCODE_R2T:
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (41));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (46));
+          ruleset_list = g_slist_append(ruleset_list, GINT_TO_POINTER (47));
+          break;
+     }
+
+     if (TRUE == opcode_is_valid(opcode)){
+          if (TRUE == iscsiexpert_is_iscsirsp(opcode)){
+               ruleset_list = g_slist_append(ruleset_list,GINT_TO_POINTER(3));
+          }else{
+               ruleset_list = g_slist_append(ruleset_list,GINT_TO_POINTER(4));
+          }
+     }else{
+          ruleset_list = g_slist_append (ruleset_list, GINT_TO_POINTER (32));
+     }
+
+     return ruleset_list;
+}
+
+gint rule_result_compare(gconstpointer a,gconstpointer b){
+	iscsiexpert_rule_result *rule_result_a = (iscsiexpert_rule_result *) a;
+	gint offset = GPOINTER_TO_INT( b);
+
+	if (rule_result_a->offset == offset) {
+		return 0;
+	}
+
+	return rule_result_a->offset < offset? -1 : 1;
+
+}
+
+
+GSList *
+iscsi_knowbase_query(tvbuff_t *tvb, guint offset, guint opcode,
+                     packet_info *pinfo, iscsiexpert_conv_data_t *conv_data,
+                     iscsiexpert_session_t *conn,
+                     iscsiexpert_sessionset_t * sessset)
+{
+     iscsiexpert_fact    cur_fact_list[MAX_FACT_NUM];    //record the cur fact
+     iscsiexpert_fact    cur_fact = FACT_UNKNOWN;
+     gint32      i = 0;
+     gint32      j = 0;
+     gint32      resultid = 0;
+     GSList      * rule_set_list = NULL;
+     GSList      * expert_list       = NULL;
+	 GSList		 * result_list		 = NULL;
+     GSList      * item = NULL;
+	 iscsiexpert_rule_result	* rule_result = NULL;
+
+     memset(cur_fact_list,FACT_INIT,sizeof(cur_fact_list));
+
+     rule_set_list = get_rule_set(tvb,opcode,pinfo,conv_data,conn,sessset);
+
+     for (item = rule_set_list; item; item = g_slist_next(item)) {
+          i = GPOINTER_TO_UINT(item->data);
+          j = 0;
+          cur_fact = FACT_UNKNOWN; //set the cur_fact TRUE when the rule begins.
+          while (iscsi_knowbase[i].rule_condition_list[j].factid != 0
+                 && j < MAX_FACT_NUM)  {
+               iscsiexpert_rule_condition cur_condition =\
+                    iscsi_knowbase[i].rule_condition_list[j];
+
+               if (cur_fact_list[cur_condition.factid] == FACT_INIT) {
+                    // calculate factid through calling handler.
+                    cur_fact_list[cur_condition.factid] = \
+                         iscsi_factbase[cur_condition.factid].fact_conclude\
+                         (tvb,offset,opcode,pinfo,conv_data,conn,sessset);
+               }
+
+               /* if (j == 0) { */
+               /*      cur_fact = cur_fact_list[cur_condition.factid]; */
+               /* } */
+
+               switch(cur_condition.type ) {
+               case FACT_TRUE_AND:
+                    //cur_fact & cur_fact_list[cur_condition.factid].
+                    if (cur_fact_list[cur_condition.factid] != FACT_TRUE) {
+                         cur_fact = FACT_FALSE;
+                    }
+
+                    break;
+               case FACT_TRUE_OR:
+                    //cur_fact | cur_fact_list[cur_condition.factid].
+                    if (cur_fact_list[cur_condition.factid] == FACT_TRUE) {
+                         cur_fact = FACT_TRUE;
+                    }
+                    break;
+               case FACT_FALSE_AND:
+                    //cur_fact & !cur_fact_list[cur_condition.factid].
+                    if (cur_fact_list[cur_condition.factid] != FACT_FALSE) {
+                         cur_fact = FACT_FALSE;
+                    }
+                    break;
+               case FACT_FALSE_OR:
+                    //cur_fact | !cur_fact_list[cur_condition.factid].
+                    if (cur_fact_list[cur_condition.factid] == FACT_FALSE) {
+                         cur_fact = FACT_TRUE;
+                    }
+                    break;
+               default:
+                    cur_fact = FACT_FALSE;
+                    break;
+               }
+
+               //query the next rule condition
+               j ++;
+          }
+
+          if (cur_fact == FACT_TRUE)
+          {
+               //find the rule and break
+			   rule_result = g_malloc(sizeof(iscsiexpert_rule_result));
+			   rule_result->result_id = iscsi_knowbase[i].result_id;
+			   rule_result->offset    = iscsi_resultbase[i].start;
+			   rule_result->length	  = iscsi_resultbase[i].length;
+               result_list = g_slist_append (result_list, rule_result);
+               //break;
+          }
+
+     }
+
+	 g_slist_free(rule_set_list);
+     expert_list = g_slist_sort(result_list,rule_result_compare);
+	 return expert_list;
+}
+
+void iscsiexpert_free_expertlist(GSList * expert_list)
+{
+	GSList * list = expert_list;
+	while (list)
+	{
+		g_free(list->data);
+		list = g_slist_next(list);
+	}
+
+	g_slist_free(expert_list);
+}
+
+
diff -urN wireshark-1.2.2/epan/dissectors/packet-iscsiexpert.c wireshark-1.2.2-iscsie/epan/dissectors/packet-iscsiexpert.c
--- wireshark-1.2.2/epan/dissectors/packet-iscsiexpert.c	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/epan/dissectors/packet-iscsiexpert.c	2010-01-20 16:41:24.000000000 +0800
@@ -0,0 +1,5561 @@
+/* packet-iscsiexpert.c
+ * Routines for iSCSI Expert dissection
+ * Copyright 2009, Ji-dong Wang <Wang.ji-dong@xxxxxxxxxxxxxx>
+ * 				   Qian Zhang <Zhang.qian@xxxxxxxxxxxxxx>
+ * 				   Ying-chao Yang <Yang.ying-chao@xxxxxxxxxxxxxx>
+ * 				   Cang-mou Cao	<Cao.cang-mou@xxxxxxxxxxxxxx>
+ * 				   Xing-jia	Wang <Wang.xing-jia@xxxxxxxxxxxxxx>
+ *
+ * $Id: packet-iscsiexpert.c 28363 2009-05-14 19:28:07Z etxrab $
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ * 
+ * Copied from packet-iscsi.c
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <epan/packet.h>
+#include <epan/prefs.h>
+#include <epan/conversation.h>
+#include <epan/iscsisession.h>
+//#include "packet-scsi.h"
+#include "packet-iscsiexpert.h"
+#include "epan/nstime.h"
+#include <epan/emem.h>
+#include <epan/crc32.h>
+#include <epan/tap.h>
+#include <epan/dissectors/packet-tcp.h>
+
+/* William, 10-2009, iscsi expert */
+#include <epan/expert.h>
+#include "iscsiexpert-rules.c"
+
+/*Add by ZQ*/
+extern GHashTable *iscsisession_hashtable;
+extern GHashTable *conversation_hashtable_exact;
+iscsiexpert_sess_tv_t sess_tv;
+
+void proto_reg_handoff_iscsiexpert(void);
+
+/* the absolute values of these constants don't matter as long as
+ * latter revisions of the protocol are assigned a larger number */
+#define ISCSIEXPERT_PROTOCOL_DRAFT08 1
+#define ISCSIEXPERT_PROTOCOL_DRAFT09 2
+#define ISCSIEXPERT_PROTOCOL_DRAFT11 3
+#define ISCSIEXPERT_PROTOCOL_DRAFT12 4
+#define ISCSIEXPERT_PROTOCOL_DRAFT13 5
+
+static enum_val_t iscsiexpert_protocol_versions[] = {
+	 { "draft-08", "Draft 08", ISCSIEXPERT_PROTOCOL_DRAFT08 },
+	 { "draft-09", "Draft 09", ISCSIEXPERT_PROTOCOL_DRAFT09 },
+	 { "draft-11", "Draft 11", ISCSIEXPERT_PROTOCOL_DRAFT11 },
+	 { "draft-12", "Draft 12", ISCSIEXPERT_PROTOCOL_DRAFT12 },
+	 { "draft-13", "Draft 13", ISCSIEXPERT_PROTOCOL_DRAFT13 },
+	 { NULL, NULL, 0 }
+};
+
+static const value_string ahs_type_vals[] = {
+	 {1, "Extended CDB"},
+	 {2, "Expected Bidirection Read Data Length"},
+	 {0, NULL}
+};
+
+
+static guint conn_index;
+
+static dissector_handle_t iscsiexpert_handle=NULL;
+
+static gint iscsiexpert_protocol_version = ISCSIEXPERT_PROTOCOL_DRAFT13;
+
+static gboolean iscsiexpert_desegment = TRUE;
+
+static int demand_good_f_bit = FALSE;
+static int enable_bogosity_filter = TRUE;
+static guint32 bogus_pdu_data_length_threshold = 256 * 1024;
+
+static int enableDataDigests = FALSE;
+
+static int dataDigestIsCRC32 = TRUE;
+
+static guint dataDigestSize = 4;
+
+static guint iscsiexpert_port = 3260;
+
+/* Initialize the protocol and registered fields */
+static int proto_iscsiexpert = -1;
+
+static int iscsiexpert_tap = -1;
+static int iscsiexpert_tap_analyzer = -1;
+static int iscsiexpert_tap_sesstv = -1;
+
+
+static int hf_iscsiexpert_time = -1;
+static int hf_iscsiexpert_request_frame = -1;
+static int hf_iscsiexpert_data_in_frame = -1;
+static int hf_iscsiexpert_data_out_frame = -1;
+static int hf_iscsiexpert_response_frame = -1;
+static int hf_iscsiexpert_AHS = -1;
+static int hf_iscsiexpert_AHS_length = -1;
+static int hf_iscsiexpert_AHS_type = -1;
+static int hf_iscsiexpert_AHS_blob = -1;
+static int hf_iscsiexpert_AHS_read_data_length = -1;
+static int hf_iscsiexpert_AHS_extended_cdb = -1;
+static int hf_iscsiexpert_Padding = -1;
+static int hf_iscsiexpert_ping_data = -1;
+static int hf_iscsiexpert_immediate_data = -1;
+static int hf_iscsiexpert_write_data = -1;
+static int hf_iscsiexpert_read_data = -1;
+static int hf_iscsiexpert_error_pdu_data = -1;
+static int hf_iscsiexpert_async_event_data = -1;
+static int hf_iscsiexpert_vendor_specific_data = -1;
+static int hf_iscsiexpert_Opcode = -1;
+static int hf_iscsiexpert_Flags = -1;
+static int hf_iscsiexpert_HeaderDigest32 = -1;
+static int hf_iscsiexpert_DataDigest = -1;
+static int hf_iscsiexpert_DataDigest32 = -1;
+/* #ifdef DRAFT08 */
+static int hf_iscsiexpert_X = -1;
+/* #endif */
+static int hf_iscsiexpert_I = -1;
+static int hf_iscsiexpert_SCSICommand_F = -1;
+static int hf_iscsiexpert_SCSICommand_R = -1;
+static int hf_iscsiexpert_SCSICommand_W = -1;
+static int hf_iscsiexpert_SCSICommand_Attr = -1;
+static int hf_iscsiexpert_SCSICommand_CRN = -1;
+static int hf_iscsiexpert_SCSICommand_AddCDB = -1;
+static int hf_iscsiexpert_DataSegmentLength = -1;
+static int hf_iscsiexpert_TotalAHSLength = -1;
+static int hf_iscsiexpert_LUN = -1;
+static int hf_iscsiexpert_InitiatorTaskTag = -1;
+static int hf_iscsiexpert_ExpectedDataTransferLength = -1;
+static int hf_iscsiexpert_CmdSN = -1;
+static int hf_iscsiexpert_ExpStatSN = -1;
+static int hf_iscsiexpert_StatSN = -1;
+static int hf_iscsiexpert_ExpCmdSN = -1;
+static int hf_iscsiexpert_MaxCmdSN = -1;
+static int hf_iscsiexpert_SCSIResponse_o = -1;
+static int hf_iscsiexpert_SCSIResponse_u = -1;
+static int hf_iscsiexpert_SCSIResponse_O = -1;
+static int hf_iscsiexpert_SCSIResponse_U = -1;
+static int hf_iscsiexpert_SCSIResponse_BidiReadResidualCount = -1;
+static int hf_iscsiexpert_SCSIResponse_ResidualCount = -1;
+static int hf_iscsiexpert_SCSIResponse_Response = -1;
+static int hf_iscsiexpert_SCSIResponse_Status = -1;
+static int hf_iscsiexpert_SenseLength = -1;
+static int hf_iscsiexpert_SCSIData_F = -1;
+static int hf_iscsiexpert_SCSIData_A = -1;
+static int hf_iscsiexpert_SCSIData_S = -1;
+static int hf_iscsiexpert_SCSIData_O = -1;
+static int hf_iscsiexpert_SCSIData_U = -1;
+static int hf_iscsiexpert_TargetTransferTag = -1;
+static int hf_iscsiexpert_DataSN = -1;
+static int hf_iscsiexpert_BufferOffset = -1;
+static int hf_iscsiexpert_SCSIData_ResidualCount = -1;
+static int hf_iscsiexpert_VersionMin = -1;
+static int hf_iscsiexpert_VersionMax = -1;
+static int hf_iscsiexpert_VersionActive = -1;
+static int hf_iscsiexpert_CID = -1;
+static int hf_iscsiexpert_ISID8 = -1;
+static int hf_iscsiexpert_ISID = -1;
+/* #if defined(DRAFT09) */
+static int hf_iscsiexpert_ISID_Type = -1;
+static int hf_iscsiexpert_ISID_NamingAuthority = -1;
+static int hf_iscsiexpert_ISID_Qualifier = -1;
+/* #elif !defined(DRAFT08) */
+static int hf_iscsiexpert_ISID_t = -1;
+static int hf_iscsiexpert_ISID_a = -1;
+static int hf_iscsiexpert_ISID_b = -1;
+static int hf_iscsiexpert_ISID_c = -1;
+static int hf_iscsiexpert_ISID_d = -1;
+/* #endif */
+static int hf_iscsiexpert_TSID = -1;
+static int hf_iscsiexpert_TSIH = -1;
+static int hf_iscsiexpert_InitStatSN = -1;
+static int hf_iscsiexpert_InitCmdSN = -1;
+/* #ifdef DRAFT09 */
+static int hf_iscsiexpert_Login_X = -1;
+/* #endif */
+static int hf_iscsiexpert_Login_C = -1;
+static int hf_iscsiexpert_Login_T = -1;
+static int hf_iscsiexpert_Login_CSG = -1;
+static int hf_iscsiexpert_Login_NSG = -1;
+static int hf_iscsiexpert_Login_Status = -1;
+static int hf_iscsiexpert_KeyValue = -1;
+static int hf_iscsiexpert_Text_C = -1;
+static int hf_iscsiexpert_Text_F = -1;
+static int hf_iscsiexpert_ExpDataSN = -1;
+static int hf_iscsiexpert_R2TSN = -1;
+static int hf_iscsiexpert_TaskManagementFunction_ReferencedTaskTag = -1;
+static int hf_iscsiexpert_RefCmdSN = -1;
+static int hf_iscsiexpert_TaskManagementFunction_Function = -1;
+static int hf_iscsiexpert_TaskManagementFunction_Response = -1;
+static int hf_iscsiexpert_Logout_Reason = -1;
+static int hf_iscsiexpert_Logout_Response = -1;
+static int hf_iscsiexpert_Time2Wait = -1;
+static int hf_iscsiexpert_Time2Retain = -1;
+static int hf_iscsiexpert_DesiredDataLength = -1;
+static int hf_iscsiexpert_AsyncEvent = -1;
+static int hf_iscsiexpert_EventVendorCode = -1;
+static int hf_iscsiexpert_Parameter1 = -1;
+static int hf_iscsiexpert_Parameter2 = -1;
+static int hf_iscsiexpert_Parameter3 = -1;
+static int hf_iscsiexpert_Reject_Reason = -1;
+static int hf_iscsiexpert_snack_type = -1;
+static int hf_iscsiexpert_BegRun = -1;
+static int hf_iscsiexpert_RunLength = -1;
+
+static int hf_expert_msg = -1;
+static int hf_expert_group = -1;
+static int hf_expert_severity = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_iscsiexpert = -1;
+static gint ett_iscsiexpert_KeyValues = -1;
+static gint ett_iscsiexpert_CDB = -1;
+static gint ett_iscsiexpert_Flags = -1;
+/* #ifndef DRAFT08 */
+static gint ett_iscsiexpert_ISID = -1;
+
+static int ett_expert = -1;
+static int ett_subexpert = -1;
+
+static const value_string iscsiexpert_opcodes[] = {
+	 { ISCSIEXPERT_OPCODE_NOP_OUT,							"NOP Out" },
+	 { ISCSIEXPERT_OPCODE_SCSI_COMMAND,						"SCSI Command" },
+	 { ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION,			"Task Management Function" },
+	 { ISCSIEXPERT_OPCODE_LOGIN_COMMAND,						"Login Command" },
+	 { ISCSIEXPERT_OPCODE_TEXT_COMMAND,						"Text Command" },
+	 { ISCSIEXPERT_OPCODE_SCSI_DATA_OUT,						"SCSI Data Out" },
+	 { ISCSIEXPERT_OPCODE_LOGOUT_COMMAND,					"Logout Command" },
+	 { ISCSIEXPERT_OPCODE_SNACK_REQUEST,						"SNACK Request" },
+	 { ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I0,				"Vendor Specific I0" },
+	 { ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I1,				"Vendor Specific I1" },
+	 { ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I2,				"Vendor Specific I2" },
+
+	 { ISCSIEXPERT_OPCODE_NOP_IN,							"NOP In" },
+	 { ISCSIEXPERT_OPCODE_SCSI_RESPONSE,						"SCSI Response" },
+	 { ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION_RESPONSE, "Task Management Function Response" },
+	 { ISCSIEXPERT_OPCODE_LOGIN_RESPONSE,					"Login Response" },
+	 { ISCSIEXPERT_OPCODE_TEXT_RESPONSE,						"Text Response" },
+	 { ISCSIEXPERT_OPCODE_SCSI_DATA_IN,						"SCSI Data In" },
+	 { ISCSIEXPERT_OPCODE_LOGOUT_RESPONSE,					"Logout Response" },
+	 { ISCSIEXPERT_OPCODE_R2T,								"Ready To Transfer" },
+	 { ISCSIEXPERT_OPCODE_ASYNC_MESSAGE,						"Asynchronous Message" },
+	 { ISCSIEXPERT_OPCODE_REJECT,							"Reject"},
+	 { ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T0,				"Vendor Specific T0" },
+	 { ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T1,				"Vendor Specific T1" },
+	 { ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T2,				"Vendor Specific T2" },
+	 {0, NULL},
+};
+
+/* #ifdef DRAFT08 */
+static const true_false_string iscsiexpert_meaning_X = {
+	 "Retry",
+	 "Not retry"
+};
+/* #endif */
+
+/* #ifdef DRAFT09 */
+static const true_false_string iscsiexpert_meaning_login_X = {
+	 "Reinstate failed connection",
+	 "New connection"
+};
+/* #endif */
+
+static const true_false_string iscsiexpert_meaning_I = {
+	 "Immediate delivery",
+	 "Queued delivery"
+};
+
+static const true_false_string iscsiexpert_meaning_F = {
+	 "Final PDU in sequence",
+	 "Not final PDU in sequence"
+};
+
+static const true_false_string iscsiexpert_meaning_A = {
+	 "Acknowledge requested",
+	 "Acknowledge not requested"
+};
+
+static const true_false_string iscsiexpert_meaning_T = {
+	 "Transit to next login stage",
+	 "Stay in current login stage"
+};
+
+static const true_false_string iscsiexpert_meaning_C = {
+	 "Text is incomplete",
+	 "Text is complete"
+};
+
+static const true_false_string iscsiexpert_meaning_S = {
+	 "Response contains SCSI status",
+	 "Response does not contain SCSI status"
+};
+
+static const true_false_string iscsiexpert_meaning_R = {
+	 "Data will be read from target",
+	 "No data will be read from target"
+};
+
+static const true_false_string iscsiexpert_meaning_W = {
+	 "Data will be written to target",
+	 "No data will be written to target"
+};
+
+static const true_false_string iscsiexpert_meaning_o = {
+	 "Read part of bi-directional command overflowed",
+	 "No overflow of read part of bi-directional command",
+};
+
+static const true_false_string iscsiexpert_meaning_u = {
+	 "Read part of bi-directional command underflowed",
+	 "No underflow of read part of bi-directional command",
+};
+
+static const true_false_string iscsiexpert_meaning_O = {
+	 "Residual overflow occurred",
+	 "No residual overflow occurred",
+};
+
+static const true_false_string iscsiexpert_meaning_U = {
+	 "Residual underflow occurred",
+	 "No residual underflow occurred",
+};
+
+static const value_string iscsiexpert_scsi_responses[] = {
+	 { 0, "Command completed at target" },
+	 { 1, "Response does not contain SCSI status"},
+	 { 0, NULL }
+};
+
+static const value_string iscsiexpert_scsicommand_taskattrs[] = {
+	 {0, "Untagged"},
+	 {1, "Simple"},
+	 {2, "Ordered"},
+	 {3, "Head of Queue"},
+	 {4, "ACA"},
+	 {0, NULL},
+};
+
+static const value_string iscsiexpert_task_management_responses[] = {
+	 {0, "Function complete"},
+	 {1, "Task not in task set"},
+	 {2, "LUN does not exist"},
+	 {3, "Task still allegiant"},
+	 {4, "Task failover not supported"},
+	 {5, "Task management function not supported"},
+	 {6, "Authorisation failed"},
+	 {255, "Function rejected"},
+	 {0, NULL},
+};
+
+static const value_string iscsiexpert_task_management_functions[] = {
+	 {1, "Abort Task"},
+	 {2, "Abort Task Set"},
+	 {3, "Clear ACA"},
+	 {4, "Clear Task Set"},
+	 {5, "Logical Unit Reset"},
+	 {6, "Target Warm Reset"},
+	 {7, "Target Cold Reset"},
+	 {8, "Target Reassign"},
+	 {0, NULL},
+};
+
+static const value_string iscsiexpert_login_status[] = {
+	 {0x0000, "Success"},
+	 {0x0101, "Target moved temporarily"},
+	 {0x0102, "Target moved permanently"},
+	 {0x0200, "Initiator error (miscellaneous error)"},
+	 {0x0201, "Authentication failed"},
+	 {0x0202, "Authorisation failure"},
+	 {0x0203, "Target not found"},
+	 {0x0204, "Target removed"},
+	 {0x0205, "Unsupported version"},
+	 {0x0206, "Too many connections"},
+	 {0x0207, "Missing parameter"},
+	 {0x0208, "Can't include in session"},
+	 {0x0209, "Session type not supported"},
+	 {0x020a, "Session does not exist"},
+	 {0x020b, "Invalid request during login"},
+	 {0x0300, "Target error (miscellaneous error)"},
+	 {0x0301, "Service unavailable"},
+	 {0x0302, "Out of resources"},
+	 {0, NULL},
+};
+
+static const value_string iscsiexpert_login_stage[] = {
+	 {0, "Security negotiation"},
+	 {1, "Operational negotiation"},
+	 {3, "Full feature phase"},
+	 {0, NULL},
+};
+
+/* #ifndef DRAFT08 */
+static const value_string iscsiexpert_isid_type[] = {
+	 {0x00, "IEEE OUI"},
+	 {0x01, "IANA Enterprise Number"},
+	 {0x02, "Random"},
+	 {0, NULL},
+};
+/* #endif */
+
+static const value_string iscsiexpert_logout_reasons[] = {
+	 {0, "Close session"},
+	 {1, "Close connection"},
+	 {2, "Remove connection for recovery"},
+	 {0, NULL},
+};
+
+static const value_string iscsiexpert_logout_response[] = {
+	 {0, "Connection closed successfully"},
+	 {1, "CID not found"},
+	 {2, "Connection recovery not supported"},
+	 {3, "Cleanup failed for various reasons"},
+	 {0, NULL},
+};
+
+static const value_string iscsiexpert_asyncevents[] = {
+	 {0, "A SCSI asynchronous event is reported in the sense data"},
+	 {1, "Target requests logout"},
+	 {2, "Target will/has dropped connection"},
+	 {3, "Target will/has dropped all connections"},
+	 {4, "Target requests parameter negotiation"},
+	 {0, NULL},
+};
+
+static const value_string iscsiexpert_snack_types[] = {
+	 {0, "Data/R2T"},
+	 {1, "Status"},
+	 /* #ifndef DRAFT08 */
+	 {2, "Data ACK"},
+	 /* #endif */
+	 {3, "R-Data"},
+	 {0, NULL}
+};
+
+static const value_string iscsiexpert_reject_reasons[] = {
+	 /* #ifdef DRAFT08 */
+	 {0x01, "Full feature phase command before login"},
+	 /* #endif */
+	 {0x02, "Data (payload) digest error"},
+	 {0x03, "Data SNACK reject"},
+	 {0x04, "Protocol error"},
+	 {0x05, "Command not supported in this session type"},
+	 {0x06, "Immediate command reject (too many immediate commands)"},
+	 {0x07, "Task in progress"},
+	 {0x08, "Invalid Data Ack"},
+	 {0x09, "Invalid PDU field"},
+	 {0x0a, "Long operation reject"},
+	 {0x0b, "Negotiation reset"},
+	 {0x0c, "Waiting for logout"},
+	 {0, NULL},
+};
+
+/*key-value pair negotiate status*/
+enum{
+	 KEY_VALUE_NO_NEGO = 0,
+	 KEY_VALUE_NEGO,
+	 KEY_VALUE_DONE_NEGO,
+	 KEY_VALUE_REPLY_NEGO,
+};
+
+enum{
+	 RES_MIN = 0,
+	 RES_MAX,
+	 RES_AND,
+	 RES_OR,
+	 RES_LIST,
+	 RES_MARKER,
+	 RES_NONE,
+};
+
+#define DIGEST_NONE (1 << 0)
+#define DIGEST_CRC32C (1 << 1)
+#define DIGEST_ALL (DIGEST_NONE | DIGEST_CRC32C)
+#define DIGESET_REJECT (1 << 2)
+#define DIGEST_NOTUNDERSTOOD (1 << 3)
+#define DIGEST_IRRELEVANT (1 << 4)
+
+#define AUTHMETHOD_NONE		(1 << 0)
+#define AUTHMETHOD_CHAP		(1 << 1)
+#define AUTHMETHOD_SRP		(1 << 2)
+#define AUTHMETHOD_SPKM2	(1 << 3)
+#define AUTHMETHOD_SPKM1	(1 << 4)
+#define AUTHMETHOD_KRB5		(1 << 5)
+#define AUTHMETHOD_ALL		(AUTHMETHOD_NONE | AUTHMETHOD_CHAP |	\
+							 AUTHMETHOD_SRP | AUTHMETHOD_SPKM2 |	\
+							 AUTHMETHOD_SPKM1 | AUTHMETHOD_KRB5)
+#define AUTHMETHOD_REJECT	(1 << 6)
+#define AUTHMETHOD_NOTUNDERSTOOD (1 << 7)
+#define AUTHMETHOD_IRRELEVANT (1 << 8)
+
+enum{
+    MAXCONNECTIONS_FLAG  = 0x1001,
+    INITIALR2T_FLAG,
+    IMMEDIATEDATA_FLAG,
+    MAXBURSTLENGTH_FLAG,
+    FIRSTBURSTLENGTH_FLAG,
+    DEFAULTTIME2WAIT_FLAG,
+    DEFAULTTIME2RETAIN_FLAG,
+    MAXOUTSTANDINGR2T_FLAG,
+    DATAPDUINORDER_FLAG,
+    DATASEQUENCEINORDER_FLAG,
+    ERRORRECOVERYLEVEL_FLAG,
+
+    HEADERDIGEST_FLAG,
+    DATADIGEST_FLAG,
+    MAXRECVDATASEGMENTLENGTH_FLAG,
+    MAXXMITDATASEGMENTLENGTH_FLAG,
+    AUTHMETHOD_FLAG,
+    OFMARKER_FLAG,
+    IFMARKER_FLAG,
+    OFMARKINT_FLAG,
+    IFMARKINT_FLAG,
+
+
+    ALL_PARAMS,
+};
+
+#undef  MAX
+#define MAX(x,y) ((x) > (y) ? (x) : (y))
+
+iscsi_key_t session_keys[] = {
+     {"MaxConnections",
+       MAXCONNECTIONS_FLAG,
+       1, 1, 65535, 0, 0,
+       KEY_VALUE_NO_NEGO,
+       TRUE, RES_MIN, NULL, NULL},
+
+     {"InitialR2T",
+       INITIALR2T_FLAG,
+       1, 0, 1, 0, 0,
+       KEY_VALUE_NO_NEGO,
+       TRUE, RES_OR, NULL, NULL},
+
+     {"ImmediateData",
+       IMMEDIATEDATA_FLAG,
+       1, 0, 1, 0, 0,
+       KEY_VALUE_NO_NEGO,
+       TRUE, RES_AND, NULL, NULL},
+
+     {"MaxBurstLength",
+       MAXBURSTLENGTH_FLAG,
+       262144, 512, 16777215, 0, 0,
+       KEY_VALUE_NO_NEGO,
+       TRUE, RES_MIN, NULL, NULL},
+
+     {"FirstBurstLength",
+       FIRSTBURSTLENGTH_FLAG,
+       262144, 512, 16777215, 0, 0,
+       KEY_VALUE_NO_NEGO,
+       TRUE, RES_MIN, NULL, NULL},
+
+     {"DefaultTime2Wait",
+       DEFAULTTIME2WAIT_FLAG,
+       2, 0, 3600, 0, 0,
+       KEY_VALUE_NO_NEGO,
+       TRUE, RES_MAX, NULL, NULL},
+
+     {"DefaultTime2Retain",
+       DEFAULTTIME2RETAIN_FLAG,
+       20, 0, 3600, 0, 0,
+       KEY_VALUE_NO_NEGO,
+       TRUE, RES_MIN, NULL, NULL},
+
+     {"MaxOutstandingR2T",
+       MAXOUTSTANDINGR2T_FLAG,
+       1, 1, 65535, 0, 0,
+       KEY_VALUE_NO_NEGO,
+       TRUE, RES_MIN, NULL, NULL},
+
+     {"DataPDUInOrder",
+       DATAPDUINORDER_FLAG,
+       1, 0, 1, 0, 0,
+       KEY_VALUE_NO_NEGO,
+       TRUE, RES_OR, NULL, NULL},
+
+     {"DataSequenceInOrder",
+       DATASEQUENCEINORDER_FLAG,
+       1, 0, 1, 0, 0,
+       KEY_VALUE_NO_NEGO,
+       TRUE, RES_OR, NULL, NULL},
+
+     {"ErrorRecoveryLevel",
+       ERRORRECOVERYLEVEL_FLAG,
+       0, 0, 2, 0, 0,
+       KEY_VALUE_NO_NEGO,
+       TRUE, RES_MIN, NULL, NULL},
+
+     {NULL},
+};
+
+iscsi_key_t connection_keys[] = {
+     {"HeaderDigest",
+       HEADERDIGEST_FLAG,
+       DIGEST_NONE, DIGEST_CRC32C, DIGEST_ALL, 0, 0,
+       KEY_VALUE_NO_NEGO,
+       TRUE, RES_LIST, NULL, NULL},
+
+     {"DataDigest",
+       DATADIGEST_FLAG,
+       DIGEST_NONE, DIGEST_CRC32C, DIGEST_ALL, 0, 0,
+       KEY_VALUE_NO_NEGO,
+       TRUE, RES_LIST, NULL, NULL},
+
+     {"MaxRecvDataSegmentLength",
+       MAXRECVDATASEGMENTLENGTH_FLAG,
+       8192, 512, 16777215, 0, 0,
+       KEY_VALUE_NO_NEGO,
+       TRUE, RES_NONE, NULL, NULL},
+
+     {"MaxXmitDataSegmentLength",
+       MAXXMITDATASEGMENTLENGTH_FLAG,
+       8192, 512, 16777215, 0, 0,
+       KEY_VALUE_NO_NEGO,
+       FALSE, RES_NONE, NULL, NULL},
+
+     {"AuthMethod",
+       AUTHMETHOD_FLAG,
+       AUTHMETHOD_NONE, AUTHMETHOD_CHAP, AUTHMETHOD_ALL, 0, 0,
+       KEY_VALUE_NO_NEGO,
+       TRUE, RES_LIST, NULL, NULL},
+
+     {"OFMarker", 
+       OFMARKER_FLAG, 
+       0, 0, 1, 0, 0, 
+       KEY_VALUE_NO_NEGO, 
+       TRUE, RES_AND, NULL, NULL},
+              
+     {"OFMarkInt", 
+       OFMARKINT_FLAG,
+       2048, 1, 65535, 0, 0, 
+       KEY_VALUE_NO_NEGO, 
+       TRUE, RES_MARKER, NULL, NULL},
+
+     {"IFMarker", 
+       IFMARKER_FLAG,
+       0, 0, 1, 0, 0, 
+       KEY_VALUE_NO_NEGO, 
+       TRUE, RES_AND, NULL, NULL},
+       
+     {"OFMarkInt", 
+       IFMARKINT_FLAG, 
+       2048, 1, 65535, 0, 0, 
+       KEY_VALUE_NO_NEGO, 
+       TRUE, RES_MARKER, NULL, NULL},
+       
+     {NULL},
+};
+
+#define SESSION_KEYS_NUM	sizeof(session_keys)/sizeof(session_keys[0])
+#define CONNECTION_KEY_NUM	sizeof(connection_keys)/sizeof(connection_keys[0])
+
+static int
+iscsiexpert_min(int a, int b) {
+	 return (a < b)? a : b;
+}
+
+static gint
+addTextKeys(proto_tree *tt, tvbuff_t *tvb, gint offset, guint32 text_len) {
+	 const gint limit = offset + text_len;
+	 while(offset < limit) {
+		  gint len = tvb_strnlen(tvb, offset, limit - offset);
+		  if(len == -1)
+			   len = limit - offset;
+		  else
+			   len = len + 1;
+		  proto_tree_add_item(tt, hf_iscsiexpert_KeyValue, tvb, offset, len, FALSE);
+		  offset += len;
+	 }
+	 return offset;
+}
+
+static gint
+handleHeaderDigest(iscsiexpert_session_t *iscsiexpert_session, proto_item *ti, tvbuff_t *tvb, guint offset, int headerLen) {
+	 int available_bytes = tvb_length_remaining(tvb, offset);
+
+    switch(iscsiexpert_session->params.header_digest.value){
+	 case ISCSIEXPERT_HEADER_DIGEST_CRC32:
+		  if(available_bytes >= (headerLen + 4)) {
+			   guint32 crc = ~calculate_crc32c(tvb_get_ptr(tvb, offset, headerLen), headerLen, CRC32C_PRELOAD);
+			   guint32 sent = tvb_get_ntohl(tvb, offset + headerLen);
+			   if(crc == sent) {
+					proto_tree_add_uint_format(ti, hf_iscsiexpert_HeaderDigest32, tvb, offset + headerLen, 4, sent, "HeaderDigest: 0x%08x (Good CRC32)", sent);
+			   } else {
+					proto_tree_add_uint_format(ti, hf_iscsiexpert_HeaderDigest32, tvb, offset + headerLen, 4, sent, "HeaderDigest: 0x%08x (Bad CRC32, should be 0x%08x)", sent, crc);
+			   }
+		  }
+		  return offset + headerLen + 4;
+	 }
+
+	 return offset + headerLen;
+}
+
+static gint
+handleDataDigest(proto_item *ti, tvbuff_t *tvb, guint offset, int dataLen) {
+	 int available_bytes = tvb_length_remaining(tvb, offset);
+	 if(enableDataDigests) {
+		  if(dataDigestIsCRC32) {
+			   if(available_bytes >= (dataLen + 4)) {
+					guint32 crc = ~calculate_crc32c(tvb_get_ptr(tvb, offset, dataLen), dataLen, CRC32C_PRELOAD);
+					guint32 sent = tvb_get_ntohl(tvb, offset + dataLen);
+					if(crc == sent) {
+						 proto_tree_add_uint_format(ti, hf_iscsiexpert_DataDigest32, tvb, offset + dataLen, 4, sent, "DataDigest: 0x%08x (Good CRC32)", sent);
+					}
+					else {
+						 proto_tree_add_uint_format(ti, hf_iscsiexpert_DataDigest32, tvb, offset + dataLen, 4, sent, "DataDigest: 0x%08x (Bad CRC32, should be 0x%08x)", sent, crc);
+					}
+			   }
+			   return offset + dataLen + 4;
+		  }
+		  if((unsigned)available_bytes >= (dataLen + dataDigestSize)) {
+			   proto_tree_add_item(ti, hf_iscsiexpert_DataDigest, tvb, offset + dataLen, dataDigestSize, FALSE);
+		  }
+		  return offset + dataLen + dataDigestSize;
+	 }
+	 return offset + dataLen;
+}
+
+static int
+handleDataSegment(proto_item *ti, tvbuff_t *tvb, guint offset, guint dataSegmentLen, guint endOffset, int hf_id) {
+	 if(endOffset > offset) {
+		  int dataOffset = offset;
+		  int dataLen = iscsiexpert_min(dataSegmentLen, endOffset - offset);
+		  if(dataLen > 0) {
+			   proto_tree_add_item(ti, hf_id, tvb, offset, dataLen, FALSE);
+			   offset += dataLen;
+		  }
+		  if(offset < endOffset && (offset & 3) != 0) {
+			   int padding = 4 - (offset & 3);
+			   proto_tree_add_item(ti, hf_iscsiexpert_Padding, tvb, offset, padding, FALSE);
+			   offset += padding;
+		  }
+		  if(dataSegmentLen > 0 && offset < endOffset)
+			   offset = handleDataDigest(ti, tvb, dataOffset, offset - dataOffset);
+	 }
+
+	 return offset;
+}
+
+static int
+handleDataSegmentAsTextKeys(proto_item *ti, tvbuff_t *tvb, guint offset, guint dataSegmentLen, guint endOffset, int digestsActive) {
+	 if(endOffset > offset) {
+		  int dataOffset = offset;
+		  int textLen = iscsiexpert_min(dataSegmentLen, endOffset - offset);
+		  if(textLen > 0) {
+			   proto_item *tf = proto_tree_add_text(ti, tvb, offset, textLen, "Key/Value Pairs");
+			   proto_tree *tt = proto_item_add_subtree(tf, ett_iscsiexpert_KeyValues);
+			   offset = addTextKeys(tt, tvb, offset, textLen);
+		  }
+		  if(offset < endOffset && (offset & 3) != 0) {
+			   int padding = 4 - (offset & 3);
+			   proto_tree_add_item(ti, hf_iscsiexpert_Padding, tvb, offset, padding, FALSE);
+			   offset += padding;
+		  }
+		  if(digestsActive && dataSegmentLen > 0 && offset < endOffset)
+			   offset = handleDataDigest(ti, tvb, dataOffset, offset - dataOffset);
+	 }
+	 return offset;
+}
+
+/* set's the PI_ flags to a protocol item
+ * (and it's parent items till the toplevel) */
+static void
+iscsiexpert_set_item_flags(proto_item *pi, int group, int severity)
+{
+
+	 if(proto_item_set_expert_flags(pi, group, severity)) {
+		  /* propagate till toplevel item */
+		  pi = proto_item_get_parent(pi);
+		  iscsiexpert_set_item_flags(pi, group, severity);
+	 }
+}
+
+static proto_tree*
+iscsiexpert_create_tree(tvbuff_t * tvb,proto_item *pi,
+						int group, int severity,
+						const gint start, const gint length,const char *msg)
+{
+	 proto_tree *tree;
+	 proto_item *ti;
+
+	 tree = proto_item_add_subtree(pi, ett_expert);
+	 ti = proto_tree_add_protocol_format(tree, proto_iscsiexpert, tvb, start,
+										 length, "iSCSI Expert Info (%s/%s): %s",
+										 val_to_str(severity, expert_severity_vals, "?%u?"),
+										 val_to_str(group, expert_group_vals, "?%u?"),
+										 msg);
+	 PROTO_ITEM_SET_GENERATED(ti);
+
+	 return proto_item_add_subtree(ti, ett_subexpert);
+}
+
+void iscsiexpert_add_packetdetail(
+        packet_info *pinfo, tvbuff_t * tvb, proto_item *pi, int group,
+        int severity,guint8 opcode, iscsiexpert_session_t * conn,
+		const gchar * msg, const gint start, const gint length)
+{
+    proto_tree	*tree;
+	proto_item	*ti;
+
+	tree = iscsiexpert_create_tree(tvb,pi, group, severity, 0,0, msg);
+    iscsiexpert_set_item_flags(tree,group,severity);
+    ti = proto_tree_add_string(tree, hf_expert_msg, tvb, 0, 0, msg);
+    PROTO_ITEM_SET_GENERATED(ti);
+    iscsiexpert_set_item_flags(ti,group,severity);
+    PROTO_ITEM_SET_GENERATED(ti);
+    ti = proto_tree_add_uint(tree, hf_expert_severity, NULL, 0, 0, severity);
+    PROTO_ITEM_SET_GENERATED(ti);
+    ti = proto_tree_add_uint(tree, hf_expert_group, NULL, 0, 0, group);
+    PROTO_ITEM_SET_GENERATED(ti);
+
+    /* if we have a proto_item (not a faked item), set expert attributes to it */
+    if(pi != NULL && pi->finfo != NULL) {
+        pi = proto_item_get_parent(pi);
+        iscsiexpert_set_item_flags(pi, group, severity);
+    }
+
+}
+
+void
+iscsiexpert_add_info_to_analyzer_tap(
+	 packet_info *pinfo, tvbuff_t * tvb, proto_item *pi, int group,
+	 int severity,guint8 opcode, iscsiexpert_session_t * conn,
+	 const gchar * msg, const gint start, const gint length)
+{
+	 iscsiexpert_expertdata_info_t	* eti = NULL;
+
+	 eti = ep_alloc(sizeof(iscsiexpert_expertdata_info_t));
+
+	 eti->packet_num = pinfo->fd->num;
+	 eti->opcode		= opcode;
+	 eti->pitem		= NULL;
+
+	 if (TRUE == iscsiexpert_is_iscsirsp(opcode)){
+		  eti->direction	= TRUE;
+	 }
+	 else{
+		  eti->direction	= FALSE;
+	 }
+	 eti->protocol	= ep_strdup(pinfo->current_proto);
+	 eti->conn = conn;
+
+	 eti->group		= group;
+	 eti->severity	= severity;
+	 eti->summary	= se_strdup(msg);
+
+	if(pi != NULL && pi->finfo != NULL) {
+        eti->pitem       = pi;
+    }
+
+    /* we queue this packet to the tap system */
+    tap_queue_packet(iscsiexpert_tap_analyzer, pinfo, eti);
+
+	iscsiexpert_add_packetdetail(pinfo,tvb,pi,group,severity,
+								 opcode,conn,msg,start,length);
+}
+
+//void
+//add_iscsiexpert_knowbase(tvbuff_t *tvb, proto_item *pi,guint offset, guint opcode,
+//                     packet_info *pinfo, iscsiexpert_conv_data_t *conv_data,
+//                     iscsiexpert_session_t *conn,
+//                     iscsiexpert_sessionset_t *sess)
+//{
+//    GSList * item = NULL;
+//    GSList * expert_list = NULL;
+//    guint32   index;
+//
+//    expert_list = iscsi_knowbase_query(tvb,offset,opcode,pinfo,conv_data,conn,sess);
+//
+//    if (0 < g_slist_length(expert_list)){
+//            for (index = 0,item = expert_list; item; index++, item = g_slist_next(item)){
+//                    //find a expert rule.
+//                    iscsiexpert_rule_result * rule_result = ((iscsiexpert_rule_result *)item->data);
+//                    iscsiexpert_resultbase * resulebase = &iscsi_resultbase[rule_result->result_id];
+//
+//                    iscsiexpert_add_info_to_analyzer_tap(pinfo,tvb,pi, PI_MALFORMED, PI_ERROR, opcode,conn,
+//                                  resulebase->result_name,
+//                                  offset + rule_result->offset,
+//                                  resulebase->length);
+//            }
+//
+//            iscsiexpert_free_expertlist(expert_list);
+//
+//   }
+//
+//}
+
+void
+iscsiexpert_add_expert_info(GSList * expert_list, guint32 offset,guint32 length,
+							packet_info *pinfo, tvbuff_t * tvb, proto_item *pi,
+							guint8 opcode, iscsiexpert_session_t * conn)
+{
+	GSList * item =   g_slist_find_custom(expert_list,GINT_TO_POINTER(offset),rule_result_compare);
+	if (item){
+		iscsiexpert_rule_result * rule_result = (iscsiexpert_rule_result *)item->data;
+		iscsiexpert_resultbase  * resulebase  = &iscsi_resultbase[rule_result->result_id];
+
+		if (rule_result->length != length) {
+			ISCSIE_DEBUG("rule_result length %d is less than the request length %d: packet number: %d, offset %d rule_name: %s\n",
+							rule_result->length,length,
+		 					pinfo->fd->num,
+							offset,
+							resulebase->result_name);
+		}
+
+		iscsiexpert_add_info_to_analyzer_tap(pinfo,tvb,pi, PI_MALFORMED, PI_ERROR, opcode,conn,
+									resulebase->result_name,
+									rule_result->offset,
+									rule_result->length);
+	}
+}
+
+static void init_session_keys(iscsiexpert_sessionset_t *iscsiexpert_sessionset)
+{
+	 iscsiexpert_sessionset->session_keys = se_alloc(sizeof(session_keys));
+	 memset(iscsiexpert_sessionset->session_keys, 0, sizeof(session_keys));
+	 memcpy(iscsiexpert_sessionset->session_keys, &session_keys, sizeof(session_keys));
+}
+
+static void init_connection_keys(iscsiexpert_session_t *iscsiexpert_session)
+{
+     iscsiexpert_session->connection_keys = se_alloc(sizeof(connection_keys));
+     memset(iscsiexpert_session->connection_keys, 0, sizeof(connection_keys));
+     memcpy(iscsiexpert_session->connection_keys, &connection_keys, sizeof(connection_keys));
+}
+
+static iscsi_param_num_t *find_num_key_by_flag(guint flag,
+                                        iscsiexpert_sessionset_t *iscsiexpert_sessionset)
+{
+    iscsi_session_params_t *p = &iscsiexpert_sessionset->params;
+
+    iscsi_param_num_t * ret = NULL;
+
+    if (flag == p->dflt_time2retain.flag)
+        ret = &p->dflt_time2retain;
+    else if(flag == p->dflt_time2wait.flag)
+        ret = &p->dflt_time2wait;
+    else if(flag == p->error_recovery_lvl.flag)
+        ret = &p->error_recovery_lvl;
+    else if(flag == p->first_burst_len.flag)
+        ret = &p->first_burst_len;
+    else if(flag == p->max_burst_len.flag)
+        ret = &p->max_burst_len;
+    else if(flag == p->max_connections.flag)
+        ret = &p->max_connections;
+    else if(flag == p->max_outstand_r2t.flag)
+        ret = &p->max_outstand_r2t;
+
+
+    return ret;
+}
+
+static iscsi_param_bool_t *find_bool_key_by_flag(guint flag,
+                                    iscsiexpert_sessionset_t *iscsiexpert_sessionset,
+                                    iscsiexpert_session_t *iscsiexpert_session)
+{
+    iscsi_session_params_t *p = &iscsiexpert_sessionset->params;
+    iscsi_connection_params_t *q = &iscsiexpert_session->params;
+
+    iscsi_param_bool_t * ret = NULL;
+
+    /*first: find the key in session keys*/
+    if(flag == p->data_pdu_inorder.flag)
+        ret = &p->data_pdu_inorder;
+    else if(flag == p->data_seq_inorder.flag)
+        ret = &p->data_seq_inorder;
+    else if(flag == p->imm_data.flag)
+        ret = &p->imm_data;
+    else if(flag == p->initial_r2t.flag)
+        ret = &p->initial_r2t;
+
+    /*if it is not a session wide key, fint it in connection keys*/
+    if(ret == NULL){
+        if(flag == q->ifmarker.flag)
+            ret = &q->ifmarker;
+        else if(flag == q->ofmarker.flag)
+            ret = &q->ofmarker;
+    }
+    return ret;
+
+
+}
+
+static iscsi_param_num_t *find_list_key_by_flag(guint flag, 
+                                    iscsiexpert_session_t *iscsiexpert_session)
+{
+    iscsi_connection_params_t *p = &iscsiexpert_session->params;
+    iscsi_param_num_t *ret = NULL;
+
+    if(flag == p->header_digest.flag)
+        ret = &p->header_digest;
+    else if(flag == p->data_digest.flag)
+        ret = &p->data_digest;
+    else if(flag == p->authmethod.flag)
+        ret = &p->authmethod;
+
+    return ret;
+
+}
+
+static void handle_min_max_param(iscsi_key_t *key_item, iscsiexpert_sessionset_t *iscsiexpert_sessionset)
+{
+    guint flag = key_item->flag;
+    iscsi_param_num_t *param = NULL;
+
+    if (key_item->req_val < 0 || key_item->rsp_val < 0){
+        if (param = find_num_key_by_flag(flag, iscsiexpert_sessionset)){
+            param->value = key_item->def;
+            param->from = NEGOTIATION_VALUE_FROM_DEF;
+            param->req_val = key_item->req_val;
+            param->rsp_val = key_item->rsp_val;
+        }
+    }
+    else{
+        if (param = find_num_key_by_flag(flag,iscsiexpert_sessionset)){
+            if (key_item->ops_type == RES_MIN)
+                param->value = MIN(key_item->req_val, key_item->rsp_val);
+            else
+                param->value = MAX(key_item->req_val, key_item->rsp_val);
+            param->req_val = key_item->req_val;
+            param->rsp_val = key_item->rsp_val;
+            param->from = NEGOTIATION_VALUE_FROM_NEGO;
+        }
+    }
+}
+
+static void set_marker_related_key(guint flag, iscsiexpert_session_t *iscsiexpert_session, iscsi_key_t *key_item)
+{
+    
+    iscsi_key_t *rel_key_item = NULL;
+    
+    if(flag == iscsiexpert_session->params.ifmarkint.flag
+        && iscsiexpert_session->params.ifmarkint.value== VALUE_REJECT){            
+            rel_key_item = key_item - 1;
+            iscsiexpert_session->params.ifmarker.value = FALSE;
+            iscsiexpert_session->params.ifmarker.from = NEGOTIATION_VALUE_FROM_NEGO;
+    }
+    else if(flag == iscsiexpert_session->params.ofmarkint.flag
+            && iscsiexpert_session->params.ofmarkint.value == VALUE_REJECT){        
+        rel_key_item = key_item - 1;       
+        iscsiexpert_session->params.ofmarker.value = FALSE;
+        iscsiexpert_session->params.ofmarker.from = NEGOTIATION_VALUE_FROM_NEGO;
+    }
+    else if(flag == iscsiexpert_session->params.ifmarker.flag
+            && iscsiexpert_session->params.ifmarker.value == FALSE){
+        rel_key_item = key_item + 1;
+        iscsiexpert_session->params.ifmarkint.value = VALUE_IRRLELVANT;
+        iscsiexpert_session->params.ifmarkint.from = NEGOTIATION_VALUE_FROM_NEGO;        
+    }
+    else if(flag == iscsiexpert_session->params.ofmarker.flag
+            && iscsiexpert_session->params.ofmarker.value == FALSE){
+        rel_key_item = key_item + 1;
+        iscsiexpert_session->params.ofmarkint.value = VALUE_IRRLELVANT;
+        iscsiexpert_session->params.ofmarkint.from = NEGOTIATION_VALUE_FROM_NEGO;        
+    }
+
+    if (rel_key_item)    
+        rel_key_item->nego_status = KEY_VALUE_DONE_NEGO;        
+    
+}
+
+static void handle_and_or_param(iscsi_key_t *key_item, iscsiexpert_sessionset_t *iscsiexpert_sessionset,
+                                       iscsiexpert_session_t *iscsiexpert_session)
+{
+    guint flag = key_item->flag;
+    iscsi_param_bool_t *param = NULL;
+
+    if(key_item->nego_status == KEY_VALUE_REPLY_NEGO){        
+        param = find_bool_key_by_flag(flag, iscsiexpert_sessionset, iscsiexpert_session);
+        if(key_item->ini2tar == TRUE){
+            param->value = key_item->req_val ? TRUE : FALSE;
+            param->from = NEGOTIATION_VALUE_FROM_NEGO;
+            param->req_val = key_item->req_val;         
+            param->rsp_val = key_item->req_val;  /*the target should respond*/
+        }
+        else{
+            param->value = key_item->rsp_val ? TRUE : FALSE;
+            param->from = NEGOTIATION_VALUE_FROM_NEGO;
+            param->req_val = key_item->rsp_val;
+            param->rsp_val = key_item->rsp_val;  /*the initiator should respond*/
+        }
+
+		return;
+    }       
+    else if(key_item->nego_status == KEY_VALUE_DONE_NEGO){
+    if (key_item->req_val < 0 || key_item->rsp_val < 0){
+            if (param = find_bool_key_by_flag(flag,iscsiexpert_sessionset, iscsiexpert_session)){
+            param->value = key_item->def ? TRUE : FALSE;
+            param->from = NEGOTIATION_VALUE_FROM_DEF;
+            param->req_val = key_item->req_val;
+            param->rsp_val = key_item->rsp_val;
+        }
+    }
+    else{
+            if (param = find_bool_key_by_flag(flag,iscsiexpert_sessionset, iscsiexpert_session)){
+            if (key_item->ops_type == RES_AND)
+                param->value = (key_item->req_val && key_item->rsp_val) ? TRUE : FALSE;
+            else
+                param->value = (key_item->req_val || key_item->rsp_val) ? TRUE : FALSE;
+            param->req_val = key_item->req_val;
+            param->rsp_val = key_item->rsp_val;
+            param->from = NEGOTIATION_VALUE_FROM_NEGO;
+        }
+        }
+    }
+    if(flag == iscsiexpert_session->params.ofmarker.flag 
+        || flag == iscsiexpert_session->params.ofmarkint.flag
+        || flag == iscsiexpert_session->params.ifmarker.flag
+        || flag == iscsiexpert_session->params.ifmarkint.flag){
+        /*handle the releation between the 4 keys*/
+        set_marker_related_key(flag, iscsiexpert_session, key_item);
+    }
+}
+
+static void handle_list_param(iscsi_key_t *key_item, iscsiexpert_session_t *iscsiexpert_session)
+{
+    guint flag = key_item->flag;
+    iscsi_param_num_t *param = NULL;
+
+    
+    if (key_item->req_val < 0 || key_item->rsp_val < 0){
+        if(param = find_list_key_by_flag(flag, iscsiexpert_session)){
+            param->value = key_item->def;
+            param->from = NEGOTIATION_VALUE_FROM_DEF;
+            param->req_val = key_item->req_val;
+            param->req_val = key_item->rsp_val;
+    }
+}
+    else{
+        if(param = find_list_key_by_flag(flag, iscsiexpert_session)){
+            guint val = key_item->req_val & key_item->rsp_val;
+            if(val){
+                param->value = val;
+                param->from = NEGOTIATION_VALUE_FROM_NEGO;
+            }
+            else{
+                param->value = key_item->def;
+                param->from = NEGOTIATION_VALUE_FROM_DEF;
+            }
+            param->req_val = key_item->req_val;
+            param->rsp_val = key_item->rsp_val;                
+        }
+    }
+}
+
+static void handle_marker_param(iscsi_key_t *key_item, iscsiexpert_session_t *iscsiexpert_session)
+{
+    guint flag = key_item->flag;
+    iscsi_param_num_t *param = NULL;
+    gchar **value_list = NULL;
+    gint val_min = 0;
+    gint val_max = 0;
+    char *endptr;
+    iscsi_key_t *rel_key_item = key_item - 1;
+
+    if (key_item->ini2tar){
+        /*Initiator sent the key first*/
+        if(key_item->req_val == VALUE_OTHER){
+            /*initiator sent value range*/
+            value_list = g_strsplit(key_item->req_ptr, "~", -1);
+            val_min = strtol(value_list[0], &endptr, 10);
+            val_max = strtol(value_list[1], &endptr, 10);
+            if(val_min > val_max){
+                /*the initiator send a wrong range, so we have to use the default value*/
+                param->value = key_item->def;
+                param->from = NEGOTIATION_VALUE_FROM_DEF;
+            }
+            else{
+                /*initiator send a correct range*/
+                if(key_item->rsp_val == VALUE_OTHER){
+                    /*target alse responed with a range, so wo have to use the default value*/
+                    param->value = key_item->def;
+                    param->from = NEGOTIATION_VALUE_FROM_DEF;                    
+                }
+                else if(key_item->rsp_val == VALUE_IRRLELVANT || key_item->rsp_val == VALUE_REJECT){                    
+                    param->value = key_item->rsp_val;
+                    param->from = NEGOTIATION_VALUE_FROM_NEGO;
+
+                    /*
+                                When the interval is unacceptable the responder
+                                   answers with "Reject".  Reject is resetting the marker function in
+                                   the specified direction (Output or Input) to No. RFC3720 Page 211
+                                */
+                    set_marker_related_key(flag, iscsiexpert_session, key_item);
+                }
+                else if(key_item->rsp_val < 0){
+                    /* NotUnderstood, or non-value*/
+                    param->value = key_item->def;
+                    param->from = NEGOTIATION_VALUE_FROM_DEF;
+                }
+                else{
+                    if(key_item->rsp_val >= val_min && key_item->rsp_val <= val_max){
+                        param->value = key_item->rsp_val;
+                        param->from = NEGOTIATION_VALUE_FROM_NEGO;
+                    }
+                    else{
+                        param->value = key_item->def;
+                        param->from = NEGOTIATION_VALUE_FROM_DEF;
+                    }
+                }
+            }
+        }
+        else{
+            /*initiator sent a simple value*/
+            if(key_item->rsp_val == VALUE_IRRLELVANT || key_item->rsp_val == VALUE_REJECT){
+                param->value = key_item->rsp_val;
+                param->from = NEGOTIATION_VALUE_FROM_NEGO;
+
+                set_marker_related_key(flag, iscsiexpert_session, key_item);
+            }
+            else if(key_item->rsp_val < 0){
+                /*a list as response, or NotUnderstood, or non-value*/
+                param->value = key_item->def;
+                param->from = NEGOTIATION_VALUE_FROM_DEF;
+            }
+            else{
+                if(key_item->req_val != key_item->rsp_val){
+                    param->value = key_item->def;
+                    param->from = NEGOTIATION_VALUE_FROM_DEF;                
+                }
+                else{
+                    param->value = key_item->rsp_val;
+                    param->from = NEGOTIATION_VALUE_FROM_NEGO;
+                }
+            }
+        }
+    }
+    else{
+        /*target sent the key first*/
+        if(key_item->rsp_val == VALUE_OTHER){
+            /*target sent a list*/
+            value_list = g_strsplit(key_item->rsp_ptr, "~", -1);
+            val_min = strtol(value_list[0], &endptr, 10);
+            val_max = strtol(value_list[1], &endptr, 10);
+            if(val_min > val_max){
+                /*the target send a wrong range, so we have to use the default value*/
+                param->value = key_item->def;
+                param->from = NEGOTIATION_VALUE_FROM_DEF;
+            }
+            else{
+                /*target send a correct range*/
+                if(key_item->req_val == VALUE_OTHER){
+                    /*initiator alse responed with a range, so wo have to use the default value*/
+                    param->value = key_item->def;
+                    param->from = NEGOTIATION_VALUE_FROM_DEF;                    
+                }
+                else if(key_item->req_val == VALUE_IRRLELVANT || key_item->req_val == VALUE_REJECT){                    
+                    param->value = key_item->req_val;
+                    param->from = NEGOTIATION_VALUE_FROM_NEGO;
+                }
+                else if(key_item->req_val < 0){
+                    /* NotUnderstood, or non-value*/
+                    param->value = key_item->def;
+                    param->from = NEGOTIATION_VALUE_FROM_DEF;
+                }
+                else{
+                    if(key_item->req_val >= val_min && key_item->req_val <= val_max){
+                        param->value = key_item->req_val;
+                        param->from = NEGOTIATION_VALUE_FROM_NEGO;
+                    }
+                    else{
+                        param->value = key_item->def;
+                        param->from = NEGOTIATION_VALUE_FROM_DEF;
+                    }
+                }
+            }            
+        }
+        else{
+            /*target sent a simple value*/
+            if(key_item->req_val == VALUE_IRRLELVANT || key_item->req_val == VALUE_REJECT){
+                param->value = key_item->req_val;
+                param->from = NEGOTIATION_VALUE_FROM_NEGO;
+            }
+            else if(key_item->req_val < 0){
+                /*a list as response, or NotUnderstood, or non-value*/
+                param->value = key_item->def;
+                param->from = NEGOTIATION_VALUE_FROM_DEF;
+            }
+            else{
+                if(key_item->rsp_val != key_item->req_val){
+                    param->value = key_item->def;
+                    param->from = NEGOTIATION_VALUE_FROM_DEF;                
+                }
+                else{
+                    param->value = key_item->req_val;
+                    param->from = NEGOTIATION_VALUE_FROM_NEGO;
+                }
+            }            
+        }
+    }  
+}
+
+static void set_key_value(const gchar **key_value, guint key_type,
+                          guint type,
+                             iscsi_key_t *key_item,
+                             iscsiexpert_session_t *iscsiexpert_session,
+                             iscsiexpert_sessionset_t *iscsiexpert_sessionset)
+{
+     const gchar *key = key_value[0];
+     const gchar *value = key_value[1];
+     gint val = 0;
+     char *endptr;
+     gchar **value_list = NULL;
+     guint list_len = 0;
+     guint i = 0;
+     gboolean mrdsl = FALSE;
+
+     if (key_item->nego_status == KEY_VALUE_DONE_NEGO)
+          return;
+
+     /*check whether the value is "Reject", "NotUnderstood", "Irrelevant"*/
+     if (strcmp(value, "Reject") == 0)
+          val = VALUE_REJECT;
+     else if (strcmp(value, "NotUnderstood") == 0)
+          val = VALUE_NOTUNDERSTOOD;
+     else if (strcmp(value, "Irrelevant") == 0)
+          val = VALUE_IRRLELVANT;
+     else{
+          switch(key_type){
+          case RES_MIN:
+          case RES_MAX:
+          case RES_NONE:
+               /*the value is number*/
+               if (strlen(value)){
+                    val = strtol(value, &endptr, 10);
+               }
+               else{
+                    val = VALUE_NONE;
+               }
+               break;
+          case RES_AND:
+          case RES_OR:
+               /*the value is boolean*/
+               if (strlen(value)){
+                    if (0 == strcmp(value, "Yes"))
+                         val = 1;
+                    else if (0 == strcmp(value, "No"))
+                         val = 0;
+                    else
+                         val = VALUE_OTHER;
+               }
+               else{
+                    val = VALUE_NONE;
+               }
+               break;
+          case RES_LIST:
+               /*the value may be a list*/
+               if (strlen(value)){
+
+                   /*value is a list separated by comma*/
+                   value_list = g_strsplit(value, ",", -1);
+                   list_len = g_strv_length(value_list);
+                   for(i = 0; i < list_len; ++i){
+                       if(0 == strcmp("HeaderDigest", key)
+                          || 0 == strcmp("DataDigest", key)){
+                           if(0 == strcmp("CRC32C", value_list[i])){                                  
+                               val |= DIGEST_CRC32C;
+                           }
+                           else if(0 == strcmp("None", value_list[i])){
+                               val |= DIGEST_NONE;
+                           }
+                           else{
+                               val |= DIGEST_NOTUNDERSTOOD;
+                           }
+                       }
+                       else if(0 == strcmp("AuthMethod", key)){
+                           if(0 == strcmp("CHAP", value_list[i])){
+                               val |= AUTHMETHOD_CHAP;
+                           }
+                           else if(0 == strcmp("None", value_list[i])){
+                               val |= AUTHMETHOD_NONE;
+                           }
+                           else if(0 == strcmp("SRP", value_list[i])){
+                               val |= AUTHMETHOD_SRP;
+                           }
+                           else if(0 == strcmp("SPKM1", value_list[i])){
+                               val |= AUTHMETHOD_SPKM1;
+                           }
+                           else if(0 == strcmp("SPKM2", value_list[i])){
+                               val |= AUTHMETHOD_SPKM2;
+                           }
+                           else if(0 == strcmp("KRB5", value_list[i])){
+                               val |= AUTHMETHOD_NONE;
+                           }
+                           else{
+                               val |= AUTHMETHOD_NOTUNDERSTOOD;
+                           }
+                       }
+                   }
+               }
+               else
+                    val = VALUE_NONE;
+               break;
+          case RES_MARKER:
+               /*the value is marker*/
+               if (strlen(value)){
+                   value_list = g_strsplit(value, "~", -1);
+                   list_len = g_strv_length(value_list);
+                   if(list_len == 1){
+                       /*the MarkInt is a value*/
+                       val = strtol(value_list[0], &endptr, 10);
+                   }
+                   else if(list_len == 2){
+                        /*the MarkInt is a value range*/
+                        val = VALUE_OTHER;  /*record the value in val_ptr*/
+                   }
+               }
+               else
+                    val = VALUE_NONE;
+               break;
+          default:
+               break;
+          }
+     }
+     switch(type)
+     {
+          /*Login request*/
+     case ISCSIEXPERT_OPCODE_LOGIN_COMMAND:
+          /*set key's status*/
+          if (key_item->nego_status == KEY_VALUE_NO_NEGO){
+               if (key && 0 == strcmp(key, "MaxRecvDataSegmentLength")){
+                    key_item->nego_status = KEY_VALUE_DONE_NEGO;
+               }
+               else{
+                   key_item->nego_status = KEY_VALUE_NEGO;
+               }
+
+               key_item->ini2tar = TRUE;
+          }
+          else if (key_item->nego_status == KEY_VALUE_NEGO){
+              if (!key_item->ini2tar)
+                  key_item->nego_status = KEY_VALUE_DONE_NEGO;
+              else
+                  break;
+          }
+
+          key_item->req_val = val;
+          if (val < 0){
+               key_item->req_ptr = g_strdup(value);
+          }
+          break;
+          /*Login response*/
+     case ISCSIEXPERT_OPCODE_LOGIN_RESPONSE:
+          /*whether the MRDSL is the target's declarative*/
+          if (key && 0 == strcmp(key, "MaxRecvDataSegmentLength")){
+               key_item += 1;
+               mrdsl = TRUE;
+          }
+
+          /*set key's status*/
+          if (key_item->nego_status == KEY_VALUE_NEGO){
+              if (key_item->ini2tar)
+                  key_item->nego_status = KEY_VALUE_DONE_NEGO;
+              else
+                  break;
+          }
+          else if(key_item->nego_status == KEY_VALUE_NO_NEGO){
+               key_item->ini2tar = FALSE;
+               if (mrdsl){
+                    key_item->nego_status = KEY_VALUE_DONE_NEGO;
+               }
+               else{
+                    key_item->nego_status = KEY_VALUE_NEGO;
+               }
+          }
+
+          key_item->rsp_val = val;
+          if (val < 0){
+               key_item->rsp_ptr = g_strdup(value);
+          }
+          break;
+     default:
+          break;
+     }
+
+    if (key_item->nego_status == KEY_VALUE_DONE_NEGO){
+        switch(key_item->ops_type){
+            case RES_NONE:
+                if(key_item->ini2tar){
+                    if (key_item->req_val > 0){
+                        iscsiexpert_session->params.max_recv_data_segment_length.value = key_item->req_val;
+                        iscsiexpert_session->params.max_recv_data_segment_length.req_val = key_item->req_val;
+                        iscsiexpert_session->params.max_recv_data_segment_length.from = NEGOTIATION_VALUE_FROM_INI;
+                    }
+                    else{
+                        iscsiexpert_session->params.max_recv_data_segment_length.value = key_item->def;
+                        iscsiexpert_session->params.max_recv_data_segment_length.req_val = key_item->req_val;
+                        iscsiexpert_session->params.max_recv_data_segment_length.from = NEGOTIATION_VALUE_FROM_DEF;
+                    }
+                }
+                else{
+                    if (key_item->rsp_val > 0){
+                        iscsiexpert_session->params.max_xmit_data_segment_length.value = key_item->rsp_val;
+                        iscsiexpert_session->params.max_xmit_data_segment_length.rsp_val = key_item->rsp_val;
+                        iscsiexpert_session->params.max_xmit_data_segment_length.from = NEGOTIATION_VALUE_FROM_TAR;
+                    }
+                    else{
+                        iscsiexpert_session->params.max_xmit_data_segment_length.value = key_item->def;
+                        iscsiexpert_session->params.max_xmit_data_segment_length.rsp_val = key_item->rsp_val;
+                        iscsiexpert_session->params.max_xmit_data_segment_length.from = NEGOTIATION_VALUE_FROM_DEF;
+                    }
+
+                }
+                break;
+            case RES_MIN:
+            case RES_MAX:
+                handle_min_max_param(key_item, iscsiexpert_sessionset);
+                break;
+            case RES_AND:
+            case RES_OR:
+                handle_and_or_param(key_item, iscsiexpert_sessionset, iscsiexpert_session);
+                break;
+            case RES_LIST:
+                handle_list_param(key_item, iscsiexpert_session);
+                break;
+            case RES_MARKER:
+                handle_marker_param(key_item, iscsiexpert_session);
+                break;
+            default:
+                break;
+        }
+    }
+    else if (key_item->nego_status == KEY_VALUE_NEGO 
+            && (key_item->ops_type == RES_AND || key_item->ops_type == RES_OR)){
+        if(key_item->ini2tar == TRUE){
+            /*initiator negotiation first, check the request value*/
+            if (key_item->req_val == 1 && key_item->ops_type == RES_OR){
+                key_item->nego_status = KEY_VALUE_REPLY_NEGO;
+}
+            else if(key_item->req_val == 0 && key_item->ops_type == RES_AND){
+                key_item->nego_status = KEY_VALUE_REPLY_NEGO;
+            }
+        }
+        else{
+            /*target negotiation first, check the response value*/
+            if (key_item->rsp_val == 1 && key_item->ops_type == RES_OR){
+                key_item->nego_status = KEY_VALUE_REPLY_NEGO;
+            }
+            else if(key_item->rsp_val == 0 && key_item->ops_type == RES_AND){
+                key_item->nego_status = KEY_VALUE_REPLY_NEGO;
+            }
+        }
+
+        /*Because replying, the key maybe didn't respond by receiver*/
+        handle_and_or_param(key_item, iscsiexpert_sessionset, iscsiexpert_session);
+    }
+}
+
+static void free_nums(gpointer data, gpointer user_data _U_)
+{
+	g_free(data);
+}
+
+void
+free_packet_num_list(GSList *pnum_list)
+{
+	if (pnum_list)
+	{
+		g_slist_foreach(pnum_list, free_nums, NULL);
+		g_slist_free(pnum_list);
+        pnum_list = NULL;
+	}
+}
+
+
+static void
+record_kvpair(tvbuff_t *tvb, guint32 pnum,
+              guint offset,
+              guint end_offset,
+              guint type,
+              iscsiexpert_session_t *iscsiexpert_session,
+              iscsiexpert_sessionset_t *iscsiexpert_sessionset)
+{
+     guint c_bit = (tvb_get_guint8(tvb, offset + 1) & 0x40) >> 6;
+     guint32 dsl = tvb_get_ntohl(tvb, offset + 4) & 0x00FFFFFF;
+     guint32 dsl_new = dsl;
+     guint limit = offset + 48 + dsl;
+     guint offset_new = offset + 48;
+     gchar *kv_pair = NULL;
+     gchar **kv = NULL;
+     iscsi_key_t *keys = NULL;
+     gint i  = 0;
+
+     gint find = 0;
+     gchar *key = NULL;
+     gchar *value = NULL;
+     char *endptr;
+     gboolean need_free = FALSE;
+     guint32 *num_tmp = NULL;
+     gboolean has_record = FALSE;
+
+     /*traversing the session's packet num list
+         * if the login packet has dissected,
+         * we should free the iscsiexpert_session->session_keys.
+         * It means we have already gotten the iscsi negotiaiton parameters
+         */
+     for(i = 0; i < 32; ++i){
+        if (iscsiexpert_session->login_num_list[i] == pnum){
+            has_record = TRUE;
+            break;
+        }
+     }
+     if (has_record){
+        if (iscsiexpert_session->req_trunced_ptr)
+            g_free(iscsiexpert_session->req_trunced_ptr);
+        iscsiexpert_session->req_trunced_ptr = NULL;
+        if (iscsiexpert_session->rsp_trunced_ptr)
+            g_free(iscsiexpert_session->rsp_trunced_ptr);
+        iscsiexpert_session->rsp_trunced_ptr = NULL;
+
+        return;
+     }
+     else{
+        /*the packet isn't in the array, so append it*/
+        for(i = 0; i < 32; ++i){
+            if (iscsiexpert_session->login_num_list[i] == 0){
+                iscsiexpert_session->login_num_list[i] = pnum;
+                break;
+            }
+        }
+     }
+
+
+     if (iscsiexpert_sessionset->session_keys == NULL)
+     {
+          init_session_keys(iscsiexpert_sessionset);
+     }
+
+     if (iscsiexpert_session->connection_keys == NULL)
+     {
+          init_connection_keys(iscsiexpert_session);
+     }
+
+     while(offset_new < limit)
+     {
+          gint len = tvb_strnlen(tvb, offset_new, dsl);
+          if (len == -1)
+               len = limit - offset_new;
+          else
+               len = len + 1;
+
+          /*get key-value pair from tvb*/
+          kv_pair = tvb_get_ephemeral_string(tvb, offset_new, len);
+          find = 0;
+          if (offset_new == offset + 48)
+          {
+               /*the first key-value pair*/
+               if (type == ISCSIEXPERT_OPCODE_LOGIN_COMMAND){
+                    /*check if the last login request has c bit set*/
+                    if (iscsiexpert_session->req_c_bit){
+                         if (iscsiexpert_session->req_trunced_ptr == NULL){
+                              /*it should not happen */
+                         }
+                         else{
+                              gchar *old_req = iscsiexpert_session->req_trunced_ptr;
+                              iscsiexpert_session->req_trunced_ptr = g_strconcat(old_req, kv_pair, NULL);
+                              g_free(old_req);
+                              old_req = NULL;
+
+                              if (c_bit == 0){
+                                   old_req = iscsiexpert_session->req_trunced_ptr;
+                                   kv_pair = g_strdup(old_req);
+                                   need_free = TRUE;
+                                   g_free(old_req);
+                                   old_req = NULL;
+                                   iscsiexpert_session->req_trunced_ptr = NULL;
+                                   iscsiexpert_session->req_c_bit = 0;
+                              }
+                         }
+                    }
+               }
+               else if (type == ISCSIEXPERT_OPCODE_LOGIN_RESPONSE){
+                    if (iscsiexpert_session->rsp_c_bit){
+                         if (iscsiexpert_session->rsp_trunced_ptr == NULL){
+                              /*it should not happen*/
+                         }
+                         else{
+                              gchar *old_rsp = iscsiexpert_session->rsp_trunced_ptr;
+                              iscsiexpert_session->rsp_trunced_ptr = g_strconcat(old_rsp, kv_pair, NULL);
+                              g_free(old_rsp);
+                              old_rsp = NULL;
+
+                              if (c_bit == 0){
+                                   old_rsp = iscsiexpert_session->rsp_trunced_ptr;
+                                   kv_pair = g_strdup(old_rsp);
+                                   need_free = TRUE;
+                                   g_free(old_rsp);
+                                   old_rsp = NULL;
+                                   iscsiexpert_session->rsp_trunced_ptr = NULL;
+                                   iscsiexpert_session->rsp_c_bit = 0;
+                              }
+                         }
+                    }
+               }
+          }
+
+          if ((offset_new + len >= offset + 48 + dsl) && c_bit){
+               if (type == ISCSIEXPERT_OPCODE_LOGIN_COMMAND
+                   && iscsiexpert_session->req_c_bit == 0){
+                    iscsiexpert_session->req_trunced_ptr = g_strdup(kv_pair);
+                    iscsiexpert_session->req_c_bit = 1;
+               }
+               else if (type == ISCSIEXPERT_OPCODE_LOGIN_RESPONSE
+                        && iscsiexpert_session->req_c_bit == 0){
+                    iscsiexpert_session->rsp_trunced_ptr = g_strdup(kv_pair);
+                    iscsiexpert_session->rsp_c_bit = 1;
+               }
+          }
+          else{
+               /*handle the key-value pair*/
+               if (strchr(kv_pair, '=') != NULL){
+                    /*get the key and value separately*/
+                    kv = g_strsplit(kv_pair, "=", -1);
+                    keys = iscsiexpert_sessionset->session_keys;
+                    /*check whether the key is session key in session_keys list*/
+                    for(i = 0; keys[i].name; ++i){
+                         if (kv[0] && (strcmp(keys[i].name, kv[0]) == 0))
+                         {
+                        set_key_value(kv, keys[i].ops_type, type, &keys[i],
+                                      iscsiexpert_session, iscsiexpert_sessionset);
+                              find = 1;
+                         }
+                    }
+                    /*check whether the key is connection key in connection_keys list*/
+                    if (find == 0){
+                         keys = iscsiexpert_session->connection_keys;
+                         for (i = 0; keys[i].name; ++i){
+                              if (kv[0] && strcmp(keys[i].name, kv[0]) == 0){
+                            set_key_value(kv, keys[i].ops_type, type, &keys[i],
+                                          iscsiexpert_session, iscsiexpert_sessionset);
+                                   find = 1;
+                              }
+                         }
+                    }
+                    /*it should be TargetName etal.*/
+                    if (find == 0){
+                         key = kv[0];
+                         value = kv[1];
+                         if (strlen(key))
+                              if (0 == strcmp(key, "TargetName")){
+                                   if((NULL == iscsiexpert_sessionset->params.target_name)
+                                      && (type == ISCSIEXPERT_OPCODE_LOGIN_COMMAND))
+                                        iscsiexpert_sessionset->params.target_name = g_strdup(value);
+                              }
+                              else if (0 == strcmp(key, "TargetAlias")){
+                                   if ((NULL == iscsiexpert_sessionset->params.target_alias)
+                                       && (type == ISCSIEXPERT_OPCODE_LOGIN_RESPONSE))
+                                        iscsiexpert_sessionset->params.target_alias= g_strdup(value);
+                              }
+                              else if (0 == strcmp(key, "InitiatorName")){
+                                   if ((NULL == iscsiexpert_sessionset->params.initiator_name)
+                                      && (type == ISCSIEXPERT_OPCODE_LOGIN_COMMAND))
+                                        iscsiexpert_sessionset->params.initiator_name= g_strdup(value);
+                              }
+                              else if (0 == strcmp(key, "InitiatorAlias")){
+                                   if ((NULL == iscsiexpert_sessionset->params.initiator_alias)
+                                      && (type == ISCSIEXPERT_OPCODE_LOGIN_COMMAND))
+                                        iscsiexpert_sessionset->params.initiator_alias= g_strdup(value);
+                              }
+                              else if (0 == strcmp(key, "SessionType")){
+                                   if (type == ISCSIEXPERT_OPCODE_LOGIN_COMMAND){
+                                       if (0 == strcmp(value, "Discovery"))
+                                            iscsiexpert_sessionset->params.session_type = DISCOVERY_TYPE;
+                                       else if (0 == strcmp(value, "Normal"))
+                                            iscsiexpert_sessionset->params.session_type = NORMAL_TYPE;
+                                   }
+                              }
+                              else if (0 == strcmp(key, "TargetPortalGroupTag")){
+                                   if (type == ISCSIEXPERT_OPCODE_LOGIN_RESPONSE
+                                       && iscsiexpert_sessionset->params.target_portal_group_tag == -1)
+                                        iscsiexpert_sessionset->params.target_portal_group_tag = strtol(value, &endptr, 10);
+                              }
+                    }
+                    g_strfreev(kv);
+               }
+               else{
+                    /*ignore*/
+               }
+          }
+          dsl_new -= len;
+          offset_new += len;
+          if(need_free){
+               g_free(kv_pair);
+               kv_pair = NULL;
+               need_free = FALSE;
+          }
+     }
+
+     return;
+}
+
+
+/* Code to actually dissect the packets */
+static void
+dissect_iscsiexpert_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, guint8 opcode, const char *opcode_str, guint32 data_segment_len, iscsiexpert_session_t *iscsiexpert_session, conversation_t *conversation,iscsiexpert_sessionset_t   * iscsiexpert_sessionset) {
+
+     guint original_offset = offset;
+     proto_tree *ti = NULL;
+     guint8 scsi_status = 0;
+     gboolean S_bit=FALSE;
+     guint cdb_offset = offset + 32; /* offset of CDB from start of PDU */
+     guint end_offset = offset + tvb_length_remaining(tvb, offset);
+     iscsiexpert_conv_data_t *cdata = NULL;
+	 iscsipacket_conv_context_t *cdata_context = NULL;
+     int paddedDataSegmentLength = data_segment_len;
+     guint16 lun=0xffff;
+     guint immediate_data_length=0;
+     guint immediate_data_offset=0;
+     itl_nexus_t *itl=NULL;
+     guint ahs_cdb_length=0;
+     guint ahs_cdb_offset=0;
+     guint32 data_offset=0;
+     //guint32 login_req_dsl = 0;
+     //guint32 login_rsp_dsl  = 0;
+
+	 guint last_offset	  = offset;
+     GSList * item = NULL;
+	 GSList * expert_list = NULL;
+	 proto_item *pi = NULL;
+
+	 if(paddedDataSegmentLength & 3)
+		  paddedDataSegmentLength += 4 - (paddedDataSegmentLength & 3);
+
+	 /* Make entries in Protocol column and Info column on summary display */
+	 if (check_col(pinfo->cinfo, COL_PROTOCOL))
+		  col_set_str(pinfo->cinfo, COL_PROTOCOL, "iSCSI[E]");
+
+	 /* XXX we need a way to handle replayed iscsi itt here
+      * If ITT in this PDU is used in other task (which has been
+      * accomplished), then this  function will return a existed conversation.
+      * This is not exactly what we need. */
+	 cdata=(iscsiexpert_conv_data_t *)se_tree_lookup32(iscsiexpert_session->itlq, tvb_get_ntohl(tvb, offset+16));
+	 if(!cdata){
+		  //find the new itt and alloc the cdata. wjd
+		  cdata = se_alloc (sizeof(iscsiexpert_conv_data_t));
+		  cdata->itlq.lun=0xffff;
+		  cdata->itlq.scsi_opcode=0xffff;
+		  cdata->itlq.task_flags=0;
+		  cdata->itlq.data_length=0;
+		  cdata->itlq.bidir_data_length=0;
+		  cdata->itlq.fc_time = pinfo->fd->abs_ts;
+		  cdata->itlq.first_exchange_frame=0;
+		  cdata->itlq.last_exchange_frame=0;
+		  cdata->itlq.flags=0;
+		  cdata->itlq.alloc_len=0;
+		  cdata->itlq.extra_data=NULL;
+		  cdata->data_in_frame=0;
+		  cdata->data_out_frame=0;
+
+		  cdata->contextq = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "iSCSI CONV ContextQ");
+
+		  //add for iscsi expert system by wjd
+          cdata->init_opcode = opcode;		/* Init opcode of this conv_data*/
+          cdata->init_fd = pinfo->fd->num; 	/* Init PDU number of this conv_data*/
+		  cdata->lastdatasn	= 0xFFFFFFFF;
+		  cdata->lastexpdatasn = 0;
+		  cdata->maxdatasn	 = (guint32) -1;
+		  cdata->exp_bufferoffset = (guint32) -1;
+		  cdata->last_exp_bufferoffset = (guint32) -1;
+          cdata->r2t_desired_transfer_length = (guint32) -1;
+          cdata->r2t_received = FALSE;
+          cdata->r2tsn = (guint32) -1;
+          cdata->data_out_total_transfer_leghth = 0;
+          cdata->new_created = TRUE;
+          cdata->task_done = FALSE;
+          cdata->has_snack = FALSE;
+		  cdata->first_login_response = TRUE;
+		  
+		  //record the last cmd sn information
+		  cdata->lastmaxcmdsn	= iscsiexpert_sessionset->maxcmdsn;
+		  cdata->lastexpcmdsn	= iscsiexpert_sessionset->expcmdsn;
+		  cdata->lastcmdsn		= iscsiexpert_sessionset->cmdsn;
+		  cdata->prev_i_bit 	= iscsiexpert_sessionset->cur_i_bit;
+
+//  	  ISCSIE_DEBUG("frame number: %d,prev_i_bit = %s\n",
+//  							pinfo->fd->num,
+//  							cdata->prev_i_bit?"YES":"No");
+		  //end by wjd
+
+		  se_tree_insert32(iscsiexpert_session->itlq, tvb_get_ntohl(tvb, offset+16), cdata);
+	 }
+     else /* This variable is needed by Rule NO.37.*/
+          cdata->new_created = FALSE;
+
+	 cdata_context = (iscsipacket_conv_context_t *)se_tree_lookup32(cdata->contextq, (((pinfo->fd->num &0xFFFF) << 16) | (tvb->length &0xFFFF)));
+	 if (!cdata_context){
+		  cdata_context = se_alloc (sizeof(iscsipacket_conv_context_t));
+
+		  cdata_context->lastdatasn = cdata->lastdatasn;
+		  cdata_context->lastexpdatasn = cdata->lastexpdatasn;
+		  cdata_context->lastexpstatsn	= iscsiexpert_session->expstatsn;
+		  cdata_context->laststatsn	= iscsiexpert_session->statsn;
+		  cdata_context->first_login_response = cdata->first_login_response;
+          cdata_context->pending_r2t = iscsiexpert_sessionset->pending_r2t;
+          cdata_context->last_r2tsn = cdata->r2tsn;
+		  se_tree_insert32(cdata->contextq, (((pinfo->fd->num &0xFFFF) << 16) | (tvb->length  &0xFFFF)), cdata_context);
+	 }
+
+	 if (opcode == ISCSIEXPERT_OPCODE_SCSI_RESPONSE ||
+		 opcode == ISCSIEXPERT_OPCODE_SCSI_DATA_IN) {
+		  scsi_status = tvb_get_guint8 (tvb, offset+3);
+	 }
+
+	 if ((opcode == ISCSIEXPERT_OPCODE_SCSI_RESPONSE) ||
+		 (opcode == ISCSIEXPERT_OPCODE_SCSI_DATA_IN) ||
+		 (opcode == ISCSIEXPERT_OPCODE_SCSI_DATA_OUT)) {
+		  /* first time we see this packet. check if we can find the request */
+		  switch(opcode){
+		  case ISCSIEXPERT_OPCODE_SCSI_RESPONSE:
+			   cdata->itlq.last_exchange_frame=pinfo->fd->num;
+
+			   break;
+		  case ISCSIEXPERT_OPCODE_SCSI_DATA_IN:
+			   /* a bit ugly but we need to check the S bit here */
+			   if(tvb_get_guint8(tvb, offset+1)&ISCSIEXPERT_SCSI_DATA_FLAG_S){
+					cdata->itlq.last_exchange_frame=pinfo->fd->num;
+			   }
+
+			   cdata->data_in_frame=pinfo->fd->num;
+			   break;
+		  case ISCSIEXPERT_OPCODE_SCSI_DATA_OUT:
+			   cdata->data_out_frame=pinfo->fd->num;
+
+			   break;
+		  }
+
+	 } else if (opcode == ISCSIEXPERT_OPCODE_SCSI_COMMAND) {
+		  /*we need the LUN value for some of the commands so we can pass it
+			across to the SCSI dissector.
+			Not correct but simple	and probably accurate enough :
+			If bit 6 of first bit is 0	 then just take second byte as the LUN
+			If bit 6 of first bit is 1, then take 6 bits from first byte
+			and all of second byte and pretend it is the lun value
+			people that care can add host specific dissection of vsa later.
+
+			We need to keep track of this on a per transaction basis since
+			for error recoverylevel 0 and when the A bit is clear in a
+			Data-In PDU, there will not be a LUN field in teh iscsi layer.
+		  */
+		  if(tvb_get_guint8(tvb, offset+8)&0x40){
+			   /* volume set addressing */
+			   lun=tvb_get_guint8(tvb,offset+8)&0x3f;
+			   lun<<=8;
+			   lun|=tvb_get_guint8(tvb,offset+9);
+		  } else {
+			   lun=tvb_get_guint8(tvb,offset+9);
+		  }
+
+		  cdata->itlq.lun=lun;
+		  cdata->itlq.first_exchange_frame=pinfo->fd->num;
+
+		  itl=(itl_nexus_t *)se_tree_lookup32(iscsiexpert_session->itl, lun);
+		  if(!itl){
+			   itl=se_alloc(sizeof(itl_nexus_t));
+			   itl->cmdset=0xff;
+			   itl->conversation=conversation;
+			   se_tree_insert32(iscsiexpert_session->itl, lun, itl);
+		  }
+
+	 }
+	 
+	 if(!itl){
+		  itl=(itl_nexus_t *)se_tree_lookup32(iscsiexpert_session->itl, cdata->itlq.lun);
+	 }
+
+
+	 if (check_col(pinfo->cinfo, COL_INFO)) {
+
+		  if (opcode != ISCSIEXPERT_OPCODE_SCSI_COMMAND) {
+
+			   col_append_str(pinfo->cinfo, COL_INFO, opcode_str);
+
+			   if (opcode == ISCSIEXPERT_OPCODE_SCSI_RESPONSE ||
+				   (opcode == ISCSIEXPERT_OPCODE_SCSI_DATA_IN &&
+					(tvb_get_guint8(tvb, offset + 1) & ISCSIEXPERT_SCSI_DATA_FLAG_S))) {
+					col_append_fstr (pinfo->cinfo, COL_INFO, " (%s)",
+									 val_to_str (scsi_status, scsi_status_val, "0x%x"));
+			   }
+			   else if (opcode == ISCSIEXPERT_OPCODE_LOGIN_RESPONSE) {
+					guint16 login_status = tvb_get_ntohs(tvb, offset+36);
+					col_append_fstr (pinfo->cinfo, COL_INFO, " (%s)",
+									 val_to_str (login_status, iscsiexpert_login_status, "0x%x"));
+			   }
+			   else if (opcode == ISCSIEXPERT_OPCODE_LOGOUT_COMMAND) {
+					guint8 logoutReason;
+					if(iscsiexpert_protocol_version == ISCSIEXPERT_PROTOCOL_DRAFT08) {
+						 logoutReason = tvb_get_guint8(tvb, offset+11);
+					} else if(iscsiexpert_protocol_version >= ISCSIEXPERT_PROTOCOL_DRAFT13) {
+						 logoutReason = tvb_get_guint8(tvb, offset+1) & 0x7f;
+					}
+					else {
+						 logoutReason = tvb_get_guint8(tvb, offset+23);
+					}
+					col_append_fstr (pinfo->cinfo, COL_INFO, " (%s)",
+									 val_to_str (logoutReason, iscsiexpert_logout_reasons, "0x%x"));
+			   }
+			   else if (opcode == ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION) {
+					guint8 tmf = tvb_get_guint8(tvb, offset + 1);
+					col_append_fstr (pinfo->cinfo, COL_INFO, " (%s)",
+									 val_to_str (tmf, iscsiexpert_task_management_functions, "0x%x"));
+			   }
+			   else if (opcode == ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION_RESPONSE) {
+					guint8 resp = tvb_get_guint8(tvb, offset + 2);
+					col_append_fstr (pinfo->cinfo, COL_INFO, " (%s)",
+									 val_to_str (resp, iscsiexpert_task_management_responses, "0x%x"));
+			   }
+			   else if (opcode == ISCSIEXPERT_OPCODE_REJECT) {
+					guint8 reason = tvb_get_guint8(tvb, offset + 2);
+					col_append_fstr (pinfo->cinfo, COL_INFO, " (%s)",
+									 val_to_str (reason, iscsiexpert_reject_reasons, "0x%x"));
+			   }
+			   else if (opcode == ISCSIEXPERT_OPCODE_ASYNC_MESSAGE) {
+					guint8 asyncEvent = tvb_get_guint8(tvb, offset + 36);
+					col_append_fstr (pinfo->cinfo, COL_INFO, " (%s)",
+									 val_to_str (asyncEvent, iscsiexpert_asyncevents, "0x%x"));
+			   }
+		  }
+	 }
+
+     /* A sign to indicate whether previous PDU has I bit set. I bit may
+      * affect the CmdSN. (PDUs which have I bit set should not have CmdSN
+	  * increased.)  Added by Yyc.  
+      */
+	 if (FALSE == iscsiexpert_is_iscsirsp(opcode)) {
+			//record the first iscsi packet information
+			iscsiexpert_sessionset->cur_i_bit = is_immediate_iscsi_cmd(tvb_get_guint8(tvb, offset + 0));
+//  		ISCSIE_DEBUG("frame number: %d,cur_i_bit = %s\n",
+//  							pinfo->fd->num,
+//  							iscsiexpert_sessionset->cur_i_bit?"YES":"No");
+	 }
+
+	 {
+		switch (opcode){
+		case ISCSIEXPERT_OPCODE_NOP_OUT:
+			/* NOP Out */
+			{
+				iscsiexpert_sessionset->cmdsn   = tvb_get_ntohl(tvb, original_offset + 24);
+				iscsiexpert_session->expstatsn  = tvb_get_ntohl(tvb, original_offset + 28);
+			}
+
+			break;
+		case ISCSIEXPERT_OPCODE_NOP_IN:
+			/* NOP In */
+			{
+				iscsiexpert_session->statsn         = tvb_get_ntohl(tvb, original_offset + 24);
+				iscsiexpert_sessionset->expcmdsn    = tvb_get_ntohl(tvb, original_offset + 28);
+				iscsiexpert_sessionset->maxcmdsn    = tvb_get_ntohl(tvb, original_offset + 32);
+			}
+
+			break;
+		case ISCSIEXPERT_OPCODE_SCSI_COMMAND:
+			/* SCSI Command */
+			{
+				if (tree){
+					//set the stat info when dissecting pdu
+					if (nstime_is_zero(&iscsiexpert_session->scsi_start_time)) {
+						nstime_add(&iscsiexpert_session->scsi_start_time,&pinfo->fd->rel_ts);
+					}
+					iscsiexpert_session->scsi_cmd_count++;
+					iscsiexpert_session->total_scsi_data_length += tvb_get_ntohl(tvb, original_offset+20);
+				}
+
+				iscsiexpert_sessionset->cmdsn   = tvb_get_ntohl(tvb, original_offset + 24);
+				iscsiexpert_session->expstatsn  = tvb_get_ntohl(tvb, original_offset + 28);
+			}
+			break;
+		case ISCSIEXPERT_OPCODE_SCSI_RESPONSE:
+			/* SCSI Response */
+			{
+				//add for iscsi expert system by wjd
+				cdata->lastexpdatasn        = tvb_get_ntohl(tvb, original_offset + 36);
+
+                cdata->task_done  		= TRUE;
+				//end by wjd
+
+                if (cdata->has_snack == FALSE)
+                     iscsiexpert_session->statsn         = tvb_get_ntohl(tvb, original_offset + 24);
+				iscsiexpert_sessionset->expcmdsn    = tvb_get_ntohl(tvb, original_offset + 28);
+				iscsiexpert_sessionset->maxcmdsn    = tvb_get_ntohl(tvb, original_offset + 32);
+			}
+
+			break;
+		case ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION:
+			/* Task Management Function */
+			{
+				iscsiexpert_sessionset->cmdsn   = tvb_get_ntohl(tvb, original_offset + 24);
+				iscsiexpert_session->expstatsn  = tvb_get_ntohl(tvb, original_offset + 28);
+			}
+			break;
+		case ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION_RESPONSE:
+			/* Task Management Function Response */
+			{
+				iscsiexpert_session->statsn         = tvb_get_ntohl(tvb, original_offset + 24);
+				iscsiexpert_sessionset->expcmdsn    = tvb_get_ntohl(tvb, original_offset + 28);
+				iscsiexpert_sessionset->maxcmdsn    = tvb_get_ntohl(tvb, original_offset + 32);
+                cdata->task_done  					= TRUE;
+			}
+			break;
+		case ISCSIEXPERT_OPCODE_LOGIN_COMMAND:
+			/* Login Command */
+			{
+				iscsiexpert_sessionset->cmdsn   = tvb_get_ntohl(tvb, original_offset + 24);
+				iscsiexpert_session->expstatsn  = tvb_get_ntohl(tvb, original_offset + 28);
+
+              /*record the key-value pairs of login request*/
+               record_kvpair(tvb, pinfo->fd->num,
+                             original_offset,
+                             end_offset,
+                             ISCSIEXPERT_OPCODE_LOGIN_COMMAND,
+                             iscsiexpert_session,
+                             iscsiexpert_sessionset);
+
+			}
+			break;
+		case ISCSIEXPERT_OPCODE_LOGIN_RESPONSE:
+			/* Login Response */
+			{
+				guint8 status_class = tvb_get_guint8(tvb, offset+36);
+
+				if (!status_class){
+					//For the first Login Response (the response to the first Login
+					//Request), this is the starting status Sequence Number for the
+					//connection. The next response of any kind, including the next Login
+					//Response, if any, in the same Login Phase, will carry this number +
+					//1. This field is only valid if the Status-Class is 0.
+					if (cdata->first_login_response){
+						cdata->first_login_response = FALSE;
+					}
+					iscsiexpert_session->statsn         = tvb_get_ntohl(tvb, original_offset + 24);
+				}
+
+				iscsiexpert_sessionset->expcmdsn    = tvb_get_ntohl(tvb, original_offset + 28);
+				iscsiexpert_sessionset->maxcmdsn    = tvb_get_ntohl(tvb, original_offset + 32);
+                cdata->task_done  					= TRUE;
+
+				/*record the key-value pairs of login response*/
+               record_kvpair(tvb, pinfo->fd->num,
+                             original_offset,
+                             end_offset,
+                             ISCSIEXPERT_OPCODE_LOGIN_RESPONSE,
+                             iscsiexpert_session,
+                             iscsiexpert_sessionset);
+			}
+			break;
+		case ISCSIEXPERT_OPCODE_TEXT_COMMAND:
+			/* Text Command */
+			{
+				iscsiexpert_sessionset->cmdsn   = tvb_get_ntohl(tvb, original_offset + 24);
+				iscsiexpert_session->expstatsn  = tvb_get_ntohl(tvb, original_offset + 28);
+			}
+			break;
+		case ISCSIEXPERT_OPCODE_TEXT_RESPONSE:
+			/* Text Response */
+			{
+				iscsiexpert_session->statsn         = tvb_get_ntohl(tvb, original_offset + 24);
+				iscsiexpert_sessionset->expcmdsn    = tvb_get_ntohl(tvb, original_offset + 28);
+				iscsiexpert_sessionset->maxcmdsn    = tvb_get_ntohl(tvb, original_offset + 32);
+                cdata->task_done  					= TRUE;
+			}
+			break;
+		case ISCSIEXPERT_OPCODE_SCSI_DATA_OUT:
+			/* SCSI Data Out (write) */
+			{
+				//if(tvb_get_ntohl(tvb, original_offset+36))
+					{
+					cdata->lastdatasn			= \
+						 tvb_get_ntohl (tvb, original_offset+36);
+                    cdata->last_exp_bufferoffset = cdata->exp_bufferoffset;
+					cdata->exp_bufferoffset = \
+						 tvb_get_ntohl (tvb, original_offset+40) +\
+						 (guint32) tvb_get_ntoh24(tvb, original_offset+5);
+					if (cdata->lastdatasn > cdata->maxdatasn)
+						 cdata->maxdatasn = cdata->lastdatasn;
+					}
+                cdata->data_out_total_transfer_leghth +=\
+                     (guint32) tvb_get_ntoh24(tvb, original_offset+5);
+
+				iscsiexpert_session->expstatsn  = tvb_get_ntohl(tvb, original_offset + 28);
+                /* If Initial_R2T=Yes, then R2T is needed to soliate Data-Out.*/
+                if (iscsiexpert_sessionset->params.initial_r2t.value &&
+                    (tvb_get_guint8(tvb, original_offset+1) & 0x80) >> 7){
+                     if (iscsiexpert_sessionset->pending_r2t > 0)
+                          iscsiexpert_sessionset->pending_r2t -= 1;
+                     else
+                          iscsiexpert_sessionset->pending_r2t = 0;
+			}
+			}
+			break;
+		case ISCSIEXPERT_OPCODE_SCSI_DATA_IN:
+			/* SCSI Data In (read) */
+			{
+				guint8 s_bit;
+
+				//add for iscsi expert system by wjd
+
+				cdata->lastdatasn			= \
+					 tvb_get_ntohl (tvb, original_offset+36);
+				cdata->exp_bufferoffset = \
+					 tvb_get_ntohl (tvb, original_offset+40) +\
+					 (guint32) tvb_get_ntoh24(tvb, original_offset+5);
+				if (cdata->lastdatasn > cdata->maxdatasn)
+					 cdata->maxdatasn = cdata->lastdatasn;
+
+                if ((tvb_get_guint8(tvb, original_offset+1) & 0x80) > 7)
+                     cdata->task_done  				= TRUE;
+
+				s_bit = tvb_get_guint8(tvb, offset+1) & 0x01;
+				if (s_bit && cdata->has_snack==FALSE){
+					//RFC10.7.3 The fields StatSN, Status, and Residual Count only have meaningful
+					//content if the S bit is set to 1 and their values are defined in
+					//Section 10.4 SCSI Response.
+					iscsiexpert_session->statsn         = tvb_get_ntohl(tvb, original_offset + 24);
+				}
+
+				iscsiexpert_sessionset->expcmdsn    = tvb_get_ntohl(tvb, original_offset + 28);
+				iscsiexpert_sessionset->maxcmdsn    = tvb_get_ntohl(tvb, original_offset + 32);
+
+				//end by wjd
+			}
+			break;
+		case ISCSIEXPERT_OPCODE_LOGOUT_COMMAND:
+			/* Logout Command */
+			{
+				iscsiexpert_sessionset->cmdsn   = tvb_get_ntohl(tvb, original_offset + 24);
+				iscsiexpert_session->expstatsn  = tvb_get_ntohl(tvb, original_offset + 28);
+			}
+			break;
+		case ISCSIEXPERT_OPCODE_LOGOUT_RESPONSE:
+			/* Logout Response */
+			{
+				iscsiexpert_session->statsn         = tvb_get_ntohl(tvb, original_offset + 24);
+				iscsiexpert_sessionset->expcmdsn    = tvb_get_ntohl(tvb, original_offset + 28);
+				iscsiexpert_sessionset->maxcmdsn    = tvb_get_ntohl(tvb, original_offset + 32);
+                cdata->task_done  					= TRUE;
+			}
+			break;
+		case ISCSIEXPERT_OPCODE_SNACK_REQUEST:
+			/* SNACK Request */
+			{
+				iscsiexpert_session->expstatsn  = tvb_get_ntohl(tvb, original_offset + 28);
+                cdata->has_snack = TRUE;
+			}
+			break;
+		case ISCSIEXPERT_OPCODE_R2T:
+			/* R2T */
+			{
+				iscsiexpert_session->statsn         = tvb_get_ntohl(tvb, original_offset + 24);
+				iscsiexpert_sessionset->expcmdsn    = tvb_get_ntohl(tvb, original_offset + 28);
+				iscsiexpert_sessionset->maxcmdsn    = tvb_get_ntohl(tvb, original_offset + 32);
+                iscsiexpert_sessionset->pending_r2t += 1;
+                cdata->r2t_desired_transfer_length 	= tvb_get_ntohl(tvb, original_offset + 34);
+                cdata->data_out_total_transfer_leghth = 0; /* Clear total_transfer_leghth*/
+                cdata->r2tsn						= tvb_get_ntohl(tvb, original_offset + 36);
+                cdata->r2t_received  				= TRUE;
+			}
+			break;
+		case ISCSIEXPERT_OPCODE_ASYNC_MESSAGE:
+			{
+				iscsiexpert_session->statsn         = tvb_get_ntohl(tvb, original_offset + 24);
+				iscsiexpert_sessionset->expcmdsn    = tvb_get_ntohl(tvb, original_offset + 28);
+				iscsiexpert_sessionset->maxcmdsn    = tvb_get_ntohl(tvb, original_offset + 32);
+			}
+			break;
+		case ISCSIEXPERT_OPCODE_REJECT:
+			/* Reject */
+			{
+				iscsiexpert_session->statsn         = tvb_get_ntohl(tvb, original_offset + 24);
+				iscsiexpert_sessionset->expcmdsn    = tvb_get_ntohl(tvb, original_offset + 28);
+				iscsiexpert_sessionset->maxcmdsn    = tvb_get_ntohl(tvb, original_offset + 32);
+                cdata->task_done  					= TRUE;
+			}
+			break;
+		case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I0:
+		case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I1:
+		case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I2:
+		case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T0:
+		case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T1:
+		case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T2:
+			/* Vendor specific opcodes */
+			break;
+		}
+
+		expert_list = iscsi_knowbase_query(tvb,offset,opcode,pinfo,cdata,iscsiexpert_session,iscsiexpert_sessionset);
+	}
+
+ /* In the interest of speed, if "tree" is NULL, don't do any
+		work not necessary to generate protocol tree items. */
+	 if (tree) {
+		  proto_item *tp;
+		  /* create display subtree for the protocol */
+		  tp = proto_tree_add_protocol_format(tree, proto_iscsiexpert, tvb,
+											  offset, -1, "iSCSI Protocol [Expert]: %s",
+											  opcode_str? opcode_str: "Unknown code");
+		  ti = proto_item_add_subtree(tp, ett_iscsiexpert);
+	 }
+
+	 pi = proto_tree_add_uint(ti, hf_iscsiexpert_Opcode, tvb,
+						 offset + 0, 1, opcode);
+	 if(	((opcode & TARGET_OPCODE_BIT) == 0)
+			&& opcode_is_valid(opcode)) {
+		  /* initiator -> target */
+		  gint b = tvb_get_guint8(tvb, offset + 0);
+		  if(iscsiexpert_protocol_version == ISCSIEXPERT_PROTOCOL_DRAFT08) {
+			   if(opcode != ISCSIEXPERT_OPCODE_SCSI_DATA_OUT &&
+				  opcode != ISCSIEXPERT_OPCODE_LOGOUT_COMMAND &&
+				  opcode != ISCSIEXPERT_OPCODE_SNACK_REQUEST)
+					pi = proto_tree_add_boolean(ti, hf_iscsiexpert_X, tvb, offset + 0, 1, b);
+		  }
+		  if(opcode != ISCSIEXPERT_OPCODE_SCSI_DATA_OUT &&
+			 opcode != ISCSIEXPERT_OPCODE_LOGIN_COMMAND &&
+			 opcode != ISCSIEXPERT_OPCODE_SNACK_REQUEST)
+			   pi = proto_tree_add_boolean(ti, hf_iscsiexpert_I, tvb, offset + 0, 1, b);
+	 }
+
+ 	iscsiexpert_add_expert_info(expert_list,offset + 0,1,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+
+
+
+    switch (opcode)
+        {
+        case ISCSIEXPERT_OPCODE_NOP_OUT:
+            /* NOP Out */
+            if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 4,1,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+            }
+			pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+			iscsiexpert_add_expert_info(expert_list,offset + 5,3,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_LUN, tvb, offset + 8, 8, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 8,8,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_InitiatorTaskTag, tvb, offset + 16, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 16,4,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_TargetTransferTag, tvb, offset + 20, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 20,4,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_CmdSN, tvb, offset + 24, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 24,4,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpStatSN, tvb, offset + 28, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 28,4,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+			last_offset = offset;
+            offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+			iscsiexpert_add_expert_info(expert_list,last_offset, offset - last_offset,
+						pinfo,tvb,ti, opcode,iscsiexpert_session);
+			last_offset = offset;
+            offset = handleDataSegment(ti, tvb, offset, data_segment_len, end_offset, hf_iscsiexpert_ping_data);
+			iscsiexpert_add_expert_info(expert_list,last_offset, offset - last_offset,
+						pinfo,tvb,ti, opcode,iscsiexpert_session);
+            break;
+        case ISCSIEXPERT_OPCODE_NOP_IN:
+            /* NOP In */
+            if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 4,1,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+            }
+            pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+			iscsiexpert_add_expert_info(expert_list,offset + 5,3,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_LUN, tvb, offset + 8, 8, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 8,8,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_InitiatorTaskTag, tvb, offset + 16, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 16,4,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_TargetTransferTag, tvb, offset + 20, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 20,4,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_StatSN, tvb, offset + 24, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 24,4,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpCmdSN, tvb, offset + 28, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 28,4,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_MaxCmdSN, tvb, offset + 32, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 32,4,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+			last_offset = offset;
+            offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+			iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+						pinfo,tvb,ti, opcode,iscsiexpert_session);
+			last_offset = offset;
+            offset = handleDataSegment(ti, tvb, offset, data_segment_len, end_offset, hf_iscsiexpert_ping_data);
+			iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+						pinfo,tvb,ti, opcode,iscsiexpert_session);
+            break;
+        case ISCSIEXPERT_OPCODE_SCSI_COMMAND:
+            /* SCSI Command */
+            {
+                guint32 ahsLen = tvb_get_guint8(tvb, offset + 4) * 4;
+                /* William, 10-2009, iscsi expert */
+                guint32 dsLen = tvb_get_ntohl(tvb, offset + 4) & 0x00FFFFFF;
+                gint b = tvb_get_guint8(tvb, offset + 1);
+                guint64 LUN = tvb_get_ntoh64(tvb, offset + 8);
+
+                proto_item *tf = proto_tree_add_uint(ti, hf_iscsiexpert_Flags, tvb, offset + 1, 1, b);
+                proto_tree *tt = proto_item_add_subtree(tf, ett_iscsiexpert_Flags);
+
+                proto_tree_add_boolean(tt, hf_iscsiexpert_SCSICommand_F, tvb, offset + 1, 1, b);
+                proto_tree_add_boolean(tt, hf_iscsiexpert_SCSICommand_R, tvb, offset + 1, 1, b);
+                if(b&0x40){
+                    cdata->itlq.task_flags|=SCSI_DATA_READ;
+                }
+                proto_tree_add_boolean(tt, hf_iscsiexpert_SCSICommand_W, tvb, offset + 1, 1, b);
+                if(b&0x20){
+                    cdata->itlq.task_flags|=SCSI_DATA_WRITE;
+                }
+                pi = proto_tree_add_uint(tt, hf_iscsiexpert_SCSICommand_Attr, tvb, offset + 1, 1, b);
+
+				iscsiexpert_add_expert_info(expert_list,offset + 1,1,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+
+                if(iscsiexpert_protocol_version < ISCSIEXPERT_PROTOCOL_DRAFT12) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_SCSICommand_CRN, tvb, offset + 3, 1, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 3,1,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 4,1,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+                /* William, 10-2009, iscsi expert */
+                /* if (ahsLen)
+                   {
+                   expert_add_info_format(pinfo, tf, PI_MALFORMED, PI_CHAT,
+                   "Alternate Header Segment (AHS) present in PDU, LUN:0x%016"PRIx64, LUN);
+                   }*/
+                pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+				iscsiexpert_add_expert_info(expert_list,offset + 5,3,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+                /* William, 10-2009, iscsi expert */
+                //if (dsLen)
+                //    {
+                //        expert_add_info_format(pinfo, tf, PI_MALFORMED, PI_CHAT, "Immediate Data Out in Command PDU, LUN:0x%016"PRIx64, LUN);
+                //    }
+
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_LUN, tvb, offset + 8, 8, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 8,8,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_InitiatorTaskTag, tvb, offset + 16, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 16,4,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpectedDataTransferLength, tvb, offset + 20, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 20,4,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+                cdata->itlq.data_length=tvb_get_ntohl(tvb, offset+20);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_CmdSN, tvb, offset + 24, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 24,4,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpStatSN, tvb, offset + 28, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 28,4,
+						pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(ahsLen > 0) {
+                    guint ahs_offset=offset+48;
+                    guint16 ahs_length=0;
+                    guint8 ahs_type=0;
+
+                    while(ahs_offset<(offset+48+ahsLen)){
+
+                        ahs_length=tvb_get_ntohs(tvb, ahs_offset);
+                        pi = proto_tree_add_item(ti, hf_iscsiexpert_AHS_length, tvb, ahs_offset, 2, FALSE);
+						iscsiexpert_add_expert_info(expert_list,ahs_offset,2,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                        ahs_offset+=2;
+
+                        ahs_type=tvb_get_guint8(tvb, ahs_offset);
+                        pi = proto_tree_add_item(ti, hf_iscsiexpert_AHS_type, tvb, ahs_offset, 1, FALSE);
+						iscsiexpert_add_expert_info(expert_list,ahs_offset,1,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                        ahs_offset++;
+
+                        switch(ahs_type){
+                        case 0x01: /* extended CDB */
+                            /* additional cdb */
+                            ahs_cdb_offset=ahs_offset+1;
+                            ahs_cdb_length=ahs_length-1;
+                            pi = proto_tree_add_item(ti, hf_iscsiexpert_AHS_extended_cdb, tvb, ahs_cdb_offset, ahs_cdb_length, FALSE);
+							iscsiexpert_add_expert_info(expert_list,ahs_cdb_offset,ahs_cdb_length,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                            ahs_offset+=ahs_length;
+                            break;
+                        case 0x02: /* bidirectional read data length */
+                            /* skip reserved byte */
+                            ahs_offset++;
+                            /* read data length */
+                            pi = proto_tree_add_item(ti, hf_iscsiexpert_AHS_read_data_length, tvb, ahs_offset, 4, FALSE);
+							iscsiexpert_add_expert_info(expert_list,ahs_offset,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                            cdata->itlq.bidir_data_length=tvb_get_ntohl(tvb, ahs_offset);
+                            ahs_offset+=4;
+                            break;
+                        default:
+                            pi = proto_tree_add_item(ti, hf_iscsiexpert_AHS_blob, tvb, ahs_offset, ahs_length, FALSE);
+							iscsiexpert_add_expert_info(expert_list,ahs_offset,ahs_length,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+
+                            ahs_offset+=ahs_length;
+                        }
+
+                        /* strip off padding bytes */
+                        if(ahs_offset&0x0003){
+                            ahs_offset=(ahs_offset+3)&0xfffc;
+                        }
+
+                    }
+
+                }
+				last_offset = offset;
+                offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48 + ahsLen);
+				iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+													pinfo,tvb,ti, opcode,iscsiexpert_session);
+
+                immediate_data_offset=offset;
+				last_offset = offset;
+                offset = handleDataSegment(ti, tvb, offset, data_segment_len, end_offset, hf_iscsiexpert_immediate_data);
+				iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+													pinfo,tvb,ti, opcode,iscsiexpert_session);
+				immediate_data_length=offset-immediate_data_offset;
+            }
+            break;
+        case ISCSIEXPERT_OPCODE_SCSI_RESPONSE:
+            /* SCSI Response */
+            {
+                gint b = tvb_get_guint8(tvb, offset + 1);
+                proto_item *tf = proto_tree_add_uint(ti, hf_iscsiexpert_Flags, tvb, offset + 1, 1, b);
+				proto_tree *tt = proto_item_add_subtree(tf, ett_iscsiexpert_Flags);
+
+                proto_tree_add_boolean(tt, hf_iscsiexpert_SCSIResponse_o, tvb, offset + 1, 1, b);
+                proto_tree_add_boolean(tt, hf_iscsiexpert_SCSIResponse_u, tvb, offset + 1, 1, b);
+                proto_tree_add_boolean(tt, hf_iscsiexpert_SCSIResponse_O, tvb, offset + 1, 1, b);
+                pi = proto_tree_add_boolean(tt, hf_iscsiexpert_SCSIResponse_U, tvb, offset + 1, 1, b);
+            }
+			iscsiexpert_add_expert_info(expert_list,offset + 1,1,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_SCSIResponse_Response, tvb, offset + 2, 1, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 2,1,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_SCSIResponse_Status, tvb, offset + 3, 1, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 3,1,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+            if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 4,1,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+            }
+            pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+			iscsiexpert_add_expert_info(expert_list,offset + 5,3,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_InitiatorTaskTag, tvb, offset + 16, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 16,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+            if(iscsiexpert_protocol_version <= ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_SCSIResponse_ResidualCount, tvb, offset + 20, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 20,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+            }
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_StatSN, tvb, offset + 24, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 24,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpCmdSN, tvb, offset + 28, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 28,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_MaxCmdSN, tvb, offset + 32, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 32,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpDataSN, tvb, offset + 36, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 36,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+            if(iscsiexpert_protocol_version <= ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_SCSIResponse_BidiReadResidualCount, tvb, offset + 44, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 44,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+            }
+            else {
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_SCSIResponse_BidiReadResidualCount, tvb, offset + 40, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 40,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_SCSIResponse_ResidualCount, tvb, offset + 44, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 44,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+            }
+			last_offset = offset;
+            offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+			iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+													pinfo,tvb,ti, opcode,iscsiexpert_session);
+            /* do not update offset here because the data segment is
+             * dissected below */
+			handleDataDigest(ti, tvb, offset, paddedDataSegmentLength);
+			iscsiexpert_add_expert_info(expert_list,offset,paddedDataSegmentLength,
+													pinfo,tvb,ti, opcode,iscsiexpert_session);
+            break;
+        case ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION:
+            /* Task Management Function */
+            {
+                /* William, 10-2009, iscsi expert */
+                guint8 fun = tvb_get_guint8(tvb, offset + 1) & 0x7F;
+                guint64 LUN = tvb_get_ntoh64(tvb, offset + 8);
+
+                //expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_CHAT, "Task Management Request, Function:%s, LUN:0x%016"PRIx64,
+                //                       match_strval(fun, iscsiexpert_task_management_functions), LUN);
+
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_TaskManagementFunction_Function, tvb, offset + 1, 1, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 1,1,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 4,1,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+					iscsiexpert_add_expert_info(expert_list,offset + 5,3,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_LUN, tvb, offset + 8, 8, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 8,8,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_InitiatorTaskTag, tvb, offset + 16, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 16,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_TaskManagementFunction_ReferencedTaskTag, tvb, offset + 20, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 20,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_CmdSN, tvb, offset + 24, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 24,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpStatSN, tvb, offset + 28, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 28,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_RefCmdSN, tvb, offset + 32, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 32,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+				last_offset = offset;
+                offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+				iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+													pinfo,tvb,ti, opcode,iscsiexpert_session);
+            }
+            break;
+        case ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION_RESPONSE:
+            /* Task Management Function Response */
+            {
+                /* William, 10-2009, iscsi expert */
+                //guint8 response = tvb_get_guint8(tvb, offset + 2);
+
+                //expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_CHAT, "Task Management Response:%s",
+                //                       match_strval(response, iscsiexpert_task_management_responses));
+
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_TaskManagementFunction_Response, tvb, offset + 2, 1, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 2,1,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(iscsiexpert_protocol_version <= ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 4,1,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+					iscsiexpert_add_expert_info(expert_list,offset + 5,3,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_InitiatorTaskTag, tvb, offset + 16, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 16,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(iscsiexpert_protocol_version < ISCSIEXPERT_PROTOCOL_DRAFT12) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TaskManagementFunction_ReferencedTaskTag, tvb, offset + 20, 4, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 20,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_StatSN, tvb, offset + 24, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 24,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpCmdSN, tvb, offset + 28, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 28,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_MaxCmdSN, tvb, offset + 32, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 32,4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+				last_offset = offset;
+                offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+				iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+													pinfo,tvb,ti, opcode,iscsiexpert_session);
+            }
+            break;
+        case ISCSIEXPERT_OPCODE_LOGIN_COMMAND:
+            /* Login Command */
+            {
+                int digestsActive = 0;
+                gint b = tvb_get_guint8(tvb, offset + 1);
+                /* William, 10-2009, iscsi expert */
+                guint64 ISID = (tvb_get_ntoh64(tvb, offset + 8) & 0xFFFFFFFFFFFF0000) >> 16;
+                guint16 CID = tvb_get_ntohs(tvb, offset + 20);
+                guint16 TSIH = tvb_get_ntohs(tvb, offset + 14);
+
+#if 0
+                proto_item *tf = proto_tree_add_uint(ti, hf_iscsiexpert_Flags, tvb, offset + 1, 1, b);
+                proto_tree *tt = proto_item_add_subtree(tf, ett_iscsiexpert_Flags);
+#endif
+
+                if(iscsiexpert_protocol_version == ISCSIEXPERT_PROTOCOL_DRAFT08) {
+                    if((b & CSG_MASK) >= ISCSIEXPERT_CSG_OPERATIONAL_NEGOTIATION)
+                        digestsActive = 1;
+                }
+
+                ///* William, 10-2009, iscsi expert */
+                //expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_CHAT, "Login Request  T:%d,%s->%s, ISID:0x%012"PRIx64", CID:0x%04x, TSIH:0x%04x",
+                //                       (b & 0x80) >> 7,
+                //                       match_strval((b & 0x0C) >> 2, iscsiexpert_login_stage),
+                //                       match_strval(b & 0x03, iscsiexpert_login_stage),
+                //                       ISID,
+                //                       CID,
+                //                       TSIH);
+
+                pi = proto_tree_add_boolean(ti, hf_iscsiexpert_Login_T, tvb, offset + 1, 1, b);
+                if(iscsiexpert_protocol_version >= ISCSIEXPERT_PROTOCOL_DRAFT13) {
+                    pi = proto_tree_add_boolean(ti, hf_iscsiexpert_Login_C, tvb, offset + 1, 1, b);
+                }
+                if(iscsiexpert_protocol_version == ISCSIEXPERT_PROTOCOL_DRAFT08) {
+                    pi = proto_tree_add_boolean(ti, hf_iscsiexpert_Login_X, tvb, offset + 1, 1, b);
+                }
+                pi =proto_tree_add_item(ti, hf_iscsiexpert_Login_CSG, tvb, offset + 1, 1, FALSE);
+
+                /* NSG is undefined unless T is set */
+                if(b&0x80){
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_Login_NSG, tvb, offset + 1, 1, FALSE);
+                }
+
+				iscsiexpert_add_expert_info(expert_list,offset + 1,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_VersionMax, tvb, offset + 2, 1, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 2,1,
+										pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_VersionMin, tvb, offset + 3, 1, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 3,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 4,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+				iscsiexpert_add_expert_info(expert_list,offset + 5,3,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(iscsiexpert_protocol_version == ISCSIEXPERT_PROTOCOL_DRAFT08) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_CID, tvb, offset + 8, 2, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 8,2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_ISID8, tvb, offset + 12, 2, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 12,2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                else {
+                    proto_item *tf = proto_tree_add_item(ti, hf_iscsiexpert_ISID, tvb, offset + 8, 6, FALSE);
+                    proto_tree *tt = proto_item_add_subtree(tf, ett_iscsiexpert_ISID);
+                    if(iscsiexpert_protocol_version == ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                        pi = proto_tree_add_item(tt, hf_iscsiexpert_ISID_Type, tvb, offset + 8, 1, FALSE);
+                        pi = proto_tree_add_item(tt, hf_iscsiexpert_ISID_NamingAuthority, tvb, offset + 9, 3, FALSE);
+                        pi = proto_tree_add_item(tt, hf_iscsiexpert_ISID_Qualifier, tvb, offset + 12, 2, FALSE);
+                    }
+                    else {
+                        pi = proto_tree_add_item(tt, hf_iscsiexpert_ISID_t, tvb, offset + 8, 1, FALSE);
+                        pi = proto_tree_add_item(tt, hf_iscsiexpert_ISID_a, tvb, offset + 8, 1, FALSE);
+                        pi = proto_tree_add_item(tt, hf_iscsiexpert_ISID_b, tvb, offset + 9, 2, FALSE);
+                        pi = proto_tree_add_item(tt, hf_iscsiexpert_ISID_c, tvb, offset + 11, 1, FALSE);
+                        pi = proto_tree_add_item(tt, hf_iscsiexpert_ISID_d, tvb, offset + 12, 2, FALSE);
+                    }
+
+					iscsiexpert_add_expert_info(expert_list,offset + 8,6,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                if(iscsiexpert_protocol_version < ISCSIEXPERT_PROTOCOL_DRAFT12) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TSID, tvb, offset + 14, 2, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 14,2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                else {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TSIH, tvb, offset + 14, 2, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 14,2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_InitiatorTaskTag, tvb, offset + 16, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 16,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT08) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_CID, tvb, offset + 20, 2, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 20,2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_CmdSN, tvb, offset + 24, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 24,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpStatSN, tvb, offset + 28, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 28,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(digestsActive){
+					last_offset = offset;
+                    offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+					iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+                } else {
+                    offset += 48;
+                }
+				last_offset = offset;
+                offset = handleDataSegmentAsTextKeys(ti, tvb, offset, data_segment_len, end_offset, digestsActive);
+				iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+													pinfo,tvb,ti, opcode,iscsiexpert_session);
+
+            }
+            break;
+        case ISCSIEXPERT_OPCODE_LOGIN_RESPONSE:
+            /* Login Response */
+            {
+                int digestsActive = 0;
+                gint b = tvb_get_guint8(tvb, offset + 1);
+                /* William, 10-2009, iscsi expert */
+                guint64 ISID = (tvb_get_ntoh64(tvb, offset + 8) & 0xFFFFFFFFFFFF0000) >> 16;
+                guint16 TSIH = tvb_get_ntohs(tvb, offset + 14);
+
+#if 0
+                proto_item *tf = proto_tree_add_uint(ti, hf_iscsiexpert_Flags, tvb, offset + 1, 1, b);
+                proto_tree *tt = proto_item_add_subtree(tf, ett_iscsiexpert_Flags);
+#endif
+
+                if(iscsiexpert_protocol_version == ISCSIEXPERT_PROTOCOL_DRAFT08) {
+                    if((b & CSG_MASK) >= ISCSIEXPERT_CSG_OPERATIONAL_NEGOTIATION)
+                        digestsActive = 1;
+                }
+
+                ///* William, 10-2009, iscsi expert */
+                //expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_CHAT, "Login Response T:%d,%s->%s, ISID:0x%012"PRIx64", TSIH:0x%04x",
+                //                       (b & 0x80) >> 7,
+                //                       match_strval((b & 0x0C) >> 2, iscsiexpert_login_stage),
+                //                       match_strval(b & 0x03, iscsiexpert_login_stage),
+                //                       ISID,
+                //                       TSIH);
+
+                pi = proto_tree_add_boolean(ti, hf_iscsiexpert_Login_T, tvb, offset + 1, 1, b);
+                if(iscsiexpert_protocol_version >= ISCSIEXPERT_PROTOCOL_DRAFT13) {
+                    pi = proto_tree_add_boolean(ti, hf_iscsiexpert_Login_C, tvb, offset + 1, 1, b);
+                }
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_Login_CSG, tvb, offset + 1, 1, FALSE);
+                /* NSG is undefined unless T is set */
+                if(b&0x80){
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_Login_NSG, tvb, offset + 1, 1, FALSE);
+                }
+
+				iscsiexpert_add_expert_info(expert_list,offset + 1,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_VersionMax, tvb, offset + 2, 1, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 2,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_VersionActive, tvb, offset + 3, 1, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 3,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 4,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+				iscsiexpert_add_expert_info(expert_list,offset + 5,3,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(iscsiexpert_protocol_version == ISCSIEXPERT_PROTOCOL_DRAFT08) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_ISID8, tvb, offset + 12, 2, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 12,2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                else {
+                    proto_item *tf = proto_tree_add_item(ti, hf_iscsiexpert_ISID, tvb, offset + 8, 6, FALSE);
+                    proto_tree *tt = proto_item_add_subtree(tf, ett_iscsiexpert_ISID);
+                    if(iscsiexpert_protocol_version == ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                        pi = proto_tree_add_item(tt, hf_iscsiexpert_ISID_Type, tvb, offset + 8, 1, FALSE);
+						iscsiexpert_add_expert_info(expert_list,offset + 8,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                        pi = proto_tree_add_item(tt, hf_iscsiexpert_ISID_NamingAuthority, tvb, offset + 9, 3, FALSE);
+						iscsiexpert_add_expert_info(expert_list,offset + 9,3,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                        pi = proto_tree_add_item(tt, hf_iscsiexpert_ISID_Qualifier, tvb, offset + 12, 2, FALSE);
+						iscsiexpert_add_expert_info(expert_list,offset + 12,2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    }
+                    else {
+                        pi = proto_tree_add_item(tt, hf_iscsiexpert_ISID_t, tvb, offset + 8, 1, FALSE);
+						pi = proto_tree_add_item(tt, hf_iscsiexpert_ISID_a, tvb, offset + 8, 1, FALSE);
+						iscsiexpert_add_expert_info(expert_list,offset + 8,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                        pi = proto_tree_add_item(tt, hf_iscsiexpert_ISID_b, tvb, offset + 9, 2, FALSE);
+						iscsiexpert_add_expert_info(expert_list,offset + 9,2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                        pi = proto_tree_add_item(tt, hf_iscsiexpert_ISID_c, tvb, offset + 11, 1, FALSE);
+						iscsiexpert_add_expert_info(expert_list,offset + 11,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                        pi = proto_tree_add_item(tt, hf_iscsiexpert_ISID_d, tvb, offset + 12, 2, FALSE);
+						iscsiexpert_add_expert_info(expert_list,offset + 12,2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    }
+                }
+                if(iscsiexpert_protocol_version < ISCSIEXPERT_PROTOCOL_DRAFT12) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TSID, tvb, offset + 14, 2, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 14,2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                else {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TSIH, tvb, offset + 14, 2, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 14,2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_InitiatorTaskTag, tvb, offset + 16, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 16,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_StatSN, tvb, offset + 24, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 24,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpCmdSN, tvb, offset + 28, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 28,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_MaxCmdSN, tvb, offset + 32, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 32,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_Login_Status, tvb, offset + 36, 2, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 36,2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(digestsActive){
+					last_offset = offset;
+                    offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+					iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+                } else {
+                    offset += 48;
+                }
+				last_offset = offset;
+                offset = handleDataSegmentAsTextKeys(ti, tvb, offset, data_segment_len, end_offset, digestsActive);
+				iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+            }
+            break;
+        case ISCSIEXPERT_OPCODE_TEXT_COMMAND:
+            /* Text Command */
+            {
+                gint b = tvb_get_guint8(tvb, offset + 1);
+                proto_item *tf = proto_tree_add_uint(ti, hf_iscsiexpert_Flags, tvb, offset + 1, 1, b);
+                proto_tree *tt = proto_item_add_subtree(tf, ett_iscsiexpert_Flags);
+
+                pi = proto_tree_add_boolean(tt, hf_iscsiexpert_Text_F, tvb, offset + 1, 1, b);
+                if(iscsiexpert_protocol_version >= ISCSIEXPERT_PROTOCOL_DRAFT13) {
+                    pi = proto_tree_add_boolean(tt, hf_iscsiexpert_Text_C, tvb, offset + 1, 1, b);
+                }
+
+				iscsiexpert_add_expert_info(expert_list,offset + 1,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+
+
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 4,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+				iscsiexpert_add_expert_info(expert_list,offset + 5,3,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_LUN, tvb, offset + 8, 8, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 8,8,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_InitiatorTaskTag, tvb, offset + 16, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 16,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_TargetTransferTag, tvb, offset + 20, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 20,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_CmdSN, tvb, offset + 24, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 24,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpStatSN, tvb, offset + 28, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 28,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+				last_offset = offset;
+                offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+				iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+				last_offset = offset;
+                offset = handleDataSegmentAsTextKeys(ti, tvb, offset, data_segment_len, end_offset, TRUE);
+				iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+            }
+            break;
+        case ISCSIEXPERT_OPCODE_TEXT_RESPONSE:
+            /* Text Response */
+            {
+                gint b = tvb_get_guint8(tvb, offset + 1);
+                proto_item *tf = proto_tree_add_uint(ti, hf_iscsiexpert_Flags, tvb, offset + 1, 1, b);
+                proto_tree *tt = proto_item_add_subtree(tf, ett_iscsiexpert_Flags);
+
+                pi = proto_tree_add_boolean(tt, hf_iscsiexpert_Text_F, tvb, offset + 1, 1, b);
+                if(iscsiexpert_protocol_version >= ISCSIEXPERT_PROTOCOL_DRAFT13) {
+                    pi = proto_tree_add_boolean(tt, hf_iscsiexpert_Text_C, tvb, offset + 1, 1, b);
+                }
+
+				iscsiexpert_add_expert_info(expert_list,offset + 1,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 4,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+				iscsiexpert_add_expert_info(expert_list,offset + 5,3,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_LUN, tvb, offset + 8, 8, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 8,8,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_InitiatorTaskTag, tvb, offset + 16, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 16,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_TargetTransferTag, tvb, offset + 20, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 20,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_StatSN, tvb, offset + 24, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 24,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpCmdSN, tvb, offset + 28, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 28,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_MaxCmdSN, tvb, offset + 32, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 32,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+				last_offset = offset;
+                offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+				iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+				last_offset = offset;
+                offset = handleDataSegmentAsTextKeys(ti, tvb, offset, data_segment_len, end_offset, TRUE);
+				iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+            }
+            break;
+        case ISCSIEXPERT_OPCODE_SCSI_DATA_OUT:
+            /* SCSI Data Out (write) */
+            {
+                gint b = tvb_get_guint8(tvb, offset + 1);
+                proto_item *tf = proto_tree_add_uint(ti, hf_iscsiexpert_Flags, tvb, offset + 1, 1, b);
+                proto_tree *tt = proto_item_add_subtree(tf, ett_iscsiexpert_Flags);
+
+                pi = proto_tree_add_boolean(tt, hf_iscsiexpert_SCSIData_F, tvb, offset + 1, 1, b);
+				iscsiexpert_add_expert_info(expert_list,offset + 1,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 4,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+				iscsiexpert_add_expert_info(expert_list,offset + 5,3,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_LUN, tvb, offset + 8, 8, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 8,8,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_InitiatorTaskTag, tvb, offset + 16, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 16,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_TargetTransferTag, tvb, offset + 20, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 20,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpStatSN, tvb, offset + 28, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 28,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_DataSN, tvb, offset + 36, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 36,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_BufferOffset, tvb, offset + 40, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 40,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                data_offset=tvb_get_ntohl(tvb, offset+40);
+
+				last_offset = offset;
+                offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+				iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+                /* do not update offset here because the data segment is
+                 * dissected below */
+                handleDataDigest(ti, tvb, offset, paddedDataSegmentLength);
+				iscsiexpert_add_expert_info(expert_list,offset,paddedDataSegmentLength,
+													pinfo,tvb,ti, opcode,iscsiexpert_session);
+            }
+            break;
+        case ISCSIEXPERT_OPCODE_SCSI_DATA_IN:
+            /* SCSI Data In (read) */
+            {
+                gint b = tvb_get_guint8(tvb, offset + 1);
+                proto_item *tf = proto_tree_add_uint(ti, hf_iscsiexpert_Flags, tvb, offset + 1, 1, b);
+                proto_tree *tt = proto_item_add_subtree(tf, ett_iscsiexpert_Flags);
+                /* William, 10-2009, iscsi expert */
+                guint64 LUN = tvb_get_ntoh64(tvb, offset + 8);
+
+                if(b&ISCSIEXPERT_SCSI_DATA_FLAG_S){
+                    S_bit=TRUE;
+                    ///* William, 10-2009, iscsi expert */
+                    //expert_add_info_format(pinfo, tf, PI_MALFORMED, PI_CHAT,
+                    //                       "Phase Collapse being used (combined data and status), LUN:0x%016"PRIx64, LUN);
+                }
+                pi = proto_tree_add_boolean(tt, hf_iscsiexpert_SCSIData_F, tvb, offset + 1, 1, b);
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT08) {
+                    pi = proto_tree_add_boolean(tt, hf_iscsiexpert_SCSIData_A, tvb, offset + 1, 1, b);
+                }
+                pi = proto_tree_add_boolean(tt, hf_iscsiexpert_SCSIData_O, tvb, offset + 1, 1, b);
+                pi = proto_tree_add_boolean(tt, hf_iscsiexpert_SCSIData_U, tvb, offset + 1, 1, b);
+                pi = proto_tree_add_boolean(tt, hf_iscsiexpert_SCSIData_S, tvb, offset + 1, 1, b);
+
+				iscsiexpert_add_expert_info(expert_list,offset + 1,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+
+                if(S_bit){
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_SCSIResponse_Status, tvb, offset + 3, 1, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 3,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 4,1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+				iscsiexpert_add_expert_info(expert_list,offset + 5,3,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_LUN, tvb, offset + 8, 8, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 8,8,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_InitiatorTaskTag, tvb, offset + 16, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 16,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(iscsiexpert_protocol_version <= ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_SCSIData_ResidualCount, tvb, offset + 20, 4, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 20,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                else {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TargetTransferTag, tvb, offset + 20, 4, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 20,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+
+				pi = proto_tree_add_item(ti, hf_iscsiexpert_StatSN, tvb, offset + 24, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 24,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpCmdSN, tvb, offset + 28, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 28,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_MaxCmdSN, tvb, offset + 32, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 32,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_DataSN, tvb, offset + 36, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 36,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_BufferOffset, tvb, offset + 40, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 40,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                data_offset=tvb_get_ntohl(tvb, offset+40);
+
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_SCSIData_ResidualCount, tvb, offset + 44, 4, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 44,4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+				last_offset = offset;
+                offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+				iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+                /* do not update offset here because the data segment is
+                 * dissected below */
+                handleDataDigest(ti, tvb, offset, paddedDataSegmentLength);
+				iscsiexpert_add_expert_info(expert_list,offset,paddedDataSegmentLength,
+													pinfo,tvb,ti, opcode,iscsiexpert_session);
+            }
+            break;
+        case ISCSIEXPERT_OPCODE_LOGOUT_COMMAND:
+            /* Logout Command */
+            {
+                guint8 b = tvb_get_guint8(tvb, offset + 1);
+                /* William, 10-2009, iscsi expert */
+                guint16 CID = tvb_get_ntohs(tvb, offset + 20);
+
+                /* William, 10-2009, iscsi expert */
+                //expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_CHAT, "Lougout Request Reason:%s, CID:0x%04x",
+                //                       match_strval(b & 0x7F, iscsiexpert_logout_reasons), CID);
+
+                if(iscsiexpert_protocol_version >= ISCSIEXPERT_PROTOCOL_DRAFT13) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_Logout_Reason, tvb, offset + 1, 1, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 1, 1,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 4, 1,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+					iscsiexpert_add_expert_info(expert_list,offset + 5, 3,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                if(iscsiexpert_protocol_version == ISCSIEXPERT_PROTOCOL_DRAFT08) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_CID, tvb, offset + 8, 2, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 8, 2,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_Logout_Reason, tvb, offset + 11, 1, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 11, 1,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_InitiatorTaskTag, tvb, offset + 16, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 16, 4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT08) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_CID, tvb, offset + 20, 2, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 20, 2,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    if(iscsiexpert_protocol_version < ISCSIEXPERT_PROTOCOL_DRAFT13) {
+                        pi = proto_tree_add_item(ti, hf_iscsiexpert_Logout_Reason, tvb, offset + 23, 1, FALSE);
+						iscsiexpert_add_expert_info(expert_list,offset + 23, 1,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    }
+                }
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_CmdSN, tvb, offset + 24, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 24, 1,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpStatSN, tvb, offset + 28, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 28, 4,
+													pinfo,tvb,pi, opcode,iscsiexpert_session);
+				last_offset = offset;
+                offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+				iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+
+            }
+            break;
+        case ISCSIEXPERT_OPCODE_LOGOUT_RESPONSE:
+            /* Logout Response */
+            {
+                guint8 b = tvb_get_guint8(tvb, offset + 2);
+                /* William, 10-2009, iscsi expert */
+                //expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_CHAT, "Lougout Response:%s",
+                //                       match_strval(b, iscsiexpert_logout_response));
+
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_Logout_Response, tvb, offset + 2, 1, FALSE);
+				iscsiexpert_add_expert_info(expert_list, offset + 2, 1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+					iscsiexpert_add_expert_info(expert_list, offset + 4, 1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+
+                    pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+					iscsiexpert_add_expert_info(expert_list, offset + 5, 3,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_InitiatorTaskTag, tvb, offset + 16, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list, offset + 16, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_StatSN, tvb, offset + 24, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list, offset + 24, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpCmdSN, tvb, offset + 28, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list, offset + 28, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_MaxCmdSN, tvb, offset + 32, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list, offset + 32, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_Time2Wait, tvb, offset + 40, 2, FALSE);
+				iscsiexpert_add_expert_info(expert_list, offset + 40, 2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_Time2Retain, tvb, offset + 42, 2, FALSE);
+				iscsiexpert_add_expert_info(expert_list, offset + 42, 2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+				last_offset = offset;
+                offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+				iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+            }
+            break;
+        case ISCSIEXPERT_OPCODE_SNACK_REQUEST:
+            /* SNACK Request */
+            {
+                gint b = tvb_get_guint8(tvb, offset + 1);
+#if 0
+                proto_item *tf = proto_tree_add_uint(ti, hf_iscsiexpert_Flags, tvb, offset + 1, 1, b);
+                proto_tree *tt = proto_item_add_subtree(tf, ett_iscsiexpert_Flags);
+#endif
+
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_snack_type, tvb, offset + 1, 1, b);
+				iscsiexpert_add_expert_info(expert_list,offset + 1, 1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 4, 1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+					iscsiexpert_add_expert_info(expert_list,offset + 5, 3,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_LUN, tvb, offset + 8, 8, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 8, 8,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_InitiatorTaskTag, tvb, offset + 16, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 16, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                if(iscsiexpert_protocol_version <= ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_BegRun, tvb, offset + 20, 4, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 20, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_RunLength, tvb, offset + 24, 4, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 24, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpStatSN, tvb, offset + 28, 4, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 28, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpDataSN, tvb, offset + 36, 4, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 36, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                else {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TargetTransferTag, tvb, offset + 20, 4, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 20, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpStatSN, tvb, offset + 28, 4, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 28, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_BegRun, tvb, offset + 40, 4, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 40, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_RunLength, tvb, offset + 44, 4, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 44, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+				last_offset = offset;
+                offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+				iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+            }
+            break;
+        case ISCSIEXPERT_OPCODE_R2T:
+            /* R2T */
+            if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 4, 1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+				iscsiexpert_add_expert_info(expert_list,offset + 5, 3,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_LUN, tvb, offset + 8, 8, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 8, 8,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+            }
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_InitiatorTaskTag, tvb, offset + 16, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 16, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_TargetTransferTag, tvb, offset + 20, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 20, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_StatSN, tvb, offset + 24, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 24, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpCmdSN, tvb, offset + 28, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 28, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_MaxCmdSN, tvb, offset + 32, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 32, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_R2TSN, tvb, offset + 36, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 36, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_BufferOffset, tvb, offset + 40, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 40, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_DesiredDataLength, tvb, offset + 44, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 44, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+			last_offset = offset;
+            offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+			iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+            break;
+        case ISCSIEXPERT_OPCODE_ASYNC_MESSAGE:
+            {
+                int dsl, snsl;
+
+                /* Asynchronous Message */
+                if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                    pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+					iscsiexpert_add_expert_info(expert_list,offset + 4, 1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                }
+                dsl=tvb_get_ntoh24(tvb, offset+5);
+                pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+				iscsiexpert_add_expert_info(expert_list,offset + 5, 3,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_LUN, tvb, offset + 8, 8, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 8, 8,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_StatSN, tvb, offset + 24, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 24, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpCmdSN, tvb, offset + 28, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 28, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_MaxCmdSN, tvb, offset + 32, 4, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 32, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_AsyncEvent, tvb, offset + 36, 1, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 36, 1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_EventVendorCode, tvb, offset + 37, 1, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 37, 1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_Parameter1, tvb, offset + 38, 2, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 38, 2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_Parameter2, tvb, offset + 40, 2, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 40, 2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_Parameter3, tvb, offset + 42, 2, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 42, 2,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+				last_offset = offset;
+                offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+				iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+
+                /* If we have a datasegment this contains scsi sense info followed
+                 * by iscsiexpert event data. (rfc3720 10.9.4)
+                 */
+                if(dsl){
+                    snsl=tvb_get_ntohs(tvb, offset);
+                    offset+=2;
+                    if(snsl){
+                        tvbuff_t *data_tvb;
+                        int tvb_len, tvb_rlen;
+                        tvb_len=tvb_length_remaining(tvb, offset);
+                        if(tvb_len>snsl)
+                            tvb_len=snsl;
+                        tvb_rlen=tvb_reported_length_remaining(tvb, offset);
+                        if(tvb_rlen>snsl)
+                            tvb_rlen=snsl;
+                        data_tvb=tvb_new_subset(tvb, offset, tvb_len, tvb_rlen);
+                        dissect_scsi_snsinfo (data_tvb, pinfo, tree, 0, tvb_len, &cdata->itlq, itl);
+                        offset+=snsl;
+                    }
+                    if((end_offset-offset)>0){
+                        pi = proto_tree_add_item(ti, hf_iscsiexpert_async_event_data, tvb, offset, end_offset-offset, FALSE);
+						iscsiexpert_add_expert_info(expert_list,offset,end_offset-offset,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+                    }
+                }
+                offset=end_offset;
+            }
+            break;
+        case ISCSIEXPERT_OPCODE_REJECT:
+            /* Reject */
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_Reject_Reason, tvb, offset + 2, 1, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 2, 1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+
+            if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 4, 1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+            }
+            pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+			iscsiexpert_add_expert_info(expert_list,offset + 5, 3,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_StatSN, tvb, offset + 24, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 24, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_ExpCmdSN, tvb, offset + 28, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 28, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_MaxCmdSN, tvb, offset + 32, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 32, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+            pi = proto_tree_add_item(ti, hf_iscsiexpert_DataSN, tvb, offset + 36, 4, FALSE);
+			iscsiexpert_add_expert_info(expert_list,offset + 36, 4,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+			last_offset = offset;
+            offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+			iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+			last_offset = offset;
+            offset = handleDataSegment(ti, tvb, offset, data_segment_len, end_offset, hf_iscsiexpert_error_pdu_data);
+			iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+            break;
+        case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I0:
+        case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I1:
+        case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I2:
+        case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T0:
+        case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T1:
+        case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T2:
+            /* Vendor specific opcodes */
+            if(iscsiexpert_protocol_version > ISCSIEXPERT_PROTOCOL_DRAFT09) {
+                pi = proto_tree_add_item(ti, hf_iscsiexpert_TotalAHSLength, tvb, offset + 4, 1, FALSE);
+				iscsiexpert_add_expert_info(expert_list,offset + 4, 1,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+            }
+            pi = proto_tree_add_uint(ti, hf_iscsiexpert_DataSegmentLength, tvb, offset + 5, 3, data_segment_len);
+			iscsiexpert_add_expert_info(expert_list,offset + 5, 3,
+											pinfo,tvb,pi, opcode,iscsiexpert_session);
+			last_offset = offset;
+            offset = handleHeaderDigest(iscsiexpert_session, ti, tvb, offset, 48);
+			iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+			last_offset = offset;
+            offset = handleDataSegment(ti, tvb, offset, data_segment_len, end_offset, hf_iscsiexpert_vendor_specific_data);
+			iscsiexpert_add_expert_info(expert_list,last_offset,offset - last_offset,
+											pinfo,tvb,ti, opcode,iscsiexpert_session);
+            break;
+        }
+
+
+
+    /* handle request/response matching */
+    switch(opcode){
+    case ISCSIEXPERT_OPCODE_SCSI_RESPONSE:
+        if (cdata->itlq.first_exchange_frame){
+            nstime_t delta_time;
+            proto_tree_add_uint(ti, hf_iscsiexpert_request_frame, tvb, 0, 0, cdata->itlq.first_exchange_frame);
+            nstime_delta(&delta_time, &pinfo->fd->abs_ts, &cdata->itlq.fc_time);
+            proto_tree_add_time(ti, hf_iscsiexpert_time, tvb, 0, 0, &delta_time);
+        }
+        if (cdata->data_in_frame)
+            proto_tree_add_uint(ti, hf_iscsiexpert_data_in_frame, tvb, 0, 0, cdata->data_in_frame);
+        if (cdata->data_out_frame)
+            proto_tree_add_uint(ti, hf_iscsiexpert_data_out_frame, tvb, 0, 0, cdata->data_out_frame);
+        break;
+    case ISCSIEXPERT_OPCODE_SCSI_DATA_IN:
+        /* if we have phase collaps then we might have the
+           response embedded in the last DataIn segment */
+        if(!S_bit){
+            if (cdata->itlq.first_exchange_frame)
+                proto_tree_add_uint(ti, hf_iscsiexpert_request_frame, tvb, 0, 0, cdata->itlq.first_exchange_frame);
+            if (cdata->itlq.last_exchange_frame)
+                proto_tree_add_uint(ti, hf_iscsiexpert_response_frame, tvb, 0, 0, cdata->itlq.last_exchange_frame);
+        } else {
+            if (cdata->itlq.first_exchange_frame){
+                nstime_t delta_time;
+                proto_tree_add_uint(ti, hf_iscsiexpert_request_frame, tvb, 0, 0, cdata->itlq.first_exchange_frame);
+                nstime_delta(&delta_time, &pinfo->fd->abs_ts, &cdata->itlq.fc_time);
+                proto_tree_add_time(ti, hf_iscsiexpert_time, tvb, 0, 0, &delta_time);
+            }
+        }
+        if (cdata->data_out_frame)
+            proto_tree_add_uint(ti, hf_iscsiexpert_data_out_frame, tvb, 0, 0, cdata->data_out_frame);
+        break;
+    case ISCSIEXPERT_OPCODE_SCSI_DATA_OUT:
+        if (cdata->itlq.first_exchange_frame)
+            proto_tree_add_uint(ti, hf_iscsiexpert_request_frame, tvb, 0, 0, cdata->itlq.first_exchange_frame);
+        if (cdata->data_in_frame)
+            proto_tree_add_uint(ti, hf_iscsiexpert_data_in_frame, tvb, 0, 0, cdata->data_in_frame);
+        if (cdata->itlq.last_exchange_frame)
+            proto_tree_add_uint(ti, hf_iscsiexpert_response_frame, tvb, 0, 0, cdata->itlq.last_exchange_frame);
+        break;
+    case ISCSIEXPERT_OPCODE_SCSI_COMMAND:
+        if (cdata->data_in_frame)
+            proto_tree_add_uint(ti, hf_iscsiexpert_data_in_frame, tvb, 0, 0, cdata->data_in_frame);
+        if (cdata->data_out_frame)
+            proto_tree_add_uint(ti, hf_iscsiexpert_data_out_frame, tvb, 0, 0, cdata->data_out_frame);
+        if (cdata->itlq.last_exchange_frame)
+            proto_tree_add_uint(ti, hf_iscsiexpert_response_frame, tvb, 0, 0, cdata->itlq.last_exchange_frame);
+        break;
+    }
+
+    proto_item_set_len(ti, offset - original_offset);
+
+    if((opcode & ((iscsiexpert_protocol_version == ISCSIEXPERT_PROTOCOL_DRAFT08)?
+                  ~(X_BIT | I_BIT) :
+                  ~I_BIT)) == ISCSIEXPERT_OPCODE_SCSI_COMMAND) {
+        tvbuff_t *cdb_tvb, *data_tvb;
+        int tvb_len, tvb_rlen;
+        guint8 scsi_opcode;
+
+        /* SCSI Command */
+        tvb_len=tvb_length_remaining(tvb, cdb_offset);
+        tvb_rlen=tvb_reported_length_remaining(tvb, cdb_offset);
+        scsi_opcode=tvb_get_guint8(tvb, cdb_offset);
+        if(ahs_cdb_length && ahs_cdb_length<1024){
+            char *cdb_buf;
+
+            /* We have a variable length CDB where bytes >16 is transported
+             * in the AHS.
+             */
+            cdb_buf=ep_alloc(16+ahs_cdb_length);
+            /* the 16 first bytes of the cdb */
+            tvb_memcpy(tvb, cdb_buf, cdb_offset, 16);
+            /* the remainder of the cdb from the ahs */
+            tvb_memcpy(tvb, cdb_buf+16, ahs_cdb_offset, ahs_cdb_length);
+
+            cdb_tvb = tvb_new_child_real_data(tvb, cdb_buf,
+                                              ahs_cdb_length+16,
+                                              ahs_cdb_length+16);
+
+            add_new_data_source(pinfo, cdb_tvb, "CDB+AHS");
+        } else {
+            if(tvb_len>16){
+                tvb_len=16;
+            }
+            if(tvb_rlen>16){
+                tvb_rlen=16;
+            }
+            cdb_tvb=tvb_new_subset(tvb, cdb_offset, tvb_len, tvb_rlen);
+        }
+        dissect_scsi_cdb(cdb_tvb, pinfo, tree, SCSI_DEV_UNKNOWN, &cdata->itlq, itl);
+        /* we dont want the immediata below to overwrite our CDB info */
+        if (check_col(pinfo->cinfo, COL_INFO)) {
+            col_set_fence(pinfo->cinfo, COL_INFO);
+        }
+        /* where there any ImmediateData ? */
+        if(immediate_data_length){
+            /* Immediate Data TVB */
+            tvb_len=tvb_length_remaining(tvb, immediate_data_offset);
+            if(tvb_len>(int)immediate_data_length)
+                tvb_len=immediate_data_length;
+            tvb_rlen=tvb_reported_length_remaining(tvb, immediate_data_offset);
+            if(tvb_rlen>(int)immediate_data_length)
+                tvb_rlen=immediate_data_length;
+            data_tvb=tvb_new_subset(tvb, immediate_data_offset, tvb_len, tvb_rlen);
+            dissect_scsi_payload (data_tvb, pinfo, tree,
+                                  TRUE,
+                                  &cdata->itlq, itl,
+                                  0);
+        }
+    }
+    else if (opcode == ISCSIEXPERT_OPCODE_SCSI_RESPONSE) {
+        if (scsi_status == 0x2) {
+            /* A SCSI response with Check Condition contains sense data */
+            /* offset is setup correctly by the iscsi code for response above */
+            if((end_offset - offset) >= 2) {
+                int senseLen = tvb_get_ntohs(tvb, offset);
+                if(ti != NULL)
+                    proto_tree_add_item(ti, hf_iscsiexpert_SenseLength, tvb, offset, 2, FALSE);
+                offset += 2;
+                if(senseLen > 0){
+                    tvbuff_t *data_tvb;
+                    int tvb_len, tvb_rlen;
+
+                    tvb_len=tvb_length_remaining(tvb, offset);
+                    if(tvb_len>senseLen)
+                        tvb_len=senseLen;
+                    tvb_rlen=tvb_reported_length_remaining(tvb, offset);
+                    if(tvb_rlen>senseLen)
+                        tvb_rlen=senseLen;
+                    data_tvb=tvb_new_subset(tvb, offset, tvb_len, tvb_rlen);
+                    dissect_scsi_snsinfo (data_tvb, pinfo, tree, 0,
+                                          tvb_len,
+                                          &cdata->itlq, itl);
+                }
+            }
+        }
+        else {
+            dissect_scsi_rsp(tvb, pinfo, tree, &cdata->itlq, itl, scsi_status);
+        }
+    }
+    else if ((opcode == ISCSIEXPERT_OPCODE_SCSI_DATA_IN) ||
+             (opcode == ISCSIEXPERT_OPCODE_SCSI_DATA_OUT)) {
+        tvbuff_t *data_tvb;
+        int tvb_len, tvb_rlen;
+
+        /* offset is setup correctly by the iscsi code for response above */
+        tvb_len=tvb_length_remaining(tvb, offset);
+        if(tvb_len>(int)data_segment_len)
+            tvb_len=data_segment_len;
+        tvb_rlen=tvb_reported_length_remaining(tvb, offset);
+        if(tvb_rlen>(int)data_segment_len)
+            tvb_rlen=data_segment_len;
+        data_tvb=tvb_new_subset(tvb, offset, tvb_len, tvb_rlen);
+        dissect_scsi_payload (data_tvb, pinfo, tree,
+                              (opcode==ISCSIEXPERT_OPCODE_SCSI_DATA_OUT),
+                              &cdata->itlq, itl,
+                              data_offset);
+    }
+
+    if(S_bit){
+        dissect_scsi_rsp(tvb, pinfo, tree, &cdata->itlq, itl, scsi_status);
+    }
+
+	{
+        GSList * item = NULL;
+        iscsiexpert_tapdata_info_t * iti = NULL;
+
+        iti = ep_alloc(sizeof(iscsiexpert_tapdata_info_t));
+
+		{
+			iti->packet_num = pinfo->fd->num;
+            iti->opcode     = opcode;
+            if (TRUE == iscsiexpert_is_iscsirsp(opcode)){
+                iti->direction  = TRUE;
+            }
+            else{
+                iti->direction  = FALSE;
+            }
+
+			iti->protocol	= ep_strdup(pinfo->current_proto);
+            iti->conn = iscsiexpert_session;
+
+			iti->group      = 0;
+            iti->severity   = PI_CHAT;
+            iti->summary    = NULL;
+            iti->sess_index = iscsiexpert_session->sess_index;
+        }
+
+		item =  g_slist_nth(expert_list,0);
+		if (item){
+			iscsiexpert_resultbase * resulebase = &iscsi_resultbase[((iscsiexpert_rule_result *)item->data)->result_id];
+			iti->group      = PI_MALFORMED;
+			iti->severity   = PI_ERROR;
+			iti->summary    = se_strdup(resulebase->result_name);
+
+
+			iscsiexpert_free_expertlist(expert_list);
+		}
+
+		/* we queue this packet to the tap system	*/
+		tap_queue_packet(iscsiexpert_tap, pinfo, iti);
+	}
+
+	{
+        if ((iscsisession_hashtable && (sess_tv.session_hashlist != iscsisession_hashtable))
+            || (conversation_hashtable_exact && (sess_tv.conversation_hashlist != conversation_hashtable_exact)))
+            {
+                sess_tv.proto_iscsiexpert = proto_iscsiexpert;
+                sess_tv.session_hashlist = iscsisession_hashtable;
+                sess_tv.conversation_hashlist = conversation_hashtable_exact;
+                sess_tv.current_proto = ep_strdup(pinfo->current_proto);
+                tap_queue_packet(iscsiexpert_tap_sesstv, pinfo, &sess_tv);
+            }
+    }
+
+}
+
+static gboolean
+iscsiexpert_loginrsp_final(guint8 flag)
+{
+	 guint8 nsg;
+	 guint8 csg;
+	 guint8 tbit;
+
+	 nsg = flag&0x03;
+	 csg = flag&0xc0;
+
+	 tbit = flag&0x80;
+
+	 if ((nsg == 3) && (tbit))
+	 {
+		  return TRUE;
+	 }
+
+	 return FALSE;
+}
+
+static gboolean
+iscsiexpert_addconnection_to_session(guint8 opcode,guint8 flag, iscsiexpert_session_t *iscsiexpert_session,iscsiexpert_sessionset_t * iscsiexpert_sessionset){
+	 if ((opcode == ISCSIEXPERT_OPCODE_LOGIN_RESPONSE) &&
+		 iscsiexpert_loginrsp_final(flag)){
+		  return TRUE;
+	 }
+
+	 if ((opcode == ISCSIEXPERT_OPCODE_SCSI_COMMAND) &&
+		 (ISCSIEXPERT_UNVAILD_CID == iscsiexpert_session->cid) &&
+		 (0 == iscsiexpert_sessionset->conn_count)){
+		  return TRUE;
+	 }
+
+	 return FALSE;
+}
+
+
+static iscsiexpert_session_init(iscsiexpert_sessionset_t * iscsiexpert_sessionset){
+	 iscsiexpert_sessionset->conn_count = 0;
+	 iscsiexpert_sessionset->cmdsn	   = 0;
+     iscsiexpert_sessionset->expcmdsn    = 0;
+     iscsiexpert_sessionset->maxcmdsn    = SNA32_CHECK;
+     //iscsiexpert_sessionset->last_cmdsn    = 0;
+     iscsiexpert_sessionset->init_fd    = 0;
+     iscsiexpert_sessionset->cur_i_bit    = FALSE;
+     iscsiexpert_sessionset->pending_r2t = 0;
+
+     iscsiexpert_sessionset->connq = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "iSCSI CONNQ");
+
+    iscsiexpert_sessionset->params.data_pdu_inorder.value=TRUE;
+    iscsiexpert_sessionset->params.data_seq_inorder.value=TRUE;
+    iscsiexpert_sessionset->params.dflt_time2retain.value=20;
+    iscsiexpert_sessionset->params.dflt_time2wait.value=2;
+    iscsiexpert_sessionset->params.error_recovery_lvl.value=0;
+    iscsiexpert_sessionset->params.first_burst_len.value=65536;
+    iscsiexpert_sessionset->params.imm_data.value=TRUE;
+    iscsiexpert_sessionset->params.initial_r2t.value=TRUE;
+    iscsiexpert_sessionset->params.max_burst_len.value=262144;
+    iscsiexpert_sessionset->params.max_connections.value=1;
+    iscsiexpert_sessionset->params.max_outstand_r2t.value=1;
+	 iscsiexpert_sessionset->params.session_type=NORMAL_TYPE;
+	 iscsiexpert_sessionset->params.target_portal_group_tag=-1;
+	 iscsiexpert_sessionset->params.initiator_alias=NULL;
+	 iscsiexpert_sessionset->params.initiator_name=NULL;
+	 iscsiexpert_sessionset->params.target_addr=NULL;
+	 iscsiexpert_sessionset->params.target_alias=NULL;
+	 iscsiexpert_sessionset->params.target_name=NULL;
+
+    iscsiexpert_sessionset->params.data_pdu_inorder.req_val=FALSE;
+    iscsiexpert_sessionset->params.data_seq_inorder.req_val=FALSE;
+    iscsiexpert_sessionset->params.dflt_time2retain.req_val=0;
+    iscsiexpert_sessionset->params.dflt_time2wait.req_val=0;
+    iscsiexpert_sessionset->params.error_recovery_lvl.req_val=0;
+    iscsiexpert_sessionset->params.first_burst_len.req_val=0;
+    iscsiexpert_sessionset->params.imm_data.req_val=FALSE;
+    iscsiexpert_sessionset->params.initial_r2t.req_val=FALSE;
+    iscsiexpert_sessionset->params.max_burst_len.req_val=0;
+    iscsiexpert_sessionset->params.max_connections.req_val=0;
+    iscsiexpert_sessionset->params.max_outstand_r2t.req_val=0;
+
+    iscsiexpert_sessionset->params.data_pdu_inorder.rsp_val=FALSE;
+    iscsiexpert_sessionset->params.data_seq_inorder.rsp_val=FALSE;
+    iscsiexpert_sessionset->params.dflt_time2retain.rsp_val=0;
+    iscsiexpert_sessionset->params.dflt_time2wait.rsp_val=0;
+    iscsiexpert_sessionset->params.error_recovery_lvl.rsp_val=0;
+    iscsiexpert_sessionset->params.first_burst_len.rsp_val=0;
+    iscsiexpert_sessionset->params.imm_data.rsp_val=FALSE;
+    iscsiexpert_sessionset->params.initial_r2t.rsp_val=FALSE;
+    iscsiexpert_sessionset->params.max_burst_len.rsp_val=0;
+    iscsiexpert_sessionset->params.max_connections.rsp_val=0;
+    iscsiexpert_sessionset->params.max_outstand_r2t.rsp_val=0;
+
+    iscsiexpert_sessionset->params.data_pdu_inorder.from=NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_sessionset->params.data_seq_inorder.from=NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_sessionset->params.dflt_time2retain.from=NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_sessionset->params.dflt_time2wait.from=NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_sessionset->params.error_recovery_lvl.from=NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_sessionset->params.first_burst_len.from=NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_sessionset->params.imm_data.from=NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_sessionset->params.initial_r2t.from=NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_sessionset->params.max_burst_len.from=NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_sessionset->params.max_connections.from=NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_sessionset->params.max_outstand_r2t.from=NEGOTIATION_VALUE_FROM_DEF;
+
+     iscsiexpert_sessionset->params.data_pdu_inorder.flag=DATAPDUINORDER_FLAG;
+     iscsiexpert_sessionset->params.data_seq_inorder.flag=DATASEQUENCEINORDER_FLAG;
+     iscsiexpert_sessionset->params.dflt_time2retain.flag=DEFAULTTIME2RETAIN_FLAG;
+     iscsiexpert_sessionset->params.dflt_time2wait.flag=DEFAULTTIME2WAIT_FLAG;
+     iscsiexpert_sessionset->params.error_recovery_lvl.flag=ERRORRECOVERYLEVEL_FLAG;
+     iscsiexpert_sessionset->params.first_burst_len.flag=FIRSTBURSTLENGTH_FLAG;
+     iscsiexpert_sessionset->params.imm_data.flag=IMMEDIATEDATA_FLAG;
+     iscsiexpert_sessionset->params.initial_r2t.flag=INITIALR2T_FLAG;
+     iscsiexpert_sessionset->params.max_burst_len.flag=MAXBURSTLENGTH_FLAG;
+     iscsiexpert_sessionset->params.max_connections.flag=MAXCONNECTIONS_FLAG;
+     iscsiexpert_sessionset->params.max_outstand_r2t.flag=MAXOUTSTANDINGR2T_FLAG;
+
+	 iscsiexpert_sessionset->session_keys = NULL;
+}
+
+static iscsiexpert_connection_init(iscsiexpert_session_t * iscsiexpert_session){
+	 iscsiexpert_session->magic_flag = ISCSIE_MAGIC_FLAG;
+	 iscsiexpert_session->conn_index =	conn_index++;
+	 iscsiexpert_session->sess_index =  -1;
+	 iscsiexpert_session->in_session = FALSE;
+	 //iscsiexpert_session->display = TRUE;
+	 iscsiexpert_session->display = FALSE;
+	 iscsiexpert_session->itlq=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "iSCSI ITLQ");
+	 iscsiexpert_session->itl=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "iSCSI ITL");
+	 iscsiexpert_session->tsih=0;
+	 iscsiexpert_session->cid=ISCSIEXPERT_UNVAILD_CID;
+	 memset(&iscsiexpert_session->isid,0,sizeof(iscsi_isid_tx_t));
+     iscsiexpert_session->expstatsn = 0;
+     iscsiexpert_session->statsn = 0;
+
+    iscsiexpert_session->params.header_digest.value = ISCSIEXPERT_HEADER_DIGEST_AUTO;
+    iscsiexpert_session->params.data_digest.value=ISCSIEXPERT_HEADER_DIGEST_AUTO;
+    iscsiexpert_session->params.max_recv_data_segment_length.value=8192;
+    iscsiexpert_session->params.max_xmit_data_segment_length.value= 8192;
+    iscsiexpert_session->params.authmethod.value= ISCSIEXPERT_AUTH_METHOD_AUTO;
+    iscsiexpert_session->params.ofmarker.value = FALSE;
+    iscsiexpert_session->params.ifmarker.value = FALSE;
+    iscsiexpert_session->params.ofmarkint.value = 0;
+    iscsiexpert_session->params.ifmarkint.value = 0;
+
+    iscsiexpert_session->params.header_digest.req_val = 0;
+    iscsiexpert_session->params.data_digest.req_val=0;
+    iscsiexpert_session->params.max_recv_data_segment_length.req_val=0;
+    iscsiexpert_session->params.max_xmit_data_segment_length.req_val= 0;
+    iscsiexpert_session->params.authmethod.req_val= 0;
+    iscsiexpert_session->params.ofmarker.req_val= FALSE;
+    iscsiexpert_session->params.ifmarker.req_val= FALSE;
+    iscsiexpert_session->params.ofmarkint.req_val= 0;
+    iscsiexpert_session->params.ifmarkint.req_val= 0;
+
+    iscsiexpert_session->params.header_digest.rsp_val = 0;
+    iscsiexpert_session->params.data_digest.rsp_val=0;
+    iscsiexpert_session->params.max_recv_data_segment_length.rsp_val=0;
+    iscsiexpert_session->params.max_xmit_data_segment_length.rsp_val= 0;
+    iscsiexpert_session->params.authmethod.rsp_val= 0;
+    iscsiexpert_session->params.ofmarker.rsp_val= FALSE;
+    iscsiexpert_session->params.ifmarker.rsp_val= FALSE;
+    iscsiexpert_session->params.ofmarkint.rsp_val= 0;
+    iscsiexpert_session->params.ifmarkint.rsp_val= 0;
+
+
+    iscsiexpert_session->params.header_digest.from= NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_session->params.data_digest.from=NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_session->params.max_recv_data_segment_length.from=NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_session->params.max_xmit_data_segment_length.from= NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_session->params.authmethod.from= NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_session->params.ofmarker.from= NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_session->params.ifmarker.from= NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_session->params.ofmarkint.from= NEGOTIATION_VALUE_FROM_DEF;
+    iscsiexpert_session->params.ifmarkint.from= NEGOTIATION_VALUE_FROM_DEF;
+
+     iscsiexpert_session->params.header_digest.flag= HEADERDIGEST_FLAG;
+     iscsiexpert_session->params.data_digest.flag=DATADIGEST_FLAG;
+     iscsiexpert_session->params.max_recv_data_segment_length.flag=MAXRECVDATASEGMENTLENGTH_FLAG;
+     iscsiexpert_session->params.max_xmit_data_segment_length.flag= MAXXMITDATASEGMENTLENGTH_FLAG;
+     iscsiexpert_session->params.authmethod.flag= AUTHMETHOD_FLAG;
+     iscsiexpert_session->params.ofmarker.flag= OFMARKER_FLAG;
+     iscsiexpert_session->params.ifmarker.flag= IFMARKER_FLAG;
+     iscsiexpert_session->params.ofmarkint.flag= OFMARKINT_FLAG;
+     iscsiexpert_session->params.ifmarkint.flag= IFMARKINT_FLAG;
+
+
+	 /* scsi statistic info*/
+	 nstime_set_zero(&iscsiexpert_session->scsi_start_time);
+	 iscsiexpert_session->scsi_cmd_count			 = 0;
+	 iscsiexpert_session->total_scsi_data_length	 = 0;
+
+	 iscsiexpert_session->connection_keys = NULL;
+     iscsiexpert_session->req_trunced_ptr = NULL;
+     iscsiexpert_session->req_c_bit = 0;
+     iscsiexpert_session->rsp_trunced_ptr = NULL;
+     iscsiexpert_session->rsp_c_bit = 0;
+     memset(&iscsiexpert_session->login_num_list, 0, 32);
+
+}
+
+static gboolean
+dissect_iscsiexpert_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,gboolean check_port) {
+	 /* Set up structures needed to add the protocol subtree and manage it */
+	 guint iscsiexpertPdusDissected = 0;
+	 guint offset = 0;
+	 guint32 available_bytes = tvb_length(tvb);
+	 int digestsActive = 1;
+	 conversation_t *conversation = NULL;
+	 iscsisession_t	* iscsisession = NULL;
+	 iscsiexpert_sessionset_t	* iscsiexpert_sessionset = NULL;
+	 iscsiexpert_session_t *iscsiexpert_session=NULL;
+	 guint8 opcode, flag, tmpbyte;
+	 iscsi_isid_tx_t isid;
+	 guint16 tsih = 0;
+	 /* record the cid to use later*/
+	 guint16 cid = ISCSIEXPERT_UNVAILD_CID;
+
+	 if (available_bytes < 48 ){
+		  /* heuristic already rejected the packet if size < 48,
+			 assume it's an iscsi packet with a segmented header */
+		  pinfo->desegment_offset = offset;
+		  pinfo->desegment_len = 48 - available_bytes;
+		  return TRUE;
+	 }
+
+	 memset(&isid,0,sizeof(iscsi_isid_tx_t));
+
+	 opcode = tvb_get_guint8(tvb, offset + 0);
+	 opcode &= OPCODE_MASK;
+	 
+	 flag = tvb_get_guint8(tvb, offset + 1);
+
+	 /* heuristics to verify that the packet looks sane.	  the heuristics
+	  * are based on the RFC version of iscsi.
+	  * (we should retire support for older iscsi versions in wireshark)
+	  *		-- ronnie s
+	  */
+	 /* opcode must be any of the ones from the standard
+	  * also check the header that it looks "sane"
+	  * all reserved or undefined bits in iscsi must be set to zero.
+	  */
+	 switch(opcode){
+	 case ISCSIEXPERT_OPCODE_NOP_IN:
+		  /* top two bits of byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0xc0){
+			   return FALSE;
+		  }
+		  /* byte 1 must be 0x80 */
+		  if(tvb_get_guint8(tvb, offset+1)!=0x80){
+			   return FALSE;
+		  }
+		  /* bytes 2 and 3 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+2)||tvb_get_guint8(tvb, offset+3)){
+			   return FALSE;
+		  }
+		  break;
+	 case ISCSIEXPERT_OPCODE_NOP_OUT:
+		  /* top bit of byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0x80){
+			   return FALSE;
+		  }
+		  /* byte 1 must be 0x80 */
+		  if(tvb_get_guint8(tvb, offset+1)!=0x80){
+			   return FALSE;
+		  }
+		  /* bytes 2 and 3 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+2)||tvb_get_guint8(tvb, offset+3)){
+			   return FALSE;
+		  }
+		  /* assume ITT and TTT must always be non NULL (ok they can be NULL
+		   * from time to time but it usually means we are in the middle
+		   * of a zeroed datablock).
+		   */
+		  if(!tvb_get_letohl(tvb,offset+16) || !tvb_get_letohl(tvb,offset+20)){
+			   return FALSE;
+		  }
+		  /* all reserved bytes between 32 - 47 must be null */
+		  if(tvb_get_letohl(tvb,offset+32)
+			 || tvb_get_letohl(tvb,offset+36)
+			 || tvb_get_letohl(tvb,offset+40)
+			 || tvb_get_letohl(tvb,offset+44)){
+			   return FALSE;
+		  }
+		  break;
+	 case ISCSIEXPERT_OPCODE_LOGIN_COMMAND:
+		  /* top two bits in byte 0 must be 0x40 */
+		  if((tvb_get_guint8(tvb, offset+0)&0xc0)!=0x40){
+
+			   return FALSE;
+		  }
+		  /* both the T and C bits can not be set
+		   * and the two reserved bits in byte 1 must be 0
+		   */
+		  tmpbyte=tvb_get_guint8(tvb, offset+1);
+		  switch(tmpbyte&0xf0){
+		  case 0x80:
+		  case 0x40:
+		  case 0x00:
+			   break;
+		  default:
+			   return FALSE;
+		  }
+		  /* ISID */
+		  isid.fmt_type = (tvb_get_guint8(tvb,offset + 8) & 0xC0) >> 6;
+		  isid.A = tvb_get_guint8(tvb,offset + 8) & 0x3F;
+		  isid.B0 = tvb_get_guint8(tvb,offset + 9);
+		  isid.B1 = tvb_get_guint8(tvb,offset + 10);
+		  isid.C	= tvb_get_guint8(tvb,offset + 11);
+		  isid.D0 = tvb_get_guint8(tvb,offset + 12);
+		  isid.D1 = tvb_get_guint8(tvb,offset + 13);
+
+		  tsih	= tvb_get_ntohs(tvb,offset + 14);
+
+		  /* record the cid to use later*/
+		  cid = tvb_get_ntohs(tvb, offset+20);
+
+		  /* should we test that datasegmentlen is non zero? */
+		  break;
+	 case ISCSIEXPERT_OPCODE_LOGIN_RESPONSE:
+		  /* top two bits in byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0xc0){
+			   return FALSE;
+		  }
+		  /* both the T and C bits can not be set
+		   * and the two reserved bits in byte 1 must be 0
+		   */
+		  tmpbyte=tvb_get_guint8(tvb, offset+1);
+		  switch(tmpbyte&0xf0){
+		  case 0x80:
+		  case 0x40:
+		  case 0x00:
+			   break;
+		  default:
+			   return FALSE;
+		  }
+
+		  if (TRUE == iscsiexpert_loginrsp_final(tmpbyte))
+		  {
+			   /* ISID */
+			   isid.fmt_type = (tvb_get_guint8(tvb,offset + 8) & 0xC0) >> 6;
+			   isid.A = tvb_get_guint8(tvb,offset + 8) & 0x3F;
+			   isid.B0 = tvb_get_guint8(tvb,offset + 9);
+			   isid.B1 = tvb_get_guint8(tvb,offset + 10);
+			   isid.C	= tvb_get_guint8(tvb,offset + 11);
+			   isid.D0 = tvb_get_guint8(tvb,offset + 12);
+			   isid.D1 = tvb_get_guint8(tvb,offset + 13);
+
+			   tsih	= tvb_get_ntohs(tvb,offset + 14);
+		  }
+
+		  /* the 32bit words at offsets 20, 40, 44 must be zero */
+		  if(tvb_get_letohl(tvb,offset+20)
+			 || tvb_get_letohl(tvb,offset+40)
+			 || tvb_get_letohl(tvb,offset+44)){
+			   return FALSE;
+		  }
+		  /* the two bytes at offset 38 must be zero */
+		  if(tvb_get_letohs(tvb,offset+38)){
+			   return FALSE;
+		  }
+		  /* should we test that datasegmentlen is non zero unless we just
+		   * entered full featured phase?
+		   */
+
+		  break;
+	 case ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION:
+		  /* top bit in byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0x80){
+			   return FALSE;
+		  }
+		  /* top bit in byte 1 must be set */
+		  tmpbyte=tvb_get_guint8(tvb, offset+1);
+		  if(!(tmpbyte&0x80)){
+			   return FALSE;
+		  }
+		  /* bytes 2,3 must be null */
+		  if(tvb_get_letohs(tvb,offset+2)){
+			   return FALSE;
+		  }
+		  /* ahs and dsl must be null */
+		  if(tvb_get_letohl(tvb,offset+4)){
+			   return FALSE;
+		  }
+		  break;
+	 case ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION_RESPONSE:
+		  /* top two bits in byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0xc0){
+			   return FALSE;
+		  }
+		  /* byte 1 must be 0x80 */
+		  if(tvb_get_guint8(tvb, offset+1)!=0x80){
+			   return FALSE;
+		  }
+		  /* byte 3 must be 0 */
+		  if(tvb_get_guint8(tvb,offset+3)){
+			   return FALSE;
+		  }
+		  /* ahs and dsl	as well as the 32bit words at offsets 8, 12, 20, 36
+		   * 40, 44 must all be 0
+		   */
+		  if(tvb_get_letohl(tvb,offset+4)
+			 || tvb_get_letohl(tvb,offset+8)
+			 || tvb_get_letohl(tvb,offset+12)
+			 || tvb_get_letohl(tvb,offset+20)
+			 || tvb_get_letohl(tvb,offset+36)
+			 || tvb_get_letohl(tvb,offset+40)
+			 || tvb_get_letohl(tvb,offset+44)){
+			   return FALSE;
+		  }
+		  break;
+	 case ISCSIEXPERT_OPCODE_LOGOUT_COMMAND:
+		  /* top bit in byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0x80){
+			   return FALSE;
+		  }
+		  /* top bit in byte 1 must be set */
+		  tmpbyte=tvb_get_guint8(tvb, offset+1);
+		  if(!(tmpbyte&0x80)){
+			   return FALSE;
+		  }
+
+		  /* Note: should be checked by iscsiexpert rule */
+
+		  /* Reason code must be known */
+		  /* if(!match_strval(tmpbyte&0x7f, iscsiexpert_logout_reasons)){ */
+		  /*	   return FALSE; */
+		  /* } */
+
+		  /* bytes 2,3 must be null */
+		  if(tvb_get_letohs(tvb,offset+2)){
+			   return FALSE;
+		  }
+		  /* ahs and dsl	as well as the 32bit words at offsets 8, 12, 32, 36
+		   * 40, 44 must all be 0
+		   */
+		  if(tvb_get_letohl(tvb,offset+4)
+			 || tvb_get_letohl(tvb,offset+8)
+			 || tvb_get_letohl(tvb,offset+12)
+			 || tvb_get_letohl(tvb,offset+32)
+			 || tvb_get_letohl(tvb,offset+36)
+			 || tvb_get_letohl(tvb,offset+40)
+			 || tvb_get_letohl(tvb,offset+44)){
+			   return FALSE;
+		  }
+		  break;
+	 case ISCSIEXPERT_OPCODE_SNACK_REQUEST:
+		  /* top two bits in byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0xc0){
+			   return FALSE;
+		  }
+		  /* top 4 bits in byte 1 must be 0x80 */
+		  tmpbyte=tvb_get_guint8(tvb, offset+1);
+		  if((tmpbyte&0xf0)!=0x80){
+			   return FALSE;
+		  }
+		  /* for status/snack and datack itt must be 0xffffffff
+		   * for rdata/snack ttt must not be 0 or 0xffffffff
+		   */
+		  switch(tmpbyte&0x0f){
+		  case 1:
+		  case 2:
+			   if(tvb_get_letohl(tvb,offset+16)!=0xffffffff){
+					return FALSE;
+			   }
+			   break;
+		  case 3:
+			   if(tvb_get_letohl(tvb,offset+20)==0xffffffff){
+					return FALSE;
+			   }
+			   if(tvb_get_letohl(tvb,offset+20)==0){
+					return FALSE;
+			   }
+			   break;
+		  }
+		  /* bytes 2,3 must be null */
+		  if(tvb_get_letohs(tvb,offset+2)){
+			   return FALSE;
+		  }
+		  /* the 32bit words at offsets 24, 32, 36
+		   * must all be 0
+		   */
+		  if(tvb_get_letohl(tvb,offset+24)
+			 || tvb_get_letohl(tvb,offset+32)
+			 || tvb_get_letohl(tvb,offset+36)){
+			   return FALSE;
+		  }
+
+		  break;
+	 case ISCSIEXPERT_OPCODE_R2T:
+		  /* top two bits in byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0xc0){
+			   return FALSE;
+		  }
+		  /* byte 1 must be 0x80 */
+		  if(tvb_get_guint8(tvb, offset+1)!=0x80){
+			   return FALSE;
+		  }
+		  /* bytes 2,3 must be null */
+		  if(tvb_get_letohs(tvb,offset+2)){
+			   return FALSE;
+		  }
+		  /* ahs and dsl must be null */
+		  if(tvb_get_letohl(tvb,offset+4)){
+			   return FALSE;
+		  }
+		  /* desired data transfer length must not be null */
+		  if(!tvb_get_letohl(tvb,offset+44)){
+			   return FALSE;
+		  }
+		  break;
+	 case ISCSIEXPERT_OPCODE_REJECT:
+		  /* top two bits in byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0xc0){
+			   return FALSE;
+		  }
+		  /* byte 1 must be 0x80 */
+		  if(tvb_get_guint8(tvb, offset+1)!=0x80){
+			   return FALSE;
+		  }
+		  /* reason must be known */
+		  if(!match_strval(tvb_get_guint8(tvb,offset+2), iscsiexpert_reject_reasons)){
+			   return FALSE;
+		  }
+		  /* byte 3 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+3)){
+			   return FALSE;
+		  }
+		  /* the 32bit words at offsets 8, 12, 20, 40, 44
+		   * must all be 0
+		   */
+		  if(tvb_get_letohl(tvb,offset+8)
+			 || tvb_get_letohl(tvb,offset+12)
+			 || tvb_get_letohl(tvb,offset+20)
+			 || tvb_get_letohl(tvb,offset+40)
+			 || tvb_get_letohl(tvb,offset+44)){
+			   return FALSE;
+		  }
+		  /* the 32bit word at 16 must be 0xffffffff */
+		  if(tvb_get_letohl(tvb,offset+16)!=0xffffffff){
+			   return FALSE;
+		  }
+		  break;
+	 case ISCSIEXPERT_OPCODE_TEXT_COMMAND:
+		  /* top bit in byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0x80){
+			   return FALSE;
+		  }
+		  /* one of the F and C bits must be set but not both
+		   * low 6 bits in byte 1 must be 0
+		   */
+		  switch(tvb_get_guint8(tvb,offset+1)){
+		  case 0x80:
+		  case 0x40:
+			   break;
+		  default:
+			   return FALSE;
+		  }
+		  /* bytes 2,3 must be null */
+		  if(tvb_get_letohs(tvb,offset+2)){
+			   return FALSE;
+		  }
+		  /* the 32bit words at offsets 32, 36, 40, 44
+		   * must all be 0
+		   */
+		  if(tvb_get_letohl(tvb,offset+32)
+			 || tvb_get_letohl(tvb,offset+36)
+			 || tvb_get_letohl(tvb,offset+40)
+			 || tvb_get_letohl(tvb,offset+44)){
+			   return FALSE;
+		  }
+		  break;
+	 case ISCSIEXPERT_OPCODE_TEXT_RESPONSE:
+		  /* top two bits in byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0xc0){
+			   return FALSE;
+		  }
+		  /* one of the F and C bits must be set but not both
+		   * low 6 bits in byte 1 must be 0
+		   */
+		  switch(tvb_get_guint8(tvb,offset+1)){
+		  case 0x80:
+		  case 0x40:
+			   break;
+		  default:
+			   return FALSE;
+		  }
+		  /* bytes 2,3 must be null */
+		  if(tvb_get_letohs(tvb,offset+2)){
+			   return FALSE;
+		  }
+		  /* the 32bit words at offsets 36, 40, 44
+		   * must all be 0
+		   */
+		  if(tvb_get_letohl(tvb,offset+36)
+			 || tvb_get_letohl(tvb,offset+40)
+			 || tvb_get_letohl(tvb,offset+44)){
+			   return FALSE;
+		  }
+		  break;
+	 case ISCSIEXPERT_OPCODE_SCSI_COMMAND:
+		  /* top bit in byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0x80){
+			   return FALSE;
+		  }
+		  /* reserved bits in byte 1 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+1)&0x18){
+			   return FALSE;
+		  }
+		  /* bytes 2,3 must be null */
+		  if(tvb_get_letohs(tvb,offset+2)){
+			   return FALSE;
+		  }
+		  /* last 6 bytes of LUN are always 0 */
+		  if(tvb_get_ntohs(tvb, offset+10) || tvb_get_ntohl(tvb, offset+12)){
+			   return FALSE;
+		  }
+		  /* expected data transfer length is never >16MByte ? */
+		  if(tvb_get_guint8(tvb,offset+20)){
+			   return FALSE;
+		  }
+		  break;
+	 case ISCSIEXPERT_OPCODE_SCSI_RESPONSE:
+		  /* top two bits in byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0xc0){
+			   return FALSE;
+		  }
+		  /* top bit in byte 1 must be 1 */
+		  tmpbyte=tvb_get_guint8(tvb,offset+1);
+		  if(!(tmpbyte&0x80)){
+			   return FALSE;
+		  }
+		  /* the reserved bits in byte 1 must be 0 */
+		  if(tmpbyte&0x61){
+			   return FALSE;
+		  }
+		  /* status must be known */
+		  if(!match_strval(tvb_get_guint8(tvb,offset+3), scsi_status_val)){
+			   return FALSE;
+		  }
+		  /* the 32bit words at offsets 8, 12
+		   * must all be 0
+		   */
+		  if(tvb_get_letohl(tvb,offset+8)
+			 || tvb_get_letohl(tvb,offset+12)){
+			   return FALSE;
+		  }
+		  break;
+	 case ISCSIEXPERT_OPCODE_ASYNC_MESSAGE:
+		  /* top two bits in byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0xc0){
+			   return FALSE;
+		  }
+		  /* byte 1 must be 0x80 */
+		  if(tvb_get_guint8(tvb, offset+1)!=0x80){
+			   return FALSE;
+		  }
+		  /* bytes 2,3 must be null */
+		  if(tvb_get_letohs(tvb,offset+2)){
+			   return FALSE;
+		  }
+		  /* the 32bit words at offsets 20, 44
+		   * must all be 0
+		   */
+		  if(tvb_get_letohl(tvb,offset+20)
+			 || tvb_get_letohl(tvb,offset+44)){
+			   return FALSE;
+		  }
+		  /* the 32bit word at 16 must be 0xffffffff */
+		  if(tvb_get_letohl(tvb,offset+16)!=0xffffffff){
+			   return FALSE;
+		  }
+		  break;
+	 case ISCSIEXPERT_OPCODE_LOGOUT_RESPONSE:
+		  /* top two bits in byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0xc0){
+			   return FALSE;
+		  }
+		  /* byte 1 must be 0x80 */
+		  if(tvb_get_guint8(tvb, offset+1)!=0x80){
+			   return FALSE;
+		  }
+		  /* byte 3 must be 0 */
+		  if(tvb_get_guint8(tvb,offset+3)){
+			   return FALSE;
+		  }
+		  /* ahs and dsl	as well as the 32bit words at offsets 8, 12, 20, 36
+		   * 44 must all be 0
+		   */
+		  if(tvb_get_letohl(tvb,offset+4)
+			 || tvb_get_letohl(tvb,offset+8)
+			 || tvb_get_letohl(tvb,offset+12)
+			 || tvb_get_letohl(tvb,offset+20)
+			 || tvb_get_letohl(tvb,offset+36)
+			 || tvb_get_letohl(tvb,offset+44)){
+			   return FALSE;
+		  }
+		  break;
+	 case ISCSIEXPERT_OPCODE_SCSI_DATA_OUT:
+		  /* top two bits in byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0xc0){
+			   return FALSE;
+		  }
+		  /* low 7 bits in byte 1 must be 0 */
+		  if(tvb_get_guint8(tvb,offset+1)&0x7f){
+			   return FALSE;
+		  }
+		  /* bytes 2,3 must be null */
+		  if(tvb_get_letohs(tvb,offset+2)){
+			   return FALSE;
+		  }
+		  /* the 32bit words at offsets 24, 32, 44
+		   * must all be 0
+		   */
+		  if(tvb_get_letohl(tvb,offset+24)
+			 || tvb_get_letohl(tvb,offset+32)
+			 || tvb_get_letohl(tvb,offset+44)){
+			   return FALSE;
+		  }
+		  break;
+	 case ISCSIEXPERT_OPCODE_SCSI_DATA_IN:
+		  /* top two bits in byte 0 must be 0 */
+		  if(tvb_get_guint8(tvb, offset+0)&0xc0){
+			   return FALSE;
+		  }
+		  /* reserved bits in byte 1 must be 0 */
+		  if(tvb_get_guint8(tvb,offset+1)&0x38){
+			   return FALSE;
+		  }
+		  /* byte 2 must be reserved */
+		  if(tvb_get_guint8(tvb,offset+2)){
+			   return FALSE;
+		  }
+		  break;
+	 case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I0:
+	 case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I1:
+	 case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I2:
+	 case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T0:
+	 case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T1:
+	 case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T2:
+		  break;
+	 default:
+		  /* When opcode is not valid, it should be checked by Rule No.27. */
+		  /* return TRUE; */
+		  /* return FALSE; */
+		  ;
+	 }
+
+
+	 /* process multiple iSCSI PDUs per packet */
+	 while(available_bytes >= 48 || (iscsiexpert_desegment && available_bytes >= 8)) {
+		  const char *opcode_str = NULL;
+		  guint32 data_segment_len;
+		  guint32 pduLen = 48;
+		  guint8 secondPduByte = tvb_get_guint8(tvb, offset + 1);
+		  int badPdu = FALSE;
+		  guint8 ahsLen=0;
+
+
+		  /* mask out any extra bits in the opcode byte */
+		  opcode = tvb_get_guint8(tvb, offset + 0);
+		  opcode &= OPCODE_MASK;
+
+		  opcode_str = match_strval(opcode, iscsiexpert_opcodes);
+		  if(opcode == ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION ||
+			 opcode == ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION_RESPONSE ||
+			 opcode == ISCSIEXPERT_OPCODE_R2T ||
+			 opcode == ISCSIEXPERT_OPCODE_LOGOUT_COMMAND ||
+			 opcode == ISCSIEXPERT_OPCODE_LOGOUT_RESPONSE ||
+			 opcode == ISCSIEXPERT_OPCODE_SNACK_REQUEST)
+			   data_segment_len = 0;
+		  else
+			   data_segment_len = tvb_get_ntohl(tvb, offset + 4) & 0x00ffffff;
+
+		  /* This should be checked by expert rule No.32. */
+		  if(opcode_str == NULL) {
+			   /* badPdu = TRUE; */
+			   ;
+		  }
+		  else if(check_port && iscsiexpert_port != 0 &&
+				  (((opcode & TARGET_OPCODE_BIT) && pinfo->srcport != iscsiexpert_port) ||
+				   (!(opcode & TARGET_OPCODE_BIT) && pinfo->destport != iscsiexpert_port))) {
+			   badPdu = TRUE;
+		  }
+		  else if(enable_bogosity_filter) {
+			   /* try and distinguish between data and real headers */
+			   if(data_segment_len > bogus_pdu_data_length_threshold) {
+					badPdu = TRUE;
+			   }
+			   else if(demand_good_f_bit &&
+					   !(secondPduByte & 0x80) &&
+					   (opcode == ISCSIEXPERT_OPCODE_NOP_OUT ||
+						opcode == ISCSIEXPERT_OPCODE_NOP_IN ||
+						opcode == ISCSIEXPERT_OPCODE_LOGOUT_COMMAND ||
+						opcode == ISCSIEXPERT_OPCODE_LOGOUT_RESPONSE ||
+						opcode == ISCSIEXPERT_OPCODE_SCSI_RESPONSE ||
+						opcode == ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION_RESPONSE ||
+						opcode == ISCSIEXPERT_OPCODE_R2T ||
+						opcode == ISCSIEXPERT_OPCODE_ASYNC_MESSAGE ||
+						opcode == ISCSIEXPERT_OPCODE_SNACK_REQUEST ||
+						opcode == ISCSIEXPERT_OPCODE_REJECT)) {
+					badPdu = TRUE;
+			   } else if(opcode==ISCSIEXPERT_OPCODE_NOP_OUT) {
+					/* TransferTag for NOP-Out should either be -1 or
+					   the tag value we want for a response.
+					   Assume 0 means we are just inside a big all zero
+					   datablock.
+					*/
+					if(tvb_get_ntohl(tvb, offset+20)==0){
+						 badPdu = TRUE;
+					}
+			   }
+		  }
+
+		  if(badPdu) {
+			   return iscsiexpertPdusDissected > 0;
+		  }
+
+		  if(opcode == ISCSIEXPERT_OPCODE_LOGIN_COMMAND ||
+			 opcode == ISCSIEXPERT_OPCODE_LOGIN_RESPONSE) {
+			   if(iscsiexpert_protocol_version == ISCSIEXPERT_PROTOCOL_DRAFT08) {
+					if((secondPduByte & CSG_MASK) < ISCSIEXPERT_CSG_OPERATIONAL_NEGOTIATION) {
+						 /* digests are not yet turned on */
+						 digestsActive = 0;
+					}
+			   } else {
+					digestsActive = 0;
+			   }
+		  }
+
+		  if(opcode == ISCSIEXPERT_OPCODE_SCSI_COMMAND) {
+			   /* ahsLen */
+			   ahsLen = tvb_get_guint8(tvb, offset + 4);
+			   pduLen += ahsLen * 4;
+		  }
+
+		  pduLen += data_segment_len;
+		  if((pduLen & 3) != 0)
+			   pduLen += 4 - (pduLen & 3);
+
+
+		  if(digestsActive && data_segment_len > 0 && enableDataDigests) {
+			   if(dataDigestIsCRC32)
+					pduLen += 4;
+			   else
+					pduLen += dataDigestSize;
+		  }
+
+        {
+			   /* make sure we have a conversation for this session */
+			   conversation = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst,
+												 pinfo->ptype, pinfo->srcport,
+												 pinfo->destport, 0);
+			   if (!conversation) {
+					if (FALSE == opcode_is_valid(opcode)) {
+						//ignore the first invalid opcode packet
+						return TRUE;
+					}
+               		conversation = conversation_new (pinfo->fd->num, &pinfo->src, &pinfo->dst,
+                                                 pinfo->ptype, pinfo->srcport,
+                                                 pinfo->destport, 0);
+            }
+
+			   iscsiexpert_session=conversation_get_proto_data(conversation, proto_iscsiexpert);
+			   if(!iscsiexpert_session){
+				   	if (FALSE == opcode_is_valid(opcode)) {
+						//ignore the first invalid opcode packet
+						return TRUE;
+					}
+
+					iscsiexpert_session=se_alloc(sizeof(iscsiexpert_session_t));
+					iscsiexpert_connection_init(iscsiexpert_session);
+				if (iscsiexpert_is_iscsirsp(opcode)) {
+					COPY_ADDRESS(&iscsiexpert_session->target_addr, &pinfo->src);
+					COPY_ADDRESS(&iscsiexpert_session->initiaor_addr, &pinfo->dst);
+					iscsiexpert_session->target_port = pinfo->srcport;
+					iscsiexpert_session->initiator_port	= pinfo->destport;
+				}else{
+					COPY_ADDRESS(&iscsiexpert_session->target_addr, &pinfo->dst);
+					COPY_ADDRESS(&iscsiexpert_session->initiaor_addr, &pinfo->src);
+					iscsiexpert_session->target_port = pinfo->destport;
+					iscsiexpert_session->initiator_port	= pinfo->srcport;
+				}
+                conversation_add_proto_data(conversation, proto_iscsiexpert, iscsiexpert_session);
+
+					/* DataOut PDUs are often mistaken by DCERPC heuristics to be
+					 * that protocol. Now that we know this is iscsi, set a
+					 * dissector for this conversation to block other heuristic
+					 * dissectors.
+					 */
+					conversation_set_dissector(conversation, iscsiexpert_handle);
+			   }
+
+			   if (0 != tsih){
+					iscsiexpert_session->tsih=tsih;
+			   }
+
+			   if (is_isid_vaild(&isid)){
+					memcpy(&iscsiexpert_session->isid,&isid,sizeof(iscsi_isid_tx_t));
+			   }
+
+			   if(ISCSIEXPERT_UNVAILD_CID != cid){
+					iscsiexpert_session->cid=cid;
+			   }
+		  }
+
+		  {
+			   /* make sure we have a iscsisession for this session */
+			   iscsisession = find_iscsisession_with_ssid (pinfo->fd->num,&iscsiexpert_session->isid,iscsiexpert_session->tsih);
+			   if (!iscsisession) {
+					iscsisession = find_iscsisession (pinfo->fd->num, &pinfo->src, &pinfo->dst,
+													  pinfo->srcport,pinfo->destport, 0);
+
+					if (iscsisession){
+						 //if (is_new_connection(iscsisession,pinfo->fd->num,&iscsiexpert_session->isid,iscsiexpert_session->tsih)) {
+						 if (is_vaild_ssid(&iscsiexpert_session->isid,iscsiexpert_session->tsih)){
+							  //get the session ssid and set
+							  set_iscsisession_ssid (iscsisession,pinfo->fd->num, &iscsiexpert_session->isid,iscsiexpert_session->tsih);
+						 }
+					}else {
+						 iscsisession = iscsisession_new (pinfo->fd->num, &pinfo->src, &pinfo->dst,
+														  pinfo->srcport,pinfo->destport, 0,&isid,tsih);
+					}
+			   }
+
+			   iscsiexpert_sessionset = iscsisession_get_proto_data(iscsisession, proto_iscsiexpert);
+			   if(!iscsiexpert_sessionset){
+					iscsiexpert_sessionset=se_alloc(sizeof(iscsiexpert_sessionset_t));
+					iscsiexpert_session_init(iscsiexpert_sessionset);
+                    iscsiexpert_sessionset->init_fd = pinfo->fd->num;
+					if (FALSE == iscsiexpert_is_iscsirsp(opcode)) {
+						//record the first iscsi packet information
+						iscsiexpert_sessionset->cmdsn   = tvb_get_ntohl(tvb, offset + 24);
+						iscsiexpert_sessionset->cur_i_bit = is_immediate_iscsi_cmd(tvb_get_guint8(tvb, offset + 0));
+//  					ISCSIE_DEBUG("frame number: %d,cur_i_bit = %s\n",
+//  							pinfo->fd->num,
+//  							iscsiexpert_sessionset->cur_i_bit?"YES":"No");
+					}
+
+					iscsisession_add_proto_data(iscsisession, proto_iscsiexpert, iscsiexpert_sessionset);
+			   }
+
+			   {
+					if (FALSE == iscsiexpert_session->in_session){
+						 iscsiexpert_session->in_session = TRUE;
+						 iscsiexpert_sessionset->conn_count++;
+
+						 iscsiexpert_session->sess_index = iscsisession->index;
+						 se_tree_insert32(iscsiexpert_sessionset->connq,iscsiexpert_sessionset->conn_count, conversation);
+
+					}
+			   }
+		  }
+
+
+		  /* try to autodetect if header digest is used or not */
+		  if(digestsActive && (available_bytes>=(guint32) (48+4+ahsLen*4)) && (iscsiexpert_session->params.header_digest.value==ISCSIEXPERT_HEADER_DIGEST_AUTO) ){
+			   guint32 crc;
+			   /* we have enough data to test if HeaderDigest is enabled */
+			   crc= ~calculate_crc32c(tvb_get_ptr(tvb, offset, 48+ahsLen*4), 48+ahsLen*4, CRC32C_PRELOAD);
+			   if(crc==tvb_get_ntohl(tvb,48+ahsLen*4)){
+                iscsiexpert_session->params.header_digest.value=ISCSIEXPERT_HEADER_DIGEST_CRC32;
+			   } else {
+                iscsiexpert_session->params.header_digest.value=ISCSIEXPERT_HEADER_DIGEST_NONE;
+			   }
+		  }
+
+
+		  /* Add header digest length to pdulen */
+		  if(digestsActive){
+            switch(iscsiexpert_session->params.header_digest.value){
+			   case ISCSIEXPERT_HEADER_DIGEST_CRC32:
+					pduLen += 4;
+					break;
+			   case ISCSIEXPERT_HEADER_DIGEST_NONE:
+					break;
+			   case ISCSIEXPERT_HEADER_DIGEST_AUTO:
+					/* oops we didnt know what digest is used yet */
+					/* here we should use some default */
+					break;
+			   default:
+					DISSECTOR_ASSERT_NOT_REACHED();
+			   }
+		  }
+
+		  /*
+		   * Desegmentation check.
+		   */
+		  if(iscsiexpert_desegment && pinfo->can_desegment) {
+			   if(pduLen > available_bytes) {
+					/*
+					 * This frame doesn't have all of the data for
+					 * this message, but we can do reassembly on it.
+					 *
+					 * Tell the TCP dissector where the data for this
+					 * message starts in the data it handed us, and
+					 * how many more bytes we need, and return.
+					 */
+					pinfo->desegment_offset = offset;
+					pinfo->desegment_len = pduLen - available_bytes;
+					return TRUE;
+			   }
+		  }
+
+		  /* This is to help TCP keep track of PDU boundaries
+			 and allows it to find PDUs that are not aligned to
+			 the start of a TCP segments.
+			 Since it also allows TCP to know what is in the middle
+			 of a large PDU, it reduces the probability of a segment
+			 in the middle of a large PDU transfer being misdissected as
+			 a PDU.
+		  */
+		  if(!pinfo->fd->flags.visited){
+			   if(pduLen>(guint32)tvb_reported_length_remaining(tvb, offset)){
+					pinfo->want_pdu_tracking=2;
+					pinfo->bytes_until_next_pdu=pduLen-tvb_reported_length_remaining(tvb, offset);
+			   }
+		  }
+
+		  if(check_col(pinfo->cinfo, COL_INFO)) {
+			   if(iscsiexpertPdusDissected == 0)
+					col_set_str(pinfo->cinfo, COL_INFO, "");
+			   else
+					col_append_str(pinfo->cinfo, COL_INFO, ", ");
+		  }
+
+		  dissect_iscsiexpert_pdu(tvb, pinfo, tree, offset, opcode, opcode_str, data_segment_len, iscsiexpert_session, conversation,iscsiexpert_sessionset);
+		  if(pduLen > available_bytes)
+			   pduLen = available_bytes;
+		  offset += pduLen;
+		  available_bytes -= pduLen;
+		  ++iscsiexpertPdusDissected;
+	 }
+
+
+	 return iscsiexpertPdusDissected > 0;
+}
+
+/* This is called for those sessions where we have explicitely said
+   this to be iSCSI using "Decode As..."
+   In this case we will not check the port number for sanity and just
+   do as the user said.
+   We still check that the PDU header looks sane though.
+*/
+static int
+dissect_iscsiexpert_handle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
+	 //here is the place where the resemble packet is handled
+	 return dissect_iscsiexpert_msg(tvb, pinfo, tree, FALSE);
+}
+
+/* This is called through the heuristic handler.
+   In this case we also want to check that the port matches the preference
+   setting for iSCSI in order to reduce the number of
+   false positives.
+*/
+static gboolean
+dissect_iscsiexpert_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
+	 guint32 available_bytes = tvb_length(tvb);
+
+	 /* quick check to see if the packet is long enough to contain the
+	  * minimum amount of information we need */
+	 if (available_bytes < 48 ){
+		  /* no, so give up */
+		  return FALSE;
+	 }
+
+	 return dissect_iscsiexpert_msg(tvb, pinfo, tree, TRUE);
+}
+
+
+/* Register the protocol with Wireshark */
+
+/*
+ * this format is require because a script is used to build the C
+ * function that calls all the protocol registration.
+ */
+
+void
+proto_register_iscsiexpertexpert(void)
+{
+
+	 /* Setup list of header fields	See Section 1.6.1 for details*/
+	 static hf_register_info hf[] = {
+		  { &hf_iscsiexpert_request_frame,
+			{ "Request in", "iscsi.request_frame",
+			  FT_FRAMENUM, BASE_NONE, NULL, 0,
+			  "The request to this transaction is in this frame", HFILL }},
+
+		  { &hf_iscsiexpert_time,
+			{ "Time from request", "iscsi.time",
+			  FT_RELATIVE_TIME, BASE_NONE, NULL, 0,
+			  "Time between the Command and the Response", HFILL }},
+
+		  { &hf_iscsiexpert_data_in_frame,
+			{ "Data In in", "iscsi.data_in_frame",
+			  FT_FRAMENUM, BASE_NONE, NULL, 0,
+			  "The Data In for this transaction is in this frame", HFILL }},
+
+		  { &hf_iscsiexpert_data_out_frame,
+			{ "Data Out in", "iscsi.data_out_frame",
+			  FT_FRAMENUM, BASE_NONE, NULL, 0,
+			  "The Data Out for this transaction is in this frame", HFILL }},
+
+		  { &hf_iscsiexpert_response_frame,
+			{ "Response in", "iscsi.response_frame",
+			  FT_FRAMENUM, BASE_NONE, NULL, 0,
+			  "The response to this transaction is in this frame", HFILL }},
+
+		  { &hf_iscsiexpert_AHS,
+			{ "AHS", "iscsi.ahs",
+			  FT_BYTES, BASE_HEX, NULL, 0,
+			  "Additional header segment", HFILL }
+		  },
+		  { &hf_iscsiexpert_AHS_length,
+			{ "AHS Length", "iscsi.ahs.length",
+			  FT_UINT16, BASE_DEC, NULL, 0,
+			  "Length of Additional header segment", HFILL }
+		  },
+		  { &hf_iscsiexpert_AHS_read_data_length,
+			{ "Bidirectional Read Data Length", "iscsi.ahs.bidir.length",
+			  FT_UINT32, BASE_DEC, NULL, 0,
+			  "", HFILL }
+		  },
+		  { &hf_iscsiexpert_AHS_type,
+			{ "AHS Type", "iscsi.ahs.type",
+			  FT_UINT8, BASE_DEC, VALS(ahs_type_vals), 0,
+			  "Type of Additional header segment", HFILL }
+		  },
+		  { &hf_iscsiexpert_AHS_extended_cdb,
+			{ "AHS Extended CDB", "iscsi.ahs.extended_cdb",
+			  FT_BYTES, BASE_HEX, NULL, 0,
+			  "", HFILL }
+		  },
+		  { &hf_iscsiexpert_AHS_blob,
+			{ "Unknown AHS blob", "iscsi.ahs.unknown_blob",
+			  FT_BYTES, BASE_HEX, NULL, 0,
+			  "", HFILL }
+		  },
+		  { &hf_iscsiexpert_Padding,
+			{ "Padding", "iscsi.padding",
+			  FT_BYTES, BASE_HEX, NULL, 0,
+			  "Padding to 4 byte boundary", HFILL }
+		  },
+		  { &hf_iscsiexpert_ping_data,
+			{ "PingData", "iscsi.pingdata",
+			  FT_BYTES, BASE_HEX, NULL, 0,
+			  "Ping Data", HFILL }
+		  },
+		  { &hf_iscsiexpert_immediate_data,
+			{ "ImmediateData", "iscsi.immediatedata",
+			  FT_BYTES, BASE_HEX, NULL, 0,
+			  "Immediate Data", HFILL }
+		  },
+		  { &hf_iscsiexpert_write_data,
+			{ "WriteData", "iscsi.writedata",
+			  FT_BYTES, BASE_HEX, NULL, 0,
+			  "Write Data", HFILL }
+		  },
+		  { &hf_iscsiexpert_read_data,
+			{ "ReadData", "iscsi.readdata",
+			  FT_BYTES, BASE_HEX, NULL, 0,
+			  "Read Data", HFILL }
+		  },
+		  { &hf_iscsiexpert_error_pdu_data,
+			{ "ErrorPDUData", "iscsi.errorpdudata",
+			  FT_BYTES, BASE_HEX, NULL, 0,
+			  "Error PDU Data", HFILL }
+		  },
+		  { &hf_iscsiexpert_async_event_data,
+			{ "AsyncEventData", "iscsi.asynceventdata",
+			  FT_BYTES, BASE_HEX, NULL, 0,
+			  "Async Event Data", HFILL }
+		  },
+		  { &hf_iscsiexpert_vendor_specific_data,
+			{ "VendorSpecificData", "iscsi.vendorspecificdata",
+			  FT_BYTES, BASE_HEX, NULL, 0,
+			  "Vendor Specific Data", HFILL }
+		  },
+		  { &hf_iscsiexpert_HeaderDigest32,
+			{ "HeaderDigest", "iscsi.headerdigest32",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Header Digest", HFILL }
+		  },
+		  { &hf_iscsiexpert_DataDigest,
+			{ "DataDigest", "iscsi.datadigest",
+			  FT_BYTES, BASE_HEX, NULL, 0,
+			  "Data Digest", HFILL }
+		  },
+		  { &hf_iscsiexpert_DataDigest32,
+			{ "DataDigest", "iscsi.datadigest32",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Data Digest", HFILL }
+		  },
+		  { &hf_iscsiexpert_Opcode,
+			{ "Opcode", "iscsi.opcode",
+			  FT_UINT8, BASE_HEX, VALS(iscsiexpert_opcodes), 0,
+			  "Opcode", HFILL }
+		  },
+		  /* #ifdef DRAFT08 */
+		  { &hf_iscsiexpert_X,
+			{ "X", "iscsi.X",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_X), 0x80,
+			  "Command Retry", HFILL }
+		  },
+		  /* #endif */
+		  { &hf_iscsiexpert_I,
+			{ "I", "iscsi.I",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_I), 0x40,
+			  "Immediate delivery", HFILL }
+		  },
+		  { &hf_iscsiexpert_Flags,
+			{ "Flags", "iscsi.flags",
+			  FT_UINT8, BASE_HEX, NULL, 0,
+			  "Opcode specific flags", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSICommand_F,
+			{ "F", "iscsi.scsicommand.F",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_F), 0x80,
+			  "PDU completes command", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSICommand_R,
+			{ "R", "iscsi.scsicommand.R",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_R), 0x40,
+			  "Command reads from SCSI target", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSICommand_W,
+			{ "W", "iscsi.scsicommand.W",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_W), 0x20,
+			  "Command writes to SCSI target", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSICommand_Attr,
+			{ "Attr", "iscsi.scsicommand.attr",
+			  FT_UINT8, BASE_HEX, VALS(iscsiexpert_scsicommand_taskattrs), 0x07,
+			  "SCSI task attributes", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSICommand_CRN,
+			{ "CRN", "iscsi.scsicommand.crn",
+			  FT_UINT8, BASE_HEX, NULL, 0,
+			  "SCSI command reference number", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSICommand_AddCDB,
+			{ "AddCDB", "iscsi.scsicommand.addcdb",
+			  FT_UINT8, BASE_HEX, NULL, 0,
+			  "Additional CDB length (in 4 byte units)", HFILL }
+		  },
+		  { &hf_iscsiexpert_DataSegmentLength,
+			{ "DataSegmentLength", "iscsi.datasegmentlength",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Data segment length (bytes)", HFILL }
+		  },
+		  { &hf_iscsiexpert_TotalAHSLength,
+			{ "TotalAHSLength", "iscsi.totalahslength",
+			  FT_UINT8, BASE_HEX, NULL, 0,
+			  "Total additional header segment length (4 byte words)", HFILL }
+		  },
+		  { &hf_iscsiexpert_LUN,
+			{ "LUN", "iscsi.lun",
+			  FT_BYTES, BASE_HEX, NULL, 0,
+			  "Logical Unit Number", HFILL }
+		  },
+		  { &hf_iscsiexpert_InitiatorTaskTag,
+			{ "InitiatorTaskTag", "iscsi.initiatortasktag",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Initiator's task tag", HFILL }
+		  },
+		  { &hf_iscsiexpert_ExpectedDataTransferLength,
+			{ "ExpectedDataTransferLength", "iscsi.scsicommand.expecteddatatransferlength",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Expected length of data transfer", HFILL }
+		  },
+		  { &hf_iscsiexpert_CmdSN,
+			{ "CmdSN", "iscsi.cmdsn",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Sequence number for this command", HFILL }
+		  },
+		  { &hf_iscsiexpert_ExpStatSN,
+			{ "ExpStatSN", "iscsi.expstatsn",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Next expected status sequence number", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSIResponse_ResidualCount,
+			{ "ResidualCount", "iscsi.scsiresponse.residualcount",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Residual count", HFILL }
+		  },
+		  { &hf_iscsiexpert_StatSN,
+			{ "StatSN", "iscsi.statsn",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Status sequence number", HFILL }
+		  },
+		  { &hf_iscsiexpert_ExpCmdSN,
+			{ "ExpCmdSN", "iscsi.expcmdsn",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Next expected command sequence number", HFILL }
+		  },
+		  { &hf_iscsiexpert_MaxCmdSN,
+			{ "MaxCmdSN", "iscsi.maxcmdsn",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Maximum acceptable command sequence number", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSIResponse_o,
+			{ "o", "iscsi.scsiresponse.o",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_o), 0x10,
+			  "Bi-directional read residual overflow", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSIResponse_u,
+			{ "u", "iscsi.scsiresponse.u",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_u), 0x08,
+			  "Bi-directional read residual underflow", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSIResponse_O,
+			{ "O", "iscsi.scsiresponse.O",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_O), 0x04,
+			  "Residual overflow", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSIResponse_U,
+			{ "U", "iscsi.scsiresponse.U",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_U), 0x02,
+			  "Residual underflow", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSIResponse_Status,
+			{ "Status", "iscsi.scsiresponse.status",
+			  FT_UINT8, BASE_HEX, VALS(scsi_status_val), 0,
+			  "SCSI command status value", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSIResponse_Response,
+			{ "Response", "iscsi.scsiresponse.response",
+			  FT_UINT8, BASE_HEX, VALS(iscsiexpert_scsi_responses), 0,
+			  "SCSI command response value", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSIResponse_BidiReadResidualCount,
+			{ "BidiReadResidualCount", "iscsi.scsiresponse.bidireadresidualcount",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Bi-directional read residual count", HFILL }
+		  },
+		  { &hf_iscsiexpert_SenseLength,
+			{ "SenseLength", "iscsi.scsiresponse.senselength",
+			  FT_UINT16, BASE_HEX, NULL, 0,
+			  "Sense data length", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSIData_F,
+			{ "F", "iscsi.scsidata.F",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_F), ISCSIEXPERT_SCSI_DATA_FLAG_F,
+			  "Final PDU", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSIData_A,
+			{ "A", "iscsi.scsidata.A",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_A), ISCSIEXPERT_SCSI_DATA_FLAG_A,
+			  "Acknowledge Requested", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSIData_S,
+			{ "S", "iscsi.scsidata.S",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_S), ISCSIEXPERT_SCSI_DATA_FLAG_S,
+			  "PDU Contains SCSI command status", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSIData_U,
+			{ "U", "iscsi.scsidata.U",
+			  FT_BOOLEAN, 8,	TFS(&iscsiexpert_meaning_U), ISCSIEXPERT_SCSI_DATA_FLAG_U,
+			  "Residual underflow", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSIData_O,
+			{ "O", "iscsi.scsidata.O",
+			  FT_BOOLEAN, 8,	TFS(&iscsiexpert_meaning_O), ISCSIEXPERT_SCSI_DATA_FLAG_O,
+			  "Residual overflow", HFILL }
+		  },
+		  { &hf_iscsiexpert_TargetTransferTag,
+			{ "TargetTransferTag", "iscsi.targettransfertag",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Target transfer tag", HFILL }
+		  },
+		  { &hf_iscsiexpert_BufferOffset,
+			{ "BufferOffset", "iscsi.bufferOffset",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Buffer offset", HFILL }
+		  },
+		  { &hf_iscsiexpert_SCSIData_ResidualCount,
+			{ "ResidualCount", "iscsi.scsidata.readresidualcount",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Residual count", HFILL }
+		  },
+		  { &hf_iscsiexpert_DataSN,
+			{ "DataSN", "iscsi.datasn",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Data sequence number", HFILL }
+		  },
+		  { &hf_iscsiexpert_VersionMax,
+			{ "VersionMax", "iscsi.versionmax",
+			  FT_UINT8, BASE_HEX, NULL, 0,
+			  "Maximum supported protocol version", HFILL }
+		  },
+		  { &hf_iscsiexpert_VersionMin,
+			{ "VersionMin", "iscsi.versionmin",
+			  FT_UINT8, BASE_HEX, NULL, 0,
+			  "Minimum supported protocol version", HFILL }
+		  },
+		  { &hf_iscsiexpert_VersionActive,
+			{ "VersionActive", "iscsi.versionactive",
+			  FT_UINT8, BASE_HEX, NULL, 0,
+			  "Negotiated protocol version", HFILL }
+		  },
+		  { &hf_iscsiexpert_CID,
+			{ "CID", "iscsi.cid",
+			  FT_UINT16, BASE_HEX, NULL, 0,
+			  "Connection identifier", HFILL }
+		  },
+		  /* #ifdef DRAFT08 */
+		  { &hf_iscsiexpert_ISID8,
+			{ "ISID", "iscsi.isid",
+			  FT_UINT16, BASE_HEX, NULL, 0,
+			  "Initiator part of session identifier", HFILL }
+		  },
+		  /* #else */
+		  { &hf_iscsiexpert_ISID,
+			{ "ISID", "iscsi.isid",
+			  FT_BYTES, BASE_HEX, NULL, 0,
+			  "Initiator part of session identifier", HFILL }
+		  },
+		  /* #ifdef DRAFT09 */
+		  { &hf_iscsiexpert_ISID_Type,
+			{ "ISID_Type", "iscsi.isid.type",
+			  FT_UINT8, BASE_HEX, VALS(iscsiexpert_isid_type), 0,
+			  "Initiator part of session identifier - type", HFILL }
+		  },
+		  { &hf_iscsiexpert_ISID_NamingAuthority,
+			{ "ISID_NamingAuthority", "iscsi.isid.namingauthority",
+			  FT_UINT24, BASE_HEX, NULL, 0,
+			  "Initiator part of session identifier - naming authority", HFILL }
+		  },
+		  { &hf_iscsiexpert_ISID_Qualifier,
+			{ "ISID_Qualifier", "iscsi.isid.qualifier",
+			  FT_UINT8, BASE_HEX, NULL, 0,
+			  "Initiator part of session identifier - qualifier", HFILL }
+		  },
+		  /* #else */
+		  { &hf_iscsiexpert_ISID_t,
+			{ "ISID_t", "iscsi.isid.t",
+			  FT_UINT8, BASE_HEX, VALS(iscsiexpert_isid_type), 0xc0,
+			  "Initiator part of session identifier - t", HFILL }
+		  },
+		  { &hf_iscsiexpert_ISID_a,
+			{ "ISID_a", "iscsi.isid.a",
+			  FT_UINT8, BASE_HEX, NULL, 0x3f,
+			  "Initiator part of session identifier - a", HFILL }
+		  },
+		  { &hf_iscsiexpert_ISID_b,
+			{ "ISID_b", "iscsi.isid.b",
+			  FT_UINT16, BASE_HEX, NULL, 0,
+			  "Initiator part of session identifier - b", HFILL }
+		  },
+		  { &hf_iscsiexpert_ISID_c,
+			{ "ISID_c", "iscsi.isid.c",
+			  FT_UINT8, BASE_HEX, NULL, 0,
+			  "Initiator part of session identifier - c", HFILL }
+		  },
+		  { &hf_iscsiexpert_ISID_d,
+			{ "ISID_d", "iscsi.isid.d",
+			  FT_UINT16, BASE_HEX, NULL, 0,
+			  "Initiator part of session identifier - d", HFILL }
+		  },
+		  /* #endif */
+		  /* #endif */
+		  { &hf_iscsiexpert_TSID,
+			{ "TSID", "iscsi.tsid",
+			  FT_UINT16, BASE_HEX, NULL, 0,
+			  "Target part of session identifier", HFILL }
+		  },
+		  { &hf_iscsiexpert_TSIH,
+			{ "TSIH", "iscsi.tsih",
+			  FT_UINT16, BASE_HEX, NULL, 0,
+			  "Target session identifying handle", HFILL }
+		  },
+		  { &hf_iscsiexpert_InitStatSN,
+			{ "InitStatSN", "iscsi.initstatsn",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Initial status sequence number", HFILL }
+		  },
+		  { &hf_iscsiexpert_InitCmdSN,
+			{ "InitCmdSN", "iscsi.initcmdsn",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Initial command sequence number", HFILL }
+		  },
+		  { &hf_iscsiexpert_Login_T,
+			{ "T", "iscsi.login.T",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_T), 0x80,
+			  "Transit to next login stage",	HFILL }
+		  },
+		  { &hf_iscsiexpert_Login_C,
+			{ "C", "iscsi.login.C",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_C), 0x40,
+			  "Text incomplete",	HFILL }
+		  },
+		  /* #ifdef DRAFT09 */
+		  { &hf_iscsiexpert_Login_X,
+			{ "X", "iscsi.login.X",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_login_X), 0x40,
+			  "Restart Connection",	 HFILL }
+		  },
+		  /* #endif */
+		  { &hf_iscsiexpert_Login_CSG,
+			{ "CSG", "iscsi.login.csg",
+			  FT_UINT8, BASE_HEX, VALS(iscsiexpert_login_stage), CSG_MASK,
+			  "Current stage",	HFILL }
+		  },
+		  { &hf_iscsiexpert_Login_NSG,
+			{ "NSG", "iscsi.login.nsg",
+			  FT_UINT8, BASE_HEX, VALS(iscsiexpert_login_stage), NSG_MASK,
+			  "Next stage",	 HFILL }
+		  },
+		  { &hf_iscsiexpert_Login_Status,
+			{ "Status", "iscsi.login.status",
+			  FT_UINT16, BASE_HEX, VALS(iscsiexpert_login_status), 0,
+			  "Status class and detail", HFILL }
+		  },
+		  { &hf_iscsiexpert_KeyValue,
+			{ "KeyValue", "iscsi.keyvalue",
+			  FT_STRING, 0, NULL, 0,
+			  "Key/value pair", HFILL }
+		  },
+		  { &hf_iscsiexpert_Text_F,
+			{ "F", "iscsi.text.F",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_F), 0x80,
+			  "Final PDU in text sequence", HFILL }
+		  },
+		  { &hf_iscsiexpert_Text_C,
+			{ "C", "iscsi.text.C",
+			  FT_BOOLEAN, 8, TFS(&iscsiexpert_meaning_C), 0x40,
+			  "Text incomplete", HFILL }
+		  },
+		  { &hf_iscsiexpert_ExpDataSN,
+			{ "ExpDataSN", "iscsi.expdatasn",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Next expected data sequence number", HFILL }
+		  },
+		  { &hf_iscsiexpert_R2TSN,
+			{ "R2TSN", "iscsi.r2tsn",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "R2T PDU Number", HFILL }
+		  },
+		  { &hf_iscsiexpert_TaskManagementFunction_Response,
+			{ "Response", "iscsi.taskmanfun.response",
+			  FT_UINT8, BASE_HEX, VALS(iscsiexpert_task_management_responses), 0,
+			  "Response", HFILL }
+		  },
+		  { &hf_iscsiexpert_TaskManagementFunction_ReferencedTaskTag,
+			{ "ReferencedTaskTag", "iscsi.taskmanfun.referencedtasktag",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Referenced task tag", HFILL }
+		  },
+		  { &hf_iscsiexpert_RefCmdSN,
+			{ "RefCmdSN", "iscsi.refcmdsn",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Command sequence number for command to be aborted", HFILL }
+		  },
+		  { &hf_iscsiexpert_TaskManagementFunction_Function,
+			{ "Function", "iscsi.taskmanfun.function",
+			  FT_UINT8, BASE_HEX, VALS(iscsiexpert_task_management_functions), 0x7F,
+			  "Requested task function", HFILL }
+		  },
+		  { &hf_iscsiexpert_Logout_Reason,
+			{ "Reason", "iscsi.logout.reason",
+			  FT_UINT8, BASE_HEX, VALS(iscsiexpert_logout_reasons), 0x7F,
+			  "Reason for logout", HFILL }
+		  },
+		  { &hf_iscsiexpert_Logout_Response,
+			{ "Response", "iscsi.logout.response",
+			  FT_UINT8, BASE_HEX, VALS(iscsiexpert_logout_response), 0,
+			  "Logout response", HFILL }
+		  },
+		  { &hf_iscsiexpert_Time2Wait,
+			{ "Time2Wait", "iscsi.time2wait",
+			  FT_UINT16, BASE_HEX, NULL, 0,
+			  "Time2Wait", HFILL }
+		  },
+		  { &hf_iscsiexpert_Time2Retain,
+			{ "Time2Retain", "iscsi.time2retain",
+			  FT_UINT16, BASE_HEX, NULL, 0,
+			  "Time2Retain", HFILL }
+		  },
+		  { &hf_iscsiexpert_DesiredDataLength,
+			{ "DesiredDataLength", "iscsi.desireddatalength",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Desired data length (bytes)", HFILL }
+		  },
+		  { &hf_iscsiexpert_AsyncEvent,
+			{ "AsyncEvent", "iscsi.asyncevent",
+			  FT_UINT8, BASE_HEX, VALS(iscsiexpert_asyncevents), 0,
+			  "Async event type", HFILL }
+		  },
+		  { &hf_iscsiexpert_EventVendorCode,
+			{ "EventVendorCode", "iscsi.eventvendorcode",
+			  FT_UINT8, BASE_HEX, NULL, 0,
+			  "Event vendor code", HFILL }
+		  },
+		  { &hf_iscsiexpert_Parameter1,
+			{ "Parameter1", "iscsi.parameter1",
+			  FT_UINT16, BASE_HEX, NULL, 0,
+			  "Parameter 1", HFILL }
+		  },
+		  { &hf_iscsiexpert_Parameter2,
+			{ "Parameter2", "iscsi.parameter2",
+			  FT_UINT16, BASE_HEX, NULL, 0,
+			  "Parameter 2", HFILL }
+		  },
+		  { &hf_iscsiexpert_Parameter3,
+			{ "Parameter3", "iscsi.parameter3",
+			  FT_UINT16, BASE_HEX, NULL, 0,
+			  "Parameter 3", HFILL }
+		  },
+		  { &hf_iscsiexpert_Reject_Reason,
+			{ "Reason", "iscsi.reject.reason",
+			  FT_UINT8, BASE_HEX, VALS(iscsiexpert_reject_reasons), 0,
+			  "Reason for command rejection", HFILL }
+		  },
+		  { &hf_iscsiexpert_snack_type,
+			{ "S", "iscsi.snack.type",
+			  FT_UINT8, BASE_DEC, VALS(iscsiexpert_snack_types), 0x0f,
+			  "Type of SNACK requested", HFILL }
+		  },
+		  { &hf_iscsiexpert_BegRun,
+			{ "BegRun", "iscsi.snack.begrun",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "First missed DataSN or StatSN", HFILL }
+		  },
+		  { &hf_iscsiexpert_RunLength,
+			{ "RunLength", "iscsi.snack.runlength",
+			  FT_UINT32, BASE_HEX, NULL, 0,
+			  "Number of additional missing status PDUs in this run", HFILL }
+		  },
+		  { &hf_expert_msg,
+			{ "ISCSI Expert Message", "iscsiexpert.message", FT_STRING, BASE_NONE, NULL, 0, "Wireshark iscsiexpert information", HFILL }
+		  },
+		  { &hf_expert_group,
+			{ "ISCSI Group", "iscsiexpert.group", FT_UINT32, BASE_NONE, VALS(expert_group_vals), 0, "Wireshark iscsiexpert group", HFILL }
+		  },
+		  { &hf_expert_severity,
+			{ "ISCSI Severity level", "iscsiexpert.severity", FT_UINT32, BASE_NONE, VALS(expert_severity_vals), 0, "Wireshark iscsiexpert severity level", HFILL }
+		  }
+	 };
+
+	 /* Setup protocol subtree array */
+	 static gint *ett[] = {
+		  &ett_iscsiexpert,
+		  &ett_iscsiexpert_KeyValues,
+		  &ett_iscsiexpert_CDB,
+		  &ett_iscsiexpert_Flags,
+		  /* #ifndef DRAFT08 */
+		  &ett_iscsiexpert_ISID,
+		  /* #endif */
+		  &ett_expert,
+		  &ett_subexpert
+	 };
+
+	 /* Register the protocol name and description */
+	 proto_iscsiexpert = proto_register_protocol("iSCSI Protocol Expert", "iSCSI[E]", "iscsiexpert");
+
+	 /* Required function calls to register the header fields and
+	  * subtrees used */
+	 proto_register_field_array(proto_iscsiexpert, hf, array_length(hf));
+	 proto_register_subtree_array(ett, array_length(ett));
+
+	 {
+		  module_t *iscsiexpert_module = prefs_register_protocol(proto_iscsiexpert, NULL);
+
+		  prefs_register_enum_preference(iscsiexpert_module,
+										 "protocol_version",
+										 "Protocol version",
+										 "The iSCSI protocol version",
+										 &iscsiexpert_protocol_version,
+										 iscsiexpert_protocol_versions,
+										 FALSE);
+
+		  prefs_register_bool_preference(iscsiexpert_module,
+										 "desegment_iscsi_messages",
+										 "Reassemble iSCSI messages\nspanning multiple TCP segments",
+										 "Whether the iSCSI dissector should reassemble messages spanning multiple TCP segments."
+										 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
+										 &iscsiexpert_desegment);
+
+		  prefs_register_bool_preference(iscsiexpert_module,
+										 "bogus_pdu_filter",
+										 "Enable bogus pdu filter",
+										 "When enabled, packets that appear bogus are ignored",
+										 &enable_bogosity_filter);
+
+		  prefs_register_bool_preference(iscsiexpert_module,
+										 "demand_good_f_bit",
+										 "Ignore packets with bad F bit",
+										 "Ignore packets that haven't set the F bit when they should have",
+										 &demand_good_f_bit);
+
+		  prefs_register_uint_preference(iscsiexpert_module,
+										 "bogus_pdu_max_data_len",
+										 "Bogus pdu max data length threshold",
+										 "Treat packets whose data segment length is greater than this value as bogus",
+										 10,
+										 &bogus_pdu_data_length_threshold);
+
+
+		  prefs_register_uint_preference(iscsiexpert_module,
+										 "target_port",
+										 "Target port",
+										 "Port number of iSCSI target",
+										 10,
+										 &iscsiexpert_port);
+
+		  prefs_register_bool_preference(iscsiexpert_module,
+										 "enable_data_digests",
+										 "Enable data digests",
+										 "When enabled, pdus are assumed to contain a data digest",
+										 &enableDataDigests);
+
+		  prefs_register_bool_preference(iscsiexpert_module,
+										 "data_digest_is_crc32c",
+										 "Data digest is CRC32C",
+										 "When enabled, data digests are assumed to be CRC32C",
+										 &dataDigestIsCRC32);
+
+		  prefs_register_uint_preference(iscsiexpert_module,
+										 "data_digest_size",
+										 "Data digest size",
+										 "The size of a data digest (bytes)",
+										 10,
+										 &dataDigestSize);
+
+		  /* Preference supported in older versions.
+			 Register them as obsolete. */
+		  prefs_register_obsolete_preference(iscsiexpert_module,
+											 "version_03_compatible");
+		  prefs_register_obsolete_preference(iscsiexpert_module,
+											 "bogus_pdu_max_digest_padding");
+		  prefs_register_obsolete_preference(iscsiexpert_module,
+											 "header_digest_is_crc32c");
+		  prefs_register_obsolete_preference(iscsiexpert_module,
+											 "header_digest_size");
+		  prefs_register_obsolete_preference(iscsiexpert_module,
+											 "enable_header_digests");
+	 }
+
+	 iscsiexpert_tap = register_tap("iscsiexpert");
+
+	 iscsiexpert_tap_analyzer = register_tap("iscsiexpert_analyzer");
+	 /*To deliver session/conversation info to gtk*/
+	 iscsiexpert_tap_sesstv = register_tap("iscsiexpert_session_tv");
+	 memset((void *)&sess_tv, 0, sizeof(sess_tv));
+}
+
+/* determine PDU length of protocol foo */
+static guint get_iscsiexpert_message_len(packet_info *pinfo, tvbuff_t *tvb, int offset)
+{
+	 /* TODO: change this to your needs */
+	 guint8 abs_length = (guint8)tvb_get_guint8(tvb, offset+4);
+	 guint32 data_length = (guint32)tvb_get_ntoh24(tvb, offset+5);
+	 return 48 + abs_length + data_length; /* e.g. length is at offset 4 */
+}
+
+/* The main dissecting routine */
+static gboolean dissect_iscsi_expert(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+	 gint length = tvb_length(tvb);
+	 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 48,
+					  get_iscsiexpert_message_len, dissect_iscsiexpert_handle);
+	 return length;
+}
+
+/* The main dissecting routine */
+static gboolean dissect_iscsi_expert_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+	 gint length = tvb_length(tvb);
+	 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 48,
+					  get_iscsiexpert_message_len, dissect_iscsiexpert_heur);
+
+	 return length;
+}
+
+
+/*
+ * If this dissector uses sub-dissector registration add a
+ * registration routine.
+ */
+
+/*
+ * This format is required because a script is used to find these
+ * routines and create the code that calls these routines.
+ */
+void
+proto_reg_handoff_iscsiexpert(void)
+{
+	 heur_dissector_add("tcp", dissect_iscsiexpert_heur, proto_iscsiexpert);
+
+	 iscsiexpert_handle = new_create_dissector_handle(dissect_iscsiexpert_handle, proto_iscsiexpert);
+	 dissector_add_handle("tcp.port", iscsiexpert_handle);
+}
+
diff -urN wireshark-1.2.2/epan/dissectors/packet-iscsiexpert.h wireshark-1.2.2-iscsie/epan/dissectors/packet-iscsiexpert.h
--- wireshark-1.2.2/epan/dissectors/packet-iscsiexpert.h	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/epan/dissectors/packet-iscsiexpert.h	2010-01-20 15:17:11.000000000 +0800
@@ -0,0 +1,407 @@
+/* packet-iscsiexpert.h
+ * Definitions for packet disassembly structures and routines
+ * Copyright 2009, Ji-dong Wang <Wang.ji-dong@xxxxxxxxxxxxxx>
+ * 				   Qian Zhang <Zhang.qian@xxxxxxxxxxxxxx>
+ * 				   Ying-chao Yang <Yang.ying-chao@xxxxxxxxxxxxxx>
+ * 				   Cang-mou Cao	<Cao.cang-mou@xxxxxxxxxxxxxx>
+ * 				   Xing-jia	Wang <Wang.xing-jia@xxxxxxxxxxxxxx>
+ *
+ * $Id: packet-iscsiexpert.h 27792 2009-03-18 23:30:21Z guy $
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxxx>
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef __PACKET_ISCSIEXPERT_H__
+#define __PACKET_ISCSIEXPERT_H__
+
+#include <epan/conversation.h>
+#include <epan/iscsisession.h>
+#include "packet-scsi.h"
+
+#define ISCSIE_DEBUG(...)	(printf("%s %d: ", __FUNCTION__, __LINE__), printf("" __VA_ARGS__))
+
+#define ISCSIEXPERT_HEADER_DIGEST_AUTO	0
+#define ISCSIEXPERT_HEADER_DIGEST_NONE	(1 << 0)
+#define ISCSIEXPERT_HEADER_DIGEST_CRC32	(1 << 1)
+
+#define	ISCSIEXPERT_UNVAILD_CID		0xFFFF
+
+#define ISCSIEXPERT_AUTH_METHOD_AUTO	0
+#define ISCSIEXPERT_AUTH_METHOD_NONE	(1 << 0)
+#define ISCSIEXPERT_AUTH_METHOD_CHAP	(1 << 1)
+#define ISCSIEXPERT_AUTH_METHOD_SRP	    (1 << 2)
+#define ISCSIEXPERT_AUTH_METHOD_SPKM2   (1 << 3)
+#define ISCSIEXPERT_AUTH_METHOD_SPKM1   (1 << 4)
+#define ISCSIEXPERT_AUTH_METHOD_KRB5    (1 << 5)
+
+enum{
+	 VALUE_REJECT = -1,
+	 VALUE_NOTUNDERSTOOD = -2,
+	 VALUE_IRRLELVANT = -3,
+	 VALUE_OTHER = -4,
+     VALUE_NONE = -5,     /*like key=*/
+};
+
+/* Note: the iscsiexpert_session_t is corrspond to the iscsi connection, and
+ 		the iscsiexpert_sessionset_t is corrspond to the iscsi session in RFC3270
+ 	*/
+
+typedef enum iscsi_session_s{
+	NORMAL_TYPE,
+	DISCOVERY_TYPE
+}iscsi_session_t;
+
+typedef struct iscsi_param_num_s{
+    guint flag;
+    guint32 value;
+    guint32 req_val;
+    guint32 rsp_val;
+    guint32 from;
+}iscsi_param_num_t;
+
+typedef struct iscsi_param_bool_s{
+    guint flag;
+    gboolean value;
+    gboolean req_val;
+    gboolean rsp_val;
+    guint32 from;
+}iscsi_param_bool_t;
+
+enum{
+    NEGOTIATION_VALUE_FROM_DEF=0,
+    NEGOTIATION_VALUE_FROM_NEGO,
+    NEGOTIATION_VALUE_FROM_INI,
+    NEGOTIATION_VALUE_FROM_TAR,
+};
+typedef struct iscsi_session_params_s
+{
+	/* all session wide parameters except:
+	 *   error - SendTargets, TargetAddress, TargetPortalGroupTag
+	 *   ignore - TargetAlias, InitiatorAlias
+	 * */
+	iscsi_param_num_t				max_connections;
+	iscsi_param_bool_t			initial_r2t;
+	iscsi_param_bool_t			imm_data;
+	iscsi_param_num_t				max_burst_len;
+	iscsi_param_num_t				first_burst_len;
+	iscsi_param_num_t				dflt_time2wait;
+	iscsi_param_num_t				dflt_time2retain;
+	iscsi_param_num_t				max_outstand_r2t;
+	iscsi_param_bool_t			data_pdu_inorder;
+	iscsi_param_bool_t			data_seq_inorder;
+	iscsi_param_num_t				error_recovery_lvl;
+	iscsi_session_t 	session_type;
+	gint32				target_portal_group_tag;
+	gchar 	* 			initiator_name;
+	gchar	*			target_name;
+	gchar	*			target_addr;
+	gchar	*			initiator_alias;
+	gchar	*			target_alias;
+
+
+} iscsi_session_params_t;
+
+typedef struct iscsi_connection_params_s
+{
+	iscsi_param_num_t		header_digest;
+	iscsi_param_num_t		data_digest;
+	iscsi_param_num_t		max_recv_data_segment_length;
+    iscsi_param_num_t		max_xmit_data_segment_length;
+    iscsi_param_num_t     authmethod;
+    iscsi_param_bool_t            ofmarker;
+    iscsi_param_bool_t            ifmarker;
+    iscsi_param_num_t             ofmarkint;
+    iscsi_param_num_t             ifmarkint;    
+} iscsi_connection_params_t;
+
+/*iscsi key-value pair for negotiation process*/
+typedef struct iscsi_key_s{
+    gchar *name;  /*key name*/
+    guint flag;
+    gint def;     /*the key's default value in RFC3720*/
+    gint min;      /*the key's min value in RFC3720*/
+    gint max;      /*the key's max value in RFC3720*/
+
+    gint req_val;  /*the key's value in login request sent by initiator*/
+    gint rsp_val;  /*the key's value in login response sent by target*/
+    guint nego_status; /*the key's negotiation status*/
+    gboolean ini2tar; /*the key's negotiation direct, Ture: initiator negotiate first; False: else*/
+    guint ops_type;   /*result function for the key*/
+    gchar *req_ptr;      /*point to the invalid value, generally it is NULL*/
+    gchar *rsp_ptr;
+}iscsi_key_t;
+
+#define ISCSIE_MAGIC_FLAG		0x12345678
+
+/* this structure contains session wide state for a specific tcp conversation */
+typedef struct _iscsiexpert_session_t {
+	guint32		magic_flag;
+	gboolean	in_session;
+	address	target_addr;
+	address	initiaor_addr;
+	guint32	target_port;
+	guint32	initiator_port;
+	nstime_t 	scsi_start_time;
+	guint64		scsi_cmd_count;
+	guint64		total_scsi_data_length;
+	gboolean	display;
+	guint16	cid;
+	emem_tree_t *itlq;	/* indexed by ITT */
+	emem_tree_t *itl;		/* indexed by LUN */
+	guint32		statsn;
+	guint32		expstatsn;
+	iscsi_isid_tx_t	isid;
+	guint16 tsih;
+	guint32	sess_index;			/* unique index for session */
+	guint32	conn_index;			/* unique index for connection */
+	iscsi_connection_params_t	params;
+
+    iscsi_key_t *connection_keys;
+    gchar *req_trunced_ptr;         /*used to store the trunced key-value due to C bit=1*/
+    guint32 req_c_bit;
+    gchar *rsp_trunced_ptr;
+    guint32 rsp_c_bit;
+    guint32 login_num_list[32];
+} iscsiexpert_session_t;
+
+
+typedef struct _iscsiexpert_sessionset_t {
+	guint32 conn_count;		/* iscsi conn count*/
+	guint32 cmdsn;			/* iscsi session cmd sn*/
+	//guint32 last_cmdsn;
+    guint32	init_fd;     	/* Leading PDU of this session*/
+    //gboolean prev_i_bit;    /* Whether previous pdu in this session has I bit set*/
+    gboolean cur_i_bit;     /* Whether current pdu in this session has I bit set*/
+	guint32 maxcmdsn;
+	guint32 expcmdsn;
+     guint32 pending_r2t;
+	emem_tree_t *connq;		/* iscsi conn list*/
+	iscsi_session_params_t	params;
+
+    iscsi_key_t *session_keys;
+}iscsiexpert_sessionset_t;
+
+
+typedef struct iscsiexpert_tapdata_info_s {
+	guint32 	packet_num;
+	gboolean	direction;
+	guint8		opcode;
+	int 		group;
+	int 		severity;
+	gchar 	* 	summary;
+	gchar	*	protocol;
+	guint32		sess_index;
+	iscsiexpert_session_t * conn;
+} iscsiexpert_tapdata_info_t;
+
+typedef struct iscsiexpert_expertdata_info_s {
+	guint32 	packet_num;
+	gboolean	direction;
+	guint8		opcode;
+	int 		group;
+	int 		severity;
+	gchar 	* 	summary;
+	gchar	*	protocol;
+	iscsiexpert_session_t * conn;
+	proto_item *pitem;
+} iscsiexpert_expertdata_info_t;
+
+
+/* #ifdef DRAFT08 */
+#define X_BIT 0x80
+/* #endif */
+
+#define I_BIT 0x40
+
+#define OPCODE_MASK 0x3f
+
+#define TARGET_OPCODE_BIT 0x20
+
+#define ISCSIEXPERT_OPCODE_NOP_OUT                  0x00
+#define ISCSIEXPERT_OPCODE_SCSI_COMMAND             0x01
+#define ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION 0x02
+#define ISCSIEXPERT_OPCODE_LOGIN_COMMAND            0x03
+#define ISCSIEXPERT_OPCODE_TEXT_COMMAND             0x04
+#define ISCSIEXPERT_OPCODE_SCSI_DATA_OUT            0x05
+#define ISCSIEXPERT_OPCODE_LOGOUT_COMMAND           0x06
+#define ISCSIEXPERT_OPCODE_SNACK_REQUEST            0x10
+#define ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I0       0x1c
+#define ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I1       0x1d
+#define ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I2       0x1e
+
+#define ISCSIEXPERT_OPCODE_NOP_IN                            0x20
+#define ISCSIEXPERT_OPCODE_SCSI_RESPONSE                     0x21
+#define ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION_RESPONSE 0x22
+#define ISCSIEXPERT_OPCODE_LOGIN_RESPONSE                    0x23
+#define ISCSIEXPERT_OPCODE_TEXT_RESPONSE                     0x24
+#define ISCSIEXPERT_OPCODE_SCSI_DATA_IN                      0x25
+#define ISCSIEXPERT_OPCODE_LOGOUT_RESPONSE                   0x26
+#define ISCSIEXPERT_OPCODE_R2T                               0x31
+#define ISCSIEXPERT_OPCODE_ASYNC_MESSAGE                     0x32
+#define ISCSIEXPERT_OPCODE_REJECT                            0x3f
+#define ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T0                0x3c
+#define ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T1                0x3d
+#define ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T2                0x3e
+
+#define CSG_SHIFT 2
+#define CSG_MASK  (0x03 << CSG_SHIFT)
+#define NSG_MASK  0x03
+
+#define ISCSIEXPERT_CSG_SECURITY_NEGOTIATION    (0 << CSG_SHIFT)
+#define ISCSIEXPERT_CSG_OPERATIONAL_NEGOTIATION (1 << CSG_SHIFT)
+#define ISCSIEXPERT_CSG_FULL_FEATURE_PHASE      (3 << CSG_SHIFT)
+
+#define ISCSIEXPERT_SCSI_DATA_FLAG_S 0x01
+#define ISCSIEXPERT_SCSI_DATA_FLAG_U 0x02
+#define ISCSIEXPERT_SCSI_DATA_FLAG_O 0x04
+#define ISCSIEXPERT_SCSI_DATA_FLAG_A 0x40
+#define ISCSIEXPERT_SCSI_DATA_FLAG_F 0x80
+
+#define  UINT32MASK				0xFFFFFFFF
+
+/* Some Definitions of SCSI opcode */
+#define SCSI_SBC_READLONG10		0x3E
+#define SCSI_SBC_READLONG16 	0x9E
+#define SCSI_SBC_WRITELONG10	0x4F
+#define SCSI_SBC_WRITELONG16	0x9F
+#define SCSI_SBC_ORWRITE		0x8B
+
+typedef struct _iscsipacket_conv_context_t {
+	 guint32 	lastdatasn;		//record the last value in conversion
+	 guint32	lastexpdatasn;
+	 guint32	lastexpstatsn;
+     guint32	laststatsn;
+     guint32	pending_r2t;
+     guint32	last_r2tsn;
+	 gboolean	first_login_response;	//record the first login response
+} iscsipacket_conv_context_t;
+
+/* structure and functions to keep track of
+ * COMMAND/DATA_IN/DATA_OUT/RESPONSE matching
+ */
+typedef struct _iscsiexpert_conv_data {
+     guint8	init_opcode;
+     guint32	init_fd;		/* Leading pdu in this conv_data */
+	 guint16	cid;
+	 guint32 data_in_frame;
+	 guint32 data_out_frame;
+	 itlq_nexus_t itlq;
+
+	 emem_tree_t *contextq;		/* iscsi conv context list*/
+
+	 guint32	lastdatasn;			//record the new value in conversion
+	 guint32	lastexpdatasn;
+
+	 guint32	maxdatasn;
+
+	 guint32	lastmaxcmdsn;
+	 guint32	lastexpcmdsn;
+	 guint32	lastcmdsn;
+	 gboolean	prev_i_bit;
+     guint32 	exp_bufferoffset;
+     guint32 	last_exp_bufferoffset;
+
+     guint32	r2t_desired_transfer_length;
+     guint32	r2tsn;
+     gboolean 	r2t_received;		// Flag: whether r2t has been received.
+     guint32 	data_out_total_transfer_leghth;
+
+     gboolean	new_created;		// Whether this task is new created one.
+     gboolean	task_done;			// Whether this task has been finished.
+     gboolean 	has_snack;
+
+	 gboolean	first_login_response;	//record the first login response
+} iscsiexpert_conv_data_t;
+
+
+typedef enum _iscsiexpert_fact
+{
+	FACT_INIT	= 0,
+	FACT_TRUE = 1,
+	FACT_FALSE = 2,
+	FACT_UNKNOWN = 3,
+}iscsiexpert_fact;
+
+typedef enum _iscsiexpert_facttype
+{
+	//>0 indicate true , < 0 indicate false,
+	//1 indicate "and" operation with prev condition, 2 indicate "or" opertion  with prev condition
+	FACT_TRUE_AND	= 1,
+	FACT_TRUE_OR	= 2,
+	FACT_FALSE_AND	= -1,
+	FACT_FALSE_OR	= -2,
+
+}iscsiexpert_fact;
+
+typedef struct _iscsiexpert_factbase{
+	//struct _iscsiexpert_factbase	* next;
+	guint32 			fact_id;						//fact identifier
+	iscsiexpert_fact  	(* fact_conclude) (tvbuff_t *tvb,guint offset, guint opcode, packet_info *pinfo,iscsiexpert_conv_data_t * conv_data,iscsiexpert_session_t *conn, iscsiexpert_sessionset_t * sessset);	//fact conclude function
+	gchar	* 			fact_name;				//fact name
+}iscsiexpert_factbase;
+
+
+typedef struct _iscsiexpert_resultbase{
+	guint32  			result_id;						//result identifier
+	gint				start;						//packet detail start position
+	gint				length;						//packet detail length
+	gchar	* 			result_name;				//result name
+}iscsiexpert_resultbase;
+
+
+typedef struct _iscsiexpert_rule_result{
+	guint32				result_id;
+	gint				offset;
+	guint				length;
+}iscsiexpert_rule_result;
+
+typedef struct _iscsiexpert_rule_condition{
+	gint8				type;		//>0 indicate true , < 0 indicate false,
+									//1 indicate "and" operation with prev condition, 2 indicate "or" opertion  with prev condition
+	guint32				factid;
+}iscsiexpert_rule_condition;
+
+typedef struct _iscsiexpert_knowledgebased{
+	guint32								result_id;				//result id
+	iscsiexpert_rule_condition			rule_condition_list[10];				//fact list to conclude the result
+}iscsiexpert_knowledgebased;
+
+typedef struct _iscsiexpert_filter{
+	gint8		opcode;			//opcode filter;
+}iscsiexpert_filter;
+
+typedef struct _iscsiexpert_kv_result{
+    iscsiexpert_fact key_result;
+    iscsiexpert_fact keyvalue_result;
+    iscsiexpert_fact value_result;
+} iscsiexpert_kv_result;
+
+typedef struct _cdb_info{
+     guint32 scsi_opcode;
+     guint32 offset;
+     guint32 length;
+} cdb_info;
+
+GSList *
+iscsi_knowbase_query(tvbuff_t *tvb, guint offset, guint opcode,
+                     packet_info *pinfo, iscsiexpert_conv_data_t *conv_data,
+                     iscsiexpert_session_t *conn,
+                     iscsiexpert_sessionset_t * sessset);
+
+#endif
diff -urN wireshark-1.2.2/epan/epan.c wireshark-1.2.2-iscsie/epan/epan.c
--- wireshark-1.2.2/epan/epan.c	2009-09-15 09:50:18.000000000 +0800
+++ wireshark-1.2.2-iscsie/epan/epan.c	2009-11-26 16:35:37.000000000 +0800
@@ -44,6 +44,7 @@
 #include "report_err.h"
 
 #include "conversation.h"
+#include "iscsisession.h"
 #include "circuit.h"
 #include "except.h"
 #include "packet.h"
@@ -139,6 +140,12 @@
 }
 
 void
+epan_iscsisession_init(void)
+{
+	iscsisession_init();
+}
+
+void
 epan_circuit_init(void)
 {
 	circuit_init();
diff -urN wireshark-1.2.2/epan/epan.h wireshark-1.2.2-iscsie/epan/epan.h
--- wireshark-1.2.2/epan/epan.h	2009-09-15 09:50:18.000000000 +0800
+++ wireshark-1.2.2-iscsie/epan/epan.h	2009-11-26 16:35:37.000000000 +0800
@@ -55,6 +55,14 @@
 void epan_conversation_init(void);
 
 /*
+ * Initialize the table of iscsisession.  iscsisession are identified by
+ * their endpoints; they are used for protocols such as IP, TCP, and UDP,
+ * where packets contain endpoint information but don't contain a single
+ * value indicating to which flow the packet belongs.
+ */
+void epan_iscsisession_init(void);
+
+/*
  * Initialize the table of circuits.  Circuits are identified by a
  * circuit ID; they are used for protocols where packets *do* contain
  * a circuit ID value indicating to which flow the packet belongs.
diff -urN wireshark-1.2.2/epan/iscsisession.c wireshark-1.2.2-iscsie/epan/iscsisession.c
--- wireshark-1.2.2/epan/iscsisession.c	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/epan/iscsisession.c	2010-01-20 15:17:11.000000000 +0800
@@ -0,0 +1,698 @@
+/* iscsisession.c
+ * Routines for building lists of packets that are part of a "iscsisession"
+ *  Copyright 2009, Ji-dong Wang <Wang.ji-dong@xxxxxxxxxxxxxx>
+ * 				   Qian Zhang <Zhang.qian@xxxxxxxxxxxxxx>
+ * 				   Ying-chao Yang <Yang.ying-chao@xxxxxxxxxxxxxx>
+ * 				   Cang-mou Cao	<Cao.cang-mou@xxxxxxxxxxxxxx>
+ * 				   Xing-jia	Wang <Wang.xing-jia@xxxxxxxxxxxxxx>
+ *
+ * $Id: iscsisession.c 25158 2008-04-23 21:31:50Z jake $
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * Copied from conversation.c
+ * 
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include <string.h>
+#include <glib.h>
+#include "packet.h"
+#include "emem.h"
+#include "iscsisession.h"
+
+/*
+ * Hash table for iscsisessions with no wildcards.
+ */
+//static GHashTable *iscsisession_hashtable = NULL;
+GHashTable *iscsisession_hashtable = NULL;
+
+/*
+ * Linked list of iscsisession keys, so we can, before freeing them all,
+ * free the address data allocations associated with them.
+ */
+static iscsisession_key *iscsisession_keys;
+
+static guint32 new_index;
+
+/*
+ * Protocol-specific data attached to a iscsisession_t structure - protocol
+ * index and opaque pointer.
+ */
+typedef struct _sess_proto_data {
+	int	proto;
+	void	*proto_data;
+} sess_proto_data;
+
+/*
+ * Creates a new iscsisession with known endpoints based on a iscsisession
+ * created with the iscsisession_TEMPLATE option while keeping the
+ * iscsisession created with the iscsisession_TEMPLATE option so it can still
+ * match future connections.
+ *
+ * Passing a pointer to a iscsisession whose options mask does not include
+ * iscsisession_TEMPLATE or where the iscsisession's protocol type (ptype)
+ * indicates a non-connnection oriented protocol will return the iscsisession
+ * without changes.
+ *
+ * addr2 and port2 are used in the function if their respective iscsisession
+ * options bits are set (NO_ADDR2 and NO_PORT2).
+ */
+static iscsisession_t *
+iscsisession_create_from_template(iscsisession_t *iscsisession, address *addr2, guint32 port2,iscsi_isid_tx_t *isid,guint16 tsih)
+{
+   /*
+    * Add a new iscsisession and keep the iscsisession template only if the
+    * iscsisession_TEMPLATE bit is set for a connection oriented protocol.
+    */
+   if(iscsisession->options & ISCSISESSION_TEMPLATE)
+   {
+      /*
+       * Set up a new options mask where the iscsisession template bit and the
+       * bits for absence of a second address and port pair have been removed.
+       */
+      iscsisession_t *new_iscsisession_from_template;
+      guint options = iscsisession->options & ~(ISCSISESSION_TEMPLATE | NO_ADDR2 | NO_PORT2);
+
+      /*
+       * Are both the NO_ADDR2 and NO_PORT2 wildcards set in the options mask?
+       */
+      if(iscsisession->options & NO_ADDR2 && iscsisession->options & NO_PORT2)
+      {
+         /*
+          * The iscsisession template was created without knowledge of both
+          * the second address as well as the second port. Create a new
+          * iscsisession with new 2nd address and 2nd port.
+          */
+         new_iscsisession_from_template =
+            iscsisession_new(iscsisession->setup_frame,
+                             &iscsisession->key.addr1, addr2,
+                             iscsisession->key.port1,port2, options,isid,tsih);
+      }
+      else if(iscsisession->options & NO_PORT2)
+      {
+         /*
+          * The iscsisession template was created without knowledge of port 2
+          * only. Create a new iscsisession with new 2nd port.
+          */
+         new_iscsisession_from_template =
+            iscsisession_new(iscsisession->setup_frame,
+                             &iscsisession->key.addr1, &iscsisession->key.addr2,
+                             iscsisession->key.port1,port2, options,isid,tsih);
+      }
+      else if(iscsisession->options & NO_ADDR2)
+      {
+         /*
+          * The iscsisession template was created without knowledge of address
+          * 2. Create a new iscsisession with new 2nd address.
+          */
+         new_iscsisession_from_template =
+            iscsisession_new(iscsisession->setup_frame,
+                             &iscsisession->key.addr1, addr2,
+                             iscsisession->key.port1,iscsisession->key.port2,
+							 options,isid,tsih);
+      }
+      else
+      {
+         /*
+          * The iscsisession_TEMPLATE bit was set, but no other bit that the
+          * iscsisession_TEMPLATE bit controls is active. Just return the old
+          * iscsisession.
+          */
+         return iscsisession;
+      }
+
+      return new_iscsisession_from_template;
+   }
+   else
+   {
+      return iscsisession;
+   }
+}
+
+
+#define ADD_ISID_TO_HASH(hash_val, isid) { \
+	hash_val += (isid)->fmt_type; \
+	hash_val += (isid)->A; \
+	hash_val += (isid)->B0; \
+	hash_val += (isid)->B1; \
+	hash_val += (isid)->C; \
+	hash_val += (isid)->D0; \
+	hash_val += (isid)->D1; \
+	}
+
+/*
+ * Compute the hash value for two given address/port pairs if the match
+ * is to be exact.
+ */
+static guint
+iscsisession_hash_exact(gconstpointer v)
+{
+	const iscsisession_key *key = (const iscsisession_key *)v;
+	guint hash_val;
+
+	hash_val = 0;
+	ADD_ADDRESS_TO_HASH(hash_val, &key->addr1);
+	hash_val += key->port1;
+	ADD_ADDRESS_TO_HASH(hash_val, &key->addr2);
+	hash_val += key->port2;
+	ADD_ISID_TO_HASH(hash_val,&key->isid);
+	hash_val += key->tsih;
+	
+
+	return hash_val;
+}
+
+
+gboolean
+is_isid_equal(const iscsi_isid_tx_t *isida,const iscsi_isid_tx_t *isidb)
+{
+	if ((isida->fmt_type == isidb->fmt_type)
+		&& (isida->A  ==  isidb->A)
+		&& (isida->B0 ==  isidb->B0)
+		&& (isida->B1 ==  isidb->B1)
+		&& (isida->C  ==  isidb->C)
+		&& (isida->D0 ==  isidb->D0)
+		&& (isida->D1 ==  isidb->D1)) {
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/*
+ * Compare two iscsisession keys for an exact match.
+ */
+static gint
+iscsisession_match_exact(gconstpointer v, gconstpointer w)
+{
+	const iscsisession_key *v1 = (const iscsisession_key *)v;
+	const iscsisession_key *v2 = (const iscsisession_key *)w;
+
+	/*
+	 * Are the first and second port 1 values the same, the first and
+	 * second port 2 values the same, the first and second address
+	 * 1 values the same, and the first and second address 2 values
+	 * the same?
+	 */
+	if (v1->port1 == v2->port1 &&
+	    v1->port2 == v2->port2 &&
+	    ADDRESSES_EQUAL(&v1->addr1, &v2->addr1) &&
+	    ADDRESSES_EQUAL(&v1->addr2, &v2->addr2) &&
+		v1->tsih == v2->tsih &&
+		(TRUE == is_isid_equal(&(v1->isid),&(v2->isid)))
+		) {
+		/*
+		 * Yes.  It's the same iscsisession, and the two
+		 * address/port pairs are going in the same direction.
+		 */
+		return 1;
+	}
+
+	/*
+	 * Is the first port 2 the same as the second port 1, the first
+	 * port 1 the same as the second port 2, the first address 2
+	 * the same as the second address 1, and the first address 1
+	 * the same as the second address 2?
+	 */
+	if (v1->port2 == v2->port1 &&
+	    v1->port1 == v2->port2 &&
+	    ADDRESSES_EQUAL(&v1->addr2, &v2->addr1) &&
+	    ADDRESSES_EQUAL(&v1->addr1, &v2->addr2) &&
+		v1->tsih == v2->tsih &&
+		(TRUE == is_isid_equal(&(v1->isid),&(v2->isid)))
+		) {
+		/*
+		 * Yes.  It's the same iscsisession, and the two
+		 * address/port pairs are going in opposite directions.
+		 */
+		return 1;
+	}
+
+	/*
+	 * The addresses or the ports don't match.
+	 */
+	return 0;
+}
+
+/*
+ * Initialize some variables every time a file is loaded or re-loaded.
+ * Destroy all existing iscsisessions, and create a new hash table
+ * for the iscsisessions in the new file.
+ */
+void
+iscsisession_init(void)
+{
+	/* The iscsisession keys are se_ allocated so they are already gone */
+	iscsisession_keys = NULL;
+	if (iscsisession_hashtable != NULL)
+		g_hash_table_destroy(iscsisession_hashtable);
+
+	/*
+	 * Free up any space allocated for iscsisession protocol data
+	 * areas.
+	 *
+	 * We can free the space, as the structures it contains are
+	 * pointed to by iscsisession data structures that were freed
+	 * above.
+	 */
+
+	iscsisession_hashtable = g_hash_table_new(iscsisession_hash_exact,
+								iscsisession_match_exact);
+	
+	/*
+	 * Start the iscsisession indices over at 0.
+	 */
+	new_index = 0;
+}
+
+gboolean
+is_isid_vaild(iscsi_isid_tx_t *isida)
+{
+	if ((isida->fmt_type == 0)
+		&& (isida->A == 0)
+		&& (isida->B0 == 0)
+		&& (isida->B1 == 0)
+		&& (isida->C  == 0)
+		&& (isida->D0 == 0)
+		&& (isida->D1 == 0)) {
+		return FALSE;
+	}
+	
+	return TRUE;
+}
+
+gboolean
+is_vaild_ssid(iscsi_isid_tx_t *isid,guint16 tsih)
+{
+	if ((tsih != 0) && is_isid_vaild(isid))
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+
+/*
+ * Given two address/port pairs for a packet, create a new iscsisession
+ * to contain packets between those address/port pairs.
+ *
+ * The options field is used to specify whether the address 2 value
+ * and/or port 2 value are not given and any value is acceptable
+ * when searching for this iscsisession.
+ */
+iscsisession_t *
+iscsisession_new(guint32 setup_frame, address *addr1, address *addr2,
+    guint32 port1, guint32 port2, guint options,iscsi_isid_tx_t *isid,guint16 tsih)
+{
+/*
+	DISSECTOR_ASSERT(!(options | iscsisession_TEMPLATE) || ((options | (NO_ADDR2 | NO_PORT2 | NO_PORT2_FORCE))) &&
+				"A iscsisession template may not be constructed without wildcard options");
+*/
+	GHashTable* hashtable;
+	iscsisession_t *iscsisession;
+	iscsisession_t *tc;
+	iscsisession_key existing_key;
+	iscsisession_key *new_key;
+
+	hashtable = iscsisession_hashtable;
+
+	memset(&existing_key,0,sizeof(iscsisession_key));
+
+	if (is_vaild_ssid(isid,tsih) == FALSE)
+	{
+		SE_COPY_ADDRESS(&existing_key.addr1,addr1);
+		SE_COPY_ADDRESS(&existing_key.addr2,addr2);
+		existing_key.port1 = port1;
+		existing_key.port2 = port2;
+	}
+	else
+	{
+		existing_key.tsih = tsih;
+		memcpy(&existing_key.isid,isid,sizeof(iscsi_isid_tx_t));
+	}
+	
+	iscsisession = g_hash_table_lookup(hashtable, &existing_key);
+	tc = iscsisession; /* Remember if lookup was successful */
+
+	new_key = se_alloc(sizeof(struct iscsisession_key));
+	memset(new_key,0,sizeof(iscsisession_key));
+
+	new_key->next = iscsisession_keys;
+	iscsisession_keys = new_key;
+	
+	if (is_vaild_ssid(isid,tsih) == FALSE)
+	{
+		SE_COPY_ADDRESS(&new_key->addr1,addr1);
+		SE_COPY_ADDRESS(&new_key->addr2,addr2);
+		new_key->port1 = port1;
+		new_key->port2 = port2;
+	}
+	else
+	{
+		new_key->tsih = tsih;
+		memcpy(&new_key->isid,isid,sizeof(iscsi_isid_tx_t));
+	}
+
+	if (iscsisession) {
+		for (; iscsisession->next; iscsisession = iscsisession->next)
+			;
+		iscsisession->next = se_alloc(sizeof(iscsisession_t));
+		iscsisession = iscsisession->next;
+	} else {
+		iscsisession = se_alloc(sizeof(iscsisession_t));
+		memset(iscsisession,0,sizeof(iscsisession_t));
+	}
+
+	iscsisession->next 			= NULL;
+	iscsisession->index 		= new_index;
+	iscsisession->setup_frame 	= setup_frame;
+	iscsisession->data_list 	= NULL;
+
+	/* set the options and key pointer */
+	iscsisession->options 		= options;
+
+	SE_COPY_ADDRESS(&iscsisession->key.addr1,addr1);
+	SE_COPY_ADDRESS(&iscsisession->key.addr2,addr2);
+	iscsisession->key.port1 = port1;
+	iscsisession->key.port2 = port2;
+
+	if (is_vaild_ssid(isid,tsih) == TRUE)
+	{
+		iscsisession->key.tsih = tsih;
+		memcpy(&iscsisession->key.isid,isid,sizeof(iscsi_isid_tx_t));
+	}
+
+	iscsisession->key_ptr 		= new_key;
+
+	new_index++;
+	
+	/* only insert a hash table entry if this
+	 * is the first iscsisession with this key */
+	if (!tc){
+		g_hash_table_insert(hashtable, new_key, iscsisession);
+	}
+
+	return iscsisession;
+}
+
+static gboolean
+isid_compare(iscsi_isid_tx_t *isida, iscsi_isid_tx_t *isidb)
+{
+	if ((isida->fmt_type == isidb->fmt_type)
+		&& (isida->A == isidb->A)
+		&& (isida->B0 == isidb->B0)
+		&& (isida->B1 == isidb->B1)
+		&& (isida->C  == isidb->C)
+		&& (isida->D0 == isidb->D0)
+		&& (isida->D1 == isidb->D1)) {
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
+gboolean is_new_connection(iscsisession_t *sess,guint32 frame_num,iscsi_isid_tx_t *isid,guint16 tsih){
+
+	if (is_vaild_ssid(isid,tsih) == TRUE)
+	{
+		if ((FALSE == isid_compare(&sess->key.isid,isid))
+				&& (sess->key.tsih != tsih)){
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+void set_iscsisession_ssid(iscsisession_t *sess,guint32 frame_num,iscsi_isid_tx_t *isid,guint16 tsih){
+	GHashTable* hashtable;
+	iscsisession_key * new_key;
+
+	hashtable = iscsisession_hashtable;
+	/*
+	 * We don't make a copy of the address data, we just copy the
+	 * pointer to it, as "key" disappears when we return.
+	 */
+
+	g_hash_table_remove(hashtable,sess->key_ptr);
+
+	new_key = se_alloc(sizeof(struct iscsisession_key));
+	memset(new_key,0,sizeof(struct iscsisession_key));
+
+	new_key->next = iscsisession_keys;
+	iscsisession_keys = new_key;
+
+	new_key->tsih = tsih;
+	memcpy(&new_key->isid,isid,sizeof(iscsi_isid_tx_t));
+	sess->key_ptr 		= new_key;
+
+	sess->key.tsih=tsih;
+	memcpy(&sess->key.isid,isid,sizeof(iscsi_isid_tx_t));
+
+	g_hash_table_insert(hashtable,new_key, sess);
+}
+
+/*
+ * Search a particular hash table for a iscsisession with the specified
+ * {addr1, port1, addr2, port2} and set up before frame_num.
+ */
+static iscsisession_t *
+iscsisession_lookup_hashtable(GHashTable *hashtable, guint32 frame_num, address *addr1, address *addr2,
+							  guint32 port1, guint32 port2)
+{
+	iscsisession_t* iscsisession;
+	iscsisession_t* match;
+	iscsisession_key key;
+
+	/*
+	 * We don't make a copy of the address data, we just copy the
+	 * pointer to it, as "key" disappears when we return.
+	 */
+	memset(&key,0,sizeof(iscsisession_key));
+	key.addr1 = *addr1;
+	key.addr2 = *addr2;
+	key.port1 = port1;
+	key.port2 = port2;
+
+	match = g_hash_table_lookup(hashtable, &key);
+
+	if (match) {
+		for (iscsisession = match->next; iscsisession; iscsisession = iscsisession->next) {
+			if ((iscsisession->setup_frame <= frame_num)
+				&& (iscsisession->setup_frame > match->setup_frame))
+				match = iscsisession;
+		}
+		if (match->setup_frame > frame_num)
+			match = NULL;
+	}
+
+	return match;
+}
+
+/*
+ * Search a particular hash table for a iscsisession with the specified
+ * {isid, tsih} and set up before frame_num.
+ */
+static iscsisession_t *
+iscsisession_lookup_hashtable_with_ssid(GHashTable *hashtable,  guint32 frame_num,iscsi_isid_tx_t * isid,guint16 tsih)
+{
+	iscsisession_t* iscsisession;
+	iscsisession_t* match = NULL;
+	iscsisession_key key;
+
+	if (is_vaild_ssid(isid,tsih) == FALSE){
+
+		return NULL;
+	}
+
+	/*
+	 * We don't make a copy of the address data, we just copy the
+	 * pointer to it, as "key" disappears when we return.
+	 */
+	memset(&key,0,sizeof(iscsisession_key));
+	key.tsih = tsih;
+	memcpy(&key.isid,isid,sizeof(iscsi_isid_tx_t));
+
+	match = g_hash_table_lookup(hashtable, &key);
+
+	if (match) {
+		for (iscsisession = match->next; iscsisession; iscsisession = iscsisession->next) {
+			if ((iscsisession->setup_frame <= frame_num)
+				&& (iscsisession->setup_frame > match->setup_frame))
+				match = iscsisession;
+		}
+		if (match->setup_frame > frame_num)
+			match = NULL;
+	}
+
+	return match;
+}
+
+
+/*
+ * Given two address/port pairs for a packet, search for a iscsisession
+ * containing packets between those address/port pairs.  Returns NULL if
+ * not found.
+ *
+ * We try to find the most exact match that we can, and then proceed to
+ * try wildcard matches on the "addr_b" and/or "port_b" argument if a more
+ * exact match failed.
+ *
+ * Either or both of the "addr_b" and "port_b" arguments may be specified as
+ * a wildcard by setting the NO_ADDR_B or NO_PORT_B flags in the "options"
+ * argument.  We do only wildcard matches on addresses and ports specified
+ * as wildcards.
+ *
+ * I.e.:
+ *
+ *	if neither "addr_b" nor "port_b" were specified as wildcards, we
+ *	do an exact match (addr_a/port_a and addr_b/port_b) and, if that
+ *	succeeds, we return a pointer to the matched iscsisession;
+ *
+ *	otherwise, if "port_b" wasn't specified as a wildcard, we try to
+ *	match any address 2 with the specified port 2 (addr_a/port_a and
+ *	{any}/addr_b) and, if that succeeds, we return a pointer to the
+ *	matched iscsisession;
+ *
+ *	otherwise, if "addr_b" wasn't specified as a wildcard, we try to
+ *	match any port 2 with the specified address 2 (addr_a/port_a and
+ *	addr_b/{any}) and, if that succeeds, we return a pointer to the
+ *	matched iscsisession;
+ *
+ *	otherwise, we try to match any address 2 and any port 2
+ *	(addr_a/port_a and {any}/{any}) and, if that succeeds, we return
+ *	a pointer to the matched iscsisession;
+ *
+ *	otherwise, we found no matching iscsisession, and return NULL.
+ */
+
+
+/*
+ 	how to find the iscsisession
+ 	use the addr and port to determize the unknown session
+*/
+iscsisession_t *
+find_iscsisession(guint32 frame_num, address *addr_a, address *addr_b, 
+				  guint32 port_a, guint32 port_b, guint options)
+{
+   iscsisession_t *iscsisession = NULL;
+
+   /*
+    * First try an exact match, if we have two addresses and ports.
+    */
+   //if (!(options & (NO_ADDR_B|NO_PORT_B))) {
+      /*
+       * Neither search address B nor search port B are wildcarded,
+       * start out with an exact match.
+       * Exact matches check both directions.
+       */
+      iscsisession = iscsisession_lookup_hashtable(iscsisession_hashtable,
+									frame_num, addr_a, addr_b,	port_a, port_b);
+  // }
+
+   return iscsisession;
+}
+
+/*
+ 	how to find the iscsisession
+ 	1. use the isid and tsih to determize the only one session
+*/
+iscsisession_t *
+find_iscsisession_with_ssid(guint32 frame_num,iscsi_isid_tx_t * isid,guint16 tsih)
+{
+   iscsisession_t *iscsisession = NULL;
+
+   iscsisession = iscsisession_lookup_hashtable_with_ssid(iscsisession_hashtable,
+									frame_num,isid, tsih);
+
+   return iscsisession;
+}
+
+
+static gint
+p_compare(gconstpointer a, gconstpointer b)
+{
+	const sess_proto_data *ap = (const sess_proto_data *)a;
+	const sess_proto_data *bp = (const sess_proto_data *)b;
+
+	if (ap->proto > bp->proto)
+		return 1;
+	else if (ap->proto == bp->proto)
+		return 0;
+	else
+		return -1;
+}
+
+void
+iscsisession_add_proto_data(iscsisession_t *sess, int proto, void *proto_data)
+{
+	sess_proto_data *p1 = se_alloc(sizeof(sess_proto_data));
+
+	p1->proto = proto;
+	p1->proto_data = proto_data;
+
+	/* Add it to the list of items for this iscsisession. */
+	sess->data_list = g_slist_insert_sorted(sess->data_list, (gpointer *)p1,
+											p_compare);
+}
+
+void *
+iscsisession_get_proto_data(iscsisession_t *sess, int proto)
+{
+	sess_proto_data temp, *p1;
+	GSList *item;
+
+	temp.proto = proto;
+	temp.proto_data = NULL;
+
+	item = g_slist_find_custom(sess->data_list, (gpointer *)&temp,
+							   p_compare);
+
+	if (item != NULL) {
+		p1 = (sess_proto_data *)item->data;
+		return p1->proto_data;
+	}
+
+	return NULL;
+}
+
+void
+iscsisession_delete_proto_data(iscsisession_t *sess, int proto)
+{
+	sess_proto_data temp;
+	GSList *item;
+
+	temp.proto = proto;
+	temp.proto_data = NULL;
+
+	item = g_slist_find_custom(sess->data_list, (gpointer *)&temp,
+	    p_compare);
+
+	while(item){
+		sess->data_list = g_slist_remove(sess->data_list, item->data);
+		item=item->next;
+	}
+}
+
+void iscsisession_foreach( GHFunc func, gpointer user_data){
+	g_hash_table_foreach(iscsisession_hashtable,func,user_data);
+}
+
diff -urN wireshark-1.2.2/epan/iscsisession.h wireshark-1.2.2-iscsie/epan/iscsisession.h
--- wireshark-1.2.2/epan/iscsisession.h	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/epan/iscsisession.h	2010-01-20 15:17:11.000000000 +0800
@@ -0,0 +1,133 @@
+/* iscsisession.h
+ * Routines for building lists of packets that are part of a "conversation"
+ * Copyright 2009, Ji-dong Wang <Wang.ji-dong@xxxxxxxxxxxxxx>
+ * 				   Qian Zhang <Zhang.qian@xxxxxxxxxxxxxx>
+ * 				   Ying-chao Yang <Yang.ying-chao@xxxxxxxxxxxxxx>
+ * 				   Cang-mou Cao	<Cao.cang-mou@xxxxxxxxxxxxxx>
+ * 				   Xing-jia	Wang <Wang.xing-jia@xxxxxxxxxxxxxx>
+ *
+ * $Id: iscsisession.h 24644 2008-03-15 23:01:12Z guy $
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxxx>
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef __ISCSISESSION_H__
+#define __ISCSISESSION_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * Flags to pass to "conversation_new()" to indicate that the address 2
+ * and/or port 2 values for the conversation should be wildcards.
+ * The CONVERSATION_TEMPLATE option tells that any of the other supplied
+ * port and / or address wildcards will be used to match an infinite number
+ * of new connections to the conversation(s) that have the CONVERSATION_-
+ * TEMPLATE flag set. Any conversation created without the CONVERSATION_-
+ * TEMPLATE flag will be altered once the first connections (connection
+ * oriented protocols only) to include the newly found information which
+ * matched the wildcard options.
+ */
+#define NO_ADDR2 0x01
+#define NO_PORT2 0x02
+#define NO_PORT2_FORCE 0x04
+#define ISCSISESSION_TEMPLATE 0x08
+
+/*
+ * Flags to pass to "find_conversation()" to indicate that the address B
+ * and/or port B search arguments are wildcards.
+ */
+#define NO_ADDR_B 0x01
+#define NO_PORT_B 0x02
+
+#include "packet.h"		/* for iscsisession dissector type */
+
+typedef struct iscsi_isid_tx_s {
+	guint8 A:6,            // 0 :
+		  fmt_type:2;       // Naming authority qualifier format
+	guint8 B1;             // 1 :
+	guint8 B0;             // 2 :
+	guint8 C;              // 3:
+	guint8 D1;             // 4:
+	guint8 D0;             // 5:
+} iscsi_isid_tx_t;
+
+/*
+ * Data structure representing a conversation.
+ */
+
+typedef struct iscsisession_key {
+	struct iscsisession_key *next;
+	address	addr1;
+	address	addr2;
+	guint32	port1;
+	guint32	port2;
+	iscsi_isid_tx_t	isid;
+	guint16 tsih;
+} iscsisession_key;
+
+typedef struct iscsisession {
+	struct iscsisession *next;	/* pointer to next conversation on hash chain */
+	guint32	index;			/* unique ID for conversation */
+	guint32 setup_frame;	/* frame number that setup this conversation */
+	GSList *data_list;		/* list of data associated with conversation */
+	guint	options;		/* wildcard flags */
+	iscsisession_key key;	/* pointer to the key for this conversation */
+	iscsisession_key *key_ptr;	/* pointer to the key for this conversation */
+} iscsisession_t;
+
+extern void iscsisession_init(void);
+
+extern gboolean is_isid_vaild(iscsi_isid_tx_t *isid);
+extern gboolean is_vaild_ssid(iscsi_isid_tx_t *isid,guint16 tsih);
+
+extern iscsisession_t *iscsisession_new(guint32 setup_frame, address *addr1, address *addr2,
+							guint32 port1, guint32 port2, guint options,iscsi_isid_tx_t *isid,guint16 tsih);
+
+extern gboolean is_new_connection(iscsisession_t *sess,guint32 frame_num,iscsi_isid_tx_t *isid,guint16 tsih);
+extern void set_iscsisession_ssid(iscsisession_t *sess,guint32 frame_num,iscsi_isid_tx_t *isid,guint16 tsih);
+
+extern iscsisession_t *
+find_iscsisession(guint32 frame_num, address *addr_a, address *addr_b, 
+				  guint32 port_a, guint32 port_b, guint options);
+
+extern iscsisession_t *
+find_iscsisession_with_ssid(guint32 frame_num,iscsi_isid_tx_t *isid,guint16 tsih);
+
+extern void iscsisession_add_proto_data(iscsisession_t *sess, int proto,void *proto_data);
+extern void *iscsisession_get_proto_data(iscsisession_t *sess, int proto);
+extern void iscsisession_delete_proto_data(iscsisession_t *sess, int proto);
+
+extern void iscsisession_foreach( GHFunc func, gpointer user_data);
+
+typedef struct iscsiexpert_sess_tv_s{
+	int proto_iscsiexpert;
+    const char *current_proto;
+	GHashTable *session_hashlist;
+	GHashTable *conversation_hashlist;
+	
+}iscsiexpert_sess_tv_t;
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* iscsisession.h */
diff -urN wireshark-1.2.2/epan/packet.c wireshark-1.2.2-iscsie/epan/packet.c
--- wireshark-1.2.2/epan/packet.c	2009-09-15 09:50:17.000000000 +0800
+++ wireshark-1.2.2-iscsie/epan/packet.c	2009-11-26 16:35:37.000000000 +0800
@@ -133,6 +133,9 @@
 	/* Initialize the table of conversations. */
 	epan_conversation_init();
 
+	/* Initialize the table of iscsi sessions*/
+	epan_iscsisession_init();
+
 	/* Initialize the table of circuits. */
 	epan_circuit_init();
 
diff -urN wireshark-1.2.2/gtk/Makefile.common wireshark-1.2.2-iscsie/gtk/Makefile.common
--- wireshark-1.2.2/gtk/Makefile.common	2009-09-15 09:47:05.000000000 +0800
+++ wireshark-1.2.2-iscsie/gtk/Makefile.common	2009-11-26 16:35:37.000000000 +0800
@@ -154,6 +154,8 @@
 	diameter_stat.c	\
 	expert_comp_dlg.c     \
 	expert_dlg.c	\
+	iscsiexpert_dlg.c	\
+	iscsiexpert_stat.c	\
 	fc_stat.c	\
 	flow_graph.c	\
 	funnel_stat.c	\
diff -urN wireshark-1.2.2/gtk/iscsiexpert_dlg.c wireshark-1.2.2-iscsie/gtk/iscsiexpert_dlg.c
--- wireshark-1.2.2/gtk/iscsiexpert_dlg.c	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/gtk/iscsiexpert_dlg.c	2010-01-20 15:17:11.000000000 +0800
@@ -0,0 +1,2549 @@
+/* iscsiexpert_dlg.c
+ * Display of iSCSI Expert information.
+ * Implemented as a tap listener to the "expert" tap.
+ * 
+ * Copyright 2009, Ji-dong Wang <Wang.ji-dong@xxxxxxxxxxxxxx>
+ * 				   Qian Zhang <Zhang.qian@xxxxxxxxxxxxxx>
+ * 				   Ying-chao Yang <Yang.ying-chao@xxxxxxxxxxxxxx>
+ * 				   Cang-mou Cao	<Cao.cang-mou@xxxxxxxxxxxxxx>
+ * 				   Xing-jia	Wang <Wang.xing-jia@xxxxxxxxxxxxxx>
+ *
+ *
+ * $Id: expert_dlg.c 28709 2009-06-11 18:38:15Z gerald $
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ * 
+ * Copied from expert_dlg.c
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#include <gtk/gtk.h>
+#include <glib/gprintf.h>
+
+#include <epan/packet.h>
+#include <epan/expert.h>
+#include <epan/emem.h>
+#include <epan/tap.h>
+#include "epan/packet_info.h"
+#include <epan/stat_cmd_args.h>
+#include <epan/prefs.h>
+#include <epan/epan_dissect.h>
+#include <epan/addr_resolv.h>
+
+#include "../simple_dialog.h"
+#include "../globals.h"
+#include "../color.h"
+#include "../stat_menu.h"
+#include "../ui_util.h"
+#include "image/clist_ascend.xpm"
+#include "image/clist_descend.xpm"
+
+#include "gtk/find_dlg.h"
+#include "gtk/color_dlg.h"
+#include "gtk/main.h"
+#include "gtk/gui_utils.h"
+#include "gtk/gtkglobals.h"
+#include "gtk/dlg_utils.h"
+#include "gtk/gui_stat_menu.h"
+#include "gtk/tap_dfilter_dlg.h"
+#include "gtk/color_utils.h"
+#include "gtk/main_proto_draw.h"
+#include "gtk/help_dlg.h"
+
+#include "../epan/dissectors/packet-iscsiexpert.h"
+#include "../epan/iscsisession.h"
+#include "../image/iscsi_network.xpm"
+#include "../image/iscsi_connection.xpm"
+#include "../image/iscsi_session.xpm"
+#include "../image/iscsi_only_connection.xpm"
+#include "epan/iscsisession.h"
+
+#define PI_ALL		0x00000200
+#define PI_TCP		0x00000400
+#define PI_ISCSI	0x00000600
+
+static const value_string iscsiexpert_severity_om_vals[] = {
+	{ PI_ERROR,		"Errors only" },
+	{ PI_WARN,		"Error+Warn" },
+	{ PI_NOTE,		"Error+Warn+Note" },
+	{ PI_CHAT,		"Error+Warn+Note+Chat" },
+	{ 0, NULL }
+};
+
+//static const value_string iscsiexpert_protocol_om_vals[]={
+//	{ PI_ISCSI,	"iSCSI only" },
+//	{ PI_TCP,	"iSCSI+TCP"	 },
+//	{ PI_ALL,	"iSCSI+TCP+Other"	 },
+//	{ 0, NULL }
+//};
+
+enum{
+	COL_ICON=0,
+	COLUMN,
+	NUM_COLS
+};
+
+enum{
+	KEY_COLUMN = 0,
+	VALUE_COLUMN,
+	ATTRIBUTE_COLUMN,
+	PARAMETER_NUM_COLS
+};
+
+enum{
+	SESSION = 0,
+	CONNECTION,
+	SIG_CONNECTION,
+	OTHER,
+};
+
+typedef struct iscsiexpert_tapdata_s {
+	GtkWidget	*win;
+	GtkWidget	*scrolled_window;
+	
+	GtkWidget	*tree_scrolled_window;
+	GtkWidget	*treeview_window;
+	GtkWidget   * iscsi_parameter_window;
+	GtkTreeStore      *store;
+	GtkTreeSelection  *selection;
+	GtkCellRenderer   *renderer;
+	GtkTreeViewColumn *column;
+
+	GtkCList	*table;
+	GtkWidget	*label;
+	GList		*all_events;
+	GList		*new_events;
+	guint32		disp_events;
+	guint32		chat_events;
+	guint32		note_events;
+	guint32		warn_events;
+	guint32		error_events;
+	gboolean	first_row;
+	int			severity_report_level;
+	//int			protocol_report_level;
+	
+	GSList *iscsiexpert_session_list;
+} iscsiexpert_tapdata_t;
+
+iscsiexpert_sess_tv_t iscsiexpert_session_tv_info;
+gint proto_iscsie;
+#define SESSION_NAME_LEN 128
+#define VAL_BUFF_LEN  64
+
+
+typedef struct iscsiexpert_sess_display_s{
+	gchar tagtxt[SESSION_NAME_LEN];
+	gint node_type;
+	GSList *con_list;
+	iscsi_session_params_t session_params;
+	iscsiexpert_session_t *dissector_conn; // connect to the right paned
+}iscsiexpert_sess_display_t;
+
+typedef struct iscsiexpert_conn_display_s{
+	gchar tagtxt[SESSION_NAME_LEN];
+	gint node_type;
+	iscsi_connection_params_t connection_params;
+	iscsiexpert_sess_display_t *isd;
+	iscsiexpert_session_t *dissector_conn;
+}iscsiexpert_conn_display_t;
+
+typedef struct _sess_proto_data {
+	int	proto;
+	void	*proto_data;
+} sess_proto_data;
+typedef void (*GTreeCallFunc)(GtkTreeSelection *selection, gpointer data);
+
+void
+iscsi_cf_select_packet(capture_file *cf, int row)
+{
+  frame_data *fdata;
+  int err;
+  gchar *err_info;
+
+  /* Get the frame data struct pointer for this frame */
+  fdata = (frame_data *)packet_list_get_row_data(row);
+
+  if (fdata == NULL) {
+    /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
+       the first entry is added to it by "real_insert_row()", that row
+       is selected (see "real_insert_row()", in "gtk/gtkclist.c", in both
+       our version and the vanilla GTK+ version).
+
+       This means that a "select-row" signal is emitted; this causes
+       "packet_list_select_cb()" to be called, which causes "cf_select_packet()"
+       to be called.
+
+       "cf_select_packet()" fetches, above, the data associated with the
+       row that was selected; however, as "gtk_clist_append()", which
+       called "real_insert_row()", hasn't yet returned, we haven't yet
+       associated any data with that row, so we get back a null pointer.
+
+       We can't assume that there's only one frame in the frame list,
+       either, as we may be filtering the display.
+
+       We therefore assume that, if "row" is 0, i.e. the first row
+       is being selected, and "cf->first_displayed" equals
+       "cf->last_displayed", i.e. there's only one frame being
+       displayed, that frame is the frame we want.
+
+       This means we have to set "cf->first_displayed" and
+       "cf->last_displayed" before adding the row to the
+       GtkCList; see the comment in "add_packet_to_packet_list()". */
+
+       if (row == 0 && cf->first_displayed == cf->last_displayed)
+         fdata = cf->first_displayed;
+  }
+
+  /* If fdata _still_ isn't set simply give up. */
+  if (fdata == NULL) {
+    return;
+  }
+
+  /* Get the data in that frame. */
+  if (!wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
+  		       cf->pd, fdata->cap_len, &err, &err_info)) {
+    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+		  cf_read_error_message(err, err_info), cf->filename);
+    return;
+  }
+
+  /* Record that this frame is the current frame. */
+  cf->current_frame = fdata;
+  cf->current_row = row;
+
+  ///* Create the logical protocol tree. */
+  //if (cf->edt != NULL) {
+  //  epan_dissect_free(cf->edt);
+  //  cf->edt = NULL;
+  //}
+  ///* We don't need the columns here. */
+  //cf->edt = epan_dissect_new(TRUE, TRUE);
+
+  //epan_dissect_run(cf->edt, &cf->pseudo_header, cf->pd, cf->current_frame,
+  //        NULL);
+
+  //dfilter_macro_build_ftv_cache(cf->edt->tree);
+
+  //cf_callback_invoke(cf_cb_packet_selected, cf);
+}
+
+
+gboolean
+iscsi_cf_goto_frame(capture_file *cf, guint fnumber)
+{
+  frame_data *fdata;
+  int row;
+
+  for (fdata = cf->plist; fdata != NULL && fdata->num < fnumber; fdata = fdata->next)
+    ;
+
+  if (fdata == NULL) {
+    /* we didn't find a packet with that packet number */
+    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+	 	  "There is no packet with the packet number %u.", fnumber);
+    return FALSE;	/* we failed to go to that packet */
+  }
+  if (!fdata->flags.passed_dfilter) {
+    /* that packet currently isn't displayed */
+    /* XXX - add it to the set of displayed packets? */
+    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+		  "The packet number %u isn't currently being displayed.", fnumber);
+    return FALSE;	/* we failed to go to that packet */
+  }
+
+  /* We found that packet, and it's currently being displayed.
+     Find what row it's in. */
+  row = packet_list_find_row_from_data(fdata);
+  g_assert(row != -1);
+
+  /* Select that row, make it the focus row, and make it visible. */
+  //packet_list_set_selected_row(row);
+
+  iscsi_cf_select_packet(&cfile, row);
+
+  return TRUE;	/* we got to that packet */
+}
+
+
+/*
+ * init a treestore model, doesn't display the detail content. 
+ * Only display the column infomation of the tree.
+*/
+static GtkTreeModel *init_iscsi_model(void)
+{
+	GtkTreeStore *treestore;
+
+	treestore = gtk_tree_store_new(NUM_COLS, GDK_TYPE_PIXBUF, G_TYPE_STRING);
+
+	return GTK_TREE_MODEL(treestore);
+}
+
+static gint
+p_compare(gconstpointer a, gconstpointer b)
+{
+	const sess_proto_data *ap = (const sess_proto_data *)a;
+	const sess_proto_data *bp = (const sess_proto_data *)b;
+
+	if (ap->proto > bp->proto)
+		return 1;
+	else if (ap->proto == bp->proto)
+		return 0;
+	else
+		return -1;
+}
+
+
+static void *
+iscsisession_get_proto_data(iscsisession_t *sess, int proto)
+{
+	sess_proto_data temp, *p1;
+	GSList *item;
+
+	temp.proto = proto;
+	temp.proto_data = NULL;
+
+	item = g_slist_find_custom(sess->data_list, (gpointer *)&temp,
+							   p_compare);
+
+	if (item != NULL) {
+		p1 = (sess_proto_data *)item->data;
+		return p1->proto_data;
+	}
+
+	return NULL;
+}
+
+
+/*
+ * Fill the model with session/connection information
+ * model: [input], the initialized tree store
+*/
+GtkTreeModel *fill_model(GtkTreeModel *model, GSList *sess_list)
+{
+	GtkTreeStore *treestore = GTK_TREE_STORE(model);
+	GtkTreeIter toplevel;
+	GdkPixbuf *icon_nettop = NULL;
+	GdkPixbuf *icon_sess_conn = NULL;
+	GdkPixbuf *icon_conn = NULL;
+	GdkPixbuf *icon_only_conn = NULL;
+	
+	GHashTable *s_hash = NULL;
+	GHashTable *c_hash = NULL;
+
+	GSList *tmp = NULL;
+	GSList *tmp2 = NULL;
+	iscsiexpert_sess_display_t *isd = NULL;
+	iscsiexpert_conn_display_t *icd = NULL;
+	GtkTreeIter child;
+	GtkTreeIter grandchild;
+	//GtkTreePath *path;
+	gint con_num = 0;
+	gint i = 0;
+
+	if (sess_list == NULL)
+		return GTK_TREE_MODEL(treestore);
+
+	icon_nettop = gdk_pixbuf_new_from_xpm_data(iscsi_network_xpm);
+	icon_sess_conn = gdk_pixbuf_new_from_xpm_data(iscsi_session_xpm);
+	icon_conn = gdk_pixbuf_new_from_xpm_data(iscsi_connection_xpm);	
+	icon_only_conn = gdk_pixbuf_new_from_xpm_data(iscsi_only_connection_xpm);
+
+	/*top level: all sessions and connections*/
+	gtk_tree_store_append(treestore, &toplevel, NULL);
+	gtk_tree_store_set(treestore, &toplevel, COL_ICON, icon_nettop, COLUMN, "Sessions/Connections", -1);
+
+	for (tmp = sess_list; tmp; tmp = g_slist_next(tmp))
+	{
+		isd = tmp->data;
+		if (isd->node_type == SESSION)
+		{
+			gtk_tree_store_append(treestore, &child, &toplevel);
+			gtk_tree_store_set(treestore, &child, COL_ICON, icon_sess_conn, COLUMN, isd->tagtxt, -1);
+
+			con_num = g_slist_length(isd->con_list);
+			for (tmp2 = isd->con_list; tmp2; tmp2 = g_slist_next(tmp2))
+			{
+				icd = tmp2->data;
+
+				if (icd->node_type == CONNECTION)
+				{
+					gtk_tree_store_append(treestore, &grandchild, &child);
+					gtk_tree_store_set(treestore, &grandchild, COL_ICON, icon_conn, COLUMN, icd->tagtxt, -1);
+					
+				}
+			}
+		}
+	}
+
+	
+	for (tmp = sess_list; tmp; tmp = g_slist_next(tmp))
+	{
+		isd = tmp->data;
+		if (isd->node_type == SIG_CONNECTION)
+		{
+			gtk_tree_store_append(treestore, &child, &toplevel);
+			gtk_tree_store_set(treestore, &child, COL_ICON, icon_only_conn, COLUMN, isd->tagtxt, -1);
+		}
+	}
+
+	return GTK_TREE_MODEL(treestore);
+}
+
+/*
+ * init a topology for iscsi session/connection.
+*/
+GtkWidget *iscsi_topology_init(void)
+{
+	GtkTreeViewColumn *col;
+	GtkCellRenderer *renderer;
+	GtkWidget *view;
+	GtkTreeModel *model = NULL;
+
+	view = gtk_tree_view_new();
+	col = gtk_tree_view_column_new();
+	gtk_tree_view_column_set_title(col, "Session/Connection Topology");
+
+	/*pix*/
+	renderer = gtk_cell_renderer_pixbuf_new();
+	gtk_tree_view_column_pack_start(col, renderer, FALSE);
+	gtk_tree_view_column_set_attributes(col, renderer, "pixbuf", COL_ICON, NULL);
+
+	/*text*/
+	renderer = gtk_cell_renderer_text_new();
+	gtk_tree_view_column_pack_start(col, renderer, TRUE);
+	gtk_tree_view_column_add_attribute(col, renderer, "text", COLUMN);
+
+	gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
+
+	model = init_iscsi_model();
+	gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
+	
+	//g_object_set_data(G_OBJECT(model), "iscsiexpert_session_list", &iscsiexpert_session_list);
+
+	return view;
+
+}
+
+void display_param_in_list(GtkWidget *parameter_list, const gchar *key, 
+                                        const gchar *value, guint32 from)
+{
+	GtkListStore *store = NULL;
+	GtkTreeIter iter;
+    gchar attr_nego[] = "Value got from negotiation";
+    gchar attr_def[] = "Default value in RFC3720";
+    gchar attr_ini[] = "Initiator provides the value";
+    gchar attr_tar[] = "Target provides the value";
+    gchar *attr = NULL;
+
+	if (from == -1)
+	{
+		store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(parameter_list)));
+		gtk_list_store_append(store, &iter);
+		gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(parameter_list), GTK_TREE_VIEW_GRID_LINES_NONE);
+		gtk_list_store_set(store, &iter, KEY_COLUMN, "Please select a session or connection.",
+										 VALUE_COLUMN, "",
+										 ATTRIBUTE_COLUMN, "",
+										 -1);
+		return;		
+	}
+    else if (from == -3){
+		store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(parameter_list)));
+		gtk_list_store_append(store, &iter);
+		gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(parameter_list), GTK_TREE_VIEW_GRID_LINES_NONE);
+		gtk_list_store_set(store, &iter, KEY_COLUMN, "There is no iSCSI session/connection.",
+										 VALUE_COLUMN, "",
+										 ATTRIBUTE_COLUMN, "",
+										 -1);
+        return;
+    }
+    else if(from == -2){
+		store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(parameter_list)));
+		gtk_list_store_append(store, &iter);
+		gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(parameter_list), GTK_TREE_VIEW_GRID_LINES_NONE);
+		gtk_list_store_set(store, &iter, KEY_COLUMN, "There is no pcap file opened for iSCSI Expert.",
+										 VALUE_COLUMN, "",
+										 ATTRIBUTE_COLUMN, "",
+										 -1);
+		return;
+    }
+    else{
+        switch(from){
+            case NEGOTIATION_VALUE_FROM_DEF:
+                attr = attr_def;
+                break;
+            case NEGOTIATION_VALUE_FROM_NEGO:
+                attr = attr_nego;
+                break;
+            case NEGOTIATION_VALUE_FROM_INI:
+                attr = attr_ini;
+                break;
+            case NEGOTIATION_VALUE_FROM_TAR:
+                attr = attr_tar;
+                break;
+            default:
+                break;
+        }
+    }
+	
+	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(parameter_list)));
+	gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(parameter_list), GTK_TREE_VIEW_GRID_LINES_BOTH);
+	
+	/*Display the real negotiation key=value pairs*/
+	gtk_list_store_append(store, &iter);
+	gtk_list_store_set(store, &iter, KEY_COLUMN, key,
+									 VALUE_COLUMN, value,
+									 ATTRIBUTE_COLUMN, attr,
+									 -1);
+	
+}
+
+static void
+display_sess_params_detail(GtkWidget *params_list, iscsi_session_params_t *sess_params)
+{
+	//const gchar attr_sess[64] = "Session parameter got from login.";
+	gchar num_val[VAL_BUFF_LEN];
+    iscsi_session_t sess_type;
+
+	memset(num_val, 0, VAL_BUFF_LEN); 
+	g_sprintf(num_val, "%s", sess_params->session_type ? "Discovery" : "Normal");
+	display_param_in_list(params_list, "SessionType", 
+                          num_val, 
+                          NEGOTIATION_VALUE_FROM_INI);
+    sess_type = sess_params->session_type;
+
+	if (sess_params->target_name)
+	{
+		display_param_in_list(params_list, "TargetName", 
+                              sess_params->target_name, 
+                              NEGOTIATION_VALUE_FROM_INI);  
+	}
+	if (sess_params->target_addr)
+	{
+		display_param_in_list(params_list, "TargetAddress", 
+                              sess_params->target_addr, 
+                              NEGOTIATION_VALUE_FROM_TAR);   
+	}
+	if (sess_params->target_alias)
+	{
+		display_param_in_list(params_list, "TargetAlias", 
+                              sess_params->target_alias, 
+                              NEGOTIATION_VALUE_FROM_TAR);  
+	}	
+	if (sess_params->initiator_name)
+	{
+		display_param_in_list(params_list, "InitiatorName", 
+                              sess_params->initiator_name,
+                              NEGOTIATION_VALUE_FROM_INI); 
+	}
+	if (sess_params->initiator_alias)
+	{
+		display_param_in_list(params_list, "InitiatorAlias", 
+                              sess_params->initiator_alias,
+                              NEGOTIATION_VALUE_FROM_INI);
+	}
+
+	memset(num_val, 0, VAL_BUFF_LEN); 
+	g_sprintf(num_val, "%d", sess_params->target_portal_group_tag);
+	display_param_in_list(params_list, "TargetPortalGroupTag", 
+                          num_val,
+                          NEGOTIATION_VALUE_FROM_TAR);
+
+    if (sess_type == NORMAL_TYPE){
+        memset(num_val, 0, VAL_BUFF_LEN); 
+        g_sprintf(num_val, "%d", sess_params->max_connections.value);
+        display_param_in_list(params_list, "MaxConnections", 
+                              num_val, 
+                              sess_params->max_connections.from);
+
+        memset(num_val, 0, VAL_BUFF_LEN); 
+        g_sprintf(num_val, "%s", sess_params->initial_r2t.value ? "Yes" : "No");
+        display_param_in_list(params_list, "InitialR2T", 
+                              num_val, 
+                              sess_params->initial_r2t.from);
+
+    	memset(num_val, 0, VAL_BUFF_LEN); 
+        g_sprintf(num_val, "%s", sess_params->imm_data.value ? "Yes" : "No");
+    	display_param_in_list(params_list, "ImmediateData", 
+                              num_val, 
+                              sess_params->imm_data.from);
+    
+    	memset(num_val, 0, VAL_BUFF_LEN); 
+        g_sprintf(num_val, "%d", sess_params->max_burst_len.value);
+    	display_param_in_list(params_list, "MaxBurstLength", 
+                              num_val, 
+                              sess_params->max_burst_len.from);
+
+    	memset(num_val, 0, VAL_BUFF_LEN); 
+        g_sprintf(num_val, "%d", sess_params->first_burst_len.value);
+    	display_param_in_list(params_list, "FirstBurstLength", 
+                              num_val, 
+                              sess_params->first_burst_len.from);
+
+		memset(num_val, 0, VAL_BUFF_LEN); 
+        g_sprintf(num_val, "%d", sess_params->max_outstand_r2t.value);
+    	display_param_in_list(params_list, "MaxOutstandingR2T", 
+                              num_val, 
+                              sess_params->max_outstand_r2t.from);
+
+    	memset(num_val, 0, VAL_BUFF_LEN); 
+        g_sprintf(num_val, "%s", sess_params->data_pdu_inorder.value ? "Yes" : "No");
+    	display_param_in_list(params_list, "DataPDUInOrder", 
+                              num_val, 
+                              sess_params->data_pdu_inorder.from);
+
+    	memset(num_val, 0, VAL_BUFF_LEN); 
+        g_sprintf(num_val, "%s", sess_params->data_seq_inorder.value ? "Yes" : "No");
+    	display_param_in_list(params_list, "DataSequenceInOrder", 
+                              num_val, 
+                              sess_params->data_seq_inorder.from);
+    }
+	
+	memset(num_val, 0, VAL_BUFF_LEN); 
+    g_sprintf(num_val, "%d", sess_params->dflt_time2wait.value);
+	display_param_in_list(params_list, "DefaultTime2Wait", 
+                          num_val, 
+                          sess_params->dflt_time2wait.from);
+	
+	memset(num_val, 0, VAL_BUFF_LEN); 
+    g_sprintf(num_val, "%d", sess_params->dflt_time2retain.value);
+	display_param_in_list(params_list, "DefaultTime2Retain", 
+                          num_val, 
+                          sess_params->dflt_time2retain.from);
+
+	memset(num_val, 0, VAL_BUFF_LEN); 
+    g_sprintf(num_val, "%d", sess_params->error_recovery_lvl.value);
+	display_param_in_list(params_list, "ErrorRecoveryLevel", 
+                          num_val, 
+                          sess_params->error_recovery_lvl.from);
+	
+}
+
+static void
+display_conn_params_detail(GtkWidget *params_list, iscsi_connection_params_t *conn_params)
+{
+	//const gchar attr_conn[64] = "Connection parameter got from login.";
+	char num_val[VAL_BUFF_LEN];
+
+	memset(num_val, 0, VAL_BUFF_LEN); 
+	switch(conn_params->header_digest.value){
+	case ISCSIEXPERT_HEADER_DIGEST_NONE:
+    case ISCSIEXPERT_HEADER_DIGEST_AUTO:
+        g_sprintf(num_val, "%s", "None");
+        break;
+    case ISCSIEXPERT_HEADER_DIGEST_CRC32:
+        g_sprintf(num_val, "%s", "CRC32C");
+        break;
+    default:
+        g_sprintf(num_val, "%s", "Unknown");
+        break;
+	}
+    /*here should be fixed for list type param: zq*/
+	display_param_in_list(params_list, "HeaderDigest", 
+                          num_val, 
+                          conn_params->header_digest.from);        
+
+	memset(num_val, 0, VAL_BUFF_LEN); 
+	switch(conn_params->data_digest.value){
+	case ISCSIEXPERT_HEADER_DIGEST_NONE:
+    case ISCSIEXPERT_HEADER_DIGEST_AUTO:
+        g_sprintf(num_val, "%s", "None");
+        break;
+    case ISCSIEXPERT_HEADER_DIGEST_CRC32:
+        g_sprintf(num_val, "%s", "CRC32C");
+        break;
+    default:
+        g_sprintf(num_val, "%s", "Unknown");
+        break;
+	}
+	display_param_in_list(params_list, "DataDigest", 
+                          num_val, 
+                          conn_params->data_digest.from);        
+
+	memset(num_val, 0, VAL_BUFF_LEN); 
+    g_sprintf(num_val, "%d", conn_params->max_recv_data_segment_length.value);
+	display_param_in_list(params_list, "MaxRecvDataSegmentLength - Initiator", 
+                          num_val, 
+                          conn_params->max_recv_data_segment_length.from);
+
+
+    
+	memset(num_val, 0, VAL_BUFF_LEN); 
+    g_sprintf(num_val, "%d", conn_params->max_xmit_data_segment_length.value);
+	display_param_in_list(params_list, "MaxRecvDataSegmentLength - Target", 
+                          num_val, 
+                          conn_params->max_xmit_data_segment_length.from);
+
+
+
+    memset(num_val, 0, VAL_BUFF_LEN); 
+    switch (conn_params->authmethod.value)
+    {
+    case ISCSIEXPERT_AUTH_METHOD_NONE:
+    case ISCSIEXPERT_AUTH_METHOD_AUTO:  // in this time, AuthMethod didn't be negotiated
+        g_sprintf(num_val, "%s", "None");
+        break;
+    case ISCSIEXPERT_AUTH_METHOD_CHAP:
+        g_sprintf(num_val, "%s", "CHAP");
+        break;
+    case ISCSIEXPERT_AUTH_METHOD_SRP:
+        g_sprintf(num_val, "%s", "SRP");
+        break;
+    case ISCSIEXPERT_AUTH_METHOD_SPKM1:
+        g_sprintf(num_val, "%s", "SPKM1");
+        break;
+    case ISCSIEXPERT_AUTH_METHOD_SPKM2:
+        g_sprintf(num_val, "%s", "SPKM2");
+        break;
+    case ISCSIEXPERT_AUTH_METHOD_KRB5:
+        g_sprintf(num_val, "%s", "KRB5");
+        break;
+    default:
+        g_sprintf(num_val, "%s", "Unknown");
+        break;
+    }    
+    /*Here should be fiexed for auth param: zq*/
+    display_param_in_list(params_list, "AuthMethod", 
+                          num_val, conn_params->authmethod.from);        
+
+    memset(num_val, 0, VAL_BUFF_LEN); 
+    if(conn_params->ofmarkint.value == VALUE_REJECT)
+        g_sprintf(num_val, "%s", "No");
+    else
+        g_sprintf(num_val, "%s", conn_params->ofmarker.value ? "Yes" : "No");
+    display_param_in_list(params_list, "OFMarker", 
+                          num_val, 
+                          conn_params->ofmarker.from);
+
+    memset(num_val, 0, VAL_BUFF_LEN); 
+    if(conn_params->ofmarker.value == TRUE){
+        if(conn_params->ofmarkint.value == VALUE_REJECT)
+            g_sprintf(num_val, "%s", "Reject");
+        else if(conn_params->ofmarkint.value == VALUE_IRRLELVANT)
+            g_sprintf(num_val, "%s", "Irrelevant");
+        else
+            g_sprintf(num_val, "%d", conn_params->ofmarkint.value);
+    }
+
+    else
+        g_sprintf(num_val, "%s", "Irrelevant");
+    display_param_in_list(params_list, "OFMarkInt", 
+                          num_val, 
+                          conn_params->ofmarkint.from);
+
+    memset(num_val, 0, VAL_BUFF_LEN); 
+    if(conn_params->ifmarkint.value == VALUE_REJECT)
+        g_sprintf(num_val, "%s", "No");
+    else
+        g_sprintf(num_val, "%s", conn_params->ifmarker.value ? "Yes" : "No");
+    display_param_in_list(params_list, "IFMarker", 
+                          num_val, 
+                          conn_params->ifmarker.from);
+
+    memset(num_val, 0, VAL_BUFF_LEN); 
+    if(conn_params->ifmarkint.value == TRUE){
+        if(conn_params->ifmarkint.value == VALUE_REJECT)
+            g_sprintf(num_val, "%s", "Reject");
+        else if(conn_params->ifmarkint.value == VALUE_IRRLELVANT)
+            g_sprintf(num_val, "%s", "Irrelevant");
+        else
+            g_sprintf(num_val, "%d", conn_params->ifmarkint.value);
+    }
+    else
+        g_sprintf(num_val, "%s", "Irrelevant");
+    display_param_in_list(params_list, "IFMarkInt", 
+                          num_val, 
+                          conn_params->ifmarkint.from);
+	
+}
+
+static void
+display_params_default(GtkWidget *params_list,
+							 iscsi_session_params_t *sess_params,
+							 iscsi_connection_params_t *conn_params)
+{
+
+    
+	display_param_in_list(params_list, "SessionType", "Normal", NEGOTIATION_VALUE_FROM_DEF);	
+
+	/*session wide params*/
+	display_param_in_list(params_list, "MaxConnections", "1", NEGOTIATION_VALUE_FROM_DEF);
+	
+	display_param_in_list(params_list, "InitialR2T", "Yes", NEGOTIATION_VALUE_FROM_DEF);
+	
+	display_param_in_list(params_list, "ImmediateData", "Yes", NEGOTIATION_VALUE_FROM_DEF);
+	
+	display_param_in_list(params_list, "MaxBurstLength", "262144", NEGOTIATION_VALUE_FROM_DEF);
+	
+	display_param_in_list(params_list, "FirstBurstLength", "65536", NEGOTIATION_VALUE_FROM_DEF);
+	
+	display_param_in_list(params_list, "MaxOutstandingR2T", "1", NEGOTIATION_VALUE_FROM_DEF);	
+
+	display_param_in_list(params_list, "DataPDUInOrder", "Yes", NEGOTIATION_VALUE_FROM_DEF);		
+	
+	display_param_in_list(params_list, "DataSequenceInOrder", "Yes", NEGOTIATION_VALUE_FROM_DEF);		
+	
+	display_param_in_list(params_list, "DefaultTime2Wait", "2", NEGOTIATION_VALUE_FROM_DEF);
+	
+	display_param_in_list(params_list, "DefaultTime2Retain", "20", NEGOTIATION_VALUE_FROM_DEF);
+	
+	display_param_in_list(params_list, "ErrorRecoveryLevel", "0", NEGOTIATION_VALUE_FROM_DEF);	
+	
+	/*connection wide params*/
+	display_param_in_list(params_list, "HeaderDigest", "None", NEGOTIATION_VALUE_FROM_DEF);		
+
+	display_param_in_list(params_list, "DataDigest", "None", NEGOTIATION_VALUE_FROM_DEF); 	
+
+	display_param_in_list(params_list, "MaxRecvDataSegmentLength - Initiator", "8192", NEGOTIATION_VALUE_FROM_DEF); 
+
+    display_param_in_list(params_list, "MaxRecvDataSegmentLength - Target", "8192", NEGOTIATION_VALUE_FROM_DEF);
+
+    display_param_in_list(params_list, "AuthMethod", "None", NEGOTIATION_VALUE_FROM_DEF);	
+
+    display_param_in_list(params_list, "IFMarker", "No", NEGOTIATION_VALUE_FROM_DEF);   
+
+    display_param_in_list(params_list, "IFMarkInt", "Irrelevant", NEGOTIATION_VALUE_FROM_DEF);  
+
+    display_param_in_list(params_list, "OFMarker", "No", NEGOTIATION_VALUE_FROM_DEF);   
+
+    display_param_in_list(params_list, "OFMarkInt", "Irrelevant", NEGOTIATION_VALUE_FROM_DEF);  
+    
+}
+
+static void 
+display_params_detail(GtkWidget *params_list, 
+					  iscsi_session_params_t *sess_params, iscsi_connection_params_t *conn_params)
+{
+	GtkListStore *store = NULL;
+	
+	/*clear the old list store*/
+	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(params_list)));
+	gtk_list_store_clear(store);
+
+	if (sess_params && conn_params)
+	{
+		/*display session params*/
+		display_sess_params_detail(params_list, sess_params);
+
+		/*display connection params*/
+		display_conn_params_detail(params_list, conn_params);
+	}
+	else if (sess_params)
+	{
+		/*only display session params*/
+		display_sess_params_detail(params_list, sess_params);
+	}
+	else
+	{
+		/*single connection, display default iscsi params value*/
+		display_params_default(params_list, sess_params, conn_params);
+	}
+
+	gtk_widget_show(GTK_WIDGET(params_list));
+}
+
+static void
+copy_sess_params(iscsi_session_params_t *dst, iscsi_session_params_t *src)
+{
+	if (dst == NULL || src == NULL)
+		return;
+
+	memcpy(dst, src, sizeof(iscsi_session_params_t));
+
+	if (src->initiator_name)
+		dst->initiator_name = g_strdup(src->initiator_name);
+	if (src->target_name)
+		dst->target_name = g_strdup(src->target_name);
+	if (src->target_addr)
+		dst->target_addr = g_strdup(src->target_addr);
+	if (src->initiator_alias)
+		dst->initiator_alias = g_strdup(src->initiator_alias);
+	if (src->target_alias)
+		dst->target_alias = g_strdup(src->target_alias);
+	
+}
+
+static void
+unselect_all(GSList *sess_list)
+{
+	GSList *tmp = NULL;
+	GSList *tmp2 = NULL;
+	iscsiexpert_sess_display_t *isd = NULL;
+	iscsiexpert_conn_display_t *icd = NULL;
+	
+	for (tmp = sess_list; tmp; tmp = g_slist_next(tmp))
+	{
+		isd = tmp->data;
+
+		if (isd->node_type == SESSION)
+		{
+			for (tmp2 = isd->con_list; tmp2; tmp2 = g_slist_next(tmp2))
+			{
+				icd = tmp2->data;
+				icd->dissector_conn->display = FALSE;
+			}
+		}
+		else
+		{
+			/*single connection*/
+			isd->dissector_conn->display = FALSE;
+		}
+	}
+}
+
+static void
+select_expert_items(GSList *sess_list, 
+                         iscsiexpert_sess_display_t *isd, 
+                         iscsiexpert_conn_display_t *icd,
+						 gint who)
+{
+	GSList *tmp = NULL;
+
+	unselect_all(sess_list);
+
+	switch (who)
+	{
+	case SESSION:
+		for (tmp = isd->con_list; tmp; tmp = g_slist_next(tmp))
+		{
+			icd = tmp->data;
+			icd->dissector_conn->display = TRUE;
+		}
+		break;
+	case CONNECTION:
+		icd->dissector_conn->display = TRUE;
+		break;
+	case SIG_CONNECTION:
+		isd->dissector_conn->display = TRUE;
+		break;
+	default:
+		break;
+	}
+
+}
+
+
+
+void display_params(GtkTreeSelection *selection, GtkWidget *iscsi_params_window, GSList *sess_list)
+{
+	GtkTreeView *treeview;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gchar *value;
+	gchar test[64] = {0};
+	iscsiexpert_sess_display_t *isd = NULL;
+	iscsiexpert_conn_display_t *icd = NULL;
+	GSList *tmp = NULL;
+	GSList *tmp2 = NULL;
+	gint find = -1;
+	iscsi_session_params_t session_param;
+	iscsi_connection_params_t connection_param;
+
+	GtkWidget *param_list = g_object_get_data(G_OBJECT(iscsi_params_window), "parameter_list");
+	GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(param_list)));
+	
+	/*Get the session and connection information, and display it*/
+	memset(&session_param, 0, sizeof(iscsi_session_params_t));
+	memset(&connection_param, 0, sizeof(iscsi_connection_params_t));
+
+	treeview = gtk_tree_selection_get_tree_view (selection);
+	if (gtk_tree_selection_get_selected(selection, &model, &iter))
+	{
+		gtk_tree_model_get(model, &iter, COLUMN, &value, -1);
+
+		for (tmp = sess_list; tmp; tmp = g_slist_next(tmp))
+		{
+			isd = tmp->data;
+			if (strcmp(isd->tagtxt, value) == 0)
+			{
+				find = isd->node_type;
+				switch (find)
+				{
+					case SESSION:
+						copy_sess_params(&session_param, &isd->session_params);
+						
+						/*display the session parameter*/
+						display_params_detail(param_list, &session_param, NULL);						
+						select_expert_items(sess_list, isd, NULL, find);
+						break;
+					case SIG_CONNECTION:
+						/*display the default parameter*/
+						display_params_detail(param_list, NULL, NULL);
+						select_expert_items(sess_list, isd, NULL, find);
+
+						break;
+					default:
+						break;
+				}
+				break;
+			}
+		}
+		if (find == -1)
+		{
+			for (tmp = sess_list; tmp; tmp = g_slist_next(tmp))
+			{
+				isd = tmp->data;
+				if (isd->node_type == SESSION)
+				{
+					for (tmp2 = isd->con_list; tmp2; tmp2 = g_slist_next(tmp2))
+					{
+						icd = tmp2->data;
+						if (strcmp(icd->tagtxt, value) == 0)
+						{
+							find = icd->node_type;
+							memcpy(&connection_param, &icd->connection_params, sizeof(iscsi_connection_params_t));
+							copy_sess_params(&session_param, &isd->session_params);
+
+							/*display session and connection params*/
+							display_params_detail(param_list, &session_param, &connection_param);
+							select_expert_items(sess_list, isd, icd, find);
+							break;
+						}
+					}
+
+				}
+			}
+		}
+
+		if (find == -1)
+		{
+			gtk_list_store_clear(store);
+			display_param_in_list(param_list, NULL, NULL ,-1);
+		}
+
+		g_free(value);
+
+		g_free(session_param.target_addr);
+		g_free(session_param.target_alias);
+		g_free(session_param.target_name);
+		g_free(session_param.initiator_alias);
+		g_free(session_param.initiator_name);
+		
+		return;
+		}
+
+}
+
+/* reset of display only, e.g. for filtering */
+static void iscsiexpert_dlg_display_reset(iscsiexpert_tapdata_t * etd)
+{
+	etd->disp_events = 0;
+	etd->first_row = TRUE;
+	gtk_clist_clear(etd->table);
+	gtk_clist_columns_autosize(etd->table);
+
+	gtk_window_set_title(GTK_WINDOW(etd->win), "Wireshark: ? Expert Infos");
+	if(etd->label) {
+		gtk_label_set_text(GTK_LABEL(etd->label), "Please wait ...");
+	}
+}
+
+
+/* complete reset, e.g. capture file closed */
+void iscsiexpert_dlg_reset(void *tapdata)
+{
+	iscsiexpert_tapdata_t * etd = tapdata;
+
+	g_list_free(etd->all_events);
+	etd->all_events = NULL;
+	g_list_free(etd->new_events);
+	etd->new_events = NULL;
+	etd->chat_events = 0;
+	etd->note_events = 0;
+	etd->warn_events = 0;
+	etd->error_events = 0;
+	etd->first_row	  = TRUE;
+
+	iscsiexpert_dlg_display_reset(etd);
+}
+
+int iscsiexpert_dlg_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *pointer)
+{
+	iscsiexpert_expertdata_info_t	*iti = se_memdup(pointer,sizeof(iscsiexpert_expertdata_info_t));
+	iscsiexpert_tapdata_t * etd = tapdata;
+	int ei_proto_level = PI_ALL;
+
+    iti->protocol = se_strdup(iti->protocol);
+    iti->summary = se_strdup(iti->summary);
+
+	switch(iti->severity) {
+	case(PI_CHAT):
+		etd->chat_events++;
+		break;
+	case(PI_NOTE):
+		etd->note_events++;
+		break;
+	case(PI_WARN):
+		etd->warn_events++;
+		break;
+	case(PI_ERROR):
+		etd->error_events++;
+		break;
+	default:
+		g_assert_not_reached();
+		;
+	}
+
+	/* insert(0) is a *lot* faster than append! */
+	etd->new_events = g_list_insert(etd->new_events, iti, 0);
+
+	if (!strcmp(iti->protocol, "TCP"))
+	{
+		ei_proto_level = PI_TCP;
+	} 
+	else if (!strcmp(iti->protocol, "iSCSI[E]"))
+	{
+		ei_proto_level = PI_ISCSI;
+	}
+
+	if(iti->severity < etd->severity_report_level 
+			//||	ei_proto_level < etd->protocol_report_level 
+			||	FALSE == iti->conn->display ) {
+		return 0; /* draw not required */
+	} else {
+		/* display the first row*/
+		if (etd->first_row == TRUE){
+			iscsi_cf_goto_frame(&cfile, iti->packet_num);
+			etd->first_row = FALSE;
+		}
+		return 1; /* draw required */
+	}
+
+}
+
+void
+iscsiexpert_dlg_draw(void *data)
+{
+	iscsiexpert_tapdata_t *etd = data;
+	int row;
+	int displayed;
+	char *strp;
+	iscsiexpert_expertdata_info_t *iti;
+	gchar *title;
+	const char *entries[5];   /**< column entries */
+
+	displayed = etd->disp_events;
+	//simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+	// 	  "iscsiexpert_dlg_draw");
+
+	if(etd->label) {
+		if(etd->new_events != NULL) {
+			title = g_strdup_printf("Adding: %u new messages",
+				g_list_length(etd->new_events));
+			gtk_label_set_text(GTK_LABEL(etd->label), title);
+			g_free(title);
+		}
+	}
+
+	gtk_clist_freeze(etd->table);
+
+	/* append new events (remove from new list, append to displayed list and clist) */
+	while(etd->new_events != NULL){
+		int ei_proto_level = PI_ALL;
+		
+
+		iti = etd->new_events->data;
+
+		etd->new_events = g_list_remove(etd->new_events, iti);
+		/* insert(0) is a *lot* faster than append! */
+		etd->all_events = g_list_insert(etd->all_events, iti, 0);
+
+		if (!strcmp(iti->protocol, "TCP"))
+		{
+			ei_proto_level = PI_TCP;
+		} 
+		else if (!strcmp(iti->protocol, "iSCSI[E]"))
+		{
+			ei_proto_level = PI_ISCSI;
+		}
+
+		if(iti->severity < etd->severity_report_level 
+		  // || ei_proto_level < etd->protocol_report_level
+		   || FALSE == iti->conn->display) {
+			continue;
+		}
+		etd->disp_events++;
+		/* display the first row*/
+		if (etd->first_row == TRUE){
+			iscsi_cf_goto_frame(&cfile, iti->packet_num);
+			etd->first_row = FALSE;
+		}
+
+		if(etd->disp_events == 1000)
+			gtk_clist_columns_autosize(etd->table);
+
+		/* packet number */
+		if(iti->packet_num) {
+			/* XXX */
+			strp= se_strdup_printf("%u", iti->packet_num);
+			entries[0] = strp;
+			/*entries[0] = itoa(ei->packet_num, str, 10);*/
+		} else {
+			entries[0] = "-";
+		}
+
+		/* severity */
+		entries[1] = val_to_str(iti->severity, expert_severity_vals, "Unknown severity (%u)");
+
+		/* group */
+		entries[2] = val_to_str(iti->group, expert_group_vals, "Unknown group (%u)");
+
+		/* protocol */
+		if(iti->protocol) {
+			entries[3] = iti->protocol;
+		} else {
+			entries[3] = "-";
+		}
+
+		/* summary */
+		entries[4] = iti->summary;
+
+		/*gtk_clist_set_pixmap(etd->table, row, 5, ascend_pm, ascend_bm);*/
+
+		row=gtk_clist_append(etd->table, (gchar **) entries);
+		gtk_clist_set_row_data(etd->table, row, iti);
+
+		/* set rows background color depending on severity */
+		switch(iti->severity) {
+		case(PI_CHAT):
+			gtk_clist_set_background(etd->table, row, &expert_color_chat);
+			break;
+		case(PI_NOTE):
+			gtk_clist_set_background(etd->table, row, &expert_color_note);
+			break;
+		case(PI_WARN):
+			gtk_clist_set_background(etd->table, row, &expert_color_warn);
+			break;
+		case(PI_ERROR):
+			gtk_clist_set_background(etd->table, row, &expert_color_error);
+			break;
+		default:
+			g_assert_not_reached();
+		}
+		gtk_clist_set_foreground(etd->table, row, &expert_color_foreground);
+	}
+
+	gtk_clist_sort(etd->table);
+	/* column autosizing is very slow for large number of entries,
+	 * so do it only for the first 1000 of it
+	 * (there might be no large changes behind this amount) */
+	if(etd->disp_events < 1000)
+		gtk_clist_columns_autosize(etd->table);
+	gtk_clist_moveto(etd->table,
+                     etd->disp_events - 1, -1, 1.0f, 1.0f);
+	gtk_clist_thaw(etd->table);
+
+	if(etd->label) {
+		title = g_strdup_printf("Errors: %u Warnings: %u Notes: %u Chats: %u",
+			etd->error_events, etd->warn_events, etd->note_events, etd->chat_events);
+			gtk_label_set_text(GTK_LABEL(etd->label), title);
+		g_free(title);
+	}
+
+	title = g_strdup_printf("Wireshark: %u Expert Info%s",
+		etd->disp_events,
+		plurality(etd->disp_events, "", "s"));
+	gtk_window_set_title(GTK_WINDOW(etd->win), title);
+	g_free(title);
+}
+
+
+static void
+iscsiexpert_dlg_redraw(gpointer data)
+{
+	iscsiexpert_tapdata_t *etd=(iscsiexpert_tapdata_t *)data;
+
+	//simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,"iscsiexpert_dialog_redraw");
+
+	//for test
+//  if (etd->severity_report_level == PI_CHAT) {
+//  	etd->severity_report_level = PI_ERROR;
+//  }else {
+//  	etd->severity_report_level = PI_CHAT;
+//  }
+	
+	/* "move" all events from "all" back to "new" lists */
+	protect_thread_critical_region();
+	etd->new_events = g_list_concat(etd->new_events, etd->all_events);
+	etd->all_events = NULL;
+	unprotect_thread_critical_region();
+
+	/* redraw table */
+	iscsiexpert_dlg_display_reset(etd);
+	iscsiexpert_dlg_draw(etd);
+}
+
+
+static void
+on_changed(GtkTreeSelection *selection, gpointer data)
+{
+	GtkTreeView *treeview;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gchar *value;
+	GtkWidget *iscsi_params_window = NULL;
+	GSList *sess_list = NULL;
+
+	iscsiexpert_tapdata_t *etd=(iscsiexpert_tapdata_t *)data;
+
+	iscsi_params_window = etd->iscsi_parameter_window;
+	sess_list = etd->iscsiexpert_session_list;
+
+	/*display the session/connection releated iscsi parameters*/
+	display_params(selection, iscsi_params_window, sess_list);
+
+	/*refresh the PDU list*/
+	treeview = gtk_tree_selection_get_tree_view (selection);
+
+	gtk_widget_trigger_tooltip_query(GTK_WIDGET(treeview));
+
+	if (gtk_tree_selection_get_selected(selection, &model, &iter))
+	{
+		gtk_tree_model_get(model, &iter, COLUMN, &value, -1);
+
+		//simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,"The item is selected.");
+
+		iscsiexpert_dlg_redraw(etd);
+		
+		return;
+	}
+}
+
+typedef struct column_arrows {
+	GtkWidget *table;
+	GtkWidget *ascend_pm;
+	GtkWidget *descend_pm;
+} column_arrows;
+
+
+static gint
+srt_sort_column(GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2)
+{
+	char *text1 = NULL;
+	char *text2 = NULL;
+	int i1, i2;
+
+	const GtkCListRow *row1 = ptr1;
+	const GtkCListRow *row2 = ptr2;
+
+	text1 = GTK_CELL_TEXT (row1->cell[clist->sort_column])->text;
+	text2 = GTK_CELL_TEXT (row2->cell[clist->sort_column])->text;
+
+	switch(clist->sort_column){
+	case 0:
+		i1=atoi(text1);
+		i2=atoi(text2);
+		return i1-i2;
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+		return strcmp (text1, text2);
+	}
+	g_assert_not_reached();
+	return 0;
+}
+
+
+static void
+srt_click_column_cb(GtkCList *clist, gint column, gpointer data)
+{
+	column_arrows *col_arrows = (column_arrows *) data;
+	int i;
+
+	gtk_clist_freeze(clist);
+
+	for (i = 0; i < 5; i++) {
+		gtk_widget_hide(col_arrows[i].ascend_pm);
+		gtk_widget_hide(col_arrows[i].descend_pm);
+	}
+
+	if (column == clist->sort_column) {
+		if (clist->sort_type == GTK_SORT_ASCENDING) {
+			clist->sort_type = GTK_SORT_DESCENDING;
+			gtk_widget_show(col_arrows[column].descend_pm);
+		} else {
+			clist->sort_type = GTK_SORT_ASCENDING;
+			gtk_widget_show(col_arrows[column].ascend_pm);
+		}
+	} else {
+		clist->sort_type = GTK_SORT_ASCENDING;
+		gtk_widget_show(col_arrows[column].ascend_pm);
+		gtk_clist_set_sort_column(clist, column);
+	}
+	gtk_clist_sort(clist);
+
+	gtk_clist_thaw(clist);
+}
+
+
+
+
+
+static GtkWidget   *tv_scrollw;
+void
+tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_);
+
+/* Data structure holding information about a packet-detail window. */
+struct PacketWinData {
+	frame_data *frame;	   /* The frame being displayed */
+	union wtap_pseudo_header pseudo_header; /* Pseudo-header for packet */
+	guint8     *pd;		   /* Data for packet */
+	GtkWidget  *main;
+	GtkWidget  *tv_scrollw;
+	GtkWidget  *tree_view;
+	GtkWidget  *bv_nb_ptr;
+ 	field_info *finfo_selected;
+	epan_dissect_t	*edt;
+};
+
+/* List of all the packet-detail windows popped up. */
+static GList *detail_windows;
+static struct PacketWinData *DataPtr;
+
+static void
+select_row_cb(GtkCList *clist, gint row, gint column _U_, GdkEventButton *event _U_, gpointer user_data _U_)
+{
+	expert_info_t	*ei;
+
+
+	ei = (expert_info_t *) gtk_clist_get_row_data(clist, row);
+
+	//cf_select_packet(&cfile,row);
+
+	if (FALSE == iscsi_cf_goto_frame(&cfile, ei->packet_num))
+	{
+		return;
+	}
+
+	    /* Allocate data structure to represent this window. */
+	  //DataPtr = (struct PacketWinData *) g_malloc(sizeof(struct PacketWinData));
+
+	  DataPtr->frame = cfile.current_frame;
+	  memcpy(&DataPtr->pseudo_header, &cfile.pseudo_header, sizeof DataPtr->pseudo_header);
+	  DataPtr->pd = g_malloc(DataPtr->frame->cap_len);
+	  memcpy(DataPtr->pd, cfile.pd, DataPtr->frame->cap_len);
+	  DataPtr->edt = epan_dissect_new(TRUE, TRUE);
+	  epan_dissect_run(DataPtr->edt, &DataPtr->pseudo_header, DataPtr->pd,
+			  DataPtr->frame, &cfile.cinfo);
+	  epan_dissect_fill_in_columns(DataPtr->edt);
+
+	add_byte_views(DataPtr->edt,  DataPtr->tree_view, DataPtr->bv_nb_ptr);
+	proto_tree_draw(DataPtr->edt->tree,  DataPtr->tree_view);
+
+	DataPtr->finfo_selected = NULL;
+	gtk_widget_show(DataPtr->main);
+}
+
+
+void
+iscsiexpert_dlg_init_table(iscsiexpert_tapdata_t * etd, GtkWidget *hpaned)
+{
+	int i;
+	column_arrows *col_arrows;
+	GtkStyle *win_style;
+	GtkWidget *column_lb;
+	GdkBitmap *ascend_bm, *descend_bm;
+	GdkPixmap *ascend_pm, *descend_pm;
+	const char *default_titles[] = { "No.", "Sever.", "Group", "Protocol", "Summary" };
+
+
+	etd->scrolled_window=scrolled_window_new(NULL, NULL);
+	gtk_widget_set_size_request(etd->scrolled_window, 400, 300);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (etd->scrolled_window), GTK_POLICY_ALWAYS, GTK_POLICY_NEVER);
+
+	gtk_paned_pack2(GTK_PANED(hpaned), etd->scrolled_window,TRUE,TRUE);
+
+	etd->table=(GtkCList *)gtk_clist_new(5);
+	g_signal_connect(etd->table, "select-row", G_CALLBACK(select_row_cb), etd);
+
+	gtk_widget_show(GTK_WIDGET(etd->table));
+	gtk_widget_show(etd->scrolled_window);
+
+	col_arrows = (column_arrows *) g_malloc(sizeof(column_arrows) * 5);
+	win_style = gtk_widget_get_style(etd->scrolled_window);
+	ascend_pm = gdk_pixmap_create_from_xpm_d(etd->scrolled_window->window,
+			&ascend_bm,
+			&win_style->bg[GTK_STATE_NORMAL],
+			(gchar **)clist_ascend_xpm);
+	descend_pm = gdk_pixmap_create_from_xpm_d(etd->scrolled_window->window,
+			&descend_bm,
+			&win_style->bg[GTK_STATE_NORMAL],
+			(gchar **)clist_descend_xpm);
+	for (i = 0; i < 5; i++) {
+		col_arrows[i].table = gtk_table_new(2, 2, FALSE);
+		gtk_table_set_col_spacings(GTK_TABLE(col_arrows[i].table), 5);
+		column_lb = gtk_label_new(default_titles[i]);
+		gtk_table_attach(GTK_TABLE(col_arrows[i].table), column_lb, 0, 1, 0, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
+		gtk_widget_show(column_lb);
+
+		col_arrows[i].ascend_pm = gtk_pixmap_new(ascend_pm, ascend_bm);
+		gtk_table_attach(GTK_TABLE(col_arrows[i].table), col_arrows[i].ascend_pm, 1, 2, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
+		col_arrows[i].descend_pm = gtk_pixmap_new(descend_pm, descend_bm);
+		gtk_table_attach(GTK_TABLE(col_arrows[i].table), col_arrows[i].descend_pm, 1, 2, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
+		if (i == 0) {
+			gtk_widget_show(col_arrows[i].ascend_pm);
+		}
+		gtk_clist_set_column_widget(GTK_CLIST(etd->table), i, col_arrows[i].table);
+		gtk_widget_show(col_arrows[i].table);
+	}
+	gtk_clist_column_titles_show(GTK_CLIST(etd->table));
+
+	gtk_clist_set_compare_func(etd->table, srt_sort_column);
+	gtk_clist_set_sort_column(etd->table, 0);
+	gtk_clist_set_sort_type(etd->table, GTK_SORT_ASCENDING);
+
+	gtk_clist_set_column_justification(etd->table, 0, GTK_JUSTIFY_RIGHT);
+	gtk_clist_set_column_justification(etd->table, 3, GTK_JUSTIFY_RIGHT);
+	gtk_clist_set_shadow_type(etd->table, GTK_SHADOW_IN);
+	gtk_clist_column_titles_show(etd->table);
+	gtk_clist_columns_autosize(etd->table);
+/*	gtk_clist_set_selection_mode(etd->table, GTK_SELECTION_SINGLE);*/
+/*    gtk_list_set_selection_mode(GTK_LIST(etd->table), GTK_SELECTION_BROWSE);*/
+/*    gtk_list_select_item(GTK_LIST(value_list), 0);*/
+	gtk_container_add(GTK_CONTAINER(etd->scrolled_window), (GtkWidget *)etd->table);
+
+	g_signal_connect(etd->table, "click-column", G_CALLBACK(srt_click_column_cb), col_arrows);
+
+	gtk_widget_show(GTK_WIDGET(etd->table));
+	gtk_widget_show(etd->scrolled_window);
+
+	/* create popup menu for this table */
+	/*if(etd->filter_string){
+		srt_create_popup_menu(etd);
+	}*/
+}
+
+
+/* called when a tree row is (un)selected in the popup packet window */
+static void
+new_tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data)
+{
+    field_info   *finfo;
+    GtkWidget    *byte_view;
+    const guint8 *data;
+    guint         len;
+    GtkTreeModel *model;
+    GtkTreeIter   iter;
+
+    struct PacketWinData *DataPtr = (struct PacketWinData*)user_data;
+
+    /* if something is selected */
+    if (gtk_tree_selection_get_selected(sel, &model, &iter))
+    {
+        gtk_tree_model_get(model, &iter, 1, &finfo, -1);
+        if (!finfo) return;
+
+        set_notebook_page(DataPtr->bv_nb_ptr, finfo->ds_tvb);
+        byte_view = get_notebook_bv_ptr(DataPtr->bv_nb_ptr);
+        if (!byte_view)	/* exit if no hex window to write in */
+            return;
+
+        data = get_byte_view_data_and_length(byte_view, &len);
+        if (data == NULL) {
+            data = DataPtr->pd;
+            len =  DataPtr->frame->cap_len;
+        }
+
+        DataPtr->finfo_selected = finfo;
+        packet_hex_print(byte_view, data, DataPtr->frame, finfo, len);
+    }
+    else
+    {
+        DataPtr->finfo_selected = NULL;
+
+        byte_view = get_notebook_bv_ptr(DataPtr->bv_nb_ptr);
+        if (!byte_view)	/* exit if no hex window to write in */
+            return;
+
+        data = get_byte_view_data_and_length(byte_view, &len);
+        g_assert(data != NULL);
+        packet_hex_reprint(byte_view);
+    }
+}
+
+static gint
+button_press_handler(GtkWidget *widget, GdkEvent *event, gpointer data _U_)
+{
+  if (widget == NULL || event == NULL) {
+    return FALSE;
+  }
+
+  tree_view_select(widget, (GdkEventButton *) event);
+
+  /* GDK_2BUTTON_PRESS is a doubleclick -> expand/collapse tree row */
+  if (event->type == GDK_2BUTTON_PRESS) {
+    GtkTreePath      *path;
+
+    if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget),
+				      (gint) (((GdkEventButton *)event)->x),
+				      (gint) (((GdkEventButton *)event)->y),
+				      &path, NULL, NULL, NULL))
+    {
+      if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(widget), path)) {
+	gtk_tree_view_collapse_row(GTK_TREE_VIEW(widget), path);
+      }	else {
+	gtk_tree_view_expand_row(GTK_TREE_VIEW(widget), path, FALSE);
+      }
+      gtk_tree_path_free(path);
+    }
+  }
+
+  return FALSE;
+}
+
+static void
+destroy_new_window(GtkObject *object _U_, gpointer user_data)
+{
+  struct PacketWinData *DataPtr = user_data;
+
+  detail_windows = g_list_remove(detail_windows, DataPtr);
+  epan_dissect_free(DataPtr->edt);
+  g_free(DataPtr->pd);
+  g_free(DataPtr);
+
+}
+
+void
+iscsiexpert_dlg_init_treeview(iscsiexpert_tapdata_t * etd, GtkWidget *hpaned)
+{
+  gint32 tv_size = 125;
+  gint bv_size = 75;
+  GtkWidget   *tree_view, *tv_scrollw,
+                      *bv_nb_ptr ;
+
+  if (!cfile.is_tempfile && !cfile.filename)
+  {
+	  return;
+  }
+
+    /* Allocate data structure to represent this window. */
+  DataPtr = (struct PacketWinData *) g_malloc(sizeof(struct PacketWinData));
+  DataPtr->frame = cfile.current_frame;
+  memcpy(&DataPtr->pseudo_header, &cfile.pseudo_header, sizeof DataPtr->pseudo_header);
+  DataPtr->pd = g_malloc(DataPtr->frame->cap_len);
+  memcpy(DataPtr->pd, cfile.pd, DataPtr->frame->cap_len);
+  DataPtr->edt = epan_dissect_new(TRUE, TRUE);
+  epan_dissect_run(DataPtr->edt, &DataPtr->pseudo_header, DataPtr->pd,
+          DataPtr->frame, &cfile.cinfo);
+  epan_dissect_fill_in_columns(DataPtr->edt);
+
+  /* Tree view */
+  tv_scrollw = main_tree_view_new(&prefs, &tree_view);
+  gtk_paned_pack1(GTK_PANED(hpaned), tv_scrollw, TRUE, TRUE);
+  gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
+  gtk_widget_show(tv_scrollw);
+  gtk_widget_show(tree_view);
+
+  //* Byte view */
+  bv_nb_ptr = byte_view_new();
+  gtk_paned_pack2(GTK_PANED(hpaned), bv_nb_ptr, FALSE, FALSE);
+  gtk_widget_set_size_request(bv_nb_ptr, -1, bv_size);
+  gtk_widget_show(bv_nb_ptr);
+
+  DataPtr->main = hpaned;
+  DataPtr->tv_scrollw = tv_scrollw;
+  DataPtr->tree_view = tree_view;
+  DataPtr->bv_nb_ptr = bv_nb_ptr;
+  detail_windows = g_list_append(detail_windows, DataPtr);
+
+  /* load callback handlers */
+  g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)),
+                 "changed", G_CALLBACK(new_tree_view_selection_changed_cb), DataPtr);
+  g_signal_connect(tree_view, "button_press_event", G_CALLBACK(button_press_handler), NULL);
+  g_signal_connect(tree_view, "destroy", G_CALLBACK(destroy_new_window), DataPtr);
+
+  /* draw the protocol tree & print hex data */
+  add_byte_views(DataPtr->edt, tree_view, DataPtr->bv_nb_ptr);
+  proto_tree_draw(DataPtr->edt->tree, tree_view);
+
+  DataPtr->finfo_selected = NULL;
+  gtk_widget_show(DataPtr->main);
+
+}
+
+/*
+ * Description: initilize the parameter display treeview
+ * Parameter:
+ * iscsi_parameter_window: widget pointer of the window for treeview
+ * hpaned: widget pointer of the hpaned for the parent window of treeview
+ */
+gboolean iscsiexpert_init_parameter(GtkWidget *iscsi_parameter_window, GtkWidget *hpaned)
+{
+ 	GtkWidget *parameter_list = NULL;
+	GtkCellRenderer *renderer = NULL;
+	GtkTreeViewColumn *column = NULL;
+	GtkListStore *store = NULL;
+	GtkWidget *hscrollbar = NULL;
+	GtkWidget *vscrollbar = NULL;
+    gboolean ret = TRUE;
+ 	
+	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(iscsi_parameter_window), GTK_SHADOW_IN);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(iscsi_parameter_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	gtk_paned_pack2(GTK_PANED(hpaned), iscsi_parameter_window,TRUE,TRUE);
+
+ 	parameter_list = gtk_tree_view_new();
+
+ 	gtk_container_add(GTK_CONTAINER(iscsi_parameter_window), parameter_list);
+
+ 	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(parameter_list), TRUE);
+	gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW(parameter_list), TRUE);
+ 	
+	/*Key*/
+	renderer = gtk_cell_renderer_text_new();
+	column = gtk_tree_view_column_new_with_attributes("Key Name",
+													  renderer, "text", KEY_COLUMN, NULL);
+	gtk_tree_view_column_set_spacing(column, 5);
+	gtk_tree_view_column_set_resizable(column, TRUE);
+	gtk_tree_view_column_set_min_width(column, 100);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(parameter_list), column);
+
+	/*Value*/
+	renderer = gtk_cell_renderer_text_new();
+	column = gtk_tree_view_column_new_with_attributes("Value",
+													  renderer, "text", VALUE_COLUMN, NULL);
+	gtk_tree_view_column_set_spacing(column, 5);
+	gtk_tree_view_column_set_resizable(column, TRUE);
+	gtk_tree_view_column_set_min_width(column, 100);	
+	gtk_tree_view_append_column(GTK_TREE_VIEW(parameter_list), column);
+
+	/*Parameter attribute*/
+	renderer = gtk_cell_renderer_text_new();
+	column = gtk_tree_view_column_new_with_attributes("Comment",
+													  renderer, "text", ATTRIBUTE_COLUMN, NULL);
+	gtk_tree_view_column_set_spacing(column, 5);
+	gtk_tree_view_column_set_resizable(column, TRUE);
+	gtk_tree_view_column_set_min_width(column, 100);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(parameter_list), column);
+
+	store = gtk_list_store_new(PARAMETER_NUM_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+	gtk_tree_view_set_model(GTK_TREE_VIEW(parameter_list), GTK_TREE_MODEL(store));
+	
+	if (!cfile.is_tempfile && !cfile.filename)
+	{
+		display_param_in_list(parameter_list, NULL, NULL, -2);
+        ret = FALSE;
+	}
+
+	gtk_tree_view_set_model(GTK_TREE_VIEW(parameter_list), GTK_TREE_MODEL(store));
+ 	gtk_widget_show(GTK_WIDGET(parameter_list));
+	g_object_set_data(G_OBJECT(iscsi_parameter_window), "parameter_list", parameter_list);
+
+	return ret;
+}
+
+/*
+ * Description: initialize for the iscsi parameter
+ * Parameter:
+ * etd: struct which contains the pointers of all the widget and list used in expert dlg
+ * hpaned: widget pointer of hpaned, in which iscsi parameter is placed
+ */
+void
+iscsiexpert_dlg_init_iscsiparameter(iscsiexpert_tapdata_t * etd, GtkWidget *hpaned)
+{
+    GtkWidget *parameter_list = NULL;
+    gboolean openfile;
+    
+	etd->iscsi_parameter_window = scrolled_window_new(NULL, NULL);
+	openfile= iscsiexpert_init_parameter(etd->iscsi_parameter_window, hpaned);
+	
+	g_object_set_data(G_OBJECT(etd->win), "iscsi_parameter_window", etd->iscsi_parameter_window);
+    parameter_list = g_object_get_data(G_OBJECT(etd->iscsi_parameter_window), "parameter_list");    
+
+    if (openfile == TRUE && etd->iscsiexpert_session_list == NULL){
+        /*if the list is NULL, it means there is no iSCSI session/connection can be displayed by expert sys*/
+        display_param_in_list(parameter_list, NULL, NULL, -3);
+    }
+	
+	gtk_widget_show(GTK_WIDGET(etd->iscsi_parameter_window));
+
+}
+
+/*
+ * Description: query tooltip(callback of "query-tooltip") for the iscsi session topology treeview
+ */
+static gboolean
+query_tooltip_tree_view_cb(GtkWidget *widget,
+                                 gint x,
+                                 gint y,
+                                 gboolean keyboard_mode,
+                                 GtkTooltip *tooltip,
+                                 gpointer user_data)
+{
+	GtkTreeIter iter;
+	GtkTreeView *view = GTK_TREE_VIEW(widget);
+	GtkTreeModel *model = gtk_tree_view_get_model(view);
+	GtkTreePath *path = NULL;
+	GtkTreeViewColumn *column = NULL;
+	//GdkRectangle rect;
+	gchar *tmp;
+
+	char buf[512] = {0};
+
+	if (!gtk_tree_view_get_tooltip_context(view, 
+		                                  &x, 
+		                                  &y, 
+		                                  keyboard_mode, 
+		                                  &model,
+		                                  &path,
+		                                  &iter))
+		return FALSE;
+
+	gtk_tree_model_get(model, &iter, COLUMN, &tmp, -1);
+
+	g_snprintf(buf, 511, "%s", tmp);
+	gtk_tooltip_set_text(tooltip, buf);
+
+	column = gtk_tree_view_get_column(GTK_TREE_VIEW(view), COLUMN);
+	//rect.x = x;
+	//rect.y = y;
+	//rect.width = 200;
+	//rect.height = -1;
+	//gtk_tooltip_set_tip_area(tooltip, &rect);
+	gtk_tree_view_set_tooltip_cell(view, tooltip, path, column, NULL);
+	
+	gtk_tree_path_free(path);
+	g_free(tmp);
+		
+	return TRUE;
+}
+
+/*
+ * Description: initialize for iscsi session topology treeview
+ * Parameters:
+ * tree_scrooled_window: the widget pointer of scrolled window in which the treeview is placed
+ * hpaned: the widget pointer of hpaned in which the scrolled window is placed
+ * Return: the pointer of iscsi session topology treeview
+ */
+GtkWidget *tree_init(GtkWidget *tree_scrolled_window, GtkWidget *hpaned)
+{
+	GtkWidget *view = NULL;
+
+	gtk_paned_pack1(GTK_PANED(hpaned), tree_scrolled_window,TRUE,TRUE);
+	
+	view = iscsi_topology_init();
+	gtk_container_add(GTK_CONTAINER(tree_scrolled_window), view);
+
+	/*for tooltip*/
+	g_object_set(view, "has-tooltip", TRUE, NULL);
+	g_signal_connect (view, "query-tooltip", G_CALLBACK (query_tooltip_tree_view_cb), NULL);
+
+	if (!cfile.is_tempfile && !cfile.filename)
+	{
+		return view;
+	}
+
+	gtk_widget_show(view);	
+
+	return view;
+
+}
+
+/*
+ * Description: get connection from session set and append it into the sesion's connection list
+ * Parameter: 
+ * value: item of iscsi_sessionset->connq
+ * user_data: pointer of iscsiexpert_sess_display_t which the connection belongs to 
+ * Return: False (for the following add)
+ */
+static gboolean
+get_connections_from_sessionset(gpointer value, gpointer user_data)
+{	
+	conversation_t *conn = (conversation_t *)value;
+	iscsiexpert_session_t *iscsiexpert_session = NULL;
+
+	char tagtxt[SESSION_NAME_LEN] = {0};
+	guint32 index = conn->index;
+	conversation_key *conn_key = conn->key_ptr;
+	guint16 cid = 0;
+	iscsiexpert_sess_display_t *isd = (iscsiexpert_sess_display_t *)user_data;
+	iscsiexpert_conn_display_t *icd = NULL;
+	
+	iscsiexpert_session=conversation_get_proto_data(conn, proto_iscsie);
+	cid = iscsiexpert_session->cid;
+
+	g_sprintf(tagtxt, "Initiator:%s:%d<=>Target:%s:%d,CID:0x%04x", 
+		      get_addr_name(&iscsiexpert_session->initiaor_addr),
+			  iscsiexpert_session->initiator_port,
+			  get_addr_name(&iscsiexpert_session->target_addr),
+			  iscsiexpert_session->target_port, 
+			  cid);
+
+	icd = (iscsiexpert_conn_display_t *)g_malloc(sizeof(iscsiexpert_conn_display_t));
+	memset(icd, 0, sizeof(iscsiexpert_conn_display_t));
+	icd->node_type = CONNECTION;
+	g_stpcpy(icd->tagtxt, tagtxt);
+	
+	memcpy(&icd->connection_params, &iscsiexpert_session->params, sizeof(iscsi_connection_params_t));
+	icd->isd = isd;
+	isd->con_list= g_slist_append(isd->con_list, icd);
+	icd->dissector_conn = iscsiexpert_session;
+	
+	return FALSE;
+}
+
+/*
+ * Description: get the connection from session
+  (the function is called when the connection is a single connection, 
+   it doesn't belong to any session. We didn't add it into a sessionset. 
+   So, we get it's dissector_conn with this method)
+ * Parameter: 
+ * value: item of iscsi_sessionset->connq
+ * user_data: pointer of iscsiexpert_sess_display_t which the connection belongs to 
+ * Return: TRUE (don't need continuous)
+ */
+static gboolean
+get_connections_from_session(gpointer value, gpointer user_data)
+{	
+	conversation_t *conn = (conversation_t *)value;
+	iscsiexpert_session_t *iscsiexpert_session = NULL;
+	iscsiexpert_sess_display_t *isd = (iscsiexpert_sess_display_t *)user_data;
+    conversation_key *conn_key = conn->key_ptr;
+    
+	iscsiexpert_session=conversation_get_proto_data(conn, proto_iscsie);
+	isd->dissector_conn = iscsiexpert_session;
+
+	if (iscsiexpert_session->magic_flag != ISCSIE_MAGIC_FLAG){
+		printf("The ISCSIE Magic Flag is not right.\n");
+		return TRUE;
+	}
+
+	if (iscsiexpert_session->in_session == FALSE){
+		printf("The ISCSIE is not in session.\n");
+		return TRUE;
+	}
+
+
+	ISCSIE_DEBUG("Initiator:%s:%d<=>Target:%s:%d\n",
+		  get_addr_name(&iscsiexpert_session->initiaor_addr),
+		  iscsiexpert_session->initiator_port, 
+		  get_addr_name(&iscsiexpert_session->target_addr),
+		  iscsiexpert_session->target_port); 
+
+	g_sprintf(isd->tagtxt, "Initiator:%s:%d<=>Target:%s:%d", 
+		  get_addr_name(&iscsiexpert_session->initiaor_addr),
+		  iscsiexpert_session->initiator_port, 
+		  get_addr_name(&iscsiexpert_session->target_addr),
+		  iscsiexpert_session->target_port); 
+    
+	return TRUE; // only once
+}
+
+/*
+ * Description: get the needed session/connection info from the tapped hash table
+ * Parameter:
+ * key: key in hash table
+ * value: the value in hash table
+ * user_data: the session list used to display and relate sessions and connections in
+ *                session topology treeview with other part of the expert and statistic dlg
+ */
+void
+prepare_session_list (gpointer key, gpointer value _U_, gpointer user_data)
+{
+	GSList **sess_list = (GSList **)user_data;
+	
+	iscsisession_t *sess = value;
+	iscsisession_key *sess_key = &sess->key;
+
+	iscsiexpert_sess_display_t *isd = NULL;
+
+	guint64 isid = 0;
+	char isid_disp[6] = {0};
+	
+	iscsiexpert_sessionset_t *iscsi_sessionset = NULL;
+	char tagtxt[SESSION_NAME_LEN] = {0};
+	guint16 tsih = sess_key->tsih;
+
+	if (tsih != 0) /*connections within session*/
+	{
+		isid_disp[0] = (sess_key->isid.fmt_type << 6) & (sess_key->isid.A | 0xC0);
+		isid_disp[1] = sess_key->isid.B0;
+		isid_disp[2] = sess_key->isid.B1;
+		isid_disp[3] = sess_key->isid.C;
+		isid_disp[4] = sess_key->isid.D0;
+		isid_disp[5] = sess_key->isid.D1;
+		isid = pntoh64(isid_disp) >> 16;
+
+		g_sprintf(tagtxt, "ISID:0x%012"PRIx64",TSIH:0x%04x", isid, tsih);
+		
+		iscsi_sessionset = (iscsiexpert_sessionset_t *) iscsisession_get_proto_data(sess, proto_iscsie);
+		isd = (iscsiexpert_sess_display_t *)g_malloc(sizeof(iscsiexpert_sess_display_t));
+		memset(isd, 0, sizeof(iscsiexpert_sess_display_t));
+		isd->node_type = SESSION;
+		g_stpcpy(isd->tagtxt, tagtxt);
+		copy_sess_params(&isd->session_params, &iscsi_sessionset->params);
+		
+		if (iscsi_sessionset->conn_count)
+		{
+			se_tree_foreach(iscsi_sessionset->connq, get_connections_from_sessionset, (void *)isd);
+		}
+		isd->dissector_conn = NULL;
+
+		*sess_list = g_slist_append(*sess_list, isd);
+	}
+	else /*single connections*/
+	{		
+		isd = (iscsiexpert_sess_display_t *)g_malloc(sizeof(iscsiexpert_sess_display_t));
+		memset(isd, 0, sizeof(iscsiexpert_sess_display_t));
+		isd->node_type = SIG_CONNECTION;
+
+		iscsi_sessionset = (iscsiexpert_sessionset_t *) iscsisession_get_proto_data(sess, proto_iscsie);
+		if (iscsi_sessionset->conn_count)
+		{
+			se_tree_foreach(iscsi_sessionset->connq, get_connections_from_session, (void *)isd);
+		}		
+		
+		*sess_list = g_slist_append(*sess_list, isd);	
+	}
+}
+
+/*
+ * Description: initilize the tree of iscsi session topology
+ * Parameters:
+ * etd: struct which contains the pointers of all the widget and list used in expert dlg
+ * hpaned: point to a widget in which the parent window of iscsi topology treeview is placed
+ * call_func: callback for the "changed" signal
+ * func_data: the parameter fo callback function
+ */
+static void iscsiexpert_init_tree(iscsiexpert_tapdata_t *etd, 
+									 GtkWidget *hpaned,
+									 GTreeCallFunc call_func,
+									 gpointer * func_data)
+{
+
+	GtkWidget *tree_scrolled_window = etd->tree_scrolled_window;
+	GtkTreeSelection * selection = NULL;
+	GtkWidget *view = NULL;
+	GtkTreeModel *model = NULL;
+
+	GHashTable *s_hash = NULL;
+	GHashTable *c_hash = NULL;
+
+	view = tree_init(tree_scrolled_window, hpaned);
+	
+	etd->iscsiexpert_session_list = NULL;
+
+	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
+	
+	g_signal_connect(selection, "changed", G_CALLBACK(call_func), etd);
+
+	/*get the iscsi expert session list*/
+	s_hash = iscsiexpert_session_tv_info.session_hashlist;
+	c_hash = iscsiexpert_session_tv_info.conversation_hashlist;
+
+	if (s_hash == NULL && c_hash == NULL)
+	{
+		gtk_widget_show(view);
+		return;
+	}
+
+	if (s_hash)
+	{
+		g_hash_table_foreach(s_hash, (GHFunc)prepare_session_list, &etd->iscsiexpert_session_list);
+	}
+	
+
+	/*fill the view with real data*/
+	model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
+	model = fill_model(model, etd->iscsiexpert_session_list);
+	gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
+
+	g_object_set_data(G_OBJECT(tree_scrolled_window), "sess_conn_tree", view);
+	gtk_tree_view_expand_all(GTK_TREE_VIEW(view));
+
+	gtk_widget_show(view);	
+
+	
+
+	return;
+}
+
+/*
+ * Description: the toppest initialized function of iscsi topology treeview
+ * Parameter:
+ * etd: struct which contains the pointers of all the widget and list used in expert dlg
+ * hpaned: point to a widget in which the parent window of iscsi topology treeview is placed
+ */
+void
+iscsiexpert_dlg_init_tree(iscsiexpert_tapdata_t * etd, GtkWidget *hpaned)
+{
+
+	//GtkWidget * label;
+	//GtkWidget * label_box;
+
+	etd->tree_scrolled_window = scrolled_window_new(NULL, NULL);
+	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(etd->tree_scrolled_window), GTK_SHADOW_IN);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(etd->tree_scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	gtk_widget_set_size_request(etd->tree_scrolled_window, 250, 300);
+
+	iscsiexpert_init_tree(etd, hpaned,on_changed,(gpointer) etd);
+
+#if 0
+	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(etd->tree_scrolled_window), GTK_SHADOW_IN);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(etd->tree_scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+	gtk_paned_pack1(GTK_PANED(hpaned), etd->tree_scrolled_window,TRUE,TRUE);
+	gtk_widget_set_size_request(etd->tree_scrolled_window, 100, 100);
+
+	/* display label */
+	label_box = gtk_hbox_new(FALSE, 0);
+	//gtk_table_attach_defaults(GTK_TABLE(hpaned), label_box, 1, 2, 0, 1);
+	gtk_container_add(GTK_CONTAINER(etd->tree_scrolled_window), label_box);
+	gtk_widget_show(label_box);
+
+	label = gtk_label_new("This is topology tree view in analyze menu");
+	gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.0f);
+	gtk_box_pack_start(GTK_BOX(label_box), label, FALSE, FALSE, 0);
+
+	//g_signal_connect(gtk_tree_view_get_selection(GTK_SCROLLED_WINDOW(etd->tree_scrolled_window )),
+	//               "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
+
+	g_object_set_data(G_OBJECT(etd->win), "tree_scrolled_window", etd->tree_scrolled_window);
+
+	gtk_widget_show(GTK_WIDGET(label));
+
+	gtk_widget_show(GTK_WIDGET(etd->tree_scrolled_window));
+#endif
+
+	g_object_set_data(G_OBJECT(etd->win), "tree_scrolled_window", etd->tree_scrolled_window);
+
+	gtk_widget_show(GTK_WIDGET(etd->tree_scrolled_window));
+}
+
+static void free_conn(gpointer data, gpointer user_data _U_)
+{
+	g_free(data);
+}
+
+static void free_sess(gpointer data, gpointer user_data _U_)
+{
+	iscsiexpert_sess_display_t *isd = (iscsiexpert_sess_display_t *)data;
+
+	g_free(isd->session_params.target_name);
+	g_free(isd->session_params.target_alias);
+	g_free(isd->session_params.initiator_name);
+	g_free(isd->session_params.initiator_alias);
+	g_free(isd->session_params.target_addr);
+
+	g_slist_foreach(isd->con_list, free_conn, NULL);
+	g_slist_free(isd->con_list);
+	g_free(isd);
+}
+
+void
+free_iscsi_sess_list(GSList *sess_list)
+{	
+	if (sess_list)
+	{
+		g_slist_foreach(sess_list, free_sess, NULL);
+		g_slist_free(sess_list);
+	}
+}
+
+static void
+iscsiexpert_dlg_destroy_cb(GtkWindow *win _U_, gpointer data)
+{
+	iscsiexpert_tapdata_t *etd=(iscsiexpert_tapdata_t *)data;
+
+	protect_thread_critical_region();
+	remove_tap_listener(etd);
+	unprotect_thread_critical_region();
+
+	/*free_srt_table_data(&etd->afp_srt_table);*/
+	free_iscsi_sess_list(etd->iscsiexpert_session_list);
+	g_free(etd);
+	
+}
+
+
+static void
+iscsiexpert_dlg_severity_cb(GtkWidget *w, gpointer data)
+{
+	int i = GPOINTER_TO_INT(data);
+	iscsiexpert_tapdata_t * etd;
+
+
+	etd = g_object_get_data(G_OBJECT(w), "tapdata");
+
+	etd->severity_report_level = iscsiexpert_severity_om_vals[i].value;
+
+	/* "move" all events from "all" back to "new" lists */
+	protect_thread_critical_region();
+	etd->new_events = g_list_concat(etd->new_events, etd->all_events);
+	etd->all_events = NULL;
+	unprotect_thread_critical_region();
+
+	/* redraw table */
+	iscsiexpert_dlg_display_reset(etd);
+	iscsiexpert_dlg_draw(etd);
+}
+
+static void
+iscsiexpert_dlg_protocol_cb(GtkWidget *w, gpointer data)
+{
+	int i = GPOINTER_TO_INT(data);
+	iscsiexpert_tapdata_t * etd;
+
+
+	etd = g_object_get_data(G_OBJECT(w), "tapdata");
+
+	//etd->protocol_report_level = iscsiexpert_protocol_om_vals[i].value;
+
+	/* "move" all events from "all" back to "new" lists */
+	protect_thread_critical_region();
+	etd->new_events = g_list_concat(etd->new_events, etd->all_events);
+	etd->all_events = NULL;
+	unprotect_thread_critical_region();
+
+	/* redraw table */
+	iscsiexpert_dlg_display_reset(etd);
+	iscsiexpert_dlg_draw(etd);
+}
+
+void
+select_sess_item(GtkWidget *sess_treeview, GSList *iscsiexpert_session_list)
+{
+	GtkTreeModel *model = NULL;
+	GtkTreeIter iter;	
+	gboolean valid;
+	//GtkWidget *sess_treeview = NULL;
+	GtkTreeSelection *selection = NULL;
+	GtkTreePath *path = NULL;
+
+	if (g_slist_length(iscsiexpert_session_list) == 0)
+	{
+		return;
+	}
+
+	//sess_treeview = g_object_get_data(G_OBJECT(etd->tree_scrolled_window), "sess_conn_tree");
+	model = gtk_tree_view_get_model(GTK_TREE_VIEW(sess_treeview));
+	valid = gtk_tree_model_get_iter_first (model, &iter);
+
+	if (valid)
+	{	
+		path = gtk_tree_model_get_path(model, &iter);
+		gtk_tree_path_down(path);
+		
+	}
+	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(sess_treeview));
+	gtk_tree_selection_select_path(selection, path);
+	gtk_tree_path_free(path);
+	
+}
+
+static void
+iscsiexpert_dlg_init(const char *optarg, void* userdata _U_)
+{
+	iscsiexpert_tapdata_t * etd;
+	const char *filter=NULL;
+	GString *error_string;
+	GtkWidget *frame_vbox;
+	GtkWidget *hbox;
+	GtkWidget *hpaned;
+
+	GtkWidget *table;
+	GtkWidget *bbox;
+	GtkWidget *close_bt;
+	GtkWidget *help_bt;
+
+	GtkWidget *severity_box;
+	GtkWidget *severity_om;
+	GtkWidget *menu;
+	GtkWidget *menu_item;
+	GtkWidget *label;
+
+//  GtkWidget *protocol_box;
+//  GtkWidget *protocol_om;
+//  GtkWidget *proto_menu;
+//  GtkWidget *proto_menu_item;
+//  GtkWidget *proto_label;
+
+	GtkWidget * main_nb;
+	GtkWidget * packet_detail_label;
+	GtkWidget *	packet_detail_hbox;
+	GtkWidget * packet_detail_hpaned;
+
+	GtkWidget * iscsi_parameter_label;
+	GtkWidget *	iscsi_parameter_hbox;
+	GtkWidget * iscsi_parameter_hpaned;
+
+	GtkTooltips *tooltips = gtk_tooltips_new();
+	int i;
+	gint tv_size = 95;
+
+
+	if(!strncmp(optarg,"afp,srt,",8)){
+		filter=optarg+8;
+	} else {
+		filter=NULL;
+	}
+
+	proto_draw_colors_init();
+
+	etd=g_malloc(sizeof(iscsiexpert_tapdata_t));
+	etd->all_events = NULL;
+	etd->new_events = NULL;
+	etd->disp_events = 0;
+	etd->chat_events = 0;
+	etd->note_events = 0;
+	etd->warn_events = 0;
+	etd->error_events = 0;
+	etd->first_row	  = TRUE;
+	etd->severity_report_level = PI_CHAT;
+	//etd->protocol_report_level = PI_ALL;
+
+	etd->win = dlg_window_new("Wireshark: iSCSI Expert Info");  /* transient_for top_level */
+	gtk_window_set_destroy_with_parent (GTK_WINDOW(etd->win), TRUE);
+	gtk_window_set_default_size(GTK_WINDOW(etd->win), 650, 500);
+
+	/***************************   Whole Frame of Components **********************/
+	frame_vbox = gtk_vbox_new(FALSE, 5);
+	gtk_container_add(GTK_CONTAINER(etd->win), frame_vbox);
+	gtk_container_set_border_width(GTK_CONTAINER(frame_vbox), 12);
+
+	/***************************   Top Level: ComboBox and Label **********************/
+	table = gtk_table_new(1, 2, TRUE /* homogeneous */);
+	gtk_box_pack_start(GTK_BOX(frame_vbox), table, FALSE, FALSE, 0);
+
+	/* display level */
+	severity_box = gtk_hbox_new(FALSE, 0);
+	gtk_table_attach_defaults(GTK_TABLE(table), severity_box, 0, 1, 0, 1);
+
+	label=gtk_label_new("Severity filter:");
+	gtk_box_pack_start(GTK_BOX(severity_box), label, FALSE, FALSE, 0);
+
+	menu=gtk_menu_new();
+	for(i=0; iscsiexpert_severity_om_vals[i].strptr != NULL;i++){
+		menu_item=gtk_menu_item_new_with_label(iscsiexpert_severity_om_vals[i].strptr);
+		g_object_set_data(G_OBJECT(menu_item), "tapdata", etd);
+		g_signal_connect(menu_item, "activate", G_CALLBACK(iscsiexpert_dlg_severity_cb), (gpointer)(long) i);
+		gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+		if(iscsiexpert_severity_om_vals[i].value == (guint) etd->severity_report_level) {
+			gtk_menu_set_active(GTK_MENU(menu), i);
+		}
+	}
+	severity_om=gtk_option_menu_new();
+	gtk_option_menu_set_menu(GTK_OPTION_MENU(severity_om), menu);
+	gtk_box_pack_start(GTK_BOX(severity_box), severity_om, FALSE, FALSE, 0);
+
+	/* protocol select */
+//	protocol_box = gtk_hbox_new(FALSE, 0);
+//	gtk_table_attach_defaults(GTK_TABLE(table), protocol_box, 1, 2, 0, 1);
+
+//	proto_label = gtk_label_new("  Protocol filter:");
+//	gtk_box_pack_start(GTK_BOX(protocol_box), proto_label, FALSE, FALSE, 0);
+
+//  proto_menu = gtk_menu_new();
+//  for(i = 0; iscsiexpert_protocol_om_vals[i].strptr != NULL; i++){
+//  	proto_menu_item = gtk_menu_item_new_with_label(iscsiexpert_protocol_om_vals[i].strptr);
+//  	g_object_set_data(G_OBJECT(proto_menu_item), "tapdata", etd);
+//  	g_signal_connect(proto_menu_item, "activate", G_CALLBACK(iscsiexpert_dlg_protocol_cb), (gpointer)(long) i);
+//  	gtk_menu_shell_append(GTK_MENU_SHELL(proto_menu), proto_menu_item);
+//  	if(iscsiexpert_protocol_om_vals[i].value == (guint) etd->protocol_report_level) {
+//  		gtk_menu_set_active(GTK_MENU(proto_menu), i);
+//  	}
+//  }
+//  protocol_om = gtk_option_menu_new();
+//  gtk_option_menu_set_menu(GTK_OPTION_MENU(protocol_om), proto_menu);
+//  gtk_box_pack_start(GTK_BOX(protocol_box), protocol_om, FALSE, FALSE, 0);
+
+	/* display label */
+	etd->label=gtk_label_new("Please wait ...");
+	gtk_misc_set_alignment(GTK_MISC(etd->label), 0.0f, 0.0f);
+	gtk_box_pack_start(GTK_BOX(frame_vbox), etd->label, FALSE, FALSE, 0);
+
+	/***************************   Initiator-Target and Expert Result **********************/
+
+	hbox = gtk_hbox_new(FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(frame_vbox), hbox, TRUE, TRUE, 0);
+
+	hpaned = gtk_hpaned_new();
+	gtk_box_pack_start(GTK_BOX(hbox), hpaned, TRUE, TRUE, 0);
+	gtk_paned_set_position(GTK_PANED(hpaned), 150);
+
+	/* We must display TOP LEVEL Widget before calling init_srt_table() */
+	//gtk_widget_show_all(etd->win);
+
+	iscsiexpert_dlg_init_table(etd, hpaned);
+
+	error_string=register_tap_listener("iscsiexpert_analyzer", etd, NULL /* fstring */,
+		iscsiexpert_dlg_reset,
+		iscsiexpert_dlg_packet,
+		iscsiexpert_dlg_draw);
+	if(error_string){
+		simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
+		g_string_free(error_string, TRUE);
+		free_iscsi_sess_list(etd->iscsiexpert_session_list);
+		g_free(etd);
+		return;
+	}
+
+	cf_retap_packets(&cfile, FALSE);
+
+	/*session/connection topology treeview*/
+	iscsiexpert_dlg_init_tree(etd, hpaned);
+
+	/***************************   Packet Detail Panel and iSCSI Parameter Panel **********************/
+
+	main_nb = gtk_notebook_new();
+    gtk_box_pack_start(GTK_BOX(frame_vbox), main_nb, TRUE, TRUE, 0);
+
+	packet_detail_label = gtk_label_new("Packet Detail");
+    gtk_widget_show(packet_detail_label);
+
+	packet_detail_hbox = gtk_hbox_new(FALSE, 0);
+	gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), packet_detail_hbox, packet_detail_label);
+
+	packet_detail_hpaned = gtk_vpaned_new();
+	gtk_box_pack_start(GTK_BOX(packet_detail_hbox), packet_detail_hpaned, TRUE, TRUE, 0);
+	gtk_paned_set_position(GTK_PANED(packet_detail_hbox), 200);
+
+	iscsiexpert_dlg_init_treeview(etd, packet_detail_hpaned);
+
+	iscsi_parameter_label = gtk_label_new("iSCSI Parameter");
+    gtk_widget_show(iscsi_parameter_label);
+
+	iscsi_parameter_hbox = gtk_hbox_new(FALSE, 0);
+	gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), iscsi_parameter_hbox, iscsi_parameter_label);
+
+	iscsi_parameter_hpaned = gtk_vpaned_new();
+
+	gtk_box_pack_start(GTK_BOX(iscsi_parameter_hbox), iscsi_parameter_hpaned, TRUE, TRUE, 0);
+	//gtk_paned_set_position(GTK_PANED(iscsi_parameter_hpaned), 400);
+
+	iscsiexpert_dlg_init_iscsiparameter(etd, iscsi_parameter_hpaned);
+
+	/*select a session/connection*/
+	select_sess_item(g_object_get_data(G_OBJECT(etd->tree_scrolled_window), "sess_conn_tree"),
+	                 etd->iscsiexpert_session_list);
+
+	/* Button row. */
+	bbox = dlg_button_row_new(GTK_STOCK_CLOSE, GTK_STOCK_HELP, NULL);
+	gtk_box_pack_end(GTK_BOX(frame_vbox), bbox, FALSE, FALSE, 0);
+
+	close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
+	window_set_cancel_button(etd->win, close_bt, window_cancel_button_cb);
+
+	help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
+	g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)HELP_EXPERT_INFO_DIALOG);
+	gtk_tooltips_set_tip (tooltips, help_bt, "Show topic specific help", NULL);
+
+	g_signal_connect(etd->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
+	g_signal_connect(etd->win, "destroy", G_CALLBACK(iscsiexpert_dlg_destroy_cb), etd);
+
+	gtk_widget_show_all(etd->win);
+	window_present(etd->win);
+
+	/* This will bring up the progress bar
+	 * Put our window back in front
+	 */
+	gdk_window_raise(etd->win->window);
+
+}
+
+
+static void
+iscsiexpert_dlg_cb(GtkWidget *w _U_, gpointer d _U_)
+{
+	iscsiexpert_dlg_init("", NULL);
+}
+
+/*For session/conversation treeview*/
+void iscsiexpert_session_tv_reset(void *tapdata)
+{
+	
+	return;
+}
+
+int iscsiexpert_session_tv_packet(void *tapdata,
+								  packet_info *pinfo _U_,
+								  epan_dissect_t *edt _U_,
+								  const void *data)
+{
+	iscsiexpert_sess_tv_t	*stv = (iscsiexpert_sess_tv_t *)data;
+    //iscsiexpert_sess_tv_t	*stv = se_memdup(data,sizeof(iscsiexpert_sess_tv_t));
+
+	GHashTable *s_hash = stv->session_hashlist;
+	GHashTable *c_hash = stv->conversation_hashlist;
+
+	iscsiexpert_session_tv_info.session_hashlist = s_hash;
+	iscsiexpert_session_tv_info.conversation_hashlist = c_hash;
+	iscsiexpert_session_tv_info.proto_iscsiexpert = stv->proto_iscsiexpert;
+    iscsiexpert_session_tv_info.current_proto = se_strdup(stv->current_proto);
+    
+	proto_iscsie = stv->proto_iscsiexpert;
+
+					
+
+	return 0;
+}
+
+
+
+void iscsiexpert_session_tv_draw(void *tapdata)
+{
+	if (iscsiexpert_session_tv_info.session_hashlist == NULL)
+		return;
+
+	
+	return;
+}
+
+
+void
+register_tap_listener_iscsiexpert(void)
+{
+	register_stat_cmd_arg("expert", iscsiexpert_dlg_init,NULL);
+
+	register_stat_menu_item("_iSCSI Expert", REGISTER_ANALYZE_GROUP_UNSORTED,
+        iscsiexpert_dlg_cb, NULL, NULL, NULL);
+}
+
+/*
+ * Description: used for tap session hash table from epan iscsiexpert
+ */
+void
+register_tap_listener_iscsiexpert_session_tv(void)
+{
+	GString *err_p;
+
+	memset((void *)&iscsiexpert_session_tv_info, 0, sizeof(iscsiexpert_sess_tv_t));
+	
+	err_p = register_tap_listener("iscsiexpert_session_tv",
+		                          &iscsiexpert_session_tv_info,
+		                          NULL,
+		                          iscsiexpert_session_tv_reset,
+		                          iscsiexpert_session_tv_packet,
+		                          iscsiexpert_session_tv_draw);
+	
+	cf_retap_packets(&cfile, TRUE);
+
+	if(err_p != NULL)
+	{
+		simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_p->str);	
+		g_string_free(err_p, TRUE);		
+	}
+}
+
+
diff -urN wireshark-1.2.2/gtk/iscsiexpert_stat.c wireshark-1.2.2-iscsie/gtk/iscsiexpert_stat.c
--- wireshark-1.2.2/gtk/iscsiexpert_stat.c	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/gtk/iscsiexpert_stat.c	2010-01-20 15:17:11.000000000 +0800
@@ -0,0 +1,3187 @@
+/* iscsiexpert_stat.c
+ * $Id: iscsiexpert_stat.c 29099 2009-07-15 00:10:08Z gerald $
+ * Allows to display a flow graph of the currently displayed packets
+ *
+ * Copyright 2009, Ji-dong Wang <Wang.ji-dong@xxxxxxxxxxxxxx>
+ * 				   Qian Zhang <Zhang.qian@xxxxxxxxxxxxxx>
+ * 				   Ying-chao Yang <Yang.ying-chao@xxxxxxxxxxxxxx>
+ * 				   Cang-mou Cao	<Cao.cang-mou@xxxxxxxxxxxxxx>
+ * 				   Xing-jia	Wang <Wang.xing-jia@xxxxxxxxxxxxxx>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ * 
+ * Copied from flow_graph.c
+ * 
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <string.h>
+#include <math.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <glib/gprintf.h>
+
+#include <epan/epan.h>
+#include <epan/packet.h>
+#include <epan/filesystem.h>
+#include <epan/stat_cmd_args.h>
+#include <epan/to_str.h>
+#include <epan/tap.h>
+#include <epan/epan_dissect.h>
+#include <epan/strutil.h>
+#include <epan/addr_resolv.h>
+#include <epan/prefs.h>
+
+#include "../register.h"
+#include "../globals.h"
+#include "../stat_menu.h"
+#include "../simple_dialog.h"
+#include "../color.h"
+#include "../ui_util.h"
+
+#include "../epan/dissectors/packet-iscsiexpert.h"
+#include "gtk/gui_stat_menu.h"
+#include "gtk/dlg_utils.h"
+#include "gtk/gui_utils.h"
+#include "gtk/stock_icons.h"
+#include "gtk/gtkglobals.h"
+#include "gtk/main.h"
+
+#include "gtk/main_proto_draw.h"
+
+
+
+#include "gtk/filter_dlg.h"
+#include "../alert_box.h"
+#include "gtk/filter_dlg.h"
+#include "gtk/filter_autocomplete.h"
+#include "gtk/pixmap_save.h"
+#include "gtk/help_dlg.h"
+
+#include "image/iscsi_login_c0.xpm"
+#include "image/iscsi_login_c1.xpm"
+#include "image/iscsi_login_c3.xpm"
+
+#include "image/iscsi_login_rsp_n0.xpm"
+#include "image/iscsi_login_rsp_n1.xpm"
+#include "image/iscsi_login_rsp_n3.xpm"
+
+#include "image/iscsi_nop_out.xpm"
+#include "image/iscsi_nop_in.xpm"
+#include "image/iscsi_asyncmsg.xpm"
+#include "image/iscsi_reject.xpm"
+#include "image/iscsi_text_request.xpm"
+#include "image/iscsi_text_response.xpm"
+#include "image/iscsi_r2t.xpm"
+#include "image/iscsi_ivs.xpm"
+#include "image/iscsi_tvs.xpm"
+#include "image/iscsi_snack.xpm"
+#include "image/iscsi_tmf_rq.xpm"
+#include "image/iscsi_tmf_rsp.xpm"
+#include "image/iscsi_scsi_cmd.xpm"
+#include "image/iscsi_scsi_rsp.xpm"
+#include "image/iscsi_scsi_datain.xpm"
+#include "image/iscsi_scsi_dataout.xpm"
+#include "image/iscsi_logout_rq.xpm"
+#include "image/iscsi_logout_rsp.xpm"
+
+#include "image/iscsi_error.xpm"
+#include "image/iscsi_warn.xpm"
+
+#include "image/iscsi_toarrow.xpm"
+#include "image/iscsi_fromarrow.xpm"
+
+/* defines an entry in for the graph analysis */
+typedef struct _isciexpert_graph_analysis_item {
+	guint32 frame_num;			/* frame number used to "go to" that frame */
+	double time;				/* frame time */
+	address src_addr;
+	guint16 port_src;
+	address dst_addr;
+	guint16 port_dst;
+	gchar *frame_label;			/* the label on top of the arrow */
+	gchar *comment;				/* a comment that appears at the left of the graph */
+	guint16 conv_num;			/* the conversation number, each conversation will be colored */
+	gboolean display;			/* indicate if the packet is displayed or not in the graph */
+	guint16 line_style;			/* the arrow line width in pixels*/
+	guint8	opcode;
+	gboolean direction;
+	int 		group;
+	int 		severity;
+	gchar 	* 	summary;
+	iscsiexpert_session_t * conn;
+} iscsiexpert_graph_analysis_item_t;
+
+/* defines an entry in for the statitics information */
+typedef struct _isciexpert_statitics_info_item {
+	nstime_t 	scsi_end_time;		//record the scsi end time
+	iscsiexpert_session_t * conn;
+} iscsiexpert_statitics_info_item_t;
+
+/* defines the graph analysis structure */
+typedef struct _iscsiexpert_graph_analysis_info {
+	int     nconv;       /* number of conversations in the list */
+	GList*  list;   /* list with the graph analysis items */
+} iscsiexpert_graph_analysis_info_t;
+
+/* defines the statitics information structure */
+typedef struct _iscsiexpert_statitics_info {
+	int     nconv;       /* number of conversations in the list */
+	GList*  list;   	/* list with the statitics info items */
+} iscsiexpert_statitics_info_t;
+
+/* max number of nodes to display, each node will be an IP address */
+#define MAX_NUM_COL_CONV 10
+#define NODE_OVERFLOW MAX_NUM_NODES+1
+#define NUM_DISPLAY_ITEMS 1000
+
+typedef struct _display_items {
+	guint32 frame_num;			/* frame number used to "go to" that frame */
+	double time;				/* frame time */
+	guint16 port_src;
+	guint16 port_dst;
+	gchar *frame_label;			/* the label on top of the arrow */
+	gchar *comment;				/* a comment that appears at the left of the graph */
+	guint16 conv_num;			/* the conversation number, each conversation will be colored */
+	guint16 line_style;			/* the arrow line width in pixels*/
+	address src_addr;
+	address dst_addr;
+	guint8	opcode;
+	gboolean direction;
+	int 		group;
+	int 		severity;
+	gchar 	* 	summary;
+	iscsiexpert_session_t * conn;
+} display_items_t;
+
+typedef struct _dialog_data_t {
+	GtkWidget *window;
+	GtkWidget *parent_w;
+	gboolean needs_redraw;
+	gboolean inverse;          /* set the nodes in reverse mode as "dst <---- src" instead of "src ----> dst"*/
+	gint selected_row;
+	GtkWidget *draw_area_framenum;
+    GtkWidget *draw_area_time;
+	GtkWidget *draw_area_icon;
+	GtkWidget *draw_area_initiator;
+	GtkWidget *draw_area_operation;
+	GtkWidget *draw_area_target;
+	GtkWidget *draw_area_comments;
+
+    GdkPixmap *pixmap_framenum;
+    GdkPixmap *pixmap_time;
+	GdkPixmap *pixmap_icon;
+	GdkPixmap *pixmap_initiator;
+	GdkPixmap *pixmap_operation;
+	GdkPixmap *pixmap_target;
+    GdkPixmap *pixmap_comments;
+
+	GtkWidget *v_scrollbar;
+	GtkAdjustment *v_scrollbar_adjustment;
+	GtkWidget *hpane;
+	GdkGC *bg_gc[MAX_NUM_COL_CONV+1];
+	GdkGC *bg_expert_gc[4];
+    int pixmap_width;
+    int pixmap_height;
+	guint16 first_node;			/* the first node on the left to show in the screen */
+	guint32	first_item;			/* the first item (row) to show from the top */
+	guint32	selected_item;		/* the selected item */
+	guint32	mouse_move_item;		/* the selected item */
+	display_items_t items[NUM_DISPLAY_ITEMS];
+    guint32 left_x_border;
+} dialog_data_t;
+
+typedef struct _statinfo_dialog_data_t {
+	GtkWidget *window;
+	GtkWidget *parent_w;
+	gboolean needs_redraw;
+
+	GtkWidget  *iscsi_parameter_list;
+} statinfo_dialog_data_t;
+
+
+typedef void (*destroy_user_data_cb)(void *data);
+
+typedef struct iscsiexpert_stat_data_s {
+	GtkWidget	*	win;
+	GtkWidget	*	stat_notebook_window;
+	
+	GtkWidget	*	tree_scrolled_window;
+	GtkWidget	*	treeview_window;
+	GtkWidget   * 	iscsi_parameter_window;
+
+	GSList *iscsiexpert_session_list;
+	
+} iscsiexpert_stat_data_t;
+
+/* structure that holds general information and the dialog */
+typedef struct _iscsiexpert_graph_analysis_data_t {
+	/* graphic data */
+	iscsiexpert_graph_analysis_info_t *graph_info;
+
+	/* dialog associated data */
+	dialog_data_t dlg;
+	guint32 num_items;
+	void *data; /* data to be passes when on destroy */
+
+	iscsiexpert_stat_data_t *etd;
+	gboolean	first_row;
+} iscsiexpert_graph_analysis_data_t;
+
+/* structure that holds general information and the dialog */
+typedef struct _iscsiexpert_statitics_info_data_t {
+	/* graphic data */
+	iscsiexpert_statitics_info_t *stat_info;
+
+	/* dialog associated data */
+	statinfo_dialog_data_t dlg;
+	guint32 num_items;
+	//void *data; /* data to be passes when on destroy */
+} iscsiexpert_statitics_info_data_t;
+
+static iscsiexpert_graph_analysis_info_t *graph_analysis 		= NULL;
+//static iscsiexpert_graph_analysis_data_t *graph_analysis_data	= NULL;
+
+static iscsiexpert_statitics_info_t 	 *statitics_info 		= NULL;
+//static iscsiexpert_statitics_info_data_t *statitics_info_data	= NULL;
+
+typedef struct _statui_data_combo_s{
+	iscsiexpert_graph_analysis_data_t *graph_analysis_data;
+	iscsiexpert_statitics_info_data_t *statitics_info_data;
+}statui_data_combo_t;
+
+static statui_data_combo_t		statui_data_combo;
+
+/* Data structure holding information about a packet-detail window. */
+struct PacketWinData {
+	frame_data *frame;	   /* The frame being displayed */
+	union wtap_pseudo_header pseudo_header; /* Pseudo-header for packet */
+	guint8     *pd;		   /* Data for packet */
+	GtkWidget  *main;
+	GtkWidget  *tv_scrollw;
+	GtkWidget  *tree_view;
+	GtkWidget  *bv_nb_ptr;
+ 	field_info *finfo_selected;
+	epan_dissect_t	*edt;
+};
+
+/* List of all the packet-detail windows popped up. */
+static GList *detail_windows;
+static struct PacketWinData *DataPtr;
+
+typedef struct __iscsi_pixmap{
+	GdkPixmap * pixmap;
+	const char ** pixmap_name;
+}iscsi_pixmap_t;
+
+static iscsi_pixmap_t iscsiexpert_icons[] = {
+	{NULL,iscsi_login_c0_xpm},
+	{NULL,iscsi_login_c1_xpm},
+	{NULL,iscsi_login_c3_xpm},
+	{NULL,iscsi_login_rsp_n0_xpm},
+	{NULL,iscsi_login_rsp_n1_xpm},
+	{NULL,iscsi_login_rsp_n3_xpm},
+
+	{NULL,iscsi_scsi_cmd_xpm},
+	{NULL,iscsi_scsi_rsp_xpm},
+
+	{NULL,iscsi_scsi_datain_xpm},
+	{NULL,iscsi_scsi_dataout_xpm},
+
+	{NULL,iscsi_tmf_rq_xpm},
+	{NULL,iscsi_tmf_rsp_xpm},
+
+	{NULL,iscsi_nop_out_xpm},
+	{NULL,iscsi_nop_in_xpm},
+
+	{NULL,iscsi_asyncmsg_xpm},
+	{NULL,iscsi_reject_xpm},
+	{NULL,iscsi_r2t_xpm},
+
+	{NULL,iscsi_text_request_xpm},
+	{NULL,iscsi_text_response_xpm},
+	
+	{NULL,iscsi_ivs_xpm},
+	{NULL,iscsi_tvs_xpm},
+	
+	{NULL,iscsi_snack_xpm},
+
+	{NULL,iscsi_logout_rq_xpm},
+	{NULL,iscsi_logout_rsp_xpm},
+	{NULL,iscsi_warn_xpm},
+	{NULL,iscsi_error_xpm},
+	{NULL,NULL}
+};
+
+
+static iscsi_pixmap_t iscsiexpert_direction_icons[] = {
+	{NULL,iscsi_fromarrow_xpm},
+	{NULL,iscsi_toarrow_xpm},
+	{NULL,NULL}
+};
+
+#define MAX_LABEL 50
+#define MAX_TOOLTIP		30
+#define MAX_INITIATOR	50
+#define MAX_COMMENT 100
+#define ITEM_HEIGHT 20
+#define TOP_Y_BORDER 40
+#define BOTTOM_Y_BORDER 10
+#define COMMENT_WIDTH 	400
+#define	FRAMENUM_WIDTH	30
+#define TIME_WIDTH 50
+#define	INITIATOR_WIDTH  130
+#define	ICON_WIDTH  	 30
+#define TARGET_WIDTH     130
+#define OPERATION_WIDTH	 30
+
+extern GtkWidget *iscsi_topology_init(void);
+extern GtkTreeModel *fill_model(GtkTreeModel *model, GSList *sess_list);
+extern GtkWidget *tree_init(GtkWidget *tree_scrolled_window, GtkWidget *hpaned);
+extern gboolean iscsiexpert_init_parameter(GtkWidget *iscsi_parameter_window, GtkWidget *hpaned);
+extern void prepare_session_list (gpointer key, gpointer value _U_, gpointer user_data);
+extern void display_params(GtkTreeSelection *selection, GtkWidget *iscsi_params_window, GSList *sess_list);
+extern iscsiexpert_sess_tv_t iscsiexpert_session_tv_info;
+extern void select_sess_item(GtkWidget *sess_treeview, GSList *iscsiexpert_session_list);
+extern void display_param_in_list(GtkWidget *parameter_list, const gchar *key, const gchar *value, guint32 from);
+
+typedef void (*GTreeCallFunc)(GtkTreeSelection *selection, gpointer data);
+
+void iscsiexpert_dialog_graph_redraw(iscsiexpert_graph_analysis_data_t* user_data);
+void iscsiexpert_statitics_info_redraw(iscsiexpert_statitics_info_data_t* statinfo_data);
+
+
+static void
+on_changed(GtkTreeSelection *selection, gpointer data)
+{
+	GtkTreeView *treeview;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+
+	statui_data_combo_t * statui_data = (statui_data_combo_t*)data;
+
+	iscsiexpert_graph_analysis_data_t* user_data= statui_data->graph_analysis_data;
+	iscsiexpert_statitics_info_data_t *statitics_info_data	= statui_data->statitics_info_data;
+
+	iscsiexpert_stat_data_t *etd = user_data->etd;
+	GtkWidget *iscsi_params_window = etd->iscsi_parameter_window;
+
+	/*display the parameter*/
+	display_params(selection, iscsi_params_window, etd->iscsiexpert_session_list);
+
+	treeview = gtk_tree_selection_get_tree_view (selection);
+
+	if (gtk_tree_selection_get_selected(selection, &model, &iter))
+	{
+		//gtk_tree_model_get(model, &iter, COLUMN, &value, -1);
+
+		//simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,"The item is selected.");
+
+		iscsiexpert_dialog_graph_redraw(user_data);
+		iscsiexpert_statitics_info_redraw(statitics_info_data);
+		
+		return;
+	}
+}
+
+/****************************************************************************/
+/* Reset the user_data structure */
+static void iscsiexpert_graph_analysis_reset(iscsiexpert_graph_analysis_data_t* user_data)
+{
+	user_data->num_items = 0;
+
+	user_data->dlg.first_node=0;
+	user_data->dlg.first_item=0;
+	user_data->dlg.left_x_border=0;
+	user_data->dlg.selected_item=0xFFFFFFFF;    /*not item selected */
+	user_data->dlg.mouse_move_item=0xFFFFFFFF;
+
+}
+
+/****************************************************************************/
+/* Reset the user_data structure */
+static void iscsiexpert_statitics_info_reset(iscsiexpert_statitics_info_data_t* statinfo_data)
+{
+	statinfo_data->num_items = 0;
+}
+
+/****************************************************************************/
+/* Reset the user_data structure */
+static void iscsiexpert_graph_analysis_init_dlg(iscsiexpert_graph_analysis_data_t* user_data)
+{
+	user_data->num_items = 0;
+	user_data->data = NULL;
+
+	user_data->dlg.first_node=0;
+	user_data->dlg.first_item=0;
+	user_data->dlg.left_x_border=0;
+	user_data->dlg.selected_item=0xFFFFFFFF;    /*not item selected */
+	user_data->dlg.mouse_move_item=0xFFFFFFFF;
+	/* init dialog_graph */
+	user_data->dlg.needs_redraw=TRUE;
+	user_data->dlg.draw_area_framenum=NULL;
+	user_data->dlg.draw_area_time=NULL;
+	user_data->dlg.draw_area_icon = NULL;
+	user_data->dlg.draw_area_initiator = NULL;
+	user_data->dlg.draw_area_operation = NULL;
+	user_data->dlg.draw_area_target = NULL;
+	user_data->dlg.draw_area_comments=NULL;
+
+	user_data->dlg.pixmap_framenum=NULL;
+	user_data->dlg.pixmap_time=NULL;
+	user_data->dlg.pixmap_icon = NULL;
+	user_data->dlg.pixmap_initiator = NULL;
+	user_data->dlg.pixmap_operation = NULL;
+	user_data->dlg.pixmap_target = NULL;
+	user_data->dlg.pixmap_comments=NULL;
+
+	user_data->dlg.v_scrollbar=NULL;
+	user_data->dlg.v_scrollbar_adjustment=NULL;
+	user_data->dlg.hpane=NULL;
+	user_data->dlg.pixmap_width = 350;
+	user_data->dlg.pixmap_height=400;
+	user_data->dlg.first_node=0;
+	user_data->dlg.first_item=0;
+	user_data->dlg.left_x_border=0;
+	user_data->dlg.selected_item=0xFFFFFFFF;    /*not item selected */
+	user_data->dlg.mouse_move_item=0xFFFFFFFF;    /*not item selected */
+	user_data->dlg.window=NULL;
+	user_data->dlg.parent_w=NULL;
+	user_data->dlg.inverse = FALSE;
+	//user_data->dlg.title=NULL;
+
+	user_data->first_row = TRUE;
+}
+
+/****************************************************************************/
+/* free up memory and initialize the pointers */
+
+static void iscsiexpert_stat_reset(void *ptr _U_)
+{
+	iscsiexpert_graph_analysis_item_t *graph_item;
+	iscsiexpert_statitics_info_item_t *statinfo_item;
+
+	GList* list;
+
+	if (graph_analysis !=NULL){
+
+		/* free the graph data items */
+		list = g_list_first(graph_analysis->list);
+		while (list)
+		{
+			graph_item = list->data;
+			g_free(graph_item->frame_label);
+			g_free(graph_item->comment);
+			g_free(list->data);
+			list = g_list_next(list);
+		}
+		g_list_free(graph_analysis->list);
+		graph_analysis->nconv = 0;
+		graph_analysis->list = NULL;
+	}
+
+	if (statitics_info !=NULL){
+
+		/* free the graph data items */
+		list = g_list_first(statitics_info->list);
+		while (list)
+		{
+			statinfo_item = list->data;
+			g_free(list->data);
+			list = g_list_next(list);
+		}
+		g_list_free(statitics_info->list);
+		statitics_info->nconv = 0;
+		statitics_info->list = NULL;
+	}
+	return;
+}
+
+/****************************************************************************/
+static void iscsiexpert_stat_data_init() {
+	graph_analysis = g_malloc(sizeof(iscsiexpert_graph_analysis_info_t));
+	graph_analysis->nconv = 0;
+	graph_analysis->list = NULL;
+
+	statitics_info = g_malloc(sizeof(iscsiexpert_statitics_info_t));
+	statitics_info->nconv = 0;
+	statitics_info->list = NULL;
+
+	return;
+}
+
+
+
+/****************************************************************************/
+static void
+remove_tap_listener_iscsiexpert_stat( iscsiexpert_graph_analysis_data_t* user_data)
+{
+	protect_thread_critical_region();
+	remove_tap_listener(user_data);
+	unprotect_thread_critical_region();
+}
+
+static void iscsiexpert_userdata_init(GdkDrawable * drawable, iscsiexpert_graph_analysis_data_t* user_data)
+{
+	gint32 i;
+
+	/* the first color is blue to highlight the selected item */
+	static GdkColor col[MAX_NUM_COL_CONV+1] = {
+		{0,     0xCC00, 0xCC00, 0xE000},
+		{0,     0x33FF, 0xFFFF, 0x33FF},
+		{0,     0x00FF, 0xCCFF, 0xCCFF},
+		{0,     0x66FF, 0xFFFF, 0xFFFF},
+		{0,     0x99FF, 0x66FF, 0xFFFF},
+		{0,     0xFFFF, 0xFFFF, 0x33FF},
+		{0,     0xCCFF, 0x99FF, 0xFFFF},
+		{0,     0xCCFF, 0xFFFF, 0x33FF},
+		{0,     0xFFFF, 0xCCFF, 0xCCFF},
+		{0,     0xFFFF, 0x99FF, 0x66FF},
+		{0,     0xFFFF, 0xFFFF, 0x99FF}
+	};
+
+	static GdkColor color_expert_line[4] = {
+		{0, 0xcc00, 0xcc00, 0xe000},
+		{0, 0xa000, 0xff00, 0xff00},
+		{0, 0xff00, 0xff00, 0},
+		{0, 0xff00, 0x5c00, 0x5c00}
+	};
+
+
+	/* create gcs for the background items */
+	for (i=0; i<MAX_NUM_COL_CONV+1; i++){
+		user_data->dlg.bg_gc[i]=gdk_gc_new(drawable);
+		gdk_gc_set_rgb_fg_color(user_data->dlg.bg_gc[i], &col[i]);
+	}
+
+	/* create gcs for the expert background items */
+	for (i=0; i<4; i++){
+		user_data->dlg.bg_expert_gc[i]=gdk_gc_new(drawable);
+		gdk_gc_set_rgb_fg_color(user_data->dlg.bg_expert_gc[i], &color_expert_line[i]);
+	}
+
+}
+
+static void iscsiexpert_icon_init(GtkWidget	*	win)
+{
+	GtkStyle    *style;
+	GdkColormap *cmap;
+	gint32 i;
+	
+	style = gtk_widget_get_style(win);
+	cmap  = gdk_colormap_get_system();
+
+	for (i = 0; iscsiexpert_icons[i].pixmap_name != NULL; i++) {
+		iscsiexpert_icons[i].pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, cmap,  NULL,
+											&style->bg[GTK_STATE_NORMAL], (gchar **)iscsiexpert_icons[i].pixmap_name);
+	}
+
+	for (i = 0; iscsiexpert_direction_icons[i].pixmap_name != NULL; i++) {
+		iscsiexpert_direction_icons[i].pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, cmap,  NULL,
+											&style->bg[GTK_STATE_NORMAL], (gchar **)iscsiexpert_direction_icons[i].pixmap_name);
+	}
+
+}
+
+
+/****************************************************************************/
+/* CALLBACKS                                                                */
+/****************************************************************************/
+static void
+iscsiexpert_stat_on_destroy(GtkObject *object _U_, gpointer data)
+{
+	iscsiexpert_graph_analysis_data_t * user_data = (iscsiexpert_graph_analysis_data_t *) data;
+
+	/* remove_tap_listeners */
+	remove_tap_listener_iscsiexpert_stat(user_data);
+
+	/* Clean up memory used by tap */
+	iscsiexpert_stat_reset(NULL);
+}
+
+static gboolean iscsiexpert_display_expertinfo( int severity)
+{
+	if ((severity != 0) &&
+		(severity != PI_CHAT)) {
+		return TRUE;
+	}
+	return FALSE;
+}
+
+
+static void
+iscsi_cf_select_packet(capture_file *cf, int row)
+{
+  frame_data *fdata;
+  int err;
+  gchar *err_info;
+
+  /* Get the frame data struct pointer for this frame */
+  fdata = (frame_data *)packet_list_get_row_data(row);
+
+  if (fdata == NULL) {
+    /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
+       the first entry is added to it by "real_insert_row()", that row
+       is selected (see "real_insert_row()", in "gtk/gtkclist.c", in both
+       our version and the vanilla GTK+ version).
+
+       This means that a "select-row" signal is emitted; this causes
+       "packet_list_select_cb()" to be called, which causes "cf_select_packet()"
+       to be called.
+
+       "cf_select_packet()" fetches, above, the data associated with the
+       row that was selected; however, as "gtk_clist_append()", which
+       called "real_insert_row()", hasn't yet returned, we haven't yet
+       associated any data with that row, so we get back a null pointer.
+
+       We can't assume that there's only one frame in the frame list,
+       either, as we may be filtering the display.
+
+       We therefore assume that, if "row" is 0, i.e. the first row
+       is being selected, and "cf->first_displayed" equals
+       "cf->last_displayed", i.e. there's only one frame being
+       displayed, that frame is the frame we want.
+
+       This means we have to set "cf->first_displayed" and
+       "cf->last_displayed" before adding the row to the
+       GtkCList; see the comment in "add_packet_to_packet_list()". */
+
+       if (row == 0 && cf->first_displayed == cf->last_displayed)
+         fdata = cf->first_displayed;
+  }
+
+  /* If fdata _still_ isn't set simply give up. */
+  if (fdata == NULL) {
+    return;
+  }
+
+  /* Get the data in that frame. */
+  if (!wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
+  		       cf->pd, fdata->cap_len, &err, &err_info)) {
+    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+		  cf_read_error_message(err, err_info), cf->filename);
+    return;
+  }
+
+  /* Record that this frame is the current frame. */
+  cf->current_frame = fdata;
+  cf->current_row = row;
+
+  ///* Create the logical protocol tree. */
+  //if (cf->edt != NULL) {
+  //  epan_dissect_free(cf->edt);
+  //  cf->edt = NULL;
+  //}
+  ///* We don't need the columns here. */
+  //cf->edt = epan_dissect_new(TRUE, TRUE);
+
+  //epan_dissect_run(cf->edt, &cf->pseudo_header, cf->pd, cf->current_frame,
+  //        NULL);
+
+  //dfilter_macro_build_ftv_cache(cf->edt->tree);
+
+  //cf_callback_invoke(cf_cb_packet_selected, cf);
+}
+
+
+static gboolean
+iscsi_cf_goto_frame(capture_file *cf, guint fnumber)
+{
+  frame_data *fdata;
+  int row;
+
+  for (fdata = cf->plist; fdata != NULL && fdata->num < fnumber; fdata = fdata->next)
+    ;
+
+  if (fdata == NULL) {
+    /* we didn't find a packet with that packet number */
+    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+	 	  "There is no packet with the packet number %u.", fnumber);
+    return FALSE;	/* we failed to go to that packet */
+  }
+  if (!fdata->flags.passed_dfilter) {
+    /* that packet currently isn't displayed */
+    /* XXX - add it to the set of displayed packets? */
+    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+		  "The packet number %u isn't currently being displayed.", fnumber);
+    return FALSE;	/* we failed to go to that packet */
+  }
+
+  /* We found that packet, and it's currently being displayed.
+     Find what row it's in. */
+  row = packet_list_find_row_from_data(fdata);
+  g_assert(row != -1);
+
+  /* Select that row, make it the focus row, and make it visible. */
+  //packet_list_set_selected_row(row);
+
+  iscsi_cf_select_packet(&cfile, row);
+
+  return TRUE;	/* we got to that packet */
+}
+
+/****************************************************************************/
+/* Add a new frame into the graph */
+static int iscsiexpert_stat_iscsi_add_to_graph(packet_info *pinfo,iscsiexpert_tapdata_info_t * iti,iscsiexpert_graph_analysis_data_t * user_data)
+{
+	iscsiexpert_graph_analysis_item_t *gai;
+	int i;
+	gchar *protocol;
+	gchar *colinfo;
+	gchar *frame_label;
+
+	protocol=NULL;
+	colinfo=NULL;
+
+	if (pinfo->net_src.type!=AT_NONE && pinfo->net_dst.type!=AT_NONE) {
+		gai = g_malloc(sizeof(iscsiexpert_graph_analysis_item_t));
+		COPY_ADDRESS(&(gai->src_addr),&(pinfo->net_src));
+		COPY_ADDRESS(&(gai->dst_addr),&(pinfo->net_dst));
+	}
+	else return 0;
+
+
+	gai->frame_num = pinfo->fd->num;
+	gai->time= nstime_to_sec(&pinfo->fd->rel_ts);
+
+	gai->port_src=pinfo->srcport;
+	gai->port_dst=pinfo->destport;
+
+	gai->comment=NULL;
+	gai->frame_label=NULL;
+
+	gai->conn=(iscsiexpert_session_t *)iti->conn;
+
+	/* this code doesn't make sense.
+	g_free(gai->comment); 
+	g_free(gai->frame_label); 
+	*/
+
+	if(pinfo->cinfo) {
+		if (pinfo->cinfo->col_first[COL_INFO]>=0){
+
+			for (i = pinfo->cinfo->col_first[COL_INFO]; i <= pinfo->cinfo->col_last[COL_INFO]; i++) {
+				if (pinfo->cinfo->fmt_matx[i][COL_INFO]) {
+					colinfo = g_strdup(pinfo->cinfo->col_data[i]);
+					/* break; ? or g_free(colinfo); before g_strdup() */
+				}
+			}
+		}
+
+		if (pinfo->cinfo->col_first[COL_PROTOCOL]>=0){
+
+			for (i = pinfo->cinfo->col_first[COL_PROTOCOL]; i <= pinfo->cinfo->col_last[COL_PROTOCOL]; i++) {
+				if (pinfo->cinfo->fmt_matx[i][COL_PROTOCOL]) {
+					protocol = g_strdup(pinfo->cinfo->col_data[i]);
+					/* break; ? or g_free(protocol); before g_strdup() */
+				}
+			}
+		}
+	}
+
+	if (colinfo != NULL) {
+		if (protocol != NULL) {
+			frame_label = g_strdup_printf("%.19s", colinfo);
+			gai->comment = g_strdup_printf("%s: %s", protocol, colinfo);
+		} else {
+			frame_label = g_strdup_printf("%.19s", colinfo);
+			gai->comment = g_strdup_printf("%s", colinfo);
+		}
+	} else {
+		/* This will probably never happen...*/
+		if (protocol != NULL) {
+			frame_label = g_strdup_printf("%.19s", protocol);
+			gai->comment = g_strdup_printf("%s", protocol);
+		}
+	}
+
+	g_free(protocol);
+	g_free(colinfo);
+
+	gai->line_style = 1;
+
+	gai->conv_num	= iti->sess_index;
+	gai->display	= TRUE;
+
+	gai->opcode     = iti->opcode;
+	gai->direction	= iti->direction;
+	gai->group		= iti->group;
+	gai->severity	= iti->severity;
+	gai->summary	= g_strdup_printf("%s",iti->summary);
+
+	user_data->num_items++;
+
+	if (TRUE == iscsiexpert_display_expertinfo(gai->severity)) {
+		gai->frame_label = g_strdup_printf("%s",gai->summary);
+	}
+	else{
+		gai->frame_label = g_strdup_printf("%s",frame_label);
+	}
+
+	g_free(frame_label);
+
+	graph_analysis->list = g_list_append(graph_analysis->list, gai);
+
+	if (user_data->first_row == TRUE){
+			/* display the first row*/
+			iscsi_cf_goto_frame(&cfile, gai->frame_num);
+			user_data->first_row = FALSE;
+	}
+
+	return 1;
+
+}
+
+static gint  iscsiexpert_is_same_connection(gconstpointer a,
+                                       gconstpointer b){
+	iscsiexpert_statitics_info_item_t *sii_a = (iscsiexpert_statitics_info_item_t *) a;
+	iscsiexpert_session_t *conn_b = (iscsiexpert_session_t *) b;
+
+	if (sii_a->conn->conn_index == conn_b->conn_index) {
+		return 0;
+	}
+	return -1;
+}
+
+/****************************************************************************/
+/* Add a new frame into the graph */
+static int iscsiexpert_stat_iscsi_add_to_statlist(packet_info *pinfo,iscsiexpert_tapdata_info_t * iti)
+{
+	GList		* list;
+	iscsiexpert_statitics_info_item_t *sii;
+
+	if (pinfo->net_src.type!=AT_NONE && pinfo->net_dst.type!=AT_NONE) {
+		if (list = g_list_find_custom(statitics_info->list,iti->conn,iscsiexpert_is_same_connection)){
+			sii = list->data;
+			sii->scsi_end_time.nsecs= pinfo->fd->rel_ts.nsecs;
+			sii->scsi_end_time.secs= pinfo->fd->rel_ts.secs;
+		}else{
+			sii = g_malloc(sizeof(iscsiexpert_statitics_info_item_t));
+			sii->scsi_end_time.nsecs= pinfo->fd->rel_ts.nsecs;
+			sii->scsi_end_time.secs= pinfo->fd->rel_ts.secs;
+			sii->conn=(iscsiexpert_session_t *)iti->conn;
+			statitics_info->list = g_list_append(statitics_info->list, sii);
+		}
+
+		return 1;
+	}else{
+		return 0;
+	}
+}
+
+/****************************************************************************/
+/* whenever a iscsi packet is seen by the tap listener */
+static int
+iscsiexpert_stat_iscsi_packet( void * tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pointer)
+{
+	iscsiexpert_tapdata_info_t	*iti = se_memdup(pointer,sizeof(iscsiexpert_tapdata_info_t));
+	iscsiexpert_graph_analysis_data_t * user_data = tapdata;
+
+	if (pinfo->fd->flags.passed_dfilter==1){
+		iscsiexpert_stat_iscsi_add_to_graph(pinfo,iti,user_data);
+		iscsiexpert_stat_iscsi_add_to_statlist(pinfo,iti);
+	}
+
+	return 1;
+}
+
+static void iscsiexpert_stat_packet_draw(void *prs _U_)
+{
+	return;
+}
+
+/****************************************************************************/
+/* close the dialog window */
+static void on_destroy(GtkWidget *win _U_, iscsiexpert_graph_analysis_data_t *user_data)
+{
+	user_data->dlg.window = NULL;
+	g_free(user_data);
+}
+
+#define RIGHT_ARROW 1
+#define LEFT_ARROW  0
+#define WIDTH_ARROW 8
+#define HEIGHT_ARROW 6
+
+/****************************************************************************/
+static void draw_arrow(GdkDrawable *pixmap, GdkGC *gc, gint x, gint y, gboolean direction)
+{
+	GdkPoint arrow_point[3];
+
+	arrow_point[0].x = x;
+	arrow_point[0].y = y-HEIGHT_ARROW/2;
+	if (direction == RIGHT_ARROW)
+		arrow_point[1].x = x+WIDTH_ARROW;
+	else
+		arrow_point[1].x = x-WIDTH_ARROW;
+	arrow_point[1].y = y;
+	arrow_point[2].x = x;
+	arrow_point[2].y = y+HEIGHT_ARROW/2;;
+
+	if (GDK_IS_DRAWABLE(pixmap)) {
+		gdk_draw_polygon(pixmap, gc, TRUE, arrow_point, 3);
+	}
+}
+
+guint32 iscsiexpert_get_pixmap_index( display_items_t * di)
+{
+	switch (di->severity){
+		case PI_NOTE:
+			return 24;;
+		case PI_WARN:
+			return 24;
+		case PI_ERROR:
+			return 25;
+	}
+
+	switch (di->opcode){
+		case ISCSIEXPERT_OPCODE_LOGIN_COMMAND:
+			return 0;
+		case ISCSIEXPERT_OPCODE_LOGIN_RESPONSE:
+			return 5;
+		case ISCSIEXPERT_OPCODE_SCSI_COMMAND:
+			return 6;
+		case ISCSIEXPERT_OPCODE_SCSI_RESPONSE:
+			return 7;
+		case ISCSIEXPERT_OPCODE_SCSI_DATA_OUT:
+			return 8;
+		case ISCSIEXPERT_OPCODE_SCSI_DATA_IN:
+			return 9;
+		case ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION:
+			return 10;
+		case ISCSIEXPERT_OPCODE_TASK_MANAGEMENT_FUNCTION_RESPONSE:
+			return 11;
+		case ISCSIEXPERT_OPCODE_NOP_OUT:
+			return 12;
+		case ISCSIEXPERT_OPCODE_NOP_IN:
+			return 13;
+		case ISCSIEXPERT_OPCODE_ASYNC_MESSAGE:
+			return 14;
+		case ISCSIEXPERT_OPCODE_REJECT:
+			return 15;
+		case ISCSIEXPERT_OPCODE_R2T:
+			return 16;
+		case ISCSIEXPERT_OPCODE_TEXT_COMMAND:
+			return 17;
+		case ISCSIEXPERT_OPCODE_TEXT_RESPONSE:
+			return 18;
+		case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I0:
+		case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I1:
+		case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_I2:
+			return 19;
+		case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T0:
+		case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T1:
+		case ISCSIEXPERT_OPCODE_VENDOR_SPECIFIC_T2:
+			return 20;
+		case ISCSIEXPERT_OPCODE_SNACK_REQUEST:
+			return 21;
+		case ISCSIEXPERT_OPCODE_LOGOUT_COMMAND:
+			return 22;
+		case ISCSIEXPERT_OPCODE_LOGOUT_RESPONSE:
+			return 23;
+		default:
+			break;
+	}
+	return  0;
+}
+
+/****************************************************************************/
+static void iscsiexpert_dialog_graph_draw(iscsiexpert_graph_analysis_data_t* user_data)
+{
+	guint32 i, last_item, first_item, display_items;
+	
+	//guint32 start_arrow, end_arrow;
+	//GdkGC *frame_fg_color;
+	//GdkGC *div_line_color;
+	GdkGC *frame_bg_color;
+	
+	guint32 current_item;
+	guint32 left_x_border;
+	guint32 right_x_border;
+	guint32 top_y_border;
+	guint32 bottom_y_border;
+	iscsiexpert_graph_analysis_item_t *gai;
+	guint16 first_conv_num;
+	gboolean several_convs = FALSE;
+	gboolean first_packet = TRUE;
+
+	PangoLayout  *layout;
+	PangoLayout  *big_layout;
+	PangoLayout  *small_layout;
+	gint label_width, label_height;
+	guint32 draw_height;
+	char label_string[MAX_COMMENT];
+	GList* list;
+
+	GtkTooltips *tooltips = gtk_tooltips_new();
+
+	/* new variables */
+
+	if(!user_data->dlg.needs_redraw){
+		return;
+	}
+	user_data->dlg.needs_redraw=FALSE;
+
+	/* Clear out old plt */
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_framenum) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_framenum,
+						   user_data->dlg.draw_area_framenum->style->white_gc,
+						   TRUE,
+						   0, 0,
+						   user_data->dlg.draw_area_framenum->allocation.width,
+						   user_data->dlg.draw_area_framenum->allocation.height);
+
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_time) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_time,
+						   user_data->dlg.draw_area_time->style->white_gc,
+						   TRUE,
+						   0, 0,
+						   user_data->dlg.draw_area_time->allocation.width,
+						   user_data->dlg.draw_area_time->allocation.height);
+
+
+
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_icon) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_icon,
+						   user_data->dlg.draw_area_icon->style->white_gc,
+						   TRUE,
+						   0, 0,
+						   user_data->dlg.draw_area_icon->allocation.width,
+						   user_data->dlg.draw_area_icon->allocation.height);
+
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_initiator) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_initiator,
+						   user_data->dlg.draw_area_initiator->style->white_gc,
+						   TRUE,
+						   0, 0,
+						   user_data->dlg.draw_area_initiator->allocation.width,
+						   user_data->dlg.draw_area_initiator->allocation.height);
+
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_operation) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_operation,
+						   user_data->dlg.draw_area_operation->style->white_gc,
+						   TRUE,
+						   0, 0,
+						   user_data->dlg.draw_area_operation->allocation.width,
+						   user_data->dlg.draw_area_operation->allocation.height);
+
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_target) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_target,
+						   user_data->dlg.draw_area_target->style->white_gc,
+						   TRUE,
+						   0, 0,
+						   user_data->dlg.draw_area_target->allocation.width,
+						   user_data->dlg.draw_area_target->allocation.height);
+
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_comments) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_comments,
+						   user_data->dlg.draw_area_comments->style->white_gc,
+						   TRUE,
+						   0, 0,
+						   user_data->dlg.draw_area_comments->allocation.width,
+						   user_data->dlg.draw_area_comments->allocation.height);
+
+	/* Calculate the y border */
+	top_y_border=TOP_Y_BORDER;	/* to display the node address */
+	bottom_y_border=BOTTOM_Y_BORDER;
+
+	draw_height=user_data->dlg.draw_area_time->allocation.height-top_y_border-bottom_y_border;
+
+	first_item = user_data->dlg.first_item;
+	display_items = draw_height/ITEM_HEIGHT;
+	last_item = first_item+display_items-1;
+
+	/* get the items to display and fill the matrix array */
+	list = g_list_first(user_data->graph_info->list);
+	current_item = 0;
+	i = 0;
+	while (list)
+	{
+		gai = list->data;
+		if (gai->conn->display){
+			if (current_item>=display_items) break;		/* the item is outside the display */
+			if (i>=first_item){
+				user_data->dlg.items[current_item].frame_num = gai->frame_num;
+				user_data->dlg.items[current_item].time = gai->time;
+				user_data->dlg.items[current_item].port_src = gai->port_src;
+				user_data->dlg.items[current_item].port_dst = gai->port_dst;
+
+				/* Add "..." if the length is 50 characters */
+				if (strlen(gai->frame_label) > MAX_TOOLTIP) {
+					gai->frame_label[MAX_TOOLTIP] = '.';
+					gai->frame_label[MAX_TOOLTIP - 1] = '.';
+					gai->frame_label[MAX_TOOLTIP - 2] = '.';
+				}
+				user_data->dlg.items[current_item].frame_label = gai->frame_label;
+
+				user_data->dlg.items[current_item].comment = gai->comment;
+				user_data->dlg.items[current_item].conv_num = gai->conv_num;
+
+				if (first_packet){
+					first_conv_num = gai->conv_num;
+					first_packet=FALSE;
+				}
+
+				if (user_data->dlg.items[current_item].conv_num != first_conv_num){
+					several_convs = TRUE;
+				}
+
+				user_data->dlg.items[current_item].line_style = gai->line_style;
+
+				COPY_ADDRESS(&(user_data->dlg.items[current_item].src_addr),&(gai->src_addr))
+				COPY_ADDRESS(&(user_data->dlg.items[current_item].dst_addr),&(gai->dst_addr))
+
+				user_data->dlg.items[current_item].opcode		= gai->opcode;
+				user_data->dlg.items[current_item].direction	= gai->direction;
+				user_data->dlg.items[current_item].group		= gai->group;
+				user_data->dlg.items[current_item].severity		= gai->severity;
+				user_data->dlg.items[current_item].summary		= gai->summary;
+				user_data->dlg.items[current_item].conn			= gai->conn;
+
+
+				current_item++;
+			}
+			i++;
+		}
+
+		list = g_list_next(list);
+	}
+	/* in case the windows is resized so we have to move the top item */
+	if ((first_item + display_items) > user_data->num_items){
+		if (display_items>user_data->num_items)
+			first_item=0;
+		else
+			first_item = user_data->num_items - display_items;
+	}
+
+	/* in case there are less items than possible displayed */
+	display_items = current_item;
+	last_item = first_item+display_items-1;
+
+	/* if no items to display */
+	if (display_items == 0)	return;
+
+	/* Calculate the x borders */
+	/* We use time from the last display item to calcultate the x left border */
+	g_snprintf(label_string, MAX_LABEL, "%.3f", user_data->dlg.items[display_items-1].time);
+	layout = gtk_widget_create_pango_layout(user_data->dlg.draw_area_time, label_string);
+	big_layout = gtk_widget_create_pango_layout(user_data->dlg.draw_area_time, label_string);
+	small_layout = gtk_widget_create_pango_layout(user_data->dlg.draw_area_time, label_string);
+
+	/* XXX - to prevent messages like "Couldn't load font x, falling back to y", I've changed font
+	         description from "Helvetica-Bold 8" to "Helvetica,Sans,Bold 8", this seems to be
+	         conforming to the API, see http://developer.gnome.org/doc/API/2.0/pango/pango-Fonts.html */
+	pango_layout_set_font_description(big_layout, pango_font_description_from_string("Helvetica,Sans,Bold 8"));
+	pango_layout_set_font_description(small_layout, pango_font_description_from_string("Helvetica,Sans,Bold 7"));
+
+	pango_layout_get_pixel_size(layout, &label_width, &label_height);
+
+	/* resize the "time" draw area */
+	left_x_border=3;
+	user_data->dlg.left_x_border = left_x_border;
+
+	right_x_border=2;
+
+	/* Paint framenum title background */
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_framenum) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_framenum,
+						   user_data->dlg.draw_area_framenum->style->bg_gc[2],
+						   TRUE,
+						   0,
+						   0,
+						   user_data->dlg.draw_area_framenum->allocation.width,
+						   top_y_border);
+
+	/* Paint time title background */
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_time) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_time,
+						   user_data->dlg.draw_area_time->style->bg_gc[2],
+						   TRUE,
+						   0,
+						   0,
+						   user_data->dlg.draw_area_time->allocation.width,
+						   top_y_border);
+
+	/* Paint icon title background */
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_icon) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_icon,
+						   user_data->dlg.draw_area_icon->style->bg_gc[2],
+						   TRUE,
+						   0,
+						   0,
+						   user_data->dlg.draw_area_icon->allocation.width,
+						   top_y_border);
+
+	/* Paint initiator title background */
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_initiator) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_initiator,
+						   user_data->dlg.draw_area_initiator->style->bg_gc[2],
+						   TRUE,
+						   0,
+						   0,
+						   user_data->dlg.draw_area_initiator->allocation.width,
+						   top_y_border);
+
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_operation) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_operation,
+						   user_data->dlg.draw_area_operation->style->bg_gc[2],
+						   TRUE,
+						   0,
+						   0,
+						   user_data->dlg.draw_area_operation->allocation.width,
+						   top_y_border);
+
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_target) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_target,
+						   user_data->dlg.draw_area_target->style->bg_gc[2],
+						   TRUE,
+						   0,
+						   0,
+						   user_data->dlg.draw_area_target->allocation.width,
+						   top_y_border);
+
+	/* Paint main comment background */
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_comments) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_comments,
+						   user_data->dlg.draw_area_comments->style->bg_gc[2],
+						   TRUE,
+						   0,
+						   0,
+						   user_data->dlg.draw_area_comments->allocation.width,
+						   top_y_border);
+
+	/* Draw the word "FrameNum" on top of time column */
+	g_snprintf(label_string, label_width, "%s", "No.");
+	pango_layout_set_text(layout, label_string, -1);
+	pango_layout_get_pixel_size(layout, &label_width, &label_height);
+	if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_framenum)) {
+		gdk_draw_layout(user_data->dlg.pixmap_framenum,
+						user_data->dlg.draw_area_framenum->style->black_gc,
+						FRAMENUM_WIDTH/2-label_width/2,
+						top_y_border/2-label_height/2,
+						layout);
+	}
+
+
+	/* Draw the word "Time" on top of time column */
+	g_snprintf(label_string, label_width, "%s", "Time");
+	pango_layout_set_text(layout, label_string, -1);
+	pango_layout_get_pixel_size(layout, &label_width, &label_height);
+	if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_time)) {
+		gdk_draw_layout(user_data->dlg.pixmap_time,
+						user_data->dlg.draw_area_time->style->black_gc,
+						TIME_WIDTH/2-label_width/2,
+						top_y_border/2-label_height/2,
+						layout);
+	}
+
+	/* Draw the word "ICON" on top of Initiator column */
+	g_snprintf(label_string, label_width, "%s", "ICON");
+	pango_layout_set_text(layout, label_string, -1);
+	pango_layout_get_pixel_size(layout, &label_width, &label_height);
+	if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_icon)) {
+		gdk_draw_layout(user_data->dlg.pixmap_icon,
+						user_data->dlg.draw_area_icon->style->black_gc,
+						ICON_WIDTH/2-label_width/2,
+						top_y_border/2-label_height/2,
+						layout);
+	}
+
+	/* Draw the word "Initiator" on top of Initiator column */
+	g_snprintf(label_string, label_width, "%s", "Initiator");
+	pango_layout_set_text(layout, label_string, -1);
+	pango_layout_get_pixel_size(layout, &label_width, &label_height);
+	if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_initiator)) {
+		gdk_draw_layout(user_data->dlg.pixmap_initiator,
+						user_data->dlg.draw_area_initiator->style->black_gc,
+						INITIATOR_WIDTH/2-label_width/2,
+						top_y_border/2-label_height/2,
+						layout);
+	}
+	/* Draw the word "Operation" on top of Operation column */
+	g_snprintf(label_string, label_width, "%s", "<-->");
+	pango_layout_set_text(layout, label_string, -1);
+	pango_layout_get_pixel_size(layout, &label_width, &label_height);
+	if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_operation)) {
+		gdk_draw_layout(user_data->dlg.pixmap_operation,
+						user_data->dlg.draw_area_operation->style->black_gc,
+						OPERATION_WIDTH/2-label_width/2,
+						top_y_border/2-label_height/2,
+						layout);
+	}
+
+	/* Draw the word "Target" on top of Target column */
+	g_snprintf(label_string, label_width, "%s", "Target");
+	pango_layout_set_text(layout, label_string, -1);
+	pango_layout_get_pixel_size(layout, &label_width, &label_height);
+	if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_target)) {
+		gdk_draw_layout(user_data->dlg.pixmap_target,
+						user_data->dlg.draw_area_target->style->black_gc,
+						TARGET_WIDTH/2-label_width/2,
+						top_y_border/2-label_height/2,
+						layout);
+	}
+
+	/* Draw the word "Comment" on top of comment column */
+	g_snprintf(label_string, label_width, "%s", "Comment");
+	pango_layout_set_text(layout, label_string, -1);
+	pango_layout_get_pixel_size(layout, &label_width, &label_height);
+	if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_comments)) {
+		gdk_draw_layout(user_data->dlg.pixmap_comments,
+			   user_data->dlg.draw_area_comments->style->black_gc,
+			   MAX_COMMENT/2-label_width/2,
+			   top_y_border/2-label_height/2,
+			   layout);
+	}
+
+	/* Paint the background items */
+	for (current_item=0; current_item<display_items; current_item++){
+		/*select the color. if it is the selected item select blue color */
+		if ( current_item+first_item == user_data->dlg.selected_item ) {
+			frame_bg_color = user_data->dlg.bg_gc[0];
+//		} else if (TRUE == iscsiexpert_display_expertinfo(&user_data->dlg.items[current_item])) {
+//  		switch(user_data->dlg.items[current_item].severity) {
+//  			case PI_CHAT:
+//  				frame_bg_color = user_data->dlg.bg_expert_gc[0];
+//  				break;
+//  			case PI_NOTE:
+//  				frame_bg_color = user_data->dlg.bg_expert_gc[1];
+//  				break;
+//  			case PI_WARN:
+//  				frame_bg_color = user_data->dlg.bg_expert_gc[2];
+//  				break;
+//  			case PI_ERROR:
+//  				frame_bg_color = user_data->dlg.bg_expert_gc[3];
+//  				break;
+//  			default:
+//  				break;
+//  		}
+		}else {
+			frame_bg_color = user_data->dlg.bg_gc[1+user_data->dlg.items[current_item].conv_num%MAX_NUM_COL_CONV];
+		}
+
+		/* Paint background */
+		if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_initiator)) {
+			gdk_draw_rectangle(user_data->dlg.pixmap_initiator,
+							   frame_bg_color,
+							   TRUE,
+							   0,
+							   top_y_border + current_item*ITEM_HEIGHT,
+							   user_data->dlg.draw_area_initiator->allocation.width,
+							   ITEM_HEIGHT);
+		}
+
+		if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_operation)) {
+			gdk_draw_rectangle(user_data->dlg.pixmap_operation,
+							   frame_bg_color,
+							   TRUE,
+							   0,
+							   top_y_border + current_item*ITEM_HEIGHT,
+							   user_data->dlg.draw_area_operation->allocation.width,
+							   ITEM_HEIGHT);
+		}
+
+		if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_target)) {
+			gdk_draw_rectangle(user_data->dlg.pixmap_target,
+							   frame_bg_color,
+							   TRUE,
+							   0,
+							   top_y_border + current_item*ITEM_HEIGHT,
+							   user_data->dlg.draw_area_target->allocation.width,
+							   ITEM_HEIGHT);
+		}
+
+		//if ( current_item+first_item == user_data->dlg.selected_item ) {
+//        if (TRUE == iscsiexpert_display_expertinfo(user_data->dlg.items[current_item].severity)){
+//            switch(user_data->dlg.items[current_item].severity) {
+//                case PI_CHAT:
+//                    frame_bg_color = user_data->dlg.bg_expert_gc[0];
+//                    break;
+//                case PI_NOTE:
+//                    frame_bg_color = user_data->dlg.bg_expert_gc[1];
+//                    break;
+//                case PI_WARN:
+//                    frame_bg_color = user_data->dlg.bg_expert_gc[2];
+//                    break;
+//                case PI_ERROR:
+//                    frame_bg_color = user_data->dlg.bg_expert_gc[3];
+//                    break;
+//                default:
+//                    break;
+//            }
+//
+////  		if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_time)) {
+////  			gdk_draw_rectangle(user_data->dlg.pixmap_time,
+////  							   frame_bg_color,
+////  							   TRUE,
+////  							   0,
+////  							   top_y_border + current_item*ITEM_HEIGHT,
+////  							   user_data->dlg.draw_area_time->allocation.width,
+////  							   ITEM_HEIGHT);
+////  		}
+////
+////  		if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_icon)) {
+////  			gdk_draw_rectangle(user_data->dlg.pixmap_icon,
+////  							   frame_bg_color,
+////  							   TRUE,
+////  							   0,
+////  							   top_y_border + current_item*ITEM_HEIGHT,
+////  							   user_data->dlg.draw_area_icon->allocation.width,
+////  							   ITEM_HEIGHT);
+////  		}
+//
+//            if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_comments)) {
+//                gdk_draw_rectangle(user_data->dlg.pixmap_comments,
+//                                   frame_bg_color,
+//                                   TRUE,
+//                                   0,
+//                                   top_y_border + current_item*ITEM_HEIGHT,
+//                                   user_data->dlg.draw_area_comments->allocation.width,
+//                                   ITEM_HEIGHT);
+//            }
+//
+//        }
+		
+	}
+
+	/* Draw the items */
+	for (current_item=0; current_item<display_items; current_item++){
+		/* draw the framenum */
+		g_snprintf(label_string, MAX_LABEL, "%d", 
+				   user_data->dlg.items[current_item].frame_num);
+		pango_layout_set_text(layout, label_string, -1);
+		pango_layout_get_pixel_size(layout, &label_width, &label_height);
+		if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_framenum)) {
+			gdk_draw_layout(user_data->dlg.pixmap_framenum,
+							user_data->dlg.draw_area_time->style->black_gc,
+							3,
+							top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
+							layout);
+		}
+
+		/* draw the time */
+		g_snprintf(label_string, MAX_LABEL, "%.3f", 
+				   user_data->dlg.items[current_item].time);
+		pango_layout_set_text(layout, label_string, -1);
+		pango_layout_get_pixel_size(layout, &label_width, &label_height);
+		if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_time)) {
+			gdk_draw_layout(user_data->dlg.pixmap_time,
+							user_data->dlg.draw_area_time->style->black_gc,
+							3,
+							top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
+							layout);
+		}
+
+		/* draw the ICON */
+		{
+				guint pixmap_index = iscsiexpert_get_pixmap_index(&user_data->dlg.items[current_item]);
+
+				if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_icon)) {
+						gdk_draw_pixmap(user_data->dlg.pixmap_icon,
+									user_data->dlg.draw_area_time->style->black_gc,
+									iscsiexpert_icons[pixmap_index].pixmap,
+									0,
+									0,
+									2,
+									top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
+									-1,
+									-1);
+				}
+
+				if ( current_item+first_item == user_data->dlg.mouse_move_item ) {
+					/* draw the frame comment */
+					g_snprintf(label_string, MAX_TOOLTIP, "%s", user_data->dlg.items[current_item].frame_label);
+					gtk_tooltips_set_tip (tooltips, user_data->dlg.draw_area_icon, label_string, NULL);
+				}
+		}
+		
+
+		/* draw the initiator */
+		if (user_data->dlg.items[current_item].direction){
+			g_snprintf(label_string, MAX_INITIATOR, "%s:%i", 
+						get_addr_name(&(user_data->dlg.items[current_item].dst_addr)),
+						user_data->dlg.items[current_item].port_dst);
+		}else{
+			g_snprintf(label_string, MAX_INITIATOR, "%s:%i", 
+						get_addr_name(&(user_data->dlg.items[current_item].src_addr)),
+						user_data->dlg.items[current_item].port_src);
+		}
+
+		pango_layout_set_text(layout, label_string, -1);
+		pango_layout_get_pixel_size(layout, &label_width, &label_height);
+		if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_initiator)) {
+			gdk_draw_layout(user_data->dlg.pixmap_initiator,
+							user_data->dlg.draw_area_time->style->black_gc,
+							2,
+							top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
+							layout);
+		}
+
+		{
+			/* draw the operation */
+			if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_operation)) {
+				if (user_data->dlg.items[current_item].direction) {
+						gdk_draw_pixmap(user_data->dlg.pixmap_operation,
+									user_data->dlg.draw_area_time->style->black_gc,
+									iscsiexpert_direction_icons[0].pixmap,
+									0,
+									0,
+									7,
+									top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
+									-1,
+									-1);
+				}else{
+						gdk_draw_pixmap(user_data->dlg.pixmap_operation,
+									user_data->dlg.draw_area_time->style->black_gc,
+									iscsiexpert_direction_icons[1].pixmap,
+									0,
+									0,
+									7,
+									top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
+									-1,
+									-1);
+				}
+			}
+		}
+
+		/* draw the target */
+		if (user_data->dlg.items[current_item].direction){
+			g_snprintf(label_string, MAX_INITIATOR, "%s:%i", 
+					get_addr_name(&(user_data->dlg.items[current_item].src_addr)),
+					user_data->dlg.items[current_item].port_src);
+		}else{
+			g_snprintf(label_string, MAX_INITIATOR, "%s:%i", 
+					get_addr_name(&(user_data->dlg.items[current_item].dst_addr)),
+					user_data->dlg.items[current_item].port_dst);
+		}
+
+		pango_layout_set_text(layout, label_string, -1);
+		pango_layout_get_pixel_size(layout, &label_width, &label_height);
+		if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_target)) {
+			gdk_draw_layout(user_data->dlg.pixmap_target,
+							user_data->dlg.draw_area_time->style->black_gc,
+							2,
+							top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
+							layout);
+		}
+
+		{
+			/*draw the comments */
+			static const GdkColor text_color[2] = { {0, 0, 0, 0},
+													{0, 0xff00, 0x5c00, 0x5c00} };
+			if (TRUE == iscsiexpert_display_expertinfo(user_data->dlg.items[current_item].severity)) {
+				g_snprintf(label_string, MAX_COMMENT, "Expert : %s (iSCSI Packet: %s)", 
+						   user_data->dlg.items[current_item].summary,
+						   user_data->dlg.items[current_item].comment);
+				pango_layout_set_text(small_layout, label_string, -1);
+				pango_layout_get_pixel_size(small_layout, &label_width, &label_height);
+				if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_comments)) {
+					gdk_draw_layout_with_colors(user_data->dlg.pixmap_comments,
+									user_data->dlg.draw_area_time->style->black_gc,
+									2,
+									top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
+									small_layout,&text_color[10],NULL);
+				}
+			}else{
+				g_snprintf(label_string, MAX_COMMENT, "%s", user_data->dlg.items[current_item].comment);
+				pango_layout_set_text(small_layout, label_string, -1);
+				pango_layout_get_pixel_size(small_layout, &label_width, &label_height);
+				if (GDK_IS_DRAWABLE(user_data->dlg.pixmap_comments)) {
+					gdk_draw_layout_with_colors(user_data->dlg.pixmap_comments,
+									user_data->dlg.draw_area_time->style->black_gc,
+									2,
+									top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
+									small_layout,&text_color[0],NULL);
+				}
+			}
+		}
+	}
+
+	g_object_unref(G_OBJECT(layout));
+
+	/* refresh the draw areas */
+
+	if (GDK_IS_DRAWABLE(user_data->dlg.draw_area_framenum->window) )
+		gdk_draw_pixmap(user_data->dlg.draw_area_framenum->window,
+						user_data->dlg.draw_area_framenum->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area_framenum)],
+						user_data->dlg.pixmap_framenum,
+						0, 0,
+						0, 0,
+						user_data->dlg.draw_area_framenum->allocation.width, user_data->dlg.draw_area_framenum->allocation.height);
+
+	if (GDK_IS_DRAWABLE(user_data->dlg.draw_area_time->window) )
+		gdk_draw_pixmap(user_data->dlg.draw_area_time->window,
+						user_data->dlg.draw_area_time->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area_time)],
+						user_data->dlg.pixmap_time,
+						0, 0,
+						0, 0,
+						user_data->dlg.draw_area_time->allocation.width, user_data->dlg.draw_area_time->allocation.height);
+
+	if (GDK_IS_DRAWABLE(user_data->dlg.draw_area_icon->window) )
+		gdk_draw_pixmap(user_data->dlg.draw_area_icon->window,
+						user_data->dlg.draw_area_icon->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area_icon)],
+						user_data->dlg.pixmap_icon,
+						0, 0,
+						0, 0,
+						user_data->dlg.draw_area_icon->allocation.width, user_data->dlg.draw_area_icon->allocation.height);
+
+
+	if (GDK_IS_DRAWABLE(user_data->dlg.draw_area_initiator->window) )
+		gdk_draw_pixmap(user_data->dlg.draw_area_initiator->window,
+						user_data->dlg.draw_area_initiator->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area_initiator)],
+						user_data->dlg.pixmap_initiator,
+						0, 0,
+						0, 0,
+						user_data->dlg.draw_area_initiator->allocation.width, user_data->dlg.draw_area_initiator->allocation.height);
+
+
+	if (GDK_IS_DRAWABLE(user_data->dlg.draw_area_operation->window) )
+		gdk_draw_pixmap(user_data->dlg.draw_area_operation->window,
+						user_data->dlg.draw_area_operation->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area_operation)],
+						user_data->dlg.pixmap_operation,
+						0, 0,
+						0, 0,
+						user_data->dlg.draw_area_operation->allocation.width, user_data->dlg.draw_area_operation->allocation.height);
+
+	if (GDK_IS_DRAWABLE(user_data->dlg.draw_area_target->window) )
+		gdk_draw_pixmap(user_data->dlg.draw_area_target->window,
+						user_data->dlg.draw_area_target->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area_target)],
+						user_data->dlg.pixmap_target,
+						0, 0,
+						0, 0,
+						user_data->dlg.draw_area_target->allocation.width, user_data->dlg.draw_area_target->allocation.height);
+
+
+	if (GDK_IS_DRAWABLE(user_data->dlg.draw_area_comments->window) )
+		gdk_draw_pixmap(user_data->dlg.draw_area_comments->window,
+						user_data->dlg.draw_area_comments->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area_comments)],
+						user_data->dlg.pixmap_comments,
+						0, 0,
+						0, 0,
+						user_data->dlg.draw_area_comments->allocation.width, user_data->dlg.draw_area_comments->allocation.height);
+
+	/* update the v_scrollbar */
+	user_data->dlg.v_scrollbar_adjustment->upper=(gfloat) user_data->num_items-1;
+	user_data->dlg.v_scrollbar_adjustment->step_increment=1;
+	user_data->dlg.v_scrollbar_adjustment->page_increment=(gfloat) (last_item-first_item);
+	user_data->dlg.v_scrollbar_adjustment->page_size=(gfloat) (last_item-first_item);
+	user_data->dlg.v_scrollbar_adjustment->value=(gfloat) first_item;
+
+	gtk_adjustment_changed(user_data->dlg.v_scrollbar_adjustment);
+	gtk_adjustment_value_changed(user_data->dlg.v_scrollbar_adjustment);
+}
+
+enum{
+	KEY_COLUMN = 0,
+	VALUE_COLUMN,
+	PARAMETER_NUM_COLS
+};
+
+static void add_parameter_to_list(GtkWidget *parameter_list, const gchar *key,const gchar *value)
+{
+	GtkListStore *store = NULL;
+	GtkTreeIter iter;
+
+	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(parameter_list)));
+	gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(parameter_list), GTK_TREE_VIEW_GRID_LINES_BOTH);
+	
+	/*Display the real negotiation key=value pairs*/
+	gtk_list_store_append(store, &iter);
+	gtk_list_store_set(store, &iter, KEY_COLUMN, key,
+									 VALUE_COLUMN, value,
+									 -1);
+}
+
+static void clear_parameter_list(GtkWidget *parameter_list)
+{
+	GtkListStore *store = NULL;
+
+	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(parameter_list)));
+
+	gtk_list_store_clear (store);
+}
+
+
+
+/****************************************************************************/
+static void iscsiexpert_dialog_graph_redraw(iscsiexpert_graph_analysis_data_t* user_data)
+{
+	user_data->dlg.needs_redraw=TRUE;
+	iscsiexpert_dialog_graph_draw(user_data);
+}
+
+/****************************************************************************/
+static void iscsiexpert_statitics_info_draw(iscsiexpert_statitics_info_data_t* statinfo_data)
+{
+	iscsiexpert_statitics_info_item_t *sii;
+	char value_buff[128];
+	GList* list;
+
+	guint64		scsi_cmd_count;
+	guint64		total_scsi_data_length;
+	nstime_t	start_time;
+	nstime_t	end_time;
+	nstime_t	delta_time;
+
+	if(!statinfo_data->dlg.needs_redraw){
+		return;
+	}
+
+	statinfo_data->dlg.needs_redraw=FALSE;
+
+	scsi_cmd_count = 0;
+	total_scsi_data_length = 0;
+
+	nstime_set_zero(&start_time);
+	nstime_set_zero(&end_time);
+
+	/* get the items to display and fill the matrix array */
+	list = g_list_first(statitics_info->list);
+	while (list)
+	{
+		sii = list->data;
+
+		if (TRUE == sii->conn->display) {
+			if (0 != sii->conn->scsi_cmd_count){
+				scsi_cmd_count += sii->conn->scsi_cmd_count;
+				total_scsi_data_length += sii->conn->total_scsi_data_length;
+
+				if (0 < nstime_cmp(&start_time,&sii->conn->scsi_start_time)){
+					start_time.secs = sii->conn->scsi_start_time.secs;
+					start_time.nsecs = sii->conn->scsi_start_time.nsecs;
+				}
+
+				if (0 > nstime_cmp(&end_time,&sii->scsi_end_time)){
+					end_time.secs = sii->scsi_end_time.secs;
+					end_time.nsecs = sii->scsi_end_time.nsecs;
+				}
+			}
+		}
+
+		list = g_list_next(list);
+	}
+
+	nstime_delta(&delta_time,&end_time,&start_time);
+
+	clear_parameter_list(statinfo_data->dlg.iscsi_parameter_list);
+
+	if (FALSE == nstime_is_zero(&delta_time)){
+		double		double_delta_time;
+		double_delta_time = nstime_to_sec(&delta_time);
+		g_sprintf(value_buff, "%.2f /s", scsi_cmd_count  / double_delta_time);
+		add_parameter_to_list(statinfo_data->dlg.iscsi_parameter_list, "Average IOPS", value_buff);
+		g_sprintf(value_buff, "%.2f MB/S",(total_scsi_data_length  / double_delta_time) / 2048);
+		add_parameter_to_list(statinfo_data->dlg.iscsi_parameter_list, "Average Throught",value_buff);
+	}else {
+		add_parameter_to_list(statinfo_data->dlg.iscsi_parameter_list, "Average IOPS", "N/A");
+		add_parameter_to_list(statinfo_data->dlg.iscsi_parameter_list, "Average Throught","N/A");
+	}
+
+	gtk_widget_show(GTK_WIDGET(statinfo_data->dlg.iscsi_parameter_list));
+}
+
+/****************************************************************************/
+static void iscsiexpert_statitics_info_redraw(iscsiexpert_statitics_info_data_t* statinfo_data)
+{
+	statinfo_data->dlg.needs_redraw=TRUE;
+	iscsiexpert_statitics_info_draw(statinfo_data);
+}
+
+/****************************************************************************/
+static gint button_press_event(GtkWidget *widget, GdkEventButton *event _U_)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+	guint32 item;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+
+	if (event->type != GDK_BUTTON_PRESS) return TRUE;
+
+	if (event->y<TOP_Y_BORDER) return TRUE;
+
+	/* get the item clicked */
+	item = ((guint32)event->y - TOP_Y_BORDER) / ITEM_HEIGHT;
+
+	//simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+	 //	  "the packet number %u %u",item, user_data->num_items);
+
+	if (item >= user_data->num_items) return TRUE;
+	user_data->dlg.selected_item = item + user_data->dlg.first_item;
+
+	//simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+	// 	  "There is no packet with the packet number %u.", user_data->dlg.selected_item);
+
+	user_data->dlg.needs_redraw=TRUE;
+	iscsiexpert_dialog_graph_draw(user_data);
+
+	if (FALSE == iscsi_cf_goto_frame(&cfile, user_data->dlg.items[item].frame_num))
+	{
+		return TRUE;
+	}
+
+	{
+		//update the packet detail panel
+		DataPtr->frame = cfile.current_frame;
+		memcpy(&DataPtr->pseudo_header, &cfile.pseudo_header, sizeof DataPtr->pseudo_header);
+		DataPtr->pd = g_malloc(DataPtr->frame->cap_len);
+		memcpy(DataPtr->pd, cfile.pd, DataPtr->frame->cap_len);
+		DataPtr->edt = epan_dissect_new(TRUE, TRUE);
+		epan_dissect_run(DataPtr->edt, &DataPtr->pseudo_header, DataPtr->pd,
+				  DataPtr->frame, &cfile.cinfo);
+		epan_dissect_fill_in_columns(DataPtr->edt);
+
+		add_byte_views(DataPtr->edt,  DataPtr->tree_view, DataPtr->bv_nb_ptr);
+		proto_tree_draw(DataPtr->edt->tree,  DataPtr->tree_view);
+
+		DataPtr->finfo_selected = NULL;
+		gtk_widget_show(DataPtr->main);
+	}
+
+	return TRUE;
+}
+
+/****************************************************************************/
+static gint mouse_move_event(GtkWidget *widget, GdkEventMotion *event _U_)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+	guint32 item;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+
+	if (event->type != GDK_MOTION_NOTIFY) return TRUE;
+
+	if (event->y<TOP_Y_BORDER) return TRUE;
+
+	/* get the item clicked */
+	item = ((guint32)event->y - TOP_Y_BORDER) / ITEM_HEIGHT;
+
+	//simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+	 //	  "the packet number %u %u",item, user_data->num_items);
+
+	if (item >= user_data->num_items) return TRUE;
+	user_data->dlg.mouse_move_item = item + user_data->dlg.first_item;
+
+	//simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+	// 	  "There is no packet with the packet number %u.", user_data->dlg.selected_item);
+
+	user_data->dlg.needs_redraw=TRUE;
+	iscsiexpert_dialog_graph_draw(user_data);
+
+	return TRUE;
+}
+
+/****************************************************************************/
+static gint scroll_event(GtkWidget *widget, GdkEventScroll *event)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+
+	/* Up scroll */
+	switch(event->direction) {
+	case(GDK_SCROLL_UP):
+		if (user_data->dlg.first_item == 0) return TRUE;
+		if (user_data->dlg.first_item < 3)
+			user_data->dlg.first_item = 0;
+		else
+			user_data->dlg.first_item -= 3;
+		break;
+	case(GDK_SCROLL_DOWN):
+		if ((user_data->dlg.first_item+user_data->dlg.v_scrollbar_adjustment->page_size+1 == user_data->num_items)) return TRUE;
+		if ((user_data->dlg.first_item+user_data->dlg.v_scrollbar_adjustment->page_size+1) > (user_data->num_items-3))
+			user_data->dlg.first_item = user_data->num_items-(guint32)user_data->dlg.v_scrollbar_adjustment->page_size-1;
+		else
+			user_data->dlg.first_item += 3;
+	    break;
+	case(GDK_SCROLL_LEFT):
+	case(GDK_SCROLL_RIGHT):
+		/* nothing to do */
+		break;
+	}
+
+	iscsiexpert_dialog_graph_redraw(user_data);
+	
+	return TRUE;
+}
+
+/****************************************************************************/
+static gint key_press_event(GtkWidget *widget, GdkEventKey *event _U_)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+
+	/* if there is nothing selected, just return */
+	if (user_data->dlg.selected_item == 0xFFFFFFFF) return TRUE;
+
+	/* Up arrow */
+	if (event->keyval == GDK_Up){
+		if (user_data->dlg.selected_item == 0) return TRUE;
+		user_data->dlg.selected_item--;
+		if ( (user_data->dlg.selected_item<user_data->dlg.first_item) || (user_data->dlg.selected_item>user_data->dlg.first_item+user_data->dlg.v_scrollbar_adjustment->page_size) )
+			user_data->dlg.first_item = user_data->dlg.selected_item;
+		/* Down arrow */
+	} else if (event->keyval == GDK_Down){
+		if (user_data->dlg.selected_item == user_data->num_items-1) return TRUE;
+		user_data->dlg.selected_item++;
+		if ( (user_data->dlg.selected_item<user_data->dlg.first_item) || (user_data->dlg.selected_item>user_data->dlg.first_item+user_data->dlg.v_scrollbar_adjustment->page_size) )
+			user_data->dlg.first_item = (guint32)user_data->dlg.selected_item-(guint32)user_data->dlg.v_scrollbar_adjustment->page_size;
+	} else if (event->keyval == GDK_Left){
+		if (user_data->dlg.first_node == 0) return TRUE;
+		user_data->dlg.first_node--;
+	} else return TRUE;
+
+	user_data->dlg.needs_redraw=TRUE;
+	iscsiexpert_dialog_graph_draw(user_data);
+
+	if (FALSE == iscsi_cf_goto_frame(&cfile, user_data->dlg.items[user_data->dlg.selected_item-user_data->dlg.first_item].frame_num))
+	{
+		return TRUE;
+	}
+
+	{
+		//update the packet detail panel
+		DataPtr->frame = cfile.current_frame;
+		memcpy(&DataPtr->pseudo_header, &cfile.pseudo_header, sizeof DataPtr->pseudo_header);
+		DataPtr->pd = g_malloc(DataPtr->frame->cap_len);
+		memcpy(DataPtr->pd, cfile.pd, DataPtr->frame->cap_len);
+		DataPtr->edt = epan_dissect_new(TRUE, TRUE);
+		epan_dissect_run(DataPtr->edt, &DataPtr->pseudo_header, DataPtr->pd,
+				  DataPtr->frame, &cfile.cinfo);
+		epan_dissect_fill_in_columns(DataPtr->edt);
+
+		add_byte_views(DataPtr->edt,  DataPtr->tree_view, DataPtr->bv_nb_ptr);
+		proto_tree_draw(DataPtr->edt->tree,  DataPtr->tree_view);
+
+		DataPtr->finfo_selected = NULL;
+		gtk_widget_show(DataPtr->main);
+	}
+
+	return TRUE;
+}
+
+/****************************************************************************/
+static gint expose_event_comments(GtkWidget *widget, GdkEventExpose *event)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+	if(!user_data){
+		exit(10);
+	}
+
+	if (GDK_IS_DRAWABLE(widget->window))
+		gdk_draw_pixmap(widget->window,
+			widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+			user_data->dlg.pixmap_comments,
+			event->area.x, event->area.y,
+			event->area.x, event->area.y,
+			event->area.width, event->area.height);
+
+	return FALSE;
+}
+
+/****************************************************************************/
+static gint expose_event_framenum(GtkWidget *widget, GdkEventExpose *event)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+	if(!user_data){
+		exit(10);
+	}
+
+	if (GDK_IS_DRAWABLE(widget->window) )
+		gdk_draw_pixmap(widget->window,
+			widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+			user_data->dlg.pixmap_framenum,
+			event->area.x, event->area.y,
+			event->area.x, event->area.y,
+			event->area.width, event->area.height);
+
+	return FALSE;
+}
+
+/****************************************************************************/
+static gint expose_event_time(GtkWidget *widget, GdkEventExpose *event)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+	if(!user_data){
+		exit(10);
+	}
+
+	if (GDK_IS_DRAWABLE(widget->window) )
+		gdk_draw_pixmap(widget->window,
+			widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+			user_data->dlg.pixmap_time,
+			event->area.x, event->area.y,
+			event->area.x, event->area.y,
+			event->area.width, event->area.height);
+
+	return FALSE;
+}
+
+/****************************************************************************/
+static gint expose_event_icon(GtkWidget *widget, GdkEventExpose *event)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+	if(!user_data){
+		exit(10);
+	}
+
+	if (GDK_IS_DRAWABLE(widget->window) )
+		gdk_draw_pixmap(widget->window,
+			widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+			user_data->dlg.pixmap_icon,
+			event->area.x, event->area.y,
+			event->area.x, event->area.y,
+			event->area.width, event->area.height);
+
+	return FALSE;
+}
+
+/****************************************************************************/
+static gint expose_event_initiator(GtkWidget *widget, GdkEventExpose *event)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+	if(!user_data){
+		exit(10);
+	}
+
+	if (GDK_IS_DRAWABLE(widget->window) )
+		gdk_draw_pixmap(widget->window,
+			widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+			user_data->dlg.pixmap_initiator,
+			event->area.x, event->area.y,
+			event->area.x, event->area.y,
+			event->area.width, event->area.height);
+
+	return FALSE;
+}
+
+/****************************************************************************/
+static gint expose_event_operation(GtkWidget *widget, GdkEventExpose *event)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+	if(!user_data){
+		exit(10);
+	}
+
+	if (GDK_IS_DRAWABLE(widget->window) )
+		gdk_draw_pixmap(widget->window,
+			widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+			user_data->dlg.pixmap_operation,
+			event->area.x, event->area.y,
+			event->area.x, event->area.y,
+			event->area.width, event->area.height);
+
+	return FALSE;
+}
+
+/****************************************************************************/
+static gint expose_event_target(GtkWidget *widget, GdkEventExpose *event)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+	if(!user_data){
+		exit(10);
+	}
+
+	if (GDK_IS_DRAWABLE(widget->window) )
+		gdk_draw_pixmap(widget->window,
+			widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+			user_data->dlg.pixmap_target,
+			event->area.x, event->area.y,
+			event->area.x, event->area.y,
+			event->area.width, event->area.height);
+
+	return FALSE;
+}
+
+/****************************************************************************/
+static gint configure_event_framenum(GtkWidget *widget, GdkEventConfigure *event _U_)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+
+	if(!user_data){
+		exit(10);
+	}
+
+	if(user_data->dlg.pixmap_framenum){
+		gdk_pixmap_unref(user_data->dlg.pixmap_framenum);
+		user_data->dlg.pixmap_framenum=NULL;
+	}
+
+	user_data->dlg.pixmap_framenum=gdk_pixmap_new(widget->window,
+						widget->allocation.width,
+						widget->allocation.height,
+						-1);
+
+
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_framenum) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_time,
+						widget->style->white_gc,
+						TRUE,
+						0, 0,
+						widget->allocation.width,
+						widget->allocation.height);
+
+	iscsiexpert_dialog_graph_redraw(user_data);
+
+	return TRUE;
+}
+
+/****************************************************************************/
+static gint configure_event_time(GtkWidget *widget, GdkEventConfigure *event _U_)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+
+	if(!user_data){
+		exit(10);
+	}
+
+	if(user_data->dlg.pixmap_time){
+		gdk_pixmap_unref(user_data->dlg.pixmap_time);
+		user_data->dlg.pixmap_time=NULL;
+	}
+
+	user_data->dlg.pixmap_time=gdk_pixmap_new(widget->window,
+						widget->allocation.width,
+						widget->allocation.height,
+						-1);
+
+
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_time) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_time,
+						widget->style->white_gc,
+						TRUE,
+						0, 0,
+						widget->allocation.width,
+						widget->allocation.height);
+
+
+	iscsiexpert_userdata_init(user_data->dlg.pixmap_time, user_data);
+
+	iscsiexpert_dialog_graph_redraw(user_data);
+
+	return TRUE;
+}
+
+/****************************************************************************/
+static gint configure_event_icon(GtkWidget *widget, GdkEventConfigure *event _U_)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+
+	if(!user_data){
+		exit(10);
+	}
+
+	if(user_data->dlg.pixmap_icon){
+		gdk_pixmap_unref(user_data->dlg.pixmap_icon);
+		user_data->dlg.pixmap_icon=NULL;
+	}
+
+	user_data->dlg.pixmap_icon=gdk_pixmap_new(widget->window,
+						widget->allocation.width,
+						widget->allocation.height,
+						-1);
+
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_icon) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_icon,
+						widget->style->white_gc,
+						TRUE,
+						0, 0,
+						widget->allocation.width,
+						widget->allocation.height);
+
+	iscsiexpert_dialog_graph_redraw(user_data);
+
+	return TRUE;
+}
+
+/****************************************************************************/
+static gint configure_event_initiator(GtkWidget *widget, GdkEventConfigure *event _U_)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+
+	if(!user_data){
+		exit(10);
+	}
+
+	if(user_data->dlg.pixmap_initiator){
+		gdk_pixmap_unref(user_data->dlg.pixmap_initiator);
+		user_data->dlg.pixmap_initiator=NULL;
+	}
+
+	user_data->dlg.pixmap_initiator=gdk_pixmap_new(widget->window,
+						widget->allocation.width,
+						widget->allocation.height,
+						-1);
+
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_initiator) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_initiator,
+						widget->style->white_gc,
+						TRUE,
+						0, 0,
+						widget->allocation.width,
+						widget->allocation.height);
+
+
+
+	iscsiexpert_dialog_graph_redraw(user_data);
+
+	return TRUE;
+}
+
+/****************************************************************************/
+static gint configure_event_operation(GtkWidget *widget, GdkEventConfigure *event _U_)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+
+	if(!user_data){
+		exit(10);
+	}
+
+	if(user_data->dlg.pixmap_operation){
+		gdk_pixmap_unref(user_data->dlg.pixmap_operation);
+		user_data->dlg.pixmap_operation=NULL;
+	}
+
+	user_data->dlg.pixmap_operation=gdk_pixmap_new(widget->window,
+						widget->allocation.width,
+						widget->allocation.height,
+						-1);
+
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_operation) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_operation,
+						widget->style->white_gc,
+						TRUE,
+						0, 0,
+						widget->allocation.width,
+						widget->allocation.height);
+
+
+
+	iscsiexpert_dialog_graph_redraw(user_data);
+
+	return TRUE;
+}
+
+/****************************************************************************/
+static gint configure_event_target(GtkWidget *widget, GdkEventConfigure *event _U_)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+
+	if(!user_data){
+		exit(10);
+	}
+
+	if(user_data->dlg.pixmap_target){
+		gdk_pixmap_unref(user_data->dlg.pixmap_target);
+		user_data->dlg.pixmap_target=NULL;
+	}
+
+	user_data->dlg.pixmap_target=gdk_pixmap_new(widget->window,
+						widget->allocation.width,
+						widget->allocation.height,
+						-1);
+
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_target) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_target,
+						widget->style->white_gc,
+						TRUE,
+						0, 0,
+						widget->allocation.width,
+						widget->allocation.height);
+
+	iscsiexpert_dialog_graph_redraw(user_data);
+
+	return TRUE;
+}
+
+/****************************************************************************/
+static gint configure_event_comments(GtkWidget *widget, GdkEventConfigure *event _U_)
+{
+	iscsiexpert_graph_analysis_data_t *user_data;
+
+	user_data=(iscsiexpert_graph_analysis_data_t *)g_object_get_data(G_OBJECT(widget), "iscsiexpert_graph_analysis_data");
+
+	if(!user_data){
+		exit(10);
+	}
+
+	if(user_data->dlg.pixmap_comments){
+		gdk_pixmap_unref(user_data->dlg.pixmap_comments);
+		user_data->dlg.pixmap_comments=NULL;
+	}
+
+	user_data->dlg.pixmap_comments=gdk_pixmap_new(widget->window,
+						widget->allocation.width,
+						widget->allocation.height,
+						-1);
+
+	if ( GDK_IS_DRAWABLE(user_data->dlg.pixmap_comments) )
+		gdk_draw_rectangle(user_data->dlg.pixmap_comments,
+						widget->style->white_gc,
+						TRUE,
+						0, 0,
+						widget->allocation.width,
+						widget->allocation.height);
+
+	iscsiexpert_dialog_graph_redraw(user_data);
+	return TRUE;
+}
+
+/****************************************************************************/
+static gint pane_callback(GtkWidget *widget, GParamSpec *pspec _U_, gpointer data)
+{
+	iscsiexpert_graph_analysis_data_t *user_data=(iscsiexpert_graph_analysis_data_t *)data;
+
+	if(!user_data){
+		exit(10);
+	}
+	if (gtk_paned_get_position(GTK_PANED(user_data->dlg.hpane)) > user_data->dlg.pixmap_width)
+		gtk_paned_set_position(GTK_PANED(user_data->dlg.hpane), user_data->dlg.pixmap_width);
+
+	/* repaint the comment area because when moving the pane position there are times that the expose_event_comments is not called */
+	if (GDK_IS_DRAWABLE(user_data->dlg.draw_area_comments->window))
+		gdk_draw_pixmap(user_data->dlg.draw_area_comments->window,
+			user_data->dlg.draw_area_comments->style->fg_gc[GTK_WIDGET_STATE(widget)],
+			user_data->dlg.pixmap_comments,
+			0,0,
+			0,0,
+			user_data->dlg.draw_area_comments->allocation.width,
+			user_data->dlg.draw_area_comments->allocation.height);
+
+	return TRUE;
+}
+
+/****************************************************************************/
+static gint v_scrollbar_changed(GtkWidget *widget _U_, gpointer data)
+{
+	iscsiexpert_graph_analysis_data_t *user_data=(iscsiexpert_graph_analysis_data_t *)data;
+	if ((user_data->dlg.first_item+user_data->dlg.v_scrollbar_adjustment->page_size+1 == user_data->num_items)
+		&& (user_data->dlg.v_scrollbar_adjustment->value >= user_data->dlg.first_item ))
+		return TRUE;
+
+	if (user_data->dlg.first_item == user_data->dlg.v_scrollbar_adjustment->value)
+		return TRUE;
+
+	user_data->dlg.first_item = (guint32) user_data->dlg.v_scrollbar_adjustment->value;
+
+	iscsiexpert_dialog_graph_redraw(user_data);
+
+	return TRUE;
+}
+
+/****************************************************************************/
+static void iscsiexpert_create_draw_area(iscsiexpert_graph_analysis_data_t* user_data, GtkWidget *box)
+{
+	GtkWidget *vbox;
+	GtkWidget *hbox;
+	GtkWidget *scroll_window_comments;
+	GtkWidget *viewport_comments;
+
+	hbox=gtk_hbox_new(FALSE, 0);
+	gtk_widget_show(hbox);
+
+	vbox=gtk_vbox_new(FALSE, 0);
+	gtk_widget_show(vbox);
+
+	/* create "framenum" draw area */
+	user_data->dlg.draw_area_framenum=gtk_drawing_area_new();
+	gtk_widget_set_size_request(user_data->dlg.draw_area_framenum, FRAMENUM_WIDTH, user_data->dlg.pixmap_height);
+	g_object_set_data(G_OBJECT(user_data->dlg.draw_area_framenum), "iscsiexpert_graph_analysis_data", user_data);
+
+	/* create "time" draw area */
+	user_data->dlg.draw_area_time=gtk_drawing_area_new();
+	gtk_widget_set_size_request(user_data->dlg.draw_area_time, TIME_WIDTH, user_data->dlg.pixmap_height);
+	g_object_set_data(G_OBJECT(user_data->dlg.draw_area_time), "iscsiexpert_graph_analysis_data", user_data);
+
+	/* create "ICON" draw area */
+	user_data->dlg.draw_area_icon=gtk_drawing_area_new();
+	gtk_widget_set_size_request(user_data->dlg.draw_area_icon, ICON_WIDTH, user_data->dlg.pixmap_height);
+	g_object_set_data(G_OBJECT(user_data->dlg.draw_area_icon), "iscsiexpert_graph_analysis_data", user_data);
+
+
+	/* create "Initiator" draw area */
+	user_data->dlg.draw_area_initiator=gtk_drawing_area_new();
+	gtk_widget_set_size_request(user_data->dlg.draw_area_initiator, INITIATOR_WIDTH, user_data->dlg.pixmap_height);
+	g_object_set_data(G_OBJECT(user_data->dlg.draw_area_initiator), "iscsiexpert_graph_analysis_data", user_data);
+
+	/* create "Operation" draw area */
+	user_data->dlg.draw_area_operation=gtk_drawing_area_new();
+	gtk_widget_set_size_request(user_data->dlg.draw_area_operation, OPERATION_WIDTH, user_data->dlg.pixmap_height);
+	g_object_set_data(G_OBJECT(user_data->dlg.draw_area_operation), "iscsiexpert_graph_analysis_data", user_data);
+	gtk_widget_set_has_tooltip (user_data->dlg.draw_area_operation,TRUE);
+
+
+	/* create "Target" draw area */
+	user_data->dlg.draw_area_target=gtk_drawing_area_new();
+	gtk_widget_set_size_request(user_data->dlg.draw_area_target, TARGET_WIDTH, user_data->dlg.pixmap_height);
+	g_object_set_data(G_OBJECT(user_data->dlg.draw_area_target), "iscsiexpert_graph_analysis_data", user_data);
+
+
+	/* create "comments" draw area */
+	user_data->dlg.draw_area_comments=gtk_drawing_area_new();
+	gtk_widget_set_size_request(user_data->dlg.draw_area_comments, COMMENT_WIDTH, user_data->dlg.pixmap_height);
+	scroll_window_comments=gtk_scrolled_window_new(NULL, NULL);
+	gtk_widget_set_size_request(scroll_window_comments, COMMENT_WIDTH/2, user_data->dlg.pixmap_height);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scroll_window_comments), GTK_POLICY_ALWAYS, GTK_POLICY_NEVER);
+	viewport_comments = gtk_viewport_new(gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(scroll_window_comments)), gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scroll_window_comments)));
+	gtk_container_add(GTK_CONTAINER(viewport_comments), user_data->dlg.draw_area_comments);
+	gtk_container_add(GTK_CONTAINER(scroll_window_comments), viewport_comments);
+	gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport_comments), GTK_SHADOW_NONE);
+	g_object_set_data(G_OBJECT(user_data->dlg.draw_area_comments), "iscsiexpert_graph_analysis_data", user_data);
+
+	/* signals needed to handle backing pixmap framenum */
+	g_signal_connect(user_data->dlg.draw_area_framenum, "expose_event", G_CALLBACK(expose_event_framenum), NULL);
+	g_signal_connect(user_data->dlg.draw_area_framenum, "configure_event", G_CALLBACK(configure_event_framenum), user_data);
+	g_signal_connect(user_data->dlg.draw_area_framenum, "scroll_event",  G_CALLBACK(scroll_event), user_data);
+
+	/* signals needed to handle backing pixmap time */
+	g_signal_connect(user_data->dlg.draw_area_time, "expose_event", G_CALLBACK(expose_event_time), NULL);
+	g_signal_connect(user_data->dlg.draw_area_time, "configure_event", G_CALLBACK(configure_event_time), user_data);
+	g_signal_connect(user_data->dlg.draw_area_time, "scroll_event",  G_CALLBACK(scroll_event), user_data);
+
+	/* signals needed to handle backing pixmap initator */
+	g_signal_connect(user_data->dlg.draw_area_icon, "expose_event", G_CALLBACK(expose_event_icon), NULL);
+	g_signal_connect(user_data->dlg.draw_area_icon, "configure_event", G_CALLBACK(configure_event_icon), user_data);
+	g_signal_connect(user_data->dlg.draw_area_icon, "scroll_event",  G_CALLBACK(scroll_event), user_data);
+
+	/* signals needed to handle backing pixmap initator */
+	g_signal_connect(user_data->dlg.draw_area_initiator, "expose_event", G_CALLBACK(expose_event_initiator), NULL);
+	g_signal_connect(user_data->dlg.draw_area_initiator, "configure_event", G_CALLBACK(configure_event_initiator), user_data);
+	g_signal_connect(user_data->dlg.draw_area_initiator, "scroll_event",  G_CALLBACK(scroll_event), user_data);
+
+	/* signals needed to handle backing pixmap operation */
+	g_signal_connect(user_data->dlg.draw_area_operation, "expose_event", G_CALLBACK(expose_event_operation), NULL);
+	g_signal_connect(user_data->dlg.draw_area_operation, "configure_event", G_CALLBACK(configure_event_operation), user_data);
+	g_signal_connect(user_data->dlg.draw_area_operation, "scroll_event",  G_CALLBACK(scroll_event), user_data);
+
+	/* signals needed to handle backing pixmap target */
+	g_signal_connect(user_data->dlg.draw_area_target, "expose_event", G_CALLBACK(expose_event_target), NULL);
+	g_signal_connect(user_data->dlg.draw_area_target, "configure_event", G_CALLBACK(configure_event_target), user_data);
+	g_signal_connect(user_data->dlg.draw_area_target, "scroll_event",  G_CALLBACK(scroll_event), user_data);
+
+	/* signals needed to handle backing pixmap comments */
+	g_signal_connect(user_data->dlg.draw_area_comments, "expose_event", G_CALLBACK(expose_event_comments), NULL);
+	g_signal_connect(user_data->dlg.draw_area_comments, "configure_event", G_CALLBACK(configure_event_comments), user_data);
+	g_signal_connect(user_data->dlg.draw_area_comments, "scroll_event",  G_CALLBACK(scroll_event), user_data);
+
+
+	gtk_widget_add_events (user_data->dlg.draw_area_framenum, GDK_BUTTON_PRESS_MASK);
+	g_signal_connect(user_data->dlg.draw_area_framenum, "button_press_event", G_CALLBACK(button_press_event), user_data);
+	g_signal_connect(user_data->dlg.draw_area_framenum, "key_press_event",  G_CALLBACK(key_press_event), user_data);
+
+	gtk_widget_add_events (user_data->dlg.draw_area_time, GDK_BUTTON_PRESS_MASK);
+	g_signal_connect(user_data->dlg.draw_area_time, "button_press_event", G_CALLBACK(button_press_event), user_data);
+	g_signal_connect(user_data->dlg.draw_area_time, "key_press_event",  G_CALLBACK(key_press_event), user_data);
+
+	gtk_widget_add_events (user_data->dlg.draw_area_icon, GDK_BUTTON_PRESS_MASK);
+	g_signal_connect(user_data->dlg.draw_area_icon, "button_press_event", G_CALLBACK(button_press_event), user_data);
+	g_signal_connect(user_data->dlg.draw_area_icon, "key_press_event",  G_CALLBACK(key_press_event), user_data);
+
+	gtk_widget_add_events (user_data->dlg.draw_area_initiator, GDK_BUTTON_PRESS_MASK);
+	g_signal_connect(user_data->dlg.draw_area_initiator, "button_press_event", G_CALLBACK(button_press_event), user_data);
+	g_signal_connect(user_data->dlg.draw_area_initiator, "key_press_event",  G_CALLBACK(key_press_event), user_data);
+
+
+	gtk_widget_add_events (user_data->dlg.draw_area_operation, GDK_BUTTON_PRESS_MASK);
+	g_signal_connect(user_data->dlg.draw_area_operation, "button_press_event", G_CALLBACK(button_press_event), user_data);
+	g_signal_connect(user_data->dlg.draw_area_operation, "key_press_event",  G_CALLBACK(key_press_event), user_data);
+
+	gtk_widget_add_events (user_data->dlg.draw_area_operation, GDK_POINTER_MOTION_MASK); 
+	g_signal_connect (user_data->dlg.draw_area_operation, "motion-notify-event", G_CALLBACK(mouse_move_event), NULL); 
+
+	gtk_widget_add_events (user_data->dlg.draw_area_target, GDK_BUTTON_PRESS_MASK);
+	g_signal_connect(user_data->dlg.draw_area_target, "button_press_event", G_CALLBACK(button_press_event), user_data);
+	g_signal_connect(user_data->dlg.draw_area_target, "key_press_event",  G_CALLBACK(key_press_event), user_data);
+
+	gtk_widget_add_events (user_data->dlg.draw_area_comments, GDK_BUTTON_PRESS_MASK);
+	g_signal_connect(user_data->dlg.draw_area_comments, "button_press_event", G_CALLBACK(button_press_event), user_data);
+	g_signal_connect(user_data->dlg.draw_area_comments, "key_press_event",  G_CALLBACK(key_press_event), user_data);
+
+	gtk_widget_show(user_data->dlg.draw_area_framenum);
+	gtk_widget_show(user_data->dlg.draw_area_time);
+	gtk_widget_show(user_data->dlg.draw_area_icon);
+	gtk_widget_show(user_data->dlg.draw_area_initiator);
+	gtk_widget_show(user_data->dlg.draw_area_operation);
+	gtk_widget_show(user_data->dlg.draw_area_target);
+	gtk_widget_show(user_data->dlg.draw_area_comments);
+	gtk_widget_show(viewport_comments);
+
+	gtk_widget_show(scroll_window_comments);
+
+	gtk_box_pack_start(GTK_BOX(hbox), user_data->dlg.draw_area_framenum, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(hbox), user_data->dlg.draw_area_time, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(hbox), user_data->dlg.draw_area_icon, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(hbox), user_data->dlg.draw_area_initiator, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(hbox), user_data->dlg.draw_area_operation, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(hbox), user_data->dlg.draw_area_target, FALSE, FALSE, 0);
+
+	user_data->dlg.hpane = gtk_hpaned_new();
+	gtk_paned_pack2(GTK_PANED (user_data->dlg.hpane), scroll_window_comments, TRUE, TRUE);
+	g_signal_connect(user_data->dlg.hpane, "notify::position",  G_CALLBACK(pane_callback), user_data);
+	gtk_widget_show(user_data->dlg.hpane);
+
+	gtk_box_pack_start(GTK_BOX(hbox), user_data->dlg.hpane, TRUE, TRUE, 0);
+
+	/* create the associated v_scrollbar */
+	user_data->dlg.v_scrollbar_adjustment=(GtkAdjustment *)gtk_adjustment_new(0,0,0,0,0,0);
+	user_data->dlg.v_scrollbar=gtk_vscrollbar_new(user_data->dlg.v_scrollbar_adjustment);
+	gtk_widget_show(user_data->dlg.v_scrollbar);
+	gtk_box_pack_end(GTK_BOX(hbox), user_data->dlg.v_scrollbar, FALSE, FALSE, 0);
+	g_signal_connect(user_data->dlg.v_scrollbar_adjustment, "value_changed", G_CALLBACK(v_scrollbar_changed), user_data);
+
+	gtk_box_pack_start(GTK_BOX(box), hbox, TRUE, TRUE, 0);
+}
+
+/****************************************************************************/
+static void iscsiexpert_graph_create_window(iscsiexpert_graph_analysis_data_t* user_data)
+{
+	GtkWidget *vbox;
+	GtkWidget *hbuttonbox;
+	GtkTooltips *tooltips = gtk_tooltips_new();
+
+	user_data->dlg.window = scrolled_window_new(NULL, NULL);
+	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(user_data->dlg.window), GTK_SHADOW_IN);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(user_data->dlg.window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+	gtk_paned_pack1(GTK_PANED(user_data->dlg.parent_w),user_data->dlg.window,TRUE,TRUE);
+	gtk_widget_set_size_request(user_data->dlg.window, 450, 300);
+
+	vbox=gtk_vbox_new(FALSE, 0);
+	gtk_container_add(GTK_CONTAINER(user_data->dlg.window), vbox);
+	gtk_widget_show(vbox);
+
+	iscsiexpert_create_draw_area(user_data, vbox);
+
+	/* button row */
+	hbuttonbox = gtk_hbutton_box_new ();
+	gtk_box_pack_start (GTK_BOX (vbox), hbuttonbox, FALSE, FALSE, 0);
+	gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_SPREAD);
+	gtk_box_set_spacing (GTK_BOX (hbuttonbox), 30);
+	gtk_widget_show(hbuttonbox);
+
+	g_signal_connect(user_data->dlg.window, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
+	g_signal_connect(user_data->dlg.window, "destroy", G_CALLBACK(on_destroy), user_data);
+
+	gtk_widget_show(user_data->dlg.window);
+}
+
+
+/****************************************************************************/
+static void
+iscsiexpert_stat_drawarea(GtkWidget *paned)
+{
+	statui_data_combo.graph_analysis_data->dlg.parent_w = paned;
+
+	register_tap_listener("iscsiexpert", statui_data_combo.graph_analysis_data, NULL,
+			iscsiexpert_stat_reset,
+			iscsiexpert_stat_iscsi_packet,
+			iscsiexpert_stat_packet_draw
+			);
+	cf_retap_packets(&cfile, TRUE);
+
+	iscsiexpert_graph_create_window(statui_data_combo.graph_analysis_data);
+
+}
+
+static void iscsiexpert_init_tree(iscsiexpert_stat_data_t *etd, GtkWidget *hpaned,
+									 GTreeCallFunc call_func,gpointer * func_data)
+{
+	GtkTreeSelection * selection = NULL;
+	GtkWidget *tree_scrolled_window = etd->tree_scrolled_window;	
+	GtkTreeModel *model = NULL;
+	GtkWidget *view = NULL;
+
+	GHashTable *s_hash = NULL;
+	GHashTable *c_hash = NULL;
+	
+	view = tree_init(tree_scrolled_window, hpaned);
+	etd->iscsiexpert_session_list = NULL;
+
+	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
+	
+	//On changed function is used to relate the topology with the session/connection params
+	g_signal_connect(selection, "changed", G_CALLBACK(call_func), func_data);
+
+	s_hash = iscsiexpert_session_tv_info.session_hashlist;
+	c_hash = iscsiexpert_session_tv_info.conversation_hashlist;
+
+	if (s_hash == NULL && c_hash == NULL)
+	{
+		gtk_widget_show(view);	
+
+		return;		
+	}
+
+	if (s_hash)
+	{
+		g_hash_table_foreach(s_hash, (GHFunc)prepare_session_list, &etd->iscsiexpert_session_list);
+	}
+
+	/*fill the view with real data*/
+	model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
+	model = fill_model(model, etd->iscsiexpert_session_list);
+	gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
+
+	g_object_set_data(G_OBJECT(tree_scrolled_window), "sess_conn_tree", view);
+	gtk_tree_view_expand_all(GTK_TREE_VIEW(view));
+
+	gtk_widget_show(view);	
+
+	return;
+}
+
+
+void
+iscsiexpert_stat_init_tree(iscsiexpert_stat_data_t * etd, GtkWidget *hpaned)
+{
+	//GtkWidget * label;
+	//GtkWidget * label_box;
+	
+	etd->tree_scrolled_window = scrolled_window_new(NULL, NULL);
+	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(etd->tree_scrolled_window), GTK_SHADOW_IN);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(etd->tree_scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	gtk_widget_set_size_request(etd->tree_scrolled_window, 200, 300);
+
+	iscsiexpert_init_tree(etd, hpaned, on_changed,(gpointer)&statui_data_combo);
+	
+#if 0
+	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(etd->tree_scrolled_window), GTK_SHADOW_IN);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(etd->tree_scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+	gtk_paned_pack1(GTK_PANED(hpaned), etd->tree_scrolled_window,TRUE,TRUE);
+	gtk_widget_set_size_request(etd->tree_scrolled_window, 100, 100);
+
+	/* display label */
+	label_box = gtk_hbox_new(FALSE, 0);
+	//gtk_table_attach_defaults(GTK_TABLE(hpaned), label_box, 1, 2, 0, 1);
+	gtk_container_add(GTK_CONTAINER(etd->tree_scrolled_window), label_box);
+	gtk_widget_show(label_box);
+
+	label = gtk_label_new("This is topology tree view");
+	gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.0f);
+	gtk_box_pack_start(GTK_BOX(label_box), label, FALSE, FALSE, 0);
+
+	//g_signal_connect(gtk_tree_view_get_selection(GTK_SCROLLED_WINDOW(etd->tree_scrolled_window )),
+    //               "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
+#endif
+
+	g_object_set_data(G_OBJECT(etd->win), "tree_scrolled_window", etd->tree_scrolled_window);
+	
+	//gtk_widget_show(GTK_WIDGET(label));
+
+	gtk_widget_show(GTK_WIDGET(etd->tree_scrolled_window));
+
+}
+
+/* called when a tree row is (un)selected in the popup packet window */
+static void
+new_tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data)
+{
+    field_info   *finfo;
+    GtkWidget    *byte_view;
+    const guint8 *data;
+    guint         len;
+    GtkTreeModel *model;
+    GtkTreeIter   iter;
+
+    struct PacketWinData *DataPtr = (struct PacketWinData*)user_data;
+
+    /* if something is selected */
+    if (gtk_tree_selection_get_selected(sel, &model, &iter))
+    {
+        gtk_tree_model_get(model, &iter, 1, &finfo, -1);
+        if (!finfo) return;
+
+        set_notebook_page(DataPtr->bv_nb_ptr, finfo->ds_tvb);
+        byte_view = get_notebook_bv_ptr(DataPtr->bv_nb_ptr);
+        if (!byte_view)	/* exit if no hex window to write in */
+            return;
+
+        data = get_byte_view_data_and_length(byte_view, &len);
+        if (data == NULL) {
+            data = DataPtr->pd;
+            len =  DataPtr->frame->cap_len;
+        }
+
+        DataPtr->finfo_selected = finfo;
+        packet_hex_print(byte_view, data, DataPtr->frame, finfo, len);
+    }
+    else
+    {
+        DataPtr->finfo_selected = NULL;
+
+        byte_view = get_notebook_bv_ptr(DataPtr->bv_nb_ptr);
+        if (!byte_view)	/* exit if no hex window to write in */
+            return;
+
+        data = get_byte_view_data_and_length(byte_view, &len);
+        g_assert(data != NULL);
+        packet_hex_reprint(byte_view);
+    }
+}
+
+static gint
+button_press_handler(GtkWidget *widget, GdkEvent *event, gpointer data _U_)
+{
+  if (widget == NULL || event == NULL) {
+    return FALSE;
+  }
+
+  tree_view_select(widget, (GdkEventButton *) event);
+
+  /* GDK_2BUTTON_PRESS is a doubleclick -> expand/collapse tree row */
+  if (event->type == GDK_2BUTTON_PRESS) {
+    GtkTreePath      *path;
+
+    if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget),
+				      (gint) (((GdkEventButton *)event)->x),
+				      (gint) (((GdkEventButton *)event)->y),
+				      &path, NULL, NULL, NULL))
+    {
+      if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(widget), path)) {
+	gtk_tree_view_collapse_row(GTK_TREE_VIEW(widget), path);
+      }	else {
+	gtk_tree_view_expand_row(GTK_TREE_VIEW(widget), path, FALSE);
+      }
+      gtk_tree_path_free(path);
+    }
+  }
+
+  return FALSE;
+}
+
+static void
+destroy_new_window(GtkObject *object _U_, gpointer user_data)
+{
+  struct PacketWinData *DataPtr = user_data;
+
+  detail_windows = g_list_remove(detail_windows, DataPtr);
+  epan_dissect_free(DataPtr->edt);
+  g_free(DataPtr->pd);
+  g_free(DataPtr);
+}
+
+void
+iscsiexpert_stat_init_treeview(iscsiexpert_stat_data_t * etd, GtkWidget *hpaned)
+{
+  gint32 tv_size = 125;
+  gint bv_size = 75;
+  GtkWidget   *tree_view, *tv_scrollw,*bv_nb_ptr ;
+
+  if (!cfile.is_tempfile && !cfile.filename)
+  {
+	  return;
+  }
+
+    /* Allocate data structure to represent this window. */
+  DataPtr = (struct PacketWinData *) g_malloc(sizeof(struct PacketWinData));
+  DataPtr->frame = cfile.current_frame;
+  memcpy(&DataPtr->pseudo_header, &cfile.pseudo_header, sizeof DataPtr->pseudo_header);
+  DataPtr->pd = g_malloc(DataPtr->frame->cap_len);
+  memcpy(DataPtr->pd, cfile.pd, DataPtr->frame->cap_len);
+  DataPtr->edt = epan_dissect_new(TRUE, TRUE);
+  epan_dissect_run(DataPtr->edt, &DataPtr->pseudo_header, DataPtr->pd,
+          DataPtr->frame, &cfile.cinfo);
+  epan_dissect_fill_in_columns(DataPtr->edt);
+
+  /* Tree view */
+  tv_scrollw = main_tree_view_new(&prefs, &tree_view);
+  gtk_paned_pack1(GTK_PANED(hpaned), tv_scrollw, TRUE, TRUE);
+  gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
+  gtk_widget_show(tv_scrollw);
+  gtk_widget_show(tree_view);
+
+  //* Byte view */
+  bv_nb_ptr = byte_view_new();
+  gtk_paned_pack2(GTK_PANED(hpaned), bv_nb_ptr, FALSE, FALSE);
+  gtk_widget_set_size_request(bv_nb_ptr, -1, bv_size);
+  gtk_widget_show(bv_nb_ptr);
+
+  DataPtr->main = hpaned;
+  DataPtr->tv_scrollw = tv_scrollw;
+  DataPtr->tree_view = tree_view;
+  DataPtr->bv_nb_ptr = bv_nb_ptr;
+  detail_windows = g_list_append(detail_windows, DataPtr);
+
+  /* load callback handlers */
+  g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)),
+                 "changed", G_CALLBACK(new_tree_view_selection_changed_cb), DataPtr);
+  g_signal_connect(tree_view, "button_press_event", G_CALLBACK(button_press_handler), NULL);
+  g_signal_connect(tree_view, "destroy", G_CALLBACK(destroy_new_window), DataPtr);
+
+  /* draw the protocol tree & print hex data */
+  add_byte_views(DataPtr->edt, tree_view, DataPtr->bv_nb_ptr);
+  proto_tree_draw(DataPtr->edt->tree, tree_view);
+
+  DataPtr->finfo_selected = NULL;
+  gtk_widget_show(DataPtr->main);
+
+}
+
+void
+iscsiexpert_stat_init_statinfo(iscsiexpert_stat_data_t * etd, GtkWidget *hpaned)
+{
+	GtkWidget *list_box;
+	//GtkWidget *parameter_list = NULL;
+	GtkCellRenderer *renderer = NULL;
+	GtkTreeViewColumn *column = NULL;
+	GtkListStore *store = NULL;
+	GtkWidget *hscrollbar = NULL;
+	GtkWidget *vscrollbar = NULL;
+	gint i = 0;
+	const char *default_titles[] = { "Key Name", "Value" };
+
+	etd->iscsi_parameter_window = scrolled_window_new(NULL, NULL);
+	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(etd->iscsi_parameter_window), GTK_SHADOW_IN);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(etd->iscsi_parameter_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	gtk_paned_pack2(GTK_PANED(hpaned), etd->iscsi_parameter_window,TRUE,TRUE);
+
+	list_box = gtk_hbox_new(FALSE, 0);
+	gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(etd->iscsi_parameter_window), list_box);
+	gtk_container_add(GTK_CONTAINER(etd->iscsi_parameter_window), list_box);
+	gtk_widget_show(list_box);
+
+	statui_data_combo.statitics_info_data->dlg.iscsi_parameter_list = gtk_tree_view_new();
+	//gtk_tree_view_columns_autosize (GTK_TREE_VIEW(parameter_list));
+	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(statui_data_combo.statitics_info_data->dlg.iscsi_parameter_list ), TRUE);
+	gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW(statui_data_combo.statitics_info_data->dlg.iscsi_parameter_list ), TRUE);
+
+	gtk_box_pack_start(GTK_BOX(list_box), statui_data_combo.statitics_info_data->dlg.iscsi_parameter_list, TRUE, TRUE, 2);
+	
+	/*Key*/
+	renderer = gtk_cell_renderer_text_new();
+	column = gtk_tree_view_column_new_with_attributes(default_titles[0],
+													  renderer, "text", KEY_COLUMN, NULL);
+	gtk_tree_view_column_set_spacing(column, 5);
+	gtk_tree_view_column_set_resizable(column, TRUE);
+	gtk_tree_view_column_set_min_width(column, 100);
+	gtk_tree_view_append_column(GTK_TREE_VIEW(statui_data_combo.statitics_info_data->dlg.iscsi_parameter_list), column);
+
+	/*Value*/
+	renderer = gtk_cell_renderer_text_new();
+	column = gtk_tree_view_column_new_with_attributes(default_titles[1],
+													  renderer, "text", VALUE_COLUMN, NULL);
+	gtk_tree_view_column_set_spacing(column, 5);
+	gtk_tree_view_column_set_resizable(column, TRUE);
+	gtk_tree_view_column_set_min_width(column, 100);	
+	gtk_tree_view_append_column(GTK_TREE_VIEW(statui_data_combo.statitics_info_data->dlg.iscsi_parameter_list), column);
+
+	store = gtk_list_store_new(PARAMETER_NUM_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+	gtk_tree_view_set_model(GTK_TREE_VIEW(statui_data_combo.statitics_info_data->dlg.iscsi_parameter_list), GTK_TREE_MODEL(store));
+	
+	if (!cfile.is_tempfile && !cfile.filename)
+	{
+		add_parameter_to_list(statui_data_combo.statitics_info_data->dlg.iscsi_parameter_list, "There is no iscsi session/connection","");
+	}
+
+	gtk_tree_view_set_model(GTK_TREE_VIEW(statui_data_combo.statitics_info_data->dlg.iscsi_parameter_list), GTK_TREE_MODEL(store));
+	gtk_box_pack_start(GTK_BOX(list_box), statui_data_combo.statitics_info_data->dlg.iscsi_parameter_list, FALSE, FALSE, 0);
+	gtk_widget_show(GTK_WIDGET(statui_data_combo.statitics_info_data->dlg.iscsi_parameter_list));
+	//g_object_set_data(G_OBJECT(iscsi_parameter_window), "parameter_list", parameter_list);
+
+}
+
+void
+iscsiexpert_stat_init_iscsiparameter(iscsiexpert_stat_data_t * etd, GtkWidget *hpaned)
+{
+    GtkWidget *parameter_list = NULL;
+    gboolean openfile;
+    
+	etd->iscsi_parameter_window = scrolled_window_new(NULL, NULL);
+	openfile = iscsiexpert_init_parameter(etd->iscsi_parameter_window, hpaned);
+
+	g_object_set_data(G_OBJECT(etd->win), "iscsi_parameter_window", etd->iscsi_parameter_window);
+    parameter_list = g_object_get_data(G_OBJECT(etd->iscsi_parameter_window), "parameter_list");
+
+    if(openfile == TRUE && etd->iscsiexpert_session_list == NULL){
+        display_param_in_list(parameter_list, NULL, NULL, -3);
+    }
+
+	gtk_widget_show(GTK_WIDGET(etd->iscsi_parameter_window));
+
+}
+
+void
+iscsiexpert_stat_init_statview(iscsiexpert_stat_data_t * etd, GtkWidget *main_vb,GtkWidget *hpaned)
+{
+	GtkWidget * stat_graph_label;
+	GtkWidget *	stat_graph_hbox;
+	GtkWidget * stat_graph_hpaned;
+
+	GtkWidget * stat_statinfo_label;
+	GtkWidget *	stat_statinfo_hbox;
+	GtkWidget * stat_statinfo_hpaned;
+
+	/* initialize iscsi pixmap array*/
+	iscsiexpert_icon_init(etd->win);
+
+	etd->stat_notebook_window = gtk_notebook_new();
+    gtk_paned_pack2(GTK_PANED(hpaned), etd->stat_notebook_window, TRUE, TRUE);
+	
+	stat_graph_label = gtk_label_new("iSCSI Flow Analyzer");
+    gtk_widget_show(stat_graph_label);
+
+	stat_graph_hbox = gtk_hbox_new(FALSE, 0);
+	gtk_notebook_append_page(GTK_NOTEBOOK(etd->stat_notebook_window), stat_graph_hbox, stat_graph_label);
+
+	stat_graph_hpaned = gtk_vpaned_new();
+	gtk_box_pack_start(GTK_BOX(stat_graph_hbox), stat_graph_hpaned, TRUE, TRUE, 0);
+	//gtk_paned_set_position(GTK_PANED(stat_graph_hbox), 650);
+
+	iscsiexpert_stat_drawarea(stat_graph_hpaned);
+
+	stat_statinfo_label = gtk_label_new("iSCSI Statistics Info");
+    gtk_widget_show(stat_statinfo_label);
+
+	stat_statinfo_hbox = gtk_hbox_new(FALSE, 0);
+	gtk_notebook_append_page(GTK_NOTEBOOK(etd->stat_notebook_window), stat_statinfo_hbox, stat_statinfo_label);
+
+	stat_statinfo_hpaned = gtk_vpaned_new();
+
+	gtk_box_pack_start(GTK_BOX(stat_statinfo_hbox), stat_statinfo_hpaned, TRUE, TRUE, 0);
+	//gtk_paned_set_position(GTK_PANED(stat_statinfo_hpaned), 200);
+
+	iscsiexpert_stat_init_statinfo(etd, stat_statinfo_hpaned);
+
+	gtk_widget_show(GTK_WIDGET(etd->stat_notebook_window));
+}
+
+
+
+/****************************************************************************/
+/* INTERFACE                                                                */
+/****************************************************************************/
+
+static void iscsiexpert_stat_dlg_create_windows (iscsiexpert_graph_analysis_data_t* user_data,
+												 iscsiexpert_statitics_info_data_t *statitics_info_data)
+{
+
+	iscsiexpert_stat_data_t * etd;
+
+	GtkWidget *main_vb;
+	GtkWidget *hbuttonbox;
+	GtkWidget *bt_close;
+
+	GtkWidget *hbox;
+	GtkWidget *hpaned;
+
+	GtkWidget * main_nb;
+	GtkWidget * packet_detail_label;
+	GtkWidget *	packet_detail_hbox;
+	GtkWidget * packet_detail_hpaned;
+
+	GtkWidget * iscsi_parameter_label;
+	GtkWidget *	iscsi_parameter_hbox;
+	GtkWidget * iscsi_parameter_hpaned;
+
+	GtkWidget *top_label = NULL;
+
+	GtkTooltips *tooltips = gtk_tooltips_new();
+
+	etd=g_malloc(sizeof(iscsiexpert_stat_data_t));
+	user_data->etd = etd;
+	etd->win = dlg_window_new("Wireshark: iSCSI Expert Statistics");  /* transient_for top_level */
+	gtk_window_set_destroy_with_parent (GTK_WINDOW(etd->win), TRUE);
+
+	gtk_window_set_default_size(GTK_WINDOW(etd->win), 650, 500);
+
+	/***************************   Whole Frame of Components **********************/
+	main_vb = gtk_vbox_new (FALSE, 0);
+	gtk_container_add(GTK_CONTAINER(etd->win), main_vb);
+	gtk_container_set_border_width (GTK_CONTAINER (main_vb), 7);
+
+	top_label = gtk_label_new ("iSCSI Expert Statistics Information");
+	gtk_box_pack_start (GTK_BOX (main_vb), top_label, FALSE, FALSE, 8);
+
+	/***************************   Initiator-Target and Expert Result **********************/
+
+	hbox = gtk_hbox_new(FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(main_vb), hbox, TRUE, TRUE, 0);
+
+	hpaned = gtk_hpaned_new();
+	gtk_box_pack_start(GTK_BOX(hbox), hpaned, TRUE, TRUE, 0);
+	gtk_paned_set_position(GTK_PANED(hpaned), 150);
+
+	/*session/connection topology tree view*/
+	iscsiexpert_stat_init_tree(etd, hpaned);
+
+	iscsiexpert_stat_init_statview(etd,main_vb,hpaned);
+
+	/***************************   Packet Detail Panel and iSCSI Parameter Panel **********************/
+
+	main_nb = gtk_notebook_new();
+    gtk_box_pack_start(GTK_BOX(main_vb), main_nb, TRUE, TRUE, 0);
+
+	packet_detail_label = gtk_label_new("Packet Detail");
+    gtk_widget_show(packet_detail_label);
+
+	packet_detail_hbox = gtk_hbox_new(FALSE, 0);
+	gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), packet_detail_hbox, packet_detail_label);
+
+	packet_detail_hpaned = gtk_vpaned_new();
+	gtk_box_pack_start(GTK_BOX(packet_detail_hbox), packet_detail_hpaned, TRUE, TRUE, 0);
+	gtk_paned_set_position(GTK_PANED(packet_detail_hbox), 200);
+
+	iscsiexpert_stat_init_treeview(etd, packet_detail_hpaned);
+
+	iscsi_parameter_label = gtk_label_new("iSCSI Parameter");
+    gtk_widget_show(iscsi_parameter_label);
+
+	iscsi_parameter_hbox = gtk_hbox_new(FALSE, 0);
+	gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), iscsi_parameter_hbox, iscsi_parameter_label);
+
+	iscsi_parameter_hpaned = gtk_vpaned_new();
+
+	gtk_box_pack_start(GTK_BOX(iscsi_parameter_hbox), iscsi_parameter_hpaned, TRUE, TRUE, 0);
+	gtk_paned_set_position(GTK_PANED(iscsi_parameter_hpaned), 200);
+
+	iscsiexpert_stat_init_iscsiparameter(etd, iscsi_parameter_hpaned);
+
+	/*select a session/connection*/
+	select_sess_item(g_object_get_data(G_OBJECT(etd->tree_scrolled_window), "sess_conn_tree"), 
+	                 etd->iscsiexpert_session_list);
+	
+	/* button row */
+	//hbuttonbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
+	//gtk_box_pack_end(GTK_BOX(main_vb), hbuttonbox, FALSE, FALSE, 0);
+	//bt_close = g_object_get_data(G_OBJECT(hbuttonbox), GTK_STOCK_CLOSE);
+	//gtk_tooltips_set_tip (tooltips, bt_close, "Close this window", NULL);
+	//window_set_cancel_button(etd->win, bt_close, window_cancel_button_cb);
+
+	hbuttonbox = gtk_hbutton_box_new ();
+
+	gtk_box_pack_start (GTK_BOX (main_vb), hbuttonbox, FALSE, FALSE, 5);
+	
+	gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_SPREAD);
+	gtk_box_set_spacing (GTK_BOX (hbuttonbox), 30);
+
+	bt_close = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
+	gtk_container_add (GTK_CONTAINER (hbuttonbox), bt_close);
+	GTK_WIDGET_SET_FLAGS(bt_close, GTK_CAN_DEFAULT);
+	gtk_tooltips_set_tip (tooltips, bt_close, "Close this window", NULL);
+	window_set_cancel_button(etd->win, bt_close, window_cancel_button_cb);
+
+	g_signal_connect(etd->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
+	g_signal_connect(etd->win, "destroy", G_CALLBACK(iscsiexpert_stat_on_destroy), user_data);
+
+	gtk_widget_show_all(etd->win);
+	window_present(etd->win);
+
+	/* This will bring up the progress bar
+	 * Put our window back in front
+	 */
+	gdk_window_raise(etd->win->window);
+}
+
+
+/****************************************************************************/
+void iscsiexpert_stat_dlg_create(iscsiexpert_graph_analysis_data_t* user_data,
+								 iscsiexpert_statitics_info_data_t *statitics_info_data)
+{
+	/* reset the data */
+	iscsiexpert_graph_analysis_reset(user_data);
+	iscsiexpert_statitics_info_reset(statitics_info_data);
+
+	/* create the graph windows */
+	iscsiexpert_stat_dlg_create_windows(user_data,statitics_info_data);
+
+	/* redraw the graph */
+	iscsiexpert_dialog_graph_redraw(user_data);
+	iscsiexpert_statitics_info_redraw(statitics_info_data);
+
+	return;
+}
+
+
+
+/****************************************************************************/
+static iscsiexpert_graph_analysis_data_t* iscsiexpert_stat_graph_analysis_init(void)
+{
+	iscsiexpert_graph_analysis_data_t* user_data;
+	/* init */
+	user_data = g_malloc(sizeof(iscsiexpert_graph_analysis_data_t));
+
+	/* init user_data */
+	iscsiexpert_graph_analysis_init_dlg(user_data);
+
+	return user_data;
+}
+
+
+static void
+iscsiexpert_stat_init_tap(const char *dummy _U_, void* userdata _U_)
+{
+	/* initialize graph items store */
+	iscsiexpert_stat_data_init();
+
+	/* init the Graph Analysys */
+	statui_data_combo.graph_analysis_data = iscsiexpert_stat_graph_analysis_init();
+	statui_data_combo.graph_analysis_data->graph_info = graph_analysis;
+
+	/* init */
+	statui_data_combo.statitics_info_data	= g_malloc(sizeof(iscsiexpert_graph_analysis_data_t));
+	statui_data_combo.statitics_info_data->stat_info = statitics_info;
+
+	iscsiexpert_stat_dlg_create(statui_data_combo.graph_analysis_data,statui_data_combo.statitics_info_data);
+}
+
+
+/****************************************************************************/
+/* entry point when called via the GTK menu */
+static void iscsiexpert_stat_launch(GtkWidget *w _U_, gpointer data _U_)
+{
+	iscsiexpert_stat_init_tap("",NULL);
+}
+
+/****************************************************************************/
+void
+register_tap_listener_iscsiexpert_stat(void)
+{
+	register_stat_cmd_arg("iSCSI Expert Statistics Info",iscsiexpert_stat_init_tap,NULL);
+	register_stat_menu_item_stock("iSCSI Expert Statistics Info",
+        REGISTER_STAT_GROUP_UNSORTED, WIRESHARK_STOCK_EXPERT_INFO,
+	    iscsiexpert_stat_launch, NULL, NULL, NULL);
+}
+
diff -urN wireshark-1.2.2/image/expert_chat.xpm wireshark-1.2.2-iscsie/image/expert_chat.xpm
--- wireshark-1.2.2/image/expert_chat.xpm	2009-09-15 09:46:52.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/expert_chat.xpm	2009-11-26 16:35:37.000000000 +0800
@@ -1,88 +1,88 @@
-/* XPM */
-static const char * expert_chat_xpm[] = {
-"14 14 71 1",
-" 	c None",
-".	c #191919",
-"+	c #1A1A1A",
-"@	c #101010",
-"#	c #0D0D0D",
-"$	c #0A0A0A",
-"%	c #282828",
-"&	c #6E6E6E",
-"*	c #969696",
-"=	c #A7A7A7",
-"-	c #A2A2A2",
-";	c #848484",
-">	c #535353",
-",	c #0B0B0B",
-"'	c #3E3E3E",
-")	c #AAAAAA",
-"!	c #C5C5C5",
-"~	c #C9C9C9",
-"{	c #B8B8B8",
-"]	c #9F9F9F",
-"^	c #838383",
-"/	c #121212",
-"(	c #313131",
-"_	c #ACACAC",
-":	c #D1D1D1",
-"<	c #DFDFDF",
-"[	c #E3E3E3",
-"}	c #DEDEDE",
-"|	c #CFCFCF",
-"1	c #BABABA",
-"2	c #9D9D9D",
-"3	c #818181",
-"4	c #212121",
-"5	c #747474",
-"6	c #C7C7C7",
-"7	c #EAEAEA",
-"8	c #EDEDED",
-"9	c #E9E9E9",
-"0	c #DCDCDC",
-"a	c #9E9E9E",
-"b	c #9A9A9A",
-"c	c #505050",
-"d	c #080808",
-"e	c #1F1F1F",
-"f	c #979797",
-"g	c #C6C6C6",
-"h	c #DDDDDD",
-"i	c #ECECEC",
-"j	c #C4C4C4",
-"k	c #7D7D7D",
-"l	c #0E0E0E",
-"m	c #111111",
-"n	c #A4A4A4",
-"o	c #E0E0E0",
-"p	c #DBDBDB",
-"q	c #CDCDCD",
-"r	c #A6A6A6",
-"s	c #9C9C9C",
-"t	c #999999",
-"u	c #0C0C0C",
-"v	c #A9A9A9",
-"w	c #B7B7B7",
-"x	c #C2C2C2",
-"y	c #C1C1C1",
-"z	c #B6B6B6",
-"A	c #A8A8A8",
-"B	c #0F0F0F",
-"C	c #7F7F7F",
-"D	c #A3A3A3",
-"E	c #515151",
-"F	c #9B9B9B",
-"    .+@#@$    ",
-"   %&*=-;>,   ",
-"  ')!~!{)]^/  ",
-" (_:<[}|1=23$ ",
-"456}7890!_abcd",
-"efgh9i90j_abkl",
-"mn1|0opq{rst*d",
-"usvwxgyzAabt*d",
-"BCaDA)AD2bttkl",
-"dEbFsssFbtttcd",
-" $3tttttttt3$ ",
-"  /3tttttt3/  ",
-"   $ck**kc$   ",
-"    dlddld    "};
+/* XPM */
+static const char * expert_chat_xpm[] = {
+"14 14 71 1",
+" 	c None",
+".	c #191919",
+"+	c #1A1A1A",
+"@	c #101010",
+"#	c #0D0D0D",
+"$	c #0A0A0A",
+"%	c #282828",
+"&	c #6E6E6E",
+"*	c #969696",
+"=	c #A7A7A7",
+"-	c #A2A2A2",
+";	c #848484",
+">	c #535353",
+",	c #0B0B0B",
+"'	c #3E3E3E",
+")	c #AAAAAA",
+"!	c #C5C5C5",
+"~	c #C9C9C9",
+"{	c #B8B8B8",
+"]	c #9F9F9F",
+"^	c #838383",
+"/	c #121212",
+"(	c #313131",
+"_	c #ACACAC",
+":	c #D1D1D1",
+"<	c #DFDFDF",
+"[	c #E3E3E3",
+"}	c #DEDEDE",
+"|	c #CFCFCF",
+"1	c #BABABA",
+"2	c #9D9D9D",
+"3	c #818181",
+"4	c #212121",
+"5	c #747474",
+"6	c #C7C7C7",
+"7	c #EAEAEA",
+"8	c #EDEDED",
+"9	c #E9E9E9",
+"0	c #DCDCDC",
+"a	c #9E9E9E",
+"b	c #9A9A9A",
+"c	c #505050",
+"d	c #080808",
+"e	c #1F1F1F",
+"f	c #979797",
+"g	c #C6C6C6",
+"h	c #DDDDDD",
+"i	c #ECECEC",
+"j	c #C4C4C4",
+"k	c #7D7D7D",
+"l	c #0E0E0E",
+"m	c #111111",
+"n	c #A4A4A4",
+"o	c #E0E0E0",
+"p	c #DBDBDB",
+"q	c #CDCDCD",
+"r	c #A6A6A6",
+"s	c #9C9C9C",
+"t	c #999999",
+"u	c #0C0C0C",
+"v	c #A9A9A9",
+"w	c #B7B7B7",
+"x	c #C2C2C2",
+"y	c #C1C1C1",
+"z	c #B6B6B6",
+"A	c #A8A8A8",
+"B	c #0F0F0F",
+"C	c #7F7F7F",
+"D	c #A3A3A3",
+"E	c #515151",
+"F	c #9B9B9B",
+"    .+@#@$    ",
+"   %&*=-;>,   ",
+"  ')!~!{)]^/  ",
+" (_:<[}|1=23$ ",
+"456}7890!_abcd",
+"efgh9i90j_abkl",
+"mn1|0opq{rst*d",
+"usvwxgyzAabt*d",
+"BCaDA)AD2bttkl",
+"dEbFsssFbtttcd",
+" $3tttttttt3$ ",
+"  /3tttttt3/  ",
+"   $ck**kc$   ",
+"    dlddld    "};
diff -urN wireshark-1.2.2/image/expert_error.xpm wireshark-1.2.2-iscsie/image/expert_error.xpm
--- wireshark-1.2.2/image/expert_error.xpm	2009-09-15 09:46:52.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/expert_error.xpm	2009-11-26 16:35:37.000000000 +0800
@@ -1,112 +1,112 @@
-/* XPM */
-static const char * expert_error_xpm[] = {
-"14 14 95 2",
-"  	c None",
-". 	c #1D1111",
-"+ 	c #230D0D",
-"@ 	c #160808",
-"# 	c #130505",
-"$ 	c #1A0303",
-"% 	c #0F0202",
-"& 	c #2F2020",
-"* 	c #9A2C2C",
-"= 	c #DA3131",
-"- 	c #FB2A2A",
-"; 	c #FB1C1C",
-"> 	c #D30D0D",
-", 	c #870404",
-"' 	c #120101",
-") 	c #482F2F",
-"! 	c #E45252",
-"~ 	c #FF6F6F",
-"{ 	c #FF7979",
-"] 	c #FF6D6D",
-"^ 	c #FF4E4E",
-"/ 	c #FF2A2A",
-"( 	c #FF1010",
-"_ 	c #D80404",
-": 	c #1E0000",
-"< 	c #372828",
-"[ 	c #E55858",
-"} 	c #FF8C8C",
-"| 	c #FFAEAE",
-"1 	c #FFB8B8",
-"2 	c #FFACAC",
-"3 	c #FF8888",
-"4 	c #FF5353",
-"5 	c #FF2222",
-"6 	c #FF0909",
-"7 	c #D70101",
-"8 	c #110000",
-"9 	c #261A1A",
-"0 	c #9E3535",
-"a 	c #FF7373",
-"b 	c #FFADAD",
-"c 	c #FFCACA",
-"d 	c #FFD1D1",
-"e 	c #FFC9C9",
-"f 	c #FFA8A8",
-"g 	c #FF6E6E",
-"h 	c #FF3030",
-"i 	c #FF0D0D",
-"j 	c #FF0202",
-"k 	c #850000",
-"l 	c #0D0000",
-"m 	c #281212",
-"n 	c #DA3333",
-"o 	c #FF7171",
-"p 	c #FFABAB",
-"q 	c #FFD0D0",
-"r 	c #FFC7C7",
-"s 	c #FFA7A7",
-"t 	c #FF6C6C",
-"u 	c #FF2F2F",
-"v 	c #FF0C0C",
-"w 	c #D10000",
-"x 	c #180000",
-"y 	c #170A0A",
-"z 	c #FB2323",
-"A 	c #FF8686",
-"B 	c #FFB2B2",
-"C 	c #FFA6A6",
-"D 	c #FF8383",
-"E 	c #FF2020",
-"F 	c #FF0808",
-"G 	c #FF0101",
-"H 	c #FA0000",
-"I 	c #0E0000",
-"J 	c #120404",
-"K 	c #FA0F0F",
-"L 	c #FF2828",
-"M 	c #FF4A4A",
-"N 	c #FF6666",
-"O 	c #FF6565",
-"P 	c #FF4848",
-"Q 	c #FF2626",
-"R 	c #FF0303",
-"S 	c #FF0000",
-"T 	c #190101",
-"U 	c #D20404",
-"V 	c #FF1919",
-"W 	c #FF2B2B",
-"X 	c #FF2525",
-"Y 	c #FF1818",
-"Z 	c #FF0B0B",
-"` 	c #850101",
-" .	c #FF0404",
-"..	c #FF0707",
-"+.	c #D70000",
-"        . + @ # $ %         ",
-"      & * = - ; > , '       ",
-"    ) ! ~ { ] ^ / ( _ :     ",
-"  < [ } | 1 2 3 4 5 6 7 8   ",
-"9 0 a b c d e f g h i j k l ",
-"m n o p e q r s t u v j w x ",
-"y z 4 A f B C D ^ E F G H I ",
-"J K L M N o O P Q i R S H I ",
-"T U v V Q W X Y Z R G S w x ",
-"l ` j  ...F .. .j S S S k l ",
-"  8 +.S G G G S S S S +.8   ",
-"    : +.S S S S S S +.:     ",
-"      8 k w H H w k 8       ",
-"        l x I I x l         "};
+/* XPM */
+static const char * expert_error_xpm[] = {
+"14 14 95 2",
+"  	c None",
+". 	c #1D1111",
+"+ 	c #230D0D",
+"@ 	c #160808",
+"# 	c #130505",
+"$ 	c #1A0303",
+"% 	c #0F0202",
+"& 	c #2F2020",
+"* 	c #9A2C2C",
+"= 	c #DA3131",
+"- 	c #FB2A2A",
+"; 	c #FB1C1C",
+"> 	c #D30D0D",
+", 	c #870404",
+"' 	c #120101",
+") 	c #482F2F",
+"! 	c #E45252",
+"~ 	c #FF6F6F",
+"{ 	c #FF7979",
+"] 	c #FF6D6D",
+"^ 	c #FF4E4E",
+"/ 	c #FF2A2A",
+"( 	c #FF1010",
+"_ 	c #D80404",
+": 	c #1E0000",
+"< 	c #372828",
+"[ 	c #E55858",
+"} 	c #FF8C8C",
+"| 	c #FFAEAE",
+"1 	c #FFB8B8",
+"2 	c #FFACAC",
+"3 	c #FF8888",
+"4 	c #FF5353",
+"5 	c #FF2222",
+"6 	c #FF0909",
+"7 	c #D70101",
+"8 	c #110000",
+"9 	c #261A1A",
+"0 	c #9E3535",
+"a 	c #FF7373",
+"b 	c #FFADAD",
+"c 	c #FFCACA",
+"d 	c #FFD1D1",
+"e 	c #FFC9C9",
+"f 	c #FFA8A8",
+"g 	c #FF6E6E",
+"h 	c #FF3030",
+"i 	c #FF0D0D",
+"j 	c #FF0202",
+"k 	c #850000",
+"l 	c #0D0000",
+"m 	c #281212",
+"n 	c #DA3333",
+"o 	c #FF7171",
+"p 	c #FFABAB",
+"q 	c #FFD0D0",
+"r 	c #FFC7C7",
+"s 	c #FFA7A7",
+"t 	c #FF6C6C",
+"u 	c #FF2F2F",
+"v 	c #FF0C0C",
+"w 	c #D10000",
+"x 	c #180000",
+"y 	c #170A0A",
+"z 	c #FB2323",
+"A 	c #FF8686",
+"B 	c #FFB2B2",
+"C 	c #FFA6A6",
+"D 	c #FF8383",
+"E 	c #FF2020",
+"F 	c #FF0808",
+"G 	c #FF0101",
+"H 	c #FA0000",
+"I 	c #0E0000",
+"J 	c #120404",
+"K 	c #FA0F0F",
+"L 	c #FF2828",
+"M 	c #FF4A4A",
+"N 	c #FF6666",
+"O 	c #FF6565",
+"P 	c #FF4848",
+"Q 	c #FF2626",
+"R 	c #FF0303",
+"S 	c #FF0000",
+"T 	c #190101",
+"U 	c #D20404",
+"V 	c #FF1919",
+"W 	c #FF2B2B",
+"X 	c #FF2525",
+"Y 	c #FF1818",
+"Z 	c #FF0B0B",
+"` 	c #850101",
+" .	c #FF0404",
+"..	c #FF0707",
+"+.	c #D70000",
+"        . + @ # $ %         ",
+"      & * = - ; > , '       ",
+"    ) ! ~ { ] ^ / ( _ :     ",
+"  < [ } | 1 2 3 4 5 6 7 8   ",
+"9 0 a b c d e f g h i j k l ",
+"m n o p e q r s t u v j w x ",
+"y z 4 A f B C D ^ E F G H I ",
+"J K L M N o O P Q i R S H I ",
+"T U v V Q W X Y Z R G S w x ",
+"l ` j  ...F .. .j S S S k l ",
+"  8 +.S G G G S S S S +.8   ",
+"    : +.S S S S S S +.:     ",
+"      8 k w H H w k 8       ",
+"        l x I I x l         "};
diff -urN wireshark-1.2.2/image/expert_none.xpm wireshark-1.2.2-iscsie/image/expert_none.xpm
--- wireshark-1.2.2/image/expert_none.xpm	2009-09-15 09:46:52.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/expert_none.xpm	2009-11-26 16:35:37.000000000 +0800
@@ -1,19 +1,19 @@
-/* XPM */
-static const char * expert_none_xpm[] = {
-"14 14 2 1",
-" 	c None",
-".	c #000000",
-"    ......    ",
-"   ..    ..   ",
-"  .        .  ",
-" .          . ",
-"..          ..",
-".            .",
-".            .",
-".            .",
-".            .",
-"..          ..",
-" .          . ",
-"  .        .  ",
-"   ..    ..   ",
-"    ......    "};
+/* XPM */
+static const char * expert_none_xpm[] = {
+"14 14 2 1",
+" 	c None",
+".	c #000000",
+"    ......    ",
+"   ..    ..   ",
+"  .        .  ",
+" .          . ",
+"..          ..",
+".            .",
+".            .",
+".            .",
+".            .",
+"..          ..",
+" .          . ",
+"  .        .  ",
+"   ..    ..   ",
+"    ......    "};
diff -urN wireshark-1.2.2/image/expert_note.xpm wireshark-1.2.2-iscsie/image/expert_note.xpm
--- wireshark-1.2.2/image/expert_note.xpm	2009-09-15 09:46:52.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/expert_note.xpm	2009-11-26 16:35:37.000000000 +0800
@@ -1,115 +1,115 @@
-/* XPM */
-static const char * expert_note_xpm[] = {
-"14 14 98 2",
-"  	c None",
-". 	c #131F1F",
-"+ 	c #0E2525",
-"@ 	c #0B1818",
-"# 	c #061414",
-"$ 	c #041B1B",
-"% 	c #020F0F",
-"& 	c #253434",
-"* 	c #349E9E",
-"= 	c #39DBDB",
-"- 	c #32FBFB",
-"; 	c #20FBFB",
-"> 	c #0FD4D4",
-", 	c #058787",
-"' 	c #011212",
-") 	c #384F4F",
-"! 	c #60E6E6",
-"~ 	c #82FFFF",
-"{ 	c #8EFFFF",
-"] 	c #80FFFF",
-"^ 	c #5CFFFF",
-"/ 	c #31FFFF",
-"( 	c #12FFFF",
-"_ 	c #04D8D8",
-": 	c #001E1E",
-"< 	c #303E3E",
-"[ 	c #66E7E7",
-"} 	c #A4FFFF",
-"| 	c #CCFFFF",
-"1 	c #D7FFFF",
-"2 	c #C9FFFF",
-"3 	c #9FFFFF",
-"4 	c #60FFFF",
-"5 	c #28FFFF",
-"6 	c #0AFFFF",
-"7 	c #01D7D7",
-"8 	c #001111",
-"9 	c #1E2929",
-"0 	c #3EA3A3",
-"a 	c #86FFFF",
-"b 	c #CAFFFF",
-"c 	c #EDFFFF",
-"d 	c #F5FFFF",
-"e 	c #EBFFFF",
-"f 	c #C5FFFF",
-"g 	c #38FFFF",
-"h 	c #0FFFFF",
-"i 	c #02FFFF",
-"j 	c #008585",
-"k 	c #000D0D",
-"l 	c #142A2A",
-"m 	c #3BDCDC",
-"n 	c #84FFFF",
-"o 	c #C8FFFF",
-"p 	c #F4FFFF",
-"q 	c #E9FFFF",
-"r 	c #C3FFFF",
-"s 	c #7EFFFF",
-"t 	c #36FFFF",
-"u 	c #0EFFFF",
-"v 	c #00D1D1",
-"w 	c #001818",
-"x 	c #0C1919",
-"y 	c #28FBFB",
-"z 	c #61FFFF",
-"A 	c #9DFFFF",
-"B 	c #D1FFFF",
-"C 	c #C2FFFF",
-"D 	c #99FFFF",
-"E 	c #5BFFFF",
-"F 	c #25FFFF",
-"G 	c #09FFFF",
-"H 	c #01FFFF",
-"I 	c #00FAFA",
-"J 	c #000E0E",
-"K 	c #041212",
-"L 	c #12FAFA",
-"M 	c #2FFFFF",
-"N 	c #57FFFF",
-"O 	c #78FFFF",
-"P 	c #76FFFF",
-"Q 	c #54FFFF",
-"R 	c #2CFFFF",
-"S 	c #10FFFF",
-"T 	c #04FFFF",
-"U 	c #00FFFF",
-"V 	c #011919",
-"W 	c #04D2D2",
-"X 	c #1DFFFF",
-"Y 	c #2DFFFF",
-"Z 	c #33FFFF",
-"` 	c #2BFFFF",
-" .	c #1CFFFF",
-"..	c #0DFFFF",
-"+.	c #018585",
-"@.	c #05FFFF",
-"#.	c #08FFFF",
-"$.	c #00D7D7",
-"        . + @ # $ %         ",
-"      & * = - ; > , '       ",
-"    ) ! ~ { ] ^ / ( _ :     ",
-"  < [ } | 1 2 3 4 5 6 7 8   ",
-"9 0 a b c d e f ] g h i j k ",
-"l m n o e p q r s t u i v w ",
-"x y z A f B C D E F G H I J ",
-"K L M N O n P Q R S T U I J ",
-"V W u X Y Z `  ...T H U v w ",
-"k +.i @.#.6 #[email protected] H U U j k ",
-"  8 $.U H H H U U U U $.8   ",
-"    : $.U U U U U U $.:     ",
-"      8 j v I I v j 8       ",
-"        k w J J w k         "};
+/* XPM */
+static const char * expert_note_xpm[] = {
+"14 14 98 2",
+"  	c None",
+". 	c #131F1F",
+"+ 	c #0E2525",
+"@ 	c #0B1818",
+"# 	c #061414",
+"$ 	c #041B1B",
+"% 	c #020F0F",
+"& 	c #253434",
+"* 	c #349E9E",
+"= 	c #39DBDB",
+"- 	c #32FBFB",
+"; 	c #20FBFB",
+"> 	c #0FD4D4",
+", 	c #058787",
+"' 	c #011212",
+") 	c #384F4F",
+"! 	c #60E6E6",
+"~ 	c #82FFFF",
+"{ 	c #8EFFFF",
+"] 	c #80FFFF",
+"^ 	c #5CFFFF",
+"/ 	c #31FFFF",
+"( 	c #12FFFF",
+"_ 	c #04D8D8",
+": 	c #001E1E",
+"< 	c #303E3E",
+"[ 	c #66E7E7",
+"} 	c #A4FFFF",
+"| 	c #CCFFFF",
+"1 	c #D7FFFF",
+"2 	c #C9FFFF",
+"3 	c #9FFFFF",
+"4 	c #60FFFF",
+"5 	c #28FFFF",
+"6 	c #0AFFFF",
+"7 	c #01D7D7",
+"8 	c #001111",
+"9 	c #1E2929",
+"0 	c #3EA3A3",
+"a 	c #86FFFF",
+"b 	c #CAFFFF",
+"c 	c #EDFFFF",
+"d 	c #F5FFFF",
+"e 	c #EBFFFF",
+"f 	c #C5FFFF",
+"g 	c #38FFFF",
+"h 	c #0FFFFF",
+"i 	c #02FFFF",
+"j 	c #008585",
+"k 	c #000D0D",
+"l 	c #142A2A",
+"m 	c #3BDCDC",
+"n 	c #84FFFF",
+"o 	c #C8FFFF",
+"p 	c #F4FFFF",
+"q 	c #E9FFFF",
+"r 	c #C3FFFF",
+"s 	c #7EFFFF",
+"t 	c #36FFFF",
+"u 	c #0EFFFF",
+"v 	c #00D1D1",
+"w 	c #001818",
+"x 	c #0C1919",
+"y 	c #28FBFB",
+"z 	c #61FFFF",
+"A 	c #9DFFFF",
+"B 	c #D1FFFF",
+"C 	c #C2FFFF",
+"D 	c #99FFFF",
+"E 	c #5BFFFF",
+"F 	c #25FFFF",
+"G 	c #09FFFF",
+"H 	c #01FFFF",
+"I 	c #00FAFA",
+"J 	c #000E0E",
+"K 	c #041212",
+"L 	c #12FAFA",
+"M 	c #2FFFFF",
+"N 	c #57FFFF",
+"O 	c #78FFFF",
+"P 	c #76FFFF",
+"Q 	c #54FFFF",
+"R 	c #2CFFFF",
+"S 	c #10FFFF",
+"T 	c #04FFFF",
+"U 	c #00FFFF",
+"V 	c #011919",
+"W 	c #04D2D2",
+"X 	c #1DFFFF",
+"Y 	c #2DFFFF",
+"Z 	c #33FFFF",
+"` 	c #2BFFFF",
+" .	c #1CFFFF",
+"..	c #0DFFFF",
+"+.	c #018585",
+"@.	c #05FFFF",
+"#.	c #08FFFF",
+"$.	c #00D7D7",
+"        . + @ # $ %         ",
+"      & * = - ; > , '       ",
+"    ) ! ~ { ] ^ / ( _ :     ",
+"  < [ } | 1 2 3 4 5 6 7 8   ",
+"9 0 a b c d e f ] g h i j k ",
+"l m n o e p q r s t u i v w ",
+"x y z A f B C D E F G H I J ",
+"K L M N O n P Q R S T U I J ",
+"V W u X Y Z `  ...T H U v w ",
+"k +.i @.#.6 #[email protected] H U U j k ",
+"  8 $.U H H H U U U U $.8   ",
+"    : $.U U U U U U $.:     ",
+"      8 j v I I v j 8       ",
+"        k w J J w k         "};
diff -urN wireshark-1.2.2/image/expert_warn.xpm wireshark-1.2.2-iscsie/image/expert_warn.xpm
--- wireshark-1.2.2/image/expert_warn.xpm	2009-09-15 09:46:52.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/expert_warn.xpm	2009-11-26 16:35:37.000000000 +0800
@@ -1,115 +1,115 @@
-/* XPM */
-static const char * expert_warn_xpm[] = {
-"14 14 98 2",
-"  	c None",
-". 	c #1F1F13",
-"+ 	c #25250E",
-"@ 	c #18180B",
-"# 	c #141406",
-"$ 	c #1B1B04",
-"% 	c #0F0F02",
-"& 	c #343425",
-"* 	c #9E9E34",
-"= 	c #DBDB39",
-"- 	c #FBFB32",
-"; 	c #FBFB20",
-"> 	c #D4D40F",
-", 	c #878705",
-"' 	c #121201",
-") 	c #4F4F38",
-"! 	c #E6E660",
-"~ 	c #FFFF82",
-"{ 	c #FFFF8E",
-"] 	c #FFFF80",
-"^ 	c #FFFF5C",
-"/ 	c #FFFF31",
-"( 	c #FFFF12",
-"_ 	c #D8D804",
-": 	c #1E1E00",
-"< 	c #3E3E30",
-"[ 	c #E7E766",
-"} 	c #FFFFA4",
-"| 	c #FFFFCC",
-"1 	c #FFFFD7",
-"2 	c #FFFFC9",
-"3 	c #FFFF9F",
-"4 	c #FFFF60",
-"5 	c #FFFF28",
-"6 	c #FFFF0A",
-"7 	c #D7D701",
-"8 	c #111100",
-"9 	c #29291E",
-"0 	c #A3A33E",
-"a 	c #FFFF86",
-"b 	c #FFFFCA",
-"c 	c #FFFFED",
-"d 	c #FFFFF5",
-"e 	c #FFFFEB",
-"f 	c #FFFFC5",
-"g 	c #FFFF38",
-"h 	c #FFFF0F",
-"i 	c #FFFF02",
-"j 	c #858500",
-"k 	c #0D0D00",
-"l 	c #2A2A14",
-"m 	c #DCDC3B",
-"n 	c #FFFF84",
-"o 	c #FFFFC8",
-"p 	c #FFFFF4",
-"q 	c #FFFFE9",
-"r 	c #FFFFC3",
-"s 	c #FFFF7E",
-"t 	c #FFFF36",
-"u 	c #FFFF0E",
-"v 	c #D1D100",
-"w 	c #181800",
-"x 	c #19190C",
-"y 	c #FBFB28",
-"z 	c #FFFF61",
-"A 	c #FFFF9D",
-"B 	c #FFFFD1",
-"C 	c #FFFFC2",
-"D 	c #FFFF99",
-"E 	c #FFFF5B",
-"F 	c #FFFF25",
-"G 	c #FFFF09",
-"H 	c #FFFF01",
-"I 	c #FAFA00",
-"J 	c #0E0E00",
-"K 	c #121204",
-"L 	c #FAFA12",
-"M 	c #FFFF2F",
-"N 	c #FFFF57",
-"O 	c #FFFF78",
-"P 	c #FFFF76",
-"Q 	c #FFFF54",
-"R 	c #FFFF2C",
-"S 	c #FFFF10",
-"T 	c #FFFF04",
-"U 	c #FFFF00",
-"V 	c #191901",
-"W 	c #D2D204",
-"X 	c #FFFF1D",
-"Y 	c #FFFF2D",
-"Z 	c #FFFF33",
-"` 	c #FFFF2B",
-" .	c #FFFF1C",
-"..	c #FFFF0D",
-"+.	c #858501",
-"@.	c #FFFF05",
-"#.	c #FFFF08",
-"$.	c #D7D700",
-"        . + @ # $ %         ",
-"      & * = - ; > , '       ",
-"    ) ! ~ { ] ^ / ( _ :     ",
-"  < [ } | 1 2 3 4 5 6 7 8   ",
-"9 0 a b c d e f ] g h i j k ",
-"l m n o e p q r s t u i v w ",
-"x y z A f B C D E F G H I J ",
-"K L M N O n P Q R S T U I J ",
-"V W u X Y Z `  ...T H U v w ",
-"k +.i @.#.6 #[email protected] H U U j k ",
-"  8 $.U H H H U U U U $.8   ",
-"    : $.U U U U U U $.:     ",
-"      8 j v I I v j 8       ",
-"        k w J J w k         "};
+/* XPM */
+static const char * expert_warn_xpm[] = {
+"14 14 98 2",
+"  	c None",
+". 	c #1F1F13",
+"+ 	c #25250E",
+"@ 	c #18180B",
+"# 	c #141406",
+"$ 	c #1B1B04",
+"% 	c #0F0F02",
+"& 	c #343425",
+"* 	c #9E9E34",
+"= 	c #DBDB39",
+"- 	c #FBFB32",
+"; 	c #FBFB20",
+"> 	c #D4D40F",
+", 	c #878705",
+"' 	c #121201",
+") 	c #4F4F38",
+"! 	c #E6E660",
+"~ 	c #FFFF82",
+"{ 	c #FFFF8E",
+"] 	c #FFFF80",
+"^ 	c #FFFF5C",
+"/ 	c #FFFF31",
+"( 	c #FFFF12",
+"_ 	c #D8D804",
+": 	c #1E1E00",
+"< 	c #3E3E30",
+"[ 	c #E7E766",
+"} 	c #FFFFA4",
+"| 	c #FFFFCC",
+"1 	c #FFFFD7",
+"2 	c #FFFFC9",
+"3 	c #FFFF9F",
+"4 	c #FFFF60",
+"5 	c #FFFF28",
+"6 	c #FFFF0A",
+"7 	c #D7D701",
+"8 	c #111100",
+"9 	c #29291E",
+"0 	c #A3A33E",
+"a 	c #FFFF86",
+"b 	c #FFFFCA",
+"c 	c #FFFFED",
+"d 	c #FFFFF5",
+"e 	c #FFFFEB",
+"f 	c #FFFFC5",
+"g 	c #FFFF38",
+"h 	c #FFFF0F",
+"i 	c #FFFF02",
+"j 	c #858500",
+"k 	c #0D0D00",
+"l 	c #2A2A14",
+"m 	c #DCDC3B",
+"n 	c #FFFF84",
+"o 	c #FFFFC8",
+"p 	c #FFFFF4",
+"q 	c #FFFFE9",
+"r 	c #FFFFC3",
+"s 	c #FFFF7E",
+"t 	c #FFFF36",
+"u 	c #FFFF0E",
+"v 	c #D1D100",
+"w 	c #181800",
+"x 	c #19190C",
+"y 	c #FBFB28",
+"z 	c #FFFF61",
+"A 	c #FFFF9D",
+"B 	c #FFFFD1",
+"C 	c #FFFFC2",
+"D 	c #FFFF99",
+"E 	c #FFFF5B",
+"F 	c #FFFF25",
+"G 	c #FFFF09",
+"H 	c #FFFF01",
+"I 	c #FAFA00",
+"J 	c #0E0E00",
+"K 	c #121204",
+"L 	c #FAFA12",
+"M 	c #FFFF2F",
+"N 	c #FFFF57",
+"O 	c #FFFF78",
+"P 	c #FFFF76",
+"Q 	c #FFFF54",
+"R 	c #FFFF2C",
+"S 	c #FFFF10",
+"T 	c #FFFF04",
+"U 	c #FFFF00",
+"V 	c #191901",
+"W 	c #D2D204",
+"X 	c #FFFF1D",
+"Y 	c #FFFF2D",
+"Z 	c #FFFF33",
+"` 	c #FFFF2B",
+" .	c #FFFF1C",
+"..	c #FFFF0D",
+"+.	c #858501",
+"@.	c #FFFF05",
+"#.	c #FFFF08",
+"$.	c #D7D700",
+"        . + @ # $ %         ",
+"      & * = - ; > , '       ",
+"    ) ! ~ { ] ^ / ( _ :     ",
+"  < [ } | 1 2 3 4 5 6 7 8   ",
+"9 0 a b c d e f ] g h i j k ",
+"l m n o e p q r s t u i v w ",
+"x y z A f B C D E F G H I J ",
+"K L M N O n P Q R S T U I J ",
+"V W u X Y Z `  ...T H U v w ",
+"k +.i @.#.6 #[email protected] H U U j k ",
+"  8 $.U H H H U U U U $.8   ",
+"    : $.U U U U U U $.:     ",
+"      8 j v I I v j 8       ",
+"        k w J J w k         "};
diff -urN wireshark-1.2.2/image/iscsi_asyncmsg.xpm wireshark-1.2.2-iscsie/image/iscsi_asyncmsg.xpm
--- wireshark-1.2.2/image/iscsi_asyncmsg.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_asyncmsg.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,23 @@
+/* XPM */
+static char * iscsi_asyncmsg_xpm[] = {
+"16 16 4 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #080808",
+"   @            ",
+"  @@            ",
+" @@@@@@@@       ",
+"@@@@@@@@@@      ",
+" @@@@@@@@@      ",
+"  @@    @@      ",
+"   @  @ @@      ",
+"     @@ @@      ",
+"     @@ @@      ",
+"     @@ @   @   ",
+"     @@     @@  ",
+"     @@@@@@@@@@ ",
+"     @@@@@@@@@@@",
+"      @@@@@@@@@ ",
+"            @@  ",
+"            @   "};
diff -urN wireshark-1.2.2/image/iscsi_connection.xpm wireshark-1.2.2-iscsie/image/iscsi_connection.xpm
--- wireshark-1.2.2/image/iscsi_connection.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_connection.xpm	2009-12-25 09:02:29.000000000 +0800
@@ -0,0 +1,177 @@
+/* XPM */
+static const char *iscsi_connection_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 155 2",
+"   c #555753",
+".  c #585A56",
+"X  c #595B57",
+"o  c #5A5C58",
+"O  c #5B5D59",
+"+  c #5C5E5A",
+"@  c #5D5F5B",
+"#  c #5E605B",
+"$  c #5E605C",
+"%  c #60625D",
+"&  c #61635F",
+"*  c #626460",
+"=  c #646662",
+"-  c #656762",
+";  c #676964",
+":  c #676A65",
+">  c #686A66",
+",  c #696B67",
+"<  c #6A6C68",
+"1  c #6C6E69",
+"2  c #6D6F6A",
+"3  c #6E716C",
+"4  c #71736F",
+"5  c #727470",
+"6  c #737570",
+"7  c #737671",
+"8  c #747671",
+"9  c #747772",
+"0  c #757772",
+"q  c #747773",
+"w  c #757872",
+"e  c #757873",
+"r  c #767873",
+"t  c #777874",
+"y  c #767974",
+"u  c #777974",
+"i  c #777A75",
+"p  c #787A75",
+"a  c #797C77",
+"s  c #7A7C78",
+"d  c #7A7D78",
+"f  c #7C7E79",
+"g  c #204A87",
+"h  c #224B87",
+"j  c #224B88",
+"k  c #224C88",
+"l  c #345A92",
+"z  c #395E95",
+"x  c #3A5F95",
+"c  c #385F96",
+"v  c #3C6196",
+"b  c #3C6399",
+"n  c #406498",
+"m  c #43689E",
+"M  c #436A9F",
+"N  c #486A9C",
+"B  c #426AA0",
+"V  c #4B72A7",
+"C  c #4D76A9",
+"Z  c #4E78AC",
+"A  c #5172A2",
+"S  c #5576A5",
+"D  c #5378A8",
+"F  c #527AAE",
+"G  c #577EAF",
+"H  c #597FAE",
+"J  c #557FB1",
+"K  c #567EB2",
+"L  c #617FAA",
+"P  c #5F80AD",
+"I  c #5E81AF",
+"U  c #5D83B1",
+"Y  c #5A83B4",
+"T  c #5982B6",
+"R  c #5983B6",
+"E  c #5D86B7",
+"W  c #6180AC",
+"Q  c #6081AF",
+"!  c #6683AD",
+"~  c #6384B0",
+"^  c #6686B2",
+"/  c #6085B4",
+"(  c #6386B4",
+")  c #6487B6",
+"_  c #6B87B0",
+"`  c #6588B7",
+"'  c #6889B3",
+"]  c #6D88B1",
+"[  c #6D89B2",
+"{  c #6E8AB2",
+"}  c #6088BA",
+"|  c #628ABA",
+" . c #628ABB",
+".. c #708BB3",
+"X. c #758FB5",
+"o. c #858782",
+"O. c #868783",
+"+. c #878984",
+"@. c #888A86",
+"#. c #91928F",
+"$. c #929390",
+"%. c #9FA19B",
+"&. c #AAADA6",
+"*. c #ABADA9",
+"=. c #ADAFAA",
+"-. c #B0B2AE",
+";. c #B1B3AE",
+":. c #BBBDB8",
+">. c #BABEB9",
+",. c #BCBFBB",
+"<. c #BDC1BD",
+"1. c #BFC2BC",
+"2. c #BFC2BE",
+"3. c #C0C3BF",
+"4. c #C2C4BE",
+"5. c #C3C5BF",
+"6. c #C1C4C0",
+"7. c #C2C5C1",
+"8. c #C4C6C0",
+"9. c #C4C5C2",
+"0. c #C6C7C4",
+"q. c #C6C8C2",
+"w. c #C8CAC4",
+"e. c #C9CBC5",
+"r. c #CACCC6",
+"t. c #CACCC7",
+"y. c #CBCDC8",
+"u. c #CDCFCA",
+"i. c #CDCECB",
+"p. c #CED0CB",
+"a. c #D0D2CD",
+"s. c #D2D4CF",
+"d. c #D2D3D0",
+"f. c #D3D5D0",
+"g. c #D6D8D3",
+"h. c #D7D8D4",
+"j. c #D8D9D5",
+"k. c #D9DBD7",
+"l. c #DBDCD8",
+"z. c #DBDCD9",
+"x. c #DCDDDA",
+"c. c #DDDEDB",
+"v. c #E0E0DD",
+"b. c #E3E3E0",
+"n. c #E6E6E3",
+"m. c #E9E9E6",
+"M. c #E9E9E8",
+"N. c #EBEBE9",
+"B. c #F4F4F3",
+"V. c #F5F5F4",
+"C. c #F6F6F5",
+"Z. c #F7F7F6",
+"A. c #F8F8F7",
+"S. c #F9F9F8",
+"D. c None",
+/* pixels */
+"D.f p p p t r 8 u 8 8 8 7 4 r D.",
+"a :.f.k.v.n.N.m.b.c.g.a.y.7.=.7 ",
+"8 y.g g g g g j j g g g g g :.3 ",
+"4 r.g v x M L n l A X...] g ,., ",
+"3 w.g x x S L x b ] ] _ ! h <.; ",
+"1 q.g m M I D B I ` _ ~ W h <.- ",
+", 8.g V C ( Z J ` ` E U H k 7.* ",
+"; 4.g F J Y Y  .} } E Y J h 7.% ",
+"- <.j j g j g j g g g g g g 7.O ",
+"- &.4.w.i.f.h.c.c.c.l.h.s.i.;.$ ",
+"D.% $ $ O O O O O O O X X X O D.",
+"[email protected][email protected].",
+"D.O.d , t , 8 , t , u , p a o.D.",
+"r $.-.%.@.%.@.%.+.%.+.%.@.*.$.8 ",
+"O N.B.C.C.C.A.S.S.C.S.C.C.C.N.O ",
+"O                             O "
+};
diff -urN wireshark-1.2.2/image/iscsi_error.xpm wireshark-1.2.2-iscsie/image/iscsi_error.xpm
--- wireshark-1.2.2/image/iscsi_error.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_error.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,25 @@
+/* XPM */
+static char * iscsi_error_xpm[] = {
+"16 16 6 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #C4542D",
+"#	c #FF2A00",
+"$	c #8F2915",
+"                ",
+"   $       @    ",
+"  @#$     @#@   ",
+" @###$   @###$  ",
+"  @###$ @###$   ",
+"   @###@###$    ",
+"    @#####$     ",
+"     @###$      ",
+"    @#####$     ",
+"   @#######$    ",
+"  @###$ @###$   ",
+" @###$   @###$  ",
+"  @#$     @#$   ",
+"   $       $    ",
+"                ",
+"                "};
diff -urN wireshark-1.2.2/image/iscsi_fromarrow.xpm wireshark-1.2.2-iscsie/image/iscsi_fromarrow.xpm
--- wireshark-1.2.2/image/iscsi_fromarrow.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_fromarrow.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,25 @@
+/* XPM */
+static char * iscsi_fromarrow_xpm[] = {
+"16 16 6 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #3A9807",
+"#	c #205105",
+"$	c #4EAF19",
+"                ",
+"                ",
+"                ",
+"    @           ",
+"   @$           ",
+"  @$$@@@@@@@@@@#",
+" @$$$$$$$$$$$$$#",
+"@$$$$$$$$$$$$$$#",
+" @$$$$$$$$$$$$$#",
+"  @$############",
+"   @#           ",
+"    #           ",
+"                ",
+"                ",
+"                ",
+"                "};
diff -urN wireshark-1.2.2/image/iscsi_ivs.xpm wireshark-1.2.2-iscsie/image/iscsi_ivs.xpm
--- wireshark-1.2.2/image/iscsi_ivs.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_ivs.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,28 @@
+/* XPM */
+static char * iscsi_ivs_xpm[] = {
+"16 16 9 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #2492D8",
+"#	c #71C3F7",
+"$	c #2EB200",
+"%	c #124700",
+"&	c #30AA00",
+"*	c #616161",
+"    ########### ",
+"    @@@@@@@@@@@ ",
+"    ........... ",
+"    .*******... ",
+"    ........... ",
+"    .*****..... ",
+"    ........... ",
+"    ........... ",
+"    ........... ",
+"                ",
+"    $           ",
+"   $$           ",
+"  $$$$$$$$$$$$& ",
+"  %$$%%%%%%%%%% ",
+"   %$           ",
+"    %           "};
diff -urN wireshark-1.2.2/image/iscsi_login_c0.xpm wireshark-1.2.2-iscsie/image/iscsi_login_c0.xpm
--- wireshark-1.2.2/image/iscsi_login_c0.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_login_c0.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,25 @@
+/* XPM */
+static char * iscsi_login_c0_xpm[] = {
+"16 16 6 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #C89700",
+"#	c #A37C04",
+"$	c #684F03",
+" ...         .  ",
+".   .        .. ",
+".   . ..........",
+".   . ..........",
+".   .        .. ",
+" ...         .  ",
+"                ",
+"  ##$      #### ",
+"  ##$     #@@@@$",
+"  ##$     #@  @$",
+"##########@@  @$",
+"#@@@@@@@@@@@  @$",
+"$$$$$$$$$$@@  @$",
+"          $@  @$",
+"          $@@@@$",
+"           $$$$ "};
diff -urN wireshark-1.2.2/image/iscsi_login_c1.xpm wireshark-1.2.2-iscsie/image/iscsi_login_c1.xpm
--- wireshark-1.2.2/image/iscsi_login_c1.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_login_c1.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,25 @@
+/* XPM */
+static char * iscsi_login_c1_xpm[] = {
+"16 16 6 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #C89700",
+"#	c #A37C04",
+"$	c #684F03",
+"  .        .    ",
+"  .        ..   ",
+"  .  .........  ",
+"  .  .........  ",
+"  .        ..   ",
+"  .        .    ",
+"  .             ",
+"           #### ",
+"  ##$     #@@@@$",
+"  ##$     #@  @$",
+"##########@@  @$",
+"#@@@@@@@@@@@  @$",
+"$$$$$$$$$$@@  @$",
+"          $@  @$",
+"          $@@@@$",
+"           $$$$ "};
diff -urN wireshark-1.2.2/image/iscsi_login_c3.xpm wireshark-1.2.2-iscsie/image/iscsi_login_c3.xpm
--- wireshark-1.2.2/image/iscsi_login_c3.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_login_c3.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,25 @@
+/* XPM */
+static char * iscsi_login_c3_xpm[] = {
+"16 16 6 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #C89700",
+"#	c #A37C04",
+"$	c #684F03",
+" .....       .  ",
+"     .       .. ",
+"     . .........",
+" ..... .........",
+"     .       .. ",
+"     .       .  ",
+" .....          ",
+"           #### ",
+"  ##$     #@@@@$",
+"  ##$     #@  @$",
+"##########@@  @$",
+"#@@@@@@@@@@@  @$",
+"$$$$$$$$$$@@  @$",
+"          $@  @$",
+"          $@@@@$",
+"           $$$$ "};
diff -urN wireshark-1.2.2/image/iscsi_login_rsp_n0.xpm wireshark-1.2.2-iscsie/image/iscsi_login_rsp_n0.xpm
--- wireshark-1.2.2/image/iscsi_login_rsp_n0.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_login_rsp_n0.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,27 @@
+/* XPM */
+static char * iscsi_login_rsp_n0_xpm[] = {
+"16 16 8 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #358B02",
+"#	c #235903",
+"$	c #C89700",
+"%	c #A37C04",
+"&	c #684F03",
+"  @         @@@ ",
+" @@        @   @",
+"@@@@@@@@@@ @   @",
+"@@@####### @   @",
+" @@        @   #",
+"  #         ### ",
+"                ",
+"  %%&      %%%% ",
+"  %%&     %$$$$&",
+"  %%&     %$  $&",
+"%%%%%%%%%%$$  $&",
+"%$$$$$$$$$$$  $&",
+"&&&&&&&&&&$$  $&",
+"          &$  $&",
+"          &$$$$&",
+"           &&&& "};
diff -urN wireshark-1.2.2/image/iscsi_login_rsp_n1.xpm wireshark-1.2.2-iscsie/image/iscsi_login_rsp_n1.xpm
--- wireshark-1.2.2/image/iscsi_login_rsp_n1.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_login_rsp_n1.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,27 @@
+/* XPM */
+static char * iscsi_login_rsp_n1_xpm[] = {
+"16 16 8 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #358B02",
+"#	c #235903",
+"$	c #C89700",
+"%	c #A37C04",
+"&	c #684F03",
+"             @  ",
+"  @          @  ",
+" @@          @  ",
+"@@@@@@@@@@   @  ",
+"@@@#######   @  ",
+" @@          @  ",
+"  #             ",
+"           %%%% ",
+"  %%&     %$$$$&",
+"  %%&     %$  $&",
+"%%%%%%%%%%$$  $&",
+"%$$$$$$$$$$$  $&",
+"&&&&&&&&&&$$  $&",
+"          &$  $&",
+"          &$$$$&",
+"           &&&& "};
diff -urN wireshark-1.2.2/image/iscsi_login_rsp_n3.xpm wireshark-1.2.2-iscsie/image/iscsi_login_rsp_n3.xpm
--- wireshark-1.2.2/image/iscsi_login_rsp_n3.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_login_rsp_n3.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,27 @@
+/* XPM */
+static char * iscsi_login_rsp_n3_xpm[] = {
+"16 16 8 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #358B02",
+"#	c #235903",
+"$	c #C89700",
+"%	c #A37C04",
+"&	c #684F03",
+"  @        @@@@@",
+" @@            @",
+"@@@@@@@@@@     @",
+"@@@####### @@@@@",
+" @#            @",
+"  #            #",
+"           #####",
+"                ",
+"           %%%% ",
+"  %%&     %$$$$&",
+"  %%&     %$  $&",
+"%%%%%%%%%%$$  $&",
+"%$$$$$$$$$$$  $&",
+"&&&&&&&&&&$$  $&",
+"          &$$$$&",
+"           &&&& "};
diff -urN wireshark-1.2.2/image/iscsi_logout_rq.xpm wireshark-1.2.2-iscsie/image/iscsi_logout_rq.xpm
--- wireshark-1.2.2/image/iscsi_logout_rq.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_logout_rq.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,28 @@
+/* XPM */
+static char * iscsi_logout_rq_xpm[] = {
+"16 16 9 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #C89700",
+"#	c #705500",
+"$	c #423200",
+"%	c #C69A14",
+"&	c #896D15",
+"*	c #E7D291",
+"     #####      ",
+"    ######$     ",
+"    ##   #$     ",
+"    ##   #$     ",
+"   &&&&&&&&&    ",
+"  &*********$   ",
+"  &*%%%%%%@@$   ",
+"  &*@@%%%@@@$   ",
+"  #*%%%%%%%%$   ",
+"  $$$$$$$$$$$   ",
+"                ",
+"            .   ",
+"            ..  ",
+"  ............. ",
+"            ..  ",
+"            .   "};
diff -urN wireshark-1.2.2/image/iscsi_logout_rsp.xpm wireshark-1.2.2-iscsie/image/iscsi_logout_rsp.xpm
--- wireshark-1.2.2/image/iscsi_logout_rsp.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_logout_rsp.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,29 @@
+/* XPM */
+static char * iscsi_logout_rsp_xpm[] = {
+"16 16 10 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #589500",
+"#	c #C89700",
+"$	c #705500",
+"%	c #423200",
+"&	c #C69A14",
+"*	c #896D15",
+"=	c #E7D291",
+"     $$$$$      ",
+"    $$$$$$%     ",
+"    $$   $%     ",
+"    $$   $%     ",
+"   *********    ",
+"  *=========%   ",
+"  *=&&&&&&##%   ",
+"  *=##&&&###%   ",
+"  $=&&&&&&&&%   ",
+"  %%%%%%%%%%%   ",
+"                ",
+"    @           ",
+"   @@           ",
+"  @@@@@@@@@@@@@ ",
+"   @@           ",
+"    @           "};
diff -urN wireshark-1.2.2/image/iscsi_network.xpm wireshark-1.2.2-iscsie/image/iscsi_network.xpm
--- wireshark-1.2.2/image/iscsi_network.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_network.xpm	2009-12-25 09:02:29.000000000 +0800
@@ -0,0 +1,162 @@
+/* XPM */
+static const char *iscsi_network_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 140 2",
+"   c #72736D",
+".  c #75766F",
+"X  c #747670",
+"o  c #757670",
+"O  c #7B7D75",
+"+  c #7D7E78",
+"@  c #7F807A",
+"#  c #7F807B",
+"$  c #83847D",
+"%  c #96B162",
+"&  c #3E6296",
+"*  c #416598",
+"=  c #426698",
+"-  c #456B9E",
+";  c #4E6E9B",
+":  c #4E6F9B",
+">  c #486B9C",
+",  c #496B9C",
+"<  c #4C6D9D",
+"1  c #4E6F9F",
+"2  c #56759F",
+"3  c #58769F",
+"4  c #4B70A1",
+"5  c #4C70A2",
+"6  c #4E72A4",
+"7  c #4D76AA",
+"8  c #5071A1",
+"9  c #5575A2",
+"0  c #5675A3",
+"q  c #5776A4",
+"w  c #5F7CA3",
+"e  c #5C7BA6",
+"r  c #5079AD",
+"t  c #547CAF",
+"y  c #587BAA",
+"u  c #587FB1",
+"i  c #6D8096",
+"p  c #6E8198",
+"a  c #6C829C",
+"s  c #738393",
+"d  c #73869D",
+"f  c #73879E",
+"g  c #6783A8",
+"h  c #7187A2",
+"j  c #768AA1",
+"k  c #778BA2",
+"l  c #7489A5",
+"z  c #748AA5",
+"x  c #768BA7",
+"c  c #7893AB",
+"v  c #6988B2",
+"b  c #808280",
+"n  c #828481",
+"m  c #878885",
+"M  c #868886",
+"N  c #8A8B84",
+"B  c #888B87",
+"V  c #848989",
+"C  c #878C8A",
+"Z  c #828A8E",
+"A  c #838B8E",
+"S  c #8D8E8A",
+"D  c #91928F",
+"F  c #92938F",
+"G  c #828C93",
+"H  c #878E90",
+"J  c #899092",
+"K  c #8E9392",
+"L  c #8F9595",
+"P  c #8E9496",
+"I  c #8C9499",
+"U  c #8F969A",
+"Y  c #8E969D",
+"T  c #939590",
+"R  c #959691",
+"E  c #969792",
+"W  c #939794",
+"Q  c #949796",
+"!  c #999B96",
+"~  c #999B97",
+"^  c #9A9B97",
+"/  c #9B9D99",
+"(  c #9E9F9B",
+")  c #989C9C",
+"_  c #9DA09F",
+"`  c #A9B98C",
+"'  c #B0BF93",
+"]  c #929BA2",
+"[  c #959CA0",
+"{  c #919BA4",
+"}  c #939DA6",
+"|  c #999FA3",
+" . c #9CA2A6",
+".. c #9DA3A7",
+"X. c #97A0A9",
+"o. c #8FA8BE",
+"O. c #A3A4A1",
+"+. c #A3A5A1",
+"@. c #A3A4A2",
+"#. c #A4A5A2",
+"$. c #A5A6A4",
+"%. c #A6A7A4",
+"&. c #A7A9A6",
+"*. c #A8AAA7",
+"=. c #A7ABAA",
+"-. c #ABADA9",
+";. c #ACADAA",
+":. c #ADAEAB",
+">. c #AAADAC",
+",. c #ADAEAC",
+"<. c #ACAFAC",
+"1. c #AEAFAC",
+"2. c #AFB0AC",
+"3. c #AFB0AD",
+"4. c #B4BDA3",
+"5. c #B0B1AE",
+"6. c #B2B3B0",
+"7. c #B2B4B0",
+"8. c #B3B4B0",
+"9. c #B3B5B1",
+"0. c #B8BAB5",
+"q. c #B8B9B6",
+"w. c #B9BBB7",
+"e. c #B9BCB7",
+"r. c #BABCB8",
+"t. c #BFC1BD",
+"y. c #C0C4BA",
+"u. c #C3C7BB",
+"i. c #C0C2BD",
+"p. c #C7C8C5",
+"a. c #CACCC7",
+"s. c #CBCDC7",
+"d. c #CBCEC6",
+"f. c #CECFCC",
+"g. c #D1D3CE",
+"h. c #D2D3D0",
+"j. c #D7D9D5",
+"k. c #DBDCDA",
+"l. c #DCDDD9",
+"z. c None",
+/* pixels */
+"z.z.z.z.z.z.z.z.z.z.z.z.z.z.z.z.",
+"z.z.z.z.z.z.z.z.z.z.z.z.z.z.z.z.",
+"z.z.z.z.z.z.z.z.z.z.z.z.z.z.z.z.",
+"z.z.( ( z.z.z.) | .. .[ U K z.z.",
+"z.p.k.k.p.z.N k * 8 > 0 0 d z.z.",
+"6.t.0.0.i.5.$ a & 2 : g w i O z.",
+"7.w.(  .w.6.+ p s ] } X.{ Y P N ",
+"3.w.<.<.w.5.o G U < < < < e 0 H ",
+"2.e.W W w.3.z.  J = 5 6 y v 0 A ",
+"1.4.` t.i.1.z.D J - 7 r u t 4 A ",
+"1.' % u.a.1.z.S C d h z x z k V ",
+"-.a.u.a.g.-.c z.z.. # E E + . z.",
+"*.g.g.j.l.=.o.z.P / T ! ! T ^ D ",
+"$ &.&.$.#.b z.z.M #.O.O.O.O.O.M ",
+"z.z.z.z.z.z.z.z.z.z.z.z.z.z.z.z.",
+"z.z.z.z.z.z.z.z.z.z.z.z.z.z.z.z."
+};
diff -urN wireshark-1.2.2/image/iscsi_nop_in.xpm wireshark-1.2.2-iscsie/image/iscsi_nop_in.xpm
--- wireshark-1.2.2/image/iscsi_nop_in.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_nop_in.xpm	2010-01-19 13:42:26.000000000 +0800
@@ -0,0 +1,25 @@
+/* XPM */
+static char * iscsi_nop_in_xpm[] = {
+"16 16 6 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #2EB200",
+"#	c #124700",
+"$	c #30AA00",
+"                ",
+" ...............",
+" ......+........",
+" ......+........",
+" ....+.+........",
+" ....+.+........",
+" .+++.+.+++++++.",
+" ...............",
+" ...............",
+"                ",
+"  @             ",
+" @@             ",
+"@@@@@@@@@@@@$@@@",
+"#@@#############",
+" #@             ",
+"  #             "};
diff -urN wireshark-1.2.2/image/iscsi_nop_out.xpm wireshark-1.2.2-iscsie/image/iscsi_nop_out.xpm
--- wireshark-1.2.2/image/iscsi_nop_out.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_nop_out.xpm	2010-01-19 13:42:26.000000000 +0800
@@ -0,0 +1,22 @@
+/* XPM */
+static char * iscsi_nop_out_xpm[] = {
+"16 16 3 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"                ",
+"............... ",
+"......+........ ",
+"......+........ ",
+"....+.+........ ",
+"....+.+........ ",
+".+++.+.+++++++. ",
+"............... ",
+"............... ",
+"                ",
+"             .  ",
+"             .. ",
+"................",
+"................",
+"             .. ",
+"             .  "};
diff -urN wireshark-1.2.2/image/iscsi_only_connection.xpm wireshark-1.2.2-iscsie/image/iscsi_only_connection.xpm
--- wireshark-1.2.2/image/iscsi_only_connection.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_only_connection.xpm	2009-12-30 11:26:42.000000000 +0800
@@ -0,0 +1,172 @@
+/* XPM */
+static const char *iscsi_only_connection_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 150 2",
+"   c #555753",
+".  c #585A56",
+"X  c #595B57",
+"o  c #5A5C58",
+"O  c #5B5D59",
+"+  c #5C5E5A",
+"@  c #5D5F5B",
+"#  c #5E605B",
+"$  c #5E605C",
+"%  c #60625D",
+"&  c #61635F",
+"*  c #626460",
+"=  c #646662",
+"-  c #656762",
+";  c #676964",
+":  c #676A65",
+">  c #686A66",
+",  c #696B67",
+"<  c #6A6C68",
+"1  c #6C6E69",
+"2  c #6D6F6A",
+"3  c #6E716C",
+"4  c #71736F",
+"5  c #727470",
+"6  c #737570",
+"7  c #737671",
+"8  c #747671",
+"9  c #747772",
+"0  c #757772",
+"q  c #747773",
+"w  c #757872",
+"e  c #757873",
+"r  c #767873",
+"t  c #777874",
+"y  c #767974",
+"u  c #777974",
+"i  c #777A75",
+"p  c #787A75",
+"a  c #797C77",
+"s  c #7A7C78",
+"d  c #7A7D78",
+"f  c #7C7E79",
+"g  c #A40000",
+"h  c #A40202",
+"j  c #AC1616",
+"k  c #AE1A1A",
+"l  c #AF1C1C",
+"z  c #AF1E1E",
+"x  c #B11F1F",
+"c  c #B02020",
+"v  c #B72020",
+"b  c #B52222",
+"n  c #B22525",
+"m  c #B42D2D",
+"M  c #BC2828",
+"N  c #BD2929",
+"B  c #BD3434",
+"V  c #B83838",
+"C  c #BA3B3B",
+"Z  c #C02A2A",
+"A  c #C12B2B",
+"S  c #C32D2D",
+"D  c #C72E2E",
+"F  c #C23232",
+"G  c #C73030",
+"H  c #C73131",
+"J  c #C13737",
+"K  c #C83535",
+"L  c #CA3737",
+"P  c #C43B3B",
+"I  c #C53F3F",
+"U  c #CB3939",
+"Y  c #BE4A4A",
+"T  c #C14040",
+"R  c #C14343",
+"E  c #C74141",
+"W  c #C64242",
+"Q  c #C14545",
+"!  c #C34747",
+"~  c #C84343",
+"^  c #C04A4A",
+"/  c #C44B4B",
+"(  c #C64C4C",
+")  c #C15050",
+"_  c #C35454",
+"`  c #C45757",
+"'  c #C35858",
+"]  c #C45858",
+"[  c #C55C5C",
+"{  c #C66161",
+"}  c #858782",
+"|  c #868783",
+" . c #878984",
+".. c #888A86",
+"X. c #91928F",
+"o. c #929390",
+"O. c #9FA19B",
+"+. c #AAADA6",
+"@. c #ABADA9",
+"#. c #ADAFAA",
+"$. c #B0B2AE",
+"%. c #B1B3AE",
+"&. c #BEBCB5",
+"*. c #BBBDB8",
+"=. c #C0BDB7",
+"-. c #C1BFB9",
+";. c #BFC2BC",
+":. c #C3C0BA",
+">. c #C4C1BB",
+",. c #C5C2BC",
+"<. c #C6C3BD",
+"1. c #C2C4BE",
+"2. c #C3C5BF",
+"3. c #C4C6C0",
+"4. c #C4C5C2",
+"5. c #C6C7C4",
+"6. c #C6C8C2",
+"7. c #C8CAC4",
+"8. c #C9CBC5",
+"9. c #CACCC6",
+"0. c #CACCC7",
+"q. c #CBCDC8",
+"w. c #CDCFCA",
+"e. c #CDCECB",
+"r. c #CED0CB",
+"t. c #D0D2CD",
+"y. c #D2D4CF",
+"u. c #D2D3D0",
+"i. c #D3D5D0",
+"p. c #D6D8D3",
+"a. c #D7D8D4",
+"s. c #D8D9D5",
+"d. c #D9DBD7",
+"f. c #DBDCD8",
+"g. c #DBDCD9",
+"h. c #DCDDDA",
+"j. c #DDDEDB",
+"k. c #E0E0DD",
+"l. c #E3E3E0",
+"z. c #E6E6E3",
+"x. c #E9E9E6",
+"c. c #E9E9E8",
+"v. c #EBEBE9",
+"b. c #F4F4F3",
+"n. c #F5F5F4",
+"m. c #F6F6F5",
+"M. c #F7F7F6",
+"N. c #F8F8F7",
+"B. c #F9F9F8",
+"V. c None",
+/* pixels */
+"V.f p p i i r r r 8 9 7 7 7 r V.",
+"a *.i.d.k.z.v.x.l.h.a.r.9.3.#.7 ",
+"8 q.g g g g g g g g g g g g &.1 ",
+"4 9.g c x m Y c j C { [ ' g =.< ",
+"3 7.g z z C ^ x c _ ] _ ) g :.; ",
+"1 6.g b b Q B v T ( ( ! Q g :.; ",
+", 3.g M M E A F ~ ~ I P J h >.* ",
+"; 1.g A S G S U U L L F S g 1.$ ",
+"= >.g g g g g g g g g g g g <.+ ",
+"- +.1.9.r.i.d.g.h.h.f.a.y.w.%.$ ",
+"V.* $ + + + + O + + o X X X + V.",
+"V.V.V.V.V...u.3.3.e...V.V.V.V.V.",
+"V.} d , t , t , t , i , p s } V.",
+"r o.$.O. .O. .O.| O. .O. [email protected] ",
+"O v.b.n.n.N.N.N.B.N.B.n.n.n.v.+ ",
+"O                             + "
+};
diff -urN wireshark-1.2.2/image/iscsi_r2t.xpm wireshark-1.2.2-iscsie/image/iscsi_r2t.xpm
--- wireshark-1.2.2/image/iscsi_r2t.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_r2t.xpm	2010-01-19 13:42:26.000000000 +0800
@@ -0,0 +1,25 @@
+/* XPM */
+static char * iscsi_r2t_xpm[] = {
+"16 16 6 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #4FFF00",
+"#	c #51B200",
+"$	c #213D00",
+"                ",
+"                ",
+"                ",
+"         ##     ",
+"         #@#    ",
+"### ### ##@@#   ",
+"#@# #@# #@@@@#  ",
+"#@# #@# #@@@@@$ ",
+"#@# #@# #@@@@$  ",
+"$$$ $$$ $$@@$   ",
+"         $@$    ",
+"         $$     ",
+"                ",
+"                ",
+"                ",
+"                "};
diff -urN wireshark-1.2.2/image/iscsi_reject.xpm wireshark-1.2.2-iscsie/image/iscsi_reject.xpm
--- wireshark-1.2.2/image/iscsi_reject.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_reject.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,26 @@
+/* XPM */
+static char * iscsi_reject_xpm[] = {
+"16 16 7 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #C4542D",
+"#	c #FF2A00",
+"$	c #8F2915",
+"%	c #B04530",
+"    %%%%%%%%    ",
+"   %########%   ",
+"  @##      ##%  ",
+" @##        ##% ",
+"@##  ##      ##$",
+"@#  ####      #$",
+"@#  %####     #$",
+"@#   %####    #$",
+"@#    %####   #$",
+"@#     %####  #$",
+"@#      %##%  #$",
+"%##      %%  ##$",
+" %##        ##% ",
+"  %##      ##%  ",
+"   %########%   ",
+"    %%%%%%%%    "};
diff -urN wireshark-1.2.2/image/iscsi_scsi_cmd.xpm wireshark-1.2.2-iscsie/image/iscsi_scsi_cmd.xpm
--- wireshark-1.2.2/image/iscsi_scsi_cmd.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_scsi_cmd.xpm	2010-01-19 13:42:26.000000000 +0800
@@ -0,0 +1,21 @@
+/* XPM */
+static char * iscsi_scsi_cmd_xpm[] = {
+"16 16 2 1",
+" 	c None",
+".	c #000000",
+"                ",
+"                ",
+".... .... .... .",
+".    .    .    .",
+".... .    .... .",
+"   . .       . .",
+".... .... .... .",
+"                ",
+"             .  ",
+"             .. ",
+"................",
+"................",
+"             .. ",
+"             .  ",
+"                ",
+"                "};
diff -urN wireshark-1.2.2/image/iscsi_scsi_datain.xpm wireshark-1.2.2-iscsie/image/iscsi_scsi_datain.xpm
--- wireshark-1.2.2/image/iscsi_scsi_datain.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_scsi_datain.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,28 @@
+/* XPM */
+static char * iscsi_scsi_datain_xpm[] = {
+"16 16 9 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #2492D8",
+"#	c #71C3F7",
+"$	c #2EB200",
+"%	c #124700",
+"&	c #30AA00",
+"*	c #616161",
+"    ########### ",
+"    @@@@@@@@@@@ ",
+"    ........... ",
+"    .*******... ",
+"    ........... ",
+"    .*****..... ",
+"    ........... ",
+"    ........... ",
+"    ........... ",
+"                ",
+"    $           ",
+"   $$           ",
+"  $$$$$$$$$$$$& ",
+"  %$$%%%%%%%%%% ",
+"   %$           ",
+"    %           "};
diff -urN wireshark-1.2.2/image/iscsi_scsi_dataout.xpm wireshark-1.2.2-iscsie/image/iscsi_scsi_dataout.xpm
--- wireshark-1.2.2/image/iscsi_scsi_dataout.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_scsi_dataout.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,28 @@
+/* XPM */
+static char * iscsi_scsi_dataout_xpm[] = {
+"16 16 9 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #2492D8",
+"#	c #71C3F7",
+"$	c #2EB200",
+"%	c #124700",
+"&	c #30AA00",
+"*	c #616161",
+"    ########### ",
+"    @@@@@@@@@@@ ",
+"    ........... ",
+"    .*******... ",
+"    ........... ",
+"    .*****..... ",
+"    ........... ",
+"    ........... ",
+"    ........... ",
+"                ",
+"    $           ",
+"   $$           ",
+"  $$$$$$$$$$$$& ",
+"  %$$%%%%%%%%%% ",
+"   %$           ",
+"    %           "};
diff -urN wireshark-1.2.2/image/iscsi_scsi_rsp.xpm wireshark-1.2.2-iscsie/image/iscsi_scsi_rsp.xpm
--- wireshark-1.2.2/image/iscsi_scsi_rsp.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_scsi_rsp.xpm	2010-01-19 13:42:26.000000000 +0800
@@ -0,0 +1,24 @@
+/* XPM */
+static char * iscsi_scsi_rsp_xpm[] = {
+"16 16 5 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #2EB200",
+"#	c #124700",
+"                ",
+"                ",
+".... .... .... .",
+".    .    .    .",
+".... .    .... .",
+"   . .       . .",
+".... .... .... .",
+"                ",
+"  @             ",
+" @@             ",
+"@@@@@@@@@@@@@@@@",
+"#@@#############",
+" #@             ",
+"  #             ",
+"                ",
+"                "};
diff -urN wireshark-1.2.2/image/iscsi_session.xpm wireshark-1.2.2-iscsie/image/iscsi_session.xpm
--- wireshark-1.2.2/image/iscsi_session.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_session.xpm	2009-12-25 09:02:29.000000000 +0800
@@ -0,0 +1,129 @@
+/* XPM */
+static const char *iscsi_session_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 107 2",
+"   c #555753",
+".  c #565854",
+"X  c #5C5E5A",
+"o  c #5D5F5B",
+"O  c #60625D",
+"+  c #60625E",
+"@  c #61635E",
+"#  c #61635F",
+"$  c #62645F",
+"%  c #626460",
+"&  c #636560",
+"*  c #636561",
+"=  c #646662",
+"-  c #656863",
+";  c #666964",
+":  c #676964",
+">  c #686A66",
+",  c #696B67",
+"<  c #696C67",
+"1  c #6A6C67",
+"2  c #6B6E68",
+"3  c #6C6E69",
+"4  c #6C6E6A",
+"5  c #6E716C",
+"6  c #6F716C",
+"7  c #71736F",
+"8  c #747671",
+"9  c #747672",
+"0  c #747772",
+"q  c #757772",
+"w  c #757773",
+"e  c #757873",
+"r  c #767873",
+"t  c #767974",
+"y  c #777974",
+"u  c #777A75",
+"i  c #787A75",
+"p  c #797C77",
+"a  c #7A7C78",
+"s  c #7A7D78",
+"d  c #787C7A",
+"f  c #797D7B",
+"g  c #7C7E79",
+"h  c #204A87",
+"j  c #3C6196",
+"k  c #496B9D",
+"l  c #4A6C9E",
+"z  c #667A95",
+"x  c #486FA4",
+"c  c #4F76A9",
+"v  c #5978A5",
+"b  c #5982B3",
+"n  c #5E87B9",
+"m  c #6284B1",
+"M  c #6889B5",
+"N  c #6C8DB7",
+"B  c #618BBC",
+"V  c #6C8DB8",
+"C  c #728DB4",
+"Z  c #6790BF",
+"A  c #7992B7",
+"S  c #6790C1",
+"D  c #6A93C2",
+"F  c #858782",
+"G  c #868883",
+"H  c #878984",
+"J  c #8E908B",
+"K  c #91928F",
+"L  c #929490",
+"P  c #9FA19B",
+"I  c #ABADA9",
+"U  c #AFB1AB",
+"Y  c #B0B2AE",
+"T  c #BBBDB8",
+"R  c #C1C3BE",
+"E  c #C2C3C1",
+"W  c #C3C4C0",
+"Q  c #C4C6C0",
+"!  c #C6C8C2",
+"~  c #C8CAC4",
+"^  c #CACCC6",
+"/  c #CBCDC8",
+"(  c #CDCFCA",
+")  c #D3D5D0",
+"_  c #D8D9D5",
+"`  c #D8DAD6",
+"'  c #D9DBD7",
+"]  c #DBDCD8",
+"[  c #DCDDD9",
+"{  c #DCDDDA",
+"}  c #DDDEDB",
+"|  c #E0E0DD",
+" . c #E0E1DD",
+".. c #E1E2DE",
+"X. c #E2E3DF",
+"o. c #E3E3E0",
+"O. c #E6E6E3",
+"+. c #E9E9E6",
+"@. c #E9E9E8",
+"#. c #EBEBE9",
+"$. c #EBECEA",
+"%. c #F4F4F3",
+"&. c #F6F6F5",
+"*. c #F7F7F6",
+"=. c #F8F8F7",
+"-. c #F9F9F8",
+";. c None",
+/* pixels */
+";.g i i i y y y 8 e y ;.;.;.;.;.",
+"p T ) '  .O.#.+.o.{ R 9 ;.;.;.;.",
+"8 / h h h h h h h h ` 5 ;.;.;.;.",
+"7 ^ h j z d i i y y y y y e y ;.",
+"5 ~ h x d T ) ' | O.#.+.o.{ R 9 ",
+"3 ! h b 8 / h h h h h h h h ` 5 ",
+", Q h h 7 ^ h j v l l A C h ' 2 ",
+"1 U ~ ( 5 ~ h x m c V V M h ' 2 ",
+";.: = $ 3 ~ h b n B D S B h } : ",
+";.G p , , R h h h h h h h h ] = ",
+"e L Y P 3 Y ~ ( ) ' }  . .} R : ",
+"o #.%.%.R 6 = $ = $ $ $ $ $ = ;.",
+"o .     . i d , J , K , J d F ;.",
+";.;.;.;.8 K Y P G P G P H I K 8 ",
+";.;.;.;.o +.%.&.&.=.-.=.&.&.$.o ",
+";.;.;.;.o .                   o "
+};
diff -urN wireshark-1.2.2/image/iscsi_snack.xpm wireshark-1.2.2-iscsie/image/iscsi_snack.xpm
--- wireshark-1.2.2/image/iscsi_snack.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_snack.xpm	2010-01-19 13:42:26.000000000 +0800
@@ -0,0 +1,28 @@
+/* XPM */
+static char * iscsi_snack_xpm[] = {
+"16 16 9 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #6EC300",
+"#	c #2B4D00",
+"$	c #62AB03",
+"%	c #410C00",
+"&	c #EC0000",
+"*	c #B70707",
+"                ",
+"                ",
+"$         *     ",
+"@$        &*    ",
+"$@$       &&*   ",
+" $@$       &&*  ",
+"  $@$       &&* ",
+"   @@# .. .. &&%",
+"  $@#       &&% ",
+" $@#       &&%  ",
+"$@#       &&%   ",
+"@#        &%    ",
+"#         %     ",
+"                ",
+"                ",
+"                "};
diff -urN wireshark-1.2.2/image/iscsi_text_request.xpm wireshark-1.2.2-iscsie/image/iscsi_text_request.xpm
--- wireshark-1.2.2/image/iscsi_text_request.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_text_request.xpm	2010-01-19 13:42:26.000000000 +0800
@@ -0,0 +1,27 @@
+/* XPM */
+static char * iscsi_text_request_xpm[] = {
+"16 16 8 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #FFF495",
+"#	c #C7B137",
+"$	c #665401",
+"%	c #EBD66F",
+"&	c #CFAD5D",
+"%%%%%%%%#       ",
+"%@@@@@@@##      ",
+"%@&&&&&&@@$     ",
+"%@@@@@@@@@$     ",
+"%@&&&&&&&@$     ",
+"%@@@@@@@@@$     ",
+"%@&&&&@@@@$     ",
+"%@@@@@@@@@$     ",
+"%@@@@@@@@@$     ",
+"$$$$$$$$$$$     ",
+"            .   ",
+"            ..  ",
+"............... ",
+"............... ",
+"            ..  ",
+"            .   "};
diff -urN wireshark-1.2.2/image/iscsi_text_response.xpm wireshark-1.2.2-iscsie/image/iscsi_text_response.xpm
--- wireshark-1.2.2/image/iscsi_text_response.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_text_response.xpm	2010-01-19 13:42:26.000000000 +0800
@@ -0,0 +1,29 @@
+/* XPM */
+static char * iscsi_text_response_xpm[] = {
+"16 16 10 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #2EB200",
+"#	c #124700",
+"$	c #FFF495",
+"%	c #C7B137",
+"&	c #665401",
+"*	c #EBD66F",
+"=	c #CFAD5D",
+"     ********%  ",
+"     *$$$$$$$%% ",
+"     *$======$$&",
+"     *$$$$$$$$$&",
+"     *$=======$&",
+"     *$$$$$$$$$&",
+"     *$====$$$$&",
+"     *$$$$$$$$$&",
+"     *$$$$$$$$$&",
+"     &&&&&&&&&&&",
+"   @            ",
+"  @@            ",
+" @@@@@@@@@@@@@@@",
+" #@@############",
+"  #@            ",
+"   #            "};
diff -urN wireshark-1.2.2/image/iscsi_tmf_rq.xpm wireshark-1.2.2-iscsie/image/iscsi_tmf_rq.xpm
--- wireshark-1.2.2/image/iscsi_tmf_rq.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_tmf_rq.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,28 @@
+/* XPM */
+static char * iscsi_tmf_rq_xpm[] = {
+"16 16 9 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #2EB200",
+"#	c #124700",
+"$	c #FFF495",
+"%	c #C7B137",
+"&	c #665401",
+"*	c #EBD66F",
+"     ********%  ",
+"     *$$$$$$$%% ",
+"     *$$$$$$$%%&",
+"     *$$$$$$$$$&",
+"     *$$$$$$$$$&",
+"     *$$$$$$$$$&",
+"     *$$$$$$$$$&",
+"     *$$$$$$$$$&",
+"     *$$$$$$$$$&",
+"     &&&&&&&&&&&",
+"   @            ",
+"  @@            ",
+" @@@@@@@@@@@@@@@",
+" #@@############",
+"  #@            ",
+"   #            "};
diff -urN wireshark-1.2.2/image/iscsi_tmf_rsp.xpm wireshark-1.2.2-iscsie/image/iscsi_tmf_rsp.xpm
--- wireshark-1.2.2/image/iscsi_tmf_rsp.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_tmf_rsp.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,28 @@
+/* XPM */
+static char * iscsi_tmf_rsp_xpm[] = {
+"16 16 9 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #2EB200",
+"#	c #124700",
+"$	c #FFF495",
+"%	c #C7B137",
+"&	c #665401",
+"*	c #EBD66F",
+"     ********%  ",
+"     *$$$$$$$%% ",
+"     *$$$$$$$%%&",
+"     *$$$$$$$$$&",
+"     *$$$$$$$$$&",
+"     *$$$$$$$$$&",
+"     *$$$$$$$$$&",
+"     *$$$$$$$$$&",
+"     *$$$$$$$$$&",
+"     &&&&&&&&&&&",
+"   @            ",
+"  @@            ",
+" @@@@@@@@@@@@@@@",
+" #@@############",
+"  #@            ",
+"   #            "};
diff -urN wireshark-1.2.2/image/iscsi_toarrow.xpm wireshark-1.2.2-iscsie/image/iscsi_toarrow.xpm
--- wireshark-1.2.2/image/iscsi_toarrow.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_toarrow.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,21 @@
+/* XPM */
+static char * iscsi_toarrow_xpm[] = {
+"16 16 2 1",
+" 	c None",
+".	c #000000",
+"                ",
+"                ",
+"                ",
+"           .    ",
+"           ..   ",
+"..............  ",
+"............... ",
+"................",
+"............... ",
+"..............  ",
+"           ..   ",
+"           .    ",
+"                ",
+"                ",
+"                ",
+"                "};
diff -urN wireshark-1.2.2/image/iscsi_tvs.xpm wireshark-1.2.2-iscsie/image/iscsi_tvs.xpm
--- wireshark-1.2.2/image/iscsi_tvs.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_tvs.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,28 @@
+/* XPM */
+static char * iscsi_tvs_xpm[] = {
+"16 16 9 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #2EB200",
+"#	c #124700",
+"$	c #FFF495",
+"%	c #C7B137",
+"&	c #665401",
+"*	c #EBD66F",
+"     ********%  ",
+"     *$$$$$$$%% ",
+"     *$$$$$$$%%&",
+"     *$$$$$$$$$&",
+"     *$$$$$$$$$&",
+"     *$$$$$$$$$&",
+"     *$$$$$$$$$&",
+"     *$$$$$$$$$&",
+"     *$$$$$$$$$&",
+"     &&&&&&&&&&&",
+"   @            ",
+"  @@            ",
+" @@@@@@@@@@@@@@@",
+" #@@############",
+"  #@            ",
+"   #            "};
diff -urN wireshark-1.2.2/image/iscsi_warn.xpm wireshark-1.2.2-iscsie/image/iscsi_warn.xpm
--- wireshark-1.2.2/image/iscsi_warn.xpm	1970-01-01 08:00:00.000000000 +0800
+++ wireshark-1.2.2-iscsie/image/iscsi_warn.xpm	2009-12-23 13:54:52.000000000 +0800
@@ -0,0 +1,25 @@
+/* XPM */
+static char * iscsi_warn_xpm[] = {
+"16 16 6 1",
+" 	c None",
+".	c #000000",
+"+	c #FFFFFF",
+"@	c #C4542D",
+"#	c #FF2A00",
+"$	c #8F2915",
+"                ",
+"      @@$       ",
+"      @#$       ",
+"      @#$       ",
+"      @#$       ",
+"      @#$       ",
+"      @#$       ",
+"      @#$       ",
+"      @#$       ",
+"      $$$       ",
+"                ",
+"      @@$       ",
+"      @@$       ",
+"      $$$       ",
+"                ",
+"                "};