wireshark/epan/dissectors/packet-teap.c

734 lines
22 KiB
C

/* packet-teap.c
* Routines for TEAP (Tunnel Extensible Authentication Protocol)
* RFC 7170
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.h"
#include <stdio.h>
#include <epan/packet.h>
#include <epan/expert.h>
#include <epan/proto_data.h>
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, {
"Lifetime", "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:
*/