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; }
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); }
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); }
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); }
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; }
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; }
/* 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; }
/** 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; }