2 * Routines for Message Session Relay Protocol(MSRP) dissection
3 * Copyright 2005, Anders Broman <anders.broman[at]ericsson.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 * https://tools.ietf.org/html/rfc4975
17 #include <epan/packet.h>
18 #include <epan/conversation.h>
19 #include <epan/prefs.h>
20 #include <epan/proto_data.h>
21 #include <epan/expert.h>
22 #include <wsutil/strtoi.h>
23 #include <wsutil/str_util.h>
24 #include <wsutil/array.h>
26 #include "packet-msrp.h"
27 #include "packet-media-type.h"
29 void proto_register_msrp(void);
30 void proto_reg_handoff_msrp(void);
32 #define TCP_PORT_MSRP 2855
34 #define MSRP_HDR "MSRP"
35 #define MSRP_HDR_LEN (strlen (MSRP_HDR))
37 /* Initialize the protocol and registered fields */
38 static int proto_msrp
;
40 /* Initialize the subtree pointers */
42 static int ett_raw_text
;
43 static int ett_msrp_reqresp
;
44 static int ett_msrp_hdr
;
45 static int ett_msrp_data
;
46 static int ett_msrp_end_line
;
47 static int ett_msrp_setup
;
49 static int hf_msrp_response_line
;
50 static int hf_msrp_request_line
;
51 static int hf_msrp_transactionID
;
52 static int hf_msrp_method
;
53 static int hf_msrp_status_code
;
54 static int hf_msrp_hdr
;
55 static int hf_msrp_msg_hdr
;
56 static int hf_msrp_end_line
;
57 static int hf_msrp_cnt_flg
;
59 static int hf_msrp_data
;
61 static expert_field ei_msrp_status_code_invalid
;
63 /* MSRP setup fields */
64 static int hf_msrp_setup
;
65 static int hf_msrp_setup_frame
;
66 static int hf_msrp_setup_method
;
72 static const msrp_header_t msrp_headers
[] = {
74 { "From-Path"}, /* 1 */
76 { "Message-ID"}, /* 3 */
77 { "Success-Report"}, /* 4 */
78 { "Failure-Report"}, /* 5 */
79 { "Byte-Range"}, /* 6 */
81 { "Content-Type"}, /* 8 */
82 { "Content-ID"}, /* 9 */
83 { "Content-Description"}, /* 10 */
84 { "Content-Disposition"}, /* 11 */
85 { "Use-Path"}, /* 12 */
86 { "WWW-Authenticate"}, /* 13 */
87 { "Authorization"}, /* 14 */
88 { "Authentication-Info"}, /* 15 */
91 static int hf_header_array
[array_length(msrp_headers
)];
93 #define MSRP_FROM_PATH 1
94 #define MSRP_TO_PATH 2
95 #define MSRP_MESSAGE_ID 3
96 #define MSRP_SUCCESS_REPORT 4
97 #define MSRP_FAILURE_REPORT 5
98 #define MSRP_BYTE_RANGE 6
100 #define MSRP_CONTENT_TYPE 8
101 #define MSRP_CONTENT_ID 9
102 #define MSRP_CONTENT_DISCRIPTION 10
103 #define MSRP_CONTENT_DISPOSITION 11
104 #define MSRP_USE_PATH 12
105 #define MSRP_WWW_AUTHENTICATE 13
106 #define MSRP_AUTHORIZATION 14
107 #define MSRP_AUTHENTICATION_INFO 15
109 static dissector_handle_t msrp_handle
;
110 static bool global_msrp_raw_text
= true;
112 /* MSRP content type and internet media type used by other dissectors
113 * are the same. List of media types from IANA at:
114 * http://www.iana.org/assignments/media-types/index.html */
115 static dissector_table_t media_type_dissector_table
;
117 static int dissect_msrp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
);
120 /* Displaying conversation setup info */
121 static bool global_msrp_show_setup_info
= true;
122 static void show_setup_info(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
);
124 /* Set up an MSRP conversation using the info given */
126 msrp_add_address( packet_info
*pinfo
,
127 address
*addr
, int port
,
128 const char *setup_method
, uint32_t setup_frame_number
)
131 conversation_t
* p_conv
;
132 struct _msrp_conversation_info
*p_conv_data
= NULL
;
135 * If this isn't the first time this packet has been processed,
136 * we've already done this work, so we don't need to do it
139 if (pinfo
->fd
->visited
)
144 clear_address(&null_addr
);
147 * Check if the ip address and port combination is not
148 * already registered as a conversation.
150 p_conv
= find_conversation( pinfo
->num
, addr
, &null_addr
, CONVERSATION_TCP
, port
, 0,
151 NO_ADDR_B
| NO_PORT_B
);
154 * If not, create a new conversation.
157 p_conv
= conversation_new( pinfo
->num
, addr
, &null_addr
, CONVERSATION_TCP
,
159 NO_ADDR2
| NO_PORT2
);
163 conversation_set_dissector(p_conv
, msrp_handle
);
166 * Check if the conversation has data associated with it.
168 p_conv_data
= (struct _msrp_conversation_info
*)conversation_get_proto_data(p_conv
, proto_msrp
);
171 * If not, add a new data item.
174 /* Create conversation data */
175 p_conv_data
= wmem_new0(wmem_file_scope(), struct _msrp_conversation_info
);
176 conversation_add_proto_data(p_conv
, proto_msrp
, p_conv_data
);
180 * Update the conversation data.
182 p_conv_data
->setup_method_set
= true;
183 (void) g_strlcpy(p_conv_data
->setup_method
, setup_method
, MAX_MSRP_SETUP_METHOD_SIZE
);
184 p_conv_data
->setup_frame_number
= setup_frame_number
;
189 /* Look for conversation info and display any setup info found */
191 show_setup_info(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
193 /* Conversation and current data */
194 conversation_t
*p_conv
= NULL
;
195 struct _msrp_conversation_info
*p_conv_data
= NULL
;
197 /* Use existing packet data if available */
198 p_conv_data
= (struct _msrp_conversation_info
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_msrp
, 0);
202 /* First time, get info from conversation */
203 p_conv
= find_conversation(pinfo
->num
, &pinfo
->net_dst
, &pinfo
->net_src
,
205 pinfo
->destport
, pinfo
->srcport
, 0);
209 /* Look for data in conversation */
210 struct _msrp_conversation_info
*p_conv_packet_data
;
211 p_conv_data
= (struct _msrp_conversation_info
*)conversation_get_proto_data(p_conv
, proto_msrp
);
215 /* Save this conversation info into packet info */
216 p_conv_packet_data
= (struct _msrp_conversation_info
*)wmem_memdup(wmem_file_scope(),
217 p_conv_data
, sizeof(struct _msrp_conversation_info
));
219 p_add_proto_data(wmem_file_scope(), pinfo
, proto_msrp
, 0, p_conv_packet_data
);
224 /* Create setup info subtree with summary info. */
225 if (p_conv_data
&& p_conv_data
->setup_method_set
)
227 proto_tree
*msrp_setup_tree
;
228 proto_item
*ti
= proto_tree_add_string_format(tree
, hf_msrp_setup
, tvb
, 0, 0,
230 "Stream setup by %s (frame %u)",
231 p_conv_data
->setup_method
,
232 p_conv_data
->setup_frame_number
);
233 proto_item_set_generated(ti
);
234 msrp_setup_tree
= proto_item_add_subtree(ti
, ett_msrp_setup
);
237 /* Add details into subtree */
238 proto_item
* item
= proto_tree_add_uint(msrp_setup_tree
, hf_msrp_setup_frame
,
239 tvb
, 0, 0, p_conv_data
->setup_frame_number
);
240 proto_item_set_generated(item
);
241 item
= proto_tree_add_string(msrp_setup_tree
, hf_msrp_setup_method
,
242 tvb
, 0, 0, p_conv_data
->setup_method
);
243 proto_item_set_generated(item
);
250 /* Returns index of headers */
251 static int msrp_is_known_msrp_header(tvbuff_t
*tvb
, int offset
, unsigned header_len
)
255 for (i
= 1; i
< array_length(msrp_headers
); i
++) {
256 if (header_len
== strlen(msrp_headers
[i
].name
) &&
257 tvb_strncaseeql(tvb
, offset
, msrp_headers
[i
].name
, header_len
) == 0)
268 * Display the entire message as raw text.
271 tvb_raw_text_add(tvbuff_t
*tvb
, proto_tree
*tree
)
273 int offset
, next_offset
, linelen
;
276 while (tvb_offset_exists(tvb
, offset
)) {
277 /* 'desegment' is false so will set next_offset to beyond the end of
278 the buffer if no line ending is found */
279 tvb_find_line_end(tvb
, offset
, -1, &next_offset
, false);
280 linelen
= next_offset
- offset
;
281 proto_tree_add_format_text(tree
, tvb
, offset
, linelen
);
282 offset
= next_offset
;
286 /* This code is modeled on the code in packet-sip.c
287 * ABNF code for the MSRP header:
288 * The following syntax specification uses the augmented Backus-Naur
289 * Form (BNF) as described in RFC-2234 [6].
292 * msrp-req-or-resp = msrp-request / msrp-response
293 * msrp-request = req-start headers [content-stuff] end-line
294 * msrp-response = resp-start headers end-line
296 * req-start = pMSRP SP transact-id SP method CRLF
297 * resp-start = pMSRP SP transact-id SP status-code [SP phrase] CRLF
300 * pMSRP = %x4D.53.52.50 ; MSRP in caps
301 * transact-id = ident
302 * method = mSEND / mREPORT / other-method
303 * mSEND = %x53.45.4e.44 ; SEND in caps
304 * mREPORT = %x52.45.50.4f.52.54; REPORT in caps
305 * other-method = 1*UPALPHA
307 * "MSRP 1234 SEND(CRLF)"
308 * "MSRP 1234 200 OK(CRLF)
311 check_msrp_header(tvbuff_t
*tvb
)
316 unsigned token_1_len
;
320 * Note that "tvb_find_line_end()" will return a value that
321 * is not longer than what's in the buffer, so the
322 * "tvb_get_ptr()" calls below won't throw exceptions. *
324 if(tvb_captured_length(tvb
) < 4 || tvb_get_ntohl(tvb
, 0) != 0x4d535250 /* MSRP */){
328 linelen
= tvb_find_line_end(tvb
, 0, -1, &next_offset
, false);
329 /* Find the first SP */
330 space_offset
= tvb_find_uint8(tvb
, 0, linelen
, ' ');
332 if (space_offset
<= 0) {
334 * Either there's no space in the line (which means
335 * the line is empty or doesn't have a token followed
336 * by a space; neither is valid for a request or response), or
337 * the first character in the line is a space ( which isn't valid
338 * for a MSRP header.)
343 token_1_len
= space_offset
;
344 token_2_start
= space_offset
+ 1;
345 space_offset
= tvb_find_uint8(tvb
, token_2_start
, linelen
, ' ');
346 if (space_offset
== -1) {
348 * There's no space after the second token, so we don't
349 * have a third token.
354 * Is the first token "MSRP"?
356 if (token_1_len
== MSRP_HDR_LEN
) { /* && tvb_strneql(tvb, 0, MSRP_HDR, MSRP_HDR_LEN) == 0){ */
357 /* This check can be made more strict but accept we do have MSRP for now */
365 * end-line = "-------" transact-id continuation-flag CRLF
366 * This code is modeled on the code in packet-multipart.c
369 find_end_line(tvbuff_t
*tvb
, int start
)
371 int offset
= start
, next_offset
, linelen
;
373 while (tvb_offset_exists(tvb
, offset
)) {
374 /* 'desegment' is false so will set next_offset to beyond the end of
375 the buffer if no line ending is found */
376 linelen
= tvb_find_line_end(tvb
, offset
, -1, &next_offset
, false);
380 if (tvb_strneql(tvb
, next_offset
, (const char *)"-------", 7) == 0)
382 offset
= next_offset
;
389 dissect_msrp_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
391 conversation_t
* conversation
;
393 if ( check_msrp_header(tvb
)){
395 * TODO Set up conversation here
397 if (pinfo
->fd
->visited
){
398 /* Look for existing conversation */
399 conversation
= find_or_create_conversation(pinfo
);
401 conversation_set_dissector(conversation
, msrp_handle
);
403 dissect_msrp(tvb
, pinfo
, tree
, data
);
409 /* Code to actually dissect the packets */
411 dissect_msrp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
415 proto_item
*ti
, *th
, *msrp_headers_item
;
416 proto_tree
*msrp_tree
, *reqresp_tree
, *raw_tree
, *msrp_hdr_tree
, *msrp_end_tree
;
417 proto_tree
*msrp_data_tree
;
421 unsigned token_2_len
;
423 unsigned token_3_len
;
424 int token_4_start
= 0;
425 unsigned token_4_len
= 0;
426 bool is_msrp_response
;
430 int message_end_offset
;
438 bool have_body
= false;
440 int content_type_len
, content_type_parameter_str_len
;
441 char *media_type_str_lower_case
= NULL
;
442 media_content_info_t content_info
= { MEDIA_CONTAINER_OTHER
, NULL
, NULL
, NULL
};
444 int parameter_offset
;
445 int semi_colon_offset
;
448 if ( !check_msrp_header(tvb
)){
451 /* We have a MSRP header with at least three tokens
453 * Note that "tvb_find_line_end()" will return a value that
454 * is not longer than what's in the buffer, so the
455 * "tvb_get_ptr()" calls below won't throw exceptions. *
457 linelen
= tvb_find_line_end(tvb
, 0, -1, &next_offset
, false);
459 /* Find the first SP and skip the first token */
460 token_2_start
= tvb_find_uint8(tvb
, 0, linelen
, ' ') + 1;
462 /* Work out 2nd token's length by finding next space */
463 space_offset
= tvb_find_uint8(tvb
, token_2_start
, linelen
-token_2_start
, ' ');
464 token_2_len
= space_offset
- token_2_start
;
466 /* Look for another space in this line to indicate a 4th token */
467 token_3_start
= space_offset
+ 1;
468 space_offset
= tvb_find_uint8(tvb
, token_3_start
,linelen
-token_3_start
, ' ');
469 if ( space_offset
== -1){
470 /* 3rd token runs to the end of the line */
471 token_3_len
= linelen
- token_3_start
;
473 /* We have a fourth token */
474 token_3_len
= space_offset
- token_3_start
;
475 token_4_start
= space_offset
+ 1;
476 token_4_len
= linelen
- token_4_start
;
480 * Yes, so this is either a msrp-request or msrp-response.
481 * To be a msrp-response, the second token must be
484 is_msrp_response
= false;
485 if (token_3_len
== 3) {
486 if (g_ascii_isdigit(tvb_get_uint8(tvb
, token_3_start
)) &&
487 g_ascii_isdigit(tvb_get_uint8(tvb
, token_3_start
+ 1)) &&
488 g_ascii_isdigit(tvb_get_uint8(tvb
, token_3_start
+ 2))) {
489 is_msrp_response
= true;
493 /* Find the end line to be able to process the headers
494 * Note that in case of [content-stuff] headers and [content-stuff] is separated by CRLF
497 offset
= next_offset
;
498 end_line_offset
= find_end_line(tvb
,offset
);
499 if (end_line_offset
< 0) {
500 pinfo
->desegment_offset
= 0;
501 pinfo
->desegment_len
= DESEGMENT_ONE_MORE_SEGMENT
;
502 return tvb_reported_length_remaining(tvb
, offset
);
504 end_line_len
= tvb_find_line_end(tvb
, end_line_offset
, -1, &next_offset
, false);
505 message_end_offset
= end_line_offset
+ end_line_len
+ 2;
507 /* Make entries in Protocol column and Info column on summary display */
508 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MSRP");
509 if (is_msrp_response
){
510 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Response: %s ",
511 tvb_format_text(pinfo
->pool
, tvb
, token_3_start
, token_3_len
));
514 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s ",
515 tvb_format_text(pinfo
->pool
, tvb
, token_4_start
, token_4_len
));
517 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "Transaction ID: %s",
518 tvb_format_text(pinfo
->pool
, tvb
, token_2_start
, token_2_len
));
520 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Request: %s ",
521 tvb_format_text(pinfo
->pool
, tvb
, token_3_start
, token_3_len
));
523 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "Transaction ID: %s",
524 tvb_format_text(pinfo
->pool
, tvb
, token_2_start
, token_2_len
));
528 ti
= proto_tree_add_item(tree
, proto_msrp
, tvb
, 0, message_end_offset
, ENC_NA
);
529 msrp_tree
= proto_item_add_subtree(ti
, ett_msrp
);
531 if (is_msrp_response
){
532 uint32_t msrp_status_code
= -1;
533 bool msrp_status_code_valid
;
535 th
= proto_tree_add_item(msrp_tree
,hf_msrp_response_line
,tvb
,0,linelen
,ENC_UTF_8
);
536 reqresp_tree
= proto_item_add_subtree(th
, ett_msrp_reqresp
);
537 proto_tree_add_item(reqresp_tree
,hf_msrp_transactionID
,tvb
,token_2_start
,token_2_len
,ENC_UTF_8
);
538 msrp_status_code_valid
= ws_strtou32(
539 tvb_get_string_enc(pinfo
->pool
, tvb
, token_3_start
, token_3_len
, ENC_UTF_8
|ENC_NA
),
540 NULL
, & msrp_status_code
);
541 pi
= proto_tree_add_uint(reqresp_tree
,hf_msrp_status_code
,tvb
,token_3_start
,token_3_len
,msrp_status_code
);
542 if (!msrp_status_code_valid
)
543 expert_add_info(pinfo
, pi
, &ei_msrp_status_code_invalid
);
545 th
= proto_tree_add_item(msrp_tree
,hf_msrp_request_line
,tvb
,0,linelen
,ENC_UTF_8
);
546 reqresp_tree
= proto_item_add_subtree(th
, ett_msrp_reqresp
);
547 proto_tree_add_item(reqresp_tree
,hf_msrp_transactionID
,tvb
,token_2_start
,token_2_len
,ENC_UTF_8
);
548 proto_tree_add_item(reqresp_tree
,hf_msrp_method
,tvb
,token_3_start
,token_3_len
,ENC_UTF_8
);
551 /* Conversation setup info */
552 if (global_msrp_show_setup_info
)
554 show_setup_info(tvb
, pinfo
, msrp_tree
);
558 msrp_headers_item
= proto_tree_add_item(msrp_tree
, hf_msrp_msg_hdr
, tvb
, offset
,(end_line_offset
- offset
), ENC_NA
);
559 msrp_hdr_tree
= proto_item_add_subtree(msrp_headers_item
, ett_msrp_hdr
);
562 * Process the headers
564 while (tvb_offset_exists(tvb
, offset
) && offset
< end_line_offset
) {
565 /* 'desegment' is false so will set next_offset to beyond the end of
566 the buffer if no line ending is found */
567 linelen
= tvb_find_line_end(tvb
, offset
, -1, &next_offset
, false);
570 * This is a blank line separating the
571 * message header from the message body.
576 line_end_offset
= offset
+ linelen
;
577 colon_offset
= tvb_find_uint8(tvb
, offset
, linelen
, ':');
578 if (colon_offset
== -1) {
580 * Malformed header - no colon after the name.
582 hdr_str
= tvb_format_text(pinfo
->pool
, tvb
, offset
, linelen
);
583 proto_tree_add_string_format(msrp_hdr_tree
, hf_msrp_hdr
, tvb
, offset
,
584 next_offset
- offset
, hdr_str
, "%s", hdr_str
);
586 header_len
= colon_offset
- offset
;
587 hf_index
= msrp_is_known_msrp_header(tvb
, offset
, header_len
);
589 if (hf_index
== -1) {
590 hdr_str
= tvb_format_text(pinfo
->pool
, tvb
, offset
, linelen
);
591 proto_tree_add_string_format(msrp_hdr_tree
, hf_msrp_hdr
, tvb
,
592 offset
, next_offset
- offset
, hdr_str
, "%s", hdr_str
);
595 * Skip whitespace after the colon.
597 value_offset
= colon_offset
+ 1;
598 while (value_offset
< line_end_offset
&&
599 ((c
= tvb_get_uint8(tvb
, value_offset
)) == ' ' ||
605 value_len
= line_end_offset
- value_offset
;
606 value
= tvb_get_string_enc(pinfo
->pool
, tvb
, value_offset
,
607 value_len
, ENC_UTF_8
|ENC_NA
);
610 * Add it to the protocol tree,
611 * but display the line as is.
613 proto_tree_add_string_format(msrp_hdr_tree
,
614 hf_header_array
[hf_index
], tvb
,
615 offset
, next_offset
- offset
,
617 tvb_format_text(pinfo
->pool
, tvb
, offset
, linelen
));
619 switch ( hf_index
) {
621 case MSRP_CONTENT_TYPE
:
622 content_type_len
= value_len
;
623 semi_colon_offset
= tvb_find_uint8(tvb
, value_offset
,linelen
, ';');
624 if ( semi_colon_offset
!= -1) {
625 parameter_offset
= semi_colon_offset
+1;
627 * Skip whitespace after the semicolon.
629 while (parameter_offset
< line_end_offset
630 && ((c
= tvb_get_uint8(tvb
, parameter_offset
)) == ' '
633 content_type_len
= semi_colon_offset
- value_offset
;
634 content_type_parameter_str_len
= line_end_offset
- parameter_offset
;
635 content_info
.media_str
= tvb_get_string_enc(pinfo
->pool
, tvb
,
636 parameter_offset
, content_type_parameter_str_len
, ENC_UTF_8
|ENC_NA
);
638 media_type_str_lower_case
= ascii_strdown_inplace(
639 (char *)tvb_get_string_enc(pinfo
->pool
, tvb
, value_offset
, content_type_len
, ENC_UTF_8
|ENC_NA
));
647 offset
= next_offset
;
652 * There's a message body starting at "next_offset".
653 * Set the length of the header item.
655 proto_item_set_end(msrp_headers_item
, tvb
, next_offset
);
657 /* Create new tree & tvb for data */
658 next_tvb
= tvb_new_subset_remaining(tvb
, next_offset
);
659 ti
= proto_tree_add_item(msrp_tree
, hf_msrp_data
, tvb
,
660 next_offset
, -1, ENC_UTF_8
);
661 msrp_data_tree
= proto_item_add_subtree(ti
, ett_msrp_data
);
663 /* give the content type parameters to sub dissectors */
665 if ( media_type_str_lower_case
!= NULL
) {
666 found_match
= dissector_try_string(media_type_dissector_table
,
667 media_type_str_lower_case
,
669 msrp_data_tree
, &content_info
);
670 /* If no match dump as text */
672 if ( found_match
== 0 )
675 while (tvb_offset_exists(next_tvb
, offset
)) {
676 tvb_find_line_end(next_tvb
, offset
, -1, &next_offset
, false);
677 linelen
= next_offset
- offset
;
678 proto_tree_add_format_text(msrp_data_tree
, next_tvb
, offset
, linelen
);
679 offset
= next_offset
;
688 ti
= proto_tree_add_item(msrp_tree
,hf_msrp_end_line
,tvb
,end_line_offset
,end_line_len
,ENC_UTF_8
);
689 msrp_end_tree
= proto_item_add_subtree(ti
, ett_msrp_end_line
);
691 proto_tree_add_item(msrp_end_tree
,hf_msrp_transactionID
,tvb
,end_line_offset
+ 7,token_2_len
,ENC_UTF_8
);
692 /* continuation-flag */
693 proto_tree_add_item(msrp_end_tree
,hf_msrp_cnt_flg
,tvb
,end_line_offset
+end_line_len
-1,1,ENC_UTF_8
);
695 if (global_msrp_raw_text
&& tree
) {
696 raw_tree
= proto_tree_add_subtree(tree
, tvb
, 0, -1, ett_msrp
, NULL
, "Message Session Relay Protocol(as raw text)");
697 tvb_raw_text_add(tvb
,raw_tree
);
701 return message_end_offset
;
702 /* return tvb_captured_length(tvb); */
704 /* If this protocol has a sub-dissector call it here, see section 1.8 */
709 proto_register_msrp(void)
711 expert_module_t
* expert_msrp
;
713 /* Setup protocol subtree array */
714 static int *ett
[] = {
724 /* Setup list of header fields */
725 static hf_register_info hf
[] = {
726 { &hf_msrp_request_line
,
727 { "Request Line", "msrp.request.line",
728 FT_STRING
, BASE_NONE
,NULL
,0x0,
731 { &hf_msrp_response_line
,
732 { "Response Line", "msrp.response.line",
733 FT_STRING
, BASE_NONE
,NULL
,0x0,
736 { &hf_msrp_transactionID
,
737 { "Transaction Id", "msrp.transaction.id",
738 FT_STRING
, BASE_NONE
,NULL
,0x0,
742 { "Method", "msrp.method",
743 FT_STRING
, BASE_NONE
,NULL
,0x0,
746 { &hf_msrp_status_code
,
747 { "Status code", "msrp.status.code",
748 FT_UINT16
, BASE_DEC
,NULL
,0x0,
752 { "Header", "msrp.hdr",
753 FT_STRING
, BASE_NONE
,NULL
,0x0,
757 { "Message Header", "msrp.msg.hdr",
758 FT_NONE
, BASE_NONE
,NULL
,0x0,
762 { "End Line", "msrp.end.line",
763 FT_STRING
, BASE_NONE
,NULL
,0x0,
767 { "Continuation-flag", "msrp.cnt.flg",
768 FT_STRING
, BASE_NONE
,NULL
,0x0,
771 { &hf_header_array
[MSRP_FROM_PATH
],
772 { "From Path", "msrp.from.path",
773 FT_STRING
, BASE_NONE
,NULL
,0x0,
776 { &hf_header_array
[MSRP_TO_PATH
],
777 { "To Path", "msrp.to.path",
778 FT_STRING
, BASE_NONE
,NULL
,0x0,
781 { &hf_header_array
[MSRP_MESSAGE_ID
],
782 { "Message ID", "msrp.messageid",
783 FT_STRING
, BASE_NONE
,NULL
,0x0,
786 { &hf_header_array
[MSRP_SUCCESS_REPORT
],
787 { "Success Report", "msrp.success.report",
788 FT_STRING
, BASE_NONE
,NULL
,0x0,
791 { &hf_header_array
[MSRP_FAILURE_REPORT
],
792 { "Failure Report", "msrp.failure.report",
793 FT_STRING
, BASE_NONE
,NULL
,0x0,
796 { &hf_header_array
[MSRP_BYTE_RANGE
],
797 { "Byte Range", "msrp.byte.range",
798 FT_STRING
, BASE_NONE
,NULL
,0x0,
801 { &hf_header_array
[MSRP_STATUS
],
802 { "Status", "msrp.status",
803 FT_STRING
, BASE_NONE
,NULL
,0x0,
806 { &hf_header_array
[MSRP_CONTENT_TYPE
],
807 { "Content-Type", "msrp.content.type",
808 FT_STRING
, BASE_NONE
,NULL
,0x0,
811 { &hf_header_array
[MSRP_CONTENT_ID
],
812 { "Content-ID", "msrp.content.id",
813 FT_STRING
, BASE_NONE
,NULL
,0x0,
816 { &hf_header_array
[MSRP_CONTENT_DISCRIPTION
],
817 { "Content-Description", "msrp.content.description",
818 FT_STRING
, BASE_NONE
,NULL
,0x0,
821 { &hf_header_array
[MSRP_CONTENT_DISPOSITION
],
822 { "Content-Disposition", "msrp.content.disposition",
823 FT_STRING
, BASE_NONE
,NULL
,0x0,
826 { &hf_header_array
[MSRP_USE_PATH
],
827 { "Use-Path", "msrp.use.path",
828 FT_STRING
, BASE_NONE
,NULL
,0x0,
831 { &hf_header_array
[MSRP_WWW_AUTHENTICATE
],
832 { "WWW-Authenticate", "msrp.www.authenticate",
833 FT_STRING
, BASE_NONE
,NULL
,0x0,
836 { &hf_header_array
[MSRP_AUTHORIZATION
],
837 { "Authorization", "msrp.authorization",
838 FT_STRING
, BASE_NONE
,NULL
,0x0,
841 { &hf_header_array
[MSRP_AUTHENTICATION_INFO
],
842 { "Authentication-Info", "msrp.authentication.info",
843 FT_STRING
, BASE_NONE
,NULL
,0x0,
847 { "Data", "msrp.data",
848 FT_STRING
, BASE_NONE
, NULL
, 0x0,
852 { "Stream setup", "msrp.setup",
853 FT_STRING
, BASE_NONE
, NULL
, 0x0,
854 "Stream setup, method and frame number", HFILL
}
856 { &hf_msrp_setup_frame
,
857 { "Setup frame", "msrp.setup-frame",
858 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
859 "Frame that set up this stream", HFILL
}
861 { &hf_msrp_setup_method
,
862 { "Setup Method", "msrp.setup-method",
863 FT_STRING
, BASE_NONE
, NULL
, 0x0,
864 "Method used to set up this stream", HFILL
}
868 static ei_register_info ei
[] = {
869 { &ei_msrp_status_code_invalid
, { "msrp.status.code.invalid", PI_MALFORMED
, PI_ERROR
,
870 "Invalid status code", EXPFILL
}}
873 module_t
*msrp_module
;
874 /* Register the protocol name and description */
875 proto_msrp
= proto_register_protocol("Message Session Relay Protocol","MSRP", "msrp");
877 /* Required function calls to register the header fields and subtrees used */
878 proto_register_field_array(proto_msrp
, hf
, array_length(hf
));
879 proto_register_subtree_array(ett
, array_length(ett
));
881 msrp_module
= prefs_register_protocol(proto_msrp
, NULL
);
883 prefs_register_bool_preference(msrp_module
, "display_raw_text",
884 "Display raw text for MSRP message",
885 "Specifies that the raw text of the "
886 "MSRP message should be displayed "
887 "in addition to the dissection tree",
888 &global_msrp_raw_text
);
890 prefs_register_bool_preference(msrp_module
, "show_setup_info",
891 "Show stream setup information",
892 "Where available, show which protocol and frame caused "
893 "this MSRP stream to be created",
894 &global_msrp_show_setup_info
);
898 * Register the dissector by name, so other dissectors can
899 * grab it by name rather than just referring to it directly.
901 msrp_handle
= register_dissector("msrp", dissect_msrp
, proto_msrp
);
903 expert_msrp
= expert_register_protocol(proto_msrp
);
904 expert_register_field_array(expert_msrp
, ei
, array_length(ei
));
908 /* Register the protocol with Wireshark */
910 proto_reg_handoff_msrp(void)
912 heur_dissector_add("tcp", dissect_msrp_heur
, "MSRP over TCP", "msrp_tcp", proto_msrp
, HEURISTIC_ENABLE
);
913 dissector_add_uint_with_preference("tcp.port", TCP_PORT_MSRP
, msrp_handle
);
914 media_type_dissector_table
= find_dissector_table("media_type");
918 * Editor modelines - https://www.wireshark.org/tools/modelines.html
923 * indent-tabs-mode: nil
926 * vi: set shiftwidth=4 tabstop=8 expandtab:
927 * :indentSize=4:tabSize=8:noTabs=true: