forked from osmocom/wireshark
I'm adding the "Expert Info" prototype now, as it seems to be in a state where others might have a look and probably already find it useful :-). Anyway, we can easily disable it at one or two places in the code if it get's in our way of a new release.
Please see: http://wiki.ethereal.com/Development/ExpertInfo for a complete overview of the intended feature and it's current state of implementation. While I'm working on this, I've also added some more status result codes to the DCE/RPC and DCOM dissectors. svn path=/trunk/; revision=15754
This commit is contained in:
parent
266e1a3491
commit
642467ad5c
|
@ -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 \
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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__ */
|
|
@ -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
|
||||
|
|
26
epan/proto.c
26
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)
|
||||
{
|
||||
|
|
61
epan/proto.h
61
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.
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue