Ethereal-dev: [ethereal-dev] Packet-icq.c update
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Kojak <kojak@xxxxxxxxxx>
Date: Thu, 04 Nov 1999 22:57:17 +0100
Hi, I've updated and extended the ICQ decoder a lot further. Included in this message is the diff, I hope it can be applied... Grtz -- Kojak Index: packet-icq.c =================================================================== RCS file: /cvsroot/ethereal/packet-icq.c,v retrieving revision 1.4 diff -c -r1.4 packet-icq.c *** packet-icq.c 1999/11/03 06:21:35 1.4 --- packet-icq.c 1999/11/04 21:51:43 *************** *** 74,80 **** --- 74,95 ---- int hf_icq_sessionid =-1; int hf_icq_checkcode =-1; int hf_icq_decode = -1; + int hf_icq_type = -1; + enum { ICQ5_client, ICQ5_server}; + + void dissect_icqv5(const u_char *pd, + int offset, + frame_data *fd, + proto_tree *tree); + + static void + dissect_icqv5Server(const u_char *pd, + int offset, + frame_data *fd, + proto_tree *tree, + guint32 pktsize); + /* Offsets of fields in the ICQ headers */ /* Can be 0x0002 or 0x0005 */ #define ICQ_VERSION 0x00 *************** *** 105,124 **** int code; } cmdcode; cmdcode serverCmdCode[] = { ! { "SRV_ACK", 10 }, ! { "SRV_GO_AWAY", 40 }, ! { "SRV_NEW_UIN", 70 }, ! { "SRV_LOGIN_REPLY", 90 }, ! { "SRV_BAD_PASS", 100 }, ! { "SRV_USER_ONLINE", 110 }, ! { "SRV_USER_OFFLINE", 120 }, { "SRV_QUERY", 130 }, { "SRV_USER_FOUND", 140 }, { "SRV_END_OF_SEARCH", 160 }, { "SRV_NEW_USER", 180 }, { "SRV_UPDATE_EXT", 200 }, ! { "SRV_RECV_MESSAGE", 220 }, { "SRV_X2", 230 }, { "SRV_NOT_CONNECTED", 240 }, { "SRV_TRY_AGAIN", 250 }, --- 120,199 ---- int code; } cmdcode; + #define SRV_ACK 0x000a + + #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 + #define SRV_USER_ONL_STATUS 0x0011 + #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 + */ + #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 + + cmdcode serverMetaSubCmdCode[] = { + { "META_USER_FOUND", META_USER_FOUND }, + { "META_ABOUT", META_ABOUT }, + { "META_USER_INFO", META_USER_INFO }, + { NULL, -1 } + }; + cmdcode serverCmdCode[] = { ! { "SRV_ACK", SRV_ACK }, ! { "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_X2", 230 }, { "SRV_NOT_CONNECTED", 240 }, { "SRV_TRY_AGAIN", 250 }, *************** *** 127,140 **** { "SRV_EXT_INFO_REPLY", 290 }, { "SRV_STATUS_UPDATE", 420 }, { "SRV_SYSTEM_MESSAGE", 450 }, ! { "SRV_UPDATE_SUCCESS", 480 }, ! { "SRV_UPDATE_FAIL", 490 }, { "SRV_AUTH_UPDATE", 500 }, ! { "SRV_MULTI_PACKET", 530 }, { "SRV_X1", 540 }, { "SRV_RAND_USER", 590 }, ! { "SRV_META_USER", 990 }, ! { NULL, 0 } }; #define MSG_TEXT 0x0001 --- 202,215 ---- { "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_X1", 540 }, { "SRV_RAND_USER", 590 }, ! { "SRV_META_USER", SRV_META_USER }, ! { NULL, -1 } }; #define MSG_TEXT 0x0001 *************** *** 142,147 **** --- 217,223 ---- #define MSG_AUTH_REQ 0x0006 #define MSG_AUTH 0x0008 #define MSG_USER_ADDED 0x000c + #define MSG_EMAIL 0x000e #define MSG_CONTACTS 0x0013 #define STATUS_ONLINE 0x00000000 *************** *** 176,188 **** --- 252,296 ---- #define CMD_LOGIN_IP 0x0004 #define CMD_LOGIN_STATUS 0x0009 + #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 + + #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 + 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} }; *************** *** 202,214 **** { "CMD_ACK", CMD_ACK }, { "CMD_SEND_MESSAGE", CMD_SEND_MSG }, { "CMD_LOGIN", CMD_LOGIN }, ! { "CMD_REG_NEW_USER", 1020 }, { "CMD_CONTACT_LIST", 1030 }, { "CMD_SEARCH_UIN", 1050 }, { "CMD_SEARCH_USER", 1060 }, { "CMD_KEEP_ALIVE", 1070 }, ! { "CMD_SEND_TEXT_CODE", 1080 }, ! { "CMD_ACK_MESSAGES", 1090 }, { "CMD_LOGIN_1", 1100 }, { "CMD_MSG_TO_NEW_USER", 1110 }, { "CMD_INFO_REQ", 1120 }, --- 310,322 ---- { "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", 1110 }, { "CMD_INFO_REQ", 1120 }, *************** *** 216,233 **** { "CMD_CHANGE_PW", 1180 }, { "CMD_NEW_USER_INFO", 1190 }, { "CMD_UPDATE_EXT_INFO", 1200 }, ! { "CMD_QUERY_SERVERS", 1210 }, ! { "CMD_QUERY_ADDONS", 1220 }, ! { "CMD_STATUS_CHANGE", 1240 }, { "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", 1340 }, { "CMD_RAND_SET", 1380 }, ! { "CMD_RAND_SEARCH", 1390 }, ! { "CMD_META_USER", 1610 }, { "CMD_INVIS_LIST", 1700 }, { "CMD_VIS_LIST", 1710 }, { "CMD_UPDATE_LIST", 1720 }, --- 324,341 ---- { "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 }, *************** *** 278,283 **** --- 386,397 ---- } static char* + findSubCmd(int num) + { + return findcmd(serverMetaSubCmdCode, num); + }; + + static char* findClientCmd(int num) { return findcmd(clientCmdCode, num); *************** *** 447,453 **** --- 561,815 ---- return p; } + static void + icqv5_decode_msgType(proto_tree* tree, + const unsigned char* pd, /* From start of messageType */ + 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[] = { + "Nickname", + "First name", + "Last name", + "Email address", + "Reason"}; + static char* emain_field_descr[] = { + "Nickname", + "First name", + "Last name", + "Email address", + "Unknown", + "Text\n" + }; + + 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, + offset , + 2, + "Type: %d (%s)", msgType, findMsgType(msgType)); + /* Create a new subtree */ + subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY_PARTS); + + switch(msgType) { + case 0xffff: /* Field unknown */ + break; + default: + fprintf(stderr, "Unknown msgType: %d (%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, + offset + OFF_MSG_TEXT, + left, + "Msg: %s", msgText); + g_free(msgText); + 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; + } + 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, + 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, + 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, + offset + OFF_MSG_TEXT + j, + i - j - 1, + "%s: %s", emain_field_descr[n], msgText); + } else { + proto_tree_add_text(subtree, + offset + OFF_MSG_TEXT + j, + 0, + "%s: %s", emain_field_descr[n], "(empty)"); + } + j = ++i; + } + 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, + offset + OFF_MSG_LEN, + 1, + "Authorization: (%d) %s",auth_suc, + (auth_suc==0)?"Denied":"Allowed"); + proto_tree_add_text(subtree, + offset + OFF_MSG_LEN + 1, + sizeof(guint16), + "x1: 0x%04x",x1); + break; + } + case MSG_AUTH_REQ: + /* Five parts, separated by FE */ + i = 0; + j = 0; + msgText = NULL; + for (n = 0; n < 5; n++) { + for (; + (i<left) && (pd[OFF_MSG_TEXT+i]!=0xfe); + i++) + ; + 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, + offset + OFF_MSG_TEXT + j, + i - j - 1, + "%s: %s", auth_req_field_descr[n], msgText); + j = ++i; + } + if (msgText != NULL) + g_free(msgText); + 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; n++) { + for (; + (i<left) && (pd[OFF_MSG_TEXT+i]!=0xfe); + i++) + ; + msgText = g_realloc(msgText, i-j+1); + strncpy(msgText, pd + OFF_MSG_TEXT + j, i - j); + msgText[i-j] = '\0'; + proto_tree_add_text(subtree, + offset + OFF_MSG_TEXT + j, + i - j, + "%s: %s", auth_req_field_descr[n], msgText); + j = ++i; + } + if (msgText != NULL) + g_free(msgText); + break; + case MSG_CONTACTS: + { + u_char* p = (u_char*) &pd[OFF_MSG_TEXT]; + u_char* pprev = p; + 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 + sz = left; + msgText = g_realloc(msgText, sz+1); + strncpy(msgText, pprev, sz); + msgText[sz] = '\0'; + + if (n == 0) { + /* The first element is the number of Nick/UIN pairs follow */ + proto_tree_add_text(subtree, + offset + OFF_MSG_TEXT + done, + sz, + "Number of pairs: %s", msgText); + n++; + } else if (p!=NULL) { + int svsz = sz; + left -= (sz+1); + pprev = p + 1; + p = strnchr(pprev, 0xfe, left); + if (p!=NULL) + sz = (int)(p - pprev); + else + sz = left; + msgText2 = g_malloc(sz+1); + strncpy(msgText2, pprev, sz); + msgText2[sz] = '\0'; + + proto_tree_add_text(subtree, + offset + OFF_MSG_TEXT + done, + sz + svsz + 2, + "%s:%s", msgText, msgText2); + n+=2; + g_free(msgText2); + } + + left -= (sz+1); + pprev = p+1; + } + if (msgText != NULL) + g_free(msgText); + break; + }} + } + + /********************************* + * + * Client commands + * + *********************************/ + 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 */ *************** *** 463,472 **** offset, 4, CMD_ACK, ! "%s : %d", ! findClientCmd(CMD_ACK), ! CMD_ACK); ! subtree = proto_item_add_subtree(ti, ETT_ICQ_SUBTREE); proto_tree_add_text(subtree, offset + CMD_ACK_RANDOM, 4, --- 825,832 ---- offset, 4, CMD_ACK, ! "Body"); ! subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); proto_tree_add_text(subtree, offset + CMD_ACK_RANDOM, 4, *************** *** 475,480 **** --- 835,1041 ---- } 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 */ + { + guint16 group = pletohs(pd + CMD_RAND_SEARCH_GROUP); + 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){ + ti = proto_tree_add_item_format(tree, + hf_icq_cmd, + offset, + 4, + CMD_RAND_SEARCH, + "Body"); + subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); + if (group>0 && (group<=sizeof(groups)/sizeof(const char*))) + proto_tree_add_text(subtree, + offset + CMD_RAND_SEARCH_GROUP, + 4, + "Group: (%d) %s", group, groups[group-1]); + else + proto_tree_add_text(subtree, + offset + CMD_RAND_SEARCH_GROUP, + 4, + "Group: (%d)", 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 */ + { + guint32 random = pletohl(pd + CMD_ACK_MESSAGES_RANDOM); + proto_tree* subtree; + proto_item* ti; + + if (tree){ + ti = proto_tree_add_item_format(tree, + hf_icq_cmd, + offset, + 4, + CMD_ACK_MESSAGES, + "Body"); + subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); + proto_tree_add_text(subtree, + offset + CMD_ACK_MESSAGES_RANDOM, + 4, + "Random: 0x%08lx", 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 */ + { + guint32 random = pletohl(pd + CMD_KEEP_ALIVE_RANDOM); + proto_tree* subtree; + proto_item* ti; + + if (tree){ + ti = proto_tree_add_item_format(tree, + hf_icq_cmd, + offset, + 4, + CMD_KEEP_ALIVE, + "Body"); + subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); + proto_tree_add_text(subtree, + offset + CMD_KEEP_ALIVE_RANDOM, + 4, + "Random: 0x%08lx", 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 */ + { + proto_tree* subtree; + proto_item* ti; + gint16 len = -1; + guint16 x1 = -1; + char* text = NULL; + int left = size; /* The amount of data left to analyse */ + + if (left>=sizeof(gint16)) { + len = pletohs(pd+CMD_SEND_TEXT_CODE_LEN); + left -= sizeof(gint16); + } + 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 (left>=sizeof(gint16)) { + x1 = pletohs(pd + size - left); + left -= sizeof(gint16); + } + if (tree){ + ti = proto_tree_add_item_format(tree, + hf_icq_cmd, + offset, + left, + CMD_KEEP_ALIVE, + "Body"); + subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); + proto_tree_add_text(subtree, + offset + CMD_SEND_TEXT_CODE_LEN, + 2, + "Length: %d", len); + proto_tree_add_text(subtree, + offset + CMD_SEND_TEXT_CODE_TEXT, + len, + "Text: %s",text); + proto_tree_add_text(subtree, + offset + CMD_SEND_TEXT_CODE_TEXT + len, + 2, + "X1: 0x%04x", x1); + } + if (text!=NULL) + g_free(text); + } + + 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 */ + { + 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_item_format(tree, + hf_icq_cmd, + offset, + 4, + CMD_ADD_TO_LIST, + "Body"); + subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); + proto_tree_add_text(subtree, + offset + CMD_ADD_TO_LIST_UIN, + 4, + "UIN: %ld", 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 */ + { + guint32 status = -1; + 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_item_format(tree, + hf_icq_cmd, + offset, + 4, + "Body"); + subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); + if (status!=-1) + proto_tree_add_text(subtree, + offset + CMD_STATUS_CHANGE_STATUS, + 4, + "Status: %08x (%s)", status, findStatus(status)); + } + } + + static void icqv5_cmd_send_msg(proto_tree* tree, const u_char* pd, int offset, *************** *** 485,499 **** guint32 receiverUIN = 0xffffffff; guint16 msgType = 0xffff; guint16 msgLen = 0xffff; - u_char* msgText = NULL; int left = size; /* left chars to do */ - int i,n,j; - static char* auth_req_field_descr[] = { - "Nickname", - "First name", - "Last name", - "Email address", - "Reason"}; if (left >= 4) { receiverUIN = pletohl(pd + CMD_SEND_MSG_RECV_UIN); --- 1046,1052 ---- *************** *** 514,684 **** size, CMD_SEND_MSG, "Body"); ! subtree = proto_item_add_subtree(ti, ETT_ICQ_SUBTREE); proto_tree_add_text(subtree, offset + CMD_SEND_MSG_RECV_UIN, 4, "Receiver UIN: %ld", receiverUIN); - ti = proto_tree_add_text(subtree, - offset + CMD_SEND_MSG_MSG_TYPE, - 2, - "Type: %d (%s)", msgType, findMsgType(msgType)); proto_tree_add_text(subtree, offset + CMD_SEND_MSG_MSG_LEN, 2, "Length: %d", msgLen); ! /* It's silly to do anything if there's nothing left */ ! if (left==0) ! return; ! if (msgLen == 0) ! return; ! /* Create a subtree for every message type */ ! switch(msgType) { ! case 0xffff: /* Field unknown */ ! break; ! case MSG_TEXT: ! msgText = g_malloc(left + 1); ! strncpy(msgText, pd + CMD_SEND_MSG_MSG_TEXT, left); ! msgText[left] = '\0'; ! proto_tree_add_text(subtree, ! offset + CMD_SEND_MSG_MSG_TEXT, ! left, ! "Msg: %s", msgText); ! g_free(msgText); ! break; ! case MSG_URL: ! /* Two parts, a description and the URL. Separeted by FE */ ! for (i=0;i<left;i++) { ! if (pd[CMD_SEND_MSG_MSG_TEXT + i] == 0xfe) ! break; ! } ! msgText = g_malloc(i + 1); ! strncpy(msgText, pd + CMD_SEND_MSG_MSG_TEXT, i); ! if (i==left) ! msgText[i] = '\0'; ! else ! msgText[i-1] = '\0'; ! proto_tree_add_text(subtree, ! offset + CMD_SEND_MSG_MSG_TEXT, ! i, ! "Description: %s", msgText); ! if (i==left) ! break; ! msgText = g_realloc(msgText, left - i); ! strncpy(msgText, pd + CMD_SEND_MSG_MSG_TEXT + i + 1, left - i - 1); ! msgText[left - i] = '\0'; ! proto_tree_add_text(subtree, ! offset + CMD_SEND_MSG_MSG_TEXT, ! i, ! "URL: %s", msgText); ! g_free(msgText); ! break; ! case MSG_AUTH_REQ: ! /* Five parts, separated by FE */ ! i = 0; ! j = 0; ! msgText = NULL; ! for (n = 0; n < 5; n++) { ! for (; ! (i<left) && (pd[CMD_SEND_MSG_MSG_TEXT+i]!=0xfe); ! i++) ! ; ! msgText = g_realloc(msgText, i-j); ! strncpy(msgText, pd + CMD_SEND_MSG_MSG_TEXT + j, i - j - 1); ! msgText[i-j-1] = '\0'; ! proto_tree_add_text(subtree, ! offset + CMD_SEND_MSG_MSG_TEXT + j, ! i - j - 1, ! "%s: %s", auth_req_field_descr[n], msgText); ! j = ++i; ! } ! if (msgText != NULL) ! g_free(msgText); ! break; ! case MSG_USER_ADDED: ! /* Create a new subtree */ ! subtree = proto_item_add_subtree(ti, ETT_ICQ_SUBTREE); ! /* 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; n++) { ! for (; ! (i<left) && (pd[CMD_SEND_MSG_MSG_TEXT+i]!=0xfe); ! i++) ! ; ! msgText = g_realloc(msgText, i-j+1); ! strncpy(msgText, pd + CMD_SEND_MSG_MSG_TEXT + j, i - j); ! msgText[i-j] = '\0'; ! proto_tree_add_text(subtree, ! offset + CMD_SEND_MSG_MSG_TEXT + j, ! i - j, ! "%s: %s", auth_req_field_descr[n], msgText); ! j = ++i; ! } ! if (msgText != NULL) ! g_free(msgText); ! break; ! case MSG_CONTACTS: ! { ! u_char* p = (u_char*) &pd[CMD_SEND_MSG_MSG_TEXT]; ! u_char* pprev = p; ! 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_SUBTREE); ! while (p!=NULL) { ! p = strnchr(pprev, 0xfe, left); ! ! if (p!=NULL) ! sz = (int)(p - pprev); ! else ! sz = left; ! msgText = g_realloc(msgText, sz+1); ! strncpy(msgText, pprev, sz); ! msgText[sz] = '\0'; ! ! if (n == 0) { ! /* The first element is the number of Nick/UIN pairs follow */ ! proto_tree_add_text(subtree, ! offset + CMD_SEND_MSG_MSG_TEXT + done, ! sz, ! "Number of pairs: %s", msgText); ! n++; ! } else if (p!=NULL) { ! int svsz = sz; ! left -= (sz+1); ! pprev = p + 1; ! p = strnchr(pprev, 0xfe, left); ! if (p!=NULL) ! sz = (int)(p - pprev); ! else ! sz = left; ! msgText2 = g_malloc(sz+1); ! strncpy(msgText2, pprev, sz); ! msgText2[sz] = '\0'; ! ! proto_tree_add_text(subtree, ! offset + CMD_SEND_MSG_MSG_TEXT + done, ! sz + svsz + 2, ! "%s:%s", msgText, msgText2); ! n+=2; ! g_free(msgText2); ! } ! ! left -= (sz+1); ! pprev = p+1; ! } ! if (msgText != NULL) ! g_free(msgText); ! break; ! }} } } --- 1067,1086 ---- size, CMD_SEND_MSG, "Body"); ! subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); proto_tree_add_text(subtree, offset + CMD_SEND_MSG_RECV_UIN, 4, "Receiver UIN: %ld", receiverUIN); proto_tree_add_text(subtree, offset + CMD_SEND_MSG_MSG_LEN, 2, "Length: %d", msgLen); ! icqv5_decode_msgType(subtree, ! pd + CMD_SEND_MSG_MSG_TYPE, ! offset + CMD_SEND_MSG_MSG_TYPE, ! left+4); /* There are 4 bytes more... */ } } *************** *** 726,732 **** size, CMD_SEND_MSG, "Body"); ! subtree = proto_item_add_subtree(ti, ETT_ICQ_SUBTREE); if (theTime!=-1) proto_tree_add_text(subtree, offset + CMD_LOGIN_TIME, --- 1128,1134 ---- size, CMD_SEND_MSG, "Body"); ! subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); if (theTime!=-1) proto_tree_add_text(subtree, offset + CMD_LOGIN_TIME, *************** *** 757,762 **** --- 1159,1817 ---- g_free(password); } + static void + icqv5_cmd_contact_list(proto_tree* tree, + const u_char* pd, + int offset, + int size) + { + proto_tree* subtree; + proto_item* ti; + unsigned char num = -1; + int i, left; + 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_item_format(tree, + hf_icq_cmd, + offset, + size, + CMD_CONTACT_LIST, + "Body"); + subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); + proto_tree_add_text(subtree, + offset + CMD_CONTACT_LIST, + 1, + "Number of uins: %d", 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, + offset, + 4, + "UIN[%d]: %ld",i,uin); + p += 4; + offset += 4; + left -= 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 */ + int cmd) + { + proto_tree* subtree; + proto_item* ti; + + if (tree){ + ti = proto_tree_add_item_format(tree, + hf_icq_cmd, + offset, + 0, + cmd, + "Body"); + subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); + proto_tree_add_text(subtree, + offset, + 0, + "No parameters"); + } + } + + /********************** + * + * Server commands + * + ********************** + */ + 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 */ + int cmd) + { + proto_tree* subtree; + proto_item* ti; + + if (tree){ + ti = proto_tree_add_item_format(tree, + hf_icq_cmd, + offset, + 0, + cmd, + "Body"); + subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); + proto_tree_add_text(subtree, + 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 */ + { + proto_tree* subtree; + proto_item* ti; + const u_char *ipAddrp = NULL; + + if (size >= SRV_LOGIN_REPLY_IP + 4) + ipAddrp = &pd[SRV_LOGIN_REPLY_IP]; + + if (tree) { + ti = proto_tree_add_item_format(tree, + hf_icq_cmd, + offset, + SRV_LOGIN_REPLY_IP + 8, + SRV_LOGIN_REPLY, + "Body"); + subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); + proto_tree_add_text(subtree, + 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 */ + { + 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 + 4) + status = pletohl(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); + + if (tree) { + ti = proto_tree_add_item_format(tree, + hf_icq_cmd, + offset, + SRV_LOGIN_REPLY_IP + 8, + SRV_LOGIN_REPLY, + "Body"); + subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); + proto_tree_add_text(subtree, + offset + SRV_USER_ONL_UIN, + 4, + "UIN: %d", uin); + proto_tree_add_text(subtree, + offset + SRV_USER_ONL_IP, + 4, + "IP: %s", ip_to_str(ipAddrp)); + proto_tree_add_text(subtree, + offset + SRV_USER_ONL_PORT, + 4, + "Port: %d", port); + proto_tree_add_text(subtree, + offset + SRV_USER_ONL_REALIP, + 4, + "RealIP: %s", ip_to_str(realipAddrp)); + proto_tree_add_text(subtree, + offset + SRV_USER_ONL_STATUS, + 4, + "Status: %s", findStatus(status)); + proto_tree_add_text(subtree, + offset + SRV_USER_ONL_X2, + 4, + "Version: %08x", version); + } + } + + 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 */ + { + 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_item_format(tree, + hf_icq_cmd, + offset, + SRV_USER_OFFLINE_UIN + 4, + SRV_USER_OFFLINE, + "Body"); + subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); + proto_tree_add_text(subtree, + offset + SRV_USER_OFFLINE_UIN, + 4, + "UIN: %d", uin); + } + } + + 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) + { + 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]; + + if (tree) { + ti = proto_tree_add_item_format(tree, + hf_icq_cmd, + offset, + size, + SRV_MULTI, + "Body"); + subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); + proto_tree_add_text(subtree, + offset + SRV_MULTI_NUM, + 1, + "Number of pkts: %d", 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; + } + } + } + } + } + + 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 */ + { + proto_tree* subtree = 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]; + + if (tree) { + ti = proto_tree_add_item_format(tree, + hf_icq_cmd, + offset, + size, + SRV_META_USER, + "Body"); + subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); + ti = proto_tree_add_text(subtree, + offset + SRV_META_USER_SUBCMD, + 2, + "%s", findSubCmd(subcmd)); + proto_tree_add_text(subtree, + offset + SRV_META_USER_RESULT, + 1, + "%s", (result==0x0a)?"Success":"Failure"); + switch(subcmd) { + 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 + */ + guint32 uin = -1; + char* nick = NULL; /* Nick */ + char* first = NULL; /* First name */ + char* last = NULL; /* Last name */ + char* email = NULL; + unsigned char auth = -1; + int len = 0; + guint16 x2 = -1; + guint32 x3 = -1; + proto_tree* sstree = proto_item_add_subtree(ti, ETT_ICQ_BODY_PARTS); + + /* Skip over META_USER header */ + left -= 3; + p += 3; + /* Get the uin */ + if (left<sizeof(guint32)) + goto stopMetaUser; + uin = pletohl(p); + proto_tree_add_text(sstree, + offset + size - left, + sizeof(guint32), + "UIN: %ld", uin); + p+=sizeof(guint32);left-=sizeof(guint32); + /* Get the nickname */ + if (left<sizeof(guint16)) + goto stopMetaUser; + len = pletohs(p); + p+=sizeof(guint16);left-=sizeof(guint16); + if ((len<=0) || (left<len)) + goto stopMetaUser; + nick = g_malloc(len); + strncpy(nick, p, len); + proto_tree_add_text(sstree, + offset + size - left, + sizeof(guint16)+len, + "Nick(%d): %s", len, nick); + p+=len;left-=len; + /* Get the first name */ + if (left<sizeof(guint16)) + goto stopMetaUser; + len = pletohs(p); + p+=sizeof(guint16);left-=sizeof(guint16); + if ((len<=0) || (left<len)) + goto stopMetaUser; + first = g_malloc(len); + strncpy(first, p, len); + proto_tree_add_text(sstree, + offset + size - left, + sizeof(guint16)+len, + "First(%d): %s", len, first); + p+=len;left-=len; + /* Get last name */ + if (left<sizeof(guint16)) + goto stopMetaUser; + len = pletohs(p); + p+=sizeof(guint16);left-=sizeof(guint16); + if ((len<=0) || (left<len)) + goto stopMetaUser; + last = g_malloc(len); + strncpy(last, p, len); + proto_tree_add_text(sstree, + offset + size - left, + sizeof(guint16)+len, + "Last(%d): %s", len, last); + p+=len;left-=len; + /* Get email address */ + if (left<sizeof(guint16)) + goto stopMetaUser; + len = pletohs(p); + p+=sizeof(guint16);left-=sizeof(guint16); + if ((len<=0) || (left<len)) + goto stopMetaUser; + email = g_malloc(len); + strncpy(email, p, len); + proto_tree_add_text(sstree, + offset + size - left, + sizeof(guint16)+len, + "Email(%d): %s", len, email); + p+=len;left-=len; + /* Get the authorize setting */ + if (left<sizeof(unsigned char)) + goto stopMetaUser; + auth = *p; + p++; left--; + /* Get x2 */ + if (left<sizeof(guint16)) + goto stopMetaUser; + x2 = pletohs(p); + proto_tree_add_text(sstree, + offset + size - left, + sizeof(guint16), + "x2: %04x", x2); + p+=sizeof(guint16);left-=sizeof(guint16); + /* Get x3 */ + if (left<sizeof(guint32)) + goto stopMetaUser; + x3 = pletohl(p); + proto_tree_add_text(sstree, + offset + size - left, + sizeof(guint32), + "x3: %08x", x3); + p+=sizeof(guint32);left-=sizeof(guint32); + + stopMetaUser: + if (nick!=NULL) + g_free(nick); + if (first!=NULL) + g_free(first); + if (last!=NULL) + g_free(last); + if (email!=NULL) + g_free(last); + break; + } + case META_ABOUT: + { + int len; + char* about = NULL; + proto_tree* sstree = proto_item_add_subtree(ti, ETT_ICQ_BODY_PARTS); + + /* Skip over META_USER header */ + left -= 3; + p += 3; + /* 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, + offset + size - left, + sizeof(guint16)+len, + "About(%d): %s", len, about); + p+=len;left-=len; + left -= 3; + g_free(about); + 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; + char* item = NULL; + guint16 country; + unsigned char user_timezone = -1; + unsigned char auth = -1; + int len = 0; + proto_tree* sstree = proto_item_add_subtree(ti, ETT_ICQ_BODY_PARTS); + + /* Skip over META_USER header */ + left -= 3; + p += 3; + #if 0 + /* Get the uin */ + if (left<sizeof(guint32)) + break; + uin = pletohl(p); + proto_tree_add_text(sstree, + offset + size - left, + sizeof(guint32), + "UIN: %ld", uin); + p+=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; + if (len>0) { + item = g_malloc(len); + strncpy(item, p, len); + proto_tree_add_text(sstree, + offset + size - left - sizeof(guint16), + sizeof(guint16)+len, + "%s(%d): %s",*d, len, item); + g_free(item); + p+=len;left-=len; + } + d++; + } + /* Get country code */ + if (left<sizeof(guint16)) + break; + country = pletohs(p); + proto_tree_add_text(sstree, + offset + size - left, + sizeof(guint16), + "Countrycode: %d", country); + p+=sizeof(guint16); left-=sizeof(guint16); + /* Get the timezone setting */ + if (left<sizeof(unsigned char)) + break; + user_timezone = *p; + proto_tree_add_text(sstree, + offset + size - left, + sizeof(unsigned char), + "Timezone: %d", user_timezone); + p++; left--; + /* Get the authorize setting */ + if (left<sizeof(unsigned char)) + break; + auth = *p; + proto_tree_add_text(sstree, + offset + size - left, + sizeof(unsigned char), + "Authorization: (%d) %s", + auth, (auth==0)?"No":"Yes"); + p++; left--; + /* Get the webaware setting */ + if (left<sizeof(unsigned char)) + break; + auth = *p; + proto_tree_add_text(sstree, + offset + size - left, + sizeof(unsigned char), + "Webaware: (%d) %s", + auth, (auth==0)?"No":"Yes"); + p++; left--; + /* Get the authorize setting */ + if (left<sizeof(unsigned char)) + break; + auth = *p; + proto_tree_add_text(sstree, + offset + size - left, + sizeof(unsigned char), + "HideIP: (%d) %s", + auth, (auth==0)?"No":"Yes"); + p++; left--; + break; + } + default: + /* This information is already printed in the tree */ + fprintf(stderr, "Meta subcmd: %04x\n", subcmd); + break; + } + } + } + + 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 */ + { + proto_tree* subtree = NULL; + proto_item* ti = NULL; + int left = size; + guint32 uin = -1; + guint16 year = -1; + unsigned char month = -1; + unsigned char day = -1; + unsigned char hour = -1; + unsigned char minute = -1; + + if (tree) { + ti = proto_tree_add_item_format(tree, + hf_icq_cmd, + offset, + 4, + SRV_RECV_MESSAGE, + "Body"); + subtree = proto_item_add_subtree(ti, ETT_ICQ_BODY); + if (left>=sizeof(guint32)) { + uin = pletohl(pd + SRV_RECV_MSG_UIN); + proto_tree_add_item_format(subtree, + hf_icq_uin, + offset + SRV_RECV_MSG_UIN, + sizeof(guint32), + uin, + "UIN: %d", 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, + offset + SRV_RECV_MSG_YEAR, + sizeof(guint16) + 4*sizeof(unsigned char), + "Time: %d-%d-%d %02d:%02d", + day, month, year, hour, minute); + + left -= (sizeof(guint16)+4*sizeof(unsigned char)); + } else + return; + icqv5_decode_msgType(subtree, + pd + SRV_RECV_MSG_MSG_TYPE, + offset + SRV_RECV_MSG_MSG_TYPE, + left); + } + } + /* * Dissect all the v5 client traffic. This is encrypted, so be careful. */ *************** *** 808,819 **** "ICQv5 %s (len %d)", findClientCmd(cmd), pktsize); ! icq_tree = proto_item_add_subtree(ti, ETT_CL_ICQ); ! ti = proto_tree_add_text(icq_tree, ! offset, ! ICQ5_CL_HDRSIZE, ! "Header"); ! icq_header_tree = proto_item_add_subtree(ti, ETT_ICQ_SUBTREE); proto_tree_add_item_format(icq_header_tree, hf_icq_sessionid, --- 1863,1876 ---- "ICQv5 %s (len %d)", findClientCmd(cmd), pktsize); ! icq_tree = proto_item_add_subtree(ti, ETT_ICQ); ! ti = proto_tree_add_item_format(icq_tree, ! hf_icq_type, ! offset, ! ICQ5_CL_HDRSIZE, ! ICQ5_client, ! "Header"); ! icq_header_tree = proto_item_add_subtree(ti, ETT_ICQ_HEADER); proto_tree_add_item_format(icq_header_tree, hf_icq_sessionid, *************** *** 857,875 **** offset + 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, pktsize - ICQ5_CL_HDRSIZE); break; default: proto_tree_add_item_format(icq_tree, hf_icq_cmd, offset+ICQ5_CL_CMD, 2, cmd, ! "Command: %d (%s)", cmd, findcmd(clientCmdCode, cmd)); break; } ti = proto_tree_add_text(icq_tree, --- 1914,1986 ---- offset + ICQ5_CL_HDRSIZE, pktsize - ICQ5_CL_HDRSIZE); break; + case CMD_RAND_SEARCH: + icqv5_cmd_rand_search(icq_tree, + decr_pd + ICQ5_CL_HDRSIZE, + offset + 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, 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, + 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); + break; + case CMD_ACK_MESSAGES: + icqv5_cmd_ack_messages(icq_tree, + decr_pd + ICQ5_CL_HDRSIZE, + offset + ICQ5_CL_HDRSIZE, + pktsize - 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); + 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); + break; + case CMD_CONTACT_LIST: + icqv5_cmd_contact_list(icq_tree, + decr_pd + ICQ5_CL_HDRSIZE, + offset + ICQ5_CL_HDRSIZE, + 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, + decr_pd + ICQ5_CL_HDRSIZE, + offset + ICQ5_CL_HDRSIZE, + pktsize - ICQ5_CL_HDRSIZE, + cmd); + break; default: proto_tree_add_item_format(icq_tree, hf_icq_cmd, offset+ICQ5_CL_CMD, 2, cmd, ! "Command: %d (%s)", ! cmd, findClientCmd(cmd)); ! fprintf(stderr,"Missing: %s\n", findClientCmd(cmd)); break; } ti = proto_tree_add_text(icq_tree, *************** *** 877,883 **** pktsize, "Decoded packet"); icq_decode_tree = proto_item_add_subtree(ti, ! ETT_CL_ICQ_DECODE); proto_tree_add_hexdump(icq_decode_tree, offset, decr_pd, pktsize); } --- 1988,1994 ---- 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); } *************** *** 887,949 **** dissect_icqv5Server(const u_char *pd, int offset, frame_data *fd, ! proto_tree *tree) { /* Server traffic is easy, not encrypted */ proto_tree *icq_tree = NULL; proto_tree *icq_decode_tree = NULL; proto_item *ti = NULL; guint16 version, cmd; guint32 uin, sessionid; ! guint32 pktsize; ! uin = pletohl(&pd[offset + ICQ5_SRV_UIN]); ! cmd = pletohs(&pd[offset + ICQ5_SRV_CMD]); ! sessionid = pletohl(&pd[offset + ICQ5_SRV_SESSIONID]); ! version = pletohs(&pd[offset + ICQ_VERSION]); ! pktsize = fd->pkt_len - offset; ! if (check_col(fd, COL_INFO)) col_add_fstr(fd, COL_INFO, "ICQv5 %s", findServerCmd(cmd)); if (tree) { ti = proto_tree_add_item_format(tree, proto_icq, offset, ! pktsize, ! NULL, ! "ICQv5 Server: len %d", pktsize); ! icq_tree = proto_item_add_subtree(ti, ETT_SRV_ICQ); ! proto_tree_add_item_format(icq_tree, ! hf_icq_cmd, ! offset + ICQ5_SRV_CMD, ! 2, ! cmd, ! "Command: %d (%s)", ! cmd, findServerCmd(cmd)); ! proto_tree_add_item_format(icq_tree, hf_icq_uin, offset+ICQ5_SRV_UIN, 4, uin, "UIN: %ld", uin); ! proto_tree_add_item_format(icq_tree, ! hf_icq_sessionid, ! offset+ICQ5_SRV_SESSIONID, 4, ! sessionid, ! "Session ID: 0x%08x", ! sessionid); ti = proto_tree_add_text(icq_tree, offset, pktsize, "Decoded packet"); icq_decode_tree = proto_item_add_subtree(ti, ! ETT_CL_ICQ_DECODE); ! proto_tree_add_hexdump(icq_decode_tree, offset, pd+offset, pktsize); } } --- 1998,2151 ---- dissect_icqv5Server(const u_char *pd, int offset, frame_data *fd, ! proto_tree *tree, ! guint32 pktsize) { /* Server traffic is easy, not encrypted */ proto_tree *icq_tree = NULL; + proto_tree *icq_header_tree = NULL; proto_tree *icq_decode_tree = NULL; proto_item *ti = NULL; + const u_char* decr_pd; + int changeCol = (pktsize==(guint32)-1); guint16 version, cmd; guint32 uin, sessionid; ! guint16 seq_num1, seq_num2; ! guint32 checkcode; ! 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]); ! seq_num1 = pletohs(&pd[ICQ5_SRV_SEQNUM1]); ! seq_num2 = pletohs(&pd[ICQ5_SRV_SEQNUM2]); ! if (pktsize == -1) ! pktsize = fd->pkt_len - offset; ! decr_pd = pd; ! if (changeCol && check_col(fd, COL_INFO)) col_add_fstr(fd, COL_INFO, "ICQv5 %s", findServerCmd(cmd)); if (tree) { ti = proto_tree_add_item_format(tree, proto_icq, offset, ! pktsize, NULL, ! "ICQv5 %s (len %d)", ! findServerCmd(cmd), ! pktsize); ! icq_tree = proto_item_add_subtree(ti, ETT_ICQ); ! ! ti = proto_tree_add_item_format(icq_tree, ! hf_icq_type, ! offset, ! ICQ5_SRV_HDRSIZE, ! ICQ5_server, ! "Header"); ! icq_header_tree = proto_item_add_subtree(ti, ETT_ICQ_HEADER); ! ! proto_tree_add_item_format(icq_header_tree, ! hf_icq_sessionid, ! offset+ICQ5_SRV_SESSIONID, ! 4, ! sessionid, ! "Session ID: 0x%08x", ! sessionid); ! proto_tree_add_text(icq_header_tree, ! offset+ICQ5_SRV_SEQNUM1, ! 2, ! "Seq Number1: 0x%04x", ! seq_num1); ! proto_tree_add_text(icq_header_tree, ! offset+ICQ5_SRV_SEQNUM2, ! 2, ! "Seq Number2: 0x%04x", ! seq_num2); ! proto_tree_add_item_format(icq_header_tree, hf_icq_uin, offset+ICQ5_SRV_UIN, 4, uin, "UIN: %ld", uin); ! proto_tree_add_item_format(icq_header_tree, ! hf_icq_checkcode, ! offset+ICQ5_SRV_CHECKCODE, 4, ! checkcode, ! "Checkcode: 0x%08x", ! checkcode); ! switch (cmd) { ! case SRV_USER_ONLINE: ! icqv5_srv_user_online(icq_tree, ! decr_pd + ICQ5_SRV_HDRSIZE, ! offset + ICQ5_SRV_HDRSIZE, ! pktsize - ICQ5_SRV_HDRSIZE); ! break; ! case SRV_USER_OFFLINE: ! icqv5_srv_user_offline(icq_tree, ! decr_pd + ICQ5_SRV_HDRSIZE, ! offset + ICQ5_SRV_HDRSIZE, ! pktsize - ICQ5_SRV_HDRSIZE); ! break; ! case SRV_LOGIN_REPLY: ! icqv5_srv_login_reply(icq_tree, ! decr_pd + ICQ5_SRV_HDRSIZE, ! offset + ICQ5_SRV_HDRSIZE, ! pktsize - ICQ5_SRV_HDRSIZE); ! break; ! case SRV_META_USER: ! icqv5_srv_meta_user(icq_tree, ! decr_pd + ICQ5_SRV_HDRSIZE, ! offset + ICQ5_SRV_HDRSIZE, ! pktsize - ICQ5_SRV_HDRSIZE); ! break; ! case SRV_RECV_MESSAGE: ! icqv5_srv_recv_message(icq_tree, ! decr_pd + ICQ5_SRV_HDRSIZE, ! offset + ICQ5_SRV_HDRSIZE, ! pktsize - ICQ5_SRV_HDRSIZE); ! break; ! case SRV_MULTI: ! icqv5_srv_multi(icq_tree, ! decr_pd + ICQ5_SRV_HDRSIZE, ! offset + ICQ5_SRV_HDRSIZE, ! pktsize - ICQ5_SRV_HDRSIZE, ! fd); ! break; ! case SRV_ACK: ! case SRV_GO_AWAY: ! case SRV_NEW_UIN: ! case SRV_BAD_PASS: ! case SRV_UPDATE_SUCCESS: ! icqv5_srv_no_params(icq_tree, ! decr_pd + ICQ5_SRV_HDRSIZE, ! offset + ICQ5_SRV_HDRSIZE, ! pktsize - ICQ5_SRV_HDRSIZE, ! cmd); ! break; ! default: ! proto_tree_add_item_format(icq_tree, ! hf_icq_cmd, ! offset + ICQ5_SRV_CMD, ! 2, ! cmd, ! "Command: %d (%s)", ! cmd, findServerCmd(cmd)); ! fprintf(stderr,"Missing: %s\n", findServerCmd(cmd)); ! break; ! } ! ti = proto_tree_add_text(icq_tree, 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); } } *************** *** 961,967 **** if (unknown == 0x0L) { dissect_icqv5Client(pd, offset, fd, tree); } else { ! dissect_icqv5Server(pd, offset, fd, tree); } } --- 2163,2169 ---- if (unknown == 0x0L) { dissect_icqv5Client(pd, offset, fd, tree); } else { ! dissect_icqv5Server(pd + offset, offset, fd, tree, (guint32) -1); } } *************** *** 991,996 **** --- 2193,2200 ---- proto_register_icq(void) { static hf_register_info hf[] = { + { &hf_icq_type, + {"Type", "icq.type", FT_UINT16, BASE_DEC, NULL, 0x0, ""}}, { &hf_icq_uin, {"UIN", "icq.uin", FT_UINT32, BASE_DEC, NULL, 0x0, ""}}, { &hf_icq_sessionid, Index: packet-tcp.c =================================================================== RCS file: /cvsroot/ethereal/packet-tcp.c,v retrieving revision 1.40 diff -c -r1.40 packet-tcp.c *** packet-tcp.c 1999/11/02 07:04:46 1.40 --- packet-tcp.c 1999/11/04 21:51:44 *************** *** 495,501 **** pi.match_port = TCP_PORT_PPTP; dissect_pptp(pd, offset, fd, tree); } else if (PORT_IS(TCP_PORT_HTTP) || PORT_IS(TCP_ALT_PORT_HTTP) ! || PORT_IS(631)) dissect_http(pd, offset, fd, tree); else if (PORT_IS(TCP_PORT_NBSS)) { pi.match_port = TCP_PORT_NBSS; --- 495,501 ---- pi.match_port = TCP_PORT_PPTP; dissect_pptp(pd, offset, fd, tree); } else if (PORT_IS(TCP_PORT_HTTP) || PORT_IS(TCP_ALT_PORT_HTTP) ! || PORT_IS(631) || PORT_IS(800)) dissect_http(pd, offset, fd, tree); else if (PORT_IS(TCP_PORT_NBSS)) { pi.match_port = TCP_PORT_NBSS; Index: packet.h =================================================================== RCS file: /cvsroot/ethereal/packet.h,v retrieving revision 1.124 diff -c -r1.124 packet.h *** packet.h 1999/10/30 06:10:32 1.124 --- packet.h 1999/11/04 21:51:44 *************** *** 251,260 **** ETT_DNS_ANS, ETT_DNS_RR, ETT_EIGRP, ! ETT_CL_ICQ, ! ETT_CL_ICQ_DECODE, ! ETT_ICQ_SUBTREE, ! ETT_SRV_ICQ, ETT_ISAKMP, ETT_ISAKMP_FLAGS, ETT_ISAKMP_PAYLOAD, --- 251,261 ---- ETT_DNS_ANS, ETT_DNS_RR, ETT_EIGRP, ! ETT_ICQ, ! ETT_ICQ_DECODE, ! ETT_ICQ_HEADER, ! ETT_ICQ_BODY, ! ETT_ICQ_BODY_PARTS, ETT_ISAKMP, ETT_ISAKMP_FLAGS, ETT_ISAKMP_PAYLOAD,
- Follow-Ups:
- Re: [ethereal-dev] Packet-icq.c update
- From: Guy Harris
- Re: [ethereal-dev] Packet-icq.c update
- From: Guy Harris
- Re: [ethereal-dev] Packet-icq.c update
- Prev by Date: Re: [ethereal-dev] NFS dissector continued
- Next by Date: Re: [ethereal-dev] Packet-icq.c update
- Previous by thread: Re: [ethereal-dev] NFS dissector continued
- Next by thread: Re: [ethereal-dev] Packet-icq.c update
- Index(es):