Coverage Report

Created: 2026-06-30 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-stat.c
Line
Count
Source
1
/* packet-stat.c
2
 * Routines for stat dissection
3
 *
4
 * Wireshark - Network traffic analyzer
5
 * By Gerald Combs <gerald@wireshark.org>
6
 * Copyright 1998 Gerald Combs
7
 *
8
 * Copied from packet-smb.c
9
 *
10
 * 2001  Ronnie Sahlberg <See AUTHORS for email>
11
 *     Added the dissectors for STAT protocol
12
 *
13
 * SPDX-License-Identifier: GPL-2.0-or-later
14
 */
15
#include "config.h"
16
17
#include "packet-rpc.h"
18
#include "packet-stat.h"
19
20
void proto_register_stat(void);
21
void proto_reg_handoff_stat(void);
22
23
static const value_string stat1_proc_vals[] = {
24
  { 0,                   "NULL" },
25
  { STATPROC_STAT,       "STAT" },
26
  { STATPROC_MON,        "MON" },
27
  { STATPROC_UNMON,      "UNMON" },
28
  { STATPROC_UNMON_ALL,  "UNMON_ALL" },
29
  { STATPROC_SIMU_CRASH, "SIMU_CRASH" },
30
  { STATPROC_NOTIFY,     "NOTIFY" },
31
  { 0, NULL }
32
};
33
34
static const value_string stat_res[] =
35
{
36
  { 0, "STAT_SUCC" },
37
  { 1, "STAT_FAIL" },
38
  { 0, NULL }
39
};
40
41
static int proto_stat;
42
43
static int hf_stat_mon;
44
static int hf_stat_mon_id_name;
45
static int hf_stat_mon_name;
46
static int hf_stat_my_id;
47
static int hf_stat_my_id_hostname;
48
static int hf_stat_my_id_proc;
49
static int hf_stat_my_id_prog;
50
static int hf_stat_my_id_vers;
51
static int hf_stat_priv;
52
static int hf_stat_procedure_v1;
53
static int hf_stat_stat_chge;
54
static int hf_stat_stat_res;
55
static int hf_stat_stat_res_res;
56
static int hf_stat_stat_res_state;
57
static int hf_stat_state;
58
59
static int ett_stat;
60
static int ett_stat_stat_res;
61
static int ett_stat_mon;
62
static int ett_stat_my_id;
63
static int ett_stat_stat_chge;
64
65
0
#define STAT_SUCC 0
66
#define STAT_FAIL 1
67
68
/* Calculate length (including padding) of my_id structure.
69
 * First read the length of the string and round it upwards to nearest
70
 * multiple of 4, then add 16 (4*uint32)
71
 */
72
static int
73
my_id_len(tvbuff_t *tvb, int offset)
74
0
{
75
0
  int len;
76
77
0
  len = tvb_get_ntohl(tvb, offset);
78
0
  if(len&0x03)
79
0
    len = (len&0xfc)+4;
80
81
0
  len += 16;
82
83
0
  return len;
84
0
}
85
86
/* Calculate length (including padding) of my_id structure.
87
 * First read the length of the string and round it upwards to nearest
88
 * multiple of 4, then add 4 (string len) and size of my_id struct.
89
 */
