Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-smb-pipe.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
XXX  Fixme : shouldn't show [malformed frame] for long packets
3
*/
4
5
/* packet-smb-pipe.c
6
 * Routines for SMB named pipe packet dissection
7
 * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
8
 * significant rewrite to tvbuffify the dissector, Ronnie Sahlberg and
9
 * Guy Harris 2001
10
 *
11
 * Wireshark - Network traffic analyzer
12
 * By Gerald Combs <gerald@wireshark.org>
13
 * Copyright 1998 Gerald Combs
14
 *
15
 * Copied from packet-pop.c
16
 *
17
 * SPDX-License-Identifier: GPL-2.0-or-later
18
 */
19
20
#include "config.h"
21
22
#include <epan/packet.h>
23
#include <epan/exceptions.h>
24
#include <epan/to_str.h>
25
#include <epan/strutil.h>
26
#include <epan/expert.h>
27
#include <epan/reassemble.h>
28
#include "packet-smb.h"
29
#include "packet-smb-pipe.h"
30
#include "packet-smb-browse.h"
31
#include "packet-smb-common.h"
32
#include "packet-windows-common.h"
33
34
void proto_register_pipe_lanman(void);
35
void proto_register_smb_pipe(void);
36
37
static int proto_smb_pipe;
38
static int hf_smb_pipe_function;
39
static int hf_smb_pipe_priority;
40
static int hf_smb_pipe_peek_available;
41
static int hf_smb_pipe_peek_remaining;
42
static int hf_smb_pipe_peek_status;
43
static int hf_smb_pipe_getinfo_info_level;
44
static int hf_smb_pipe_getinfo_output_buffer_size;
45
static int hf_smb_pipe_getinfo_input_buffer_size;
46
static int hf_smb_pipe_getinfo_maximum_instances;
47
static int hf_smb_pipe_getinfo_current_instances;
48
static int hf_smb_pipe_getinfo_pipe_name_length;
49
static int hf_smb_pipe_getinfo_pipe_name;
50
static int hf_smb_pipe_write_raw_bytes_written;
51
static int hf_smb_pipe_fragments;
52
static int hf_smb_pipe_fragment;
53
static int hf_smb_pipe_fragment_overlap;
54
static int hf_smb_pipe_fragment_overlap_conflict;
55
static int hf_smb_pipe_fragment_multiple_tails;
56
static int hf_smb_pipe_fragment_too_long_fragment;
57
static int hf_smb_pipe_fragment_error;
58
static int hf_smb_pipe_fragment_count;
59
static int hf_smb_pipe_reassembled_in;
60
static int hf_smb_pipe_reassembled_length;
61
62
static int ett_smb_pipe;
63
static int ett_smb_pipe_fragment;
64
static int ett_smb_pipe_fragments;
65
66
static const fragment_items smb_pipe_frag_items = {
67
  &ett_smb_pipe_fragment,
68
  &ett_smb_pipe_fragments,
69
  &hf_smb_pipe_fragments,
70
  &hf_smb_pipe_fragment,
71
  &hf_smb_pipe_fragment_overlap,
72
  &hf_smb_pipe_fragment_overlap_conflict,
73
  &hf_smb_pipe_fragment_multiple_tails,
74
  &hf_smb_pipe_fragment_too_long_fragment,
75
  &hf_smb_pipe_fragment_error,
76
  &hf_smb_pipe_fragment_count,
77
  NULL,
78
  &hf_smb_pipe_reassembled_length,
79
  /* Reassembled data field */
80
  NULL,
81
  "fragments"
82
};
83
84
static int proto_smb_lanman;
85
static int hf_function_code;
86
static int hf_param_desc;
87
static int hf_return_desc;
88
static int hf_aux_data_desc;
89
static int hf_detail_level;
90
static int hf_padding;
91
static int hf_recv_buf_len;
92
static int hf_send_buf_len;
93
/* static int hf_continuation_from; */
94
static int hf_status;
95
static int hf_convert;
96
static int hf_param_no_descriptor;
97
static int hf_data_no_descriptor;
98
static int hf_data_no_recv_buffer;
99
static int hf_ecount;
100
static int hf_acount;
101
static int hf_share;
102
static int hf_share_name;
103
static int hf_share_type;
104
static int hf_share_comment;
105
static int hf_share_permissions;
106
static int hf_share_max_uses;
107
static int hf_share_current_uses;
108
static int hf_share_path;
109
static int hf_share_password;
110
static int hf_server;
111
static int hf_server_name;
112
static int hf_server_major;
113
static int hf_server_minor;
114
static int hf_server_comment;
115
static int hf_abytes;
116
static int hf_current_time;
117
static int hf_msecs;
118
static int hf_hour;
119
static int hf_minute;
120
static int hf_second;
121
static int hf_hundredths;
122
static int hf_tzoffset;
123
static int hf_timeinterval;
124
static int hf_day;
125
static int hf_month;
126
static int hf_year;
127
static int hf_weekday;
128
static int hf_enumeration_domain;
129
static int hf_last_entry;
130
static int hf_computer_name;
131
static int hf_user_name;
132
static int hf_group_name;
133
static int hf_workstation_domain;
134
static int hf_workstation_major;
135
static int hf_workstation_minor;
136
static int hf_logon_domain;
137
static int hf_other_domains;
138
static int hf_password;
139
static int hf_workstation_name;
140
static int hf_ustruct_size;
141
static int hf_logon_code;
142
static int hf_privilege_level;
143
static int hf_operator_privileges;
144
static int hf_num_logons;
145
static int hf_bad_pw_count;
146
static int hf_last_logon;
147
static int hf_last_logoff;
148
static int hf_logoff_time;
149
static int hf_kickoff_time;
150
static int hf_password_age;
151
static int hf_password_can_change;
152
static int hf_password_must_change;
153
static int hf_script_path;
154
static int hf_logoff_code;
155
static int hf_duration;
156
static int hf_comment;
157
static int hf_user_comment;
158
static int hf_full_name;
159
static int hf_homedir;
160
static int hf_parameters;
161
static int hf_logon_server;
162
static int hf_country_code;
163
static int hf_workstations;
164
static int hf_max_storage;
165
static int hf_units_per_week;
166
static int hf_logon_hours;
167
static int hf_code_page;
168
static int hf_new_password;
169
static int hf_old_password;
170
static int hf_reserved;
171
static int hf_aux_data_struct_count;
172
173
/* Generated from convert_proto_tree_add_text.pl */
174
static int hf_smb_pipe_stringz_param;
175
static int hf_smb_pipe_string_param;
176
static int hf_smb_pipe_bytes_param;
177
static int hf_smb_pipe_byte_param;
178
static int hf_smb_pipe_doubleword_param;
179
static int hf_smb_pipe_word_param;
180
181
static int ett_lanman;
182
static int ett_lanman_unknown_entries;
183
static int ett_lanman_unknown_entry;
184
static int ett_lanman_shares;
185
static int ett_lanman_share;
186
static int ett_lanman_groups;
187
static int ett_lanman_servers;
188
static int ett_lanman_server;
189
190
static expert_field ei_smb_pipe_bogus_netwkstauserlogon;
191
static expert_field ei_smb_pipe_bad_type;
192
193
/*
194
 * See
195
 *
196
 *  ftp://ftp.microsoft.com/developr/drg/CIFS/cifsrap2.txt
197
 *
198
 * among other documents.
199
 */
200
201
static const value_string status_vals[] = {
202
  {   0,  "Success"},
203
  {   5,  "User has insufficient privilege"},
204
  {  65,  "Network access is denied"},
205
  {  86,  "The specified password is invalid"},
206
  {SMBE_DOS_moredata, "Additional data is available"},
207
  {2114,  "Service is not running on the remote computer"},
208
  {2123,  "Supplied buffer is too small"},
209
  {2141,  "Server is not configured for transactions (IPC$ not shared)"},
210
  {2212,  "An error occurred while loading or running the logon script"},
211
  {2214,  "The logon was not validated by any server"},
212
  {2217,  "The logon server is running an older software version"},
213
  {2221,  "The user name was not found"},
214
  {2226,  "Operation not permitted on Backup Domain Controller"},
215
  {2240,  "The user is not allowed to logon from this computer"},
216
  {2241,  "The user is not allowed to logon at this time"},
217
  {2242,  "The user password has expired"},
218
  {2243,  "The password cannot be changed"},
219
  {2246,  "The password is too short"},
220
  {0,     NULL}
221
};
222
223
static const value_string privilege_vals[] = {
224
  {0, "Guest"},
225
  {1, "User"},
226
  {2, "Administrator"},
227
  {0, NULL}
228
};
229
230
static const value_string op_privilege_vals[] = {
231
  {0, "Print operator"},
232
  {1, "Communications operator"},
233
  {2, "Server operator"},
234
  {3, "Accounts operator"},
235
  {0, NULL}
236
};
237
238
static const value_string weekday_vals[] = {
239
  {0, "Sunday"},
240
  {1, "Monday"},
241
  {2, "Tuesday"},
242
  {3, "Wednesday"},
243
  {4, "Thursday"},
244
  {5, "Friday"},
245
  {6, "Saturday"},
246
  {0, NULL}
247
};
248
249
static int
250
add_word_param(tvbuff_t *tvb, int offset, int count _U_,
251
    packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_)
252
0
{
253
0
  proto_tree_add_item(tree, hf_index, tvb, offset, 2, ENC_LITTLE_ENDIAN);
254
0
  offset += 2;
255
0
  return offset;
256
0
}
257
258
static int
259
add_dword_param(tvbuff_t *tvb, int offset, int count _U_,
260
    packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_)
261
0
{
262
0
  proto_tree_add_item(tree, hf_index, tvb, offset, 4, ENC_LITTLE_ENDIAN);
263
0
  offset += 4;
264
0
  return offset;
265
0
}
266
267
static int
268
add_bytes_param(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
269
    proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_)
270
0
{
271
0
  header_field_info *hfinfo;
272
273
0
  if (hf_index > 0) {
274
0
    hfinfo = proto_registrar_get_nth(hf_index);
275
0
    if ((hfinfo == NULL) ||
276
0
        ((hfinfo->type == FT_INT8 || hfinfo->type == FT_UINT8)
277
0
        && (count != 1))) {
278
0
      THROW(ReportedBoundsError);
279
0
    }
280
0
    switch (hfinfo->type) {
281
282
0
    case FT_INT8:
283
0
    case FT_UINT8:
284
0
      proto_tree_add_item(tree, hf_index, tvb, offset, count,
285
0
          ENC_LITTLE_ENDIAN);
286
0
      break;
287
288
0
    case FT_STRING:
289
0
      proto_tree_add_item(tree, hf_index, tvb, offset, count,
290
0
          ENC_ASCII|ENC_NA);  /* XXX - code page? */
291
0
      break;
292
293
0
    default:
294
0
      proto_tree_add_item(tree, hf_index, tvb, offset, count,
295
0
          ENC_NA);
296
0
      break;
297
0
    }
298
0
  } else {
299
0
    if (count == 1) {
300
0
      proto_tree_add_item(tree, hf_smb_pipe_byte_param, tvb, offset, count, ENC_LITTLE_ENDIAN);
301
0
    } else {
302
0
      proto_tree_add_item(tree, hf_smb_pipe_bytes_param, tvb, offset, count, ENC_NA);
303
0
    }
304
0
  }
305
0
  offset += count;
306
0
  return offset;
307
0
}
308
309
static int
310
add_string_param_update_parent(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
311
    proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_)
312
0
{
313
0
  proto_item *ti, *parent_ti;
314
0
  const uint8_t *str;
315
316
0
  DISSECTOR_ASSERT(hf_index > 0);
317
0
  ti = proto_tree_add_item_ret_string(tree, hf_index, tvb, offset,
318
0
      count, ENC_ASCII|ENC_NA, pinfo->pool, &str);
319
      /* XXX - code page? */
320
0
  parent_ti = proto_item_get_parent(ti);
321
0
  proto_item_append_text(parent_ti, ": %s",
322
0
      format_text(pinfo->pool, str, strlen(str)));
323
0
  offset += count;
324
0
  return offset;
325
0
}
326
327
static int
328
add_pad_param(tvbuff_t *tvb _U_, int offset, int count, packet_info *pinfo _U_,
329
    proto_tree *tree _U_, int convert _U_, int hf_index _U_, smb_info_t *smb_info _U_)
330
0
{
331
  /*
332
   * This is for parameters that have descriptor entries but that
333
   * are, in practice, just padding.
334
   */
335
0
  offset += count;
336
0
  return offset;
337
0
}
338
339
static void
340
add_null_pointer_param(tvbuff_t *tvb, int offset, int count _U_,
341
    packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_)
342
0
{
343
0
  if (hf_index > 0) {
344
0
    proto_tree_add_string_format_value(tree, hf_index, tvb, offset, 0, "", "(Null pointer)");
345
0
  } else {
346
0
    proto_tree_add_string_format_value(tree, hf_smb_pipe_string_param, tvb, offset, 0, "", "(Null pointer)");
347
0
  }
348
0
}
349
350
static int
351
add_string_param(tvbuff_t *tvb, int offset, int count _U_,
352
    packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_)
353
0
{
354
0
  unsigned string_len;
355
356
0
  string_len = tvb_strsize(tvb, offset);
357
0
  if (hf_index > 0) {
358
0
    proto_tree_add_item(tree, hf_index, tvb, offset, string_len,
359
0
        ENC_ASCII|ENC_NA);  /* XXX - code page? */
360
0
  } else {
361
0
    proto_tree_add_item(tree, hf_smb_pipe_string_param, tvb, offset, string_len, ENC_NA|ENC_ASCII);
362
0
  }
363
0
  offset += string_len;
364
0
  return offset;
365
0
}
366
367
static const char *
368
get_stringz_pointer_value(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int convert, int *cptrp,
369
    int *lenp)
370
0
{
371
0
  int cptr;
372
0
  int string_len;
373
374
  /* pointer to string */
375
0
  cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
376
0
  *cptrp = cptr;
377
378
  /* string */
379
0
  if (tvb_offset_exists(tvb, cptr) &&
380
0
      (string_len = tvb_strnlen(tvb, cptr, -1)) != -1) {
381
0
        string_len++; /* include the terminating '\0' */
382
0
      *lenp = string_len;
383
0
      return tvb_format_text(scope, tvb, cptr, string_len - 1);
384
0
  } else
385
0
    return NULL;
386
0
}
387
388
static int
389
add_stringz_pointer_param(tvbuff_t *tvb, int offset, int count _U_,
390
    packet_info *pinfo, proto_tree *tree, int convert, int hf_index, smb_info_t *smb_info _U_)
391
0
{
392
0
  int cptr;
393
0
  const char *string;
394
0
  int string_len;
395
396
0
  string = get_stringz_pointer_value(pinfo->pool, tvb, offset, convert, &cptr,
397
0
      &string_len);
398
0
  offset += 4;
399
400
  /* string */
401
0
  if (string != NULL) {
402
0
    if (hf_index > 0) {
403
0
      proto_tree_add_item(tree, hf_index, tvb, cptr,
404
0
          string_len, ENC_ASCII|ENC_NA);  /* XXX - code page? */
405
0
    } else {
406
0
      proto_tree_add_item(tree, hf_smb_pipe_stringz_param, tvb, cptr, string_len, ENC_NA|ENC_ASCII);
407
0
    }
408
0
  } else {
409
0
    if (hf_index > 0) {
410
0
      proto_tree_add_string(tree, hf_index, tvb, 0, 0,
411
0
          "<String goes past end of frame>");
412
0
    } else {
413
0
      proto_tree_add_string(tree, hf_smb_pipe_stringz_param, tvb, 0, 0,
414
0
          "<String goes past end of frame>");
415
0
    }
416
0
  }
417
418
0
  return offset;
419
0
}
420
421
static int
422
add_bytes_pointer_param(tvbuff_t *tvb, int offset, int count,
423
    packet_info *pinfo _U_, proto_tree *tree, int convert, int hf_index, smb_info_t *smb_info _U_)
424
0
{
425
0
  int cptr;
426
427
  /* pointer to byte array */
428
0
  cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
429
0
  offset += 4;
430
431
  /* bytes */
432
0
  if (tvb_bytes_exist(tvb, cptr, count)) {
433
0
    if (hf_index > 0) {
434
0
      proto_tree_add_item(tree, hf_index, tvb, cptr,
435
0
          count, ENC_NA);
436
0
    } else {
437
0
      proto_tree_add_item(tree, hf_smb_pipe_bytes_param, tvb, cptr, count, ENC_NA);
438
0
    }
439
0
  } else {
440
0
    if (hf_index > 0) {
441
0
      proto_tree_add_bytes_format_value(tree, hf_index, tvb, 0, 0,
442
0
          NULL, "<Bytes go past end of frame>");
443
0
    } else {
444
0
      proto_tree_add_bytes_format_value(tree, hf_smb_pipe_bytes_param, tvb, 0, 0,
445
0
          NULL, "<Bytes go past end of frame>");
446
0
    }
447
0
  }
448
449
0
  return offset;
450
0
}
451
452
static int
453
add_detail_level(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo,
454
    proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info)
455
0
{
456
0
  smb_transact_info_t *trp = NULL;
457
0
  uint16_t level;
458
459
0
  if (smb_info->sip->extra_info_type == SMB_EI_TRI)
460
0
    trp = (smb_transact_info_t *)smb_info->sip->extra_info;
461
462
0
  level = tvb_get_letohs(tvb, offset);
463
0
  if (!pinfo->fd->visited)
464
0
    if (trp)
465
0
      trp->info_level = level; /* remember this for the response */
466
467
0
  proto_tree_add_uint(tree, hf_index, tvb, offset, 2, level);
468
0
  offset += 2;
469
0
  return offset;
470
0
}
471
472
static int
473
add_max_uses(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
474
    proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_)
475
0
{
476
0
  uint16_t WParam;
477
478
0
  WParam = tvb_get_letohs(tvb, offset);
479
0
  if (WParam == 0xffff) { /* -1 */
480
0
    proto_tree_add_uint_format_value(tree, hf_index, tvb,
481
0
        offset, 2, WParam,
482
0
        "No limit");
483
0
  } else {
484
0
    proto_tree_add_uint(tree, hf_index, tvb,
485
0
          offset, 2, WParam);
486
0
  }
487
0
  offset += 2;
488
0
  return offset;
489
0
}
490
491
static int
492
add_server_type(tvbuff_t *tvb, int offset, int count _U_,
493
    packet_info *pinfo, proto_tree *tree, int convert _U_, int hf_index _U_, smb_info_t *smb_info _U_)
494
0
{
495
0
  offset = dissect_smb_server_type_flags(
496
0
    tvb, offset, pinfo, tree, NULL, false);
497
0
  return offset;
498
0
}
499
500
static int
501
add_server_type_info(tvbuff_t *tvb, int offset, int count _U_,
502
    packet_info *pinfo, proto_tree *tree, int convert _U_, int hf_index _U_, smb_info_t *smb_info _U_)
503
0
{
504
0
  offset = dissect_smb_server_type_flags(
505
0
    tvb, offset, pinfo, tree, NULL, true);
506
0
  return offset;
507
0
}
508
509
static int
510
add_reltime(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
511
    proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_)
512
0
{
513
0
  nstime_t nstime;
514
515
0
  nstime.secs = tvb_get_letohl(tvb, offset);
516
0
  nstime.nsecs = 0;
517
0
  proto_tree_add_time_format_value(tree, hf_index, tvb, offset, 4,
518
0
      &nstime, "%s",
519
0
      signed_time_secs_to_str(pinfo->pool,  (int32_t) nstime.secs));
520
0
  offset += 4;
521
0
  return offset;
522
0
}
523
524
/*
525
 * Sigh.  These are for handling Microsoft's annoying almost-UNIX-time-but-
526
 * it's-local-time-not-UTC time.
527
 */
528
static int
529
add_abstime_common(tvbuff_t *tvb, int offset, proto_tree *tree, int hf_index,
530
    const char *absent_name)
531
0
{
532
0
  nstime_t nstime;
533
0
  struct tm *tmp;
534
535
0
  nstime.secs = tvb_get_letohl(tvb, offset);
536
0
  nstime.nsecs = 0;
537
  /*
538
   * Sigh.  Sometimes it appears that -1 means "unknown", and
539
   * sometimes it appears that 0 means "unknown", for the last
540
   * logoff date/time.
541
   */
542
0
  if (nstime.secs == -1 || nstime.secs == 0) {
543
0
    proto_tree_add_time_format_value(tree, hf_index, tvb, offset, 4,
544
0
        &nstime, "%s",
545
0
        absent_name);
546
0
  } else {
547
    /*
548
     * Run it through "gmtime()" to break it down, and then
549
     * run it through "mktime()" to put it back together
550
     * as UTC.
551
     */
552
0
    tmp = gmtime(&nstime.secs);
553
0
    if (tmp == NULL) {
554
      /*
555
       * Can't be represented.
556
       */
557
0
      proto_tree_add_time_format_value(tree, hf_index, tvb,
558
0
          offset, 4, &nstime, "Not representable");
559
0
    } else {
560
0
      tmp->tm_isdst = -1; /* we don't know if it's DST or not */
561
0
      nstime.secs = mktime(tmp);
562
0
      proto_tree_add_time(tree, hf_index, tvb, offset, 4,
563
0
          &nstime);
564
0
    }
565
0
  }
566
0
  offset += 4;
567
0
  return offset;
568
0
}
569
570
static int
571
add_abstime_absent_never(tvbuff_t *tvb, int offset, int count _U_,
572
    packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_)
573
0
{
574
0
  return add_abstime_common(tvb, offset, tree, hf_index, "Never");
575
0
}
576
577
static int
578
add_abstime_absent_unknown(tvbuff_t *tvb, int offset, int count _U_,
579
    packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_)
580
0
{
581
0
  return add_abstime_common(tvb, offset, tree, hf_index, "Unknown");
582
0
}
583
584
static int
585
add_nlogons(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
586
    proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_)
587
0
{
588
0
  uint16_t nlogons;
589
590
0
  nlogons = tvb_get_letohs(tvb, offset);
591
0
  if (nlogons == 0xffff) /* -1 */
592
0
    proto_tree_add_uint_format_value(tree, hf_index, tvb, offset, 2,
593
0
        nlogons, "Unknown");
594
0
  else
595
0
    proto_tree_add_uint(tree, hf_index, tvb, offset, 2, nlogons);
596
0
  offset += 2;
597
0
  return offset;
598
0
}
599
600
static int
601
add_max_storage(tvbuff_t *tvb, int offset, int count _U_,
602
    packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index, smb_info_t *smb_info _U_)
603
0
{
604
0
  uint32_t max_storage;
605
606
0
  max_storage = tvb_get_letohl(tvb, offset);
607
0
  if (max_storage == 0xffffffff)
608
0
    proto_tree_add_uint_format(tree, hf_index, tvb, offset, 4,
609
0
        max_storage, "No limit");
610
0
  else
611
0
    proto_tree_add_uint(tree, hf_index, tvb, offset, 4, max_storage);
612
0
  offset += 4;
613
0
  return offset;
614
0
}
615
616
static int
617
add_logon_hours(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
618
    proto_tree *tree, int convert, int hf_index, smb_info_t *smb_info _U_)
619
0
{
620
0
  int cptr;
621
622
  /* pointer to byte array */
623
0
  cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
624
0
  offset += 4;
625
626
  /* bytes */
627
0
  if (tvb_bytes_exist(tvb, cptr, count)) {
628
0
    if (count == 21) {
629
      /*
630
       * The logon hours should be exactly 21 bytes long.
631
       *
632
       * XXX - should actually carve up the bits;
633
       * we need the units per week to do that, though.
634
       */
635
0
      proto_tree_add_item(tree, hf_index, tvb, cptr, count,
636
0
          ENC_NA);
637
0
    } else {
638
0
      proto_tree_add_bytes_format_value(tree, hf_index, tvb,
639
0
          cptr, count, NULL,
640
0
          "%s (wrong length, should be 21, is %d",
641
0
          tvb_bytes_to_str(pinfo->pool, tvb, cptr, count), count);
642
0
    }
643
0
  } else {
644
0
    proto_tree_add_bytes_format_value(tree, hf_index, tvb, 0, 0,
645
0
          NULL, "<Bytes go past end of frame>");
646
0
  }
647
648
0
  return offset;
649
0
}
650
651
static int
652
add_tzoffset(tvbuff_t *tvb, int offset, int count _U_, packet_info *pinfo _U_,
653
    proto_tree *tree, int convert _U_, int hf_index _U_, smb_info_t *smb_info _U_)
654
0
{
655
0
  int16_t tzoffset;
656
657
0
  tzoffset = tvb_get_letohs(tvb, offset);
658
0
  if (tzoffset < 0) {
659
0
    proto_tree_add_int_format_value(tree, hf_tzoffset, tvb, offset, 2,
660
0
        tzoffset, "%s east of UTC",
661
0
        signed_time_secs_to_str(pinfo->pool, -tzoffset*60));
662
0
  } else if (tzoffset > 0) {
663
0
    proto_tree_add_int_format_value(tree, hf_tzoffset, tvb, offset, 2,
664
0
        tzoffset, "%s west of UTC",
665
0
        signed_time_secs_to_str(pinfo->pool, tzoffset*60));
666
0
  } else {
667
0
    proto_tree_add_int_format_value(tree, hf_tzoffset, tvb, offset, 2,
668
0
        tzoffset, "at UTC");
669
0
  }
670
0
  offset += 2;
671
0
  return offset;
672
0
}
673
674
static int
675
add_timeinterval(tvbuff_t *tvb, int offset, int count _U_,
676
    packet_info *pinfo _U_, proto_tree *tree, int convert _U_, int hf_index _U_, smb_info_t *smb_info _U_)
677
0
{
678
0
  uint16_t timeinterval;
679
680
0
  timeinterval = tvb_get_letohs(tvb, offset);
681
0
  proto_tree_add_uint_format_value(tree, hf_timeinterval, tvb, offset, 2,
682
0
     timeinterval, "%f seconds", timeinterval*.0001);
683
0
  offset += 2;
684
0
  return offset;
685
0
}
686
687
static int
688
add_logon_args(tvbuff_t *tvb, int offset, int count, packet_info *pinfo _U_,
689
    proto_tree *tree, int convert _U_, int hf_index _U_, smb_info_t *smb_info _U_)
690
0
{
691
0
  if (count != 54) {
692
0
    proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bogus_netwkstauserlogon, tvb, offset, count, "Bogus NetWkstaUserLogon parameters: length is %d, should be 54", count);
693
0
    offset += count;
694
0
    return offset;
695
0
  }
696
697
  /* user name */
698
0
  proto_tree_add_item(tree, hf_user_name, tvb, offset, 21, ENC_ASCII);
699
0
  offset += 21;
700
701
  /* pad1 */
702
0
  offset += 1;
703
704
  /* password */
705
0
  proto_tree_add_item(tree, hf_password, tvb, offset, 15, ENC_ASCII);
706
0
  offset += 15;
707
708
  /* pad2 */
709
0
  offset += 1;
710
711
  /* workstation name */
712
0
  proto_tree_add_item(tree, hf_workstation_name, tvb, offset, 16, ENC_ASCII);
713
0
  offset += 16;
714
0
  return offset;
715
0
}
716
717
/*
718
 * The following data structure describes the Remote API requests we
719
 * understand.
720
 *
721
 * Simply fill in the number and parameter information.
722
 * Try to keep them in order.
723
 *
724
 * We will extend this data structure as we try to decode more.
725
 */
726
727
/*
728
 * This is a pointer to a function to process an item.
729
 */
730
typedef int (*item_func)(tvbuff_t *, int, int, packet_info *, proto_tree *,
731
           int, int, smb_info_t*);
732
733
/*
734
 * Type of an item; determines what parameter strings are valid for
735
 * the item.
736
 */
737
typedef enum {
738
  PARAM_NONE, /* for the end-of-list stopper */
739
  PARAM_WORD, /* 'W' or 'h' - 16-bit word */
740
  PARAM_DWORD,  /* 'D' or 'i' - 32-bit word */
741
  PARAM_BYTES,  /* 'B' or 'b' or 'g' or 'O' - one or more bytes */
742
  PARAM_STRINGZ /* 'z' or 'O' - null-terminated string */
743
} param_type_t;
744
745
/*
746
 * This structure describes an item; "hf_index" points to the index
747
 * for the field corresponding to that item, "func" points to the
748
 * function to use to add that item to the tree, and "type" is the
749
 * type that the item is supposed to have.
750
 */
751
typedef struct {
752
  int   *hf_index;
753
  item_func func;
754
  param_type_t  type;
755
} item_t;
756
757
/*
758
 * This structure describes a list of items; each list of items
759
 * has a corresponding detail level.
760
 */
761
typedef struct {
762
  int   level;
763
  const item_t  *item_list;
764
} item_list_t;
765
766
struct lanman_desc {
767
  int   lanman_num;
768
  const item_t  *req;
769
  proto_item  *(*req_data_item)(tvbuff_t *, packet_info *,
770
            proto_tree *, int);
771
  int   *ett_req_data;
772
  const item_t  *req_data;
773
  const item_t  *req_aux_data;
774
  const item_t  *resp;
775
  const char  *resp_data_entry_list_label;
776
  int   *ett_data_entry_list;
777
  proto_item  *(*resp_data_element_item)(tvbuff_t *, proto_tree *,
778
               int);
779
  int   *ett_resp_data_element_item;
780
  const item_list_t *resp_data_list;
781
  const item_t  *resp_aux_data;
782
};
783
784
static int no_hf = -1;  /* for padding crap */
785
786
static const item_t lm_params_req_netshareenum[] = {
787
  { &hf_detail_level, add_detail_level, PARAM_WORD },
788
  { &hf_recv_buf_len, add_word_param, PARAM_WORD },
789
  { NULL, NULL, PARAM_NONE }
790
};
791
792
static const item_t lm_params_resp_netshareenum[] = {
793
  { &hf_acount, add_word_param, PARAM_WORD },
794
  { NULL, NULL, PARAM_NONE }
795
};
796
797
/*
798
 * Create a subtree for a share.
799
 */
800
static proto_item *
801
netshareenum_share_entry(tvbuff_t *tvb, proto_tree *tree, int offset)
802
0
{
803
0
  return proto_tree_add_item(tree, hf_share, tvb, offset, -1, ENC_NA);
804
0
}
805
806
static const item_t lm_null[] = {
807
  { NULL, NULL, PARAM_NONE }
808
};
809
810
static const item_list_t lm_null_list[] = {
811
  { -1, lm_null }
812
};
813
814
static const item_t lm_data_resp_netshareenum_1[] = {
815
  { &hf_share_name, add_string_param_update_parent, PARAM_BYTES },
816
  { &no_hf, add_pad_param, PARAM_BYTES },
817
  { &hf_share_type, add_word_param, PARAM_WORD },
818
  { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
819
  { NULL, NULL, PARAM_NONE }
820
};
821
822
static const item_list_t lm_data_resp_netshareenum[] = {
823
  { 1, lm_data_resp_netshareenum_1 },
824
  { -1, lm_null }
825
};
826
827
static const item_t lm_params_req_netsharegetinfo[] = {
828
  { &hf_share_name, add_string_param, PARAM_STRINGZ },
829
  { &hf_detail_level, add_detail_level, PARAM_WORD },
830
  { NULL, NULL, PARAM_NONE }
831
};
832
833
static const item_t lm_params_resp_netsharegetinfo[] = {
834
  { &hf_abytes, add_word_param, PARAM_WORD },
835
  { NULL, NULL, PARAM_NONE }
836
};
837
838
static const item_t lm_data_resp_netsharegetinfo_0[] = {
839
  { &hf_share_name, add_bytes_param, PARAM_BYTES },
840
  { NULL, NULL, PARAM_NONE }
841
};
842
843
static const item_t lm_data_resp_netsharegetinfo_1[] = {
844
  { &hf_share_name, add_bytes_param, PARAM_BYTES },
845
  { &no_hf, add_pad_param, PARAM_BYTES },
846
  { &hf_share_type, add_word_param, PARAM_WORD },
847
  { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
848
  { NULL, NULL, PARAM_NONE }
849
};
850
851
static const item_t lm_data_resp_netsharegetinfo_2[] = {
852
  { &hf_share_name, add_bytes_param, PARAM_BYTES },
853
  { &no_hf, add_pad_param, PARAM_BYTES },
854
  { &hf_share_type, add_word_param, PARAM_WORD },
855
  { &hf_share_comment, add_stringz_pointer_param, PARAM_STRINGZ },
856
  { &hf_share_permissions, add_word_param, PARAM_WORD }, /* XXX - do as bit fields */
857
  { &hf_share_max_uses, add_max_uses, PARAM_WORD },
858
  { &hf_share_current_uses, add_word_param, PARAM_WORD },
859
  { &hf_share_path, add_stringz_pointer_param, PARAM_STRINGZ },
860
  { &hf_share_password, add_bytes_param, PARAM_BYTES },
861
  { NULL, NULL, PARAM_NONE }
862
};
863
864
static const item_list_t lm_data_resp_netsharegetinfo[] = {
865
  { 0, lm_data_resp_netsharegetinfo_0 },
866
  { 1, lm_data_resp_netsharegetinfo_1 },
867
  { 2, lm_data_resp_netsharegetinfo_2 },
868
  { -1, lm_null }
869
};
870
871
static const item_t lm_params_req_netservergetinfo[] = {
872
  { &hf_detail_level, add_detail_level, PARAM_WORD },
873
  { NULL, NULL, PARAM_NONE }
874
};
875
876
static const item_t lm_params_resp_netservergetinfo[] = {
877
  { &hf_abytes, add_word_param, PARAM_WORD },
878
  { NULL, NULL, PARAM_NONE }
879
};
880
881
static const item_t lm_data_serverinfo_0[] = {
882
  { &hf_server_name, add_string_param_update_parent, PARAM_BYTES },
883
  { NULL, NULL, PARAM_NONE }
884
};
885
886
static const item_t lm_data_serverinfo_1[] = {
887
  { &hf_server_name, add_string_param_update_parent, PARAM_BYTES },
888
  { &hf_server_major, add_bytes_param, PARAM_BYTES },
889
  { &hf_server_minor, add_bytes_param, PARAM_BYTES },
890
  { &no_hf, add_server_type, PARAM_DWORD },
891
  { &hf_server_comment, add_stringz_pointer_param, PARAM_STRINGZ },
892
  { NULL, NULL, PARAM_NONE }
893
};
894
895
static const item_list_t lm_data_serverinfo[] = {
896
  { 0, lm_data_serverinfo_0 },
897
  { 1, lm_data_serverinfo_1 },
898
  { -1, lm_null }
899
};
900
901
static const item_t lm_params_req_netusergetinfo[] = {
902
  { &hf_user_name, add_string_param, PARAM_STRINGZ },
903
  { &hf_detail_level, add_detail_level, PARAM_WORD },
904
  { NULL, NULL, PARAM_NONE }
905
};
906
907
static const item_t lm_params_resp_netusergetinfo[] = {
908
  { &hf_abytes, add_word_param, PARAM_WORD },
909
  { NULL, NULL, PARAM_NONE }
910
};
911
912
static const item_t lm_data_resp_netusergetinfo_11[] = {
913
  { &hf_user_name, add_bytes_param, PARAM_BYTES },
914
  { &no_hf, add_pad_param, PARAM_BYTES },
915
  { &hf_comment, add_stringz_pointer_param, PARAM_STRINGZ },
916
  { &hf_user_comment, add_stringz_pointer_param, PARAM_STRINGZ },
917
  { &hf_full_name, add_stringz_pointer_param, PARAM_STRINGZ },
918
  { &hf_privilege_level, add_word_param, PARAM_WORD },
919
  { &hf_operator_privileges, add_dword_param, PARAM_DWORD },
920
  { &hf_password_age, add_reltime, PARAM_DWORD },
921
  { &hf_homedir, add_stringz_pointer_param, PARAM_STRINGZ },
922
  { &hf_parameters, add_stringz_pointer_param, PARAM_STRINGZ },
923
  { &hf_last_logon, add_abstime_absent_unknown, PARAM_DWORD },
924
  { &hf_last_logoff, add_abstime_absent_unknown, PARAM_DWORD },
925
  { &hf_bad_pw_count, add_word_param, PARAM_WORD },
926
  { &hf_num_logons, add_nlogons, PARAM_WORD },
927
  { &hf_logon_server, add_stringz_pointer_param, PARAM_STRINGZ },
928
  { &hf_country_code, add_word_param, PARAM_WORD },
929
  { &hf_workstations, add_stringz_pointer_param, PARAM_STRINGZ },
930
  { &hf_max_storage, add_max_storage, PARAM_DWORD },
931
  { &hf_units_per_week, add_word_param, PARAM_WORD },
932
  { &hf_logon_hours, add_logon_hours, PARAM_BYTES },
933
  { &hf_code_page, add_word_param, PARAM_WORD },
934
  { NULL, NULL, PARAM_NONE }
935
};
936
937
static const item_list_t lm_data_resp_netusergetinfo[] = {
938
  { 11, lm_data_resp_netusergetinfo_11 },
939
  { -1, lm_null }
940
};
941
942
static const item_t lm_params_req_netusergetgroups[] = {
943
  { &hf_user_name, add_string_param, PARAM_STRINGZ },
944
  { &hf_detail_level, add_detail_level, PARAM_WORD },
945
  { NULL, NULL, PARAM_NONE }
946
};
947
948
static const item_t lm_params_resp_netusergetgroups[] = {
949
  { &hf_abytes, add_word_param, PARAM_WORD },
950
  { NULL, NULL, PARAM_NONE }
951
};
952
953
static const item_t lm_data_resp_netusergetgroups_0[] = {
954
  { &hf_group_name, add_bytes_param, PARAM_BYTES },
955
  { NULL, NULL, PARAM_NONE }
956
};
957
958
static const item_list_t lm_data_resp_netusergetgroups[] = {
959
  { 0, lm_data_resp_netusergetgroups_0 },
960
  { -1, lm_null }
961
};
962
963
/*
964
 * Has no detail level; make it the default.
965
 */
966
static const item_t lm_data_resp_netremotetod_nolevel[] = {
967
  { &hf_current_time, add_abstime_absent_unknown, PARAM_DWORD },
968
  { &hf_msecs, add_dword_param, PARAM_DWORD },
969
  { &hf_hour, add_bytes_param, PARAM_BYTES },
970
  { &hf_minute, add_bytes_param, PARAM_BYTES },
971
  { &hf_second, add_bytes_param, PARAM_BYTES },
972
  { &hf_hundredths, add_bytes_param, PARAM_BYTES },
973
  { &hf_tzoffset, add_tzoffset, PARAM_WORD },
974
  { &hf_timeinterval, add_timeinterval, PARAM_WORD },
975
  { &hf_day, add_bytes_param, PARAM_BYTES },
976
  { &hf_month, add_bytes_param, PARAM_BYTES },
977
  { &hf_year, add_word_param, PARAM_WORD },
978
  { &hf_weekday, add_bytes_param, PARAM_BYTES },
979
  { NULL, NULL, PARAM_NONE }
980
};
981
982
static const item_list_t lm_data_resp_netremotetod[] = {
983
  { -1, lm_data_resp_netremotetod_nolevel },
984
};
985
986
static const item_t lm_params_req_netserverenum2[] = {
987
  { &hf_detail_level, add_detail_level, PARAM_WORD },
988
  { &no_hf, add_server_type_info, PARAM_DWORD },
989
  { &hf_enumeration_domain, add_string_param, PARAM_STRINGZ },
990
  { NULL, NULL, PARAM_NONE }
991
};
992
993
/*
994
 * Create a subtree for a server.
995
 */
996
static proto_item *
997
netserverenum2_server_entry(tvbuff_t *tvb, proto_tree *tree, int offset)
998
0
{
999
0
  return proto_tree_add_item(tree, hf_server, tvb, offset, -1, ENC_NA);
1000
0
}
1001
1002
static const item_t lm_params_resp_netserverenum2[] = {
1003
  { &hf_acount, add_word_param, PARAM_WORD },
1004
  { NULL, NULL, PARAM_NONE }
1005
};
1006
1007
1008
static const item_t lm_params_req_netserverenum3[] = {
1009
  { &hf_detail_level, add_detail_level, PARAM_WORD },
1010
  { &no_hf, add_server_type_info, PARAM_DWORD },
1011
  { &hf_enumeration_domain, add_string_param, PARAM_STRINGZ },
1012
  { &hf_last_entry, add_string_param, PARAM_STRINGZ },
1013
  { NULL, NULL, PARAM_NONE }
1014
};
1015
1016
1017
static const item_t lm_params_req_netwkstagetinfo[] = {
1018
  { &hf_detail_level, add_detail_level, PARAM_WORD },
1019
  { NULL, NULL, PARAM_NONE }
1020
};
1021
1022
static const item_t lm_params_resp_netwkstagetinfo[] = {
1023
  { &hf_abytes, add_word_param, PARAM_WORD },
1024
  { NULL, NULL, PARAM_NONE }
1025
};
1026
1027
static const item_t lm_data_resp_netwkstagetinfo_10[] = {
1028
  { &hf_computer_name, add_stringz_pointer_param, PARAM_STRINGZ },
1029
  { &hf_user_name, add_stringz_pointer_param, PARAM_STRINGZ },
1030
  { &hf_workstation_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1031
  { &hf_workstation_major, add_bytes_param, PARAM_BYTES },
1032
  { &hf_workstation_minor, add_bytes_param, PARAM_BYTES },
1033
  { &hf_logon_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1034
  { &hf_other_domains, add_stringz_pointer_param, PARAM_STRINGZ },
1035
  { NULL, NULL, PARAM_NONE }
1036
};
1037
1038
static const item_list_t lm_data_resp_netwkstagetinfo[] = {
1039
  { 10, lm_data_resp_netwkstagetinfo_10 },
1040
  { -1, lm_null }
1041
};
1042
1043
static const item_t lm_params_req_netwkstauserlogon[] = {
1044
  { &no_hf, add_stringz_pointer_param, PARAM_STRINGZ },
1045
  { &no_hf, add_stringz_pointer_param, PARAM_STRINGZ },
1046
  { &hf_detail_level, add_detail_level, PARAM_WORD },
1047
  { &no_hf, add_logon_args, PARAM_BYTES },
1048
  { &hf_ustruct_size, add_word_param, PARAM_WORD },
1049
  { NULL, NULL, PARAM_NONE }
1050
};
1051
1052
static const item_t lm_params_resp_netwkstauserlogon[] = {
1053
  { &hf_abytes, add_word_param, PARAM_WORD },
1054
  { NULL, NULL, PARAM_NONE }
1055
};
1056
1057
static const item_t lm_data_resp_netwkstauserlogon_1[] = {
1058
  { &hf_logon_code, add_word_param, PARAM_WORD },
1059
  { &hf_user_name, add_bytes_param, PARAM_BYTES },
1060
  { &no_hf, add_pad_param, PARAM_BYTES },
1061
  { &hf_privilege_level, add_word_param, PARAM_WORD },
1062
  { &hf_operator_privileges, add_dword_param, PARAM_DWORD },
1063
  { &hf_num_logons, add_nlogons, PARAM_WORD },
1064
  { &hf_bad_pw_count, add_word_param, PARAM_WORD },
1065
  { &hf_last_logon, add_abstime_absent_unknown, PARAM_DWORD },
1066
  { &hf_last_logoff, add_abstime_absent_unknown, PARAM_DWORD },
1067
  { &hf_logoff_time, add_abstime_absent_never, PARAM_DWORD },
1068
  { &hf_kickoff_time, add_abstime_absent_never, PARAM_DWORD },
1069
  { &hf_password_age, add_reltime, PARAM_DWORD },
1070
  { &hf_password_can_change, add_abstime_absent_never, PARAM_DWORD },
1071
  { &hf_password_must_change, add_abstime_absent_never, PARAM_DWORD },
1072
  { &hf_server_name, add_stringz_pointer_param, PARAM_STRINGZ },
1073
  { &hf_logon_domain, add_stringz_pointer_param, PARAM_STRINGZ },
1074
  { &hf_script_path, add_stringz_pointer_param, PARAM_STRINGZ },
1075
  { &hf_reserved, add_dword_param, PARAM_DWORD },
1076
  { NULL, NULL, PARAM_NONE }
1077
};
1078
1079
static const item_list_t lm_data_resp_netwkstauserlogon[] = {
1080
  { 1, lm_data_resp_netwkstauserlogon_1 },
1081
  { -1, lm_null }
1082
};
1083
1084
static const item_t lm_params_req_netwkstauserlogoff[] = {
1085
  { &hf_user_name, add_bytes_param, PARAM_BYTES },
1086
  { &no_hf, add_pad_param, PARAM_BYTES },
1087
  { &hf_workstation_name, add_bytes_param, PARAM_BYTES },
1088
  { NULL, NULL, PARAM_NONE }
1089
};
1090
1091
static const item_t lm_params_resp_netwkstauserlogoff[] = {
1092
  { &hf_abytes, add_word_param, PARAM_WORD },
1093
  { NULL, NULL, PARAM_NONE }
1094
};
1095
1096
static const item_t lm_data_resp_netwkstauserlogoff_1[] = {
1097
  { &hf_logoff_code, add_word_param, PARAM_WORD },
1098
  { &hf_duration, add_reltime, PARAM_DWORD },
1099
  { &hf_num_logons, add_nlogons, PARAM_WORD },
1100
  { NULL, NULL, PARAM_NONE }
1101
};
1102
1103
static const item_list_t lm_data_resp_netwkstauserlogoff[] = {
1104
  { 1, lm_data_resp_netwkstauserlogoff_1 },
1105
  { -1, lm_null }
1106
};
1107
1108
static const item_t lm_params_req_samoemchangepassword[] = {
1109
  { &hf_user_name, add_string_param, PARAM_STRINGZ },
1110
  { NULL, NULL, PARAM_NONE }
1111
};
1112
1113
static const item_t lm_data_req_samoemchangepassword[] = {
1114
  { &hf_new_password, add_bytes_param, PARAM_BYTES },
1115
  { &hf_old_password, add_bytes_param, PARAM_BYTES },
1116
  { NULL, NULL, PARAM_NONE }
1117
};
1118
1119
#define API_NetShareEnum    0
1120
#define API_NetShareGetInfo   1
1121
#define API_NetShareSetInfo   2
1122
#define API_NetShareAdd     3
1123
#define API_NetShareDel     4
1124
#define API_NetShareCheck   5
1125
#define API_NetSessionEnum    6
1126
#define API_NetSessionGetInfo   7
1127
#define API_NetSessionDel   8
1128
#define API_WconnectionEnum   9
1129
#define API_NetFileEnum     10
1130
#define API_NetFileGetInfo    11
1131
#define API_NetFileClose    12
1132
#define API_NetServerGetInfo    13
1133
#define API_NetServerSetInfo    14
1134
#define API_NetServerDiskEnum   15
1135
#define API_NetServerAdminCommand 16
1136
#define API_NetAuditOpen    17
1137
#define API_NetAuditClear   18
1138
#define API_NetErrorLogOpen   19
1139
#define API_NetErrorLogClear    20
1140
#define API_NetCharDevEnum    21
1141
#define API_NetCharDevGetInfo   22
1142
#define API_NetCharDevControl   23
1143
#define API_NetCharDevQEnum   24
1144
#define API_NetCharDevQGetInfo    25
1145
#define API_NetCharDevQSetInfo    26
1146
#define API_NetCharDevQPurge    27
1147
#define API_NetCharDevQPurgeSelf  28
1148
#define API_NetMessageNameEnum    29
1149
#define API_NetMessageNameGetInfo 30
1150
#define API_NetMessageNameAdd   31
1151
#define API_NetMessageNameDel   32
1152
#define API_NetMessageNameFwd   33
1153
#define API_NetMessageNameUnFwd   34
1154
#define API_NetMessageBufferSend  35
1155
#define API_NetMessageFileSend    36
1156
#define API_NetMessageLogFileSet  37
1157
#define API_NetMessageLogFileGet  38
1158
#define API_NetServiceEnum    39
1159
#define API_NetServiceInstall   40
1160
#define API_NetServiceControl   41
1161
#define API_NetAccessEnum   42
1162
#define API_NetAccessGetInfo    43
1163
#define API_NetAccessSetInfo    44
1164
#define API_NetAccessAdd    45
1165
#define API_NetAccessDel    46
1166
#define API_NetGroupEnum    47
1167
#define API_NetGroupAdd     48
1168
#define API_NetGroupDel     49
1169
#define API_NetGroupAddUser   50
1170
#define API_NetGroupDelUser   51
1171
#define API_NetGroupGetUsers    52
1172
#define API_NetUserEnum     53
1173
#define API_NetUserAdd      54
1174
#define API_NetUserDel      55
1175
#define API_NetUserGetInfo    56
1176
#define API_NetUserSetInfo    57
1177
#define API_NetUserPasswordSet    58
1178
#define API_NetUserGetGroups    59
1179
/*This line and number replaced a Dead Entry for 60 */
1180
/*This line and number replaced a Dead Entry for 61 */
1181
#define API_NetWkstaSetUID    62
1182
#define API_NetWkstaGetInfo   63
1183
#define API_NetWkstaSetInfo   64
1184
#define API_NetUseEnum      65
1185
#define API_NetUseAdd     66
1186
#define API_NetUseDel     67
1187
#define API_NetUseGetInfo   68
1188
#define API_WPrintQEnum     69
1189
#define API_WPrintQGetInfo    70
1190
#define API_WPrintQSetInfo    71
1191
#define API_WPrintQAdd      72
1192
#define API_WPrintQDel      73
1193
#define API_WPrintQPause    74
1194
#define API_WPrintQContinue   75
1195
#define API_WPrintJobEnum   76
1196
#define API_WPrintJobGetInfo    77
1197
#define API_WPrintJobSetInfo_OLD  78
1198
/* This line and number replaced a Dead Entry for 79 */
1199
/* This line and number replaced a Dead Entry for 80 */
1200
#define API_WPrintJobDel    81
1201
#define API_WPrintJobPause    82
1202
#define API_WPrintJobContinue   83
1203
#define API_WPrintDestEnum    84
1204
#define API_WPrintDestGetInfo   85
1205
#define API_WPrintDestControl   86
1206
#define API_NetProfileSave    87
1207
#define API_NetProfileLoad    88
1208
#define API_NetStatisticsGet    89
1209
#define API_NetStatisticsClear    90
1210
#define API_NetRemoteTOD    91
1211
#define API_WNetBiosEnum    92
1212
#define API_WNetBiosGetInfo   93
1213
#define API_NetServerEnum   94
1214
#define API_I_NetServerEnum   95
1215
#define API_NetServiceGetInfo   96
1216
/* This line and number replaced a Dead Entry for 97 */
1217
/* This line and number replaced a Dead Entry for 98 */
1218
/* This line and number replaced a Dead Entry for 99 */
1219
/* This line and number replaced a Dead Entry for 100 */
1220
/* This line and number replaced a Dead Entry for 101 */
1221
/* This line and number replaced a Dead Entry for 102 */
1222
#define API_WPrintQPurge    103
1223
#define API_NetServerEnum2    104
1224
#define API_NetAccessGetUserPerms 105
1225
#define API_NetGroupGetInfo   106
1226
#define API_NetGroupSetInfo   107
1227
#define API_NetGroupSetUsers    108
1228
#define API_NetUserSetGroups    109
1229
#define API_NetUserModalsGet    110
1230
#define API_NetUserModalsSet    111
1231
#define API_NetFileEnum2    112
1232
#define API_NetUserAdd2     113
1233
#define API_NetUserSetInfo2   114
1234
#define API_NetUserPasswordSet2   115
1235
#define API_I_NetServerEnum2    116
1236
#define API_NetConfigGet2   117
1237
#define API_NetConfigGetAll2    118
1238
#define API_NetGetDCName    119
1239
#define API_NetHandleGetInfo    120
1240
#define API_NetHandleSetInfo    121
1241
#define API_NetStatisticsGet2   122
1242
#define API_WBuildGetInfo   123
1243
#define API_NetFileGetInfo2   124
1244
#define API_NetFileClose2   125
1245
#define API_NetServerReqChallenge 126
1246
#define API_NetServerAuthenticate 127
1247
#define API_NetServerPasswordSet  128
1248
#define API_WNetAccountDeltas   129
1249
#define API_WNetAccountSync   130
1250
#define API_NetUserEnum2    131
1251
#define API_NetWkstaUserLogon   132
1252
#define API_NetWkstaUserLogoff    133
1253
#define API_NetLogonEnum    134
1254
#define API_NetErrorLogRead   135
1255
#define API_I_NetPathType   136
1256
#define API_I_NetPathCanonicalize 137
1257
#define API_I_NetPathCompare    138
1258
#define API_I_NetNameValidate   139
1259
#define API_I_NetNameCanonicalize 140
1260
#define API_I_NetNameCompare    141
1261
#define API_NetAuditRead    142
1262
#define API_WPrintDestAdd   143
1263
#define API_WPrintDestSetInfo   144
1264
#define API_WPrintDestDel   145
1265
#define API_NetUserValidate2    146
1266
#define API_WPrintJobSetInfo    147
1267
#define API_TI_NetServerDiskEnum  148
1268
#define API_TI_NetServerDiskGetInfo 149
1269
#define API_TI_FTVerifyMirror   150
1270
#define API_TI_FTAbortVerify    151
1271
#define API_TI_FTGetInfo    152
1272
#define API_TI_FTSetInfo    153
1273
#define API_TI_FTLockDisk   154
1274
#define API_TI_FTFixError   155
1275
#define API_TI_FTAbortFix   156
1276
#define API_TI_FTDiagnoseError    157
1277
#define API_TI_FTGetDriveStats    158
1278
/* This line and number replaced a Dead Entry for 159 */
1279
#define API_TI_FTErrorGetInfo   160
1280
/* This line and number replaced a Dead Entry for 161 */
1281
/* This line and number replaced a Dead Entry for 162 */
1282
#define API_NetAccessCheck    163
1283
#define API_NetAlertRaise   164
1284
#define API_NetAlertStart   165
1285
#define API_NetAlertStop    166
1286
#define API_NetAuditWrite   167
1287
#define API_NetIRemoteAPI   168
1288
#define API_NetServiceStatus    169
1289
#define API_I_NetServerRegister   170
1290
#define API_I_NetServerDeregister 171
1291
#define API_I_NetSessionEntryMake 172
1292
#define API_I_NetSessionEntryClear  173
1293
#define API_I_NetSessionEntryGetInfo  174
1294
#define API_I_NetSessionEntrySetInfo  175
1295
#define API_I_NetConnectionEntryMake  176
1296
#define API_I_NetConnectionEntryClear 177
1297
#define API_I_NetConnectionEntrySetInfo 178
1298
#define API_I_NetConnectionEntryGetInfo 179
1299
#define API_I_NetFileEntryMake    180
1300
#define API_I_NetFileEntryClear   181
1301
#define API_I_NetFileEntrySetInfo 182
1302
#define API_I_NetFileEntryGetInfo 183
1303
#define API_AltSrvMessageBufferSend 184
1304
#define API_AltSrvMessageFileSend 185
1305
#define API_wI_NetRplWkstaEnum    186
1306
#define API_wI_NetRplWkstaGetInfo 187
1307
#define API_wI_NetRplWkstaSetInfo 188
1308
#define API_wI_NetRplWkstaAdd   189
1309
#define API_wI_NetRplWkstaDel   190
1310
#define API_wI_NetRplProfileEnum  191
1311
#define API_wI_NetRplProfileGetInfo 192
1312
#define API_wI_NetRplProfileSetInfo 193
1313
#define API_wI_NetRplProfileAdd   194
1314
#define API_wI_NetRplProfileDel   195
1315
#define API_wI_NetRplProfileClone 196
1316
#define API_wI_NetRplBaseProfileEnum  197
1317
/* This line and number replaced a Dead Entry for 198 */
1318
/* This line and number replaced a Dead Entry for 199 */
1319
/* This line and number replaced a Dead Entry for 200 */
1320
#define API_WIServerSetInfo   201
1321
/* This line and number replaced a Dead Entry for 202 */
1322
/* This line and number replaced a Dead Entry for 203 */
1323
/* This line and number replaced a Dead Entry for 204 */
1324
#define API_WPrintDriverEnum    205
1325
#define API_WPrintQProcessorEnum  206
1326
#define API_WPrintPortEnum    207
1327
#define API_WNetWriteUpdateLog    208
1328
#define API_WNetAccountUpdate   209
1329
#define API_WNetAccountConfirmUpdate  210
1330
#define API_NetConfigSet    211
1331
#define API_WAccountsReplicate    212
1332
/* 213 is used by WfW */
1333
#define API_SamOEMChgPasswordUser2_P  214
1334
#define API_NetServerEnum3    215
1335
/* XXX - what about 216 through 249? */
1336
#define API_WPrintDriverGetInfo   250
1337
#define API_WPrintDriverSetInfo   251
1338
#define API_NetAliasAdd     252
1339
#define API_NetAliasDel     253
1340
#define API_NetAliasGetInfo   254
1341
#define API_NetAliasSetInfo   255
1342
#define API_NetAliasEnum    256
1343
#define API_NetUserGetLogonAsn    257
1344
#define API_NetUserSetLogonAsn    258
1345
#define API_NetUserGetAppSel    259
1346
#define API_NetUserSetAppSel    260
1347
#define API_NetAppAdd     261
1348
#define API_NetAppDel     262
1349
#define API_NetAppGetInfo   263
1350
#define API_NetAppSetInfo   264
1351
#define API_NetAppEnum      265
1352
#define API_NetUserDCDBInit   266
1353
#define API_NetDASDAdd      267
1354
#define API_NetDASDDel      268
1355
#define API_NetDASDGetInfo    269
1356
#define API_NetDASDSetInfo    270
1357
#define API_NetDASDEnum     271
1358
#define API_NetDASDCheck    272
1359
#define API_NetDASDCtl      273
1360
#define API_NetUserRemoteLogonCheck 274
1361
#define API_NetUserPasswordSet3   275
1362
#define API_NetCreateRIPLMachine  276
1363
#define API_NetDeleteRIPLMachine  277
1364
#define API_NetGetRIPLMachineInfo 278
1365
#define API_NetSetRIPLMachineInfo 279
1366
#define API_NetEnumRIPLMachine    280
1367
#define API_I_ShareAdd      281
1368
#define API_I_AliasEnum     282
1369
#define API_NetAccessApply    283
1370
#define API_WPrt16Query     284
1371
#define API_WPrt16Set     285
1372
#define API_NetUserDel100   286
1373
#define API_NetUserRemoteLogonCheck2  287
1374
#define API_WRemoteTODSet   294
1375
#define API_WPrintJobMoveAll    295
1376
#define API_W16AppParmAdd   296
1377
#define API_W16AppParmDel   297
1378
#define API_W16AppParmGet   298
1379
#define API_W16AppParmSet   299
1380
#define API_W16RIPLMachineCreate  300
1381
#define API_W16RIPLMachineGetInfo 301
1382
#define API_W16RIPLMachineSetInfo 302
1383
#define API_W16RIPLMachineEnum    303
1384
#define API_W16RIPLMachineListParmEnum  304
1385
#define API_W16RIPLMachClassGetInfo 305
1386
#define API_W16RIPLMachClassEnum  306
1387
#define API_W16RIPLMachClassCreate  307
1388
#define API_W16RIPLMachClassSetInfo 308
1389
#define API_W16RIPLMachClassDelete  309
1390
#define API_W16RIPLMachClassLPEnum  310
1391
#define API_W16RIPLMachineDelete  311
1392
#define API_W16WSLevelGetInfo   312
1393
#define API_NetServerNameAdd    313
1394
#define API_NetServerNameDel    314
1395
#define API_NetServerNameEnum   315
1396
#define API_I_WDASDEnum     316
1397
#define API_I_WDASDEnumTerminate  317
1398
#define API_I_WDASDSetInfo2   318
1399
1400
static const struct lanman_desc lmd[] = {
1401
  { API_NetShareEnum,
1402
    lm_params_req_netshareenum,
1403
    NULL,
1404
    NULL,
1405
    lm_null,
1406
    lm_null,
1407
    lm_params_resp_netshareenum,
1408
    "Available Shares",
1409
    &ett_lanman_shares,
1410
    netshareenum_share_entry,
1411
    &ett_lanman_share,
1412
    lm_data_resp_netshareenum,
1413
    lm_null },
1414
1415
  { API_NetShareGetInfo,
1416
    lm_params_req_netsharegetinfo,
1417
    NULL,
1418
    NULL,
1419
    lm_null,
1420
    lm_null,
1421
    lm_params_resp_netsharegetinfo,
1422
    NULL,
1423
    NULL,
1424
    NULL,
1425
    NULL,
1426
    lm_data_resp_netsharegetinfo,
1427
    lm_null },
1428
1429
  { API_NetServerGetInfo,
1430
    lm_params_req_netservergetinfo,
1431
    NULL,
1432
    NULL,
1433
    lm_null,
1434
    lm_null,
1435
    lm_params_resp_netservergetinfo,
1436
    NULL,
1437
    NULL,
1438
    NULL,
1439
    NULL,
1440
    lm_data_serverinfo,
1441
    lm_null },
1442
1443
  { API_NetUserGetInfo,
1444
    lm_params_req_netusergetinfo,
1445
    NULL,
1446
    NULL,
1447
    lm_null,
1448
    lm_null,
1449
    lm_params_resp_netusergetinfo,
1450
    NULL,
1451
    NULL,
1452
    NULL,
1453
    NULL,
1454
    lm_data_resp_netusergetinfo,
1455
    lm_null },
1456
1457
  { API_NetUserGetGroups,
1458
    lm_params_req_netusergetgroups,
1459
    NULL,
1460
    NULL,
1461
    lm_null,
1462
    lm_null,
1463
    lm_params_resp_netusergetgroups,
1464
    "Groups",
1465
    &ett_lanman_groups,
1466
    NULL,
1467
    NULL,
1468
    lm_data_resp_netusergetgroups,
1469
    lm_null },
1470
1471
  { API_NetRemoteTOD,
1472
    lm_null,
1473
    NULL,
1474
    NULL,
1475
    lm_null,
1476
    lm_null,
1477
    lm_null,
1478
    NULL,
1479
    NULL,
1480
    NULL,
1481
    NULL,
1482
    lm_data_resp_netremotetod,
1483
    lm_null },
1484
1485
  { API_NetServerEnum2,
1486
    lm_params_req_netserverenum2,
1487
    NULL,
1488
    NULL,
1489
    lm_null,
1490
    lm_null,
1491
    lm_params_resp_netserverenum2,
1492
    "Servers",
1493
    &ett_lanman_servers,
1494
    netserverenum2_server_entry,
1495
    &ett_lanman_server,
1496
    lm_data_serverinfo,
1497
    lm_null },
1498
1499
  { API_NetWkstaGetInfo,
1500
    lm_params_req_netwkstagetinfo,
1501
    NULL,
1502
    NULL,
1503
    lm_null,
1504
    lm_null,
1505
    lm_params_resp_netwkstagetinfo,
1506
    NULL,
1507
    NULL,
1508
    NULL,
1509
    NULL,
1510
    lm_data_resp_netwkstagetinfo,
1511
    lm_null },
1512
1513
  { API_NetWkstaUserLogon,
1514
    lm_params_req_netwkstauserlogon,
1515
    NULL,
1516
    NULL,
1517
    lm_null,
1518
    lm_null,
1519
    lm_params_resp_netwkstauserlogon,
1520
    NULL,
1521
    NULL,
1522
    NULL,
1523
    NULL,
1524
    lm_data_resp_netwkstauserlogon,
1525
    lm_null },
1526
1527
  { API_NetWkstaUserLogoff,
1528
    lm_params_req_netwkstauserlogoff,
1529
    NULL,
1530
    NULL,
1531
    lm_null,
1532
    lm_null,
1533
    lm_params_resp_netwkstauserlogoff,
1534
    NULL,
1535
    NULL,
1536
    NULL,
1537
    NULL,
1538
    lm_data_resp_netwkstauserlogoff,
1539
    lm_null },
1540
1541
  { API_SamOEMChgPasswordUser2_P,
1542
    lm_params_req_samoemchangepassword,
1543
    NULL,
1544
    NULL,
1545
    lm_data_req_samoemchangepassword,
1546
    lm_null,
1547
    lm_null,
1548
    NULL,
1549
    NULL,
1550
    NULL,
1551
    NULL,
1552
    lm_null_list,
1553
    lm_null },
1554
1555
  { API_NetServerEnum3,
1556
    lm_params_req_netserverenum3,
1557
    NULL,
1558
    NULL,
1559
    lm_null,
1560
    lm_null,
1561
    lm_params_resp_netserverenum2,
1562
    "Servers",
1563
    &ett_lanman_servers,
1564
    netserverenum2_server_entry,
1565
    &ett_lanman_server,
1566
    lm_data_serverinfo,
1567
    lm_null },
1568
1569
  { -1,
1570
    lm_null,
1571
    NULL,
1572
    NULL,
1573
    lm_null,
1574
    lm_null,
1575
    lm_null,
1576
    NULL,
1577
    NULL,
1578
    NULL,
1579
    &ett_lanman_unknown_entry,
1580
    lm_null_list,
1581
    lm_null }
1582
};
1583
1584
static const struct lanman_desc *
1585
find_lanman(int lanman_num)
1586
0
{
1587
0
  int i;
1588
1589
0
  for (i = 0; lmd[i].lanman_num != -1; i++) {
1590
0
    if (lmd[i].lanman_num == lanman_num)
1591
0
      break;
1592
0
  }
1593
0
  return &lmd[i];
1594
0
}
1595
1596
static const unsigned char *
1597
get_count(const unsigned char *desc, int *countp)
1598
0
{
1599
0
  int count = 0;
1600
0
  unsigned char c;
1601
1602
0
  if (!g_ascii_isdigit(*desc)) {
1603
0
    *countp = 1;  /* no count was supplied */
1604
0
    return desc;
1605
0
  }
1606
1607
0
  while ((c = *desc) != '\0' && g_ascii_isdigit(c)) {
1608
0
    count = (count * 10) + c - '0';
1609
0
    desc++;
1610
0
  }
1611
1612
0
  *countp = count;  /* XXX - what if it's 0? */
1613
0
  return desc;
1614
0
}
1615
1616
static int
1617
dissect_request_parameters(tvbuff_t *tvb, int offset, packet_info *pinfo,
1618
    proto_tree *tree, const unsigned char *desc, const item_t *items,
1619
    bool *has_data_p, smb_info_t *smb_info)
1620
0
{
1621
0
  unsigned c;
1622
0
  uint16_t WParam;
1623
0
  uint32_t LParam;
1624
0
  unsigned string_len;
1625
0
  int count;
1626
1627
0
  *has_data_p = false;
1628
0
  while ((c = *desc++) != '\0') {
1629
0
    switch (c) {
1630
1631
0
    case 'W':
1632
      /*
1633
       * A 16-bit word value in the request.
1634
       */
1635
0
      if (items->func == NULL) {
1636
        /*
1637
         * We've run out of items in the table;
1638
         * fall back on the default.
1639
         */
1640
0
        offset = add_word_param(tvb, offset, 0, pinfo,
1641
0
            tree, 0, hf_smb_pipe_word_param, smb_info);
1642
0
      } else if (items->type != PARAM_WORD) {
1643
        /*
1644
         * Descriptor character is 'W', but this
1645
         * isn't a word parameter.
1646
         */
1647
0
        WParam = tvb_get_letohs(tvb, offset);
1648
0
        proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, 2,
1649
0
            "%s: Value is %u (0x%04X), type is wrong (W)",
1650
0
            proto_registrar_get_name((*items->hf_index <= 0) ?
1651
0
              hf_smb_pipe_word_param : *items->hf_index),
1652
0
            WParam, WParam);
1653
0
        offset += 2;
1654
0
        items++;
1655
0
      } else {
1656
0
        offset = (*items->func)(tvb, offset, 0, pinfo,
1657
0
            tree, 0, *items->hf_index, smb_info);
1658
0
        items++;
1659
0
      }
1660
0
      break;
1661
1662
0
    case 'D':
1663
      /*
1664
       * A 32-bit doubleword value in the request.
1665
       */
1666
0
      if (items->func == NULL) {
1667
        /*
1668
         * We've run out of items in the table;
1669
         * fall back on the default.
1670
         */
1671
0
        offset = add_dword_param(tvb, offset, 0, pinfo,
1672
0
            tree, 0, hf_smb_pipe_doubleword_param, smb_info);
1673
0
      } else if (items->type != PARAM_DWORD) {
1674
        /*
1675
         * Descriptor character is 'D', but this
1676
         * isn't a doubleword parameter.
1677
         */
1678
0
        LParam = tvb_get_letohl(tvb, offset);
1679
0
        proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, 2,
1680
0
            "%s: Value is %u (0x%08X), type is wrong (D)",
1681
0
            proto_registrar_get_name((*items->hf_index <= 0) ?
1682
0
              hf_smb_pipe_doubleword_param : *items->hf_index),
1683
0
            LParam, LParam);
1684
0
        offset += 4;
1685
0
        items++;
1686
0
      } else {
1687
0
        offset = (*items->func)(tvb, offset, 0, pinfo,
1688
0
            tree, 0, *items->hf_index, smb_info);
1689
0
        items++;
1690
0
      }
1691
0
      break;
1692
1693
0
    case 'b':
1694
      /*
1695
       * A byte or multi-byte value in the request.
1696
       */
1697
0
      desc = get_count(desc, &count);
1698
0
      if (items->func == NULL) {
1699
        /*
1700
         * We've run out of items in the table;
1701
         * fall back on the default.
1702
         */
1703
0
        offset = add_bytes_param(tvb, offset, count,
1704
0
            pinfo, tree, 0, -1, smb_info);
1705
0
      } else if (items->type != PARAM_BYTES) {
1706
        /*
1707
         * Descriptor character is 'b', but this
1708
         * isn't a byte/bytes parameter.
1709
         */
1710
0
        proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, count,
1711
0
            "%s: Value is %s, type is wrong (b)",
1712
0
            proto_registrar_get_name((*items->hf_index <= 0) ?
1713
0
              hf_smb_pipe_bytes_param : *items->hf_index),
1714
0
            tvb_bytes_to_str(pinfo->pool, tvb, offset, count));
1715
0
        offset += count;
1716
0
        items++;
1717
0
      } else {
1718
0
        offset = (*items->func)(tvb, offset, count,
1719
0
            pinfo, tree, 0, *items->hf_index, smb_info);
1720
0
        items++;
1721
0
      }
1722
0
      break;
1723
1724
0
    case 'O':
1725
      /*
1726
       * A null pointer.
1727
       */
1728
0
      if (items->func == NULL) {
1729
        /*
1730
         * We've run out of items in the table;
1731
         * fall back on the default.
1732
         */
1733
0
        add_null_pointer_param(tvb, offset, 0,
1734
0
            pinfo, tree, 0, -1, smb_info);
1735
0
      } else {
1736
        /*
1737
         * If "*items->hf_index" is -1, this is
1738
         * a reserved must-be-null field; don't
1739
         * clutter the protocol tree by putting
1740
         * it in.
1741
         */
1742
0
        if (*items->hf_index > 0) {
1743
0
          add_null_pointer_param(tvb,
1744
0
              offset, 0, pinfo, tree, 0,
1745
0
              *items->hf_index, smb_info);
1746
0
        }
1747
0
        items++;
1748
0
      }
1749
0
      break;
1750
1751
0
    case 'z':
1752
      /*
1753
       * A null-terminated ASCII string.
1754
       */
1755
0
      if (items->func == NULL) {
1756
        /*
1757
         * We've run out of items in the table;
1758
         * fall back on the default.
1759
         */
1760
0
        offset = add_string_param(tvb, offset, 0,
1761
0
            pinfo, tree, 0, -1, smb_info);
1762
0
      } else if (items->type != PARAM_STRINGZ) {
1763
        /*
1764
         * Descriptor character is 'z', but this
1765
         * isn't a string parameter.
1766
         */
1767
0
        string_len = tvb_strsize(tvb, offset);
1768
0
        proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, string_len,
1769
0
            "%s: Value is %s, type is wrong (z)",
1770
0
            proto_registrar_get_name((*items->hf_index <= 0) ?
1771
0
              hf_smb_pipe_string_param : *items->hf_index),
1772
0
            tvb_format_text(pinfo->pool, tvb, offset, string_len));
1773
0
        offset += string_len;
1774
0
        items++;
1775
0
      } else {
1776
0
        offset = (*items->func)(tvb, offset, 0,
1777
0
            pinfo, tree, 0, *items->hf_index, smb_info);
1778
0
        items++;
1779
0
      }
1780
0
      break;
1781
1782
0
    case 'F':
1783
      /*
1784
       * One or more pad bytes.
1785
       */
1786
0
      desc = get_count(desc, &count);
1787
0
      proto_tree_add_item(tree, hf_padding, tvb, offset, count, ENC_NA);
1788
0
      offset += count;
1789
0
      break;
1790
1791
0
    case 'L':
1792
      /*
1793
       * 16-bit receive buffer length.
1794
       */
1795
0
      proto_tree_add_item(tree, hf_recv_buf_len, tvb,
1796
0
          offset, 2, ENC_LITTLE_ENDIAN);
1797
0
      offset += 2;
1798
0
      break;
1799
1800
0
    case 's':
1801
      /*
1802
       * 32-bit send buffer offset.
1803
       * This appears not to be sent over the wire.
1804
       */
1805
0
      *has_data_p = true;
1806
0
      break;
1807
1808
0
    case 'T':
1809
      /*
1810
       * 16-bit send buffer length.
1811
       */
1812
0
      proto_tree_add_item(tree, hf_send_buf_len, tvb,
1813
0
          offset, 2, ENC_LITTLE_ENDIAN);
1814
0
      offset += 2;
1815
0
      break;
1816
1817
0
    default:
1818
0
      break;
1819
0
    }
1820
0
  }
1821
0
  return offset;
1822
0
}
1823
1824
static int
1825
dissect_response_parameters(tvbuff_t *tvb, int offset, packet_info *pinfo,
1826
    proto_tree *tree, const unsigned char *desc, const item_t *items,
1827
    bool *has_data_p, bool *has_ent_count_p, uint16_t *ent_count_p, smb_info_t *smb_info)
