Coverage Report

Created: 2025-08-04 07:15

/src/wireshark/epan/dissectors/packet-hdfsdata.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-hdfsdata.c
2
 * HDFS data Protocol and dissectors
3
 *
4
 * Copyright (c) 2011 by Isilon Systems.
5
 *
6
 * Author: Allison Obourn <aobourn@isilon.com>
7
 *
8
 * Wireshark - Network traffic analyzer
9
 * By Gerald Combs <gerald@wireshark.org>
10
 * Copyright 1999 Gerald Combs
11
 *
12
 * SPDX-License-Identifier: GPL-2.0-or-later
13
 */
14
15
16
#include "config.h"
17
18
#include <epan/packet.h>
19
#include "packet-tcp.h"
20
21
void proto_register_hdfsdata(void);
22
void proto_reg_handoff_hdfsdata(void);
23
24
#if 0
25
#define NAMENODE_PORT 8020
26
#define DATANODE_PORT 8021
27
#endif
28
29
0
#define FIRST_READ_FRAGMENT_LEN 15
30
0
#define SECOND_READ_FRAGMENT_LEN 29
31
0
#define LAST_READ_FRAGMENT_LEN 4
32
0
#define WRITE_OP 80
33
0
#define READ_OP 81
34
0
#define MIN_WRITE_REQ 35
35
0
#define MIN_READ_REQ 36
36
37
0
#define STATUS_SUCCESS 6
38
0
#define PIPELINE_LEN 1
39
0
#define STATUS_LEN 2
40
0
#define FINISH_REQ_LEN 4
41
0
#define END_PACKET_LEN 8
42
0
#define READ_RESP_HEAD_LEN 19
43
0
#define WRITE_RESP_HEAD_LEN 21
44
0
#define WRITE_REQ_HEAD_LEN 7
45
46
0
#define CRC 1
47
0
#define CRC_SIZE 8.0
48
0
#define CHUNKSIZE_START 3
49
50
51
#if 0
52
static const int RESPONSE_HEADER = 1;
53
static const int RESPONSE_METADATA = 2;
54
static const int RESPONSE_DATA = 3;
55
#endif
56
57
static int proto_hdfsdata;
58
static int hf_hdfsdata_version;
59
static int hf_hdfsdata_cmd;
60
static int hf_hdfsdata_blockid;
61
static int hf_hdfsdata_timestamp;
62
static int hf_hdfsdata_startoffset;
63
static int hf_hdfsdata_blocklen;
64
static int hf_hdfsdata_clientlen;
65
static int hf_hdfsdata_clientid;
66
static int hf_hdfsdata_tokenlen;
67
static int hf_hdfsdata_tokenid;
68
static int hf_hdfsdata_tokenpassword;
69
static int hf_hdfsdata_tokentype;
70
static int hf_hdfsdata_tokenservice;
71
static int hf_hdfsdata_status;
72
static int hf_hdfsdata_checksumtype;
73
static int hf_hdfsdata_chunksize;
74
static int hf_hdfsdata_chunkoffset;
75
static int hf_hdfsdata_datalength;
76
static int hf_hdfsdata_inblockoffset;
77
static int hf_hdfsdata_seqnum;
78
static int hf_hdfsdata_last;
79
static int hf_hdfsdata_crc32;
80
static int hf_hdfsdata_datalen;
81
static int hf_hdfsdata_rest;
82
static int hf_hdfsdata_end;
83
static int hf_hdfsdata_packetsize;
84
static int hf_hdfsdata_chunklength;
85
static int hf_hdfsdata_crc64;
86
static int hf_hdfsdata_pipelinestatus;
87
88
static int hf_hdfsdata_pipelinenum;
89
static int hf_hdfsdata_recovery;
90
static int hf_hdfsdata_sourcenode;
91
static int hf_hdfsdata_currentpipeline;
92
static int hf_hdfsdata_node;
93
94
static int ett_hdfsdata;
95
96
static dissector_handle_t hdfsdata_handle;
97
98
/* Taken from HDFS
99
   Parse the first byte of a vint/vlong to determine the number of bytes
100
   value is the first byte of the vint/vlong
101
   returns the total number of bytes (1 to 9) */
102
static int
103
0
decode_vint_size (int8_t value) {
104
0
  if (value >= -112) {
105
0
    return 1;
106
0
  } else if (value < -120) {
107
0
    return -119 - value;
108
0
  }
109
0
  return -111 - value;
110
0
}
111
112
/* Taken from HDFS
113
   converts a variable length number into a long and discovers how many bytes it is
114
   returns the decoded number */
115
static unsigned
116
dissect_variable_length_long (tvbuff_t *tvb, proto_tree *hdfsdata_tree, int* offset)
117
0
{
118
0
  int byte_count = 1;
119
0
  int idx = 0;
120
0
  unsigned i = 0;
121
0
  int8_t first_byte = tvb_get_uint8(tvb, *offset);
122
0
  unsigned size = 0;
123
124
0
  int len = decode_vint_size(first_byte);
125
0
  if (len == 1) {
126
0
    proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_clientlen, tvb, *offset, byte_count, ENC_BIG_ENDIAN);
127
0
    *offset = (*offset) + byte_count;
128
0
    return first_byte;
129
0
  }
130
131
0
  for  (idx = 0; idx < len-1; idx++) {
132
0
    char b = tvb_get_uint8(tvb, *offset + byte_count);
133
0
    byte_count++;
134
0
    i = i << 8;
135
0
    i = i | (b & 0xFF);
136
0
  }
137
0
  size = ((first_byte < -120 || (first_byte >= -112 && first_byte < 0)) ? (i ^ 0xFFFFFFFF) : i);
138
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_clientlen, tvb, *offset, byte_count, ENC_BIG_ENDIAN);
139
0
  *offset = (*offset) + byte_count;
140
141
0
  return size;
142
0
}
143
144
/* dissects a variable length int and then using its value dissects the following string */
145
static void
146
dissect_variable_int_string(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int *offset)
147
0
{
148
  /* Get the variable length int that represents the length of the next field */
149
0
  int len = dissect_variable_length_long (tvb, hdfsdata_tree, offset);
150
151
  /* client id = amount of bytes in previous */
152
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_clientid, tvb, *offset, len, ENC_ASCII);
153
0
  *offset += len;
154
0
}
155
156
/* dissects the access tokens that appear at the end of requests.
157
 tokens: id, password, kind, service */
158
static void
159
dissect_access_tokens(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int *offset)
160
0
{
161
0
  int len = 0;
162
163
0
  len = tvb_get_uint8(tvb, *offset);
164
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_tokenlen, tvb, *offset, 1, ENC_BIG_ENDIAN);
165
0
  *offset += 1;
166
167
  /* token id = amount of bytes in previous */
168
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_tokenid, tvb, *offset, len, ENC_ASCII);
169
0
  *offset += len;
170
171
0
  len = tvb_get_uint8(tvb, *offset);
172
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_tokenlen, tvb, *offset, 1, ENC_BIG_ENDIAN);
173
0
  *offset += 1;
174
175
  /* token password = amount of bytes in previous */
176
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_tokenpassword, tvb, *offset, len, ENC_ASCII);
177
0
  *offset += len;
178
179
0
  len = tvb_get_uint8(tvb, *offset);
180
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_tokenlen, tvb, *offset, 1, ENC_BIG_ENDIAN);
181
0
  *offset += 1;
182
183
  /* token type = amount of bytes in previous */
184
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_tokentype, tvb, *offset, len, ENC_ASCII);
185
0
  *offset += len;
186
187
0
  len = tvb_get_uint8(tvb, *offset);
188
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_tokenlen, tvb, *offset, 1, ENC_BIG_ENDIAN);
189
0
  *offset += 1;
190
191
  /* token service = amount of bytes in previous; */
192
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_tokenservice, tvb, *offset, len, ENC_ASCII);
193
0
  *offset += len;
194
0
}
195
196
/* handles parsing read response packets */
197
static void
198
dissect_read_response(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int offset)
199
0
{
200
0
  int len = 0;
201
0
  uint32_t chunksize;
202
203
  /* 4 bytes = data length */
204
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_datalength, tvb, offset, 4, ENC_BIG_ENDIAN);
205
0
  offset += 4;
206
207
  /* 8 bytes = in block offset */
208
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_inblockoffset, tvb, offset, 8, ENC_BIG_ENDIAN);
209
0
  offset += 8;
210
211
  /* 8 bytes = sequence number */
212
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_seqnum, tvb, offset, 8, ENC_BIG_ENDIAN);
213
0
  offset += 8;
214
215
  /* 1 byte = last packet in block */
