Coverage Report

Created: 2026-08-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-nasdaq-itch.c
Line
Count
Source
1
/* packet-nasdaq-itch.c
2
 * Routines for NASDAQ TotalView-ITCH version 2.00/3.00 (with Chi-X extension) Protocol dissection
3
 * Copyright 2007,2008 Didier Gautheron <dgautheron@magic.fr>
4
 *
5
 * Wireshark - Network traffic analyzer
6
 * By Gerald Combs <gerald@wireshark.org>
7
 * Copyright 1998 Gerald Combs
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 *
11
 * Documentation:
12
 * http://www.nasdaqtrader.com/Trader.aspx?id=DPSpecs
13
 * ex:
14
 * http://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/tv-itch2a.pdf
15
 * http://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/tvitch-v3.pdf
16
 *
17
 * Chi-X
18
 * http://www.chi-x.com/docs/Chi-X%20CHIXMD.pdf
19
20
 */
21
22
#include "config.h"
23
24
#include <stdlib.h>
25
26
#include <epan/packet.h>
27
#include <epan/prefs.h>
28
#include <wsutil/type_util.h>
29
30
void proto_register_nasdaq_itch(void);
31
void proto_reg_handoff_nasdaq_itch(void);
32
33
static dissector_handle_t nasdaq_itch_handle;
34
35
/* Chi-X version */
36
static bool nasdaq_itch_chi_x = true;
37
38
static const value_string message_types_val[] = {
39
 { 'A', "Add Order " },
40
 { 'X', "Order Cancel " },
41
 { 'M', "Milliseconds " },
42
 { 'E', "Order Executed " },
43
 { 'T', "Second " },
44
 { 'P', "Trade Message Identifier " },
45
 { 'C', "Order Executed With Price " },
46
 { 'D', "Order Delete " },
47
 { 'Q', "Cross Trade " },
48
 { 'S', "System Event " },
49
 { 'R' , "Stock Directory " },
50
 { 'H', "Stock Trading Action " },
51
 { 'F', "Add Order (MPID) " },
52
 { 'I', "Net Order Imbalance Indicator (NOII) " },
53
 { 'B', "Broken Trade " },
54
 /* Chi-X msg with big size,price */
55
 { 'a', "Add Order (big)" },
56
 { 'p', "Trade Message Identifier (big)" },
57
 { 'e', "Order Executed (big)" },
58
 { 'x', "Order Cancel (big)" },
59
 { 0, NULL }
60
};
61
62
static const char chix_msg[] = "apex";
63
64
static const value_string system_event_val[] = {
65
 { 'O', "Start of Messages" },
66
 { 'S', "Start of System hours" },
67
 { 'Q', "Start of Market hours" },
68
 { 'M', "End of Market hours" },
69
 { 'E', "End of System hours" },
70
 { 'C', "End of Messages" },
71
 { 0, NULL }
72
};
73
74
static const value_string market_category_val[] = {
75
 { 'T', "CQS (NYSE, Amex or regional exchange)" },
76
 { 'Q', "NASDAQ Global Select MarketSM" },
77
 { 'G', "NASDAQ Global MarketSM" },
78
 { 'S', "NASDAQ Capital Market" },
79
 { ' ', "Not available" },
80
 { 0, NULL }
81
};
82
83
static const value_string financial_status_val[] = {
84
 { 'D', "Deficient" },
85
 { 'E', "Delinquent" },
86
 { 'Q', "Bankrupt" },
87
 { 'S', "Suspended" },
88
 { 'G', "Deficient and Bankrupt" },
89
 { 'H', "Deficient and Delinquent" },
90
 { 'J', "Delinquent and Bankrupt" },
91
 { 'K', "Deficient, Delinquent and Bankrupt" },
92
 { ' ', "Company is in compliance" },
93
 { 0, NULL }
94
};
95
96
static const value_string round_lots_only_val[] = {
97
 { 'Y', "only round lots are accepted in this stock" },
98
 { 'N', "odd/mixed lots are allowed" },
99
 { 0, NULL }
100
};
101
102
/* Initialize the protocol and registered fields */
103
static int proto_nasdaq_itch;
104
105
/* Initialize the subtree pointers */
106
static int ett_nasdaq_itch;
107
108
static int hf_nasdaq_itch_version;
109
110
static int hf_nasdaq_itch_message_type;
111
static int hf_nasdaq_itch_market_category;
112
static int hf_nasdaq_itch_financial_status;
113
static int hf_nasdaq_itch_stock;
114
static int hf_nasdaq_itch_round_lot_size;
115
static int hf_nasdaq_itch_round_lots_only;
116
117
static int hf_nasdaq_itch_system_event;
118
static int hf_nasdaq_itch_second;
119
static int hf_nasdaq_itch_millisecond;
120
121
static int hf_nasdaq_itch_message;
122
123
static int hf_nasdaq_itch_trading_state;
124
static int hf_nasdaq_itch_reserved;
125
static int hf_nasdaq_itch_reason;
126
static int hf_nasdaq_itch_order_reference;
127
static int hf_nasdaq_itch_buy_sell;
128
static int hf_nasdaq_itch_shares;
129
static int hf_nasdaq_itch_price;
130
static int hf_nasdaq_itch_attribution;
131
static int hf_nasdaq_itch_executed;
132
static int hf_nasdaq_itch_match;
133
static int hf_nasdaq_itch_printable;
134
static int hf_nasdaq_itch_execution_price;
135
static int hf_nasdaq_itch_canceled;
136
static int hf_nasdaq_itch_cross;
137
138
/* ---------------------- */
139
static int
140
order_ref_number(tvbuff_t *tvb, packet_info *pinfo, proto_tree *nasdaq_itch_tree, int offset)
141
0
{
142
0
  const char *str_value = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, 9, ENC_ASCII);
