Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-spp.c
blobddfd89c22def93b246cfe255465b725a98d8c905
1 /* packet-spp.c
2 * Routines for XNS SPP
3 * Based on the Netware SPX dissector by Gilbert Ramirez <gram@alumni.rice.edu>
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
12 #include "config.h"
14 #include <epan/packet.h>
15 #include "packet-idp.h"
17 void proto_register_spp(void);
18 void proto_reg_handoff_spp(void);
19 static dissector_handle_t spp_handle;
21 static int proto_spp;
22 static int hf_spp_connection_control;
23 static int hf_spp_connection_control_sys;
24 static int hf_spp_connection_control_send_ack;
25 static int hf_spp_connection_control_attn;
26 static int hf_spp_connection_control_eom;
27 static int hf_spp_datastream_type;
28 static int hf_spp_src_id;
29 static int hf_spp_dst_id;
30 static int hf_spp_seq_nr;
31 static int hf_spp_ack_nr;
32 static int hf_spp_all_nr;
33 /* static int hf_spp_rexmt_frame; */
35 static int ett_spp;
36 static int ett_spp_connctrl;
38 static dissector_table_t spp_socket_dissector_table;
41 * See
43 * "Internet Transport Protocols", XSIS 028112, December 1981
45 * if you can find it; this is based on the headers in the BSD XNS
46 * implementation.
49 #define SPP_SYS_PACKET 0x80
50 #define SPP_SEND_ACK 0x40
51 #define SPP_ATTN 0x20
52 #define SPP_EOM 0x10
54 static const char*
55 spp_conn_ctrl(uint8_t ctrl)
57 static const value_string conn_vals[] = {
58 { 0x00, "Data, No Ack Required" },
59 { SPP_EOM, "End-of-Message" },
60 { SPP_ATTN, "Attention" },
61 { SPP_SEND_ACK, "Acknowledgment Required"},
62 { SPP_SEND_ACK|SPP_EOM, "Send Ack: End Message"},
63 { SPP_SYS_PACKET, "System Packet"},
64 { SPP_SYS_PACKET|SPP_SEND_ACK, "System Packet: Send Ack"},
65 { 0x00, NULL }
68 return val_to_str_const((ctrl & 0xf0), conn_vals, "Unknown");
71 static const char*
72 spp_datastream(uint8_t type)
74 switch (type) {
75 case 0xfe:
76 return "End-of-Connection";
77 case 0xff:
78 return "End-of-Connection Acknowledgment";
79 default:
80 return NULL;
84 #define SPP_HEADER_LEN 12
87 * XXX - do reassembly, using the EOM flag. (Then do that in the Netware
88 * SPX implementation, too.)
90 * XXX - hand off to subdissectors based on the socket number.
92 static int
93 dissect_spp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
95 proto_tree *spp_tree;
96 proto_item *ti;
97 tvbuff_t *next_tvb;
98 uint8_t conn_ctrl;
99 uint8_t datastream_type;
100 const char *datastream_type_string;
101 uint16_t spp_seq;
102 const char *spp_msg_string;
103 uint16_t low_socket, high_socket;
104 static int * const ctrl[] = {
105 &hf_spp_connection_control_sys,
106 &hf_spp_connection_control_send_ack,
107 &hf_spp_connection_control_attn,
108 &hf_spp_connection_control_eom,
109 NULL
112 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SPP");
113 col_set_str(pinfo->cinfo, COL_INFO, "SPP");
115 ti = proto_tree_add_item(tree, proto_spp, tvb, 0, SPP_HEADER_LEN, ENC_NA);
116 spp_tree = proto_item_add_subtree(ti, ett_spp);
118 conn_ctrl = tvb_get_uint8(tvb, 0);
119 spp_msg_string = spp_conn_ctrl(conn_ctrl);
120 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", spp_msg_string);
122 proto_tree_add_bitmask_with_flags(spp_tree, tvb, 0, hf_spp_connection_control, ett_spp_connctrl,
123 ctrl, ENC_NA, BMT_NO_FALSE);
125 datastream_type = tvb_get_uint8(tvb, 1);
126 datastream_type_string = spp_datastream(datastream_type);
127 if (datastream_type_string != NULL) {
128 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", datastream_type_string);
130 if (tree) {
131 if (datastream_type_string != NULL) {
132 proto_tree_add_uint_format_value(spp_tree, hf_spp_datastream_type, tvb,
133 1, 1, datastream_type,
134 "%s (0x%02X)",
135 datastream_type_string,
136 datastream_type);
137 } else {
138 proto_tree_add_uint(spp_tree, hf_spp_datastream_type, tvb,
139 1, 1, datastream_type);
141 proto_tree_add_item(spp_tree, hf_spp_src_id, tvb, 2, 2, ENC_BIG_ENDIAN);
142 proto_tree_add_item(spp_tree, hf_spp_dst_id, tvb, 4, 2, ENC_BIG_ENDIAN);
144 spp_seq = tvb_get_ntohs(tvb, 6);
145 if (tree) {
146 proto_tree_add_uint(spp_tree, hf_spp_seq_nr, tvb, 6, 2, spp_seq);
147 proto_tree_add_item(spp_tree, hf_spp_ack_nr, tvb, 8, 2, ENC_BIG_ENDIAN);
148 proto_tree_add_item(spp_tree, hf_spp_all_nr, tvb, 10, 2, ENC_BIG_ENDIAN);
151 if (tvb_reported_length_remaining(tvb, SPP_HEADER_LEN) > 0) {
152 if (pinfo->srcport > pinfo->destport) {
153 low_socket = pinfo->destport;
154 high_socket = pinfo->srcport;
155 } else {
156 low_socket = pinfo->srcport;
157 high_socket = pinfo->destport;
160 next_tvb = tvb_new_subset_remaining(tvb, SPP_HEADER_LEN);
161 if (dissector_try_uint(spp_socket_dissector_table, low_socket,
162 next_tvb, pinfo, tree))
163 return tvb_captured_length(tvb);
165 if (dissector_try_uint(spp_socket_dissector_table, high_socket,
166 next_tvb, pinfo, tree))
167 return tvb_captured_length(tvb);
169 call_data_dissector(next_tvb, pinfo, tree);
171 return tvb_captured_length(tvb);
175 void
176 proto_register_spp(void)
178 static hf_register_info hf_spp[] = {
179 { &hf_spp_connection_control,
180 { "Connection Control", "spp.ctl",
181 FT_UINT8, BASE_HEX, NULL, 0x0,
182 NULL, HFILL }},
184 { &hf_spp_connection_control_sys,
185 { "System Packet", "spp.ctl.sys",
186 FT_BOOLEAN, 8, NULL, SPP_SYS_PACKET,
187 NULL, HFILL }},
189 { &hf_spp_connection_control_send_ack,
190 { "Send Ack", "spp.ctl.send_ack",
191 FT_BOOLEAN, 8, NULL, SPP_SEND_ACK,
192 NULL, HFILL }},
194 { &hf_spp_connection_control_attn,
195 { "Attention", "spp.ctl.attn",
196 FT_BOOLEAN, 8, NULL, SPP_ATTN,
197 NULL, HFILL }},
199 { &hf_spp_connection_control_eom,
200 { "End of Message", "spp.ctl.eom",
201 FT_BOOLEAN, 8, NULL, SPP_EOM,
202 NULL, HFILL }},
204 { &hf_spp_datastream_type,
205 { "Datastream Type", "spp.type",
206 FT_UINT8, BASE_HEX, NULL, 0x0,
207 NULL, HFILL }},
209 { &hf_spp_src_id,
210 { "Source Connection ID", "spp.src",
211 FT_UINT16, BASE_DEC, NULL, 0x0,
212 NULL, HFILL }},
214 { &hf_spp_dst_id,
215 { "Destination Connection ID", "spp.dst",
216 FT_UINT16, BASE_DEC, NULL, 0x0,
217 NULL, HFILL }},
219 { &hf_spp_seq_nr,
220 { "Sequence Number", "spp.seq",
221 FT_UINT16, BASE_DEC, NULL, 0x0,
222 NULL, HFILL }},
224 { &hf_spp_ack_nr,
225 { "Acknowledgment Number", "spp.ack",
226 FT_UINT16, BASE_DEC, NULL, 0x0,
227 NULL, HFILL }},
229 { &hf_spp_all_nr,
230 { "Allocation Number", "spp.alloc",
231 FT_UINT16, BASE_DEC, NULL, 0x0,
232 NULL, HFILL }},
234 #if 0
235 { &hf_spp_rexmt_frame,
236 { "Retransmitted Frame Number", "spp.rexmt_frame",
237 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
238 NULL, HFILL }},
239 #endif
242 static int *ett[] = {
243 &ett_spp,
244 &ett_spp_connctrl,
247 proto_spp = proto_register_protocol("Sequenced Packet Protocol",
248 "SPP", "spp");
249 proto_register_field_array(proto_spp, hf_spp, array_length(hf_spp));
250 proto_register_subtree_array(ett, array_length(ett));
251 spp_handle = register_dissector("spp", dissect_spp, proto_spp);
253 spp_socket_dissector_table = register_dissector_table("spp.socket",
254 "SPP socket", proto_spp, FT_UINT16, BASE_HEX);
257 void
258 proto_reg_handoff_spp(void)
260 dissector_add_uint("idp.packet_type", IDP_PACKET_TYPE_SPP, spp_handle);
264 * Editor modelines - https://www.wireshark.org/tools/modelines.html
266 * Local variables:
267 * c-basic-offset: 8
268 * tab-width: 8
269 * indent-tabs-mode: t
270 * End:
272 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
273 * :indentSize=8:tabSize=8:noTabs=false: