2 * Routines for Blubster/Piolet Manolito Protocol dissection
3 * Copyright 2003-2004, Jeff Connelly <shellreef+mp2p@gmail.com>
5 * Official home page: http://openlito.sourceforge.net/
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
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (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
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 #include <epan/packet.h>
39 #include <epan/emem.h>
41 /* Initialize the protocol and registered fields */
42 static int proto_manolito = -1;
43 static int hf_manolito_checksum = -1;
44 static int hf_manolito_seqno = -1;
45 static int hf_manolito_src = -1;
46 static int hf_manolito_dest = -1;
47 static int hf_manolito_options = -1;
49 /* Initialize the subtree pointers */
50 static gint ett_manolito = -1;
52 struct MANOLITO_HEADER {
60 /* Code to actually dissect the packets */
62 dissect_manolito(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
64 struct MANOLITO_HEADER header;
67 /* Set up structures needed to add the protocol subtree and manage it */
69 proto_tree *manolito_tree;
70 const char* packet_type = 0;
72 /* Make entries in Protocol column and Info column on summary display */
73 if (check_col(pinfo->cinfo, COL_PROTOCOL))
74 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MANOLITO");
76 ti = proto_tree_add_item(tree, proto_manolito, tvb, 0, -1, FALSE);
78 manolito_tree = proto_item_add_subtree(ti, ett_manolito);
80 /* MANOLITO packet header (network byte order) */
81 header.checksum = tvb_get_ntohl(tvb, 0);
82 header.seqno = tvb_get_ntohl(tvb, 4);
83 header.src = tvb_get_ipv4(tvb, 8);
84 header.dest = tvb_get_ipv4(tvb, 12);
85 if (tvb_reported_length(tvb) == 19)
87 header.options = (tvb_get_ntohs(tvb, 16) << 8) +
88 tvb_get_guint8(tvb, 18);
89 packet_type = "Ping (truncated)";
91 header.options = tvb_get_ntohl(tvb, 16);
94 proto_tree_add_item(manolito_tree,
95 hf_manolito_checksum, tvb, 0, 4, header.checksum);
96 proto_tree_add_item(manolito_tree,
97 hf_manolito_seqno, tvb, 4, 4, header.seqno);
99 proto_tree_add_ipv4(manolito_tree,
100 hf_manolito_src, tvb, 8, 4, header.src);
102 proto_tree_add_ipv4(manolito_tree,
103 hf_manolito_dest, tvb, 12, 4, header.dest);
105 proto_tree_add_item(manolito_tree,
106 hf_manolito_options, tvb, 16, 4, header.options);
109 if (tvb_reported_length(tvb) <= 20) /* no payload, just headers */
111 if (check_col(pinfo->cinfo, COL_INFO))
113 col_set_str(pinfo->cinfo, COL_INFO, "Ping");
116 offset = 20; /* fields start here */
118 /* fields format: 2-byte name, optional NULL, 1-byte lenlen, */
119 /* that many bytes(len or data), for NI,CN,VL is len, more */
120 /* (that many bytes) data follows; else is raw data. */
123 guint16 field_name; /* 16-bit field name */
124 guint8 dtype; /* data-type */
125 guint8 length; /* length */
126 guint8* data; /* payload */
127 int start; /* field starting location */
128 char field_name_str[3]; /* printable name */
129 const char* longname; /* human-friendly field name */
133 /* 2-byte field name */
134 field_name = tvb_get_ntohs(tvb, offset);
137 /* Identify the packet based on existing fields */
138 /* Maybe using the options fields is a better idea...*/
139 if (field_name == 0x434b) /* CK */
140 packet_type = "Search Hit";
141 if (field_name == 0x4e43) /* NC */
142 packet_type = "User Information";
143 if (field_name == 0x464e) /* FN - if only field */
144 packet_type = "Search Query";
145 if (field_name == 0x4944) /* ID ?? search by CK? */
146 packet_type = "Search Query (by hash)";
147 if (field_name == 0x5054) /* PT */
148 packet_type = "Download Request";
149 if (field_name == 0x4d45) /* ME */
150 packet_type = "Chat";
152 if (tvb_reported_length(tvb) == 20) /* no fields */
153 packet_type = "Ping";
155 /* Find the long name of the field */
158 case 0x5346: longname = "Shared Files"; break; /* SF */
159 case 0x534b: longname = "Shared Kilobytes";break; /* SK */
160 case 0x4e49: longname = "Network ID"; break; /* NI */
161 case 0x4e43: longname = "Num. Connections";break; /* NC */
162 case 0x4356: longname = "Client Version"; break; /* CV */
163 case 0x564c: longname = "Velocity"; break; /* VL */
164 case 0x464e: longname = "Filename"; break; /* FN */
165 case 0x464c: longname = "File Length"; break; /* FL */
166 case 0x4252: longname = "Bit Rate"; break; /* BR */
167 case 0x4643: longname = "Frequency"; break; /* FC */
168 case 0x5354: longname = "???"; break; /* ST */
169 case 0x534c: longname = "Song Length (s)"; break; /* SL */
170 case 0x434b: longname = "Checksum"; break; /* CK */
171 case 0x4e4e: longname = "Nickname"; break; /* NN */
172 case 0x434e: longname = "Client Name"; break; /* CN */
173 case 0x5054: longname = "Port"; break; /* PT */
174 case 0x484e: longname = "???"; break; /* HN */
175 case 0x4d45: longname = "Message"; break; /* ME */
176 case 0x4944: longname = "Identification"; break; /* ID */
177 case 0x4144: longname = "???"; break; /* AD */
178 default: longname = "unknown"; break;
181 /* 1-byte data type */
182 #define MANOLITO_STRING 1
183 #define MANOLITO_INTEGER 0
184 dtype = tvb_get_guint8(tvb, offset);
185 length = tvb_get_guint8(tvb, ++offset);
190 * XXX - is the cast necessary? I think the
191 * "usual arithmetic conversions" should
192 * widen it past 8 bits, so there shouldn't
195 data = ep_alloc((guint)length + 1);
196 tvb_memcpy(tvb, data, ++offset, length);
199 /* convert the 16-bit integer field name to a string */
200 /* XXX: changed this to use g_htons */
201 field_name_str[0] = g_htons(field_name) & 0x00ff;
202 field_name_str[1] = (g_htons(field_name) & 0xff00) >> 8;
203 field_name_str[2] = 0;
205 if (dtype == MANOLITO_STRING)
208 proto_tree_add_text(manolito_tree, tvb, start,
209 offset - start, "%s (%s): %s",
210 (char*)field_name_str, longname, data);
211 } else if (dtype == MANOLITO_INTEGER) {
214 /* integers can be up to 5 bytes */
217 case 5: n += data[4] << ((length - 5) * 8);
218 case 4: n += data[3] << ((length - 4) * 8);
219 case 3: n += data[2] << ((length - 3) * 8);
220 case 2: n += data[1] << ((length - 2) * 8);
221 case 1: n += data[0] << ((length - 1) * 8);
223 proto_tree_add_text(manolito_tree, tvb, start,
224 offset - start, "%s (%s): %d",
225 (char*)field_name_str, longname, n);
227 proto_tree_add_text(manolito_tree, tvb, start,
228 offset - start, "unknown type %d", dtype);
231 } while(offset < tvb_reported_length(tvb));
235 if (packet_type && check_col(pinfo->cinfo, COL_INFO))
237 col_set_str(pinfo->cinfo, COL_INFO, packet_type);
242 /* Register the protocol with Wireshark */
245 proto_register_manolito(void)
248 /* Setup list of header fields See Section 1.6.1 for details*/
249 static hf_register_info hf[] = {
250 { &hf_manolito_checksum,
251 { "Checksum", "manolito.checksum",
252 FT_UINT32, BASE_HEX, NULL, 0,
253 "Checksum used for verifying integrity", HFILL }
255 { &hf_manolito_seqno,
256 { "Sequence Number", "manolito.seqno",
257 FT_UINT32, BASE_HEX, NULL, 0,
258 "Incremental sequence number", HFILL }
261 { "Forwarded IP Address", "manolito.src",
262 FT_IPv4, BASE_NONE, NULL, 0,
263 "Host packet was forwarded from (or 0)", HFILL }
266 { "Destination IP Address","manolito.dest",
267 FT_IPv4, BASE_NONE, NULL, 0,
268 "Destination IPv4 address", HFILL }
270 { &hf_manolito_options,
271 { "Options", "manolito.options",
272 FT_UINT32, BASE_HEX, NULL, 0,
273 "Packet-dependent data", HFILL }
277 static gint *ett[] = {
281 proto_manolito = proto_register_protocol("Blubster/Piolet MANOLITO Protocol",
282 "Manolito", "manolito");
284 proto_register_field_array(proto_manolito, hf, array_length(hf));
285 proto_register_subtree_array(ett, array_length(ett));
289 /* If this dissector uses sub-dissector registration add a registration routine.
290 This format is required because a script is used to find these routines and
291 create the code that calls these routines.
294 proto_reg_handoff_manolito(void)
296 dissector_handle_t manolito_handle;
298 manolito_handle = create_dissector_handle(dissect_manolito,
300 dissector_add("udp.port", 41170, manolito_handle);