aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2004-09-23 17:40:36 +0000
committerGuy Harris <guy@alum.mit.edu>2004-09-23 17:40:36 +0000
commit285066ac5bfcf1569cb86a56cca9825f8e416ada (patch)
treeceb0d8814448bfe08595ed1b4e7c3535aa257fc1
parent91d4c8135b32b49f5c5dee418281367d06733fe2 (diff)
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
-rw-r--r--epan/dissectors/packet-aim-icq.c125
-rw-r--r--epan/dissectors/packet-aim-messaging.c94
-rw-r--r--epan/dissectors/packet-aim-oft.c39
-rw-r--r--epan/dissectors/packet-aim-signon.c22
-rw-r--r--epan/dissectors/packet-aim.c143
-rw-r--r--epan/dissectors/packet-aim.h26
6 files changed, 346 insertions, 103 deletions
diff --git a/epan/dissectors/packet-aim-icq.c b/epan/dissectors/packet-aim-icq.c
index 52b833f152..0a1a9ba9a4 100644
--- a/epan/dissectors/packet-aim-icq.c
+++ b/epan/dissectors/packet-aim-icq.c
@@ -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 */
diff --git a/epan/dissectors/packet-aim-messaging.c b/epan/dissectors/packet-aim-messaging.c
index b531889a4d..47ea5bd381 100644
--- a/epan/dissectors/packet-aim-messaging.c
+++ b/epan/dissectors/packet-aim-messaging.c
@@ -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 */
diff --git a/epan/dissectors/packet-aim-oft.c b/epan/dissectors/packet-aim-oft.c
index a4c8ded9f0..eabdb1e942 100644
--- a/epan/dissectors/packet-aim-oft.c
+++ b/epan/dissectors/packet-aim-oft.c
@@ -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
diff --git a/epan/dissectors/packet-aim-signon.c b/epan/dissectors/packet-aim-signon.c
index 7f35bad1ba..392ddaf36f 100644
--- a/epan/dissectors/packet-aim-signon.c
+++ b/epan/dissectors/packet-aim-signon.c
@@ -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 },
diff --git a/epan/dissectors/packet-aim.c b/epan/dissectors/packet-aim.c
index 41b911f6f0..3c7f8efc61 100644
--- a/epan/dissectors/packet-aim.c
+++ b/epan/dissectors/packet-aim.c
@@ -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_capabilities {
- const char *description;
- e_uuid_t clsid;
-} aim_client_capabilities;
-
-static const aim_client_capabilities client_caps[] = {
+typedef struct _aim_client_capability
+{
+ const char *name;
+ e_uuid_t clsid;
+} aim_client_capability;
+
+static const aim_client_capability known_client_caps[] = {
+ { "Send File",
+ {0x09461343, 0x4c7f, 0x11d1,
+ { 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
+
+ { "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,51 +990,69 @@ 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 offset = 0;
- proto_tree *entry;
+ int i;
- proto_item_set_text(ti, "Client Capabilities List");
+ for(i = 0; known_client_caps[i].name; i++)
+ {
+ const aim_client_capability *caps = &(known_client_caps[i]);
- 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;
+ 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;
+}
- 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);
+int dissect_aim_capability(proto_tree *entry, tvbuff_t *tvb, int offset)
+{
+ const aim_client_capability *caps = NULL;
+ e_uuid_t clsid;
- for(i = 0; client_caps[i].description; i++) {
+ 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);
- if(memcmp(&(client_caps[i].clsid), &clsid, sizeof(e_uuid_t)) == 0) {
- caps = &client_caps[i];
- break;
- }
- }
+ 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->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],
+ 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;
- offset+=16;
+ proto_item_set_text(ti, "Client Capabilities List");
+
+ entry = proto_item_add_subtree(ti, ett_aim_client_capabilities);
+
+ while (tvb_length_remaining(tvb, offset) > 0) {
+ 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;
diff --git a/epan/dissectors/packet-aim.h b/epan/dissectors/packet-aim.h
index efacdd05d1..b30556173b 100644
--- a/epan/dissectors/packet-aim.h
+++ b/epan/dissectors/packet-aim.h
@@ -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[];