diff --git a/AUTHORS b/AUTHORS index 4f7c9d462b..83d79b8ce6 100644 --- a/AUTHORS +++ b/AUTHORS @@ -481,6 +481,7 @@ Martti Kuparinen { David Hampton { Support for HTTP methods added by GENA (the uPnP protocol) Support for the HTTP-based SSDP protocol + "Decode As" dialog } Kent Engström { @@ -490,6 +491,7 @@ Kent Engstr Ronnie Sahlberg { NLM dissector enhancements Mount dissector enhancements + Support for status monitor protocol } Borosa Tomislav { @@ -501,10 +503,6 @@ Alexandre P. Ferreira { WSP fixes } -David Hampton { - "Decode As" dialog -} - Simharajan Srishylam { Include Service ID field in dissection of Service Info component of WCCP 2 messages even if the service type is diff --git a/packet-stat.c b/packet-stat.c index 8de36f8e15..d72d4da47b 100644 --- a/packet-stat.c +++ b/packet-stat.c @@ -1,7 +1,7 @@ /* packet-stat.c * Routines for stat dissection * - * $Id: packet-stat.c,v 1.7 2001/01/18 09:55:10 guy Exp $ + * $Id: packet-stat.c,v 1.8 2001/03/15 21:55:07 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -9,6 +9,9 @@ * * Copied from packet-smb.c * + * 2001 Ronnie Sahlberg + * Added the dissectors for STAT protocol + * * 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 @@ -37,8 +40,209 @@ #include "packet-stat.h" static int proto_stat = -1; +static int hf_stat_mon_name = -1; +static int hf_stat_stat_res = -1; +static int hf_stat_stat_res_res = -1; +static int hf_stat_stat_res_state = -1; +static int hf_stat_state = -1; +static int hf_stat_mon = -1; +static int hf_stat_mon_id_name = -1; +static int hf_stat_my_id = -1; +static int hf_stat_my_id_hostname = -1; +static int hf_stat_my_id_prog = -1; +static int hf_stat_my_id_vers = -1; +static int hf_stat_my_id_proc = -1; +static int hf_stat_priv = -1; +static int hf_stat_stat_chge = -1; static gint ett_stat = -1; +static gint ett_stat_stat_res = -1; +static gint ett_stat_mon = -1; +static gint ett_stat_my_id = -1; +static gint ett_stat_stat_chge = -1; + +#define STAT_SUCC 0 +#define STAT_FAIL 1 + +static const value_string stat_res[] = +{ + { 0, "STAT_SUCC" }, + { 1, "STAT_FAIL" }, + { 0, NULL } +}; + +/* Calculate length (including padding) of my_id structure. + * First read the lenght of the string and round it upwards to nearest + * multiple of 4, then add 16 (4*uint32) + */ +static int +my_id_len(tvbuff_t *tvb, int offset) +{ + int len; + + len = tvb_get_ntohl(tvb, offset); + if(len&0x03) + len = (len&0xfc)+4; + + len += 16; + + return len; +} + +/* Calculate length (including padding) of my_id structure. + * First read the lenght of the string and round it upwards to nearest + * multiple of 4, then add 4 (string len) and size of my_id struct. + */ +static int +mon_id_len(tvbuff_t *tvb, int offset) +{ + int len; + + len = tvb_get_ntohl(tvb, offset); + if(len&0x03){ + len = (len&0xfc)+4; + } + + len += 4; + + return len+my_id_len(tvb,offset+len); +} + +static int +dissect_stat_stat(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) +{ + if (tree) + { + offset = dissect_rpc_string_tvb(tvb,pinfo,tree,hf_stat_mon_name,offset,NULL); + } + + return offset; +} + +static int +dissect_stat_stat_res(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) +{ + proto_item* lock_item = NULL; + proto_tree* lock_tree = NULL; + gint32 res; + gint32 state; + + if (tree) { + lock_item = proto_tree_add_item(tree, hf_stat_stat_res, tvb, + offset, tvb_length_remaining(tvb, offset), FALSE); + if (lock_item) + lock_tree = proto_item_add_subtree(lock_item, ett_stat_stat_res); + } + + res = tvb_get_ntohl(tvb, offset); + offset = dissect_rpc_uint32_tvb(tvb,pinfo,lock_tree,hf_stat_stat_res_res,offset); + + if (res==STAT_SUCC) { + state = tvb_get_ntohl(tvb, offset); + offset = dissect_rpc_uint32_tvb(tvb,pinfo,lock_tree,hf_stat_stat_res_state,offset); + } else { + offset += 4; + } + + return offset; +} + +static int +dissect_stat_my_id(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) +{ + proto_item* lock_item = NULL; + proto_tree* lock_tree = NULL; + + if (tree) { + lock_item = proto_tree_add_item(tree, hf_stat_my_id, tvb, + offset, my_id_len(tvb,offset), FALSE); + if (lock_item) + lock_tree = proto_item_add_subtree(lock_item, ett_stat_my_id); + } + + offset = dissect_rpc_string_tvb(tvb,pinfo,lock_tree,hf_stat_my_id_hostname,offset,NULL); + offset = dissect_rpc_uint32_tvb(tvb,pinfo,lock_tree,hf_stat_my_id_prog,offset); + offset = dissect_rpc_uint32_tvb(tvb,pinfo,lock_tree,hf_stat_my_id_vers,offset); + offset = dissect_rpc_uint32_tvb(tvb,pinfo,lock_tree,hf_stat_my_id_proc,offset); + + return offset; +} + +static int +dissect_stat_mon_id(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) +{ + proto_item* lock_item = NULL; + proto_tree* lock_tree = NULL; + + if (tree) { + lock_item = proto_tree_add_item(tree, hf_stat_mon, tvb, + offset, mon_id_len(tvb,offset), FALSE); + if (lock_item) + lock_tree = proto_item_add_subtree(lock_item, ett_stat_mon); + } + + + offset = dissect_rpc_string_tvb(tvb,pinfo,lock_tree,hf_stat_mon_id_name,offset,NULL); + + offset = dissect_stat_my_id(tvb,offset,pinfo,lock_tree); + + return offset; +} + +static int +dissect_stat_priv(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) +{ + proto_tree_add_item(tree, hf_stat_priv, tvb, offset, 16, FALSE); + offset += 16; + + return offset; +} + +static int +dissect_stat_mon(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) +{ + + offset = dissect_stat_mon_id(tvb,offset,pinfo,tree); + + offset = dissect_stat_priv(tvb,offset,pinfo,tree); + return offset; +} + +static int +dissect_stat_state(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) +{ + offset = dissect_rpc_uint32_tvb(tvb,pinfo,tree,hf_stat_state,offset); + + return offset; +} + +static int +dissect_stat_notify(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) +{ + proto_item* lock_item = NULL; + proto_tree* lock_tree = NULL; + + if (tree) { + lock_item = proto_tree_add_item(tree, hf_stat_stat_chge, tvb, + offset, tvb_length_remaining(tvb, offset)-4, FALSE); + if (lock_item) + lock_tree = proto_item_add_subtree(lock_item, ett_stat_stat_chge); + } + + offset = dissect_rpc_string_tvb(tvb,pinfo,lock_tree,hf_stat_mon_id_name,offset,NULL); + + offset = dissect_rpc_uint32_tvb(tvb,pinfo,tree,hf_stat_state,offset); + + return offset; +} + +static int +dissect_stat_umon_all(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) +{ + offset = dissect_stat_my_id(tvb,offset,pinfo,tree); + + return offset; +} /* proc number, "proc name", dissect_request, dissect_reply */ /* NULL as function pointer means: type of arguments is "void". */ @@ -46,17 +250,17 @@ static gint ett_stat = -1; static const vsff stat_proc[] = { { 0, "NULL", NULL, NULL }, { STATPROC_STAT, "STAT", - NULL, NULL }, + dissect_stat_stat, dissect_stat_stat_res }, { STATPROC_MON, "MON", - NULL, NULL }, + dissect_stat_mon, dissect_stat_stat_res }, { STATPROC_UNMON, "UNMON", - NULL, NULL }, + dissect_stat_mon_id, dissect_stat_state }, { STATPROC_UNMON_ALL, "UNMON_ALL", - NULL, NULL }, + dissect_stat_umon_all, dissect_stat_state }, { STATPROC_SIMU_CRASH, "SIMU_CRASH", NULL, NULL }, { STATPROC_NOTIFY, "NOTIFY", - NULL, NULL }, + dissect_stat_notify, NULL }, { 0, NULL, NULL, NULL } }; /* end of stat version 1 */ @@ -65,21 +269,61 @@ static const vsff stat_proc[] = { void proto_register_stat(void) { -#if 0 static hf_register_info hf[] = { - { &hf_stat_path, { - "Path", "stat.path", FT_STRING, BASE_DEC, - NULL, 0, "Path" }}, + { &hf_stat_mon_name, { + "Name", "stat.name", FT_STRING, BASE_DEC, + NULL, 0, "Name" }}, + { &hf_stat_stat_res, { + "Status Result", "stat.stat_res", FT_NONE,0, + NULL, 0, "Status Result" }}, + { &hf_stat_stat_res_res, { + "Result", "stat.stat_res.res", FT_UINT32, BASE_DEC, + VALS(stat_res), 0, "Result" }}, + { &hf_stat_stat_res_state, { + "State", "stat.stat_res.state", FT_UINT32, BASE_DEC, + NULL, 0, "State" }}, + { &hf_stat_mon, { + "Monitor", "stat.mon", FT_NONE, 0, + NULL, 0, "Monitor Host" }}, + { &hf_stat_mon_id_name, { + "Monitor ID Name", "stat.mon_id.name", FT_STRING, BASE_DEC, + NULL, 0, "Monitor ID Name" }}, + { &hf_stat_my_id, { + "My ID", "stat.my_id", FT_NONE,0, + NULL, 0, "My_ID structure" }}, + { &hf_stat_my_id_hostname, { + "Hostname", "stat.my_id.hostname", FT_STRING, BASE_DEC, + NULL, 0, "My_ID Host to callback" }}, + { &hf_stat_my_id_prog, { + "Program", "stat.my_id.prog", FT_UINT32, BASE_DEC, + NULL, 0, "My_ID Program to callback" }}, + { &hf_stat_my_id_vers, { + "Version", "stat.my_id.vers", FT_UINT32, BASE_DEC, + NULL, 0, "My_ID Version of callback" }}, + { &hf_stat_my_id_proc, { + "Procedure", "stat.my_id.proc", FT_UINT32, BASE_DEC, + NULL, 0, "My_ID Procedure to callback" }}, + { &hf_stat_priv, { + "Priv", "stat.priv", FT_BYTES, BASE_HEX, + NULL, 0, "Private client supplied opaque data" }}, + { &hf_stat_state, { + "State", "stat.state", FT_UINT32, BASE_DEC, + NULL, 0, "State of local NSM" }}, + { &hf_stat_stat_chge, { + "Status Change", "stat.stat_chge", FT_NONE, 0, + NULL, 0, "Status Change structure" }}, }; -#endif + static gint *ett[] = { &ett_stat, + &ett_stat_stat_res, + &ett_stat_mon, + &ett_stat_my_id, + &ett_stat_stat_chge, }; - proto_stat = proto_register_protocol("Status Service", "STAT", "stat"); -#if 0 + proto_stat = proto_register_protocol("Network Status Monitor Protocol", "STAT", "stat"); proto_register_field_array(proto_stat, hf, array_length(hf)); -#endif proto_register_subtree_array(ett, array_length(ett)); }