2 * Routines for decoding IP over InfiniBand (IPoIB) packet disassembly
3 * See: https://tools.ietf.org/html/rfc4391#section-6
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include <epan/etypes.h>
16 #include <wiretap/wtap.h>
18 void proto_register_ipoib(void);
19 void proto_reg_handoff_ipoib(void);
21 static dissector_handle_t ipoib_handle
;
23 static int proto_ipoib
;
26 static int hf_daddr_qpn
;
28 static int hf_grh_ip_version
;
29 static int hf_grh_traffic_class
;
30 static int hf_grh_flow_label
;
31 static int hf_grh_sqpn
;
32 static int hf_grh_sgid
;
34 static int hf_reserved
;
39 static dissector_handle_t arp_handle
;
40 static dissector_handle_t ip_handle
;
41 static dissector_handle_t ipv6_handle
;
44 dissect_ipoib(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
47 proto_tree
*fh_subtree
;
53 if (pinfo
->rec
->rec_header
.packet_header
.pkt_encap
== WTAP_ENCAP_IP_OVER_IB_PCAP
)
56 /* load the top pane info. This should be overwritten by
57 the next protocol in the stack */
58 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "IPoIB");
59 col_set_str(pinfo
->cinfo
, COL_INFO
, "IP over Infiniband");
61 /* populate a tree in the second pane with the IPoIB header data */
63 ti
= proto_tree_add_item (tree
, proto_ipoib
, tvb
, 0, grh_size
+ 4, ENC_NA
);
64 fh_tree
= proto_item_add_subtree(ti
, ett_raw
);
66 /* for PCAP data populate subtree with GRH pseudo header data */
67 if (pinfo
->rec
->rec_header
.packet_header
.pkt_encap
== WTAP_ENCAP_IP_OVER_IB_PCAP
) {
69 /* Zero means GRH is not valid (unicast). Only destination
71 if (tvb_get_ntohs(tvb
, 0) == 0) {
72 ti
= proto_tree_add_item (fh_tree
, hf_daddr
, tvb
, 20, 20, ENC_NA
);
73 fh_subtree
= proto_item_add_subtree(ti
, ett_hdr
);
75 proto_tree_add_item(fh_subtree
, hf_daddr_qpn
, tvb
, 21, 3, ENC_BIG_ENDIAN
);
76 proto_tree_add_item(fh_subtree
, hf_dgid
, tvb
, 24, 16, ENC_NA
);
78 ti
= proto_tree_add_item (fh_tree
, hf_grh
, tvb
, 0, 40, ENC_NA
);
79 fh_subtree
= proto_item_add_subtree(ti
, ett_hdr
);
81 proto_tree_add_item(fh_subtree
, hf_grh_ip_version
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
82 proto_tree_add_item(fh_subtree
, hf_grh_traffic_class
, tvb
, 0, 2, ENC_BIG_ENDIAN
);
83 proto_tree_add_item(fh_subtree
, hf_grh_flow_label
,tvb
, 0, 4, ENC_BIG_ENDIAN
);
84 proto_tree_add_item(fh_subtree
, hf_grh_sqpn
, tvb
, 5, 3, ENC_BIG_ENDIAN
);
85 proto_tree_add_item(fh_subtree
, hf_grh_sgid
, tvb
, 8, 16, ENC_NA
);
86 proto_tree_add_item(fh_subtree
, hf_dgid
, tvb
, 24, 16, ENC_NA
);
90 proto_tree_add_item(fh_tree
, hf_type
, tvb
, grh_size
+ 0, 2, ENC_BIG_ENDIAN
);
91 proto_tree_add_item(fh_tree
, hf_reserved
, tvb
, grh_size
+ 2, 2, ENC_BIG_ENDIAN
);
94 next_tvb
= tvb_new_subset_remaining(tvb
, grh_size
+ 4);
96 type
= tvb_get_ntohs(tvb
, grh_size
+ 0);
99 call_dissector(ip_handle
, next_tvb
, pinfo
, tree
);
102 call_dissector(ipv6_handle
, next_tvb
, pinfo
, tree
);
105 case ETHERTYPE_REVARP
:
106 call_dissector(arp_handle
, next_tvb
, pinfo
, tree
);
111 return tvb_captured_length(tvb
);
115 proto_register_ipoib(void)
117 static hf_register_info hf
[] = {
119 { "Destination address", "ipoib.daddr",
120 FT_NONE
, BASE_NONE
, NULL
, 0x0,
123 { "Destination QPN", "ipoib.daddr.qpn",
124 FT_UINT24
, BASE_HEX
, NULL
, 0x0,
127 { "Destination GID", "ipoib.dgid",
128 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
131 { "Global Route Header", "ipoib.grh",
132 FT_NONE
, BASE_NONE
, NULL
, 0x0,
134 { &hf_grh_ip_version
, {
135 "IP Version", "ipoib.grh.ipver",
136 FT_UINT8
, BASE_DEC
, NULL
, 0xF0,
138 { &hf_grh_traffic_class
, {
139 "Traffic Class", "ipoib.grh.tclass",
140 FT_UINT16
, BASE_DEC
, NULL
, 0x0FF0,
142 { &hf_grh_flow_label
, {
143 "Flow Label", "ipoib.grh.flowlabel",
144 FT_UINT32
, BASE_DEC
, NULL
, 0x000FFFFF,
147 { "Source QPN", "ipoib.grh.sqpn",
148 FT_UINT24
, BASE_HEX
, NULL
, 0x0,
151 { "Source GID", "ipoib.grh.sgid",
152 FT_IPv6
, BASE_NONE
, NULL
, 0x0,
155 { "Type", "ipoib.type",
156 FT_UINT16
, BASE_HEX
, VALS(etype_vals
), 0x0,
159 { "Reserved", "ipoib.reserved",
160 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
164 static int *ett
[] = {
169 proto_ipoib
= proto_register_protocol("IP over Infiniband", "IPoIB", "ipoib");
170 proto_register_field_array(proto_ipoib
, hf
, array_length(hf
));
171 proto_register_subtree_array(ett
, array_length(ett
));
173 ipoib_handle
= register_dissector("ipoib", dissect_ipoib
, proto_ipoib
);
177 proto_reg_handoff_ipoib(void)
180 * Get handles for the ARP, IP and IPv6 dissectors.
182 arp_handle
= find_dissector_add_dependency("arp", proto_ipoib
);
183 ip_handle
= find_dissector_add_dependency("ip", proto_ipoib
);
184 ipv6_handle
= find_dissector_add_dependency("ipv6", proto_ipoib
);
186 dissector_add_uint("wtap_encap", WTAP_ENCAP_IP_OVER_IB_SNOOP
, ipoib_handle
);
187 dissector_add_uint("wtap_encap", WTAP_ENCAP_IP_OVER_IB_PCAP
, ipoib_handle
);
191 * Editor modelines - https://www.wireshark.org/tools/modelines.html
196 * indent-tabs-mode: nil
199 * ex: set shiftwidth=2 tabstop=8 expandtab:
200 * :indentSize=2:tabSize=8:noTabs=true: