2 * Routines for MoldUDP dissection
3 * Copyright 2012, Evan Huus <eapache@gmail.com>
5 * http://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/moldudp.pdf
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.
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 */
67 dissect_moldudp_msgblk(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
68 guint offset
, guint32 sequence
)
72 guint16 msglen
, real_msglen
, whole_len
;
75 if (tvb_reported_length(tvb
) - offset
< MOLDUDP_MSGLEN_LEN
)
78 msglen
= tvb_get_letohs(tvb
, offset
);
79 remaining
= tvb_reported_length(tvb
) - offset
- MOLDUDP_MSGLEN_LEN
;
82 col_set_str(pinfo
->cinfo
, COL_INFO
, "MoldUDP Messages (End Of Session)");
84 if (tvb_reported_length(tvb
) < (offset
+ MOLDUDP_MSGLEN_LEN
))
86 else if (msglen
<= remaining
)
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
);
121 /* Code to actually dissect the packets */
123 dissect_moldudp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
126 proto_tree
*moldudp_tree
;
128 guint16 count
, real_count
= 0;
131 /* Check that there's enough data */
132 if (tvb_reported_length(tvb
) < (MOLDUDP_SESSION_LEN
+
133 MOLDUDP_SEQUENCE_LEN
+
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");
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
,
177 if (real_count
!= count
)
179 expert_add_info_format(pinfo
, ti
, &ei_moldudp_count_invalid
,
180 "Invalid Message Count (claimed %u, found %u)",
184 /* Return the amount of data this dissector was able to dissect */
185 return tvb_length(tvb
);
189 /* Register the protocol with Wireshark */
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
}},
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
[] = {
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
);
262 proto_reg_handoff_moldudp(void)
264 static gboolean initialized
= FALSE
;
265 static dissector_handle_t moldudp_handle
;
266 static int currentPort
;
269 moldudp_handle
= new_create_dissector_handle(dissect_moldudp
,
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
289 * indent-tabs-mode: nil
292 * vi: set shiftwidth=4 tabstop=8 expandtab:
293 * :indentSize=4:tabSize=8:noTabs=true: