* Routines for World of Warcraft (WoW) protocol dissection
* Copyright 2008-2009, Stephen Fisher (see AUTHORS file)
*
- * $Id$
- *
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
* SRP protocol documents (http://srp.stanford.edu) and RFC 2945: "The SRP
* Authentication and Key Exchange System." */
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdlib.h>
-
-#include <glib.h>
+#include "config.h"
#include <epan/packet.h>
#include <epan/prefs.h>
#include "packet-tcp.h"
+void proto_register_wow(void);
+void proto_reg_handoff_wow(void);
+
typedef enum {
AUTH_LOGON_CHALLENGE = 0x00,
AUTH_LOGON_PROOF = 0x01,
{ 0, NULL }
};
+#if 0
static const value_string account_type_vs[] = {
{ 0, "Player" },
{ 1, "Moderator" },
{ 3, "Administrator" },
{ 0, NULL }
};
+#endif
static const value_string realm_status_vs[] = {
{ 0, "Online" },
static gint ett_wow = -1;
static gint ett_wow_realms = -1;
-static void dissect_wow_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-static guint get_wow_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset);
-
-
-static gboolean
-dissect_wow(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- gint8 size_field_offset = -1;
- guint8 cmd;
-
- cmd = tvb_get_guint8(tvb, 0);
-
- if(WOW_SERVER_TO_CLIENT && cmd == REALM_LIST)
- size_field_offset = 1;
- if(WOW_CLIENT_TO_SERVER && cmd == AUTH_LOGON_CHALLENGE)
- size_field_offset = 2;
-
- if(size_field_offset > -1) {
- tcp_dissect_pdus(tvb, pinfo, tree, wow_preference_desegment,
- size_field_offset+2, get_wow_pdu_len,
- dissect_wow_pdu);
-
- } else {
- /* Doesn't have a size field, so it cannot span multiple
- segments. Therefore, dissect this packet normally. */
- dissect_wow_pdu(tvb, pinfo, tree);
- }
-
- return TRUE;
-}
-
static guint
-get_wow_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset)
+get_wow_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset, void *data _U_)
{
gint8 size_field_offset = -1;
guint8 cmd;
}
-static void
-dissect_wow_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+static int
+dissect_wow_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
proto_item *ti;
proto_tree *wow_tree, *wow_realms_tree;
guint8 cmd, srp_i_len, srp_g_len, srp_n_len;
guint16 num_realms;
guint32 offset = 0;
- gint len, i;
+ gint len, ii;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "WOW");
cmd = tvb_get_guint8(tvb, offset);
- if(check_col(pinfo->cinfo, COL_INFO)) {
- col_set_str(pinfo->cinfo, COL_INFO,
+ col_set_str(pinfo->cinfo, COL_INFO,
val_to_str_const(cmd, cmd_vs,
"Unrecognized packet type"));
- }
if(tree) {
- ti = proto_tree_add_item(tree, proto_wow, tvb, 0, -1, TRUE);
+ ti = proto_tree_add_item(tree, proto_wow, tvb, 0, -1, ENC_NA);
wow_tree = proto_item_add_subtree(ti, ett_wow);
proto_tree_add_item(wow_tree, hf_wow_command, tvb, offset, 1,
- TRUE);
+ ENC_LITTLE_ENDIAN);
offset += 1;
switch(cmd) {
if(WOW_CLIENT_TO_SERVER) {
proto_tree_add_item(wow_tree, hf_wow_error, tvb,
- offset, 1, TRUE);
+ offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
proto_tree_add_item(wow_tree, hf_wow_pkt_size,
- tvb, offset, 2, TRUE);
+ tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
- string = g_strreverse(tvb_get_ephemeral_string(tvb, offset, 4));
+ string = g_strreverse(tvb_get_string_enc(wmem_packet_scope(), tvb, offset, 4, ENC_ASCII));
proto_tree_add_string(wow_tree, hf_wow_gamename,
tvb, offset, 4, string);
offset += 4;
proto_tree_add_item(wow_tree, hf_wow_version1,
- tvb, offset, 1, TRUE);
+ tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
proto_tree_add_item(wow_tree, hf_wow_version2,
- tvb, offset, 1, TRUE);
+ tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
proto_tree_add_item(wow_tree, hf_wow_version3,
- tvb, offset, 1, TRUE);
+ tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
proto_tree_add_item(wow_tree, hf_wow_build, tvb,
- offset, 2, TRUE);
+ offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
- string = g_strreverse(tvb_get_ephemeral_string(tvb, offset, 4));
+ string = g_strreverse(tvb_get_string_enc(wmem_packet_scope(), tvb, offset, 4, ENC_ASCII));
proto_tree_add_string(wow_tree, hf_wow_platform,
tvb, offset, 4, string);
offset += 4;
- string = g_strreverse(tvb_get_ephemeral_string(tvb, offset, 4));
+ string = g_strreverse(tvb_get_string_enc(wmem_packet_scope(), tvb, offset, 4, ENC_ASCII));
proto_tree_add_string(wow_tree, hf_wow_os, tvb,
offset, 4, string);
offset += 4;
- string = g_strreverse(tvb_get_ephemeral_string(tvb, offset, 4));
+ string = g_strreverse(tvb_get_string_enc(wmem_packet_scope(), tvb, offset, 4, ENC_ASCII));
proto_tree_add_string(wow_tree, hf_wow_country,
tvb, offset, 4, string);
offset += 4;
proto_tree_add_item(wow_tree,
hf_wow_timezone_bias,
- tvb, offset, 4, TRUE);
+ tvb, offset, 4, ENC_LITTLE_ENDIAN);
offset += 4;
proto_tree_add_item(wow_tree, hf_wow_ip, tvb,
- offset, 4, FALSE);
+ offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(wow_tree,
hf_wow_srp_i_len,
- tvb, offset, 1, TRUE);
+ tvb, offset, 1, ENC_LITTLE_ENDIAN);
srp_i_len = tvb_get_guint8(tvb, offset);
offset += 1;
proto_tree_add_item(wow_tree,
hf_wow_srp_i, tvb,
offset, srp_i_len,
- TRUE);
- offset += srp_i_len;
+ ENC_ASCII|ENC_NA);
+ /*offset += srp_i_len;*/
} else if(WOW_SERVER_TO_CLIENT) {
proto_tree_add_item(wow_tree, hf_wow_error, tvb,
- offset, 1, TRUE);
+ offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
offset += 1; /* Unknown field */
offset += 32;
proto_tree_add_item(wow_tree, hf_wow_srp_g_len,
- tvb, offset, 1, TRUE);
+ tvb, offset, 1, ENC_LITTLE_ENDIAN);
srp_g_len = tvb_get_guint8(tvb, offset);
offset += 1;
offset += srp_g_len;
proto_tree_add_item(wow_tree, hf_wow_srp_n_len,
- tvb, offset, 1, TRUE);
+ tvb, offset, 1, ENC_LITTLE_ENDIAN);
srp_n_len = tvb_get_guint8(tvb, offset);
offset += 1;
proto_tree_add_item(wow_tree, hf_wow_srp_s, tvb,
offset, 32, ENC_NA);
- offset += 32;
+ /*offset += 32;*/
- offset += 16; /* Unknown field */
+ /*offset += 16;*/ /* Unknown field */
}
break;
offset += 20;
proto_tree_add_item(wow_tree, hf_wow_num_keys,
- tvb, offset, 1, TRUE);
- offset += 1;
+ tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ /*offset += 1;*/
- offset += 1; /* Unknown field */
+ /*offset += 1; *//* Unknown field */
} else if(WOW_SERVER_TO_CLIENT) {
proto_tree_add_item(wow_tree, hf_wow_error, tvb,
- offset, 1, TRUE);
+ offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
proto_tree_add_item(wow_tree, hf_wow_srp_m2,
tvb, offset, 20, ENC_NA);
- offset += 20;
+ /*offset += 20;*/
- offset += 4; /* Unknown field */
+ /*offset += 4;*/ /* Unknown field */
- offset += 2; /* Unknown field */
+ /*offset += 2;*/ /* Unknown field */
}
break;
} else if(WOW_SERVER_TO_CLIENT) {
proto_tree_add_item(wow_tree, hf_wow_pkt_size,
- tvb, offset, 2, TRUE);
+ tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
offset += 4; /* Unknown field; always 0 */
proto_tree_add_item(wow_tree, hf_wow_num_realms,
- tvb, offset, 2, TRUE);
+ tvb, offset, 2, ENC_LITTLE_ENDIAN);
num_realms = tvb_get_letohs(tvb, offset);
offset += 2;
- for(i = 1; i <= num_realms; i++) {
- realm_name = tvb_get_ephemeral_stringz(tvb,
+ for(ii = 0; ii < num_realms; ii++) {
+ realm_name = tvb_get_stringz_enc(wmem_packet_scope(), tvb,
offset + 3,
- &len);
+ &len, ENC_ASCII);
- ti = proto_tree_add_text(wow_tree, tvb,
+ wow_realms_tree = proto_tree_add_subtree(wow_tree, tvb,
offset, 0,
- "%s",
+ ett_wow_realms, NULL,
realm_name);
- wow_realms_tree = proto_item_add_subtree(ti, ett_wow_realms);
- proto_tree_add_item(wow_realms_tree, hf_wow_realm_type, tvb, offset, 1, TRUE);
+ proto_tree_add_item(wow_realms_tree, hf_wow_realm_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
- proto_tree_add_item(wow_realms_tree, hf_wow_realm_status, tvb, offset, 1, TRUE);
+ proto_tree_add_item(wow_realms_tree, hf_wow_realm_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
- proto_tree_add_item(wow_realms_tree, hf_wow_realm_color, tvb, offset, 1, TRUE);
+ proto_tree_add_item(wow_realms_tree, hf_wow_realm_color, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
proto_tree_add_string(wow_realms_tree, hf_wow_realm_name, tvb, offset, len, realm_name);
offset += len;
- string = tvb_get_ephemeral_stringz(tvb, offset,
- &len);
+ string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset,
+ &len, ENC_ASCII);
proto_tree_add_string(wow_realms_tree, hf_wow_realm_socket, tvb, offset, len, string);
offset += len;
- proto_tree_add_item(wow_realms_tree, hf_wow_realm_population_level, tvb, offset, 4, TRUE);
+ proto_tree_add_item(wow_realms_tree, hf_wow_realm_population_level, tvb, offset, 4, ENC_LITTLE_ENDIAN);
offset += 4;
- proto_tree_add_item(wow_realms_tree, hf_wow_realm_num_characters, tvb, offset, 1, TRUE);
+ proto_tree_add_item(wow_realms_tree, hf_wow_realm_num_characters, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
- proto_tree_add_item(wow_realms_tree, hf_wow_realm_timezone, tvb, offset, 1, TRUE);
+ proto_tree_add_item(wow_realms_tree, hf_wow_realm_timezone, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
offset += 1; /* Unknown field */
}
}
}
+
+ return tvb_captured_length(tvb);
+}
+
+static gboolean
+dissect_wow(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+{
+ gint8 size_field_offset = -1;
+ guint8 cmd;
+
+ cmd = tvb_get_guint8(tvb, 0);
+
+ if(WOW_SERVER_TO_CLIENT && cmd == REALM_LIST)
+ size_field_offset = 1;
+ if(WOW_CLIENT_TO_SERVER && cmd == AUTH_LOGON_CHALLENGE)
+ size_field_offset = 2;
+
+ if(size_field_offset > -1) {
+ tcp_dissect_pdus(tvb, pinfo, tree, wow_preference_desegment,
+ size_field_offset+2, get_wow_pdu_len,
+ dissect_wow_pdu, data);
+
+ } else {
+ /* Doesn't have a size field, so it cannot span multiple
+ segments. Therefore, dissect this packet normally. */
+ dissect_wow_pdu(tvb, pinfo, tree, data);
+ }
+
+ return TRUE;
}
dissector_add_uint("tcp.port", WOW_PORT, wow_handle);
}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */