#include "packet-tcp.h"
#include "packet-aim.h"
-#include "prefs.h"
+#include <epan/prefs.h>
#define TCP_PORT_AIM 5190
};
-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
#define AIM_ONLINEBUDDY_UNKNOWN 0x000e
#define AIM_ONLINEBUDDY_SESSIONLEN 0x000f
#define AIM_ONLINEBUDDY_ICQSESSIONLEN 0x0010
+#define AIM_ONLINEBUDDY_AVAILMSG 0x001d
const aim_tlv onlinebuddy_tlvs[] = {
{ AIM_ONLINEBUDDY_USERCLASS, "User class", dissect_aim_tlv_value_userclass },
{ AIM_ONLINEBUDDY_STATUS, "Online status", dissect_aim_tlv_value_userstatus },
{ AIM_ONLINEBUDDY_IPADDR, "User IP Address", dissect_aim_tlv_value_ipv4 },
{ AIM_ONLINEBUDDY_DCINFO, "DC Info", dissect_aim_tlv_value_dcinfo},
- { AIM_ONLINEBUDDY_CAPINFO, "Capability Info", dissect_aim_tlv_value_bytes },
+ { AIM_ONLINEBUDDY_CAPINFO, "Capability Info", dissect_aim_tlv_value_client_capabilities },
{ AIM_ONLINEBUDDY_MEMBERSINCE, "Member since", dissect_aim_tlv_value_time },
{ AIM_ONLINEBUDDY_UNKNOWN, "Unknown", dissect_aim_tlv_value_uint16 },
{ AIM_ONLINEBUDDY_TIMEUPDATE, "Time update", dissect_aim_tlv_value_bytes },
{ AIM_ONLINEBUDDY_SESSIONLEN, "Session Length (sec)", dissect_aim_tlv_value_uint32 },
{ AIM_ONLINEBUDDY_ICQSESSIONLEN, "ICQ Session Length (sec)", dissect_aim_tlv_value_uint32 },
+ { AIM_ONLINEBUDDY_AVAILMSG, "Available Message", dissect_aim_tlv_value_bytes },
{ 0, "Unknown", NULL }
};
-struct aim_family {
- guint16 family;
- const char *name;
- const value_string *subtypes;
+#define DC_DISABLED 0x0000
+#define DC_HTTPS 0x0001
+#define DC_SOCKS 0x0002
+#define DC_NORMAL 0x0003
+#define DC_IMPOSSIBLE 0x0004
+
+static const value_string dc_types[] = {
+ { DC_DISABLED, "DC disabled" },
+ { DC_HTTPS, "DC thru firewall or HTTPS proxy" },
+ { DC_SOCKS, "DC thru SOCKS proxy" },
+ { DC_NORMAL, "Regular connection" },
+ { DC_IMPOSSIBLE, "DC not possible " },
+ { 0, "Unknown" },
+};
+
+#define PROTO_VERSION_ICQ98 0x0004
+#define PROTO_VERSION_ICQ99 0x0006
+#define PROTO_VERSION_ICQ2K 0x0007
+#define PROTO_VERSION_ICQ2K1 0x0008
+#define PROTO_VERSION_ICQLITE 0x0009
+#define PROTO_VERSION_ICQ2K3B 0x000A
+
+static const value_string protocol_versions[] = {
+ { PROTO_VERSION_ICQ98, "ICQ '98" },
+ { PROTO_VERSION_ICQ99, "ICQ '99" },
+ { PROTO_VERSION_ICQ2K, "ICQ 2000" },
+ { PROTO_VERSION_ICQ2K1, "ICQ 2001" },
+ { PROTO_VERSION_ICQLITE, "ICQ Lite" },
+ { PROTO_VERSION_ICQ2K3B, "ICQ 2003B" },
+ { 0, "Unknown" },
};
static GList *families = NULL;
static int hf_aim_messageblock_charsubset = -1;
static int hf_aim_messageblock_message = -1;
+static int hf_aim_dcinfo_ip = -1;
+static int hf_aim_dcinfo_tcpport = -1;
+static int hf_aim_dcinfo_type = -1;
+static int hf_aim_dcinfo_proto_version = -1;
+static int hf_aim_dcinfo_auth_cookie = -1;
+static int hf_aim_dcinfo_webport = -1;
+static int hf_aim_dcinfo_client_future = -1;
+static int hf_aim_dcinfo_last_info_update = -1;
+static int hf_aim_dcinfo_last_ext_info_update = -1;
+static int hf_aim_dcinfo_last_ext_status_update = -1;
+static int hf_aim_dcinfo_unknown = -1;
/* Initialize the subtree pointers */
static gint ett_aim = -1;
+static gint ett_aim_dcinfo = -1;
static gint ett_aim_buddyname= -1;
static gint ett_aim_fnac = -1;
static gint ett_aim_fnac_flags = -1;
}
}
-
-const char *aim_get_subtypename( guint16 famnum, guint16 subtype )
+const aim_subtype *aim_get_subtype( guint16 famnum, guint16 subtype )
{
GList *gl = families;
while(gl) {
- struct aim_family *fam = gl->data;
- if(fam->family == famnum) return match_strval(subtype, fam->subtypes);
+ aim_family *fam = gl->data;
+ if(fam->family == famnum) {
+ int i;
+ for(i = 0; fam->subtypes[i].name; i++) {
+ if(fam->subtypes[i].id == subtype) return &(fam->subtypes[i]);
+ }
+ }
gl = gl->next;
}
}
-const char *aim_get_familyname( guint16 famnum )
+const aim_family *aim_get_family( guint16 famnum )
{
GList *gl = families;
while(gl) {
- struct aim_family *fam = gl->data;
- if(fam->family == famnum) return fam->name;
+ aim_family *fam = gl->data;
+ if(fam->family == famnum) return fam;
gl = gl->next;
}
}
}
-void aim_init_family(guint16 family, const char *name, const value_string *subtypes)
+void aim_init_family(int proto, int ett, guint16 family, const aim_subtype *subtypes)
{
- struct aim_family *fam = g_new(struct aim_family, 1);
- fam->name = g_strdup(name);
+ aim_family *fam = g_new(aim_family, 1);
+ fam->proto = find_protocol_by_id(proto);
+ fam->name = proto_get_protocol_short_name(fam->proto);
fam->family = family;
fam->subtypes = subtypes;
families = g_list_append(families, fam);
+
+ fam->proto_id = proto;
+ fam->ett = ett;
}
static void dissect_aim_newconn(tvbuff_t *tvb, packet_info *pinfo,
if (tvb_length_remaining(tvb, offset) > 0) {
proto_tree_add_item(tree, hf_aim_authcookie, tvb, offset, 4, FALSE);
offset+=4;
- while(tvb_reported_length_remaining(tvb, offset) > 0) {
- offset = dissect_aim_tlv(tvb, pinfo, offset, tree, client_tlvs);
- }
+ offset = dissect_aim_tlv_sequence(tvb, pinfo, offset, tree, client_tlvs);
}
if (tvb_length_remaining(tvb, offset) > 0)
int dissect_aim_snac_error(tvbuff_t *tvb, packet_info *pinfo,
- int offset, proto_tree *aim_tree)
+ proto_tree *aim_tree)
{
char *name;
- if ((name = match_strval(tvb_get_ntohs(tvb, offset), aim_snac_errors)) != NULL) {
+ if ((name = match_strval(tvb_get_ntohs(tvb, 0), aim_snac_errors)) != NULL) {
if (check_col(pinfo->cinfo, COL_INFO))
col_add_fstr(pinfo->cinfo, COL_INFO, name);
}
proto_tree_add_item (aim_tree, hf_aim_snac_error,
- tvb, offset, 2, FALSE);
- return tvb_length_remaining(tvb, 2);
+ tvb, 0, 2, FALSE);
+
+ return dissect_aim_tlv_sequence(tvb, pinfo, 2, aim_tree, client_tlvs);
}
int dissect_aim_userinfo(tvbuff_t *tvb, packet_info *pinfo,
static void dissect_aim_snac(tvbuff_t *tvb, packet_info *pinfo,
int offset, proto_tree *aim_tree, proto_tree *root_tree)
{
- guint16 family;
- guint16 subtype;
+ guint16 family_id;
+ guint16 subtype_id;
guint16 flags;
guint32 id;
proto_item *ti1;
struct aiminfo aiminfo;
- const char *fam_name, *subtype_name;
proto_tree *aim_tree_fnac = NULL;
tvbuff_t *subtvb;
int orig_offset;
+ const aim_subtype *subtype;
+ proto_tree *family_tree = NULL;
+ const aim_family *family;
orig_offset = offset;
- family = tvb_get_ntohs(tvb, offset);
- fam_name = aim_get_familyname(family);
+ family_id = tvb_get_ntohs(tvb, offset);
+ family = aim_get_family(family_id);
offset += 2;
- subtype = tvb_get_ntohs(tvb, offset);
- subtype_name = aim_get_subtypename(family, subtype);
+ subtype_id = tvb_get_ntohs(tvb, offset);
+ subtype = aim_get_subtype(family_id, subtype_id);
offset += 2;
flags = tvb_get_ntohs(tvb, offset);
offset += 2;
id = tvb_get_ntohl(tvb, offset);
offset += 4;
- if (check_col(pinfo->cinfo, COL_INFO)) {
- col_add_fstr(pinfo->cinfo, COL_INFO, "SNAC data");
- }
-
+
if( aim_tree )
{
offset = orig_offset;
- ti1 = proto_tree_add_text(aim_tree, tvb, 6, 10, "FNAC");
+ ti1 = proto_tree_add_text(aim_tree, tvb, 6, 10, "FNAC: Family: 0x%04x, Subtype: %04x", family_id, subtype_id);
aim_tree_fnac = proto_item_add_subtree(ti1, ett_aim_fnac);
proto_tree_add_text (aim_tree_fnac,
- tvb, offset, 2, "Family: %s (0x%04x)", fam_name?fam_name:"Unknown", family);
+ tvb, offset, 2, "Family: %s (0x%04x)", family?family->name:"Unknown", family_id);
offset += 2;
proto_tree_add_text (aim_tree_fnac,
- tvb, offset, 2, "Subtype: %s (0x%04x)", subtype_name?subtype_name:"Unknown", subtype);
+ tvb, offset, 2, "Subtype: %s (0x%04x)", (subtype && subtype->name)?subtype->name:"Unknown", subtype_id);
offset += 2;
ti1 = proto_tree_add_uint(aim_tree_fnac, hf_aim_fnac_flags, tvb, offset,
subtvb = tvb_new_subset(tvb, offset, -1, -1);
aiminfo.tcpinfo = pinfo->private_data;
- aiminfo.family = family;
- aiminfo.subtype = subtype;
+ aiminfo.family = family_id;
+ aiminfo.subtype = subtype_id;
pinfo->private_data = &aiminfo;
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL) && family) {
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, family->name);
+ }
if (check_col(pinfo->cinfo, COL_INFO)) {
- if(fam_name) col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", fam_name);
- else col_append_fstr(pinfo->cinfo, COL_INFO, ", Family: 0x%04x", family);
- if(subtype_name) col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", subtype_name);
- else col_append_fstr(pinfo->cinfo, COL_INFO, ", Subtype: 0x%04x", subtype);
+ if(subtype) {
+ col_set_str(pinfo->cinfo, COL_INFO, family->name);
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", subtype->name);
+ } else {
+ col_set_str(pinfo->cinfo, COL_INFO, "SNAC data");
+
+ if(family) col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", family->name);
+ else col_append_fstr(pinfo->cinfo, COL_INFO, ", Family: 0x%04x", family_id);
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Subtype: 0x%04x", subtype_id);
+ }
+ }
+
+ if(aim_tree && family)
+ {
+ proto_item *ti = proto_tree_add_item(root_tree, family->proto_id, subtvb, 0, -1, FALSE);
+ family_tree = proto_item_add_subtree(ti, family->ett);
+ if(subtype) proto_item_append_text(ti, ", %s", subtype->name);
}
- if(tvb_length_remaining(tvb, offset) == 0 || !dissector_try_port(subdissector_table, family, subtvb, pinfo, root_tree)) {
- /* Show the undissected payload */
- if (tvb_length_remaining(tvb, offset) > 0)
- proto_tree_add_item(aim_tree, hf_aim_data, tvb, offset, -1, FALSE);
+ if(tvb_length_remaining(tvb, offset) > 0 && subtype && subtype->dissector) {
+ subtype->dissector(subtvb, pinfo, family_tree);
}
}
col_add_fstr(pinfo->cinfo, COL_INFO, "Close Connection");
}
- while(tvb_reported_length_remaining(tvb, offset) > 0) {
- offset = dissect_aim_tlv(tvb, pinfo, offset, tree, client_tlvs);
- }
+ offset = dissect_aim_tlv_sequence(tvb, pinfo, offset, tree, client_tlvs);
}
static void dissect_aim_unknown_channel(tvbuff_t *tvb, packet_info *pinfo,
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}}},
{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}}},
{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}}},
{0xf2e7c7f4, 0xfead, 0x4dfb,
{0xb2, 0x35, 0x36, 0x79, 0x8b, 0xdf, 0x00, 0x00}}},
- { "Unknown", {0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } } }
+ { "Unknown 1",
+ {0x0946f004, 0x4c7f, 0x11d1,
+ {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
+
+ { "Unknown 2",
+ {0x0946f004, 0x4c7f, 0x11d1,
+ {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
+
+ { "Unknown 3",
+ {0x09460103, 0x4c7f, 0x11d1,
+ {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
+
+ { "Unknown 4",
+ {0x0946f003, 0x4c7f, 0x11d1,
+ {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
+
+ { NULL, {0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } } }
};
+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_tlv_value_client_capabilities(proto_item *ti _U_, guint16 valueid _U_, tvbuff_t *tvb)
+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;
entry = proto_item_add_subtree(ti, ett_aim_client_capabilities);
while (tvb_length_remaining(tvb, offset) > 0) {
- int i;
- const aim_client_capabilities *caps;
- guint32 Data1 = tvb_get_ntoh24(tvb, offset);
- guint16 Data2 = tvb_get_ntohs(tvb, offset+4);
- guint16 Data3 = tvb_get_ntohs(tvb, offset+6);
- guint8 Data4[8];
- tvb_memcpy(tvb, Data4, offset+8, 8);
-
- caps = &client_caps[0];
-
- for(i = 0; !strcmp(client_caps[i].description, "Unknown"); i++) {
- caps = &client_caps[i];
-
- if(Data1 == caps->clsid.Data1 && Data2 == caps->clsid.Data2 &&
- Data3 == caps->clsid.Data3 && !memcmp(caps->clsid.Data4, Data4, 8))
- break;
- }
-
- proto_tree_add_text(entry, tvb, offset, 16,
- "%s {%06x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
- caps->description, Data1, Data2,
- Data3, Data4[0], Data4[1], Data4[2], Data4[3], Data4[4],
- Data4[5], Data4[6], 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);
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 _U_, 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_)
{
- /* FIXME */
- return tvb_length(tvb);
+ int offset = 0;
+
+ proto_tree *dctree = proto_item_add_subtree(ti, ett_aim_dcinfo);
+
+ proto_tree_add_item(dctree, hf_aim_dcinfo_ip , tvb, offset, 4, FALSE); offset+=4;
+ proto_tree_add_item(dctree, hf_aim_dcinfo_tcpport, tvb, offset, 4, FALSE); offset+=4;
+ proto_tree_add_item(dctree, hf_aim_dcinfo_type, tvb, offset, 1, FALSE); offset+=1;
+ proto_tree_add_item(dctree, hf_aim_dcinfo_proto_version, tvb, offset, 2, FALSE); offset+=2;
+ proto_tree_add_item(dctree, hf_aim_dcinfo_auth_cookie, tvb, offset, 4, FALSE); offset+=2;
+ proto_tree_add_item(dctree, hf_aim_dcinfo_webport, tvb, offset, 4, FALSE); offset+=4;
+ proto_tree_add_item(dctree, hf_aim_dcinfo_client_future, tvb, offset, 4, FALSE); offset+=4;
+ proto_tree_add_item(dctree, hf_aim_dcinfo_last_info_update, tvb, offset, 4, FALSE); offset+=4;
+ proto_tree_add_item(dctree, hf_aim_dcinfo_last_ext_info_update, tvb, offset, 4, FALSE); offset+=4;
+ proto_tree_add_item(dctree, hf_aim_dcinfo_last_ext_status_update, tvb, offset, 4, FALSE); offset+=4;
+ proto_tree_add_item(dctree, hf_aim_dcinfo_unknown, tvb, offset, 2, FALSE); offset+=2;
+
+ 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;
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;
"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;
return offset;
}
-int dissect_aim_tlv_list(tvbuff_t *tvb, packet_info *pinfo _U_,
+int dissect_aim_tlv_sequence(tvbuff_t *tvb, packet_info *pinfo,
+ int offset, proto_tree *tree, const aim_tlv *tlv_table)
+{
+ while (tvb_length_remaining(tvb, offset) > 0) {
+ offset = dissect_aim_tlv(tvb, pinfo, offset, tree, tlv_table);
+ }
+ return offset;
+}
+
+int dissect_aim_tlv_list(tvbuff_t *tvb, packet_info *pinfo,
int offset, proto_tree *tree, const aim_tlv *tlv_table)
{
guint16 i, tlv_count = tvb_get_ntohs(tvb, offset);
{ &hf_aim_messageblock_message,
{ "Message", "aim.messageblock.message", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL },
},
+ { &hf_aim_dcinfo_ip,
+ { "Internal IP address", "aim.dcinfo.addr", FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL },
+ },
+ { &hf_aim_dcinfo_tcpport,
+ { "TCP Port", "aim.dcinfo.tcpport", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL },
+ },
+ { &hf_aim_dcinfo_type,
+ { "Type", "aim.dcinfo.type", FT_UINT8, BASE_HEX, VALS(dc_types), 0x0, "", HFILL },
+ },
+ { &hf_aim_dcinfo_proto_version,
+ { "Protocol Version", "aim.dcinfo.proto_version", FT_UINT16, BASE_DEC, VALS(protocol_versions), 0x0, "", HFILL },
+ },
+ { &hf_aim_dcinfo_auth_cookie,
+ { "Authorization Cookie", "aim.dcinfo.auth_cookie", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL },
+ },
+ { &hf_aim_dcinfo_webport,
+ { "Web Front Port", "aim.dcinfo.webport", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL },
+ },
+ { &hf_aim_dcinfo_client_future,
+ { "Client Futures", "aim.dcinfo.client_futures", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL },
+ },
+ { &hf_aim_dcinfo_last_info_update,
+ { "Last Info Update", "aim.dcinfo.last_info_update", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL },
+ },
+ { &hf_aim_dcinfo_last_ext_info_update,
+ { "Last Extended Info Update", "aim.dcinfo.last_ext_info_update", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL },
+ },
+ { &hf_aim_dcinfo_last_ext_status_update,
+ { "Last Extended Status Update", "aim.dcinfo.last_ext_status_update", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL },
+ },
+ { &hf_aim_dcinfo_unknown,
+ { "Unknown", "aim.dcinfo.unknown", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL },
+ },
+
};
/* Setup protocol subtree array */
static gint *ett[] = {
&ett_aim,
+ &ett_aim_dcinfo,
&ett_aim_fnac,
&ett_aim_fnac_flags,
&ett_aim_tlv,