1/* $OpenBSD: print-mpls.c,v 1.4 2018/07/06 07:00:49 dlg 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 40int controlword_tryprint(const u_char **, u_int *); 41 42void 43mpls_print(const u_char *bp, u_int len) 44{ 45 u_int32_t tag, label, exp, bottom, ttl; 46 int has_cw; 47 48 do { 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 } while (!bottom); 65 66 /* Handle pseudowire control word. */ 67 has_cw = controlword_tryprint(&bp, &len); 68 69 /* 70 * guessing the underlying protocol is about all we can do if 71 * it's not explicitly defined. 72 */ 73 74 switch (label) { 75 case 0x00000: /* IPv4 Explicit NULL */ 76 ip_print(bp, len); 77 break; 78 case 0x00001: /* Router Alert */ 79 /* shouldn't happen at stack bottom */ 80 printf("Route-Alert"); 81 break; 82 case 0x00002: /* IPv6 Explicit NULL */ 83 ip6_print(bp, len); 84 break; 85 case 0x00003: /* Implicit NULL */ 86 /* shouldn't happen in the tag stack */ 87 printf("Implicit-NULL"); 88 break; 89 90 case 0x00004: /* reserved labels */ 91 case 0x00005: 92 case 0x00006: 93 case 0x00007: 94 case 0x00008: 95 case 0x00009: 96 case 0x0000a: 97 case 0x0000b: 98 case 0x0000c: 99 case 0x0000d: 100 case 0x0000e: 101 case 0x0000f: 102 break; 103 104 default: /* dunno, guess? */ 105 if (len == 0) 106 break; 107 if (bp >= snapend) 108 goto trunc; 109 110 switch (bp[0] & 0xf0) { 111 case 0x40: 112 ip_print(bp, len); 113 break; 114 case 0x60: 115 ip6_print(bp, len); 116 break; 117 } 118 } 119 120 if (has_cw) 121 ether_tryprint(bp, len, 0); 122 123 return; 124trunc: 125 printf("[|mpls]"); 126} 127 128/* Print control word if any and returns 1 on success. */ 129int 130controlword_tryprint(const u_char **bp, u_int *lenp) 131{ 132 uint32_t cw, frag, seq; 133 134 if (*lenp < 4) 135 return (0); 136 137 cw = EXTRACT_32BITS(*bp); 138 if (cw & CW_ZERO_MASK) 139 return (0); 140 141 *bp += sizeof(cw); 142 *lenp += sizeof(cw); 143 144 frag = (cw & CW_FRAG_MASK) >> 16; 145 seq = cw & CW_SEQUENCE_MASK; 146 147 printf("CW(frag %u, sequence %u) ", frag, seq); 148 149 return (1); 150} 151