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 bool pcapfile_can_write(libtrace_packet_t *packet) { /* Get the linktype */ libtrace_linktype_t ltype = trace_get_link_type(packet); if (ltype == TRACE_TYPE_PCAPNG_META || ltype == TRACE_TYPE_CONTENT_INVALID || ltype == TRACE_TYPE_UNKNOWN || ltype == TRACE_TYPE_ERF_META || ltype == TRACE_TYPE_NONDATA) { return false; } 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; }
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; }