Grab-bag of dead initializers and two actual bugs.
[metze/wireshark/wip.git] / asn1 / atn-cpdlc / packet-atn-cpdlc-template.c
1 /* c-basic-offset: 2; tab-width: 2; indent-tabs-mode: t
2  * vi: set shiftwidth=2 tabstop=2 noexpandtab:
3  * :indentSize=2:tabSize=2:noTabs=false:
4  */
5
6 /* packet-atn-cpdlc-template.c
7  * By Mathias Guettler <guettler@web.de>
8  * Copyright 2013
9  *
10  * Routines for ATN Cpdlcc protocol packet disassembly
11
12  * details see:
13  * http://en.wikipedia.org/wiki/CPDLC
14  * http://members.optusnet.com.au/~cjr/introduction.htm
15
16  * standards:
17  * http://legacy.icao.int/anb/panels/acp/repository.cfm
18
19  * note:
20  * We are dealing with ATN/CPDLC aka ICAO Doc 9705 Ed2 here
21  * (CPDLC may also be transmitted via ACARS/AOA aka "FANS-1/A ").
22
23  *
24  * Wireshark - Network traffic analyzer
25  * By Gerald Combs <gerald@wireshark.org>
26  * Copyright 1998 Gerald Combs
27  *
28  * This program is free software; you can redistribute it and/or
29  * modify it under the terms of the GNU General Public License
30  * as published by the Free Software Foundation; either version 2
31  * of the License, or (at your option) any later version.
32  *
33  * This program is distributed in the hope that it will be useful,
34  * but WITHOUT ANY WARRANTY; without even the implied warranty of
35  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
36  * GNU General Public License for more details.
37  *
38  * You should have received a copy of the GNU General Public License
39  * along with this program; if not, write to the Free Software
40  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
41  */
42
43 /*
44  developper comments:
45         Which CPDLC messages are supported ?
46                 Protected Mode CPDLC (AeQualifier 22) and Plain Old CPDLC (AeQualifier 2)
47                 The dissector has been tested with ICAO doc9705 Edition2 compliant traffic.
48 */
49
50 #include "config.h"
51
52 #include <glib.h>
53 #include <epan/packet.h>
54 #include <epan/exceptions.h>
55 #include <epan/conversation.h>
56 #include <epan/dissectors/packet-ber.h>
57 #include <epan/dissectors/packet-per.h>
58
59 #include <stdio.h>
60 #include <string.h>
61
62 #include "packet-atn-ulcs.h"
63
64 #define ATN_CPDLC_PROTO "ICAO Doc9705 CPDLC"
65
66 void proto_register_atn_cpdlc(void);
67 void proto_reg_handoff_atn_cpdlc(void);
68
69 static const char *object_identifier_id;
70
71 /* forward declarations */
72 static void dissect_GroundPDUs_PDU(
73                 tvbuff_t *tvb _U_,
74                 packet_info *pinfo _U_,
75                 proto_tree *tree _U_);
76 static void dissect_AircraftPDUs_PDU(
77                 tvbuff_t *tvb _U_,
78                 packet_info *pinfo _U_,
79                 proto_tree *tree _U_);
80 static void dissect_ProtectedGroundPDUs_PDU(
81                 tvbuff_t *tvb _U_,
82                 packet_info *pinfo _U_,
83                 proto_tree *tree _U_);
84 static void dissect_ProtectedAircraftPDUs_PDU(
85                 tvbuff_t *tvb _U_,
86                 packet_info *pinfo _U_,
87                 proto_tree *tree _U_);
88
89 #include "packet-atn-cpdlc-hf.c"
90
91 #include "packet-atn-cpdlc-ett.c"
92 static gint ett_atn_cpdlc = -1;
93
94 #include "packet-atn-cpdlc-fn.c"
95
96 /* Wireshark ID of CPDLC protocol */
97 static int proto_atn_cpdlc = -1;
98
99
100 static int
101 dissect_atn_cpdlc(
102                 tvbuff_t *tvb,
103                 packet_info *pinfo,
104                 proto_tree *tree,
105                 void *data _U_)
106 {
107                 /* note: */
108                 /* there are two co-existing applications of CPDLC: */
109                 /* "plain old" (ae-qualifier 2) and */
110                 /* "protected mode" (ae-qualifier 22) CPDLC. */
111                 /* "protected mode" was introduced to cope with a */
112                 /* safety issue in which a message would sent to the wrong aircraft. */
113
114                 /* note:*/
115                 /* The protection is an additional checksum and covers the message content, */
116                 /* the 24-bit address of the aircraft, the current flight id and */
117                 /* the current ground facility so that an aircraft would be able to reject */
118                 /* messages which are unexpected (i.e. messages to another flight or */
119                 /* messages from the wrong center). */
120
121                 /*note:*/
122                 /* although "plain old" CPDLC is more or less deprecated */
123                 /* many aircraft cannot perform  */
124                 /* "protected mode" for this largely depends on */
125                 /* upgraded avionics packages */
126
127                 /*note:*/
128                 /* The use of CPDLC is *optional* as the pilot  */
129                 /* may always use a voice radio channel to talk to the controller.*/
130
131                 proto_item *ti = NULL;
132                 proto_tree *atn_cpdlc_tree = NULL;
133                 atn_conversation_t *atn_cv = NULL;
134
135                 /* note: */
136                 /* we need the ae qualifier stored within the conversation */
137                 /* to decode "plain old cpdlc" or  */
138                 /* "protected mode cpdlc correctly " */
139
140                 /* DT: dstref present, srcref is always zero */
141                 if((pinfo->clnp_dstref) && (!pinfo->clnp_srcref)){
142                                 atn_cv = find_atn_conversation(
143                                                 &pinfo->dst,
144                                                 pinfo->clnp_dstref,
145                                                 &pinfo->src );
146                 }
147                 /* CR: srcref present, dstref is always zero */
148                 if((!pinfo->clnp_dstref) && (pinfo->clnp_srcref)){
149                                 atn_cv = find_atn_conversation(
150                                                 &pinfo->src,
151                                                 pinfo->clnp_srcref,
152                                                 &pinfo->dst );
153                 }
154                 /* CC: srcref and dstref present, always use src/srcref & dst */
155                 if((pinfo->clnp_dstref) && (pinfo->clnp_srcref)){
156                                 atn_cv = find_atn_conversation(
157                                                 &pinfo->src,
158                                                 pinfo->clnp_srcref,
159                                                 &pinfo->dst );
160                 }
161
162                 if(!atn_cv){ /* atn conversation not found */
163                         return 0; }
164
165                 ti = proto_tree_add_text(
166                                 tree,
167                                 tvb,
168                                 0,
169                                 tvb_reported_length_remaining(tvb, 0) ,
170                                 ATN_CPDLC_PROTO );
171
172                 atn_cpdlc_tree = proto_item_add_subtree(
173                                 ti,
174                                 ett_atn_cpdlc);
175
176                 switch(atn_cv->ae_qualifier){
177                                 case  pmcpdlc:
178                                                 if( check_heur_msg_type(pinfo) == um ) {
179                                                                 /* uplink PDU's = Ground PDU's */
180                                                                 dissect_ProtectedGroundPDUs_PDU(
181                                                                                 tvb,
182                                                                                 pinfo,
183                                                                                 atn_cpdlc_tree);
184                                                 }else {  /* downlink PDU's = Aircraft PDU's */
185                                                                 dissect_ProtectedAircraftPDUs_PDU(
186                                                                                 tvb,
187                                                                                 pinfo,
188                                                                         atn_cpdlc_tree);
189                                                 }
190                                                 break;
191                                 case cpdlc:
192                                                 if( check_heur_msg_type(pinfo) == um ) {
193                                                                 /* uplink PDU's = Ground PDU's */
194                                                                 dissect_GroundPDUs_PDU(
195                                                                                 tvb,
196                                                                                 pinfo,
197                                                                                 atn_cpdlc_tree);
198                                                 }else {  /* downlink PDU's = Aircraft PDU's */
199                                                                 dissect_AircraftPDUs_PDU(
200                                                                                 tvb,
201                                                                                 pinfo,
202                                                                                 atn_cpdlc_tree);
203                                                 }
204                                                 break;
205                                 default:
206                                                 break;
207                 }
208                 return tvb_reported_length_remaining(tvb, 0);
209 }
210
211 static gboolean
212 dissect_atn_cpdlc_heur(
213                 tvbuff_t *tvb,
214                 packet_info *pinfo,
215                 proto_tree *tree,
216                 void *data _U_)
217 {
218                 atn_conversation_t *atn_cv = NULL;
219                 volatile gboolean is_atn_cpdlc = FALSE;
220                 volatile gboolean is_pm = FALSE;
221                 int type;
222
223                 type = check_heur_msg_type(pinfo);
224
225                 switch(type){
226                         case um:
227                                         TRY {
228                                                 dissect_ProtectedGroundPDUs_PDU(tvb, pinfo, NULL);
229                                                 is_atn_cpdlc = TRUE;
230                                                 is_pm = TRUE;
231                                                 break;}
232                                         CATCH_ALL{
233                                                 is_atn_cpdlc = FALSE;
234                                                 is_pm = FALSE;}
235                                         ENDTRY;
236                                         TRY {
237                         dissect_GroundPDUs_PDU(tvb, pinfo, NULL);
238                                                 is_pm = FALSE;
239                                                 is_atn_cpdlc = TRUE;
240                                                 break;}
241                                         CATCH_ALL{
242                                                 is_atn_cpdlc = FALSE;
243                                                 is_pm = FALSE;}
244                                         ENDTRY;
245                                 break;
246                 case dm:
247                                         TRY {
248                                                 dissect_ProtectedAircraftPDUs_PDU(tvb, pinfo, NULL);
249                                                 is_atn_cpdlc = TRUE;
250                                                 is_pm = TRUE;
251                                                 break;}
252                                         CATCH_ALL {
253                                                 is_atn_cpdlc = FALSE;
254                                                 is_pm = FALSE; }
255                                         ENDTRY;
256                                         TRY{
257                                                 dissect_AircraftPDUs_PDU(tvb, pinfo, NULL);
258                                                 is_atn_cpdlc = TRUE;
259                                                 is_pm = FALSE;
260                                                 break;}
261                                         CATCH_ALL{
262                                                 is_atn_cpdlc = FALSE;
263                                                 is_pm = FALSE;}
264                                         ENDTRY;
265                         break;
266                 default:
267                         break;
268         }
269
270         if(is_atn_cpdlc){
271                 /* note: */
272                 /* all subsequent PDU's belonging to this conversation */
273                 /* are considered CPDLC */
274                 /* if the first CPDLC PDU has been decoded succesfully */
275                 /* (This is done in "atn-ulcs" by using "call_dissector_with_data()") */
276
277                 /* DT: dstref present, srcref is always zero */
278                 if((pinfo->clnp_dstref) && (!pinfo->clnp_srcref)){
279                                 atn_cv = find_atn_conversation(&pinfo->dst,
280                                                                                                         pinfo->clnp_dstref,
281                                                                                                         &pinfo->src );
282                 }
283                 /* CR: srcref present, dstref is always zero */
284                 if((!pinfo->clnp_dstref) && (pinfo->clnp_srcref)){
285                                 atn_cv = find_atn_conversation(&pinfo->src,
286                                                                                                         pinfo->clnp_srcref,
287                                                                                                         &pinfo->dst );
288                 }
289                 /* CC: srcref and dstref present, always use src/srcref & dst */
290                 if((pinfo->clnp_dstref) && (pinfo->clnp_srcref)){
291                                 atn_cv = find_atn_conversation(&pinfo->src,
292                                                                                                         pinfo->clnp_srcref,
293                                                                                                         &pinfo->dst );
294                 }
295
296                 if(atn_cv){ /* atn conversation found */
297                         if(is_pm == TRUE) {
298                                 atn_cv->ae_qualifier =  pmcpdlc; }
299                         else {
300                                 atn_cv->ae_qualifier =  cpdlc; }
301                         dissect_atn_cpdlc(tvb, pinfo, tree, NULL);
302                 }
303         }else { /* there should *always* be an atn conversation */
304                 is_atn_cpdlc = FALSE;
305         }
306
307         return is_atn_cpdlc;
308 }
309
310
311
312 void proto_register_atn_cpdlc (void)
313 {
314     static hf_register_info hf_atn_cpdlc[] = {
315                                 #include "packet-atn-cpdlc-hfarr.c"
316                         };
317
318                 static gint *ett[] = {
319                                 #include "packet-atn-cpdlc-ettarr.c"
320                                 &ett_atn_cpdlc
321                 };
322
323                 /* register CPDLC */
324                 proto_atn_cpdlc = proto_register_protocol(
325                                 ATN_CPDLC_PROTO ,
326                                 "ATN-CPDLC",
327                                 "atn-cpdlc");
328
329                 proto_register_field_array(
330                                 proto_atn_cpdlc,
331                                 hf_atn_cpdlc,
332                                 array_length(hf_atn_cpdlc));
333
334                 proto_register_subtree_array(
335                                 ett,
336                                 array_length(ett));
337
338                 new_register_dissector(
339                                 "atn-cpdlc",
340                                 dissect_atn_cpdlc,
341                                 proto_atn_cpdlc);
342 }
343
344 void proto_reg_handoff_atn_cpdlc(void)
345 {
346                 /* add session dissector to atn dissector list dissector list*/
347                 heur_dissector_add(
348                                 "atn-ulcs",
349                                 dissect_atn_cpdlc_heur,
350                                 proto_atn_cpdlc);
351 }
352
353
354 /*
355  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
356  *
357  * Local variables:
358  * c-basic-offset: 2
359  * tab-width: 2
360  * indent-tabs-mode: t
361  * End:
362  *
363  * vi: set shiftwidth=2 tabstop=2 noexpandtab:
364  * :indentSize=2:tabSize=2:noTabs=false:
365  */