source: examples/tutorial/gettransportdemo.c @ c909fad

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since c909fad was af27241, checked in by Shane Alcock <salcock@…>, 8 years ago
  • Added a couple of new examples that show off trace_get_transport (as an example of a layer access function) and trace_get_payload_from_ip (as an example of a get payload from X function)
  • Property mode set to 100644
File size: 3.7 KB
Line 
1/* Trivial libtrace program that prints the fields in the header for all
2 * UDP packets in a trace.
3 *
4 * Designed to demonstrate the use of trace_get_transport()
5 */
6#include "libtrace.h"
7#include <stdio.h>
8#include <inttypes.h>
9#include <assert.h>
10#include <getopt.h>
11#include <arpa/inet.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        uint8_t proto;
21        uint32_t rem;
22        void *transport = NULL;
23        libtrace_udp_t *udp = NULL;
24
25        /* OK, this is slightly tricky so pay attention.
26         *
27         * proto and rem are used as 'output' parameters here. What this
28         * means is that their current values are ignored by the function
29         * but they are updated to contain the protocol and amount of
30         * payload remaining for the header that is being returned.
31         *
32         * We need to pass in the address of both these parameters, so
33         * that they can be modified by the function. This is why there
34         * is an '&' before both parameters.
35         */
36        transport = trace_get_transport(packet, &proto, &rem);
37
38        /* If there was no transport header, it can't be a UDP packet */
39        if (transport == NULL)
40                return;
41
42        /* Check if the protocol is UDP, using the defined value for UDP
43         * that is defined in libtrace.h (search for libtrace_ipproto_t for
44         * a full list) */
45        if (proto != TRACE_IPPROTO_UDP)
46                return;
47
48        /* One last check - make sure we have a full UDP header before
49         * trying to grab fields out of it */
50        if (rem < sizeof(libtrace_udp_t))
51                return;
52
53        /* Now, cast the returned header to the appropriate header type */
54        udp = (libtrace_udp_t *)transport;
55
56        /* Dump each field to standard output. Be careful to byteswap any
57         * fields that are larger than one byte, as these will be in network
58         * byte order */
59        printf("UDP: source=%u dest=%u len=%u checksum=%u\n",
60                        ntohs(udp->source), ntohs(udp->dest),
61                        ntohs(udp->len), ntohs(udp->check));
62}
63
64
65/* Due to the amount of error checking required in our main function, it
66 * is a lot simpler and tidier to place all the calls to various libtrace
67 * destroy functions into a separate function.
68 */
69static void libtrace_cleanup(libtrace_t *trace, libtrace_packet_t *packet) {
70       
71        /* It's very important to ensure that we aren't trying to destroy
72         * a NULL structure, so each of the destroy calls will only occur
73         * if the structure exists */
74        if (trace)
75                trace_destroy(trace);
76
77        if (packet)
78                trace_destroy_packet(packet);
79
80}
81
82int main(int argc, char *argv[])
83{
84        /* This is essentially the same main function from readdemo.c */
85       
86        libtrace_t *trace = NULL;
87        libtrace_packet_t *packet = NULL;
88
89        /* Ensure we have at least one argument after the program name */
90        if (argc < 2) {
91                fprintf(stderr, "Usage: %s inputURI\n", argv[0]);
92                return 1;
93        }       
94       
95        packet = trace_create_packet();
96
97        if (packet == NULL) {
98                perror("Creating libtrace packet");
99                libtrace_cleanup(trace, packet);
100                return 1;
101        }
102
103        trace = trace_create(argv[1]);
104
105        if (trace_is_err(trace)) {
106                trace_perror(trace,"Opening trace file");
107                libtrace_cleanup(trace, packet);
108                return 1;
109        }
110
111        if (trace_start(trace) == -1) {
112                trace_perror(trace,"Starting trace");
113                libtrace_cleanup(trace, packet);
114                return 1;
115        }
116
117
118        while (trace_read_packet(trace,packet)>0) {
119                per_packet(packet);
120        }
121
122
123        if (trace_is_err(trace)) {
124                trace_perror(trace,"Reading packets");
125                libtrace_cleanup(trace, packet);
126                return 1;
127        }
128
129        /* Print the stats for the final reporting period that was probably
130         * not complete when the trace finished */
131        printf("%u\t", next_report);
132        printf("%.2f\t\t", ((double)wire_count) / packet_count);
133        printf("%.2f\n", ((double)capture_count) / packet_count);
134
135        libtrace_cleanup(trace, packet);
136        return 0;
137}
Note: See TracBrowser for help on using the repository browser.