1828
0
{
1829
0
  unsigned c;
1830
0
  uint16_t WParam;
1831
0
  uint32_t LParam;
1832
0
  int count;
1833
1834
0
  *has_data_p = false;
1835
0
  *has_ent_count_p = false;
1836
0
  while ((c = *desc++) != '\0') {
1837
0
    switch (c) {
1838
1839
0
    case 'r':
1840
      /*
1841
       * 32-bit receive buffer offset.
1842
       */
1843
0
      *has_data_p = true;
1844
0
      break;
1845
1846
0
    case 'g':
1847
      /*
1848
       * A byte or series of bytes is returned.
1849
       */
1850
0
      desc = get_count(desc, &count);
1851
0
      if (items->func == NULL) {
1852
        /*
1853
         * We've run out of items in the table;
1854
         * fall back on the default.
1855
         */
1856
0
        offset = add_bytes_param(tvb, offset, count,
1857
0
            pinfo, tree, 0, -1, smb_info);
1858
0
      } else if (items->type != PARAM_BYTES) {
1859
        /*
1860
         * Descriptor character is 'b', but this
1861
         * isn't a byte/bytes parameter.
1862
         */
1863
0
        proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, count,
1864
0
            "%s: Value is %s, type is wrong (g)",
1865
0
            proto_registrar_get_name((*items->hf_index <= 0) ?
1866
0
              hf_smb_pipe_bytes_param : *items->hf_index),
1867
0
            tvb_bytes_to_str(pinfo->pool, tvb, offset, count));
1868
0
        offset += count;
1869
0
        items++;
1870
0
      } else {
1871
0
        offset = (*items->func)(tvb, offset, count,
1872
0
            pinfo, tree, 0, *items->hf_index, smb_info);
1873
0
        items++;
1874
0
      }
1875
0
      break;
1876
1877
0
    case 'h':
1878
      /*
1879
       * A 16-bit word is received.
1880
       */
1881
0
      if (items->func == NULL) {
1882
        /*
1883
         * We've run out of items in the table;
1884
         * fall back on the default.
1885
         */
1886
0
        offset = add_word_param(tvb, offset, 0, pinfo,
1887
0
            tree, 0, hf_smb_pipe_word_param, smb_info);
1888
0
      } else if (items->type != PARAM_WORD) {
1889
        /*
1890
         * Descriptor character is 'h', but this
1891
         * isn't a word parameter.
1892
         */
1893
0
        WParam = tvb_get_letohs(tvb, offset);
1894
0
        proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, 2,
1895
0
            "%s: Value is %u (0x%04X), type is wrong (W)",
1896
0
            proto_registrar_get_name((*items->hf_index <= 0) ?
1897
0
              hf_smb_pipe_word_param : *items->hf_index),
1898
0
            WParam, WParam);
1899
0
        offset += 2;
1900
0
        items++;
1901
0
      } else {
1902
0
        offset = (*items->func)(tvb, offset, 0, pinfo,
1903
0
            tree, 0, *items->hf_index, smb_info);
1904
0
        items++;
1905
0
      }
1906
0
      break;
1907
1908
0
    case 'i':
1909
      /*
1910
       * A 32-bit doubleword is received.
1911
       */
1912
0
      if (items->func == NULL) {
1913
        /*
1914
         * We've run out of items in the table;
1915
         * fall back on the default.
1916
         */
1917
0
        offset = add_dword_param(tvb, offset, 0, pinfo,
1918
0
            tree, 0, hf_smb_pipe_doubleword_param, smb_info);
1919
0
      } else if (items->type != PARAM_DWORD) {
1920
        /*
1921
         * Descriptor character is 'i', but this
1922
         * isn't a doubleword parameter.
1923
         */
1924
0
        LParam = tvb_get_letohl(tvb, offset);
1925
0
        proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, 2,
1926
0
            "%s: Value is %u (0x%08X), type is wrong (i)",
1927
0
            proto_registrar_get_name((*items->hf_index <= 0) ?
1928
0
              hf_smb_pipe_doubleword_param : *items->hf_index),
1929
0
            LParam, LParam);
1930
0
        offset += 4;
1931
0
        items++;
1932
0
      } else {
1933
0
        offset = (*items->func)(tvb, offset, 0, pinfo,
1934
0
            tree, 0, *items->hf_index, smb_info);
1935
0
        items++;
1936
0
      }
1937
0
      break;
1938
1939
0
    case 'e':
1940
      /*
1941
       * A 16-bit entry count is returned.
1942
       */
1943
0
      WParam = tvb_get_letohs(tvb, offset);
1944
0
      proto_tree_add_uint(tree, hf_ecount, tvb, offset, 2,
1945
0
          WParam);
1946
0
      offset += 2;
1947
0
      *has_ent_count_p = true;
1948
0
      *ent_count_p = WParam;  /* Save this for later retrieval */
1949
0
      break;
1950
1951
0
    default:
1952
0
      break;
1953
0
    }
1954
0
  }
1955
0
  return offset;
1956
0
}
1957
1958
static int
1959
dissect_transact_data(tvbuff_t *tvb, int offset, int convert,
1960
    packet_info *pinfo, proto_tree *tree, const unsigned char *desc,
1961
    const item_t *items, uint16_t *aux_count_p, smb_info_t *smb_info)
1962
0
{
1963
0
  unsigned c;
1964
0
  uint16_t WParam;
1965
0
  uint32_t LParam;
1966
0
  int count;
1967
0
  int cptr;
1968
0
  const char *string;
1969
0
  int string_len = 0;
1970
1971
0
  if (aux_count_p != NULL)
1972
0
    *aux_count_p = 0;
1973
1974
0
  while ((c = *desc++) != '\0') {
1975
0
    switch (c) {
1976
1977
0
    case 'W':
1978
      /*
1979
       * A 16-bit word value.
1980
       * XXX - handle the count?
1981
       */
1982
0
      desc = get_count(desc, &count);
1983
0
      if (items->func == NULL) {
1984
        /*
1985
         * We've run out of items in the table;
1986
         * fall back on the default.
1987
         */
1988
0
        offset = add_word_param(tvb, offset, 0, pinfo,
1989
0
            tree, convert, hf_smb_pipe_word_param, smb_info);
1990
0
      } else if (items->type != PARAM_WORD) {
1991
        /*
1992
         * Descriptor character is 'W', but this
1993
         * isn't a word parameter.
1994
         */
1995
0
        WParam = tvb_get_letohs(tvb, offset);
1996
0
        proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, 2,
1997
0
            "%s: Value is %u (0x%04X), type is wrong (W)",
1998
0
            proto_registrar_get_name((*items->hf_index <= 0) ?
1999
0
              hf_smb_pipe_word_param : *items->hf_index),
2000
0
            WParam, WParam);
2001
0
        offset += 2;
2002
0
        items++;
2003
0
      } else {
2004
0
        offset = (*items->func)(tvb, offset, 0, pinfo,
2005
0
            tree, convert, *items->hf_index, smb_info);
2006
0
        items++;
2007
0
      }
2008
0
      break;
2009
2010
0
    case 'D':
2011
      /*
2012
       * A 32-bit doubleword value.
2013
       * XXX - handle the count?
2014
       */
2015
0
      desc = get_count(desc, &count);
2016
0
      if (items->func == NULL) {
2017
        /*
2018
         * We've run out of items in the table;
2019
         * fall back on the default.
2020
         */
2021
0
        offset = add_dword_param(tvb, offset, 0, pinfo,
2022
0
            tree, convert, hf_smb_pipe_doubleword_param, smb_info);
2023
0
      } else if (items->type != PARAM_DWORD) {
2024
        /*
2025
         * Descriptor character is 'D', but this
2026
         * isn't a doubleword parameter.
2027
         */
2028
0
        LParam = tvb_get_letohl(tvb, offset);
2029
0
        proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, 2,
2030
0
            "%s: Value is %u (0x%08X), type is wrong (D)",
2031
0
            proto_registrar_get_name((*items->hf_index <= 0) ?
2032
0
              hf_smb_pipe_doubleword_param : *items->hf_index),
2033
0
            LParam, LParam);
2034
0
        offset += 4;
2035
0
        items++;
2036
0
      } else {
2037
0
        offset = (*items->func)(tvb, offset, 0, pinfo,
2038
0
            tree, convert, *items->hf_index, smb_info);
2039
0
        items++;
2040
0
      }
2041
0
      break;
2042
2043
0
    case 'B':
2044
      /*
2045
       * A byte or multi-byte value.
2046
       */
2047
0
      desc = get_count(desc, &count);
2048
0
      if (items->func == NULL) {
2049
        /*
2050
         * We've run out of items in the table;
2051
         * fall back on the default.
2052
         */
2053
0
        offset = add_bytes_param(tvb, offset, count,
2054
0
            pinfo, tree, convert, -1, smb_info);
2055
0
      } else if (items->type != PARAM_BYTES) {
2056
        /*
2057
         * Descriptor character is 'B', but this
2058
         * isn't a byte/bytes parameter.
2059
         */
2060
0
        proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, count,
2061
0
            "%s: Value is %s, type is wrong (B)",
2062
0
            proto_registrar_get_name((*items->hf_index <= 0) ?
2063
0
              hf_smb_pipe_bytes_param : *items->hf_index),
2064
0
            tvb_bytes_to_str(pinfo->pool, tvb, offset, count));
2065
0
        offset += count;
2066
0
        items++;
2067
0
      } else {
2068
0
        offset = (*items->func)(tvb, offset, count,
2069
0
            pinfo, tree, convert, *items->hf_index, smb_info);
2070
0
        items++;
2071
0
      }
2072
0
      break;
2073
2074
0
    case 'O':
2075
      /*
2076
       * A null pointer.
2077
       */
2078
0
      if (items->func == NULL) {
2079
        /*
2080
         * We've run out of items in the table;
2081
         * fall back on the default.
2082
         */
2083
0
        add_null_pointer_param(tvb, offset, 0,
2084
0
            pinfo, tree, convert, -1, smb_info);
2085
0
      } else {
2086
        /*
2087
         * If "*items->hf_index" is -1, this is
2088
         * a reserved must-be-null field; don't
2089
         * clutter the protocol tree by putting
2090
         * it in.
2091
         */
2092
0
        if (*items->hf_index > 0) {
2093
0
          add_null_pointer_param(tvb,
2094
0
              offset, 0, pinfo, tree, convert,
2095
0
              *items->hf_index, smb_info);
2096
0
        }
2097
0
        items++;
2098
0
      }
2099
0
      break;
2100
2101
0
    case 'z':
2102
      /*
2103
       * A pointer to a null-terminated ASCII string.
2104
       */
2105
0
      if (items->func == NULL) {
2106
        /*
2107
         * We've run out of items in the table;
2108
         * fall back on the default.
2109
         */
2110
0
        offset = add_stringz_pointer_param(tvb, offset,
2111
0
            0, pinfo, tree, convert, -1, smb_info);
2112
0
      } else if (items->type != PARAM_STRINGZ) {
2113
        /*
2114
         * Descriptor character is 'z', but this
2115
         * isn't a string parameter.
2116
         */
2117
0
        string = get_stringz_pointer_value(pinfo->pool, tvb, offset,
2118
0
            convert, &cptr, &string_len);
2119
0
        offset += 4;
2120
0
        proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, cptr, string_len,
2121
0
            "%s: Value is %s, type is wrong (z)",
2122
0
            proto_registrar_get_name((*items->hf_index <= 0) ?
2123
0
              hf_smb_pipe_string_param : *items->hf_index),
2124
0
            string ? string : "(null)");
2125
0
        items++;
2126
0
      } else {
2127
0
        offset = (*items->func)(tvb, offset, 0,
2128
0
            pinfo, tree, convert, *items->hf_index, smb_info);
2129
0
        items++;
2130
0
      }
2131
0
      break;
2132
2133
0
    case 'b':
2134
      /*
2135
       * A pointer to a byte or multi-byte value.
2136
       */
2137
0
      desc = get_count(desc, &count);
2138
0
      if (items->func == NULL) {
2139
        /*
2140
         * We've run out of items in the table;
2141
         * fall back on the default.
2142
         */
2143
0
        offset = add_bytes_pointer_param(tvb, offset,
2144
0
            count, pinfo, tree, convert, -1, smb_info);
2145
0
      } else if (items->type != PARAM_BYTES) {
2146
        /*
2147
         * Descriptor character is 'b', but this
2148
         * isn't a byte/bytes parameter.
2149
         */
2150
0
        cptr = (tvb_get_letohl(tvb, offset)&0xffff)-convert;
2151
0
        offset += 4;
2152
0
        proto_tree_add_expert_format(tree, pinfo, &ei_smb_pipe_bad_type, tvb, offset, count,
2153
0
            "%s: Value is %s, type is wrong (b)",
2154
0
            proto_registrar_get_name((*items->hf_index <= 0) ?
2155
0
              hf_smb_pipe_bytes_param : *items->hf_index),
2156
0
            tvb_bytes_to_str(pinfo->pool, tvb, cptr, count));
2157
0
        items++;
2158
0
      } else {
2159
0
        offset = (*items->func)(tvb, offset, count,
2160
0
            pinfo, tree, convert, *items->hf_index, smb_info);
2161
0
        items++;
2162
0
      }
2163
0
      break;
2164
2165
0
    case 'N':
2166
      /*
2167
       * 16-bit auxiliary data structure count.
2168
       * XXX - hf_acount?
2169
       */
2170
0
      WParam = tvb_get_letohs(tvb, offset);
2171
0
      proto_tree_add_uint(tree, hf_aux_data_struct_count, tvb, offset, 2, WParam);
2172
0
      offset += 2;
2173
0
      if (aux_count_p != NULL)
2174
0
        *aux_count_p = WParam;  /* Save this for later retrieval */
2175
0
      break;
2176
2177
0
    default:
2178
0
      break;
2179
0
    }
2180
0
  }
2181
0
  return offset;
