2 * Routines for IPARS/ALC (International Passenger Airline Reservation System/Airline Link Control) WAN protocol dissection
3 * Copyright 2007, Fulko Hew, SITA INC Canada, Inc.
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 /* NOTE: This should be rewritten to be more in line with how packet-uts.c is
13 * written so that there are filterable fields available for IPARS too.
18 #include <epan/packet.h>
19 #include <wsutil/str_util.h>
20 void proto_register_ipars(void);
22 static int proto_ipars
;
33 #define MAX_EOM_MSG_SIZE (24) /* max size of an EOMx indicator string */
36 dissect_ipars(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
39 uint8_t ia
= 0, ta
= 0, cmd
= 0, la
= 0;
43 uint8_t ipars_eomtype
;
45 eom_msg
= (char *)wmem_alloc(pinfo
->pool
, MAX_EOM_MSG_SIZE
);
48 col_clear(pinfo
->cinfo
, COL_INFO
);
50 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "IPARS");
52 if (tvb_captured_length_remaining(tvb
, 0) >= 2 ) {
53 ia
= tvb_get_uint8(tvb
, 0) & 0x3f;
54 ta
= tvb_get_uint8(tvb
, 1) & 0x3f;
55 if (ia
== S1
&& ta
== S2
) { /* if the first two bytes are S1/S2 skip over them */
59 if (tvb_captured_length_remaining(tvb
, offset
) >= 1) ia
= tvb_get_uint8(tvb
, offset
+ 0);
60 if (tvb_captured_length_remaining(tvb
, offset
) >= 2) ta
= tvb_get_uint8(tvb
, offset
+ 1);
62 if (ia
== 0x83 || ia
== 0x43 || ia
== GA
) { /* if it's an FPGA or 'corresponsdance code' 'go ahead'... */
63 if (tvb_captured_length_remaining(tvb
, offset
) > 2) { /* if the msg is long, it must have been a 'poll' */
64 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Poll IA: %2.2X", ta
);
65 } else { /* if it's short, then it was a 'no traffic' response */
66 if (tvb_captured_length_remaining(tvb
, offset
) >= 2 ) {
67 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "GoAhead NextIA (0x%2.2X)", ta
);
69 col_set_str(pinfo
->cinfo
, COL_INFO
, "GoAhead NextIA");
72 } else { /* if it's not a 'go ahead'... it must be some kind of data message */
76 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Reset IA: %2.2X", ia
); /* the TA character was the 'reset' command */
78 if (tvb_captured_length_remaining(tvb
, offset
) >= 3) cmd
= tvb_get_uint8(tvb
, offset
+ 2) & 0x3f; /* get the first two bytes of the data message */
79 if (tvb_captured_length_remaining(tvb
, offset
) >= 4) la
= tvb_get_uint8(tvb
, offset
+ 3) & 0x3f;
80 if (cmd
== 0x1f && la
== 0x38) {
81 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Please Resend - IA: %2.2X TA: %2.2X", ia
, ta
); /* light the resend indicator */
82 } else if (cmd
== 0x2a && la
== 0x05) {
83 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Unsolicited Msg Indicator - IA: %2.2X TA: %2.2X", ia
, ta
); /* light the unsolicited msg indicator */
85 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Data Msg - IA: %2.2X TA: %2.2X", ia
, ta
); /* it was a data message (display or printer */
89 bytes
= tvb_captured_length_remaining(tvb
, 0);
91 proto_tree
*ipars_tree
;
94 ia
= tvb_get_uint8(tvb
, 0) & 0x3f;
96 ti
= proto_tree_add_protocol_format(tree
, proto_ipars
, tvb
, 0, -1, "Ipars");
97 ipars_tree
= proto_item_add_subtree(ti
, ett_ipars
);
100 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, tvb
, 0, 1, "GoAhead Next IA");
101 col_set_str(pinfo
->cinfo
, COL_INFO
, "GoAhead");
102 return tvb_captured_length(tvb
);
103 } else if (ia
!= S1
) {
104 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, tvb
,
106 bytes
, "Unknown format - Data (%d byte%s)", bytes
,
107 plurality(bytes
, "", "s"));
108 return tvb_captured_length(tvb
);
110 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, tvb
, 0, 1, "S1");
111 ia
= tvb_get_uint8(tvb
, 1) & 0x3f;
113 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, tvb
,
115 bytes
, "Unknown format - Data (%d byte%s)", bytes
,
116 plurality(bytes
, "", "s"));
117 return tvb_captured_length(tvb
);
119 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, tvb
, 1, 1, "S2");
120 ia
= tvb_get_uint8(tvb
, 2) & 0x3f;
122 ia
= tvb_get_uint8(tvb
, 3) & 0x3f;
123 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, tvb
, 2, 2, "GoAhead IA: %2.2X", ia
);
124 ipars_eomtype
= tvb_get_uint8(tvb
, 4) & 0x3f;
125 switch (ipars_eomtype
) {
126 case EOMc
: snprintf(eom_msg
, MAX_EOM_MSG_SIZE
, "EOMc"); break;
127 case EOMi
: snprintf(eom_msg
, MAX_EOM_MSG_SIZE
, "EOMi"); break;
128 case EOMu
: snprintf(eom_msg
, MAX_EOM_MSG_SIZE
, "EOMu"); break;
129 case EOMpb
: snprintf(eom_msg
, MAX_EOM_MSG_SIZE
, "EOMpb"); break;
130 default: snprintf(eom_msg
, MAX_EOM_MSG_SIZE
, "Unknown EOM type (0x%2.2X)", ia
); break;
132 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, tvb
, 4, 1, "%s", eom_msg
);
133 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, tvb
, 5, 1, "Good BCC");
135 next_tvb
= tvb_new_subset_remaining(tvb
, 3);
136 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, next_tvb
,
138 bytes
, "Data (%d byte%s)", bytes
,
139 plurality(bytes
, "", "s"));
140 return tvb_captured_length(tvb
);
143 return tvb_captured_length(tvb
);
147 proto_register_ipars(void)
149 static int *ett
[] = {
153 proto_ipars
= proto_register_protocol("International Passenger Airline Reservation System", "IPARS", "ipars");
154 proto_register_subtree_array(ett
, array_length(ett
));
156 register_dissector("ipars", dissect_ipars
, proto_ipars
);
160 * Editor modelines - https://www.wireshark.org/tools/modelines.html
165 * indent-tabs-mode: nil
168 * vi: set shiftwidth=4 tabstop=8 expandtab:
169 * :indentSize=4:tabSize=8:noTabs=true: