Coverage Report

Created: 2026-08-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-sstp.c
Line
Count
Source
1
/* packet-sstp.c
2
 * routines for sstp packet disassembly
3
 * - MS-SSTP:
4
 *
5
 *    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sstp
6
 *
7
 * Created as part of a semester project at the University of Applied Sciences Hagenberg
8
 * (https://www.fh-ooe.at/en/hagenberg-campus/)
9
 *
10
 * Copyright (c) 2013:
11
 *   Hofer Manuel (manuel@mnlhfr.at)
12
 *   Nemeth Franz
13
 *   Scheipner Alexander
14
 *   Stiftinger Thomas
15
 *   Werner Sebastian
16
 *
17
 * SPDX-License-Identifier: GPL-2.0-or-later
18
 */
19
20
21
#include "config.h"
22
23
#include <epan/packet.h>
24
#include "packet-tcp.h"
25
26
void proto_register_sstp(void);
27
void proto_reg_handoff_sstp(void);
28
29
16
#define SSTP_BITMASK_MAJORVERSION 0xF0
30
16
#define SSTP_BITMASK_MINORVERSION 0x0F
31
16
#define SSTP_BITMASK_CONTROLFLAG 0x01
32
16
#define SSTP_BITMASK_LENGTH_RESERVED 0xF000
33
16
#define SSTP_BITMASK_LENGTH_LENGTH 0x0FFF
34
0
#define SSTP_CERT_HASH_PROTOCOL_SHA1 0x01
35
0
#define SSTP_CERT_HASH_PROTOCOL_SHA256 0x02
36
#define SSTP_ENCAPSULATED_PPP 0x0001
37
38
/* bytewise offsets inside the packet buffer */
39
0
#define SSTP_OFFSET_ATTRIBUTES    8
40
0
#define SSTP_OFFSET_DATA          4
41
0
#define SSTP_OFFSET_RESERVED      1
42
0
#define SSTP_OFFSET_ISCONTROL     1
43
0
#define SSTP_OFFSET_LENGTH        2
44
0
#define SSTP_OFFSET_MAJORVERSION  0
45
0
#define SSTP_OFFSET_MINORVERSION  0
46
0
#define SSTP_OFFSET_MSGTYPE       4
47
0
#define SSTP_OFFSET_NUMATTRIB     6
48
49
/* fieldsize in byte */
50
#define SSTP_FSIZE_ATTRIBUTE              4
51
0
#define SSTP_FSIZE_ATTRIB_ID              1
52
0
#define SSTP_FSIZE_ATTRIB_LENGTH          2
53
0
#define SSTP_FSIZE_ATTRIB_RESERVED        1
54
0
#define SSTP_FSIZE_CERT_HASH_SHA1         20
55
0
#define SSTP_FSIZE_CERT_HASH_SHA256       32
56
0
#define SSTP_FSIZE_COMPOUND_MAC_SHA1      20
57
#define SSTP_FSIZE_COMPOUND_MAC_SHA256    32
58
0
#define SSTP_FSIZE_ENCAPSULATED_PROTOCOL  2
59
0
#define SSTP_FSIZE_HASH_PROTOCOL          1
60
#define SSTP_FSIZE_HASH_PROTOCOL_BITMASK  1
61
0
#define SSTP_FSIZE_ISCONTROL              1
62
0
#define SSTP_FSIZE_LENGTH                 2
63
0
#define SSTP_FSIZE_MAJORVERSION           1
64
0
#define SSTP_FSIZE_MINORVERSION           1
65
0
#define SSTP_FSIZE_MSGTYPE                2
66
0
#define SSTP_FSIZE_NONCE                  32
67
0
#define SSTP_FSIZE_NUMATTRIB              2
68
0
#define SSTP_FSIZE_PADDING_SHA1           12
69
0
#define SSTP_FSIZE_RESERVED               1
70
0
#define SSTP_FSIZE_RESERVED2              3
71
0
#define SSTP_FSIZE_STATUS                 4
72
73
/* Message types */
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
83
84
/* Attribute Types */
85
0
#define SSTP_ATTRIB_CRYPTO_BINDING 3
86
0
#define SSTP_ATTRIB_CRYPTO_BINDING_REQ 4
87
0
#define SSTP_ATTRIB_ENCAPSULATED_PROTOCOL_ID 1
88
#define SSTP_ATTRIB_NO_ERROR 0
89
0
#define SSTP_ATTRIB_STATUS_INFO 2
90
91
/* Status Types */
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
104
105
static dissector_handle_t ppp_hdlc_handle;
106
static int ett_sstp;
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;
130
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"},
141
  {0, NULL}
142
};
143
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"},
150
  {0, NULL}
151
};
152
153
static const value_string encapsulated_protocols[] = {
154
  {SSTP_ENCAPSULATED_PPP, "PPP"},
155
  {0, NULL}
156
};
157
158
static const value_string hash_protocols[] = {
159
  {SSTP_CERT_HASH_PROTOCOL_SHA1, "SHA1"},
160
  {SSTP_CERT_HASH_PROTOCOL_SHA256, "SHA256"},
161
  {0, NULL}
162
};
163
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"},
177
  {0, NULL}
178
};
179
180
static int
181
dissect_sstp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
182
0
{
183
0
  uint16_t sstp_control_flag;
184
0
  uint32_t offset = 0;
185
0
  uint8_t sstp_major;
186
0
  uint8_t sstp_minor;
187
0
  proto_item *ti;
188
0
  proto_tree *sstp_tree;
189
0
  proto_tree *sstp_tree_attribute;
190
0
  proto_tree *sstp_tree_version;
191
0
  uint16_t sstp_numattrib;
192
0
  tvbuff_t *tvb_next;
193
194
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "SSTP");
195
  /* Clear out stuff in the info column */
196
0
  col_clear(pinfo->cinfo, COL_INFO);
197
198
0
  ti = proto_tree_add_item(tree, proto_sstp, tvb, 0, -1, ENC_NA);
199
0
  sstp_tree = proto_item_add_subtree(ti, ett_sstp);
200
201
0
  sstp_control_flag = tvb_get_uint8(tvb, SSTP_OFFSET_ISCONTROL) & SSTP_BITMASK_CONTROLFLAG;
202
0
  sstp_minor = (tvb_get_uint8(tvb, SSTP_OFFSET_MINORVERSION) & SSTP_BITMASK_MINORVERSION); /* leftmost 4 bit */
203
0
  sstp_major = (tvb_get_uint8(tvb, SSTP_OFFSET_MAJORVERSION) >> 4); /* rightmost 4 bit */
204
0
  col_append_fstr(pinfo->cinfo, COL_INFO, "SSTP-%u.%u ", sstp_major, sstp_minor);
205
206
0
  sstp_tree_version = proto_tree_add_subtree_format(sstp_tree, tvb, offset, SSTP_FSIZE_MAJORVERSION, ett_sstp_version,
207
0
      NULL, "Version %d.%d", sstp_major, sstp_minor);
208
0
  proto_tree_add_item(sstp_tree_version, hf_sstp_major, tvb, SSTP_OFFSET_MAJORVERSION, SSTP_FSIZE_MAJORVERSION, ENC_BIG_ENDIAN);
209
0
  proto_tree_add_item(sstp_tree_version, hf_sstp_minor, tvb, SSTP_OFFSET_MINORVERSION, SSTP_FSIZE_MINORVERSION, ENC_BIG_ENDIAN);
210
0
  proto_tree_add_item(sstp_tree, hf_sstp_reserved, tvb,      SSTP_OFFSET_RESERVED, SSTP_FSIZE_RESERVED, ENC_NA);
211
0
  proto_tree_add_item(sstp_tree, hf_sstp_control_flag, tvb,  SSTP_OFFSET_ISCONTROL, SSTP_FSIZE_ISCONTROL, ENC_BIG_ENDIAN);
212
0
  proto_tree_add_item(sstp_tree, hf_sstp_length, tvb,        SSTP_OFFSET_LENGTH, SSTP_FSIZE_LENGTH, ENC_BIG_ENDIAN);
213
214
  /* check wether we got a control or data packet */
215
0
  if (sstp_control_flag) {
216
0
    uint16_t sstp_messagetype = tvb_get_uint16(tvb, SSTP_OFFSET_MSGTYPE, ENC_BIG_ENDIAN);
217
218
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "Type: CONTROL, %s; ", val_to_str_const(sstp_messagetype, sstp_messagetypes, "Unknown Messagetype"));
219
0
    proto_tree_add_item(sstp_tree, hf_sstp_messagetype, tvb,  SSTP_OFFSET_MSGTYPE, SSTP_FSIZE_MSGTYPE, ENC_BIG_ENDIAN);
220
0
    proto_tree_add_item_ret_uint16(sstp_tree, hf_sstp_numattrib, tvb, SSTP_OFFSET_NUMATTRIB, SSTP_FSIZE_NUMATTRIB, ENC_BIG_ENDIAN, &sstp_numattrib);
221
222
    /* display attributes */
223
0
    if (sstp_numattrib > 0) {
224
0
      uint16_t attrib_length = 0;
225
0
      uint8_t attrib_id = 0;
226
0
      uint8_t hashproto = 0;
227
0
      offset = SSTP_OFFSET_ATTRIBUTES;
228
229
0
      for(;sstp_numattrib > 0; sstp_numattrib--) {
230
        /* read attribute id and create subtree for attribute */
231
0
        attrib_id = tvb_get_uint8(tvb, offset+1);
232
0
        sstp_tree_attribute = proto_tree_add_subtree_format(sstp_tree, tvb, offset, SSTP_FSIZE_ATTRIB_RESERVED, ett_sstp_attribute,
233
0
            NULL, "Attribute %s", val_to_str_const(attrib_id, sstp_attributes, "Unknown Attribute"));
234
0
        proto_tree_add_item(sstp_tree_attribute, hf_sstp_attrib_reserved, tvb, offset, SSTP_FSIZE_ATTRIB_RESERVED, ENC_BIG_ENDIAN);
235
0
        offset++;
236
0
        proto_tree_add_item(sstp_tree_attribute, hf_sstp_attrib_id, tvb, offset, SSTP_FSIZE_ATTRIB_ID, ENC_BIG_ENDIAN);
237
0
        offset++;
238
0
        proto_tree_add_item(sstp_tree_attribute, hf_sstp_attrib_length_reserved, tvb, offset, SSTP_FSIZE_ATTRIB_LENGTH, ENC_BIG_ENDIAN);
239
        /* length of attribute */
240
0
        proto_tree_add_item_ret_uint16(sstp_tree_attribute, hf_sstp_attrib_length, tvb, offset, SSTP_FSIZE_ATTRIB_LENGTH, ENC_BIG_ENDIAN, &attrib_length);
241
242
        /* if this attribute follows the specification, length should at least be 4 */
243
0
        if (attrib_length >= 4) {
244
          /* length field also contains the previously processed 4 bytes */
245
0
          attrib_length -= 4;
246
0
        }
247
0
        offset += 2;
248
249
        /* attributes that need special treatment... */
250
0
        switch(attrib_id) {
251
252
0
          case SSTP_ATTRIB_ENCAPSULATED_PROTOCOL_ID:
253
0
            proto_tree_add_item(sstp_tree_attribute, hf_sstp_ecapsulated_protocol, tvb, offset, SSTP_FSIZE_ENCAPSULATED_PROTOCOL, ENC_BIG_ENDIAN);
254
0
            offset += SSTP_FSIZE_ENCAPSULATED_PROTOCOL;
255
0
          break;
256
257
0
          case SSTP_ATTRIB_STATUS_INFO:
258
0
            proto_tree_add_item(sstp_tree_attribute, hf_sstp_reserved, tvb, offset, SSTP_FSIZE_RESERVED2, ENC_NA);
259
0
            offset += SSTP_FSIZE_RESERVED2;
260
0
            attrib_length -= SSTP_FSIZE_RESERVED2;
261
0
            proto_tree_add_item(sstp_tree_attribute, hf_sstp_attrib_id, tvb, offset, SSTP_FSIZE_ATTRIB_ID, ENC_BIG_ENDIAN);
262
0
            offset += SSTP_FSIZE_ATTRIB_ID;
263
0
            attrib_length -= SSTP_FSIZE_ATTRIB_ID;
264
0
            proto_tree_add_item(sstp_tree_attribute, hf_sstp_status, tvb, offset, SSTP_FSIZE_STATUS, ENC_BIG_ENDIAN);
265
0
            offset += SSTP_FSIZE_STATUS;
266
0
            attrib_length -= SSTP_FSIZE_STATUS;
267
0
            proto_tree_add_item(sstp_tree_attribute, hf_sstp_attrib_value, tvb, offset, attrib_length, ENC_NA);
268
0
            offset += attrib_length;
269
0
          break;
270
271
0
          case SSTP_ATTRIB_CRYPTO_BINDING:
272
0
            proto_tree_add_item(sstp_tree_attribute, hf_sstp_reserved, tvb, offset, SSTP_FSIZE_RESERVED2, ENC_NA);
273
0
            offset += SSTP_FSIZE_RESERVED2;
274
0
            proto_tree_add_item(sstp_tree_attribute, hf_sstp_hash_protocol, tvb, offset, SSTP_FSIZE_HASH_PROTOCOL, ENC_BIG_ENDIAN);
275
0
            hashproto = tvb_get_uint8(tvb, offset);
276
0
            offset += SSTP_FSIZE_HASH_PROTOCOL;
277
0
            proto_tree_add_item(sstp_tree_attribute, hf_sstp_nonce, tvb, offset, SSTP_FSIZE_NONCE, ENC_NA);
278
0
            offset += SSTP_FSIZE_NONCE;
279
280
0
            if (hashproto == SSTP_CERT_HASH_PROTOCOL_SHA1) {
281
0
              proto_tree_add_item(sstp_tree_attribute, hf_sstp_cert_hash, tvb, offset, SSTP_FSIZE_CERT_HASH_SHA1, ENC_NA);
282
0
              offset += SSTP_FSIZE_CERT_HASH_SHA1;
283
0
              proto_tree_add_item(sstp_tree_attribute, hf_sstp_padding, tvb, offset, SSTP_FSIZE_PADDING_SHA1, ENC_NA);
284
0
              offset += SSTP_FSIZE_PADDING_SHA1;
285
0
              proto_tree_add_item(sstp_tree_attribute, hf_sstp_compound_mac, tvb, offset, SSTP_FSIZE_COMPOUND_MAC_SHA1, ENC_NA);
286
0
              offset += SSTP_FSIZE_COMPOUND_MAC_SHA1;
287
0
              proto_tree_add_item(sstp_tree_attribute, hf_sstp_padding, tvb, offset, SSTP_FSIZE_PADDING_SHA1, ENC_NA);
288
0
              offset += SSTP_FSIZE_PADDING_SHA1;
289
0
            }
290
291
0
            if (hashproto == SSTP_CERT_HASH_PROTOCOL_SHA256) {
292
0
              proto_tree_add_item(sstp_tree_attribute, hf_sstp_cert_hash, tvb, offset, SSTP_FSIZE_CERT_HASH_SHA256, ENC_NA);
293
0
              offset += SSTP_FSIZE_CERT_HASH_SHA256;
294
0
            }
295
0
          break;
296
297
0
          case SSTP_ATTRIB_CRYPTO_BINDING_REQ:
298
0
            proto_tree_add_item(sstp_tree_attribute, hf_sstp_reserved, tvb, offset, SSTP_FSIZE_RESERVED2, ENC_NA);
299
0
            offset += SSTP_FSIZE_RESERVED2;
300
0
            proto_tree_add_item(sstp_tree_attribute, hf_sstp_hash_protocol, tvb, offset, SSTP_FSIZE_HASH_PROTOCOL, ENC_BIG_ENDIAN);
301
0
            offset += SSTP_FSIZE_HASH_PROTOCOL;
302
0
            proto_tree_add_item(sstp_tree_attribute, hf_sstp_nonce, tvb, offset, SSTP_FSIZE_NONCE, ENC_NA);
303
0
            offset += SSTP_FSIZE_NONCE;
304
0
          break;
305
0
        }
306
0
      }
307
0
    }