143
0
  uint32_t    value     = (uint32_t)strtoul(str_value, NULL, 10);
144
145
0
  proto_tree_add_uint(nasdaq_itch_tree, hf_nasdaq_itch_order_reference, tvb, offset, 9, value);
146
0
  col_append_fstr(pinfo->cinfo, COL_INFO, "%u ", value);
147
148
0
  return offset + 9;
149
0
}
150
151
/* -------------------------- */
152
static int
153
time_stamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *nasdaq_itch_tree, int id, int offset, int size)
154
0
{
155
156
0
  if (nasdaq_itch_tree) {
157
0
      uint32_t    ms, val;
158
0
      const char *display   = "";
159
0
      const char *str_value = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, size, ENC_ASCII);
160
161
0
      ms = val = (uint32_t)strtoul(str_value, NULL, 10);
162
0
      switch (size) {
163
0
      case 3:
164
0
          display = wmem_strdup_printf(pinfo->pool, " %03u" , val);
165
0
          break;
166
0
      case 5:
167
0
          ms = val *1000;
168
          /* Fall Through */
169
0
      case 8: /* 0 86 400 000 */
170
0
          display = wmem_strdup_printf(pinfo->pool, " %u (%02u:%02u:%02u.%03u)", val,
171
0
              ms/3600000, (ms % 3600000)/60000, (ms % 60000)/1000, ms %1000);
172
0
          break;
173
0
      }
174
0
      proto_tree_add_uint_format_value(nasdaq_itch_tree, id, tvb, offset, size, val, "%s", display);
175
0
  }
176
0
  return offset + size;
177
0
}
178
179
/* -------------------------- */
180
static int
181
number_of_shares(tvbuff_t *tvb, packet_info *pinfo, proto_tree *nasdaq_itch_tree, int id, int offset, int big)
182
0
{
183
0
  int size = (big) ? 10 : 6;
184
0
  const char *str_value = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, size, ENC_ASCII);
185
186
0
  uint32_t value = (uint32_t)strtoul(str_value, NULL, 10);
187
188
0
  proto_tree_add_uint(nasdaq_itch_tree, id, tvb, offset, size, value);
189
0
  col_append_fstr(pinfo->cinfo, COL_INFO, "qty %u ", value);
190
191
0
  return offset + size;
192
0
}
193
194
/* -------------------------- */
195
static int
196
price(tvbuff_t *tvb, packet_info *pinfo, proto_tree *nasdaq_itch_tree, int id, int offset, int big)
197
0
{
198
0
  int size = (big) ? 19 : 10;
199
200
0
  const char *str_value = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, size, ENC_ASCII);
201
0
  double      value     = uint64_to_double(g_ascii_strtoull(str_value, NULL, 10))/((big)?1000000.0:10000.0);
202
203
0
  proto_tree_add_double(nasdaq_itch_tree, id, tvb, offset, size, value);
204
0
  col_append_fstr(pinfo->cinfo, COL_INFO, "price %g ", value);
205
206
0
  return offset + size;
207
0
}
208
209
/* -------------------------- */
210
static int
211
stock(tvbuff_t *tvb, packet_info *pinfo, proto_tree *nasdaq_itch_tree, int offset)
212
0
{
213
0
  char *stock_p = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, 6, ENC_ASCII);
214
215
0
  proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_stock, tvb, offset, 6, ENC_ASCII);
216
0
  col_append_fstr(pinfo->cinfo, COL_INFO, "<%s> ", stock_p);
217
218
0
  return offset + 6;
219
0
}
220
221
/* -------------------------- */
222
static int
223
order(tvbuff_t *tvb, packet_info *pinfo, proto_tree *nasdaq_itch_tree, int offset, int big)
224
0
{
225
0
  uint8_t value;
226
227
0
  offset = order_ref_number(tvb, pinfo, nasdaq_itch_tree, offset);
228
229
0
  value = tvb_get_uint8(tvb, offset);
230
231
0
  col_append_fstr(pinfo->cinfo, COL_INFO, "%c ", value);
232
0
  proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_buy_sell, tvb, offset, 1, ENC_ASCII);
233
0
  offset += 1;
234
235
0
  offset = number_of_shares(tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_shares, offset, big);
236
237
0
  offset = stock(tvb, pinfo, nasdaq_itch_tree, offset);
238
239
0
  offset = price(tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_price, offset, big);
240
0
  return offset;
241
0
}
242
243
/* -------------------------- */
244
static int
245
executed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *nasdaq_itch_tree, int offset, int big)
246
0
{
247
0
  offset = order_ref_number(tvb, pinfo, nasdaq_itch_tree, offset);
248
249
0
  offset = number_of_shares(tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_executed, offset, big);
250
251
0
  proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_match, tvb, offset, 9, ENC_ASCII);
252
0
  offset += 9;
253
0
  return offset;
254
0
}
255
256
/* ---------------------------- */
257
static int
258
dissect_nasdaq_itch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
259
0
{
260
0
  proto_item  *ti;
261
0
  proto_tree  *nasdaq_itch_tree = NULL;
262
0
  uint8_t      nasdaq_itch_type;
263
0
  int          offset           = 0;
264
0
  int          version          = 3;
265
0
  int          big              = 0;
266
0
  const char *rep;
267
268
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "Nasdaq-ITCH");
269
270
0
  nasdaq_itch_type = tvb_get_uint8(tvb, offset);
271
0
  if (nasdaq_itch_type >= '0' && nasdaq_itch_type <= '9') {
272
0
    version = 2;
273
0
    nasdaq_itch_type = tvb_get_uint8(tvb, offset +8);
274
0
  }
275
276
0
  if ((!nasdaq_itch_chi_x || version == 3) && strchr(chix_msg, nasdaq_itch_type)) {
277
0
    nasdaq_itch_type = 0; /* unknown */
278
0
  }
279
280
0
  rep = val_to_str(pinfo->pool, nasdaq_itch_type, message_types_val, "Unknown packet type (0x%02x) ");
281
0
  col_add_str(pinfo->cinfo, COL_INFO, rep);
282
283
0
  if (tree) {
284
0
    proto_item *item;
285
286
0
    ti = proto_tree_add_protocol_format(tree, proto_nasdaq_itch, tvb, offset, -1, "Nasdaq TotalView-ITCH %s, %s",
287
0
                                        version == 2?"2.0":"3.0", rep);
288
289
0
    nasdaq_itch_tree = proto_item_add_subtree(ti, ett_nasdaq_itch);
290
291
0
    item = proto_tree_add_uint(nasdaq_itch_tree, hf_nasdaq_itch_version, tvb, 0, 0, version);
292
0
    proto_item_set_generated(item);
293
0
  }
294
295
0
  if (version == 2) {
296
0
    offset = time_stamp (tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_millisecond, offset, 8);
297
0
  }
298
299
0
  proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_message_type, tvb, offset, 1, ENC_ASCII);
300
0
  offset += 1;
301
302
0
  if (version == 3) {
303
0
    switch (nasdaq_itch_type) {
304
0
    case 'T': /* seconds */
305
0
      /*offset =*/ time_stamp (tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_second, offset, 5);
306
0
      return tvb_captured_length(tvb);
307
308
0
    case 'M': /* milliseconds */
309
0
      /*offset =*/ time_stamp (tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_millisecond, offset, 3);
310
0
      return tvb_captured_length(tvb);
311
0
    }
312
0
  }
313
314
0
  switch (nasdaq_itch_type) {
315
0
  case 'S': /* system event */
316
0
    proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_system_event, tvb, offset, 1, ENC_ASCII);
317
    /*offset += 1;*/
318
0
    break;
319
320
0
  case 'R': /* Stock Directory */
321
0
    offset = stock(tvb, pinfo, nasdaq_itch_tree, offset);
322
323
0
    proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_market_category, tvb, offset, 1, ENC_ASCII);
324
0
    offset += 1;
325
0
    proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_financial_status, tvb, offset, 1, ENC_ASCII);
326
0
    offset += 1;
327
0
    proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_round_lot_size, tvb, offset, 6, ENC_ASCII);
328
0
    offset += 6;
329
0
    proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_round_lots_only, tvb, offset, 1, ENC_ASCII);
330
    /*offset += 1;*/
331
0
    break;
332
333
0
  case 'H': /* Stock trading action */
334
0
    offset = stock(tvb, pinfo, nasdaq_itch_tree, offset);
335
336
0
    proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_trading_state, tvb, offset, 1, ENC_ASCII);
337
0
    offset += 1;
338
0
    proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_reserved, tvb, offset, 1, ENC_ASCII);
339
0
    offset += 1;
340
0
    proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_reason, tvb, offset, 4, ENC_ASCII);
341
    /*offset += 4;*/
342
0
    break;
343
344
0
  case 'a' :
345
0
    big = 1;
346
    /* FALL THROUGH */
347
0
  case 'A': /* Add order, no MPID */
348
0
    offset = order(tvb, pinfo, nasdaq_itch_tree, offset, big);
349
0
    if (version == 2) {
350
0
      proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_printable, tvb, offset, 1, ENC_ASCII);
351
      /*offset += 1;*/
352
0
    }
353
0
    break;
354
355
0
  case 'F': /* Add order, MPID */
356
0
    offset = order(tvb, pinfo, nasdaq_itch_tree, offset, big);
357
0
    proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_attribution, tvb, offset, 4, ENC_ASCII);
358
    /*offset += 4;*/
359
0
    break;
360
361
0
  case 'e' :
362
0
    big = 1;
363
    /* FALL THROUGH */
364
0
  case 'E' : /* Order executed */
365
0
    /*offset =*/ executed(tvb, pinfo, nasdaq_itch_tree, offset, big);
366
0
    break;
367
368
0
  case 'C' : /* Order executed with price */
369
0
    offset = executed(tvb, pinfo, nasdaq_itch_tree, offset, big);
370
0
    proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_printable, tvb, offset, 1, ENC_ASCII);
371
0
    offset += 1;
372
373
    /*offset = */price(tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_execution_price, offset, big);
374
0
    break;
375
376
0
  case 'x' :
377
0
    big = 1;
378
    /* FALL THROUGH */
379
0
  case 'X' : /* Order cancel */
380
0
    offset = order_ref_number(tvb, pinfo, nasdaq_itch_tree, offset);
381
0
    /*offset = */number_of_shares(tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_canceled, offset, big);
382
0
    break;
383
384
0
  case 'D' : /* Order delete */
385
0
    /*offset = */order_ref_number(tvb, pinfo, nasdaq_itch_tree, offset);
386
    /*offset += 9;*/
387
0
    break;
388
389
0
  case 'p' :
390
0
    big = 1;
391
    /* FALL THROUGH */
392
0
  case 'P' : /* Trade identifier */
393
0
    offset = order(tvb, pinfo, nasdaq_itch_tree, offset, big);
394
0
    proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_match, tvb, offset, 9, ENC_ASCII);
395
    /*offset += 9;*/
396
0
    break;
397
398
0
  case 'Q' : /* Cross Trade */
399
0
    offset = number_of_shares(tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_shares, offset, big);
400
401
0
    offset = stock(tvb, pinfo, nasdaq_itch_tree, offset);
402
403
0
    offset = price(tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_price, offset, big);
404
405
0
    proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_match, tvb, offset, 9, ENC_ASCII);
406
0
    offset += 9;
407
0
    proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_cross, tvb, offset, 1, ENC_ASCII);
408
    /*offset += 1;*/
409
0
    break;
410
411
0
  case 'B' : /* Broken Trade */
412
0
    proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_match, tvb, offset, 9, ENC_ASCII);
413
    /*offset += 9;*/
414
0
    break;
415
416
0
  case 'I': /* NOII, FIXME */
417
0
    offset = stock(tvb, pinfo, nasdaq_itch_tree, offset);
418
419
0
    proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_cross, tvb, offset, 1, ENC_ASCII);
420
    /*offset += 1;*/
421
0
    break;
422
423
0
  default:
424
    /* unknown */
425
0
    proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_message, tvb, offset, -1, ENC_ASCII);
426
    /*offset += 5-1;*/
427
0
    break;
428
0
  }
429
0
  return tvb_captured_length(tvb);
430
0
}
431
432
/* Register the protocol with Wireshark */
433
void
434
proto_register_nasdaq_itch(void)
435
16
{
436
437
/* Setup list of header fields  See Section 1.6.1 for details*/
438
16
  static hf_register_info hf[] = {
439
16
    { &hf_nasdaq_itch_version,
440
16
      { "Version",         "nasdaq-itch.version",
441
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
442
16
        NULL, HFILL }},
443
444
16
    { &hf_nasdaq_itch_message_type,
445
16
      { "Message Type",         "nasdaq-itch.message_type",
446
16
        FT_CHAR, BASE_HEX, VALS(message_types_val), 0x0,
447
16
        NULL, HFILL }},
448
449
16
    { &hf_nasdaq_itch_second,
450
16
      { "Second",         "nasdaq-itch.second",
451
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
452
16
        NULL, HFILL }},
453
454
16
    { &hf_nasdaq_itch_millisecond,
455
16
      { "Millisecond",         "nasdaq-itch.millisecond",
456
16
        FT_UINT32, BASE_DEC,  NULL, 0x0,
457
16
        NULL, HFILL }},
458
459
16
    { &hf_nasdaq_itch_system_event,
460
16
      { "System Event",         "nasdaq-itch.system_event",
461
16
        FT_CHAR, BASE_HEX, VALS(system_event_val), 0x0,
462
16
        NULL, HFILL }},
463
464
16
    { &hf_nasdaq_itch_market_category,
465
16
      { "Market Category",         "nasdaq-itch.market_category",
466
16
        FT_CHAR, BASE_HEX, VALS(market_category_val), 0x0,
467
16
        NULL, HFILL }},
468
469
16
    { &hf_nasdaq_itch_financial_status,
470
16
      { "Financial Status Indicator",         "nasdaq-itch.financial_status",
471
16
        FT_CHAR, BASE_HEX, VALS(financial_status_val), 0x0,
472
16
        NULL, HFILL }},
473
474
16
    { &hf_nasdaq_itch_stock,
475
16
      { "Stock",         "nasdaq-itch.stock",
476
16
        FT_STRING, BASE_NONE, NULL, 0x0,
477
16
        NULL, HFILL }},
478
479
16
    { &hf_nasdaq_itch_round_lot_size,
480
16
      { "Round Lot Size",         "nasdaq-itch.round_lot_size",
481
16
        FT_STRING, BASE_NONE, NULL, 0x0,
482
16
        NULL, HFILL }},
483
484
16
    { &hf_nasdaq_itch_round_lots_only,
485
16
      { "Round Lots Only",         "nasdaq-itch.round_lots_only",
486
16
        FT_CHAR, BASE_HEX, VALS(round_lots_only_val), 0x0,
487
16
        NULL, HFILL }},
488
489
16
    { &hf_nasdaq_itch_trading_state,
490
16
      { "Trading State",         "nasdaq-itch.trading_state",
491
16
        FT_STRING, BASE_NONE, NULL, 0x0,
492
16
        NULL, HFILL }},
493
494
16
    { &hf_nasdaq_itch_reserved,
495
16
      { "Reserved",         "nasdaq-itch.reserved",
496
16
        FT_STRING, BASE_NONE, NULL, 0x0,
497
16
        NULL, HFILL }},
498
499
16
    { &hf_nasdaq_itch_reason,
500
16
      { "Reason",         "nasdaq-itch.reason",
501
16
        FT_STRING, BASE_NONE, NULL, 0x0,
502
16
        NULL, HFILL }},
503
504
16
    { &hf_nasdaq_itch_order_reference,
505
16
      { "Order Reference",         "nasdaq-itch.order_reference",
506
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
507
16
        "Order reference number", HFILL }},
508
509
16
    { &hf_nasdaq_itch_buy_sell,
510
16
      { "Buy/Sell",         "nasdaq-itch.buy_sell",
511
16
        FT_STRING, BASE_NONE, NULL, 0x0,
512
16
        "Buy/Sell indicator", HFILL }},
513
514
16
    { &hf_nasdaq_itch_shares,
515
16
      { "Shares",         "nasdaq-itch.shares",
516
16
        FT_UINT32, BASE_DEC,  NULL, 0x0,
517
16
        "Number of shares", HFILL }},
518
519
16
    { &hf_nasdaq_itch_price,
520
16
      { "Price",         "nasdaq-itch.price",
521
16
        FT_DOUBLE, BASE_NONE, NULL, 0x0,
522
16
        NULL, HFILL }},
523
524
16
    { &hf_nasdaq_itch_attribution,
525
16
      { "Attribution",         "nasdaq-itch.attribution",
526
16
        FT_STRING, BASE_NONE, NULL, 0x0,
527
16
        "Market participant identifier", HFILL }},
528
529
16
    { &hf_nasdaq_itch_executed,
530
16
      { "Executed Shares",         "nasdaq-itch.executed",
531
16
        FT_UINT32, BASE_DEC,  NULL, 0x0,
532
16
        "Number of shares executed", HFILL }},
533
534
16
    { &hf_nasdaq_itch_match,
535
16
      { "Matched",         "nasdaq-itch.match",
536
16
        FT_STRING, BASE_NONE, NULL, 0x0,
537
16
        "Match number", HFILL }},
538
539
16
    { &hf_nasdaq_itch_printable,
540
16
      { "Printable",         "nasdaq-itch.printable",
541
16
        FT_STRING, BASE_NONE, NULL, 0x0,
542
16
        NULL, HFILL }},
543
544
16
    { &hf_nasdaq_itch_execution_price,
545
16
      { "Execution Price",         "nasdaq-itch.execution_price",
546
16
        FT_DOUBLE, BASE_NONE, NULL, 0x0,
547
16
        NULL, HFILL }},
548
549
16
    { &hf_nasdaq_itch_canceled,
550
16
      { "Canceled Shares",         "nasdaq-itch.canceled",
551
16
        FT_UINT32, BASE_DEC,  NULL, 0x0,
552
16
        "Number of shares to be removed", HFILL }},
553
554
16
    { &hf_nasdaq_itch_cross,
555
16
      { "Cross Type",         "nasdaq-itch.cross",
556
16
        FT_STRING, BASE_NONE, NULL, 0x0,
557
16
        "Cross trade type", HFILL }},
558
559
16
    { &hf_nasdaq_itch_message,
560
16
      { "Message",         "nasdaq-itch.message",
561
16
        FT_STRING, BASE_NONE, NULL, 0x0,
562
16
        NULL, HFILL }}
563
16
  };
564
565
/* Setup protocol subtree array */
566
16
  static int *ett[] = {
567
16
    &ett_nasdaq_itch
568
16
  };
569
570
16
  module_t *nasdaq_itch_module;
571
572
  /* Register the protocol name and description */
573
16
  proto_nasdaq_itch = proto_register_protocol("Nasdaq TotalView-ITCH", "NASDAQ-ITCH", "nasdaq_itch");
574
575
  /* Required function calls to register the header fields and subtrees used */
576
16
  proto_register_field_array(proto_nasdaq_itch, hf, array_length(hf));
577
16
  proto_register_subtree_array(ett, array_length(ett));
578
579
16
  nasdaq_itch_module = prefs_register_protocol(proto_nasdaq_itch, NULL);
580
16
  prefs_register_bool_preference(nasdaq_itch_module, "chi_x", "Decode Chi X extensions",
581
16
                                 "Whether the Nasdaq ITCH dissector should decode Chi X extensions.",
582
16
                                 &nasdaq_itch_chi_x);
583
584
16
  nasdaq_itch_handle = register_dissector("nasdaq-itch", dissect_nasdaq_itch, proto_nasdaq_itch);
585
16
}
586
587
void
588
proto_reg_handoff_nasdaq_itch(void)
589
16
{
590
16
  dissector_add_for_decode_as("moldudp64.payload", nasdaq_itch_handle );
591
16
  dissector_add_for_decode_as("moldudp.payload", nasdaq_itch_handle );
592
16
}
593
594
/*
595
 * Editor modelines
596
 *
597
 * Local Variables:
598
 * c-basic-offset: 2
599
 * tab-width: 8
600
 * indent-tabs-mode: nil
601
 * End:
602
 *
603
 * ex: set shiftwidth=2 tabstop=8 expandtab:
604
 * :indentSize=2:tabSize=8:noTabs=true:
605
 */