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-rmp.c
Line
Count
Source
1
/* packet-rmp.c
2
 * Routines for HP remote management protocol
3
 * Gilbert Ramirez <jochen@scram.de>
4
 *
5
 * Wireshark - Network traffic analyzer
6
 * By Gerald Combs <gerald@wireshark.org>
7
 * Copyright 1998 Gerald Combs
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 */
11
12
#include "config.h"
13
14
#include <epan/packet.h>
15
16
#include "packet-hpext.h"
17
18
void proto_register_rmp(void);
19
void proto_reg_handoff_rmp(void);
20
21
static int proto_rmp;
22
23
static int hf_rmp_type;
24
static int hf_rmp_retcode;
25
static int hf_rmp_seqnum;
26
static int hf_rmp_sessionid;
27
static int hf_rmp_version;
28
static int hf_rmp_machtype;
29
static int hf_rmp_filename;
30
static int hf_rmp_offset;
31
static int hf_rmp_size;
32
static int hf_rmp_reserved;
33
34
static int ett_rmp;
35
36
static dissector_handle_t rmp_handle;
37
38
/*
39
 *  Possible values for "rmp_type" fields.
40
 */
41
42
0
#define RMP_BOOT_REQ    1       /* boot request packet */
43
0
#define RMP_BOOT_REPL   129     /* boot reply packet */
44
0
#define RMP_READ_REQ    2       /* read request packet */
45
0
#define RMP_READ_REPL   130     /* read reply packet */
46
0
#define RMP_BOOT_DONE   3       /* boot complete packet */
47
48
/*
49
 *  RMP error codes
50
 */
51
52
#define RMP_E_OKAY      0
53
#define RMP_E_EOF       2       /* read reply: returned end of file */
54
#define RMP_E_ABORT     3       /* abort operation */
55
#define RMP_E_BUSY      4       /* boot reply: server busy */
56
#define RMP_E_TIMEOUT   5       /* lengthen time out (not implemented) */
57
#define RMP_E_NOFILE    16      /* boot reply: file does not exist */
58
#define RMP_E_OPENFILE  17      /* boot reply: file open failed */
59
#define RMP_E_NODFLT    18      /* boot reply: default file does not exist */
60
#define RMP_E_OPENDFLT  19      /* boot reply: default file open failed */
61
#define RMP_E_BADSID    25      /* read reply: bad session ID */
62
#define RMP_E_BADPACKET 27      /* Bad packet detected */
63
64
static const value_string rmp_type_vals[] = {
65
  { RMP_BOOT_REQ,       "Boot Request" },
66
  { RMP_BOOT_REPL,      "Boot Reply" },
67
  { RMP_READ_REQ,       "Read Request" },
68
  { RMP_READ_REPL,      "Read Reply" },
69
  { RMP_BOOT_DONE,      "Boot Done" },
70
  { 0x00,               NULL }
71
};
72
73
static const value_string rmp_error_vals[] = {
74
  { RMP_E_OKAY,         "OK" },
75
  { RMP_E_EOF,          "End Of File" },
76
  { RMP_E_ABORT,        "Abort Operation" },
77
  { RMP_E_BUSY,         "Server Busy" },
78
  { RMP_E_TIMEOUT,      "Lengthen Time Out" },
79
  { RMP_E_NOFILE,       "File Does Not Exist" },
80
  { RMP_E_OPENFILE,     "File Open Failed" },
81
  { RMP_E_NODFLT,       "Default File Does Not Exist" },
82
  { RMP_E_OPENDFLT,     "Default File Open Failed" },
83
  { RMP_E_BADSID,       "Bad Session Id" },
84
  { RMP_E_BADPACKET,    "Bad Packet Detected" },
85
  { 0x00,               NULL }
86
};
87
88
static int
89
dissect_rmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
90
0
{
91
0
  proto_tree  *rmp_tree = NULL;
92
0
  proto_item  *ti = NULL;
93
0
  uint8_t   type, len;
94
95
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "RMP");
96
97
0
  col_clear(pinfo->cinfo, COL_INFO);
98
99
0
  type = tvb_get_uint8(tvb, 0);
100
101
0
  col_set_str(pinfo->cinfo, COL_INFO,
102
0
        val_to_str_const(type, rmp_type_vals, "Unknown Type"));
103
104
0
  ti = proto_tree_add_item(tree, proto_rmp, tvb, 0, -1, ENC_NA);
