diff options
Diffstat (limited to 'epan/dissectors/packet-sstp.c')
-rw-r--r-- | epan/dissectors/packet-sstp.c | 525 |
1 files changed, 525 insertions, 0 deletions
diff --git a/epan/dissectors/packet-sstp.c b/epan/dissectors/packet-sstp.c new file mode 100644 index 00000000..a4efe981 --- /dev/null +++ b/epan/dissectors/packet-sstp.c @@ -0,0 +1,525 @@ +/* packet-sstp.c + * routines for sstp packet dissasembly + * - MS-SSTP: + * + * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sstp + * + * Created as part of a semester project at the University of Applied Sciences Hagenberg + * (https://www.fh-ooe.at/en/hagenberg-campus/) + * + * Copyright (c) 2013: + * Hofer Manuel (manuel@mnlhfr.at) + * Nemeth Franz + * Scheipner Alexander + * Stiftinger Thomas + * Werner Sebastian + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + + +#include "config.h" + +#include <epan/packet.h> +#include "packet-tcp.h" + +void proto_register_sstp(void); +void proto_reg_handoff_sstp(void); + +#define SSTP_BITMASK_MAJORVERSION 0xF0 +#define SSTP_BITMASK_MINORVERSION 0x0F +#define SSTP_BITMASK_CONTROLFLAG 0x01 +#define SSTP_BITMASK_LENGTH_RESERVED 0xF000 +#define SSTP_BITMASK_LENGTH_LENGTH 0x0FFF +#define SSTP_CERT_HASH_PROTOCOL_SHA1 0x01 +#define SSTP_CERT_HASH_PROTOCOL_SHA256 0x02 +#define SSTP_ENCAPSULATED_PPP 0x0001 + +/* bytewise offsets inside the paket buffer */ +#define SSTP_OFFSET_ATTRIBUTES 8 +#define SSTP_OFFSET_DATA 4 +#define SSTP_OFFSET_RESERVED 1 +#define SSTP_OFFSET_ISCONTROL 1 +#define SSTP_OFFSET_LENGTH 2 +#define SSTP_OFFSET_MAJORVERSION 0 +#define SSTP_OFFSET_MINORVERSION 0 +#define SSTP_OFFSET_MSGTYPE 4 +#define SSTP_OFFSET_NUMATTRIB 6 + +/* fieldsize in byte */ +#define SSTP_FSIZE_ATTRIBUTE 4 +#define SSTP_FSIZE_ATTRIB_ID 1 +#define SSTP_FSIZE_ATTRIB_LENGTH 2 +#define SSTP_FSIZE_ATTRIB_RESERVED 1 +#define SSTP_FSIZE_CERT_HASH_SHA1 20 +#define SSTP_FSIZE_CERT_HASH_SHA256 32 +#define SSTP_FSIZE_COMPOUND_MAC_SHA1 20 +#define SSTP_FSIZE_COMPOUND_MAC_SHA256 32 +#define SSTP_FSIZE_ENCAPSULATED_PROTOCOL 2 +#define SSTP_FSIZE_HASH_PROTOCOL 1 +#define SSTP_FSIZE_HASH_PROTOCOL_BITMASK 1 +#define SSTP_FSIZE_ISCONTROL 1 +#define SSTP_FSIZE_LENGTH 2 +#define SSTP_FSIZE_MAJORVERSION 1 +#define SSTP_FSIZE_MINORVERSION 1 +#define SSTP_FSIZE_MSGTYPE 2 +#define SSTP_FSIZE_NONCE 32 +#define SSTP_FSIZE_NUMATTRIB 2 +#define SSTP_FSIZE_PADDING_SHA1 12 +#define SSTP_FSIZE_RESERVED 1 +#define SSTP_FSIZE_RESERVED2 3 +#define SSTP_FSIZE_STATUS 4 + +/* Message types */ +#define SSTP_MSG_CALL_ABORT 0x005 +#define SSTP_MSG_CALL_CONNECTED 0x004 +#define SSTP_MSG_CALL_CONNECT_ACK 0x002 +#define SSTP_MSG_CALL_CONNECT_NAK 0x003 +#define SSTP_MSG_CALL_CONNECT_REQUEST 0x001 +#define SSTP_MSG_CALL_DISCONNECT 0x006 +#define SSTP_MSG_CALL_DISCONNECT_ACK 0x007 +#define SSTP_MSG_ECHO_REQUEST 0x008 +#define SSTP_MSG_ECHO_RESPONSE 0x009 + +/* Attribute Types */ +#define SSTP_ATTRIB_CRYPTO_BINDING 3 +#define SSTP_ATTRIB_CRYPTO_BINDING_REQ 4 +#define SSTP_ATTRIB_ENCAPSULATED_PROTOCOL_ID 1 +#define SSTP_ATTRIB_NO_ERROR 0 +#define SSTP_ATTRIB_STATUS_INFO 2 + +/* Status Types */ +#define SSTP_ATTRIB_STATUS_ATTRIB_NOT_SUPPORTED_IN_MSG 0x000009 +#define SSTP_ATTRIB_STATUS_DUPLICATE_ATTRIBUTE 0x000001 +#define SSTP_ATTRIB_STATUS_INVALID_ATTRIB_VALUE_LENGTH 0x000003 +#define SSTP_ATTRIB_STATUS_INVALID_FRAME_RECEIVED 0x000007 +#define SSTP_ATTRIB_STATUS_NEGOTIATION_TIMEOUT 0x000008 +#define SSTP_ATTRIB_STATUS_NO_ERROR 0x000000 +#define SSTP_ATTRIB_STATUS_REQUIRED_ATTRIBUTE_MISSING 0x00000a +#define SSTP_ATTRIB_STATUS_RETRY_COUNT_EXCEEDED 0x000006 +#define SSTP_ATTRIB_STATUS_STATUS_INFO_NOT_SUPPORTED_IN_MSG 0x00000b +#define SSTP_ATTRIB_STATUS_UNACCEPTED_FRAME_RECEIVED 0x000005 +#define SSTP_ATTRIB_STATUS_UNRECOGNIZED_ATTRIBUTE 0x000002 +#define SSTP_ATTRIB_STATUS_VALUE_NOT_SUPPORTED 0x000004 + +static dissector_handle_t ppp_hdlc_handle = NULL; +static gint ett_sstp = -1; +static gint ett_sstp_attribute = -1; +static gint ett_sstp_version = -1; +static gint hf_sstp_attrib_id = -1; +static gint hf_sstp_attrib_length = -1; +static gint hf_sstp_attrib_length_reserved = -1; +static gint hf_sstp_attrib_reserved = -1; +static gint hf_sstp_attrib_value = -1; +static gint hf_sstp_cert_hash = -1; +static gint hf_sstp_compound_mac = -1; +static gint hf_sstp_control_flag = -1; +static gint hf_sstp_data_unknown = -1; +static gint hf_sstp_ecapsulated_protocol = -1; +static gint hf_sstp_hash_protocol = -1; +static gint hf_sstp_length = -1; +static gint hf_sstp_major = -1; +static gint hf_sstp_messagetype = -1; +static gint hf_sstp_minor = -1; +static gint hf_sstp_nonce = -1; +static gint hf_sstp_numattrib = -1; +static gint hf_sstp_padding = -1; +static gint hf_sstp_reserved = -1; +static gint hf_sstp_status = -1; +static gint proto_sstp = -1; + +static const value_string sstp_messagetypes[] = { + {SSTP_MSG_CALL_CONNECT_REQUEST, "SSTP_MSG_CALL_CONNECT_REQUEST"}, + {SSTP_MSG_CALL_CONNECT_ACK, "SSTP_MSG_CALL_CONNECT_ACK"}, + {SSTP_MSG_CALL_CONNECT_NAK, "SSTP_MSG_CALL_CONNECT_NAK"}, + {SSTP_MSG_CALL_CONNECTED, "SSTP_MSG_CALL_CONNECTED"}, + {SSTP_MSG_CALL_ABORT, "SSTP_MSG_CALL_ABORT"}, + {SSTP_MSG_CALL_DISCONNECT, "SSTP_MSG_CALL_DISCONNECT"}, + {SSTP_MSG_CALL_DISCONNECT_ACK, "SSTP_MSG_CALL_DISCONNECT_ACK"}, + {SSTP_MSG_ECHO_REQUEST, "SSTP_MSG_ECHO_REQUEST"}, + {SSTP_MSG_ECHO_RESPONSE, "SSTP_MSG_ECHO_RESPONSE"}, + {0, NULL} +}; + +static const value_string sstp_attributes[] = { + {SSTP_ATTRIB_NO_ERROR, "SSTP_ATTRIB_NO_ERROR"}, + {SSTP_ATTRIB_ENCAPSULATED_PROTOCOL_ID, "SSTP_ATTRIB_ENCAPSULATED_PROTOCOL_ID"}, + {SSTP_ATTRIB_STATUS_INFO, "SSTP_ATTRIB_STATUS_INFO"}, + {SSTP_ATTRIB_CRYPTO_BINDING, "SSTP_ATTRIB_CRYPTO_BINDING"}, + {SSTP_ATTRIB_CRYPTO_BINDING_REQ, "SSTP_ATTRIB_CRYPTO_BINDING_REQ"}, + {0, NULL} +}; + +static const value_string encapsulated_protocols[] = { + {SSTP_ENCAPSULATED_PPP, "PPP"}, + {0, NULL} +}; + +static const value_string hash_protocols[] = { + {SSTP_CERT_HASH_PROTOCOL_SHA1, "SHA1"}, + {SSTP_CERT_HASH_PROTOCOL_SHA256, "SHA256"}, + {0, NULL} +}; + +static const value_string attrib_status[] = { + {SSTP_ATTRIB_STATUS_NO_ERROR, "SSTP_ATTRIB_STATUS_NO_ERROR"}, + {SSTP_ATTRIB_STATUS_DUPLICATE_ATTRIBUTE, "SSTP_ATTRIB_STATUS_DUPLICATE_ATTRIBUTE"}, + {SSTP_ATTRIB_STATUS_UNRECOGNIZED_ATTRIBUTE, "SSTP_ATTRIB_STATUS_UNRECOGNIZED_ATTRIBUTE"}, + {SSTP_ATTRIB_STATUS_INVALID_ATTRIB_VALUE_LENGTH , "SSTP_ATTRIB_STATUS_INVALID_ATTRIB_VALUE_LENGTH"}, + {SSTP_ATTRIB_STATUS_VALUE_NOT_SUPPORTED, "SSTP_ATTRIB_STATUS_VALUE_NOT_SUPPORTED"}, + {SSTP_ATTRIB_STATUS_UNACCEPTED_FRAME_RECEIVED, "SSTP_ATTRIB_STATUS_UNACCEPTED_FRAME_RECEIVED"}, + {SSTP_ATTRIB_STATUS_RETRY_COUNT_EXCEEDED, "SSTP_ATTRIB_STATUS_RETRY_COUNT_EXCEEDED"}, + {SSTP_ATTRIB_STATUS_INVALID_FRAME_RECEIVED, "SSTP_ATTRIB_STATUS_INVALID_FRAME_RECEIVED"}, + {SSTP_ATTRIB_STATUS_NEGOTIATION_TIMEOUT, "SSTP_ATTRIB_STATUS_NEGOTIATION_TIMEOUT"}, + {SSTP_ATTRIB_STATUS_ATTRIB_NOT_SUPPORTED_IN_MSG, "SSTP_ATTRIB_STATUS_ATTRIB_NOT_SUPPORTED_IN_MSG"}, + {SSTP_ATTRIB_STATUS_REQUIRED_ATTRIBUTE_MISSING, "SSTP_ATTRIB_STATUS_REQUIRED_ATTRIBUTE_MISSING"}, + {SSTP_ATTRIB_STATUS_STATUS_INFO_NOT_SUPPORTED_IN_MSG, "SSTP_ATTRIB_STATUS_STATUS_INFO_NOT_SUPPORTED_IN_MSG"}, + {0, NULL} +}; + +static int +dissect_sstp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) +{ + guint16 sstp_control_flag; + guint32 offset = 0; + guint8 sstp_major; + guint8 sstp_minor; + proto_item *ti; + proto_tree *sstp_tree; + proto_tree *sstp_tree_attribute; + proto_tree *sstp_tree_version; + guint16 sstp_numattrib; + tvbuff_t *tvb_next; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "SSTP"); + /* Clear out stuff in the info column */ + col_clear(pinfo->cinfo, COL_INFO); + + ti = proto_tree_add_item(tree, proto_sstp, tvb, 0, -1, ENC_NA); + sstp_tree = proto_item_add_subtree(ti, ett_sstp); + + sstp_control_flag = tvb_get_guint8(tvb, SSTP_OFFSET_ISCONTROL) & SSTP_BITMASK_CONTROLFLAG; + sstp_minor = (tvb_get_guint8(tvb, SSTP_OFFSET_MINORVERSION) & SSTP_BITMASK_MINORVERSION); /* leftmost 4 bit */ + sstp_major = (tvb_get_guint8(tvb, SSTP_OFFSET_MAJORVERSION) >> 4); /* rightmost 4 bit */ + col_append_fstr(pinfo->cinfo, COL_INFO, "SSTP-%u.%u ", sstp_major, sstp_minor); + + sstp_tree_version = proto_tree_add_subtree_format(sstp_tree, tvb, offset, SSTP_FSIZE_MAJORVERSION, ett_sstp_version, + NULL, "Version %d.%d", sstp_major, sstp_minor); + proto_tree_add_item(sstp_tree_version, hf_sstp_major, tvb, SSTP_OFFSET_MAJORVERSION, SSTP_FSIZE_MAJORVERSION, ENC_BIG_ENDIAN); + proto_tree_add_item(sstp_tree_version, hf_sstp_minor, tvb, SSTP_OFFSET_MINORVERSION, SSTP_FSIZE_MINORVERSION, ENC_BIG_ENDIAN); + proto_tree_add_item(sstp_tree, hf_sstp_reserved, tvb, SSTP_OFFSET_RESERVED, SSTP_FSIZE_RESERVED, ENC_NA); + proto_tree_add_item(sstp_tree, hf_sstp_control_flag, tvb, SSTP_OFFSET_ISCONTROL, SSTP_FSIZE_ISCONTROL, ENC_BIG_ENDIAN); + proto_tree_add_item(sstp_tree, hf_sstp_length, tvb, SSTP_OFFSET_LENGTH, SSTP_FSIZE_LENGTH, ENC_BIG_ENDIAN); + + /* check wether we got a control or data packet */ + if (sstp_control_flag) { + guint16 sstp_messagetype = tvb_get_guint16(tvb, SSTP_OFFSET_MSGTYPE, ENC_BIG_ENDIAN); + + col_append_fstr(pinfo->cinfo, COL_INFO, "Type: CONTROL, %s; ", val_to_str_const(sstp_messagetype, sstp_messagetypes, "Unknown Messagetype")); + proto_tree_add_item(sstp_tree, hf_sstp_messagetype, tvb, SSTP_OFFSET_MSGTYPE, SSTP_FSIZE_MSGTYPE, ENC_BIG_ENDIAN); + proto_tree_add_item(sstp_tree, hf_sstp_numattrib, tvb, SSTP_OFFSET_NUMATTRIB, SSTP_FSIZE_NUMATTRIB, ENC_BIG_ENDIAN); + sstp_numattrib = tvb_get_ntohs(tvb, SSTP_OFFSET_NUMATTRIB); + + /* display attributes */ + if (sstp_numattrib > 0) { + guint16 attrib_length = 0; + guint8 attrib_id = 0; + guint8 hashproto = 0; + offset = SSTP_OFFSET_ATTRIBUTES; + + for(;sstp_numattrib > 0; sstp_numattrib--) { + /* read attribute id and create subtree for attribute */ + attrib_id = tvb_get_guint8(tvb, offset+1); + sstp_tree_attribute = proto_tree_add_subtree_format(sstp_tree, tvb, offset, SSTP_FSIZE_ATTRIB_RESERVED, ett_sstp_attribute, + NULL, "Attribute %s", val_to_str_const(attrib_id, sstp_attributes, "Unknown Attribute")); + proto_tree_add_item(sstp_tree_attribute, hf_sstp_attrib_reserved, tvb, offset, SSTP_FSIZE_ATTRIB_RESERVED, ENC_BIG_ENDIAN); + offset++; + proto_tree_add_item(sstp_tree_attribute, hf_sstp_attrib_id, tvb, offset, SSTP_FSIZE_ATTRIB_ID, ENC_BIG_ENDIAN); + offset++; + proto_tree_add_item(sstp_tree_attribute, hf_sstp_attrib_length_reserved, tvb, offset, SSTP_FSIZE_ATTRIB_LENGTH, ENC_BIG_ENDIAN); + proto_tree_add_item(sstp_tree_attribute, hf_sstp_attrib_length, tvb, offset, SSTP_FSIZE_ATTRIB_LENGTH, ENC_BIG_ENDIAN); + + /* get length of attribute value */ + attrib_length = (tvb_get_ntohs(tvb, offset) & SSTP_BITMASK_LENGTH_LENGTH); + + /* if this attribute follows the specification, length should at least be 4 */ + if (attrib_length >= 4) { + /* length field also contains the previously processed 4 bytes */ + attrib_length -= 4; + } + offset += 2; + + /* attributes that need special treatment... */ + switch(attrib_id) { + + case SSTP_ATTRIB_ENCAPSULATED_PROTOCOL_ID: + proto_tree_add_item(sstp_tree_attribute, hf_sstp_ecapsulated_protocol, tvb, offset, SSTP_FSIZE_ENCAPSULATED_PROTOCOL, ENC_BIG_ENDIAN); + offset += SSTP_FSIZE_ENCAPSULATED_PROTOCOL; + break; + + case SSTP_ATTRIB_STATUS_INFO: + proto_tree_add_item(sstp_tree_attribute, hf_sstp_reserved, tvb, offset, SSTP_FSIZE_RESERVED2, ENC_NA); + offset += SSTP_FSIZE_RESERVED2; + attrib_length -= SSTP_FSIZE_RESERVED2; + proto_tree_add_item(sstp_tree_attribute, hf_sstp_attrib_id, tvb, offset, SSTP_FSIZE_ATTRIB_ID, ENC_BIG_ENDIAN); + offset += SSTP_FSIZE_ATTRIB_ID; + attrib_length -= SSTP_FSIZE_ATTRIB_ID; + proto_tree_add_item(sstp_tree_attribute, hf_sstp_status, tvb, offset, SSTP_FSIZE_STATUS, ENC_BIG_ENDIAN); + offset += SSTP_FSIZE_STATUS; + attrib_length -= SSTP_FSIZE_STATUS; + proto_tree_add_item(sstp_tree_attribute, hf_sstp_attrib_value, tvb, offset, attrib_length, ENC_NA); + offset += attrib_length; + break; + + case SSTP_ATTRIB_CRYPTO_BINDING: + proto_tree_add_item(sstp_tree_attribute, hf_sstp_reserved, tvb, offset, SSTP_FSIZE_RESERVED2, ENC_NA); + offset += SSTP_FSIZE_RESERVED2; + proto_tree_add_item(sstp_tree_attribute, hf_sstp_hash_protocol, tvb, offset, SSTP_FSIZE_HASH_PROTOCOL, ENC_BIG_ENDIAN); + hashproto = tvb_get_guint8(tvb, offset); + offset += SSTP_FSIZE_HASH_PROTOCOL; + proto_tree_add_item(sstp_tree_attribute, hf_sstp_nonce, tvb, offset, SSTP_FSIZE_NONCE, ENC_NA); + offset += SSTP_FSIZE_NONCE; + + if (hashproto == SSTP_CERT_HASH_PROTOCOL_SHA1) { + proto_tree_add_item(sstp_tree_attribute, hf_sstp_cert_hash, tvb, offset, SSTP_FSIZE_CERT_HASH_SHA1, ENC_NA); + offset += SSTP_FSIZE_CERT_HASH_SHA1; + proto_tree_add_item(sstp_tree_attribute, hf_sstp_padding, tvb, offset, SSTP_FSIZE_PADDING_SHA1, ENC_NA); + offset += SSTP_FSIZE_PADDING_SHA1; + proto_tree_add_item(sstp_tree_attribute, hf_sstp_compound_mac, tvb, offset, SSTP_FSIZE_COMPOUND_MAC_SHA1, ENC_NA); + offset += SSTP_FSIZE_COMPOUND_MAC_SHA1; + proto_tree_add_item(sstp_tree_attribute, hf_sstp_padding, tvb, offset, SSTP_FSIZE_PADDING_SHA1, ENC_NA); + offset += SSTP_FSIZE_PADDING_SHA1; + } + + if (hashproto == SSTP_CERT_HASH_PROTOCOL_SHA256) { + proto_tree_add_item(sstp_tree_attribute, hf_sstp_cert_hash, tvb, offset, SSTP_FSIZE_CERT_HASH_SHA256, ENC_NA); + offset += SSTP_FSIZE_CERT_HASH_SHA256; + } + break; + + case SSTP_ATTRIB_CRYPTO_BINDING_REQ: + proto_tree_add_item(sstp_tree_attribute, hf_sstp_reserved, tvb, offset, SSTP_FSIZE_RESERVED2, ENC_NA); + offset += SSTP_FSIZE_RESERVED2; + proto_tree_add_item(sstp_tree_attribute, hf_sstp_hash_protocol, tvb, offset, SSTP_FSIZE_HASH_PROTOCOL, ENC_BIG_ENDIAN); + offset += SSTP_FSIZE_HASH_PROTOCOL; + proto_tree_add_item(sstp_tree_attribute, hf_sstp_nonce, tvb, offset, SSTP_FSIZE_NONCE, ENC_NA); + offset += SSTP_FSIZE_NONCE; + break; + } + } + } + + /* While testing with different dumps, i noticed data in the buffer i couldnt find any documentation about */ + if (tvb_reported_length_remaining(tvb, offset) > 0) { + proto_tree_add_item(sstp_tree, hf_sstp_data_unknown, tvb, offset, -1, ENC_NA); + } + + } else { + col_append_fstr(pinfo->cinfo, COL_INFO, "Type: DATA; "); + /* our work here is done, since sstp encapsulates ppp, we hand the remaining buffer + over to the ppp dissector for further analysis */ + tvb_next = tvb_new_subset_remaining(tvb, SSTP_OFFSET_DATA); + call_dissector(ppp_hdlc_handle, tvb_next, pinfo, tree); + } + + return tvb_captured_length(tvb); +} + +static guint +get_sstp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) +{ + return tvb_get_ntohs(tvb, offset+SSTP_OFFSET_LENGTH); +} + +static int +dissect_sstp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) +{ + tcp_dissect_pdus(tvb, pinfo, tree, TRUE, SSTP_OFFSET_LENGTH+SSTP_FSIZE_LENGTH, get_sstp_pdu_len, dissect_sstp_pdu, data); + return tvb_captured_length(tvb); +} + +void +proto_register_sstp(void) +{ + /* Setting up header data structure */ + static hf_register_info hf[] = { + /* sstp minor version (4 Bit) */ + { &hf_sstp_major, + { "Major Version", "sstp.majorversion", + FT_UINT8, BASE_DEC, + NULL, SSTP_BITMASK_MAJORVERSION, + NULL, HFILL } + }, + /* sstp major version (4 Bit) */ + { &hf_sstp_minor, + { "Minor Version", "sstp.minorversion", + FT_UINT8, BASE_DEC, + NULL, SSTP_BITMASK_MINORVERSION, + NULL, HFILL } + }, + /* Several Reserved Fields with different size */ + { &hf_sstp_reserved, + { "Reserved", "sstp.reserved", + FT_BYTES, BASE_NONE, + NULL, 0x0, + NULL, HFILL } + }, + /* C (1 Bit, set to 1 if control packet, 0 means data packet) */ + { &hf_sstp_control_flag, + { "Control Packet", "sstp.iscontrol", + FT_BOOLEAN, 8, + NULL, SSTP_BITMASK_CONTROLFLAG, + NULL, HFILL } + }, + /* Length Packet (16 Bit) */ + { &hf_sstp_length, + { "Length-Packet", "sstp.length", + FT_UINT16, BASE_DEC, + NULL, 0x0, + NULL, HFILL } + }, + /* Message Type (16 Bit) */ + { &hf_sstp_messagetype, + { "Message Type", "sstp.messagetype", + FT_UINT16, BASE_HEX, + VALS(sstp_messagetypes), 0x0, + NULL, HFILL } + }, + /* Number of Attributes (16 Bit) */ + { &hf_sstp_numattrib, + { "Number of Attributes", "sstp.numattrib", + FT_UINT16, BASE_DEC, + NULL, 0x0, + NULL, HFILL } + }, + /* Fields for Attributes */ + /* Attribute Reserved Field (8 Bit) */ + { &hf_sstp_attrib_reserved, + { "Reserved", "sstp.attribreserved", + FT_UINT8, BASE_HEX, + NULL, 0x0, + NULL, HFILL } + }, + /* Attribute ID (8 Bit) */ + { &hf_sstp_attrib_id, + { "ID", "sstp.attribid", + FT_UINT8, BASE_DEC, + VALS(sstp_attributes), 0x0, + NULL, HFILL } + }, + /* Attribute Length Reserved (4 Bit reserved for future use inside the 16 bit length field) */ + { &hf_sstp_attrib_length_reserved, + { "Reserved", "sstp.attriblengthreserved", + FT_UINT16, BASE_HEX, + NULL, SSTP_BITMASK_LENGTH_RESERVED, + NULL, HFILL } + }, + /* Attribute Length Actual Length (12 Bit) */ + { &hf_sstp_attrib_length, + { "Length", "sstp.attriblength", + FT_UINT16, BASE_DEC, + NULL, SSTP_BITMASK_LENGTH_LENGTH, + NULL, HFILL } + }, + /* Undocumented Data in SSTP_MSG_CALL_CONNECT_REQUEST + see also MS-SSTP section 2.2.9 "Call Connect Request Message + (SSTP_MSG_CALL_CONNECT_REQUEST)": + + https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sstp/e73ced14-7bef-407b-a85b-a6f624324dd1 + */ + { &hf_sstp_data_unknown, + { "Unknown Data", "sstp.dataunknown", + FT_BYTES, BASE_NONE, + NULL, 0x0, + NULL, HFILL } + }, + /* Hash Protocol (8 Bit) */ + { &hf_sstp_hash_protocol, + { "Hash Protocol", "sstp.hash", + FT_UINT8, BASE_HEX, + VALS(hash_protocols), 0x0, + NULL, HFILL } + }, + /* Nonce (256 Bit) */ + { &hf_sstp_nonce, + { "Nonce", "sstp.nonce", + FT_BYTES, BASE_NONE, + NULL, 0x0, + NULL, HFILL } + }, + /* Cert Hash (20 Bytes if SHA1 is used, 32 Bytes with SHA256) */ + { &hf_sstp_cert_hash, + { "Cert Hash", "sstp.cert_hash", + FT_BYTES, BASE_NONE, + NULL, 0x0, + NULL, HFILL } + }, + /* Cert Padding (0 Bytes if SHA256 is used, 12 Bytes with SHA1) */ + { &hf_sstp_padding, + { "Padding", "sstp.padding", + FT_BYTES, BASE_NONE, + NULL, 0x0, + NULL, HFILL } + }, + /* Compound MAC (20 Bytes if SHA1 is used, 32 Bytes with SHA1) */ + { &hf_sstp_compound_mac, + { "Compound Mac", "sstp.compoundmac", + FT_BYTES, BASE_NONE, + NULL, 0x0, + NULL, HFILL } + }, + /* Encapsulated Protocol (2 Bytes) */ + { &hf_sstp_ecapsulated_protocol, + { "Encapsulated Protocol", "sstp.encapsulatedprotocol", + FT_UINT16, BASE_HEX, + VALS(encapsulated_protocols), 0x0, + NULL, HFILL } + }, + /* Attribute Status (4 Bytes) */ + { &hf_sstp_status, + { "Status", "sstp.status", + FT_UINT32, BASE_HEX, + VALS(attrib_status), 0x0, + NULL, HFILL } + }, + /* Attribute Value (Variable Length) */ + { &hf_sstp_attrib_value, + { "Attribute Value", "sstp.attribvalue", + FT_BYTES, BASE_NONE, + NULL, 0x0, + NULL, HFILL } + } + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_sstp, + &ett_sstp_attribute, + &ett_sstp_version + }; + + proto_sstp = proto_register_protocol("Secure Socket Tunneling Protocol", "SSTP", "sstp"); + + register_dissector("sstp", dissect_sstp, proto_sstp); + proto_register_field_array(proto_sstp, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +void +proto_reg_handoff_sstp(void) +{ + ppp_hdlc_handle = find_dissector_add_dependency("ppp_hdlc", proto_sstp); +} + +/* +* Editor modelines - https://www.wireshark.org/tools/modelines.html +* +* Local variables: +* c-basic-offset: 2 +* tab-width: 8 +* indent-tabs-mode: nil +* End: +* +* vi: set shiftwidth=2 tabstop=8 expandtab: +* :indentSize=2:tabSize=8:noTabs=true: +*/ |