xref: /openbsd/usr.sbin/tcpdump/print-mpls.c (revision 17df1aa7)
1 /*	$OpenBSD: print-mpls.c,v 1.1 2005/10/08 19:45:15 canacar 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 <stdio.h>
30 
31 #include "interface.h"
32 #include "extract.h"		    /* must come after interface.h */
33 
34 void
35 mpls_print(const u_char *bp, u_int len)
36 {
37 	u_int32_t tag, label, exp, bottom, ttl;
38 
39  again:
40 	if (bp + sizeof(tag) > snapend)
41 		goto trunc;
42 
43 	tag = EXTRACT_32BITS(bp);
44 	bp += sizeof(tag);
45 	len -= sizeof(tag);
46 
47 	label = (tag >> 12) & 0xfffff;
48 	exp = (tag >> 9) & 0x7;
49 	bottom = (tag >> 8) & 0x1;
50 	ttl = (tag >> 0) & 0xff;
51 
52 	printf("MPLS(label 0x%x, exp %u, ttl %u) ", label, exp, ttl);
53 
54 	/* XXX decode "Router Alert Label" */
55 
56 	if (!bottom)
57 		goto again;
58 
59 	/*
60 	 * guessing the underlying protocol is about all we can do if
61 	 * it's not explicitly defined.
62 	 */
63 
64 	switch (label) {
65 	case 0x00000:			/* IPv4 Explicit NULL */
66 		ip_print(bp, len);
67 		break;
68 	case 0x00001:			/* Router Alert */
69 		/* shouldn't happen at stack bottom */
70 		printf("Route-Alert");
71 		break;
72 	case 0x00002:			/* IPv6 Explicit NULL */
73 		ip6_print(bp, len);
74 		break;
75 	case 0x00003:			/* Implicit NULL */
76 		/* shouldn't happen in the tag stack */
77 		printf("Implicit-NULL");
78 		break;
79 
80 	case 0x00004:			/* reserved labels */
81 	case 0x00005:
82 	case 0x00006:
83 	case 0x00007:
84 	case 0x00008:
85 	case 0x00009:
86 	case 0x0000a:
87 	case 0x0000b:
88 	case 0x0000c:
89 	case 0x0000d:
90 	case 0x0000e:
91 	case 0x0000f:
92 		break;
93 
94 	default:			/* dunno, guess? */
95 		if (len == 0)
96 			break;
97 		if (bp >= snapend)
98 			goto trunc;
99 
100 		switch (bp[0] & 0xf0) {
101 		case 0x40:
102 			ip_print(bp, len);
103 			break;
104 		case 0x60:
105 			ip6_print(bp, len);
106 			break;
107 		}
108 	}
109 
110 	return;
111 trunc:
112 	printf("[|mpls]");
113 }
114