We always HAVE_CONFIG_H so don't bother checking whether we have it or not.
[metze/wireshark/wip.git] / epan / dissectors / packet-wow.c
1 /* packet-wow.c
2  * Routines for World of Warcraft (WoW) protocol dissection
3  * Copyright 2008-2009, Stephen Fisher (see AUTHORS file)
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
24  * USA.
25  */
26
27 /* This dissector is based on the MaNGOS project's source code, Stanford's
28  * SRP protocol documents (http://srp.stanford.edu) and RFC 2945: "The SRP
29  * Authentication and Key Exchange System." */
30
31 #include "config.h"
32
33 #include <glib.h>
34
35 #include <epan/packet.h>
36 #include <epan/prefs.h>
37 #include "packet-tcp.h"
38
39 typedef enum {
40         AUTH_LOGON_CHALLENGE = 0x00,
41         AUTH_LOGON_PROOF     = 0x01,
42         REALM_LIST           = 0x10,
43         XFER_INITIATE        = 0x30,
44         XFER_DATA            = 0x31,
45         XFER_ACCEPT          = 0x32,
46         XFER_RESUME          = 0x33,
47         XFER_CANCEL          = 0x34
48 } auth_cmd_e;
49
50 static const value_string cmd_vs[] = {
51         { AUTH_LOGON_CHALLENGE, "Authentication Logon Challenge" },
52         { AUTH_LOGON_PROOF,     "Authentication Logon Proof"     },
53         { REALM_LIST,           "Realm List"                     },
54         { XFER_INITIATE,        "Transfer Initiate"              },
55         { XFER_DATA,            "Transfer Data"                  },
56         { XFER_ACCEPT,          "Transfer Accept"                },
57         { XFER_RESUME,          "Transfer Resume"                },
58         { XFER_CANCEL,          "Transfer Cancel"                },
59         { 0, NULL                                                }
60 };
61
62 static const value_string account_type_vs[] = {
63         { 0, "Player"        },
64         { 1, "Moderator"     },
65         { 2, "Game master"   },
66         { 3, "Administrator" },
67         { 0, NULL            }
68 };
69
70 static const value_string realm_status_vs[] = {
71         { 0, "Online"  },
72         { 1, "Locked"  },
73         { 2, "Offline" },
74         { 0, NULL      }
75 };
76
77 static const value_string realm_type_vs[] = {
78         { 0, "Normal"                             },
79         { 1, "Player versus player"               },
80         { 4, "Normal (2)"                         },
81         { 6, "Role playing normal"                },
82         { 8, "Role playing player versus player)" },
83         { 0, NULL                                 }
84 };
85
86 #define WOW_PORT 3724
87
88 #define WOW_CLIENT_TO_SERVER pinfo->destport == WOW_PORT
89 #define WOW_SERVER_TO_CLIENT pinfo->srcport  == WOW_PORT
90
91 /* Initialize the protocol and registered fields */
92 static int proto_wow = -1;
93
94 static int hf_wow_command = -1;
95 static int hf_wow_error = -1;
96 static int hf_wow_pkt_size = -1;
97 static int hf_wow_gamename = -1;
98 static int hf_wow_version1 = -1;
99 static int hf_wow_version2 = -1;
100 static int hf_wow_version3 = -1;
101 static int hf_wow_build = -1;
102 static int hf_wow_platform = -1;
103 static int hf_wow_os = -1;
104 static int hf_wow_country = -1;
105 static int hf_wow_timezone_bias = -1;
106 static int hf_wow_ip = -1;
107 static int hf_wow_srp_i_len = -1;
108 static int hf_wow_srp_i = -1;
109
110 static int hf_wow_srp_b = -1;
111 static int hf_wow_srp_g_len = -1;
112 static int hf_wow_srp_g = -1;
113 static int hf_wow_srp_n_len = -1;
114 static int hf_wow_srp_n = -1;
115 static int hf_wow_srp_s = -1;
116
117 static int hf_wow_srp_a = -1;
118 static int hf_wow_srp_m1 = -1;
119 static int hf_wow_crc_hash = -1;
120 static int hf_wow_num_keys = -1;
121
122 static int hf_wow_srp_m2 = -1;
123
124 static int hf_wow_num_realms = -1;
125 static int hf_wow_realm_type = -1;
126 static int hf_wow_realm_status = -1;
127 static int hf_wow_realm_color = -1;
128 static int hf_wow_realm_name = -1;
129 static int hf_wow_realm_socket = -1;
130 static int hf_wow_realm_population_level = -1;
131 static int hf_wow_realm_num_characters = -1;
132 static int hf_wow_realm_timezone = -1;
133
134 static gboolean wow_preference_desegment = TRUE;
135
136 static gint ett_wow = -1;
137 static gint ett_wow_realms = -1;
138
139 static void dissect_wow_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
140 static guint get_wow_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset);
141
142
143 static gboolean
144 dissect_wow(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
145 {
146         gint8 size_field_offset = -1;
147         guint8 cmd;
148
149         cmd = tvb_get_guint8(tvb, 0);
150
151         if(WOW_SERVER_TO_CLIENT && cmd == REALM_LIST)
152                 size_field_offset = 1;
153         if(WOW_CLIENT_TO_SERVER && cmd == AUTH_LOGON_CHALLENGE)
154                 size_field_offset = 2;
155
156         if(size_field_offset > -1) {
157                 tcp_dissect_pdus(tvb, pinfo, tree, wow_preference_desegment,
158                                  size_field_offset+2, get_wow_pdu_len,
159                                  dissect_wow_pdu);
160
161         } else {
162                 /* Doesn't have a size field, so it cannot span multiple
163                    segments.  Therefore, dissect this packet normally. */
164                 dissect_wow_pdu(tvb, pinfo, tree);
165         }
166
167         return TRUE;
168 }
169
170 static guint
171 get_wow_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset)
172 {
173         gint8 size_field_offset = -1;
174         guint8 cmd;
175         guint16 pkt_len;
176
177         cmd = tvb_get_guint8(tvb, offset);
178
179         if(WOW_SERVER_TO_CLIENT && cmd == REALM_LIST)
180                 size_field_offset = 1;
181         if(WOW_CLIENT_TO_SERVER && cmd == AUTH_LOGON_CHALLENGE)
182                 size_field_offset = 2;
183
184         pkt_len = tvb_get_letohs(tvb, size_field_offset);
185
186         return pkt_len + size_field_offset + 2;
187 }
188
189
190 static void
191 dissect_wow_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
192 {
193         proto_item *ti;
194         proto_tree *wow_tree, *wow_realms_tree;
195
196         gchar *string, *realm_name;
197         guint8 cmd, srp_i_len, srp_g_len, srp_n_len;
198         guint16 num_realms;
199         guint32 offset = 0;
200         gint len, i;
201
202         col_set_str(pinfo->cinfo, COL_PROTOCOL, "WOW");
203
204         col_clear(pinfo->cinfo, COL_INFO);
205
206         cmd = tvb_get_guint8(tvb, offset);
207
208         if(check_col(pinfo->cinfo, COL_INFO)) {
209                 col_set_str(pinfo->cinfo, COL_INFO,
210                             val_to_str_const(cmd, cmd_vs,
211                                        "Unrecognized packet type"));
212         }
213
214         if(tree) {
215                 ti = proto_tree_add_item(tree, proto_wow, tvb, 0, -1, ENC_NA);
216                 wow_tree = proto_item_add_subtree(ti, ett_wow);
217
218                 proto_tree_add_item(wow_tree, hf_wow_command, tvb, offset, 1,
219                                     ENC_LITTLE_ENDIAN);
220                 offset += 1;
221
222                 switch(cmd) {
223
224                 case AUTH_LOGON_CHALLENGE :
225
226                         if(WOW_CLIENT_TO_SERVER) {
227                                 proto_tree_add_item(wow_tree, hf_wow_error, tvb,
228                                                     offset, 1, ENC_LITTLE_ENDIAN);
229                                 offset += 1;
230
231                                 proto_tree_add_item(wow_tree, hf_wow_pkt_size,
232                                                     tvb, offset, 2, ENC_LITTLE_ENDIAN);
233                                 offset += 2;
234
235                                 string = g_strreverse(tvb_get_ephemeral_string(tvb, offset, 4));
236                                 proto_tree_add_string(wow_tree, hf_wow_gamename,
237                                                       tvb, offset, 4, string);
238                                 offset += 4;
239
240                                 proto_tree_add_item(wow_tree, hf_wow_version1,
241                                                     tvb, offset, 1, ENC_LITTLE_ENDIAN);
242                                 offset += 1;
243
244                                 proto_tree_add_item(wow_tree, hf_wow_version2,
245                                                     tvb, offset, 1, ENC_LITTLE_ENDIAN);
246                                 offset += 1;
247
248                                 proto_tree_add_item(wow_tree, hf_wow_version3,
249                                                     tvb, offset, 1, ENC_LITTLE_ENDIAN);
250                                 offset += 1;
251
252                                 proto_tree_add_item(wow_tree, hf_wow_build, tvb,
253                                                     offset, 2, ENC_LITTLE_ENDIAN);
254                                 offset += 2;
255
256                                 string = g_strreverse(tvb_get_ephemeral_string(tvb, offset, 4));
257                                 proto_tree_add_string(wow_tree, hf_wow_platform,
258                                                       tvb, offset, 4, string);
259                                 offset += 4;
260
261                                 string = g_strreverse(tvb_get_ephemeral_string(tvb, offset, 4));
262                                 proto_tree_add_string(wow_tree, hf_wow_os, tvb,
263                                                       offset, 4, string);
264                                 offset += 4;
265
266                                 string = g_strreverse(tvb_get_ephemeral_string(tvb, offset, 4));
267                                 proto_tree_add_string(wow_tree, hf_wow_country,
268                                                       tvb, offset, 4, string);
269                                 offset += 4;
270
271                                 proto_tree_add_item(wow_tree,
272                                                     hf_wow_timezone_bias,
273                                                     tvb, offset, 4, ENC_LITTLE_ENDIAN);
274                                 offset += 4;
275
276                                 proto_tree_add_item(wow_tree, hf_wow_ip, tvb,
277                                                     offset, 4, ENC_BIG_ENDIAN);
278                                 offset += 4;
279
280                                 proto_tree_add_item(wow_tree,
281                                                     hf_wow_srp_i_len,
282                                                     tvb, offset, 1, ENC_LITTLE_ENDIAN);
283                                 srp_i_len = tvb_get_guint8(tvb, offset);
284                                 offset += 1;
285
286                                 proto_tree_add_item(wow_tree,
287                                                     hf_wow_srp_i, tvb,
288                                                     offset, srp_i_len,
289                                                     ENC_ASCII|ENC_NA);
290                                 offset += srp_i_len;
291
292
293                         } else if(WOW_SERVER_TO_CLIENT) {
294                                 proto_tree_add_item(wow_tree, hf_wow_error, tvb,
295                                                     offset, 1, ENC_LITTLE_ENDIAN);
296                                 offset += 1;
297
298                                 offset += 1; /* Unknown field */
299
300                                 proto_tree_add_item(wow_tree, hf_wow_srp_b, tvb,
301                                                     offset, 32, ENC_NA);
302                                 offset += 32;
303
304                                 proto_tree_add_item(wow_tree, hf_wow_srp_g_len,
305                                                     tvb, offset, 1, ENC_LITTLE_ENDIAN);
306                                 srp_g_len = tvb_get_guint8(tvb, offset);
307                                 offset += 1;
308
309                                 proto_tree_add_item(wow_tree, hf_wow_srp_g, tvb,
310                                                     offset, srp_g_len, ENC_NA);
311                                 offset += srp_g_len;
312
313                                 proto_tree_add_item(wow_tree, hf_wow_srp_n_len,
314                                                     tvb, offset, 1, ENC_LITTLE_ENDIAN);
315                                 srp_n_len = tvb_get_guint8(tvb, offset);
316                                 offset += 1;
317
318                                 proto_tree_add_item(wow_tree, hf_wow_srp_n, tvb,
319                                                     offset, srp_n_len, ENC_NA);
320                                 offset += srp_n_len;
321
322                                 proto_tree_add_item(wow_tree, hf_wow_srp_s, tvb,
323                                                     offset, 32, ENC_NA);
324                                 offset += 32;
325
326                                 offset += 16; /* Unknown field */
327                         }
328
329                         break;
330
331                 case AUTH_LOGON_PROOF :
332
333                         if(WOW_CLIENT_TO_SERVER) {
334                                 proto_tree_add_item(wow_tree, hf_wow_srp_a, tvb,
335                                                     offset, 32, ENC_NA);
336                                 offset += 32;
337
338                                 proto_tree_add_item(wow_tree, hf_wow_srp_m1,
339                                                     tvb, offset, 20, ENC_NA);
340                                 offset += 20;
341
342                                 proto_tree_add_item(wow_tree, hf_wow_crc_hash,
343                                                     tvb, offset, 20, ENC_NA);
344                                 offset += 20;
345
346                                 proto_tree_add_item(wow_tree, hf_wow_num_keys,
347                                                     tvb, offset, 1, ENC_LITTLE_ENDIAN);
348                                 offset += 1;
349
350                                 offset += 1; /* Unknown field */
351
352                         } else if(WOW_SERVER_TO_CLIENT) {
353                                 proto_tree_add_item(wow_tree, hf_wow_error, tvb,
354                                                     offset, 1, ENC_LITTLE_ENDIAN);
355                                 offset += 1;
356
357                                 proto_tree_add_item(wow_tree, hf_wow_srp_m2,
358                                                     tvb, offset, 20, ENC_NA);
359                                 offset += 20;
360
361                                 offset += 4; /* Unknown field */
362
363                                 offset += 2; /* Unknown field */
364                         }
365
366                         break;
367
368                 case REALM_LIST :
369
370                         if(WOW_CLIENT_TO_SERVER) {
371
372
373                         } else if(WOW_SERVER_TO_CLIENT) {
374
375                                 proto_tree_add_item(wow_tree, hf_wow_pkt_size,
376                                                     tvb, offset, 2, ENC_LITTLE_ENDIAN);
377                                 offset += 2;
378
379                                 offset += 4; /* Unknown field; always 0 */
380
381                                 proto_tree_add_item(wow_tree, hf_wow_num_realms,
382                                                     tvb, offset, 2, ENC_LITTLE_ENDIAN);
383                                 num_realms = tvb_get_letohs(tvb, offset);
384                                 offset += 2;
385
386                                 for(i = 1; i <= num_realms; i++) {
387                                         realm_name = tvb_get_ephemeral_stringz(tvb,
388                                                                      offset + 3,
389                                                                      &len);
390
391                                         ti = proto_tree_add_text(wow_tree, tvb,
392                                                                  offset, 0,
393                                                                  "%s",
394                                                                  realm_name);
395
396                                         wow_realms_tree = proto_item_add_subtree(ti, ett_wow_realms);
397                                         proto_tree_add_item(wow_realms_tree, hf_wow_realm_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
398                                         offset += 1;
399
400                                         proto_tree_add_item(wow_realms_tree, hf_wow_realm_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
401                                         offset += 1;
402
403                                         proto_tree_add_item(wow_realms_tree, hf_wow_realm_color, tvb, offset, 1, ENC_LITTLE_ENDIAN);
404                                         offset += 1;
405
406                                         proto_tree_add_string(wow_realms_tree, hf_wow_realm_name, tvb, offset, len, realm_name);
407                                         offset += len;
408
409                                         string = tvb_get_ephemeral_stringz(tvb, offset,
410                                                                  &len);
411                                         proto_tree_add_string(wow_realms_tree, hf_wow_realm_socket, tvb, offset, len, string);
412                                         offset += len;
413
414                                         proto_tree_add_item(wow_realms_tree, hf_wow_realm_population_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
415                                         offset += 4;
416
417                                         proto_tree_add_item(wow_realms_tree, hf_wow_realm_num_characters, tvb, offset, 1, ENC_LITTLE_ENDIAN);
418                                         offset += 1;
419
420                                         proto_tree_add_item(wow_realms_tree, hf_wow_realm_timezone, tvb, offset, 1, ENC_LITTLE_ENDIAN);
421                                         offset += 1;
422
423                                         offset += 1; /* Unknown field */
424                                 }
425
426                                 break;
427                         }
428                 }
429         }
430 }
431
432
433 void
434 proto_register_wow(void)
435 {
436         module_t *wow_module; /* For our preferences */
437
438         static hf_register_info hf[] = {
439                 { &hf_wow_command,
440                   { "Command", "wow.cmd",
441                     FT_UINT8, BASE_HEX, VALS(cmd_vs), 0,
442                     "Type of packet", HFILL }
443                 },
444
445                 { &hf_wow_error,
446                   { "Error", "wow.error",
447                     FT_UINT8, BASE_DEC, 0, 0,
448                     NULL, HFILL }
449                 },
450                 { &hf_wow_pkt_size,
451                   { "Packet size", "wow.pkt_size",
452                     FT_UINT16, BASE_DEC, 0, 0,
453                     NULL, HFILL }
454                 },
455                 { &hf_wow_gamename,
456                   { "Game name", "wow.gamename",
457                     FT_STRING, BASE_NONE, 0, 0,
458                     NULL, HFILL }
459                 },
460                 { &hf_wow_version1,
461                   { "Version 1", "wow.version1",
462                     FT_UINT8, BASE_DEC, 0, 0,
463                     NULL, HFILL }
464                 },
465                 { &hf_wow_version2,
466                   { "Version 2", "wow.version2",
467                     FT_UINT8, BASE_DEC, 0, 0,
468                     NULL, HFILL }
469                 },
470                 { &hf_wow_version3,
471                   { "Version 3", "wow.version3",
472                     FT_UINT8, BASE_DEC, 0, 0,
473                     NULL, HFILL }
474                 },
475                 { &hf_wow_build,
476                   { "Build", "wow.build",
477                     FT_UINT16, BASE_DEC, 0, 0,
478                     NULL, HFILL }
479                 },
480                 { &hf_wow_platform,
481                   { "Platform", "wow.platform",
482                     FT_STRING, BASE_NONE, 0, 0,
483                     "CPU architecture of client system", HFILL }
484                 },
485                 { &hf_wow_os,
486                   { "Operating system", "wow.os",
487                     FT_STRING, BASE_NONE, 0, 0,
488                     "Operating system of client system", HFILL }
489                 },
490                 { &hf_wow_country,
491                   { "Country", "wow.country",
492                     FT_STRING, BASE_NONE, 0, 0,
493                     "Language and country of client system", HFILL }
494                 },
495                 { &hf_wow_timezone_bias,
496                   { "Timezone bias", "wow.timezone_bias",
497                     FT_UINT32, BASE_DEC, 0, 0,
498                     NULL, HFILL }
499                 },
500                 { &hf_wow_ip,
501                   { "IP address", "wow.ip",
502                     FT_IPv4, BASE_NONE, 0, 0,
503                     "Client's actual IP address", HFILL }
504                 },
505                 { &hf_wow_srp_i_len,
506                   { "SRP I length", "wow.srp.i_len",
507                     FT_UINT8, BASE_DEC, 0, 0,
508                     "Secure Remote Password protocol 'I' value length", HFILL }
509                 },
510                 { &hf_wow_srp_i,
511                   { "SRP I", "wow.srp.i",
512                     FT_STRING, BASE_NONE, 0, 0,
513                     "Secure Remote Password protocol 'I' value (username)", HFILL }
514                 },
515                 { &hf_wow_srp_b,
516                   { "SRP B", "wow.srp.b",
517                     FT_BYTES, BASE_NONE, 0, 0,
518                     "Secure Remote Password protocol 'B' value (one of the public ephemeral values)", HFILL }
519                 },
520                 { &hf_wow_srp_g_len,
521                   { "SRP g length", "wow.srp.g_len",
522                     FT_UINT8, BASE_DEC, 0, 0,
523                     "Secure Remote Password protocol 'g' value length",
524                     HFILL }
525                 },
526                 { &hf_wow_srp_g,
527                   { "SRP g", "wow.srp.g",
528                     FT_BYTES, BASE_NONE, 0, 0,
529                     "Secure Remote Password protocol 'g' value", HFILL }
530                 },
531                 { &hf_wow_srp_n_len,
532                   { "SRP N length", "wow.srp.n_len",
533                     FT_UINT8, BASE_DEC, 0, 0,
534                     "Secure Remote Password protocol 'N' value length",
535                     HFILL }
536                 },
537                 { &hf_wow_srp_n,
538                   { "SRP N", "wow.srp.n",
539                     FT_BYTES, BASE_NONE, 0, 0,
540                     "Secure Remote Password protocol 'N' value (a large safe prime)", HFILL }
541                 },
542                 { &hf_wow_srp_s,
543                   { "SRP s", "wow.srp.s",
544                     FT_BYTES, BASE_NONE, 0, 0,
545                     "Secure Remote Password protocol 's' (user's salt) value",
546                     HFILL }
547                 },
548                 { &hf_wow_srp_a,
549                   { "SRP A", "wow.srp.a",
550                     FT_BYTES, BASE_NONE, 0, 0,
551                     "Secure Remote Password protocol 'A' value (one of the public ephemeral values)", HFILL }
552                 },
553                 { &hf_wow_srp_m1,
554                   { "SRP M1", "wow.srp.m1",
555                     FT_BYTES, BASE_NONE, 0, 0,
556                     "Secure Remote Password protocol 'M1' value", HFILL }
557                 },
558                 { &hf_wow_crc_hash,
559                   { "CRC hash", "wow.crc_hash",
560                     FT_BYTES, BASE_NONE, 0, 0,
561                     NULL, HFILL }
562                 },
563                 { &hf_wow_num_keys,
564                   { "Number of keys", "wow.num_keys",
565                     FT_UINT8, BASE_DEC, 0, 0,
566                     NULL, HFILL }
567                 },
568                 { &hf_wow_srp_m2,
569                   { "SRP M2", "wow.srp.m2",
570                     FT_BYTES, BASE_NONE, 0, 0,
571                     "Secure Remote Password protocol 'M2' value", HFILL }
572                 },
573                 { &hf_wow_num_realms,
574                   { "Number of realms", "wow.num_realms",
575                     FT_UINT16, BASE_DEC, 0, 0,
576                     NULL, HFILL }
577                 },
578                 { &hf_wow_realm_type,
579                   { "Type", "wow.realm_type",
580                     FT_UINT8, BASE_DEC, VALS(realm_type_vs), 0,
581                     "Also known as realm icon", HFILL }
582                 },
583                 { &hf_wow_realm_status,
584                   { "Status", "wow.realm_status",
585                     FT_UINT8, BASE_DEC, VALS(realm_status_vs), 0,
586                     NULL, HFILL }
587                 },
588                 { &hf_wow_realm_color,
589                   { "Color", "wow.realm_color",
590                     FT_UINT8, BASE_DEC, 0, 0,
591                     NULL, HFILL }
592                 },
593                 { &hf_wow_realm_name,
594                   { "Name", "wow.realm_name",
595                     FT_STRINGZ, BASE_NONE, 0, 0,
596                     NULL, HFILL }
597                 },
598                 { &hf_wow_realm_socket,
599                   { "Server socket", "wow.realm_socket",
600                     FT_STRINGZ, BASE_NONE, 0, 0,
601                     "IP address and port to connect to on the server to reach this realm", HFILL }
602                 },
603                 { &hf_wow_realm_population_level,
604                   { "Population level", "wow.realm_population_level",
605                     FT_FLOAT, BASE_NONE, 0, 0,
606                     NULL, HFILL }
607                 },
608                 { &hf_wow_realm_num_characters,
609                   { "Number of characters", "wow.realm_num_characters",
610                     FT_UINT8, BASE_DEC, 0, 0,
611                     "Number of characters the user has in this realm", HFILL }
612                 },
613                 { &hf_wow_realm_timezone,
614                   { "Timezone", "wow.realm_timezone",
615                     FT_UINT8, BASE_DEC, 0, 0,
616                     NULL, HFILL }
617                 }
618         };
619
620         static gint *ett[] = {
621                 &ett_wow,
622                 &ett_wow_realms
623         };
624
625         proto_wow = proto_register_protocol("World of Warcraft",
626                                             "WOW", "wow");
627
628         proto_register_field_array(proto_wow, hf, array_length(hf));
629         proto_register_subtree_array(ett, array_length(ett));
630
631         wow_module = prefs_register_protocol(proto_wow, NULL);
632
633         prefs_register_bool_preference(wow_module, "desegment", "Reassemble wow messages spanning multiple TCP segments.", "Whether the wow dissector should reassemble messages spanning multiple TCP segments.  To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.", &wow_preference_desegment);
634
635 }
636
637 void
638 proto_reg_handoff_wow(void)
639 {
640         dissector_handle_t wow_handle;
641
642         wow_handle = new_create_dissector_handle(dissect_wow, proto_wow);
643         dissector_add_uint("tcp.port", WOW_PORT, wow_handle);
644
645 }