static void ndpi_search_icecast_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; u_int8_t i; NDPI_LOG(NDPI_PROTOCOL_ICECAST, ndpi_struct, NDPI_LOG_DEBUG, "search icecast.\n"); if ((packet->payload_packet_len < 500 && packet->payload_packet_len >= 7 && ndpi_mem_cmp(packet->payload, "SOURCE ", 7) == 0) || flow->l4.tcp.icecast_stage) { ndpi_parse_packet_line_info_unix(ndpi_struct, flow); NDPI_LOG(NDPI_PROTOCOL_ICECAST, ndpi_struct, NDPI_LOG_DEBUG, "Icecast lines=%d\n", packet->parsed_unix_lines); for (i = 0; i < packet->parsed_unix_lines; i++) { if (packet->unix_line[i].ptr != NULL && packet->unix_line[i].len > 4 && ndpi_mem_cmp(packet->unix_line[i].ptr, "ice-", 4) == 0) { NDPI_LOG(NDPI_PROTOCOL_ICECAST, ndpi_struct, NDPI_LOG_DEBUG, "Icecast detected.\n"); ndpi_int_icecast_add_connection(ndpi_struct, flow); return; } } if (packet->parsed_unix_lines < 1 && !flow->l4.tcp.icecast_stage) { flow->l4.tcp.icecast_stage = 1; return; } } #ifdef NDPI_PROTOCOL_HTTP if (NDPI_FLOW_PROTOCOL_EXCLUDED(ndpi_struct, flow, NDPI_PROTOCOL_HTTP)) { goto icecast_exclude; } #endif if (packet->packet_direction == flow->setup_packet_direction && flow->packet_counter < 10) { return; } if (packet->packet_direction != flow->setup_packet_direction) { /* server answer, now test Server for Icecast */ ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->server_line.ptr != NULL && packet->server_line.len > NDPI_STATICSTRING_LEN("Icecast") && memcmp(packet->server_line.ptr, "Icecast", NDPI_STATICSTRING_LEN("Icecast")) == 0) { NDPI_LOG(NDPI_PROTOCOL_ICECAST, ndpi_struct, NDPI_LOG_DEBUG, "Icecast detected.\n"); /* TODO maybe store the previous protocol type as subtype? * e.g. ogg or mpeg */ ndpi_int_icecast_add_connection(ndpi_struct, flow); return; } } icecast_exclude: NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_ICECAST); NDPI_LOG(NDPI_PROTOCOL_ICECAST, ndpi_struct, NDPI_LOG_DEBUG, "Icecast excluded.\n"); }
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); }
void ndpi_search_rtp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; if (packet->udp) { ndpi_rtp_search(ndpi_struct, flow, packet->payload, packet->payload_packet_len); } else if (packet->tcp) { /* skip special packets seen at yahoo traces */ if (packet->payload_packet_len >= 20 && ntohs(get_u_int16_t(packet->payload, 2)) + 20 == packet->payload_packet_len && packet->payload[0] == 0x90 && packet->payload[1] >= 0x01 && packet->payload[1] <= 0x07) { if (flow->packet_counter == 2) flow->l4.tcp.rtp_special_packets_seen = 1; NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "skipping STUN-like, special yahoo packets with payload[0] == 0x90.\n"); return; } #ifdef NDPI_PROTOCOL_STUN /* TODO the rtp detection sometimes doesn't exclude rtp * so for TCP flows only run the detection if STUN has been * detected (or RTP is already detected) * If flows will be seen which start directly with RTP * we can remove this restriction */ if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STUN || packet->detected_protocol_stack[0] == NDPI_PROTOCOL_RTP) { /* RTP may be encapsulated in TCP packets */ if (packet->payload_packet_len >= 2 && ntohs(get_u_int16_t(packet->payload, 0)) + 2 == packet->payload_packet_len) { /* TODO there could be several RTP packets in a single TCP packet so maybe the detection could be * improved by checking only the RTP packet of given length */ ndpi_rtp_search(ndpi_struct, flow, packet->payload + 2, packet->payload_packet_len - 2); return; } } if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN && flow->l4.tcp.rtp_special_packets_seen == 1) { if (packet->payload_packet_len >= 4 && ntohl(get_u_int32_t(packet->payload, 0)) + 4 == packet->payload_packet_len) { /* TODO there could be several RTP packets in a single TCP packet so maybe the detection could be * improved by checking only the RTP packet of given length */ ndpi_rtp_search(ndpi_struct, flow, packet->payload + 4, packet->payload_packet_len - 4); return; } } if (NDPI_FLOW_PROTOCOL_EXCLUDED(ndpi_struct, flow, NDPI_PROTOCOL_STUN)) { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude rtp.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP); } else { NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "STUN not yet excluded, need next packet.\n"); } #else NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude rtp.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP); #endif } }