예제 #1
0
 static inline
#else
__forceinline static
#endif
	 void ndpi_int_search_thunder_http(struct ndpi_detection_module_struct
												  *ndpi_struct, struct ndpi_flow_struct *flow)
{
	struct ndpi_packet_struct *packet = &flow->packet;
	struct ndpi_id_struct *src = flow->src;
	struct ndpi_id_struct *dst = flow->dst;


	if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_THUNDER) {
		if (src != NULL && ((u_int32_t)
							(packet->tick_timestamp - src->thunder_ts) < ndpi_struct->thunder_timeout)) {
			NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG,
					"thunder : save src connection packet detected\n");
			src->thunder_ts = packet->tick_timestamp;
		} else if (dst != NULL && ((u_int32_t)
								   (packet->tick_timestamp - dst->thunder_ts) < ndpi_struct->thunder_timeout)) {
			NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG,
					"thunder : save dst connection packet detected\n");
			dst->thunder_ts = packet->tick_timestamp;
		}
		return;
	}

	if (packet->payload_packet_len > 5
		&& memcmp(packet->payload, "GET /", 5) == 0 && NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_THUNDER)) {
		NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG, "HTTP packet detected.\n");
		ndpi_parse_packet_line_info(ndpi_struct, flow);

		if (packet->parsed_lines > 7
			&& packet->parsed_lines < 11
			&& packet->line[1].len > 10
			&& memcmp(packet->line[1].ptr, "Accept: */*", 11) == 0
			&& packet->line[2].len > 22
			&& memcmp(packet->line[2].ptr, "Cache-Control: no-cache",
						   23) == 0 && packet->line[3].len > 16
			&& memcmp(packet->line[3].ptr, "Connection: close", 17) == 0
			&& packet->line[4].len > 6
			&& memcmp(packet->line[4].ptr, "Host: ", 6) == 0
			&& packet->line[5].len > 15
			&& memcmp(packet->line[5].ptr, "Pragma: no-cache", 16) == 0
			&& packet->user_agent_line.ptr != NULL
			&& packet->user_agent_line.len > 49
			&& memcmp(packet->user_agent_line.ptr,
						   "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)", 50) == 0) {
			NDPI_LOG(NDPI_PROTOCOL_THUNDER, ndpi_struct, NDPI_LOG_DEBUG,
					"Thunder HTTP download detected, adding flow.\n");
			ndpi_int_thunder_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
		}
	}
}
예제 #2
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);
}
예제 #3
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;
  }
}
예제 #4
0
파일: yahoo.c 프로젝트: T-NOVA/vTC
static void ndpi_search_yahoo_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
  struct ndpi_packet_struct *packet = &flow->packet;
	
  struct ndpi_id_struct *src = flow->src;
  struct ndpi_id_struct *dst = flow->dst;

  const struct ndpi_yahoo_header *yahoo = (struct ndpi_yahoo_header *) packet->payload;
  if (packet->payload_packet_len == 0) {
    return;
  }

  /* packet must be at least 20 bytes long */
  if (packet->payload_packet_len >= 20
      && memcmp(yahoo->YMSG_str, "YMSG", 4) == 0 && ((packet->payload_packet_len - 20) == ntohs(yahoo->len)
						     || check_ymsg(packet->payload, packet->payload_packet_len))) {
    NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO FOUND\n");
    flow->yahoo_detection_finished = 2;
    if (ntohs(yahoo->service) == 24 || ntohs(yahoo->service) == 152 || ntohs(yahoo->service) == 74) {
      NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO conference or chat invite  found");
      if (src != NULL) {
	src->yahoo_conf_logged_in = 1;
      }
      if (dst != NULL) {
	dst->yahoo_conf_logged_in = 1;
      }
    }
    if (ntohs(yahoo->service) == 27 || ntohs(yahoo->service) == 155 || ntohs(yahoo->service) == 160) {
      NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO conference or chat logoff found");
      if (src != NULL) {
	src->yahoo_conf_logged_in = 0;
	src->yahoo_voice_conf_logged_in = 0;
      }
    }
    NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
    ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
    return;
  } else if (flow->yahoo_detection_finished == 2 && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_YAHOO) {
    return;
  } else if (packet->payload_packet_len == 4 && memcmp(yahoo->YMSG_str, "YMSG", 4) == 0) {
    flow->l4.tcp.yahoo_sip_comm = 1;
    return;
  } else if (flow->l4.tcp.yahoo_sip_comm && packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN
	     && flow->packet_counter < 3) {
    return;
  }

  /* now test for http login, at least 100 a bytes packet */
  if (ndpi_struct->yahoo_detect_http_connections != 0 && packet->payload_packet_len > 100) {
    if (memcmp(packet->payload, "POST /relay?token=", 18) == 0
	|| memcmp(packet->payload, "GET /relay?token=", 17) == 0
	|| memcmp(packet->payload, "GET /?token=", 12) == 0
	|| memcmp(packet->payload, "HEAD /relay?token=", 18) == 0) {
      if ((src != NULL
	   && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO)
	   != 0) || (dst != NULL
		     && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO)
		     != 0)) {
	/* this is mostly a file transfer */
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
	ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	return;
      }
    }
    if (memcmp(packet->payload, "POST ", 5) == 0) {
      u_int16_t a;
      ndpi_parse_packet_line_info(ndpi_struct, flow);

      if ((packet->user_agent_line.len >= 21)
	  && (memcmp(packet->user_agent_line.ptr, "YahooMobileMessenger/", 21) == 0)) {
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO(Mobile)");
	ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	return;
      }

      if (NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_YAHOO)
	  && packet->parsed_lines > 5
	  && memcmp(&packet->payload[5], "/Messenger.", 11) == 0
	  && packet->line[1].len >= 17
	  && memcmp(packet->line[1].ptr, "Connection: Close",
			  17) == 0 && packet->line[2].len >= 6
	  && memcmp(packet->line[2].ptr, "Host: ", 6) == 0
	  && packet->line[3].len >= 16
	  && memcmp(packet->line[3].ptr, "Content-Length: ",
			  16) == 0 && packet->line[4].len >= 23
	  && memcmp(packet->line[4].ptr, "User-Agent: Mozilla/5.0",
			  23) == 0 && packet->line[5].len >= 23
	  && memcmp(packet->line[5].ptr, "Cache-Control: no-cache", 23) == 0) {
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE,
		 "YAHOO HTTP POST P2P FILETRANSFER FOUND\n");
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
	ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	return;
      }

      if (packet->host_line.ptr != NULL && packet->host_line.len >= 26 &&
	  memcmp(packet->host_line.ptr, "filetransfer.msg.yahoo.com", 26) == 0) {
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO HTTP POST FILETRANSFER FOUND\n");
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
	ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	return;
      }
      /* now check every line */
      for (a = 0; a < packet->parsed_lines; a++) {
	if (packet->line[a].len >= 4 && memcmp(packet->line[a].ptr, "YMSG", 4) == 0) {
	  NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct,
		   NDPI_LOG_TRACE,
		   "YAHOO HTTP POST FOUND, line is: %.*s\n", packet->line[a].len, packet->line[a].ptr);
	  NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
	  ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	  return;
	}
      }
      if (packet->parsed_lines > 8 && packet->line[8].len > 250 && packet->line[8].ptr != NULL) {
	if (memcmp(packet->line[8].ptr, "<Session ", 9) == 0) {
	  if (ndpi_check_for_YmsgCommand(packet->line[8].len, packet->line[8].ptr)) {
	    NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG,
		     "found HTTP Proxy Yahoo Chat <Ymsg Command= pattern  \n");
	    ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	    return;
	  }
	}
      }
    }
    if (memcmp(packet->payload, "GET /Messenger.", 15) == 0) {
      if ((src != NULL
	   && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO)
	   != 0) || (dst != NULL
		     && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO)
		     != 0)) {
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO HTTP GET /Messenger. match\n");
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
	ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	return;
      }
    }

    if ((memcmp(packet->payload, "GET /", 5) == 0)) {
      ndpi_parse_packet_line_info(ndpi_struct, flow);
      if ((packet->user_agent_line.ptr != NULL
	   && packet->user_agent_line.len >= NDPI_STATICSTRING_LEN("YahooMobileMessenger/")
	   && memcmp(packet->user_agent_line.ptr, "YahooMobileMessenger/",
		     NDPI_STATICSTRING_LEN("YahooMobileMessenger/")) == 0)
	  || (packet->user_agent_line.len >= 15
	      && (memcmp(packet->user_agent_line.ptr, "Y!%20Messenger/", 15) == 0))) {
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO(Mobile)");
	ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	return;
      }
      if (packet->host_line.ptr != NULL && packet->host_line.len >= NDPI_STATICSTRING_LEN("msg.yahoo.com") &&
	  memcmp(&packet->host_line.ptr[packet->host_line.len - NDPI_STATICSTRING_LEN("msg.yahoo.com")],
		 "msg.yahoo.com", NDPI_STATICSTRING_LEN("msg.yahoo.com")) == 0) {
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
	ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	return;
      }

    }

  }
  /* found another http login command for yahoo, it is like OSCAR */
  /* detect http connections */

  if (packet->payload_packet_len > 50 && (memcmp(packet->payload, "content-length: ", 16) == 0)) {
    ndpi_parse_packet_line_info(ndpi_struct, flow);
    if (packet->parsed_lines > 2 && packet->line[1].len == 0) {
      NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "first line is empty.\n");
      if (packet->line[2].len > 13 && memcmp(packet->line[2].ptr, "<Ymsg Command=", 14) == 0) {
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO web chat found\n");
	ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
	return;
      }
    }
  }

  if (packet->payload_packet_len > 38 && memcmp(packet->payload, "CONNECT scs.msg.yahoo.com:5050 HTTP/1.", 38) == 0) {
    NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE, "YAHOO-HTTP FOUND\n");
    NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
    ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
    return;
  }

  if ((src != NULL && NDPI_COMPARE_PROTOCOL_TO_BITMASK(src->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) != 0)
      || (dst != NULL
	  && NDPI_COMPARE_PROTOCOL_TO_BITMASK(dst->detected_protocol_bitmask, NDPI_PROTOCOL_YAHOO) != 0)) {
    if (packet->payload_packet_len == 6 && memcmp(packet->payload, "YAHOO!", 6) == 0) {
      NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
      ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      return;
    }
    /* asymmetric detection for SNDIMG not done yet.
     * See ./Yahoo8.1-VideoCall-LAN.pcap and ./Yahoo-VideoCall-inPublicIP.pcap */


    if (packet->payload_packet_len == 8
	&& (memcmp(packet->payload, "<SNDIMG>", 8) == 0 || memcmp(packet->payload, "<REQIMG>", 8) == 0
	    || memcmp(packet->payload, "<RVWCFG>", 8) == 0 || memcmp(packet->payload, "<RUPCFG>", 8) == 0)) {
      NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_TRACE,
	       "YAHOO SNDIMG or REQIMG or RVWCFG or RUPCFG FOUND\n");
      if (src != NULL) {
	if (memcmp(packet->payload, "<SNDIMG>", 8) == 0) {
	  src->yahoo_video_lan_dir = 0;
	} else {
	  src->yahoo_video_lan_dir = 1;
	}
	src->yahoo_video_lan_timer = packet->tick_timestamp;
      }
      if (dst != NULL) {
	if (memcmp(packet->payload, "<SNDIMG>", 8) == 0) {
	  dst->yahoo_video_lan_dir = 0;
	} else {
	  dst->yahoo_video_lan_dir = 1;
	}
	dst->yahoo_video_lan_timer = packet->tick_timestamp;

      }
      NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO subtype VIDEO");
      ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
      return;
    }
    if (src != NULL && packet->tcp->dest == htons(5100)
	&& ((u_int32_t)
	    (packet->tick_timestamp - src->yahoo_video_lan_timer) < ndpi_struct->yahoo_lan_video_timeout)) {
      if (src->yahoo_video_lan_dir == 1) {
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
	ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "IMG MARKED");
	return;
      }

    }
    if (dst != NULL && packet->tcp->dest == htons(5100)
	&& ((u_int32_t)
	    (packet->tick_timestamp - dst->yahoo_video_lan_timer) < ndpi_struct->yahoo_lan_video_timeout)) {
      if (dst->yahoo_video_lan_dir == 0) {
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO");
	ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL);
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "IMG MARKED");
	return;
      }

    }
  }

  /* detect YAHOO over HTTP proxy */
#ifdef NDPI_PROTOCOL_HTTP
  if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP)
#endif
    {

      if (flow->l4.tcp.yahoo_http_proxy_stage == 0) {
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG,
		 "YAHOO maybe HTTP proxy packet 1 => need next packet\n");
	flow->l4.tcp.yahoo_http_proxy_stage = 1 + packet->packet_direction;
	return;
      }
      if (flow->l4.tcp.yahoo_http_proxy_stage == 1 + packet->packet_direction) {
	if ((packet->payload_packet_len > 250) && (memcmp(packet->payload, "<Session ", 9) == 0)) {
	  if (ndpi_check_for_YmsgCommand(packet->payload_packet_len, packet->payload)) {
	    NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG,
		     "found HTTP Proxy Yahoo Chat <Ymsg Command= pattern  \n");
	    ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	    return;
	  }
	}
	NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG,
		 "YAHOO maybe HTTP proxy still initial direction => need next packet\n");
	return;
      }
      if (flow->l4.tcp.yahoo_http_proxy_stage == 2 - packet->packet_direction) {

	ndpi_parse_packet_line_info_any(ndpi_struct, flow);

	if (packet->parsed_lines >= 9) {

	  if (packet->line[4].ptr != NULL && packet->line[4].len >= 9 &&
	      packet->line[8].ptr != NULL && packet->line[8].len >= 6 &&
	      memcmp(packet->line[4].ptr, "<Session ", 9) == 0 &&
	      memcmp(packet->line[8].ptr, "<Ymsg ", 6) == 0) {

	    NDPI_LOG(NDPI_PROTOCOL_YAHOO, ndpi_struct, NDPI_LOG_DEBUG, "found YAHOO over HTTP proxy");
	    ndpi_int_yahoo_add_connection(ndpi_struct, flow, NDPI_CORRELATED_PROTOCOL);
	    return;
	  }
	}
      }
    }
  NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_YAHOO);
}
예제 #5
0
void ndpi_search_worldofwarcraft(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_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, "Search World of Warcraft.\n");

  if (packet->tcp != NULL) {
    /*
      if ((packet->payload_packet_len > NDPI_STATICSTRING_LEN("POST /") &&
      memcmp(packet->payload, "POST /", NDPI_STATICSTRING_LEN("POST /")) == 0) ||
      (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /") &&
      memcmp(packet->payload, "GET /", NDPI_STATICSTRING_LEN("GET /")) == 0)) {
      ndpi_parse_packet_line_info(ndpi_struct, flow);
      if (packet->user_agent_line.ptr != NULL &&
      packet->user_agent_line.len == NDPI_STATICSTRING_LEN("Blizzard Web Client") &&
      memcmp(packet->user_agent_line.ptr, "Blizzard Web Client",
      NDPI_STATICSTRING_LEN("Blizzard Web Client")) == 0) {
      ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow);
      NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG,
      "World of Warcraft: Web Client found\n");
      return;
      }
      }
    */
    if (packet->payload_packet_len > NDPI_STATICSTRING_LEN("GET /")
	&& memcmp(packet->payload, "GET /", NDPI_STATICSTRING_LEN("GET /")) == 0) {
      ndpi_parse_packet_line_info(ndpi_struct, flow);
      if (packet->user_agent_line.ptr != NULL && packet->host_line.ptr != NULL
	  && packet->user_agent_line.len > NDPI_STATICSTRING_LEN("Blizzard Downloader")
	  && packet->host_line.len > NDPI_STATICSTRING_LEN("worldofwarcraft.com")
	  && memcmp(packet->user_agent_line.ptr, "Blizzard Downloader",
		    NDPI_STATICSTRING_LEN("Blizzard Downloader")) == 0
	  && memcmp(&packet->host_line.ptr[packet->host_line.len - NDPI_STATICSTRING_LEN("worldofwarcraft.com")],
		    "worldofwarcraft.com", NDPI_STATICSTRING_LEN("worldofwarcraft.com")) == 0) {
	ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow);
	NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG,
		 "World of Warcraft: Web Client found\n");
	return;
      }
    }
    if (packet->payload_packet_len == 50 && memcmp(&packet->payload[2], "WORLD OF WARCRAFT CONNECTION",
						   NDPI_STATICSTRING_LEN("WORLD OF WARCRAFT CONNECTION")) == 0) {
      ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow);
      NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, "World of Warcraft: Login found\n");
      return;
    }
    if (packet->tcp->dest == htons(3724) && packet->payload_packet_len < 70
	&& packet->payload_packet_len > 40 && (memcmp(&packet->payload[4], "WoW", 3) == 0
					       || memcmp(&packet->payload[5], "WoW", 3) == 0)) {
      ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow);
      NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, "World of Warcraft: Login found\n");
      return;
    }

    if (NDPI_SRC_OR_DST_HAS_PROTOCOL(src, dst, NDPI_PROTOCOL_WORLDOFWARCRAFT) != 0) {
      if (packet->tcp->source == htons(3724)
	  && packet->payload_packet_len == 8 && get_u_int32_t(packet->payload, 0) == htonl(0x0006ec01)) {
	ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow);
	NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
		 NDPI_LOG_DEBUG, "World of Warcraft: connection detected\n");
	return;
      }

    }

    /* for some well known WoW ports
       check another pattern */
    if (flow->l4.tcp.wow_stage == 0) {
      if (ndpi_int_is_wow_port(packet->tcp->source) &&
	  packet->payload_packet_len >= 14 &&
	  ntohs(get_u_int16_t(packet->payload, 0)) == (packet->payload_packet_len - 2)) {
	if (get_u_int32_t(packet->payload, 2) == htonl(0xec010100)) {

	  NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
		   NDPI_LOG_DEBUG, "probably World of Warcraft, waiting for final packet\n");
	  flow->l4.tcp.wow_stage = 2;
	  return;
	} else if (packet->payload_packet_len == 41 &&
		   (get_u_int16_t(packet->payload, 2) == htons(0x0085) ||
		    get_u_int16_t(packet->payload, 2) == htons(0x0034) ||
		    get_u_int16_t(packet->payload, 2) == htons(0x1960))) {
	  NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
		   NDPI_LOG_DEBUG, "maybe World of Warcraft, need next\n");
	  flow->l4.tcp.wow_stage = 1;
	  return;
	}
      }
    }

    if (flow->l4.tcp.wow_stage == 1) {
      if (packet->payload_packet_len == 325 &&
	  ntohs(get_u_int16_t(packet->payload, 0)) == (packet->payload_packet_len - 2) &&
	  get_u_int16_t(packet->payload, 4) == 0 &&
	  (get_u_int16_t(packet->payload, packet->payload_packet_len - 3) == htons(0x2331) ||
	   get_u_int16_t(packet->payload, 67) == htons(0x2331)) &&
	  (memcmp
	   (&packet->payload[packet->payload_packet_len - 18],
	    "\x94\xec\xff\xfd\x67\x62\xd4\x67\xfb\xf9\xdd\xbd\xfd\x01\xc0\x8f\xf9\x81", 18) == 0
	   || memcmp(&packet->payload[packet->payload_packet_len - 30],
		     "\x94\xec\xff\xfd\x67\x62\xd4\x67\xfb\xf9\xdd\xbd\xfd\x01\xc0\x8f\xf9\x81", 18) == 0)) {
	ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow);
	NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
		 NDPI_LOG_DEBUG, "World of Warcraft: connection detected\n");
	return;
      }
      if (packet->payload_packet_len > 32 &&
	  ntohs(get_u_int16_t(packet->payload, 0)) == (packet->payload_packet_len - 2)) {
	if (get_u_int16_t(packet->payload, 4) == 0) {

	  NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
		   NDPI_LOG_DEBUG, "probably World of Warcraft, waiting for final packet\n");
	  flow->l4.tcp.wow_stage = 2;
	  return;
	} else if (get_u_int32_t(packet->payload, 2) == htonl(0x12050000)) {
	  NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
		   NDPI_LOG_DEBUG, "probably World of Warcraft, waiting for final packet\n");
	  flow->l4.tcp.wow_stage = 2;
	  return;
	}
      }
    }

    if (flow->l4.tcp.wow_stage == 2) {
      if (packet->payload_packet_len == 4) {
	ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow);
	NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
		 NDPI_LOG_DEBUG, "World of Warcraft: connection detected\n");
	return;
      } else if (packet->payload_packet_len > 4 && packet->payload_packet_len <= 16 && packet->payload[4] == 0x0c) {
	ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow);
	NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
		 NDPI_LOG_DEBUG, "World of Warcraft: connection detected\n");
	return;
      } else if (flow->packet_counter < 3) {
	NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct, NDPI_LOG_DEBUG, "waiting for final packet\n");
	return;
      }
    }
    if (flow->l4.tcp.wow_stage == 0 && packet->tcp->dest == htons(1119)) {
      /* special log in port for battle.net/world of warcraft */

      if (packet->payload_packet_len >= 77 &&
	  get_u_int32_t(packet->payload, 0) == htonl(0x40000aed) && get_u_int32_t(packet->payload, 4) == htonl(0xea070aed)) {

	ndpi_int_worldofwarcraft_add_connection(ndpi_struct, flow);
	NDPI_LOG(NDPI_PROTOCOL_WORLDOFWARCRAFT, ndpi_struct,
		 NDPI_LOG_DEBUG, "World of Warcraft: connection detected\n");
	return;
      }
    }
  }

  NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_WORLDOFWARCRAFT);
}