Beispiel #1
0
void ipoque_search_http_tcp(struct ipoque_detection_module_struct *ipoque_struct)
{
  struct ipoque_packet_struct *packet = &ipoque_struct->packet;
  struct ipoque_flow_struct *flow = ipoque_struct->flow;
  //      struct ipoque_id_struct         *src=ipoque_struct->src;
  //      struct ipoque_id_struct         *dst=ipoque_struct->dst;

  u16 filename_start;

  IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG, "search http\n");

  /* set client-server_direction */
  if (flow->l4.tcp.http_setup_dir == 0) {
    IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG, "initializes http to stage: 1 \n");
    flow->l4.tcp.http_setup_dir = 1 + packet->packet_direction;
  }

  if (IPOQUE_COMPARE_PROTOCOL_TO_BITMASK
      (ipoque_struct->generic_http_packet_bitmask, packet->detected_protocol_stack[0]) != 0) {
    IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG,
	    "protocol might be detected earlier as http jump to payload type detection\n");
    goto http_parse_detection;
  }

  if (flow->l4.tcp.http_setup_dir == 1 + packet->packet_direction) {
    IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG, "http stage: 1\n");

    if (flow->l4.tcp.http_wait_for_retransmission) {
      if (!packet->tcp_retransmission) {
	if (flow->packet_counter <= 5) {
	  IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG, "still waiting for retransmission\n");
	  return;
	} else {
	  IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG, "retransmission not found, exclude\n");
	  http_bitmask_exclude(flow);
	  return;
	}
      }
    }

    if (flow->l4.tcp.http_stage == 0) {
      filename_start = http_request_url_offset(ipoque_struct);
      if (filename_start == 0) {
	IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG, "filename not found, exclude\n");
	http_bitmask_exclude(flow);
	return;
      }
      // parse packet
      ipq_parse_packet_line_info(ipoque_struct);

      if (packet->parsed_lines <= 1) {
	/* parse one more packet .. */
	IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG, "just one line, search next packet\n");
	flow->l4.tcp.http_stage = 1;
	return;
      }
      // parsed_lines > 1 here
      if (packet->line[0].len >= (9 + filename_start)
	  && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) {
	packet->http_url_name.ptr = &packet->payload[filename_start];
	packet->http_url_name.len = packet->line[0].len - (filename_start + 9);

	packet->http_method.ptr = packet->line[0].ptr;
	packet->http_method.len = filename_start - 1;

	IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG, "http structure detected, adding\n");

	ipoque_int_http_add_connection(ipoque_struct, (filename_start == 8) ? NTOP_PROTOCOL_HTTP_CONNECT : IPOQUE_PROTOCOL_HTTP);
	check_content_type_and_change_protocol(ipoque_struct);
	/* HTTP found, look for host... */
	if (packet->host_line.ptr != NULL) {
	  /* aaahh, skip this direction and wait for a server reply here */
	  flow->l4.tcp.http_stage = 2;
	  IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG, "HTTP START HOST found\n");
	  return;
	}
	IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG, "HTTP START HOST found\n");

	/* host not found, check in next packet after */
	flow->l4.tcp.http_stage = 1;
	return;
      }
    } else if (flow->l4.tcp.http_stage == 1) {
      /* SECOND PAYLOAD TRAFFIC FROM CLIENT, FIRST PACKET MIGHT HAVE BEEN HTTP... */
      /* UNKNOWN TRAFFIC, HERE FOR HTTP again.. */
      // parse packet
      ipq_parse_packet_line_info(ipoque_struct);

      if (packet->parsed_lines <= 1) {

	/* wait some packets in case request is split over more than 2 packets */
	if (flow->packet_counter < 5) {
	  IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG,
		  "line still not finished, search next packet\n");
	  return;
	} else {
	  /* stop parsing here */
	  IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG,
		  "HTTP: PACKET DOES NOT HAVE A LINE STRUCTURE\n");
	  http_bitmask_exclude(flow);
	  return;
	}
      }

      if (packet->line[0].len >= 9 && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) {
	ipoque_int_http_add_connection(ipoque_struct, IPOQUE_PROTOCOL_HTTP);
	check_content_type_and_change_protocol(ipoque_struct);
	IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG,
		"HTTP START HTTP found in 2. packet, check host here...\n");
	/* HTTP found, look for host... */
	flow->l4.tcp.http_stage = 2;

	return;
      }
    }
  }
  IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG, "HTTP: REQUEST NOT HTTP CONFORM\n");
  http_bitmask_exclude(flow);
  return;

 http_parse_detection:
  if (flow->l4.tcp.http_setup_dir == 1 + packet->packet_direction) {
    /* we have something like http here, so check for host and content type if possible */
    if (flow->l4.tcp.http_stage == 0 || flow->l4.tcp.http_stage == 3) {
      IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG, "HTTP RUN MAYBE NEXT GET/POST...\n");
      // parse packet
      ipq_parse_packet_line_info(ipoque_struct);
      /* check for url here */
      filename_start = http_request_url_offset(ipoque_struct);
      if (filename_start != 0 && packet->parsed_lines > 1 && packet->line[0].len >= (9 + filename_start)
	  && memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) {
	packet->http_url_name.ptr = &packet->payload[filename_start];
	packet->http_url_name.len = packet->line[0].len - (filename_start + 9);

	packet->http_method.ptr = packet->line[0].ptr;
	packet->http_method.len = filename_start - 1;

	IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG, "next http action, "
		"resetting to http and search for other protocols later.\n");
	ipoque_int_http_add_connection(ipoque_struct, IPOQUE_PROTOCOL_HTTP);
      }
      check_content_type_and_change_protocol(ipoque_struct);
      /* HTTP found, look for host... */
      if (packet->host_line.ptr != NULL) {
	IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG,
		"HTTP RUN MAYBE NEXT HOST found, skipping all packets from this direction\n");
	/* aaahh, skip this direction and wait for a server reply here */
	flow->l4.tcp.http_stage = 2;
	return;
      }
      IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG,
	      "HTTP RUN MAYBE NEXT HOST NOT found, scanning one more packet from this direction\n");
      flow->l4.tcp.http_stage = 1;
    } else if (flow->l4.tcp.http_stage == 1) {
      // parse packet and maybe find a packet info with host ptr,...
      ipq_parse_packet_line_info(ipoque_struct);
      check_content_type_and_change_protocol(ipoque_struct);
      IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG, "HTTP RUN second packet scanned\n");
      /* HTTP found, look for host... */
      flow->l4.tcp.http_stage = 2;
    }
    IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG,
	    "HTTP skipping client packets after second packet\n");
    return;
  }
  /* server response */
  if (flow->l4.tcp.http_stage > 0) {
    /* first packet from server direction, might have a content line */
    ipq_parse_packet_line_info(ipoque_struct);
    check_content_type_and_change_protocol(ipoque_struct);


    if (packet->empty_line_position_set != 0 || flow->l4.tcp.http_empty_line_seen == 1) {
      IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG, "empty line. check_http_payload.\n");
      check_http_payload(ipoque_struct);
    }
    if (flow->l4.tcp.http_stage == 2) {
      flow->l4.tcp.http_stage = 3;
    } else {
      flow->l4.tcp.http_stage = 0;
    }
    IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG,
	    "HTTP response first or second packet scanned,new stage is: %u\n", flow->l4.tcp.http_stage);
    return;
  } else {
    IPQ_LOG(IPOQUE_PROTOCOL_HTTP, ipoque_struct, IPQ_LOG_DEBUG, "HTTP response next packet skipped\n");
  }
}
Beispiel #2
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
}
Beispiel #3
0
void ipoque_search_jabber_tcp(struct ipoque_detection_module_struct
							  *ipoque_struct)
{
	struct ipoque_packet_struct *packet = &ipoque_struct->packet;
	struct ipoque_flow_struct *flow = ipoque_struct->flow;

	struct ipoque_id_struct *src = ipoque_struct->src;
	struct ipoque_id_struct *dst = ipoque_struct->dst;

	u16 x;

	IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "search jabber.\n");

	/* search for jabber file transfer */
	/* this part is working asymmetrically */
	if (packet->tcp != NULL && packet->tcp->syn != 0 && packet->payload_packet_len == 0) {
		IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "check jabber syn\n");
		if (src != NULL && src->jabber_file_transfer_port[0] != 0) {
			IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_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 (((IPOQUE_TIMESTAMP_COUNTER_SIZE)
				 (packet->tick_timestamp - src->jabber_stun_or_ft_ts)) >= ipoque_struct->jabber_file_transfer_timeout) {
				IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct,
						IPQ_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) {
				IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG,
						"found jabber file transfer.\n");

				ipoque_int_jabber_add_connection(ipoque_struct,
												 IPOQUE_PROTOCOL_UNENCRYPED_JABBER, IPOQUE_CORRELATED_PROTOCOL);
			}
		}
		if (dst != NULL && dst->jabber_file_transfer_port[0] != 0) {
			IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_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 (((IPOQUE_TIMESTAMP_COUNTER_SIZE)
				 (packet->tick_timestamp - dst->jabber_stun_or_ft_ts)) >= ipoque_struct->jabber_file_transfer_timeout) {
				IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct,
						IPQ_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) {
				IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG,
						"found jabber file transfer.\n");

				ipoque_int_jabber_add_connection(ipoque_struct,
												 IPOQUE_PROTOCOL_UNENCRYPED_JABBER, IPOQUE_CORRELATED_PROTOCOL);
			}
		}
		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] == IPOQUE_PROTOCOL_UNENCRYPED_JABBER) {
		u16 lastlen;
		u16 j_port = 0;
		/* check for google jabber voip connections ... */
		/* need big packet */
		if (packet->payload_packet_len < 100) {
			IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_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) {
			IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "JABBER <iq from=\".\n");
			lastlen = packet->payload_packet_len - 11;
			for (x = 10; x < lastlen; x++) {
				if (packet->payload[x] == 'p') {
					if (ipq_mem_cmp(&packet->payload[x], "port=", 5) == 0) {
						IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_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_ipq_bytestream_to_number(&packet->payload[x], packet->payload_packet_len, &x);
						IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct,
								IPQ_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) {
								IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct,
										IPQ_LOG_DEBUG, "src->jabber_file_transfer_port[0] = j_port = %u;\n",
										ntohs(j_port));
								src->jabber_file_transfer_port[0] = j_port;
							} else {
								IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct,
										IPQ_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) {
								IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct,
										IPQ_LOG_DEBUG, "dst->jabber_file_transfer_port[0] = j_port = %u;\n",
										ntohs(j_port));
								dst->jabber_file_transfer_port[0] = j_port;
							} else {
								IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct,
										IPQ_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) {
			IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_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] == '@') {
					IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_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 (ipq_mem_cmp(&packet->payload[x], "port=", 5) == 0) {
						IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_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_ipq_bytestream_to_number(&packet->payload[x], packet->payload_packet_len, &x);
						IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct,
								IPQ_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) {
									IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG,
											"src->jabber_file_transfer_port[0] = j_port = %u;\n", ntohs(j_port));
									src->jabber_file_transfer_port[0] = j_port;
								} else {
									IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct,
											IPQ_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) {
									IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG,
											"dst->jabber_file_transfer_port[0] = j_port = %u;\n", ntohs(j_port));
									dst->jabber_file_transfer_port[0] = j_port;
								} else {
									IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct,
											IPQ_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 >= IPQ_STATICSTRING_LEN("<stream:stream ")
			&& memcmp(packet->payload, "<stream:stream ", IPQ_STATICSTRING_LEN("<stream:stream ")) == 0)) {

		if (packet->payload_packet_len > 47) {
			const u16 lastlen = packet->payload_packet_len - 47;
			for (x = 0; x < lastlen; x++) {
				if (ipq_mem_cmp
					(&packet->payload[x],
					 "xmlns:stream='http://etherx.jabber.org/streams'", 47) == 0
					|| ipq_mem_cmp(&packet->payload[x], "xmlns:stream=\"http://etherx.jabber.org/streams\"", 47) == 0) {
					IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_TRACE, "found JABBER.\n");
					x += 47;

					ipoque_int_jabber_add_connection(ipoque_struct,
													 IPOQUE_PROTOCOL_UNENCRYPED_JABBER, IPOQUE_REAL_PROTOCOL);



					/* search for other protocols: Truphone */
					check_content_type_and_change_protocol(ipoque_struct, x);

					return;
				}
			}
		}
	}
	if (flow->packet_counter < 3) {
		IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct,
				IPQ_LOG_TRACE, "packet_counter: %u\n", flow->packet_counter);
		return;
	}



	IPQ_LOG(IPOQUE_PROTOCOL_UNENCRYPED_JABBER, ipoque_struct, IPQ_LOG_DEBUG, "Excluding jabber connection\n");
	IPOQUE_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, IPOQUE_PROTOCOL_UNENCRYPED_JABBER);

#ifdef IPOQUE_PROTOCOL_TRUPHONE
	IPOQUE_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, IPOQUE_PROTOCOL_TRUPHONE);
#endif
}