source: examples/tutorial/lengthdemo.c @ d025ff7

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since d025ff7 was d025ff7, checked in by Shane Alcock <salcock@…>, 11 years ago
  • Fix warnings in tutorial code
  • Property mode set to 100644
File size: 3.9 KB
Line 
1/* Trivial libtrace program that periodically prints out the average capture
2 * and wire length  for packets within a trace.
3 *
4 * Designed to demonstrate the use of trace_get_capture_length() and
5 * trace_get_wire_length()
6 */
7#include "libtrace.h"
8#include <stdio.h>
9#include <inttypes.h>
10#include <assert.h>
11#include <getopt.h>
12
13uint64_t packet_count = 0;
14uint64_t capture_count = 0;
15uint64_t wire_count = 0;
16uint32_t next_report = 0;
17
18static void per_packet(libtrace_packet_t *packet)
19{
20        struct timeval ts;
21
22        /* Get the timestamp for the current packet */
23        ts = trace_get_timeval(packet);
24
25        /* If next_report is zero, then this is the first packet from the
26         * trace so we need to determine the time at which the first report
27         * must occur, i.e. 10 seconds from now. */
28        if (next_report == 0) {
29                next_report = ts.tv_sec + 10;
30
31                /* This is also a good opportunity to print column headings */
32                printf("Time\t\tWire Length\tCapture Length\n");
33        }
34
35        /* Check whether we need to report average packet sizes or not.
36         *
37         * If the timestamp for the current packet is beyond the time when the
38         * next report was due then we have to output our current stats and
39         * reset it to zero.
40         *
41         * Note that I use a while loop here to ensure that we correctly deal
42         * with periods in which no packets are observed.
43         */
44        while ((uint32_t)ts.tv_sec > next_report) {
45
46                /* Print the timestamp for the report */
47                printf("%u\t", next_report);
48
49                /* Calculate and print the average wire length */
50                printf("%.2f\t\t", ((double)wire_count) / packet_count);
51
52                /* Calculate and print the average capture length */
53                printf("%.2f\n", ((double)capture_count) / packet_count);
54
55                /* Reset the counters */
56                packet_count = 0;
57                wire_count = 0;
58                capture_count = 0;
59
60                /* Determine when the next report is due */
61                next_report += 10;
62        }
63
64        /* Increment our counters */
65
66        /* Packet count is easy to keep track of */
67        packet_count += 1;
68
69        /* Use trace_get_wire_length() to increment our wire length counter */
70        wire_count += trace_get_wire_length(packet);
71
72        /* trace_get_capture_length() will tell us the capture length of the
73         * packet */
74        capture_count += trace_get_capture_length(packet);
75
76}
77
78
79/* Due to the amount of error checking required in our main function, it
80 * is a lot simpler and tidier to place all the calls to various libtrace
81 * destroy functions into a separate function.
82 */
83static void libtrace_cleanup(libtrace_t *trace, libtrace_packet_t *packet) {
84       
85        /* It's very important to ensure that we aren't trying to destroy
86         * a NULL structure, so each of the destroy calls will only occur
87         * if the structure exists */
88        if (trace)
89                trace_destroy(trace);
90
91        if (packet)
92                trace_destroy_packet(packet);
93
94}
95
96int main(int argc, char *argv[])
97{
98        /* This is essentially the same main function from readdemo.c */
99       
100        libtrace_t *trace = NULL;
101        libtrace_packet_t *packet = NULL;
102
103        /* Ensure we have at least one argument after the program name */
104        if (argc < 2) {
105                fprintf(stderr, "Usage: %s inputURI\n", argv[0]);
106                return 1;
107        }       
108       
109        packet = trace_create_packet();
110
111        if (packet == NULL) {
112                perror("Creating libtrace packet");
113                libtrace_cleanup(trace, packet);
114                return 1;
115        }
116
117        trace = trace_create(argv[1]);
118
119        if (trace_is_err(trace)) {
120                trace_perror(trace,"Opening trace file");
121                libtrace_cleanup(trace, packet);
122                return 1;
123        }
124
125        if (trace_start(trace) == -1) {
126                trace_perror(trace,"Starting trace");
127                libtrace_cleanup(trace, packet);
128                return 1;
129        }
130
131
132        while (trace_read_packet(trace,packet)>0) {
133                per_packet(packet);
134        }
135
136
137        if (trace_is_err(trace)) {
138                trace_perror(trace,"Reading packets");
139                libtrace_cleanup(trace, packet);
140                return 1;
141        }
142
143        /* Print the stats for the final reporting period that was probably
144         * not complete when the trace finished */
145        printf("%u\t", next_report);
146        printf("%.2f\t\t", ((double)wire_count) / packet_count);
147        printf("%.2f\n", ((double)capture_count) / packet_count);
148
149        libtrace_cleanup(trace, packet);
150        return 0;
151}
Note: See TracBrowser for help on using the repository browser.