* Routines for AIM Instant Messenger (OSCAR) dissection
* Copyright 2000, Ralf Hoelzer <ralf@well.com>
*
- * $Id: packet-aim.c,v 1.1 2000/11/06 00:07:04 guy Exp $
+ * $Id: packet-aim.c,v 1.16 2002/08/02 23:35:47 jmayer Exp $
*
* Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@unicom.net>
+ * By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
#include <string.h>
#include <ctype.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-
#include <glib.h>
-#ifdef NEED_SNPRINTF_H
-# include "snprintf.h"
-#endif
-
-#include "packet.h"
-#include "strutil.h"
+#include <epan/packet.h>
+#include <epan/strutil.h>
#define TCP_PORT_AIM 5190
#define MAX_BUDDYNAME_LENGTH 30
#define FAMILY_TRANSLATE 0x000C
#define FAMILY_CHAT_NAV 0x000D
#define FAMILY_CHAT 0x000E
+#define FAMILY_SIGNON 0x0017
/* messaging */
-#define MSG_FROM_CLIENT 0x006
-#define MSG_TO_CLIENT 0x007
+#define MSG_TO_CLIENT 0x006
+#define MSG_FROM_CLIENT 0x007
static void dissect_aim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-void get_message( u_char *msg, tvbuff_t *tvb, int msg_offset, int msg_length);
-int get_buddyname( char *name, tvbuff_t *tvb, int len_offset, int name_offset);
+
+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);
/* Initialize the protocol and registered fields */
static int proto_aim = -1;
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];
- u_char msg[1000];
+ guchar msg[1000];
/* Set up structures we will need to add the protocol subtree and manage it */
proto_item *ti;
proto_tree *aim_tree = NULL;
proto_tree *aim_tree_fnac = NULL;
-/* Check if protocol decoding is enabled else decode as data and return */
-
- CHECK_DISPLAY_AS_DATA(proto_aim, tvb, pinfo, tree);
-
-/* load the display labels */
- pinfo->current_proto = "aim";
-
/* check, if this is really an AIM packet, they start with 0x2a */
if(!(tvb_get_guint8(tvb, 0) == 0x2a)) {
}
/* Make entries in Protocol column and Info column on summary display */
- if (check_col(pinfo->fd, COL_PROTOCOL))
- col_add_str(pinfo->fd, COL_PROTOCOL, "AIM");
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "AIM");
- if (check_col(pinfo->fd, COL_INFO))
- col_add_str(pinfo->fd, COL_INFO, "AOL Instant Messenger");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_add_str(pinfo->cinfo, COL_INFO, "AOL Instant Messenger");
/* get relevant header information */
necessary to generate protocol tree items. */
if (tree) {
- ti = proto_tree_add_item(tree, proto_aim, tvb, 0, tvb_length(tvb), 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_channel, tvb, 1, 1, hdr_channel);
{
/* New connection request */
case CHANNEL_NEW_CONN:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "New Connection");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "New Connection");
break;
/* SNAC channel. Most packets are of this type, such as messages or buddy list
family = tvb_get_ntohs(tvb, 6);
subtype = tvb_get_ntohs(tvb, 8);
- if (check_col(pinfo->fd, COL_INFO)) {
- col_add_fstr(pinfo->fd, COL_INFO, "SNAC data");
+ 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), "FNAC");
+ 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->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Family: %d - Subtype: %d (unknown)", family, 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->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Client is now online and ready for normal function");
+ 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->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Server is now ready for normal functions");
+ 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->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Request for new service (server will redirect client)");
+ 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->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Redirect response");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Redirect response");
break;
case 0x0006:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Request Rate Information");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Request Rate Information");
break;
case 0x0007:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Rate information response");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Rate information response");
break;
case 0x0008:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Rate Information Response Ack");
+ 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->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "No-op");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "No-op");
break;
}
break;
switch(subtype)
{
case 0x0001:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Buddylist - Error");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Buddylist - Error");
break;
case 0x0002:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Request Rights information");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Request Rights information");
break;
case 0x0003:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Rights information");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Rights information");
break;
case 0x0004:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Add to Buddylist");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Add to Buddylist");
break;
case 0x0005:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Remove from Buddylist");
+ 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->fd, COL_INFO)) {
- col_add_fstr(pinfo->fd, COL_INFO, "Oncoming Buddy");
- col_append_fstr(pinfo->fd, COL_INFO, ": %s", buddyname);
+ 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 )
buddyname_length = get_buddyname( buddyname, tvb, 16, 17 );
- if (check_col(pinfo->fd, COL_INFO)) {
- col_add_fstr(pinfo->fd, COL_INFO, "Offgoing Buddy");
- col_append_fstr(pinfo->fd, COL_INFO, ": %s", buddyname);
+ 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 )
switch(subtype)
{
case 0x0001:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Location - Error");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Location - Error");
break;
case 0x0002:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Request Rights Information");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Request Rights Information");
break;
case 0x0003:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Rights Information");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Rights Information");
break;
case 0x0004:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Set User Information");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Set User Information");
break;
case 0x0005:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Request User Information");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Request User Information");
break;
case 0x0006:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "User Information");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "User Information");
break;
case 0x0007:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Watcher Subrequest");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Watcher Subrequest");
break;
case 0x0008:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Watcher Notification");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Watcher Notification");
break;
}
break;
switch(subtype)
{
case 0x0001:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Advertisements - Error");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Advertisements - Error");
break;
case 0x0002:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Advertisement Request");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Advertisement Request");
break;
case 0x0003:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Advertisement data (GIF)");
+ if (check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "Advertisement data (GIF)");
break;
}
break;
switch(subtype)
{
case 0x0001:
- if (check_col(pinfo->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Search - Error (could be: not found)");
+ 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->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Search for Screen Name by e-mail");
+ 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->fd, COL_INFO)) col_add_fstr(pinfo->fd, COL_INFO, "Screen Name Search Result");
+ 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_FROM_CLIENT:
+ 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->fd, COL_INFO)) {
- col_add_fstr(pinfo->fd, COL_INFO, "Message ");
- col_append_fstr(pinfo->fd, COL_INFO, "from: %s", buddyname);
- col_append_fstr(pinfo->fd, COL_INFO, " -> %s", msg);
+ 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 )
break;
- case MSG_TO_CLIENT:
+ 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->fd, COL_INFO)) {
- col_add_fstr(pinfo->fd, COL_INFO, "Message");
- col_append_fstr(pinfo->fd, COL_INFO, " to: %s", buddyname);
+ 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->fd, COL_INFO, " -> %s", msg);
+ col_append_fstr(pinfo->cinfo, COL_INFO, " -> %s", msg);
}
if( tree )
break;
case CHANNEL_FLAP_ERR:
- if (check_col(pinfo->fd, COL_INFO)) {
- col_add_fstr(pinfo->fd, COL_INFO, "FLAP error");
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_add_fstr(pinfo->cinfo, COL_INFO, "FLAP error");
}
break;
case CHANNEL_CLOSE_CONN:
- if (check_col(pinfo->fd, COL_INFO)) {
- col_add_fstr(pinfo->fd, COL_INFO, "Close Connection");
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Close Connection");
}
break;
default:
- if (check_col(pinfo->fd, COL_INFO)) {
- col_add_fstr(pinfo->fd, COL_INFO, "Unknown Channel: %d", hdr_channel );
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown Channel: %d", hdr_channel );
}
break;
}
}
-int get_buddyname( char *name, tvbuff_t *tvb, int len_offset, int name_offset)
+static int get_buddyname( char *name, tvbuff_t *tvb, int len_offset, int name_offset)
{
guint8 buddyname_length;
}
-void get_message( u_char *msg, tvbuff_t *tvb, int msg_offset, int msg_length)
+static void get_message( guchar *msg, tvbuff_t *tvb, int msg_offset, int msg_length)
{
int i,j,c;
int bracket = FALSE;
/* Register the protocol with Ethereal */
-void proto_register_aim(void)
+void
+proto_register_aim(void)
{
/* Setup list of header fields */
static hf_register_info hf[] = {
{ &hf_aim_cmd_start,
- { "Command Start", "aim.cmd_start", FT_UINT8, BASE_HEX, NULL, 0x0, "" }
+ { "Command Start", "aim.cmd_start", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }
},
{ &hf_aim_channel,
- { "Channel ID", "aim.channel", FT_UINT8, BASE_HEX, NULL, 0x0, "" }
+ { "Channel ID", "aim.channel", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }
},
{ &hf_aim_seqno,
- { "Sequence Number", "aim.seqno", FT_UINT16, BASE_DEC, NULL, 0x0, "" }
+ { "Sequence Number", "aim.seqno", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
},
{ &hf_aim_data_len,
- { "Data Field Length", "aim.datalen", FT_UINT16, BASE_DEC, NULL, 0x0, "" }
+ { "Data Field Length", "aim.datalen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
},
{ &hf_aim_fnac_family,
- { "FNAC Family ID", "aim.fnac.family", FT_UINT16, BASE_HEX, NULL, 0x0, "" }
+ { "FNAC Family ID", "aim.fnac.family", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
},
{ &hf_aim_fnac_subtype,
- { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, NULL, 0x0, "" }
+ { "FNAC Subtype ID", "aim.fnac.subtype", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
},
};
};
/* Register the protocol name and description */
- proto_aim = proto_register_protocol("AOL Instant Messenger", "aim");
+ proto_aim = proto_register_protocol("AOL Instant Messenger", "AIM", "aim");
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array(proto_aim, hf, array_length(hf));
void
proto_reg_handoff_aim(void)
{
- dissector_add("tcp.port", TCP_PORT_AIM, &dissect_aim);
+ dissector_handle_t aim_handle;
+
+ aim_handle = create_dissector_handle(dissect_aim, proto_aim);
+ dissector_add("tcp.port", TCP_PORT_AIM, aim_handle);
}