File: mplstag.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 (136 lines) | stat: -rw-r--r-- 3,469 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
/* Trivial libtrace program that prints all the MPLS tags within a packet.
 * Designed to demonstrate the use of trace_get_payload_from_mpls()
 */
#include "libtrace.h"
#include <stdio.h>
#include <inttypes.h>
#include <assert.h>
#include <getopt.h>

static void print_mpls_label(void *mpls, uint32_t remaining) {
	uint32_t label = 0;
	if (remaining < 4)
		return;

	/* Cast MPLS header into a 32 bit number */
	label = *(uint32_t *)mpls;
	/* Label number is in network byte order */
	label = ntohl(label);
	/* MPLS labels are comprise only 20 of the 32 bits in the header */
	label = (label >> 12) & 0x000fffff;

	printf("%u ", label);
}


static void per_packet(libtrace_packet_t *packet)
{
	void *l2 = NULL;
	void *l2_payload = NULL;
	libtrace_linktype_t link_type;
	uint16_t ethertype;
	uint32_t remaining;

	l2 = trace_get_layer2(packet, &link_type, &remaining);
	
	/* No layer 2 header */
	if (l2 == NULL)
		return;

	
	/* XXX We could check if link_type is ethernet here, but this won't
	 * affect our results in any way */
	l2_payload = trace_get_payload_from_layer2(l2, link_type, &ethertype,
		&remaining);
	
	/* Incomplete layer 2 header */
	if (l2_payload == NULL)
		return;
	
	/* No actual payload after the layer 2 header */
	if (remaining == 0)
		return;

	/* Only look for MPLS labels as long as we have payload available
	 * to look at! */
	while (l2_payload != NULL && remaining > 0) {
		
		/* 0x8847 is the ethertype for MPLS headers */
		if (ethertype == 0x8847) {
			print_mpls_label(l2_payload, remaining);
			/* Move onto the next header */
			l2_payload = trace_get_payload_from_mpls(l2_payload,
					&ethertype, &remaining);
		} else 
			/* Stop as soon as we encounter a non-MPLS header */
			break;
	}
	
	printf("\n");

}
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;
        }


        libtrace_cleanup(trace, packet);
        return 0;
}