Coverage Report

Created: 2026-08-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-rdp_snd.c
Line
Count
Source
1
/* packet-rdp_snd.c
2
 * Routines for the audio output RDP channel
3
 * Copyright 2023, David Fort <contact@hardening-consulting.com>
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
/*
13
 * See: "[MS-RDPEA] "
14
 */
15
16
#include "config.h"
17
18
#include <epan/packet.h>
19
#include <epan/prefs.h>
20
#include <epan/conversation.h>
21
#include <epan/expert.h>
22
23
#include "packet-rdpudp.h"
24
25
void proto_register_rdp_snd(void);
26
void proto_reg_handoff_rdp_snd(void);
27
28
static int proto_rdp_snd;
29
30
static int hf_snd_msgType;
31
static int hf_snd_bPad;
32
static int hf_snd_bodySize;
33
34
static int ett_rdp_snd;
35
36
enum {
37
  SNDC_CLOSE = 0x01,
38
  SNDC_WAVE = 0x02,
39
  SNDC_SETVOLUME = 0x03,
40
  SNDC_SETPITCH = 0x04,
41
  SNDC_WAVECONFIRM = 0x05,
42
  SNDC_TRAINING = 0x06,
43
  SNDC_FORMATS = 0x07,
44
  SNDC_CRYPTKEY = 0x08,
45
  SNDC_WAVEENCRYPT = 0x09,
46
  SNDC_UDPWAVE = 0x0A,
47
  SNDC_UDPWAVELAST = 0x0B,
48
  SNDC_QUALITYMODE = 0x0C,
49
  SNDC_WAVE2 = 0x0D,
50
};
51
52
53
static const value_string rdp_snd_order_vals[] = {
54
  { SNDC_CLOSE, "Close"},
55
  { SNDC_WAVE, "Wave"},
56
  { SNDC_SETVOLUME, "Set volume"},
57
  { SNDC_SETPITCH, "Set pitch"},
58
  { SNDC_WAVECONFIRM, "Wave confirm"},
59
  { SNDC_TRAINING, "Training"},
60
  { SNDC_FORMATS, "Formats"},
61
  { SNDC_CRYPTKEY, "Crypt key"},
62
  { SNDC_WAVEENCRYPT, "Wave encrypt"},
63
  { SNDC_UDPWAVE, "Udp wave"},
64
  { SNDC_UDPWAVELAST, "Udp wave last"},
65
  { SNDC_QUALITYMODE, "Quality mode"},
66
  { SNDC_WAVE2, "Wave 2"},
67
  { 0x0, NULL},
68
};
69
70
71
static int
72
dissect_rdp_snd(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *parent_tree _U_, void *data _U_)
73
0
{
74
0
  proto_item *item;
75
0
  int nextOffset, offset = 0;
76
0
  uint32_t cmdId = 0;
77
0
  uint32_t pduLength;
78
0
  proto_tree *tree;
79
80
0
  parent_tree = proto_tree_get_root(parent_tree);
81
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "RDPSND");
82
0
  col_clear(pinfo->cinfo, COL_INFO);
83
84
0
  pduLength = tvb_get_uint32(tvb, offset + 2, ENC_LITTLE_ENDIAN) + 4;
85
0
  nextOffset = offset + pduLength;
86
87
0
  item = proto_tree_add_item(parent_tree, proto_rdp_snd, tvb, offset, pduLength, ENC_NA);
88
0
  tree = proto_item_add_subtree(item, ett_rdp_snd);
89
90
0
  proto_tree_add_item_ret_uint(tree, hf_snd_msgType, tvb, offset, 1, ENC_LITTLE_ENDIAN, &cmdId);
91
0
  offset += 1;
92
93
0
  proto_tree_add_item(tree, hf_snd_bPad, tvb, offset, 1, ENC_LITTLE_ENDIAN);
94
0
  offset += 1;
95
96
0
  proto_tree_add_item(tree, hf_snd_bodySize, tvb, offset, 2, ENC_LITTLE_ENDIAN);
97
  //offset += 2;
98
99
0
  col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(cmdId, rdp_snd_order_vals, "Unknown rdpsnd command"));
100
101
0
  switch (cmdId) {
102
0
  case SNDC_CLOSE:
103
0
  case SNDC_WAVE:
104
0
  case SNDC_SETVOLUME:
105
0
  case SNDC_SETPITCH:
106
0
  case SNDC_WAVECONFIRM:
107
0
  case SNDC_TRAINING:
108
0
  case SNDC_FORMATS:
109
0
  case SNDC_CRYPTKEY:
110
0
  case SNDC_WAVEENCRYPT:
111
0
  case SNDC_UDPWAVE:
112
0
  case SNDC_UDPWAVELAST:
113
0
  case SNDC_QUALITYMODE:
114
0
  case SNDC_WAVE2:
115
0
  default:
116
0
    break;
117
0
  }
118
119
0
  offset = nextOffset;
120
0
  return offset;
121
0
}
122
123
124
16
void proto_register_rdp_snd(void) {
125
16
  static hf_register_info hf[] = {
126
16
    { &hf_snd_msgType,
127
16
      { "MsgrType", "rdp_snd.msgtype",
128
16
        FT_UINT8, BASE_HEX, VALS(rdp_snd_order_vals), 0x0,
129
16
      NULL, HFILL }
130
16
    },
131
16
    { &hf_snd_bPad,
132
16
      { "bPad", "rdp_snd.bpad",
133
16
      FT_UINT8, BASE_HEX, NULL, 0x0,
134
16
      NULL, HFILL }
135
16
    },
136
16
    { &hf_snd_bodySize,
137
16
      { "BodySize", "rdp_snd.bodysize",
138
16
      FT_UINT16, BASE_DEC, NULL, 0x0,
139
16
      NULL, HFILL }
140
16
    },
141
16
  };
142
143
16
  static int *ett[] = {
144
16
    &ett_rdp_snd,
145
16
  };
146
147
16
  proto_rdp_snd = proto_register_protocol("RDP audio output virtual channel Protocol", "rdpsnd", "rdp_snd");
148
149
  /* Register fields and subtrees */
150
16
  proto_register_field_array(proto_rdp_snd, hf, array_length(hf));
151
16
  proto_register_subtree_array(ett, array_length(ett));
152
153
16
  register_dissector("rdp_snd", dissect_rdp_snd, proto_rdp_snd);
154
16
}
155
156
16
void proto_reg_handoff_rdp_snd(void) {
157
16
}