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); }
int main(int argc, char *argv[]) { char *uri = lookup_uri(argv[1]); int psize = 0; int error = 0; int count = 0; libtrace_packet_t *packet; trace = trace_create(uri); iferr(trace); trace_start(trace); iferr(trace); packet=trace_create_packet(); for (;;) { double ts; double tsdiff; struct timeval tv; if ((psize = trace_read_packet(trace, packet)) <0) { error = 1; break; } if (psize == 0) { error = 0; break; } count ++; tv=trace_get_timeval(packet); ts=trace_get_seconds(packet); tsdiff = (tv.tv_sec+tv.tv_usec/1000000.0)-ts; assert(tsdiff > -0.001 && tsdiff < 0.001); } trace_destroy_packet(packet); if (error == 0) { if (count == 100) { printf("success: 100 packets read\n"); } else { printf("failure: 100 packets expected, %d seen\n",count); error = 1; } } else { iferr(trace); } trace_destroy(trace); return error; }
static void per_packet(libtrace_packet_t *packet) { /* Packet data */ uint32_t remaining; /* L3 data */ void *l3; uint16_t ethertype; /* Transport data */ void *transport; uint8_t proto; /* Payload data */ void *payload; if (lastts < 1) lastts = trace_get_seconds(packet); if (lastts+1.0 < trace_get_seconds(packet)) { ++lastts; printf("%.03f,",lastts); printf("%"PRIu64",%"PRIu64",",v4,v6); printf("%"PRIu64",%"PRIu64",%"PRIu64,icmp,tcp,udp); printf("\n"); v4=v6=0; icmp=tcp=udp=0; } l3 = trace_get_layer3(packet,ðertype,&remaining); if (!l3) /* Probable ARP or something */ return; /* Get the UDP/TCP/ICMP header from the IPv4/IPv6 packet */ switch (ethertype) { case 0x0800: transport = trace_get_payload_from_ip( (libtrace_ip_t*)l3, &proto, &remaining); if (!transport) return; ++v4; break; case 0x86DD: transport = trace_get_payload_from_ip6( (libtrace_ip6_t*)l3, &proto, &remaining); if (!transport) return; ++v6; break; default: return; } /* Parse the udp/tcp/icmp payload */ switch(proto) { case 1: ++icmp; return; case 6: payload = trace_get_payload_from_tcp( (libtrace_tcp_t*)transport, &remaining); if (!payload) return; ++tcp; break; case 17: payload = trace_get_payload_from_udp( (libtrace_udp_t*)transport, &remaining); if (!payload) return; ++udp; break; default: return; } ++ok; }
int main(int argc, char *argv[]) { char *uri = 0; int psize = 0; struct libtrace_ip *ipptr = 0; struct libtrace_packet_t *packet = trace_create_packet(); libtrace_err_t trace_err; uint32_t last_second = 0; double ts = 0.0; if (argc == 2) { uri = strdup(argv[1]); } // create an trace to uri trace = trace_create(uri); if (trace_is_err(trace)) { trace_err = trace_get_err(trace); printf("Error in trace_create: %s\n", trace_err.problem); return -1; } trace_start(trace); if (trace_is_err(trace)) { trace_err = trace_get_err(trace); printf("Error in trace_start: %s\n", trace_err.problem); return -1; } for (;;) { if ((psize = trace_read_packet(trace,packet)) < 1) { // terminate break; } if (psize == 0) { continue; } if((ipptr = trace_get_ip(packet)) == 0) { continue; } counter[BYTES][INSTANT] += ntohs(ipptr->ip_len); counter[PACKETS][INSTANT] ++; ts = trace_get_seconds(packet); if(last_second == 0) { last_second = ts; } else if (last_second < ts) { last_second = ts; docalc++; } if(docalc) { secondreport(); } } trace_destroy(trace); return 0; }
/* * Updates the RTT estimates given a new packet belonging to the flow. */ void rtt_handshake_update (void *data, struct libtrace_packet_t *packet) { struct rtt_handshake_record_t *record = (struct rtt_handshake_record_t *) data; struct libtrace_tcp *tcp; double time; int direction; // If a session has been established then skip all calculations. if (!record->established) { if ((tcp = trace_get_tcp (packet)) == NULL) return; time = trace_get_seconds (packet); direction = trace_get_direction (packet); // Check that the direction is ok if(!(direction==0 || direction==1)) return; // Check if the packet is a SYN, a SYN/ACK or an ACK if (tcp->syn) { if (tcp->ack) { // If the SYN/ACK is a retransmit, then we must not // update the rtt to the origin of the SYN/ACK but // only to the destination. if (direction == 0) { //outbound, so incoming syn if(record->rtt_in < 0.0) { // Do not update if rtt already set record->rtt_in += time; } record->rtt_out = -time; } else { if(record->rtt_out < 0.0) { record->rtt_out += time; } record->rtt_in = -time; } } else { if(direction == 0) { record->rtt_out = -time; } else { record->rtt_in = -time; } } } else if (tcp->ack) { // ack - syn_ack gives the time for the other direction if (direction == 0) { //outbound, so incoming syn_ack record->rtt_in += time; } else { record->rtt_out += time; } record->established = 1; } } }
/* 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 per_packet(libtrace_packet_t *packet, tcp_session_t *session) { int dir; double ts, rttsample; if (session == NULL) { return; // was not a tcp packet } ts = trace_get_seconds(packet); dir = trace_get_direction(packet); if (!(dir==OUT || dir==IN)) return; if (last_report_ts == 0) { last_report_ts = ts; } // time interval based reporting while (packet_interval != UINT32_MAX && last_report_ts+packet_interval<ts && (report_periods == UINT64_MAX || reported < report_periods)) { last_report_ts+=packet_interval; if (report_rel_time) { print_report(packet_interval); } else { print_report(last_report_ts); } } // did this packet create a new sample ? if (ts == rtt_n_sequence_last_sample_ts(session->data[0]) && dir == rtt_n_sequence_last_sample_dir(session->data[0])) { // update RTT stats if we got a valid sample rttsample = rtt_n_sequence_last_sample_value(session->data[0]); if (rttsample > 0) { rttsample = rttsample * 1000.0; // in ms reports[dir].count += 1; reports[dir].sum += rttsample; reports[dir].ssq += (rttsample*rttsample); if (reports[dir].min < 0 || rttsample < reports[dir].min) reports[dir].min = rttsample; if (reports[dir].max < 0 || rttsample > reports[dir].max) reports[dir].max = rttsample; } } if (packet_count != UINT64_MAX && (reports[OUT].count+reports[IN].count) > 0 && (reports[OUT].count+reports[IN].count)%packet_count == 0 && (report_periods == UINT64_MAX || reported < report_periods)) { if (report_rel_time) { print_report(ts-last_report_ts); } else { print_report(ts); } last_report_ts = ts; } last_packet_ts = ts; }
int main(int argc, char *argv[]) { libtrace_t *trace; libtrace_packet_t *packet; libtrace_filter_t *filter=NULL; session_manager_t *sm; uint64_t f; while(1) { int option_index; struct option long_options[] = { { "filter", 1, 0, 'f' }, { "interval", 1, 0, 'i' }, { "count", 1, 0, 'c' }, { "exit", 1, 0, 'e' }, { "relative", 0, 0, 'r' }, { "help", 0, 0, 'h' }, { "libtrace-help",0, 0, 'H' }, { NULL, 0, 0, 0 } }; int c= getopt_long(argc, argv, "c:e:f:i:hHr", long_options, &option_index); if (c==-1) break; switch (c) { case 'f': filter=trace_create_filter(optarg); break; case 'i': packet_interval=atof(optarg); break; case 'c': packet_count=atoi(optarg); packet_interval=UINT32_MAX; // make sure only one is defined break; case 'e': report_periods=atoi(optarg); break; case 'r': report_rel_time = 1; break; case 'H': trace_help(); return 1; default: fprintf(stderr,"Unknown option: %c\n",c); /* FALL THRU */ case 'h': usage(argv[0]); return 1; } } if (optind>=argc) { fprintf(stderr,"Missing input uri\n"); usage(argv[0]); return 1; } while (optind<argc) { // create tcp session manager sm = session_manager_create(); // create and register the data-ack based RTT module session_manager_register_module(sm,rtt_n_sequence_module()); fprintf(stderr, "Processing %s\n",argv[optind]); trace = trace_create(argv[optind]); ++optind; if (trace_is_err(trace)) { trace_perror(trace,"Opening trace file"); return 1; } if (filter && trace_config(trace,TRACE_OPTION_FILTER,filter)==1) { trace_perror(trace,"Configuring filter"); } if (trace_start(trace)) { trace_perror(trace,"Starting trace"); trace_destroy(trace); return 1; } packet = trace_create_packet(); print_report_hdr(); reset_report(); last_report_ts = 0; last_packet_ts = 0; while (trace_read_packet(trace,packet)>0) { per_packet(packet,session_manager_update(sm,packet)); if (report_periods != UINT64_MAX && reported >= report_periods) { break; } } // remaining pkts (or all if no period set) if ((reports[OUT].count+reports[IN].count) > 0 || (packet_interval == UINT32_MAX && packet_count == UINT64_MAX)) { double ts = trace_get_seconds(packet); if (report_rel_time) { print_report(ts-last_report_ts); } else { print_report(ts); } } trace_destroy_packet(packet); if (trace_is_err(trace)) { trace_perror(trace,"Reading packets"); } // some stats f=trace_get_received_packets(trace); if (f!=UINT64_MAX) fprintf(stderr,"%" PRIu64 " packets on input\n",f); f=trace_get_filtered_packets(trace); if (f!=UINT64_MAX) fprintf(stderr,"%" PRIu64 " packets filtered\n",f); f=trace_get_dropped_packets(trace); if (f!=UINT64_MAX) fprintf(stderr,"%" PRIu64 " packets dropped\n",f); f=trace_get_accepted_packets(trace); if (f!=UINT64_MAX) fprintf(stderr,"%" PRIu64 " packets accepted\n",f); trace_destroy(trace); session_manager_destroy(sm); } return 0; }
/* Process a trace, counting packets that match filter(s) */ static void run_trace(char *uri) { struct libtrace_packet_t *packet = trace_create_packet(); int i; uint64_t count = 0; uint64_t bytes = 0; uint64_t packets; fprintf(stderr,"%s:\n",uri); trace = trace_create(uri); if (trace_is_err(trace)) { trace_perror(trace,"Failed to create trace"); return; } if (trace_start(trace)==-1) { trace_perror(trace,"Failed to start trace"); return; } for (;;) { int psize; int wlen; int match = 0; if ((psize = trace_read_packet(trace, packet)) <1) { break; } if (done) break; wlen = trace_get_wire_length(packet); for(i=0; i<filter_count; ++i) { if (filters[i].filter == NULL) continue; if(trace_apply_filter(filters[i].filter,packet) > 0) { ++filters[i].count; filters[i].bytes+=wlen; match = 1; } if (trace_is_err(trace)) { trace_perror(trace, "trace_apply_filter"); fprintf(stderr, "Removing filter from filterlist\n"); filters[i].filter = NULL; } } if(match == 1 || filter_count == 0) { libtrace_ip_t *ip_hdr = trace_get_ip(packet); if(ip_hdr != NULL) { char src_ip[INET_ADDRSTRLEN]; char dst_ip[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &ip_hdr->ip_src, &src_ip[0], INET_ADDRSTRLEN); inet_ntop(AF_INET, &ip_hdr->ip_dst, &dst_ip[0], INET_ADDRSTRLEN); printf("%f\t%s\t%s\t%"PRIu16"\t%"PRIu16"\t" "%"PRIu8"\t%"PRIu16"\t%"PRIu16"\n", trace_get_seconds(packet), src_ip, dst_ip, trace_get_source_port(packet), trace_get_destination_port(packet), ip_hdr->ip_p, ntohs(ip_hdr->ip_id), ntohs(ip_hdr->ip_len) ); } } ++count; bytes+=wlen; } fprintf(stderr, "%-30s\t%12s\t%12s\t%7s\n","filter","count","bytes","%"); for(i=0; i<filter_count; ++i) { fprintf(stderr, "%30s:\t%12"PRIu64"\t%12"PRIu64"\t%7.03f\n", filters[i].expr,filters[i].count, filters[i].bytes,filters[i].count*100.0/count); filters[i].bytes=0; filters[i].count=0; } packets=trace_get_received_packets(trace); if (packets!=UINT64_MAX) fprintf(stderr,"%30s:\t%12" PRIu64"\n", "Input packets", packets); packets=trace_get_filtered_packets(trace); if (packets!=UINT64_MAX) fprintf(stderr,"%30s:\t%12" PRIu64"\n", "Filtered packets", packets); packets=trace_get_dropped_packets(trace); if (packets!=UINT64_MAX) fprintf(stderr,"%30s:\t%12" PRIu64"\n", "Dropped packets",packets); packets=trace_get_accepted_packets(trace); if (packets!=UINT64_MAX) fprintf(stderr,"%30s:\t%12" PRIu64 "\n", "Accepted Packets",packets); fprintf(stderr, "%30s:\t%12"PRIu64"\t%12" PRIu64 "\n","Total",count,bytes); totcount+=count; totbytes+=bytes; if (trace_is_err(trace)) trace_perror(trace,"%s",uri); trace_destroy(trace); }