static libtrace_eventobj_t trace_event_rt(libtrace_t *trace, libtrace_packet_t *packet) { libtrace_eventobj_t event = {0,0,0.0,0}; libtrace_err_t read_err; assert(trace); assert(packet); if (trace->format->get_fd) { event.fd = trace->format->get_fd(trace); } else { event.fd = 0; } do { event.size = rt_read_packet_versatile(trace, packet, 0); if (event.size == -1) { read_err = trace_get_err(trace); if (read_err.err_num == EAGAIN) { /* No data available - do an IOWAIT */ event.type = TRACE_EVENT_IOWAIT; } else { trace_perror(trace, "Error doing a non-blocking read from rt"); event.type = TRACE_EVENT_PACKET; break; } } else if (event.size == 0) { /* RT gives us a specific indicator that there will be * no more packets. */ if (packet->type == TRACE_RT_END_DATA) event.type = TRACE_EVENT_TERMINATE; else /* Since several RT messages can have zero-byte * length (once the framing is removed), an * event size of zero can still indicate a * PACKET event */ event.type = TRACE_EVENT_PACKET; } else { event.type = TRACE_EVENT_PACKET; } if (trace->filter && event.type == TRACE_EVENT_PACKET) { if (!trace_apply_filter(trace->filter, packet)) { trace_clear_cache(packet); continue; } } break; } while (1); return event; }
/* Attempts to read a packet from a DAG card in a NON-BLOCKING fashion. If * a packet is available, we will return a packet event. Otherwise we will * return a SLEEP event (as we cannot select on the DAG file descriptor). */ static libtrace_eventobj_t trace_event_dag(libtrace_t *trace, libtrace_packet_t *packet) { libtrace_eventobj_t event = {0,0,0.0,0}; int data; do { data = dag_available(trace); /* If no data is available, drop out and return a sleep event */ if (data <= 0) break; /* Data is available, so we can call the blocking read because * we know that we will get a packet straight away */ event.size = dag_read_packet(trace,packet); //DATA(trace)->dag.diff -= event.size; /* XXX trace_read_packet() normally applies the following * config options for us, but this function is called via * trace_event() so we have to do it ourselves */ /* Check that the packet matches any pre-existing filter */ if (trace->filter) { if (trace_apply_filter(trace->filter, packet)) { event.type = TRACE_EVENT_PACKET; } else { /* Do not sleep - try to read another packet */ trace->filtered_packets ++; continue; } } else { event.type = TRACE_EVENT_PACKET; } /* If the user has specified a snap length, apply that too */ if (trace->snaplen > 0) { trace_set_capture_length(packet, trace->snaplen); } trace->accepted_packets ++; return event; } while (1); /* We only want to sleep for a very short time */ assert(data == 0); event.type = TRACE_EVENT_SLEEP; event.seconds = 0.0001; event.size = 0; return event; }
/* 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); }