]> The Tcpdump Group git mirrors - tcpdump/commitdiff
MPLS label encapsulation decoding, per RFC3032.
authoritojun <itojun>
Thu, 21 Jun 2001 17:56:02 +0000 (17:56 +0000)
committeritojun <itojun>
Thu, 21 Jun 2001 17:56:02 +0000 (17:56 +0000)
TODO: multiple labels.  other media types.

Makefile.in
ethertype.h
interface.h
print-ether.c
print-mpls.c [new file with mode: 0644]

index af3bcced5ff12a4e42f3b88d9937168e13abf54b..524914e51df822cd329eb4f2b3496efe534fed04 100644 (file)
@@ -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 \
index ca6dbfc82f54f58f541426ab76fe2aad917dc370..fcfd3ec40a5bc991a14c0dd29d84403adfc9194b 100644 (file)
@@ -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)
  */
 
 /*
 #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
index 21f2481f67c58c1edf516ae38a43b2de4a7b8a83..3d5634e59a573a3e1a93b941a0a0272495467d0d 100644 (file)
@@ -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);
index 24d199294fadeb462a484f05be519a6d1e25de8b..30956ed7df9fcea4f5e407693e0f6d30c9564432 100644 (file)
@@ -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 (file)
index 0000000..69afa17
--- /dev/null
@@ -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 <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#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]");
+}