From: itojun Date: Thu, 21 Jun 2001 17:56:02 +0000 (+0000) Subject: MPLS label encapsulation decoding, per RFC3032. X-Git-Tag: tcpdump-3.7.1~178 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/544c52e1ef8ee0ba92c7d259c062bbd24a1084eb MPLS label encapsulation decoding, per RFC3032. TODO: multiple labels. other media types. --- diff --git a/Makefile.in b/Makefile.in index af3bcced..524914e5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -17,7 +17,7 @@ # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. # -# @(#) $Header: /tcpdump/master/tcpdump/Makefile.in,v 1.251 2001-06-12 05:17:16 guy Exp $ (LBL) +# @(#) $Header: /tcpdump/master/tcpdump/Makefile.in,v 1.252 2001-06-21 17:56:02 itojun Exp $ (LBL) # # Various configurable paths (remember to edit Makefile.in, not Makefile) @@ -75,7 +75,7 @@ CSRC = addrtoname.c gmt2local.c machdep.c parsenfsfh.c \ print-igrp.c print-ip.c print-ipcomp.c print-ipx.c \ print-isakmp.c print-isoclns.c print-krb.c print-l2tp.c \ print-lane.c print-lcp.c print-llc.c print-lwres.c \ - print-mobile.c print-nfs.c print-ntp.c print-null.c \ + print-mobile.c print-mpls.c print-nfs.c print-ntp.c print-null.c \ print-ospf.c print-pim.c print-ppp.c print-pppoe.c \ print-pptp.c print-radius.c print-raw.c print-rip.c \ print-rx.c print-sctp.c print-sl.c print-sll.c print-smb.c \ diff --git a/ethertype.h b/ethertype.h index ca6dbfc8..fcfd3ec4 100644 --- a/ethertype.h +++ b/ethertype.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/tcpdump/ethertype.h,v 1.15 2001-04-03 05:21:24 fenner Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/ethertype.h,v 1.16 2001-06-21 17:56:02 itojun Exp $ (LBL) */ /* @@ -105,6 +105,12 @@ #ifndef ETHERTYPE_PPP #define ETHERTYPE_PPP 0x880b #endif +#ifndef ETHERTYPE_MPLS +#define ETHERTYPE_MPLS 0x8847 +#endif +#ifndef ETHERTYPE_MPLS_MULTI +#define ETHERTYPE_MPLS_MULTI 0x8848 +#endif #ifndef ETHERTYPE_PPPOED #define ETHERTYPE_PPPOED 0x8863 #endif diff --git a/interface.h b/interface.h index 21f2481f..3d5634e5 100644 --- a/interface.h +++ b/interface.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.162 2001-06-20 07:40:44 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.163 2001-06-21 17:56:03 itojun Exp $ (LBL) */ #ifndef tcpdump_interface_h @@ -279,6 +279,7 @@ extern void radius_print(const u_char *, u_int); extern void lwres_print(const u_char *, u_int); extern void pptp_print(const u_char *, u_int); extern void sctp_print(const u_char *, const u_char *, u_int); +extern void mpls_print(const u_char *, u_int); #ifdef INET6 extern void ip6_print(const u_char *, int); diff --git a/print-ether.c b/print-ether.c index 24d19929..30956ed7 100644 --- a/print-ether.c +++ b/print-ether.c @@ -20,7 +20,7 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.63 2001-03-12 00:24:54 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.64 2001-06-21 17:56:03 itojun Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -234,6 +234,11 @@ ether_encap_print(u_short ethertype, const u_char *p, } return (1); + case ETHERTYPE_MPLS: + case ETHERTYPE_MPLS_MULTI: + mpls_print(p, length); + return (1); + case ETHERTYPE_LAT: case ETHERTYPE_SCA: case ETHERTYPE_MOPRC: diff --git a/print-mpls.c b/print-mpls.c new file mode 100644 index 00000000..69afa17f --- /dev/null +++ b/print-mpls.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2001 WIDE Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static const char rcsid[] = + "@(#) $Header: /tcpdump/master/tcpdump/print-mpls.c,v 1.1 2001-06-21 17:56:04 itojun Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include +#include +#include +#include + +#include "addrtoname.h" +#include "interface.h" +#include "extract.h" /* must come after interface.h */ + +#define LABEL_MASK 0xfffff000 +#define LABEL_SHIFT 12 +#define EXP_MASK 0x00000e00 +#define EXP_SHIFT 9 +#define STACK_MASK 0x00000100 +#define STACK_SHIFT 8 +#define TTL_MASK 0x000000ff +#define TTL_SHIFT 0 + +#define MPLS_LABEL(x) (((x) & LABEL_MASK) >> LABEL_SHIFT) +#define MPLS_EXP(x) (((x) & EXP_MASK) >> EXP_SHIFT) +#define MPLS_STACK(x) (((x) & STACK_MASK) >> STACK_SHIFT) +#define MPLS_TTL(x) (((x) & TTL_MASK) >> TTL_SHIFT) + +static const char *mpls_labelname[] = { +/*0*/ "IPv4 explicit NULL", "router alert", "IPv6 explicit NULL", + "implicit NULL", "rsvd", +/*5*/ "rsvd", "rsvd", "rsvd", "rsvd", "rsvd", +/*10*/ "rsvd", "rsvd", "rsvd", "rsvd", "rsvd", +/*15*/ "rsvd", +}; + +/* + * RFC3032: MPLS label stack encoding + */ +void +mpls_print(const u_char *bp, u_int length) +{ + const u_char *p; + u_int32_t v; + + p = bp; + printf("MPLS"); + TCHECK2(*p, sizeof(v)); + memcpy(&v, p, sizeof(v)); + v = (u_int32_t)ntohl(v); + printf(" ("); /*)*/ + printf("label 0x%x", MPLS_LABEL(v)); + if (vflag && + MPLS_LABEL(v) < sizeof(mpls_labelname) / sizeof(mpls_labelname[0])) + printf("(%s)", mpls_labelname[MPLS_LABEL(v)]); + if (MPLS_EXP(v)) + printf(" exp 0x%x", MPLS_EXP(v)); + if (MPLS_STACK(v)) + printf("[S]"); + printf(" TTL %u", MPLS_TTL(v)); + /*(*/ + printf(")"); + + p += sizeof(v); + + switch (MPLS_LABEL(v)) { + case 0: /* IPv4 explicit NULL label */ + ip_print(p, length - (p - bp)); + break; +#ifdef INET6 + case 2: /* IPv6 explicit NULL label */ + ip6_print(p, length - (p - bp)); + break; +#endif + default: + /* + * Since there's no indication of protocol in MPLS label + * encoding, we can print nothing further. + */ + return; + } + +trunc: + printf("[|MPLS]"); +}