From Hannes Gredler
authorsahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 11 May 2005 11:24:17 +0000 (11:24 +0000)
committersahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 11 May 2005 11:24:17 +0000 (11:24 +0000)
support for Juniper PPPOE encapsulation

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@14346 f5534014-38df-0310-8fa8-9805f1628bb7

AUTHORS
epan/dissectors/packet-juniper.c
wiretap/libpcap.c
wiretap/wtap.c
wiretap/wtap.h

diff --git a/AUTHORS b/AUTHORS
index db008a7dc94af64fbb2318c73da4963649ac77a2..73d0e53e217ea1fc1bacc777f3df368435a7d13d 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -740,6 +740,7 @@ Hannes Gredler          <hannes[AT]juniper.net> {
        Support MPLS over CHDLC
        Bi-directional Fault Detection (BFD) support
        Support for Juniper's DLT_JUNIPER_ATM{1,2} values
+       Support for Juniper's PPPOE encapsulation
 }
 
 Inoue                   <inoue[AT]ainet.or.jp> {
index a159304aff24d5a9fe8f6e8d50b1fa4e2856a8f1..e30d914756cb0ab0b46e3891962c10fc21c7ecf9 100644 (file)
@@ -82,10 +82,103 @@ static dissector_handle_t data_handle;
 static dissector_table_t osinl_subdissector_table;
 static dissector_table_t osinl_excl_subdissector_table;
 
+int dissect_juniper_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *ti, guint8 *flags);
 static void dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 atm_pictype);
 static gboolean ppp_heuristic_guess(guint16 proto);
 static guint ip_heuristic_guess(guint8 ip_header_byte);
 
