static struct libtrace_out_t *create_output(char *uri) { struct libtrace_out_t *output = NULL; output = trace_create_output(uri); if (trace_is_err_output(output)) { trace_perror_output(output,"%s",uri); trace_destroy_output(output); return NULL; } /* Default values for now */ trace_start_output(output); if (trace_is_err_output(output)) { trace_perror_output(output,"%s",uri); trace_destroy_output(output); return NULL; } return output; }
/* Creates an output trace and configures it according to our preferences */ static libtrace_out_t *create_output(int my_id) { libtrace_out_t *out = NULL; char name[1024]; const char * file_index = NULL; const char * first_extension = NULL; file_index = strrchr(outputfile, '/'); if (file_index) first_extension = strchr(file_index, '.'); else first_extension = strchr(name, '.'); if (first_extension) { snprintf(name, sizeof(name), "%.*s-%d%s", (int) (first_extension - outputfile), outputfile, my_id, first_extension); } else { snprintf(name, sizeof(name), "%s-%d", outputfile, my_id); } out = trace_create_output(name); assert(out); if (compress_level >= 0 && trace_config_output(out, TRACE_OPTION_OUTPUT_COMPRESS, &compress_level) == -1) { trace_perror_output(out, "Configuring compression level"); trace_destroy_output(out); exit(-1); } if (trace_config_output(out, TRACE_OPTION_OUTPUT_COMPRESSTYPE, &compress_type) == -1) { trace_perror_output(out, "Configuring compression type"); trace_destroy_output(out); exit(-1); } if (trace_start_output(out)==-1) { trace_perror_output(out,"trace_start_output"); trace_destroy_output(out); exit(-1); } return out; }
int main(int argc, char *argv[]) { struct libtrace_t *input = NULL; struct libtrace_out_t *in_write = NULL; struct libtrace_out_t *out_write = NULL; libtrace_err_t trace_err; struct libtrace_packet_t *packet = trace_create_packet(); if (argc < 3) { usage(argv[0]); return 1; } input = trace_create(argv[1]); if (trace_is_err(input)) { trace_err = trace_get_err(input); printf("Problem reading input trace: %s\n", trace_err.problem); return 1; } if (trace_start(input)==-1) { trace_perror(input,"Unable to start trace: %s",argv[1]); return 1; } while(1) { if (trace_read_packet(input, packet) < 1) break; switch(trace_get_direction(packet)) { case TRACE_DIR_INCOMING: if (!out_write) { out_write = create_output(argv[3]); if (!out_write) return 1; } if (trace_write_packet(out_write, packet)==-1){ trace_perror_output(in_write,"write"); return 1; } break; case TRACE_DIR_OUTGOING: if (!in_write) { in_write = create_output(argv[2]); if (!in_write) return 1; } if (trace_write_packet(in_write, packet)==-1) { trace_perror_output(in_write,"write"); return 1; } break; default: ignored++; } } if (out_write) trace_destroy_output(out_write); if (in_write) trace_destroy_output(in_write); trace_destroy(input); trace_destroy_packet(packet); if (ignored) fprintf(stderr,"warning: Ignored %" PRIu64 " packets with unknown directions\n", ignored); return 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; }
static void pkt(struct lfc *lfc, void *pdata, struct lfc_flow *lf, void *data, double ts, bool up, bool is_new, libtrace_packet_t *pkt) { struct flow *f = data; char *name, *uri; libtrace_out_t *out; if (f->ignore) return; if (is_new) { /* find the flow by its id in the ARFF file, get output file name */ name = thash_uint_get(fd->cache, lf->id); if (!name) { cache_update(); name = thash_uint_get(fd->cache, lf->id); if (!name) { f->ignore = true; thash_uint_set(fd->cache, lf->id, NULL); return; } } /* ignore flows with column values we are not interested in */ if (fd->value && !streq(fd->value, name)) { f->ignore = true; thash_uint_set(fd->cache, lf->id, NULL); return; } /* get libtrace output file */ out = thash_get(fd->out_files, name); if (!out) { uri = mmatic_sprintf(fd->mm, "pcap:%s/%s.pcap", fd->dir, name); out = trace_create_output(uri); if (!out) { cleanup(); die("trace_create_output(%s) failed\n", uri); } if (trace_is_err_output(out)) { trace_perror_output(out, "Opening output trace file"); cleanup(); die("trace_create_output(%s) failed\n", uri); } if (trace_start_output(out) == -1) { trace_perror_output(out, "Starting output trace"); cleanup(); die("trace_start_output(%s) failed\n", uri); } thash_set(fd->out_files, name, out); } f->out = out; /* remove id from cache */ thash_uint_set(fd->cache, lf->id, NULL); } trace_write_packet(f->out, pkt); if (trace_is_err_output(f->out)) { trace_perror_output(f->out, "Writing packet to output trace file"); cleanup(); die("trace_write_packet() failed\n"); } }