1999-10-24 00:56:11 +00:00
|
|
|
/* packet-icq.c
|
|
|
|
* Routines for ICQ packet disassembly
|
|
|
|
*
|
2002-08-03 19:47:50 +00:00
|
|
|
* $Id: packet-icq.c,v 1.47 2002/08/03 19:47:50 guy Exp $
|
1999-10-24 00:56:11 +00:00
|
|
|
*
|
|
|
|
* Ethereal - Network traffic analyzer
|
2001-05-27 21:37:23 +00:00
|
|
|
* By Gerald Combs <gerald@ethereal.com>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
1999-10-24 00:56:11 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This file: by Kojak <kojak@bigwig.net>
|
|
|
|
*
|
|
|
|
* Decoding code ripped, reference to the original author at the
|
|
|
|
* appropriate place with the code itself.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_STDDEF_H
|
|
|
|
#include <stddef.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <ctype.h>
|
1999-11-03 06:21:35 +00:00
|
|
|
#include <time.h>
|
1999-10-25 20:28:21 +00:00
|
|
|
#include <string.h>
|
1999-10-24 00:56:11 +00:00
|
|
|
#include <glib.h>
|
1999-10-25 20:28:21 +00:00
|
|
|
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/packet.h>
|
|
|
|
#include <epan/resolv.h>
|
1999-10-24 00:56:11 +00:00
|
|
|
|
1999-11-16 11:44:20 +00:00
|
|
|
static int proto_icq = -1;
|
2001-07-03 09:08:03 +00:00
|
|
|
static int hf_icq_uin = -1;
|
|
|
|
static int hf_icq_client_cmd = -1;
|
|
|
|
static int hf_icq_server_cmd = -1;
|
|
|
|
static int hf_icq_sessionid = -1;
|
|
|
|
static int hf_icq_checkcode = -1;
|
1999-11-16 11:44:20 +00:00
|
|
|
static int hf_icq_decode = -1;
|
|
|
|
static int hf_icq_type = -1;
|
|
|
|
|
|
|
|
static gint ett_icq = -1;
|
|
|
|
static gint ett_icq_header = -1;
|
|
|
|
static gint ett_icq_decode = -1;
|
|
|
|
static gint ett_icq_body = -1;
|
|
|
|
static gint ett_icq_body_parts = -1;
|
1999-11-06 03:08:34 +00:00
|
|
|
|
2000-04-08 07:07:42 +00:00
|
|
|
#define UDP_PORT_ICQ 4000
|
|
|
|
|
1999-11-06 03:08:34 +00:00
|
|
|
enum { ICQ5_client, ICQ5_server};
|
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
static void dissect_icqv5(tvbuff_t *tvb,
|
|
|
|
packet_info *pinfo,
|
1999-11-06 03:08:34 +00:00
|
|
|
proto_tree *tree);
|
|
|
|
|
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
dissect_icqv5Server(tvbuff_t *tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
int offset,
|
2001-03-25 01:52:16 +00:00
|
|
|
packet_info *pinfo,
|
1999-11-06 03:08:34 +00:00
|
|
|
proto_tree *tree,
|
2001-04-27 01:38:19 +00:00
|
|
|
int pktsize);
|
1999-10-24 00:56:11 +00:00
|
|
|
|
|
|
|
/* Offsets of fields in the ICQ headers */
|
|
|
|
/* Can be 0x0002 or 0x0005 */
|
|
|
|
#define ICQ_VERSION 0x00
|
|
|
|
/* Is either one (server) or four (client) bytes long */
|
|
|
|
/* Client header offsets */
|
|
|
|
#define ICQ5_UNKNOWN 0x02
|
|
|
|
#define ICQ5_CL_UIN 0x06
|
|
|
|
#define ICQ5_CL_SESSIONID 0x0a
|
|
|
|
#define ICQ5_CL_CMD 0x0e
|
|
|
|
#define ICQ5_CL_SEQNUM1 0x10
|
|
|
|
#define ICQ5_CL_SEQNUM2 0x12
|
|
|
|
#define ICQ5_CL_CHECKCODE 0x14
|
|
|
|
#define ICQ5_CL_PARAM 0x18
|
|
|
|
#define ICQ5_CL_HDRSIZE 0x18
|
|
|
|
|
|
|
|
/* Server header offsets */
|
|
|
|
#define ICQ5_SRV_SESSIONID 0x03
|
|
|
|
#define ICQ5_SRV_CMD 0x07
|
|
|
|
#define ICQ5_SRV_SEQNUM1 0x09
|
|
|
|
#define ICQ5_SRV_SEQNUM2 0x0b
|
|
|
|
#define ICQ5_SRV_UIN 0x0d
|
|
|
|
#define ICQ5_SRV_CHECKCODE 0x11
|
|
|
|
#define ICQ5_SRV_PARAM 0x15
|
|
|
|
#define ICQ5_SRV_HDRSIZE 0x15
|
|
|
|
|
1999-11-06 03:08:34 +00:00
|
|
|
#define SRV_ACK 0x000a
|
|
|
|
|
2000-08-04 23:12:21 +00:00
|
|
|
#define SRV_SILENT_TOO_LONG 0x001e
|
|
|
|
|
1999-11-06 03:08:34 +00:00
|
|
|
#define SRV_GO_AWAY 0x0028
|
|
|
|
|
|
|
|
#define SRV_NEW_UIN 0x0046
|
|
|
|
|
|
|
|
/* LOGIN_REPLY is very scary. It has a lot of fields that are undocumented
|
|
|
|
* Only the IP field makes sense */
|
|
|
|
#define SRV_LOGIN_REPLY 0x005a
|
|
|
|
#define SRV_LOGIN_REPLY_IP 0x000c
|
|
|
|
|
|
|
|
#define SRV_BAD_PASS 0x0064
|
|
|
|
|
|
|
|
#define SRV_USER_ONLINE 0x006e
|
|
|
|
#define SRV_USER_ONL_UIN 0x0000
|
|
|
|
#define SRV_USER_ONL_IP 0x0004
|
|
|
|
#define SRV_USER_ONL_PORT 0x0008
|
|
|
|
#define SRV_USER_ONL_REALIP 0x000c
|
|
|
|
#define SRV_USER_ONL_X1 0x0010
|
1999-12-05 22:59:55 +00:00
|
|
|
#define SRV_USER_ONL_STATUS 0x0013
|
1999-11-06 03:08:34 +00:00
|
|
|
#define SRV_USER_ONL_X2 0x0015
|
|
|
|
|
|
|
|
#define SRV_USER_OFFLINE 0x0078
|
|
|
|
#define SRV_USER_OFFLINE_UIN 0x0000
|
|
|
|
|
|
|
|
#define SRV_MULTI 0x0212
|
|
|
|
#define SRV_MULTI_NUM 0x0000
|
|
|
|
|
|
|
|
#define SRV_META_USER 0x03de
|
|
|
|
#define SRV_META_USER_SUBCMD 0x0000
|
|
|
|
#define SRV_META_USER_RESULT 0x0002
|
|
|
|
#define SRV_META_USER_DATA 0x0003
|
|
|
|
|
|
|
|
#define SRV_UPDATE_SUCCESS 0x01e0
|
|
|
|
|
|
|
|
#define SRV_UPDATE_FAIL 0x01ea
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ICQv5 SRV_META_USER subcommands
|
|
|
|
*/
|
1999-12-05 22:59:55 +00:00
|
|
|
#define META_EX_USER_FOUND 0x0190
|
1999-11-06 03:08:34 +00:00
|
|
|
#define META_USER_FOUND 0x019a
|
|
|
|
#define META_ABOUT 0x00e6
|
|
|
|
#define META_USER_INFO 0x00c8
|
|
|
|
|
|
|
|
#define SRV_RECV_MESSAGE 0x00dc
|
|
|
|
#define SRV_RECV_MSG_UIN 0x0000
|
|
|
|
#define SRV_RECV_MSG_YEAR 0x0004
|
|
|
|
#define SRV_RECV_MSG_MONTH 0x0006
|
|
|
|
#define SRV_RECV_MSG_DAY 0x0007
|
|
|
|
#define SRV_RECV_MSG_HOUR 0x0008
|
|
|
|
#define SRV_RECV_MSG_MINUTE 0x0009
|
|
|
|
#define SRV_RECV_MSG_MSG_TYPE 0x000a
|
|
|
|
|
1999-12-05 22:59:55 +00:00
|
|
|
#define SRV_RAND_USER 0x024e
|
|
|
|
#define SRV_RAND_USER_UIN 0x0000
|
|
|
|
#define SRV_RAND_USER_IP 0x0004
|
|
|
|
#define SRV_RAND_USER_PORT 0x0008
|
|
|
|
#define SRV_RAND_USER_REAL_IP 0x000c
|
|
|
|
#define SRV_RAND_USER_CLASS 0x0010
|
|
|
|
#define SRV_RAND_USER_X1 0x0011
|
|
|
|
#define SRV_RAND_USER_STATUS 0x0015
|
|
|
|
#define SRV_RAND_USER_TCP_VER 0x0019
|
|
|
|
|
|
|
|
/* This message has the same structure as cmd_send_msg */
|
|
|
|
#define SRV_SYS_DELIVERED_MESS 0x0104
|
|
|
|
|
2001-07-03 09:08:03 +00:00
|
|
|
static const value_string serverMetaSubCmdCode[] = {
|
|
|
|
{ META_USER_FOUND, "META_USER_FOUND" },
|
|
|
|
{ META_EX_USER_FOUND, "META_EX_USER_FOUND" },
|
|
|
|
{ META_ABOUT, "META_ABOUT" },
|
|
|
|
{ META_USER_INFO, "META_USER_INFO" },
|
|
|
|
{ 0, NULL }
|
1999-11-06 03:08:34 +00:00
|
|
|
};
|
|
|
|
|
2001-07-03 09:08:03 +00:00
|
|
|
static const value_string serverCmdCode[] = {
|
|
|
|
{ SRV_ACK, "SRV_ACK" },
|
|
|
|
{ SRV_SILENT_TOO_LONG, "SRV_SILENT_TOO_LONG" },
|
|
|
|
{ SRV_GO_AWAY, "SRV_GO_AWAY" },
|
|
|
|
{ SRV_NEW_UIN, "SRV_NEW_UIN" },
|
|
|
|
{ SRV_LOGIN_REPLY, "SRV_LOGIN_REPLY" },
|
|
|
|
{ SRV_BAD_PASS, "SRV_BAD_PASS" },
|
|
|
|
{ SRV_USER_ONLINE, "SRV_USER_ONLINE" },
|
|
|
|
{ SRV_USER_OFFLINE, "SRV_USER_OFFLINE" },
|
|
|
|
{ 130, "SRV_QUERY" },
|
|
|
|
{ 140, "SRV_USER_FOUND" },
|
|
|
|
{ 160, "SRV_END_OF_SEARCH" },
|
|
|
|
{ 180, "SRV_NEW_USER" },
|
|
|
|
{ 200, "SRV_UPDATE_EXT" },
|
|
|
|
{ SRV_RECV_MESSAGE, "SRV_RECV_MESSAGE" },
|
|
|
|
{ 230, "SRV_END_OFFLINE_MESSAGES" },
|
|
|
|
{ 240, "SRV_NOT_CONNECTED" },
|
|
|
|
{ 250, "SRV_TRY_AGAIN" },
|
|
|
|
{ SRV_SYS_DELIVERED_MESS, "SRV_SYS_DELIVERED_MESS" },
|
|
|
|
{ 280, "SRV_INFO_REPLY" },
|
|
|
|
{ 290, "SRV_EXT_INFO_REPLY" },
|
|
|
|
{ 420, "SRV_STATUS_UPDATE" },
|
|
|
|
{ 450, "SRV_SYSTEM_MESSAGE" },
|
|
|
|
{ SRV_UPDATE_SUCCESS, "SRV_UPDATE_SUCCESS" },
|
|
|
|
{ SRV_UPDATE_FAIL, "SRV_UPDATE_FAIL" },
|
|
|
|
{ 500, "SRV_AUTH_UPDATE" },
|
|
|
|
{ SRV_MULTI, "SRV_MULTI_PACKET" },
|
|
|
|
{ 540, "SRV_END_CONTACTLIST_STATUS" },
|
|
|
|
{ SRV_RAND_USER, "SRV_RAND_USER" },
|
|
|
|
{ SRV_META_USER, "SRV_META_USER" },
|
|
|
|
{ 0, NULL }
|
1999-10-24 00:56:11 +00:00
|
|
|
};
|
|
|
|
|
1999-10-25 20:28:21 +00:00
|
|
|
#define MSG_TEXT 0x0001
|
|
|
|
#define MSG_URL 0x0004
|
|
|
|
#define MSG_AUTH_REQ 0x0006
|
|
|
|
#define MSG_AUTH 0x0008
|
|
|
|
#define MSG_USER_ADDED 0x000c
|
1999-11-06 03:08:34 +00:00
|
|
|
#define MSG_EMAIL 0x000e
|
1999-10-25 20:28:21 +00:00
|
|
|
#define MSG_CONTACTS 0x0013
|
|
|
|
|
|
|
|
#define STATUS_ONLINE 0x00000000
|
|
|
|
#define STATUS_AWAY 0x00000001
|
|
|
|
#define STATUS_DND 0x00000013
|
|
|
|
#define STATUS_INVISIBLE 0x00000100
|
|
|
|
#define STATUS_OCCUPIED 0x00000010
|
|
|
|
#define STATUS_NA 0x00000004
|
|
|
|
#define STATUS_CHAT 0x00000020
|
|
|
|
|
|
|
|
/* Offsets for all packets measured from the start of the payload; i.e.
|
|
|
|
* with the ICQ header removed
|
|
|
|
*/
|
|
|
|
#define CMD_ACK 0x000a
|
|
|
|
#define CMD_ACK_RANDOM 0x0000
|
|
|
|
|
|
|
|
#define CMD_SEND_MSG 0x010E
|
|
|
|
#define CMD_SEND_MSG_RECV_UIN 0x0000
|
|
|
|
#define CMD_SEND_MSG_MSG_TYPE 0x0004
|
|
|
|
#define CMD_SEND_MSG_MSG_LEN 0x0006
|
|
|
|
#define CMD_SEND_MSG_MSG_TEXT 0x0008
|
|
|
|
/* The rest of the packet should be a null-term string */
|
|
|
|
|
|
|
|
#define CMD_LOGIN 0x03E8
|
|
|
|
#define CMD_LOGIN_TIME 0x0000
|
|
|
|
#define CMD_LOGIN_PORT 0x0004
|
|
|
|
#define CMD_LOGIN_PASSLEN 0x0008
|
|
|
|
#define CMD_LOGIN_PASSWD 0x000A
|
|
|
|
/* The password is variable length; so when we've decoded the passwd,
|
|
|
|
* the structure starts counting at 0 again.
|
|
|
|
*/
|
|
|
|
#define CMD_LOGIN_IP 0x0004
|
|
|
|
#define CMD_LOGIN_STATUS 0x0009
|
|
|
|
|
1999-11-06 03:08:34 +00:00
|
|
|
#define CMD_CONTACT_LIST 0x0406
|
|
|
|
#define CMD_CONTACT_LIST_NUM 0x0000
|
|
|
|
|
|
|
|
#define CMD_USER_META 0x064a
|
|
|
|
|
|
|
|
#define CMD_REG_NEW_USER 0x03fc
|
|
|
|
|
|
|
|
#define CMD_ACK_MESSAGES 0x0442
|
|
|
|
#define CMD_ACK_MESSAGES_RANDOM 0x0000
|
|
|
|
|
|
|
|
#define CMD_KEEP_ALIVE 0x042e
|
|
|
|
#define CMD_KEEP_ALIVE_RANDOM 0x0000
|
|
|
|
|
|
|
|
#define CMD_SEND_TEXT_CODE 0x0438
|
|
|
|
#define CMD_SEND_TEXT_CODE_LEN 0x0000
|
|
|
|
#define CMD_SEND_TEXT_CODE_TEXT 0x0002
|
|
|
|
|
1999-12-05 22:59:55 +00:00
|
|
|
#define CMD_MSG_TO_NEW_USER 0x0456
|
|
|
|
|
1999-11-06 03:08:34 +00:00
|
|
|
#define CMD_QUERY_SERVERS 0x04ba
|
|
|
|
|
|
|
|
#define CMD_QUERY_ADDONS 0x04c4
|
|
|
|
|
|
|
|
#define CMD_STATUS_CHANGE 0x04d8
|
|
|
|
#define CMD_STATUS_CHANGE_STATUS 0x0000
|
|
|
|
|
|
|
|
#define CMD_ADD_TO_LIST 0x053c
|
|
|
|
#define CMD_ADD_TO_LIST_UIN 0x0000
|
|
|
|
|
|
|
|
#define CMD_RAND_SEARCH 0x056e
|
|
|
|
#define CMD_RAND_SEARCH_GROUP 0x0000
|
|
|
|
|
|
|
|
#define CMD_META_USER 0x064a
|
1999-10-25 20:28:21 +00:00
|
|
|
|
2001-07-03 09:08:03 +00:00
|
|
|
static const value_string msgTypeCode[] = {
|
|
|
|
{ MSG_TEXT, "MSG_TEXT" },
|
|
|
|
{ MSG_URL, "MSG_URL" },
|
|
|
|
{ MSG_AUTH_REQ, "MSG_AUTH_REQ" },
|
|
|
|
{ MSG_AUTH, "MSG_AUTH" },
|
|
|
|
{ MSG_USER_ADDED, "MSG_USER_ADDED" },
|
|
|
|
{ MSG_EMAIL, "MSG_EMAIL" },
|
|
|
|
{ MSG_CONTACTS, "MSG_CONTACTS" },
|
|
|
|
{ 0, NULL }
|
1999-10-25 20:28:21 +00:00
|
|
|
};
|
|
|
|
|
2001-07-03 09:08:03 +00:00
|
|
|
static const value_string statusCode[] = {
|
|
|
|
{ STATUS_ONLINE, "ONLINE" },
|
|
|
|
{ STATUS_AWAY, "AWAY" },
|
|
|
|
{ STATUS_DND, "DND" },
|
|
|
|
{ STATUS_INVISIBLE, "INVISIBLE" },
|
|
|
|
{ STATUS_OCCUPIED, "OCCUPIED" },
|
|
|
|
{ STATUS_NA, "NA" },
|
|
|
|
{ STATUS_CHAT, "Free for Chat" },
|
|
|
|
{ 0, NULL }
|
1999-10-25 20:28:21 +00:00
|
|
|
};
|
|
|
|
|
2001-07-03 09:08:03 +00:00
|
|
|
static const value_string clientCmdCode[] = {
|
|
|
|
{ CMD_ACK, "CMD_ACK" },
|
|
|
|
{ CMD_SEND_MSG, "CMD_SEND_MESSAGE" },
|
|
|
|
{ CMD_LOGIN, "CMD_LOGIN" },
|
|
|
|
{ CMD_REG_NEW_USER, "CMD_REG_NEW_USER" },
|
|
|
|
{ 1030, "CMD_CONTACT_LIST" },
|
|
|
|
{ 1050, "CMD_SEARCH_UIN" },
|
|
|
|
{ 1060, "CMD_SEARCH_USER" },
|
|
|
|
{ 1070, "CMD_KEEP_ALIVE" },
|
|
|
|
{ CMD_SEND_TEXT_CODE, "CMD_SEND_TEXT_CODE" },
|
|
|
|
{ CMD_ACK_MESSAGES, "CMD_ACK_MESSAGES" },
|
|
|
|
{ 1100, "CMD_LOGIN_1" },
|
|
|
|
{ CMD_MSG_TO_NEW_USER, "CMD_MSG_TO_NEW_USER" },
|
|
|
|
{ 1120, "CMD_INFO_REQ" },
|
|
|
|
{ 1130, "CMD_EXT_INFO_REQ" },
|
|
|
|
{ 1180, "CMD_CHANGE_PW" },
|
|
|
|
{ 1190, "CMD_NEW_USER_INFO" },
|
|
|
|
{ 1200, "CMD_UPDATE_EXT_INFO" },
|
|
|
|
{ CMD_QUERY_SERVERS, "CMD_QUERY_SERVERS" },
|
|
|
|
{ CMD_QUERY_ADDONS, "CMD_QUERY_ADDONS" },
|
|
|
|
{ CMD_STATUS_CHANGE, "CMD_STATUS_CHANGE" },
|
|
|
|
{ 1260, "CMD_NEW_USER_1" },
|
|
|
|
{ 1290, "CMD_UPDATE_INFO" },
|
|
|
|
{ 1300, "CMD_AUTH_UPDATE" },
|
|
|
|
{ 1310, "CMD_KEEP_ALIVE2" },
|
|
|
|
{ 1320, "CMD_LOGIN_2" },
|
|
|
|
{ CMD_ADD_TO_LIST, "CMD_ADD_TO_LIST" },
|
|
|
|
{ 1380, "CMD_RAND_SET" },
|
|
|
|
{ CMD_RAND_SEARCH, "CMD_RAND_SEARCH" },
|
|
|
|
{ CMD_META_USER, "CMD_META_USER" },
|
|
|
|
{ 1700, "CMD_INVIS_LIST" },
|
|
|
|
{ 1710, "CMD_VIS_LIST" },
|
|
|
|
{ 1720, "CMD_UPDATE_LIST" },
|
|
|
|
{ 0, NULL }
|
1999-10-24 00:56:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* All ICQv5 decryption code thanx to Sebastien Dault (daus01@gel.usherb.ca)
|
|
|
|
*/
|
2002-08-02 23:36:07 +00:00
|
|
|
static const guchar
|
1999-10-24 00:56:11 +00:00
|
|
|
table_v5 [] = {
|
|
|
|
0x59, 0x60, 0x37, 0x6B, 0x65, 0x62, 0x46, 0x48, 0x53, 0x61, 0x4C, 0x59, 0x60, 0x57, 0x5B, 0x3D,
|
|
|
|
0x5E, 0x34, 0x6D, 0x36, 0x50, 0x3F, 0x6F, 0x67, 0x53, 0x61, 0x4C, 0x59, 0x40, 0x47, 0x63, 0x39,
|
|
|
|
0x50, 0x5F, 0x5F, 0x3F, 0x6F, 0x47, 0x43, 0x69, 0x48, 0x33, 0x31, 0x64, 0x35, 0x5A, 0x4A, 0x42,
|
|
|
|
0x56, 0x40, 0x67, 0x53, 0x41, 0x07, 0x6C, 0x49, 0x58, 0x3B, 0x4D, 0x46, 0x68, 0x43, 0x69, 0x48,
|
|
|
|
0x33, 0x31, 0x44, 0x65, 0x62, 0x46, 0x48, 0x53, 0x41, 0x07, 0x6C, 0x69, 0x48, 0x33, 0x51, 0x54,
|
|
|
|
0x5D, 0x4E, 0x6C, 0x49, 0x38, 0x4B, 0x55, 0x4A, 0x62, 0x46, 0x48, 0x33, 0x51, 0x34, 0x6D, 0x36,
|
|
|
|
0x50, 0x5F, 0x5F, 0x5F, 0x3F, 0x6F, 0x47, 0x63, 0x59, 0x40, 0x67, 0x33, 0x31, 0x64, 0x35, 0x5A,
|
|
|
|
0x6A, 0x52, 0x6E, 0x3C, 0x51, 0x34, 0x6D, 0x36, 0x50, 0x5F, 0x5F, 0x3F, 0x4F, 0x37, 0x4B, 0x35,
|
|
|
|
0x5A, 0x4A, 0x62, 0x66, 0x58, 0x3B, 0x4D, 0x66, 0x58, 0x5B, 0x5D, 0x4E, 0x6C, 0x49, 0x58, 0x3B,
|
|
|
|
0x4D, 0x66, 0x58, 0x3B, 0x4D, 0x46, 0x48, 0x53, 0x61, 0x4C, 0x59, 0x40, 0x67, 0x33, 0x31, 0x64,
|
|
|
|
0x55, 0x6A, 0x32, 0x3E, 0x44, 0x45, 0x52, 0x6E, 0x3C, 0x31, 0x64, 0x55, 0x6A, 0x52, 0x4E, 0x6C,
|
|
|
|
0x69, 0x48, 0x53, 0x61, 0x4C, 0x39, 0x30, 0x6F, 0x47, 0x63, 0x59, 0x60, 0x57, 0x5B, 0x3D, 0x3E,
|
|
|
|
0x64, 0x35, 0x3A, 0x3A, 0x5A, 0x6A, 0x52, 0x4E, 0x6C, 0x69, 0x48, 0x53, 0x61, 0x6C, 0x49, 0x58,
|
|
|
|
0x3B, 0x4D, 0x46, 0x68, 0x63, 0x39, 0x50, 0x5F, 0x5F, 0x3F, 0x6F, 0x67, 0x53, 0x41, 0x25, 0x41,
|
|
|
|
0x3C, 0x51, 0x54, 0x3D, 0x5E, 0x54, 0x5D, 0x4E, 0x4C, 0x39, 0x50, 0x5F, 0x5F, 0x5F, 0x3F, 0x6F,
|
|
|
|
0x47, 0x43, 0x69, 0x48, 0x33, 0x51, 0x54, 0x5D, 0x6E, 0x3C, 0x31, 0x64, 0x35, 0x5A, 0x00, 0x00 };
|
|
|
|
|
1999-10-25 20:28:21 +00:00
|
|
|
static char*
|
|
|
|
findMsgType(int num)
|
|
|
|
{
|
2001-07-03 09:08:03 +00:00
|
|
|
return val_to_str(num, msgTypeCode, "Unknown");
|
1999-10-25 20:28:21 +00:00
|
|
|
}
|
|
|
|
|
1999-11-06 03:08:34 +00:00
|
|
|
static char*
|
|
|
|
findSubCmd(int num)
|
|
|
|
{
|
2001-07-03 09:08:03 +00:00
|
|
|
return val_to_str(num, serverMetaSubCmdCode, "Unknown (0x%04x)");
|
1999-11-18 21:04:54 +00:00
|
|
|
}
|
1999-11-06 03:08:34 +00:00
|
|
|
|
1999-10-25 20:28:21 +00:00
|
|
|
static char*
|
|
|
|
findClientCmd(int num)
|
|
|
|
{
|
2001-07-03 09:08:03 +00:00
|
|
|
return val_to_str(num, clientCmdCode, "Unknown (%u)");
|
1999-10-25 20:28:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static char*
|
|
|
|
findServerCmd(int num)
|
|
|
|
{
|
2001-07-03 09:08:03 +00:00
|
|
|
return val_to_str(num, serverCmdCode, "Unknown (%u)");
|
1999-10-25 20:28:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static char*
|
|
|
|
findStatus(int num)
|
|
|
|
{
|
2001-07-03 09:08:03 +00:00
|
|
|
return val_to_str(num, statusCode, "Unknown (0x%08x)");
|
1999-10-25 20:28:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static guint32
|
2001-03-25 01:52:16 +00:00
|
|
|
get_v5key(tvbuff_t *tvb, int len)
|
1999-10-24 00:56:11 +00:00
|
|
|
{
|
1999-10-25 20:28:21 +00:00
|
|
|
guint32 a1, a2, a3, a4, a5;
|
|
|
|
guint32 code, check, key;
|
1999-10-24 00:56:11 +00:00
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
code = tvb_get_letohl(tvb, ICQ5_CL_CHECKCODE);
|
1999-10-24 00:56:11 +00:00
|
|
|
|
|
|
|
a1 = code & 0x0001f000;
|
|
|
|
a2 = code & 0x07c007c0;
|
|
|
|
a3 = code & 0x003e0001;
|
|
|
|
a4 = code & 0xf8000000;
|
|
|
|
a5 = code & 0x0000083e;
|
|
|
|
|
|
|
|
a1 = a1 >> 0x0c;
|
|
|
|
a2 = a2 >> 0x01;
|
|
|
|
a3 = a3 << 0x0a;
|
|
|
|
a4 = a4 >> 0x10;
|
|
|
|
a5 = a5 << 0x0f;
|
|
|
|
|
|
|
|
check = a5 + a1 + a2 + a3 + a4;
|
|
|
|
key = len * 0x68656C6C;
|
|
|
|
key += check;
|
|
|
|
return key;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2002-08-02 23:36:07 +00:00
|
|
|
decrypt_v5(guchar *bfr, guint32 size,guint32 key)
|
1999-10-24 00:56:11 +00:00
|
|
|
{
|
1999-10-25 20:28:21 +00:00
|
|
|
guint32 i;
|
|
|
|
guint32 k;
|
2001-06-18 05:54:26 +00:00
|
|
|
|
|
|
|
for (i=ICQ5_CL_SESSIONID; i < size; i+=4 ) {
|
1999-10-24 00:56:11 +00:00
|
|
|
k = key+table_v5[i&0xff];
|
|
|
|
if ( i != 0x16 ) {
|
2002-08-02 23:36:07 +00:00
|
|
|
bfr[i] ^= (guchar)(k & 0xff);
|
|
|
|
bfr[i+1] ^= (guchar)((k & 0xff00)>>8);
|
1999-10-24 00:56:11 +00:00
|
|
|
}
|
|
|
|
if ( i != 0x12 ) {
|
2002-08-02 23:36:07 +00:00
|
|
|
bfr[i+2] ^= (guchar)((k & 0xff0000)>>16);
|
|
|
|
bfr[i+3] ^= (guchar)((k & 0xff000000)>>24);
|
1999-10-24 00:56:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-08-04 23:12:21 +00:00
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
dissect_icqv4(tvbuff_t *tvb,
|
|
|
|
packet_info *pinfo,
|
2000-08-04 23:12:21 +00:00
|
|
|
proto_tree *tree)
|
|
|
|
{
|
2002-05-02 10:53:03 +00:00
|
|
|
proto_tree *icq_tree = NULL;
|
|
|
|
proto_item *ti = NULL;
|
|
|
|
|
2000-08-04 23:12:21 +00:00
|
|
|
/* Not really implemented yet */
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICQv4 (UDP)");
|
2000-08-04 23:12:21 +00:00
|
|
|
}
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_INFO)) {
|
|
|
|
col_set_str(pinfo->cinfo, COL_INFO, "ICQ Version 4 protocol");
|
2000-08-04 23:12:21 +00:00
|
|
|
}
|
2002-05-02 10:46:23 +00:00
|
|
|
if (tree) {
|
2002-05-02 10:53:03 +00:00
|
|
|
ti = proto_tree_add_protocol_format(tree,
|
2002-05-02 10:46:23 +00:00
|
|
|
proto_icq,
|
|
|
|
tvb,
|
|
|
|
0,
|
|
|
|
-1,
|
|
|
|
"ICQv4");
|
2002-05-02 10:53:03 +00:00
|
|
|
icq_tree = proto_item_add_subtree(ti, ett_icq);
|
|
|
|
|
|
|
|
proto_tree_add_text(icq_tree, tvb,
|
|
|
|
ICQ_VERSION,
|
|
|
|
2,
|
|
|
|
"Version: %u",
|
|
|
|
tvb_get_letohs(tvb, ICQ_VERSION));
|
2002-05-02 10:46:23 +00:00
|
|
|
}
|
2000-08-04 23:12:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
dissect_icqv3(tvbuff_t *tvb,
|
|
|
|
packet_info *pinfo,
|
2000-08-04 23:12:21 +00:00
|
|
|
proto_tree *tree)
|
|
|
|
{
|
2002-05-02 10:53:03 +00:00
|
|
|
proto_tree *icq_tree = NULL;
|
|
|
|
proto_item *ti = NULL;
|
|
|
|
|
2000-08-04 23:12:21 +00:00
|
|
|
/* Not really implemented yet */
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICQv3 (UDP)");
|
2000-08-04 23:12:21 +00:00
|
|
|
}
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_INFO)) {
|
|
|
|
col_set_str(pinfo->cinfo, COL_INFO, "ICQ Version 3 protocol");
|
2000-08-04 23:12:21 +00:00
|
|
|
}
|
2002-05-02 10:46:23 +00:00
|
|
|
if (tree) {
|
2002-05-02 10:53:03 +00:00
|
|
|
ti = proto_tree_add_protocol_format(tree,
|
2002-05-02 10:46:23 +00:00
|
|
|
proto_icq,
|
|
|
|
tvb,
|
|
|
|
0,
|
|
|
|
-1,
|
|
|
|
"ICQv3");
|
2002-05-02 10:53:03 +00:00
|
|
|
icq_tree = proto_item_add_subtree(ti, ett_icq);
|
|
|
|
|
|
|
|
proto_tree_add_text(icq_tree, tvb,
|
|
|
|
ICQ_VERSION,
|
|
|
|
2,
|
|
|
|
"Version: %u",
|
|
|
|
tvb_get_letohs(tvb, ICQ_VERSION));
|
2002-05-02 10:46:23 +00:00
|
|
|
}
|
2000-08-04 23:12:21 +00:00
|
|
|
}
|
|
|
|
|
1999-10-24 00:56:11 +00:00
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
dissect_icqv2(tvbuff_t *tvb,
|
|
|
|
packet_info *pinfo,
|
1999-10-24 00:56:11 +00:00
|
|
|
proto_tree *tree)
|
|
|
|
{
|
2002-05-02 10:53:03 +00:00
|
|
|
proto_tree *icq_tree = NULL;
|
|
|
|
proto_item *ti = NULL;
|
|
|
|
|
1999-10-24 00:56:11 +00:00
|
|
|
/* Not really implemented yet */
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICQv2 (UDP)");
|
1999-10-24 00:56:11 +00:00
|
|
|
}
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_INFO)) {
|
|
|
|
col_set_str(pinfo->cinfo, COL_INFO, "ICQ Version 2 protocol");
|
1999-10-24 00:56:11 +00:00
|
|
|
}
|
2002-05-02 10:46:23 +00:00
|
|
|
if (tree) {
|
2002-05-02 10:53:03 +00:00
|
|
|
ti = proto_tree_add_protocol_format(tree,
|
2002-05-02 10:46:23 +00:00
|
|
|
proto_icq,
|
|
|
|
tvb,
|
|
|
|
0,
|
|
|
|
-1,
|
|
|
|
"ICQv2");
|
2002-05-02 10:53:03 +00:00
|
|
|
icq_tree = proto_item_add_subtree(ti, ett_icq);
|
|
|
|
|
|
|
|
proto_tree_add_text(icq_tree, tvb,
|
|
|
|
ICQ_VERSION,
|
|
|
|
2,
|
|
|
|
"Version: %u",
|
|
|
|
tvb_get_letohs(tvb, ICQ_VERSION));
|
2002-05-02 10:46:23 +00:00
|
|
|
}
|
1999-10-24 00:56:11 +00:00
|
|
|
}
|
|
|
|
|
1999-10-25 20:28:21 +00:00
|
|
|
/*
|
2001-03-25 01:52:16 +00:00
|
|
|
* The packet has, at offset "offset" a (len, string) pair.
|
|
|
|
* Display the length and string in the tree.
|
1999-12-05 22:59:55 +00:00
|
|
|
*
|
|
|
|
* If anything is wrong, return -1, since -1 is not a valid string
|
|
|
|
* length. Else, return the number of chars processed.
|
|
|
|
*/
|
|
|
|
static guint16
|
|
|
|
proto_add_icq_attr(proto_tree* tree, /* The tree to add to */
|
2001-03-25 01:52:16 +00:00
|
|
|
tvbuff_t *tvb, /* Tvbuff with packet */
|
|
|
|
const int offset, /* Offset from the start of packet of field */
|
1999-12-05 22:59:55 +00:00
|
|
|
char* descr) /* The description to use in the tree */
|
|
|
|
{
|
|
|
|
guint16 len;
|
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
len = tvb_get_letohs(tvb, offset);
|
|
|
|
if (len > tvb_reported_length_remaining(tvb, offset))
|
|
|
|
return -1; /* length goes past end of packet */
|
|
|
|
proto_tree_add_text(tree, tvb,
|
1999-12-05 22:59:55 +00:00
|
|
|
offset,
|
|
|
|
sizeof(guint16) + len,
|
2001-03-25 01:52:16 +00:00
|
|
|
"%s[%u]: %.*s", descr, len, len,
|
|
|
|
tvb_get_ptr(tvb, offset + sizeof(guint16), len));
|
1999-12-05 22:59:55 +00:00
|
|
|
return len + sizeof(guint16);
|
|
|
|
}
|
1999-11-06 03:08:34 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
icqv5_decode_msgType(proto_tree* tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvbuff_t *tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
int offset,
|
|
|
|
int size)
|
|
|
|
{
|
|
|
|
proto_item* ti = NULL;
|
|
|
|
proto_tree* subtree = NULL;
|
|
|
|
int left = size;
|
2001-03-25 01:52:16 +00:00
|
|
|
guint16 msgType;
|
|
|
|
gint sep_offset;
|
|
|
|
int sz; /* Size of the current element */
|
2001-04-27 01:27:37 +00:00
|
|
|
unsigned int n;
|
2001-03-25 01:52:16 +00:00
|
|
|
static char* url_field_descr[] = {
|
|
|
|
"Description",
|
|
|
|
"URL",
|
|
|
|
};
|
|
|
|
#define N_URL_FIELDS (sizeof url_field_descr / sizeof url_field_descr[0])
|
|
|
|
static char* email_field_descr[] = {
|
1999-11-06 03:08:34 +00:00
|
|
|
"Nickname",
|
|
|
|
"First name",
|
|
|
|
"Last name",
|
|
|
|
"Email address",
|
1999-12-05 22:59:55 +00:00
|
|
|
"Unknown",
|
2001-03-25 01:52:16 +00:00
|
|
|
"Text"
|
|
|
|
};
|
|
|
|
#define N_EMAIL_FIELDS (sizeof email_field_descr / sizeof email_field_descr[0])
|
|
|
|
static char* auth_req_field_descr[] = {
|
1999-11-06 03:08:34 +00:00
|
|
|
"Nickname",
|
|
|
|
"First name",
|
|
|
|
"Last name",
|
|
|
|
"Email address",
|
|
|
|
"Unknown",
|
2001-03-25 01:52:16 +00:00
|
|
|
"Reason"
|
1999-11-06 03:08:34 +00:00
|
|
|
};
|
2001-03-25 01:52:16 +00:00
|
|
|
#define N_AUTH_REQ_FIELDS (sizeof auth_req_field_descr / sizeof auth_req_field_descr[0])
|
|
|
|
static char* user_added_field_descr[] = {
|
|
|
|
"Nickname",
|
|
|
|
"First name",
|
|
|
|
"Last name",
|
|
|
|
"Email address",
|
|
|
|
};
|
|
|
|
#define N_USER_ADDED_FIELDS (sizeof user_added_field_descr / sizeof user_added_field_descr[0])
|
1999-11-06 03:08:34 +00:00
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
msgType = tvb_get_letohs(tvb, offset);
|
|
|
|
ti = proto_tree_add_text(tree, tvb,
|
|
|
|
offset,
|
|
|
|
size,
|
|
|
|
"Message: Type = %u (%s)", msgType, findMsgType(msgType));
|
1999-11-06 03:08:34 +00:00
|
|
|
/* Create a new subtree */
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body_parts);
|
1999-11-06 03:08:34 +00:00
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset,
|
|
|
|
2,
|
|
|
|
"Type: %u (%s)", msgType, findMsgType(msgType));
|
|
|
|
offset += 2;
|
|
|
|
left -= 2;
|
|
|
|
if (msgType != MSG_AUTH) {
|
|
|
|
/*
|
|
|
|
* XXX - does a MSG_AUTH message really have 3 bytes of information
|
|
|
|
* rather than a length field?
|
|
|
|
*/
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset,
|
|
|
|
2,
|
|
|
|
"Length: %u",
|
|
|
|
tvb_get_letohs(tvb, offset));
|
|
|
|
offset += 2;
|
|
|
|
left -= 2;
|
|
|
|
}
|
|
|
|
|
1999-11-06 03:08:34 +00:00
|
|
|
switch(msgType) {
|
|
|
|
case 0xffff: /* Field unknown */
|
|
|
|
break;
|
|
|
|
default:
|
2000-03-07 05:30:37 +00:00
|
|
|
fprintf(stderr, "Unknown msgType: %u (%04x)\n", msgType, msgType);
|
1999-11-06 03:08:34 +00:00
|
|
|
break;
|
|
|
|
case MSG_TEXT:
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset,
|
1999-11-06 03:08:34 +00:00
|
|
|
left,
|
2001-03-25 01:52:16 +00:00
|
|
|
"Msg: %.*s", left-1,
|
|
|
|
tvb_get_ptr(tvb, offset, left));
|
1999-11-06 03:08:34 +00:00
|
|
|
break;
|
|
|
|
case MSG_URL:
|
2001-03-25 01:52:16 +00:00
|
|
|
for (n = 0; n < N_URL_FIELDS; n++) {
|
|
|
|
if (n != N_URL_FIELDS - 1) {
|
|
|
|
sep_offset = tvb_find_guint8(tvb, offset, left, 0xfe);
|
|
|
|
sz = sep_offset - offset + 1;
|
|
|
|
} else
|
|
|
|
sz = left;
|
|
|
|
if (sz != 0) {
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset,
|
|
|
|
sz,
|
|
|
|
"%s: %.*s",
|
|
|
|
url_field_descr[n],
|
|
|
|
sz - 1,
|
|
|
|
tvb_get_ptr(tvb, offset, sz));
|
|
|
|
} else {
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset,
|
|
|
|
0,
|
|
|
|
"%s: %s", url_field_descr[n], "(empty)");
|
|
|
|
}
|
|
|
|
offset += sz;
|
|
|
|
left -= sz;
|
1999-11-06 03:08:34 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MSG_EMAIL:
|
2001-03-25 01:52:16 +00:00
|
|
|
for (n = 0; n < N_EMAIL_FIELDS; n++) {
|
|
|
|
if (n != N_EMAIL_FIELDS - 1) {
|
|
|
|
sep_offset = tvb_find_guint8(tvb, offset, left, 0xfe);
|
|
|
|
sz = sep_offset - offset + 1;
|
|
|
|
} else
|
|
|
|
sz = left;
|
|
|
|
if (sz != 0) {
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset,
|
|
|
|
sz,
|
|
|
|
"%s: %.*s",
|
|
|
|
email_field_descr[n],
|
|
|
|
sz - 1,
|
|
|
|
tvb_get_ptr(tvb, offset, sz));
|
1999-11-06 03:08:34 +00:00
|
|
|
} else {
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset,
|
1999-11-06 03:08:34 +00:00
|
|
|
0,
|
2001-03-25 01:52:16 +00:00
|
|
|
"%s: %s", email_field_descr[n], "(empty)");
|
1999-11-06 03:08:34 +00:00
|
|
|
}
|
2001-03-25 01:52:16 +00:00
|
|
|
offset += sz;
|
|
|
|
left -= sz;
|
1999-11-06 03:08:34 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MSG_AUTH:
|
|
|
|
{
|
|
|
|
/* Three bytes, first is a char signifying success */
|
2001-03-25 01:52:16 +00:00
|
|
|
unsigned char auth_suc;
|
|
|
|
|
|
|
|
auth_suc = tvb_get_guint8(tvb, offset);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset,
|
1999-11-06 03:08:34 +00:00
|
|
|
1,
|
2000-03-07 05:30:37 +00:00
|
|
|
"Authorization: (%u) %s",auth_suc,
|
1999-11-06 03:08:34 +00:00
|
|
|
(auth_suc==0)?"Denied":"Allowed");
|
2001-03-25 01:52:16 +00:00
|
|
|
offset++;
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset,
|
1999-11-06 03:08:34 +00:00
|
|
|
sizeof(guint16),
|
2001-03-25 01:52:16 +00:00
|
|
|
"x1: 0x%04x",
|
|
|
|
tvb_get_letohs(tvb, offset));
|
1999-11-06 03:08:34 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MSG_AUTH_REQ:
|
2001-03-25 01:52:16 +00:00
|
|
|
for (n = 0; n < N_AUTH_REQ_FIELDS; n++) {
|
|
|
|
if (n != N_AUTH_REQ_FIELDS - 1) {
|
|
|
|
sep_offset = tvb_find_guint8(tvb, offset, left, 0xfe);
|
|
|
|
sz = sep_offset - offset + 1;
|
|
|
|
} else
|
|
|
|
sz = left;
|
|
|
|
if (sz != 0) {
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset,
|
|
|
|
sz,
|
|
|
|
"%s: %.*s",
|
|
|
|
auth_req_field_descr[n],
|
|
|
|
sz - 1,
|
|
|
|
tvb_get_ptr(tvb, offset, sz));
|
|
|
|
} else {
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset,
|
|
|
|
0,
|
|
|
|
"%s: %s", auth_req_field_descr[n], "(empty)");
|
|
|
|
}
|
|
|
|
offset += sz;
|
|
|
|
left -= sz;
|
|
|
|
}
|
1999-11-06 03:08:34 +00:00
|
|
|
break;
|
|
|
|
case MSG_USER_ADDED:
|
2001-03-25 01:52:16 +00:00
|
|
|
for (n = 0; n < N_USER_ADDED_FIELDS; n++) {
|
|
|
|
if (n != N_USER_ADDED_FIELDS - 1) {
|
|
|
|
sep_offset = tvb_find_guint8(tvb, offset, left, 0xfe);
|
|
|
|
sz = sep_offset - offset + 1;
|
|
|
|
} else
|
|
|
|
sz = left;
|
|
|
|
if (sz != 0) {
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset,
|
|
|
|
sz,
|
|
|
|
"%s: %.*s",
|
|
|
|
user_added_field_descr[n],
|
|
|
|
sz - 1,
|
|
|
|
tvb_get_ptr(tvb, offset, sz));
|
|
|
|
} else {
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset,
|
|
|
|
0,
|
|
|
|
"%s: %s", user_added_field_descr[n], "(empty)");
|
|
|
|
}
|
|
|
|
offset += sz;
|
|
|
|
left -= sz;
|
|
|
|
}
|
1999-11-06 03:08:34 +00:00
|
|
|
break;
|
|
|
|
case MSG_CONTACTS:
|
|
|
|
{
|
2001-03-25 01:52:16 +00:00
|
|
|
gint sep_offset_prev;
|
1999-11-06 03:08:34 +00:00
|
|
|
int sz = 0; /* Size of the current element */
|
|
|
|
int n = 0; /* The nth element */
|
2001-03-25 01:52:16 +00:00
|
|
|
gboolean last = FALSE;
|
|
|
|
|
|
|
|
while (!last) {
|
|
|
|
sep_offset = tvb_find_guint8(tvb, offset, left, 0xfe);
|
|
|
|
if (sep_offset != -1)
|
|
|
|
sz = sep_offset - offset + 1;
|
|
|
|
else {
|
1999-11-06 03:08:34 +00:00
|
|
|
sz = left;
|
2001-03-25 01:52:16 +00:00
|
|
|
last = TRUE;
|
|
|
|
}
|
1999-11-06 03:08:34 +00:00
|
|
|
if (n == 0) {
|
|
|
|
/* The first element is the number of Nick/UIN pairs follow */
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset,
|
1999-11-06 03:08:34 +00:00
|
|
|
sz,
|
2001-03-25 01:52:16 +00:00
|
|
|
"Number of pairs: %.*s",
|
|
|
|
sz - 1,
|
|
|
|
tvb_get_ptr(tvb, offset, sz));
|
1999-11-06 03:08:34 +00:00
|
|
|
n++;
|
2001-03-25 01:52:16 +00:00
|
|
|
} else if (!last) {
|
1999-11-06 03:08:34 +00:00
|
|
|
int svsz = sz;
|
2001-03-25 01:52:16 +00:00
|
|
|
|
|
|
|
left -= sz;
|
|
|
|
sep_offset_prev = sep_offset;
|
|
|
|
sep_offset = tvb_find_guint8(tvb, sep_offset_prev, left,
|
|
|
|
0xfe);
|
|
|
|
if (sep_offset != -1)
|
|
|
|
sz = sep_offset - offset + 1;
|
|
|
|
else {
|
1999-11-06 03:08:34 +00:00
|
|
|
sz = left;
|
2001-03-25 01:52:16 +00:00
|
|
|
last = TRUE;
|
|
|
|
}
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset,
|
|
|
|
sz + svsz,
|
|
|
|
"%.*s: %.*s",
|
|
|
|
svsz - 1,
|
|
|
|
tvb_get_ptr(tvb, offset, svsz),
|
|
|
|
sz - 1,
|
|
|
|
tvb_get_ptr(tvb, sep_offset_prev + 1, sz));
|
|
|
|
n += 2;
|
1999-11-06 03:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
left -= (sz+1);
|
2001-03-25 01:52:16 +00:00
|
|
|
offset = sep_offset + 1;
|
1999-11-06 03:08:34 +00:00
|
|
|
}
|
|
|
|
break;
|
2001-03-25 01:52:16 +00:00
|
|
|
}
|
|
|
|
}
|
1999-11-06 03:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************
|
|
|
|
*
|
|
|
|
* Client commands
|
|
|
|
*
|
|
|
|
*********************************/
|
1999-10-25 20:28:21 +00:00
|
|
|
static void
|
|
|
|
icqv5_cmd_ack(proto_tree* tree,/* Tree to put the data in */
|
2001-03-25 01:52:16 +00:00
|
|
|
tvbuff_t *tvb, /* Tvbuff with decrypted packet data */
|
|
|
|
int offset) /* Offset from the start of the packet to the content */
|
1999-10-25 20:28:21 +00:00
|
|
|
{
|
|
|
|
proto_tree* subtree;
|
|
|
|
proto_item* ti;
|
|
|
|
|
|
|
|
if (tree){
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
4,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-10-25 20:28:21 +00:00
|
|
|
offset + CMD_ACK_RANDOM,
|
|
|
|
4,
|
2001-03-25 01:52:16 +00:00
|
|
|
"Random: 0x%08x",
|
|
|
|
tvb_get_letohl(tvb, offset + CMD_ACK_RANDOM));
|
1999-10-25 20:28:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-11-06 03:08:34 +00:00
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
icqv5_cmd_rand_search(proto_tree* tree, /* Tree to put the data in */
|
|
|
|
tvbuff_t *tvb, /* Decrypted packet content */
|
|
|
|
int offset, /* Offset from the start of the packet to the content */
|
|
|
|
int size) /* Number of chars left to do */
|
1999-11-06 03:08:34 +00:00
|
|
|
{
|
2001-03-25 01:52:16 +00:00
|
|
|
guint16 group;
|
1999-11-06 03:08:34 +00:00
|
|
|
proto_tree* subtree;
|
|
|
|
proto_item* ti;
|
|
|
|
|
|
|
|
static const char* groups[] = {
|
|
|
|
"Name",
|
|
|
|
"General",
|
|
|
|
"Romance",
|
|
|
|
"Games",
|
|
|
|
"Students",
|
|
|
|
"20 Something",
|
|
|
|
"30 Something",
|
|
|
|
"40 Something",
|
|
|
|
"50 or worse",
|
|
|
|
"Man want women",
|
|
|
|
"Women want men"
|
|
|
|
};
|
|
|
|
|
|
|
|
if (tree){
|
2002-05-02 10:46:23 +00:00
|
|
|
if (size < 4) {
|
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
size,
|
|
|
|
"Body (%d bytes, should be 4)", size);
|
|
|
|
return;
|
|
|
|
}
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
4,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
group = tvb_get_letohs(tvb, offset + CMD_RAND_SEARCH_GROUP);
|
1999-11-06 03:08:34 +00:00
|
|
|
if (group>0 && (group<=sizeof(groups)/sizeof(const char*)))
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + CMD_RAND_SEARCH_GROUP,
|
|
|
|
4,
|
2000-03-07 05:30:37 +00:00
|
|
|
"Group: (%u) %s", group, groups[group-1]);
|
1999-11-06 03:08:34 +00:00
|
|
|
else
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + CMD_RAND_SEARCH_GROUP,
|
|
|
|
4,
|
2000-03-07 05:30:37 +00:00
|
|
|
"Group: (%u)", group);
|
1999-11-06 03:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
icqv5_cmd_ack_messages(proto_tree* tree, /* Tree to put the data in */
|
|
|
|
tvbuff_t *tvb, /* Decrypted packet content */
|
|
|
|
int offset) /* Offset from the start of the packet to the content */
|
1999-11-06 03:08:34 +00:00
|
|
|
{
|
|
|
|
proto_tree* subtree;
|
|
|
|
proto_item* ti;
|
|
|
|
|
|
|
|
if (tree){
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
4,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + CMD_ACK_MESSAGES_RANDOM,
|
|
|
|
4,
|
2001-03-25 01:52:16 +00:00
|
|
|
"Random: 0x%08x",
|
|
|
|
tvb_get_letohl(tvb, offset + CMD_ACK_MESSAGES_RANDOM));
|
1999-11-06 03:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
icqv5_cmd_keep_alive(proto_tree* tree, /* Tree to put the data in */
|
|
|
|
tvbuff_t *tvb, /* Decrypted packet content */
|
|
|
|
int offset) /* Offset from the start of the packet to the content */
|
1999-11-06 03:08:34 +00:00
|
|
|
{
|
2001-03-25 01:52:16 +00:00
|
|
|
guint32 random;
|
1999-11-06 03:08:34 +00:00
|
|
|
proto_tree* subtree;
|
|
|
|
proto_item* ti;
|
|
|
|
|
|
|
|
if (tree){
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
4,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
random = tvb_get_letohl(tvb, offset + CMD_KEEP_ALIVE_RANDOM);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + CMD_KEEP_ALIVE_RANDOM,
|
|
|
|
4,
|
2000-03-07 05:30:37 +00:00
|
|
|
"Random: 0x%08x", random);
|
1999-11-06 03:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
icqv5_cmd_send_text_code(proto_tree* tree, /* Tree to put the data in */
|
|
|
|
tvbuff_t *tvb, /* Decrypted packet content */
|
|
|
|
int offset, /* Offset from the start of the packet to the content */
|
|
|
|
int size) /* Number of chars left to do */
|
1999-11-06 03:08:34 +00:00
|
|
|
{
|
2000-03-07 05:30:37 +00:00
|
|
|
proto_tree* subtree = NULL;
|
|
|
|
proto_item* ti = NULL;
|
2002-02-25 07:56:59 +00:00
|
|
|
guint16 len;
|
|
|
|
guint16 x1;
|
1999-11-06 03:08:34 +00:00
|
|
|
|
|
|
|
if (tree){
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
size,
|
|
|
|
"Body");
|
2000-03-07 05:30:37 +00:00
|
|
|
}
|
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
len = tvb_get_letohs(tvb, offset+CMD_SEND_TEXT_CODE_LEN);
|
2000-03-07 05:30:37 +00:00
|
|
|
if (tree){
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + CMD_SEND_TEXT_CODE_LEN,
|
|
|
|
2,
|
|
|
|
"Length: %d", len);
|
2000-03-07 05:30:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (len>0) {
|
|
|
|
if (tree){
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + CMD_SEND_TEXT_CODE_TEXT,
|
|
|
|
len,
|
2001-03-25 01:52:16 +00:00
|
|
|
"Text: %.*s",
|
|
|
|
len,
|
|
|
|
tvb_get_ptr(tvb, offset + CMD_SEND_TEXT_CODE_TEXT,
|
|
|
|
len));
|
2000-03-07 05:30:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
x1 = tvb_get_letohs(tvb, offset + CMD_SEND_TEXT_CODE_TEXT + len);
|
2000-03-07 05:30:37 +00:00
|
|
|
if (tree){
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + CMD_SEND_TEXT_CODE_TEXT + len,
|
|
|
|
2,
|
|
|
|
"X1: 0x%04x", x1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
icqv5_cmd_add_to_list(proto_tree* tree, /* Tree to put the data in */
|
|
|
|
tvbuff_t *tvb, /* Decrypted packet content */
|
|
|
|
int offset) /* Offset from the start of the packet to the content */
|
1999-11-06 03:08:34 +00:00
|
|
|
{
|
2002-02-25 07:56:59 +00:00
|
|
|
guint32 uin;
|
1999-11-06 03:08:34 +00:00
|
|
|
proto_tree* subtree;
|
|
|
|
proto_item* ti;
|
2001-03-25 01:52:16 +00:00
|
|
|
|
1999-11-06 03:08:34 +00:00
|
|
|
if (tree){
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
4,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
uin = tvb_get_letohl(tvb, offset + CMD_ADD_TO_LIST);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + CMD_ADD_TO_LIST_UIN,
|
|
|
|
4,
|
2000-03-07 05:30:37 +00:00
|
|
|
"UIN: %u", uin);
|
1999-11-06 03:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
icqv5_cmd_status_change(proto_tree* tree, /* Tree to put the data in */
|
|
|
|
tvbuff_t *tvb, /* Decrypted packet content */
|
|
|
|
int offset) /* Offset from the start of the packet to the content */
|
1999-11-06 03:08:34 +00:00
|
|
|
{
|
2001-03-25 01:52:16 +00:00
|
|
|
guint32 status;
|
1999-11-06 03:08:34 +00:00
|
|
|
proto_tree* subtree;
|
|
|
|
proto_item* ti;
|
|
|
|
|
|
|
|
if (tree){
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
4,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
status = tvb_get_letohl(tvb, offset + CMD_STATUS_CHANGE_STATUS);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset + CMD_STATUS_CHANGE_STATUS,
|
|
|
|
4,
|
2001-07-03 09:08:03 +00:00
|
|
|
"Status: %s", findStatus(status));
|
1999-11-06 03:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-10-25 20:28:21 +00:00
|
|
|
static void
|
|
|
|
icqv5_cmd_send_msg(proto_tree* tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvbuff_t *tvb,
|
1999-10-25 20:28:21 +00:00
|
|
|
int offset,
|
2002-05-02 10:46:23 +00:00
|
|
|
int size)
|
1999-10-25 20:28:21 +00:00
|
|
|
{
|
|
|
|
proto_tree* subtree;
|
|
|
|
proto_item* ti;
|
|
|
|
int left = size; /* left chars to do */
|
1999-12-05 22:59:55 +00:00
|
|
|
|
1999-10-25 20:28:21 +00:00
|
|
|
if (tree) {
|
2002-05-02 10:46:23 +00:00
|
|
|
if (size < 4) {
|
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
size,
|
|
|
|
"Body (%d bytes, should be >= 4)", size);
|
|
|
|
return;
|
|
|
|
}
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
size,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-10-25 20:28:21 +00:00
|
|
|
offset + CMD_SEND_MSG_RECV_UIN,
|
|
|
|
4,
|
2001-03-25 01:52:16 +00:00
|
|
|
"Receiver UIN: %u",
|
|
|
|
tvb_get_letohl(tvb, offset + CMD_SEND_MSG_RECV_UIN));
|
|
|
|
left -= 4;
|
1999-10-25 20:28:21 +00:00
|
|
|
|
1999-11-06 03:08:34 +00:00
|
|
|
icqv5_decode_msgType(subtree,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + CMD_SEND_MSG_MSG_TYPE,
|
2001-03-25 01:52:16 +00:00
|
|
|
left);
|
1999-10-25 20:28:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
icqv5_cmd_login(proto_tree* tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvbuff_t *tvb,
|
1999-10-25 20:28:21 +00:00
|
|
|
int offset,
|
|
|
|
int size)
|
|
|
|
{
|
|
|
|
proto_item* ti;
|
|
|
|
proto_tree* subtree;
|
2001-03-25 01:52:16 +00:00
|
|
|
time_t theTime;
|
|
|
|
char *aTime;
|
|
|
|
guint32 port;
|
|
|
|
guint32 passwdLen;
|
2002-08-02 23:36:07 +00:00
|
|
|
const guchar *ipAddrp;
|
2001-03-25 01:52:16 +00:00
|
|
|
guint32 status;
|
1999-10-25 20:28:21 +00:00
|
|
|
|
|
|
|
if (tree) {
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
size,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
theTime = tvb_get_letohl(tvb, offset + CMD_LOGIN_TIME);
|
|
|
|
aTime = ctime(&theTime);
|
|
|
|
aTime[strlen(aTime)-1] = '\0';
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset + CMD_LOGIN_TIME,
|
|
|
|
4,
|
|
|
|
"Time: %ld = %s", (long)theTime, aTime);
|
|
|
|
port = tvb_get_letohl(tvb, offset + CMD_LOGIN_PORT);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset + CMD_LOGIN_PORT,
|
|
|
|
4,
|
|
|
|
"Port: %u", port);
|
|
|
|
passwdLen = tvb_get_letohs(tvb, offset + CMD_LOGIN_PASSLEN);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset + CMD_LOGIN_PASSLEN,
|
|
|
|
2 + passwdLen,
|
|
|
|
"Passwd: %.*s",
|
|
|
|
(int)passwdLen,
|
|
|
|
tvb_get_ptr(tvb, offset + CMD_LOGIN_PASSWD,
|
|
|
|
passwdLen));
|
|
|
|
ipAddrp = tvb_get_ptr(tvb,
|
|
|
|
offset + CMD_LOGIN_PASSWD + passwdLen + CMD_LOGIN_IP,
|
|
|
|
4);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset + CMD_LOGIN_PASSWD + passwdLen + CMD_LOGIN_IP,
|
|
|
|
4,
|
|
|
|
"IP: %s", ip_to_str(ipAddrp));
|
|
|
|
status = tvb_get_letohs(tvb,
|
|
|
|
offset + CMD_LOGIN_PASSWD + passwdLen + CMD_LOGIN_STATUS);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset + CMD_LOGIN_PASSWD + passwdLen + CMD_LOGIN_STATUS,
|
|
|
|
4,
|
|
|
|
"Status: %s", findStatus(status));
|
1999-10-25 20:28:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-11-06 03:08:34 +00:00
|
|
|
static void
|
|
|
|
icqv5_cmd_contact_list(proto_tree* tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvbuff_t *tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
int offset,
|
|
|
|
int size)
|
|
|
|
{
|
|
|
|
proto_tree* subtree;
|
|
|
|
proto_item* ti;
|
2001-03-25 01:52:16 +00:00
|
|
|
unsigned char num;
|
|
|
|
int i;
|
1999-11-06 03:08:34 +00:00
|
|
|
guint32 uin;
|
|
|
|
|
|
|
|
if (tree) {
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
size,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
num = tvb_get_guint8(tvb, offset + CMD_CONTACT_LIST_NUM);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + CMD_CONTACT_LIST,
|
|
|
|
1,
|
2000-03-07 05:30:37 +00:00
|
|
|
"Number of uins: %u", num);
|
1999-11-06 03:08:34 +00:00
|
|
|
/*
|
|
|
|
* A sequence of num times UIN follows
|
|
|
|
*/
|
|
|
|
offset += (CMD_CONTACT_LIST_NUM + 1);
|
2001-03-25 01:52:16 +00:00
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
uin = tvb_get_letohl(tvb, offset);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset,
|
|
|
|
4,
|
|
|
|
"UIN[%d]: %u", i ,uin);
|
|
|
|
offset += 4;
|
1999-11-06 03:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
icqv5_cmd_no_params(proto_tree* tree, /* Tree to put the data in */
|
|
|
|
tvbuff_t *tvb, /* Decrypted packet content */
|
2002-05-02 10:46:23 +00:00
|
|
|
int offset) /* Offset from the start of the packet to the content */
|
1999-11-06 03:08:34 +00:00
|
|
|
{
|
|
|
|
proto_tree* subtree;
|
|
|
|
proto_item* ti;
|
|
|
|
|
|
|
|
if (tree){
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
0,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset,
|
|
|
|
0,
|
|
|
|
"No parameters");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
*
|
|
|
|
* Server commands
|
|
|
|
*
|
|
|
|
**********************
|
|
|
|
*/
|
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
icqv5_srv_no_params(proto_tree* tree, /* Tree to put the data in */
|
|
|
|
tvbuff_t *tvb, /* Packet content */
|
2002-05-02 10:46:23 +00:00
|
|
|
int offset) /* Offset from the start of the packet to the content */
|
1999-11-06 03:08:34 +00:00
|
|
|
{
|
|
|
|
proto_tree* subtree;
|
|
|
|
proto_item* ti;
|
|
|
|
|
|
|
|
if (tree){
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
0,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset,
|
|
|
|
0,
|
|
|
|
"No Parameters");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
icqv5_srv_login_reply(proto_tree* tree,/* Tree to put the data in */
|
2001-03-25 01:52:16 +00:00
|
|
|
tvbuff_t *tvb, /* Tvbuff with packet */
|
|
|
|
int offset, /* Offset from the start of the packet to the content */
|
|
|
|
int size) /* Number of chars left to do */
|
1999-11-06 03:08:34 +00:00
|
|
|
{
|
|
|
|
proto_tree* subtree;
|
|
|
|
proto_item* ti;
|
2002-08-02 23:36:07 +00:00
|
|
|
const guchar *ipAddrp;
|
1999-11-06 03:08:34 +00:00
|
|
|
|
|
|
|
if (tree) {
|
2002-05-02 10:46:23 +00:00
|
|
|
if (size < SRV_LOGIN_REPLY_IP + 8) {
|
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
size,
|
|
|
|
"Body (%d bytes, should be %d)", size,
|
|
|
|
SRV_LOGIN_REPLY_IP + 8);
|
|
|
|
return;
|
|
|
|
}
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
SRV_LOGIN_REPLY_IP + 8,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
ipAddrp = tvb_get_ptr(tvb, offset + SRV_LOGIN_REPLY_IP, 4);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + SRV_LOGIN_REPLY_IP,
|
|
|
|
4,
|
|
|
|
"IP: %s", ip_to_str(ipAddrp));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
icqv5_srv_user_online(proto_tree* tree,/* Tree to put the data in */
|
2001-03-25 01:52:16 +00:00
|
|
|
tvbuff_t *tvb, /* Tvbuff with packet */
|
|
|
|
int offset, /* Offset from the start of the packet to the content */
|
|
|
|
int size) /* Number of chars left to do */
|
1999-11-06 03:08:34 +00:00
|
|
|
{
|
|
|
|
proto_tree* subtree;
|
|
|
|
proto_item* ti;
|
2002-08-02 23:36:07 +00:00
|
|
|
const guchar *ipAddrp;
|
|
|
|
const guchar *realipAddrp;
|
2001-03-25 01:52:16 +00:00
|
|
|
guint32 status;
|
1999-11-06 03:08:34 +00:00
|
|
|
|
|
|
|
if (tree) {
|
2002-05-02 10:46:23 +00:00
|
|
|
if (size < SRV_LOGIN_REPLY_IP + 8) {
|
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
size,
|
|
|
|
"Body (%d bytes, should be %d)", size,
|
|
|
|
SRV_LOGIN_REPLY_IP + 8);
|
|
|
|
return;
|
|
|
|
}
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
SRV_LOGIN_REPLY_IP + 8,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + SRV_USER_ONL_UIN,
|
|
|
|
4,
|
2001-03-25 01:52:16 +00:00
|
|
|
"UIN: %u",
|
|
|
|
tvb_get_letohl(tvb, offset + SRV_USER_ONL_UIN));
|
|
|
|
ipAddrp = tvb_get_ptr(tvb, offset + SRV_USER_ONL_IP, 4);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + SRV_USER_ONL_IP,
|
|
|
|
4,
|
|
|
|
"IP: %s", ip_to_str(ipAddrp));
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + SRV_USER_ONL_PORT,
|
|
|
|
4,
|
2001-03-25 01:52:16 +00:00
|
|
|
"Port: %u",
|
|
|
|
tvb_get_letohl(tvb, offset + SRV_USER_ONL_PORT));
|
|
|
|
realipAddrp = tvb_get_ptr(tvb, offset + SRV_USER_ONL_REALIP, 4);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + SRV_USER_ONL_REALIP,
|
|
|
|
4,
|
|
|
|
"RealIP: %s", ip_to_str(realipAddrp));
|
2001-03-25 01:52:16 +00:00
|
|
|
status = tvb_get_letohs(tvb, offset + SRV_USER_ONL_STATUS);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + SRV_USER_ONL_STATUS,
|
1999-12-05 22:59:55 +00:00
|
|
|
2,
|
1999-11-06 03:08:34 +00:00
|
|
|
"Status: %s", findStatus(status));
|
2001-03-25 01:52:16 +00:00
|
|
|
/*
|
|
|
|
* Kojak: Hypothesis is that this field might be an encoding for the
|
|
|
|
* version used by the UIN that changed. To test this, I included
|
|
|
|
* this line to the code.
|
|
|
|
*/
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + SRV_USER_ONL_X2,
|
|
|
|
4,
|
2001-03-25 01:52:16 +00:00
|
|
|
"Version: %08x",
|
|
|
|
tvb_get_letohl(tvb, offset + SRV_USER_ONL_X2));
|
1999-11-06 03:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
icqv5_srv_user_offline(proto_tree* tree,/* Tree to put the data in */
|
2001-03-25 01:52:16 +00:00
|
|
|
tvbuff_t *tvb, /* Tvbuff with packet */
|
|
|
|
int offset, /* Offset from the start of the packet to the content */
|
|
|
|
int size) /* Number of chars left to do */
|
1999-11-06 03:08:34 +00:00
|
|
|
{
|
|
|
|
proto_tree* subtree;
|
|
|
|
proto_item* ti;
|
|
|
|
|
|
|
|
if (tree) {
|
2002-05-02 10:46:23 +00:00
|
|
|
if (size < SRV_USER_OFFLINE_UIN + 4) {
|
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
size,
|
|
|
|
"Body (%d bytes, should be %d)", size,
|
|
|
|
SRV_USER_OFFLINE_UIN + 4);
|
|
|
|
return;
|
|
|
|
}
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
SRV_USER_OFFLINE_UIN + 4,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + SRV_USER_OFFLINE_UIN,
|
|
|
|
4,
|
2001-03-25 01:52:16 +00:00
|
|
|
"UIN: %u",
|
|
|
|
tvb_get_letohl(tvb, offset + SRV_USER_OFFLINE));
|
1999-11-06 03:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
icqv5_srv_multi(proto_tree* tree, /* Tree to put the data in */
|
|
|
|
tvbuff_t *tvb, /* Packet content */
|
|
|
|
int offset, /* Offset from the start of the packet to the content */
|
|
|
|
int size, /* Number of chars left to do */
|
|
|
|
packet_info* pinfo)
|
1999-11-06 03:08:34 +00:00
|
|
|
{
|
|
|
|
proto_tree* subtree;
|
|
|
|
proto_item* ti;
|
2002-02-25 07:56:59 +00:00
|
|
|
guint8 num;
|
1999-11-06 03:08:34 +00:00
|
|
|
guint16 pktSz;
|
2001-07-03 09:08:03 +00:00
|
|
|
int i;
|
1999-11-06 03:08:34 +00:00
|
|
|
|
|
|
|
if (tree) {
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
size,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
num = tvb_get_guint8(tvb, offset + SRV_MULTI_NUM);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + SRV_MULTI_NUM,
|
|
|
|
1,
|
2000-03-07 05:30:37 +00:00
|
|
|
"Number of pkts: %u", num);
|
1999-11-06 03:08:34 +00:00
|
|
|
/*
|
|
|
|
* A sequence of num times ( pktsize, packetData) follows
|
|
|
|
*/
|
|
|
|
offset += (SRV_MULTI_NUM + 1);
|
2001-07-03 09:08:03 +00:00
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
pktSz = tvb_get_letohs(tvb, offset);
|
|
|
|
offset += 2;
|
|
|
|
dissect_icqv5Server(tvb, offset, pinfo, subtree, pktSz);
|
|
|
|
offset += pktSz;
|
1999-11-06 03:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
icqv5_srv_meta_user(proto_tree* tree, /* Tree to put the data in */
|
|
|
|
tvbuff_t *tvb, /* Tvbuff with packet */
|
|
|
|
int offset, /* Offset from the start of the packet to the content */
|
|
|
|
int size) /* Number of chars left to do */
|
1999-11-06 03:08:34 +00:00
|
|
|
{
|
1999-12-05 22:59:55 +00:00
|
|
|
#if 0
|
1999-11-06 03:08:34 +00:00
|
|
|
proto_tree* subtree = NULL;
|
1999-12-05 22:59:55 +00:00
|
|
|
#endif
|
|
|
|
proto_tree* sstree = NULL;
|
1999-11-06 03:08:34 +00:00
|
|
|
proto_item* ti = NULL;
|
|
|
|
int left = size;
|
2001-03-25 01:52:16 +00:00
|
|
|
guint16 subcmd;
|
|
|
|
unsigned char result;
|
1999-11-06 03:08:34 +00:00
|
|
|
|
|
|
|
if (tree) {
|
1999-12-05 22:59:55 +00:00
|
|
|
#if 0
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
size,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2001-03-25 01:52:16 +00:00
|
|
|
subcmd = tvb_get_letohs(tvb, offset + SRV_META_USER_SUBCMD);
|
|
|
|
ti = proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + SRV_META_USER_SUBCMD,
|
|
|
|
2,
|
|
|
|
"%s", findSubCmd(subcmd));
|
2001-03-25 01:52:16 +00:00
|
|
|
result = tvb_get_guint8(tvb, offset + SRV_META_USER_RESULT);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + SRV_META_USER_RESULT,
|
|
|
|
1,
|
|
|
|
"%s", (result==0x0a)?"Success":"Failure");
|
1999-12-05 22:59:55 +00:00
|
|
|
sstree = proto_item_add_subtree(ti, ett_icq_body_parts);
|
|
|
|
#else
|
2001-03-25 01:52:16 +00:00
|
|
|
subcmd = tvb_get_letohs(tvb, offset + SRV_META_USER_SUBCMD);
|
|
|
|
ti = proto_tree_add_text(tree, tvb,
|
1999-12-05 22:59:55 +00:00
|
|
|
offset + SRV_META_USER_SUBCMD,
|
|
|
|
2,
|
|
|
|
"%s", findSubCmd(subcmd));
|
|
|
|
sstree = proto_item_add_subtree(ti, ett_icq_body_parts);
|
2001-03-25 01:52:16 +00:00
|
|
|
result = tvb_get_guint8(tvb, offset + SRV_META_USER_RESULT);
|
|
|
|
proto_tree_add_text(sstree, tvb,
|
1999-12-05 22:59:55 +00:00
|
|
|
offset + SRV_META_USER_RESULT,
|
|
|
|
1,
|
|
|
|
"%s", (result==0x0a)?"Success":"Failure");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Skip the META_USER header */
|
|
|
|
left -= 3;
|
2001-03-25 01:52:16 +00:00
|
|
|
offset += 3;
|
1999-12-05 22:59:55 +00:00
|
|
|
|
1999-11-06 03:08:34 +00:00
|
|
|
switch(subcmd) {
|
1999-12-05 22:59:55 +00:00
|
|
|
case META_EX_USER_FOUND:
|
|
|
|
{
|
|
|
|
/* This is almost the same as META_USER_FOUND,
|
|
|
|
* however, there's an extra length field
|
|
|
|
*/
|
2002-02-25 07:56:59 +00:00
|
|
|
guint16 pktLen;
|
1999-12-05 22:59:55 +00:00
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
/* Read the length field */
|
|
|
|
pktLen = tvb_get_letohs(tvb, offset);
|
|
|
|
proto_tree_add_text(sstree, tvb,
|
|
|
|
offset,
|
1999-12-05 22:59:55 +00:00
|
|
|
sizeof(guint16),
|
2000-03-07 05:30:37 +00:00
|
|
|
"Length: %u", pktLen);
|
1999-12-05 22:59:55 +00:00
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
offset += sizeof(guint16); left -= sizeof(guint16);
|
1999-12-05 22:59:55 +00:00
|
|
|
}
|
1999-11-06 03:08:34 +00:00
|
|
|
case META_USER_FOUND:
|
|
|
|
{
|
|
|
|
/* The goto mentioned in this block should be local to this
|
|
|
|
* block if C'd allow it.
|
|
|
|
*
|
|
|
|
* They are used to "implement" a poorman's exception handling
|
|
|
|
*/
|
|
|
|
int len = 0;
|
1999-12-05 22:59:55 +00:00
|
|
|
char *descr[] = {
|
|
|
|
"Nick",
|
|
|
|
"First name",
|
|
|
|
"Last name",
|
|
|
|
"Email",
|
|
|
|
NULL};
|
|
|
|
char** d = descr;
|
|
|
|
unsigned char auth;
|
|
|
|
/*
|
|
|
|
* Read UIN
|
|
|
|
*/
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(sstree, tvb,
|
|
|
|
offset,
|
1999-11-06 03:08:34 +00:00
|
|
|
sizeof(guint32),
|
2001-03-25 01:52:16 +00:00
|
|
|
"UIN: %u",
|
|
|
|
tvb_get_letohl(tvb, offset));
|
|
|
|
offset+=sizeof(guint32);left-=sizeof(guint32);
|
1999-12-05 22:59:55 +00:00
|
|
|
|
|
|
|
for ( ; *d!=NULL; d++) {
|
|
|
|
len = proto_add_icq_attr(sstree,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
|
|
|
offset,
|
1999-12-05 22:59:55 +00:00
|
|
|
*d);
|
|
|
|
if (len == -1)
|
|
|
|
return;
|
2001-03-25 01:52:16 +00:00
|
|
|
offset += len; left -= len;
|
1999-12-05 22:59:55 +00:00
|
|
|
}
|
1999-11-06 03:08:34 +00:00
|
|
|
/* Get the authorize setting */
|
2001-03-25 01:52:16 +00:00
|
|
|
auth = tvb_get_guint8(tvb, offset);
|
|
|
|
proto_tree_add_text(sstree, tvb,
|
|
|
|
offset,
|
|
|
|
1,
|
1999-12-05 22:59:55 +00:00
|
|
|
"authorization: %s", (auth==0x01)?"Neccessary":"Who needs it");
|
2001-03-25 01:52:16 +00:00
|
|
|
offset++; left--;
|
1999-11-06 03:08:34 +00:00
|
|
|
/* Get x2 */
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(sstree, tvb,
|
|
|
|
offset,
|
1999-11-06 03:08:34 +00:00
|
|
|
sizeof(guint16),
|
2001-03-25 01:52:16 +00:00
|
|
|
"x2: 0x%04x",
|
|
|
|
tvb_get_letohs(tvb, offset));
|
|
|
|
offset+=sizeof(guint16);left-=sizeof(guint16);
|
1999-11-06 03:08:34 +00:00
|
|
|
/* Get x3 */
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(sstree, tvb,
|
|
|
|
offset,
|
1999-11-06 03:08:34 +00:00
|
|
|
sizeof(guint32),
|
2001-03-25 01:52:16 +00:00
|
|
|
"x3: 0x%08x",
|
|
|
|
tvb_get_letohl(tvb, offset));
|
|
|
|
offset+=sizeof(guint32);left-=sizeof(guint32);
|
1999-11-06 03:08:34 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case META_ABOUT:
|
|
|
|
{
|
|
|
|
int len;
|
2001-03-25 01:52:16 +00:00
|
|
|
|
1999-11-06 03:08:34 +00:00
|
|
|
/* Get the about information */
|
2001-03-25 01:52:16 +00:00
|
|
|
len = tvb_get_letohs(tvb, offset);
|
|
|
|
offset+=sizeof(guint16);left-=sizeof(guint16);
|
|
|
|
proto_tree_add_text(sstree, tvb,
|
|
|
|
offset - sizeof(guint16),
|
1999-11-06 03:08:34 +00:00
|
|
|
sizeof(guint16)+len,
|
2001-03-25 01:52:16 +00:00
|
|
|
"About(%d): %.*s", len,
|
|
|
|
len, tvb_get_ptr(tvb, offset, len));
|
|
|
|
offset+=len;left-=len;
|
1999-11-06 03:08:34 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case META_USER_INFO:
|
|
|
|
{
|
|
|
|
/* The goto mentioned in this block should be local to this
|
|
|
|
* block if C'd allow it.
|
|
|
|
*
|
|
|
|
* They are used to "implement" a poorman's exception handling
|
|
|
|
*/
|
|
|
|
static const char* descr[] = {
|
|
|
|
"Nick",
|
|
|
|
"First name",
|
|
|
|
"Last name",
|
|
|
|
"Primary email",
|
|
|
|
"Secundary email",
|
|
|
|
"Old email",
|
|
|
|
"City",
|
|
|
|
"State",
|
|
|
|
"Phone",
|
|
|
|
"Fax",
|
|
|
|
"Street",
|
|
|
|
"Cellphone",
|
|
|
|
"Zip",
|
|
|
|
NULL};
|
|
|
|
const char** d = descr;
|
|
|
|
guint16 country;
|
2002-02-25 07:56:59 +00:00
|
|
|
guint8 user_timezone;
|
|
|
|
guint8 auth;
|
1999-11-06 03:08:34 +00:00
|
|
|
int len = 0;
|
|
|
|
#if 0
|
|
|
|
/* Get the uin */
|
2001-03-25 01:52:16 +00:00
|
|
|
uin = tvb_get_letohl(tvb, offset);
|
|
|
|
proto_tree_add_text(sstree, tvb,
|
|
|
|
offset,
|
1999-11-06 03:08:34 +00:00
|
|
|
sizeof(guint32),
|
2000-03-07 05:30:37 +00:00
|
|
|
"UIN: %u", uin);
|
2001-03-25 01:52:16 +00:00
|
|
|
offset+=sizeof(guint32);left-=sizeof(guint32);
|
1999-11-06 03:08:34 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get every field from the description
|
|
|
|
*/
|
|
|
|
while ((*d)!=NULL) {
|
2001-03-25 01:52:16 +00:00
|
|
|
len = tvb_get_letohs(tvb, offset);
|
|
|
|
offset+=sizeof(guint16);left-=sizeof(guint16);
|
1999-11-06 03:08:34 +00:00
|
|
|
if (len>0) {
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(sstree, tvb,
|
|
|
|
offset - sizeof(guint16),
|
1999-11-06 03:08:34 +00:00
|
|
|
sizeof(guint16)+len,
|
2001-03-25 01:52:16 +00:00
|
|
|
"%s(%d): %.*s",*d, len,
|
|
|
|
len - 1,
|
|
|
|
tvb_get_ptr(tvb, offset, len - 1));
|
|
|
|
offset+=len;left-=len;
|
1999-11-06 03:08:34 +00:00
|
|
|
}
|
|
|
|
d++;
|
|
|
|
}
|
|
|
|
/* Get country code */
|
2001-03-25 01:52:16 +00:00
|
|
|
country = tvb_get_letohs(tvb, offset);
|
|
|
|
proto_tree_add_text(sstree, tvb,
|
|
|
|
offset,
|
1999-11-06 03:08:34 +00:00
|
|
|
sizeof(guint16),
|
2000-03-07 05:30:37 +00:00
|
|
|
"Countrycode: %u", country);
|
2001-03-25 01:52:16 +00:00
|
|
|
offset+=sizeof(guint16); left-=sizeof(guint16);
|
1999-11-06 03:08:34 +00:00
|
|
|
/* Get the timezone setting */
|
2001-03-25 01:52:16 +00:00
|
|
|
user_timezone = tvb_get_guint8(tvb, offset);
|
|
|
|
proto_tree_add_text(sstree, tvb,
|
|
|
|
offset,
|
1999-11-06 03:08:34 +00:00
|
|
|
sizeof(unsigned char),
|
2000-03-07 05:30:37 +00:00
|
|
|
"Timezone: %u", user_timezone);
|
2001-03-25 01:52:16 +00:00
|
|
|
offset++; left--;
|
1999-11-06 03:08:34 +00:00
|
|
|
/* Get the authorize setting */
|
2001-03-25 01:52:16 +00:00
|
|
|
auth = tvb_get_guint8(tvb, offset);
|
|
|
|
proto_tree_add_text(sstree, tvb,
|
|
|
|
offset,
|
1999-11-06 03:08:34 +00:00
|
|
|
sizeof(unsigned char),
|
2000-03-07 05:30:37 +00:00
|
|
|
"Authorization: (%u) %s",
|
1999-11-06 03:08:34 +00:00
|
|
|
auth, (auth==0)?"No":"Yes");
|
2001-03-25 01:52:16 +00:00
|
|
|
offset++; left--;
|
1999-11-06 03:08:34 +00:00
|
|
|
/* Get the webaware setting */
|
2001-03-25 01:52:16 +00:00
|
|
|
auth = tvb_get_guint8(tvb, offset);
|
|
|
|
proto_tree_add_text(sstree, tvb,
|
|
|
|
offset,
|
1999-11-06 03:08:34 +00:00
|
|
|
sizeof(unsigned char),
|
2000-03-07 05:30:37 +00:00
|
|
|
"Webaware: (%u) %s",
|
1999-11-06 03:08:34 +00:00
|
|
|
auth, (auth==0)?"No":"Yes");
|
2001-03-25 01:52:16 +00:00
|
|
|
offset++; left--;
|
1999-11-06 03:08:34 +00:00
|
|
|
/* Get the authorize setting */
|
2001-03-25 01:52:16 +00:00
|
|
|
auth = tvb_get_guint8(tvb, offset);
|
|
|
|
proto_tree_add_text(sstree, tvb,
|
|
|
|
offset,
|
1999-11-06 03:08:34 +00:00
|
|
|
sizeof(unsigned char),
|
2000-03-07 05:30:37 +00:00
|
|
|
"HideIP: (%u) %s",
|
1999-11-06 03:08:34 +00:00
|
|
|
auth, (auth==0)?"No":"Yes");
|
2001-03-25 01:52:16 +00:00
|
|
|
offset++; left--;
|
1999-11-06 03:08:34 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
/* This information is already printed in the tree */
|
|
|
|
fprintf(stderr, "Meta subcmd: %04x\n", subcmd);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
icqv5_srv_recv_message(proto_tree* tree, /* Tree to put the data in */
|
|
|
|
tvbuff_t* tvb, /* Packet content */
|
|
|
|
int offset, /* Offset from the start of the packet to the content */
|
|
|
|
int size) /* Number of chars left to do */
|
1999-11-06 03:08:34 +00:00
|
|
|
{
|
|
|
|
proto_tree* subtree = NULL;
|
|
|
|
proto_item* ti = NULL;
|
|
|
|
int left = size;
|
2002-02-25 07:56:59 +00:00
|
|
|
guint16 year;
|
|
|
|
guint8 month;
|
|
|
|
guint8 day;
|
|
|
|
guint8 hour;
|
|
|
|
guint8 minute;
|
1999-11-06 03:08:34 +00:00
|
|
|
|
|
|
|
if (tree) {
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
4,
|
|
|
|
"Body");
|
1999-11-16 11:44:20 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
2002-02-25 07:56:59 +00:00
|
|
|
proto_tree_add_item(subtree,
|
2001-03-25 01:52:16 +00:00
|
|
|
hf_icq_uin,
|
|
|
|
tvb,
|
|
|
|
offset + SRV_RECV_MSG_UIN,
|
|
|
|
sizeof(guint32),
|
2002-02-25 07:56:59 +00:00
|
|
|
TRUE);
|
2001-03-25 01:52:16 +00:00
|
|
|
year = tvb_get_letohs(tvb, offset + SRV_RECV_MSG_YEAR);
|
|
|
|
month = tvb_get_guint8(tvb, offset + SRV_RECV_MSG_MONTH);
|
|
|
|
day = tvb_get_guint8(tvb, offset + SRV_RECV_MSG_DAY);
|
|
|
|
hour = tvb_get_guint8(tvb, offset + SRV_RECV_MSG_HOUR);
|
|
|
|
minute = tvb_get_guint8(tvb, offset + SRV_RECV_MSG_MINUTE);
|
|
|
|
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
|
|
|
offset + SRV_RECV_MSG_YEAR,
|
|
|
|
sizeof(guint16) + 4*sizeof(unsigned char),
|
|
|
|
"Time: %u-%u-%u %02u:%02u",
|
|
|
|
day, month, year, hour, minute);
|
1999-11-06 03:08:34 +00:00
|
|
|
icqv5_decode_msgType(subtree,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + SRV_RECV_MSG_MSG_TYPE,
|
|
|
|
left);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-12-05 22:59:55 +00:00
|
|
|
static void
|
|
|
|
icqv5_srv_rand_user(proto_tree* tree, /* Tree to put the data in */
|
2001-03-25 01:52:16 +00:00
|
|
|
tvbuff_t *tvb, /* Tvbuff with packet */
|
|
|
|
int offset) /* Offset from the start of the packet to the content */
|
1999-12-05 22:59:55 +00:00
|
|
|
{
|
|
|
|
proto_tree* subtree = NULL;
|
|
|
|
proto_item* ti = NULL;
|
2002-02-25 07:56:59 +00:00
|
|
|
guint32 uin;
|
1999-12-05 22:59:55 +00:00
|
|
|
const unsigned char* IP = NULL;
|
2002-02-25 07:56:59 +00:00
|
|
|
guint32 port;
|
1999-12-05 22:59:55 +00:00
|
|
|
const unsigned char* realIP = NULL;
|
2002-02-25 07:56:59 +00:00
|
|
|
guint8 commClass;
|
1999-12-05 22:59:55 +00:00
|
|
|
guint32 status;
|
|
|
|
guint16 tcpVer;
|
|
|
|
|
|
|
|
if (tree) {
|
2001-07-03 09:08:03 +00:00
|
|
|
ti = proto_tree_add_text(tree,
|
|
|
|
tvb,
|
|
|
|
offset,
|
|
|
|
SRV_RAND_USER_TCP_VER + 2,
|
|
|
|
"Body");
|
1999-12-05 22:59:55 +00:00
|
|
|
subtree = proto_item_add_subtree(ti, ett_icq_body);
|
|
|
|
/* guint32 UIN */
|
2001-03-25 01:52:16 +00:00
|
|
|
uin = tvb_get_letohl(tvb, offset + SRV_RAND_USER_UIN);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-12-05 22:59:55 +00:00
|
|
|
offset + SRV_RAND_USER_UIN,
|
|
|
|
sizeof(guint32),
|
2000-03-07 05:30:37 +00:00
|
|
|
"UIN: %u", uin);
|
1999-12-05 22:59:55 +00:00
|
|
|
/* guint32 IP */
|
2001-03-25 01:52:16 +00:00
|
|
|
IP = tvb_get_ptr(tvb, offset + SRV_RAND_USER_IP, 4);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-12-05 22:59:55 +00:00
|
|
|
offset + SRV_RAND_USER_IP,
|
|
|
|
sizeof(guint32),
|
2001-03-25 01:52:16 +00:00
|
|
|
"IP: %s",
|
|
|
|
ip_to_str(IP));
|
2002-02-25 07:56:59 +00:00
|
|
|
/* guint16 portNum */
|
|
|
|
/* XXX - 16 bits, or 32 bits? */
|
2001-03-25 01:52:16 +00:00
|
|
|
port = tvb_get_letohs(tvb, offset + SRV_RAND_USER_PORT);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-12-05 22:59:55 +00:00
|
|
|
offset + SRV_RAND_USER_UIN,
|
|
|
|
sizeof(guint32),
|
2000-03-07 05:30:37 +00:00
|
|
|
"Port: %u", port);
|
2001-03-25 01:52:16 +00:00
|
|
|
/* guint32 realIP */
|
|
|
|
realIP = tvb_get_ptr(tvb, offset + SRV_RAND_USER_REAL_IP, 4);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-12-05 22:59:55 +00:00
|
|
|
offset + SRV_RAND_USER_REAL_IP,
|
|
|
|
sizeof(guint32),
|
|
|
|
"RealIP: %s", ip_to_str(realIP));
|
2002-02-25 07:56:59 +00:00
|
|
|
/* guint8 Communication Class */
|
2001-03-25 01:52:16 +00:00
|
|
|
commClass = tvb_get_guint8(tvb, offset + SRV_RAND_USER_CLASS);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-12-05 22:59:55 +00:00
|
|
|
offset + SRV_RAND_USER_CLASS,
|
2002-02-25 07:56:59 +00:00
|
|
|
sizeof(guint8),
|
1999-12-05 22:59:55 +00:00
|
|
|
"Class: %s", (commClass!=4)?"User to User":"Through Server");
|
|
|
|
/* guint32 status */
|
2002-02-25 07:56:59 +00:00
|
|
|
/* XXX - 16 bits, or 32 bits? */
|
2001-03-25 01:52:16 +00:00
|
|
|
status = tvb_get_letohs(tvb, offset + SRV_RAND_USER_STATUS);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-12-05 22:59:55 +00:00
|
|
|
offset + SRV_RAND_USER_STATUS,
|
|
|
|
sizeof(guint32),
|
2001-07-03 09:08:03 +00:00
|
|
|
"Status: %s", findStatus(status));
|
1999-12-05 22:59:55 +00:00
|
|
|
/* guint16 tcpVersion */
|
2001-03-25 01:52:16 +00:00
|
|
|
tcpVer = tvb_get_letohs(tvb, offset + SRV_RAND_USER_TCP_VER);
|
|
|
|
proto_tree_add_text(subtree, tvb,
|
1999-12-05 22:59:55 +00:00
|
|
|
offset + SRV_RAND_USER_TCP_VER,
|
|
|
|
sizeof(guint16),
|
2000-03-07 05:30:37 +00:00
|
|
|
"TCPVersion: %u", tcpVer);
|
1999-12-05 22:59:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-10-24 00:56:11 +00:00
|
|
|
/*
|
|
|
|
* Dissect all the v5 client traffic. This is encrypted, so be careful.
|
|
|
|
*/
|
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
dissect_icqv5Client(tvbuff_t *tvb,
|
|
|
|
packet_info *pinfo,
|
1999-10-24 00:56:11 +00:00
|
|
|
proto_tree *tree)
|
|
|
|
{
|
|
|
|
proto_tree *icq_tree = NULL;
|
1999-10-25 20:28:21 +00:00
|
|
|
proto_tree *icq_header_tree = NULL;
|
1999-10-24 00:56:11 +00:00
|
|
|
proto_item *ti = NULL;
|
|
|
|
|
2002-05-02 10:46:23 +00:00
|
|
|
int pktsize; /* The actual size of the ICQ content */
|
|
|
|
int capturedsize; /* The captured size of the ICQ content */
|
2001-06-18 05:54:26 +00:00
|
|
|
guint32 rounded_size;
|
2001-03-25 01:52:16 +00:00
|
|
|
guint32 key;
|
|
|
|
guint16 cmd;
|
2001-05-27 21:37:23 +00:00
|
|
|
guint8 *decr_pd; /* Decrypted content */
|
2001-03-25 01:52:16 +00:00
|
|
|
tvbuff_t *decr_tvb;
|
1999-10-24 00:56:11 +00:00
|
|
|
|
2002-05-02 10:46:23 +00:00
|
|
|
pktsize = tvb_reported_length(tvb);
|
|
|
|
capturedsize = tvb_length(tvb);
|
2000-11-19 19:23:54 +00:00
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
/* Get the encryption key */
|
|
|
|
key = get_v5key(tvb, pktsize);
|
|
|
|
|
2001-06-18 05:54:26 +00:00
|
|
|
/*
|
|
|
|
* Make a copy of the packet data, and decrypt it.
|
2001-06-18 06:31:05 +00:00
|
|
|
* The decryption processes 4 bytes at a time, and starts at
|
|
|
|
* an offset of ICQ5_CL_SESSIONID (which isn't a multiple of 4),
|
|
|
|
* so we make sure that there are
|
|
|
|
*
|
|
|
|
* (ICQ5_CL_SESSIONID + a multiple of 4)
|
|
|
|
*
|
|
|
|
* bytes in the buffer.
|
2001-06-18 05:54:26 +00:00
|
|
|
*/
|
2002-05-02 10:46:23 +00:00
|
|
|
rounded_size = ((((capturedsize - ICQ5_CL_SESSIONID) + 3)/4)*4) + ICQ5_CL_SESSIONID;
|
2001-06-18 05:54:26 +00:00
|
|
|
decr_pd = g_malloc(rounded_size);
|
2002-05-02 10:46:23 +00:00
|
|
|
tvb_memcpy(tvb, decr_pd, 0, capturedsize);
|
2001-06-18 05:54:26 +00:00
|
|
|
decrypt_v5(decr_pd, rounded_size, key);
|
1999-10-24 00:56:11 +00:00
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
/* Allocate a new tvbuff, referring to the decrypted data. */
|
2002-05-02 10:46:23 +00:00
|
|
|
decr_tvb = tvb_new_real_data(decr_pd, capturedsize, pktsize);
|
2001-03-25 01:52:16 +00:00
|
|
|
|
2001-05-27 21:37:23 +00:00
|
|
|
/* Arrange that the allocated packet data copy be freed when the
|
|
|
|
tvbuff is freed. */
|
|
|
|
tvb_set_free_cb(decr_tvb, g_free);
|
|
|
|
|
2001-03-27 02:01:31 +00:00
|
|
|
/* Add the tvbuff to the list of tvbuffs to which the tvbuff we
|
|
|
|
were handed refers, so it'll get cleaned up when that tvbuff
|
|
|
|
is cleaned up. */
|
|
|
|
tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
|
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
/* Add the decrypted data to the data source list. */
|
2002-06-04 07:03:57 +00:00
|
|
|
add_new_data_source(pinfo, decr_tvb, "Decrypted");
|
2001-03-25 01:52:16 +00:00
|
|
|
|
|
|
|
cmd = tvb_get_letohs(decr_tvb, ICQ5_CL_CMD);
|
|
|
|
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_INFO))
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "ICQv5 %s", findClientCmd(cmd));
|
1999-10-24 00:56:11 +00:00
|
|
|
|
|
|
|
if (tree) {
|
2000-03-14 07:12:23 +00:00
|
|
|
ti = proto_tree_add_protocol_format(tree,
|
1999-10-24 00:56:11 +00:00
|
|
|
proto_icq,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
|
|
|
0,
|
2002-05-02 10:46:23 +00:00
|
|
|
-1,
|
2000-03-07 05:30:37 +00:00
|
|
|
"ICQv5 %s (len %u)",
|
1999-10-25 20:28:21 +00:00
|
|
|
findClientCmd(cmd),
|
|
|
|
pktsize);
|
1999-11-16 11:44:20 +00:00
|
|
|
icq_tree = proto_item_add_subtree(ti, ett_icq);
|
2000-03-12 04:48:32 +00:00
|
|
|
ti = proto_tree_add_uint_format(icq_tree,
|
1999-11-06 03:08:34 +00:00
|
|
|
hf_icq_type,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
|
|
|
0,
|
1999-11-06 03:08:34 +00:00
|
|
|
ICQ5_CL_HDRSIZE,
|
|
|
|
ICQ5_client,
|
|
|
|
"Header");
|
1999-11-16 11:44:20 +00:00
|
|
|
icq_header_tree = proto_item_add_subtree(ti, ett_icq_header);
|
1999-10-25 20:28:21 +00:00
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(icq_header_tree, tvb,
|
|
|
|
ICQ_VERSION,
|
2000-08-04 23:12:21 +00:00
|
|
|
2,
|
2001-03-25 01:52:16 +00:00
|
|
|
"Version: %u",
|
|
|
|
tvb_get_letohs(tvb, ICQ_VERSION));
|
|
|
|
proto_tree_add_item(icq_header_tree,
|
|
|
|
hf_icq_uin,
|
|
|
|
tvb,
|
|
|
|
ICQ5_CL_UIN,
|
|
|
|
4,
|
|
|
|
TRUE);
|
|
|
|
proto_tree_add_item(icq_header_tree,
|
|
|
|
hf_icq_sessionid,
|
|
|
|
decr_tvb,
|
|
|
|
ICQ5_CL_SESSIONID,
|
|
|
|
4,
|
|
|
|
TRUE);
|
2001-07-03 09:08:03 +00:00
|
|
|
proto_tree_add_uint_format(icq_header_tree,
|
|
|
|
hf_icq_client_cmd,
|
|
|
|
decr_tvb,
|
2001-03-25 01:52:16 +00:00
|
|
|
ICQ5_CL_CMD,
|
2000-08-04 23:12:21 +00:00
|
|
|
2,
|
2001-07-03 09:08:03 +00:00
|
|
|
cmd,
|
|
|
|
"Command: %s (%u)",
|
|
|
|
val_to_str(cmd, clientCmdCode, "Unknown"), cmd);
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(icq_header_tree, decr_tvb,
|
|
|
|
ICQ5_CL_SEQNUM1,
|
2000-08-04 23:12:21 +00:00
|
|
|
2,
|
2001-03-25 01:52:16 +00:00
|
|
|
"Seq Number 1: 0x%04x",
|
|
|
|
tvb_get_letohs(decr_tvb, ICQ5_CL_SEQNUM1));
|
|
|
|
proto_tree_add_text(icq_header_tree, decr_tvb,
|
|
|
|
ICQ5_CL_SEQNUM2,
|
2000-08-04 23:12:21 +00:00
|
|
|
2,
|
2001-03-25 01:52:16 +00:00
|
|
|
"Seq Number 2: 0x%04x",
|
|
|
|
tvb_get_letohs(decr_tvb, ICQ5_CL_SEQNUM2));
|
2000-03-12 04:48:32 +00:00
|
|
|
proto_tree_add_uint_format(icq_header_tree,
|
1999-10-24 00:56:11 +00:00
|
|
|
hf_icq_checkcode,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
|
|
|
ICQ5_CL_CHECKCODE,
|
1999-10-24 00:56:11 +00:00
|
|
|
4,
|
|
|
|
key,
|
|
|
|
"Key: 0x%08x",
|
|
|
|
key);
|
1999-10-25 20:28:21 +00:00
|
|
|
switch(cmd) {
|
|
|
|
case CMD_ACK:
|
|
|
|
icqv5_cmd_ack(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
decr_tvb,
|
|
|
|
ICQ5_CL_HDRSIZE);
|
1999-10-25 20:28:21 +00:00
|
|
|
break;
|
|
|
|
case CMD_SEND_MSG:
|
1999-12-05 22:59:55 +00:00
|
|
|
case CMD_MSG_TO_NEW_USER:
|
1999-10-25 20:28:21 +00:00
|
|
|
icqv5_cmd_send_msg(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
decr_tvb,
|
|
|
|
ICQ5_CL_HDRSIZE,
|
2002-05-02 10:46:23 +00:00
|
|
|
pktsize - ICQ5_CL_HDRSIZE);
|
1999-10-25 20:28:21 +00:00
|
|
|
break;
|
1999-11-06 03:08:34 +00:00
|
|
|
case CMD_RAND_SEARCH:
|
|
|
|
icqv5_cmd_rand_search(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
decr_tvb,
|
|
|
|
ICQ5_CL_HDRSIZE,
|
1999-11-06 03:08:34 +00:00
|
|
|
pktsize - ICQ5_CL_HDRSIZE);
|
|
|
|
break;
|
1999-10-25 20:28:21 +00:00
|
|
|
case CMD_LOGIN:
|
|
|
|
icqv5_cmd_login(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
decr_tvb,
|
|
|
|
ICQ5_CL_HDRSIZE,
|
1999-10-25 20:28:21 +00:00
|
|
|
pktsize - ICQ5_CL_HDRSIZE);
|
|
|
|
break;
|
1999-11-06 03:08:34 +00:00
|
|
|
case CMD_SEND_TEXT_CODE:
|
|
|
|
icqv5_cmd_send_text_code(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
decr_tvb,
|
|
|
|
ICQ5_CL_HDRSIZE,
|
1999-11-06 03:08:34 +00:00
|
|
|
pktsize - ICQ5_CL_HDRSIZE);
|
|
|
|
break;
|
|
|
|
case CMD_STATUS_CHANGE:
|
|
|
|
icqv5_cmd_status_change(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
decr_tvb,
|
|
|
|
ICQ5_CL_HDRSIZE);
|
1999-11-06 03:08:34 +00:00
|
|
|
break;
|
|
|
|
case CMD_ACK_MESSAGES:
|
|
|
|
icqv5_cmd_ack_messages(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
decr_tvb,
|
|
|
|
ICQ5_CL_HDRSIZE);
|
1999-11-06 03:08:34 +00:00
|
|
|
break;
|
|
|
|
case CMD_KEEP_ALIVE:
|
|
|
|
icqv5_cmd_keep_alive(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
decr_tvb,
|
|
|
|
ICQ5_CL_HDRSIZE);
|
1999-11-06 03:08:34 +00:00
|
|
|
break;
|
|
|
|
case CMD_ADD_TO_LIST:
|
|
|
|
icqv5_cmd_add_to_list(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
decr_tvb,
|
|
|
|
ICQ5_CL_HDRSIZE);
|
1999-11-06 03:08:34 +00:00
|
|
|
break;
|
|
|
|
case CMD_CONTACT_LIST:
|
|
|
|
icqv5_cmd_contact_list(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
decr_tvb,
|
|
|
|
ICQ5_CL_HDRSIZE,
|
1999-11-06 03:08:34 +00:00
|
|
|
pktsize - ICQ5_CL_HDRSIZE);
|
|
|
|
break;
|
|
|
|
case CMD_META_USER:
|
|
|
|
case CMD_REG_NEW_USER:
|
|
|
|
case CMD_QUERY_SERVERS:
|
|
|
|
case CMD_QUERY_ADDONS:
|
|
|
|
icqv5_cmd_no_params(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
decr_tvb,
|
2002-05-02 10:46:23 +00:00
|
|
|
ICQ5_CL_HDRSIZE);
|
1999-11-06 03:08:34 +00:00
|
|
|
break;
|
1999-10-25 20:28:21 +00:00
|
|
|
default:
|
2001-07-03 09:08:03 +00:00
|
|
|
proto_tree_add_text(icq_tree,
|
|
|
|
decr_tvb,
|
|
|
|
ICQ5_CL_HDRSIZE,
|
|
|
|
pktsize - ICQ5_CL_HDRSIZE,
|
|
|
|
"Body");
|
1999-11-06 03:08:34 +00:00
|
|
|
fprintf(stderr,"Missing: %s\n", findClientCmd(cmd));
|
1999-10-25 20:28:21 +00:00
|
|
|
break;
|
|
|
|
}
|
1999-10-24 00:56:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-03-25 01:52:16 +00:00
|
|
|
dissect_icqv5Server(tvbuff_t *tvb,
|
1999-10-24 00:56:11 +00:00
|
|
|
int offset,
|
2001-03-25 01:52:16 +00:00
|
|
|
packet_info *pinfo,
|
1999-11-06 03:08:34 +00:00
|
|
|
proto_tree *tree,
|
2001-04-27 01:38:19 +00:00
|
|
|
int pktsize)
|
1999-10-24 00:56:11 +00:00
|
|
|
{
|
|
|
|
/* Server traffic is easy, not encrypted */
|
|
|
|
proto_tree *icq_tree = NULL;
|
1999-11-06 03:08:34 +00:00
|
|
|
proto_tree *icq_header_tree = NULL;
|
1999-10-24 00:56:11 +00:00
|
|
|
proto_item *ti = NULL;
|
2001-04-27 01:38:19 +00:00
|
|
|
int changeCol = (pktsize==-1);
|
1999-10-24 00:56:11 +00:00
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
guint16 cmd;
|
1999-10-24 00:56:11 +00:00
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
cmd = tvb_get_letohs(tvb, offset + ICQ5_SRV_CMD);
|
2001-12-10 00:26:21 +00:00
|
|
|
if (changeCol && check_col(pinfo->cinfo, COL_INFO))
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "ICQv5 %s", findServerCmd(cmd));
|
2001-03-25 01:52:16 +00:00
|
|
|
|
2001-04-27 01:38:19 +00:00
|
|
|
if (pktsize == -1)
|
2001-03-25 01:52:16 +00:00
|
|
|
pktsize = tvb_reported_length(tvb);
|
1999-10-24 00:56:11 +00:00
|
|
|
|
|
|
|
if (tree) {
|
2000-03-14 07:12:23 +00:00
|
|
|
ti = proto_tree_add_protocol_format(tree,
|
1999-10-24 00:56:11 +00:00
|
|
|
proto_icq,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
1999-10-24 00:56:11 +00:00
|
|
|
offset,
|
2000-03-14 07:12:23 +00:00
|
|
|
pktsize,
|
2000-03-07 05:30:37 +00:00
|
|
|
"ICQv5 %s (len %u)",
|
1999-11-06 03:08:34 +00:00
|
|
|
findServerCmd(cmd),
|
|
|
|
pktsize);
|
1999-10-24 00:56:11 +00:00
|
|
|
|
1999-11-16 11:44:20 +00:00
|
|
|
icq_tree = proto_item_add_subtree(ti, ett_icq);
|
1999-11-06 03:08:34 +00:00
|
|
|
|
2000-03-12 04:48:32 +00:00
|
|
|
ti = proto_tree_add_uint_format(icq_tree,
|
1999-11-06 03:08:34 +00:00
|
|
|
hf_icq_type,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset,
|
|
|
|
ICQ5_SRV_HDRSIZE,
|
|
|
|
ICQ5_server,
|
|
|
|
"Header");
|
1999-11-16 11:44:20 +00:00
|
|
|
icq_header_tree = proto_item_add_subtree(ti, ett_icq_header);
|
1999-11-06 03:08:34 +00:00
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(icq_header_tree, tvb,
|
2000-08-04 23:12:21 +00:00
|
|
|
offset + ICQ_VERSION,
|
|
|
|
2,
|
2001-03-25 01:52:16 +00:00
|
|
|
"Version: %u",
|
|
|
|
tvb_get_letohs(tvb, ICQ_VERSION));
|
|
|
|
proto_tree_add_item(icq_header_tree,
|
|
|
|
hf_icq_sessionid,
|
|
|
|
tvb,
|
|
|
|
offset + ICQ5_SRV_SESSIONID,
|
|
|
|
4,
|
|
|
|
TRUE);
|
2001-07-03 09:08:03 +00:00
|
|
|
proto_tree_add_uint_format(icq_header_tree,
|
|
|
|
hf_icq_server_cmd,
|
|
|
|
tvb,
|
2000-08-04 23:12:21 +00:00
|
|
|
offset + ICQ5_SRV_CMD,
|
|
|
|
2,
|
2001-07-03 09:08:03 +00:00
|
|
|
cmd,
|
|
|
|
"Command: %s (%u)",
|
|
|
|
val_to_str(cmd, serverCmdCode, "Unknown"), cmd);
|
2001-03-25 01:52:16 +00:00
|
|
|
proto_tree_add_text(icq_header_tree, tvb,
|
2000-08-05 00:55:55 +00:00
|
|
|
offset + ICQ5_SRV_SEQNUM1,
|
1999-11-06 03:08:34 +00:00
|
|
|
2,
|
2001-03-25 01:52:16 +00:00
|
|
|
"Seq Number 1: 0x%04x",
|
|
|
|
tvb_get_letohs(tvb, offset + ICQ5_SRV_SEQNUM1));
|
|
|
|
proto_tree_add_text(icq_header_tree, tvb,
|
2000-08-05 00:55:55 +00:00
|
|
|
offset + ICQ5_SRV_SEQNUM2,
|
1999-11-06 03:08:34 +00:00
|
|
|
2,
|
2001-03-25 01:52:16 +00:00
|
|
|
"Seq Number 2: 0x%04x",
|
|
|
|
tvb_get_letohs(tvb, offset + ICQ5_SRV_SEQNUM2));
|
|
|
|
proto_tree_add_item(icq_header_tree,
|
|
|
|
hf_icq_uin,
|
|
|
|
tvb,
|
|
|
|
offset + ICQ5_SRV_UIN,
|
|
|
|
4,
|
|
|
|
TRUE);
|
|
|
|
proto_tree_add_item(icq_header_tree,
|
|
|
|
hf_icq_checkcode,
|
|
|
|
tvb,
|
|
|
|
offset + ICQ5_SRV_CHECKCODE,
|
|
|
|
4,
|
|
|
|
TRUE);
|
1999-11-06 03:08:34 +00:00
|
|
|
switch (cmd) {
|
1999-12-05 22:59:55 +00:00
|
|
|
case SRV_RAND_USER:
|
|
|
|
icqv5_srv_rand_user(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
|
|
|
offset + ICQ5_SRV_HDRSIZE);
|
1999-12-05 22:59:55 +00:00
|
|
|
break;
|
|
|
|
case SRV_SYS_DELIVERED_MESS:
|
|
|
|
/* The message structures are all the same. Why not run
|
|
|
|
* the same routine? */
|
|
|
|
icqv5_cmd_send_msg(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
1999-12-05 22:59:55 +00:00
|
|
|
offset + ICQ5_SRV_HDRSIZE,
|
2002-05-02 10:46:23 +00:00
|
|
|
pktsize - ICQ5_SRV_HDRSIZE);
|
1999-12-05 22:59:55 +00:00
|
|
|
break;
|
1999-11-06 03:08:34 +00:00
|
|
|
case SRV_USER_ONLINE:
|
|
|
|
icqv5_srv_user_online(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + ICQ5_SRV_HDRSIZE,
|
|
|
|
pktsize - ICQ5_SRV_HDRSIZE);
|
|
|
|
break;
|
|
|
|
case SRV_USER_OFFLINE:
|
|
|
|
icqv5_srv_user_offline(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + ICQ5_SRV_HDRSIZE,
|
|
|
|
pktsize - ICQ5_SRV_HDRSIZE);
|
|
|
|
break;
|
|
|
|
case SRV_LOGIN_REPLY:
|
|
|
|
icqv5_srv_login_reply(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + ICQ5_SRV_HDRSIZE,
|
|
|
|
pktsize - ICQ5_SRV_HDRSIZE);
|
|
|
|
break;
|
|
|
|
case SRV_META_USER:
|
|
|
|
icqv5_srv_meta_user(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + ICQ5_SRV_HDRSIZE,
|
|
|
|
pktsize - ICQ5_SRV_HDRSIZE);
|
|
|
|
break;
|
|
|
|
case SRV_RECV_MESSAGE:
|
|
|
|
icqv5_srv_recv_message(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + ICQ5_SRV_HDRSIZE,
|
|
|
|
pktsize - ICQ5_SRV_HDRSIZE);
|
|
|
|
break;
|
|
|
|
case SRV_MULTI:
|
|
|
|
icqv5_srv_multi(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
1999-11-06 03:08:34 +00:00
|
|
|
offset + ICQ5_SRV_HDRSIZE,
|
|
|
|
pktsize - ICQ5_SRV_HDRSIZE,
|
2001-03-25 01:52:16 +00:00
|
|
|
pinfo);
|
1999-11-06 03:08:34 +00:00
|
|
|
break;
|
|
|
|
case SRV_ACK:
|
2000-08-04 23:12:21 +00:00
|
|
|
case SRV_SILENT_TOO_LONG:
|
1999-11-06 03:08:34 +00:00
|
|
|
case SRV_GO_AWAY:
|
|
|
|
case SRV_NEW_UIN:
|
|
|
|
case SRV_BAD_PASS:
|
|
|
|
case SRV_UPDATE_SUCCESS:
|
|
|
|
icqv5_srv_no_params(icq_tree,
|
2001-03-25 01:52:16 +00:00
|
|
|
tvb,
|
2002-05-02 10:46:23 +00:00
|
|
|
offset + ICQ5_SRV_HDRSIZE);
|
1999-11-06 03:08:34 +00:00
|
|
|
break;
|
|
|
|
default:
|
2001-07-03 09:08:03 +00:00
|
|
|
proto_tree_add_text(icq_tree,
|
|
|
|
tvb,
|
|
|
|
offset + ICQ5_SRV_HDRSIZE,
|
|
|
|
pktsize - ICQ5_SRV_HDRSIZE,
|
|
|
|
"Body");
|
1999-11-06 03:08:34 +00:00
|
|
|
fprintf(stderr,"Missing: %s\n", findServerCmd(cmd));
|
|
|
|
break;
|
|
|
|
}
|
1999-10-24 00:56:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
static void dissect_icqv5(tvbuff_t *tvb,
|
|
|
|
packet_info *pinfo,
|
2000-04-08 07:07:42 +00:00
|
|
|
proto_tree *tree)
|
1999-10-24 00:56:11 +00:00
|
|
|
{
|
2001-03-25 01:52:16 +00:00
|
|
|
guint32 unknown;
|
1999-10-24 00:56:11 +00:00
|
|
|
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_PROTOCOL))
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICQv5 (UDP)");
|
|
|
|
if (check_col(pinfo->cinfo, COL_INFO))
|
|
|
|
col_set_str(pinfo->cinfo, COL_INFO, "ICQv5 packet");
|
2001-03-25 01:52:16 +00:00
|
|
|
|
|
|
|
unknown = tvb_get_letohl(tvb, ICQ5_UNKNOWN);
|
|
|
|
|
1999-10-24 00:56:11 +00:00
|
|
|
if (unknown == 0x0L) {
|
2001-03-25 01:52:16 +00:00
|
|
|
dissect_icqv5Client(tvb, pinfo, tree);
|
1999-10-24 00:56:11 +00:00
|
|
|
} else {
|
2001-04-27 01:38:19 +00:00
|
|
|
dissect_icqv5Server(tvb, 0, pinfo, tree, -1);
|
1999-10-24 00:56:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
static void dissect_icq(tvbuff_t *tvb,
|
|
|
|
packet_info *pinfo,
|
2000-04-08 07:07:42 +00:00
|
|
|
proto_tree *tree)
|
1999-10-24 00:56:11 +00:00
|
|
|
{
|
2001-03-25 01:52:16 +00:00
|
|
|
int version;
|
1999-10-24 00:56:11 +00:00
|
|
|
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICQ");
|
2001-03-25 01:52:16 +00:00
|
|
|
}
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_INFO)) {
|
|
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
2001-03-25 01:52:16 +00:00
|
|
|
}
|
Add the "Edit:Protocols..." feature which currently only implements
the following:
It is now possible to enable/disable a particular protocol decoding
(i.e. the protocol dissector is void or not). When a protocol
is disabled, it is displayed as Data and of course, all linked
sub-protocols are disabled as well.
Disabling a protocol could be interesting:
- in case of buggy dissectors
- in case of wrong heuristics
- for performance reasons
- to decode the data as another protocol (TODO)
Currently (if I am not wrong), all dissectors but NFS can be disabled
(and dissectors that do not register protocols :-)
I do not like the way the RPC sub-dissectors are disabled (in the
sub-dissectors) since this could be done in the RPC dissector itself,
knowing the sub-protocol hfinfo entry (this is why, I've not modified
the NFS one yet).
Two functions are added in proto.c :
gboolean proto_is_protocol_enabled(int n);
void proto_set_decoding(int n, gboolean enabled);
and two MACROs which can be used in dissectors:
OLD_CHECK_DISPLAY_AS_DATA(index, pd, offset, fd, tree)
CHECK_DISPLAY_AS_DATA(index, tvb, pinfo, tree)
See also the XXX in proto_dlg.c and proto.c around the new functions.
svn path=/trunk/; revision=2267
2000-08-13 14:09:15 +00:00
|
|
|
|
2001-03-25 01:52:16 +00:00
|
|
|
version = tvb_get_letohs(tvb, ICQ_VERSION);
|
1999-10-24 00:56:11 +00:00
|
|
|
switch (version) {
|
|
|
|
case 0x0005:
|
2001-03-25 01:52:16 +00:00
|
|
|
dissect_icqv5(tvb, pinfo, tree);
|
1999-10-24 00:56:11 +00:00
|
|
|
break;
|
2000-08-04 23:12:21 +00:00
|
|
|
case 0x0004:
|
2001-03-25 01:52:16 +00:00
|
|
|
dissect_icqv4(tvb, pinfo, tree);
|
2000-08-04 23:12:21 +00:00
|
|
|
break;
|
|
|
|
case 0x0003:
|
2001-03-25 01:52:16 +00:00
|
|
|
dissect_icqv3(tvb, pinfo, tree);
|
2000-08-04 23:12:21 +00:00
|
|
|
break;
|
1999-10-24 00:56:11 +00:00
|
|
|
case 0x0002:
|
2001-03-25 01:52:16 +00:00
|
|
|
dissect_icqv2(tvb, pinfo, tree);
|
1999-10-24 00:56:11 +00:00
|
|
|
break;
|
|
|
|
default:
|
1999-10-25 20:28:21 +00:00
|
|
|
fprintf(stderr, "ICQ: Unknown version (%d)\n", version);
|
1999-10-24 00:56:11 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* registration with the filtering engine */
|
|
|
|
void
|
|
|
|
proto_register_icq(void)
|
|
|
|
{
|
|
|
|
static hf_register_info hf[] = {
|
1999-11-06 03:08:34 +00:00
|
|
|
{ &hf_icq_type,
|
2001-06-18 02:18:27 +00:00
|
|
|
{"Type", "icq.type", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
|
1999-10-24 00:56:11 +00:00
|
|
|
{ &hf_icq_uin,
|
2001-06-18 02:18:27 +00:00
|
|
|
{"UIN", "icq.uin", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
|
1999-10-24 00:56:11 +00:00
|
|
|
{ &hf_icq_sessionid,
|
2001-06-18 02:18:27 +00:00
|
|
|
{"Session ID", "icq.sessionid", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
|
2001-07-03 09:08:03 +00:00
|
|
|
{ &hf_icq_client_cmd,
|
|
|
|
{"Client command", "icq.client_cmd", FT_UINT16, BASE_HEX, VALS(clientCmdCode), 0x0, "", HFILL }},
|
|
|
|
{ &hf_icq_server_cmd,
|
|
|
|
{"Server command", "icq.server_cmd", FT_UINT16, BASE_DEC, VALS(serverCmdCode), 0x0, "", HFILL }},
|
1999-10-24 00:56:11 +00:00
|
|
|
{ &hf_icq_checkcode,
|
2001-06-18 02:18:27 +00:00
|
|
|
{"Checkcode", "icq.checkcode", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
|
1999-10-24 00:56:11 +00:00
|
|
|
{ &hf_icq_decode,
|
2001-06-18 02:18:27 +00:00
|
|
|
{"Decode", "icq.decode", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}
|
1999-10-24 00:56:11 +00:00
|
|
|
};
|
1999-11-16 11:44:20 +00:00
|
|
|
static gint *ett[] = {
|
|
|
|
&ett_icq,
|
|
|
|
&ett_icq_header,
|
|
|
|
&ett_icq_decode,
|
|
|
|
&ett_icq_body,
|
|
|
|
&ett_icq_body_parts,
|
|
|
|
};
|
1999-10-24 00:56:11 +00:00
|
|
|
|
2001-01-03 06:56:03 +00:00
|
|
|
proto_icq = proto_register_protocol("ICQ Protocol", "ICQ", "icq");
|
1999-10-24 00:56:11 +00:00
|
|
|
|
|
|
|
proto_register_field_array(proto_icq, hf, array_length(hf));
|
1999-11-16 11:44:20 +00:00
|
|
|
|
|
|
|
proto_register_subtree_array(ett, array_length(ett));
|
1999-10-24 00:56:11 +00:00
|
|
|
}
|
2000-04-08 07:07:42 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
proto_reg_handoff_icq(void)
|
|
|
|
{
|
2001-12-03 04:00:26 +00:00
|
|
|
dissector_handle_t icq_handle;
|
|
|
|
|
|
|
|
icq_handle = create_dissector_handle(dissect_icq, proto_icq);
|
|
|
|
dissector_add("udp.port", UDP_PORT_ICQ, icq_handle);
|
2000-04-08 07:07:42 +00:00
|
|
|
}
|