X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=packet-aim.c;h=62719f75f1e3180059b4bb29aa39f6c6e2e6f508;hb=5141a54984eddfdd70625f40960f39f0744c1cc1;hp=83991ba44cff562dfe00305961b54538852d59e5;hpb=4ad4caac3465466d917054d2f911b18ba27b4fe0;p=obnox%2Fwireshark%2Fwip.git diff --git a/packet-aim.c b/packet-aim.c index 83991ba44c..62719f75f1 100644 --- a/packet-aim.c +++ b/packet-aim.c @@ -2,7 +2,7 @@ * Routines for AIM Instant Messenger (OSCAR) dissection * Copyright 2000, Ralf Hoelzer * - * $Id: packet-aim.c,v 1.16 2002/08/02 23:35:47 jmayer Exp $ + * $Id: packet-aim.c,v 1.31 2003/12/21 11:40:45 jmayer Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -12,12 +12,12 @@ * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. @@ -37,11 +37,20 @@ #include #include +#include "packet-tcp.h" +#include "prefs.h" + #define TCP_PORT_AIM 5190 #define MAX_BUDDYNAME_LENGTH 30 #define STRIP_TAGS 1 +typedef struct _aim_tlv { + guint16 valueid; + char *desc; + int datatype; +} aim_tlv; + /* channels */ #define CHANNEL_NEW_CONN 0x01 #define CHANNEL_SNAC_DATA 0x02 @@ -63,416 +72,695 @@ #define FAMILY_TRANSLATE 0x000C #define FAMILY_CHAT_NAV 0x000D #define FAMILY_CHAT 0x000E +#define FAMILY_SSI 0x0013 +#define FAMILY_ICQ 0x0015 #define FAMILY_SIGNON 0x0017 +#define FAMILY_OFT 0xfffe + +/* Family Signon */ +#define FAMILY_SIGNON_LOGON 0x0002 +#define FAMILY_SIGNON_LOGON_REPLY 0x0003 +#define FAMILY_SIGNON_SIGNON 0x0006 +#define FAMILY_SIGNON_SIGNON_REPLY 0x0007 + +/* Family Generic */ +#define FAMILY_GENERIC_ERROR 0x0001 +#define FAMILY_GENERIC_CLIENTREADY 0x0002 +#define FAMILY_GENERIC_SERVERREADY 0x0003 +#define FAMILY_GENERIC_SERVICEREQ 0x0004 +#define FAMILY_GENERIC_REDIRECT 0x0005 +#define FAMILY_GENERIC_RATEINFOREQ 0x0006 +#define FAMILY_GENERIC_RATEINFO 0x0007 +#define FAMILY_GENERIC_RATEINFOACK 0x0008 +#define FAMILY_GENERIC_UNKNOWNx09 0x0009 +#define FAMILY_GENERIC_RATECHANGE 0x000a +#define FAMILY_GENERIC_SERVERPAUSE 0x000b +#define FAMILY_GENERIC_SERVERRESUME 0x000d +#define FAMILY_GENERIC_REQSELFINFO 0x000e +#define FAMILY_GENERIC_SELFINFO 0x000f +#define FAMILY_GENERIC_EVIL 0x0010 +#define FAMILY_GENERIC_SETIDLE 0x0011 +#define FAMILY_GENERIC_MIGRATIONREQ 0x0012 +#define FAMILY_GENERIC_MOTD 0x0013 +#define FAMILY_GENERIC_SETPRIVFLAGS 0x0014 +#define FAMILY_GENERIC_WELLKNOWNURL 0x0015 +#define FAMILY_GENERIC_NOP 0x0016 +#define FAMILY_GENERIC_DEFAULT 0xffff + +/* Family Location Services */ +#define FAMILY_LOCATION_ERROR 0x0001 +#define FAMILY_LOCATION_REQRIGHTS 0x0002 +#define FAMILY_LOCATION_RIGHTSINFO 0x0003 +#define FAMILY_LOCATION_SETUSERINFO 0x0004 +#define FAMILY_LOCATION_REQUSERINFO 0x0005 +#define FAMILY_LOCATION_USERINFO 0x0006 +#define FAMILY_LOCATION_WATCHERSUBREQ 0x0007 +#define FAMILY_LOCATION_WATCHERNOT 0x0008 +#define FAMILY_LOCATION_DEFAULT 0xffff + +/* Family Buddy List */ +#define FAMILY_BUDDYLIST_ERROR 0x0001 +#define FAMILY_BUDDYLIST_REQRIGHTS 0x0002 +#define FAMILY_BUDDYLIST_RIGHTSINFO 0x0003 +#define FAMILY_BUDDYLIST_ADDBUDDY 0x0004 +#define FAMILY_BUDDYLIST_REMBUDDY 0x0005 +#define FAMILY_BUDDYLIST_REJECT 0x000a +#define FAMILY_BUDDYLIST_ONCOMING 0x000b +#define FAMILY_BUDDYLIST_OFFGOING 0x000c +#define FAMILY_BUDDYLIST_DEFAULT 0xffff + +/* Family Messaging Service */ +#define FAMILY_MESSAGING_ERROR 0x0001 +#define FAMILY_MESSAGING_PARAMINFO 0x0005 +#define FAMILY_MESSAGING_OUTGOING 0x0006 +#define FAMILY_MESSAGING_INCOMING 0x0007 +#define FAMILY_MESSAGING_EVIL 0x0009 +#define FAMILY_MESSAGING_MISSEDCALL 0x000a +#define FAMILY_MESSAGING_CLIENTAUTORESP 0x000b +#define FAMILY_MESSAGING_ACK 0x000c +#define FAMILY_MESSAGING_DEFAULT 0xffff + +/* Family Advertising */ +#define FAMILY_ADVERTS_ERROR 0x0001 +#define FAMILY_ADVERTS_REQUEST 0x0002 +#define FAMILY_ADVERTS_DATA 0x0003 +#define FAMILY_ADVERTS_DEFAULT 0xffff + +/* Family Invitation */ +#define FAMILY_INVITATION_ERROR 0x0001 +#define FAMILY_INVITATION_DEFAULT 0xffff + +/* Family Admin */ +#define FAMILY_ADMIN_ERROR 0x0001 +#define FAMILY_ADMIN_INFOCHANGEREPLY 0x0005 +#define FAMILY_ADMIN_DEFAULT 0xffff + +/* Family Popup */ +#define FAMILY_POPUP_ERROR 0x0001 +#define FAMILY_POPUP_DEFAULT 0xffff + +/* Family BOS (Misc) */ +#define FAMILY_BOS_ERROR 0x0001 +#define FAMILY_BOS_RIGHTSQUERY 0x0002 +#define FAMILY_BOS_RIGHTS 0x0003 +#define FAMILY_BOS_DEFAULT 0xffff + +/* Family User Lookup */ +#define FAMILY_USERLOOKUP_ERROR 0x0001 +#define FAMILY_USERLOOKUP_SEARCHEMAIL 0x0002 +#define FAMILY_USERLOOKUP_SEARCHRESULT 0x0003 +#define FAMILY_USERLOOKUP_DEFAULT 0xffff + +/* Family User Stats */ +#define FAMILY_STATS_ERROR 0x0001 +#define FAMILY_STATS_SETREPORTINTERVAL 0x0002 +#define FAMILY_STATS_REPORTACK 0x0004 +#define FAMILY_STATS_DEFAULT 0xffff + +/* Family Translation */ +#define FAMILY_TRANSLATE_ERROR 0x0001 +#define FAMILY_TRANSLATE_DEFAULT 0xffff + +/* Family Chat Navigation */ +#define FAMILY_CHATNAV_ERROR 0x0001 +#define FAMILY_CHATNAV_CREATE 0x0008 +#define FAMILY_CHATNAV_INFO 0x0009 +#define FAMILY_CHATNAV_DEFAULT 0xffff + +/* Family Chat */ +#define FAMILY_CHAT_ERROR 0x0001 +#define FAMILY_CHAT_ROOMINFOUPDATE 0x0002 +#define FAMILY_CHAT_USERJOIN 0x0003 +#define FAMILY_CHAT_USERLEAVE 0x0004 +#define FAMILY_CHAT_OUTGOINGMSG 0x0005 +#define FAMILY_CHAT_INCOMINGMSG 0x0006 +#define FAMILY_CHAT_DEFAULT 0xffff + +/* Family Server-Stored Buddy Lists */ +#define FAMILY_SSI_ERROR 0x0001 +#define FAMILY_SSI_REQRIGHTS 0x0002 +#define FAMILY_SSI_RIGHTSINFO 0x0003 +#define FAMILY_SSI_REQLIST 0x0005 +#define FAMILY_SSI_LIST 0x0006 +#define FAMILY_SSI_ACTIVATE 0x0007 +#define FAMILY_SSI_ADD 0x0008 +#define FAMILY_SSI_MOD 0x0009 +#define FAMILY_SSI_DEL 0x000a +#define FAMILY_SSI_SRVACK 0x000e +#define FAMILY_SSI_NOLIST 0x000f +#define FAMILY_SSI_EDITSTART 0x0011 +#define FAMILY_SSI_EDITSTOP 0x0012 + +/* Family ICQ */ +#define FAMILY_ICQ_ERROR 0x0001 +#define FAMILY_ICQ_LOGINREQUEST 0x0002 +#define FAMILY_ICQ_LOGINRESPONSE 0x0003 +#define FAMILY_ICQ_AUTHREQUEST 0x0006 +#define FAMILY_ICQ_AUTHRESPONSE 0x0007 + +static const value_string aim_fnac_family_ids[] = { + { FAMILY_GENERIC, "Generic" }, + { FAMILY_LOCATION, "Location" }, + { FAMILY_BUDDYLIST, "Buddy List" }, + { FAMILY_MESSAGING, "Messaging" }, + { FAMILY_ADVERTS, "Advertisement" }, + { FAMILY_INVITATION, "Invitation" }, + { FAMILY_ADMIN, "Admin" }, + { FAMILY_POPUP, "Popup" }, + { FAMILY_BOS, "Bos" }, + { FAMILY_USERLOOKUP, "User Lookup" }, + { FAMILY_STATS, "Stats" }, + { FAMILY_TRANSLATE, "Translate" }, + { FAMILY_CHAT_NAV, "Chat Nav" }, + { FAMILY_CHAT, "Chat" }, + { FAMILY_SSI, "Server Stored Info" }, + { FAMILY_ICQ, "ICQ" }, + { FAMILY_SIGNON, "Sign-on" }, + { FAMILY_OFT, "OFT/Rvous" }, + { 0, NULL } +}; + +static const value_string aim_fnac_family_signon[] = { + { FAMILY_SIGNON_LOGON, "Logon" }, + { FAMILY_SIGNON_LOGON_REPLY, "Logon Reply" }, + { FAMILY_SIGNON_SIGNON, "Sign-on" }, + { FAMILY_SIGNON_SIGNON_REPLY, "Sign-on Reply" }, + { 0, NULL } +}; + +static const value_string aim_fnac_family_generic[] = { + { FAMILY_GENERIC_ERROR, "Error" }, + { FAMILY_GENERIC_CLIENTREADY , "Client Ready" }, + { FAMILY_GENERIC_SERVERREADY, "Server Ready" }, + { FAMILY_GENERIC_SERVICEREQ, "Service Req" }, + { FAMILY_GENERIC_REDIRECT, "Redirect" }, + { FAMILY_GENERIC_RATEINFOREQ, "Rate Info Req" }, + { FAMILY_GENERIC_RATEINFO, "Rate Info" }, + { FAMILY_GENERIC_RATEINFOACK, "Rate Info Ack" }, + { FAMILY_GENERIC_UNKNOWNx09, "Unknown" }, + { FAMILY_GENERIC_RATECHANGE, "Rate Change" }, + { FAMILY_GENERIC_SERVERPAUSE, "Server Pause" }, + { FAMILY_GENERIC_SERVERRESUME, "Server Resume" }, + { FAMILY_GENERIC_REQSELFINFO, "Self Info Req" }, + { FAMILY_GENERIC_SELFINFO, "Self Info" }, + { FAMILY_GENERIC_EVIL, "Evil" }, + { FAMILY_GENERIC_SETIDLE, "Set Idle" }, + { FAMILY_GENERIC_MIGRATIONREQ, "Migration Req" }, + { FAMILY_GENERIC_MOTD, "MOTD" }, + { FAMILY_GENERIC_SETPRIVFLAGS, "Set Privilege Flags" }, + { FAMILY_GENERIC_WELLKNOWNURL, "Well Known URL" }, + { FAMILY_GENERIC_NOP, "noop" }, + { FAMILY_GENERIC_DEFAULT, "Generic Default" }, + { 0, NULL } +}; + +static const value_string aim_fnac_family_location[] = { + { FAMILY_LOCATION_ERROR, "Error" }, + { FAMILY_LOCATION_REQRIGHTS, "Request Rights" }, + { FAMILY_LOCATION_RIGHTSINFO, "Rights Info" }, + { FAMILY_LOCATION_SETUSERINFO, "Set User Info" }, + { FAMILY_LOCATION_REQUSERINFO, "Request User Info" }, + { FAMILY_LOCATION_USERINFO, "User Info" }, + { FAMILY_LOCATION_WATCHERSUBREQ, "Watcher Subrequest" }, + { FAMILY_LOCATION_WATCHERNOT, "Watcher Notification" }, + { FAMILY_LOCATION_DEFAULT, "Location Default" }, + { 0, NULL } +}; + +static const value_string aim_fnac_family_buddylist[] = { + { FAMILY_BUDDYLIST_ERROR, "Error" }, + { FAMILY_BUDDYLIST_REQRIGHTS, "Request Rights" }, + { FAMILY_BUDDYLIST_RIGHTSINFO, "Rights Info" }, + { FAMILY_BUDDYLIST_ADDBUDDY, "Add Buddy" }, + { FAMILY_BUDDYLIST_REMBUDDY, "Remove Buddy" }, + { FAMILY_BUDDYLIST_REJECT, "Reject Buddy" }, + { FAMILY_BUDDYLIST_ONCOMING, "Oncoming Buddy" }, + { FAMILY_BUDDYLIST_OFFGOING, "Offgoing Buddy" }, + { FAMILY_BUDDYLIST_DEFAULT, "Buddy Default" }, + { 0, NULL } +}; + +static const value_string aim_fnac_family_messaging[] = { + { FAMILY_MESSAGING_ERROR, "Error" }, + { FAMILY_MESSAGING_PARAMINFO, "Parameter Info" }, + { FAMILY_MESSAGING_INCOMING, "Incoming" }, + { FAMILY_MESSAGING_EVIL, "Evil" }, + { FAMILY_MESSAGING_MISSEDCALL, "Missed Call" }, + { FAMILY_MESSAGING_CLIENTAUTORESP, "Client Auto Response" }, + { FAMILY_MESSAGING_ACK, "Acknowledge" }, + { FAMILY_MESSAGING_DEFAULT, "Messaging Default" }, + { 0, NULL } +}; + +static const value_string aim_fnac_family_adverts[] = { + { FAMILY_ADVERTS_ERROR, "Error" }, + { FAMILY_ADVERTS_REQUEST, "Request" }, + { FAMILY_ADVERTS_DATA, "Data (GIF)" }, + { FAMILY_ADVERTS_DEFAULT, "Adverts Default" }, + { 0, NULL } +}; + +static const value_string aim_fnac_family_invitation[] = { + { FAMILY_INVITATION_ERROR, "Error" }, + { FAMILY_INVITATION_DEFAULT, "Invitation Default" }, + { 0, NULL } +}; + +static const value_string aim_fnac_family_admin[] = { + { FAMILY_ADMIN_ERROR, "Error" }, + { FAMILY_ADMIN_INFOCHANGEREPLY, "Infochange reply" }, + { FAMILY_ADMIN_DEFAULT, "Adminstrative Default" }, + { 0, NULL } +}; + +static const value_string aim_fnac_family_popup[] = { + { FAMILY_POPUP_ERROR, "Error" }, + { FAMILY_POPUP_DEFAULT, "Popup Default" }, + { 0, NULL } +}; + +static const value_string aim_fnac_family_bos[] = { + { FAMILY_BOS_ERROR, "Error" }, + { FAMILY_BOS_RIGHTSQUERY, "Rights Query" }, + { FAMILY_BOS_RIGHTS, "Rights" }, + { FAMILY_BOS_DEFAULT, "BOS Default" }, + { 0, NULL } +}; + +static const value_string aim_fnac_family_userlookup[] = { + { FAMILY_USERLOOKUP_ERROR, "Error" }, + { FAMILY_USERLOOKUP_DEFAULT, "Userlookup Default" }, + { 0, NULL } +}; -/* messaging */ -#define MSG_TO_CLIENT 0x006 -#define MSG_FROM_CLIENT 0x007 +static const value_string aim_fnac_family_stats[] = { + { FAMILY_STATS_ERROR, "Error" }, + { FAMILY_STATS_SETREPORTINTERVAL, "Set Report Interval" }, + { FAMILY_STATS_REPORTACK, "Report Ack" }, + { FAMILY_STATS_DEFAULT, "Stats Default" }, + { 0, NULL } +}; + +static const value_string aim_fnac_family_translate[] = { + { FAMILY_TRANSLATE_ERROR, "Error" }, + { FAMILY_TRANSLATE_DEFAULT, "Translate Default" }, + { 0, NULL } +}; + +static const value_string aim_fnac_family_chatnav[] = { + { FAMILY_CHATNAV_ERROR, "Error" }, + { FAMILY_CHATNAV_CREATE, "Create" }, + { FAMILY_CHATNAV_INFO, "Info" }, + { FAMILY_CHATNAV_DEFAULT, "ChatNav Default" }, + { 0, NULL } +}; + +static const value_string aim_fnac_family_chat[] = { + { FAMILY_CHAT_ERROR, "Error" }, + { FAMILY_CHAT_USERJOIN, "User Join" }, + { FAMILY_CHAT_USERLEAVE, "User Leave" }, + { FAMILY_CHAT_OUTGOINGMSG, "Outgoing Message" }, + { FAMILY_CHAT_INCOMINGMSG, "Incoming Message" }, + { FAMILY_CHAT_DEFAULT, "Chat Default" }, + { 0, NULL } +}; -static void dissect_aim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); +static const value_string aim_fnac_family_ssi[] = { + { FAMILY_SSI_ERROR, "Error" }, + { FAMILY_SSI_REQRIGHTS, "Request Rights" }, + { FAMILY_SSI_RIGHTSINFO, "Rights Info" }, + { FAMILY_SSI_REQLIST, "Request List" }, + { FAMILY_SSI_LIST, "List" }, + { FAMILY_SSI_ACTIVATE, "Activate" }, + { FAMILY_SSI_ADD, "Add Buddy" }, + { FAMILY_SSI_MOD, "Modify Buddy" }, + { FAMILY_SSI_DEL, "Delete Buddy" }, + { FAMILY_SSI_SRVACK, "Server Ack" }, + { FAMILY_SSI_NOLIST, "No List" }, + { FAMILY_SSI_EDITSTART, "Edit Start" }, + { FAMILY_SSI_EDITSTOP, "Edit Stop" }, + { 0, NULL } +}; + +#define FAMILY_SSI_TYPE_BUDDY 0x0000 +#define FAMILY_SSI_TYPE_GROUP 0x0001 +#define FAMILY_SSI_TYPE_PERMIT 0x0002 +#define FAMILY_SSI_TYPE_DENY 0x0003 +#define FAMILY_SSI_TYPE_PDINFO 0x0004 +#define FAMILY_SSI_TYPE_PRESENCEPREFS 0x0005 +#define FAMILY_SSI_TYPE_ICONINFO 0x0014 + +static const value_string aim_fnac_family_ssi_types[] = { + { FAMILY_SSI_TYPE_BUDDY, "Buddy" }, + { FAMILY_SSI_TYPE_GROUP, "Group" }, + { FAMILY_SSI_TYPE_PERMIT, "Permit" }, + { FAMILY_SSI_TYPE_DENY, "Deny" }, + { FAMILY_SSI_TYPE_PDINFO, "PDINFO" }, + { FAMILY_SSI_TYPE_PRESENCEPREFS, "Presence Preferences" }, + { FAMILY_SSI_TYPE_ICONINFO, "Icon Info" }, + { 0, NULL } +}; + +static const value_string aim_fnac_family_icq[] = { + { FAMILY_ICQ_ERROR, "Error" }, + { FAMILY_ICQ_LOGINREQUEST, "Login Request" }, + { FAMILY_ICQ_LOGINRESPONSE, "Login Response" }, + { FAMILY_ICQ_AUTHREQUEST, "Auth Request" }, + { FAMILY_ICQ_AUTHRESPONSE, "Auth Response" }, + { 0, NULL } +}; + +#define SIGNON_SCREENNAME 0x0001 +#define SIGNON_PASSWORD 0x0025 +#define SIGNON_CLIENTSTRING 0x0003 +#define SIGNON_CLIENTMAJOR 0x0017 +#define SIGNON_CLIENTMINOR 0x0018 +#define SIGNON_CLIENTPOINT 0x0019 +#define SIGNON_CLIENTBUILD 0x001a +#define SIGNON_CLIENTCOUNTRY 0x000e +#define SIGNON_CLIENTLANGUAGE 0x000f +#define SIGNON_CLIENTUSESSI 0x004a + +static const aim_tlv aim_signon_signon_tlv[] = { + { SIGNON_SCREENNAME, "Screen Name", FT_STRING }, + { SIGNON_PASSWORD, "Signon Challenge Response", FT_BYTES }, + { SIGNON_CLIENTSTRING, "Login Request", FT_STRING }, + { SIGNON_CLIENTMAJOR, "Client Major Version", FT_UINT16 }, + { SIGNON_CLIENTMINOR, "Client Minor Version", FT_UINT16 }, + { SIGNON_CLIENTPOINT, "Client Point", FT_UINT16 }, + { SIGNON_CLIENTBUILD, "Client Build", FT_UINT16 }, + { SIGNON_CLIENTCOUNTRY, "Client Country", FT_STRING }, + { SIGNON_CLIENTLANGUAGE, "Client Language", FT_STRING }, + { SIGNON_CLIENTUSESSI, "Use SSI", FT_UINT8 }, + { 0, "Unknown", 0 } +}; + +#define SIGNON_LOGON_REPLY_SCREENNAME 0x0001 +#define SIGNON_LOGON_REPLY_ERRORURL 0x0004 +#define SIGNON_LOGON_REPLY_BOSADDR 0x0005 +#define SIGNON_LOGON_REPLY_AUTHCOOKIE 0x0006 +#define SIGNON_LOGON_REPLY_ERRORCODE 0x0008 +#define SIGNON_LOGON_REPLY_EMAILADDR 0x0011 +#define SIGNON_LOGON_REPLY_REGSTATUS 0x0013 +#define SIGNON_LOGON_REPLY_LATESTBETABUILD 0x0040 +#define SIGNON_LOGON_REPLY_LATESTBETAURL 0x0041 +#define SIGNON_LOGON_REPLY_LATESTBETAINFO 0x0042 +#define SIGNON_LOGON_REPLY_LATESTBETANAME 0x0043 +#define SIGNON_LOGON_REPLY_LATESTRELEASEBUILD 0x0044 +#define SIGNON_LOGON_REPLY_LATESTRELEASEURL 0x0045 +#define SIGNON_LOGON_REPLY_LATESTRELEASEINFO 0x0046 +#define SIGNON_LOGON_REPLY_LATESTRELEASENAME 0x0047 + +static const aim_tlv aim_signon_logon_reply_tlv[] = { + { SIGNON_LOGON_REPLY_SCREENNAME, "Screen Name", FT_STRING }, + { SIGNON_LOGON_REPLY_ERRORURL, "Error URL", FT_STRING }, + { SIGNON_LOGON_REPLY_BOSADDR, "BOS Server Address", FT_STRING }, + { SIGNON_LOGON_REPLY_AUTHCOOKIE, "Authorization Cookie", FT_BYTES }, + { SIGNON_LOGON_REPLY_ERRORCODE, "Error Code", FT_UINT16 }, + { SIGNON_LOGON_REPLY_EMAILADDR, "Account Email Address", FT_STRING }, + { SIGNON_LOGON_REPLY_REGSTATUS, "Registration Status", FT_UINT16 }, + { SIGNON_LOGON_REPLY_LATESTBETABUILD, "Latest Beta Build", FT_UINT32 }, + { SIGNON_LOGON_REPLY_LATESTBETAURL, "Latest Beta URL", FT_STRING }, + { SIGNON_LOGON_REPLY_LATESTBETAINFO, "Latest Beta Info", FT_STRING }, + { SIGNON_LOGON_REPLY_LATESTBETANAME, "Latest Beta Name", FT_STRING }, + { SIGNON_LOGON_REPLY_LATESTRELEASEBUILD, "Latest Release Build", FT_UINT32 }, + { SIGNON_LOGON_REPLY_LATESTRELEASEURL, "Latest Release URL", FT_STRING }, + { SIGNON_LOGON_REPLY_LATESTRELEASEINFO, "Latest Release Info", FT_STRING }, + { SIGNON_LOGON_REPLY_LATESTRELEASENAME, "Latest Release Name", FT_STRING }, + { 0, "Unknown", 0 } +}; + +#define FAMILY_BUDDYLIST_USERFLAGS 0x0001 +#define FAMILY_BUDDYLIST_MEMBERSINCE 0x0002 +#define FAMILY_BUDDYLIST_ONSINCE 0x0003 +#define FAMILY_BUDDYLIST_IDLETIME 0x0004 +#define FAMILY_BUDDYLIST_ICQSTATUS 0x0006 +#define FAMILY_BUDDYLIST_ICQIPADDR 0x000a +#define FAMILY_BUDDYLIST_ICQSTUFF 0x000c +#define FAMILY_BUDDYLIST_CAPINFO 0x000d +#define FAMILY_BUDDYLIST_UNKNOWN 0x000e +#define FAMILY_BUDDYLIST_SESSIONLEN 0x000f +#define FAMILY_BUDDYLIST_ICQSESSIONLEN 0x0010 + +static const aim_tlv aim_fnac_family_buddylist_oncoming_tlv[] = { + { FAMILY_BUDDYLIST_USERFLAGS, "User flags", FT_UINT16 }, + { FAMILY_BUDDYLIST_MEMBERSINCE, "Member since date", FT_UINT32 }, + { FAMILY_BUDDYLIST_ONSINCE, "Online since", FT_UINT32 }, + { FAMILY_BUDDYLIST_IDLETIME, "Idle time (sec)", FT_UINT16 }, + { FAMILY_BUDDYLIST_ICQSTATUS, "ICQ Online status", FT_UINT16 }, + { FAMILY_BUDDYLIST_ICQIPADDR, "ICQ User IP Address", FT_UINT16 }, + { FAMILY_BUDDYLIST_ICQSTUFF, "ICQ Info", FT_BYTES }, + { FAMILY_BUDDYLIST_CAPINFO, "Capability Info", FT_BYTES }, + { FAMILY_BUDDYLIST_UNKNOWN, "Unknown", FT_UINT16 }, + { FAMILY_BUDDYLIST_SESSIONLEN, "Session Length (sec)", FT_UINT32 }, + { FAMILY_BUDDYLIST_SESSIONLEN, "ICQ Session Length (sec)", FT_UINT32 }, + { 0, "Unknown", 0 } +}; + + +#define FAMILY_LOCATION_USERINFO_INFOENCODING 0x0001 +#define FAMILY_LOCATION_USERINFO_INFOMSG 0x0002 +#define FAMILY_LOCATION_USERINFO_AWAYENCODING 0x0003 +#define FAMILY_LOCATION_USERINFO_AWAYMSG 0x0004 +#define FAMILY_LOCATION_USERINFO_CAPS 0x0005 + +static const aim_tlv aim_fnac_family_location_userinfo_tlv[] = { + { FAMILY_LOCATION_USERINFO_INFOENCODING, "Info Msg Encoding", FT_STRING }, + { FAMILY_LOCATION_USERINFO_INFOMSG, "Info Message", FT_STRING }, + { FAMILY_LOCATION_USERINFO_AWAYENCODING, "Away Msg Encoding", FT_STRING }, + { FAMILY_LOCATION_USERINFO_AWAYMSG, "Away Message", FT_STRING }, + { FAMILY_LOCATION_USERINFO_CAPS, "Capabilities", FT_BYTES }, + { 0, "Unknown", 0 } +}; + +#define FAMILY_LOCATION_USERINFO_INFOTYPE_GENERALINFO 0x0001 +#define FAMILY_LOCATION_USERINFO_INFOTYPE_AWAYMSG 0x0003 +#define FAMILY_LOCATION_USERINFO_INFOTYPE_CAPS 0x0005 + +static const value_string aim_snac_location_request_user_info_infotypes[] = { + { FAMILY_LOCATION_USERINFO_INFOTYPE_GENERALINFO, "Request General Info" }, + { FAMILY_LOCATION_USERINFO_INFOTYPE_AWAYMSG, "Request Away Message" }, + { FAMILY_LOCATION_USERINFO_INFOTYPE_CAPS, "Request Capabilities" }, + { 0, NULL } +}; + +static int dissect_aim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); +static guint get_aim_pdu_len(tvbuff_t *tvb, int offset); +static void dissect_aim_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); static void get_message( guchar *msg, tvbuff_t *tvb, int msg_offset, int msg_length); static int get_buddyname( char *name, tvbuff_t *tvb, int len_offset, int name_offset); +static void dissect_aim_newconn(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree); +static void dissect_aim_snac(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree); +static void dissect_aim_snac_fnac_subtype(tvbuff_t *tvb, int offset, + proto_tree *tree, guint16 family); +static void dissect_aim_snac_signon(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree, + guint16 subtype); +static void dissect_aim_snac_signon_logon(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree); +static void dissect_aim_snac_signon_logon_reply(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree); +static void dissect_aim_snac_signon_signon(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree); +static void dissect_aim_snac_signon_signon_reply(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree); +static void dissect_aim_snac_generic(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree, + guint16 subtype); +static void dissect_aim_snac_buddylist(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree, + guint16 subtype); +static void dissect_aim_snac_location(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree, + guint16 subtype); +static void dissect_aim_snac_location_request_user_information(tvbuff_t *tvb, int offset, proto_tree *tree); +static void dissect_aim_snac_location_user_information(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree); +static void dissect_aim_snac_adverts(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree, + guint16 subtype); +static void dissect_aim_snac_userlookup(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree, + guint16 subtype); +static void dissect_aim_snac_chat(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree, + guint16 subtype); +static void dissect_aim_snac_messaging(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree, + guint16 subtype); +static void dissect_aim_snac_ssi(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree, + guint16 subtype); +static void dissect_aim_snac_ssi_list(tvbuff_t *tvb, packet_info *pinfo _U_, + int offset, proto_tree *tree, + guint16 subtype _U_); +static void dissect_aim_flap_err(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree); +static void dissect_aim_close_conn(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree); +static void dissect_aim_unknown_channel(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree); +static int dissect_aim_tlv(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree, const aim_tlv *tlv); /* Initialize the protocol and registered fields */ static int proto_aim = -1; static int hf_aim_cmd_start = -1; static int hf_aim_channel = -1; static int hf_aim_seqno = -1; +static int hf_aim_data = -1; static int hf_aim_data_len = -1; +static int hf_aim_signon_challenge_len = -1; +static int hf_aim_signon_challenge = -1; static int hf_aim_fnac_family = -1; static int hf_aim_fnac_subtype = -1; +static int hf_aim_fnac_subtype_signon = -1; +static int hf_aim_fnac_subtype_generic = -1; +static int hf_aim_fnac_subtype_location = -1; +static int hf_aim_fnac_subtype_buddylist = -1; +static int hf_aim_fnac_subtype_messaging = -1; +static int hf_aim_fnac_subtype_adverts = -1; +static int hf_aim_fnac_subtype_invitation = -1; +static int hf_aim_fnac_subtype_admin = -1; +static int hf_aim_fnac_subtype_popup = -1; +static int hf_aim_fnac_subtype_bos = -1; +static int hf_aim_fnac_subtype_userlookup = -1; +static int hf_aim_fnac_subtype_stats = -1; +static int hf_aim_fnac_subtype_translate = -1; +static int hf_aim_fnac_subtype_chatnav = -1; +static int hf_aim_fnac_subtype_chat = -1; +static int hf_aim_fnac_subtype_ssi = -1; +static int hf_aim_fnac_subtype_ssi_version = -1; +static int hf_aim_fnac_subtype_ssi_numitems = -1; +static int hf_aim_fnac_subtype_ssi_buddyname_len = -1; +static int hf_aim_fnac_subtype_ssi_buddyname = -1; +static int hf_aim_fnac_subtype_ssi_gid = -1; +static int hf_aim_fnac_subtype_ssi_bid = -1; +static int hf_aim_fnac_subtype_ssi_type = -1; +static int hf_aim_fnac_subtype_ssi_tlvlen = -1; +static int hf_aim_fnac_subtype_ssi_data = -1; +static int hf_aim_fnac_subtype_icq = -1; +static int hf_aim_fnac_flags = -1; +static int hf_aim_fnac_id = -1; +static int hf_aim_infotype = -1; +static int hf_aim_snac_location_request_user_info_infotype = -1; +static int hf_aim_buddyname_len = -1; +static int hf_aim_buddyname = -1; +static int hf_aim_userinfo_warninglevel = -1; +static int hf_aim_userinfo_tlvcount = -1; /* Initialize the subtree pointers */ static gint ett_aim = -1; static gint ett_aim_fnac = -1; +static gint ett_aim_tlv = -1; +static gint ett_aim_ssi = -1; + +/* desegmentation of AIM over TCP */ +static gboolean aim_desegment = TRUE; /* Code to actually dissect the packets */ -static void dissect_aim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +static int dissect_aim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ +/* check, if this is really an AIM packet, they start with 0x2a */ +/* XXX - I've seen some stuff starting with 0x5a followed by 0x2a */ + + if(tvb_bytes_exist(tvb, 0, 1) && tvb_get_guint8(tvb, 0) != 0x2a) { + /* Not an instant messenger packet, just happened to use the same port */ + /* XXX - if desegmentation disabled, this might be a continuation + packet, not a non-AIM packet */ + return 0; + } + + tcp_dissect_pdus(tvb, pinfo, tree, aim_desegment, 6, get_aim_pdu_len, + dissect_aim_pdu); + return tvb_length(tvb); +} + +static guint get_aim_pdu_len(tvbuff_t *tvb, int offset) +{ + guint16 plen; + + /* + * Get the length of the AIM packet. + */ + plen = tvb_get_ntohs(tvb, offset + 4); + + /* + * That length doesn't include the length of the header itself; add that in. + */ + return plen + 6; +} + +static void dissect_aim_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Header fields */ unsigned char hdr_channel; /* channel ID */ unsigned short hdr_sequence_no; /* Internal frame sequence number, not needed */ unsigned short hdr_data_field_length; /* length of data within frame */ - guint16 family; - guint16 subtype; - guint8 buddyname_length = 0; - char buddyname[MAX_BUDDYNAME_LENGTH]; - guchar msg[1000]; + int offset=0; /* Set up structures we will need to add the protocol subtree and manage it */ proto_item *ti; - proto_item *ti1; proto_tree *aim_tree = NULL; - proto_tree *aim_tree_fnac = NULL; - -/* check, if this is really an AIM packet, they start with 0x2a */ - if(!(tvb_get_guint8(tvb, 0) == 0x2a)) { - /* Not an instant messenger packet, just happened to use the same port */ - return; - } - /* Make entries in Protocol column and Info column on summary display */ - if (check_col(pinfo->cinfo, COL_PROTOCOL)) + if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "AIM"); - - if (check_col(pinfo->cinfo, COL_INFO)) - col_add_str(pinfo->cinfo, COL_INFO, "AOL Instant Messenger"); -/* get relevant header information */ + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_str(pinfo->cinfo, COL_INFO, "AOL Instant Messenger"); - hdr_channel = tvb_get_guint8(tvb, 1); - hdr_sequence_no = tvb_get_ntohs(tvb, 2); - hdr_data_field_length = tvb_get_ntohs(tvb, 4); + /* get relevant header information */ + offset += 1; /* XXX - put the identifier into the tree? */ + hdr_channel = tvb_get_guint8(tvb, offset); + offset += 1; + hdr_sequence_no = tvb_get_ntohs(tvb, offset); + offset += 2; + hdr_data_field_length = tvb_get_ntohs(tvb, offset); + offset += 2; /* In the interest of speed, if "tree" is NULL, don't do any work not necessary to generate protocol tree items. */ if (tree) { - - ti = proto_tree_add_item(tree, proto_aim, tvb, 0, -1, FALSE); + + ti = proto_tree_add_item(tree, proto_aim, tvb, 0, -1, FALSE); aim_tree = proto_item_add_subtree(ti, ett_aim); - proto_tree_add_uint(aim_tree, hf_aim_cmd_start, tvb, 0, 1, '*'); + proto_tree_add_uint(aim_tree, hf_aim_cmd_start, tvb, 0, 1, '*'); proto_tree_add_uint(aim_tree, hf_aim_channel, tvb, 1, 1, hdr_channel); proto_tree_add_uint(aim_tree, hf_aim_seqno, tvb, 2, 2, hdr_sequence_no); proto_tree_add_uint(aim_tree, hf_aim_data_len, tvb, 4, 2, hdr_data_field_length); } - - switch(hdr_channel) { /* New connection request */ case CHANNEL_NEW_CONN: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "New Connection"); + dissect_aim_newconn(tvb, pinfo, offset, aim_tree); break; - - /* SNAC channel. Most packets are of this type, such as messages or buddy list - * management. - */ case CHANNEL_SNAC_DATA: - family = tvb_get_ntohs(tvb, 6); - subtype = tvb_get_ntohs(tvb, 8); - - if (check_col(pinfo->cinfo, COL_INFO)) { - col_add_fstr(pinfo->cinfo, COL_INFO, "SNAC data"); - } - if( tree ) - { - ti1 = proto_tree_add_text(aim_tree, tvb, 6, tvb_length(tvb) - 6, "FNAC"); - aim_tree_fnac = proto_item_add_subtree(ti1, ett_aim_fnac); - proto_tree_add_uint(aim_tree_fnac, hf_aim_fnac_family, tvb, 6, 2, family); - proto_tree_add_uint(aim_tree_fnac, hf_aim_fnac_subtype, tvb, 8, 2, subtype); - } - - - - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Family: 0x%04x - Subtype: 0x%04x (unknown)", family, subtype); - - switch(family) - { - case FAMILY_SIGNON: - switch(subtype) - { - case 0x0002: - buddyname_length = get_buddyname( buddyname, tvb, 19, 20 ); - - if (check_col(pinfo->cinfo, COL_INFO)) { - col_add_fstr(pinfo->cinfo, COL_INFO, "Login"); - col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", buddyname); - } - - if( tree ) - { - proto_tree_add_text(aim_tree_fnac, tvb, 20, buddyname_length, "Screen Name: %s", buddyname); - } - - break; - case 0x0003: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Login information reply"); - break; - case 0x0006: - buddyname_length = get_buddyname( buddyname, tvb, 19, 20 ); - - if (check_col(pinfo->cinfo, COL_INFO)) { - col_add_fstr(pinfo->cinfo, COL_INFO, "Sign-on"); - col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", buddyname); - } - - if( tree ) - { - proto_tree_add_text(aim_tree_fnac, tvb, 20, buddyname_length, "Screen Name: %s", buddyname); - } - - break; - case 0x0007: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Sign-on reply"); - break; - } - break; - - case FAMILY_GENERIC: - switch(subtype) - { - case 0x0002: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Client is now online and ready for normal function"); - break; - case 0x0003: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Server is now ready for normal functions"); - break; - case 0x0004: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Request for new service (server will redirect client)"); - break; - case 0x0005: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Redirect response"); - break; - case 0x0006: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Request Rate Information"); - break; - case 0x0007: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Rate information response"); - break; - case 0x0008: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Rate Information Response Ack"); - break; - case 0x0016: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "No-op"); - break; - } - break; - - case FAMILY_BUDDYLIST: - switch(subtype) - { - case 0x0001: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Buddylist - Error"); - break; - - case 0x0002: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Request Rights information"); - break; - - case 0x0003: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Rights information"); - break; - - case 0x0004: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Add to Buddylist"); - break; - - case 0x0005: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Remove from Buddylist"); - break; - - case 0x000b: - buddyname_length = get_buddyname( buddyname, tvb, 16, 17 ); - - if (check_col(pinfo->cinfo, COL_INFO)) { - col_add_fstr(pinfo->cinfo, COL_INFO, "Oncoming Buddy"); - col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", buddyname); - } - - if( tree ) - { - proto_tree_add_text(aim_tree_fnac, tvb, 17, buddyname_length, "Screen Name: %s", buddyname); - } - - break; - - case 0x000c: - - buddyname_length = get_buddyname( buddyname, tvb, 16, 17 ); - - if (check_col(pinfo->cinfo, COL_INFO)) { - col_add_fstr(pinfo->cinfo, COL_INFO, "Offgoing Buddy"); - col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", buddyname); - } - - if( tree ) - { - proto_tree_add_text(aim_tree_fnac, tvb, 17, buddyname_length, "Screen Name: %s", buddyname); - } - - - break; - } - break; - - case FAMILY_LOCATION: - switch(subtype) - { - case 0x0001: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Location - Error"); - break; - case 0x0002: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Request Rights Information"); - break; - case 0x0003: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Rights Information"); - break; - case 0x0004: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Set User Information"); - break; - case 0x0005: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Request User Information"); - break; - case 0x0006: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "User Information"); - break; - case 0x0007: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Watcher Subrequest"); - break; - case 0x0008: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Watcher Notification"); - break; - } - break; - - case FAMILY_ADVERTS: - switch(subtype) - { - case 0x0001: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Advertisements - Error"); - break; - case 0x0002: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Advertisement Request"); - break; - case 0x0003: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Advertisement data (GIF)"); - break; - } - break; - - case FAMILY_USERLOOKUP: - switch(subtype) - { - case 0x0001: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Search - Error (could be: not found)"); - break; - case 0x0002: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Search for Screen Name by e-mail"); - break; - case 0x0003: - if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Screen Name Search Result"); - break; - } - break; - - case FAMILY_CHAT: - switch(subtype) - { - case 0x005: - /* channel message from client */ - get_message( msg, tvb, 40 + buddyname_length, tvb_length(tvb) - 40 - buddyname_length ); - - if (check_col(pinfo->cinfo, COL_INFO)) { - col_add_fstr(pinfo->cinfo, COL_INFO, "Chat Message "); - col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg); - } - break; - - case 0x006: - /* channel message to client */ - buddyname_length = get_buddyname( buddyname, tvb, 30, 31 ); - get_message( msg, tvb, 36 + buddyname_length, tvb_length(tvb) - 36 - buddyname_length ); - - if (check_col(pinfo->cinfo, COL_INFO)) { - col_add_fstr(pinfo->cinfo, COL_INFO, "Chat Message "); - col_append_fstr(pinfo->cinfo, COL_INFO, "from: %s", buddyname); - col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg); - } - - if( tree ) - { - proto_tree_add_text(aim_tree_fnac, tvb, 31, buddyname_length, "Screen Name: %s", buddyname); - } - break; - } - break; - - - case FAMILY_MESSAGING: - switch(subtype) - { - case MSG_TO_CLIENT: - buddyname_length = get_buddyname( buddyname, tvb, 26, 27 ); - - get_message( msg, tvb, 36 + buddyname_length, tvb_length(tvb) - 36 - buddyname_length ); - - if (check_col(pinfo->cinfo, COL_INFO)) { - col_add_fstr(pinfo->cinfo, COL_INFO, "Message "); - col_append_fstr(pinfo->cinfo, COL_INFO, "to: %s", buddyname); - col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg); - } - - if( tree ) - { - proto_tree_add_text(aim_tree_fnac, tvb, 27, buddyname_length, "Screen Name: %s", buddyname); - } - - break; - - case MSG_FROM_CLIENT: - buddyname_length = get_buddyname( buddyname, tvb, 26, 27 ); - - get_message( msg, tvb, 36 + buddyname_length, tvb_length(tvb) - 36 - buddyname_length); - - if (check_col(pinfo->cinfo, COL_INFO)) { - col_add_fstr(pinfo->cinfo, COL_INFO, "Message"); - col_append_fstr(pinfo->cinfo, COL_INFO, " from: %s", buddyname); - - col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg); - } - - if( tree ) - { - proto_tree_add_text(aim_tree_fnac, tvb, 27, buddyname_length, "Screen Name: %s", buddyname); - } - break; - } - - break; - } - - - + dissect_aim_snac(tvb, pinfo, offset, aim_tree); break; - case CHANNEL_FLAP_ERR: - if (check_col(pinfo->cinfo, COL_INFO)) { - col_add_fstr(pinfo->cinfo, COL_INFO, "FLAP error"); - } + dissect_aim_flap_err(tvb, pinfo, offset, aim_tree); break; - case CHANNEL_CLOSE_CONN: - if (check_col(pinfo->cinfo, COL_INFO)) { - col_add_fstr(pinfo->cinfo, COL_INFO, "Close Connection"); - } + dissect_aim_close_conn(tvb, pinfo, offset, aim_tree); break; - default: - if (check_col(pinfo->cinfo, COL_INFO)) { - col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown Channel: %d", hdr_channel ); - } + dissect_aim_unknown_channel(tvb, pinfo, offset, aim_tree); break; } - - } static int get_buddyname( char *name, tvbuff_t *tvb, int len_offset, int name_offset) { guint8 buddyname_length; - + buddyname_length = tvb_get_guint8(tvb, len_offset); if(buddyname_length > MAX_BUDDYNAME_LENGTH ) buddyname_length = MAX_BUDDYNAME_LENGTH; - memset( name, '\0', sizeof(name)); - tvb_get_nstringz0(tvb, name_offset, buddyname_length, name); + tvb_get_nstringz0(tvb, name_offset, buddyname_length + 1, name); return buddyname_length; } @@ -513,20 +801,20 @@ static void get_message( guchar *msg, tvbuff_t *tvb, int msg_offset, int msg_len new_offset++; new_length--; } - + /* set offset and length of message to after the first HTML tag */ msg_offset = new_offset; msg_length = new_length; max = msg_length - 1; tagchars = 0; - + /* find the rest of the message until either a is reached or the end of the frame. * All other HTML tags are stripped to display only the raw message (printable characters) */ while( (c < max) && (tagchars < 7) ) { j = tvb_get_guint8(tvb, msg_offset+c); - + /* make sure this is an HTML tag by checking the order of the chars */ if( ( (j == '<') && (tagchars == 0) ) || ( (j == '/') && (tagchars == 1) ) || @@ -542,7 +830,7 @@ static void get_message( guchar *msg, tvbuff_t *tvb, int msg_offset, int msg_len #ifdef STRIP_TAGS if( j == '<' ) bracket = TRUE; - if( j == '>' ) bracket = FALSE; + if( j == '>' ) bracket = FALSE; if( (isprint(j) ) && (bracket == FALSE) && (j != '>')) #else if( isprint(j) ) @@ -554,12 +842,952 @@ static void get_message( guchar *msg, tvbuff_t *tvb, int msg_offset, int msg_len c++; } } - + +static void dissect_aim_newconn(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree) +{ + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "New Connection"); + if (tvb_length_remaining(tvb, offset) > 0) + proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE); +} + +static void dissect_aim_snac(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *aim_tree) +{ + guint16 family; + guint16 subtype; + guint16 flags; + guint32 id; + proto_item *ti1; + proto_tree *aim_tree_fnac = NULL; + int orig_offset; + + orig_offset = offset; + family = tvb_get_ntohs(tvb, offset); + offset += 2; + subtype = tvb_get_ntohs(tvb, offset); + 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"); + aim_tree_fnac = proto_item_add_subtree(ti1, ett_aim_fnac); + + proto_tree_add_item (aim_tree_fnac, hf_aim_fnac_family, + tvb, offset, 2, FALSE); + offset += 2; + + /* Dissect the subtype based on the family */ + dissect_aim_snac_fnac_subtype(tvb, offset, aim_tree_fnac, family); + offset += 2; + + proto_tree_add_uint(aim_tree_fnac, hf_aim_fnac_flags, tvb, offset, + 2, flags); + offset += 2; + proto_tree_add_uint(aim_tree_fnac, hf_aim_fnac_id, tvb, offset, + 4, id); + offset += 4; + } + + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_fstr(pinfo->cinfo, COL_INFO, ", Family: %s", + val_to_str(family, aim_fnac_family_ids, + "Unknown Family ID=0x%04x")); + + switch(family) + { + case FAMILY_SIGNON: + dissect_aim_snac_signon(tvb, pinfo, offset, aim_tree, subtype); + break; + case FAMILY_GENERIC: + dissect_aim_snac_generic(tvb, pinfo, offset, aim_tree, subtype); + break; + case FAMILY_BUDDYLIST: + dissect_aim_snac_buddylist(tvb, pinfo, offset, aim_tree, subtype); + break; + case FAMILY_LOCATION: + dissect_aim_snac_location(tvb, pinfo, offset, aim_tree, subtype); + break; + case FAMILY_ADVERTS: + dissect_aim_snac_adverts(tvb, pinfo, offset, aim_tree, subtype); + break; + case FAMILY_USERLOOKUP: + dissect_aim_snac_userlookup(tvb, pinfo, offset, aim_tree, subtype); + break; + case FAMILY_CHAT: + dissect_aim_snac_chat(tvb, pinfo, offset, aim_tree, subtype); + break; + case FAMILY_MESSAGING: + dissect_aim_snac_messaging(tvb, pinfo, offset, aim_tree, subtype); + break; + case FAMILY_SSI: + dissect_aim_snac_ssi(tvb, pinfo, offset, aim_tree, subtype); + break; + } +} + +static void dissect_aim_snac_signon(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree, + guint16 subtype) +{ + switch(subtype) + { + case FAMILY_SIGNON_LOGON: + dissect_aim_snac_signon_logon(tvb, pinfo, offset, tree); + break; + case FAMILY_SIGNON_LOGON_REPLY: + dissect_aim_snac_signon_logon_reply(tvb, pinfo, offset, tree); + break; + case FAMILY_SIGNON_SIGNON: + dissect_aim_snac_signon_signon(tvb, pinfo, offset, tree); + break; + case FAMILY_SIGNON_SIGNON_REPLY: + dissect_aim_snac_signon_signon_reply(tvb, pinfo, offset, tree); + break; + } +} + +static void dissect_aim_snac_signon_logon(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree) +{ + while (tvb_length_remaining(tvb, offset) > 0) { + offset = dissect_aim_tlv(tvb, pinfo, offset, tree, aim_signon_signon_tlv); + } +} + +static void dissect_aim_snac_signon_logon_reply(tvbuff_t *tvb, + packet_info *pinfo, + int offset, proto_tree *tree) +{ + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_fstr(pinfo->cinfo, COL_INFO, ", Login information reply"); + + while (tvb_length_remaining(tvb, offset) > 0) { + offset = dissect_aim_tlv(tvb, pinfo, offset, tree, + aim_signon_logon_reply_tlv); + } +} + +static void dissect_aim_snac_signon_signon(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree) +{ + guint8 buddyname_length = 0; + char buddyname[MAX_BUDDYNAME_LENGTH + 1]; + + /* Info Type */ + proto_tree_add_item(tree, hf_aim_infotype, tvb, offset, 2, FALSE); + offset += 2; + + /* Unknown */ + offset += 1; + + /* Buddy Name */ + buddyname_length = get_buddyname( buddyname, tvb, offset, offset + 1 ); + + if (check_col(pinfo->cinfo, COL_INFO)) { + col_append_fstr(pinfo->cinfo, COL_INFO, " Username: %s", buddyname); + } + + if(tree) { + proto_tree_add_text(tree, tvb, offset + 1, buddyname_length, + "Screen Name: %s", buddyname); + } + + offset += buddyname_length + 1; +} + +static void dissect_aim_snac_signon_signon_reply(tvbuff_t *tvb, + packet_info *pinfo, + int offset, proto_tree *tree) +{ + guint16 challenge_length = 0; + + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_fstr(pinfo->cinfo, COL_INFO, ", Sign-on reply"); + + /* Logon Challenge Length */ + challenge_length = tvb_get_ntohs(tvb, offset); + proto_tree_add_item(tree, hf_aim_signon_challenge_len, tvb, offset, 2, FALSE); + offset += 2; + + /* Challenge */ + proto_tree_add_item(tree, hf_aim_signon_challenge, tvb, offset, challenge_length, FALSE); + offset += challenge_length; +} + +static void dissect_aim_snac_generic(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree, + guint16 subtype) +{ + switch(subtype) + { + case FAMILY_GENERIC_ERROR: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Generic Error"); + break; + case FAMILY_GENERIC_CLIENTREADY: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, + "Client is now online and ready for normal function"); + break; + case FAMILY_GENERIC_SERVERREADY: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, + "Server is now ready for normal functions"); + break; + case FAMILY_GENERIC_SERVICEREQ: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, + "Request for new service (server will redirect client)"); + break; + case FAMILY_GENERIC_REDIRECT: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Redirect response"); + break; + case FAMILY_GENERIC_RATEINFOREQ: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Request Rate Information"); + break; + case FAMILY_GENERIC_RATEINFO: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Rate information response"); + break; + case FAMILY_GENERIC_RATEINFOACK: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Rate Information Response Ack"); + break; + case FAMILY_GENERIC_RATECHANGE: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Rate Change"); + break; + case FAMILY_GENERIC_SERVERPAUSE: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Server Pause"); + break; + case FAMILY_GENERIC_SERVERRESUME: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Server Resume"); + break; + case FAMILY_GENERIC_REQSELFINFO: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Request Self Info"); + break; + case FAMILY_GENERIC_SELFINFO: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Self Info"); + break; + case FAMILY_GENERIC_EVIL: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Evil"); + break; + case FAMILY_GENERIC_SETIDLE: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Set Idle"); + break; + case FAMILY_GENERIC_MIGRATIONREQ: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Request Migration"); + break; + case FAMILY_GENERIC_MOTD: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "MOTD"); + break; + case FAMILY_GENERIC_SETPRIVFLAGS: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Set Privilege Flags"); + break; + case FAMILY_GENERIC_WELLKNOWNURL: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Well Known URL"); + break; + case FAMILY_GENERIC_NOP: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "No-op"); + break; + case FAMILY_GENERIC_DEFAULT: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Generic Default"); + break; + } + + /* Show the undissected payload */ + if (tvb_length_remaining(tvb, offset) > 0) + proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE); +} + +static void dissect_aim_snac_buddylist(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree, + guint16 subtype) +{ + guint8 buddyname_length = 0; + char buddyname[MAX_BUDDYNAME_LENGTH + 1]; + guint16 tlv_count = 0; + + switch(subtype) + { + case FAMILY_BUDDYLIST_ERROR: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Buddylist - Error"); + break; + + case FAMILY_BUDDYLIST_REQRIGHTS: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Request Rights information"); + break; + + case FAMILY_BUDDYLIST_RIGHTSINFO: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Rights information"); + break; + + case FAMILY_BUDDYLIST_ADDBUDDY: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Add to Buddylist"); + break; + + case FAMILY_BUDDYLIST_REMBUDDY: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Remove from Buddylist"); + break; + + case FAMILY_BUDDYLIST_ONCOMING: + buddyname_length = get_buddyname( buddyname, tvb, offset, offset + 1 ); + + if (check_col(pinfo->cinfo, COL_INFO)) { + col_add_fstr(pinfo->cinfo, COL_INFO, "Oncoming Buddy"); + col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", buddyname); + } + + if (tree) { + proto_tree_add_text(tree, tvb, offset + 1, buddyname_length, + "Screen Name: %s", buddyname); + } + offset += buddyname_length + 1; + + /* Warning level */ + proto_tree_add_item(tree, hf_aim_userinfo_warninglevel, tvb, offset, + 2, FALSE); + offset += 2; + + /* TLV Count */ + tlv_count = tvb_get_ntohs(tvb, offset); + proto_tree_add_item(tree, hf_aim_userinfo_tlvcount, tvb, offset, + 2, FALSE); + offset += 2; + + while (tvb_length_remaining(tvb, offset) > 0) { + offset = dissect_aim_tlv(tvb, pinfo, offset, tree, + aim_fnac_family_buddylist_oncoming_tlv); + } + + break; + + case FAMILY_BUDDYLIST_OFFGOING: + buddyname_length = get_buddyname( buddyname, tvb, offset, offset + 1 ); + + if (check_col(pinfo->cinfo, COL_INFO)) { + col_add_fstr(pinfo->cinfo, COL_INFO, "Offgoing Buddy"); + col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", buddyname); + } + + if (tree) { + proto_tree_add_text(tree, tvb, offset + 1, buddyname_length, + "Screen Name: %s", buddyname); + } + offset += buddyname_length + 1; + + /* Warning level */ + proto_tree_add_item(tree, hf_aim_userinfo_warninglevel, tvb, offset, + 2, FALSE); + offset += 2; + + /* TLV Count */ + tlv_count = tvb_get_ntohs(tvb, offset); + proto_tree_add_item(tree, hf_aim_userinfo_tlvcount, tvb, offset, + 2, FALSE); + offset += 2; + + break; + } + + /* Show the undissected payload */ + if (tvb_length_remaining(tvb, offset) > 0) + proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE); +} + +static void dissect_aim_snac_location(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree, + guint16 subtype) +{ + switch(subtype) + { + case FAMILY_LOCATION_ERROR: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Location - Error"); + break; + case FAMILY_LOCATION_REQRIGHTS: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Request Rights Information"); + break; + case FAMILY_LOCATION_RIGHTSINFO: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Rights Information"); + break; + case FAMILY_LOCATION_SETUSERINFO: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Set User Information"); + break; + case FAMILY_LOCATION_REQUSERINFO: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Request User Information"); + dissect_aim_snac_location_request_user_information(tvb, offset, tree); + break; + case FAMILY_LOCATION_USERINFO: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "User Information"); + dissect_aim_snac_location_user_information(tvb, pinfo, offset, tree); + break; + case FAMILY_LOCATION_WATCHERSUBREQ: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Watcher Subrequest"); + break; + case FAMILY_LOCATION_WATCHERNOT: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Watcher Notification"); + break; + case FAMILY_LOCATION_DEFAULT: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Location Default"); + break; + } +} + +static void dissect_aim_snac_location_request_user_information(tvbuff_t *tvb, + int offset, + proto_tree *tree) +{ + guint8 buddyname_length = 0; + + /* Info Type */ + proto_tree_add_item(tree, hf_aim_snac_location_request_user_info_infotype, + tvb, offset, 2, FALSE); + offset += 2; + + /* Buddy Name length */ + buddyname_length = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tree, hf_aim_buddyname_len, tvb, offset, 1, FALSE); + offset += 1; + + /* Buddy name */ + proto_tree_add_item(tree, hf_aim_buddyname, tvb, offset, buddyname_length, FALSE); + offset += buddyname_length; + + /* Show the undissected payload */ + if (tvb_length_remaining(tvb, offset) > 0) + proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE); +} + +static void dissect_aim_snac_location_user_information(tvbuff_t *tvb, + packet_info *pinfo _U_, + int offset, proto_tree *tree) +{ + guint8 buddyname_length = 0; + guint16 tlv_count = 0; + guint16 i = 0; + + /* Buddy Name length */ + buddyname_length = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tree, hf_aim_buddyname_len, tvb, offset, 1, FALSE); + offset += 1; + + /* Buddy name */ + proto_tree_add_item(tree, hf_aim_buddyname, tvb, offset, buddyname_length, FALSE); + offset += buddyname_length; + + /* Warning level */ + proto_tree_add_item(tree, hf_aim_userinfo_warninglevel, tvb, offset, 2, FALSE); + offset += 2; + + /* TLV Count */ + tlv_count = tvb_get_ntohs(tvb, offset); + proto_tree_add_item(tree, hf_aim_userinfo_tlvcount, tvb, offset, 2, FALSE); + offset += 2; + + /* Dissect the TLV array containing general user status */ + while (i++ < tlv_count) { + offset = dissect_aim_tlv(tvb, pinfo, offset, tree, + aim_fnac_family_buddylist_oncoming_tlv); + } + + /* Dissect the TLV array containing the away message (or whatever info was + specifically requested) */ + while (tvb_length_remaining(tvb, offset) > 0) { + offset = dissect_aim_tlv(tvb, pinfo, offset, tree, + aim_fnac_family_location_userinfo_tlv); + } +} + +static void dissect_aim_snac_adverts(tvbuff_t *tvb _U_, + packet_info *pinfo _U_, + int offset _U_, proto_tree *tree _U_, + guint16 subtype) +{ + switch(subtype) + { + case FAMILY_ADVERTS_ERROR: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Advertisements - Error"); + break; + case FAMILY_ADVERTS_REQUEST: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Advertisement Request"); + break; + case FAMILY_ADVERTS_DATA: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Advertisement data (GIF)"); + break; + } + + /* Show the undissected payload */ + if (tvb_length_remaining(tvb, offset) > 0) + proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE); +} + +static void dissect_aim_snac_userlookup(tvbuff_t *tvb _U_, packet_info *pinfo, + int offset _U_, proto_tree *tree _U_, + guint16 subtype) +{ + switch(subtype) + { + case FAMILY_USERLOOKUP_ERROR: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, + "Search - Error (could be: not found)"); + break; + case FAMILY_USERLOOKUP_SEARCHEMAIL: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, + "Search for Screen Name by e-mail"); + break; + case FAMILY_USERLOOKUP_SEARCHRESULT: + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "Screen Name Search Result"); + break; + } + + /* Show the undissected payload */ + if (tvb_length_remaining(tvb, offset) > 0) + proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE); +} + +static void dissect_aim_snac_chat(tvbuff_t *tvb, packet_info *pinfo, + int offset _U_, proto_tree *tree, + guint16 subtype) +{ + guint8 buddyname_length = 0; + char buddyname[MAX_BUDDYNAME_LENGTH + 1]; + guchar msg[1000]; + + switch(subtype) + { + case FAMILY_CHAT_OUTGOINGMSG: + /* channel message from client */ + get_message( msg, tvb, 40 + buddyname_length, tvb_length(tvb) + - 40 - buddyname_length ); + + if (check_col(pinfo->cinfo, COL_INFO)) { + col_add_fstr(pinfo->cinfo, COL_INFO, "Chat Message "); + col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg); + } + break; + + case FAMILY_CHAT_INCOMINGMSG: + /* channel message to client */ + buddyname_length = get_buddyname( buddyname, tvb, 30, 31 ); + get_message( msg, tvb, 36 + buddyname_length, tvb_length(tvb) + - 36 - buddyname_length ); + + if (check_col(pinfo->cinfo, COL_INFO)) { + col_add_fstr(pinfo->cinfo, COL_INFO, "Chat Message "); + col_append_fstr(pinfo->cinfo, COL_INFO, "from: %s", buddyname); + col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg); + } + + if(tree) { + proto_tree_add_text(tree, tvb, 31, buddyname_length, + "Screen Name: %s", buddyname); + } + break; + } +} + +static void dissect_aim_snac_messaging(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree, + guint16 subtype) +{ + guint8 buddyname_length = 0; + char buddyname[MAX_BUDDYNAME_LENGTH + 1]; + guchar msg[1000]; + + switch(subtype) + { + case FAMILY_MESSAGING_OUTGOING: + + /* Unknown */ + offset += 10; + + buddyname_length = get_buddyname( buddyname, tvb, offset, offset + 1 ); + + /* djh - My test suggest that this is broken. Need to give this a + closer look @@@@@@@@@ */ + get_message( msg, tvb, 36 + buddyname_length, tvb_length(tvb) - 36 + - buddyname_length ); + + if (check_col(pinfo->cinfo, COL_INFO)) { + col_add_fstr(pinfo->cinfo, COL_INFO, "Message "); + col_append_fstr(pinfo->cinfo, COL_INFO, "to: %s", buddyname); + col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg); + } + + if(tree) { + proto_tree_add_text(tree, tvb, 27, buddyname_length, + "Screen Name: %s", buddyname); + } + + break; + + case FAMILY_MESSAGING_INCOMING: + + /* Unknown */ + offset += 10; + + buddyname_length = get_buddyname( buddyname, tvb, offset, offset + 1 ); + + /* djh - My test suggest that this is broken. Need to give this a + closer look @@@@@@@@@ */ + get_message( msg, tvb, 36 + buddyname_length, tvb_length(tvb) - 36 + - buddyname_length); + + if (check_col(pinfo->cinfo, COL_INFO)) { + col_add_fstr(pinfo->cinfo, COL_INFO, "Message"); + col_append_fstr(pinfo->cinfo, COL_INFO, " from: %s", buddyname); + + col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg); + } + + if(tree) { + proto_tree_add_text(tree, tvb, 27, buddyname_length, + "Screen Name: %s", buddyname); + } + break; + } +} + +static void dissect_aim_snac_ssi(tvbuff_t *tvb, packet_info *pinfo _U_, + int offset, proto_tree *tree, + guint16 subtype _U_) +{ + switch(subtype) + { + case FAMILY_SSI_LIST: + dissect_aim_snac_ssi_list(tvb, pinfo, offset, tree, subtype); + break; + default: + /* Show the undissected payload */ + if (tvb_length_remaining(tvb, offset) > 0) + proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE); + } +} + +static void dissect_aim_snac_ssi_list(tvbuff_t *tvb, packet_info *pinfo _U_, + int offset, proto_tree *tree, + guint16 subtype _U_) +{ + guint16 buddyname_length = 0; + guint16 tlv_len = 0; + proto_item *ti; + proto_tree *ssi_entry = NULL; + + /* SSI Version */ + proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_version, tvb, offset, 1, + FALSE); + offset += 1; + + /* Number of items */ + proto_tree_add_item(tree, hf_aim_fnac_subtype_ssi_numitems, tvb, offset, 2, + FALSE); + offset += 2; + + while (tvb_length_remaining(tvb, offset) > 4) { + ti = proto_tree_add_text(tree, tvb, offset, 0, "SSI Entry"); + ssi_entry = proto_item_add_subtree(ti, ett_aim_ssi); + + /* Buddy Name Length */ + buddyname_length = tvb_get_ntohs(tvb, offset); + proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_buddyname_len, + tvb, offset, 2, FALSE); + offset += 2; + + /* Buddy Name */ + if (buddyname_length > 0) { + proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_buddyname, tvb, + offset, buddyname_length, FALSE); + offset += buddyname_length; + } + + /* Buddy group ID */ + proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_gid, tvb, offset, + 2, FALSE); + offset += 2; + + /* Buddy ID */ + proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_bid, tvb, offset, + 2, FALSE); + offset += 2; + + /* Buddy Type */ + proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_type, tvb, offset, + 2, FALSE); + offset += 2; + + /* Size of the following TLV in bytes (as opposed to the number of + TLV objects in the chain) */ + tlv_len = tvb_get_ntohs(tvb, offset); + proto_tree_add_item(ssi_entry, hf_aim_fnac_subtype_ssi_tlvlen, tvb, + offset, 2, FALSE); + offset += 2; + + /* For now, we just dump the TLV contents as-is, since there is not a + TLV dissection utility that works based on total chain length */ + if (tlv_len > 0) { + proto_tree_add_item(ssi_entry, hf_aim_data, tvb, offset, tlv_len, + FALSE); + offset += tlv_len; + } + } +} + +static void dissect_aim_snac_fnac_subtype(tvbuff_t *tvb, int offset, + proto_tree *tree, guint16 family) +{ + /* Since the subtypes differ by family, we need to display the correct + subtype based on the family. If we don't know the family, or we do + not have the subtypes enumerated for a known family, we just dump the + subtype as-is */ + + switch (family) + { + case FAMILY_GENERIC: + proto_tree_add_item (tree, hf_aim_fnac_subtype_generic, + tvb, offset, 2, FALSE); + break; + case FAMILY_LOCATION: + proto_tree_add_item (tree, hf_aim_fnac_subtype_location, + tvb, offset, 2, FALSE); + break; + case FAMILY_BUDDYLIST: + proto_tree_add_item (tree, hf_aim_fnac_subtype_buddylist, + tvb, offset, 2, FALSE); + break; + case FAMILY_MESSAGING: + proto_tree_add_item (tree, hf_aim_fnac_subtype_messaging, + tvb, offset, 2, FALSE); + break; + case FAMILY_ADVERTS: + proto_tree_add_item (tree, hf_aim_fnac_subtype_adverts, + tvb, offset, 2, FALSE); + break; + case FAMILY_INVITATION: + proto_tree_add_item (tree, hf_aim_fnac_subtype_invitation, + tvb, offset, 2, FALSE); + break; + case FAMILY_ADMIN: + proto_tree_add_item (tree, hf_aim_fnac_subtype_admin, + tvb, offset, 2, FALSE); + break; + case FAMILY_POPUP: + proto_tree_add_item (tree, hf_aim_fnac_subtype_popup, + tvb, offset, 2, FALSE); + break; + case FAMILY_BOS: + proto_tree_add_item (tree, hf_aim_fnac_subtype_bos, + tvb, offset, 2, FALSE); + break; + case FAMILY_USERLOOKUP: + proto_tree_add_item (tree, hf_aim_fnac_subtype_userlookup, + tvb, offset, 2, FALSE); + break; + case FAMILY_STATS: + proto_tree_add_item (tree, hf_aim_fnac_subtype_stats, + tvb, offset, 2, FALSE); + break; + case FAMILY_TRANSLATE: + proto_tree_add_item (tree, hf_aim_fnac_subtype_translate, + tvb, offset, 2, FALSE); + break; + case FAMILY_CHAT_NAV: + proto_tree_add_item (tree, hf_aim_fnac_subtype_chatnav, + tvb, offset, 2, FALSE); + break; + case FAMILY_CHAT: + proto_tree_add_item (tree, hf_aim_fnac_subtype_chat, + tvb, offset, 2, FALSE); + break; + case FAMILY_SSI: + proto_tree_add_item (tree, hf_aim_fnac_subtype_ssi, + tvb, offset, 2, FALSE); + break; + case FAMILY_ICQ: + proto_tree_add_item (tree, hf_aim_fnac_subtype_icq, + tvb, offset, 2, FALSE); + break; + case FAMILY_SIGNON: + proto_tree_add_item (tree, hf_aim_fnac_subtype_signon, + tvb, offset, 2, FALSE); + break; + case FAMILY_OFT: + default: + proto_tree_add_item(tree, hf_aim_fnac_subtype, tvb, offset, 2, FALSE); + break; + + } +} + +static void dissect_aim_flap_err(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree) +{ + if (check_col(pinfo->cinfo, COL_INFO)) { + col_add_fstr(pinfo->cinfo, COL_INFO, "FLAP error"); + } + + /* Show the undissected payload */ + if (tvb_length_remaining(tvb, offset) > 0) + proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE); +} + +static void dissect_aim_close_conn(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree) +{ + if (check_col(pinfo->cinfo, COL_INFO)) { + col_add_fstr(pinfo->cinfo, COL_INFO, "Close Connection"); + } + + /* Show the undissected payload */ + if (tvb_length_remaining(tvb, offset) > 0) + proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE); +} + +static void dissect_aim_unknown_channel(tvbuff_t *tvb, packet_info *pinfo, + int offset, proto_tree *tree) +{ + if (check_col(pinfo->cinfo, COL_INFO)) { + col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown Channel"); + } + + /* Show the undissected payload */ + if (tvb_length_remaining(tvb, offset) > 0) + proto_tree_add_item(tree, hf_aim_data, tvb, offset, -1, FALSE); +} + +/* Dissect a TLV value */ +static int dissect_aim_tlv(tvbuff_t *tvb, packet_info *pinfo _U_, + int offset, proto_tree *tree, const aim_tlv *tlv) +{ + guint16 valueid; + guint16 length; + int i = 0; + const aim_tlv *tmp; + proto_item *ti1; + proto_tree *tlv_tree; + int orig_offset; + guint16 value16; + guint32 value32; + + /* Record the starting offset so we can reuse it at the second pass */ + orig_offset = offset; + + /* Get the value ID */ + valueid = tvb_get_ntohs(tvb, offset); + offset += 2; + + /* Figure out which entry applies from the tlv list */ + tmp = tlv; + while (tmp[i].valueid) { + if (tmp[i].valueid == valueid) { + /* We found a match */ + break; + } + i++; + } + + /* At this point, we are either pointing at the correct record, or + we didn't find the record, and are pointing at the last item in the + list */ + + length = tvb_get_ntohs(tvb, offset); + offset += 2; + offset += length; + + if (tree) { + offset = orig_offset; + + /* Show the info in the top of the tree if it's one of the standard + data types */ + if (tmp[i].datatype == FT_STRING && length > 0) { + guint8 *buf; + buf = tvb_get_string(tvb, offset + 4, length); + ti1 = proto_tree_add_text(tree, tvb, offset, length + 4, + "%s: %s", tmp[i].desc, buf); + g_free(buf); + } + else if (tmp[i].datatype == FT_UINT16) { + value16 = tvb_get_ntohs(tvb, offset + 4); + ti1 = proto_tree_add_text(tree, tvb, offset, length + 4, + "%s: %d", tmp[i].desc, value16); + } + else if (tmp[i].datatype == FT_UINT32) { + value32 = tvb_get_ntohl(tvb, offset + 4); + ti1 = proto_tree_add_text(tree, tvb, offset, length + 4, + "%s: %d", tmp[i].desc, value32); + } + else { + ti1 = proto_tree_add_text(tree, tvb, offset, length + 4, + "%s", tmp[i].desc); + } + + tlv_tree = proto_item_add_subtree(ti1, ett_aim_tlv); + + proto_tree_add_text(tlv_tree, tvb, offset, 2, + "Value ID: %s (0x%04x)", tmp[i].desc, valueid); + offset += 2; + + proto_tree_add_text(tlv_tree, tvb, offset, 2, + "Length: %d", length); + offset += 2; + + ti1 = proto_tree_add_text(tlv_tree, tvb, offset, length, + "Value"); + offset += length; + } + + /* Return the new length */ + return offset; +} + /* Register the protocol with Ethereal */ -void +void proto_register_aim(void) -{ +{ /* Setup list of header fields */ static hf_register_info hf[] = { @@ -575,19 +1803,135 @@ proto_register_aim(void) { &hf_aim_data_len, { "Data Field Length", "aim.datalen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } }, + { &hf_aim_data, + { "Data", "aim.data", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_aim_signon_challenge_len, + { "Signon challenge length", "aim.signon.challengelen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_aim_signon_challenge, + { "Signon challenge", "aim.signon.challenge", FT_STRING, BASE_HEX, NULL, 0x0, "", HFILL } + }, { &hf_aim_fnac_family, - { "FNAC Family ID", "aim.fnac.family", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + { "FNAC Family ID", "aim.fnac.family", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_ids), 0x0, "", HFILL } }, { &hf_aim_fnac_subtype, { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } }, + { &hf_aim_fnac_subtype_signon, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_signon), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_generic, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_generic), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_location, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_location), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_buddylist, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_buddylist), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_messaging, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_messaging), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_adverts, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_adverts), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_invitation, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_invitation), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_admin, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_admin), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_popup, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_popup), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_bos, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_bos), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_userlookup, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_userlookup), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_stats, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_stats), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_translate, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_translate), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_chatnav, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_chatnav), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_chat, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_chat), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_ssi, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_ssi), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_ssi_version, + { "SSI Version", "aim.fnac.ssi.version", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_ssi_numitems, + { "SSI Object count", "aim.fnac.ssi.numitems", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_ssi_buddyname_len, + { "SSI Buddy Name length", "aim.fnac.ssi.buddyname_len", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_ssi_buddyname, + { "Buddy Name", "aim.fnac.ssi.buddyname", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_ssi_gid, + { "SSI Buddy Group ID", "aim.fnac.ssi.gid", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_ssi_bid, + { "SSI Buddy ID", "aim.fnac.ssi.bid", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_ssi_type, + { "SSI Buddy type", "aim.fnac.ssi.type", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_ssi_types), 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_ssi_tlvlen, + { "SSI TLV Len", "aim.fnac.ssi.tlvlen", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_ssi_data, + { "SSI Buddy Data", "aim.fnac.ssi.data", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_aim_fnac_subtype_icq, + { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, VALS(aim_fnac_family_icq), 0x0, "", HFILL } + }, + { &hf_aim_fnac_flags, + { "FNAC Flags", "aim.fnac.flags", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_aim_fnac_id, + { "FNAC ID", "aim.fnac.id", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_aim_infotype, + { "Infotype", "aim.infotype", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_aim_snac_location_request_user_info_infotype, + { "Infotype", "aim.snac.location.request_user_info.infotype", FT_UINT16, + BASE_HEX, VALS(aim_snac_location_request_user_info_infotypes), 0x0, + "", HFILL } + }, + { &hf_aim_buddyname_len, + { "Buddyname len", "aim.buddynamelen", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_aim_buddyname, + { "Buddy Name", "aim.buddyname", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_aim_userinfo_warninglevel, + { "Warning Level", "aim.userinfo.warninglevel", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }, + }, + { &hf_aim_userinfo_tlvcount, + { "TLV Count", "aim.userinfo.tlvcount", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }, + }, }; /* Setup protocol subtree array */ static gint *ett[] = { &ett_aim, &ett_aim_fnac, + &ett_aim_tlv, + &ett_aim_ssi, }; + module_t *aim_module; /* Register the protocol name and description */ proto_aim = proto_register_protocol("AOL Instant Messenger", "AIM", "aim"); @@ -595,13 +1939,19 @@ proto_register_aim(void) /* Required function calls to register the header fields and subtrees used */ proto_register_field_array(proto_aim, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); -}; + + aim_module = prefs_register_protocol(proto_aim, NULL); + prefs_register_bool_preference(aim_module, "desegment", + "Desegment all AIM messages spanning multiple TCP segments", + "Whether the AIM dissector should desegment all messages spanning multiple TCP segments", + &aim_desegment); +} void proto_reg_handoff_aim(void) { dissector_handle_t aim_handle; - aim_handle = create_dissector_handle(dissect_aim, proto_aim); + aim_handle = new_create_dissector_handle(dissect_aim, proto_aim); dissector_add("tcp.port", TCP_PORT_AIM, aim_handle); }