From Jelmer Vernooij:

- Dissect ICQ TLV values
- Dissect channel 1 and channel 2 messages correctly in Oscar (required
  for dissecting direct connections)

svn path=/trunk/; revision=12072
This commit is contained in:
Guy Harris 2004-09-23 17:40:36 +00:00
parent 91d4c8135b
commit 285066ac5b
6 changed files with 344 additions and 101 deletions

View File

@ -44,12 +44,14 @@
#define ICQ_CLI_OFFLINE_MESSAGE_REQ 0x003c
#define ICQ_CLI_DELETE_OFFLINE_MSGS 0x003e
#define ICQ_SRV_OFFLINE_MSGS 0x0041
#define ICQ_SRV_END_OF_OFFLINE_MSGS 0x0042
#define ICQ_CLI_META_INFO_REQ 0x07d0
#define ICQ_SRV_META_INFO_REPL 0x07da
static const value_string aim_icq_data_types[] = {
{ ICQ_CLI_OFFLINE_MESSAGE_REQ, "Offline Message Request" },
{ ICQ_SRV_OFFLINE_MSGS, "Offline Messages Reply" },
{ ICQ_SRV_END_OF_OFFLINE_MSGS, "End Of Offline Messages Reply" },
{ ICQ_CLI_DELETE_OFFLINE_MSGS, "Delete Offline Messages Request" },
{ ICQ_CLI_META_INFO_REQ, "Metainfo Request" },
@ -58,7 +60,7 @@ static const value_string aim_icq_data_types[] = {
};
static int dissect_aim_tlv_value_icq(proto_item *ti, guint16 subtype, tvbuff_t *tvb);
static int dissect_aim_tlv_value_icq(proto_item *ti, guint16 subtype, tvbuff_t *tvb, packet_info *pinfo _U_);
#define TLV_ICQ_META_DATA 0x0001
@ -77,27 +79,124 @@ static gint ett_aim_icq_tlv = -1;
static gint hf_icq_tlv_data_chunk_size = -1;
static gint hf_icq_tlv_request_owner_uid = -1;
static gint hf_icq_tlv_request_type = -1;
static gint hf_icq_meta_subtype = -1;
static gint hf_icq_tlv_request_seq_num = -1;
static gint hf_icq_dropped_msg_flag = -1;
static int dissect_aim_tlv_value_icq(proto_item *ti _U_, guint16 subtype _U_, tvbuff_t *tvb _U_)
static struct
{
guint16 subtype;
char *name;
int (*dissector) (tvbuff_t *, packet_info *, proto_tree *);
} icq_calls [] = {
{ 0x0001, "Server Error Reply", NULL },
{ 0x0064, "Set User Home Info Reply", NULL },
{ 0x006e, "Set User Work Info Reply", NULL },
{ 0x0078, "Set User More Info Reply", NULL },
{ 0x0082, "Set User Notes Info Reply", NULL },
{ 0x0087, "Set User Email Info Reply", NULL },
{ 0x008c, "Set User Interests Info Reply", NULL },
{ 0x0096, "Set User Affiliations Info Reply", NULL },
{ 0x00a0, "Set User Permissions Reply", NULL },
{ 0x00aa, "Set User Password Reply", NULL },
{ 0x00b4, "Unregister Account Reply", NULL },
{ 0x00be, "Set User Homepage Category Reply", NULL },
{ 0x00c8, "User Basic Info Reply", NULL },
{ 0x00d2, "User Work Info Reply", NULL },
{ 0x00dc, "User More Info Reply", NULL },
{ 0x00e6, "User Notes Info Reply", NULL },
{ 0x00eb, "User Extended Email Reply", NULL },
{ 0x00f0, "User Interests Info Reply", NULL },
{ 0x00fa, "User Affiliations Info Reply", NULL },
{ 0x0104, "Short User Info Reply", NULL },
{ 0x010e, "User Homepage Category Reply", NULL },
{ 0x01a4, "Search: User found", NULL },
{ 0x0302, "Registration Stats Reply", NULL },
{ 0x0366, "Random Search Server Reply", NULL },
{ 0x03ea, "Set User Home Info Request", NULL },
{ 0x03f3, "Set User Work Info Request", NULL },
{ 0x03fd, "Set User More Info Request", NULL },
{ 0x0406, "Set User Notes Request", NULL },
{ 0x040b, "Set User Extended Email Info Request", NULL },
{ 0x0410, "Set User Interests Info Request", NULL },
{ 0x041a, "Set User Affiliations Info Request", NULL },
{ 0x0424, "Set User Permissions Info Request", NULL },
{ 0x042e, "Change User Password Request", NULL },
{ 0x0442, "Set User Homepage Category Request", NULL },
{ 0x04b2, "Fullinfo Request", NULL },
{ 0x04ba, "Short User Info Request", NULL },
{ 0x04c4, "Unregister User Request", NULL },
{ 0x0515, "Search By Details Request", NULL },
{ 0x0569, "Search By UIN Request", NULL },
{ 0x055f, "Whitepages Search Request", NULL },
{ 0x0573, "Search By Email Request", NULL },
{ 0x074e, "Random Chat User Search Request", NULL },
{ 0x0898, "Server Variable Request (XML)", NULL },
{ 0x0aa5, "Registration Report Request", NULL },
{ 0x0aaf, "Shortcut Bar Stats Report Request", NULL },
{ 0x0c3a, "Save Info Request", NULL },
{ 0x1482, "Send SMS Request", NULL },
{ 0x2008, "Spam Report Request", NULL },
{ 0x08a2, "Server Variable Reply (XML)", NULL },
{ 0x0c3f, "Set Fullinfo Reply", NULL },
{ 0x2012, "User Spam Report Reply", NULL },
{ 0, NULL, NULL },
};
static int dissect_aim_tlv_value_icq(proto_item *ti _U_, guint16 subtype _U_, tvbuff_t *tvb _U_, packet_info *pinfo)
{
int offset = 0;
int i;
proto_item *subtype_item;
guint16 req_type, req_subtype;
proto_tree *t = proto_item_add_subtree(ti, ett_aim_icq_tlv);
proto_tree_add_item(t, hf_icq_tlv_data_chunk_size, tvb, offset, 2, tvb_get_ntohs(tvb, offset));
proto_tree_add_item(t, hf_icq_tlv_data_chunk_size, tvb, offset, 2, TRUE);
offset += 2;
proto_tree_add_item(t, hf_icq_tlv_request_owner_uid, tvb, offset, 4, tvb_get_ntoh24(tvb, offset));
proto_tree_add_item(t, hf_icq_tlv_request_owner_uid, tvb, offset, 4, TRUE);
offset += 4;
proto_tree_add_item(t, hf_icq_tlv_request_type, tvb, offset, 2, tvb_get_ntohs(tvb, offset));
proto_tree_add_item(t, hf_icq_tlv_request_type, tvb, offset, 2, TRUE);
req_type = tvb_get_letohs(tvb, offset);
offset += 2;
proto_tree_add_item(t, hf_icq_tlv_request_seq_num, tvb, offset, 2, tvb_get_ntohs(tvb, offset));
proto_tree_add_item(t, hf_icq_tlv_request_seq_num, tvb, offset, 2, TRUE);
offset += 2;
return 0;
switch(req_type) {
case ICQ_CLI_OFFLINE_MESSAGE_REQ: return offset;
case ICQ_CLI_DELETE_OFFLINE_MSGS: return offset;
case ICQ_SRV_OFFLINE_MSGS:
/* FIXME */
break;
case ICQ_SRV_END_OF_OFFLINE_MSGS:
proto_tree_add_item(t, hf_icq_dropped_msg_flag, tvb, offset, 1, TRUE);
return offset+1;
case ICQ_CLI_META_INFO_REQ:
case ICQ_SRV_META_INFO_REPL:
req_subtype = tvb_get_letohs(tvb, offset);
subtype_item = proto_tree_add_item(t, hf_icq_meta_subtype, tvb, offset, 2, TRUE); offset+=2;
for(i = 0; icq_calls[i].name; i++) {
if(icq_calls[i].subtype == req_subtype) break;
}
if(check_col(pinfo->cinfo, COL_INFO))
col_set_str(pinfo->cinfo, COL_INFO, icq_calls[i].name?icq_calls[i].name:"Unknown ICQ Meta Call");
proto_item_append_text(subtype_item, " (%s)", icq_calls[i].name?icq_calls[i].name:"Unknown");
if(icq_calls[i].dissector)
return icq_calls[i].dissector(tvb_new_subset(tvb, offset, -1, -1), pinfo, t);
default:
break;
}
return offset;
}
static int dissect_aim_icq_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
@ -107,8 +206,8 @@ static int dissect_aim_icq_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
static const aim_subtype aim_fnac_family_icq[] = {
{ 0x0001, "Error", dissect_aim_snac_error },
{ 0x0002, "Login Request", dissect_aim_icq_tlv },
{ 0x0003, "Login Response", dissect_aim_icq_tlv },
{ 0x0002, "ICQ Request", dissect_aim_icq_tlv },
{ 0x0003, "ICQ Response", dissect_aim_icq_tlv },
{ 0x0006, "Auth Request", NULL },
{ 0x0007, "Auth Response", NULL },
{ 0, NULL, NULL }
@ -134,6 +233,12 @@ proto_register_aim_icq(void)
{ &hf_icq_tlv_request_seq_num,
{"Request Sequence Number", "aim_icq.request_seq_number", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL},
},
{ &hf_icq_dropped_msg_flag,
{"Dropped messages flag", "aim_icq.offline_msgs.dropped_flag", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL },
},
{ &hf_icq_meta_subtype,
{"Meta Request Subtype", "aim_icq.subtype", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL },
},
};
/* Setup protocol subtree array */

View File

@ -60,7 +60,33 @@ static const aim_tlv messaging_incoming_ch1_tlvs[] = {
{ INCOMING_CH1_ICON_PRESENT, "Icon present", dissect_aim_tlv_value_bytes },
{ INCOMING_CH1_BUDDY_REQ, "Buddy Req", dissect_aim_tlv_value_bytes },
{ INCOMING_CH1_TYPING, "Non-direct connect typing notification", dissect_aim_tlv_value_bytes },
{ 0, "Unknown", NULL }
{ 0, "Unknown", NULL },
};
int dissect_aim_tlv_value_rendezvous ( proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_);
extern int dissect_aim_tlv_value_capability_data ( proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_);
#define INCOMING_CH2_SERVER_ACK_REQ 0x0003
#define INCOMING_CH2_RENDEZVOUS_DATA 0x0005
static const aim_tlv messaging_incoming_ch2_tlvs[] = {
{ INCOMING_CH2_SERVER_ACK_REQ, "Server Ack Requested", dissect_aim_tlv_value_bytes },
{ INCOMING_CH2_RENDEZVOUS_DATA, "Rendez Vous Data", dissect_aim_tlv_value_rendezvous },
{ 0, "Unknown", NULL },
};
#define RENDEZVOUS_TLV_INT_IP 0x0003
#define RENDEZVOUS_TLV_EXT_IP 0x0004
#define RENDEZVOUS_TLV_EXT_PORT 0x0005
#define RENDEZVOUS_TLV_CAPABILITY_DATA 0x2711
static const aim_tlv rendezvous_tlvs[] = {
{ RENDEZVOUS_TLV_INT_IP, "Internal IP", dissect_aim_tlv_value_ipv4 },
{ RENDEZVOUS_TLV_EXT_IP, "External IP", dissect_aim_tlv_value_ipv4 },
{ RENDEZVOUS_TLV_EXT_PORT, "External Port", dissect_aim_tlv_value_uint16 },
{ RENDEZVOUS_TLV_CAPABILITY_DATA, "Capability Data", dissect_aim_tlv_value_capability_data },
{ 0, "Unknown", NULL },
};
#define MINITYPING_FINISHED_SIGN 0x0000
@ -74,6 +100,17 @@ static const value_string minityping_type[] = {
{0, NULL }
};
#define RENDEZVOUS_MSG_REQUEST 0
#define RENDEZVOUS_MSG_CANCEL 1
#define RENDEZVOUS_MSG_ACCEPT 2
static const value_string rendezvous_msg_types[] = {
{ RENDEZVOUS_MSG_REQUEST, "Request" },
{ RENDEZVOUS_MSG_CANCEL, "Cancel" },
{ RENDEZVOUS_MSG_ACCEPT, "Accept" },
{ 0, "Unknown" },
};
#define EVIL_ORIGIN_ANONYMOUS 1
#define EVIL_ORIGIN_NONANONYMOUS 2
@ -100,18 +137,39 @@ static int hf_aim_message_channel_id = -1;
static int hf_aim_icbm_evil = -1;
static int hf_aim_evil_warn_level = -1;
static int hf_aim_evil_new_warn_level = -1;
static int hf_aim_rendezvous_msg_type = -1;
/* Initialize the subtree pointers */
static gint ett_aim_messaging = -1;
static gint ett_aim_rendezvous_data = -1;
int dissect_aim_tlv_value_rendezvous ( proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
{
int offset = 0;
proto_tree *entry = proto_item_add_subtree(ti, ett_aim_rendezvous_data);
proto_tree_add_item(entry, hf_aim_rendezvous_msg_type, tvb, offset, 2, FALSE);
offset+=2;
proto_tree_add_item(entry, hf_aim_icbm_cookie, tvb, offset, 8, FALSE);
offset += 8;
offset = dissect_aim_capability(entry, tvb, offset);
return dissect_aim_tlv_sequence(tvb, pinfo, offset, entry, rendezvous_tlvs);
}
static int dissect_aim_msg_outgoing(tvbuff_t *tvb, packet_info *pinfo, proto_tree *msg_tree)
{
int offset = 0;
const aim_tlv *ch_tlvs = NULL;
guint16 channel_id;
/* ICBM Cookie */
proto_tree_add_item(msg_tree, hf_aim_icbm_cookie, tvb, offset, 8, FALSE);
offset += 8;
/* Message Channel ID */
channel_id = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(msg_tree, hf_aim_message_channel_id, tvb, offset, 2,
FALSE);
offset += 2;
@ -127,21 +185,22 @@ static int dissect_aim_msg_outgoing(tvbuff_t *tvb, packet_info *pinfo, proto_tre
offset = dissect_aim_buddyname(tvb, pinfo, offset, msg_tree);
while(tvb_reported_length_remaining(tvb, offset) > 0) {
/* djh - Note that we reuse the "incoming ch1 tlv" set even though this
is outgoing. We may need to split this to a separate TLV set, but
so far I haven't seen the need @@@@@@@@ */
offset = dissect_aim_tlv(tvb, pinfo, offset, msg_tree,
messaging_incoming_ch1_tlvs);
switch(channel_id) {
case 1: ch_tlvs = messaging_incoming_ch1_tlvs; break;
case 2: ch_tlvs = messaging_incoming_ch2_tlvs; break;
default: return offset;
}
return offset;
return dissect_aim_tlv_sequence(tvb, pinfo, offset, msg_tree, ch_tlvs);
}
static int dissect_aim_msg_incoming(tvbuff_t *tvb, packet_info *pinfo, proto_tree *msg_tree)
{
int offset = 0;
const aim_tlv *ch_tlvs;
guint16 channel_id;
/* ICBM Cookie */
proto_tree_add_item(msg_tree, hf_aim_icbm_cookie, tvb, offset, 8, FALSE);
offset += 8;
@ -149,12 +208,19 @@ static int dissect_aim_msg_incoming(tvbuff_t *tvb, packet_info *pinfo, proto_tre
/* Message Channel ID */
proto_tree_add_item(msg_tree, hf_aim_message_channel_id, tvb, offset, 2,
FALSE);
channel_id = tvb_get_ntohs(tvb, offset);
offset += 2;
offset = dissect_aim_userinfo(tvb, pinfo, offset, msg_tree);
switch(channel_id) {
case 1: ch_tlvs = messaging_incoming_ch1_tlvs; break;
case 2: ch_tlvs = messaging_incoming_ch2_tlvs; break;
default: return offset;
}
return dissect_aim_tlv_sequence(tvb, pinfo, offset, msg_tree,
messaging_incoming_ch1_tlvs);
ch_tlvs);
}
static int dissect_aim_msg_params(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *msg_tree)
@ -202,8 +268,8 @@ static const aim_subtype aim_fnac_family_messaging[] = {
{ 0x0003, "Reset ICBM Parameter", NULL },
{ 0x0004, "Request Parameter Info", NULL},
{ 0x0005, "Parameter Info", dissect_aim_msg_params },
{ 0x0006, "Incoming", dissect_aim_msg_incoming },
{ 0x0007, "Outgoing", dissect_aim_msg_outgoing },
{ 0x0006, "Outgoing", dissect_aim_msg_outgoing },
{ 0x0007, "Incoming", dissect_aim_msg_incoming },
{ 0x0008, "Evil Request", dissect_aim_msg_evil_req },
{ 0x0009, "Evil Response", dissect_aim_msg_evil_repl },
{ 0x000a, "Missed Call", NULL },
@ -267,11 +333,15 @@ proto_register_aim_messaging(void)
{ &hf_aim_icbm_notification_type,
{ "Notification Type", "aim.notification.type", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL },
},
{ &hf_aim_rendezvous_msg_type,
{ "Message Type", "aim.rendezvous.msg_type", FT_UINT16, BASE_HEX, VALS(rendezvous_msg_types), 0x0, "", HFILL },
},
};
/* Setup protocol subtree array */
static gint *ett[] = {
&ett_aim_messaging,
&ett_aim_rendezvous_data,
};
/* Register the protocol name and description */

View File

@ -44,6 +44,41 @@
static int proto_aim_oft = -1;
static int ett_aim_recvfile = -1;
static int ett_aim_sendfile = -1;
/*
* cookie (8 chars)
* encrypt (uint16)
* compress (uint16)
* totfiles (uint16)
* filesleft (uint16)
* totparts (uint16)
* partsleft (uint16)
* totsize (uint32)
* size (uint32)
* modtime (uint32)
* checksum (uint32)
* rfrcsum (uint32)
* rfsize (uint32)
* cretime (uint32)
* rfcsum (uint32)
* nrecvd (uint32)
* recvscum (uint32)
* idstring (32 chars)
* flags (uint8)
* lnameoffset (uint8)
* lsizeoffset (uint8)
* unknown (69 chars)
* macfileinfo (16 chars)
* nencode (uint16)
* nlanguage (uint16)
* filename (raw, 64 chars)
*
* length of file (uint16)
* file data
*/
/* Register the protocol with Ethereal */
void
@ -62,8 +97,8 @@ proto_register_aim_oft(void)
proto_aim_oft = proto_register_protocol("AIM OFT", "AIM OFT", "aim_oft");
/* Required function calls to register the header fields and subtrees used */
/* proto_register_field_array(proto_aim_oft, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));*/
/* proto_register_field_array(proto_aim_oft, hf, array_length(hf));*/
/* proto_register_subtree_array(ett, array_length(ett));*/
}
void

View File

@ -121,12 +121,30 @@ static int dissect_aim_snac_signon_signon_reply(tvbuff_t *tvb,
return offset;
}
static int dissect_aim_tlv_value_registration(proto_item *ti _U_, guint16 value_id _U_, tvbuff_t *tvb _U_, packet_info *pinfo)
{
/* FIXME */
return 0;
}
#define REG_TLV_REGISTRATION_INFO 0x0001
static const aim_tlv registration_tlvs[] = {
{ REG_TLV_REGISTRATION_INFO, "Registration Info", dissect_aim_tlv_value_registration },
{ 0, "Unknown", NULL },
};
static int dissect_aim_snac_register (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
return dissect_aim_tlv(tvb, pinfo, 0, tree, registration_tlvs);
}
static const aim_subtype aim_fnac_family_signon[] = {
{ 0x0001, "Error", dissect_aim_snac_error },
{ 0x0002, "Logon", dissect_aim_snac_signon_logon },
{ 0x0003, "Logon Reply", dissect_aim_snac_signon_logon_reply },
{ 0x0004, "Request UIN", NULL },
{ 0x0005, "New UIN response", NULL },
{ 0x0004, "Request UIN", dissect_aim_snac_register },
{ 0x0005, "New UIN response", dissect_aim_snac_register },
{ 0x0006, "Sign-on", dissect_aim_snac_signon_signon },
{ 0x0007, "Sign-on Reply", dissect_aim_snac_signon_signon_reply },
{ 0x000a, "Server SecureID Request", NULL },

View File

@ -231,8 +231,8 @@ const aim_tlv client_tlvs[] = {
};
static int dissect_aim_tlv_value_userstatus(proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb);
static int dissect_aim_tlv_value_dcinfo(proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb);
static int dissect_aim_tlv_value_userstatus(proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_);
static int dissect_aim_tlv_value_dcinfo(proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_);
#define AIM_ONLINEBUDDY_USERCLASS 0x0001
#define AIM_ONLINEBUDDY_ONSINCE 0x0003
@ -674,7 +674,8 @@ int dissect_aim_snac_error(tvbuff_t *tvb, packet_info *pinfo,
proto_tree_add_item (aim_tree, hf_aim_snac_error,
tvb, 0, 2, FALSE);
return tvb_length_remaining(tvb, 2);
return dissect_aim_tlv_sequence(tvb, pinfo, 2, aim_tree, client_tlvs);
}
int dissect_aim_userinfo(tvbuff_t *tvb, packet_info *pinfo,
@ -866,19 +867,21 @@ int dissect_aim_buddyname(tvbuff_t *tvb, packet_info *pinfo _U_, int offset,
return offset+buddyname_length;
}
typedef struct _e_uuid_t {
guint32 Data1;
guint16 Data2;
guint16 Data3;
guint8 Data4[8];
} e_uuid_t;
typedef struct _aim_client_capability
{
const char *name;
e_uuid_t clsid;
} aim_client_capability;
typedef struct _aim_client_capabilities {
const char *description;
e_uuid_t clsid;
} aim_client_capabilities;
static const aim_client_capability known_client_caps[] = {
{ "Send File",
{0x09461343, 0x4c7f, 0x11d1,
{ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
static const aim_client_capabilities client_caps[] = {
{ "Recv File",
{ 0x09461348, 0x4c7f, 0x11d1,
{ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
{ "iChat",
{0x09460000, 0x4c7f, 0x11d1,
{ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
@ -911,15 +914,6 @@ static const aim_client_capabilities client_caps[] = {
{0x09461341, 0x4c7f, 0x11d1,
{ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
{ "Send File",
{0x09461343, 0x4c7f, 0x11d1,
{ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
{ "Receive File",
{0x09461348, 0x4c7f, 0x11d1,
{ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
{ "Direct ICQ Communication",
{0x09461344, 0x4c7f, 0x11d1,
{0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
@ -936,7 +930,6 @@ static const aim_client_capabilities client_caps[] = {
{0x09461347, 0x4c7f, 0x11d1,
{0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
{ "ICQ Server Relaying",
{0x09461349, 0x4c7f, 0x11d1,
{0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
@ -997,10 +990,53 @@ static const aim_client_capabilities client_caps[] = {
{0x0946f003, 0x4c7f, 0x11d1,
{0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
{ "Unknown", {0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } } }
{ NULL, {0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } } }
};
int dissect_aim_tlv_value_client_capabilities(proto_item *ti _U_, guint16 valueid _U_, tvbuff_t *tvb)
const aim_client_capability *aim_find_capability ( e_uuid_t clsid)
{
int i;
for(i = 0; known_client_caps[i].name; i++)
{
const aim_client_capability *caps = &(known_client_caps[i]);
if(memcmp(&(caps->clsid), &clsid, sizeof(e_uuid_t)) == 0)
return caps;
}
return NULL;
}
int dissect_aim_tlv_value_capability_data ( proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb _U_, packet_info *pinfo _U_)
{
return 0;
}
int dissect_aim_capability(proto_tree *entry, tvbuff_t *tvb, int offset)
{
const aim_client_capability *caps = NULL;
e_uuid_t clsid;
clsid.Data1 = tvb_get_ntohl(tvb, offset);
clsid.Data2 = tvb_get_ntohs(tvb, offset+4);
clsid.Data3 = tvb_get_ntohs(tvb, offset+6);
tvb_memcpy(tvb, clsid.Data4, offset+8, 8);
caps = aim_find_capability(clsid);
proto_tree_add_text(entry, tvb, offset, 16,
"%s {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
caps?caps->name:"Unknown", clsid.Data1, clsid.Data2,
clsid.Data3, clsid.Data4[0], clsid.Data4[1], clsid.Data4[2],
clsid.Data4[3], clsid.Data4[4], clsid.Data4[5], clsid.Data4[6],
clsid.Data4[7]
);
return offset+16;
}
int dissect_aim_tlv_value_client_capabilities(proto_item *ti _U_, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
{
int offset = 0;
proto_tree *entry;
@ -1010,38 +1046,13 @@ int dissect_aim_tlv_value_client_capabilities(proto_item *ti _U_, guint16 valuei
entry = proto_item_add_subtree(ti, ett_aim_client_capabilities);
while (tvb_length_remaining(tvb, offset) > 0) {
int i;
const aim_client_capabilities *caps = NULL;
e_uuid_t clsid;
clsid.Data1 = tvb_get_ntohl(tvb, offset);
clsid.Data2 = tvb_get_ntohs(tvb, offset+4);
clsid.Data3 = tvb_get_ntohs(tvb, offset+6);
tvb_memcpy(tvb, clsid.Data4, offset+8, 8);
for(i = 0; client_caps[i].description; i++) {
if(memcmp(&(client_caps[i].clsid), &clsid, sizeof(e_uuid_t)) == 0) {
caps = &client_caps[i];
break;
}
}
proto_tree_add_text(entry, tvb, offset, 16,
"%s {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
caps?caps->description:"Unknown", clsid.Data1, clsid.Data2,
clsid.Data3, clsid.Data4[0], clsid.Data4[1], clsid.Data4[2],
clsid.Data4[3], clsid.Data4[4], clsid.Data4[5], clsid.Data4[6],
clsid.Data4[7]
);
offset+=16;
offset = dissect_aim_capability(entry, tvb, offset);
}
return tvb_length(tvb);
}
int dissect_aim_tlv_value_time(proto_item *ti _U_, guint16 valueid _U_, tvbuff_t *tvb)
int dissect_aim_tlv_value_time(proto_item *ti _U_, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
{
/* FIXME */
return tvb_length(tvb);
@ -1067,20 +1078,20 @@ int dissect_aim_userclass(tvbuff_t *tvb, int offset, int len, proto_item *ti, gu
return offset+len;
}
int dissect_aim_tlv_value_userclass(proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb)
int dissect_aim_tlv_value_userclass(proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
{
guint16 value16 = tvb_get_ntohs(tvb, 0);
proto_item_set_text(ti, "Value: 0x%04x", value16);
return dissect_aim_userclass(tvb, 0, 2, ti, value16);
}
static int dissect_aim_tlv_value_userstatus(proto_item *ti _U_, guint16 valueid _U_, tvbuff_t *tvb)
static int dissect_aim_tlv_value_userstatus(proto_item *ti _U_, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
{
/* FIXME */
return tvb_length(tvb);
}
static int dissect_aim_tlv_value_dcinfo(proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb)
static int dissect_aim_tlv_value_dcinfo(proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
{
int offset = 0;
@ -1101,7 +1112,7 @@ static int dissect_aim_tlv_value_dcinfo(proto_item *ti, guint16 valueid _U_, tvb
return offset;
}
int dissect_aim_tlv_value_string (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb)
int dissect_aim_tlv_value_string (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_)
{
guint8 *buf;
gint string_len;
@ -1113,37 +1124,37 @@ int dissect_aim_tlv_value_string (proto_item *ti, guint16 valueid _U_, tvbuff_t
return string_len;
}
int dissect_aim_tlv_value_bytes (proto_item *ti _U_, guint16 valueid _U_, tvbuff_t *tvb _U_)
int dissect_aim_tlv_value_bytes (proto_item *ti _U_, guint16 valueid _U_, tvbuff_t *tvb _U_, packet_info *pinfo _U_)
{
return tvb_length(tvb);
}
int dissect_aim_tlv_value_uint8 (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb){
int dissect_aim_tlv_value_uint8 (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_){
guint8 value8 = tvb_get_guint8(tvb, 0);
proto_item_set_text(ti, "Value: %d", value8);
return 1;
}
int dissect_aim_tlv_value_uint16 (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb){
int dissect_aim_tlv_value_uint16 (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_){
guint16 value16 = tvb_get_ntohs(tvb, 0);
proto_item_set_text(ti, "Value: %d", value16);
return 2;
}
int dissect_aim_tlv_value_ipv4 (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb){
int dissect_aim_tlv_value_ipv4 (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_){
/* FIXME: Somewhat more readable format ? */
guint32 value32 = tvb_get_ntoh24(tvb, 0);
proto_item_set_text(ti, "Value: %d", value32);
return 4;
}
int dissect_aim_tlv_value_uint32 (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb){
int dissect_aim_tlv_value_uint32 (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_){
guint32 value32 = tvb_get_ntoh24(tvb, 0);
proto_item_set_text(ti, "Value: %d", value32);
return 4;
}
int dissect_aim_tlv_value_messageblock (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb){
int dissect_aim_tlv_value_messageblock (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *pinfo _U_){
proto_tree *entry;
guint8 *buf;
guint16 featurelen;
@ -1262,7 +1273,7 @@ int dissect_aim_tlv(tvbuff_t *tvb, packet_info *pinfo _U_,
"Value");
if (tmp[i].dissector) {
tmp[i].dissector(ti1, valueid, tvb_new_subset(tvb, offset, length, length));
tmp[i].dissector(ti1, valueid, tvb_new_subset(tvb, offset, length, length), pinfo);
}
offset += length;

View File

@ -25,12 +25,15 @@
#ifndef __PACKET_AIM_H__
#define __PACKET_AIM_H__
/* For e_uuid_t */
#include "packet-dcerpc.h"
#define MAX_BUDDYNAME_LENGTH 30
typedef struct _aim_tlv {
guint16 valueid;
char *desc;
int (*dissector) (proto_item *ti, guint16 value_id, tvbuff_t *tvb);
int (*dissector) (proto_item *ti, guint16 value_id, tvbuff_t *tvb, packet_info *);
} aim_tlv;
struct aiminfo {
@ -71,17 +74,18 @@ int dissect_aim_tlv_sequence(tvbuff_t *tvb, packet_info *pinfo _U_, int offset,
const aim_family *aim_get_family( guint16 family );
const aim_subtype *aim_get_subtype( guint16 family, guint16 subtype);
int dissect_aim_tlv_value_string(proto_item *ti, guint16, tvbuff_t *);
int dissect_aim_tlv_value_uint8(proto_item *ti, guint16, tvbuff_t *);
int dissect_aim_tlv_value_uint16(proto_item *ti, guint16, tvbuff_t *);
int dissect_aim_tlv_value_uint32(proto_item *ti, guint16, tvbuff_t *);
int dissect_aim_tlv_value_bytes(proto_item *ti, guint16, tvbuff_t *);
int dissect_aim_tlv_value_ipv4(proto_item *ti, guint16, tvbuff_t *);
int dissect_aim_tlv_value_time(proto_item *ti, guint16, tvbuff_t *);
int dissect_aim_tlv_value_client_capabilities(proto_item *ti, guint16, tvbuff_t *);
int dissect_aim_tlv_value_string(proto_item *ti, guint16, tvbuff_t *, packet_info *);
int dissect_aim_tlv_value_uint8(proto_item *ti, guint16, tvbuff_t *, packet_info *);
int dissect_aim_tlv_value_uint16(proto_item *ti, guint16, tvbuff_t *, packet_info *);
int dissect_aim_tlv_value_uint32(proto_item *ti, guint16, tvbuff_t *, packet_info *);
int dissect_aim_tlv_value_bytes(proto_item *ti, guint16, tvbuff_t *, packet_info *);
int dissect_aim_tlv_value_ipv4(proto_item *ti, guint16, tvbuff_t *, packet_info *);
int dissect_aim_tlv_value_time(proto_item *ti, guint16, tvbuff_t *, packet_info *);
int dissect_aim_tlv_value_client_capabilities(proto_item *ti, guint16, tvbuff_t *, packet_info *);
int dissect_aim_capability(proto_tree *entry, tvbuff_t *tvb, int offset);
int dissect_aim_userclass(tvbuff_t *tvb, int offset, int len, proto_item *ti, guint32 flags);
int dissect_aim_tlv_value_userclass(proto_item *ti, guint16, tvbuff_t *);
int dissect_aim_tlv_value_messageblock (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb);
int dissect_aim_tlv_value_userclass(proto_item *ti, guint16, tvbuff_t *, packet_info *);
int dissect_aim_tlv_value_messageblock (proto_item *ti, guint16 valueid _U_, tvbuff_t *tvb, packet_info *);
extern const aim_tlv client_tlvs[];
extern const aim_tlv onlinebuddy_tlvs[];