/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 | } |