source: tools/tracereport/tracereport.c @ 8e11beb

cachetimestampsdevelopdpdk-ndagetsilivendag_formatrc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformance
Last change on this file since 8e11beb was 8e11beb, checked in by Shane Alcock <salcock@…>, 4 years ago

Update tools to properly ignore meta records and missing timestamps

pcapng introduces a lot of meta records that we should preserve as
long as possible. Since we aren't automatically discarding them,
we need to make sure that our tools do not try to treat them as
"real" packets, i.e. try to get a timestamp or capture length from
them.

Similarly, simple pcapng packet records do not have a timestamp
so we need to make sure the tools do the right thing when
trace_get_seconds() returns a timestamp of zero on a packet. For
starters, we don't want to set our "first" packet time to zero
in that case!

  • Property mode set to 100644
File size: 8.0 KB
RevLine 
[d3ff1fb]1/*
2 *
[ee6e802]3 * Copyright (c) 2007-2016 The University of Waikato, Hamilton, New Zealand.
[d3ff1fb]4 * All rights reserved.
5 *
[ee6e802]6 * This file is part of libtrace.
7 *
8 * This code has been developed by the University of Waikato WAND
[d3ff1fb]9 * research group. For further information please see http://www.wand.net.nz/
10 *
11 * libtrace is free software; you can redistribute it and/or modify
[ee6e802]12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
[d3ff1fb]14 * (at your option) any later version.
15 *
16 * libtrace is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
[ee6e802]19 * GNU Lesser General Public License for more details.
[d3ff1fb]20 *
[ee6e802]21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
[d3ff1fb]23 *
24 *
25 */
26
[ee6e802]27
[a472b50]28/* This program takes a series of traces and bpf filters and outputs how many
29 * bytes/packets
30 */
[d3ff1fb]31
32#include <stdio.h>
33#include <stdlib.h>
34#include <assert.h>
35#include <string.h>
36#include <sys/time.h>
37#include <sys/types.h>
[f9b6f64]38
[d3ff1fb]39#include <getopt.h>
40#include <inttypes.h>
[2cf30f6]41#include <signal.h>
[d3ff1fb]42
43#include "libtrace.h"
44#include "tracereport.h"
45#include "report.h"
46
47struct libtrace_t *trace;
[f9b6f64]48uint32_t reports_required = 0;
[904c639]49int packets_read = 0;
[d3ff1fb]50
[2cf30f6]51static volatile int done=0;
52
[a8f2692]53static void cleanup_signal(int sig UNUSED)
[2cf30f6]54{
55        done=1;
[c0ccccd]56        trace_interrupt();
[2cf30f6]57}
58
[d3ff1fb]59/* Process a trace, counting packets that match filter(s) */
[466aed6]60static void run_trace(char *uri, libtrace_filter_t *filter, int count) 
[d3ff1fb]61{
[d56089a]62        struct libtrace_packet_t *packet = trace_create_packet();
[d3ff1fb]63
[904c639]64        /* Already read the maximum number of packets - don't need to read
65         * anything from this trace */
66        if ((count >= 0 && packets_read >= count) || done)
67                return;
68
[d4336d5]69        trace = trace_create(uri);
70       
[c3e6e47]71        if (trace_is_err(trace)) {
72                trace_perror(trace,"trace_create");
[a472b50]73                return;
74        }
75
76        if (filter) {
77                trace_config(trace,TRACE_OPTION_FILTER,filter);
[c3e6e47]78        }
79
80        if (trace_start(trace)==-1) {
81                trace_perror(trace,"trace_start");
[a472b50]82                return;
[c3e6e47]83        }
[d3ff1fb]84
[904c639]85        while (1) {
[d3ff1fb]86                int psize;
[f9b6f64]87               
[904c639]88                if (count >= 0 && packets_read >= count)
[a472b50]89                        break;
[2cf30f6]90                if (done)
91                        break;
[d4336d5]92                if ((psize = trace_read_packet(trace, packet)) <1) {
93                        break;
94                }
[8e11beb]95                if (IS_LIBTRACE_META_PACKET(packet))
96                        continue;
97
[7be3cc4]98                if (reports_required & REPORT_TYPE_MISC)
99                        misc_per_packet(packet);
[f9b6f64]100                if (reports_required & REPORT_TYPE_ERROR)
101                        error_per_packet(packet);
102                if (reports_required & REPORT_TYPE_PORT)
103                        port_per_packet(packet);
104                if (reports_required & REPORT_TYPE_PROTO)
105                        protocol_per_packet(packet);
106                if (reports_required & REPORT_TYPE_TOS)
107                        tos_per_packet(packet);
108                if (reports_required & REPORT_TYPE_TTL)
109                        ttl_per_packet(packet);
110                if (reports_required & REPORT_TYPE_FLOW)
111                        flow_per_packet(packet);
112                if (reports_required & REPORT_TYPE_TCPOPT)
113                        tcpopt_per_packet(packet);
[051618c]114                if (reports_required & REPORT_TYPE_SYNOPT)
115                        synopt_per_packet(packet);
[f9b6f64]116                if (reports_required & REPORT_TYPE_NLP)
117                        nlp_per_packet(packet);
118                if (reports_required & REPORT_TYPE_DIR)
119                        dir_per_packet(packet);
120                if (reports_required & REPORT_TYPE_ECN)
121                        ecn_per_packet(packet);
[b5dc60d]122                if (reports_required & REPORT_TYPE_TCPSEG)
[f9b6f64]123                        tcpseg_per_packet(packet);
[904c639]124
125                packets_read ++;
[d4336d5]126        }
[4423dc7]127        if (reports_required & REPORT_TYPE_DROPS)
128                drops_per_trace(trace);
[bf986a1]129        trace_destroy_packet(packet);
[d4336d5]130        trace_destroy(trace);
[d3ff1fb]131}
132
[466aed6]133static void usage(char *argv0)
[d3ff1fb]134{
[66caf4b]135        fprintf(stderr,"Usage:\n"
136        "%s flags traceuri [traceuri...]\n"
[f9b6f64]137        "-f --filter=bpf        \tApply BPF filter. Can be specified multiple times\n"
[904c639]138        "-c --count=N           Stop after reading N packets\n"
[f9b6f64]139        "-e --error             Report packet errors (e.g. checksum failures, rxerrors)\n"
140        "-F --flow              Report flows\n"
[7be3cc4]141        "-m --misc              Report misc information (start/end times, duration, pps)\n"
[f9b6f64]142        "-P --protocol          Report transport protocols\n"
143        "-p --port              Report port numbers\n"
144        "-T --tos               Report IP TOS\n"
[4eec8dc]145        "-t --ttl               Report IP TTL\n"
[f9b6f64]146        "-O --tcpoptions        \tReport TCP Options\n"
[051618c]147        "-o --synoptions        \tReport TCP Options seen on SYNs\n"
[f9b6f64]148        "-n --nlp               Report network layer protocols\n"
149        "-d --direction         Report direction\n"
150        "-C --ecn               Report TCP ECN information\n"
151        "-s --tcpsegment        \tReport TCP segment size\n"
152        "-H --help              Print libtrace runtime documentation\n"
[66caf4b]153        ,argv0);
154        exit(1);
[d3ff1fb]155}
156
157int main(int argc, char *argv[]) {
158
[d4336d5]159        int i;
[f9b6f64]160        int opt;
161        char *filterstring=NULL;
[2cf30f6]162        struct sigaction sigact;
[904c639]163        int count = -1;
[d4336d5]164
165        libtrace_filter_t *filter = NULL;/*trace_bpf_setfilter(filterstring); */
166
[f9b6f64]167        while (1) {
168                int option_index;
169                struct option long_options[] = {
[904c639]170                        { "count",              1, 0, 'c' },
[4423dc7]171                        { "ecn",                0, 0, 'C' },
172                        { "direction",          0, 0, 'd' },
173                        { "drops",              0, 0, 'D' },
[f9b6f64]174                        { "error",              0, 0, 'e' },
175                        { "flow",               0, 0, 'F' },
[4423dc7]176                        { "filter",             1, 0, 'f' },
177                        { "help",               0, 0, 'H' },
[7be3cc4]178                        { "misc",               0, 0, 'm' },
[4423dc7]179                        { "nlp",                0, 0, 'n' },
[f9b6f64]180                        { "tcpoptions",         0, 0, 'O' },
[051618c]181                        { "synoptions",         0, 0, 'o' },
[4423dc7]182                        { "protocol",           0, 0, 'P' },
183                        { "port",               0, 0, 'p' },
[f9b6f64]184                        { "tcpsegment",         0, 0, 's' },
[4423dc7]185                        { "tos",                0, 0, 'T' },
186                        { "ttl",                0, 0, 't' },
[f9b6f64]187                        { NULL,                 0, 0, 0 }
188                };
[904c639]189                opt = getopt_long(argc, argv, "Df:HemFPpTtOondCsc:", 
[b25f4b0]190                                long_options, &option_index);
[f9b6f64]191                if (opt == -1)
192                        break;
193               
194                switch (opt) {
[904c639]195                        case 'c':
196                                count = atoi(optarg);
197                                break;
[f9b6f64]198                        case 'C':
199                                reports_required |= REPORT_TYPE_ECN;
200                                break;
201                        case 'd':
202                                reports_required |= REPORT_TYPE_DIR;
203                                break;
[4423dc7]204                        case 'D':
205                                reports_required |= REPORT_TYPE_DROPS;
206                                break;
[f9b6f64]207                        case 'e':
208                                reports_required |= REPORT_TYPE_ERROR;
209                                break;
210                        case 'F':
211                                reports_required |= REPORT_TYPE_FLOW;
212                                break;
213                        case 'f':
214                                filterstring = optarg;
215                                break;
216                        case 'H':
217                                usage(argv[0]);
218                                break;
[b25f4b0]219                        case 'm':
220                                reports_required |= REPORT_TYPE_MISC;
221                                break;
[f9b6f64]222                        case 'n':
223                                reports_required |= REPORT_TYPE_NLP;
224                                break;
225                        case 'O':
226                                reports_required |= REPORT_TYPE_TCPOPT;
227                                break;
[051618c]228                        case 'o':
229                                reports_required |= REPORT_TYPE_SYNOPT;
230                                break;
[f9b6f64]231                        case 'P':
232                                reports_required |= REPORT_TYPE_PROTO;
233                                break;
234                        case 'p':
235                                reports_required |= REPORT_TYPE_PORT;
236                                break;
237                        case 's':
238                                reports_required |= REPORT_TYPE_TCPSEG;
239                                break;
240                        case 'T':
241                                reports_required |= REPORT_TYPE_TOS;
242                                break;
243                        case 't':
244                                reports_required |= REPORT_TYPE_TTL;
245                                break;
246                        default:
247                                usage(argv[0]);
248                }
249        }
250
[7be3cc4]251        /* Default to all reports, instead of no reports at all.  It's annoying
252         * waiting for 10 minutes for a trace to process then discover you
253         * forgot to ask for any reports!
254         */
[212f9da2]255        if (reports_required == 0) {
[7be3cc4]256                reports_required = ~0;
257
[212f9da2]258                /* Except we might want to not do the flow report, because
259                 * that can be rather resource-intensive */
260                reports_required &= ~REPORT_TYPE_FLOW;
261        }
262
263
[f9b6f64]264        if (filterstring) {
265                filter = trace_create_filter(filterstring);
266        }
[2cf30f6]267
268        sigact.sa_handler = cleanup_signal;
269        sigemptyset(&sigact.sa_mask);
270        sigact.sa_flags = SA_RESTART;
271
272        sigaction(SIGINT, &sigact, NULL);
273        sigaction(SIGTERM, &sigact, NULL);
[f9b6f64]274               
275       
276        for(i=optind;i<argc;++i) {
277                /* This is handy for knowing how far through the traceset
278                 * we are - printing to stderr because we use stdout for
279                 * genuine output at the moment */
280                fprintf(stderr, "Reading from trace: %s\n", argv[i]);
[904c639]281                run_trace(argv[i],filter, count);
[d3ff1fb]282        }
283
[7be3cc4]284        if (reports_required & REPORT_TYPE_MISC)
285                misc_report();
[f9b6f64]286        if (reports_required & REPORT_TYPE_ERROR)
287                error_report();
288        if (reports_required & REPORT_TYPE_FLOW)
289                flow_report();
290        if (reports_required & REPORT_TYPE_TOS)
291                tos_report();
292        if (reports_required & REPORT_TYPE_PROTO)
293                protocol_report();
294        if (reports_required & REPORT_TYPE_PORT)
295                port_report();
296        if (reports_required & REPORT_TYPE_TTL)
297                ttl_report();   
298        if (reports_required & REPORT_TYPE_TCPOPT)
299                tcpopt_report();
[051618c]300        if (reports_required & REPORT_TYPE_SYNOPT)
301                synopt_report();
[f9b6f64]302        if (reports_required & REPORT_TYPE_NLP)
303                nlp_report();
304        if (reports_required & REPORT_TYPE_DIR)
305                dir_report();
306        if (reports_required & REPORT_TYPE_ECN)
307                ecn_report();
308        if (reports_required & REPORT_TYPE_TCPSEG)
309                tcpseg_report();
[4423dc7]310        if (reports_required & REPORT_TYPE_DROPS)
311                drops_report();
[09be643]312        return 0;
[d3ff1fb]313}
Note: See TracBrowser for help on using the repository browser.