head 1.1; access; symbols; locks; strict; comment @ * @; 1.1 date 2008.04.21.23.39.06; author wessels; state Exp; branches; next ; desc @@ 1.1 log @Initial revision @ text @#include #include #include #include #include #include #include #include #include #include #include #include #include #define XCMP(X,Y) (XY?1:0)) int SORTSIZE = 256; struct _pkt { struct pcap_pkthdr hdr; u_char *data; }; int npkts = 0; struct _pkt *packets; struct timeval max_flushed = {0,0}; int cmp_timeval(struct timeval a, struct timeval b) { return (a.tv_sec == b.tv_sec) ? XCMP(a.tv_usec,b.tv_usec) : XCMP(a.tv_sec,b.tv_sec); } int sorter(const void *A, const void *B) { struct _pkt *a = (struct _pkt *) A; struct _pkt *b = (struct _pkt *) B; return cmp_timeval(a->hdr.ts, b->hdr.ts); } void flush(pcap_dumper_t *out, int keep) { int i; qsort(packets, npkts, sizeof(struct _pkt), sorter); for (i=0; i<(npkts-keep); i++) { pcap_dump((void *)out, &packets[i].hdr, packets[i].data); free(packets[i].data); } max_flushed = packets[i-1].hdr.ts; if (keep) memmove(&packets[0], &packets[npkts-keep], keep * sizeof(struct _pkt)); npkts = keep; } void push(struct pcap_pkthdr *hdr, const u_char *data) { assert (npkts < SORTSIZE); packets[npkts].hdr = *hdr; packets[npkts].data = malloc(hdr->caplen); memcpy(packets[npkts].data, data, hdr->caplen); if (cmp_timeval(max_flushed, hdr->ts) > 0) { warnx("sortsize %d is not large enough " "to fully sort this file. " "flushed=%10lld.%06lldd, this=%10lld.%06lld", SORTSIZE, (long long int) max_flushed.tv_sec, (long long int) max_flushed.tv_usec, (long long int) hdr->ts.tv_sec, (long long int) hdr->ts.tv_usec); } npkts++; } int main(int argc, char *argv[]) { pcap_t *in = NULL; pcap_dumper_t *out = NULL; char errbuf[PCAP_ERRBUF_SIZE + 1]; struct pcap_pkthdr hdr; const u_char *data; if (argc < 2) { fprintf(stderr, "usage: tcpdump-reorder sortsize\n"); exit(1); } SORTSIZE = atoi(argv[1]); if (SORTSIZE < 2) { fprintf(stderr, "sortsize should be greater than 1\n"); exit(1); } packets = calloc(SORTSIZE, sizeof(struct _pkt)); in = pcap_open_offline("-", errbuf); if (NULL == in) { fprintf(stderr, "stdin: %s", errbuf); exit(1); } out = pcap_dump_open(in, "-"); if (NULL == out) { perror("stdout"); exit(1); } while ((data = pcap_next(in, &hdr))) { push(&hdr, data); if (SORTSIZE == npkts) flush(out, npkts/2); } pcap_close(in); flush(out, 0); pcap_dump_close(out); exit(0); } @