Esempio n. 1
0
File: ssl.c Progetto: unusedPhD/ndpi
int sslDetectProtocolFromCertificate(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
  struct ndpi_packet_struct *packet = &flow->packet;

  if(!packet->iph /* IPv4 */) return(-1);

  if((packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN)
     || (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL)) {
    char certificate[64];
    int rc;
    
    certificate[0] = '\0';
    rc = getSSLcertificate(ndpi_struct, flow, certificate, sizeof(certificate));
    packet->ssl_certificate_num_checks++;

    if(rc > 0) {
      packet->ssl_certificate_detected = 1;
#ifdef CERTIFICATE_DEBUG
      printf("***** [SSL] %s\n", certificate);
#endif
      if(ndpi_match_string_subprotocol(ndpi_struct, flow, certificate, strlen(certificate)) != NDPI_PROTOCOL_UNKNOWN)
	return(rc); /* Fix courtesy of Gianluca Costa <*****@*****.**> */
    } 

    if((packet->ssl_certificate_num_checks >= 2)
       && (certificate[0] != '\0')
       && flow->l4.tcp.seen_syn && flow->l4.tcp.seen_syn_ack && flow->l4.tcp.seen_ack) /* We have seen the 3-way handshake */
      ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSL);
  }

  return(0);
}
Esempio n. 2
0
File: http.c Progetto: aoshiken/ndpi
static void parseHttpSubprotocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
  // int i = 0;
  struct ndpi_packet_struct *packet = &flow->packet;

  if(packet->iph /* IPv4 only */) {
    /* 
       Twitter Inc. TWITTER-NETWORK (NET-199-59-148-0-1) 199.59.148.0 - 199.59.151.255
       199.59.148.0/22
    */
    if(((ntohl(packet->iph->saddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC73B9400 /* 199.59.148.0 */)
       || ((ntohl(packet->iph->daddr) & 0xFFFFFC00 /* 255.255.252.0 */) == 0xC73B9400 /* 199.59.148.0 */)) {
      packet->detected_protocol_stack[0] = NDPI_PROTOCOL_TWITTER;
      return;
    }

    /* 
       CIDR:           69.53.224.0/19
       OriginAS:       AS2906
       NetName:        NETFLIX-INC
    */
    if(((ntohl(packet->iph->saddr) & 0xFFFFE000 /* 255.255.224.0 */) == 0x4535E000 /* 69.53.224.0 */)
       || ((ntohl(packet->iph->daddr) & 0xFFFFE000 /* 255.255.224.0 */) == 0x4535E000 /* 69.53.224.0 */)) {
      packet->detected_protocol_stack[0] = NDPI_PROTOCOL_NETFLIX;
      return;
    }
  }
    
  if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_HTTP) {
    /* Try matching subprotocols */
    // ndpi_match_string_subprotocol(ndpi_struct, flow, (char*)packet->host_line.ptr, packet->host_line.len);
    ndpi_match_string_subprotocol(ndpi_struct, flow, flow->host_server_name, strlen(flow->host_server_name));
  }
}
Esempio n. 3
0
int sslDetectProtocolFromCertificate(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
  struct ndpi_packet_struct *packet = &flow->packet;

  if(!packet->iph /* IPv4 */) return(-1);

  if((packet->payload_packet_len > 9)
     && (packet->payload[0] == 0x16 /* consider only specific SSL packets (handshake) */)) {
    if((packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN)
       || (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL)) {
      char certificate[64];
      int rc;

      certificate[0] = '\0';
      rc = getSSLcertificate(ndpi_struct, flow, certificate, sizeof(certificate));
      packet->ssl_certificate_num_checks++;

      if(rc > 0) {
	packet->ssl_certificate_detected++;
#ifdef CERTIFICATE_DEBUG
	printf("***** [SSL] %s\n", certificate);
#endif

	if(ndpi_match_string_subprotocol(ndpi_struct, flow, certificate, strlen(certificate)) != NDPI_PROTOCOL_UNKNOWN)
	  return(rc); /* Fix courtesy of Gianluca Costa <*****@*****.**> */

#ifdef NDPI_PROTOCOL_TOR
	if(ndpi_is_ssl_tor(ndpi_struct, flow, certificate) != 0)
	  return(rc);
#endif
      }

      if(((packet->ssl_certificate_num_checks >= 2)
	  && flow->l4.tcp.seen_syn
	  && flow->l4.tcp.seen_syn_ack
	  && flow->l4.tcp.seen_ack /* We have seen the 3-way handshake */)
	 || (flow->protos.ssl.server_certificate[0] != '\0')
	 || (flow->protos.ssl.client_certificate[0] != '\0')
	 )
	ndpi_int_ssl_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_SSL);
    }
  }

  return(0);
}
Esempio n. 4
0
File: dns.c Progetto: qiuzi/ndpi
void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
  struct ndpi_packet_struct *packet = &flow->packet;
  u_int16_t dport = 0, sport = 0;
  
#define NDPI_MAX_DNS_REQUESTS			16

  NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "search DNS.\n");
  
  if (packet->udp != NULL) {
    sport = ntohs(packet->udp->source),  dport = ntohs(packet->udp->dest);
    NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over UDP.\n");
  } else  if(packet->tcp != NULL) {
    sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest);
    NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "calculated dport over tcp.\n");
  }

  if(((dport == 53) || (sport == 53))
     && (packet->payload_packet_len > sizeof(struct dns_packet_header))) {
    int i = packet->tcp ? 2 : 0;
    struct dns_packet_header header, *dns = (struct dns_packet_header*)&packet->payload[i];
    u_int8_t is_query, ret_code, is_dns = 0;
    u_int32_t a_record[NDPI_MAX_DNS_REQUESTS] = { 0 }, query_offset, num_a_records = 0;

    header.flags = ntohs(dns->flags);
    header.transaction_id = ntohs(dns->transaction_id);
    header.num_queries = ntohs(dns->num_queries);
    header.answer_rrs = ntohs(dns->answer_rrs);
    header.authority_rrs = ntohs(dns->authority_rrs);
    header.additional_rrs = ntohs(dns->additional_rrs);
    is_query = (header.flags & 0x8000) ? 0 : 1;
    ret_code = is_query ? 0 : (header.flags & 0x0F);
    i += sizeof(struct dns_packet_header);
    query_offset = i;

    if(is_query) {
      /* DNS Request */
      if((header.num_queries > 0) && (header.num_queries <= NDPI_MAX_DNS_REQUESTS)
	 && (header.answer_rrs == 0)
	 && (header.authority_rrs == 0)) {
	/* This is a good query */
	is_dns = 1;
      }
    } else {
      /* DNS Reply */
      if((header.num_queries <= NDPI_MAX_DNS_REQUESTS) /* Don't assume that num_queries must be zero */
	 && (((header.answer_rrs > 0) && (header.answer_rrs <= NDPI_MAX_DNS_REQUESTS))
	     || ((header.authority_rrs > 0) && (header.authority_rrs <= NDPI_MAX_DNS_REQUESTS))
	     || ((header.additional_rrs > 0) && (header.additional_rrs <= NDPI_MAX_DNS_REQUESTS)))
	 ) {
	/* This is a good reply */
	is_dns = 1;

	i++;
	
	if(packet->payload[i] != '\0') {
	  while((i < packet->payload_packet_len)
		&& (packet->payload[i] != '\0')) {
	    i++;
	  }
	  
	  i++;
	}

	i += 4;

	if(header.answer_rrs > 0) {
	  u_int16_t rsp_type, rsp_class;
	  u_int16_t num;

	  for(num = 0; num < header.answer_rrs; num++) {
	    u_int16_t data_len;
	
	    if((i+6) >= packet->payload_packet_len) {
	      break;
	    }

	    if((data_len = getNameLength(i, packet->payload, packet->payload_packet_len)) == 0) {
	      break;
	    } else
	      i += data_len;
	
	    rsp_type = get16(&i, packet->payload);
	    rsp_class = get16(&i, packet->payload);

	    i += 4;
	    data_len = get16(&i, packet->payload);

	    if((data_len <= 1) || (data_len > (packet->payload_packet_len-i))) {
	      break;
	    }
	
	    if(rsp_type == 1 /* A */) {
	      if(data_len == 4) {
		u_int32_t v = ntohl(*((u_int32_t*)&packet->payload[i]));

		if(num_a_records < (NDPI_MAX_DNS_REQUESTS-1))
		  a_record[num_a_records++] = v;
		else
		  break; /* One record is enough */
	      }
	    }
	
	    if(data_len == 0) {
	      break;
	    }

	    i += data_len;
	  } /* for */
	}
      }

      if((header.num_queries <= NDPI_MAX_DNS_REQUESTS)
	 && ((header.answer_rrs == 0)
	     || (header.authority_rrs == 0)
	     || (header.additional_rrs == 0))
	 && (ret_code != 0 /* 0 == OK */)
	 ) {
	/* This is a good reply */
	is_dns = 1;
      }
    }

    if(is_dns) {
      int j = 0;
#ifdef DEBUG
      u_int16_t query_type, query_class;
#endif

      i = query_offset+1;

      while((i < packet->payload_packet_len)
	    && (j < (sizeof(flow->host_server_name)-1))	  
	    && (packet->payload[i] != '\0')) {
	flow->host_server_name[j] = tolower(packet->payload[i]);
	if(flow->host_server_name[j] < ' ')
	  flow->host_server_name[j] = '.';	
	j++, i++;
      }

      if(a_record != 0) {
	char a_buf[32];
	int i;

	for(i=0; i<num_a_records; i++) {
	  j += snprintf(&flow->host_server_name[j], sizeof(flow->host_server_name)-1-j, "%s%s",
			(i == 0) ? "@" : ";",
			ndpi_intoa_v4(a_record[i], a_buf, sizeof(a_buf)));
	}
      }
		      
      flow->host_server_name[j] = '\0';

      if(j > 0) {
#ifdef DEBUG
	printf("==> %s\n", flow->host_server_name);
#endif

	if(ndpi_struct->match_dns_host_names)
	  ndpi_match_string_subprotocol(ndpi_struct, flow, flow->host_server_name, strlen(flow->host_server_name));
      }

#ifdef DEBUG
      i++;
      memcpy(&query_type, &packet->payload[i], 2); query_type  = ntohs(query_type), i += 2;
      memcpy(&query_class, &packet->payload[i], 2); query_class  = ntohs(query_class), i += 2;

      printf("%s [type=%04X][class=%04X]\n", flow->host_server_name, query_type, query_class);
#endif

      if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN) {
	/* 
	   Do not set the protocol with DNS if ndpi_match_string_subprotocol() has
	   matched a subprotocol
	*/
	NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "found DNS.\n");      
	ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_DNS, NDPI_REAL_PROTOCOL);
      }
    } else {
      NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n");
      NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS);
    }
  }
}