Update a URL.
[obnox/wireshark/wip.git] / packet-eap.c
index 90bc638eba2bc8e27aecedbd8036113137a5e914..2a1bc999df4bc0683ba20bef565fc78b6549c63d 100644 (file)
@@ -2,22 +2,22 @@
  * Routines for EAP Extensible Authentication Protocol dissection
  * RFC 2284
  *
- * $Id: packet-eap.c,v 1.24 2002/03/28 09:51:17 guy Exp $
+ * $Id: packet-eap.c,v 1.34 2003/04/20 11:36:13 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * 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
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-
 #include <glib.h>
 #include <epan/packet.h>
 #include <epan/conversation.h>
@@ -57,7 +49,7 @@ static dissector_handle_t ssl_handle;
 #define EAP_SUCCESS    3
 #define EAP_FAILURE    4
 
-static const value_string eap_code_vals[] = { 
+static const value_string eap_code_vals[] = {
     { EAP_REQUEST,  "Request" },
     { EAP_RESPONSE, "Response" },
     { EAP_SUCCESS,  "Success" },
@@ -67,7 +59,7 @@ static const value_string eap_code_vals[] = {
 
 /*
 References:
-  1) http://www.iana.org/assignments/ppp-numbers       
+  1) http://www.iana.org/assignments/ppp-numbers
                        PPP EAP REQUEST/RESPONSE TYPES
   2) http://www.ietf.org/internet-drafts/draft-ietf-pppext-rfc2284bis-02.txt
   3) RFC2284
@@ -79,7 +71,7 @@ References:
 #define EAP_TYPE_TLS   13
 #define EAP_TYPE_LEAP  17
 
-static const value_string eap_type_vals[] = { 
+static const value_string eap_type_vals[] = {
   {EAP_TYPE_ID,  "Identity [RFC2284]" },
   {EAP_TYPE_NOTIFY,"Notification [RFC2284]" },
   {EAP_TYPE_NAK, "Nak (Response only) [RFC2284]" },
@@ -94,16 +86,16 @@ static const value_string eap_type_vals[] = {
   { 12,          "KEA-VALIDATE [Nace]" },
   {EAP_TYPE_TLS, "EAP-TLS [RFC2716] [Aboba]" },
   { 14,          "Defender Token (AXENT) [Rosselli]" },
-  { 15,          "Windows 2000 EAP [Asnes]" },
+  { 15,          "RSA Security SecurID EAP [Asnes, Liberman]" },
   { 16,          "Arcot Systems EAP [Jerdonek]" },
-  {EAP_TYPE_LEAP,"EAP-Cisco Wireless (LEAP) [Norman]" }, 
-  { 18,          "Nokia IP smart card authentication [Haverinen]" },  
+  {EAP_TYPE_LEAP,"EAP-Cisco Wireless (LEAP) [Norman]" },
+  { 18,          "Nokia IP smart card authentication [Haverinen]" },
   { 19,          "SRP-SHA1 Part 1 [Carlson]" },
   { 20,          "SRP-SHA1 Part 2 [Carlson]" },
   { 21,          "EAP-TTLS [Funk]" },
   { 22,          "Remote Access Service [Fields]" },
-  { 23,          "UMTS Authentication and Key Agreement [Haverinen]" }, 
-  { 24,          "EAP-3Com Wireless [Young]" }, 
+  { 23,          "UMTS Authentication and Key Agreement [Haverinen]" },
+  { 24,          "EAP-3Com Wireless [Young]" },
   { 25,          "PEAP [Palekar]" },
   { 26,          "MS-EAP-Authentication [Palekar]" },
   { 27,          "Mutual Authentication w/Key Exchange (MAKE)[Berrendonner]" },
@@ -112,6 +104,15 @@ static const value_string eap_type_vals[] = {
   { 30,          "DynamID [Merlin]" },
   { 31,          "Rob EAP [Ullah]" },
   { 32,          "SecurID EAP [Josefsson]" },
+  { 33,          "MS-Authentication-TLV [Palekar]" },
+  { 34,          "SentriNET [Kelleher]" },
+  { 35,          "EAP-Actiontec Wireless [Chang]" },
+  { 36,          "Cogent Systems Biometrics Authentication EAP [Xiong]" },
+  { 37,          "AirFortress EAP [Hibbard]" },
+  { 38,          "EAP-HTTP Digest [Tavakoli]" },
+  { 39,          "SecureSuite EAP [Clements]" },
+  { 40,          "DeviceConnect EAP [Pitard]" },
+  { 41,          "EAP-SPEKE [Zick]" },
   { 255,         "Vendor-specific [draft-ietf-pppext-rfc2284bis-02.txt]" },
   { 0,          NULL }
 
@@ -163,7 +164,7 @@ typedef struct {
 } frame_state_t;
 
 /*********************************************************************
-                           EAP-TLS 
+                           EAP-TLS
 RFC2716
 **********************************************************************/
 
@@ -194,14 +195,33 @@ static GHashTable *eaptls_fragment_table = NULL;
 
 static int   hf_eaptls_fragment  = -1;
 static int   hf_eaptls_fragments = -1;
+static int   hf_eaptls_fragment_overlap = -1;
+static int   hf_eaptls_fragment_overlap_conflict = -1;
+static int   hf_eaptls_fragment_multiple_tails = -1;
+static int   hf_eaptls_fragment_too_long_fragment = -1;
+static int   hf_eaptls_fragment_error = -1;
 static gint ett_eaptls_fragment  = -1;
 static gint ett_eaptls_fragments = -1;
 
+static const fragment_items eaptls_frag_items = {
+       &ett_eaptls_fragment,
+       &ett_eaptls_fragments,
+       &hf_eaptls_fragments,
+       &hf_eaptls_fragment,
+       &hf_eaptls_fragment_overlap,
+       &hf_eaptls_fragment_overlap_conflict,
+       &hf_eaptls_fragment_multiple_tails,
+       &hf_eaptls_fragment_too_long_fragment,
+       &hf_eaptls_fragment_error,
+       NULL,
+       "fragments"
+};
+
 /*********************************************************************
 **********************************************************************/
 
 static gboolean
-test_flag(unsigned char flag, unsigned char mask) 
+test_flag(unsigned char flag, unsigned char mask)
 {
   return ( ( flag & mask ) != 0 );
 }
@@ -381,7 +401,7 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
       **********************************************************************/
       case EAP_TYPE_ID:
        if (tree) {
-         proto_tree_add_text(eap_tree, tvb, offset, size, 
+         proto_tree_add_text(eap_tree, tvb, offset, size,
                              "Identity (%d byte%s): %s",
                              size, plurality(size, "", "s"),
                              tvb_format_text(tvb, offset, size));
@@ -394,7 +414,7 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
       **********************************************************************/
       case EAP_TYPE_NOTIFY:
        if (tree) {
-         proto_tree_add_text(eap_tree, tvb, offset, size, 
+         proto_tree_add_text(eap_tree, tvb, offset, size,
                              "Notification (%d byte%s): %s",
                              size, plurality(size, "", "s"),
                              tvb_format_text(tvb, offset, size));
@@ -404,8 +424,8 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
       **********************************************************************/
       case EAP_TYPE_NAK:
        if (tree) {
-         proto_tree_add_uint(eap_tree, hf_eap_type_nak, tvb,
-                             offset, size, eap_type);
+         proto_tree_add_item(eap_tree, hf_eap_type_nak, tvb,
+                             offset, 1, FALSE);
        }
        break;
       /*********************************************************************
@@ -446,39 +466,39 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        if (size>0) {
 
          tvbuff_t *next_tvb;
-         gint tvb_len; 
+         gint tvb_len;
          gboolean save_fragmented;
 
          tvb_len = tvb_length_remaining(tvb, offset);
          if (size < tvb_len)
            tvb_len = size;
-         
-           /* 
-              EAP/TLS is weird protocol (it comes from 
-              Microsoft after all). 
+
+           /*
+              EAP/TLS is weird protocol (it comes from
+              Microsoft after all).
 
               If we have series of fragmented packets,
               then there's no way of knowing that from
               the packet itself, if it is the last packet
-              in series, that is that the packet part of 
+              in series, that is that the packet part of
               bigger fragmented set of data.
 
               The only way to know is, by knowing
               that we are already in defragmentation
               "mode" and we are expecing packet
-              carrying fragment of data. (either 
+              carrying fragment of data. (either
               because we have not received expected
               amount of data, or because the packet before
               had "F"ragment flag set.)
 
-              The situation is alleviated by fact that it 
-              is simple ack/nack protcol so there's no 
-              place for out-of-order packets like it is 
-              possible with IP. 
+              The situation is alleviated by fact that it
+              is simple ack/nack protcol so there's no
+              place for out-of-order packets like it is
+              possible with IP.
 
               Anyway, point of this lengthy essay is that
               we have to keep state information in the
-              conversation, so that we can put ourselves in 
+              conversation, so that we can put ourselves in
               defragmenting mode and wait for the last packet,
               and have to attach state to frames as well, so
               that we can handle defragmentation after the
@@ -577,9 +597,9 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
            eap_tls_seq = 0;
          }
 
-         /* 
-            We test here to see whether EAP-TLS packet 
-            carry fragmented of TLS data. 
+         /*
+            We test here to see whether EAP-TLS packet
+            carry fragmented of TLS data.
 
             If this is the case, we do reasembly below,
             otherwise we just call dissector.
@@ -593,43 +613,25 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
             */
            save_fragmented = pinfo->fragmented;
            pinfo->fragmented = TRUE;
-           fd_head = fragment_add_seq(tvb, offset, pinfo, 
+           fd_head = fragment_add_seq(tvb, offset, pinfo,
                                   eap_reass_cookie,
                                   eaptls_fragment_table,
-                                  eap_tls_seq, 
+                                  eap_tls_seq,
                                   size,
                                   more_fragments);
 
            if (fd_head != NULL)            /* Reassembled  */
              {
 
-               fragment_data *ffd; /* fragment file descriptor */
-               proto_tree *ft=NULL;
-               proto_item *fi=NULL;
-               guint32 frag_offset;
-
                next_tvb = tvb_new_real_data(fd_head->data,
                                             fd_head->len,
                                             fd_head->len);
                tvb_set_child_real_data_tvbuff(tvb, next_tvb);
-               add_new_data_source(pinfo->fd, next_tvb,
-                                   "Reassembled EAP-TLS");
-               pinfo->fragmented = FALSE;
-               
-               fi = proto_tree_add_item(eap_tree, hf_eaptls_fragments,
-                                        next_tvb, 0, -1, FALSE);
-               ft = proto_item_add_subtree(fi, ett_eaptls_fragments);
-               frag_offset = 0;
-               for (ffd=fd_head->next; ffd; ffd=ffd->next){
-                 proto_tree_add_none_format(ft, hf_eaptls_fragment,
-                                            next_tvb, frag_offset, ffd->len,
-                                            "Frame:%u payload:%u-%u",
-                                            ffd->frame,
-                                            frag_offset,
-                                            frag_offset+ffd->len-1
-                                            );
-                 frag_offset += ffd->len;
-               }
+               add_new_data_source(pinfo, next_tvb, "Reassembled EAP-TLS");
+
+               show_fragment_seq_tree(fd_head, &eaptls_frag_items,
+                   eap_tree, pinfo, next_tvb);
+
                call_dissector(ssl_handle, next_tvb, pinfo, eap_tree);
 
                /*
@@ -641,7 +643,7 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
              }
 
            pinfo->fragmented = save_fragmented;
-                       
+
          } else { /* this data is NOT fragmented */
            next_tvb = tvb_new_subset(tvb, offset, tvb_len, size);
            call_dissector(ssl_handle, next_tvb, pinfo, eap_tree);
@@ -660,7 +662,7 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
          /* Version (byte) */
          if (tree) {
            field = tvb_get_guint8(tvb, offset);
-           proto_tree_add_text(eap_tree, tvb, offset, 1, 
+           proto_tree_add_text(eap_tree, tvb, offset, 1,
                                "Version: %i",field);
          }
          size--;
@@ -669,7 +671,7 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
          /* Unused  (byte) */
          if (tree) {
            field = tvb_get_guint8(tvb, offset);
-           proto_tree_add_text(eap_tree, tvb, offset, 1, 
+           proto_tree_add_text(eap_tree, tvb, offset, 1,
                                "Reserved: %i",field);
          }
          size--;
@@ -678,7 +680,7 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
          /* Count   (byte) */
          count = tvb_get_guint8(tvb, offset);
          if (tree) {
-           proto_tree_add_text(eap_tree, tvb, offset, 1, 
+           proto_tree_add_text(eap_tree, tvb, offset, 1,
                                "Count: %i",count);
          }
          size--;
@@ -695,7 +697,7 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
             * state in the conversation.
             */
            leap_state = conversation_state->leap_state;
-           
+
            /* Advance the state machine. */
            if (leap_state==0) leap_state =  1; else
            if (leap_state==1) leap_state =  2; else
@@ -720,26 +722,26 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
          /* Get the remembered state. */
          leap_state = packet_state->info;
 
-         if (tree) { 
+         if (tree) {
 
            if        (leap_state==1) {
-             proto_tree_add_text(eap_tree, tvb, offset, count, 
+             proto_tree_add_text(eap_tree, tvb, offset, count,
                                  "Peer Challenge [8] Random Value:\"%s\"",
                                  tvb_bytes_to_str(tvb, offset, count));
            } else if (leap_state==2) {
-             proto_tree_add_text(eap_tree, tvb, offset, count, 
+             proto_tree_add_text(eap_tree, tvb, offset, count,
                                  "Peer Response [24] NtChallengeResponse(%s)",
                                  tvb_bytes_to_str(tvb, offset, count));
            } else if (leap_state==3) {
-             proto_tree_add_text(eap_tree, tvb, offset, count, 
+             proto_tree_add_text(eap_tree, tvb, offset, count,
                                  "AP Challenge [8] Random Value:\"%s\"",
                                  tvb_bytes_to_str(tvb, offset, count));
            } else if (leap_state==4) {
-             proto_tree_add_text(eap_tree, tvb, offset, count, 
+             proto_tree_add_text(eap_tree, tvb, offset, count,
                                  "AP Response [24] ChallengeResponse(%s)",
                                  tvb_bytes_to_str(tvb, offset, count));
            } else {
-             proto_tree_add_text(eap_tree, tvb, offset, count, 
+             proto_tree_add_text(eap_tree, tvb, offset, count,
                                "Data (%d byte%s): \"%s\"",
                                count, plurality(count, "", "s"),
                                tvb_bytes_to_str(tvb, offset, count));
@@ -754,7 +756,7 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
          /* Name    (Length-(8+Count)) */
          namesize = eap_len - (8+count);
          if (tree) {
-           proto_tree_add_text(eap_tree, tvb, offset, namesize, 
+           proto_tree_add_text(eap_tree, tvb, offset, namesize,
                                "Name (%d byte%s): %s",
                                namesize, plurality(count, "", "s"),
                                tvb_format_text(tvb, offset, namesize));
@@ -768,7 +770,7 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
       **********************************************************************/
       default:
         if (tree) {
-         proto_tree_add_text(eap_tree, tvb, offset, size, 
+         proto_tree_add_text(eap_tree, tvb, offset, size,
                              "Type-Data (%d byte%s) Value: %s",
                              size, plurality(size, "", "s"),
                              tvb_bytes_to_str(tvb, offset, size));
@@ -801,8 +803,8 @@ void
 proto_register_eap(void)
 {
   static hf_register_info hf[] = {
-       { &hf_eap_code, { 
-               "Code", "eap.code", FT_UINT8, BASE_DEC, 
+       { &hf_eap_code, {
+               "Code", "eap.code", FT_UINT8, BASE_DEC,
                VALS(eap_code_vals), 0x0, "", HFILL }},
        { &hf_eap_identifier, {
                "Id", "eap.id", FT_UINT8, BASE_DEC,
@@ -810,22 +812,40 @@ proto_register_eap(void)
        { &hf_eap_len, {
                "Length", "eap.len", FT_UINT16, BASE_DEC,
                NULL, 0x0, "", HFILL }},
-       { &hf_eap_type, { 
-               "Type", "eap.type", FT_UINT8, BASE_DEC, 
+       { &hf_eap_type, {
+               "Type", "eap.type", FT_UINT8, BASE_DEC,
                VALS(eap_type_vals), 0x0, "", HFILL }},
-       { &hf_eap_type_nak, { 
-               "Desired Auth Type", "eap.type", FT_UINT8, BASE_DEC, 
+       { &hf_eap_type_nak, {
+               "Desired Auth Type", "eap.desired_type", FT_UINT8, BASE_DEC,
                VALS(eap_type_vals), 0x0, "", HFILL }},
        { &hf_eaptls_fragment,
-         { "EAP-TLS Fragment", "eaptls.fragment", 
-               FT_NONE, BASE_NONE, NULL, 0x0,
-               "EAP-TLS Fragment", HFILL }},
+         { "EAP-TLS Fragment", "eaptls.fragment",
+               FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+               "EAP-TLS Fragment", HFILL }},
        { &hf_eaptls_fragments,
-         { "EAP-TLS Fragments", "eaptls.fragments", 
+         { "EAP-TLS Fragments", "eaptls.fragments",
                FT_NONE, BASE_NONE, NULL, 0x0,
                "EAP-TLS Fragments", HFILL }},
-
-
+       { &hf_eaptls_fragment_overlap,
+         { "Fragment overlap", "eaptls.fragment.overlap",
+               FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+               "Fragment overlaps with other fragments", HFILL }},
+       { &hf_eaptls_fragment_overlap_conflict,
+         { "Conflicting data in fragment overlap",     "eaptls.fragment.overlap.conflict",
+               FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+               "Overlapping fragments contained conflicting data", HFILL }},
+       { &hf_eaptls_fragment_multiple_tails,
+         { "Multiple tail fragments found",    "eaptls.fragment.multipletails",
+               FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+               "Several tails were found when defragmenting the packet", HFILL }},
+       { &hf_eaptls_fragment_too_long_fragment,
+         { "Fragment too long",        "eaptls.fragment.toolongfragment",
+               FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+               "Fragment contained data past end of packet", HFILL }},
+       { &hf_eaptls_fragment_error,
+         { "Defragmentation error", "eaptls.fragment.error",
+               FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+               "Defragmentation error due to illegal fragments", HFILL }},
   };
   static gint *ett[] = {
        &ett_eap,
@@ -833,7 +853,7 @@ proto_register_eap(void)
        &ett_eaptls_fragments,
   };
 
-  proto_eap = proto_register_protocol("Extensible Authentication Protocol", 
+  proto_eap = proto_register_protocol("Extensible Authentication Protocol",
                                      "EAP", "eap");
   proto_register_field_array(proto_eap, hf, array_length(hf));
   proto_register_subtree_array(ett, array_length(ett));