sensitivity of packet range options fine tuning:
[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.12 2003/01/21 01:45:17 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-tcp.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 guint get_xot_pdu_len(tvbuff_t *tvb, int offset)
55 {
56   guint16 plen;
57
58   /*
59    * Get the length of the X.25-over-TCP packet.
60    */
61   plen = tvb_get_ntohs(tvb, offset + 2);
62
63   /*
64    * That length doesn't include the header; add that in.
65    */
66   return plen + 4;
67 }
68
69 static void dissect_xot_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
70 {
71   int offset = 0;
72   guint16 version;
73   guint16 plen;
74   int length;
75   proto_item *ti;
76   proto_tree *xot_tree;
77   tvbuff_t   *next_tvb;
78
79   /*
80    * Dissect the X.25-over-TCP packet.
81    */
82   version = tvb_get_ntohs(tvb, offset + 0);
83   plen = tvb_get_ntohs(tvb, offset + 2);
84   if (check_col(pinfo->cinfo, COL_PROTOCOL))
85     col_set_str(pinfo->cinfo, COL_PROTOCOL, "XOT");
86   if (check_col(pinfo->cinfo, COL_INFO))
87     col_add_fstr(pinfo->cinfo, COL_INFO, "XOT Version = %u, size = %u",
88                  version, plen);
89
90   if (tree) {
91     ti = proto_tree_add_protocol_format(tree, proto_xot, tvb, offset, 4,
92                                             "X.25 over TCP");
93     xot_tree = proto_item_add_subtree(ti, ett_xot);
94
95     proto_tree_add_uint(xot_tree, hf_xot_version, tvb, offset, 2, version);
96     proto_tree_add_uint(xot_tree, hf_xot_length, tvb, offset + 2, 2, plen);
97   }
98
99   /*
100    * Construct a tvbuff containing the amount of the payload we have
101    * available.  Make its reported length the amount of data in the
102    * X.25-over-TCP packet.
103    */
104   length = tvb_length_remaining(tvb, offset + 4);
105   if (length > plen)
106     length = plen;
107   next_tvb = tvb_new_subset(tvb, offset + 4, length, plen);
108   call_dissector(x25_handle, next_tvb, pinfo, tree);
109 }
110
111 static int dissect_xot(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
112 {
113   /*
114    * Do we have the full version number and, if so, is it zero?
115    * If we have it but it's not zero, reject this segment.
116    */
117   if (tvb_bytes_exist(tvb, 0, 2)) {
118     if (tvb_get_ntohs(tvb, 0) != 0)
119       return 0;
120   }
121
122   /*
123    * The version number's OK, so dissect this segment.
124    */
125   tcp_dissect_pdus(tvb, pinfo, tree, xot_desegment, 4, get_xot_pdu_len,
126                    dissect_xot_pdu);
127
128   return tvb_length(tvb);
129 }
130
131 /* Register the protocol with Ethereal */
132 void
133 proto_register_xot(void)
134 {
135         static hf_register_info hf[] = {
136                 { &hf_xot_version,
137                         { "Version", "xot.version", FT_UINT16, BASE_DEC,
138                         NULL, 0, "Version of X.25 over TCP protocol", HFILL }},
139
140                 { &hf_xot_length,
141                         { "Length", "xot.length", FT_UINT16, BASE_DEC,
142                         NULL, 0, "Length of X.25 over TCP packet", HFILL }}
143
144         };
145
146         static gint *ett[] = {
147                 &ett_xot,
148         };
149         module_t *xot_module;
150
151         proto_xot = proto_register_protocol("X.25 over TCP", "XOT", "xot");
152         proto_register_field_array(proto_xot, hf, array_length(hf));
153         proto_register_subtree_array(ett, array_length(ett));
154
155         xot_module = prefs_register_protocol(proto_xot, NULL);
156         prefs_register_bool_preference(xot_module, "desegment",
157             "Desegment all X.25-over-TCP messages spanning multiple TCP segments",
158             "Whether the X.25-over-TCP dissector should desegment all messages spanning multiple TCP segments",
159             &xot_desegment);
160 }
161
162 void
163 proto_reg_handoff_xot(void)
164 {
165         dissector_handle_t xot_handle;
166
167         /*
168          * Get a handle for the X.25 dissector.
169          */
170         x25_handle = find_dissector("x.25");
171
172         xot_handle = new_create_dissector_handle(dissect_xot, proto_xot);
173         dissector_add("tcp.port", TCP_PORT_XOT, xot_handle);
174 }