From Bernd Leibing: catch another place where we weren't checking
[obnox/wireshark/wip.git] / packet-sdp.c
index 74ee22849daf5d3e992bcbb8d4529f78b9014c34..301785b03c401689e1f41527ad84077d6661edb5 100644 (file)
@@ -4,22 +4,22 @@
  * Jason Lango <jal@netapp.com>
  * Liberally copied from packet-http.c, by Guy Harris <guy@alum.mit.edu>
  *
- * $Id: packet-sdp.c,v 1.24 2001/12/15 20:22:47 hagbard Exp $
+ * $Id: packet-sdp.c,v 1.34 2003/06/12 08:33:29 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
  * Copyright 1998 Gerald Combs
- * 
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  * of the License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "config.h"
 
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
 #include <string.h>
 #include <ctype.h>
 
 #include <glib.h>
-#include "packet.h"
-#include "strutil.h"
+#include <epan/packet.h>
+#include <epan/strutil.h>
 
 static int proto_sdp = -1;
 
@@ -59,7 +55,6 @@ static int hf_repeat_time = -1;
 static int hf_media = -1;
 static int hf_media_title = -1;
 static int hf_unknown = -1;
-static int hf_misplaced = -1;
 static int hf_invalid = -1;
 
 /* hf_owner subfields*/
@@ -128,30 +123,19 @@ static int ett_sdp_media_attribute = -1;
 
 /* static functions */
 
-static void call_sdp_subdissector(tvbuff_t *tvb, packet_info *pinfo, 
-                                 proto_tree *tree, int hf, proto_tree* ti);
+static void call_sdp_subdissector(tvbuff_t *tvb, int hf, proto_tree* ti);
 
 /* Subdissector functions */
-static void dissect_sdp_owner(tvbuff_t *tvb, packet_info *pinfo, 
-                             proto_tree *tree, proto_item* ti);
-static void dissect_sdp_connection_info(tvbuff_t *tvb, packet_info *pinfo,
-                                       proto_tree *tree, proto_item* ti);
-static void dissect_sdp_bandwidth(tvbuff_t *tvb, packet_info *pinfo,
-                                 proto_tree *tree, proto_item *ti);
-static void dissect_sdp_time(tvbuff_t *tvb, packet_info *pinfo,
-                            proto_tree *tree, proto_item* ti);
-static void dissect_sdp_repeat_time(tvbuff_t *tvb, packet_info *pinfo,
-                                   proto_tree *tree, proto_item* ti);
-static void dissect_sdp_timezone(tvbuff_t *tvb, packet_info *pinfo,
-                                proto_tree *tree, proto_item* ti);
-static void dissect_sdp_encryption_key(tvbuff_t *tvb, packet_info *pinfo,
-                                      proto_tree *tree, proto_item * ti);
-static void dissect_sdp_session_attribute(tvbuff_t *tvb, packet_info *pinfo,
-                                 proto_tree *tree,proto_item *ti);
-static void dissect_sdp_media(tvbuff_t *tvb, packet_info *pinfo,
-                             proto_tree *tree, proto_item *ti);
-static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo,
-                                 proto_tree *tree,proto_item *ti);
+static void dissect_sdp_owner(tvbuff_t *tvb, proto_item* ti);
+static void dissect_sdp_connection_info(tvbuff_t *tvb, proto_item* ti);
+static void dissect_sdp_bandwidth(tvbuff_t *tvb, proto_item *ti);
+static void dissect_sdp_time(tvbuff_t *tvb, proto_item* ti);
+static void dissect_sdp_repeat_time(tvbuff_t *tvb, proto_item* ti);
+static void dissect_sdp_timezone(tvbuff_t *tvb, proto_item* ti);
+static void dissect_sdp_encryption_key(tvbuff_t *tvb, proto_item * ti);
+static void dissect_sdp_session_attribute(tvbuff_t *tvb, proto_item *ti);
+static void dissect_sdp_media(tvbuff_t *tvb, proto_item *ti);
+static void dissect_sdp_media_attribute(tvbuff_t *tvb, proto_item *ti);
 
 static void
 dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
@@ -161,12 +145,13 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        gint            offset = 0;
        gint            next_offset;
        int             linelen;
-       u_char          section;
-       u_char          type;
-       u_char          delim;
+       gboolean        in_media_description;
+       guchar          type;
+       guchar          delim;
        int             datalen;
        int             tokenoffset;
        int             hf = -1;
+       char            *string;
 
        /*
         * As RFC 2327 says, "SDP is purely a format for session
@@ -193,14 +178,13 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        if (!tree)
                return;
 
-       ti = proto_tree_add_item(tree, proto_sdp, tvb, offset,
-           tvb_length_remaining(tvb, offset), FALSE);
+       ti = proto_tree_add_item(tree, proto_sdp, tvb, offset, -1, FALSE);
        sdp_tree = proto_item_add_subtree(ti, ett_sdp);
 
        /*
         * Show the SDP message a line at a time.
         */
-       section = 0;
+       in_media_description = FALSE;
        while (tvb_offset_exists(tvb, offset)) {
                /*
                 * Find the end of the line.
@@ -217,10 +201,8 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                type = tvb_get_guint8(tvb,offset);
                delim = tvb_get_guint8(tvb,offset + 1);
                if (delim != '=') {
-                       proto_tree_add_string(sdp_tree,hf_invalid,tvb, offset,
-                                             linelen,
-                                             tvb_format_text(tvb,
-                                                             offset,linelen));
+                       proto_tree_add_item(sdp_tree,hf_invalid,tvb, offset,
+                                             linelen, FALSE);
                         offset = next_offset;
                        continue;
                }
@@ -231,7 +213,6 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                switch (type) {
                case 'v':
                        hf = hf_protocol_version;
-                       section = 'v';
                        break;
                case 'o':
                        hf = hf_owner;
@@ -240,14 +221,11 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                        hf = hf_session_name;
                        break;
                case 'i':
-                       if (section == 'v'){
-                               hf = hf_session_info;
-                       }
-                       else if (section == 'm'){
+                       if (in_media_description) {
                                hf = hf_media_title;
                        }
                        else{
-                               hf = hf_misplaced;
+                               hf = hf_session_info;
                        }
                        break;
                case 'u':
@@ -267,27 +245,23 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                        break;
                case 't':
                        hf = hf_time;
-                       section = 't';
                        break;
                case 'r':
                        hf = hf_repeat_time;
                        break;
                case 'm':
                        hf = hf_media;
-                       section = 'm';
+                       in_media_description = TRUE;
                        break;
                case 'k':
                        hf = hf_encryption_key;
                        break;
                case 'a':
-                       if (section == 'v'){
-                               hf = hf_session_attribute; 
-                       }
-                       else if (section == 'm'){
+                       if (in_media_description) {
                                hf = hf_media_attribute;
                        }
                        else{
-                               hf = hf_misplaced;
+                               hf = hf_session_attribute;
                        }
                        break;
                case 'z':
@@ -298,16 +272,20 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                        break;
                }
                tokenoffset = 2;
-               if( hf == hf_unknown || hf == hf_misplaced )
-                 tokenoffset = 0;
-               sub_ti = proto_tree_add_string(sdp_tree,hf,tvb, offset, 
-                                              linelen,
-                                              tvb_format_text(tvb,
-                                                     offset+tokenoffset,
-                                                     linelen - tokenoffset));
+               if (hf == hf_unknown)
+                       tokenoffset = 0;
+               string = tvb_get_string(tvb, offset + tokenoffset,
+                   linelen - tokenoffset);
+               sub_ti = proto_tree_add_string_format(sdp_tree,hf,tvb, offset,
+                                              linelen, string,
+                                              "%s: %s",
+                                              proto_registrar_get_name(hf),
+                                              format_text(string,
+                                                linelen - tokenoffset));
+               g_free(string);
                call_sdp_subdissector(tvb_new_subset(tvb,offset+tokenoffset,
                                                     linelen-tokenoffset,-1),
-                                     pinfo,tree,hf,sub_ti);
+                                     hf,sub_ti);
                offset = next_offset;
        }
 
@@ -318,55 +296,50 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        }
 }
 
-static void 
-call_sdp_subdissector(tvbuff_t *tvb, packet_info *pinfo, 
-                     proto_tree *tree, int hf, proto_tree* ti){
+static void
+call_sdp_subdissector(tvbuff_t *tvb, int hf, proto_tree* ti){
   if(hf == hf_owner){
-    dissect_sdp_owner(tvb,pinfo,tree,ti);
+    dissect_sdp_owner(tvb,ti);
   } else if ( hf == hf_connection_info) {
-    dissect_sdp_connection_info(tvb,pinfo,tree,ti);
+    dissect_sdp_connection_info(tvb,ti);
   } else if ( hf == hf_bandwidth) {
-    dissect_sdp_bandwidth(tvb,pinfo,tree,ti);
+    dissect_sdp_bandwidth(tvb,ti);
   } else if ( hf == hf_time) {
-    dissect_sdp_time(tvb,pinfo,tree,ti);
+    dissect_sdp_time(tvb,ti);
   } else if ( hf == hf_repeat_time ){
-    dissect_sdp_repeat_time(tvb,pinfo,tree,ti);
+    dissect_sdp_repeat_time(tvb,ti);
   } else if ( hf == hf_timezone ) {
-    dissect_sdp_timezone(tvb,pinfo,tree,ti);
+    dissect_sdp_timezone(tvb,ti);
   } else if ( hf == hf_encryption_key ) {
-    dissect_sdp_encryption_key(tvb,pinfo,tree,ti);
+    dissect_sdp_encryption_key(tvb,ti);
   } else if ( hf == hf_session_attribute ){
-    dissect_sdp_session_attribute(tvb,pinfo,tree,ti);
+    dissect_sdp_session_attribute(tvb,ti);
   } else if ( hf == hf_media ) {
-    dissect_sdp_media(tvb,pinfo,tree,ti);
+    dissect_sdp_media(tvb,ti);
   } else if ( hf == hf_media_attribute ){
-    dissect_sdp_media_attribute(tvb,pinfo,tree,ti);
+    dissect_sdp_media_attribute(tvb,ti);
   }
 }
 
-static void 
-dissect_sdp_owner(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                 proto_item *ti){
+static void
+dissect_sdp_owner(tvbuff_t *tvb, proto_item *ti){
   proto_tree *sdp_owner_tree;
   gint offset,next_offset,tokenlen;
 
-  if(!tree)
-    return;
-  
   offset = 0;
   next_offset = 0;
   tokenlen = 0;
 
   sdp_owner_tree = proto_item_add_subtree(ti,ett_sdp_owner);
-  
+
   /* Find the username */
   next_offset = tvb_find_guint8(tvb,offset,-1,' ');
   if( next_offset == -1 )
     return;
   tokenlen = next_offset - offset;
 
-  proto_tree_add_string(sdp_owner_tree,hf_owner_username,tvb, offset,tokenlen,
-                       tvb_format_text(tvb,offset,tokenlen));
+  proto_tree_add_item(sdp_owner_tree,hf_owner_username,tvb, offset,tokenlen,
+                     FALSE);
   offset = next_offset  + 1;
 
   /* Find the session id */
@@ -375,9 +348,8 @@ dissect_sdp_owner(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
     return;
   tokenlen = next_offset - offset;
 
-  proto_tree_add_string(sdp_owner_tree,hf_owner_sessionid, tvb, 
-                       offset,tokenlen,
-                       tvb_format_text(tvb,offset,tokenlen));
+  proto_tree_add_item(sdp_owner_tree,hf_owner_sessionid, tvb,
+                     offset,tokenlen,FALSE);
   offset = next_offset + 1;
 
   /* Find the version */
@@ -386,8 +358,8 @@ dissect_sdp_owner(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
     return;
   tokenlen = next_offset - offset;
 
-  proto_tree_add_string(sdp_owner_tree,hf_owner_version, tvb, offset,tokenlen,
-                       tvb_format_text(tvb,offset,tokenlen));
+  proto_tree_add_item(sdp_owner_tree,hf_owner_version, tvb,
+                     offset,tokenlen,FALSE);
   offset = next_offset + 1;
 
   /* Find the network type */
@@ -396,56 +368,45 @@ dissect_sdp_owner(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
     return;
   tokenlen = next_offset - offset;
 
-  proto_tree_add_string(sdp_owner_tree,hf_owner_network_type, tvb, 
-                       offset,tokenlen,
-                       tvb_format_text(tvb,offset,tokenlen));
+  proto_tree_add_item(sdp_owner_tree,hf_owner_network_type, tvb,
+                     offset,tokenlen,FALSE);
   offset = next_offset + 1;
-  
+
   /* Find the address type */
   next_offset = tvb_find_guint8(tvb,offset,-1,' ');
   if( next_offset == -1 )
     return;
   tokenlen = next_offset - offset;
 
-  proto_tree_add_string(sdp_owner_tree,hf_owner_address_type, tvb, 
-                       offset,tokenlen,
-                       tvb_format_text(tvb,offset,tokenlen));
+  proto_tree_add_item(sdp_owner_tree,hf_owner_address_type, tvb,
+                     offset,tokenlen,FALSE);
   offset = next_offset + 1;
 
   /* Find the address */
-  tokenlen = tvb_length_remaining(tvb,offset);
-
-  proto_tree_add_string(sdp_owner_tree,hf_owner_address, tvb, 
-                       offset,tokenlen,
-                       tvb_format_text(tvb,offset,tokenlen));
+  proto_tree_add_item(sdp_owner_tree,hf_owner_address, tvb, offset, -1, FALSE);
 }
 
-static void 
-dissect_sdp_connection_info(tvbuff_t *tvb, packet_info *pinfo,
-                           proto_tree *tree, proto_item* ti){
+static void
+dissect_sdp_connection_info(tvbuff_t *tvb, proto_item* ti){
   proto_tree *sdp_connection_info_tree;
   gint offset,next_offset,tokenlen;
 
-  if(!tree)
-    return;
-  
   offset = 0;
   next_offset = 0;
   tokenlen = 0;
-  
+
   sdp_connection_info_tree = proto_item_add_subtree(ti,
                                                    ett_sdp_connection_info);
-  
+
   /* Find the network type */
   next_offset = tvb_find_guint8(tvb,offset,-1,' ');
   if( next_offset == -1 )
     return;
   tokenlen = next_offset - offset;
 
-  proto_tree_add_string(sdp_connection_info_tree,
-                       hf_connection_info_network_type,tvb, 
-                       offset,tokenlen,
-                       tvb_format_text(tvb,offset,tokenlen));
+  proto_tree_add_item(sdp_connection_info_tree,
+                     hf_connection_info_network_type,tvb,
+                     offset,tokenlen,FALSE);
   offset = next_offset + 1;
 
   /* Find the address type */
@@ -454,53 +415,44 @@ dissect_sdp_connection_info(tvbuff_t *tvb, packet_info *pinfo,
     return;
   tokenlen = next_offset - offset;
 
-  proto_tree_add_string(sdp_connection_info_tree,
-                       hf_connection_info_address_type,tvb, 
-                       offset,tokenlen,
-                       tvb_format_text(tvb,offset,tokenlen));
+  proto_tree_add_item(sdp_connection_info_tree,
+                     hf_connection_info_address_type,tvb,
+                     offset,tokenlen,FALSE);
   offset = next_offset + 1;
 
   /* Find the connection address */
   next_offset = tvb_find_guint8(tvb,offset,-1,'/');
   if( next_offset == -1){
-    tokenlen = tvb_length_remaining(tvb,offset);
+    tokenlen = -1;     /* end of tvbuff */
   } else {
     tokenlen = next_offset - offset;
   }
-  proto_tree_add_string(sdp_connection_info_tree,
-                       hf_connection_info_connection_address, tvb, 
-                       offset,tokenlen,
-                       tvb_format_text(tvb,offset,tokenlen));
+  proto_tree_add_item(sdp_connection_info_tree,
+                     hf_connection_info_connection_address, tvb,
+                     offset,tokenlen,FALSE);
   if(next_offset != -1){
     offset = next_offset + 1;
     next_offset = tvb_find_guint8(tvb,offset,-1,'/');
     if( next_offset == -1){
-      tokenlen = tvb_length_remaining(tvb,offset);
+      tokenlen = -1;   /* end of tvbuff */
     } else {
       tokenlen = next_offset - offset;
     }
-    proto_tree_add_string(sdp_connection_info_tree,
-                         hf_connection_info_ttl,tvb,offset,tokenlen,
-                         tvb_format_text(tvb,offset,tokenlen));
+    proto_tree_add_item(sdp_connection_info_tree,
+                       hf_connection_info_ttl,tvb,offset,tokenlen,FALSE);
     if(next_offset != -1){
       offset = next_offset + 1;
-      tokenlen = tvb_length_remaining(tvb,offset);
-      proto_tree_add_string(sdp_connection_info_tree,
-                           hf_connection_info_num_addr, tvb,
-                           offset, tokenlen,
-                           tvb_format_text(tvb,offset,tokenlen));
+      proto_tree_add_item(sdp_connection_info_tree,
+                         hf_connection_info_num_addr, tvb,
+                         offset, -1, FALSE);
     }
   }
 }
 
-static void 
-dissect_sdp_bandwidth(tvbuff_t *tvb, packet_info *pinfo,
-                     proto_tree *tree,proto_item *ti){
+static void
+dissect_sdp_bandwidth(tvbuff_t *tvb, proto_item *ti){
   proto_tree * sdp_bandwidth_tree;
   gint offset, next_offset, tokenlen;
-  
-  if(!tree)
-    return;
 
   offset = 0;
   next_offset = 0;
@@ -513,35 +465,27 @@ dissect_sdp_bandwidth(tvbuff_t *tvb, packet_info *pinfo,
 
   if( next_offset == -1)
     return;
-  
+
   tokenlen = next_offset - offset;
-  
-  proto_tree_add_string(sdp_bandwidth_tree, hf_bandwidth_modifier,
-                       tvb, offset, tokenlen, 
-                       tvb_format_text(tvb,offset,tokenlen));
+
+  proto_tree_add_item(sdp_bandwidth_tree, hf_bandwidth_modifier,
+                     tvb, offset, tokenlen, FALSE);
 
   offset = next_offset + 1;
-  
-  tokenlen = tvb_length_remaining(tvb,offset);
-  
-  proto_tree_add_string(sdp_bandwidth_tree, hf_bandwidth_value,
-                       tvb, offset, tokenlen,
-                       tvb_format_text(tvb,offset,tokenlen));
+
+  proto_tree_add_item(sdp_bandwidth_tree, hf_bandwidth_value,
+                     tvb, offset, -1, FALSE);
 
 }
 
-static void dissect_sdp_time(tvbuff_t *tvb, packet_info *pinfo,
-                            proto_tree *tree, proto_item* ti){
+static void dissect_sdp_time(tvbuff_t *tvb, proto_item* ti){
   proto_tree *sdp_time_tree;
   gint offset,next_offset, tokenlen;
 
-  if(!tree)
-    return;
-  
   offset = 0;
   next_offset = 0;
   tokenlen = 0;
-  
+
   sdp_time_tree = proto_item_add_subtree(ti,ett_sdp_time);
 
   /* get start time */
@@ -550,30 +494,23 @@ static void dissect_sdp_time(tvbuff_t *tvb, packet_info *pinfo,
     return;
 
   tokenlen = next_offset - offset;
-  proto_tree_add_string(sdp_time_tree, hf_time_start, tvb,
-                       offset, tokenlen, 
-                       tvb_format_text(tvb,offset,tokenlen));
+  proto_tree_add_item(sdp_time_tree, hf_time_start, tvb,
+                     offset, tokenlen, FALSE);
 
   /* get stop time */
   offset = next_offset + 1;
-  tokenlen = tvb_length_remaining(tvb,offset);
-  proto_tree_add_string(sdp_time_tree,hf_time_start, tvb,
-                       offset, tokenlen,
-                       tvb_format_text(tvb,offset,tokenlen));
+  proto_tree_add_item(sdp_time_tree,hf_time_start, tvb,
+                     offset, -1, FALSE);
 }
 
-static void dissect_sdp_repeat_time(tvbuff_t *tvb, packet_info *pinfo,
-                                   proto_tree *tree, proto_item* ti){
+static void dissect_sdp_repeat_time(tvbuff_t *tvb, proto_item* ti){
   proto_tree *sdp_repeat_time_tree;
   gint offset,next_offset, tokenlen;
 
-  if(!tree)
-    return;
-  
   offset = 0;
   next_offset = 0;
   tokenlen = 0;
-  
+
   sdp_repeat_time_tree = proto_item_add_subtree(ti,ett_sdp_time);
 
   /* get interval */
@@ -582,9 +519,8 @@ static void dissect_sdp_repeat_time(tvbuff_t *tvb, packet_info *pinfo,
     return;
 
   tokenlen = next_offset - offset;
-  proto_tree_add_string(sdp_repeat_time_tree, hf_repeat_time_interval, tvb,
-                       offset, tokenlen, 
-                       tvb_format_text(tvb,offset,tokenlen));
+  proto_tree_add_item(sdp_repeat_time_tree, hf_repeat_time_interval, tvb,
+                     offset, tokenlen, FALSE);
 
   /* get duration */
   offset = next_offset + 1;
@@ -593,9 +529,8 @@ static void dissect_sdp_repeat_time(tvbuff_t *tvb, packet_info *pinfo,
     return;
 
   tokenlen = next_offset - offset;
-  proto_tree_add_string(sdp_repeat_time_tree,hf_repeat_time_duration, tvb,
-                       offset, tokenlen,
-                       tvb_format_text(tvb,offset,tokenlen));
+  proto_tree_add_item(sdp_repeat_time_tree,hf_repeat_time_duration, tvb,
+                     offset, tokenlen, FALSE);
 
   /* get offsets */
   do{
@@ -604,54 +539,47 @@ static void dissect_sdp_repeat_time(tvbuff_t *tvb, packet_info *pinfo,
     if(next_offset != -1){
       tokenlen = next_offset - offset;
     } else {
-      tokenlen = tvb_length_remaining(tvb,offset);
+      tokenlen = -1;   /* end of tvbuff */
     }
-    proto_tree_add_string(sdp_repeat_time_tree, hf_repeat_time_offset,
-                         tvb, offset, tokenlen,
-                         tvb_format_text(tvb,offset,tokenlen));
+    proto_tree_add_item(sdp_repeat_time_tree, hf_repeat_time_offset,
+                       tvb, offset, tokenlen, FALSE);
   } while( next_offset != -1 );
-  
+
 }
-static void 
-dissect_sdp_timezone(tvbuff_t *tvb, packet_info *pinfo,
-                    proto_tree *tree, proto_item* ti){
+static void
+dissect_sdp_timezone(tvbuff_t *tvb, proto_item* ti){
   proto_tree* sdp_timezone_tree;
   gint offset, next_offset, tokenlen;
-  if(!tree)
-    return;
   offset = 0;
   next_offset = 0;
   tokenlen = 0;
-  
+
   sdp_timezone_tree = proto_item_add_subtree(ti,ett_sdp_timezone);
-  
+
   do{
     next_offset = tvb_find_guint8(tvb,offset,-1,' ');
     if(next_offset == -1)
       break;
     tokenlen = next_offset - offset;
-    
-    proto_tree_add_string(sdp_timezone_tree,hf_timezone_time,tvb,
-                         offset, tokenlen,
-                         tvb_format_text(tvb,offset,tokenlen));
+
+    proto_tree_add_item(sdp_timezone_tree,hf_timezone_time,tvb,
+                       offset, tokenlen, FALSE);
     offset = next_offset + 1;
     next_offset = tvb_find_guint8(tvb,offset,-1,' ');
     if(next_offset != -1){
       tokenlen = next_offset - offset;
     } else {
-      tokenlen = tvb_length_remaining(tvb,offset);
+      tokenlen = -1;   /* end of tvbuff */
     }
-    proto_tree_add_string(sdp_timezone_tree,hf_timezone_offset,tvb,
-                         offset, tokenlen,
-                         tvb_format_text(tvb,offset,tokenlen));
+    proto_tree_add_item(sdp_timezone_tree,hf_timezone_offset,tvb,
+                       offset, tokenlen, FALSE);
     offset = next_offset + 1;
   } while (next_offset != -1);
-    
+
 }
 
 
-static void dissect_sdp_encryption_key(tvbuff_t *tvb, packet_info *pinfo,
-                                      proto_tree *tree, proto_item * ti){
+static void dissect_sdp_encryption_key(tvbuff_t *tvb, proto_item * ti){
   proto_tree *sdp_encryption_key_tree;
   gint offset, next_offset, tokenlen;
 
@@ -667,23 +595,19 @@ static void dissect_sdp_encryption_key(tvbuff_t *tvb, packet_info *pinfo,
     return;
 
   tokenlen = next_offset - offset;
-  
-  proto_tree_add_string(sdp_encryption_key_tree,hf_encryption_key_type,
-                       tvb, offset, tokenlen, 
-                       tvb_format_text(tvb,offset,tokenlen));
-  
+
+  proto_tree_add_item(sdp_encryption_key_tree,hf_encryption_key_type,
+                     tvb, offset, tokenlen, FALSE);
+
   offset = next_offset + 1;
-  tokenlen = tvb_length_remaining(tvb,offset);
-  proto_tree_add_string(sdp_encryption_key_tree,hf_encryption_key_data,
-                       tvb, offset, tokenlen,
-                       tvb_format_text(tvb,offset,tokenlen));
+  proto_tree_add_item(sdp_encryption_key_tree,hf_encryption_key_data,
+                     tvb, offset, -1, FALSE);
 
 }
 
 
 
-static void dissect_sdp_session_attribute(tvbuff_t *tvb, packet_info *pinfo,
-                                         proto_tree *tree, proto_item * ti){
+static void dissect_sdp_session_attribute(tvbuff_t *tvb, proto_item * ti){
   proto_tree *sdp_session_attribute_tree;
   gint offset, next_offset, tokenlen;
 
@@ -700,30 +624,23 @@ static void dissect_sdp_session_attribute(tvbuff_t *tvb, packet_info *pinfo,
     return;
 
   tokenlen = next_offset - offset;
-  
-  proto_tree_add_string(sdp_session_attribute_tree,
-                       hf_session_attribute_field,
-                       tvb, offset, tokenlen, 
-                       tvb_format_text(tvb,offset,tokenlen));
-  
+
+  proto_tree_add_item(sdp_session_attribute_tree,
+                     hf_session_attribute_field,
+                     tvb, offset, tokenlen, FALSE);
+
   offset = next_offset + 1;
-  tokenlen = tvb_length_remaining(tvb,offset);
-  proto_tree_add_string(sdp_session_attribute_tree,
-                       hf_session_attribute_value,
-                       tvb, offset, tokenlen,
-                       tvb_format_text(tvb,offset,tokenlen));
+  proto_tree_add_item(sdp_session_attribute_tree,
+                     hf_session_attribute_value,
+                     tvb, offset, -1, FALSE);
 
 }
 
-static void 
-dissect_sdp_media(tvbuff_t *tvb, packet_info *pinfo,
-                 proto_tree *tree, proto_item *ti){
+static void
+dissect_sdp_media(tvbuff_t *tvb, proto_item *ti){
   proto_tree *sdp_media_tree;
   gint offset, next_offset, tokenlen;
 
-  if(!tree)
-    return;
-  
   offset = 0;
   next_offset = 0;
   tokenlen = 0;
@@ -731,15 +648,14 @@ dissect_sdp_media(tvbuff_t *tvb, packet_info *pinfo,
   sdp_media_tree = proto_item_add_subtree(ti,ett_sdp_media);
 
   next_offset = tvb_find_guint8(tvb,offset, -1, ' ');
-  
+
   if(next_offset == -1)
     return;
 
   tokenlen = next_offset - offset;
-  
-  proto_tree_add_string(sdp_media_tree, hf_media_media, tvb, 
-                       offset ,tokenlen, 
-                       tvb_format_text(tvb,offset,tokenlen));
+
+  proto_tree_add_item(sdp_media_tree, hf_media_media, tvb,
+                     offset, tokenlen, FALSE);
 
   offset = next_offset + 1;
 
@@ -748,65 +664,59 @@ dissect_sdp_media(tvbuff_t *tvb, packet_info *pinfo,
     return;
   tokenlen = next_offset - offset;
   next_offset = tvb_find_guint8(tvb,offset, tokenlen, '/');
-  
+
   if(next_offset != -1){
     tokenlen = next_offset - offset;
-  
-    proto_tree_add_string(sdp_media_tree, hf_media_port, tvb, 
-                         offset ,tokenlen, 
-                         tvb_format_text(tvb,offset,tokenlen));
+
+    proto_tree_add_item(sdp_media_tree, hf_media_port, tvb,
+                       offset, tokenlen, FALSE);
     offset = next_offset + 1;
     next_offset = tvb_find_guint8(tvb,offset, -1, ' ');
     if(next_offset == -1)
       return;
     tokenlen = next_offset - offset;
-    proto_tree_add_string(sdp_media_tree, hf_media_portcount, tvb,
-                         offset, tokenlen,
-                         tvb_format_text(tvb,offset,tokenlen));
+    proto_tree_add_item(sdp_media_tree, hf_media_portcount, tvb,
+                       offset, tokenlen, FALSE);
     offset = next_offset + 1;
   } else {
     next_offset = tvb_find_guint8(tvb,offset, -1, ' ');
-    
+
     if(next_offset == -1)
       return;
     tokenlen = next_offset - offset;
-    
-    proto_tree_add_string(sdp_media_tree, hf_media_port, tvb,
-                         offset, tokenlen,
-                         tvb_format_text(tvb,offset,tokenlen));
+
+    proto_tree_add_item(sdp_media_tree, hf_media_port, tvb,
+                       offset, tokenlen, FALSE);
     offset = next_offset + 1;
   }
 
   next_offset = tvb_find_guint8(tvb,offset,-1,' ');
-  
+
   if( next_offset == -1)
     return;
-  
+
   tokenlen = next_offset - offset;
 
-  proto_tree_add_string(sdp_media_tree, hf_media_proto, tvb,
-                       offset, tokenlen, 
-                       tvb_format_text(tvb,offset, tokenlen));
+  proto_tree_add_item(sdp_media_tree, hf_media_proto, tvb,
+                     offset, tokenlen, FALSE);
 
   do{
     offset = next_offset + 1;
     next_offset = tvb_find_guint8(tvb,offset,-1,' ');
-    
+
     if(next_offset == -1){
-      tokenlen = tvb_length_remaining(tvb,offset);
+      tokenlen = -1;   /* End of tvbuff */
     } else {
       tokenlen = next_offset - offset;
     }
 
-    proto_tree_add_string(sdp_media_tree, hf_media_format, tvb,
-                         offset, tokenlen, 
-                         tvb_format_text(tvb,offset,tokenlen));
+    proto_tree_add_item(sdp_media_tree, hf_media_format, tvb,
+                       offset, tokenlen, FALSE);
   } while (next_offset != -1);
 
 }
 
-static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo,
-                                         proto_tree *tree, proto_item * ti){
+static void dissect_sdp_media_attribute(tvbuff_t *tvb, proto_item * ti){
   proto_tree *sdp_media_attribute_tree;
   gint offset, next_offset, tokenlen;
 
@@ -823,18 +733,15 @@ static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo,
     return;
 
   tokenlen = next_offset - offset;
-  
-  proto_tree_add_string(sdp_media_attribute_tree,
-                       hf_media_attribute_field,
-                       tvb, offset, tokenlen, 
-                       tvb_format_text(tvb,offset,tokenlen));
-  
+
+  proto_tree_add_item(sdp_media_attribute_tree,
+                     hf_media_attribute_field,
+                     tvb, offset, tokenlen, FALSE);
+
   offset = next_offset + 1;
-  tokenlen = tvb_length_remaining(tvb,offset);
-  proto_tree_add_string(sdp_media_attribute_tree,
-                       hf_media_attribute_value,
-                       tvb, offset, tokenlen,
-                       tvb_format_text(tvb,offset,tokenlen));
+  proto_tree_add_item(sdp_media_attribute_tree,
+                     hf_media_attribute_value,
+                     tvb, offset, -1, FALSE);
 
 }
 
@@ -846,7 +753,7 @@ proto_register_sdp(void)
       { "Session Description Protocol Version (v)",
        "sdp.version", FT_STRING, BASE_NONE,NULL,0x0,
        "Session Description Protocol Version", HFILL }},
-    { &hf_owner, 
+    { &hf_owner,
       { "Owner/Creator, Session Id (o)",
        "sdp.owner", FT_STRING, BASE_NONE, NULL, 0x0,
        "Owner/Creator, Session Id", HFILL}},
@@ -855,7 +762,7 @@ proto_register_sdp(void)
        "sdp.session_name", FT_STRING, BASE_NONE,NULL, 0x0,
        "Session Name", HFILL }},
     { &hf_session_info,
-      { "Session Information (i)", 
+      { "Session Information (i)",
        "sdp.session_info", FT_STRING, BASE_NONE, NULL, 0x0,
        "Session Information", HFILL }},
     { &hf_uri,
@@ -863,7 +770,7 @@ proto_register_sdp(void)
        "sdp.uri", FT_STRING, BASE_NONE,NULL, 0x0,
        "URI of Description", HFILL }},
     { &hf_email,
-      { "E-mail Address (e)", 
+      { "E-mail Address (e)",
        "sdp.email", FT_STRING, BASE_NONE, NULL, 0x0,
        "E-mail Address", HFILL }},
     { &hf_phone,
@@ -886,12 +793,12 @@ proto_register_sdp(void)
       { "Encryption Key (k)",
        "sdp.encryption_key", FT_STRING, BASE_NONE, NULL, 0x0,
        "Encryption Key", HFILL }},
-    { &hf_session_attribute, 
-      { "Session Attribute (a)", 
+    { &hf_session_attribute,
+      { "Session Attribute (a)",
        "sdp.session_attr", FT_STRING, BASE_NONE, NULL, 0x0,
        "Session Attribute", HFILL }},
-    { &hf_media_attribute, 
-      { "Media Attribute (a)", 
+    { &hf_media_attribute,
+      { "Media Attribute (a)",
        "sdp.media_attr", FT_STRING, BASE_NONE, NULL, 0x0,
        "Media Attribute", HFILL }},
     { &hf_time,
@@ -914,10 +821,6 @@ proto_register_sdp(void)
       { "Unknown",
        "sdp.unknown",FT_STRING, BASE_NONE, NULL, 0x0,
        "Unknown", HFILL }},
-    { &hf_misplaced,
-      { "Misplaced",
-       "sdp.misplaced",FT_STRING, BASE_NONE, NULL, 0x0,
-       "Misplaced", HFILL }},
     { &hf_invalid,
       { "Invalid line",
        "sdp.invalid",FT_STRING, BASE_NONE, NULL, 0x0,
@@ -969,11 +872,11 @@ proto_register_sdp(void)
     { &hf_bandwidth_modifier,
       { "Bandwidth Modifier",
        "sdp.bandwidth.modifier",FT_STRING, BASE_NONE, NULL, 0x0,
-       "Bandwidth Modifier", HFILL }},    
+       "Bandwidth Modifier", HFILL }},
     { &hf_bandwidth_value,
       { "Bandwidth Value",
        "sdp.bandwidth.value",FT_STRING, BASE_NONE, NULL, 0x0,
-       "Bandwidth Value", HFILL }},    
+       "Bandwidth Value", HFILL }},
     { &hf_time_start,
       { "Session Start Time",
        "sdp.time.start",FT_STRING, BASE_NONE, NULL, 0x0,
@@ -1061,12 +964,12 @@ proto_register_sdp(void)
     &ett_sdp_media,
     &ett_sdp_media_attribute,
   };
-  
+
   proto_sdp = proto_register_protocol("Session Description Protocol",
                                      "SDP", "sdp");
   proto_register_field_array(proto_sdp, hf, array_length(hf));
   proto_register_subtree_array(ett, array_length(ett));
-       
+
   /*
    * Register the dissector by name, so other dissectors can
    * grab it by name rather than just referring to it directly