static int linuxnative_start_output(libtrace_out_t *libtrace) { FORMAT_DATA_OUT->fd = socket(PF_PACKET, SOCK_RAW, 0); if (FORMAT_DATA_OUT->fd==-1) { free(FORMAT_DATA_OUT); trace_set_err_out(libtrace, errno, "Failed to create raw socket"); return -1; } return 0; }
static int pcapfile_init_output(libtrace_out_t *libtrace) { libtrace->format_data = malloc(sizeof(struct pcapfile_format_data_out_t)); if (!libtrace->format_data) { trace_set_err_out(libtrace, TRACE_ERR_INIT_FAILED, "Unable to allocate memory for " "format data inside pcapfile_init_output()"); return -1; } DATAOUT(libtrace)->file=NULL; DATAOUT(libtrace)->compress_type=TRACE_OPTION_COMPRESSTYPE_NONE; DATAOUT(libtrace)->level=0; DATAOUT(libtrace)->flag=O_CREAT|O_WRONLY; return 0; }
static int pcapint_init_output(libtrace_out_t *libtrace) { #ifdef HAVE_PCAP_INJECT libtrace->format_data = malloc(sizeof(struct pcap_format_data_out_t)); OUTPUT.trace.pcap = NULL; OUTPUT.trace.dump = NULL; return 0; #else #ifdef HAVE_PCAP_SENDPACKET libtrace->format_data = malloc(sizeof(struct pcap_format_data_out_t)); OUTPUT.trace.pcap = NULL; OUTPUT.trace.dump = NULL; return 0; #else trace_set_err_out(libtrace,TRACE_ERR_UNSUPPORTED, "writing not supported by this version of pcap"); return -1; #endif #endif }
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; }