Exemple #1
0
void error_per_packet(struct libtrace_packet_t *packet)
{
	struct libtrace_ip *ip = trace_get_ip(packet);
	struct libtrace_tcp *tcp = trace_get_tcp(packet);
	void *link = trace_get_packet_buffer(packet,NULL,NULL);
	if (!link) {
		++rx_errors;
	}
	
	/* This isn't quite as simple as it seems.
	 *
	 * If the packets were captured via wdcap's anonymisation module,
	 * the checksum is set to 0 when it is correct and 1 if incorrect.
	 *
	 * If a different capture method is used, there's a good chance the
	 * checksum has not been altered
	 */
	if (ip) {
		if (ntohs(ip->ip_sum)!=0)
			++ip_errors;
	}
	if (tcp) {
		if (ntohs(tcp->check)!=0)
			++tcp_errors;
	}
}
Exemple #2
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;
}
Exemple #3
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;
}
Exemple #4
0
static int pcap_get_wire_length(const libtrace_packet_t *packet) {
    struct pcap_pkthdr *pcapptr = 0;
    pcapptr = (struct pcap_pkthdr *)packet->header;
    if (packet->type==pcap_linktype_to_rt(TRACE_DLT_EN10MB))
        return pcapptr->len+4; /* Include the missing FCS */
    else if (packet->type==pcap_linktype_to_rt(TRACE_DLT_IEEE802_11_RADIO)) {
        libtrace_linktype_t linktype;
        void *link = trace_get_packet_buffer(packet,&linktype,NULL);
        /* If the packet is Radiotap and the flags field indicates
         * that the FCS is not included in the 802.11 frame, then
         * we need to add 4 to the wire-length to account for it.
         */
        uint8_t flags;
        trace_get_wireless_flags(link,
                                 linktype, &flags);
        if ((flags & TRACE_RADIOTAP_F_FCS) == 0)
            return pcapptr->len + 4;
    }
    return pcapptr->len;
}
Exemple #5
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;
}
Exemple #6
0
DLLEXPORT void *trace_get_layer2(const libtrace_packet_t *packet,
                                 libtrace_linktype_t *linktype,
                                 uint32_t *remaining)
{
    uint32_t dummyrem;
    void *meta = NULL;

    assert(packet != NULL);
    assert(linktype != NULL);

    if (remaining == NULL)
        remaining = &dummyrem;

    if (packet->l2_header) {
        /* Use cached values */
        *linktype = packet->link_type;
        *remaining = packet->l2_remaining;
        return packet->l2_header;
    }

    /* Code looks a bit inefficient, but I'm actually trying to avoid
     * calling trace_get_packet_buffer more than once like we used to.
     */

    meta = trace_get_packet_buffer(packet, linktype, remaining);

    /* If there are no meta-data headers, we just return the start of the
     * packet buffer, along with the linktype, etc.
     */
    switch(*linktype) {
    /* meta points to a layer 2 header! */
    case TRACE_TYPE_HDLC_POS:
    case TRACE_TYPE_ETH:
    case TRACE_TYPE_ATM:
    case TRACE_TYPE_80211:
    case TRACE_TYPE_NONE:
    case TRACE_TYPE_POS:
    case TRACE_TYPE_AAL5:
    case TRACE_TYPE_DUCK:
    case TRACE_TYPE_LLCSNAP:
    case TRACE_TYPE_PPP:
    case TRACE_TYPE_METADATA:
    case TRACE_TYPE_NONDATA:
    case TRACE_TYPE_OPENBSD_LOOP:
        ((libtrace_packet_t*)packet)->l2_header = meta;
        ((libtrace_packet_t*)packet)->l2_remaining = *remaining;
        return meta;
    case TRACE_TYPE_LINUX_SLL:
    case TRACE_TYPE_80211_RADIO:
    case TRACE_TYPE_80211_PRISM:
    case TRACE_TYPE_PFLOG:
        break;
    case TRACE_TYPE_UNKNOWN:
        return NULL;
    }

    /* If there are meta-data headers, we need to skip over them until we
     * find a non-meta data header and return that.
     */
    for(;;) {
        void *nexthdr = trace_get_payload_from_meta(meta,
                        linktype, remaining);

        if (nexthdr == NULL) {
            switch (*linktype) {
            /* meta points to a layer 2 header! */
            case TRACE_TYPE_HDLC_POS:
            case TRACE_TYPE_ETH:
            case TRACE_TYPE_ATM:
            case TRACE_TYPE_80211:
            case TRACE_TYPE_NONE:
            case TRACE_TYPE_POS:
            case TRACE_TYPE_AAL5:
            case TRACE_TYPE_DUCK:
            case TRACE_TYPE_LLCSNAP:
            case TRACE_TYPE_PPP:
            case TRACE_TYPE_METADATA:
            case TRACE_TYPE_NONDATA:
            case TRACE_TYPE_OPENBSD_LOOP:
                ((libtrace_packet_t*)packet)->l2_header = meta;
                ((libtrace_packet_t*)packet)->l2_remaining = *remaining;
                return meta;
            case TRACE_TYPE_LINUX_SLL:
            case TRACE_TYPE_80211_RADIO:
            case TRACE_TYPE_80211_PRISM:
            case TRACE_TYPE_PFLOG:
                break;
            case TRACE_TYPE_UNKNOWN:
                return NULL;
            }

            /* Otherwise, we must have hit the end of the packet */
            return NULL;
        }


        meta = nexthdr;
    }

}
Exemple #7
0
static libtrace_direction_t pcap_get_direction(const libtrace_packet_t *packet) {
    libtrace_direction_t direction  = -1;
    switch(pcap_get_link_type(packet)) {
    /* Only packets encapsulated in Linux SLL or PFLOG have any
     * direction information */

    case TRACE_TYPE_LINUX_SLL:
    {
        libtrace_sll_header_t *sll;
        sll = trace_get_packet_buffer(packet, NULL, NULL);
        /* TODO: should check remaining>=sizeof(*sll) */
        if (!sll) {
            trace_set_err(packet->trace,
                          TRACE_ERR_BAD_PACKET,
                          "Bad or missing packet");
            return -1;
        }
        /* 0 == LINUX_SLL_HOST */
        /* the Waikato Capture point defines "packets
         * originating locally" (ie, outbound), with a
         * direction of 0, and "packets destined locally"
         * (ie, inbound), with a direction of 1.
         * This is kind-of-opposite to LINUX_SLL.
         * We return consistent values here, however
         *
         * Note that in recent versions of pcap, you can
         * use "inbound" and "outbound" on ppp in linux
         */
        if (sll->pkttype == TRACE_SLL_OUTGOING) {
            direction = TRACE_DIR_OUTGOING;
        } else {
            direction = TRACE_DIR_INCOMING;
        }
        break;

    }
    case TRACE_TYPE_PFLOG:
    {
        libtrace_pflog_header_t *pflog;
        pflog = trace_get_packet_buffer(packet, NULL, NULL);
        /* TODO: should check remaining >= sizeof(*pflog) */
        if (!pflog) {
            trace_set_err(packet->trace,
                          TRACE_ERR_BAD_PACKET,
                          "Bad or missing packet");
            return -1;
        }
        /* enum    { PF_IN=0, PF_OUT=1 }; */
        if (ntohs(pflog->dir==0)) {

            direction = TRACE_DIR_INCOMING;
        }
        else {
            direction = TRACE_DIR_OUTGOING;
        }
        break;
    }
    default:
        break;
    }
    return direction;
}
Exemple #8
0
static int pcap_write_packet(libtrace_out_t *libtrace,
                             libtrace_packet_t *packet)
{
    struct pcap_pkthdr pcap_pkt_hdr;
    void *link;
    libtrace_linktype_t linktype;
    uint32_t remaining;

    link = trace_get_packet_buffer(packet,&linktype,&remaining);

    /* We may have to convert this packet into a suitable PCAP packet */

    /* If this packet cannot be converted to a pcap linktype then
     * pop off the top header until it can be converted
     */
    while (libtrace_to_pcap_linktype(linktype)==TRACE_DLT_ERROR) {
        if (!demote_packet(packet)) {
            trace_set_err_out(libtrace,
                              TRACE_ERR_NO_CONVERSION,
                              "pcap does not support this format");
            return -1;
        }

        link = trace_get_packet_buffer(packet,&linktype,&remaining);
    }


    if (!OUTPUT.trace.pcap) {
        int linktype=libtrace_to_pcap_dlt(trace_get_link_type(packet));
        OUTPUT.trace.pcap = pcap_open_dead(linktype,65536);
        if (!OUTPUT.trace.pcap) {
            trace_set_err_out(libtrace,TRACE_ERR_INIT_FAILED,
                              "Failed to open dead trace: %s\n",
                              pcap_geterr(OUTPUT.trace.pcap));
        }
        OUTPUT.trace.dump = pcap_dump_open(OUTPUT.trace.pcap,
                                           libtrace->uridata);
        if (!OUTPUT.trace.dump) {
            char *errmsg = pcap_geterr(OUTPUT.trace.pcap);
            trace_set_err_out(libtrace,TRACE_ERR_INIT_FAILED,"Failed to open output file: %s\n",
                              errmsg ? errmsg : "Unknown error");
            return -1;
        }
    }

    /* Corrupt packet, or other "non data" packet, so skip it */
    if (link == NULL) {
        /* Return "success", but nothing written */
        return 0;
    }

    /* Check if the packet was captured using one of the PCAP formats */
    if (packet->trace->format == &pcap ||
            packet->trace->format == &pcapint) {
        /* Yes - this means we can write it straight out */
        pcap_dump((u_char*)OUTPUT.trace.dump,
                  (struct pcap_pkthdr *)packet->header,
                  packet->payload);
    } else {
        /* No - need to fill in a PCAP header with the appropriate
         * values */

        /* Leave the manual copy as it is, as it gets around
         * some OS's having different structures in pcap_pkt_hdr
         */
        struct timeval ts = trace_get_timeval(packet);
        pcap_pkt_hdr.ts.tv_sec = ts.tv_sec;
        pcap_pkt_hdr.ts.tv_usec = ts.tv_usec;
        pcap_pkt_hdr.caplen = remaining;
        /* trace_get_wire_length includes FCS, while pcap doesn't */
        if (trace_get_link_type(packet)==TRACE_TYPE_ETH)
            if (trace_get_wire_length(packet) >= 4) {
                pcap_pkt_hdr.len =
                    trace_get_wire_length(packet)-4;
            }
            else {
                pcap_pkt_hdr.len = 0;
            }
        else
            pcap_pkt_hdr.len = trace_get_wire_length(packet);

        assert(pcap_pkt_hdr.caplen<65536);
        assert(pcap_pkt_hdr.len<65536);

        pcap_dump((u_char*)OUTPUT.trace.dump, &pcap_pkt_hdr, packet->payload);
    }
    return 0;
}