tcpdump  4.99.1
About: tcpdump is a tool for network monitoring and data acquisition.
  Fossies Dox: tcpdump-4.99.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

print-mpls.c
Go to the documentation of this file.
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 /* \summary: Multi-Protocol Label Switching (MPLS) printer */
30 
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34 
35 #include "netdissect-stdinc.h"
36 
37 #define ND_LONGJMP_FROM_TCHECK
38 #include "netdissect.h"
39 #include "extract.h"
40 #include "mpls.h"
41 
42 static const char *mpls_labelname[] = {
43 /*0*/ "IPv4 explicit NULL", "router alert", "IPv6 explicit NULL",
44  "implicit NULL", "rsvd",
45 /*5*/ "rsvd", "rsvd", "rsvd", "rsvd", "rsvd",
46 /*10*/ "rsvd", "rsvd", "rsvd", "rsvd", "rsvd",
47 /*15*/ "rsvd",
48 };
49 
54  PT_OSI
55 };
56 
57 /*
58  * RFC3032: MPLS label stack encoding
59  */
60 void
61 mpls_print(netdissect_options *ndo, const u_char *bp, u_int length)
62 {
63  const u_char *p;
64  uint32_t label_entry;
65  uint16_t label_stack_depth = 0;
66  uint8_t first;
67  enum mpls_packet_type pt = PT_UNKNOWN;
68 
69  ndo->ndo_protocol = "mpls";
70  p = bp;
72  do {
73  if (length < sizeof(label_entry))
74  goto invalid;
75  label_entry = GET_BE_U_4(p);
76  ND_PRINT("%s(label %u",
77  (label_stack_depth && ndo->ndo_vflag) ? "\n\t" : " ",
78  MPLS_LABEL(label_entry));
79  label_stack_depth++;
80  if (ndo->ndo_vflag &&
81  MPLS_LABEL(label_entry) < sizeof(mpls_labelname) / sizeof(mpls_labelname[0]))
82  ND_PRINT(" (%s)", mpls_labelname[MPLS_LABEL(label_entry)]);
83  ND_PRINT(", exp %u", MPLS_EXP(label_entry));
84  if (MPLS_STACK(label_entry))
85  ND_PRINT(", [S]");
86  ND_PRINT(", ttl %u)", MPLS_TTL(label_entry));
87 
88  p += sizeof(label_entry);
89  length -= sizeof(label_entry);
90  } while (!MPLS_STACK(label_entry));
91 
92  /*
93  * Try to figure out the packet type.
94  */
95  switch (MPLS_LABEL(label_entry)) {
96 
97  case 0: /* IPv4 explicit NULL label */
98  case 3: /* IPv4 implicit NULL label */
99  pt = PT_IPV4;
100  break;
101 
102  case 2: /* IPv6 explicit NULL label */
103  pt = PT_IPV6;
104  break;
105 
106  default:
107  /*
108  * Generally there's no indication of protocol in MPLS label
109  * encoding.
110  *
111  * However, draft-hsmit-isis-aal5mux-00.txt describes a
112  * technique for encapsulating IS-IS and IP traffic on the
113  * same ATM virtual circuit; you look at the first payload
114  * byte to determine the network layer protocol, based on
115  * the fact that
116  *
117  * 1) the first byte of an IP header is 0x45-0x4f
118  * for IPv4 and 0x60-0x6f for IPv6;
119  *
120  * 2) the first byte of an OSI CLNP packet is 0x81,
121  * the first byte of an OSI ES-IS packet is 0x82,
122  * and the first byte of an OSI IS-IS packet is
123  * 0x83;
124  *
125  * so the network layer protocol can be inferred from the
126  * first byte of the packet, if the protocol is one of the
127  * ones listed above.
128  *
129  * Cisco sends control-plane traffic MPLS-encapsulated in
130  * this fashion.
131  */
132  if (length < 1) {
133  /* nothing to print */
134  return;
135  }
136  first = GET_U_1(p);
137  pt =
138  (first >= 0x45 && first <= 0x4f) ? PT_IPV4 :
139  (first >= 0x60 && first <= 0x6f) ? PT_IPV6 :
140  (first >= 0x81 && first <= 0x83) ? PT_OSI :
141  /* ok bail out - we did not figure out what it is*/
142  PT_UNKNOWN;
143  }
144 
145  /*
146  * Print the payload.
147  */
148  switch (pt) {
149  case PT_UNKNOWN:
150  if (!ndo->ndo_suppress_default_print)
151  ND_DEFAULTPRINT(p, length);
152  break;
153 
154  case PT_IPV4:
155  ND_PRINT(ndo->ndo_vflag ? "\n\t" : " ");
156  ip_print(ndo, p, length);
157  break;
158 
159  case PT_IPV6:
160  ND_PRINT(ndo->ndo_vflag ? "\n\t" : " ");
161  ip6_print(ndo, p, length);
162  break;
163 
164  case PT_OSI:
165  ND_PRINT(ndo->ndo_vflag ? "\n\t" : " ");
166  isoclns_print(ndo, p, length);
167  break;
168  }
169  return;
170 
171 invalid:
172  nd_print_invalid(ndo);
173  ND_TCHECK_LEN(p, length);
174 }
#define GET_BE_U_4(p)
Definition: extract.h:877
#define GET_U_1(p)
Definition: extract.h:872
#define MPLS_TTL(x)
Definition: mpls.h:41
#define MPLS_EXP(x)
Definition: mpls.h:39
#define MPLS_STACK(x)
Definition: mpls.h:40
#define MPLS_LABEL(x)
Definition: mpls.h:38
void nd_print_protocol_caps(netdissect_options *)
Definition: util-print.c:421
void ip6_print(netdissect_options *, const u_char *, u_int)
Definition: print-ip6.c:226
#define ND_TCHECK_LEN(p, l)
Definition: netdissect.h:368
void isoclns_print(netdissect_options *, const u_char *, u_int)
void nd_print_invalid(netdissect_options *)
Definition: util-print.c:429
#define ND_DEFAULTPRINT(ap, length)
Definition: netdissect.h:386
void ip_print(netdissect_options *, const u_char *, u_int)
Definition: print-ip.c:319
#define ND_PRINT(...)
Definition: netdissect.h:385
void mpls_print(netdissect_options *ndo, const u_char *bp, u_int length)
Definition: print-mpls.c:61
mpls_packet_type
Definition: print-mpls.c:50
@ PT_IPV6
Definition: print-mpls.c:53
@ PT_IPV4
Definition: print-mpls.c:52
@ PT_OSI
Definition: print-mpls.c:54
@ PT_UNKNOWN
Definition: print-mpls.c:51
static const char * mpls_labelname[]
Definition: print-mpls.c:42
int ndo_suppress_default_print
Definition: netdissect.h:222
const char * ndo_protocol
Definition: netdissect.h:218