Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-steam-ihs-discovery.c
blobdf1d7660174fd33ec2be7cad82f3c79a7f4380fc
1 /* packet-steam_ihs_discovery.c
2 * Routines for Steam In-Home Streaming Discovery Protocol dissection
3 * Copyright 2017, Jan Holthuis <jan.holthuis@ruhr-uni-bochum.de>
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
12 /* Steam In-Home Streaming Discovery Protocol detects servers and negotiates
13 * connections to stream video games over the networks. It is used by
14 * Valve Software's Steam Client and Steam Link devices.
16 * Further Information:
17 * https://codingrange.com/blog/steam-in-home-streaming-discovery-protocol
18 * https://codingrange.com/blog/steam-in-home-streaming-control-protocol
21 #include <config.h>
23 #include <epan/packet.h> /* Should be first Wireshark include (other than config.h) */
24 #include <epan/expert.h> /* Include only as needed */
25 #include <epan/prefs.h> /* Include only as needed */
27 /* Prototypes */
28 /* (Required to prevent [-Wmissing-prototypes] warnings */
29 void proto_reg_handoff_steam_ihs_discovery(void);
30 void proto_register_steam_ihs_discovery(void);
32 static dissector_handle_t steam_ihs_discovery_handle;
34 static int proto_steam_ihs_discovery;
36 static int hf_steam_ihs_discovery_signature;
37 static int hf_steam_ihs_discovery_header_length;
38 static int hf_steam_ihs_discovery_header_clientid;
39 static int hf_steam_ihs_discovery_header_msgtype;
40 static int hf_steam_ihs_discovery_header_instanceid;
41 static int hf_steam_ihs_discovery_body_length;
42 static int hf_steam_ihs_discovery_body_discovery_seqnum;
43 static int hf_steam_ihs_discovery_body_discovery_clientids;
44 static int hf_steam_ihs_discovery_body_status_version;
45 static int hf_steam_ihs_discovery_body_status_minversion;
46 static int hf_steam_ihs_discovery_body_status_connectport;
47 static int hf_steam_ihs_discovery_body_status_hostname;
48 static int hf_steam_ihs_discovery_body_status_enabledservices;
49 static int hf_steam_ihs_discovery_body_status_ostype;
50 static int hf_steam_ihs_discovery_body_status_is64bit;
51 static int hf_steam_ihs_discovery_body_status_euniverse;
52 static int hf_steam_ihs_discovery_body_status_timestamp;
53 static int hf_steam_ihs_discovery_body_status_screenlocked;
54 static int hf_steam_ihs_discovery_body_status_gamesrunning;
55 static int hf_steam_ihs_discovery_body_status_macaddresses;
56 static int hf_steam_ihs_discovery_body_status_user_steamid;
57 static int hf_steam_ihs_discovery_body_status_user_authkeyid;
58 static int hf_steam_ihs_discovery_body_authrequest_devicetoken;
59 static int hf_steam_ihs_discovery_body_authrequest_devicename;
60 static int hf_steam_ihs_discovery_body_authrequest_encryptedrequest;
61 static int hf_steam_ihs_discovery_body_authresponse_authresult;
62 static int hf_steam_ihs_discovery_body_streamingrequest_requestid;
63 static int hf_steam_ihs_discovery_body_streamingrequest_maximumresolutionx;
64 static int hf_steam_ihs_discovery_body_streamingrequest_maximumresolutiony;
65 static int hf_steam_ihs_discovery_body_streamingrequest_audiochannelcount;
66 static int hf_steam_ihs_discovery_body_streamingrequest_deviceversion;
67 static int hf_steam_ihs_discovery_body_streamingrequest_streamdesktop;
68 static int hf_steam_ihs_discovery_body_streamingrequest_devicetoken;
69 static int hf_steam_ihs_discovery_body_streamingrequest_pin;
70 static int hf_steam_ihs_discovery_body_streamingrequest_enablevideostreaming;
71 static int hf_steam_ihs_discovery_body_streamingrequest_enableaudiostreaming;
72 static int hf_steam_ihs_discovery_body_streamingrequest_enableinputstreaming;
73 static int hf_steam_ihs_discovery_body_streamingcancelrequest_requestid;
74 static int hf_steam_ihs_discovery_body_streamingresponse_requestid;
75 static int hf_steam_ihs_discovery_body_streamingresponse_result;
76 static int hf_steam_ihs_discovery_body_streamingresponse_port;
77 static int hf_steam_ihs_discovery_body_streamingresponse_encryptedsessionkey;
78 static int hf_steam_ihs_discovery_body_streamingresponse_virtualherelicenseddevicecount;
79 static int hf_steam_ihs_discovery_body_proofrequest_challenge;
80 static int hf_steam_ihs_discovery_body_proofresponse_response;
81 static int hf_steam_ihs_discovery_unknown_data;
82 static int hf_steam_ihs_discovery_unknown_number;
84 static const val64_string hf_steam_ihs_discovery_header_msgtype_strings[] = {
85 { 0, "Client Discovery" },
86 { 1, "Client Status" },
87 { 2, "Client Offline" },
88 { 3, "Device Authorization Request" },
89 { 4, "Device Authorization Response" },
90 { 5, "Device Streaming Request" },
91 { 6, "Device Streaming Response" },
92 { 7, "Device Proof Request" },
93 { 8, "Device Proof Response" },
94 { 9, "Device Authorization Cancel Request" },
95 { 10, "Device Streaming Cancel Request" },
96 { 0, NULL }
99 static const val64_string hf_steam_ihs_discovery_body_authresponse_authresult_strings[] = {
100 { 0, "Success" },
101 { 1, "Denied" },
102 { 2, "Not Logged In" },
103 { 3, "Offline" },
104 { 4, "Busy" },
105 { 5, "In Progress" },
106 { 6, "TimedOut" },
107 { 7, "Failed" },
108 { 8, "Canceled" },
109 { 0, NULL }
112 static const val64_string hf_steam_ihs_discovery_body_streamingresponse_result_strings[] = {
113 { 0, "Success" },
114 { 1, "Unauthorized" },
115 { 2, "Screen Locked" },
116 { 3, "Failed" },
117 { 4, "Busy" },
118 { 5, "In Progress" },
119 { 6, "Canceled" },
120 { 7, "Drivers Not Installed" },
121 { 8, "Disabled" },
122 { 9, "Broadcasting Active" },
123 { 10, "VR Active" },
124 { 11, "PIN Required" },
125 { 0, NULL }
128 static expert_field ei_steam_ihs_discovery_unknown_data;
129 static expert_field ei_steam_ihs_discovery_unknown_number;
130 static expert_field ei_steam_ihs_discovery_unknown_lengthdelimited;
131 static expert_field ei_steam_ihs_discovery_invalid_wiretype;
132 static expert_field ei_steam_ihs_discovery_invalid_length;
134 #define STEAM_IHS_DISCOVERY_UDP_PORT 27036
136 /* Initialize the subtree pointers */
137 static int ett_steam_ihs_discovery;
138 static int ett_steam_ihs_discovery_body_status_user;
140 #define STEAM_IHS_DISCOVERY_MIN_LENGTH 12
141 #define STEAM_IHS_DISCOVERY_SIGNATURE_LENGTH 8
142 #define STEAM_IHS_DISCOVERY_SIGNATURE_VALUE 0xFFFFFFFF214C5FA0
144 /* Helper functions and structs for reading Protocol Buffers.
146 * Detailed information about protobuf message encoding can be found at:
147 * https://developers.google.com/protocol-buffers/docs/encoding#structure
149 #define PROTOBUF_WIRETYPE_VARINT 0
150 #define PROTOBUF_WIRETYPE_64BIT 1
151 #define PROTOBUF_WIRETYPE_LENGTHDELIMITED 2
152 #define PROTOBUF_WIRETYPE_32BIT 5
154 static const char * const protobuf_wiretype_names[] = {"VarInt", "64-bit", "Length-delimited", "Start group", "End group", "32-bit"};
155 static const char protobuf_wiretype_name_unknown[] = "Unknown";
157 static const char* protobuf_get_wiretype_name(uint8_t wire_type) {
158 if (wire_type <= 5) {
159 return protobuf_wiretype_names[wire_type];
161 return protobuf_wiretype_name_unknown;
164 static int64_t
165 get_varint64(tvbuff_t *tvb, int offset, int bytes_left, int* len)
167 uint8_t b;
168 int64_t result = 0;
169 *len = 0;
170 while ((*len) < bytes_left) {
171 b = tvb_get_uint8(tvb, offset+(*len));
172 result |= ((int64_t)b & 0x7f) << ((*len)*7);
173 (*len)++;
174 if ((b & 0x80) == 0) {
175 break;
178 return result;
181 typedef struct {
182 tvbuff_t *tvb;
183 int offset;
184 int bytes_left;
185 } protobuf_desc_t;
187 typedef struct {
188 uint64_t value;
189 uint64_t field_number;
190 uint8_t wire_type;
191 } protobuf_tag_t;
193 static void
194 protobuf_seek_forward(protobuf_desc_t* pb, int len)
196 pb->offset += len;
197 pb->bytes_left -= len;
200 static int
201 protobuf_iter_next(protobuf_desc_t* pb, protobuf_tag_t* tag)
203 int len;
204 if (pb->bytes_left <= 0) {
205 return 0;
207 tag->value = get_varint64(pb->tvb, pb->offset, pb->bytes_left, &len);
208 tag->field_number = tag->value >> 3;
209 tag->wire_type = tag->value & 0x7;
210 protobuf_seek_forward(pb, len);
211 return pb->bytes_left;
214 static int
215 protobuf_dissect_unknown_field(protobuf_desc_t *pb, protobuf_tag_t *tag, packet_info *pinfo, proto_tree *tree, proto_item** tiptr)
217 int len;
218 int64_t value;
219 proto_item* ti;
221 switch(tag->wire_type) {
222 case PROTOBUF_WIRETYPE_VARINT:
223 value = get_varint64(pb->tvb, pb->offset, pb->bytes_left, &len);
224 ti = proto_tree_add_uint64(tree, hf_steam_ihs_discovery_unknown_number, pb->tvb,
225 pb->offset, len, (uint64_t)value);
226 expert_add_info_format(pinfo, ti, &ei_steam_ihs_discovery_unknown_number, "Unknown numeric protobuf field (wire type %d = %s)", tag->wire_type, protobuf_get_wiretype_name(tag->wire_type));
227 break;
228 case PROTOBUF_WIRETYPE_64BIT:
229 len = 8;
230 ti = proto_tree_add_item(tree, hf_steam_ihs_discovery_unknown_number, pb->tvb, pb->offset+len, len, ENC_LITTLE_ENDIAN);
231 expert_add_info_format(pinfo, ti, &ei_steam_ihs_discovery_unknown_number, "Unknown numeric protobuf field (wire type %d = %s)", tag->wire_type, protobuf_get_wiretype_name(tag->wire_type));
232 break;
233 case PROTOBUF_WIRETYPE_LENGTHDELIMITED:
234 value = get_varint64(pb->tvb, pb->offset, pb->bytes_left, &len);
235 if((uint64_t)value > (uint64_t)(pb->bytes_left-len)) {
236 ti = proto_tree_add_item(tree, hf_steam_ihs_discovery_unknown_data, pb->tvb, pb->offset+len, pb->bytes_left-len, ENC_NA);
237 expert_add_info_format(pinfo, ti, &ei_steam_ihs_discovery_invalid_length, "Length-delimited field %"PRIu64" has length prefix %"PRIu64", but buffer is only %d bytes long.", tag->field_number, (uint64_t)value, (pb->bytes_left-len));
238 len = pb->bytes_left;
239 } else {
240 ti = proto_tree_add_item(tree, hf_steam_ihs_discovery_unknown_data, pb->tvb, pb->offset+len, (int)value, ENC_NA);
241 len += (int)value;
243 expert_add_info(pinfo, ti, &ei_steam_ihs_discovery_unknown_lengthdelimited);
244 break;
245 case PROTOBUF_WIRETYPE_32BIT:
246 len = 4;
247 ti = proto_tree_add_item(tree, hf_steam_ihs_discovery_unknown_number, pb->tvb, pb->offset+len, len, ENC_LITTLE_ENDIAN);
248 expert_add_info_format(pinfo, ti, &ei_steam_ihs_discovery_unknown_number, "Unknown numeric protobuf field (wire type %d = %s)", tag->wire_type, protobuf_get_wiretype_name(tag->wire_type));
249 break;
250 default:
251 len = pb->bytes_left;
252 ti = proto_tree_add_item(tree, hf_steam_ihs_discovery_unknown_data, pb->tvb, pb->offset, len, ENC_NA);
253 expert_add_info(pinfo, ti, &ei_steam_ihs_discovery_unknown_data);
254 break;
256 if(tiptr != NULL) {
257 *tiptr = ti;
260 return len;
263 static int
264 protobuf_verify_wiretype(protobuf_desc_t *pb, protobuf_tag_t *tag, packet_info *pinfo, proto_tree *tree, uint8_t expected_wire_type)
266 int len;
267 int64_t len_prefix;
268 proto_item *ti = NULL;
270 if(expected_wire_type == tag->wire_type) {
271 if(expected_wire_type == PROTOBUF_WIRETYPE_LENGTHDELIMITED) {
272 len_prefix = get_varint64(pb->tvb, pb->offset, pb->bytes_left, &len);
273 if(len_prefix < 0 || len_prefix > INT_MAX) {
274 ti = proto_tree_add_item(tree, hf_steam_ihs_discovery_unknown_data, pb->tvb, pb->offset+len, pb->bytes_left-len, ENC_NA);
275 expert_add_info_format(pinfo, ti, &ei_steam_ihs_discovery_invalid_length, "Length-delimited field %"PRIu64" has length prefix %"PRId64" outside valid range (0 <= x <= INT_MAX).", tag->field_number, len_prefix);
276 return pb->bytes_left;
277 } else if(((int)len_prefix) > (pb->bytes_left-len)) {
278 ti = proto_tree_add_item(tree, hf_steam_ihs_discovery_unknown_data, pb->tvb, pb->offset+len, pb->bytes_left-len, ENC_NA);
279 expert_add_info_format(pinfo, ti, &ei_steam_ihs_discovery_invalid_length, "Length-delimited field %"PRIu64" has length prefix %"PRId64", but buffer is only %d bytes long.", tag->field_number, len_prefix, (pb->bytes_left-len));
280 return pb->bytes_left;
283 return 0;
285 len = protobuf_dissect_unknown_field(pb, tag, pinfo, tree, &ti);
287 expert_add_info_format(pinfo, ti, &ei_steam_ihs_discovery_invalid_wiretype, "Expected wiretype %d (%s) for field %"PRIu64", but got %d (%s) instead.", expected_wire_type, protobuf_get_wiretype_name(expected_wire_type), tag->field_number, tag->wire_type, protobuf_get_wiretype_name(tag->wire_type));
288 return len;
291 /* The actual protocol-specific stuff */
293 #define STEAMDISCOVER_FN_HEADER_CLIENTID 1
294 #define STEAMDISCOVER_FN_HEADER_MSGTYPE 2
295 #define STEAMDISCOVER_FN_HEADER_INSTANCEID 3
297 #define STEAMDISCOVER_FN_DISCOVERY_SEQNUM 1
298 #define STEAMDISCOVER_FN_DISCOVERY_CLIENTIDS 2
300 #define STEAMDISCOVER_FN_STATUS_VERSION 1
301 #define STEAMDISCOVER_FN_STATUS_MINVERSION 2
302 #define STEAMDISCOVER_FN_STATUS_CONNECTPORT 3
303 #define STEAMDISCOVER_FN_STATUS_HOSTNAME 4
304 #define STEAMDISCOVER_FN_STATUS_ENABLEDSERVICES 6
305 #define STEAMDISCOVER_FN_STATUS_OSTYPE 7
306 #define STEAMDISCOVER_FN_STATUS_IS64BIT 8
307 #define STEAMDISCOVER_FN_STATUS_USERS 9
308 #define STEAMDISCOVER_FN_STATUS_EUNIVERSE 11
309 #define STEAMDISCOVER_FN_STATUS_TIMESTAMP 12
310 #define STEAMDISCOVER_FN_STATUS_SCREENLOCKED 13
311 #define STEAMDISCOVER_FN_STATUS_GAMESRUNNING 14
312 #define STEAMDISCOVER_FN_STATUS_MACADDRESSES 15
313 #define STEAMDISCOVER_FN_STATUS_USER_STEAMID 1
314 #define STEAMDISCOVER_FN_STATUS_USER_AUTHKEYID 2
316 #define STEAMDISCOVER_FN_AUTHREQUEST_DEVICETOKEN 1
317 #define STEAMDISCOVER_FN_AUTHREQUEST_DEVICENAME 2
318 #define STEAMDISCOVER_FN_AUTHREQUEST_ENCRYPTEDREQUEST 3
320 #define STEAMDISCOVER_FN_AUTHRESPONSE_AUTHRESULT 1
322 #define STEAMDISCOVER_FN_STREAMINGREQUEST_REQUESTID 1
323 #define STEAMDISCOVER_FN_STREAMINGREQUEST_MAXIMUMRESOLUTIONX 2
324 #define STEAMDISCOVER_FN_STREAMINGREQUEST_MAXIMUMRESOLUTIONY 3
325 #define STEAMDISCOVER_FN_STREAMINGREQUEST_AUDIOCHANNELCOUNT 4
326 #define STEAMDISCOVER_FN_STREAMINGREQUEST_DEVICEVERSION 5
327 #define STEAMDISCOVER_FN_STREAMINGREQUEST_STREAMDESKTOP 6
328 #define STEAMDISCOVER_FN_STREAMINGREQUEST_DEVICETOKEN 7
329 #define STEAMDISCOVER_FN_STREAMINGREQUEST_PIN 8
330 #define STEAMDISCOVER_FN_STREAMINGREQUEST_ENABLEVIDEOSTREAMING 9
331 #define STEAMDISCOVER_FN_STREAMINGREQUEST_ENABLEAUDIOSTREAMING 10
332 #define STEAMDISCOVER_FN_STREAMINGREQUEST_ENABLEINPUTSTREAMING 11
334 #define STEAMDISCOVER_FN_STREAMINGCANCELREQUEST_REQUESTID 1
336 #define STEAMDISCOVER_FN_STREAMINGRESPONSE_REQUESTID 1
337 #define STEAMDISCOVER_FN_STREAMINGRESPONSE_RESULT 2
338 #define STEAMDISCOVER_FN_STREAMINGRESPONSE_PORT 3
339 #define STEAMDISCOVER_FN_STREAMINGRESPONSE_ENCRYPTEDSESSIONKEY 4
340 #define STEAMDISCOVER_FN_STREAMINGRESPONSE_VIRTUALHERELICENSEDDEVICECOUNT 5
342 #define STEAMDISCOVER_FN_PROOFREQUEST_CHALLENGE 1
343 #define STEAMDISCOVER_FN_PROOFRESPONSE_RESPONSE 1
345 #define STEAMDISCOVER_MSGTYPE_CLIENTBROADCASTMSGDISCOVERY 0
346 #define STEAMDISCOVER_MSGTYPE_CLIENTBROADCASTMSGSTATUS 1
347 #define STEAMDISCOVER_MSGTYPE_CLIENTBROADCASTMSGOFFLINE 2
348 #define STEAMDISCOVER_MSGTYPE_DEVICEAUTHORIZATIONREQUEST 3
349 #define STEAMDISCOVER_MSGTYPE_DEVICEAUTHORIZATIONRESPONSE 4
350 #define STEAMDISCOVER_MSGTYPE_DEVICESTREAMINGREQUEST 5
351 #define STEAMDISCOVER_MSGTYPE_DEVICESTREAMINGRESPONSE 6
352 #define STEAMDISCOVER_MSGTYPE_DEVICEPROOFREQUEST 7
353 #define STEAMDISCOVER_MSGTYPE_DEVICEPROOFRESPONSE 8
354 #define STEAMDISCOVER_MSGTYPE_DEVICEAUTHORIZATIONCANCELREQUEST 9
355 #define STEAMDISCOVER_MSGTYPE_DEVICESTREAMINGCANCELREQUEST 10
356 #define STEAMDISCOVER_MSGTYPES_MAX 10
358 #define STEAMDISCOVER_ENSURE_WIRETYPE(X) if((len = protobuf_verify_wiretype(&pb, &tag, pinfo, tree, X))) break;
360 /* Dissect the header section of a packet. The header is a
361 * CMsgRemoteClientBroadcastHeader protobuf message.
363 * enum ERemoteClientBroadcastMsg {
364 * k_ERemoteClientBroadcastMsgDiscovery = 0;
365 * k_ERemoteClientBroadcastMsgStatus = 1;
366 * k_ERemoteClientBroadcastMsgOffline = 2;
367 * k_ERemoteDeviceAuthorizationRequest = 3;
368 * k_ERemoteDeviceAuthorizationResponse = 4;
369 * k_ERemoteDeviceStreamingRequest = 5;
370 * k_ERemoteDeviceStreamingResponse = 6;
371 * k_ERemoteDeviceProofRequest = 7;
372 * k_ERemoteDeviceProofResponse = 8;
373 * k_ERemoteDeviceAuthorizationCancelRequest = 9;
374 * k_ERemoteDeviceStreamingCancelRequest = 10;
377 * message CMsgRemoteClientBroadcastHeader {
378 * optional uint64 client_id = 1;
379 * optional ERemoteClientBroadcastMsg msg_type = 2;
380 * optional uint64 instance_id = 3;
383 static int64_t
384 steamdiscover_dissect_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
385 int offset, int bytes_left)
387 int len;
388 int64_t value;
389 int64_t msg_type = -1;
390 protobuf_desc_t pb = { tvb, offset, bytes_left };
391 protobuf_tag_t tag = { 0, 0, 0 };
392 while (protobuf_iter_next(&pb, &tag)) {
393 switch(tag.field_number) {
394 case STEAMDISCOVER_FN_HEADER_CLIENTID:
395 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
396 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
397 proto_tree_add_uint64(tree, hf_steam_ihs_discovery_header_clientid, pb.tvb,
398 pb.offset, len, (uint64_t)value);
399 break;
400 case STEAMDISCOVER_FN_HEADER_MSGTYPE:
401 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
402 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
403 msg_type = value;
404 proto_tree_add_uint64(tree, hf_steam_ihs_discovery_header_msgtype, pb.tvb,
405 pb.offset, len, (uint64_t)value);
406 break;
407 case STEAMDISCOVER_FN_HEADER_INSTANCEID:
408 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
409 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
410 proto_tree_add_uint64(tree, hf_steam_ihs_discovery_header_instanceid, pb.tvb,
411 pb.offset, len, (uint64_t)value);
412 break;
413 default:
414 len = protobuf_dissect_unknown_field(&pb, &tag, pinfo, tree, NULL);
415 break;
417 protobuf_seek_forward(&pb, len);
419 return msg_type;
422 /* Dissect a CMsgRemoteClientBroadcastDiscovery protobuf message body.
424 * message CMsgRemoteClientBroadcastDiscovery {
425 * optional uint32 seq_num = 1;
426 * repeated uint64 client_ids = 2;
429 static void
430 steamdiscover_dissect_body_discovery(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
431 int offset, int bytes_left)
433 int len;
434 int64_t value;
435 protobuf_desc_t pb = { tvb, offset, bytes_left };
436 protobuf_tag_t tag = { 0, 0, 0 };
437 while (protobuf_iter_next(&pb, &tag)) {
438 switch(tag.field_number) {
439 case STEAMDISCOVER_FN_DISCOVERY_SEQNUM:
440 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
441 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
442 proto_tree_add_uint(tree, hf_steam_ihs_discovery_body_discovery_seqnum, pb.tvb,
443 pb.offset, len, (uint32_t)value);
444 col_append_fstr(pinfo->cinfo, COL_INFO, " Seq=%"PRIu32, (uint32_t)value);
445 break;
446 case STEAMDISCOVER_FN_DISCOVERY_CLIENTIDS:
447 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
448 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
449 proto_tree_add_uint64(tree, hf_steam_ihs_discovery_body_discovery_clientids, pb.tvb,
450 pb.offset, len, value);
451 break;
452 default:
453 len = protobuf_dissect_unknown_field(&pb, &tag, pinfo, tree, NULL);
454 break;
456 protobuf_seek_forward(&pb, len);
460 /* Dissect a CMsgRemoteClientBroadcastStatus protobuf message body.
462 * message CMsgRemoteClientBroadcastStatus {
463 * message User {
464 * optional fixed64 steamid = 1;
465 * optional uint32 auth_key_id = 2;
467 * optional int32 version = 1;
468 * optional int32 min_version = 2;
469 * optional uint32 connect_port = 3;
470 * optional string hostname = 4;
471 * optional uint32 enabled_services = 6;
472 * optional int32 ostype = 7 [default = 0];
473 * optional bool is64bit = 8 [default = false];
474 * repeated CMsgRemoteClientBroadcastStatus.User users = 9;
475 * optional int32 euniverse = 11;
476 * optional uint32 timestamp = 12;
477 * optional bool screen_locked = 13;
478 * optional bool games_running = 14;
479 * repeated string mac_addresses = 15;
480 * optional uint32 download_lan_peer_group = 16;
481 * optional bool broadcasting_active = 17;
482 * optional bool vr_active = 18;
485 static void
486 steamdiscover_dissect_body_status(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
487 int offset, int bytes_left)
489 int64_t value;
490 int len;
491 int len2;
492 protobuf_desc_t pb = { tvb, offset, bytes_left };
493 protobuf_desc_t pb2 = { tvb, 0, 0 };
494 protobuf_tag_t tag = { 0, 0, 0 };
495 uint8_t *hostname;
496 nstime_t timestamp;
497 proto_tree *user_tree;
498 proto_item *user_it;
499 while (protobuf_iter_next(&pb, &tag)) {
500 switch(tag.field_number) {
501 case STEAMDISCOVER_FN_STATUS_VERSION:
502 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
503 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
504 proto_tree_add_int(tree, hf_steam_ihs_discovery_body_status_version, pb.tvb,
505 pb.offset, len, (int32_t)value);
506 break;
507 case STEAMDISCOVER_FN_STATUS_MINVERSION:
508 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
509 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
510 proto_tree_add_int(tree, hf_steam_ihs_discovery_body_status_minversion, pb.tvb,
511 pb.offset, len, (int32_t)value);
512 break;
513 case STEAMDISCOVER_FN_STATUS_CONNECTPORT:
514 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
515 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
516 proto_tree_add_uint(tree, hf_steam_ihs_discovery_body_status_connectport, pb.tvb,
517 pb.offset, len, (uint32_t)value);
518 break;
519 case STEAMDISCOVER_FN_STATUS_HOSTNAME:
520 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_LENGTHDELIMITED);
521 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
522 proto_tree_add_item(tree, hf_steam_ihs_discovery_body_status_hostname, pb.tvb,
523 pb.offset+len, (int)value, ENC_UTF_8);
524 hostname = tvb_get_string_enc(pinfo->pool, pb.tvb, pb.offset+len, (int)value, ENC_UTF_8);
525 if(hostname && strlen(hostname)) {
526 col_add_fstr(pinfo->cinfo, COL_INFO, "%s from %s", hf_steam_ihs_discovery_header_msgtype_strings[STEAMDISCOVER_MSGTYPE_CLIENTBROADCASTMSGSTATUS].strptr, hostname);
528 len += (int)value;
529 break;
530 case STEAMDISCOVER_FN_STATUS_ENABLEDSERVICES:
531 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
532 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
533 proto_tree_add_uint(tree, hf_steam_ihs_discovery_body_status_enabledservices, pb.tvb,
534 pb.offset, len, (uint32_t)value);
535 break;
536 case STEAMDISCOVER_FN_STATUS_OSTYPE:
537 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
538 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
539 proto_tree_add_int(tree, hf_steam_ihs_discovery_body_status_ostype, pb.tvb,
540 pb.offset, len, (int32_t)value);
541 break;
542 case STEAMDISCOVER_FN_STATUS_IS64BIT:
543 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
544 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
545 proto_tree_add_boolean(tree, hf_steam_ihs_discovery_body_status_is64bit, pb.tvb,
546 pb.offset, len, (int32_t)value);
547 break;
548 case STEAMDISCOVER_FN_STATUS_USERS:
549 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_LENGTHDELIMITED);
550 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
551 pb2.offset = pb.offset+len;
552 pb2.bytes_left = (int)value;
553 len += (int)value;
554 user_tree = proto_tree_add_subtree(tree, pb.tvb, pb.offset, len, ett_steam_ihs_discovery_body_status_user, &user_it, "User");
555 while (protobuf_iter_next(&pb2, &tag)) {
556 switch(tag.field_number) {
557 case STEAMDISCOVER_FN_STATUS_USER_STEAMID:
558 if((len2 = protobuf_verify_wiretype(&pb2, &tag, pinfo, user_tree, PROTOBUF_WIRETYPE_64BIT))) break;
559 len2 = 8;
560 value = tvb_get_letoh64(pb2.tvb, pb2.offset);
561 proto_tree_add_uint64(user_tree, hf_steam_ihs_discovery_body_status_user_steamid, pb2.tvb,
562 pb2.offset, len2, (uint64_t)value);
563 proto_item_append_text(user_it, ", Steam ID: %"PRIu64, (uint64_t)value);
564 break;
565 case STEAMDISCOVER_FN_STATUS_USER_AUTHKEYID:
566 if((len2 = protobuf_verify_wiretype(&pb2, &tag, pinfo, user_tree, PROTOBUF_WIRETYPE_VARINT))) break;
567 value = get_varint64(pb2.tvb, pb2.offset, pb2.bytes_left, &len2);
568 proto_tree_add_uint(user_tree, hf_steam_ihs_discovery_body_status_user_authkeyid, pb2.tvb,
569 pb2.offset, len2, (uint32_t)value);
570 proto_item_append_text(user_it, ", Auth Key ID: %"PRIu32, (uint32_t)value);
571 break;
572 default:
573 len2 = protobuf_dissect_unknown_field(&pb2, &tag, pinfo, tree, NULL);
574 break;
576 protobuf_seek_forward(&pb2, len2);
578 break;
579 case STEAMDISCOVER_FN_STATUS_EUNIVERSE:
580 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
581 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
582 proto_tree_add_int(tree, hf_steam_ihs_discovery_body_status_euniverse, pb.tvb,
583 pb.offset, len, (int32_t)value);
584 break;
585 case STEAMDISCOVER_FN_STATUS_TIMESTAMP:
586 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
587 timestamp.secs = (time_t)get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
588 timestamp.nsecs = 0;
589 proto_tree_add_time(tree, hf_steam_ihs_discovery_body_status_timestamp, pb.tvb,
590 pb.offset, len, &timestamp);
591 break;
592 case STEAMDISCOVER_FN_STATUS_SCREENLOCKED:
593 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
594 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
595 proto_tree_add_boolean(tree, hf_steam_ihs_discovery_body_status_screenlocked, pb.tvb,
596 pb.offset, len, (int32_t)value);
597 break;
598 case STEAMDISCOVER_FN_STATUS_GAMESRUNNING:
599 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
600 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
601 proto_tree_add_boolean(tree, hf_steam_ihs_discovery_body_status_gamesrunning, pb.tvb,
602 pb.offset, len, (int32_t)value);
603 break;
604 case STEAMDISCOVER_FN_STATUS_MACADDRESSES:
605 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_LENGTHDELIMITED);
606 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
607 proto_tree_add_item(tree, hf_steam_ihs_discovery_body_status_macaddresses, pb.tvb,
608 pb.offset+len, (int)value, ENC_UTF_8);
609 len += (int)value;
610 break;
611 default:
612 len = protobuf_dissect_unknown_field(&pb, &tag, pinfo, tree, NULL);
613 break;
615 protobuf_seek_forward(&pb, len);
619 /* Dissect a CMsgRemoteDeviceAuthorizationRequest protobuf message body.
621 * message CMsgRemoteDeviceAuthorizationRequest {
622 * message CKeyEscrow_Ticket {
623 * optional bytes password = 1;
624 * optional uint64 identifier = 2;
625 * optional bytes payload = 3;
626 * optional uint32 timestamp = 4;
627 * optional CMsgRemoteDeviceAuthorizationRequest.EKeyEscrowUsage usage = 5;
628 * optional string device_name = 6;
629 * optional string device_model = 7;
630 * optional string device_serial = 8;
631 * optional uint32 device_provisioning_id = 9;
633 * enum EKeyEscrowUsage {
634 * k_EKeyEscrowUsageStreamingDevice = 0;
636 * required bytes device_token = 1;
637 * optional string device_name = 2;
638 * required bytes encrypted_request = 3;
641 static void
642 steamdiscover_dissect_body_authrequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
643 int offset, int bytes_left)
645 unsigned len;
646 int64_t value;
647 protobuf_desc_t pb = { tvb, offset, bytes_left };
648 protobuf_tag_t tag = { 0, 0, 0 };
649 uint8_t* devicename;
650 while (protobuf_iter_next(&pb, &tag)) {
651 switch(tag.field_number) {
652 case STEAMDISCOVER_FN_AUTHREQUEST_DEVICETOKEN:
653 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_LENGTHDELIMITED);
654 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
655 proto_tree_add_item(tree, hf_steam_ihs_discovery_body_authrequest_devicetoken, pb.tvb,
656 pb.offset+len, (int)value, ENC_NA);
657 len += (int)value;
658 break;
659 case STEAMDISCOVER_FN_AUTHREQUEST_DEVICENAME:
660 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_LENGTHDELIMITED);
661 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
662 proto_tree_add_item(tree, hf_steam_ihs_discovery_body_authrequest_devicename, pb.tvb,
663 pb.offset+len, (int)value, ENC_UTF_8);
664 devicename = tvb_get_string_enc(pinfo->pool, pb.tvb, pb.offset+len, (int)value, ENC_UTF_8);
665 if (devicename && strlen(devicename)) {
666 col_append_fstr(pinfo->cinfo, COL_INFO, " from %s", devicename);
668 len += (int)value;
669 break;
670 case STEAMDISCOVER_FN_AUTHREQUEST_ENCRYPTEDREQUEST:
671 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_LENGTHDELIMITED);
672 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
673 proto_tree_add_item(tree, hf_steam_ihs_discovery_body_authrequest_encryptedrequest, pb.tvb,
674 pb.offset+len, (int)value, ENC_NA);
675 len += (int)value;
676 break;
677 default:
678 len = protobuf_dissect_unknown_field(&pb, &tag, pinfo, tree, NULL);
679 break;
681 protobuf_seek_forward(&pb, len);
685 /* Dissect a CMsgRemoteDeviceAuthorizationResponse protobuf message body.
687 * message CMsgRemoteDeviceAuthorizationResponse {
688 * required ERemoteDeviceAuthorizationResult result = 1;
691 static void
692 steamdiscover_dissect_body_authresponse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
693 int offset, int bytes_left)
695 int len;
696 int64_t value;
697 protobuf_desc_t pb = { tvb, offset, bytes_left };
698 protobuf_tag_t tag = { 0, 0, 0 };
699 while (protobuf_iter_next(&pb, &tag)) {
700 switch(tag.field_number) {
701 case STEAMDISCOVER_FN_AUTHRESPONSE_AUTHRESULT:
702 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
703 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
704 proto_tree_add_uint64(tree, hf_steam_ihs_discovery_body_authresponse_authresult, pb.tvb,
705 pb.offset, len, (uint64_t)value);
706 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Result=%"PRIu64"(%s)", hf_steam_ihs_discovery_header_msgtype_strings[STEAMDISCOVER_MSGTYPE_DEVICEAUTHORIZATIONRESPONSE].strptr,
707 (uint64_t)value, val64_to_str_const((uint64_t)value, hf_steam_ihs_discovery_body_authresponse_authresult_strings, "Unknown"));
708 break;
709 default:
710 len = protobuf_dissect_unknown_field(&pb, &tag, pinfo, tree, NULL);
711 break;
713 protobuf_seek_forward(&pb, len);
717 /* Dissect a CMsgRemoteDeviceStreamingRequest protobuf message body.
719 * message CMsgRemoteDeviceStreamingRequest {
720 * required uint32 request_id = 1;
721 * optional int32 maximum_resolution_x = 2;
722 * optional int32 maximum_resolution_y = 3;
723 * optional int32 audio_channel_count = 4 [default = 2];
724 * optional string device_version = 5;
725 * optional bool stream_desktop = 6;
726 * optional bytes device_token = 7;
727 * optional bytes pin = 8;
728 * optional bool enable_video_streaming = 9 [default = true];
729 * optional bool enable_audio_streaming = 10 [default = true];
730 * optional bool enable_input_streaming = 11 [default = true];
733 static void
734 steamdiscover_dissect_body_streamingrequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
735 int offset, int bytes_left)
737 int len;
738 int64_t value;
739 protobuf_desc_t pb = { tvb, offset, bytes_left };
740 protobuf_tag_t tag = { 0, 0, 0 };
741 while (protobuf_iter_next(&pb, &tag)) {
742 switch(tag.field_number) {
743 case STEAMDISCOVER_FN_STREAMINGREQUEST_REQUESTID:
744 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
745 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
746 proto_tree_add_uint(tree, hf_steam_ihs_discovery_body_streamingrequest_requestid, pb.tvb,
747 pb.offset, len, (uint32_t)value);
748 col_add_fstr(pinfo->cinfo, COL_INFO, "%s ID=%08x", hf_steam_ihs_discovery_header_msgtype_strings[STEAMDISCOVER_MSGTYPE_DEVICESTREAMINGREQUEST].strptr, (uint32_t)value);
749 break;
750 case STEAMDISCOVER_FN_STREAMINGREQUEST_MAXIMUMRESOLUTIONX:
751 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
752 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
753 proto_tree_add_int(tree, hf_steam_ihs_discovery_body_streamingrequest_maximumresolutionx, pb.tvb,
754 pb.offset, len, (int32_t)value);
755 break;
756 case STEAMDISCOVER_FN_STREAMINGREQUEST_MAXIMUMRESOLUTIONY:
757 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
758 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
759 proto_tree_add_int(tree, hf_steam_ihs_discovery_body_streamingrequest_maximumresolutiony, pb.tvb,
760 pb.offset, len, (int32_t)value);
761 break;
762 case STEAMDISCOVER_FN_STREAMINGREQUEST_AUDIOCHANNELCOUNT:
763 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
764 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
765 proto_tree_add_int(tree, hf_steam_ihs_discovery_body_streamingrequest_audiochannelcount, pb.tvb,
766 pb.offset, len, (int32_t)value);
767 break;
768 case STEAMDISCOVER_FN_STREAMINGREQUEST_DEVICEVERSION:
769 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_LENGTHDELIMITED);
770 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
771 proto_tree_add_item(tree, hf_steam_ihs_discovery_body_streamingrequest_deviceversion, pb.tvb, pb.offset+len, (int)value, ENC_UTF_8);
772 len += (int)value;
773 break;
774 case STEAMDISCOVER_FN_STREAMINGREQUEST_STREAMDESKTOP:
775 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
776 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
777 proto_tree_add_boolean(tree, hf_steam_ihs_discovery_body_streamingrequest_streamdesktop, pb.tvb,
778 pb.offset, len, (int32_t)value);
779 break;
780 case STEAMDISCOVER_FN_STREAMINGREQUEST_DEVICETOKEN:
781 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_LENGTHDELIMITED);
782 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
783 proto_tree_add_item(tree, hf_steam_ihs_discovery_body_streamingrequest_devicetoken, pb.tvb, pb.offset+len, (int)value, ENC_NA);
784 len += (int)value;
785 break;
786 case STEAMDISCOVER_FN_STREAMINGREQUEST_PIN:
787 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_LENGTHDELIMITED);
788 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
789 proto_tree_add_item(tree, hf_steam_ihs_discovery_body_streamingrequest_pin, pb.tvb, pb.offset+len, (int)value, ENC_NA);
790 len += (int)value;
791 break;
792 case STEAMDISCOVER_FN_STREAMINGREQUEST_ENABLEVIDEOSTREAMING:
793 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
794 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
795 proto_tree_add_boolean(tree, hf_steam_ihs_discovery_body_streamingrequest_enablevideostreaming, pb.tvb,
796 pb.offset, len, (int32_t)value);
797 break;
798 case STEAMDISCOVER_FN_STREAMINGREQUEST_ENABLEAUDIOSTREAMING:
799 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
800 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
801 proto_tree_add_boolean(tree, hf_steam_ihs_discovery_body_streamingrequest_enableaudiostreaming, pb.tvb,
802 pb.offset, len, (int32_t)value);
803 break;
804 case STEAMDISCOVER_FN_STREAMINGREQUEST_ENABLEINPUTSTREAMING:
805 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
806 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
807 proto_tree_add_boolean(tree, hf_steam_ihs_discovery_body_streamingrequest_enableinputstreaming, pb.tvb,
808 pb.offset, len, (int32_t)value);
809 break;
810 default:
811 len = protobuf_dissect_unknown_field(&pb, &tag, pinfo, tree, NULL);
812 break;
814 protobuf_seek_forward(&pb, len);
818 /* Dissect a CMsgRemoteDeviceStreamingCancelRequest protobuf message body.
820 * message CMsgRemoteDeviceStreamingCancelRequest {
821 * required uint32 request_id = 1;
824 static void
825 steamdiscover_dissect_body_streamingcancelrequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
826 int offset, int bytes_left)
828 unsigned len;
829 int64_t value;
830 protobuf_desc_t pb = { tvb, offset, bytes_left };
831 protobuf_tag_t tag = { 0, 0, 0 };
832 while (protobuf_iter_next(&pb, &tag)) {
833 switch(tag.field_number) {
834 case STEAMDISCOVER_FN_STREAMINGCANCELREQUEST_REQUESTID:
835 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
836 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
837 proto_tree_add_uint(tree, hf_steam_ihs_discovery_body_streamingcancelrequest_requestid, pb.tvb,
838 pb.offset, len, (uint32_t)value);
839 col_add_fstr(pinfo->cinfo, COL_INFO, "%s, ID=%08x", hf_steam_ihs_discovery_header_msgtype_strings[STEAMDISCOVER_MSGTYPE_DEVICESTREAMINGCANCELREQUEST].strptr, (uint32_t)value);
840 break;
841 default:
842 len = protobuf_dissect_unknown_field(&pb, &tag, pinfo, tree, NULL);
843 break;
845 protobuf_seek_forward(&pb, len);
849 /* Dissect a CMsgRemoteDeviceStreamingResponse protobuf message body.
851 * enum ERemoteDeviceStreamingResult {
852 * k_ERemoteDeviceStreamingSuccess = 0;
853 * k_ERemoteDeviceStreamingUnauthorized = 1;
854 * k_ERemoteDeviceStreamingScreenLocked = 2;
855 * k_ERemoteDeviceStreamingFailed = 3;
856 * k_ERemoteDeviceStreamingBusy = 4;
857 * k_ERemoteDeviceStreamingInProgress = 5;
858 * k_ERemoteDeviceStreamingCanceled = 6;
859 * k_ERemoteDeviceStreamingDriversNotInstalled = 7;
860 * k_ERemoteDeviceStreamingDisabled = 8;
861 * k_ERemoteDeviceStreamingBroadcastingActive = 9;
862 * k_ERemoteDeviceStreamingVRActive = 10;
863 * k_ERemoteDeviceStreamingPINRequired = 11;
866 * message CMsgRemoteDeviceStreamingResponse {
867 * required uint32 request_id = 1;
868 * required ERemoteDeviceStreamingResult result = 2;
869 * optional uint32 port = 3;
870 * optional bytes encrypted_session_key = 4;
871 * optional int32 virtualhere_licensed_device_count_OBSOLETE = 5;
874 static void
875 steamdiscover_dissect_body_streamingresponse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
876 int offset, int bytes_left)
878 unsigned len;
879 int64_t value;
880 protobuf_desc_t pb = { tvb, offset, bytes_left };
881 protobuf_tag_t tag = { 0, 0, 0 };
882 while (protobuf_iter_next(&pb, &tag)) {
883 switch(tag.field_number) {
884 case STEAMDISCOVER_FN_STREAMINGRESPONSE_REQUESTID:
885 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
886 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
887 proto_tree_add_uint(tree, hf_steam_ihs_discovery_body_streamingresponse_requestid, pb.tvb,
888 pb.offset, len, (uint32_t)value);
889 col_append_fstr(pinfo->cinfo, COL_INFO, " ID=%08x", (uint32_t)value);
890 break;
891 case STEAMDISCOVER_FN_STREAMINGRESPONSE_RESULT:
892 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
893 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
894 proto_tree_add_uint64(tree, hf_steam_ihs_discovery_body_streamingresponse_result, pb.tvb,
895 pb.offset, len, (uint64_t)value);
896 col_append_fstr(pinfo->cinfo, COL_INFO, " Result=%"PRIu64"(%s)", (uint64_t)value, val64_to_str_const((uint64_t)value, hf_steam_ihs_discovery_body_streamingresponse_result_strings, "Unknown"));
897 break;
898 case STEAMDISCOVER_FN_STREAMINGRESPONSE_PORT:
899 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
900 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
901 proto_tree_add_uint(tree, hf_steam_ihs_discovery_body_streamingresponse_port, pb.tvb,
902 pb.offset, len, (uint32_t)value);
903 col_append_fstr(pinfo->cinfo, COL_INFO, " Port=%"PRIu32, (uint32_t)value);
904 break;
905 case STEAMDISCOVER_FN_STREAMINGRESPONSE_ENCRYPTEDSESSIONKEY:
906 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_LENGTHDELIMITED);
907 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
908 proto_tree_add_item(tree, hf_steam_ihs_discovery_body_streamingresponse_encryptedsessionkey, pb.tvb, pb.offset+len, (int)value, ENC_NA);
909 len += (int)value;
910 break;
911 case STEAMDISCOVER_FN_STREAMINGRESPONSE_VIRTUALHERELICENSEDDEVICECOUNT:
912 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_VARINT);
913 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
914 proto_tree_add_int(tree, hf_steam_ihs_discovery_body_streamingresponse_virtualherelicenseddevicecount, pb.tvb,
915 pb.offset, len, (int32_t)value);
916 break;
917 default:
918 len = protobuf_dissect_unknown_field(&pb, &tag, pinfo, tree, NULL);
919 break;
921 protobuf_seek_forward(&pb, len);
925 /* Dissect a CMsgRemoteDeviceProofRequest protobuf message body.
927 * message CMsgRemoteDeviceProofRequest {
928 * required bytes challenge = 1;
931 static void
932 steamdiscover_dissect_body_proofrequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
933 int offset, int bytes_left)
935 int len;
936 int64_t value;
937 protobuf_desc_t pb = { tvb, offset, bytes_left };
938 protobuf_tag_t tag = { 0, 0, 0 };
939 while (protobuf_iter_next(&pb, &tag)) {
940 switch(tag.field_number) {
941 case STEAMDISCOVER_FN_PROOFREQUEST_CHALLENGE:
942 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_LENGTHDELIMITED);
943 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
944 proto_tree_add_item(tree, hf_steam_ihs_discovery_body_proofrequest_challenge, pb.tvb, pb.offset+len, (int)value, ENC_NA);
945 len += (int)value;
946 break;
947 default:
948 len = protobuf_dissect_unknown_field(&pb, &tag, pinfo, tree, NULL);
949 break;
951 protobuf_seek_forward(&pb, len);
955 /* Dissect a CMsgRemoteDeviceProofResponse protobuf message body.
957 * message CMsgRemoteDeviceProofResponse {
958 * required bytes response = 1;
961 static void
962 steamdiscover_dissect_body_proofresponse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
963 int offset, int bytes_left)
965 int len;
966 int64_t value;
967 protobuf_desc_t pb = { tvb, offset, bytes_left };
968 protobuf_tag_t tag = { 0, 0, 0 };
969 while (protobuf_iter_next(&pb, &tag)) {
970 switch(tag.field_number) {
971 case STEAMDISCOVER_FN_PROOFRESPONSE_RESPONSE:
972 STEAMDISCOVER_ENSURE_WIRETYPE(PROTOBUF_WIRETYPE_LENGTHDELIMITED);
973 value = get_varint64(pb.tvb, pb.offset, pb.bytes_left, &len);
974 proto_tree_add_item(tree, hf_steam_ihs_discovery_body_proofresponse_response, pb.tvb, pb.offset+len, (int)value, ENC_NA);
975 len += (int)value;
976 break;
977 default:
978 len = protobuf_dissect_unknown_field(&pb, &tag, pinfo, tree, NULL);
979 break;
981 protobuf_seek_forward(&pb, len);
985 static void
986 steamdiscover_dissect_body_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
987 int offset, int bytes_left)
989 int len;
990 protobuf_desc_t pb = { tvb, offset, bytes_left };
991 protobuf_tag_t tag = { 0, 0, 0 };
992 while (protobuf_iter_next(&pb, &tag)) {
993 len = protobuf_dissect_unknown_field(&pb, &tag, pinfo, tree, NULL);
994 protobuf_seek_forward(&pb, len);
998 /* Code to actually dissect the packets */
999 static int
1000 dissect_steam_ihs_discovery(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1001 void *data _U_)
1003 /* Set up structures needed to add the protocol subtree and manage it */
1004 proto_item *ti;
1005 proto_tree *steam_ihs_discovery_tree;
1006 /* Other misc. local variables. */
1007 int offset = 0;
1008 int header_length = 0;
1009 int body_length = 0;
1010 int total_length = 0;
1011 int64_t msg_type;
1013 /* Check that the packet is long enough for it to belong to us. */
1014 if (tvb_reported_length(tvb) < STEAM_IHS_DISCOVERY_MIN_LENGTH)
1015 return 0;
1017 if (tvb_captured_length(tvb) < STEAM_IHS_DISCOVERY_MIN_LENGTH)
1018 return 0;
1020 /* Check if packet starts with the 8 byte signature value. */
1021 if (tvb_get_ntoh64(tvb, 0) != STEAM_IHS_DISCOVERY_SIGNATURE_VALUE)
1022 return 0;
1024 /* Parse header and body lengths.
1026 * A packet looks like this:
1027 * 1. Signature Value (8 bytes)
1028 * 2. Header length (4 bytes)
1029 * 3. Header
1030 * 4. Body length (4 bytes)
1031 * 6. Body
1032 * */
1033 header_length = tvb_get_letohl(tvb, STEAM_IHS_DISCOVERY_SIGNATURE_LENGTH);
1034 body_length = tvb_get_letohl(tvb, STEAM_IHS_DISCOVERY_SIGNATURE_LENGTH + 4 + header_length);
1035 total_length = STEAM_IHS_DISCOVERY_SIGNATURE_LENGTH + 4 + header_length + 4 + body_length;
1037 /* Check if expected and captured packet length are equal. */
1038 if (tvb_reported_length(tvb) != (unsigned)total_length)
1039 return 0;
1041 if (tvb_captured_length(tvb) != (unsigned)total_length)
1042 return 0;
1044 /* Set the Protocol column to the constant string of steam_ihs_discovery */
1045 col_set_str(pinfo->cinfo, COL_PROTOCOL, "STEAMDISCOVER");
1047 col_clear(pinfo->cinfo, COL_INFO);
1049 /* create display subtree for the protocol */
1050 ti = proto_tree_add_item(tree, proto_steam_ihs_discovery, tvb, 0, -1, ENC_NA);
1052 steam_ihs_discovery_tree = proto_item_add_subtree(ti, ett_steam_ihs_discovery);
1054 proto_tree_add_item(steam_ihs_discovery_tree, hf_steam_ihs_discovery_signature, tvb,
1055 offset, STEAM_IHS_DISCOVERY_SIGNATURE_LENGTH, ENC_LITTLE_ENDIAN);
1056 offset += STEAM_IHS_DISCOVERY_SIGNATURE_LENGTH;
1058 proto_tree_add_item(steam_ihs_discovery_tree, hf_steam_ihs_discovery_header_length, tvb,
1059 offset, 4, ENC_LITTLE_ENDIAN);
1060 offset += 4;
1062 msg_type = steamdiscover_dissect_header(tvb, pinfo, steam_ihs_discovery_tree, offset, header_length);
1064 if ((0 <= msg_type) && (msg_type <= STEAMDISCOVER_MSGTYPES_MAX)) {
1065 col_set_str(pinfo->cinfo, COL_INFO, hf_steam_ihs_discovery_header_msgtype_strings[msg_type].strptr);
1066 } else {
1067 col_set_str(pinfo->cinfo, COL_INFO, "Unknown Message");
1070 offset += header_length;
1072 proto_tree_add_item(steam_ihs_discovery_tree, hf_steam_ihs_discovery_body_length, tvb,
1073 offset, 4, ENC_LITTLE_ENDIAN);
1074 offset += 4;
1076 switch(msg_type)
1078 case STEAMDISCOVER_MSGTYPE_CLIENTBROADCASTMSGDISCOVERY:
1079 steamdiscover_dissect_body_discovery(tvb, pinfo, steam_ihs_discovery_tree, offset, body_length);
1080 break;
1081 case STEAMDISCOVER_MSGTYPE_CLIENTBROADCASTMSGSTATUS:
1082 steamdiscover_dissect_body_status(tvb, pinfo, steam_ihs_discovery_tree, offset, body_length);
1083 break;
1084 case STEAMDISCOVER_MSGTYPE_CLIENTBROADCASTMSGOFFLINE:
1085 /* Message seems to have no body */
1086 break;
1087 case STEAMDISCOVER_MSGTYPE_DEVICEAUTHORIZATIONREQUEST:
1088 steamdiscover_dissect_body_authrequest(tvb, pinfo, steam_ihs_discovery_tree, offset, body_length);
1089 break;
1090 case STEAMDISCOVER_MSGTYPE_DEVICEAUTHORIZATIONCANCELREQUEST:
1091 /* Message seems to have no body */
1092 break;
1093 case STEAMDISCOVER_MSGTYPE_DEVICEAUTHORIZATIONRESPONSE:
1094 steamdiscover_dissect_body_authresponse(tvb, pinfo, steam_ihs_discovery_tree, offset, body_length);
1095 break;
1096 case STEAMDISCOVER_MSGTYPE_DEVICESTREAMINGREQUEST:
1097 steamdiscover_dissect_body_streamingrequest(tvb, pinfo, steam_ihs_discovery_tree, offset, body_length);
1098 break;
1099 case STEAMDISCOVER_MSGTYPE_DEVICESTREAMINGCANCELREQUEST:
1100 steamdiscover_dissect_body_streamingcancelrequest(tvb, pinfo, steam_ihs_discovery_tree, offset, body_length);
1101 break;
1102 case STEAMDISCOVER_MSGTYPE_DEVICESTREAMINGRESPONSE:
1103 steamdiscover_dissect_body_streamingresponse(tvb, pinfo, steam_ihs_discovery_tree, offset, body_length);
1104 break;
1105 case STEAMDISCOVER_MSGTYPE_DEVICEPROOFREQUEST:
1106 steamdiscover_dissect_body_proofrequest(tvb, pinfo, steam_ihs_discovery_tree, offset, body_length);
1107 break;
1108 case STEAMDISCOVER_MSGTYPE_DEVICEPROOFRESPONSE:
1109 steamdiscover_dissect_body_proofresponse(tvb, pinfo, steam_ihs_discovery_tree, offset, body_length);
1110 break;
1111 default:
1112 steamdiscover_dissect_body_unknown(tvb, pinfo, steam_ihs_discovery_tree, offset, body_length);
1113 break;
1116 return tvb_captured_length(tvb);
1119 /* Register the protocol with Wireshark. */
1120 void
1121 proto_register_steam_ihs_discovery(void)
1123 expert_module_t *expert_steam_ihs_discovery;
1125 static hf_register_info hf[] = {
1126 /* Non-protobuf header fields */
1127 { &hf_steam_ihs_discovery_signature,
1128 { "Signature", "steam_ihs_discovery.signature",
1129 FT_UINT64, BASE_HEX, NULL, 0,
1130 "Every packet of the Steam In-Home Streaming Discovery Protocol begins with this signature.", HFILL }
1132 { &hf_steam_ihs_discovery_header_length,
1133 { "Header Length", "steam_ihs_discovery.header_length",
1134 FT_UINT32, BASE_DEC, NULL, 0,
1135 NULL, HFILL }
1137 { &hf_steam_ihs_discovery_body_length,
1138 { "Body Length", "steam_ihs_discovery.body_length",
1139 FT_UINT32, BASE_DEC, NULL, 0,
1140 NULL, HFILL }
1142 { &hf_steam_ihs_discovery_unknown_data,
1143 { "Unknown Data", "steam_ihs_discovery.unknown_data",
1144 FT_BYTES, BASE_NONE, NULL, 0,
1145 NULL, HFILL }
1147 { &hf_steam_ihs_discovery_unknown_number,
1148 { "Unknown Number", "steam_ihs_discovery.unknown_number",
1149 FT_UINT64, BASE_DEC_HEX, NULL, 0,
1150 NULL, HFILL }
1152 /* CMsgRemoteClientBroadcastHeader */
1153 { &hf_steam_ihs_discovery_header_clientid,
1154 { "Client ID", "steam_ihs_discovery.header_client_id",
1155 FT_UINT64, BASE_DEC_HEX, NULL, 0,
1156 NULL, HFILL }
1158 { &hf_steam_ihs_discovery_header_msgtype,
1159 { "Message Type", "steam_ihs_discovery.header_msg_type",
1160 FT_UINT64, BASE_DEC|BASE_VAL64_STRING, VALS64(hf_steam_ihs_discovery_header_msgtype_strings), 0,
1161 NULL, HFILL }
1163 { &hf_steam_ihs_discovery_header_instanceid,
1164 { "Instance ID", "steam_ihs_discovery.header_instance_id",
1165 FT_UINT64, BASE_DEC_HEX, NULL, 0,
1166 NULL, HFILL }
1168 /* CMsgRemoteClientBroadcastDiscovery message */
1169 { &hf_steam_ihs_discovery_body_discovery_seqnum,
1170 { "Sequence Number", "steam_ihs_discovery.body_discovery_seqnum",
1171 FT_UINT32, BASE_DEC, NULL, 0,
1172 NULL, HFILL }
1174 { &hf_steam_ihs_discovery_body_discovery_clientids,
1175 { "Client IDs", "steam_ihs_discovery.body_discovery_clientids",
1176 FT_UINT64, BASE_HEX, NULL, 0,
1177 NULL, HFILL }
1179 /* CMsgRemoteClientBroadcastStatus message */
1180 { &hf_steam_ihs_discovery_body_status_version,
1181 { "Version", "steam_ihs_discovery.body_status_version",
1182 FT_INT32, BASE_DEC, NULL, 0,
1183 NULL, HFILL }
1185 { &hf_steam_ihs_discovery_body_status_minversion,
1186 { "Minimum Version", "steam_ihs_discovery.body_status_minversion",
1187 FT_INT32, BASE_DEC, NULL, 0,
1188 NULL, HFILL }
1190 { &hf_steam_ihs_discovery_body_status_connectport,
1191 { "Connect Port", "steam_ihs_discovery.body_status_connectport",
1192 FT_UINT32, BASE_DEC, NULL, 0,
1193 NULL, HFILL }
1195 { &hf_steam_ihs_discovery_body_status_hostname,
1196 { "Hostname", "steam_ihs_discovery.body_status_hostname",
1197 FT_STRING, BASE_NONE, NULL, 0,
1198 NULL, HFILL }
1200 { &hf_steam_ihs_discovery_body_status_enabledservices,
1201 { "Enabled Services", "steam_ihs_discovery.body_status_enabledservices",
1202 FT_UINT32, BASE_HEX, NULL, 0,
1203 NULL, HFILL }
1205 { &hf_steam_ihs_discovery_body_status_ostype,
1206 { "OS Type", "steam_ihs_discovery.body_status_ostype",
1207 FT_INT32, BASE_DEC, NULL, 0,
1208 NULL, HFILL }
1210 { &hf_steam_ihs_discovery_body_status_is64bit,
1211 { "Is 64 Bit", "steam_ihs_discovery.body_status_is64bit",
1212 FT_BOOLEAN, BASE_NONE, NULL, 0,
1213 NULL, HFILL }
1215 { &hf_steam_ihs_discovery_body_status_euniverse,
1216 { "EUniverse", "steam_ihs_discovery.body_status_euniverse",
1217 FT_INT32, BASE_DEC, NULL, 0,
1218 NULL, HFILL }
1220 { &hf_steam_ihs_discovery_body_status_timestamp,
1221 { "Timestamp", "steam_ihs_discovery.body_status_timestamp",
1222 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0,
1223 NULL, HFILL }
1225 { &hf_steam_ihs_discovery_body_status_screenlocked,
1226 { "Screen Locked", "steam_ihs_discovery.body_status_screenlocked",
1227 FT_BOOLEAN, BASE_NONE, NULL, 0,
1228 NULL, HFILL }
1230 { &hf_steam_ihs_discovery_body_status_gamesrunning,
1231 { "Games Running", "steam_ihs_discovery.body_status_gamesrunning",
1232 FT_BOOLEAN, BASE_NONE, NULL, 0,
1233 NULL, HFILL }
1235 { &hf_steam_ihs_discovery_body_status_macaddresses,
1236 { "MAC Addresses", "steam_ihs_discovery.body_status_macaddresses",
1237 FT_STRING, BASE_NONE, NULL, 0,
1238 NULL, HFILL }
1240 /* CMsgRemoteClientBroadcastStatus.User */
1241 { &hf_steam_ihs_discovery_body_status_user_steamid,
1242 { "Steam ID", "steam_ihs_discovery.body_status_user_steamid",
1243 FT_UINT64, BASE_DEC, NULL, 0,
1244 NULL, HFILL }
1246 { &hf_steam_ihs_discovery_body_status_user_authkeyid,
1247 { "Auth Key ID", "steam_ihs_discovery.body_status_user_authkeyid",
1248 FT_UINT32, BASE_DEC, NULL, 0,
1249 NULL, HFILL }
1251 /* CMsgRemoteDeviceAuthorizationRequest */
1252 { &hf_steam_ihs_discovery_body_authrequest_devicetoken,
1253 { "Device Token", "steam_ihs_discovery.body_authrequest_devicetoken",
1254 FT_BYTES, BASE_NONE, NULL, 0,
1255 NULL, HFILL }
1257 { &hf_steam_ihs_discovery_body_authrequest_devicename,
1258 { "Device Name", "steam_ihs_discovery.body_authrequest_devicename",
1259 FT_STRING, BASE_NONE, NULL, 0,
1260 NULL, HFILL }
1262 { &hf_steam_ihs_discovery_body_authrequest_encryptedrequest,
1263 { "Encrypted Request", "steam_ihs_discovery.body_authrequest_encryptedrequest",
1264 FT_BYTES, BASE_NO_DISPLAY_VALUE, NULL, 0,
1265 NULL, HFILL }
1267 /* CMsgRemoteDeviceAuthorizationResponse */
1268 { &hf_steam_ihs_discovery_body_authresponse_authresult,
1269 { "Result", "steam_ihs_discovery.body_authresponse_authresult",
1270 FT_UINT64, BASE_DEC|BASE_VAL64_STRING, VALS64(hf_steam_ihs_discovery_body_authresponse_authresult_strings), 0,
1271 NULL, HFILL }
1273 /* CMsgRemoteDeviceStreamingRequest */
1274 { &hf_steam_ihs_discovery_body_streamingrequest_requestid,
1275 { "Request ID", "steam_ihs_discovery.body_streamingrequest_requestid",
1276 FT_UINT32, BASE_HEX, NULL, 0,
1277 NULL, HFILL }
1279 { &hf_steam_ihs_discovery_body_streamingrequest_maximumresolutionx,
1280 { "Maximum Resolution X", "steam_ihs_discovery.body_streamingrequest_maximumresolutionx",
1281 FT_INT32, BASE_DEC, NULL, 0,
1282 NULL, HFILL }
1284 { &hf_steam_ihs_discovery_body_streamingrequest_maximumresolutiony,
1285 { "Maximum Resolution Y", "steam_ihs_discovery.body_streamingrequest_maximumresolutiony",
1286 FT_INT32, BASE_DEC, NULL, 0,
1287 NULL, HFILL }
1289 { &hf_steam_ihs_discovery_body_streamingrequest_audiochannelcount,
1290 { "Audio Channel Count", "steam_ihs_discovery.body_streamingrequest_audiochannelcount",
1291 FT_INT32, BASE_DEC, NULL, 0,
1292 NULL, HFILL }
1294 { &hf_steam_ihs_discovery_body_streamingrequest_deviceversion,
1295 { "Device Version", "steam_ihs_discovery.body_streamingrequest_deviceversion",
1296 FT_STRING, BASE_NONE, NULL, 0,
1297 NULL, HFILL }
1299 { &hf_steam_ihs_discovery_body_streamingrequest_streamdesktop,
1300 { "Stream Desktop", "steam_ihs_discovery.body_streamingrequest_streamdesktop",
1301 FT_BOOLEAN, BASE_NONE, NULL, 0,
1302 NULL, HFILL }
1304 { &hf_steam_ihs_discovery_body_streamingrequest_devicetoken,
1305 { "Device Token", "steam_ihs_discovery.body_streamingrequest_devicetoken",
1306 FT_BYTES, BASE_NONE, NULL, 0,
1307 NULL, HFILL }
1309 { &hf_steam_ihs_discovery_body_streamingrequest_pin,
1310 { "PIN", "steam_ihs_discovery.body_streamingrequest_pin",
1311 FT_BYTES, BASE_NONE, NULL, 0,
1312 NULL, HFILL }
1314 { &hf_steam_ihs_discovery_body_streamingrequest_enablevideostreaming,
1315 { "Enable Video Streaming", "steam_ihs_discovery.body_streamingrequest_enablevideostreaming",
1316 FT_BOOLEAN, BASE_NONE, NULL, 0,
1317 NULL, HFILL }
1319 { &hf_steam_ihs_discovery_body_streamingrequest_enableaudiostreaming,
1320 { "Enable Audio Streaming", "steam_ihs_discovery.body_streamingrequest_enableaudiostreaming",
1321 FT_BOOLEAN, BASE_NONE, NULL, 0,
1322 NULL, HFILL }
1324 { &hf_steam_ihs_discovery_body_streamingrequest_enableinputstreaming,
1325 { "Enable Input Streaming", "steam_ihs_discovery.body_streamingrequest_enableinputstreaming",
1326 FT_BOOLEAN, BASE_NONE, NULL, 0,
1327 NULL, HFILL }
1329 /* CMsgRemoteDeviceStreamingCancelRequest */
1330 { &hf_steam_ihs_discovery_body_streamingcancelrequest_requestid,
1331 { "Request ID", "steam_ihs_discovery.body_streamingcancelrequest_requestid",
1332 FT_UINT32, BASE_HEX, NULL, 0,
1333 NULL, HFILL }
1335 /* CMsgRemoteDeviceStreamingResponse */
1336 { &hf_steam_ihs_discovery_body_streamingresponse_requestid,
1337 { "Request ID", "steam_ihs_discovery.body_streamingresponse_requestid",
1338 FT_UINT32, BASE_HEX, NULL, 0,
1339 NULL, HFILL }
1341 { &hf_steam_ihs_discovery_body_streamingresponse_result,
1342 { "Result", "steam_ihs_discovery.body_streamingresponse_result",
1343 FT_UINT64, BASE_DEC|BASE_VAL64_STRING, VALS64(hf_steam_ihs_discovery_body_streamingresponse_result_strings), 0,
1344 NULL, HFILL }
1346 { &hf_steam_ihs_discovery_body_streamingresponse_port,
1347 { "Port", "steam_ihs_discovery.body_streamingresponse_port",
1348 FT_UINT32, BASE_DEC, NULL, 0,
1349 NULL, HFILL }
1351 { &hf_steam_ihs_discovery_body_streamingresponse_encryptedsessionkey,
1352 { "Encrypted Session Key", "steam_ihs_discovery.body_streamingresponse_encryptedsessionkey",
1353 FT_BYTES, BASE_NONE, NULL, 0,
1354 NULL, HFILL }
1356 { &hf_steam_ihs_discovery_body_streamingresponse_virtualherelicenseddevicecount,
1357 { "VirtualHere Licensed Device Count", "steam_ihs_discovery.body_streamingresponse_virtualherelicenseddevicecount",
1358 FT_INT32, BASE_DEC, NULL, 0,
1359 NULL, HFILL }
1361 /* CMsgRemoteDeviceProofRequest */
1362 { &hf_steam_ihs_discovery_body_proofrequest_challenge,
1363 { "Challenge", "steam_ihs_discovery.body_proofrequest_challenge",
1364 FT_BYTES, BASE_NONE, NULL, 0,
1365 NULL, HFILL }
1367 /* CMsgRemoteDeviceProofResponse */
1368 { &hf_steam_ihs_discovery_body_proofresponse_response,
1369 { "Response", "steam_ihs_discovery.body_proofresponse_response",
1370 FT_BYTES, BASE_NONE, NULL, 0,
1371 NULL, HFILL }
1375 /* Setup protocol subtree array */
1376 static int *ett[] = {
1377 &ett_steam_ihs_discovery,
1378 &ett_steam_ihs_discovery_body_status_user
1381 /* Setup protocol expert items */
1382 static ei_register_info ei[] = {
1383 { &ei_steam_ihs_discovery_unknown_data,
1384 { "steam_ihs_discovery.unknowndata", PI_UNDECODED, PI_WARN,
1385 "Unknown data section", EXPFILL }
1387 { &ei_steam_ihs_discovery_unknown_number,
1388 { "steam_ihs_discovery.unknownnumber", PI_UNDECODED, PI_WARN,
1389 "Unknown numeric protobuf field", EXPFILL }
1391 { &ei_steam_ihs_discovery_unknown_lengthdelimited,
1392 { "steam_ihs_discovery.unknownlengthdelimited", PI_UNDECODED, PI_WARN,
1393 "Unknown length-delimited protobuf field", EXPFILL }
1395 { &ei_steam_ihs_discovery_invalid_wiretype,
1396 { "steam_ihs_discovery.invalid_wiretype", PI_MALFORMED, PI_ERROR,
1397 "Unexpected wire type", EXPFILL }
1399 { &ei_steam_ihs_discovery_invalid_length,
1400 { "steam_ihs_discovery.invalid_length", PI_MALFORMED, PI_ERROR,
1401 "Length-delimited field has invalid length", EXPFILL }
1405 /* Register the protocol name and description */
1406 proto_steam_ihs_discovery = proto_register_protocol("Steam In-Home Streaming Discovery Protocol",
1407 "Steam IHS Discovery", "steam_ihs_discovery");
1409 /* Register the dissector handle */
1410 steam_ihs_discovery_handle = register_dissector("steam_ihs_discovery", dissect_steam_ihs_discovery, proto_steam_ihs_discovery);
1412 /* Required function calls to register the header fields and subtrees */
1413 proto_register_field_array(proto_steam_ihs_discovery, hf, array_length(hf));
1414 proto_register_subtree_array(ett, array_length(ett));
1416 /* Required function calls to register expert items */
1417 expert_steam_ihs_discovery = expert_register_protocol(proto_steam_ihs_discovery);
1418 expert_register_field_array(expert_steam_ihs_discovery, ei, array_length(ei));
1420 /* Register a preferences module - handled by Decode As. */
1421 /* steam_ihs_discovery_module = prefs_register_protocol(proto_steam_ihs_discovery, NULL); */
1424 void
1425 proto_reg_handoff_steam_ihs_discovery(void)
1427 dissector_add_uint_with_preference("udp.port", STEAM_IHS_DISCOVERY_UDP_PORT, steam_ihs_discovery_handle);
1431 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1433 * Local variables:
1434 * c-basic-offset: 4
1435 * tab-width: 8
1436 * indent-tabs-mode: nil
1437 * End:
1439 * vi: set shiftwidth=4 tabstop=8 expandtab:
1440 * :indentSize=4:tabSize=8:noTabs=true: