Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-opa.c
Line
Count
Source
1
/* packet-opa.c
2
 * Routines for Omni-Path 9B L2, L4, and extended L4 header dissection
3
 * Copyright (c) 2016, Intel Corporation.
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
12
#include "config.h"
13
14
#include <epan/packet.h>
15
#include <epan/tfs.h>
16
#include <wsutil/array.h>
17
#include <wiretap/erf_record.h>
18
19
void proto_reg_handoff_opa_9b(void);
20
void proto_register_opa_9b(void);
21
22
/* OpCodeValues
23
 * Code Bits [7-5] Connection Type
24
 *           [4-0] Message Type
25
 * Reliable Connection (RC) [7-5] = 000 */
26
#define RC_SEND_FIRST                    0 /*0x00000000 */
27
#define RC_SEND_MIDDLE                   1 /*0x00000001 */
28
#define RC_SEND_LAST                     2 /*0x00000010 */
29
#define RC_SEND_LAST_IMM                 3 /*0x00000011 */
30
#define RC_SEND_ONLY                     4 /*0x00000100 */
31
#define RC_SEND_ONLY_IMM                 5 /*0x00000101 */
32
#define RC_RDMA_WRITE_FIRST              6 /*0x00000110 */
33
#define RC_RDMA_WRITE_MIDDLE             7 /*0x00000111 */
34
#define RC_RDMA_WRITE_LAST               8 /*0x00001000 */
35
#define RC_RDMA_WRITE_LAST_IMM           9 /*0x00001001 */
36
#define RC_RDMA_WRITE_ONLY              10 /*0x00001010 */
37
#define RC_RDMA_WRITE_ONLY_IMM          11 /*0x00001011 */
38
0
#define RC_RDMA_READ_REQUEST            12 /*0x00001100 */
39
#define RC_RDMA_READ_RESPONSE_FIRST     13 /*0x00001101 */
40
#define RC_RDMA_READ_RESPONSE_MIDDLE    14 /*0x00001110 */
41
#define RC_RDMA_READ_RESPONSE_LAST      15 /*0x00001111 */
42
#define RC_RDMA_READ_RESPONSE_ONLY      16 /*0x00010000 */
43
0
#define RC_ACKNOWLEDGE                  17 /*0x00010001 */
44
0
#define RC_ATOMIC_ACKNOWLEDGE           18 /*0x00010010 */
45
#define RC_CMP_SWAP                     19 /*0x00010011 */
46
#define RC_FETCH_ADD                    20 /*0x00010100 */
47
#define RC_SEND_LAST_INVAL              22 /*0x00010110 */
48
#define RC_SEND_ONLY_INVAL              23 /*0x00010111 */
49
/* Reliable Datagram (RD) [7-5] = 010 */
50
#define RD_SEND_FIRST                   64 /*0x01000000 */
51
#define RD_SEND_MIDDLE                  65 /*0x01000001 */
52
#define RD_SEND_LAST                    66 /*0x01000010 */
53
#define RD_SEND_LAST_IMM                67 /*0x01000011 */
54
#define RD_SEND_ONLY                    68 /*0x01000100 */
55
#define RD_SEND_ONLY_IMM                69 /*0x01000101 */
56
#define RD_RDMA_WRITE_FIRST             70 /*0x01000110 */
57
#define RD_RDMA_WRITE_MIDDLE            71 /*0x01000111 */
58
#define RD_RDMA_WRITE_LAST              72 /*0x01001000 */
59
#define RD_RDMA_WRITE_LAST_IMM          73 /*0x01001001 */
60
#define RD_RDMA_WRITE_ONLY              74 /*0x01001010 */
61
0
#define RD_RDMA_WRITE_ONLY_IMM          75 /*0x01001011 */
62
0
#define RD_RDMA_READ_REQUEST            76 /*0x01001100 */
63
#define RD_RDMA_READ_RESPONSE_FIRST     77 /*0x01001101 */
64
0
#define RD_RDMA_READ_RESPONSE_MIDDLE    78 /*0x01001110 */
65
#define RD_RDMA_READ_RESPONSE_LAST      79 /*0x01001111 */
66
#define RD_RDMA_READ_RESPONSE_ONLY      80 /*0x01010000 */
67
0
#define RD_ACKNOWLEDGE                  81 /*0x01010001 */
68
0
#define RD_ATOMIC_ACKNOWLEDGE           82 /*0x01010010 */
69
#define RD_CMP_SWAP                     83 /*0x01010011 */
70
#define RD_FETCH_ADD                    84 /*0x01010100 */
71
0
#define RD_RESYNC                       85 /*0x01010101 */
72
/* Unreliable Datagram (UD) [7-5] = 011 */
73
0
#define UD_SEND_ONLY                   100 /*0x01100100 */
74
0
#define UD_SEND_ONLY_IMM               101 /*0x01100101 */
75
/* Unreliable Connection (UC) [7-5] = 001 */
76
#define UC_SEND_FIRST                   32 /*0x00100000 */
77
#define UC_SEND_MIDDLE                  33 /*0x00100001 */
78
#define UC_SEND_LAST                    34 /*0x00100010 */
79
#define UC_SEND_LAST_IMM                35 /*0x00100011 */
80
#define UC_SEND_ONLY                    36 /*0x00100100 */
81
#define UC_SEND_ONLY_IMM                37 /*0x00100101 */
82
#define UC_RDMA_WRITE_FIRST             38 /*0x00100110 */
83
#define UC_RDMA_WRITE_MIDDLE            39 /*0x00100111 */
84
#define UC_RDMA_WRITE_LAST              40 /*0x00101000 */
85
#define UC_RDMA_WRITE_LAST_IMM          41 /*0x00101001 */
86
#define UC_RDMA_WRITE_ONLY              42 /*0x00101010 */
87
#define UC_RDMA_WRITE_ONLY_IMM          43 /*0x00101011 */
88
89
/* Header Ordering Based on OPCODES */
90
0
#define RDETH_DETH_PAYLD            0
91
0
#define RDETH_DETH_RETH_PAYLD       1
92
0
#define RDETH_DETH_IMMDT_PAYLD      2
93
0
#define RDETH_DETH_RETH_IMMDT_PAYLD 3
94
0
#define RDETH_DETH_RETH             4
95
0
#define RDETH_AETH_PAYLD            5
96
0
#define RDETH_PAYLD                 6
97
0
#define RDETH_AETH                  7
98
0
#define RDETH_AETH_ATOMICACKETH     8
99
0
#define RDETH_DETH_ATOMICETH        9
100
0
#define RDETH_DETH                  10
101
0
#define DETH_PAYLD                  11
102
0
#define DETH_IMMDT_PAYLD            12
103
0
#define PAYLD                       13
104
0
#define IMMDT_PAYLD                 14
105
0
#define RETH_PAYLD                  15
106
0
#define RETH_IMMDT_PAYLD            16
107
0
#define RETH                        17
108
0
#define AETH_PAYLD                  18
109
0
#define AETH                        19
110
0
#define AETH_ATOMICACKETH           20
111
0
#define ATOMICETH                   21
112
0
#define IETH_PAYLD                  22
113
0
#define KDETH_PSM                   23
114
0
#define KDETH_TIDRDMA               24
115
116
/* PSM */
117
#define PSM_RESERVED                    0xC0
118
0
#define PSM_TINY                        0xC1
119
0
#define PSM_SHORT                       0xC2
120
0
#define PSM_MEDIUM                      0xC3
121
0
#define PSM_MEDIUM_DATA                 0xC4
122
0
#define PSM_LONG_RTS                    0xC5
123
0
#define PSM_LONG_CTS                    0xC6
124
0
#define PSM_LONG_DATA                   0xC7
125
0
#define PSM_TIDS_GRANT                  0xC8
126
0
#define PSM_TIDS_GRANT_ACK              0xC9
127
0
#define PSM_TIDS_RELEASE                0xCA
128
0
#define PSM_TIDS_RELEASE_CONFIRM        0xCB
129
0
#define PSM_EXPTID_UNALIGNED            0xCC
130
0
#define PSM_EXPTID                      0xCD
131
0
#define PSM_ACK                         0xCE
132
0
#define PSM_NAK                         0xCF
133
0
#define PSM_ERR_CHK                     0xD0
134
0
#define PSM_ERR_CHK_BAD                 0xD1
135
0
#define PSM_ERR_CHK_GEN                 0xD2
136
0
#define PSM_FLOW_CCA_BECN               0xD3
137
0
#define PSM_CONNECT_REQUEST             0xD4
138
0
#define PSM_CONNECT_REPLY               0xD5
139
0
#define PSM_DISCONNECT_REQUEST          0xD6
140
0
#define PSM_DISCONNECT_REPLY            0xD7
141
0
#define PSM_AM_REQUEST_NOREPLY          0xD8
142
0
#define PSM_AM_REQUEST                  0xD9
143
0
#define PSM_AM_REPLY                    0xDA
144
145
/* TID RDMA */
146
0
#define TID_RDMA_WRITE_REQUEST          0xE0
147
0
#define TID_RDMA_WRITE_RESPONSE         0xE1
148
0
#define TID_RDMA_WRITE_DATA             0xE2
149
0
#define TID_RDMA_WRITE_DATA_LAST        0xE3
150
0
#define TID_RDMA_READ_REQUEST           0xE4
151
0
#define TID_RDMA_READ_RESPONSE          0xE5
152
0
#define TID_RDMA_RESYNC                 0xE6
153
0
#define TID_RDMA_ACK                    0xE7
154
155
/* Array of all availavle OpCodes to make matching a bit easier. The OpCodes
156
 * dictate the header sequence following in the packet. These arrays tell the
157
 * dissector which headers must be decoded for the given OpCode.
158
 */
159
static const uint32_t opCode_RDETH_DETH_ATOMICETH[] = {
160
    RD_CMP_SWAP,
161
    RD_FETCH_ADD
162
};
163
static const uint32_t opCode_IETH_PAYLD[] = {
164
    RC_SEND_LAST_INVAL,
165
    RC_SEND_ONLY_INVAL
166
};
167
static const uint32_t opCode_ATOMICETH[] = {
168
    RC_CMP_SWAP,
169
    RC_FETCH_ADD
170
};
171
static const uint32_t opCode_RDETH_DETH_RETH_PAYLD[] = {
172
    RD_RDMA_WRITE_FIRST,
173
    RD_RDMA_WRITE_ONLY
174
};
175
static const uint32_t opCode_RETH_IMMDT_PAYLD[] = {
176
    RC_RDMA_WRITE_ONLY_IMM,
177
    UC_RDMA_WRITE_ONLY_IMM
178
};
179
static const uint32_t opCode_RDETH_DETH_IMMDT_PAYLD[] = {
180
    RD_SEND_LAST_IMM,
181
    RD_SEND_ONLY_IMM,
182
    RD_RDMA_WRITE_LAST_IMM
183
};
184
static const uint32_t opCode_RDETH_AETH_PAYLD[] = {
185
    RD_RDMA_READ_RESPONSE_FIRST,
186
    RD_RDMA_READ_RESPONSE_LAST,
187
    RD_RDMA_READ_RESPONSE_ONLY
188
};
189
static const uint32_t opCode_AETH_PAYLD[] = {
190
    RC_RDMA_READ_RESPONSE_FIRST,
191
    RC_RDMA_READ_RESPONSE_LAST,
192
    RC_RDMA_READ_RESPONSE_ONLY
193
};
194
static const uint32_t opCode_RETH_PAYLD[] = {
195
    RC_RDMA_WRITE_FIRST,
196
    RC_RDMA_WRITE_ONLY,
197
    UC_RDMA_WRITE_FIRST,
198
    UC_RDMA_WRITE_ONLY
199
};
200
static const uint32_t opCode_RDETH_DETH_PAYLD[] = {
201
    RD_SEND_FIRST,
202
    RD_SEND_MIDDLE,
203
    RD_SEND_LAST,
204
    RD_SEND_ONLY,
205
    RD_RDMA_WRITE_MIDDLE,
206
    RD_RDMA_WRITE_LAST
207
};
208
static const uint32_t opCode_IMMDT_PAYLD[] = {
209
    RC_SEND_LAST_IMM,
210
    RC_SEND_ONLY_IMM,
211
    RC_RDMA_WRITE_LAST_IMM,
212
    UC_SEND_LAST_IMM,
213
    UC_SEND_ONLY_IMM,
214
    UC_RDMA_WRITE_LAST_IMM
215
};
216
static const uint32_t opCode_PAYLD[] = {
217
    RC_SEND_FIRST,
218
    RC_SEND_MIDDLE,
219
    RC_SEND_LAST,
220
    RC_SEND_ONLY,
221
    RC_RDMA_WRITE_MIDDLE,
222
    RC_RDMA_WRITE_LAST,
223
    RC_RDMA_READ_RESPONSE_MIDDLE,
224
    UC_SEND_FIRST,
225
    UC_SEND_MIDDLE,
226
    UC_SEND_LAST,
227
    UC_SEND_ONLY,
228
    UC_RDMA_WRITE_MIDDLE,
229
    UC_RDMA_WRITE_LAST
230
};
231
static const uint32_t opCode_PSM[] = {
232
    PSM_RESERVED,
233
    PSM_TINY,
234
    PSM_SHORT,
235
    PSM_MEDIUM,
236
    PSM_MEDIUM_DATA,
237
    PSM_LONG_RTS,
238
    PSM_LONG_CTS,
239
    PSM_LONG_DATA,
240
    PSM_TIDS_GRANT,
241
    PSM_TIDS_GRANT_ACK,
242
    PSM_TIDS_RELEASE,
243
    PSM_TIDS_RELEASE_CONFIRM,
244
    PSM_EXPTID_UNALIGNED,
245
    PSM_EXPTID,
246
    PSM_ACK,
247
    PSM_NAK,
248
    PSM_ERR_CHK,
249
    PSM_ERR_CHK_BAD,
250
    PSM_ERR_CHK_GEN,
251
    PSM_FLOW_CCA_BECN,
252
    PSM_CONNECT_REQUEST,
253
    PSM_CONNECT_REPLY,
254
    PSM_DISCONNECT_REQUEST,
255
    PSM_DISCONNECT_REPLY,
256
    PSM_AM_REQUEST_NOREPLY,
257
    PSM_AM_REQUEST,
258
    PSM_AM_REPLY
259
};
260
static const uint32_t opCode_TIDRDMA[] = {
261
    TID_RDMA_WRITE_REQUEST,
262
    TID_RDMA_WRITE_RESPONSE,
263
    TID_RDMA_WRITE_DATA,
264
    TID_RDMA_WRITE_DATA_LAST,
265
    TID_RDMA_READ_REQUEST,
266
    TID_RDMA_READ_RESPONSE,
267
    TID_RDMA_RESYNC,
268
    TID_RDMA_ACK
269
};
270
271
/* OP Codes */
272
static const value_string vals_opa_bth_opcode[] = {
273
    { RC_SEND_FIRST,                "RC Send First" },
274
    { RC_SEND_MIDDLE,               "RC Send Middle" },
275
    { RC_SEND_LAST,                 "RC Send Last" },
276
    { RC_SEND_LAST_IMM,             "RC Send Last Immediate" },
277
    { RC_SEND_ONLY,                 "RC Send Only" },
278
    { RC_SEND_ONLY_IMM,             "RC Send Only Immediate" },
279
    { RC_RDMA_WRITE_FIRST,          "RC RDMA Write First" },
280
    { RC_RDMA_WRITE_MIDDLE,         "RC RDMA Write Middle" },
281
    { RC_RDMA_WRITE_LAST,           "RC RDMA Write Last" },
282
    { RC_RDMA_WRITE_LAST_IMM,       "RC RDMA Write Last Immediate" },
283
    { RC_RDMA_WRITE_ONLY,           "RC RDMA Write Only" },
284
    { RC_RDMA_WRITE_ONLY_IMM,       "RC RDMA Write Only Immediate" },
285
    { RC_RDMA_READ_REQUEST,         "RC RDMA Read Request" },
286
    { RC_RDMA_READ_RESPONSE_FIRST,  "RC RDMA Read Response First" },
287
    { RC_RDMA_READ_RESPONSE_MIDDLE, "RC RDMA Read Response Middle" },
288
    { RC_RDMA_READ_RESPONSE_LAST,   "RC RDMA Read Response Last" },
289
    { RC_RDMA_READ_RESPONSE_ONLY,   "RC RDMA Read Response Only" },
290
    { RC_ACKNOWLEDGE,               "RC Acknowledge" },
291
    { RC_ATOMIC_ACKNOWLEDGE,        "RC Atomic Acknowledge" },
292
    { RC_CMP_SWAP,                  "RC Compare Swap" },
293
    { RC_FETCH_ADD,                 "RC Fetch Add" },
294
    { RC_SEND_LAST_INVAL,           "RC Send Last Invalidate" },
295
    { RC_SEND_ONLY_INVAL,           "RC Send Only Invalidate" },
296
    { RD_SEND_FIRST,                "RD Send First" },
297
    { RD_SEND_MIDDLE,               "RD Send Middle" },
298
    { RD_SEND_LAST,                 "RD Send Last" },
299
    { RD_SEND_LAST_IMM,             "RD Last Immediate" },
300
    { RD_SEND_ONLY,                 "RD Send Only" },
301
    { RD_SEND_ONLY_IMM,             "RD Send Only Immediate" },
302
    { RD_RDMA_WRITE_FIRST,          "RD RDMA Write First" },
303
    { RD_RDMA_WRITE_MIDDLE,         "RD RDMA Write Middle" },
304
    { RD_RDMA_WRITE_LAST,           "RD RDMA Write Last" },
305
    { RD_RDMA_WRITE_LAST_IMM,       "RD RDMA Write Last Immediate" },
306
    { RD_RDMA_WRITE_ONLY,           "RD RDMA Write Only" },
307
    { RD_RDMA_WRITE_ONLY_IMM,       "RD RDMA Write Only Immediate" },
308
    { RD_RDMA_READ_REQUEST,         "RD RDMA Read Request" },
309
    { RD_RDMA_READ_RESPONSE_FIRST,  "RD RDMA Read Response First" },
310
    { RD_RDMA_READ_RESPONSE_MIDDLE, "RD RDMA Read Response Middle" },
311
    { RD_RDMA_READ_RESPONSE_LAST,   "RD RDMA Read Response Last" },
312
    { RD_RDMA_READ_RESPONSE_ONLY,   "RD RDMA Read Response Only" },
313
    { RD_ACKNOWLEDGE,               "RD Acknowledge" },
314
    { RD_ATOMIC_ACKNOWLEDGE,        "RD Atomic Acknowledge" },
315
    { RD_CMP_SWAP,                  "RD Compare Swap" },
316
    { RD_FETCH_ADD,                 "RD Fetch Add" },
317
    { RD_RESYNC,                    "RD RESYNC" },
318
    { UD_SEND_ONLY,                 "UD Send Only" },
319
    { UD_SEND_ONLY_IMM,             "UD Send Only Immediate" },
320
    { UC_SEND_FIRST,                "UC Send First" },
321
    { UC_SEND_MIDDLE,               "UC Send Middle" },
322
    { UC_SEND_LAST,                 "UC Send Last" },
323
    { UC_SEND_LAST_IMM,             "UC Send Last Immediate" },
324
    { UC_SEND_ONLY,                 "UC Send Only" },
325
    { UC_SEND_ONLY_IMM,             "UC Send Only Immediate" },
326
    { UC_RDMA_WRITE_FIRST,          "UC RDMA Write First" },
327
    { UC_RDMA_WRITE_MIDDLE,         "Unreliable Connection RDMA Write Middle" },
328
    { UC_RDMA_WRITE_LAST,           "UC RDMA Write Last" },
329
    { UC_RDMA_WRITE_LAST_IMM,       "UC RDMA Write Last Immediate" },
330
    { UC_RDMA_WRITE_ONLY,           "UC RDMA Write Only" },
331
    { UC_RDMA_WRITE_ONLY_IMM,       "UC RDMA Write Only Immediate" },
332
    { PSM_RESERVED,                 "PSM Reserved" },
333
    { PSM_TINY,                     "PSM TINY" },
334
    { PSM_SHORT,                    "PSM SHORT" },
335
    { PSM_MEDIUM,                   "PSM MEDIUM" },
336
    { PSM_MEDIUM_DATA,              "PSM MEDIUM_DATA" },
337
    { PSM_LONG_RTS,                 "PSM LONG RTS" },
338
    { PSM_LONG_CTS,                 "PSM LONG CTS" },
339
    { PSM_LONG_DATA,                "PSM LONG DATA" },
340
    { PSM_TIDS_GRANT,               "PSM TIDS GRANT" },
341
    { PSM_TIDS_GRANT_ACK,           "PSM TIDS GRANT ACK" },
342
    { PSM_TIDS_RELEASE,             "PSM TIDS RELEASE" },
343
    { PSM_TIDS_RELEASE_CONFIRM,     "PSM TIDS RELEASE CONFIRM" },
344
    { PSM_EXPTID_UNALIGNED,         "PSM EXPTID UNALIGNED" },
345
    { PSM_EXPTID,                   "PSM EXPTID" },
346
    { PSM_ACK,                      "PSM ACK" },
347
    { PSM_NAK,                      "PSM NAK" },
348
    { PSM_ERR_CHK,                  "PSM ERR CHK" },
349
    { PSM_ERR_CHK_BAD,              "PSM ERR CHK BAD" },
350
    { PSM_ERR_CHK_GEN,              "PSM ERR CHK GEN" },
351
    { PSM_FLOW_CCA_BECN,            "PSM FLOW CCA BECN" },
352
    { PSM_CONNECT_REQUEST,          "PSM CONNECT REQUEST" },
353
    { PSM_CONNECT_REPLY,            "PSM CONNECT REPLY" },
354
    { PSM_DISCONNECT_REQUEST,       "PSM DISCONNECT REQUEST" },
355
    { PSM_DISCONNECT_REPLY,         "PSM DISCONNECT REPLY" },
356
    { PSM_AM_REQUEST_NOREPLY,       "PSM AM REQUEST NOREPLY" },
357
    { PSM_AM_REQUEST,               "PSM AM REQUEST" },
358
    { PSM_AM_REPLY,                 "PSM AM REPLY" },
359
    { TID_RDMA_WRITE_REQUEST,       "TID RDMA Write Request" },
360
    { TID_RDMA_WRITE_RESPONSE,      "TID RDMA Write Response" },
361
    { TID_RDMA_WRITE_DATA,          "TID RDMA Write Data" },
362
    { TID_RDMA_WRITE_DATA_LAST,     "TID RDMA Write Data Last" },
363
    { TID_RDMA_READ_REQUEST,        "TID RDMA Read Request" },
364
    { TID_RDMA_READ_RESPONSE,       "TID RDMA Read Response" },
365
    { TID_RDMA_RESYNC,              "TID RDMA ReSync" },
366
    { TID_RDMA_ACK,                 "TID RDMA Ack" },
367
    { 0, NULL }
368
};
369
static const value_string vals_opa_9b_lnh[] = {
370
    { 0, "RAW" },
371
    { 3, "GRH" },
372
    { 2, "BTH" },
373
    { 1, "Ipv6" },
374
    { 0, NULL }
375
};
376
static const value_string vals_opa_9b_grh_ipver[] = {
377
    { 4, "IPv4" },
378
    { 6, "IPv6" },
379
    { 0, NULL },
380
};
381
static const value_string vals_opa_9b_grh_next_hdr[] = {
382
    { 0x1B, "BTH Follows" },
383
    { 0, NULL }
384
};
385
static const true_false_string tfs_opa_bth_migrated_notmigrated = {
386
    "Migrated",
387
    "Not Migrated"
388
};
389
static const true_false_string tfs_opa_kdeth_offset_32_64 = {
390
    "32 Byte Words",
391
    "64 Byte Words"
392
};
393
/* Wireshark ID */
394
static int proto_opa_9b;
395
396
/* Variables to hold expansion values between packets */
397
static int ett_all_headers;
398
static int ett_9b;
399
static int ett_grh;
400
static int ett_bth;
401
static int ett_rdeth;
402
static int ett_deth;
403
static int ett_reth;
404
static int ett_atomiceth;
405
static int ett_aeth;
406
static int ett_atomicacketh;
407
static int ett_immdt;
408
static int ett_ieth;
409
static int ett_kdeth;
410
static int ett_psm;
411
static int ett_tidrdma;
412
413
/* 9B Header Fields */
414
static int hf_opa_9B;
415
static int hf_opa_9B_service_channel;
416
static int hf_opa_9B_link_version;
417
static int hf_opa_9B_service_level;
418
static int hf_opa_9B_reserved2;
419
static int hf_opa_9B_lnh;
420
static int hf_opa_9B_dlid;
421
static int hf_opa_9B_reserved3;
422
static int hf_opa_9B_packet_length;
423
static int hf_opa_9B_slid;
424
/* ICRC */
425
static int hf_opa_9b_ICRC;
426
427
/* GRH */
428
static int hf_opa_grh;
429
static int hf_opa_grh_ip_version;
430
static int hf_opa_grh_traffic_class;
431
static int hf_opa_grh_flow_label;
432
static int hf_opa_grh_payload_length;
433
static int hf_opa_grh_next_header;
434
static int hf_opa_grh_hop_limit;
435
static int hf_opa_grh_source_gid;
436
static int hf_opa_grh_destination_gid;
437
438
/* BTH */
439
static int hf_opa_bth;
440
static int hf_opa_bth_opcode;
441
static int hf_opa_bth_solicited_event;
442
static int hf_opa_bth_migreq;
443
static int hf_opa_bth_pad_count;
444
static int hf_opa_bth_transport_header_version;
445
static int hf_opa_bth_partition_key;
446
static int hf_opa_bth_fcn;
447
static int hf_opa_bth_bcn;
448
static int hf_opa_bth_Reserved8a;
449
static int hf_opa_bth_destination_qp;
450
static int hf_opa_bth_acknowledge_request;
451
static int hf_opa_bth_packet_sequence_number;
452
453
/* XXETH */
454
static int hf_opa_RDETH;
455
static int hf_opa_RDETH_reserved8;
456
static int hf_opa_RDETH_ee_context;
457
static int hf_opa_DETH;
458
static int hf_opa_DETH_queue_key;
459
static int hf_opa_DETH_reserved8;
460
static int hf_opa_DETH_source_qp;
461
static int hf_opa_RETH;
462
static int hf_opa_RETH_virtual_address;
463
static int hf_opa_RETH_remote_key;
464
static int hf_opa_RETH_dma_length;
465
static int hf_opa_AtomicETH;
466
static int hf_opa_AtomicETH_virtual_address;
467
static int hf_opa_AtomicETH_remote_key;
468
static int hf_opa_AtomicETH_swap_or_add_data;
469
static int hf_opa_AtomicETH_compare_data;
470
static int hf_opa_AETH;
471
static int hf_opa_AETH_syndrome;
472
static int hf_opa_AETH_message_sequence_number;
473
static int hf_opa_AtomicAckETH;
474
static int hf_opa_AtomicAckETH_original_remote_data;
475
static int hf_opa_IMMDT;
476
static int hf_opa_IMMDT_data;
477
static int hf_opa_IETH;
478
static int hf_opa_IETH_r_key;
479
static int hf_opa_KDETH;
480
static int hf_opa_KDETH_kver;
481
static int hf_opa_KDETH_sh;
482
static int hf_opa_KDETH_intr;
483
static int hf_opa_KDETH_tidctrl;
484
static int hf_opa_KDETH_tid;
485
static int hf_opa_KDETH_offset_mode;
486
static int hf_opa_KDETH_offset;
487
static int * const _opa_KDETH_word1[] = {
488
    &hf_opa_KDETH_kver,
489
    &hf_opa_KDETH_sh,
490
    &hf_opa_KDETH_intr,
491
    &hf_opa_KDETH_tidctrl,
492
    &hf_opa_KDETH_tid,
493
    &hf_opa_KDETH_offset_mode,
494
    &hf_opa_KDETH_offset,
495
    NULL
496
};
497
static int hf_opa_KDETH_hcrc;
498
static int hf_opa_KDETH_j_key;
499
static int * const _opa_KDETH_word2[] = {
500
    &hf_opa_KDETH_hcrc,
501
    &hf_opa_KDETH_j_key,
502
    NULL
503
};
504
/* PSM */
505
static int hf_opa_psm;
506
static int hf_opa_psm_a;
507
static int hf_opa_psm_ackpsn;
508
static int hf_opa_psm_flags;
509
static int hf_opa_psm_commidx;
510
static int hf_opa_psm_flowid;
511
static int hf_opa_psm_msglen;
512
static int hf_opa_psm_msgseq;
513
static int hf_opa_psm_tag;
514
static int hf_opa_psm_msgdata;
515
static int hf_opa_psm_short_msglen;
516
static int hf_opa_psm_paylen;
517
static int hf_opa_psm_offset;
518
static int hf_opa_psm_sreqidx;
519
static int hf_opa_psm_rreqidx;
520
static int hf_opa_psm_rdescid;
521
static int hf_opa_psm_sdescid;
522
static int hf_opa_psm_psn;
523
static int hf_opa_psm_hostipv4;
524
static int hf_opa_psm_hostpid;
525
static int hf_opa_psm_dlen;
526
static int hf_opa_psm_nargs;
527
static int hf_opa_psm_hidx;
528
static int hf_opa_psm_arg;
529
static int hf_opa_psm_payload;
530
/* TID RDMA */
531
static int hf_opa_TIDRDMA;
532
static int hf_opa_TIDRDMA_reserved;
533
static int hf_opa_TIDRDMA_TIDFlowPSN_reserved;
534
static int hf_opa_TIDRDMA_TIDFlowPSN;
535
static int hf_opa_TIDRDMA_TIDFlowQP_reserved;
536
static int hf_opa_TIDRDMA_TIDFlowQP;
537
static int hf_opa_TIDRDMA_VerbsPSN_reserved;
538
static int hf_opa_TIDRDMA_VerbsPSN;
539
static int hf_opa_TIDRDMA_VerbsQP_reserved;
540
static int hf_opa_TIDRDMA_VerbsQP;
541
542
543
/* Custom Functions */
544
static void cf_opa_dw_to_b(char *buf, uint32_t value)
545
0
{
546
0
    snprintf(buf, ITEM_LABEL_LENGTH, "%u DWORDS (%u Bytes)", value, value * 4);
547
0
}
548
549
/* Dissector Declarations */
550
static dissector_handle_t opa_9b_handle;
551
static dissector_handle_t opa_mad_handle;
552
static dissector_handle_t infiniband_handle;
553
static dissector_handle_t ipv6_handle;
554
555
static void parse_opa_9B_Header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, uint8_t *lnh_val)
556
0
{
557
    /* 16B - L2 Header */
558
0
    proto_item *L2_9B_header_item;
559
0
    proto_tree *L2_9B_header_tree;
560
0
    void *src_addr, *dst_addr;
561
562
0
    int local_offset = *offset;
563
564
0
    col_prepend_fstr(pinfo->cinfo, COL_INFO, "9B: ");
565
0
    L2_9B_header_item = proto_tree_add_item(tree, hf_opa_9B, tvb, local_offset, 8, ENC_NA);
566
0
    L2_9B_header_tree = proto_item_add_subtree(L2_9B_header_item, ett_9b);
567
568
0
    proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_service_channel, tvb, local_offset, 1, ENC_BIG_ENDIAN);
569
0
    proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_link_version, tvb, local_offset, 1, ENC_BIG_ENDIAN);
570
0
    local_offset += 1;
571
0
    proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_service_level, tvb, local_offset, 1, ENC_BIG_ENDIAN);
572
0
    proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_reserved2, tvb, local_offset, 1, ENC_BIG_ENDIAN);
573
0
    proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_lnh, tvb, local_offset, 1, ENC_BIG_ENDIAN);
574
575
    /* Save Link Next Header... This tells us what the next header is. */
576
0
    *lnh_val = tvb_get_uint8(tvb, local_offset);
577
0
    *lnh_val &= 0x03;
578
0
    local_offset += 1;
579
580
0
    proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_dlid, tvb, local_offset, 2, ENC_BIG_ENDIAN);
581
582
    /* Set destination in packet view. */
583
0
    dst_addr = wmem_alloc(pinfo->pool, sizeof(uint16_t));
584
0
    *((uint16_t *)dst_addr) = tvb_get_ntohs(tvb, local_offset);
585
0
    set_address(&pinfo->dst, AT_IB, sizeof(uint16_t), dst_addr);
586
0
    local_offset += 2;
587
588
0
    proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_reserved3, tvb, local_offset, 1, ENC_BIG_ENDIAN);
589
590
0
    proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_packet_length, tvb, local_offset, 2, ENC_BIG_ENDIAN);
591
0
    local_offset += 2;
592
0
    proto_tree_add_item(L2_9B_header_tree, hf_opa_9B_slid, tvb, local_offset, 2, ENC_BIG_ENDIAN);
593
594
    /* Set Source in packet view. */
595
0
    src_addr = wmem_alloc(pinfo->pool, sizeof(uint16_t));
596
0
    *((uint16_t *)src_addr) = tvb_get_ntohs(tvb, local_offset);
597
0
    set_address(&pinfo->src, AT_IB, sizeof(uint16_t), src_addr);
598
0
    local_offset += 2;
599
600
0
    *offset = local_offset;
601
0
}
602
603
static void parse_opa_grh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, uint8_t *nextHdr)
604
0
{
605
0
    proto_item *global_route_header_item;
606
0
    proto_tree *global_route_header_tree;
607
608
0
    int local_offset = *offset;
609
610
0
    col_append_str(pinfo->cinfo, COL_INFO, "GRH: ");
611
0
    global_route_header_item = proto_tree_add_item(tree, hf_opa_grh, tvb, local_offset, 40, ENC_NA);
612
0
    global_route_header_tree = proto_item_add_subtree(global_route_header_item, ett_grh);
613
614
0
    proto_tree_add_item(global_route_header_tree, hf_opa_grh_ip_version, tvb, local_offset, 1, ENC_BIG_ENDIAN);
615
0
    proto_tree_add_item(global_route_header_tree, hf_opa_grh_traffic_class, tvb, local_offset, 2, ENC_BIG_ENDIAN);
616
0
    proto_tree_add_item(global_route_header_tree, hf_opa_grh_flow_label, tvb, local_offset, 4, ENC_BIG_ENDIAN);
617
0
    local_offset += 4;
618
619
0
    proto_tree_add_item(global_route_header_tree, hf_opa_grh_payload_length, tvb, local_offset, 2, ENC_BIG_ENDIAN);
620
0
    local_offset += 2;
621
622
0
    *nextHdr = tvb_get_uint8(tvb, local_offset);
623
624
0
    proto_tree_add_item(global_route_header_tree, hf_opa_grh_next_header, tvb, local_offset, 1, ENC_BIG_ENDIAN);
625
0
    local_offset += 1;
626
0
    proto_tree_add_item(global_route_header_tree, hf_opa_grh_hop_limit, tvb, local_offset, 1, ENC_BIG_ENDIAN);
627
0
    local_offset += 1;
628
0
    proto_tree_add_item(global_route_header_tree, hf_opa_grh_source_gid, tvb, local_offset, 16, ENC_NA);
629
630
    /* set source GID in packet view*/
631
0
    set_address_tvb(&pinfo->src, AT_IB, 16, tvb, local_offset);
632
0
    local_offset += 16;
633
634
0
    proto_tree_add_item(global_route_header_tree, hf_opa_grh_destination_gid, tvb, local_offset, 16, ENC_NA);
635
636
    /* set destination GID in packet view*/
637
0
    set_address_tvb(&pinfo->dst, AT_IB, 16, tvb, local_offset);
638
0
    local_offset += 16;
639
640
0
    *offset = local_offset;
641
0
}
642
643
static void parse_opa_bth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, uint8_t *opCode)
644
0
{
645
0
    proto_item *base_transport_header_item;
646
0
    proto_tree *base_transport_header_tree;
647
648
0
    int local_offset = *offset;
649
650
0
    col_append_str(pinfo->cinfo, COL_INFO, "BTH: ");
651
0
    base_transport_header_item = proto_tree_add_item(tree, hf_opa_bth, tvb, local_offset, 12, ENC_NA);
652
0
    base_transport_header_tree = proto_item_add_subtree(base_transport_header_item, ett_bth);
653
654
0
    proto_tree_add_item(base_transport_header_tree, hf_opa_bth_opcode, tvb, local_offset, 1, ENC_LITTLE_ENDIAN);
655
0
    *opCode = tvb_get_uint8(tvb, local_offset);
656
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(pinfo->pool, (uint32_t)(*opCode), vals_opa_bth_opcode, "Unknown OpCode (0x%0x)"));
657
0
    local_offset += 1;
658
659
0
    proto_tree_add_item(base_transport_header_tree, hf_opa_bth_solicited_event, tvb, local_offset, 1, ENC_BIG_ENDIAN);
660
0
    proto_tree_add_item(base_transport_header_tree, hf_opa_bth_migreq, tvb, local_offset, 1, ENC_BIG_ENDIAN);
661
0
    proto_tree_add_item(base_transport_header_tree, hf_opa_bth_pad_count, tvb, local_offset, 1, ENC_BIG_ENDIAN);
662
0
    proto_tree_add_item(base_transport_header_tree, hf_opa_bth_transport_header_version, tvb, local_offset, 1, ENC_BIG_ENDIAN);
663
664
0
    local_offset += 1;
665
0
    proto_tree_add_item(base_transport_header_tree, hf_opa_bth_partition_key, tvb, local_offset, 2, ENC_BIG_ENDIAN);
666
667
0
    local_offset += 2;
668
0
    proto_tree_add_item(base_transport_header_tree, hf_opa_bth_fcn, tvb, local_offset, 1, ENC_BIG_ENDIAN);
669
0
    proto_tree_add_item(base_transport_header_tree, hf_opa_bth_bcn, tvb, local_offset, 1, ENC_BIG_ENDIAN);
670
0
    proto_tree_add_item(base_transport_header_tree, hf_opa_bth_Reserved8a, tvb, local_offset, 1, ENC_BIG_ENDIAN);
671
0
    local_offset += 1;
672
0
    proto_tree_add_item(base_transport_header_tree, hf_opa_bth_destination_qp, tvb, local_offset, 3, ENC_BIG_ENDIAN);
673
0
    pinfo->destport = tvb_get_ntoh24(tvb, local_offset); local_offset += 3;
674
0
    proto_tree_add_item(base_transport_header_tree, hf_opa_bth_acknowledge_request, tvb, local_offset, 1, ENC_BIG_ENDIAN);
675
0
    proto_tree_add_item(base_transport_header_tree, hf_opa_bth_packet_sequence_number, tvb, local_offset, 4, ENC_BIG_ENDIAN);
676
0
    local_offset += 4;
677
678
0
    *offset = local_offset;
679
0
}
680
static bool contains(uint32_t OpCode, uint32_t const *Codes, int32_t length)
681
0
{
682
0
    int32_t i;
683
0
    for (i = 0; i < length; i++) {
684
0
        if ((OpCode ^ Codes[i]) == 0)
685
0
            return true;
686
0
    }
687
0
    return false;
688
0
}
689
static int32_t find_next_header_sequence(uint32_t OpCode)
690
0
{
691
0
    if (contains(OpCode, &opCode_PAYLD[0], (int32_t)array_length(opCode_PAYLD)))
692
0
        return PAYLD;
693
694
0
    if (contains(OpCode, &opCode_IMMDT_PAYLD[0], (int32_t)array_length(opCode_IMMDT_PAYLD)))
695
0
        return IMMDT_PAYLD;
696
697
0
    if (contains(OpCode, &opCode_RDETH_DETH_PAYLD[0], (int32_t)array_length(opCode_RDETH_DETH_PAYLD)))
698
0
        return RDETH_DETH_PAYLD;
699
700
0
    if (contains(OpCode, &opCode_RETH_PAYLD[0], (int32_t)array_length(opCode_RETH_PAYLD)))
701
0
        return RETH_PAYLD;
702
703
0
    if (contains(OpCode, &opCode_RDETH_AETH_PAYLD[0], (int32_t)array_length(opCode_RDETH_AETH_PAYLD)))
704
0
        return RDETH_AETH_PAYLD;
705
706
0
    if (contains(OpCode, &opCode_AETH_PAYLD[0], (int32_t)array_length(opCode_AETH_PAYLD)))
707
0
        return AETH_PAYLD;
708
709
0
    if (contains(OpCode, &opCode_RDETH_DETH_IMMDT_PAYLD[0], (int32_t)array_length(opCode_RDETH_DETH_IMMDT_PAYLD)))
710
0
        return RDETH_DETH_IMMDT_PAYLD;
711
712
0
    if (contains(OpCode, &opCode_RETH_IMMDT_PAYLD[0], (int32_t)array_length(opCode_RETH_IMMDT_PAYLD)))
713
0
        return RETH_IMMDT_PAYLD;
714
715
0
    if (contains(OpCode, &opCode_RDETH_DETH_RETH_PAYLD[0], (int32_t)array_length(opCode_RDETH_DETH_RETH_PAYLD)))
716
0
        return RDETH_DETH_RETH_PAYLD;
717
718
0
    if (contains(OpCode, &opCode_ATOMICETH[0], (int32_t)array_length(opCode_ATOMICETH)))
719
0
        return ATOMICETH;
720
721
0
    if (contains(OpCode, &opCode_IETH_PAYLD[0], (int32_t)array_length(opCode_IETH_PAYLD)))
722
0
        return IETH_PAYLD;
723
724
0
    if (contains(OpCode, &opCode_RDETH_DETH_ATOMICETH[0], (int32_t)array_length(opCode_RDETH_DETH_ATOMICETH)))
725
0
        return RDETH_DETH_ATOMICETH;
726
727
0
    if (contains(OpCode, &opCode_PSM[0], (int32_t)array_length(opCode_PSM)))
728
0
        return KDETH_PSM;
729
730
0
    if (contains(OpCode, &opCode_TIDRDMA[0], (int32_t)array_length(opCode_TIDRDMA)))
731
0
        return KDETH_TIDRDMA;
732
733
0
    if ((OpCode ^ RC_ACKNOWLEDGE) == 0)
734
0
        return AETH;
735
736
0
    if ((OpCode ^ RC_RDMA_READ_REQUEST) == 0)
737
0
        return RETH;
738
739
0
    if ((OpCode ^ RC_ATOMIC_ACKNOWLEDGE) == 0)
740
0
        return AETH_ATOMICACKETH;
741
742
0
    if ((OpCode ^ RD_RDMA_READ_RESPONSE_MIDDLE) == 0)
743
0
        return RDETH_PAYLD;
744
745
0
    if ((OpCode ^ RD_ACKNOWLEDGE) == 0)
746
0
        return RDETH_AETH;
747
748
0
    if ((OpCode ^ RD_ATOMIC_ACKNOWLEDGE) == 0)
749
0
        return RDETH_AETH_ATOMICACKETH;
750
751
0
    if ((OpCode ^ RD_RDMA_WRITE_ONLY_IMM) == 0)
752
0
        return RDETH_DETH_RETH_IMMDT_PAYLD;
753
754
0
    if ((OpCode ^ RD_RDMA_READ_REQUEST) == 0)
755
0
        return RDETH_DETH_RETH;
756
757
0
    if ((OpCode ^ RD_RESYNC) == 0)
758
0
        return RDETH_DETH;
759
760
0
    if ((OpCode ^ UD_SEND_ONLY) == 0)
761
0
        return DETH_PAYLD;
762
763
0
    if ((OpCode ^ UD_SEND_ONLY_IMM) == 0)
764
0
        return DETH_IMMDT_PAYLD;
765
766
0
    return -1;
767
0
}
768
769
/* Parse RDETH - Reliable Datagram Extended Transport Header */
770
static void parse_RDETH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset)
771
0
{
772
0
    int local_offset = *offset;
773
    /* RDETH - Reliable Datagram Extended Transport Header */
774
0
    proto_item *RDETH_header_item;
775
0
    proto_tree *RDETH_header_tree;
776
777
0
    col_append_str(pinfo->cinfo, COL_INFO, "RDETH: ");
778
0
    RDETH_header_item = proto_tree_add_item(tree, hf_opa_RDETH, tvb, local_offset, 4, ENC_NA);
779
0
    RDETH_header_tree = proto_item_add_subtree(RDETH_header_item, ett_rdeth);
780
781
0
    proto_tree_add_item(RDETH_header_tree, hf_opa_RDETH_reserved8, tvb, local_offset, 1, ENC_BIG_ENDIAN);
782
0
    local_offset += 1;
783
0
    proto_tree_add_item(RDETH_header_tree, hf_opa_RDETH_ee_context, tvb, local_offset, 3, ENC_BIG_ENDIAN);
784
0
    local_offset += 3;
785
0
    *offset = local_offset;
786
0
}
787
/* Parse DETH - Datagram Extended Transport Header */
788
static void parse_DETH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset)
789
0
{
790
0
    int local_offset = *offset;
791
    /* DETH - Datagram Extended Transport Header */
792
0
    proto_item *DETH_header_item;
793
0
    proto_tree *DETH_header_tree;
794
795
0
    col_append_str(pinfo->cinfo, COL_INFO, "DETH: ");
796
0
    DETH_header_item = proto_tree_add_item(tree, hf_opa_DETH, tvb, local_offset, 8, ENC_NA);
797
0
    DETH_header_tree = proto_item_add_subtree(DETH_header_item, ett_deth);
798
799
0
    proto_tree_add_item(DETH_header_tree, hf_opa_DETH_queue_key, tvb, local_offset, 4, ENC_BIG_ENDIAN);
800
0
    local_offset += 4;
801
0
    proto_tree_add_item(DETH_header_tree, hf_opa_DETH_reserved8, tvb, local_offset, 1, ENC_BIG_ENDIAN);
802
0
    local_offset += 1;
803
0
    proto_tree_add_item(DETH_header_tree, hf_opa_DETH_source_qp, tvb, local_offset, 3, ENC_BIG_ENDIAN);
804
0
    pinfo->srcport = tvb_get_ntoh24(tvb, local_offset); local_offset += 3;
805
806
0
    *offset = local_offset;
807
0
}
808
/* Parse RETH - RDMA Extended Transport Header */
809
static void parse_RETH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset)
810
0
{
811
0
    int local_offset = *offset;
812
    /* RETH - RDMA Extended Transport Header */
813
0
    proto_item *RETH_header_item;
814
0
    proto_tree *RETH_header_tree;
815
816
0
    col_append_str(pinfo->cinfo, COL_INFO, "RETH: ");
817
0
    RETH_header_item = proto_tree_add_item(tree, hf_opa_RETH, tvb, local_offset, 16, ENC_NA);
818
0
    RETH_header_tree = proto_item_add_subtree(RETH_header_item, ett_reth);
819
820
0
    proto_tree_add_item(RETH_header_tree, hf_opa_RETH_virtual_address, tvb, local_offset, 8, ENC_BIG_ENDIAN);
821
0
    local_offset += 8;
822
0
    proto_tree_add_item(RETH_header_tree, hf_opa_RETH_remote_key, tvb, local_offset, 4, ENC_BIG_ENDIAN);
823
0
    local_offset += 4;
824
0
    proto_tree_add_item(RETH_header_tree, hf_opa_RETH_dma_length, tvb, local_offset, 4, ENC_BIG_ENDIAN);
825
0
    local_offset += 4;
826
827
0
    *offset = local_offset;
828
0
}
829
/* Parse AtomicETH - Atomic Extended Transport Header */
830
static void parse_ATOMICETH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset)
831
0
{
832
0
    int local_offset = *offset;
833
    /* AtomicETH - Atomic Extended Transport Header */
834
0
    proto_item *ATOMICETH_header_item;
835
0
    proto_tree *ATOMICETH_header_tree;
836
837
0
    col_append_str(pinfo->cinfo, COL_INFO, "AtomicETH: ");
838
0
    ATOMICETH_header_item = proto_tree_add_item(tree, hf_opa_AtomicETH, tvb, local_offset, 28, ENC_NA);
839
0
    ATOMICETH_header_tree = proto_item_add_subtree(ATOMICETH_header_item, ett_atomiceth);
840
841
0
    proto_tree_add_item(ATOMICETH_header_tree, hf_opa_AtomicETH_virtual_address, tvb, local_offset, 8, ENC_BIG_ENDIAN);
842
0
    local_offset += 8;
843
0
    proto_tree_add_item(ATOMICETH_header_tree, hf_opa_AtomicETH_remote_key, tvb, local_offset, 4, ENC_BIG_ENDIAN);
844
0
    local_offset += 4;
845
0
    proto_tree_add_item(ATOMICETH_header_tree, hf_opa_AtomicETH_swap_or_add_data, tvb, local_offset, 8, ENC_BIG_ENDIAN);
846
0
    local_offset += 8;
847
0
    proto_tree_add_item(ATOMICETH_header_tree, hf_opa_AtomicETH_compare_data, tvb, local_offset, 8, ENC_BIG_ENDIAN);
848
0
    local_offset += 8;
849
0
    *offset = local_offset;
850
0
}
851
/* Parse AETH - ACK Extended Transport Header */
852
static void parse_AETH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset)
853
0
{
854
0
    int local_offset = *offset;
855
    /* AETH - ACK Extended Transport Header */
856
0
    proto_item *AETH_header_item;
857
0
    proto_tree *AETH_header_tree;
858
859
0
    col_append_str(pinfo->cinfo, COL_INFO, "AETH: ");
860
0
    AETH_header_item = proto_tree_add_item(tree, hf_opa_AETH, tvb, local_offset, 4, ENC_NA);
861
0
    AETH_header_tree = proto_item_add_subtree(AETH_header_item, ett_aeth);
862
863
0
    proto_tree_add_item(AETH_header_tree, hf_opa_AETH_syndrome, tvb, local_offset, 1, ENC_BIG_ENDIAN);
864
0
    local_offset += 1;
865
0
    proto_tree_add_item(AETH_header_tree, hf_opa_AETH_message_sequence_number, tvb, local_offset, 3, ENC_BIG_ENDIAN);
866
0
    local_offset += 3;
867
868
0
    *offset = local_offset;
869
0
}
870
/* Parse AtomicAckEth - Atomic ACK Extended Transport Header */
871
static void parse_ATOMICACKETH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset)
872
0
{
873
0
    int local_offset = *offset;
874
    /* AtomicAckEth - Atomic ACK Extended Transport Header */
875
0
    proto_item *ATOMICACKETH_header_item;
876
0
    proto_tree *ATOMICACKETH_header_tree;
877
878
0
    col_append_str(pinfo->cinfo, COL_INFO, "AtomicACKETH: ");
879
0
    ATOMICACKETH_header_item = proto_tree_add_item(tree, hf_opa_AtomicAckETH, tvb, local_offset, 8, ENC_NA);
880
0
    ATOMICACKETH_header_tree = proto_item_add_subtree(ATOMICACKETH_header_item, ett_atomicacketh);
881
0
    proto_tree_add_item(ATOMICACKETH_header_tree, hf_opa_AtomicAckETH_original_remote_data, tvb, local_offset, 8, ENC_BIG_ENDIAN);
882
0
    local_offset += 8;
883
0
    *offset = local_offset;
884
0
}
885
/* Parse IMMDT - Immediate Data Extended Transport Header */
886
static void parse_IMMDT(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset)
887
0
{
888
0
    int local_offset = *offset;
889
    /* IMMDT - Immediate Data Extended Transport Header */
890
0
    proto_item *IMMDT_header_item;
891
0
    proto_tree *IMMDT_header_tree;
892
893
0
    col_append_str(pinfo->cinfo, COL_INFO, "IMMDT: ");
894
0
    IMMDT_header_item = proto_tree_add_item(tree, hf_opa_IMMDT, tvb, local_offset, 4, ENC_NA);
895
0
    IMMDT_header_tree = proto_item_add_subtree(IMMDT_header_item, ett_immdt);
896
0
    proto_tree_add_item(IMMDT_header_tree, hf_opa_IMMDT_data, tvb, local_offset, 4, ENC_BIG_ENDIAN);
897
0
    local_offset += 4;
898
0
    *offset = local_offset;
899
0
}
900
/* Parse IETH - Invalidate Extended Transport Header */
901
static void parse_IETH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset)
902
0
{
903
0
    int local_offset = *offset;
904
    /* IETH - Invalidate Extended Transport Header */
905
0
    proto_item *IETH_header_item;
906
0
    proto_tree *IETH_header_tree;
907
908
0
    col_append_str(pinfo->cinfo, COL_INFO, "IETH: ");
909
0
    IETH_header_item = proto_tree_add_item(tree, hf_opa_IETH, tvb, local_offset, 4, ENC_NA);
910
0
    IETH_header_tree = proto_item_add_subtree(IETH_header_item, ett_ieth);
911
912
0
    proto_tree_add_item(IETH_header_tree, hf_opa_IETH_r_key,  tvb, local_offset, 4, ENC_BIG_ENDIAN);
913
0
    local_offset += 4;
914
915
0
    *offset = local_offset;
916
0
}
917
/* Parse KDETH - Key Datagram Extended Transport Header */
918
static void parse_KDETH(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset)
919
0
{
920
0
    int local_offset = *offset;
921
    /* KDETH - Key Datagram Extended Transport Header */
922
0
    proto_item *KDETH_header_item;
923
0
    proto_tree *KDETH_header_tree;
924
925
0
    col_append_str(pinfo->cinfo, COL_INFO, "KDETH: ");
926
0
    KDETH_header_item = proto_tree_add_item(tree, hf_opa_KDETH, tvb, local_offset, 8, ENC_NA);
927
0
    KDETH_header_tree = proto_item_add_subtree(KDETH_header_item, ett_kdeth);
928
929
0
    proto_tree_add_bitmask_list(KDETH_header_tree, tvb, local_offset, 4, _opa_KDETH_word1, ENC_LITTLE_ENDIAN);
930
0
    local_offset += 4;
931
0
    proto_tree_add_bitmask_list(KDETH_header_tree, tvb, local_offset, 4, _opa_KDETH_word2, ENC_LITTLE_ENDIAN);
932
0
    local_offset += 4;
933
934
0
    *offset = local_offset;
935
0
}
936
937
/* Parse PSM header */
938
static void parse_PSM(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, int opCode)
939
0
{
940
0
    int local_offset = *offset;
941
    /* PSM Header */
942
0
    proto_item *PSM_header_item;
943
0
    proto_tree *PSM_header_tree;
944
0
    uint32_t payLength;
945
946
0
    col_append_str(pinfo->cinfo, COL_INFO, "PSM: ");
947
0
    PSM_header_item = proto_tree_add_item(tree, hf_opa_psm, tvb, local_offset, 28, ENC_NA);
948
0
    PSM_header_tree = proto_item_add_subtree(PSM_header_item, ett_psm);
949
950
0
    proto_tree_add_item(PSM_header_tree, hf_opa_psm_a, tvb, local_offset + 3, 1, ENC_LITTLE_ENDIAN);
951
0
    proto_tree_add_item(PSM_header_tree, hf_opa_psm_ackpsn, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
952
0
    local_offset += 4;
953
0
    proto_tree_add_item(PSM_header_tree, hf_opa_psm_flags, tvb, local_offset + 3, 1, ENC_LITTLE_ENDIAN);
954
0
    proto_tree_add_item(PSM_header_tree, hf_opa_psm_commidx, tvb, local_offset, 3, ENC_LITTLE_ENDIAN);
955
0
    local_offset += 4;
956
0
    proto_tree_add_item(PSM_header_tree, hf_opa_psm_flowid, tvb, local_offset + 3, 1, ENC_LITTLE_ENDIAN);
957
958
0
    switch (opCode) {
959
0
    case PSM_TINY:
960
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_msglen, tvb, local_offset + 2, 1, ENC_LITTLE_ENDIAN);
961
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_msgseq, tvb, local_offset, 2, ENC_LITTLE_ENDIAN);
962
0
        local_offset += 4;
963
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_tag, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
964
0
        local_offset += 8;
965
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_msgdata, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
966
0
        local_offset += 8;
967
0
        break;
968
0
    case PSM_SHORT:
969
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_msgseq, tvb, local_offset, 2, ENC_LITTLE_ENDIAN);
970
0
        local_offset += 4;
971
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_tag, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
972
0
        local_offset += 8;
973
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_msglen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
974
0
        payLength = tvb_get_letohl(tvb, local_offset);
975
0
        local_offset += 8;
976
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_payload, tvb, local_offset, payLength, ENC_NA);
977
0
        local_offset += payLength;
978
0
        break;
979
0
    case PSM_MEDIUM:
980
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_msgseq, tvb, local_offset, 2, ENC_LITTLE_ENDIAN);
981
0
        local_offset += 4;
982
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_tag, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
983
0
        local_offset += 8;
984
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_msglen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
985
0
        local_offset += 4;
986
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_paylen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
987
0
        local_offset += 4;
988
0
        break;
989
0
    case PSM_MEDIUM_DATA:
990
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_msgseq, tvb, local_offset, 2, ENC_LITTLE_ENDIAN);
991
0
        local_offset += 4;
992
0
        local_offset += 8;
993
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_offset, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
994
0
        local_offset += 4;
995
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_paylen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
996
0
        local_offset += 4;
997
0
        break;
998
0
    case PSM_LONG_RTS:
999
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_msgseq, tvb, local_offset, 2, ENC_LITTLE_ENDIAN);
1000
0
        local_offset += 4;
1001
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_tag, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
1002
0
        local_offset += 8;
1003
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_msglen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
1004
0
        local_offset += 4;
1005
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_sreqidx, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
1006
0
        local_offset += 4;
1007
0
        break;
1008
0
    case PSM_LONG_CTS:
1009
0
        local_offset += 4;
1010
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_sreqidx, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
1011
0
        local_offset += 4;
1012
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_rreqidx, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
1013
0
        local_offset += 4;
1014
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_msglen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
1015
0
        local_offset += 8;
1016
0
        break;
1017
0
    case PSM_LONG_DATA:
1018
0
        local_offset += 4;
1019
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_rreqidx, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
1020
0
        local_offset += 4;
1021
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_offset, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
1022
0
        local_offset += 4;
1023
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_paylen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
1024
0
        local_offset += 8;
1025
0
        break;
1026
0
    case PSM_TIDS_GRANT:
1027
0
        local_offset += 4;
1028
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_sreqidx, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
1029
0
        local_offset += 4;
1030
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_short_msglen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
1031
0
        local_offset += 4;
1032
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_paylen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
1033
0
        local_offset += 8;
1034
0
        break;
1035
0
    case PSM_TIDS_GRANT_ACK:
1036
0
        local_offset += 4;
1037
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_rdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
1038
0
        local_offset += 8;
1039
0
        local_offset += 8;
1040
0
        break;
1041
0
    case PSM_TIDS_RELEASE:
1042
0
        local_offset += 4;
1043
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_rdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
1044
0
        local_offset += 8;
1045
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_sdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
1046
0
        local_offset += 8;
1047
0
        break;
1048
0
    case PSM_TIDS_RELEASE_CONFIRM:
1049
0
        local_offset += 4;
1050
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_sdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
1051
0
        local_offset += 8;
1052
0
        local_offset += 8;
1053
0
        break;
1054
0
    case PSM_EXPTID_UNALIGNED:
1055
0
        local_offset += 4;
1056
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_rdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
1057
0
        local_offset += 8;
1058
0
        local_offset += 8;
1059
0
        break;
1060
0
    case PSM_EXPTID:
1061
0
        local_offset += 4;
1062
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_rdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
1063
0
        local_offset += 8;
1064
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_sdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
1065
0
        local_offset += 8;
1066
0
        break;
1067
0
    case PSM_ACK:
1068
0
        local_offset += 4;
1069
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_sdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
1070
0
        local_offset += 8;
1071
0
        local_offset += 8;
1072
0
        break;
1073
0
    case PSM_NAK:
1074
0
        local_offset += 4;
1075
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_sdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
1076
0
        local_offset += 8;
1077
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_psn, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
1078
0
        local_offset += 8;
1079
0
        break;
1080
0
    case PSM_ERR_CHK:
1081
0
    case PSM_ERR_CHK_BAD:
1082
0
        local_offset += 4;
1083
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_hostipv4, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
1084
0
        local_offset += 4;
1085
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_hostpid, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
1086
0
        local_offset += 12;
1087
0
        break;
1088
0
    case PSM_ERR_CHK_GEN:
1089
0
        local_offset += 4;
1090
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_rdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
1091
0
        local_offset += 8;
1092
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_sdescid, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
1093
0
        local_offset += 8;
1094
0
        break;
1095
0
    case PSM_FLOW_CCA_BECN:
1096
0
        break;
1097
0
    case PSM_CONNECT_REQUEST:
1098
0
    case PSM_CONNECT_REPLY:
1099
0
    case PSM_DISCONNECT_REQUEST:
1100
0
    case PSM_DISCONNECT_REPLY:
1101
0
        local_offset += 4;
1102
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_paylen, tvb, local_offset, 4, ENC_LITTLE_ENDIAN);
1103
0
        local_offset += 16;
1104
0
        break;
1105
0
    case PSM_AM_REQUEST_NOREPLY:
1106
0
    case PSM_AM_REQUEST:
1107
0
    case PSM_AM_REPLY:
1108
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_dlen, tvb, local_offset + 3, 1, ENC_LITTLE_ENDIAN);
1109
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_nargs, tvb, local_offset + 3, 1, ENC_LITTLE_ENDIAN);
1110
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_hidx, tvb, local_offset + 2, 1, ENC_LITTLE_ENDIAN);
1111
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_msgseq, tvb, local_offset, 2, ENC_LITTLE_ENDIAN);
1112
0
        local_offset += 4;
1113
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_arg, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
1114
0
        local_offset += 8;
1115
0
        proto_tree_add_item(PSM_header_tree, hf_opa_psm_arg, tvb, local_offset, 8, ENC_LITTLE_ENDIAN);
1116
0
        local_offset += 8;
1117
0
        break;
1118
0
    }
1119
0
    *offset = local_offset;
1120
0
}
1121
static void parse_TIDRDMA(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset, int opCode, bool *parsePayload)
1122
0
{
1123
0
    int local_offset = *offset;
1124
0
    proto_item *TIDRDMA_header_item;
1125
0
    proto_tree *TIDRDMA_header_tree;
1126
1127
0
    switch (opCode) {
1128
0
    case TID_RDMA_WRITE_REQUEST:
1129
0
        parse_RETH(tvb, pinfo, tree, &local_offset);
1130
0
        col_append_str(pinfo->cinfo, COL_INFO, "TID RDMA Write Request: ");
1131
0
        TIDRDMA_header_item = proto_tree_add_item(tree, hf_opa_TIDRDMA, tvb, local_offset, 12, ENC_NA);
1132
0
        proto_item_set_text(TIDRDMA_header_item, "TID RDMA Write Request Header");
1133
0
        TIDRDMA_header_tree = proto_item_add_subtree(TIDRDMA_header_item, ett_tidrdma);
1134
1135
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_reserved, tvb, local_offset, 8, ENC_NA);
1136
0
        local_offset += 8;
1137
1138
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1139
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1140
0
        local_offset += 4;
1141
1142
0
        *parsePayload = false;
1143
0
        break;
1144
0
    case TID_RDMA_WRITE_RESPONSE:
1145
0
        parse_AETH(tvb, pinfo, tree, &local_offset);
1146
0
        col_append_str(pinfo->cinfo, COL_INFO, "TID RDMA Write Response: ");
1147
0
        TIDRDMA_header_item = proto_tree_add_item(tree, hf_opa_TIDRDMA, tvb, local_offset, 24, ENC_NA);
1148
0
        proto_item_set_text(TIDRDMA_header_item, "TID RDMA Write Response Header");
1149
0
        TIDRDMA_header_tree = proto_item_add_subtree(TIDRDMA_header_item, ett_tidrdma);
1150
1151
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_reserved, tvb, local_offset, 12, ENC_NA);
1152
0
        local_offset += 12;
1153
1154
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowPSN_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1155
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowPSN, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1156
0
        local_offset += 4;
1157
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1158
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowQP, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1159
0
        local_offset += 4;
1160
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1161
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1162
0
        local_offset += 4;
1163
1164
0
        *parsePayload = false;
1165
0
        break;
1166
0
    case TID_RDMA_WRITE_DATA:
1167
0
        col_append_str(pinfo->cinfo, COL_INFO, "TID RDMA Write Data: ");
1168
0
        TIDRDMA_header_item = proto_tree_add_item(tree, hf_opa_TIDRDMA, tvb, local_offset, 28, ENC_NA);
1169
0
        proto_item_set_text(TIDRDMA_header_item, "TID RDMA Write Data Header");
1170
0
        TIDRDMA_header_tree = proto_item_add_subtree(TIDRDMA_header_item, ett_tidrdma);
1171
1172
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_reserved, tvb, local_offset, 24, ENC_NA);
1173
0
        local_offset += 24;
1174
1175
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1176
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1177
0
        local_offset += 4;
1178
1179
0
        *parsePayload = true;
1180
0
        break;
1181
0
    case TID_RDMA_WRITE_DATA_LAST:
1182
0
        col_append_str(pinfo->cinfo, COL_INFO, "TID RDMA Write Data Last: ");
1183
0
        TIDRDMA_header_item = proto_tree_add_item(tree, hf_opa_TIDRDMA, tvb, local_offset, 28, ENC_NA);
1184
0
        proto_item_set_text(TIDRDMA_header_item, "TID RDMA Write Data Last Header");
1185
0
        TIDRDMA_header_tree = proto_item_add_subtree(TIDRDMA_header_item, ett_tidrdma);
1186
1187
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_reserved, tvb, local_offset, 24, ENC_NA);
1188
0
        local_offset += 24;
1189
1190
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1191
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1192
0
        local_offset += 4;
1193
1194
0
        *parsePayload = true;
1195
0
        break;
1196
0
    case TID_RDMA_READ_REQUEST:
1197
0
        parse_RETH(tvb, pinfo, tree, &local_offset);
1198
0
        col_append_str(pinfo->cinfo, COL_INFO, "TID RDMA Read Request: ");
1199
0
        TIDRDMA_header_item = proto_tree_add_item(tree, hf_opa_TIDRDMA, tvb, local_offset, 12, ENC_NA);
1200
0
        proto_item_set_text(TIDRDMA_header_item, "TID RDMA Read Request Header");
1201
0
        TIDRDMA_header_tree = proto_item_add_subtree(TIDRDMA_header_item, ett_tidrdma);
1202
1203
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowPSN_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1204
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowPSN, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1205
0
        local_offset += 4;
1206
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1207
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowQP, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1208
0
        local_offset += 4;
1209
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1210
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1211
0
        local_offset += 4;
1212
1213
0
        *parsePayload = false;
1214
0
        break;
1215
0
    case TID_RDMA_READ_RESPONSE:
1216
0
        parse_AETH(tvb, pinfo, tree, &local_offset);
1217
0
        col_append_str(pinfo->cinfo, COL_INFO, "TID RDMA Read Response: ");
1218
0
        TIDRDMA_header_item = proto_tree_add_item(tree, hf_opa_TIDRDMA, tvb, local_offset, 24, ENC_NA);
1219
0
        proto_item_set_text(TIDRDMA_header_item, "TID RDMA Read Response Header");
1220
0
        TIDRDMA_header_tree = proto_item_add_subtree(TIDRDMA_header_item, ett_tidrdma);
1221
1222
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_reserved, tvb, local_offset, 16, ENC_NA);
1223
0
        local_offset += 16;
1224
1225
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsPSN_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1226
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsPSN, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1227
0
        local_offset += 4;
1228
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1229
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1230
0
        local_offset += 4;
1231
1232
0
        *parsePayload = true;
1233
0
        break;
1234
0
    case TID_RDMA_RESYNC:
1235
0
        col_append_str(pinfo->cinfo, COL_INFO, "TID RDMA Read ReSync: ");
1236
0
        TIDRDMA_header_item = proto_tree_add_item(tree, hf_opa_TIDRDMA, tvb, local_offset, 28, ENC_NA);
1237
0
        proto_item_set_text(TIDRDMA_header_item, "TID RDMA Read ReSync Header");
1238
0
        TIDRDMA_header_tree = proto_item_add_subtree(TIDRDMA_header_item, ett_tidrdma);
1239
1240
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_reserved, tvb, local_offset, 24, ENC_NA);
1241
0
        local_offset += 24;
1242
1243
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1244
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1245
0
        local_offset += 4;
1246
1247
0
        *parsePayload = false;
1248
0
        break;
1249
0
    case TID_RDMA_ACK:
1250
0
        parse_AETH(tvb, pinfo, tree, &local_offset);
1251
0
        col_append_str(pinfo->cinfo, COL_INFO, "TID RDMA ACK: ");
1252
0
        TIDRDMA_header_item = proto_tree_add_item(tree, hf_opa_TIDRDMA, tvb, local_offset, 24, ENC_NA);
1253
0
        proto_item_set_text(TIDRDMA_header_item, "TID RDMA ACK Header");
1254
0
        TIDRDMA_header_tree = proto_item_add_subtree(TIDRDMA_header_item, ett_tidrdma);
1255
1256
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_reserved, tvb, local_offset, 8, ENC_NA);
1257
0
        local_offset += 8;
1258
1259
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowPSN_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1260
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowPSN, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1261
0
        local_offset += 4;
1262
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsPSN_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1263
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsPSN, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1264
0
        local_offset += 4;
1265
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1266
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_TIDFlowQP, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1267
0
        local_offset += 4;
1268
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP_reserved, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1269
0
        proto_tree_add_item(TIDRDMA_header_tree, hf_opa_TIDRDMA_VerbsQP, tvb, local_offset, 4, ENC_BIG_ENDIAN);
1270
0
        local_offset += 4;
1271
1272
0
        *parsePayload = false;
1273
0
        break;
1274
0
    default:
1275
0
        *parsePayload = false;
1276
0
    }
1277
0
    *offset = local_offset;
1278
0
}
1279
static void parse_IPvSix(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset)
1280
0
{
1281
0
    call_dissector(ipv6_handle, tvb_new_subset_remaining(tvb, *offset), pinfo, tree);
1282
0
    *offset = tvb_reported_length(tvb);
1283
0
}
1284
1285
static int dissect_opa_9b(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1286
0
{
1287
0
    proto_item *opa_packet;
1288
1289
    /* TVB to pass to opa header */
1290
0
    tvbuff_t *opa_tvb;
1291
    /* TVB to pass to infiniband header */
1292
0
    tvbuff_t *infiniband_tvb;
1293
1294
0
    int offset = 0;    /* Current Offset */
1295
0
    int ib_offset = 0; /* Offset to track if IB packet */
1296
0
    int reported_length;
1297
0
    uint8_t lnh_val = 0;
1298
0
    bool bthFollows = false;
1299
0
    bool parsePayload = false;
1300
0
    int32_t nextHeaderSequence = -1;
1301
0
    uint8_t nextHdr = 0, opCode = 0;
1302
0
    uint8_t baseVersion = 0;
1303
1304
    /* Infiniband Check */
1305
0
    lnh_val = tvb_get_uint8(tvb, ib_offset + 1) & 0x3;
1306
0
    if (lnh_val == 3) {
1307
0
        nextHdr = tvb_get_uint8(tvb, ib_offset + 6);
1308
0
        ib_offset += 40;
1309
0
    }
1310
0
    if (lnh_val == 2 || nextHdr == 0x1B) {
1311
0
        opCode = tvb_get_uint8(tvb, ib_offset + 8);
1312
0
        if (opCode == 0x64) {
1313
0
            baseVersion = tvb_get_uint8(tvb, ib_offset + 28);
1314
0
            if (baseVersion == 0x01) {
1315
0
                infiniband_tvb = tvb_new_subset_remaining(tvb, offset);
1316
0
                call_dissector(infiniband_handle, infiniband_tvb, pinfo, tree);
1317
0
                return tvb_captured_length(tvb);
1318
0
            }
1319
0
        }
1320
0
    }
1321
1322
0
    tree = proto_tree_get_parent_tree(tree);
1323
1324
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Omni-Path");
1325
0
    col_clear(pinfo->cinfo, COL_INFO);
1326
1327
0
    pinfo->srcport = pinfo->destport = 0xffffffff;
1328
1329
0
    opa_packet = proto_tree_add_item(tree, proto_opa_9b, tvb, offset, -1, ENC_NA);
1330
1331
    /* Headers Level Tree */
1332
0
    tree = proto_item_add_subtree(opa_packet, ett_all_headers);
1333
0
    parse_opa_9B_Header(tvb, pinfo, tree, &offset, &lnh_val);
1334
1335
0
    switch (lnh_val) {
1336
0
    case 3: /* GLOBAL - GRH - Global Route Header */
1337
0
        parse_opa_grh(tvb, pinfo, tree, &offset, &nextHdr);
1338
0
        if (nextHdr != 0x1B) {   /* no BTH following. */
1339
0
            break;
1340
0
        }
1341
        /* FALL THROUGH */
1342
0
    case 2: /* LOCAL - BTH - Base Transport Header */
1343
0
        parse_opa_bth(tvb, pinfo, tree, &offset, &opCode);
1344
0
        bthFollows = true;
1345
0
        break;
1346
0
    case 1: /* NON OPA - IPv6 Packet */
1347
0
        set_address(&pinfo->dst, AT_STRINGZ, (int)strlen("IPv6 over OPA Packet") + 1,
1348
0
            wmem_strdup(pinfo->pool, "IPv6 over OPA Packet"));
1349
1350
0
        parse_IPvSix(tvb, pinfo, tree, &offset);
1351
1352
0
        break;
1353
0
    case 0: /* RAW */
1354
1355
0
        break;
1356
0
    default:
1357
0
        break;
1358
0
    }
1359
1360
0
    if (bthFollows) {
1361
        /* Save transport type for identifying EoOPA payloads later */
1362
0
        nextHeaderSequence = find_next_header_sequence((uint32_t)opCode);
1363
0
        switch (nextHeaderSequence) {
1364
0
        case RDETH_DETH_PAYLD:
1365
0
            parse_RDETH(tvb, pinfo, tree, &offset);
1366
0
            parse_DETH(tvb, pinfo, tree, &offset);
1367
1368
0
            parsePayload = true;
1369
0
            break;
1370
0
        case RDETH_DETH_RETH_PAYLD:
1371
0
            parse_RDETH(tvb, pinfo, tree, &offset);
1372
0
            parse_DETH(tvb, pinfo, tree, &offset);
1373
0
            parse_RETH(tvb, pinfo, tree, &offset);
1374
1375
0
            parsePayload = true;
1376
0
            break;
1377
0
        case RDETH_DETH_IMMDT_PAYLD:
1378
0
            parse_RDETH(tvb, pinfo, tree, &offset);
1379
0
            parse_DETH(tvb, pinfo, tree, &offset);
1380
0
            parse_IMMDT(tvb, pinfo, tree, &offset);
1381
1382
0
            parsePayload = true;
1383
0
            break;
1384
0
        case RDETH_DETH_RETH_IMMDT_PAYLD:
1385
0
            parse_RDETH(tvb, pinfo, tree, &offset);
1386
0
            parse_DETH(tvb, pinfo, tree, &offset);
1387
0
            parse_RETH(tvb, pinfo, tree, &offset);
1388
0
            parse_IMMDT(tvb, pinfo, tree, &offset);
1389
1390
0
            parsePayload = true;
1391
0
            break;
1392
0
        case RDETH_DETH_RETH:
1393
0
            parse_RDETH(tvb, pinfo, tree, &offset);
1394
0
            parse_DETH(tvb, pinfo, tree, &offset);
1395
0
            parse_RETH(tvb, pinfo, tree, &offset);
1396
1397
0
            break;
1398
0
        case RDETH_AETH_PAYLD:
1399
0
            parse_RDETH(tvb, pinfo, tree, &offset);
1400
0
            parse_AETH(tvb, pinfo, tree, &offset);
1401
1402
0
            parsePayload = true;
1403
0
            break;
1404
0
        case RDETH_PAYLD:
1405
0
            parse_RDETH(tvb, pinfo, tree, &offset);
1406
1407
0
            parsePayload = true;
1408
0
            break;
1409
0
        case RDETH_AETH:
1410
0
            parse_AETH(tvb, pinfo, tree, &offset);
1411
1412
0
            break;
1413
0
        case RDETH_AETH_ATOMICACKETH:
1414
0
            parse_RDETH(tvb, pinfo, tree, &offset);
1415
0
            parse_AETH(tvb, pinfo, tree, &offset);
1416
0
            parse_ATOMICACKETH(tvb, pinfo, tree, &offset);
1417
1418
0
            break;
1419
0
        case RDETH_DETH_ATOMICETH:
1420
0
            parse_RDETH(tvb, pinfo, tree, &offset);
1421
0
            parse_DETH(tvb, pinfo, tree, &offset);
1422
0
            parse_ATOMICETH(tvb, pinfo, tree, &offset);
1423
1424
0
            break;
1425
0
        case RDETH_DETH:
1426
0
            parse_RDETH(tvb, pinfo, tree, &offset);
1427
0
            parse_DETH(tvb, pinfo, tree, &offset);
1428
1429
0
            break;
1430
0
        case DETH_PAYLD:
1431
0
            parse_DETH(tvb, pinfo, tree, &offset);
1432
1433
0
            parsePayload = true;
1434
0
            break;
1435
0
        case PAYLD:
1436
1437
0
            parsePayload = true;
1438
0
            break;
1439
0
        case IMMDT_PAYLD:
1440
0
            parse_IMMDT(tvb, pinfo, tree, &offset);
1441
1442
0
            parsePayload = true;
1443
0
            break;
1444
0
        case RETH_PAYLD:
1445
0
            parse_RETH(tvb, pinfo, tree, &offset);
1446
1447
0
            parsePayload = true;
1448
0
            break;
1449
0
        case RETH:
1450
0
            parse_RETH(tvb, pinfo, tree, &offset);
1451
1452
0
            break;
1453
0
        case AETH_PAYLD:
1454
0
            parse_AETH(tvb, pinfo, tree, &offset);
1455
1456
0
            parsePayload = true;
1457
0
            break;
1458
0
        case AETH:
1459
0
            parse_AETH(tvb, pinfo, tree, &offset);
1460
1461
0
            break;
1462
0
        case AETH_ATOMICACKETH:
1463
0
            parse_AETH(tvb, pinfo, tree, &offset);
1464
0
            parse_ATOMICACKETH(tvb, pinfo, tree, &offset);
1465
1466
0
            break;
1467
0
        case ATOMICETH:
1468
0
            parse_ATOMICETH(tvb, pinfo, tree, &offset);
1469
1470
0
            break;
1471
0
        case IETH_PAYLD:
1472
0
            parse_IETH(tvb, pinfo, tree, &offset);
1473
1474
0
            parsePayload = true;
1475
0
            break;
1476
0
        case DETH_IMMDT_PAYLD:
1477
0
            parse_DETH(tvb, pinfo, tree, &offset);
1478
0
            parse_IMMDT(tvb, pinfo, tree, &offset);
1479
1480
0
            parsePayload = true;
1481
0
            break;
1482
0
        case KDETH_PSM:
1483
0
            parse_KDETH(tvb, pinfo, tree, &offset);
1484
0
            parse_PSM(tvb, pinfo, tree, &offset, opCode);
1485
1486
0
            break;
1487
0
        case KDETH_TIDRDMA:
1488
0
            parse_KDETH(tvb, pinfo, tree, &offset);
1489
0
            parse_TIDRDMA(tvb, pinfo, tree, &offset, opCode, &parsePayload);
1490
1491
0
            break;
1492
0
        default:
1493
0
            break;
1494
1495
0
        } /* END: switch (nextHeaderSequence) */
1496
1497
0
        if (parsePayload) {
1498
            /* Pass to OPA MAD dissector */
1499
0
            reported_length = tvb_reported_length_remaining(tvb, offset);
1500
1501
0
            if (reported_length >= 4)
1502
0
                reported_length -= 4;
1503
1504
0
            if (reported_length > 0) {
1505
0
                opa_tvb = tvb_new_subset_length(tvb, offset, reported_length);
1506
0
                call_dissector(opa_mad_handle, opa_tvb, pinfo, tree);
1507
0
                offset += reported_length;
1508
0
            }
1509
0
        }
1510
0
    } /* END: if(bthFollows) */
1511
1512
    /* Display the ICRC */
1513
0
    reported_length = tvb_reported_length_remaining(tvb, offset);
1514
0
    if (reported_length != 4) {
1515
0
        offset += reported_length - 4;
1516
0
    }
1517
0
    proto_tree_add_item(tree, hf_opa_9b_ICRC, tvb, offset, 4, ENC_BIG_ENDIAN);
1518
0
    offset += 4;
1519
0
    return offset;
1520
0
}
1521
void proto_register_opa_9b(void)
1522
15
{
1523
15
    static hf_register_info hf[] = {
1524
        /* L2Header(9B) */
1525
15
        { &hf_opa_9B, {
1526
15
                "Omni-Path 9B Header", "opa.9b",
1527
15
                FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1528
15
        },
1529
15
        { &hf_opa_9B_service_channel, {
1530
15
                "Service Channel", "opa.9b.sc",
1531
15
                FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
1532
15
        },
1533
15
        { &hf_opa_9B_link_version, {
1534
15
                "Link Version", "opa.9b.linkversion",
1535
15
                FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
1536
15
        },
1537
15
        { &hf_opa_9B_service_level, {
1538
15
                "Service Level", "opa.9b.sl",
1539
15
                FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
1540
15
        },
1541
15
        { &hf_opa_9B_reserved2, {
1542
15
                "Reserved (2 bits)", "opa.9b.reserved2",
1543
15
                FT_UINT8, BASE_HEX, NULL, 0x0C, NULL, HFILL }
1544
15
        },
1545
15
        { &hf_opa_9B_lnh, {
1546
15
                "Link Next Header", "opa.9b.lnh",
1547
15
                FT_UINT8, BASE_DEC, VALS(vals_opa_9b_lnh), 0x03, NULL, HFILL }
1548
15
        },
1549
15
        { &hf_opa_9B_dlid, {
1550
15
                "Dest LID", "opa.9b.dlid",
1551
15
                FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1552
15
        },
1553
15
        { &hf_opa_9B_reserved3, {
1554
15
                "Reserved (4 bits)", "opa.9b.reserved3",
1555
15
                FT_UINT16, BASE_HEX, NULL, 0xF000, NULL, HFILL }
1556
15
        },
1557
15
        { &hf_opa_9B_packet_length, {
1558
15
                "Packet Length", "opa.length",
1559
15
                FT_UINT16, BASE_CUSTOM, CF_FUNC(cf_opa_dw_to_b), 0x0FFF, NULL, HFILL }
1560
15
        },
1561
15
        { &hf_opa_9B_slid, {
1562
15
                "Source LID", "opa.9b.slid",
1563
15
                FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1564
15
        },
1565
15
        { &hf_opa_9b_ICRC, {
1566
15
                "Invariant CRC", "opa.9b.icrc",
1567
15
                FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1568
15
        },
1569
1570
        /* Global Route Header */
1571
15
        { &hf_opa_grh, {
1572
15
                "GRH - Global Route Header", "opa.grh",
1573
15
                FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1574
15
        },
1575
15
        { &hf_opa_grh_ip_version, {
1576
15
                "IP Version", "opa.grh.ipver",
1577
15
                FT_UINT8, BASE_DEC, VALS(vals_opa_9b_grh_ipver), 0xF0, NULL, HFILL }
1578
15
        },
1579
15
        { &hf_opa_grh_traffic_class, {
1580
15
                "Traffic Class", "opa.grh.tclass",
1581
15
                FT_UINT16, BASE_DEC, NULL, 0x0FF0, NULL, HFILL }
1582
15
        },
1583
15
        { &hf_opa_grh_flow_label, {
1584
15
                "Flow Label", "opa.grh.flowlabel",
1585
15
                FT_UINT32, BASE_DEC, NULL, 0x000FFFFF, NULL, HFILL }
1586
15
        },
1587
15
        { &hf_opa_grh_payload_length, {
1588
15
                "Payload Length", "opa.grh.paylen",
1589
15
                FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1590
15
        },
1591
15
        { &hf_opa_grh_next_header, {
1592
15
                "Next Header", "opa.grh.nxthdr",
1593
15
                FT_UINT8, BASE_DEC, VALS(vals_opa_9b_grh_next_hdr), 0x0, NULL, HFILL }
1594
15
        },
1595
15
        { &hf_opa_grh_hop_limit, {
1596
15
                "Hop Limit", "opa.grh.hoplmt",
1597
15
                FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1598
15
        },
1599
15
        { &hf_opa_grh_source_gid, {
1600
15
                "Source GID", "opa.grh.sgid",
1601
15
                FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }
1602
15
        },
1603
15
        { &hf_opa_grh_destination_gid, {
1604
15
                "Destination GID", "opa.grh.dgid",
1605
15
                FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }
1606
15
        },
1607
1608
        /* Base Transport Header */
1609
15
        { &hf_opa_bth, {
1610
15
                "BTH - Base Transport Header", "opa.bth",
1611
15
                FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1612
15
        },
1613
15
        { &hf_opa_bth_opcode, {
1614
15
                "Opcode", "opa.bth.opcode",
1615
15
                FT_UINT8, BASE_HEX, VALS(vals_opa_bth_opcode), 0x0, NULL, HFILL }
1616
15
        },
1617
15
        { &hf_opa_bth_solicited_event, {
1618
15
                "Solicited Event", "opa.bth.se",
1619
15
                FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80, NULL, HFILL }
1620
15
        },
1621
15
        { &hf_opa_bth_migreq, {
1622
15
                "MigReq", "opa.bth.m",
1623
15
                FT_BOOLEAN, 8, TFS(&tfs_opa_bth_migrated_notmigrated), 0x40, NULL, HFILL }
1624
15
        },
1625
15
        { &hf_opa_bth_pad_count, {
1626
15
                "Pad Count", "opa.bth.padcnt",
1627
15
                FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL }
1628
15
        },
1629
15
        { &hf_opa_bth_transport_header_version, {
1630
15
                "Header Version", "opa.bth.tver",
1631
15
                FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
1632
15
        },
1633
15
        { &hf_opa_bth_partition_key, {
1634
15
                "Partition Key", "opa.bth.p_key",
1635
15
                FT_UINT16, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }
1636
15
        },
1637
15
        { &hf_opa_bth_fcn, {
1638
15
                "FCN", "opa.bth.fcn",
1639
15
                FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80, NULL, HFILL }
1640
15
        },
1641
15
        { &hf_opa_bth_bcn, {
1642
15
                "BCN", "opa.bth.bcn",
1643
15
                FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40, NULL, HFILL }
1644
15
        },
1645
15
        { &hf_opa_bth_Reserved8a, {
1646
15
                "Reserved (6 bits)", "opa.bth.reserved8a",
1647
15
                FT_UINT8, BASE_HEX, NULL, 0x3F, NULL, HFILL }
1648
15
        },
1649
15
        { &hf_opa_bth_destination_qp, {
1650
15
                "Destination Queue Pair", "opa.bth.destqp",
1651
15
                FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL }
1652
15
        },
1653
15
        { &hf_opa_bth_acknowledge_request, {
1654
15
                "Acknowledge Request", "opa.bth.a",
1655
15
                FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80, NULL, HFILL }
1656
15
        },
1657
15
        { &hf_opa_bth_packet_sequence_number, {
1658
15
                "Packet Sequence Number", "opa.bth.psn",
1659
15
                FT_UINT32, BASE_DEC, NULL, 0x7FFFFFFF, NULL, HFILL }
1660
15
        },
1661
1662
        /* Reliable Datagram Extended Transport Header (RDETH) */
1663
15
        { &hf_opa_RDETH, {
1664
15
                "RDETH - Reliable Datagram Extended Transport Header", "opa.rdeth",
1665
15
                FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1666
15
        },
1667
15
        { &hf_opa_RDETH_reserved8, {
1668
15
                "Reserved (8 bits)", "opa.rdeth.reserved",
1669
15
                FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1670
15
        },
1671
15
        { &hf_opa_RDETH_ee_context, {
1672
15
                "EE Context", "opa.rdeth.eecnxt",
1673
15
                FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL }
1674
15
        },
1675
1676
        /* Datagram Extended Transport Header (DETH) */
1677
15
        { &hf_opa_DETH, {
1678
15
                "DETH - Datagram Extended Transport Header", "opa.deth",
1679
15
                FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1680
15
        },
1681
15
        { &hf_opa_DETH_queue_key, {
1682
15
                "Queue Key", "opa.deth.q_key",
1683
15
                FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1684
15
        },
1685
15
        { &hf_opa_DETH_reserved8, {
1686
15
                "Reserved (8 bits)", "opa.deth.reserved",
1687
15
                FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1688
15
        },
1689
15
        { &hf_opa_DETH_source_qp, {
1690
15
                "Source Queue Pair", "opa.deth.srcqp",
1691
15
                FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL }
1692
15
        },
1693
1694
        /* RDMA Extended Transport Header (RETH) */
1695
15
        { &hf_opa_RETH, {
1696
15
                "RETH - RDMA Extended Transport Header", "opa.reth",
1697
15
                FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1698
15
        },
1699
15
        { &hf_opa_RETH_virtual_address, {
1700
15
                "Virtual Address", "opa.reth.va",
1701
15
                FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
1702
15
        },
1703
15
        { &hf_opa_RETH_remote_key, {
1704
15
                "Remote Key", "opa.reth.r_key",
1705
15
                FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1706
15
        },
1707
15
        { &hf_opa_RETH_dma_length, {
1708
15
                "DMA Length", "opa.reth.dmalen",
1709
15
                FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1710
15
        },
1711
1712
        /* Atomic Extended Transport Header (AtomicETH) */
1713
15
        { &hf_opa_AtomicETH, {
1714
15
                "AtomicETH - Atomic Extended Transport Header", "opa.atomiceth",
1715
15
                FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1716
15
        },
1717
15
        { &hf_opa_AtomicETH_virtual_address, {
1718
15
                "Virtual Address", "opa.atomiceth.va",
1719
15
                FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }
1720
15
        },
1721
15
        { &hf_opa_AtomicETH_remote_key, {
1722
15
                "Remote Key", "opa.atomiceth.r_key",
1723
15
                FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1724
15
        },
1725
15
        { &hf_opa_AtomicETH_swap_or_add_data, {
1726
15
                "Swap (Or Add) Data", "opa.atomiceth.swapdt",
1727
15
                FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }
1728
15
        },
1729
15
        { &hf_opa_AtomicETH_compare_data, {
1730
15
                "Compare Data", "opa.atomiceth.cmpdt",
1731
15
                FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }
1732
15
        },
1733
1734
        /* ACK Extended Transport Header (AETH) */
1735
15
        { &hf_opa_AETH, {
1736
15
                "AETH - ACK Extended Transport Header", "opa.aeth",
1737
15
                FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1738
15
        },
1739
15
        { &hf_opa_AETH_syndrome, {
1740
15
                "Syndrome", "opa.aeth.syndrome",
1741
15
                FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1742
15
        },
1743
15
        { &hf_opa_AETH_message_sequence_number, {
1744
15
                "Message Sequence Number", "opa.aeth.msn",
1745
15
                FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL }
1746
15
        },
1747
1748
        /* Atomic ACK Extended Transport Header (AtomicAckETH) */
1749
15
        { &hf_opa_AtomicAckETH, {
1750
15
                "AtomicAckETH - Atomic ACK Extended Transport Header", "opa.atomicacketh",
1751
15
                FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1752
15
        },
1753
15
        { &hf_opa_AtomicAckETH_original_remote_data, {
1754
15
                "Original Remote Data", "opa.atomicacketh.origremdt",
1755
15
                FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }
1756
15
        },
1757
1758
        /* Immediate Extended Transport Header (ImmDT) */
1759
15
        { &hf_opa_IMMDT, {
1760
15
                "IMMDT - Immediate Extended Transport Header", "opa.immdt",
1761
15
                FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1762
15
        },
1763
15
        { &hf_opa_IMMDT_data, {
1764
15
                "Immediate Data", "opa.immdt.data",
1765
15
                FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1766
15
        },
1767
1768
        /* Invalidate Extended Transport Header (IETH) */
1769
15
        { &hf_opa_IETH, {
1770
15
                "IETH - Invalidate Extended Transport Header", "opa.ieth",
1771
15
                FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1772
15
        },
1773
15
        { &hf_opa_IETH_r_key, {
1774
15
                "RKey", "opa.ieth.r_key",
1775
15
                FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1776
15
        },
1777
1778
        /* Key Datagram Extended Transport Header (KDETH) */
1779
15
        { &hf_opa_KDETH, {
1780
15
                "KDETH - Key Datagram Extended Transport Header", "opa.kdeth",
1781
15
                FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1782
15
        },
1783
15
        { &hf_opa_KDETH_kver, {
1784
15
                "KDETH Version Field", "opa.kdeth.kver",
1785
15
                FT_UINT32, BASE_HEX, NULL, 0xC0000000, NULL, HFILL }
1786
15
        },
1787
15
        { &hf_opa_KDETH_sh, {
1788
15
                "SuppressHeader", "opa.kdeth.sh",
1789
15
                FT_BOOLEAN, 32, NULL, 0x20000000, NULL, HFILL }
1790
15
        },
1791
15
        { &hf_opa_KDETH_intr, {
1792
15
                "InterruptBit", "opa.kdeth.intr",
1793
15
                FT_BOOLEAN, 32, NULL, 0x10000000, NULL, HFILL }
1794
15
        },
1795
15
        { &hf_opa_KDETH_tidctrl, {
1796
15
                "TokenIDCtrl", "opa.kdeth.tidctrl",
1797
15
                FT_UINT32, BASE_HEX, NULL, 0x0C000000, NULL, HFILL }
1798
15
        },
1799
15
        { &hf_opa_KDETH_tid, {
1800
15
                "TokenID", "opa.kdeth.tid",
1801
15
                FT_UINT32, BASE_HEX, NULL, 0x03FF0000, NULL, HFILL }
1802
15
        },
1803
15
        { &hf_opa_KDETH_offset_mode, {
1804
15
                "Offset Mode", "opa.kdeth.offsetmode",
1805
15
                FT_BOOLEAN, 32, TFS(&tfs_opa_kdeth_offset_32_64), 0x00008000, NULL, HFILL }
1806
15
        },
1807
15
        { &hf_opa_KDETH_offset, {
1808
15
                "Offset", "opa.kdeth.offset",
1809
15
                FT_UINT32, BASE_HEX, NULL, 0x00007FFF, NULL, HFILL }
1810
15
        },
1811
15
        { &hf_opa_KDETH_hcrc, {
1812
15
                "HCRC", "opa.kdeth.hcrc",
1813
15
                FT_UINT32, BASE_HEX, NULL, 0xFFFF0000, NULL, HFILL }
1814
15
        },
1815
15
        { &hf_opa_KDETH_j_key, {
1816
15
                "J_Key", "opa.kdeth.j_key",
1817
15
                FT_UINT32, BASE_HEX, NULL, 0x0000FFFF, NULL, HFILL }
1818
15
        },
1819
1820
        /* PSM */
1821
15
        { &hf_opa_psm, {
1822
15
                "PSM Header", "opa.psm",
1823
15
                FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1824
15
        },
1825
15
        { &hf_opa_psm_a, {
1826
15
                "ACKFlag", "opa.psm.a",
1827
15
                FT_UINT8, BASE_HEX, NULL, 0x80, NULL, HFILL }
1828
15
        },
1829
15
        { &hf_opa_psm_ackpsn, {
1830
15
                "ACKPSN", "opa.psm.ackpsn",
1831
15
                FT_UINT32, BASE_DEC, NULL, 0x7FFF, NULL, HFILL }
1832
15
        },
1833
15
        { &hf_opa_psm_flags, {
1834
15
                "Flags", "opa.psm.flags",
1835
15
                FT_UINT8, BASE_DEC, NULL, 0xFC, NULL, HFILL }
1836
15
        },
1837
15
        { &hf_opa_psm_commidx, {
1838
15
                "CommIdx", "opa.psm.commidx",
1839
15
                FT_UINT32, BASE_HEX, NULL, 0x3FFF, NULL, HFILL }
1840
15
        },
1841
15
        { &hf_opa_psm_flowid, {
1842
15
                "FlowId", "opa.psm.flowid",
1843
15
                FT_UINT8, BASE_HEX, NULL, 0x80, NULL, HFILL }
1844
15
        },
1845
        /* PSM opcode specific */
1846
15
        { &hf_opa_psm_msglen, {
1847
15
                "MsgLen", "opa.psm.msglen",
1848
15
                FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1849
15
        },
1850
15
        { &hf_opa_psm_msgseq, {
1851
15
                "MsqSeq", "opa.psm.msgseq",
1852
15
                FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
1853
15
        },
1854
15
        { &hf_opa_psm_tag, {
1855
15
                "Tag", "opa.psm.tag",
1856
15
                FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
1857
15
        },
1858
15
        { &hf_opa_psm_msgdata, {
1859
15
                "MsqData", "opa.psm.msgdata",
1860
15
                FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
1861
15
        },
1862
15
        { &hf_opa_psm_short_msglen, {
1863
15
                "MsgLen", "opa.psm.short.msglen",
1864
15
                FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1865
15
        },
1866
15
        { &hf_opa_psm_paylen, {
1867
15
                "PayLen", "opa.psm.paylen",
1868
15
                FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1869
15
        },
1870
15
        { &hf_opa_psm_offset, {
1871
15
                "Offset", "opa.psm.offset",
1872
15
                FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1873
15
        },
1874
15
        { &hf_opa_psm_sreqidx, {
1875
15
                "SreqIdx", "opa.psm.sreqidx",
1876
15
                FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1877
15
        },
1878
15
        { &hf_opa_psm_rreqidx, {
1879
15
                "RreqIdx", "opa.psm.rreqidx",
1880
15
                FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1881
15
        },
1882
15
        { &hf_opa_psm_rdescid, {
1883
15
                "RdescId", "opa.psm.rdescid",
1884
15
                FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
1885
15
        },
1886
15
        { &hf_opa_psm_sdescid, {
1887
15
                "SdescId", "opa.psm.sdescid",
1888
15
                FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
1889
15
        },
1890
15
        { &hf_opa_psm_psn, {
1891
15
                "PSN", "opa.psm.psn",
1892
15
                FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1893
15
        },
1894
15
        { &hf_opa_psm_hostipv4, {
1895
15
                "HostIPv4Addr", "opa.psm.hostipv4",
1896
15
                FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }
1897
15
        },
1898
15
        { &hf_opa_psm_hostpid, {
1899
15
                "HostPid", "opa.psm.hostpid",
1900
15
                FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1901
15
        },
1902
15
        { &hf_opa_psm_dlen, {
1903
15
                "Datalength", "opa.psm.dlen",
1904
15
                FT_UINT8, BASE_DEC, NULL, 0x38, NULL, HFILL }
1905
15
        },
1906
15
        { &hf_opa_psm_nargs, {
1907
15
                "NumberArgs", "opa.psm.nargs",
1908
15
                FT_UINT32, BASE_DEC, NULL, 0x07, NULL, HFILL }
1909
15
        },
1910
15
        { &hf_opa_psm_hidx, {
1911
15
                "HandlerIndex", "opa.psm.hidx",
1912
15
                FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1913
15
        },
1914
15
        { &hf_opa_psm_arg, {
1915
15
                "Argument", "opa.psm.arg",
1916
15
                FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
1917
15
        },
1918
15
        { &hf_opa_psm_payload, {
1919
15
                "Payload", "opa.psm.payload",
1920
15
                FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1921
15
        },
1922
15
        { &hf_opa_TIDRDMA, {
1923
15
                "TID RDMA Header", "opa.tidrdma",
1924
15
                FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1925
15
        },
1926
15
        { &hf_opa_TIDRDMA_reserved, {
1927
15
                "Reserved", "opa.tidrdma.reserved",
1928
15
                FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
1929
15
        },
1930
15
        { &hf_opa_TIDRDMA_TIDFlowPSN_reserved, {
1931
15
                "Reserved (1 bit)", "opa.tidrdma.tidflowpsn.reserved",
1932
15
                FT_UINT32, BASE_HEX, NULL, 0x80000000, NULL, HFILL }
1933
15
        },
1934
15
        { &hf_opa_TIDRDMA_TIDFlowPSN, {
1935
15
                "TID Flow PSN", "opa.tidrdma.tidflowpsn",
1936
15
                FT_UINT32, BASE_HEX, NULL, 0x7FFFFFFF, NULL, HFILL }
1937
15
        },
1938
15
        { &hf_opa_TIDRDMA_TIDFlowQP_reserved, {
1939
15
                "Reserved (8 bits)", "opa.tidrdma.tidflowqp.reserved",
1940
15
                FT_UINT32, BASE_HEX, NULL, 0xFF000000, NULL, HFILL }
1941
15
        },
1942
15
        { &hf_opa_TIDRDMA_TIDFlowQP, {
1943
15
                "TID Flow QP", "opa.tidrdma.tidflowqp",
1944
15
                FT_UINT32, BASE_HEX, NULL, 0x00FFFFFF, NULL, HFILL }
1945
15
        },
1946
15
        { &hf_opa_TIDRDMA_VerbsPSN_reserved, {
1947
15
                "Reserved (1 bit)", "opa.tidrdma.verbspsn.reserved",
1948
15
                FT_UINT32, BASE_HEX, NULL, 0x80000000, NULL, HFILL }
1949
15
        },
1950
15
        { &hf_opa_TIDRDMA_VerbsPSN, {
1951
15
                "Verbs PSN", "opa.tidrdma.verbspsn",
1952
15
                FT_UINT32, BASE_HEX, NULL, 0x7FFFFFFF, NULL, HFILL }
1953
15
        },
1954
15
        { &hf_opa_TIDRDMA_VerbsQP_reserved, {
1955
15
                "Reserved (8 bits)", "opa.tidrdma.verbsqp.reserved",
1956
15
                FT_UINT32, BASE_HEX, NULL, 0xFF000000, NULL, HFILL }
1957
15
        },
1958
15
        { &hf_opa_TIDRDMA_VerbsQP, {
1959
15
                "Verbs QP", "opa.tidrdma.verbsqp",
1960
15
                FT_UINT32, BASE_HEX, NULL, 0x00FFFFFF, NULL, HFILL }
1961
15
        }
1962
15
    };
1963
1964
15
    static int *ett[] = {
1965
15
        &ett_all_headers,
1966
15
        &ett_9b,
1967
15
        &ett_grh,
1968
15
        &ett_bth,
1969
15
        &ett_rdeth,
1970
15
        &ett_deth,
1971
15
        &ett_reth,
1972
15
        &ett_atomiceth,
1973
15
        &ett_aeth,
1974
15
        &ett_atomicacketh,
1975
15
        &ett_immdt,
1976
15
        &ett_ieth,
1977
15
        &ett_kdeth,
1978
15
        &ett_psm,
1979
15
        &ett_tidrdma
1980
15
    };
1981
1982
15
    proto_opa_9b = proto_register_protocol("Intel Omni-Path", "OPA", "opa");
1983
15
    opa_9b_handle = register_dissector("opa", dissect_opa_9b, proto_opa_9b);
1984
1985
15
    proto_register_field_array(proto_opa_9b, hf, array_length(hf));
1986
15
    proto_register_subtree_array(ett, array_length(ett));
1987
15
}
1988
1989
void proto_reg_handoff_opa_9b(void)
1990
15
{
1991
15
    ipv6_handle             = find_dissector("ipv6");
1992
15
    opa_mad_handle          = find_dissector("opa.mad");
1993
15
    infiniband_handle       = find_dissector("infiniband");
1994
1995
    /* announce an anonymous Omni-Path 9B dissector */
1996
15
    dissector_add_uint("erf.types.type", ERF_TYPE_OPA_9B, opa_9b_handle);
1997
1998
15
}
1999
2000
/*
2001
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2002
 *
2003
 * Local variables:
2004
 * c-basic-offset: 4
2005
 * tab-width: 8
2006
 * indent-tabs-mode: nil
2007
 * End:
2008
 *
2009
 * vi: set shiftwidth=4 tabstop=8 expandtab:
2010
 * :indentSize=4:tabSize=8:noTabs=true:
2011
 */