/src/wireshark/epan/dissectors/packet-dpnet.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* packet-dpnet.c |
2 | | * This is a dissector for the DirectPlay 8 protocol. |
3 | | * |
4 | | * Copyright 2017 - Alistair Leslie-Hughes |
5 | | * |
6 | | * Wireshark - Network traffic analyzer |
7 | | * By Gerald Combs <gerald@wireshark.org> |
8 | | * Copyright 1998 Gerald Combs |
9 | | * |
10 | | * SPDX-License-Identifier: GPL-2.0-or-later |
11 | | * |
12 | | */ |
13 | | |
14 | | #include "config.h" |
15 | | |
16 | | #include <epan/packet.h> |
17 | | #include <epan/tfs.h> |
18 | | |
19 | | void proto_register_dpnet(void); |
20 | | void proto_reg_handoff_dpnet(void); |
21 | | |
22 | | static dissector_handle_t dpnet_handle; |
23 | | |
24 | 14 | #define DPNET_PORT 6073 |
25 | | |
26 | | static int proto_dpnet; |
27 | | |
28 | | static int hf_dpnet_lead; |
29 | | static int hf_dpnet_command; |
30 | | static int hf_dpnet_payload; |
31 | | static int hf_dpnet_type; |
32 | | static int hf_dpnet_application; |
33 | | static int hf_dpnet_data; |
34 | | static int hf_dpnet_reply_offset; |
35 | | static int hf_dpnet_response_size; |
36 | | |
37 | | static int hf_dpnet_desc_size; |
38 | | static int hf_dpnet_desc_flags; |
39 | | static int hf_dpnet_max_players; |
40 | | static int hf_dpnet_current_players; |
41 | | static int hf_dpnet_session_offset; |
42 | | static int hf_dpnet_session_size; |
43 | | static int hf_dpnet_session_name; |
44 | | static int hf_dpnet_password_offset; |
45 | | static int hf_dpnet_password_size; |
46 | | static int hf_dpnet_reserved_offset; |
47 | | static int hf_dpnet_reserved_size; |
48 | | static int hf_dpnet_application_offset; |
49 | | static int hf_dpnet_application_size; |
50 | | static int hf_dpnet_application_data; |
51 | | static int hf_dpnet_instance; |
52 | | static int hf_dpnet_data_cframe_control; |
53 | | static int hf_dpnet_data_cframe_msgid; |
54 | | static int hf_dpnet_data_cframe_rspid; |
55 | | static int hf_dpnet_data_cframe_protocol; |
56 | | static int hf_dpnet_data_cframe_session; |
57 | | static int hf_dpnet_data_cframe_timestamp; |
58 | | static int hf_dpnet_data_cframe_padding; |
59 | | static int hf_dpnet_data_cframe_flags; |
60 | | static int hf_dpnet_data_cframe_retry; |
61 | | static int hf_dpnet_data_cframe_nseq; |
62 | | static int hf_dpnet_data_cframe_nrcv; |
63 | | static int hf_dpnet_data_cframe_sack_mask1; |
64 | | static int hf_dpnet_data_cframe_sack_mask2; |
65 | | static int hf_dpnet_data_cframe_send_mask1; |
66 | | static int hf_dpnet_data_cframe_send_mask2; |
67 | | static int hf_dpnet_data_cframe_signature; |
68 | | static int hf_dpnet_data_cframe_send_secret; |
69 | | static int hf_dpnet_data_cframe_recv_secret; |
70 | | static int hf_dpnet_data_cframe_signing_opts; |
71 | | static int hf_dpnet_data_cframe_echo_time; |
72 | | static int hf_dpnet_data_seq; |
73 | | static int hf_dpnet_data_nseq; |
74 | | static int hf_dpnet_data_command; |
75 | | static int hf_dpnet_command_data; |
76 | | static int hf_dpnet_command_reliable; |
77 | | static int hf_dpnet_command_seq; |
78 | | static int hf_dpnet_command_poll; |
79 | | static int hf_dpnet_command_new_msg; |
80 | | static int hf_dpnet_command_end_msg; |
81 | | static int hf_dpnet_command_user1; |
82 | | static int hf_dpnet_command_user2; |
83 | | static int hf_dpnet_desc_client_server; |
84 | | static int hf_dpnet_desc_migrate_host; |
85 | | static int hf_dpnet_desc_nodpnsvr; |
86 | | static int hf_dpnet_desc_req_password; |
87 | | static int hf_dpnet_desc_no_enums; |
88 | | static int hf_dpnet_desc_fast_signed; |
89 | | static int hf_dpnet_desc_full_signed; |
90 | | |
91 | | static int ett_dpnet; |
92 | | static int ett_dpnet_command_flags; |
93 | | static int ett_dpnet_desc_flags; |
94 | | |
95 | 0 | #define DPNET_QUERY_GUID 0x01 |
96 | | |
97 | 0 | #define DPNET_ENUM_QUERY 0x02 |
98 | 0 | #define DPNET_ENUM_RESPONSE 0x03 |
99 | | |
100 | 14 | #define DPNET_COMMAND_DATA 0x01 |
101 | 14 | #define DPNET_COMMAND_RELIABLE 0x02 |
102 | 14 | #define DPNET_COMMAND_SEQUENTIAL 0x04 |
103 | 14 | #define DPNET_COMMAND_POLL 0x08 |
104 | 14 | #define DPNET_COMMAND_NEW_MSG 0x10 |
105 | 14 | #define DPNET_COMMAND_END_MSG 0x20 |
106 | 14 | #define DPNET_COMMAND_USER_1 0x40 |
107 | 14 | #define DPNET_COMMAND_CFRAME 0x80 |
108 | | |
109 | | #define DN_MSG_INTERNAL_PLAYER_CONNECT_INFO 0x000000c1 |
110 | | #define DN_MSG_INTERNAL_SEND_CONNECT_INFO 0x000000c2 |
111 | | #define DN_MSG_INTERNAL_ACK_CONNECT_INFO 0x000000c3 |
112 | | |
113 | 0 | #define FRAME_EXOPCODE_CONNECT 0x01 |
114 | 0 | #define FRAME_EXOPCODE_CONNECTED 0x02 |
115 | 0 | #define FRAME_EXOPCODE_CONNECTED_SIGNED 0x03 |
116 | 0 | #define FRAME_EXOPCODE_HARD_DISCONNECT 0x04 |
117 | 0 | #define FRAME_EXOPCODE_SACK 0x06 |
118 | | |
119 | | #define PROTOCOL_VER_0 0x00010000 |
120 | | #define PROTOCOL_VER_1 0x00010001 |
121 | | #define PROTOCOL_VER_2 0x00010002 |
122 | | #define PROTOCOL_VER_3 0x00010003 |
123 | | #define PROTOCOL_VER_4 0x00010004 |
124 | | #define PROTOCOL_VER_5 0x00010005 |
125 | | #define PROTOCOL_VER_6 0x00010006 |
126 | | |
127 | | #define SACK_FLAGS_RESPONSE 0x01 |
128 | 0 | #define SACK_FLAGS_SACK_MASK1 0x02 |
129 | 0 | #define SACK_FLAGS_SACK_MASK2 0x04 |
130 | 0 | #define SACK_FLAGS_SEND_MASK1 0x08 |
131 | 0 | #define SACK_FLAGS_SEND_MASK2 0x10 |
132 | | |
133 | | #define PACKET_SIGNING_FAST 0x01 |
134 | | #define PACKET_SIGNING_FULL 0x02 |
135 | | |
136 | 14 | #define SESSION_CLIENT_SERVER 0x0001 |
137 | 14 | #define SESSION_MIGRATE_HOST 0x0004 |
138 | 14 | #define SESSION_NODPNSVR 0x0040 |
139 | 14 | #define SESSION_REQUIREPASSWORD 0x0080 |
140 | 14 | #define SESSION_NOENUMS 0x0100 |
141 | 14 | #define SESSION_FAST_SIGNED 0x0200 |
142 | 14 | #define SESSION_FULL_SIGNED 0x0400 |
143 | | |
144 | | static const value_string packetenumttypes[] = { |
145 | | { 1, "Application GUID" }, |
146 | | { 2, "All Applications" }, |
147 | | { 0, NULL } |
148 | | }; |
149 | | |
150 | | static const value_string packetquerytype[] = { |
151 | | { 2, "Enumeration Query" }, |
152 | | { 3, "Enumeration Response" }, |
153 | | { 0, NULL } |
154 | | }; |
155 | | |
156 | | static const value_string msg_cframe_control[] = { |
157 | | {FRAME_EXOPCODE_CONNECT, "FRAME_EXOPCODE_CONNECT"}, |
158 | | {FRAME_EXOPCODE_CONNECTED, "FRAME_EXOPCODE_CONNECTED"}, |
159 | | {FRAME_EXOPCODE_CONNECTED_SIGNED, "FRAME_EXOPCODE_CONNECTED_SIGNED"}, |
160 | | {FRAME_EXOPCODE_HARD_DISCONNECT, "FRAME_EXOPCODE_HARD_DISCONNECT"}, |
161 | | {FRAME_EXOPCODE_SACK, "FRAME_EXOPCODE_SACK"}, |
162 | | {0, NULL } |
163 | | }; |
164 | | |
165 | | static const value_string protocol_versions[] = { |
166 | | {PROTOCOL_VER_0, "Supports Base Features"}, |
167 | | {PROTOCOL_VER_1, "Supports Base Features"}, |
168 | | {PROTOCOL_VER_2, "Supports Base Features"}, |
169 | | {PROTOCOL_VER_3, "Supports Base Features"}, |
170 | | {PROTOCOL_VER_4, "Supports Base Features"}, |
171 | | {PROTOCOL_VER_5, "Supports Coalescence"}, |
172 | | {PROTOCOL_VER_6, "Supports Coalescence and Signing"}, |
173 | | {0, NULL } |
174 | | }; |
175 | | |
176 | | static const value_string sack_flags[] = { |
177 | | {SACK_FLAGS_RESPONSE, "Retry field is valid"}, |
178 | | {SACK_FLAGS_SACK_MASK1, "Low 32 bits of the SACK mask are present in sack.mask1"}, |
179 | | {SACK_FLAGS_SACK_MASK2, "High 32 bits of the SACK mask are present in sack.mask2"}, |
180 | | {SACK_FLAGS_SEND_MASK1, "Low 32 bits of the Send mask are present in send.mask1"}, |
181 | | {SACK_FLAGS_SEND_MASK2, "High 32 bits of the Send mask are present in send.mask2"}, |
182 | | {0, NULL } |
183 | | }; |
184 | | |
185 | | static const value_string signing_opts[] = { |
186 | | {PACKET_SIGNING_FAST, "Fasting signing"}, |
187 | | {PACKET_SIGNING_FULL, "Full signing"}, |
188 | | {0, NULL } |
189 | | }; |
190 | | |
191 | | static const true_false_string tfs_flags_game_client = { |
192 | | "Client/Server session", |
193 | | "Peer session" |
194 | | }; |
195 | | |
196 | | static const true_false_string tfs_flags_migrate = { |
197 | | "Host Migrating allowed", |
198 | | "Host Migrating NOT allowed" |
199 | | }; |
200 | | |
201 | | static const true_false_string tfs_flags_dpnsvr = { |
202 | | "NOT using dpnsvr.exe", |
203 | | "Using dpnsvr.exe" |
204 | | }; |
205 | | |
206 | | static const true_false_string tfs_flags_password_required = { |
207 | | "Password required", |
208 | | "NO password required" |
209 | | }; |
210 | | |
211 | | static const true_false_string tfs_flags_enumeration = { |
212 | | "Enumeration NOT allowed", |
213 | | "Enumeration allowed" |
214 | | }; |
215 | | |
216 | | static const true_false_string tfs_flags_fast = { |
217 | | "Using Fast signing", |
218 | | "NOT using Fast signing" |
219 | | }; |
220 | | |
221 | | static const true_false_string tfs_flags_full = { |
222 | | "Using Full signing", |
223 | | "NOT using Full signing" |
224 | | }; |
225 | | |
226 | | |
227 | | static int * const desc_flags[] = { |
228 | | &hf_dpnet_desc_client_server, |
229 | | &hf_dpnet_desc_migrate_host, |
230 | | &hf_dpnet_desc_nodpnsvr, |
231 | | &hf_dpnet_desc_req_password, |
232 | | &hf_dpnet_desc_no_enums, |
233 | | &hf_dpnet_desc_fast_signed, |
234 | | &hf_dpnet_desc_full_signed, |
235 | | NULL |
236 | | }; |
237 | | |
238 | | static int * const command_flags[] = { |
239 | | &hf_dpnet_command_data, |
240 | | &hf_dpnet_command_reliable, |
241 | | &hf_dpnet_command_seq, |
242 | | &hf_dpnet_command_poll, |
243 | | &hf_dpnet_command_new_msg, |
244 | | &hf_dpnet_command_end_msg, |
245 | | &hf_dpnet_command_user1, |
246 | | &hf_dpnet_command_user2, |
247 | | NULL |
248 | | }; |
249 | | |
250 | | static void process_dpnet_query(proto_tree *dpnet_tree, tvbuff_t *tvb, packet_info *pinfo) |
251 | 0 | { |
252 | 0 | int offset = 0, data_tvb_len; |
253 | 0 | uint8_t has_guid; |
254 | 0 | uint8_t is_query; |
255 | |
|
256 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_lead, tvb, 0, 1, ENC_BIG_ENDIAN); offset += 1; |
257 | 0 | is_query = tvb_get_uint8(tvb, offset); |
258 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_command, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; |
259 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_payload, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; |
260 | |
|
261 | 0 | if(is_query == DPNET_ENUM_QUERY) |
262 | 0 | { |
263 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "DPNET Enum Query"); |
264 | |
|
265 | 0 | has_guid = tvb_get_uint8(tvb, offset); |
266 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; |
267 | |
|
268 | 0 | if (has_guid & DPNET_QUERY_GUID) { |
269 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_application, tvb, offset, 16, ENC_BIG_ENDIAN); |
270 | 0 | offset += 16; |
271 | 0 | } |
272 | |
|
273 | 0 | data_tvb_len = tvb_reported_length_remaining(tvb, offset); |
274 | 0 | if(data_tvb_len) |
275 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data, tvb, offset, data_tvb_len, ENC_NA); |
276 | |
|
277 | 0 | } |
278 | 0 | else if(is_query == DPNET_ENUM_RESPONSE) |
279 | 0 | { |
280 | 0 | uint32_t session_offset, session_size; |
281 | 0 | uint32_t application_offset, application_size; |
282 | |
|
283 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "DPNET Enum Response"); |
284 | |
|
285 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_reply_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; |
286 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_response_size, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; |
287 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_desc_size, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; |
288 | 0 | proto_tree_add_bitmask(dpnet_tree, tvb, offset, hf_dpnet_desc_flags, ett_dpnet_desc_flags, desc_flags, ENC_LITTLE_ENDIAN); |
289 | 0 | offset += 4; |
290 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_max_players, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; |
291 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_current_players, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; |
292 | 0 | proto_tree_add_item_ret_uint(dpnet_tree, hf_dpnet_session_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN, &session_offset); offset += 4; |
293 | 0 | proto_tree_add_item_ret_uint(dpnet_tree, hf_dpnet_session_size, tvb, offset, 4, ENC_LITTLE_ENDIAN, &session_size); offset += 4; |
294 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_password_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; |
295 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_password_size, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; |
296 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_reserved_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; |
297 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_reserved_size, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; |
298 | 0 | proto_tree_add_item_ret_uint(dpnet_tree, hf_dpnet_application_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN, &application_offset); offset += 4; |
299 | 0 | proto_tree_add_item_ret_uint(dpnet_tree, hf_dpnet_application_size, tvb, offset, 4, ENC_LITTLE_ENDIAN, &application_size); offset += 4; |
300 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_instance, tvb, offset, 16, ENC_LITTLE_ENDIAN); offset += 16; |
301 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_application, tvb, offset, 16, ENC_LITTLE_ENDIAN); |
302 | |
|
303 | 0 | if(session_offset) |
304 | 0 | { |
305 | | /* session_offset starts from the hf_dpnet_payload */ |
306 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_session_name, tvb, session_offset + 4, session_size, ENC_UTF_16|ENC_LITTLE_ENDIAN); |
307 | 0 | } |
308 | |
|
309 | 0 | if(application_offset) |
310 | 0 | { |
311 | | /* application_offset starts from the hf_dpnet_payload */ |
312 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_application_data, tvb, application_offset + 4, application_size, ENC_NA); |
313 | 0 | } |
314 | 0 | } |
315 | 0 | } |
316 | | |
317 | | static void |
318 | | dpnet_process_data_frame(proto_tree *dpnet_tree, tvbuff_t *tvb, packet_info *pinfo) |
319 | 0 | { |
320 | 0 | int offset = 0; |
321 | |
|
322 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "DPNET DFrame"); |
323 | |
|
324 | 0 | proto_tree_add_bitmask(dpnet_tree, tvb, offset, hf_dpnet_data_command, ett_dpnet_command_flags, command_flags, ENC_BIG_ENDIAN); |
325 | | |
326 | | /* TODO */ |
327 | 0 | } |
328 | | |
329 | | static void |
330 | | dpnet_process_control_frame(proto_tree *dpnet_tree, tvbuff_t *tvb, packet_info *pinfo) |
331 | 0 | { |
332 | 0 | int offset = 0; |
333 | 0 | int command; |
334 | 0 | const char *command_str; |
335 | 0 | int flag; |
336 | 0 | uint32_t data_tvb_len; |
337 | |
|
338 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "DPNET CFrame"); |
339 | |
|
340 | 0 | proto_tree_add_bitmask(dpnet_tree, tvb, offset, hf_dpnet_data_command, ett_dpnet_command_flags, command_flags, ENC_BIG_ENDIAN); |
341 | 0 | offset += 1; |
342 | |
|
343 | 0 | command = tvb_get_uint8(tvb, offset); |
344 | 0 | command_str = val_to_str_const(command, msg_cframe_control, "Unknown Control (obsolete or malformed?)"); |
345 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", command_str); |
346 | |
|
347 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_control, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
348 | 0 | offset += 1; |
349 | |
|
350 | 0 | switch(command) |
351 | 0 | { |
352 | 0 | case FRAME_EXOPCODE_CONNECT: |
353 | 0 | case FRAME_EXOPCODE_CONNECTED: |
354 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_msgid, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
355 | 0 | offset += 1; |
356 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_rspid, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
357 | 0 | offset += 1; |
358 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_protocol, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
359 | 0 | offset += 4; |
360 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_session, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
361 | 0 | offset += 4; |
362 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_timestamp, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
363 | 0 | break; |
364 | 0 | case FRAME_EXOPCODE_CONNECTED_SIGNED: |
365 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_msgid, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
366 | 0 | offset += 1; |
367 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_rspid, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
368 | 0 | offset += 1; |
369 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_protocol, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
370 | 0 | offset += 4; |
371 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_session, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
372 | 0 | offset += 4; |
373 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_timestamp, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
374 | 0 | offset += 4; |
375 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_signature, tvb, offset, 8, ENC_NA); |
376 | 0 | offset += 8; |
377 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_send_secret, tvb, offset, 8, ENC_NA); |
378 | 0 | offset += 8; |
379 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_recv_secret, tvb, offset, 8, ENC_NA); |
380 | 0 | offset += 8; |
381 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_signing_opts, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
382 | 0 | offset += 4; |
383 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_echo_time, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
384 | 0 | break; |
385 | 0 | case FRAME_EXOPCODE_HARD_DISCONNECT: |
386 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_msgid, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
387 | 0 | offset += 1; |
388 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_rspid, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
389 | 0 | offset += 1; |
390 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_protocol, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
391 | 0 | offset += 4; |
392 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_session, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
393 | 0 | offset += 4; |
394 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_timestamp, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
395 | 0 | offset += 4; |
396 | |
|
397 | 0 | data_tvb_len = tvb_reported_length_remaining(tvb, offset); |
398 | 0 | if(data_tvb_len) |
399 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_signature, tvb, offset, 8, ENC_NA); |
400 | 0 | break; |
401 | 0 | case FRAME_EXOPCODE_SACK: |
402 | 0 | flag = tvb_get_uint8(tvb, offset); |
403 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
404 | 0 | offset += 1; |
405 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_retry, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
406 | 0 | offset += 1; |
407 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_nseq, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
408 | 0 | offset += 1; |
409 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_nrcv, tvb, offset, 1, ENC_LITTLE_ENDIAN); |
410 | 0 | offset += 1; |
411 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_padding, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
412 | 0 | offset += 2; |
413 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_timestamp, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
414 | 0 | offset += 4; |
415 | |
|
416 | 0 | if(flag & SACK_FLAGS_SACK_MASK1) |
417 | 0 | { |
418 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_sack_mask1, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
419 | 0 | offset += 4; |
420 | 0 | } |
421 | 0 | if(flag & SACK_FLAGS_SACK_MASK2) |
422 | 0 | { |
423 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_sack_mask2, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
424 | 0 | offset += 4; |
425 | 0 | } |
426 | 0 | if(flag & SACK_FLAGS_SEND_MASK1) |
427 | 0 | { |
428 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_send_mask1, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
429 | 0 | offset += 4; |
430 | 0 | } |
431 | 0 | if(flag & SACK_FLAGS_SEND_MASK2) |
432 | 0 | { |
433 | 0 | proto_tree_add_item(dpnet_tree, hf_dpnet_data_cframe_send_mask2, tvb, offset, 4, ENC_LITTLE_ENDIAN); |
434 | 0 | } |
435 | 0 | break; |
436 | 0 | default: |
437 | 0 | break; |
438 | 0 | } |
439 | 0 | } |
440 | | |
441 | | static int |
442 | | dissect_dpnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
443 | 0 | { |
444 | 0 | uint8_t lead; |
445 | |
|
446 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "DPNET"); |
447 | | /* Clear out stuff in the info column */ |
448 | 0 | col_clear(pinfo->cinfo,COL_INFO); |
449 | |
|
450 | 0 | proto_item *ti = proto_tree_add_item(tree, proto_dpnet, tvb, 0, -1, ENC_NA); |
451 | 0 | proto_tree *dpnet_tree = proto_item_add_subtree(ti, ett_dpnet); |
452 | |
|
453 | 0 | lead = tvb_get_uint8(tvb, 0); |
454 | 0 | if(lead == 0) |
455 | 0 | { |
456 | 0 | process_dpnet_query(dpnet_tree, tvb, pinfo); |
457 | 0 | } |
458 | 0 | else |
459 | 0 | { |
460 | 0 | if(lead & DPNET_COMMAND_DATA) |
461 | 0 | dpnet_process_data_frame(dpnet_tree, tvb, pinfo); |
462 | 0 | else |
463 | 0 | dpnet_process_control_frame(dpnet_tree, tvb, pinfo); |
464 | 0 | } |
465 | |
|
466 | 0 | return tvb_captured_length(tvb); |
467 | 0 | } |
468 | | |
469 | | void |
470 | | proto_register_dpnet(void) |
471 | 14 | { |
472 | 14 | static hf_register_info hf[] = { |
473 | 14 | { &hf_dpnet_lead, |
474 | 14 | { "Lead", "dpnet.lead", |
475 | 14 | FT_UINT8, BASE_DEC, |
476 | 14 | NULL, 0, |
477 | 14 | NULL, HFILL } |
478 | 14 | }, |
479 | 14 | { &hf_dpnet_command, |
480 | 14 | { "Command", "dpnet.command", |
481 | 14 | FT_UINT8, BASE_HEX, |
482 | 14 | VALS(packetquerytype), 0, |
483 | 14 | NULL, HFILL } |
484 | 14 | }, |
485 | 14 | { &hf_dpnet_payload, |
486 | 14 | { "Payload", "dpnet.payload", |
487 | 14 | FT_UINT16, BASE_HEX, |
488 | 14 | NULL, 0, |
489 | 14 | NULL, HFILL } |
490 | 14 | }, |
491 | 14 | { &hf_dpnet_type, |
492 | 14 | { "Type", "dpnet.type", |
493 | 14 | FT_UINT8, BASE_DEC, |
494 | 14 | VALS(packetenumttypes), 0, |
495 | 14 | NULL, HFILL } |
496 | 14 | }, |
497 | 14 | { &hf_dpnet_application, |
498 | 14 | { "Application GUID", "dpnet.application", |
499 | 14 | FT_GUID, BASE_NONE, |
500 | 14 | NULL, 0, |
501 | 14 | NULL, HFILL } |
502 | 14 | }, |
503 | 14 | { &hf_dpnet_data, |
504 | 14 | { "Data", "dpnet.data", |
505 | 14 | FT_BYTES, BASE_NONE, |
506 | 14 | NULL, 0, |
507 | 14 | NULL, HFILL } |
508 | 14 | }, |
509 | 14 | { &hf_dpnet_reply_offset, |
510 | 14 | { "Reply Offset", "dpnet.reply_offset", |
511 | 14 | FT_UINT32, BASE_DEC, |
512 | 14 | NULL, 0, |
513 | 14 | NULL, HFILL } |
514 | 14 | }, |
515 | 14 | { &hf_dpnet_response_size, |
516 | 14 | { "Response Size", "dpnet.response_size", |
517 | 14 | FT_UINT32, BASE_DEC, |
518 | 14 | NULL, 0, |
519 | 14 | NULL, HFILL } |
520 | 14 | }, |
521 | 14 | { &hf_dpnet_desc_size, |
522 | 14 | { "Description Size", "dpnet.desc_size", |
523 | 14 | FT_UINT32, BASE_DEC, |
524 | 14 | NULL, 0, |
525 | 14 | NULL, HFILL } |
526 | 14 | }, |
527 | 14 | { &hf_dpnet_desc_flags, |
528 | 14 | { "Description Flags", "dpnet.desc_flags", |
529 | 14 | FT_UINT16, BASE_HEX, |
530 | 14 | NULL, 0, |
531 | 14 | NULL, HFILL } |
532 | 14 | }, |
533 | 14 | { &hf_dpnet_max_players, |
534 | 14 | { "Max Players", "dpnet.max_players", |
535 | 14 | FT_UINT32, BASE_DEC, |
536 | 14 | NULL, 0, |
537 | 14 | NULL, HFILL } |
538 | 14 | }, |
539 | 14 | { &hf_dpnet_current_players, |
540 | 14 | { "Current Players", "dpnet.current_players", |
541 | 14 | FT_UINT32, BASE_DEC, |
542 | 14 | NULL, 0, |
543 | 14 | NULL, HFILL } |
544 | 14 | }, |
545 | 14 | { &hf_dpnet_session_offset, |
546 | 14 | { "Session Offset", "dpnet.session_offset", |
547 | 14 | FT_UINT32, BASE_DEC, |
548 | 14 | NULL, 0, |
549 | 14 | NULL, HFILL } |
550 | 14 | }, |
551 | 14 | { &hf_dpnet_session_size, |
552 | 14 | { "Session Size", "dpnet.session_size", |
553 | 14 | FT_UINT32, BASE_DEC, |
554 | 14 | NULL, 0, |
555 | 14 | NULL, HFILL } |
556 | 14 | }, |
557 | 14 | { &hf_dpnet_session_name, |
558 | 14 | { "Session name", "dpnet.session_name", |
559 | 14 | FT_STRING, BASE_NONE, |
560 | 14 | NULL, 0, |
561 | 14 | NULL, HFILL } |
562 | 14 | }, |
563 | 14 | { &hf_dpnet_password_offset, |
564 | 14 | { "Password Offset", "dpnet.password_offset", |
565 | 14 | FT_UINT32, BASE_DEC, |
566 | 14 | NULL, 0, |
567 | 14 | NULL, HFILL } |
568 | 14 | }, |
569 | 14 | { &hf_dpnet_password_size, |
570 | 14 | { "Password Size", "dpnet.password_size", |
571 | 14 | FT_UINT32, BASE_DEC, |
572 | 14 | NULL, 0, |
573 | 14 | NULL, HFILL } |
574 | 14 | }, |
575 | 14 | { &hf_dpnet_reserved_offset, |
576 | 14 | { "Reserved Offset", "dpnet.reserved_offset", |
577 | 14 | FT_UINT32, BASE_DEC, |
578 | 14 | NULL, 0, |
579 | 14 | NULL, HFILL } |
580 | 14 | }, |
581 | 14 | { &hf_dpnet_reserved_size, |
582 | 14 | { "Reserved Size", "dpnet.reserved_size", |
583 | 14 | FT_UINT32, BASE_DEC, |
584 | 14 | NULL, 0, |
585 | 14 | NULL, HFILL } |
586 | 14 | }, |
587 | 14 | { &hf_dpnet_application_offset, |
588 | 14 | { "Application Offset", "dpnet.application_offset", |
589 | 14 | FT_UINT32, BASE_DEC, |
590 | 14 | NULL, 0, |
591 | 14 | NULL, HFILL } |
592 | 14 | }, |
593 | 14 | { &hf_dpnet_application_size, |
594 | 14 | { "Application Size", "dpnet.application_size", |
595 | 14 | FT_UINT32, BASE_DEC, |
596 | 14 | NULL, 0, |
597 | 14 | NULL, HFILL } |
598 | 14 | }, |
599 | 14 | { &hf_dpnet_application_data, |
600 | 14 | { "Application data", "dpnet.application_data", |
601 | 14 | FT_BYTES, BASE_NONE, |
602 | 14 | NULL, 0, |
603 | 14 | NULL, HFILL } |
604 | 14 | }, |
605 | 14 | { &hf_dpnet_instance, |
606 | 14 | { "Instance GUID", "dpnet.instance", |
607 | 14 | FT_GUID, BASE_NONE, |
608 | 14 | NULL, 0, |
609 | 14 | NULL, HFILL } |
610 | 14 | }, |
611 | 14 | { &hf_dpnet_data_command, |
612 | 14 | { "Command", "dpnet.command", |
613 | 14 | FT_UINT8, BASE_HEX, |
614 | 14 | NULL, 0, |
615 | 14 | NULL, HFILL } |
616 | 14 | }, |
617 | 14 | { &hf_dpnet_data_cframe_control, |
618 | 14 | { "Control", "dpnet.cframe.control", |
619 | 14 | FT_UINT8, BASE_HEX, |
620 | 14 | VALS(msg_cframe_control), 0, |
621 | 14 | NULL, HFILL } |
622 | 14 | }, |
623 | 14 | { &hf_dpnet_data_cframe_msgid, |
624 | 14 | { "Message ID", "dpnet.cframe.msg_id", |
625 | 14 | FT_UINT8, BASE_HEX, |
626 | 14 | NULL, 0, |
627 | 14 | NULL, HFILL } |
628 | 14 | }, |
629 | 14 | { &hf_dpnet_data_cframe_rspid, |
630 | 14 | { "Response ID", "dpnet.cframe.rsp_id", |
631 | 14 | FT_UINT8, BASE_HEX, |
632 | 14 | NULL, 0, |
633 | 14 | NULL, HFILL } |
634 | 14 | }, |
635 | 14 | { &hf_dpnet_data_cframe_protocol, |
636 | 14 | { "Protocol", "dpnet.cframe.protocol", |
637 | 14 | FT_UINT32, BASE_HEX, |
638 | 14 | VALS(protocol_versions), 0, |
639 | 14 | NULL, HFILL } |
640 | 14 | }, |
641 | 14 | { &hf_dpnet_data_cframe_session, |
642 | 14 | { "Session", "dpnet.cframe.session", |
643 | 14 | FT_UINT32, BASE_HEX, |
644 | 14 | NULL, 0, |
645 | 14 | NULL, HFILL } |
646 | 14 | }, |
647 | 14 | { &hf_dpnet_data_cframe_timestamp, |
648 | 14 | { "Timestamp", "dpnet.cframe.timestamp", |
649 | 14 | FT_UINT32, BASE_DEC, |
650 | 14 | NULL, 0, |
651 | 14 | NULL, HFILL } |
652 | 14 | }, |
653 | 14 | { &hf_dpnet_data_cframe_padding, |
654 | 14 | { "Padding", "dpnet.cframe.padding", |
655 | 14 | FT_UINT16, BASE_DEC, |
656 | 14 | NULL, 0, |
657 | 14 | NULL, HFILL } |
658 | 14 | }, |
659 | 14 | { &hf_dpnet_data_cframe_flags, |
660 | 14 | { "Flags", "dpnet.cframe.flags", |
661 | 14 | FT_UINT8, BASE_HEX, |
662 | 14 | VALS(sack_flags), 0, |
663 | 14 | NULL, HFILL } |
664 | 14 | }, |
665 | 14 | { &hf_dpnet_data_cframe_retry, |
666 | 14 | { "Retry", "dpnet.cframe.retry", |
667 | 14 | FT_UINT8, BASE_HEX, |
668 | 14 | NULL, 0, |
669 | 14 | NULL, HFILL } |
670 | 14 | }, |
671 | 14 | { &hf_dpnet_data_cframe_nseq, |
672 | 14 | { "Next Sequence", "dpnet.cframe.nseq", |
673 | 14 | FT_UINT8, BASE_HEX, |
674 | 14 | NULL, 0, |
675 | 14 | NULL, HFILL } |
676 | 14 | }, |
677 | 14 | { &hf_dpnet_data_cframe_nrcv, |
678 | 14 | { "Received", "dpnet.cframe.nrcv", |
679 | 14 | FT_UINT8, BASE_HEX, |
680 | 14 | NULL, 0, |
681 | 14 | NULL, HFILL } |
682 | 14 | }, |
683 | 14 | { &hf_dpnet_data_cframe_sack_mask1, |
684 | 14 | { "SACK Mask1", "dpnet.cframe.sack.mask1", |
685 | 14 | FT_UINT32, BASE_HEX, |
686 | 14 | NULL, 0, |
687 | 14 | NULL, HFILL } |
688 | 14 | }, |
689 | 14 | { &hf_dpnet_data_cframe_sack_mask2, |
690 | 14 | { "SACK Mask2", "dpnet.cframe.sack.mask2", |
691 | 14 | FT_UINT32, BASE_HEX, |
692 | 14 | NULL, 0, |
693 | 14 | NULL, HFILL } |
694 | 14 | }, |
695 | 14 | { &hf_dpnet_data_cframe_send_mask1, |
696 | 14 | { "Send Mask1", "dpnet.cframe.send.mask1", |
697 | 14 | FT_UINT32, BASE_HEX, |
698 | 14 | NULL, 0, |
699 | 14 | NULL, HFILL } |
700 | 14 | }, |
701 | 14 | { &hf_dpnet_data_cframe_send_mask2, |
702 | 14 | { "Send Mask2", "dpnet.cframe.send.mask2", |
703 | 14 | FT_UINT32, BASE_HEX, |
704 | 14 | NULL, 0, |
705 | 14 | NULL, HFILL } |
706 | 14 | }, |
707 | 14 | { &hf_dpnet_data_cframe_signature, |
708 | 14 | { "Signature", "dpnet.cframe.signature", |
709 | 14 | FT_UINT64, BASE_HEX, |
710 | 14 | NULL, 0, |
711 | 14 | NULL, HFILL } |
712 | 14 | }, |
713 | 14 | { &hf_dpnet_data_cframe_send_secret, |
714 | 14 | { "Sender Secret", "dpnet.cframe.sender_secret", |
715 | 14 | FT_UINT64, BASE_HEX, |
716 | 14 | NULL, 0, |
717 | 14 | NULL, HFILL } |
718 | 14 | }, |
719 | 14 | { &hf_dpnet_data_cframe_recv_secret, |
720 | 14 | { "Receiver Secret", "dpnet.cframe.receiver_secret", |
721 | 14 | FT_UINT64, BASE_HEX, |
722 | 14 | NULL, 0, |
723 | 14 | NULL, HFILL } |
724 | 14 | }, |
725 | 14 | { &hf_dpnet_data_cframe_signing_opts, |
726 | 14 | { "Signing Options", "dpnet.cframe.sign_opt", |
727 | 14 | FT_UINT32, BASE_HEX, |
728 | 14 | VALS(signing_opts), 0, |
729 | 14 | NULL, HFILL } |
730 | 14 | }, |
731 | 14 | { &hf_dpnet_data_cframe_echo_time, |
732 | 14 | { "Signing Options", "dpnet.cframe.echo_time", |
733 | 14 | FT_UINT32, BASE_HEX, |
734 | 14 | NULL, 0, |
735 | 14 | NULL, HFILL } |
736 | 14 | }, |
737 | 14 | { &hf_dpnet_data_seq, |
738 | 14 | { "Sequence", "dpnet.sequence", |
739 | 14 | FT_UINT8, BASE_HEX, |
740 | 14 | NULL, 0, |
741 | 14 | NULL, HFILL } |
742 | 14 | }, |
743 | 14 | { &hf_dpnet_data_nseq, |
744 | 14 | { "Next Sequence", "dpnet.next", |
745 | 14 | FT_UINT8, BASE_HEX, |
746 | 14 | NULL, 0, |
747 | 14 | NULL, HFILL } |
748 | 14 | }, |
749 | 14 | {&hf_dpnet_command_data, |
750 | 14 | {"Control Data", "dpnet.control.data", |
751 | 14 | FT_BOOLEAN, 8, |
752 | 14 | NULL, DPNET_COMMAND_DATA, |
753 | 14 | NULL, HFILL} |
754 | 14 | }, |
755 | 14 | {&hf_dpnet_command_reliable, |
756 | 14 | {"Reliable", "dpnet.control.reliable", |
757 | 14 | FT_BOOLEAN, 8, |
758 | 14 | NULL, DPNET_COMMAND_RELIABLE, |
759 | 14 | NULL, HFILL} |
760 | 14 | }, |
761 | 14 | {&hf_dpnet_command_seq, |
762 | 14 | {"Sequential", "dpnet.control.sequential", |
763 | 14 | FT_BOOLEAN, 8, |
764 | 14 | NULL, DPNET_COMMAND_SEQUENTIAL, |
765 | 14 | NULL, HFILL} |
766 | 14 | }, |
767 | 14 | {&hf_dpnet_command_poll, |
768 | 14 | {"Poll", "dpnet.control.poll", |
769 | 14 | FT_BOOLEAN, 8, |
770 | 14 | NULL, DPNET_COMMAND_POLL, |
771 | 14 | NULL, HFILL} |
772 | 14 | }, |
773 | 14 | {&hf_dpnet_command_new_msg, |
774 | 14 | {"New Message", "dpnet.control.new_msg", |
775 | 14 | FT_BOOLEAN, 8, |
776 | 14 | NULL, DPNET_COMMAND_NEW_MSG, |
777 | 14 | NULL, HFILL} |
778 | 14 | }, |
779 | 14 | {&hf_dpnet_command_end_msg, |
780 | 14 | {"End Message", "dpnet.control.end_msg", |
781 | 14 | FT_BOOLEAN, 8, |
782 | 14 | NULL, DPNET_COMMAND_END_MSG, |
783 | 14 | NULL, HFILL} |
784 | 14 | }, |
785 | 14 | {&hf_dpnet_command_user1, |
786 | 14 | {"User 1", "dpnet.control.user1", |
787 | 14 | FT_BOOLEAN, 8, |
788 | 14 | NULL, DPNET_COMMAND_USER_1, |
789 | 14 | NULL, HFILL} |
790 | 14 | }, |
791 | 14 | {&hf_dpnet_command_user2, |
792 | 14 | {"CFrame", "dpnet.control.cframe", |
793 | 14 | FT_BOOLEAN, 8, |
794 | 14 | NULL, DPNET_COMMAND_CFRAME, |
795 | 14 | NULL, HFILL} |
796 | 14 | }, |
797 | 14 | {&hf_dpnet_desc_client_server, |
798 | 14 | {"Client", "dpnet.session.client", |
799 | 14 | FT_BOOLEAN, 16, |
800 | 14 | TFS(&tfs_flags_game_client), SESSION_CLIENT_SERVER, |
801 | 14 | NULL, HFILL} |
802 | 14 | }, |
803 | 14 | {&hf_dpnet_desc_migrate_host, |
804 | 14 | {"Migrate", "dpnet.session.migrate", |
805 | 14 | FT_BOOLEAN, 16, |
806 | 14 | TFS(&tfs_flags_migrate), SESSION_MIGRATE_HOST, |
807 | 14 | NULL, HFILL} |
808 | 14 | }, |
809 | 14 | {&hf_dpnet_desc_nodpnsvr, |
810 | 14 | {"dpnsvr", "dpnet.session.dpnsvr", |
811 | 14 | FT_BOOLEAN, 16, |
812 | 14 | TFS(&tfs_flags_dpnsvr), SESSION_NODPNSVR, |
813 | 14 | NULL, HFILL} |
814 | 14 | }, |
815 | 14 | {&hf_dpnet_desc_req_password, |
816 | 14 | {"Password", "dpnet.session.password", |
817 | 14 | FT_BOOLEAN, 16, |
818 | 14 | TFS(&tfs_flags_password_required), SESSION_REQUIREPASSWORD, |
819 | 14 | NULL, HFILL} |
820 | 14 | }, |
821 | 14 | {&hf_dpnet_desc_no_enums, |
822 | 14 | {"Enumeration", "dpnet.session.enumeration", |
823 | 14 | FT_BOOLEAN, 16, |
824 | 14 | TFS(&tfs_flags_enumeration), SESSION_NOENUMS, |
825 | 14 | NULL, HFILL} |
826 | 14 | }, |
827 | 14 | {&hf_dpnet_desc_fast_signed, |
828 | 14 | {"Fast signing", "dpnet.session.fast_sign", |
829 | 14 | FT_BOOLEAN, 16, |
830 | 14 | TFS(&tfs_flags_fast), SESSION_FAST_SIGNED, |
831 | 14 | NULL, HFILL} |
832 | 14 | }, |
833 | 14 | {&hf_dpnet_desc_full_signed, |
834 | 14 | {"Full signing", "dpnet.session.full_sign", |
835 | 14 | FT_BOOLEAN, 16, |
836 | 14 | TFS(&tfs_flags_full), SESSION_FULL_SIGNED, |
837 | 14 | NULL, HFILL} |
838 | 14 | }, |
839 | 14 | }; |
840 | | |
841 | | /* Setup protocol subtree array */ |
842 | 14 | static int *ett[] = { |
843 | 14 | &ett_dpnet, |
844 | 14 | &ett_dpnet_command_flags, |
845 | 14 | &ett_dpnet_desc_flags |
846 | 14 | }; |
847 | | |
848 | | |
849 | 14 | proto_dpnet = proto_register_protocol ("DirectPlay 8 protocol", "DPNET", "dpnet"); |
850 | | |
851 | 14 | proto_register_field_array(proto_dpnet, hf, array_length(hf)); |
852 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
853 | | |
854 | 14 | dpnet_handle = register_dissector("dpnet", dissect_dpnet, proto_dpnet); |
855 | 14 | } |
856 | | |
857 | | void |
858 | | proto_reg_handoff_dpnet(void) |
859 | 14 | { |
860 | 14 | dissector_add_uint("udp.port", DPNET_PORT, dpnet_handle); |
861 | 14 | } |
862 | | |
863 | | /* |
864 | | * Editor modelines |
865 | | * |
866 | | * Local Variables: |
867 | | * c-basic-offset: 4 |
868 | | * tab-width: 8 |
869 | | * indent-tabs-mode: nil |
870 | | * End: |
871 | | * |
872 | | * ex: set shiftwidth=4 tabstop=8 expandtab: |
873 | | * :indentSize=4:tabSize=8:noTabs=true: |
874 | | */ |