print-mpls.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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. /* \summary: Multi-Protocol Label Switching (MPLS) printer */
  29. #ifdef HAVE_CONFIG_H
  30. #include "config.h"
  31. #endif
  32. #include <netdissect-stdinc.h>
  33. #include "netdissect.h"
  34. #include "extract.h"
  35. #include "mpls.h"
  36. static const char *mpls_labelname[] = {
  37. /*0*/ "IPv4 explicit NULL", "router alert", "IPv6 explicit NULL",
  38. "implicit NULL", "rsvd",
  39. /*5*/ "rsvd", "rsvd", "rsvd", "rsvd", "rsvd",
  40. /*10*/ "rsvd", "rsvd", "rsvd", "rsvd", "rsvd",
  41. /*15*/ "rsvd",
  42. };
  43. enum mpls_packet_type {
  44. PT_UNKNOWN,
  45. PT_IPV4,
  46. PT_IPV6,
  47. PT_OSI
  48. };
  49. /*
  50. * RFC3032: MPLS label stack encoding
  51. */
  52. void
  53. mpls_print(netdissect_options *ndo, const u_char *bp, u_int length)
  54. {
  55. const u_char *p;
  56. uint32_t label_entry;
  57. uint16_t label_stack_depth = 0;
  58. enum mpls_packet_type pt = PT_UNKNOWN;
  59. p = bp;
  60. ND_PRINT((ndo, "MPLS"));
  61. do {
  62. ND_TCHECK2(*p, sizeof(label_entry));
  63. if (length < sizeof(label_entry)) {
  64. ND_PRINT((ndo, "[|MPLS], length %u", length));
  65. return;
  66. }
  67. label_entry = EXTRACT_32BITS(p);
  68. ND_PRINT((ndo, "%s(label %u",
  69. (label_stack_depth && ndo->ndo_vflag) ? "\n\t" : " ",
  70. MPLS_LABEL(label_entry)));
  71. label_stack_depth++;
  72. if (ndo->ndo_vflag &&
  73. MPLS_LABEL(label_entry) < sizeof(mpls_labelname) / sizeof(mpls_labelname[0]))
  74. ND_PRINT((ndo, " (%s)", mpls_labelname[MPLS_LABEL(label_entry)]));
  75. ND_PRINT((ndo, ", exp %u", MPLS_EXP(label_entry)));
  76. if (MPLS_STACK(label_entry))
  77. ND_PRINT((ndo, ", [S]"));
  78. ND_PRINT((ndo, ", ttl %u)", MPLS_TTL(label_entry)));
  79. p += sizeof(label_entry);
  80. length -= sizeof(label_entry);
  81. } while (!MPLS_STACK(label_entry));
  82. /*
  83. * Try to figure out the packet type.
  84. */
  85. switch (MPLS_LABEL(label_entry)) {
  86. case 0: /* IPv4 explicit NULL label */
  87. case 3: /* IPv4 implicit NULL label */
  88. pt = PT_IPV4;
  89. break;
  90. case 2: /* IPv6 explicit NULL label */
  91. pt = PT_IPV6;
  92. break;
  93. default:
  94. /*
  95. * Generally there's no indication of protocol in MPLS label
  96. * encoding.
  97. *
  98. * However, draft-hsmit-isis-aal5mux-00.txt describes a
  99. * technique for encapsulating IS-IS and IP traffic on the
  100. * same ATM virtual circuit; you look at the first payload
  101. * byte to determine the network layer protocol, based on
  102. * the fact that
  103. *
  104. * 1) the first byte of an IP header is 0x45-0x4f
  105. * for IPv4 and 0x60-0x6f for IPv6;
  106. *
  107. * 2) the first byte of an OSI CLNP packet is 0x81,
  108. * the first byte of an OSI ES-IS packet is 0x82,
  109. * and the first byte of an OSI IS-IS packet is
  110. * 0x83;
  111. *
  112. * so the network layer protocol can be inferred from the
  113. * first byte of the packet, if the protocol is one of the
  114. * ones listed above.
  115. *
  116. * Cisco sends control-plane traffic MPLS-encapsulated in
  117. * this fashion.
  118. */
  119. ND_TCHECK(*p);
  120. if (length < 1) {
  121. /* nothing to print */
  122. return;
  123. }
  124. switch(*p) {
  125. case 0x45:
  126. case 0x46:
  127. case 0x47:
  128. case 0x48:
  129. case 0x49:
  130. case 0x4a:
  131. case 0x4b:
  132. case 0x4c:
  133. case 0x4d:
  134. case 0x4e:
  135. case 0x4f:
  136. pt = PT_IPV4;
  137. break;
  138. case 0x60:
  139. case 0x61:
  140. case 0x62:
  141. case 0x63:
  142. case 0x64:
  143. case 0x65:
  144. case 0x66:
  145. case 0x67:
  146. case 0x68:
  147. case 0x69:
  148. case 0x6a:
  149. case 0x6b:
  150. case 0x6c:
  151. case 0x6d:
  152. case 0x6e:
  153. case 0x6f:
  154. pt = PT_IPV6;
  155. break;
  156. case 0x81:
  157. case 0x82:
  158. case 0x83:
  159. pt = PT_OSI;
  160. break;
  161. default:
  162. /* ok bail out - we did not figure out what it is*/
  163. break;
  164. }
  165. }
  166. /*
  167. * Print the payload.
  168. */
  169. if (pt == PT_UNKNOWN) {
  170. if (!ndo->ndo_suppress_default_print)
  171. ND_DEFAULTPRINT(p, length);
  172. return;
  173. }
  174. ND_PRINT((ndo, ndo->ndo_vflag ? "\n\t" : " "));
  175. switch (pt) {
  176. case PT_IPV4:
  177. ip_print(ndo, p, length);
  178. break;
  179. case PT_IPV6:
  180. ip6_print(ndo, p, length);
  181. break;
  182. case PT_OSI:
  183. isoclns_print(ndo, p, length);
  184. break;
  185. default:
  186. break;
  187. }
  188. return;
  189. trunc:
  190. ND_PRINT((ndo, "[|MPLS]"));
  191. }
  192. /*
  193. * Local Variables:
  194. * c-style: whitesmith
  195. * c-basic-offset: 8
  196. * End:
  197. */