Coverage Report

Created: 2026-01-02 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-asf.c
Line
Count
Source
1
/* packet-asf.c
2
 * Routines for ASF packet dissection
3
 *
4
 * Duncan Laurie <duncan@sun.com>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * Copied from packet-rmcp.c
11
 *
12
 * SPDX-License-Identifier: GPL-2.0-or-later
13
 */
14
15
#include "config.h"
16
17
#include <epan/packet.h>
18
#include <epan/expert.h>
19
#include <epan/addr_resolv.h>
20
21
/*
22
 * See
23
 *  http://www.dmtf.org/standards/standard_alert.php
24
 *  https://www.dmtf.org/sites/default/files/standards/documents/DSP0136.pdf
25
 */
26
27
void proto_register_asf(void);
28
void proto_reg_handoff_asf(void);
29
30
static dissector_handle_t asf_handle;
31
32
14
#define RMCP_CLASS_ASF 0x06
33
34
static int proto_asf;
35
static int hf_asf_iana;
36
static int hf_asf_type;
37
static int hf_asf_tag;
38
static int hf_asf_len;
39
static int hf_asf_rssp_status_code;
40
static int hf_asf_mgt_console_id;
41
static int hf_asf_client_id;
42
static int hf_asf_payload;
43
static int hf_asf_payload_type;
44
static int hf_asf_payload_len;
45
static int hf_asf_payload_data;
46
static int hf_asf_auth_alg;
47
static int hf_asf_integrity_alg;
48
static int hf_asf_reserved;
49
50
static int ett_asf;
51
static int ett_asf_payload;
52
static int ett_asf_alg_payload;
53
54
static expert_field ei_asf_payload_too_short;
55
56
57
#define ASF_TYPE_RESET                  0x10
58
#define ASF_TYPE_PWR_UP                 0x11
59
#define ASF_TYPE_PWR_DOWN               0x12
60
#define ASF_TYPE_PWR_CYCLE              0x13
61
#define ASF_TYPE_PRES_PONG              0x40
62
#define ASF_TYPE_CAP_RESP               0x41
63
#define ASF_TYPE_SYS_STATE_RESP         0x42
64
5
#define ASF_TYPE_OPEN_SESS_RESP         0x43
65
#define ASF_TYPE_CLOSE_SESS_RESP        0x44
66
#define ASF_TYPE_PRES_PING              0x80
67
#define ASF_TYPE_CAP_RQST               0x81
68
#define ASF_TYPE_SYS_STATE_RQST         0x82
69
0
#define ASF_TYPE_OPEN_SESS_RQST         0x83
70
#define ASF_TYPE_CLOSE_SESS_RQST        0x84
71
#define ASF_TYPE_RAKP_MSG_1             0xC0
72
#define ASF_TYPE_RAKP_MSG_2             0xC1
73
#define ASF_TYPE_RAKP_MSG_3             0xC2
74
75
static const value_string asf_type_vals[] = {
76
  { ASF_TYPE_RESET,           "Reset" },
77
  { ASF_TYPE_PWR_UP,          "Power-up" },
78
  { ASF_TYPE_PWR_DOWN,        "Unconditional Power-down" },
79
  { ASF_TYPE_PWR_CYCLE,       "Power Cycle" },
80
  { ASF_TYPE_PRES_PONG,       "Presence Pong" },
81
  { ASF_TYPE_CAP_RESP,        "Capabilities Response" },
82
  { ASF_TYPE_SYS_STATE_RESP,  "System State Response" },
83
  { ASF_TYPE_OPEN_SESS_RESP,  "Open Session Response" },
84
  { ASF_TYPE_CLOSE_SESS_RESP, "Close Session Response" },
85
  { ASF_TYPE_PRES_PING,       "Presence Ping" },
86
  { ASF_TYPE_CAP_RQST,        "Capabilities Request" },
87
  { ASF_TYPE_SYS_STATE_RQST,  "System State Request" },
88
  { ASF_TYPE_OPEN_SESS_RQST,  "Open Session Request" },
89
  { ASF_TYPE_CLOSE_SESS_RQST, "Close Session Request" },
90
  { ASF_TYPE_RAKP_MSG_1,      "RAKP Message 1" },
91
  { ASF_TYPE_RAKP_MSG_2,      "RAKP Message 2" },
92
  { ASF_TYPE_RAKP_MSG_3,      "RAKP Message 3" },
93
  { 0x00, NULL }
94
};
95
96
static const value_string asf_rssp_status_code_vals[] = {
97
  { 0x00, "No errors" },
98
  { 0x01, "Insufficient resources to create a session" },
99
  { 0x02, "Invalid session ID" },
100
  { 0x03, "Invalid payload type" },
101
  { 0x04, "Invalid authentication algorithm" },
102
  { 0x05, "Invalid integrity algorithm" },
103
  { 0x06, "No matching authentication payload" },
104
  { 0x07, "No matching integrity payload" },
105
  { 0x00, NULL }
106
};
107
108
#define ASF_PAYLOAD_TYPE_NONE           0x00
109
0
#define ASF_PAYLOAD_TYPE_AUTHENTICATION 0x01
110
0
#define ASF_PAYLOAD_TYPE_INTEGRITY      0x02
111
112
static const value_string asf_payload_type_vals[] = {
113
  { ASF_PAYLOAD_TYPE_NONE,           "No payload present (end of list)" },
114
  { ASF_PAYLOAD_TYPE_AUTHENTICATION, "Authentication algorithm payload" },
115
  { ASF_PAYLOAD_TYPE_INTEGRITY,      "Integrity algorithm payload" },
116
  { 0x00, NULL }
117
};
118
119
static const value_string asf_authentication_type_vals[] = {
120
  { 0x01, "RAKP-HMAC-SHA1" },
121
  { 0x00, NULL }
122
};
123
124
static const value_string asf_integrity_type_vals[] = {
125
  { 0x01, "HMAC-SHA1-96" },
126
  { 0x00, NULL }
127
};
128
129
static void dissect_asf_open_session_request(tvbuff_t *tvb, packet_info *pinfo,
130
  proto_tree *tree, int offset, int len);
