dcerpc-netlogon: remove unused variable
[wireshark-sm.git] / epan / xdlc.c
blob102417530ae4de387c941776470af82537810237
1 /* xdlc.c
2 * Routines for use by various SDLC-derived protocols, such as HDLC
3 * and its derivatives LAPB, IEEE 802.2 LLC, etc..
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 <stdio.h>
15 #include <string.h>
17 #include <glib.h>
18 #include <epan/packet.h>
19 #include <epan/xdlc.h>
20 #include <wsutil/pint.h>
22 const value_string ftype_vals[] = {
23 { XDLC_I, "Information frame" },
24 { XDLC_S, "Supervisory frame" },
25 { XDLC_U, "Unnumbered frame" },
26 { 0, NULL }
29 const value_string stype_vals[] = {
30 { XDLC_RR>>2, "Receiver ready" },
31 { XDLC_RNR>>2, "Receiver not ready" },
32 { XDLC_REJ>>2, "Reject" },
33 { XDLC_SREJ>>2, "Selective reject" },
34 { 0, NULL }
37 static const value_string modifier_short_vals_cmd[] = {
38 { XDLC_UI, "UI" },
39 { XDLC_UP, "UP" },
40 { XDLC_DISC, "DISC" },
41 { XDLC_UA, "UA" },
42 { XDLC_SNRM, "SNRM" },
43 { XDLC_SNRME, "SNRME" },
44 { XDLC_TEST, "TEST" },
45 { XDLC_SIM, "SIM" },
46 { XDLC_FRMR, "FRMR" },
47 { XDLC_CFGR, "CFGR" },
48 { XDLC_SARM, "SARM" },
49 { XDLC_SABM, "SABM" },
50 { XDLC_SARME, "SARME" },
51 { XDLC_SABME, "SABME" },
52 { XDLC_RESET, "RESET" },
53 { XDLC_XID, "XID" },
54 { XDLC_SNRME, "SNRME" },
55 { XDLC_BCN, "BCN" },
56 { 0, NULL }
59 const value_string modifier_vals_cmd[] = {
60 { XDLC_UI>>2, "Unnumbered Information" },
61 { XDLC_UP>>2, "Unnumbered Poll" },
62 { XDLC_DISC>>2, "Disconnect" },
63 { XDLC_UA>>2, "Unnumbered Acknowledge" },
64 { XDLC_SNRM>>2, "Set Normal Response Mode" },
65 { XDLC_TEST>>2, "Test" },
66 { XDLC_SIM>>2, "Set Initialization Mode" },
67 { XDLC_FRMR>>2, "Frame reject" },
68 { XDLC_CFGR>>2, "Configure" },
69 { XDLC_SARM>>2, "Set Asynchronous Response Mode" },
70 { XDLC_SABM>>2, "Set Asynchronous Balanced Mode" },
71 { XDLC_SARME>>2, "Set Asynchronous Response Mode Extended" },
72 { XDLC_SABME>>2, "Set Asynchronous Balanced Mode Extended" },
73 { XDLC_RESET>>2, "Reset" },
74 { XDLC_XID>>2, "Exchange identification" },
75 { XDLC_SNRME>>2, "Set Normal Response Mode Extended" },
76 { XDLC_BCN>>2, "Beacon" },
77 { 0, NULL }
80 static const value_string modifier_short_vals_resp[] = {
81 { XDLC_UI, "UI" },
82 { XDLC_UP, "UP" },
83 { XDLC_RD, "RD" },
84 { XDLC_UA, "UA" },
85 { XDLC_SNRM, "SNRM" },
86 { XDLC_TEST, "TEST" },
87 { XDLC_RIM, "RIM" },
88 { XDLC_FRMR, "FRMR" },
89 { XDLC_CFGR, "CFGR" },
90 { XDLC_DM, "DM" },
91 { XDLC_SABM, "SABM" },
92 { XDLC_SARME, "SARME" },
93 { XDLC_SABME, "SABME" },
94 { XDLC_RESET, "RESET" },
95 { XDLC_XID, "XID" },
96 { XDLC_SNRME, "SNRME" },
97 { XDLC_BCN, "BCN" },
98 { 0, NULL }
101 const value_string modifier_vals_resp[] = {
102 { XDLC_UI>>2, "Unnumbered Information" },
103 { XDLC_UP>>2, "Unnumbered Poll" },
104 { XDLC_RD>>2, "Request Disconnect" },
105 { XDLC_UA>>2, "Unnumbered Acknowledge" },
106 { XDLC_SNRM>>2, "Set Normal Response Mode" },
107 { XDLC_TEST>>2, "Test" },
108 { XDLC_RIM>>2, "Request Initialization Mode" },
109 { XDLC_FRMR>>2, "Frame reject" },
110 { XDLC_CFGR>>2, "Configure" },
111 { XDLC_DM>>2, "Disconnected mode" },
112 { XDLC_SABM>>2, "Set Asynchronous Balanced Mode" },
113 { XDLC_SARME>>2, "Set Asynchronous Response Mode Extended" },
114 { XDLC_SABME>>2, "Set Asynchronous Balanced Mode Extended" },
115 { XDLC_RESET>>2, "Reset" },
116 { XDLC_XID>>2, "Exchange identification" },
117 { XDLC_SNRME>>2, "Set Normal Response Mode Extended" },
118 { XDLC_BCN>>2, "Beacon" },
119 { 0, NULL }
123 get_xdlc_control(const uint8_t *pd, int offset, bool is_extended)
125 uint16_t control;
127 switch (pd[offset] & 0x03) {
129 case XDLC_S:
130 default:
132 * Supervisory or Information frame.
134 if (is_extended)
135 control = pletoh16(&pd[offset]);
136 else
137 control = pd[offset];
138 break;
140 case XDLC_U:
142 * Unnumbered frame.
144 * XXX - is this two octets, with a P/F bit, in HDLC extended
145 * operation? It's one octet in LLC, even though the control
146 * field of I and S frames is a 2-byte extended-operation field
147 * in LLC. Given that there are no sequence numbers in the
148 * control field of a U frame, there doesn't appear to be any
149 * need for it to be 2 bytes in extended operation.
151 control = pd[offset];
152 break;
154 return control;
158 dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
159 proto_tree *xdlc_tree, int hf_xdlc_control, int ett_xdlc_control,
160 const xdlc_cf_items *cf_items_nonext, const xdlc_cf_items *cf_items_ext,
161 const value_string *u_modifier_short_vals_cmd,
162 const value_string *u_modifier_short_vals_resp, bool is_response,
163 bool is_extended, bool append_info)
165 uint16_t control;
166 int control_len;
167 const xdlc_cf_items *cf_items;
168 const char *control_format;
169 uint16_t poll_final;
170 char *info;
171 proto_tree *tc, *control_tree;
172 const char *frame_type = NULL;
173 const char *modifier;
175 info=(char *)wmem_alloc(pinfo->pool, 80);
176 switch (tvb_get_uint8(tvb, offset) & 0x03) {
178 case XDLC_S:
180 * Supervisory frame.
182 if (is_extended) {
183 control = tvb_get_letohs(tvb, offset);
184 control_len = 2;
185 cf_items = cf_items_ext;
186 control_format = "Control field: %s (0x%04X)";
187 } else {
188 control = tvb_get_uint8(tvb, offset);
189 control_len = 1;
190 cf_items = cf_items_nonext;
191 control_format = "Control field: %s (0x%02X)";
193 switch (control & XDLC_S_FTYPE_MASK) {
194 case XDLC_RR:
195 frame_type = "RR";
196 break;
198 case XDLC_RNR:
199 frame_type = "RNR";
200 break;
202 case XDLC_REJ:
203 frame_type = "REJ";
204 break;
206 case XDLC_SREJ:
207 frame_type = "SREJ";
208 break;
210 if (is_extended) {
211 poll_final = (control & XDLC_P_F_EXT);
212 snprintf(info, 80, "S%s, func=%s, N(R)=%u",
213 (poll_final ?
214 (is_response ? " F" : " P") :
215 ""),
216 frame_type,
217 (control & XDLC_N_R_EXT_MASK) >> XDLC_N_R_EXT_SHIFT);
218 } else {
219 poll_final = (control & XDLC_P_F);
220 snprintf(info, 80, "S%s, func=%s, N(R)=%u",
221 (poll_final ?
222 (is_response ? " F" : " P") :
223 ""),
224 frame_type,
225 (control & XDLC_N_R_MASK) >> XDLC_N_R_SHIFT);
227 if (append_info) {
228 col_append_str(pinfo->cinfo, COL_INFO, ", ");
229 col_append_str(pinfo->cinfo, COL_INFO, info);
230 } else {
231 col_add_str(pinfo->cinfo, COL_INFO, info);
233 if (xdlc_tree) {
234 tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb,
235 offset, control_len, control, control_format, info, control);
236 control_tree = proto_item_add_subtree(tc, ett_xdlc_control);
237 proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_n_r,
238 tvb, offset, control_len, control);
239 if (poll_final) {
240 proto_tree_add_boolean(control_tree,
241 (is_response ? *cf_items->hf_xdlc_f :
242 *cf_items->hf_xdlc_p),
243 tvb, offset, control_len, control);
245 proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_s_ftype,
246 tvb, offset, control_len, control);
247 /* This will always say it's a supervisory frame */
248 proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_ftype_s_u,
249 tvb, offset, control_len, control);
251 break;
253 case XDLC_U:
255 * Unnumbered frame.
257 * XXX - is this two octets, with a P/F bit, in HDLC extended
258 * operation? It's one octet in LLC, even though the control
259 * field of I and S frames is a 2-byte extended-operation field
260 * in LLC. Given that there are no sequence numbers in the
261 * control field of a U frame, there doesn't appear to be any
262 * need for it to be 2 bytes in extended operation.
264 if (u_modifier_short_vals_cmd == NULL)
265 u_modifier_short_vals_cmd = modifier_short_vals_cmd;
266 if (u_modifier_short_vals_resp == NULL)
267 u_modifier_short_vals_resp = modifier_short_vals_resp;
268 control = tvb_get_uint8(tvb, offset);
269 control_len = 1;
270 cf_items = cf_items_nonext;
271 control_format = "Control field: %s (0x%02X)";
272 if (is_response) {
273 modifier = val_to_str(control & XDLC_U_MODIFIER_MASK,
274 u_modifier_short_vals_resp, "Unknown");
275 } else {
276 modifier = val_to_str(control & XDLC_U_MODIFIER_MASK,
277 u_modifier_short_vals_cmd, "Unknown");
279 poll_final = (control & XDLC_P_F);
280 snprintf(info, 80, "U%s, func=%s",
281 (poll_final ?
282 (is_response ? " F" : " P") :
283 ""),
284 modifier);
285 if (append_info) {
286 col_append_str(pinfo->cinfo, COL_INFO, ", ");
287 col_append_str(pinfo->cinfo, COL_INFO, info);
288 } else {
289 col_add_str(pinfo->cinfo, COL_INFO, info);
291 if (xdlc_tree) {
292 tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb,
293 offset, control_len, control, control_format, info, control);
294 control_tree = proto_item_add_subtree(tc, ett_xdlc_control);
295 if (poll_final) {
296 proto_tree_add_boolean(control_tree,
297 (is_response ? *cf_items->hf_xdlc_f:
298 *cf_items->hf_xdlc_p),
299 tvb, offset, control_len, control);
301 proto_tree_add_uint(control_tree,
302 (is_response ? *cf_items->hf_xdlc_u_modifier_resp :
303 *cf_items->hf_xdlc_u_modifier_cmd),
304 tvb, offset, control_len, control);
305 /* This will always say it's an unnumbered frame */
306 proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_ftype_s_u,
307 tvb, offset, control_len, control);
309 break;
311 default:
313 * Information frame.
315 if (is_extended) {
316 control = tvb_get_letohs(tvb, offset);
317 control_len = 2;
318 cf_items = cf_items_ext;
319 control_format = "Control field: %s (0x%04X)";
320 poll_final = (control & XDLC_P_F_EXT);
321 snprintf(info, 80, "I%s, N(R)=%u, N(S)=%u",
322 ((control & XDLC_P_F_EXT) ? " P" : ""),
323 (control & XDLC_N_R_EXT_MASK) >> XDLC_N_R_EXT_SHIFT,
324 (control & XDLC_N_S_EXT_MASK) >> XDLC_N_S_EXT_SHIFT);
325 } else {
326 control = tvb_get_uint8(tvb, offset);
327 control_len = 1;
328 cf_items = cf_items_nonext;
329 control_format = "Control field: %s (0x%02X)";
330 poll_final = (control & XDLC_P_F);
331 snprintf(info, 80, "I%s, N(R)=%u, N(S)=%u",
332 ((control & XDLC_P_F) ? " P" : ""),
333 (control & XDLC_N_R_MASK) >> XDLC_N_R_SHIFT,
334 (control & XDLC_N_S_MASK) >> XDLC_N_S_SHIFT);
336 if (append_info) {
337 col_append_str(pinfo->cinfo, COL_INFO, ", ");
338 col_append_str(pinfo->cinfo, COL_INFO, info);
339 } else {
340 col_add_str(pinfo->cinfo, COL_INFO, info);
342 if (xdlc_tree) {
343 tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb,
344 offset, control_len, control, control_format, info, control);
345 control_tree = proto_item_add_subtree(tc, ett_xdlc_control);
346 proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_n_r,
347 tvb, offset, control_len, control);
348 proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_n_s,
349 tvb, offset, control_len, control);
350 if (poll_final) {
351 proto_tree_add_boolean(control_tree, *cf_items->hf_xdlc_p,
352 tvb, offset, control_len, control);
354 /* This will always say it's an information frame */
355 proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_ftype_i,
356 tvb, offset, control_len, control);
358 break;
360 return control;
364 * Editor modelines - https://www.wireshark.org/tools/modelines.html
366 * Local variables:
367 * c-basic-offset: 4
368 * tab-width: 8
369 * indent-tabs-mode: nil
370 * End:
372 * vi: set shiftwidth=4 tabstop=8 expandtab:
373 * :indentSize=4:tabSize=8:noTabs=true: