198524Sfenner/* 298524Sfenner * Copyright (C) 2001 WIDE Project. All rights reserved. 398524Sfenner * 498524Sfenner * Redistribution and use in source and binary forms, with or without 598524Sfenner * modification, are permitted provided that the following conditions 698524Sfenner * are met: 798524Sfenner * 1. Redistributions of source code must retain the above copyright 898524Sfenner * notice, this list of conditions and the following disclaimer. 998524Sfenner * 2. Redistributions in binary form must reproduce the above copyright 1098524Sfenner * notice, this list of conditions and the following disclaimer in the 1198524Sfenner * documentation and/or other materials provided with the distribution. 1298524Sfenner * 3. Neither the name of the project nor the names of its contributors 1398524Sfenner * may be used to endorse or promote products derived from this software 1498524Sfenner * without specific prior written permission. 1598524Sfenner * 1698524Sfenner * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 1798524Sfenner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1898524Sfenner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1998524Sfenner * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2098524Sfenner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2198524Sfenner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2298524Sfenner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2398524Sfenner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2498524Sfenner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2598524Sfenner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2698524Sfenner * SUCH DAMAGE. 2798524Sfenner */ 2898524Sfenner 29276788Sdelphij#define NETDISSECT_REWORKED 3098524Sfenner#ifdef HAVE_CONFIG_H 3198524Sfenner#include "config.h" 3298524Sfenner#endif 3398524Sfenner 34127668Sbms#include <tcpdump-stdinc.h> 3598524Sfenner 3698524Sfenner#include "interface.h" 3798524Sfenner#include "extract.h" /* must come after interface.h */ 38146773Ssam#include "mpls.h" 3998524Sfenner 4098524Sfennerstatic const char *mpls_labelname[] = { 4198524Sfenner/*0*/ "IPv4 explicit NULL", "router alert", "IPv6 explicit NULL", 4298524Sfenner "implicit NULL", "rsvd", 4398524Sfenner/*5*/ "rsvd", "rsvd", "rsvd", "rsvd", "rsvd", 4498524Sfenner/*10*/ "rsvd", "rsvd", "rsvd", "rsvd", "rsvd", 4598524Sfenner/*15*/ "rsvd", 4698524Sfenner}; 4798524Sfenner 48235530Sdelphijenum mpls_packet_type { 49235530Sdelphij PT_UNKNOWN, 50235530Sdelphij PT_IPV4, 51235530Sdelphij PT_IPV6, 52235530Sdelphij PT_OSI 53235530Sdelphij}; 54235530Sdelphij 5598524Sfenner/* 5698524Sfenner * RFC3032: MPLS label stack encoding 5798524Sfenner */ 5898524Sfennervoid 59276788Sdelphijmpls_print(netdissect_options *ndo, const u_char *bp, u_int length) 6098524Sfenner{ 6198524Sfenner const u_char *p; 62276788Sdelphij uint32_t label_entry; 63276788Sdelphij uint16_t label_stack_depth = 0; 64235530Sdelphij enum mpls_packet_type pt = PT_UNKNOWN; 6598524Sfenner 6698524Sfenner p = bp; 67276788Sdelphij ND_PRINT((ndo, "MPLS")); 68111726Sfenner do { 69276788Sdelphij ND_TCHECK2(*p, sizeof(label_entry)); 70147899Ssam label_entry = EXTRACT_32BITS(p); 71276788Sdelphij ND_PRINT((ndo, "%s(label %u", 72276788Sdelphij (label_stack_depth && ndo->ndo_vflag) ? "\n\t" : " ", 73276788Sdelphij MPLS_LABEL(label_entry))); 74235530Sdelphij label_stack_depth++; 75276788Sdelphij if (ndo->ndo_vflag && 76147899Ssam MPLS_LABEL(label_entry) < sizeof(mpls_labelname) / sizeof(mpls_labelname[0])) 77276788Sdelphij ND_PRINT((ndo, " (%s)", mpls_labelname[MPLS_LABEL(label_entry)])); 78276788Sdelphij ND_PRINT((ndo, ", exp %u", MPLS_EXP(label_entry))); 79147899Ssam if (MPLS_STACK(label_entry)) 80276788Sdelphij ND_PRINT((ndo, ", [S]")); 81276788Sdelphij ND_PRINT((ndo, ", ttl %u)", MPLS_TTL(label_entry))); 8298524Sfenner 83147899Ssam p += sizeof(label_entry); 84147899Ssam } while (!MPLS_STACK(label_entry)); 8598524Sfenner 86235530Sdelphij /* 87235530Sdelphij * Try to figure out the packet type. 88235530Sdelphij */ 89147899Ssam switch (MPLS_LABEL(label_entry)) { 90235530Sdelphij 9198524Sfenner case 0: /* IPv4 explicit NULL label */ 92235530Sdelphij case 3: /* IPv4 implicit NULL label */ 93235530Sdelphij pt = PT_IPV4; 9498524Sfenner break; 95235530Sdelphij 9698524Sfenner case 2: /* IPv6 explicit NULL label */ 97235530Sdelphij pt = PT_IPV6; 9898524Sfenner break; 99235530Sdelphij 10098524Sfenner default: 10198524Sfenner /* 102127668Sbms * Generally there's no indication of protocol in MPLS label 103235530Sdelphij * encoding. 104235530Sdelphij * 105235530Sdelphij * However, draft-hsmit-isis-aal5mux-00.txt describes a 106235530Sdelphij * technique for encapsulating IS-IS and IP traffic on the 107235530Sdelphij * same ATM virtual circuit; you look at the first payload 108235530Sdelphij * byte to determine the network layer protocol, based on 109235530Sdelphij * the fact that 110235530Sdelphij * 111235530Sdelphij * 1) the first byte of an IP header is 0x45-0x4f 112235530Sdelphij * for IPv4 and 0x60-0x6f for IPv6; 113235530Sdelphij * 114235530Sdelphij * 2) the first byte of an OSI CLNP packet is 0x81, 115235530Sdelphij * the first byte of an OSI ES-IS packet is 0x82, 116235530Sdelphij * and the first byte of an OSI IS-IS packet is 117235530Sdelphij * 0x83; 118235530Sdelphij * 119235530Sdelphij * so the network layer protocol can be inferred from the 120235530Sdelphij * first byte of the packet, if the protocol is one of the 121235530Sdelphij * ones listed above. 122235530Sdelphij * 123235530Sdelphij * Cisco sends control-plane traffic MPLS-encapsulated in 124235530Sdelphij * this fashion. 12598524Sfenner */ 126235530Sdelphij switch(*p) { 127127668Sbms 128235530Sdelphij case 0x45: 129235530Sdelphij case 0x46: 130235530Sdelphij case 0x47: 131235530Sdelphij case 0x48: 132235530Sdelphij case 0x49: 133235530Sdelphij case 0x4a: 134235530Sdelphij case 0x4b: 135235530Sdelphij case 0x4c: 136235530Sdelphij case 0x4d: 137235530Sdelphij case 0x4e: 138235530Sdelphij case 0x4f: 139235530Sdelphij pt = PT_IPV4; 140235530Sdelphij break; 141276788Sdelphij 142235530Sdelphij case 0x60: 143235530Sdelphij case 0x61: 144235530Sdelphij case 0x62: 145235530Sdelphij case 0x63: 146235530Sdelphij case 0x64: 147235530Sdelphij case 0x65: 148235530Sdelphij case 0x66: 149235530Sdelphij case 0x67: 150235530Sdelphij case 0x68: 151235530Sdelphij case 0x69: 152235530Sdelphij case 0x6a: 153235530Sdelphij case 0x6b: 154235530Sdelphij case 0x6c: 155235530Sdelphij case 0x6d: 156235530Sdelphij case 0x6e: 157235530Sdelphij case 0x6f: 158235530Sdelphij pt = PT_IPV6; 159235530Sdelphij break; 160235530Sdelphij 161235530Sdelphij case 0x81: 162235530Sdelphij case 0x82: 163235530Sdelphij case 0x83: 164235530Sdelphij pt = PT_OSI; 165235530Sdelphij break; 166235530Sdelphij 167235530Sdelphij default: 168235530Sdelphij /* ok bail out - we did not figure out what it is*/ 169235530Sdelphij break; 170235530Sdelphij } 171235530Sdelphij } 172235530Sdelphij 173235530Sdelphij /* 174235530Sdelphij * Print the payload. 175235530Sdelphij */ 176235530Sdelphij if (pt == PT_UNKNOWN) { 177276788Sdelphij if (!ndo->ndo_suppress_default_print) 178276788Sdelphij ND_DEFAULTPRINT(p, length - (p - bp)); 179235530Sdelphij return; 180235530Sdelphij } 181276788Sdelphij ND_PRINT((ndo, ndo->ndo_vflag ? "\n\t" : " ")); 182235530Sdelphij switch (pt) { 183235530Sdelphij 184235530Sdelphij case PT_IPV4: 185276788Sdelphij ip_print(ndo, p, length - (p - bp)); 186235530Sdelphij break; 187235530Sdelphij 188235530Sdelphij case PT_IPV6: 189276788Sdelphij ip6_print(ndo, p, length - (p - bp)); 190235530Sdelphij break; 191235530Sdelphij 192235530Sdelphij case PT_OSI: 193276788Sdelphij isoclns_print(ndo, p, length - (p - bp), length - (p - bp)); 194235530Sdelphij break; 195235530Sdelphij 196235530Sdelphij default: 197235530Sdelphij break; 19898524Sfenner } 199235530Sdelphij return; 20098524Sfenner 20198524Sfennertrunc: 202276788Sdelphij ND_PRINT((ndo, "[|MPLS]")); 20398524Sfenner} 204127668Sbms 205146773Ssam 206127668Sbms/* 207146773Ssam * Local Variables: 208146773Ssam * c-style: whitesmith 209146773Ssam * c-basic-offset: 8 210146773Ssam * End: 211127668Sbms */ 212