2 * Lnet packet dissection
3 * Author: Laurent George <george@ocre.cea.fr>
4 * based on packet-agentx.c and packet-afs.c
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1999 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 * Copyright (c) 2012, 2013, Intel Corporation.
39 #include <epan/packet.h>
40 #include <epan/conversation.h>
41 #include <epan/prefs.h>
42 #include <epan/emem.h>
43 #include <epan/to_str.h>
44 #include <epan/dissectors/packet-tcp.h>
45 #include <epan/dissectors/packet-infiniband.h>
47 #include "wireshark-compat.h"
49 /* This value inidcates whether we are processing an Infiniband packet, or
50 TCP. It gets set to the extra bytes the IB header requires if IB,
52 static guint ib_lnd_extra_bytes;
54 /* How much data has at least to be available to be able to determine the
55 * length of the lnet message.
56 * Note: This is only used for TCP-based LNet packets. Not used for Infiniband.
58 #define LNET_HEADER_LEN 52
59 #define LNET_NID_DEST_OFFSET (24 + ib_lnd_extra_bytes)
60 #define LNET_NID_SRC_OFFSET (32 + ib_lnd_extra_bytes)
61 #define LNET_MSG_TYPE_OFFSET (48 + ib_lnd_extra_bytes)
62 #define LNET_PTL_INDEX_OFFSET_PUT (88 + ib_lnd_extra_bytes)
64 #define EXTRA_IB_HEADER_SIZE 24
66 /* TCP ports used for LNet. */
67 static guint global_lnet_tcp_port = 988;
68 static guint lnet_tcp_port = 988;
70 void proto_reg_handoff_lnet(void);
72 /* Define the lnet proto */
73 static int proto_lnet = -1;
75 static int hf_lnet_src_nid = -1 ;
76 static int hf_lnet_src_nid_addr = -1 ;
77 static int hf_lnet_src_nid_lnet_type = -1;
78 static int hf_lnet_src_nid_interface = -1 ;
80 static int hf_lnet_ksm_type = -1;
81 static int hf_lnet_ksm_csum = -1;
82 static int hf_lnet_ksm_zc_req_cookie = -1;
83 static int hf_lnet_ksm_zc_ack_cookie = -1;
85 static int hf_lnet_ib_magic = -1;
86 static int hf_lnet_ib_version = -1;
87 static int hf_lnet_ib_type = -1;
88 static int hf_lnet_ib_credits = -1;
89 static int hf_lnet_ib_nob = -1;
90 static int hf_lnet_ib_csum = -1;
91 static int hf_lnet_ib_srcstamp = -1;
92 static int hf_lnet_ib_dststamp = -1;
94 static int hf_lnet_dest_nid = -1 ;
95 static int hf_lnet_dest_nid_addr = -1 ;
96 static int hf_lnet_dest_nid_lnet_type = -1 ;
97 static int hf_lnet_dest_nid_interface = -1 ;
99 static int hf_lnet_dest_pid = -1 ;
100 static int hf_lnet_src_pid = -1 ;
102 static int hf_lnet_msg_type = -1 ;
103 static int hf_lnet_payload_length = -1;
104 static int hf_lnet_payload = -1 ;
105 static int hf_lnet_msg_header = -1 ;
106 static int hf_lnet_msg_filler = -1 ;
108 static int hf_dst_wmd = -1 ;
109 static int hf_dst_wmd_interface = -1 ;
110 static int hf_dst_wmd_object = -1 ;
112 static int hf_match_bits = -1 ;
113 static int hf_mlength = -1 ;
115 static int hf_hdr_data = -1 ;
116 static int hf_ptl_index = -1 ;
117 static int hf_offset = -1 ;
118 static gint ett_lnet = -1;
120 static int hf_src_offset = -1;
121 static int hf_sink_length = -1;
123 static int hf_hello_incarnation = -1 ;
124 static int hf_hello_type = -1 ;
126 static gint ett_lnet_dest_nid= -1;
127 static gint ett_lnet_src_nid= -1;
131 /* Breakdown of a NID. */
132 typedef struct t_nid {
138 /*static heur_dissector_list_t heur_subdissector_list; */
139 static dissector_table_t subdissector_table;
141 static const value_string lndnames[] = {
164 static const value_string lnet_msg_type_t[] = {
165 { LNET_MSG_ACK , "ACK"},
166 { LNET_MSG_PUT , "PUT"},
167 { LNET_MSG_GET , "GET"},
168 { LNET_MSG_REPLY, "REPLY"},
169 { LNET_MSG_HELLO, "HELLO"}
172 /* Port Index numbers. Defined in lustre/include/lustre/lustre_idl.h */
173 static const value_string portal_indices[] = {
174 { 0 , "LNET_RESERVED_PORTAL"},
175 { 1 , "CONNMGR_REQUEST_PORTAL"},
176 { 2 , "CONNMGR_REPLY_PORTAL"},
177 { 3 , "OSC_REQUEST_PORTAL(obsolete)"},
178 { 4 , "OSC_REPLY_PORTAL"},
179 { 5 , "OSC_BULK_PORTAL(obsolete)"},
180 { 6 , "OST_IO_PORTAL"},
181 { 7 , "OST_CREATE_PORTAL"},
182 { 8 , "OST_BULK_PORTAL"},
183 { 9 , "MDC_REQUEST_PORTAL(obsolete)"},
184 { 10 , "MDC_REPLY_PORTAL"},
185 { 11 , "MDC_BULK_PORTAL(obsolete)"},
186 { 12 , "MDS_REQUEST_PORTAL"},
187 { 13 , "MDS_REPLY_PORTAL(obsolete)"},
188 { 14 , "MDS_BULK_PORTAL"},
189 { 15 , "LDLM_CB_REQUEST_PORTAL"},
190 { 16 , "LDLM_CB_REPLY_PORTAL"},
191 { 17 , "LDLM_CANCEL_REQUEST_PORTAL"},
192 { 18 , "LDLM_CANCEL_REPLY_PORTAL"},
193 { 19 , "PTLBD_REQUEST_PORTAL(obsolete)"},
194 { 20 , "PTLBD_REPLY_PORTAL(obsolete)"},
195 { 21 , "PTLBD_BULK_PORTAL(obsolete)"},
196 { 22 , "MDS_SETATTR_PORTAL"},
197 { 23 , "MDS_READPAGE_PORTAL"},
198 { 24 , "MDS_MDS_PORTAL"},
199 { 25 , "MGC_REPLY_PORTAL"},
200 { 26 , "MGS_REQUEST_PORTAL"},
201 { 27 , "MGS_REPLY_PORTAL"},
202 { 28 , "OST_REQUEST_PORTAL"},
203 { 29 , "FLD_REQUEST_PORTAL"},
204 { 30 , "SEQ_METADATA_PORTAL"},
205 { 31 , "SEQ_DATA_PORTAL"},
206 { 32 , "SEQ_CONTROLLER_PORTAL"},
207 { 33 , "MGS_BULK_PORTAL"},
208 { 50 , "SRPC_REQUEST_PORTAL"},
209 { 51 , "SRPC_FRAMEWORK_REQUEST_PORTAL"},
210 { 52 , "SRPC_RDMA_PORTAL"}
213 /* SOCKLND constants. */
214 #define KSOCK_MSG_NOOP 0xc0 /* ksm_u empty */
215 #define KSOCK_MSG_LNET 0xc1 /* lnet msg */
217 static const value_string ksm_type_t[] = {
218 {0xc0, "KSOCK_MSG_NOOP"},/* ksm_u empty */
219 {0xc1, "KSOCK_MSG_LNET"} /* lnet msg */
222 /* O2IBLND constants. */
223 #define LNET_PROTO_IB_MAGIC 0x0be91b91
225 static const value_string ib_version_t[] = {
230 #define IBLND_MSG_CONNREQ 0xc0 /* connection request */
231 #define IBLND_MSG_CONNACK 0xc1 /* connection acknowledge */
232 #define IBLND_MSG_NOOP 0xd0 /* nothing (just credits) */
233 #define IBLND_MSG_IMMEDIATE 0xd1 /* immediate */
234 #define IBLND_MSG_PUT_REQ 0xd2 /* putreq (src->sink) */
235 #define IBLND_MSG_PUT_NAK 0xd3 /* completion (sink->src) */
236 #define IBLND_MSG_PUT_ACK 0xd4 /* putack (sink->src) */
237 #define IBLND_MSG_PUT_DONE 0xd5 /* completion (src->sink) */
238 #define IBLND_MSG_GET_REQ 0xd6 /* getreq (sink->src) */
239 #define IBLND_MSG_GET_DONE 0xd7 /* completion (src->sink: all OK) */
241 static const value_string ib_type_t[] = {
242 {0xc0, "IBLND_MSG_CONNREQ"},
243 {0xc1, "IBLND_MSG_CONNACK"},
244 {0xd0, "IBLND_MSG_NOOP"},
245 {0xd1, "IBLND_MSG_IMMEDIATE"},
246 {0xd2, "IBLND_MSG_PUT_REQ"},
247 {0xd3, "IBLND_MSG_PUT_NAK"},
248 {0xd4, "IBLND_MSG_PUT_ACK"},
249 {0xd5, "IBLND_MSG_PUT_DONE"},
250 {0xd6, "IBLND_MSG_GET_REQ"},
251 {0xd7, "IBLND_MSG_GET_DONE"}
254 static gboolean little_endian = TRUE;
256 #ifndef ENABLE_STATIC
257 const gchar version[] = VERSION;
259 /* Start the functions we need for the plugin stuff */
262 plugin_register(void)
264 extern void proto_register_lnet(void);
266 proto_register_lnet();
270 plugin_reg_handoff(void)
272 extern void proto_reg_handoff_lnet(void);
274 proto_reg_handoff_lnet();
279 get_nid(tvbuff_t *tvb, gint offset)
283 nid.addr = g_htonl(tvb_get_ipv4(tvb, offset));
284 nid.interface = tvb_get_letohs(tvb, offset + 4);
285 nid.proto = tvb_get_letohs(tvb, offset + 6);
289 static int dissect_csum(tvbuff_t * tvb, proto_tree *tree, int offset)
292 csum = tvb_get_letohl(tvb, offset);
294 proto_tree_add_text(tree, tvb, offset, 4, "Checksum Disabled");
296 if (ib_lnd_extra_bytes)
297 proto_tree_add_item(tree, hf_lnet_ib_csum, tvb, offset,
300 proto_tree_add_item(tree, hf_lnet_ksm_csum, tvb, offset,
308 static int dissect_req_cookie(tvbuff_t * tvb, proto_tree *tree, int offset)
311 req= tvb_get_letoh64(tvb, offset);
313 proto_tree_add_text(tree, tvb, offset, 8, "Ack not required");
315 proto_tree_add_item(tree, hf_lnet_ksm_zc_req_cookie, tvb, offset, 8, little_endian);
319 static int dissect_ack_cookie(tvbuff_t * tvb, proto_tree *tree, int offset)
322 ack= tvb_get_letoh64(tvb, offset);
324 proto_tree_add_text(tree, tvb, offset, 8, "Not ack");
326 proto_tree_add_item(tree, hf_lnet_ksm_zc_ack_cookie, tvb, offset, 8, little_endian);
330 #ifdef WIRESHARK_COMPAT
332 dissect_ksock_msg_noop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
335 dissect_ksock_msg_noop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
341 proto_tree_add_item(tree, hf_lnet_ksm_type, tvb, offset, 4, TRUE);offset+=4;
342 offset=dissect_csum(tvb,tree,offset);
343 offset=dissect_req_cookie(tvb, tree, offset);
344 offset=dissect_ack_cookie(tvb,tree,offset);
345 #ifndef WIRESHARK_COMPAT
351 static int dissect_ksock_msg(tvbuff_t * tvb, proto_tree *tree, int offset)
353 proto_tree_add_item(tree, hf_lnet_ksm_type, tvb, offset, 4, TRUE);offset+=4;
354 offset=dissect_csum(tvb,tree,offset);
355 offset=dissect_req_cookie(tvb, tree, offset);
356 offset=dissect_ack_cookie(tvb,tree,offset);
361 dissect_ib_msg(tvbuff_t *tvb, proto_tree *tree, int offset)
365 * __u32 ibm_magic; * I'm an ibnal message *
366 * __u16 ibm_version; * this is my version *
368 * __u8 ibm_type; * msg type *
369 * __u8 ibm_credits; * returned credits *
370 * __u32 ibm_nob; * # bytes in message *
371 * __u32 ibm_cksum; * checksum (0 == no
373 * __u64 ibm_srcnid; * sender's NID *
374 * __u64 ibm_srcstamp; * sender's incarnation *
375 * __u64 ibm_dstnid; * destination's NID *
376 * __u64 ibm_dststamp; * destination's
380 * kib_connparams_t connparams;
381 * kib_immediate_msg_t immediate;
382 * kib_putreq_msg_t putreq;
383 * kib_putack_msg_t putack;
385 * kib_completion_msg_t completion;
387 *} WIRE_ATTR kib_msg_t; */
393 proto_tree_add_item(tree, hf_lnet_ib_magic, tvb, offset, 4,
396 proto_tree_add_item(tree, hf_lnet_ib_version, tvb, offset, 2,
399 msg_type = tvb_get_guint8(tvb, offset);
400 proto_tree_add_item(tree, hf_lnet_ib_type, tvb, offset, 1,
403 proto_tree_add_item(tree, hf_lnet_ib_credits, tvb, offset, 1,
406 proto_tree_add_item(tree, hf_lnet_ib_nob, tvb, offset, 4,
409 offset = dissect_csum(tvb, tree, offset);
411 src_nid = get_nid(tvb, offset);
412 proto_tree_add_text(tree, tvb, offset, 8, "src_nid = %s@tcp%d",
413 ip_to_str((guint8 *) &src_nid.addr),
416 proto_tree_add_item(tree, hf_lnet_ib_srcstamp, tvb, offset, 8,
420 dst_nid = get_nid(tvb, offset);
421 proto_tree_add_text(tree, tvb, offset, 8, "dst_nid = %s@tcp%d",
422 ip_to_str((guint8 *) &dst_nid.addr),
425 proto_tree_add_item(tree, hf_lnet_ib_dststamp, tvb,offset, 8,
429 /* LNet payloads only exist when the LND msg type is IMMEDIATE.
430 Return a zero offset for all other types. */
431 return (msg_type == IBLND_MSG_IMMEDIATE) ? offset : 0;
434 static int dissect_dest_nid(tvbuff_t * tvb, proto_tree *tree, int offset)
436 proto_tree_add_item(tree, hf_lnet_dest_nid_addr, tvb, offset, 4, TRUE);offset+=4;
437 proto_tree_add_item(tree, hf_lnet_dest_nid_interface, tvb, offset, 2, TRUE);offset+=2;
438 proto_tree_add_item(tree, hf_lnet_dest_nid_lnet_type, tvb, offset, 2, TRUE);offset+=2;
443 static int dissect_src_nid(tvbuff_t * tvb, proto_tree *tree, int offset)
445 proto_tree_add_item(tree, hf_lnet_src_nid_addr, tvb, offset, 4, TRUE);offset+=4;
446 proto_tree_add_item(tree, hf_lnet_src_nid_interface, tvb, offset, 2, TRUE);offset+=2;
447 proto_tree_add_item(tree, hf_lnet_src_nid_lnet_type, tvb, offset, 2, TRUE);offset+=2;
451 static int dissect_lnet_put(tvbuff_t * tvb, proto_tree *tree, int offset, packet_info *pinfo _U_)
453 /* typedef struct lnet_put {
454 lnet_handle_wire_t ack_wmd;
459 } WIRE_ATTR lnet_put_t; */
461 proto_tree_add_item(tree,hf_dst_wmd_interface,tvb,offset,8,little_endian); offset+=8;
462 proto_tree_add_item(tree,hf_dst_wmd_object,tvb,offset,8,little_endian);offset+=8;
464 proto_tree_add_item(tree,hf_match_bits,tvb,offset,8,little_endian);offset+=8;
465 proto_tree_add_item(tree,hf_hdr_data,tvb,offset,8,little_endian);offset+=8;
466 col_append_sep_str(pinfo->cinfo, COL_INFO, ", ",
467 val_to_str(tvb_get_letohl(tvb, offset),
469 "Unknown")); /* add some nice value */
470 proto_item_append_text(tree, ", %s" , val_to_str(tvb_get_letohl(tvb,
474 /* print ptl_index */
475 proto_tree_add_item(tree,hf_ptl_index,tvb,offset,4,little_endian);offset+=4;
476 proto_tree_add_item(tree,hf_offset,tvb,offset,4,little_endian);offset+=4;
480 static int dissect_lnet_get(tvbuff_t * tvb, proto_tree *tree, int offset, packet_info *pinfo _U_)
482 /* typedef struct lnet_get {
483 lnet_handle_wire_t return_wmd;
488 } WIRE_ATTR lnet_get_t;
491 proto_tree_add_item(tree, hf_dst_wmd_interface,
492 tvb, offset, 8, little_endian);
494 proto_tree_add_item(tree, hf_dst_wmd_object, tvb, offset, 8,
497 proto_tree_add_item(tree, hf_match_bits, tvb, offset, 8, little_endian);
499 col_append_sep_str(pinfo->cinfo, COL_INFO, ", ",
500 val_to_str(tvb_get_letohl(tvb, offset),
501 portal_indices, "Unknown"));
502 proto_item_append_text(tree, ", %s",
503 val_to_str(tvb_get_letohl(tvb, offset),
504 portal_indices, "Unknown"));
505 proto_tree_add_item(tree, hf_ptl_index, tvb, offset, 4, little_endian);
507 proto_tree_add_item(tree, hf_src_offset, tvb, offset, 4, little_endian);
509 proto_tree_add_item(tree, hf_sink_length, tvb, offset, 4,
515 static int dissect_lnet_reply(tvbuff_t * tvb, proto_tree *tree, int offset)
517 /* typedef struct lnet_reply {
518 lnet_handle_wire_t dst_wmd;
519 } WIRE_ATTR lnet_reply_t; */
521 proto_tree_add_item(tree,hf_dst_wmd_interface,tvb,offset,8,little_endian);offset+=8;
522 proto_tree_add_item(tree,hf_dst_wmd_object,tvb,offset,8,little_endian);offset+=8;
528 static int dissect_lnet_hello(tvbuff_t * tvb, proto_tree *tree, int offset)
530 /* typedef struct lnet_hello {
533 } WIRE_ATTR lnet_hello_t; */
535 proto_tree_add_item(tree,hf_hello_incarnation,tvb,offset,8,little_endian); offset+=8;
536 proto_tree_add_item(tree,hf_hello_type,tvb,offset,4,little_endian); offset+=4;
540 static int dissect_lnet_ack(tvbuff_t * tvb, proto_tree *tree, int offset, packet_info *pinfo _U_)
542 /* typedef struct lnet_ack {
543 lnet_handle_wire_t dst_wmd;
546 } WIRE_ATTR lnet_ack_t; */
548 proto_tree_add_item(tree,hf_dst_wmd_interface,tvb,offset,8,TRUE); offset+=8;
549 proto_tree_add_item(tree,hf_dst_wmd_object,tvb,offset,8,TRUE);offset+=8;
550 proto_tree_add_item(tree,hf_match_bits,tvb,offset,8, little_endian);offset+=8;
551 proto_tree_add_item(tree,hf_mlength, tvb,offset,4, little_endian); offset+=4;
555 #ifdef WIRESHARK_COMPAT
556 static void dissect_lnet_message(tvbuff_t *, packet_info *, proto_tree *);
558 static int dissect_lnet_message(tvbuff_t *, packet_info *, proto_tree *, void*);
561 /* The next two length getting routines are only used for KSOCK LNK messages. */
563 get_lnet_message_len(packet_info __attribute__((__unused__))*pinfo, tvbuff_t *tvb, int offset)
567 /* Get the payload length */
568 plen = tvb_get_letohl(tvb, offset + 28 + 24 + ib_lnd_extra_bytes);
573 /* That length doesn't include the header; add that in. */
574 return plen + 72 + 24 + ib_lnd_extra_bytes; /* +24 == ksock msg
580 get_noop_message_len(packet_info __attribute__((__unused__))*pinfo, tvbuff_t *tvb, int offset)
586 dissect_lnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
588 /* TODO : correct this, now we do a difference between packet with
589 NOOP and others .. but I don't find how to use pdu_dissect with
590 a variable length<=LNET_HEADER_LEN */
591 ib_lnd_extra_bytes = 0;
592 switch (tvb_get_letohl(tvb, 0)) {
594 #ifdef WIRESHARK_COMPAT
595 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 0,
596 get_noop_message_len,
597 dissect_ksock_msg_noop);
599 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 0,
600 get_noop_message_len,
601 dissect_ksock_msg_noop, NULL);
605 #ifdef WIRESHARK_COMPAT
606 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, LNET_HEADER_LEN,
607 get_lnet_message_len,
608 dissect_lnet_message);
610 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, LNET_HEADER_LEN,
611 get_lnet_message_len,
612 dissect_lnet_message, NULL);
619 #ifdef WIRESHARK_COMPAT
620 dissect_ib_lnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
622 dissect_ib_lnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
625 /* We can tell if this is an LNet payload by looking at the first
626 * 32-bit word for our magic number. */
627 if (tvb_get_letohl(tvb, 0) != LNET_PROTO_IB_MAGIC) {
628 /* Not an LNet payload. */
632 ib_lnd_extra_bytes = EXTRA_IB_HEADER_SIZE;
633 #ifdef WIRESHARK_COMPAT
634 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, LNET_HEADER_LEN,
635 get_lnet_message_len, dissect_lnet_message);
637 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, LNET_HEADER_LEN,
638 get_lnet_message_len, dissect_lnet_message, NULL);
640 return tvb_length(tvb);
643 /*----------------------------------------------------------- */
644 /* For the conversation */
651 typedef struct lnet_request_key {
653 guint32 conversation;
654 } lnet_request_key_t;
656 typedef struct lnet_request_val {
658 guint32 packet_num_parent;
659 } lnet_request_val_t;
662 static GHashTable *lnet_request_hash;
668 lnet_equal(gconstpointer v, gconstpointer w)
670 const struct lnet_request_key *v1 = (const struct lnet_request_key *)v;
671 const struct lnet_request_key *v2 = (const struct lnet_request_key *)w;
673 if (v1 -> conversation == v2 -> conversation &&
674 v1 -> match_bits == v2 -> match_bits)
684 lnet_hash (gconstpointer v)
686 const struct lnet_request_key *key = (const struct lnet_request_key *)v;
687 return key -> conversation + key -> match_bits;
692 lnet_init_protocol(void)
694 if (lnet_request_hash)
695 g_hash_table_destroy(lnet_request_hash);
697 lnet_request_hash = g_hash_table_new(lnet_hash, lnet_equal);
701 static lnet_request_val_t*
702 get_lnet_conv(packet_info * pinfo , GHashTable * lnet_hash_table, guint64 match_bits )
704 conversation_t * conversation ;
705 lnet_request_key_t request_key, *new_request_key;
706 lnet_request_val_t *request_val=NULL ;
708 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
711 if (NULL == conversation)
712 /* It's not part of any conversation - create a new one. */
713 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, proto_lnet,
714 pinfo->srcport, pinfo->destport, 0);
716 request_key.conversation = conversation->index;
717 request_key.match_bits = match_bits;
719 request_val = (struct lnet_request_val * ) g_hash_table_lookup(lnet_hash_table, &request_key);
721 new_request_key = se_alloc(sizeof(struct lnet_request_key));
722 *new_request_key = request_key;
723 request_val = se_alloc(sizeof(struct lnet_request_val));
724 request_val -> match_bits = match_bits;
725 request_val -> packet_num_parent = pinfo->fd->num ;
726 /*request_val -> filename = "test" ; */
727 g_hash_table_insert(lnet_hash_table, new_request_key, request_val);
737 /*----------------------------------------------------------- */
738 #ifdef WIRESHARK_COMPAT
740 dissect_lnet_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
743 dissect_lnet_message(tvbuff_t *tvb, packet_info *pinfo,
744 proto_tree *tree, void *data)
750 t_nid dest_nid; /* nid value */
752 proto_item *ti = NULL; /* principal node */
753 proto_tree *lnet_tree = NULL; /* principal tree */
754 proto_tree *lnet_nid_src_tree = NULL; /*subtree for the nids*/
755 proto_tree *lnet_nid_dest_tree = NULL;
756 proto_item *ti_src_nid; /* node for the nids */
757 proto_item *ti_dest_nid;
758 guint32 payload_length;
759 guint32 msg_filler_length;
761 /* lnet_request_val_t* conversation_val ; */
762 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Lnet");
764 msg_type = tvb_get_letohl(tvb, LNET_MSG_TYPE_OFFSET);
765 /* We delete the entire line and add LNET + msg_type */
766 col_add_fstr(pinfo->cinfo, COL_INFO, "LNET_%s",
767 (msg_type < sizeof(lnet_msg_type_t)/sizeof(value_string))
768 ? lnet_msg_type_t[msg_type].strptr
775 ti = proto_tree_add_item(tree, proto_lnet, tvb, 0, -1, FALSE);
777 lnet_tree = proto_item_add_subtree(ti, ett_lnet);
779 if (ib_lnd_extra_bytes) {
780 offset = dissect_ib_msg(tvb, lnet_tree, offset);
782 /* There was no LNet payload, only ob2lnd. */
786 /* dissect the first 24 bytes (ksock_msg_t in
789 offset = dissect_ksock_msg(tvb, lnet_tree, offset);
793 dest_nid = get_nid(tvb, offset);
794 ti_dest_nid = proto_tree_add_text(lnet_tree, tvb, offset, 8,
795 "dest_nid = %s@tcp%d",
796 ip_to_str((guint8 *) &dest_nid.addr),
798 lnet_nid_dest_tree = proto_item_add_subtree(ti_dest_nid,
800 offset = dissect_dest_nid(tvb, lnet_nid_dest_tree, offset);
802 /* Same for src_nid */
803 src_nid = get_nid(tvb, offset);
804 ti_src_nid = proto_tree_add_text(lnet_tree, tvb, offset, 8,
805 "src_nid = %s@tcp%d",
806 ip_to_str((guint8 *) &src_nid.addr),
808 lnet_nid_src_tree = proto_item_add_subtree(ti_src_nid,
810 offset = dissect_src_nid(tvb, lnet_nid_src_tree, offset);
813 proto_tree_add_item(lnet_tree, hf_lnet_src_pid, tvb, offset, 4, TRUE);
815 proto_tree_add_item(lnet_tree, hf_lnet_dest_pid, tvb, offset, 4, TRUE);
818 /* message_type (32 bits) */
819 msg_type = tvb_get_letohl(tvb, offset+0);
820 /* put some nice info on lnet line */
821 proto_item_append_text(ti, " %s",
823 sizeof(lnet_msg_type_t)/sizeof(value_string))
824 ? lnet_msg_type_t[msg_type].strptr
826 proto_tree_add_item(lnet_tree, hf_lnet_msg_type, tvb,
830 /* payload data (to follow) length :*/
831 payload_length = tvb_get_letohl(tvb, offset+0);
832 proto_tree_add_item(lnet_tree, hf_lnet_payload_length, tvb,
836 /* here offset = 24+8+8+4+4+4+4 = 56 */
840 offset = dissect_lnet_ack(tvb, lnet_tree, offset, pinfo);
841 match = tvb_get_letoh64(tvb, 72);
844 offset = dissect_lnet_put(tvb, lnet_tree, offset, pinfo);
845 match = tvb_get_letoh64(tvb, 72);
848 offset = dissect_lnet_get(tvb, lnet_tree, offset, pinfo);
849 match = tvb_get_letoh64(tvb, 72);
852 offset = dissect_lnet_reply(tvb, lnet_tree, offset);
855 offset = dissect_lnet_hello(tvb, lnet_tree, offset);
861 /* conversation_val = */
862 get_lnet_conv(pinfo, lnet_request_hash, match);
863 /* proto_tree_add_text(tree, tvb, 0 , 0, "match = %"
864 * G_GINT64_MODIFIER "u parent = %d",
865 * conversation_val -> match_bits ,
866 * conversation_val -> packet_num_parent);
870 msg_filler_length = 72 - offset + 24 + ib_lnd_extra_bytes;
871 if (msg_filler_length > 72)
873 /* +24 : ksosck_message take 24bytes, and allready in offset */
875 proto_tree_add_item(lnet_tree, hf_lnet_msg_filler, tvb, offset,
876 msg_filler_length, little_endian);
877 offset += msg_filler_length;
879 if (payload_length > 0) {
880 /* display of payload */
881 proto_tree_add_item(lnet_tree, hf_lnet_payload, tvb,
882 offset, payload_length,
885 next_tvb = tvb_new_subset(tvb, offset,
886 payload_length, payload_length);
887 if (msg_type == LNET_MSG_PUT)
888 dissector_try_uint(subdissector_table,
889 tvb_get_letohl(tvb, LNET_PTL_INDEX_OFFSET_PUT),
890 next_tvb, pinfo, tree);
894 offset += payload_length;
897 #ifdef WIRESHARK_COMPAT
905 proto_register_lnet(void)
907 static hf_register_info hf[] = {
908 { &hf_lnet_ksm_type ,
909 { "Type of socklnd message" , "lnet.ksm_type" , FT_UINT32 , BASE_HEX , VALS(ksm_type_t) , 0x0 , "" , HFILL }} ,
910 { &hf_lnet_ksm_csum ,
911 { "Checksum" , "lnet.ksm_csum" , FT_UINT32 , BASE_DEC , NULL , 0x0 , "" , HFILL }} ,
912 { &hf_lnet_ksm_zc_req_cookie ,
913 { "Ack required" , "lnet.ksm_zc_req_cookie" , FT_UINT64 , BASE_HEX , NULL , 0x0 , "" , HFILL }} ,
914 { &hf_lnet_ksm_zc_ack_cookie ,
915 { "Ack" , "lnet.ksm_zc_ack_cookie" , FT_UINT64 , BASE_HEX , NULL , 0x0 , "" , HFILL }} ,
917 { "Magic of IB message", "lnet.ib.magic", FT_UINT32,
918 BASE_HEX, NULL, 0x0, "", HFILL} },
919 { &hf_lnet_ib_version,
920 { "Version", "lnet.ib.version", FT_UINT16, BASE_HEX,
921 VALS(ib_version_t), 0x0, "", HFILL} },
923 { "Type of IB message", "lnet.ib.type", FT_UINT8,
924 BASE_HEX, VALS(ib_type_t), 0x0, "", HFILL} },
925 { &hf_lnet_ib_credits,
926 { "Returned Credits", "lnet.ib.credits", FT_UINT8,
927 BASE_DEC, NULL, 0x0, "", HFILL} },
929 { "Number of Bytes", "lnet.ib.nob", FT_UINT32,
930 BASE_DEC, NULL, 0x0, "", HFILL} },
932 { "Checksum", "lnet.ib_csum", FT_UINT32, BASE_DEC,
933 NULL, 0x0, "", HFILL} },
934 { &hf_lnet_ib_srcstamp,
935 { "Sender Timestamp", "lnet.ib.srcstamp",
936 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
938 { &hf_lnet_ib_dststamp,
939 { "Destination Timestamp", "lnet.ib.dststamp",
940 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
944 { "Src nid" , "lnet.src_nid" , FT_UINT64 , BASE_HEX , NULL , 0x0 , "src nid" , HFILL }} ,
945 { &hf_lnet_src_nid_addr ,
946 { "Src nid" , "lnet.src_nid_addr" , FT_IPv4 , BASE_NONE , NULL , 0x0 , "" , HFILL }} ,
947 { &hf_lnet_src_nid_lnet_type ,
948 { "lnd network type" , "lnet.src_nid_type" , FT_UINT16 , BASE_DEC , VALS(lndnames) , 0x0 , "" , HFILL} },
949 { &hf_lnet_src_nid_interface ,
950 { "lnd network interface" , "lnet.src_nid_net_interface" , FT_UINT16 , BASE_DEC , NULL , 0x0 , NULL , HFILL }} ,
952 { &hf_lnet_dest_nid ,
953 { "Dest nid" , "lnet.dest_nid" , FT_UINT64 , BASE_HEX , NULL , 0x0 , "" , HFILL }} ,
955 { &hf_lnet_dest_nid_addr ,
956 { "Destination nid" , "lnet.dest_nid_addr" , FT_IPv4 , BASE_NONE , NULL , 0x0 , "" , HFILL }} ,
957 { &hf_lnet_dest_nid_lnet_type ,
958 { "lnd network type" , "lnet.dest_nid_type" , FT_UINT16 , BASE_DEC , VALS(lndnames) , 0x0 , "" , HFILL} },
959 { &hf_lnet_dest_nid_interface ,
960 { "lnd network interface" , "lnet.dest_nid_net_interface" , FT_UINT16 , BASE_DEC , NULL , 0x0 , NULL , HFILL }} ,
962 { &hf_lnet_dest_pid ,
963 { "Dest pid" , "lnet.dest_pid" , FT_UINT32 , BASE_DEC_HEX , NULL , 0x0 , "dest pid" , HFILL }} ,
965 { "Src pid" , "lnet.src_pid" , FT_UINT32 , BASE_DEC_HEX , NULL , 0x0 , "src nid" , HFILL }} ,
967 { &hf_lnet_msg_type ,
968 { "Message type" , "lnet.msg_type" , FT_UINT32 , BASE_DEC , VALS(lnet_msg_type_t) , 0x0 , "msg type" , HFILL }} ,
969 { &hf_lnet_payload_length ,
970 { "Payload length" , "lnet.payload_length" , FT_UINT32 , BASE_DEC , NULL , 0x0 , "" , HFILL }} ,
972 { "Payload" , "lnet.payload" , FT_NONE , BASE_NONE , NULL , 0x0 , "" , HFILL }} ,
975 { "DST MD index " , "lnet.msg_dst_cookie" , FT_BYTES , BASE_NONE , NULL , 0x0 , "" , HFILL }} ,
976 { &hf_dst_wmd_interface ,
977 { "DST MD index interface" , "lnet.msg_dst_inteface_cookie" , FT_UINT64 , BASE_HEX_DEC , NULL , 0x0 , "" , HFILL }} ,
978 { &hf_dst_wmd_object ,
979 { "DST MD index object" , "lnet.msg_dst_object_cookie" , FT_UINT64 , BASE_HEX_DEC , NULL , 0x0 , "" , HFILL }} ,
981 { "Match bits" , "lnet.msg_dst_match_bits" , FT_UINT64 , BASE_HEX_DEC , NULL , 0x0 , "" , HFILL}} ,
983 { "Message length" , "lnet.msg_length" , FT_UINT32 , BASE_DEC , NULL , 0x0 , "" , HFILL}} ,
988 { "hdr data" , "lnet.msg_hdr_data" , FT_UINT64 , BASE_HEX_DEC , NULL , 0x0 , "" , HFILL}} ,
990 { "ptl index" , "lnet.ptl_index" , FT_UINT32 , BASE_DEC , VALS(portal_indices) , 0x0 , "" , HFILL}} ,
992 { "offset" , "lnet.offset" , FT_UINT32 , BASE_DEC , NULL , 0x0 , "" , HFILL}} ,
996 { "src offset" , "lnet.src_offset" , FT_UINT32 , BASE_DEC , NULL , 0x0 , "" , HFILL}} ,
998 { "sink length" , "lnet.sink_length" , FT_UINT32 , BASE_DEC , NULL , 0x0 , "" , HFILL}} ,
1001 { &hf_hello_incarnation ,
1002 { "hello incarnation " , "lnet.hello_incarnation" , FT_UINT64 , BASE_HEX_DEC , NULL , 0x0 , "" , HFILL}} ,
1004 { "hello type" , "lnet.hello_type" , FT_UINT32 , BASE_DEC , NULL , 0x0 , "" , HFILL}} ,
1006 { &hf_lnet_msg_header ,
1007 { "ptl header" , "lnet.ptl_header" , FT_NONE , BASE_NONE , NULL , 0x0 , "" , HFILL}} ,
1009 { &hf_lnet_msg_filler ,
1010 { "msg filler (padding)" , "lnet.ptl_filler" , FT_NONE , BASE_NONE , NULL , 0x0 , "" , HFILL}} ,
1012 /* Add more fields here */
1015 static gint *ett[] = {
1022 module_t *lnet_module;
1024 proto_lnet = proto_register_protocol("Lnet", /*name*/
1025 "Lnet", /*short name*/
1028 proto_register_field_array(proto_lnet, hf, array_length(hf));
1029 proto_register_subtree_array(ett, array_length(ett));
1031 lnet_module = prefs_register_protocol(proto_lnet, proto_reg_handoff_lnet);
1033 prefs_register_uint_preference(lnet_module, "tcp.lnet_port",
1034 "Lnet listener TCP Port",
1035 "Set the TCP port for Lnet"
1036 "(if other than the default of 988)",
1037 10, &global_lnet_tcp_port);
1039 subdissector_table = register_dissector_table("lnet.ptl_index", "lnet portal index", FT_UINT32 , BASE_DEC);
1041 register_init_routine(&lnet_init_protocol);
1046 /* The registration hand-off routine */
1048 proto_reg_handoff_lnet(void)
1050 static int lnet_prefs_initialized = FALSE;
1051 static dissector_handle_t lnet_handle;
1053 if(!lnet_prefs_initialized) {
1054 heur_dissector_add("infiniband.payload", dissect_ib_lnet,
1056 heur_dissector_add("infiniband.mad.cm.private",
1057 dissect_ib_lnet, proto_lnet);
1058 lnet_handle = create_dissector_handle(dissect_lnet, proto_lnet);
1059 lnet_prefs_initialized = TRUE;
1062 dissector_delete_uint("tcp.port", global_lnet_tcp_port, lnet_handle);
1064 lnet_tcp_port = global_lnet_tcp_port;
1066 dissector_add_uint("tcp.port", lnet_tcp_port, lnet_handle);