void ndpi_search_tftp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; NDPI_LOG(NDPI_PROTOCOL_TFTP, ndpi_struct, NDPI_LOG_DEBUG, "search TFTP.\n"); if (packet->payload_packet_len > 3 && flow->l4.udp.tftp_stage == 0 && ntohl(get_u_int32_t(packet->payload, 0)) == 0x00030001) { NDPI_LOG(NDPI_PROTOCOL_TFTP, ndpi_struct, NDPI_LOG_DEBUG, "maybe tftp. need next packet.\n"); flow->l4.udp.tftp_stage = 1; return; } if (packet->payload_packet_len > 3 && (flow->l4.udp.tftp_stage == 1) && ntohl(get_u_int32_t(packet->payload, 0)) == 0x00040001) { NDPI_LOG(NDPI_PROTOCOL_TFTP, ndpi_struct, NDPI_LOG_DEBUG, "found tftp.\n"); ndpi_int_tftp_add_connection(ndpi_struct, flow); return; } if (packet->payload_packet_len > 1 && ((packet->payload[0] == 0 && packet->payload[packet->payload_packet_len - 1] == 0) || (packet->payload_packet_len == 4 && ntohl(get_u_int32_t(packet->payload, 0)) == 0x00040000))) { NDPI_LOG(NDPI_PROTOCOL_TFTP, ndpi_struct, NDPI_LOG_DEBUG, "skip initial packet.\n"); return; } NDPI_LOG(NDPI_PROTOCOL_TFTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude TFTP.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TFTP); }
void ndpi_search_fiesta(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "search fiesta.\n"); if (flow->l4.tcp.fiesta_stage == 0 && packet->payload_packet_len == 5 && get_u_int16_t(packet->payload, 0) == ntohs(0x0407) && (packet->payload[2] == 0x08) && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01)) { NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "maybe fiesta symmetric, first packet.\n"); flow->l4.tcp.fiesta_stage = 1 + packet->packet_direction; goto maybe_fiesta; } if (flow->l4.tcp.fiesta_stage == (2 - packet->packet_direction) && ((packet->payload_packet_len > 1 && packet->payload_packet_len - 1 == packet->payload[0]) || (packet->payload_packet_len > 3 && packet->payload[0] == 0 && get_l16(packet->payload, 1) == packet->payload_packet_len - 3))) { NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "Maybe fiesta.\n"); goto maybe_fiesta; } if (flow->l4.tcp.fiesta_stage == (1 + packet->packet_direction)) { if (packet->payload_packet_len == 4 && get_u_int32_t(packet->payload, 0) == htonl(0x03050c01)) { goto add_fiesta; } if (packet->payload_packet_len == 5 && get_u_int32_t(packet->payload, 0) == htonl(0x04030c01) && packet->payload[4] == 0) { goto add_fiesta; } if (packet->payload_packet_len == 6 && get_u_int32_t(packet->payload, 0) == htonl(0x050e080b)) { goto add_fiesta; } if (packet->payload_packet_len == 100 && packet->payload[0] == 0x63 && packet->payload[61] == 0x52 && packet->payload[81] == 0x5a && get_u_int16_t(packet->payload, 1) == htons(0x3810) && get_u_int16_t(packet->payload, 62) == htons(0x6f75)) { goto add_fiesta; } if (packet->payload_packet_len > 3 && packet->payload_packet_len - 1 == packet->payload[0] && get_u_int16_t(packet->payload, 1) == htons(0x140c)) { goto add_fiesta; } } NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "exclude fiesta.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FIESTA); return; maybe_fiesta: NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "Stage is set to %d.\n", flow->l4.tcp.fiesta_stage); return; add_fiesta: NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "detected fiesta.\n"); ndpi_int_fiesta_add_connection(ndpi_struct, flow); return; }
void ndpi_search_world_of_kung_fu(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; NDPI_LOG(NDPI_PROTOCOL_WORLD_OF_KUNG_FU, ndpi_struct, NDPI_LOG_DEBUG, "search world_of_kung_fu.\n"); if ((packet->payload_packet_len == 16) && ntohl(get_u_int32_t(packet->payload, 0)) == 0x0c000000 && ntohl(get_u_int32_t(packet->payload, 4)) == 0xd2000c00 && (packet->payload[9] == 0x16) && ntohs(get_u_int16_t(packet->payload, 10)) == 0x0000 && ntohs(get_u_int16_t(packet->payload, 14)) == 0x0000) { NDPI_LOG(NDPI_PROTOCOL_WORLD_OF_KUNG_FU, ndpi_struct, NDPI_LOG_DEBUG, "detected world_of_kung_fu.\n"); ndpi_int_world_of_kung_fu_add_connection(ndpi_struct, flow); return; } NDPI_LOG(NDPI_PROTOCOL_WORLD_OF_KUNG_FU, ndpi_struct, NDPI_LOG_DEBUG, "exclude world_of_kung_fu.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_WORLD_OF_KUNG_FU); }
void ndpi_search_kontiki(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; if (packet->payload_packet_len == 4 && (get_u_int32_t(packet->payload, 0) == htonl(0x02010100))) { NDPI_LOG(NDPI_PROTOCOL_KONTIKI, ndpi_struct, NDPI_LOG_DEBUG, "Kontiki UDP detected.\n"); ndpi_int_kontiki_add_connection(ndpi_struct, flow); return; } if (packet->payload_packet_len > 0 && packet->payload[0] == 0x02) { if (packet->payload_packet_len == 20 && (get_u_int32_t(packet->payload, 16) == htonl(0x02040100))) { NDPI_LOG(NDPI_PROTOCOL_KONTIKI, ndpi_struct, NDPI_LOG_DEBUG, "Kontiki UDP detected.\n"); ndpi_int_kontiki_add_connection(ndpi_struct, flow); return; } if (packet->payload_packet_len == 16 && (get_u_int32_t(packet->payload, 12) == htonl(0x000004e4))) { NDPI_LOG(NDPI_PROTOCOL_KONTIKI, ndpi_struct, NDPI_LOG_DEBUG, "Kontiki UDP detected.\n"); ndpi_int_kontiki_add_connection(ndpi_struct, flow); return; } } NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_KONTIKI); }
static void ndpi_search_i23v5(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; u_int32_t i; u_int32_t sum; NDPI_LOG(NDPI_PROTOCOL_I23V5, ndpi_struct, NDPI_LOG_DEBUG, "search i23v5.\n"); /* * encryption of i23v5 is tricky: the 7th bit of the first byte and the sescond bit of the second byte must be set. * Three lengths are written in three packets after 0x0d58, 0x0e58 and 0x0f58 but without a certain order. * The sum of the three packets is in another packet at any place. */ if (packet->payload_packet_len > 7 && ((packet->payload[0] & 0x04) == 0x04 && (packet->payload[2] & 0x80) == 0x80)) { NDPI_LOG(NDPI_PROTOCOL_I23V5, ndpi_struct, NDPI_LOG_DEBUG, "found i23v5 handshake bits.\n"); for (i = 3; i < packet->payload_packet_len - 5; i++) { if (packet->payload[i] == 0x0d && packet->payload[i + 1] == 0x58) { NDPI_LOG(NDPI_PROTOCOL_I23V5, ndpi_struct, NDPI_LOG_DEBUG, "found first i23v5 key len.\n"); flow->i23v5_len1 = get_u_int32_t(packet->payload, i + 2); return; } } for (i = 3; i < packet->payload_packet_len - 5; i++) { if (packet->payload[i] == 0x0e && packet->payload[i + 1] == 0x58) { NDPI_LOG(NDPI_PROTOCOL_I23V5, ndpi_struct, NDPI_LOG_DEBUG, "found second i23v5 key len.\n"); flow->i23v5_len2 = get_u_int32_t(packet->payload, i + 2); return; } } for (i = 3; i < packet->payload_packet_len - 5; i++) { if (packet->payload[i] == 0x0f && packet->payload[i + 1] == 0x58) { NDPI_LOG(NDPI_PROTOCOL_I23V5, ndpi_struct, NDPI_LOG_DEBUG, "found third i23v5 key len.\n"); flow->i23v5_len3 = get_u_int32_t(packet->payload, i + 2); return; } } if (flow->i23v5_len1 != 0 && flow->i23v5_len2 != 0 && flow->i23v5_len3 != 0) { for (i = 3; i < packet->payload_packet_len - 5; i++) { sum = flow->i23v5_len1 + flow->i23v5_len2 + flow->i23v5_len3; if (get_u_int32_t(packet->payload, i) == sum) { NDPI_LOG(NDPI_PROTOCOL_I23V5, ndpi_struct, NDPI_LOG_DEBUG, "key sum matches.\n"); ndpi_i23v5_add_connection(ndpi_struct, flow); } } } } NDPI_LOG(NDPI_PROTOCOL_I23V5, ndpi_struct, NDPI_LOG_DEBUG, "exclude i23v5.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_I23V5); }
static u_int8_t is_special_aimini_host(struct ndpi_int_one_line_struct host_line) { if (host_line.ptr != NULL && host_line.len >= NDPI_STATICSTRING_LEN("X.X.X.X.aimini.net")) { if ((get_u_int32_t(host_line.ptr, 0) & htonl(0x00ff00ff)) == htonl(0x002e002e) && (get_u_int32_t(host_line.ptr, 4) & htonl(0x00ff00ff)) == htonl(0x002e002e) && memcmp(&host_line.ptr[8], "aimini.net", NDPI_STATICSTRING_LEN("aimini.net")) == 0) { return 1; } } return 0; }
void ndpi_search_quake(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; if ((packet->payload_packet_len == 14 && get_u_int16_t(packet->payload, 0) == 0xffff && memcmp(&packet->payload[2], "getInfo", 7) == 0) || (packet->payload_packet_len == 17 && get_u_int16_t(packet->payload, 0) == 0xffff && memcmp(&packet->payload[2], "challenge", 9) == 0) || (packet->payload_packet_len > 20 && packet->payload_packet_len < 30 && get_u_int16_t(packet->payload, 0) == 0xffff && memcmp(&packet->payload[2], "getServers", 10) == 0)) { NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake IV detected.\n"); ndpi_int_quake_add_connection(ndpi_struct, flow); return; } /* Quake III/Quake Live */ if (packet->payload_packet_len == 15 && get_u_int32_t(packet->payload, 0) == 0xffffffff && memcmp(&packet->payload[4], "getinfo", NDPI_STATICSTRING_LEN("getinfo")) == 0) { NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake III Arena/Quake Live detected.\n"); ndpi_int_quake_add_connection(ndpi_struct, flow); return; } if (packet->payload_packet_len == 16 && get_u_int32_t(packet->payload, 0) == 0xffffffff && memcmp(&packet->payload[4], "getchallenge", NDPI_STATICSTRING_LEN("getchallenge")) == 0) { NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake III Arena/Quake Live detected.\n"); ndpi_int_quake_add_connection(ndpi_struct, flow); return; } if (packet->payload_packet_len > 20 && packet->payload_packet_len < 30 && get_u_int32_t(packet->payload, 0) == 0xffffffff && memcmp(&packet->payload[4], "getservers", NDPI_STATICSTRING_LEN("getservers")) == 0) { NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake III Arena/Quake Live detected.\n"); ndpi_int_quake_add_connection(ndpi_struct, flow); return; } /* ports for startup packet: Quake I 26000 (starts with 0x8000) Quake II 27910 Quake III 27960 (increases with each player) Quake IV 27650 Quake World 27500 Quake Wars ????? */ NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake excluded.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUAKE); }
static void ndpi_search_udp_msn_misc(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; struct ndpi_id_struct *src = flow->src; struct ndpi_id_struct *dst = flow->dst; /* do we have an msn login ? */ if ((src == NULL || NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) == 0) && (dst == NULL || NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) == 0)) { NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MSN); return; } /* asymmetric ft detection works */ if (packet->payload_packet_len == 20 && get_u_int32_t(packet->payload, 4) == 0 && packet->payload[9] == 0 && get_u_int16_t(packet->payload, 10) == htons(0x0100)) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "msn udp misc data connection detected\n"); ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); } /* asymmetric detection working. */ return; //} }
void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; /* this detection also works for asymmetric dhcp traffic */ /*check standard DHCP 0.0.0.0:68 -> 255.255.255.255:67 */ if (packet->payload_packet_len >= 244 && (packet->udp->source == htons(67) || packet->udp->source == htons(68)) && (packet->udp->dest == htons(67) || packet->udp->dest == htons(68)) && get_u_int32_t(packet->payload, 236) == htonl(0x63825363) && get_u_int16_t(packet->payload, 240) == htons(0x3501)) { NDPI_LOG(NDPI_PROTOCOL_DHCP, ndpi_struct, NDPI_LOG_DEBUG, "DHCP request\n"); ndpi_int_dhcp_add_connection(ndpi_struct, flow); return; } NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DHCP); }
static void ndpi_search_mysql_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; if (packet->payload_packet_len > 37 //min length && get_u_int16_t(packet->payload, 0) == packet->payload_packet_len - 4 //first 3 bytes are length && get_u_int8_t(packet->payload, 2) == 0x00 //3rd byte of packet length && get_u_int8_t(packet->payload, 3) == 0x00 //packet sequence number is 0 for startup packet && get_u_int8_t(packet->payload, 5) > 0x30 //server version > 0 && get_u_int8_t(packet->payload, 5) < 0x37 //server version < 7 && get_u_int8_t(packet->payload, 6) == 0x2e //dot ) { u_int32_t a; for (a = 7; a + 31 < packet->payload_packet_len; a++) { if (packet->payload[a] == 0x00) { if (get_u_int8_t(packet->payload, a + 13) == 0x00 //filler byte && get_u_int64_t(packet->payload, a + 19) == 0x0ULL //13 more && get_u_int32_t(packet->payload, a + 27) == 0x0 //filler bytes && get_u_int8_t(packet->payload, a + 31) == 0x0) { NDPI_LOG(NDPI_PROTOCOL_MYSQL, ndpi_struct, NDPI_LOG_DEBUG, "MySQL detected.\n"); ndpi_int_mysql_add_connection(ndpi_struct, flow); return; } break; } } } NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MYSQL); }
static void ndpi_search_steam(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; if (flow->l4.tcp.steam_stage == 0) { if (packet->payload_packet_len == 4 && ntohl(get_u_int32_t(packet->payload, 0)) <= 0x07 && ntohs(packet->tcp->dest) >= 27030 && ntohs(packet->tcp->dest) <= 27040) { flow->l4.tcp.steam_stage = 1 + packet->packet_direction; NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "steam stage 1\n"); return; } } else if (flow->l4.tcp.steam_stage == 2 - packet->packet_direction) { if ((packet->payload_packet_len == 1 || packet->payload_packet_len == 5) && packet->payload[0] == 0x01) { ndpi_int_steam_add_connection(ndpi_struct, flow); NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "steam detected\n"); return; } } NDPI_LOG(NDPI_PROTOCOL_STEAM, ndpi_struct, NDPI_LOG_DEBUG, "steam excluded.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_STEAM); }
void ndpi_search_guildwars_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "search guildwars.\n"); if (packet->payload_packet_len == 64 && get_u_int16_t(packet->payload, 1) == ntohs(0x050c) && memcmp(&packet->payload[50], "@2&P", 4) == 0) { NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "GuildWars version 29.350: found.\n"); ndpi_int_guildwars_add_connection(ndpi_struct, flow); return; } if (packet->payload_packet_len == 16 && get_u_int16_t(packet->payload, 1) == ntohs(0x040c) && get_u_int16_t(packet->payload, 4) == ntohs(0xa672) && packet->payload[8] == 0x01 && packet->payload[12] == 0x04) { NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "GuildWars version 29.350: found.\n"); ndpi_int_guildwars_add_connection(ndpi_struct, flow); return; } if (packet->payload_packet_len == 21 && get_u_int16_t(packet->payload, 0) == ntohs(0x0100) && get_u_int32_t(packet->payload, 5) == ntohl(0xf1001000) && packet->payload[9] == 0x01) { NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "GuildWars version 216.107.245.50: found.\n"); ndpi_int_guildwars_add_connection(ndpi_struct, flow); return; } NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "exclude guildwars.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_GUILDWARS); }
void ndpi_search_nfs(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; u_int8_t offset = 0; if (packet->tcp != NULL) offset = 4; if (packet->payload_packet_len < (40 + offset)) goto exclude_nfs; NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS user match stage 1\n"); if (offset != 0 && get_u_int32_t(packet->payload, 0) != htonl(0x80000000 + packet->payload_packet_len - 4)) goto exclude_nfs; NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS user match stage 2\n"); if (get_u_int32_t(packet->payload, 4 + offset) != 0) goto exclude_nfs; NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS user match stage 3\n"); if (get_u_int32_t(packet->payload, 8 + offset) != htonl(0x02)) goto exclude_nfs; NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS match stage 3\n"); if (get_u_int32_t(packet->payload, 12 + offset) != htonl(0x000186a5) && get_u_int32_t(packet->payload, 12 + offset) != htonl(0x000186a3) && get_u_int32_t(packet->payload, 12 + offset) != htonl(0x000186a0)) goto exclude_nfs; NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS match stage 4\n"); if (ntohl(get_u_int32_t(packet->payload, 16 + offset)) > 4) goto exclude_nfs; NDPI_LOG(NDPI_PROTOCOL_NFS, ndpi_struct, NDPI_LOG_DEBUG, "NFS match\n"); ndpi_int_nfs_add_connection(ndpi_struct, flow); return; exclude_nfs: NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_NFS); }
void ndpi_search_smb_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; NDPI_LOG(NDPI_PROTOCOL_SMB, ndpi_struct, NDPI_LOG_DEBUG, "search SMB.\n"); if (packet->tcp->dest == htons(445) && packet->payload_packet_len > (32 + 4 + 4) && (packet->payload_packet_len - 4) == ntohl(get_u_int32_t(packet->payload, 0)) && get_u_int32_t(packet->payload, 4) == htonl(0xff534d42)) { NDPI_LOG(NDPI_PROTOCOL_SMB, ndpi_struct, NDPI_LOG_DEBUG, "found SMB.\n"); ndpi_int_smb_add_connection(ndpi_struct, flow); return; } NDPI_LOG(NDPI_PROTOCOL_SMB, ndpi_struct, NDPI_LOG_DEBUG, "exclude SMB.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SMB); }
static u_int8_t check_for_gadugadu_payload_pattern(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "Gadu-Gadu: check for 0xbebadec0 pattern in payload.\n"); if (packet->payload_packet_len == 12) { if ((flow->packet_counter == 1) && (ntohl(get_u_int32_t(packet->payload, 0)) == 0xbebadec0)) { flow->l4.tcp.gadugadu_stage++; return 1; } if ((flow->l4.tcp.gadugadu_stage == 1) && (flow->packet_counter == 2) && (ntohl(get_u_int32_t(packet->payload, 0)) == 0xbebadec0)) { NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "Gadu-Gadu: gadugadu pattern bebadec0 FOUND \n"); ndpi_int_gadugadu_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return 1; } } return 0; }
static void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; /* I have observed 0a,0c,0d,0e at packet->payload[19/21], maybe there are other possibilities */ if (packet->payload_packet_len >= 4 && ntohl(get_u_int32_t(packet->payload, 0)) == packet->payload_packet_len - 4) { if (packet->payload_packet_len > 19 && packet->payload[14] == 0x05 && (packet->payload[19] == 0x0a || packet->payload[19] == 0x0c || packet->payload[19] == 0x0d || packet->payload[19] == 0x0e)) { NDPI_LOG(NDPI_PROTOCOL_KERBEROS, ndpi_struct, NDPI_LOG_DEBUG, "found KERBEROS\n"); ndpi_int_kerberos_add_connection(ndpi_struct, flow); return; } if (packet->payload_packet_len > 21 && packet->payload[16] == 0x05 && (packet->payload[21] == 0x0a || packet->payload[21] == 0x0c || packet->payload[21] == 0x0d || packet->payload[21] == 0x0e)) { NDPI_LOG(NDPI_PROTOCOL_KERBEROS, ndpi_struct, NDPI_LOG_DEBUG, "found KERBEROS\n"); ndpi_int_kerberos_add_connection(ndpi_struct, flow); return; } } NDPI_LOG(NDPI_PROTOCOL_KERBEROS, ndpi_struct, NDPI_LOG_DEBUG, "no KERBEROS detected.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_KERBEROS); }
void ndpi_search_afp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src = flow->src; // struct ndpi_id_struct *dst = flow->dst; /* * this will detect the OpenSession command of the Data Stream Interface (DSI) protocol * which is exclusively used by the Apple Filing Protocol (AFP) on TCP/IP networks */ if (packet->payload_packet_len >= 22 && get_u_int16_t(packet->payload, 0) == htons(0x0004) && get_u_int16_t(packet->payload, 2) == htons(0x0001) && get_u_int32_t(packet->payload, 4) == 0 && get_u_int32_t(packet->payload, 8) == htonl(packet->payload_packet_len - 16) && get_u_int32_t(packet->payload, 12) == 0 && get_u_int16_t(packet->payload, 16) == htons(0x0104)) { NDPI_LOG(NDPI_PROTOCOL_AFP, ndpi_struct, NDPI_LOG_DEBUG, "AFP: DSI OpenSession detected.\n"); ndpi_int_afp_add_connection(ndpi_struct, flow); return; } /* * detection of GetStatus command of DSI protocl */ if (packet->payload_packet_len >= 18 && get_u_int16_t(packet->payload, 0) == htons(0x0003) && get_u_int16_t(packet->payload, 2) == htons(0x0001) && get_u_int32_t(packet->payload, 4) == 0 && get_u_int32_t(packet->payload, 8) == htonl(packet->payload_packet_len - 16) && get_u_int32_t(packet->payload, 12) == 0 && get_u_int16_t(packet->payload, 16) == htons(0x0f00)) { NDPI_LOG(NDPI_PROTOCOL_AFP, ndpi_struct, NDPI_LOG_DEBUG, "AFP: DSI GetStatus detected.\n"); ndpi_int_afp_add_connection(ndpi_struct, flow); return; } NDPI_LOG(NDPI_PROTOCOL_AFP, ndpi_struct, NDPI_LOG_DEBUG, "AFP excluded.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_AFP); }
void ndpi_search_rtp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; if (packet->udp) { ndpi_rtp_search(ndpi_struct, flow, packet->payload, packet->payload_packet_len); } else if (packet->tcp) { /* skip special packets seen at yahoo traces */ if (packet->payload_packet_len >= 20 && ntohs(get_u_int16_t(packet->payload, 2)) + 20 == packet->payload_packet_len && packet->payload[0] == 0x90 && packet->payload[1] >= 0x01 && packet->payload[1] <= 0x07) { if (flow->packet_counter == 2) flow->l4.tcp.rtp_special_packets_seen = 1; NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "skipping STUN-like, special yahoo packets with payload[0] == 0x90.\n"); return; } #ifdef NDPI_PROTOCOL_STUN /* TODO the rtp detection sometimes doesn't exclude rtp * so for TCP flows only run the detection if STUN has been * detected (or RTP is already detected) * If flows will be seen which start directly with RTP * we can remove this restriction */ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STUN || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_RTP) { /* RTP may be encapsulated in TCP packets */ if (packet->payload_packet_len >= 2 && ntohs(get_u_int16_t(packet->payload, 0)) + 2 == packet->payload_packet_len) { /* TODO there could be several RTP packets in a single TCP packet so maybe the detection could be * improved by checking only the RTP packet of given length */ ndpi_rtp_search(ndpi_struct, flow, packet->payload + 2, packet->payload_packet_len - 2); return; } } if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN && flow->l4.tcp.rtp_special_packets_seen == 1) { if (packet->payload_packet_len >= 4 && ntohl(get_u_int32_t(packet->payload, 0)) + 4 == packet->payload_packet_len) { /* TODO there could be several RTP packets in a single TCP packet so maybe the detection could be * improved by checking only the RTP packet of given length */ ndpi_rtp_search(ndpi_struct, flow, packet->payload + 4, packet->payload_packet_len - 4); return; } } if (NDPI_FLOW_PROTOCOL_EXCLUDED(ndpi_struct, flow, NDPI_PROTOCOL_STUN)) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude rtp.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP); } else { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "STUN not yet excluded, need next packet.\n"); } #else NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude rtp.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP); #endif } }
static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, const u_int8_t * payload, const u_int16_t payload_len) { struct ndpi_packet_struct *packet = &flow->packet; u_int8_t stage; u_int16_t seqnum = ntohs(get_u_int16_t(payload, 2)); NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "search rtp.\n"); if (payload_len == 4 && get_u_int32_t(packet->payload, 0) == 0 && flow->packet_counter < 8) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "need next packet, maybe ClearSea out calls.\n"); return; } if (payload_len == 5 && memcmp(payload, "hello", 5) == 0) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "need next packet, initial hello packet of SIP out calls.\n"); return; } if (payload_len == 1 && payload[0] == 0) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "need next packet, payload_packet_len == 1 && payload[0] == 0.\n"); return; } if (payload_len == 3 && memcmp(payload, "png", 3) == 0) { /* weird packet found in Ninja GlobalIP trace */ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "skipping packet with len = 3 and png payload.\n"); return; } if (payload_len < 12) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "minimal packet size for rtp packets: 12.\n"); goto exclude_rtp; } if (payload_len == 12 && get_u_int32_t(payload, 0) == 0 && get_u_int32_t(payload, 4) == 0 && get_u_int32_t(payload, 8) == 0) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "skipping packet with len = 12 and only 0-bytes.\n"); return; } if ((payload[0] & 0xc0) == 0xc0 || (payload[0] & 0xc0) == 0x40 || (payload[0] & 0xc0) == 0x00) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "version = 3 || 1 || 0, maybe first rtp packet.\n"); return; } if ((payload[0] & 0xc0) != 0x80) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "rtp version must be 2, first two bits of a packets must be 10.\n"); goto exclude_rtp; } /* rtp_payload_type are the last seven bits of the second byte */ if (flow->rtp_payload_type[packet->packet_direction] != (payload[1] & 0x7F)) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "payload_type has changed, reset stages.\n"); packet->packet_direction == 0 ? (flow->rtp_stage1 = 0) : (flow->rtp_stage2 = 0); } /* first bit of first byte is not part of payload_type */ flow->rtp_payload_type[packet->packet_direction] = payload[1] & 0x7F; stage = (packet->packet_direction == 0 ? flow->rtp_stage1 : flow->rtp_stage2); if (stage > 0) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "stage = %u.\n", packet->packet_direction == 0 ? flow->rtp_stage1 : flow->rtp_stage2); if (flow->rtp_ssid[packet->packet_direction] != get_u_int32_t(payload, 8)) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "ssid has changed, goto exclude rtp.\n"); goto exclude_rtp; } if (seqnum == flow->rtp_seqnum[packet->packet_direction]) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "maybe \"retransmission\", need next packet.\n"); return; } else if ((u_int16_t) (seqnum - flow->rtp_seqnum[packet->packet_direction]) < RTP_MAX_OUT_OF_ORDER) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "new packet has larger sequence number (within valid range)\n"); update_seq(ndpi_struct, flow, packet->packet_direction, seqnum); } else if ((u_int16_t) (flow->rtp_seqnum[packet->packet_direction] - seqnum) < RTP_MAX_OUT_OF_ORDER) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "new packet has smaller sequence number (within valid range)\n"); init_seq(ndpi_struct, flow, packet->packet_direction, seqnum, 1); } else { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "sequence number diff is too big, goto exclude rtp.\n"); goto exclude_rtp; } } else { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "rtp_ssid[%u] = %u.\n", packet->packet_direction, flow->rtp_ssid[packet->packet_direction]); flow->rtp_ssid[packet->packet_direction] = get_u_int32_t(payload, 8); if (flow->packet_counter < 3) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "packet_counter < 3, need next packet.\n"); } init_seq(ndpi_struct, flow, packet->packet_direction, seqnum, 1); } if (seqnum <= 3) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "sequence_number = %u, too small, need next packet, return.\n", seqnum); return; } if (stage == 3) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "add connection I.\n"); ndpi_int_rtp_add_connection(ndpi_struct, flow); } else { packet->packet_direction == 0 ? flow->rtp_stage1++ : flow->rtp_stage2++; NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "stage[%u]++; need next packet.\n", packet->packet_direction); } return; exclude_rtp: #ifdef NDPI_PROTOCOL_STUN if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STUN || packet->real_protocol_read_only == NDPI_PROTOCOL_STUN) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "STUN: is detected, need next packet.\n"); return; } #endif /* NDPI_PROTOCOL_STUN */ NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude rtp.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP); }
void ndpi_search_snmp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; if (packet->payload_packet_len > 32 && packet->payload[0] == 0x30) { int offset; switch (packet->payload[1]) { case 0x81: offset = 3; break; case 0x82: offset = 4; break; default: if (packet->payload[1] > 0x82) { NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP excluded, second byte is > 0x82\n"); goto excl; } offset = 2; } if (get_u_int16_t(packet->payload, offset) != htons(0x0201)) { NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP excluded, 0x0201 pattern not found\n"); goto excl; } if (packet->payload[offset + 2] >= 0x04) { NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP excluded, version > 3\n"); goto excl; } if (flow->l4.udp.snmp_stage == 0) { if (packet->udp->dest == htons(161) || packet->udp->dest == htons(162)) { NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP detected due to port.\n"); ndpi_int_snmp_add_connection(ndpi_struct, flow); return; } NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP stage 0.\n"); if (packet->payload[offset + 2] == 3) { flow->l4.udp.snmp_msg_id = ntohs(get_u_int32_t(packet->payload, offset + 8)); } else if (packet->payload[offset + 2] == 0) { flow->l4.udp.snmp_msg_id = get_u_int8_t(packet->payload, offset + 15); } else { flow->l4.udp.snmp_msg_id = ntohs(get_u_int16_t(packet->payload, offset + 15)); } flow->l4.udp.snmp_stage = 1 + packet->packet_direction; return; } else if (flow->l4.udp.snmp_stage == 1 + packet->packet_direction) { if (packet->payload[offset + 2] == 0) { if (flow->l4.udp.snmp_msg_id != get_u_int8_t(packet->payload, offset + 15) - 1) { NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP v1 excluded, message ID doesn't match\n"); goto excl; } } } else if (flow->l4.udp.snmp_stage == 2 - packet->packet_direction) { NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP stage 1-2.\n"); if (packet->payload[offset + 2] == 3) { if (flow->l4.udp.snmp_msg_id != ntohs(get_u_int32_t(packet->payload, offset + 8))) { NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP v3 excluded, message ID doesn't match\n"); goto excl; } } else if (packet->payload[offset + 2] == 0) { if (flow->l4.udp.snmp_msg_id != get_u_int8_t(packet->payload, offset + 15)) { NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP v1 excluded, message ID doesn't match\n"); goto excl; } } else { if (flow->l4.udp.snmp_msg_id != ntohs(get_u_int16_t(packet->payload, offset + 15))) { NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP v2 excluded, message ID doesn't match\n"); goto excl; } } NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP detected.\n"); ndpi_int_snmp_add_connection(ndpi_struct, flow); return; } } else { NDPI_LOG(NDPI_PROTOCOL_SNMP, ndpi_struct, NDPI_LOG_DEBUG, "SNMP excluded.\n"); } excl: NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SNMP); }
static inline #else __forceinline static #endif void ndpi_search_sip_handshake(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; const u_int8_t *packet_payload = packet->payload; u_int32_t payload_len = packet->payload_packet_len; if (payload_len > 4) { /* search for STUN Turn ChannelData Prefix */ u_int16_t message_len = ntohs(get_u_int16_t(packet->payload, 2)); if (payload_len - 4 == message_len) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found STUN TURN ChannelData prefix.\n"); payload_len -= 4; packet_payload += 4; } } #ifndef NDPI_PROTOCOL_YAHOO if (payload_len >= 14 && packet_payload[payload_len - 2] == 0x0d && packet_payload[payload_len - 1] == 0x0a) #endif #ifdef NDPI_PROTOCOL_YAHOO if (payload_len >= 14) #endif { if ((memcmp(packet_payload, "NOTIFY ", 7) == 0 || memcmp(packet_payload, "notify ", 7) == 0) && (memcmp(&packet_payload[7], "SIP:", 4) == 0 || memcmp(&packet_payload[7], "sip:", 4) == 0)) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip NOTIFY.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } if ((memcmp(packet_payload, "REGISTER ", 9) == 0 || memcmp(packet_payload, "register ", 9) == 0) && (memcmp(&packet_payload[9], "SIP:", 4) == 0 || memcmp(&packet_payload[9], "sip:", 4) == 0)) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip REGISTER.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } if ((memcmp(packet_payload, "INVITE ", 7) == 0 || memcmp(packet_payload, "invite ", 7) == 0) && (memcmp(&packet_payload[7], "SIP:", 4) == 0 || memcmp(&packet_payload[7], "sip:", 4) == 0)) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip INVITE.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } /* seen this in second direction on the third position, * maybe it could be deleted, if somebody sees it in the first direction, * please delete this comment. */ /* if (memcmp(packet_payload, "SIP/2.0 200 OK", 14) == 0 || memcmp(packet_payload, "sip/2.0 200 OK", 14) == 0) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip SIP/2.0 0K.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } */ if (memcmp(packet_payload, "SIP/2.0 ", 8) == 0 || memcmp(packet_payload, "sip/2.0 ", 8) == 0) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip SIP/2.0 *.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } if ((memcmp(packet_payload, "BYE ", 4) == 0 || memcmp(packet_payload, "bye ", 4) == 0) && (memcmp(&packet_payload[4], "SIP:", 4) == 0 || memcmp(&packet_payload[4], "sip:", 4) == 0)) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip BYE.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } if ((memcmp(packet_payload, "ACK ", 4) == 0 || memcmp(packet_payload, "ack ", 4) == 0) && (memcmp(&packet_payload[4], "SIP:", 4) == 0 || memcmp(&packet_payload[4], "sip:", 4) == 0)) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip ACK.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } if ((memcmp(packet_payload, "CANCEL ", 7) == 0 || memcmp(packet_payload, "cancel ", 7) == 0) && (memcmp(&packet_payload[4], "SIP:", 7) == 0 || memcmp(&packet_payload[4], "sip:", 7) == 0)) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip CANCEL.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } /* Courtesy of Miguel Quesada <*****@*****.**> */ if ((memcmp(packet_payload, "OPTIONS ", 8) == 0 || memcmp(packet_payload, "options ", 8) == 0) && (memcmp(&packet_payload[8], "SIP:", 4) == 0 || memcmp(&packet_payload[8], "sip:", 4) == 0)) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "found sip OPTIONS.\n"); ndpi_int_sip_add_connection(ndpi_struct, flow, 0); return; } } /* add bitmask for tcp only, some stupid udp programs * send a very few (< 10 ) packets before invite (mostly a 0x0a0x0d, but just search the first 3 payload_packets here */ if (packet->udp != NULL && flow->packet_counter < 20) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "need next packet.\n"); return; } #ifdef NDPI_PROTOCOL_STUN /* for STUN flows we need some more packets */ if (packet->udp != NULL && flow->detected_protocol_stack[0] == NDPI_PROTOCOL_STUN && flow->packet_counter < 40) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "need next STUN packet.\n"); return; } #endif if (payload_len == 4 && get_u_int32_t(packet_payload, 0) == 0) { NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "maybe sip. need next packet.\n"); return; } #ifdef NDPI_PROTOCOL_YAHOO if (payload_len > 30 && packet_payload[0] == 0x90 && packet_payload[3] == payload_len - 20 && get_u_int32_t(packet_payload, 4) == 0 && get_u_int32_t(packet_payload, 8) == 0) { flow->sip_yahoo_voice = 1; NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "maybe sip yahoo. need next packet.\n"); } if (flow->sip_yahoo_voice && flow->packet_counter < 10) { return; } #endif NDPI_LOG(NDPI_PROTOCOL_SIP, ndpi_struct, NDPI_LOG_DEBUG, "exclude sip.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SIP); return; }
static void ndpi_search_shoutcast_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "search shoutcast.\n"); if (flow->packet_counter == 1) { /* this case in paul_upload_oddcast_002.pcap */ if (packet->payload_packet_len >= 6 && packet->payload_packet_len < 80 && memcmp(packet->payload, "123456", 6) == 0) { NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast stage 1, \"123456\".\n"); return; } if (flow->packet_counter < 3 #ifdef NDPI_PROTOCOL_HTTP && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP #endif ) { NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "http detected, need next packet for shoutcast detection.\n"); if (packet->payload_packet_len > 4 && get_u_int32_t(packet->payload, packet->payload_packet_len - 4) != htonl(0x0d0a0d0a)) { NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "segmented packet found.\n"); flow->l4.tcp.shoutcast_stage = 1 + packet->packet_direction; } return; } /* else goto exclude_shoutcast; */ } /* evtl. für asym detection noch User-Agent:Winamp dazunehmen. */ if (packet->payload_packet_len > 11 && memcmp(packet->payload, "ICY 200 OK\x0d\x0a", 12) == 0) { NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "found shoutcast by ICY 200 OK.\n"); ndpi_int_shoutcast_add_connection(ndpi_struct, flow); return; } if (flow->l4.tcp.shoutcast_stage == 1 + packet->packet_direction && flow->packet_direction_counter[packet->packet_direction] < 5) { return; } if (flow->packet_counter == 2) { if (packet->payload_packet_len == 2 && memcmp(packet->payload, "\x0d\x0a", 2) == 0) { NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast stage 1 continuation.\n"); return; } else if (packet->payload_packet_len > 3 && ndpi_mem_cmp(&packet->payload[0], "OK2", 3) == 0) { NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast stage 2, OK2 found.\n"); return; } else goto exclude_shoutcast; } else if (flow->packet_counter == 3 || flow->packet_counter == 4) { if (packet->payload_packet_len > 3 && ndpi_mem_cmp(&packet->payload[0], "OK2", 3) == 0) { NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast stage 2, OK2 found.\n"); return; } else if (packet->payload_packet_len > 4 && ndpi_mem_cmp(&packet->payload[0], "icy-", 4) == 0) { NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast detected.\n"); ndpi_int_shoutcast_add_connection(ndpi_struct, flow); return; } else goto exclude_shoutcast; } exclude_shoutcast: NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SHOUTCAST); NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast excluded.\n"); }
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; 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, NDPI_REAL_PROTOCOL); return; } /* 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, NDPI_REAL_PROTOCOL); return; } } /* detect http connections */ if (packet->payload_packet_len >= 18) { if ((packet->payload[0] == 'P') && (memcmp(packet->payload, "POST /photo/upload", 18) == 0)) { NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow, packet); if (packet->host_line.len >= 18 && packet->host_line.ptr != NULL) { if (memcmp(packet->host_line.ptr, "lifestream.aol.com", 18) == 0) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR over HTTP found, POST method\n"); ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } } } if (packet->payload_packet_len > 40) { if ((packet->payload[0] == 'G') && (memcmp(packet->payload, "GET /", 5) == 0)) { if ((memcmp(&packet->payload[5], "aim/fetchEvents?aimsid=", 23) == 0) || (memcmp(&packet->payload[5], "aim/startSession?", 17) == 0) || (memcmp(&packet->payload[5], "aim/gromit/aim_express", 22) == 0) || (memcmp(&packet->payload[5], "b/ss/aolwpaim", 13) == 0) || (memcmp(&packet->payload[5], "hss/storage/aimtmpshare", 23) == 0)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR over HTTP found, GET /aim/\n"); ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } if ((memcmp(&packet->payload[5], "aim", 3) == 0) || (memcmp(&packet->payload[5], "im", 2) == 0)) { NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow, packet); if (packet->user_agent_line.len > 15 && packet->user_agent_line.ptr != NULL && ((memcmp(packet->user_agent_line.ptr, "mobileAIM/", 10) == 0) || (memcmp(packet->user_agent_line.ptr, "ICQ/", 4) == 0) || (memcmp(packet->user_agent_line.ptr, "mobileICQ/", 10) == 0) || (memcmp(packet->user_agent_line.ptr, "AIM%20Free/", NDPI_STATICSTRING_LEN("AIM%20Free/")) == 0) || (memcmp(packet->user_agent_line.ptr, "AIM/", 4) == 0))) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR over HTTP found\n"); ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow, packet); if (packet->referer_line.ptr != NULL && packet->referer_line.len >= 22) { if (memcmp(&packet->referer_line.ptr[packet->referer_line.len - NDPI_STATICSTRING_LEN("WidgetMain.swf")], "WidgetMain.swf", NDPI_STATICSTRING_LEN("WidgetMain.swf")) == 0) { u_int16_t i; for (i = 0; i < (packet->referer_line.len - 22); i++) { if (packet->referer_line.ptr[i] == 'a') { if (memcmp(&packet->referer_line.ptr[i + 1], "im/gromit/aim_express", 21) == 0) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR over HTTP found : aim/gromit/aim_express\n"); ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } } } } } if (memcmp(packet->payload, "CONNECT ", 8) == 0) { if (memcmp(packet->payload, "CONNECT login.icq.com:443 HTTP/1.", 33) == 0) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR ICQ-HTTP FOUND\n"); ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } if (memcmp(packet->payload, "CONNECT login.oscar.aol.com:5190 HTTP/1.", 40) == 0) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR AIM-HTTP FOUND\n"); ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } } if (packet->payload_packet_len > 43 && memcmp(packet->payload, "GET http://http.proxy.icq.com/hello HTTP/1.", 43) == 0) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR ICQ-HTTP PROXY FOUND\n"); ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } if (packet->payload_packet_len > 46 && memcmp(packet->payload, "GET http://aimhttp.oscar.aol.com/hello HTTP/1.", 46) == 0) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR AIM-HTTP PROXY FOUND\n"); ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } if (packet->payload_packet_len > 5 && get_u_int32_t(packet->payload, 0) == htonl(0x05010003)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "Maybe OSCAR Picturetransfer\n"); return; } if (packet->payload_packet_len == 10 && get_u_int32_t(packet->payload, 0) == htonl(0x05000001) && get_u_int32_t(packet->payload, 4) == 0) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "Maybe OSCAR Picturetransfer\n"); return; } if (packet->payload_packet_len >= 70 && memcmp(&packet->payload[packet->payload_packet_len - 26], "\x67\x00\x65\x00\x74\x00\x43\x00\x61\x00\x74\x00\x61\x00\x6c\x00\x6f\x00\x67", 19) == 0) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR PICTURE TRANSFER\n"); ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } if (NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_OSCAR) != 0) { if (flow->packet_counter == 1 && ((packet->payload_packet_len == 9 && memcmp(packet->payload, "\x00\x09\x00\x00\x83\x01\xc0\x00\x00", 9) == 0) || (packet->payload_packet_len == 13 && (memcmp(packet->payload, "\x00\x0d\x00\x87\x01\xc0", 6) == 0 || memcmp(packet->payload, "\x00\x0d\x00\x87\x01\xc1", 6) == 0)))) { flow->oscar_video_voice = 1; } if (flow->oscar_video_voice && ntohs(get_u_int16_t(packet->payload, 0)) == packet->payload_packet_len && packet->payload[2] == 0x00 && packet->payload[3] == 0x00) { } if (packet->payload_packet_len >= 70 && ntohs(get_u_int16_t(packet->payload, 4)) == packet->payload_packet_len) { if (memcmp(packet->payload, "OFT", 3) == 0 && ((packet->payload[3] == '3' && ((memcmp(&packet->payload[4], "\x01\x00\x01\x01", 4) == 0) || (memcmp(&packet->payload[6], "\x01\x01\x00", 3) == 0))) || (packet->payload[3] == '2' && ((memcmp(&packet->payload[6], "\x01\x01", 2) == 0) )))) { // FILE TRANSFER PATTERN:: OFT3 or OFT2 NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR FILE TRANSFER\n"); ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } if (memcmp(packet->payload, "ODC2", 4) == 0 && memcmp(&packet->payload[6], "\x00\x01\x00\x06", 4) == 0) { //PICTURE TRANSFER PATTERN EXMAPLE:: //4f 44 43 32 00 4c 00 01 00 06 00 00 00 00 00 00 ODC2.L.......... NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR PICTURE TRANSFER\n"); ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } } if (packet->payload_packet_len > 40 && (memcmp(&packet->payload[2], "\x04\x4a\x00", 3) == 0) && (memcmp(&packet->payload[6], "\x00\x00", 2) == 0) && packet->payload[packet->payload_packet_len - 15] == 'F' && packet->payload[packet->payload_packet_len - 12] == 'L' && (memcmp(&packet->payload[packet->payload_packet_len - 6], "DEST", 4) == 0) && (memcmp(&packet->payload[packet->payload_packet_len - 2], "\x00\x00", 2) == 0)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR PICTURE TRANSFER\n"); ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); if (ntohs(packet->tcp->dest) == 443 || ntohs(packet->tcp->source) == 443) { flow->oscar_ssl_voice_stage = 1; } return; } } if (flow->packet_counter < 3 && packet->payload_packet_len > 11 && (memcmp(packet->payload, "\x00\x37\x04\x4a", 4) || memcmp(packet->payload, "\x00\x0a\x04\x4a", 4))) { return; } if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_OSCAR) { NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OSCAR); return; } }
static void ndpi_search_msn_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; struct ndpi_id_struct *src = flow->src; struct ndpi_id_struct *dst = flow->dst; u_int16_t plen; u_int16_t status = 0; NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "search msn tcp.\n"); #ifdef NDPI_PROTOCOL_SSL if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "msn ssl ft test\n"); if (flow->packet_counter < 10) { } if (flow->packet_counter == 7 && packet->payload_packet_len > 300) { if (memcmp(packet->payload + 24, "MSNSLP", 6) == 0 || (get_u_int32_t(packet->payload, 0) == htonl(0x30000000) && get_u_int32_t(packet->payload, 4) == 0x00000000)) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "detected MSN File Transfer, ifdef ssl.\n"); ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } } if (flow->packet_counter >= 5 && flow->packet_counter <= 10 && (get_u_int32_t(packet->payload, 0) == htonl(0x18000000) && get_u_int32_t(packet->payload, 4) == 0x00000000)) { flow->l4.tcp.msn_ssl_ft++; NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "increased msn ft ssl stage to: %u at packet nr: %u\n", flow->l4.tcp.msn_ssl_ft, flow->packet_counter); if (flow->l4.tcp.msn_ssl_ft == 2) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "detected MSN File Transfer, ifdef ssl 2.\n"); ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); } return; } } #endif /* we detect the initial connection only ! */ /* match: "VER " ..... "CVR" x 0x0d 0x0a * len should be small, lets say less than 100 bytes * x is now "0", but can be increased */ /* now we have a look at the first packet only. */ if (flow->packet_counter == 1 #ifdef NDPI_PROTOCOL_SSL || ((packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) && flow->packet_counter <= 3) #endif ) { /* this part is working asymmetrically */ if (packet->payload_packet_len > 32 && (packet->payload[0] == 0x02 || packet->payload[0] == 0x00) && (ntohl(get_u_int32_t(packet->payload, 8)) == 0x2112a442 || ntohl(get_u_int32_t(packet->payload, 4)) == 0x2112a442) && ((ntohl(get_u_int32_t(packet->payload, 24)) == 0x000f0004 && ntohl(get_u_int32_t(packet->payload, 28)) == 0x72c64bc6) || (ntohl(get_u_int32_t(packet->payload, 20)) == 0x000f0004 && ntohl(get_u_int32_t(packet->payload, 24)) == 0x72c64bc6))) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found MSN in packets that also contain voice.messenger.live.com.\n"); /* TODO this is an alternative pattern for video detection */ /* if (packet->payload_packet_len > 100 && get_u_int16_t(packet->payload, 86) == htons(0x05dc)) { */ if (packet->payload_packet_len > 101 && packet->payload[101] == 0x02) { ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); } else { ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); } return; } /* this case works asymmetrically */ if (packet->payload_packet_len > 10 && packet->payload_packet_len < 100) { if (get_u_int8_t(packet->payload, packet->payload_packet_len - 2) == 0x0d && get_u_int8_t(packet->payload, packet->payload_packet_len - 1) == 0x0a) { /* The MSNP string is used in XBOX clients. */ if (memcmp(packet->payload, "VER ", 4) == 0) { if (memcmp(&packet->payload[packet->payload_packet_len - 6], "CVR", 3) == 0 || memcmp(&packet->payload[packet->payload_packet_len - 8], "MSNP", 4) == 0) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found MSN by pattern VER...CVR/MSNP ODOA.\n"); ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } if (memcmp(&packet->payload[4], "MSNFT", 5) == 0) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found MSN FT by pattern VER MSNFT...0d0a.\n"); ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } } } } if ( #ifdef NDPI_PROTOCOL_HTTP packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || #endif memcmp(packet->payload, "GET ", NDPI_STATICSTRING_LEN("GET ")) == 0 || memcmp(packet->payload, "POST ", NDPI_STATICSTRING_LEN("POST ")) == 0) { ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > NDPI_STATICSTRING_LEN("Messenger/") && memcmp(packet->user_agent_line.ptr, "Messenger/", NDPI_STATICSTRING_LEN("Messenger/")) == 0) { ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } #ifdef NDPI_PROTOCOL_HTTP /* we have to examine two http packets */ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP) { } #endif /* not seen this pattern in any trace */ /* now test for http login, at least 100 a bytes packet */ if (packet->payload_packet_len > 100) { if ( #ifdef NDPI_PROTOCOL_HTTP packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || #endif memcmp(packet->payload, "POST http://", 12) == 0) { /* scan packet if not already done... */ ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->content_line.ptr != NULL && ((packet->content_line.len == NDPI_STATICSTRING_LEN("application/x-msn-messenger") && memcmp(packet->content_line.ptr, "application/x-msn-messenger", NDPI_STATICSTRING_LEN("application/x-msn-messenger")) == 0) || (packet->content_line.len >= NDPI_STATICSTRING_LEN("text/x-msnmsgr") && memcmp(packet->content_line.ptr, "text/x-msnmsgr", NDPI_STATICSTRING_LEN("text/x-msnmsgr")) == 0))) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found MSN by pattern POST http:// .... application/x-msn-messenger.\n"); ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } } /* now test for http login that uses a gateway, at least 400 a bytes packet */ /* for this case the asymmetric detection is asym (1) */ if (packet->payload_packet_len > 400) { if (( #ifdef NDPI_PROTOCOL_HTTP packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || #endif (memcmp(packet->payload, "POST ", 5) == 0))) { u_int16_t c; if (memcmp(&packet->payload[5], "http://", 7) == 0) { /* * We are searching for a paten "POST http://gateway.messenger.hotmail.com/gateway/gateway.dll" or * "POST http://<some ip addres here like 172.0.0.0>/gateway/gateway.dll" * POST http:// is 12 byte so we are searching for 13 to 70 byte for this paten. */ for (c = 13; c < 50; c++) { if (memcmp(&packet->payload[c], "/", 1) == 0) { if (memcmp(&packet->payload[c], "/gateway/gateway.dll", 20) == 0) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found pattern http://.../gateway/gateway.ddl.\n"); status = 1; break; } } } } else if ((memcmp(&packet->payload[5], "/gateway/gateway.dll", 20) == 0)) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found pattern http://.../gateway/gateway.ddl.\n"); status = 1; } } if (status) { u_int16_t a; ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->content_line.ptr != NULL && ((packet->content_line.len == 23 && memcmp(packet->content_line.ptr, "text/xml; charset=utf-8", 23) == 0) || (packet->content_line.len == 24 && memcmp(packet->content_line.ptr, "text/html; charset=utf-8", 24) == 0) || (packet->content_line.len == 33 && memcmp(packet->content_line.ptr, "application/x-www-form-urlencoded", 33) == 0) )) { if ((src != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) != 0) || (dst != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) != 0)) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found MSN with pattern text/xml; charset=utf-8.\n"); ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } for (a = 0; a < packet->parsed_lines; a++) { if (packet->line[a].len >= 4 && (memcmp(packet->line[a].ptr, "CVR ", 4) == 0 || memcmp(packet->line[a].ptr, "VER ", 4) == 0 || memcmp(packet->line[a].ptr, "ANS ", 4) == 0)) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found MSN with pattern text/sml; charset0utf-8.\n"); NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN xml CVS / VER / ANS found\n"); ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } } } } /* asym (1) ; possibly occurs in symmetric cases also. */ if (flow->packet_counter <= 10 && (flow->packet_direction_counter[0] <= 2 || flow->packet_direction_counter[1] <= 2) && packet->payload_packet_len > 100) { /* not necessary to check the length, because this has been done : >400. */ if ( #ifdef NDPI_PROTOCOL_HTTP packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || #endif (memcmp(packet->payload, "HTTP/1.0 200 OK", 15) == 0) || (memcmp(packet->payload, "HTTP/1.1 200 OK", 15) == 0) ) { ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->content_line.ptr != NULL && ((packet->content_line.len == NDPI_STATICSTRING_LEN("application/x-msn-messenger") && memcmp(packet->content_line.ptr, "application/x-msn-messenger", NDPI_STATICSTRING_LEN("application/x-msn-messenger")) == 0) || (packet->content_line.len >= NDPI_STATICSTRING_LEN("text/x-msnmsgr") && memcmp(packet->content_line.ptr, "text/x-msnmsgr", NDPI_STATICSTRING_LEN("text/x-msnmsgr")) == 0))) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "HTTP/1.0 200 OK .... application/x-msn-messenger.\n"); ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } if (ndpi_int_find_xmsn(ndpi_struct, flow) == 1) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "HTTP/1.0 200 OK .... X-MSN.\n"); ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } } /* did not find any trace with this pattern !!!!! */ /* now block proxy connection */ if (packet->payload_packet_len >= 42) { if (memcmp(packet->payload, "CONNECT messenger.hotmail.com:1863 HTTP/1.", 42) == 0) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found MSN with pattern CONNECT messenger.hotmail.com:1863 HTTP/1..\n"); ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } if (packet->payload_packet_len >= 18) { if (memcmp(packet->payload, "USR ", 4) == 0 || memcmp(packet->payload, "ANS ", 4) == 0) { /* now we must see a number */ const u_int16_t endlen = packet->payload_packet_len - 12; plen = 4; while (1) { if (packet->payload[plen] == ' ') { break; } if (packet->payload[plen] < '0' || packet->payload[plen] > '9') { goto ndpi_msn_exclude; } plen++; if (plen >= endlen) { goto ndpi_msn_exclude; } } while (plen < endlen) { if (ndpi_check_for_email_address(ndpi_struct, flow, plen) != 0) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found mail address\n"); break; } if (packet->payload_packet_len > plen + 1 && (packet->payload[plen] < 20 || packet->payload[plen] > 128)) { goto ndpi_msn_exclude; } plen++; if (plen >= endlen) { goto ndpi_msn_exclude; } } NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "found MSN with pattern USR/ANS ...mail_address.\n"); ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } } } /* finished examining the first packet only. */ /* asym (1) ; possibly occurs in symmetric cases also. */ if (flow->packet_counter <= 10 && (flow->packet_direction_counter[0] <= 2 || flow->packet_direction_counter[1] <= 2) && packet->payload_packet_len > 100) { /* not necessary to check the length, because this has been done : >400. */ if ( #ifdef NDPI_PROTOCOL_HTTP packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || #endif (memcmp(packet->payload, "HTTP/1.0 200 OK", 15) == 0) || (memcmp(packet->payload, "HTTP/1.1 200 OK", 15) == 0) ) { ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->content_line.ptr != NULL && ((packet->content_line.len == NDPI_STATICSTRING_LEN("application/x-msn-messenger") && memcmp(packet->content_line.ptr, "application/x-msn-messenger", NDPI_STATICSTRING_LEN("application/x-msn-messenger")) == 0) || (packet->content_line.len >= NDPI_STATICSTRING_LEN("text/x-msnmsgr") && memcmp(packet->content_line.ptr, "text/x-msnmsgr", NDPI_STATICSTRING_LEN("text/x-msnmsgr")) == 0))) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "HTTP/1.0 200 OK .... application/x-msn-messenger.\n"); ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } if (ndpi_int_find_xmsn(ndpi_struct, flow) == 1) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "HTTP/1.0 200 OK .... X-MSN.\n"); ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } } /* finished examining the secone packet only */ /* direct user connection (file transfer,...) */ if ((src != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) != 0) || (dst != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) != 0)) { if (flow->packet_counter == 1 && packet->payload_packet_len > 12 && memcmp(packet->payload, "recipientid=", 12) == 0) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "detected file transfer.\n"); ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } } /* MSN File Transfer of MSN 8.1 and 8.5 * first packet with length 4 and pattern 0x04000000 * second packet (in the same direction), with length 56 and pattern 0x00000000 from payload[16] * third packet (in the opposite direction to 1 & 2), with length 4 and pattern 0x30000000 */ if (flow->l4.tcp.msn_stage == 0) { /* asymmetric detection to this pattern is asym (2) */ if ((packet->payload_packet_len == 4 || packet->payload_packet_len == 8) && get_u_int32_t(packet->payload, 0) == htonl(0x04000000)) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "maybe first TCP MSN detected\n"); if (packet->payload_packet_len == 8 && get_u_int32_t(packet->payload, 4) == htonl(0x666f6f00)) { flow->l4.tcp.msn_stage = 5 + packet->packet_direction; return; } flow->l4.tcp.msn_stage = 1 + packet->packet_direction; return; } /* asymmetric detection to this pattern is asym (2) */ } else if (flow->l4.tcp.msn_stage == 1 + packet->packet_direction) { if (packet->payload_packet_len > 10 && get_u_int32_t(packet->payload, 0) == htonl(0x666f6f00)) { ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 1\n"); return; } /* did not see this pattern in any trace */ if (packet->payload_packet_len == 56 && get_u_int32_t(packet->payload, 16) == 0) { NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_DEBUG, "maybe Second TCP MSN detected\n"); flow->l4.tcp.msn_stage = 3 + packet->packet_direction; return; } } else if (flow->l4.tcp.msn_stage == 2 - packet->packet_direction && packet->payload_packet_len == 4 && get_u_int32_t(packet->payload, 0) == htonl(0x30000000)) { ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 2\n"); return; } else if ((flow->l4.tcp.msn_stage == 3 + packet->packet_direction) || (flow->l4.tcp.msn_stage == 4 - packet->packet_direction)) { if (packet->payload_packet_len == 4 && get_u_int32_t(packet->payload, 0) == htonl(0x30000000)) { ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 2\n"); return; } } else if (flow->l4.tcp.msn_stage == 6 - packet->packet_direction) { if ((packet->payload_packet_len == 4) && (get_u_int32_t(packet->payload, 0) == htonl(0x10000000) || get_u_int32_t(packet->payload, 0) == htonl(0x30000000))) { ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 3\n"); return; } } else if (flow->l4.tcp.msn_stage == 5 + packet->packet_direction) { if ((packet->payload_packet_len == 20) && get_u_int32_t(packet->payload, 0) == htonl(0x10000000)) { ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 3\n"); return; } } NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "msn 7.\n"); if (flow->packet_counter <= MAX_PACKETS_FOR_MSN) { if (packet->tcp->source == htons(443) || packet->tcp->dest == htons(443)) { if (packet->payload_packet_len > 300) { if (memcmp(&packet->payload[40], "INVITE MSNMSGR", 14) == 0 || memcmp(&packet->payload[56], "INVITE MSNMSGR", 14) == 0 || memcmp(&packet->payload[172], "INVITE MSNMSGR", 14) == 0) { ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "MSN File Transfer detected 3\n"); return; } } return; } /* For no n port 443 flows exclude flow bitmask after first packet itself */ } NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "exclude msn.\n"); ndpi_msn_exclude: NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MSN); }
void ndpi_search_armagetron_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; NDPI_LOG(NDPI_PROTOCOL_ARMAGETRON, ndpi_struct, NDPI_LOG_DEBUG, "search armagetron.\n"); if (packet->payload_packet_len > 10) { /* login request */ if (get_u_int32_t(packet->payload, 0) == htonl(0x000b0000)) { const u_int16_t dataLength = ntohs(get_u_int16_t(packet->payload, 4)); if (dataLength == 0 || dataLength * 2 + 8 != packet->payload_packet_len) goto exclude; if (get_u_int16_t(packet->payload, 6) == htons(0x0008) && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == 0) { NDPI_LOG(NDPI_PROTOCOL_ARMAGETRON, ndpi_struct, NDPI_LOG_DEBUG, "detected armagetron.\n"); ndpi_int_armagetron_add_connection(ndpi_struct, flow); return; } } /* sync_msg */ if (packet->payload_packet_len == 16 && get_u_int16_t(packet->payload, 0) == htons(0x001c) && get_u_int16_t(packet->payload, 2) != 0) { const u_int16_t dataLength = ntohs(get_u_int16_t(packet->payload, 4)); if (dataLength != 4) goto exclude; if (get_u_int32_t(packet->payload, 6) == htonl(0x00000500) && get_u_int32_t(packet->payload, 6 + 4) == htonl(0x00010000) && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == 0) { NDPI_LOG(NDPI_PROTOCOL_ARMAGETRON, ndpi_struct, NDPI_LOG_DEBUG, "detected armagetron.\n"); ndpi_int_armagetron_add_connection(ndpi_struct, flow); return; } } /* net_sync combination */ if (packet->payload_packet_len > 50 && get_u_int16_t(packet->payload, 0) == htons(0x0018) && get_u_int16_t(packet->payload, 2) != 0) { u_int16_t val; const u_int16_t dataLength = ntohs(get_u_int16_t(packet->payload, 4)); if (dataLength == 0 || dataLength * 2 + 8 > packet->payload_packet_len) goto exclude; val = get_u_int16_t(packet->payload, 6 + 2); if (val == get_u_int16_t(packet->payload, 6 + 6)) { val = ntohs(get_u_int16_t(packet->payload, 6 + 8)); if ((6 + 10 + val + 4) < packet->payload_packet_len && (get_u_int32_t(packet->payload, 6 + 10 + val) == htonl(0x00010000) || get_u_int32_t(packet->payload, 6 + 10 + val) == htonl(0x00000001)) && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == 0) { NDPI_LOG(NDPI_PROTOCOL_ARMAGETRON, ndpi_struct, NDPI_LOG_DEBUG, "detected armagetron.\n"); ndpi_int_armagetron_add_connection(ndpi_struct, flow); return; } } } } exclude: NDPI_LOG(NDPI_PROTOCOL_ARMAGETRON, ndpi_struct, NDPI_LOG_DEBUG, "exclude armagetron.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_ARMAGETRON); }
void ndpi_search_dofus(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; /* Dofus v 1.x.x */ if (packet->payload_packet_len == 13 && get_u_int16_t(packet->payload, 1) == ntohs(0x0508) && get_u_int16_t(packet->payload, 5) == ntohs(0x04a0) && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) == ntohs(0x0194)) { NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus.\n"); ndpi_dofus_add_connection(ndpi_struct, flow); return; } if (flow->l4.tcp.dofus_stage == 0 && packet->payload_packet_len == 3 && memcmp(packet->payload, "HG", 2) == 0 && packet->payload[packet->payload_packet_len - 1] == 0) { flow->l4.tcp.dofus_stage = 1; NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "maybe dofus.\n"); return; } if (flow->l4.tcp.dofus_stage == 0 && packet->payload_packet_len == 35 && memcmp(packet->payload, "HC", 2) == 0 && packet->payload[packet->payload_packet_len - 1] == 0) { flow->l4.tcp.dofus_stage = 1; NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "maybe dofus.\n"); return; } if (flow->l4.tcp.dofus_stage == 0 && packet->payload_packet_len > 2 && packet->payload[0] == 'A' && (packet->payload[1] == 'x' || packet->payload[1] == 'X') && packet->payload[packet->payload_packet_len - 1] == 0) { flow->l4.tcp.dofus_stage = 1; NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "maybe dofus.\n"); return; } if (flow->l4.tcp.dofus_stage == 0 && packet->payload_packet_len == 12 && memcmp(packet->payload, "Af", 2) == 0 && packet->payload[packet->payload_packet_len - 1] == 0) { flow->l4.tcp.dofus_stage = 1; NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "maybe dofus.\n"); return; } if (flow->l4.tcp.dofus_stage == 0 && packet->payload_packet_len > 2 && memcmp(packet->payload, "Ad", 2) && packet->payload[packet->payload_packet_len - 1] == 0) { flow->l4.tcp.dofus_stage = 1; NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "maybe dofus.\n"); return; } if (packet->payload_packet_len == 11 && memcmp(packet->payload, "AT", 2) == 0 && packet->payload[10] == 0x00) { if (flow->l4.tcp.dofus_stage == 1) { NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus.\n"); ndpi_dofus_add_connection(ndpi_struct, flow); return; } } if (flow->l4.tcp.dofus_stage == 1 && packet->payload_packet_len == 5 && packet->payload[0] == 'A' && packet->payload[4] == 0x00 && (packet->payload[1] == 'T' || packet->payload[1] == 'k')) { NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus asym.\n"); ndpi_dofus_add_connection(ndpi_struct, flow); return; } /* end Dofus 1.x.x */ /* Dofus 2.0 */ if ((packet->payload_packet_len == 11 || packet->payload_packet_len == 13 || packet->payload_packet_len == 49) && get_u_int32_t(packet->payload, 0) == ntohl(0x00050800) && get_u_int16_t(packet->payload, 4) == ntohs(0x0005) && get_u_int16_t(packet->payload, 8) == ntohs(0x0005) && packet->payload[10] == 0x18) { if (packet->payload_packet_len == 13 && get_u_int16_t(packet->payload, packet->payload_packet_len - 2) != ntohs(0x0194)) { goto exclude; } if (packet->payload_packet_len == 49 && ntohs(get_u_int16_t(packet->payload, 15)) + 17 != packet->payload_packet_len) { goto exclude; } NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus.\n"); ndpi_dofus_add_connection(ndpi_struct, flow); return; } if (packet->payload_packet_len >= 41 && get_u_int16_t(packet->payload, 0) == ntohs(0x01b9) && packet->payload[2] == 0x26) { u_int16_t len, len2; len = ntohs(get_u_int16_t(packet->payload, 3)); if ((len + 5 + 2) > packet->payload_packet_len) goto exclude; len2 = ntohs(get_u_int16_t(packet->payload, 5 + len)); if (5 + len + 2 + len2 == packet->payload_packet_len) { NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus.\n"); ndpi_dofus_add_connection(ndpi_struct, flow); return; } } if (packet->payload_packet_len == 56 && memcmp(packet->payload, "\x00\x11\x35\x02\x03\x00\x93\x96\x01\x00", 10) == 0) { u_int16_t len, len2; len = ntohs(get_u_int16_t(packet->payload, 10)); if ((len + 12 + 2) > packet->payload_packet_len) goto exclude; len2 = ntohs(get_u_int16_t(packet->payload, 12 + len)); if ((12 + len + 2 + len2 + 1) > packet->payload_packet_len) goto exclude; if (12 + len + 2 + len2 + 1 == packet->payload_packet_len && packet->payload[12 + len + 2 + len2] == 0x01) { NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "found dofus.\n"); ndpi_dofus_add_connection(ndpi_struct, flow); return; } } exclude: NDPI_LOG(NDPI_PROTOCOL_DOFUS, ndpi_struct, NDPI_LOG_DEBUG, "exclude dofus.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DOFUS); }
void ndpi_search_ppstream(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; /* check TCP Connections -> Videodata */ if (packet->tcp != NULL) { if (packet->payload_packet_len >= 60 && get_u_int32_t(packet->payload, 52) == 0 && memcmp(packet->payload, "PSProtocol\x0", 11) == 0) { NDPI_LOG(NDPI_PROTOCOL_PPSTREAM, ndpi_struct, NDPI_LOG_DEBUG, "found ppstream over tcp.\n"); ndpi_int_ppstream_add_connection(ndpi_struct, flow); return; } } if (packet->udp != NULL) { if (packet->payload_packet_len > 2 && packet->payload[2] == 0x43 && ((packet->payload_packet_len - 4 == get_l16(packet->payload, 0)) || (packet->payload_packet_len == get_l16(packet->payload, 0)) || (packet->payload_packet_len >= 6 && packet->payload_packet_len - 6 == get_l16(packet->payload, 0)))) { flow->l4.udp.ppstream_stage++; if (flow->l4.udp.ppstream_stage == 5) { NDPI_LOG(NDPI_PROTOCOL_PPSTREAM, ndpi_struct, NDPI_LOG_DEBUG, "found ppstream over udp pattern len, 43.\n"); ndpi_int_ppstream_add_connection(ndpi_struct, flow); return; } return; } if (flow->l4.udp.ppstream_stage == 0 && packet->payload_packet_len > 4 && ((packet->payload_packet_len - 4 == get_l16(packet->payload, 0)) || (packet->payload_packet_len == get_l16(packet->payload, 0)) || (packet->payload_packet_len >= 6 && packet->payload_packet_len - 6 == get_l16(packet->payload, 0)))) { if (packet->payload[2] == 0x00 && packet->payload[3] == 0x00 && packet->payload[4] == 0x03) { flow->l4.udp.ppstream_stage = 7; NDPI_LOG(NDPI_PROTOCOL_PPSTREAM, ndpi_struct, NDPI_LOG_DEBUG, "need next packet I.\n"); return; } } if (flow->l4.udp.ppstream_stage == 7 && packet->payload_packet_len > 4 && packet->payload[3] == 0x00 && ((packet->payload_packet_len - 4 == get_l16(packet->payload, 0)) || (packet->payload_packet_len == get_l16(packet->payload, 0)) || (packet->payload_packet_len >= 6 && packet->payload_packet_len - 6 == get_l16(packet->payload, 0))) && (packet->payload[2] == 0x00 && packet->payload[4] == 0x03)) { NDPI_LOG(NDPI_PROTOCOL_PPSTREAM, ndpi_struct, NDPI_LOG_DEBUG, "found ppstream over udp with pattern Vb.\n"); ndpi_int_ppstream_add_connection(ndpi_struct, flow); return; } } NDPI_LOG(NDPI_PROTOCOL_PPSTREAM, ndpi_struct, NDPI_LOG_DEBUG, "exclude ppstream.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_PPSTREAM); }
void ndpi_search_soulseek_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; struct ndpi_id_struct *src = flow->src; struct ndpi_id_struct *dst = flow->dst; NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "Soulseek: search soulseec tcp \n"); if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SOULSEEK) { NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "packet marked as Soulseek\n"); if (src != NULL) NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, " SRC bitmask: %u, packet tick %llu , last safe access timestamp: %llu\n", NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_SOULSEEK) != 0 ? 1 : 0, (u_int64_t) packet->tick_timestamp, (u_int64_t) src->soulseek_last_safe_access_time); if (dst != NULL) NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, " DST bitmask: %u, packet tick %llu , last safe ts: %llu\n", NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_SOULSEEK) != 0 ? 1 : 0, (u_int64_t) packet->tick_timestamp, (u_int64_t) dst->soulseek_last_safe_access_time); if (packet->payload_packet_len == 431) { if (dst != NULL) { dst->soulseek_last_safe_access_time = packet->tick_timestamp; } return; } if (packet->payload_packet_len == 12 && get_l32(packet->payload, 4) == 0x02) { if (src != NULL) { src->soulseek_last_safe_access_time = packet->tick_timestamp; if (packet->tcp != NULL && src->soulseek_listen_port == 0) { src->soulseek_listen_port = get_l32(packet->payload, 8); return; } } } if (src != NULL && ((u_int32_t) (packet->tick_timestamp - src->soulseek_last_safe_access_time) < ndpi_struct->soulseek_connection_ip_tick_timeout)) { NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "Soulseek: SRC update last safe access time and SKIP_FOR_TIME \n"); src->soulseek_last_safe_access_time = packet->tick_timestamp; } if (dst != NULL && ((u_int32_t) (packet->tick_timestamp - dst->soulseek_last_safe_access_time) < ndpi_struct->soulseek_connection_ip_tick_timeout)) { NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "Soulseek: DST update last safe access time and SKIP_FOR_TIME \n"); dst->soulseek_last_safe_access_time = packet->tick_timestamp; } } if (dst != NULL && dst->soulseek_listen_port != 0 && dst->soulseek_listen_port == ntohs(packet->tcp->dest) && ((u_int32_t) (packet->tick_timestamp - dst->soulseek_last_safe_access_time) < ndpi_struct->soulseek_connection_ip_tick_timeout)) { NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "Soulseek: Plain detection on Port : %u packet_tick_timestamp: %u soulseeek_last_safe_access_time: %u soulseek_connection_ip_ticktimeout: %u\n", dst->soulseek_listen_port, packet->tick_timestamp, dst->soulseek_last_safe_access_time, ndpi_struct->soulseek_connection_ip_tick_timeout); ndpi_int_soulseek_add_connection(ndpi_struct, flow); return; } if (flow->l4.tcp.soulseek_stage == 0) { u_int32_t index = 0; if (packet->payload_packet_len >= 12 && packet->payload_packet_len < 300 && get_l32(packet->payload, 4) == 1) { while (!get_u_int16_t(packet->payload, index + 2) && (index + get_l32(packet->payload, index)) < packet->payload_packet_len - 4) { if (get_l32(packet->payload, index) < 8) /*Minimum soulsek login msg is 8B */ break; if (index + get_l32(packet->payload, index) + 4 <= index) { /* avoid overflow */ break; } index += get_l32(packet->payload, index) + 4; } if (index + get_l32(packet->payload, index) == packet->payload_packet_len - 4 && !get_u_int16_t(packet->payload, 10)) { /*This structure seems to be soulseek proto */ index = get_l32(packet->payload, 8) + 12; // end of "user name" if ((index + 4) <= packet->payload_packet_len && !get_u_int16_t(packet->payload, index + 2)) // for passwd len { index += get_l32(packet->payload, index) + 4; //end of "Passwd" if ((index + 4 + 4) <= packet->payload_packet_len && !get_u_int16_t(packet->payload, index + 6)) // to read version,hashlen { index += get_l32(packet->payload, index + 4) + 8; // enf of "hash value" if (index == get_l32(packet->payload, 0)) { NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "Soulseek Login Detected\n"); ndpi_int_soulseek_add_connection(ndpi_struct, flow); return; } } } } } if (packet->payload_packet_len > 8 && packet->payload_packet_len < 200 && get_l32(packet->payload, 0) == packet->payload_packet_len - 4) { //Server Messages: const u_int32_t msgcode = get_l32(packet->payload, 4); if (msgcode == 0x7d) { flow->l4.tcp.soulseek_stage = 1 + packet->packet_direction; NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "Soulseek Messages Search\n"); return; } else if (msgcode == 0x02 && packet->payload_packet_len == 12) { const u_int32_t soulseek_listen_port = get_l32(packet->payload, 8); if (src != NULL) { src->soulseek_last_safe_access_time = packet->tick_timestamp; if (packet->tcp != NULL && src->soulseek_listen_port == 0) { src->soulseek_listen_port = soulseek_listen_port; NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "\n Listen Port Saved : %u", src->soulseek_listen_port); ndpi_int_soulseek_add_connection(ndpi_struct, flow); return; } } } //Peer Messages : Peer Init Message Detection if (get_l32(packet->payload, 0) == packet->payload_packet_len - 4) { const u_int32_t typelen = get_l32(packet->payload, packet->payload_packet_len - 9); const u_int8_t type = packet->payload[packet->payload_packet_len - 5]; const u_int32_t namelen = get_l32(packet->payload, 5); if (packet->payload[4] == 0x01 && typelen == 1 && namelen <= packet->payload_packet_len && (4 + 1 + 4 + namelen + 4 + 1 + 4) == packet->payload_packet_len && (type == 'F' || type == 'P' || type == 'D')) { NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected\n"); ndpi_int_soulseek_add_connection(ndpi_struct, flow); return; } NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "1\n"); } NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "3\n"); //Peer Message : Pierce Firewall if (packet->payload_packet_len == 9 && get_l32(packet->payload, 0) == 5 && packet->payload[4] <= 0x10 && get_u_int32_t(packet->payload, 5) != 0x00000000) { flow->l4.tcp.soulseek_stage = 1 + packet->packet_direction; NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_TRACE, "Soulseek Size 9 Pierce Firewall\n"); return; } } if (packet->payload_packet_len > 25 && packet->payload[4] == 0x01 && !get_u_int16_t(packet->payload, 7) && !get_u_int16_t(packet->payload, 2)) { const u_int32_t usrlen = get_l32(packet->payload, 5); if (usrlen <= packet->payload_packet_len - 4 + 1 + 4 + 4 + 1 + 4) { const u_int32_t typelen = get_l32(packet->payload, 4 + 1 + 4 + usrlen); const u_int8_t type = packet->payload[4 + 1 + 4 + usrlen + 4]; if (typelen == 1 && (type == 'F' || type == 'P' || type == 'D')) { NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected Pattern command(D|P|F).\n"); ndpi_int_soulseek_add_connection(ndpi_struct, flow); return; } } } } else if (flow->l4.tcp.soulseek_stage == 2 - packet->packet_direction) { if (packet->payload_packet_len > 8) { if ((packet->payload[0] || packet->payload[1]) && get_l32(packet->payload, 4) == 9) { /* 9 is search result */ NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected Second Pkt\n"); ndpi_int_soulseek_add_connection(ndpi_struct, flow); return; } if (get_l32(packet->payload, 0) == packet->payload_packet_len - 4) { const u_int32_t msgcode = get_l32(packet->payload, 4); if (msgcode == 0x03 && packet->payload_packet_len >= 12) //Server Message : Get Peer Address { const u_int32_t usrlen = get_l32(packet->payload, 8); if (usrlen <= packet->payload_packet_len && 4 + 4 + 4 + usrlen == packet->payload_packet_len) { NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "Soulseek Request Get Peer Address Detected\n"); ndpi_int_soulseek_add_connection(ndpi_struct, flow); return; } } } } if (packet->payload_packet_len == 8 && get_l32(packet->payload, 4) == 0x00000004) { NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected\n"); ndpi_int_soulseek_add_connection(ndpi_struct, flow); return; } if (packet->payload_packet_len == 4 && get_u_int16_t(packet->payload, 2) == 0x00 && get_u_int16_t(packet->payload, 0) != 0x00) { NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected\n"); ndpi_int_soulseek_add_connection(ndpi_struct, flow); return; } else if (packet->payload_packet_len == 4) { flow->l4.tcp.soulseek_stage = 3; return; } } else if (flow->l4.tcp.soulseek_stage == 1 + packet->packet_direction) { if (packet->payload_packet_len > 8) { if (packet->payload[4] == 0x03 && get_l32(packet->payload, 5) == 0x00000031) { NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected Second Pkt with SIGNATURE :: 0x0331000000 \n"); ndpi_int_soulseek_add_connection(ndpi_struct, flow); return; } } } if (flow->l4.tcp.soulseek_stage == 3 && packet->payload_packet_len == 8 && !get_u_int32_t(packet->payload, 4)) { NDPI_LOG(NDPI_PROTOCOL_SOULSEEK, ndpi_struct, NDPI_LOG_DEBUG, "soulseek detected bcz of 8B pkt\n"); ndpi_int_soulseek_add_connection(ndpi_struct, flow); return; } if (flow->l4.tcp.soulseek_stage && flow->packet_counter < 11) { } else { NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOULSEEK); } }
void ndpi_search_gnutella(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; struct ndpi_id_struct *src = flow->src; struct ndpi_id_struct *dst = flow->dst; u_int16_t c; if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_GNUTELLA) { if (src != NULL && ((u_int32_t) (packet->tick_timestamp - src->gnutella_ts) < ndpi_struct->gnutella_timeout)) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "gnutella : save src connection packet detected\n"); src->gnutella_ts = packet->tick_timestamp; } else if (dst != NULL && ((u_int32_t) (packet->tick_timestamp - dst->gnutella_ts) < ndpi_struct->gnutella_timeout)) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "gnutella : save dst connection packet detected\n"); dst->gnutella_ts = packet->tick_timestamp; } if (src != NULL && (packet->tick_timestamp - src->gnutella_ts) > ndpi_struct->gnutella_timeout) { src->detected_gnutella_udp_port1 = 0; src->detected_gnutella_udp_port2 = 0; } if (dst != NULL && (packet->tick_timestamp - dst->gnutella_ts) > ndpi_struct->gnutella_timeout) { dst->detected_gnutella_udp_port1 = 0; dst->detected_gnutella_udp_port2 = 0; } return; } /* skip packets without payload */ if (packet->payload_packet_len < 2) { return; } if (packet->tcp != NULL) { /* this case works asymmetrically */ if (packet->payload_packet_len > 10 && memcmp(packet->payload, "GNUTELLA/", 9) == 0) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "GNUTELLA DETECTED\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } /* this case works asymmetrically */ if (packet->payload_packet_len > 17 && memcmp(packet->payload, "GNUTELLA CONNECT/", 17) == 0) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "GNUTELLA DETECTED\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET /get/", 9) == 0) || (memcmp(packet->payload, "GET /uri-res/", 13) == 0) )) { ndpi_parse_packet_line_info(ndpi_struct, flow); for (c = 0; c < packet->parsed_lines; c++) { if ((packet->line[c].len > 19 && memcmp(packet->line[c].ptr, "User-Agent: Gnutella", 20) == 0) || (packet->line[c].len > 10 && memcmp(packet->line[c].ptr, "X-Gnutella-", 11) == 0) || (packet->line[c].len > 7 && memcmp(packet->line[c].ptr, "X-Queue:", 8) == 0) || (packet->line[c].len > 36 && memcmp(packet->line[c].ptr, "Content-Type: application/x-gnutella-", 37) == 0)) { NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "DETECTED GNUTELLA GET.\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } } if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET / HTTP", 9) == 0))) { ndpi_parse_packet_line_info(ndpi_struct, flow); if ((packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > 15 && memcmp(packet->user_agent_line.ptr, "BearShare Lite ", 15) == 0) || (packet->accept_line.ptr != NULL && packet->accept_line.len > 24 && memcmp(packet->accept_line.ptr, "application n/x-gnutella", 24) == 0)) { NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "DETECTED GNUTELLA GET.\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); } } /* haven't found this pattern in any trace. */ if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET /get/", 9) == 0) || (memcmp(packet->payload, "GET /uri-res/", 13) == 0))) { c = 8; while (c < (packet->payload_packet_len - 9)) { if (packet->payload[c] == '?') break; c++; } if (c < (packet->payload_packet_len - 9) && memcmp(&packet->payload[c], "urn:sha1:", 9) == 0) { NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected GET /get/ or GET /uri-res/.\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); } } /* answer to this packet is HTTP/1.1 ..... Content-Type: application/x-gnutella-packets, * it is searched in the upper paragraph. */ if (packet->payload_packet_len > 30 && memcmp(packet->payload, "HEAD /gnutella/push-proxy?", 26) == 0) { NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected HEAD /gnutella/push-proxy?\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } /* haven't found any trace with this pattern */ if (packet->payload_packet_len == 46 && memcmp(packet->payload, "\x50\x55\x53\x48\x20\x67\x75\x69\x64\x3a", 10) == 0) { NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected \x50\x55\x53\x48\x20\x67\x75\x69\x64\x3a\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } /* haven't found any trace with this pattern */ if (packet->payload_packet_len > 250 && memcmp(packet->payload, "GET /gnutella/", 14) == 0) //PATTERN IS :: GET /gnutella/tigertree/v3?urn:tree:tiger/: { const u_int16_t end = packet->payload_packet_len - 3; c = 13; while (c < end) { if ((memcmp(&packet->payload[14], "tigertree/", 10) == 0) || (end - c > 18 && memcmp(&packet->payload[c], "\r\nUser-Agent: Foxy", 18) == 0) || (end - c > 44 && memcmp(&packet->payload[c], "\r\nAccept: application/tigertree-breadthfirst", 44) == 0) || (end - c > 10 && memcmp(&packet->payload[c], "\r\nX-Queue:", 10) == 0) || (end - c > 13 && memcmp(&packet->payload[c], "\r\nX-Features:", 13) == 0)) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "FOXY :: GNUTELLA GET 2 DETECTED\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } c++; } } /* haven't found any trace with this pattern */ if (packet->payload_packet_len > 1 && packet->payload[packet->payload_packet_len - 1] == 0x0a && packet->payload[packet->payload_packet_len - 2] == 0x0a) { if (packet->payload_packet_len > 3 && memcmp(packet->payload, "GIV", 3) == 0) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "MORPHEUS GIV DETECTED\n"); /* Not Excludeing the flow now.. We shall Check the next Packet too for Gnutella Patterns */ return; } } /* might be super tricky new ssl gnutella transmission, but the certificate is strange... */ if (packet->payload_packet_len == 46 && get_u_int32_t(packet->payload, 0) == htonl(0x802c0103) && get_u_int32_t(packet->payload, 4) == htonl(0x01000300) && get_u_int32_t(packet->payload, 8) == htonl(0x00002000) && get_u_int16_t(packet->payload, 12) == htons(0x0034)) { NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected gnutella len == 46.\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } if (packet->payload_packet_len == 49 && memcmp(packet->payload, "\x80\x2f\x01\x03\x01\x00\x06\x00\x00\x00\x20\x00\x00\x34\x00\x00\xff\x4d\x6c", 19) == 0) { NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected gnutella len == 49.\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } if (packet->payload_packet_len == 89 && memcmp(&packet->payload[43], "\x20\x4d\x6c", 3) == 0 && memcmp(packet->payload, "\x16\x03\x01\x00\x54\x01\x00\x00\x50\x03\x01\x4d\x6c", 13) == 0 && memcmp(&packet->payload[76], "\x00\x02\x00\x34\x01\x00\x00\x05", 8) == 0) { NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected gnutella asymmetrically len == 388.\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } else if (packet->payload_packet_len == 82) { if (get_u_int32_t(packet->payload, 0) == htonl(0x16030100) && get_u_int32_t(packet->payload, 4) == htonl(0x4d010000) && get_u_int16_t(packet->payload, 8) == htons(0x4903) && get_u_int16_t(packet->payload, 76) == htons(0x0002) && get_u_int32_t(packet->payload, 78) == htonl(0x00340100)) { NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected len == 82.\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } } } else if (packet->udp != NULL) { if (src != NULL && (packet->udp->source == src->detected_gnutella_udp_port1 || packet->udp->source == src->detected_gnutella_udp_port2) && (packet->tick_timestamp - src->gnutella_ts) < ndpi_struct->gnutella_timeout) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "port based detection\n\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); } /* observations: * all the following patterns send out many packets which are the only ones of their flows, * often on the very beginning of the traces, or flows with many packets in one direction only. * but then suddenly, one gets an answer as you can see in netpeker-gnutella-rpc.pcap packet 11483. * Maybe gnutella tries to send out keys? */ if (packet->payload_packet_len == 23 && packet->payload[15] == 0x00 && packet->payload[16] == 0x41 && packet->payload[17] == 0x01 && packet->payload[18] == 0x00 && packet->payload[19] == 0x00 && packet->payload[20] == 0x00 && packet->payload[21] == 0x00 && packet->payload[22] == 0x00) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "detected gnutella udp, len = 23.\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } if (packet->payload_packet_len == 35 && packet->payload[25] == 0x49 && packet->payload[26] == 0x50 && packet->payload[27] == 0x40 && packet->payload[28] == 0x83 && packet->payload[29] == 0x53 && packet->payload[30] == 0x43 && packet->payload[31] == 0x50 && packet->payload[32] == 0x41) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "detected gnutella udp, len = 35.\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } if (packet->payload_packet_len == 32 && (memcmp(&packet->payload[16], "\x31\x01\x00\x09\x00\x00\x00\x4c\x49\x4d\x45", 11) == 0)) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "detected gnutella udp, len = 32.\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } if (packet->payload_packet_len == 34 && (memcmp(&packet->payload[25], "SCP@", 4) == 0) && (memcmp(&packet->payload[30], "DNA@", 4) == 0)) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "detected gnutella udp, len = 34.\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } if ((packet->payload_packet_len == 73 || packet->payload_packet_len == 96) && memcmp(&packet->payload[32], "urn:sha1:", 9) == 0) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "detected gnutella udp, len = 73,96.\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } if (memcmp(packet->payload, "GND", 3) == 0) { if ((packet->payload_packet_len == 8 && (memcmp(&packet->payload[6], "\x01\x00", 2) == 0)) || (packet->payload_packet_len == 11 && (memcmp(&packet->payload[6], "\x01\x01\x08\x50\x49", 5) == 0)) || (packet->payload_packet_len == 17 && (memcmp (&packet->payload[6], "\x01\x01\x4c\x05\x50", 5) == 0)) || (packet->payload_packet_len == 28 && (memcmp(&packet->payload[6], "\x01\x01\x54\x0f\x51\x4b\x52\x50\x06\x52", 10) == 0)) || (packet->payload_packet_len == 41 && (memcmp(&packet->payload[6], "\x01\x01\x5c\x1b\x50\x55\x53\x48\x48\x10", 10) == 0)) || (packet->payload_packet_len > 200 && packet->payload_packet_len < 300 && packet->payload[3] == 0x03) || (packet->payload_packet_len > 300 && (packet->payload[3] == 0x01 || packet->payload[3] == 0x03))) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "detected gnutella udp, GND.\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } } if ((packet->payload_packet_len == 32) && memcmp(&packet->payload[16], "\x31\x01\x00\x09\x00\x00\x00", 7) == 0) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "detected gnutella udp, len = 32 ii.\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } if ((packet->payload_packet_len == 23) && memcmp(&packet->payload[16], "\x00\x01\x00\x00\x00\x00\x00", 7) == 0) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "detected gnutella udp, len = 23 ii.\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } } //neonet detection follows /* haven't found any trace with this pattern */ if (packet->tcp != NULL && ntohs(packet->tcp->source) >= 1024 && ntohs(packet->tcp->dest) >= 1024) { if (flow->l4.tcp.gnutella_stage == 0) { if (flow->packet_counter == 1 && (packet->payload_packet_len == 11 || packet->payload_packet_len == 33 || packet->payload_packet_len == 37)) { flow->l4.tcp.gnutella_msg_id[0] = packet->payload[4]; flow->l4.tcp.gnutella_msg_id[1] = packet->payload[6]; flow->l4.tcp.gnutella_msg_id[2] = packet->payload[8]; flow->l4.tcp.gnutella_stage = 1 + packet->packet_direction; return; } } else if (flow->l4.tcp.gnutella_stage == 1 + packet->packet_direction) { if (flow->packet_counter == 2 && (packet->payload_packet_len == 33 || packet->payload_packet_len == 22) && flow->l4.tcp.gnutella_msg_id[0] == packet->payload[0] && flow->l4.tcp.gnutella_msg_id[1] == packet->payload[2] && flow->l4.tcp.gnutella_msg_id[2] == packet->payload[4] && NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_GNUTELLA)) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "GNUTELLA DETECTED due to message ID match (NEONet protocol)\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } } else if (flow->l4.tcp.gnutella_stage == 2 - packet->packet_direction) { if (flow->packet_counter == 2 && (packet->payload_packet_len == 10 || packet->payload_packet_len == 75) && flow->l4.tcp.gnutella_msg_id[0] == packet->payload[0] && flow->l4.tcp.gnutella_msg_id[1] == packet->payload[2] && flow->l4.tcp.gnutella_msg_id[2] == packet->payload[4] && NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_GNUTELLA)) { NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "GNUTELLA DETECTED due to message ID match (NEONet protocol)\n"); ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } } } NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_GNUTELLA); }
void ndpi_search_winmx_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; if (flow->l4.tcp.winmx_stage == 0) { if (packet->payload_packet_len == 1 || (packet->payload_packet_len > 1 && packet->payload[0] == 0x31)) { return; } /* did not see this pattern in any trace that we have */ if (((packet->payload_packet_len) == 4) && (memcmp(packet->payload, "SEND", 4) == 0)) { NDPI_LOG(NDPI_PROTOCOL_WINMX, ndpi_struct, NDPI_LOG_DEBUG, "maybe WinMX Send\n"); flow->l4.tcp.winmx_stage = 1; return; } if (((packet->payload_packet_len) == 3) && (memcmp(packet->payload, "GET", 3) == 0)) { NDPI_LOG(NDPI_PROTOCOL_WINMX, ndpi_struct, NDPI_LOG_DEBUG, "found winmx by GET\n"); ndpi_int_winmx_add_connection(ndpi_struct, flow); return; } if (packet->payload_packet_len == 149 && packet->payload[0] == '8') { NDPI_LOG(NDPI_PROTOCOL_WINMX, ndpi_struct, NDPI_LOG_DEBUG, "maybe WinMX\n"); if (get_u_int32_t(packet->payload, 17) == 0 && get_u_int32_t(packet->payload, 21) == 0 && get_u_int32_t(packet->payload, 25) == 0 && get_u_int16_t(packet->payload, 39) == 0 && get_u_int16_t(packet->payload, 135) == htons(0x7edf) && get_u_int16_t(packet->payload, 147) == htons(0xf792)) { NDPI_LOG(NDPI_PROTOCOL_WINMX, ndpi_struct, NDPI_LOG_DEBUG, "found winmx by pattern in first packet\n"); ndpi_int_winmx_add_connection(ndpi_struct, flow); return; } } /* did not see this pattern in any trace that we have */ } else if (flow->l4.tcp.winmx_stage == 1) { if (packet->payload_packet_len > 10 && packet->payload_packet_len < 1000) { u_int16_t left = packet->payload_packet_len - 1; while (left > 0) { if (packet->payload[left] == ' ') { NDPI_LOG(NDPI_PROTOCOL_WINMX, ndpi_struct, NDPI_LOG_DEBUG, "found winmx in second packet\n"); ndpi_int_winmx_add_connection(ndpi_struct, flow); return; } else if (packet->payload[left] < '0' || packet->payload[left] > '9') { break; } left--; } } } NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_WINMX); }