void ipoque_search_icecast_tcp(struct ipoque_detection_module_struct *ipoque_struct) { struct ipoque_packet_struct *packet = &ipoque_struct->packet; struct ipoque_flow_struct *flow = ipoque_struct->flow; u8 i; IPQ_LOG(IPOQUE_PROTOCOL_ICECAST, ipoque_struct, IPQ_LOG_DEBUG, "search icecast.\n"); if ((packet->payload_packet_len < 500 && packet->payload_packet_len >= 7 && ipq_mem_cmp(packet->payload, "SOURCE ", 7) == 0) || flow->l4.tcp.icecast_stage) { ipq_parse_packet_line_info_unix(ipoque_struct); IPQ_LOG(IPOQUE_PROTOCOL_ICECAST, ipoque_struct, IPQ_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 && ipq_mem_cmp(packet->unix_line[i].ptr, "ice-", 4) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_ICECAST, ipoque_struct, IPQ_LOG_DEBUG, "Icecast detected.\n"); ipoque_int_icecast_add_connection(ipoque_struct); return; } } if (packet->parsed_unix_lines < 1 && !flow->l4.tcp.icecast_stage) { flow->l4.tcp.icecast_stage = 1; return; } } #ifdef IPOQUE_PROTOCOL_HTTP if (IPQ_FLOW_PROTOCOL_EXCLUDED(ipoque_struct, flow, IPOQUE_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 */ ipq_parse_packet_line_info(ipoque_struct); if (packet->server_line.ptr != NULL && packet->server_line.len > IPQ_STATICSTRING_LEN("Icecast") && memcmp(packet->server_line.ptr, "Icecast", IPQ_STATICSTRING_LEN("Icecast")) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_ICECAST, ipoque_struct, IPQ_LOG_DEBUG, "Icecast detected.\n"); /* TODO maybe store the previous protocol type as subtype? * e.g. ogg or mpeg */ ipoque_int_icecast_add_connection(ipoque_struct); return; } } icecast_exclude: IPOQUE_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, IPOQUE_PROTOCOL_ICECAST); IPQ_LOG(IPOQUE_PROTOCOL_ICECAST, ipoque_struct, IPQ_LOG_DEBUG, "Icecast excluded.\n"); }
u8 search_manolito_tcp(struct ipoque_detection_module_struct *ipoque_struct) { struct ipoque_packet_struct *packet = &ipoque_struct->packet; struct ipoque_flow_struct *flow = ipoque_struct->flow; // struct ipoque_id_struct *src = ipoque_struct->src; // struct ipoque_id_struct *dst = ipoque_struct->dst; IPQ_LOG(IPOQUE_PROTOCOL_MANOLITO, ipoque_struct, IPQ_LOG_DEBUG, "MANOLITO TCP DETECTION\n"); if (flow->l4.tcp.manolito_stage == 0 && packet->payload_packet_len > 6) { if (ipq_mem_cmp(packet->payload, "SIZ ", 4) != 0) goto end_manolito_nothing_found; flow->l4.tcp.manolito_stage = 1 + packet->packet_direction; IPQ_LOG(IPOQUE_PROTOCOL_MANOLITO, ipoque_struct, IPQ_LOG_DEBUG, "MANOLITO Stage 1.\n"); goto end_manolito_maybe_hit; } else if ((flow->l4.tcp.manolito_stage == 2 - packet->packet_direction) && packet->payload_packet_len > 4) { if (ipq_mem_cmp(packet->payload, "STR ", 4) != 0) goto end_manolito_nothing_found; IPQ_LOG(IPOQUE_PROTOCOL_MANOLITO, ipoque_struct, IPQ_LOG_DEBUG, "MANOLITO Stage 2.\n"); flow->l4.tcp.manolito_stage = 3 + packet->packet_direction; goto end_manolito_maybe_hit; } else if ((flow->l4.tcp.manolito_stage == 4 - packet->packet_direction) && packet->payload_packet_len > 5) { if (ipq_mem_cmp(packet->payload, "MD5 ", 4) != 0) goto end_manolito_nothing_found; IPQ_LOG(IPOQUE_PROTOCOL_MANOLITO, ipoque_struct, IPQ_LOG_DEBUG, "MANOLITO Stage 3.\n"); flow->l4.tcp.manolito_stage = 5 + packet->packet_direction; goto end_manolito_maybe_hit; } else if ((flow->l4.tcp.manolito_stage == 6 - packet->packet_direction) && packet->payload_packet_len == 4) { if (ipq_mem_cmp(packet->payload, "GO!!", 4) != 0) goto end_manolito_nothing_found; IPQ_LOG(IPOQUE_PROTOCOL_MANOLITO, ipoque_struct, IPQ_LOG_DEBUG, "MANOLITO Stage 4.\n"); goto end_manolito_found; } //IPQ_LOG(IPOQUE_PROTOCOL_MANOLITO,ipoque_struct, IPQ_LOG_DEBUG, "MANOLITO FLOW STAGE %d\n", flow->l4.tcp.manolito_stage); goto end_manolito_nothing_found; end_manolito_found: IPQ_LOG(IPOQUE_PROTOCOL_MANOLITO, ipoque_struct, IPQ_LOG_DEBUG, "MANOLITO FOUND\n"); ipoque_int_manolito_add_connection(ipoque_struct); return 1; end_manolito_maybe_hit: IPQ_LOG(IPOQUE_PROTOCOL_MANOLITO, ipoque_struct, IPQ_LOG_DEBUG, "MANOLITO maybe hit.\n"); return 2; end_manolito_nothing_found: IPQ_LOG(IPOQUE_PROTOCOL_MANOLITO, ipoque_struct, IPQ_LOG_DEBUG, "MANOLITO NOTHING FOUND\n"); return 0; }
static inline void ipoque_int_search_thunder_tcp(struct ipoque_detection_module_struct *ipoque_struct) { struct ipoque_packet_struct *packet = &ipoque_struct->packet; struct ipoque_flow_struct *flow = ipoque_struct->flow; // struct ipoque_id_struct *src=ipoque_struct->src; // struct ipoque_id_struct *dst=ipoque_struct->dst; if (packet->payload_packet_len > 8 && packet->payload[0] >= 0x30 && packet->payload[0] < 0x40 && packet->payload[1] == 0 && packet->payload[2] == 0 && packet->payload[3] == 0) { if (flow->thunder_stage == 3) { IPQ_LOG(IPOQUE_PROTOCOL_THUNDER, ipoque_struct, IPQ_LOG_DEBUG, "THUNDER tcp detected\n"); ipoque_int_thunder_add_connection(ipoque_struct); return; } flow->thunder_stage++; IPQ_LOG(IPOQUE_PROTOCOL_THUNDER, ipoque_struct, IPQ_LOG_DEBUG, "maybe thunder tcp packet detected, stage increased to %u\n", flow->thunder_stage); return; } if (flow->thunder_stage == 0 && packet->payload_packet_len > 17 && ipq_mem_cmp(packet->payload, "POST / HTTP/1.1\r\n", 17) == 0) { ipq_parse_packet_line_info(ipoque_struct); IPQ_LOG(IPOQUE_PROTOCOL_THUNDER, ipoque_struct, IPQ_LOG_DEBUG, "maybe thunder http POST packet detected, parsed packet lines: %u, empty line set %u (at: %u)\n", packet->parsed_lines, packet->empty_line_position_set, packet->empty_line_position); if (packet->empty_line_position_set != 0 && packet->content_line.ptr != NULL && packet->content_line.len == 24 && ipq_mem_cmp(packet->content_line.ptr, "application/octet-stream", 24) == 0 && packet->empty_line_position_set < (packet->payload_packet_len - 8) && packet->payload[packet->empty_line_position + 2] >= 0x30 && packet->payload[packet->empty_line_position + 2] < 0x40 && packet->payload[packet->empty_line_position + 3] == 0x00 && packet->payload[packet->empty_line_position + 4] == 0x00 && packet->payload[packet->empty_line_position + 5] == 0x00) { IPQ_LOG(IPOQUE_PROTOCOL_THUNDER, ipoque_struct, IPQ_LOG_DEBUG, "maybe thunder http POST packet application does match\n"); ipoque_int_thunder_add_connection(ipoque_struct); return; } } IPQ_LOG(IPOQUE_PROTOCOL_THUNDER, ipoque_struct, IPQ_LOG_DEBUG, "excluding thunder tcp at stage %u\n", flow->thunder_stage); IPOQUE_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, IPOQUE_PROTOCOL_THUNDER); }
void ipoque_search_pcanywhere(struct ipoque_detection_module_struct *ipoque_struct) { struct ipoque_packet_struct *packet = &ipoque_struct->packet; struct ipoque_flow_struct *flow = ipoque_struct->flow; // struct ipoque_id_struct *src=ipoque_struct->src; // struct ipoque_id_struct *dst=ipoque_struct->dst; if (packet->udp != NULL && packet->udp->dest == htons(5632) && packet->payload_packet_len == 2 && (ipq_mem_cmp(packet->payload, "NQ", 2) == 0 || ipq_mem_cmp(packet->payload, "ST", 2) == 0)) { IPQ_LOG(IPOQUE_PROTOCOL_PCANYWHERE, ipoque_struct, IPQ_LOG_DEBUG, "PC Anywhere name or status query detected.\n"); ipoque_int_pcanywhere_add_connection(ipoque_struct); return; } IPOQUE_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, IPOQUE_PROTOCOL_PCANYWHERE); }
static void mms_parse_packet_contentline(struct ipoque_detection_module_struct *ipoque_struct) { struct ipoque_packet_struct *packet = &ipoque_struct->packet; if (packet->content_line.len >= 24 && ipq_mem_cmp(packet->content_line.ptr, "application/x-mms-framed", 24) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_MMS, ipoque_struct, IPQ_LOG_DEBUG, "MMS: Content-Type: application/x-mms-framed found\n"); ipoque_int_http_add_connection(ipoque_struct, IPOQUE_PROTOCOL_MMS); } }
static void check_content_type_and_change_protocol(struct ipoque_detection_module_struct *ipoque_struct, u16 x) { #if defined( IPOQUE_PROTOCOL_TANGO ) || defined( IPOQUE_PROTOCOL_TRUPHONE ) || defined( IPOQUE_PROTOCOL_WHATSAPP ) struct ipoque_packet_struct *packet = &ipoque_struct->packet; #endif #ifdef IPOQUE_PROTOCOL_TRUPHONE if (packet->payload_packet_len > x + 18 && packet->payload_packet_len > x && packet->payload_packet_len > 18) { const u16 lastlen = packet->payload_packet_len - 18; for (x = 0; x < lastlen; x++) { if (ipq_mem_cmp(&packet->payload[x], "=\"im.truphone.com\"", 18) == 0 || ipq_mem_cmp(&packet->payload[x], "='im.truphone.com'", 18) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_TRACE, "changed to TRUPHONE.\n"); ipoque_int_jabber_add_connection(ipoque_struct, IPOQUE_PROTOCOL_TRUPHONE, IPOQUE_CORRELATED_PROTOCOL); } } } #endif return; }
static inline void ipoque_int_search_thunder_http(struct ipoque_detection_module_struct *ipoque_struct) { struct ipoque_packet_struct *packet = &ipoque_struct->packet; struct ipoque_id_struct *src = ipoque_struct->src; struct ipoque_id_struct *dst = ipoque_struct->dst; if (packet->detected_protocol == IPOQUE_PROTOCOL_THUNDER) { if (src != NULL && ((IPOQUE_TIMESTAMP_COUNTER_SIZE) (packet->tick_timestamp - src->thunder_ts) < ipoque_struct->thunder_timeout)) { IPQ_LOG(IPOQUE_PROTOCOL_THUNDER, ipoque_struct, IPQ_LOG_DEBUG, "thunder : save src connection packet detected\n"); src->thunder_ts = packet->tick_timestamp; } else if (dst != NULL && ((IPOQUE_TIMESTAMP_COUNTER_SIZE) (packet->tick_timestamp - dst->thunder_ts) < ipoque_struct->thunder_timeout)) { IPQ_LOG(IPOQUE_PROTOCOL_THUNDER, ipoque_struct, IPQ_LOG_DEBUG, "thunder : save dst connection packet detected\n"); dst->thunder_ts = packet->tick_timestamp; } return; } if (packet->payload_packet_len > 5 && memcmp(packet->payload, "GET /", 5) == 0 && IPQ_SRC_OR_DST_HAS_PROTOCOL(src, dst, IPOQUE_PROTOCOL_THUNDER)) { IPQ_LOG(IPOQUE_PROTOCOL_THUNDER, ipoque_struct, IPQ_LOG_DEBUG, "HTTP packet detected.\n"); ipq_parse_packet_line_info(ipoque_struct); if (packet->parsed_lines > 7 && packet->parsed_lines < 11 && packet->line[1].len > 10 && ipq_mem_cmp(packet->line[1].ptr, "Accept: */*", 11) == 0 && packet->line[2].len > 22 && ipq_mem_cmp(packet->line[2].ptr, "Cache-Control: no-cache", 23) == 0 && packet->line[3].len > 16 && ipq_mem_cmp(packet->line[3].ptr, "Connection: close", 17) == 0 && packet->line[4].len > 6 && ipq_mem_cmp(packet->line[4].ptr, "Host: ", 6) == 0 && packet->line[5].len > 15 && ipq_mem_cmp(packet->line[5].ptr, "Pragma: no-cache", 16) == 0 && packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > 49 && ipq_mem_cmp(packet->user_agent_line.ptr, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)", 50) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_THUNDER, ipoque_struct, IPQ_LOG_DEBUG, "Thunder HTTP download detected, adding flow.\n"); ipoque_int_thunder_add_connection(ipoque_struct); } } }
static void windowsmedia_parse_packet_contentline(struct ipoque_detection_module_struct *ipoque_struct) { struct ipoque_packet_struct *packet = &ipoque_struct->packet; if (packet->content_line.len >= 14 && ipq_mem_cmp(packet->content_line.ptr, "video/x-ms-", 11) == 0) { if (ipq_mem_cmp(&packet->content_line.ptr[11], "wmv", 3) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_WINDOWSMEDIA, ipoque_struct, IPQ_LOG_DEBUG, "WINDOWSMEDIA: Content-Type: video/x-ms-wmv found.\n"); ipoque_int_http_add_connection(ipoque_struct, IPOQUE_PROTOCOL_WINDOWSMEDIA); return; } if (ipq_mem_cmp(&packet->content_line.ptr[11], "asf", 3) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_WINDOWSMEDIA, ipoque_struct, IPQ_LOG_DEBUG, "WINDOWSMEDIA: Content-Type: video/x-ms-asf found.\n"); ipoque_int_http_add_connection(ipoque_struct, IPOQUE_PROTOCOL_WINDOWSMEDIA); return; } if (ipq_mem_cmp(&packet->content_line.ptr[11], "asx", 3) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_WINDOWSMEDIA, ipoque_struct, IPQ_LOG_DEBUG, "WINDOWSMEDIA: Content-Type: video/x-ms-asx found.\n"); ipoque_int_http_add_connection(ipoque_struct, IPOQUE_PROTOCOL_WINDOWSMEDIA); return; } } if (packet->content_line.len >= 24 && ipq_mem_cmp(packet->content_line.ptr, "video/x-msvideo", 15) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_WINDOWSMEDIA, ipoque_struct, IPQ_LOG_DEBUG, "WINDOWSMEDIA: Content-Type: video/x-msvideo found.\n"); ipoque_int_http_add_connection(ipoque_struct, IPOQUE_PROTOCOL_WINDOWSMEDIA); return; } if (packet->content_line.len >= 24 && ipq_mem_cmp(packet->content_line.ptr, "audio/x-wav", 11) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_WINDOWSMEDIA, ipoque_struct, IPQ_LOG_DEBUG, "WINDOWSMEDIA: Content-Type: audio/x-wav found.\n"); ipoque_int_http_add_connection(ipoque_struct, IPOQUE_PROTOCOL_WINDOWSMEDIA); return; } if (packet->content_line.len >= 32 && ipq_mem_cmp(packet->content_line.ptr, "application/vnd.ms.wms-hdr.asfv1", 32) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_WINDOWSMEDIA, ipoque_struct, IPQ_LOG_DEBUG, "WINDOWSMEDIA: Content-Type: application/vnd.ms.wms-hdr.asfv1 found.\n"); ipoque_int_http_add_connection(ipoque_struct, IPOQUE_PROTOCOL_WINDOWSMEDIA); return; } }
void ipoque_search_openft_tcp(struct ipoque_detection_module_struct *ipoque_struct) { struct ipoque_packet_struct *packet = &ipoque_struct->packet; struct ipoque_flow_struct *flow = ipoque_struct->flow; // struct ipoque_id_struct *src=ipoque_struct->src; // struct ipoque_id_struct *dst=ipoque_struct->dst; if (packet->payload_packet_len > 5 && memcmp(packet->payload, "GET /", 5) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_OPENFT, ipoque_struct, IPQ_LOG_DEBUG, "HTTP packet detected.\n"); ipq_parse_packet_line_info(ipoque_struct); if (packet->parsed_lines >= 2 && packet->line[1].len > 13 && ipq_mem_cmp(packet->line[1].ptr, "X-OpenftAlias:", 14) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_OPENFT, ipoque_struct, IPQ_LOG_DEBUG, "OpenFT detected.\n"); ipoque_int_openft_add_connection(ipoque_struct); return; } } IPOQUE_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, IPOQUE_PROTOCOL_OPENFT); }
void ipoque_search_battlefield(struct ipoque_detection_module_struct *ipoque_struct) { struct ipoque_packet_struct *packet = &ipoque_struct->packet; struct ipoque_flow_struct *flow = ipoque_struct->flow; struct ipoque_id_struct *src = ipoque_struct->src; struct ipoque_id_struct *dst = ipoque_struct->dst; if (packet->detected_protocol_stack[0] == IPOQUE_PROTOCOL_BATTLEFIELD) { if (src != NULL && ((IPOQUE_TIMESTAMP_COUNTER_SIZE) (packet->tick_timestamp - src->battlefield_ts) < ipoque_struct->battlefield_timeout)) { IPQ_LOG(IPOQUE_PROTOCOL_BATTLEFIELD, ipoque_struct, IPQ_LOG_DEBUG, "battlefield : save src connection packet detected\n"); src->battlefield_ts = packet->tick_timestamp; } else if (dst != NULL && ((IPOQUE_TIMESTAMP_COUNTER_SIZE) (packet->tick_timestamp - dst->battlefield_ts) < ipoque_struct->battlefield_timeout)) { IPQ_LOG(IPOQUE_PROTOCOL_BATTLEFIELD, ipoque_struct, IPQ_LOG_DEBUG, "battlefield : save dst connection packet detected\n"); dst->battlefield_ts = packet->tick_timestamp; } return; } if (IPQ_SRC_OR_DST_HAS_PROTOCOL(src, dst, IPOQUE_PROTOCOL_BATTLEFIELD)) { if (flow->l4.udp.battlefield_stage == 0 || flow->l4.udp.battlefield_stage == 1 + packet->packet_direction) { if (packet->payload_packet_len > 8 && get_u16(packet->payload, 0) == htons(0xfefd)) { flow->l4.udp.battlefield_msg_id = get_u32(packet->payload, 2); flow->l4.udp.battlefield_stage = 1 + packet->packet_direction; return; } } else if (flow->l4.udp.battlefield_stage == 2 - packet->packet_direction) { if (packet->payload_packet_len > 8 && get_u32(packet->payload, 0) == flow->l4.udp.battlefield_msg_id) { IPQ_LOG(IPOQUE_PROTOCOL_BATTLEFIELD, ipoque_struct, IPQ_LOG_DEBUG, "Battlefield message and reply detected.\n"); ipoque_int_battlefield_add_connection(ipoque_struct); return; } } } if (flow->l4.udp.battlefield_stage == 0) { if (packet->payload_packet_len == 46 && packet->payload[2] == 0 && packet->payload[4] == 0 && get_u32(packet->payload, 7) == htonl(0x98001100)) { flow->l4.udp.battlefield_stage = 3 + packet->packet_direction; return; } } else if (flow->l4.udp.battlefield_stage == 4 - packet->packet_direction) { if (packet->payload_packet_len == 7 && (packet->payload[0] == 0x02 || packet->payload[packet->payload_packet_len - 1] == 0xe0)) { IPQ_LOG(IPOQUE_PROTOCOL_BATTLEFIELD, ipoque_struct, IPQ_LOG_DEBUG, "Battlefield message and reply detected.\n"); ipoque_int_battlefield_add_connection(ipoque_struct); return; } } if (packet->payload_packet_len == 18 && ipq_mem_cmp(&packet->payload[5], "battlefield2\x00", 13) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_BATTLEFIELD, ipoque_struct, IPQ_LOG_DEBUG, "Battlefield 2 hello packet detected.\n"); ipoque_int_battlefield_add_connection(ipoque_struct); return; } else if (packet->payload_packet_len > 10 && (ipq_mem_cmp(packet->payload, "\x11\x20\x00\x01\x00\x00\x50\xb9\x10\x11", 10) == 0 || ipq_mem_cmp(packet->payload, "\x11\x20\x00\x01\x00\x00\x30\xb9\x10\x11", 10) == 0 || ipq_mem_cmp(packet->payload, "\x11\x20\x00\x01\x00\x00\xa0\x98\x00\x11", 10) == 0)) { IPQ_LOG(IPOQUE_PROTOCOL_BATTLEFIELD, ipoque_struct, IPQ_LOG_DEBUG, "Battlefield safe pattern detected.\n"); ipoque_int_battlefield_add_connection(ipoque_struct); return; } IPOQUE_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, IPOQUE_PROTOCOL_BATTLEFIELD); return; }
void ipoque_search_ipp(struct ipoque_detection_module_struct *ipoque_struct) { struct ipoque_packet_struct *packet = &ipoque_struct->packet; struct ipoque_flow_struct *flow = ipoque_struct->flow; // struct ipoque_id_struct *src=ipoque_struct->src; // struct ipoque_id_struct *dst=ipoque_struct->dst; u8 i; IPQ_LOG(IPOQUE_PROTOCOL_IPP, ipoque_struct, IPQ_LOG_DEBUG, "search ipp\n"); if (packet->payload_packet_len > 20) { IPQ_LOG(IPOQUE_PROTOCOL_IPP, ipoque_struct, IPQ_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') { IPQ_LOG(IPOQUE_PROTOCOL_IPP, ipoque_struct, IPQ_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) { IPQ_LOG(IPOQUE_PROTOCOL_IPP, ipoque_struct, IPQ_LOG_DEBUG, "read symbols while the symbol is a number.\n"); break; } } if (packet->payload[i++] != ' ') { IPQ_LOG(IPOQUE_PROTOCOL_IPP, ipoque_struct, IPQ_LOG_DEBUG, "there is no blank following the number.\n"); goto search_for_next_pattern; } if (packet->payload[i] < '0' || packet->payload[i] > '9') { IPQ_LOG(IPOQUE_PROTOCOL_IPP, ipoque_struct, IPQ_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) { IPQ_LOG(IPOQUE_PROTOCOL_IPP, ipoque_struct, IPQ_LOG_DEBUG, "read symbols while the symbol is a number.\n"); break; } } if (ipq_mem_cmp(&packet->payload[i], " ipp://", 7) != 0) { IPQ_LOG(IPOQUE_PROTOCOL_IPP, ipoque_struct, IPQ_LOG_DEBUG, "the string ' ipp://' does not follow.\n"); goto search_for_next_pattern; } IPQ_LOG(IPOQUE_PROTOCOL_IPP, ipoque_struct, IPQ_LOG_DEBUG, "found ipp\n"); ipoque_int_ipp_add_connection(ipoque_struct); return; } search_for_next_pattern: if (packet->payload_packet_len > 3 && memcmp(packet->payload, "POST", 4) == 0) { ipq_parse_packet_line_info(ipoque_struct); if (packet->content_line.ptr != NULL && packet->content_line.len > 14 && memcmp(packet->content_line.ptr, "application/ipp", 15) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_IPP, ipoque_struct, IPQ_LOG_DEBUG, "found ipp via POST ... application/ipp.\n"); ipoque_int_ipp_add_connection(ipoque_struct); return; } } IPQ_LOG(IPOQUE_PROTOCOL_IPP, ipoque_struct, IPQ_LOG_DEBUG, "no ipp detected.\n"); IPOQUE_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, IPOQUE_PROTOCOL_IPP); }
void ipoque_search_jabber_tcp(struct ipoque_detection_module_struct *ipoque_struct) { struct ipoque_packet_struct *packet = &ipoque_struct->packet; struct ipoque_flow_struct *flow = ipoque_struct->flow; struct ipoque_id_struct *src = ipoque_struct->src; struct ipoque_id_struct *dst = ipoque_struct->dst; u16 x; IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "search jabber.\n"); /* search for jabber file transfer */ /* this part is working asymmetrically */ if (packet->tcp != NULL && packet->tcp->syn != 0 && packet->payload_packet_len == 0) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "check jabber syn\n"); if (src != NULL && src->jabber_file_transfer_port[0] != 0) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "src jabber ft port set, ports are: %u, %u\n", ntohs(src->jabber_file_transfer_port[0]), ntohs(src->jabber_file_transfer_port[1])); if (((IPOQUE_TIMESTAMP_COUNTER_SIZE) (packet->tick_timestamp - src->jabber_stun_or_ft_ts)) >= ipoque_struct->jabber_file_transfer_timeout) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "JABBER src stun timeout %u %u\n", src->jabber_stun_or_ft_ts, packet->tick_timestamp); src->jabber_file_transfer_port[0] = 0; src->jabber_file_transfer_port[1] = 0; } else if (src->jabber_file_transfer_port[0] == packet->tcp->dest || src->jabber_file_transfer_port[0] == packet->tcp->source || src->jabber_file_transfer_port[1] == packet->tcp->dest || src->jabber_file_transfer_port[1] == packet->tcp->source) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "found jabber file transfer.\n"); ipoque_int_jabber_add_connection(ipoque_struct, IPOQUE_PROTOCOL_UNENCRYPED_JABBER, IPOQUE_CORRELATED_PROTOCOL); } } if (dst != NULL && dst->jabber_file_transfer_port[0] != 0) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "dst jabber ft port set, ports are: %u, %u\n", ntohs(dst->jabber_file_transfer_port[0]), ntohs(dst->jabber_file_transfer_port[1])); if (((IPOQUE_TIMESTAMP_COUNTER_SIZE) (packet->tick_timestamp - dst->jabber_stun_or_ft_ts)) >= ipoque_struct->jabber_file_transfer_timeout) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "JABBER dst stun timeout %u %u\n", dst->jabber_stun_or_ft_ts, packet->tick_timestamp); dst->jabber_file_transfer_port[0] = 0; dst->jabber_file_transfer_port[1] = 0; } else if (dst->jabber_file_transfer_port[0] == packet->tcp->dest || dst->jabber_file_transfer_port[0] == packet->tcp->source || dst->jabber_file_transfer_port[1] == packet->tcp->dest || dst->jabber_file_transfer_port[1] == packet->tcp->source) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "found jabber file transfer.\n"); ipoque_int_jabber_add_connection(ipoque_struct, IPOQUE_PROTOCOL_UNENCRYPED_JABBER, IPOQUE_CORRELATED_PROTOCOL); } } return; } if (packet->tcp != 0 && packet->payload_packet_len == 0) { return; } /* this part parses a packet and searches for port=. it works asymmetrically. */ if (packet->detected_protocol_stack[0] == IPOQUE_PROTOCOL_UNENCRYPED_JABBER) { u16 lastlen; u16 j_port = 0; /* check for google jabber voip connections ... */ /* need big packet */ if (packet->payload_packet_len < 100) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "packet too small, return.\n"); return; } /* need message to or type for file-transfer */ if (memcmp(packet->payload, "<iq from=\"", 8) == 0 || memcmp(packet->payload, "<iq from=\'", 8) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "JABBER <iq from=\".\n"); lastlen = packet->payload_packet_len - 11; for (x = 10; x < lastlen; x++) { if (packet->payload[x] == 'p') { if (ipq_mem_cmp(&packet->payload[x], "port=", 5) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "port=\n"); if (src != NULL) { src->jabber_stun_or_ft_ts = packet->tick_timestamp; } if (dst != NULL) { dst->jabber_stun_or_ft_ts = packet->tick_timestamp; } x += 6; j_port = ntohs_ipq_bytestream_to_number(&packet->payload[x], packet->payload_packet_len, &x); IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "JABBER port : %u\n", ntohs(j_port)); if (src != NULL) { if (src->jabber_file_transfer_port[0] == 0 || src->jabber_file_transfer_port[0] == j_port) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "src->jabber_file_transfer_port[0] = j_port = %u;\n", ntohs(j_port)); src->jabber_file_transfer_port[0] = j_port; } else { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "src->jabber_file_transfer_port[1] = j_port = %u;\n", ntohs(j_port)); src->jabber_file_transfer_port[1] = j_port; } } if (dst != NULL) { if (dst->jabber_file_transfer_port[0] == 0 || dst->jabber_file_transfer_port[0] == j_port) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "dst->jabber_file_transfer_port[0] = j_port = %u;\n", ntohs(j_port)); dst->jabber_file_transfer_port[0] = j_port; } else { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "dst->jabber_file_transfer_port[1] = j_port = %u;\n", ntohs(j_port)); dst->jabber_file_transfer_port[1] = j_port; } } } } } } else if (memcmp(packet->payload, "<iq to=\"", 8) == 0 || memcmp(packet->payload, "<iq to=\'", 8) == 0 || memcmp(packet->payload, "<iq type=", 9) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "JABBER <iq to=\"/type=\"\n"); lastlen = packet->payload_packet_len - 21; for (x = 8; x < lastlen; x++) { /* invalid character */ if (packet->payload[x] < 32 || packet->payload[x] > 127) { return; } if (packet->payload[x] == '@') { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "JABBER @\n"); break; } } if (x >= lastlen) { return; } lastlen = packet->payload_packet_len - 10; for (; x < lastlen; x++) { if (packet->payload[x] == 'p') { if (ipq_mem_cmp(&packet->payload[x], "port=", 5) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "port=\n"); if (src != NULL) { src->jabber_stun_or_ft_ts = packet->tick_timestamp; } if (dst != NULL) { dst->jabber_stun_or_ft_ts = packet->tick_timestamp; } x += 6; j_port = ntohs_ipq_bytestream_to_number(&packet->payload[x], packet->payload_packet_len, &x); IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "JABBER port : %u\n", ntohs(j_port)); if (src != NULL && src->jabber_voice_stun_used_ports < JABBER_MAX_STUN_PORTS - 1) { if (packet->payload[5] == 'o') { src->jabber_voice_stun_port[src->jabber_voice_stun_used_ports++] = j_port; } else { if (src->jabber_file_transfer_port[0] == 0 || src->jabber_file_transfer_port[0] == j_port) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "src->jabber_file_transfer_port[0] = j_port = %u;\n", ntohs(j_port)); src->jabber_file_transfer_port[0] = j_port; } else { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "src->jabber_file_transfer_port[1] = j_port = %u;\n", ntohs(j_port)); src->jabber_file_transfer_port[1] = j_port; } } } if (dst != NULL && dst->jabber_voice_stun_used_ports < JABBER_MAX_STUN_PORTS - 1) { if (packet->payload[5] == 'o') { dst->jabber_voice_stun_port[dst->jabber_voice_stun_used_ports++] = j_port; } else { if (dst->jabber_file_transfer_port[0] == 0 || dst->jabber_file_transfer_port[0] == j_port) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "dst->jabber_file_transfer_port[0] = j_port = %u;\n", ntohs(j_port)); dst->jabber_file_transfer_port[0] = j_port; } else { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "dst->jabber_file_transfer_port[1] = j_port = %u;\n", ntohs(j_port)); dst->jabber_file_transfer_port[1] = j_port; } } } return; } } } } return; } /* search for jabber here */ /* this part is working asymmetrically */ if ((packet->payload_packet_len > 13 && memcmp(packet->payload, "<?xml version=", 14) == 0) || (packet->payload_packet_len >= IPQ_STATICSTRING_LEN("<stream:stream ") && memcmp(packet->payload, "<stream:stream ", IPQ_STATICSTRING_LEN("<stream:stream ")) == 0)) { if (packet->payload_packet_len > 47) { const u16 lastlen = packet->payload_packet_len - 47; for (x = 0; x < lastlen; x++) { if (ipq_mem_cmp (&packet->payload[x], "xmlns:stream='http://etherx.jabber.org/streams'", 47) == 0 || ipq_mem_cmp(&packet->payload[x], "xmlns:stream=\"http://etherx.jabber.org/streams\"", 47) == 0) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_TRACE, "found JABBER.\n"); x += 47; ipoque_int_jabber_add_connection(ipoque_struct, IPOQUE_PROTOCOL_UNENCRYPED_JABBER, IPOQUE_REAL_PROTOCOL); /* search for other protocols: Truphone */ check_content_type_and_change_protocol(ipoque_struct, x); return; } } } } if (flow->packet_counter < 3) { IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_TRACE, "packet_counter: %u\n", flow->packet_counter); return; } IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "Excluding jabber connection\n"); IPOQUE_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, IPOQUE_PROTOCOL_UNENCRYPED_JABBER); #ifdef IPOQUE_PROTOCOL_TRUPHONE IPOQUE_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, IPOQUE_PROTOCOL_TRUPHONE); #endif }