print-mpls.c revision 146773
1/* 2 * Copyright (C) 2001 WIDE Project. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the project nor the names of its contributors 13 * may be used to endorse or promote products derived from this software 14 * without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#ifndef lint 30static const char rcsid[] _U_ = 31 "@(#) $Header: /tcpdump/master/tcpdump/print-mpls.c,v 1.13 2005/04/06 21:32:41 mcr Exp $ (LBL)"; 32#endif 33 34#ifdef HAVE_CONFIG_H 35#include "config.h" 36#endif 37 38#include <tcpdump-stdinc.h> 39 40#include <stdio.h> 41#include <stdlib.h> 42#include <string.h> 43 44#include "addrtoname.h" 45#include "interface.h" 46#include "extract.h" /* must come after interface.h */ 47#include "mpls.h" 48 49static const char *mpls_labelname[] = { 50/*0*/ "IPv4 explicit NULL", "router alert", "IPv6 explicit NULL", 51 "implicit NULL", "rsvd", 52/*5*/ "rsvd", "rsvd", "rsvd", "rsvd", "rsvd", 53/*10*/ "rsvd", "rsvd", "rsvd", "rsvd", "rsvd", 54/*15*/ "rsvd", 55}; 56 57/* 58 * RFC3032: MPLS label stack encoding 59 */ 60void 61mpls_print(const u_char *bp, u_int length) 62{ 63 const u_char *p; 64 u_int32_t v; 65 66 p = bp; 67 printf("MPLS"); 68 do { 69 TCHECK2(*p, sizeof(v)); 70 v = EXTRACT_32BITS(p); 71 printf(" ("); /*)*/ 72 printf("label %u", MPLS_LABEL(v)); 73 if (vflag && 74 MPLS_LABEL(v) < sizeof(mpls_labelname) / sizeof(mpls_labelname[0])) 75 printf(" (%s)", mpls_labelname[MPLS_LABEL(v)]); 76 printf(", exp %u", MPLS_EXP(v)); 77 if (MPLS_STACK(v)) 78 printf(", [S]"); 79 printf(", ttl %u", MPLS_TTL(v)); 80 /*(*/ 81 printf(")"); 82 83 p += sizeof(v); 84 } while (!MPLS_STACK(v)); 85 86 switch (MPLS_LABEL(v)) { 87 case 0: /* IPv4 explicit NULL label */ 88 case 3: /* IPv4 implicit NULL label */ 89 ip_print(gndo, p, length - (p - bp)); 90 break; 91#ifdef INET6 92 case 2: /* IPv6 explicit NULL label */ 93 ip6_print(p, length - (p - bp)); 94 break; 95#endif 96 default: 97 /* 98 * Generally there's no indication of protocol in MPLS label 99 * encoding, however draft-hsmit-isis-aal5mux-00.txt describes 100 * a technique that looks at the first payload byte if the BOS (bottom of stack) 101 * bit is set and tries to determine the network layer protocol 102 * 0x45-0x4f is IPv4 103 * 0x60-0x6f is IPv6 104 * 0x81-0x83 is OSI (CLNP,ES-IS,IS-IS) 105 * this technique is sometimes known as NULL encapsulation 106 * and decoding is particularly useful for control-plane traffic [BGP] 107 * which cisco by default sends MPLS encapsulated 108 */ 109 110 if (MPLS_STACK(v)) { /* only do this if the stack bit is set */ 111 switch(*p) { 112 case 0x45: 113 case 0x46: 114 case 0x47: 115 case 0x48: 116 case 0x49: 117 case 0x4a: 118 case 0x4b: 119 case 0x4c: 120 case 0x4d: 121 case 0x4e: 122 case 0x4f: 123 if (vflag>0) { 124 printf("\n\t"); 125 ip_print(gndo, p, length - (p - bp)); 126 } 127 else printf(", IP, length: %u",length); 128 break; 129#ifdef INET6 130 case 0x60: 131 case 0x61: 132 case 0x62: 133 case 0x63: 134 case 0x64: 135 case 0x65: 136 case 0x66: 137 case 0x67: 138 case 0x68: 139 case 0x69: 140 case 0x6a: 141 case 0x6b: 142 case 0x6c: 143 case 0x6d: 144 case 0x6e: 145 case 0x6f: 146 if (vflag>0) { 147 printf("\n\t"); 148 ip6_print(p, length - (p - bp)); 149 } 150 else printf(", IPv6, length: %u",length); 151 break; 152#endif 153 case 0x81: 154 case 0x82: 155 case 0x83: 156 if (vflag>0) { 157 printf("\n\t"); 158 isoclns_print(p, length - (p - bp), length - (p - bp)); 159 } 160 else printf(", OSI, length: %u",length); 161 break; 162 default: 163 /* ok bail out - we did not figure out what it is*/ 164 break; 165 } 166 } 167 return; 168 } 169 170trunc: 171 printf("[|MPLS]"); 172} 173 174 175/* 176 * Local Variables: 177 * c-style: whitesmith 178 * c-basic-offset: 8 179 * End: 180 */ 181