Ejemplo n.º 1
0
DLLEXPORT libtrace_icmp_t *trace_get_icmp_from_ip(libtrace_ip_t *ip, uint32_t *remaining)
{
	libtrace_icmp_t *icmpptr = 0;

	if (ip->ip_p == TRACE_IPPROTO_ICMP)  {
		icmpptr = (libtrace_icmp_t *)trace_get_payload_from_ip(ip, 
				NULL, remaining);
	}

	return icmpptr;
}
Ejemplo n.º 2
0
DLLEXPORT libtrace_udp_t *trace_get_udp_from_ip(libtrace_ip_t *ip, uint32_t *remaining)
{
	libtrace_udp_t *udpptr = 0;

	if (ip->ip_p == TRACE_IPPROTO_UDP) {
		udpptr = (libtrace_udp_t *)
			trace_get_payload_from_ip(ip, NULL, remaining);
	}

	return udpptr;
}
Ejemplo n.º 3
0
void pkt(struct lfc *lfc, void *mydata,
	struct lfc_flow *flow, void *flowdata,
	double ts, bool up, bool is_new, libtrace_packet_t *pkt)
{
	struct flowdata *fd = flowdata;

	if (up) {
		if (fd->ups > 0) return;
	} else {
		if (fd->downs > 0) return;
	}

	/*
	 * get the payload
	 */
	uint8_t proto;
	uint16_t ethertype;
	uint32_t rem;
	void *ptr;
	uint8_t *v;

	ptr = trace_get_layer3(pkt, &ethertype, &rem);
	if (!ptr || ethertype != TRACE_ETHERTYPE_IP) return;

	ptr = trace_get_payload_from_ip(ptr, &proto, &rem);
	if (!ptr) return;

	if (proto == TRACE_IPPROTO_TCP)
		v = trace_get_payload_from_tcp(ptr, &rem);
	else if (proto == TRACE_IPPROTO_UDP)
		v = trace_get_payload_from_udp(ptr, &rem);
	else
		v = NULL;

	if (!v || rem == 0) return;

	/*
	 * copy
	 */
	if (up) {
		fd->ups = MIN(LEN, rem);
		memcpy(fd->up, v, fd->ups);
	} else {
		fd->downs = MIN(LEN, rem);
		memcpy(fd->down, v, fd->downs);
	}
}
Ejemplo n.º 4
0
DLLEXPORT void *trace_get_transport(const libtrace_packet_t *packet, 
		uint8_t *proto,
		uint32_t *remaining
		) 
{
	uint8_t dummy_proto;
	uint16_t ethertype;
	uint32_t dummy_remaining;
	void *transport;

	if (!proto) proto=&dummy_proto;

	if (!remaining) remaining=&dummy_remaining;

	if (packet->l4_header) {
		/*
		void *link;
		libtrace_linktype_t linktype;
		link = trace_get_packet_buffer(packet, &linktype, remaining);
		if (!link)
			return NULL;
		*/
		*proto = packet->transport_proto;
		/* *remaining -= (packet->l4_header - link); */
		*remaining = packet->l4_remaining;
		return packet->l4_header;
	}

	transport = trace_get_layer3(packet,&ethertype,remaining);

	if (!transport || *remaining == 0)
		return NULL;

	switch (ethertype) {
		case TRACE_ETHERTYPE_IP: /* IPv4 */
			transport=trace_get_payload_from_ip(
				(libtrace_ip_t*)transport, proto, remaining);
			/* IPv6 */
			if (transport && *proto == TRACE_IPPROTO_IPV6) {
				transport=trace_get_payload_from_ip6(
				 (libtrace_ip6_t*)transport, proto,remaining);
			}
			break;
		case TRACE_ETHERTYPE_IPV6: /* IPv6 */
			transport = trace_get_payload_from_ip6(
				(libtrace_ip6_t*)transport, proto, remaining);
			break;
		default:
			*proto = 0;
			transport = NULL;
			break;
			
	}

	((libtrace_packet_t *)packet)->transport_proto = *proto;
	((libtrace_packet_t *)packet)->l4_header = transport;
	((libtrace_packet_t *)packet)->l4_remaining = *remaining;


	return transport;
}
Ejemplo n.º 5
0
static void per_packet(libtrace_packet_t *packet)
{
	/* Packet data */
	uint32_t remaining;
	/* L3 data */
	void *l3;
	uint16_t ethertype;
	/* Transport data */
	void *transport;
	uint8_t proto;
	/* Payload data */
	void *payload;

	if (lastts < 1)
		lastts = trace_get_seconds(packet);

	if (lastts+1.0 < trace_get_seconds(packet)) {
		++lastts;
		printf("%.03f,",lastts);
		printf("%"PRIu64",%"PRIu64",",v4,v6);
		printf("%"PRIu64",%"PRIu64",%"PRIu64,icmp,tcp,udp);
		printf("\n");
		v4=v6=0;
		icmp=tcp=udp=0;
	}

 	l3 = trace_get_layer3(packet,&ethertype,&remaining);

	if (!l3)
		/* Probable ARP or something */
		return;

	/* Get the UDP/TCP/ICMP header from the IPv4/IPv6 packet */
	switch (ethertype) {
		case 0x0800:
			transport = trace_get_payload_from_ip(
					(libtrace_ip_t*)l3,
					&proto,
					&remaining);
			if (!transport)
				return;
			++v4;
			break;
		case 0x86DD:
			transport = trace_get_payload_from_ip6(
					(libtrace_ip6_t*)l3,
					&proto,
					&remaining);
			if (!transport)
				return;
			++v6;
			break;
		default:
			return;
	}

	/* Parse the udp/tcp/icmp payload */
	switch(proto) {
		case 1:
			++icmp;
			return;
		case 6:
			payload = trace_get_payload_from_tcp(
					(libtrace_tcp_t*)transport,
					&remaining);
			if (!payload)
				return;

			++tcp;
			break;
		case 17:

			payload = trace_get_payload_from_udp(
					(libtrace_udp_t*)transport,
					&remaining);
			if (!payload)
				return;
			++udp;
			break;
		default:
			return;
	}
	++ok;
}
Ejemplo n.º 6
0
/** Implements the process_packet function of the plugin API */
int corsaro_dos_process_packet(corsaro_t *corsaro,
			     corsaro_packet_t *packet)
{
  libtrace_packet_t *ltpacket = LT_PKT(packet);
  void *temp = NULL;
  uint8_t proto;
  uint32_t remaining;

  libtrace_ip_t *ip_hdr = NULL;
  libtrace_icmp_t *icmp_hdr = NULL;
  libtrace_ip_t *inner_ip_hdr = NULL;

  /* borrowed from libtrace's protocols.h (used by trace_get_*_port) */
  struct ports_t {
    uint16_t src;           /**< Source port */
    uint16_t dst;           /**< Destination port */
  };

  uint16_t attacker_port = 0;
  uint16_t target_port = 0;

  attack_vector_t findme;

  int khret;
  khiter_t khiter;
  attack_vector_t *vector = NULL;
  uint8_t *pkt_buf = NULL;
  libtrace_linktype_t linktype;

  struct timeval tv;

  if((packet->state.flags & CORSARO_PACKET_STATE_FLAG_BACKSCATTER) == 0)
    {
      /* not a backscatter packet */
      return 0;
    }

  /* backscatter packet, lets find the flow */
  /* check for ipv4 */
  /* 10/19/12 ak replaced much more verbose code to get header with this */
  if((ip_hdr = trace_get_ip(ltpacket)) == NULL)
    {
      /* non-ipv4 packet */
      return 0;
    }

  /* get the transport header */
  if((temp = trace_get_transport(ltpacket, &proto, &remaining)) == NULL)
    {
      /* not enough payload */
      return 0;
    }

  findme.target_ip = 0;

  if(ip_hdr->ip_p == TRACE_IPPROTO_ICMP && remaining >= 2)
    {
      icmp_hdr = (libtrace_icmp_t *)temp;

      if((icmp_hdr->type == 3  ||
	  icmp_hdr->type == 4  ||
	  icmp_hdr->type == 5  ||
	  icmp_hdr->type == 11 ||
	  icmp_hdr->type == 12) &&
	 ((temp = trace_get_payload_from_icmp(icmp_hdr, &remaining)) != NULL
	 && remaining >= 20 && (inner_ip_hdr = (libtrace_ip_t *)temp) &&
	  inner_ip_hdr->ip_v == 4))
	{
	  /* icmp error message */
	  if(inner_ip_hdr->ip_src.s_addr != ip_hdr->ip_dst.s_addr)
	    {
	      STATE(corsaro)->number_mismatched_packets++;
	    }

	  findme.target_ip = ntohl(inner_ip_hdr->ip_dst.s_addr);

	  /* just extract the first four bytes of payload as ports */
	  if((temp = trace_get_payload_from_ip(inner_ip_hdr, NULL,
					       &remaining)) != NULL
	     && remaining >= 4)
	    {
	      attacker_port = ntohs(((struct ports_t *)temp)->src);
	      target_port = ntohs(((struct ports_t *)temp)->dst);
	    }
	}
      else
	{
	  findme.target_ip =  ntohl(ip_hdr->ip_src.s_addr);
	  attacker_port = ntohs(icmp_hdr->code);
	  target_port = ntohs(icmp_hdr->type);
	}
    }
  else if((ip_hdr->ip_p == TRACE_IPPROTO_TCP ||
	  ip_hdr->ip_p == TRACE_IPPROTO_UDP) &&
	  remaining >= 4)
    {
      findme.target_ip = ntohl(ip_hdr->ip_src.s_addr);
      attacker_port = trace_get_destination_port(ltpacket);
      target_port = trace_get_source_port(ltpacket);
    }

  if(findme.target_ip == 0)
    {
      /* the packet is none of ICMP, TCP or UDP */
      return 0;
    }

  tv = trace_get_timeval(ltpacket);

  /* is this vector in the hash? */
  assert(STATE(corsaro)->attack_hash != NULL);
  if((khiter = kh_get(av, STATE(corsaro)->attack_hash, &findme))
     != kh_end(STATE(corsaro)->attack_hash))
    {
      /* the vector is in the hash */
      vector = kh_key(STATE(corsaro)->attack_hash, khiter);

      if(attack_vector_is_expired(vector, tv.tv_sec) != 0)
	{
	  kh_del(av, STATE(corsaro)->attack_hash, khiter);
	  attack_vector_free(vector);
	  vector = NULL;
	}
    }

  if(vector == NULL)
    {
      /* create a new vector and fill it */
      if((vector = attack_vector_init(corsaro)) == NULL)
	{
	  corsaro_log(__func__, corsaro, "failed to create new attack vector");
	  return -1;
	}

      /* i think this may be buggy. do it the safe way for now
      vector->initial_packet = corsaro_mincopy_packet(packet);
      */
      vector->initial_packet_len = trace_get_capture_length(ltpacket);

      if((vector->initial_packet = malloc(vector->initial_packet_len)) == NULL)
	{
	  corsaro_log(__func__, corsaro, "could not malloc initial packet");
	  return -1;
	}

      if((pkt_buf = trace_get_packet_buffer(ltpacket,
					    &linktype, NULL)) == NULL)
	{
	  corsaro_log(__func__, corsaro, "could not get packet buffer");
	  return -1;
	}

      memcpy(vector->initial_packet, pkt_buf, vector->initial_packet_len);

      vector->attacker_ip = ntohl(ip_hdr->ip_dst.s_addr);
      vector->responder_ip = ntohl(ip_hdr->ip_src.s_addr);
      vector->target_ip = findme.target_ip;

      vector->start_time = tv;

      vector->ppm_window.window_start = tv.tv_sec;

      /* add to the hash */
      khiter = kh_put(av, STATE(corsaro)->attack_hash, vector, &khret);
    }

  assert(vector != NULL);

  vector->packet_cnt++;
  vector->interval_packet_cnt++;
  vector->byte_cnt += ntohs(ip_hdr->ip_len);
  vector->interval_byte_cnt += ntohs(ip_hdr->ip_len);

  vector->latest_time = tv;
  /* update the pps window */
  attack_vector_update_ppm_window(vector, tv);

  /* add the attacker ip to the hash */
  kh_put(32xx, vector->attack_ip_hash, ntohl(ip_hdr->ip_dst.s_addr), &khret);

  /* add the ports to the hashes */
  kh_put(32xx, vector->attack_port_hash, attacker_port, &khret);
  kh_put(32xx, vector->target_port_hash, target_port, &khret);

  return 0;
}