/* -------------------------- */ static int executed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *nasdaq_itch_tree, int offset, int big) { offset = order_ref_number(tvb, pinfo, nasdaq_itch_tree, offset); offset = number_of_shares(tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_executed, offset, big); proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_match, tvb, offset, 9, ENC_ASCII|ENC_NA); offset += 9; return offset; }
/* -------------------------- */ static int order(tvbuff_t *tvb, packet_info *pinfo, proto_tree *nasdaq_itch_tree, int offset, int big) { guint8 value; offset = order_ref_number(tvb, pinfo, nasdaq_itch_tree, offset); value = tvb_get_guint8(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, "%c ", value); proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_buy_sell, tvb, offset, 1, ENC_ASCII|ENC_NA); offset += 1; offset = number_of_shares(tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_shares, offset, big); offset = stock(tvb, pinfo, nasdaq_itch_tree, offset); offset = price(tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_price, offset, big); return offset; }
/* ---------------------------- */ static void dissect_nasdaq_itch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *nasdaq_itch_tree = NULL; guint8 nasdaq_itch_type; int offset = 0; gint col_info; int version = 3; int big = 0; col_info = PINFO_COL(pinfo); col_set_str(pinfo->cinfo, COL_PROTOCOL, "Nasdaq-ITCH"); nasdaq_itch_type = tvb_get_guint8(tvb, offset); if (nasdaq_itch_type >= '0' && nasdaq_itch_type <= '9') { version = 2; nasdaq_itch_type = tvb_get_guint8(tvb, offset +8); } if ((!nasdaq_itch_chi_x || version == 3) && strchr(chix_msg, nasdaq_itch_type)) { nasdaq_itch_type = 0; /* unknown */ } if (col_info || tree) { const gchar *rep = val_to_str(nasdaq_itch_type, message_types_val, "Unknown packet type (0x%02x) "); if (col_info ) { col_clear(pinfo->cinfo, COL_INFO); col_add_str(pinfo->cinfo, COL_INFO, rep); } if (tree) { proto_item *item; ti = proto_tree_add_protocol_format(tree, proto_nasdaq_itch, tvb, offset, -1, "Nasdaq TotalView-ITCH %s, %s", version == 2?"2.0":"3.0", rep); nasdaq_itch_tree = proto_item_add_subtree(ti, ett_nasdaq_itch); item=proto_tree_add_uint(nasdaq_itch_tree, hf_nasdaq_itch_version, tvb, 0, 0, version); PROTO_ITEM_SET_GENERATED(item); } } if (version == 2) { offset = time_stamp (tvb, nasdaq_itch_tree, hf_nasdaq_itch_millisecond, offset, 8); } proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_message_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; if (version == 3) { switch (nasdaq_itch_type) { case 'T': /* seconds */ offset = time_stamp (tvb, nasdaq_itch_tree, hf_nasdaq_itch_second, offset, 5); return; case 'M': /* milliseconds */ offset = time_stamp (tvb, nasdaq_itch_tree, hf_nasdaq_itch_millisecond, offset, 3); return; } } switch (nasdaq_itch_type) { case 'S': /* system event */ proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_system_event, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; break; case 'R': /* Stock Directory */ offset = stock(tvb, pinfo, nasdaq_itch_tree, offset); proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_market_category, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_financial_status, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_round_lot_size, tvb, offset, 6, ENC_ASCII|ENC_NA); offset += 6; proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_round_lots_only, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; break; case 'H': /* Stock trading action */ offset = stock(tvb, pinfo, nasdaq_itch_tree, offset); proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_trading_state, tvb, offset, 1, ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_reserved, tvb, offset, 1, ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_reason, tvb, offset, 4, ENC_ASCII|ENC_NA); offset += 4; break; case 'a' : big = 1; case 'A': /* Add order, no MPID */ offset = order(tvb, pinfo, nasdaq_itch_tree, offset, big); if (version == 2) { proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_printable, tvb, offset, 1, ENC_ASCII|ENC_NA); offset += 1; } break; case 'F': /* Add order, MPID */ offset = order(tvb, pinfo, nasdaq_itch_tree, offset, big); proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_attribution, tvb, offset, 4, ENC_ASCII|ENC_NA); offset += 4; break; case 'e' : big = 1; case 'E' : /* Order executed */ offset = executed(tvb, pinfo, nasdaq_itch_tree, offset, big); break; case 'C' : /* Order executed with price */ offset = executed(tvb, pinfo, nasdaq_itch_tree, offset, big); proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_printable, tvb, offset, 1, ENC_ASCII|ENC_NA); offset += 1; offset = price(tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_execution_price, offset, big); break; case 'x' : big = 1; case 'X' : /* Order cancel */ offset = order_ref_number(tvb, pinfo, nasdaq_itch_tree, offset); offset = number_of_shares(tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_canceled, offset, big); break; case 'D' : /* Order delete */ offset = order_ref_number(tvb, pinfo, nasdaq_itch_tree, offset); offset += 9; break; case 'p' : big = 1; case 'P' : /* Trade identifier */ offset = order(tvb, pinfo, nasdaq_itch_tree, offset, big); proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_match, tvb, offset, 9, ENC_ASCII|ENC_NA); offset += 9; break; case 'Q' : /* Cross Trade */ offset = number_of_shares(tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_shares, offset, big); offset = stock(tvb, pinfo, nasdaq_itch_tree, offset); offset = price(tvb, pinfo, nasdaq_itch_tree, hf_nasdaq_itch_price, offset, big); proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_match, tvb, offset, 9, ENC_ASCII|ENC_NA); offset += 9; proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_cross, tvb, offset, 1, ENC_ASCII|ENC_NA); offset += 1; break; case 'B' : /* Broken Trade */ proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_match, tvb, offset, 9, ENC_ASCII|ENC_NA); offset += 9; break; case 'I': /* NOII, FIXME */ offset = stock(tvb, pinfo, nasdaq_itch_tree, offset); proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_cross, tvb, offset, 1, ENC_ASCII|ENC_NA); offset += 1; break; default: /* unknown */ proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_message, tvb, offset, -1, ENC_ASCII|ENC_NA); offset += 5-1; break; } }