Esempio n. 1
0
static void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
  struct ndpi_packet_struct *packet = &flow->packet;
  if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_BITTORRENT) {
    /* check for tcp retransmission here */

    if ((packet->tcp != NULL)
	&& (packet->tcp_retransmission == 0 || packet->num_retried_bytes)) {
      ndpi_int_search_bittorrent_tcp(ndpi_struct, flow);
    }
    else if(packet->udp != NULL) {
      flow->bittorrent_stage++;

      if(flow->bittorrent_stage < 10) {
	if(packet->payload_packet_len > 19 /* min size */) {
	  char *begin;
	
	  if(ndpi_strnstr(packet->payload, ":target20:", packet->payload_packet_len)
	     || ndpi_strnstr(packet->payload, ":find_node1:", packet->payload_packet_len)
	     || ndpi_strnstr(packet->payload, "d1:ad2:id20:", packet->payload_packet_len)) {
	  bittorrent_found:
	    NDPI_LOG_BITTORRENT(NDPI_PROTOCOL_BITTORRENT,
			       ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n");
	    ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
						NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION,
						NDPI_REAL_PROTOCOL);
	    return;
	  } else if((begin = memchr(packet->payload, 'B',  packet->payload_packet_len-19)) != NULL) {
	    long offset = (u_long)begin - (u_long)packet->payload;
	    
	    if((packet->payload_packet_len-19) > offset) {
	      if(memcmp(begin, "BitTorrent protocol", 19) == 0) {
		goto bittorrent_found;
	      }
	    }
	  }
	}

	return;
      }

      NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BITTORRENT);
    }
  }
}
Esempio n. 2
0
static int matchStringProtocol(struct ndpi_detection_module_struct *ndpi_struct, 
			struct ndpi_flow_struct *flow, 
			char *string_to_match, 
			u_int string_to_match_len) {
  int i = 0, end = string_to_match_len-1, num_found = 0;
  struct ndpi_packet_struct *packet = &flow->packet;
#ifdef AHOCORASICK
  AC_TEXT_t ac_input_text;
#endif

  while(end > 0) {
    if(string_to_match[end] == '.') {
      num_found++;
      if(num_found == 2) {
	end++;
	break;
      }
    }
    end--;
  }

  strncpy(flow->l4.tcp.host_server_name, 
	  &string_to_match[end], 
	  ndpi_min(sizeof(flow->l4.tcp.host_server_name)-1, string_to_match_len-end));

#ifdef AHOCORASICK
  matching_protocol_id = -1;

  ac_input_text.astring = string_to_match;
  ac_input_text.length = string_to_match_len;
  ac_automata_search (ac_automa, &ac_input_text, 0);
  
  ac_automata_reset(ac_automa);

  if (matching_protocol_id != -1) {
    packet->detected_protocol_stack[0] = matching_protocol_id;
    return(packet->detected_protocol_stack[0]);
  }
#else
  for (i = 0; i < host_match_num_items; i++) {
    if(ndpi_strnstr(string_to_match, 
		    host_match[i].string_to_match, 
		    string_to_match_len) != NULL) {
      packet->detected_protocol_stack[0] = host_match[i].protocol_id;
      return(packet->detected_protocol_stack[0]);
    } else
      i++;
  }
#endif

#ifdef DEBUG
  string_to_match[string_to_match_len] = '\0';
  printf("[NTOP] Unable to find a match for '%s'\n", string_to_match);
#endif

  return(-1);
}
Esempio n. 3
0
static void ndpi_check_citrix(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
  struct ndpi_packet_struct *packet = &flow->packet;
  u_int32_t payload_len = packet->payload_packet_len;

#if 0
  printf("[len=%u][%02X %02X %02X %02X]\n", payload_len,
	 packet->payload[0] & 0xFF,
	 packet->payload[1] & 0xFF,
	 packet->payload[2] & 0xFF,
	 packet->payload[3] & 0xFF);
#endif

  if(packet->tcp != NULL) {
    flow->l4.tcp.citrix_packet_id++;
    
    if((flow->l4.tcp.citrix_packet_id == 3)
       /* We have seen the 3-way handshake */
       && flow->l4.tcp.seen_syn
       && flow->l4.tcp.seen_syn_ack
       && flow->l4.tcp.seen_ack) {
      if(payload_len == 6) {
	char citrix_header[] = { 0x07, 0x07, 0x49, 0x43, 0x41, 0x00 };
	
	if(memcmp(packet->payload, citrix_header, sizeof(citrix_header)) == 0) {
	  NDPI_LOG(NDPI_PROTOCOL_CITRIX, ndpi_struct, NDPI_LOG_DEBUG, "Found citrix.\n");
	  ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_CITRIX, NDPI_REAL_PROTOCOL);
	}

	return;
      } else if(payload_len > 4) {
	char citrix_header[] = { 0x1a, 0x43, 0x47, 0x50, 0x2f, 0x30, 0x31 };
	
	if((memcmp(packet->payload, citrix_header, sizeof(citrix_header)) == 0)
	   || (ndpi_strnstr(packet->payload, "Citrix.TcpProxyService", payload_len) != NULL)) {
	  NDPI_LOG(NDPI_PROTOCOL_CITRIX, ndpi_struct, NDPI_LOG_DEBUG, "Found citrix.\n");
	  ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_CITRIX, NDPI_REAL_PROTOCOL);
	}

	return;	
      }
      
      
      NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_CITRIX);
    } else if(flow->l4.tcp.citrix_packet_id > 3)
      NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_CITRIX);
    
    return;
  }
}
Esempio n. 4
0
static void check_content_type_and_change_protocol(struct ndpi_detection_module_struct *ndpi_struct,
						   struct ndpi_flow_struct *flow, u_int16_t x)
{
  struct ndpi_packet_struct *packet = &flow->packet;
  int i, left = packet->payload_packet_len-x;

