epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / dissectors / packet-msrp.c
blob8aa14f5ebb60b69e047dec505da83d8995f084a5
1 /* packet-msrp.c
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
11 * References:
12 * https://tools.ietf.org/html/rfc4975
15 #include "config.h"
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 */
41 static int ett_msrp;
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;
68 typedef struct {
69 const char *name;
70 } msrp_header_t;
72 static const msrp_header_t msrp_headers[] = {
73 { "Unknown-header"},
74 { "From-Path"}, /* 1 */
75 { "To-Path"}, /* 2 */
76 { "Message-ID"}, /* 3 */
77 { "Success-Report"}, /* 4 */
78 { "Failure-Report"}, /* 5 */
79 { "Byte-Range"}, /* 6 */
80 { "Status"}, /* 7 */
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
99 #define MSRP_STATUS 7
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 */
125 void
126 msrp_add_address( packet_info *pinfo,
127 address *addr, int port,
128 const char *setup_method, uint32_t setup_frame_number)
130 address null_addr;
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
137 * again.
139 if (pinfo->fd->visited)
141 return;
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.
156 if (!p_conv) {
157 p_conv = conversation_new( pinfo->num, addr, &null_addr, CONVERSATION_TCP,
158 (uint32_t)port, 0,
159 NO_ADDR2 | NO_PORT2);
162 /* Set dissector */
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.
173 if (!p_conv_data) {
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 */
190 static void
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);
200 if (!p_conv_data)
202 /* First time, get info from conversation */
203 p_conv = find_conversation(pinfo->num, &pinfo->net_dst, &pinfo->net_src,
204 CONVERSATION_TCP,
205 pinfo->destport, pinfo->srcport, 0);
207 if (p_conv)
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);
213 if (p_conv_data)
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);
235 if (msrp_setup_tree)
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)
253 unsigned i;
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)
259 return i;
263 return -1;
268 * Display the entire message as raw text.
270 static void
271 tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree)
273 int offset, next_offset, linelen;
274 offset = 0;
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
298 * phrase = utf8text
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
306 * Examples:
307 * "MSRP 1234 SEND(CRLF)"
308 * "MSRP 1234 200 OK(CRLF)
310 static bool
311 check_msrp_header(tvbuff_t *tvb)
313 int linelen;
314 int space_offset;
315 int next_offset = 0;
316 unsigned token_1_len;
317 int token_2_start;
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 */){
325 return false;
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.)
340 return false;
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.
351 return false;
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 */
358 return true;
361 return false;
364 /* ABNF of line-end:
365 * end-line = "-------" transact-id continuation-flag CRLF
366 * This code is modeled on the code in packet-multipart.c
368 static int
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);
377 if (linelen == -1) {
378 return -1;
380 if (tvb_strneql(tvb, next_offset, (const char *)"-------", 7) == 0)
381 return next_offset;
382 offset = next_offset;
385 return -1;
388 static bool
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);
400 /* Set dissector */
401 conversation_set_dissector(conversation, msrp_handle);
403 dissect_msrp(tvb, pinfo, tree, data);
404 return true;
406 return false;
409 /* Code to actually dissect the packets */
410 static int
411 dissect_msrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
413 int offset = 0;
414 int next_offset = 0;
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;
418 int linelen;
419 int space_offset;
420 int token_2_start;
421 unsigned token_2_len;
422 int token_3_start;
423 unsigned token_3_len;
424 int token_4_start = 0;
425 unsigned token_4_len = 0;
426 bool is_msrp_response;
427 int end_line_offset;
428 int end_line_len;
429 int line_end_offset;
430 int message_end_offset;
431 int colon_offset;
432 int header_len;
433 int hf_index;
434 int value_offset;
435 unsigned char c;
436 int value_len;
437 char *value;
438 bool have_body = false;
439 int found_match = 0;
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 };
443 tvbuff_t *next_tvb;
444 int parameter_offset;
445 int semi_colon_offset;
446 char* hdr_str;
448 if ( !check_msrp_header(tvb)){
449 return 0;
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;
472 }else{
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
482 * a 3-digit number.
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));
513 if (token_4_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));
519 }else{
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));
527 if (tree) {
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;
534 proto_item* pi;
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);
544 }else{
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);
557 /* Headers */
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);
568 if (linelen == 0) {
570 * This is a blank line separating the
571 * message header from the message body.
573 have_body = true;
574 break;
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);
585 } else {
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);
593 } else {
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)) == ' ' ||
600 c == '\t'))
601 value_offset++;
603 * Fetch the value.
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,
616 value, "%s",
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)) == ' '
631 || c == '\t'))
632 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));
640 break;
642 default:
643 break;
647 offset = next_offset;
648 }/* End while */
650 if ( have_body ){
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,
668 next_tvb, pinfo,
669 msrp_data_tree, &content_info);
670 /* If no match dump as text */
672 if ( found_match == 0 )
674 offset = 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;
680 }/* end while */
687 /* End line */
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);
700 }/* if 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 */
708 void
709 proto_register_msrp(void)
711 expert_module_t* expert_msrp;
713 /* Setup protocol subtree array */
714 static int *ett[] = {
715 &ett_msrp,
716 &ett_raw_text,
717 &ett_msrp_reqresp,
718 &ett_msrp_hdr,
719 &ett_msrp_data,
720 &ett_msrp_end_line,
721 &ett_msrp_setup
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,
729 NULL, HFILL }
731 { &hf_msrp_response_line,
732 { "Response Line", "msrp.response.line",
733 FT_STRING, BASE_NONE,NULL,0x0,
734 NULL, HFILL }
736 { &hf_msrp_transactionID,
737 { "Transaction Id", "msrp.transaction.id",
738 FT_STRING, BASE_NONE,NULL,0x0,
739 NULL, HFILL }
741 { &hf_msrp_method,
742 { "Method", "msrp.method",
743 FT_STRING, BASE_NONE,NULL,0x0,
744 NULL, HFILL }
746 { &hf_msrp_status_code,
747 { "Status code", "msrp.status.code",
748 FT_UINT16, BASE_DEC,NULL,0x0,
749 NULL, HFILL }
751 { &hf_msrp_hdr,
752 { "Header", "msrp.hdr",
753 FT_STRING, BASE_NONE,NULL,0x0,
754 NULL, HFILL }
756 { &hf_msrp_msg_hdr,
757 { "Message Header", "msrp.msg.hdr",
758 FT_NONE, BASE_NONE,NULL,0x0,
759 NULL, HFILL }
761 { &hf_msrp_end_line,
762 { "End Line", "msrp.end.line",
763 FT_STRING, BASE_NONE,NULL,0x0,
764 NULL, HFILL }
766 { &hf_msrp_cnt_flg,
767 { "Continuation-flag", "msrp.cnt.flg",
768 FT_STRING, BASE_NONE,NULL,0x0,
769 NULL, HFILL }
771 { &hf_header_array[MSRP_FROM_PATH],
772 { "From Path", "msrp.from.path",
773 FT_STRING, BASE_NONE,NULL,0x0,
774 NULL, HFILL }
776 { &hf_header_array[MSRP_TO_PATH],
777 { "To Path", "msrp.to.path",
778 FT_STRING, BASE_NONE,NULL,0x0,
779 NULL, HFILL }
781 { &hf_header_array[MSRP_MESSAGE_ID],
782 { "Message ID", "msrp.messageid",
783 FT_STRING, BASE_NONE,NULL,0x0,
784 NULL, HFILL }
786 { &hf_header_array[MSRP_SUCCESS_REPORT],
787 { "Success Report", "msrp.success.report",
788 FT_STRING, BASE_NONE,NULL,0x0,
789 NULL, HFILL }
791 { &hf_header_array[MSRP_FAILURE_REPORT],
792 { "Failure Report", "msrp.failure.report",
793 FT_STRING, BASE_NONE,NULL,0x0,
794 NULL, HFILL }
796 { &hf_header_array[MSRP_BYTE_RANGE],
797 { "Byte Range", "msrp.byte.range",
798 FT_STRING, BASE_NONE,NULL,0x0,
799 NULL, HFILL }
801 { &hf_header_array[MSRP_STATUS],
802 { "Status", "msrp.status",
803 FT_STRING, BASE_NONE,NULL,0x0,
804 NULL, HFILL }
806 { &hf_header_array[MSRP_CONTENT_TYPE],
807 { "Content-Type", "msrp.content.type",
808 FT_STRING, BASE_NONE,NULL,0x0,
809 NULL, HFILL }
811 { &hf_header_array[MSRP_CONTENT_ID],
812 { "Content-ID", "msrp.content.id",
813 FT_STRING, BASE_NONE,NULL,0x0,
814 NULL, HFILL }
816 { &hf_header_array[MSRP_CONTENT_DISCRIPTION],
817 { "Content-Description", "msrp.content.description",
818 FT_STRING, BASE_NONE,NULL,0x0,
819 NULL, HFILL }
821 { &hf_header_array[MSRP_CONTENT_DISPOSITION],
822 { "Content-Disposition", "msrp.content.disposition",
823 FT_STRING, BASE_NONE,NULL,0x0,
824 NULL, HFILL }
826 { &hf_header_array[MSRP_USE_PATH],
827 { "Use-Path", "msrp.use.path",
828 FT_STRING, BASE_NONE,NULL,0x0,
829 NULL, HFILL }
831 { &hf_header_array[MSRP_WWW_AUTHENTICATE],
832 { "WWW-Authenticate", "msrp.www.authenticate",
833 FT_STRING, BASE_NONE,NULL,0x0,
834 NULL, HFILL }
836 { &hf_header_array[MSRP_AUTHORIZATION],
837 { "Authorization", "msrp.authorization",
838 FT_STRING, BASE_NONE,NULL,0x0,
839 NULL, HFILL }
841 { &hf_header_array[MSRP_AUTHENTICATION_INFO],
842 { "Authentication-Info", "msrp.authentication.info",
843 FT_STRING, BASE_NONE,NULL,0x0,
844 NULL, HFILL }
846 { &hf_msrp_data,
847 { "Data", "msrp.data",
848 FT_STRING, BASE_NONE, NULL, 0x0,
849 NULL, HFILL}
851 { &hf_msrp_setup,
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 */
909 void
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
920 * Local variables:
921 * c-basic-offset: 4
922 * tab-width: 8
923 * indent-tabs-mode: nil
924 * End:
926 * vi: set shiftwidth=4 tabstop=8 expandtab:
927 * :indentSize=4:tabSize=8:noTabs=true: