From Lars Roland:
[obnox/wireshark/wip.git] / packet-mpls.c
index e8b677dd449e58d07fb6b71adf72a1f2ec74da36..e417191600ae89e5187aac8af987479fe623bb8f 100644 (file)
@@ -1,25 +1,24 @@
 /* packet-mpls.c
  * Routines for MPLS data packet disassembly
- * 
+ *
  * (c) Copyright Ashok Narayanan <ashokn@cisco.com>
  *
- * $Id: packet-mpls.c,v 1.19 2001/04/19 23:02:44 guy Exp $
+ * $Id: packet-mpls.c,v 1.29 2003/01/27 19:28:52 guy Exp $
  *
  * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@zing.org>
+ * By Gerald Combs <gerald@ethereal.com>
  * Copyright 1998 Gerald Combs
  *
- * 
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  * of the License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 # include "config.h"
 #endif
 
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
 #include <glib.h>
-#include "packet.h"
-#include "packet-ip.h"
+#include <epan/packet.h>
 #include "ppptypes.h"
 #include "etypes.h"
 
@@ -88,28 +82,30 @@ enum mpls_filter_keys {
 static int mpls_filter[MPLSF_MAX];
 static hf_register_info mplsf_info[] = {
 
-/*    {&mpls_filter[MPLSF_PACKET], 
-     {"MPLS Label Switched Packet", "mpls", FT_UINT8, BASE_DEC, NULL, 0x0, 
-      "" }},*/
+/*    {&mpls_filter[MPLSF_PACKET],
+     {"MPLS Label Switched Packet", "mpls", FT_UINT8, BASE_DEC, NULL, 0x0,
+      "", HFILL }},*/
 
-    {&mpls_filter[MPLSF_LABEL], 
-     {"MPLS Label", "mpls.label", FT_UINT32, BASE_DEC, VALS(special_labels), 0x0, 
-      "" }},
+    {&mpls_filter[MPLSF_LABEL],
+     {"MPLS Label", "mpls.label", FT_UINT32, BASE_DEC, VALS(special_labels), 0x0,
+      "", HFILL }},
 
-    {&mpls_filter[MPLSF_EXP], 
-     {"MPLS Experimental Bits", "mpls.exp", FT_UINT8, BASE_DEC, NULL, 0x0, 
-      "" }},
+    {&mpls_filter[MPLSF_EXP],
+     {"MPLS Experimental Bits", "mpls.exp", FT_UINT8, BASE_DEC, NULL, 0x0,
+      "", HFILL }},
 
-    {&mpls_filter[MPLSF_BOTTOM_OF_STACK], 
-     {"MPLS Bottom Of Label Stack", "mpls.bottom", FT_UINT8, BASE_DEC, NULL, 0x0, 
-      "" }},
+    {&mpls_filter[MPLSF_BOTTOM_OF_STACK],
+     {"MPLS Bottom Of Label Stack", "mpls.bottom", FT_UINT8, BASE_DEC, NULL, 0x0,
+      "", HFILL }},
 
-    {&mpls_filter[MPLSF_TTL], 
-     {"MPLS TTL", "mpls.ttl", FT_UINT8, BASE_DEC, NULL, 0x0, 
-      "" }},
+    {&mpls_filter[MPLSF_TTL],
+     {"MPLS TTL", "mpls.ttl", FT_UINT8, BASE_DEC, NULL, 0x0,
+      "", HFILL }},
 };
 
-static dissector_handle_t ip_handle;
+static dissector_handle_t ipv4_handle;
+static dissector_handle_t ipv6_handle;
+static dissector_handle_t eth_handle;
 
 /*
  * Given a 4-byte MPLS label starting at offset "offset", in tvbuff "tvb",
@@ -132,24 +128,25 @@ void decode_mpls_label(tvbuff_t *tvb, int offset,
 }
 
 static void
-dissect_mpls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) 
+dissect_mpls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
     int offset = 0;
     guint32 label;
     guint8 exp;
     guint8 bos;
     guint8 ttl;
+    guint8 ipvers;
 
     proto_tree  *mpls_tree;
     proto_item  *ti;
     tvbuff_t *next_tvb;
 
-    if (check_col(pinfo->fd, COL_PROTOCOL)) {
-       col_set_str(pinfo->fd,COL_PROTOCOL, "MPLS");
+    if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
+       col_set_str(pinfo->cinfo,COL_PROTOCOL, "MPLS");
     }
-    
-    if (check_col(pinfo->fd,COL_INFO)) {
-       col_add_fstr(pinfo->fd,COL_INFO,"MPLS Label Switched Packet");
+
+    if (check_col(pinfo->cinfo,COL_INFO)) {
+       col_add_fstr(pinfo->cinfo,COL_INFO,"MPLS Label Switched Packet");
     }
 
     /* Start Decoding Here. */
@@ -163,25 +160,33 @@ dissect_mpls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
            if (label <= MAX_RESERVED)
                proto_tree_add_uint_format(mpls_tree, mpls_filter[MPLSF_LABEL], tvb,
-                                   offset, 3, label, "Label: %u (%s)", 
-                                   label, val_to_str(label, special_labels, 
+                                   offset, 3, label, "Label: %u (%s)",
+                                   label, val_to_str(label, special_labels,
                                                      "Reserved - Unknown"));
            else
                proto_tree_add_uint(mpls_tree, mpls_filter[MPLSF_LABEL], tvb,
                                    offset, 3, label);
 
-           proto_tree_add_uint(mpls_tree,mpls_filter[MPLSF_EXP], tvb, 
+           proto_tree_add_uint(mpls_tree,mpls_filter[MPLSF_EXP], tvb,
                                offset+2,1, exp);
-           proto_tree_add_uint(mpls_tree,mpls_filter[MPLSF_BOTTOM_OF_STACK], tvb, 
+           proto_tree_add_uint(mpls_tree,mpls_filter[MPLSF_BOTTOM_OF_STACK], tvb,
                                offset+2,1, bos);
-           proto_tree_add_uint(mpls_tree,mpls_filter[MPLSF_TTL], tvb, 
+           proto_tree_add_uint(mpls_tree,mpls_filter[MPLSF_TTL], tvb,
                                offset+3,1, ttl);
        }
        offset += 4;
        if (bos) break;
     }
     next_tvb = tvb_new_subset(tvb, offset, -1, -1);
-    call_dissector(ip_handle, next_tvb, pinfo, tree);
+
+    ipvers = (tvb_get_guint8(tvb, offset) >> 4) & 0x0F;
+    if (ipvers == 6) {
+      call_dissector(ipv6_handle, next_tvb, pinfo, tree);
+    } else if (ipvers == 4) {
+      call_dissector(ipv4_handle, next_tvb, pinfo, tree);
+    } else {
+      call_dissector(eth_handle, next_tvb, pinfo, tree);
+    }
 }
 
 void
@@ -200,11 +205,18 @@ proto_register_mpls(void)
 void
 proto_reg_handoff_mpls(void)
 {
+       dissector_handle_t mpls_handle;
+
        /*
-        * Get a handle for the IP dissector.
+        * Get a handle for the IPv4 and IPv6 dissectors.
         */
-       ip_handle = find_dissector("ip");
-
-       dissector_add("ethertype", ETHERTYPE_MPLS, dissect_mpls, proto_mpls);
-       dissector_add("ppp.protocol", PPP_MPLS_UNI, dissect_mpls, proto_mpls);
+       ipv4_handle = find_dissector("ip");
+       ipv6_handle = find_dissector("ipv6");
+       eth_handle = find_dissector("eth");
+
+       mpls_handle = create_dissector_handle(dissect_mpls, proto_mpls);
+       dissector_add("ethertype", ETHERTYPE_MPLS, mpls_handle);
+       dissector_add("ppp.protocol", PPP_MPLS_UNI, mpls_handle);
+       dissector_add("chdlctype", ETHERTYPE_MPLS, mpls_handle);
+       dissector_add("chdlctype", ETHERTYPE_MPLS_MULTI, mpls_handle);
 }