  if(left <= 0) return;

  for(i=0; jabber_strings[i].string != NULL; i++) {
    if(ndpi_strnstr((const char*)&packet->payload[x], jabber_strings[i].string, left) != NULL) {    
      ndpi_int_jabber_add_connection(ndpi_struct, flow, jabber_strings[i].ndpi_protocol);
      return;
    }
  }  
}
Esempio n. 5
0
static void ndpi_add_connection_as_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow,
					      int bt_offset, int check_hash,
                                              const u_int8_t save_detection, const u_int8_t encrypted_connection)
{
  if(check_hash) {
    const char *bt_hash = NULL; /* 20 bytes long */
    const char *peer_id = NULL; /* 20 bytes long */

    if(bt_offset == -1) {
      const char *bt_magic = ndpi_strnstr((const char *)flow->packet.payload, 
					  "BitTorrent protocol", flow->packet.payload_packet_len);

      if(bt_magic)
	bt_hash = &bt_magic[19], peer_id = &bt_magic[39];
    } else
      bt_hash = (const char*)&flow->packet.payload[28], peer_id = (const char*)&flow->packet.payload[48];
 
    if(bt_hash) memcpy(flow->bittorent_hash, bt_hash, 20);
  }

  ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_BITTORRENT, NDPI_PROTOCOL_UNKNOWN);
}
Esempio n. 6
0
void ndpi_search_jabber_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_int16_t x;

  NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_TRACE, "JABBER detection....\n");

  /* search for jabber file transfer */
  /* this part is working asymmetrically */
  if (packet->tcp != NULL && packet->tcp->syn != 0 && packet->payload_packet_len == 0) {
    NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "check jabber syn\n");
    if (src != NULL && src->jabber_file_transfer_port[0] != 0) {
      NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG,
	       "src jabber ft port set, ports are: %u, %u\n", ntohs(src->jabber_file_transfer_port[0]),
	       ntohs(src->jabber_file_transfer_port[1]));
      if (((u_int32_t)
	   (packet->tick_timestamp - src->jabber_stun_or_ft_ts)) >= ndpi_struct->jabber_file_transfer_timeout) {
	NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
		 NDPI_LOG_DEBUG, "JABBER src stun timeout %u %u\n", src->jabber_stun_or_ft_ts,
		 packet->tick_timestamp);
	src->jabber_file_transfer_port[0] = 0;
	src->jabber_file_transfer_port[1] = 0;
      } else if (src->jabber_file_transfer_port[0] == packet->tcp->dest
		 || src->jabber_file_transfer_port[0] == packet->tcp->source
		 || src->jabber_file_transfer_port[1] == packet->tcp->dest
		 || src->jabber_file_transfer_port[1] == packet->tcp->source) {
	NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG,
		 "found jabber file transfer.\n");

	ndpi_int_jabber_add_connection(ndpi_struct, flow,
				       NDPI_PROTOCOL_UNENCRYPED_JABBER);
      }
    }
    if (dst != NULL && dst->jabber_file_transfer_port[0] != 0) {
      NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG,
	       "dst jabber ft port set, ports are: %u, %u\n", ntohs(dst->jabber_file_transfer_port[0]),
	       ntohs(dst->jabber_file_transfer_port[1]));
      if (((u_int32_t)
	   (packet->tick_timestamp - dst->jabber_stun_or_ft_ts)) >= ndpi_struct->jabber_file_transfer_timeout) {
	NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
		 NDPI_LOG_DEBUG, "JABBER dst stun timeout %u %u\n", dst->jabber_stun_or_ft_ts,
		 packet->tick_timestamp);
	dst->jabber_file_transfer_port[0] = 0;
	dst->jabber_file_transfer_port[1] = 0;
      } else if (dst->jabber_file_transfer_port[0] == packet->tcp->dest
		 || dst->jabber_file_transfer_port[0] == packet->tcp->source
		 || dst->jabber_file_transfer_port[1] == packet->tcp->dest
		 || dst->jabber_file_transfer_port[1] == packet->tcp->source) {
	NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG,
		 "found jabber file transfer.\n");

	ndpi_int_jabber_add_connection(ndpi_struct, flow,
				       NDPI_PROTOCOL_UNENCRYPED_JABBER);
      }
    }
    return;
  }

  if (packet->tcp != 0 && packet->payload_packet_len == 0) {
    return;
  }


  /* this part parses a packet and searches for port=. it works asymmetrically. */
  if (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNENCRYPED_JABBER) {
    u_int16_t lastlen;
    u_int16_t j_port = 0;
    /* check for google jabber voip connections ... */
    /* need big packet */
    if (packet->payload_packet_len < 100) {
      NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "packet too small, return.\n");
      return;
    }
    /* need message to or type for file-transfer */
    if (memcmp(packet->payload, "<iq from=\"", 8) == 0 || memcmp(packet->payload, "<iq from=\'", 8) == 0) {
      NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "JABBER <iq from=\".\n");
      lastlen = packet->payload_packet_len - 11;
      for (x = 10; x < lastlen; x++) {
	if (packet->payload[x] == 'p') {
	  if (memcmp(&packet->payload[x], "port=", 5) == 0) {
	    NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "port=\n");
	    if (src != NULL) {
	      src->jabber_stun_or_ft_ts = packet->tick_timestamp;
	    }

	    if (dst != NULL) {
	      dst->jabber_stun_or_ft_ts = packet->tick_timestamp;
	    }
	    x += 6;
	    j_port = ntohs_ndpi_bytestream_to_number(&packet->payload[x], packet->payload_packet_len, &x);
	    NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
		     NDPI_LOG_DEBUG, "JABBER port : %u\n", ntohs(j_port));
	    if (src != NULL) {
	      if (src->jabber_file_transfer_port[0] == 0 || src->jabber_file_transfer_port[0] == j_port) {
		NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
			 NDPI_LOG_DEBUG, "src->jabber_file_transfer_port[0] = j_port = %u;\n",
			 ntohs(j_port));
		src->jabber_file_transfer_port[0] = j_port;
	      } else {
		NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
			 NDPI_LOG_DEBUG, "src->jabber_file_transfer_port[1] = j_port = %u;\n",
			 ntohs(j_port));
		src->jabber_file_transfer_port[1] = j_port;
	      }
	    }
	    if (dst != NULL) {
	      if (dst->jabber_file_transfer_port[0] == 0 || dst->jabber_file_transfer_port[0] == j_port) {
		NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
			 NDPI_LOG_DEBUG, "dst->jabber_file_transfer_port[0] = j_port = %u;\n",
			 ntohs(j_port));
		dst->jabber_file_transfer_port[0] = j_port;
	      } else {
		NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
			 NDPI_LOG_DEBUG, "dst->jabber_file_transfer_port[1] = j_port = %u;\n",
			 ntohs(j_port));
		dst->jabber_file_transfer_port[1] = j_port;
	      }
	    }
	  }


	}
      }

    } else if (memcmp(packet->payload, "<iq to=\"", 8) == 0 || memcmp(packet->payload, "<iq to=\'", 8) == 0
	       || memcmp(packet->payload, "<iq type=", 9) == 0) {
      NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "JABBER <iq to=\"/type=\"\n");
      lastlen = packet->payload_packet_len - 21;
      for (x = 8; x < lastlen; x++) {
	/* invalid character */
	if (packet->payload[x] < 32 || packet->payload[x] > 127) {
	  return;
	}
	if (packet->payload[x] == '@') {
	  NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "JABBER @\n");
	  break;
	}
      }
      if (x >= lastlen) {
	return;
      }

      lastlen = packet->payload_packet_len - 10;
      for (; x < lastlen; x++) {
	if (packet->payload[x] == 'p') {
	  if (memcmp(&packet->payload[x], "port=", 5) == 0) {
	    NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG, "port=\n");
	    if (src != NULL) {
	      src->jabber_stun_or_ft_ts = packet->tick_timestamp;
	    }

	    if (dst != NULL) {
	      dst->jabber_stun_or_ft_ts = packet->tick_timestamp;
	    }

	    x += 6;
	    j_port = ntohs_ndpi_bytestream_to_number(&packet->payload[x], packet->payload_packet_len, &x);
	    NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
		     NDPI_LOG_DEBUG, "JABBER port : %u\n", ntohs(j_port));

	    if (src != NULL && src->jabber_voice_stun_used_ports < JABBER_MAX_STUN_PORTS - 1) {
	      if (packet->payload[5] == 'o') {
		src->jabber_voice_stun_port[src->jabber_voice_stun_used_ports++]
		  = j_port;
	      } else {
		if (src->jabber_file_transfer_port[0] == 0
		    || src->jabber_file_transfer_port[0] == j_port) {
		  NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG,
			   "src->jabber_file_transfer_port[0] = j_port = %u;\n", ntohs(j_port));
		  src->jabber_file_transfer_port[0] = j_port;
		} else {
		  NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
			   NDPI_LOG_DEBUG, "src->jabber_file_transfer_port[1] = j_port = %u;\n",
			   ntohs(j_port));
		  src->jabber_file_transfer_port[1] = j_port;
		}
	      }
	    }

	    if (dst != NULL && dst->jabber_voice_stun_used_ports < JABBER_MAX_STUN_PORTS - 1) {
	      if (packet->payload[5] == 'o') {
		dst->jabber_voice_stun_port[dst->jabber_voice_stun_used_ports++]
		  = j_port;
	      } else {
		if (dst->jabber_file_transfer_port[0] == 0
		    || dst->jabber_file_transfer_port[0] == j_port) {
		  NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_DEBUG,
			   "dst->jabber_file_transfer_port[0] = j_port = %u;\n", ntohs(j_port));
		  dst->jabber_file_transfer_port[0] = j_port;
		} else {
		  NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
			   NDPI_LOG_DEBUG, "dst->jabber_file_transfer_port[1] = j_port = %u;\n",
			   ntohs(j_port));
		  dst->jabber_file_transfer_port[1] = j_port;
		}
	      }
	    }
	    return;
	  }
	}
      }
    }
    return;
  }


  /* search for jabber here */
  /* this part is working asymmetrically */
  if ((packet->payload_packet_len > 13 && memcmp(packet->payload, "<?xml version=", 14) == 0)
      || (packet->payload_packet_len >= NDPI_STATICSTRING_LEN("<stream:stream ")
	  && memcmp(packet->payload, "<stream:stream ", NDPI_STATICSTRING_LEN("<stream:stream ")) == 0)) {
    int start = packet->payload_packet_len-13;

    if(ndpi_strnstr((const char *)&packet->payload[13], "xmlns:stream='http://etherx.jabber.org/streams'", start)
       || ndpi_strnstr((const char *)&packet->payload[13], "xmlns:stream=\"http://etherx.jabber.org/streams\"", start)) {
  
      /* Protocol family */
      ndpi_int_jabber_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNENCRYPED_JABBER);

      /* search for subprotocols */
      check_content_type_and_change_protocol(ndpi_struct, flow, 13);
      return;
    }
  }
  
  if (flow->packet_counter < 3) {
    NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct,
	     NDPI_LOG_DEBUG, "packet_counter: %u\n", flow->packet_counter);
    return;
  }

  NDPI_LOG(NDPI_PROTOCOL_UNENCRYPED_JABBER, ndpi_struct, NDPI_LOG_TRACE, "JABBER Excluded.\n");
  NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_UNENCRYPED_JABBER);

#ifdef NDPI_PROTOCOL_TRUPHONE
  NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TRUPHONE);
#endif
}
Esempio n. 7
0
void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
  struct ndpi_packet_struct *packet = &flow->packet;

  /* This is broadcast */
  if(packet->iph
     && ((packet->iph->saddr == 0xFFFFFFFF) || (packet->iph->daddr == 0xFFFFFFFF)))
    return;

  if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_BITTORRENT) {
    /* check for tcp retransmission here */

    if ((packet->tcp != NULL)
	&& (packet->tcp_retransmission == 0 || packet->num_retried_bytes)) {
      ndpi_int_search_bittorrent_tcp(ndpi_struct, flow);
    }
    else if(packet->udp != NULL) {
      char *bt_search = "BT-SEARCH * HTTP/1.1\r\n";

      if((ntohs(packet->udp->source) < 1024)
	 || (ntohs(packet->udp->dest) < 1024) /* High ports only */)
	return;

      /*
	Check for uTP http://www.bittorrent.org/beps/bep_0029.html

	wireshark/epan/dissectors/packet-bt-utp.c
      */

      if(packet->payload_packet_len >= 23 /* min header size */) {
	if(strncmp((const char*)packet->payload, bt_search, strlen(bt_search)) == 0) {
	  ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
					    NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION,
					    NDPI_REAL_PROTOCOL);
	  return;
	} else {
	  /* Check if this is protocol v0 */
	  u_int8_t v0_extension = packet->payload[17];
	  u_int8_t v0_flags     = packet->payload[18];

	  /* Check if this is protocol v1 */
	  u_int8_t v1_version     = packet->payload[0];
	  u_int8_t v1_extension   = packet->payload[1];
	  u_int32_t v1_window_size = *((u_int32_t*)&packet->payload[12]);

	  if((packet->payload[0]== 0x60)
	     && (packet->payload[1]== 0x0)
	     && (packet->payload[2]== 0x0)
	     && (packet->payload[3]== 0x0)
	     && (packet->payload[4]== 0x0)) {
	    /* Heuristic */
	    goto bittorrent_found;
	  } else if(((v1_version & 0x0f) == 1)
		    && ((v1_version >> 4) < 5 /* ST_NUM_STATES */)
		    && (v1_extension      < 3 /* EXT_NUM_EXT */)
		    && (v1_window_size    < 32768 /* 32k */)
		    ) {
	    goto bittorrent_found;
	  } else if((v0_flags < 6 /* ST_NUM_STATES */)
		    && (v0_extension < 3 /* EXT_NUM_EXT */)) {
	    u_int32_t ts = ntohl(*((u_int32_t*)&(packet->payload[4])));
	    u_int32_t now;

#ifndef __KERNEL__
	    now = (u_int32_t)time(NULL);
#else
	    struct timespec t;

	    getnstimeofday(&t);
	    now = t.tv_sec;
#endif

	    if((ts < (now+86400)) && (ts > (now-86400))) {
	      goto bittorrent_found;
	    }
	  }
	}
      }

      flow->bittorrent_stage++;

      if(flow->bittorrent_stage < 10) {
	if(packet->payload_packet_len > 19 /* min size */) {
	  if(ndpi_strnstr((const char *)packet->payload, ":target20:", packet->payload_packet_len)
	     || ndpi_strnstr((const char *)packet->payload, ":find_node1:", packet->payload_packet_len)
	     || ndpi_strnstr((const char *)packet->payload, "d1:ad2:id20:", packet->payload_packet_len)
	     || ndpi_strnstr((const char *)packet->payload, ":info_hash20:", packet->payload_packet_len)
	     || ndpi_strnstr((const char *)packet->payload, ":filter64", packet->payload_packet_len)
	     || ndpi_strnstr((const char *)packet->payload, "d1:rd2:id20:", packet->payload_packet_len)
	     || ndpi_strnstr((const char *)packet->payload, "BitTorrent protocol", packet->payload_packet_len)
	     ) {
	  bittorrent_found:
	    NDPI_LOG(NDPI_PROTOCOL_BITTORRENT,
		     ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n");
	    ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
					      NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION,
					      NDPI_REAL_PROTOCOL);
	    return;
	  }
	}

	return;
      }

      NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BITTORRENT);
    }
Esempio n. 8
0
void ndpi_search_bittorrent(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
  struct ndpi_packet_struct *packet = &flow->packet;

  /* This is broadcast */
  if(packet->iph 
     && ((packet->iph->saddr == 0xFFFFFFFF) || (packet->iph->daddr == 0xFFFFFFFF)))
    return;

  if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_BITTORRENT) {
    /* check for tcp retransmission here */

    if ((packet->tcp != NULL)
	&& (packet->tcp_retransmission == 0 || packet->num_retried_bytes)) {
      ndpi_int_search_bittorrent_tcp(ndpi_struct, flow);
    }
    else if(packet->udp != NULL) {
      /*
	Check for uTP http://www.bittorrent.org/beps/bep_0029.html

	wireshark/epan/dissectors/packet-bt-utp.c
       */

      if(packet->payload_packet_len >= 23 /* min header size */) {
	/* Check if this is protocol v0 */
	u_int8_t v0_extension = packet->payload[17];
	u_int8_t v0_flags     = packet->payload[18];

	/* Check if this is protocol v1 */
	u_int8_t v1_version   = packet->payload[0];
	u_int8_t v1_extension = packet->payload[1];
	
	if(((v1_version & 0x0f) == 1)
	   && ((v1_version >> 4) < 6 /* ST_NUM_STATES */)
	   && (v1_extension      < 3 /* EXT_NUM_EXT */)) {
	  goto bittorrent_found;
	} else if((v0_flags < 6 /* ST_NUM_STATES */)
		  && (v0_extension < 3 /* EXT_NUM_EXT */)) {
	  u_int32_t ts, 
	    // ts_usec, 
	    now = (u_int32_t)time(NULL);
	  
	  ts      = ntohl(*((u_int32_t*)&(packet->payload[4])));
	  // ts_usec = ntohl(*((u_int32_t*)&(packet->payload[8])));
	  
	  if((ts < (now+86400)) && (ts > (now-86400))) {
	    goto bittorrent_found;
	  }
	}
      }

      flow->bittorrent_stage++;

      if(flow->bittorrent_stage < 10) {
	if(packet->payload_packet_len > 19 /* min size */) {
	  char *begin;

	  if(ndpi_strnstr(packet->payload, ":target20:", packet->payload_packet_len)
	     || ndpi_strnstr(packet->payload, ":find_node1:", packet->payload_packet_len)
	     || ndpi_strnstr(packet->payload, "d1:ad2:id20:", packet->payload_packet_len)) {
	  bittorrent_found:
	    NDPI_LOG_BITTORRENT(NDPI_PROTOCOL_BITTORRENT,
			       ndpi_struct, NDPI_LOG_TRACE, "BT: plain BitTorrent protocol detected\n");
	    ndpi_add_connection_as_bittorrent(ndpi_struct, flow,
						NDPI_PROTOCOL_SAFE_DETECTION, NDPI_PROTOCOL_PLAIN_DETECTION,
						NDPI_REAL_PROTOCOL);
	    return;
	  } else if((begin = memchr(packet->payload, 'B',  packet->payload_packet_len-19)) != NULL) {
	    long offset = (u_long)begin - (u_long)packet->payload;

	    if((packet->payload_packet_len-19) > offset) {
	      if(memcmp(begin, "BitTorrent protocol", 19) == 0) {
		goto bittorrent_found;
	      }
	    }
	  }
	}

	return;
      }

      NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_BITTORRENT);
    }