Get rid of unused variables, and mark unused arguments as such.
[obnox/wireshark/wip.git] / packet-xot.c
1 /* packet-xot.c
2  * Routines for X.25 over TCP dissection (RFC 1613)
3  *
4  * Copyright 2000, Paul Ionescu <paul@acorp.ro>
5  *
6  * $Id: packet-xot.c,v 1.10 2002/04/09 08:15:02 guy Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  * 
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  * 
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <ctype.h>
34
35 #include <string.h>
36 #include <glib.h>
37 #include <epan/packet.h>
38 #include "packet-frame.h"
39 #include "prefs.h"
40
41 #define TCP_PORT_XOT 1998
42
43 static gint proto_xot = -1;
44 static gint hf_xot_version = -1;
45 static gint hf_xot_length = -1;
46
47 static gint ett_xot = -1;
48
49 /* desegmentation of X.25 over TCP */
50 static gboolean xot_desegment = TRUE;
51
52 static dissector_handle_t x25_handle;
53
54 static void dissect_xot(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
55 {
56   volatile int offset = 0;
57   int length_remaining;
58   guint16 version;
59   guint16 plen;
60   int length;
61   proto_item *ti;
62   proto_tree *xot_tree;
63   tvbuff_t   *next_tvb; 
64
65   while (tvb_reported_length_remaining(tvb, offset) != 0) {
66     length_remaining = tvb_length_remaining(tvb, offset);
67
68     /*
69      * Can we do reassembly?
70      */
71     if (xot_desegment && pinfo->can_desegment) {
72       /*
73        * Yes - is the X.25-over-TCP header split across segment boundaries?
74        */
75       if (length_remaining < 4) {
76         /*
77          * Yes.  Tell the TCP dissector where the data for this message
78          * starts in the data it handed us, and how many
79          * more bytes we need, and return.
80          */
81         pinfo->desegment_offset = offset;
82         pinfo->desegment_len = 4 - length_remaining;
83         return;
84       }
85     }
86
87     /*
88      * Get the length of the XOT packet.
89      */
90     version = tvb_get_ntohs(tvb, offset + 0);
91     if (version != 0)
92       return;
93     plen    = tvb_get_ntohs(tvb, offset + 2);
94
95     /*
96      * Can we do reassembly?
97      */
98     if (xot_desegment && pinfo->can_desegment) {
99       /*
100        * Yes - is the XOT packet split across segment boundaries?
101        */
102       if (length_remaining < plen + 4) {
103         /*
104          * Yes.  Tell the TCP dissector where the data for this message
105          * starts in the data it handed us, and how many more bytes we
106          * need, and return.
107          */
108         pinfo->desegment_offset = offset;
109         pinfo->desegment_len = (plen + 4) - length_remaining;
110         return;
111       }
112     }
113
114     /*
115      * Dissect the X.25-over-TCP packet.
116      *
117      * Catch the ReportedBoundsError exception; if this particular message
118      * happens to get a ReportedBoundsError exception, that doesn't mean
119      * that we should stop dissecting X.25-over-TCP messages within this
120      * frame or chunk of reassembled data.
121      *
122      * If it gets a BoundsError, we can stop, as there's nothing more to see,
123      * so we just re-throw it.
124      */
125     TRY {
126       if (check_col(pinfo->cinfo, COL_PROTOCOL))
127         col_set_str(pinfo->cinfo, COL_PROTOCOL, "XOT");
128       if (check_col(pinfo->cinfo, COL_INFO)) 
129         col_add_fstr(pinfo->cinfo, COL_INFO, "XOT Version = %u, size = %u",
130                      version,plen );
131
132       if (tree) {
133         ti = proto_tree_add_protocol_format(tree, proto_xot, tvb, offset, 4,
134                                             "X.25 over TCP");
135         xot_tree = proto_item_add_subtree(ti, ett_xot);
136      
137         proto_tree_add_uint(xot_tree, hf_xot_version, tvb, offset, 2, version);
138         proto_tree_add_uint(xot_tree, hf_xot_length, tvb, offset + 2, 2, plen);
139       }
140
141       /*
142        * Construct a tvbuff containing the amount of the payload we have
143        * available.  Make its reported length the amount of data in the
144        * X.25-over-TCP packet.
145        *
146        * XXX - if reassembly isn't enabled. the subdissector will throw a
147        * BoundsError exception, rather than a ReportedBoundsError exception.
148        * We really want a tvbuff where the length is "length", the reported
149        * length is "plen + 4", and the "if the snapshot length were infinite"
150        * length is the minimum of the reported length of the tvbuff handed
151        * to us and "plen+4", with a new type of exception thrown if the offset
152        * is within the reported length but beyond that third length, with that
153        * exception getting the "Unreassembled Packet" error.
154        */
155       length = length_remaining - 4;
156       if (length > plen)
157         length = plen;
158       next_tvb = tvb_new_subset(tvb, offset + 4, length, plen);
159       call_dissector(x25_handle,next_tvb,pinfo,tree);
160     }
161     CATCH(BoundsError) {
162       RETHROW;
163     }
164     CATCH(ReportedBoundsError) {
165       show_reported_bounds_error(tvb, pinfo, tree);
166     }
167     ENDTRY;
168
169     /*
170      * Skip the X.25-over-TCP header and the payload.
171      */
172     offset += plen + 4;
173   }
174 }
175
176 /* Register the protocol with Ethereal */
177 void 
178 proto_register_xot(void)
179 {
180         static hf_register_info hf[] = {
181                 { &hf_xot_version,
182                         { "Version", "xot.version", FT_UINT16, BASE_DEC,
183                         NULL, 0, "Version of X.25 over TCP protocol", HFILL }},
184
185                 { &hf_xot_length,
186                         { "Length", "xot.length", FT_UINT16, BASE_DEC,
187                         NULL, 0, "Length of X.25 over TCP packet", HFILL }}
188
189         };
190
191         static gint *ett[] = {
192                 &ett_xot,
193         };
194         module_t *xot_module;
195
196         proto_xot = proto_register_protocol("X.25 over TCP", "XOT", "xot");
197         proto_register_field_array(proto_xot, hf, array_length(hf));
198         proto_register_subtree_array(ett, array_length(ett));
199
200         xot_module = prefs_register_protocol(proto_xot, NULL);
201         prefs_register_bool_preference(xot_module, "desegment",
202             "Desegment all X.25-over-TCP messages spanning multiple TCP segments",
203             "Whether the X.25-over-TCP dissector should desegment all messages spanning multiple TCP segments",
204             &xot_desegment);
205 }
206
207 void
208 proto_reg_handoff_xot(void)
209 {
210         dissector_handle_t xot_handle;
211
212         /*
213          * Get a handle for the X.25 dissector.
214          */
215         x25_handle = find_dissector("x.25");
216
217         xot_handle = create_dissector_handle(dissect_xot, proto_xot);
218         dissector_add("tcp.port", TCP_PORT_XOT, xot_handle);
219 }