105
0
  rmp_tree = proto_item_add_subtree(ti, ett_rmp);
106
0
  proto_tree_add_uint(rmp_tree, hf_rmp_type, tvb, 0, 1, type);
107
108
0
  switch (type) {
109
0
    case RMP_BOOT_REQ:
110
0
      proto_tree_add_item(rmp_tree,
111
0
        hf_rmp_retcode, tvb, 1, 1, ENC_BIG_ENDIAN);
112
0
      proto_tree_add_item(rmp_tree,
113
0
        hf_rmp_seqnum, tvb, 2, 4, ENC_BIG_ENDIAN);
114
0
      proto_tree_add_item(rmp_tree,
115
0
        hf_rmp_sessionid, tvb, 6, 2, ENC_BIG_ENDIAN);
116
0
      proto_tree_add_item(rmp_tree,
117
0
        hf_rmp_version, tvb, 8, 2, ENC_BIG_ENDIAN);
118
0
      proto_tree_add_item(rmp_tree,
119
0
        hf_rmp_machtype, tvb, 10, 20, ENC_ASCII);
120
      /* The remaining fields are optional */
121
0
      if(!tvb_offset_exists(tvb, 30))
122
0
        return 30;
123
0
      len = tvb_get_uint8(tvb, 30);
124
0
      proto_tree_add_item(rmp_tree,
125
0
        hf_rmp_filename, tvb, 30, 1, ENC_ASCII|ENC_BIG_ENDIAN);
126
0
      if(tvb_offset_exists(tvb, len+31))
127
0
        call_data_dissector(tvb_new_subset_remaining(tvb, len+31),
128
0
          pinfo, tree);
129
0
      break;
130
131
0
    case RMP_BOOT_REPL:
132
0
      proto_tree_add_item(rmp_tree,
133
0
        hf_rmp_retcode, tvb, 1, 1, ENC_BIG_ENDIAN);
134
0
      proto_tree_add_item(rmp_tree,
135
0
        hf_rmp_seqnum, tvb, 2, 4, ENC_BIG_ENDIAN);
136
0
      proto_tree_add_item(rmp_tree,
137
0
        hf_rmp_sessionid, tvb, 6, 2, ENC_BIG_ENDIAN);
138
0
      proto_tree_add_item(rmp_tree,
139
0
        hf_rmp_version, tvb, 8, 2, ENC_BIG_ENDIAN);
140
0
      len = tvb_get_uint8(tvb, 10);
141
0
      proto_tree_add_item(rmp_tree,
142
0
        hf_rmp_filename, tvb, 10, 1, ENC_ASCII|ENC_BIG_ENDIAN);
143
0
      if(tvb_offset_exists(tvb, len+11))
144
0
        call_data_dissector(tvb_new_subset_remaining(tvb, len+11),
145
0
          pinfo, tree);
146
0
      break;
147
148
0
    case RMP_READ_REQ:
149
0
      proto_tree_add_item(rmp_tree,
150
0
        hf_rmp_retcode, tvb, 1, 1, ENC_BIG_ENDIAN);
151
0
      proto_tree_add_item(rmp_tree,
152
0
        hf_rmp_offset, tvb, 2, 4, ENC_BIG_ENDIAN);
153
0
      proto_tree_add_item(rmp_tree,
154
0
        hf_rmp_sessionid, tvb, 6, 2, ENC_BIG_ENDIAN);
155
0
      proto_tree_add_item(rmp_tree,
156
0
        hf_rmp_size, tvb, 8, 2, ENC_BIG_ENDIAN);
157
0
      if(tvb_offset_exists(tvb, 10))
158
0
        call_data_dissector(tvb_new_subset_remaining(tvb, 10),
159
0
          pinfo, tree);
160
0
      break;
161
162
0
    case RMP_READ_REPL:
163
0
      proto_tree_add_item(rmp_tree,
164
0
        hf_rmp_retcode, tvb, 1, 1, ENC_BIG_ENDIAN);
165
0
      proto_tree_add_item(rmp_tree,
166
0
        hf_rmp_offset, tvb, 2, 4, ENC_BIG_ENDIAN);
167
0
      proto_tree_add_item(rmp_tree,
168
0
        hf_rmp_sessionid, tvb, 6, 2, ENC_BIG_ENDIAN);
169
0
      call_data_dissector(tvb_new_subset_remaining(tvb,
170
0
        8), pinfo, rmp_tree);
171
0
      break;
172
173
0
    case RMP_BOOT_DONE:
174
0
      proto_tree_add_item(rmp_tree,
175
0
        hf_rmp_retcode, tvb, 1, 1, ENC_BIG_ENDIAN);
176
0
      proto_tree_add_item(rmp_tree,
177
0
        hf_rmp_reserved, tvb, 2, 4, ENC_BIG_ENDIAN);
178
0
      proto_tree_add_item(rmp_tree,
179
0
        hf_rmp_sessionid, tvb, 6, 2, ENC_BIG_ENDIAN);
180
0
      if(tvb_offset_exists(tvb, 8))
181
0
        call_data_dissector(tvb_new_subset_remaining(tvb, 6),
182
0
          pinfo, tree);
183
0
      break;
184
0
    default:
185
0
      call_data_dissector(tvb_new_subset_remaining(tvb, 1), pinfo, tree);
186
0
  }
187
0
  return tvb_captured_length(tvb);
188
0
}
189
190
void
191
proto_register_rmp(void)
192
14
{
193
14
  static hf_register_info hf[] = {
194
14
    { &hf_rmp_type,
195
14
    { "Type", "rmp.type", FT_UINT8, BASE_HEX,
196
14
      VALS(rmp_type_vals), 0x0, NULL, HFILL }},
197
14
    { &hf_rmp_retcode,
198
14
    { "Returncode", "rmp.retcode", FT_UINT8, BASE_HEX,
199
14
      VALS(rmp_error_vals), 0x0, NULL, HFILL }},
200
14
    { &hf_rmp_seqnum,
201
14
    { "Sequence Number", "rmp.seqnum", FT_UINT32, BASE_HEX,
202
14
      NULL, 0x0, NULL, HFILL }},
203
14
    { &hf_rmp_sessionid,
204
14
    { "Session ID", "rmp.sessionid", FT_UINT16, BASE_HEX,
205
14
      NULL, 0x0, NULL, HFILL }},
206
14
    { &hf_rmp_version,
207
14
    { "Version", "rmp.version", FT_UINT16, BASE_DEC,
208
14
      NULL, 0x0, NULL, HFILL }},
209
14
    { &hf_rmp_machtype,
210
14
    { "Machine Type", "rmp.machtype", FT_STRING, BASE_NONE,
211
14
      NULL, 0x0, NULL, HFILL }},
212
14
    { &hf_rmp_filename,
213
14
    { "Filename", "rmp.filename", FT_UINT_STRING, BASE_NONE,
214
14
      NULL, 0x0, NULL, HFILL }},
215
14
    { &hf_rmp_offset,
216
14
    { "Offset", "rmp.offset", FT_UINT32, BASE_HEX,
217
14
      NULL, 0x0, NULL, HFILL }},
218
14
    { &hf_rmp_size,
219
14
    { "Size", "rmp.size", FT_UINT16, BASE_DEC,
220
14
      NULL, 0x0, NULL, HFILL }},
221
14
    { &hf_rmp_reserved,
222
14
    { "Reserved", "rmp.reserved", FT_UINT32, BASE_HEX,
223
14
      NULL, 0x0, NULL, HFILL }},
224
14
  };
225
226
14
  static int *ett[] = {
227
14
    &ett_rmp,
228
14
  };
229
230
14
  proto_rmp = proto_register_protocol("HP Remote Maintenance Protocol", "RMP", "rmp");
231
14
  proto_register_field_array(proto_rmp, hf, array_length(hf));
232
14
  proto_register_subtree_array(ett, array_length(ett));
233
234
14
  rmp_handle = register_dissector("rmp", dissect_rmp, proto_rmp);
235
14
}
236
237
void
238
proto_reg_handoff_rmp(void)
239
14
{
240
14
  dissector_add_uint("hpext.dxsap", HPEXT_DXSAP, rmp_handle);
241
14
  dissector_add_uint("hpext.dxsap", HPEXT_SXSAP, rmp_handle);
242
14
}
243
244
/*
245
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
246
 *
247
 * Local variables:
248
 * c-basic-offset: 8
249
 * tab-width: 8
250
 * indent-tabs-mode: t
251
 * End:
252
 *
253
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
254
 * :indentSize=8:tabSize=8:noTabs=false:
255
 */