/* -------------------------- */
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;
}
Example #2
0
/* -------------------------- */
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;
    }
}