/src/wireshark/epan/dissectors/packet-idp.c
Line | Count | Source |
1 | | /* packet-idp.c |
2 | | * Routines for XNS IDP |
3 | | * Based on the Netware IPX dissector by Gilbert Ramirez <gram@alumni.rice.edu> |
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 "packet-idp.h" |
16 | | #include <epan/etypes.h> |
17 | | #include <epan/unit_strings.h> |
18 | | |
19 | | void proto_register_idp(void); |
20 | | void proto_reg_handoff_idp(void); |
21 | | |
22 | | static dissector_handle_t idp_handle; |
23 | | |
24 | | static int proto_idp; |
25 | | static int hf_idp_checksum; |
26 | | static int hf_idp_len; |
27 | | /* static int hf_idp_src; */ |
28 | | /* static int hf_idp_dst; */ |
29 | | static int hf_idp_hops; |
30 | | static int hf_idp_packet_type; |
31 | | static int hf_idp_dnet; |
32 | | static int hf_idp_dnode; |
33 | | static int hf_idp_dsocket; |
34 | | static int hf_idp_snet; |
35 | | static int hf_idp_snode; |
36 | | static int hf_idp_ssocket; |
37 | | |
38 | | static int ett_idp; |
39 | | |
40 | | static dissector_table_t idp_type_dissector_table; |
41 | | |
42 | | /* |
43 | | * See |
44 | | * |
45 | | * "Internet Transport Protocols", XSIS 028112, December 1981 |
46 | | * |
47 | | * if you can find it; this is based on the headers in the BSD XNS |
48 | | * implementation. |
49 | | */ |
50 | | |
51 | 98 | #define IDP_HEADER_LEN 30 /* It's *always* 30 bytes */ |
52 | | |
53 | | static const value_string idp_packet_type_vals[] = { |
54 | | { IDP_PACKET_TYPE_RIP, "RIP" }, |
55 | | { IDP_PACKET_TYPE_ECHO, "Echo" }, |
56 | | { IDP_PACKET_TYPE_ERROR, "Error" }, |
57 | | { IDP_PACKET_TYPE_PEP, "PEP" }, |
58 | | { IDP_PACKET_TYPE_SPP, "SPP" }, |
59 | | { IDP_PACKET_TYPE_PUPLOOKUP, "PUPLookup"}, |
60 | | { 0, NULL } |
61 | | }; |
62 | | |
63 | | static const value_string idp_socket_vals[] = { |
64 | | { IDP_SOCKET_RIP, "RIP"}, |
65 | | { IDP_SOCKET_ECHO, "Echo"}, |
66 | | { IDP_SOCKET_ERROR, "Error"}, |
67 | | { IDP_SOCKET_COURIER, "Courier"}, |
68 | | { IDP_SOCKET_TIME, "Time"}, |
69 | | { IDP_SOCKET_PUPLOOKUP, "PUPLookup"}, |
70 | | { IDP_SOCKET_SMB, "SMB" }, |
71 | | { 0, NULL } |
72 | | }; |
73 | | |
74 | | static int |
75 | | dissect_idp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
76 | 49 | { |
77 | 49 | proto_tree *idp_tree; |
78 | 49 | proto_item *ti; |
79 | 49 | uint16_t length; |
80 | 49 | uint8_t type; |
81 | 49 | tvbuff_t *next_tvb; |
82 | | |
83 | 49 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "IDP"); |
84 | 49 | col_clear(pinfo->cinfo, COL_INFO); |
85 | | |
86 | 49 | ti = proto_tree_add_item(tree, proto_idp, tvb, 0, IDP_HEADER_LEN, ENC_NA); |
87 | 49 | idp_tree = proto_item_add_subtree(ti, ett_idp); |
88 | | |
89 | 49 | proto_tree_add_checksum(idp_tree, tvb, 0, hf_idp_checksum, -1, NULL, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS); |
90 | 49 | length = tvb_get_ntohs(tvb, 2); |
91 | 49 | proto_tree_add_uint(idp_tree, hf_idp_len, tvb, 2, 2, length); |
92 | | /* Adjust the tvbuff length to include only the IDP datagram. */ |
93 | 49 | set_actual_length(tvb, length); |
94 | 49 | proto_tree_add_item(idp_tree, hf_idp_hops, tvb, 4, 1, ENC_BIG_ENDIAN); |
95 | 49 | type = tvb_get_uint8(tvb, 5); |
96 | 49 | proto_tree_add_uint(idp_tree, hf_idp_packet_type, tvb, 5, 1, type); |
97 | | |
98 | 49 | pinfo->ptype = PT_IDP; |
99 | | |
100 | | /* Destination */ |
101 | 49 | proto_tree_add_item(idp_tree, hf_idp_dnet, tvb, 6, 4, ENC_BIG_ENDIAN); |
102 | 49 | proto_tree_add_item(idp_tree, hf_idp_dnode, tvb, 10, 6, ENC_NA); |
103 | 49 | pinfo->destport = tvb_get_ntohs(tvb, 16); |
104 | 49 | proto_tree_add_uint(idp_tree, hf_idp_dsocket, tvb, 16, 2, |
105 | 49 | pinfo->destport); |
106 | | |
107 | | /* Source */ |
108 | 49 | proto_tree_add_item(idp_tree, hf_idp_snet, tvb, 18, 4, ENC_BIG_ENDIAN); |
109 | 49 | proto_tree_add_item(idp_tree, hf_idp_snode, tvb, 22, 6, ENC_NA); |
110 | 49 | pinfo->srcport = tvb_get_ntohs(tvb, 28); |
111 | 49 | proto_tree_add_uint(idp_tree, hf_idp_ssocket, tvb, 28, 2, |
112 | 49 | pinfo->srcport); |
113 | | |
114 | | /* Make the next tvbuff */ |
115 | 49 | next_tvb = tvb_new_subset_remaining(tvb, IDP_HEADER_LEN); |
116 | | |
117 | | /* |
118 | | * Hand off to the dissector for the packet type. |
119 | | */ |
120 | 49 | if (!dissector_try_uint(idp_type_dissector_table, type, next_tvb, |
121 | 49 | pinfo, tree)) |
122 | 9 | { |
123 | 9 | call_data_dissector(next_tvb, pinfo, tree); |
124 | 9 | } |
125 | 49 | return tvb_captured_length(tvb); |
126 | 49 | } |
127 | | |
128 | | void |
129 | | proto_register_idp(void) |
130 | 16 | { |
131 | 16 | static hf_register_info hf_idp[] = { |
132 | 16 | { &hf_idp_checksum, |
133 | 16 | { "Checksum", "idp.checksum", FT_UINT16, BASE_HEX, |
134 | 16 | NULL, 0x0, NULL, HFILL }}, |
135 | | |
136 | | #if 0 |
137 | | { &hf_idp_src, |
138 | | { "Source Address", "idp.src", FT_STRING, BASE_NONE, |
139 | | NULL, 0x0, NULL, HFILL }}, |
140 | | #endif |
141 | | |
142 | | #if 0 |
143 | | { &hf_idp_dst, |
144 | | { "Destination Address", "idp.dst", FT_STRING, BASE_NONE, |
145 | | NULL, 0x0, NULL, HFILL }}, |
146 | | #endif |
147 | | |
148 | 16 | { &hf_idp_len, |
149 | 16 | { "Length", "idp.len", FT_UINT16, BASE_DEC|BASE_UNIT_STRING, |
150 | 16 | UNS(&units_byte_bytes), 0x0, NULL, HFILL }}, |
151 | | |
152 | | /* XXX - does this have separate hop count and time subfields? */ |
153 | 16 | { &hf_idp_hops, |
154 | 16 | { "Transport Control (Hops)", "idp.hops", FT_UINT8, BASE_DEC, |
155 | 16 | NULL, 0x0, NULL, HFILL }}, |
156 | | |
157 | 16 | { &hf_idp_packet_type, |
158 | 16 | { "Packet Type", "idp.packet_type", FT_UINT8, BASE_DEC, |
159 | 16 | VALS(idp_packet_type_vals), 0x0, NULL, HFILL }}, |
160 | | |
161 | 16 | { &hf_idp_dnet, |
162 | 16 | { "Destination Network","idp.dst.net", FT_UINT32, BASE_HEX, |
163 | 16 | NULL, 0x0, NULL, HFILL }}, |
164 | | |
165 | 16 | { &hf_idp_dnode, |
166 | 16 | { "Destination Node", "idp.dst.node", FT_ETHER, BASE_NONE, |
167 | 16 | NULL, 0x0, NULL, HFILL }}, |
168 | | |
169 | 16 | { &hf_idp_dsocket, |
170 | 16 | { "Destination Socket", "idp.dst.socket", FT_UINT16, BASE_HEX, |
171 | 16 | VALS(idp_socket_vals), 0x0, NULL, HFILL }}, |
172 | | |
173 | 16 | { &hf_idp_snet, |
174 | 16 | { "Source Network","idp.src.net", FT_UINT32, BASE_HEX, |
175 | 16 | NULL, 0x0, NULL, HFILL }}, |
176 | | |
177 | 16 | { &hf_idp_snode, |
178 | 16 | { "Source Node", "idp.src.node", FT_ETHER, BASE_NONE, |
179 | 16 | NULL, 0x0, NULL, HFILL }}, |
180 | | |
181 | 16 | { &hf_idp_ssocket, |
182 | 16 | { "Source Socket", "idp.src.socket", FT_UINT16, BASE_HEX, |
183 | 16 | VALS(idp_socket_vals), 0x0, NULL, HFILL }}, |
184 | 16 | }; |
185 | | |
186 | 16 | static int *ett[] = { |
187 | 16 | &ett_idp, |
188 | 16 | }; |
189 | | |
190 | 16 | proto_idp = proto_register_protocol("Internetwork Datagram Protocol", |
191 | 16 | "IDP", "idp"); |
192 | 16 | proto_register_field_array(proto_idp, hf_idp, array_length(hf_idp)); |
193 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
194 | | |
195 | 16 | idp_type_dissector_table = register_dissector_table("idp.packet_type", |
196 | 16 | "IDP packet type", proto_idp, FT_UINT8, BASE_DEC); |
197 | | |
198 | 16 | idp_handle = register_dissector("idp", dissect_idp, proto_idp); |
199 | 16 | } |
200 | | |
201 | | void |
202 | | proto_reg_handoff_idp(void) |
203 | 16 | { |
204 | 16 | dissector_add_uint("ethertype", ETHERTYPE_XNS_IDP, idp_handle); |
205 | 16 | dissector_add_uint("chdlc.protocol", ETHERTYPE_XNS_IDP, idp_handle); |
206 | 16 | } |
207 | | |
208 | | /* |
209 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
210 | | * |
211 | | * Local variables: |
212 | | * c-basic-offset: 8 |
213 | | * tab-width: 8 |
214 | | * indent-tabs-mode: t |
215 | | * End: |
216 | | * |
217 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
218 | | * :indentSize=8:tabSize=8:noTabs=false: |
219 | | */ |