2 * routines for sstp packet dissasembly
5 * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sstp
7 * Created as part of a semester project at the University of Applied Sciences Hagenberg
8 * (https://www.fh-ooe.at/en/hagenberg-campus/)
11 * Hofer Manuel (manuel@mnlhfr.at)
17 * SPDX-License-Identifier: GPL-2.0-or-later
23 #include <epan/packet.h>
24 #include "packet-tcp.h"
26 void proto_register_sstp(void);
27 void proto_reg_handoff_sstp(void);
29 #define SSTP_BITMASK_MAJORVERSION 0xF0
30 #define SSTP_BITMASK_MINORVERSION 0x0F
31 #define SSTP_BITMASK_CONTROLFLAG 0x01
32 #define SSTP_BITMASK_LENGTH_RESERVED 0xF000
33 #define SSTP_BITMASK_LENGTH_LENGTH 0x0FFF
34 #define SSTP_CERT_HASH_PROTOCOL_SHA1 0x01
35 #define SSTP_CERT_HASH_PROTOCOL_SHA256 0x02
36 #define SSTP_ENCAPSULATED_PPP 0x0001
38 /* bytewise offsets inside the packet buffer */
39 #define SSTP_OFFSET_ATTRIBUTES 8
40 #define SSTP_OFFSET_DATA 4
41 #define SSTP_OFFSET_RESERVED 1
42 #define SSTP_OFFSET_ISCONTROL 1
43 #define SSTP_OFFSET_LENGTH 2
44 #define SSTP_OFFSET_MAJORVERSION 0
45 #define SSTP_OFFSET_MINORVERSION 0
46 #define SSTP_OFFSET_MSGTYPE 4
47 #define SSTP_OFFSET_NUMATTRIB 6
49 /* fieldsize in byte */
50 #define SSTP_FSIZE_ATTRIBUTE 4
51 #define SSTP_FSIZE_ATTRIB_ID 1
52 #define SSTP_FSIZE_ATTRIB_LENGTH 2
53 #define SSTP_FSIZE_ATTRIB_RESERVED 1
54 #define SSTP_FSIZE_CERT_HASH_SHA1 20
55 #define SSTP_FSIZE_CERT_HASH_SHA256 32
56 #define SSTP_FSIZE_COMPOUND_MAC_SHA1 20
57 #define SSTP_FSIZE_COMPOUND_MAC_SHA256 32
58 #define SSTP_FSIZE_ENCAPSULATED_PROTOCOL 2
59 #define SSTP_FSIZE_HASH_PROTOCOL 1
60 #define SSTP_FSIZE_HASH_PROTOCOL_BITMASK 1
61 #define SSTP_FSIZE_ISCONTROL 1
62 #define SSTP_FSIZE_LENGTH 2
63 #define SSTP_FSIZE_MAJORVERSION 1
64 #define SSTP_FSIZE_MINORVERSION 1
65 #define SSTP_FSIZE_MSGTYPE 2
66 #define SSTP_FSIZE_NONCE 32
67 #define SSTP_FSIZE_NUMATTRIB 2
68 #define SSTP_FSIZE_PADDING_SHA1 12
69 #define SSTP_FSIZE_RESERVED 1
70 #define SSTP_FSIZE_RESERVED2 3
71 #define SSTP_FSIZE_STATUS 4
74 #define SSTP_MSG_CALL_ABORT 0x005
75 #define SSTP_MSG_CALL_CONNECTED 0x004
76 #define SSTP_MSG_CALL_CONNECT_ACK 0x002
77 #define SSTP_MSG_CALL_CONNECT_NAK 0x003
78 #define SSTP_MSG_CALL_CONNECT_REQUEST 0x001
79 #define SSTP_MSG_CALL_DISCONNECT 0x006
80 #define SSTP_MSG_CALL_DISCONNECT_ACK 0x007
81 #define SSTP_MSG_ECHO_REQUEST 0x008
82 #define SSTP_MSG_ECHO_RESPONSE 0x009
85 #define SSTP_ATTRIB_CRYPTO_BINDING 3
86 #define SSTP_ATTRIB_CRYPTO_BINDING_REQ 4
87 #define SSTP_ATTRIB_ENCAPSULATED_PROTOCOL_ID 1
88 #define SSTP_ATTRIB_NO_ERROR 0
89 #define SSTP_ATTRIB_STATUS_INFO 2
92 #define SSTP_ATTRIB_STATUS_ATTRIB_NOT_SUPPORTED_IN_MSG 0x000009
93 #define SSTP_ATTRIB_STATUS_DUPLICATE_ATTRIBUTE 0x000001
94 #define SSTP_ATTRIB_STATUS_INVALID_ATTRIB_VALUE_LENGTH 0x000003
95 #define SSTP_ATTRIB_STATUS_INVALID_FRAME_RECEIVED 0x000007
96 #define SSTP_ATTRIB_STATUS_NEGOTIATION_TIMEOUT 0x000008
97 #define SSTP_ATTRIB_STATUS_NO_ERROR 0x000000
98 #define SSTP_ATTRIB_STATUS_REQUIRED_ATTRIBUTE_MISSING 0x00000a
99 #define SSTP_ATTRIB_STATUS_RETRY_COUNT_EXCEEDED 0x000006
100 #define SSTP_ATTRIB_STATUS_STATUS_INFO_NOT_SUPPORTED_IN_MSG 0x00000b
101 #define SSTP_ATTRIB_STATUS_UNACCEPTED_FRAME_RECEIVED 0x000005
102 #define SSTP_ATTRIB_STATUS_UNRECOGNIZED_ATTRIBUTE 0x000002
103 #define SSTP_ATTRIB_STATUS_VALUE_NOT_SUPPORTED 0x000004
105 static dissector_handle_t ppp_hdlc_handle
;
107 static int ett_sstp_attribute
;
108 static int ett_sstp_version
;
109 static int hf_sstp_attrib_id
;
110 static int hf_sstp_attrib_length
;
111 static int hf_sstp_attrib_length_reserved
;
112 static int hf_sstp_attrib_reserved
;
113 static int hf_sstp_attrib_value
;
114 static int hf_sstp_cert_hash
;
115 static int hf_sstp_compound_mac
;
116 static int hf_sstp_control_flag
;
117 static int hf_sstp_data_unknown
;
118 static int hf_sstp_ecapsulated_protocol
;
119 static int hf_sstp_hash_protocol
;
120 static int hf_sstp_length
;
121 static int hf_sstp_major
;
122 static int hf_sstp_messagetype
;
123 static int hf_sstp_minor
;
124 static int hf_sstp_nonce
;
125 static int hf_sstp_numattrib
;
126 static int hf_sstp_padding
;
127 static int hf_sstp_reserved
;
128 static int hf_sstp_status
;
129 static int proto_sstp
;
131 static const value_string sstp_messagetypes
[] = {
132 {SSTP_MSG_CALL_CONNECT_REQUEST
, "SSTP_MSG_CALL_CONNECT_REQUEST"},
133 {SSTP_MSG_CALL_CONNECT_ACK
, "SSTP_MSG_CALL_CONNECT_ACK"},
134 {SSTP_MSG_CALL_CONNECT_NAK
, "SSTP_MSG_CALL_CONNECT_NAK"},
135 {SSTP_MSG_CALL_CONNECTED
, "SSTP_MSG_CALL_CONNECTED"},
136 {SSTP_MSG_CALL_ABORT
, "SSTP_MSG_CALL_ABORT"},
137 {SSTP_MSG_CALL_DISCONNECT
, "SSTP_MSG_CALL_DISCONNECT"},
138 {SSTP_MSG_CALL_DISCONNECT_ACK
, "SSTP_MSG_CALL_DISCONNECT_ACK"},
139 {SSTP_MSG_ECHO_REQUEST
, "SSTP_MSG_ECHO_REQUEST"},
140 {SSTP_MSG_ECHO_RESPONSE
, "SSTP_MSG_ECHO_RESPONSE"},
144 static const value_string sstp_attributes
[] = {
145 {SSTP_ATTRIB_NO_ERROR
, "SSTP_ATTRIB_NO_ERROR"},
146 {SSTP_ATTRIB_ENCAPSULATED_PROTOCOL_ID
, "SSTP_ATTRIB_ENCAPSULATED_PROTOCOL_ID"},
147 {SSTP_ATTRIB_STATUS_INFO
, "SSTP_ATTRIB_STATUS_INFO"},
148 {SSTP_ATTRIB_CRYPTO_BINDING
, "SSTP_ATTRIB_CRYPTO_BINDING"},
149 {SSTP_ATTRIB_CRYPTO_BINDING_REQ
, "SSTP_ATTRIB_CRYPTO_BINDING_REQ"},
153 static const value_string encapsulated_protocols
[] = {
154 {SSTP_ENCAPSULATED_PPP
, "PPP"},
158 static const value_string hash_protocols
[] = {
159 {SSTP_CERT_HASH_PROTOCOL_SHA1
, "SHA1"},
160 {SSTP_CERT_HASH_PROTOCOL_SHA256
, "SHA256"},
164 static const value_string attrib_status
[] = {
165 {SSTP_ATTRIB_STATUS_NO_ERROR
, "SSTP_ATTRIB_STATUS_NO_ERROR"},
166 {SSTP_ATTRIB_STATUS_DUPLICATE_ATTRIBUTE
, "SSTP_ATTRIB_STATUS_DUPLICATE_ATTRIBUTE"},
167 {SSTP_ATTRIB_STATUS_UNRECOGNIZED_ATTRIBUTE
, "SSTP_ATTRIB_STATUS_UNRECOGNIZED_ATTRIBUTE"},
168 {SSTP_ATTRIB_STATUS_INVALID_ATTRIB_VALUE_LENGTH
, "SSTP_ATTRIB_STATUS_INVALID_ATTRIB_VALUE_LENGTH"},
169 {SSTP_ATTRIB_STATUS_VALUE_NOT_SUPPORTED
, "SSTP_ATTRIB_STATUS_VALUE_NOT_SUPPORTED"},
170 {SSTP_ATTRIB_STATUS_UNACCEPTED_FRAME_RECEIVED
, "SSTP_ATTRIB_STATUS_UNACCEPTED_FRAME_RECEIVED"},
171 {SSTP_ATTRIB_STATUS_RETRY_COUNT_EXCEEDED
, "SSTP_ATTRIB_STATUS_RETRY_COUNT_EXCEEDED"},
172 {SSTP_ATTRIB_STATUS_INVALID_FRAME_RECEIVED
, "SSTP_ATTRIB_STATUS_INVALID_FRAME_RECEIVED"},
173 {SSTP_ATTRIB_STATUS_NEGOTIATION_TIMEOUT
, "SSTP_ATTRIB_STATUS_NEGOTIATION_TIMEOUT"},
174 {SSTP_ATTRIB_STATUS_ATTRIB_NOT_SUPPORTED_IN_MSG
, "SSTP_ATTRIB_STATUS_ATTRIB_NOT_SUPPORTED_IN_MSG"},
175 {SSTP_ATTRIB_STATUS_REQUIRED_ATTRIBUTE_MISSING
, "SSTP_ATTRIB_STATUS_REQUIRED_ATTRIBUTE_MISSING"},
176 {SSTP_ATTRIB_STATUS_STATUS_INFO_NOT_SUPPORTED_IN_MSG
, "SSTP_ATTRIB_STATUS_STATUS_INFO_NOT_SUPPORTED_IN_MSG"},
181 dissect_sstp_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
183 uint16_t sstp_control_flag
;
188 proto_tree
*sstp_tree
;
189 proto_tree
*sstp_tree_attribute
;
190 proto_tree
*sstp_tree_version
;
191 uint16_t sstp_numattrib
;
194 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "SSTP");
195 /* Clear out stuff in the info column */
196 col_clear(pinfo
->cinfo
, COL_INFO
);
198 ti
= proto_tree_add_item(tree
, proto_sstp
, tvb
, 0, -1, ENC_NA
);
199 sstp_tree
= proto_item_add_subtree(ti
, ett_sstp
);
201 sstp_control_flag
= tvb_get_uint8(tvb
, SSTP_OFFSET_ISCONTROL
) & SSTP_BITMASK_CONTROLFLAG
;
202 sstp_minor
= (tvb_get_uint8(tvb
, SSTP_OFFSET_MINORVERSION
) & SSTP_BITMASK_MINORVERSION
); /* leftmost 4 bit */
203 sstp_major
= (tvb_get_uint8(tvb
, SSTP_OFFSET_MAJORVERSION
) >> 4); /* rightmost 4 bit */
204 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "SSTP-%u.%u ", sstp_major
, sstp_minor
);
206 sstp_tree_version
= proto_tree_add_subtree_format(sstp_tree
, tvb
, offset
, SSTP_FSIZE_MAJORVERSION
, ett_sstp_version
,
207 NULL
, "Version %d.%d", sstp_major
, sstp_minor
);
208 proto_tree_add_item(sstp_tree_version
, hf_sstp_major
, tvb
, SSTP_OFFSET_MAJORVERSION
, SSTP_FSIZE_MAJORVERSION
, ENC_BIG_ENDIAN
);
209 proto_tree_add_item(sstp_tree_version
, hf_sstp_minor
, tvb
, SSTP_OFFSET_MINORVERSION
, SSTP_FSIZE_MINORVERSION
, ENC_BIG_ENDIAN
);
210 proto_tree_add_item(sstp_tree
, hf_sstp_reserved
, tvb
, SSTP_OFFSET_RESERVED
, SSTP_FSIZE_RESERVED
, ENC_NA
);
211 proto_tree_add_item(sstp_tree
, hf_sstp_control_flag
, tvb
, SSTP_OFFSET_ISCONTROL
, SSTP_FSIZE_ISCONTROL
, ENC_BIG_ENDIAN
);
212 proto_tree_add_item(sstp_tree
, hf_sstp_length
, tvb
, SSTP_OFFSET_LENGTH
, SSTP_FSIZE_LENGTH
, ENC_BIG_ENDIAN
);
214 /* check wether we got a control or data packet */
215 if (sstp_control_flag
) {
216 uint16_t sstp_messagetype
= tvb_get_uint16(tvb
, SSTP_OFFSET_MSGTYPE
, ENC_BIG_ENDIAN
);
218 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "Type: CONTROL, %s; ", val_to_str_const(sstp_messagetype
, sstp_messagetypes
, "Unknown Messagetype"));
219 proto_tree_add_item(sstp_tree
, hf_sstp_messagetype
, tvb
, SSTP_OFFSET_MSGTYPE
, SSTP_FSIZE_MSGTYPE
, ENC_BIG_ENDIAN
);
220 proto_tree_add_item(sstp_tree
, hf_sstp_numattrib
, tvb
, SSTP_OFFSET_NUMATTRIB
, SSTP_FSIZE_NUMATTRIB
, ENC_BIG_ENDIAN
);
221 sstp_numattrib
= tvb_get_ntohs(tvb
, SSTP_OFFSET_NUMATTRIB
);
223 /* display attributes */
224 if (sstp_numattrib
> 0) {
225 uint16_t attrib_length
= 0;
226 uint8_t attrib_id
= 0;
227 uint8_t hashproto
= 0;
228 offset
= SSTP_OFFSET_ATTRIBUTES
;
230 for(;sstp_numattrib
> 0; sstp_numattrib
--) {
231 /* read attribute id and create subtree for attribute */
232 attrib_id
= tvb_get_uint8(tvb
, offset
+1);
233 sstp_tree_attribute
= proto_tree_add_subtree_format(sstp_tree
, tvb
, offset
, SSTP_FSIZE_ATTRIB_RESERVED
, ett_sstp_attribute
,
234 NULL
, "Attribute %s", val_to_str_const(attrib_id
, sstp_attributes
, "Unknown Attribute"));
235 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_attrib_reserved
, tvb
, offset
, SSTP_FSIZE_ATTRIB_RESERVED
, ENC_BIG_ENDIAN
);
237 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_attrib_id
, tvb
, offset
, SSTP_FSIZE_ATTRIB_ID
, ENC_BIG_ENDIAN
);
239 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_attrib_length_reserved
, tvb
, offset
, SSTP_FSIZE_ATTRIB_LENGTH
, ENC_BIG_ENDIAN
);
240 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_attrib_length
, tvb
, offset
, SSTP_FSIZE_ATTRIB_LENGTH
, ENC_BIG_ENDIAN
);
242 /* get length of attribute value */
243 attrib_length
= (tvb_get_ntohs(tvb
, offset
) & SSTP_BITMASK_LENGTH_LENGTH
);
245 /* if this attribute follows the specification, length should at least be 4 */
246 if (attrib_length
>= 4) {
247 /* length field also contains the previously processed 4 bytes */
252 /* attributes that need special treatment... */
255 case SSTP_ATTRIB_ENCAPSULATED_PROTOCOL_ID
:
256 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_ecapsulated_protocol
, tvb
, offset
, SSTP_FSIZE_ENCAPSULATED_PROTOCOL
, ENC_BIG_ENDIAN
);
257 offset
+= SSTP_FSIZE_ENCAPSULATED_PROTOCOL
;
260 case SSTP_ATTRIB_STATUS_INFO
:
261 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_reserved
, tvb
, offset
, SSTP_FSIZE_RESERVED2
, ENC_NA
);
262 offset
+= SSTP_FSIZE_RESERVED2
;
263 attrib_length
-= SSTP_FSIZE_RESERVED2
;
264 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_attrib_id
, tvb
, offset
, SSTP_FSIZE_ATTRIB_ID
, ENC_BIG_ENDIAN
);
265 offset
+= SSTP_FSIZE_ATTRIB_ID
;
266 attrib_length
-= SSTP_FSIZE_ATTRIB_ID
;
267 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_status
, tvb
, offset
, SSTP_FSIZE_STATUS
, ENC_BIG_ENDIAN
);
268 offset
+= SSTP_FSIZE_STATUS
;
269 attrib_length
-= SSTP_FSIZE_STATUS
;
270 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_attrib_value
, tvb
, offset
, attrib_length
, ENC_NA
);
271 offset
+= attrib_length
;
274 case SSTP_ATTRIB_CRYPTO_BINDING
:
275 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_reserved
, tvb
, offset
, SSTP_FSIZE_RESERVED2
, ENC_NA
);
276 offset
+= SSTP_FSIZE_RESERVED2
;
277 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_hash_protocol
, tvb
, offset
, SSTP_FSIZE_HASH_PROTOCOL
, ENC_BIG_ENDIAN
);
278 hashproto
= tvb_get_uint8(tvb
, offset
);
279 offset
+= SSTP_FSIZE_HASH_PROTOCOL
;
280 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_nonce
, tvb
, offset
, SSTP_FSIZE_NONCE
, ENC_NA
);
281 offset
+= SSTP_FSIZE_NONCE
;
283 if (hashproto
== SSTP_CERT_HASH_PROTOCOL_SHA1
) {
284 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_cert_hash
, tvb
, offset
, SSTP_FSIZE_CERT_HASH_SHA1
, ENC_NA
);
285 offset
+= SSTP_FSIZE_CERT_HASH_SHA1
;
286 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_padding
, tvb
, offset
, SSTP_FSIZE_PADDING_SHA1
, ENC_NA
);
287 offset
+= SSTP_FSIZE_PADDING_SHA1
;
288 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_compound_mac
, tvb
, offset
, SSTP_FSIZE_COMPOUND_MAC_SHA1
, ENC_NA
);
289 offset
+= SSTP_FSIZE_COMPOUND_MAC_SHA1
;
290 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_padding
, tvb
, offset
, SSTP_FSIZE_PADDING_SHA1
, ENC_NA
);
291 offset
+= SSTP_FSIZE_PADDING_SHA1
;
294 if (hashproto
== SSTP_CERT_HASH_PROTOCOL_SHA256
) {
295 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_cert_hash
, tvb
, offset
, SSTP_FSIZE_CERT_HASH_SHA256
, ENC_NA
);
296 offset
+= SSTP_FSIZE_CERT_HASH_SHA256
;
300 case SSTP_ATTRIB_CRYPTO_BINDING_REQ
:
301 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_reserved
, tvb
, offset
, SSTP_FSIZE_RESERVED2
, ENC_NA
);
302 offset
+= SSTP_FSIZE_RESERVED2
;
303 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_hash_protocol
, tvb
, offset
, SSTP_FSIZE_HASH_PROTOCOL
, ENC_BIG_ENDIAN
);
304 offset
+= SSTP_FSIZE_HASH_PROTOCOL
;
305 proto_tree_add_item(sstp_tree_attribute
, hf_sstp_nonce
, tvb
, offset
, SSTP_FSIZE_NONCE
, ENC_NA
);
306 offset
+= SSTP_FSIZE_NONCE
;
312 /* While testing with different dumps, i noticed data in the buffer i couldnt find any documentation about */
313 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
314 proto_tree_add_item(sstp_tree
, hf_sstp_data_unknown
, tvb
, offset
, -1, ENC_NA
);
318 col_append_str(pinfo
->cinfo
, COL_INFO
, "Type: DATA; ");
319 /* our work here is done, since sstp encapsulates ppp, we hand the remaining buffer
320 over to the ppp dissector for further analysis */
321 tvb_next
= tvb_new_subset_remaining(tvb
, SSTP_OFFSET_DATA
);
322 call_dissector(ppp_hdlc_handle
, tvb_next
, pinfo
, tree
);
325 return tvb_captured_length(tvb
);
329 get_sstp_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
, void *data _U_
)
331 return tvb_get_ntohs(tvb
, offset
+SSTP_OFFSET_LENGTH
);
335 dissect_sstp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
337 tcp_dissect_pdus(tvb
, pinfo
, tree
, true, SSTP_OFFSET_LENGTH
+SSTP_FSIZE_LENGTH
, get_sstp_pdu_len
, dissect_sstp_pdu
, data
);
338 return tvb_captured_length(tvb
);
342 proto_register_sstp(void)
344 /* Setting up header data structure */
345 static hf_register_info hf
[] = {
346 /* sstp minor version (4 Bit) */
348 { "Major Version", "sstp.majorversion",
350 NULL
, SSTP_BITMASK_MAJORVERSION
,
353 /* sstp major version (4 Bit) */
355 { "Minor Version", "sstp.minorversion",
357 NULL
, SSTP_BITMASK_MINORVERSION
,
360 /* Several Reserved Fields with different size */
362 { "Reserved", "sstp.reserved",
367 /* C (1 Bit, set to 1 if control packet, 0 means data packet) */
368 { &hf_sstp_control_flag
,
369 { "Control Packet", "sstp.iscontrol",
371 NULL
, SSTP_BITMASK_CONTROLFLAG
,
374 /* Length Packet (16 Bit) */
376 { "Length-Packet", "sstp.length",
381 /* Message Type (16 Bit) */
382 { &hf_sstp_messagetype
,
383 { "Message Type", "sstp.messagetype",
385 VALS(sstp_messagetypes
), 0x0,
388 /* Number of Attributes (16 Bit) */
389 { &hf_sstp_numattrib
,
390 { "Number of Attributes", "sstp.numattrib",
395 /* Fields for Attributes */
396 /* Attribute Reserved Field (8 Bit) */
397 { &hf_sstp_attrib_reserved
,
398 { "Reserved", "sstp.attribreserved",
403 /* Attribute ID (8 Bit) */
404 { &hf_sstp_attrib_id
,
405 { "ID", "sstp.attribid",
407 VALS(sstp_attributes
), 0x0,
410 /* Attribute Length Reserved (4 Bit reserved for future use inside the 16 bit length field) */
411 { &hf_sstp_attrib_length_reserved
,
412 { "Reserved", "sstp.attriblengthreserved",
414 NULL
, SSTP_BITMASK_LENGTH_RESERVED
,
417 /* Attribute Length Actual Length (12 Bit) */
418 { &hf_sstp_attrib_length
,
419 { "Length", "sstp.attriblength",
421 NULL
, SSTP_BITMASK_LENGTH_LENGTH
,
424 /* Undocumented Data in SSTP_MSG_CALL_CONNECT_REQUEST
425 see also MS-SSTP section 2.2.9 "Call Connect Request Message
426 (SSTP_MSG_CALL_CONNECT_REQUEST)":
428 https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sstp/e73ced14-7bef-407b-a85b-a6f624324dd1
430 { &hf_sstp_data_unknown
,
431 { "Unknown Data", "sstp.dataunknown",
436 /* Hash Protocol (8 Bit) */
437 { &hf_sstp_hash_protocol
,
438 { "Hash Protocol", "sstp.hash",
440 VALS(hash_protocols
), 0x0,
443 /* Nonce (256 Bit) */
445 { "Nonce", "sstp.nonce",
450 /* Cert Hash (20 Bytes if SHA1 is used, 32 Bytes with SHA256) */
451 { &hf_sstp_cert_hash
,
452 { "Cert Hash", "sstp.cert_hash",
457 /* Cert Padding (0 Bytes if SHA256 is used, 12 Bytes with SHA1) */
459 { "Padding", "sstp.padding",
464 /* Compound MAC (20 Bytes if SHA1 is used, 32 Bytes with SHA1) */
465 { &hf_sstp_compound_mac
,
466 { "Compound Mac", "sstp.compoundmac",
471 /* Encapsulated Protocol (2 Bytes) */
472 { &hf_sstp_ecapsulated_protocol
,
473 { "Encapsulated Protocol", "sstp.encapsulatedprotocol",
475 VALS(encapsulated_protocols
), 0x0,
478 /* Attribute Status (4 Bytes) */
480 { "Status", "sstp.status",
482 VALS(attrib_status
), 0x0,
485 /* Attribute Value (Variable Length) */
486 { &hf_sstp_attrib_value
,
487 { "Attribute Value", "sstp.attribvalue",
494 /* Setup protocol subtree array */
495 static int *ett
[] = {
501 proto_sstp
= proto_register_protocol("Secure Socket Tunneling Protocol", "SSTP", "sstp");
503 register_dissector("sstp", dissect_sstp
, proto_sstp
);
504 proto_register_field_array(proto_sstp
, hf
, array_length(hf
));
505 proto_register_subtree_array(ett
, array_length(ett
));
509 proto_reg_handoff_sstp(void)
511 ppp_hdlc_handle
= find_dissector_add_dependency("ppp_hdlc", proto_sstp
);
515 * Editor modelines - https://www.wireshark.org/tools/modelines.html
520 * indent-tabs-mode: nil
523 * vi: set shiftwidth=2 tabstop=8 expandtab:
524 * :indentSize=2:tabSize=8:noTabs=true: