Move the pointer to the "column_info" structure in the "frame_data"
[obnox/wireshark/wip.git] / packet-sdp.c
1 /* packet-sdp.c
2  * Routines for SDP packet disassembly (RFC 2327)
3  *
4  * Jason Lango <jal@netapp.com>
5  * Liberally copied from packet-http.c, by Guy Harris <guy@alum.mit.edu>
6  *
7  * $Id: packet-sdp.c,v 1.21 2001/12/10 00:25:34 guy Exp $
8  *
9  * Ethereal - Network traffic analyzer
10  * By Gerald Combs <gerald@ethereal.com>
11  * Copyright 1998 Gerald Combs
12  * 
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.
17  * 
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.
22  * 
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.
26  */
27
28 #include "config.h"
29
30 #ifdef HAVE_SYS_TYPES_H
31 #include <sys/types.h>
32 #endif
33
34 #include <string.h>
35 #include <ctype.h>
36
37 #include <glib.h>
38 #include "packet.h"
39 #include "strutil.h"
40
41 static int proto_sdp = -1;
42
43 static int ett_sdp = -1;
44
45 static void
46 dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
47 {
48         proto_tree      *sdp_tree;
49         proto_item      *ti;
50         gint            offset = 0;
51         const u_char    *line;
52         gint            next_offset;
53         int             linelen;
54         u_char          section;
55         u_char          type;
56         const u_char    *value;
57         int             valuelen;
58         const char      *typename;
59         int             datalen;
60
61         /*
62          * As RFC 2327 says, "SDP is purely a format for session
63          * description - it does not incorporate a transport protocol,
64          * and is intended to use different transport protocols as
65          * appropriate including the Session Announcement Protocol,
66          * Session Initiation Protocol, Real-Time Streaming Protocol,
67          * electronic mail using the MIME extensions, and the
68          * Hypertext Transport Protocol."
69          *
70          * We therefore don't set the protocol or info columns;
71          * instead, we append to them, so that we don't erase
72          * what the protocol inside which the SDP stuff resides
73          * put there.
74          */
75         if (check_col(pinfo->cinfo, COL_PROTOCOL))
76                 col_append_str(pinfo->cinfo, COL_PROTOCOL, "/SDP");
77
78         if (check_col(pinfo->cinfo, COL_INFO)) {
79                 /* XXX: Needs description. */
80                 col_append_str(pinfo->cinfo, COL_INFO, ", with session description");
81         }
82
83         if (!tree)
84                 return;
85
86         ti = proto_tree_add_item(tree, proto_sdp, tvb, offset,
87             tvb_length_remaining(tvb, offset), FALSE);
88         sdp_tree = proto_item_add_subtree(ti, ett_sdp);
89
90         /*
91          * Show the SDP message a line at a time.
92          */
93         section = 0;
94         while (tvb_offset_exists(tvb, offset)) {
95                 /*
96                  * Find the end of the line.
97                  */
98                 linelen = tvb_find_line_end_unquoted(tvb, offset, -1,
99                     &next_offset);
100
101                 /*
102                  * Line must contain at least e.g. "v=".
103                  */
104                 if (linelen < 2)
105                         break;
106
107                 line = tvb_get_ptr(tvb, offset, next_offset - offset);
108                 type = line[0];
109                 if (line[1] != '=') {
110                         proto_tree_add_text(sdp_tree, tvb, offset,
111                             next_offset - offset,
112                             "Invalid line: %s",
113                             tvb_format_text(tvb, offset, next_offset - offset));
114                         offset = next_offset;
115                         continue;
116                 }
117                 value = line + 2;
118                 valuelen = linelen - 2;
119
120                 /*
121                  * Attributes.
122                  */
123                 switch (type) {
124                 case 'v':
125                         section = 'v';
126                         typename = "Session Description, version";
127                         break;
128                 case 'o':
129                         typename = "Owner/Creator, Session Id";
130                         break;
131                 case 's':
132                         typename = "Session Name";
133                         break;
134                 case 'i':
135                         if (section == 'v')
136                                 typename = "Session Information";
137                         else if (section == 'm')
138                                 typename = "Media Title";
139                         else
140                                 typename = "Misplaced";
141                         break;
142                 case 'u':
143                         typename = "URI of Description";
144                         break;
145                 case 'e':
146                         typename = "E-mail Address";
147                         break;
148                 case 'p':
149                         typename = "Phone Number";
150                         break;
151                 case 'c':
152                         typename = "Connection Information";
153                         break;
154                 case 'b':
155                         typename = "Bandwidth Information";
156                         break;
157                 case 't':
158                         section = 't';
159                         typename = "Time Description, active time";
160                         break;
161                 case 'r':
162                         typename = "Repeat Time";
163                         break;
164                 case 'm':
165                         section = 'm';
166                         typename = "Media Description, name and address";
167                         break;
168                 case 'k':
169                         typename = "Encryption Key";
170                         break;
171                 case 'a':
172                         if (section == 'v')
173                                 typename = "Session Attribute";
174                         else if (section == 'm')
175                                 typename = "Media Attribute";
176                         else
177                                 typename = "Misplaced";
178                         break;
179                 case 'z':
180                         typename = "Time Zone Adjustment";
181                         break;
182                 default:
183                         typename = "Unknown";
184                         break;
185                 }
186
187                 proto_tree_add_text(sdp_tree, tvb, offset,
188                     next_offset - offset,
189                     "%s (%c): %s", typename, type,
190                     format_text(value, valuelen));
191                 offset = next_offset;
192         }
193
194         datalen = tvb_length_remaining(tvb, offset);
195         if (datalen > 0) {
196                 proto_tree_add_text(sdp_tree, tvb, offset, datalen,
197                     "Data (%d bytes)", datalen);
198         }
199 }
200
201 void
202 proto_register_sdp(void)
203 {
204 /*        static hf_register_info hf[] = {
205                 { &variable,
206                 { "Name",           "sdp.abbreviation", TYPE, VALS_POINTER }},
207         };*/
208         static gint *ett[] = {
209                 &ett_sdp,
210         };
211
212         proto_sdp = proto_register_protocol("Session Description Protocol",
213             "SDP", "sdp");
214  /*       proto_register_field_array(proto_sdp, hf, array_length(hf));*/
215         proto_register_subtree_array(ett, array_length(ett));
216
217         /*
218          * Register the dissector by name, so other dissectors can
219          * grab it by name rather than just referring to it directly
220          * (you can't refer to it directly from a plugin dissector
221          * on Windows without stuffing it into the Big Transfer Vector).
222          */
223         register_dissector("sdp", dissect_sdp, proto_sdp);
224 }