Bug Summary

File:builds/wireshark/wireshark/plugins/epan/irda/packet-irda.c
Warning:line 1243, column 32
Access to field 'iap_result_frame' results in a dereference of a null pointer (loaded from variable 'lmp_conv')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name packet-irda.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D PLUGIN_VERSION="0.0.6" -D WS_DEBUG -D WS_DEBUG_UTF_8 -D irda_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/plugins/epan/irda -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-10-17-100342-3661-1 -x c /builds/wireshark/wireshark/plugins/epan/irda/packet-irda.c
1/* packet-irda.c
2 * Routines for IrDA dissection
3 * By Shaun Jackman <sjackman@pathwayconnect.com>
4 * Copyright 2000 Shaun Jackman
5 *
6 * Extended by Jan Kiszka <jan.kiszka@web.de>
7 * Copyright 2003 Jan Kiszka
8 *
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
12 *
13 * SPDX-License-Identifier: GPL-2.0-or-later
14 */
15
16#include "config.h"
17
18#include <string.h>
19
20#include <epan/packet.h>
21#include <epan/address_types.h>
22#include <epan/to_str.h>
23#include <epan/strutil.h>
24#include <epan/conversation.h>
25#include <epan/tfs.h>
26#include <wsutil/array.h>
27#include <wiretap/wtap.h>
28
29#include <epan/dissectors/packet-sll.h>
30#include <epan/dissectors/packet-xdlc.h>
31#include "irda-appl.h"
32
33/*
34 * This plugin dissects infrared data transmissions as defined by IrDA
35 * specifications. See
36 *
37 * https://web.archive.org/web/20040405053146/http://www.irda.org/standards/specifications.asp
38 *
39 * or
40 *
41 * https://archive.org/search?query=creator%3A%22Infrared+Data+Association%22
42 *
43 * for various IrDA specifications, including a zip archive of the IrPHY
44 * 1.4, IrLAP 1.1, IrLMP 1.1, IrDA Tiny TP 1.1, and IrDA Point and Shoot
45 * Profile 1.1 and Test Specification 1.0 at
46 *
47 * https://web.archive.org/web/20040405053146/http://www.irda.org/standards/pubs/IrData.zip
48 *
49 * or the the IrLAP 1.1 specification at
50 *
51 * https://archive.org/details/ir-lap-11
52 *
53 * The plugin operates both offline with libpcap files and online on supported
54 * platforms. Live dissection is currently available for Linux-IrDA
55 * (irda.sourceforge.net) and for Windows if the Linux-IrDA port IrCOMM2k
56 * (www.ircomm2k.de) is installed.
57 */
58
59/*
60 * LAP
61 */
62
63/* Frame types and templates */
64#define INVALID0xff 0xff
65
66/*
67 * XXX - the IrDA spec gives XID as 0x2c; HDLC (and other HDLC-derived
68 * protocols) use 0xAC.
69 */
70#define IRDA_XID_CMD0x2c 0x2c /* Exchange Station Identification */
71
72#define CMD_FRAME0x01 0x01
73#define RSP_FRAME0x00 0x00
74
75/* Discovery Flags */
76#define S_MASK0x03 0x03
77#define CONFLICT0x04 0x04
78
79/* Negotiation Parameters */
80#define PI_BAUD_RATE0x01 0x01
81#define PI_MAX_TURN_TIME0x82 0x82
82#define PI_DATA_SIZE0x83 0x83
83#define PI_WINDOW_SIZE0x84 0x84
84#define PI_ADD_BOFS0x85 0x85
85#define PI_MIN_TURN_TIME0x86 0x86
86#define PI_LINK_DISC0x08 0x08
87
88
89/*
90 * LMP
91 */
92
93/* IrLMP frame opcodes */
94#define CONNECT_CMD0x01 0x01
95#define CONNECT_CNF0x81 0x81
96#define DISCONNECT0x02 0x02
97#define ACCESSMODE_CMD0x03 0x03
98#define ACCESSMODE_CNF0x83 0x83
99
100#define CONTROL_BIT0x80 0x80
101#define RESERVED_BIT0x80 0x80
102
103/* LSAP-SEL's */
104#define LSAP_MASK0x7f 0x7f
105#define LSAP_IAS0x00 0x00
106#define LSAP_ANY0xff 0xff
107#define LSAP_MAX0x6f 0x6f /* 0x70-0x7f are reserved */
108#define LSAP_CONNLESS0x70 0x70 /* Connectionless LSAP, mostly used for Ultra */
109
110
111/*
112 * IAP
113 */
114
115/* IrIAP Op-codes */
116#define GET_INFO_BASE0x01 0x01
117#define GET_OBJECTS0x02 0x02
118#define GET_VALUE0x03 0x03
119#define GET_VALUE_BY_CLASS0x04 0x04
120#define GET_OBJECT_INFO0x05 0x05
121#define GET_ATTRIB_NAMES0x06 0x06
122
123#define IAP_LST0x80 0x80
124#define IAP_ACK0x40 0x40
125#define IAP_OP0x3F 0x3F
126
127#define IAS_SUCCESS0 0
128#define IAS_CLASS_UNKNOWN1 1
129#define IAS_ATTRIB_UNKNOWN2 2
130#define IAS_ATTR_TOO_LONG3 3
131#define IAS_DISCONNECT10 10
132#define IAS_UNSUPPORTED0xFF 0xFF
133
134
135/*
136 * TTP
137 */
138
139#define TTP_PARAMETERS0x80 0x80
140#define TTP_MORE0x80 0x80
141
142void proto_reg_handoff_irda(void);
143void proto_register_irda(void);
144
145/* Initialize the protocol and registered fields */
146static int proto_irlap;
147static int hf_lap_a;
148static int hf_lap_a_cr;
149static int hf_lap_a_address;
150static int hf_lap_c;
151static int hf_lap_c_nr;
152static int hf_lap_c_ns;
153static int hf_lap_c_p;
154static int hf_lap_c_f;
155static int hf_lap_c_s;
156static int hf_lap_c_u_cmd;
157static int hf_lap_c_u_rsp;
158static int hf_lap_c_i;
159static int hf_lap_c_s_u;
160static int hf_lap_i;
161static int hf_snrm_saddr;
162static int hf_snrm_daddr;
163static int hf_snrm_ca;
164static int hf_ua_saddr;
165static int hf_ua_daddr;
166static int hf_negotiation_param;
167static int hf_param_pi;
168static int hf_param_pl;
169static int hf_param_pv;
170static int hf_xid_ident;
171static int hf_xid_saddr;
172static int hf_xid_daddr;
173static int hf_xid_flags;
174static int hf_xid_s;
175static int hf_xid_conflict;
176static int hf_xid_slotnr;
177static int hf_xid_version;
178
179static int proto_irlmp;
180static int hf_lmp_xid_hints;
181static int hf_lmp_xid_charset;
182static int hf_lmp_xid_name;
183static int hf_lmp_xid_name_no_encoding;
184static int hf_lmp_dst;
185static int hf_lmp_dst_control;
186static int hf_lmp_dst_lsap;
187static int hf_lmp_src;
188static int hf_lmp_src_r;
189static int hf_lmp_src_lsap;
190static int hf_lmp_opcode;
191static int hf_lmp_rsvd;
192static int hf_lmp_reason;
193static int hf_lmp_mode;
194static int hf_lmp_status;
195
196static int proto_iap;
197static int hf_iap_ctl;
198static int hf_iap_ctl_lst;
199static int hf_iap_ctl_ack;
200static int hf_iap_ctl_opcode;
201static int hf_iap_class_name;
202static int hf_iap_attr_name;
203static int hf_iap_return;
204static int hf_iap_list_len;
205static int hf_iap_list_entry;
206static int hf_iap_obj_id;
207static int hf_iap_attr_type;
208static int hf_iap_int;
209static int hf_iap_seq_len;
210static int hf_iap_oct_seq;
211static int hf_iap_char_set;
212static int hf_iap_string;
213static int hf_iap_invaloctet;
214static int hf_iap_invallsap;
215
216static int proto_ttp;
217static int hf_ttp_p;
218static int hf_ttp_icredit;
219static int hf_ttp_m;
220static int hf_ttp_dcredit;
221
222static int proto_log;
223static int hf_log_msg;
224static int hf_log_missed;
225
226/* Initialize the subtree pointers */
227static int ett_irlap;
228static int ett_lap_a;
229static int ett_lap_c;
230static int ett_lap_i;
231static int ett_xid_flags;
232static int ett_log;
233static int ett_irlmp;
234static int ett_lmp_dst;
235static int ett_lmp_src;
236static int ett_iap;
237static int ett_iap_ctl;
238static int ett_ttp;
239
240#define MAX_PARAMETERS32 32
241static int ett_param[MAX_PARAMETERS32];
242
243static int ett_iap_entry[MAX_IAP_ENTRIES32];
244
245static int irda_address_type = -1;
246
247static dissector_handle_t irda_handle;
248
249static const xdlc_cf_items irlap_cf_items = {
250 &hf_lap_c_nr,
251 &hf_lap_c_ns,
252 &hf_lap_c_p,
253 &hf_lap_c_f,
254 &hf_lap_c_s,
255 &hf_lap_c_u_cmd,
256 &hf_lap_c_u_rsp,
257 &hf_lap_c_i,
258 &hf_lap_c_s_u
259};
260
261/* IAP conversation type */
262typedef struct iap_conversation {
263 struct iap_conversation* pnext;
264 uint32_t iap_query_frame;
265 ias_attr_dissector_t* pattr_dissector;
266} iap_conversation_t;
267
268/* IrLMP conversation type */
269typedef struct lmp_conversation {
270 struct lmp_conversation* pnext;
271 uint32_t iap_result_frame;
272 bool_Bool ttp;
273 dissector_handle_t dissector;
274} lmp_conversation_t;
275
276static const true_false_string lap_cr_vals = {
277 "Command",
278 "Response"
279};
280
281static const true_false_string set_notset = {
282 "Set",
283 "Not set"
284};
285
286static const value_string lap_c_ftype_vals[] = {
287 { XDLC_I0x00, "Information frame" },
288 { XDLC_S0x01, "Supervisory frame" },
289 { XDLC_U0x03, "Unnumbered frame" },
290 { 0, NULL((void*)0) }
291};
292
293static const value_string lap_c_u_cmd_abbr_vals[] = {
294 { XDLC_SNRM0x80, "SNRM" },
295 { XDLC_DISC0x40, "DISC" },
296 { XDLC_UI0x00, "UI" },
297 { IRDA_XID_CMD0x2c, "XID" },
298 { XDLC_TEST0xE0, "TEST" },
299 { 0, NULL((void*)0) }
300};
301
302static const value_string lap_c_u_rsp_abbr_vals[] = {
303 { XDLC_SNRM0x80, "RNRM" },
304 { XDLC_UA0x60, "UA" },
305 { XDLC_FRMR0x84, "FRMR" },
306 { XDLC_DM0x0C, "DM" },
307 { XDLC_RD0x40, "RD" },
308 { XDLC_UI0x00, "UI" },
309 { XDLC_XID0xAC, "XID" },
310 { XDLC_TEST0xE0, "TEST" },
311 { 0, NULL((void*)0) }
312};
313
314static const value_string lap_c_u_cmd_vals[] = {
315 { XDLC_SNRM0x80>>2, "Set Normal Response Mode" },
316 { XDLC_DISC0x40>>2, "Disconnect" },
317 { XDLC_UI0x00>>2, "Unnumbered Information" },
318 { IRDA_XID_CMD0x2c>>2, "Exchange Station Identification" },
319 { XDLC_TEST0xE0>>2, "Test" },
320 { 0, NULL((void*)0) }
321};
322
323static const value_string lap_c_u_rsp_vals[] = {
324 { XDLC_SNRM0x80>>2, "Request Normal Response Mode" },
325 { XDLC_UA0x60>>2, "Unnumbered Acknowledge" },
326 { XDLC_FRMR0x84>>2, "Frame Reject" },
327 { XDLC_DM0x0C>>2, "Disconnect Mode" },
328 { XDLC_RD0x40>>2, "Request Disconnect" },
329 { XDLC_UI0x00>>2, "Unnumbered Information" },
330 { XDLC_XID0xAC>>2, "Exchange Station Identification" },
331 { XDLC_TEST0xE0>>2, "Test" },
332 { 0, NULL((void*)0) }
333};
334
335static const value_string lap_c_s_vals[] = {
336 { XDLC_RR0x00>>2, "Receiver ready" },
337 { XDLC_RNR0x04>>2, "Receiver not ready" },
338 { XDLC_REJ0x08>>2, "Reject" },
339 { XDLC_SREJ0x0C>>2, "Selective reject" },
340 { 0, NULL((void*)0) }
341};
342
343static const value_string xid_slot_numbers[] = {
344/* Number of XID slots */
345 { 0, "1" },
346 { 1, "6" },
347 { 2, "8" },
348 { 3, "16" },
349 { 0, NULL((void*)0) }
350};
351
352static const value_string lmp_opcode_vals[] = {
353/* IrLMP frame opcodes */
354 { CONNECT_CMD0x01, "Connect Command" },
355 { CONNECT_CNF0x81, "Connect Confirm" },
356 { DISCONNECT0x02, "Disconnect" },
357 { ACCESSMODE_CMD0x03, "Access Mode Command" },
358 { ACCESSMODE_CNF0x83, "Access Mode Confirm" },
359 { 0, NULL((void*)0) }
360};
361
362static const value_string lmp_reason_vals[] = {
363/* IrLMP disconnect reasons */
364 { 0x01, "User Request" },
365 { 0x02, "Unexpected IrLAP Disconnect" },
366 { 0x03, "Failed to establish IrLAP connection" },
367 { 0x04, "IrLAP Reset" },
368 { 0x05, "Link Management Initiated Disconnect" },
369 { 0x06, "Data delivered on disconnected LSAP-Connection"},
370 { 0x07, "Non Responsive LM-MUX Client" },
371 { 0x08, "No available LM-MUX Client" },
372 { 0x09, "Connection Half Open" },
373 { 0x0A, "Illegal Source Address" },
374 { 0xFF, "Unspecified Disconnect Reason" },
375 { 0, NULL((void*)0) }
376};
377
378static const value_string lmp_mode_vals[] = {
379/* IrLMP modes */
380 { 0x00, "Multiplexed" },
381 { 0x01, "Exclusive" },
382 { 0, NULL((void*)0) }
383};
384
385static const value_string lmp_status_vals[] = {
386/* IrLMP status */
387 { 0x00, "Success" },
388 { 0x01, "Failure" },
389 { 0xFF, "Unsupported" },
390 { 0, NULL((void*)0) }
391};
392
393#define LMP_CHARSET_ASCII0 0
394#define LMP_CHARSET_ISO_8859_11 1
395#define LMP_CHARSET_ISO_8859_22 2
396#define LMP_CHARSET_ISO_8859_33 3
397#define LMP_CHARSET_ISO_8859_44 4
398#define LMP_CHARSET_ISO_8859_55 5
399#define LMP_CHARSET_ISO_8859_66 6
400#define LMP_CHARSET_ISO_8859_77 7
401#define LMP_CHARSET_ISO_8859_88 8
402#define LMP_CHARSET_ISO_8859_99 9
403#define LMP_CHARSET_UNICODE0xFF 0xFF /* UCS-2 (byte order?) */
404
405static const value_string lmp_charset_vals[] = {
406/* IrLMP character set */
407 { LMP_CHARSET_ASCII0, "ASCII" },
408 { LMP_CHARSET_ISO_8859_11, "ISO 8859-1" },
409 { LMP_CHARSET_ISO_8859_22, "ISO 8859-2" },
410 { LMP_CHARSET_ISO_8859_33, "ISO 8859-3" },
411 { LMP_CHARSET_ISO_8859_44, "ISO 8859-4" },
412 { LMP_CHARSET_ISO_8859_55, "ISO 8859-5" },
413 { LMP_CHARSET_ISO_8859_66, "ISO 8859-6" },
414 { LMP_CHARSET_ISO_8859_77, "ISO 8859-7" },
415 { LMP_CHARSET_ISO_8859_88, "ISO 8859-8" },
416 { LMP_CHARSET_ISO_8859_99, "ISO 8859-9" },
417 { LMP_CHARSET_UNICODE0xFF, "Unicode" },
418 { 0, NULL((void*)0) }
419};
420
421static const value_string iap_opcode_vals[] = {
422/* IrIAP Op-codes */
423 { GET_INFO_BASE0x01, "GetInfoBase" },
424 { GET_OBJECTS0x02, "GetObjects" },
425 { GET_VALUE0x03, "GetValue" },
426 { GET_VALUE_BY_CLASS0x04, "GetValueByClass" },
427 { GET_OBJECT_INFO0x05, "GetObjectInfo" },
428 { GET_ATTRIB_NAMES0x06, "GetAttributeNames" },
429 { 0, NULL((void*)0) }
430};
431
432static const value_string iap_return_vals[] = {
433/* IrIAP Return-codes */
434 { IAS_SUCCESS0, "Success" },
435 { IAS_CLASS_UNKNOWN1, "Class/Object Unknown" },
436 { IAS_ATTRIB_UNKNOWN2, "Attribute Unknown" },
437 { IAS_ATTR_TOO_LONG3, "Attribute List Too Long" },
438 { IAS_DISCONNECT10, "Disconnect (Linux-IrDA only)" },
439 { IAS_UNSUPPORTED0xFF, "Unsupported Optional Operation" },
440 { 0, NULL((void*)0) }
441};
442
443static const value_string iap_attr_type_vals[] = {
444/* LM-IAS Attribute types */
445 { IAS_MISSING0, "Missing" },
446 { IAS_INTEGER1, "Integer" },
447 { IAS_OCT_SEQ2, "Octet Sequence" },
448 { IAS_STRING3, "String" },
449 { 0, NULL((void*)0) }
450};
451
452static ias_attr_dissector_t device_attr_dissector[] = {
453/* Device attribute dissectors */
454/* { "IrLMPSupport", xxx }, not implemented yet... */
455 { NULL((void*)0), NULL((void*)0) }
456};
457
458/* IAS class dissectors */
459static ias_class_dissector_t class_dissector[] = { CLASS_DISSECTORS{ "Device", device_attr_dissector }, { "IrDA:IrCOMM", ircomm_attr_dissector
}, { "IrLPT", irlpt_attr_dissector }, { ((void*)0), ((void*)
0) }
};
460
461
462/*
463 * Dissect parameter tuple
464 */
465unsigned dissect_param_tuple(tvbuff_t* tvb, proto_tree* tree, unsigned offset)
466{
467 uint8_t len = tvb_get_uint8(tvb, offset + 1);
468
469 if (tree)
470 proto_tree_add_item(tree, hf_param_pi, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
471 offset++;
472
473 if (tree)
474 proto_tree_add_item(tree, hf_param_pl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
475 offset++;
476
477 if (len > 0)
478 {
479 if (tree)
480 proto_tree_add_item(tree, hf_param_pv, tvb, offset, len, ENC_NA0x00000000);
481 offset += len;
482 }
483
484 return offset;
485}
486
487
488/*
489 * Dissect TTP
490 */
491static unsigned dissect_ttp(tvbuff_t* tvb, packet_info* pinfo, proto_tree* root, bool_Bool data)
492{
493 unsigned offset = 0;
494 uint8_t head;
495 char buf[128];
496
497 if (tvb_reported_length(tvb) == 0)
498 return 0;
499
500 /* Make entries in Protocol column on summary display */
501 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TTP");
502
503 head = tvb_get_uint8(tvb, offset);
504
505 snprintf(buf, 128, ", Credit=%d", head & ~TTP_PARAMETERS0x80);
506 col_append_str(pinfo->cinfo, COL_INFO, buf);
507
508 if (root)
509 {
510 /* create display subtree for the protocol */
511 proto_item* ti = proto_tree_add_item(root, proto_ttp, tvb, 0, -1, ENC_NA0x00000000);
512 proto_tree* tree = proto_item_add_subtree(ti, ett_ttp);
513
514 if (data)
515 {
516 proto_tree_add_item(tree, hf_ttp_m, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
517 proto_tree_add_item(tree, hf_ttp_dcredit, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
518 offset++;
519 }
520 else
521 {
522 proto_tree_add_item(tree, hf_ttp_p, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
523 proto_tree_add_item(tree, hf_ttp_icredit, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
524 offset++;
525 }
526 proto_item_set_len(tree, offset);
527 }
528 else
529 offset++;
530
531 return offset;
532}
533
534
535/*
536 * Dissect IAP request
537 */
538static void dissect_iap_request(tvbuff_t* tvb, packet_info* pinfo, proto_tree* root, uint8_t circuit_id)
539{
540 unsigned offset = 0;
541 uint8_t op;
542 uint8_t clen = 0;
543 uint8_t alen = 0;
544 uint8_t src;
545 address srcaddr;
546 address destaddr;
547 conversation_t* conv;
548 iap_conversation_t* iap_conv;
549
550 if (tvb_reported_length(tvb) == 0)
551 return;
552
553 /* Make entries in Protocol column on summary display */
554 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IAP");
555
556 op = tvb_get_uint8(tvb, offset) & IAP_OP0x3F;
557
558 switch (op)
559 {
560 case GET_VALUE_BY_CLASS0x04:
561 clen = MIN(tvb_get_uint8(tvb, offset + 1), 60)(((tvb_get_uint8(tvb, offset + 1)) < (60)) ? (tvb_get_uint8
(tvb, offset + 1)) : (60))
;
562 alen = MIN(tvb_get_uint8(tvb, offset + 1 + 1 + clen), 60)(((tvb_get_uint8(tvb, offset + 1 + 1 + clen)) < (60)) ? (tvb_get_uint8
(tvb, offset + 1 + 1 + clen)) : (60))
;
563
564 /* create conversation entry */
565 src = circuit_id ^ CMD_FRAME0x01;
566 set_address(&srcaddr, irda_address_type, 1, &src);
567
568 set_address(&destaddr, irda_address_type, 1, &circuit_id);
569
570 conv = find_conversation(pinfo->num, &srcaddr, &destaddr, CONVERSATION_NONE, pinfo->srcport, pinfo->destport, 0);
571 if (conv)
572 {
573 iap_conv = (iap_conversation_t*)conversation_get_proto_data(conv, proto_iap);
574 while (iap_conv)
575 {
576 if (iap_conv->iap_query_frame == pinfo->num)
577 {
578 iap_conv = NULL((void*)0);
579 break;
580 }
581 if (iap_conv->pnext == NULL((void*)0))
582 {
583 iap_conv->pnext = wmem_new0(wmem_file_scope(), iap_conversation_t)((iap_conversation_t*)wmem_alloc0((wmem_file_scope()), sizeof
(iap_conversation_t)))
;
584 iap_conv = iap_conv->pnext;
585 break;
586 }
587 iap_conv = iap_conv->pnext;
588 }
589 }
590 else
591 {
592 conv = conversation_new(pinfo->num, &srcaddr, &destaddr, CONVERSATION_NONE, pinfo->srcport, pinfo->destport, 0);
593 iap_conv = wmem_new0(wmem_file_scope(), iap_conversation_t)((iap_conversation_t*)wmem_alloc0((wmem_file_scope()), sizeof
(iap_conversation_t)))
;
594 conversation_add_proto_data(conv, proto_iap, (void*)iap_conv);
595 }
596 if (iap_conv)
597 {
598 iap_conv->iap_query_frame = pinfo->num;
599 }
600
601 char *class_name = (char *) tvb_get_string_enc(pinfo->pool, tvb, offset + 1 + 1, clen, ENC_ASCII0x00000000|ENC_NA0x00000000);
602 char *attr_name = (char *) tvb_get_string_enc(pinfo->pool, tvb, offset + 1 + 1 + clen + 1, alen, ENC_ASCII0x00000000|ENC_NA0x00000000);
603
604 col_add_fstr(pinfo->cinfo, COL_INFO, "GetValueByClass: \"%s\" \"%s\"",
605 format_text(pinfo->pool, class_name, strlen(class_name)),
606 format_text(pinfo->pool, attr_name, strlen(attr_name)));
607
608 /* Dissect IAP query if it is new */
609 if (iap_conv)
610 {
611 int i, j;
612
613 /* Find the attribute dissector */
614 for (i = 0; class_dissector[i].class_name != NULL((void*)0); i++)
615 if (strcmp(class_name, class_dissector[i].class_name) == 0)
616 {
617 for (j = 0; class_dissector[i].pattr_dissector[j].attr_name != NULL((void*)0); j++)
618 if (strcmp(attr_name, class_dissector[i].pattr_dissector[j].attr_name) == 0)
619 {
620 iap_conv->pattr_dissector = &class_dissector[i].pattr_dissector[j];
621 break;
622 }
623 break;
624 }
625 }
626 }
627
628 if (root)
629 {
630 /* create display subtree for the protocol */
631 proto_item* ti = proto_tree_add_item(root, proto_iap, tvb, 0, -1, ENC_NA0x00000000);
632 proto_tree* tree = proto_item_add_subtree(ti, ett_iap);
633
634 proto_tree* ctl_tree;
635
636
637 ti = proto_tree_add_item(tree, hf_iap_ctl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
638 ctl_tree = proto_item_add_subtree(ti, ett_iap_ctl);
639 proto_tree_add_item(ctl_tree, hf_iap_ctl_lst, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
640 proto_tree_add_item(ctl_tree, hf_iap_ctl_ack, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
641 proto_tree_add_item(ctl_tree, hf_iap_ctl_opcode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
642 offset++;
643
644 switch (op)
645 {
646 case GET_VALUE_BY_CLASS0x04:
647 proto_tree_add_item(tree, hf_iap_class_name, tvb, offset, 1, ENC_ASCII0x00000000|ENC_BIG_ENDIAN0x00000000);
648 offset += 1 + clen;
649
650 proto_tree_add_item(tree, hf_iap_attr_name, tvb, offset, 1, ENC_ASCII0x00000000|ENC_BIG_ENDIAN0x00000000);
651 offset += 1 + alen;
652 break;
653 }
654 }
655 else
656 {
657 offset++;
658 switch (op)
659 {
660 case GET_VALUE_BY_CLASS0x04:
661 offset += 1 + clen + 1 + alen;
662 break;
663 }
664 }
665
666 /* If any bytes remain, send it to the generic data dissector */
667 tvb = tvb_new_subset_remaining(tvb, offset);
668 call_data_dissector(tvb, pinfo, root);
669}
670
671
672/*
673 * Dissect IAP result
674 */
675static void dissect_iap_result(tvbuff_t* tvb, packet_info* pinfo, proto_tree* root, uint8_t circuit_id)
676{
677 unsigned offset = 0;
678 unsigned len = tvb_reported_length(tvb);
679 unsigned n = 0;
680 unsigned list_len;
681 uint8_t op;
682 uint8_t retcode;
683 uint8_t type;
684 uint16_t attr_len;
685 char buf[300];
686 uint8_t src;
687 address srcaddr;
688 address destaddr;
689 conversation_t* conv;
690 iap_conversation_t* cur_iap_conv;
691 iap_conversation_t* iap_conv = NULL((void*)0);
692 uint32_t num;
693
694
695 if (len == 0)
696 return;
697
698 /* Make entries in Protocol column on summary display */
699 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IAP");
700
701 op = tvb_get_uint8(tvb, offset) & IAP_OP0x3F;
702 retcode = tvb_get_uint8(tvb, offset + 1);
703
704 src = circuit_id ^ CMD_FRAME0x01;
705 set_address(&srcaddr, irda_address_type, 1, &src);
706
707 set_address(&destaddr, irda_address_type, 1, &circuit_id);
708
709 /* Find result value dissector */
710 conv = find_conversation(pinfo->num, &srcaddr, &destaddr, CONVERSATION_NONE, pinfo->srcport, pinfo->destport, 0);
711 if (conv)
712 {
713 num = pinfo->num;
714
715 iap_conv = (iap_conversation_t*)conversation_get_proto_data(conv, proto_iap);
716 while (iap_conv && (iap_conv->iap_query_frame >= num))
717 iap_conv = iap_conv->pnext;
718
719 if (iap_conv)
720 {
721 cur_iap_conv = iap_conv->pnext;
722 while (cur_iap_conv)
723 {
724 if ((cur_iap_conv->iap_query_frame < num) &&
725 (cur_iap_conv->iap_query_frame > iap_conv->iap_query_frame))
726 {
727 iap_conv = cur_iap_conv;
728 }
729
730 cur_iap_conv = cur_iap_conv->pnext;
731 }
732 }
733 }
734
735 col_set_str(pinfo->cinfo, COL_INFO, "Result: ");
736 col_append_str(pinfo->cinfo, COL_INFO, val_to_str(pinfo->pool, retcode, iap_return_vals, "0x%02X"));
737
738 switch (op)
739 {
740 case GET_VALUE_BY_CLASS0x04:
741 if (retcode == 0)
742 {
743 switch (tvb_get_uint8(tvb, offset + 6))
744 {
745 case IAS_MISSING0:
746 col_append_str(pinfo->cinfo, COL_INFO, ", Missing");
747 break;
748
749 case IAS_INTEGER1:
750 col_append_fstr(pinfo->cinfo, COL_INFO, ", Integer: %d", tvb_get_ntohl(tvb, offset + 7));
751 break;
752
753 case IAS_OCT_SEQ2:
754 snprintf(buf, 300, ", %d Octets", tvb_get_ntohs(tvb, offset + 7));
755 break;
756
757 case IAS_STRING3:
758 n = tvb_get_uint8(tvb, offset + 8);
759 col_append_fstr(pinfo->cinfo, COL_INFO, ", \"%s\"", tvb_get_string_enc(pinfo->pool, tvb, offset + 9, n, ENC_ASCII0x00000000));
760 break;
761 default:
762 break;
763 }
764 if (tvb_get_ntohs(tvb, offset + 2) > 1)
765 col_append_str(pinfo->cinfo, COL_INFO, ", ...");
766 }
767 break;
768 }
769
770 if (root)
771 {
772 /* create display subtree for the protocol */
773 proto_item* ti = proto_tree_add_item(root, proto_iap, tvb, 0, -1, ENC_NA0x00000000);
774 proto_tree* tree = proto_item_add_subtree(ti, ett_iap);
775
776 proto_tree* ctl_tree;
777 proto_tree* entry_tree;
778
779
780 ti = proto_tree_add_item(tree, hf_iap_ctl, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
781 ctl_tree = proto_item_add_subtree(ti, ett_iap_ctl);
782 proto_tree_add_item(ctl_tree, hf_iap_ctl_lst, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
783 proto_tree_add_item(ctl_tree, hf_iap_ctl_ack, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
784 proto_tree_add_item(ctl_tree, hf_iap_ctl_opcode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
785 offset++;
786
787 proto_tree_add_item(tree, hf_iap_return, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
788 offset++;
789
790 switch (op)
791 {
792 case GET_VALUE_BY_CLASS0x04:
793 if (retcode == 0)
794 {
795 proto_tree_add_item_ret_uint(tree, hf_iap_list_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &list_len);
796 offset += 2;
797
798 while ((offset < len) && (n < list_len))
799 {
800 type = tvb_get_uint8(tvb, offset + 2);
801 switch (type)
802 {
803 case IAS_INTEGER1:
804 attr_len = 4;
805 break;
806
807 case IAS_OCT_SEQ2:
808 attr_len = tvb_get_ntohs(tvb, offset + 2 + 1) + 2;
809 break;
810
811 case IAS_STRING3:
812 attr_len = tvb_get_uint8(tvb, offset + 2 + 1 + 1) + 2;
813 break;
814
815 default:
816 attr_len = 0;
817 }
818
819 ti = proto_tree_add_item(tree, hf_iap_list_entry, tvb, offset, 2 + 1 + attr_len, ENC_NA0x00000000);
820 proto_item_append_text(ti, "%d", n + 1);
821 entry_tree = proto_item_add_subtree(ti, ett_iap_entry[MIN(n, MAX_IAP_ENTRIES - 1)(((n) < (32 - 1)) ? (n) : (32 - 1))]);
822
823 proto_tree_add_item(entry_tree, hf_iap_obj_id, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
824 offset += 2;
825
826 proto_tree_add_item(entry_tree, hf_iap_attr_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
827 offset++;
828
829 switch (type)
830 {
831 case IAS_INTEGER1:
832 if (!iap_conv || !iap_conv->pattr_dissector ||
833 !iap_conv->pattr_dissector->value_dissector(tvb, offset, pinfo, entry_tree,
834 n, type, circuit_id))
835 proto_tree_add_item(entry_tree, hf_iap_int, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
836 break;
837
838 case IAS_OCT_SEQ2:
839 proto_tree_add_item(entry_tree, hf_iap_seq_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
840 if (!iap_conv || !iap_conv->pattr_dissector ||
841 !iap_conv->pattr_dissector->value_dissector(tvb, offset, pinfo, entry_tree,
842 n, type, circuit_id))
843 proto_tree_add_item(entry_tree, hf_iap_oct_seq, tvb, offset + 2,
844 attr_len - 2, ENC_NA0x00000000);
845 break;
846
847 case IAS_STRING3:
848 proto_tree_add_item(entry_tree, hf_iap_char_set, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
849 if (!iap_conv || !iap_conv->pattr_dissector ||
850 !iap_conv->pattr_dissector->value_dissector(tvb, offset, pinfo, entry_tree,
851 n, type, circuit_id))
852 proto_tree_add_item(entry_tree, hf_iap_string, tvb, offset + 1, 1, ENC_ASCII0x00000000|ENC_BIG_ENDIAN0x00000000);
853 break;
854 }
855 offset += attr_len;
856
857 n++;
858 }
859 }
860 break;
861 }
862 }
863 else
864 {
865 offset += 2;
866 switch (op)
867 {
868 case GET_VALUE_BY_CLASS0x04:
869 if (retcode == 0)
870 {
871 offset += 2;
872
873 while (offset < len)
874 {
875 offset += 2;
876 type = tvb_get_uint8(tvb, offset);
877 offset++;
878
879 switch (type)
880 {
881 case IAS_INTEGER1:
882 attr_len = 4;
883 if (iap_conv && iap_conv->pattr_dissector)
884 iap_conv->pattr_dissector->value_dissector(tvb, offset, pinfo, 0,
885 n, type, circuit_id);
886 break;
887
888 case IAS_OCT_SEQ2:
889 attr_len = tvb_get_ntohs(tvb, offset) + 2;
890 if (iap_conv && iap_conv->pattr_dissector)
891 iap_conv->pattr_dissector->value_dissector(tvb, offset, pinfo, 0,
892 n, type, circuit_id);
893 break;
894
895 case IAS_STRING3:
896 attr_len = tvb_get_uint8(tvb, offset + 1) + 2;
897 if (iap_conv && iap_conv->pattr_dissector)
898 iap_conv->pattr_dissector->value_dissector(tvb, offset, pinfo, 0,
899 n, type, circuit_id);
900 break;
901
902 default:
903 attr_len = 0;
904 }
905 offset += attr_len;
906
907 n++;
908 }
909 }
910 break;
911 }
912 }
913
914 /* If any bytes remain, send it to the generic data dissector */
915 tvb = tvb_new_subset_remaining(tvb, offset);
916 call_data_dissector(tvb, pinfo, root);
917}
918
919
920/*
921 * Check if IAP result is octet sequence
922 */
923bool_Bool check_iap_octet_result(tvbuff_t* tvb, proto_tree* tree, unsigned offset,
924 const char* attr_name, uint8_t attr_type)
925{
926 if (attr_type != IAS_OCT_SEQ2)
927 {
928 if (tree)
929 {
930 proto_item* ti = proto_tree_add_item(tree, hf_iap_invaloctet, tvb, offset, 0, ENC_NA0x00000000);
931 proto_item_append_text(ti, "%s", attr_name);
932 proto_item_append_text(ti, "\" attribute must be octet sequence!");
933 }
934
935 return false0;
936 }
937 else
938 return true1;
939}
940
941
942/*
943 * Check if IAP result is correct LsapSel
944 */
945uint8_t check_iap_lsap_result(tvbuff_t* tvb, proto_tree* tree, unsigned offset,
946 const char* attr_name, uint8_t attr_type)
947{
948 uint32_t lsap;
949
950
951 if ((attr_type != IAS_INTEGER1) || ((lsap = tvb_get_ntohl(tvb, offset)) < 0x01) ||
952 (lsap > 0x6F))
953 {
954 if (tree)
955 {
956 proto_item* ti = proto_tree_add_item(tree, hf_iap_invallsap, tvb, offset, 0, ENC_NA0x00000000);
957 proto_item_append_text(ti, "%s", attr_name);
958 proto_item_append_text(ti, "\" attribute must be integer value between 0x01 and 0x6F!");
959 }
960
961 return 0;
962 }
963 else
964 return lsap;
965}
966
967
968/*
969 * Dissect IrDA application protocol
970 */
971static void dissect_appl_proto(tvbuff_t* tvb, packet_info* pinfo, proto_tree* root, pdu_type_t pdu_type, uint8_t circuit_id)
972{
973 unsigned offset = 0;
974 uint8_t src;
975 address srcaddr;
976 address destaddr;
977 conversation_t* conv;
978 lmp_conversation_t* cur_lmp_conv;
979 lmp_conversation_t* lmp_conv = NULL((void*)0);
980 uint32_t num;
981
982
983 src = circuit_id ^ CMD_FRAME0x01;
984 set_address(&srcaddr, irda_address_type, 1, &src);
985
986 set_address(&destaddr, irda_address_type, 1, &circuit_id);
987
988 /* Find result value dissector */
989 conv = find_conversation(pinfo->num, &srcaddr, &destaddr, CONVERSATION_NONE, pinfo->srcport, pinfo->destport, 0);
990 if (conv)
991 {
992 num = pinfo->num;
993
994 lmp_conv = (lmp_conversation_t*)conversation_get_proto_data(conv, proto_irlmp);
995 while (lmp_conv && (lmp_conv->iap_result_frame >= num))
996 lmp_conv = lmp_conv->pnext;
997
998 if (lmp_conv)
999 {
1000 cur_lmp_conv = lmp_conv->pnext;
1001 while (cur_lmp_conv)
1002 {
1003 if ((cur_lmp_conv->iap_result_frame < num) &&
1004 (cur_lmp_conv->iap_result_frame > lmp_conv->iap_result_frame))
1005 {
1006 lmp_conv = cur_lmp_conv;
1007 }
1008
1009 cur_lmp_conv = cur_lmp_conv->pnext;
1010 }
1011 }
1012 }
1013
1014 if (lmp_conv)
1015 {
1016/*ws_message("%x:%d->%x:%d = %p\n", src, pinfo->srcport, circuit_id, pinfo->destport, lmp_conv); */
1017/*ws_message("->%d: %d %d %p\n", pinfo->num, lmp_conv->iap_result_frame, lmp_conv->ttp, lmp_conv->proto_dissector); */
1018 if ((lmp_conv->ttp) && (pdu_type != DISCONNECT_PDU))
1019 {
1020 offset += dissect_ttp(tvb, pinfo, root, (pdu_type == DATA_PDU));
1021
1022 tvb = tvb_new_subset_remaining(tvb, offset);
1023 }
1024
1025 call_dissector_with_data(lmp_conv->dissector, tvb, pinfo, root, GUINT_TO_POINTER(pdu_type)((gpointer) (gulong) (pdu_type)));
1026 }
1027 else
1028 call_data_dissector(tvb, pinfo, root);
1029}
1030
1031
1032/*
1033 * Dissect LMP
1034 */
1035static void dissect_irlmp(tvbuff_t* tvb, packet_info* pinfo, proto_tree* root, uint8_t circuit_id)
1036{
1037 unsigned offset = 0;
1038 uint8_t dlsap;
1039 uint8_t slsap;
1040 uint8_t cbit;
1041 uint8_t opcode = 0;
1042
1043
1044 /* Make entries in Protocol column on summary display */
1045 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IrLMP");
1046
1047 dlsap = tvb_get_uint8(tvb, offset);
1048 cbit = dlsap & CONTROL_BIT0x80;
1049 dlsap &= ~CONTROL_BIT0x80;
1050
1051 slsap = tvb_get_uint8(tvb, offset+1) & ~CONTROL_BIT0x80;
1052
1053 /* save Lsaps in pinfo */
1054 pinfo->srcport = slsap;
1055 pinfo->destport = dlsap;
1056
1057 if (cbit != 0)
1058 {
1059 opcode = tvb_get_uint8(tvb, offset+2);
1060
1061 col_add_fstr(pinfo->cinfo, COL_INFO, "%d > %d, ", slsap, dlsap);
1062 col_append_str(pinfo->cinfo, COL_INFO, val_to_str(pinfo->pool, opcode, lmp_opcode_vals, "0x%02X"));
1063 if ((opcode == ACCESSMODE_CMD0x03) || (opcode == ACCESSMODE_CNF0x83))
1064 {
1065 col_append_str(pinfo->cinfo, COL_INFO, " (");
1066 col_append_str(pinfo->cinfo, COL_INFO,
1067 val_to_str(pinfo->pool, tvb_get_uint8(tvb, offset+4), lmp_mode_vals, "0x%02X"));
1068 col_append_str(pinfo->cinfo, COL_INFO, ")");
1069 }
1070 }
1071 else
1072 col_add_fstr(pinfo->cinfo, COL_INFO, "%d > %d, Len=%d", slsap, dlsap,
1073 tvb_reported_length(tvb) - 2);
1074
1075 if (root)
1076 {
1077 /* create display subtree for the protocol */
1078 proto_item* ti = proto_tree_add_item(root, proto_irlmp, tvb, 0, -1, ENC_NA0x00000000);
1079 proto_tree* tree = proto_item_add_subtree(ti, ett_irlmp);
1080
1081 proto_tree* dst_tree;
1082 proto_tree* src_tree;
1083
1084
1085 ti = proto_tree_add_item(tree, hf_lmp_dst, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1086 dst_tree = proto_item_add_subtree(ti, ett_lmp_dst);
1087 proto_tree_add_item(dst_tree, hf_lmp_dst_control, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1088 proto_tree_add_item(dst_tree, hf_lmp_dst_lsap, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1089 offset++;
1090
1091 ti = proto_tree_add_item(tree, hf_lmp_src, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1092 src_tree = proto_item_add_subtree(ti, ett_lmp_src);
1093 proto_tree_add_item(src_tree, hf_lmp_src_r, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1094 proto_tree_add_item(src_tree, hf_lmp_src_lsap, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1095 offset++;
1096
1097 if (cbit != 0)
1098 {
1099 proto_tree_add_item(tree, hf_lmp_opcode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1100 offset++;
1101
1102 switch (opcode)
1103 {
1104 case CONNECT_CMD0x01:
1105 case CONNECT_CNF0x81:
1106 if (offset < tvb_reported_length(tvb))
1107 {
1108 proto_tree_add_item(tree, hf_lmp_rsvd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1109 offset++;
1110 }
1111 break;
1112
1113 case DISCONNECT0x02:
1114 proto_tree_add_item(tree, hf_lmp_reason, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1115 offset++;
1116 break;
1117
1118 case ACCESSMODE_CMD0x03:
1119 proto_tree_add_item(tree, hf_lmp_rsvd, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1120 offset++;
1121
1122 proto_tree_add_item(tree, hf_lmp_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1123 offset++;
1124 break;
1125
1126 case ACCESSMODE_CNF0x83:
1127 proto_tree_add_item( tree, hf_lmp_status, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1128 offset++;
1129
1130 proto_tree_add_item(tree, hf_lmp_mode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1131 offset++;
1132 break;
1133 }
1134 }
1135
1136 tvb = tvb_new_subset_remaining(tvb, offset);
1137 proto_item_set_len(tree, offset);
1138 }
1139 else
1140 {
1141 offset += 2;
1142 if (cbit != 0)
1143 {
1144 offset += 1;
1145
1146 switch (opcode)
1147 {
1148 case CONNECT_CMD0x01:
1149 case CONNECT_CNF0x81:
1150 if (offset < tvb_reported_length(tvb))
1151 offset++;
1152 break;
1153
1154 case DISCONNECT0x02:
1155 offset++;
1156 break;
1157
1158 case ACCESSMODE_CMD0x03:
1159 case ACCESSMODE_CNF0x83:
1160 offset += 2;
1161 break;
1162 }
1163 }
1164
1165 tvb = tvb_new_subset_remaining(tvb, offset);
1166 }
1167
1168 if (cbit == 0)
1169 {
1170 if (dlsap == LSAP_IAS0x00)
1171 dissect_iap_request(tvb, pinfo, root, circuit_id);
1172 else if (slsap == LSAP_IAS0x00)
1173 dissect_iap_result(tvb, pinfo, root, circuit_id);
1174 else
1175 dissect_appl_proto(tvb, pinfo, root, DATA_PDU, circuit_id);
1176 }
1177 else
1178 {
1179 if ((dlsap == LSAP_IAS0x00) || (slsap == LSAP_IAS0x00))
1180 call_data_dissector(tvb, pinfo, root);
1181 else
1182 switch (opcode)
1183 {
1184 case CONNECT_CMD0x01:
1185 case CONNECT_CNF0x81:
1186 dissect_appl_proto(tvb, pinfo, root, CONNECT_PDU, circuit_id);
1187 break;
1188
1189 case DISCONNECT0x02:
1190 dissect_appl_proto(tvb, pinfo, root, DISCONNECT_PDU, circuit_id);
1191 break;
1192
1193 default:
1194 call_data_dissector(tvb, pinfo, root);
1195 }
1196 }
1197}
1198
1199
1200/*
1201 * Add LMP conversation
1202 */
1203void add_lmp_conversation(packet_info* pinfo, uint8_t dlsap, bool_Bool ttp, dissector_handle_t dissector, uint8_t circuit_id)
1204{
1205 uint8_t dest;
1206 address srcaddr;
1207 address destaddr;
1208 conversation_t* conv;
1209 lmp_conversation_t* lmp_conv = NULL((void*)0);
1210
1211
1212/*ws_message("%d: add_lmp_conversation(%p, %d, %d, %p) = ", pinfo->num, pinfo, dlsap, ttp, proto_dissector); */
1213 set_address(&srcaddr, irda_address_type, 1, &circuit_id);
1214 dest = circuit_id ^ CMD_FRAME0x01;
1215 set_address(&destaddr, irda_address_type, 1, &dest);
1216
1217 conv = find_conversation(pinfo->num, &destaddr, &srcaddr, CONVERSATION_NONE, dlsap, 0, NO_PORT_B0x00020000);
1218 if (conv)
1
Assuming 'conv' is non-null
2
Taking true branch
1219 {
1220 lmp_conv = (lmp_conversation_t*)conversation_get_proto_data(conv, proto_irlmp);
3
Value assigned to 'lmp_conv'
1221 while (lmp_conv)
4
Assuming pointer value is null
5
Loop condition is false. Execution continues on line 1243
1222 {
1223 /* Does entry already exist? */
1224 if (lmp_conv->iap_result_frame == pinfo->num)
1225 return;
1226
1227 if (lmp_conv->pnext == NULL((void*)0))
1228 {
1229 lmp_conv->pnext = wmem_new0(wmem_file_scope(), lmp_conversation_t)((lmp_conversation_t*)wmem_alloc0((wmem_file_scope()), sizeof
(lmp_conversation_t)))
;
1230 lmp_conv = lmp_conv->pnext;
1231 break;
1232 }
1233 lmp_conv = lmp_conv->pnext;
1234 }
1235 }
1236 else
1237 {
1238 conv = conversation_new(pinfo->num, &destaddr, &srcaddr, CONVERSATION_NONE, dlsap, 0, NO_PORT20x02);
1239 lmp_conv = wmem_new0(wmem_file_scope(), lmp_conversation_t)((lmp_conversation_t*)wmem_alloc0((wmem_file_scope()), sizeof
(lmp_conversation_t)))
;
1240 conversation_add_proto_data(conv, proto_irlmp, (void*)lmp_conv);
1241 }
1242
1243 lmp_conv->iap_result_frame = pinfo->num;
6
Access to field 'iap_result_frame' results in a dereference of a null pointer (loaded from variable 'lmp_conv')
1244 lmp_conv->ttp = ttp;
1245 lmp_conv->dissector = dissector;
1246
1247/*ws_message("%p\n", lmp_conv); */
1248}
1249
1250
1251/*
1252 * Dissect Negotiation Parameters
1253 */
1254static unsigned dissect_negotiation(tvbuff_t* tvb, proto_tree* tree, unsigned offset)
1255{
1256 unsigned n = 0;
1257 proto_item* ti;
1258 proto_tree* p_tree;
1259 char buf[256];
1260 uint8_t pv;
1261
1262 while (tvb_reported_length_remaining(tvb, offset) > 0)
1263 {
1264 uint8_t p_len = tvb_get_uint8(tvb, offset + 1);
1265
1266 if (tree)
1267 {
1268 ti = proto_tree_add_item(tree, hf_negotiation_param, tvb, offset, p_len + 2, ENC_NA0x00000000);
1269 p_tree = proto_item_add_subtree(ti, ett_param[MIN(n, MAX_PARAMETERS - 1)(((n) < (32 - 1)) ? (n) : (32 - 1))]);
1270
1271 pv = tvb_get_uint8(tvb, offset+2);
1272 buf[0] = 0;
1273
1274 switch (tvb_get_uint8(tvb, offset))
1275 {
1276 case PI_BAUD_RATE0x01:
1277 proto_item_append_text(ti, ": Baud Rate (");
1278
1279 if (pv & 0x01)
1280 (void) g_strlcat(buf, ", 2400", 256);
1281 if (pv & 0x02)
1282 (void) g_strlcat(buf, ", 9600", 256);
1283 if (pv & 0x04)
1284 (void) g_strlcat(buf, ", 19200", 256);
1285 if (pv & 0x08)
1286 (void) g_strlcat(buf, ", 38400", 256);
1287 if (pv & 0x10)
1288 (void) g_strlcat(buf, ", 57600", 256);
1289 if (pv & 0x20)
1290 (void) g_strlcat(buf, ", 115200", 256);
1291 if (pv & 0x40)
1292 (void) g_strlcat(buf, ", 576000", 256);
1293 if (pv & 0x80)
1294 (void) g_strlcat(buf, ", 1152000", 256);
1295 if ((p_len > 1) && (tvb_get_uint8(tvb, offset+3) & 0x01))
1296 (void) g_strlcat(buf, ", 4000000", 256);
1297
1298 (void) g_strlcat(buf, " bps)", 256);
1299
1300 proto_item_append_text(ti, "%s", buf+2);
1301
1302 break;
1303
1304 case PI_MAX_TURN_TIME0x82:
1305 proto_item_append_text(ti, ": Maximum Turn Time (");
1306
1307 if (pv & 0x01)
1308 (void) g_strlcat(buf, ", 500", 256);
1309 if (pv & 0x02)
1310 (void) g_strlcat(buf, ", 250", 256);
1311 if (pv & 0x04)
1312 (void) g_strlcat(buf, ", 100", 256);
1313 if (pv & 0x08)
1314 (void) g_strlcat(buf, ", 50", 256);
1315
1316 (void) g_strlcat(buf, " ms)", 256);
1317
1318 proto_item_append_text(ti, "%s", buf+2);
1319
1320 break;
1321
1322 case PI_DATA_SIZE0x83:
1323 proto_item_append_text(ti, ": Data Size (");
1324
1325 if (pv & 0x01)
1326 (void) g_strlcat(buf, ", 64", 256);
1327 if (pv & 0x02)
1328 (void) g_strlcat(buf, ", 128", 256);
1329 if (pv & 0x04)
1330 (void) g_strlcat(buf, ", 256", 256);
1331 if (pv & 0x08)
1332 (void) g_strlcat(buf, ", 512", 256);
1333 if (pv & 0x10)
1334 (void) g_strlcat(buf, ", 1024", 256);
1335 if (pv & 0x20)
1336 (void) g_strlcat(buf, ", 2048", 256);
1337
1338 (void) g_strlcat(buf, " bytes)", 256);
1339
1340 proto_item_append_text(ti, "%s", buf+2);
1341
1342 break;
1343
1344 case PI_WINDOW_SIZE0x84:
1345 proto_item_append_text(ti, ": Window Size (");
1346
1347 if (pv & 0x01)
1348 (void) g_strlcat(buf, ", 1", 256);
1349 if (pv & 0x02)
1350 (void) g_strlcat(buf, ", 2", 256);
1351 if (pv & 0x04)
1352 (void) g_strlcat(buf, ", 3", 256);
1353 if (pv & 0x08)
1354 (void) g_strlcat(buf, ", 4", 256);
1355 if (pv & 0x10)
1356 (void) g_strlcat(buf, ", 5", 256);
1357 if (pv & 0x20)
1358 (void) g_strlcat(buf, ", 6", 256);
1359 if (pv & 0x40)
1360 (void) g_strlcat(buf, ", 7", 256);
1361
1362 (void) g_strlcat(buf, " frame window)", 256);
1363
1364 proto_item_append_text(ti, "%s", buf+2);
1365
1366 break;
1367
1368 case PI_ADD_BOFS0x85:
1369 proto_item_append_text(ti, ": Additional BOFs (");
1370
1371 if (pv & 0x01)
1372 (void) g_strlcat(buf, ", 48", 256);
1373 if (pv & 0x02)
1374 (void) g_strlcat(buf, ", 24", 256);
1375 if (pv & 0x04)
1376 (void) g_strlcat(buf, ", 12", 256);
1377 if (pv & 0x08)
1378 (void) g_strlcat(buf, ", 5", 256);
1379 if (pv & 0x10)
1380 (void) g_strlcat(buf, ", 3", 256);
1381 if (pv & 0x20)
1382 (void) g_strlcat(buf, ", 2", 256);
1383 if (pv & 0x40)
1384 (void) g_strlcat(buf, ", 1", 256);
1385 if (pv & 0x80)
1386 (void) g_strlcat(buf, ", 0", 256);
1387
1388 (void) g_strlcat(buf, " additional BOFs at 115200)", 256);
1389
1390 proto_item_append_text(ti, "%s", buf+2);
1391
1392 break;
1393
1394 case PI_MIN_TURN_TIME0x86:
1395 proto_item_append_text(ti, ": Minimum Turn Time (");
1396
1397 if (pv & 0x01)
1398 (void) g_strlcat(buf, ", 10", 256);
1399 if (pv & 0x02)
1400 (void) g_strlcat(buf, ", 5", 256);
1401 if (pv & 0x04)
1402 (void) g_strlcat(buf, ", 1", 256);
1403 if (pv & 0x08)
1404 (void) g_strlcat(buf, ", 0.5", 256);
1405 if (pv & 0x10)
1406 (void) g_strlcat(buf, ", 0.1", 256);
1407 if (pv & 0x20)
1408 (void) g_strlcat(buf, ", 0.05", 256);
1409 if (pv & 0x40)
1410 (void) g_strlcat(buf, ", 0.01", 256);
1411 if (pv & 0x80)
1412 (void) g_strlcat(buf, ", 0", 256);
1413
1414 (void) g_strlcat(buf, " ms)", 256);
1415
1416 proto_item_append_text(ti, "%s", buf+2);
1417
1418 break;
1419
1420 case PI_LINK_DISC0x08:
1421 proto_item_append_text(ti, ": Link Disconnect/Threshold Time (");
1422
1423 if (pv & 0x01)
1424 (void) g_strlcat(buf, ", 3/0", 256);
1425 if (pv & 0x02)
1426 (void) g_strlcat(buf, ", 8/3", 256);
1427 if (pv & 0x04)
1428 (void) g_strlcat(buf, ", 12/3", 256);
1429 if (pv & 0x08)
1430 (void) g_strlcat(buf, ", 16/3", 256);
1431 if (pv & 0x10)
1432 (void) g_strlcat(buf, ", 20/3", 256);
1433 if (pv & 0x20)
1434 (void) g_strlcat(buf, ", 25/3", 256);
1435 if (pv & 0x40)
1436 (void) g_strlcat(buf, ", 30/3", 256);
1437 if (pv & 0x80)
1438 (void) g_strlcat(buf, ", 40/3", 256);
1439
1440 (void) g_strlcat(buf, " s)", 256);
1441
1442 proto_item_append_text(ti, "%s", buf+2);
1443
1444 break;
1445
1446 default:
1447 proto_item_append_text(ti, ": unknown");
1448 }
1449 } else
1450 p_tree = NULL((void*)0);
1451
1452 offset = dissect_param_tuple(tvb, p_tree, offset);
1453 n++;
1454 }
1455
1456 return offset;
1457}
1458
1459
1460/*
1461 * Dissect XID packet
1462 */
1463static void dissect_xid(tvbuff_t* tvb, packet_info* pinfo, proto_tree* root, proto_tree* lap_tree, bool_Bool is_command)
1464{
1465 int offset = 0;
1466 proto_item* ti = NULL((void*)0);
1467 proto_tree* i_tree = NULL((void*)0);
1468 proto_tree* flags_tree;
1469 uint32_t saddr, daddr;
1470 uint8_t s;
1471 proto_tree* lmp_tree = NULL((void*)0);
1472
1473 if (lap_tree)
1474 {
1475 ti = proto_tree_add_item(lap_tree, hf_lap_i, tvb, offset, -1, ENC_NA0x00000000);
1476 i_tree = proto_item_add_subtree(ti, ett_lap_i);
1477
1478 proto_tree_add_item(i_tree, hf_xid_ident, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1479 }
1480 offset++;
1481
1482 saddr = tvb_get_letohl(tvb, offset);
1483 col_add_fstr(pinfo->cinfo, COL_DEF_SRC, "0x%08X", saddr);
1484 if (lap_tree)
1485 proto_tree_add_uint(i_tree, hf_xid_saddr, tvb, offset, 4, saddr);
1486 offset += 4;
1487
1488 daddr = tvb_get_letohl(tvb, offset);
1489 col_add_fstr(pinfo->cinfo, COL_DEF_DST, "0x%08X", daddr);
1490 if (lap_tree)
1491 proto_tree_add_uint(i_tree, hf_xid_daddr, tvb, offset, 4, daddr);
1492 offset += 4;
1493
1494 if (lap_tree)
1495 {
1496 /* Discovery flags */
1497 ti = proto_tree_add_item(i_tree, hf_xid_flags, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1498 flags_tree = proto_item_add_subtree(ti, ett_xid_flags);
1499 proto_tree_add_item(flags_tree, hf_xid_s, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1500 proto_tree_add_item(flags_tree, hf_xid_conflict, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1501 }
1502 offset++;
1503
1504 if (is_command)
1505 {
1506 s = tvb_get_uint8(tvb, offset);
1507 if (s == 0xFF)
1508 col_append_str(pinfo->cinfo, COL_INFO, ", s=final");
1509 else
1510 col_append_fstr(pinfo->cinfo, COL_INFO, ", s=%u", s);
1511 if (lap_tree)
1512 {
1513 ti = proto_tree_add_uint(i_tree, hf_xid_slotnr, tvb, offset, 1, s);
1514 if (s == 0xFF)
1515 proto_item_append_text(ti, " (final)");
1516 }
1517 }
1518 /* Skip (empty?) byte even if no command.. Have seen non-zero values in a capture */
1519 offset++;
1520
1521 if (lap_tree)
1522 proto_tree_add_item(i_tree, hf_xid_version, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1523 offset++;
1524
1525 if (lap_tree)
1526 {
1527 proto_item_set_end(lap_tree, tvb, offset);
1528 proto_item_set_end(i_tree, tvb, offset);
1529 }
1530
1531 if (tvb_reported_length_remaining(tvb, offset) > 0)
1532 {
1533 unsigned hints_len;
1534 uint8_t hint1 = 0;
1535 uint8_t hint2 = 0;
1536
1537 if (root)
1538 {
1539 ti = proto_tree_add_item(root, proto_irlmp, tvb, offset, -1, ENC_NA0x00000000);
1540 lmp_tree = proto_item_add_subtree(ti, ett_irlmp);
1541 }
1542
1543 for (hints_len = 0;;)
1544 {
1545 uint8_t hint = tvb_get_uint8(tvb, offset + hints_len++);
1546
1547 if (hints_len == 1)
1548 hint1 = hint;
1549 else if (hints_len == 2)
1550 hint2 = hint;
1551
1552 if ((hint & 0x80) == 0)
1553 break;
1554 }
1555
1556 if (root)
1557 {
1558 ti = proto_tree_add_item(lmp_tree, hf_lmp_xid_hints, tvb, offset, hints_len, ENC_NA0x00000000);
1559 if ((hint1 | hint2) != 0)
1560 {
1561 char service_hints[256];
1562
1563 service_hints[0] = 0;
1564
1565 if (hint1 & 0x01)
1566 (void) g_strlcat(service_hints, ", PnP Compatible", 256);
1567 if (hint1 & 0x02)
1568 (void) g_strlcat(service_hints, ", PDA/Palmtop", 256);
1569 if (hint1 & 0x04)
1570 (void) g_strlcat(service_hints, ", Computer", 256);
1571 if (hint1 & 0x08)
1572 (void) g_strlcat(service_hints, ", Printer", 256);
1573 if (hint1 & 0x10)
1574 (void) g_strlcat(service_hints, ", Modem", 256);
1575 if (hint1 & 0x20)
1576 (void) g_strlcat(service_hints, ", Fax", 256);
1577 if (hint1 & 0x40)
1578 (void) g_strlcat(service_hints, ", LAN Access", 256);
1579 if (hint2 & 0x01)
1580 (void) g_strlcat(service_hints, ", Telephony", 256);
1581 if (hint2 & 0x02)
1582 (void) g_strlcat(service_hints, ", File Server", 256);
1583 if (hint2 & 0x04)
1584 (void) g_strlcat(service_hints, ", IrCOMM", 256);
1585 if (hint2 & 0x20)
1586 (void) g_strlcat(service_hints, ", OBEX", 256);
1587
1588 (void) g_strlcat(service_hints, ")", 256);
1589 service_hints[0] = ' ';
1590 service_hints[1] = '(';
1591
1592 proto_item_append_text(ti, "%s", service_hints);
1593 }
1594 }
1595 offset += hints_len;
1596
1597 if (tvb_reported_length_remaining(tvb, offset) > 0)
1598 {
1599 uint8_t cset;
1600 int name_len;
1601 char *name;
1602 bool_Bool have_encoding;
1603 unsigned encoding;
1604
1605 cset = tvb_get_uint8(tvb, offset);
1606 if (root)
1607 proto_tree_add_uint(lmp_tree, hf_lmp_xid_charset, tvb, offset, 1, cset);
1608 offset++;
1609 name_len = tvb_reported_length_remaining(tvb, offset);
1610 if (name_len > 0)
1611 {
1612 switch (cset) {
1613
1614 case LMP_CHARSET_ASCII0:
1615 encoding = ENC_ASCII0x00000000|ENC_NA0x00000000;
1616 have_encoding = true1;
1617 break;
1618
1619 case LMP_CHARSET_ISO_8859_11:
1620 encoding = ENC_ISO_8859_10x0000000A|ENC_NA0x00000000;
1621 have_encoding = true1;
1622 break;
1623
1624 case LMP_CHARSET_ISO_8859_22:
1625 encoding = ENC_ISO_8859_20x0000000C|ENC_NA0x00000000;
1626 have_encoding = true1;
1627 break;
1628
1629 case LMP_CHARSET_ISO_8859_33:
1630 encoding = ENC_ISO_8859_30x0000000E|ENC_NA0x00000000;
1631 have_encoding = true1;
1632 break;
1633
1634 case LMP_CHARSET_ISO_8859_44:
1635 encoding = ENC_ISO_8859_40x00000010|ENC_NA0x00000000;
1636 have_encoding = true1;
1637 break;
1638
1639 case LMP_CHARSET_ISO_8859_55:
1640 encoding = ENC_ISO_8859_50x00000012|ENC_NA0x00000000;
1641 have_encoding = true1;
1642 break;
1643
1644 case LMP_CHARSET_ISO_8859_66:
1645 encoding = ENC_ISO_8859_60x00000014|ENC_NA0x00000000;
1646 have_encoding = true1;
1647 break;
1648
1649 case LMP_CHARSET_ISO_8859_77:
1650 encoding = ENC_ISO_8859_70x00000016|ENC_NA0x00000000;
1651 have_encoding = true1;
1652 break;
1653
1654 case LMP_CHARSET_ISO_8859_88:
1655 encoding = ENC_ISO_8859_80x00000018|ENC_NA0x00000000;
1656 have_encoding = true1;
1657 break;
1658
1659 case LMP_CHARSET_ISO_8859_99:
1660 encoding = ENC_ISO_8859_90x0000001A|ENC_NA0x00000000;
1661 have_encoding = true1;
1662 break;
1663
1664 case LMP_CHARSET_UNICODE0xFF:
1665 /* Presumably big-endian; assume just UCS-2 for now */
1666 encoding = ENC_UCS_20x00000006|ENC_BIG_ENDIAN0x00000000;
1667 have_encoding = true1;
1668 break;
1669
1670 default:
1671 encoding = 0;
1672 have_encoding = false0;
1673 break;
1674 }
1675
1676 if (have_encoding)
1677 {
1678 name = (char *) tvb_get_string_enc(pinfo->pool, tvb, offset, name_len, encoding);
1679 col_append_fstr(pinfo->cinfo, COL_INFO, ", \"%s\"", format_text(pinfo->pool, name, strlen(name)));
1680 if (root)
1681 proto_tree_add_item(lmp_tree, hf_lmp_xid_name, tvb, offset,
1682 -1, encoding);
1683 }
1684 else
1685 {
1686 if (root)
1687 proto_tree_add_item(lmp_tree, hf_lmp_xid_name_no_encoding, tvb, offset,
1688 -1, ENC_NA0x00000000);
1689 }
1690 }
1691 }
1692 }
1693}
1694
1695
1696/*
1697 * Dissect Log Messages
1698 */
1699static void dissect_log(tvbuff_t* tvb, packet_info* pinfo, proto_tree* root)
1700{
1701 /* Make entries in Protocol column on summary display */
1702 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Log");
1703
1704 /* missed messages? */
1705 if (pinfo->pseudo_header->irda.pkttype == IRDA_MISSED_MSG0x0101)
1706 {
1707 col_set_str(pinfo->cinfo, COL_INFO, "WARNING: Missed one or more messages while capturing!");
1708 }
1709 else
1710 {
1711 unsigned length;
1712 char *buf;
1713
1714 length = tvb_captured_length(tvb);
1715 buf = (char *) tvb_get_string_enc(pinfo->pool, tvb, 0, length, ENC_ASCII0x00000000|ENC_NA0x00000000);
1716 if (length > 0 && buf[length-1] == '\n')
1717 buf[length-1] = 0;
1718 else if (length > 1 && buf[length-2] == '\n')
1719 buf[length-2] = 0;
1720
1721 col_add_str(pinfo->cinfo, COL_INFO, format_text(pinfo->pool, buf, strlen(buf)));
1722 }
1723
1724 if (root)
1725 {
1726 proto_item* ti = proto_tree_add_item(root, proto_log, tvb, 0, -1, ENC_NA0x00000000);
1727 proto_tree* tree = proto_item_add_subtree(ti, ett_log);
1728
1729 if (pinfo->pseudo_header->irda.pkttype == IRDA_MISSED_MSG0x0101)
1730 proto_tree_add_item(tree, hf_log_missed, tvb, 0, 0, ENC_NA0x00000000);
1731 else
1732 proto_tree_add_item(tree, hf_log_msg, tvb, 0, -1, ENC_ASCII0x00000000);
1733 }
1734}
1735
1736
1737/*
1738 * Dissect IrLAP
1739 */
1740static void dissect_irlap(tvbuff_t* tvb, packet_info* pinfo, proto_tree* root)
1741{
1742 int offset = 0;
1743 uint8_t circuit_id, c;
1744 bool_Bool is_response;
1745 char addr[9];
1746 proto_item* ti = NULL((void*)0);
1747 proto_tree* tree = NULL((void*)0);
1748 proto_tree* i_tree = NULL((void*)0);
1749 uint32_t saddr, daddr;
1750 uint8_t ca;
1751
1752 /* Make entries in Protocol column on summary display */
1753 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IrLAP");
1754
1755 /* Clear Info column */
1756 col_clear(pinfo->cinfo, COL_INFO);
1757
1758 /* set direction column */
1759 switch (pinfo->pseudo_header->irda.pkttype)
1760 {
1761 case IRDA_OUTGOING0x0004:
1762 col_set_str(pinfo->cinfo, COL_IF_DIR, "Out");
1763 break;
1764
1765 case IRDA_INCOMING0x0000:
1766 col_set_str(pinfo->cinfo, COL_IF_DIR, "In");
1767 break;
1768 }
1769
1770 /* decode values used for demuxing */
1771 circuit_id = tvb_get_uint8(tvb, 0);
1772
1773 /* initially set address columns to connection address */
1774 snprintf(addr, sizeof(addr)-1, "0x%02X", circuit_id >> 1);
1775 col_add_str(pinfo->cinfo, COL_DEF_SRC, addr);
1776 col_add_str(pinfo->cinfo, COL_DEF_DST, addr);
1777
1778 if (root)
1779 {
1780 proto_tree* a_tree;
1781 proto_item* addr_item;
1782
1783 /* create display subtree for the protocol */
1784 ti = proto_tree_add_item(root, proto_irlap, tvb, 0, -1, ENC_NA0x00000000);
1785 tree = proto_item_add_subtree(ti, ett_irlap);
1786
1787 /* create subtree for the address field */
1788 ti = proto_tree_add_item(tree, hf_lap_a, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1789 a_tree = proto_item_add_subtree(ti, ett_lap_a);
1790 proto_tree_add_item(a_tree, hf_lap_a_cr, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1791 addr_item = proto_tree_add_item(a_tree, hf_lap_a_address, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1792 switch (circuit_id & ~CMD_FRAME0x01)
1793 {
1794 case 0:
1795 proto_item_append_text(addr_item, " (NULL Address)");
1796 break;
1797 case 0xFE:
1798 proto_item_append_text(addr_item, " (Broadcast)");
1799 break;
1800 }
1801 }
1802 is_response = ((circuit_id & CMD_FRAME0x01) == 0);
1803 offset++;
1804
1805 /* process the control field */
1806 c = dissect_xdlc_control(tvb, offset, pinfo, tree, hf_lap_c,
1807 ett_lap_c, &irlap_cf_items, NULL((void*)0), lap_c_u_cmd_abbr_vals,
1808 lap_c_u_rsp_abbr_vals, is_response, false0, false0);
1809 offset++;
1810
1811 if ((c & XDLC_I_MASK0x01) == XDLC_I0x00) {
1812 /* I frame */
1813 proto_item_set_len(tree, offset);
1814 tvb = tvb_new_subset_remaining(tvb, offset);
1815 dissect_irlmp(tvb, pinfo, root, circuit_id);
1816 return;
1817 }
1818
1819 if ((c & XDLC_S_U_MASK0x03) == XDLC_U0x03) {
1820 /* U frame */
1821 switch (c & XDLC_U_MODIFIER_MASK0xEC)
1822 {
1823 case XDLC_SNRM0x80:
1824 if (root)
1825 {
1826 ti = proto_tree_add_item(tree, hf_lap_i, tvb, offset, -1, ENC_NA0x00000000);
1827 i_tree = proto_item_add_subtree(ti, ett_lap_i);
1828 }
1829
1830 saddr = tvb_get_letohl(tvb, offset);
1831 if (!is_response)
1832 {
1833 col_add_fstr(pinfo->cinfo, COL_DEF_SRC, "0x%08X", saddr);
1834 }
1835 if (root)
1836 proto_tree_add_uint(i_tree, hf_snrm_saddr, tvb, offset, 4, saddr);
1837 offset += 4;
1838
1839 daddr = tvb_get_letohl(tvb, offset);
1840 if (!is_response)
1841 {
1842 col_add_fstr(pinfo->cinfo, COL_DEF_DST, "0x%08X", daddr);
1843 }
1844 if (root)
1845 proto_tree_add_uint(i_tree, hf_snrm_daddr, tvb, offset, 4, daddr);
1846 offset += 4;
1847
1848 ca = tvb_get_uint8(tvb, offset);
1849 if (!is_response)
1850 {
1851 col_append_fstr(pinfo->cinfo, COL_INFO, ", ca=0x%02X",
1852 ca >> 1);
1853 }
1854 if (root)
1855 proto_tree_add_uint(i_tree, hf_snrm_ca, tvb, offset, 1, ca >> 1);
1856 offset++;
1857
1858 offset = dissect_negotiation(tvb, i_tree, offset);
1859 if (root)
1860 proto_item_set_end(ti, tvb, offset);
1861 break;
1862
1863 case IRDA_XID_CMD0x2c:
1864 tvb = tvb_new_subset_remaining(tvb, offset);
1865 dissect_xid(tvb, pinfo, root, tree, true1);
1866 return;
1867
1868 case XDLC_UA0x60:
1869 if (tvb_reported_length_remaining(tvb, offset) > 0)
1870 {
1871 if (root)
1872 {
1873 ti = proto_tree_add_item(tree, hf_lap_i, tvb, offset, -1, ENC_NA0x00000000);
1874 i_tree = proto_item_add_subtree(ti, ett_lap_i);
1875 }
1876
1877 saddr = tvb_get_letohl(tvb, offset);
1878 col_add_fstr(pinfo->cinfo, COL_DEF_SRC, "0x%08X", saddr);
1879 if (root)
1880 proto_tree_add_uint(i_tree, hf_ua_saddr, tvb, offset, 4, saddr);
1881 offset += 4;
1882
1883 daddr = tvb_get_letohl(tvb, offset);
1884 col_add_fstr(pinfo->cinfo, COL_DEF_DST, "0x%08X", daddr);
1885 if (root)
1886 proto_tree_add_uint(i_tree, hf_ua_daddr, tvb, offset, 4, daddr);
1887 offset += 4;
1888
1889 offset = dissect_negotiation(tvb, i_tree, offset);
1890 if (root)
1891 proto_item_set_end(ti, tvb, offset);
1892 }
1893 break;
1894
1895 case XDLC_XID0xAC:
1896 tvb = tvb_new_subset_remaining(tvb, offset);
1897 dissect_xid(tvb, pinfo, root, tree, false0);
1898 return;
1899 }
1900 }
1901
1902 /* If any bytes remain, send it to the generic data dissector */
1903 if (tvb_reported_length_remaining(tvb, offset) > 0)
1904 {
1905 tvb = tvb_new_subset_remaining(tvb, offset);
1906 call_data_dissector(tvb, pinfo, root);
1907 }
1908}
1909
1910
1911/*
1912 * Dissect IrDA protocol
1913 */
1914static int dissect_irda(tvbuff_t* tvb, packet_info* pinfo, proto_tree* root, void* data _U___attribute__((unused)))
1915{
1916 /* check if log message */
1917 if ((pinfo->pseudo_header->irda.pkttype & IRDA_CLASS_MASK0xFF00) == IRDA_CLASS_LOG0x0100)
1918 {
1919 dissect_log(tvb, pinfo, root);
1920 return tvb_captured_length(tvb);
1921 }
1922
1923
1924 dissect_irlap(tvb, pinfo, root);
1925 return tvb_captured_length(tvb);
1926}
1927
1928static int irda_addr_to_str(const address* addr, char *buf, int buf_len _U___attribute__((unused)))
1929{
1930 const uint8_t *addrdata = (const uint8_t *)addr->data;
1931
1932 uint32_to_str_buf(*addrdata, buf, buf_len);
1933 return (int)strlen(buf);
1934}
1935
1936static int irda_addr_str_len(const address* addr _U___attribute__((unused)))
1937{
1938 return 11; /* Leaves required space (10 bytes) for uint_to_str_back() */
1939}
1940
1941static const char* irda_col_filter_str(const address* addr _U___attribute__((unused)), bool_Bool is_src _U___attribute__((unused)))
1942{
1943 return "irlap.a";
1944}
1945
1946static int irda_addr_len(void)
1947{
1948 return 1;
1949}
1950
1951/*
1952 * Register the protocol with Wireshark
1953 * This format is required because a script is used to build the C function
1954 * that calls all the protocol registrations.
1955 */
1956void proto_register_irda(void)
1957{
1958 unsigned i;
1959
1960 /* Setup list of header fields */
1961 static hf_register_info hf_lap[] = {
1962 { &hf_lap_a,
1963 { "Address Field", "irlap.a",
1964 FT_UINT8, BASE_HEX, NULL((void*)0), 0,
1965 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1966 { &hf_lap_a_cr,
1967 { "C/R", "irlap.a.cr",
1968 FT_BOOLEAN, 8, TFS(&lap_cr_vals)((0 ? (const struct true_false_string*)0 : ((&lap_cr_vals
))))
, CMD_FRAME0x01,
1969 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1970 { &hf_lap_a_address,
1971 { "Address", "irlap.a.address",
1972 FT_UINT8, BASE_HEX, NULL((void*)0), ~CMD_FRAME0x01,
1973 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1974 { &hf_lap_c,
1975 { "Control Field", "irlap.c",
1976 FT_UINT8, BASE_HEX, NULL((void*)0), 0,
1977 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1978 { &hf_lap_c_nr,
1979 { "N(R)", "irlap.c.n_r",
1980 FT_UINT8, BASE_DEC, NULL((void*)0), XDLC_N_R_MASK0xE0,
1981 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1982 { &hf_lap_c_ns,
1983 { "N(S)", "irlap.c.n_s",
1984 FT_UINT8, BASE_DEC, NULL((void*)0), XDLC_N_S_MASK0x0E,
1985 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1986 { &hf_lap_c_p,
1987 { "Poll", "irlap.c.p",
1988 FT_BOOLEAN, 8, TFS(&set_notset)((0 ? (const struct true_false_string*)0 : ((&set_notset)
)))
, XDLC_P_F0x10,
1989 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1990 { &hf_lap_c_f,
1991 { "Final", "irlap.c.f",
1992 FT_BOOLEAN, 8, TFS(&set_notset)((0 ? (const struct true_false_string*)0 : ((&set_notset)
)))
, XDLC_P_F0x10,
1993 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1994 { &hf_lap_c_s,
1995 { "Supervisory frame type", "irlap.c.s_ftype",
1996 FT_UINT8, BASE_HEX, VALS(lap_c_s_vals)((0 ? (const struct _value_string*)0 : ((lap_c_s_vals)))), XDLC_S_FTYPE_MASK0x0C,
1997 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1998 { &hf_lap_c_u_cmd,
1999 { "Command", "irlap.c.u_modifier_cmd",
2000 FT_UINT8, BASE_HEX, VALS(lap_c_u_cmd_vals)((0 ? (const struct _value_string*)0 : ((lap_c_u_cmd_vals)))), XDLC_U_MODIFIER_MASK0xEC,
2001 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2002 { &hf_lap_c_u_rsp,
2003 { "Response", "irlap.c.u_modifier_resp",
2004 FT_UINT8, BASE_HEX, VALS(lap_c_u_rsp_vals)((0 ? (const struct _value_string*)0 : ((lap_c_u_rsp_vals)))), XDLC_U_MODIFIER_MASK0xEC,
2005 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2006 { &hf_lap_c_i,
2007 { "Frame Type", "irlap.c.ftype",
2008 FT_UINT8, BASE_HEX, VALS(lap_c_ftype_vals)((0 ? (const struct _value_string*)0 : ((lap_c_ftype_vals)))), XDLC_I_MASK0x01,
2009 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2010 { &hf_lap_c_s_u,
2011 { "Frame Type", "irlap.c.ftype",
2012 FT_UINT8, BASE_HEX, VALS(lap_c_ftype_vals)((0 ? (const struct _value_string*)0 : ((lap_c_ftype_vals)))), XDLC_S_U_MASK0x03,
2013 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2014 { &hf_lap_i,
2015 { "Information Field", "irlap.i",
2016 FT_NONE, BASE_NONE, NULL((void*)0), 0,
2017 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2018 { &hf_snrm_saddr,
2019 { "Source Device Address", "irlap.snrm.saddr",
2020 FT_UINT32, BASE_HEX, NULL((void*)0), 0,
2021 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2022 { &hf_snrm_daddr,
2023 { "Destination Device Address", "irlap.snrm.daddr",
2024 FT_UINT32, BASE_HEX, NULL((void*)0), 0,
2025 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2026 { &hf_snrm_ca,
2027 { "Connection Address", "irlap.snrm.ca",
2028 FT_UINT8, BASE_HEX, NULL((void*)0), 0,
2029 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2030 { &hf_negotiation_param,
2031 { "Negotiation Parameter", "irlap.negotiation",
2032 FT_NONE, BASE_NONE, NULL((void*)0), 0,
2033 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2034 { &hf_param_pi,
2035 { "Parameter Identifier", "irlap.pi",
2036 FT_UINT8, BASE_HEX, NULL((void*)0), 0,
2037 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2038 { &hf_param_pl,
2039 { "Parameter Length", "irlap.pl",
2040 FT_UINT8, BASE_HEX, NULL((void*)0), 0,
2041 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2042 { &hf_param_pv,
2043 { "Parameter Value", "irlap.pv",
2044 FT_BYTES, BASE_NONE, NULL((void*)0), 0,
2045 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2046 { &hf_ua_saddr,
2047 { "Source Device Address", "irlap.ua.saddr",
2048 FT_UINT32, BASE_HEX, NULL((void*)0), 0,
2049 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2050 { &hf_ua_daddr,
2051 { "Destination Device Address", "irlap.ua.daddr",
2052 FT_UINT32, BASE_HEX, NULL((void*)0), 0,
2053 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2054 { &hf_xid_ident,
2055 { "Format Identifier", "irlap.xid.fi",
2056 FT_UINT8, BASE_HEX, NULL((void*)0), 0,
2057 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2058 { &hf_xid_saddr,
2059 { "Source Device Address", "irlap.xid.saddr",
2060 FT_UINT32, BASE_HEX, NULL((void*)0), 0,
2061 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2062 { &hf_xid_daddr,
2063 { "Destination Device Address", "irlap.xid.daddr",
2064 FT_UINT32, BASE_HEX, NULL((void*)0), 0,
2065 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2066 { &hf_xid_flags,
2067 { "Discovery Flags", "irlap.xid.flags",
2068 FT_UINT8, BASE_HEX, NULL((void*)0), 0,
2069 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2070 { &hf_xid_s,
2071 { "Number of Slots", "irlap.xid.s",
2072 FT_UINT8, BASE_DEC, VALS(xid_slot_numbers)((0 ? (const struct _value_string*)0 : ((xid_slot_numbers)))), S_MASK0x03,
2073 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2074 { &hf_xid_conflict,
2075 { "Conflict", "irlap.xid.conflict",
2076 FT_BOOLEAN, 8, TFS(&set_notset)((0 ? (const struct true_false_string*)0 : ((&set_notset)
)))
, CONFLICT0x04,
2077 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2078 { &hf_xid_slotnr,
2079 { "Slot Number", "irlap.xid.slotnr",
2080 FT_UINT8, BASE_DEC, NULL((void*)0), 0,
2081 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2082 { &hf_xid_version,
2083 { "Version Number", "irlap.xid.version",
2084 FT_UINT8, BASE_HEX, NULL((void*)0), 0,
2085 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }}
2086 };
2087
2088 static hf_register_info hf_log[] = {
2089 { &hf_log_msg,
2090 { "Message", "log.msg",
2091 FT_STRING, BASE_NONE, NULL((void*)0), 0,
2092 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2093 { &hf_log_missed,
2094 { "WARNING: Missed one or more messages while capturing!", "log.missed",
2095 FT_NONE, BASE_NONE, NULL((void*)0), 0,
2096 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }}
2097 };
2098
2099 static hf_register_info hf_lmp[] = {
2100 { &hf_lmp_xid_hints,
2101 { "Service Hints", "irlmp.xid.hints",
2102 FT_BYTES, BASE_NONE, NULL((void*)0), 0,
2103 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2104 { &hf_lmp_xid_charset,
2105 { "Character Set", "irlmp.xid.charset",
2106 FT_UINT8, BASE_HEX, VALS(lmp_charset_vals)((0 ? (const struct _value_string*)0 : ((lmp_charset_vals)))), 0,
2107 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2108 { &hf_lmp_xid_name,
2109 { "Device Nickname", "irlmp.xid.name",
2110 FT_STRING, BASE_NONE, NULL((void*)0), 0,
2111 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2112 { &hf_lmp_xid_name_no_encoding,
2113 { "Device Nickname (unsupported character set)", "irlmp.xid.name.no_encoding",
2114 FT_BYTES, BASE_NONE, NULL((void*)0), 0,
2115 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2116 { &hf_lmp_dst,
2117 { "Destination", "irlmp.dst",
2118 FT_UINT8, BASE_HEX, NULL((void*)0), 0,
2119 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2120 { &hf_lmp_dst_control,
2121 { "Control Bit", "irlmp.dst.c",
2122 FT_BOOLEAN, 8, TFS(&set_notset)((0 ? (const struct true_false_string*)0 : ((&set_notset)
)))
, CONTROL_BIT0x80,
2123 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2124 { &hf_lmp_dst_lsap,
2125 { "Destination LSAP", "irlmp.dst.lsap",
2126 FT_UINT8, BASE_DEC, NULL((void*)0), ~CONTROL_BIT0x80,
2127 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2128 { &hf_lmp_src,
2129 { "Source", "irlmp.src",
2130 FT_UINT8, BASE_HEX, NULL((void*)0), 0,
2131 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2132 { &hf_lmp_src_r,
2133 { "reserved", "irlmp.src.r",
2134 FT_UINT8, BASE_DEC, NULL((void*)0), RESERVED_BIT0x80,
2135 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2136 { &hf_lmp_src_lsap,
2137 { "Source LSAP", "irlmp.src.lsap",
2138 FT_UINT8, BASE_DEC, NULL((void*)0), ~RESERVED_BIT0x80,
2139 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2140 { &hf_lmp_opcode,
2141 { "Opcode", "irlmp.opcode",
2142 FT_UINT8, BASE_HEX, VALS(lmp_opcode_vals)((0 ? (const struct _value_string*)0 : ((lmp_opcode_vals)))), 0x0,
2143 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2144 { &hf_lmp_rsvd,
2145 { "Reserved", "irlmp.rsvd",
2146 FT_UINT8, BASE_HEX, NULL((void*)0), 0x0,
2147 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2148 { &hf_lmp_reason,
2149 { "Reason", "irlmp.reason",
2150 FT_UINT8, BASE_HEX, VALS(lmp_reason_vals)((0 ? (const struct _value_string*)0 : ((lmp_reason_vals)))), 0x0,
2151 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2152 { &hf_lmp_mode,
2153 { "Mode", "irlmp.mode",
2154 FT_UINT8, BASE_HEX, VALS(lmp_mode_vals)((0 ? (const struct _value_string*)0 : ((lmp_mode_vals)))), 0x0,
2155 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2156 { &hf_lmp_status,
2157 { "Status", "irlmp.status",
2158 FT_UINT8, BASE_HEX, VALS(lmp_status_vals)((0 ? (const struct _value_string*)0 : ((lmp_status_vals)))), 0x0,
2159 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }}
2160 };
2161
2162 static hf_register_info hf_iap[] = {
2163 { &hf_iap_ctl,
2164 { "Control Field", "iap.ctl",
2165 FT_UINT8, BASE_HEX, NULL((void*)0), 0,
2166 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2167 { &hf_iap_ctl_lst,
2168 { "Last Frame", "iap.ctl.lst",
2169 FT_BOOLEAN, 8, TFS(&set_notset)((0 ? (const struct true_false_string*)0 : ((&set_notset)
)))
, IAP_LST0x80,
2170 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2171 { &hf_iap_ctl_ack,
2172 { "Acknowledge", "iap.ctl.ack",
2173 FT_BOOLEAN, 8, TFS(&set_notset)((0 ? (const struct true_false_string*)0 : ((&set_notset)
)))
, IAP_ACK0x40,
2174 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2175 { &hf_iap_ctl_opcode,
2176 { "Opcode", "iap.ctl.opcode",
2177 FT_UINT8, BASE_HEX, VALS(iap_opcode_vals)((0 ? (const struct _value_string*)0 : ((iap_opcode_vals)))), IAP_OP0x3F,
2178 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2179 { &hf_iap_class_name,
2180 { "Class Name", "iap.classname",
2181 FT_UINT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2182 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2183 { &hf_iap_attr_name,
2184 { "Attribute Name", "iap.attrname",
2185 FT_UINT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2186 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2187 { &hf_iap_return,
2188 { "Return", "iap.return",
2189 FT_UINT8, BASE_HEX, VALS(iap_return_vals)((0 ? (const struct _value_string*)0 : ((iap_return_vals)))), 0x0,
2190 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2191 { &hf_iap_list_len,
2192 { "List Length", "iap.listlen",
2193 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
2194 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2195 { &hf_iap_list_entry,
2196 { "List Entry", "iap.listentry",
2197 FT_NONE, BASE_NONE, NULL((void*)0), 0x0,
2198 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2199 { &hf_iap_obj_id,
2200 { "Object Identifier", "iap.objectid",
2201 FT_UINT16, BASE_HEX, NULL((void*)0), 0x0,
2202 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2203 { &hf_iap_attr_type,
2204 { "Type", "iap.attrtype",
2205 FT_UINT8, BASE_DEC, VALS(iap_attr_type_vals)((0 ? (const struct _value_string*)0 : ((iap_attr_type_vals))
))
, 0x0,
2206 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2207 { &hf_iap_int,
2208 { "Value", "iap.int",
2209 FT_INT32, BASE_DEC, NULL((void*)0), 0x0,
2210 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2211 { &hf_iap_seq_len,
2212 { "Sequence Length", "iap.seqlen",
2213 FT_UINT16, BASE_DEC, NULL((void*)0), 0x0,
2214 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2215 { &hf_iap_oct_seq,
2216 { "Sequence", "iap.octseq",
2217 FT_BYTES, BASE_NONE, NULL((void*)0), 0x0,
2218 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2219 { &hf_iap_char_set,
2220 { "Character Set", "iap.charset",
2221 FT_UINT8, BASE_HEX, NULL((void*)0), 0x0,
2222 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2223 { &hf_iap_string,
2224 { "String", "iap.string",
2225 FT_UINT_STRING, BASE_NONE, NULL((void*)0), 0x0,
2226 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2227 { &hf_iap_invaloctet,
2228 { "Malformed IAP result: \"", "iap.invaloctet",
2229 FT_NONE, BASE_NONE, NULL((void*)0), 0,
2230 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2231 { &hf_iap_invallsap,
2232 { "Malformed IAP result: \"", "iap.invallsap",
2233 FT_NONE, BASE_NONE, NULL((void*)0), 0,
2234 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }}
2235 };
2236
2237 static hf_register_info hf_ttp[] = {
2238 { &hf_ttp_p,
2239 { "Parameter Bit", "ttp.p",
2240 FT_BOOLEAN, 8, TFS(&set_notset)((0 ? (const struct true_false_string*)0 : ((&set_notset)
)))
, TTP_PARAMETERS0x80,
2241 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2242 { &hf_ttp_icredit,
2243 { "Initial Credit", "ttp.icredit",
2244 FT_UINT8, BASE_DEC, NULL((void*)0), ~TTP_PARAMETERS0x80,
2245 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2246 { &hf_ttp_m,
2247 { "More Bit", "ttp.m",
2248 FT_BOOLEAN, 8, TFS(&set_notset)((0 ? (const struct true_false_string*)0 : ((&set_notset)
)))
, TTP_MORE0x80,
2249 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
2250 { &hf_ttp_dcredit,
2251 { "Delta Credit", "ttp.dcredit",
2252 FT_UINT8, BASE_DEC, NULL((void*)0), ~TTP_MORE0x80,
2253 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }}
2254 };
2255
2256 /* Setup protocol subtree arrays */
2257 static int* ett[] = {
2258 &ett_irlap,
2259 &ett_lap_a,
2260 &ett_lap_c,
2261 &ett_lap_i,
2262 &ett_xid_flags,
2263 &ett_log,
2264 &ett_irlmp,
2265 &ett_lmp_dst,
2266 &ett_lmp_src,
2267 &ett_iap,
2268 &ett_iap_ctl,
2269 &ett_ttp
2270 };
2271
2272 int* ett_p[MAX_PARAMETERS32];
2273 int* ett_iap_e[MAX_IAP_ENTRIES32];
2274
2275
2276 /* Register protocol names and descriptions */
2277 proto_irlap = proto_register_protocol("IrDA Link Access Protocol", "IrLAP", "irlap");
2278 proto_log = proto_register_protocol("Log Message", "Log", "log");
2279 proto_irlmp = proto_register_protocol("IrDA Link Management Protocol", "IrLMP", "irlmp");
2280 proto_iap = proto_register_protocol("Information Access Protocol", "IAP", "iap");
2281 proto_ttp = proto_register_protocol("Tiny Transport Protocol", "TTP", "ttp");
2282
2283 /* Register the dissector */
2284 irda_handle = register_dissector("irda", dissect_irda, proto_irlap);
2285
2286 /* Required function calls to register the header fields */
2287 proto_register_field_array(proto_irlap, hf_lap, array_length(hf_lap)(sizeof (hf_lap) / sizeof (hf_lap)[0]));
2288 proto_register_field_array(proto_log, hf_log, array_length(hf_log)(sizeof (hf_log) / sizeof (hf_log)[0]));
2289 proto_register_field_array(proto_irlmp, hf_lmp, array_length(hf_lmp)(sizeof (hf_lmp) / sizeof (hf_lmp)[0]));
2290 proto_register_field_array(proto_iap, hf_iap, array_length(hf_iap)(sizeof (hf_iap) / sizeof (hf_iap)[0]));
2291 proto_register_field_array(proto_ttp, hf_ttp, array_length(hf_ttp)(sizeof (hf_ttp) / sizeof (hf_ttp)[0]));
2292
2293 /* Register subtrees */
2294 proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
2295 for (i = 0; i < MAX_PARAMETERS32; i++)
2296 {
2297 ett_p[i] = &ett_param[i];
2298 }
2299 proto_register_subtree_array(ett_p, MAX_PARAMETERS32);
2300 for (i = 0; i < MAX_IAP_ENTRIES32; i++)
2301 {
2302 ett_iap_e[i] = &ett_iap_entry[i];
2303 }
2304 proto_register_subtree_array(ett_iap_e, MAX_IAP_ENTRIES32);
2305
2306 irda_address_type = address_type_dissector_register("AT_IRDA", "IRDA Address", irda_addr_to_str, irda_addr_str_len, NULL((void*)0), irda_col_filter_str, irda_addr_len, NULL((void*)0), NULL((void*)0));
2307}
2308
2309
2310/* If this dissector uses sub-dissector registration add a registration routine.
2311 This format is required because a script is used to find these routines and
2312 create the code that calls these routines.
2313*/
2314
2315void proto_reg_handoff_irda(void)
2316{
2317 dissector_add_uint("wtap_encap", WTAP_ENCAP_IRDA44, irda_handle);
2318 dissector_add_uint("sll.ltype", LINUX_SLL_P_IRDA_LAP0x0017, irda_handle);
2319}
2320
2321/*
2322 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2323 *
2324 * Local variables:
2325 * c-basic-offset: 4
2326 * tab-width: 8
2327 * indent-tabs-mode: nil
2328 * End:
2329 *
2330 * vi: set shiftwidth=4 tabstop=8 expandtab:
2331 * :indentSize=4:tabSize=8:noTabs=true:
2332 */