HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-hdfsdata.c
bloba3f0ba79589079a4dbd88bc43187716d8dc29a04
1 /* packet-hdfsdata.c
2 * HDFS data Protocol and dissectors
4 * Copyright (c) 2011 by Isilon Systems.
6 * Author: Allison Obourn <aobourn@isilon.com>
8 * $Id$
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1999 Gerald Combs
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include "config.h"
32 #include <epan/packet.h>
33 #include <epan/prefs.h>
34 #include "epan/dissectors/packet-tcp.h"
37 #if 0
38 #define NAMENODE_PORT 8020
39 #define DATANODE_PORT 8021
40 #endif
42 #define FIRST_READ_FRAGMENT_LEN 15
43 #define SECOND_READ_FRAGMENT_LEN 29
44 #define LAST_READ_FRAGMENT_LEN 4
45 #define WRITE_OP 80
46 #define READ_OP 81
47 #define MIN_WRITE_REQ 35
48 #define MIN_READ_REQ 36
50 #define STATUS_SUCCESS 6
51 #define PIPELINE_LEN 1
52 #define STATUS_LEN 2
53 #define FINISH_REQ_LEN 4
54 #define END_PACKET_LEN 8
55 #define READ_RESP_HEAD_LEN 19
56 #define WRITE_RESP_HEAD_LEN 21
57 #define WRITE_REQ_HEAD_LEN 7
59 #define CRC 1
60 #define CRC_SIZE 8.0
61 #define CHUNKSIZE_START 3
64 #if 0
65 static const int RESPONSE_HEADER = 1;
66 static const int RESPONSE_METADATA = 2;
67 static const int RESPONSE_DATA = 3;
68 #endif
70 static guint tcp_port = 0;
72 static int proto_hdfsdata = -1;
73 static int hf_hdfsdata_version = -1;
74 static int hf_hdfsdata_cmd = -1;
75 static int hf_hdfsdata_blockid = -1;
76 static int hf_hdfsdata_timestamp = -1;
77 static int hf_hdfsdata_startoffset = -1;
78 static int hf_hdfsdata_blocklen = -1;
79 static int hf_hdfsdata_clientlen = -1;
80 static int hf_hdfsdata_clientid = -1;
81 static int hf_hdfsdata_tokenlen = -1;
82 static int hf_hdfsdata_tokenid = -1;
83 static int hf_hdfsdata_tokenpassword = -1;
84 static int hf_hdfsdata_tokentype = -1;
85 static int hf_hdfsdata_tokenservice = -1;
86 static int hf_hdfsdata_status = -1;
87 static int hf_hdfsdata_checksumtype = -1;
88 static int hf_hdfsdata_chunksize = -1;
89 static int hf_hdfsdata_chunkoffset = -1;
90 static int hf_hdfsdata_datalength = -1;
91 static int hf_hdfsdata_inblockoffset = -1;
92 static int hf_hdfsdata_seqnum = -1;
93 static int hf_hdfsdata_last = -1;
94 static int hf_hdfsdata_crc32 = -1;
95 static int hf_hdfsdata_datalen = -1;
96 static int hf_hdfsdata_rest = -1;
97 static int hf_hdfsdata_end = -1;
98 static int hf_hdfsdata_packetsize = -1;
99 static int hf_hdfsdata_chunklength = -1;
100 static int hf_hdfsdata_crc64 = -1;
101 static int hf_hdfsdata_pipelinestatus = -1;
103 static int hf_hdfsdata_pipelinenum = -1;
104 static int hf_hdfsdata_recovery = -1;
105 static int hf_hdfsdata_sourcenode = -1;
106 static int hf_hdfsdata_currentpipeline = -1;
107 static int hf_hdfsdata_node = -1;
109 static gint ett_hdfsdata = -1;
111 static dissector_handle_t hdfsdata_handle;
113 void proto_reg_handoff_hdfsdata(void);
115 /* Taken from HDFS
116 Parse the first byte of a vint/vlong to determine the number of bytes
117 value is the first byte of the vint/vlong
118 returns the total number of bytes (1 to 9) */
119 static int
120 decode_vint_size (char value) {
121 if (value >= -112) {
122 return 1;
123 } else if (value < -120) {
124 return -119 - value;
126 return -111 - value;
129 /* Taken from HDFS
130 converts a variable length number into a long and discovers how many bytes it is
131 returns the decoded number */
132 static guint
133 dissect_variable_length_long (tvbuff_t *tvb, proto_tree *hdfsdata_tree, int* offset)
135 int byte_count = 1;
136 int idx = 0;
137 guint i = 0;
138 gint8 first_byte = tvb_get_guint8(tvb, *offset);
139 guint size = 0;
141 int len = decode_vint_size(first_byte);
142 if (len == 1) {
143 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_clientlen, tvb, *offset, byte_count, ENC_BIG_ENDIAN);
144 *offset = (*offset) + byte_count;
145 return first_byte;
148 for (idx = 0; idx < len-1; idx++) {
149 char b = tvb_get_guint8(tvb, *offset + byte_count);
150 byte_count++;
151 i = i << 8;
152 i = i | (b & 0xFF);
154 size = ((first_byte < -120 || (first_byte >= -112 && first_byte < 0)) ? (i ^ 0xFFFFFFFF) : i);
155 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_clientlen, tvb, *offset, byte_count, ENC_BIG_ENDIAN);
156 *offset = (*offset) + byte_count;
158 return size;
161 /* dissects a variable length int and then using its value dissects the following string */
162 static void
163 dissect_variable_int_string(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int *offset)
165 /* Get the variable length int that represents the length of the next feild */
166 int len = dissect_variable_length_long (tvb, hdfsdata_tree, offset);
168 /* client id = amount of bytes in previous */
169 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_clientid, tvb, *offset, len, ENC_ASCII|ENC_NA);
170 *offset += len;
173 /* dissects the access tokens that appear at the end of requests.
174 tokens: id, password, kind, service */
175 static void
176 dissect_access_tokens(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int *offset)
178 int len = 0;
180 len = tvb_get_guint8(tvb, *offset);
181 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_tokenlen, tvb, *offset, 1, ENC_BIG_ENDIAN);
182 *offset += 1;
184 /* token id = amount of bytes in previous */
185 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_tokenid, tvb, *offset, len, ENC_ASCII|ENC_NA);
186 *offset += len;
188 len = tvb_get_guint8(tvb, *offset);
189 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_tokenlen, tvb, *offset, 1, ENC_BIG_ENDIAN);
190 *offset += 1;
192 /* token password = amount of bytes in previous */
193 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_tokenpassword, tvb, *offset, len, ENC_ASCII|ENC_NA);
194 *offset += len;
196 len = tvb_get_guint8(tvb, *offset);
197 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_tokenlen, tvb, *offset, 1, ENC_BIG_ENDIAN);
198 *offset += 1;
200 /* token type = amount of bytes in previous */
201 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_tokentype, tvb, *offset, len, ENC_ASCII|ENC_NA);
202 *offset += len;
204 len = tvb_get_guint8(tvb, *offset);
205 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_tokenlen, tvb, *offset, 1, ENC_BIG_ENDIAN);
206 *offset += 1;
208 /* token service = amount of bytes in previous; */
209 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_tokenservice, tvb, *offset, len, ENC_ASCII|ENC_NA);
210 *offset += len;
213 /* handles parsing read response packets */
214 static void
215 dissect_read_response(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int offset)
217 int len = 0;
218 guint32 chunksize;
220 /* 4 bytes = data length */
221 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_datalength, tvb, offset, 4, ENC_BIG_ENDIAN);
222 offset += 4;
224 /* 8 bytes = in block offset */
225 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_inblockoffset, tvb, offset, 8, ENC_BIG_ENDIAN);
226 offset += 8;
228 /* 8 bytes = sequence number */
229 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_seqnum, tvb, offset, 8, ENC_BIG_ENDIAN);
230 offset += 8;
232 /* 1 byte = last packet in block */
233 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_last, tvb, offset, 1, ENC_BIG_ENDIAN);
234 offset += 1;
236 /* 4 byte = length of data */
237 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_datalen, tvb, offset, 4, ENC_BIG_ENDIAN);
238 offset += 4;
240 /* if there is a crc checksum it is 8* the length of the data * checksum size / chunksize */
241 chunksize = tvb_get_ntohl(tvb, CHUNKSIZE_START);
242 if (chunksize == 0) /* let's not divide by zero */
243 return;
244 if (tvb_get_guint8(tvb, 2) == CRC) {
245 len = (int)(CRC_SIZE * tvb_get_ntohl(tvb, offset - 4) *
246 tvb_get_ntohl(tvb, offset - 8) / chunksize);
249 /* the rest of bytes (usually 4) = crc32 code */
250 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_crc32, tvb, offset, len, ENC_BIG_ENDIAN);
251 /* offset += len; */
254 /* dissects the first packet of the read response */
255 static void
256 dissect_read_response_start(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int offset) {
257 /* 2 bytes = status code */
258 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_status, tvb, offset, 2, ENC_BIG_ENDIAN);
259 offset += 2;
261 /* checksum type = 1 byte. 1 = crc32, 0 = null */
262 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_checksumtype, tvb, offset, 1, ENC_BIG_ENDIAN);
263 offset += 1;
265 /* 4 bytes = chunksize */
266 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_chunksize, tvb, offset, 4, ENC_BIG_ENDIAN);
267 offset += 4;
269 /* 8 bytes = chunk offset */
270 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_chunkoffset, tvb, offset, 8, ENC_BIG_ENDIAN);
271 /* offset += 8; */
274 /* dissects the fields specific to a read request */
275 static void
276 dissect_read_request(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int *offset)
279 /* 8 bytes = start offset */
280 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_startoffset, tvb, *offset, 8, ENC_BIG_ENDIAN);
281 *offset += 8;
283 /* 8 bytes = block length */
284 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_blocklen, tvb, *offset, 8, ENC_BIG_ENDIAN);
285 *offset += 8;
289 /* dissects the fields specific to a write request */
290 static void
291 dissect_write_request(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int *offset)
293 /* 4 bytes = number of nodes in pipeline */
294 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_pipelinenum, tvb, *offset, 4, ENC_BIG_ENDIAN);
295 *offset += 4;
297 /* 1 bytes = recovery boolean */
298 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_recovery, tvb, *offset, 1, ENC_BIG_ENDIAN);
299 *offset += 1;
302 /* dissects the fields specific to a write request */
303 static void
304 dissect_write_request_end(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int *offset)
306 int i = 0;
307 int len = 0;
309 /* 1 bytes = source node */
310 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_sourcenode, tvb, *offset, 1, ENC_BIG_ENDIAN);
311 *offset += 1;
313 /* 4 bytes = number of nodes currently in the pipeline (usually just -1 of before) */
314 len = tvb_get_ntohl(tvb, *offset);
315 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_currentpipeline, tvb, *offset, 4, ENC_BIG_ENDIAN);
316 *offset += 4;
318 /* varible length sequence of node objects */
319 for (i = 0; i < len; i++) {
320 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_node, tvb, *offset, 4, ENC_BIG_ENDIAN);
321 *offset += 4;
325 /* dissects the beginning of the read and write request messages */
326 static int
327 dissect_header(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int* offset){
329 int command = 0;
331 /* 2 bytes = protocol version */
332 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_version, tvb, *offset, 2, ENC_BIG_ENDIAN);
333 *offset += 2;
335 /* 1 byte = command */
336 command = tvb_get_guint8(tvb, *offset);
337 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_cmd, tvb, *offset, 1, ENC_BIG_ENDIAN);
338 *offset += 1;
340 /* 8 bytes = block id */
341 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_blockid, tvb, *offset, 8, ENC_BIG_ENDIAN);
342 *offset += 8;
344 /* 8 bytes = timestamp */
345 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_timestamp, tvb, *offset, 8, ENC_BIG_ENDIAN);
346 *offset += 8;
348 return command;
351 /* decodes the write response messages */
352 static void
353 dissect_write_response(tvbuff_t *tvb, proto_tree *hdfsdata_tree, int offset)
355 /* 4 bytes = packetsize */
356 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_packetsize, tvb, offset, 4, ENC_BIG_ENDIAN);
357 offset += 4;
359 /* 8 bytes = offset in block */
360 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_startoffset, tvb, offset, 8, ENC_BIG_ENDIAN);
361 offset += 8;
363 /* 8 bytes = sequence number */
364 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_seqnum, tvb, offset, 8, ENC_BIG_ENDIAN);
365 offset += 8;
367 /* 1 bytes = last packet */
368 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_last, tvb, offset, 1, ENC_BIG_ENDIAN);
369 offset += 1;
371 /* 4 bytes = chunk length */
372 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_chunklength, tvb, offset, 4, ENC_BIG_ENDIAN);
373 offset += 4;
375 /* 8 bytes = crc code */
376 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_crc64, tvb, offset, 8, ENC_BIG_ENDIAN);
377 offset += 8;
379 /* add the rest -> RESPONSE_DATA */
380 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_rest, tvb, offset, (tvb_reported_length(tvb)) - offset, ENC_ASCII|ENC_NA);
381 /* offset += (tvb_reported_length(tvb)); */
384 /* determine PDU length of protocol */
385 static guint
386 get_hdfsdata_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
388 /* get data packet len, add FIRST_READ_FRAGMENT_LEN for first fragment (before len),
389 SECOND_READ_FRAGMENT_LEN for second fragment (incl len), subtract 4 for length itself. */
391 if (tvb_reported_length(tvb) <= 4 || tvb_reported_length(tvb) == END_PACKET_LEN
392 || tvb_get_ntohl(tvb, 0) == tvb_reported_length(tvb) - WRITE_RESP_HEAD_LEN
393 || (tvb_reported_length(tvb) >= MIN_READ_REQ && tvb_get_guint8(tvb, 2) == READ_OP)
394 || (tvb_reported_length(tvb) >= MIN_WRITE_REQ && tvb_get_guint8(tvb, 2) == WRITE_OP)) {
396 return tvb_reported_length(tvb);
398 return tvb_get_ntohl(tvb, offset + FIRST_READ_FRAGMENT_LEN) +
399 FIRST_READ_FRAGMENT_LEN + SECOND_READ_FRAGMENT_LEN - LAST_READ_FRAGMENT_LEN;
402 /* This method dissects fully reassembled messages */
403 static int
404 dissect_hdfsdata_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
406 int offset = 0;
408 col_set_str(pinfo->cinfo, COL_PROTOCOL, "HDFSDATA");
409 /* Clear out stuff in the info column */
410 col_set_str(pinfo->cinfo, COL_INFO, "HDFS Data");
413 if (tree) {
414 proto_item *ti = NULL;
415 proto_tree *hdfsdata_tree = NULL;
417 ti = proto_tree_add_item(tree, proto_hdfsdata, tvb, offset, -1, ENC_NA);
418 hdfsdata_tree = proto_item_add_subtree(ti, ett_hdfsdata);
420 /* if only 1 bytes packet must just contain just the pipeline status */
421 if ((tvb_reported_length(tvb)) == PIPELINE_LEN) {
423 /* 1 bytes = pipeline status */
424 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_pipelinestatus, tvb, offset, PIPELINE_LEN, ENC_BIG_ENDIAN);
426 /* if only 2 bytes packet must just contain just a status code */
427 } else if ((tvb_reported_length(tvb)) == STATUS_LEN) {
428 /* 2 bytes = status code */
429 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_status, tvb, offset, STATUS_LEN, ENC_BIG_ENDIAN);
431 /* if it is 4 bytes long it must be a finish request packet */
432 } else if ((tvb_reported_length(tvb)) == FINISH_REQ_LEN) {
433 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_end, tvb, offset, 4, ENC_BIG_ENDIAN);
435 /* read response packet */
436 } else if (tvb_reported_length(tvb) >= READ_RESP_HEAD_LEN && tvb_reported_length(tvb) ==
437 tvb_get_ntohl(tvb, FIRST_READ_FRAGMENT_LEN) +
438 FIRST_READ_FRAGMENT_LEN + SECOND_READ_FRAGMENT_LEN - LAST_READ_FRAGMENT_LEN){
440 dissect_read_response_start(tvb, hdfsdata_tree, offset);
441 offset += FIRST_READ_FRAGMENT_LEN;
443 dissect_read_response(tvb, hdfsdata_tree, offset);
444 offset+= SECOND_READ_FRAGMENT_LEN;
446 /* This message just contains data so we can display it all as one block */
448 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_rest, tvb, offset, (tvb_reported_length(tvb)) - offset, ENC_ASCII|ENC_NA);
450 } else {
452 guint8 op = tvb_get_guint8(tvb, 2);
454 /* READ request */
455 if ((tvb_reported_length(tvb)) >= MIN_READ_REQ && op == READ_OP) {
456 dissect_header(tvb, hdfsdata_tree, &offset);
457 dissect_read_request(tvb, hdfsdata_tree, &offset);
458 dissect_variable_int_string(tvb, hdfsdata_tree, &offset);
459 dissect_access_tokens(tvb, hdfsdata_tree, &offset);
461 /* WRITE request */
462 } else if ((tvb_reported_length(tvb)) >= MIN_WRITE_REQ && op == WRITE_OP) {
463 dissect_header(tvb, hdfsdata_tree, &offset);
464 dissect_write_request(tvb, hdfsdata_tree, &offset);
465 dissect_variable_int_string(tvb, hdfsdata_tree, &offset);
466 dissect_write_request_end(tvb, hdfsdata_tree, &offset);
467 dissect_access_tokens(tvb, hdfsdata_tree, &offset);
469 /* checksum type = 1 byte. 1 = crc32, 0 = null */
470 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_checksumtype, tvb, offset, 1, ENC_BIG_ENDIAN);
471 offset += 1;
473 /* 4 bytes = chunksize */
474 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_chunksize, tvb, offset, 4, ENC_BIG_ENDIAN);
476 /* write responses store the data length in the first 4 bytes. This length does not
477 include 21 bits of header */
478 } else if (tvb_reported_length(tvb) >= 4 && tvb_get_ntohl(tvb, 0) ==
479 tvb_reported_length(tvb) - WRITE_RESP_HEAD_LEN) {
481 dissect_write_response(tvb, hdfsdata_tree, offset);
483 } else {
484 /* This message contains some form of data that we have not successfully been able to
485 pattern match and catagorize. Display all of it as data. */
486 proto_tree_add_item(hdfsdata_tree, hf_hdfsdata_rest, tvb, offset, (tvb_reported_length(tvb)), ENC_ASCII|ENC_NA);
491 return tvb_length(tvb);
494 static int
495 dissect_hdfsdata(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
497 int frame_header_len = 0;
499 gboolean need_reassemble = FALSE;
500 guint8 op = 0;
501 gboolean only_packet = tvb_reported_length(tvb) == 1 || (tvb_reported_length(tvb) == 2 &&
502 tvb_get_ntohs(tvb, 0) == STATUS_SUCCESS);
504 if (tvb_reported_length(tvb) >= 3)
505 op = tvb_get_guint8(tvb, 2);
507 if (!only_packet && tvb_reported_length(tvb) != 4 && !(tvb_reported_length(tvb) >= MIN_READ_REQ && op == READ_OP) &&
508 !(tvb_reported_length(tvb) >= MIN_WRITE_REQ && op == WRITE_OP) && !(tvb_reported_length(tvb) == END_PACKET_LEN &&
509 !tvb_get_ntohl(tvb, 0) && !tvb_get_ntohl(tvb, 4))) {
511 need_reassemble = TRUE;
514 /* setting the header size for the different types of packets */
515 if (only_packet || tvb_reported_length(tvb) == END_PACKET_LEN) {
516 frame_header_len = tvb_reported_length(tvb);
518 } else if (tvb_reported_length(tvb) == FIRST_READ_FRAGMENT_LEN ||(tvb_reported_length(tvb) >= MIN_READ_REQ &&
519 op == READ_OP && !((tvb_reported_length(tvb)) == 2 && !tvb_get_ntohs(tvb, 0)))) {
521 frame_header_len = READ_RESP_HEAD_LEN;
523 } else if (tvb_reported_length(tvb) >= MIN_WRITE_REQ && op == WRITE_OP) {
524 frame_header_len = WRITE_REQ_HEAD_LEN;
527 tcp_dissect_pdus(tvb, pinfo, tree, need_reassemble, frame_header_len, get_hdfsdata_message_len, dissect_hdfsdata_message, data);
528 return tvb_length(tvb);
531 /* registers the protcol with the given names */
532 void
533 proto_register_hdfsdata(void)
535 static hf_register_info hf[] = {
537 /* list of all options for dissecting the protocol */
539 /*************************************************
540 Read request
541 **************************************************/
542 { &hf_hdfsdata_version,
543 { "HDFSDATA protocol version", "hdfsdata.version",
544 FT_UINT16, BASE_DEC,
545 NULL, 0x0,
546 NULL, HFILL }
548 { &hf_hdfsdata_cmd,
549 { "HDFSDATA command", "hdfsdata.cmd",
550 FT_UINT8, BASE_DEC,
551 NULL, 0x0,
552 NULL, HFILL }
554 { &hf_hdfsdata_blockid,
555 { "HDFSDATA block id", "hdfsdata.blockid",
556 FT_UINT64, BASE_DEC,
557 NULL, 0x0,
558 NULL, HFILL }
560 { &hf_hdfsdata_timestamp,
561 { "HDFSDATA timestamp", "hdfsdata.timestamp",
562 FT_UINT64, BASE_DEC,
563 NULL, 0x0,
564 NULL, HFILL }
566 /***
567 Read specific
568 ***/
569 { &hf_hdfsdata_startoffset,
570 { "HDFSDATA start offset" , "hdfsdata.startoffset",
571 FT_UINT64, BASE_DEC,
572 NULL, 0x0,
573 NULL, HFILL }
575 { &hf_hdfsdata_blocklen,
576 { "HDFSDATA block length", "hdfsdata.blocklen",
577 FT_UINT64, BASE_DEC,
578 NULL, 0x0,
579 NULL, HFILL }
581 /***
582 Write specific
583 ***/
584 { &hf_hdfsdata_pipelinenum,
585 { "HDFSDATA number in pipeline", "hdfsdata.pipelinenum",
586 FT_UINT32, BASE_DEC,
587 NULL, 0x0,
588 NULL, HFILL }
590 { &hf_hdfsdata_recovery,
591 { "HDFSDATA recovery boolean", "hdfsdata.recovery",
592 FT_UINT8, BASE_DEC,
593 NULL, 0x0,
594 NULL, HFILL }
596 { &hf_hdfsdata_sourcenode,
597 { "HDFSDATA source node", "hdfsdata.sourcenode",
598 FT_UINT8, BASE_DEC,
599 NULL, 0x0,
600 NULL, HFILL }
602 { &hf_hdfsdata_currentpipeline,
603 { "HDFSDATA current number of nodes in the pipeline", "hdfsdata.currentpipline",
604 FT_UINT32, BASE_DEC,
605 NULL, 0x0,
606 NULL, HFILL }
608 { &hf_hdfsdata_node,
609 { "HDFSDATA node object", "hdfsdata.node",
610 FT_UINT32, BASE_DEC,
611 NULL, 0x0,
612 NULL, HFILL }
614 /***
615 Var length
617 { &hf_hdfsdata_clientlen,
618 { "HDFSDATA client id length", "hdfsdata.clientlen",
619 FT_UINT8, BASE_DEC,
620 NULL, 0x0,
621 NULL, HFILL }
623 { &hf_hdfsdata_clientid,
624 { "HDFSDATA client id", "hdfsdata.clientid",
625 FT_STRING, BASE_NONE,
626 NULL, 0x0,
627 NULL, HFILL }
629 { &hf_hdfsdata_end,
630 { "HDFSDATA end data request", "hdfsdata.end",
631 FT_UINT32, BASE_DEC,
632 NULL, 0x0,
633 NULL, HFILL }
635 /*************************************************
636 Access tokens
637 **************************************************/
638 { &hf_hdfsdata_tokenlen,
639 { "HDFSDATA access token length", "hdfsdata.tokenlen",
640 FT_UINT8, BASE_DEC,
641 NULL, 0x0,
642 NULL, HFILL }
644 { &hf_hdfsdata_tokenid,
645 { "HDFSDATA access token ID", "hdfsdata.tokenid",
646 FT_STRING, BASE_NONE,
647 NULL, 0x0,
648 NULL, HFILL }
650 { &hf_hdfsdata_tokenpassword,
651 { "HDFSDATA access token password", "hdfsdata.tokenpassword",
652 FT_STRING, BASE_NONE,
653 NULL, 0x0,
654 NULL, HFILL }
656 { &hf_hdfsdata_tokentype,
657 { "HDFSDATA access token type", "hdfsdata.tokentype",
658 FT_STRING, BASE_NONE,
659 NULL, 0x0,
660 NULL, HFILL }
662 { &hf_hdfsdata_tokenservice,
663 { "HDFSDATA access token service", "hdfsdata.tokenservice",
664 FT_STRING, BASE_NONE,
665 NULL, 0x0,
666 NULL, HFILL }
668 /***********************************************
669 Responses 1
670 ***********************************************/
671 { &hf_hdfsdata_status,
672 { "HDFSDATA status code", "hdfsdata.status",
673 FT_UINT16, BASE_DEC,
674 NULL, 0x0,
675 NULL, HFILL }
677 { &hf_hdfsdata_checksumtype,
678 { "HDFSDATA checksum type", "hdfsdata.checksumtype",
679 FT_UINT8, BASE_DEC,
680 NULL, 0x0,
681 NULL, HFILL }
683 { &hf_hdfsdata_chunksize,
684 { "HDFSDATA chunk size", "hdfsdata.chunksize",
685 FT_UINT16, BASE_DEC,
686 NULL, 0x0,
687 NULL, HFILL }
689 { &hf_hdfsdata_chunkoffset,
690 { "HDFSDATA chunk offset", "hdfsdata.chunkoffset",
691 FT_UINT64, BASE_DEC,
692 NULL, 0x0,
693 NULL, HFILL }
695 /***********************************************
696 Responses 2
697 ***********************************************/
698 { &hf_hdfsdata_datalength,
699 { "HDFSDATA length of data", "hdfsdata.datalength",
700 FT_UINT32, BASE_DEC,
701 NULL, 0x0,
702 NULL, HFILL }
704 { &hf_hdfsdata_inblockoffset,
705 { "HDFSDATA in block offset", "hdfsdata.inblockoffset",
706 FT_UINT64, BASE_DEC,
707 NULL, 0x0,
708 NULL, HFILL }
710 { &hf_hdfsdata_seqnum,
711 { "HDFSDATA sequence number", "hdfsdata.seqnum",
712 FT_UINT64, BASE_DEC,
713 NULL, 0x0,
714 NULL, HFILL }
716 { &hf_hdfsdata_last,
717 { "HDFSDATA last packet in block", "hdfsdata.last",
718 FT_INT8, BASE_DEC,
719 NULL, 0x0,
720 NULL, HFILL }
722 { &hf_hdfsdata_datalen,
723 { "HDFSDATA length of data", "hdfsdata.datalen",
724 FT_INT32, BASE_DEC,
725 NULL, 0x0,
726 NULL, HFILL }
728 { &hf_hdfsdata_crc32,
729 { "HDFSDATA crc32 checksum", "hdfsdata.crc32",
730 FT_INT32, BASE_DEC,
731 NULL, 0x0,
732 NULL, HFILL }
734 /***********************************************
735 Responses 3
736 ***********************************************/
737 { &hf_hdfsdata_rest,
738 { "HDFSDATA data", "hdfsdata.rest",
739 FT_STRING, BASE_NONE,
740 NULL, 0x0,
741 NULL, HFILL }
743 /***********************************************
744 Write Response 1
745 ***********************************************/
746 { &hf_hdfsdata_packetsize,
747 { "HDFSDATA packet size", "hdfsdata.packetsize",
748 FT_UINT32, BASE_DEC,
749 NULL, 0x0,
750 NULL, HFILL }
752 { &hf_hdfsdata_chunklength,
753 { "HDFSDATA chunk length", "hdfsdata.chunklength",
754 FT_UINT32, BASE_DEC,
755 NULL, 0x0,
756 NULL, HFILL }
758 { &hf_hdfsdata_crc64,
759 { "HDFSDATA crc64 checksum", "hdfsdata.crc64",
760 FT_INT64, BASE_DEC,
761 NULL, 0x0,
762 NULL, HFILL }
764 { &hf_hdfsdata_pipelinestatus,
765 { "HDFSDATA pipeline status", "hdfsdata.pipelinestatus",
766 FT_INT8, BASE_DEC,
767 NULL, 0x0,
768 NULL, HFILL }
772 /* Setup protocol subtree array */
773 static gint *ett[] = {
774 &ett_hdfsdata
777 module_t *hdfsdata_module;
779 proto_hdfsdata = proto_register_protocol (
780 "HDFSDATA Protocol", /* name */
781 "HDFSDATA", /* short name */
782 "hdfsdata" /* abbrev */
785 proto_register_field_array(proto_hdfsdata, hf, array_length(hf));
786 proto_register_subtree_array(ett, array_length(ett));
788 hdfsdata_module = prefs_register_protocol(proto_hdfsdata, proto_reg_handoff_hdfsdata);
790 prefs_register_uint_preference(hdfsdata_module,
791 "tcp.port",
792 "TCP port for HDFSDATA",
793 "Set the TCP port for HDFSDATA",
795 &tcp_port);
797 hdfsdata_handle = new_register_dissector("hdfsdata", dissect_hdfsdata, proto_hdfsdata);
800 /* registers handoff */
801 void
802 proto_reg_handoff_hdfsdata(void)
804 static gboolean initialized = FALSE;
805 static guint saved_tcp_port;
807 if (!initialized) {
808 dissector_add_handle("tcp.port", hdfsdata_handle); /* for "decode as" */
809 initialized = TRUE;
810 } else if (saved_tcp_port != 0) {
811 dissector_delete_uint("tcp.port", saved_tcp_port, hdfsdata_handle);
814 if (tcp_port != 0) {
815 dissector_add_uint("tcp.port", tcp_port, hdfsdata_handle);
818 saved_tcp_port = tcp_port;
821 * Editor modelines
823 * Local Variables:
824 * c-basic-offset: 2
825 * tab-width: 8
826 * indent-tabs-mode: nil
827 * End:
829 * ex: set shiftwidth=2 tabstop=8 expandtab:
830 * :indentSize=2:tabSize=8:noTabs=true: