2 * Routines for SDP packet disassembly (RFC 2327)
4 * Jason Lango <jal@netapp.com>
5 * Liberally copied from packet-http.c, by Guy Harris <guy@alum.mit.edu>
7 * $Id: packet-sdp.c,v 1.28 2002/02/02 21:54:04 guy Exp $
9 * Ethereal - Network traffic analyzer
10 * By Gerald Combs <gerald@ethereal.com>
11 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #ifdef HAVE_SYS_TYPES_H
31 #include <sys/types.h>
38 #include <epan/packet.h>
39 #include <epan/strutil.h>
41 static int proto_sdp = -1;
43 /* Top level fields */
44 static int hf_protocol_version = -1;
45 static int hf_owner = -1;
46 static int hf_session_name = -1;
47 static int hf_session_info = -1;
48 static int hf_uri = -1;
49 static int hf_email = -1;
50 static int hf_phone = -1;
51 static int hf_connection_info = -1;
52 static int hf_bandwidth = -1;
53 static int hf_timezone = -1;
54 static int hf_encryption_key = -1;
55 static int hf_session_attribute = -1;
56 static int hf_media_attribute = -1;
57 static int hf_time = -1;
58 static int hf_repeat_time = -1;
59 static int hf_media = -1;
60 static int hf_media_title = -1;
61 static int hf_unknown = -1;
62 static int hf_misplaced = -1;
63 static int hf_invalid = -1;
65 /* hf_owner subfields*/
66 static int hf_owner_username = -1;
67 static int hf_owner_sessionid = -1;
68 static int hf_owner_version = -1;
69 static int hf_owner_network_type = -1;
70 static int hf_owner_address_type = -1;
71 static int hf_owner_address = -1;
73 /* hf_connection_info subfields */
74 static int hf_connection_info_network_type = -1;
75 static int hf_connection_info_address_type = -1;
76 static int hf_connection_info_connection_address = -1;
77 static int hf_connection_info_ttl = -1;
78 static int hf_connection_info_num_addr = -1;
80 /* hf_bandwidth subfields */
81 static int hf_bandwidth_modifier = -1;
82 static int hf_bandwidth_value = -1;
84 /* hf_time subfields */
85 static int hf_time_start = -1;
86 static int hf_time_stop = -1;
88 /* hf_repeat_time subfield */
89 static int hf_repeat_time_interval = -1;
90 static int hf_repeat_time_duration = -1;
91 static int hf_repeat_time_offset = -1;
93 /* hf_timezone subfields */
94 static int hf_timezone_time = -1;
95 static int hf_timezone_offset = -1;
97 /* hf_encryption_key subfields */
98 static int hf_encryption_key_type = -1;
99 static int hf_encryption_key_data = -1;
101 /* hf_session_attribute subfields */
102 static int hf_session_attribute_field = -1;
103 static int hf_session_attribute_value = -1;
105 /* hf_media subfields */
106 static int hf_media_media = -1;
107 static int hf_media_port = -1;
108 static int hf_media_portcount = -1;
109 static int hf_media_proto = -1;
110 static int hf_media_format = -1;
112 /* hf_session_attribute subfields */
113 static int hf_media_attribute_field = -1;
114 static int hf_media_attribute_value = -1;
117 static int ett_sdp = -1;
118 static int ett_sdp_owner = -1;
119 static int ett_sdp_connection_info = -1;
120 static int ett_sdp_bandwidth = -1;
121 static int ett_sdp_time = -1;
122 static int ett_sdp_repeat_time = -1;
123 static int ett_sdp_timezone = -1;
124 static int ett_sdp_encryption_key = -1;
125 static int ett_sdp_session_attribute = -1;
126 static int ett_sdp_media = -1;
127 static int ett_sdp_media_attribute = -1;
129 /* static functions */
131 static void call_sdp_subdissector(tvbuff_t *tvb, packet_info *pinfo,
132 proto_tree *tree, int hf, proto_tree* ti);
134 /* Subdissector functions */
135 static void dissect_sdp_owner(tvbuff_t *tvb, packet_info *pinfo,
136 proto_tree *tree, proto_item* ti);
137 static void dissect_sdp_connection_info(tvbuff_t *tvb, packet_info *pinfo,
138 proto_tree *tree, proto_item* ti);
139 static void dissect_sdp_bandwidth(tvbuff_t *tvb, packet_info *pinfo,
140 proto_tree *tree, proto_item *ti);
141 static void dissect_sdp_time(tvbuff_t *tvb, packet_info *pinfo,
142 proto_tree *tree, proto_item* ti);
143 static void dissect_sdp_repeat_time(tvbuff_t *tvb, packet_info *pinfo,
144 proto_tree *tree, proto_item* ti);
145 static void dissect_sdp_timezone(tvbuff_t *tvb, packet_info *pinfo,
146 proto_tree *tree, proto_item* ti);
147 static void dissect_sdp_encryption_key(tvbuff_t *tvb, packet_info *pinfo,
148 proto_tree *tree, proto_item * ti);
149 static void dissect_sdp_session_attribute(tvbuff_t *tvb, packet_info *pinfo,
150 proto_tree *tree,proto_item *ti);
151 static void dissect_sdp_media(tvbuff_t *tvb, packet_info *pinfo,
152 proto_tree *tree, proto_item *ti);
153 static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo,
154 proto_tree *tree,proto_item *ti);
157 dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
159 proto_tree *sdp_tree;
160 proto_item *ti, *sub_ti;
173 * As RFC 2327 says, "SDP is purely a format for session
174 * description - it does not incorporate a transport protocol,
175 * and is intended to use different transport protocols as
176 * appropriate including the Session Announcement Protocol,
177 * Session Initiation Protocol, Real-Time Streaming Protocol,
178 * electronic mail using the MIME extensions, and the
179 * Hypertext Transport Protocol."
181 * We therefore don't set the protocol or info columns;
182 * instead, we append to them, so that we don't erase
183 * what the protocol inside which the SDP stuff resides
186 if (check_col(pinfo->cinfo, COL_PROTOCOL))
187 col_append_str(pinfo->cinfo, COL_PROTOCOL, "/SDP");
189 if (check_col(pinfo->cinfo, COL_INFO)) {
190 /* XXX: Needs description. */
191 col_append_str(pinfo->cinfo, COL_INFO, ", with session description");
197 ti = proto_tree_add_item(tree, proto_sdp, tvb, offset, -1, FALSE);
198 sdp_tree = proto_item_add_subtree(ti, ett_sdp);
201 * Show the SDP message a line at a time.
204 while (tvb_offset_exists(tvb, offset)) {
206 * Find the end of the line.
208 linelen = tvb_find_line_end_unquoted(tvb, offset, -1,
212 * Line must contain at least e.g. "v=".
217 type = tvb_get_guint8(tvb,offset);
218 delim = tvb_get_guint8(tvb,offset + 1);
220 proto_tree_add_item(sdp_tree,hf_invalid,tvb, offset,
222 offset = next_offset;
231 hf = hf_protocol_version;
238 hf = hf_session_name;
242 hf = hf_session_info;
244 else if (section == 'm'){
261 hf = hf_connection_info;
278 hf = hf_encryption_key;
282 hf = hf_session_attribute;
284 else if (section == 'm'){
285 hf = hf_media_attribute;
299 if( hf == hf_unknown || hf == hf_misplaced )
301 string = g_malloc(linelen - tokenoffset + 1);
302 CLEANUP_PUSH(g_free, string);
303 tvb_memcpy(tvb, (guint8 *)string, offset + tokenoffset,
304 linelen - tokenoffset);
305 string[linelen - tokenoffset] = '\0';
306 sub_ti = proto_tree_add_string(sdp_tree,hf,tvb, offset,
308 CLEANUP_CALL_AND_POP;
309 call_sdp_subdissector(tvb_new_subset(tvb,offset+tokenoffset,
310 linelen-tokenoffset,-1),
311 pinfo,tree,hf,sub_ti);
312 offset = next_offset;
315 datalen = tvb_length_remaining(tvb, offset);
317 proto_tree_add_text(sdp_tree, tvb, offset, datalen,
318 "Data (%d bytes)", datalen);
323 call_sdp_subdissector(tvbuff_t *tvb, packet_info *pinfo,
324 proto_tree *tree, int hf, proto_tree* ti){
326 dissect_sdp_owner(tvb,pinfo,tree,ti);
327 } else if ( hf == hf_connection_info) {
328 dissect_sdp_connection_info(tvb,pinfo,tree,ti);
329 } else if ( hf == hf_bandwidth) {
330 dissect_sdp_bandwidth(tvb,pinfo,tree,ti);
331 } else if ( hf == hf_time) {
332 dissect_sdp_time(tvb,pinfo,tree,ti);
333 } else if ( hf == hf_repeat_time ){
334 dissect_sdp_repeat_time(tvb,pinfo,tree,ti);
335 } else if ( hf == hf_timezone ) {
336 dissect_sdp_timezone(tvb,pinfo,tree,ti);
337 } else if ( hf == hf_encryption_key ) {
338 dissect_sdp_encryption_key(tvb,pinfo,tree,ti);
339 } else if ( hf == hf_session_attribute ){
340 dissect_sdp_session_attribute(tvb,pinfo,tree,ti);
341 } else if ( hf == hf_media ) {
342 dissect_sdp_media(tvb,pinfo,tree,ti);
343 } else if ( hf == hf_media_attribute ){
344 dissect_sdp_media_attribute(tvb,pinfo,tree,ti);
349 dissect_sdp_owner(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
351 proto_tree *sdp_owner_tree;
352 gint offset,next_offset,tokenlen;
361 sdp_owner_tree = proto_item_add_subtree(ti,ett_sdp_owner);
363 /* Find the username */
364 next_offset = tvb_find_guint8(tvb,offset,-1,' ');
365 if( next_offset == -1 )
367 tokenlen = next_offset - offset;
369 proto_tree_add_item(sdp_owner_tree,hf_owner_username,tvb, offset,tokenlen,
371 offset = next_offset + 1;
373 /* Find the session id */
374 next_offset = tvb_find_guint8(tvb,offset,-1,' ');
375 if( next_offset == -1 )
377 tokenlen = next_offset - offset;
379 proto_tree_add_item(sdp_owner_tree,hf_owner_sessionid, tvb,
380 offset,tokenlen,FALSE);
381 offset = next_offset + 1;
383 /* Find the version */
384 next_offset = tvb_find_guint8(tvb,offset,-1,' ');
385 if( next_offset == -1 )
387 tokenlen = next_offset - offset;
389 proto_tree_add_item(sdp_owner_tree,hf_owner_version, tvb,
390 offset,tokenlen,FALSE);
391 offset = next_offset + 1;
393 /* Find the network type */
394 next_offset = tvb_find_guint8(tvb,offset,-1,' ');
395 if( next_offset == -1 )
397 tokenlen = next_offset - offset;
399 proto_tree_add_item(sdp_owner_tree,hf_owner_network_type, tvb,
400 offset,tokenlen,FALSE);
401 offset = next_offset + 1;
403 /* Find the address type */
404 next_offset = tvb_find_guint8(tvb,offset,-1,' ');
405 if( next_offset == -1 )
407 tokenlen = next_offset - offset;
409 proto_tree_add_item(sdp_owner_tree,hf_owner_address_type, tvb,
410 offset,tokenlen,FALSE);
411 offset = next_offset + 1;
413 /* Find the address */
414 proto_tree_add_item(sdp_owner_tree,hf_owner_address, tvb, offset, -1, FALSE);
418 dissect_sdp_connection_info(tvbuff_t *tvb, packet_info *pinfo,
419 proto_tree *tree, proto_item* ti){
420 proto_tree *sdp_connection_info_tree;
421 gint offset,next_offset,tokenlen;
430 sdp_connection_info_tree = proto_item_add_subtree(ti,
431 ett_sdp_connection_info);
433 /* Find the network type */
434 next_offset = tvb_find_guint8(tvb,offset,-1,' ');
435 if( next_offset == -1 )
437 tokenlen = next_offset - offset;
439 proto_tree_add_item(sdp_connection_info_tree,
440 hf_connection_info_network_type,tvb,
441 offset,tokenlen,FALSE);
442 offset = next_offset + 1;
444 /* Find the address type */
445 next_offset = tvb_find_guint8(tvb,offset,-1,' ');
446 if( next_offset == -1 )
448 tokenlen = next_offset - offset;
450 proto_tree_add_item(sdp_connection_info_tree,
451 hf_connection_info_address_type,tvb,
452 offset,tokenlen,FALSE);
453 offset = next_offset + 1;
455 /* Find the connection address */
456 next_offset = tvb_find_guint8(tvb,offset,-1,'/');
457 if( next_offset == -1){
458 tokenlen = -1; /* end of tvbuff */
460 tokenlen = next_offset - offset;
462 proto_tree_add_item(sdp_connection_info_tree,
463 hf_connection_info_connection_address, tvb,
464 offset,tokenlen,FALSE);
465 if(next_offset != -1){
466 offset = next_offset + 1;
467 next_offset = tvb_find_guint8(tvb,offset,-1,'/');
468 if( next_offset == -1){
469 tokenlen = -1; /* end of tvbuff */
471 tokenlen = next_offset - offset;
473 proto_tree_add_item(sdp_connection_info_tree,
474 hf_connection_info_ttl,tvb,offset,tokenlen,FALSE);
475 if(next_offset != -1){
476 offset = next_offset + 1;
477 proto_tree_add_item(sdp_connection_info_tree,
478 hf_connection_info_num_addr, tvb,
485 dissect_sdp_bandwidth(tvbuff_t *tvb, packet_info *pinfo,
486 proto_tree *tree,proto_item *ti){
487 proto_tree * sdp_bandwidth_tree;
488 gint offset, next_offset, tokenlen;
497 sdp_bandwidth_tree = proto_item_add_subtree(ti,ett_sdp_bandwidth);
499 /* find the modifier */
500 next_offset = tvb_find_guint8(tvb,offset,-1,':');
502 if( next_offset == -1)
505 tokenlen = next_offset - offset;
507 proto_tree_add_item(sdp_bandwidth_tree, hf_bandwidth_modifier,
508 tvb, offset, tokenlen, FALSE);
510 offset = next_offset + 1;
512 proto_tree_add_item(sdp_bandwidth_tree, hf_bandwidth_value,
513 tvb, offset, -1, FALSE);
517 static void dissect_sdp_time(tvbuff_t *tvb, packet_info *pinfo,
518 proto_tree *tree, proto_item* ti){
519 proto_tree *sdp_time_tree;
520 gint offset,next_offset, tokenlen;
529 sdp_time_tree = proto_item_add_subtree(ti,ett_sdp_time);
532 next_offset = tvb_find_guint8(tvb,offset,-1,' ');
533 if( next_offset == -1 )
536 tokenlen = next_offset - offset;
537 proto_tree_add_item(sdp_time_tree, hf_time_start, tvb,
538 offset, tokenlen, FALSE);
541 offset = next_offset + 1;
542 proto_tree_add_item(sdp_time_tree,hf_time_start, tvb,
546 static void dissect_sdp_repeat_time(tvbuff_t *tvb, packet_info *pinfo,
547 proto_tree *tree, proto_item* ti){
548 proto_tree *sdp_repeat_time_tree;
549 gint offset,next_offset, tokenlen;
558 sdp_repeat_time_tree = proto_item_add_subtree(ti,ett_sdp_time);
561 next_offset = tvb_find_guint8(tvb,offset,-1,' ');
562 if( next_offset == -1 )
565 tokenlen = next_offset - offset;
566 proto_tree_add_item(sdp_repeat_time_tree, hf_repeat_time_interval, tvb,
567 offset, tokenlen, FALSE);
570 offset = next_offset + 1;
571 next_offset = tvb_find_guint8(tvb,offset,-1,' ');
572 if( next_offset == -1 )
575 tokenlen = next_offset - offset;
576 proto_tree_add_item(sdp_repeat_time_tree,hf_repeat_time_duration, tvb,
577 offset, tokenlen, FALSE);
581 offset = next_offset +1;
582 next_offset = tvb_find_guint8(tvb,offset,-1,' ');
583 if(next_offset != -1){
584 tokenlen = next_offset - offset;
586 tokenlen = -1; /* end of tvbuff */
588 proto_tree_add_item(sdp_repeat_time_tree, hf_repeat_time_offset,
589 tvb, offset, tokenlen, FALSE);
590 } while( next_offset != -1 );
594 dissect_sdp_timezone(tvbuff_t *tvb, packet_info *pinfo,
595 proto_tree *tree, proto_item* ti){
596 proto_tree* sdp_timezone_tree;
597 gint offset, next_offset, tokenlen;
604 sdp_timezone_tree = proto_item_add_subtree(ti,ett_sdp_timezone);
607 next_offset = tvb_find_guint8(tvb,offset,-1,' ');
608 if(next_offset == -1)
610 tokenlen = next_offset - offset;
612 proto_tree_add_item(sdp_timezone_tree,hf_timezone_time,tvb,
613 offset, tokenlen, FALSE);
614 offset = next_offset + 1;
615 next_offset = tvb_find_guint8(tvb,offset,-1,' ');
616 if(next_offset != -1){
617 tokenlen = next_offset - offset;
619 tokenlen = -1; /* end of tvbuff */
621 proto_tree_add_item(sdp_timezone_tree,hf_timezone_offset,tvb,
622 offset, tokenlen, FALSE);
623 offset = next_offset + 1;
624 } while (next_offset != -1);
629 static void dissect_sdp_encryption_key(tvbuff_t *tvb, packet_info *pinfo,
630 proto_tree *tree, proto_item * ti){
631 proto_tree *sdp_encryption_key_tree;
632 gint offset, next_offset, tokenlen;
638 sdp_encryption_key_tree = proto_item_add_subtree(ti,ett_sdp_encryption_key);
640 next_offset = tvb_find_guint8(tvb,offset,-1,':');
642 if(next_offset == -1)
645 tokenlen = next_offset - offset;
647 proto_tree_add_item(sdp_encryption_key_tree,hf_encryption_key_type,
648 tvb, offset, tokenlen, FALSE);
650 offset = next_offset + 1;
651 proto_tree_add_item(sdp_encryption_key_tree,hf_encryption_key_data,
652 tvb, offset, -1, FALSE);
658 static void dissect_sdp_session_attribute(tvbuff_t *tvb, packet_info *pinfo,
659 proto_tree *tree, proto_item * ti){
660 proto_tree *sdp_session_attribute_tree;
661 gint offset, next_offset, tokenlen;
667 sdp_session_attribute_tree = proto_item_add_subtree(ti,
668 ett_sdp_session_attribute);
670 next_offset = tvb_find_guint8(tvb,offset,-1,':');
672 if(next_offset == -1)
675 tokenlen = next_offset - offset;
677 proto_tree_add_item(sdp_session_attribute_tree,
678 hf_session_attribute_field,
679 tvb, offset, tokenlen, FALSE);
681 offset = next_offset + 1;
682 proto_tree_add_item(sdp_session_attribute_tree,
683 hf_session_attribute_value,
684 tvb, offset, -1, FALSE);
689 dissect_sdp_media(tvbuff_t *tvb, packet_info *pinfo,
690 proto_tree *tree, proto_item *ti){
691 proto_tree *sdp_media_tree;
692 gint offset, next_offset, tokenlen;
701 sdp_media_tree = proto_item_add_subtree(ti,ett_sdp_media);
703 next_offset = tvb_find_guint8(tvb,offset, -1, ' ');
705 if(next_offset == -1)
708 tokenlen = next_offset - offset;
710 proto_tree_add_item(sdp_media_tree, hf_media_media, tvb,
711 offset, tokenlen, FALSE);
713 offset = next_offset + 1;
715 next_offset = tvb_find_guint8(tvb,offset, -1, ' ');
716 if(next_offset == -1)
718 tokenlen = next_offset - offset;
719 next_offset = tvb_find_guint8(tvb,offset, tokenlen, '/');
721 if(next_offset != -1){
722 tokenlen = next_offset - offset;
724 proto_tree_add_item(sdp_media_tree, hf_media_port, tvb,
725 offset, tokenlen, FALSE);
726 offset = next_offset + 1;
727 next_offset = tvb_find_guint8(tvb,offset, -1, ' ');
728 if(next_offset == -1)
730 tokenlen = next_offset - offset;
731 proto_tree_add_item(sdp_media_tree, hf_media_portcount, tvb,
732 offset, tokenlen, FALSE);
733 offset = next_offset + 1;
735 next_offset = tvb_find_guint8(tvb,offset, -1, ' ');
737 if(next_offset == -1)
739 tokenlen = next_offset - offset;
741 proto_tree_add_item(sdp_media_tree, hf_media_port, tvb,
742 offset, tokenlen, FALSE);
743 offset = next_offset + 1;
746 next_offset = tvb_find_guint8(tvb,offset,-1,' ');
748 if( next_offset == -1)
751 tokenlen = next_offset - offset;
753 proto_tree_add_item(sdp_media_tree, hf_media_proto, tvb,
754 offset, tokenlen, FALSE);
757 offset = next_offset + 1;
758 next_offset = tvb_find_guint8(tvb,offset,-1,' ');
760 if(next_offset == -1){
761 tokenlen = -1; /* End of tvbuff */
763 tokenlen = next_offset - offset;
766 proto_tree_add_item(sdp_media_tree, hf_media_format, tvb,
767 offset, tokenlen, FALSE);
768 } while (next_offset != -1);
772 static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo,
773 proto_tree *tree, proto_item * ti){
774 proto_tree *sdp_media_attribute_tree;
775 gint offset, next_offset, tokenlen;
781 sdp_media_attribute_tree = proto_item_add_subtree(ti,
782 ett_sdp_media_attribute);
784 next_offset = tvb_find_guint8(tvb,offset,-1,':');
786 if(next_offset == -1)
789 tokenlen = next_offset - offset;
791 proto_tree_add_item(sdp_media_attribute_tree,
792 hf_media_attribute_field,
793 tvb, offset, tokenlen, FALSE);
795 offset = next_offset + 1;
796 proto_tree_add_item(sdp_media_attribute_tree,
797 hf_media_attribute_value,
798 tvb, offset, -1, FALSE);
803 proto_register_sdp(void)
805 static hf_register_info hf[] = {
806 { &hf_protocol_version,
807 { "Session Description Protocol Version (v)",
808 "sdp.version", FT_STRING, BASE_NONE,NULL,0x0,
809 "Session Description Protocol Version", HFILL }},
811 { "Owner/Creator, Session Id (o)",
812 "sdp.owner", FT_STRING, BASE_NONE, NULL, 0x0,
813 "Owner/Creator, Session Id", HFILL}},
815 { "Session Name (s)",
816 "sdp.session_name", FT_STRING, BASE_NONE,NULL, 0x0,
817 "Session Name", HFILL }},
819 { "Session Information (i)",
820 "sdp.session_info", FT_STRING, BASE_NONE, NULL, 0x0,
821 "Session Information", HFILL }},
823 { "URI of Description (u)",
824 "sdp.uri", FT_STRING, BASE_NONE,NULL, 0x0,
825 "URI of Description", HFILL }},
827 { "E-mail Address (e)",
828 "sdp.email", FT_STRING, BASE_NONE, NULL, 0x0,
829 "E-mail Address", HFILL }},
831 { "Phone Number (p)",
832 "sdp.phone", FT_STRING, BASE_NONE, NULL, 0x0,
833 "Phone Number", HFILL }},
834 { &hf_connection_info,
835 { "Connection Information (c)",
836 "sdp.connection_info", FT_STRING, BASE_NONE, NULL, 0x0,
837 "Connection Information", HFILL }},
839 { "Bandwidth Information (b)",
840 "sdp.bandwidth", FT_STRING, BASE_NONE, NULL, 0x0,
841 "Bandwidth Information", HFILL }},
843 { "Time Zone Adjustments (z)",
844 "sdp.timezone", FT_STRING, BASE_NONE, NULL, 0x0,
845 "Time Zone Adjustments", HFILL }},
846 { &hf_encryption_key,
847 { "Encryption Key (k)",
848 "sdp.encryption_key", FT_STRING, BASE_NONE, NULL, 0x0,
849 "Encryption Key", HFILL }},
850 { &hf_session_attribute,
851 { "Session Attribute (a)",
852 "sdp.session_attr", FT_STRING, BASE_NONE, NULL, 0x0,
853 "Session Attribute", HFILL }},
854 { &hf_media_attribute,
855 { "Media Attribute (a)",
856 "sdp.media_attr", FT_STRING, BASE_NONE, NULL, 0x0,
857 "Media Attribute", HFILL }},
859 { "Time Description, active time (t)",
860 "sdp.time", FT_STRING, BASE_NONE, NULL, 0x0,
861 "Time Description, active time", HFILL }},
864 "sdp.repeat_time", FT_STRING, BASE_NONE, NULL, 0x0,
865 "Repeat Time", HFILL }},
867 { "Media Description, name and address (m)",
868 "sdp.media", FT_STRING, BASE_NONE, NULL, 0x0,
869 "Media Description, name and address", HFILL }},
872 "sdp.media_title",FT_STRING, BASE_NONE, NULL, 0x0,
873 "Media Title", HFILL }},
876 "sdp.unknown",FT_STRING, BASE_NONE, NULL, 0x0,
880 "sdp.misplaced",FT_STRING, BASE_NONE, NULL, 0x0,
881 "Misplaced", HFILL }},
884 "sdp.invalid",FT_STRING, BASE_NONE, NULL, 0x0,
885 "Invalid line", HFILL }},
886 { &hf_owner_username,
888 "sdp.owner.username",FT_STRING, BASE_NONE, NULL, 0x0,
889 "Owner Username", HFILL }},
890 { &hf_owner_sessionid,
892 "sdp.owner.sessionid",FT_STRING, BASE_NONE, NULL, 0x0,
893 "Session ID", HFILL }},
896 "sdp.owner.version",FT_STRING, BASE_NONE, NULL, 0x0,
897 "Session Version", HFILL }},
898 { &hf_owner_network_type,
899 { "Owner Network Type",
900 "sdp.owner.network_type",FT_STRING, BASE_NONE, NULL, 0x0,
901 "Owner Network Type", HFILL }},
902 { &hf_owner_address_type,
903 { "Owner Address Type",
904 "sdp.owner.address_type",FT_STRING, BASE_NONE, NULL, 0x0,
905 "Owner Address Type", HFILL }},
908 "sdp.owner.address",FT_STRING, BASE_NONE, NULL, 0x0,
909 "Owner Address", HFILL }},
910 { &hf_connection_info_network_type,
911 { "Connection Network Type",
912 "sdp.connection_info.network_type",FT_STRING, BASE_NONE, NULL, 0x0,
913 "Connection Network Type", HFILL }},
914 { &hf_connection_info_address_type,
915 { "Connection Address Type",
916 "sdp.connection_info.address_type",FT_STRING, BASE_NONE, NULL, 0x0,
917 "Connection Address Type", HFILL }},
918 { &hf_connection_info_connection_address,
919 { "Connection Address",
920 "sdp.connection_info.address",FT_STRING, BASE_NONE, NULL, 0x0,
921 "Connection Address", HFILL }},
922 { &hf_connection_info_ttl,
924 "sdp.connection_info.ttl",FT_STRING, BASE_NONE, NULL, 0x0,
925 "Connection TTL", HFILL }},
926 { &hf_connection_info_num_addr,
927 { "Connection Number of Addresses",
928 "sdp.connection_info.num_addr",FT_STRING, BASE_NONE, NULL, 0x0,
929 "Connection Number of Addresses", HFILL }},
930 { &hf_bandwidth_modifier,
931 { "Bandwidth Modifier",
932 "sdp.bandwidth.modifier",FT_STRING, BASE_NONE, NULL, 0x0,
933 "Bandwidth Modifier", HFILL }},
934 { &hf_bandwidth_value,
936 "sdp.bandwidth.value",FT_STRING, BASE_NONE, NULL, 0x0,
937 "Bandwidth Value", HFILL }},
939 { "Session Start Time",
940 "sdp.time.start",FT_STRING, BASE_NONE, NULL, 0x0,
941 "Session Start Time", HFILL }},
943 { "Session Stop Time",
944 "sdp.time.stop",FT_STRING, BASE_NONE, NULL, 0x0,
945 "Session Stop Time", HFILL }},
946 { &hf_repeat_time_interval,
948 "sdp.repeat_time.interval",FT_STRING, BASE_NONE, NULL, 0x0,
949 "Repeat Interval", HFILL }},
950 { &hf_repeat_time_duration,
952 "sdp.repeat_time.duration",FT_STRING, BASE_NONE, NULL, 0x0,
953 "Repeat Duration", HFILL }},
954 { &hf_repeat_time_offset,
956 "sdp.repeat_time.offset",FT_STRING, BASE_NONE, NULL, 0x0,
957 "Repeat Offset", HFILL }},
960 "sdp.timezone.time",FT_STRING, BASE_NONE, NULL, 0x0,
961 "Timezone Time", HFILL }},
962 { &hf_timezone_offset,
964 "sdp.timezone.offset",FT_STRING, BASE_NONE, NULL, 0x0,
965 "Timezone Offset", HFILL }},
966 { &hf_encryption_key_type,
968 "sdp.encryption_key.type",FT_STRING, BASE_NONE, NULL, 0x0,
970 { &hf_encryption_key_data,
972 "sdp.encryption_key.data",FT_STRING, BASE_NONE, NULL, 0x0,
974 { &hf_session_attribute_field,
975 { "Session Attribute Fieldname",
976 "sdp.session_attr.field",FT_STRING, BASE_NONE, NULL, 0x0,
977 "Session Attribute Fieldname", HFILL }},
978 { &hf_session_attribute_value,
979 { "Session Attribute Value",
980 "sdp.session_attr.value",FT_STRING, BASE_NONE, NULL, 0x0,
981 "Session Attribute Value", HFILL }},
984 "sdp.media.media",FT_STRING, BASE_NONE, NULL, 0x0,
985 "Media Type", HFILL }},
988 "sdp.media.port",FT_STRING, BASE_NONE, NULL, 0x0,
989 "Media Port", HFILL }},
990 { &hf_media_portcount,
991 { "Media Port Count",
992 "sdp.media.portcount",FT_STRING, BASE_NONE, NULL, 0x0,
993 "Media Port Count", HFILL }},
996 "sdp.media.proto",FT_STRING, BASE_NONE, NULL, 0x0,
997 "Media Proto", HFILL }},
1000 "sdp.media.format",FT_STRING, BASE_NONE, NULL, 0x0,
1001 "Media Format", HFILL }},
1002 { &hf_media_attribute_field,
1003 { "Media Attribute Fieldname",
1004 "sdp.media_attribute.field",FT_STRING, BASE_NONE, NULL, 0x0,
1005 "Media Attribute Fieldname", HFILL }},
1006 { &hf_media_attribute_value,
1007 { "Media Attribute Value",
1008 "sdp.media_attribute.value",FT_STRING, BASE_NONE, NULL, 0x0,
1009 "Media Attribute Value", HFILL }},
1012 static gint *ett[] = {
1015 &ett_sdp_connection_info,
1018 &ett_sdp_repeat_time,
1020 &ett_sdp_encryption_key,
1021 &ett_sdp_session_attribute,
1023 &ett_sdp_media_attribute,
1026 proto_sdp = proto_register_protocol("Session Description Protocol",
1028 proto_register_field_array(proto_sdp, hf, array_length(hf));
1029 proto_register_subtree_array(ett, array_length(ett));
1032 * Register the dissector by name, so other dissectors can
1033 * grab it by name rather than just referring to it directly
1034 * (you can't refer to it directly from a plugin dissector
1035 * on Windows without stuffing it into the Big Transfer Vector).
1037 register_dissector("sdp", dissect_sdp, proto_sdp);