File: lengthdemo.c

package info (click to toggle)
libtrace3 3.0.7-1
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 3,676 kB
  • ctags: 3,140
  • sloc: ansic: 20,551; sh: 10,125; cpp: 1,384; makefile: 415; yacc: 96; lex: 50
file content (151 lines) | stat: -rw-r--r-- 4,011 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* Trivial libtrace program that periodically prints out the average capture
 * and wire length  for packets within a trace.
 *
 * Designed to demonstrate the use of trace_get_capture_length() and
 * trace_get_wire_length()
 */
#include "libtrace.h"
#include <stdio.h>
#include <inttypes.h>
#include <assert.h>
#include <getopt.h>

uint64_t packet_count = 0;
uint64_t capture_count = 0;
uint64_t wire_count = 0;
uint32_t next_report = 0;

static void per_packet(libtrace_packet_t *packet)
{
	struct timeval ts;

	/* Get the timestamp for the current packet */
	ts = trace_get_timeval(packet);

	/* If next_report is zero, then this is the first packet from the
	 * trace so we need to determine the time at which the first report
	 * must occur, i.e. 10 seconds from now. */
	if (next_report == 0) {
		next_report = ts.tv_sec + 10;

		/* This is also a good opportunity to print column headings */
		printf("Time\t\tWire Length\tCapture Length\n");
	}

	/* Check whether we need to report average packet sizes or not.
	 *
	 * If the timestamp for the current packet is beyond the time when the
	 * next report was due then we have to output our current stats and
	 * reset it to zero.
	 *
	 * Note that I use a while loop here to ensure that we correctly deal
	 * with periods in which no packets are observed.
	 */
	while ((uint32_t)ts.tv_sec > next_report) {

		/* Print the timestamp for the report */
		printf("%u\t", next_report);

		/* Calculate and print the average wire length */
		printf("%.2f\t\t", ((double)wire_count) / packet_count);

		/* Calculate and print the average capture length */
		printf("%.2f\n", ((double)capture_count) / packet_count);

		/* Reset the counters */
		packet_count = 0;
		wire_count = 0;
		capture_count = 0;

		/* Determine when the next report is due */
		next_report += 10;
	}

	/* Increment our counters */

	/* Packet count is easy to keep track of */
	packet_count += 1;

	/* Use trace_get_wire_length() to increment our wire length counter */
	wire_count += trace_get_wire_length(packet);

	/* trace_get_capture_length() will tell us the capture length of the
	 * packet */
	capture_count += trace_get_capture_length(packet);

}


/* Due to the amount of error checking required in our main function, it
 * is a lot simpler and tidier to place all the calls to various libtrace
 * destroy functions into a separate function.
 */
static void libtrace_cleanup(libtrace_t *trace, libtrace_packet_t *packet) {
	
	/* It's very important to ensure that we aren't trying to destroy
         * a NULL structure, so each of the destroy calls will only occur
         * if the structure exists */
	if (trace)
		trace_destroy(trace);

	if (packet)
		trace_destroy_packet(packet);

}

int main(int argc, char *argv[])
{
	/* This is essentially the same main function from readdemo.c */
	
	libtrace_t *trace = NULL;
	libtrace_packet_t *packet = NULL;

	/* Ensure we have at least one argument after the program name */
        if (argc < 2) {
                fprintf(stderr, "Usage: %s inputURI\n", argv[0]);
                return 1;
        }	
	
	packet = trace_create_packet();

	if (packet == NULL) {
		perror("Creating libtrace packet");
		libtrace_cleanup(trace, packet);
		return 1;
	}

	trace = trace_create(argv[1]);

	if (trace_is_err(trace)) {
		trace_perror(trace,"Opening trace file");
		libtrace_cleanup(trace, packet);
		return 1;
	}

	if (trace_start(trace) == -1) {
		trace_perror(trace,"Starting trace");
		libtrace_cleanup(trace, packet);
		return 1;
	}


	while (trace_read_packet(trace,packet)>0) {
		per_packet(packet);
	}


	if (trace_is_err(trace)) {
		trace_perror(trace,"Reading packets");
		libtrace_cleanup(trace, packet);
		return 1;
	}

	/* Print the stats for the final reporting period that was probably
	 * not complete when the trace finished */
	printf("%u\t", next_report);
	printf("%.2f\t\t", ((double)wire_count) / packet_count);
	printf("%.2f\n", ((double)capture_count) / packet_count);

	libtrace_cleanup(trace, packet);
	return 0;
}