90
static int
91
mon_id_len(tvbuff_t *tvb, int offset)
92
0
{
93
0
  int len;
94
95
0
  len = tvb_get_ntohl(tvb, offset);
96
0
  if(len&0x03){
97
0
    len = (len&0xfc)+4;
98
0
  }
99
100
0
  len += 4;
101
102
0
  return len+my_id_len(tvb,offset+len);
103
0
}
104
105
static int
106
dissect_stat_stat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
107
0
{
108
0
  return dissect_rpc_string(tvb,pinfo,tree,hf_stat_mon_name,0,NULL);
109
0
}
110
111
static int
112
dissect_stat_stat_res(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
113
0
{
114
0
  proto_item *sub_item;
115
0
  proto_tree *sub_tree;
116
0
  int32_t res;
117
0
  unsigned offset = 0;
118
119
0
  sub_item = proto_tree_add_item(tree, hf_stat_stat_res, tvb,
120
0
        offset, -1, ENC_NA);
121
0
  sub_tree = proto_item_add_subtree(sub_item, ett_stat_stat_res);
122
123
0
  res = tvb_get_ntohl(tvb, offset);
124
0
  offset = dissect_rpc_uint32(tvb,sub_tree,hf_stat_stat_res_res,offset);
125
126
0
  if (res==STAT_SUCC) {
127
0
    offset = dissect_rpc_uint32(tvb,sub_tree,hf_stat_stat_res_state,offset);
128
0
  } else {
129
0
    offset += 4;
130
0
  }
131
132
0
  return offset;
133
0
}
134
135
static int
136
dissect_stat_my_id(tvbuff_t *tvb, packet_info* pinfo, int offset, proto_tree *tree)
137
0
{
138
0
  proto_item *sub_item;
139
0
  proto_tree *sub_tree;
140
141
0
  sub_item = proto_tree_add_item(tree, hf_stat_my_id, tvb,
142
0
        offset, my_id_len(tvb,offset), ENC_NA);
143
0
  sub_tree = proto_item_add_subtree(sub_item, ett_stat_my_id);
144
145
0
  offset = dissect_rpc_string(tvb,pinfo,sub_tree,hf_stat_my_id_hostname,offset,NULL);
146
0
  offset = dissect_rpc_uint32(tvb,sub_tree,hf_stat_my_id_prog,offset);
147
0
  offset = dissect_rpc_uint32(tvb,sub_tree,hf_stat_my_id_vers,offset);
148
0
  offset = dissect_rpc_uint32(tvb,sub_tree,hf_stat_my_id_proc,offset);
149
150
0
  return offset;
151
0
}
152
153
static int
154
dissect_stat_mon_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
155
0
{
156
0
  proto_item *sub_item;
157
0
  proto_tree *sub_tree;
158
0
  unsigned offset = 0;
159
160
0
  sub_item = proto_tree_add_item(tree, hf_stat_mon, tvb,
161
0
        offset, mon_id_len(tvb,offset), ENC_NA);
162
0
  sub_tree = proto_item_add_subtree(sub_item, ett_stat_mon);
163
164
0
  offset = dissect_rpc_string(tvb,pinfo,sub_tree,hf_stat_mon_id_name,offset,NULL);
165
166
0
  offset = dissect_stat_my_id(tvb,pinfo,offset,sub_tree);
167
168
0
  return offset;
169
0
}
170
171
static int
172
dissect_stat_priv(tvbuff_t *tvb, int offset, proto_tree *tree)
173
0
{
174
0
  proto_tree_add_item(tree, hf_stat_priv, tvb, offset, 16, ENC_NA);
175
0
  offset += 16;
176
177
0
  return offset;
178
0
}
179
180
static int
181
dissect_stat_mon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
182
0
{
183
0
  int offset = dissect_stat_mon_id(tvb,pinfo,tree,data);
184
185
0
  offset = dissect_stat_priv(tvb,offset,tree);
186
0
  return offset;
187
0
}
188
189
static int
190
dissect_stat_state(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
191
0
{
192
0
  return dissect_rpc_uint32(tvb,tree,hf_stat_state,0);
193
0
}
194
195
static int
196
dissect_stat_notify(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
197
0
{
198
0
  proto_item *sub_item;
199
0
  proto_tree *sub_tree;
200
0
  unsigned offset = 0;
201
0
  int start_offset = offset;
202
203
0
  sub_item = proto_tree_add_item(tree, hf_stat_stat_chge, tvb,
204
0
        offset, -1, ENC_NA);
205
0
  sub_tree = proto_item_add_subtree(sub_item, ett_stat_stat_chge);
206
207
0
  offset = dissect_rpc_string(tvb,pinfo,sub_tree,hf_stat_mon_id_name,offset,NULL);
208
209
0
  offset = dissect_rpc_uint32(tvb,tree,hf_stat_state,offset);
210
211
0
  if(sub_item)
212
0
    proto_item_set_len(sub_item, offset - start_offset);
213
214
0
  return offset;
215
0
}
216
217
static int
218
dissect_stat_umon_all(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
219
0
{
220
0
  return dissect_stat_my_id(tvb,pinfo,0,tree);
221
0
}
222
223
/* proc number, "proc name", dissect_request, dissect_reply */
224
225
static const vsff stat1_proc[] = {
226
  { 0, "NULL",
227
    dissect_rpc_void, dissect_rpc_void },
228
  { STATPROC_STAT,       "STAT",
229
    dissect_stat_stat, dissect_stat_stat_res },
230
  { STATPROC_MON,        "MON",
231
    dissect_stat_mon, dissect_stat_stat_res },
232
  { STATPROC_UNMON,      "UNMON",
233
    dissect_stat_mon_id, dissect_stat_state },
234
  { STATPROC_UNMON_ALL,  "UNMON_ALL",
235
    dissect_stat_umon_all, dissect_stat_state },
236
  { STATPROC_SIMU_CRASH, "SIMU_CRASH",
237
    dissect_rpc_void, dissect_rpc_void },
238
  { STATPROC_NOTIFY,     "NOTIFY",
239
    dissect_stat_notify, dissect_rpc_void },
240
  { 0, NULL, NULL, NULL }
241
};
242
/* end of stat version 1 */
243
244
245
static const rpc_prog_vers_info stat_vers_info[] = {
246
  { 1, stat1_proc, &hf_stat_procedure_v1 },
247
};
248
249
void
250
proto_register_stat(void)
251
14
{
252
14
  static hf_register_info hf[] = {
253
14
    { &hf_stat_procedure_v1,
254
14
      { "V1 Procedure", "stat.procedure_v1",
255
14
        FT_UINT32, BASE_DEC, VALS(stat1_proc_vals), 0,
256
14
        NULL, HFILL }
257
14
    },
258
14
    { &hf_stat_mon_name,
259
14
      { "Name", "stat.name",
260
14
        FT_STRING, BASE_NONE, NULL, 0,
261
14
        NULL, HFILL }
262
14
    },
263
14
    { &hf_stat_stat_res,
264
14
      { "Status Result", "stat.stat_res",
265
14
        FT_NONE, BASE_NONE, NULL, 0,
266
14
        NULL, HFILL }
267
14
    },
268
14
    { &hf_stat_stat_res_res,
269
14
      { "Result", "stat.stat_res.res",
270
14
        FT_UINT32, BASE_DEC, VALS(stat_res), 0,
271
14
        NULL, HFILL }
272
14
    },
273
14
    { &hf_stat_stat_res_state,
274
14
      { "State", "stat.stat_res.state",
275
14
        FT_UINT32, BASE_DEC, NULL, 0,
276
14
        NULL, HFILL }
277
14
    },
278
14
    { &hf_stat_state,
279
14
      { "State", "stat.state",
280
14
        FT_UINT32, BASE_DEC, NULL, 0,
281
14
        "State of local NSM", HFILL }
282
14
    },
283
14
    { &hf_stat_mon,
284
14
      { "Monitor", "stat.mon",
285
14
        FT_NONE, BASE_NONE, NULL, 0,
286
14
        "Monitor Host", HFILL }
287
14
    },
288
14
    { &hf_stat_mon_id_name,
289
14
      { "Monitor ID Name", "stat.mon_id.name",
290
14
        FT_STRING, BASE_NONE, NULL, 0,
291
14
        NULL, HFILL }
292
14
    },
293
14
    { &hf_stat_my_id,
294
14
      { "My ID", "stat.my_id",
295
14
        FT_NONE, BASE_NONE, NULL, 0,
296
14
        "My_ID structure", HFILL }
297
14
    },
298
14
    { &hf_stat_my_id_hostname,
299
14
      { "Hostname", "stat.my_id.hostname",
300
14
        FT_STRING, BASE_NONE, NULL, 0,
301
14
        "My_ID Host to callback", HFILL }
302
14
    },
303
14
    { &hf_stat_my_id_prog,
304
14
      { "Program", "stat.my_id.prog",
305
14
        FT_UINT32, BASE_DEC, NULL, 0,
306
14
        "My_ID Program to callback", HFILL }
307
14
    },
308
14
    { &hf_stat_my_id_vers,
309
14
      { "Version", "stat.my_id.vers",
310
14
        FT_UINT32, BASE_DEC, NULL, 0,
311
14
        "My_ID Version of callback", HFILL }
312
14
    },
313
14
    { &hf_stat_my_id_proc,
314
14
      { "Procedure", "stat.my_id.proc",
315
14
        FT_UINT32, BASE_DEC, NULL, 0,
316
14
        "My_ID Procedure to callback", HFILL }
317
14
    },
318
14
    { &hf_stat_priv,
319
14
      { "Priv", "stat.priv",
320
14
        FT_BYTES, BASE_NONE, NULL, 0,
321
14
        "Private client supplied opaque data", HFILL }
322
14
    },
323
14
    { &hf_stat_stat_chge,
324
14
      { "Status Change", "stat.stat_chge",
325
14
        FT_NONE, BASE_NONE, NULL, 0,
326
14
        "Status Change structure", HFILL }
327
14
    },
328
14
  };
329
330
14
  static int *ett[] = {
331
14
    &ett_stat,
332
14
    &ett_stat_stat_res,
333
14
    &ett_stat_mon,
334
14
    &ett_stat_my_id,
335
14
    &ett_stat_stat_chge,
336
14
  };
337
338
14
  proto_stat = proto_register_protocol("Network Status Monitor Protocol", "STAT", "stat");
339
14
  proto_register_field_array(proto_stat, hf, array_length(hf));
340
14
  proto_register_subtree_array(ett, array_length(ett));
341
14
}
342
343
void
344
proto_reg_handoff_stat(void)
345
14
{
346
  /* Register the protocol as RPC */
347
14
  rpc_init_prog(proto_stat, STAT_PROGRAM, ett_stat,
348
      G_N_ELEMENTS(stat_vers_info), stat_vers_info);
349
14
}
350
351
/*
352
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
353
 *
354
 * Local variables:
355
 * c-basic-offset: 8
356
 * tab-width: 8
357
 * indent-tabs-mode: t
358
 * End:
359
 *
360
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
361
 * :indentSize=8:tabSize=8:noTabs=false:
362
 */