source: examples/tutorial/sourcedemo.c @ e26c1fc

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivendag_formatrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since e26c1fc was ee0805a, checked in by Richard Sanger <rsangerarj@…>, 5 years ago

#30 fix missed updating sizes given to inet_ntop

  • Property mode set to 100644
File size: 4.8 KB
Line 
1/* Libtrace program designed to demonstrate the use of the trace_get_source_*
2 * shortcut functions.
3 *
4 * This code also contains examples of sockaddr manipulation.
5 */
6#include "libtrace.h"
7#include <stdio.h>
8#include <inttypes.h>
9#include <assert.h>
10#include <getopt.h>
11#include <sys/socket.h>
12#include <netinet/in.h>
13#include <arpa/inet.h>
14
15/* This is not the nicest way to print a 6 byte MAC address, but it is
16 * effective. Libtrace will have provided us a pointer to the start of the
17 * MAC address within the packet, so we can just use array indices to grab
18 * each byte of the MAC address in turn */
19static inline void print_mac(uint8_t *mac) {
20
21        printf("%02x:%02x:%02x:%02x:%02x:%02x ", mac[0], mac[1], mac[2], mac[3],
22                mac[4], mac[5]);
23
24}
25
26/* Given a sockaddr containing an IP address, prints the IP address to stdout
27 * using the common string representation for that address type */
28static inline void print_ip(struct sockaddr *ip) {
29
30        char str[40];
31       
32        /* Check the sockaddr family so we can cast it to the appropriate
33         * address type, IPv4 or IPv6 */
34        if (ip->sa_family == AF_INET) {
35                /* IPv4 - cast the generic sockaddr to a sockaddr_in */
36                struct sockaddr_in *v4 = (struct sockaddr_in *)ip;
37                /* Use inet_ntop to convert the address into a string using
38                 * dotted decimal notation */
39                printf("%s ", inet_ntop(AF_INET, &(v4->sin_addr), str, sizeof(str)));
40        }
41
42        if (ip->sa_family == AF_INET6) {
43                /* IPv6 - cast the generic sockaddr to a sockaddr_in6 */
44                struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)ip;
45                /* Use inet_ntop to convert the address into a string using
46                 * IPv6 address notation */
47                printf("%s ", inet_ntop(AF_INET6, &(v6->sin6_addr), str, sizeof(str)));
48        }
49
50
51}
52
53static void per_packet(libtrace_packet_t *packet)
54{
55       
56        struct sockaddr_storage addr;
57        struct sockaddr *addr_ptr;
58        uint16_t port;
59        uint8_t *mac;
60
61        /* Get the source mac */
62        mac = trace_get_source_mac(packet);
63       
64        /* If this packet does not contain a MAC address, print "NULL" */
65        if (mac == NULL) 
66                printf("NULL ");
67        else
68                print_mac(mac);
69
70        /* Get the source IP address */
71       
72        /* Note that we pass a casted sockaddr_storage into this function. This
73         * is because we do not know if the IP address we get back will be a
74         * v4 or v6 address. v6 addresses are much larger than v4 addresses and
75         * will not fit within a sockaddr_in structure used for storing IPv4
76         * addresses, leading to memory corruption and segmentation faults.
77         *
78         * The safest way to avoid this problem is to use a sockaddr_storage
79         * which is guaranteed to be large enough to contain any known address
80         * format.
81         */
82        addr_ptr = trace_get_source_address(packet, (struct sockaddr *)&addr);
83
84        /* No IP address? Print "NULL" instead */
85        if (addr_ptr == NULL)
86                printf("NULL ");
87        else
88                print_ip(addr_ptr);
89       
90        /* Get the source port */
91        port = trace_get_source_port(packet);
92
93        /* If the port is zero, libtrace has told us that there is no
94         * legitimate port number present in the packet */
95        if (port == 0)
96                printf("NULL\n");
97        else
98                /* Port numbers are simply 16 bit values so we don't need to
99                 * do anything special to print them. trace_get_source_port()
100                 * even converts it into host byte order for us */
101                printf("%u\n", port);
102
103}
104
105static void libtrace_cleanup(libtrace_t *trace, libtrace_packet_t *packet) {
106
107        /* It's very important to ensure that we aren't trying to destroy
108         * a NULL structure, so each of the destroy calls will only occur
109         * if the structure exists */
110        if (trace)
111                trace_destroy(trace);
112
113        if (packet)
114                trace_destroy_packet(packet);
115
116}
117
118int main(int argc, char *argv[])
119{
120        /* This is essentially the same main function from readdemo.c */
121
122        libtrace_t *trace = NULL;
123        libtrace_packet_t *packet = NULL;
124
125        /* Ensure we have at least one argument after the program name */
126        if (argc < 2) {
127                fprintf(stderr, "Usage: %s inputURI\n", argv[0]);
128                return 1;
129        }
130
131        packet = trace_create_packet();
132
133        if (packet == NULL) {
134                perror("Creating libtrace packet");
135                libtrace_cleanup(trace, packet);
136                return 1;
137        }
138
139        trace = trace_create(argv[1]);
140
141        if (trace_is_err(trace)) {
142                trace_perror(trace,"Opening trace file");
143                libtrace_cleanup(trace, packet);
144                return 1;
145        }
146
147        if (trace_start(trace) == -1) {
148                trace_perror(trace,"Starting trace");
149                libtrace_cleanup(trace, packet);
150                return 1;
151        }
152
153
154        while (trace_read_packet(trace,packet)>0) {
155                per_packet(packet);
156        }
157
158
159        if (trace_is_err(trace)) {
160                trace_perror(trace,"Reading packets");
161                libtrace_cleanup(trace, packet);
162                return 1;
163        }
164
165        libtrace_cleanup(trace, packet);
166        return 0;
167}
168
Note: See TracBrowser for help on using the repository browser.