Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / plugins / epan / irda / packet-ircomm.c
blobd3237014df65a26884e03666b695f68f8670eed7
1 /* packet-ircomm.c
2 * Routines for IrCOMM dissection
3 * Copyright 2003 Jan Kiszka <jan.kiszka@web.de>
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>
17 * See
19 * https://web.archive.org/web/20040405053146/http://www.irda.org/standards/specifications.asp
21 * or
23 * https://archive.org/search?query=creator%3A%22Infrared+Data+Association%22
25 * for various IrDA specifications, including the IrCOMM 1.0 specification
26 * at
28 * https://web.archive.org/web/20040229015523/http://www.irda.org/standards/pubs/IrCOMM10.PDF
30 * or
32 * https://archive.org/details/ir-comm-10
35 #include "irda-appl.h"
38 /* Parameters common to all service types */
39 #define IRCOMM_SERVICE_TYPE 0x00
40 #define IRCOMM_PORT_TYPE 0x01 /* Only used in LM-IAS */
41 #define IRCOMM_PORT_NAME 0x02 /* Only used in LM-IAS */
43 /* Parameters for both 3 wire and 9 wire */
44 #define IRCOMM_DATA_RATE 0x10
45 #define IRCOMM_DATA_FORMAT 0x11
46 #define IRCOMM_FLOW_CONTROL 0x12
47 #define IRCOMM_XON_XOFF 0x13
48 #define IRCOMM_ENQ_ACK 0x14
49 #define IRCOMM_LINE_STATUS 0x15
50 #define IRCOMM_BREAK 0x16
52 /* Parameters for 9 wire */
53 #define IRCOMM_DTE 0x20
54 #define IRCOMM_DCE 0x21
55 #define IRCOMM_POLL 0x22
57 /* Service type (details) */
58 #define IRCOMM_3_WIRE_RAW 0x01
59 #define IRCOMM_3_WIRE 0x02
60 #define IRCOMM_9_WIRE 0x04
61 #define IRCOMM_CENTRONICS 0x08
63 /* Port type (details) */
64 #define IRCOMM_SERIAL 0x01
65 #define IRCOMM_PARALLEL 0x02
67 /* Data format (details) */
68 #define IRCOMM_WSIZE_5 0x00
69 #define IRCOMM_WSIZE_6 0x01
70 #define IRCOMM_WSIZE_7 0x02
71 #define IRCOMM_WSIZE_8 0x03
73 #define IRCOMM_1_STOP_BIT 0x00
74 #define IRCOMM_2_STOP_BIT 0x04 /* 1.5 if char len 5 */
76 #define IRCOMM_PARITY_DISABLE 0x00
77 #define IRCOMM_PARITY_ENABLE 0x08
79 #define IRCOMM_PARITY_ODD 0x00
80 #define IRCOMM_PARITY_EVEN 0x10
81 #define IRCOMM_PARITY_MARK 0x20
82 #define IRCOMM_PARITY_SPACE 0x30
84 /* Flow control */
85 #define IRCOMM_XON_XOFF_IN 0x01
86 #define IRCOMM_XON_XOFF_OUT 0x02
87 #define IRCOMM_RTS_CTS_IN 0x04
88 #define IRCOMM_RTS_CTS_OUT 0x08
89 #define IRCOMM_DSR_DTR_IN 0x10
90 #define IRCOMM_DSR_DTR_OUT 0x20
91 #define IRCOMM_ENQ_ACK_IN 0x40
92 #define IRCOMM_ENQ_ACK_OUT 0x80
94 /* Line status */
95 #define IRCOMM_OVERRUN_ERROR 0x02
96 #define IRCOMM_PARITY_ERROR 0x04
97 #define IRCOMM_FRAMING_ERROR 0x08
99 /* DTE (Data terminal equipment) line settings */
100 #define IRCOMM_DELTA_DTR 0x01
101 #define IRCOMM_DELTA_RTS 0x02
102 #define IRCOMM_DTR 0x04
103 #define IRCOMM_RTS 0x08
105 /* DCE (Data communications equipment) line settings */
106 #define IRCOMM_DELTA_CTS 0x01 /* Clear to send has changed */
107 #define IRCOMM_DELTA_DSR 0x02 /* Data set ready has changed */
108 #define IRCOMM_DELTA_RI 0x04 /* Ring indicator has changed */
109 #define IRCOMM_DELTA_CD 0x08 /* Carrier detect has changed */
110 #define IRCOMM_CTS 0x10 /* Clear to send is high */
111 #define IRCOMM_DSR 0x20 /* Data set ready is high */
112 #define IRCOMM_RI 0x40 /* Ring indicator is high */
113 #define IRCOMM_CD 0x80 /* Carrier detect is high */
114 #define IRCOMM_DCE_DELTA_ANY 0x0f
116 void proto_reg_handoff_ircomm(void);
118 /* Initialize the subtree pointers */
119 static int ett_ircomm;
120 static int ett_ircomm_ctrl;
122 #define MAX_PARAMETERS 32
123 static int ett_param[MAX_IAP_ENTRIES * MAX_PARAMETERS];
125 static dissector_handle_t ircomm_raw_handle;
126 static dissector_handle_t ircomm_cooked_handle;
128 static int proto_ircomm;
129 static int hf_ircomm_param;
130 /* static int hf_param_pi; */
131 /* static int hf_param_pl; */
132 /* static int hf_param_pv; */
133 static int hf_control;
134 static int hf_control_len;
136 static bool dissect_ircomm_parameters(tvbuff_t* tvb, unsigned offset, packet_info* pinfo,
137 proto_tree* tree, unsigned list_index, uint8_t attr_type, uint8_t circuit_id);
138 static bool dissect_ircomm_ttp_lsap(tvbuff_t* tvb, unsigned offset, packet_info* pinfo,
139 proto_tree* tree, unsigned list_index, uint8_t attr_type, uint8_t circuit_id);
140 static bool dissect_ircomm_lmp_lsap(tvbuff_t* tvb, unsigned offset, packet_info* pinfo,
141 proto_tree* tree, unsigned list_index, uint8_t attr_type, uint8_t circuit_id);
143 ias_attr_dissector_t ircomm_attr_dissector[] = {
144 /* IrDA:IrCOMM attribute dissectors */
145 { "Parameters", dissect_ircomm_parameters },
146 { "IrDA:TinyTP:LsapSel", dissect_ircomm_ttp_lsap },
147 { NULL, NULL }
150 ias_attr_dissector_t irlpt_attr_dissector[] = {
151 /* IrLPT attribute dissectors */
152 { "IrDA:IrLMP:LsapSel", dissect_ircomm_lmp_lsap },
153 { "IrDA:IrLMP:LSAPSel", dissect_ircomm_lmp_lsap }, /* according to IrCOMM V1.0, p25 */
154 { NULL, NULL }
159 * Dissect the cooked IrCOMM protocol
161 static int dissect_cooked_ircomm(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
163 proto_item *ti;
164 proto_tree *ircomm_tree, *ctrl_tree;
165 unsigned offset = 0;
166 unsigned clen;
167 int len = tvb_reported_length(tvb);
169 if (len == 0)
170 return len;
172 /* Make entries in Protocol column on summary display */
173 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IrCOMM");
175 clen = tvb_get_uint8(tvb, offset);
176 len -= 1 + clen;
178 if (len > 0)
179 col_add_fstr(pinfo->cinfo, COL_INFO, "Clen=%d, UserData: %d byte%s", clen, len, (len > 1)? "s": "");
180 else
181 col_add_fstr(pinfo->cinfo, COL_INFO, "Clen=%d", clen);
183 /* create display subtree for the protocol */
184 ti = proto_tree_add_item(tree, proto_ircomm, tvb, 0, -1, ENC_NA);
185 ircomm_tree = proto_item_add_subtree(ti, ett_ircomm);
187 ti = proto_tree_add_item(ircomm_tree, hf_control, tvb, 0, clen + 1, ENC_NA);
188 ctrl_tree = proto_item_add_subtree(ti, ett_ircomm_ctrl);
189 proto_tree_add_item(ctrl_tree, hf_control_len, tvb, offset, 1, ENC_BIG_ENDIAN);
190 offset++;
192 call_data_dissector(tvb_new_subset_length(tvb, offset, clen), pinfo, ctrl_tree);
193 offset += clen;
195 call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, ircomm_tree);
197 return len;
202 * Dissect the raw IrCOMM/IrLPT protocol
204 static int dissect_raw_ircomm(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
206 unsigned len = tvb_reported_length(tvb);
207 proto_item* ti;
208 proto_tree* ircomm_tree;
210 if (len == 0)
211 return 0;
213 /* Make entries in Protocol column on summary display */
214 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IrCOMM");
216 col_add_fstr(pinfo->cinfo, COL_INFO, "User Data: %d byte%s", len, (len > 1)? "s": "");
218 /* create display subtree for the protocol */
219 ti = proto_tree_add_item(tree, proto_ircomm, tvb, 0, -1, ENC_NA);
220 ircomm_tree = proto_item_add_subtree(ti, ett_ircomm);
222 call_data_dissector(tvb, pinfo, ircomm_tree);
224 return len;
229 * Dissect IrCOMM IAS "Parameters" attribute
231 static bool dissect_ircomm_parameters(tvbuff_t* tvb, unsigned offset, packet_info* pinfo _U_,
232 proto_tree* tree, unsigned list_index, uint8_t attr_type, uint8_t circuit_id _U_)
234 unsigned len;
235 unsigned n = 0;
236 proto_item* ti;
237 proto_tree* p_tree;
238 char buf[256];
239 uint8_t pv;
242 if (!check_iap_octet_result(tvb, tree, offset, "Parameters", attr_type))
243 return true;
245 if (tree)
247 len = tvb_get_ntohs(tvb, offset) + offset + 2;
248 offset += 2;
250 while (offset < len)
252 uint8_t p_len = tvb_get_uint8(tvb, offset + 1);
255 ti = proto_tree_add_item(tree, hf_ircomm_param, tvb, offset, p_len + 2, ENC_NA);
256 p_tree = proto_item_add_subtree(ti, ett_param[list_index * MAX_PARAMETERS + n]);
258 buf[0] = 0;
260 switch (tvb_get_uint8(tvb, offset))
262 case IRCOMM_SERVICE_TYPE:
263 proto_item_append_text(ti, ": Service Type (");
265 pv = tvb_get_uint8(tvb, offset+2);
266 if (pv & IRCOMM_3_WIRE_RAW)
267 (void) g_strlcat(buf, ", 3-Wire raw", 256);
268 if (pv & IRCOMM_3_WIRE)
269 (void) g_strlcat(buf, ", 3-Wire", 256);
270 if (pv & IRCOMM_9_WIRE)
271 (void) g_strlcat(buf, ", 9-Wire", 256);
272 if (pv & IRCOMM_CENTRONICS)
273 (void) g_strlcat(buf, ", Centronics", 256);
275 (void) g_strlcat(buf, ")", 256);
277 if (strlen(buf) > 2)
278 proto_item_append_text(ti, "%s", buf+2);
279 else
280 proto_item_append_text(ti, "unknown)");
282 break;
284 case IRCOMM_PORT_TYPE:
285 proto_item_append_text(ti, ": Port Type (");
287 pv = tvb_get_uint8(tvb, offset+2);
288 if (pv & IRCOMM_SERIAL)
289 (void) g_strlcat(buf, ", serial", 256);
290 if (pv & IRCOMM_PARALLEL)
291 (void) g_strlcat(buf, ", parallel", 256);
293 (void) g_strlcat(buf, ")", 256);
295 if (strlen(buf) > 2)
296 proto_item_append_text(ti, "%s", buf+2);
297 else
298 proto_item_append_text(ti, "unknown)");
300 break;
302 case IRCOMM_PORT_NAME:
303 /* XXX - the IrCOMM V1.0 spec says this "Normally
304 human readable text, but not required". */
305 proto_item_append_text(ti, ": Port Name (\"%s\")",
306 tvb_format_text(pinfo->pool, tvb, offset+2, p_len));
308 break;
310 default:
311 proto_item_append_text(ti, ": unknown");
314 offset = dissect_param_tuple(tvb, p_tree, offset);
315 n++;
320 return true;
325 * Dissect IrCOMM IAS "IrDA:TinyTP:LsapSel" attribute
327 static bool dissect_ircomm_ttp_lsap(tvbuff_t* tvb, unsigned offset, packet_info* pinfo,
328 proto_tree* tree, unsigned list_index _U_, uint8_t attr_type, uint8_t circuit_id)
330 uint8_t dlsap;
333 if ((dlsap = check_iap_lsap_result(tvb, tree, offset, "IrDA:TinyTP:LsapSel", attr_type)) == 0)
334 return false;
336 add_lmp_conversation(pinfo, dlsap, true, ircomm_cooked_handle, circuit_id);
338 return false;
343 * Dissect IrCOMM/IrLPT IAS "IrDA:IrLMP:LsapSel" attribute
345 static bool dissect_ircomm_lmp_lsap(tvbuff_t* tvb, unsigned offset, packet_info* pinfo,
346 proto_tree* tree, unsigned list_index _U_, uint8_t attr_type, uint8_t circuit_id)
348 uint8_t dlsap;
351 if ((dlsap = check_iap_lsap_result(tvb, tree, offset, "IrDA:IrLMP:LsapSel", attr_type)) == 0)
352 return false;
354 add_lmp_conversation(pinfo, dlsap, false, ircomm_raw_handle, circuit_id);
356 return false;
361 * Register the IrCOMM protocol
363 void proto_register_ircomm(void)
365 unsigned i;
367 /* Setup list of header fields */
368 static hf_register_info hf_ircomm[] = {
369 { &hf_ircomm_param,
370 { "IrCOMM Parameter", "ircomm.parameter",
371 FT_NONE, BASE_NONE, NULL, 0,
372 NULL, HFILL }},
373 #if 0
374 { &hf_param_pi,
375 { "Parameter Identifier", "ircomm.pi",
376 FT_UINT8, BASE_HEX, NULL, 0,
377 NULL, HFILL }},
378 { &hf_param_pl,
379 { "Parameter Length", "ircomm.pl",
380 FT_UINT8, BASE_HEX, NULL, 0,
381 NULL, HFILL }},
382 { &hf_param_pv,
383 { "Parameter Value", "ircomm.pv",
384 FT_BYTES, BASE_NONE, NULL, 0,
385 NULL, HFILL }},
386 #endif
387 { &hf_control,
388 { "Control Channel", "ircomm.control",
389 FT_NONE, BASE_NONE, NULL, 0,
390 NULL, HFILL }},
391 { &hf_control_len,
392 { "Clen", "ircomm.control.len",
393 FT_UINT8, BASE_DEC, NULL, 0,
394 NULL, HFILL }}
397 /* Setup protocol subtree arrays */
398 static int* ett[] = {
399 &ett_ircomm,
400 &ett_ircomm_ctrl
403 int* ett_p[MAX_IAP_ENTRIES * MAX_PARAMETERS];
406 /* Register protocol names and descriptions */
407 proto_ircomm = proto_register_protocol("IrCOMM Protocol", "IrCOMM", "ircomm");
408 ircomm_raw_handle = register_dissector("ircomm_raw", dissect_raw_ircomm, proto_ircomm);
409 ircomm_cooked_handle = register_dissector("ircomm_cooked", dissect_cooked_ircomm, proto_ircomm);
411 /* Required function calls to register the header fields */
412 proto_register_field_array(proto_ircomm, hf_ircomm, array_length(hf_ircomm));
414 /* Register subtrees */
415 proto_register_subtree_array(ett, array_length(ett));
416 for (i = 0; i < MAX_IAP_ENTRIES * MAX_PARAMETERS; i++)
418 ett_p[i] = &ett_param[i];
420 proto_register_subtree_array(ett_p, MAX_IAP_ENTRIES * MAX_PARAMETERS);
424 * Editor modelines - https://www.wireshark.org/tools/modelines.html
426 * Local variables:
427 * c-basic-offset: 4
428 * tab-width: 8
429 * indent-tabs-mode: nil
430 * End:
432 * vi: set shiftwidth=4 tabstop=8 expandtab:
433 * :indentSize=4:tabSize=8:noTabs=true: