diff options
Diffstat (limited to 'epan/dissectors/packet-opa.c')
-rw-r--r-- | epan/dissectors/packet-opa.c | 2012 |
1 files changed, 2012 insertions, 0 deletions
diff --git a/epan/dissectors/packet-opa.c b/epan/dissectors/packet-opa.c new file mode 100644 index 00000000..7b2c7c70 --- /dev/null +++ b/epan/dissectors/packet-opa.c @@ -0,0 +1,2012 @@ +/* packet-opa.c + * Routines for Omni-Path 9B L2, L4, and extended L4 header dissection + * Copyright (c) 2016, Intel Corporation. + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +#include <epan/packet.h> +#include <wiretap/erf_record.h> + +void proto_reg_handoff_opa_9b(void); +void proto_register_opa_9b(void); + +/* OpCodeValues + * Code Bits [7-5] Connection Type + * [4-0] Message Type + * Reliable Connection (RC) [7-5] = 000 */ +#define RC_SEND_FIRST 0 /*0x00000000 */ +#define RC_SEND_MIDDLE 1 /*0x00000001 */ +#define RC_SEND_LAST 2 /*0x00000010 */ +#define RC_SEND_LAST_IMM 3 /*0x00000011 */ +#define RC_SEND_ONLY 4 /*0x00000100 */ +#define RC_SEND_ONLY_IMM 5 /*0x00000101 */ +#define RC_RDMA_WRITE_FIRST 6 /*0x00000110 */ +#define RC_RDMA_WRITE_MIDDLE 7 /*0x00000111 */ +#define RC_RDMA_WRITE_LAST 8 /*0x00001000 */ +#define RC_RDMA_WRITE_LAST_IMM 9 /*0x00001001 */ +#define RC_RDMA_WRITE_ONLY 10 /*0x00001010 */ +#define RC_RDMA_WRITE_ONLY_IMM 11 /*0x00001011 */ +#define RC_RDMA_READ_REQUEST 12 /*0x00001100 */ +#define RC_RDMA_READ_RESPONSE_FIRST 13 /*0x00001101 */ +#define RC_RDMA_READ_RESPONSE_MIDDLE 14 /*0x00001110 */ +#define RC_RDMA_READ_RESPONSE_LAST 15 /*0x00001111 */ +#define RC_RDMA_READ_RESPONSE_ONLY 16 /*0x00010000 */ +#define RC_ACKNOWLEDGE 17 /*0x00010001 */ +#define RC_ATOMIC_ACKNOWLEDGE 18 /*0x00010010 */ +#define RC_CMP_SWAP 19 /*0x00010011 */ +#define RC_FETCH_ADD 20 /*0x00010100 */ +#define RC_SEND_LAST_INVAL 22 /*0x00010110 */ +#define RC_SEND_ONLY_INVAL 23 /*0x00010111 */ +/* Reliable Datagram (RD) [7-5] = 010 */ +#define RD_SEND_FIRST 64 /*0x01000000 */ +#define RD_SEND_MIDDLE 65 /*0x01000001 */ +#define RD_SEND_LAST 66 /*0x01000010 */ +#define RD_SEND_LAST_IMM 67 /*0x01000011 */ +#define RD_SEND_ONLY 68 /*0x01000100 */ +#define RD_SEND_ONLY_IMM 69 /*0x01000101 */ +#define RD_RDMA_WRITE_FIRST 70 /*0x01000110 */ +#define RD_RDMA_WRITE_MIDDLE 71 /*0x01000111 */ +#define RD_RDMA_WRITE_LAST 72 /*0x01001000 */ +#define RD_RDMA_WRITE_LAST_IMM 73 /*0x01001001 */ +#define RD_RDMA_WRITE_ONLY 74 /*0x01001010 */ +#define RD_RDMA_WRITE_ONLY_IMM 75 /*0x01001011 */ +#define RD_RDMA_READ_REQUEST 76 /*0x01001100 */ +#define RD_RDMA_READ_RESPONSE_FIRST 77 /*0x01001101 */ +#define RD_RDMA_READ_RESPONSE_MIDDLE 78 /*0x01001110 */ +#define RD_RDMA_READ_RESPONSE_LAST 79 /*0x01001111 */ +#define RD_RDMA_READ_RESPONSE_ONLY 80 /*0x01010000 */ +#define RD_ACKNOWLEDGE 81 /*0x01010001 */ +#define RD_ATOMIC_ACKNOWLEDGE 82 /*0x01010010 */ +#define RD_CMP_SWAP 83 /*0x01010011 */ +#define RD_FETCH_ADD 84 /*0x01010100 */ +#define RD_RESYNC 85 /*0x01010101 */ +/* Unreliable Datagram (UD) [7-5] = 011 */ +#define UD_SEND_ONLY 100 /*0x01100100 */ +#define UD_SEND_ONLY_IMM 101 /*0x01100101 */ +/* Unreliable Connection (UC) [7-5] = 001 */ +#define UC_SEND_FIRST 32 /*0x00100000 */ +#define UC_SEND_MIDDLE 33 /*0x00100001 */ +#define UC_SEND_LAST 34 /*0x00100010 */ +#define UC_SEND_LAST_IMM 35 /*0x00100011 */ +#define UC_SEND_ONLY 36 /*0x00100100 */ +#define UC_SEND_ONLY_IMM 37 /*0x00100101 */ +#define UC_RDMA_WRITE_FIRST 38 /*0x00100110 */ +#define UC_RDMA_WRITE_MIDDLE 39 /*0x00100111 */ +#define UC_RDMA_WRITE_LAST 40 /*0x00101000 */ +#define UC_RDMA_WRITE_LAST_IMM 41 /*0x00101001 */ +#define UC_RDMA_WRITE_ONLY 42 /*0x00101010 */ +#define UC_RDMA_WRITE_ONLY_IMM 43 /*0x00101011 */ + +/* Header Ordering Based on OPCODES */ +#define RDETH_DETH_PAYLD 0 +#define RDETH_DETH_RETH_PAYLD 1 +#define RDETH_DETH_IMMDT_PAYLD 2 +#define RDETH_DETH_RETH_IMMDT_PAYLD 3 +#define RDETH_DETH_RETH 4 +#define RDETH_AETH_PAYLD 5 +#define RDETH_PAYLD 6 +#define RDETH_AETH 7 +#define RDETH_AETH_ATOMICACKETH 8 +#define RDETH_DETH_ATOMICETH 9 +#define RDETH_DETH 10 +#define DETH_PAYLD 11 +#define DETH_IMMDT_PAYLD 12 +#define PAYLD 13 +#define IMMDT_PAYLD 14 +#define RETH_PAYLD 15 +#define RETH_IMMDT_PAYLD 16 +#define RETH 17 +#define AETH_PAYLD 18 +#define AETH 19 +#define AETH_ATOMICACKETH 20 +#define ATOMICETH 21 +#define IETH_PAYLD 22 +#define KDETH_PSM 23 +#define KDETH_TIDRDMA 24 + +/* PSM */ +#define PSM_RESERVED 0xC0 +#define PSM_TINY 0xC1 +#define PSM_SHORT 0xC2 +#define PSM_MEDIUM 0xC3 +#define PSM_MEDIUM_DATA 0xC4 +#define PSM_LONG_RTS 0xC5 +#define PSM_LONG_CTS 0xC6 +#define PSM_LONG_DATA 0xC7 +#define PSM_TIDS_GRANT 0xC8 +#define PSM_TIDS_GRANT_ACK 0xC9 +#define PSM_TIDS_RELEASE 0xCA +#define PSM_TIDS_RELEASE_CONFIRM 0xCB +#define PSM_EXPTID_UNALIGNED 0xCC +#define PSM_EXPTID 0xCD +#define PSM_ACK 0xCE +#define PSM_NAK 0xCF +#define PSM_ERR_CHK 0xD0 +#define PSM_ERR_CHK_BAD 0xD1 +#define PSM_ERR_CHK_GEN 0xD2 +#define PSM_FLOW_CCA_BECN 0xD3 +#define PSM_CONNECT_REQUEST 0xD4 +#define PSM_CONNECT_REPLY 0xD5 +#define PSM_DISCONNECT_REQUEST 0xD6 +#define PSM_DISCONNECT_REPLY 0xD7 +#define PSM_AM_REQUEST_NOREPLY 0xD8 +#define PSM_AM_REQUEST 0xD9 +#define PSM_AM_REPLY 0xDA + +/* TID RDMA */ +#define TID_RDMA_WRITE_REQUEST 0xE0 +#define TID_RDMA_WRITE_RESPONSE 0xE1 +#define TID_RDMA_WRITE_DATA 0xE2 +#define TID_RDMA_WRITE_DATA_LAST 0xE3 +#define TID_RDMA_READ_REQUEST 0xE4 +#define TID_RDMA_READ_RESPONSE 0xE5 +#define TID_RDMA_RESYNC 0xE6 +#define TID_RDMA_ACK 0xE7 + +/* Array of all availavle OpCodes to make matching a bit easier. The OpCodes + * dictate the header sequence following in the packet. These arrays tell the + * dissector which headers must be decoded for the given OpCode. + */ +static guint32 opCode_RDETH_DETH_ATOMICETH[] = { + RD_CMP_SWAP, + RD_FETCH_ADD +}; +static guint32 opCode_IETH_PAYLD[] = { + RC_SEND_LAST_INVAL, + RC_SEND_ONLY_INVAL +}; +static guint32 opCode_ATOMICETH[] = { + RC_CMP_SWAP, + RC_FETCH_ADD +}; +static guint32 opCode_RDETH_DETH_RETH_PAYLD[] = { + RD_RDMA_WRITE_FIRST, + RD_RDMA_WRITE_ONLY +}; +static guint32 opCode_RETH_IMMDT_PAYLD[] = { + RC_RDMA_WRITE_ONLY_IMM, + UC_RDMA_WRITE_ONLY_IMM +}; +static guint32 opCode_RDETH_DETH_IMMDT_PAYLD[] = { + RD_SEND_LAST_IMM, + RD_SEND_ONLY_IMM, + RD_RDMA_WRITE_LAST_IMM +}; +static guint32 opCode_RDETH_AETH_PAYLD[] = { + RD_RDMA_READ_RESPONSE_FIRST, + RD_RDMA_READ_RESPONSE_LAST, + RD_RDMA_READ_RESPONSE_ONLY +}; +static guint32 opCode_AETH_PAYLD[] = { + RC_RDMA_READ_RESPONSE_FIRST, + RC_RDMA_READ_RESPONSE_LAST, + RC_RDMA_READ_RESPONSE_ONLY +}; +static guint32 opCode_RETH_PAYLD[] = { + RC_RDMA_WRITE_FIRST, + RC_RDMA_WRITE_ONLY, + UC_RDMA_WRITE_FIRST, + UC_RDMA_WRITE_ONLY +}; +static guint32 opCode_RDETH_DETH_PAYLD[] = { + RD_SEND_FIRST, + RD_SEND_MIDDLE, + RD_SEND_LAST, + RD_SEND_ONLY, + RD_RDMA_WRITE_MIDDLE, + RD_RDMA_WRITE_LAST +}; +static guint32 opCode_IMMDT_PAYLD[] = { + RC_SEND_LAST_IMM, + RC_SEND_ONLY_IMM, + RC_RDMA_WRITE_LAST_IMM, + UC_SEND_LAST_IMM, + UC_SEND_ONLY_IMM, + UC_RDMA_WRITE_LAST_IMM +}; +static guint32 opCode_PAYLD[] = { + RC_SEND_FIRST, + RC_SEND_MIDDLE, + RC_SEND_LAST, + RC_SEND_ONLY, + RC_RDMA_WRITE_MIDDLE, + RC_RDMA_WRITE_LAST, + RC_RDMA_READ_RESPONSE_MIDDLE, + UC_SEND_FIRST, + UC_SEND_MIDDLE, + UC_SEND_LAST, + UC_SEND_ONLY, + UC_RDMA_WRITE_MIDDLE, + UC_RDMA_WRITE_LAST +}; +static guint32 opCode_PSM[] = { + PSM_RESERVED, + PSM_TINY, + PSM_SHORT, + PSM_MEDIUM, + PSM_MEDIUM_DATA, + PSM_LONG_RTS, + PSM_LONG_CTS, + PSM_LONG_DATA, + PSM_TIDS_GRANT, + PSM_TIDS_GRANT_ACK, + PSM_TIDS_RELEASE, + PSM_TIDS_RELEASE_CONFIRM, + PSM_EXPTID_UNALIGNED, + PSM_EXPTID, + PSM_ACK, + PSM_NAK, + PSM_ERR_CHK, + PSM_ERR_CHK_BAD, + PSM_ERR_CHK_GEN, + PSM_FLOW_CCA_BECN, + PSM_CONNECT_REQUEST, + PSM_CONNECT_REPLY, + PSM_DISCONNECT_REQUEST, + PSM_DISCONNECT_REPLY, + PSM_AM_REQUEST_NOREPLY, + PSM_AM_REQUEST, + PSM_AM_REPLY +}; +static guint opCode_TIDRDMA[] = { + TID_RDMA_WRITE_REQUEST, + TID_RDMA_WRITE_RESPONSE, + TID_RDMA_WRITE_DATA, + TID_RDMA_WRITE_DATA_LAST, + TID_RDMA_READ_REQUEST, + TID_RDMA_READ_RESPONSE, + TID_RDMA_RESYNC, + TID_RDMA_ACK +}; + +/* OP Codes */ +static const value_string vals_opa_bth_opcode[] = { + { RC_SEND_FIRST, "RC Send First" }, + { RC_SEND_MIDDLE, "RC Send Middle" }, + { RC_SEND_LAST, "RC Send Last" }, + { RC_SEND_LAST_IMM, "RC Send Last Immediate" }, + { RC_SEND_ONLY, "RC Send Only" }, + { RC_SEND_ONLY_IMM, "RC Send Only Immediate" }, + { RC_RDMA_WRITE_FIRST, "RC RDMA Write First" }, + { RC_RDMA_WRITE_MIDDLE, "RC RDMA Write Middle" }, + { RC_RDMA_WRITE_LAST, "RC RDMA Write Last" }, + { RC_RDMA_WRITE_LAST_IMM, "RC RDMA Write Last Immediate" }, + { RC_RDMA_WRITE_ONLY, "RC RDMA Write Only" }, + { RC_RDMA_WRITE_ONLY_IMM, "RC RDMA Write Only Immediate" }, + { RC_RDMA_READ_REQUEST, "RC RDMA Read Request" }, + { RC_RDMA_READ_RESPONSE_FIRST, "RC RDMA Read Response First" }, + { RC_RDMA_READ_RESPONSE_MIDDLE, "RC RDMA Read Response Middle" }, + { RC_RDMA_READ_RESPONSE_LAST, "RC RDMA Read Response Last" }, + { RC_RDMA_READ_RESPONSE_ONLY, "RC RDMA Read Response Only" }, + { RC_ACKNOWLEDGE, "RC Acknowledge" }, + { RC_ATOMIC_ACKNOWLEDGE, "RC Atomic Acknowledge" }, + { RC_CMP_SWAP, "RC Compare Swap" }, + { RC_FETCH_ADD, "RC Fetch Add" }, + { RC_SEND_LAST_INVAL, "RC Send Last Invalidate" }, + { RC_SEND_ONLY_INVAL, "RC Send Only Invalidate" }, + { RD_SEND_FIRST, "RD Send First" }, + { RD_SEND_MIDDLE, "RD Send Middle" }, + { RD_SEND_LAST, "RD Send Last" }, + { RD_SEND_LAST_IMM, "RD Last Immediate" }, + { RD_SEND_ONLY, "RD Send Only" }, + { RD_SEND_ONLY_IMM, "RD Send Only Immediate" }, + { RD_RDMA_WRITE_FIRST, "RD RDMA Write First" }, + { RD_RDMA_WRITE_MIDDLE, "RD RDMA Write Middle" }, + { RD_RDMA_WRITE_LAST, "RD RDMA Write Last" }, + { RD_RDMA_WRITE_LAST_IMM, "RD RDMA Write Last Immediate" }, + { RD_RDMA_WRITE_ONLY, "RD RDMA Write Only" }, + { RD_RDMA_WRITE_ONLY_IMM, "RD RDMA Write Only Immediate" }, + { RD_RDMA_READ_REQUEST, "RD RDMA Read Request" }, + { RD_RDMA_READ_RESPONSE_FIRST, "RD RDMA Read Response First" }, + { RD_RDMA_READ_RESPONSE_MIDDLE, "RD RDMA Read Response Middle" }, + { RD_RDMA_READ_RESPONSE_LAST, "RD RDMA Read Response Last" }, + { RD_RDMA_READ_RESPONSE_ONLY, "RD RDMA Read Response Only" }, + { RD_ACKNOWLEDGE, "RD Acknowledge" }, + { RD_ATOMIC_ACKNOWLEDGE, "RD Atomic Acknowledge" }, + { RD_CMP_SWAP, "RD Compare Swap" }, + { RD_FETCH_ADD, "RD Fetch Add" }, + { RD_RESYNC, "RD RESYNC" }, + { UD_SEND_ONLY, "UD Send Only" }, + { UD_SEND_ONLY_IMM, "UD Send Only Immediate" }, + { UC_SEND_FIRST, "UC Send First" }, + { UC_SEND_MIDDLE, "UC Send Middle" }, + { UC_SEND_LAST, "UC Send Last" }, + { UC_SEND_LAST_IMM, "UC Send Last Immediate" }, + { UC_SEND_ONLY, "UC Send Only" }, + { UC_SEND_ONLY_IMM, "UC Send Only Immediate" }, + { UC_RDMA_WRITE_FIRST, "UC RDMA Write First" }, + { UC_RDMA_WRITE_MIDDLE, "Unreliable Connection RDMA Write Middle" }, + { UC_RDMA_WRITE_LAST, "UC RDMA Write Last" }, + { UC_RDMA_WRITE_LAST_IMM, "UC RDMA Write Last Immediate" }, + { UC_RDMA_WRITE_ONLY, "UC RDMA Write Only" }, + { UC_RDMA_WRITE_ONLY_IMM, "UC RDMA Write Only Immediate" }, + { PSM_RESERVED, "PSM Reserved" }, + { PSM_TINY, "PSM TINY" }, + { PSM_SHORT, "PSM SHORT" }, + { PSM_MEDIUM, "PSM MEDIUM" }, + { PSM_MEDIUM_DATA, "PSM MEDIUM_DATA" }, + { PSM_LONG_RTS, "PSM LONG RTS" }, + { PSM_LONG_CTS, "PSM LONG CTS" }, + { PSM_LONG_DATA, "PSM LONG DATA" }, + { PSM_TIDS_GRANT, "PSM TIDS GRANT" }, + { PSM_TIDS_GRANT_ACK, "PSM TIDS GRANT ACK" }, + { PSM_TIDS_RELEASE, "PSM TIDS RELEASE" }, + { PSM_TIDS_RELEASE_CONFIRM, "PSM TIDS RELEASE CONFIRM" }, + { PSM_EXPTID_UNALIGNED, "PSM EXPTID UNALIGNED" }, + { PSM_EXPTID, "PSM EXPTID" }, + { PSM_ACK, "PSM ACK" }, + { PSM_NAK, "PSM NAK" }, + { PSM_ERR_CHK, "PSM ERR CHK" }, + { PSM_ERR_CHK_BAD, "PSM ERR CHK BAD" }, + { PSM_ERR_CHK_GEN, "PSM ERR CHK GEN" }, + { PSM_FLOW_CCA_BECN, "PSM FLOW CCA BECN" }, + { PSM_CONNECT_REQUEST, "PSM CONNECT REQUEST" }, + { PSM_CONNECT_REPLY, "PSM CONNECT REPLY" }, + { PSM_DISCONNECT_REQUEST, "PSM DISCONNECT REQUEST" }, + { PSM_DISCONNECT_REPLY, "PSM DISCONNECT REPLY" }, + { PSM_AM_REQUEST_NOREPLY, "PSM AM REQUEST NOREPLY" }, + { PSM_AM_REQUEST, "PSM AM REQUEST" }, + { PSM_AM_REPLY, "PSM AM REPLY" }, + { TID_RDMA_WRITE_REQUEST, "TID RDMA Write Request" }, + { TID_RDMA_WRITE_RESPONSE, "TID RDMA Write Response" }, + { TID_RDMA_WRITE_DATA, "TID RDMA Write Data" }, + { TID_RDMA_WRITE_DATA_LAST, "TID RDMA Write Data Last" }, + { TID_RDMA_READ_REQUEST, "TID RDMA Read Request" }, + { TID_RDMA_READ_RESPONSE, "TID RDMA Read Response" }, + { TID_RDMA_RESYNC, "TID RDMA ReSync" }, + { TID_RDMA_ACK, "TID RDMA Ack" }, + { 0, NULL } +}; +static const value_string vals_opa_9b_lnh[] = { + { 0, "RAW" }, + { 3, "GRH" }, + { 2, "BTH" }, + { 1, "Ipv6" }, + { 0, NULL } +}; +static const value_string vals_opa_9b_grh_ipver[] = { + { 4, "IPv4" }, + { 6, "IPv6" }, + { 0, NULL }, +}; +static const value_string vals_opa_9b_grh_next_hdr[] = { + { 0x1B, "BTH Follows" }, + { 0, NULL } +}; +static const true_false_string tfs_opa_bth_migrated_notmigrated = { + "Migrated", + "Not Migrated" +}; +static const true_false_string tfs_opa_kdeth_offset_32_64 = { + "32 Byte Words", + "64 Byte Words" +}; +/* Wireshark ID */ +static gint proto_opa_9b = -1; + +/* Variables to hold expansion values between packets */ +static gint ett_all_headers = -1; +static gint ett_9b = -1; +static gint ett_grh = -1; +static gint ett_bth = -1; +static gint ett_rdeth = -1; +static gint ett_deth = -1; +static gint ett_reth = -1; +static gint ett_atomiceth = -1; +static gint ett_aeth = -1; +static gint ett_atomicacketh = -1; +static gint ett_immdt = -1; +static gint ett_ieth = -1; +static gint ett_kdeth = -1; +static gint ett_psm = -1; +static gint ett_tidrdma = -1; + +/* 9B Header Fields */ +static gint hf_opa_9B = -1; +static gint hf_opa_9B_service_channel = -1; +static gint hf_opa_9B_link_version = -1; +static gint hf_opa_9B_service_level = -1; +static gint hf_opa_9B_reserved2 = -1; +static gint hf_opa_9B_lnh = -1; +static gint hf_opa_9B_dlid = -1; +static gint hf_opa_9B_reserved3 = -1; +static gint hf_opa_9B_packet_length = -1; +static gint hf_opa_9B_slid = -1; +/* ICRC */ +static gint hf_opa_9b_ICRC = -1; + +/* GRH */ +static gint hf_opa_grh = -1; +static gint hf_opa_grh_ip_version = -1; +static gint hf_opa_grh_traffic_class = -1; +static gint hf_opa_grh_flow_label = -1; +static gint hf_opa_grh_payload_length = -1; +static gint hf_opa_grh_next_header = -1; +static gint hf_opa_grh_hop_limit = -1; +static gint hf_opa_grh_source_gid = -1; +static gint hf_opa_grh_destination_gid = -1; + +/* BTH */ +static gint hf_opa_bth = -1; +static gint hf_opa_bth_opcode = -1; +static gint hf_opa_bth_solicited_event = -1; +static gint hf_opa_bth_migreq = -1; +static gint hf_opa_bth_pad_count = -1; +static gint hf_opa_bth_transport_header_version = -1; +static gint hf_opa_bth_partition_key = -1; +static gint hf_opa_bth_fcn = -1; +static gint hf_opa_bth_bcn = -1; +static gint hf_opa_bth_Reserved8a = -1; +static gint hf_opa_bth_destination_qp = -1; +static gint hf_opa_bth_acknowledge_request = -1; +static gint hf_opa_bth_packet_sequence_number = -1; + +/* XXETH */ +static gint hf_opa_RDETH = -1; +static gint hf_opa_RDETH_reserved8 = -1; +static gint hf_opa_RDETH_ee_context = -1; +static gint hf_opa_DETH = -1; +static gint hf_opa_DETH_queue_key = -1; +static gint hf_opa_DETH_reserved8 = -1; +static gint hf_opa_DETH_source_qp = -1; +static gint hf_opa_RETH = -1; +static gint hf_opa_RETH_virtual_address = -1; +static gint hf_opa_RETH_remote_key = -1; +static gint hf_opa_RETH_dma_length = -1; +static gint hf_opa_AtomicETH = -1; +static gint hf_opa_AtomicETH_virtual_address = -1; +static gint hf_opa_AtomicETH_remote_key = -1; +static gint hf_opa_AtomicETH_swap_or_add_data = -1; +static gint hf_opa_AtomicETH_compare_data = -1; +static gint hf_opa_AETH = -1; +static gint hf_opa_AETH_syndrome = -1; +static gint hf_opa_AETH_message_sequence_number = -1; +static gint hf_opa_AtomicAckETH = -1; +static gint hf_opa_AtomicAckETH_original_remote_data = -1; +static gint hf_opa_IMMDT = -1; +static gint hf_opa_IMMDT_data = -1; +static gint hf_opa_IETH = -1; +static gint hf_opa_IETH_r_key = -1; +static gint hf_opa_KDETH = -1; +static gint hf_opa_KDETH_kver = -1; +static gint hf_opa_KDETH_sh = -1; +static gint hf_opa_KDETH_intr = -1; +static gint hf_opa_KDETH_tidctrl = -1; +static gint hf_opa_KDETH_tid = -1; +static gint hf_opa_KDETH_offset_mode = -1; +static gint hf_opa_KDETH_offset = -1; +static int * const _opa_KDETH_word1[] = { + &hf_opa_KDETH_kver, + &hf_opa_KDETH_sh, + &hf_opa_KDETH_intr, + &hf_opa_KDETH_tidctrl, + &hf_opa_KDETH_tid, + &hf_opa_KDETH_offset_mode, + &hf_opa_KDETH_offset, + NULL +}; +static gint hf_opa_KDETH_hcrc = -1; +static gint hf_opa_KDETH_j_key = -1; +static int * const _opa_KDETH_word2[] = { + &hf_opa_KDETH_hcrc, + &hf_opa_KDETH_j_key, + NULL +}; +/* PSM */ +static gint hf_opa_psm = -1; +static gint hf_opa_psm_a = -1; +static gint hf_opa_psm_ackpsn = -1; +static gint hf_opa_psm_flags = -1; +static gint hf_opa_psm_commidx = -1; +static gint hf_opa_psm_flowid = -1; +static gint hf_opa_psm_msglen = -1; +static gint hf_opa_psm_msgseq = -1; +static gint hf_opa_psm_tag = -1; +static gint hf_opa_psm_msgdata = -1; +static gint hf_opa_psm_short_msglen = -1; +static gint hf_opa_psm_paylen = -1; +static gint hf_opa_psm_offset = -1; +static gint hf_opa_psm_sreqidx = -1; +static gint hf_opa_psm_rreqidx = -1; +static gint hf_opa_psm_rdescid = -1; +static gint hf_opa_psm_sdescid = -1; +static gint hf_opa_psm_psn = -1; +static gint hf_opa_psm_hostipv4 = -1; +static gint hf_opa_psm_hostpid = -1; +static gint hf_opa_psm_dlen = -1; +static gint hf_opa_psm_nargs = -1; +static gint hf_opa_psm_hidx = -1; +static gint hf_opa_psm_arg = -1; +static gint hf_opa_psm_payload = -1; +/* TID RDMA */ +static gint hf_opa_TIDRDMA = -1; +static gint hf_opa_TIDRDMA_reserved = -1; +static gint hf_opa_TIDRDMA_TIDFlowPSN_reserved = -1; +static gint hf_opa_TIDRDMA_TIDFlowPSN = -1; +static gint hf_opa_TIDRDMA_TIDFlowQP_reserved = -1; +static gint hf_opa_TIDRDMA_TIDFlowQP = -1; +static gint hf_opa_TIDRDMA_VerbsPSN_reserved = -1; +static gint hf_opa_TIDRDMA_VerbsPSN = -1; +static gint hf_opa_TIDRDMA_VerbsQP_reserved = -1; +static gint hf_opa_TIDRDMA_VerbsQP = -1; + + +/* Custom Functions */ +static void cf_opa_dw_to_b(gchar *buf, guint32 value) +{ + snprintf(buf, ITEM_LABEL_LENGTH, "%u DWORDS (%u Bytes)", value, value * 4); +} + +/* Dissector Declarations */ +static dissector_handle_t opa_9b_handle; +static dissector_handle_t opa_mad_handle; +static dissector_handle_t infiniband_handle; +static dissector_handle_t ipv6_handle; + +static void parse_opa_9B_Header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset, guint8 *lnh_val) +{ + /* 16B - L2 Header */ + proto_item *L2_9B_header_item; + proto_tree *L2_9B_header_tree; + void *src_addr, *dst_addr; + + gint local_offset = *offset; + + col_prepend_fstr(pinfo->cinfo, COL_INFO, "9B: "); + L2_9B_header_item = proto_tree_add_item(tree, hf_opa_9B, tvb, local_offset, 8, ENC_NA); + L2_9B_header_tree = proto_item_add_subtree(L2_9B_header_item, ett_9b); + + proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_service_channel, tvb, local_offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_link_version, tvb, local_offset, 1, ENC_BIG_ENDIAN); + local_offset += 1; + proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_service_level, tvb, local_offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_reserved2, tvb, local_offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_lnh, tvb, local_offset, 1, ENC_BIG_ENDIAN); + + /* Save Link Next Header... This tells us what the next header is. */ + *lnh_val = tvb_get_guint8(tvb, local_offset); + *lnh_val &= 0x03; + local_offset += 1; + + proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_dlid, tvb, local_offset, 2, ENC_BIG_ENDIAN); + + /* Set destination in packet view. */ + dst_addr = wmem_alloc(pinfo->pool, sizeof(guint16)); + *((guint16 *)dst_addr) = tvb_get_ntohs(tvb, local_offset); + set_address(&pinfo->dst, AT_IB, sizeof(guint16), dst_addr); + local_offset += 2; + + proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_reserved3, tvb, local_offset, 1, ENC_BIG_ENDIAN); + + proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_packet_length, tvb, local_offset, 2, ENC_BIG_ENDIAN); + local_offset += 2; + proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_slid, tvb, local_offset, 2, ENC_BIG_ENDIAN); + + /* Set Source in packet view. */ + src_addr = wmem_alloc(pinfo->pool, sizeof(guint16)); + *((guint16 *)src_addr) = tvb_get_ntohs(tvb, local_offset); + set_address(&pinfo->src, AT_IB, sizeof(guint16), src_addr); + local_offset += 2; + + *offset = local_offset; +} + +static void parse_opa_grh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset, guint8 *nextHdr) +{ + proto_item *global_route_header_item; + proto_tree *global_route_header_tree; + + gint local_offset = *offset; + + col_append_fstr(pinfo->cinfo, COL_INFO, "GRH: "); + global_route_header_item = proto_tree_add_item(tree, hf_opa_grh, tvb, local_offset, 40, ENC_NA); + global_route_header_tree = proto_item_add_subtree(global_route_header_item, ett_grh); + + proto_tree_add_item(global_route_header_tree, hf_opa_grh_ip_version, tvb, local_offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(global_route_header_tree, hf_opa_grh_traffic_class, tvb, local_offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(global_route_header_tree, hf_opa_grh_flow_label, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + + proto_tree_add_item(global_route_header_tree, hf_opa_grh_payload_length, tvb, local_offset, 2, ENC_BIG_ENDIAN); + local_offset += 2; + + *nextHdr = tvb_get_guint8(tvb, local_offset); + + proto_tree_add_item(global_route_header_tree, hf_opa_grh_next_header, tvb, local_offset, 1, ENC_BIG_ENDIAN); + local_offset += 1; + proto_tree_add_item(global_route_header_tree, hf_opa_grh_hop_limit, tvb, local_offset, 1, ENC_BIG_ENDIAN); + local_offset += 1; + proto_tree_add_item(global_route_header_tree, hf_opa_grh_source_gid, tvb, local_offset, 16, ENC_NA); + + /* set source GID in packet view*/ + set_address_tvb(&pinfo->src, AT_IB, 16, tvb, local_offset); + local_offset += 16; + + proto_tree_add_item(global_route_header_tree, hf_opa_grh_destination_gid, tvb, local_offset, 16, ENC_NA); + + /* set destination GID in packet view*/ + set_address_tvb(&pinfo->dst, AT_IB, 16, tvb, local_offset); + local_offset += 16; + + *offset = local_offset; +} + +static void parse_opa_bth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset, guint8 *opCode) +{ + proto_item *base_transport_header_item; + proto_tree *base_transport_header_tree; + + gint local_offset = *offset; + + col_append_fstr(pinfo->cinfo, COL_INFO, "BTH: "); + base_transport_header_item = proto_tree_add_item(tree, hf_opa_bth, tvb, local_offset, 12, ENC_NA); + base_transport_header_tree = proto_item_add_subtree(base_transport_header_item, ett_bth); + + proto_tree_add_item(base_transport_header_tree, hf_opa_bth_opcode, tvb, local_offset, 1, ENC_LITTLE_ENDIAN); + *opCode = tvb_get_guint8(tvb, local_offset); + col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str((guint32)(*opCode), vals_opa_bth_opcode, "Unknown OpCode (0x%0x)")); + local_offset += 1; + + proto_tree_add_item(base_transport_header_tree, hf_opa_bth_solicited_event, tvb, local_offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(base_transport_header_tree, hf_opa_bth_migreq, tvb, local_offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(base_transport_header_tree, hf_opa_bth_pad_count, tvb, local_offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(base_transport_header_tree, hf_opa_bth_transport_header_version, tvb, local_offset, 1, ENC_BIG_ENDIAN); + + local_offset += 1; + proto_tree_add_item(base_transport_header_tree, hf_opa_bth_partition_key, tvb, local_offset, 2, ENC_BIG_ENDIAN); + + local_offset += 2; + proto_tree_add_item(base_transport_header_tree, hf_opa_bth_fcn, tvb, local_offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(base_transport_header_tree, hf_opa_bth_bcn, tvb, local_offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(base_transport_header_tree, hf_opa_bth_Reserved8a, tvb, local_offset, 1, ENC_BIG_ENDIAN); + local_offset += 1; + proto_tree_add_item(base_transport_header_tree, hf_opa_bth_destination_qp, tvb, local_offset, 3, ENC_BIG_ENDIAN); + pinfo->destport = tvb_get_ntoh24(tvb, local_offset); local_offset += 3; + proto_tree_add_item(base_transport_header_tree, hf_opa_bth_acknowledge_request, tvb, local_offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(base_transport_header_tree, hf_opa_bth_packet_sequence_number, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + + *offset = local_offset; +} +static gboolean contains(guint32 OpCode, guint32 *Codes, gint32 length) +{ + gint32 i; + for (i = 0; i < length; i++) { + if ((OpCode ^ Codes[i]) == 0) + return TRUE; + } + return FALSE; +} +static gint32 find_next_header_sequence(guint32 OpCode) +{ + if (contains(OpCode, &opCode_PAYLD[0], (gint32)array_length(opCode_PAYLD))) + return PAYLD; + + if (contains(OpCode, &opCode_IMMDT_PAYLD[0], (gint32)array_length(opCode_IMMDT_PAYLD))) + return IMMDT_PAYLD; + + if (contains(OpCode, &opCode_RDETH_DETH_PAYLD[0], (gint32)array_length(opCode_RDETH_DETH_PAYLD))) + return RDETH_DETH_PAYLD; + + if (contains(OpCode, &opCode_RETH_PAYLD[0], (gint32)array_length(opCode_RETH_PAYLD))) + return RETH_PAYLD; + + if (contains(OpCode, &opCode_RDETH_AETH_PAYLD[0], (gint32)array_length(opCode_RDETH_AETH_PAYLD))) + return RDETH_AETH_PAYLD; + + if (contains(OpCode, &opCode_AETH_PAYLD[0], (gint32)array_length(opCode_AETH_PAYLD))) + return AETH_PAYLD; + + if (contains(OpCode, &opCode_RDETH_DETH_IMMDT_PAYLD[0], (gint32)array_length(opCode_RDETH_DETH_IMMDT_PAYLD))) + return RDETH_DETH_IMMDT_PAYLD; + + if (contains(OpCode, &opCode_RETH_IMMDT_PAYLD[0], (gint32)array_length(opCode_RETH_IMMDT_PAYLD))) + return RETH_IMMDT_PAYLD; + + if (contains(OpCode, &opCode_RDETH_DETH_RETH_PAYLD[0], (gint32)array_length(opCode_RDETH_DETH_RETH_PAYLD))) + return RDETH_DETH_RETH_PAYLD; + + if (contains(OpCode, &opCode_ATOMICETH[0], (gint32)array_length(opCode_ATOMICETH))) + return ATOMICETH; + + if (contains(OpCode, &opCode_IETH_PAYLD[0], (gint32)array_length(opCode_IETH_PAYLD))) + return IETH_PAYLD; + + if (contains(OpCode, &opCode_RDETH_DETH_ATOMICETH[0], (gint32)array_length(opCode_RDETH_DETH_ATOMICETH))) + return RDETH_DETH_ATOMICETH; + + if (contains(OpCode, &opCode_PSM[0], (gint32)array_length(opCode_PSM))) + return KDETH_PSM; + + if (contains(OpCode, &opCode_TIDRDMA[0], (gint32)array_length(opCode_TIDRDMA))) + return KDETH_TIDRDMA; + + if ((OpCode ^ RC_ACKNOWLEDGE) == 0) + return AETH; + + if ((OpCode ^ RC_RDMA_READ_REQUEST) == 0) + return RETH; + + if ((OpCode ^ RC_ATOMIC_ACKNOWLEDGE) == 0) + return AETH_ATOMICACKETH; + + if ((OpCode ^ RD_RDMA_READ_RESPONSE_MIDDLE) == 0) + return RDETH_PAYLD; + + if ((OpCode ^ RD_ACKNOWLEDGE) == 0) + return RDETH_AETH; + + if ((OpCode ^ RD_ATOMIC_ACKNOWLEDGE) == 0) + return RDETH_AETH_ATOMICACKETH; + + if ((OpCode ^ RD_RDMA_WRITE_ONLY_IMM) == 0) + return RDETH_DETH_RETH_IMMDT_PAYLD; + + if ((OpCode ^ RD_RDMA_READ_REQUEST) == 0) + return RDETH_DETH_RETH; + + if ((OpCode ^ RD_RESYNC) == 0) + return RDETH_DETH; + + if ((OpCode ^ UD_SEND_ONLY) == 0) + return DETH_PAYLD; + + if ((OpCode ^ UD_SEND_ONLY_IMM) == 0) + return DETH_IMMDT_PAYLD; + + return -1; +} + +/* Parse RDETH - Reliable Datagram Extended Transport Header */ +static void parse_RDETH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset) +{ + gint local_offset = *offset; + /* RDETH - Reliable Datagram Extended Transport Header */ + proto_item *RDETH_header_item; + proto_tree *RDETH_header_tree; + + col_append_fstr(pinfo->cinfo, COL_INFO, "RDETH: "); + RDETH_header_item = proto_tree_add_item(tree, hf_opa_RDETH, tvb, local_offset, 4, ENC_NA); + RDETH_header_tree = proto_item_add_subtree(RDETH_header_item, ett_rdeth); + + proto_tree_add_item(RDETH_header_tree, hf_opa_RDETH_reserved8, tvb, local_offset, 1, ENC_BIG_ENDIAN); + local_offset += 1; + proto_tree_add_item(RDETH_header_tree, hf_opa_RDETH_ee_context, tvb, local_offset, 3, ENC_BIG_ENDIAN); + local_offset += 3; + *offset = local_offset; +} +/* Parse DETH - Datagram Extended Transport Header */ +static void parse_DETH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset) +{ + gint local_offset = *offset; + /* DETH - Datagram Extended Transport Header */ + proto_item *DETH_header_item; + proto_tree *DETH_header_tree; + + col_append_fstr(pinfo->cinfo, COL_INFO, "DETH: "); + DETH_header_item = proto_tree_add_item(tree, hf_opa_DETH, tvb, local_offset, 8, ENC_NA); + DETH_header_tree = proto_item_add_subtree(DETH_header_item, ett_deth); + + proto_tree_add_item(DETH_header_tree, hf_opa_DETH_queue_key, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + proto_tree_add_item(DETH_header_tree, hf_opa_DETH_reserved8, tvb, local_offset, 1, ENC_BIG_ENDIAN); + local_offset += 1; + proto_tree_add_item(DETH_header_tree, hf_opa_DETH_source_qp, tvb, local_offset, 3, ENC_BIG_ENDIAN); + pinfo->srcport = tvb_get_ntoh24(tvb, local_offset); local_offset += 3; + + *offset = local_offset; +} +/* Parse RETH - RDMA Extended Transport Header */ +static void parse_RETH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset) +{ + gint local_offset = *offset; + /* RETH - RDMA Extended Transport Header */ + proto_item *RETH_header_item; + proto_tree *RETH_header_tree; + + col_append_fstr(pinfo->cinfo, COL_INFO, "RETH: "); + RETH_header_item = proto_tree_add_item(tree, hf_opa_RETH, tvb, local_offset, 16, ENC_NA); + RETH_header_tree = proto_item_add_subtree(RETH_header_item, ett_reth); + + proto_tree_add_item(RETH_header_tree, hf_opa_RETH_virtual_address, tvb, local_offset, 8, ENC_BIG_ENDIAN); + local_offset += 8; + proto_tree_add_item(RETH_header_tree, hf_opa_RETH_remote_key, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + proto_tree_add_item(RETH_header_tree, hf_opa_RETH_dma_length, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + + *offset = local_offset; +} +/* Parse AtomicETH - Atomic Extended Transport Header */ +static void parse_ATOMICETH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset) +{ + gint local_offset = *offset; + /* AtomicETH - Atomic Extended Transport Header */ + proto_item *ATOMICETH_header_item; + proto_tree *ATOMICETH_header_tree; + + col_append_fstr(pinfo->cinfo, COL_INFO, "AtomicETH: "); + ATOMICETH_header_item = proto_tree_add_item(tree, hf_opa_AtomicETH, tvb, local_offset, 28, ENC_NA); + ATOMICETH_header_tree = proto_item_add_subtree(ATOMICETH_header_item, ett_atomiceth); + + proto_tree_add_item(ATOMICETH_header_tree, hf_opa_AtomicETH_virtual_address, tvb, local_offset, 8, ENC_BIG_ENDIAN); + local_offset += 8; + proto_tree_add_item(ATOMICETH_header_tree, hf_opa_AtomicETH_remote_key, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + proto_tree_add_item(ATOMICETH_header_tree, hf_opa_AtomicETH_swap_or_add_data, tvb, local_offset, 8, ENC_BIG_ENDIAN); + local_offset += 8; + proto_tree_add_item(ATOMICETH_header_tree, hf_opa_AtomicETH_compare_data, tvb, local_offset, 8, ENC_BIG_ENDIAN); + local_offset += 8; + *offset = local_offset; +} +/* Parse AETH - ACK Extended Transport Header */ +static void parse_AETH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset) +{ + gint local_offset = *offset; + /* AETH - ACK Extended Transport Header */ + proto_item *AETH_header_item; + proto_tree *AETH_header_tree; + + col_append_fstr(pinfo->cinfo, COL_INFO, "AETH: "); + AETH_header_item = proto_tree_add_item(tree, hf_opa_AETH, tvb, local_offset, 4, ENC_NA); + AETH_header_tree = proto_item_add_subtree(AETH_header_item, ett_aeth); + + proto_tree_add_item(AETH_header_tree, hf_opa_AETH_syndrome, tvb, local_offset, 1, ENC_BIG_ENDIAN); + local_offset += 1; + proto_tree_add_item(AETH_header_tree, hf_opa_AETH_message_sequence_number, tvb, local_offset, 3, ENC_BIG_ENDIAN); + local_offset += 3; + + *offset = local_offset; +} +/* Parse AtomicAckEth - Atomic ACK Extended Transport Header */ +static void parse_ATOMICACKETH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset) +{ + gint local_offset = *offset; + /* AtomicAckEth - Atomic ACK Extended Transport Header */ + proto_item *ATOMICACKETH_header_item; + proto_tree *ATOMICACKETH_header_tree; + + col_append_fstr(pinfo->cinfo, COL_INFO, "AtomicACKETH: "); + ATOMICACKETH_header_item = proto_tree_add_item(tree, hf_opa_AtomicAckETH, tvb, local_offset, 8, ENC_NA); + ATOMICACKETH_header_tree = proto_item_add_subtree(ATOMICACKETH_header_item, ett_atomicacketh); + proto_tree_add_item(ATOMICACKETH_header_tree, hf_opa_AtomicAckETH_original_remote_data, tvb, local_offset, 8, ENC_BIG_ENDIAN); + local_offset += 8; + *offset = local_offset; +} +/* Parse IMMDT - Immediate Data Extended Transport Header */ +static void parse_IMMDT(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset) +{ + gint local_offset = *offset; + /* IMMDT - Immediate Data Extended Transport Header */ + proto_item *IMMDT_header_item; + proto_tree *IMMDT_header_tree; + + col_append_fstr(pinfo->cinfo, COL_INFO, "IMMDT: "); + IMMDT_header_item = proto_tree_add_item(tree, hf_opa_IMMDT, tvb, local_offset, 4, ENC_NA); + IMMDT_header_tree = proto_item_add_subtree(IMMDT_header_item, ett_immdt); + proto_tree_add_item(IMMDT_header_tree, hf_opa_IMMDT_data, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + *offset = local_offset; +} +/* Parse IETH - Invalidate Extended Transport Header */ +static void parse_IETH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset) +{ + gint local_offset = *offset; + /* IETH - Invalidate Extended Transport Header */ + proto_item *IETH_header_item; + proto_tree *IETH_header_tree; + + col_append_fstr(pinfo->cinfo, COL_INFO, "IETH: "); + IETH_header_item = proto_tree_add_item(tree, hf_opa_IETH, tvb, local_offset, 4, ENC_NA); + IETH_header_tree = proto_item_add_subtree(IETH_header_item, ett_ieth); + + proto_tree_add_item(IETH_header_tree, hf_opa_IETH_r_key, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + + *offset = local_offset; +} +/* Parse KDETH - Key Datagram Extended Transport Header */ +static void parse_KDETH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset) +{ + gint local_offset = *offset; + /* KDETH - Key Datagram Extended Transport Header */ + proto_item *KDETH_header_item; + proto_tree *KDETH_header_tree; + + col_append_fstr(pinfo->cinfo, COL_INFO, "KDETH: "); + KDETH_header_item = proto_tree_add_item(tree, hf_opa_KDETH, tvb, local_offset, 8, ENC_NA); + KDETH_header_tree = proto_item_add_subtree(KDETH_header_item, ett_kdeth); + + proto_tree_add_bitmask_list(KDETH_header_tree, tvb, local_offset, 4, _opa_KDETH_word1, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_bitmask_list(KDETH_header_tree, tvb, local_offset, 4, _opa_KDETH_word2, ENC_LITTLE_ENDIAN); + local_offset += 4; + + *offset = local_offset; +} + +/* Parse PSM header */ +static void parse_PSM(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset, gint opCode) +{ + gint local_offset = *offset; + /* PSM Header */ + proto_item *PSM_header_item; + proto_tree *PSM_header_tree; + guint32 payLength; + + col_append_fstr(pinfo->cinfo, COL_INFO, "PSM: "); + PSM_header_item = proto_tree_add_item(tree, hf_opa_psm, tvb, local_offset, 28, ENC_NA); + PSM_header_tree = proto_item_add_subtree(PSM_header_item, ett_psm); + + proto_tree_add_item(PSM_header_tree, hf_opa_psm_a, tvb, local_offset + 3, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(PSM_header_tree, hf_opa_psm_ackpsn, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_flags, tvb, local_offset + 3, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(PSM_header_tree, hf_opa_psm_commidx, tvb, local_offset, 3, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_flowid, tvb, local_offset + 3, 1, ENC_LITTLE_ENDIAN); + + switch (opCode) { + case PSM_TINY: + proto_tree_add_item(PSM_header_tree, hf_opa_psm_msglen, tvb, local_offset + 2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(PSM_header_tree, hf_opa_psm_msgseq, tvb, local_offset, 2, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_tag, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_msgdata, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + break; + case PSM_SHORT: + proto_tree_add_item(PSM_header_tree, hf_opa_psm_msgseq, tvb, local_offset, 2, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_tag, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_msglen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + payLength = tvb_get_letohl(tvb, local_offset); + local_offset += 8; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_payload, tvb, local_offset, payLength, ENC_NA); + local_offset += payLength; + break; + case PSM_MEDIUM: + proto_tree_add_item(PSM_header_tree, hf_opa_psm_msgseq, tvb, local_offset, 2, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_tag, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_msglen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_paylen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 4; + break; + case PSM_MEDIUM_DATA: + proto_tree_add_item(PSM_header_tree, hf_opa_psm_msgseq, tvb, local_offset, 2, ENC_LITTLE_ENDIAN); + local_offset += 4; + local_offset += 8; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_offset, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_paylen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 4; + break; + case PSM_LONG_RTS: + proto_tree_add_item(PSM_header_tree, hf_opa_psm_msgseq, tvb, local_offset, 2, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_tag, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_msglen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_sreqidx, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 4; + break; + case PSM_LONG_CTS: + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_sreqidx, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_rreqidx, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_msglen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 8; + break; + case PSM_LONG_DATA: + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_rreqidx, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_offset, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_paylen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 8; + break; + case PSM_TIDS_GRANT: + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_sreqidx, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_short_msglen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_paylen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 8; + break; + case PSM_TIDS_GRANT_ACK: + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_rdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + local_offset += 8; + break; + case PSM_TIDS_RELEASE: + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_rdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_sdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + break; + case PSM_TIDS_RELEASE_CONFIRM: + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_sdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + local_offset += 8; + break; + case PSM_EXPTID_UNALIGNED: + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_rdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + local_offset += 8; + break; + case PSM_EXPTID: + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_rdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_sdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + break; + case PSM_ACK: + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_sdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + local_offset += 8; + break; + case PSM_NAK: + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_sdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_psn, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 8; + break; + case PSM_ERR_CHK: + case PSM_ERR_CHK_BAD: + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_hostipv4, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_hostpid, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 12; + break; + case PSM_ERR_CHK_GEN: + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_rdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_sdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + break; + case PSM_FLOW_CCA_BECN: + break; + case PSM_CONNECT_REQUEST: + case PSM_CONNECT_REPLY: + case PSM_DISCONNECT_REQUEST: + case PSM_DISCONNECT_REPLY: + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_paylen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN); + local_offset += 16; + break; + case PSM_AM_REQUEST_NOREPLY: + case PSM_AM_REQUEST: + case PSM_AM_REPLY: + proto_tree_add_item(PSM_header_tree, hf_opa_psm_dlen, tvb, local_offset + 3, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(PSM_header_tree, hf_opa_psm_nargs, tvb, local_offset + 3, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(PSM_header_tree, hf_opa_psm_hidx, tvb, local_offset + 2, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(PSM_header_tree, hf_opa_psm_msgseq, tvb, local_offset, 2, ENC_LITTLE_ENDIAN); + local_offset += 4; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_arg, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + proto_tree_add_item(PSM_header_tree, hf_opa_psm_arg, tvb, local_offset, 8, ENC_LITTLE_ENDIAN); + local_offset += 8; + break; + } + *offset = local_offset; +} +static void parse_TIDRDMA(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset, gint opCode, gboolean *parsePayload) +{ + gint local_offset = *offset; + proto_item *TIDRDMA_header_item; + proto_tree *TIDRDMA_header_tree; + + switch (opCode) { + case TID_RDMA_WRITE_REQUEST: + parse_RETH(tvb, pinfo, tree, &local_offset); + col_append_fstr(pinfo->cinfo, COL_INFO, "TID RDMA Write Request: "); + TIDRDMA_header_item = proto_tree_add_item(tree, hf_opa_TIDRDMA, tvb, local_offset, 12, ENC_NA); + proto_item_set_text(TIDRDMA_header_item, "TID RDMA Write Request Header"); + TIDRDMA_header_tree = proto_item_add_subtree(TIDRDMA_header_item, ett_tidrdma); + + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_reserved, tvb, local_offset, 8, ENC_NA); + local_offset += 8; + + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + + *parsePayload = FALSE; + break; + case TID_RDMA_WRITE_RESPONSE: + parse_AETH(tvb, pinfo, tree, &local_offset); + col_append_fstr(pinfo->cinfo, COL_INFO, "TID RDMA Write Response: "); + TIDRDMA_header_item = proto_tree_add_item(tree, hf_opa_TIDRDMA, tvb, local_offset, 24, ENC_NA); + proto_item_set_text(TIDRDMA_header_item, "TID RDMA Write Response Header"); + TIDRDMA_header_tree = proto_item_add_subtree(TIDRDMA_header_item, ett_tidrdma); + + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_reserved, tvb, local_offset, 12, ENC_NA); + local_offset += 12; + + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowPSN_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowPSN, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowQP, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + + *parsePayload = FALSE; + break; + case TID_RDMA_WRITE_DATA: + col_append_fstr(pinfo->cinfo, COL_INFO, "TID RDMA Write Data: "); + TIDRDMA_header_item = proto_tree_add_item(tree, hf_opa_TIDRDMA, tvb, local_offset, 28, ENC_NA); + proto_item_set_text(TIDRDMA_header_item, "TID RDMA Write Data Header"); + TIDRDMA_header_tree = proto_item_add_subtree(TIDRDMA_header_item, ett_tidrdma); + + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_reserved, tvb, local_offset, 24, ENC_NA); + local_offset += 24; + + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + + *parsePayload = TRUE; + break; + case TID_RDMA_WRITE_DATA_LAST: + col_append_fstr(pinfo->cinfo, COL_INFO, "TID RDMA Write Data Last: "); + TIDRDMA_header_item = proto_tree_add_item(tree, hf_opa_TIDRDMA, tvb, local_offset, 28, ENC_NA); + proto_item_set_text(TIDRDMA_header_item, "TID RDMA Write Data Last Header"); + TIDRDMA_header_tree = proto_item_add_subtree(TIDRDMA_header_item, ett_tidrdma); + + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_reserved, tvb, local_offset, 24, ENC_NA); + local_offset += 24; + + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + + *parsePayload = TRUE; + break; + case TID_RDMA_READ_REQUEST: + parse_RETH(tvb, pinfo, tree, &local_offset); + col_append_fstr(pinfo->cinfo, COL_INFO, "TID RDMA Read Request: "); + TIDRDMA_header_item = proto_tree_add_item(tree, hf_opa_TIDRDMA, tvb, local_offset, 12, ENC_NA); + proto_item_set_text(TIDRDMA_header_item, "TID RDMA Read Request Header"); + TIDRDMA_header_tree = proto_item_add_subtree(TIDRDMA_header_item, ett_tidrdma); + + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowPSN_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowPSN, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowQP, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + + *parsePayload = FALSE; + break; + case TID_RDMA_READ_RESPONSE: + parse_AETH(tvb, pinfo, tree, &local_offset); + col_append_fstr(pinfo->cinfo, COL_INFO, "TID RDMA Read Response: "); + TIDRDMA_header_item = proto_tree_add_item(tree, hf_opa_TIDRDMA, tvb, local_offset, 24, ENC_NA); + proto_item_set_text(TIDRDMA_header_item, "TID RDMA Read Response Header"); + TIDRDMA_header_tree = proto_item_add_subtree(TIDRDMA_header_item, ett_tidrdma); + + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_reserved, tvb, local_offset, 16, ENC_NA); + local_offset += 16; + + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsPSN_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsPSN, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + + *parsePayload = TRUE; + break; + case TID_RDMA_RESYNC: + col_append_fstr(pinfo->cinfo, COL_INFO, "TID RDMA Read ReSync: "); + TIDRDMA_header_item = proto_tree_add_item(tree, hf_opa_TIDRDMA, tvb, local_offset, 28, ENC_NA); + proto_item_set_text(TIDRDMA_header_item, "TID RDMA Read ReSync Header"); + TIDRDMA_header_tree = proto_item_add_subtree(TIDRDMA_header_item, ett_tidrdma); + + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_reserved, tvb, local_offset, 24, ENC_NA); + local_offset += 24; + + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + + *parsePayload = FALSE; + break; + case TID_RDMA_ACK: + parse_AETH(tvb, pinfo, tree, &local_offset); + col_append_fstr(pinfo->cinfo, COL_INFO, "TID RDMA ACK: "); + TIDRDMA_header_item = proto_tree_add_item(tree, hf_opa_TIDRDMA, tvb, local_offset, 24, ENC_NA); + proto_item_set_text(TIDRDMA_header_item, "TID RDMA ACK Header"); + TIDRDMA_header_tree = proto_item_add_subtree(TIDRDMA_header_item, ett_tidrdma); + + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_reserved, tvb, local_offset, 8, ENC_NA); + local_offset += 8; + + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowPSN_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowPSN, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsPSN_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsPSN, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowQP, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP, tvb, local_offset, 4, ENC_BIG_ENDIAN); + local_offset += 4; + + *parsePayload = FALSE; + break; + default: + *parsePayload = FALSE; + } + *offset = local_offset; +} +static void parse_IPvSix(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset) +{ + call_dissector(ipv6_handle, tvb_new_subset_remaining(tvb, *offset), pinfo, tree); + *offset = tvb_reported_length(tvb); +} + +static int dissect_opa_9b(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) +{ + proto_item *opa_packet; + + /* TVB to pass to opa header */ + tvbuff_t *opa_tvb; + /* TVB to pass to infiniband header */ + tvbuff_t *infiniband_tvb; + + gint offset = 0; /* Current Offset */ + gint ib_offset = 0; /* Offset to track if IB packet */ + gint captured_length, reported_length; + guint8 lnh_val = 0; + gboolean bthFollows = FALSE; + gboolean parsePayload = FALSE; + gint32 nextHeaderSequence = -1; + guint8 nextHdr = 0, opCode = 0; + guint8 baseVersion = 0; + + /* Infiniband Check */ + lnh_val = tvb_get_guint8(tvb, ib_offset + 1) & 0x3; + if (lnh_val == 3) { + nextHdr = tvb_get_guint8(tvb, ib_offset + 6); + ib_offset += 40; + } + if (lnh_val == 2 || nextHdr == 0x1B) { + opCode = tvb_get_guint8(tvb, ib_offset + 8); + if (opCode == 0x64) { + baseVersion = tvb_get_guint8(tvb, ib_offset + 28); + if (baseVersion == 0x01) { + infiniband_tvb = tvb_new_subset_remaining(tvb, offset); + call_dissector(infiniband_handle, infiniband_tvb, pinfo, tree); + return tvb_captured_length(tvb); + } + } + } + + tree = proto_tree_get_parent_tree(tree); + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "Omni-Path"); + col_clear(pinfo->cinfo, COL_INFO); + + pinfo->srcport = pinfo->destport = 0xffffffff; + + opa_packet = proto_tree_add_item(tree, proto_opa_9b, tvb, offset, -1, ENC_NA); + + /* Headers Level Tree */ + tree = proto_item_add_subtree(opa_packet, ett_all_headers); + parse_opa_9B_Header(tvb, pinfo, tree, &offset, &lnh_val); + + switch (lnh_val) { + case 3: /* GLOBAL - GRH - Global Route Header */ + parse_opa_grh(tvb, pinfo, tree, &offset, &nextHdr); + if (nextHdr != 0x1B) { /* no BTH following. */ + break; + } + /* FALL THROUGH */ + case 2: /* LOCAL - BTH - Base Transport Header */ + parse_opa_bth(tvb, pinfo, tree, &offset, &opCode); + bthFollows = TRUE; + break; + case 1: /* NON OPA - IPv6 Packet */ + set_address(&pinfo->dst, AT_STRINGZ, (int)strlen("IPv6 over OPA Packet") + 1, + wmem_strdup(pinfo->pool, "IPv6 over OPA Packet")); + + parse_IPvSix(tvb, pinfo, tree, &offset); + + break; + case 0: /* RAW */ + + break; + default: + break; + } + + if (bthFollows) { + /* Save transport type for identifying EoOPA payloads later */ + nextHeaderSequence = find_next_header_sequence((guint32)opCode); + switch (nextHeaderSequence) { + case RDETH_DETH_PAYLD: + parse_RDETH(tvb, pinfo, tree, &offset); + parse_DETH(tvb, pinfo, tree, &offset); + + parsePayload = TRUE; + break; + case RDETH_DETH_RETH_PAYLD: + parse_RDETH(tvb, pinfo, tree, &offset); + parse_DETH(tvb, pinfo, tree, &offset); + parse_RETH(tvb, pinfo, tree, &offset); + + parsePayload = TRUE; + break; + case RDETH_DETH_IMMDT_PAYLD: + parse_RDETH(tvb, pinfo, tree, &offset); + parse_DETH(tvb, pinfo, tree, &offset); + parse_IMMDT(tvb, pinfo, tree, &offset); + + parsePayload = TRUE; + break; + case RDETH_DETH_RETH_IMMDT_PAYLD: + parse_RDETH(tvb, pinfo, tree, &offset); + parse_DETH(tvb, pinfo, tree, &offset); + parse_RETH(tvb, pinfo, tree, &offset); + parse_IMMDT(tvb, pinfo, tree, &offset); + + parsePayload = TRUE; + break; + case RDETH_DETH_RETH: + parse_RDETH(tvb, pinfo, tree, &offset); + parse_DETH(tvb, pinfo, tree, &offset); + parse_RETH(tvb, pinfo, tree, &offset); + + break; + case RDETH_AETH_PAYLD: + parse_RDETH(tvb, pinfo, tree, &offset); + parse_AETH(tvb, pinfo, tree, &offset); + + parsePayload = TRUE; + break; + case RDETH_PAYLD: + parse_RDETH(tvb, pinfo, tree, &offset); + + parsePayload = TRUE; + break; + case RDETH_AETH: + parse_AETH(tvb, pinfo, tree, &offset); + + break; + case RDETH_AETH_ATOMICACKETH: + parse_RDETH(tvb, pinfo, tree, &offset); + parse_AETH(tvb, pinfo, tree, &offset); + parse_ATOMICACKETH(tvb, pinfo, tree, &offset); + + break; + case RDETH_DETH_ATOMICETH: + parse_RDETH(tvb, pinfo, tree, &offset); + parse_DETH(tvb, pinfo, tree, &offset); + parse_ATOMICETH(tvb, pinfo, tree, &offset); + + break; + case RDETH_DETH: + parse_RDETH(tvb, pinfo, tree, &offset); + parse_DETH(tvb, pinfo, tree, &offset); + + break; + case DETH_PAYLD: + parse_DETH(tvb, pinfo, tree, &offset); + + parsePayload = TRUE; + break; + case PAYLD: + + parsePayload = TRUE; + break; + case IMMDT_PAYLD: + parse_IMMDT(tvb, pinfo, tree, &offset); + + parsePayload = TRUE; + break; + case RETH_PAYLD: + parse_RETH(tvb, pinfo, tree, &offset); + + parsePayload = TRUE; + break; + case RETH: + parse_RETH(tvb, pinfo, tree, &offset); + + break; + case AETH_PAYLD: + parse_AETH(tvb, pinfo, tree, &offset); + + parsePayload = TRUE; + break; + case AETH: + parse_AETH(tvb, pinfo, tree, &offset); + + break; + case AETH_ATOMICACKETH: + parse_AETH(tvb, pinfo, tree, &offset); + parse_ATOMICACKETH(tvb, pinfo, tree, &offset); + + break; + case ATOMICETH: + parse_ATOMICETH(tvb, pinfo, tree, &offset); + + break; + case IETH_PAYLD: + parse_IETH(tvb, pinfo, tree, &offset); + + parsePayload = TRUE; + break; + case DETH_IMMDT_PAYLD: + parse_DETH(tvb, pinfo, tree, &offset); + parse_IMMDT(tvb, pinfo, tree, &offset); + + parsePayload = TRUE; + break; + case KDETH_PSM: + parse_KDETH(tvb, pinfo, tree, &offset); + parse_PSM(tvb, pinfo, tree, &offset, opCode); + + break; + case KDETH_TIDRDMA: + parse_KDETH(tvb, pinfo, tree, &offset); + parse_TIDRDMA(tvb, pinfo, tree, &offset, opCode, &parsePayload); + + break; + default: + break; + + } /* END: switch (nextHeaderSequence) */ + + if (parsePayload) { + /* Pass to OPA MAD dissector */ + captured_length = tvb_captured_length_remaining(tvb, offset); + reported_length = tvb_reported_length_remaining(tvb, offset); + + if (reported_length >= 4) + reported_length -= 4; + if (captured_length > reported_length) + captured_length = reported_length; + + if (captured_length > 0) { + opa_tvb = tvb_new_subset_length_caplen(tvb, offset, captured_length, reported_length); + call_dissector(opa_mad_handle, opa_tvb, pinfo, tree); + offset += captured_length; + } + } + } /* END: if(bthFollows) */ + + /* Display the ICRC */ + reported_length = tvb_reported_length_remaining(tvb, offset); + if (reported_length != 4) { + offset += reported_length - 4; + } + proto_tree_add_item(tree, hf_opa_9b_ICRC, tvb, offset, 4, ENC_BIG_ENDIAN); + offset += 4; + return offset; +} +void proto_register_opa_9b(void) +{ + static hf_register_info hf[] = { + /* L2Header(9B) */ + { &hf_opa_9B, { + "Omni-Path 9B Header", "opa.9b", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_9B_service_channel, { + "Service Channel", "opa.9b.sc", + FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL } + }, + { &hf_opa_9B_link_version, { + "Link Version", "opa.9b.linkversion", + FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL } + }, + { &hf_opa_9B_service_level, { + "Service Level", "opa.9b.sl", + FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL } + }, + { &hf_opa_9B_reserved2, { + "Reserved (2 bits)", "opa.9b.reserved2", + FT_UINT8, BASE_HEX, NULL, 0x0C, NULL, HFILL } + }, + { &hf_opa_9B_lnh, { + "Link Next Header", "opa.9b.lnh", + FT_UINT8, BASE_DEC, VALS(vals_opa_9b_lnh), 0x03, NULL, HFILL } + }, + { &hf_opa_9B_dlid, { + "Dest LID", "opa.9b.dlid", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_9B_reserved3, { + "Reserved (4 bits)", "opa.9b.reserved3", + FT_UINT16, BASE_HEX, NULL, 0xF000, NULL, HFILL } + }, + { &hf_opa_9B_packet_length, { + "Packet Length", "opa.length", + FT_UINT16, BASE_CUSTOM, CF_FUNC(cf_opa_dw_to_b), 0x0FFF, NULL, HFILL } + }, + { &hf_opa_9B_slid, { + "Source LID", "opa.9b.slid", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_9b_ICRC, { + "Invariant CRC", "opa.9b.icrc", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + + /* Global Route Header */ + { &hf_opa_grh, { + "GRH - Global Route Header", "opa.grh", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_grh_ip_version, { + "IP Version", "opa.grh.ipver", + FT_UINT8, BASE_DEC, VALS(vals_opa_9b_grh_ipver), 0xF0, NULL, HFILL } + }, + { &hf_opa_grh_traffic_class, { + "Traffic Class", "opa.grh.tclass", + FT_UINT16, BASE_DEC, NULL, 0x0FF0, NULL, HFILL } + }, + { &hf_opa_grh_flow_label, { + "Flow Label", "opa.grh.flowlabel", + FT_UINT32, BASE_DEC, NULL, 0x000FFFFF, NULL, HFILL } + }, + { &hf_opa_grh_payload_length, { + "Payload Length", "opa.grh.paylen", + FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_grh_next_header, { + "Next Header", "opa.grh.nxthdr", + FT_UINT8, BASE_DEC, VALS(vals_opa_9b_grh_next_hdr), 0x0, NULL, HFILL } + }, + { &hf_opa_grh_hop_limit, { + "Hop Limit", "opa.grh.hoplmt", + FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_grh_source_gid, { + "Source GID", "opa.grh.sgid", + FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_grh_destination_gid, { + "Destination GID", "opa.grh.dgid", + FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + + /* Base Transport Header */ + { &hf_opa_bth, { + "BTH - Base Transport Header", "opa.bth", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_bth_opcode, { + "Opcode", "opa.bth.opcode", + FT_UINT8, BASE_HEX, VALS(vals_opa_bth_opcode), 0x0, NULL, HFILL } + }, + { &hf_opa_bth_solicited_event, { + "Solicited Event", "opa.bth.se", + FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80, NULL, HFILL } + }, + { &hf_opa_bth_migreq, { + "MigReq", "opa.bth.m", + FT_BOOLEAN, 8, TFS(&tfs_opa_bth_migrated_notmigrated), 0x40, NULL, HFILL } + }, + { &hf_opa_bth_pad_count, { + "Pad Count", "opa.bth.padcnt", + FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL } + }, + { &hf_opa_bth_transport_header_version, { + "Header Version", "opa.bth.tver", + FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL } + }, + { &hf_opa_bth_partition_key, { + "Partition Key", "opa.bth.p_key", + FT_UINT16, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_bth_fcn, { + "FCN", "opa.bth.fcn", + FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80, NULL, HFILL } + }, + { &hf_opa_bth_bcn, { + "BCN", "opa.bth.bcn", + FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40, NULL, HFILL } + }, + { &hf_opa_bth_Reserved8a, { + "Reserved (6 bits)", "opa.bth.reserved8a", + FT_UINT8, BASE_HEX, NULL, 0x3F, NULL, HFILL } + }, + { &hf_opa_bth_destination_qp, { + "Destination Queue Pair", "opa.bth.destqp", + FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_bth_acknowledge_request, { + "Acknowledge Request", "opa.bth.a", + FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80, NULL, HFILL } + }, + { &hf_opa_bth_packet_sequence_number, { + "Packet Sequence Number", "opa.bth.psn", + FT_UINT32, BASE_DEC, NULL, 0x7FFFFFFF, NULL, HFILL } + }, + + /* Reliable Datagram Extended Transport Header (RDETH) */ + { &hf_opa_RDETH, { + "RDETH - Reliable Datagram Extended Transport Header", "opa.rdeth", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_RDETH_reserved8, { + "Reserved (8 bits)", "opa.rdeth.reserved", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_RDETH_ee_context, { + "EE Context", "opa.rdeth.eecnxt", + FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + + /* Datagram Extended Transport Header (DETH) */ + { &hf_opa_DETH, { + "DETH - Datagram Extended Transport Header", "opa.deth", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_DETH_queue_key, { + "Queue Key", "opa.deth.q_key", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_DETH_reserved8, { + "Reserved (8 bits)", "opa.deth.reserved", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_DETH_source_qp, { + "Source Queue Pair", "opa.deth.srcqp", + FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + + /* RDMA Extended Transport Header (RETH) */ + { &hf_opa_RETH, { + "RETH - RDMA Extended Transport Header", "opa.reth", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_RETH_virtual_address, { + "Virtual Address", "opa.reth.va", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_RETH_remote_key, { + "Remote Key", "opa.reth.r_key", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_RETH_dma_length, { + "DMA Length", "opa.reth.dmalen", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + + /* Atomic Extended Transport Header (AtomicETH) */ + { &hf_opa_AtomicETH, { + "AtomicETH - Atomic Extended Transport Header", "opa.atomiceth", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_AtomicETH_virtual_address, { + "Virtual Address", "opa.atomiceth.va", + FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_AtomicETH_remote_key, { + "Remote Key", "opa.atomiceth.r_key", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_AtomicETH_swap_or_add_data, { + "Swap (Or Add) Data", "opa.atomiceth.swapdt", + FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_AtomicETH_compare_data, { + "Compare Data", "opa.atomiceth.cmpdt", + FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + + /* ACK Extended Transport Header (AETH) */ + { &hf_opa_AETH, { + "AETH - ACK Extended Transport Header", "opa.aeth", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_AETH_syndrome, { + "Syndrome", "opa.aeth.syndrome", + FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_AETH_message_sequence_number, { + "Message Sequence Number", "opa.aeth.msn", + FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + + /* Atomic ACK Extended Transport Header (AtomicAckETH) */ + { &hf_opa_AtomicAckETH, { + "AtomicAckETH - Atomic ACK Extended Transport Header", "opa.atomicacketh", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_AtomicAckETH_original_remote_data, { + "Original Remote Data", "opa.atomicacketh.origremdt", + FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + + /* Immediate Extended Transport Header (ImmDT) */ + { &hf_opa_IMMDT, { + "IMMDT - Immediate Extended Transport Header", "opa.immdt", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_IMMDT_data, { + "Immediate Data", "opa.immdt.data", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + + /* Invalidate Extended Transport Header (IETH) */ + { &hf_opa_IETH, { + "IETH - Invalidate Extended Transport Header", "opa.ieth", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_IETH_r_key, { + "RKey", "opa.ieth.r_key", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + + /* Key Datagram Extended Transport Header (KDETH) */ + { &hf_opa_KDETH, { + "KDETH - Key Datagram Extended Transport Header", "opa.kdeth", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_KDETH_kver, { + "KDETH Version Field", "opa.kdeth.kver", + FT_UINT32, BASE_HEX, NULL, 0xC0000000, NULL, HFILL } + }, + { &hf_opa_KDETH_sh, { + "SuppressHeader", "opa.kdeth.sh", + FT_BOOLEAN, 32, NULL, 0x20000000, NULL, HFILL } + }, + { &hf_opa_KDETH_intr, { + "InterruptBit", "opa.kdeth.intr", + FT_BOOLEAN, 32, NULL, 0x10000000, NULL, HFILL } + }, + { &hf_opa_KDETH_tidctrl, { + "TokenIDCtrl", "opa.kdeth.tidctrl", + FT_UINT32, BASE_HEX, NULL, 0x0C000000, NULL, HFILL } + }, + { &hf_opa_KDETH_tid, { + "TokenID", "opa.kdeth.tid", + FT_UINT32, BASE_HEX, NULL, 0x03FF0000, NULL, HFILL } + }, + { &hf_opa_KDETH_offset_mode, { + "Offset Mode", "opa.kdeth.offsetmode", + FT_BOOLEAN, 32, TFS(&tfs_opa_kdeth_offset_32_64), 0x00008000, NULL, HFILL } + }, + { &hf_opa_KDETH_offset, { + "Offset", "opa.kdeth.offset", + FT_UINT32, BASE_HEX, NULL, 0x00007FFF, NULL, HFILL } + }, + { &hf_opa_KDETH_hcrc, { + "HCRC", "opa.kdeth.hcrc", + FT_UINT32, BASE_HEX, NULL, 0xFFFF0000, NULL, HFILL } + }, + { &hf_opa_KDETH_j_key, { + "J_Key", "opa.kdeth.j_key", + FT_UINT32, BASE_HEX, NULL, 0x0000FFFF, NULL, HFILL } + }, + + /* PSM */ + { &hf_opa_psm, { + "PSM Header", "opa.psm", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_a, { + "ACKFlag", "opa.psm.a", + FT_UINT8, BASE_HEX, NULL, 0x80, NULL, HFILL } + }, + { &hf_opa_psm_ackpsn, { + "ACKPSN", "opa.psm.ackpsn", + FT_UINT32, BASE_DEC, NULL, 0x7FFF, NULL, HFILL } + }, + { &hf_opa_psm_flags, { + "Flags", "opa.psm.flags", + FT_UINT8, BASE_DEC, NULL, 0xFC, NULL, HFILL } + }, + { &hf_opa_psm_commidx, { + "CommIdx", "opa.psm.commidx", + FT_UINT32, BASE_HEX, NULL, 0x3FFF, NULL, HFILL } + }, + { &hf_opa_psm_flowid, { + "FlowId", "opa.psm.flowid", + FT_UINT8, BASE_HEX, NULL, 0x80, NULL, HFILL } + }, + /* PSM opcode specific */ + { &hf_opa_psm_msglen, { + "MsgLen", "opa.psm.msglen", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_msgseq, { + "MsqSeq", "opa.psm.msgseq", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_tag, { + "Tag", "opa.psm.tag", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_msgdata, { + "MsqData", "opa.psm.msgdata", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_short_msglen, { + "MsgLen", "opa.psm.short.msglen", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_paylen, { + "PayLen", "opa.psm.paylen", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_offset, { + "Offset", "opa.psm.offset", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_sreqidx, { + "SreqIdx", "opa.psm.sreqidx", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_rreqidx, { + "RreqIdx", "opa.psm.rreqidx", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_rdescid, { + "RdescId", "opa.psm.rdescid", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_sdescid, { + "SdescId", "opa.psm.sdescid", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_psn, { + "PSN", "opa.psm.psn", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_hostipv4, { + "HostIPv4Addr", "opa.psm.hostipv4", + FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_hostpid, { + "HostPid", "opa.psm.hostpid", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_dlen, { + "Datalength", "opa.psm.dlen", + FT_UINT8, BASE_DEC, NULL, 0x38, NULL, HFILL } + }, + { &hf_opa_psm_nargs, { + "NumberArgs", "opa.psm.nargs", + FT_UINT32, BASE_DEC, NULL, 0x07, NULL, HFILL } + }, + { &hf_opa_psm_hidx, { + "HandlerIndex", "opa.psm.hidx", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_arg, { + "Argument", "opa.psm.arg", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_psm_payload, { + "Payload", "opa.psm.payload", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_TIDRDMA, { + "TID RDMA Header", "opa.tidrdma", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_TIDRDMA_reserved, { + "Reserved", "opa.tidrdma.reserved", + FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } + }, + { &hf_opa_TIDRDMA_TIDFlowPSN_reserved, { + "Reserved (1 bit)", "opa.tidrdma.tidflowpsn.reserved", + FT_UINT32, BASE_HEX, NULL, 0x80000000, NULL, HFILL } + }, + { &hf_opa_TIDRDMA_TIDFlowPSN, { + "TID Flow PSN", "opa.tidrdma.tidflowpsn", + FT_UINT32, BASE_HEX, NULL, 0x7FFFFFFF, NULL, HFILL } + }, + { &hf_opa_TIDRDMA_TIDFlowQP_reserved, { + "Reserved (8 bits)", "opa.tidrdma.tidflowqp.reserved", + FT_UINT32, BASE_HEX, NULL, 0xFF000000, NULL, HFILL } + }, + { &hf_opa_TIDRDMA_TIDFlowQP, { + "TID Flow QP", "opa.tidrdma.tidflowqp", + FT_UINT32, BASE_HEX, NULL, 0x00FFFFFF, NULL, HFILL } + }, + { &hf_opa_TIDRDMA_VerbsPSN_reserved, { + "Reserved (1 bit)", "opa.tidrdma.verbspsn.reserved", + FT_UINT32, BASE_HEX, NULL, 0x80000000, NULL, HFILL } + }, + { &hf_opa_TIDRDMA_VerbsPSN, { + "Verbs PSN", "opa.tidrdma.verbspsn", + FT_UINT32, BASE_HEX, NULL, 0x7FFFFFFF, NULL, HFILL } + }, + { &hf_opa_TIDRDMA_VerbsQP_reserved, { + "Reserved (8 bits)", "opa.tidrdma.verbsqp.reserved", + FT_UINT32, BASE_HEX, NULL, 0xFF000000, NULL, HFILL } + }, + { &hf_opa_TIDRDMA_VerbsQP, { + "Verbs QP", "opa.tidrdma.verbsqp", + FT_UINT32, BASE_HEX, NULL, 0x00FFFFFF, NULL, HFILL } + } + }; + + static gint *ett[] = { + &ett_all_headers, + &ett_9b, + &ett_grh, + &ett_bth, + &ett_rdeth, + &ett_deth, + &ett_reth, + &ett_atomiceth, + &ett_aeth, + &ett_atomicacketh, + &ett_immdt, + &ett_ieth, + &ett_kdeth, + &ett_psm, + &ett_tidrdma + }; + + proto_opa_9b = proto_register_protocol("Intel Omni-Path", "OPA", "opa"); + opa_9b_handle = register_dissector("opa", dissect_opa_9b, proto_opa_9b); + + proto_register_field_array(proto_opa_9b, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +void proto_reg_handoff_opa_9b(void) +{ + ipv6_handle = find_dissector("ipv6"); + opa_mad_handle = find_dissector("opa.mad"); + infiniband_handle = find_dissector("infiniband"); + + /* announce an anonymous Omni-Path 9B dissector */ + dissector_add_uint("erf.types.type", ERF_TYPE_OPA_9B, opa_9b_handle); + +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ |