static void search_active_ftp_mode(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; struct ndpi_id_struct *src = flow->src; struct ndpi_id_struct *dst = flow->dst; if (packet->payload_packet_len > 5 && (ndpi_mem_cmp(packet->payload, "PORT ", 5) == 0 || ndpi_mem_cmp(packet->payload, "EPRT ", 5) == 0)) { //src->local_ftp_data_port = htons(data_port_number); if (src != NULL) { ndpi_packet_dst_ip_get(packet, &src->ftp_ip); src->ftp_timer = packet->tick_timestamp; src->ftp_timer_set = 1; NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP ACTIVE MODE FOUND, command is %.*s\n", 4, packet->payload); } if (dst != NULL) { ndpi_packet_src_ip_get(packet, &dst->ftp_ip); dst->ftp_timer = packet->tick_timestamp; dst->ftp_timer_set = 1; NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP ACTIVE MODE FOUND, command is %.*s\n", 4, packet->payload); } } return; }
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_pcanywhere(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; if (packet->udp != NULL && packet->udp->dest == htons(5632) && packet->payload_packet_len == 2 && (ndpi_mem_cmp(packet->payload, "NQ", 2) == 0 || ndpi_mem_cmp(packet->payload, "ST", 2) == 0)) { NDPI_LOG(NDPI_PROTOCOL_PCANYWHERE, ndpi_struct, NDPI_LOG_DEBUG, "PC Anywhere name or status query detected.\n"); ndpi_int_pcanywhere_add_connection(ndpi_struct, flow); return; } NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_PCANYWHERE); }
static void mms_parse_packet_contentline(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; if (packet->content_line.len >= 24 && ndpi_mem_cmp(packet->content_line.ptr, "application/x-mms-framed", 24) == 0) { NDPI_LOG(NDPI_PROTOCOL_MMS, ndpi_struct, NDPI_LOG_DEBUG, "MMS: Content-Type: application/x-mms-framed found\n"); ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MMS); } }
static void ndpi_search_applejuice_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; NDPI_LOG(NDPI_PROTOCOL_APPLEJUICE, ndpi_struct, NDPI_LOG_DEBUG, "search applejuice.\n"); if ((packet->payload_packet_len > 7) && (packet->payload[6] == 0x0d) && (packet->payload[7] == 0x0a) && (ndpi_mem_cmp(packet->payload, "ajprot", 6) == 0)) { NDPI_LOG(NDPI_PROTOCOL_APPLEJUICE, ndpi_struct, NDPI_LOG_DEBUG, "detected applejuice.\n"); ndpi_int_applejuice_add_connection(ndpi_struct, flow); return; } NDPI_LOG(NDPI_PROTOCOL_APPLEJUICE, ndpi_struct, NDPI_LOG_DEBUG, "exclude applejuice.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_APPLEJUICE); }
static void windowsmedia_parse_packet_contentline(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; if (packet->content_line.len >= 14 && ndpi_mem_cmp(packet->content_line.ptr, "video/x-ms-", 11) == 0) { if (ndpi_mem_cmp(&packet->content_line.ptr[11], "wmv", 3) == 0) { NDPI_LOG(NDPI_PROTOCOL_WINDOWSMEDIA, ndpi_struct, NDPI_LOG_DEBUG, "WINDOWSMEDIA: Content-Type: video/x-ms-wmv found.\n"); ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_WINDOWSMEDIA); return; } if (ndpi_mem_cmp(&packet->content_line.ptr[11], "asf", 3) == 0) { NDPI_LOG(NDPI_PROTOCOL_WINDOWSMEDIA, ndpi_struct, NDPI_LOG_DEBUG, "WINDOWSMEDIA: Content-Type: video/x-ms-asf found.\n"); ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_WINDOWSMEDIA); return; } if (ndpi_mem_cmp(&packet->content_line.ptr[11], "asx", 3) == 0) { NDPI_LOG(NDPI_PROTOCOL_WINDOWSMEDIA, ndpi_struct, NDPI_LOG_DEBUG, "WINDOWSMEDIA: Content-Type: video/x-ms-asx found.\n"); ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_WINDOWSMEDIA); return; } } if (packet->content_line.len >= 24 && ndpi_mem_cmp(packet->content_line.ptr, "video/x-msvideo", 15) == 0) { NDPI_LOG(NDPI_PROTOCOL_WINDOWSMEDIA, ndpi_struct, NDPI_LOG_DEBUG, "WINDOWSMEDIA: Content-Type: video/x-msvideo found.\n"); ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_WINDOWSMEDIA); return; } if (packet->content_line.len >= 24 && ndpi_mem_cmp(packet->content_line.ptr, "audio/x-wav", 11) == 0) { NDPI_LOG(NDPI_PROTOCOL_WINDOWSMEDIA, ndpi_struct, NDPI_LOG_DEBUG, "WINDOWSMEDIA: Content-Type: audio/x-wav found.\n"); ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_WINDOWSMEDIA); return; } if (packet->content_line.len >= 32 && ndpi_mem_cmp(packet->content_line.ptr, "application/vnd.ms.wms-hdr.asfv1", 32) == 0) { NDPI_LOG(NDPI_PROTOCOL_WINDOWSMEDIA, ndpi_struct, NDPI_LOG_DEBUG, "WINDOWSMEDIA: Content-Type: application/vnd.ms.wms-hdr.asfv1 found.\n"); ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_WINDOWSMEDIA); return; } }
static void ndpi_search_openft_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; if (packet->payload_packet_len > 5 && memcmp(packet->payload, "GET /", 5) == 0) { NDPI_LOG(NDPI_PROTOCOL_OPENFT, ndpi_struct, NDPI_LOG_DEBUG, "HTTP packet detected.\n"); ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->parsed_lines >= 2 && packet->line[1].len > 13 && ndpi_mem_cmp(packet->line[1].ptr, "X-OpenftAlias:", 14) == 0) { NDPI_LOG(NDPI_PROTOCOL_OPENFT, ndpi_struct, NDPI_LOG_DEBUG, "OpenFT detected.\n"); ndpi_int_openft_add_connection(ndpi_struct, flow); return; } } NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OPENFT); }
static void search_passive_ftp_mode(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; struct ndpi_id_struct *dst = flow->dst; struct ndpi_id_struct *src = flow->src; u_int16_t plen; u_int8_t i; u_int32_t ftp_ip; // TODO check if normal passive mode also needs adaption for ipv6 if (packet->payload_packet_len > 3 && ndpi_mem_cmp(packet->payload, "227 ", 4) == 0) { NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP passive mode initial string\n"); plen = 4; //=4 for "227 " while (1) { if (plen >= packet->payload_packet_len) { NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "plen >= packet->payload_packet_len, return\n"); return; } if (packet->payload[plen] == '(') { NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "found (. break.\n"); break; } /* if (!isalnum(packet->payload[plen])) { NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "no alpha numeric symbol --> break.\n"); return; } */ plen++; } plen++; if (plen >= packet->payload_packet_len) return; ftp_ip = 0; for (i = 0; i < 4; i++) { u_int16_t oldplen = plen; ftp_ip = (ftp_ip << 8) + ndpi_bytestream_to_number(&packet->payload[plen], packet->payload_packet_len - plen, &plen); if (oldplen == plen || plen >= packet->payload_packet_len) { NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP passive mode %u value parse failed\n", i); return; } if (packet->payload[plen] != ',') { NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP passive mode %u value parse failed, char ',' is missing\n", i); return; } plen++; NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP passive mode %u value parsed, ip is now: %u\n", i, ftp_ip); } if (dst != NULL) { dst->ftp_ip.ipv4 = htonl(ftp_ip); dst->ftp_timer = packet->tick_timestamp; dst->ftp_timer_set = 1; NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "saved ftp_ip, ftp_timer, ftp_timer_set to dst"); NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP PASSIVE MODE FOUND: use Server %s\n", ndpi_get_ip_string(ndpi_struct, &dst->ftp_ip)); } if (src != NULL) { src->ftp_ip.ipv4 = packet->iph->daddr; src->ftp_timer = packet->tick_timestamp; src->ftp_timer_set = 1; NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "saved ftp_ip, ftp_timer, ftp_timer_set to src"); NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP PASSIVE MODE FOUND: use Server %s\n", ndpi_get_ip_string(ndpi_struct, &src->ftp_ip)); } return; } if (packet->payload_packet_len > 34 && ndpi_mem_cmp(packet->payload, "229 Entering Extended Passive Mode", 34) == 0) { if (dst != NULL) { ndpi_packet_src_ip_get(packet, &dst->ftp_ip); dst->ftp_timer = packet->tick_timestamp; dst->ftp_timer_set = 1; NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "saved ftp_ip, ftp_timer, ftp_timer_set to dst"); NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP Extended PASSIVE MODE FOUND: use Server %s\n", ndpi_get_ip_string(ndpi_struct, &dst->ftp_ip)); } if (src != NULL) { ndpi_packet_dst_ip_get(packet, &src->ftp_ip); src->ftp_timer = packet->tick_timestamp; src->ftp_timer_set = 1; NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "saved ftp_ip, ftp_timer, ftp_timer_set to src"); NDPI_LOG(NDPI_PROTOCOL_FTP, ndpi_struct, NDPI_LOG_DEBUG, "FTP Extended PASSIVE MODE FOUND: use Server %s\n", ndpi_get_ip_string(ndpi_struct, &src->ftp_ip)); } return; } }
static void ndpi_search_shoutcast_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "search shoutcast.\n"); if (flow->packet_counter == 1) { /* this case in paul_upload_oddcast_002.pcap */ if (packet->payload_packet_len >= 6 && packet->payload_packet_len < 80 && memcmp(packet->payload, "123456", 6) == 0) { NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast stage 1, \"123456\".\n"); return; } if (flow->packet_counter < 3 #ifdef NDPI_PROTOCOL_HTTP && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP #endif ) { NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "http detected, need next packet for shoutcast detection.\n"); if (packet->payload_packet_len > 4 && get_u_int32_t(packet->payload, packet->payload_packet_len - 4) != htonl(0x0d0a0d0a)) { NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "segmented packet found.\n"); flow->l4.tcp.shoutcast_stage = 1 + packet->packet_direction; } return; } /* else goto exclude_shoutcast; */ } /* evtl. für asym detection noch User-Agent:Winamp dazunehmen. */ if (packet->payload_packet_len > 11 && memcmp(packet->payload, "ICY 200 OK\x0d\x0a", 12) == 0) { NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "found shoutcast by ICY 200 OK.\n"); ndpi_int_shoutcast_add_connection(ndpi_struct, flow); return; } if (flow->l4.tcp.shoutcast_stage == 1 + packet->packet_direction && flow->packet_direction_counter[packet->packet_direction] < 5) { return; } if (flow->packet_counter == 2) { if (packet->payload_packet_len == 2 && memcmp(packet->payload, "\x0d\x0a", 2) == 0) { NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast stage 1 continuation.\n"); return; } else if (packet->payload_packet_len > 3 && ndpi_mem_cmp(&packet->payload[0], "OK2", 3) == 0) { NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast stage 2, OK2 found.\n"); return; } else goto exclude_shoutcast; } else if (flow->packet_counter == 3 || flow->packet_counter == 4) { if (packet->payload_packet_len > 3 && ndpi_mem_cmp(&packet->payload[0], "OK2", 3) == 0) { NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast stage 2, OK2 found.\n"); return; } else if (packet->payload_packet_len > 4 && ndpi_mem_cmp(&packet->payload[0], "icy-", 4) == 0) { NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast detected.\n"); ndpi_int_shoutcast_add_connection(ndpi_struct, flow); return; } else goto exclude_shoutcast; } exclude_shoutcast: NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SHOUTCAST); NDPI_LOG(NDPI_PROTOCOL_SHOUTCAST, ndpi_struct, NDPI_LOG_DEBUG, "Shoutcast excluded.\n"); }
void ndpi_search_ipp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; u_int8_t i; NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "search ipp\n"); if (packet->payload_packet_len > 20) { NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "searching for a payload with a pattern like 'number(1to8)blanknumber(1to3)ipp://.\n"); /* this pattern means that there is a printer saying that his state is idle, * means that he is not printing anything at the moment */ i = 0; if (packet->payload[i] < '0' || packet->payload[i] > '9') { NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "payload does not begin with a number.\n"); goto search_for_next_pattern; } for (;;) { i++; if (!((packet->payload[i] >= '0' && packet->payload[i] <= '9') || (packet->payload[i] >= 'a' && packet->payload[i] <= 'f') || (packet->payload[i] >= 'A' && packet->payload[i] <= 'F')) || i > 8) { NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "read symbols while the symbol is a number.\n"); break; } } if (packet->payload[i++] != ' ') { NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "there is no blank following the number.\n"); goto search_for_next_pattern; } if (packet->payload[i] < '0' || packet->payload[i] > '9') { NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "no number following the blank.\n"); goto search_for_next_pattern; } for (;;) { i++; if (packet->payload[i] < '0' || packet->payload[i] > '9' || i > 12) { NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "read symbols while the symbol is a number.\n"); break; } } if (ndpi_mem_cmp(&packet->payload[i], " ipp://", 7) != 0) { NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "the string ' ipp://' does not follow.\n"); goto search_for_next_pattern; } NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "found ipp\n"); ndpi_int_ipp_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } search_for_next_pattern: if (packet->payload_packet_len > 3 && memcmp(packet->payload, "POST", 4) == 0) { ndpi_parse_packet_line_info(ndpi_struct, flow); if (packet->content_line.ptr != NULL && packet->content_line.len > 14 && memcmp(packet->content_line.ptr, "application/ipp", 15) == 0) { NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "found ipp via POST ... application/ipp.\n"); ndpi_int_ipp_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } NDPI_LOG(NDPI_PROTOCOL_IPP, ndpi_struct, NDPI_LOG_DEBUG, "no ipp detected.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_IPP); }
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 && ndpi_mem_cmp(packet->line[1].ptr, "Connection: Close", 17) == 0 && packet->line[2].len >= 6 && ndpi_mem_cmp(packet->line[2].ptr, "Host: ", 6) == 0 && packet->line[3].len >= 16 && ndpi_mem_cmp(packet->line[3].ptr, "Content-Length: ", 16) == 0 && packet->line[4].len >= 23 && ndpi_mem_cmp(packet->line[4].ptr, "User-Agent: Mozilla/5.0", 23) == 0 && packet->line[5].len >= 23 && ndpi_mem_cmp(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 && ndpi_mem_cmp(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 && ndpi_mem_cmp(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_unix(ndpi_struct, flow); if (packet->parsed_unix_lines >= 9) { if (packet->unix_line[4].ptr != NULL && packet->unix_line[4].len >= 9 && packet->unix_line[8].ptr != NULL && packet->unix_line[8].len >= 6 && memcmp(packet->unix_line[4].ptr, "<Session ", 9) == 0 && memcmp(packet->unix_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); }
void ndpi_search_syslog(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; // struct ndpi_id_struct *src=ndpi_struct->src; // struct ndpi_id_struct *dst=ndpi_struct->dst; u_int8_t i; NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "search syslog\n"); if (packet->payload_packet_len > 20 && packet->payload_packet_len <= 1024 && packet->payload[0] == '<') { NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "checked len>20 and <1024 and first symbol=<.\n"); i = 1; for (;;) { if (packet->payload[i] < '0' || packet->payload[i] > '9' || i++ > 3) { NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "read symbols while the symbol is a number.\n"); break; } } if (packet->payload[i++] != '>') { NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "there is no > following the number.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SYSLOG); return; } else { NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "a > following the number.\n"); } if (packet->payload[i] == 0x20) { NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "a blank following the >: increment i.\n"); i++; } else { NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "no blank following the >: do nothing.\n"); } /* check for "last message repeated" */ if (i + sizeof("last message") - 1 <= packet->payload_packet_len && memcmp(packet->payload + i, "last message", sizeof("last message") - 1) == 0) { NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "found syslog by 'last message' string.\n"); ndpi_int_syslog_add_connection(ndpi_struct, flow); return; } else if (i + sizeof("snort: ") - 1 <= packet->payload_packet_len && memcmp(packet->payload + i, "snort: ", sizeof("snort: ") - 1) == 0) { /* snort events */ NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "found syslog by 'snort: ' string.\n"); ndpi_int_syslog_add_connection(ndpi_struct, flow); return; } if (ndpi_mem_cmp(&packet->payload[i], "Jan", 3) != 0 && ndpi_mem_cmp(&packet->payload[i], "Feb", 3) != 0 && ndpi_mem_cmp(&packet->payload[i], "Mar", 3) != 0 && ndpi_mem_cmp(&packet->payload[i], "Apr", 3) != 0 && ndpi_mem_cmp(&packet->payload[i], "May", 3) != 0 && ndpi_mem_cmp(&packet->payload[i], "Jun", 3) != 0 && ndpi_mem_cmp(&packet->payload[i], "Jul", 3) != 0 && ndpi_mem_cmp(&packet->payload[i], "Aug", 3) != 0 && ndpi_mem_cmp(&packet->payload[i], "Sep", 3) != 0 && ndpi_mem_cmp(&packet->payload[i], "Oct", 3) != 0 && ndpi_mem_cmp(&packet->payload[i], "Nov", 3) != 0 && ndpi_mem_cmp(&packet->payload[i], "Dec", 3) != 0) { NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "no month-shortname following: syslog excluded.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SYSLOG); return; } else { NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "a month-shortname following: syslog detected.\n"); ndpi_int_syslog_add_connection(ndpi_struct, flow); return; } } NDPI_LOG(NDPI_PROTOCOL_SYSLOG, ndpi_struct, NDPI_LOG_DEBUG, "no syslog detected.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SYSLOG); }
static u_int8_t ndpi_int_search_bittorrent_tcp_zero(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 a = 0; if (packet->payload_packet_len == 1 && packet->payload[0] == 0x13) { /* reset stage back to 0 so we will see the next packet here too */ flow->bittorrent_stage = 0; return 0; } if (flow->packet_counter == 2 && packet->payload_packet_len > 20) { if (memcmp(&packet->payload[0], "BitTorrent protocol", 19) == 0) { NDPI_LOG_BITTORRENT(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n"); ndpi_add_connection_as_bittorrent(ndpi_struct, flow, NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION, NDPI_REAL_PROTOCOL); return 1; } } if (packet->payload_packet_len > 20) { /* test for match 0x13+"BitTorrent protocol" */ if (packet->payload[0] == 0x13) { if (memcmp(&packet->payload[1], "BitTorrent protocol", 19) == 0) { NDPI_LOG_BITTORRENT(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n"); ndpi_add_connection_as_bittorrent(ndpi_struct, flow, NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION, NDPI_REAL_PROTOCOL); return 1; } } } if (packet->payload_packet_len > 23 && memcmp(packet->payload, "GET /webseed?info_hash=", 23) == 0) { NDPI_LOG_BITTORRENT(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "BT: plain webseed BitTorrent protocol detected\n"); ndpi_add_connection_as_bittorrent(ndpi_struct, flow, NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION, NDPI_CORRELATED_PROTOCOL); return 1; } /* seen Azureus as server for webseed, possibly other servers existing, to implement */ /* is Server: hypertracker Bittorrent? */ /* no asymmetric detection possible for answer of pattern "GET /data?fid=". */ if (packet->payload_packet_len > 60 && memcmp(packet->payload, "GET /data?fid=", 14) == 0 && memcmp(&packet->payload[54], "&size=", 6) == 0) { NDPI_LOG_BITTORRENT(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "BT: plain Bitcomet persistent seed protocol detected\n"); ndpi_add_connection_as_bittorrent(ndpi_struct, flow, NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION, NDPI_CORRELATED_PROTOCOL); return 1; } if (packet->payload_packet_len > 90 && (memcmp(packet->payload, "GET ", 4) == 0 || memcmp(packet->payload, "POST ", 5) == 0)) { const u_int8_t *ptr = &packet->payload[4]; u_int16_t len = packet->payload_packet_len - 4; a = 0; /* parse complete get packet here into line structure elements */ ndpi_parse_packet_line_info(ndpi_struct, flow); /* answer to this pattern is HTTP....Server: hypertracker */ if (packet->user_agent_line.ptr != NULL && ((packet->user_agent_line.len > 8 && memcmp(packet->user_agent_line.ptr, "Azureus ", 8) == 0) || (packet->user_agent_line.len >= 10 && memcmp(packet->user_agent_line.ptr, "BitTorrent", 10) == 0) || (packet->user_agent_line.len >= 11 && memcmp(packet->user_agent_line.ptr, "BTWebClient", 11) == 0))) { NDPI_LOG_BITTORRENT(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "Azureus /Bittorrent user agent line detected\n"); ndpi_add_connection_as_bittorrent(ndpi_struct, flow, NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION, NDPI_CORRELATED_PROTOCOL); return 1; } if (packet->user_agent_line.ptr != NULL && (packet->user_agent_line.len >= 9 && memcmp(packet->user_agent_line.ptr, "Shareaza ", 9) == 0) && (packet->parsed_lines > 8 && packet->line[8].ptr != 0 && packet->line[8].len >= 9 && memcmp(packet->line[8].ptr, "X-Queue: ", 9) == 0)) { NDPI_LOG_BITTORRENT(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "Bittorrent Shareaza detected.\n"); ndpi_add_connection_as_bittorrent(ndpi_struct, flow, NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION, NDPI_CORRELATED_PROTOCOL); return 1; } /* this is a self built client, not possible to catch asymmetrically */ if ((packet->parsed_lines == 10 || (packet->parsed_lines == 11 && packet->line[11].len == 0)) && packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > 12 && ndpi_mem_cmp(packet->user_agent_line.ptr, "Mozilla/4.0 ", 12) == 0 && packet->host_line.ptr != NULL && packet->host_line.len >= 7 && packet->line[2].ptr != NULL && packet->line[2].len > 14 && ndpi_mem_cmp(packet->line[2].ptr, "Keep-Alive: 300", 15) == 0 && packet->line[3].ptr != NULL && packet->line[3].len > 21 && ndpi_mem_cmp(packet->line[3].ptr, "Connection: Keep-alive", 22) == 0 && packet->line[4].ptr != NULL && packet->line[4].len > 10 && (ndpi_mem_cmp(packet->line[4].ptr, "Accpet: */*", 11) == 0 || ndpi_mem_cmp(packet->line[4].ptr, "Accept: */*", 11) == 0) && packet->line[5].ptr != NULL && packet->line[5].len > 12 && ndpi_mem_cmp(packet->line[5].ptr, "Range: bytes=", 13) == 0 && packet->line[7].ptr != NULL && packet->line[7].len > 15 && ndpi_mem_cmp(packet->line[7].ptr, "Pragma: no-cache", 16) == 0 && packet->line[8].ptr != NULL && packet->line[8].len > 22 && ndpi_mem_cmp(packet->line[8].ptr, "Cache-Control: no-cache", 23) == 0) { NDPI_LOG_BITTORRENT(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "Bitcomet LTS detected\n"); ndpi_add_connection_as_bittorrent(ndpi_struct, flow, NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION, NDPI_CORRELATED_PROTOCOL); return 1; } /* FlashGet pattern */ if (packet->parsed_lines == 8 && packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > (sizeof("Mozilla/4.0 (compatible; MSIE 6.0;") - 1) && memcmp(packet->user_agent_line.ptr, "Mozilla/4.0 (compatible; MSIE 6.0;", sizeof("Mozilla/4.0 (compatible; MSIE 6.0;") - 1) == 0 && packet->host_line.ptr != NULL && packet->host_line.len >= 7 && packet->line[2].ptr != NULL && packet->line[2].len == 11 && memcmp(packet->line[2].ptr, "Accept: */*", 11) == 0 && packet->line[3].ptr != NULL && packet->line[3].len >= (sizeof("Referer: ") - 1) && ndpi_mem_cmp(packet->line[3].ptr, "Referer: ", sizeof("Referer: ") - 1) == 0 && packet->line[5].ptr != NULL && packet->line[5].len > 13 && ndpi_mem_cmp(packet->line[5].ptr, "Range: bytes=", 13) == 0 && packet->line[6].ptr != NULL && packet->line[6].len > 21 && ndpi_mem_cmp(packet->line[6].ptr, "Connection: Keep-Alive", 22) == 0) { NDPI_LOG_BITTORRENT(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "FlashGet detected\n"); ndpi_add_connection_as_bittorrent(ndpi_struct, flow, NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION, NDPI_CORRELATED_PROTOCOL); return 1; } if (packet->parsed_lines == 7 && packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > (sizeof("Mozilla/4.0 (compatible; MSIE 6.0;") - 1) && memcmp(packet->user_agent_line.ptr, "Mozilla/4.0 (compatible; MSIE 6.0;", sizeof("Mozilla/4.0 (compatible; MSIE 6.0;") - 1) == 0 && packet->host_line.ptr != NULL && packet->host_line.len >= 7 && packet->line[2].ptr != NULL && packet->line[2].len == 11 && memcmp(packet->line[2].ptr, "Accept: */*", 11) == 0 && packet->line[3].ptr != NULL && packet->line[3].len >= (sizeof("Referer: ") - 1) && ndpi_mem_cmp(packet->line[3].ptr, "Referer: ", sizeof("Referer: ") - 1) == 0 && packet->line[5].ptr != NULL && packet->line[5].len > 21 && ndpi_mem_cmp(packet->line[5].ptr, "Connection: Keep-Alive", 22) == 0) { NDPI_LOG_BITTORRENT(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "FlashGet detected\n"); ndpi_add_connection_as_bittorrent(ndpi_struct, flow, NDPI_PROTOCOL_UNSAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION, NDPI_CORRELATED_PROTOCOL); return 1; } /* answer to this pattern is not possible to implement asymmetrically */ while (1) { if (len < 50 || ptr[0] == 0x0d) { goto ndpi_end_bt_tracker_check; } if (memcmp(ptr, "info_hash=", 10) == 0) { break; } len--; ptr++; } NDPI_LOG_BITTORRENT(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, " BT stat: tracker info hash found\n"); /* len is > 50, so save operation here */ len -= 10; ptr += 10; /* parse bt hash */ for (a = 0; a < 20; a++) { if (len < 3) { goto ndpi_end_bt_tracker_check; } if (*ptr == '%') { u_int8_t x1 = 0xFF; u_int8_t x2 = 0xFF; if (ptr[1] >= '0' && ptr[1] <= '9') { x1 = ptr[1] - '0'; } if (ptr[1] >= 'a' && ptr[1] <= 'f') { x1 = 10 + ptr[1] - 'a'; } if (ptr[1] >= 'A' && ptr[1] <= 'F') { x1 = 10 + ptr[1] - 'A'; } if (ptr[2] >= '0' && ptr[2] <= '9') { x2 = ptr[2] - '0'; } if (ptr[2] >= 'a' && ptr[2] <= 'f') { x2 = 10 + ptr[2] - 'a'; } if (ptr[2] >= 'A' && ptr[2] <= 'F') { x2 = 10 + ptr[2] - 'A'; } if (x1 == 0xFF || x2 == 0xFF) { goto ndpi_end_bt_tracker_check; } ptr += 3; len -= 3; } else if (*ptr >= 32 && *ptr < 127) { ptr++; len--; } else { goto ndpi_end_bt_tracker_check; } } NDPI_LOG_BITTORRENT(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, " BT stat: tracker info hash parsed\n"); ndpi_add_connection_as_bittorrent(ndpi_struct, flow, NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION, NDPI_CORRELATED_PROTOCOL); return 1; } ndpi_end_bt_tracker_check: if (packet->payload_packet_len == 80) { /* Warez 80 Bytes Packet * +----------------+---------------+-----------------+-----------------+ * |20 BytesPattern | 32 Bytes Value| 12 BytesPattern | 16 Bytes Data | * +----------------+---------------+-----------------+-----------------+ * 20 BytesPattern : 4c 00 00 00 ff ff ff ff 57 00 00 00 00 00 00 00 20 00 00 00 * 12 BytesPattern : 28 23 00 00 01 00 00 00 10 00 00 00 * */ static const char pattern_20_bytes[20] = { 0x4c, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00 }; static const char pattern_12_bytes[12] = { 0x28, 0x23, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00 }; /* did not see this pattern anywhere */ if ((memcmp(&packet->payload[0], pattern_20_bytes, 20) == 0) && (memcmp(&packet->payload[52], pattern_12_bytes, 12) == 0)) { NDPI_LOG_BITTORRENT(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "BT: Warez - Plain BitTorrent protocol detected\n"); ndpi_add_connection_as_bittorrent(ndpi_struct, flow, NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION, NDPI_REAL_PROTOCOL); return 1; } } else if (packet->payload_packet_len > 50) { if (memcmp(packet->payload, "GET", 3) == 0) { ndpi_parse_packet_line_info(ndpi_struct, flow); /* haven't fount this pattern anywhere */ if (packet->host_line.ptr != NULL && packet->host_line.len >= 9 && memcmp(packet->host_line.ptr, "ip2p.com:", 9) == 0) { NDPI_LOG_BITTORRENT(NDPI_PROTOCOL_BITTORRENT, ndpi_struct, NDPI_LOG_TRACE, "BT: Warez - Plain BitTorrent protocol detected due to Host: ip2p.com: pattern\n"); ndpi_add_connection_as_bittorrent(ndpi_struct, flow, NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_WEBSEED_DETECTION, NDPI_CORRELATED_PROTOCOL); return 1; } } } return 0; }
static void ndpi_search_zattoo(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 i; if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_ZATTOO) { if (src != NULL && ((u_int32_t) (packet->tick_timestamp - src->zattoo_ts) < ndpi_struct->zattoo_connection_timeout)) { src->zattoo_ts = packet->tick_timestamp; } if (dst != NULL && ((u_int32_t) (packet->tick_timestamp - dst->zattoo_ts) < ndpi_struct->zattoo_connection_timeout)) { dst->zattoo_ts = packet->tick_timestamp; } return; } if (packet->tcp != NULL) { if (packet->payload_packet_len > 50 && memcmp(packet->payload, "GET /frontdoor/fd?brand=Zattoo&v=", 33) == 0) { NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "add connection over tcp with pattern GET /frontdoor/fd?brand=Zattoo&v=\n"); ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } if (packet->payload_packet_len > 50 && memcmp(packet->payload, "GET /ZattooAdRedirect/redirect.jsp?user="******"add connection over tcp with pattern GET /ZattooAdRedirect/redirect.jsp?user=\n"); ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } if (packet->payload_packet_len > 50 && (memcmp(packet->payload, "POST /channelserver/player/channel/update HTTP/1.1", 50) == 0 || memcmp(packet->payload, "GET /epg/query", 14) == 0)) { ndpi_parse_packet_line_info(ndpi_struct, flow); for (i = 0; i < packet->parsed_lines; i++) { if (packet->line[i].len >= 18 && (ndpi_mem_cmp(packet->line[i].ptr, "User-Agent: Zattoo", 18) == 0)) { NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "add connection over tcp with pattern POST /channelserver/player/channel/update HTTP/1.1\n"); ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } } else if (packet->payload_packet_len > 50 && (memcmp(packet->payload, "GET /", 5) == 0 || memcmp(packet->payload, "POST /", NDPI_STATICSTRING_LEN("POST /")) == 0)) { /* TODO to avoid searching currently only a specific length and offset is used * that might be changed later */ ndpi_parse_packet_line_info(ndpi_struct, flow); if (ndpi_int_zattoo_user_agent_set(ndpi_struct, flow)) { ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } else if (packet->payload_packet_len > 50 && memcmp(packet->payload, "POST http://", 12) == 0) { ndpi_parse_packet_line_info(ndpi_struct, flow); // test for unique character of the zattoo header if (packet->parsed_lines == 4 && packet->host_line.ptr != NULL) { u_int32_t ip; u_int16_t bytes_read = 0; ip = ndpi_bytestream_to_ipv4(&packet->payload[12], packet->payload_packet_len, &bytes_read); // and now test the firt 5 bytes of the payload for zattoo pattern if (ip == packet->iph->daddr && packet->empty_line_position_set != 0 && ((packet->payload_packet_len - packet->empty_line_position) > 10) && packet->payload[packet->empty_line_position + 2] == 0x03 && packet->payload[packet->empty_line_position + 3] == 0x04 && packet->payload[packet->empty_line_position + 4] == 0x00 && packet->payload[packet->empty_line_position + 5] == 0x04 && packet->payload[packet->empty_line_position + 6] == 0x0a && packet->payload[packet->empty_line_position + 7] == 0x00) { NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "add connection over tcp with pattern POST http://\n"); ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } } } else if (flow->zattoo_stage == 0) { if (packet->payload_packet_len > 50 && packet->payload[0] == 0x03 && packet->payload[1] == 0x04 && packet->payload[2] == 0x00 && packet->payload[3] == 0x04 && packet->payload[4] == 0x0a && packet->payload[5] == 0x00) { flow->zattoo_stage = 1 + packet->packet_direction; NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "need next packet, seen pattern 0x030400040a00\n"); return; } /* the following is is searching for flash, not for zattoo. cust1 wants to do so. */ } else if (flow->zattoo_stage == 2 - packet->packet_direction && packet->payload_packet_len > 50 && packet->payload[0] == 0x03 && packet->payload[1] == 0x04) { NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "add connection over tcp with 0x0304.\n"); ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } else if (flow->zattoo_stage == 1 + packet->packet_direction) { if (packet->payload_packet_len > 500 && packet->payload[0] == 0x00 && packet->payload[1] == 0x00) { flow->zattoo_stage = 3 + packet->packet_direction; NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "need next packet, seen pattern 0x0000\n"); return; } if (packet->payload_packet_len > 50 && packet->payload[0] == 0x03 && packet->payload[1] == 0x04 && packet->payload[2] == 0x00 && packet->payload[3] == 0x04 && packet->payload[4] == 0x0a && packet->payload[5] == 0x00) { } NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "need next packet, seen pattern 0x030400040a00\n"); return; } else if (flow->zattoo_stage == 4 - packet->packet_direction && packet->payload_packet_len > 50 && packet->payload[0] == 0x03 && packet->payload[1] == 0x04) { NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "add connection over tcp with 0x0304.\n"); ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } else if (flow->zattoo_stage == 5 + packet->packet_direction && (packet->payload_packet_len == 125)) { NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "detected zattoo.\n"); ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } else if (flow->zattoo_stage == 6 - packet->packet_direction && packet->payload_packet_len == 1412) { NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "found zattoo.\n"); ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL); return; } NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "ZATTOO: discarted the flow (TCP): packet_size: %u; Flowstage: %u\n", packet->payload_packet_len, flow->zattoo_stage); } else if (packet->udp != NULL) { if (packet->payload_packet_len > 20 && (packet->udp->dest == htons(5003) || packet->udp->source == htons(5003)) && (get_u_int16_t(packet->payload, 0) == htons(0x037a) || get_u_int16_t(packet->payload, 0) == htons(0x0378) || get_u_int16_t(packet->payload, 0) == htons(0x0305) || get_u_int32_t(packet->payload, 0) == htonl(0x03040004) || get_u_int32_t(packet->payload, 0) == htonl(0x03010005))) { if (++flow->zattoo_stage == 2) { NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "add connection over udp.\n"); ndpi_int_zattoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "need next packet udp.\n"); return; } NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "ZATTOO: discarded the flow (UDP): packet_size: %u; Flowstage: %u\n", packet->payload_packet_len, flow->zattoo_stage); } NDPI_LOG(NDPI_PROTOCOL_ZATTOO, ndpi_struct, NDPI_LOG_DEBUG, "exclude zattoo.\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_ZATTOO); }