FIXUP: WIP: verification_trailer
[wireshark-wip.git] / epan / dissectors / packet-moldudp.c
blobfc6d3eb459eee5c99ff1d232921f83c85d9b1b04
1 /* packet-moldudp.c
2 * Routines for MoldUDP dissection
3 * Copyright 2012, Evan Huus <eapache@gmail.com>
5 * http://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/moldudp.pdf
7 * $Id$
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
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.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "config.h"
30 #include <glib.h>
32 #include <epan/packet.h>
33 #include <epan/prefs.h>
34 #include <epan/expert.h>
36 void proto_reg_handoff_moldudp(void);
38 /* Initialize the protocol and registered fields */
39 static int proto_moldudp = -1;
40 static int hf_moldudp_session = -1;
41 static int hf_moldudp_sequence = -1;
42 static int hf_moldudp_count = -1;
43 static int hf_moldudp_msgblk = -1;
44 static int hf_moldudp_msgseq = -1;
45 static int hf_moldudp_msglen = -1;
46 static int hf_moldudp_msgdata = -1;
48 #define MOLDUDP_SESSION_LEN 10
49 #define MOLDUDP_SEQUENCE_LEN 4
50 #define MOLDUDP_COUNT_LEN 2
51 #define MOLDUDP_MSGLEN_LEN 2
53 #define MOLDUDP_HEARTBEAT 0x0000
55 /* Global port pref */
56 static guint pf_moldudp_port = 0;
58 /* Initialize the subtree pointers */
59 static gint ett_moldudp = -1;
60 static gint ett_moldudp_msgblk = -1;
62 static expert_field ei_moldudp_msglen_invalid = EI_INIT;
63 static expert_field ei_moldudp_count_invalid = EI_INIT;
65 /* Code to dissect a message block */
66 guint
67 dissect_moldudp_msgblk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
68 guint offset, guint32 sequence)
70 proto_item *ti;
71 proto_tree *blk_tree;
72 guint16 msglen, real_msglen, whole_len;
73 guint remaining;
75 if (tvb_reported_length(tvb) - offset < MOLDUDP_MSGLEN_LEN)
76 return 0;
78 msglen = tvb_get_letohs(tvb, offset);
79 remaining = tvb_reported_length(tvb) - offset - MOLDUDP_MSGLEN_LEN;
81 if (msglen == 0)
82 col_set_str(pinfo->cinfo, COL_INFO, "MoldUDP Messages (End Of Session)");
84 if (tvb_reported_length(tvb) < (offset + MOLDUDP_MSGLEN_LEN))
85 real_msglen = 0;
86 else if (msglen <= remaining)
87 real_msglen = msglen;
88 else
89 real_msglen = remaining;
91 /* msglen and real_msglen only count the data section, and don't
92 * include the two bytes for the length field itself. */
93 whole_len = real_msglen + MOLDUDP_MSGLEN_LEN;
95 ti = proto_tree_add_item(tree, hf_moldudp_msgblk,
96 tvb, offset, whole_len, ENC_NA);
98 blk_tree = proto_item_add_subtree(ti, ett_moldudp_msgblk);
100 ti = proto_tree_add_uint(blk_tree, hf_moldudp_msgseq,
101 tvb, offset, 0, sequence);
103 PROTO_ITEM_SET_GENERATED(ti);
105 ti = proto_tree_add_item(blk_tree, hf_moldudp_msglen,
106 tvb, offset, MOLDUDP_MSGLEN_LEN, ENC_LITTLE_ENDIAN);
108 if (msglen != real_msglen)
109 expert_add_info_format(pinfo, ti, &ei_moldudp_msglen_invalid,
110 "Invalid Message Length (claimed %u, found %u)",
111 msglen, real_msglen);
113 offset += MOLDUDP_MSGLEN_LEN;
115 proto_tree_add_item(blk_tree, hf_moldudp_msgdata,
116 tvb, offset, real_msglen, ENC_NA);
118 return whole_len;
121 /* Code to actually dissect the packets */
122 static int
123 dissect_moldudp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
125 proto_item *ti;
126 proto_tree *moldudp_tree;
127 guint offset = 0;
128 guint16 count, real_count = 0;
129 guint32 sequence;
131 /* Check that there's enough data */
132 if (tvb_reported_length(tvb) < (MOLDUDP_SESSION_LEN +
133 MOLDUDP_SEQUENCE_LEN +
134 MOLDUDP_COUNT_LEN))
135 return 0;
137 /* Make entries in Protocol column and Info column on summary display */
138 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MoldUDP");
140 /* Clear the info column so it's sane if we crash. We fill it in later when
141 * we've dissected more of the packet. */
142 col_clear(pinfo->cinfo, COL_INFO);
144 count = tvb_get_letohs(tvb, MOLDUDP_SESSION_LEN + MOLDUDP_SEQUENCE_LEN);
146 if (count == MOLDUDP_HEARTBEAT)
147 col_set_str(pinfo->cinfo, COL_INFO, "MoldUDP Heartbeat");
148 else
149 col_set_str(pinfo->cinfo, COL_INFO, "MoldUDP Messages");
151 /* create display subtree for the protocol */
152 ti = proto_tree_add_item(tree, proto_moldudp,
153 tvb, offset, -1, ENC_NA);
155 moldudp_tree = proto_item_add_subtree(ti, ett_moldudp);
157 proto_tree_add_item(moldudp_tree, hf_moldudp_session,
158 tvb, offset, MOLDUDP_SESSION_LEN, ENC_ASCII|ENC_NA);
159 offset += MOLDUDP_SESSION_LEN;
161 sequence = tvb_get_letohl(tvb, offset);
162 proto_tree_add_item(moldudp_tree, hf_moldudp_sequence,
163 tvb, offset, MOLDUDP_SEQUENCE_LEN, ENC_LITTLE_ENDIAN);
164 offset += MOLDUDP_SEQUENCE_LEN;
166 ti = proto_tree_add_item(moldudp_tree, hf_moldudp_count,
167 tvb, offset, MOLDUDP_COUNT_LEN, ENC_LITTLE_ENDIAN);
168 offset += MOLDUDP_COUNT_LEN;
170 while (tvb_reported_length(tvb) >= offset + MOLDUDP_MSGLEN_LEN)
172 offset += dissect_moldudp_msgblk(tvb, pinfo, moldudp_tree,
173 offset, sequence++);
174 real_count++;
177 if (real_count != count)
179 expert_add_info_format(pinfo, ti, &ei_moldudp_count_invalid,
180 "Invalid Message Count (claimed %u, found %u)",
181 count, real_count);
184 /* Return the amount of data this dissector was able to dissect */
185 return tvb_length(tvb);
189 /* Register the protocol with Wireshark */
190 void
191 proto_register_moldudp(void)
193 module_t *moldudp_module;
195 /* Setup list of header fields */
196 static hf_register_info hf[] = {
198 { &hf_moldudp_session,
199 { "Session", "moldudp.session", FT_STRING, BASE_NONE, NULL, 0,
200 "The session to which this packet belongs.", HFILL }},
202 { &hf_moldudp_sequence,
203 { "Sequence", "moldudp.sequence", FT_UINT32, BASE_DEC, NULL, 0,
204 "The sequence number of the first message in this packet.", HFILL }},
206 { &hf_moldudp_count,
207 { "Count", "moldudp.count", FT_UINT16, BASE_DEC, NULL, 0,
208 "The number of messages contained in this packet.", HFILL }},
210 { &hf_moldudp_msgblk,
211 { "Message Block", "moldudp.msgblock", FT_NONE, BASE_NONE, NULL, 0,
212 "A message.", HFILL }},
214 { &hf_moldudp_msglen,
215 { "Length", "moldudp.msglen", FT_UINT16, BASE_DEC, NULL, 0,
216 "The length of this message.", HFILL }},
218 { &hf_moldudp_msgseq,
219 { "Sequence", "moldudp.msgseq", FT_UINT32, BASE_DEC, NULL, 0,
220 "The sequence number of this message.", HFILL }},
222 { &hf_moldudp_msgdata,
223 { "Payload", "moldudp.msgdata", FT_BYTES, BASE_NONE, NULL, 0,
224 "The payload data of this message.", HFILL }}
227 /* Setup protocol subtree array */
228 static gint *ett[] = {
229 &ett_moldudp,
230 &ett_moldudp_msgblk
233 static ei_register_info ei[] = {
234 { &ei_moldudp_msglen_invalid, { "moldudp.msglen.invalid", PI_MALFORMED, PI_ERROR, "Invalid Message Length", EXPFILL }},
235 { &ei_moldudp_count_invalid, { "moldudp.count.invalid", PI_MALFORMED, PI_ERROR, "Invalid Count", EXPFILL }},
238 expert_module_t* expert_moldudp;
240 /* Register the protocol name and description */
241 proto_moldudp = proto_register_protocol("MoldUDP",
242 "MoldUDP", "moldudp");
244 /* Required function calls to register the header fields and subtrees used */
245 proto_register_field_array(proto_moldudp, hf, array_length(hf));
246 proto_register_subtree_array(ett, array_length(ett));
247 expert_moldudp = expert_register_protocol(proto_moldudp);
248 expert_register_field_array(expert_moldudp, ei, array_length(ei));
250 /* Register preferences module */
251 moldudp_module = prefs_register_protocol(proto_moldudp,
252 proto_reg_handoff_moldudp);
254 /* Register a port preference */
255 prefs_register_uint_preference(moldudp_module, "udp.port", "MoldUDP UDP Port",
256 "MoldUDP UDP port to capture on.",
257 10, &pf_moldudp_port);
261 void
262 proto_reg_handoff_moldudp(void)
264 static gboolean initialized = FALSE;
265 static dissector_handle_t moldudp_handle;
266 static int currentPort;
268 if (!initialized) {
269 moldudp_handle = new_create_dissector_handle(dissect_moldudp,
270 proto_moldudp);
271 initialized = TRUE;
272 } else {
274 dissector_delete_uint("udp.port", currentPort, moldudp_handle);
277 currentPort = pf_moldudp_port;
279 dissector_add_uint("udp.port", currentPort, moldudp_handle);
284 * Editor modelines - http://www.wireshark.org/tools/modelines.html
286 * Local variables:
287 * c-basic-offset: 4
288 * tab-width: 8
289 * indent-tabs-mode: nil
290 * End:
292 * vi: set shiftwidth=4 tabstop=8 expandtab:
293 * :indentSize=4:tabSize=8:noTabs=true: