2 * Routines for the audio output RDP channel
3 * Copyright 2023, David Fort <contact@hardening-consulting.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include <epan/packet.h>
19 #include <epan/prefs.h>
20 #include <epan/conversation.h>
21 #include <epan/expert.h>
22 #include <epan/value_string.h>
24 #include "packet-rdpudp.h"
26 #define PNAME "RDP audio output virtual channel Protocol"
27 #define PSNAME "rdpsnd"
28 #define PFNAME "rdp_snd"
30 void proto_register_rdp_snd(void);
31 void proto_reg_handoff_rdp_snd(void);
34 static int proto_rdp_snd
;
36 static int hf_snd_msgType
;
37 static int hf_snd_bPad
;
38 static int hf_snd_bodySize
;
40 static int ett_rdp_snd
;
46 SNDC_SETVOLUME
= 0x03,
48 SNDC_WAVECONFIRM
= 0x05,
52 SNDC_WAVEENCRYPT
= 0x09,
54 SNDC_UDPWAVELAST
= 0x0B,
55 SNDC_QUALITYMODE
= 0x0C,
60 static const value_string rdp_snd_order_vals
[] = {
61 { SNDC_CLOSE
, "Close"},
63 { SNDC_SETVOLUME
, "Set volume"},
64 { SNDC_SETPITCH
, "Set pitch"},
65 { SNDC_WAVECONFIRM
, "Wave confirm"},
66 { SNDC_TRAINING
, "Training"},
67 { SNDC_FORMATS
, "Formats"},
68 { SNDC_CRYPTKEY
, "Crypt key"},
69 { SNDC_WAVEENCRYPT
, "Wave encrypt"},
70 { SNDC_UDPWAVE
, "Udp wave"},
71 { SNDC_UDPWAVELAST
, "Udp wave last"},
72 { SNDC_QUALITYMODE
, "Quality mode"},
73 { SNDC_WAVE2
, "Wave 2"},
79 dissect_rdp_snd(tvbuff_t
*tvb _U_
, packet_info
*pinfo
, proto_tree
*parent_tree _U_
, void *data _U_
)
82 int nextOffset
, offset
= 0;
87 parent_tree
= proto_tree_get_root(parent_tree
);
88 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RDPSND");
89 col_clear(pinfo
->cinfo
, COL_INFO
);
91 pduLength
= tvb_get_uint32(tvb
, offset
+ 2, ENC_LITTLE_ENDIAN
) + 4;
92 nextOffset
= offset
+ pduLength
;
94 item
= proto_tree_add_item(parent_tree
, proto_rdp_snd
, tvb
, offset
, pduLength
, ENC_NA
);
95 tree
= proto_item_add_subtree(item
, ett_rdp_snd
);
97 proto_tree_add_item_ret_uint(tree
, hf_snd_msgType
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &cmdId
);
100 proto_tree_add_item(tree
, hf_snd_bPad
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
103 proto_tree_add_item(tree
, hf_snd_bodySize
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
106 col_set_str(pinfo
->cinfo
, COL_INFO
, val_to_str_const(cmdId
, rdp_snd_order_vals
, "Unknown rdpsnd command"));
113 case SNDC_WAVECONFIRM
:
117 case SNDC_WAVEENCRYPT
:
119 case SNDC_UDPWAVELAST
:
120 case SNDC_QUALITYMODE
:
131 void proto_register_rdp_snd(void) {
132 static hf_register_info hf
[] = {
134 { "MsgrType", "rdp_snd.msgtype",
135 FT_UINT8
, BASE_HEX
, VALS(rdp_snd_order_vals
), 0x0,
139 { "bPad", "rdp_snd.bpad",
140 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
144 { "BodySize", "rdp_snd.bodysize",
145 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
150 static int *ett
[] = {
154 proto_rdp_snd
= proto_register_protocol(PNAME
, PSNAME
, PFNAME
);
156 /* Register fields and subtrees */
157 proto_register_field_array(proto_rdp_snd
, hf
, array_length(hf
));
158 proto_register_subtree_array(ett
, array_length(ett
));
160 register_dissector("rdp_snd", dissect_rdp_snd
, proto_rdp_snd
);
163 void proto_reg_handoff_rdp_snd(void) {