131
static void dissect_asf_open_session_response(tvbuff_t *tvb, packet_info *pinfo,
132
  proto_tree *tree, int offset, int len);
133
static void dissect_asf_payloads(tvbuff_t *tvb, packet_info *pinfo,
134
  proto_tree *tree, int offset, int len);
135
static void dissect_asf_payload_authentication(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree,
136
  int offset, int len);
137
static void dissect_asf_payload_integrity(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree,
138
  int offset, int len);
139
140
static int
141
dissect_asf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
142
7
{
143
7
  proto_tree *asf_tree = NULL;
144
7
  proto_item *ti;
145
7
  uint8_t     type;
146
7
  uint8_t     len;
147
7
  tvbuff_t   *next_tvb;
148
149
7
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "ASF");
150
151
7
  col_clear(pinfo->cinfo, COL_INFO);
152
153
7
  type = tvb_get_uint8(tvb, 4);
154
7
  len = tvb_get_uint8(tvb, 7);
155
156
7
  col_add_str(pinfo->cinfo, COL_INFO,
157
7
    val_to_str(pinfo->pool, type, asf_type_vals, "Unknown (0x%02x)"));
158
159
7
  if (tree) {
160
7
    ti = proto_tree_add_item(tree, proto_asf, tvb, 0, 8,ENC_NA);
161
7
    asf_tree = proto_item_add_subtree(ti, ett_asf);
162
7
    proto_tree_add_item(asf_tree, hf_asf_iana, tvb, 0, 4,ENC_BIG_ENDIAN);
163
7
    proto_tree_add_item(asf_tree, hf_asf_type, tvb, 4, 1,ENC_BIG_ENDIAN);
164
7
    proto_tree_add_item(asf_tree, hf_asf_tag, tvb, 5, 1,ENC_BIG_ENDIAN);
165
7
    proto_tree_add_item(asf_tree, hf_asf_len, tvb, 7, 1,ENC_BIG_ENDIAN);
166
7
  }
167
168
7
  if (len) {
169
6
    switch(type) {
170
0
    case ASF_TYPE_OPEN_SESS_RQST:
171
0
      dissect_asf_open_session_request(tvb, pinfo, asf_tree, 8, len);
172
0
      break;
173
5
    case ASF_TYPE_OPEN_SESS_RESP:
174
5
      dissect_asf_open_session_response(tvb, pinfo, asf_tree, 8, len);
175
5
      break;
176
177
    /* TODO: Add the rest as captures become available to test. */
178
179
1
    default:
180
1
      next_tvb = tvb_new_subset_length(tvb, 8, len);
181
1
      call_data_dissector(next_tvb, pinfo, tree);
182
1
      break;
183
6
    }
184
6
  }
185
7
  return 8 + len;
186
7
}
187
188
static void
189
dissect_asf_open_session_request(tvbuff_t *tvb, packet_info *pinfo,
190
  proto_tree *tree, int offset, int len)
191
0
{
192
0
  proto_tree_add_item(tree, hf_asf_mgt_console_id, tvb, offset, 4,ENC_BIG_ENDIAN);
193
0
  offset += 4;
194
0
  len    -= 4;
195
0
  dissect_asf_payloads(tvb, pinfo, tree, offset, len);
196
0
}
197
198
static void
199
dissect_asf_open_session_response(tvbuff_t *tvb, packet_info *pinfo,
200
  proto_tree *tree, int offset, int len)
