ec3b31ebf864ceb0b574e1df764be078ad363742
[obnox/wireshark/wip.git] / epan / dissectors / packet-simulcrypt.c
1 /* packet-simulcrypt.c
2  * Simulcrypt protocol interface as defined in ETSI TS 103.197 v 1.5.1
3  *
4  * ECMG <-> SCS support
5  * David Castleford, Orange Labs / France Telecom R&D
6  * Oct 2008
7  *
8  * EMMG <-> MUX support and generic interface support
9  * Copyright 2009, Stig Bjorlykke <stig@bjorlykke.org>
10  *
11  * $Id$
12  *
13  * Wireshark - Network traffic analyzer
14  * By Gerald Combs <gerald@wireshark.org>
15  * Copyright 1998 Gerald Combs
16  *
17  * This program is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU General Public License
19  * as published by the Free Software Foundation; either version 2
20  * of the License, or (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
30  */
31  
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include <glib.h>
37 #include <epan/packet.h>
38 #include <epan/dissectors/packet-tcp.h>
39 #include <epan/prefs.h>
40
41 #define PROTO_TAG_SIMULCRYPT            "SIMULCRYPT"
42 #define CA_SYSTEM_ID_MIKEY              0x9999  /* CA_system_ID corresponding to MIKEY ECM */
43 #define CA_SYSTEM_ID_MIKEY_PROTO        "mikey" /* Protocol name to be used to "decode as" ECMs with CA_SYSTEM_ID_MIKEY */
44
45 /* Tecm_interpretation links ca_system_id to ecmg port and protocol name for dissection of ecm_datagram in ECM_Response message
46 * Currently size is 1 as only have MIKEY protocol but could add extra protocols
47 * could add option in preferences for new ca_system_id for new protocol for example
48 */
49 typedef struct Tecm_interpretation
50 {
51         int ca_system_id;
52         char *protocol_name;
53         dissector_handle_t protocol_handle;
54         guint ecmg_port;
55 } ecm_interpretation;
56
57 #define ECM_MIKEY_INDEX 0  /* must agree with tab_ecm_inter initialization */
58
59 static ecm_interpretation tab_ecm_inter[]={
60         {CA_SYSTEM_ID_MIKEY, CA_SYSTEM_ID_MIKEY_PROTO, NULL, -1}
61 };
62
63 #define ECM_INTERPRETATION_SIZE (sizeof(tab_ecm_inter)/sizeof(ecm_interpretation))
64
65 static void  dissect_simulcrypt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
66 static guint get_simulcrypt_message_len(packet_info *pinfo, tvbuff_t *tvb, int offset);
67
68 /* Wireshark ID of the SIMULCRYPT protocol */
69 static guint proto_simulcrypt = -1;
70
71 /* Preferences (with default values) */
72 static guint global_simulcrypt_tcp_port = 0;   /* Simulcrypt registered only if pref set to non-zero value */
73 static guint global_simulcrypt_udp_port = 0;   /* Simulcrypt registered only if pref set to non-zero value */
74 static int ca_system_id_mikey = CA_SYSTEM_ID_MIKEY; /* MIKEY ECM CA_system_ID */
75
76 /* MIKEY payload start bytes */
77 /*unsigned char mikey_start[3]={0x01,0x00,0x15};
78 * mikey_start[0]=0x01;   first byte mikey payload (version)
79 * mikey_start[1]=0x00;   second byte mikey payload (data type)
80 * mikey_start[2]=0x15;   third byte (next payload)
81 */
82
83 /* Dissector-internal values to determine interface, can be re-organized */
84 #define SIMULCRYPT_RESERVED     0
85 #define SIMULCRYPT_ECMG_SCS     1
86 #define SIMULCRYPT_EMMG_MUX     2
87 #define SIMULCRYPT_CPSIG_PSIG   3
88 #define SIMULCRYPT_EIS_SCS      4
89 #define SIMULCRYPT_PSIG_MUX     5
90 #define SIMULCRYPT_MUX_CIM      6
91 #define SIMULCRYPT_PSIG_CIP     7
92 #define SIMULCRYPT_USER_DEFINED 8
93
94 static const value_string interfacenames[] = {
95         { SIMULCRYPT_RESERVED,     "DVB reserved" },
96         { SIMULCRYPT_ECMG_SCS,     "ECMG <-> SCS" },
97         { SIMULCRYPT_EMMG_MUX,     "EMMG <-> MUX" },
98         { SIMULCRYPT_CPSIG_PSIG,   "C(P)SIG <-> (P)SIG" },
99         { SIMULCRYPT_EIS_SCS,      "EIS <-> SCS" },
100         { SIMULCRYPT_PSIG_MUX,     "(P)SIG <-> MUX" },
101         { SIMULCRYPT_MUX_CIM,      "Carousel in the MUX - CiM" },
102         { SIMULCRYPT_PSIG_CIP,     "Carousel in the (P) - CiP" },
103         { SIMULCRYPT_USER_DEFINED, "User defined" },
104         { 0, NULL }
105 };
106
107 /* Reserved 0x0000 */
108 #define SIMULCRYPT_ECMG_CHANNEL_SETUP                   0x0001
109 #define SIMULCRYPT_ECMG_CHANNEL_TEST                    0x0002
110 #define SIMULCRYPT_ECMG_CHANNEL_STATUS                  0x0003
111 #define SIMULCRYPT_ECMG_CHANNEL_CLOSE                   0x0004
112 #define SIMULCRYPT_ECMG_CHANNEL_ERROR                   0x0005
113 /* Reserved 0x0006 - 0x0010 */
114 #define SIMULCRYPT_EMMG_CHANNEL_SETUP                   0x0011
115 #define SIMULCRYPT_EMMG_CHANNEL_TEST                    0x0012
116 #define SIMULCRYPT_EMMG_CHANNEL_STATUS                  0x0013
117 #define SIMULCRYPT_EMMG_CHANNEL_CLOSE                   0x0014
118 #define SIMULCRYPT_EMMG_CHANNEL_ERROR                   0x0015
119 /* Reserved 0x0016 - 0x0100 */
120 #define SIMULCRYPT_ECMG_STREAM_SETUP                    0x0101
121 #define SIMULCRYPT_ECMG_STREAM_TEST                     0x0102
122 #define SIMULCRYPT_ECMG_STREAM_STATUS                   0x0103
123 #define SIMULCRYPT_ECMG_STREAM_CLOSE_REQUEST            0x0104
124 #define SIMULCRYPT_ECMG_STREAM_CLOSE_RESPONSE           0x0105
125 #define SIMULCRYPT_ECMG_STREAM_ERROR                    0x0106
126 /* Reserved 0x0107 - 0x0110 */
127 #define SIMULCRYPT_EMMG_STREAM_SETUP                    0x0111
128 #define SIMULCRYPT_EMMG_STREAM_TEST                     0x0112
129 #define SIMULCRYPT_EMMG_STREAM_STATUS                   0x0113
130 #define SIMULCRYPT_EMMG_STREAM_CLOSE_REQUEST            0x0114
131 #define SIMULCRYPT_EMMG_STREAM_CLOSE_RESPONSE           0x0115
132 #define SIMULCRYPT_EMMG_STREAM_ERROR                    0x0116
133 #define SIMULCRYPT_EMMG_STREAM_BW_REQUEST               0x0117
134 #define SIMULCRYPT_EMMG_STREAM_BW_ALLOCATION            0x0118
135 /* Reserved 0x0119 - 0x0200 */
136 #define SIMULCRYPT_ECMG_CW_PROVISION                    0x0201
137 #define SIMULCRYPT_ECMG_ECM_RESPONSE                    0x0202
138 /* Reserved 0x0203 - 0x0210 */
139 #define SIMULCRYPT_EMMG_DATA_PROVISION                  0x0211
140 /* Reserved 0x0212 - 0x0300 */
141 /* Not implemented 0x0301 - 0x7FFF */
142 /* User defined 0x8000 - 0xFFFF */
143
144 static const value_string messagetypenames[] = {
145         { SIMULCRYPT_ECMG_CHANNEL_SETUP,         "CHANNEL_SETUP" },
146         { SIMULCRYPT_ECMG_CHANNEL_TEST,          "CHANNEL_TEST" },
147         { SIMULCRYPT_ECMG_CHANNEL_STATUS,        "CHANNEL_STATUS" },
148         { SIMULCRYPT_ECMG_CHANNEL_CLOSE,         "CHANNEL_CLOSE" },
149         { SIMULCRYPT_ECMG_CHANNEL_ERROR,         "CHANNEL_ERROR" },
150
151         { SIMULCRYPT_EMMG_CHANNEL_SETUP,         "CHANNEL_SETUP" },
152         { SIMULCRYPT_EMMG_CHANNEL_TEST,          "CHANNEL_TEST" },
153         { SIMULCRYPT_EMMG_CHANNEL_STATUS,        "CHANNEL_STATUS" },
154         { SIMULCRYPT_EMMG_CHANNEL_CLOSE,         "CHANNEL_CLOSE" },
155         { SIMULCRYPT_EMMG_CHANNEL_ERROR,         "CHANNEL_ERROR" },
156
157         { SIMULCRYPT_ECMG_STREAM_SETUP,          "STREAM_SETUP" },
158         { SIMULCRYPT_ECMG_STREAM_TEST,           "STREAM_TEST" },
159         { SIMULCRYPT_ECMG_STREAM_STATUS,         "STREAM_STATUS" },
160         { SIMULCRYPT_ECMG_STREAM_CLOSE_REQUEST,  "STREAM_CLOSE_REQUEST" },
161         { SIMULCRYPT_ECMG_STREAM_CLOSE_RESPONSE, "STREAM_CLOSE_RESPONSE" },
162         { SIMULCRYPT_ECMG_STREAM_ERROR,          "STREAM_ERROR" },
163
164         { SIMULCRYPT_EMMG_STREAM_SETUP,          "STREAM_SETUP" },
165         { SIMULCRYPT_EMMG_STREAM_TEST,           "STREAM_TEST" },
166         { SIMULCRYPT_EMMG_STREAM_STATUS,         "STREAM_STATUS" },
167         { SIMULCRYPT_EMMG_STREAM_CLOSE_REQUEST,  "STREAM_CLOSE_REQUEST" },
168         { SIMULCRYPT_EMMG_STREAM_CLOSE_RESPONSE, "STREAM_CLOSE_RESPONSE" },
169         { SIMULCRYPT_EMMG_STREAM_ERROR,          "STREAM_ERROR" },
170         { SIMULCRYPT_EMMG_STREAM_BW_REQUEST,     "STREAM_BW_REQUEST" },
171         { SIMULCRYPT_EMMG_STREAM_BW_ALLOCATION,  "STREAM_BW_ALLOCATION" },
172
173         { SIMULCRYPT_ECMG_CW_PROVISION,          "CW_PROVISION" },
174         { SIMULCRYPT_ECMG_ECM_RESPONSE,          "ECM_RESPONSE" },
175
176         { SIMULCRYPT_EMMG_DATA_PROVISION,        "DATA_PROVISION" },
177         { 0, NULL }
178 };      
179
180 /* Simulcrypt ECMG Parameter Types */
181 #define SIMULCRYPT_ECMG_DVB_RESERVED                    0x0000
182 #define SIMULCRYPT_ECMG_SUPER_CAS_ID                    0x0001
183 #define SIMULCRYPT_ECMG_SECTION_TSPKT_FLAG              0x0002
184 #define SIMULCRYPT_ECMG_DELAY_START                     0x0003
185 #define SIMULCRYPT_ECMG_DELAY_STOP                      0x0004
186 #define SIMULCRYPT_ECMG_TRANSITION_DELAY_START          0x0005
187 #define SIMULCRYPT_ECMG_TRANSITION_DELAY_STOP           0x0006
188 #define SIMULCRYPT_ECMG_ECM_REP_PERIOD                  0x0007
189 #define SIMULCRYPT_ECMG_MAX_STREAMS                     0x0008
190 #define SIMULCRYPT_ECMG_MIN_CP_DURATION                 0x0009
191 #define SIMULCRYPT_ECMG_LEAD_CW                         0x000A
192 #define SIMULCRYPT_ECMG_CW_PER_MESSAGE                  0x000B
193 #define SIMULCRYPT_ECMG_MAX_COMP_TIME                   0x000C
194 #define SIMULCRYPT_ECMG_ACCESS_CRITERIA                 0x000D
195 #define SIMULCRYPT_ECMG_ECM_CHANNEL_ID                  0x000E
196 #define SIMULCRYPT_ECMG_ECM_STREAM_ID                   0x000F
197 #define SIMULCRYPT_ECMG_NOMINAL_CP_DURATION             0x0010
198 #define SIMULCRYPT_ECMG_ACCESS_CRITERIA_TRANSFER_MODE   0x0011
199 #define SIMULCRYPT_ECMG_CP_NUMBER                       0x0012
200 #define SIMULCRYPT_ECMG_CP_DURATION                     0x0013
201 #define SIMULCRYPT_ECMG_CP_CW_COMBINATION               0x0014
202 #define SIMULCRYPT_ECMG_ECM_DATAGRAM                    0x0015
203 #define SIMULCRYPT_ECMG_AC_DELAY_START                  0x0016
204 #define SIMULCRYPT_ECMG_AC_DELAY_STOP                   0x0017
205 #define SIMULCRYPT_ECMG_CW_ENCRYPTION                   0x0018
206 #define SIMULCRYPT_ECMG_ECM_ID                          0x0019
207 #define SIMULCRYPT_ECMG_ERROR_STATUS                    0x7000
208 #define SIMULCRYPT_ECMG_ERROR_INFORMATION               0x7001
209
210 static const value_string ecmg_parametertypenames[] = {
211         { SIMULCRYPT_ECMG_DVB_RESERVED,                  "DVB_RESERVED" },
212         { SIMULCRYPT_ECMG_SUPER_CAS_ID,                  "SUPER_CAS_ID" },
213         { SIMULCRYPT_ECMG_SECTION_TSPKT_FLAG,            "SECTION_TSPKT_FLAG" },
214         { SIMULCRYPT_ECMG_DELAY_START,                   "DELAY_START" },
215         { SIMULCRYPT_ECMG_DELAY_STOP,                    "DELAY_STOP" },
216         { SIMULCRYPT_ECMG_TRANSITION_DELAY_START,        "TRANSITION_DELAY_START" },
217         { SIMULCRYPT_ECMG_TRANSITION_DELAY_STOP,         "TRANSITION_DELAY_STOP" },
218         { SIMULCRYPT_ECMG_ECM_REP_PERIOD,                "ECM_REP_PERIOD" },
219         { SIMULCRYPT_ECMG_MAX_STREAMS,                   "MAX_STREAMS" },
220         { SIMULCRYPT_ECMG_MIN_CP_DURATION,               "MIN_CP_DURATION" },
221         { SIMULCRYPT_ECMG_LEAD_CW,                       "LEAD_CW" },
222         { SIMULCRYPT_ECMG_CW_PER_MESSAGE,                "CW_PER_MESSAGE" },
223         { SIMULCRYPT_ECMG_MAX_COMP_TIME,                 "MAX_COMP_TIME" },
224         { SIMULCRYPT_ECMG_ACCESS_CRITERIA,               "ACCESS_CRITERIA" },
225         { SIMULCRYPT_ECMG_ECM_CHANNEL_ID,                "ECM_CHANNEL_ID" },
226         { SIMULCRYPT_ECMG_ECM_STREAM_ID,                 "ECM_STREAM_ID" },
227         { SIMULCRYPT_ECMG_NOMINAL_CP_DURATION,           "NOMINAL_CP_DURATION" },
228         { SIMULCRYPT_ECMG_ACCESS_CRITERIA_TRANSFER_MODE, "ACCESS_CRITERIA_TRANSFER_MODE" },
229         { SIMULCRYPT_ECMG_CP_NUMBER,                     "CP_NUMBER" },
230         { SIMULCRYPT_ECMG_CP_DURATION,                   "CP_DURATION" },
231         { SIMULCRYPT_ECMG_CP_CW_COMBINATION,             "CP_CW_COMBINATION" },
232         { SIMULCRYPT_ECMG_ECM_DATAGRAM,                  "ECM_DATAGRAM" },
233         { SIMULCRYPT_ECMG_AC_DELAY_START,                "AC_DELAY_START" },
234         { SIMULCRYPT_ECMG_AC_DELAY_STOP,                 "AC_DELAY_STOP" },
235         { SIMULCRYPT_ECMG_CW_ENCRYPTION,                 "CW_ENCRYPTION" },
236         { SIMULCRYPT_ECMG_ECM_ID,                        "ECM_ID" },
237         { SIMULCRYPT_ECMG_ERROR_STATUS,                  "ERROR_STATUS" },
238         { SIMULCRYPT_ECMG_ERROR_INFORMATION,             "ERROR_INFORMATION" },
239         { 0, NULL }
240 };
241
242 /* Simulcrypt ECMG protocol error values */
243 static const value_string ecmg_error_values[] = {
244         { 0x0000, "DVB Reserved" },
245         { 0x0001, "Invalid message" },
246         { 0x0002, "Unsupported protocol version" },
247         { 0x0003, "Unknown message type value" },
248         { 0x0004, "Message too long" },
249         { 0x0005, "Unknown super CAS ID value" },
250         { 0x0006, "Unknown ECM channel ID value" },
251         { 0x0007, "Unknown ECM stream ID value" },
252         { 0x0008, "Too many channels on this ECMG" },
253         { 0x0009, "Too many ECM streams on this channel" },
254         { 0x000A, "Too many ECM streams on this ECMG" },
255         { 0x000B, "Not enough control words to compute ECM" },
256         { 0x000C, "ECMG out of storage capacity" },
257         { 0x000D, "ECMG out of computational resources" },
258         { 0x000E, "Unknown parameter type value" },
259         { 0x000F, "Inconsistent length for DVB parameter" },
260         { 0x0010, "Missing mandatory DVB parameter" },
261         { 0x0011, "Invalid value for DVB parameter" },
262         { 0x0012, "Unknown ECM ID value" },
263         { 0x0013, "ECM channel ID value already in use" },
264         { 0x0014, "ECM stream ID value already in use" },
265         { 0x0015, "ECM ID value already in use" },
266         { 0x7000, "Unknown error" },
267         { 0x7001, "Unrecoverable error" },
268         { 0, NULL }
269 };
270
271 /* Simulcrypt EMMG Parameter Types */
272 #define SIMULCRYPT_EMMG_DVB_RESERVED                    0x0000
273 #define SIMULCRYPT_EMMG_CLIENT_ID                       0x0001
274 #define SIMULCRYPT_EMMG_SECTION_TSPKT_FLAG              0x0002
275 #define SIMULCRYPT_EMMG_DATA_CHANNEL_ID                 0x0003
276 #define SIMULCRYPT_EMMG_DATA_STREAM_ID                  0x0004
277 #define SIMULCRYPT_EMMG_DATAGRAM                        0x0005
278 #define SIMULCRYPT_EMMG_BANDWIDTH                       0x0006
279 #define SIMULCRYPT_EMMG_DATA_TYPE                       0x0007
280 #define SIMULCRYPT_EMMG_DATA_ID                         0x0008
281 #define SIMULCRYPT_EMMG_ERROR_STATUS                    0x7000
282 #define SIMULCRYPT_EMMG_ERROR_INFORMATION               0x7001
283
284 static const value_string emmg_parametertypenames[] = {
285         { SIMULCRYPT_EMMG_DVB_RESERVED,       "DVB_RESERVED" },
286         { SIMULCRYPT_EMMG_CLIENT_ID,          "CLIENT_ID" },
287         { SIMULCRYPT_EMMG_SECTION_TSPKT_FLAG, "SECTION_TSPKT_FLAG" },
288         { SIMULCRYPT_EMMG_DATA_CHANNEL_ID,    "DATA_CHANNEL_ID" },
289         { SIMULCRYPT_EMMG_DATA_STREAM_ID,     "DATA_STREAM_ID" },
290         { SIMULCRYPT_EMMG_DATAGRAM,           "DATAGRAM" },
291         { SIMULCRYPT_EMMG_BANDWIDTH,          "BANDWIDTH" },
292         { SIMULCRYPT_EMMG_DATA_TYPE,          "DATA_TYPE" },
293         { SIMULCRYPT_EMMG_DATA_ID,            "DATA_ID" },
294         { SIMULCRYPT_EMMG_ERROR_STATUS,       "ERROR_STATUS" },
295         { SIMULCRYPT_EMMG_ERROR_INFORMATION,  "ERROR_INFORMATION" },
296         { 0, NULL }
297 };
298
299 /* Simulcrypt EMMG protocol error values */
300 static const value_string emmg_error_values[] = {
301         { 0x0000, "DVB Reserved" },
302         { 0x0001, "Invalid message" },
303         { 0x0002, "Unsupported protocol version" },
304         { 0x0003, "Unknown message type value" },
305         { 0x0004, "Message too long" },
306         { 0x0005, "Unknown data stream ID value" },
307         { 0x0006, "Unknown data channel ID value" },
308         { 0x0007, "Too many channels on this MUX" },
309         { 0x0008, "Too many data streams on this channel" },
310         { 0x0009, "Too many data streams on this MUX" },
311         { 0x000A, "Unknown parameter type" },
312         { 0x000B, "Inconsistent length for DVB parameter" },
313         { 0x000C, "Missing mandatory DVB parameter" },
314         { 0x000D, "Invalid value for DVB parameter" },
315         { 0x000E, "Unknown client ID value" },
316         { 0x000F, "Exceeded bandwidth" },
317         { 0x0010, "Unknown data ID value" },
318         { 0x0011, "Data channel ID value already in use" },
319         { 0x0012, "Data stream ID value already in use" },
320         { 0x0013, "Data ID value already in use" },
321         { 0x0014, "Client ID value already in use" },
322         { 0x7000, "Unknown error" },
323         { 0x7001, "Unrecoverable error" },
324         { 0, NULL }
325 };
326
327 /* The following hf_* variables are used to hold the Wireshark IDs of
328 * our header fields; they are filled out when we call
329 * proto_register_field_array() in proto_register_simulcrypt()
330 */
331 static gint hf_simulcrypt_header = -1;
332 static gint hf_simulcrypt_version = -1;
333 static gint hf_simulcrypt_message_type = -1;
334 static gint hf_simulcrypt_interface = -1;
335 static gint hf_simulcrypt_message_length = -1;
336 static gint hf_simulcrypt_message = -1;
337 static gint hf_simulcrypt_parameter = -1;
338 static gint hf_simulcrypt_parameter_type = -1;
339 static gint hf_simulcrypt_ecmg_parameter_type = -1;
340 static gint hf_simulcrypt_emmg_parameter_type = -1;
341 static gint hf_simulcrypt_parameter_length = -1;
342 static gint hf_simulcrypt_ca_system_id = -1;
343 static gint hf_simulcrypt_ca_subsystem_id = -1;
344 static gint hf_simulcrypt_super_cas_id = -1;
345 static gint hf_simulcrypt_section_tspkt_flag = -1;
346 static gint hf_simulcrypt_ecm_channel_id = -1;
347 static gint hf_simulcrypt_delay_start = -1;
348 static gint hf_simulcrypt_delay_stop = -1;
349 static gint hf_simulcrypt_ac_delay_start = -1;
350 static gint hf_simulcrypt_ac_delay_stop = -1;
351 static gint hf_simulcrypt_transition_delay_start = -1;
352 static gint hf_simulcrypt_transition_delay_stop = -1;
353 static gint hf_simulcrypt_ecm_rep_period = -1;
354 static gint hf_simulcrypt_max_streams = -1;
355 static gint hf_simulcrypt_min_cp_duration = -1;
356 static gint hf_simulcrypt_lead_cw = -1;
357 static gint hf_simulcrypt_cw_per_msg = -1;
358 static gint hf_simulcrypt_max_comp_time = -1;
359 static gint hf_simulcrypt_access_criteria = -1;
360 static gint hf_simulcrypt_ecm_stream_id = -1;
361 static gint hf_simulcrypt_nominal_cp_duration = -1;
362 static gint hf_simulcrypt_access_criteria_transfer_mode = -1;
363 static gint hf_simulcrypt_cp_number = -1;
364 static gint hf_simulcrypt_cp_duration = -1;
365 static gint hf_simulcrypt_cp_cw_combination = -1;
366 static gint hf_simulcrypt_ecm_datagram = -1;
367 static gint hf_simulcrypt_cw_encryption = -1;
368 static gint hf_simulcrypt_ecm_id = -1;
369 static gint hf_simulcrypt_client_id = -1;
370 static gint hf_simulcrypt_data_channel_id = -1;
371 static gint hf_simulcrypt_data_stream_id = -1;
372 static gint hf_simulcrypt_datagram = -1;
373 static gint hf_simulcrypt_bandwidth = -1;
374 static gint hf_simulcrypt_data_type = -1;
375 static gint hf_simulcrypt_data_id = -1;
376 static gint hf_simulcrypt_ecmg_error_status = -1;
377 static gint hf_simulcrypt_emmg_error_status = -1;
378 static gint hf_simulcrypt_error_information = -1;
379
380 /* These are the ids of the subtrees that we may be creating */
381 static gint ett_simulcrypt = -1;
382 static gint ett_simulcrypt_header = -1;
383 static gint ett_simulcrypt_message = -1;
384 static gint ett_simulcrypt_parameter = -1;
385 static gint ett_simulcrypt_super_cas_id = -1;
386 static gint ett_simulcrypt_ecm_datagram = -1;
387
388
389 #define FRAME_HEADER_LEN 8
390
391 /* The main dissecting routine */
392 static void dissect_simulcrypt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
393 {
394     tcp_dissect_pdus(tvb, pinfo, tree, TRUE, FRAME_HEADER_LEN,
395                      get_simulcrypt_message_len, dissect_simulcrypt_message);
396 }
397
398 /* Informative tree structure is shown here:
399 * TREE  -
400 *       - HEADER
401 *               version
402 *               message type
403 *               message length
404 *       - MESSAGE
405 *               - TYPE of parameter
406 *                       length of parameter
407                         value of parameter
408                         - PARAMETER (optional branch for certain parameters only)
409 *                               parameter value sub items here
410 * End informative tree structure 
411 */
412
413 static guint16
414 get_interface (guint16 type)
415 {
416         int interface;
417
418         if (type >= 0x8000) {
419                 return SIMULCRYPT_USER_DEFINED;
420         }
421
422         /* Hex values fetched from Table 3: Message-type values for command/response-based protocols */
423         switch (type & 0xFFF0) {
424         case 0x0000:
425         case 0x0100:
426         case 0x0200:
427                 interface = SIMULCRYPT_ECMG_SCS;
428                 break;
429         case 0x0010:
430         case 0x0110:
431         case 0x0210:
432                 interface = SIMULCRYPT_EMMG_MUX;
433                 break;
434         case 0x0310:
435         case 0x0320:
436                 interface = SIMULCRYPT_CPSIG_PSIG;
437                 break;
438         case 0x0400:
439                 interface = SIMULCRYPT_EIS_SCS;
440                 break;
441         case 0x0410:
442         case 0x0420:
443                 interface = SIMULCRYPT_PSIG_MUX;
444                 break;
445         case 0x0430:
446                 interface = SIMULCRYPT_MUX_CIM;
447                 break;
448         case 0x0440:
449                 interface = SIMULCRYPT_PSIG_CIP;
450                 break;
451         default:
452                 interface = SIMULCRYPT_RESERVED;
453                 break;
454         }
455
456         return interface;
457 }
458
459 static void 
460 dissect_ecmg_parameter_value (proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, guint32 offset, guint16 plen, guint16 ptype, gchar *pvalue_char)
461 {
462         proto_item *simulcrypt_item;
463         proto_tree *simulcrypt_super_cas_id_tree;
464         proto_tree *simulcrypt_ecm_datagram_tree;
465         tvbuff_t   *next_tvb;
466         guint32     pvaluedec;    /* parameter decimal value */
467         int         ca_system_id;
468         guint       i;
469
470         switch (ptype) {
471         case SIMULCRYPT_ECMG_SUPER_CAS_ID:
472                 /* add super_cas_id item */
473                 simulcrypt_item = proto_tree_add_item(tree, hf_simulcrypt_super_cas_id, tvb, offset, plen, FALSE); /* value item */
474                 simulcrypt_super_cas_id_tree = proto_item_add_subtree(simulcrypt_item, ett_simulcrypt_super_cas_id);
475                 
476                 /* Simulcrypt_super_cas_id_tree */
477                 simulcrypt_item = proto_tree_add_item(simulcrypt_super_cas_id_tree, hf_simulcrypt_ca_system_id, tvb, offset, 2, FALSE );
478                         
479                 /* Test for known CA_System_ID */
480                 ca_system_id = tvb_get_ntohs(tvb,offset);
481                 for(i=0;i<ECM_INTERPRETATION_SIZE;i++)
482                 {                       
483                         if(tab_ecm_inter[i].ca_system_id==ca_system_id)
484                         {
485                                 tab_ecm_inter[i].ecmg_port=pinfo->destport;
486                                 proto_item_append_text(simulcrypt_item, ", Port %d, Protocol %s",tab_ecm_inter[i].ecmg_port, tab_ecm_inter[i].protocol_name);
487                                 break;
488                         }
489                 }
490                 proto_tree_add_item(simulcrypt_super_cas_id_tree, hf_simulcrypt_ca_subsystem_id, tvb, offset+2, 2, FALSE );
491                 break;
492         case SIMULCRYPT_ECMG_SECTION_TSPKT_FLAG:
493                 proto_tree_add_item(tree, hf_simulcrypt_section_tspkt_flag, tvb, offset, plen, FALSE); /* value item */
494                 break;
495         case SIMULCRYPT_ECMG_ECM_CHANNEL_ID:
496                 proto_tree_add_item(tree, hf_simulcrypt_ecm_channel_id, tvb, offset, plen, FALSE);
497                 break;
498         case SIMULCRYPT_ECMG_DELAY_START:
499                 simulcrypt_item = proto_tree_add_item(tree, hf_simulcrypt_delay_start, tvb, offset, plen, FALSE);
500                 proto_item_append_text(simulcrypt_item, " ms");
501                 break;
502         case SIMULCRYPT_ECMG_DELAY_STOP:
503                 simulcrypt_item = proto_tree_add_item(tree, hf_simulcrypt_delay_stop, tvb, offset, plen, FALSE);
504                 proto_item_append_text(simulcrypt_item, " ms"); 
505                 break;
506         case SIMULCRYPT_ECMG_TRANSITION_DELAY_START:
507                 simulcrypt_item = proto_tree_add_item(tree, hf_simulcrypt_transition_delay_start, tvb, offset, plen, FALSE);
508                 proto_item_append_text(simulcrypt_item, " ms");
509                 break;
510         case SIMULCRYPT_ECMG_TRANSITION_DELAY_STOP:
511                 simulcrypt_item = proto_tree_add_item(tree, hf_simulcrypt_transition_delay_stop, tvb, offset, plen, FALSE);
512                 proto_item_append_text(simulcrypt_item, " ms");
513                 break;
514         case SIMULCRYPT_ECMG_AC_DELAY_START:
515                 simulcrypt_item = proto_tree_add_item(tree, hf_simulcrypt_ac_delay_start, tvb, offset, plen, FALSE);
516                 proto_item_append_text(simulcrypt_item, " ms");
517                 break;
518         case SIMULCRYPT_ECMG_AC_DELAY_STOP:
519                 simulcrypt_item = proto_tree_add_item(tree, hf_simulcrypt_ac_delay_stop, tvb, offset, plen, FALSE);
520                 proto_item_append_text(simulcrypt_item, " ms");
521                 break;
522         case SIMULCRYPT_ECMG_ECM_REP_PERIOD:
523                 simulcrypt_item = proto_tree_add_item(tree, hf_simulcrypt_ecm_rep_period, tvb, offset, plen, FALSE);
524                 proto_item_append_text(simulcrypt_item, " ms");
525                 break;
526         case SIMULCRYPT_ECMG_MAX_STREAMS:
527                 proto_tree_add_item(tree, hf_simulcrypt_max_streams, tvb, offset, plen, FALSE);
528                 break;
529         case SIMULCRYPT_ECMG_MIN_CP_DURATION:
530                 /* convert value to ms (in units 100 ms) */
531                 pvaluedec = tvb_get_ntohs(tvb, offset); /* read 2 byte min CP duration value */
532                 pvaluedec = pvaluedec*100; /* in ms now */
533                 simulcrypt_item = proto_tree_add_item(tree, hf_simulcrypt_min_cp_duration, tvb, offset, plen, FALSE);
534                 proto_item_append_text(simulcrypt_item, " (%d ms)",pvaluedec);
535                 break;
536         case SIMULCRYPT_ECMG_LEAD_CW:
537                 proto_tree_add_item(tree, hf_simulcrypt_lead_cw, tvb, offset, plen, FALSE);
538                 break;
539         case SIMULCRYPT_ECMG_CW_PER_MESSAGE:
540                 proto_tree_add_item(tree, hf_simulcrypt_cw_per_msg, tvb, offset, plen, FALSE);
541                 break;
542         case SIMULCRYPT_ECMG_MAX_COMP_TIME:
543                 simulcrypt_item = proto_tree_add_item(tree, hf_simulcrypt_max_comp_time, tvb, offset, plen, FALSE);
544                 proto_item_append_text(simulcrypt_item, " ms");
545                 break;
546         case SIMULCRYPT_ECMG_ACCESS_CRITERIA:
547                 proto_tree_add_item(tree, hf_simulcrypt_access_criteria, tvb, offset, plen, FALSE);
548                 break;
549         case SIMULCRYPT_ECMG_ECM_STREAM_ID:
550                 proto_tree_add_item(tree, hf_simulcrypt_ecm_stream_id, tvb, offset, plen, FALSE);
551                 break;
552         case SIMULCRYPT_ECMG_NOMINAL_CP_DURATION:
553                 /* convert value to ms (in units 100 ms) */
554                 pvaluedec = tvb_get_ntohs(tvb, offset); /* read 2 byte nominal CP duration value */
555                 pvaluedec = pvaluedec*100; /* in ms now */
556                 simulcrypt_item = proto_tree_add_item(tree, hf_simulcrypt_nominal_cp_duration, tvb, offset, plen, FALSE);
557                 proto_item_append_text(simulcrypt_item, " (%d ms)", pvaluedec);
558                 break;
559         case SIMULCRYPT_ECMG_ACCESS_CRITERIA_TRANSFER_MODE:
560                 proto_tree_add_item(tree, hf_simulcrypt_access_criteria_transfer_mode, tvb, offset, plen, FALSE);
561                 break;
562         case SIMULCRYPT_ECMG_CP_NUMBER:
563                 proto_tree_add_item(tree, hf_simulcrypt_cp_number, tvb, offset, plen, FALSE);
564                 break;
565         case SIMULCRYPT_ECMG_CP_DURATION:
566                 /* convert value to ms (in units 100 ms) */
567                 pvaluedec = tvb_get_ntohs(tvb, offset); /* read 2 byte CP duration value */
568                 pvaluedec = pvaluedec*100; /* in ms now */
569                 simulcrypt_item = proto_tree_add_item(tree, hf_simulcrypt_cp_duration, tvb, offset, plen, FALSE);
570                 proto_item_append_text(simulcrypt_item, " (%d ms)", pvaluedec);
571                 break;
572         case SIMULCRYPT_ECMG_CP_CW_COMBINATION:
573                 proto_tree_add_item(tree, hf_simulcrypt_cp_cw_combination, tvb, offset, plen, FALSE); 
574                 break;
575         case SIMULCRYPT_ECMG_ECM_DATAGRAM:
576                 simulcrypt_item = proto_tree_add_item(tree, hf_simulcrypt_ecm_datagram, tvb, offset, plen, FALSE); 
577                 /* Test srcport against table of ECMG ports & CA_System_ID for known protocol types */
578                 for(i=0;i<ECM_INTERPRETATION_SIZE;i++)
579                 {
580                         if(tab_ecm_inter[i].ecmg_port==pinfo->srcport) /* ECMG source port */
581                         { /* recognise port & ca_system_id and hence protocol name for ECM datagram */
582                                 next_tvb = tvb_new_subset_remaining(tvb, offset);
583                                 simulcrypt_ecm_datagram_tree = proto_item_add_subtree(simulcrypt_item, ett_simulcrypt_ecm_datagram);
584                                 if(tab_ecm_inter[i].protocol_handle != NULL)
585                                 {
586                                         call_dissector(tab_ecm_inter[i].protocol_handle, next_tvb,pinfo, simulcrypt_ecm_datagram_tree);
587                                 }
588                                 break;
589                         }
590                 }
591                 break;
592         case SIMULCRYPT_ECMG_CW_ENCRYPTION:
593                 proto_tree_add_item(tree, hf_simulcrypt_cw_encryption, tvb, offset, plen, FALSE); 
594                 break;
595         case SIMULCRYPT_ECMG_ECM_ID:
596                 proto_tree_add_item(tree, hf_simulcrypt_ecm_id, tvb, offset, plen, FALSE);
597                 break;
598         case SIMULCRYPT_ECMG_ERROR_STATUS:
599                 proto_tree_add_item(tree, hf_simulcrypt_ecmg_error_status, tvb, offset, plen, FALSE);
600                 break;
601         case SIMULCRYPT_ECMG_ERROR_INFORMATION:
602                 proto_tree_add_item(tree, hf_simulcrypt_error_information, tvb, offset, plen, FALSE);
603                 break;
604         default:  /* Unknown parameter type */
605                 proto_tree_add_text(tree, tvb, offset, plen, "Parameter Value: %s", pvalue_char); 
606                 break;
607         } /* end parameter type switch */
608 }
609
610 static void 
611 dissect_emmg_parameter_value (proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, guint32 offset, guint16 plen, guint16 ptype, gchar *pvalue_char)
612 {
613         proto_item *simulcrypt_item;
614
615         switch (ptype) {
616         case SIMULCRYPT_EMMG_CLIENT_ID:
617                 proto_tree_add_item(tree, hf_simulcrypt_client_id, tvb, offset, plen, FALSE);
618                 break;
619         case SIMULCRYPT_EMMG_SECTION_TSPKT_FLAG:
620                 proto_tree_add_item(tree, hf_simulcrypt_section_tspkt_flag, tvb, offset, plen, FALSE);
621                 break;
622         case SIMULCRYPT_EMMG_DATA_CHANNEL_ID:
623                 proto_tree_add_item(tree, hf_simulcrypt_data_channel_id, tvb, offset, plen, FALSE);
624                 break;
625         case SIMULCRYPT_EMMG_DATA_STREAM_ID:
626                 proto_tree_add_item(tree, hf_simulcrypt_data_stream_id, tvb, offset, plen, FALSE);
627                 break;
628         case SIMULCRYPT_EMMG_DATAGRAM:
629                 proto_tree_add_item(tree, hf_simulcrypt_datagram, tvb, offset, plen, FALSE);
630                 break;
631         case SIMULCRYPT_EMMG_BANDWIDTH:
632                 simulcrypt_item = proto_tree_add_item(tree, hf_simulcrypt_bandwidth, tvb, offset, plen, FALSE);
633                 proto_item_append_text(simulcrypt_item, " kbit/s");
634                 break;
635         case SIMULCRYPT_EMMG_DATA_TYPE:
636                 proto_tree_add_item(tree, hf_simulcrypt_data_type, tvb, offset, plen, FALSE);
637                 break;
638         case SIMULCRYPT_EMMG_DATA_ID:
639                 proto_tree_add_item(tree, hf_simulcrypt_data_id, tvb, offset, plen, FALSE);
640                 break;
641         case SIMULCRYPT_EMMG_ERROR_STATUS:
642                 proto_tree_add_item(tree, hf_simulcrypt_emmg_error_status, tvb, offset, plen, FALSE);
643                 break;
644         case SIMULCRYPT_EMMG_ERROR_INFORMATION:
645                 proto_tree_add_item(tree, hf_simulcrypt_error_information, tvb, offset, plen, FALSE);
646                 break;
647         default:  /* Unknown parameter type */
648                 proto_tree_add_text(tree, tvb, offset, plen, "Parameter Value: %s", pvalue_char); 
649                 break;
650         } /* end parameter type switch */
651 }
652
653
654 /* This method dissects fully reassembled messages */
655 static void dissect_simulcrypt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
656 {
657         proto_item *simulcrypt_item;
658         proto_tree *simulcrypt_tree;
659         proto_tree *simulcrypt_header_tree;
660         proto_tree *simulcrypt_message_tree;
661         proto_tree *simulcrypt_parameter_tree;
662         guint16     type, iftype;
663
664         col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_SIMULCRYPT);
665         col_clear(pinfo->cinfo,COL_INFO);
666
667         /* get 2 byte type value */
668         type =  tvb_get_ntohs(tvb, 1); /* 2 bytes starting at offset 1 are the message type */
669         iftype = get_interface (type);
670
671         col_add_fstr(pinfo->cinfo, COL_INFO, "%d > %d Info Type:[%s]",
672                      pinfo->srcport, pinfo->destport, 
673                      val_to_str(type, messagetypenames, "Unknown Type:0x%02x"));
674
675         if (tree)
676         {
677                 /* we are being asked for details */
678                 guint32 offset = 0;
679                 guint32 msg_length;
680                 
681                 simulcrypt_item = proto_tree_add_item(tree, proto_simulcrypt, tvb, 0, -1, FALSE);
682                 simulcrypt_tree = proto_item_add_subtree(simulcrypt_item, ett_simulcrypt);
683
684                 proto_item_append_text(simulcrypt_item, ", Interface: %s", val_to_str(iftype, interfacenames, "Unknown (0x%02x)"));
685
686                 /* Simulcrypt_tree analysis */
687                 /* we are being asked for details */
688                 /* ADD HEADER BRANCH */
689                 simulcrypt_item = proto_tree_add_item(simulcrypt_tree, hf_simulcrypt_header, tvb, offset, 5, FALSE );
690                 simulcrypt_header_tree = proto_item_add_subtree(simulcrypt_item, ett_simulcrypt_header);
691                 proto_item_append_text(simulcrypt_header_tree, ", Length: %s", "5 bytes"); /* add text to Header tree indicating Length 5 bytes */
692
693                 /* Simulcrypt_header_tree analysis */
694                 /* Message Version 1 Byte */
695                 proto_tree_add_item(simulcrypt_header_tree, hf_simulcrypt_version, tvb, offset, 1, FALSE);              
696                 offset+=1;
697
698                 /* Message Type 2 Bytes */
699                 proto_tree_add_item(simulcrypt_header_tree, hf_simulcrypt_message_type, tvb, offset, 2, FALSE);
700                 simulcrypt_item = proto_tree_add_uint_format(simulcrypt_header_tree, hf_simulcrypt_interface, tvb, offset, 2, iftype, 
701                                                              "Interface: %s", val_to_str(iftype, interfacenames, "Unknown"));
702                 PROTO_ITEM_SET_GENERATED (simulcrypt_item);
703                 offset+=2;
704
705                 /* Message Length 2 Bytes */
706                 simulcrypt_item = proto_tree_add_item(simulcrypt_header_tree, hf_simulcrypt_message_length, tvb, offset, 2, FALSE);
707                 proto_item_append_text(simulcrypt_item, " (bytes)");
708                 msg_length = tvb_get_ntohs(tvb, offset); /* read 2 byte message length value */
709                 offset+=2;
710         
711                 /* ADD MESSAGE BRANCH */
712                 simulcrypt_item = proto_tree_add_item(simulcrypt_tree, hf_simulcrypt_message, tvb, offset, -1, FALSE );
713                 simulcrypt_message_tree = proto_item_add_subtree(simulcrypt_item, ett_simulcrypt_message);
714                 proto_item_append_text(simulcrypt_message_tree, " containing TLV parameters"); /* add text to Message tree      */      
715                 proto_item_append_text(simulcrypt_message_tree, ", Length: %d (bytes)", msg_length); /* add length info to message_tree */
716                 
717                 /* end header details */
718  
719                 /* Simulcrypt_message_tree analysis */
720                 /*  we are being asked for details */
721                 /* Navigate through message after header to find one or more parameters */
722                 while (offset < (msg_length+5))  /* offset is from beginning of the 5 byte header */
723                 {
724                         guint16 plen;         /* parameter length */
725                         guint16 ptype;        /* parameter type */
726                         gchar  *pvalue_char;  /* parameter value string */
727                         
728                         /* Parameter  Type 2 Bytes */
729                         ptype = tvb_get_ntohs(tvb, offset); /* read 2 byte type value */
730                         /* Parameter  Length 2 Bytes */
731                         plen = tvb_get_ntohs(tvb, offset+2); /* read 2 byte length value */
732                         /* Parameter  Value plen Bytes */
733                         pvalue_char = tvb_bytes_to_str(tvb, offset+4, plen);
734
735                         simulcrypt_item = proto_tree_add_item(simulcrypt_message_tree, hf_simulcrypt_parameter, tvb, offset, plen+2+2, FALSE );
736
737                         /* add length and value info to type */
738                         switch (iftype) {
739                         case SIMULCRYPT_ECMG_SCS:
740                                 proto_item_append_text(simulcrypt_item, ": Type=%s", val_to_str(ptype, ecmg_parametertypenames, "Unknown Type:0x%02x"));
741                                 break;
742                         case SIMULCRYPT_EMMG_MUX:
743                                 proto_item_append_text(simulcrypt_item, ": Type=%s", val_to_str(ptype, emmg_parametertypenames, "Unknown Type:0x%02x"));
744                                 break;
745                         default:
746                                 proto_item_append_text(simulcrypt_item, ": Type=0x%02x", ptype);
747                                 break;
748                         }
749                         proto_item_append_text(simulcrypt_item, ", Value Length=%d (bytes)", plen); /* add length info to parameter */
750                         proto_item_append_text(simulcrypt_item, ", Value=0x%s", pvalue_char); /* add value info to parameter */
751                         /* add subtree for parameter type, length and value items */
752                         simulcrypt_parameter_tree = proto_item_add_subtree(simulcrypt_item, ett_simulcrypt_parameter); /* add subtree for Length and Value */
753                         switch (iftype) { /* parameter type */
754                         case SIMULCRYPT_ECMG_SCS:
755                                 proto_tree_add_item(simulcrypt_parameter_tree, hf_simulcrypt_ecmg_parameter_type, tvb, offset, 2, FALSE);
756                                 break;
757                         case SIMULCRYPT_EMMG_MUX:
758                                 proto_tree_add_item(simulcrypt_parameter_tree, hf_simulcrypt_emmg_parameter_type, tvb, offset, 2, FALSE);
759                                 break;
760                         default:
761                                 proto_tree_add_item(simulcrypt_parameter_tree, hf_simulcrypt_parameter_type, tvb, offset, 2, FALSE);
762                                 break;
763                         }
764                         simulcrypt_item = proto_tree_add_item(simulcrypt_parameter_tree, hf_simulcrypt_parameter_length, tvb, offset+2, 2, FALSE); /* length item */
765                         proto_item_append_text(simulcrypt_item, " (bytes)");
766                         offset += 2+2;  /* offset --> parameter value */
767                         
768                         switch (iftype) {
769                         case SIMULCRYPT_ECMG_SCS:
770                                 dissect_ecmg_parameter_value (simulcrypt_parameter_tree, tvb, pinfo, offset, plen, ptype, pvalue_char);
771                                 break;
772                         case SIMULCRYPT_EMMG_MUX:
773                                 dissect_emmg_parameter_value (simulcrypt_parameter_tree, tvb, pinfo, offset, plen, ptype, pvalue_char);
774                                 break;
775                         default:
776                                 proto_tree_add_text(tree, tvb, offset, plen, "Parameter Value: %s", pvalue_char); 
777                                 break;
778                         }
779
780                         offset += plen;
781                 } /* end parameter tree details */
782                         
783         } /* end tree */
784 }       
785
786 /* determine PDU length of protocol foo */
787 static guint get_simulcrypt_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
788 {
789         guint iLg;
790         
791         iLg = tvb_get_ntohs(tvb,offset+3); /*length is at offset 3 */
792         iLg += 5; /* add 1 byte version + 2 byte type + 2 byte length (simulcrypt "header" */
793         return iLg;
794 }       
795
796 /* Clean out the ecm_interpretation port association whenever            */
797 /* making a pass through a capture file to dissect all its packets       */
798 /*  (e.g., reading in a new capture file, changing a simulcrypt pref,    */
799 /*  or running a "filter packets" or "colorize packets" pass over the    */
800 /*  current capture file.                                                */
801
802 static void 
803 simulcrypt_init(void) 
804 {
805         guint i;
806
807         for(i=0;i<ECM_INTERPRETATION_SIZE;i++)
808         {
809                 tab_ecm_inter[i].ecmg_port = -1;
810         }
811 }
812
813 void proto_reg_handoff_simulcrypt(void);
814
815 void proto_register_simulcrypt (void)
816 {
817         /* A header field is something you can search/filter on.
818         * 
819         * We create a structure to register our fields. It consists of an
820         * array of hf_register_info structures, each of which are of the format
821         * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
822         */
823         static hf_register_info hf[] =
824         {
825                 { &hf_simulcrypt_header,
826                 { "Header", "simulcrypt.header", FT_NONE, BASE_NONE, NULL, 0x0,
827                  NULL, HFILL }},
828                  
829                 { &hf_simulcrypt_version,
830                 { "Version", "simulcrypt.version", FT_UINT8, BASE_HEX, NULL, 0x0,       /* version 1 byte */
831                 NULL, HFILL }},
832
833                 { &hf_simulcrypt_message_type,
834                 { "Message Type", "simulcrypt.message.type", FT_UINT16, BASE_HEX, VALS(messagetypenames), 0x0,          /* type 2 bytes */
835                  NULL, HFILL }},
836
837                 { &hf_simulcrypt_interface,
838                 { "Interface", "simulcrypt.message.interface", FT_UINT16, BASE_DEC, VALS(interfacenames), 0x0,
839                  NULL, HFILL }},
840
841                 { &hf_simulcrypt_message_length,
842                 { "Message Length", "simulcrypt.message.len", FT_UINT16, BASE_DEC, NULL, 0x0,           /* length 2 bytes, print as decimal value */
843                 NULL, HFILL }},
844
845                 { &hf_simulcrypt_message,
846                 { "Message", "simulcrypt.message", FT_NONE, BASE_NONE, NULL, 0x0,
847                  NULL, HFILL }}, 
848                  
849                 { &hf_simulcrypt_parameter,
850                 { "Parameter", "simulcrypt.parameter", FT_NONE, BASE_NONE, NULL, 0x0,
851                  NULL, HFILL }}, 
852                  
853                 { &hf_simulcrypt_parameter_type,
854                 { "Parameter Type", "simulcrypt.parameter.type", FT_UINT16, BASE_HEX, NULL, 0x0,        /* type 2 bytes */
855                  NULL, HFILL }},
856
857                 { &hf_simulcrypt_ecmg_parameter_type,
858                 { "Parameter Type", "simulcrypt.parameter.type", FT_UINT16, BASE_HEX, VALS(ecmg_parametertypenames), 0x0,       /* type 2 bytes */
859                  NULL, HFILL }},
860
861                 { &hf_simulcrypt_emmg_parameter_type,
862                 { "Parameter Type", "simulcrypt.parameter.type", FT_UINT16, BASE_HEX, VALS(emmg_parametertypenames), 0x0,       /* type 2 bytes */
863                  NULL, HFILL }},
864
865                 { &hf_simulcrypt_parameter_length,
866                 { "Parameter Length", "simulcrypt.parameter.len", FT_UINT16, BASE_DEC, NULL, 0x0,               /* length 2 bytes, print as decimal value */
867                 NULL, HFILL }},
868
869                 { &hf_simulcrypt_ca_system_id,
870                 { "CA System ID", "simulcrypt.parameter.ca_system_id", FT_UINT16, BASE_DEC, NULL, 0x0,
871                  NULL, HFILL }}, 
872
873                 { &hf_simulcrypt_ca_subsystem_id,
874                 { "CA Subsystem ID", "simulcrypt.parameter.ca_subsystem_id", FT_UINT16, BASE_DEC, NULL, 0x0,
875                  NULL, HFILL }},
876                  
877                 { &hf_simulcrypt_super_cas_id,
878                 { "SuperCAS ID", "simulcrypt.super_cas_id", FT_UINT32, BASE_HEX, NULL, 0x0,
879                  NULL, HFILL }},
880
881                 { &hf_simulcrypt_section_tspkt_flag,
882                 { "Section TS pkt flag", "simulcrypt.section_tspkt_flag", FT_UINT8, BASE_HEX, NULL, 0x0,
883                  NULL, HFILL }},
884
885                 { &hf_simulcrypt_ecm_channel_id,
886                 { "ECM channel ID", "simulcrypt.ecm_channel_id", FT_UINT16, BASE_DEC, NULL, 0x0,
887                  NULL, HFILL }},
888
889                 { &hf_simulcrypt_delay_start,   
890                 { "Delay start", "simulcrypt.delay_start", FT_INT16, BASE_DEC, NULL, 0x0,
891                  NULL, HFILL }},
892
893                 { &hf_simulcrypt_delay_stop,    
894                 { "Delay stop", "simulcrypt.delay_stop", FT_INT16, BASE_DEC, NULL, 0x0,
895                  NULL, HFILL }},
896
897                 { &hf_simulcrypt_ac_delay_start,        
898                 { "AC delay start", "simulcrypt.ac_delay_start", FT_INT16, BASE_DEC, NULL, 0x0,
899                  NULL, HFILL }},
900
901                 { &hf_simulcrypt_ac_delay_stop, 
902                 { "AC delay stop", "simulcrypt.ac_delay_stop", FT_INT16, BASE_DEC, NULL, 0x0,
903                  NULL, HFILL }},
904
905                 { &hf_simulcrypt_transition_delay_start,        
906                 { "Transition delay start", "simulcrypt.transition_delay_start", FT_INT16, BASE_DEC, NULL, 0x0,
907                  NULL, HFILL }},
908
909                 { &hf_simulcrypt_transition_delay_stop, 
910                 { "Transition delay stop", "simulcrypt.transition_delay_stop", FT_INT16, BASE_DEC, NULL, 0x0,
911                  NULL, HFILL }},        
912
913                 { &hf_simulcrypt_ecm_rep_period,
914                 { "ECM repetition period", "simulcrypt.ecm_rep_period", FT_UINT16, BASE_DEC, NULL, 0x0,
915                  NULL, HFILL }},
916
917                 { &hf_simulcrypt_max_streams,
918                 { "Max streams", "simulcrypt.max_streams", FT_UINT16, BASE_DEC, NULL, 0x0,
919                  NULL, HFILL }},
920
921                 { &hf_simulcrypt_min_cp_duration,
922                 { "Min CP duration", "simulcrypt.min_cp_duration", FT_UINT16, BASE_DEC, NULL, 0x0,
923                  NULL, HFILL }},
924
925                 { &hf_simulcrypt_lead_cw,
926                 { "Lead CW", "simulcrypt.lead_cw", FT_UINT8, BASE_DEC, NULL, 0x0,
927                  NULL, HFILL }},
928
929                 { &hf_simulcrypt_cw_per_msg,
930                 { "CW per msg", "simulcrypt.cw_per_msg", FT_UINT8, BASE_DEC, NULL, 0x0,
931                  NULL, HFILL }},
932
933                 { &hf_simulcrypt_max_comp_time,
934                 { "Max comp time", "simulcrypt.max_comp_time", FT_UINT16, BASE_DEC, NULL, 0x0,
935                  NULL, HFILL }},
936
937                 { &hf_simulcrypt_access_criteria,
938                 { "Access criteria", "simulcrypt.access_criteria", FT_BYTES, BASE_NONE, NULL, 0x0,
939                  NULL, HFILL }},
940
941                 { &hf_simulcrypt_ecm_stream_id,
942                 { "ECM stream ID", "simulcrypt.ecm_stream_id", FT_UINT16, BASE_DEC, NULL, 0x0,
943                  NULL, HFILL }},        
944
945                 { &hf_simulcrypt_nominal_cp_duration,
946                 { "Nominal CP duration", "simulcrypt.nominal_cp_duration", FT_UINT16, BASE_DEC, NULL, 0x0,
947                  NULL, HFILL }},
948
949                 { &hf_simulcrypt_access_criteria_transfer_mode,
950                 { "AC transfer mode", "simulcrypt.access_criteria_transfer_mode", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
951                  NULL, HFILL }},
952
953                 { &hf_simulcrypt_cp_number,
954                 { "CP number", "simulcrypt.cp_number", FT_UINT16, BASE_DEC, NULL, 0x0,
955                  NULL, HFILL }},
956
957                 { &hf_simulcrypt_cp_duration,
958                 { "CP duration", "simulcrypt.cp_duration", FT_UINT16, BASE_DEC, NULL, 0x0,
959                  NULL, HFILL }},
960
961                 { &hf_simulcrypt_cp_cw_combination,
962                 { "CP CW combination", "simulcrypt.cp_cw_combination", FT_BYTES, BASE_NONE, NULL, 0x0,
963                  NULL, HFILL }},
964                  
965                 { &hf_simulcrypt_ecm_datagram,
966                 { "ECM datagram", "simulcrypt.ecm_datagram", FT_BYTES, BASE_NONE, NULL, 0x0,
967                  NULL, HFILL }},
968
969                 { &hf_simulcrypt_cw_encryption,
970                 { "CW encryption", "simulcrypt.cw_encryption", FT_NONE, BASE_NONE, NULL, 0x0,
971                  NULL, HFILL }},
972
973                 { &hf_simulcrypt_ecm_id,
974                 { "ECM ID", "simulcrypt.ecm_id", FT_UINT16, BASE_DEC, NULL, 0x0,
975                  NULL, HFILL }},
976
977                 { &hf_simulcrypt_client_id,
978                 { "Client ID", "simulcrypt.client_id", FT_UINT32, BASE_DEC, NULL, 0x0,
979                  NULL, HFILL }},
980
981                 { &hf_simulcrypt_data_channel_id,
982                 { "Data Channel ID", "simulcrypt.data_channel_id", FT_UINT16, BASE_DEC, NULL, 0x0,
983                  NULL, HFILL }},
984
985                 { &hf_simulcrypt_data_stream_id,
986                 { "Data Stream ID", "simulcrypt.data_stream_id", FT_UINT16, BASE_DEC, NULL, 0x0,
987                  NULL, HFILL }},
988
989                 { &hf_simulcrypt_datagram,
990                 { "Datagram", "simulcrypt.datagram", FT_BYTES, BASE_NONE, NULL, 0x0,
991                  NULL, HFILL }},
992
993                 { &hf_simulcrypt_bandwidth,
994                 { "Bandwidth", "simulcrypt.bandwidth", FT_UINT16, BASE_DEC, NULL, 0x0,
995                  NULL, HFILL }},
996
997                 { &hf_simulcrypt_data_type,
998                 { "Data Type", "simulcrypt.data_type", FT_UINT8, BASE_DEC, NULL, 0x0,
999                  NULL, HFILL }},
1000
1001                 { &hf_simulcrypt_data_id,
1002                 { "Data ID", "simulcrypt.data_id", FT_UINT16, BASE_DEC, NULL, 0x0,
1003                  NULL, HFILL }},
1004
1005                 { &hf_simulcrypt_ecmg_error_status,
1006                 { "Error status", "simulcrypt.error_status", FT_UINT16, BASE_DEC, VALS(ecmg_error_values), 0x0,
1007                  NULL, HFILL }},
1008
1009                 { &hf_simulcrypt_emmg_error_status,
1010                 { "Error status", "simulcrypt.error_status", FT_UINT16, BASE_DEC, VALS(emmg_error_values), 0x0,
1011                  NULL, HFILL }},
1012
1013                 { &hf_simulcrypt_error_information,
1014                 { "Error information", "simulcrypt.error_information", FT_BYTES, BASE_NONE, NULL, 0x0,
1015                  NULL, HFILL }}          
1016         };
1017         
1018         static gint *ett[] =
1019         {
1020                 &ett_simulcrypt,
1021                 &ett_simulcrypt_header,
1022                 &ett_simulcrypt_message,
1023                 &ett_simulcrypt_parameter,
1024                 &ett_simulcrypt_super_cas_id,
1025                 &ett_simulcrypt_ecm_datagram
1026         };
1027         
1028         module_t *simulcrypt_module;
1029         
1030         /* execute protocol initialization only once */
1031         proto_simulcrypt = proto_register_protocol ("SIMULCRYPT Protocol", "SIMULCRYPT", "simulcrypt");
1032
1033         proto_register_field_array (proto_simulcrypt, hf, array_length (hf));
1034         proto_register_subtree_array (ett, array_length (ett));
1035         
1036         register_init_routine(simulcrypt_init);
1037
1038         /* Register our configuration options for Simulcrypt, particularly our port. */
1039         /* This registers our preferences; function proto_reg_handoff_simulcrypt is  */
1040         /*  called when preferences are applied.                                     */
1041         simulcrypt_module = prefs_register_protocol(proto_simulcrypt, proto_reg_handoff_simulcrypt);
1042         
1043         prefs_register_uint_preference(simulcrypt_module, "tcp.port", "Simulcrypt TCP Port",
1044                                  "Set the TCP port for Simulcrypt messages ('0' means no port is assigned)",
1045                                  10, &global_simulcrypt_tcp_port);
1046                                                                         
1047         prefs_register_uint_preference(simulcrypt_module, "udp.port", "Simulcrypt UDP Port",
1048                                  "Set the UDP port for Simulcrypt messages ('0' means no port is assigned)",
1049                                  10, &global_simulcrypt_udp_port);
1050                                                                         
1051         prefs_register_uint_preference(simulcrypt_module, "ca_system_id_mikey","MIKEY ECM CA_system_ID (in hex)",
1052                                         "Set the CA_system_ID used to decode ECM datagram as MIKEY", 16, &ca_system_id_mikey);          
1053 }
1054
1055 /* this is run every time preferences are changed and also during Wireshark initialization */
1056 void proto_reg_handoff_simulcrypt(void)
1057 {
1058         static gboolean initialized=FALSE;
1059         static dissector_handle_t simulcrypt_handle;
1060         static guint tcp_port, udp_port;
1061         guint  i;
1062
1063         if (!initialized) {
1064                 simulcrypt_handle = create_dissector_handle(dissect_simulcrypt, proto_simulcrypt);
1065                 for(i=0;i<ECM_INTERPRETATION_SIZE;i++)
1066                 {
1067                         tab_ecm_inter[i].protocol_handle = find_dissector(tab_ecm_inter[i].protocol_name);
1068                 }
1069                 dissector_add_handle("tcp.port", simulcrypt_handle);   /* for "decode_as" */
1070                 dissector_add_handle("udp.port", simulcrypt_handle);   /* for "decode_as" */
1071                 initialized = TRUE;
1072         }
1073         else {
1074                 dissector_delete("tcp.port", tcp_port, simulcrypt_handle);
1075                 dissector_delete("udp.port", udp_port, simulcrypt_handle);
1076         }       
1077         if (global_simulcrypt_tcp_port != 0) {
1078                 dissector_add("tcp.port", global_simulcrypt_tcp_port, simulcrypt_handle);
1079         }
1080         if (global_simulcrypt_udp_port != 0) {
1081                 dissector_add("udp.port", global_simulcrypt_udp_port, simulcrypt_handle);
1082         }
1083         tcp_port = global_simulcrypt_tcp_port;
1084         udp_port = global_simulcrypt_udp_port;
1085
1086         /* update tab_ecm_inter table (always do this) */
1087         tab_ecm_inter[ECM_MIKEY_INDEX].ca_system_id=ca_system_id_mikey;
1088 }
1089