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; //} }
static void ndpi_search_msn(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; /* this if request should always be true */ if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MSN) == 0) { /* we deal with tcp now */ if (packet->tcp != NULL) { /* msn can use http or ssl for connection. That's why every http, ssl and ukn packet must enter in the msn detection */ /* the detection can swich out the http or the ssl detection. In this case we need not check those protocols */ // need to do the ceck when protocol == http too (POST /gateway ...) if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN #if defined(NDPI_PROTOCOL_HTTP) || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP #endif #if defined(NDPI_PROTOCOL_SSL) || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL #endif #if defined(NDPI_PROTOCOL_STUN) || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STUN #endif ) { ndpi_search_msn_tcp(ndpi_struct, flow); } } else if (packet->udp != NULL) { ndpi_search_udp_msn_misc(ndpi_struct, flow); } } }
static void check_http_payload(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "called check_http_payload.\n"); #ifdef NDPI_PROTOCOL_FLASH if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_FLASH) != 0) flash_check_http_payload(ndpi_struct, flow); #endif #ifdef NDPI_PROTOCOL_AVI if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_AVI) != 0) avi_check_http_payload(ndpi_struct, flow); #endif #ifdef NDPI_PROTOCOL_TEAMVIEWER teamviewer_check_http_payload(ndpi_struct, flow); #endif }
static inline #else __forceinline static #endif void ndpi_search_yahoo_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_id_struct *src = flow->src; if (src == NULL || NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) == 0) { goto excl_yahoo_udp; } excl_yahoo_udp: NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_YAHOO); }
static void ndpi_int_edonkey_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; int edk_stage2_len; /*len range increase if safe mode and also only once */ if (ndpi_struct->edonkey_safe_mode == 0) edk_stage2_len = 140; else if (!flow->l4.tcp.edk_ext || packet->payload_packet_len == 212) { edk_stage2_len = 300; } else edk_stage2_len = 140; /* skip excluded connections */ if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_EDONKEY) != 0) return; /* source and dst port must be 80 443 or > 1024 */ if (ndpi_struct->edonkey_upper_ports_only != 0) { u_int16_t port; port = ntohs(packet->tcp->source); /* source and dst port must be 80 443 or > 1024 */ if (port < 1024 && port != 80 && port != 443) goto exclude_edk_tcp; port = ntohs(packet->tcp->dest); if (port < 1024 && port != 80 && port != 443) goto exclude_edk_tcp; } /* return here for empty packets, we needed them only for bt port detection */ if (packet->payload_packet_len == 0) return; /* skip marked packets */ if (flow->edk_stage == 0 && packet->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN) return; /* first: check for unencrypted traffic */ if (flow->edk_stage == 0) { /* check for client hello */ if (packet->payload_packet_len >= 32 && get_l32(packet->payload, 1) <= (packet->payload_packet_len - 5) && (packet->payload[0] == 0xe3 || packet->payload[0] == 0xc5)) { if (packet->payload[5] == 0x01 && ((packet->payload[6] == 0x10 && get_l32(packet->payload, 29) < 0x0F) || (get_l32(packet->payload, 28) > 0x00 && get_l32(packet->payload, 28) < 0x0F))) { NDPI_LOG_EDONKEY(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "edk hello meta tag recognized\n"); flow->edk_stage = 16 + packet->packet_direction; return; } } } if ((17 - packet->packet_direction) == flow->edk_stage) { if ((packet->payload_packet_len >= 32 && get_l32(packet->payload, 1) == 9 && (packet->payload[0] == 0xe3) && packet->payload[5] == 0x40) || (packet->payload_packet_len >= 32 && (packet->payload[0] == 0xe3) && packet->payload[5] == 0x40 && check_edk_len(packet->payload, packet->payload_packet_len)) || (packet->payload_packet_len >= 32 && packet->payload[0] == 0xe3 && packet->payload[5] == 0x4c && (get_l32(packet->payload, 1) == (packet->payload_packet_len - 5) || check_edk_len(packet->payload, packet->payload_packet_len))) || (packet->payload_packet_len >= 32 && get_l32(packet->payload, 1) == (packet->payload_packet_len - 5) && packet->payload[0] == 0xe3 && packet->payload[5] == 0x38) || (packet->payload_packet_len >= 20 && get_l32(packet->payload, 1) == (packet->payload_packet_len - 5) && packet->payload[0] == 0xc5 && packet->payload[5] == 0x92) || (packet->payload_packet_len >= 20 && get_l32(packet->payload, 1) <= (packet->payload_packet_len - 5) && packet->payload[0] == 0xe3 && packet->payload[5] == 0x58) || (packet->payload_packet_len >= 20 && get_l32(packet->payload, 1) <= (packet->payload_packet_len - 5) && (packet->payload[0] == 0xe3 || packet->payload[0] == 0xc5) && packet->payload[5] == 0x01)) { NDPI_LOG_EDONKEY(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "edk 17: detected plain detection\n"); ndpi_add_connection_as_edonkey(ndpi_struct, flow, NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION); return; } NDPI_LOG_EDONKEY(NDPI_PROTOCOL_EDONKEY, ndpi_struct, NDPI_LOG_DEBUG, "edk 17: id: %u, %u, %u not detected\n", packet->payload[0], get_l32(packet->payload, 1), packet->payload[5]); } exclude_edk_tcp: NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_EDONKEY); return; }
static void ssl_mark_and_payload_search_for_other_protocols(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { #if defined(NDPI_PROTOCOL_MEEBO)|| defined(NDPI_PROTOCOL_TOR) || defined(NDPI_PROTOCOL_VPN_X) || defined(NDPI_PROTOCOL_UNENCRYPED_JABBER) || defined (NDPI_PROTOCOL_OSCAR) || defined (NDPI_PROTOCOL_ITUNES) || defined (NDPI_SERVICE_GMAIL) struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=flow->src; // struct ndpi_id_struct *dst=flow->dst; u_int32_t a; u_int32_t end; #if defined(NDPI_PROTOCOL_UNENCRYPED_JABBER) if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER) != 0) goto check_for_ssl_payload; #endif #if defined(NDPI_PROTOCOL_OSCAR) if(NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_OSCAR) != 0) goto check_for_ssl_payload; #endif goto no_check_for_ssl_payload; check_for_ssl_payload: end = packet->payload_packet_len - 20; for (a = 5; a < end; a++) { #ifdef NDPI_PROTOCOL_UNENCRYPED_JABBER if(packet->payload[a] == 't') { if(memcmp(&packet->payload[a], "talk.google.com", 15) == 0) { NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "ssl jabber packet match\n"); if(NDPI_COMPARE_PROTOCOL_TO_BITMASK (ndpi_struct->detection_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER) != 0) { ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNENCRYPED_JABBER); return; } } } #endif #ifdef NDPI_PROTOCOL_OSCAR if(packet->payload[a] == 'A' || packet->payload[a] == 'k' || packet->payload[a] == 'c' || packet->payload[a] == 'h') { if(((a + 19) < packet->payload_packet_len && memcmp(&packet->payload[a], "America Online Inc.", 19) == 0) // || (end - c > 3 memcmp (&packet->payload[c],"AOL", 3) == 0 ) // || (end - c > 7 && memcmp (&packet->payload[c], "AOL LLC", 7) == 0) || ((a + 15) < packet->payload_packet_len && memcmp(&packet->payload[a], "kdc.uas.aol.com", 15) == 0) || ((a + 14) < packet->payload_packet_len && memcmp(&packet->payload[a], "*****@*****.**", 14) == 0) || ((a + 41) < packet->payload_packet_len && memcmp(&packet->payload[a], "http://crl.aol.com/AOLMSPKI/aolServerCert", 41) == 0) || ((a + 28) < packet->payload_packet_len && memcmp(&packet->payload[a], "http://ocsp.web.aol.com/ocsp", 28) == 0) || ((a + 32) < packet->payload_packet_len && memcmp(&packet->payload[a], "http://pki-info.aol.com/AOLMSPKI", 32) == 0)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR SERVER SSL DETECTED\n"); if(flow->dst != NULL && packet->payload_packet_len > 75) { memcpy(flow->dst->oscar_ssl_session_id, &packet->payload[44], 32); flow->dst->oscar_ssl_session_id[32] = '\0'; flow->dst->oscar_last_safe_access_time = packet->tick_timestamp; } ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OSCAR); return; } } if(packet->payload[a] == 'm' || packet->payload[a] == 's') { if((a + 21) < packet->payload_packet_len && (memcmp(&packet->payload[a], "my.screenname.aol.com", 21) == 0 || memcmp(&packet->payload[a], "sns-static.aolcdn.com", 21) == 0)) { NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR SERVER SSL DETECTED\n"); ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OSCAR); return; } } #endif } no_check_for_ssl_payload: #endif if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) { NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "found ssl connection.\n"); sslDetectProtocolFromCertificate(ndpi_struct, flow); if(!packet->ssl_certificate_detected && (!(flow->l4.tcp.ssl_seen_client_cert && flow->l4.tcp.ssl_seen_server_cert))) { /* SSL without certificate (Skype, Ultrasurf?) */ ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSL_NO_CERT); } else ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSL); } }
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); } }
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); }
static void ndpi_search_yahoo_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; const struct ndpi_yahoo_header *yahoo = (struct ndpi_yahoo_header *) packet->payload; if (packet->payload_packet_len == 0) { return; } /* packet must be at least 20 bytes long */ if (packet->payload_packet_len >= 20 && memcmp(yahoo->YMSG_str, "YMSG", 4) == 0 && ((packet->payload_packet_len - 20) == ntohs(yahoo->len) || check_ymsg(packet->payload, packet->payload_packet_len))) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO FOUND\n"); flow->yahoo_detection_finished = 2; if (ntohs(yahoo->service) == 24 || ntohs(yahoo->service) == 152 || ntohs(yahoo->service) == 74) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO conference or chat invite found"); if (src != NULL) { src->yahoo_conf_logged_in = 1; } if (dst != NULL) { dst->yahoo_conf_logged_in = 1; } } if (ntohs(yahoo->service) == 27 || ntohs(yahoo->service) == 155 || ntohs(yahoo->service) == 160) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO conference or chat logoff found"); if (src != NULL) { src->yahoo_conf_logged_in = 0; src->yahoo_voice_conf_logged_in = 0; } } NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } else if (flow->yahoo_detection_finished == 2 && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_YAHOO) { return; } else if (packet->payload_packet_len == 4 && memcmp(yahoo->YMSG_str, "YMSG", 4) == 0) { flow->l4.tcp.yahoo_sip_comm = 1; return; } else if (flow->l4.tcp.yahoo_sip_comm && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN && flow->packet_counter < 3) { return; } /* now test for http login, at least 100 a bytes packet */ if (ndpi_struct->yahoo_detect_http_connections != 0 && packet->payload_packet_len > 100) { if (memcmp(packet->payload, "POST /relay?token=", 18) == 0 || memcmp(packet->payload, "GET /relay?token=", 17) == 0 || memcmp(packet->payload, "GET /?token=", 12) == 0 || memcmp(packet->payload, "HEAD /relay?token=", 18) == 0) { if ((src != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) != 0) || (dst != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) != 0)) { /* this is mostly a file transfer */ NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } if (memcmp(packet->payload, "POST ", 5) == 0) { u_int16_t a; ndpi_parse_packet_line_info(ndpi_struct, flow); if ((packet->user_agent_line.len >= 21) && (memcmp(packet->user_agent_line.ptr, "YahooMobileMessenger/", 21) == 0)) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO(Mobile)"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } if (NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_YAHOO) && packet->parsed_lines > 5 && memcmp(&packet->payload[5], "/Messenger.", 11) == 0 && packet->line[1].len >= 17 && memcmp(packet->line[1].ptr, "Connection: Close", 17) == 0 && packet->line[2].len >= 6 && memcmp(packet->line[2].ptr, "Host: ", 6) == 0 && packet->line[3].len >= 16 && memcmp(packet->line[3].ptr, "Content-Length: ", 16) == 0 && packet->line[4].len >= 23 && memcmp(packet->line[4].ptr, "User-Agent: Mozilla/5.0", 23) == 0 && packet->line[5].len >= 23 && memcmp(packet->line[5].ptr, "Cache-Control: no-cache", 23) == 0) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO HTTP POST P2P FILETRANSFER FOUND\n"); NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } if (packet->host_line.ptr != NULL && packet->host_line.len >= 26 && memcmp(packet->host_line.ptr, "filetransfer.msg.yahoo.com", 26) == 0) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO HTTP POST FILETRANSFER FOUND\n"); NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } /* now check every line */ for (a = 0; a < packet->parsed_lines; a++) { if (packet->line[a].len >= 4 && memcmp(packet->line[a].ptr, "YMSG", 4) == 0) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO HTTP POST FOUND, line is: %.*s\n", packet->line[a].len, packet->line[a].ptr); NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } if (packet->parsed_lines > 8 && packet->line[8].len > 250 && packet->line[8].ptr != NULL) { if (memcmp(packet->line[8].ptr, "<Session ", 9) == 0) { if (ndpi_check_for_YmsgCommand(packet->line[8].len, packet->line[8].ptr)) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found HTTP Proxy Yahoo Chat <Ymsg Command= pattern \n"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } } } if (memcmp(packet->payload, "GET /Messenger.", 15) == 0) { if ((src != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) != 0) || (dst != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) != 0)) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO HTTP GET /Messenger. match\n"); NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } if ((memcmp(packet->payload, "GET /", 5) == 0)) { ndpi_parse_packet_line_info(ndpi_struct, flow); if ((packet->user_agent_line.ptr != NULL && packet->user_agent_line.len >= NDPI_STATICSTRING_LEN("YahooMobileMessenger/") && memcmp(packet->user_agent_line.ptr, "YahooMobileMessenger/", NDPI_STATICSTRING_LEN("YahooMobileMessenger/")) == 0) || (packet->user_agent_line.len >= 15 && (memcmp(packet->user_agent_line.ptr, "Y!%20Messenger/", 15) == 0))) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO(Mobile)"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } if (packet->host_line.ptr != NULL && packet->host_line.len >= NDPI_STATICSTRING_LEN("msg.yahoo.com") && memcmp(&packet->host_line.ptr[packet->host_line.len - NDPI_STATICSTRING_LEN("msg.yahoo.com")], "msg.yahoo.com", NDPI_STATICSTRING_LEN("msg.yahoo.com")) == 0) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } } /* found another http login command for yahoo, it is like OSCAR */ /* detect http connections */ if (packet->payload_packet_len > 50 && (memcmp(packet->payload, "content-length: ", 16) == 0)) { ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->parsed_lines > 2 && packet->line[1].len == 0) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "first line is empty.\n"); if (packet->line[2].len > 13 && memcmp(packet->line[2].ptr, "<Ymsg Command=", 14) == 0) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO web chat found\n"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } } } if (packet->payload_packet_len > 38 && memcmp(packet->payload, "CONNECT scs.msg.yahoo.com:5050 HTTP/1.", 38) == 0) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO-HTTP FOUND\n"); NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } if ((src != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) != 0) || (dst != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) != 0)) { if (packet->payload_packet_len == 6 && memcmp(packet->payload, "YAHOO!", 6) == 0) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } /* asymmetric detection for SNDIMG not done yet. * See ./Yahoo8.1-VideoCall-LAN.pcap and ./Yahoo-VideoCall-inPublicIP.pcap */ if (packet->payload_packet_len == 8 && (memcmp(packet->payload, "<SNDIMG>", 8) == 0 || memcmp(packet->payload, "<REQIMG>", 8) == 0 || memcmp(packet->payload, "<RVWCFG>", 8) == 0 || memcmp(packet->payload, "<RUPCFG>", 8) == 0)) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO SNDIMG or REQIMG or RVWCFG or RUPCFG FOUND\n"); if (src != NULL) { if (memcmp(packet->payload, "<SNDIMG>", 8) == 0) { src->yahoo_video_lan_dir = 0; } else { src->yahoo_video_lan_dir = 1; } src->yahoo_video_lan_timer = packet->tick_timestamp; } if (dst != NULL) { if (memcmp(packet->payload, "<SNDIMG>", 8) == 0) { dst->yahoo_video_lan_dir = 0; } else { dst->yahoo_video_lan_dir = 1; } dst->yahoo_video_lan_timer = packet->tick_timestamp; } NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO subtype VIDEO"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } if (src != NULL && packet->tcp->dest == htons(5100) && ((u_int32_t) (packet->tick_timestamp - src->yahoo_video_lan_timer) < ndpi_struct->yahoo_lan_video_timeout)) { if (src->yahoo_video_lan_dir == 1) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "IMG MARKED"); return; } } if (dst != NULL && packet->tcp->dest == htons(5100) && ((u_int32_t) (packet->tick_timestamp - dst->yahoo_video_lan_timer) < ndpi_struct->yahoo_lan_video_timeout)) { if (dst->yahoo_video_lan_dir == 0) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "IMG MARKED"); return; } } } /* detect YAHOO over HTTP proxy */ #ifdef NDPI_PROTOCOL_HTTP if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP) #endif { if (flow->l4.tcp.yahoo_http_proxy_stage == 0) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "YAHOO maybe HTTP proxy packet 1 => need next packet\n"); flow->l4.tcp.yahoo_http_proxy_stage = 1 + packet->packet_direction; return; } if (flow->l4.tcp.yahoo_http_proxy_stage == 1 + packet->packet_direction) { if ((packet->payload_packet_len > 250) && (memcmp(packet->payload, "<Session ", 9) == 0)) { if (ndpi_check_for_YmsgCommand(packet->payload_packet_len, packet->payload)) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found HTTP Proxy Yahoo Chat <Ymsg Command= pattern \n"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "YAHOO maybe HTTP proxy still initial direction => need next packet\n"); return; } if (flow->l4.tcp.yahoo_http_proxy_stage == 2 - packet->packet_direction) { ndpi_parse_packet_line_info_any(ndpi_struct, flow); if (packet->parsed_lines >= 9) { if (packet->line[4].ptr != NULL && packet->line[4].len >= 9 && packet->line[8].ptr != NULL && packet->line[8].len >= 6 && memcmp(packet->line[4].ptr, "<Session ", 9) == 0 && memcmp(packet->line[8].ptr, "<Ymsg ", 6) == 0) { NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO over HTTP proxy"); ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } } } NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_YAHOO); }
static void ndpi_search_irc_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; int less; u_int16_t c = 0; u_int16_t c1 = 0; u_int16_t port = 0; u_int16_t sport = 0; u_int16_t dport = 0; u_int16_t counter = 0; u_int16_t i = 0; u_int16_t j = 0; u_int16_t k = 0; u_int16_t h; u_int16_t http_content_ptr_len = 0; u_int8_t space = 0; NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "irc : search irc\n"); if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC && flow->packet_counter > 70) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "exclude irc, packet_counter > 70\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_IRC); return; } if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC && flow->packet_counter > 30 && flow->l4.tcp.irc_stage2 == 0) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "packet_counter > 30, exclude irc.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_IRC); return; } if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_IRC) { if (src != NULL && ((u_int32_t) (packet->tick_timestamp - src->irc_ts) < ndpi_struct->irc_timeout)) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "irc : save src connection packet detected\n"); src->irc_ts = packet->tick_timestamp; } else if (dst != NULL && ((u_int32_t) (packet->tick_timestamp - dst->irc_ts) < ndpi_struct->irc_timeout)) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "irc : save dst connection packet detected\n"); dst->irc_ts = packet->tick_timestamp; } } if (((dst != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_IRC) && ((u_int32_t) (packet->tick_timestamp - dst->irc_ts)) < ndpi_struct->irc_timeout)) || (src != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK (src->detected_protocol_bitmask, NDPI_PROTOCOL_IRC) && ((u_int32_t) (packet->tick_timestamp - src->irc_ts)) < ndpi_struct->irc_timeout)) { if (packet->tcp != NULL) { sport = packet->tcp->source; dport = packet->tcp->dest; } if (dst != NULL) { for (counter = 0; counter < dst->irc_number_of_port; counter++) { if (dst->irc_port[counter] == sport || dst->irc_port[counter] == dport) { dst->last_time_port_used[counter] = packet->tick_timestamp; NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "dest port matched with the DCC port and the flow is marked as IRC"); ndpi_int_irc_add_connection(ndpi_struct, flow); return; } } } if (src != NULL) { for (counter = 0; counter < src->irc_number_of_port; counter++) { if (src->irc_port[counter] == sport || src->irc_port[counter] == dport) { src->last_time_port_used[counter] = packet->tick_timestamp; ndpi_int_irc_add_connection(ndpi_struct, flow); NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "Source port matched with the DCC port and the flow is marked as IRC"); return; } } } } if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC && flow->packet_counter == 2 && (packet->payload_packet_len > 400 && packet->payload_packet_len < 1381)) { for (c1 = 50; c1 < packet->payload_packet_len - 23; c1++) { if (packet->payload[c1] == 'i' || packet->payload[c1] == 'd') { if ((memcmp(&packet->payload[c1], "irc.hackthissite.org0", 21) == 0) || (memcmp(&packet->payload[c1], "irc.gamepad.ca1", 15) == 0) || (memcmp(&packet->payload[c1], "dungeon.axenet.org0", 19) == 0) || (memcmp(&packet->payload[c1], "dazed.nuggethaus.net", 20) == 0) || (memcmp(&packet->payload[c1], "irc.indymedia.org", 17) == 0) || (memcmp(&packet->payload[c1], "irc.cccp-project.net", 20) == 0) || (memcmp(&packet->payload[c1], "dirc.followell.net0", 19) == 0) || (memcmp(&packet->payload[c1], "irc.discostars.de1", 18) == 0) || (memcmp(&packet->payload[c1], "irc.rizon.net", 13) == 0)) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC SSL detected with :- irc.hackthissite.org0 | irc.gamepad.ca1 | dungeon.axenet.org0 " "| dazed.nuggethaus.net | irc.indymedia.org | irc.discostars.de1 "); ndpi_int_irc_add_connection(ndpi_struct, flow); break; } } } } if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC && ndpi_search_irc_ssl_detect_ninty_percent_but_very_fast(ndpi_struct, flow) != 0) { return; } if (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC && flow->packet_counter < 20 && packet->payload_packet_len >= 8) { if (get_u_int8_t(packet->payload, packet->payload_packet_len - 1) == 0x0a || (ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0a00)) { if (memcmp(packet->payload, ":", 1) == 0) { if (packet->payload[packet->payload_packet_len - 2] != 0x0d && packet->payload[packet->payload_packet_len - 1] == 0x0a) { ndpi_parse_packet_line_info_unix(ndpi_struct, flow); packet->parsed_lines = packet->parsed_unix_lines; for (i = 0; i < packet->parsed_lines; i++) { packet->line[i] = packet->unix_line[i]; packet->line[i].ptr = packet->unix_line[i].ptr; packet->line[i].len = packet->unix_line[i].len; } } else if (packet->payload[packet->payload_packet_len - 2] == 0x0d) { ndpi_parse_packet_line_info(ndpi_struct, flow); } else { flow->l4.tcp.irc_3a_counter++; } for (i = 0; i < packet->parsed_lines; i++) { if (packet->line[i].ptr[0] == ':') { flow->l4.tcp.irc_3a_counter++; if (flow->l4.tcp.irc_3a_counter == 7) { /* ':' == 0x3a */ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "0x3a. seven times. found irc."); ndpi_int_irc_add_connection(ndpi_struct, flow); goto detected_irc; } } } if (flow->l4.tcp.irc_3a_counter == 7) { /* ':' == 0x3a */ NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "0x3a. seven times. found irc."); ndpi_int_irc_add_connection(ndpi_struct, flow); goto detected_irc; } } if ((memcmp(packet->payload, "USER ", 5) == 0) || (memcmp(packet->payload, "NICK ", 5) == 0) || (memcmp(packet->payload, "PASS ", 5) == 0) || (memcmp(packet->payload, ":", 1) == 0 && ndpi_check_for_NOTICE_or_PRIVMSG(ndpi_struct, flow) != 0) || (memcmp(packet->payload, "PONG ", 5) == 0) || (memcmp(packet->payload, "PING ", 5) == 0) || (memcmp(packet->payload, "JOIN ", 5) == 0) || (memcmp(packet->payload, "NOTICE ", 7) == 0) || (memcmp(packet->payload, "PRIVMSG ", 8) == 0) || (memcmp(packet->payload, "VERSION ", 8) == 0)) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "USER, NICK, PASS, NOTICE, PRIVMSG one time"); if (flow->l4.tcp.irc_stage == 2) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "found irc"); ndpi_int_irc_add_connection(ndpi_struct, flow); flow->l4.tcp.irc_stage = 3; } if (flow->l4.tcp.irc_stage == 1) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "second time, stage=2"); flow->l4.tcp.irc_stage = 2; } if (flow->l4.tcp.irc_stage == 0) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "first time, stage=1"); flow->l4.tcp.irc_stage = 1; } /* irc packets can have either windows line breaks (0d0a) or unix line breaks (0a) */ if (packet->payload[packet->payload_packet_len - 2] == 0x0d && packet->payload[packet->payload_packet_len - 1] == 0x0a) { ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->parsed_lines > 1) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "packet contains more than one line"); for (c = 1; c < packet->parsed_lines; c++) { if (packet->line[c].len > 4 && (memcmp(packet->line[c].ptr, "NICK ", 5) == 0 || memcmp(packet->line[c].ptr, "USER ", 5) == 0)) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "two icq signal words in the same packet"); ndpi_int_irc_add_connection(ndpi_struct, flow); flow->l4.tcp.irc_stage = 3; return; } } } } else if (packet->payload[packet->payload_packet_len - 1] == 0x0a) { ndpi_parse_packet_line_info_unix(ndpi_struct, flow); if (packet->parsed_unix_lines > 1) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "packet contains more than one line"); for (c = 1; c < packet->parsed_unix_lines; c++) { if (packet->unix_line[c].len > 4 && (memcmp(packet->unix_line[c].ptr, "NICK ", 5) == 0 || memcmp(packet->unix_line[c].ptr, "USER ", 5) == 0)) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "two icq signal words in the same packet"); ndpi_int_irc_add_connection(ndpi_struct, flow); flow->l4.tcp.irc_stage = 3; return; } } } } } } } /** * Trying to primarily detect the HTTP Web based IRC chat patterns based on the HTTP headers * during the User login time.When the HTTP data gets posted using the POST method ,patterns * will be searched in the HTTP content. */ if ((flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC) && (flow->l4.tcp.irc_stage == 0) && (packet->payload_packet_len > 5)) { //HTTP POST Method being employed if (memcmp(packet->payload, "POST ", 5) == 0) { ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->parsed_lines) { u_int16_t http_header_len = (packet->line[packet->parsed_lines - 1].ptr - packet->payload) + 2; if (packet->payload_packet_len > http_header_len) { http_content_ptr_len = packet->payload_packet_len - http_header_len; } if ((ndpi_check_for_IRC_traces(packet->line[0].ptr, packet->line[0].len)) || ((packet->http_url_name.ptr) && (ndpi_check_for_IRC_traces(packet->http_url_name.ptr, packet->http_url_name.len))) || ((packet->referer_line.ptr) && (ndpi_check_for_IRC_traces(packet->referer_line.ptr, packet->referer_line.len)))) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC detected from the Http URL/ Referer header "); flow->l4.tcp.irc_stage = 1; // HTTP POST Request body is not in the same packet. if (!http_content_ptr_len) { return; } } } } } if ((flow->detected_protocol_stack[0] != NDPI_PROTOCOL_IRC) && (flow->l4.tcp.irc_stage == 1)) { if ((((packet->payload_packet_len - http_content_ptr_len) > 10) && (memcmp(packet->payload + http_content_ptr_len, "interface=", 10) == 0) && (ndpi_check_for_Nickname(ndpi_struct, flow) != 0)) || (((packet->payload_packet_len - http_content_ptr_len) > 5) && (memcmp(packet->payload + http_content_ptr_len, "item=", 5) == 0) && (ndpi_check_for_cmd(ndpi_struct, flow) != 0))) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "IRC Nickname, cmd, one time"); ndpi_int_irc_add_connection(ndpi_struct, flow); return; } } detected_irc: NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "detected_irc:"); if (flow->detected_protocol_stack[0] == NDPI_PROTOCOL_IRC) { /* maybe this can be deleted at the end */ if (packet->payload[packet->payload_packet_len - 2] != 0x0d && packet->payload[packet->payload_packet_len - 1] == 0x0a) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "ndpi_parse_packet_line_info_unix(ndpi_struct, flow);"); ndpi_parse_packet_line_info_unix(ndpi_struct, flow); packet->parsed_lines = packet->parsed_unix_lines; for (i = 0; i < packet->parsed_lines; i++) { packet->line[i] = packet->unix_line[i]; packet->line[i].ptr = packet->unix_line[i].ptr; packet->line[i].len = packet->unix_line[i].len; } } else if (packet->payload[packet->payload_packet_len - 2] == 0x0d) { ndpi_parse_packet_line_info(ndpi_struct, flow); } else { return; } for (i = 0; i < packet->parsed_lines; i++) { if (packet->line[i].len > 6 && memcmp(packet->line[i].ptr, "NOTICE ", 7) == 0) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "NOTICE"); for (j = 7; j < packet->line[i].len - 8; j++) { if (packet->line[i].ptr[j] == ':') { if (memcmp(&packet->line[i].ptr[j + 1], "DCC SEND ", 9) == 0 || memcmp(&packet->line[i].ptr[j + 1], "DCC CHAT ", 9) == 0) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "found NOTICE and DCC CHAT or DCC SEND."); } } } } if (packet->payload_packet_len > 0 && packet->payload[0] == 0x3a /* 0x3a = ':' */ ) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "3a"); for (j = 1; j < packet->line[i].len - 9; j++) { if (packet->line[i].ptr[j] == ' ') { j++; if (packet->line[i].ptr[j] == 'P') { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "P"); j++; if (memcmp(&packet->line[i].ptr[j], "RIVMSG ", 7) == 0) NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "RIVMSG"); h = j + 7; goto read_privmsg; } } } } if (packet->line[i].len > 7 && (memcmp(packet->line[i].ptr, "PRIVMSG ", 8) == 0)) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "PRIVMSG "); h = 7; read_privmsg: for (j = h; j < packet->line[i].len - 9; j++) { if (packet->line[i].ptr[j] == ':') { if (memcmp(&packet->line[i].ptr[j + 1], "xdcc ", 5) == 0) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "xdcc should match."); } j += 2; if (memcmp(&packet->line[i].ptr[j], "DCC ", 4) == 0) { j += 4; NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "found DCC."); if (memcmp(&packet->line[i].ptr[j], "SEND ", 5) == 0 || (memcmp(&packet->line[i].ptr[j], "CHAT", 4) == 0) || (memcmp(&packet->line[i].ptr[j], "chat", 4) == 0) || (memcmp(&packet->line[i].ptr[j], "sslchat", 7) == 0) || (memcmp(&packet->line[i].ptr[j], "TSEND", 5) == 0)) { NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "found CHAT,chat,sslchat,TSEND."); j += 4; while (packet->line[i].len > j && ((packet->line[i].ptr[j] >= 'a' && packet->line[i].ptr[j] <= 'z') || (packet->line[i].ptr[j] >= 'A' && packet->line[i].ptr[j] <= 'Z') || (packet->line[i].ptr[j] >= '0' && packet->line[i].ptr[j] <= '9') || (packet->line[i].ptr[j] >= ' ') || (packet->line[i].ptr[j] >= '.') || (packet->line[i].ptr[j] >= '-'))) { if (packet->line[i].ptr[j] == ' ') { space++; NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "space %u.", space); } if (space == 3) { j++; NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "read port."); if (src != NULL) { k = j; port = ntohs_ndpi_bytestream_to_number (&packet->line[i].ptr[j], packet->payload_packet_len - j, &j); NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "port %u.", port); j = k; // hier jetzt überlegen, wie die ports abgespeichert werden sollen if (src->irc_number_of_port < 16) NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "src->irc_number_of_port < 16."); if (src->irc_number_of_port < 16 && port != 0) { if (!ndpi_is_duplicate(src, port)) { src->irc_port[src->irc_number_of_port] = port; src->irc_number_of_port++; NDPI_LOG (NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "found port=%d", ntohs(get_u_int16_t(src->irc_port, 0))); NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "jjeeeeeeeeeeeeeeeeeeeeeeeee"); } src->irc_ts = packet->tick_timestamp; } else if (port != 0 && src->irc_number_of_port == 16) { if (!ndpi_is_duplicate(src, port)) { less = 0; NDPI_IRC_FIND_LESS(src->last_time_port_used, less); src->irc_port[less] = port; NDPI_LOG (NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "found port=%d", ntohs(get_u_int16_t(src->irc_port, 0))); } src->irc_ts = packet->tick_timestamp; } if (dst == NULL) { break; } } if (dst != NULL) { port = ntohs_ndpi_bytestream_to_number (&packet->line[i].ptr[j], packet->payload_packet_len - j, &j); NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_TRACE, "port %u.", port); // hier das gleiche wie oben. /* hier werden 16 ports pro irc flows mitgespeichert. könnte man denn nicht ein- * fach an die dst oder src einen flag setzten, dass dieser port für eine bestimmte * zeit ein irc-port bleibt? */ if (dst->irc_number_of_port < 16 && port != 0) { if (!ndpi_is_duplicate(dst, port)) { dst->irc_port[dst->irc_number_of_port] = port; dst->irc_number_of_port++; NDPI_LOG (NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "found port=%d", ntohs(get_u_int16_t(dst->irc_port, 0))); NDPI_LOG(NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "juuuuuuuuuuuuuuuu"); } dst->irc_ts = packet->tick_timestamp; } else if (port != 0 && dst->irc_number_of_port == 16) { if (!ndpi_is_duplicate(dst, port)) { less = 0; NDPI_IRC_FIND_LESS(dst->last_time_port_used, less); dst->irc_port[less] = port; NDPI_LOG (NDPI_PROTOCOL_IRC, ndpi_struct, NDPI_LOG_DEBUG, "found port=%d", ntohs(get_u_int16_t(dst->irc_port, 0))); } dst->irc_ts = packet->tick_timestamp; } break; } } j++; } } } } } } } } }
static void ndpi_search_xbox(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 IS TH XBOX UDP DETCTION ONLY !!! * the xbox tcp detection is done by http code */ /* this detection also works for asymmetric xbox udp traffic */ if (packet->udp != NULL) { u_int16_t dport = ntohs(packet->udp->dest); u_int16_t sport = ntohs(packet->udp->source); NDPI_LOG(NDPI_PROTOCOL_XBOX, ndpi_struct, NDPI_LOG_DEBUG, "search xbox\n"); if (packet->payload_packet_len > 12 && get_u_int32_t(packet->payload, 0) == 0 && packet->payload[5] == 0x58 && memcmp(&packet->payload[7], "\x00\x00\x00", 3) == 0) { if ((packet->payload[4] == 0x0c && packet->payload[6] == 0x76) || (packet->payload[4] == 0x02 && packet->payload[6] == 0x18) || (packet->payload[4] == 0x0b && packet->payload[6] == 0x80) || (packet->payload[4] == 0x03 && packet->payload[6] == 0x40) || (packet->payload[4] == 0x06 && packet->payload[6] == 0x4e)) { ndpi_int_xbox_add_connection(ndpi_struct, flow); NDPI_LOG(NDPI_PROTOCOL_XBOX, ndpi_struct, NDPI_LOG_DEBUG, "xbox udp connection detected\n"); return; } } if ((dport == 3074 || sport == 3074) && ((packet->payload_packet_len == 24 && packet->payload[0] == 0x00) || (packet->payload_packet_len == 42 && packet->payload[0] == 0x4f && packet->payload[2] == 0x0a) || (packet->payload_packet_len == 80 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x50bc && packet->payload[2] == 0x45) || (packet->payload_packet_len == 40 && ntohl(get_u_int32_t(packet->payload, 0)) == 0xcf5f3202) || (packet->payload_packet_len == 38 && ntohl(get_u_int32_t(packet->payload, 0)) == 0xc1457f03) || (packet->payload_packet_len == 28 && ntohl(get_u_int32_t(packet->payload, 0)) == 0x015f2c00))) { if (flow->l4.udp.xbox_stage == 1) { ndpi_int_xbox_add_connection(ndpi_struct, flow); NDPI_LOG(NDPI_PROTOCOL_XBOX, ndpi_struct, NDPI_LOG_DEBUG, "xbox udp connection detected\n"); return; } NDPI_LOG(NDPI_PROTOCOL_XBOX, ndpi_struct, NDPI_LOG_DEBUG, "maybe xbox.\n"); flow->l4.udp.xbox_stage++; return; } /* exclude here all non matched udp traffic, exclude here tcp only if http has been excluded, because xbox could use http */ if (packet->tcp == NULL #ifdef NDPI_PROTOCOL_HTTP || NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_HTTP) != 0 #endif ) { NDPI_LOG(NDPI_PROTOCOL_XBOX, ndpi_struct, NDPI_LOG_DEBUG, "xbox udp excluded.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_XBOX); } } /* to not exclude tcp traffic here, done by http code... */ }
static void ndpi_search_gadugadu_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; if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_GADUGADU) { if (src != NULL) src->gg_timeout = packet->tick_timestamp; if (dst != NULL) dst->gg_timeout = packet->tick_timestamp; if (packet->payload_packet_len == 311) { if (packet->payload[28] != 0) { if (src != NULL) { src->gg_timeout = packet->tick_timestamp; if (ntohs(packet->tcp->dest) == 8074 || ntohs(packet->tcp->dest) == 443) src->gadu_gadu_ft_direction = 0; else src->gadu_gadu_ft_direction = 1; src->gadu_gadu_voice = 0; } if (dst != NULL) { dst->gg_timeout = packet->tick_timestamp; if (ntohs(packet->tcp->dest) == 8074 || ntohs(packet->tcp->dest) == 443) dst->gadu_gadu_ft_direction = 0; else dst->gadu_gadu_ft_direction = 1; dst->gadu_gadu_voice = 0; } NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "gg filetransfer setup detected\n"); } else { if (src != NULL) { src->gadu_gadu_voice = 1; src->gg_timeout = packet->tick_timestamp; } if (dst != NULL) { dst->gadu_gadu_voice = 1; dst->gg_timeout = packet->tick_timestamp; } NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "gg voice setup detected \n"); } } return; } #ifdef NDPI_PROTOCOL_HTTP if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP) { #endif NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "Gadu-Gadu: HTTP CHECK FOUND\n"); if (packet->tcp != NULL && ntohs(packet->tcp->dest) == 80) if (check_for_http(ndpi_struct, flow)) return; #ifdef NDPI_PROTOCOL_HTTP } #endif /* the following code is implemented asymmetrically. */ if (packet->tcp != NULL && (ntohs(packet->tcp->dest) == 443 || ntohs(packet->tcp->dest) == 8074 || ntohs(packet->tcp->source) == 443 || ntohs(packet->tcp->source) == 8074)) { NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "Gadu-Gadu: found port 8074 or 443.\n"); if (flow->packet_counter <= 6) { if ((packet->payload_packet_len == 9 || packet->payload_packet_len == 12 || packet->payload_packet_len == 100 || (packet->payload_packet_len > 190 && packet->payload_packet_len < 210) ) && get_l32(packet->payload, 4) == packet->payload_packet_len - 8 && (ntohl(get_u_int32_t(packet->payload, 0)) == 0x01000000 || ntohl(get_u_int32_t(packet->payload, 0)) == 0x02000000 || ntohl(get_u_int32_t(packet->payload, 0)) == 0x03000000 || ntohl(get_u_int32_t(packet->payload, 0)) == 0x12000000 || ntohl(get_u_int32_t(packet->payload, 0)) == 0x19000000 || ntohl(get_u_int32_t(packet->payload, 0)) == 0x31000000 || ntohl(get_u_int32_t(packet->payload, 0)) == 0x35000000 || ntohl(get_u_int32_t(packet->payload, 0)) == 0x10000000 || ntohl(get_u_int32_t(packet->payload, 0)) == 0x15000000)) { flow->l4.tcp.gadugadu_stage++; NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "Gadu-Gadu: len=9,12,100,190-210, stage++.\n"); } /*detection of mirinda client .this has a different way of communicating ports */ if (packet->payload_packet_len == 114 && ntohl(get_u_int32_t(packet->payload, 0)) == 0x19000000 && get_l32(packet->payload, 4) == packet->payload_packet_len - 8) { flow->l4.tcp.gadugadu_stage++; NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "Gadu-Gadu: len=114, stage++.\n"); /* here the asymmetric implementation ends */ if (flow->l4.tcp.gadugadu_stage == 2) { if (src != NULL) { memcpy(src->gg_call_id[src->gg_next_id], &packet->payload[8], 4); NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "call id parsed %d\n", packet->payload[8]); src->gg_ft_ip_address = get_u_int32_t(packet->payload, 86); src->gg_ft_port = htons(get_u_int16_t(packet->payload, 90)); NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "mirinda file transfer port %d \n", ntohs(src->gg_ft_port)); } if (dst != NULL) { memcpy(dst->gg_call_id[dst->gg_next_id], &packet->payload[8], 4); NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "call id parsed %d\n", packet->payload[8]); dst->gg_ft_ip_address = get_u_int32_t(packet->payload, 86); dst->gg_ft_port = htons(get_u_int16_t(packet->payload, 90)); NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "mirinda file transfer port %d \n", ntohs(dst->gg_ft_port)); } } } if (flow->l4.tcp.gadugadu_stage == 2) { NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "Gadu-Gadu: add connection.\n"); ndpi_int_gadugadu_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); } return; } } /*mirinda file detection */ if (packet->tcp != NULL && src != NULL) { if (NDPI_COMPARE_PROTOCOL_TO_BITMASK (src->detected_protocol_bitmask, NDPI_PROTOCOL_GADUGADU) != 0 && ((src->gg_ft_ip_address == packet->iph->saddr && src->gg_ft_port == packet->tcp->source) || (src->gg_ft_ip_address == packet->iph->daddr && src->gg_ft_port == packet->tcp->dest))) { if ((packet->tick_timestamp - src->gg_timeout) < ndpi_struct->gadugadu_peer_connection_timeout) { ndpi_int_gadugadu_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "file transfer detected %d\n", ntohs(packet->tcp->dest)); return; } else { src->gg_ft_ip_address = 0; src->gg_ft_port = 0; } } else if (NDPI_COMPARE_PROTOCOL_TO_BITMASK (src->detected_protocol_bitmask, NDPI_PROTOCOL_GADUGADU) != 0 && (packet->tcp->dest == htons(80) || packet->tcp->source == htons(80)) && packet->payload_packet_len == 12 && (memcmp(src->gg_call_id[0], &packet->payload[5], 4) == 0 || (src->gg_call_id[1][0] && (memcmp(src->gg_call_id[1], &packet->payload[5], 4) == 0)))) { if ((packet->tick_timestamp - src->gg_timeout) < ndpi_struct->gadugadu_peer_connection_timeout) { ndpi_int_gadugadu_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "http file transfer detetced \n"); return; } else { NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "http file transfer timeout \n"); } } else if (NDPI_COMPARE_PROTOCOL_TO_BITMASK (src->detected_protocol_bitmask, NDPI_PROTOCOL_GADUGADU) != 0 && packet->payload_packet_len == 8 && (memcmp(src->gg_call_id[0], &packet->payload[0], 4) == 0 || (src->gg_call_id[1][0] && (memcmp (src->gg_call_id[1], &packet->payload[0], 4) == 0)))) { if ((packet->tick_timestamp - src->gg_timeout) < ndpi_struct->gadugadu_peer_connection_timeout) { ndpi_int_gadugadu_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "file transfer detetced %d\n", htons(packet->tcp->dest)); return; } else { NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, " file transfer timeout \n"); } } } if (packet->tcp != NULL && dst != NULL) { if (NDPI_COMPARE_PROTOCOL_TO_BITMASK (dst->detected_protocol_bitmask, NDPI_PROTOCOL_GADUGADU) != 0 && ((dst->gg_ft_ip_address == packet->iph->saddr && dst->gg_ft_port == packet->tcp->source) || (dst->gg_ft_ip_address == packet->iph->daddr && dst->gg_ft_port == packet->tcp->dest))) { if ((packet->tick_timestamp - dst->gg_timeout) < ndpi_struct->gadugadu_peer_connection_timeout) { ndpi_int_gadugadu_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "file transfer detected %d\n", ntohs(packet->tcp->dest)); return; } else { dst->gg_ft_ip_address = 0; dst->gg_ft_port = 0; } } else if (NDPI_COMPARE_PROTOCOL_TO_BITMASK (dst->detected_protocol_bitmask, NDPI_PROTOCOL_GADUGADU) != 0 && (packet->tcp->dest == htons(80) || packet->tcp->source == htons(80)) && packet->payload_packet_len == 12 && (memcmp(dst->gg_call_id[0], &packet->payload[0], 4) == 0 || (dst->gg_call_id[1][0] && (memcmp(dst->gg_call_id[1], &packet->payload[0], 4) == 0)))) { if ((packet->tick_timestamp - dst->gg_timeout) < ndpi_struct->gadugadu_peer_connection_timeout) { ndpi_int_gadugadu_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "http file transfer detetced \n"); return; } else { NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "http file transfer timeout \n"); } } else if (NDPI_COMPARE_PROTOCOL_TO_BITMASK (dst->detected_protocol_bitmask, NDPI_PROTOCOL_GADUGADU) != 0 && packet->payload_packet_len == 8 && (memcmp(dst->gg_call_id[0], &packet->payload[0], 4) == 0 || (dst->gg_call_id[1][0] && (memcmp (dst->gg_call_id[1], &packet->payload[0], 4) == 0)))) { if ((packet->tick_timestamp - dst->gg_timeout) < ndpi_struct->gadugadu_peer_connection_timeout) { ndpi_int_gadugadu_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, "file transfer detected %d\n", ntohs(packet->tcp->dest)); return; } else { NDPI_LOG(NDPI_PROTOCOL_GADUGADU, ndpi_struct, NDPI_LOG_DEBUG, " file transfer timeout \n"); } } } /** newly added start **/ if (packet->tcp != NULL && ((ntohs(packet->tcp->dest) == 80) || (ntohs(packet->tcp->source) == 80))) { if (check_for_gadugadu_payload_pattern(ndpi_struct, flow)) { return; } } NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_GADUGADU); }
static void ndpi_search_http_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; u_int16_t filename_start; NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "search http\n"); /* set client-server_direction */ if (flow->l4.tcp.http_setup_dir == 0) { NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "initializes http to stage: 1 \n"); flow->l4.tcp.http_setup_dir = 1 + packet->packet_direction; } if (NDPI_COMPARE_PROTOCOL_TO_BITMASK (ndpi_struct->generic_http_packet_bitmask, packet->detected_protocol_stack[0]) != 0) { NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "protocol might be detected earlier as http jump to payload type detection\n"); goto http_parse_detection; } if (flow->l4.tcp.http_setup_dir == 1 + packet->packet_direction) { NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "http stage: 1\n"); if (flow->l4.tcp.http_wait_for_retransmission) { if (!packet->tcp_retransmission) { if (flow->packet_counter <= 5) { NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "still waiting for retransmission\n"); return; } else { NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "retransmission not found, exclude\n"); http_bitmask_exclude(flow); return; } } } if (flow->l4.tcp.http_stage == 0) { filename_start = http_request_url_offset(ndpi_struct, flow); if (filename_start == 0) { if (packet->payload_packet_len >= 7 && memcmp(packet->payload, "HTTP/1.", 7) == 0) { NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP response found (truncated flow ?)\n"); ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); return; } NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "filename not found, exclude\n"); http_bitmask_exclude(flow); return; } // parse packet ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->parsed_lines <= 1) { /* parse one more packet .. */ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "just one line, search next packet\n"); packet->http_method.ptr = packet->line[0].ptr; packet->http_method.len = filename_start - 1; flow->l4.tcp.http_stage = 1; return; } // parsed_lines > 1 here if (packet->line[0].len >= (9 + filename_start) && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) { packet->http_url_name.ptr = &packet->payload[filename_start]; packet->http_url_name.len = packet->line[0].len - (filename_start + 9); packet->http_method.ptr = packet->line[0].ptr; packet->http_method.len = filename_start - 1; NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "http structure detected, adding\n"); ndpi_int_http_add_connection(ndpi_struct, flow, (filename_start == 8) ? NDPI_PROTOCOL_HTTP_CONNECT : NDPI_PROTOCOL_HTTP); check_content_type_and_change_protocol(ndpi_struct, flow); /* HTTP found, look for host... */ if (packet->host_line.ptr != NULL) { /* aaahh, skip this direction and wait for a server reply here */ flow->l4.tcp.http_stage = 2; NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP START HOST found\n"); return; } NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP START HOST found\n"); /* host not found, check in next packet after */ flow->l4.tcp.http_stage = 1; return; } } else if (flow->l4.tcp.http_stage == 1) { /* SECOND PAYLOAD TRAFFIC FROM CLIENT, FIRST PACKET MIGHT HAVE BEEN HTTP... */ /* UNKNOWN TRAFFIC, HERE FOR HTTP again.. */ // parse packet ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->parsed_lines <= 1) { /* wait some packets in case request is split over more than 2 packets */ if (flow->packet_counter < 5) { NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "line still not finished, search next packet\n"); return; } else { /* stop parsing here */ NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: PACKET DOES NOT HAVE A LINE STRUCTURE\n"); http_bitmask_exclude(flow); return; } } if (packet->line[0].len >= 9 && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) { ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); check_content_type_and_change_protocol(ndpi_struct, flow); NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP START HTTP found in 2. packet, check host here...\n"); /* HTTP found, look for host... */ flow->l4.tcp.http_stage = 2; return; } } } else { /* We have received a response for a previously identified partial HTTP request */ if((packet->parsed_lines == 1) && (packet->packet_direction == 1 /* server -> client */)) { /* In apache if you do "GET /\n\n" the response comes without any header so we can assume that this can be the case */ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); return; } } NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP: REQUEST NOT HTTP CONFORM\n"); http_bitmask_exclude(flow); return; http_parse_detection: if (flow->l4.tcp.http_setup_dir == 1 + packet->packet_direction) { /* we have something like http here, so check for host and content type if possible */ if (flow->l4.tcp.http_stage == 0 || flow->l4.tcp.http_stage == 3) { NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP RUN MAYBE NEXT GET/POST...\n"); // parse packet ndpi_parse_packet_line_info(ndpi_struct, flow); /* check for url here */ filename_start = http_request_url_offset(ndpi_struct, flow); if (filename_start != 0 && packet->parsed_lines > 1 && packet->line[0].len >= (9 + filename_start) && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) { packet->http_url_name.ptr = &packet->payload[filename_start]; packet->http_url_name.len = packet->line[0].len - (filename_start + 9); packet->http_method.ptr = packet->line[0].ptr; packet->http_method.len = filename_start - 1; NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "next http action, " "resetting to http and search for other protocols later.\n"); ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP); } check_content_type_and_change_protocol(ndpi_struct, flow); /* HTTP found, look for host... */ if (packet->host_line.ptr != NULL) { NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP RUN MAYBE NEXT HOST found, skipping all packets from this direction\n"); /* aaahh, skip this direction and wait for a server reply here */ flow->l4.tcp.http_stage = 2; return; } NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP RUN MAYBE NEXT HOST NOT found, scanning one more packet from this direction\n"); flow->l4.tcp.http_stage = 1; } else if (flow->l4.tcp.http_stage == 1) { // parse packet and maybe find a packet info with host ptr,... ndpi_parse_packet_line_info(ndpi_struct, flow); check_content_type_and_change_protocol(ndpi_struct, flow); NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP RUN second packet scanned\n"); /* HTTP found, look for host... */ flow->l4.tcp.http_stage = 2; } NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP skipping client packets after second packet\n"); return; } /* server response */ if (flow->l4.tcp.http_stage > 0) { /* first packet from server direction, might have a content line */ ndpi_parse_packet_line_info(ndpi_struct, flow); check_content_type_and_change_protocol(ndpi_struct, flow); if (packet->empty_line_position_set != 0 || flow->l4.tcp.http_empty_line_seen == 1) { NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "empty line. check_http_payload.\n"); check_http_payload(ndpi_struct, flow); } if (flow->l4.tcp.http_stage == 2) { flow->l4.tcp.http_stage = 3; } else { flow->l4.tcp.http_stage = 0; } NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP response first or second packet scanned,new stage is: %u\n", flow->l4.tcp.http_stage); return; } else { NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HTTP response next packet skipped\n"); } }
void ndpi_search_ftp_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; if (src != NULL && ndpi_packet_dst_ip_eql(packet, &src->ftp_ip) && packet->tcp->syn != 0 && packet->tcp->ack == 0 && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_FTP) != 0 && src->ftp_timer_set != 0) { NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "possible ftp data, src!= 0.\n"); if (((u_int32_t) (packet->tick_timestamp - src->ftp_timer)) >= ndpi_struct->ftp_connection_timeout) { src->ftp_timer_set = 0; } else if (ntohs(packet->tcp->dest) > 1024 && (ntohs(packet->tcp->source) > 1024 || ntohs(packet->tcp->source) == 20)) { NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "detected FTP data stream.\n"); ndpi_int_ftp_add_connection(ndpi_struct, flow); return; } } if (dst != NULL && ndpi_packet_src_ip_eql(packet, &dst->ftp_ip) && packet->tcp->syn != 0 && packet->tcp->ack == 0 && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_FTP) != 0 && dst->ftp_timer_set != 0) { NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "possible ftp data; dst!= 0.\n"); if (((u_int32_t) (packet->tick_timestamp - dst->ftp_timer)) >= ndpi_struct->ftp_connection_timeout) { dst->ftp_timer_set = 0; } else if (ntohs(packet->tcp->dest) > 1024 && (ntohs(packet->tcp->source) > 1024 || ntohs(packet->tcp->source) == 20)) { NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "detected FTP data stream.\n"); ndpi_int_ftp_add_connection(ndpi_struct, flow); return; } } // ftp data asymmetrically /* skip packets without payload */ if (packet->payload_packet_len == 0) { NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP test skip because of data connection or zero byte packet_payload.\n"); return; } /* skip excluded connections */ // we test for FTP connection and search for passive mode if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_FTP) { NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "detected ftp command mode. going to test data mode.\n"); search_passive_ftp_mode(ndpi_struct, flow); search_active_ftp_mode(ndpi_struct, flow); return; } if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN && search_ftp(ndpi_struct, flow) != 0) { NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "unknown. need next packet.\n"); return; } NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FTP); NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude ftp.\n"); }
/* this function searches for a rtsp-"handshake" over tcp or udp. */ void ndpi_search_rtsp_tcp_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 = flow->src; struct ndpi_id_struct *dst = flow->dst; NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "calling ndpi_search_rtsp_tcp_udp.\n"); if (flow->rtsprdt_stage == 0 #ifdef NDPI_PROTOCOL_RTCP && !(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_RTCP) #endif ) { flow->rtsprdt_stage = 1 + packet->packet_direction; NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "maybe handshake 1; need next packet, return.\n"); return; } if (flow->packet_counter < 3 && flow->rtsprdt_stage == 1 + packet->packet_direction) { NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "maybe handshake 2; need next packet.\n"); return; } if (packet->payload_packet_len > 20 && flow->rtsprdt_stage == 2 - packet->packet_direction) { // RTSP Server Message if (memcmp(packet->payload, "RTSP/1.0 ", 9) == 0) { NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "found RTSP/1.0 .\n"); if (dst != NULL) { NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "found dst.\n"); ndpi_packet_src_ip_get(packet, &dst->rtsp_ip_address); dst->rtsp_timer = packet->tick_timestamp; dst->rtsp_ts_set = 1; } if (src != NULL) { NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "found src.\n"); ndpi_packet_dst_ip_get(packet, &src->rtsp_ip_address); src->rtsp_timer = packet->tick_timestamp; src->rtsp_ts_set = 1; } NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "found RTSP.\n"); flow->rtsp_control_flow = 1; ndpi_int_rtsp_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } } if (packet->udp != NULL && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN && ((NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP) == 0) #ifdef NDPI_PROTOCOL_RTCP || (NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTCP) == 0) #endif )) { NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "maybe RTSP RTP, RTSP RTCP, RDT; need next packet.\n"); return; } NDPI_LOG(NDPI_PROTOCOL_RTSP, ndpi_struct, NDPI_LOG_DEBUG, "didn't find handshake, exclude.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTSP); return; }
void ndpi_search_meebo(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_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "search meebo.\n"); /* catch audio/video flows which are flash (rtmp) */ if ( #ifdef NDPI_CONTENT_FLASH packet->detected_protocol_stack[0] == NDPI_CONTENT_FLASH #else (packet->tcp->source == htons(1935) || packet->tcp->dest == htons(1935)) #endif ) { /* TODO: once we have an amf decoder we can more directly access the rtmp fields * if so, we may also exclude earlier */ if (packet->payload_packet_len > 900) { if (memcmp(packet->payload + 116, "tokbox/", NDPI_STATICSTRING_LEN("tokbox/")) == 0 || memcmp(packet->payload + 316, "tokbox/", NDPI_STATICSTRING_LEN("tokbox/")) == 0) { NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "found meebo/tokbox flash flow.\n"); ndpi_int_meebo_add_connection(ndpi_struct, flow); return; } } if (flow->packet_counter < 16 && flow->packet_direction_counter[flow->setup_packet_direction] < 6) { NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "need next packet.\n"); return; } NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "exclude meebo.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MEEBO); return; } if (( #ifdef NDPI_PROTOCOL_HTTP packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP || #endif ((packet->payload_packet_len > 3 && memcmp(packet->payload, "GET ", 4) == 0) || (packet->payload_packet_len > 4 && memcmp(packet->payload, "POST ", 5) == 0)) ) && flow->packet_counter == 1) { u_int8_t host_or_referer_match = 0; ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->host_line.ptr != NULL && packet->host_line.len >= 9 && memcmp(&packet->host_line.ptr[packet->host_line.len - 9], "meebo.com", 9) == 0) { NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found Meebo host\n"); host_or_referer_match = 1; } else if (packet->host_line.ptr != NULL && packet->host_line.len >= 10 && memcmp(&packet->host_line.ptr[packet->host_line.len - 10], "tokbox.com", 10) == 0) { NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found tokbox host\n"); /* set it to 2 to avoid having plain tokbox traffic detected as meebo */ host_or_referer_match = 2; } else if (packet->host_line.ptr != NULL && packet->host_line.len >= NDPI_STATICSTRING_LEN("74.114.28.110") && memcmp(&packet->host_line.ptr[packet->host_line.len - NDPI_STATICSTRING_LEN("74.114.28.110")], "74.114.28.110", NDPI_STATICSTRING_LEN("74.114.28.110")) == 0) { NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found meebo IP\n"); host_or_referer_match = 1; } else if (packet->referer_line.ptr != NULL && packet->referer_line.len >= NDPI_STATICSTRING_LEN("http://www.meebo.com/") && memcmp(packet->referer_line.ptr, "http://www.meebo.com/", NDPI_STATICSTRING_LEN("http://www.meebo.com/")) == 0) { NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found meebo referer\n"); host_or_referer_match = 1; } else if (packet->referer_line.ptr != NULL && packet->referer_line.len >= NDPI_STATICSTRING_LEN("http://mee.tokbox.com/") && memcmp(packet->referer_line.ptr, "http://mee.tokbox.com/", NDPI_STATICSTRING_LEN("http://mee.tokbox.com/")) == 0) { NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found tokbox referer\n"); host_or_referer_match = 1; } else if (packet->referer_line.ptr != NULL && packet->referer_line.len >= NDPI_STATICSTRING_LEN("http://74.114.28.110/") && memcmp(packet->referer_line.ptr, "http://74.114.28.110/", NDPI_STATICSTRING_LEN("http://74.114.28.110/")) == 0) { NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found meebo IP referer\n"); host_or_referer_match = 1; } if (host_or_referer_match) { if (host_or_referer_match == 1) { NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "Found Meebo traffic based on host/referer\n"); ndpi_int_meebo_add_connection(ndpi_struct, flow); return; } } } if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_MEEBO) { NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "in case that ssl meebo has been detected return.\n"); return; } if (flow->packet_counter < 5 && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN && NDPI_COMPARE_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SSL) == 0) { NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "ssl not yet excluded. need next packet.\n"); return; } #ifdef NDPI_CONTENT_FLASH if (flow->packet_counter < 5 && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN && !NDPI_FLOW_PROTOCOL_EXCLUDED(ndpi_struct, flow, NDPI_CONTENT_FLASH)) { NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "flash not yet excluded. need next packet.\n"); return; } #endif NDPI_LOG(NDPI_PROTOCOL_MEEBO, ndpi_struct, NDPI_LOG_DEBUG, "exclude meebo.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MEEBO); }
static void check_content_type_and_change_protocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { #ifdef NDPI_PROTOCOL_MPEG struct ndpi_packet_struct *packet = &flow->packet; #endif #ifdef NDPI_PROTOCOL_AVI #endif // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; u_int8_t a; if (packet->content_line.ptr != NULL && packet->content_line.len != 0) { NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "Content Type Line found %.*s\n", packet->content_line.len, packet->content_line.ptr); #ifdef NDPI_PROTOCOL_MPEG if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_MPEG) != 0) mpeg_parse_packet_contentline(ndpi_struct, flow); #endif #ifdef NDPI_PROTOCOL_FLASH if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_FLASH) != 0) flash_parse_packet_contentline(ndpi_struct, flow); #endif #ifdef NDPI_PROTOCOL_QUICKTIME if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_QUICKTIME) != 0) qt_parse_packet_contentline(ndpi_struct, flow); #endif #ifdef NDPI_PROTOCOL_REALMEDIA if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_REALMEDIA) != 0) realmedia_parse_packet_contentline(ndpi_struct, flow); #endif #ifdef NDPI_PROTOCOL_WINDOWSMEDIA if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_WINDOWSMEDIA) != 0) windowsmedia_parse_packet_contentline(ndpi_struct, flow); #endif #ifdef NDPI_PROTOCOL_MMS if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_MMS) != 0) mms_parse_packet_contentline(ndpi_struct, flow); #endif #ifdef NDPI_PROTOCOL_OFF if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_OFF) != 0) off_parse_packet_contentline(ndpi_struct, flow); #endif #ifdef NDPI_PROTOCOL_OGG if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_OGG) != 0) ogg_parse_packet_contentline(ndpi_struct, flow); #endif #ifdef NDPI_PROTOCOL_MOVE if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_MOVE) != 0) move_parse_packet_contentline(ndpi_struct, flow); #endif } /* check user agent here too */ if (packet->user_agent_line.ptr != NULL && packet->user_agent_line.len != 0) { NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "User Agent Type Line found %.*s\n", packet->user_agent_line.len, packet->user_agent_line.ptr); #ifdef NDPI_PROTOCOL_XBOX if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_XBOX) != 0) xbox_parse_packet_useragentline(ndpi_struct, flow); #endif #ifdef NDPI_PROTOCOL_WINDOWS_UPDATE if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_WINDOWS_UPDATE) != 0) windows_update_packet_useragentline(ndpi_struct, flow); #endif #ifdef NDPI_PROTOCOL_WINDOWSMEDIA if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_WINDOWSMEDIA) != 0) winmedia_parse_packet_useragentline(ndpi_struct, flow); #endif } /* check for host line */ if (packet->host_line.ptr != NULL) { NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HOST Line found %.*s\n", packet->host_line.len, packet->host_line.ptr); #ifdef NDPI_PROTOCOL_QQ if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_QQ) != 0) { qq_parse_packet_URL_and_hostname(ndpi_struct, flow); } #endif parseHttpSubprotocol(ndpi_struct, flow); } /* check for accept line */ if (packet->accept_line.ptr != NULL) { NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "Accept Line found %.*s\n", packet->accept_line.len, packet->accept_line.ptr); #ifdef NDPI_PROTOCOL_RTSP if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_RTSP) != 0) { rtsp_parse_packet_acceptline(ndpi_struct, flow); } #endif } /* search for line startin with "Icy-MetaData" */ #ifdef NDPI_PROTOCOL_MPEG for (a = 0; a < packet->parsed_lines; a++) { if (packet->line[a].len > 11 && memcmp(packet->line[a].ptr, "Icy-MetaData", 12) == 0) { NDPI_LOG(NDPI_PROTOCOL_MPEG, ndpi_struct, NDPI_LOG_DEBUG, "MPEG: Icy-MetaData found.\n"); ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MPEG); return; } } #ifdef NDPI_PROTOCOL_AVI #endif #endif }