308
309
    /* While testing with different dumps, I noticed data in the buffer I couldn't find any documentation about */
310
0
    if (tvb_reported_length_remaining(tvb, offset) > 0) {
311
0
      proto_tree_add_item(sstp_tree, hf_sstp_data_unknown, tvb, offset, -1, ENC_NA);
312
0
    }
313
314
0
  } else {
315
0
    col_append_str(pinfo->cinfo, COL_INFO, "Type: DATA; ");
316
    /* our work here is done, since sstp encapsulates ppp, we hand the remaining buffer
317
       over to the ppp dissector for further analysis */
318
0
    tvb_next = tvb_new_subset_remaining(tvb, SSTP_OFFSET_DATA);
319
0
    call_dissector(ppp_hdlc_handle, tvb_next, pinfo, tree);
320
0
  }
321
322
0
  return tvb_captured_length(tvb);
323
0
}
324
325
static unsigned
326
get_sstp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
327
0
{
328
0
  return tvb_get_ntohs(tvb, offset+SSTP_OFFSET_LENGTH);
329
0
}
330
331
static int
332
dissect_sstp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
333
0
{
334
0
  tcp_dissect_pdus(tvb, pinfo, tree, true, SSTP_OFFSET_LENGTH+SSTP_FSIZE_LENGTH, get_sstp_pdu_len, dissect_sstp_pdu, data);
335
0
  return tvb_captured_length(tvb);
336
0
}
337
338
void
339
proto_register_sstp(void)
340
16
{
341
  /* Setting up header data structure */
342
16
  static hf_register_info hf[] = {
343
    /* sstp minor version (4 Bit) */
344
16
    { &hf_sstp_major,
345
16
      { "Major Version", "sstp.majorversion",
346
16
      FT_UINT8, BASE_DEC,
347
16
      NULL, SSTP_BITMASK_MAJORVERSION,
348
16
      NULL, HFILL }
349
16
    },
350
    /* sstp major version (4 Bit) */
351
16
    { &hf_sstp_minor,
352
16
      { "Minor Version", "sstp.minorversion",
353
16
      FT_UINT8, BASE_DEC,
354
16
      NULL, SSTP_BITMASK_MINORVERSION,
355
16
      NULL, HFILL }
356
16
    },
357
    /* Several Reserved Fields with different size */
358
16
    { &hf_sstp_reserved,
359
16
      { "Reserved", "sstp.reserved",
360
16
      FT_BYTES, BASE_NONE,
361
16
      NULL, 0x0,
362
16
      NULL, HFILL }
363
16
    },
364
    /* C (1 Bit, set to 1 if control packet, 0 means data packet) */
365
16
    { &hf_sstp_control_flag,
366
16
      { "Control Packet", "sstp.iscontrol",
367
16
      FT_BOOLEAN, 8,
368
16
      NULL, SSTP_BITMASK_CONTROLFLAG,
369
16
      NULL, HFILL }
370
16
    },
371
    /* Length Packet (16 Bit) */
372
16
    { &hf_sstp_length,
373
16
      { "Length-Packet", "sstp.length",
374
16
      FT_UINT16, BASE_DEC,
375
16
      NULL, 0x0,
376
16
      NULL, HFILL }
377
16
    },
378
    /* Message Type (16 Bit) */
379
16
    { &hf_sstp_messagetype,
380
16
      { "Message Type", "sstp.messagetype",
381
16
      FT_UINT16, BASE_HEX,
382
16
      VALS(sstp_messagetypes), 0x0,
383
16
      NULL, HFILL }
384
16
    },
385
    /* Number of Attributes (16 Bit) */
386
16
    { &hf_sstp_numattrib,
387
16
      { "Number of Attributes", "sstp.numattrib",
388
16
      FT_UINT16, BASE_DEC,
389
16
      NULL, 0x0,
390
16
      NULL, HFILL }
391
16
    },
392
    /* Fields for Attributes */
393
    /* Attribute Reserved Field (8 Bit) */
394
16
    { &hf_sstp_attrib_reserved,
395
16
      { "Reserved", "sstp.attribreserved",
396
16
      FT_UINT8, BASE_HEX,
397
16
      NULL, 0x0,
398
16
      NULL, HFILL }
399
16
    },
400
    /* Attribute ID (8 Bit) */
401
16
    { &hf_sstp_attrib_id,
402
16
      { "ID", "sstp.attribid",
403
16
      FT_UINT8, BASE_DEC,
404
16
      VALS(sstp_attributes), 0x0,
405
16
      NULL, HFILL }
406
16
    },
407
    /* Attribute Length Reserved (4 Bit reserved for future use inside the 16 bit length field) */
408
16
    { &hf_sstp_attrib_length_reserved,
409
16
      { "Reserved", "sstp.attriblengthreserved",
410
16
      FT_UINT16, BASE_HEX,
411
16
      NULL, SSTP_BITMASK_LENGTH_RESERVED,
412
16
      NULL, HFILL }
413
16
    },
414
    /* Attribute Length Actual Length (12 Bit) */
415
16
    { &hf_sstp_attrib_length,
416
16
      { "Length", "sstp.attriblength",
417
16
      FT_UINT16, BASE_DEC,
418
16
      NULL, SSTP_BITMASK_LENGTH_LENGTH,
419
16
      NULL, HFILL }
420
16
    },
421
    /* Undocumented Data in SSTP_MSG_CALL_CONNECT_REQUEST
422
       see also MS-SSTP section 2.2.9 "Call Connect Request Message
423
       (SSTP_MSG_CALL_CONNECT_REQUEST)":
424
425
           https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sstp/e73ced14-7bef-407b-a85b-a6f624324dd1
426
     */
427
16
    { &hf_sstp_data_unknown,
428
16
      { "Unknown Data", "sstp.dataunknown",
429
16
      FT_BYTES, BASE_NONE,
430
16
      NULL, 0x0,
431
16
      NULL, HFILL }
432
16
    },
433
    /* Hash Protocol (8 Bit) */
434
16
    { &hf_sstp_hash_protocol,
435
16
      { "Hash Protocol", "sstp.hash",
436
16
      FT_UINT8, BASE_HEX,
437
16
      VALS(hash_protocols), 0x0,
438
16
      NULL, HFILL }
439
16
    },
440
    /* Nonce (256 Bit) */
441
16
    { &hf_sstp_nonce,
442
16
      { "Nonce", "sstp.nonce",
443
16
      FT_BYTES, BASE_NONE,
444
16
      NULL, 0x0,
445
16
      NULL, HFILL }
446
16
    },
447
    /* Cert Hash (20 Bytes if SHA1 is used, 32 Bytes with SHA256) */
448
16
    { &hf_sstp_cert_hash,
449
16
      { "Cert Hash", "sstp.cert_hash",
450
16
      FT_BYTES, BASE_NONE,
451
16
      NULL, 0x0,
452
16
      NULL, HFILL }
453
16
    },
454
    /* Cert Padding (0 Bytes if SHA256 is used, 12 Bytes with SHA1) */
455
16
    { &hf_sstp_padding,
456
16
      { "Padding", "sstp.padding",
457
16
      FT_BYTES, BASE_NONE,
458
16
      NULL, 0x0,
459
16
      NULL, HFILL }
460
16
    },
461
    /* Compound MAC (20 Bytes if SHA1 is used, 32 Bytes with SHA1) */
462
16
    { &hf_sstp_compound_mac,
463
16
      { "Compound Mac", "sstp.compoundmac",
464
16
      FT_BYTES, BASE_NONE,
465
16
      NULL, 0x0,
466
16
      NULL, HFILL }
467
16
    },
468
    /* Encapsulated Protocol (2 Bytes) */
469
16
    { &hf_sstp_ecapsulated_protocol,
470
16
      { "Encapsulated Protocol", "sstp.encapsulatedprotocol",
471
16
      FT_UINT16, BASE_HEX,
472
16
      VALS(encapsulated_protocols), 0x0,
473
16
      NULL, HFILL }
474
16
    },
475
    /* Attribute Status (4 Bytes) */
476
16
    { &hf_sstp_status,
477
16
      { "Status", "sstp.status",
478
16
      FT_UINT32, BASE_HEX,
479
16
      VALS(attrib_status), 0x0,
480
16
      NULL, HFILL }
481
16
    },
482
    /* Attribute Value (Variable Length) */
483
16
    { &hf_sstp_attrib_value,
484
16
      { "Attribute Value", "sstp.attribvalue",
485
16
      FT_BYTES, BASE_NONE,
486
16
      NULL, 0x0,
487
16
      NULL, HFILL }
488
16
    }
489
16
  };
490
491
  /* Setup protocol subtree array */
492
16
  static int *ett[] = {
493
16
    &ett_sstp,
494
16
    &ett_sstp_attribute,
495
16
    &ett_sstp_version
496
16
  };
497
498
16
  proto_sstp = proto_register_protocol("Secure Socket Tunneling Protocol", "SSTP", "sstp");
499
500
16
  register_dissector("sstp", dissect_sstp, proto_sstp);
501
16
  proto_register_field_array(proto_sstp, hf, array_length(hf));
502
16
  proto_register_subtree_array(ett, array_length(ett));
503
16
}
504
505
void
506
proto_reg_handoff_sstp(void)
507
16
{
508
16
  ppp_hdlc_handle = find_dissector_add_dependency("ppp_hdlc", proto_sstp);
509
16
}
510
511
/*
512
* Editor modelines  -  https://www.wireshark.org/tools/modelines.html
513
*
514
* Local variables:
515
* c-basic-offset: 2
516
* tab-width: 8
517
* indent-tabs-mode: nil
518
* End:
519
*
520
* vi: set shiftwidth=2 tabstop=8 expandtab:
521
* :indentSize=2:tabSize=8:noTabs=true:
522
*/