201
5
{
202
5
  proto_tree_add_item(tree, hf_asf_rssp_status_code, tvb, offset, 1,ENC_BIG_ENDIAN);
203
5
  proto_tree_add_item(tree, hf_asf_mgt_console_id, tvb, offset + 4, 4,ENC_BIG_ENDIAN);
204
5
  proto_tree_add_item(tree, hf_asf_client_id, tvb, offset + 8, 4,ENC_BIG_ENDIAN);
205
5
  offset += 12;
206
5
  len    -= 12;
207
5
  dissect_asf_payloads(tvb, pinfo, tree, offset, len);
208
5
}
209
210
static void
211
dissect_asf_payloads(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
212
  int offset, int len)
213
5
{
214
5
  uint8_t     ptype;
215
5
  uint16_t    plen;
216
5
  proto_item *ti;
217
5
  proto_tree *ptree;
218
219
9
  while ( len >= 4 )
220
5
  {
221
5
    ptype = tvb_get_uint8(tvb, offset);
222
5
    plen = tvb_get_ntohs(tvb, offset + 2);
223
224
5
    ti = proto_tree_add_none_format(tree, hf_asf_payload, tvb, offset,
225
5
      plen, "%s: %u bytes",
226
5
      val_to_str(pinfo->pool, ptype, asf_payload_type_vals, "Unknown (%u)"), plen);
227
5
    ptree = proto_item_add_subtree(ti, ett_asf_payload);
228
5
    proto_tree_add_item(ptree, hf_asf_payload_type, tvb, offset, 1,ENC_BIG_ENDIAN);
229
5
    ti = proto_tree_add_item(ptree, hf_asf_payload_len, tvb, offset + 2, 2,ENC_BIG_ENDIAN);
230
5
    if (plen < 4)
231
1
    {
232
1
      expert_add_info(pinfo, ti, &ei_asf_payload_too_short);
233
1
      break;
234
1
    }
235
4
    if ( ptype && (plen > 4) )
236
3
    {
237
3
      switch ( ptype )
238
3
      {
239
0
        case ASF_PAYLOAD_TYPE_AUTHENTICATION:
240
0
          dissect_asf_payload_authentication(tvb, pinfo, ptree,
241
0
            offset + 4, plen - 4);
242
0
          break;
243
0
        case ASF_PAYLOAD_TYPE_INTEGRITY:
244
0
          dissect_asf_payload_integrity(tvb, pinfo, ptree,
245
0
            offset + 4, plen - 4);
246
0
          break;
247
3
        default:
248
3
          proto_tree_add_item(ptree, hf_asf_payload_data, tvb,
249
3
            offset + 4, plen - 4,ENC_NA);
250
3
          break;
251
3
      }
252
3
    }
253
4
    offset += plen;
254
4
    len    -= plen;
255
4
  }
256
5
}
257
258
static void
259
dissect_asf_payload_authentication(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree,
260
  int offset, int len)
261
0
{
262
0
  uint8_t     alg;
263
0
  proto_item *ti;
264
0
  proto_tree *atree;
265
266
0
  alg = tvb_get_uint8(tvb, offset);
267
0
  ti = proto_tree_add_none_format(tree, hf_asf_payload_data, tvb, offset,
268
0
    len, "Authentication Algorithm: %s",
269
0
    val_to_str(pinfo->pool, alg, asf_authentication_type_vals, "Unknown (%u)"));
270
0
  atree = proto_item_add_subtree(ti, ett_asf_alg_payload);
271
0
  proto_tree_add_item(atree, hf_asf_auth_alg, tvb, offset, 1,ENC_BIG_ENDIAN);
272
0
  proto_tree_add_item(atree, hf_asf_reserved, tvb, offset + 1, len - 1,ENC_NA);
273
0
}
274
275
static void
276
dissect_asf_payload_integrity(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree,
277
  int offset, int len)
278
0
{
279
0
  uint8_t     alg;
280
0
  proto_item *ti;
281
0
  proto_tree *atree;
282
283
0
  alg = tvb_get_uint8(tvb, offset);
284
0
  ti = proto_tree_add_none_format(tree, hf_asf_payload_data, tvb, offset,
285
0
    len, "Integrity Algorithm: %s",
286
0
    val_to_str(pinfo->pool, alg, asf_integrity_type_vals, "Unknown (%u)"));
287
0
  atree = proto_item_add_subtree(ti, ett_asf_alg_payload);
288
0
  proto_tree_add_item(atree, hf_asf_integrity_alg, tvb, offset, 1,ENC_BIG_ENDIAN);
289
0
  proto_tree_add_item(atree, hf_asf_reserved, tvb, offset + 1, len - 1,ENC_NA);
290
0
}
291
292
void
293
proto_register_asf(void)
294
14
{
295
14
  static hf_register_info hf[] = {
296
14
    { &hf_asf_iana, {
297
14
      "IANA Enterprise Number", "asf.iana",
298
14
      FT_UINT32, BASE_ENTERPRISES, STRINGS_ENTERPRISES, 0,
299
14
      NULL, HFILL }},
300
14
    { &hf_asf_type, {
301
14
      "Message Type", "asf.type",
302
14
      FT_UINT8, BASE_HEX, VALS(asf_type_vals), 0,
303
14
      "ASF Message Type", HFILL }},
304
14
    { &hf_asf_tag, {
305
14
      "Message Tag", "asf.tag",
306
14
      FT_UINT8, BASE_HEX, NULL, 0,
307
14
      "ASF Message Tag", HFILL }},
308
14
    { &hf_asf_len, {
309
14
      "Data Length", "asf.len",
310
14
      FT_UINT8, BASE_DEC, NULL, 0,
311
14
      "ASF Data Length", HFILL }},
312
14
    { &hf_asf_rssp_status_code, {
313
14
      "Status Code", "asf.rssp_status_code",
314
14
      FT_UINT8, BASE_DEC, VALS(asf_rssp_status_code_vals), 0,
315
14
      "Identifies the status of the previous message", HFILL }},
316
14
    { &hf_asf_mgt_console_id, {
317
14
      "Mgt Console Session ID", "asf.mgt_console_id",
318
14
      FT_UINT32, BASE_DEC, NULL, 0,
319
14
      NULL, HFILL }},
320
14
    { &hf_asf_client_id, {
321
14
      "Managed Client Session ID", "asf.client_id",
322
14
      FT_UINT32, BASE_DEC, NULL, 0,
323
14
      NULL, HFILL }},
324
14
    { &hf_asf_payload, {
325
14
      "Payload", "asf.payload",
326
14
      FT_NONE, BASE_NONE, NULL, 0,
327
14
      NULL, HFILL }},
328
14
    { &hf_asf_payload_type, {
329
14
      "Payload Type", "asf.payload.type",
330
14
      FT_UINT8, BASE_DEC, VALS(asf_payload_type_vals), 0,
331
14
      "Identifies the type of payload that follows", HFILL }},
332
14
    { &hf_asf_payload_len, {
333
14
      "Payload Length", "asf.payload.len",
334
14
      FT_UINT16, BASE_DEC, NULL, 0,
335
14
      "The total length in bytes of the payload including the header",
336
14
      HFILL }},
337
14
    { &hf_asf_payload_data, {
338
14
      "Data", "asf.payload.data",
339
14
      FT_NONE, BASE_NONE, NULL, 0,
340
14
      NULL, HFILL }},
341
14
    { &hf_asf_auth_alg, {
342
14
      "Authentication Algorithm", "asf.auth_alg",
343
14
      FT_UINT8, BASE_DEC, VALS(asf_authentication_type_vals), 0,
344
14
      NULL, HFILL }},
345
14
    { &hf_asf_integrity_alg, {
346
14
      "Integrity Algorithm", "asf.integrity_alg",
347
14
      FT_UINT8, BASE_DEC, VALS(asf_integrity_type_vals), 0,
348
14
      NULL, HFILL }},
349
14
    { &hf_asf_reserved, {
350
14
      "Reserved", "asf.reserved",
351
14
      FT_NONE, BASE_NONE, NULL, 0,
352
14
      NULL, HFILL }},
353
14
  };
354
14
  static int *ett[] = {
355
14
    &ett_asf,
356
14
    &ett_asf_payload,
357
14
    &ett_asf_alg_payload
358
14
  };
359
360
14
  static ei_register_info ei[] = {
361
14
    { &ei_asf_payload_too_short, { "asf.payload_too_short", PI_MALFORMED, PI_ERROR, "Payload length too short to include the type and length", EXPFILL }},
362
14
  };
363
364
14
  expert_module_t* expert_asf;
365
366
14
  proto_asf = proto_register_protocol("Alert Standard Forum", "ASF", "asf");
367
368
14
  proto_register_field_array(proto_asf, hf, array_length(hf));
369
14
  proto_register_subtree_array(ett, array_length(ett));
370
14
  expert_asf = expert_register_protocol(proto_asf);
371
14
  expert_register_field_array(expert_asf, ei, array_length(ei));
372
373
14
  asf_handle = register_dissector("asf", dissect_asf, proto_asf);
374
14
}
375
376
void
377
proto_reg_handoff_asf(void)
378
14
{
379
14
  dissector_add_uint("rmcp.class", RMCP_CLASS_ASF, asf_handle);
380
14
}
381
382
/*
383
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
384
 *
385
 * Local variables:
386
 * c-basic-offset: 8
387
 * tab-width: 8
388
 * indent-tabs-mode: t
389
 * End:
390
 *
391
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
392
 * :indentSize=8:tabSize=8:noTabs=false:
393
 */