+/* generic juniper header dissector  */
+int
+dissect_juniper_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *ti, guint8 *flags)
+{
+  proto_item *tisub;
+  proto_tree *subtree = NULL;
+  guint8     direction,l2hdr_presence,ipvers;
+  guint32    magic_number;
+
+  tvbuff_t   *next_tvb;
+
+  magic_number = tvb_get_ntoh24(tvb, 0);
+  *flags = tvb_get_guint8(tvb, 3);
+  direction = *flags & JUNIPER_FLAG_PKT_IN;
+  l2hdr_presence = *flags & JUNIPER_FLAG_NO_L2;
+
+  subtree = proto_item_add_subtree(ti, ett_juniper);          
+  tisub = proto_tree_add_text (subtree, tvb, 0, 3,
+                            "Magic-Number: 0x%06x (%scorrect)", 
+                            magic_number,
+                            (magic_number == JUNIPER_PCAP_MAGIC) ?  "" : "in" );
+    
+  if (magic_number != JUNIPER_PCAP_MAGIC)
+     return -1;
+  
+  tisub = proto_tree_add_uint_format (subtree, hf_juniper_direction, tvb, 3, 1,
+                            direction, "Direction: %s",
+                            val_to_str(direction,juniper_direction_vals,"Unknown"));
+  
+  tisub = proto_tree_add_uint_format (subtree, hf_juniper_l2hdr_presence, tvb, 3, 1,
+                            l2hdr_presence, "L2-header: %s",
+                            val_to_str(l2hdr_presence,juniper_l2hdr_presence_vals,"Unknown"));
+
+  if ((*flags & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) { /* no link header present ? */
+      next_tvb = tvb_new_subset(tvb, 8, -1, -1);
+      ipvers = ip_heuristic_guess(tvb_get_guint8(tvb, 8)); /* try IP */
+      if (ipvers != 0) {
+          ti = proto_tree_add_text (subtree, tvb, 8, 0,
+                                    "Payload Type: Null encapsulation IPv%u",
+                                    ipvers);
+          switch (ipvers) {
+          case 6:
+              call_dissector(ipv6_handle, next_tvb, pinfo, tree);
+              break;
+          case 4:
+              call_dissector(ipv4_handle, next_tvb, pinfo, tree);  
+              break;
+          }
+      }
+      return -1;
+  }
+
+  return 4; /* 4 bytes parsed */
+
+}
+
+
+/* PPPoE dissector */
+static void
+dissect_juniper_pppoe(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+  proto_item *ti;
+  proto_tree *subtree = NULL;
+  guint      offset;
+  int        bytes_processed;
+  guint8     flags;
+  tvbuff_t   *next_tvb;
+
+  if (check_col(pinfo->cinfo, COL_PROTOCOL))
+      col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper PPPoE");
+  if (check_col(pinfo->cinfo, COL_INFO))
+      col_clear(pinfo->cinfo, COL_INFO);
+
+  offset = 0;
+
+  ti = proto_tree_add_text (tree, tvb, offset, 4, "Juniper PPPoE PIC");
+  bytes_processed = dissect_juniper_header(tvb, pinfo, tree, ti, &flags);
+
+  /* parse header, match mgc, extract flags and build first tree */
+  if(bytes_processed == -1)
+      return;
+  else
+      offset+=bytes_processed;
+
+  next_tvb = tvb_new_subset(tvb, offset, -1, -1);  
+
+  ti = proto_tree_add_text (subtree, tvb, offset, 0, "Payload Type: Ethernet");
+  call_dissector(eth_handle, next_tvb, pinfo, tree);
+
+}
+
+
 /* wrapper for passing the PIC type to the generic ATM dissector */
 static void
 dissect_juniper_atm1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
@@ -106,11 +199,11 @@ dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16
 {
   proto_item *ti,*tisub;
   proto_tree *subtree = NULL;
-  guint8     direction,l2hdr_presence,flags,ipvers,atm1_header_len,atm2_header_len;
-  guint32    magic_number, cookie1, proto;
+  guint8     ipvers,atm1_header_len,atm2_header_len,flags;
+  guint32    cookie1, proto;
   guint64    cookie2;
-  guint      offset;
-
+  guint      offset = 0;
+  int        bytes_processed;
   tvbuff_t   *next_tvb;
 
   switch (atm_pictype) {
@@ -132,80 +225,33 @@ dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16
   if (check_col(pinfo->cinfo, COL_INFO))
       col_clear(pinfo->cinfo, COL_INFO);
 
-  offset = 0;
-  magic_number = tvb_get_ntoh24(tvb, 0);
-  flags = tvb_get_guint8(tvb, 3);
-  direction = flags & JUNIPER_FLAG_PKT_IN;
-  l2hdr_presence = flags & JUNIPER_FLAG_NO_L2;
-
-  if ((flags & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) {
-      atm1_header_len = 8;
-      atm2_header_len = 8;
-  }
-  else {
-      atm1_header_len = 8;
-      atm2_header_len = 12;
-  }
-
   switch (atm_pictype) {
   case JUNIPER_ATM1:
-      ti = proto_tree_add_text (tree, tvb, 0, atm1_header_len, "Juniper ATM1 PIC");
+      ti = proto_tree_add_text (tree, tvb, 0, , "Juniper ATM1 PIC");
       break;
   case JUNIPER_ATM2:
-      ti = proto_tree_add_text (tree, tvb, 0, atm2_header_len, "Juniper ATM2 PIC");
+      ti = proto_tree_add_text (tree, tvb, 0, , "Juniper ATM2 PIC");
       break;
   default: /* should not happen */
       ti = proto_tree_add_text (tree, tvb, 0, 0 , "Juniper unknown ATM PIC");
       return;
   }
 
-  subtree = proto_item_add_subtree(ti, ett_juniper);  
-        
-  tisub = proto_tree_add_text (subtree, tvb, 0, 3,
-                            "Magic-Number: 0x%06x (%scorrect)", 
-                            magic_number,
-                            (magic_number == JUNIPER_PCAP_MAGIC) ?  "" : "in" );
-    
-  if (magic_number != JUNIPER_PCAP_MAGIC)
-     return;
-  
-  tisub = proto_tree_add_uint_format (subtree, hf_juniper_direction, tvb, 3, 1,
-                            direction, "Direction: %s",
-                            val_to_str(direction,juniper_direction_vals,"Unknown"));
-  
-  tisub = proto_tree_add_uint_format (subtree, hf_juniper_l2hdr_presence, tvb, 3, 1,
-                            l2hdr_presence, "L2-header: %s",
-                            val_to_str(l2hdr_presence,juniper_l2hdr_presence_vals,"Unknown"));
-
+  subtree = proto_item_add_subtree(ti, ett_juniper);
+  /* parse header, match mgc, extract flags and build first tree */
+  bytes_processed = dissect_juniper_header(tvb, pinfo, tree, ti, &flags);
+  if(bytes_processed == -1)
+      return;
+  else
+      offset+=bytes_processed;
 
-  switch (atm_pictype) {
-  case JUNIPER_ATM1:
-      offset += atm1_header_len;
-      break;
-  case JUNIPER_ATM2:
-      offset += atm2_header_len;
-      break;
-  default: /* should not happen */
-      return;  
+  if ((flags & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) {
+      atm1_header_len = 4;
+      atm2_header_len = 4;
   }
-
-  if ((flags & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) { /* no link header present ? */
-      next_tvb = tvb_new_subset(tvb, offset, -1, -1);
-      ipvers = ip_heuristic_guess(tvb_get_guint8(tvb, offset)); /* try IP */
-      if (ipvers != 0) {
-          ti = proto_tree_add_text (subtree, tvb, offset, 0,
-                                    "Payload Type: Null encapsulation IPv%u",
-                                    ipvers);
-          switch (ipvers) {
-          case 6:
-              call_dissector(ipv6_handle, next_tvb, pinfo, tree);
-              break;
-          case 4:
-              call_dissector(ipv4_handle, next_tvb, pinfo, tree);  
-              break;
-          }
-      }
-      return;
+  else {
+      atm1_header_len = 4;
+      atm2_header_len = 8;
   }
 
   cookie1 = tvb_get_ntohl(tvb,4);
@@ -214,9 +260,11 @@ dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16
   switch (atm_pictype) {
   case JUNIPER_ATM1:
       tisub = proto_tree_add_uint(subtree, hf_juniper_atm1_cookie, tvb, 4, 4, cookie1);
+      offset += atm1_header_len;
       break;
   case JUNIPER_ATM2:
       tisub = proto_tree_add_uint64(subtree, hf_juniper_atm2_cookie, tvb, 4, 8, cookie2);
+      offset += atm2_header_len;
       break;
   default: /* should not happen */
       return;  
@@ -248,7 +296,7 @@ dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16
       return;
   }
 
-  if (direction != JUNIPER_FLAG_PKT_IN && /* ether-over-1483 encaps ? */
+  if ((flags & JUNIPER_FLAG_PKT_IN) != JUNIPER_FLAG_PKT_IN && /* ether-over-1483 encaps ? */
       (cookie1 & JUNIPER_ATM2_GAP_COUNT_MASK) &&
       atm_pictype != JUNIPER_ATM1) {
       ti = proto_tree_add_text (subtree, tvb, offset, 0, "Payload Type: Ethernet");
@@ -418,6 +466,7 @@ proto_reg_handoff_juniper(void)
 {
   dissector_handle_t juniper_atm1_handle;
   dissector_handle_t juniper_atm2_handle;
+  dissector_handle_t juniper_pppoe_handle;
 
   osinl_subdissector_table = find_dissector_table("osinl");
   osinl_excl_subdissector_table = find_dissector_table("osinl.excl");
@@ -430,7 +479,9 @@ proto_reg_handoff_juniper(void)
 
   juniper_atm2_handle = create_dissector_handle(dissect_juniper_atm2, proto_juniper);
   juniper_atm1_handle = create_dissector_handle(dissect_juniper_atm1, proto_juniper);
+  juniper_pppoe_handle = create_dissector_handle(dissect_juniper_pppoe, proto_juniper);
   dissector_add("wtap_encap", WTAP_ENCAP_JUNIPER_ATM2, juniper_atm2_handle);
   dissector_add("wtap_encap", WTAP_ENCAP_JUNIPER_ATM1, juniper_atm1_handle);
+  dissector_add("wtap_encap", WTAP_ENCAP_JUNIPER_PPPOE, juniper_pppoe_handle);
 }
 
index 25c741b0c9a7e10f07bdb790d804344cea9fad90..2fc7b78a02f0b8b579403247143e13db40b7e684 100644 (file)
@@ -356,8 +356,13 @@ static const struct {
         * of the 0xff03 header, the 0xff, is replaced by a direction
         * byte.  I don't know whether any captures look like that,
         * but it is used for some Linux IP filtering (ipfilter?).
-        *
-        * 167 and 168 are reserved for more Juniper private-chassis-
+        */
+
+        /* Ethernet PPPoE frames captured on a service PIC */
+        { 167,          WTAP_ENCAP_JUNIPER_PPPOE },
+
+        /*
+        * 168 is reserved for more Juniper private-chassis-
         * internal meta-information.
         */
 
index 77daab6500fd25cd0edac80b7e500bb9e1826edc..a4a26459bd33801fa3d989117eb51719f4122241 100644 (file)
@@ -287,6 +287,9 @@ static const struct encap_type_info {
 
        /* WTAP_ENCAP_MTP2_WITH_PHDR */
        { "MTP2 with pseudoheader", "mtp2-with-phdr" },
+
+       /* WTAP_ENCAP_JUNIPER_PPPOE */
+       { "Juniper PPPoE", "juniper-pppoe" },
 };
 
 /* Name that should be somewhat descriptive. */
index 4fbc13b49994241a8a5dba9c3944b3b3800b5316..a6f4ab6cd7447954e0d89020a0a662586d144d8b 100644 (file)
 #define WTAP_ENCAP_NETTL_FDDI                  74
 #define WTAP_ENCAP_NETTL_UNKNOWN               75
 #define WTAP_ENCAP_MTP2_WITH_PHDR               76
+#define WTAP_ENCAP_JUNIPER_PPPOE                       77
 /* last WTAP_ENCAP_ value + 1 */
-#define WTAP_NUM_ENCAP_TYPES                   77
+#define WTAP_NUM_ENCAP_TYPES                   78
 
 /* File types that can be read by wiretap.
    We support writing some many of these file types, too, so we