216
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_last, tvb, offset, 1, ENC_BIG_ENDIAN);
217
0
  offset += 1;
218
219
  /* 4 byte = length of data */
220
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_datalen, tvb, offset, 4, ENC_BIG_ENDIAN);
221
0
  offset += 4;
222
223
  /* if there is a crc checksum it is 8* the length of the data * checksum size / chunksize */
224
0
  chunksize = tvb_get_ntohl(tvb, CHUNKSIZE_START);
225
0
  if (chunksize == 0)   /* let's not divide by zero */
226
0
    return;
227
0
  if (tvb_get_uint8(tvb, 2) == CRC) {
228
0
    len = (int)(CRC_SIZE * tvb_get_ntohl(tvb, offset - 4) *
229
0
      tvb_get_ntohl(tvb, offset - 8) / chunksize);
230
0
  }
231
232
  /* the rest of bytes (usually 4) = crc32 code */
233
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_crc32, tvb, offset, len, ENC_BIG_ENDIAN);
234
  /* offset += len; */
235
0
}
236
237
/* dissects the first packet of the read response */
238
static void
239
0
dissect_read_response_start(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int offset) {
240
  /* 2 bytes = status code */
241
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_status, tvb, offset, 2, ENC_BIG_ENDIAN);
242
0
  offset += 2;
243
244
  /* checksum type = 1 byte. 1 = crc32, 0 = null */
245
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_checksumtype, tvb, offset, 1, ENC_BIG_ENDIAN);
246
0
  offset += 1;
247
248
  /* 4 bytes = chunksize */
249
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_chunksize, tvb, offset, 4, ENC_BIG_ENDIAN);
250
0
  offset += 4;
251
252
  /* 8 bytes = chunk offset */
253
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_chunkoffset, tvb, offset, 8, ENC_BIG_ENDIAN);
254
  /* offset += 8; */
255
0
}
256
257
/* dissects the fields specific to a read request */
258
static void
259
dissect_read_request(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int *offset)
260
0
{
261
262
  /* 8 bytes = start offset */
263
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_startoffset, tvb, *offset, 8, ENC_BIG_ENDIAN);
264
0
  *offset += 8;
265
266
  /* 8 bytes = block length */
267
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_blocklen, tvb, *offset, 8, ENC_BIG_ENDIAN);
268
0
  *offset += 8;
269
270
0
}
271
272
/* dissects the fields specific to a write request */
273
static void
274
dissect_write_request(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int *offset)
275
0
{
276
  /* 4 bytes = number of nodes in pipeline */
277
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_pipelinenum, tvb, *offset, 4, ENC_BIG_ENDIAN);
278
0
  *offset += 4;
279
280
  /* 1 bytes = recovery boolean */
281
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_recovery, tvb, *offset, 1, ENC_BIG_ENDIAN);
282
0
  *offset += 1;
283
0
}
284
285
/* dissects the fields specific to a write request */
286
static void
287
dissect_write_request_end(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int *offset)
288
0
{
289
0
  int i = 0;
290
0
  int len = 0;
291
292
  /* 1 bytes = source node */
293
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_sourcenode, tvb, *offset, 1, ENC_BIG_ENDIAN);
294
0
  *offset += 1;
295
296
  /* 4 bytes = number of nodes currently in the pipeline (usually just -1 of before) */
297
0
  len = tvb_get_ntohl(tvb, *offset);
298
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_currentpipeline, tvb, *offset, 4, ENC_BIG_ENDIAN);
299
0
  *offset += 4;
300
301
  /* variable length sequence of node objects */
302
0
  for (i = 0; i < len; i++) {
303
0
    proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_node, tvb, *offset, 4, ENC_BIG_ENDIAN);
304
0
    *offset += 4;
305
0
  }
306
0
}
307
308
/* dissects the beginning of the read and write request messages */
309
static int
310
0
dissect_header(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int* offset){
311
312
0
  int command = 0;
313
314
  /* 2 bytes = protocol version */
315
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_version, tvb, *offset, 2, ENC_BIG_ENDIAN);
316
0
  *offset += 2;
317
318
  /* 1 byte = command */
319
0
  command = tvb_get_uint8(tvb, *offset);
320
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_cmd, tvb, *offset, 1, ENC_BIG_ENDIAN);
321
0
  *offset += 1;
322
323
  /* 8 bytes = block id */
324
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_blockid, tvb, *offset, 8, ENC_BIG_ENDIAN);
325
0
  *offset += 8;
326
327
  /* 8 bytes = timestamp */
328
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_timestamp, tvb, *offset, 8, ENC_BIG_ENDIAN);
329
0
  *offset += 8;
330
331
0
  return command;
332
0
}
333
334
/* decodes the write response messages */
335
static void
336
dissect_write_response(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int offset)
337
0
{
338
  /* 4 bytes = packetsize */
339
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_packetsize, tvb, offset, 4, ENC_BIG_ENDIAN);
340
0
  offset += 4;
341
342
  /* 8 bytes = offset in block */
343
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_startoffset, tvb, offset, 8, ENC_BIG_ENDIAN);
344
0
  offset += 8;
345
346
  /* 8 bytes = sequence number */
347
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_seqnum, tvb, offset, 8, ENC_BIG_ENDIAN);
348
0
  offset += 8;
349
350
  /* 1 bytes = last packet */
351
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_last, tvb, offset, 1, ENC_BIG_ENDIAN);
352
0
  offset += 1;
353
354
  /* 4 bytes = chunk length */
355
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_chunklength, tvb, offset, 4, ENC_BIG_ENDIAN);
356
0
  offset += 4;
357
358
  /* 8 bytes = crc code */
359
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_crc64, tvb, offset, 8, ENC_BIG_ENDIAN);
360
0
  offset += 8;
361
362
  /* add the rest -> RESPONSE_DATA */
363
0
  proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_rest, tvb, offset, (tvb_reported_length(tvb)) - offset, ENC_ASCII);
364
   /* offset += (tvb_reported_length(tvb)); */
365
0
}
366
367
/* determine PDU length of protocol  */
368
static unsigned
369
get_hdfsdata_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
370
0
{
371
  /* get data packet len, add FIRST_READ_FRAGMENT_LEN for first fragment (before len),
372
     SECOND_READ_FRAGMENT_LEN for second fragment (incl len), subtract 4 for length itself. */
373
374
0
  if (tvb_reported_length(tvb) <= 4 || tvb_reported_length(tvb) == END_PACKET_LEN
375
0
    || tvb_get_ntohl(tvb, 0) == tvb_reported_length(tvb) - WRITE_RESP_HEAD_LEN
376
0
    || (tvb_reported_length(tvb) >= MIN_READ_REQ && tvb_get_uint8(tvb, 2) == READ_OP)
377
0
    || (tvb_reported_length(tvb) >= MIN_WRITE_REQ && tvb_get_uint8(tvb, 2) == WRITE_OP)) {
378
379
0
    return tvb_reported_length(tvb);
380
0
  }
381
0
  return tvb_get_ntohl(tvb, offset + FIRST_READ_FRAGMENT_LEN) +
382
0
    FIRST_READ_FRAGMENT_LEN + SECOND_READ_FRAGMENT_LEN - LAST_READ_FRAGMENT_LEN;
383
0
}
384
385
/* This method dissects fully reassembled messages */
386
static int
387
dissect_hdfsdata_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
388
0
{
389
0
  int offset = 0;
390
391
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "HDFSDATA");
392
  /* Clear out stuff in the info column */
393
0
  col_set_str(pinfo->cinfo, COL_INFO, "HDFS Data");
394
395
396
0
  if (tree) {
397
0
    proto_item *ti = NULL;
398
0
    proto_tree *hdfsdata_tree = NULL;
399
400
0
    ti = proto_tree_add_item(tree, proto_hdfsdata, tvb, offset, -1, ENC_NA);
401
0
    hdfsdata_tree = proto_item_add_subtree(ti, ett_hdfsdata);
402
403
    /* if only 1 bytes packet must just contain just the pipeline status */
404
0
    if ((tvb_reported_length(tvb)) == PIPELINE_LEN) {
405
406
      /* 1 bytes = pipeline status */
407
0
      proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_pipelinestatus, tvb, offset, PIPELINE_LEN, ENC_BIG_ENDIAN);
408
409
    /* if only 2 bytes packet must just contain just a status code */
410
0
    } else if ((tvb_reported_length(tvb)) == STATUS_LEN) {
411
      /* 2 bytes = status code */
412
0
      proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_status, tvb, offset, STATUS_LEN, ENC_BIG_ENDIAN);
413
414
    /* if it is 4 bytes long it must be a finish request packet */
415
0
    } else if ((tvb_reported_length(tvb)) == FINISH_REQ_LEN) {
416
0
      proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_end, tvb, offset, 4, ENC_BIG_ENDIAN);
417
418
    /* read response packet */
419
0
    } else if (tvb_reported_length(tvb) >= READ_RESP_HEAD_LEN && tvb_reported_length(tvb) ==
420
0
      tvb_get_ntohl(tvb, FIRST_READ_FRAGMENT_LEN) +
421
0
      FIRST_READ_FRAGMENT_LEN + SECOND_READ_FRAGMENT_LEN - LAST_READ_FRAGMENT_LEN){
422
423
0
      dissect_read_response_start(tvb, hdfsdata_tree, offset);
424
0
      offset += FIRST_READ_FRAGMENT_LEN;
425
426
0
      dissect_read_response(tvb, hdfsdata_tree, offset);
427
0
      offset+= SECOND_READ_FRAGMENT_LEN;
428
429
      /* This message just contains data so we can display it all as one block */
430
431
0
      proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_rest, tvb, offset, (tvb_reported_length(tvb)) - offset, ENC_ASCII);
432
433
0
    } else {
434
435
0
      uint8_t op = tvb_get_uint8(tvb, 2);
436
437
      /* READ  request */
438
0
      if ((tvb_reported_length(tvb)) >= MIN_READ_REQ && op == READ_OP) {
439
0
        dissect_header(tvb, hdfsdata_tree, &offset);
440
0
        dissect_read_request(tvb, hdfsdata_tree, &offset);
441
0
        dissect_variable_int_string(tvb, hdfsdata_tree, &offset);
442
0
        dissect_access_tokens(tvb, hdfsdata_tree, &offset);
443
444
      /* WRITE request */
445
0
      } else if ((tvb_reported_length(tvb)) >= MIN_WRITE_REQ && op == WRITE_OP) {
446
0
        dissect_header(tvb, hdfsdata_tree, &offset);
447
0
        dissect_write_request(tvb, hdfsdata_tree, &offset);
448
0
        dissect_variable_int_string(tvb, hdfsdata_tree, &offset);
449
0
        dissect_write_request_end(tvb, hdfsdata_tree, &offset);
450
0
        dissect_access_tokens(tvb, hdfsdata_tree, &offset);
451
452
        /* checksum type = 1 byte. 1 = crc32, 0 = null */
453
0
        proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_checksumtype, tvb, offset, 1, ENC_BIG_ENDIAN);
454
0
        offset += 1;
455
456
        /* 4 bytes = chunksize */
457
0
        proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_chunksize, tvb, offset, 4, ENC_BIG_ENDIAN);
458
459
      /* write responses store the data length in the first 4 bytes. This length does not
460
         include 21 bits of header */
461
0
      } else if (tvb_reported_length(tvb) >= 4 && tvb_get_ntohl(tvb, 0) ==
462
0
        tvb_reported_length(tvb) - WRITE_RESP_HEAD_LEN) {
463
464
0
        dissect_write_response(tvb, hdfsdata_tree, offset);
465
466
0
      } else {
467
        /* This message contains some form of data that we have not successfully been able to
468
           pattern match and catagorize. Display all of it as data. */
469
0
        proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_rest, tvb, offset, (tvb_reported_length(tvb)), ENC_ASCII);
470
0
      }
471
0
    }
472
0
  }
473
474
0
  return tvb_captured_length(tvb);
475
0
}
476
477
static int
478
dissect_hdfsdata(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
479
0
{
480
0
  int frame_header_len = 0;
481
482
0
  bool need_reassemble = false;
483
0
  uint8_t op = 0;
484
0
  bool only_packet = tvb_reported_length(tvb) == 1 || (tvb_reported_length(tvb) == 2 &&
485
0
    tvb_get_ntohs(tvb, 0) == STATUS_SUCCESS);
486
487
0
  if (tvb_reported_length(tvb) >= 3)
488
0
    op = tvb_get_uint8(tvb, 2);
489
490
0
  if (!only_packet && tvb_reported_length(tvb) != 4 && !(tvb_reported_length(tvb) >= MIN_READ_REQ && op == READ_OP) &&
491
0
    !(tvb_reported_length(tvb) >= MIN_WRITE_REQ && op == WRITE_OP) && !(tvb_reported_length(tvb) == END_PACKET_LEN &&
492
0
    !tvb_get_ntohl(tvb, 0) && !tvb_get_ntohl(tvb, 4))) {
493
494
0
    need_reassemble = true;
495
0
  }
496
497
  /* setting the header size for the different types of packets */
498
0
  if (only_packet || tvb_reported_length(tvb) == END_PACKET_LEN) {
499
0
    frame_header_len = tvb_reported_length(tvb);
500
501
0
  } else if (tvb_reported_length(tvb) == FIRST_READ_FRAGMENT_LEN ||(tvb_reported_length(tvb) >= MIN_READ_REQ &&
502
0
    op == READ_OP && !((tvb_reported_length(tvb)) == 2 && !tvb_get_ntohs(tvb, 0)))) {
503
504
0
    frame_header_len = READ_RESP_HEAD_LEN;
505
506
0
  } else if (tvb_reported_length(tvb) >= MIN_WRITE_REQ && op == WRITE_OP) {
507
0
    frame_header_len = WRITE_REQ_HEAD_LEN;
508
0
  }
509
510
0
  tcp_dissect_pdus(tvb, pinfo, tree, need_reassemble, frame_header_len, get_hdfsdata_message_len, dissect_hdfsdata_message, data);
511
0
  return tvb_captured_length(tvb);
512
0
}
513
514
/* registers the protocol with the given names */
515
void
516
proto_register_hdfsdata(void)
517
14
{
518
14
    static hf_register_info hf[] = {
519
520
  /* list of all options for dissecting the protocol */
521
522
  /*************************************************
523
  Read request
524
  **************************************************/
525
14
  { &hf_hdfsdata_version,
526
14
    { "HDFSDATA protocol version", "hdfsdata.version",
527
14
      FT_UINT16, BASE_DEC,
528
14
      NULL, 0x0,
529
14
      NULL, HFILL }
530
14
  },
531
14
  { &hf_hdfsdata_cmd,
532
14
    { "HDFSDATA command", "hdfsdata.cmd",
533
14
      FT_UINT8, BASE_DEC,
534
14
      NULL, 0x0,
535
14
      NULL, HFILL }
536
14
  },
537
14
  { &hf_hdfsdata_blockid,
538
14
    { "HDFSDATA block id", "hdfsdata.blockid",
539
14
      FT_UINT64, BASE_DEC,
540
14
      NULL, 0x0,
541
14
      NULL, HFILL }
542
14
  },
543
14
  { &hf_hdfsdata_timestamp,
544
14
    { "HDFSDATA timestamp", "hdfsdata.timestamp",
545
14
      FT_UINT64, BASE_DEC,
546
14
      NULL, 0x0,
547
14
      NULL, HFILL }
548
14
  },
549
  /***
550
  Read specific
551
  ***/
552
14
  { &hf_hdfsdata_startoffset,
553
14
    { "HDFSDATA start offset", "hdfsdata.startoffset",
554
14
      FT_UINT64, BASE_DEC,
555
14
      NULL, 0x0,
556
14
      NULL, HFILL }
557
14
  },
558
14
  { &hf_hdfsdata_blocklen,
559
14
    { "HDFSDATA block length", "hdfsdata.blocklen",
560
14
      FT_UINT64, BASE_DEC,
561
14
      NULL, 0x0,
562
14
      NULL, HFILL }
563
14
  },
564
  /***
565
  Write specific
566
  ***/
567
14
  { &hf_hdfsdata_pipelinenum,
568
14
    { "HDFSDATA number in pipeline", "hdfsdata.pipelinenum",
569
14
      FT_UINT32, BASE_DEC,
570
14
      NULL, 0x0,
571
14
      NULL, HFILL }
572
14
  },
573
14
  { &hf_hdfsdata_recovery,
574
14
    { "HDFSDATA recovery boolean", "hdfsdata.recovery",
575
14
      FT_UINT8, BASE_DEC,
576
14
      NULL, 0x0,
577
14
      NULL, HFILL }
578
14
  },
579
14
  { &hf_hdfsdata_sourcenode,
580
14
    { "HDFSDATA source node", "hdfsdata.sourcenode",
581
14
      FT_UINT8, BASE_DEC,
582
14
      NULL, 0x0,
583
14
      NULL, HFILL }
584
14
  },
585
14
  { &hf_hdfsdata_currentpipeline,
586
14
    { "HDFSDATA current number of nodes in the pipeline", "hdfsdata.currentpipeline",
587
14
      FT_UINT32, BASE_DEC,
588
14
      NULL, 0x0,
589
14
      NULL, HFILL }
590
14
  },
591
14
  { &hf_hdfsdata_node,
592
14
    { "HDFSDATA node object", "hdfsdata.node",
593
14
      FT_UINT32, BASE_DEC,
594
14
      NULL, 0x0,
595
14
      NULL, HFILL }
596
14
  },
597
  /***
598
  Var length
599
  **/
600
14
  { &hf_hdfsdata_clientlen,
601
14
    { "HDFSDATA client id length", "hdfsdata.clientlen",
602
14
      FT_UINT8, BASE_DEC,
603
14
      NULL, 0x0,
604
14
      NULL, HFILL }
605
14
  },
606
14
  { &hf_hdfsdata_clientid,
607
14
    { "HDFSDATA client id", "hdfsdata.clientid",
608
14
      FT_STRING, BASE_NONE,
609
14
      NULL, 0x0,
610
14
      NULL, HFILL }
611
14
  },
612
14
  { &hf_hdfsdata_end,
613
14
    { "HDFSDATA end data request", "hdfsdata.end",
614
14
      FT_UINT32, BASE_DEC,
615
14
      NULL, 0x0,
616
14
      NULL, HFILL }
617
14
  },
618
  /*************************************************
619
  Access tokens
620
  **************************************************/
621
14
  { &hf_hdfsdata_tokenlen,
622
14
    { "HDFSDATA access token length", "hdfsdata.tokenlen",
623
14
      FT_UINT8, BASE_DEC,
624
14
      NULL, 0x0,
625
14
      NULL, HFILL }
626
14
  },
627
14
  { &hf_hdfsdata_tokenid,
628
14
    { "HDFSDATA access token ID", "hdfsdata.tokenid",
629
14
      FT_STRING, BASE_NONE,
630
14
      NULL, 0x0,
631
14
      NULL, HFILL }
632
14
  },
633
14
  { &hf_hdfsdata_tokenpassword,
634
14
    { "HDFSDATA access token password", "hdfsdata.tokenpassword",
635
14
      FT_STRING, BASE_NONE,
636
14
      NULL, 0x0,
637
14
      NULL, HFILL }
638
14
  },
639
14
  { &hf_hdfsdata_tokentype,
640
14
    { "HDFSDATA access token type", "hdfsdata.tokentype",
641
14
      FT_STRING, BASE_NONE,
642
14
      NULL, 0x0,
643
14
      NULL, HFILL }
644
14
  },
645
14
  { &hf_hdfsdata_tokenservice,
646
14
    { "HDFSDATA access token service", "hdfsdata.tokenservice",
647
14
      FT_STRING, BASE_NONE,
648
14
      NULL, 0x0,
649
14
      NULL, HFILL }
650
14
  },
651
  /***********************************************
652
  Responses 1
653
  ***********************************************/
654
14
  { &hf_hdfsdata_status,
655
14
    { "HDFSDATA status code", "hdfsdata.status",
656
14
      FT_UINT16, BASE_DEC,
657
14
      NULL, 0x0,
658
14
      NULL, HFILL }
659
14
  },
660
14
  { &hf_hdfsdata_checksumtype,
661
14
    { "HDFSDATA checksum type", "hdfsdata.checksumtype",
662
14
      FT_UINT8, BASE_DEC,
663
14
      NULL, 0x0,
664
14
      NULL, HFILL }
665
14
  },
666
14
  { &hf_hdfsdata_chunksize,
667
14
    { "HDFSDATA chunk size", "hdfsdata.chunksize",
668
14
      FT_UINT32, BASE_DEC,
669
14
      NULL, 0x0,
670
14
      NULL, HFILL }
671
14
  },
672
14
  { &hf_hdfsdata_chunkoffset,
673
14
    { "HDFSDATA chunk offset", "hdfsdata.chunkoffset",
674
14
      FT_UINT64, BASE_DEC,
675
14
      NULL, 0x0,
676
14
      NULL, HFILL }
677
14
  },
678
  /***********************************************
679
  Responses 2
680
  ***********************************************/
681
14
  { &hf_hdfsdata_datalength,
682
14
    { "HDFSDATA length of data", "hdfsdata.datalength",
683
14
      FT_UINT32, BASE_DEC,
684
14
      NULL, 0x0,
685
14
      NULL, HFILL }
686
14
  },
687
14
  { &hf_hdfsdata_inblockoffset,
688
14
    { "HDFSDATA in block offset", "hdfsdata.inblockoffset",
689
14
      FT_UINT64, BASE_DEC,
690
14
      NULL, 0x0,
691
14
      NULL, HFILL }
692
14
  },
693
14
  { &hf_hdfsdata_seqnum,
694
14
    { "HDFSDATA sequence number", "hdfsdata.seqnum",
695
14
      FT_UINT64, BASE_DEC,
696
14
      NULL, 0x0,
697
14
      NULL, HFILL }
698
14
  },
699
14
  { &hf_hdfsdata_last,
700
14
    { "HDFSDATA last packet in block", "hdfsdata.last",
701
14
      FT_INT8, BASE_DEC,
702
14
      NULL, 0x0,
703
14
      NULL, HFILL }
704
14
  },
705
14
  { &hf_hdfsdata_datalen,
706
14
    { "HDFSDATA length of data", "hdfsdata.datalen",
707
14
      FT_INT32, BASE_DEC,
708
14
      NULL, 0x0,
709
14
      NULL, HFILL }
710
14
  },
711
14
  { &hf_hdfsdata_crc32,
712
14
    { "HDFSDATA crc32 checksum", "hdfsdata.crc32",
713
14
      FT_INT32, BASE_DEC,
714
14
      NULL, 0x0,
715
14
      NULL, HFILL }
716
14
  },
717
  /***********************************************
718
  Responses 3
719
  ***********************************************/
720
14
  { &hf_hdfsdata_rest,
721
14
    { "HDFSDATA data", "hdfsdata.rest",
722
14
      FT_STRING, BASE_NONE,
723
14
      NULL, 0x0,
724
14
      NULL, HFILL }
725
14
  },
726
  /***********************************************
727
  Write Response 1
728
  ***********************************************/
729
14
  { &hf_hdfsdata_packetsize,
730
14
    { "HDFSDATA packet size", "hdfsdata.packetsize",
731
14
      FT_UINT32, BASE_DEC,
732
14
      NULL, 0x0,
733
14
      NULL, HFILL }
734
14
  },
735
14
  { &hf_hdfsdata_chunklength,
736
14
    { "HDFSDATA chunk length", "hdfsdata.chunklength",
737
14
      FT_UINT32, BASE_DEC,
738
14
      NULL, 0x0,
739
14
      NULL, HFILL }
740
14
  },
741
14
  { &hf_hdfsdata_crc64,
742
14
    { "HDFSDATA crc64 checksum", "hdfsdata.crc64",
743
14
      FT_INT64, BASE_DEC,
744
14
      NULL, 0x0,
745
14
      NULL, HFILL }
746
14
  },
747
14
  { &hf_hdfsdata_pipelinestatus,
748
14
    { "HDFSDATA pipeline status", "hdfsdata.pipelinestatus",
749
14
      FT_INT8, BASE_DEC,
750
14
      NULL, 0x0,
751
14
      NULL, HFILL }
752
14
  },
753
14
    };
754
755
    /* Setup protocol subtree array */
756
14
    static int *ett[] = {
757
14
        &ett_hdfsdata
758
14
    };
759
760
14
    proto_hdfsdata = proto_register_protocol ("HDFSDATA Protocol", "HDFSDATA", "hdfsdata");
761
762
14
    proto_register_field_array(proto_hdfsdata, hf, array_length(hf));
763
14
    proto_register_subtree_array(ett, array_length(ett));
764
765
14
    hdfsdata_handle = register_dissector("hdfsdata", dissect_hdfsdata, proto_hdfsdata);
766
14
}
767
768
/* registers handoff */
769
void
770
proto_reg_handoff_hdfsdata(void)
771
14
{
772
14
    dissector_add_for_decode_as_with_preference("tcp.port", hdfsdata_handle);
773
14
}
774
/*
775
 * Editor modelines
776
 *
777
 * Local Variables:
778
 * c-basic-offset: 2
779
 * tab-width: 8
780
 * indent-tabs-mode: nil
781
 * End:
782
 *
783
 * ex: set shiftwidth=2 tabstop=8 expandtab:
784
 * :indentSize=2:tabSize=8:noTabs=true:
785
 */