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.
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 /* NOTE: This should be rewritten to be more in line with how packet-uts.c is
27 * written so that there are filterable fields available for IPARS too.
33 #include <epan/packet.h>
34 #include <epan/wmem/wmem.h>
36 static int proto_ipars
= -1;
37 static guint8 ipars_eomtype
= G_MAXUINT8
;
38 static gint ett_ipars
= -1;
48 #define MAX_EOM_MSG_SIZE (16) /* max size of an EOMx indicator string */
51 dissect_ipars(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
53 proto_tree
*ipars_tree
= NULL
;
56 guint8 ia
= 0, ta
= 0, cmd
= 0, la
= 0;
61 eom_msg
= (gchar
*)wmem_alloc(wmem_packet_scope(), MAX_EOM_MSG_SIZE
);
64 col_clear(pinfo
->cinfo
, COL_INFO
);
66 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "IPARS");
68 if (tvb_length_remaining(tvb
, 0) >= 2 ) {
69 ia
= tvb_get_guint8(tvb
, 0) & 0x3f;
70 ta
= tvb_get_guint8(tvb
, 1) & 0x3f;
71 if (ia
== S1
&& ta
== S2
) { /* if the first two bytes are S1/S2 skip over them */
75 if (tvb_length_remaining(tvb
, offset
) >= 1) ia
= tvb_get_guint8(tvb
, offset
+ 0);
76 if (tvb_length_remaining(tvb
, offset
) >= 2) ta
= tvb_get_guint8(tvb
, offset
+ 1);
78 if (ia
== 0x83 || ia
== 0x43 || ia
== GA
) { /* if it's an FPGA or 'corresponsdance code' 'go ahead'... */
79 if (tvb_length_remaining(tvb
, offset
) > 2) { /* if the msg is long, it must have been a 'poll' */
80 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Poll IA: %2.2X", ta
);
81 } else { /* if it's short, then it was a 'no traffic' response */
82 if (tvb_length_remaining(tvb
, offset
) >= 2 ) {
83 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "GoAhead NextIA (0x%2.2X)", ta
);
85 col_set_str(pinfo
->cinfo
, COL_INFO
, "GoAhead NextIA");
88 } else { /* if it's not a 'go ahead'... it must be some kind of data message */
92 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Reset IA: %2.2X", ia
); /* the TA character was the 'reset' command */
94 if (tvb_length_remaining(tvb
, offset
) >= 3) cmd
= tvb_get_guint8(tvb
, offset
+ 2) & 0x3f; /* get the first two bytes of the data message */
95 if (tvb_length_remaining(tvb
, offset
) >= 4) la
= tvb_get_guint8(tvb
, offset
+ 3) & 0x3f;
96 if (cmd
== 0x1f && la
== 0x38) {
97 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Please Resend - IA: %2.2X TA: %2.2X", ia
, ta
); /* light the resend indicator */
98 } else if (cmd
== 0x2a && la
== 0x05) {
99 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Unsolicited Msg Indicator - IA: %2.2X TA: %2.2X", ia
, ta
); /* light the unsolicited msg indicator */
101 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 */
106 bytes
= tvb_length_remaining(tvb
, 0);
108 ia
= tvb_get_guint8(tvb
, 0) & 0x3f;
110 ti
= proto_tree_add_protocol_format(tree
, proto_ipars
, tvb
, 0, -1, "Ipars");
111 ipars_tree
= proto_item_add_subtree(ti
, ett_ipars
);
114 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, tvb
, 0, 1, "GoAhead Next IA");
115 col_set_str(pinfo
->cinfo
, COL_INFO
, "GoAhead");
117 } else if (ia
!= S1
) {
118 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, tvb
,
120 bytes
, "Unknown format - Data (%d byte%s)", bytes
,
121 plurality(bytes
, "", "s"));
124 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, tvb
, 0, 1, "S1");
125 ia
= tvb_get_guint8(tvb
, 1) & 0x3f;
127 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, tvb
,
129 bytes
, "Unknown format - Data (%d byte%s)", bytes
,
130 plurality(bytes
, "", "s"));
133 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, tvb
, 1, 1, "S2");
134 ia
= tvb_get_guint8(tvb
, 2) & 0x3f;
136 ia
= tvb_get_guint8(tvb
, 3) & 0x3f;
137 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, tvb
, 2, 2, "GoAhead IA: %2.2X", ia
);
138 ipars_eomtype
= tvb_get_guint8(tvb
, 4) & 0x3f;
139 switch (ipars_eomtype
) {
140 case EOMc
: g_snprintf(eom_msg
, MAX_EOM_MSG_SIZE
, "EOMc"); break;
141 case EOMi
: g_snprintf(eom_msg
, MAX_EOM_MSG_SIZE
, "EOMi"); break;
142 case EOMu
: g_snprintf(eom_msg
, MAX_EOM_MSG_SIZE
, "EOMu"); break;
143 case EOMpb
: g_snprintf(eom_msg
, MAX_EOM_MSG_SIZE
, "EOMpb"); break;
144 default: g_snprintf(eom_msg
, MAX_EOM_MSG_SIZE
, "Unknown EOM type (0x%2.2X)", ia
); break;
146 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, tvb
, 4, 1, "%s", eom_msg
);
147 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, tvb
, 5, 1, "Good BCC");
149 next_tvb
= tvb_new_subset_remaining(tvb
, 3);
150 proto_tree_add_protocol_format(ipars_tree
, proto_ipars
, next_tvb
,
152 bytes
, "Data (%d byte%s)", bytes
,
153 plurality(bytes
, "", "s"));
162 proto_register_ipars(void)
164 static gint
*ett
[] = {
168 proto_ipars
= proto_register_protocol("International Passenger Airline Reservation System", "IPARS", "ipars");
169 proto_register_subtree_array(ett
, array_length(ett
));
171 register_dissector("ipars", dissect_ipars
, proto_ipars
);
175 * Editor modelines - http://www.wireshark.org/tools/modelines.html
180 * indent-tabs-mode: nil
183 * vi: set shiftwidth=4 tabstop=4 expandtab:
184 * :indentSize=4:tabSize=8:noTabs=true: