aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/Makefile.common2
-rw-r--r--epan/dissectors/packet-clnp.c30
-rw-r--r--epan/dissectors/packet-dcerpc.c70
-rw-r--r--epan/dissectors/packet-dcom.c42
-rw-r--r--epan/dissectors/packet-frame.c20
-rw-r--r--epan/dissectors/packet-http.c3
-rw-r--r--epan/dissectors/packet-tcp.c53
-rw-r--r--epan/epan.c3
-rw-r--r--epan/expert.c117
-rw-r--r--epan/expert.h60
-rw-r--r--epan/libethereal.def4
-rw-r--r--epan/proto.c26
-rw-r--r--epan/proto.h61
-rw-r--r--gtk/Makefile.common1
-rw-r--r--gtk/expert_dlg.c511
-rw-r--r--gtk/proto_draw.c66
-rw-r--r--gtk/proto_draw.h10
17 files changed, 1019 insertions, 60 deletions
diff --git a/epan/Makefile.common b/epan/Makefile.common
index 150140a00a..339d516345 100644
--- a/epan/Makefile.common
+++ b/epan/Makefile.common
@@ -49,6 +49,7 @@ LIBETHEREAL_SRC = \
emem.c \
epan.c \
except.c \
+ expert.c \
filesystem.c \
follow.c \
frame_data.c \
@@ -115,6 +116,7 @@ LIBETHEREAL_INCLUDES = \
epan_dissect.h \
except.h \
exceptions.h \
+ expert.h \
filesystem.h \
follow.h \
frame_data.h \
diff --git a/epan/dissectors/packet-clnp.c b/epan/dissectors/packet-clnp.c
index b7c734cf32..e7501d5c6c 100644
--- a/epan/dissectors/packet-clnp.c
+++ b/epan/dissectors/packet-clnp.c
@@ -41,6 +41,7 @@
#include "packet-esis.h"
#include "nlpid.h"
#include <epan/ipproto.h>
+#include <epan/expert.h>
/* protocols and fields */
@@ -782,7 +783,7 @@ static int ositp_decode_DR(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
packet_info *pinfo, proto_tree *tree)
{
proto_tree *cotp_tree;
- proto_item *ti;
+ proto_item *ti = NULL;
guint16 dst_ref, src_ref;
guchar reason;
const char *str;
@@ -843,6 +844,9 @@ static int ositp_decode_DR(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
offset += li + 1;
+ expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_CHAT,
+ "Disconnect Request(DR): 0x%x -> 0x%x", src_ref, dst_ref);
+
/* User data */
call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1), pinfo, tree);
offset += tvb_length_remaining(tvb, offset);
@@ -1176,6 +1180,7 @@ static int ositp_decode_RJ(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
{
proto_tree *cotp_tree;
proto_item *ti;
+ proto_item *item = NULL;
guint16 dst_ref;
guint tpdu_nr;
gushort credit = 0;
@@ -1206,7 +1211,7 @@ static int ositp_decode_RJ(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE);
cotp_tree = proto_item_add_subtree(ti, ett_cotp);
proto_tree_add_uint(cotp_tree, hf_cotp_li, tvb, offset, 1,li);
- proto_tree_add_uint(cotp_tree, hf_cotp_type, tvb, offset + 1, 1, tpdu);
+ item = proto_tree_add_uint(cotp_tree, hf_cotp_type, tvb, offset + 1, 1, tpdu);
if (li == LI_NORMAL_RJ)
proto_tree_add_text(cotp_tree, tvb, offset + 1, 1,
"Credit: %u", cdt);
@@ -1224,6 +1229,9 @@ static int ositp_decode_RJ(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
offset += li + 1;
+ expert_add_info_format(pinfo, item, PI_SEQUENCE, PI_NOTE,
+ "Reject(RJ): -> 0x%x", dst_ref);
+
return offset;
} /* ositp_decode_RJ */
@@ -1238,6 +1246,7 @@ static int ositp_decode_CC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
proto_tree *cotp_tree = NULL;
proto_item *ti;
+ proto_item *item = NULL;
guint16 dst_ref, src_ref;
guchar class_option;
tvbuff_t *next_tvb;
@@ -1266,7 +1275,7 @@ static int ositp_decode_CC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
offset += 1;
if (tree) {
- proto_tree_add_uint(cotp_tree, hf_cotp_type, tvb, offset, 1, tpdu);
+ item = proto_tree_add_uint(cotp_tree, hf_cotp_type, tvb, offset, 1, tpdu);
}
offset += 1;
li -= 1;
@@ -1281,6 +1290,14 @@ static int ositp_decode_CC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
offset += 2;
li -= 2;
+ /* expert info, but only if not encapsulated in TCP/SMB */
+ /* XXX - the best way to detect seems to be if we have a port set */
+ if (pinfo->destport == 0) {
+ expert_add_info_format(pinfo, item, PI_SEQUENCE, PI_CHAT,
+ tpdu == CR_TPDU ? "Connection Request(CR): 0x%x -> 0x%x" : "Connection Confirm(CC): 0x%x -> 0x%x",
+ src_ref, dst_ref);
+ }
+
if (tree) {
proto_tree_add_text(cotp_tree, tvb, offset, 1,
"Class option: 0x%02x", class_option);
@@ -1315,6 +1332,7 @@ static int ositp_decode_DC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
{
proto_tree *cotp_tree = NULL;
proto_item *ti;
+ proto_item *item = NULL;
guint16 dst_ref, src_ref;
if (li > LI_MAX_DC)
@@ -1339,7 +1357,7 @@ static int ositp_decode_DC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
offset += 1;
if (tree) {
- proto_tree_add_uint(cotp_tree, hf_cotp_type, tvb, offset, 1, tpdu);
+ item = proto_tree_add_uint(cotp_tree, hf_cotp_type, tvb, offset, 1, tpdu);
}
offset += 1;
li -= 1;
@@ -1358,6 +1376,9 @@ static int ositp_decode_DC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu,
ositp_decode_var_part(tvb, offset, li, 4, cotp_tree);
offset += li;
+ expert_add_info_format(pinfo, item, PI_SEQUENCE, PI_CHAT,
+ "Disconnect Confirm(DC): 0x%x -> 0x%x", src_ref, dst_ref);
+
return offset;
} /* ositp_decode_DC */
@@ -1684,6 +1705,7 @@ static gboolean dissect_ositp_internal(tvbuff_t *tvb, packet_info *pinfo,
if (!first_tpdu) {
if (check_col(pinfo->cinfo, COL_INFO))
col_append_str(pinfo->cinfo, COL_INFO, ", ");
+ expert_add_info_format(pinfo, NULL, PI_SEQUENCE, PI_NOTE, "Multiple TDPUs in one packet");
}
if ((li = tvb_get_guint8(tvb, offset + P_LI)) == 0) {
if (check_col(pinfo->cinfo, COL_INFO))
diff --git a/epan/dissectors/packet-dcerpc.c b/epan/dissectors/packet-dcerpc.c
index 9fad9ef11d..57fbbee4bf 100644
--- a/epan/dissectors/packet-dcerpc.c
+++ b/epan/dissectors/packet-dcerpc.c
@@ -45,6 +45,7 @@
#include <epan/emem.h>
#include <epan/dissectors/packet-frame.h>
#include <epan/dissectors/packet-dcerpc-nt.h>
+#include <epan/expert.h>
static int dcerpc_tap = -1;
@@ -284,6 +285,29 @@ static const value_string reject_status_vals[] = {
{ 0x1c010013, "nca_out_args_too_big" },
{ 0x1c010014, "nca_server_too_busy" },
{ 0x1c010017, "nca_unsupported_type" },
+ /* MS Windows specific values
+ * see: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/system_error_codes__1700-3999_.asp
+ * and: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/seccrypto/security/common_hresult_values.asp
+ * and: http://www.megos.ch/support/doserrors.txt
+ *
+ * XXX - we might need a way to dynamically add entries here, as higher layer protocols use these values too,
+ * at least MS protocols (like DCOM) do it that way ... */
+ { 0x80004001, "E_NOTIMPL" },
+ { 0x80004003, "E_POINTER" },
+ { 0x80004004, "E_ABORT" },
+ { 0x80010105, "RPC_E_SERVERFAULT" },
+ { 0x80010108, "RPC_E_DISCONNECTED" },
+ { 0x80010113, "RPC_E_INVALID_IPID" },
+ { 0x80020006, "DISP_E_UNKNOWNNAME" },
+ { 0x8004CB00, "CBA_E_MALFORMED" },
+ { 0x8004CB01, "CBA_E_UNKNOWNOBJECT" },
+ { 0x8004CB09, "CBA_E_INVALIDCOOKIE" },
+ { 0x8004CB0B, "CBA_E_QOSTYPEUNSUPPORTED" },
+ { 0x8004CB0C, "CBA_E_QOSVALUEUNSUPPORTED" },
+ { 0x8004CB0F, "CBA_E_NOTAPPLICABLE" },
+ { 0x8004CB12, "CBA_E_LIMITVIOLATION" },
+ { 0x80070057, "E_INVALIDARG" },
+ { 0x800706d1, "RPC_S_PROCNUM_OUT_OF_RANGE" },
{ 0, NULL }
};
@@ -3040,6 +3064,8 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
col_append_fstr(pinfo->cinfo, COL_INFO,
" [DCE/RPC %s fragment]", fragment_type(hdr->flags));
}
+ expert_add_info_format(pinfo, NULL, PI_REASSEMBLE, PI_CHAT,
+ "%s fragment", fragment_type(hdr->flags));
pinfo->fragmented = save_fragmented;
return;
}
@@ -3166,6 +3192,9 @@ end_cn_stub:
pinfo->fragmented = FALSE;
+ expert_add_info_format(pinfo, NULL, PI_REASSEMBLE, PI_CHAT,
+ "%s fragment, reassembled here in #%u", fragment_type(hdr->flags), fd_head->reassembled_in);
+
dcerpc_try_handoff (pinfo, tree, dcerpc_tree, next_tvb,
next_tvb, hdr->drep, di, auth_info);
@@ -3181,6 +3210,8 @@ end_cn_stub:
col_append_fstr(pinfo->cinfo, COL_INFO,
" [DCE/RPC %s fragment, reas: #%u]", fragment_type(hdr->flags), fd_head->reassembled_in);
}
+ expert_add_info_format(pinfo, NULL, PI_REASSEMBLE, PI_CHAT,
+ "%s fragment, reassembled in #%u", fragment_type(hdr->flags), fd_head->reassembled_in);
}
} else {
/* Reassembly not complete - some fragments
@@ -3189,6 +3220,8 @@ end_cn_stub:
col_append_fstr(pinfo->cinfo, COL_INFO,
" [DCE/RPC %s fragment]", fragment_type(hdr->flags));
}
+ expert_add_info_format(pinfo, NULL, PI_REASSEMBLE, PI_CHAT,
+ "%s fragment", fragment_type(hdr->flags));
if(decrypted_tvb){
show_stub_data (decrypted_tvb, 0, tree, auth_info, FALSE);
@@ -3560,7 +3593,7 @@ dissect_dcerpc_cn_fault (tvbuff_t *tvb, gint offset, packet_info *pinfo,
guint32 status;
guint32 alloc_hint;
dcerpc_auth_info auth_info;
- proto_item *pi;
+ proto_item *pi = NULL;
offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
hf_dcerpc_cn_alloc_hint, &alloc_hint);
@@ -3573,8 +3606,19 @@ dissect_dcerpc_cn_fault (tvbuff_t *tvb, gint offset, packet_info *pinfo,
/* padding */
offset++;
- offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
- hf_dcerpc_cn_status, &status);
+ /*offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_dcerpc_cn_status, &status);*/
+ status = ((hdr->drep[0] & 0x10)
+ ? tvb_get_letohl (tvb, offset)
+ : tvb_get_ntohl (tvb, offset));
+
+ if (dcerpc_tree) {
+ pi = proto_tree_add_item (dcerpc_tree, hf_dcerpc_cn_status, tvb, offset, 4, (hdr->drep[0] & 0x10));
+ }
+ offset+=4;
+
+ expert_add_info_format(pinfo, pi, PI_APPL_RESPONSE, PI_NOTE, "Fault: %s",
+ val_to_str(status, reject_status_vals, "Unknown (0x%08x)"));
/* save context ID for use with dcerpc_add_conv_to_bind_table() */
pinfo->dcectxid = ctx_id;
@@ -3910,6 +3954,11 @@ dissect_dcerpc_cn (tvbuff_t *tvb, int offset, packet_info *pinfo,
pckt_vals[hdr.ptype].strptr, hdr.call_id);
}
+ if(pinfo->dcectxid != 0) {
+ /* this is not the first DCE-RPC request/response in this (TCP?-)PDU */
+ expert_add_info_format(pinfo, NULL, PI_SEQUENCE, PI_NOTE, "Multiple DCE/RPC fragments/PDU's in one packet");
+ }
+
if (tree) {
offset = start_offset;
tvb_ensure_bytes_exist(tvb, offset, hdr.frag_len);
@@ -3919,7 +3968,20 @@ dissect_dcerpc_cn (tvbuff_t *tvb, int offset, packet_info *pinfo,
}
proto_tree_add_uint (dcerpc_tree, hf_dcerpc_ver, tvb, offset++, 1, hdr.rpc_ver);
proto_tree_add_uint (dcerpc_tree, hf_dcerpc_ver_minor, tvb, offset++, 1, hdr.rpc_ver_minor);
- proto_tree_add_uint (dcerpc_tree, hf_dcerpc_packet_type, tvb, offset++, 1, hdr.ptype);
+ tf = proto_tree_add_uint (dcerpc_tree, hf_dcerpc_packet_type, tvb, offset++, 1, hdr.ptype);
+ } else {
+ tf = NULL;
+ }
+
+ /* XXX - too much "output noise", removed for now
+ if(hdr.ptype == PDU_BIND || hdr.ptype == PDU_ALTER ||
+ hdr.ptype == PDU_BIND_ACK || hdr.ptype == PDU_ALTER_ACK)
+ expert_add_info_format(pinfo, tf, PI_SEQUENCE, PI_CHAT, "Context change: %s",
+ val_to_str(hdr.ptype, pckt_vals, "(0x%x)"));*/
+ if(hdr.ptype == PDU_BIND_NAK)
+ expert_add_info_format(pinfo, tf, PI_SEQUENCE, PI_WARN, "Bind not acknowledged");
+
+ if (tree) {
proto_item_append_text(ti, " %s, Fragment:", val_to_str(hdr.ptype, pckt_vals, "Unknown (0x%02x)"));
tf = proto_tree_add_uint (dcerpc_tree, hf_dcerpc_cn_flags, tvb, offset, 1, hdr.flags);
diff --git a/epan/dissectors/packet-dcom.c b/epan/dissectors/packet-dcom.c
index b64d1150c4..0a13d041c6 100644
--- a/epan/dissectors/packet-dcom.c
+++ b/epan/dissectors/packet-dcom.c
@@ -87,6 +87,7 @@
#include "packet-dcerpc.h"
#include "packet-dcom.h"
#include "prefs.h"
+#include "expert.h"
static int proto_dcom = -1;
@@ -339,10 +340,12 @@ const value_string dcom_hresult_vals[] = {
{ 0x80070057, "E_INVALIDARG" },
{ 0x80010108, "RPC_E_DISCONNECTED" },
+ { 0x80010113, "RPC_E_INVALID_IPID" },
{ 0x80020004, "DISP_E_PARAMNOTFOUND" },
{ 0x80040154, "REGDB_E_CLASSNOTREG" },
+ { 0x80040201, "CO_E_FAILEDTOGETSECCTX" },
/* following are CBA application specific values */
{ 0x0004CA00, "CBA_S_PERSISTPENDING" },
@@ -391,6 +394,9 @@ const value_string dcom_hresult_vals[] = {
{ 0x8004CB23, "CBA_E_FRAMECOUNTUNSUPPORTED" },
{ 0x8004CB24, "CBA_E_LINKFAILURE" },
{ 0x8004CB25, "CBA_E_MODECHANGE" },
+
+ { 0x80080004, "CO_E_BAD_PATH" },
+
{ 0, NULL }
};
@@ -730,11 +736,14 @@ extern int
dissect_dcom_tobedone_data(tvbuff_t *tvb, int offset,
packet_info *pinfo _U_, proto_tree *tree, guint8 *drep _U_, int length)
{
+ proto_item *item;
proto_tree_add_uint(tree, hf_dcom_tobedone_len, tvb, offset, length, length);
- proto_tree_add_bytes(tree, hf_dcom_tobedone, tvb, offset, length,
+ item = proto_tree_add_bytes(tree, hf_dcom_tobedone, tvb, offset, length,
tvb_get_ptr(tvb, offset, length));
+ expert_add_info_format(pinfo, item, PI_UNDECODED, PI_WARN, "%u bytes still undecoded", length);
+
offset += length;
return offset;
@@ -807,8 +816,26 @@ dissect_dcom_HRESULT(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, guint8 *drep,
guint32 * pu32HResult)
{
- offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, drep,
- hf_dcom_hresult, pu32HResult);
+ guint32 u32HResult;
+ proto_item *item = NULL;
+
+ /* dissect the DWORD, but don't add to tree */
+ offset = dissect_dcom_DWORD(tvb, offset, pinfo, NULL /*tree*/, drep,
+ hf_dcom_hresult, &u32HResult);
+
+ if (tree) {
+ /* special formatted output of indexed value */
+ item = proto_tree_add_item (tree, hf_dcom_hresult, tvb, offset-4, 4, (drep[0] & 0x10));
+ }
+
+ /* expert info only if severity is set */
+ /* XXX - move this to the callers of this function, to provide a more detailed error output */
+ if(u32HResult & 0x80000000) {
+ expert_add_info_format(pinfo, item, PI_APPL_RESPONSE, PI_NOTE, "Hresult: %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%x)"));
+ }
+ if (pu32HResult)
+ *pu32HResult = u32HResult;
return offset;
}
@@ -821,6 +848,7 @@ dissect_dcom_indexed_HRESULT(tvbuff_t *tvb, int offset, packet_info *pinfo,
guint32 * pu32HResult, int field_index)
{
guint32 u32HResult;
+ proto_item *item = NULL;
/* dissect the DWORD, but don't add to tree */
@@ -829,11 +857,17 @@ dissect_dcom_indexed_HRESULT(tvbuff_t *tvb, int offset, packet_info *pinfo,
if (tree) {
/* special formatted output of indexed value */
- proto_tree_add_uint_format(tree, hf_dcom_hresult, tvb, offset-4, 4, (drep[0] & 0x10),
+ item = proto_tree_add_uint_format(tree, hf_dcom_hresult, tvb, offset-4, 4, (drep[0] & 0x10),
"HResult[%u]: %s (0x%08x)", field_index,
val_to_str(u32HResult, dcom_hresult_vals, "Unknown"),
u32HResult);
}
+ /* expert info only if severity flag is set */
+ /* XXX - move this to the callers of this function, to provide a more detailed error output */
+ if(u32HResult & 0x80000000) {
+ expert_add_info_format(pinfo, item, PI_APPL_RESPONSE, PI_NOTE, "Hresult: %s",
+ val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%x)"));
+ }
if (pu32HResult)
*pu32HResult = u32HResult;
diff --git a/epan/dissectors/packet-frame.c b/epan/dissectors/packet-frame.c
index 9b581d8913..b7d35cad25 100644
--- a/epan/dissectors/packet-frame.c
+++ b/epan/dissectors/packet-frame.c
@@ -34,6 +34,7 @@
#include "packet-frame.h"
#include <epan/prefs.h>
#include <epan/tap.h>
+#include <epan/expert.h>
int proto_frame = -1;
int hf_frame_arrival_time = -1;
@@ -264,14 +265,18 @@ show_exception(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
{
static const char dissector_error_nomsg[] =
"Dissector writer didn't bother saying what the error was";
+ proto_item *item;
+
switch (exception) {
case BoundsError:
if (check_col(pinfo->cinfo, COL_INFO))
col_append_str(pinfo->cinfo, COL_INFO, "[Short Frame]");
- proto_tree_add_protocol_format(tree, proto_short, tvb, 0, 0,
+ item = proto_tree_add_protocol_format(tree, proto_short, tvb, 0, 0,
"[Short Frame: %s]", pinfo->current_proto);
+ expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
+ "Short Frame");
break;
case ReportedBoundsError:
@@ -285,7 +290,7 @@ show_exception(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
pinfo->current_proto,
exception_message == NULL ?
dissector_error_nomsg : exception_message);
- proto_tree_add_protocol_format(tree, proto_malformed, tvb, 0, 0,
+ item = proto_tree_add_protocol_format(tree, proto_malformed, tvb, 0, 0,
"[Dissector bug, protocol %s: %s]",
pinfo->current_proto,
exception_message == NULL ?
@@ -294,6 +299,9 @@ show_exception(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
pinfo->current_proto, pinfo->fd->num,
exception_message == NULL ?
dissector_error_nomsg : exception_message);
+ expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
+ exception_message == NULL ?
+ dissector_error_nomsg : exception_message);
if (exception_message != NULL)
g_free(exception_message);
break;
@@ -307,6 +315,8 @@ show_exception(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
void
show_reported_bounds_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
+ proto_item *item;
+
if (pinfo->fragmented) {
/*
* We were dissecting an unreassembled fragmented
@@ -320,15 +330,17 @@ show_reported_bounds_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
col_append_fstr(pinfo->cinfo, COL_INFO,
"[Unreassembled Packet%s]",
pinfo->noreassembly_reason);
- proto_tree_add_protocol_format(tree, proto_unreassembled,
+ item = proto_tree_add_protocol_format(tree, proto_unreassembled,
tvb, 0, 0, "[Unreassembled Packet%s: %s]",
pinfo->noreassembly_reason, pinfo->current_proto);
+ expert_add_info_format(pinfo, item, PI_REASSEMBLE, PI_WARN, "Unreassembled Packet (Exception occured)");
} else {
if (check_col(pinfo->cinfo, COL_INFO))
col_append_str(pinfo->cinfo, COL_INFO,
"[Malformed Packet]");
- proto_tree_add_protocol_format(tree, proto_malformed,
+ item = proto_tree_add_protocol_format(tree, proto_malformed,
tvb, 0, 0, "[Malformed Packet: %s]", pinfo->current_proto);
+ expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Malformed Packet (Exception occured)");
}
}
diff --git a/epan/dissectors/packet-http.c b/epan/dissectors/packet-http.c
index 6fb851fa93..741ee5ffa7 100644
--- a/epan/dissectors/packet-http.c
+++ b/epan/dissectors/packet-http.c
@@ -47,6 +47,7 @@
#include <epan/req_resp_hdrs.h>
#include "packet-http.h"
#include <epan/prefs.h>
+#include <epan/expert.h>
typedef enum _http_type {
HTTP_REQUEST,
@@ -755,6 +756,8 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo,
tvb_format_text(tvb, offset,
next_offset - offset));
}
+ expert_add_info_format(pinfo, hdr_item, PI_SEQUENCE, PI_CHAT,
+ tvb_format_text(tvb, offset, next_offset - offset));
if (reqresp_dissector) {
if (tree) req_tree = proto_item_add_subtree(hdr_item, ett_http_request);
else req_tree = NULL;
diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c
index 71f7351d26..6c59cb67d8 100644
--- a/epan/dissectors/packet-tcp.c
+++ b/epan/dissectors/packet-tcp.c
@@ -46,6 +46,7 @@
#include <epan/tap.h>
#include <epan/emem.h>
#include <epan/slab.h>
+#include <epan/expert.h>
static int tcp_tap = -1;
@@ -1306,13 +1307,14 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree
if( ta->flags&TCP_A_RETRANSMISSION ){
flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_retransmission, tvb, 0, 0, "This frame is a (suspected) retransmission");
PROTO_ITEM_SET_GENERATED(flags_item);
+ expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Retransmission (suspected)");
if(check_col(pinfo->cinfo, COL_INFO)){
col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Retransmission] ");
}
if( ta->rto_ts.secs || ta->rto_ts.nsecs ){
item = proto_tree_add_time(flags_tree, hf_tcp_analysis_rto,
tvb, 0, 0, &ta->rto_ts);
- PROTO_ITEM_SET_GENERATED(item);
+ PROTO_ITEM_SET_GENERATED(item);
item=proto_tree_add_uint(flags_tree, hf_tcp_analysis_rto_frame, tvb, 0, 0, ta->rto_frame);
PROTO_ITEM_SET_GENERATED(item);
}
@@ -1320,6 +1322,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree
if( ta->flags&TCP_A_FAST_RETRANSMISSION ){
flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_fast_retransmission, tvb, 0, 0, "This frame is a (suspected) fast retransmission");
PROTO_ITEM_SET_GENERATED(flags_item);
+ expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Fast retransmission (suspected)");
flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_retransmission, tvb, 0, 0, "This frame is a (suspected) retransmission");
PROTO_ITEM_SET_GENERATED(flags_item);
if(check_col(pinfo->cinfo, COL_INFO)){
@@ -1329,6 +1332,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree
if( ta->flags&TCP_A_OUT_OF_ORDER ){
flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_out_of_order, tvb, 0, 0, "This frame is a (suspected) out-of-order segment");
PROTO_ITEM_SET_GENERATED(flags_item);
+ expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Out-Of-Order segment");
if(check_col(pinfo->cinfo, COL_INFO)){
col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Out-Of-Order] ");
}
@@ -1336,6 +1340,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree
if( ta->flags&TCP_A_LOST_PACKET ){
flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_lost_packet, tvb, 0, 0, "A segment before this frame was lost");
PROTO_ITEM_SET_GENERATED(flags_item);
+ expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Previous segment lost (common at capture start)");
if(check_col(pinfo->cinfo, COL_INFO)){
col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Previous segment lost] ");
}
@@ -1343,6 +1348,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree
if( ta->flags&TCP_A_ACK_LOST_PACKET ){
flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_ack_lost_packet, tvb, 0, 0, "This frame ACKs a segment we have not seen (lost?)");
PROTO_ITEM_SET_GENERATED(flags_item);
+ expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "ACKed lost segment (common at capture start)");
if(check_col(pinfo->cinfo, COL_INFO)){
col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP ACKed lost segment] ");
}
@@ -1350,6 +1356,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree
if( ta->flags&TCP_A_WINDOW_UPDATE ){
flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_window_update, tvb, 0, 0, "This is a tcp window update");
PROTO_ITEM_SET_GENERATED(flags_item);
+ expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Window update");
if(check_col(pinfo->cinfo, COL_INFO)){
col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Update] ");
}
@@ -1357,6 +1364,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree
if( ta->flags&TCP_A_WINDOW_FULL ){
flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_window_full, tvb, 0, 0, "The transmission window is now completely full");
PROTO_ITEM_SET_GENERATED(flags_item);
+ expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Window is full");
if(check_col(pinfo->cinfo, COL_INFO)){
col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Full] ");
}
@@ -1364,6 +1372,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree
if( ta->flags&TCP_A_KEEP_ALIVE ){
flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_keep_alive, tvb, 0, 0, "This is a TCP keep-alive segment");
PROTO_ITEM_SET_GENERATED(flags_item);
+ expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Keep-Alive");
if(check_col(pinfo->cinfo, COL_INFO)){
col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive] ");
}
@@ -1371,6 +1380,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree
if( ta->flags&TCP_A_KEEP_ALIVE_ACK ){
flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_keep_alive_ack, tvb, 0, 0, "This is an ACK to a TCP keep-alive segment");
PROTO_ITEM_SET_GENERATED(flags_item);
+ expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Keep-Alive ACK");
if(check_col(pinfo->cinfo, COL_INFO)){
col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive ACK] ");
}
@@ -1389,10 +1399,13 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree
flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_frame,
tvb, 0, 0, ta->dupack_frame);
PROTO_ITEM_SET_GENERATED(flags_item);
+ expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Duplicate ACK (#%u) to ACK in packet #%u",
+ ta->dupack_num, ta->dupack_frame);
}
if( ta->flags&TCP_A_ZERO_WINDOW_PROBE ){
flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_zero_window_probe, tvb, 0, 0, "This is a TCP zero-window-probe");
PROTO_ITEM_SET_GENERATED(flags_item);
+ expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window probe");
if(check_col(pinfo->cinfo, COL_INFO)){
col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowProbe] ");
}
@@ -1400,7 +1413,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree
if( ta->flags&TCP_A_ZERO_WINDOW ){
flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_zero_window, tvb, 0, 0, "This is a ZeroWindow segment");
PROTO_ITEM_SET_GENERATED(flags_item);
- PROTO_ITEM_SET_SEQUENCE_WARNING(flags_item);
+ expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window");
if(check_col(pinfo->cinfo, COL_INFO)){
col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindow] ");
}
@@ -1408,6 +1421,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree
if( ta->flags&TCP_A_ZERO_WINDOW_VIOLATION ){
flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_zero_window_violation, tvb, 0, 0, "This is a ZeroWindow violation, attempts to write >1 byte of data to a zero-window");
PROTO_ITEM_SET_GENERATED(flags_item);
+ expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window violation");
if(check_col(pinfo->cinfo, COL_INFO)){
col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowViolation] ");
}
@@ -2679,6 +2693,7 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
struct tcpinfo tcpinfo;
static struct tcpheader tcphstruct[4], *tcph;
static int tcph_count=0;
+ proto_item *tf_syn = NULL, *tf_fin = NULL, *tf_rst = NULL;
tcph_count++;
if(tcph_count>=4){
@@ -2866,9 +2881,9 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, tcph->th_flags);
proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, tcph->th_flags);
proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, tcph->th_flags);
- proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, tcph->th_flags);
- proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, tcph->th_flags);
- proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, tcph->th_flags);
+ tf_rst = proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, tcph->th_flags);
+ tf_syn = proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, tcph->th_flags);
+ tf_fin = proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, tcph->th_flags);
if(tcp_relative_seq && (tcph->th_win!=real_window)){
proto_tree_add_uint_format(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, tcph->th_win, "Window size: %u (scaled)", tcph->th_win);
} else {
@@ -2876,6 +2891,20 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
}
+ if(tcph->th_flags & TH_SYN)
+ if(tcph->th_flags & TH_ACK)
+ expert_add_info_format(pinfo, tf_syn, PI_SEQUENCE, PI_CHAT, "Connection establish acknowledge (SYN+ACK): %s -> %s",
+ get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
+ else
+ expert_add_info_format(pinfo, tf_syn, PI_SEQUENCE, PI_CHAT, "Connection establish request (SYN): %s -> %s",
+ get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
+ if(tcph->th_flags & TH_FIN)
+ expert_add_info_format(pinfo, tf_fin, PI_SEQUENCE, PI_CHAT, "Connection finish (FIN): %s -> %s",
+ get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
+ if(tcph->th_flags & TH_RST)
+ expert_add_info_format(pinfo, tf_rst, PI_SEQUENCE, PI_CHAT, "Connection reset (RST): %s -> %s",
+ get_tcp_port(tcph->th_sport), get_tcp_port(tcph->th_dport));
+
/* Supply the sequence number of the first byte and of the first byte
after the segment. */
tcpinfo.seq = tcph->th_seq;
@@ -2937,13 +2966,15 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
} else {
proto_item *item;
- proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
+ item = proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
offset + 16, 2, th_sum,
"Checksum: 0x%04x [incorrect, should be 0x%04x]", th_sum,
in_cksum_shouldbe(th_sum, computed_cksum));
+ expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
item = proto_tree_add_boolean(tcp_tree, hf_tcp_checksum_bad, tvb,
offset + 16, 2, TRUE);
PROTO_ITEM_SET_GENERATED(item);
+ /* XXX - don't use hidden fields for checksums */
PROTO_ITEM_SET_HIDDEN(item);
if (check_col(pinfo->cinfo, COL_INFO))
@@ -2955,7 +2986,7 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
} else {
proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
- offset + 16, 2, th_sum, "Checksum: 0x%04x", th_sum);
+ offset + 16, 2, th_sum, "Checksum: 0x%04x [validation disabled]", th_sum);
/* We didn't check the checksum, and don't care if it's valid,
so we're willing to desegment it. */
@@ -2964,7 +2995,7 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
} else {
/* We don't have all the packet data, so we can't checksum it... */
proto_tree_add_uint_format(tcp_tree, hf_tcp_checksum, tvb,
- offset + 16, 2, th_sum, "Checksum: 0x%04x", th_sum);
+ offset + 16, 2, th_sum, "Checksum: 0x%04x [unchecked, not all data available]", th_sum);
/* ...and aren't willing to desegment it. */
desegment_ok = FALSE;
@@ -3201,7 +3232,7 @@ proto_register_tcp(void)
{ &hf_tcp_analysis_window_full,
{ "Window full", "tcp.analysis.window_full", FT_NONE, BASE_NONE, NULL, 0x0,
- "The this segment has caused the allowed window to become 100% full", HFILL }},
+ "This segment has caused the allowed window to become 100% full", HFILL }},
{ &hf_tcp_analysis_keep_alive,
{ "Keep Alive", "tcp.analysis.keep_alive", FT_NONE, BASE_NONE, NULL, 0x0,
@@ -3397,8 +3428,8 @@ proto_register_tcp(void)
"Whether the TCP summary line should be shown in the protocol tree",
&tcp_summary_in_tree);
prefs_register_bool_preference(tcp_module, "check_checksum",
- "Check the validity of the TCP checksum when possible",
- "Whether to check the validity of the TCP checksum",
+ "Validate the TCP checksum if possible",
+ "Whether to validate the TCP checksum",
&tcp_check_checksum);
prefs_register_bool_preference(tcp_module, "desegment_tcp_streams",
"Allow subdissector to reassemble TCP streams",
diff --git a/epan/epan.c b/epan/epan.c
index 1a289e396e..895d3faa0d 100644
--- a/epan/epan.c
+++ b/epan/epan.c
@@ -22,6 +22,7 @@
#include "tap.h"
#include "addr_resolv.h"
#include "emem.h"
+#include "expert.h"
static void (*report_failure_func)(const char *, va_list);
static void (*report_open_failure_func)(const char *, int, gboolean);
@@ -66,11 +67,13 @@ epan_init(const char *plugin_dir, void (*register_all_protocols)(void),
dfilter_init();
final_registration_all_protocols();
host_name_lookup_init();
+ expert_init();
}
void
epan_cleanup(void)
{
+ expert_cleanup();
dfilter_cleanup();
proto_cleanup();
packet_cleanup();
diff --git a/epan/expert.c b/epan/expert.c
new file mode 100644
index 0000000000..dfa585f7e2
--- /dev/null
+++ b/epan/expert.c
@@ -0,0 +1,117 @@
+/* expert.c
+ * Collecting Expert information.
+ *
+ * Implemented as a tap named "expert".
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "packet.h"
+#include "expert.h"
+#include "emem.h"
+#include "tap.h"
+
+
+
+static int expert_tap = -1;
+
+
+void
+expert_init(void)
+{
+ if(expert_tap == -1) {
+ expert_tap = register_tap("expert");
+ }
+}
+
+void
+expert_cleanup(void)
+{
+ /* memory cleanup will be done by se_... */
+}
+
+
+/* set's the PI_ flags to a protocol item
+ * (and it's parent items till the toplevel) */
+static void
+expert_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);
+ expert_set_item_flags(pi, group, severity);
+ }
+}
+
+
+static void
+expert_set_info_vformat(
+packet_info *pinfo, proto_item *pi, int group, int severity, const char *format, va_list ap)
+{
+ int ret; /*tmp return value */
+ char formatted[300];
+ expert_info_t *ei;
+
+
+ /* if this packet isn't loaded because of a read filter, don't output anything */
+ if(pinfo->fd->num == -1) {
+ return;
+ }
+
+ /* XXX - use currently nonexistant se_vsnprintf instead */
+ ret = g_vsnprintf(formatted, sizeof(formatted), format, ap);
+ if ((ret == -1) || (ret >= sizeof(formatted)))
+ formatted[sizeof(formatted) - 1] = '\0';
+
+ ei = se_alloc(sizeof(expert_info_t));
+ ei->packet_num = pinfo ? pinfo->fd->num : -1;
+ ei->group = group;
+ ei->severity = severity;
+ ei->protocol = se_strdup(pinfo->current_proto);
+ ei->summary = se_strdup(formatted);
+
+ /* if we have a proto_item (not a faked item), set expert attributes to it */
+ if(pi != NULL && pi->finfo != NULL) {
+ expert_set_item_flags(pi, group, severity);
+ }
+
+ tap_queue_packet(expert_tap, pinfo, ei);
+}
+
+
+void
+expert_add_info_format(
+packet_info *pinfo, proto_item *pi, int group, int severity, const char *format, ...)
+{
+ va_list ap;
+
+
+ va_start(ap, format);
+ expert_set_info_vformat(pinfo, pi, group, severity, format, ap);
+ va_end(ap);
+}
+
+
diff --git a/epan/expert.h b/epan/expert.h
new file mode 100644
index 0000000000..5860121fba
--- /dev/null
+++ b/epan/expert.h
@@ -0,0 +1,60 @@
+/* expert.h
+ * Collecting of Expert information.
+ *
+ * For further info, see: http://wiki.ethereal.com/Development/ExpertInfo
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * 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 __EXPERT_H__
+#define __EXPERT_H__
+
+
+/** only for internal and display use */
+typedef struct expert_info_s {
+ int packet_num;
+ int group;
+ int severity;
+ gchar * protocol;
+ gchar * summary;
+} expert_info_t;
+
+
+extern void
+expert_init(void);
+
+extern void
+expert_cleanup(void);
+
+/** Add an expert info.
+ * XXX - add gcc format string check.
+
+ @param pinfo packet info of the currently processed packet
+ @param pi current protocol item (or NULL)
+ @param group the expert group (like PI_CHECKSUM)
+ @param severity the expert severity (like PI_WARN)
+ @param format printf like format string with further infos
+ */
+extern void
+expert_add_info_format(
+packet_info *pinfo, proto_item *pi, int group, int severity, const char *format, ...);
+
+#endif /* __EXPERT_H__ */
diff --git a/epan/libethereal.def b/epan/libethereal.def
index 91f676e935..019122a86f 100644
--- a/epan/libethereal.def
+++ b/epan/libethereal.def
@@ -191,7 +191,9 @@ ep_alloc
se_alloc
ep_alloc0
ep_strdup
+se_strdup
ep_strdup_printf
+se_strdup_printf
ep_strndup
ep_strsplit
ep_memdup
@@ -217,6 +219,7 @@ except_throw
except_throwd
except_throwf
except_unhandled_catcher
+expert_set_info_format
FacilityReason_vals DATA
fc_fc4_val DATA
file_open_error_message
@@ -404,6 +407,7 @@ proto_item_get_parent
proto_item_get_parent_nth
proto_item_get_subtree
proto_item_set_end
+proto_item_set_expert_flags
proto_item_set_len
proto_item_set_text
proto_register_field_array
diff --git a/epan/proto.c b/epan/proto.c
index 5deb8f1b18..a7996f4276 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -2465,6 +2465,32 @@ proto_item_get_len(proto_item *pi)
return fi->length;
}
+
+/** clear flags according to the mask and set new flag values */
+#define FI_REPLACE_FLAGS(fi, mask, flags_in) { \
+ (fi->flags = (fi)->flags & ~(mask)); \
+ (fi->flags = (fi)->flags | (flags_in)); \
+}
+
+gboolean
+proto_item_set_expert_flags(proto_item *pi, int group, int severity)
+{
+ if(pi == NULL || pi->finfo == NULL)
+ return FALSE;
+
+ /* only change things if severity is worse or at least equal than before */
+ if(severity >= FI_GET_FLAG(pi->finfo, PI_SEVERITY_MASK)) {
+ FI_REPLACE_FLAGS(pi->finfo, PI_GROUP_MASK, group);
+ FI_REPLACE_FLAGS(pi->finfo, PI_SEVERITY_MASK, severity);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+
proto_tree*
proto_tree_create_root(void)
{
diff --git a/epan/proto.h b/epan/proto.h
index 950687810f..50618acf98 100644
--- a/epan/proto.h
+++ b/epan/proto.h
@@ -218,20 +218,13 @@ typedef struct field_info {
/** The protocol field should be displayed as "generated by Ethereal",
* used in field_info.flags. */
#define FI_GENERATED 0x0002
-/** The protocol field has a bad checksum */
-#define FI_CHECKSUM_ERROR 0x0004
-/** The protocol field has an unusual sequence (e.g. TCP window is zero) */
-#define FI_SEQUENCE_WARNING 0x0008
-/** The protocol field has a bad sequence (e.g. TCP segment is lost) */
-#define FI_SEQUENCE_ERROR 0x0010
+
/** convenience macro to get field_info.flags */
#define FI_GET_FLAG(fi, flag) (fi->flags & flag)
/** convenience macro to set field_info.flags */
#define FI_SET_FLAG(fi, flag) (fi->flags = fi->flags | flag)
-
-
/** One of these exists for the entire protocol tree. Each proto_node
* in the protocol tree points to the same copy. */
typedef struct {
@@ -254,6 +247,38 @@ typedef proto_node proto_tree;
/** A protocol item element. */
typedef proto_node proto_item;
+/* expert severities */
+#define PI_SEVERITY_MASK 0x001C /* mask usually for internal use only! */
+/** Usual workflow, e.g. TCP connection establishing */
+#define PI_CHAT 0x0004
+/** Notable messages, e.g. an application returned an "usual" error code like HTTP 404 */
+#define PI_NOTE 0x0008
+/** Warning, e.g. application returned an "unusual" error code */
+#define PI_WARN 0x000C
+/** Serious problems, e.g. [Malformed Packet] */
+#define PI_ERROR 0x0010
+
+/* expert "event groups" */
+#define PI_GROUP_MASK 0xFF00 /* mask usually for internal use only! */
+/** The protocol field has a bad checksum, usually PI_WARN */
+#define PI_CHECKSUM 0x0100
+/** The protocol field indicates a sequence problem (e.g. TCP window is zero) */
+#define PI_SEQUENCE 0x0200
+/** The protocol field indicates a bad application response code (e.g. HTTP 404), usually PI_NOTE */
+#define PI_RESPONSE_CODE 0x0400
+/** The data is undecoded, the protocol dissection is incomplete here, usually PI_WARN */
+#define PI_UNDECODED 0x0800
+/** The protocol field indicates a reassemble (e.g. DCE/RPC defragmentation), usually PI_CHAT (or PI_ERROR) */
+#define PI_REASSEMBLE 0x1000
+/** The packet data is malformed, the dissector has "given up", usually PI_ERROR */
+#define PI_MALFORMED 0x2000
+/** A generic debugging message (shouldn't remain in production code!), usually PI_ERROR */
+#define PI_DEBUG 0x4000
+/** The protocol field indicates a security probem (e.g. unsecure implementation) */
+/*#define PI_SECURITY 0x8000*/
+
+/* add more, see http://wiki.ethereal.com/Development/ExpertInfo */
+
/** is this protocol field hidden from the protocol tree display (used for filtering only)? */
/* HIDING PROTOCOL FIELDS IS DEPRECATED, IT'S CONSIDERED TO BE BAD GUI DESIGN! */
@@ -269,16 +294,6 @@ typedef proto_node proto_item;
/** mark this protocol field as generated by Ethereal (and not read from the packet data) */
#define PROTO_ITEM_SET_GENERATED(proto_item) \
((proto_item) ? FI_SET_FLAG((proto_item)->finfo, FI_GENERATED) : 0)
-/** mark this protocol field having a bad checksum */
-#define PROTO_ITEM_SET_CHECKSUM_ERROR(proto_item) \
- ((proto_item) ? FI_SET_FLAG((proto_item)->finfo, FI_CHECKSUM_ERROR) : 0)
-/** mark this protocol field having a sequence warning */
-#define PROTO_ITEM_SET_SEQUENCE_WARNING(proto_item) \
- ((proto_item) ? FI_SET_FLAG((proto_item)->finfo, FI_SEQUENCE_WARNING) : 0)
-/** mark this protocol field having a sequence error */
-#define PROTO_ITEM_SET_SEQUENCE_ERROR(proto_item) \
- ((proto_item) ? FI_SET_FLAG((proto_item)->finfo, FI_SEQUENCE_ERROR) : 0)
-
typedef void (*proto_tree_foreach_func)(proto_node *, gpointer);
@@ -376,6 +391,16 @@ extern void proto_item_set_end(proto_item *ti, tvbuff_t *tvb, gint end);
@return the current length */
extern int proto_item_get_len(proto_item *ti);
+/**
+ * Sets an expert info to the proto_item.
+ @param ti the item to set the expert info
+ @param group the group of this info (e.g. FI_CHECKSUM)
+ @param severity of this info (e.g. FI_ERROR)
+ @return TRUE if value was written
+ */
+extern gboolean proto_item_set_expert_flags(proto_item *ti, int group, int severity);
+
+
/** Creates a new proto_tree root.
diff --git a/gtk/Makefile.common b/gtk/Makefile.common
index da06f639d8..a6d934e1dd 100644
--- a/gtk/Makefile.common
+++ b/gtk/Makefile.common
@@ -122,6 +122,7 @@ ETHEREAL_TAP_SRC = \
conversations_wlan.c \
conversations_rsvp.c \
dcerpc_stat.c \
+ expert_dlg.c \
fc_stat.c \
flow_graph.c \
gsm_a_stat.c \
diff --git a/gtk/expert_dlg.c b/gtk/expert_dlg.c
new file mode 100644
index 0000000000..957f3cd787
--- /dev/null
+++ b/gtk/expert_dlg.c
@@ -0,0 +1,511 @@
+/* expert_dlg.c
+ * Display of Expert information.
+ *
+ * Implemented as a tap listener to the "expert" tap.
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <epan/packet.h>
+#include <epan/expert.h>
+#include <epan/emem.h>
+#include <epan/tap.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <gtk/gtk.h>
+#include "compat_macros.h"
+#include "epan/packet_info.h"
+#include "image/clist_ascend.xpm"
+#include "image/clist_descend.xpm"
+#include "simple_dialog.h"
+#include "globals.h"
+#include "gtk/find_dlg.h"
+#include "color.h"
+#include "gtk/color_dlg.h"
+#include "main.h"
+#include "gui_utils.h"
+#include "gtkglobals.h"
+#include "dlg_utils.h"
+#include "../stat_menu.h"
+#include "gui_stat_menu.h"
+#include <../tap_dfilter_dlg.h>
+#include <epan/stat_cmd_args.h>
+
+#include <epan/prefs.h>
+#include "colors.h"
+#include "proto_draw.h"
+#include <epan/emem.h>
+
+
+
+static const value_string expert_severity_vals[] = {
+ { PI_CHAT, "Chat" },
+ { PI_NOTE, "Note" },
+ { PI_WARN, "Warn" },
+ { PI_ERROR, "Error" },
+ { 0, NULL }
+};
+
+static const value_string expert_group_vals[] = {
+ { PI_CHECKSUM, "Checksum" },
+ { PI_SEQUENCE, "Sequence" },
+ { PI_APPL_RESPONSE, "Response" },
+ { PI_UNDECODED, "Undecoded" },
+ { PI_MALFORMED, "Malformed" },
+ { PI_REASSEMBLE, "Reassemble" },
+ { PI_SECURITY, "Security" },
+ { 0, NULL }
+};
+
+typedef struct expert_tapdata_s {
+ GtkWidget *win;
+ GtkWidget *scrolled_window;
+ GtkCList *table;
+ GtkWidget *label;
+ GList *displayed_events;
+ GList *new_events;
+ guint32 chat_events;
+ guint32 note_events;
+ guint32 warn_events;
+ guint32 error_events;
+} expert_tapdata_t;
+
+
+/* the current warning severity */
+/* XXX - make this a preference setting / a setting in the dialog */
+int severity_report_level = PI_CHAT;
+//int severity_report_level = PI_NOTE;
+
+
+void expert_dlg_reset(void *tapdata)
+{
+ expert_tapdata_t * etd = tapdata;
+ gchar *title;
+
+ g_list_free(etd->displayed_events);
+ etd->displayed_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;
+ gtk_clist_clear(etd->table);
+ gtk_clist_columns_autosize(etd->table);
+
+ 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), "Please wait ...");
+ g_free(title);
+
+ title = g_strdup_printf("Ethereal: %u Expert Infos",
+ g_list_length(etd->displayed_events));
+ gtk_window_set_title(GTK_WINDOW(etd->win), title);
+ g_free(title);
+}
+
+int expert_dlg_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, const void *pointer)
+{
+ expert_info_t *ei = (expert_info_t *) pointer;
+ expert_tapdata_t * etd = tapdata;
+
+
+ switch(ei->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();
+ }
+
+ if(ei->severity < severity_report_level) {
+ return 0; /* draw not required */
+ }
+
+ etd->new_events = g_list_append(etd->new_events, ei);
+
+ return 1; /* draw required */
+}
+
+void
+expert_dlg_draw(expert_tapdata_t *etd)
+{
+ int row;
+ char *strp;
+ expert_info_t *ei;
+ gchar *title;
+ char *entries[5] = { "", "", "", "", "" }; /**< column entries */
+
+
+ /*g_warning("draw start: displayed:%u new:%u",
+ g_list_length(etd->displayed_events), g_list_length(etd->new_events));*/
+
+ 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);
+
+ gtk_clist_freeze(etd->table);
+
+ /* append new events (remove from new list, append to displayed list and clist) */
+ while(etd->new_events != NULL){
+ ei = etd->new_events->data;
+
+ etd->new_events = g_list_remove(etd->new_events, ei);
+ etd->displayed_events = g_list_append(etd->displayed_events, ei);
+
+ row=gtk_clist_append(etd->table, entries);
+ gtk_clist_set_row_data(etd->table, row, ei);
+
+ /* packet number */
+ strp=se_strdup_printf("%d", ei->packet_num);
+ gtk_clist_set_text(etd->table, row, 0, strp);
+
+ /* severity */
+ strp=se_strdup(val_to_str(ei->severity, expert_severity_vals, "Unknown severity (%u)"));
+ gtk_clist_set_text(etd->table, row, 1, strp);
+
+ /* group */
+ strp=se_strdup(val_to_str(ei->group, expert_group_vals, "Unknown group (%u)"));
+ gtk_clist_set_text(etd->table, row, 2, strp);
+
+ /* protocol */
+ if(ei->protocol) {
+ gtk_clist_set_text(etd->table, row, 3, ei->protocol);
+ } else {
+ gtk_clist_set_text(etd->table, row, 3, "-");
+ }
+
+ /* summary */
+ gtk_clist_set_text(etd->table, row, 4, ei->summary);
+
+ /*gtk_clist_set_pixmap(etd->table, row, 5, ascend_pm, ascend_bm);*/
+
+ /* set rows background color depending on severity */
+ switch(ei->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_sort(etd->table);
+ gtk_clist_columns_autosize(etd->table);
+ gtk_clist_thaw(etd->table);
+
+ title = g_strdup_printf("Ethereal: %u Expert Infos",
+ g_list_length(etd->displayed_events));
+ gtk_window_set_title(GTK_WINDOW(etd->win), title);
+ g_free(title);
+
+ /*g_warning("draw end: displayed:%u", g_list_length(etd->displayed_events));*/
+}
+
+
+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 void
+select_row_cb(GtkCList *clist, gint row, gint column, GdkEventButton *event, gpointer user_data)
+{
+ expert_info_t *ei;
+
+
+ ei = (expert_info_t *) gtk_clist_get_row_data(clist, row);
+
+ cf_goto_frame(&cfile, ei->packet_num);
+}
+
+
+void
+expert_dlg_init_table(expert_tapdata_t * etd, GtkWidget *vbox)
+{
+ 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_box_pack_start(GTK_BOX(vbox), etd->scrolled_window, TRUE, TRUE, 0);
+
+ etd->table=(GtkCList *)gtk_clist_new(5);
+ SIGNAL_CONNECT(etd->table, "select-row", 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);
+
+ SIGNAL_CONNECT(etd->table, "click-column", 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);
+ }*/
+}
+
+void protect_thread_critical_region(void);
+void unprotect_thread_critical_region(void);
+static void
+expert_dlg_destroy_cb(GtkWindow *win _U_, gpointer data)
+{
+ expert_tapdata_t *etd=(expert_tapdata_t *)data;
+
+ protect_thread_critical_region();
+ remove_tap_listener(etd);
+ unprotect_thread_critical_region();
+
+ //free_srt_table_data(&etd->afp_srt_table);
+ g_free(etd);
+}
+
+
+
+static void
+expert_dlg_init(const char *optarg)
+{
+ expert_tapdata_t * etd;
+ const char *filter=NULL;
+ GString *error_string;
+ GtkWidget *vbox;
+ GtkWidget *bbox;
+ GtkWidget *close_bt;
+
+ if(!strncmp(optarg,"afp,srt,",8)){
+ filter=optarg+8;
+ } else {
+ filter=NULL;
+ }
+
+ proto_draw_colors_init();
+
+ etd=g_malloc(sizeof(expert_tapdata_t));
+ etd->displayed_events = NULL;
+ etd->new_events = NULL;
+ etd->chat_events = 0;
+ etd->note_events = 0;
+ etd->warn_events = 0;
+ etd->error_events = 0;
+
+ etd->win=window_new(GTK_WINDOW_TOPLEVEL, "Ethereal: Expert Info");
+ gtk_window_set_default_size(GTK_WINDOW(etd->win), 650, 600);
+
+ vbox=gtk_vbox_new(FALSE, 3);
+ gtk_container_add(GTK_CONTAINER(etd->win), vbox);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
+
+ etd->label=gtk_label_new("Please wait ...");
+ gtk_box_pack_start(GTK_BOX(vbox), etd->label, FALSE, FALSE, 0);
+
+ /* We must display TOP LEVEL Widget before calling init_srt_table() */
+ gtk_widget_show_all(etd->win);
+
+ expert_dlg_init_table(etd, vbox);
+ /*for(i=0;i<256;i++){
+ init_srt_table_row(&etd->afp_srt_table, i, val_to_str(i, CommandCode_vals, "Unknown(%u)"));
+ }*/
+
+ error_string=register_tap_listener("expert", etd, NULL /* fstring */,
+ expert_dlg_reset,
+ expert_dlg_packet,
+ expert_dlg_draw);
+ if(error_string){
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str);
+ g_string_free(error_string, TRUE);
+ g_free(etd);
+ return;
+ }
+
+ /* Button row. */
+ bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
+ gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
+
+ close_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CLOSE);
+ window_set_cancel_button(etd->win, close_bt, window_cancel_button_cb);
+
+ SIGNAL_CONNECT(etd->win, "delete_event", window_delete_event_cb, NULL);
+ SIGNAL_CONNECT(etd->win, "destroy", expert_dlg_destroy_cb, etd);
+
+ gtk_widget_show_all(etd->win);
+ window_present(etd->win);
+
+ cf_retap_packets(&cfile);
+}
+
+
+static void
+expert_dlg_cb(GtkWidget *w _U_, gpointer d _U_)
+{
+ expert_dlg_init("");
+}
+
+
+
+
+void
+register_tap_listener_expert(void)
+{
+ register_stat_cmd_arg("expert", expert_dlg_init);
+
+ register_stat_menu_item("_Expert Info", REGISTER_STAT_GROUP_GENERIC,
+ expert_dlg_cb, NULL, NULL, NULL);
+}
diff --git a/gtk/proto_draw.c b/gtk/proto_draw.c
index b2fd2340b3..f1ece58795 100644
--- a/gtk/proto_draw.c
+++ b/gtk/proto_draw.c
@@ -1602,6 +1602,27 @@ set_ptree_font_all(FONT_TYPE *font)
}
+gboolean colors_ok = FALSE;
+GdkColor expert_color_chat = { 0, 0xcc00, 0xcc00, 0xe000 }; /* a pale bluegrey */
+GdkColor expert_color_note = { 0, 0xa000, 0xff00, 0xff00 }; /* a bright turquoise */
+GdkColor expert_color_warn = { 0, 0xff00, 0xff00, 0 }; /* yellow */
+GdkColor expert_color_error = { 0, 0xff00, 0x5c00, 0x5c00 }; /* pale red */
+
+void proto_draw_colors_init(void)
+{
+ if(colors_ok) {
+ return;
+ }
+
+ get_color(&expert_color_chat);
+ get_color(&expert_color_note);
+ get_color(&expert_color_warn);
+ get_color(&expert_color_error);
+
+ colors_ok = TRUE;
+}
+
+
#if GTK_MAJOR_VERSION >= 2
static void tree_cell_renderer(GtkTreeViewColumn *tree_column _U_,
GtkCellRenderer *cell,
@@ -1613,11 +1634,16 @@ static void tree_cell_renderer(GtkTreeViewColumn *tree_column _U_,
gtk_tree_model_get(tree_model, iter, 1, &fi, -1);
+ if(!colors_ok) {
+ proto_draw_colors_init();
+ }
+
/* for the various possible attributes, see:
* http://developer.gnome.org/doc/API/2.0/gtk/GtkCellRendererText.html
*
* color definitions can be found at:
* http://cvs.gnome.org/viewcvs/gtk+/gdk-pixbuf/io-xpm.c?rev=1.42
+ * (a good color overview: http://www.computerhope.com/htmcolor.htm)
*
* some experiences:
* background-gdk: doesn't seem to work (probably the GdkColor must be allocated)
@@ -1639,22 +1665,9 @@ static void tree_cell_renderer(GtkTreeViewColumn *tree_column _U_,
/*g_object_set (cell, "weight", PANGO_WEIGHT_NORMAL, NULL);
g_object_set (cell, "weight-set", FALSE, NULL);*/
- if(FI_GET_FLAG(fi, FI_CHECKSUM_ERROR)) {
- g_object_set (cell, "background", "red", NULL);
- g_object_set (cell, "background-set", TRUE, NULL);
- }
-
- if(FI_GET_FLAG(fi, FI_SEQUENCE_WARNING)) {
- g_object_set (cell, "background", "yellow", NULL);
- g_object_set (cell, "background-set", TRUE, NULL);
- }
-
- if(FI_GET_FLAG(fi, FI_SEQUENCE_ERROR)) {
- g_object_set (cell, "background", "red", NULL);
- g_object_set (cell, "background-set", TRUE, NULL);
- }
-
if(FI_GET_FLAG(fi, FI_GENERATED)) {
+ /* we use "[...]" to mark generated items, no need to change things here */
+
/* as some fonts don't support italic, don't use this */
/*g_object_set (cell, "style", PANGO_STYLE_ITALIC, NULL);
g_object_set (cell, "style-set", TRUE, NULL);
@@ -1677,6 +1690,29 @@ static void tree_cell_renderer(GtkTreeViewColumn *tree_column _U_,
g_object_set (cell, "underline", PANGO_UNDERLINE_SINGLE, NULL);
g_object_set (cell, "underline-set", TRUE, NULL);
}
+
+ if(FI_GET_FLAG(fi, PI_SEVERITY_MASK)) {
+ switch(FI_GET_FLAG(fi, PI_SEVERITY_MASK)) {
+ case(PI_CHAT):
+ g_object_set (cell, "background-gdk", &expert_color_chat, NULL);
+ g_object_set (cell, "background-set", TRUE, NULL);
+ break;
+ case(PI_NOTE):
+ g_object_set (cell, "background-gdk", &expert_color_note, NULL);
+ g_object_set (cell, "background-set", TRUE, NULL);
+ break;
+ case(PI_WARN):
+ g_object_set (cell, "background-gdk", &expert_color_warn, NULL);
+ g_object_set (cell, "background-set", TRUE, NULL);
+ break;
+ case(PI_ERROR):
+ g_object_set (cell, "background-gdk", &expert_color_error, NULL);
+ g_object_set (cell, "background-set", TRUE, NULL);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ }
}
#endif
diff --git a/gtk/proto_draw.h b/gtk/proto_draw.h
index 740161df58..54b5868985 100644
--- a/gtk/proto_draw.h
+++ b/gtk/proto_draw.h
@@ -206,4 +206,14 @@ extern gboolean tree_view_select(GtkWidget *widget, GdkEventButton *event);
*/
extern void set_ptree_sel_browse_all(gboolean val);
+
+/** init the expert colors */
+extern void proto_draw_colors_init(void);
+
+/** the expert colors */
+extern GdkColor expert_color_chat;
+extern GdkColor expert_color_note;
+extern GdkColor expert_color_warn;
+extern GdkColor expert_color_error;
+
#endif