MSWSP: fix dissect_mswsp_smb()
[wireshark-wip.git] / epan / dissectors / packet-infiniband_sdp.c
blobad7a9c5f19e148bd6dfbd4212285844e76f0191f
1 /* packet-infiniband_sdp.c
2 * Routines for Infiniband Sockets Direct Protocol dissection
3 * Copyright 2010, Mellanox Technologies Ltd.
4 * Code by Amir Vadai and Slava Koyfman.
6 * $Id$
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "config.h"
29 #include <glib.h>
31 #include <epan/packet.h>
32 #include <epan/prefs.h>
33 #include <epan/conversation.h>
34 #include <epan/wmem/wmem.h>
35 #include <stdlib.h>
36 #include <errno.h>
38 #ifdef HAVE_ARPA_INET_H
39 # include <arpa/inet.h>
40 #endif
41 #ifdef HAVE_SYS_SOCKET_H
42 # include <sys/socket.h> /* needed to define AF_ values on UNIX */
43 #endif
44 #ifdef HAVE_WINSOCK2_H
45 # include <winsock2.h> /* needed to define AF_ values on Windows */
46 #endif
47 #ifdef NEED_INET_V6DEFS_H
48 # include "wsutil/inet_v6defs.h"
49 #endif
51 #include "packet-infiniband.h"
53 /* If the service-id is non-zero after being ANDed with the following mask then
54 this is SDP traffic */
55 #define SERVICE_ID_MASK 0x0000000000010000
57 /* Forward declaration we need below (for using proto_reg_handoff as a prefs callback) */
58 void proto_reg_handoff_ib_sdp(void);
60 static int proto_infiniband = -1; /* we'll need the Infiniband protocol index sometimes, so keep it here */
62 /* Initialize the protocol and registered fields... */
63 static int proto_ib_sdp = -1;
65 static int hf_ib_sdp = -1;
67 /* IB SDP BSDH Header */
68 static int hf_ib_sdp_bsdh = -1;
69 static int hf_ib_sdp_mid = -1;
70 static int hf_ib_sdp_flags = -1;
71 static int hf_ib_sdp_flags_oobpres = -1;
72 static int hf_ib_sdp_flags_oob_pend = -1;
73 static int hf_ib_sdp_flags_reqpipe = -1;
75 static int hf_ib_sdp_len = -1;
76 static int hf_ib_sdp_bufs = -1;
77 static int hf_ib_sdp_mseq = -1;
78 static int hf_ib_sdp_mseqack = -1;
80 /* IB SDP Hello Header */
81 static int hf_ib_sdp_hh = -1;
82 static int hf_ib_sdp_majv = -1;
83 static int hf_ib_sdp_minv = -1;
84 static int hf_ib_sdp_ipv = -1;
85 static int hf_ib_sdp_cap = -1;
86 static int hf_ib_sdp_cap_invalidate = -1;
87 static int hf_ib_sdp_cap_extmaxadverts = -1;
88 static int hf_ib_sdp_maxadverts = -1;
89 static int hf_ib_sdp_desremrcvsz = -1;
90 static int hf_ib_sdp_localrcvsz = -1;
91 static int hf_ib_sdp_localport = -1;
92 static int hf_ib_sdp_src_ip = -1;
93 static int hf_ib_sdp_dst_ip = -1;
94 static int hf_ib_sdp_extmaxadverts = -1;
95 static int hf_ib_sdp_hah = -1;
96 static int hf_ib_sdp_rwch = -1;
97 static int hf_ib_sdp_rrch = -1;
98 static int hf_ib_sdp_mch = -1;
99 static int hf_ib_sdp_crbh = -1;
100 static int hf_ib_sdp_crbah = -1;
101 static int hf_ib_sdp_suspch = -1;
102 static int hf_ib_sdp_sinkah = -1;
103 static int hf_ib_sdp_srcah = -1;
104 static int hf_ib_sdp_data = -1;
106 /* Initialize the subtree pointers */
107 static gint ett_ib_sdp = -1;
108 static gint ett_ib_sdp_bsdh = -1;
109 static gint ett_ib_sdp_hh = -1;
111 /* global preferences */
112 static gboolean gPREF_MAN_EN = FALSE;
113 static gint gPREF_TYPE[2] = {0};
114 static const char *gPREF_ID[2] = {NULL};
115 static guint gPREF_QP[2] = {0};
117 /* source/destination addresses from preferences menu (parsed from gPREF_TYPE[?], gPREF_ID[?]) */
118 address manual_addr[2];
119 void *manual_addr_data[2];
121 static const enum_val_t pref_address_types[] = {
122 {"lid", "LID", 0},
123 {"gid", "GID", 1},
124 {NULL, NULL, -1}
127 typedef enum {
128 Hello = 0x0,
129 HelloAck,
130 DisConn,
131 AbortConn,
132 SendSm,
133 RdmaWrCompl,
134 RdmaRdCompl,
135 ModeChange,
136 SrcAvailCancel,
137 SinkAvailCancel,
138 SinkCancelAck,
139 ChRcvBuf,
140 ChRcvBufAck,
141 SuspComm,
142 SuspCommAck,
143 SinkAvail = 0xfd,
144 SrcAvail,
145 Data
146 } message_by_mid_t;
148 static const range_string mid_meanings[] = {
149 { Hello, Hello, "Hello" },
150 { HelloAck, HelloAck, "HelloAck" },
151 { DisConn, DisConn, "DisConn" },
152 { AbortConn, AbortConn, "AbortConn" },
153 { SendSm, SendSm, "SendSm" },
154 { RdmaWrCompl, RdmaWrCompl, "RdmaWrCompl" },
155 { RdmaRdCompl, RdmaRdCompl, "RdmaRdCompl" },
156 { ModeChange, ModeChange, "ModeChange" },
157 { SrcAvailCancel, SrcAvailCancel, "SrcAvailCancel" },
158 { SinkAvailCancel, SinkAvailCancel, "SinkAvailCancel" },
159 { SinkCancelAck, SinkCancelAck, "SinkCancelAck" },
160 { ChRcvBuf, ChRcvBuf, "ChRcvBuf" },
161 { ChRcvBufAck, ChRcvBufAck, "ChRcvBufAck" },
162 { SuspComm, SuspComm, "SuspComm" },
163 { SuspCommAck, SuspCommAck, "SuspCommAck" },
164 { SinkAvail, SinkAvail, "SinkAvail" },
165 { SrcAvail, SrcAvail, "SrcAvail" },
166 { Data, Data, "Data" },
167 { 0x00001111, 0x00111111, "Reserved" },
168 { 0x01000000, 0x01111111, "Experimental" },
169 { 0x10000000, 0x11111100, "Reserved" },
170 { 0, 0, NULL }
173 /* Code to actually dissect the packets */
174 static int
175 dissect_ib_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
177 int local_offset = 0;
178 proto_item *SDP_header_item = NULL;
179 proto_tree *SDP_header_tree = NULL;
180 proto_item *SDP_BSDH_header_item = NULL;
181 proto_tree *SDP_BSDH_header_tree = NULL;
182 proto_item *SDP_EH_header_item = NULL;
183 proto_tree *SDP_EH_header_tree = NULL;
184 guint8 mid;
185 conversation_t *conv;
186 conversation_infiniband_data *convo_data = NULL;
187 dissector_handle_t infiniband_handle;
189 if (tvb_length(tvb) < 16) /* check this has at least enough bytes for the BSDH */
190 return 0;
192 if (gPREF_MAN_EN) {
193 /* If the manual settings are enabled see if this fits - in which case we can skip
194 the following checks entirely and go straight to dissecting */
195 if ( (ADDRESSES_EQUAL(&pinfo->src, &manual_addr[0]) &&
196 ADDRESSES_EQUAL(&pinfo->dst, &manual_addr[1]) &&
197 (pinfo->srcport == 0xffffffff /* is unknown */ || pinfo->srcport == gPREF_QP[0]) &&
198 (pinfo->destport == 0xffffffff /* is unknown */ || pinfo->destport == gPREF_QP[1])) ||
199 (ADDRESSES_EQUAL(&pinfo->src, &manual_addr[1]) &&
200 ADDRESSES_EQUAL(&pinfo->dst, &manual_addr[0]) &&
201 (pinfo->srcport == 0xffffffff /* is unknown */ || pinfo->srcport == gPREF_QP[1]) &&
202 (pinfo->destport == 0xffffffff /* is unknown */ || pinfo->destport == gPREF_QP[0])) )
203 goto manual_override;
206 /* first try to find a conversation between the two current hosts. in most cases this
207 will not work since we do not have the source QP. this WILL succeed when we're still
208 in the process of CM negotiations */
209 conv = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
210 PT_IBQP, pinfo->srcport, pinfo->destport, 0);
212 if (!conv) {
213 /* if not, try to find an established RC channel. recall Infiniband conversations are
214 registered with one side of the channel. since the packet is only guaranteed to
215 contain the qpn of the destination, we'll use this */
216 conv = find_conversation(pinfo->fd->num, &pinfo->dst, &pinfo->dst,
217 PT_IBQP, pinfo->destport, pinfo->destport, NO_ADDR_B|NO_PORT_B);
219 if (!conv)
220 return 0; /* nothing to do with no conversation context */
223 if (proto_infiniband < 0) { /* first time - get the infiniband protocol index*/
224 infiniband_handle = find_dissector("infiniband");
225 if (!infiniband_handle)
226 return 0; /* no infiniband handle? can't get our proto-data; sorry, can't help you without this */
227 proto_infiniband = dissector_handle_get_protocol_index(infiniband_handle);
229 convo_data = (conversation_infiniband_data *)conversation_get_proto_data(conv, proto_infiniband);
231 if (!(convo_data->service_id & SERVICE_ID_MASK))
232 return 0; /* the service id doesn't match that of SDP - nothing for us to do here */
234 manual_override:
236 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SDP");
238 SDP_header_item = proto_tree_add_item(tree, hf_ib_sdp, tvb, local_offset, -1, ENC_NA);
239 SDP_header_tree = proto_item_add_subtree(SDP_header_item, ett_ib_sdp);
241 SDP_BSDH_header_item = proto_tree_add_item(SDP_header_tree, hf_ib_sdp_bsdh, tvb, local_offset, 16, ENC_NA);
242 SDP_BSDH_header_tree = proto_item_add_subtree(SDP_BSDH_header_item, ett_ib_sdp_bsdh);
244 mid = tvb_get_guint8(tvb, local_offset);
245 proto_tree_add_item(SDP_BSDH_header_tree, hf_ib_sdp_mid, tvb, local_offset, 1, ENC_BIG_ENDIAN); local_offset += 1;
247 proto_tree_add_item(SDP_BSDH_header_tree, hf_ib_sdp_flags, tvb, local_offset, 1, ENC_BIG_ENDIAN);
248 proto_tree_add_item(SDP_BSDH_header_tree, hf_ib_sdp_flags_oobpres, tvb, local_offset, 2, ENC_BIG_ENDIAN);
249 proto_tree_add_item(SDP_BSDH_header_tree, hf_ib_sdp_flags_oob_pend, tvb, local_offset, 4, ENC_BIG_ENDIAN);
250 proto_tree_add_item(SDP_BSDH_header_tree, hf_ib_sdp_flags_reqpipe, tvb, local_offset, 4, ENC_BIG_ENDIAN); local_offset += 1;
252 proto_tree_add_item(SDP_BSDH_header_tree, hf_ib_sdp_bufs, tvb, local_offset, 2, ENC_BIG_ENDIAN); local_offset += 2;
253 proto_tree_add_item(SDP_BSDH_header_tree, hf_ib_sdp_len, tvb, local_offset, 4, ENC_BIG_ENDIAN); local_offset += 4;
254 proto_tree_add_item(SDP_BSDH_header_tree, hf_ib_sdp_mseq, tvb, local_offset, 4, ENC_BIG_ENDIAN); local_offset += 4;
255 proto_tree_add_item(SDP_BSDH_header_tree, hf_ib_sdp_mseqack, tvb, local_offset, 4, ENC_BIG_ENDIAN); local_offset += 4;
257 switch (mid) {
258 case Hello:
259 SDP_EH_header_item = proto_tree_add_item(SDP_header_tree, hf_ib_sdp_hh, tvb, local_offset, 48, ENC_NA);
260 SDP_EH_header_tree = proto_item_add_subtree(SDP_EH_header_item, ett_ib_sdp_hh);
261 proto_tree_add_item(SDP_EH_header_tree, hf_ib_sdp_majv, tvb, local_offset, 1, ENC_BIG_ENDIAN);
262 proto_tree_add_item(SDP_EH_header_tree, hf_ib_sdp_minv, tvb, local_offset, 1, ENC_BIG_ENDIAN); local_offset += 1;
263 proto_tree_add_item(SDP_EH_header_tree, hf_ib_sdp_ipv, tvb, local_offset, 1, ENC_BIG_ENDIAN);
264 proto_tree_add_item(SDP_EH_header_tree, hf_ib_sdp_cap, tvb, local_offset, 1, ENC_BIG_ENDIAN);
265 proto_tree_add_item(SDP_EH_header_tree, hf_ib_sdp_cap_invalidate, tvb, local_offset, 1, ENC_BIG_ENDIAN);
266 proto_tree_add_item(SDP_EH_header_tree, hf_ib_sdp_cap_extmaxadverts, tvb, local_offset, 1, ENC_BIG_ENDIAN); local_offset += 1;
267 local_offset += 1; /* skip reserved */
268 proto_tree_add_item(SDP_EH_header_tree, hf_ib_sdp_maxadverts, tvb, local_offset, 1, ENC_BIG_ENDIAN); local_offset += 1;
269 proto_tree_add_item(SDP_EH_header_tree, hf_ib_sdp_desremrcvsz, tvb, local_offset, 4, ENC_BIG_ENDIAN); local_offset += 4;
270 proto_tree_add_item(SDP_EH_header_tree, hf_ib_sdp_localrcvsz, tvb, local_offset, 4, ENC_BIG_ENDIAN); local_offset += 4;
271 proto_tree_add_item(SDP_EH_header_tree, hf_ib_sdp_localport, tvb, local_offset, 2, ENC_BIG_ENDIAN); local_offset += 2;
272 local_offset += 2; /* skip reserved */
273 proto_tree_add_item(SDP_EH_header_tree, hf_ib_sdp_src_ip, tvb, local_offset, 16, ENC_NA); local_offset += 16;
274 proto_tree_add_item(SDP_EH_header_tree, hf_ib_sdp_dst_ip, tvb, local_offset, 16, ENC_NA); local_offset += 16;
275 local_offset += 2; /* skip reserved */
276 proto_tree_add_item(SDP_EH_header_tree, hf_ib_sdp_extmaxadverts, tvb, local_offset, 2, ENC_BIG_ENDIAN); /*local_offset += 2;*/
277 break;
278 case HelloAck:
279 proto_tree_add_item(SDP_header_tree, hf_ib_sdp_hah, tvb, local_offset, 48, ENC_NA);
280 break;
281 case DisConn:
282 break;
283 case AbortConn:
284 break;
285 case SendSm:
286 break;
287 case RdmaWrCompl:
288 proto_tree_add_item(SDP_header_tree, hf_ib_sdp_rwch, tvb, local_offset, 48, ENC_NA);
289 break;
290 case RdmaRdCompl:
291 proto_tree_add_item(SDP_header_tree, hf_ib_sdp_rrch, tvb, local_offset, 48, ENC_NA);
292 break;
293 case ModeChange:
294 proto_tree_add_item(SDP_BSDH_header_tree, hf_ib_sdp_mch, tvb, local_offset, 48, ENC_NA);
295 break;
296 case SrcAvailCancel:
297 break;
298 case SinkAvailCancel:
299 break;
300 case SinkCancelAck:
301 break;
302 case ChRcvBuf:
303 proto_tree_add_item(SDP_header_tree, hf_ib_sdp_crbh, tvb, local_offset, 48, ENC_NA);
304 break;
305 case ChRcvBufAck:
306 proto_tree_add_item(SDP_header_tree, hf_ib_sdp_crbah, tvb, local_offset, 48, ENC_NA);
307 break;
308 case SuspComm:
309 proto_tree_add_item(SDP_header_tree, hf_ib_sdp_suspch, tvb, local_offset, 48, ENC_NA);
310 break;
311 case SuspCommAck:
312 break;
313 case SinkAvail:
314 proto_tree_add_item(SDP_header_tree, hf_ib_sdp_sinkah, tvb, local_offset, 48, ENC_NA);
315 break;
316 case SrcAvail:
317 proto_tree_add_item(SDP_header_tree, hf_ib_sdp_srcah, tvb, local_offset, 48, ENC_NA);
318 break;
319 case Data:
320 proto_tree_add_item(SDP_header_tree, hf_ib_sdp_data, tvb, local_offset, -1, ENC_NA);
321 break;
322 default:
323 break;
326 col_append_fstr(pinfo->cinfo, COL_INFO, "(SDP %s)",
327 rval_to_str(mid, mid_meanings, "Unknown"));
329 return tvb_length(tvb);
332 void
333 proto_register_ib_sdp(void)
335 module_t *ib_sdp_module;
336 static hf_register_info hf[] = {
337 { &hf_ib_sdp, {
338 "SDP", "infiniband_sdp",
339 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}
341 /* SDP BSDH Header */
342 { &hf_ib_sdp_bsdh, {
343 "BSDH", "infiniband_sdp.bsdh",
344 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}
346 { &hf_ib_sdp_mid, {
347 "MID", "infiniband_sdp.bsdh.mid",
348 FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(mid_meanings), 0x0, NULL, HFILL}
350 {&hf_ib_sdp_flags, {
351 "Flags", "infiniband_sdp.bsdh.flags",
352 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
354 {&hf_ib_sdp_flags_oobpres, {
355 "OOB_PRES", "infiniband_sdp.bsdh.oobpres",
356 FT_UINT8, BASE_HEX, NULL, 0x1, "Out-Of-Band Data is present", HFILL}
358 {&hf_ib_sdp_flags_oob_pend, {
359 "OOB_PEND", "infiniband_sdp.bsdh.oobpend",
360 FT_UINT8, BASE_HEX, NULL, 0x2, "Out-Of-Band Data is pending", HFILL}
362 {&hf_ib_sdp_flags_reqpipe, {
363 "REQ_PIPE", "infiniband_sdp.bsdh.reqpipe",
364 FT_UINT8, BASE_HEX, NULL, 0x4, "Request change to Pipelined Mode", HFILL}
366 {&hf_ib_sdp_bufs, {
367 "Buffers", "infiniband_sdp.bsdh.bufs",
368 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
370 {&hf_ib_sdp_len, {
371 "Length", "infiniband_sdp.bsdh.len",
372 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
374 {&hf_ib_sdp_mseq, {
375 "MSeq", "infiniband_sdp.bsdh.mseq",
376 FT_UINT32, BASE_HEX, NULL, 0x0, "Message Sequence Number", HFILL}
378 {&hf_ib_sdp_mseqack, {
379 "MSeqAck", "infiniband_sdp.bsdh.mseqack",
380 FT_UINT32, BASE_HEX, NULL, 0x0, "Message Sequence Number Acknowledgement", HFILL}
382 /* SDP Hello Header */
383 {&hf_ib_sdp_hh, {
384 "Hello Header", "infiniband_sdp.hh",
385 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL}
387 {&hf_ib_sdp_majv, {
388 "Major Protocol Version Number", "infiniband_sdp.hh.majv",
389 FT_UINT8, BASE_HEX, NULL, 0xf0, NULL, HFILL}
391 {&hf_ib_sdp_minv, {
392 "Minor Protocol Version Number", "infiniband_sdp.hh.minv",
393 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL}
395 {&hf_ib_sdp_ipv,
396 {"IP version", "infiniband_sdp.hh.ipv",
397 FT_UINT8, BASE_HEX, NULL, 0xf0, NULL, HFILL}
399 {&hf_ib_sdp_cap, {
400 "Capabilities", "infiniband_sdp.hh.cap",
401 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL}
403 {&hf_ib_sdp_cap_invalidate, {
404 "INVALIDATE_CAP", "infiniband_sdp.hh.cap_invalidate",
405 FT_UINT8, BASE_HEX, NULL, 0x1, "Supports incoming Send w/Invalidate opcode", HFILL}
407 {&hf_ib_sdp_cap_extmaxadverts, {
408 "EXTENDED_MAXADVERTS", "infiniband_sdp.hh.cap_extmaxadverts",
409 FT_UINT8, BASE_HEX, NULL, 0x2, "Extended MaxAdverts is used", HFILL}
411 {&hf_ib_sdp_maxadverts, {
412 "Maximum Advertisements", "infiniband_sdp.hh.maxadverts",
413 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}
415 {&hf_ib_sdp_desremrcvsz, {
416 "DesRemRcvSz", "infiniband_sdp.hh.desremrcvsz",
417 FT_UINT32, BASE_DEC, NULL, 0x0, "Desired Remote Receive Size", HFILL}
419 {&hf_ib_sdp_localrcvsz,
420 {"LocalRcvSz", "infiniband_sdp.hh.localrcvsz",
421 FT_UINT32, BASE_DEC, NULL, 0x0, "Local Receive Size", HFILL}
423 {&hf_ib_sdp_localport, {
424 "Local Port", "infiniband_sdp.hh.localport",
425 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
427 {&hf_ib_sdp_src_ip, {
428 "Source IP", "infiniband_sdp.hh.src_ip",
429 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}
431 {&hf_ib_sdp_dst_ip, {
432 "Destination IP", "infiniband_sdp.hh.dst_ip",
433 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}
435 {&hf_ib_sdp_extmaxadverts, {
436 "Extended MaxAdverts", "infiniband_sdp.hh.extmaxadverts",
437 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}
439 /* Rest of Headers */
440 {&hf_ib_sdp_hah, {
441 "HelloAck Header", "infiniband_sdp.hah",
442 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL}
444 {&hf_ib_sdp_rwch, {
445 "RdmaWrCompl Header", "infiniband_sdp.rwch",
446 FT_NONE, BASE_NONE, NULL, 0x00, "RDMA Write Complete", HFILL}
448 {&hf_ib_sdp_rrch, {
449 "RdmaRdCompl Header", "infiniband_sdp.rrch",
450 FT_NONE, BASE_NONE, NULL, 0x00, "RDMA Read Complete", HFILL}
452 {&hf_ib_sdp_mch, {
453 "ModeChange Header", "infiniband_sdp.mch",
454 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL}
456 {&hf_ib_sdp_crbh, {
457 "ChRcvBuf Header", "infiniband_sdp.crbh",
458 FT_NONE, BASE_NONE, NULL, 0x00, "Change Receive private Buffer size", HFILL}
460 {&hf_ib_sdp_crbah, {
461 "ChRcvBufAck Header", "infiniband_sdp.crbah",
462 FT_NONE, BASE_NONE, NULL, 0x00, "Change Receive private Buffer size Acknowledgement", HFILL}
464 {&hf_ib_sdp_suspch, {
465 "SuspComm Header", "infiniband_sdp.suspch",
466 FT_NONE, BASE_NONE, NULL, 0x00, "Suspend Communication", HFILL}
468 {&hf_ib_sdp_sinkah, {
469 "SinkAvail Header", "infiniband_sdp.sinkah",
470 FT_NONE, BASE_NONE, NULL, 0x00, "Data Sink Available", HFILL}
472 {&hf_ib_sdp_srcah, {
473 "SrcAvail Header", "infiniband_sdp.srcah",
474 FT_NONE, BASE_NONE, NULL, 0x00, "Data Source Available", HFILL}
476 {&hf_ib_sdp_data, {
477 "Data", "infiniband_sdp.Data",
478 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}
482 /* Setup protocol subtree array */
483 static gint *ett[] = {
484 &ett_ib_sdp,
485 &ett_ib_sdp_bsdh,
486 &ett_ib_sdp_hh,
489 proto_ib_sdp = proto_register_protocol("Infiniband Sockets Direct Protocol", "Infiniband SDP", "infiniband_sdp");
491 new_register_dissector("infiniband_sdp", dissect_ib_sdp, proto_ib_sdp);
493 /* Required function calls to register the header fields and subtrees used */
494 proto_register_field_array(proto_ib_sdp, hf, array_length(hf));
495 proto_register_subtree_array(ett, array_length(ett));
497 /* Register preferences */
498 ib_sdp_module = prefs_register_protocol(proto_ib_sdp, proto_reg_handoff_ib_sdp);
500 prefs_register_bool_preference(ib_sdp_module, "manual_en", "Enable manual settings",
501 "Check to treat all traffic between the configured source/destination as SDP",
502 &gPREF_MAN_EN);
504 prefs_register_static_text_preference(ib_sdp_module, "addr_a", "Address A",
505 "Side A of the manually-configured connection");
506 prefs_register_enum_preference(ib_sdp_module, "addr_a_type", "Address Type",
507 "Type of address specified", &gPREF_TYPE[0], pref_address_types, FALSE);
508 prefs_register_string_preference(ib_sdp_module, "addr_a_id", "ID",
509 "LID/GID of address A", &gPREF_ID[0]);
510 prefs_register_uint_preference(ib_sdp_module, "addr_a_qp", "QP Number",
511 "QP Number for address A", 10, &gPREF_QP[0]);
513 prefs_register_static_text_preference(ib_sdp_module, "addr_b", "Address B",
514 "Side B of the manually-configured connection");
515 prefs_register_enum_preference(ib_sdp_module, "addr_b_type", "Address Type",
516 "Type of address specified", &gPREF_TYPE[1], pref_address_types, FALSE);
517 prefs_register_string_preference(ib_sdp_module, "addr_b_id", "ID",
518 "LID/GID of address B", &gPREF_ID[1]);
519 prefs_register_uint_preference(ib_sdp_module, "addr_b_qp", "QP Number",
520 "QP Number for address B", 10, &gPREF_QP[1]);
523 void
524 proto_reg_handoff_ib_sdp(void)
526 static gboolean initialized = FALSE;
528 if (!initialized) {
529 heur_dissector_add("infiniband.payload", dissect_ib_sdp, proto_ib_sdp);
530 heur_dissector_add("infiniband.mad.cm.private", dissect_ib_sdp, proto_ib_sdp);
532 /* allocate enough space in the addresses to store the largest address (a GID) */
533 manual_addr_data[0] = wmem_alloc(wmem_epan_scope(), GID_SIZE);
534 manual_addr_data[1] = wmem_alloc(wmem_epan_scope(), GID_SIZE);
536 initialized = TRUE;
539 if (gPREF_MAN_EN) {
540 /* the manual setting is enabled, so parse the settings into the address type */
541 gboolean error_occured = FALSE;
542 char *not_parsed;
543 int i;
545 for (i = 0; i < 2; i++) {
546 if (gPREF_TYPE[i] == 0) { /* LID */
547 errno = 0; /* reset any previous error indicators */
548 *((guint16*)manual_addr_data[i]) = (guint16)strtoul(gPREF_ID[i], &not_parsed, 0);
549 if (errno || *not_parsed != '\0') {
550 error_occured = TRUE;
551 } else {
552 SET_ADDRESS(&manual_addr[i], AT_IB, sizeof(guint16), manual_addr_data[i]);
554 } else { /* GID */
555 if (inet_pton(AF_INET6, gPREF_ID[i], manual_addr_data[i]) <= 0) {
556 error_occured = TRUE;
557 } else {
558 SET_ADDRESS(&manual_addr[i], AT_IB, GID_SIZE, manual_addr_data[i]);
562 if (error_occured) {
563 /* an invalid id was specified - disable manual settings until it's fixed */
564 gPREF_MAN_EN = FALSE;
565 break;