Ejemplo n.º 1
0
void ndpi_search_fiesta(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_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "search fiesta.\n");

	if (flow->l4.tcp.fiesta_stage == 0 && packet->payload_packet_len == 5
		&& get_u_int16_t(packet->payload, 0) == ntohs(0x0407)
		&& (packet->payload[2] == 0x08)
		&& (packet->payload[4] == 0x00 || packet->payload[4] == 0x01)) {

		NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "maybe fiesta symmetric, first packet.\n");
		flow->l4.tcp.fiesta_stage = 1 + packet->packet_direction;
		goto maybe_fiesta;
	}
	if (flow->l4.tcp.fiesta_stage == (2 - packet->packet_direction)
		&& ((packet->payload_packet_len > 1 && packet->payload_packet_len - 1 == packet->payload[0])
			|| (packet->payload_packet_len > 3 && packet->payload[0] == 0
				&& get_l16(packet->payload, 1) == packet->payload_packet_len - 3))) {
		NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "Maybe fiesta.\n");
		goto maybe_fiesta;
	}
	if (flow->l4.tcp.fiesta_stage == (1 + packet->packet_direction)) {
		if (packet->payload_packet_len == 4 && get_u_int32_t(packet->payload, 0) == htonl(0x03050c01)) {
			goto add_fiesta;
		}
		if (packet->payload_packet_len == 5 && get_u_int32_t(packet->payload, 0) == htonl(0x04030c01)
			&& packet->payload[4] == 0) {
			goto add_fiesta;
		}
		if (packet->payload_packet_len == 6 && get_u_int32_t(packet->payload, 0) == htonl(0x050e080b)) {
			goto add_fiesta;
		}
		if (packet->payload_packet_len == 100 && packet->payload[0] == 0x63 && packet->payload[61] == 0x52
			&& packet->payload[81] == 0x5a && get_u_int16_t(packet->payload, 1) == htons(0x3810)
			&& get_u_int16_t(packet->payload, 62) == htons(0x6f75)) {
			goto add_fiesta;
		}
		if (packet->payload_packet_len > 3 && packet->payload_packet_len - 1 == packet->payload[0]
			&& get_u_int16_t(packet->payload, 1) == htons(0x140c)) {
			goto add_fiesta;
		}
	}

	NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "exclude fiesta.\n");
	NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FIESTA);
	return;

  maybe_fiesta:
	NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "Stage is set to %d.\n", flow->l4.tcp.fiesta_stage);
	return;

  add_fiesta:
	NDPI_LOG(NDPI_PROTOCOL_FIESTA, ndpi_struct, NDPI_LOG_DEBUG, "detected fiesta.\n");
	ndpi_int_fiesta_add_connection(ndpi_struct, flow);
	return;
}
Ejemplo n.º 2
0
static void ndpi_search_xdmcp(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_XDMCP, ndpi_struct, NDPI_LOG_DEBUG, "search xdmcp.\n");

	if (packet->tcp != NULL && (ntohs(packet->tcp->dest) >= 6000 && ntohs(packet->tcp->dest) <= 6005)
		&& packet->payload_packet_len == 48
		&& packet->payload[0] == 0x6c && packet->payload[1] == 0x00
		&& ntohs(get_u_int16_t(packet->payload, 6)) == 0x1200 && ntohs(get_u_int16_t(packet->payload, 8)) == 0x1000) {

		NDPI_LOG(NDPI_PROTOCOL_XDMCP, ndpi_struct, NDPI_LOG_DEBUG, "found xdmcp over tcp.\n");
		ndpi_int_xdmcp_add_connection(ndpi_struct, flow);
		return;
	}
	if (packet->udp != NULL && ntohs(packet->udp->dest) == 177
		&& packet->payload_packet_len >= 6 && packet->payload_packet_len == 6 + ntohs(get_u_int16_t(packet->payload, 4))
		&& ntohs(get_u_int16_t(packet->payload, 0)) == 0x0001 && ntohs(get_u_int16_t(packet->payload, 2)) == 0x0002) {

		NDPI_LOG(NDPI_PROTOCOL_XDMCP, ndpi_struct, NDPI_LOG_DEBUG, "found xdmcp over udp.\n");
		ndpi_int_xdmcp_add_connection(ndpi_struct, flow);
		return;
	}


	NDPI_LOG(NDPI_PROTOCOL_XDMCP, ndpi_struct, NDPI_LOG_DEBUG, "exclude xdmcp.\n");
	NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_XDMCP);
}
Ejemplo n.º 3
0
void ndpi_search_world_of_kung_fu(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_WORLD_OF_KUNG_FU, ndpi_struct, NDPI_LOG_DEBUG,
		 "search world_of_kung_fu.\n");

	if ((packet->payload_packet_len == 16)
	    && ntohl(get_u_int32_t(packet->payload, 0)) == 0x0c000000
	    && ntohl(get_u_int32_t(packet->payload, 4)) == 0xd2000c00
	    && (packet->payload[9]
		== 0x16) && ntohs(get_u_int16_t(packet->payload, 10)) == 0x0000
	    && ntohs(get_u_int16_t(packet->payload, 14)) == 0x0000) {
		NDPI_LOG(NDPI_PROTOCOL_WORLD_OF_KUNG_FU, ndpi_struct,
			 NDPI_LOG_DEBUG, "detected world_of_kung_fu.\n");
		ndpi_int_world_of_kung_fu_add_connection(ndpi_struct, flow);
		return;
	}

	NDPI_LOG(NDPI_PROTOCOL_WORLD_OF_KUNG_FU, ndpi_struct, NDPI_LOG_DEBUG,
		 "exclude world_of_kung_fu.\n");
	NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask,
				     NDPI_PROTOCOL_WORLD_OF_KUNG_FU);
}
Ejemplo n.º 4
0
static int ndpi_int_check_mdns_payload(struct ndpi_detection_module_struct
				       *ndpi_struct,
				       struct ndpi_flow_struct *flow)
{
	struct ndpi_packet_struct *packet = &flow->packet;

	if ((packet->payload[2] & 0x80) == 0 &&
	    ntohs(get_u_int16_t(packet->payload, 4)) <= NDPI_MAX_MDNS_REQUESTS
	    && ntohs(get_u_int16_t(packet->payload, 6)) <=
	    NDPI_MAX_MDNS_REQUESTS) {

		NDPI_LOG(NDPI_PROTOCOL_MDNS, ndpi_struct, NDPI_LOG_DEBUG,
			 "found MDNS with question query.\n");

		return 1;
	} else if ((packet->payload[2] & 0x80) != 0 &&
		   ntohs(get_u_int16_t(packet->payload, 4)) == 0 &&
		   ntohs(get_u_int16_t(packet->payload, 6)) <=
		   NDPI_MAX_MDNS_REQUESTS
		   && ntohs(get_u_int16_t(packet->payload, 6)) != 0) {
		NDPI_LOG(NDPI_PROTOCOL_MDNS, ndpi_struct, NDPI_LOG_DEBUG,
			 "found MDNS with answer query.\n");

		return 1;
	}

	return 0;
}
Ejemplo n.º 5
0
void ndpi_search_guildwars_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_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "search guildwars.\n");

	if (packet->payload_packet_len == 64 && get_u_int16_t(packet->payload, 1) == ntohs(0x050c)
		&& memcmp(&packet->payload[50], "@2&P", 4) == 0) {
		NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "GuildWars version 29.350: found.\n");
		ndpi_int_guildwars_add_connection(ndpi_struct, flow);
		return;
	}
	if (packet->payload_packet_len == 16 && get_u_int16_t(packet->payload, 1) == ntohs(0x040c)
		&& get_u_int16_t(packet->payload, 4) == ntohs(0xa672)
		&& packet->payload[8] == 0x01 && packet->payload[12] == 0x04) {
		NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "GuildWars version 29.350: found.\n");
		ndpi_int_guildwars_add_connection(ndpi_struct, flow);
		return;
	}
	if (packet->payload_packet_len == 21 && get_u_int16_t(packet->payload, 0) == ntohs(0x0100)
		&& get_u_int32_t(packet->payload, 5) == ntohl(0xf1001000)
		&& packet->payload[9] == 0x01) {
		NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "GuildWars version 216.107.245.50: found.\n");
		ndpi_int_guildwars_add_connection(ndpi_struct, flow);
		return;
	}

	NDPI_LOG(NDPI_PROTOCOL_GUILDWARS, ndpi_struct, NDPI_LOG_DEBUG, "exclude guildwars.\n");
	NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_GUILDWARS);
}
Ejemplo n.º 6
0
Archivo: tds.c Proyecto: houcy/nDPI-1
void ndpi_search_tds_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 > 8
      && packet->payload_packet_len < 512
      && packet->payload[1] < 0x02
      && ntohs(get_u_int16_t(packet->payload, 2)) == packet->payload_packet_len && get_u_int16_t(packet->payload, 4) == 0x0000) {

    if (flow->l4.tcp.tds_stage == 0) {
      if (packet->payload[0] != 0x02 && packet->payload[0] != 0x07 && packet->payload[0] != 0x12) {
	goto exclude_tds;
      } else {
	flow->l4.tcp.tds_stage = 1 + packet->packet_direction;
	flow->l4.tcp.tds_login_version = packet->payload[0];
	return;
      }
    } else if (flow->l4.tcp.tds_stage == 2 - packet->packet_direction) {
      switch (flow->l4.tcp.tds_login_version) {
      case 0x12:
	if (packet->payload[0] == 0x04) {
	  flow->l4.tcp.tds_stage = 3 + packet->packet_direction;
	  return;
	} else {
	  goto exclude_tds;
	}
	//TODO: add more cases for other versions
      default:
	goto exclude_tds;
      }
    } else if (flow->l4.tcp.tds_stage == 4 - packet->packet_direction) {
      switch (flow->l4.tcp.tds_login_version) {
      case 0x12:
	if (packet->payload[0] == 0x12) {
	  NDPI_LOG(NDPI_PROTOCOL_TDS, ndpi_struct, NDPI_LOG_DEBUG, "TDS detected\n");
	  ndpi_int_tds_add_connection(ndpi_struct, flow);
	  return;
	} else {
	  goto exclude_tds;
	}
	//TODO: add more cases for other versions
      default:
	goto exclude_tds;
      }
    }
  }

 exclude_tds:

  NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TDS);
}
void ndpi_search_quake(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 == 14
		 && get_u_int16_t(packet->payload, 0) == 0xffff && memcmp(&packet->payload[2], "getInfo", 7) == 0)
		|| (packet->payload_packet_len == 17
			&& get_u_int16_t(packet->payload, 0) == 0xffff && memcmp(&packet->payload[2], "challenge", 9) == 0)
		|| (packet->payload_packet_len > 20
			&& packet->payload_packet_len < 30
			&& get_u_int16_t(packet->payload, 0) == 0xffff && memcmp(&packet->payload[2], "getServers", 10) == 0)) {
		NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake IV detected.\n");
		ndpi_int_quake_add_connection(ndpi_struct, flow);
		return;
	}

	/* Quake III/Quake Live */
	if (packet->payload_packet_len == 15 && get_u_int32_t(packet->payload, 0) == 0xffffffff
		&& memcmp(&packet->payload[4], "getinfo", NDPI_STATICSTRING_LEN("getinfo")) == 0) {
		NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake III Arena/Quake Live detected.\n");
		ndpi_int_quake_add_connection(ndpi_struct, flow);
		return;
	}
	if (packet->payload_packet_len == 16 && get_u_int32_t(packet->payload, 0) == 0xffffffff
		&& memcmp(&packet->payload[4], "getchallenge", NDPI_STATICSTRING_LEN("getchallenge")) == 0) {
		NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake III Arena/Quake Live detected.\n");
		ndpi_int_quake_add_connection(ndpi_struct, flow);
		return;
	}
	if (packet->payload_packet_len > 20 && packet->payload_packet_len < 30
		&& get_u_int32_t(packet->payload, 0) == 0xffffffff
		&& memcmp(&packet->payload[4], "getservers", NDPI_STATICSTRING_LEN("getservers")) == 0) {
		NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake III Arena/Quake Live detected.\n");
		ndpi_int_quake_add_connection(ndpi_struct, flow);
		return;
	}



	/* ports for startup packet:
	   Quake I        26000 (starts with 0x8000)
	   Quake II       27910
	   Quake III      27960 (increases with each player)
	   Quake IV       27650
	   Quake World    27500
	   Quake Wars     ?????
	 */

	NDPI_LOG(NDPI_PROTOCOL_QUAKE, ndpi_struct, NDPI_LOG_DEBUG, "Quake excluded.\n");
	NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUAKE);
}
Ejemplo n.º 8
0
Archivo: sopcast.c Proyecto: T-NOVA/vTC
 static inline
#else
__forceinline static
#endif
	 u_int8_t ndpi_int_is_sopcast_tcp(const u_int8_t * payload, const u_int16_t payload_len)
{
	if (payload_len != 54)
		return 0;

	if (payload[2] != payload[3] - 4 && payload[2] != payload[3] + 4)
		return 0;

	if (payload[2] != payload[4] - 1 && payload[2] != payload[4] + 1)
		return 0;

	if (payload[25] != payload[25 + 16 - 1] + 1 && payload[25] != payload[25 + 16 - 1] - 1) {

		if (payload[3] != payload[25] &&
			payload[3] != payload[25] - 4 && payload[3] != payload[25] + 4 && payload[3] != payload[25] - 21) {
			return 0;
		}
	}

	if (payload[4] != payload[28] ||
		payload[28] != payload[30] ||
		payload[30] != payload[31] ||
		get_u_int16_t(payload, 30) != get_u_int16_t(payload, 32) || get_u_int16_t(payload, 32) != get_u_int16_t(payload, 34)) {

		if ((payload[2] != payload[5] - 1 && payload[2] != payload[5] + 1) ||
			payload[2] != payload[25] ||
			payload[4] != payload[28] ||
			payload[4] != payload[31] ||
			payload[4] != payload[32] ||
			payload[4] != payload[33] ||
			payload[4] != payload[34] ||
			payload[4] != payload[35] || payload[4] != payload[30] || payload[2] != payload[36]) {
			return 0;
		}
	}

	if (payload[42] != payload[53])
		return 0;

	if (payload[45] != payload[46] + 1 && payload[45] != payload[46] - 1)
		return 0;

	if (payload[45] != payload[49] || payload[46] != payload[50] || payload[47] != payload[51])
		return 0;

	return 1;
}
Ejemplo n.º 9
0
void ndpi_search_dhcp_udp(struct ndpi_detection_module_struct *ndpi_struct,
			  struct ndpi_flow_struct *flow)
{
	struct ndpi_packet_struct *packet = &flow->packet;

//      struct ndpi_id_struct         *src=ndpi_struct->src;
//      struct ndpi_id_struct         *dst=ndpi_struct->dst;

	/* this detection also works for asymmetric dhcp traffic */

	/*check standard DHCP 0.0.0.0:68 -> 255.255.255.255:67 */
	if (packet->payload_packet_len >= 244
	    && (packet->udp->source == htons(67)
		|| packet->udp->source == htons(68))
	    && (packet->udp->dest == htons(67)
		|| packet->udp->dest == htons(68))
	    && get_u_int32_t(packet->payload, 236) == htonl(0x63825363)
	    && get_u_int16_t(packet->payload, 240) == htons(0x3501)) {

		NDPI_LOG(NDPI_PROTOCOL_DHCP, ndpi_struct, NDPI_LOG_DEBUG,
			 "DHCP request\n");

		ndpi_int_dhcp_add_connection(ndpi_struct, flow);
		return;
	}

	NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask,
				     NDPI_PROTOCOL_DHCP);
}
Ejemplo n.º 10
0
static void ndpi_search_mysql_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 > 37	//min length
		&& get_u_int16_t(packet->payload, 0) == packet->payload_packet_len - 4	//first 3 bytes are length
		&& get_u_int8_t(packet->payload, 2) == 0x00	//3rd byte of packet length
		&& get_u_int8_t(packet->payload, 3) == 0x00	//packet sequence number is 0 for startup packet
		&& get_u_int8_t(packet->payload, 5) > 0x30	//server version > 0
		&& get_u_int8_t(packet->payload, 5) < 0x37	//server version < 7
		&& get_u_int8_t(packet->payload, 6) == 0x2e	//dot
		) {
		u_int32_t a;
		for (a = 7; a + 31 < packet->payload_packet_len; a++) {
			if (packet->payload[a] == 0x00) {
				if (get_u_int8_t(packet->payload, a + 13) == 0x00	//filler byte
					&& get_u_int64_t(packet->payload, a + 19) == 0x0ULL	//13 more
					&& get_u_int32_t(packet->payload, a + 27) == 0x0	//filler bytes
					&& get_u_int8_t(packet->payload, a + 31) == 0x0) {
					NDPI_LOG(NDPI_PROTOCOL_MYSQL, ndpi_struct, NDPI_LOG_DEBUG, "MySQL detected.\n");
					ndpi_int_mysql_add_connection(ndpi_struct, flow);
					return;
				}
				break;
			}
		}
	}

	NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MYSQL);

}
Ejemplo n.º 11
0
static void ndpi_search_udp_msn_misc(struct ndpi_detection_module_struct
				     *ndpi_struct, struct ndpi_flow_struct *flow)
{
  struct ndpi_packet_struct *packet = &flow->packet;
	
  struct ndpi_id_struct *src = flow->src;
  struct ndpi_id_struct *dst = flow->dst;


  /* do we have an msn login ? */
  if ((src == NULL || NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) == 0)
      && (dst == NULL
	  || NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_MSN) == 0)) {
    NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MSN);
    return;
  }

  /* asymmetric ft detection works */
  if (packet->payload_packet_len == 20
      && get_u_int32_t(packet->payload, 4) == 0 && packet->payload[9] == 0
      && get_u_int16_t(packet->payload, 10) == htons(0x0100)) {
    NDPI_LOG(NDPI_PROTOCOL_MSN, ndpi_struct, NDPI_LOG_TRACE, "msn udp misc data connection detected\n");
    ndpi_int_msn_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
  }

  /* asymmetric detection working. */
  return;
  //}
}
Ejemplo n.º 12
0
Archivo: stun.c Proyecto: T-NOVA/vTC
void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
  struct ndpi_packet_struct *packet = &flow->packet;


  NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "search stun.\n");


  if (packet->tcp) {

    /* STUN may be encapsulated in TCP packets */

    if (packet->payload_packet_len >= 2 + 20 &&
	ntohs(get_u_int16_t(packet->payload, 0)) + 2 == packet->payload_packet_len) {

      /* TODO there could be several STUN packets in a single TCP packet so maybe the detection could be
       * improved by checking only the STUN packet of given length */

      if (ndpi_int_check_stun(ndpi_struct, packet->payload + 2, packet->payload_packet_len - 2) ==
	  NDPI_IS_STUN) {
	NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found TCP stun.\n");
	ndpi_int_stun_add_connection(ndpi_struct, flow);
	return;
      }
    }
  }
  if (ndpi_int_check_stun(ndpi_struct, packet->payload, packet->payload_packet_len) == NDPI_IS_STUN) {
    NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found UDP stun.\n");
    ndpi_int_stun_add_connection(ndpi_struct, flow);
    return;
  }

  NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "exclude stun.\n");
  NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_STUN);
}
Ejemplo n.º 13
0
 static inline
#else
__forceinline static
#endif
	void ndpi_search_mgcp_connection(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;

	/* information about MGCP taken from http://en.wikipedia.org/wiki/MGCP */

	u_int16_t pos = 4;

	if (packet->payload_packet_len < 8) {
		goto mgcp_excluded;
	}

	/* packet must end with 0x0d0a or with 0x0a */
	if (packet->payload[packet->payload_packet_len - 1] != 0x0a
		&& get_u_int16_t(packet->payload, packet->payload_packet_len - 2) != htons(0x0d0a)) {
		goto mgcp_excluded;
	}



	if (packet->payload[0] != 'A' && packet->payload[0] != 'C' && packet->payload[0] != 'D' &&
		packet->payload[0] != 'E' && packet->payload[0] != 'M' && packet->payload[0] != 'N' &&
		packet->payload[0] != 'R') {
		goto mgcp_excluded;
	}
	if (memcmp(packet->payload, "AUEP ", 5) != 0 && memcmp(packet->payload, "AUCX ", 5) != 0 &&
		memcmp(packet->payload, "CRCX ", 5) != 0 && memcmp(packet->payload, "DLCX ", 5) != 0 &&
		memcmp(packet->payload, "EPCF ", 5) != 0 && memcmp(packet->payload, "MDCX ", 5) != 0 &&
		memcmp(packet->payload, "NTFY ", 5) != 0 && memcmp(packet->payload, "RQNT ", 5) != 0 &&
		memcmp(packet->payload, "RSIP ", 5) != 0) {
		goto mgcp_excluded;
	}
	// now search for string "MGCP " in the rest of the message
	while ((pos + 5) < packet->payload_packet_len) {
		if (memcmp(&packet->payload[pos], "MGCP ", 5) == 0) {
			NDPI_LOG(NDPI_PROTOCOL_MGCP, ndpi_struct, NDPI_LOG_DEBUG, "MGCP match.\n");
			ndpi_int_mgcp_add_connection(ndpi_struct, flow);
			return;
		}
		pos++;
	}

  mgcp_excluded:
	NDPI_LOG(NDPI_PROTOCOL_MGCP, ndpi_struct, NDPI_LOG_DEBUG, "exclude MGCP.\n");
	NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MGCP);
}
Ejemplo n.º 14
0
static void ndpi_search_rdp(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 > 10
            && get_u_int8_t(packet->payload, 0) > 0
            && get_u_int8_t(packet->payload, 0) < 4 && get_u_int16_t(packet->payload, 2) == ntohs(packet->payload_packet_len)
            && get_u_int8_t(packet->payload, 4) == packet->payload_packet_len - 5
            && get_u_int8_t(packet->payload, 5) == 0xe0
            && get_u_int16_t(packet->payload, 6) == 0 && get_u_int16_t(packet->payload, 8) == 0 && get_u_int8_t(packet->payload, 10) == 0) {
        NDPI_LOG(NDPI_PROTOCOL_RDP, ndpi_struct, NDPI_LOG_DEBUG, "RDP detected.\n");
        ndpi_int_rdp_add_connection(ndpi_struct, flow);
        return;
    }

    NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RDP);
}
Ejemplo n.º 15
0
void ndpi_search_mail_pop_tcp(struct ndpi_detection_module_struct
								*ndpi_struct, struct ndpi_flow_struct *flow)
{
	struct ndpi_packet_struct *packet = &flow->packet;
	
//  struct ndpi_id_struct         *src=ndpi_struct->src;
//  struct ndpi_id_struct         *dst=ndpi_struct->dst;
	u_int8_t a = 0;
	u_int8_t bit_count = 0;

	NDPI_LOG(NDPI_PROTOCOL_MAIL_POP, ndpi_struct, NDPI_LOG_DEBUG, "search mail_pop\n");



	if ((packet->payload_packet_len > 3
		 && (packet->payload[0] == '+' && (packet->payload[1] == 'O' || packet->payload[1] == 'o')
			 && (packet->payload[2] == 'K' || packet->payload[2] == 'k')))
		|| (packet->payload_packet_len > 4
			&& (packet->payload[0] == '-' && (packet->payload[1] == 'E' || packet->payload[1] == 'e')
				&& (packet->payload[2] == 'R' || packet->payload[2] == 'r')
				&& (packet->payload[3] == 'R' || packet->payload[3] == 'r')))) {
		// +OK or -ERR seen
		flow->l4.tcp.mail_pop_stage += 1;
	} else if (!ndpi_int_mail_pop_check_for_client_commands(ndpi_struct, flow)) {
		goto maybe_split_pop;
	}

	if (packet->payload_packet_len > 2 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) {

		// count the bits set in the bitmask
		if (flow->l4.tcp.pop_command_bitmask != 0) {
			for (a = 0; a < 16; a++) {
				bit_count += (flow->l4.tcp.pop_command_bitmask >> a) & 0x01;
			}
		}

		NDPI_LOG(NDPI_PROTOCOL_MAIL_POP, ndpi_struct, NDPI_LOG_DEBUG,
				"mail_pop +OK/-ERR responses: %u, unique commands: %u\n", flow->l4.tcp.mail_pop_stage, bit_count);

		if ((bit_count + flow->l4.tcp.mail_pop_stage) >= 3) {
			if (flow->l4.tcp.mail_pop_stage > 0) {
				NDPI_LOG(NDPI_PROTOCOL_MAIL_POP, ndpi_struct, NDPI_LOG_DEBUG, "mail_pop identified\n");
				ndpi_int_mail_pop_add_connection(ndpi_struct, flow);
				return;
			} else {
				return;
			}
		} else {
			return;
		}

	} else {
Ejemplo n.º 16
0
void ndpi_search_fasttrack_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 > 6 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) {
		NDPI_LOG(NDPI_PROTOCOL_FASTTRACK, ndpi_struct, NDPI_LOG_TRACE, "detected 0d0a at the end of the packet.\n");

		if (memcmp(packet->payload, "GIVE ", 5) == 0 && packet->payload_packet_len >= 8) {
			u_int16_t i;
			for (i = 5; i < (packet->payload_packet_len - 2); i++) {
				// make shure that the argument to GIVE is numeric
				if (!(packet->payload[i] >= '0' && packet->payload[i] <= '9')) {
					goto exclude_fasttrack;
				}
			}

			NDPI_LOG(NDPI_PROTOCOL_FASTTRACK, ndpi_struct, NDPI_LOG_TRACE, "FASTTRACK GIVE DETECTED\n");
			ndpi_int_fasttrack_add_connection(ndpi_struct, flow);
			return;
		}

		if (packet->payload_packet_len > 50 && memcmp(packet->payload, "GET /", 5) == 0) {
			u_int8_t a = 0;
			NDPI_LOG(NDPI_PROTOCOL_FASTTRACK, ndpi_struct, NDPI_LOG_TRACE, "detected GET /. \n");
			ndpi_parse_packet_line_info(ndpi_struct, flow);
			for (a = 0; a < packet->parsed_lines; a++) {
				if ((packet->line[a].len > 17 && memcmp(packet->line[a].ptr, "X-Kazaa-Username: "******"User-Agent: PeerEnabler/", 24) == 0)) {
					NDPI_LOG(NDPI_PROTOCOL_FASTTRACK, ndpi_struct, NDPI_LOG_TRACE,
							"detected X-Kazaa-Username: || User-Agent: PeerEnabler/\n");
					ndpi_int_fasttrack_add_connection(ndpi_struct, flow);
					return;
				}
			}
		}
	}

  exclude_fasttrack:
	NDPI_LOG(NDPI_PROTOCOL_FASTTRACK, ndpi_struct, NDPI_LOG_TRACE, "fasttrack/kazaa excluded.\n");
	NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_FASTTRACK);
}
Ejemplo n.º 17
0
Archivo: sopcast.c Proyecto: T-NOVA/vTC
static void ndpi_search_sopcast_tcp(struct ndpi_detection_module_struct
									  *ndpi_struct, struct ndpi_flow_struct *flow)
{

	struct ndpi_packet_struct *packet = &flow->packet;
	
	if (flow->packet_counter == 1 && packet->payload_packet_len == 54 && get_u_int16_t(packet->payload, 0) == ntohs(0x0036)) {
		if (ndpi_int_is_sopcast_tcp(packet->payload, packet->payload_packet_len)) {
			NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "found sopcast TCP \n");
			ndpi_int_sopcast_add_connection(ndpi_struct, flow);
			return;
		}
	}

	NDPI_LOG(NDPI_PROTOCOL_SOPCAST, ndpi_struct, NDPI_LOG_DEBUG, "exclude sopcast TCP.  \n");
	NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SOPCAST);


}
Ejemplo n.º 18
0
Archivo: bgp.c Proyecto: jnicholls/nDPI
/* this detection also works asymmetrically */
void ndpi_search_bgp(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 > 18 &&
            get_u_int64_t(packet->payload, 0) == 0xffffffffffffffffULL &&
            get_u_int64_t(packet->payload, 8) == 0xffffffffffffffffULL &&
            ntohs(get_u_int16_t(packet->payload, 16)) <= packet->payload_packet_len &&
            (packet->tcp->dest == htons(179) || packet->tcp->source == htons(179))
            && packet->payload[18] < 5) {
        NDPI_LOG(NDPI_PROTOCOL_BGP, ndpi_struct, NDPI_LOG_DEBUG, "BGP detected.\n");
        ndpi_int_bgp_add_connection(ndpi_struct, flow);
        return;
    }

    NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BGP);
}
Ejemplo n.º 19
0
Archivo: afp.c Proyecto: T-NOVA/vTC
void ndpi_search_afp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
  struct ndpi_packet_struct *packet = &flow->packet;
  //  struct ndpi_id_struct *src = flow->src;
//  struct ndpi_id_struct *dst = flow->dst;
  

	/*
	 * this will detect the OpenSession command of the Data Stream Interface (DSI) protocol
	 * which is exclusively used by the Apple Filing Protocol (AFP) on TCP/IP networks
	 */
	if (packet->payload_packet_len >= 22 && get_u_int16_t(packet->payload, 0) == htons(0x0004) &&
		get_u_int16_t(packet->payload, 2) == htons(0x0001) && get_u_int32_t(packet->payload, 4) == 0 &&
		get_u_int32_t(packet->payload, 8) == htonl(packet->payload_packet_len - 16) &&
		get_u_int32_t(packet->payload, 12) == 0 && get_u_int16_t(packet->payload, 16) == htons(0x0104)) {

		NDPI_LOG(NDPI_PROTOCOL_AFP, ndpi_struct, NDPI_LOG_DEBUG, "AFP: DSI OpenSession detected.\n");
		ndpi_int_afp_add_connection(ndpi_struct, flow);
		return;
	}

	/*
	 * detection of GetStatus command of DSI protocl
	 */
	if (packet->payload_packet_len >= 18 && get_u_int16_t(packet->payload, 0) == htons(0x0003) &&
		get_u_int16_t(packet->payload, 2) == htons(0x0001) && get_u_int32_t(packet->payload, 4) == 0 &&
		get_u_int32_t(packet->payload, 8) == htonl(packet->payload_packet_len - 16) &&
		get_u_int32_t(packet->payload, 12) == 0 && get_u_int16_t(packet->payload, 16) == htons(0x0f00)) {

		NDPI_LOG(NDPI_PROTOCOL_AFP, ndpi_struct, NDPI_LOG_DEBUG, "AFP: DSI GetStatus detected.\n");
		ndpi_int_afp_add_connection(ndpi_struct, flow);
		return;
	}


	NDPI_LOG(NDPI_PROTOCOL_AFP, ndpi_struct, NDPI_LOG_DEBUG, "AFP excluded.\n");
	NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_AFP);
}
Ejemplo n.º 20
0
void ndpi_search_gnutella(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 c;
  if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_GNUTELLA) {
    if (src != NULL && ((u_int32_t)
			(packet->tick_timestamp - src->gnutella_ts) < ndpi_struct->gnutella_timeout)) {
      NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct,
			NDPI_LOG_DEBUG, "gnutella : save src connection packet detected\n");
      src->gnutella_ts = packet->tick_timestamp;
    } else if (dst != NULL && ((u_int32_t)
			       (packet->tick_timestamp - dst->gnutella_ts) < ndpi_struct->gnutella_timeout)) {
      NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct,
			NDPI_LOG_DEBUG, "gnutella : save dst connection packet detected\n");
      dst->gnutella_ts = packet->tick_timestamp;
    }
    if (src != NULL && (packet->tick_timestamp - src->gnutella_ts) > ndpi_struct->gnutella_timeout) {
      src->detected_gnutella_udp_port1 = 0;
      src->detected_gnutella_udp_port2 = 0;
    }
    if (dst != NULL && (packet->tick_timestamp - dst->gnutella_ts) > ndpi_struct->gnutella_timeout) {
      dst->detected_gnutella_udp_port1 = 0;
      dst->detected_gnutella_udp_port2 = 0;
    }

    return;
  }

  /* skip packets without payload */
  if (packet->payload_packet_len < 2) {
    return;
  }
  if (packet->tcp != NULL) {
    /* this case works asymmetrically */
    if (packet->payload_packet_len > 10 && memcmp(packet->payload, "GNUTELLA/", 9) == 0) {
      NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "GNUTELLA DETECTED\n");
      ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      return;
    }
    /* this case works asymmetrically */
    if (packet->payload_packet_len > 17 && memcmp(packet->payload, "GNUTELLA CONNECT/", 17) == 0) {
      NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "GNUTELLA DETECTED\n");
      ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      return;
    }

    if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET /get/", 9) == 0)
					    || (memcmp(packet->payload, "GET /uri-res/", 13) == 0)
					    )) {
      ndpi_parse_packet_line_info(ndpi_struct, flow);
      for (c = 0; c < packet->parsed_lines; c++) {
	if ((packet->line[c].len > 19 && memcmp(packet->line[c].ptr, "User-Agent: Gnutella", 20) == 0)
	    || (packet->line[c].len > 10 && memcmp(packet->line[c].ptr, "X-Gnutella-", 11) == 0)
	    || (packet->line[c].len > 7 && memcmp(packet->line[c].ptr, "X-Queue:", 8) == 0)
	    || (packet->line[c].len > 36 && memcmp(packet->line[c].ptr,
						   "Content-Type: application/x-gnutella-", 37) == 0)) {
	  NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "DETECTED GNUTELLA GET.\n");
	  ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	  return;
	}
      }
    }
    if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET / HTTP", 9) == 0))) {
      ndpi_parse_packet_line_info(ndpi_struct, flow);
      if ((packet->user_agent_line.ptr != NULL && packet->user_agent_line.len > 15
	   && memcmp(packet->user_agent_line.ptr, "BearShare Lite ", 15) == 0)
	  || (packet->accept_line.ptr != NULL && packet->accept_line.len > 24
	      && memcmp(packet->accept_line.ptr, "application n/x-gnutella", 24) == 0)) {
	NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "DETECTED GNUTELLA GET.\n");
	ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
      }

    }
    /* haven't found this pattern in any trace. */
    if (packet->payload_packet_len > 50 && ((memcmp(packet->payload, "GET /get/", 9) == 0)
					    || (memcmp(packet->payload, "GET /uri-res/", 13) == 0))) {
      c = 8;
      while (c < (packet->payload_packet_len - 9)) {
	if (packet->payload[c] == '?')
	  break;
	c++;
      }

      if (c < (packet->payload_packet_len - 9) && memcmp(&packet->payload[c], "urn:sha1:", 9) == 0) {
	NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE,
		 "detected GET /get/ or GET /uri-res/.\n");
	ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
      }

    }

    /* answer to this packet is HTTP/1.1 ..... Content-Type: application/x-gnutella-packets,
     * it is searched in the upper paragraph. */
    if (packet->payload_packet_len > 30 && memcmp(packet->payload, "HEAD /gnutella/push-proxy?", 26) == 0) {
      NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected HEAD /gnutella/push-proxy?\n");
      ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
      return;
    }
    /* haven't found any trace with this pattern */
    if (packet->payload_packet_len == 46
	&& memcmp(packet->payload, "\x50\x55\x53\x48\x20\x67\x75\x69\x64\x3a", 10) == 0) {
      NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE,
	       "detected \x50\x55\x53\x48\x20\x67\x75\x69\x64\x3a\n");
      ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      return;
    }
    /* haven't found any trace with this pattern */
    if (packet->payload_packet_len > 250 && memcmp(packet->payload, "GET /gnutella/", 14) == 0)
      //PATTERN IS :: GET /gnutella/tigertree/v3?urn:tree:tiger/:
      {
	const u_int16_t end = packet->payload_packet_len - 3;

	c = 13;
	while (c < end) {
	  if ((memcmp(&packet->payload[14], "tigertree/", 10) == 0)
	      || (end - c > 18 && memcmp(&packet->payload[c], "\r\nUser-Agent: Foxy", 18) == 0)
	      || (end - c > 44
		  && memcmp(&packet->payload[c],
			    "\r\nAccept: application/tigertree-breadthfirst",
			    44) == 0) || (end - c > 10 && memcmp(&packet->payload[c], "\r\nX-Queue:", 10) == 0)
	      || (end - c > 13 && memcmp(&packet->payload[c], "\r\nX-Features:", 13) == 0)) {

	    NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA,
			      ndpi_struct, NDPI_LOG_TRACE, "FOXY :: GNUTELLA GET 2 DETECTED\n");
	    ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	    return;
	  }

	  c++;
	}
      }
    /* haven't found any trace with this pattern */
    if (packet->payload_packet_len > 1 && packet->payload[packet->payload_packet_len - 1] == 0x0a
	&& packet->payload[packet->payload_packet_len - 2] == 0x0a) {
      if (packet->payload_packet_len > 3 && memcmp(packet->payload, "GIV", 3) == 0) {
	NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "MORPHEUS GIV DETECTED\n");
	/* Not Excludeing the flow now.. We shall Check the next Packet too for Gnutella Patterns */
	return;
      }
    }
    /* might be super tricky new ssl gnutella transmission, but the certificate is strange... */
    if (packet->payload_packet_len == 46 && get_u_int32_t(packet->payload, 0) == htonl(0x802c0103) &&
	get_u_int32_t(packet->payload, 4) == htonl(0x01000300) && get_u_int32_t(packet->payload, 8) == htonl(0x00002000) &&
	get_u_int16_t(packet->payload, 12) == htons(0x0034)) {
      NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected gnutella len == 46.\n");
      ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      return;
    }
    if (packet->payload_packet_len == 49 &&
	memcmp(packet->payload, "\x80\x2f\x01\x03\x01\x00\x06\x00\x00\x00\x20\x00\x00\x34\x00\x00\xff\x4d\x6c",
	       19) == 0) {
      NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected gnutella len == 49.\n");
      ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      return;
    }
    if (packet->payload_packet_len == 89 && memcmp(&packet->payload[43], "\x20\x4d\x6c", 3) == 0 &&
	memcmp(packet->payload, "\x16\x03\x01\x00\x54\x01\x00\x00\x50\x03\x01\x4d\x6c", 13) == 0 &&
	memcmp(&packet->payload[76], "\x00\x02\x00\x34\x01\x00\x00\x05", 8) == 0) {
      NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE,
	       "detected gnutella asymmetrically len == 388.\n");
      ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      return;
    } else if (packet->payload_packet_len == 82) {
      if (get_u_int32_t(packet->payload, 0) == htonl(0x16030100)
	  && get_u_int32_t(packet->payload, 4) == htonl(0x4d010000)
	  && get_u_int16_t(packet->payload, 8) == htons(0x4903)
	  && get_u_int16_t(packet->payload, 76) == htons(0x0002)
	  && get_u_int32_t(packet->payload, 78) == htonl(0x00340100)) {
	NDPI_LOG(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_TRACE, "detected len == 82.\n");
	ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
	return;
      }
    }
  } else if (packet->udp != NULL) {
    if (src != NULL && (packet->udp->source == src->detected_gnutella_udp_port1 ||
			packet->udp->source == src->detected_gnutella_udp_port2) &&
	(packet->tick_timestamp - src->gnutella_ts) < ndpi_struct->gnutella_timeout) {
      NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG, "port based detection\n\n");
      ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
    }
    /* observations:
     * all the following patterns send out many packets which are the only ones of their flows,
     * often on the very beginning of the traces, or flows with many packets in one direction only.
     * but then suddenly, one gets an answer as you can see in netpeker-gnutella-rpc.pcap packet 11483.
     * Maybe gnutella tries to send out keys?
     */
    if (packet->payload_packet_len == 23 && packet->payload[15] == 0x00
	&& packet->payload[16] == 0x41 && packet->payload[17] == 0x01
	&& packet->payload[18] == 0x00 && packet->payload[19] == 0x00
	&& packet->payload[20] == 0x00 && packet->payload[21] == 0x00 && packet->payload[22] == 0x00) {
      NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG,
			"detected gnutella udp, len = 23.\n");
      ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);

      return;
    }
    if (packet->payload_packet_len == 35 && packet->payload[25] == 0x49
	&& packet->payload[26] == 0x50 && packet->payload[27] == 0x40
	&& packet->payload[28] == 0x83 && packet->payload[29] == 0x53
	&& packet->payload[30] == 0x43 && packet->payload[31] == 0x50 && packet->payload[32] == 0x41) {
      NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG,
			"detected gnutella udp, len = 35.\n");
      ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      return;
    }
    if (packet->payload_packet_len == 32
	&& (memcmp(&packet->payload[16], "\x31\x01\x00\x09\x00\x00\x00\x4c\x49\x4d\x45", 11) == 0)) {
      NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG,
			"detected gnutella udp, len = 32.\n");
      ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      return;
    }
    if (packet->payload_packet_len == 34 && (memcmp(&packet->payload[25], "SCP@", 4) == 0)
	&& (memcmp(&packet->payload[30], "DNA@", 4) == 0)) {
      NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG,
			"detected gnutella udp, len = 34.\n");
      ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      return;
    }
    if ((packet->payload_packet_len == 73 || packet->payload_packet_len == 96)
	&& memcmp(&packet->payload[32], "urn:sha1:", 9) == 0) {
      NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG,
			"detected gnutella udp, len = 73,96.\n");
      ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      return;
    }

    if (memcmp(packet->payload, "GND", 3) == 0) {
      if ((packet->payload_packet_len == 8 && (memcmp(&packet->payload[6], "\x01\x00", 2) == 0))
	  || (packet->payload_packet_len == 11 && (memcmp(&packet->payload[6], "\x01\x01\x08\x50\x49", 5)
						   == 0)) || (packet->payload_packet_len == 17
							      &&
							      (memcmp
							       (&packet->payload[6], "\x01\x01\x4c\x05\x50",
								5) == 0))
	  || (packet->payload_packet_len == 28
	      && (memcmp(&packet->payload[6], "\x01\x01\x54\x0f\x51\x4b\x52\x50\x06\x52", 10) == 0))
	  || (packet->payload_packet_len == 41
	      && (memcmp(&packet->payload[6], "\x01\x01\x5c\x1b\x50\x55\x53\x48\x48\x10", 10) == 0))
	  || (packet->payload_packet_len > 200 && packet->payload_packet_len < 300 && packet->payload[3] == 0x03)
	  || (packet->payload_packet_len > 300 && (packet->payload[3] == 0x01 || packet->payload[3] == 0x03))) {
	NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG,
			  "detected gnutella udp, GND.\n");
	ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
	return;
      }
    }

    if ((packet->payload_packet_len == 32)
	&& memcmp(&packet->payload[16], "\x31\x01\x00\x09\x00\x00\x00", 7) == 0) {
      NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG,
			"detected gnutella udp, len = 32 ii.\n");
      ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      return;
    }
    if ((packet->payload_packet_len == 23)
	&& memcmp(&packet->payload[16], "\x00\x01\x00\x00\x00\x00\x00", 7) == 0) {
      NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct, NDPI_LOG_DEBUG,
			"detected gnutella udp, len = 23 ii.\n");
      ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      return;
    }
  }
  //neonet detection follows

  /* haven't found any trace with this pattern */
  if (packet->tcp != NULL && ntohs(packet->tcp->source) >= 1024 && ntohs(packet->tcp->dest) >= 1024) {
    if (flow->l4.tcp.gnutella_stage == 0) {
      if (flow->packet_counter == 1
	  && (packet->payload_packet_len == 11
	      || packet->payload_packet_len == 33 || packet->payload_packet_len == 37)) {
	flow->l4.tcp.gnutella_msg_id[0] = packet->payload[4];
	flow->l4.tcp.gnutella_msg_id[1] = packet->payload[6];
	flow->l4.tcp.gnutella_msg_id[2] = packet->payload[8];
	flow->l4.tcp.gnutella_stage = 1 + packet->packet_direction;
	return;
      }
    } else if (flow->l4.tcp.gnutella_stage == 1 + packet->packet_direction) {
      if (flow->packet_counter == 2 && (packet->payload_packet_len == 33 || packet->payload_packet_len == 22)
	  && flow->l4.tcp.gnutella_msg_id[0] == packet->payload[0]
	  && flow->l4.tcp.gnutella_msg_id[1] == packet->payload[2]
	  && flow->l4.tcp.gnutella_msg_id[2] == packet->payload[4]
	  && NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_GNUTELLA)) {
	NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct,
			  NDPI_LOG_TRACE, "GNUTELLA DETECTED due to message ID match (NEONet protocol)\n");
	ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
	return;
      }
    } else if (flow->l4.tcp.gnutella_stage == 2 - packet->packet_direction) {
      if (flow->packet_counter == 2 && (packet->payload_packet_len == 10 || packet->payload_packet_len == 75)
	  && flow->l4.tcp.gnutella_msg_id[0] == packet->payload[0]
	  && flow->l4.tcp.gnutella_msg_id[1] == packet->payload[2]
	  && flow->l4.tcp.gnutella_msg_id[2] == packet->payload[4]
	  && NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_GNUTELLA)) {
	NDPI_LOG_GNUTELLA(NDPI_PROTOCOL_GNUTELLA, ndpi_struct,
			  NDPI_LOG_TRACE, "GNUTELLA DETECTED due to message ID match (NEONet protocol)\n");
	ndpi_int_gnutella_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
	return;
      }
    }
  }

  NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_GNUTELLA);
}
Ejemplo n.º 21
0
Archivo: rtp.c Proyecto: unusedPhD/ndpi
void ndpi_search_rtp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
  struct ndpi_packet_struct *packet = &flow->packet;
	

  if (packet->udp) {
    ndpi_rtp_search(ndpi_struct, flow, packet->payload, packet->payload_packet_len);
  } else if (packet->tcp) {

    /* skip special packets seen at yahoo traces */
    if (packet->payload_packet_len >= 20 && ntohs(get_u_int16_t(packet->payload, 2)) + 20 == packet->payload_packet_len &&
	packet->payload[0] == 0x90 && packet->payload[1] >= 0x01 && packet->payload[1] <= 0x07) {
      if (flow->packet_counter == 2)
	flow->l4.tcp.rtp_special_packets_seen = 1;
      NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG,
	       "skipping STUN-like, special yahoo packets with payload[0] == 0x90.\n");
      return;
    }
#ifdef NDPI_PROTOCOL_STUN
    /* TODO the rtp detection sometimes doesn't exclude rtp
     * so for TCP flows only run the detection if STUN has been
     * detected (or RTP is already detected)
     * If flows will be seen which start directly with RTP
     * we can remove this restriction
     */

    if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STUN
	|| packet->detected_protocol_stack[0] == NDPI_PROTOCOL_RTP) {

      /* RTP may be encapsulated in TCP packets */

      if (packet->payload_packet_len >= 2 && ntohs(get_u_int16_t(packet->payload, 0)) + 2 == packet->payload_packet_len) {

	/* TODO there could be several RTP packets in a single TCP packet so maybe the detection could be
	 * improved by checking only the RTP packet of given length */

	ndpi_rtp_search(ndpi_struct, flow, packet->payload + 2, packet->payload_packet_len - 2);

	return;
      }
    }
    if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN && flow->l4.tcp.rtp_special_packets_seen == 1) {

      if (packet->payload_packet_len >= 4 && ntohl(get_u_int32_t(packet->payload, 0)) + 4 == packet->payload_packet_len) {

	/* TODO there could be several RTP packets in a single TCP packet so maybe the detection could be
	 * improved by checking only the RTP packet of given length */

	ndpi_rtp_search(ndpi_struct, flow, packet->payload + 4, packet->payload_packet_len - 4);

	return;
      }
    }

    if (NDPI_FLOW_PROTOCOL_EXCLUDED(ndpi_struct, flow, NDPI_PROTOCOL_STUN)) {
      NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude rtp.\n");
      NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP);
    } else {
      NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "STUN not yet excluded, need next packet.\n");
    }
#else
    NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude rtp.\n");
    NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP);
#endif
  }
}
Ejemplo n.º 22
0
Archivo: rtp.c Proyecto: unusedPhD/ndpi
static void ndpi_rtp_search(struct ndpi_detection_module_struct *ndpi_struct,
			    struct ndpi_flow_struct *flow,
			    const u_int8_t * payload, const u_int16_t payload_len)
{
  struct ndpi_packet_struct *packet = &flow->packet;
	
  u_int8_t stage;
  u_int16_t seqnum = ntohs(get_u_int16_t(payload, 2));

  NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "search rtp.\n");

  if (payload_len == 4 && get_u_int32_t(packet->payload, 0) == 0 && flow->packet_counter < 8) {
    NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "need next packet, maybe ClearSea out calls.\n");
    return;
  }

  if (payload_len == 5 && memcmp(payload, "hello", 5) == 0) {
    NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG,
	     "need next packet, initial hello packet of SIP out calls.\n");
    return;
  }

  if (payload_len == 1 && payload[0] == 0) {
    NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG,
	     "need next packet, payload_packet_len == 1 && payload[0] == 0.\n");
    return;
  }

  if (payload_len == 3 && memcmp(payload, "png", 3) == 0) {
    /* weird packet found in Ninja GlobalIP trace */
    NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "skipping packet with len = 3 and png payload.\n");
    return;
  }

  if (payload_len < 12) {
    NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "minimal packet size for rtp packets: 12.\n");
    goto exclude_rtp;
  }

  if (payload_len == 12 && get_u_int32_t(payload, 0) == 0 && get_u_int32_t(payload, 4) == 0 && get_u_int32_t(payload, 8) == 0) {
    NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "skipping packet with len = 12 and only 0-bytes.\n");
    return;
  }

  if ((payload[0] & 0xc0) == 0xc0 || (payload[0] & 0xc0) == 0x40 || (payload[0] & 0xc0) == 0x00) {
    NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "version = 3 || 1 || 0, maybe first rtp packet.\n");
    return;
  }

  if ((payload[0] & 0xc0) != 0x80) {
    NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct,
	     NDPI_LOG_DEBUG, "rtp version must be 2, first two bits of a packets must be 10.\n");
    goto exclude_rtp;
  }

  /* rtp_payload_type are the last seven bits of the second byte */
  if (flow->rtp_payload_type[packet->packet_direction] != (payload[1] & 0x7F)) {
    NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "payload_type has changed, reset stages.\n");
    packet->packet_direction == 0 ? (flow->rtp_stage1 = 0) : (flow->rtp_stage2 = 0);
  }
  /* first bit of first byte is not part of payload_type */
  flow->rtp_payload_type[packet->packet_direction] = payload[1] & 0x7F;

  stage = (packet->packet_direction == 0 ? flow->rtp_stage1 : flow->rtp_stage2);

  if (stage > 0) {
    NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct,
	     NDPI_LOG_DEBUG, "stage = %u.\n", packet->packet_direction == 0 ? flow->rtp_stage1 : flow->rtp_stage2);
    if (flow->rtp_ssid[packet->packet_direction] != get_u_int32_t(payload, 8)) {
      NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "ssid has changed, goto exclude rtp.\n");
      goto exclude_rtp;
    }

    if (seqnum == flow->rtp_seqnum[packet->packet_direction]) {
      NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "maybe \"retransmission\", need next packet.\n");
      return;
    } else if ((u_int16_t) (seqnum - flow->rtp_seqnum[packet->packet_direction]) < RTP_MAX_OUT_OF_ORDER) {
      NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG,
	       "new packet has larger sequence number (within valid range)\n");
      update_seq(ndpi_struct, flow, packet->packet_direction, seqnum);
    } else if ((u_int16_t) (flow->rtp_seqnum[packet->packet_direction] - seqnum) < RTP_MAX_OUT_OF_ORDER) {
      NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG,
	       "new packet has smaller sequence number (within valid range)\n");
      init_seq(ndpi_struct, flow, packet->packet_direction, seqnum, 1);
    } else {
      NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG,
	       "sequence number diff is too big, goto exclude rtp.\n");
      goto exclude_rtp;
    }
  } else {
    NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct,
	     NDPI_LOG_DEBUG, "rtp_ssid[%u] = %u.\n", packet->packet_direction,
	     flow->rtp_ssid[packet->packet_direction]);
    flow->rtp_ssid[packet->packet_direction] = get_u_int32_t(payload, 8);
    if (flow->packet_counter < 3) {
      NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "packet_counter < 3, need next packet.\n");
    }
    init_seq(ndpi_struct, flow, packet->packet_direction, seqnum, 1);
  }
  if (seqnum <= 3) {
    NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct,
	     NDPI_LOG_DEBUG, "sequence_number = %u, too small, need next packet, return.\n", seqnum);
    return;
  }

  if (stage == 3) {
    NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "add connection I.\n");
    ndpi_int_rtp_add_connection(ndpi_struct, flow);
  } else {
    packet->packet_direction == 0 ? flow->rtp_stage1++ : flow->rtp_stage2++;
    NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "stage[%u]++; need next packet.\n",
	     packet->packet_direction);
  }
  return;

 exclude_rtp:
#ifdef NDPI_PROTOCOL_STUN
  if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_STUN
      || packet->real_protocol_read_only == NDPI_PROTOCOL_STUN) {
    NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "STUN: is detected, need next packet.\n");
    return;
  }
#endif							/*  NDPI_PROTOCOL_STUN */
  NDPI_LOG(NDPI_PROTOCOL_RTP, ndpi_struct, NDPI_LOG_DEBUG, "exclude rtp.\n");
  NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_RTP);
}
Ejemplo n.º 23
0
Archivo: stun.c Proyecto: T-NOVA/vTC
static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *ndpi_struct,
					   const u_int8_t * payload, const u_int16_t payload_length)
{
  u_int16_t a;


  if((payload_length > 13)
     && (strncmp((const char*)payload, (const char*)"RSP/", 4) == 0)
     && (strncmp((const char*)&payload[7], (const char*)" STUN_", 6) == 0)) {
    NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "Found stun.\n");
    return NDPI_IS_STUN;
  }

  /*
   * token list of message types and attribute types from
   * http://wwwbs1.informatik.htw-dresden.de/svortrag/i02/Schoene/stun/stun.html
   * the same list you can find in
   * https://summersoft.fay.ar.us/repos/ethereal/branches/redhat-9/ethereal-0.10.3-1/ethereal-0.10.3/packet-stun.c
   * token further message types and attributes from
   * http://www.freeswitch.org/docs/group__stun1.html
   * added further attributes observed
   * message types: 0x0001, 0x0101, 0x0111, 0x0002, 0x0102, 0x0112, 0x0003, 0x0103, 0x0004, 0x0104, 0x0114, 0x0115
   * attribute types: 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009,
   * 0x000a, 0x000b, 0c000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0020,
   * 0x0022, 0x0024, 0x8001, 0x8006, 0x8008, 0x8015, 0x8020, 0x8028, 0x802a, 0x8029, 0x8050, 0x8054, 0x8055
   *
   * 0x8003, 0x8004 used by facetime
   */

  if (payload_length >= 20 && ntohs(get_u_int16_t(payload, 2)) + 20 == payload_length &&
      ((payload[0] == 0x00 && (payload[1] >= 0x01 && payload[1] <= 0x04)) ||
       (payload[0] == 0x01 &&
	((payload[1] >= 0x01 && payload[1] <= 0x04) || (payload[1] >= 0x11 && payload[1] <= 0x15))))) {
    u_int8_t mod;
    u_int8_t old = 1;
    u_int8_t padding = 0;
    NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "len and type match.\n");

    if (payload_length == 20) {
      NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found stun.\n");
      return NDPI_IS_STUN;
    }

    a = 20;

    while (a < payload_length) {

      if (old && payload_length >= a + 4
	  &&
	  ((payload[a] == 0x00
	    && ((payload[a + 1] >= 0x01 && payload[a + 1] <= 0x16) || payload[a + 1] == 0x19
		|| payload[a + 1] == 0x20 || payload[a + 1] == 0x22 || payload[a + 1] == 0x24
		|| payload[a + 1] == 0x25))
	   || (payload[a] == 0x80
	       && (payload[a + 1] == 0x01 || payload[a + 1] == 0x03 || payload[a + 1] == 0x04
		   || payload[a + 1] == 0x06 || payload[a + 1] == 0x08 || payload[a + 1] == 0x15
		   || payload[a + 1] == 0x20 || payload[a + 1] == 0x22 || payload[a + 1] == 0x28
		   || payload[a + 1] == 0x2a || payload[a + 1] == 0x29 || payload[a + 1] == 0x50
		   || payload[a + 1] == 0x54 || payload[a + 1] == 0x55)))) {

	NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "attribute match.\n");

	a += ((payload[a + 2] << 8) + payload[a + 3] + 4);
	mod = a % 4;
	if (mod) {
	  padding = 4 - mod;
	}
	if (a == payload_length || (padding && (a + padding) == payload_length)) {
	  NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found stun.\n");
	  return NDPI_IS_STUN;
	}

      } else if (payload_length >= a + padding + 4
		 &&
		 ((payload[a + padding] == 0x00
		   && ((payload[a + 1 + padding] >= 0x01 && payload[a + 1 + padding] <= 0x16)
		       || payload[a + 1 + padding] == 0x19 || payload[a + 1 + padding] == 0x20
		       || payload[a + 1 + padding] == 0x22 || payload[a + 1 + padding] == 0x24
		       || payload[a + 1 + padding] == 0x25))
		  || (payload[a + padding] == 0x80
		      && (payload[a + 1 + padding] == 0x01 || payload[a + 1 + padding] == 0x03
			  || payload[a + 1 + padding] == 0x04 || payload[a + 1 + padding] == 0x06
			  || payload[a + 1 + padding] == 0x08 || payload[a + 1 + padding] == 0x15
			  || payload[a + 1 + padding] == 0x20 || payload[a + 1 + padding] == 0x22
			  || payload[a + 1 + padding] == 0x28 || payload[a + 1 + padding] == 0x2a
			  || payload[a + 1 + padding] == 0x29 || payload[a + 1 + padding] == 0x50
			  || payload[a + 1 + padding] == 0x54 || payload[a + 1 + padding] == 0x55)))) {

	NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "New STUN - attribute match.\n");

	old = 0;
	a += ((payload[a + 2 + padding] << 8) + payload[a + 3 + padding] + 4);
	padding = 0;
	mod = a % 4;
	if (mod) {
	  a += 4 - mod;
	}
	if (a == payload_length) {
	  NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found stun.\n");
	  return NDPI_IS_STUN;
	}
      } else {
	break;
      }
    }
  }

  return NDPI_IS_NOT_STUN;
}
Ejemplo n.º 24
0
void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
  struct ndpi_packet_struct *packet = &flow->packet;

  //      struct ndpi_id_struct         *src=flow->src;
  //      struct ndpi_id_struct         *dst=flow->dst;

  u_int8_t ret;

  if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) {
    if(flow->l4.tcp.ssl_stage == 3 && packet->payload_packet_len > 20 && flow->packet_counter < 5) {
      /* this should only happen, when we detected SSL with a packet that had parts of the certificate in subsequent packets
       * so go on checking for certificate patterns for a couple more packets
       */
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG,
	       "ssl flow but check another packet for patterns\n");
      ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow);
      if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) {
	/* still ssl so check another packet */
	return;
      } else {
	/* protocol has changed so we are done */
	return;
      }
    }
    return;
  }

  NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "search ssl\n");

  {
    /* Check if this is whatsapp first (this proto runs over port 443) */
    if((packet->payload_packet_len > 5)
       && ((packet->payload[0] == 'W')
	   && (packet->payload[1] == 'A')
	   && (packet->payload[4] == 0)
	   && (packet->payload[2] <= 9)
	   && (packet->payload[3] <= 9))) {
      ndpi_int_add_connection(ndpi_struct, flow, NDPI_SERVICE_WHATSAPP, NDPI_REAL_PROTOCOL);
      return;
    } else {
      /* No whatsapp, let's try SSL */
      if(sslDetectProtocolFromCertificate(ndpi_struct, flow) > 0)
	return;
    }
  }

  if(packet->payload_packet_len > 40 && flow->l4.tcp.ssl_stage == 0) {
    NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "first ssl packet\n");
    // SSLv2 Record
    if(packet->payload[2] == 0x01 && packet->payload[3] == 0x03
	&& (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02)
	&& (packet->payload_packet_len - packet->payload[1] == 2)) {
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv2 len match\n");
      flow->l4.tcp.ssl_stage = 1 + packet->packet_direction;
      return;
    }

    if(packet->payload[0] == 0x16 && packet->payload[1] == 0x03
	&& (packet->payload[2] == 0x00 || packet->payload[2] == 0x01 || packet->payload[2] == 0x02)
	&& (packet->payload_packet_len - ntohs(get_u_int16_t(packet->payload, 3)) == 5)) {
      // SSLv3 Record
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv3 len match\n");
      flow->l4.tcp.ssl_stage = 1 + packet->packet_direction;
      return;
    }
  }

  if(packet->payload_packet_len > 40 &&
      flow->l4.tcp.ssl_stage == 1 + packet->packet_direction
      && flow->packet_direction_counter[packet->packet_direction] < 5) {
    return;
  }

  if(packet->payload_packet_len > 40 && flow->l4.tcp.ssl_stage == 2 - packet->packet_direction) {
    NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "second ssl packet\n");
    // SSLv2 Record
    if(packet->payload[2] == 0x01 && packet->payload[3] == 0x03
	&& (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02)
	&& (packet->payload_packet_len - 2) >= packet->payload[1]) {
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv2 server len match\n");
      ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow);
      return;
    }

    ret = ndpi_search_sslv3_direction1(ndpi_struct, flow);
    if(ret == 1) {
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv3 server len match\n");
      ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow);
      return;
    } else if(ret == 2) {
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG,
	       "sslv3 server len match with split packet -> check some more packets for SSL patterns\n");
      ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow);
      if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) {
	flow->l4.tcp.ssl_stage = 3;
      }
      return;
    }

    if(packet->payload_packet_len > 40 && flow->packet_direction_counter[packet->packet_direction] < 5) {
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "need next packet\n");
      return;
    }
  }

  NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "exclude ssl\n");
  NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SSL);
  return;
}
Ejemplo n.º 25
0
static void ndpi_search_aimini(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_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "search aimini.\n");

	if (packet->udp != NULL) {
		if (flow->l4.udp.aimini_stage == 0) {
			if (packet->payload_packet_len == 64 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010b) {
				flow->l4.udp.aimini_stage = 1;
				NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 1.\n");
				return;
			}
			if (packet->payload_packet_len == 136
				&& (ntohs(get_u_int16_t(packet->payload, 0)) == 0x01c9 || ntohs(get_u_int16_t(packet->payload, 0)) == 0x0165)) {
				flow->l4.udp.aimini_stage = 4;
				NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 4.\n");
				return;
			}
			if (packet->payload_packet_len == 88 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0101) {
				flow->l4.udp.aimini_stage = 7;
				NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 7.\n");
				return;
			}
			if (packet->payload_packet_len == 104 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0102) {
				flow->l4.udp.aimini_stage = 10;
				NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 10.\n");
				return;
			}
			if (packet->payload_packet_len == 32 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca) {
				flow->l4.udp.aimini_stage = 13;
				NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 13.\n");
				return;
			}
			if (packet->payload_packet_len == 16 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010c) {
				flow->l4.udp.aimini_stage = 16;
				NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 16.\n");
				return;
			}
		}
		/* first packet chronology: (len, value): (64, 0x010b), (>100, 0x0115), (16, 0x010c || 64, 0x010b || 88, 0x0115),
		 * (16, 0x010c || 64, 0x010b || >100, 0x0115)
		 */
		if (flow->l4.udp.aimini_stage == 1 && packet->payload_packet_len > 100
			&& ntohs(get_u_int16_t(packet->payload, 0)) == 0x0115) {
			flow->l4.udp.aimini_stage = 2;
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 2.\n");
			return;
		}
		if (flow->l4.udp.aimini_stage == 2 &&
			((packet->payload_packet_len == 16 && get_u_int16_t(packet->payload, 0) == htons(0x010c)) ||
			 (packet->payload_packet_len == 64 && get_u_int16_t(packet->payload, 0) == htons(0x010b)) ||
			 (packet->payload_packet_len == 88 && get_u_int16_t(packet->payload, 0) == ntohs(0x0115)))) {
			flow->l4.udp.aimini_stage = 3;
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 3.\n");
			return;
		}
		if (flow->l4.udp.aimini_stage == 3
			&& ((packet->payload_packet_len == 16 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010c)
				|| (packet->payload_packet_len == 64 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010b)
				|| (packet->payload_packet_len > 100 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0115))) {
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "found aimini (64, 0x010b), (>300, 0x0115), "
					"(16, 0x010c || 64, 0x010b), (16, 0x010c || 64, 0x010b || >100, 0x0115).\n");
			ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
			return;
		}

		/* second packet chronology: (len, value): (136, 0x01c9), (136, 0x01c9),(136, 0x01c9),(136, 0x01c9 || 32, 0x01ca) */

		if (flow->l4.udp.aimini_stage == 4 && packet->payload_packet_len == 136
			&& (ntohs(get_u_int16_t(packet->payload, 0)) == 0x01c9 || ntohs(get_u_int16_t(packet->payload, 0)) == 0x0165)) {
			flow->l4.udp.aimini_stage = 5;
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 5.\n");
			return;
		}
		if (flow->l4.udp.aimini_stage == 5 && (packet->payload_packet_len == 136
											   && (ntohs(get_u_int16_t(packet->payload, 0)) == 0x01c9
												   || ntohs(get_u_int16_t(packet->payload, 0)) == 0x0165))) {
			flow->l4.udp.aimini_stage = 6;
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 6.\n");
			return;
		}
		if (flow->l4.udp.aimini_stage == 6 && ((packet->payload_packet_len == 136
												&& ((ntohs(get_u_int16_t(packet->payload, 0)) == 0x0165)
													|| ntohs(get_u_int16_t(packet->payload, 0)) == 0x01c9))
											   || (packet->payload_packet_len == 32
												   && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca))) {
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG,
					"found aimini (136, 0x01c9), (136, 0x01c9)," "(136, 0x01c9),(136, 0x01c9 || 32, 0x01ca).\n");
			ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
			return;
		}

		/* third packet chronology: (len, value): (88, 0x0101), (88, 0x0101),(88, 0x0101),(88, 0x0101) */

		if (flow->l4.udp.aimini_stage == 7 && packet->payload_packet_len == 88
			&& ntohs(get_u_int16_t(packet->payload, 0)) == 0x0101) {
			flow->l4.udp.aimini_stage = 8;
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 8.\n");
			return;
		}
		if (flow->l4.udp.aimini_stage == 8
			&& (packet->payload_packet_len == 88 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0101)) {
			flow->l4.udp.aimini_stage = 9;
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 9.\n");
			return;
		}
		if (flow->l4.udp.aimini_stage == 9
			&& (packet->payload_packet_len == 88 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0101)) {
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG,
					"found aimini (88, 0x0101), (88, 0x0101)," "(88, 0x0101),(88, 0x0101).\n");
			ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
			return;
		}

		/* fourth packet chronology: (len, value): (104, 0x0102), (104, 0x0102), (104, 0x0102), (104, 0x0102) */

		if (flow->l4.udp.aimini_stage == 10 && packet->payload_packet_len == 104
			&& ntohs(get_u_int16_t(packet->payload, 0)) == 0x0102) {
			flow->l4.udp.aimini_stage = 11;
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 11.\n");
			return;
		}
		if (flow->l4.udp.aimini_stage == 11
			&& (packet->payload_packet_len == 104 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0102)) {
			flow->l4.udp.aimini_stage = 12;
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 12.\n");
			return;
		}
		if (flow->l4.udp.aimini_stage == 12
			&& ((packet->payload_packet_len == 104 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0102)
				|| (packet->payload_packet_len == 32 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca))) {
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG,
					"found aimini (104, 0x0102), (104, 0x0102), " "(104, 0x0102), (104, 0x0102).\n");
			ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
			return;
		}

		/* fifth packet chronology (len, value): (32,0x01ca), (32,0x01ca), (32,0x01ca), ((136, 0x0166) || (32,0x01ca)) */

		if (flow->l4.udp.aimini_stage == 13 && packet->payload_packet_len == 32
			&& ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca) {
			flow->l4.udp.aimini_stage = 14;
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 14.\n");
			return;
		}
		if (flow->l4.udp.aimini_stage == 14
			&& ((packet->payload_packet_len == 32 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca)
				|| (packet->payload_packet_len == 136 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0166))) {
			flow->l4.udp.aimini_stage = 15;
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 15.\n");
			return;
		}
		if (flow->l4.udp.aimini_stage == 15
			&& ((packet->payload_packet_len == 136 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0166)
				|| (packet->payload_packet_len == 32 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x01ca))) {
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG,
					"found aimini (32,0x01ca), (32,0x01ca), (32,0x01ca), ((136, 0x0166)||(32,0x01ca)).\n");
			ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
			return;
		}

		/* sixth packet chronology (len, value): (16, 0x010c), (16, 0x010c), (16, 0x010c), (16, 0x010c) */

		if (flow->l4.udp.aimini_stage == 16 && packet->payload_packet_len == 16
			&& ntohs(get_u_int16_t(packet->payload, 0)) == 0x010c) {
			flow->l4.udp.aimini_stage = 17;
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 17.\n");
			return;
		}
		if (flow->l4.udp.aimini_stage == 17
			&& (packet->payload_packet_len == 16 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010c)) {
			flow->l4.udp.aimini_stage = 18;
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "stage = 18.\n");
			return;
		}
		if (flow->l4.udp.aimini_stage == 18
			&& (packet->payload_packet_len == 16 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x010c)) {
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG,
					"found aimini (16, 0x010c), (16, 0x010c), (16, 0x010c), (16, 0x010c).\n");
			ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
			return;
		}
	} else if (packet->tcp != NULL) {
		if ((packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /player/") &&
			 (memcmp(packet->payload, "GET /player/", NDPI_STATICSTRING_LEN("GET /player/")) == 0)) ||
			(packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /play/?fid=") &&
			 (memcmp(packet->payload, "GET /play/?fid=", NDPI_STATICSTRING_LEN("GET /play/?fid=")) == 0))) {
			NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "HTTP packet detected.\n");
			ndpi_parse_packet_line_info(ndpi_struct, flow);
			if (packet->host_line.ptr != NULL && packet->host_line.len > 11
				&& (memcmp(&packet->host_line.ptr[packet->host_line.len - 11], ".aimini.net", 11) == 0)) {
				NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "AIMINI HTTP traffic detected.\n");
				ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
				return;
			}
		}
		if (packet->payload_packet_len > 100) {
			if (memcmp(packet->payload, "GET /", NDPI_STATICSTRING_LEN("GET /")) == 0) {
				if (memcmp(&packet->payload[NDPI_STATICSTRING_LEN("GET /")], "play/",
						   NDPI_STATICSTRING_LEN("play/")) == 0 ||
					memcmp(&packet->payload[NDPI_STATICSTRING_LEN("GET /")], "download/",
						   NDPI_STATICSTRING_LEN("download/")) == 0) {
					ndpi_parse_packet_line_info(ndpi_struct, flow);
					if (is_special_aimini_host(packet->host_line) == 1) {
						NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG,
								"AIMINI HTTP traffic detected.\n");
						ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
						return;
					}
				}
			} else if (memcmp(packet->payload, "POST /", NDPI_STATICSTRING_LEN("POST /")) == 0) {
				if (memcmp(&packet->payload[NDPI_STATICSTRING_LEN("POST /")], "upload/",
						   NDPI_STATICSTRING_LEN("upload/")) == 0) {
					ndpi_parse_packet_line_info(ndpi_struct, flow);
					if (is_special_aimini_host(packet->host_line) == 1) {
						NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG,
								"AIMINI HTTP traffic detected.\n");
						ndpi_int_aimini_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
						return;
					}
				}
			}
		}
	}

	NDPI_LOG(NDPI_PROTOCOL_AIMINI, ndpi_struct, NDPI_LOG_DEBUG, "exclude aimini.\n");
	NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_AIMINI);

}
Ejemplo n.º 26
0
static u_int8_t ndpi_search_sslv3_direction1(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)
      && (packet->payload[0] == 0x16)
      && (packet->payload[1] == 0x03)
      && ((packet->payload[2] == 0x00)
	  || (packet->payload[2] == 0x01)
	  || (packet->payload[2] == 0x02)
	  || (packet->payload[2] == 0x03)
	  )) {
    u_int32_t temp;
    NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "search sslv3\n");
    // SSLv3 Record
    if(packet->payload_packet_len >= 1300) {
      return 1;
    }
    temp = ntohs(get_u_int16_t(packet->payload, 3)) + 5;
    NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp);
    if(packet->payload_packet_len == temp
	|| (temp < packet->payload_packet_len && packet->payload_packet_len > 500)) {
      return 1;
    }

    if(packet->payload_packet_len < temp && temp < 5000 && packet->payload_packet_len > 9) {
      /* the server hello may be split into small packets */
      u_int32_t cert_start;

      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG,
	       "maybe SSLv3 server hello split into smaller packets\n");

      /* lets hope at least the server hello and the start of the certificate block are in the first packet */
      cert_start = ntohs(get_u_int16_t(packet->payload, 7)) + 5 + 4;
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "suspected start of certificate: %u\n",
	       cert_start);

      if(cert_start < packet->payload_packet_len && packet->payload[cert_start] == 0x0b) {
	NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG,
		 "found 0x0b at suspected start of certificate block\n");
	return 2;
      }
    }

    if((packet->payload_packet_len > temp && packet->payload_packet_len > 100) && packet->payload_packet_len > 9) {
      /* the server hello may be split into small packets and the certificate has its own SSL Record
       * so temp contains only the length for the first ServerHello block */
      u_int32_t cert_start;

      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG,
	       "maybe SSLv3 server hello split into smaller packets but with seperate record for the certificate\n");

      /* lets hope at least the server hello record and the start of the certificate record are in the first packet */
      cert_start = ntohs(get_u_int16_t(packet->payload, 7)) + 5 + 5 + 4;
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "suspected start of certificate: %u\n",
	       cert_start);

      if(cert_start < packet->payload_packet_len && packet->payload[cert_start] == 0x0b) {
	NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG,
		 "found 0x0b at suspected start of certificate block\n");
	return 2;
      }
    }


    if(packet->payload_packet_len >= temp + 5 && (packet->payload[temp] == 0x14 || packet->payload[temp] == 0x16)
	&& packet->payload[temp + 1] == 0x03) {
      u_int32_t temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5;
      if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) {
	return 1;
      }
      temp += temp2;
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp);
      if(packet->payload_packet_len == temp) {
	return 1;
      }
      if(packet->payload_packet_len >= temp + 5 &&
	  packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) {
	temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5;
	if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) {
	  return 1;
	}
	temp += temp2;
	NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp);
	if(packet->payload_packet_len == temp) {
	  return 1;
	}
	if(packet->payload_packet_len >= temp + 5 &&
	    packet->payload[temp] == 0x16 && packet->payload[temp + 1] == 0x03) {
	  temp2 = ntohs(get_u_int16_t(packet->payload, temp + 3)) + 5;
	  if(temp + temp2 > NDPI_MAX_SSL_REQUEST_SIZE) {
	    return 1;
	  }
	  temp += temp2;
	  NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "temp = %u.\n", temp);
	  if(temp == packet->payload_packet_len) {
	    return 1;
	  }
	}
      }
    }
  }

  return 0;
}
Ejemplo n.º 27
0
static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *ndpi_struct,
					   struct ndpi_flow_struct *flow,
					   const u_int8_t * payload, 
					   const u_int16_t payload_length,
					   u_int8_t *is_whatsapp)
{
  u_int16_t msg_type, msg_len;
  struct stun_packet_header *h = (struct stun_packet_header*)payload;

  if(payload_length < sizeof(struct stun_packet_header))
    return(NDPI_IS_NOT_STUN);

  if((strncmp((const char*)payload, (const char*)"RSP/", 4) == 0)
     && (strncmp((const char*)&payload[7], (const char*)" STUN_", 6) == 0)) {
    NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "Found stun.\n");
    goto udp_stun_found;
  }
  
  msg_type = ntohs(h->msg_type) & 0x3EEF, msg_len = ntohs(h->msg_len);

  if((payload_length == (msg_len+20))
     && ((msg_type <= 0x000b) /* http://www.3cx.com/blog/voip-howto/stun-details/ */))
    goto udp_stun_found;

#ifdef ORIGINAL_CODE
  /*
   * token list of message types and attribute types from
   * http://wwwbs1.informatik.htw-dresden.de/svortrag/i02/Schoene/stun/stun.html
   * the same list you can find in
   * https://summersoft.fay.ar.us/repos/ethereal/branches/redhat-9/ethereal-0.10.3-1/ethereal-0.10.3/packet-stun.c
   * token further message types and attributes from
   * http://www.freeswitch.org/docs/group__stun1.html
   * added further attributes observed
   * message types: 0x0001, 0x0101, 0x0111, 0x0002, 0x0102, 0x0112, 0x0003, 0x0103, 0x0004, 0x0104, 0x0114, 0x0115
   * attribute types: 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009,
   * 0x000a, 0x000b, 0c000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0020,
   * 0x0022, 0x0024, 0x8001, 0x8006, 0x8008, 0x8015, 0x8020, 0x8028, 0x802a, 0x8029, 0x8050, 0x8054, 0x8055
   *
   * 0x8003, 0x8004 used by facetime
   */

  if(payload_length >= 20 && ntohs(get_u_int16_t(payload, 2)) + 20 == payload_length &&
      ((payload[0] == 0x00 && (payload[1] >= 0x01 && payload[1] <= 0x04)) ||
       (payload[0] == 0x01 &&
	((payload[1] >= 0x01 && payload[1] <= 0x04) || (payload[1] >= 0x11 && payload[1] <= 0x15))))) {
    u_int8_t mod;
    u_int8_t old = 1;
    u_int8_t padding = 0;
    NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "len and type match.\n");

    if(payload_length == 20) {
      NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found stun.\n");
      goto udp_stun_found;
    }

    a = 20;

    while (a < payload_length) {

      if(old && payload_length >= a + 4
	  &&
	  ((payload[a] == 0x00
	    && ((payload[a + 1] >= 0x01 && payload[a + 1] <= 0x16) || payload[a + 1] == 0x19
		|| payload[a + 1] == 0x20 || payload[a + 1] == 0x22 || payload[a + 1] == 0x24
		|| payload[a + 1] == 0x25))
	   || (payload[a] == 0x80
	       && (payload[a + 1] == 0x01 || payload[a + 1] == 0x03 || payload[a + 1] == 0x04
		   || payload[a + 1] == 0x06 || payload[a + 1] == 0x08 || payload[a + 1] == 0x15
		   || payload[a + 1] == 0x20 || payload[a + 1] == 0x22 || payload[a + 1] == 0x28
		   || payload[a + 1] == 0x2a || payload[a + 1] == 0x29 || payload[a + 1] == 0x50
		   || payload[a + 1] == 0x54 || payload[a + 1] == 0x55)))) {

	NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "attribute match.\n");

	a += ((payload[a + 2] << 8) + payload[a + 3] + 4);
	mod = a % 4;
	if(mod) {
	  padding = 4 - mod;
	}
	if(a == payload_length || (padding && (a + padding) == payload_length)) {
	  NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found stun.\n");
	  goto udp_stun_found;
	}

      } else if(payload_length >= a + padding + 4
		&&
		 ((payload[a + padding] == 0x00
		   && ((payload[a + 1 + padding] >= 0x01 && payload[a + 1 + padding] <= 0x16)
		       || payload[a + 1 + padding] == 0x19 || payload[a + 1 + padding] == 0x20
		       || payload[a + 1 + padding] == 0x22 || payload[a + 1 + padding] == 0x24
		       || payload[a + 1 + padding] == 0x25))
		  || (payload[a + padding] == 0x80
		      && (payload[a + 1 + padding] == 0x01 || payload[a + 1 + padding] == 0x03
			  || payload[a + 1 + padding] == 0x04 || payload[a + 1 + padding] == 0x06
			  || payload[a + 1 + padding] == 0x08 || payload[a + 1 + padding] == 0x15
			  || payload[a + 1 + padding] == 0x20 || payload[a + 1 + padding] == 0x22
			  || payload[a + 1 + padding] == 0x28 || payload[a + 1 + padding] == 0x2a
			  || payload[a + 1 + padding] == 0x29 || payload[a + 1 + padding] == 0x50
			  || payload[a + 1 + padding] == 0x54 || payload[a + 1 + padding] == 0x55))
		  || ((payload[a + padding] == 0x40) && (payload[a + padding + 1] == 0x00))
		  )) {
	if((payload[a + padding] == 0x40) && (payload[a + padding + 1] == 0x00))
	  goto udp_stun_found;

	NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "New STUN - attribute match.\n");

	old = 0;
	a += ((payload[a + 2 + padding] << 8) + payload[a + 3 + padding] + 4);
	padding = 0;
	mod = a % 4;
	if(mod) {
	  a += 4 - mod;
	}
	if(a == payload_length) {
	  NDPI_LOG(NDPI_PROTOCOL_STUN, ndpi_struct, NDPI_LOG_DEBUG, "found stun.\n");
	  goto udp_stun_found;
	}
      } else {
	break;
      }
    }
  }
#endif


  if((flow->num_stun_udp_pkts > 0) && ((payload[0] == 0x80) || (payload[0] == 0x81))) {
    *is_whatsapp = 1;
    return NDPI_IS_STUN; /* This is WhatsApp Voice */
  } else
    return NDPI_IS_NOT_STUN;

 udp_stun_found:
  flow->num_stun_udp_pkts++;
    
  return((flow->num_stun_udp_pkts < MAX_NUM_STUN_PKTS) ? NDPI_IS_NOT_STUN : NDPI_IS_STUN);
}
Ejemplo n.º 28
0
static void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
	struct ndpi_packet_struct *packet = &flow->packet;
	

	u_int16_t i = 0;
	u_int16_t space_pos = 0;
	u_int16_t command_start = 0;
	u_int8_t saw_command = 0;
	const u_int8_t *command = 0;


	NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, "search IMAP.\n");



	if (packet->payload_packet_len >= 4 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) {
		// the DONE command appears without a tag
		if (packet->payload_packet_len == 6 && ((packet->payload[0] == 'D' || packet->payload[0] == 'd')
												&& (packet->payload[1] == 'O' || packet->payload[1] == 'o')
												&& (packet->payload[2] == 'N' || packet->payload[2] == 'n')
												&& (packet->payload[3] == 'E' || packet->payload[3] == 'e'))) {
			flow->l4.tcp.mail_imap_stage += 1;
			saw_command = 1;
		} else {

			if (flow->l4.tcp.mail_imap_stage < 4) {
				// search for the first space character (end of the tag)
				while (i < 20 && i < packet->payload_packet_len) {
					if (i > 0 && packet->payload[i] == ' ') {
						space_pos = i;
						break;
					}
					if (!((packet->payload[i] >= 'a' && packet->payload[i] <= 'z') ||
						  (packet->payload[i] >= 'A' && packet->payload[i] <= 'Z') ||
						  (packet->payload[i] >= '0' && packet->payload[i] <= '9') || packet->payload[i] == '*')) {
						goto imap_excluded;
					}
					i++;
				}
				if (space_pos == 0 || space_pos == (packet->payload_packet_len - 1)) {
					goto imap_excluded;
				}
				// now walk over a possible mail number to the next space
				i++;
				if (i < packet->payload_packet_len && (packet->payload[i] >= '0' && packet->payload[i] <= '9')) {
					while (i < 20 && i < packet->payload_packet_len) {
						if (i > 0 && packet->payload[i] == ' ') {
							space_pos = i;
							break;
						}
						if (!(packet->payload[i] >= '0' && packet->payload[i] <= '9')) {
							goto imap_excluded;
						}
						i++;
					}
					if (space_pos == 0 || space_pos == (packet->payload_packet_len - 1)) {
						goto imap_excluded;
					}
				}
				command_start = space_pos + 1;
				command = &(packet->payload[command_start]);
			} else {
				command_start = 0;
				command = &(packet->payload[command_start]);
			}

			if ((command_start + 3) < packet->payload_packet_len) {
				if ((packet->payload[command_start] == 'O' || packet->payload[command_start] == 'o')
					&& (packet->payload[command_start + 1] == 'K' || packet->payload[command_start + 1] == 'k')
					&& packet->payload[command_start + 2] == ' ') {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				} else if ((packet->payload[command_start] == 'U' || packet->payload[command_start] == 'u')
						   && (packet->payload[command_start + 1] == 'I' || packet->payload[command_start + 1] == 'i')
						   && (packet->payload[command_start + 2] == 'D' || packet->payload[command_start + 2] == 'd')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				}
			}
			if ((command_start + 10) < packet->payload_packet_len) {
				if ((packet->payload[command_start] == 'C' || packet->payload[command_start] == 'c')
					&& (packet->payload[command_start + 1] == 'A' || packet->payload[command_start + 1] == 'a')
					&& (packet->payload[command_start + 2] == 'P' || packet->payload[command_start + 2] == 'p')
					&& (packet->payload[command_start + 3] == 'A' || packet->payload[command_start + 3] == 'a')
					&& (packet->payload[command_start + 4] == 'B' || packet->payload[command_start + 4] == 'b')
					&& (packet->payload[command_start + 5] == 'I' || packet->payload[command_start + 5] == 'i')
					&& (packet->payload[command_start + 6] == 'L' || packet->payload[command_start + 6] == 'l')
					&& (packet->payload[command_start + 7] == 'I' || packet->payload[command_start + 7] == 'i')
					&& (packet->payload[command_start + 8] == 'T' || packet->payload[command_start + 8] == 't')
					&& (packet->payload[command_start + 9] == 'Y' || packet->payload[command_start + 9] == 'y')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				}
			}
			if ((command_start + 8) < packet->payload_packet_len) {
				if ((packet->payload[command_start] == 'S' || packet->payload[command_start] == 's')
					&& (packet->payload[command_start + 1] == 'T' || packet->payload[command_start + 1] == 't')
					&& (packet->payload[command_start + 2] == 'A' || packet->payload[command_start + 2] == 'a')
					&& (packet->payload[command_start + 3] == 'R' || packet->payload[command_start + 3] == 'r')
					&& (packet->payload[command_start + 4] == 'T' || packet->payload[command_start + 4] == 't')
					&& (packet->payload[command_start + 5] == 'T' || packet->payload[command_start + 5] == 't')
					&& (packet->payload[command_start + 6] == 'L' || packet->payload[command_start + 6] == 'l')
					&& (packet->payload[command_start + 7] == 'S' || packet->payload[command_start + 7] == 's')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				}
			}
			if ((command_start + 5) < packet->payload_packet_len) {
				if ((packet->payload[command_start] == 'L' || packet->payload[command_start] == 'l')
					&& (packet->payload[command_start + 1] == 'O' || packet->payload[command_start + 1] == 'o')
					&& (packet->payload[command_start + 2] == 'G' || packet->payload[command_start + 2] == 'g')
					&& (packet->payload[command_start + 3] == 'I' || packet->payload[command_start + 3] == 'i')
					&& (packet->payload[command_start + 4] == 'N' || packet->payload[command_start + 4] == 'n')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				} else if ((packet->payload[command_start] == 'F' || packet->payload[command_start] == 'f')
						   && (packet->payload[command_start + 1] == 'E' || packet->payload[command_start + 1] == 'e')
						   && (packet->payload[command_start + 2] == 'T' || packet->payload[command_start + 2] == 't')
						   && (packet->payload[command_start + 3] == 'C' || packet->payload[command_start + 3] == 'c')
						   && (packet->payload[command_start + 4] == 'H' || packet->payload[command_start + 4] == 'h')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				} else if ((packet->payload[command_start] == 'F' || packet->payload[command_start] == 'f')
						   && (packet->payload[command_start + 1] == 'L' || packet->payload[command_start + 1] == 'l')
						   && (packet->payload[command_start + 2] == 'A' || packet->payload[command_start + 2] == 'a')
						   && (packet->payload[command_start + 3] == 'G' || packet->payload[command_start + 3] == 'g')
						   && (packet->payload[command_start + 4] == 'S' || packet->payload[command_start + 4] == 's')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				} else if ((packet->payload[command_start] == 'C' || packet->payload[command_start] == 'c')
						   && (packet->payload[command_start + 1] == 'H' || packet->payload[command_start + 1] == 'h')
						   && (packet->payload[command_start + 2] == 'E' || packet->payload[command_start + 2] == 'e')
						   && (packet->payload[command_start + 3] == 'C' || packet->payload[command_start + 3] == 'c')
						   && (packet->payload[command_start + 4] == 'K' || packet->payload[command_start + 4] == 'k')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				} else if ((packet->payload[command_start] == 'S' || packet->payload[command_start] == 's')
						   && (packet->payload[command_start + 1] == 'T' || packet->payload[command_start + 1] == 't')
						   && (packet->payload[command_start + 2] == 'O' || packet->payload[command_start + 2] == 'o')
						   && (packet->payload[command_start + 3] == 'R' || packet->payload[command_start + 3] == 'r')
						   && (packet->payload[command_start + 4] == 'E' || packet->payload[command_start + 4] == 'e')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				}
			}
			if ((command_start + 12) < packet->payload_packet_len) {
				if ((packet->payload[command_start] == 'A' || packet->payload[command_start] == 'a')
					&& (packet->payload[command_start + 1] == 'U' || packet->payload[command_start + 1] == 'u')
					&& (packet->payload[command_start + 2] == 'T' || packet->payload[command_start + 2] == 't')
					&& (packet->payload[command_start + 3] == 'H' || packet->payload[command_start + 3] == 'h')
					&& (packet->payload[command_start + 4] == 'E' || packet->payload[command_start + 4] == 'e')
					&& (packet->payload[command_start + 5] == 'N' || packet->payload[command_start + 5] == 'n')
					&& (packet->payload[command_start + 6] == 'T' || packet->payload[command_start + 6] == 't')
					&& (packet->payload[command_start + 7] == 'I' || packet->payload[command_start + 7] == 'i')
					&& (packet->payload[command_start + 8] == 'C' || packet->payload[command_start + 8] == 'c')
					&& (packet->payload[command_start + 9] == 'A' || packet->payload[command_start + 9] == 'a')
					&& (packet->payload[command_start + 10] == 'T' || packet->payload[command_start + 10] == 't')
					&& (packet->payload[command_start + 11] == 'E' || packet->payload[command_start + 11] == 'e')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				}
			}
			if ((command_start + 9) < packet->payload_packet_len) {
				if ((packet->payload[command_start] == 'N' || packet->payload[command_start] == 'n')
					&& (packet->payload[command_start + 1] == 'A' || packet->payload[command_start + 1] == 'a')
					&& (packet->payload[command_start + 2] == 'M' || packet->payload[command_start + 2] == 'm')
					&& (packet->payload[command_start + 3] == 'E' || packet->payload[command_start + 3] == 'e')
					&& (packet->payload[command_start + 4] == 'S' || packet->payload[command_start + 4] == 's')
					&& (packet->payload[command_start + 5] == 'P' || packet->payload[command_start + 5] == 'p')
					&& (packet->payload[command_start + 6] == 'A' || packet->payload[command_start + 6] == 'a')
					&& (packet->payload[command_start + 7] == 'C' || packet->payload[command_start + 7] == 'c')
					&& (packet->payload[command_start + 8] == 'E' || packet->payload[command_start + 8] == 'e')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				}
			}
			if ((command_start + 4) < packet->payload_packet_len) {
				if ((packet->payload[command_start] == 'L' || packet->payload[command_start] == 'l')
					&& (packet->payload[command_start + 1] == 'S' || packet->payload[command_start + 1] == 's')
					&& (packet->payload[command_start + 2] == 'U' || packet->payload[command_start + 2] == 'u')
					&& (packet->payload[command_start + 3] == 'B' || packet->payload[command_start + 3] == 'b')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				} else if ((packet->payload[command_start] == 'L' || packet->payload[command_start] == 'l')
						   && (packet->payload[command_start + 1] == 'I' || packet->payload[command_start + 1] == 'i')
						   && (packet->payload[command_start + 2] == 'S' || packet->payload[command_start + 2] == 's')
						   && (packet->payload[command_start + 3] == 'T' || packet->payload[command_start + 3] == 't')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				} else if ((packet->payload[command_start] == 'N' || packet->payload[command_start] == 'n')
						   && (packet->payload[command_start + 1] == 'O' || packet->payload[command_start + 1] == 'o')
						   && (packet->payload[command_start + 2] == 'O' || packet->payload[command_start + 2] == 'o')
						   && (packet->payload[command_start + 3] == 'P' || packet->payload[command_start + 3] == 'p')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				} else if ((packet->payload[command_start] == 'I' || packet->payload[command_start] == 'i')
						   && (packet->payload[command_start + 1] == 'D' || packet->payload[command_start + 1] == 'd')
						   && (packet->payload[command_start + 2] == 'L' || packet->payload[command_start + 2] == 'l')
						   && (packet->payload[command_start + 3] == 'E' || packet->payload[command_start + 3] == 'e')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				}
			}
			if ((command_start + 6) < packet->payload_packet_len) {
				if ((packet->payload[command_start] == 'S' || packet->payload[command_start] == 's')
					&& (packet->payload[command_start + 1] == 'E' || packet->payload[command_start + 1] == 'e')
					&& (packet->payload[command_start + 2] == 'L' || packet->payload[command_start + 2] == 'l')
					&& (packet->payload[command_start + 3] == 'E' || packet->payload[command_start + 3] == 'e')
					&& (packet->payload[command_start + 4] == 'C' || packet->payload[command_start + 4] == 'c')
					&& (packet->payload[command_start + 5] == 'T' || packet->payload[command_start + 5] == 't')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				} else if ((packet->payload[command_start] == 'E' || packet->payload[command_start] == 'e')
						   && (packet->payload[command_start + 1] == 'X' || packet->payload[command_start + 1] == 'x')
						   && (packet->payload[command_start + 2] == 'I' || packet->payload[command_start + 2] == 'i')
						   && (packet->payload[command_start + 3] == 'S' || packet->payload[command_start + 3] == 's')
						   && (packet->payload[command_start + 4] == 'T' || packet->payload[command_start + 4] == 't')
						   && (packet->payload[command_start + 5] == 'S' || packet->payload[command_start + 5] == 's')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				} else if ((packet->payload[command_start] == 'A' || packet->payload[command_start] == 'a')
						   && (packet->payload[command_start + 1] == 'P' || packet->payload[command_start + 1] == 'p')
						   && (packet->payload[command_start + 2] == 'P' || packet->payload[command_start + 2] == 'p')
						   && (packet->payload[command_start + 3] == 'E' || packet->payload[command_start + 3] == 'e')
						   && (packet->payload[command_start + 4] == 'N' || packet->payload[command_start + 4] == 'n')
						   && (packet->payload[command_start + 5] == 'D' || packet->payload[command_start + 5] == 'd')) {
					flow->l4.tcp.mail_imap_stage += 1;
					saw_command = 1;
				}
			}

		}

		if (saw_command == 1) {
			if (flow->l4.tcp.mail_imap_stage == 3 || flow->l4.tcp.mail_imap_stage == 5) {
				NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, "mail imap identified\n");
				ndpi_int_mail_imap_add_connection(ndpi_struct, flow);
				return;
			}
		}
	}

	if (packet->payload_packet_len > 1 && packet->payload[packet->payload_packet_len - 1] == ' ') {
		NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG,
				"maybe a split imap command -> need next packet and imap_stage is set to 4.\n");
		flow->l4.tcp.mail_imap_stage = 4;
		return;
	}

  imap_excluded:

	// skip over possible authentication hashes etc. that cannot be identified as imap commands or responses
	// if the packet count is low enough and at least one command or response was seen before
	if ((packet->payload_packet_len >= 2 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a)
		&& flow->packet_counter < 6 && flow->l4.tcp.mail_imap_stage >= 1) {
		NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG,
				"no imap command or response but packet count < 6 and imap stage >= 1 -> skip\n");
		return;
	}

	NDPI_LOG(NDPI_PROTOCOL_MAIL_IMAP, ndpi_struct, NDPI_LOG_DEBUG, "exclude IMAP.\n");
	NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MAIL_IMAP);
}
Ejemplo n.º 29
0
static void ndpi_search_oscar_tcp_connect(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 >= 10 && packet->payload[0] == 0x2a) {

    /* if is a oscar connection, 10 bytes long */

    /* OSCAR Connection :: Connection detected at initial packets only
     * +----+----+------+------+---------------+
     * |0x2a|Code|SeqNum|PktLen|ProtcolVersion |
     * +----+----+------+------+---------------+
     * Code 1 Byte : 0x01 Oscar Connection
     * SeqNum and PktLen are 2 Bytes each and ProtcolVersion: 0x00000001
     * */
    if (get_u_int8_t(packet->payload, 1) == 0x01 && get_u_int16_t(packet->payload, 4) == htons(packet->payload_packet_len - 6)
	&& get_u_int32_t(packet->payload, 6) == htonl(0x0000000001)) {
      NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR Connection FOUND \n");
      ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      return;
    }

    /* OSCAR IM
     * +----+----+------+------+----------+-----------+
     * |0x2a|Code|SeqNum|PktLen|FNACfamily|FNACsubtype|
     * +----+----+------+------+----------+-----------+
     * Code 1 Byte : 0x02 SNAC Header Code;
     * SeqNum and PktLen are 2 Bytes each
     * FNACfamily   2 Byte : 0x0004 IM Messaging
     * FNACEsubtype 2 Byte : 0x0006 IM Outgoing Message, 0x000c IM Message Acknowledgment
     * */
    if (packet->payload[1] == 0x02
	&& ntohs(get_u_int16_t(packet->payload, 4)) >=
	packet->payload_packet_len - 6 && get_u_int16_t(packet->payload, 6) == htons(0x0004)
	&& (get_u_int16_t(packet->payload, 8) == htons(0x0006)
	    || get_u_int16_t(packet->payload, 8) == htons(0x000c))) {
      NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR IM Detected \n");
      ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      return;
    }
  }


  /* detect http connections */
  if (packet->payload_packet_len >= 18) {
    if ((packet->payload[0] == 'P') && (memcmp(packet->payload, "POST /photo/upload", 18) == 0)) {
      NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow, packet);
      if (packet->host_line.len >= 18 && packet->host_line.ptr != NULL) {
	if (memcmp(packet->host_line.ptr, "lifestream.aol.com", 18) == 0) {
	  NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG,
		   "OSCAR over HTTP found, POST method\n");
	  ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	  return;
	}
      }
    }
  }
  if (packet->payload_packet_len > 40) {
    if ((packet->payload[0] == 'G') && (memcmp(packet->payload, "GET /", 5) == 0)) {
      if ((memcmp(&packet->payload[5], "aim/fetchEvents?aimsid=", 23) == 0) ||
	  (memcmp(&packet->payload[5], "aim/startSession?", 17) == 0) ||
	  (memcmp(&packet->payload[5], "aim/gromit/aim_express", 22) == 0) ||
	  (memcmp(&packet->payload[5], "b/ss/aolwpaim", 13) == 0) ||
	  (memcmp(&packet->payload[5], "hss/storage/aimtmpshare", 23) == 0)) {
	NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR over HTTP found, GET /aim/\n");
	ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	return;
      }

      if ((memcmp(&packet->payload[5], "aim", 3) == 0) || (memcmp(&packet->payload[5], "im", 2) == 0)) {
	NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow, packet);
	if (packet->user_agent_line.len > 15 && packet->user_agent_line.ptr != NULL &&
	    ((memcmp(packet->user_agent_line.ptr, "mobileAIM/", 10) == 0) ||
	     (memcmp(packet->user_agent_line.ptr, "ICQ/", 4) == 0) ||
	     (memcmp(packet->user_agent_line.ptr, "mobileICQ/", 10) == 0) ||
	     (memcmp(packet->user_agent_line.ptr, "AIM%20Free/", NDPI_STATICSTRING_LEN("AIM%20Free/")) == 0) ||
	     (memcmp(packet->user_agent_line.ptr, "AIM/", 4) == 0))) {
	  NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR over HTTP found\n");
	  ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	  return;
	}
      }
      NDPI_PARSE_PACKET_LINE_INFO(ndpi_struct, flow, packet);
      if (packet->referer_line.ptr != NULL && packet->referer_line.len >= 22) {

	if (memcmp(&packet->referer_line.ptr[packet->referer_line.len - NDPI_STATICSTRING_LEN("WidgetMain.swf")],
		   "WidgetMain.swf", NDPI_STATICSTRING_LEN("WidgetMain.swf")) == 0) {
	  u_int16_t i;
	  for (i = 0; i < (packet->referer_line.len - 22); i++) {
	    if (packet->referer_line.ptr[i] == 'a') {
	      if (memcmp(&packet->referer_line.ptr[i + 1], "im/gromit/aim_express", 21) == 0) {
		NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG,
			 "OSCAR over HTTP found : aim/gromit/aim_express\n");
		ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
		return;
	      }
	    }
	  }
	}
      }
    }
    if (memcmp(packet->payload, "CONNECT ", 8) == 0) {
      if (memcmp(packet->payload, "CONNECT login.icq.com:443 HTTP/1.", 33) == 0) {
	NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR ICQ-HTTP FOUND\n");
	ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	return;
      }
      if (memcmp(packet->payload, "CONNECT login.oscar.aol.com:5190 HTTP/1.", 40) == 0) {
	NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR AIM-HTTP FOUND\n");
	ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	return;
      }

    }
  }

  if (packet->payload_packet_len > 43
      && memcmp(packet->payload, "GET http://http.proxy.icq.com/hello HTTP/1.", 43) == 0) {
    NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR ICQ-HTTP PROXY FOUND\n");
    ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
    return;
  }

  if (packet->payload_packet_len > 46
      && memcmp(packet->payload, "GET http://aimhttp.oscar.aol.com/hello HTTP/1.", 46) == 0) {
    NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR AIM-HTTP PROXY FOUND\n");
    ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
    return;
  }

  if (packet->payload_packet_len > 5 && get_u_int32_t(packet->payload, 0) == htonl(0x05010003)) {
    NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "Maybe OSCAR Picturetransfer\n");
    return;
  }

  if (packet->payload_packet_len == 10 && get_u_int32_t(packet->payload, 0) == htonl(0x05000001) &&
      get_u_int32_t(packet->payload, 4) == 0) {
    NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "Maybe OSCAR Picturetransfer\n");
    return;
  }

  if (packet->payload_packet_len >= 70 &&
      memcmp(&packet->payload[packet->payload_packet_len - 26],
	     "\x67\x00\x65\x00\x74\x00\x43\x00\x61\x00\x74\x00\x61\x00\x6c\x00\x6f\x00\x67", 19) == 0) {
    NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR PICTURE TRANSFER\n");
    ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
    return;
  }

  if (NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_OSCAR) != 0) {

    if (flow->packet_counter == 1
	&&
	((packet->payload_packet_len == 9
	  && memcmp(packet->payload, "\x00\x09\x00\x00\x83\x01\xc0\x00\x00", 9) == 0)
	 || (packet->payload_packet_len == 13
	     && (memcmp(packet->payload, "\x00\x0d\x00\x87\x01\xc0", 6) == 0
		 || memcmp(packet->payload, "\x00\x0d\x00\x87\x01\xc1", 6) == 0)))) {
      flow->oscar_video_voice = 1;
    }
    if (flow->oscar_video_voice && ntohs(get_u_int16_t(packet->payload, 0)) == packet->payload_packet_len
	&& packet->payload[2] == 0x00 && packet->payload[3] == 0x00) {
    }

    if (packet->payload_packet_len >= 70 && ntohs(get_u_int16_t(packet->payload, 4)) == packet->payload_packet_len) {
      if (memcmp(packet->payload, "OFT", 3) == 0 &&
	  ((packet->payload[3] == '3' && ((memcmp(&packet->payload[4], "\x01\x00\x01\x01", 4) == 0)
					  || (memcmp(&packet->payload[6], "\x01\x01\x00", 3) == 0)))
	   || (packet->payload[3] == '2' && ((memcmp(&packet->payload[6], "\x01\x01", 2)
					      == 0)
					     )))) {
	// FILE TRANSFER PATTERN:: OFT3 or OFT2
	NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR FILE TRANSFER\n");
	ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
	return;
      }

      if (memcmp(packet->payload, "ODC2", 4) == 0 && memcmp(&packet->payload[6], "\x00\x01\x00\x06", 4) == 0) {
	//PICTURE TRANSFER PATTERN EXMAPLE::
	//4f 44 43 32 00 4c 00 01 00 06 00 00 00 00 00 00  ODC2.L..........
	NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR PICTURE TRANSFER\n");
	ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
	return;
      }
    }
    if (packet->payload_packet_len > 40 && (memcmp(&packet->payload[2], "\x04\x4a\x00", 3) == 0)
	&& (memcmp(&packet->payload[6], "\x00\x00", 2) == 0)
	&& packet->payload[packet->payload_packet_len - 15] == 'F'
	&& packet->payload[packet->payload_packet_len - 12] == 'L'
	&& (memcmp(&packet->payload[packet->payload_packet_len - 6], "DEST", 4) == 0)
	&& (memcmp(&packet->payload[packet->payload_packet_len - 2], "\x00\x00", 2) == 0)) {
      NDPI_LOG(NDPI_PROTOCOL_OSCAR, ndpi_struct, NDPI_LOG_DEBUG, "OSCAR PICTURE TRANSFER\n");
      ndpi_int_oscar_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      if (ntohs(packet->tcp->dest) == 443 || ntohs(packet->tcp->source) == 443) {
	flow->oscar_ssl_voice_stage = 1;
      }
      return;

    }
  }
  if (flow->packet_counter < 3 && packet->payload_packet_len > 11 && (memcmp(packet->payload, "\x00\x37\x04\x4a", 4)
								      || memcmp(packet->payload, "\x00\x0a\x04\x4a",
										4))) {
    return;
  }


  if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_OSCAR) {
    NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OSCAR);
    return;
  }
}
Ejemplo n.º 30
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);
	}
}