Beispiel #1
0
 static inline
#else
__forceinline static
#endif
	 u_int8_t check_edk_len(const u_int8_t * payload, u_int16_t payload_packet_len)
{
	u_int32_t edk_len_parsed = 0;
	// we use a do / while loop here, because we have checked the byte 0 for 0xe3 or 0xc5 already before this call
	do {
		u_int32_t edk_len;
		edk_len = get_l32(payload, 1 + edk_len_parsed);

		/* if bigger, return here directly with an error... */
		if (edk_len > payload_packet_len)
			return 0;
		/* this is critical here:
		 * if (edk_len + 5) provokes an overflow to zero, we will have an infinite loop...
		 * the check above does prevent this, bcause the edk_len must be ((u_int32_t)-5), which is always bigger than the packet size
		 */
		edk_len_parsed += 5 + edk_len;

		if (edk_len_parsed == payload_packet_len)
			return 1;
		if (edk_len_parsed > payload_packet_len)
			return 0;
	}
	while (payload[edk_len_parsed] == 0xe3 || payload[edk_len_parsed] == 0xc5 || payload[edk_len_parsed] == 0xd4);
	return 0;
}
Beispiel #2
0
void ipoque_search_imesh_tcp_udp(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 == IPOQUE_PROTOCOL_IMESH) {
        if (src != NULL) {
            src->imesh_timer = packet->tick_timestamp;
        }
        if (dst != NULL) {
            dst->imesh_timer = packet->tick_timestamp;
        }
        return;
    }

    /* skip marked packets */
    if (packet->detected_protocol != IPOQUE_PROTOCOL_UNKNOWN)
        goto imesh_not_found_end;

    if (packet->udp != NULL) {

        IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG, "UDP FOUND\n");

        // this is the login packet
        if (					//&& ((IPOQUE_TIMESTAMP_COUNTER_SIZE)(packet->tick_timestamp - src->imesh_timer)) < ipoque_struct->imesh_connection_timeout
            packet->payload_packet_len == 28 && (get_l32(packet->payload, 0)) == 0x00000002	// PATTERN : 02 00 00 00
            && (get_l32(packet->payload, 24)) == 0x00000000	// PATTERN : 00 00 00 00
            && (packet->udp->dest == htons(1864) || packet->udp->source == htons(1864))) {
            IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG, "iMesh Login detected\n");
            if (src != NULL) {
                src->imesh_timer = packet->tick_timestamp;
            }
            if (dst != NULL) {
                dst->imesh_timer = packet->tick_timestamp;
            }
            ipoque_int_imesh_add_connection(ipoque_struct);
            return;
        } else if (				//&& ((IPOQUE_TIMESTAMP_COUNTER_SIZE)(packet->tick_timestamp - src->imesh_timer)) < ipoque_struct->imesh_connection_timeout
            packet->payload_packet_len == 36 && (get_l32(packet->payload, 0)) == 0x00000002	// PATTERN : 02 00 00 00
            //&& packet->payload[35]==0x0f
        ) {
            IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG, "iMesh detected, %u\n",
                    ipoque_struct->imesh_connection_timeout);
            if (src != NULL) {
                IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG, "iMesh: src < %u, %u, %u\n",
                        (packet->tick_timestamp - src->imesh_timer), packet->tick_timestamp, src->imesh_timer);
                if (((IPOQUE_TIMESTAMP_COUNTER_SIZE)
                        (packet->tick_timestamp - src->imesh_timer)) < ipoque_struct->imesh_connection_timeout) {
                    src->imesh_timer = packet->tick_timestamp;
                    ipoque_int_imesh_add_connection(ipoque_struct);
                }
            }
            if (dst != NULL) {
                IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG, "iMesh: dst < %u, %u, %u\n",
                        (packet->tick_timestamp - dst->imesh_timer), packet->tick_timestamp, dst->imesh_timer);
                if (((IPOQUE_TIMESTAMP_COUNTER_SIZE)
                        (packet->tick_timestamp - dst->imesh_timer)) < ipoque_struct->imesh_connection_timeout) {
                    dst->imesh_timer = packet->tick_timestamp;
                    ipoque_int_imesh_add_connection(ipoque_struct);
                }
            }
            return;
        }

        IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG,
                "iMesh UDP packetlen: %d\n", packet->payload_packet_len);

    } else if (packet->tcp != NULL) {

        IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG,
                "TCP FOUND :: Payload %u\n", packet->payload_packet_len);

        if (packet->actual_payload_len == 0) {
            return;

        } else if ((packet->actual_payload_len == 8 || packet->payload_packet_len == 10)	/* PATTERN:: 04 00 00 00 00 00 00 00 [00 00] */
                   &&packet->payload[0] == 0x04
                   && packet->payload[1] == 0x00
                   && packet->payload[2] == 0x00
                   && packet->payload[3] == 0x00
                   && packet->payload[4] == 0x00
                   && packet->payload[5] == 0x00 && packet->payload[6] == 0x00 && packet->payload[7] == 0x00) {
            flow->imesh_stage += 2;

            IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG,
                    "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);

        } else if (packet->actual_payload_len == 10	/* PATTERN:: ?? ?? 04|00 00 64|00 00 */
                   && (packet->payload[2] == 0x04 || packet->payload[2] == 0x00)
                   && packet->payload[3] == 0x00 && (packet->payload[4] == 0x00 || packet->payload[4] == 0x64)
                   && packet->payload[5] == 0x00) {
            flow->imesh_stage += 2;
            IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG,
                    "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);

        } else if (packet->actual_payload_len == 2 && packet->payload[0] == 0x06 && packet->payload[1] == 0x00) {
            flow->imesh_stage++;
            IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG,
                    "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);

        } else if (packet->actual_payload_len == 10	/* PATTERN:: 06 00 04|00 00 01|00 00 01|00 00 ?? 00 */
                   && packet->payload[0] == 0x06
                   && packet->payload[1] == 0x00 && (packet->payload[2] == 0x04 || packet->payload[2] == 0x00)
                   && packet->payload[3] == 0x00 && (packet->payload[4] == 0x00 || packet->payload[4] == 0x01)
                   && packet->payload[5] == 0x00 && (packet->payload[6] == 0x01 || packet->payload[6] == 0x00)
                   && packet->payload[7] == 0x00 && packet->payload[9] == 0x00) {
            flow->imesh_stage += 2;
            IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG,
                    "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
        }

        else if (packet->actual_payload_len == 24 && packet->payload[0] == 0x06	// PATTERN :: 06 00 12 00 00 00 34 00 00
                 && packet->payload[1] == 0x00
                 && packet->payload[2] == 0x12
                 && packet->payload[3] == 0x00
                 && packet->payload[4] == 0x00
                 && packet->payload[5] == 0x00
                 && packet->payload[6] == 0x34 && packet->payload[7] == 0x00 && packet->payload[8] == 0x00) {
            flow->imesh_stage += 2;
            IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG,
                    "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
        }

        else if (packet->actual_payload_len == 8	/* PATTERN:: 06|00 00 02 00 00 00 33 00 */
                 && (packet->payload[0] == 0x06 || packet->payload[0] == 0x00)
                 && packet->payload[1] == 0x00
                 && packet->payload[2] == 0x02
                 && packet->payload[3] == 0x00
                 && packet->payload[4] == 0x00
                 && packet->payload[5] == 0x00 && packet->payload[6] == 0x33 && packet->payload[7] == 0x00) {
            flow->imesh_stage += 2;
            IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG,
                    "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
        }

        else if (packet->payload_packet_len == 6	/* PATTERN:: 02 00 00 00 33 00 */
                 && packet->payload[0] == 0x02
                 && packet->payload[1] == 0x00
                 && packet->payload[2] == 0x00
                 && packet->payload[3] == 0x00 && packet->payload[4] == 0x33 && packet->payload[5] == 0x00) {
            flow->imesh_stage += 2;
            IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG,
                    "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
        }

        else if (packet->actual_payload_len == 12 && packet->payload[0] == 0x06	// PATTERN : 06 00 06 00 00 00 64 00
                 && packet->payload[1] == 0x00
                 && packet->payload[2] == 0x06
                 && packet->payload[3] == 0x00
                 && packet->payload[4] == 0x00
                 && packet->payload[5] == 0x00 && packet->payload[6] == 0x64 && packet->payload[7] == 0x00) {
            flow->imesh_stage += 2;
            IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG,
                    "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
        }

        else if (packet->actual_payload_len == 10	/* PATTERN:: 06 00 04|01 00 00 00 01|00 00 ?? 00 */
                 && packet->payload[0] == 0x06
                 && packet->payload[1] == 0x00 && (packet->payload[2] == 0x04 || packet->payload[2] == 0x01)
                 && packet->payload[3] == 0x00
                 && packet->payload[4] == 0x00
                 && packet->payload[5] == 0x00 && (packet->payload[6] == 0x01 || packet->payload[6] == 0x00)
                 && packet->payload[7] == 0x00
                 /* && packet->payload[8]==0x00 */
                 && packet->payload[9] == 0x00) {
            flow->imesh_stage += 2;
            IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG,
                    "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);

        } else if ((packet->actual_payload_len == 64 || packet->actual_payload_len == 52	/* PATTERN:: [len] 00 00 00 00 */
                    || packet->actual_payload_len == 95)
                   && get_u16(packet->payload, 0) == (packet->actual_payload_len)
                   && packet->payload[1] == 0x00 && packet->payload[2] == 0x00
                   && packet->payload[3] == 0x00 && packet->payload[4] == 0x00) {
            flow->imesh_stage += 2;
            IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG,
                    "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);

        } else if (packet->actual_payload_len == 6 && packet->payload[0] == 0x06	// PATTERN : 06 00 04|6c 00|01 00 00
                   && packet->payload[1] == 0x00 && (packet->payload[2] == 0x04 || packet->payload[2] == 0x6c)
                   && (packet->payload[3] == 0x00 || packet->payload[3] == 0x01)
                   && packet->payload[4] == 0x00 && packet->payload[5] == 0x00) {

            flow->imesh_stage += 2;
            IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG,
                    "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);

        } else if (packet->actual_payload_len == 6	/* PATTERN:: [len] ?? ee 00 00 00 */
                   && get_u16(packet->payload, 0) == (packet->actual_payload_len)
                   && packet->payload[2] == 0xee
                   && packet->payload[3] == 0x00 && packet->payload[4] == 0x00 && packet->payload[5] == 0x00) {
            flow->imesh_stage += 2;
            IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG,
                    "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);
        }

        else if (packet->actual_payload_len == 10	/* PATTERN:: 06 00 00 00 00 00 00 00 */
                 && packet->payload[0] == 0x06
                 && packet->payload[1] == 0x00
                 && packet->payload[2] == 0x00
                 && packet->payload[3] == 0x00
                 && packet->payload[4] == 0x00
                 && packet->payload[5] == 0x00 && packet->payload[6] == 0x00 && packet->payload[7] == 0x00) {
            flow->imesh_stage += 2;
            IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG,
                    "IMESH FOUND :: Payload %u\n", packet->actual_payload_len);

        }
    }

    /*give one packet tolerance for detection */
    if (flow->imesh_stage >= 4)

        ipoque_int_imesh_add_connection(ipoque_struct);


    else if ((flow->packet_counter < 5) || packet->actual_payload_len == 0) {
        return;
    } else {
        goto imesh_not_found_end;
    }

imesh_not_found_end:
    IPOQUE_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, IPOQUE_PROTOCOL_IMESH);
    IPQ_LOG(IPOQUE_PROTOCOL_IMESH, ipoque_struct, IPQ_LOG_DEBUG, "iMesh excluded at stage %d\n", flow->imesh_stage);

}
Beispiel #3
0
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;
}
Beispiel #4
0
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);
	}
}
Beispiel #5
0
void ipoque_search_pplive_tcp_udp(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 a;

	IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "search pplive.\n");


	if (packet->udp != NULL) {

		if (src != NULL && src->pplive_vod_cli_port == packet->udp->source
			&& IPOQUE_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, IPOQUE_PROTOCOL_PPLIVE)) {
			if (src->pplive_last_packet_time_set == 1 && (IPOQUE_TIMESTAMP_COUNTER_SIZE)
				(packet->tick_timestamp - src->pplive_last_packet_time) < ipoque_struct->pplive_connection_timeout) {
				ipoque_int_pplive_add_connection(ipoque_struct);
				src->pplive_last_packet_time_set = 1;
				src->pplive_last_packet_time = packet->tick_timestamp;
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "timestamp src.\n");
				return;
			} else {
				src->pplive_vod_cli_port = 0;
				src->pplive_last_packet_time = 0;
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "PPLIVE: VOD port timer reset.\n");
			}
		}

		if (dst != NULL && dst->pplive_vod_cli_port == packet->udp->dest
			&& IPOQUE_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, IPOQUE_PROTOCOL_PPLIVE)) {
			if (dst->pplive_last_packet_time_set == 1 && (IPOQUE_TIMESTAMP_COUNTER_SIZE)
				(packet->tick_timestamp - dst->pplive_last_packet_time) < ipoque_struct->pplive_connection_timeout) {
				ipoque_int_pplive_add_connection(ipoque_struct);
				dst->pplive_last_packet_time_set = 1;
				dst->pplive_last_packet_time = packet->tick_timestamp;
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "timestamp dst.\n");
				return;
			} else {
				dst->pplive_last_packet_time_set = 0;
				dst->pplive_vod_cli_port = 0;
				dst->pplive_last_packet_time = 0;
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "PPLIVE: VOD port timer reset.\n");
			}
		}

		if ((packet->payload_packet_len >= 76) && ((packet->payload[0] == 0x01) || (packet->payload[0] == 0x18)
												   || (packet->payload[0] == 0x05))
			&& (packet->payload[1] == 0x00)
			&& get_l32(packet->payload, 12) == 0 && (packet->payload[16] == 0 || packet->payload[16] == 1)
			&& (packet->payload[17] == 0) && (packet->payload[24] == 0xac)) {
			IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "found pplive.\n");
			ipoque_int_pplive_add_connection(ipoque_struct);
			return;
		}

		if (packet->payload_packet_len > 50 && packet->payload[0] == 0xe9
			&& packet->payload[1] == 0x03 && (packet->payload[3] == 0x00 || packet->payload[3] == 0x01)
			&& packet->payload[4] == 0x98 && packet->payload[5] == 0xab
			&& packet->payload[6] == 0x01 && packet->payload[7] == 0x02) {
			IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "found pplive.\n");
			ipoque_int_pplive_add_connection(ipoque_struct);
			return;
		}

		if (packet->payload_packet_len == 94
			&& packet->payload[8] == 0x00 && get_u32(packet->payload, 9) == ntohl(0x02010000)
			&& get_u32(packet->payload, 58) == ntohl(0xb1130000)) {
			IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "found pplive.\n");
			ipoque_int_pplive_add_connection(ipoque_struct);
			return;
		}

		if ((packet->payload_packet_len >= 90 && packet->payload_packet_len <= 110)
			&& (packet->payload[0] >= 0x0a && packet->payload[0] <= 0x0f)
			&& get_u32(packet->payload, 86) == 0) {
			int i;
			for (i = 56; i < 68; i += 2) {
				if ((get_u32(packet->payload, i) == ntohl(0x4fde7e7f))
					&& (get_u16(packet->payload, i + 4) == 0)) {
					IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "found pplive through "
							"bitpattern 4f de 7e 7f 00 00.\n");
					ipoque_int_pplive_add_connection(ipoque_struct);
					return;
				}
			}
		}
		if (flow->packet_counter < 5 && !flow->pplive_stage) {	/* With in 1st 4 packets */
			if (((packet->payload_packet_len >= 90 && packet->payload_packet_len <= 110)
				 && (!get_u32(packet->payload, packet->payload_packet_len - 16)
					 || !get_u32(packet->payload, packet->payload_packet_len - 4)))
				) {
				flow->pplive_stage = 2;	/* Now start looking for size(28 | 30) */
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG,
						"Maybe found pplive packet. Now start looking for size(28 | 30).\n");
			}
			if (68 == packet->payload_packet_len
				&& get_l16(packet->payload, 0) == 0x21 && packet->payload[19] == packet->payload[20]
				&& packet->payload[20] == packet->payload[21]
				&& packet->payload[12] == packet->payload[13]
				&& packet->payload[14] == packet->payload[15]) {
				flow->pplive_stage = 3 + packet->packet_direction;
			}
			IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "need next packet I.\n");
			return;
		}
		if (flow->pplive_stage == 3 + packet->packet_direction) {
			/* Because we are expecting packet in reverese direction.. */
			IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "need next packet II.\n");
			return;
		}
		if (flow->pplive_stage == (4 - packet->packet_direction)
			&& packet->payload_packet_len > 67
			&& (get_l16(packet->payload, 0) == 0x21
				|| (get_l16(packet->payload, 0) == 0x22 && !get_l16(packet->payload, 28)))) {
			if (dst != NULL) {
				dst->pplive_vod_cli_port = packet->udp->dest;
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct,
						IPQ_LOG_DEBUG, "PPLIVE: VOD Port marked %u.\n", ntohs(packet->udp->dest));
				dst->pplive_last_packet_time = packet->tick_timestamp;
				dst->pplive_last_packet_time_set = 1;
			}
			IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "found pplive.\n");
			ipoque_int_pplive_add_connection(ipoque_struct);
			return;
		}

		if (flow->pplive_stage == 2) {
			if ((packet->payload_packet_len == 30 && (packet->payload[0] == 0x02 || packet->payload[0] == 0x03)
				 && get_u32(packet->payload, 21) == ntohl(0x00000001))
				|| (packet->payload_packet_len == 28 && (packet->payload[0] == 0x01 || packet->payload[0] == 0x00)
					&& (get_u32(packet->payload, 19) == ntohl(0x00000001)))) {
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "found pplive.\n");
				ipoque_int_pplive_add_connection(ipoque_struct);
				return;
			}
			if (flow->packet_counter < 45) {
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "need next packet III.\n");
				return;
			}
		}
	} else if (packet->tcp != NULL) {

		IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG,
				"PPLIVE: TCP found, plen = %d, stage = %d, payload[0] = %x, payload[1] = %x, payload[2] = %x, payload[3] = %x \n",
				packet->payload_packet_len, flow->pplive_stage, packet->payload[0], packet->payload[1],
				packet->payload[2], packet->payload[3]);

		if (src != NULL && src->pplive_vod_cli_port == packet->tcp->source
			&& IPOQUE_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, IPOQUE_PROTOCOL_PPLIVE)) {
			if (src->pplive_last_packet_time_set == 1 && (IPOQUE_TIMESTAMP_COUNTER_SIZE)
				(packet->tick_timestamp - src->pplive_last_packet_time) < ipoque_struct->pplive_connection_timeout) {
				ipoque_int_pplive_add_connection(ipoque_struct);
				src->pplive_last_packet_time_set = 1;
				src->pplive_last_packet_time = packet->tick_timestamp;
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "timestamp src.\n");
				return;
			} else {
				src->pplive_vod_cli_port = 0;
				src->pplive_last_packet_time = 0;
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "PPLIVE: VOD port timer reset.\n");
			}
		}

		if (dst != NULL && dst->pplive_vod_cli_port == packet->tcp->dest
			&& IPOQUE_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, IPOQUE_PROTOCOL_PPLIVE)) {
			if (dst->pplive_last_packet_time_set == 1 && (IPOQUE_TIMESTAMP_COUNTER_SIZE)
				(packet->tick_timestamp - dst->pplive_last_packet_time) < ipoque_struct->pplive_connection_timeout) {
				flow->detected_protocol = IPOQUE_PROTOCOL_PPLIVE;
				packet->detected_protocol = IPOQUE_PROTOCOL_PPLIVE;
				dst->pplive_last_packet_time_set = 1;
				dst->pplive_last_packet_time = packet->tick_timestamp;
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "timestamp dst.\n");
				return;
			} else {
				dst->pplive_last_packet_time_set = 0;
				dst->pplive_vod_cli_port = 0;
				dst->pplive_last_packet_time = 0;
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "PPLIVE: VOD port timer reset.\n");
			}
		}

		if (packet->payload_packet_len > 4 && memcmp(packet->payload, "GET /", 5) == 0) {
			ipq_parse_packet_line_info(ipoque_struct);
			if (packet->parsed_lines == 8
				&& packet->line[0].ptr != NULL && packet->line[0].len >= 8
				&& memcmp(&packet->payload[packet->line[0].len - 8], "HTTP/1.", 7) == 0
				&& packet->line[2].ptr != NULL && packet->line[2].len >= 16
				&& memcmp(packet->line[2].ptr, "x-flash-version:", 16) == 0
				&& packet->user_agent_line.ptr != NULL && packet->user_agent_line.len >= 11
				&& memcmp(packet->user_agent_line.ptr, "Mozilla/4.0", 11) == 0
				&& packet->line[6].ptr != NULL && packet->line[6].len >= 21
				&& memcmp(packet->line[6].ptr, "Pragma: Client=PPLive", 21) == 0) {
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "PPLIVE: found HTTP request.\n");
				ipoque_int_pplive_add_connection(ipoque_struct);
				return;
			} else if (packet->parsed_lines == 6
					   && packet->line[0].ptr != NULL && packet->line[0].len >= 8
					   && memcmp(&packet->payload[packet->line[0].len - 8], "HTTP/1.", 7) == 0
					   && packet->user_agent_line.ptr != NULL && packet->user_agent_line.len >= 10
					   && memcmp(packet->user_agent_line.ptr, "PPLive DAC", 10) == 0) {
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "PPLIVE: found HTTP request.\n");
				ipoque_int_pplive_add_connection(ipoque_struct);
				return;
			}
		}
		// searches for packets > 20 byte that begin with a hex number == packet->payload_packet_len - 4
		// and with the same number at position 16, 17, 18, 19
		if (packet->payload_packet_len > 20 && ntohl(get_u32(packet->payload, 0)) == packet->payload_packet_len - 4) {
			if (packet->payload[4] == 0x21 && packet->payload[5] == 0x00) {
				if ((packet->payload[9] == packet->payload[10]) && (packet->payload[9] == packet->payload[11])) {
					if ((packet->payload[16] == packet->payload[17]) &&
						(packet->payload[16] == packet->payload[18]) && (packet->payload[16] == packet->payload[19])) {
						IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct,
								IPQ_LOG_DEBUG, "PPLIVE: direct server request or response found\n");
						ipoque_int_pplive_add_connection(ipoque_struct);
						return;
					}
				}
			}
		}
		// stage > 0, packet begins with 21 00, bytes at positions 5, 6, 7 are equal, bytes at positions 12, 13, 14, 15 are equal,
		if (packet->payload_packet_len > 20 && flow->pplive_stage) {
			if (packet->payload[0] == 0x21 && packet->payload[1] == 0x00) {
				if (packet->payload[5] == packet->payload[6] && packet->payload[5] == packet->payload[7]) {
					if (packet->payload[12] == packet->payload[13] && packet->payload[14] == packet->payload[15]
						&& packet->payload[12] == packet->payload[14]) {
						IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct,
								IPQ_LOG_DEBUG, "PPLIVE: direct server request or response found\n");
						ipoque_int_pplive_add_connection(ipoque_struct);
						return;
					}
				}
			}
		}
		// packet (len>11) begins with a hex number == packet->payload_packet_len - 4 and matches certain bitmuster
		if (packet->payload_packet_len > 11 && ntohl(get_u32(packet->payload, 0)) == packet->payload_packet_len - 4) {
			if (packet->payload[4] == 0xe9 && packet->payload[5] == 0x03 &&
				((packet->payload[7] == packet->payload[10]) || (packet->payload[7] == packet->payload[11]))) {
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct,
						IPQ_LOG_DEBUG, "PPLIVE: direct server request or response found\n");
				ipoque_int_pplive_add_connection(ipoque_struct);
				return;
			}
		}
		// stage > 0, len>10, begins with e9 03, matches certain pattern
		if (packet->payload_packet_len > 10 && flow->pplive_stage) {
			if (packet->payload[0] == 0xe9 && packet->payload[1] == 0x03 &&
				((packet->payload[3] == packet->payload[6]) || (packet->payload[3] == packet->payload[7]))) {
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct,
						IPQ_LOG_DEBUG, "PPLIVE: direct server request or response found\n");
				ipoque_int_pplive_add_connection(ipoque_struct);
				return;
			}
		}

		/* Adware in the PPLive Client -> first TCP Packet has length of 4 Bytes -> 2nd TCP Packet has length of 96 Bytes */
		/* or */
		/* Peer-List Requests over TCP -> first Packet has length of 4 Bytes -> 2nd TCP Packet has length of 71 Bytes */
		/* there are different possibilities of the order of the packets */

		IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG,
				"PPLIVE: TCP found, plen = %d, stage = %d, payload[0] = %x, payload[1] = %x, payload[2] = %x, payload[3] = %x \n",
				packet->payload_packet_len, flow->pplive_stage,
				packet->payload[0], packet->payload[1], packet->payload[2], packet->payload[3]);

		/* generic pplive detection (independent of the stage) !!! */
		// len > 11, packet begins with a hex number == packet->payload_packet_len - 4, pattern: ?? ?? ?? ?? 21 00 ?? ?? 98 ab 01 02
		if (packet->payload_packet_len > 11 && ntohl(get_u32(packet->payload, 0)) == packet->payload_packet_len - 4) {
			if (packet->payload[4] == 0x21 && packet->payload[5] == 0x00
				&& ((packet->payload[8] == 0x98 && packet->payload[9] == 0xab
					 && packet->payload[10] == 0x01 && packet->payload[11] == 0x02)
				)) {
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct,
						IPQ_LOG_DEBUG, "PPLIVE: direct server request or response found\n");
				ipoque_int_pplive_add_connection(ipoque_struct);
				return;
			}
			// packet 4 to 19 have a hex representation from 0x30 to 0x39
			if (packet->payload_packet_len > 20) {
				a = 4;
				while (a < 20) {
					if (packet->payload[a] >= '0' && packet->payload[a] <= '9') {
						if (a == 19) {
							IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct,
									IPQ_LOG_DEBUG, "PPLIVE: direct new header format found\n");
							ipoque_int_pplive_add_connection(ipoque_struct);
							return;
						} else {
							a++;
						}
					} else {
						break;
					}
				}
			}
		}

		/* 1st and 2nd (KD: ??????? )Packet of Client is 4 Byte  */
		// stage == 0, p_len == 4, pattern: 04 00 00 00 --> need next packet
		if (flow->pplive_stage == 0) {
			if (packet->payload_packet_len == 4 && packet->payload[0] > 0x04
				&& packet->payload[1] == 0x00 && packet->payload[2] == 0x00 && packet->payload[3] == 0x00) {
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct,
						IPQ_LOG_DEBUG, "PPLIVE: 4Byte TCP Packet Request found \n");

				/* go to the 2nd Client Packet */
				flow->pplive_stage = 1 + packet->packet_direction;
				flow->pplive_next_packet_size[packet->packet_direction] = packet->payload[0];
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "need next packet i.\n");
				return;
			}
		} else if (flow->pplive_stage == 2 - packet->packet_direction) {
			if (packet->payload_packet_len == 4 && packet->payload[0] > 0x04
				&& packet->payload[1] == 0x00 && packet->payload[2] == 0x00 && packet->payload[3] == 0x00) {
				IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct,
						IPQ_LOG_DEBUG, "PPLIVE: 4Byte TCP Packet Response found \n");

				/* go to the 2nd Client Packet */
				flow->pplive_next_packet_size[packet->packet_direction] = packet->payload[0];
			}
			flow->pplive_stage = 3;
			IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "need next packet ii.\n");
			return;
		} else if (flow->pplive_stage == 1 + packet->packet_direction || flow->pplive_stage == 3) {
			if (packet->payload_packet_len > 7 && flow->pplive_next_packet_size[packet->packet_direction] >= 4) {
				if (packet->payload_packet_len == flow->pplive_next_packet_size[packet->packet_direction]) {

					if (packet->payload[0] == 0xe9 && packet->payload[1] == 0x03
						&& ((packet->payload[4] == 0x98
							 && packet->payload[5] == 0xab && packet->payload[6] == 0x01 && packet->payload[7] == 0x02)
						)) {
						IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct,
								IPQ_LOG_DEBUG, "PPLIVE: two packet response found\n");

						IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG,
								"found pplive over tcp with pattern iii.\n");
						ipoque_int_pplive_add_connection(ipoque_struct);
						return;
					}
					// packet 4 to 19 have a hex representation from 0x30 to 0x39
					if (packet->payload_packet_len > 16) {
						a = 0;
						while (a < 16) {
							if (packet->payload[a] >= '0' && packet->payload[a] <= '9') {
								if (a == 15) {
									IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG,
											"PPLIVE: new header format found\n");
									IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG,
											"found pplive over tcp with pattern v.\n");
									ipoque_int_pplive_add_connection(ipoque_struct);
									return;
								} else {
									a++;
								}
							} else {
								break;
							}
						}
					}
					// p_len>79 and a lot of 00 in the end
					if (packet->payload_packet_len > 79
						&& get_u32(packet->payload, packet->payload_packet_len - 9) == 0x00000000
						&& get_u32(packet->payload, packet->payload_packet_len - 5) == 0x00000000) {
						IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG,
								"PPLIVE: Last 8 NULL bytes found.\n");
						IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG,
								"found pplive over tcp with pattern vi.\n");
						ipoque_int_pplive_add_connection(ipoque_struct);
						return;
					}
				}
				if (packet->payload_packet_len > flow->pplive_next_packet_size[packet->packet_direction]) {
					if (packet->payload[0] == 0xe9 && packet->payload[1] == 0x03
						&& packet->payload[4] == 0x98 && packet->payload[5] == 0xab
						&& packet->payload[6] == 0x01 && packet->payload[7] == 0x02) {
						a = flow->pplive_next_packet_size[packet->packet_direction];
						IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "a=%u.\n", a);
						if (packet->payload_packet_len > a + 4
							&& packet->payload[a + 2] == 0x00 && packet->payload[a + 3] == 0x00
							&& packet->payload[a] != 0) {
							a += ((packet->payload[a + 1] << 8) + packet->payload[a] + 4);
							IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "a=%u.\n", a);
							if (packet->payload_packet_len == a) {
								IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG,
										"found pplive over tcp with pattern vii.\n");
								ipoque_int_pplive_add_connection(ipoque_struct);
								return;
							}
							if (packet->payload_packet_len > a + 4
								&& packet->payload[a + 2] == 0x00 && packet->payload[a + 3] == 0x00
								&& packet->payload[a] != 0) {
								a += ((packet->payload[a + 1] << 8) + packet->payload[a] + 4);
								if (packet->payload_packet_len == a) {
									IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG,
											"found pplive over tcp with pattern viii.\n");
									ipoque_int_pplive_add_connection(ipoque_struct);
									return;
								}
							}

						}
					}
				}
			}
		}
	}


	IPQ_LOG(IPOQUE_PROTOCOL_PPLIVE, ipoque_struct, IPQ_LOG_DEBUG, "exclude pplive.\n");
	IPOQUE_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, IPOQUE_PROTOCOL_PPLIVE);
}
Beispiel #6
0
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);

}