Exemplo n.º 1
0
static int pcapint_write_packet(libtrace_out_t *libtrace,
                                libtrace_packet_t *packet)
{
    int err;

    if (trace_get_link_type(packet) == TRACE_TYPE_NONDATA)
        return 0;

    if (!OUTPUT.trace.pcap) {
        OUTPUT.trace.pcap = (pcap_t *)pcap_open_live(
                                libtrace->uridata,65536,0,0,NULL);
    }
#ifdef HAVE_PCAP_INJECT
    err=pcap_inject(OUTPUT.trace.pcap,
                    packet->payload,
                    trace_get_capture_length(packet));
    if (err!=(int)trace_get_capture_length(packet))
        err=-1;
#else
#ifdef HAVE_PCAP_SENDPACKET
    err=pcap_sendpacket(OUTPUT.trace.pcap,
                        packet->payload,
                        trace_get_capture_length(packet));
#else
    trace_set_err(packet->trace,TRACE_ERR_UNSUPPORTED,"writing is not supported on this platform");
    return -1;
#endif
#endif
    return err;
}
Exemplo n.º 2
0
static size_t pcap_set_capture_length(libtrace_packet_t *packet,size_t size) {
    struct pcap_pkthdr *pcapptr = 0;
    assert(packet);
    if (size > trace_get_capture_length(packet)) {
        /* Can't make a packet larger */
        return trace_get_capture_length(packet);
    }
    /* Reset the cached capture length */
    packet->capture_length = -1;
    pcapptr = (struct pcap_pkthdr *)packet->header;
    pcapptr->caplen = size;
    return trace_get_capture_length(packet);
}
Exemplo n.º 3
0
void per_packet(libtrace_packet_t *packet)
{
	struct timeval ts;

	/* Get the timestamp for the current packet */
	ts = trace_get_timeval(packet);

	/* If next_report is zero, then this is the first packet from the
	 * trace so we need to determine the time at which the first report
	 * must occur, i.e. 10 seconds from now. */
	if (next_report == 0) {
		next_report = ts.tv_sec + 10;

		/* This is also a good opportunity to print column headings */
		printf("Time\t\tWire Length\tCapture Length\n");
	}

	/* Check whether we need to report average packet sizes or not.
	 *
	 * If the timestamp for the current packet is beyond the time when the
	 * next report was due then we have to output our current stats and
	 * reset it to zero.
	 *
	 * Note that I use a while loop here to ensure that we correctly deal
	 * with periods in which no packets are observed.
	 */
	while (ts.tv_sec > next_report) {

		/* Print the timestamp for the report */
		printf("%u\t", next_report);

		/* Calculate and print the average wire length */
		printf("%.2f\t\t", ((double)wire_count) / packet_count);

		/* Calculate and print the average capture length */
		printf("%.2f\n", ((double)capture_count) / packet_count);

		/* Reset the counters */
		packet_count = 0;
		wire_count = 0;
		capture_count = 0;

		/* Determine when the next report is due */
		next_report += 10;
	}

	/* Increment our counters */

	/* Packet count is easy to keep track of */
	packet_count += 1;

	/* Use trace_get_wire_length() to increment our wire length counter */
	wire_count += trace_get_wire_length(packet);

	/* trace_get_capture_length() will tell us the capture length of the
	 * packet */
	capture_count += trace_get_capture_length(packet);

}
Exemplo n.º 4
0
void misc_per_packet(struct libtrace_packet_t *packet)
{
	double ts = trace_get_seconds(packet);
	if (!has_starttime || starttime > ts)
		starttime = ts;
	if (!has_endtime || endtime < ts)
		endtime = ts;
	has_starttime = has_endtime = true;
	++packets;
	capture_bytes += trace_get_capture_length(packet) + trace_get_framing_length(packet);
}
Exemplo n.º 5
0
off_t corsaro_file_write_packet(corsaro_t *corsaro,
			      corsaro_file_t *file, libtrace_packet_t *packet)
{
  uint8_t *pkt_buf = NULL;
  libtrace_linktype_t linktype;

  switch(file->mode)
    {
    case CORSARO_FILE_MODE_ASCII:
      assert(file->wand_io != NULL);
#ifdef HAVE_LIBPACKETDUMP
      corsaro_log(__func__, corsaro,
		"libpacketdump currently does not support dumping "
		"to a file");
      return 0;
#else
      corsaro_log(__func__, corsaro,
		"corsaro must be built with libpacketdump to dump "
		"a packet to ASCII");
      return 0;
#endif
      break;

    case CORSARO_FILE_MODE_BINARY:
      assert(file->wand_io != NULL);
      if((pkt_buf = trace_get_packet_buffer(packet,
					    &linktype, NULL)) == NULL)
	{
	  corsaro_log(__func__, corsaro, "could not get packet buffer");
	  return -1;
	}
      return corsaro_file_write(corsaro, file, pkt_buf,
			      trace_get_capture_length(packet));

    case CORSARO_FILE_MODE_TRACE:
        assert(file->trace_io != NULL);
      return trace_write_packet(file->trace_io, packet);

    default:
      corsaro_log(__func__, corsaro, "invalid corsaro file mode %d", file->mode);
      return -1;
    }

  return -1;
}
Exemplo n.º 6
0
static gboolean qfTraceHandlePacket(qfTraceSource_t    *lts,
                                    yfPBuf_t           *pbuf,
                                    qfContext_t        *ctx)
{
    yfIPFragInfo_t              fraginfo_buf,
                                *fraginfo = ctx->fragtab ?
                                &fraginfo_buf : NULL;
    libtrace_linktype_t         linktype;
    uint8_t                     *pkt;
    uint32_t                    caplen;
    
    struct timeval tv;
    
    /* extract data from libtrace */
    tv = trace_get_timeval(lts->packet);
    pkt = trace_get_packet_buffer(lts->packet, &linktype, &caplen);

    /* Decode packet into packet buffer */
    if (!yfDecodeToPBuf(ctx->dectx,
                        linktype,
                        yfDecodeTimeval(&tv),
                        trace_get_capture_length(lts->packet),
                        pkt, fraginfo, pbuf))
    {
        /* Couldn't decode packet; counted in dectx. Skip. */
        return FALSE;
    }
    
#if QOF_ENABLE_DETUNE
    /* Signal drop if detune says so */
    if (ctx->ictx.detune) {
        if (!qfDetunePacket(ctx->ictx.detune, &pbuf->ptime, pbuf->iplen)) {
            return FALSE;
        }
    }
#endif
    
    /* Handle fragmentation if necessary */
    if (fraginfo && fraginfo->frag) {
        yfDefragPBuf(ctx->fragtab, fraginfo, pbuf, pkt, caplen);
    }
    
    /* signal packet processed */
    return TRUE;
}
Exemplo n.º 7
0
/* Return values:
 *  1 = continue reading packets
 *  0 = stop reading packets, cos we're done
 *  -1 = stop reading packets, we've got an error
 */
static int per_packet(libtrace_packet_t *packet) {
        double ts = trace_get_seconds(packet);

	if (trace_get_link_type(packet) == ~0U) {
		fprintf(stderr, "Halted due to being unable to determine linktype - input trace may be corrupt.\n");
		return -1;
	}

	if (snaplen>0) {
		trace_set_capture_length(packet,snaplen);
	}

	if (ts <starttime) {
		return 1;
	}

	if ( ts > endtime) {
	  	//printf( "%f\t%f\n", ts, endtime);
		return 0;
	}

	if (firsttime==0) {
		time_t now = trace_get_seconds(packet);
		if (starttime != 0.0) {
			firsttime=now-((now - (int)starttime) % interval);
		}
		else {
			firsttime=now;
		}
	}

	if (output && trace_get_seconds(packet)>firsttime+interval) {
		trace_destroy_output(output);
		output=NULL;
		firsttime+=interval;
	}

	if (output && pktcount%count==0) {
		trace_destroy_output(output);
		output=NULL;
	}

	pktcount++;
	totbytes+=trace_get_capture_length(packet);
	if (output && totbytes-totbyteslast>=bytes) {
		trace_destroy_output(output);
		output=NULL;
		totbyteslast=totbytes;
	}
	if (!output) {
		char *buffer;
		bool need_ext=false;
		if (maxfiles <= filescreated) {
			return 0;
		}
		buffer=strdup(output_base);
		if (interval!=UINT64_MAX && maxfiles>1) {
			buffer=strdupcat(buffer,"-");
			buffer=strdupcati(buffer,(uint64_t)firsttime);
			need_ext=true;
		}
		if (count!=UINT64_MAX && maxfiles>1) {
			buffer=strdupcat(buffer,"-");
			buffer=strdupcati(buffer,(uint64_t)pktcount);
			need_ext=true;
		}
		if (bytes!=UINT64_MAX && maxfiles>1) {
			static int filenum=0;
			buffer=strdupcat(buffer,"-");
			buffer=strdupcati(buffer,(uint64_t)++filenum);
			need_ext=true;
		}
		if (need_ext) {
			if (compress_level!=0)
				buffer=strdupcat(buffer,".gz");
		}
		if (verbose>1) {
			fprintf(stderr,"%s:",buffer);
			if (count!=UINT64_MAX)
				fprintf(stderr," count=%" PRIu64,pktcount);
			if (bytes!=UINT64_MAX)
				fprintf(stderr," bytes=%" PRIu64,bytes);
			if (interval!=UINT64_MAX) {
				time_t filetime = firsttime;
				fprintf(stderr," time=%s",ctime(&filetime));
			}
			else {
				fprintf(stderr,"\n");
			}
		}
		output=trace_create_output(buffer);
		if (trace_is_err_output(output)) {
			trace_perror_output(output,"%s",buffer);
			free(buffer);
			return -1;
		}
		if (compress_level!=-1) {
			if (trace_config_output(output,
						TRACE_OPTION_OUTPUT_COMPRESS,
						&compress_level)==-1) {
				trace_perror_output(output,"Unable to set compression level");
			}
		}

		if (trace_config_output(output,
					TRACE_OPTION_OUTPUT_COMPRESSTYPE,
					&compress_type) == -1) {
			trace_perror_output(output, "Unable to set compression type");
		}

		trace_start_output(output);
		if (trace_is_err_output(output)) {
			trace_perror_output(output,"%s",buffer);
			free(buffer);
			return -1;
		}
		free(buffer);
		filescreated ++;
	}

	/* Some traces we have are padded (usually with 0x00), so 
	 * lets sort that out now and truncate them properly
	 */

	if (trace_get_capture_length(packet) 
			> trace_get_wire_length(packet)) {
		trace_set_capture_length(packet,trace_get_wire_length(packet));
	}

	if (trace_write_packet(output,packet)==-1) {
		trace_perror_output(output,"write_packet");
		return -1;
	}

	return 1;

}
Exemplo n.º 8
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;
}