epan/dissectors/pidl/ C99 drsuapi
[wireshark-sm.git] / epan / dissectors / packet-ms-mms.c
blobfd9a5b6ec5f31dbe35964baa7669519b440255a6
1 /* packet-ms-mms.c
3 * Routines for MicroSoft MMS (Microsoft Media Server) message dissection
5 * See
7 * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-mmsp
9 * for the [MS-MMSP] specification.
11 * Copyright 2005
12 * Written by Martin Mathieson
14 * Wireshark - Network traffic analyzer
15 * By Gerald Combs <gerald@wireshark.org>
16 * Copyright 1998 Gerald Combs
18 * SPDX-License-Identifier: GPL-2.0-or-later
21 /* Information sources:
22 * sdp.ppona.com
25 #include "config.h"
27 #include <stdio.h> /* for sscanf() */
29 #include <epan/packet.h>
30 #include <epan/conversation.h>
31 #include <epan/strutil.h>
33 static dissector_handle_t msmms_handle;
34 static int proto_msmms;
37 /* Command fields */
38 static int hf_msmms_command;
39 static int hf_msmms_command_common_header;
40 /* static int hf_msmms_command_version; */
41 static int hf_msmms_command_signature;
42 static int hf_msmms_command_length;
43 static int hf_msmms_command_protocol_type;
44 static int hf_msmms_command_length_remaining;
45 static int hf_msmms_command_sequence_number;
46 static int hf_msmms_command_timestamp;
47 static int hf_msmms_command_length_remaining2;
48 static int hf_msmms_command_to_client_id;
49 static int hf_msmms_command_to_server_id;
50 static int hf_msmms_command_direction;
52 static int hf_msmms_command_prefix1;
53 static int hf_msmms_command_prefix1_error;
54 static int hf_msmms_command_prefix1_command_level;
55 static int hf_msmms_command_prefix2;
57 static int hf_msmms_command_client_transport_info;
58 static int hf_msmms_command_client_player_info;
60 static int hf_msmms_command_server_version;
61 static int hf_msmms_command_tool_version;
62 static int hf_msmms_command_update_url;
63 static int hf_msmms_command_password_type;
65 static int hf_msmms_command_server_version_length;
66 static int hf_msmms_command_tool_version_length;
67 static int hf_msmms_command_update_url_length;
68 static int hf_msmms_command_password_type_length;
70 static int hf_msmms_command_number_of_words;
71 static int hf_msmms_command_client_id;
72 static int hf_msmms_command_server_file;
74 static int hf_msmms_command_result_flags;
76 static int hf_msmms_command_broadcast_indexing;
77 static int hf_msmms_command_broadcast_liveness;
79 static int hf_msmms_command_recorded_media_length;
80 static int hf_msmms_command_media_packet_length;
82 static int hf_msmms_command_strange_string;
84 static int hf_msmms_command_stream_structure_count;
85 static int hf_msmms_stream_selection_flags;
86 static int hf_msmms_stream_selection_stream_id;
87 static int hf_msmms_stream_selection_action;
89 static int hf_msmms_command_header_packet_id_type;
92 /* Data fields */
93 static int hf_msmms_data;
94 static int hf_msmms_data_sequence_number;
95 static int hf_msmms_data_packet_id_type;
96 static int hf_msmms_data_udp_sequence;
97 static int hf_msmms_data_tcp_flags;
98 static int hf_msmms_data_packet_length;
100 static int hf_msmms_data_header_id;
101 static int hf_msmms_data_client_id;
102 static int hf_msmms_data_command_id;
103 static int hf_msmms_data_packet_to_resend;
105 static int hf_msmms_data_timing_pair;
106 static int hf_msmms_data_timing_pair_seqno;
107 static int hf_msmms_data_timing_pair_flags;
108 static int hf_msmms_data_timing_pair_id;
109 static int hf_msmms_data_timing_pair_flag;
110 static int hf_msmms_data_timing_pair_packet_length;
112 static int hf_msmms_data_unparsed;
115 /* Subtrees */
116 static int ett_msmms_command;
117 static int ett_msmms_command_common_header;
118 static int ett_msmms_data;
119 static int ett_msmms_data_timing_packet_pair;
121 #define MSMMS_PORT 1755
124 /* Known command IDs */
125 #define SERVER_COMMAND_CONNECT_INFO 0x01
126 #define SERVER_COMMAND_TRANSPORT_INFO 0x02
127 #define SERVER_COMMAND_PROTOCOL_SELECTION_ERROR 0x03
128 #define SERVER_COMMAND_REQUEST_SERVER_FILE 0x05
129 #define SERVER_COMMAND_START_SENDING_FROM 0x07
130 #define SERVER_COMMAND_STOP_BUTTON_PRESSED 0x09
131 #define SERVER_COMMAND_CANCEL_PROTOCOL 0x0d
132 #define SERVER_COMMAND_HEADER_REQUEST 0x15
133 #define SERVER_COMMAND_TIMING_TEST_DATA_REQUEST 0x18
134 #define SERVER_COMMAND_AUTHENTICATION_RESPONSE 0x1a
135 #define SERVER_COMMAND_NETWORK_TIMER_TEST_RESPONSE 0x1b
136 #define SERVER_COMMAND_ACTIVATE_FF_RW_BUTTONS 0x28
137 #define SERVER_COMMAND_HAVE_STOPPED_PLAYING 0x30
138 #define SERVER_COMMAND_LOCAL_COMPUTER_DETAILS 0x32
139 #define SERVER_COMMAND_MEDIA_STREAM_MBR_SELECTOR 0x33
141 static const value_string to_server_command_vals[] =
143 { SERVER_COMMAND_CONNECT_INFO, "Connect info" },
144 { SERVER_COMMAND_TRANSPORT_INFO, "Transport info" },
145 { SERVER_COMMAND_PROTOCOL_SELECTION_ERROR, "Protocol selection error" },
146 { SERVER_COMMAND_REQUEST_SERVER_FILE, "Request server file" },
147 { SERVER_COMMAND_START_SENDING_FROM, "Start sending from:" },
148 { SERVER_COMMAND_STOP_BUTTON_PRESSED, "Stop button pressed" },
149 { SERVER_COMMAND_CANCEL_PROTOCOL, "Cancel protocol" },
150 { SERVER_COMMAND_HEADER_REQUEST, "Header request" },
151 { SERVER_COMMAND_TIMING_TEST_DATA_REQUEST, "Timing test data request" },
152 { SERVER_COMMAND_AUTHENTICATION_RESPONSE, "Authentication response" },
153 { SERVER_COMMAND_NETWORK_TIMER_TEST_RESPONSE, "Network timer test response" },
154 { SERVER_COMMAND_ACTIVATE_FF_RW_BUTTONS, "Activate FF/Rewind buttons" },
155 { SERVER_COMMAND_HAVE_STOPPED_PLAYING, "Have stopped playing" },
156 { SERVER_COMMAND_LOCAL_COMPUTER_DETAILS, "Local computer details" },
157 { SERVER_COMMAND_MEDIA_STREAM_MBR_SELECTOR, "Media Stream MBR selector" },
158 { 0, NULL }
162 #define CLIENT_COMMAND_SERVER_INFO 0x01
163 #define CLIENT_COMMAND_TRANSPORT_INFO_ACK 0x02
164 #define CLIENT_COMMAND_PROTOCOL_SELECTION_ERROR 0x03
165 #define CLIENT_COMMAND_SENDING_MEDIA_FILE_NOW 0x05
166 #define CLIENT_COMMAND_MEDIA_DETAILS 0x06
167 #define CLIENT_COMMAND_FF_RW 0x0a
168 #define CLIENT_COMMAND_SENDING_HEADER_RESPONSE 0x11
169 #define CLIENT_COMMAND_TIMING_TEST_DATA_RESPONSE 0x15
170 #define CLIENT_COMMAND_TIMING_TEST_DATA_REQUEST 0x18
171 #define CLIENT_COMMAND_AUTHENTICATION_CHALLENGE 0x1a
172 #define CLIENT_COMMAND_NETWORK_TIMER_TEST 0x1b
173 #define CLIENT_COMMAND_END_OF_MEDIA_STREAM 0x1e
174 #define CLIENT_COMMAND_MEDIA_CHANGING_INDICATOR 0x20
175 #define CLIENT_COMMAND_STREAM_SELECTION_INDICATOR 0x21
177 static const value_string to_client_command_vals[] =
179 { CLIENT_COMMAND_SERVER_INFO, "Server info" },
180 { CLIENT_COMMAND_TRANSPORT_INFO_ACK, "Transport info ack" },
181 { CLIENT_COMMAND_PROTOCOL_SELECTION_ERROR, "Protocol selection error" },
182 { CLIENT_COMMAND_SENDING_MEDIA_FILE_NOW, "Sending media file now" },
183 { CLIENT_COMMAND_MEDIA_DETAILS, "Media details" },
184 { CLIENT_COMMAND_FF_RW, "FF/Rewind" },
185 { CLIENT_COMMAND_SENDING_HEADER_RESPONSE, "Sending header response" },
186 { CLIENT_COMMAND_TIMING_TEST_DATA_RESPONSE, "Timing test data response" },
187 { CLIENT_COMMAND_TIMING_TEST_DATA_REQUEST, "Timing test data request" },
188 { CLIENT_COMMAND_AUTHENTICATION_CHALLENGE, "Authentication challenge" },
189 { CLIENT_COMMAND_NETWORK_TIMER_TEST, "Network timer test" },
190 { CLIENT_COMMAND_END_OF_MEDIA_STREAM, "End of media stream" },
191 { CLIENT_COMMAND_MEDIA_CHANGING_INDICATOR, "Media changing indicator" },
192 { CLIENT_COMMAND_STREAM_SELECTION_INDICATOR, "Stream selection indicator" },
193 { 0, NULL }
196 /* Command direction */
198 #define TO_SERVER 0x0003
199 #define TO_CLIENT 0x0004
201 static const value_string command_direction_vals[] =
203 { TO_SERVER, "To Server"},
204 { TO_CLIENT, "To Client"},
205 { 0, NULL }
208 static const value_string tcp_flags_vals[] =
210 { 0x00, "Middle of packet series" },
211 { 0x04, "First packet of a packet series" },
212 { 0x08, "Last packet of a packet series" },
213 { 0x0C, "There is only one packet in this series" },
214 { 0x10, "UDP packet pair timing packet" },
215 { 0, NULL }
218 static const value_string media_result_flags_vals[] =
220 { 0x01, "Media file name was accepted (no auth)"},
221 { 0x02, "Authentication for this media was accepted (BASIC auth)"},
222 { 0x03, "Authentication accepted (NTLM auth)"},
223 { 0, NULL }
226 static const value_string broadcast_indexing_vals[] =
228 { 0x00, "No indexed seeking (live or no video streams)"},
229 { 0x80, "Indexed seeking (video streams available)"},
230 { 0, NULL }
233 static const value_string broadcast_liveness_vals[] =
235 { 0x01, "Pre-recorded broadcast"},
236 { 0x02, "Live broadcast"},
237 { 0x42, "Presentation which includes a script command"},
238 { 0, NULL }
241 static const value_string stream_selection_action_vals[] =
243 { 0x00, "Stream at full frame rate"},
244 { 0x01, "Only stream key frames"},
245 { 0x02, "No stream, switch it off"},
246 { 0, NULL }
250 /* Server to client error codes */
251 static const value_string server_to_client_error_vals[] =
253 { 0x00000000, "OK"},
254 { 0xC00D001A, "File was not found"},
255 { 0xC00D000E, "The network is busy"},
256 { 0xC00D000F, "Too many connection sessions to server exist, cannot connect"},
257 { 0xC00D0029, "The network has failed - connection was lost"},
258 { 0xC00D0034, "There is no more data in the stream (UDP)"},
259 { 0x80070005, "You do not have access to the location or file"},
260 { 0xC00D0013, "There was no timely response from the server"},
261 { 0x80070057, "A parameter in the location is incorrect"},
262 { 0x8000FFFF, "File failed to open"},
263 { 0, NULL }
269 /*************************/
270 /* Function declarations */
271 void proto_register_msmms(void);
272 void proto_reg_handoff_msmms_command(void);
274 static int dissect_msmms_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
275 static int dissect_msmms_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
276 static int dissect_msmms_data_udp_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
278 static void dissect_client_transport_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
279 unsigned offset, unsigned length_remaining);
280 static void dissect_server_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
281 unsigned offset);
282 static void dissect_client_player_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
283 unsigned offset, unsigned length_remaining);
284 static void dissect_start_sending_from_info(tvbuff_t *tvb, proto_tree *tree, unsigned offset);
285 static void dissect_cancel_info(tvbuff_t *tvb, proto_tree *tree, unsigned offset);
286 static void dissect_timing_test_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset);
287 static void dissect_timing_test_response(tvbuff_t *tvb, proto_tree *tree, unsigned offset);
288 static void dissect_request_server_file(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
289 unsigned offset, unsigned length_remaining);
290 static void dissect_media_details(tvbuff_t *tvb, proto_tree *tree, unsigned offset);
291 static void dissect_header_response(tvbuff_t *tvb, proto_tree *tree, unsigned offset);
292 static void dissect_network_timer_test_response(tvbuff_t *tvb, proto_tree *tree, unsigned offset);
293 static void dissect_transport_info_response(tvbuff_t *tvb, proto_tree *tree, unsigned offset,
294 unsigned length_remaining);
295 static void dissect_media_stream_mbr_selector(tvbuff_t *tvb, proto_tree *tree, unsigned offset);
296 static void dissect_header_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset);
297 static void dissect_stop_button_pressed(tvbuff_t *tvb, proto_tree *tree, unsigned offset);
299 static void msmms_data_add_address(packet_info *pinfo, address *addr, conversation_type ckt, int port);
303 /****************************/
304 /* Main dissection function */
305 /****************************/
306 static int dissect_msmms_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
308 /* Work out what type of packet this is and dissect it as such */
310 /* Just don't dissect if can't even read command signature */
311 if (tvb_captured_length(tvb) < 8) {
312 return 0;
315 /* Command */
316 if (tvb_get_letohl(tvb, 4) == 0xb00bface)
318 return dissect_msmms_command(tvb, pinfo, tree);
320 else
321 /* UDP data command */
322 if ((pinfo->ptype == PT_UDP) && (pinfo->destport == MSMMS_PORT))
324 return dissect_msmms_data_udp_command(tvb, pinfo, tree);
326 else
327 /* Assume data (don't consider frames from client->server data...) */
328 if (pinfo->destport != MSMMS_PORT)
330 return dissect_msmms_data(tvb, pinfo, tree);
333 /* It was none of the above so assume not really an MMS packet */
334 return 0;
338 /*************************************/
339 /* Dissection of different PDU types */
340 /*************************************/
342 /* Dissect command packet */
343 static int dissect_msmms_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
345 int offset = 0;
346 proto_item *ti;
347 proto_tree *msmms_tree;
348 proto_tree *msmms_common_command_tree;
349 uint32_t sequence_number;
350 uint16_t command_id;
351 uint16_t command_dir;
352 int32_t length_of_command;
353 uint32_t length_remaining;
355 /******************************/
356 /* Check for available length */
358 /* Need to have enough bytes for length field */
359 if (tvb_reported_length_remaining(tvb, offset) < 12)
361 pinfo->desegment_offset = 0; /* Start at beginning next time */
362 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; /* Need one more byte to try again */
363 return -1;
366 /* Read length field and see if we're short */
367 length_of_command = tvb_get_letohl(tvb, offset+8);
368 if (tvb_reported_length_remaining(tvb, 16) < length_of_command)
370 pinfo->desegment_offset = 0; /* Start at beginning next time */
371 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; /* Need one more byte to try again */
372 return -1;
376 /* Set columns */
377 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MSMMS");
378 col_set_str(pinfo->cinfo, COL_INFO, "Command: ");
380 /* Add hidden filter for "msmms.command" */
381 ti = proto_tree_add_item(tree, hf_msmms_command, tvb, 0, 0, ENC_ASCII);
382 proto_item_set_hidden(ti);
384 /* Create MSMMS control protocol tree */
385 ti = proto_tree_add_item(tree, proto_msmms, tvb, offset, -1, ENC_NA);
386 msmms_tree = proto_item_add_subtree(ti, ett_msmms_command);
389 /* Read command ID and direction now so can give common command header a
390 descriptive label */
391 command_id = tvb_get_letohs(tvb, 36);
392 command_dir = tvb_get_letohs(tvb, 36+2);
395 /*************************/
396 /* Common command header */
398 /* Add a tree for common header */
399 ti = proto_tree_add_string_format(msmms_tree, hf_msmms_command_common_header, tvb, offset, -1,
401 "%s (to %s)",
402 (command_dir == TO_SERVER) ?
403 val_to_str_const(command_id, to_server_command_vals, "Unknown") :
404 val_to_str_const(command_id, to_client_command_vals, "Unknown"),
405 (command_dir == TO_SERVER) ? "server" : "client");
406 msmms_common_command_tree = proto_item_add_subtree(ti, ett_msmms_command_common_header);
408 /* Format of 1st 4 bytes unknown. May be version... */
409 offset += 4;
411 /* Signature (already verified by main dissection function) */
412 proto_tree_add_item(msmms_common_command_tree, hf_msmms_command_signature, tvb, offset, 4, ENC_LITTLE_ENDIAN);
413 offset += 4;
415 /* Length of command */
416 proto_tree_add_item(msmms_common_command_tree, hf_msmms_command_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
417 offset += 4;
419 /* Protocol name. Must be "MMS"... */
420 if (strncmp((char*)tvb_get_string_enc(pinfo->pool, tvb, offset, 3, ENC_ASCII), "MMS", 3) != 0)
422 return offset;
424 proto_tree_add_item(msmms_common_command_tree, hf_msmms_command_protocol_type, tvb, offset, 4, ENC_ASCII);
425 offset += 4;
427 /* Remaining length in multiples of 8 bytes */
428 proto_tree_add_item(msmms_common_command_tree, hf_msmms_command_length_remaining, tvb, offset, 4, ENC_LITTLE_ENDIAN);
429 offset += 4;
431 /* Sequence number */
432 sequence_number = tvb_get_letohl(tvb, offset);
433 proto_tree_add_item(msmms_common_command_tree, hf_msmms_command_sequence_number, tvb, offset, 4, ENC_LITTLE_ENDIAN);
434 offset += 4;
436 /* Timestamp */
437 proto_tree_add_item(msmms_common_command_tree, hf_msmms_command_timestamp, tvb, offset, 8, ENC_LITTLE_ENDIAN);
438 offset += 8;
440 /* Another length remaining field... */
441 length_remaining = tvb_get_letohl(tvb, offset);
442 proto_tree_add_item(msmms_common_command_tree, hf_msmms_command_length_remaining2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
443 offset += 4;
445 /* Command depends up on direction */
446 proto_tree_add_item(msmms_common_command_tree,
447 (command_dir == TO_SERVER) ?
448 hf_msmms_command_to_server_id :
449 hf_msmms_command_to_client_id,
450 tvb, offset, 2, ENC_LITTLE_ENDIAN);
451 offset += 2;
453 /* Direction */
454 proto_tree_add_item(msmms_common_command_tree, hf_msmms_command_direction, tvb, offset, 2, ENC_LITTLE_ENDIAN);
455 offset += 2;
457 /* This is the end of the common command header */
458 proto_item_set_len(msmms_common_command_tree, offset);
461 /* Show summary in info column */
462 col_append_fstr(pinfo->cinfo, COL_INFO,
463 "seq=%03u: %s %s",
464 sequence_number,
465 (command_dir == TO_SERVER) ? "-->" : "<--",
466 (command_dir == TO_SERVER) ?
467 val_to_str_const(command_id, to_server_command_vals, "Unknown") :
468 val_to_str_const(command_id, to_client_command_vals, "Unknown"));
470 /* Adjust length_remaining for command-specific details */
471 length_remaining = (length_remaining*8) - 8;
473 /* Now parse any command-specific params */
474 if (command_dir == TO_SERVER)
476 /* Commands to server */
477 switch (command_id)
479 case SERVER_COMMAND_TRANSPORT_INFO:
480 dissect_client_transport_info(tvb, pinfo, msmms_tree,
481 offset, length_remaining);
482 break;
483 case SERVER_COMMAND_CONNECT_INFO:
484 dissect_client_player_info(tvb, pinfo, msmms_tree,
485 offset, length_remaining);
486 break;
487 case SERVER_COMMAND_START_SENDING_FROM:
488 dissect_start_sending_from_info(tvb, msmms_tree, offset);
489 break;
490 case SERVER_COMMAND_CANCEL_PROTOCOL:
491 dissect_cancel_info(tvb, msmms_tree, offset);
492 break;
493 case SERVER_COMMAND_TIMING_TEST_DATA_REQUEST:
494 dissect_timing_test_request(tvb, tree, offset);
495 break;
496 case SERVER_COMMAND_REQUEST_SERVER_FILE:
497 dissect_request_server_file(tvb, pinfo, tree, offset, length_remaining);
498 break;
499 case SERVER_COMMAND_NETWORK_TIMER_TEST_RESPONSE:
500 dissect_network_timer_test_response(tvb, tree, offset);
501 break;
502 case SERVER_COMMAND_MEDIA_STREAM_MBR_SELECTOR:
503 dissect_media_stream_mbr_selector(tvb, tree, offset);
504 break;
505 case SERVER_COMMAND_HEADER_REQUEST:
506 dissect_header_request(tvb, tree, offset);
507 break;
508 case SERVER_COMMAND_STOP_BUTTON_PRESSED:
509 dissect_stop_button_pressed(tvb, tree, offset);
510 break;
512 /* TODO: other commands */
514 default:
515 break;
518 else
520 /* Commands to client */
521 switch (command_id)
523 case CLIENT_COMMAND_SERVER_INFO:
524 dissect_server_info(tvb, pinfo, msmms_tree, offset);
525 break;
526 case CLIENT_COMMAND_TIMING_TEST_DATA_RESPONSE:
527 dissect_timing_test_response(tvb, tree, offset);
528 break;
529 case CLIENT_COMMAND_MEDIA_DETAILS:
530 dissect_media_details(tvb, tree, offset);
531 break;
532 case CLIENT_COMMAND_SENDING_HEADER_RESPONSE:
533 dissect_header_response(tvb, tree, offset);
534 break;
535 case CLIENT_COMMAND_TRANSPORT_INFO_ACK:
536 dissect_transport_info_response(tvb, tree, offset, length_remaining);
537 break;
539 /* TODO: other commands: */
540 default:
541 break;
545 /* Got to the end so assume it belongs to this protocol */
546 return length_of_command + 12;
550 /* Parse the only known UDP command (0x01) */
551 static int dissect_msmms_data_udp_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
553 proto_item *ti;
554 proto_tree *msmms_tree;
555 int offset = 0;
557 /* Set protocol column */
558 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MSMMS");
560 /* Create MSMMS data protocol tree */
561 ti = proto_tree_add_item(tree, proto_msmms, tvb, offset, -1, ENC_NA);
562 msmms_tree = proto_item_add_subtree(ti, ett_msmms_data);
564 /* Header ID */
565 proto_tree_add_item(msmms_tree, hf_msmms_data_header_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
566 offset += 4;
568 /* Client ID */
569 proto_tree_add_item(msmms_tree, hf_msmms_data_client_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
570 offset += 4;
572 /* Command ID */
573 proto_tree_add_item(msmms_tree, hf_msmms_data_command_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
574 offset += 4;
576 col_set_str(pinfo->cinfo, COL_INFO, "Request to resend packet(s):");
578 /* Show list of packets to resend */
579 while (tvb_reported_length_remaining(tvb, offset) >= 4)
581 uint32_t packet_number = tvb_get_letohl(tvb, offset);
582 proto_tree_add_item(msmms_tree, hf_msmms_data_packet_to_resend, tvb, offset, 4, ENC_LITTLE_ENDIAN);
583 offset += 4;
585 col_append_fstr(pinfo->cinfo, COL_INFO, " %u", packet_number);
588 /* Report that whole of UDP packet was dissected */
589 return tvb_reported_length_remaining(tvb, 0);
593 /* Dissect a data packet */
594 static int dissect_msmms_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
596 int offset = 0;
597 proto_item *ti;
598 proto_tree *msmms_tree;
599 proto_tree *msmms_data_timing_pair_tree = NULL;
600 uint32_t sequence_number;
601 uint16_t packet_length;
602 uint16_t packet_length_found;
603 uint8_t value = 0;
605 /* How many bytes do we need? */
606 packet_length = tvb_get_letohs(tvb, 6);
608 /* How many bytes have we got? */
609 packet_length_found = tvb_reported_length_remaining(tvb, 0);
611 /* Reject frame reported not to reach length field */
612 if (packet_length < 8)
614 return 0;
617 /* Stop and ask for more bytes if necessary */
618 if (packet_length_found < packet_length)
620 pinfo->desegment_offset = 0; /* Start from beginning again next time */
621 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; /* Try again with even one more byte */
622 return -1;
626 /* Will reject packet if is TCP and has invalid flag */
627 if (pinfo->ptype == PT_TCP)
629 /* Flag value is in 5th byte */
630 value = tvb_get_uint8(tvb, 5);
631 /* Reject packet if not a recognised packet type */
632 if (try_val_to_str(value, tcp_flags_vals) == NULL)
634 return 0;
638 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MSMMS");
640 /* Add hidden filter for "msmms.data" */
641 ti = proto_tree_add_item(tree, hf_msmms_data, tvb, 0, 0, ENC_NA);
642 proto_item_set_hidden(ti);
644 /* Create MSMMS data protocol tree */
645 ti = proto_tree_add_item(tree, proto_msmms, tvb, offset, -1, ENC_NA);
646 msmms_tree = proto_item_add_subtree(ti, ett_msmms_data);
648 /* Sequence number */
649 sequence_number = tvb_get_letohl(tvb, offset);
650 proto_tree_add_item(msmms_tree, hf_msmms_data_sequence_number, tvb, offset, 4, ENC_LITTLE_ENDIAN);
651 offset += 4;
653 /* Packet ID type */
654 proto_tree_add_item(msmms_tree, hf_msmms_data_packet_id_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
655 offset++;
657 /* Next byte depends upon whether UDP or TCP */
658 if (pinfo->ptype == PT_UDP)
660 /* UDP */
661 proto_tree_add_item(msmms_tree, hf_msmms_data_udp_sequence, tvb,
662 offset, 1, ENC_LITTLE_ENDIAN);
664 else
666 /* TCP */
667 proto_tree_add_item(msmms_tree, hf_msmms_data_tcp_flags, tvb,
668 offset, 1, ENC_LITTLE_ENDIAN);
670 offset++;
672 /* Packet Length */
673 packet_length = tvb_get_letohs(tvb, offset);
674 proto_tree_add_item(msmms_tree, hf_msmms_data_packet_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
675 offset += 2;
677 /* Parse UDP Timing packet pair headers if present */
678 if (value == 0x01)
680 /* Create subtree */
681 ti = proto_tree_add_string_format(msmms_tree, hf_msmms_data_timing_pair, tvb, offset, 8, "", "Data timing pair");
682 msmms_data_timing_pair_tree = proto_item_add_subtree(ti, ett_msmms_data_timing_packet_pair);
684 proto_tree_add_item(msmms_data_timing_pair_tree, hf_msmms_data_timing_pair_seqno, tvb, offset, 1, ENC_LITTLE_ENDIAN);
685 offset++;
686 proto_tree_add_item(msmms_data_timing_pair_tree, hf_msmms_data_timing_pair_flags, tvb, offset, 3, ENC_LITTLE_ENDIAN);
687 offset += 3;
688 proto_tree_add_item(msmms_data_timing_pair_tree, hf_msmms_data_timing_pair_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
689 offset++;
690 proto_tree_add_item(msmms_data_timing_pair_tree, hf_msmms_data_timing_pair_flag, tvb, offset, 1, ENC_LITTLE_ENDIAN);
691 offset++;
692 proto_tree_add_item(msmms_data_timing_pair_tree, hf_msmms_data_timing_pair_packet_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
693 offset += 2;
696 /* Everything else is marked as unparsed data */
697 proto_tree_add_item(msmms_tree, hf_msmms_data_unparsed, tvb, offset, packet_length-offset, ENC_NA);
698 offset = packet_length;
700 /* Show summary in info column */
701 col_add_fstr(pinfo->cinfo, COL_INFO, "Data: seq=%05u, len=%05u",
702 sequence_number, packet_length);
704 /* Whole of packet length has been dissected now */
705 return offset;
710 /***************************************/
711 /* Dissect command-specific parameters */
712 /***************************************/
714 /* Transport information (address, port, etc) */
715 static void dissect_client_transport_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
716 unsigned offset, unsigned length_remaining)
718 char *transport_info;
719 unsigned ipaddr[4];
720 char protocol[3+1] = "";
721 unsigned port;
722 int fields_matched;
724 /* Flags */
725 proto_tree_add_item(tree, hf_msmms_command_prefix1, tvb, offset, 4, ENC_LITTLE_ENDIAN);
726 offset += 4;
727 proto_tree_add_item(tree, hf_msmms_command_prefix2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
728 offset += 4;
730 /* These 12 bytes are not understood */
731 offset += 4;
732 offset += 4;
733 offset += 4;
735 /* Extract and show the string in tree and info column */
736 transport_info = tvb_get_string_enc(pinfo->pool, tvb, offset, length_remaining - 20, ENC_UTF_16|ENC_LITTLE_ENDIAN);
738 proto_tree_add_string_format(tree, hf_msmms_command_client_transport_info, tvb,
739 offset, length_remaining-20,
740 transport_info, "Transport: (%s)", transport_info);
742 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
743 format_text_string(pinfo->pool, (const unsigned char*)transport_info));
746 /* Try to extract details from this string */
747 fields_matched = sscanf(transport_info, "%*c%*c%u.%u.%u.%u%*c%3s%*c%u",
748 &ipaddr[0], &ipaddr[1], &ipaddr[2], &ipaddr[3],
749 protocol, &port);
751 /* Use this information to set up a conversation for the data stream */
752 if (fields_matched == 6)
754 conversation_type ckt = CONVERSATION_NONE;
756 /* Work out the port type */
757 if (strncmp(protocol, "UDP", 3) == 0)
759 ckt = CONVERSATION_UDP;
761 else
762 if (strncmp(protocol, "TCP", 3) == 0)
764 ckt = CONVERSATION_TCP;
767 /* Set the dissector for indicated conversation */
768 if (ckt != CONVERSATION_NONE)
770 uint8_t octets[4];
771 address addr;
772 octets[0] = ipaddr[0];
773 octets[1] = ipaddr[1];
774 octets[2] = ipaddr[2];
775 octets[3] = ipaddr[3];
776 addr.type = AT_IPv4;
777 addr.len = 4;
778 addr.data = octets;
779 msmms_data_add_address(pinfo, &addr, ckt, port);
784 /* Dissect server data */
785 static void dissect_server_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
786 unsigned offset)
788 uint32_t server_version_length;
789 uint32_t tool_version_length;
790 uint32_t download_update_player_length;
791 uint32_t password_encryption_type_length;
792 const uint8_t *server_version;
794 /* ErrorCode */
795 proto_tree_add_item(tree, hf_msmms_command_prefix1_error, tvb, offset, 4, ENC_LITTLE_ENDIAN);
796 offset += 4;
797 proto_tree_add_item(tree, hf_msmms_command_prefix2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
798 offset += 4;
800 /* Next 8 words are not understood */
801 offset += 4;
802 offset += 4;
803 offset += 4;
804 offset += 4;
805 offset += 4;
806 offset += 4;
807 offset += 4;
808 offset += 4;
811 /* Length of server version */
812 server_version_length = tvb_get_letohl(tvb, offset);
813 proto_tree_add_item(tree, hf_msmms_command_server_version_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
814 offset += 4;
816 /* Length of tool version */
817 tool_version_length = tvb_get_letohl(tvb, offset);
818 proto_tree_add_item(tree, hf_msmms_command_tool_version_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
819 offset += 4;
821 /* Length of download update player URL */
822 download_update_player_length = tvb_get_letohl(tvb, offset);
823 proto_tree_add_item(tree, hf_msmms_command_update_url_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
824 offset += 4;
826 /* Length of password encryption type */
827 password_encryption_type_length = tvb_get_letohl(tvb, offset);
828 proto_tree_add_item(tree, hf_msmms_command_password_type_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
829 offset += 4;
831 /* Server version string. */
832 if (server_version_length > 1)
834 /* Server version string */
835 proto_tree_add_item_ret_string(tree, hf_msmms_command_server_version, tvb,
836 offset, server_version_length*2,
837 ENC_UTF_16|ENC_LITTLE_ENDIAN, pinfo->pool, &server_version);
839 col_append_fstr(pinfo->cinfo, COL_INFO, " (version='%s')",
840 format_text_string(pinfo->pool, (const unsigned char*)server_version));
842 offset += (server_version_length*2);
845 /* Tool version string. */
846 if (tool_version_length > 1)
848 proto_tree_add_item(tree, hf_msmms_command_tool_version, tvb,
849 offset, tool_version_length*2,
850 ENC_UTF_16|ENC_LITTLE_ENDIAN);
852 offset += (tool_version_length*2);
854 /* Download update player url string. */
855 if (download_update_player_length > 1)
857 proto_tree_add_item(tree, hf_msmms_command_update_url, tvb,
858 offset, download_update_player_length*2,
859 ENC_UTF_16|ENC_LITTLE_ENDIAN);
861 offset += (download_update_player_length*2);
863 /* Password encryption type string. */
864 if (password_encryption_type_length > 1)
866 proto_tree_add_item(tree, hf_msmms_command_password_type, tvb,
867 offset, password_encryption_type_length*2,
868 ENC_UTF_16|ENC_LITTLE_ENDIAN);
870 /* offset += (password_encryption_type_length*2); */
873 /* Player (client) information */
874 static void dissect_client_player_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
875 unsigned offset, unsigned length_remaining)
877 const uint8_t *player_info;
879 /* Flags */
880 proto_tree_add_item(tree, hf_msmms_command_prefix1, tvb, offset, 4, ENC_LITTLE_ENDIAN);
881 offset += 4;
882 proto_tree_add_item(tree, hf_msmms_command_prefix2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
883 offset += 4;
885 /* These 4 bytes are not understood */
886 offset += 4;
888 /* Extract and show the string in tree and info column */
889 proto_tree_add_item_ret_string(tree, hf_msmms_command_client_player_info, tvb,
890 offset, length_remaining-12,
891 ENC_UTF_16|ENC_LITTLE_ENDIAN, pinfo->pool, &player_info);
893 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
894 format_text_string(pinfo->pool, (const unsigned char*)player_info));
897 /* Dissect info about where client wants to start playing from */
898 static void dissect_start_sending_from_info(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
900 /* Command Level */
901 proto_tree_add_item(tree, hf_msmms_command_prefix1_command_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
902 offset += 4;
903 proto_tree_add_item(tree, hf_msmms_command_prefix2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
905 /* 40 bytes follow the prefixes... */
908 /* Dissect cancel parameters */
909 static void dissect_cancel_info(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
911 /* Command Level */
912 proto_tree_add_item(tree, hf_msmms_command_prefix1_command_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
913 offset += 4;
914 proto_tree_add_item(tree, hf_msmms_command_prefix2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
917 /* Dissect timing test data request */
918 static void dissect_timing_test_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
920 /* Flags */
921 proto_tree_add_item(tree, hf_msmms_command_prefix1, tvb, offset, 4, ENC_LITTLE_ENDIAN);
922 offset += 4;
923 proto_tree_add_item(tree, hf_msmms_command_prefix2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
926 /* Dissect timing test data response */
927 static void dissect_timing_test_response(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
929 /* ErrorCode */
930 proto_tree_add_item(tree, hf_msmms_command_prefix1_error, tvb, offset, 4, ENC_LITTLE_ENDIAN);
931 offset += 4;
932 /* Flags */
933 proto_tree_add_item(tree, hf_msmms_command_prefix2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
934 offset += 4;
936 /* Number of 4 byte fields in structure */
937 proto_tree_add_item(tree, hf_msmms_command_number_of_words, tvb, offset, 4, ENC_LITTLE_ENDIAN);
938 offset += 4;
939 offset += 4;
940 offset += 4;
942 /* Client ID */
943 proto_tree_add_item(tree, hf_msmms_command_client_id, tvb, offset, 4, ENC_LITTLE_ENDIAN);
945 /* 20 more bytes... */
948 /* Dissect request for server file */
949 static void dissect_request_server_file(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
950 unsigned offset, unsigned length_remaining)
952 const uint8_t *server_file;
954 /* Command Level */
955 proto_tree_add_item(tree, hf_msmms_command_prefix1_command_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
956 offset += 4;
957 proto_tree_add_item(tree, hf_msmms_command_prefix2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
958 offset += 4;
960 offset += 4;
961 offset += 4;
963 /* File path on server */
964 proto_tree_add_item_ret_string(tree, hf_msmms_command_server_file, tvb,
965 offset, length_remaining-16,
966 ENC_UTF_16|ENC_LITTLE_ENDIAN, pinfo->pool, &server_file);
968 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
969 format_text_string(pinfo->pool, (const unsigned char*)server_file));
972 /* Dissect media details from server */
973 static void dissect_media_details(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
975 /* ErrorCode */
976 proto_tree_add_item(tree, hf_msmms_command_prefix1_error, tvb, offset, 4, ENC_LITTLE_ENDIAN);
977 offset += 4;
978 proto_tree_add_item(tree, hf_msmms_command_prefix2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
979 offset += 4;
981 /* Result flags */
982 proto_tree_add_item(tree, hf_msmms_command_result_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN);
983 offset += 4;
985 offset += 4;
986 offset += 4;
988 /* Broadcast flags. */
989 proto_tree_add_item(tree, hf_msmms_command_broadcast_indexing, tvb, offset+2, 1, ENC_LITTLE_ENDIAN);
990 proto_tree_add_item(tree, hf_msmms_command_broadcast_liveness, tvb, offset+3, 1, ENC_LITTLE_ENDIAN);
991 offset += 4;
993 /* These 8 bytes may be a time field... */
994 offset += 4;
995 offset += 4;
997 /* Media length in seconds */
998 proto_tree_add_item(tree, hf_msmms_command_recorded_media_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
999 offset += 4;
1001 offset += 4;
1002 offset += 4;
1003 offset += 4;
1004 offset += 4;
1006 /* Packet length in bytes */
1007 proto_tree_add_item(tree, hf_msmms_command_media_packet_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1010 /* Dissect header response */
1011 static void dissect_header_response(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
1013 /* ErrorCode */
1014 proto_tree_add_item(tree, hf_msmms_command_prefix1_error, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1015 offset += 4;
1016 /* Packet ID type */
1017 proto_tree_add_item(tree, hf_msmms_command_prefix2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1019 /* 8 more bytes */
1022 /* Dissect network timer test response */
1023 static void dissect_network_timer_test_response(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
1025 /* Command Level */
1026 proto_tree_add_item(tree, hf_msmms_command_prefix1_command_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1027 offset += 4;
1028 proto_tree_add_item(tree, hf_msmms_command_prefix2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1031 /* Dissect transport info response */
1032 static void dissect_transport_info_response(tvbuff_t *tvb, proto_tree *tree,
1033 unsigned offset, unsigned length_remaining)
1035 /* Command Level */
1036 proto_tree_add_item(tree, hf_msmms_command_prefix1_command_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1037 offset += 4;
1038 proto_tree_add_item(tree, hf_msmms_command_prefix2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1039 offset += 4;
1041 /* Length */
1042 proto_tree_add_item(tree, hf_msmms_command_number_of_words, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1043 offset += 4;
1045 /* Read this strange string */
1046 proto_tree_add_item(tree, hf_msmms_command_strange_string, tvb,
1047 offset, length_remaining-12,
1048 ENC_UTF_16|ENC_LITTLE_ENDIAN);
1051 /* Media stream MBR selector */
1052 static void dissect_media_stream_mbr_selector(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
1054 /* Stream structure count (always 1) */
1055 proto_tree_add_item(tree, hf_msmms_command_stream_structure_count, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1056 offset += 4;
1058 /* Stream selection structure */
1059 proto_tree_add_item(tree, hf_msmms_stream_selection_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1060 offset += 2;
1061 proto_tree_add_item(tree, hf_msmms_stream_selection_stream_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1062 offset += 2;
1063 proto_tree_add_item(tree, hf_msmms_stream_selection_action, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1066 /* Dissect header request */
1067 static void dissect_header_request(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
1069 int n;
1071 /* Command Level */
1072 proto_tree_add_item(tree, hf_msmms_command_prefix1_command_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1073 offset += 4;
1074 proto_tree_add_item(tree, hf_msmms_command_prefix2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1075 offset += 4;
1077 /* Skip 8 unknown words */
1078 for (n=0; n < 8; n++)
1080 offset += 4;
1083 /* Header packet ID type */
1084 proto_tree_add_item(tree, hf_msmms_command_header_packet_id_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1087 /* Dissect stop button pressed */
1088 static void dissect_stop_button_pressed(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
1090 /* Command Level */
1091 proto_tree_add_item(tree, hf_msmms_command_prefix1_command_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1092 offset += 4;
1093 proto_tree_add_item(tree, hf_msmms_command_prefix2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1097 /********************************************************/
1098 /* Helper function to set up an MS-MMS data conversation */
1099 /********************************************************/
1100 static void msmms_data_add_address(packet_info *pinfo, address *addr, conversation_type ckt, int port)
1102 address null_addr;
1103 conversation_t *p_conv;
1105 /* If this isn't the first time this packet has been processed,
1106 * we've already done this work, so we don't need to do it
1107 * again. */
1108 if (pinfo->fd->visited)
1110 return;
1113 clear_address(&null_addr);
1115 /* Check if the ip address and port combination is not
1116 * already registered as a conversation. */
1117 p_conv = find_conversation(pinfo->num, addr, &null_addr, ckt, port, 0,
1118 NO_ADDR_B | NO_PORT_B);
1120 /* If not, create a new conversation. */
1121 if (!p_conv)
1123 p_conv = conversation_new(pinfo->num, addr, &null_addr, ckt,
1124 (uint32_t)port, 0, NO_ADDR2 | NO_PORT2);
1127 /* Set dissector */
1128 conversation_set_dissector(p_conv, msmms_handle);
1133 /*************************/
1134 /* Register protocol */
1135 /*************************/
1137 void proto_register_msmms(void)
1139 static hf_register_info hf[] =
1142 /* Command fields */
1144 &hf_msmms_command,
1146 "Command",
1147 "msmms.command",
1148 FT_STRING,
1149 BASE_NONE,
1150 NULL,
1151 0x0,
1152 "MSMMS command hidden filter", HFILL
1156 &hf_msmms_command_common_header,
1158 "Command common header",
1159 "msmms.command.common-header",
1160 FT_STRING,
1161 BASE_NONE,
1162 NULL,
1163 0x0,
1164 "MSMMS command common header", HFILL
1168 #if 0
1170 &hf_msmms_command_version,
1172 "Version",
1173 "msmms.command.version",
1174 FT_UINT32,
1175 BASE_DEC,
1176 NULL,
1177 0x0,
1178 NULL, HFILL
1181 #endif
1183 &hf_msmms_command_signature,
1185 "Command signature",
1186 "msmms.command.signature",
1187 FT_UINT32,
1188 BASE_HEX,
1189 NULL,
1190 0x0,
1191 NULL, HFILL
1195 &hf_msmms_command_length,
1197 "Command length",
1198 "msmms.command.length",
1199 FT_UINT32,
1200 BASE_DEC,
1201 NULL,
1202 0x0,
1203 NULL, HFILL
1207 &hf_msmms_command_protocol_type,
1209 "Protocol type",
1210 "msmms.command.protocol-type",
1211 FT_STRING,
1212 BASE_NONE,
1213 NULL,
1214 0x0,
1215 NULL, HFILL
1219 &hf_msmms_command_length_remaining,
1221 "Length until end (8-byte blocks)",
1222 "msmms.command.length-remaining",
1223 FT_UINT32,
1224 BASE_DEC,
1225 NULL,
1226 0x0,
1227 NULL, HFILL
1231 &hf_msmms_command_sequence_number,
1233 "Sequence number",
1234 "msmms.command.sequence-number",
1235 FT_UINT32,
1236 BASE_DEC,
1237 NULL,
1238 0x0,
1239 NULL, HFILL
1243 &hf_msmms_command_timestamp,
1245 "Time stamp (s)",
1246 "msmms.command.timestamp",
1247 FT_DOUBLE,
1248 BASE_NONE,
1249 NULL,
1250 0x0,
1251 NULL, HFILL
1255 &hf_msmms_command_length_remaining2,
1257 "Length until end (8-byte blocks)",
1258 "msmms.command.length-remaining2",
1259 FT_UINT32,
1260 BASE_DEC,
1261 NULL,
1262 0x0,
1263 NULL, HFILL
1267 &hf_msmms_command_to_server_id,
1269 "Command",
1270 "msmms.command.to-server-id",
1271 FT_UINT16,
1272 BASE_HEX,
1273 VALS(to_server_command_vals),
1274 0x0,
1275 NULL, HFILL
1279 &hf_msmms_command_to_client_id,
1281 "Command",
1282 "msmms.command.to-client-id",
1283 FT_UINT16,
1284 BASE_HEX,
1285 VALS(to_client_command_vals),
1286 0x0,
1287 NULL, HFILL
1291 &hf_msmms_command_direction,
1293 "Command direction",
1294 "msmms.command.direction",
1295 FT_UINT16,
1296 BASE_HEX,
1297 VALS(command_direction_vals),
1298 0x0,
1299 NULL, HFILL
1304 &hf_msmms_command_prefix1,
1306 "Prefix 1",
1307 "msmms.command.prefix1",
1308 FT_UINT32,
1309 BASE_HEX,
1310 NULL,
1311 0x0,
1312 NULL, HFILL
1316 &hf_msmms_command_prefix1_error,
1318 "Prefix 1 ErrorCode",
1319 "msmms.command.prefix1-error-code",
1320 FT_UINT32,
1321 BASE_HEX,
1322 VALS(server_to_client_error_vals),
1323 0x0,
1324 NULL, HFILL
1328 &hf_msmms_command_prefix1_command_level,
1330 "Prefix 1 Command Level",
1331 "msmms.command.prefix1-command-level",
1332 FT_UINT32,
1333 BASE_DEC,
1334 NULL,
1335 0x0,
1336 NULL, HFILL
1340 &hf_msmms_command_prefix2,
1342 "Prefix 2",
1343 "msmms.command.prefix2",
1344 FT_UINT32,
1345 BASE_HEX,
1346 NULL,
1347 0x0,
1348 NULL, HFILL
1352 &hf_msmms_command_client_transport_info,
1354 "Client transport info",
1355 "msmms.command.client-transport-info",
1356 FT_STRING,
1357 BASE_NONE,
1358 NULL,
1359 0x0,
1360 NULL, HFILL
1364 &hf_msmms_command_client_player_info,
1366 "Player info",
1367 "msmms.command.player-info",
1368 FT_STRING,
1369 BASE_NONE,
1370 NULL,
1371 0x0,
1372 NULL, HFILL
1376 &hf_msmms_command_server_version_length,
1378 "Server Version Length",
1379 "msmms.command.server-version-length",
1380 FT_UINT32,
1381 BASE_DEC,
1382 NULL,
1383 0x0,
1384 NULL, HFILL
1388 &hf_msmms_command_tool_version_length,
1390 "Tool Version Length",
1391 "msmms.command.tool-version-length",
1392 FT_UINT32,
1393 BASE_DEC,
1394 NULL,
1395 0x0,
1396 NULL, HFILL
1400 &hf_msmms_command_update_url_length,
1402 "Download update URL length",
1403 "msmms.command.download-update-player-url-length",
1404 FT_UINT32,
1405 BASE_DEC,
1406 NULL,
1407 0x0,
1408 NULL, HFILL
1412 &hf_msmms_command_password_type_length,
1414 "Password encryption type length",
1415 "msmms.command.password-encryption-type-length",
1416 FT_UINT32,
1417 BASE_DEC,
1418 NULL,
1419 0x0,
1420 NULL, HFILL
1424 &hf_msmms_command_server_version,
1426 "Server version",
1427 "msmms.command.server-version",
1428 FT_STRING,
1429 BASE_NONE,
1430 NULL,
1431 0x0,
1432 NULL, HFILL
1436 &hf_msmms_command_tool_version,
1438 "Tool version",
1439 "msmms.command.tool-version",
1440 FT_STRING,
1441 BASE_NONE,
1442 NULL,
1443 0x0,
1444 NULL, HFILL
1448 &hf_msmms_command_update_url,
1450 "Download update player URL",
1451 "msmms.command.download-update-player-url",
1452 FT_STRING,
1453 BASE_NONE,
1454 NULL,
1455 0x0,
1456 NULL, HFILL
1460 &hf_msmms_command_password_type,
1462 "Password encryption type",
1463 "msmms.command.password-encryption-type",
1464 FT_STRING,
1465 BASE_NONE,
1466 NULL,
1467 0x0,
1468 NULL, HFILL
1472 &hf_msmms_command_number_of_words,
1474 "Number of 4 byte fields in structure",
1475 "msmms.data.words-in-structure",
1476 FT_UINT32,
1477 BASE_DEC,
1478 NULL,
1479 0x0,
1480 NULL, HFILL
1484 &hf_msmms_command_client_id,
1486 "Client ID",
1487 "msmms.data.client-id",
1488 FT_UINT32,
1489 BASE_DEC,
1490 NULL,
1491 0x0,
1492 NULL, HFILL
1496 &hf_msmms_command_server_file,
1498 "Server file",
1499 "msmms.command.server-file",
1500 FT_STRING,
1501 BASE_NONE,
1502 NULL,
1503 0x0,
1504 NULL, HFILL
1508 &hf_msmms_command_result_flags,
1510 "Result flags",
1511 "msmms.command.result-flags",
1512 FT_UINT32,
1513 BASE_HEX,
1514 VALS(media_result_flags_vals),
1515 0x0,
1516 NULL, HFILL
1520 &hf_msmms_command_broadcast_indexing,
1522 "Broadcast indexing",
1523 "msmms.command.broadcast-indexing",
1524 FT_UINT8,
1525 BASE_HEX,
1526 VALS(broadcast_indexing_vals),
1527 0x0,
1528 NULL, HFILL
1532 &hf_msmms_command_broadcast_liveness,
1534 "Broadcast liveness",
1535 "msmms.command.broadcast-liveness",
1536 FT_UINT8,
1537 BASE_HEX,
1538 VALS(broadcast_liveness_vals),
1539 0x0,
1540 NULL, HFILL
1544 &hf_msmms_command_recorded_media_length,
1546 "Pre-recorded media length (seconds)",
1547 "msmms.data.prerecorded-media-length",
1548 FT_UINT32,
1549 BASE_DEC,
1550 NULL,
1551 0x0,
1552 NULL, HFILL
1556 &hf_msmms_command_media_packet_length,
1558 "Media packet length (bytes)",
1559 "msmms.data.media-packet-length",
1560 FT_UINT32,
1561 BASE_DEC,
1562 NULL,
1563 0x0,
1564 NULL, HFILL
1568 &hf_msmms_command_strange_string,
1570 "Strange string",
1571 "msmms.command.strange-string",
1572 FT_STRING,
1573 BASE_NONE,
1574 NULL,
1575 0x0,
1576 NULL, HFILL
1580 &hf_msmms_command_stream_structure_count,
1582 "Stream structure count",
1583 "msmms.data.stream-structure-count",
1584 FT_UINT32,
1585 BASE_DEC,
1586 NULL,
1587 0x0,
1588 NULL, HFILL
1592 &hf_msmms_stream_selection_flags,
1594 "Stream selection flags",
1595 "msmms.data.stream-selection-flags",
1596 FT_UINT16,
1597 BASE_HEX,
1598 NULL,
1599 0x0,
1600 NULL, HFILL
1604 &hf_msmms_stream_selection_stream_id,
1606 "Stream id",
1607 "msmms.data.selection-stream-id",
1608 FT_UINT16,
1609 BASE_DEC,
1610 NULL,
1611 0x0,
1612 NULL, HFILL
1616 &hf_msmms_stream_selection_action,
1618 "Action",
1619 "msmms.data.selection-stream-action",
1620 FT_UINT16,
1621 BASE_DEC,
1622 VALS(stream_selection_action_vals),
1623 0x0,
1624 NULL, HFILL
1628 &hf_msmms_command_header_packet_id_type,
1630 "Header packet ID type",
1631 "msmms.data.header-packet-id-type",
1632 FT_UINT32,
1633 BASE_HEX,
1634 NULL,
1635 0x0,
1636 NULL, HFILL
1641 /* Data fields */
1643 &hf_msmms_data,
1645 "Data",
1646 "msmms.data",
1647 FT_NONE,
1648 BASE_NONE,
1649 NULL,
1650 0x0,
1651 NULL, HFILL
1655 &hf_msmms_data_sequence_number,
1657 "Sequence number",
1658 "msmms.data.sequence",
1659 FT_UINT32,
1660 BASE_DEC,
1661 NULL,
1662 0x0,
1663 NULL, HFILL
1667 &hf_msmms_data_packet_id_type,
1669 "Packet ID type",
1670 "msmms.data.packet-id-type",
1671 FT_UINT8,
1672 BASE_HEX,
1673 NULL,
1674 0x0,
1675 NULL, HFILL
1679 &hf_msmms_data_packet_length,
1681 "Packet length",
1682 "msmms.data.packet-length",
1683 FT_UINT16,
1684 BASE_DEC,
1685 NULL,
1686 0x0,
1687 NULL, HFILL
1692 &hf_msmms_data_header_id,
1694 "Header ID",
1695 "msmms.data.header-id",
1696 FT_UINT32,
1697 BASE_HEX,
1698 NULL,
1699 0x0,
1700 NULL, HFILL
1704 &hf_msmms_data_client_id,
1706 "Client ID",
1707 "msmms.data.client-id",
1708 FT_UINT32,
1709 BASE_HEX,
1710 NULL,
1711 0x0,
1712 NULL, HFILL
1716 &hf_msmms_data_command_id,
1718 "Command ID",
1719 "msmms.data.command-id",
1720 FT_UINT16,
1721 BASE_DEC,
1722 NULL,
1723 0x0,
1724 NULL, HFILL
1728 &hf_msmms_data_packet_to_resend,
1730 "Packet to resend",
1731 "msmms.data.packet-to-resend",
1732 FT_UINT32,
1733 BASE_DEC,
1734 NULL,
1735 0x0,
1736 NULL, HFILL
1740 &hf_msmms_data_udp_sequence,
1742 "UDP Sequence",
1743 "msmms.data.udp-sequence",
1744 FT_UINT8,
1745 BASE_DEC,
1746 NULL,
1747 0x0,
1748 NULL, HFILL
1752 &hf_msmms_data_tcp_flags,
1754 "TCP flags",
1755 "msmms.data.tcp-flags",
1756 FT_UINT8,
1757 BASE_HEX,
1758 VALS(tcp_flags_vals),
1759 0x0,
1760 NULL, HFILL
1765 &hf_msmms_data_timing_pair,
1767 "Data timing pair",
1768 "msmms.data.timing-pair",
1769 FT_STRING,
1770 BASE_NONE,
1771 NULL,
1772 0x0,
1773 NULL, HFILL
1777 &hf_msmms_data_timing_pair_seqno,
1779 "Sequence number",
1780 "msmms.data.timing-pair.sequence-number",
1781 FT_UINT8,
1782 BASE_DEC,
1783 NULL,
1784 0x0,
1785 NULL, HFILL
1789 &hf_msmms_data_timing_pair_flags,
1791 "Flags",
1792 "msmms.data.timing-pair.flags",
1793 FT_UINT24,
1794 BASE_DEC,
1795 NULL,
1796 0x0,
1797 NULL, HFILL
1801 &hf_msmms_data_timing_pair_id,
1803 "ID",
1804 "msmms.data.timing-pair.id",
1805 FT_UINT8,
1806 BASE_HEX,
1807 NULL,
1808 0x0,
1809 NULL, HFILL
1813 &hf_msmms_data_timing_pair_flag,
1815 "Flag",
1816 "msmms.data.timing-pair.flag",
1817 FT_UINT8,
1818 BASE_HEX,
1819 NULL,
1820 0x0,
1821 NULL, HFILL
1825 &hf_msmms_data_timing_pair_packet_length,
1827 "Packet length",
1828 "msmms.data.timing-pair.packet-length",
1829 FT_UINT16,
1830 BASE_DEC,
1831 NULL,
1832 0x0,
1833 NULL, HFILL
1837 /* Unparsed data */
1839 &hf_msmms_data_unparsed,
1841 "Unparsed data",
1842 "msmms.data.unparsed",
1843 FT_NONE,
1844 BASE_NONE,
1845 NULL,
1846 0x0,
1847 NULL, HFILL
1853 static int *ett[] =
1855 &ett_msmms_command,
1856 &ett_msmms_command_common_header,
1857 &ett_msmms_data,
1858 &ett_msmms_data_timing_packet_pair
1861 /* Register protocol and fields */
1862 proto_msmms = proto_register_protocol("Microsoft Media Server", "MSMMS", "msmms");
1863 proto_register_field_array(proto_msmms, hf, array_length(hf));
1864 proto_register_subtree_array(ett, array_length(ett));
1865 msmms_handle = register_dissector("msmms", dissect_msmms_pdu, proto_msmms);
1868 void proto_reg_handoff_msmms_command(void)
1870 /* Control commands using TCP port */
1871 dissector_add_uint_with_preference("tcp.port", MSMMS_PORT, msmms_handle);
1872 /* Data command(s) using UDP port */
1873 dissector_add_uint_with_preference("udp.port", MSMMS_PORT, msmms_handle);
1877 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1879 * Local variables:
1880 * c-basic-offset: 4
1881 * tab-width: 8
1882 * indent-tabs-mode: nil
1883 * End:
1885 * vi: set shiftwidth=4 tabstop=8 expandtab:
1886 * :indentSize=4:tabSize=8:noTabs=true: