source: tools/tracereport/tracereport.c @ 2cf30f6

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 2cf30f6 was 2cf30f6, checked in by Perry Lorier <perry@…>, 15 years ago

Add signal handling to more programs that could use it.

  • Property mode set to 100644
File size: 7.3 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2007 The University of Waikato, Hamilton, New Zealand.
5 * Authors: Daniel Lawson
6 *          Perry Lorier
7 *          Josef Vodanovich
8 *         
9 * All rights reserved.
10 *
11 * This code has been developed by the University of Waikato WAND
12 * research group. For further information please see http://www.wand.net.nz/
13 *
14 * libtrace is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * libtrace is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with libtrace; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27 *
28 * $Id$
29 *
30 */
31
32/* This program takes a series of traces and bpf filters and outputs how many
33 * bytes/packets
34 */
35
36#include <stdio.h>
37#include <stdlib.h>
38#include <assert.h>
39#include <string.h>
40#include <sys/time.h>
41#include <sys/types.h>
42
43#include <getopt.h>
44#include <inttypes.h>
45#include <signal.h>
46
47#include "libtrace.h"
48#include "tracereport.h"
49#include "report.h"
50
51struct libtrace_t *trace;
52uint32_t reports_required = 0;
53
54static volatile int done=0;
55
56static void cleanup_signal(int sig)
57{
58        done=1;
59}
60
61/* Process a trace, counting packets that match filter(s) */
62static void run_trace(char *uri, libtrace_filter_t *filter, int count) 
63{
64        struct libtrace_packet_t *packet = trace_create_packet();
65
66        trace = trace_create(uri);
67       
68        if (trace_is_err(trace)) {
69                trace_perror(trace,"trace_create");
70                return;
71        }
72
73        if (filter) {
74                trace_config(trace,TRACE_OPTION_FILTER,filter);
75        }
76
77        if (trace_start(trace)==-1) {
78                trace_perror(trace,"trace_start");
79                return;
80        }
81
82        for (;;) {
83                int psize;
84               
85                /* Not convinced we need this count business */
86                /*
87                if (count--<1)
88                        break;
89                */
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        trace_destroy(trace);
123}
124
125static void usage(char *argv0)
126{
127        fprintf(stderr,"Usage:\n"
128        "%s flags traceuri [traceuri...]\n"
129        "-f --filter=bpf        \tApply BPF filter. Can be specified multiple times\n"
130        "-e --error             Report packet errors (e.g. checksum failures, rxerrors)\n"
131        "-F --flow              Report flows\n"
132        "-m --misc              Report misc information (start/end times, duration, pps)\n"
133        "-P --protocol          Report transport protocols\n"
134        "-p --port              Report port numbers\n"
135        "-T --tos               Report IP TOS\n"
136        "-t --ttl               Report IP TTL\n"
137        "-O --tcpoptions        \tReport TCP Options\n"
138        "-o --synoptions        \tReport TCP Options seen on SYNs\n"
139        "-n --nlp               Report network layer protocols\n"
140        "-d --direction         Report direction\n"
141        "-C --ecn               Report TCP ECN information\n"
142        "-s --tcpsegment        \tReport TCP segment size\n"
143        "-H --help              Print libtrace runtime documentation\n"
144        ,argv0);
145        exit(1);
146}
147
148int main(int argc, char *argv[]) {
149
150        int i;
151        int opt;
152        char *filterstring=NULL;
153        struct sigaction sigact;
154
155        libtrace_filter_t *filter = NULL;/*trace_bpf_setfilter(filterstring); */
156
157        while (1) {
158                int option_index;
159                struct option long_options[] = {
160                        { "filter",             1, 0, 'f' },
161                        { "help",               0, 0, 'H' },
162                        { "error",              0, 0, 'e' },
163                        { "flow",               0, 0, 'F' },
164                        { "protocol",           0, 0, 'P' },
165                        { "port",               0, 0, 'p' },
166                        { "misc",               0, 0, 'm' },
167                        { "tos",                0, 0, 'T' },
168                        { "ttl",                0, 0, 't' },
169                        { "tcpoptions",         0, 0, 'O' },
170                        { "synoptions",         0, 0, 'o' },
171                        { "nlp",                0, 0, 'n' },
172                        { "direction",          0, 0, 'd' },
173                        { "ecn",                0, 0, 'C' },
174                        { "tcpsegment",         0, 0, 's' },
175                        { NULL,                 0, 0, 0 }
176                };
177                opt = getopt_long(argc, argv, "f:HemFPpTtOondCsl:", 
178                                long_options, &option_index);
179                if (opt == -1)
180                        break;
181               
182                switch (opt) {
183                        case 'C':
184                                reports_required |= REPORT_TYPE_ECN;
185                                break;
186                        case 'd':
187                                reports_required |= REPORT_TYPE_DIR;
188                                break;
189                        case 'e':
190                                reports_required |= REPORT_TYPE_ERROR;
191                                break;
192                        case 'F':
193                                reports_required |= REPORT_TYPE_FLOW;
194                                break;
195                        case 'f':
196                                filterstring = optarg;
197                                break;
198                        case 'H':
199                                usage(argv[0]);
200                                break;
201                        case 'm':
202                                reports_required |= REPORT_TYPE_MISC;
203                                break;
204                        case 'n':
205                                reports_required |= REPORT_TYPE_NLP;
206                                break;
207                        case 'O':
208                                reports_required |= REPORT_TYPE_TCPOPT;
209                                break;
210                        case 'o':
211                                reports_required |= REPORT_TYPE_SYNOPT;
212                                break;
213                        case 'P':
214                                reports_required |= REPORT_TYPE_PROTO;
215                                break;
216                        case 'p':
217                                reports_required |= REPORT_TYPE_PORT;
218                                break;
219                        case 's':
220                                reports_required |= REPORT_TYPE_TCPSEG;
221                                break;
222                        case 'T':
223                                reports_required |= REPORT_TYPE_TOS;
224                                break;
225                        case 't':
226                                reports_required |= REPORT_TYPE_TTL;
227                                break;
228                        default:
229                                usage(argv[0]);
230                }
231        }
232
233        /* Default to all reports, instead of no reports at all.  It's annoying
234         * waiting for 10 minutes for a trace to process then discover you
235         * forgot to ask for any reports!
236         */
237        if (reports_required == 0)
238                reports_required = ~0;
239
240        if (filterstring) {
241                filter = trace_create_filter(filterstring);
242        }
243
244        sigact.sa_handler = cleanup_signal;
245        sigemptyset(&sigact.sa_mask);
246        sigact.sa_flags = SA_RESTART;
247
248        sigaction(SIGINT, &sigact, NULL);
249        sigaction(SIGTERM, &sigact, NULL);
250               
251       
252        for(i=optind;i<argc;++i) {
253                /* This is handy for knowing how far through the traceset
254                 * we are - printing to stderr because we use stdout for
255                 * genuine output at the moment */
256                fprintf(stderr, "Reading from trace: %s\n", argv[i]);
257                run_trace(argv[i],filter,(1<<30));
258        }
259
260        if (reports_required & REPORT_TYPE_MISC)
261                misc_report();
262        if (reports_required & REPORT_TYPE_ERROR)
263                error_report();
264        if (reports_required & REPORT_TYPE_FLOW)
265                flow_report();
266        if (reports_required & REPORT_TYPE_TOS)
267                tos_report();
268        if (reports_required & REPORT_TYPE_PROTO)
269                protocol_report();
270        if (reports_required & REPORT_TYPE_PORT)
271                port_report();
272        if (reports_required & REPORT_TYPE_TTL)
273                ttl_report();   
274        if (reports_required & REPORT_TYPE_TCPOPT)
275                tcpopt_report();
276        if (reports_required & REPORT_TYPE_SYNOPT)
277                synopt_report();
278        if (reports_required & REPORT_TYPE_NLP)
279                nlp_report();
280        if (reports_required & REPORT_TYPE_DIR)
281                dir_report();
282        if (reports_required & REPORT_TYPE_ECN)
283                ecn_report();
284        if (reports_required & REPORT_TYPE_TCPSEG)
285                tcpseg_report();
286        return 0;
287}
Note: See TracBrowser for help on using the repository browser.