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/FIN@tcp.flags & 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]
+@check@iscsi.scsiresponse.status == 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 () inventectj com>
+ * 				   Qian Zhang <Zhang.qian () inventectj com>
+ * 				   Ying-chao Yang <Yang.ying-chao () inventectj com>
+ * 				   Cang-mou Cao	<Cao.cang-mou () inventectj com>
+ * 				   Xing-jia	Wang <Wang.xing-jia () inventectj com>
+ * 
+ * $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 () inventectj com>
+ * 				   Qian Zhang <Zhang.qian () inventectj com>
+ * 				   Ying-chao Yang <Yang.ying-chao () inventectj com>
+ * 				   Cang-mou Cao	<Cao.cang-mou () inventectj com>
+ * 				   Xing-jia	Wang <Wang.xing-jia () inventectj com>
+ *
+ * $Id: packet-iscsiexpert.c 28363 2009-05-14 19:28:07Z etxrab $
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald () wireshark org>
+ * 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 () inventectj com>
+ * 				   Qian Zhang <Zhang.qian () inventectj com>
+ * 				   Ying-chao Yang <Yang.ying-chao () inventectj com>
+ * 				   Cang-mou Cao	<Cao.cang-mou () inventectj com>
+ * 				   Xing-jia	Wang <Wang.xing-jia () inventectj com>
+ *
+ * $Id: packet-iscsiexpert.h 27792 2009-03-18 23:30:21Z guy $
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald () wireshark org>
+ * 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 () inventectj com>
+ * 				   Qian Zhang <Zhang.qian () inventectj com>
+ * 				   Ying-chao Yang <Yang.ying-chao () inventectj com>
+ * 				   Cang-mou Cao	<Cao.cang-mou () inventectj com>
+ * 				   Xing-jia	Wang <Wang.xing-jia () inventectj com>
+ *
+ * $Id: iscsisession.c 25158 2008-04-23 21:31:50Z jake $
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald () wireshark org>
+ * 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 () inventectj com>
+ * 				   Qian Zhang <Zhang.qian () inventectj com>
+ * 				   Ying-chao Yang <Yang.ying-chao () inventectj com>
+ * 				   Cang-mou Cao	<Cao.cang-mou () inventectj com>
+ * 				   Xing-jia	Wang <Wang.xing-jia () inventectj com>
+ *
+ * $Id: iscsisession.h 24644 2008-03-15 23:01:12Z guy $
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald () wireshark org>
+ * 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 () inventectj com>
+ * 				   Qian Zhang <Zhang.qian () inventectj com>
+ * 				   Ying-chao Yang <Yang.ying-chao () inventectj com>
+ * 				   Cang-mou Cao	<Cao.cang-mou () inventectj com>
+ * 				   Xing-jia	Wang <Wang.xing-jia () inventectj com>
+ *
+ *
+ * $Id: expert_dlg.c 28709 2009-06-11 18:38:15Z gerald $
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald () wireshark org>
+ * 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 () inventectj com>
+ * 				   Qian Zhang <Zhang.qian () inventectj com>
+ * 				   Ying-chao Yang <Yang.ying-chao () inventectj com>
+ * 				   Cang-mou Cao	<Cao.cang-mou () inventectj com>
+ * 				   Xing-jia	Wang <Wang.xing-jia () inventectj com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald () wireshark org>
+ * 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 #.@.i 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 #.@.i 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 #.@.i 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 #.@.i 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.",
+"D.D.D.D.D.@.d.8.8.i.@.D.D.D.D.D.",
+"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. .@.o.8 ",
+"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",
+"                ",
+"      @@$       ",
+"      @#$       ",
+"      @#$       ",
+"      @#$       ",
+"      @#$       ",
+"      @#$       ",
+"      @#$       ",
+"      @#$       ",
+"      $$$       ",
+"                ",
+"      @@$       ",
+"      @@$       ",
+"      $$$       ",
+"                ",
+"                "};