2182
0
}
2183
2184
static const value_string commands[] = {
2185
  {API_NetShareEnum,      "NetShareEnum"},
2186
  {API_NetShareGetInfo,     "NetShareGetInfo"},
2187
  {API_NetShareSetInfo,     "NetShareSetInfo"},
2188
  {API_NetShareAdd,     "NetShareAdd"},
2189
  {API_NetShareDel,     "NetShareDel"},
2190
  {API_NetShareCheck,     "NetShareCheck"},
2191
  {API_NetSessionEnum,      "NetSessionEnum"},
2192
  {API_NetSessionGetInfo,     "NetSessionGetInfo"},
2193
  {API_NetSessionDel,     "NetSessionDel"},
2194
  {API_WconnectionEnum,     "NetConnectionEnum"},
2195
  {API_NetFileEnum,     "NetFileEnum"},
2196
  {API_NetFileGetInfo,      "NetFileGetInfo"},
2197
  {API_NetFileClose,      "NetFileClose"},
2198
  {API_NetServerGetInfo,      "NetServerGetInfo"},
2199
  {API_NetServerSetInfo,      "NetServerSetInfo"},
2200
  {API_NetServerDiskEnum,     "NetServerDiskEnum"},
2201
  {API_NetServerAdminCommand,   "NetServerAdminCommand"},
2202
  {API_NetAuditOpen,      "NetAuditOpen"},
2203
  {API_NetAuditClear,     "NetAuditClear"},
2204
  {API_NetErrorLogOpen,     "NetErrorLogOpen"},
2205
  {API_NetErrorLogClear,      "NetErrorLogClear"},
2206
  {API_NetCharDevEnum,      "NetCharDevEnum"},
2207
  {API_NetCharDevGetInfo,     "NetCharDevGetInfo"},
2208
  {API_NetCharDevControl,     "NetCharDevControl"},
2209
  {API_NetCharDevQEnum,     "NetCharDevQEnum"},
2210
  {API_NetCharDevQGetInfo,    "NetCharDevQGetInfo"},
2211
  {API_NetCharDevQSetInfo,    "NetCharDevQSetInfo"},
2212
  {API_NetCharDevQPurge,      "NetCharDevQPurge"},
2213
  {API_NetCharDevQPurgeSelf,    "NetCharDevQPurgeSelf"},
2214
  {API_NetMessageNameEnum,    "NetMessageNameEnum"},
2215
  {API_NetMessageNameGetInfo,   "NetMessageNameGetInfo"},
2216
  {API_NetMessageNameAdd,     "NetMessageNameAdd"},
2217
  {API_NetMessageNameDel,     "NetMessageNameDel"},
2218
  {API_NetMessageNameFwd,     "NetMessageNameFwd"},
2219
  {API_NetMessageNameUnFwd,   "NetMessageNameUnFwd"},
2220
  {API_NetMessageBufferSend,    "NetMessageBufferSend"},
2221
  {API_NetMessageFileSend,    "NetMessageFileSend"},
2222
  {API_NetMessageLogFileSet,    "NetMessageLogFileSet"},
2223
  {API_NetMessageLogFileGet,    "NetMessageLogFileGet"},
2224
  {API_NetServiceEnum,      "NetServiceEnum"},
2225
  {API_NetServiceInstall,     "NetServiceInstall"},
2226
  {API_NetServiceControl,     "NetServiceControl"},
2227
  {API_NetAccessEnum,     "NetAccessEnum"},
2228
  {API_NetAccessGetInfo,      "NetAccessGetInfo"},
2229
  {API_NetAccessSetInfo,      "NetAccessSetInfo"},
2230
  {API_NetAccessAdd,      "NetAccessAdd"},
2231
  {API_NetAccessDel,      "NetAccessDel"},
2232
  {API_NetGroupEnum,      "NetGroupEnum"},
2233
  {API_NetGroupAdd,     "NetGroupAdd"},
2234
  {API_NetGroupDel,     "NetGroupDel"},
2235
  {API_NetGroupAddUser,     "NetGroupAddUser"},
2236
  {API_NetGroupDelUser,     "NetGroupDelUser"},
2237
  {API_NetGroupGetUsers,      "NetGroupGetUsers"},
2238
  {API_NetUserEnum,     "NetUserEnum"},
2239
  {API_NetUserAdd,      "NetUserAdd"},
2240
  {API_NetUserDel,      "NetUserDel"},
2241
  {API_NetUserGetInfo,      "NetUserGetInfo"},
2242
  {API_NetUserSetInfo,      "NetUserSetInfo"},
2243
  {API_NetUserPasswordSet,    "NetUserPasswordSet"},
2244
  {API_NetUserGetGroups,      "NetUserGetGroups"},
2245
  {API_NetWkstaSetUID,      "NetWkstaSetUID"},
2246
  {API_NetWkstaGetInfo,     "NetWkstaGetInfo"},
2247
  {API_NetWkstaSetInfo,     "NetWkstaSetInfo"},
2248
  {API_NetUseEnum,      "NetUseEnum"},
2249
  {API_NetUseAdd,       "NetUseAdd"},
2250
  {API_NetUseDel,       "NetUseDel"},
2251
  {API_NetUseGetInfo,     "NetUseGetInfo"},
2252
  {API_WPrintQEnum,     "WPrintQEnum"},
2253
  {API_WPrintQGetInfo,      "WPrintQGetInfo"},
2254
  {API_WPrintQSetInfo,      "WPrintQSetInfo"},
2255
  {API_WPrintQAdd,      "WPrintQAdd"},
2256
  {API_WPrintQDel,      "WPrintQDel"},
2257
  {API_WPrintQPause,      "WPrintQPause"},
2258
  {API_WPrintQContinue,     "WPrintQContinue"},
2259
  {API_WPrintJobEnum,     "WPrintJobEnum"},
2260
  {API_WPrintJobGetInfo,      "WPrintJobGetInfo"},
2261
  {API_WPrintJobSetInfo_OLD,    "WPrintJobSetInfo_OLD"},
2262
  {API_WPrintJobDel,      "WPrintJobDel"},
2263
  {API_WPrintJobPause,      "WPrintJobPause"},
2264
  {API_WPrintJobContinue,     "WPrintJobContinue"},
2265
  {API_WPrintDestEnum,      "WPrintDestEnum"},
2266
  {API_WPrintDestGetInfo,     "WPrintDestGetInfo"},
2267
  {API_WPrintDestControl,     "WPrintDestControl"},
2268
  {API_NetProfileSave,      "NetProfileSave"},
2269
  {API_NetProfileLoad,      "NetProfileLoad"},
2270
  {API_NetStatisticsGet,      "NetStatisticsGet"},
2271
  {API_NetStatisticsClear,    "NetStatisticsClear"},
2272
  {API_NetRemoteTOD,      "NetRemoteTOD"},
2273
  {API_WNetBiosEnum,      "WNetBiosEnum"},
2274
  {API_WNetBiosGetInfo,     "WNetBiosGetInfo"},
2275
  {API_NetServerEnum,     "NetServerEnum"},
2276
  {API_I_NetServerEnum,     "I_NetServerEnum"},
2277
  {API_NetServiceGetInfo,     "NetServiceGetInfo"},
2278
  {API_WPrintQPurge,      "WPrintQPurge"},
2279
  {API_NetServerEnum2,      "NetServerEnum2"},
2280
  {API_NetAccessGetUserPerms,   "NetAccessGetUserPerms"},
2281
  {API_NetGroupGetInfo,     "NetGroupGetInfo"},
2282
  {API_NetGroupSetInfo,     "NetGroupSetInfo"},
2283
  {API_NetGroupSetUsers,      "NetGroupSetUsers"},
2284
  {API_NetUserSetGroups,      "NetUserSetGroups"},
2285
  {API_NetUserModalsGet,      "NetUserModalsGet"},
2286
  {API_NetUserModalsSet,      "NetUserModalsSet"},
2287
  {API_NetFileEnum2,      "NetFileEnum2"},
2288
  {API_NetUserAdd2,     "NetUserAdd2"},
2289
  {API_NetUserSetInfo2,     "NetUserSetInfo2"},
2290
  {API_NetUserPasswordSet2,   "SetUserPassword"},
2291
  {API_I_NetServerEnum2,      "I_NetServerEnum2"},
2292
  {API_NetConfigGet2,     "NetConfigGet2"},
2293
  {API_NetConfigGetAll2,      "NetConfigGetAll2"},
2294
  {API_NetGetDCName,      "NetGetDCName"},
2295
  {API_NetHandleGetInfo,      "NetHandleGetInfo"},
2296
  {API_NetHandleSetInfo,      "NetHandleSetInfo"},
2297
  {API_NetStatisticsGet2,     "NetStatisticsGet2"},
2298
  {API_WBuildGetInfo,     "WBuildGetInfo"},
2299
  {API_NetFileGetInfo2,     "NetFileGetInfo2"},
2300
  {API_NetFileClose2,     "NetFileClose2"},
2301
  {API_NetServerReqChallenge,   "NetServerReqChallenge"},
2302
  {API_NetServerAuthenticate,   "NetServerAuthenticate"},
2303
  {API_NetServerPasswordSet,    "NetServerPasswordSet"},
2304
  {API_WNetAccountDeltas,     "WNetAccountDeltas"},
2305
  {API_WNetAccountSync,     "WNetAccountSync"},
2306
  {API_NetUserEnum2,      "NetUserEnum2"},
2307
  {API_NetWkstaUserLogon,     "NetWkstaUserLogon"},
2308
  {API_NetWkstaUserLogoff,    "NetWkstaUserLogoff"},
2309
  {API_NetLogonEnum,      "NetLogonEnum"},
2310
  {API_NetErrorLogRead,     "NetErrorLogRead"},
2311
  {API_I_NetPathType,     "I_NetPathType"},
2312
  {API_I_NetPathCanonicalize,   "I_NetPathCanonicalize"},
2313
  {API_I_NetPathCompare,      "I_NetPathCompare"},
2314
  {API_I_NetNameValidate,     "I_NetNameValidate"},
2315
  {API_I_NetNameCanonicalize,   "I_NetNameCanonicalize"},
2316
  {API_I_NetNameCompare,      "I_NetNameCompare"},
2317
  {API_NetAuditRead,      "NetAuditRead"},
2318
  {API_WPrintDestAdd,     "WPrintDestAdd"},
2319
  {API_WPrintDestSetInfo,     "WPrintDestSetInfo"},
2320
  {API_WPrintDestDel,     "WPrintDestDel"},
2321
  {API_NetUserValidate2,      "NetUserValidate2"},
2322
  {API_WPrintJobSetInfo,      "WPrintJobSetInfo"},
2323
  {API_TI_NetServerDiskEnum,    "TI_NetServerDiskEnum"},
2324
  {API_TI_NetServerDiskGetInfo,   "TI_NetServerDiskGetInfo"},
2325
  {API_TI_FTVerifyMirror,     "TI_FTVerifyMirror"},
2326
  {API_TI_FTAbortVerify,      "TI_FTAbortVerify"},
2327
  {API_TI_FTGetInfo,      "TI_FTGetInfo"},
2328
  {API_TI_FTSetInfo,      "TI_FTSetInfo"},
2329
  {API_TI_FTLockDisk,     "TI_FTLockDisk"},
2330
  {API_TI_FTFixError,     "TI_FTFixError"},
2331
  {API_TI_FTAbortFix,     "TI_FTAbortFix"},
2332
  {API_TI_FTDiagnoseError,    "TI_FTDiagnoseError"},
2333
  {API_TI_FTGetDriveStats,    "TI_FTGetDriveStats"},
2334
  {API_TI_FTErrorGetInfo,     "TI_FTErrorGetInfo"},
2335
  {API_NetAccessCheck,      "NetAccessCheck"},
2336
  {API_NetAlertRaise,     "NetAlertRaise"},
2337
  {API_NetAlertStart,     "NetAlertStart"},
2338
  {API_NetAlertStop,      "NetAlertStop"},
2339
  {API_NetAuditWrite,     "NetAuditWrite"},
2340
  {API_NetIRemoteAPI,     "NetIRemoteAPI"},
2341
  {API_NetServiceStatus,      "NetServiceStatus"},
2342
  {API_I_NetServerRegister,   "I_NetServerRegister"},
2343
  {API_I_NetServerDeregister,   "I_NetServerDeregister"},
2344
  {API_I_NetSessionEntryMake,   "I_NetSessionEntryMake"},
2345
  {API_I_NetSessionEntryClear,    "I_NetSessionEntryClear"},
2346
  {API_I_NetSessionEntryGetInfo,    "I_NetSessionEntryGetInfo"},
2347
  {API_I_NetSessionEntrySetInfo,    "I_NetSessionEntrySetInfo"},
2348
  {API_I_NetConnectionEntryMake,    "I_NetConnectionEntryMake"},
2349
  {API_I_NetConnectionEntryClear,   "I_NetConnectionEntryClear"},
2350
  {API_I_NetConnectionEntrySetInfo, "I_NetConnectionEntrySetInfo"},
2351
  {API_I_NetConnectionEntryGetInfo, "I_NetConnectionEntryGetInfo"},
2352
  {API_I_NetFileEntryMake,    "I_NetFileEntryMake"},
2353
  {API_I_NetFileEntryClear,   "I_NetFileEntryClear"},
2354
  {API_I_NetFileEntrySetInfo,   "I_NetFileEntrySetInfo"},
2355
  {API_I_NetFileEntryGetInfo,   "I_NetFileEntryGetInfo"},
2356
  {API_AltSrvMessageBufferSend,   "AltSrvMessageBufferSend"},
2357
  {API_AltSrvMessageFileSend,   "AltSrvMessageFileSend"},
2358
  {API_wI_NetRplWkstaEnum,    "wI_NetRplWkstaEnum"},
2359
  {API_wI_NetRplWkstaGetInfo,   "wI_NetRplWkstaGetInfo"},
2360
  {API_wI_NetRplWkstaSetInfo,   "wI_NetRplWkstaSetInfo"},
2361
  {API_wI_NetRplWkstaAdd,     "wI_NetRplWkstaAdd"},
2362
  {API_wI_NetRplWkstaDel,     "wI_NetRplWkstaDel"},
2363
  {API_wI_NetRplProfileEnum,    "wI_NetRplProfileEnum"},
2364
  {API_wI_NetRplProfileGetInfo,   "wI_NetRplProfileGetInfo"},
2365
  {API_wI_NetRplProfileSetInfo,   "wI_NetRplProfileSetInfo"},
2366
  {API_wI_NetRplProfileAdd,   "wI_NetRplProfileAdd"},
2367
  {API_wI_NetRplProfileDel,   "wI_NetRplProfileDel"},
2368
  {API_wI_NetRplProfileClone,   "wI_NetRplProfileClone"},
2369
  {API_wI_NetRplBaseProfileEnum,    "wI_NetRplBaseProfileEnum"},
2370
  {API_WIServerSetInfo,     "WIServerSetInfo"},
2371
  {API_WPrintDriverEnum,      "WPrintDriverEnum"},
2372
  {API_WPrintQProcessorEnum,    "WPrintQProcessorEnum"},
2373
  {API_WPrintPortEnum,      "WPrintPortEnum"},
2374
  {API_WNetWriteUpdateLog,    "WNetWriteUpdateLog"},
2375
  {API_WNetAccountUpdate,     "WNetAccountUpdate"},
2376
  {API_WNetAccountConfirmUpdate,    "WNetAccountConfirmUpdate"},
2377
  {API_NetConfigSet,      "NetConfigSet"},
2378
  {API_WAccountsReplicate,    "WAccountsReplicate"},
2379
  {API_SamOEMChgPasswordUser2_P,    "SamOEMChangePassword"},
2380
  {API_NetServerEnum3,      "NetServerEnum3"},
2381
  {API_WPrintDriverGetInfo,   "WPrintDriverGetInfo"},
2382
  {API_WPrintDriverSetInfo,   "WPrintDriverSetInfo"},
2383
  {API_NetAliasAdd,     "NetAliasAdd"},
2384
  {API_NetAliasDel,     "NetAliasDel"},
2385
  {API_NetAliasGetInfo,     "NetAliasGetInfo"},
2386
  {API_NetAliasSetInfo,     "NetAliasSetInfo"},
2387
  {API_NetAliasEnum,      "NetAliasEnum"},
2388
  {API_NetUserGetLogonAsn,    "NetUserGetLogonAsn"},
2389
  {API_NetUserSetLogonAsn,    "NetUserSetLogonAsn"},
2390
  {API_NetUserGetAppSel,      "NetUserGetAppSel"},
2391
  {API_NetUserSetAppSel,      "NetUserSetAppSel"},
2392
  {API_NetAppAdd,       "NetAppAdd"},
2393
  {API_NetAppDel,       "NetAppDel"},
2394
  {API_NetAppGetInfo,     "NetAppGetInfo"},
2395
  {API_NetAppSetInfo,     "NetAppSetInfo"},
2396
  {API_NetAppEnum,      "NetAppEnum"},
2397
  {API_NetUserDCDBInit,     "NetUserDCDBInit"},
2398
  {API_NetDASDAdd,      "NetDASDAdd"},
2399
  {API_NetDASDDel,      "NetDASDDel"},
2400
  {API_NetDASDGetInfo,      "NetDASDGetInfo"},
2401
  {API_NetDASDSetInfo,      "NetDASDSetInfo"},
2402
  {API_NetDASDEnum,     "NetDASDEnum"},
2403
  {API_NetDASDCheck,      "NetDASDCheck"},
2404
  {API_NetDASDCtl,      "NetDASDCtl"},
2405
  {API_NetUserRemoteLogonCheck,   "NetUserRemoteLogonCheck"},
2406
  {API_NetUserPasswordSet3,   "NetUserPasswordSet3"},
2407
  {API_NetCreateRIPLMachine,    "NetCreateRIPLMachine"},
2408
  {API_NetDeleteRIPLMachine,    "NetDeleteRIPLMachine"},
2409
  {API_NetGetRIPLMachineInfo,   "NetGetRIPLMachineInfo"},
2410
  {API_NetSetRIPLMachineInfo,   "NetSetRIPLMachineInfo"},
2411
  {API_NetEnumRIPLMachine,    "NetEnumRIPLMachine"},
2412
  {API_I_ShareAdd,      "I_ShareAdd"},
2413
  {API_I_AliasEnum,     "I_AliasEnum"},
2414
  {API_NetAccessApply,      "NetAccessApply"},
2415
  {API_WPrt16Query,     "WPrt16Query"},
2416
  {API_WPrt16Set,       "WPrt16Set"},
2417
  {API_NetUserDel100,     "NetUserDel100"},
2418
  {API_NetUserRemoteLogonCheck2,    "NetUserRemoteLogonCheck2"},
2419
  {API_WRemoteTODSet,     "WRemoteTODSet"},
2420
  {API_WPrintJobMoveAll,      "WPrintJobMoveAll"},
2421
  {API_W16AppParmAdd,     "W16AppParmAdd"},
2422
  {API_W16AppParmDel,     "W16AppParmDel"},
2423
  {API_W16AppParmGet,     "W16AppParmGet"},
2424
  {API_W16AppParmSet,     "W16AppParmSet"},
2425
  {API_W16RIPLMachineCreate,    "W16RIPLMachineCreate"},
2426
  {API_W16RIPLMachineGetInfo,   "W16RIPLMachineGetInfo"},
2427
  {API_W16RIPLMachineSetInfo,   "W16RIPLMachineSetInfo"},
2428
  {API_W16RIPLMachineEnum,    "W16RIPLMachineEnum"},
2429
  {API_W16RIPLMachineListParmEnum,  "W16RIPLMachineListParmEnum"},
2430
  {API_W16RIPLMachClassGetInfo,   "W16RIPLMachClassGetInfo"},
2431
  {API_W16RIPLMachClassEnum,    "W16RIPLMachClassEnum"},
2432
  {API_W16RIPLMachClassCreate,    "W16RIPLMachClassCreate"},
2433
  {API_W16RIPLMachClassSetInfo,   "W16RIPLMachClassSetInfo"},
2434
  {API_W16RIPLMachClassDelete,    "W16RIPLMachClassDelete"},
2435
  {API_W16RIPLMachClassLPEnum,    "W16RIPLMachClassLPEnum"},
2436
  {API_W16RIPLMachineDelete,    "W16RIPLMachineDelete"},
2437
  {API_W16WSLevelGetInfo,     "W16WSLevelGetInfo"},
2438
  {API_NetServerNameAdd,      "NetServerNameAdd"},
2439
  {API_NetServerNameDel,      "NetServerNameDel"},
2440
  {API_NetServerNameEnum,     "NetServerNameEnum"},
2441
  {API_I_WDASDEnum,     "I_WDASDEnum"},
2442
  {API_I_WDASDEnumTerminate,    "I_WDASDEnumTerminate"},
2443
  {API_I_WDASDSetInfo2,     "I_WDASDSetInfo2"},
2444
  {0,         NULL}
2445
};
2446
2447
static value_string_ext commands_ext = VALUE_STRING_EXT_INIT(commands);
2448
2449
static void
2450
dissect_response_data(tvbuff_t *tvb, packet_info *pinfo, int convert,
2451
    proto_tree *tree, smb_info_t *smb_info,
2452
    const struct lanman_desc *lanman, bool has_ent_count,
2453
    uint16_t ent_count)
2454
0
{
2455
0
  smb_transact_info_t *trp;
2456
0
  const item_list_t *resp_data_list;
2457
0
  int offset, start_offset;
2458
0
  const char *label;
2459
0
  int ett;
2460
0
  const item_t *resp_data;
2461
0
  proto_item *data_item = NULL;
2462
0
  proto_tree *data_tree = NULL;
2463
0
  proto_item *entry_item;
2464
0
  proto_tree *entry_tree;
2465
0
  unsigned i, j;
2466
0
  uint16_t aux_count;
2467
2468
0
  trp = (smb_transact_info_t *)smb_info->sip->extra_info;
2469
2470
  /*
2471
   * Find the item table for the matching request's detail level.
2472
   */
2473
0
  for (resp_data_list = lanman->resp_data_list;
2474
0
      resp_data_list->level != -1; resp_data_list++) {
2475
0
    if (resp_data_list->level == trp->info_level)
2476
0
      break;
2477
0
  }
2478
0
  resp_data = resp_data_list->item_list;
2479
2480
0
  offset = 0;
2481
0
  if (has_ent_count) {
2482
    /*
2483
     * The data is a list of entries; create a protocol tree item
2484
     * for it.
2485
     */
2486
0
    if (tree) {
2487
0
      label = lanman->resp_data_entry_list_label;
2488
0
      if (label == NULL)
2489
0
        label = "Entries";
2490
0
      if (lanman->ett_data_entry_list != NULL)
2491
0
        ett = *lanman->ett_data_entry_list;
2492
0
      else
2493
0
        ett = ett_lanman_unknown_entries;
2494
2495
0
      data_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett, &data_item, label);
2496
0
    }
2497
0
  }
2498
2499
0
  if (trp->data_descrip == NULL) {
2500
    /*
2501
     * This could happen if we only dissected
2502
     * part of the request to which this is a
2503
     * reply, e.g. if the request was split
2504
     * across TCP segments and we weren't doing
2505
     * TCP desegmentation, or if we had a snapshot
2506
     * length that was too short.
2507
     *
2508
     * We can't dissect the data; just show it as raw data or,
2509
     * if we've already created a top-level item, note that
2510
     * no descriptor is available.
2511
     */
2512
0
    if (has_ent_count) {
2513
0
      if (data_item != NULL) {
2514
0
        proto_item_append_text(data_item,
2515
0
            " (No descriptor available)");
2516
0
      }
2517
0
    } else {
2518
0
      proto_tree_add_item(data_tree, hf_data_no_descriptor, tvb, offset, -1, ENC_NA);
2519
0
    }
2520
0
    offset += tvb_captured_length_remaining(tvb, offset);
2521
0
  } else {
2522
    /*
2523
     * If we have an entry count, show all the entries,
2524
     * with each one having a protocol tree item.
2525
     *
2526
     * Otherwise, we just show one returned item, with
2527
     * no protocol tree item.
2528
     */
2529
0
    if (!has_ent_count)
2530
0
      ent_count = 1;
2531
0
    for (i = 0; i < ent_count; i++) {
2532
0
      start_offset = offset;
2533
0
      if (has_ent_count &&
2534
0
          lanman->resp_data_element_item != NULL) {
2535
        /*
2536
         * Create a protocol tree item for the
2537
         * entry.
2538
         */
2539
0
        entry_item =
2540
0
            (*lanman->resp_data_element_item)
2541
0
              (tvb, data_tree, offset);
2542
0
        entry_tree = proto_item_add_subtree(
2543
0
            entry_item,
2544
0
            *lanman->ett_resp_data_element_item);
2545
0
      } else {
2546
        /*
2547
         * Just leave it at the current
2548
         * level.
2549
         */
2550
0
        entry_item = NULL;
2551
0
        entry_tree = data_tree;
2552
0
      }
2553
2554
0
      offset = dissect_transact_data(tvb, offset,
2555
0
          convert, pinfo, entry_tree,
2556
0
          trp->data_descrip, resp_data, &aux_count, smb_info);
2557
2558
      /* auxiliary data */
2559
0
      if (trp->aux_data_descrip != NULL) {
2560
0
        for (j = 0; j < aux_count; j++) {
2561
0
          offset = dissect_transact_data(
2562
0
              tvb, offset, convert,
2563
0
              pinfo, entry_tree,
2564
0
              trp->data_descrip,
2565
0
              lanman->resp_aux_data, NULL, smb_info);
2566
0
        }
2567
0
      }
2568
2569
0
      if (entry_item != NULL) {
2570
        /*
2571
         * Set the length of the protocol tree
2572
         * item for the entry.
2573
         */
2574
0
        proto_item_set_len(entry_item,
2575
0
            offset - start_offset);
2576
0
      }
2577
0
    }
2578
0
  }
2579
2580
0
  if (data_item != NULL) {
2581
    /*
2582
     * Set the length of the protocol tree item
2583
     * for the data.
2584
     */
2585
0
    proto_item_set_len(data_item, offset);
2586
0
  }
2587
0
}
2588
2589
static bool
2590
dissect_pipe_lanman(tvbuff_t *pd_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
2591
        packet_info *pinfo, proto_tree *parent_tree, smb_info_t *smb_info)
2592
0
{
2593
0
  smb_transact_info_t *trp = NULL;
2594
0
  int offset = 0/*, start_offset*/;
2595
0
  uint16_t cmd;
2596
0
  uint16_t status;
2597
0
  int convert;
2598
0
  const struct lanman_desc *lanman;
2599
0
  proto_item *item = NULL;
2600
0
  proto_tree *tree = NULL;
2601
0
  unsigned descriptor_len;
2602
0
  const char *param_descrip, *data_descrip, *aux_data_descrip = NULL;
2603
0
  bool has_data;
2604
0
  bool has_ent_count;
2605
0
  uint16_t ent_count = 0, aux_count;
2606
0
  unsigned i;
2607
0
  proto_item *data_item;
2608
0
  proto_tree *data_tree;
2609
2610
0
  if (smb_info->sip->extra_info_type == SMB_EI_TRI)
2611
0
    trp = (smb_transact_info_t *)smb_info->sip->extra_info;
2612
2613
0
  if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_lanman)))
2614
0
    return false;
2615
0
  if (p_tvb == NULL) {
2616
    /*
2617
     * Requests must have parameters.
2618
     */
2619
0
    return false;
2620
0
  }
2621
0
  pinfo->current_proto = "LANMAN";
2622
2623
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "LANMAN");
2624
2625
0
  if (parent_tree) {
2626
0
    item = proto_tree_add_item(parent_tree, proto_smb_lanman,
2627
0
      pd_tvb, 0, -1, ENC_NA);
2628
0
    tree = proto_item_add_subtree(item, ett_lanman);
2629
0
  }
2630
2631
0
  if (smb_info->request) { /* this is a request */
2632
    /* function code */
2633
0
    cmd = tvb_get_letohs(p_tvb, offset);
2634
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "%s Request", val_to_str_ext(cmd, &commands_ext, "Unknown Command (%u)"));
2635
2636
0
    proto_tree_add_uint(tree, hf_function_code, p_tvb, offset, 2,
2637
0
        cmd);
2638
0
    offset += 2;
2639
2640
0
    if(!trp){
2641
0
      return false; /* can't dissect this request */
2642
0
    }
2643
2644
    /*
2645
     * If we haven't already done so, save the function code in
2646
     * the structure we were handed, so that it's available to
2647
     * the code parsing the reply, and initialize the detail
2648
     * level to -1, meaning "unknown".
2649
     */
2650
0
    if (!pinfo->fd->visited) {
2651
0
      trp->lanman_cmd = cmd;
2652
0
      trp->info_level = -1;
2653
0
      trp->param_descrip=NULL;
2654
0
      trp->data_descrip=NULL;
2655
0
      trp->aux_data_descrip=NULL;
2656
0
    }
2657
2658
    /* parameter descriptor */
2659
0
    param_descrip = tvb_get_stringz_enc(pinfo->pool, p_tvb, offset, &descriptor_len, ENC_ASCII);
2660
0
    proto_tree_add_string(tree, hf_param_desc, p_tvb, offset, descriptor_len, param_descrip);
2661
0
    if (!pinfo->fd->visited) {
2662
      /*
2663
       * Save the parameter descriptor for future use.
2664
       */
2665
0
      DISSECTOR_ASSERT(trp->param_descrip == NULL);
2666
0
      trp->param_descrip = wmem_strdup(wmem_file_scope(), param_descrip);
2667
0
    }
2668
0
    offset += descriptor_len;
2669
2670
    /* return descriptor */
2671
0
    data_descrip = tvb_get_stringz_enc(pinfo->pool, p_tvb, offset, &descriptor_len, ENC_ASCII);
2672
0
    proto_tree_add_string(tree, hf_return_desc, p_tvb, offset, descriptor_len, data_descrip);
2673
0
    if (!pinfo->fd->visited) {
2674
      /*
2675
       * Save the return descriptor for future use.
2676
       */
2677
0
      DISSECTOR_ASSERT(trp->data_descrip == NULL);
2678
0
      trp->data_descrip = wmem_strdup(wmem_file_scope(), data_descrip);
2679
0
    }
2680
0
    offset += descriptor_len;
2681
2682
0
    lanman = find_lanman(cmd);
2683
2684
    /* request parameters */
2685
    /*start_offset = offset;*/
2686
0
    offset = dissect_request_parameters(p_tvb, offset, pinfo, tree,
2687
0
        param_descrip, lanman->req, &has_data, smb_info);
2688
2689
    /* auxiliary data descriptor */
2690
0
    if (tvb_reported_length_remaining(p_tvb, offset) > 0){
2691
      /*
2692
       * There are more parameters left, so the next
2693
       * item is the auxiliary data descriptor.
2694
       */
2695
0
      aux_data_descrip = tvb_get_stringz_enc(pinfo->pool, p_tvb, offset, &descriptor_len, ENC_ASCII);
2696
0
      proto_tree_add_string(tree, hf_aux_data_desc, p_tvb, offset, descriptor_len, aux_data_descrip);
2697
0
      if (!pinfo->fd->visited) {
2698
        /*
2699
         * Save the auxiliary data descriptor for
2700
         * future use.
2701
         */
2702
0
        DISSECTOR_ASSERT(trp->aux_data_descrip == NULL);
2703
0
        trp->aux_data_descrip =
2704
0
            wmem_strdup(wmem_file_scope(), aux_data_descrip);
2705
0
      }
2706
0
    }
2707
2708
    /* reset offset, we now start dissecting the data area */
2709
0
    offset = 0;
2710
0
    if (has_data && d_tvb && tvb_reported_length(d_tvb) != 0) {
2711
      /*
2712
       * There's a send buffer item in the descriptor
2713
       * string, and the data count in the transaction
2714
       * is non-zero, so there's data to dissect.
2715
       */
2716
2717
0
      if (lanman->req_data_item != NULL) {
2718
        /*
2719
         * Create a protocol tree item for the data.
2720
         */
2721
0
        data_item = (*lanman->req_data_item)(d_tvb,
2722
0
            pinfo, tree, offset);
2723
0
        data_tree = proto_item_add_subtree(data_item,
2724
0
            *lanman->ett_req_data);
2725
0
      } else {
2726
        /*
2727
         * Just leave it at the top level.
2728
         */
2729
0
        data_item = NULL;
2730
0
        data_tree = tree;
2731
0
      }
2732
2733
      /* data */
2734
0
      offset = dissect_transact_data(d_tvb, offset, -1,
2735
0
          pinfo, data_tree, data_descrip, lanman->req_data,
2736
0
          &aux_count, smb_info);  /* XXX - what about strings? */
2737
2738
      /* auxiliary data */
2739
0
      if (aux_data_descrip != NULL) {
2740
0
        for (i = 0; i < aux_count; i++) {
2741
0
          offset = dissect_transact_data(d_tvb,
2742
0
              offset, -1, pinfo, data_tree,
2743
0
              aux_data_descrip,
2744
0
              lanman->req_aux_data, NULL, smb_info);
2745
0
        }
2746
0
      }
2747
2748
0
      if (data_item != NULL) {
2749
        /*
2750
         * Set the length of the protocol tree item
2751
         * for the data.
2752
         */
2753
0
        proto_item_set_len(data_item, offset);
2754
0
      }
2755
0
    }
2756
0
  } else {
2757
    /*
2758
     * This is a response.
2759
     * Have we seen the request to which it's a response?
2760
     */
2761
0
    if (trp == NULL)
2762
0
      return false; /* no - can't dissect it */
2763
2764
    /* ok we have seen this one before */
2765
2766
    /* if it looks like an interim response, update COL_INFO and return */
2767
0
    if( ( tvb_reported_length(p_tvb)==0 )
2768
0
    &&  ( tvb_reported_length(d_tvb)==0 ) ){
2769
      /* command */
2770
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "%s Interim Response",
2771
0
               val_to_str_ext(trp->lanman_cmd, &commands_ext, "Unknown Command (%u)"));
2772
2773
0
      proto_tree_add_uint(tree, hf_function_code, p_tvb, 0, 0, trp->lanman_cmd);
2774
0
      return true;
2775
0
    }
2776
2777
    /* command */
2778
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "%s Response",
2779
0
             val_to_str_ext(trp->lanman_cmd, &commands_ext, "Unknown Command (%u)"));
2780
2781
0
    proto_tree_add_uint(tree, hf_function_code, p_tvb, 0, 0,
2782
0
        trp->lanman_cmd);
2783
2784
0
    lanman = find_lanman(trp->lanman_cmd);
2785
2786
    /* response parameters */
2787
2788
    /* status */
2789
0
    status = tvb_get_letohs(p_tvb, offset);
2790
0
    proto_tree_add_uint(tree, hf_status, p_tvb, offset, 2, status);
2791
0
    offset += 2;
2792
2793
    /* convert */
2794
0
    convert = tvb_get_letohs(p_tvb, offset);
2795
0
    proto_tree_add_uint(tree, hf_convert, p_tvb, offset, 2, convert);
2796
0
    offset += 2;
2797
2798
0
    if (trp->param_descrip == NULL) {
2799
      /*
2800
       * This could happen if we only dissected
2801
       * part of the request to which this is a
2802
       * reply, e.g. if the request was split
2803
       * across TCP segments and we weren't doing
2804
       * TCP desegmentation, or if we had a snapshot
2805
       * length that was too short.
2806
       *
2807
       * We can't dissect the parameters; just show them
2808
       * as raw data.
2809
       */
2810
0
      proto_tree_add_item(tree, hf_param_no_descriptor, p_tvb, offset, -1, ENC_NA);
2811
2812
      /*
2813
       * We don't know whether we have a receive buffer,
2814
       * as we don't have the descriptor; just show what
2815
       * bytes purport to be data.
2816
       */
2817
0
      if (d_tvb && tvb_reported_length(d_tvb) > 0) {
2818
0
        proto_tree_add_item(tree, hf_data_no_descriptor, d_tvb, 0, -1, ENC_NA);
2819
0
      }
2820
0
    } else {
2821
      /* rest of the parameters */
2822
0
      dissect_response_parameters(p_tvb, offset,
2823
0
          pinfo, tree, trp->param_descrip, lanman->resp,
2824
0
          &has_data, &has_ent_count, &ent_count, smb_info);
2825
2826
      /* data */
2827
0
      if (d_tvb && tvb_reported_length(d_tvb) > 0) {
2828
        /*
2829
         * Well, there are bytes that purport to
2830
         * be data, at least.
2831
         */
2832
0
        if (has_data) {
2833
          /*
2834
           * There's a receive buffer item
2835
           * in the descriptor string, so
2836
           * dissect it as response data.
2837
           */
2838
0
          dissect_response_data(d_tvb, pinfo,
2839
0
              convert, tree, smb_info, lanman,
2840
0
              has_ent_count, ent_count);
2841
0
        } else {
2842
          /*
2843
           * There's no receive buffer item,
2844
           * but we do have data, so just
2845
           * show what bytes are data.
2846
           */
2847
0
          proto_tree_add_item(tree, hf_data_no_recv_buffer, d_tvb, 0, -1, ENC_NA);
2848
0
        }
2849
0
      }
2850
0
    }
2851
0
  }
2852
2853
0
  return true;
2854
0
}
2855
2856
void
2857
proto_register_pipe_lanman(void)
2858
14
{
2859
14
  static hf_register_info hf[] = {
2860
14
    { &hf_function_code,
2861
14
      { "Function Code", "lanman.function_code", FT_UINT16, BASE_DEC|BASE_EXT_STRING,
2862
14
      &commands_ext, 0, "LANMAN Function Code/Command", HFILL }},
2863
2864
14
    { &hf_param_desc,
2865
14
      { "Parameter Descriptor", "lanman.param_desc", FT_STRING, BASE_NONE,
2866
14
      NULL, 0, "LANMAN Parameter Descriptor", HFILL }},
2867
2868
14
    { &hf_return_desc,
2869
14
      { "Return Descriptor", "lanman.ret_desc", FT_STRING, BASE_NONE,
2870
14
      NULL, 0, "LANMAN Return Descriptor", HFILL }},
2871
2872
14
    { &hf_aux_data_desc,
2873
14
      { "Auxiliary Data Descriptor", "lanman.aux_data_desc", FT_STRING, BASE_NONE,
2874
14
      NULL, 0, "LANMAN Auxiliary Data Descriptor", HFILL }},
2875
2876
14
    { &hf_detail_level,
2877
14
      { "Detail Level", "lanman.level", FT_UINT16, BASE_DEC,
2878
14
      NULL, 0, "LANMAN Detail Level", HFILL }},
2879
2880
14
    { &hf_padding,
2881
14
      { "Padding", "lanman.padding", FT_BYTES, BASE_NONE,
2882
14
      NULL, 0, NULL, HFILL }},
2883
2884
14
    { &hf_recv_buf_len,
2885
14
      { "Receive Buffer Length", "lanman.recv_buf_len", FT_UINT16, BASE_DEC,
2886
14
      NULL, 0, "LANMAN Receive Buffer Length", HFILL }},
2887
2888
14
    { &hf_send_buf_len,
2889
14
      { "Send Buffer Length", "lanman.send_buf_len", FT_UINT16, BASE_DEC,
2890
14
      NULL, 0, "LANMAN Send Buffer Length", HFILL }},
2891
2892
#if 0
2893
    { &hf_continuation_from,
2894
      { "Continuation from message in frame", "lanman.continuation_from", FT_UINT32, BASE_DEC,
2895
      NULL, 0, "This is a LANMAN continuation from the message in the frame in question", HFILL }},
2896
#endif
2897
2898
14
    { &hf_status,
2899
14
      { "Status", "lanman.status", FT_UINT16, BASE_DEC,
2900
14
      VALS(status_vals), 0, "LANMAN Return status", HFILL }},
2901
2902
14
    { &hf_convert,
2903
14
      { "Convert", "lanman.convert", FT_UINT16, BASE_DEC,
2904
14
      NULL, 0, "LANMAN Convert", HFILL }},
2905
2906
14
    { &hf_param_no_descriptor,
2907
14
      { "Parameters (no descriptor available)", "lanman.param_no_descriptor", FT_BYTES, BASE_NONE,
2908
14
      NULL, 0, NULL, HFILL }},
2909
2910
14
    { &hf_data_no_descriptor,
2911
14
      { "Data (no descriptor available)", "lanman.data_no_descriptor", FT_BYTES, BASE_NONE,
2912
14
      NULL, 0, NULL, HFILL }},
2913
2914
14
    { &hf_data_no_recv_buffer,
2915
14
      { "Data (no receive buffer)", "lanman.data_no_recv_buffer", FT_BYTES, BASE_NONE,
2916
14
      NULL, 0, NULL, HFILL }},
2917
2918
14
    { &hf_ecount,
2919
14
      { "Entry Count", "lanman.entry_count", FT_UINT16, BASE_DEC,
2920
14
      NULL, 0, "LANMAN Number of Entries", HFILL }},
2921
2922
14
    { &hf_acount,
2923
14
      { "Available Entries", "lanman.available_count", FT_UINT16, BASE_DEC,
2924
14
      NULL, 0, "LANMAN Number of Available Entries", HFILL }},
2925
2926
14
    { &hf_share,
2927
14
      { "Share", "lanman.share", FT_NONE, BASE_NONE,
2928
14
      NULL, 0, NULL, HFILL }},
2929
2930
14
    { &hf_share_name,
2931
14
      { "Share Name", "lanman.share.name", FT_STRING, BASE_NONE,
2932
14
      NULL, 0, "LANMAN Name of Share", HFILL }},
2933
2934
14
    { &hf_share_type,
2935
14
      { "Share Type", "lanman.share.type", FT_UINT16, BASE_DEC,
2936
14
      VALS(share_type_vals), 0, "LANMAN Type of Share", HFILL }},
2937
2938
14
    { &hf_share_comment,
2939
14
      { "Share Comment", "lanman.share.comment", FT_STRING, BASE_NONE,
2940
14
      NULL, 0, "LANMAN Share Comment", HFILL }},
2941
2942
14
    { &hf_share_permissions,
2943
14
      { "Share Permissions", "lanman.share.permissions", FT_UINT16, BASE_DEC,
2944
14
      NULL, 0, "LANMAN Permissions on share", HFILL }},
2945
2946
14
    { &hf_share_max_uses,
2947
14
      { "Share Max Uses", "lanman.share.max_uses", FT_UINT16, BASE_DEC,
2948
14
      NULL, 0, "LANMAN Max connections allowed to share", HFILL }},
2949
2950
14
    { &hf_share_current_uses,
2951
14
      { "Share Current Uses", "lanman.share.current_uses", FT_UINT16, BASE_DEC,
2952
14
      NULL, 0, "LANMAN Current connections to share", HFILL }},
2953
2954
14
    { &hf_share_path,
2955
14
      { "Share Path", "lanman.share.path", FT_STRING, BASE_NONE,
2956
14
      NULL, 0, "LANMAN Share Path", HFILL }},
2957
2958
14
    { &hf_share_password,
2959
14
      { "Share Password", "lanman.share.password", FT_STRING, BASE_NONE,
2960
14
      NULL, 0, "LANMAN Share Password", HFILL }},
2961
2962
14
    { &hf_server,
2963
14
      { "Server", "lanman.server", FT_NONE, BASE_NONE,
2964
14
      NULL, 0, NULL, HFILL }},
2965
2966
14
    { &hf_server_name,
2967
14
      { "Server Name", "lanman.server.name", FT_STRING, BASE_NONE,
2968
14
      NULL, 0, "LANMAN Name of Server", HFILL }},
2969
2970
14
    { &hf_server_major,
2971
14
      { "Major Version", "lanman.server.major", FT_UINT8, BASE_DEC,
2972
14
      NULL, 0, "LANMAN Server Major Version", HFILL }},
2973
2974
14
    { &hf_server_minor,
2975
14
      { "Minor Version", "lanman.server.minor", FT_UINT8, BASE_DEC,
2976
14
      NULL, 0, "LANMAN Server Minor Version", HFILL }},
2977
2978
14
    { &hf_server_comment,
2979
14
      { "Server Comment", "lanman.server.comment", FT_STRING, BASE_NONE,
2980
14
      NULL, 0, "LANMAN Server Comment", HFILL }},
2981
2982
14
    { &hf_abytes,
2983
14
      { "Available Bytes", "lanman.available_bytes", FT_UINT16, BASE_DEC,
2984
14
      NULL, 0, "LANMAN Number of Available Bytes", HFILL }},
2985
2986
14
    { &hf_current_time,
2987
14
      { "Current Date/Time", "lanman.current_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
2988
14
      NULL, 0, "LANMAN Current date and time, in seconds since 00:00:00, January 1, 1970", HFILL }},
2989
2990
14
    { &hf_msecs,
2991
14
      { "Milliseconds", "lanman.msecs", FT_UINT32, BASE_DEC,
2992
14
      NULL, 0, "LANMAN Milliseconds since arbitrary time in the past (typically boot time)", HFILL }},
2993
2994
14
    { &hf_hour,
2995
14
      { "Hour", "lanman.hour", FT_UINT8, BASE_DEC,
2996
14
      NULL, 0, "LANMAN Current hour", HFILL }},
2997
2998
14
    { &hf_minute,
2999
14
      { "Minute", "lanman.minute", FT_UINT8, BASE_DEC,
3000
14
      NULL, 0, "LANMAN Current minute", HFILL }},
3001
3002
14
    { &hf_second,
3003
14
      { "Second", "lanman.second", FT_UINT8, BASE_DEC,
3004
14
      NULL, 0, "LANMAN Current second", HFILL }},
3005
3006
14
    { &hf_hundredths,
3007
14
      { "Hundredths of a second", "lanman.hundredths", FT_UINT8, BASE_DEC,
3008
14
      NULL, 0, "LANMAN Current hundredths of a second", HFILL }},
3009
3010
14
    { &hf_tzoffset,
3011
14
      { "Time Zone Offset", "lanman.tzoffset", FT_INT16, BASE_DEC,
3012
14
      NULL, 0, "LANMAN Offset of time zone from GMT, in minutes", HFILL }},
3013
3014
14
    { &hf_timeinterval,
3015
14
      { "Time Interval", "lanman.timeinterval", FT_UINT16, BASE_DEC,
3016
14
      NULL, 0, "LANMAN .0001 second units per clock tick", HFILL }},
3017
3018
14
    { &hf_day,
3019
14
      { "Day", "lanman.day", FT_UINT8, BASE_DEC,
3020
14
      NULL, 0, "LANMAN Current day", HFILL }},
3021
3022
14
    { &hf_month,
3023
14
      { "Month", "lanman.month", FT_UINT8, BASE_DEC,
3024
14
      NULL, 0, "LANMAN Current month", HFILL }},
3025
3026
14
    { &hf_year,
3027
14
      { "Year", "lanman.year", FT_UINT16, BASE_DEC,
3028
14
      NULL, 0, "LANMAN Current year", HFILL }},
3029
3030
14
    { &hf_weekday,
3031
14
      { "Weekday", "lanman.weekday", FT_UINT8, BASE_DEC,
3032
14
      VALS(weekday_vals), 0, "LANMAN Current day of the week", HFILL }},
3033
3034
14
    { &hf_enumeration_domain,
3035
14
      { "Enumeration Domain", "lanman.enumeration_domain", FT_STRING, BASE_NONE,
3036
14
      NULL, 0, "LANMAN Domain in which to enumerate servers", HFILL }},
3037
3038
14
    { &hf_last_entry,
3039
14
      { "Last Entry", "lanman.last_entry", FT_STRING, BASE_NONE,
3040
14
      NULL, 0, "LANMAN last reported entry of the enumerated servers", HFILL }},
3041
3042
14
    { &hf_computer_name,
3043
14
      { "Computer Name", "lanman.computer_name", FT_STRING, BASE_NONE,
3044
14
      NULL, 0, "LANMAN Computer Name", HFILL }},
3045
3046
14
    { &hf_user_name,
3047
14
      { "User Name", "lanman.user_name", FT_STRING, BASE_NONE,
3048
14
      NULL, 0, "LANMAN User Name", HFILL }},
3049
3050
14
    { &hf_group_name,
3051
14
      { "Group Name", "lanman.group_name", FT_STRING, BASE_NONE,
3052
14
      NULL, 0, "LANMAN Group Name", HFILL }},
3053
3054
14
    { &hf_workstation_domain,
3055
14
      { "Workstation Domain", "lanman.workstation_domain", FT_STRING, BASE_NONE,
3056
14
      NULL, 0, "LANMAN Workstation Domain", HFILL }},
3057
3058
14
    { &hf_workstation_major,
3059
14
      { "Workstation Major Version", "lanman.workstation_major", FT_UINT8, BASE_DEC,
3060
14
      NULL, 0, "LANMAN Workstation Major Version", HFILL }},
3061
3062
14
    { &hf_workstation_minor,
3063
14
      { "Workstation Minor Version", "lanman.workstation_minor", FT_UINT8, BASE_DEC,
3064
14
      NULL, 0, "LANMAN Workstation Minor Version", HFILL }},
3065
3066
14
    { &hf_logon_domain,
3067
14
      { "Logon Domain", "lanman.logon_domain", FT_STRING, BASE_NONE,
3068
14
      NULL, 0, "LANMAN Logon Domain", HFILL }},
3069
3070
14
    { &hf_other_domains,
3071
14
      { "Other Domains", "lanman.other_domains", FT_STRING, BASE_NONE,
3072
14
      NULL, 0, "LANMAN Other Domains", HFILL }},
3073
3074
14
    { &hf_password,
3075
14
      { "Password", "lanman.password", FT_STRING, BASE_NONE,
3076
14
      NULL, 0, "LANMAN Password", HFILL }},
3077
3078
14
    { &hf_workstation_name,
3079
14
      { "Workstation Name", "lanman.workstation_name", FT_STRING, BASE_NONE,
3080
14
      NULL, 0, "LANMAN Workstation Name", HFILL }},
3081
3082
14
    { &hf_ustruct_size,
3083
14
      { "Length of UStruct", "lanman.ustruct_size", FT_UINT16, BASE_DEC,
3084
14
      NULL, 0, "LANMAN UStruct Length", HFILL }},
3085
3086
14
    { &hf_logon_code,
3087
14
      { "Logon Code", "lanman.logon_code", FT_UINT16, BASE_DEC,
3088
14
      VALS(status_vals), 0, "LANMAN Logon Code", HFILL }},
3089
3090
14
    { &hf_privilege_level,
3091
14
      { "Privilege Level", "lanman.privilege_level", FT_UINT16, BASE_DEC,
3092
14
      VALS(privilege_vals), 0, "LANMAN Privilege Level", HFILL }},
3093
3094
14
    { &hf_operator_privileges,
3095
14
      { "Operator Privileges", "lanman.operator_privileges", FT_UINT32, BASE_DEC,
3096
14
      VALS(op_privilege_vals), 0, "LANMAN Operator Privileges", HFILL }},
3097
3098
14
    { &hf_num_logons,
3099
14
      { "Number of Logons", "lanman.num_logons", FT_UINT16, BASE_DEC,
3100
14
      NULL, 0, "LANMAN Number of Logons", HFILL }},
3101
3102
14
    { &hf_bad_pw_count,
3103
14
      { "Bad Password Count", "lanman.bad_pw_count", FT_UINT16, BASE_DEC,
3104
14
      NULL, 0, "LANMAN Number of incorrect passwords entered since last successful login", HFILL }},
3105
3106
14
    { &hf_last_logon,
3107
14
      { "Last Logon Date/Time", "lanman.last_logon", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3108
14
      NULL, 0, "LANMAN Date and time of last logon", HFILL }},
3109
3110
14
    { &hf_last_logoff,
3111
14
      { "Last Logoff Date/Time", "lanman.last_logoff", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3112
14
      NULL, 0, "LANMAN Date and time of last logoff", HFILL }},
3113
3114
14
    { &hf_logoff_time,
3115
14
      { "Logoff Date/Time", "lanman.logoff_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3116
14
      NULL, 0, "LANMAN Date and time when user should log off", HFILL }},
3117
3118
14
    { &hf_kickoff_time,
3119
14
      { "Kickoff Date/Time", "lanman.kickoff_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3120
14
      NULL, 0, "LANMAN Date and time when user will be logged off", HFILL }},
3121
3122
14
    { &hf_password_age,
3123
14
      { "Password Age", "lanman.password_age", FT_RELATIVE_TIME, BASE_NONE,
3124
14
      NULL, 0, "LANMAN Time since user last changed his/her password", HFILL }},
3125
3126
14
    { &hf_password_can_change,
3127
14
      { "Password Can Change", "lanman.password_can_change", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3128
14
      NULL, 0, "LANMAN Date and time when user can change their password", HFILL }},
3129
3130
14
    { &hf_password_must_change,
3131
14
      { "Password Must Change", "lanman.password_must_change", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
3132
14
      NULL, 0, "LANMAN Date and time when user must change their password", HFILL }},
3133
3134
14
    { &hf_script_path,
3135
14
      { "Script Path", "lanman.script_path", FT_STRING, BASE_NONE,
3136
14
      NULL, 0, "LANMAN Pathname of user's logon script", HFILL }},
3137
3138
14
    { &hf_logoff_code,
3139
14
      { "Logoff Code", "lanman.logoff_code", FT_UINT16, BASE_DEC,
3140
14
      VALS(status_vals), 0, "LANMAN Logoff Code", HFILL }},
3141
3142
14
    { &hf_duration,
3143
14
      { "Duration of Session", "lanman.duration", FT_RELATIVE_TIME, BASE_NONE,
3144
14
      NULL, 0, "LANMAN Number of seconds the user was logged on", HFILL }},
3145
3146
14
    { &hf_comment,
3147
14
      { "Comment", "lanman.comment", FT_STRING, BASE_NONE,
3148
14
      NULL, 0, "LANMAN Comment", HFILL }},
3149
3150
14
    { &hf_user_comment,
3151
14
      { "User Comment", "lanman.user_comment", FT_STRING, BASE_NONE,
3152
14
      NULL, 0, "LANMAN User Comment", HFILL }},
3153
3154
14
    { &hf_full_name,
3155
14
      { "Full Name", "lanman.full_name", FT_STRING, BASE_NONE,
3156
14
      NULL, 0, "LANMAN Full Name", HFILL }},
3157
3158
14
    { &hf_homedir,
3159
14
      { "Home Directory", "lanman.homedir", FT_STRING, BASE_NONE,
3160
14
      NULL, 0, "LANMAN Home Directory", HFILL }},
3161
3162
14
    { &hf_parameters,
3163
14
      { "Parameters", "lanman.parameters", FT_STRING, BASE_NONE,
3164
14
      NULL, 0, "LANMAN Parameters", HFILL }},
3165
3166
14
    { &hf_logon_server,
3167
14
      { "Logon Server", "lanman.logon_server", FT_STRING, BASE_NONE,
3168
14
      NULL, 0, "LANMAN Logon Server", HFILL }},
3169
3170
14
    { &hf_country_code,
3171
14
      { "Country Code", "lanman.country_code", FT_UINT16, BASE_DEC | BASE_EXT_STRING,
3172
14
      &ms_country_codes_ext, 0, "LANMAN Country Code", HFILL }},
3173
3174
14
    { &hf_workstations,
3175
14
      { "Workstations", "lanman.workstations", FT_STRING, BASE_NONE,
3176
14
      NULL, 0, "LANMAN Workstations", HFILL }},
3177
3178
14
    { &hf_max_storage,
3179
14
      { "Max Storage", "lanman.max_storage", FT_UINT32, BASE_DEC,
3180
14
      NULL, 0, "LANMAN Max Storage", HFILL }},
3181
3182
14
    { &hf_units_per_week,
3183
14
      { "Units Per Week", "lanman.units_per_week", FT_UINT16, BASE_DEC,
3184
14
      NULL, 0, "LANMAN Units Per Week", HFILL }},
3185
3186
14
    { &hf_logon_hours,
3187
14
      { "Logon Hours", "lanman.logon_hours", FT_BYTES, BASE_NONE,
3188
14
      NULL, 0, "LANMAN Logon Hours", HFILL }},
3189
3190
    /* XXX - we should have a value_string table for this */
3191
14
    { &hf_code_page,
3192
14
      { "Code Page", "lanman.code_page", FT_UINT16, BASE_DEC,
3193
14
      NULL, 0, "LANMAN Code Page", HFILL }},
3194
3195
14
    { &hf_new_password,
3196
14
      { "New Password", "lanman.new_password", FT_BYTES, BASE_NONE,
3197
14
      NULL, 0, "LANMAN New Password (encrypted)", HFILL }},
3198
3199
14
    { &hf_old_password,
3200
14
      { "Old Password", "lanman.old_password", FT_BYTES, BASE_NONE,
3201
14
      NULL, 0, "LANMAN Old Password (encrypted)", HFILL }},
3202
3203
14
    { &hf_reserved,
3204
14
      { "Reserved", "lanman.reserved", FT_UINT32, BASE_HEX,
3205
14
      NULL, 0, "LANMAN Reserved", HFILL }},
3206
3207
14
    { &hf_aux_data_struct_count,
3208
14
      { "Auxiliary data structure count", "lanman.aux_data_struct_count", FT_UINT16, BASE_DEC_HEX,
3209
14
      NULL, 0, NULL, HFILL }},
3210
3211
14
  };
3212
14
  static int *ett[] = {
3213
14
    &ett_lanman,
3214
14
    &ett_lanman_unknown_entries,
3215
14
    &ett_lanman_unknown_entry,
3216
14
    &ett_lanman_servers,
3217
14
    &ett_lanman_server,
3218
14
    &ett_lanman_groups,
3219
14
    &ett_lanman_shares,
3220
14
    &ett_lanman_share,
3221
14
  };
3222
3223
14
  proto_smb_lanman = proto_register_protocol("Microsoft Windows Lanman Remote API Protocol", "LANMAN", "lanman");
3224
14
  proto_register_field_array(proto_smb_lanman, hf, array_length(hf));
3225
14
  proto_register_subtree_array(ett, array_length(ett));
3226
14
}
3227
3228
static heur_dissector_list_t smb_transact_heur_subdissector_list;
3229
3230
static reassembly_table dcerpc_reassembly_table;
3231
3232
bool
3233
dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree,
3234
    proto_tree *tree, uint32_t fid, void *data)
3235
15
{
3236
15
  bool result=false;
3237
15
  bool save_fragmented;
3238
15
  unsigned reported_len;
3239
3240
15
  fragment_head *fd_head;
3241
15
  fragment_item *fd_i;
3242
15
  tvbuff_t *new_tvb;
3243
15
  proto_item *frag_tree_item;
3244
3245
15
  heur_dtbl_entry_t *hdtbl_entry;
3246
3247
15
  dcerpc_set_transport_salt(fid, pinfo);
3248
3249
  /*
3250
   * Offer desegmentation service to DCERPC if we have all the
3251
   * data.  Otherwise, reassembly is (probably) impossible.
3252
   */
3253
15
  pinfo->can_desegment=0;
3254
15
  pinfo->desegment_offset = 0;
3255
15
  pinfo->desegment_len = 0;
3256
15
  reported_len = tvb_reported_length(d_tvb);
3257
15
  if(smb_dcerpc_reassembly && tvb_captured_length(d_tvb) >= reported_len){
3258
5
    pinfo->can_desegment=2;
3259
5
  }
3260
3261
15
  save_fragmented = pinfo->fragmented;
3262
3263
3264
  /* if we are not offering desegmentation, just try the heuristics
3265
     and bail out
3266
  */
3267
15
  if(!pinfo->can_desegment){
3268
10
    result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree, &hdtbl_entry, data);
3269
10
    goto clean_up_and_exit;
3270
10
  }
3271
3272
3273
  /* below this line, we know we are doing reassembly */
3274
3275
  /* this is a new packet, see if we are already reassembling this
3276
     pdu and if not, check if the dissector wants us
3277
     to reassemble it
3278
  */
3279
5
  if(!pinfo->fd->visited){
3280
    /*
3281
     * This is the first pass.
3282
     *
3283
     * Check if we are already reassembling this PDU or not;
3284
     * we check for an in-progress reassembly for this FID
3285
     * in this direction, by searching for its reassembly
3286
     * structure.
3287
     */
3288
5
    fd_head=fragment_get(&dcerpc_reassembly_table, pinfo, fid, NULL);
3289
5
    if(!fd_head){
3290
      /* No reassembly, so this is a new pdu. check if the
3291
         dissector wants us to reassemble it or if we
3292
         already got the full pdu in this tvb.
3293
      */
3294
3295
      /*
3296
       * Try the heuristic dissectors and see if we
3297
       * find someone that recognizes this payload.
3298
       */
3299
5
      result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree, &hdtbl_entry, data);
3300
3301
      /* no this didn't look like something we know */
3302
5
      if(!result){
3303
5
        goto clean_up_and_exit;
3304
5
      }
3305
3306
      /* did the subdissector want us to reassemble any
3307
         more data ?
3308
      */
3309
0
      if(pinfo->desegment_len){
3310
0
        fragment_add_check(&dcerpc_reassembly_table,
3311
0
          d_tvb, 0, pinfo, fid, NULL,
3312
0
          0, reported_len, true);
3313
0
        fragment_set_tot_len(&dcerpc_reassembly_table,
3314
0
          pinfo, fid, NULL,
3315
0
          pinfo->desegment_len+reported_len);
3316
0
      }
3317
0
      goto clean_up_and_exit;
3318
5
    }
3319
3320
    /* OK, we're already doing a reassembly for this FID.
3321
       skip to last segment in the existing reassembly structure
3322
       and add this fragment there
3323
3324
       XXX we might add code here to use any offset values
3325
       we might pick up from the Read/Write calls instead of
3326
       assuming we always get them in the correct order
3327
    */
3328
0
    for (fd_i = fd_head->next; fd_i->next; fd_i = fd_i->next) {}
3329
0
    fd_head=fragment_add_check(&dcerpc_reassembly_table,
3330
0
      d_tvb, 0, pinfo, fid, NULL,
3331
0
      fd_i->offset+fd_i->len,
3332
0
      reported_len, true);
3333
3334
    /* if we completed reassembly */
3335
0
    if(fd_head){
3336
0
      new_tvb = tvb_new_chain(d_tvb, fd_head->tvb_data);
3337
0
      add_new_data_source(pinfo, new_tvb,
3338
0
          "DCERPC over SMB");
3339
0
      pinfo->fragmented=false;
3340
3341
0
      d_tvb=new_tvb;
3342
3343
      /* list what segments we have */
3344
0
      show_fragment_tree(fd_head, &smb_pipe_frag_items,
3345
0
          tree, pinfo, d_tvb, &frag_tree_item);
3346
3347
      /* dissect the full PDU */
3348
0
      result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree, &hdtbl_entry, data);
3349
0
    }
3350
0
    goto clean_up_and_exit;
3351
5
  }
3352
3353
  /*
3354
   * This is not the first pass; see if it's in the table of
3355
   * reassembled packets.
3356
   *
3357
   * XXX - we know that several of the arguments aren't going to
3358
   * be used, so we pass bogus variables.  Can we clean this
3359
   * up so that we don't have to distinguish between the first
3360
   * pass and subsequent passes?
3361
   */
3362
0
  fd_head=fragment_add_check(&dcerpc_reassembly_table,
3363
0
      d_tvb, 0, pinfo, fid, NULL, 0, 0, true);
3364
0
  if(!fd_head){
3365
    /* we didn't find it, try any of the heuristic dissectors
3366
       and bail out
3367
    */
3368
0
    result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree, &hdtbl_entry, data);
3369
0
    goto clean_up_and_exit;
3370
0
  }
3371
0
  if(!(fd_head->flags&FD_DEFRAGMENTED)){
3372
    /* we don't have a fully reassembled frame */
3373
0
    result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree, &hdtbl_entry, data);
3374
0
    goto clean_up_and_exit;
3375
0
  }
3376
3377
  /* it is reassembled but it was reassembled in a different frame */
3378
0
  if(pinfo->num!=fd_head->reassembled_in){
3379
0
    proto_tree_add_uint(parent_tree, hf_smb_pipe_reassembled_in, d_tvb, 0, 0, fd_head->reassembled_in);
3380
0
    goto clean_up_and_exit;
3381
0
  }
3382
3383
3384
  /* display the reassembled pdu */
3385
0
  new_tvb = tvb_new_chain(d_tvb, fd_head->tvb_data);
3386
0
  add_new_data_source(pinfo, new_tvb,
3387
0
      "DCERPC over SMB");
3388
0
  pinfo->fragmented=false;
3389
3390
0
  d_tvb=new_tvb;
3391
3392
  /* list what segments we have */
3393
0
  show_fragment_tree(fd_head, &smb_pipe_frag_items,
3394
0
        tree, pinfo, d_tvb, &frag_tree_item);
3395
3396
  /* dissect the full PDU */
3397
0
  result = dissector_try_heuristic(smb_transact_heur_subdissector_list, d_tvb, pinfo, parent_tree, &hdtbl_entry, data);
3398
3399
3400
3401
15
clean_up_and_exit:
3402
  /* clear out the variables */
3403
15
  pinfo->can_desegment=0;
3404
15
  pinfo->desegment_offset = 0;
3405
15
  pinfo->desegment_len = 0;
3406
3407
15
  if (!result)
3408
15
    call_data_dissector(d_tvb, pinfo, parent_tree);
3409
3410
15
  pinfo->fragmented = save_fragmented;
3411
15
  return true;
3412
0
}
3413
3414
0
#define CALL_NAMED_PIPE   0x54
3415
0
#define WAIT_NAMED_PIPE   0x53
3416
0
#define PEEK_NAMED_PIPE   0x23
3417
0
#define Q_NM_P_HAND_STATE 0x21
3418
0
#define SET_NM_P_HAND_STATE 0x01
3419
0
#define Q_NM_PIPE_INFO    0x22
3420
0
#define TRANSACT_NM_PIPE  0x26
3421
0
#define RAW_READ_NM_PIPE  0x11
3422
0
#define RAW_WRITE_NM_PIPE 0x31
3423
3424
static const value_string functions[] = {
3425
  {CALL_NAMED_PIPE, "CallNamedPipe"},
3426
  {WAIT_NAMED_PIPE, "WaitNamedPipe"},
3427
  {PEEK_NAMED_PIPE, "PeekNamedPipe"},
3428
  {Q_NM_P_HAND_STATE, "QNmPHandState"},
3429
  {SET_NM_P_HAND_STATE, "SetNmPHandState"},
3430
  {Q_NM_PIPE_INFO,  "QNmPipeInfo"},
3431
  {TRANSACT_NM_PIPE,  "TransactNmPipe"},
3432
  {RAW_READ_NM_PIPE,  "RawReadNmPipe"},
3433
  {RAW_WRITE_NM_PIPE, "RawWriteNmPipe"},
3434
  {0,     NULL}
3435
};
3436
3437
static const value_string pipe_status[] = {
3438
  {1, "Disconnected by server"},
3439
  {2, "Listening"},
3440
  {3, "Connection to server is OK"},
3441
  {4, "Server end of pipe is closed"},
3442
  {0, NULL}
3443
};
3444
3445
0
#define PIPE_LANMAN     1
3446
0
#define PIPE_DCERPC     2
3447
3448
/* decode the SMB pipe protocol
3449
   for requests
3450
    pipe is the name of the pipe, e.g. LANMAN
3451
    smb_info->trans_subcmd is set to the symbolic constant matching the mailslot name
3452
  for responses
3453
    pipe is NULL
3454
    smb_info->trans_subcmd gives us which pipe this response is for
3455
*/
3456
bool
3457
dissect_pipe_smb(tvbuff_t *sp_tvb, tvbuff_t *s_tvb, tvbuff_t *pd_tvb,
3458
     tvbuff_t *p_tvb, tvbuff_t *d_tvb, const char *pipe,
3459
     packet_info *pinfo, proto_tree *tree, smb_info_t *smb_info)
3460
0
{
3461
0
  smb_transact_info_t *tri;
3462
0
  unsigned sp_len;
3463
0
  proto_item *pipe_item = NULL;
3464
0
  proto_tree *pipe_tree = NULL;
3465
0
  int offset;
3466
0
  int trans_subcmd=0;
3467
0
  int function;
3468
0
  int fid = -1;
3469
0
  uint16_t info_level;
3470
3471
0
  if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_pipe)))
3472
0
    return false;
3473
0
  pinfo->current_proto = "SMB Pipe";
3474
3475
  /*
3476
   * Set the columns.
3477
   */
3478
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB Pipe");
3479
0
  col_set_str(pinfo->cinfo, COL_INFO,
3480
0
        smb_info->request ? "Request" : "Response");
3481
3482
0
  if (smb_info->sip != NULL && smb_info->sip->extra_info_type == SMB_EI_TRI)
3483
0
    tri = (smb_transact_info_t *)smb_info->sip->extra_info;
3484
0
  else
3485
0
    tri = NULL;
3486
3487
  /*
3488
   * Set up a subtree for the pipe protocol.  (It might not contain
3489
   * anything.)
3490
   */
3491
0
  if (sp_tvb != NULL)
3492
0
    sp_len = tvb_captured_length(sp_tvb);
3493
0
  else
3494
0
    sp_len = 0;
3495
0
  if (tree) {
3496
0
    pipe_item = proto_tree_add_item(tree, proto_smb_pipe,
3497
0
        sp_tvb, 0, sp_len, ENC_NA);
3498
0
    pipe_tree = proto_item_add_subtree(pipe_item, ett_smb_pipe);
3499
0
  }
3500
0
  offset = 0;
3501
3502
  /*
3503
   * Do we have any setup words at all?
3504
   */
3505
0
  if (s_tvb != NULL && tvb_reported_length(s_tvb) != 0) {
3506
    /*
3507
     * Yes.  The first of them is the function.
3508
     */
3509
0
    function = tvb_get_letohs(s_tvb, offset);
3510
0
    proto_tree_add_uint(pipe_tree, hf_smb_pipe_function, s_tvb,
3511
0
        offset, 2, function);
3512
0
    offset += 2;
3513
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
3514
0
          val_to_str(function, functions, "Unknown function (0x%04x)"),
3515
0
          smb_info->request ? "Request" : "Response");
3516
3517
0
    if (tri != NULL)
3518
0
      tri->function = function;
3519
3520
    /*
3521
     * The second of them depends on the function.
3522
     */
3523
0
    switch (function) {
3524
3525
0
    case CALL_NAMED_PIPE:
3526
0
    case WAIT_NAMED_PIPE:
3527
      /*
3528
       * It's a priority.
3529
       */
3530
0
      proto_tree_add_item(pipe_tree, hf_smb_pipe_priority, s_tvb,
3531
0
          offset, 2, ENC_LITTLE_ENDIAN);
3532
0
      break;
3533
3534
0
    case PEEK_NAMED_PIPE:
3535
0
    case Q_NM_P_HAND_STATE:
3536
0
    case SET_NM_P_HAND_STATE:
3537
0
    case Q_NM_PIPE_INFO:
3538
0
    case TRANSACT_NM_PIPE:
3539
0
    case RAW_READ_NM_PIPE:
3540
0
    case RAW_WRITE_NM_PIPE:
3541
      /*
3542
       * It's a FID.
3543
       */
3544
0
      fid = tvb_get_letohs(s_tvb, 2);
3545
0
      dissect_smb_fid(s_tvb, pinfo, pipe_tree, offset, 2, (uint16_t) fid, false, false, false, smb_info);
3546
0
      if (tri != NULL)
3547
0
        tri->fid = fid;
3548
0
      break;
3549
3550
0
    default:
3551
      /*
3552
       * It's something unknown.
3553
       * XXX - put it into the tree?
3554
       */
3555
0
      break;
3556
0
    }
3557
0
  } else {
3558
    /*
3559
     * This is either a response or a pipe transaction with
3560
     * no setup information.
3561
     *
3562
     * In the former case, we can get that information from
3563
     * the matching request, if we saw it.
3564
     *
3565
     * In the latter case, there is no function or FID.
3566
     */
3567
0
    if (tri != NULL && tri->function != -1) {
3568
0
      function = tri->function;
3569
0
      proto_tree_add_uint(pipe_tree, hf_smb_pipe_function, NULL,
3570
0
          0, 0, function);
3571
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
3572
0
            val_to_str(function, functions, "Unknown function (0x%04x)"),
3573
0
            smb_info->request ? "Request" : "Response");
3574
3575
0
      fid = tri->fid;
3576
0
      if (fid != -1)
3577
0
        dissect_smb_fid(d_tvb, pinfo, pipe_tree, 0, 0, (uint16_t) fid, false, false, true, smb_info);
3578
0
    } else {
3579
0
      function = -1;
3580
0
      fid = -1;
3581
0
    }
3582
0
  }
3583
3584
  /*
3585
   * XXX - put the byte count and the pipe name into the tree as well;
3586
   * that requires us to fetch a possibly-Unicode string.
3587
   */
3588
3589
0
  if(smb_info->request){
3590
0
    if(strncmp(pipe,"LANMAN",6) == 0){
3591
0
      trans_subcmd=PIPE_LANMAN;
3592
0
    } else {
3593
      /* assume it is DCERPC */
3594
0
      trans_subcmd=PIPE_DCERPC;
3595
0
    }
3596
3597
0
    if (!pinfo->fd->visited) {
3598
0
      if (tri == NULL)
3599
0
        return false;
3600
0
      tri->trans_subcmd = trans_subcmd;
3601
0
    }
3602
0
  } else {
3603
0
    if(tri == NULL)
3604
0
      return false;
3605
0
    trans_subcmd = tri->trans_subcmd;
3606
0
  }
3607
3608
0
  if (tri == NULL) {
3609
    /*
3610
     * We don't know what type of pipe transaction this
3611
     * was, so indicate that we didn't dissect it.
3612
     */
3613
0
    return false;
3614
0
  }
3615
3616
0
  switch (function) {
3617
3618
0
  case CALL_NAMED_PIPE:
3619
0
  case TRANSACT_NM_PIPE:
3620
0
    switch(trans_subcmd){
3621
3622
0
    case PIPE_LANMAN:
3623
0
      return dissect_pipe_lanman(pd_tvb, p_tvb, d_tvb, pinfo, tree, smb_info);
3624
3625
0
    case PIPE_DCERPC:
3626
      /*
3627
       * Only dissect this if we know the FID.
3628
       */
3629
0
      if (fid != -1) {
3630
0
        if (d_tvb == NULL)
3631
0
          return false;
3632
0
        return dissect_pipe_dcerpc(d_tvb, pinfo, tree, pipe_tree, fid, smb_info);
3633
0
      }
3634
0
      break;
3635
0
    }
3636
0
    break;
3637
3638
0
  case -1:
3639
    /*
3640
     * We don't know the function; we dissect only LANMAN
3641
     * pipe messages, not RPC pipe messages, in that case.
3642
     */
3643
0
    switch(trans_subcmd){
3644
0
    case PIPE_LANMAN:
3645
0
      return dissect_pipe_lanman(pd_tvb, p_tvb, d_tvb, pinfo, tree, smb_info);
3646
0
    }
3647
0
    break;
3648
3649
0
  case WAIT_NAMED_PIPE:
3650
0
    break;
3651
3652
0
  case PEEK_NAMED_PIPE:
3653
    /*
3654
     * Request contains no parameters or data.
3655
     */
3656
0
    if (!smb_info->request) {
3657
0
      if (p_tvb == NULL)
3658
0
        return false;
3659
0
      offset = 0;
3660
0
      proto_tree_add_item(pipe_tree, hf_smb_pipe_peek_available,
3661
0
          p_tvb, offset, 2, ENC_LITTLE_ENDIAN);
3662
0
      offset += 2;
3663
0
      proto_tree_add_item(pipe_tree, hf_smb_pipe_peek_remaining,
3664
0
          p_tvb, offset, 2, ENC_LITTLE_ENDIAN);
3665
0
      offset += 2;
3666
0
      proto_tree_add_item(pipe_tree, hf_smb_pipe_peek_status,
3667
0
          p_tvb, offset, 2, ENC_LITTLE_ENDIAN);
3668
0
    }
3669
0
    break;
3670
3671
0
  case Q_NM_P_HAND_STATE:
3672
    /*
3673
     * Request contains no parameters or data.
3674
     */
3675
0
    if (!smb_info->request) {
3676
0
      if (p_tvb == NULL)
3677
0
        return false;
3678
0
      dissect_ipc_state(p_tvb, pipe_tree, 0, false);
3679
0
    }
3680
0
    break;
3681
3682
0
  case SET_NM_P_HAND_STATE:
3683
    /*
3684
     * Response contains no parameters or data.
3685
     */
3686
0
    if (smb_info->request) {
3687
0
      if (p_tvb == NULL)
3688
0
        return false;
3689
0
      dissect_ipc_state(p_tvb, pipe_tree, 0, true);
3690
0
    }
3691
0
    break;
3692
3693
0
  case Q_NM_PIPE_INFO:
3694
0
    offset = 0;
3695
0
    if (smb_info->request) {
3696
0
      if (p_tvb == NULL)
3697
0
        return false;
3698
3699
      /*
3700
       * Request contains an information level.
3701
       */
3702
0
      info_level = tvb_get_letohs(p_tvb, offset);
3703
0
      proto_tree_add_uint(pipe_tree, hf_smb_pipe_getinfo_info_level,
3704
0
          p_tvb, offset, 2, info_level);
3705
0
      if (!pinfo->fd->visited)
3706
0
        tri->info_level = info_level;
3707
0
    } else {
3708
0
      uint8_t pipe_namelen;
3709
3710
0
      if (d_tvb == NULL)
3711
0
        return false;
3712
3713
0
      switch (tri->info_level) {
3714
3715
0
      case 1:
3716
0
        proto_tree_add_item(pipe_tree,
3717
0
            hf_smb_pipe_getinfo_output_buffer_size,
3718
0
            d_tvb, offset, 2, ENC_LITTLE_ENDIAN);
3719
0
        offset += 2;
3720
0
        proto_tree_add_item(pipe_tree,
3721
0
            hf_smb_pipe_getinfo_input_buffer_size,
3722
0
            d_tvb, offset, 2, ENC_LITTLE_ENDIAN);
3723
0
        offset += 2;
3724
0
        proto_tree_add_item(pipe_tree,
3725
0
            hf_smb_pipe_getinfo_maximum_instances,
3726
0
            d_tvb, offset, 1, ENC_LITTLE_ENDIAN);
3727
0
        offset += 1;
3728
0
        proto_tree_add_item(pipe_tree,
3729
0
            hf_smb_pipe_getinfo_current_instances,
3730
0
            d_tvb, offset, 1, ENC_LITTLE_ENDIAN);
3731
0
        offset += 1;
3732
0
        pipe_namelen = tvb_get_uint8(d_tvb, offset);
3733
0
        proto_tree_add_uint(pipe_tree,
3734
0
            hf_smb_pipe_getinfo_pipe_name_length,
3735
0
            d_tvb, offset, 1, pipe_namelen);
3736
0
        offset += 1;
3737
        /* XXX - can this be Unicode? */
3738
0
        proto_tree_add_item(pipe_tree,
3739
0
            hf_smb_pipe_getinfo_pipe_name,
3740
0
            d_tvb, offset, pipe_namelen, ENC_ASCII);
3741
0
        break;
3742
0
      }
3743
0
    }
3744
0
    break;
3745
3746
0
  case RAW_READ_NM_PIPE:
3747
    /*
3748
     * Request contains no parameters or data.
3749
     */
3750
0
    if (!smb_info->request) {
3751
0
      if (d_tvb == NULL)
3752
0
        return false;
3753
3754
0
      dissect_file_data(d_tvb, pipe_tree, 0,
3755
0
          (uint16_t) tvb_reported_length(d_tvb),
3756
0
          -1,
3757
0
          (uint16_t) tvb_reported_length(d_tvb));
3758
0
    }
3759
0
    break;
3760
3761
0
  case RAW_WRITE_NM_PIPE:
3762
0
    offset = 0;
3763
0
    if (smb_info->request) {
3764
0
      if (d_tvb == NULL)
3765
0
        return false;
3766
3767
0
      dissect_file_data(d_tvb, pipe_tree,
3768
0
          offset, (uint16_t) tvb_reported_length(d_tvb),
3769
0
          -1,
3770
0
          (uint16_t) tvb_reported_length(d_tvb));
3771
0
    } else {
3772
0
      if (p_tvb == NULL)
3773
0
        return false;
3774
0
      proto_tree_add_item(pipe_tree,
3775
0
          hf_smb_pipe_write_raw_bytes_written,
3776
0
          p_tvb, offset, 2, ENC_LITTLE_ENDIAN);
3777
0
    }
3778
0
    break;
3779
0
  }
3780
0
  return true;
3781
0
}
3782
3783
void
3784
proto_register_smb_pipe(void)
3785
14
{
3786
14
  static hf_register_info hf[] = {
3787
14
    { &hf_smb_pipe_function,
3788
14
      { "Function", "smb_pipe.function", FT_UINT16, BASE_HEX,
3789
14
      VALS(functions), 0, "SMB Pipe Function Code", HFILL }},
3790
14
    { &hf_smb_pipe_priority,
3791
14
      { "Priority", "smb_pipe.priority", FT_UINT16, BASE_DEC,
3792
14
      NULL, 0, "SMB Pipe Priority", HFILL }},
3793
14
    { &hf_smb_pipe_peek_available,
3794
14
      { "Available Bytes", "smb_pipe.peek.available_bytes", FT_UINT16, BASE_DEC,
3795
14
      NULL, 0, "Total number of bytes available to be read from the pipe", HFILL }},
3796
14
    { &hf_smb_pipe_peek_remaining,
3797
14
      { "Bytes Remaining", "smb_pipe.peek.remaining_bytes", FT_UINT16, BASE_DEC,
3798
14
      NULL, 0, "Total number of bytes remaining in the message at the head of the pipe", HFILL }},
3799
14
    { &hf_smb_pipe_peek_status,
3800
14
      { "Pipe Status", "smb_pipe.peek.status", FT_UINT16, BASE_DEC,
3801
14
      VALS(pipe_status), 0, NULL, HFILL }},
3802
14
    { &hf_smb_pipe_getinfo_info_level,
3803
14
      { "Information Level", "smb_pipe.getinfo.info_level", FT_UINT16, BASE_DEC,
3804
14
      NULL, 0, "Information level of information to return", HFILL }},
3805
14
    { &hf_smb_pipe_getinfo_output_buffer_size,
3806
14
      { "Output Buffer Size", "smb_pipe.getinfo.output_buffer_size", FT_UINT16, BASE_DEC,
3807
14
      NULL, 0, "Actual size of buffer for outgoing (server) I/O", HFILL }},
3808
14
    { &hf_smb_pipe_getinfo_input_buffer_size,
3809
14
      { "Input Buffer Size", "smb_pipe.getinfo.input_buffer_size", FT_UINT16, BASE_DEC,
3810
14
      NULL, 0, "Actual size of buffer for incoming (client) I/O", HFILL }},
3811
14
    { &hf_smb_pipe_getinfo_maximum_instances,
3812
14
      { "Maximum Instances", "smb_pipe.getinfo.maximum_instances", FT_UINT8, BASE_DEC,
3813
14
      NULL, 0, "Maximum allowed number of instances", HFILL }},
3814
14
    { &hf_smb_pipe_getinfo_current_instances,
3815
14
      { "Current Instances", "smb_pipe.getinfo.current_instances", FT_UINT8, BASE_DEC,
3816
14
      NULL, 0, "Current number of instances", HFILL }},
3817
14
    { &hf_smb_pipe_getinfo_pipe_name_length,
3818
14
      { "Pipe Name Length", "smb_pipe.getinfo.pipe_name_length", FT_UINT8, BASE_DEC,
3819
14
      NULL, 0, "Length of pipe name", HFILL }},
3820
14
    { &hf_smb_pipe_getinfo_pipe_name,
3821
14
      { "Pipe Name", "smb_pipe.getinfo.pipe_name", FT_STRING, BASE_NONE,
3822
14
      NULL, 0, "Name of pipe", HFILL }},
3823
14
    { &hf_smb_pipe_write_raw_bytes_written,
3824
14
      { "Bytes Written", "smb_pipe.write_raw.bytes_written", FT_UINT16, BASE_DEC,
3825
14
      NULL, 0, "Number of bytes written to the pipe", HFILL }},
3826
14
    { &hf_smb_pipe_fragment_overlap,
3827
14
      { "Fragment overlap", "smb_pipe.fragment.overlap", FT_BOOLEAN, BASE_NONE,
3828
14
      NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
3829
14
    { &hf_smb_pipe_fragment_overlap_conflict,
3830
14
      { "Conflicting data in fragment overlap", "smb_pipe.fragment.overlap.conflict", FT_BOOLEAN,
3831
14
      BASE_NONE, NULL, 0x0, "Overlapping fragments contained conflicting data", HFILL }},
3832
14
    { &hf_smb_pipe_fragment_multiple_tails,
3833
14
      { "Multiple tail fragments found",  "smb_pipe.fragment.multipletails", FT_BOOLEAN,
3834
14
      BASE_NONE, NULL, 0x0, "Several tails were found when defragmenting the packet", HFILL }},
3835
14
    { &hf_smb_pipe_fragment_too_long_fragment,
3836
14
      { "Fragment too long",  "smb_pipe.fragment.toolongfragment", FT_BOOLEAN,
3837
14
      BASE_NONE, NULL, 0x0, "Fragment contained data past end of packet", HFILL }},
3838
14
    { &hf_smb_pipe_fragment_error,
3839
14
      { "Defragmentation error", "smb_pipe.fragment.error", FT_FRAMENUM,
3840
14
      BASE_NONE, NULL, 0x0, "Defragmentation error due to illegal fragments", HFILL }},
3841
14
    { &hf_smb_pipe_fragment_count,
3842
14
      { "Fragment count", "smb_pipe.fragment.count", FT_UINT32,
3843
14
      BASE_DEC, NULL, 0x0, NULL, HFILL }},
3844
14
    { &hf_smb_pipe_fragment,
3845
14
      { "Fragment", "smb_pipe.fragment", FT_FRAMENUM,
3846
14
      BASE_NONE, NULL, 0x0, "Pipe Fragment", HFILL }},
3847
14
    { &hf_smb_pipe_fragments,
3848
14
      { "Fragments", "smb_pipe.fragments", FT_NONE,
3849
14
      BASE_NONE, NULL, 0x0, "Pipe Fragments", HFILL }},
3850
14
    { &hf_smb_pipe_reassembled_in,
3851
14
      { "This PDU is reassembled in", "smb_pipe.reassembled_in", FT_FRAMENUM,
3852
14
      BASE_NONE, NULL, 0x0, "The DCE/RPC PDU is completely reassembled in this frame", HFILL }},
3853
14
    { &hf_smb_pipe_reassembled_length,
3854
14
      { "Reassembled SMB Pipe length", "smb_pipe.reassembled.length", FT_UINT32,
3855
14
      BASE_DEC, NULL, 0x0, "The total length of the reassembled payload", HFILL }},
3856
3857
    /* Generated from convert_proto_tree_add_text.pl */
3858
14
    { &hf_smb_pipe_word_param,
3859
14
      { "Word Param", "smb_pipe.word_param", FT_UINT16,
3860
14
      BASE_DEC_HEX, NULL, 0x0, NULL, HFILL }},
3861
14
    { &hf_smb_pipe_doubleword_param,
3862
14
      { "Doubleword Param", "smb_pipe.doubleword_param", FT_UINT32,
3863
14
      BASE_DEC_HEX, NULL, 0x0, NULL, HFILL }},
3864
14
    { &hf_smb_pipe_byte_param,
3865
14
      { "Byte Param", "smb_pipe.byte_param", FT_UINT8,
3866
14
      BASE_DEC_HEX, NULL, 0x0, NULL, HFILL }},
3867
14
    { &hf_smb_pipe_bytes_param,
3868
14
      { "Bytes Param", "smb_pipe.bytes_param", FT_BYTES,
3869
14
      BASE_NONE, NULL, 0x0, NULL, HFILL }},
3870
14
    { &hf_smb_pipe_string_param,
3871
14
      { "String Param", "smb_pipe.string_param", FT_STRING,
3872
14
      BASE_NONE, NULL, 0x0, NULL, HFILL }},
3873
14
    { &hf_smb_pipe_stringz_param,
3874
14
      { "String Param", "smb_pipe.string_param", FT_STRINGZ,
3875
14
      BASE_NONE, NULL, 0x0, NULL, HFILL }},
3876
14
  };
3877
14
  static int *ett[] = {
3878
14
    &ett_smb_pipe,
3879
14
    &ett_smb_pipe_fragment,
3880
14
    &ett_smb_pipe_fragments,
3881
14
  };
3882
3883
14
  static ei_register_info ei[] = {
3884
14
    { &ei_smb_pipe_bogus_netwkstauserlogon, { "smb_pipe.bogus_netwkstauserlogon_parameters", PI_PROTOCOL, PI_WARN, "Bogus NetWkstaUserLogon parameters", EXPFILL }},
3885
14
    { &ei_smb_pipe_bad_type, { "smb_pipe.bad_type", PI_PROTOCOL, PI_ERROR, "Bad type field", EXPFILL }},
3886
14
  };
3887
3888
14
  expert_module_t* expert_smb_pipe;
3889
3890
14
  proto_smb_pipe = proto_register_protocol("SMB Pipe Protocol", "SMB Pipe", "smb_pipe");
3891
3892
14
  proto_register_field_array(proto_smb_pipe, hf, array_length(hf));
3893
14
  proto_register_subtree_array(ett, array_length(ett));
3894
14
  expert_smb_pipe = expert_register_protocol(proto_smb_pipe);
3895
14
  expert_register_field_array(expert_smb_pipe, ei, array_length(ei));
3896
3897
14
  smb_transact_heur_subdissector_list = register_heur_dissector_list_with_description("smb_transact", "SMB Pipe DCERPC data", proto_smb_pipe);
3898
  /*
3899
   * XXX - addresses_ports_reassembly_table_functions?
3900
   * Probably correct for SMB-over-NBT and SMB-over-TCP,
3901
   * as stuff from two different connections should
3902
   * probably not be combined, but what about other
3903
   * transports for SMB, e.g. NBF or Netware?
3904
   */
3905
14
  reassembly_table_register(&dcerpc_reassembly_table,
3906
14
      &addresses_reassembly_table_functions);
3907
14
}
3908
3909
/*
3910
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
3911
 *
3912
 * Local variables:
3913
 * c-basic-offset: 8
3914
 * tab-width: 8
3915
 * indent-tabs-mode: t
3916
 * End:
3917
 *
3918
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3919
 * :indentSize=8:tabSize=8:noTabs=false:
3920
 */