diff options
author | Michele Campus <fci1908@gmail.com> | 2015-07-12 17:51:21 +0200 |
---|---|---|
committer | Michele Campus <fci1908@gmail.com> | 2015-07-12 17:51:21 +0200 |
commit | 0307c85bd3c17bdb2fc96160dc86cea3472a1f6b (patch) | |
tree | 8fc66898ba9b7aa0b40f69dcc8aaf1f097b21f85 /src | |
parent | 71ed576e18907aba583fd097e182226c96651fe8 (diff) |
fixed Oscar protocol dissector
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/protocols/oscar.c | 593 |
1 files changed, 554 insertions, 39 deletions
diff --git a/src/lib/protocols/oscar.c b/src/lib/protocols/oscar.c index f190f736f..4bf0ec8fc 100644 --- a/src/lib/protocols/oscar.c +++ b/src/lib/protocols/oscar.c @@ -25,11 +25,54 @@ #include "ndpi_api.h" +#define FLAPVERSION 0x00000001 + +/* Flap channels */ +#define SIGNON 0x01 +#define DATA 0x02 +#define ERROR 0x03 +#define SIGNOFF 0x04 +#define KEEP_ALIVE 0x05 + +/* Signon tags */ +#define SCREEN_NAME 0x0001 +#define PASSWD 0x0002 +#define CLIENT_NAME 0x0003 +#define BOS 0x0005 +#define LOGIN_COOKIE 0x0006 +#define MAJOR_VERSION 0x0017 +#define MINOR_VERSION 0x0018 +#define POINT_VERSION 0x0019 +#define BUILD_NUM 0x001a +#define MULTICONN_FLAGS 0x004a +#define CLIENT_LANG 0x00OF +#define CLIENT_CNTRY 0x00OE +#define CLIENT_RECONNECT 0x0094 + +/* Family */ +#define GE_SE_CTL 0x0001 +#define LOC_SRV 0x0002 +#define BUDDY_LIST 0x0003 +#define IM 0x0004 +#define IS 0x0006 +#define ACC_ADM 0x0007 +#define POPUP 0x0008 +#define PMS 0x0009 +#define USS 0x000b +#define CHAT_ROOM_SETUP 0x000d +#define CHAT_ROOM_ACT 0x000e +#define USER_SRCH 0x000f +#define BUDDY_ICON_SERVER 0x0010 +#define SERVER_STORED_INFO 0x0013 +#define ICQ 0x0015 +#define INIT_AUTH 0x0017 +#define EMAIL 0x0018 +#define IS_EXT 0x0085 #ifdef NDPI_PROTOCOL_OSCAR static void ndpi_int_oscar_add_connection(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow/* , ndpi_protocol_type_t protocol_type */) + struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; @@ -46,50 +89,522 @@ static void ndpi_int_oscar_add_connection(struct ndpi_detection_module_struct *n } } +/** + Oscar connection work on FLAP protocol. + + FLAP is a low-level communications protocol that facilitates the development of higher-level, datagram-oriented, communications layers. + It is used on the TCP connection between all clients and servers. + Here is format of FLAP datagram +**/ static void ndpi_search_oscar_tcp_connect(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { - struct ndpi_packet_struct *packet = &flow->packet; + + int excluded = 0; + u_int8_t channel; + u_int16_t family; + u_int16_t type; + u_int16_t flag; + u_int32_t req_ID; + + struct ndpi_packet_struct * packet = &flow->packet; - struct ndpi_id_struct *src = flow->src; - struct ndpi_id_struct *dst = flow->dst; - if (packet->payload_packet_len >= 10 && packet->payload[0] == 0x2a) { - - /* if is a oscar connection, 10 bytes long */ - - /* OSCAR Connection :: Connection detected at initial packets only - * +----+----+------+------+---------------+ - * |0x2a|Code|SeqNum|PktLen|ProtcolVersion | - * +----+----+------+------+---------------+ - * Code 1 Byte : 0x01 Oscar Connection - * SeqNum and PktLen are 2 Bytes each and ProtcolVersion: 0x00000001 - * */ - if (get_u_int8_t(packet->payload, 1) == 0x01 && get_u_int16_t(packet->payload, 4) == htons(packet->payload_packet_len - 6) - && get_u_int32_t(packet->payload, 6) == htonl(0x0000000001)) { - NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Connection FOUND \n"); - ndpi_int_oscar_add_connection(ndpi_struct, flow); - return; - } + struct ndpi_id_struct * src = flow->src; + struct ndpi_id_struct * dst = flow->dst; + + /* FLAP__Header + * + * [ 6 byte FLAP header ] + * +-----------+--------------+-------------+--------------+ + * | 0x2a (1B) | Channel (1B) | SeqNum (2B) | PyldLen (2B) | + * +-----------+--------------+-------------+--------------+ + * + * [ 4 byte of data ] + * + * */ + if (packet->payload_packet_len >= 6 && packet->payload[0] == 0x2a) + { + + /* FLAP__FRAME_TYPE (Channel)*/ + u_int8_t channel = get_u_int8_t(packet->payload, 1); + + /* + Initialize the FLAP connection. + + SIGNON -> FLAP__SIGNON_FRAME + +--------------------------------------------------+ + + FLAP__Header | 6 byte + + + FlapVersion | 4 byte (Always 1 = 0x00000001) + + + TLVs | [Class: FLAP__SIGNON_TAGS] TLVs + + +--------------------------------------------------+ + */ + if (channel == SIGNON && + get_u_int16_t(packet->payload, 4) == htons(packet->payload_packet_len - 6) && + get_u_int32_t(packet->payload, 6) == htonl(FLAPVERSION)) + { + + /* No TLVs */ + if(packet->payload_packet_len == 10) + { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Sign In \n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow); + return; + } + /* /\* SCREEN_NAME *\/ */ + /* if (get_u_int16_t(packet->payload, 10) == htons(SCREEN_NAME)) /\* packet->payload[10] == 0x00 && packet->payload[11] == 0x01 *\/ */ + /* { */ + /* NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Screen Name \n"); */ + /* ndpi_int_oscar_add_connection(ndpi_struct, flow); */ + /* return; */ + /* } */ + /* /\* PASSWD *\/ */ + /* if (get_u_int16_t(packet->payload, 10) == htons(PASSWD)) /\* packet->payload[10] == 0x00 && packet->payload[11] == 0x02 *\/ */ + /* { */ + /* NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Password (roasted) \n"); */ + /* ndpi_int_oscar_add_connection(ndpi_struct, flow); */ + /* return; */ + /* } */ + /* CLIENT_NAME */ + if (get_u_int16_t(packet->payload, 10) == htons(CLIENT_NAME)) /* packet->payload[10] == 0x00 && packet->payload[11] == 0x03 */ + { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Client Name \n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow); + return; + } + /* LOGIN_COOKIE */ + if (get_u_int16_t(packet->payload, 10) == htons(LOGIN_COOKIE) && + get_u_int16_t(packet->payload, 12) == htons(0x0100)) + { + if(get_u_int16_t(packet->payload, packet->payload_packet_len - 5) == htons(MULTICONN_FLAGS)) /* MULTICONN_FLAGS */ + { + if(get_u_int16_t(packet->payload, packet->payload_packet_len - 3) == htons(0x0001)) + if(get_u_int8_t(packet->payload, packet->payload_packet_len - 1) == htons(0x00) || + get_u_int8_t(packet->payload, packet->payload_packet_len - 1) == htons(0x01) || + get_u_int8_t(packet->payload, packet->payload_packet_len - 1) == htons(0x03)) + { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Login \n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow); + return; + } + } + } + /* MAJOR_VERSION */ + if (get_u_int16_t(packet->payload, 10) == htons(MAJOR_VERSION)) + { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Major_Version \n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow); + return; + } + /* MINOR_VERSION */ + if (get_u_int16_t(packet->payload, 10) == htons(MINOR_VERSION)) + { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Minor_Version \n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow); + return; + } + /* POINT_VERSION */ + if (get_u_int16_t(packet->payload, 10) == htons(POINT_VERSION)) + { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Point_Version \n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow); + return; + } + /* BUILD_NUM */ + if (get_u_int16_t(packet->payload, 10) == htons(BUILD_NUM)) + { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Build_Num \n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow); + return; + } + /* CLIENT_RECONNECT */ + if (get_u_int16_t(packet->payload, 10) == htons(CLIENT_RECONNECT)) + { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR - Client_Reconnect \n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow); + return; + } + } + + /* + Messages using the FLAP connection, usually a SNAC message. + + DATA -> FLAP__DATA_FRAME + +-------------------------+ + + FLAP__Header | 6 byte + + + SNAC__Header | 10 byte + + + snac | + + +-------------------------+ + + SNAC__Header + +----------------------------------------------+ + + ID | 4 byte (2 foodgroup + 2 type) + + + FLAGS | 2 byte + + + requestId | 4 byte + + +----------------------------------------------+ + */ + if (channel == DATA) + { + family = get_u_int16_t(packet->payload, 6); + type = get_u_int16_t(packet->payload, 8); + flag = get_u_int16_t(packet->payload, 10); + req_ID = get_u_int32_t(packet->payload, 12); + + /* Family 0x0001 */ + if (family == htons(GE_SE_CTL)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + case (0x0003): break; + case (0x0004): break; + case (0x0005): break; + case (0x0006): break; + case (0x0007): break; + case (0x0008): break; + case (0x0009): break; + case (0x000a): break; + case (0x000b): break; + case (0x000c): break; + case (0x000d): break; + case (0x000e): break; + case (0x000f): break; + case (0x0010): break; + case (0x0011): break; + case (0x0012): break; + case (0x0013): break; + case (0x0014): break; + case (0x0015): break; + case (0x0016): break; + case (0x0017): break; + case (0x0018): break; + case (0x001e): break; + case (0x001f): break; + case (0x0020): break; + case (0x0021): break; + default: excluded = 1; + } + } + /* Family 0x0002 */ + if (family == htons(LOC_SRV)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + case (0x0003): break; + case (0x0004): break; + case (0x0005): break; + case (0x0006): break; + case (0x0007): break; + case (0x0008): break; + case (0x0009): break; + case (0x000a): break; + case (0x000b): break; + case (0x000c): break; + case (0x000f): break; + case (0x0010): break; + case (0x0015): break; + default: excluded = 1; + } + } + /* Family 0x0003 */ + if (family == htons(BUDDY_LIST)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + case (0x0003): break; + case (0x0004): break; + case (0x0005): break; + case (0x0006): break; + case (0x0007): break; + case (0x0008): break; + case (0x0009): break; + case (0x000a): break; + case (0x000b): break; + case (0x000c): break; + default: excluded = 1; + } + } + /* Family 0x0004 */ + if (family == htons(IM)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + case (0x0003): break; + case (0x0004): break; + case (0x0005): break; + case (0x0006): break; + case (0x0007): break; + case (0x0008): break; + case (0x0009): break; + case (0x000a): break; + case (0x000b): break; + case (0x000c): break; + case (0x0014): break; + default: excluded = 1; + } + } + /* Family 0x0006 */ + if (family == htons(IS)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + case (0x0003): break; + default: excluded = 1; + } + } + /* Family 0x0007 */ + if (family == htons(ACC_ADM)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + case (0x0003): break; + case (0x0004): break; + case (0x0005): break; + case (0x0006): break; + case (0x0007): break; + case (0x0008): break; + case (0x0009): break; + default: excluded = 1; + } + } + /* Family 0x0008 */ + if (family == htons(POPUP)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + default: excluded = 1; + } + } + /* Family 0x0009 */ + if (family == htons(PMS)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + case (0x0003): break; + case (0x0004): break; + case (0x0005): break; + case (0x0006): break; + case (0x0007): break; + case (0x0008): break; + case (0x0009): break; + case (0x000a): break; + case (0x000b): break; + default: excluded = 1; + } + } + /* Family 0x000b */ + if (family == htons(USS)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + case (0x0003): break; + case (0x0004): break; + default: excluded = 1; + } + } + /* Family 0x000d */ + if (family == htons(CHAT_ROOM_SETUP)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + case (0x0003): break; + case (0x0004): break; + case (0x0005): break; + case (0x0006): break; + case (0x0007): break; + case (0x0008): break; + case (0x0009): break; + default: excluded = 1; + } + } + /* Family 0x000e */ + if (family == htons(CHAT_ROOM_ACT)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + case (0x0003): break; + case (0x0004): break; + case (0x0005): break; + case (0x0006): break; + case (0x0007): break; + case (0x0008): break; + case (0x0009): break; + default: excluded = 1; + } + } + /* Family 0x000f */ + if (family == htons(USER_SRCH)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + case (0x0003): break; + case (0x0004): break; + case (0x0005): break; + default: excluded = 1; + } + } + /* Family 0x0010 */ + if (family == htons(BUDDY_ICON_SERVER)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + case (0x0003): break; + case (0x0004): break; + case (0x0005): break; + case (0x0006): break; + case (0x0007): break; + default: excluded = 1; + } + } + /* Family 0x0013 */ + if (family == htons(SERVER_STORED_INFO)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + case (0x0003): break; + case (0x0004): break; + case (0x0005): break; + case (0x0006): break; + case (0x0007): break; + case (0x0008): break; + case (0x0009): break; + case (0x000a): break; + case (0x000e): break; + case (0x000f): break; + case (0x0011): break; + case (0x0012): break; + case (0x0014): break; + case (0x0015): break; + case (0x0016): break; + case (0x0018): break; + case (0x001a): break; + case (0x001b): break; + case (0x001c): break; + default: excluded = 1; + } + } + /* Family 0x0015 */ + if (family == htons(ICQ)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + case (0x0003): break; + default: excluded = 1; + } + } + /* Family 0x0017 */ + if (family == htons(SERVER_STORED_INFO)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + case (0x0003): break; + case (0x0004): break; + case (0x0005): break; + case (0x0006): break; + case (0x0007): break; + case (0x000a): break; + case (0x000b): break; + default: excluded = 1; + } + } + /* Family 0x0018 */ + if (family == htons(EMAIL)) + { + /* TODO */ + } + /* Family 0x0085 */ + if (family == htons(SERVER_STORED_INFO)) + { + switch (type) { + + case (0x0001): break; + case (0x0002): break; + case (0x0003): break; + default: excluded = 1; + } + } - /* OSCAR IM - * +----+----+------+------+----------+-----------+ - * |0x2a|Code|SeqNum|PktLen|FNACfamily|FNACsubtype| - * +----+----+------+------+----------+-----------+ - * Code 1 Byte : 0x02 SNAC Header Code; - * SeqNum and PktLen are 2 Bytes each - * FNACfamily 2 Byte : 0x0004 IM Messaging - * FNACEsubtype 2 Byte : 0x0006 IM Outgoing Message, 0x000c IM Message Acknowledgment - * */ - if (packet->payload[1] == 0x02 - && ntohs(get_u_int16_t(packet->payload, 4)) >= - packet->payload_packet_len - 6 && get_u_int16_t(packet->payload, 6) == htons(0x0004) - && (get_u_int16_t(packet->payload, 8) == htons(0x0006) - || get_u_int16_t(packet->payload, 8) == htons(0x000c))) { - NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR IM Detected \n"); - ndpi_int_oscar_add_connection(ndpi_struct, flow); - return; + /* mettere un flag per family e type che se non settat -> excluded oscar */ + if(excluded == 1) + { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "exclude oscar.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OSCAR); + } + + /* flag */ + if (flag == htons(0x0000)|| flag == htons(0x8000) || flag == htons(0x0001)) + { + /* request ID */ + if((req_ID >= 0 && req_ID <= 2147483647) || + (req_ID >= 2147483648 && req_ID <= 4294967295)) + { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Detected \n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow); + return; + } + } + } + /* + ERROR -> FLAP__ERROR_CHANNEL_0x03 + A FLAP error - rare + */ + if (channel == ERROR) + { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Detected - Error frame \n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow); + return; + } + /* + Close down the FLAP connection gracefully. + SIGNOFF: FLAP__SIGNOFF_CHANNEL_0x04 + */ + if (channel == SIGNOFF) + { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Detected - Error frame \n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow); + return; + } + /* + Send a heartbeat to server to help keep connection open. + KEEP_ALIVE: FLAP__KEEP_ALIVE_CHANNEL_0x05 + */ + if (channel == KEEP_ALIVE) + { + NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Detected - Error frame \n"); + ndpi_int_oscar_add_connection(ndpi_struct, flow); + return; + } } - } /* detect http connections */ |