/* packet-icq.c
* Routines for ICQ packet disassembly
*
- * $Id: packet-icq.c,v 1.17 2000/08/05 00:55:55 guy Exp $
+ * $Id: packet-icq.c,v 1.39 2002/02/18 01:08:36 guy Exp $
*
* Ethereal - Network traffic analyzer
- * By Johan Feyaerts
- * Copyright 1999 Johan Feyaerts
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
* 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
#include <glib.h>
#ifdef NEED_SNPRINTF_H
-# ifdef HAVE_STDARG_H
-# include <stdarg.h>
-# else
-# include <varargs.h>
-# endif
# include "snprintf.h"
#endif
-#include "packet.h"
-#include "resolv.h"
+#include <epan/packet.h>
+#include <epan/resolv.h>
static int proto_icq = -1;
-static int hf_icq_uin =-1;
-static int hf_icq_cmd =-1;
-static int hf_icq_sessionid =-1;
-static int hf_icq_checkcode =-1;
+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;
static int hf_icq_decode = -1;
static int hf_icq_type = -1;
enum { ICQ5_client, ICQ5_server};
-static void dissect_icqv5(const u_char *pd,
- int offset,
- frame_data *fd,
+static void dissect_icqv5(tvbuff_t *tvb,
+ packet_info *pinfo,
proto_tree *tree);
static void
-dissect_icqv5Server(const u_char *pd,
+dissect_icqv5Server(tvbuff_t *tvb,
int offset,
- frame_data *fd,
+ packet_info *pinfo,
proto_tree *tree,
- guint32 pktsize);
+ int pktsize);
/* Offsets of fields in the ICQ headers */
/* Can be 0x0002 or 0x0005 */
#define ICQ5_SRV_PARAM 0x15
#define ICQ5_SRV_HDRSIZE 0x15
-typedef struct _cmdcode {
- char* descr;
- int code;
-} cmdcode;
-
#define SRV_ACK 0x000a
#define SRV_SILENT_TOO_LONG 0x001e
/* This message has the same structure as cmd_send_msg */
#define SRV_SYS_DELIVERED_MESS 0x0104
-cmdcode 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 },
- { NULL, -1 }
+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 }
};
-cmdcode 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 },
- { "SRV_QUERY", 130 },
- { "SRV_USER_FOUND", 140 },
- { "SRV_END_OF_SEARCH", 160 },
- { "SRV_NEW_USER", 180 },
- { "SRV_UPDATE_EXT", 200 },
- { "SRV_RECV_MESSAGE", SRV_RECV_MESSAGE },
- { "SRV_END_OFFLINE_MESSAGES", 230 },
- { "SRV_NOT_CONNECTED", 240 },
- { "SRV_TRY_AGAIN", 250 },
- { "SRV_SYS_DELIVERED_MESS", SRV_SYS_DELIVERED_MESS },
- { "SRV_INFO_REPLY", 280 },
- { "SRV_EXT_INFO_REPLY", 290 },
- { "SRV_STATUS_UPDATE", 420 },
- { "SRV_SYSTEM_MESSAGE", 450 },
- { "SRV_UPDATE_SUCCESS", SRV_UPDATE_SUCCESS },
- { "SRV_UPDATE_FAIL", SRV_UPDATE_FAIL },
- { "SRV_AUTH_UPDATE", 500 },
- { "SRV_MULTI_PACKET", SRV_MULTI },
- { "SRV_END_CONTACTLIST_STATUS", 540 },
- { "SRV_RAND_USER", SRV_RAND_USER },
- { "SRV_META_USER", SRV_META_USER },
- { NULL, -1 }
+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 }
};
#define MSG_TEXT 0x0001
#define CMD_META_USER 0x064a
-cmdcode 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},
- { NULL, 0}
+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 }
};
-cmdcode statusCode[] = {
- { "ONLINE", STATUS_ONLINE },
- { "AWAY", STATUS_AWAY },
- { "DND", STATUS_DND },
- { "INVISIBLE", STATUS_INVISIBLE },
- { "OCCUPIED", STATUS_OCCUPIED },
- { "NA", STATUS_NA },
- { "Free for Chat", STATUS_CHAT },
- { NULL, 0}
+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 }
};
-cmdcode clientCmdCode[] = {
- { "CMD_ACK", CMD_ACK },
- { "CMD_SEND_MESSAGE", CMD_SEND_MSG },
- { "CMD_LOGIN", CMD_LOGIN },
- { "CMD_REG_NEW_USER", CMD_REG_NEW_USER },
- { "CMD_CONTACT_LIST", 1030 },
- { "CMD_SEARCH_UIN", 1050 },
- { "CMD_SEARCH_USER", 1060 },
- { "CMD_KEEP_ALIVE", 1070 },
- { "CMD_SEND_TEXT_CODE", CMD_SEND_TEXT_CODE },
- { "CMD_ACK_MESSAGES", CMD_ACK_MESSAGES },
- { "CMD_LOGIN_1", 1100 },
- { "CMD_MSG_TO_NEW_USER", CMD_MSG_TO_NEW_USER },
- { "CMD_INFO_REQ", 1120 },
- { "CMD_EXT_INFO_REQ", 1130 },
- { "CMD_CHANGE_PW", 1180 },
- { "CMD_NEW_USER_INFO", 1190 },
- { "CMD_UPDATE_EXT_INFO", 1200 },
- { "CMD_QUERY_SERVERS", CMD_QUERY_SERVERS },
- { "CMD_QUERY_ADDONS", CMD_QUERY_ADDONS },
- { "CMD_STATUS_CHANGE", CMD_STATUS_CHANGE },
- { "CMD_NEW_USER_1", 1260 },
- { "CMD_UPDATE_INFO", 1290 },
- { "CMD_AUTH_UPDATE", 1300 },
- { "CMD_KEEP_ALIVE2", 1310 },
- { "CMD_LOGIN_2", 1320 },
- { "CMD_ADD_TO_LIST", CMD_ADD_TO_LIST },
- { "CMD_RAND_SET", 1380 },
- { "CMD_RAND_SEARCH", CMD_RAND_SEARCH },
- { "CMD_META_USER", CMD_META_USER },
- { "CMD_INVIS_LIST", 1700 },
- { "CMD_VIS_LIST", 1710 },
- { "CMD_UPDATE_LIST", 1720 },
- { NULL, 0 }
+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 }
};
/*
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 };
-static char*
-findcmd(cmdcode* c, int num)
-{
- static char buf[16];
- cmdcode* p = c;
- while (p->descr != NULL) {
- if (p->code == num) {
- return p->descr;
- }
- p++;
- }
- snprintf(buf, sizeof(buf), "(%x)", num);
- return buf;
-}
-
static char*
findMsgType(int num)
{
- return findcmd(msgTypeCode, num);
+ return val_to_str(num, msgTypeCode, "Unknown");
}
static char*
findSubCmd(int num)
{
- return findcmd(serverMetaSubCmdCode, num);
+ return val_to_str(num, serverMetaSubCmdCode, "Unknown (0x%04x)");
}
static char*
findClientCmd(int num)
{
- return findcmd(clientCmdCode, num);
+ return val_to_str(num, clientCmdCode, "Unknown (%u)");
}
static char*
findServerCmd(int num)
{
- return findcmd(serverCmdCode, num);
+ return val_to_str(num, serverCmdCode, "Unknown (%u)");
}
static char*
findStatus(int num)
{
- return findcmd(statusCode, num);
-}
-
-static void
-proto_tree_add_hexdump(proto_tree* t,
- guint32 offset,
- const u_char *data,
- int size)
-{
- int i;
- char buf[96];
- int n;
- int done = 0, line = 0;
- int added = 0;
-
- if (size==0)
- return;
-
- line = size / 16;
-
- for (i=0;i<line;i++) {
- added = 0;
- done = 0;
- for (n = i * 16; n < (i+1)*16; n++) {
- added = sprintf(buf+done, "%02x", data[n]);
- if ((n%8)==7)
- added += sprintf(buf + done + added, " ");
- else
- added += sprintf(buf + done + added, " ");
- done += added;
- }
- for (n = i * 16; n < (i+1)*16; n++) {
- if (isprint(data[n]))
- added = sprintf(buf + done, "%c", data[n]);
- else
- added = sprintf(buf + done, ".");
- done += added;
- }
- proto_tree_add_text(t, NullTVB,
- offset + i*16,
- 16,
- buf);
- }
- if ((size%16)!=0) {
- done = 0;
- for (n = line * 16 ; n < size ; n++) {
- added = sprintf(buf+done, "%02x", data[n]);
- if ((n%8)==7)
- added += sprintf(buf + done + added, " ");
- else
- added += sprintf(buf + done + added, " ");
- done += added;
- }
- for (n = size ; (n%16)!=0;n++) {
- added = 0;
- if ((n%8)==7)
- added += sprintf(buf + done + added, " ");
- else
- added += sprintf(buf + done + added, " ");
- done += added;
- }
- for (n = line * 16; n < (line+1)*16; n++) {
- added = 0;
- if (n<size) {
- if (isprint(data[n]))
- added = sprintf(buf + done, "%c", data[n]);
- else
- added = sprintf(buf + done, ".");
- } else {
- added = sprintf(buf + done, " ");
- }
- done += added;
- }
- proto_tree_add_text(t, NullTVB,
- offset + line*16,
- size % 16,
- buf);
- }
+ return val_to_str(num, statusCode, "Unknown (0x%08x)");
}
static guint32
-get_v5key(const u_char* pd, int len)
+get_v5key(tvbuff_t *tvb, int len)
{
guint32 a1, a2, a3, a4, a5;
guint32 code, check, key;
- code = pletohl(&pd[ICQ5_CL_CHECKCODE]);
+ code = tvb_get_letohl(tvb, ICQ5_CL_CHECKCODE);
a1 = code & 0x0001f000;
a2 = code & 0x07c007c0;
{
guint32 i;
guint32 k;
- for (i=0x0a; i < size+3; i+=4 ) {
+
+ for (i=ICQ5_CL_SESSIONID; i < size; i+=4 ) {
k = key+table_v5[i&0xff];
if ( i != 0x16 ) {
bfr[i] ^= (u_char)(k & 0xff);
}
static void
-dissect_icqv4(const u_char *pd,
- int offset,
- frame_data *fd,
+dissect_icqv4(tvbuff_t *tvb,
+ packet_info *pinfo,
proto_tree *tree)
{
/* Not really implemented yet */
- if (check_col(fd, COL_PROTOCOL)) {
- col_add_str(fd, COL_PROTOCOL, "ICQv4 (UDP)");
+ if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICQv4 (UDP)");
}
- if (check_col(fd, COL_INFO)) {
- col_add_str(fd, COL_INFO, "ICQ Version 4 protocol");
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_set_str(pinfo->cinfo, COL_INFO, "ICQ Version 4 protocol");
}
}
static void
-dissect_icqv3(const u_char *pd,
- int offset,
- frame_data *fd,
+dissect_icqv3(tvbuff_t *tvb,
+ packet_info *pinfo,
proto_tree *tree)
{
/* Not really implemented yet */
- if (check_col(fd, COL_PROTOCOL)) {
- col_add_str(fd, COL_PROTOCOL, "ICQv3 (UDP)");
+ if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICQv3 (UDP)");
}
- if (check_col(fd, COL_INFO)) {
- col_add_str(fd, COL_INFO, "ICQ Version 3 protocol");
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_set_str(pinfo->cinfo, COL_INFO, "ICQ Version 3 protocol");
}
}
static void
-dissect_icqv2(const u_char *pd,
- int offset,
- frame_data *fd,
+dissect_icqv2(tvbuff_t *tvb,
+ packet_info *pinfo,
proto_tree *tree)
{
/* Not really implemented yet */
- if (check_col(fd, COL_PROTOCOL)) {
- col_add_str(fd, COL_PROTOCOL, "ICQv2 (UDP)");
+ if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICQv2 (UDP)");
}
- if (check_col(fd, COL_INFO)) {
- col_add_str(fd, COL_INFO, "ICQ Version 2 protocol");
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_set_str(pinfo->cinfo, COL_INFO, "ICQ Version 2 protocol");
}
}
/*
- * Find first occurrence of ch in buf
- * Buf is max size big.
- */
-static char*
-strnchr(const u_char* buf, u_char ch, int size)
-{
- int i;
- u_char* p = (u_char*) buf;
- for (i=0;(*p) && (*p!=ch) && (i<size); p++, i++)
- ;
- if ((*p == '\0') || (i>=size))
- return NULL;
- return p;
-}
-
-/*
- * The packet at pd has a (len, string) pair.
- * Copy the string to a buffer, and display it in the tree.
- * Observe any limits you might cross.
+ * The packet has, at offset "offset" a (len, string) pair.
+ * Display the length and string in the tree.
*
* 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 */
- const char* pd, /* Pointer to the field */
- const int offset, /* Offset from the start of packet */
- const int size, /* The number of bytes left in pd */
+ tvbuff_t *tvb, /* Tvbuff with packet */
+ const int offset, /* Offset from the start of packet of field */
char* descr) /* The description to use in the tree */
{
guint16 len;
- char* data;
- int left = size;
- if (size<sizeof(guint16))
- return -1;
- len = pletohs(pd);
- left -= sizeof(guint16);
- if (left<len) {
- proto_tree_add_text(tree, NullTVB,
- offset,
- sizeof(guint16),
- "Length: %u", len);
- return -1;
- }
-
- data = g_malloc(len);
-
- strncpy(data, pd + sizeof(guint16), len);
- data[len - 1] = '\0';
-
- proto_tree_add_text(tree, NullTVB,
+ 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,
offset,
sizeof(guint16) + len,
- "%s[%u]: %s", descr, len, data);
- g_free(data);
-
+ "%s[%u]: %.*s", descr, len, len,
+ tvb_get_ptr(tvb, offset + sizeof(guint16), len));
return len + sizeof(guint16);
}
static void
icqv5_decode_msgType(proto_tree* tree,
- const unsigned char* pd, /* From start of messageType */
+ tvbuff_t *tvb,
int offset,
int size)
{
proto_item* ti = NULL;
proto_tree* subtree = NULL;
int left = size;
- char *msgText = NULL;
- guint16 msgType = -1;
- guint16 msgLen = -1;
- int i,j,n;
- static char* auth_req_field_descr[] = {
+ guint16 msgType;
+ gint sep_offset;
+ int sz; /* Size of the current element */
+ unsigned int n;
+ 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[] = {
"Nickname",
"First name",
"Last name",
"Email address",
"Unknown",
- "Reason"};
- static char* emain_field_descr[] = {
+ "Text"
+ };
+#define N_EMAIL_FIELDS (sizeof email_field_descr / sizeof email_field_descr[0])
+ static char* auth_req_field_descr[] = {
"Nickname",
"First name",
"Last name",
"Email address",
"Unknown",
- "Text\n"
+ "Reason"
};
+#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])
- enum {OFF_MSG_TYPE=0,
- OFF_MSG_LEN=2,
- OFF_MSG_TEXT=4};
-
-
- if (left >= sizeof(guint16)) {
- msgType = pletohs(pd + OFF_MSG_TYPE);
- left -= sizeof(guint16);
- }
- if (left >= sizeof(guint16)) {
- msgLen = pletohs(pd + OFF_MSG_LEN);
- left -= sizeof(guint16);
- }
-
- ti = proto_tree_add_text(tree, NullTVB,
- offset ,
- 2,
- "Type: %u (%s)", msgType, findMsgType(msgType));
+ msgType = tvb_get_letohs(tvb, offset);
+ ti = proto_tree_add_text(tree, tvb,
+ offset,
+ size,
+ "Message: Type = %u (%s)", msgType, findMsgType(msgType));
/* Create a new subtree */
subtree = proto_item_add_subtree(ti, ett_icq_body_parts);
+ 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;
+ }
+
switch(msgType) {
case 0xffff: /* Field unknown */
break;
fprintf(stderr, "Unknown msgType: %u (%04x)\n", msgType, msgType);
break;
case MSG_TEXT:
- msgText = g_malloc(left + 1);
- strncpy(msgText, pd + OFF_MSG_TEXT, left);
- msgText[left] = '\0';
- proto_tree_add_text(subtree, NullTVB,
- offset + OFF_MSG_TEXT,
+ proto_tree_add_text(subtree, tvb,
+ offset,
left,
- "Msg: %s", msgText);
- g_free(msgText);
+ "Msg: %.*s", left-1,
+ tvb_get_ptr(tvb, offset, left));
break;
case MSG_URL:
- /* Two parts, a description and the URL. Separeted by FE */
- for (i=0;i<left;i++) {
- if (pd[OFF_MSG_TEXT + i] == 0xfe)
- break;
+ 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;
}
- msgText = g_malloc(i + 1);
- strncpy(msgText, pd + OFF_MSG_TEXT, i);
- if (i==left)
- msgText[i] = '\0';
- else
- msgText[i-1] = '\0';
- proto_tree_add_text(subtree, NullTVB,
- offset + OFF_MSG_TEXT,
- i,
- "Description: %s", msgText);
- if (i==left)
- break;
- msgText = g_realloc(msgText, left - i);
- strncpy(msgText, pd + OFF_MSG_TEXT + i + 1, left - i - 1);
- msgText[left - i] = '\0';
- proto_tree_add_text(subtree, NullTVB,
- offset + OFF_MSG_TEXT,
- i,
- "URL: %s", msgText);
- g_free(msgText);
break;
case MSG_EMAIL:
- i = 0;
- j = 0;
- msgText = NULL;
- for (n = 0; n < 6; n++) {
- for (;
- (i<left) && (pd[OFF_MSG_TEXT+i]!=0xfe);
- i++)
- ;
- if (i>j) {
- msgText = g_realloc(msgText, i-j);
- strncpy(msgText, pd + OFF_MSG_TEXT + j, i - j - 1);
- msgText[i-j-1] = '\0';
- proto_tree_add_text(subtree, NullTVB,
- offset + OFF_MSG_TEXT + j,
- i - j - 1,
- "%s: %s", emain_field_descr[n], msgText);
+ 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));
} else {
- proto_tree_add_text(subtree, NullTVB,
- offset + OFF_MSG_TEXT + j,
+ proto_tree_add_text(subtree, tvb,
+ offset,
0,
- "%s: %s", emain_field_descr[n], "(empty)");
+ "%s: %s", email_field_descr[n], "(empty)");
}
- j = ++i;
+ offset += sz;
+ left -= sz;
}
- if (msgText != NULL)
- g_free(msgText);
break;
case MSG_AUTH:
{
/* Three bytes, first is a char signifying success */
- unsigned char auth_suc = pd[OFF_MSG_LEN];
- guint16 x1 = pd[OFF_MSG_LEN+1];
- proto_tree_add_text(subtree, NullTVB,
- offset + OFF_MSG_LEN,
+ unsigned char auth_suc;
+
+ auth_suc = tvb_get_guint8(tvb, offset);
+ proto_tree_add_text(subtree, tvb,
+ offset,
1,
"Authorization: (%u) %s",auth_suc,
(auth_suc==0)?"Denied":"Allowed");
- proto_tree_add_text(subtree, NullTVB,
- offset + OFF_MSG_LEN + 1,
+ offset++;
+ proto_tree_add_text(subtree, tvb,
+ offset,
sizeof(guint16),
- "x1: 0x%04x",x1);
+ "x1: 0x%04x",
+ tvb_get_letohs(tvb, offset));
break;
}
case MSG_AUTH_REQ:
- /* Six parts, separated by FE */
- i = 0;
- j = 0;
- msgText = g_malloc(64);
- for (n = 0; n < 6 && i<left; n++) {
- while (i<left && pd[OFF_MSG_TEXT+i]!=0xfe)
- i++;
- if (i<=left) {
- /* pd[OFF_MSG_TEXT+i] == 0xfe */
- if (i!=j) {
- /* Otherwise, it'd be a null string */
- msgText = g_realloc(msgText, i - j);
- strncpy(msgText, pd + OFF_MSG_TEXT + j, i-j);
- msgText[i-j] = '\0';
- proto_tree_add_text(subtree, NullTVB,
- offset + OFF_MSG_TEXT + j,
- i - j,
- "%s: %s", auth_req_field_descr[n], msgText);
- } else {
- proto_tree_add_text(subtree, NullTVB,
- offset + OFF_MSG_TEXT + j,
- i - j,
- "%s: %s", auth_req_field_descr[n], "(null)");
- }
- j = ++i;
- /* i and j point after the 0xfe character */
- }
- }
-
- if (msgText != NULL)
- g_free(msgText);
+ 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;
+ }
break;
case MSG_USER_ADDED:
- /* Four parts, separated by FE */
- i = 0;
- j = 0;
- /* This is necessary, because g_realloc does not behave like
- * g_malloc if the first parameter == NULL */
- msgText = g_malloc(64);
- for (n = 0; n < 4 && i<left; n++) {
- while (i<left && pd[OFF_MSG_TEXT+i]!=0xfe)
- i++;
- if (i<=left) {
- /* pd[OFF_MSG_TEXT+i] == 0xfe */
- if (i!=j) {
- /* Otherwise, it'd be a null string */
- msgText = g_realloc(msgText, i - j);
- strncpy(msgText, pd + OFF_MSG_TEXT + j, i-j);
- msgText[i-j] = '\0';
- proto_tree_add_text(subtree, NullTVB,
- offset + OFF_MSG_TEXT + j,
- i - j,
- "%s: %s", auth_req_field_descr[n], msgText);
- } else {
- proto_tree_add_text(subtree, NullTVB,
- offset + OFF_MSG_TEXT + j,
- i - j,
- "%s: %s", auth_req_field_descr[n], "(null)");
- }
- j = ++i;
- /* i and j point after the 0xfe character */
- }
- }
- if (msgText != NULL)
- g_free(msgText);
+ 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;
+ }
break;
case MSG_CONTACTS:
{
- u_char* p = (u_char*) &pd[OFF_MSG_TEXT];
- u_char* pprev = p;
+ gint sep_offset_prev;
int sz = 0; /* Size of the current element */
int n = 0; /* The nth element */
- int done = 0; /* Number of chars processed */
- u_char* msgText2 = NULL;
- msgText = NULL;
- /* Create a new subtree */
- subtree = proto_item_add_subtree(ti, ett_icq_body_parts);
- while (p!=NULL) {
- p = strnchr(pprev, 0xfe, left);
-
- if (p!=NULL)
- sz = (int)(p - pprev);
- else
+ gboolean last = FALSE;
+
+ while (!last) {
+ sep_offset = tvb_find_guint8(tvb, offset, left, 0xfe);
+ if (sep_offset != -1)
+ sz = sep_offset - offset + 1;
+ else {
sz = left;
- msgText = g_realloc(msgText, sz+1);
- strncpy(msgText, pprev, sz);
- msgText[sz] = '\0';
-
+ last = TRUE;
+ }
if (n == 0) {
/* The first element is the number of Nick/UIN pairs follow */
- proto_tree_add_text(subtree, NullTVB,
- offset + OFF_MSG_TEXT + done,
+ proto_tree_add_text(subtree, tvb,
+ offset,
sz,
- "Number of pairs: %s", msgText);
+ "Number of pairs: %.*s",
+ sz - 1,
+ tvb_get_ptr(tvb, offset, sz));
n++;
- } else if (p!=NULL) {
+ } else if (!last) {
int svsz = sz;
- left -= (sz+1);
- pprev = p + 1;
- p = strnchr(pprev, 0xfe, left);
- if (p!=NULL)
- sz = (int)(p - pprev);
- else
+
+ 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 {
sz = left;
- msgText2 = g_malloc(sz+1);
- strncpy(msgText2, pprev, sz);
- msgText2[sz] = '\0';
-
- proto_tree_add_text(subtree, NullTVB,
- offset + OFF_MSG_TEXT + done,
- sz + svsz + 2,
- "%s:%s", msgText, msgText2);
- n+=2;
- g_free(msgText2);
+ 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;
}
left -= (sz+1);
- pprev = p+1;
+ offset = sep_offset + 1;
}
- if (msgText != NULL)
- g_free(msgText);
break;
- }}
+ }
+ }
}
/*********************************
*********************************/
static void
icqv5_cmd_ack(proto_tree* tree,/* Tree to put the data in */
- const u_char* pd, /* Packet content */
- int offset, /* Offset from the start of the packet to the content */
- int size) /* Number of chars left to do */
+ tvbuff_t *tvb, /* Tvbuff with decrypted packet data */
+ int offset) /* Offset from the start of the packet to the content */
{
- guint32 random = pletohl(pd + CMD_ACK_RANDOM);
proto_tree* subtree;
proto_item* ti;
if (tree){
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- 4,
- CMD_ACK,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ 4,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
- proto_tree_add_text(subtree, NullTVB,
+ proto_tree_add_text(subtree, tvb,
offset + CMD_ACK_RANDOM,
4,
- "Random: 0x%08x", random);
+ "Random: 0x%08x",
+ tvb_get_letohl(tvb, offset + CMD_ACK_RANDOM));
}
}
static void
-icqv5_cmd_rand_search(proto_tree* tree, /* Tree to put the data in */
- const u_char* pd, /* Packet content */
- int offset, /* Offset from the start of the packet to the content */
- int size) /* Number of chars left to do */
+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 */
{
- guint16 group = pletohs(pd + CMD_RAND_SEARCH_GROUP);
+ guint16 group;
proto_tree* subtree;
proto_item* ti;
};
if (tree){
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- 4,
- CMD_RAND_SEARCH,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ 4,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
+ group = tvb_get_letohs(tvb, offset + CMD_RAND_SEARCH_GROUP);
if (group>0 && (group<=sizeof(groups)/sizeof(const char*)))
- proto_tree_add_text(subtree, NullTVB,
+ proto_tree_add_text(subtree, tvb,
offset + CMD_RAND_SEARCH_GROUP,
4,
"Group: (%u) %s", group, groups[group-1]);
else
- proto_tree_add_text(subtree, NullTVB,
+ proto_tree_add_text(subtree, tvb,
offset + CMD_RAND_SEARCH_GROUP,
4,
"Group: (%u)", group);
}
static void
-icqv5_cmd_ack_messages(proto_tree* tree,/* Tree to put the data in */
- const u_char* pd, /* Packet content */
- int offset, /* Offset from the start of the packet to the content */
- int size) /* Number of chars left to do */
+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 */
{
- guint32 random = pletohl(pd + CMD_ACK_MESSAGES_RANDOM);
proto_tree* subtree;
proto_item* ti;
if (tree){
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- 4,
- CMD_ACK_MESSAGES,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ 4,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
- proto_tree_add_text(subtree, NullTVB,
+ proto_tree_add_text(subtree, tvb,
offset + CMD_ACK_MESSAGES_RANDOM,
4,
- "Random: 0x%08x", random);
+ "Random: 0x%08x",
+ tvb_get_letohl(tvb, offset + CMD_ACK_MESSAGES_RANDOM));
}
}
static void
-icqv5_cmd_keep_alive(proto_tree* tree,/* Tree to put the data in */
- const u_char* pd, /* Packet content */
- int offset, /* Offset from the start of the packet to the content */
- int size) /* Number of chars left to do */
+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 */
{
- guint32 random = pletohl(pd + CMD_KEEP_ALIVE_RANDOM);
+ guint32 random;
proto_tree* subtree;
proto_item* ti;
if (tree){
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- 4,
- CMD_KEEP_ALIVE,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ 4,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
- proto_tree_add_text(subtree, NullTVB,
+ random = tvb_get_letohl(tvb, offset + CMD_KEEP_ALIVE_RANDOM);
+ proto_tree_add_text(subtree, tvb,
offset + CMD_KEEP_ALIVE_RANDOM,
4,
"Random: 0x%08x", random);
}
static void
-icqv5_cmd_send_text_code(proto_tree* tree,/* Tree to put the data in */
- const u_char* pd, /* Packet content */
- int offset, /* Offset from the start of the packet to the content */
- int size) /* Number of chars left to do */
+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 */
{
proto_tree* subtree = NULL;
proto_item* ti = NULL;
guint16 len = 0;
guint16 x1 = -1;
- char* text;
- int left = size; /* The amount of data left to analyse */
if (tree){
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- left,
- CMD_KEEP_ALIVE,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ size,
+ "Body");
}
- if (left<sizeof(guint16))
- return;
- len = pletohs(pd+CMD_SEND_TEXT_CODE_LEN);
- left -= sizeof(gint16);
+ len = tvb_get_letohs(tvb, offset+CMD_SEND_TEXT_CODE_LEN);
if (tree){
subtree = proto_item_add_subtree(ti, ett_icq_body);
- proto_tree_add_text(subtree, NullTVB,
+ proto_tree_add_text(subtree, tvb,
offset + CMD_SEND_TEXT_CODE_LEN,
2,
"Length: %d", len);
}
if (len>0) {
- len = MIN(len, left);
- text = g_malloc(len+1);
- memcpy(text, pd + CMD_SEND_TEXT_CODE_TEXT, len);
- text[len] = '\0';
- left -= len;
if (tree){
- proto_tree_add_text(subtree, NullTVB,
+ proto_tree_add_text(subtree, tvb,
offset + CMD_SEND_TEXT_CODE_TEXT,
len,
- "Text: %s",text);
+ "Text: %.*s",
+ len,
+ tvb_get_ptr(tvb, offset + CMD_SEND_TEXT_CODE_TEXT,
+ len));
}
- g_free(text);
}
- if (left<sizeof(gint16))
- return;
-
- x1 = pletohs(pd + size - left);
- left -= sizeof(gint16);
+ x1 = tvb_get_letohs(tvb, offset + CMD_SEND_TEXT_CODE_TEXT + len);
if (tree){
- proto_tree_add_text(subtree, NullTVB,
+ proto_tree_add_text(subtree, tvb,
offset + CMD_SEND_TEXT_CODE_TEXT + len,
2,
"X1: 0x%04x", x1);
}
static void
-icqv5_cmd_add_to_list(proto_tree* tree,/* Tree to put the data in */
- const u_char* pd, /* Packet content */
- int offset, /* Offset from the start of the packet to the content */
- int size) /* Number of chars left to do */
+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 */
{
guint32 uin = -1;
proto_tree* subtree;
proto_item* ti;
- if (size>=4)
- uin = pletohl(pd + CMD_ADD_TO_LIST);
+
if (tree){
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- 4,
- CMD_ADD_TO_LIST,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ 4,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
- proto_tree_add_text(subtree, NullTVB,
+ uin = tvb_get_letohl(tvb, offset + CMD_ADD_TO_LIST);
+ proto_tree_add_text(subtree, tvb,
offset + CMD_ADD_TO_LIST_UIN,
4,
"UIN: %u", uin);
}
static void
-icqv5_cmd_status_change(proto_tree* tree,/* Tree to put the data in */
- const u_char* pd, /* Packet content */
- int offset, /* Offset from the start of the packet to the content */
- int size) /* Number of chars left to do */
+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 */
{
- guint32 status = -1;
+ guint32 status;
proto_tree* subtree;
proto_item* ti;
- if (size >= CMD_STATUS_CHANGE_STATUS + 4)
- status = pletohl(pd + CMD_STATUS_CHANGE_STATUS);
if (tree){
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- 4,
- CMD_STATUS_CHANGE,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ 4,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
- if (status!=-1)
- proto_tree_add_text(subtree, NullTVB,
- offset + CMD_STATUS_CHANGE_STATUS,
- 4,
- "Status: %08x (%s)", status, findStatus(status));
+ status = tvb_get_letohl(tvb, offset + CMD_STATUS_CHANGE_STATUS);
+ proto_tree_add_text(subtree, tvb,
+ offset + CMD_STATUS_CHANGE_STATUS,
+ 4,
+ "Status: %s", findStatus(status));
}
}
static void
icqv5_cmd_send_msg(proto_tree* tree,
- const u_char* pd,
+ tvbuff_t *tvb,
int offset,
int size,
int cmd)
{
proto_tree* subtree;
proto_item* ti;
- guint32 receiverUIN = 0xffffffff;
- guint16 msgType = 0xffff;
- guint16 msgLen = 0xffff;
int left = size; /* left chars to do */
-
- if (left < 4)
- return;
- receiverUIN = pletohl(pd + CMD_SEND_MSG_RECV_UIN);
- left -= 4;
- if (left < 2)
- return;
- msgType = pletohs(pd + CMD_SEND_MSG_MSG_TYPE);
- left -= 2;
- if (left < 2)
- return;
- msgLen = pletohs(pd + CMD_SEND_MSG_MSG_LEN);
- left -= 2;
if (tree) {
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- size,
- cmd,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ size,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
- proto_tree_add_text(subtree, NullTVB,
+ proto_tree_add_text(subtree, tvb,
offset + CMD_SEND_MSG_RECV_UIN,
4,
- "Receiver UIN: %u", receiverUIN);
- proto_tree_add_text(subtree, NullTVB,
- offset + CMD_SEND_MSG_MSG_LEN,
- 2,
- "Length: %u", msgLen);
+ "Receiver UIN: %u",
+ tvb_get_letohl(tvb, offset + CMD_SEND_MSG_RECV_UIN));
+ left -= 4;
icqv5_decode_msgType(subtree,
- pd + CMD_SEND_MSG_MSG_TYPE,
+ tvb,
offset + CMD_SEND_MSG_MSG_TYPE,
- left+4); /* There are 4 bytes more... */
+ left);
}
}
static void
icqv5_cmd_login(proto_tree* tree,
- const u_char* pd,
+ tvbuff_t *tvb,
int offset,
int size)
{
proto_item* ti;
proto_tree* subtree;
- time_t theTime = -1;
- guint32 port = -1;
- guint32 passwdLen = -1;
- char* password = NULL;
- const u_char *ipAddrp = NULL;
- guint32 status = -1;
- guint32 left = size;
-
- if (left>=4) {
- theTime = pletohl(pd + CMD_LOGIN_TIME);
- }
- if (left>=8) {
- port = pletohl(pd + CMD_LOGIN_PORT);
- }
- if (left>=10) {
- passwdLen = pletohs(pd + CMD_LOGIN_PASSLEN);
- }
- if (left>=10+passwdLen) {
- password = g_malloc(passwdLen + 1);
- strncpy(password, pd + CMD_LOGIN_PASSWD, passwdLen);
- password[passwdLen] = '\0';
- }
+ time_t theTime;
+ char *aTime;
+ guint32 port;
+ guint32 passwdLen;
+ const u_char *ipAddrp;
+ guint32 status;
- if (left>=10+passwdLen+CMD_LOGIN_IP+4) {
- ipAddrp = pd + CMD_LOGIN_PASSWD + passwdLen + CMD_LOGIN_IP;
- }
- if (left>=10+passwdLen+CMD_LOGIN_STATUS+4) {
- status = pletohs(pd + CMD_LOGIN_PASSWD + passwdLen + CMD_LOGIN_STATUS);
- }
if (tree) {
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- size,
- CMD_SEND_MSG,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ size,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
- if (theTime!=-1) {
- char *aTime = ctime(&theTime);
-
- aTime[strlen(aTime)-1] = '\0';
- proto_tree_add_text(subtree, NullTVB,
- offset + CMD_LOGIN_TIME,
- 4,
- "Time: %ld = %s", (long)theTime, aTime);
- }
- if (port!=-1)
- proto_tree_add_text(subtree, NullTVB,
- offset + CMD_LOGIN_PORT,
- 4,
- "Port: %u", port);
- if ((passwdLen!=-1) && (password!=NULL))
- proto_tree_add_text(subtree, NullTVB,
- offset + CMD_LOGIN_PASSLEN,
- 2 + passwdLen,
- "Passwd: %s", password);
- if (ipAddrp!=NULL)
- proto_tree_add_text(subtree, NullTVB,
- offset + CMD_LOGIN_PASSWD + passwdLen + CMD_LOGIN_IP,
- 4,
- "IP: %s", ip_to_str(ipAddrp));
- if (status!=-1)
- proto_tree_add_text(subtree, NullTVB,
- offset + CMD_LOGIN_PASSWD + passwdLen + CMD_LOGIN_STATUS,
- 4,
- "Status: %s", findStatus(status));
+ 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));
}
- if (password!=NULL)
- g_free(password);
}
static void
icqv5_cmd_contact_list(proto_tree* tree,
- const u_char* pd,
+ tvbuff_t *tvb,
int offset,
int size)
{
proto_tree* subtree;
proto_item* ti;
- unsigned char num = -1;
- int i, left;
+ unsigned char num;
+ int i;
guint32 uin;
- const u_char* p = NULL;
-
- if (size >= CMD_CONTACT_LIST_NUM + 1)
- num = pd[CMD_CONTACT_LIST_NUM];
if (tree) {
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- size,
- CMD_CONTACT_LIST,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ size,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
- proto_tree_add_text(subtree, NullTVB,
+ num = tvb_get_guint8(tvb, offset + CMD_CONTACT_LIST_NUM);
+ proto_tree_add_text(subtree, tvb,
offset + CMD_CONTACT_LIST,
1,
"Number of uins: %u", num);
* A sequence of num times UIN follows
*/
offset += (CMD_CONTACT_LIST_NUM + 1);
- left = size;
- p = &pd[CMD_CONTACT_LIST_NUM + 1];
- for (i = 0; (i<num) && (left>0);i++) {
- if (left>=4) {
- uin = pletohl(p);
- proto_tree_add_text(subtree, NullTVB,
- offset,
- 4,
- "UIN[%d]: %u",i,uin);
- p += 4;
- offset += 4;
- left -= 4;
- }
+ 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;
}
}
}
static void
-icqv5_cmd_no_params(proto_tree* tree,/* Tree to put the data in */
- const u_char* pd, /* Packet content */
- int offset, /* Offset from the start of the packet to the content */
- int size, /* Number of chars left to do */
+icqv5_cmd_no_params(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 cmd)
{
proto_tree* subtree;
proto_item* ti;
if (tree){
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- 0,
- cmd,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ 0,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
- proto_tree_add_text(subtree, NullTVB,
+ proto_tree_add_text(subtree, tvb,
offset,
0,
"No parameters");
**********************
*/
static void
-icqv5_srv_no_params(proto_tree* tree,/* Tree to put the data in */
- const u_char* pd, /* Packet content */
- int offset, /* Offset from the start of the packet to the content */
- int size, /* Number of chars left to do */
+icqv5_srv_no_params(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 */
int cmd)
{
proto_tree* subtree;
proto_item* ti;
if (tree){
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- 0,
- cmd,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ 0,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
- proto_tree_add_text(subtree, NullTVB,
+ proto_tree_add_text(subtree, tvb,
offset,
0,
"No Parameters");
static void
icqv5_srv_login_reply(proto_tree* tree,/* Tree to put the data in */
- const u_char* pd, /* Packet content */
- int offset, /* Offset from the start of the packet to the content */
- int size) /* Number of chars left to do */
+ 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 */
{
proto_tree* subtree;
proto_item* ti;
- const u_char *ipAddrp = NULL;
-
- if (size >= SRV_LOGIN_REPLY_IP + 4)
- ipAddrp = &pd[SRV_LOGIN_REPLY_IP];
+ const u_char *ipAddrp;
if (tree) {
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- SRV_LOGIN_REPLY_IP + 8,
- SRV_LOGIN_REPLY,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ SRV_LOGIN_REPLY_IP + 8,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
- proto_tree_add_text(subtree, NullTVB,
+ ipAddrp = tvb_get_ptr(tvb, offset + SRV_LOGIN_REPLY_IP, 4);
+ proto_tree_add_text(subtree, tvb,
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 */
- const u_char* pd, /* Packet content */
- int offset, /* Offset from the start of the packet to the content */
- int size) /* Number of chars left to do */
+ 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 */
{
proto_tree* subtree;
proto_item* ti;
- guint32 uin = -1;
- const u_char *ipAddrp = NULL;
- guint32 port = -1;
- const u_char *realipAddrp = NULL;
- guint32 status = -1;
- guint32 version = -1;
-
- if (size >= SRV_USER_ONL_UIN + 4)
- uin = pletohl(pd + SRV_USER_ONL_UIN);
-
- if (size >= SRV_USER_ONL_IP + 4)
- ipAddrp = &pd[SRV_USER_ONL_IP];
-
- if (size >= SRV_USER_ONL_PORT + 4)
- port = pletohl(pd + SRV_USER_ONL_PORT);
-
- if (size >= SRV_USER_ONL_REALIP + 4)
- realipAddrp = &pd[SRV_USER_ONL_REALIP];
-
- if (size >= SRV_USER_ONL_STATUS + 2)
- status = pletohs(pd + SRV_USER_ONL_STATUS);
-
- /*
- * 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.
- */
- if (size >= SRV_USER_ONL_X2 + 4)
- version = pletohl(pd + SRV_USER_ONL_X2);
+ const u_char *ipAddrp;
+ const u_char *realipAddrp;
+ guint32 status;
if (tree) {
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- SRV_LOGIN_REPLY_IP + 8,
- SRV_LOGIN_REPLY,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ SRV_LOGIN_REPLY_IP + 8,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
- proto_tree_add_text(subtree, NullTVB,
+ proto_tree_add_text(subtree, tvb,
offset + SRV_USER_ONL_UIN,
4,
- "UIN: %u", uin);
- proto_tree_add_text(subtree, NullTVB,
+ "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,
offset + SRV_USER_ONL_IP,
4,
"IP: %s", ip_to_str(ipAddrp));
- proto_tree_add_text(subtree, NullTVB,
+ proto_tree_add_text(subtree, tvb,
offset + SRV_USER_ONL_PORT,
4,
- "Port: %u", port);
- proto_tree_add_text(subtree, NullTVB,
+ "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,
offset + SRV_USER_ONL_REALIP,
4,
"RealIP: %s", ip_to_str(realipAddrp));
- proto_tree_add_text(subtree, NullTVB,
+ status = tvb_get_letohs(tvb, offset + SRV_USER_ONL_STATUS);
+ proto_tree_add_text(subtree, tvb,
offset + SRV_USER_ONL_STATUS,
2,
"Status: %s", findStatus(status));
- proto_tree_add_text(subtree, NullTVB,
+ /*
+ * 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,
offset + SRV_USER_ONL_X2,
4,
- "Version: %08x", version);
+ "Version: %08x",
+ tvb_get_letohl(tvb, offset + SRV_USER_ONL_X2));
}
}
static void
icqv5_srv_user_offline(proto_tree* tree,/* Tree to put the data in */
- const u_char* pd, /* Packet content */
- int offset, /* Offset from the start of the packet to the content */
- int size) /* Number of chars left to do */
+ 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 */
{
proto_tree* subtree;
proto_item* ti;
- guint32 uin = -1;
-
- if (size >= SRV_USER_OFFLINE + 4)
- uin = pletohl(&pd[SRV_USER_OFFLINE]);
if (tree) {
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- SRV_USER_OFFLINE_UIN + 4,
- SRV_USER_OFFLINE,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ SRV_USER_OFFLINE_UIN + 4,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
- proto_tree_add_text(subtree, NullTVB,
+ proto_tree_add_text(subtree, tvb,
offset + SRV_USER_OFFLINE_UIN,
4,
- "UIN: %u", uin);
+ "UIN: %u",
+ tvb_get_letohl(tvb, offset + SRV_USER_OFFLINE));
}
}
static void
-icqv5_srv_multi(proto_tree* tree,/* Tree to put the data in */
- const u_char* pd, /* Packet content */
- int offset, /* Offset from the start of the packet to the content */
- int size, /* Number of chars left to do */
- frame_data* fd)
+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)
{
proto_tree* subtree;
proto_item* ti;
unsigned char num = -1;
guint16 pktSz;
- int i, left;
- const u_char* p = NULL;
-
- if (size >= SRV_MULTI_NUM + 1)
- num = pd[SRV_MULTI_NUM];
+ int i;
if (tree) {
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- size,
- SRV_MULTI,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ size,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
- proto_tree_add_text(subtree, NullTVB,
+ num = tvb_get_guint8(tvb, offset + SRV_MULTI_NUM);
+ proto_tree_add_text(subtree, tvb,
offset + SRV_MULTI_NUM,
1,
"Number of pkts: %u", num);
* A sequence of num times ( pktsize, packetData) follows
*/
offset += (SRV_MULTI_NUM + 1);
- left = size;
- p = &pd[SRV_MULTI_NUM + 1];
- for (i = 0; (i<num) && (left>0);i++) {
- if (left>=2) {
- pktSz = pletohs(p);
- p += 2;
- offset += 2;
- left -= 2;
- if (left>=pktSz) {
- dissect_icqv5Server(p, offset, fd, subtree, pktSz);
- p += pktSz;
- offset += pktSz;
- left -= pktSz;
- }
- }
+ for (i = 0; i < num; i++) {
+ pktSz = tvb_get_letohs(tvb, offset);
+ offset += 2;
+ dissect_icqv5Server(tvb, offset, pinfo, subtree, pktSz);
+ offset += pktSz;
}
}
}
static void
-icqv5_srv_meta_user(proto_tree* tree, /* Tree to put the data in */
- const u_char* pd, /* Packet content */
- int offset, /* Offset from the start of the packet to the content */
- int size) /* Number of chars left to do */
+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 */
{
#if 0
proto_tree* subtree = NULL;
proto_tree* sstree = NULL;
proto_item* ti = NULL;
int left = size;
- const char* p = pd;
-
- guint16 subcmd = -1;
- unsigned char result = -1;
-
- if (size>=SRV_META_USER_SUBCMD + 2)
- subcmd = pletohs(pd+SRV_META_USER_SUBCMD);
- if (size>=SRV_META_USER_RESULT + 1)
- result = pd[SRV_META_USER_RESULT];
+ guint16 subcmd;
+ unsigned char result;
if (tree) {
#if 0
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- size,
- SRV_META_USER,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ size,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
- ti = proto_tree_add_text(subtree, NullTVB,
+ subcmd = tvb_get_letohs(tvb, offset + SRV_META_USER_SUBCMD);
+ ti = proto_tree_add_text(subtree, tvb,
offset + SRV_META_USER_SUBCMD,
2,
"%s", findSubCmd(subcmd));
- proto_tree_add_text(subtree, NullTVB,
+ result = tvb_get_guint8(tvb, offset + SRV_META_USER_RESULT);
+ proto_tree_add_text(subtree, tvb,
offset + SRV_META_USER_RESULT,
1,
"%s", (result==0x0a)?"Success":"Failure");
sstree = proto_item_add_subtree(ti, ett_icq_body_parts);
#else
- ti = proto_tree_add_text(tree, NullTVB,
+ subcmd = tvb_get_letohs(tvb, offset + SRV_META_USER_SUBCMD);
+ ti = proto_tree_add_text(tree, tvb,
offset + SRV_META_USER_SUBCMD,
2,
"%s", findSubCmd(subcmd));
sstree = proto_item_add_subtree(ti, ett_icq_body_parts);
- proto_tree_add_text(sstree, NullTVB,
+ result = tvb_get_guint8(tvb, offset + SRV_META_USER_RESULT);
+ proto_tree_add_text(sstree, tvb,
offset + SRV_META_USER_RESULT,
1,
"%s", (result==0x0a)?"Success":"Failure");
/* Skip the META_USER header */
left -= 3;
- p += 3;
+ offset += 3;
switch(subcmd) {
case META_EX_USER_FOUND:
*/
guint16 pktLen = -1;
- /* Read the lenght field */
- pktLen = pletohs(p);
- proto_tree_add_text(sstree, NullTVB,
- offset + size - left,
+ /* Read the length field */
+ pktLen = tvb_get_letohs(tvb, offset);
+ proto_tree_add_text(sstree, tvb,
+ offset,
sizeof(guint16),
"Length: %u", pktLen);
- p += sizeof(guint16); left -= sizeof(guint16);
+ offset += sizeof(guint16); left -= sizeof(guint16);
}
case META_USER_FOUND:
{
*
* They are used to "implement" a poorman's exception handling
*/
- guint32 uin = -1;
int len = 0;
char *descr[] = {
"Nick",
"Email",
NULL};
char** d = descr;
- guint16 x2 = -1;
- guint32 x3 = -1;
unsigned char auth;
/*
* Read UIN
*/
- if (left<sizeof(guint32))
- break;
- uin = pletohl(p);
- proto_tree_add_text(sstree, NullTVB,
- offset + size - left,
+ proto_tree_add_text(sstree, tvb,
+ offset,
sizeof(guint32),
- "UIN: %u", uin);
- p+=sizeof(guint32);left-=sizeof(guint32);
+ "UIN: %u",
+ tvb_get_letohl(tvb, offset));
+ offset+=sizeof(guint32);left-=sizeof(guint32);
for ( ; *d!=NULL; d++) {
len = proto_add_icq_attr(sstree,
- p,
- offset + size - left,
- left,
+ tvb,
+ offset,
*d);
if (len == -1)
return;
- p += len; left -= len;
+ offset += len; left -= len;
}
/* Get the authorize setting */
- if (left<sizeof(unsigned char))
- break;
- auth = *p;
- proto_tree_add_text(sstree, NullTVB,
- offset + size - left,
- sizeof(guint16),
+ auth = tvb_get_guint8(tvb, offset);
+ proto_tree_add_text(sstree, tvb,
+ offset,
+ 1,
"authorization: %s", (auth==0x01)?"Neccessary":"Who needs it");
- p++; left--;
+ offset++; left--;
/* Get x2 */
- if (left<sizeof(guint16))
- break;
- x2 = pletohs(p);
- proto_tree_add_text(sstree, NullTVB,
- offset + size - left,
+ proto_tree_add_text(sstree, tvb,
+ offset,
sizeof(guint16),
- "x2: %04x", x2);
- p+=sizeof(guint16);left-=sizeof(guint16);
+ "x2: 0x%04x",
+ tvb_get_letohs(tvb, offset));
+ offset+=sizeof(guint16);left-=sizeof(guint16);
/* Get x3 */
- if (left<sizeof(guint32))
- break;
- x3 = pletohl(p);
- proto_tree_add_text(sstree, NullTVB,
- offset + size - left,
+ proto_tree_add_text(sstree, tvb,
+ offset,
sizeof(guint32),
- "x3: %08x", x3);
- p+=sizeof(guint32);left-=sizeof(guint32);
+ "x3: 0x%08x",
+ tvb_get_letohl(tvb, offset));
+ offset+=sizeof(guint32);left-=sizeof(guint32);
break;
}
case META_ABOUT:
{
int len;
- char* about = NULL;
+
/* Get the about information */
- if (left<sizeof(guint16))
- break;
- len = pletohs(p);
- p+=sizeof(guint16);left-=sizeof(guint16);
- if ((len<=0) || (left<len))
- break;
- about = g_malloc(len);
- strncpy(about, p, len);
- proto_tree_add_text(sstree, NullTVB,
- offset + size - left,
+ len = tvb_get_letohs(tvb, offset);
+ offset+=sizeof(guint16);left-=sizeof(guint16);
+ proto_tree_add_text(sstree, tvb,
+ offset - sizeof(guint16),
sizeof(guint16)+len,
- "About(%d): %s", len, about);
- p+=len;left-=len;
- left -= 3;
- g_free(about);
+ "About(%d): %.*s", len,
+ len, tvb_get_ptr(tvb, offset, len));
+ offset+=len;left-=len;
break;
}
case META_USER_INFO:
"Zip",
NULL};
const char** d = descr;
- char* item = NULL;
guint16 country;
unsigned char user_timezone = -1;
unsigned char auth = -1;
int len = 0;
#if 0
/* Get the uin */
- if (left<sizeof(guint32))
- break;
- uin = pletohl(p);
- proto_tree_add_text(sstree, NullTVB,
- offset + size - left,
+ uin = tvb_get_letohl(tvb, offset);
+ proto_tree_add_text(sstree, tvb,
+ offset,
sizeof(guint32),
"UIN: %u", uin);
- p+=sizeof(guint32);left-=sizeof(guint32);
+ offset+=sizeof(guint32);left-=sizeof(guint32);
#endif
/*
* Get every field from the description
*/
while ((*d)!=NULL) {
- if (left<sizeof(guint16))
- break;
- len = pletohs(p);
- p+=sizeof(guint16);left-=sizeof(guint16);
- if ((len<0) || (left<len))
- break;
+ len = tvb_get_letohs(tvb, offset);
+ offset+=sizeof(guint16);left-=sizeof(guint16);
if (len>0) {
- item = g_malloc(len);
- strncpy(item, p, len);
- proto_tree_add_text(sstree, NullTVB,
- offset + size - left - sizeof(guint16),
+ proto_tree_add_text(sstree, tvb,
+ offset - sizeof(guint16),
sizeof(guint16)+len,
- "%s(%d): %s",*d, len, item);
- g_free(item);
- p+=len;left-=len;
+ "%s(%d): %.*s",*d, len,
+ len - 1,
+ tvb_get_ptr(tvb, offset, len - 1));
+ offset+=len;left-=len;
}
d++;
}
/* Get country code */
- if (left<sizeof(guint16))
- break;
- country = pletohs(p);
- proto_tree_add_text(sstree, NullTVB,
- offset + size - left,
+ country = tvb_get_letohs(tvb, offset);
+ proto_tree_add_text(sstree, tvb,
+ offset,
sizeof(guint16),
"Countrycode: %u", country);
- p+=sizeof(guint16); left-=sizeof(guint16);
+ offset+=sizeof(guint16); left-=sizeof(guint16);
/* Get the timezone setting */
- if (left<sizeof(unsigned char))
- break;
- user_timezone = *p;
- proto_tree_add_text(sstree, NullTVB,
- offset + size - left,
+ user_timezone = tvb_get_guint8(tvb, offset);
+ proto_tree_add_text(sstree, tvb,
+ offset,
sizeof(unsigned char),
"Timezone: %u", user_timezone);
- p++; left--;
+ offset++; left--;
/* Get the authorize setting */
- if (left<sizeof(unsigned char))
- break;
- auth = *p;
- proto_tree_add_text(sstree, NullTVB,
- offset + size - left,
+ auth = tvb_get_guint8(tvb, offset);
+ proto_tree_add_text(sstree, tvb,
+ offset,
sizeof(unsigned char),
"Authorization: (%u) %s",
auth, (auth==0)?"No":"Yes");
- p++; left--;
+ offset++; left--;
/* Get the webaware setting */
- if (left<sizeof(unsigned char))
- break;
- auth = *p;
- proto_tree_add_text(sstree, NullTVB,
- offset + size - left,
+ auth = tvb_get_guint8(tvb, offset);
+ proto_tree_add_text(sstree, tvb,
+ offset,
sizeof(unsigned char),
"Webaware: (%u) %s",
auth, (auth==0)?"No":"Yes");
- p++; left--;
+ offset++; left--;
/* Get the authorize setting */
- if (left<sizeof(unsigned char))
- break;
- auth = *p;
- proto_tree_add_text(sstree, NullTVB,
- offset + size - left,
+ auth = tvb_get_guint8(tvb, offset);
+ proto_tree_add_text(sstree, tvb,
+ offset,
sizeof(unsigned char),
"HideIP: (%u) %s",
auth, (auth==0)?"No":"Yes");
- p++; left--;
+ offset++; left--;
break;
}
default:
}
static void
-icqv5_srv_recv_message(proto_tree* tree, /* Tree to put the data in */
- const u_char* pd, /* Packet content */
- int offset, /* Offset from the start of the packet to the content */
- int size) /* Number of chars left to do */
+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 */
{
proto_tree* subtree = NULL;
proto_item* ti = NULL;
unsigned char minute = -1;
if (tree) {
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- 4,
- SRV_RECV_MESSAGE,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ 4,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
- if (left>=sizeof(guint32)) {
- uin = pletohl(pd + SRV_RECV_MSG_UIN);
- proto_tree_add_uint_format(subtree,
- hf_icq_uin,
- NullTVB,
- offset + SRV_RECV_MSG_UIN,
- sizeof(guint32),
- uin,
- "UIN: %u", uin);
- left -= sizeof(guint32);
- } else
- return;
- if (left>=(sizeof(guint16)+4*sizeof(unsigned char))) {
- year = pletohs(pd + SRV_RECV_MSG_YEAR);
- month = pd[SRV_RECV_MSG_MONTH];
- day = pd[SRV_RECV_MSG_DAY];
- hour = pd[SRV_RECV_MSG_HOUR];
- minute = pd[SRV_RECV_MSG_MINUTE];
-
- proto_tree_add_text(subtree, NullTVB,
- offset + SRV_RECV_MSG_YEAR,
- sizeof(guint16) + 4*sizeof(unsigned char),
- "Time: %u-%u-%u %02u:%02u",
- day, month, year, hour, minute);
-
- left -= (sizeof(guint16)+4*sizeof(unsigned char));
- } else
- return;
+ uin = tvb_get_letohl(tvb, offset + SRV_RECV_MSG_UIN);
+ proto_tree_add_uint_format(subtree,
+ hf_icq_uin,
+ tvb,
+ offset + SRV_RECV_MSG_UIN,
+ sizeof(guint32),
+ uin,
+ "UIN: %u", uin);
+ 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);
icqv5_decode_msgType(subtree,
- pd + SRV_RECV_MSG_MSG_TYPE,
+ tvb,
offset + SRV_RECV_MSG_MSG_TYPE,
left);
}
static void
icqv5_srv_rand_user(proto_tree* tree, /* Tree to put the data in */
- const u_char* pd, /* Packet content */
- int offset, /* Offset from the start of the packet to the content */
- int size) /* Number of chars left to do */
+ tvbuff_t *tvb, /* Tvbuff with packet */
+ int offset) /* Offset from the start of the packet to the content */
{
proto_tree* subtree = NULL;
proto_item* ti = NULL;
unsigned char commClass = -1;
guint32 status;
guint16 tcpVer;
- int left = size;
if (tree) {
- ti = proto_tree_add_uint_format(tree,
- hf_icq_cmd,
- NullTVB,
- offset,
- SRV_RAND_USER_TCP_VER + 2,
- SRV_RAND_USER,
- "Body");
+ ti = proto_tree_add_text(tree,
+ tvb,
+ offset,
+ SRV_RAND_USER_TCP_VER + 2,
+ "Body");
subtree = proto_item_add_subtree(ti, ett_icq_body);
/* guint32 UIN */
- if (left<sizeof(guint32))
- return;
- uin = pletohl(pd + SRV_RAND_USER_UIN);
- proto_tree_add_text(subtree, NullTVB,
+ uin = tvb_get_letohl(tvb, offset + SRV_RAND_USER_UIN);
+ proto_tree_add_text(subtree, tvb,
offset + SRV_RAND_USER_UIN,
sizeof(guint32),
"UIN: %u", uin);
- left -= sizeof(guint32);
/* guint32 IP */
- if (left<sizeof(guint32))
- return;
- IP = pd + SRV_RAND_USER_IP;
- proto_tree_add_text(subtree, NullTVB,
+ IP = tvb_get_ptr(tvb, offset + SRV_RAND_USER_IP, 4);
+ proto_tree_add_text(subtree, tvb,
offset + SRV_RAND_USER_IP,
sizeof(guint32),
- "IP: %s", ip_to_str(IP));
- left -= sizeof(guint32);
+ "IP: %s",
+ ip_to_str(IP));
/* guint32 portNum */
- if (left<sizeof(guint32))
- return;
- port = pletohs(pd + SRV_RAND_USER_PORT);
- proto_tree_add_text(subtree, NullTVB,
+ port = tvb_get_letohs(tvb, offset + SRV_RAND_USER_PORT);
+ proto_tree_add_text(subtree, tvb,
offset + SRV_RAND_USER_UIN,
sizeof(guint32),
"Port: %u", port);
- left -= sizeof(guint32);
- /* guint32 realIP */
- if (left<sizeof(guint32))
- return;
- realIP = pd + SRV_RAND_USER_REAL_IP;
- proto_tree_add_text(subtree, NullTVB,
+ /* guint32 realIP */
+ realIP = tvb_get_ptr(tvb, offset + SRV_RAND_USER_REAL_IP, 4);
+ proto_tree_add_text(subtree, tvb,
offset + SRV_RAND_USER_REAL_IP,
sizeof(guint32),
"RealIP: %s", ip_to_str(realIP));
- left -= sizeof(guint32);
/* guit16 Communication Class */
- if (left<sizeof(unsigned char))
- return;
- commClass = pd[SRV_RAND_USER_CLASS];
- proto_tree_add_text(subtree, NullTVB,
+ commClass = tvb_get_guint8(tvb, offset + SRV_RAND_USER_CLASS);
+ proto_tree_add_text(subtree, tvb,
offset + SRV_RAND_USER_CLASS,
sizeof(unsigned char),
"Class: %s", (commClass!=4)?"User to User":"Through Server");
- left -= sizeof(unsigned char);
/* guint32 status */
- if (left<sizeof(guint32))
- return;
- status = pletohs(pd + SRV_RAND_USER_STATUS);
- proto_tree_add_text(subtree, NullTVB,
+ status = tvb_get_letohs(tvb, offset + SRV_RAND_USER_STATUS);
+ proto_tree_add_text(subtree, tvb,
offset + SRV_RAND_USER_STATUS,
sizeof(guint32),
- "Status: (%u) %s", status, findStatus(status));
+ "Status: %s", findStatus(status));
/* guint16 tcpVersion */
- if (left<sizeof(guint16))
- return;
- tcpVer = pletohs(pd + SRV_RAND_USER_TCP_VER);
- proto_tree_add_text(subtree, NullTVB,
+ tcpVer = tvb_get_letohs(tvb, offset + SRV_RAND_USER_TCP_VER);
+ proto_tree_add_text(subtree, tvb,
offset + SRV_RAND_USER_TCP_VER,
sizeof(guint16),
"TCPVersion: %u", tcpVer);
- left -= sizeof(guint16);
}
}
* Dissect all the v5 client traffic. This is encrypted, so be careful.
*/
static void
-dissect_icqv5Client(const u_char *pd,
- int offset,
- frame_data *fd,
+dissect_icqv5Client(tvbuff_t *tvb,
+ packet_info *pinfo,
proto_tree *tree)
{
proto_tree *icq_tree = NULL;
proto_tree *icq_header_tree = NULL;
- proto_tree *icq_decode_tree = NULL;
proto_item *ti = NULL;
- guint16 version = -1, cmd = -1;
- guint16 seqnum1 = 0 , seqnum2 = 0;
- guint32 uin = -1, sessionid = -1;
- guint32 key = -1;
- guint16 pktsize = -1; /* The size of the ICQ content */
- u_char decr_pd[1600]; /* Decrypted content, size should be dynamic */
+ guint16 pktsize; /* The size of the ICQ content */
+ guint32 rounded_size;
+ guint32 key;
+ guint16 cmd;
+ guint8 *decr_pd; /* Decrypted content */
+ tvbuff_t *decr_tvb;
- pktsize = END_OF_FRAME;
- /* First copy the memory, we don't want to overwrite the old content */
- memcpy(decr_pd, &pd[offset], pktsize);
- if (pktsize>0x14) {
- key = get_v5key(decr_pd, pktsize);
- decrypt_v5(decr_pd, pktsize, key);
+ pktsize = tvb_length(tvb);
+
+ /* Get the encryption key */
+ key = get_v5key(tvb, pktsize);
+
+ /*
+ * Make a copy of the packet data, and decrypt it.
+ * 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.
+ */
+ rounded_size = ((((pktsize - ICQ5_CL_SESSIONID) + 3)/4)*4) + ICQ5_CL_SESSIONID;
+ decr_pd = g_malloc(rounded_size);
+ tvb_memcpy(tvb, decr_pd, 0, pktsize);
+ decrypt_v5(decr_pd, rounded_size, key);
- /* This information only makes sense in the decrypted version */
- uin = pletohl(&decr_pd[ICQ5_CL_UIN]);
- cmd = pletohs(&decr_pd[ICQ5_CL_CMD]);
- sessionid = pletohl(&decr_pd[ICQ5_CL_SESSIONID]);
- version = pletohs(&decr_pd[ICQ_VERSION]);
- seqnum1 = pletohs(&decr_pd[ICQ5_CL_SEQNUM1]);
- seqnum2 = pletohs(&decr_pd[ICQ5_CL_SEQNUM2]);
-
- if (check_col(fd, COL_INFO))
- col_add_fstr(fd, COL_INFO, "ICQv5 %s", findClientCmd(cmd));
- }
+ /* Allocate a new tvbuff, referring to the decrypted data. */
+ decr_tvb = tvb_new_real_data(decr_pd, pktsize, tvb_reported_length(tvb));
+
+ /* Arrange that the allocated packet data copy be freed when the
+ tvbuff is freed. */
+ tvb_set_free_cb(decr_tvb, g_free);
+
+ /* 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);
+
+ /* Add the decrypted data to the data source list. */
+ add_new_data_source(pinfo->fd, decr_tvb, "Decrypted");
+
+ cmd = tvb_get_letohs(decr_tvb, ICQ5_CL_CMD);
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_add_fstr(pinfo->cinfo, COL_INFO, "ICQv5 %s", findClientCmd(cmd));
if (tree) {
ti = proto_tree_add_protocol_format(tree,
proto_icq,
- NullTVB,
- offset,
+ tvb,
+ 0,
pktsize,
"ICQv5 %s (len %u)",
findClientCmd(cmd),
icq_tree = proto_item_add_subtree(ti, ett_icq);
ti = proto_tree_add_uint_format(icq_tree,
hf_icq_type,
- NullTVB,
- offset,
+ tvb,
+ 0,
ICQ5_CL_HDRSIZE,
ICQ5_client,
"Header");
icq_header_tree = proto_item_add_subtree(ti, ett_icq_header);
- proto_tree_add_text(icq_header_tree, NullTVB,
- offset + ICQ_VERSION,
+ proto_tree_add_text(icq_header_tree, tvb,
+ ICQ_VERSION,
2,
- "Version: %u", version);
- proto_tree_add_uint_format(icq_header_tree,
- hf_icq_uin,
- NullTVB,
- offset+ICQ5_CL_UIN,
- 4,
- uin,
- "UIN: %u (0x%08X)",
- uin, uin);
+ "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);
proto_tree_add_uint_format(icq_header_tree,
- hf_icq_sessionid,
- NullTVB,
- offset+ICQ5_CL_SESSIONID,
- 4,
- sessionid,
- "Session ID: 0x%08x",
- sessionid);
- proto_tree_add_text(icq_header_tree, NullTVB,
- offset + ICQ5_CL_CMD,
+ hf_icq_client_cmd,
+ decr_tvb,
+ ICQ5_CL_CMD,
2,
- "Command: %s (%u)", findClientCmd(cmd), cmd);
- proto_tree_add_text(icq_header_tree, NullTVB,
- offset + ICQ5_CL_SEQNUM1,
+ cmd,
+ "Command: %s (%u)",
+ val_to_str(cmd, clientCmdCode, "Unknown"), cmd);
+ proto_tree_add_text(icq_header_tree, decr_tvb,
+ ICQ5_CL_SEQNUM1,
2,
- "Seq Number 1: 0x%04x", seqnum1);
- proto_tree_add_text(icq_header_tree, NullTVB,
- offset + ICQ5_CL_SEQNUM2,
+ "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,
2,
- "Seq Number 2: 0x%04x", seqnum2);
+ "Seq Number 2: 0x%04x",
+ tvb_get_letohs(decr_tvb, ICQ5_CL_SEQNUM2));
proto_tree_add_uint_format(icq_header_tree,
hf_icq_checkcode,
- NullTVB,
- offset+ICQ5_CL_CHECKCODE,
+ tvb,
+ ICQ5_CL_CHECKCODE,
4,
key,
"Key: 0x%08x",
switch(cmd) {
case CMD_ACK:
icqv5_cmd_ack(icq_tree,
- decr_pd + ICQ5_CL_HDRSIZE,
- offset + ICQ5_CL_HDRSIZE,
- pktsize - ICQ5_CL_HDRSIZE);
+ decr_tvb,
+ ICQ5_CL_HDRSIZE);
break;
case CMD_SEND_MSG:
case CMD_MSG_TO_NEW_USER:
icqv5_cmd_send_msg(icq_tree,
- decr_pd + ICQ5_CL_HDRSIZE,
- offset + ICQ5_CL_HDRSIZE,
+ decr_tvb,
+ ICQ5_CL_HDRSIZE,
pktsize - ICQ5_CL_HDRSIZE,
cmd);
break;
case CMD_RAND_SEARCH:
icqv5_cmd_rand_search(icq_tree,
- decr_pd + ICQ5_CL_HDRSIZE,
- offset + ICQ5_CL_HDRSIZE,
+ decr_tvb,
+ ICQ5_CL_HDRSIZE,
pktsize - ICQ5_CL_HDRSIZE);
break;
case CMD_LOGIN:
icqv5_cmd_login(icq_tree,
- decr_pd + ICQ5_CL_HDRSIZE,
- offset + ICQ5_CL_HDRSIZE,
+ decr_tvb,
+ ICQ5_CL_HDRSIZE,
pktsize - ICQ5_CL_HDRSIZE);
break;
case CMD_SEND_TEXT_CODE:
icqv5_cmd_send_text_code(icq_tree,
- decr_pd + ICQ5_CL_HDRSIZE,
- offset + ICQ5_CL_HDRSIZE,
+ decr_tvb,
+ ICQ5_CL_HDRSIZE,
pktsize - ICQ5_CL_HDRSIZE);
break;
case CMD_STATUS_CHANGE:
icqv5_cmd_status_change(icq_tree,
- decr_pd + ICQ5_CL_HDRSIZE,
- offset + ICQ5_CL_HDRSIZE,
- pktsize - ICQ5_CL_HDRSIZE);
+ decr_tvb,
+ ICQ5_CL_HDRSIZE);
break;
case CMD_ACK_MESSAGES:
icqv5_cmd_ack_messages(icq_tree,
- decr_pd + ICQ5_CL_HDRSIZE,
- offset + ICQ5_CL_HDRSIZE,
- pktsize - ICQ5_CL_HDRSIZE);
+ decr_tvb,
+ ICQ5_CL_HDRSIZE);
break;
case CMD_KEEP_ALIVE:
icqv5_cmd_keep_alive(icq_tree,
- decr_pd + ICQ5_CL_HDRSIZE,
- offset + ICQ5_CL_HDRSIZE,
- pktsize - ICQ5_CL_HDRSIZE);
+ decr_tvb,
+ ICQ5_CL_HDRSIZE);
break;
case CMD_ADD_TO_LIST:
icqv5_cmd_add_to_list(icq_tree,
- decr_pd + ICQ5_CL_HDRSIZE,
- offset + ICQ5_CL_HDRSIZE,
- pktsize - ICQ5_CL_HDRSIZE);
+ decr_tvb,
+ ICQ5_CL_HDRSIZE);
break;
case CMD_CONTACT_LIST:
icqv5_cmd_contact_list(icq_tree,
- decr_pd + ICQ5_CL_HDRSIZE,
- offset + ICQ5_CL_HDRSIZE,
+ decr_tvb,
+ ICQ5_CL_HDRSIZE,
pktsize - ICQ5_CL_HDRSIZE);
break;
case CMD_META_USER:
case CMD_QUERY_SERVERS:
case CMD_QUERY_ADDONS:
icqv5_cmd_no_params(icq_tree,
- decr_pd + ICQ5_CL_HDRSIZE,
- offset + ICQ5_CL_HDRSIZE,
- pktsize - ICQ5_CL_HDRSIZE,
+ decr_tvb,
+ ICQ5_CL_HDRSIZE,
cmd);
break;
default:
- proto_tree_add_uint_format(icq_tree,
- hf_icq_cmd,
- NullTVB,
- offset+ICQ5_CL_CMD,
- 2,
- cmd,
- "Command: %u (%s)",
- cmd, findClientCmd(cmd));
+ proto_tree_add_text(icq_tree,
+ decr_tvb,
+ ICQ5_CL_HDRSIZE,
+ pktsize - ICQ5_CL_HDRSIZE,
+ "Body");
fprintf(stderr,"Missing: %s\n", findClientCmd(cmd));
break;
}
- ti = proto_tree_add_text(icq_tree, NullTVB,
- offset,
- pktsize,
- "Decoded packet");
- icq_decode_tree = proto_item_add_subtree(ti,
- ett_icq_decode);
- proto_tree_add_hexdump(icq_decode_tree, offset, decr_pd, pktsize);
-
}
}
static void
-dissect_icqv5Server(const u_char *pd,
+dissect_icqv5Server(tvbuff_t *tvb,
int offset,
- frame_data *fd,
+ packet_info *pinfo,
proto_tree *tree,
- guint32 pktsize)
+ int pktsize)
{
/* Server traffic is easy, not encrypted */
proto_tree *icq_tree = NULL;
proto_tree *icq_header_tree = NULL;
proto_item *ti = NULL;
- const u_char* decr_pd;
- int changeCol = (pktsize==(guint32)-1);
+ int changeCol = (pktsize==-1);
- guint16 version, cmd;
- guint32 uin, sessionid;
- guint16 seqnum1, seqnum2;
- guint32 checkcode;
+ guint16 cmd;
- uin = pletohl(&pd[ICQ5_SRV_UIN]);
- sessionid = pletohl(&pd[ICQ5_SRV_SESSIONID]);
- cmd = pletohs(&pd[ICQ5_SRV_CMD]);
- version = pletohs(&pd[ICQ_VERSION]);
- checkcode = pletohl(&pd[ICQ5_SRV_CHECKCODE]);
- seqnum1 = pletohs(&pd[ICQ5_SRV_SEQNUM1]);
- seqnum2 = pletohs(&pd[ICQ5_SRV_SEQNUM2]);
+ cmd = tvb_get_letohs(tvb, offset + ICQ5_SRV_CMD);
+ if (changeCol && check_col(pinfo->cinfo, COL_INFO))
+ col_add_fstr(pinfo->cinfo, COL_INFO, "ICQv5 %s", findServerCmd(cmd));
+
if (pktsize == -1)
- pktsize = fd->pkt_len - offset;
- decr_pd = pd;
+ pktsize = tvb_reported_length(tvb);
- if (changeCol && check_col(fd, COL_INFO))
- col_add_fstr(fd, COL_INFO, "ICQv5 %s", findServerCmd(cmd));
-
if (tree) {
ti = proto_tree_add_protocol_format(tree,
proto_icq,
- NullTVB,
+ tvb,
offset,
pktsize,
"ICQv5 %s (len %u)",
ti = proto_tree_add_uint_format(icq_tree,
hf_icq_type,
- NullTVB,
+ tvb,
offset,
ICQ5_SRV_HDRSIZE,
ICQ5_server,
"Header");
icq_header_tree = proto_item_add_subtree(ti, ett_icq_header);
- proto_tree_add_text(icq_header_tree, NullTVB,
+ proto_tree_add_text(icq_header_tree, tvb,
offset + ICQ_VERSION,
2,
- "Version: %u", version);
+ "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);
proto_tree_add_uint_format(icq_header_tree,
- hf_icq_sessionid,
- NullTVB,
- offset+ICQ5_SRV_SESSIONID,
- 4,
- sessionid,
- "Session ID: 0x%08x",
- sessionid);
- proto_tree_add_text(icq_header_tree, NullTVB,
+ hf_icq_server_cmd,
+ tvb,
offset + ICQ5_SRV_CMD,
2,
- "Command: %s (%u)", findServerCmd(cmd), cmd);
- proto_tree_add_text(icq_header_tree, NullTVB,
+ cmd,
+ "Command: %s (%u)",
+ val_to_str(cmd, serverCmdCode, "Unknown"), cmd);
+ proto_tree_add_text(icq_header_tree, tvb,
offset + ICQ5_SRV_SEQNUM1,
2,
- "Seq Number 1: 0x%04x", seqnum1);
- proto_tree_add_text(icq_header_tree, NullTVB,
+ "Seq Number 1: 0x%04x",
+ tvb_get_letohs(tvb, offset + ICQ5_SRV_SEQNUM1));
+ proto_tree_add_text(icq_header_tree, tvb,
offset + ICQ5_SRV_SEQNUM2,
2,
- "Seq Number 2: 0x%04x", seqnum2);
- proto_tree_add_uint_format(icq_header_tree,
- hf_icq_uin,
- NullTVB,
- offset+ICQ5_SRV_UIN,
- 4,
- uin,
- "UIN: %u",
- uin);
- proto_tree_add_uint_format(icq_header_tree,
- hf_icq_checkcode,
- NullTVB,
- offset+ICQ5_SRV_CHECKCODE,
- 4,
- checkcode,
- "Checkcode: 0x%08x",
- checkcode);
+ "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);
switch (cmd) {
case SRV_RAND_USER:
icqv5_srv_rand_user(icq_tree,
- decr_pd + ICQ5_SRV_HDRSIZE,
- offset + ICQ5_SRV_HDRSIZE,
- pktsize - ICQ5_SRV_HDRSIZE);
+ tvb,
+ offset + ICQ5_SRV_HDRSIZE);
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,
- decr_pd + ICQ5_SRV_HDRSIZE,
+ tvb,
offset + ICQ5_SRV_HDRSIZE,
pktsize - ICQ5_SRV_HDRSIZE,
cmd);
break;
case SRV_USER_ONLINE:
icqv5_srv_user_online(icq_tree,
- decr_pd + ICQ5_SRV_HDRSIZE,
+ tvb,
offset + ICQ5_SRV_HDRSIZE,
pktsize - ICQ5_SRV_HDRSIZE);
break;
case SRV_USER_OFFLINE:
icqv5_srv_user_offline(icq_tree,
- decr_pd + ICQ5_SRV_HDRSIZE,
+ tvb,
offset + ICQ5_SRV_HDRSIZE,
pktsize - ICQ5_SRV_HDRSIZE);
break;
case SRV_LOGIN_REPLY:
icqv5_srv_login_reply(icq_tree,
- decr_pd + ICQ5_SRV_HDRSIZE,
+ tvb,
offset + ICQ5_SRV_HDRSIZE,
pktsize - ICQ5_SRV_HDRSIZE);
break;
case SRV_META_USER:
icqv5_srv_meta_user(icq_tree,
- decr_pd + ICQ5_SRV_HDRSIZE,
+ tvb,
offset + ICQ5_SRV_HDRSIZE,
pktsize - ICQ5_SRV_HDRSIZE);
break;
case SRV_RECV_MESSAGE:
icqv5_srv_recv_message(icq_tree,
- decr_pd + ICQ5_SRV_HDRSIZE,
+ tvb,
offset + ICQ5_SRV_HDRSIZE,
pktsize - ICQ5_SRV_HDRSIZE);
break;
case SRV_MULTI:
icqv5_srv_multi(icq_tree,
- decr_pd + ICQ5_SRV_HDRSIZE,
+ tvb,
offset + ICQ5_SRV_HDRSIZE,
pktsize - ICQ5_SRV_HDRSIZE,
- fd);
+ pinfo);
break;
case SRV_ACK:
case SRV_SILENT_TOO_LONG:
case SRV_BAD_PASS:
case SRV_UPDATE_SUCCESS:
icqv5_srv_no_params(icq_tree,
- decr_pd + ICQ5_SRV_HDRSIZE,
+ tvb,
offset + ICQ5_SRV_HDRSIZE,
pktsize - ICQ5_SRV_HDRSIZE,
cmd);
break;
default:
- proto_tree_add_uint_format(icq_tree,
- hf_icq_cmd,
- NullTVB,
- offset + ICQ5_SRV_CMD,
- 2,
- cmd,
- "Command: %u (%s)",
- cmd, findServerCmd(cmd));
+ proto_tree_add_text(icq_tree,
+ tvb,
+ offset + ICQ5_SRV_HDRSIZE,
+ pktsize - ICQ5_SRV_HDRSIZE,
+ "Body");
fprintf(stderr,"Missing: %s\n", findServerCmd(cmd));
break;
}
}
}
-static void dissect_icqv5(const u_char *pd,
- int offset,
- frame_data *fd,
+static void dissect_icqv5(tvbuff_t *tvb,
+ packet_info *pinfo,
proto_tree *tree)
{
- guint32 unknown = pletohl(&pd[offset + ICQ5_UNKNOWN]);
+ guint32 unknown;
- if (check_col(fd, COL_PROTOCOL))
- col_add_str(fd, COL_PROTOCOL, "ICQv5 (UDP)");
- if (check_col(fd, COL_INFO))
- col_add_str(fd, COL_INFO, "ICQv5 packet");
+ 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");
+
+ unknown = tvb_get_letohl(tvb, ICQ5_UNKNOWN);
+
if (unknown == 0x0L) {
- dissect_icqv5Client(pd, offset, fd, tree);
+ dissect_icqv5Client(tvb, pinfo, tree);
} else {
- dissect_icqv5Server(pd + offset, offset, fd, tree, (guint32) -1);
+ dissect_icqv5Server(tvb, 0, pinfo, tree, -1);
}
}
-static void dissect_icq(const u_char *pd,
- int offset,
- frame_data *fd,
+static void dissect_icq(tvbuff_t *tvb,
+ packet_info *pinfo,
proto_tree *tree)
{
- int version = 0;
+ int version;
- version = pletohs(&pd[offset + ICQ_VERSION]);
+ if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICQ");
+ }
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_clear(pinfo->cinfo, COL_INFO);
+ }
+
+ version = tvb_get_letohs(tvb, ICQ_VERSION);
switch (version) {
case 0x0005:
- dissect_icqv5(pd, offset, fd, tree);
+ dissect_icqv5(tvb, pinfo, tree);
break;
case 0x0004:
- dissect_icqv4(pd, offset, fd, tree);
+ dissect_icqv4(tvb, pinfo, tree);
break;
case 0x0003:
- dissect_icqv3(pd, offset, fd, tree);
+ dissect_icqv3(tvb, pinfo, tree);
break;
case 0x0002:
- dissect_icqv2(pd, offset, fd, tree);
+ dissect_icqv2(tvb, pinfo, tree);
break;
default:
fprintf(stderr, "ICQ: Unknown version (%d)\n", version);
{
static hf_register_info hf[] = {
{ &hf_icq_type,
- {"Type", "icq.type", FT_UINT16, BASE_DEC, NULL, 0x0, ""}},
+ {"Type", "icq.type", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
{ &hf_icq_uin,
- {"UIN", "icq.uin", FT_UINT32, BASE_DEC, NULL, 0x0, ""}},
+ {"UIN", "icq.uin", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
{ &hf_icq_sessionid,
- {"SessionID", "icq.sessionid", FT_UINT32, BASE_HEX, NULL, 0x0, ""}},
- { &hf_icq_cmd,
- {"Command", "icq.cmd", FT_UINT16, BASE_DEC, NULL, 0x0, ""}},
+ {"Session ID", "icq.sessionid", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &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 }},
{ &hf_icq_checkcode,
- {"Checkcode", "icq.checkcode", FT_UINT32, BASE_HEX, NULL, 0x0, ""}},
+ {"Checkcode", "icq.checkcode", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
{ &hf_icq_decode,
- {"Decode", "icq.decode", FT_STRING, BASE_NONE, NULL, 0x0, ""}}
+ {"Decode", "icq.decode", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}
};
static gint *ett[] = {
&ett_icq,
&ett_icq_body_parts,
};
- proto_icq = proto_register_protocol ("ICQ Protocol", "icq");
+ proto_icq = proto_register_protocol("ICQ Protocol", "ICQ", "icq");
proto_register_field_array(proto_icq, hf, array_length(hf));
void
proto_reg_handoff_icq(void)
{
- dissector_add("udp.port", UDP_PORT_ICQ, dissect_icq);
+ dissector_handle_t icq_handle;
+
+ icq_handle = create_dissector_handle(dissect_icq, proto_icq);
+ dissector_add("udp.port", UDP_PORT_ICQ, icq_handle);
}