diff --git a/docbook/release-notes.adoc b/docbook/release-notes.adoc index 7353d6deab..3efc078cb0 100644 --- a/docbook/release-notes.adoc +++ b/docbook/release-notes.adoc @@ -59,6 +59,7 @@ since version 3.2.0: Cisco MisCabling Protocol (MCP) OBSAI UDP-based Communication Protocol (UDPCP) AudioCodes Debug Recording (ACDR) +Tunnel Extensible Authentication Protocol (TEAP) -- === Updated Protocol Support diff --git a/epan/dissectors/CMakeLists.txt b/epan/dissectors/CMakeLists.txt index fcef86f9b9..4f329de0a5 100644 --- a/epan/dissectors/CMakeLists.txt +++ b/epan/dissectors/CMakeLists.txt @@ -1780,6 +1780,7 @@ set(DISSECTOR_SRC ${CMAKE_CURRENT_SOURCE_DIR}/packet-tdmoe.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-tdmop.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-tds.c + ${CMAKE_CURRENT_SOURCE_DIR}/packet-teap.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-teamspeak2.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-teimanagement.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-teklink.c diff --git a/epan/dissectors/packet-eap.c b/epan/dissectors/packet-eap.c index 8c9bfe1ce2..792abb4685 100644 --- a/epan/dissectors/packet-eap.c +++ b/epan/dissectors/packet-eap.c @@ -107,6 +107,7 @@ static dissector_handle_t eap_handle; static dissector_handle_t tls_handle; static dissector_handle_t diameter_avps_handle; +static dissector_handle_t teap_handle; const value_string eap_code_vals[] = { { EAP_REQUEST, "Request" }, @@ -1205,6 +1206,9 @@ dissect_eap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) case EAP_TYPE_PEAP: tls_set_appdata_dissector(tls_handle, pinfo, eap_handle); break; + case EAP_TYPE_TEAP: + tls_set_appdata_dissector(tls_handle, pinfo, teap_handle); + break; } call_dissector(tls_handle, next_tvb, pinfo, eap_tree); } @@ -1763,6 +1767,7 @@ proto_reg_handoff_eap(void) */ tls_handle = find_dissector_add_dependency("tls", proto_eap); diameter_avps_handle = find_dissector_add_dependency("diameter_avps", proto_eap); + teap_handle = find_dissector_add_dependency("teap", proto_eap); dissector_add_uint("ppp.protocol", PPP_EAP, eap_handle); dissector_add_uint("eapol.type", EAPOL_EAP, eap_handle); diff --git a/epan/dissectors/packet-teap.c b/epan/dissectors/packet-teap.c new file mode 100644 index 0000000000..daf5b7caf4 --- /dev/null +++ b/epan/dissectors/packet-teap.c @@ -0,0 +1,733 @@ +/* packet-teap.c + * Routines for TEAP (Tunnel Extensible Authentication Protocol) + * RFC 7170 + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +#include + +#include +#include +#include + +void proto_register_teap(void); +void proto_reg_handoff_teap(void); + +static int proto_teap = -1; + +static gint ett_teap = -1; +static gint ett_teap_tlv = -1; +static gint ett_pac_attr_tlv = -1; + +static expert_field ei_teap_bad_length = EI_INIT; + +static dissector_handle_t teap_handle; + +static dissector_handle_t eap_handle; + +/* + From RFC7170, pg 27 + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |M|R| TLV Type | Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Value... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + +#define TEAP_TLV_MANDATORY 0x8000 +#define TEAP_TLV_RESERVED 0x4000 +#define TEAP_TLV_TYPE 0x3FFF + +#define TEAP_CRYPTO_FLAGS 0xF0 +#define TEAP_CRYPTO_SUBTYPE 0x0F + +#define TEAP_UNASSIGNED 0 +#define TEAP_AUTHORITY_ID 1 +#define TEAP_IDENTITY 2 +#define TEAP_RESULT 3 +#define TEAP_NAK 4 +#define TEAP_ERROR 5 +#define TEAP_CHANNEL_BINDING 6 +#define TEAP_VENDOR_SPECIFIC 7 +#define TEAP_REQUEST_ACTION 8 +#define TEAP_EAP_PAYLOAD 9 +#define TEAP_INTERMEDIATE_RESULT 10 +#define TEAP_PAC 11 +#define TEAP_CRYPTO_BINDING 12 +#define TEAP_BASIC_PWD_AUTH_REQUEST 13 +#define TEAP_BASIC_PWD_AUTH_RESPONSE 14 +#define TEAP_PKCS7 15 +#define TEAP_PKCS10 16 +#define TEAP_TRUSTED_SERVER_ROOT 17 + +static const value_string teap_tlv_type_vals[] = { + { TEAP_UNASSIGNED, "Unassigned" }, + { TEAP_AUTHORITY_ID, "Authority-ID" }, + { TEAP_IDENTITY, "Identity-Type" }, + { TEAP_RESULT, "Result" }, + { TEAP_NAK, "NAK" }, + { TEAP_ERROR, "Error" }, + { TEAP_CHANNEL_BINDING, "Channel-Binding" }, + { TEAP_VENDOR_SPECIFIC, "Vendor-Specific" }, + { TEAP_REQUEST_ACTION, "Request-Action" }, + { TEAP_EAP_PAYLOAD, "EAP-Payload" }, + { TEAP_INTERMEDIATE_RESULT, "Intermediate-Result" }, + { TEAP_PAC, "PAC" }, + { TEAP_CRYPTO_BINDING, "Crypto-Binding" }, + { TEAP_BASIC_PWD_AUTH_REQUEST, "Basic-Password-Auth-Req" }, + { TEAP_BASIC_PWD_AUTH_RESPONSE, "Basic-Password-Auth-Resp" }, + { TEAP_PKCS7, "PKCS#7" }, + { TEAP_PKCS10, "PKCS#10" }, + { TEAP_TRUSTED_SERVER_ROOT, "Trusted-Server-Root" }, + { 0, NULL } + }; + +static const value_string teap_identity_vals[] = { + { 1, "User" }, + { 2, "Machine" }, + { 0, NULL } + }; + +static const value_string teap_status_vals[] = { + { 1, "Success" }, + { 2, "Failure" }, + { 0, NULL } + }; + + #define FLAG_EMSK_PRESENT 1 + #define FLAG_MSK_PRESENT 2 + #define FLAG_BOTH_PRESENT 3 + +static const value_string teap_crypto_flags_vals[] = { + { FLAG_EMSK_PRESENT, "EMSK Compound MAC is present" }, + { FLAG_MSK_PRESENT, "MSK Compound MAC is present" }, + { FLAG_BOTH_PRESENT, "Both EMSK and MSK Compound MAC are present" }, + { 0, NULL } +}; + +static const value_string teap_crypto_subtype_vals[] = { + { 0, "Binding Request" }, + { 1, "Binding Response" }, + { 0, NULL } +}; + +static const value_string teap_error_code_vals[] = { + { 1, "User account expires soon" }, + { 2, "User account credential expires soon" }, + { 3, "User account authorizations change soon" }, + { 4, "Clock skew detected" }, + { 5, "Contact administrator" }, + { 6, "User account credentials change required" }, + { 1001, "Inner Method Error" }, + { 1002, "Unspecified authentication infrastructure problem" }, + { 1003, "Unspecified authentication failure" }, + { 1004, "Unspecified authorization failure" }, + { 1005, "User account credentials unavailable" }, + { 1006, "User account expired" }, + { 1007, "User account locked: try again later" }, + { 1008, "User account locked: admin intervention required" }, + { 1009, "Authentication infrastructure unavailable" }, + { 1010, "Authentication infrastructure not trusted" }, + { 1011, "Clock skew too great" }, + { 1012, "Invalid inner realm" }, + { 1013, "Token out of sync: administrator intervention required" }, + { 1014, "Token out of sync: PIN change required" }, + { 1015, "Token revoked" }, + { 1016, "Tokens exhausted" }, + { 1017, "Challenge expired" }, + { 1018, "Challenge algorithm mismatch" }, + { 1019, "Client certificate not supplied" }, + { 1020, "Client certificate rejected" }, + { 1021, "Realm mismatch between inner and outer identity" }, + { 1022, "Unsupported Algorithm In Certificate Signing Request" }, + { 1023, "Unsupported Extension In Certificate Signing Request" }, + { 1024, "Bad Identity In Certificate Signing Request" }, + { 1025, "Bad Certificate Signing Request" }, + { 1026, "Internal CA Error" }, + { 1027, "General PKI Error" }, + { 1028, "Inner method's channel-binding data required but not supplied" }, + { 1029, "Inner method's channel-binding data did not include required information" }, + { 1030, "Inner method's channel binding failed" }, + { 1031, "User account credentials incorrect [USAGE NOT RECOMMENDED]" }, + { 2001, "Tunnel Compromise Error" }, + { 2002, "Unexpected TLVs Exchanged" }, + { 0, NULL } +}; + +static const value_string teap_action_vals[] = { + { 1, "Process-TLV" }, + { 2, "Negotiate-EAP" }, + { 0, NULL } + }; + +#define PAC_KEY 1 +#define PAC_OPAQUE 2 +#define PAC_LIFETIME 3 +#define PAC_A_ID 4 +#define PAC_I_ID 5 +#define PAC_RESERVED 6 +#define PAC_A_ID_INFO 7 +#define PAC_ACK 8 +#define PAC_INFO 9 +#define PAC_TYPE 10 + +static const value_string pac_attr_type_vals[] = { + { PAC_KEY, "PAC-Key" }, + { PAC_OPAQUE, "PAC-Opaque" }, + { PAC_LIFETIME, "PAC-Lifetime" }, + { PAC_A_ID, "A-ID" }, + { PAC_I_ID, "I-ID" }, + { PAC_RESERVED, "Reserved" }, + { PAC_A_ID_INFO, "A-ID-Info" }, + { PAC_ACK, "PAC-Acknowledgement" }, + { PAC_INFO, "PAC-Info" }, + { PAC_TYPE, "PAC-Type" }, + { 0, NULL } +}; + +static const value_string pac_result_vals[] = { + { 1, "Success" }, + { 2, "Failure" }, + { 0, NULL } + }; + +static const value_string pac_type_vals[] = { + { 1, "Tunnel PAC" }, + { 0, NULL } + }; + +static int hf_teap_tlv_mandatory = -1; +static int hf_teap_tlv_reserved = -1; +static int hf_teap_tlv_type = -1; +static int hf_teap_tlv_len = -1; +static int hf_teap_tlv_val = -1; +static int hf_teap_auth_id = -1; +static int hf_teap_identity = -1; +static int hf_teap_status = -1; +static int hf_teap_vendor_id = -1; +static int hf_teap_crypto_reserved = -1; +static int hf_teap_crypto_version = -1; +static int hf_teap_crypto_rcv_version = -1; +static int hf_teap_crypto_flags = -1; +static int hf_teap_crypto_subtype = -1; +static int hf_teap_crypto_nonce = -1; +static int hf_teap_crypto_emsk = -1; +static int hf_teap_crypto_msk = -1; +static int hf_teap_nak_type = -1; +static int hf_teap_error_code = -1; +static int hf_teap_action = -1; +static int hf_teap_prompt = -1; +static int hf_teap_user_len = -1; +static int hf_teap_username = -1; +static int hf_teap_pass_len = -1; +static int hf_teap_password = -1; + +static int hf_pac_attr_type = -1; +static int hf_pac_attr_pac_key = -1; +static int hf_pac_attr_pac_opaque = -1; +static int hf_pac_attr_pac_lifetime = -1; +static int hf_pac_attr_pac_a_id = -1; +static int hf_pac_attr_pac_i_id = -1; +static int hf_pac_attr_pac_reserved = -1; +static int hf_pac_attr_pac_a_id_info = -1; +static int hf_pac_attr_pac_result = -1; +static int hf_pac_attr_pac_type = -1; +static int hf_pac_attr_val = -1; + +static int +dissect_teap_tlv_pac(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 len); + +static int +dissect_pac_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) +{ + guint16 type; + guint16 len; + int start_offset = offset; + + type = tvb_get_guint16(tvb, offset, ENC_BIG_ENDIAN); + len = tvb_get_guint16(tvb, offset + 2, ENC_BIG_ENDIAN); + + proto_tree_add_item(tree, hf_pac_attr_type, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + proto_tree_add_item(tree, hf_teap_tlv_len, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + switch (type) { + case PAC_KEY: + proto_tree_add_item(tree, hf_pac_attr_pac_key, tvb, offset, len, ENC_NA); + offset += len; + break; + + case PAC_OPAQUE: + proto_tree_add_item(tree, hf_pac_attr_pac_opaque, tvb, offset, len, ENC_NA); + offset += len; + break; + + case PAC_LIFETIME: + proto_tree_add_item(tree, hf_pac_attr_pac_lifetime, tvb, offset, 4, ENC_NA); + offset += 4; + break; + + case PAC_A_ID: + proto_tree_add_item(tree, hf_pac_attr_pac_a_id, tvb, offset, len, ENC_ASCII | ENC_NA); + offset += len; + break; + + case PAC_I_ID: + proto_tree_add_item(tree, hf_pac_attr_pac_i_id, tvb, offset, len, ENC_ASCII | ENC_NA); + offset += len; + break; + + case PAC_RESERVED: + proto_tree_add_item(tree, hf_pac_attr_pac_reserved, tvb, offset, len, ENC_NA); + offset += len; + break; + + case PAC_A_ID_INFO: + proto_tree_add_item(tree, hf_pac_attr_pac_a_id_info, tvb, offset, len, ENC_ASCII | ENC_NA); + offset += len; + break; + + case PAC_ACK: + proto_tree_add_item(tree, hf_pac_attr_pac_result, tvb, offset, len, ENC_NA); + offset += len; + break; + + case PAC_INFO: + offset += dissect_teap_tlv_pac(tvb, pinfo, tree, offset, len); + break; + + case PAC_TYPE: + proto_tree_add_item(tree, hf_pac_attr_pac_type, tvb, offset, len, ENC_NA); + offset += len; + break; + + default: + proto_tree_add_item(tree, hf_pac_attr_val, tvb, offset, len, ENC_NA); + offset += len; + break; + } + return offset - start_offset; +} + +static int +dissect_teap_tlv_pac(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 len) +{ + int start_offset = offset; + + while (offset - start_offset < len) { + offset += dissect_pac_attr(tvb, pinfo, tree, offset); + } + return offset - start_offset; +} + +static int +dissect_teap_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, gboolean top) +{ + int start_offset = offset; + guint16 type; + guint16 len; + proto_tree *tlv_tree; + proto_tree *ti_len; + tvbuff_t *next_tvb; + gboolean more_tlvs = FALSE; + + type = tvb_get_guint16(tvb, offset, ENC_BIG_ENDIAN) & TEAP_TLV_TYPE; + len = tvb_get_guint16(tvb, offset + 2, ENC_BIG_ENDIAN); + + tlv_tree = proto_tree_add_subtree_format(tree, tvb, offset, 4 + len, + ett_teap_tlv, NULL, "TLV %s (%u): ", + val_to_str_const(type, teap_tlv_type_vals, "Unknown"), type); + + proto_tree_add_item(tlv_tree, hf_teap_tlv_mandatory, tvb, offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(tlv_tree, hf_teap_tlv_reserved, tvb, offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(tlv_tree, hf_teap_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + proto_tree_add_item(tlv_tree, hf_teap_tlv_len, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + + if (top) { + col_add_str(pinfo->cinfo, COL_INFO, + val_to_str(type, teap_tlv_type_vals, "Unknown TLV (0x%02X)")); + } + switch (type) { + case TEAP_AUTHORITY_ID: + proto_tree_add_item(tlv_tree, hf_teap_auth_id, tvb, offset, len, ENC_NA); + offset += len; + break; + + case TEAP_IDENTITY: + proto_tree_add_item(tlv_tree, hf_teap_identity, tvb, 2, len, ENC_BIG_ENDIAN); + offset += 2; + break; + + case TEAP_RESULT: + proto_tree_add_item(tlv_tree, hf_teap_status, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + break; + + case TEAP_NAK: + proto_tree_add_item(tlv_tree, hf_teap_vendor_id, tvb, offset, 4, ENC_BIG_ENDIAN); + offset += 4; + proto_tree_add_item(tlv_tree, hf_teap_nak_type, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + more_tlvs = TRUE; + break; + + case TEAP_ERROR: + proto_tree_add_item(tlv_tree, hf_teap_error_code, tvb, offset, 4, ENC_BIG_ENDIAN); + offset += 4; + break; + + case TEAP_VENDOR_SPECIFIC: + proto_tree_add_item(tlv_tree, hf_teap_vendor_id, tvb, offset, 4, ENC_BIG_ENDIAN); + offset += 4; + more_tlvs = TRUE; + break; + + case TEAP_REQUEST_ACTION: + proto_tree_add_item(tlv_tree, hf_teap_status, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tlv_tree, hf_teap_action, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + more_tlvs = TRUE; + break; + + case TEAP_EAP_PAYLOAD: + next_tvb = tvb_new_subset_remaining(tvb, offset); + call_dissector(eap_handle, next_tvb, pinfo, tlv_tree); + // TODO parse more_tlvs + break; + + case TEAP_INTERMEDIATE_RESULT: + proto_tree_add_item(tlv_tree, hf_teap_status, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + more_tlvs = TRUE; + break; + + case TEAP_PAC: + offset += dissect_teap_tlv_pac(tvb, pinfo, tlv_tree, offset, len); + break; + + case TEAP_CRYPTO_BINDING: + { + guint8 flags; + proto_tree_add_item(tlv_tree, hf_teap_crypto_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tlv_tree, hf_teap_crypto_version, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tlv_tree, hf_teap_crypto_rcv_version, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + flags = (tvb_get_guint8(tvb, offset) & TEAP_CRYPTO_FLAGS) >> 4; + proto_tree_add_item(tlv_tree, hf_teap_crypto_flags, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tlv_tree, hf_teap_crypto_subtype, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tlv_tree, hf_teap_crypto_nonce, tvb, offset, 32, ENC_NA); + offset += 32; + if (flags == FLAG_EMSK_PRESENT || flags == FLAG_BOTH_PRESENT) { + proto_tree_add_item(tlv_tree, hf_teap_crypto_emsk, tvb, offset, 20, ENC_NA); + } + offset += 20; + if (flags == FLAG_MSK_PRESENT || flags == FLAG_BOTH_PRESENT) { + proto_tree_add_item(tlv_tree, hf_teap_crypto_msk, tvb, offset, 20, ENC_NA); + } + offset += 20; + } + break; + + case TEAP_BASIC_PWD_AUTH_REQUEST: + if (len > 0) { + proto_tree_add_item(tlv_tree, hf_teap_prompt, tvb, offset, len, ENC_ASCII | ENC_NA); + offset += len; + } + break; + + case TEAP_BASIC_PWD_AUTH_RESPONSE: + { + guint8 auth_len; + auth_len = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tlv_tree, hf_teap_user_len, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tlv_tree, hf_teap_username, tvb, offset, auth_len, ENC_ASCII | ENC_NA); + offset += auth_len; + + auth_len = tvb_get_guint8(tvb, offset); + proto_tree_add_item(tlv_tree, hf_teap_pass_len, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tlv_tree, hf_teap_password, tvb, offset, auth_len, ENC_ASCII | ENC_NA); + offset += auth_len; + } + break; + + case TEAP_CHANNEL_BINDING: + case TEAP_TRUSTED_SERVER_ROOT: + case TEAP_PKCS7: + case TEAP_PKCS10: + default: + ti_len = proto_tree_add_item(tlv_tree, hf_teap_tlv_val, tvb, offset, len, ENC_NA); + if ((guint)len + 4 > tvb_reported_length(tvb)) { + expert_add_info(pinfo, ti_len, &ei_teap_bad_length); + } + offset += len; + break; + } + + if (more_tlvs) { + while (offset < (int)tvb_captured_length(tvb)) { + offset += dissect_teap_tlv(tvb, pinfo, tlv_tree, offset, FALSE); + } + } + return offset - start_offset; +} + +static int +dissect_teap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) +{ + proto_tree *ti; + proto_tree *teap_tree; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "TEAP"); + col_clear(pinfo->cinfo, COL_INFO); + + ti = proto_tree_add_item(tree, proto_teap, tvb, 0, tvb_captured_length(tvb), ENC_NA); + teap_tree = proto_item_add_subtree(ti, ett_teap); + + dissect_teap_tlv(tvb, pinfo, teap_tree, 0, TRUE); + return tvb_captured_length(tvb); +} + +void +proto_register_teap(void) +{ + static hf_register_info hf[] = { + { &hf_teap_tlv_mandatory, { + "Mandatory", "teap.tlv.mandatory", + FT_BOOLEAN, 16, NULL, TEAP_TLV_MANDATORY, + NULL, HFILL }}, + + { &hf_teap_tlv_reserved, { + "Reserved", "teap.tlv.reserved", + FT_UINT16, BASE_DEC, NULL, TEAP_TLV_RESERVED, + NULL, HFILL }}, + + { &hf_teap_tlv_type, { + "Type", "teap.tlv.type", + FT_UINT16, BASE_DEC, VALS(teap_tlv_type_vals), TEAP_TLV_TYPE, + NULL, HFILL }}, + + { &hf_teap_tlv_len, { + "Length", "teap.tlv.len", + FT_UINT16, BASE_DEC, NULL, 0x00, + NULL, HFILL }}, + + { &hf_teap_auth_id, { + "ID", "teap.authority-id", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_teap_identity, { + "Identity", "teap.identity", + FT_UINT16, BASE_DEC, VALS(teap_identity_vals), 0x0, + NULL, HFILL }}, + + { &hf_teap_status, { + "Status", "teap.status", + FT_UINT16, BASE_DEC, VALS(teap_status_vals), 0x0, + NULL, HFILL }}, + + { &hf_teap_vendor_id, { + "Vendor-Id", "teap.vendor-id", + FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_teap_crypto_reserved, { + "Reserved", "teap.crypto.reserved", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_teap_crypto_version, { + "Version", "teap.crypto.version", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_teap_crypto_rcv_version, { + "Received Version", "teap.crypto.received-version", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_teap_crypto_flags, { + "Flags", "teap.crypto.flags", + FT_UINT8, BASE_DEC, VALS(teap_crypto_flags_vals), TEAP_CRYPTO_FLAGS, + NULL, HFILL }}, + + { &hf_teap_crypto_subtype, { + "Subtype", "teap.crypto.subtype", + FT_UINT8, BASE_DEC, VALS(teap_crypto_subtype_vals), TEAP_CRYPTO_SUBTYPE, + NULL, HFILL }}, + + { &hf_teap_crypto_nonce, { + "Nonce", "teap.crypto.nonce", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_teap_crypto_emsk, { + "EMSK Compound MAC", "teap.crypto.emsk", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_teap_crypto_msk, { + "MSK Compound MAC", "teap.crypto.msk", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_teap_nak_type, { + "NAK-Type", "teap.nak-type", + FT_UINT16, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_teap_error_code, { + "Error-Code", "teap.error-code", + FT_UINT32, BASE_DEC, VALS(teap_error_code_vals), 0x0, + NULL, HFILL }}, + + { &hf_teap_action, { + "Action", "teap.action", + FT_UINT8, BASE_DEC, VALS(teap_action_vals), 0x0, + NULL, HFILL }}, + + { &hf_teap_prompt, { + "Action", "teap.prompt", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_teap_user_len, { + "Userlen", "teap.user_len", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_teap_username, { + "Username", "teap.username", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_teap_pass_len, { + "Passlen", "teap.pass_len", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_teap_password, { + "Password", "teap.password", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_teap_tlv_val, { + "Value", "teap.tlv.val", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_pac_attr_type, { + "Type", "teap.pac.type", + FT_UINT16, BASE_DEC, VALS(pac_attr_type_vals), 0x0, + NULL, HFILL }}, + + { &hf_pac_attr_pac_key, { + "Key", "teap.pac.key", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_pac_attr_pac_opaque, { + "Opaque", "teap.pac.opaque", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_pac_attr_pac_lifetime, { + "Liftime", "teap.pac.lifetime", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_pac_attr_pac_a_id, { + "A-ID", "teap.pac.a-id", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_pac_attr_pac_i_id, { + "I-ID", "teap.pac.i-id", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_pac_attr_pac_reserved, { + "Reserved", "teap.pac.reserved", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_pac_attr_pac_a_id_info, { + "A-ID-Info", "teap.pac.a-id-info", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_pac_attr_pac_result, { + "Type", "teap.pac.result", + FT_UINT16, BASE_DEC, VALS(pac_result_vals), 0x0, + NULL, HFILL }}, + + { &hf_pac_attr_pac_type, { + "Type", "teap.pac.pac-type", + FT_UINT16, BASE_DEC, VALS(pac_type_vals), 0x0, + NULL, HFILL }}, + + { &hf_pac_attr_val, { + "Value", "teap.pac.val", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + }; + + static gint *ett[] = { + &ett_teap, + &ett_teap_tlv, + &ett_pac_attr_tlv, + }; + static ei_register_info ei[] = { + { &ei_teap_bad_length, { "teap.bad_length", PI_PROTOCOL, PI_WARN, "Bad length (too large)", EXPFILL }}, + }; + + expert_module_t* expert_teap; + + proto_teap = proto_register_protocol("Tunnel Extensible Authentication Protocol", + "TEAP", "teap"); + proto_register_field_array(proto_teap, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + expert_teap = expert_register_protocol(proto_teap); + expert_register_field_array(expert_teap, ei, array_length(ei)); + + teap_handle = register_dissector("teap", dissect_teap, proto_teap); +} + +void +proto_reg_handoff_teap(void) +{ + eap_handle = find_dissector_add_dependency("eap", proto_teap); +} +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 2 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=2 tabstop=8 expandtab: + * :indentSize=2:tabSize=8:noTabs=true: + */