Rename the routines that handle dissector tables with unsigned integer
[obnox/wireshark/wip.git] / epan / dissectors / packet-ipsi-ctl.c
1 /* packet-ipsi-ctl.c
2  * Routines for Avaya IPSI Control packet disassembly
3  * Traffic is encapsulated Avaya proprietary CCMS
4  * (Control Channel Message Set) between PCD and SIM
5  *
6  * Copyright 2008, Randy McEoin <rmceoin@ahbelo.com>
7  *
8  * $Id$
9  *
10  * Wireshark - Network traffic analyzer
11  * By Gerald Combs <gerald@wireshark.org>
12  * Copyright 1998 Gerald Combs
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <glib.h>
34 #include <epan/packet.h>
35
36 #define IPSICTL_PORT            5010
37 #define IPSICTL_PDU_MAGIC       0x0300
38
39 static int proto_ipsictl = -1;
40
41 static int hf_ipsictl_pdu = -1;
42 static int hf_ipsictl_magic = -1;
43 static int hf_ipsictl_length = -1;
44 static int hf_ipsictl_type = -1;
45 static int hf_ipsictl_sequence = -1;
46 static int hf_ipsictl_field1 = -1;
47 static int hf_ipsictl_data = -1;
48
49 static gint ett_ipsictl = -1;
50 static gint ett_ipsictl_pdu = -1;
51
52 static void dissect_ipsictl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
53 {
54   
55   proto_tree   *ipsictl_tree = NULL;
56   proto_tree   *pdu_tree = NULL;
57   proto_item   *ti;
58   int           offset = 0;
59   int           loffset = 0;
60   int           llength = 0;
61   int           remaining_length;
62   guint16       magic;
63   guint16       length;
64   guint16       type=0;
65   guint16       sequence=0;
66   int           first_sequence=-1;
67   int           last_sequence=-1;
68   guint16       field1=0;
69   guint16       pdu=0;
70   int           haspdus=0;
71   const guint8  *data;
72
73   remaining_length=tvb_reported_length_remaining(tvb, offset);
74
75   if (tree) {
76
77       ti = proto_tree_add_item(tree, proto_ipsictl, tvb, offset, remaining_length, FALSE);
78       ipsictl_tree = proto_item_add_subtree(ti, ett_ipsictl);
79
80   }
81
82   magic = tvb_get_ntohs(tvb, offset);
83   if (magic == IPSICTL_PDU_MAGIC)
84   {
85     haspdus=1;
86   }
87
88   while (haspdus &&
89     ((remaining_length=tvb_reported_length_remaining(tvb, offset)) > 6))
90   {
91     loffset = offset;
92
93     magic = tvb_get_ntohs(tvb, loffset); loffset+=2;
94     length = tvb_get_ntohs(tvb, loffset); loffset+=2;
95     llength=length;
96     remaining_length-=4;
97     if (remaining_length>=2)
98     {
99       type = tvb_get_ntohs(tvb, loffset); loffset+=2;
100       remaining_length-=2;
101       llength-=2;
102     }
103     if (remaining_length>=2)
104     {
105       sequence = tvb_get_ntohs(tvb, loffset); loffset+=2;
106       remaining_length-=2;
107       llength-=2;
108       if (first_sequence==-1)
109       {
110         first_sequence=sequence;
111       }else{
112         last_sequence=sequence;
113       }
114     }
115     if (remaining_length>=2)
116     {
117       field1 = tvb_get_ntohs(tvb, loffset); loffset+=2;
118       remaining_length-=2;
119       llength-=2;
120     }
121     data = tvb_get_ptr(tvb, loffset, remaining_length);
122
123     if (tree) {
124
125       ti = proto_tree_add_uint_format(ipsictl_tree, hf_ipsictl_pdu, tvb,
126            offset, (length+4), pdu,
127            "PDU: %d", pdu);
128
129       pdu_tree = proto_item_add_subtree(ti, ett_ipsictl_pdu);
130     }
131
132     loffset=offset;
133     remaining_length=tvb_reported_length_remaining(tvb, offset);
134
135     if (tree) {
136       proto_tree_add_uint(pdu_tree, hf_ipsictl_magic, tvb, loffset, 2, magic);
137     }
138     loffset+=2; remaining_length-=2;
139     if (tree) {
140       proto_tree_add_uint(pdu_tree, hf_ipsictl_length, tvb, loffset, 2, length);
141     }
142     loffset+=2; remaining_length-=2;
143
144     if (remaining_length>=2)
145     {
146       if (tree) {
147         proto_tree_add_uint(pdu_tree, hf_ipsictl_type, tvb, loffset, 2, type);
148       }
149       loffset+=2; remaining_length-=2;
150     }
151     if (remaining_length>=2)
152     {
153       if (tree) {
154         proto_tree_add_uint(pdu_tree, hf_ipsictl_sequence, tvb, loffset, 2, sequence);
155       }
156       loffset+=2; remaining_length-=2;
157     }
158     if (remaining_length>=2)
159     {
160       if (tree) {
161         proto_tree_add_uint(pdu_tree, hf_ipsictl_field1, tvb, loffset, 2, field1);
162       }
163       loffset+=2; remaining_length-=2;
164     }
165     if (remaining_length>=2)
166     {
167       if (tree) {
168         proto_tree_add_bytes(pdu_tree, hf_ipsictl_data, tvb, loffset, llength, data);
169       }
170       loffset+=llength; remaining_length-=llength;
171     }
172
173     offset=loffset;
174     pdu++;
175   }
176
177   if (!haspdus)
178   {
179     data = tvb_get_ptr(tvb, offset, remaining_length);
180
181     if (tree) {
182       proto_tree_add_bytes(ipsictl_tree, hf_ipsictl_data, tvb, offset, -1, data);
183     }
184   }
185
186   col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPSICTL");
187
188   if (haspdus)
189   {
190     if (check_col(pinfo->cinfo, COL_INFO)) {
191       if (last_sequence==-1)
192       {
193         col_add_fstr(pinfo->cinfo, COL_INFO, "PDUS=%d, Seq=0x%04x",
194           pdu,first_sequence);
195       }else{
196         col_add_fstr(pinfo->cinfo, COL_INFO, "PDUS=%d, Seq=0x%04x-0x%04x",
197           pdu,first_sequence,last_sequence);
198       }
199     }
200   }else{
201     col_set_str(pinfo->cinfo, COL_INFO, "Initialization");
202   }
203
204
205 } /* dissect_ipsictl */
206
207 void proto_register_ipsictl(void) 
208 {
209
210   static hf_register_info hf[] = {
211     { &hf_ipsictl_pdu,
212       { "PDU",  "ipsictl.pdu", 
213         FT_UINT16,      BASE_HEX,       NULL,   0x0,
214         "IPSICTL PDU", HFILL }},
215     { &hf_ipsictl_magic,
216       { "Magic",        "ipsictl.magic", 
217         FT_UINT16,      BASE_HEX,       NULL,   0x0,
218         "IPSICTL Magic", HFILL }},
219     { &hf_ipsictl_length,
220       { "Length",       "ipsictl.length", 
221         FT_UINT16,      BASE_HEX,       NULL,   0x0,
222         "IPSICTL Length", HFILL }},
223     { &hf_ipsictl_type,
224       { "Type", "ipsictl.type", 
225         FT_UINT16,      BASE_HEX,       NULL,   0x0,
226         "IPSICTL Type", HFILL }},
227     { &hf_ipsictl_sequence,
228       { "Sequence",     "ipsictl.sequence", 
229         FT_UINT16,      BASE_HEX,       NULL,   0x0,
230         "IPSICTL Sequence", HFILL }},
231     { &hf_ipsictl_field1,
232       { "Field1",       "ipsictl.field1", 
233         FT_UINT16,      BASE_HEX,       NULL,   0x0,
234         "IPSICTL Field1", HFILL }},
235     { &hf_ipsictl_data,
236       { "Data", "ipsictl.data", 
237         FT_BYTES,       BASE_NONE,      NULL,   0x0,
238         "IPSICTL data", HFILL }},
239   };
240
241   static gint *ett[] = {
242     &ett_ipsictl,
243     &ett_ipsictl_pdu
244   };
245
246   proto_ipsictl = proto_register_protocol("IPSICTL", "IPSICTL", "ipsictl");
247   proto_register_field_array(proto_ipsictl, hf, array_length(hf));
248   proto_register_subtree_array(ett, array_length(ett));
249
250 }
251
252 void proto_reg_handoff_ipsictl(void) 
253 {
254
255   dissector_handle_t ipsictl_handle = NULL;
256
257   ipsictl_handle = create_dissector_handle(dissect_ipsictl, proto_ipsictl);
258
259   dissector_add_uint("tcp.port", IPSICTL_PORT, ipsictl_handle);
260
261 }
262