GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/tcpdump/print-mpls.c Lines: 0 44 0.0 %
Date: 2017-11-13 Branches: 0 34 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: print-mpls.c,v 1.3 2016/07/11 00:27:50 rzalamena Exp $	*/
2
3
/*
4
 * Copyright (c) 2005 Jason L. Wright (jason@thought.net)
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
 * POSSIBILITY OF SUCH DAMAGE.
27
 */
28
29
#include <sys/socket.h>
30
#include <sys/types.h>
31
#include <netmpls/mpls.h>
32
33
#include <stdio.h>
34
35
#include "interface.h"
36
#include "extract.h"		    /* must come after interface.h */
37
38
#define CW_SEQUENCE_MASK       (0x0000ffffU)
39
40
int controlword_tryprint(const u_char **, u_int *);
41
42
void
43
mpls_print(const u_char *bp, u_int len)
44
{
45
	u_int32_t tag, label, exp, bottom, ttl;
46
	int has_cw;
47
48
 again:
49
	if (bp + sizeof(tag) > snapend)
50
		goto trunc;
51
52
	tag = EXTRACT_32BITS(bp);
53
	bp += sizeof(tag);
54
	len -= sizeof(tag);
55
56
	label = (tag >> 12) & 0xfffff;
57
	exp = (tag >> 9) & 0x7;
58
	bottom = (tag >> 8) & 0x1;
59
	ttl = (tag >> 0) & 0xff;
60
61
	printf("MPLS(label %u, exp %u, ttl %u) ", label, exp, ttl);
62
63
	/* XXX decode "Router Alert Label" */
64
65
	if (!bottom)
66
		goto again;
67
68
	/* Handle pseudowire control word. */
69
	has_cw = controlword_tryprint(&bp, &len);
70
71
	/*
72
	 * guessing the underlying protocol is about all we can do if
73
	 * it's not explicitly defined.
74
	 */
75
76
	switch (label) {
77
	case 0x00000:			/* IPv4 Explicit NULL */
78
		ip_print(bp, len);
79
		break;
80
	case 0x00001:			/* Router Alert */
81
		/* shouldn't happen at stack bottom */
82
		printf("Route-Alert");
83
		break;
84
	case 0x00002:			/* IPv6 Explicit NULL */
85
		ip6_print(bp, len);
86
		break;
87
	case 0x00003:			/* Implicit NULL */
88
		/* shouldn't happen in the tag stack */
89
		printf("Implicit-NULL");
90
		break;
91
92
	case 0x00004:			/* reserved labels */
93
	case 0x00005:
94
	case 0x00006:
95
	case 0x00007:
96
	case 0x00008:
97
	case 0x00009:
98
	case 0x0000a:
99
	case 0x0000b:
100
	case 0x0000c:
101
	case 0x0000d:
102
	case 0x0000e:
103
	case 0x0000f:
104
		break;
105
106
	default:			/* dunno, guess? */
107
		if (len == 0)
108
			break;
109
		if (bp >= snapend)
110
			goto trunc;
111
112
		switch (bp[0] & 0xf0) {
113
		case 0x40:
114
			ip_print(bp, len);
115
			break;
116
		case 0x60:
117
			ip6_print(bp, len);
118
			break;
119
		}
120
	}
121
122
	if (has_cw)
123
		ether_tryprint(bp, len, 0);
124
125
	return;
126
trunc:
127
	printf("[|mpls]");
128
}
129
130
/* Print control word if any and returns 1 on success. */
131
int
132
controlword_tryprint(const u_char **bp, u_int *lenp)
133
{
134
	uint32_t cw, frag, seq;
135
136
	if (*lenp < 4)
137
		return (0);
138
139
	cw = EXTRACT_32BITS(*bp);
140
	if (cw & CW_ZERO_MASK)
141
		return (0);
142
143
	*bp += sizeof(cw);
144
	*lenp += sizeof(cw);
145
146
	frag = (cw & CW_FRAG_MASK) >> 16;
147
	seq = cw & CW_SEQUENCE_MASK;
148
149
	printf("CW(frag %u, sequence %u) ", frag, seq);
150
151
	return (1);
152
}