From Jelmer Vernooij:
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 23 Sep 2004 17:40:36 +0000 (17:40 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 23 Sep 2004 17:40:36 +0000 (17:40 +0000)
- Dissect ICQ TLV values
- Dissect channel 1 and channel 2 messages correctly in Oscar (required
  for dissecting direct connections)

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@12072 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dissectors/packet-aim-icq.c
epan/dissectors/packet-aim-messaging.c
epan/dissectors/packet-aim-oft.c
epan/dissectors/packet-aim-signon.c
epan/dissectors/packet-aim.c
epan/dissectors/packet-aim.h

index 52b833f152fe5b39a7cc7feca35fae678cd7a0b1..0a1a9ba9a4eb202e2ffcb139a14cd8bf866b3104 100644 (file)
 
 #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 */
index b531889a4d7ecfeb9a25ceb428c8dadb729e90e9..47ea5bd381a0641f9e175f8c460cf94aaf390464 100644 (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 */
index a4c8ded9f05b8ded476a86b48f5bbb05ee7a3649..eabdb1e9425a4133673e98c9db2b87b5a561a614 100644 (file)
 
 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
index 7f35bad1ba0514522b33e162d49b85279d2c2c64..392ddaf36f97eecd6221d7712c98cf5c698bcfab 100644 (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 },
index 41b911f6f0fd76c19bb46e5853403057fe00f002..3c7f8efc61ad04c9218acb92a24cea75c40bc2d5 100644 (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_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;
index efacdd05d18bbe94df15eed7852d1e6ca427459e..b30556173bd3ad8adb333661e8a753a7f450f98e 100644 (file)
 #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[];