source: tools/tracereport/tracereport.c @ ed5b2ce

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivendag_formatrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since ed5b2ce was ee6e802, checked in by Shane Alcock <salcock@…>, 5 years ago

Updated copyright blurb on all source files

In some cases, this meant adding copyright blurbs to files that
had never had them before.

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