Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-dvbci.c
Line
Count
Source
1
/* packet-dvbci.c
2
 * Routines for DVB-CI (Common Interface) dissection
3
 * Copyright 2011-2015, Martin Kaiser <martin@kaiser.cx>
4
 *
5
 * Wireshark - Network traffic analyzer
6
 * By Gerald Combs <gerald@wireshark.org>
7
 * Copyright 1998 Gerald Combs
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 */
11
12
/* This dissector supports DVB-CI as defined in EN50221 and
13
 * CI+ (www.ci-plus.com).
14
 * For more details, see https://gitlab.com/wireshark/wireshark/-/wikis/DVB-CI.
15
 *
16
 * The pcap input format for this dissector is documented at
17
 * http://www.kaiser.cx/pcap-dvbci.html.
18
 */
19
20
#include "config.h"
21
22
#include <epan/packet.h>
23
#include <epan/addr_resolv.h>
24
#include <epan/conversation.h>
25
#include <epan/dvb_chartbl.h>
26
#include <epan/exported_pdu.h>
27
#include <epan/reassemble.h>
28
#include <epan/prefs.h>
29
#include <epan/proto_data.h>
30
#include <epan/tap.h>
31
#include <epan/expert.h>
32
#include <epan/exceptions.h>
33
#include <epan/asn1.h>
34
#include <epan/tfs.h>
35
#include "packet-dvbci.h"
36
#include "packet-mpeg-descriptor.h"
37
#include "packet-mpeg-sect.h"
38
#include "packet-x509af.h"
39
#include "packet-x509ce.h"
40
#include "packet-ber.h"
41
#include "packet-mpeg-pmt.h"
42
#include <wsutil/wsgcrypt.h>
43
#include <wsutil/pint.h>
44
45
void proto_register_dvbci(void);
46
void proto_reg_handoff_dvbci(void);
47
48
0
#define AES_BLOCK_LEN 16
49
32
#define AES_KEY_LEN 16
50
51
16
#define EXPORTED_SAC_MSG_PROTO "ciplus_sac_msg"
52
16
#define EXPORTED_SAC_MSG_DESCRIPTION "CI+ SAC message"
53
54
0
#define IS_DATA_TRANSFER(e) (e==DVBCI_EVT_DATA_CAM_TO_HOST || e==DVBCI_EVT_DATA_HOST_TO_CAM)
55
56
/* direction of data transfer in [as]pdu_info_t and elsewhere */
57
0
#define DATA_CAM_TO_HOST  DVBCI_EVT_DATA_CAM_TO_HOST
58
0
#define DATA_HOST_TO_CAM  DVBCI_EVT_DATA_HOST_TO_CAM
59
0
#define DIRECTION_ANY     0x0
60
61
/* source/destination address field */
62
0
#define ADDR_HOST "Host"
63
0
#define ADDR_CAM  "CAM"
64
65
/* hardware event */
66
#define CAM_IN    0x01
67
#define CAM_OUT   0x02
68
#define POWER_ON  0x03
69
#define POWER_OFF 0x04
70
#define TS_ROUTE  0x05
71
#define TS_BYPASS 0x06
72
#define RESET_H   0x07
73
#define RESET_L   0x08
74
#define READY_H   0x09
75
#define READY_L   0x0A
76
77
/* Card Information Structure (CIS) */
78
79
/* tuples */
80
#define CISTPL_NO_LINK       0x14
81
0
#define CISTPL_VERS_1        0x15
82
0
#define CISTPL_CONFIG        0x1A
83
0
#define CISTPL_CFTABLE_ENTRY 0x1B
84
0
#define CISTPL_DEVICE_OC     0x1C
85
0
#define CISTPL_DEVICE_OA     0x1D
86
0
#define CISTPL_MANFID        0x20
87
0
#define CISTPL_END           0xFF
88
/* subtuple */
89
0
#define CCSTPL_CIF           0xC0
90
/* interface types */
91
#define TPCE_IF_TYPE_MEM     0
92
#define TPCE_IF_TYPE_IO_MEM  1
93
#define TPCE_IF_TYPE_CUST0   4
94
#define TPCE_IF_TYPE_CUST1   5
95
#define TPCE_IF_TYPE_CUST2   6
96
#define TPCE_IF_TYPE_CUST3   7
97
/* "voltage used" field in the device tuples */
98
#define CIS_DEV_VCC50 0
99
#define CIS_DEV_VCC33 1
100
101
/* link layer */
102
0
#define ML_MORE 0x80
103
#define ML_LAST 0x00
104
105
/* base values of sequence ids for reassembly of fragmented tpdus
106
   if there's two open transport connections, their tpdu fragments may be
107
    interleaved, we must add the tcid to the base value in order to
108
    distinguish between different transport connections
109
   TPDU_SEQ_ID_BASE and SPDU_SEQ_ID_BASE can be arbitrary 32bit values, they
110
    must be more than 256 apart since we add the 8bit tcid */
111
0
#define TPDU_SEQ_ID_BASE       123
112
/* same as above, the spdu fragments are also demultiplexed based on the
113
    t_c_id field */
114
0
#define SPDU_SEQ_ID_BASE      2417
115
116
/* transport layer */
117
0
#define NO_TAG        0x00
118
0
#define T_SB          0x80
119
0
#define T_RCV         0x81
120
#define T_CREATE_T_C  0x82
121
#define T_C_T_C_REPLY 0x83
122
#define T_DELETE_T_C  0x84
123
#define T_D_T_C_REPLY 0x85
124
#define T_REQUEST_T_C 0x86
125
#define T_NEW_T_C     0x87
126
#define T_T_C_ERROR   0x88
127
0
#define T_DATA_LAST   0xA0
128
0
#define T_DATA_MORE   0xA1
129
130
#define SB_VAL_MSG_AVAILABLE    0x80
131
#define SB_VAL_NO_MSG_AVAILABLE 0x00
132
133
/* session layer */
134
0
#define T_SESSION_NUMBER          0x90
135
0
#define T_OPEN_SESSION_REQUEST    0x91
136
0
#define T_OPEN_SESSION_RESPONSE   0x92
137
0
#define T_CREATE_SESSION          0x93
138
0
#define T_CREATE_SESSION_RESPONSE 0x94
139
0
#define T_CLOSE_SESSION_REQUEST   0x95
140
0
#define T_CLOSE_SESSION_RESPONSE  0x96
141
142
/* status for open/create session */
143
0
#define SESS_OPENED                   0x00
144
#define SESS_NOT_OPENED_RES_NON_EXIST 0xF0
145
#define SESS_NOT_OPENED_RES_UNAVAIL   0xF1
146
#define SESS_NOT_OPENED_RES_VER_LOWER 0xF2
147
#define SESS_NOT_OPENED_RES_BUSY      0xF3
148
149
/* status for close session */
150
0
#define SESS_CLOSED       0x00
151
#define SESS_NB_NOT_ALLOC 0xF0
152
153
/* circuit id from session number (16bit) and transport connection id * (8bit) */
154
0
#define CT_ID(s,t) ((uint32_t)(s<<8|t))
155
156
/* resource id */
157
16
#define RES_ID_TYPE_MASK 0xC0000000
158
16
#define RES_CLASS_MASK   0x3FFF0000
159
16
#define RES_TYPE_MASK    0x0000FFC0
160
16
#define RES_VER_MASK     0x0000003F
161
162
/* resource class */
163
#define RES_CLASS_RM  0x01
164
#define RES_CLASS_AP  0x02
165
#define RES_CLASS_CA  0x03
166
#define RES_CLASS_AUT 0x10
167
#define RES_CLASS_HC  0x20
168
#define RES_CLASS_DT  0x24
169
#define RES_CLASS_MMI 0x40
170
#define RES_CLASS_AMI 0x41
171
#define RES_CLASS_LSC 0x60
172
#define RES_CLASS_CC  0x8C
173
#define RES_CLASS_HLC 0x8D
174
#define RES_CLASS_CUP 0x8E
175
#define RES_CLASS_OPP 0x8F
176
#define RES_CLASS_AFS 0x91
177
#define RES_CLASS_SAS 0x96
178
179
0
#define RES_ID_LEN 4 /* bytes */
180
0
#define RES_CLASS(_res_id) (_res_id & RES_CLASS_MASK) >> 16
181
0
#define RES_VER(_res_id)   (_res_id & RES_VER_MASK)
182
183
/* appinfo resource */
184
#define APP_TYPE_CA  0x1
185
#define APP_TYPE_EPG 0x2
186
187
#define DATA_RATE_72 0x0
188
#define DATA_RATE_96 0x1
189
190
/* ca resource */
191
#define LIST_MGMT_MORE   0x0
192
#define LIST_MGMT_FIRST  0x1
193
#define LIST_MGMT_LAST   0x2
194
#define LIST_MGMT_ONLY   0x3
195
#define LIST_MGMT_ADD    0x4
196
#define LIST_MGMT_UPDATE 0x5
197
198
#define CMD_ID_OK_DESCR     0x1
199
#define CMD_ID_OK_MMI       0x2
200
#define CMD_ID_QUERY        0x3
201
#define CMD_ID_NOT_SELECTED 0x4
202
203
0
#define CA_DESC_TAG 0x9
204
205
0
#define CA_ENAB_DESC_OK             0x01
206
0
#define CA_ENAB_DESC_OK_PURCHASE    0x02
207
0
#define CA_ENAB_DESC_OK_TECH        0x03
208
#define CA_ENAB_DESC_NG_ENTITLEMENT 0x71
209
#define CA_ENAB_DESC_NG_TECH        0x73
210
211
/* host control resource */
212
0
#define HC_STAT_OK            0x0
213
#define HC_STAT_ERR_DLVRY     0x1
214
#define HC_STAT_ERR_LOCK      0x2
215
#define HC_STAT_ERR_BUSY      0x3
216
#define HC_STAT_ERR_PARAM     0x4
217
#define HC_STAT_ERR_NOT_FOUND 0x5
218
#define HC_STAT_ERR_UNKNOWN   0x6
219
220
#define HC_RELEASE_OK      0x0
221
#define HC_RELEASE_REFUSED 0x1
222
223
/* mmi resource */
224
#define CLOSE_MMI_CMD_ID_IMMEDIATE 0x0
225
0
#define CLOSE_MMI_CMD_ID_DELAY     0x1
226
227
/* only commands and parameters for high-level mmi are supported */
228
0
#define DISP_CMD_SET_MMI_MODE 1
229
#define DISP_CMD_GET_DISP_TBL 2
230
#define DISP_CMD_GET_INP_TBL  3
231
232
#define MMI_MODE_HIGH 1
233
234
0
#define DISP_REP_ID_MMI_MODE_ACK     0x01
235
0
#define DISP_REP_ID_DISP_CHAR_TBL    0x02
236
0
#define DISP_REP_ID_INP_CHAR_TBL     0x03
237
#define DISP_REP_ID_UNKNOWN_CMD      0xF0
238
#define DISP_REP_ID_UNKNOWN_MMI_MODE 0xF1
239
#define DISP_REP_ID_UNKNOWN_CHAR_TBL 0xF2
240
241
#define VISIBLE_ANS 0
242
#define BLIND_ANS   1
243
244
#define ANSW_ID_CANCEL 0x00
245
0
#define ANSW_ID_ANSWER 0x01
246
247
/* used for answer_text_length, choice_nb and item_nb */
248
0
#define NB_UNKNOWN 0xFF
249
250
/* cam upgrade resource */
251
#define CUP_DELAYED   0x0
252
#define CUP_IMMEDIATE 0x1
253
254
#define CUP_ANS_NO  0x0
255
#define CUP_ANS_YES 0x1
256
#define CUP_ANS_ASK 0x2
257
258
#define CUP_RESET_PCMCIA 0x0
259
#define CUP_RESET_CMDIF  0x1
260
#define CUP_RESET_NONE   0x2
261
262
/* content control resource */
263
0
#define CC_ID_HOST_ID            0x05
264
#define CC_ID_CICAM_ID           0x06
265
0
#define CC_ID_HOST_BRAND_CERT    0x07
266
0
#define CC_ID_CICAM_BRAND_CERT   0x08
267
0
#define CC_ID_KP                 0x0C
268
0
#define CC_ID_DHPH               0x0D
269
#define CC_ID_DHPM               0x0E
270
0
#define CC_ID_HOST_DEV_CERT      0x0F
271
0
#define CC_ID_CICAM_DEV_CERT     0x10
272
0
#define CC_ID_SIG_A              0x11
273
#define CC_ID_SIG_B              0x12
274
#define CC_ID_AUTH_NONCE         0x13
275
0
#define CC_ID_NS_HOST            0x14
276
#define CC_ID_NS_MODULE          0x15
277
0
#define CC_ID_AKH                0x16
278
0
#define CC_ID_URI                0x19
279
0
#define CC_ID_PROG_NUM           0x1A
280
0
#define CC_ID_URI_CNF            0x1B
281
0
#define CC_ID_KEY_REGISTER       0x1C
282
0
#define CC_ID_URI_VERSIONS       0x1D
283
0
#define CC_ID_STATUS_FIELD       0x1E
284
#define CC_ID_SRM_DATA           0x1F
285
0
#define CC_ID_SRM_CONFIRM        0x20
286
0
#define CC_ID_CICAM_LICENSE      0x21
287
0
#define CC_ID_LICENSE_STATUS     0x22
288
0
#define CC_ID_LICENSE_RCV_STATUS 0x23
289
#define CC_ID_HOST_LICENSE       0x24
290
0
#define CC_ID_PLAY_COUNT         0x25
291
0
#define CC_ID_OPERATING_MODE     0x26
292
#define CC_ID_PINCODE_DATA       0x27
293
0
#define CC_ID_REC_START_STATUS   0x28
294
0
#define CC_ID_MODE_CHG_STATUS    0x29
295
0
#define CC_ID_REC_STOP_STATUS    0x2A
296
297
0
#define CC_EMI_FREE    0x00
298
#define CC_EMI_NO_MORE 0x01
299
#define CC_EMI_ONCE    0x02
300
0
#define CC_EMI_NEVER   0x03
301
302
#define CC_KEY_EVEN 0x0
303
#define CC_KEY_ODD  0x1
304
305
#define CC_STATUS_OK                    0x0
306
#define CC_STATUS_NO_CC_SUPPORT         0x1
307
#define CC_STATUS_HOST_BUSY             0x2
308
#define CC_STATUS_AUTH_FAILED_OR_NO_SRM 0x3
309
#define CC_STATUS_CICAM_BUSY            0x4
310
#define CC_STATUS_REC_MODE_ERR          0x5
311
312
0
#define SAC_MSG_HDR_LEN 8
313
314
#define CC_SAC_AUTH_AES128_XCBC_MAC 0x0
315
0
#define CC_SAC_ENC_AES128_CBC       0x0
316
317
#define CC_CAP_NONE               0x0
318
#define CC_CAP_CAS_PIN            0x1
319
#define CC_CAP_CAS_FTA_PIN        0x2
320
#define CC_CAP_CAS_PIN_CACHED     0x3
321
#define CC_CAP_CAS_FTA_PIN_CACHED 0x4
322
323
/* length of DVB-SI utc time field in bytes */
324
0
#define UTC_TIME_LEN 5
325
326
#define CC_PIN_BAD         0x0
327
#define CC_PIN_CAM_BUSY    0x1
328
#define CC_PIN_OK          0x2
329
#define CC_PIN_UNCONFIRMED 0x3
330
#define CC_PIN_VB_NOT_REQ  0x4
331
#define CC_PIN_CSA         0x5
332
333
#define CC_OP_MODE_WATCH_BUFFER 0x0
334
#define CC_OP_MODE_TIMESHIFT    0x1
335
#define CC_OP_MODE_UNATTENDED   0x2
336
337
/* application mmi resource */
338
#define ACK_CODE_OK        0x1
339
#define ACK_CODE_WRONG_API 0x2
340
#define ACK_CODE_API_BUSY  0x3
341
342
0
#define REQ_TYPE_FILE      0x0
343
0
#define REQ_TYPE_DATA      0x1
344
0
#define REQ_TYPE_FILE_HASH 0x2
345
0
#define REQ_TYPE_REQ       0x3
346
347
/* lsc resource */
348
0
#define COMMS_CMD_ID_CONNECT_ON_CHANNEL    1
349
0
#define COMMS_CMD_ID_DISCONNECT_ON_CHANNEL 2
350
0
#define COMMS_CMD_ID_SET_PARAMS            3
351
0
#define COMMS_CMD_ID_ENQUIRE_STATUS        4
352
0
#define COMMS_CMD_ID_GET_NEXT_BUFFER       5
353
354
#define CONN_DESC_TEL      1
355
#define CONN_DESC_CABLE    2
356
0
#define CONN_DESC_IP       3
357
0
#define CONN_DESC_HOSTNAME 4
358
359
#define LSC_DESC_IP       0xCF
360
#define LSC_DESC_HOSTNAME 0xCD
361
362
0
#define LSC_IPV4 1
363
0
#define LSC_IPV6 2
364
365
0
#define LSC_TCP 1
366
0
#define LSC_UDP 2
367
368
#define COMMS_REP_ID_CONNECT_ACK         1
369
#define COMMS_REP_ID_DISCONNECT_ACK      2
370
0
#define COMMS_REP_ID_SET_PARAMS_ACK      3
371
0
#define COMMS_REP_ID_STATUS_REPLY        4
372
#define COMMS_REP_ID_GET_NEXT_BUFFER_ACK 5
373
0
#define COMMS_REP_ID_SEND_ACK            6
374
375
#define LSC_RET_OK 0
376
#define LSC_DISCONNECTED 0
377
0
#define LSC_CONNECTED    1
378
#define LSC_RET_TOO_BIG 0xFE
379
380
/* auxiliary file system resource */
381
#define AFS_ACK_RSV     0
382
#define AFS_ACK_OK      1
383
#define AFS_ACK_UNKNOWN 2
384
385
/* operator profile resource */
386
0
#define TABLE_ID_CICAM_NIT 0x40  /* CICAM NIT must be a NIT actual */
387
388
#define OPP_REF_REG_FLG_NONE  0
389
#define OPP_REF_REG_FLG_ADV   1
390
#define OPP_REF_REG_FLG_URG   2
391
#define OPP_REF_REG_FLG_SCHED 3
392
393
#define OPP_ERR_FLG_OK          0
394
#define OPP_ERR_FLG_PROF        1
395
#define OPP_ERR_FLG_UNSUPPORTED 2
396
#define OPP_ERR_FLG_CANCELLED   3
397
398
/* EIT p/f, EIT schedule usage */
399
#define OPP_EIT_ABSENT 0
400
#define OPP_EIT_NOT_X  1
401
#define OPP_EIT_FULL_X 2
402
#define OPP_EIT_BARKER 3
403
#define OPP_EPG_APP    4
404
405
#define OPP_EXT_EVT_DIFF 0
406
#define OPP_EXT_EVT_ADD  1
407
408
/* these values match the delivery system descriptor tags */
409
#define OPP_DLV_CAP_S  0x43
410
#define OPP_DLV_CAP_C  0x44
411
#define OPP_DLV_CAP_T  0x5A
412
#define OPP_DLV_CAP_S2 0x79
413
414
#define OPP_TUNE_OK          0
415
#define OPP_TUNE_UNSUPPORTED 1
416
#define OPP_TUNE_INVALID     2
417
#define OPP_TUNE_ERR         3
418
419
0
#define OPP_NO_MORE_DESC 0xFF
420
421
/* sas resource */
422
0
#define SAS_SESS_STATE_CONNECTED 0
423
#define SAS_SESS_STATE_NOT_FOUND 1
424
#define SAS_SESS_STATE_DENIED    2
425
426
427
/* application layer */
428
429
0
#define APDU_TAG_SIZE 3
430
431
/* "don't care" value for min_len_field and len_field (this can't be 0) */
432
0
#define LEN_FIELD_ANY UINT32_MAX
433
434
static GHashTable *apdu_table;
435
436
typedef struct _apdu_info_t {
437
    uint32_t tag;
438
    /* the minimum length required for this apdu */
439
    uint32_t min_len_field;
440
    /* if the apdu has a well-known length, we enforce it here
441
     * (otherwise, we set this to LEN_FIELD_ANY) */
442
    uint32_t len_field;
443
    uint8_t direction;
444
    uint16_t res_class;
445
    uint8_t res_min_ver;
446
    void (*dissect_payload)(uint32_t, int,
447
            tvbuff_t *, unsigned offset, conversation_t *, packet_info *, proto_tree *);
448
} apdu_info_t;
449
450
451
static void
452
dissect_dvbci_payload_rm(uint32_t tag, int len_field,
453
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
454
        packet_info *pinfo, proto_tree *tree);
455
static void
456
dissect_dvbci_payload_ap(uint32_t tag, int len_field _U_,
457
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
458
        packet_info *pinfo, proto_tree *tree);
459
static void
460
dissect_dvbci_payload_ca(uint32_t tag, int len_field,
461
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
462
        packet_info *pinfo, proto_tree *tree);
463
static void
464
dissect_dvbci_payload_aut(uint32_t tag, int len_field _U_,
465
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
466
        packet_info *pinfo _U_, proto_tree *tree);
467
static void
468
dissect_dvbci_payload_hc(uint32_t tag, int len_field _U_,
469
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
470
        packet_info *pinfo, proto_tree *tree);
471
static void
472
dissect_dvbci_payload_dt(uint32_t tag, int len_field,
473
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
474
        packet_info *pinfo, proto_tree *tree);
475
static void
476
dissect_dvbci_payload_mmi(uint32_t tag, int len_field,
477
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
478
        packet_info *pinfo, proto_tree *tree);
479
static void
480
dissect_dvbci_payload_hlc(uint32_t tag, int len_field _U_,
481
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
482
        packet_info *pinfo, proto_tree *tree);
483
static void
484
dissect_dvbci_payload_cup(uint32_t tag, int len_field _U_,
485
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
486
        packet_info *pinfo, proto_tree *tree);
487
static void
488
dissect_dvbci_payload_cc(uint32_t tag, int len_field _U_,
489
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
490
        packet_info *pinfo, proto_tree *tree);
491
static void
492
dissect_dvbci_payload_ami(uint32_t tag, int len_field _U_,
493
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
494
        packet_info *pinfo, proto_tree *tree);
495
static void
496
dissect_dvbci_payload_lsc(uint32_t tag, int len_field,
497
        tvbuff_t *tvb, unsigned offset, conversation_t *conv,
498
        packet_info *pinfo, proto_tree *tree);
499
static void
500
dissect_dvbci_payload_opp(uint32_t tag, int len_field _U_,
501
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
502
        packet_info *pinfo, proto_tree *tree);
503
static void
504
dissect_dvbci_payload_afs(uint32_t tag, int len_field _U_,
505
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
506
        packet_info *pinfo, proto_tree *tree);
507
static void
508
dissect_dvbci_payload_sas(uint32_t tag, int len_field _U_,
509
        tvbuff_t *tvb, unsigned offset, conversation_t *conv,
510
        packet_info *pinfo, proto_tree *tree);
511
512
513
/* apdu defines */
514
#define T_PROFILE_ENQ                   0x9F8010
515
0
#define T_PROFILE                       0x9F8011
516
#define T_PROFILE_CHANGE                0x9F8012
517
#define T_APP_INFO_ENQ                  0x9F8020
518
0
#define T_APP_INFO                      0x9F8021
519
#define T_ENTER_MENU                    0x9F8022
520
#define T_REQUEST_CICAM_RESET           0x9F8023
521
0
#define T_DATARATE_INFO                 0x9F8024
522
#define T_CA_INFO_ENQ                   0x9F8030
523
0
#define T_CA_INFO                       0x9F8031
524
0
#define T_CA_PMT                        0x9F8032
525
0
#define T_CA_PMT_REPLY                  0x9F8033
526
0
#define T_AUTH_REQ                      0x9F8200
527
0
#define T_AUTH_RESP                     0x9F8201
528
0
#define T_TUNE                          0x9F8400
529
0
#define T_REPLACE                       0x9F8401
530
0
#define T_CLEAR_REPLACE                 0x9F8402
531
#define T_ASK_RELEASE                   0x9F8403
532
0
#define T_TUNE_BROADCAST_REQ            0x9F8404
533
0
#define T_TUNE_REPLY                    0x9F8405
534
0
#define T_ASK_RELEASE_REPLY             0x9F8406
535
#define T_TUNE_LCN_REQ                  0x9F8407
536
#define T_TUNE_IP_REQ                   0x9F8408
537
#define T_TUNE_TRIPLET_REQ              0x9F8409
538
#define T_TUNE_STATUS_REQ               0x9F840A
539
#define T_TUNE_STATUS_REPLY             0x9F840B
540
0
#define T_DATE_TIME_ENQ                 0x9F8440
541
0
#define T_DATE_TIME                     0x9F8441
542
0
#define T_CLOSE_MMI                     0x9F8800
543
0
#define T_DISPLAY_CONTROL               0x9F8801
544
0
#define T_DISPLAY_REPLY                 0x9F8802
545
0
#define T_ENQ                           0x9F8807
546
0
#define T_ANSW                          0x9F8808
547
0
#define T_MENU_LAST                     0x9F8809
548
0
#define T_MENU_MORE                     0x9F880A
549
0
#define T_MENU_ANSW                     0x9F880B
550
0
#define T_LIST_LAST                     0x9F880C
551
0
#define T_LIST_MORE                     0x9F880D
552
#define T_HOST_COUNTRY_ENQ              0x9F8100
553
0
#define T_HOST_COUNTRY                  0x9F8101
554
#define T_HOST_LANGUAGE_ENQ             0x9F8110
555
0
#define T_HOST_LANGUAGE                 0x9F8111
556
0
#define T_CAM_FIRMWARE_UPGRADE          0x9F9D01
557
0
#define T_CAM_FIRMWARE_UPGRADE_REPLY    0x9F9D02
558
0
#define T_CAM_FIRMWARE_UPGRADE_PROGRESS 0x9F9D03
559
0
#define T_CAM_FIRMWARE_UPGRADE_COMPLETE 0x9F9D04
560
#define T_CC_OPEN_REQ                   0x9F9001
561
0
#define T_CC_OPEN_CNF                   0x9F9002
562
0
#define T_CC_DATA_REQ                   0x9F9003
563
0
#define T_CC_DATA_CNF                   0x9F9004
564
#define T_CC_SYNC_REQ                   0x9F9005
565
0
#define T_CC_SYNC_CNF                   0x9F9006
566
0
#define T_CC_SAC_DATA_REQ               0x9F9007
567
0
#define T_CC_SAC_DATA_CNF               0x9F9008
568
0
#define T_CC_SAC_SYNC_REQ               0x9F9009
569
0
#define T_CC_SAC_SYNC_CNF               0x9F9010
570
#define T_CC_PIN_CAPABILITIES_REQ       0x9F9011
571
0
#define T_CC_PIN_CAPABILITIES_REPLY     0x9F9012
572
0
#define T_CC_PIN_CMD                    0x9F9013
573
0
#define T_CC_PIN_REPLY                  0x9F9014
574
0
#define T_CC_PIN_EVENT                  0x9F9015
575
0
#define T_CC_PIN_PLAYBACK               0x9F9016
576
0
#define T_CC_PIN_MMI_REQ                0x9F9017
577
0
#define T_REQUEST_START                 0x9F8000
578
0
#define T_REQUEST_START_ACK             0x9F8001
579
0
#define T_FILE_REQUEST                  0x9F8002
580
0
#define T_FILE_ACKNOWLEDGE              0x9F8003
581
0
#define T_APP_ABORT_REQUEST             0x9F8004
582
0
#define T_APP_ABORT_ACK                 0x9F8005
583
0
#define T_COMMS_CMD                     0x9F8C00
584
0
#define T_COMMS_REPLY                   0x9F8C02
585
0
#define T_COMMS_SEND_LAST               0x9F8C03
586
0
#define T_COMMS_SEND_MORE               0x9F8C04
587
0
#define T_COMMS_RCV_LAST                0x9F8C05
588
0
#define T_COMMS_RCV_MORE                0x9F8C06
589
#define T_COMMS_IP_CONFIG_REQ           0x9F8C09
590
0
#define T_COMMS_IP_CONFIG_REPLY         0x9F8C0A
591
0
#define T_AFS_FILE_SYSTEM_OFFER         0x9F9400
592
0
#define T_AFS_FILE_SYSTEM_ACK           0x9F9401
593
0
#define T_AFS_FILE_REQUEST              0x9F9402
594
0
#define T_AFS_FILE_ACKNOWLEDGE          0x9F9403
595
#define T_OPERATOR_STATUS_REQ           0x9F9C00
596
0
#define T_OPERATOR_STATUS               0x9F9C01
597
#define T_OPERATOR_NIT_REQ              0x9F9C02
598
0
#define T_OPERATOR_NIT                  0x9F9C03
599
#define T_OPERATOR_INFO_REQ             0x9F9C04
600
0
#define T_OPERATOR_INFO                 0x9F9C05
601
0
#define T_OPERATOR_SEARCH_START         0x9F9C06
602
0
#define T_OPERATOR_SEARCH_STATUS        0x9F9C07
603
#define T_OPERATOR_EXIT                 0x9F9C08
604
0
#define T_OPERATOR_TUNE                 0x9F9C09
605
0
#define T_OPERATOR_TUNE_STATUS          0x9F9C0A
606
#define T_OPERATOR_ENTITLEMENT_ACK      0x9F9C0B
607
#define T_OPERATOR_SEARCH_CANCEL        0x9F9C0C
608
0
#define T_SAS_CONNECT_RQST              0x9F9A00
609
0
#define T_SAS_CONNECT_CNF               0x9F9A01
610
0
#define T_SAS_ASYNC_MSG                 0x9F9A07
611
612
/* these are no real apdus, they just use the same format */
613
0
#define T_TEXT_LAST             0x9F8803
614
0
#define T_TEXT_MORE             0x9F8804
615
0
#define T_CONNECTION_DESCRIPTOR 0x9F8C01
616
617
0
#define IS_MENU_APDU(t) (t==T_MENU_MORE || t==T_MENU_LAST)
618
619
620
static const apdu_info_t apdu_info[] = {
621
    {T_PROFILE_ENQ,         0, 0,             DIRECTION_ANY,    RES_CLASS_RM, 1, NULL},
622
    {T_PROFILE,             0, LEN_FIELD_ANY, DIRECTION_ANY,    RES_CLASS_RM, 1, dissect_dvbci_payload_rm},
623
    {T_PROFILE_CHANGE,      0, 0,             DIRECTION_ANY,    RES_CLASS_RM, 1, NULL},
624
625
    {T_APP_INFO_ENQ,        0, 0,             DATA_HOST_TO_CAM, RES_CLASS_AP, 1, NULL},
626
    {T_APP_INFO,            6, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_AP, 1, dissect_dvbci_payload_ap},
627
    {T_ENTER_MENU,          0, 0,             DATA_HOST_TO_CAM, RES_CLASS_AP, 1, NULL},
628
    {T_REQUEST_CICAM_RESET, 0, 0,             DATA_CAM_TO_HOST, RES_CLASS_AP, 3, NULL},
629
    {T_DATARATE_INFO,       0, 1,             DATA_HOST_TO_CAM, RES_CLASS_AP, 3, dissect_dvbci_payload_ap},
630
631
    {T_CA_INFO_ENQ,         0, 0,             DATA_HOST_TO_CAM, RES_CLASS_CA, 1, NULL},
632
    {T_CA_INFO,             0, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_CA, 1, dissect_dvbci_payload_ca},
633
    {T_CA_PMT,              6, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_CA, 1, dissect_dvbci_payload_ca},
634
    {T_CA_PMT_REPLY,        8, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_CA, 1, dissect_dvbci_payload_ca},
635
636
    {T_AUTH_REQ,            2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_AUT, 1, dissect_dvbci_payload_aut},
637
    {T_AUTH_RESP,           2, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_AUT, 1, dissect_dvbci_payload_aut},
638
639
    {T_TUNE,                0, 8,             DATA_CAM_TO_HOST, RES_CLASS_HC, 1, dissect_dvbci_payload_hc},
640
    {T_REPLACE,             0, 5,             DATA_CAM_TO_HOST, RES_CLASS_HC, 1, dissect_dvbci_payload_hc},
641
    {T_CLEAR_REPLACE,       0, 1,             DATA_CAM_TO_HOST, RES_CLASS_HC, 1, dissect_dvbci_payload_hc},
642
    {T_ASK_RELEASE,         0, 0,             DATA_HOST_TO_CAM, RES_CLASS_HC, 1, NULL},
643
    {T_TUNE_BROADCAST_REQ,  5, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_HC, 2, dissect_dvbci_payload_hc},
644
    {T_TUNE_REPLY,          1, 1,             DATA_HOST_TO_CAM, RES_CLASS_HC, 2, dissect_dvbci_payload_hc},
645
    {T_ASK_RELEASE_REPLY,   1, 1,             DATA_CAM_TO_HOST, RES_CLASS_HC, 2, dissect_dvbci_payload_hc},
646
647
    {T_DATE_TIME_ENQ,       0, 1,             DATA_CAM_TO_HOST, RES_CLASS_DT, 1, dissect_dvbci_payload_dt},
648
    {T_DATE_TIME,           5, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_DT, 1, dissect_dvbci_payload_dt},
649
650
    {T_CLOSE_MMI,           1, LEN_FIELD_ANY, DIRECTION_ANY,    RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
651
    {T_DISPLAY_CONTROL,     1, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
652
    {T_DISPLAY_REPLY,       1, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
653
    {T_ENQ,                 2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
654
    {T_ANSW,                1, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
655
    {T_MENU_LAST,          13, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
656
    {T_MENU_MORE,          13, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
657
    {T_MENU_ANSW,           0, 1,             DATA_HOST_TO_CAM, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
658
    {T_LIST_LAST,          13, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
659
    {T_LIST_MORE,          13, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
660
661
    {T_HOST_COUNTRY_ENQ,    0, 0,             DATA_CAM_TO_HOST, RES_CLASS_HLC, 1, NULL},
662
    {T_HOST_COUNTRY,        0, 3,             DATA_HOST_TO_CAM, RES_CLASS_HLC, 1, dissect_dvbci_payload_hlc},
663
    {T_HOST_LANGUAGE_ENQ,   0, 0,             DATA_CAM_TO_HOST, RES_CLASS_HLC, 1, NULL},
664
    {T_HOST_LANGUAGE,       0, 3,             DATA_HOST_TO_CAM, RES_CLASS_HLC, 1, dissect_dvbci_payload_hlc},
665
666
    {T_CAM_FIRMWARE_UPGRADE,          0, 3, DATA_CAM_TO_HOST, RES_CLASS_CUP, 1, dissect_dvbci_payload_cup},
667
    {T_CAM_FIRMWARE_UPGRADE_REPLY,    0, 1, DATA_HOST_TO_CAM, RES_CLASS_CUP, 1, dissect_dvbci_payload_cup},
668
    {T_CAM_FIRMWARE_UPGRADE_PROGRESS, 0, 1, DATA_CAM_TO_HOST, RES_CLASS_CUP, 1, dissect_dvbci_payload_cup},
669
    {T_CAM_FIRMWARE_UPGRADE_COMPLETE, 0, 1, DATA_CAM_TO_HOST, RES_CLASS_CUP, 1, dissect_dvbci_payload_cup},
670
671
    {T_CC_OPEN_REQ,                0,  0,             DATA_CAM_TO_HOST, RES_CLASS_CC, 1, NULL},
672
    {T_CC_OPEN_CNF,                0,  1,             DATA_HOST_TO_CAM, RES_CLASS_CC, 1, dissect_dvbci_payload_cc},
673
    {T_CC_DATA_REQ,                3,  LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_CC, 1, dissect_dvbci_payload_cc},
674
    {T_CC_DATA_CNF,                2,  LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_CC, 1, dissect_dvbci_payload_cc},
675
    {T_CC_SYNC_REQ,                0,  0,             DATA_CAM_TO_HOST, RES_CLASS_CC, 1, NULL},
676
    {T_CC_SYNC_CNF,                0,  1,             DATA_HOST_TO_CAM, RES_CLASS_CC, 1, dissect_dvbci_payload_cc},
677
    {T_CC_SAC_DATA_REQ,            8,  LEN_FIELD_ANY, DIRECTION_ANY,    RES_CLASS_CC, 1, dissect_dvbci_payload_cc},
678
    {T_CC_SAC_DATA_CNF,            8,  LEN_FIELD_ANY, DIRECTION_ANY,    RES_CLASS_CC, 1, dissect_dvbci_payload_cc},
679
    {T_CC_SAC_SYNC_REQ,            8,  LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_CC, 1, dissect_dvbci_payload_cc},
680
    {T_CC_SAC_SYNC_CNF,            8,  LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_CC, 1, dissect_dvbci_payload_cc},
681
    {T_CC_PIN_CAPABILITIES_REQ,    0,  0,             DATA_HOST_TO_CAM, RES_CLASS_CC, 2, NULL},
682
    {T_CC_PIN_CAPABILITIES_REPLY,  7,  7,             DATA_CAM_TO_HOST, RES_CLASS_CC, 2, dissect_dvbci_payload_cc},
683
    {T_CC_PIN_CMD,                 1,  LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_CC, 2, dissect_dvbci_payload_cc},
684
    {T_CC_PIN_REPLY,               1,  1,             DATA_CAM_TO_HOST, RES_CLASS_CC, 2, dissect_dvbci_payload_cc},
685
    {T_CC_PIN_EVENT,              25, 25,             DATA_CAM_TO_HOST, RES_CLASS_CC, 2, dissect_dvbci_payload_cc},
686
    {T_CC_PIN_PLAYBACK,           16, 16,             DATA_HOST_TO_CAM, RES_CLASS_CC, 2, dissect_dvbci_payload_cc},
687
    {T_CC_PIN_MMI_REQ,             1,  LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_CC, 2, dissect_dvbci_payload_cc},
688
689
    {T_REQUEST_START,       2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_AMI, 1, dissect_dvbci_payload_ami},
690
    {T_REQUEST_START_ACK,   0, 1,             DATA_HOST_TO_CAM, RES_CLASS_AMI, 1, dissect_dvbci_payload_ami},
691
    {T_FILE_REQUEST,        1, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_AMI, 1, dissect_dvbci_payload_ami},
692
    {T_FILE_ACKNOWLEDGE,    2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_AMI, 1, dissect_dvbci_payload_ami},
693
    {T_APP_ABORT_REQUEST,   0, LEN_FIELD_ANY, DIRECTION_ANY,    RES_CLASS_AMI, 1, dissect_dvbci_payload_ami},
694
    {T_APP_ABORT_ACK,       0, LEN_FIELD_ANY, DIRECTION_ANY,    RES_CLASS_AMI, 1, dissect_dvbci_payload_ami},
695
696
    {T_COMMS_CMD,             1, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_LSC, 1, dissect_dvbci_payload_lsc},
697
    {T_COMMS_REPLY,           0, 2,             DATA_HOST_TO_CAM, RES_CLASS_LSC, 1, dissect_dvbci_payload_lsc},
698
    {T_COMMS_SEND_LAST,       2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_LSC, 1, dissect_dvbci_payload_lsc},
699
    {T_COMMS_SEND_MORE,       2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_LSC, 1, dissect_dvbci_payload_lsc},
700
    {T_COMMS_RCV_LAST,        2, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_LSC, 1, dissect_dvbci_payload_lsc},
701
    {T_COMMS_RCV_MORE,        2, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_LSC, 1, dissect_dvbci_payload_lsc},
702
    {T_COMMS_IP_CONFIG_REQ,   0, 0,             DATA_CAM_TO_HOST, RES_CLASS_LSC, 4, NULL},
703
    {T_COMMS_IP_CONFIG_REPLY, 2, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_LSC, 4, dissect_dvbci_payload_lsc},
704
705
    {T_AFS_FILE_SYSTEM_OFFER, 1, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_AFS, 1, dissect_dvbci_payload_afs},
706
    {T_AFS_FILE_SYSTEM_ACK,   1, 1,             DATA_HOST_TO_CAM, RES_CLASS_AFS, 1, dissect_dvbci_payload_afs},
707
    {T_AFS_FILE_REQUEST,      1, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_AFS, 1, dissect_dvbci_payload_afs},
708
    {T_AFS_FILE_ACKNOWLEDGE,  2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_AFS, 1, dissect_dvbci_payload_afs},
709
710
    {T_OPERATOR_STATUS_REQ,       0, 0,             DATA_HOST_TO_CAM, RES_CLASS_OPP, 1, NULL},
711
    {T_OPERATOR_STATUS,           0, 6,             DATA_CAM_TO_HOST, RES_CLASS_OPP, 1, dissect_dvbci_payload_opp},
712
    {T_OPERATOR_NIT_REQ,          0, 0,             DATA_HOST_TO_CAM, RES_CLASS_OPP, 1, NULL},
713
    {T_OPERATOR_NIT,              2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_OPP, 1, dissect_dvbci_payload_opp},
714
    {T_OPERATOR_INFO_REQ,         0, 0,             DATA_HOST_TO_CAM, RES_CLASS_OPP, 1, NULL},
715
    {T_OPERATOR_INFO,             1, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_OPP, 1, dissect_dvbci_payload_opp},
716
    {T_OPERATOR_SEARCH_START,     3, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_OPP, 1, dissect_dvbci_payload_opp},
717
    {T_OPERATOR_SEARCH_STATUS,    0, 6,             DATA_CAM_TO_HOST, RES_CLASS_OPP, 1, dissect_dvbci_payload_opp},
718
    {T_OPERATOR_EXIT,             0, 0,             DATA_HOST_TO_CAM, RES_CLASS_OPP, 1, NULL},
719
    {T_OPERATOR_TUNE,             2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_OPP, 1, dissect_dvbci_payload_opp},
720
    {T_OPERATOR_TUNE_STATUS,      5, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_OPP, 1, dissect_dvbci_payload_opp},
721
    {T_OPERATOR_ENTITLEMENT_ACK,  0, 0,             DATA_HOST_TO_CAM, RES_CLASS_OPP, 1, NULL},
722
    {T_OPERATOR_SEARCH_CANCEL,    0, 0,             DATA_HOST_TO_CAM, RES_CLASS_OPP, 1, NULL},
723
724
    {T_SAS_CONNECT_RQST,    0, 8,             DATA_HOST_TO_CAM, RES_CLASS_SAS, 1, dissect_dvbci_payload_sas},
725
    {T_SAS_CONNECT_CNF,     0, 9,             DATA_CAM_TO_HOST, RES_CLASS_SAS, 1, dissect_dvbci_payload_sas},
726
    {T_SAS_ASYNC_MSG,       3, LEN_FIELD_ANY, DIRECTION_ANY,    RES_CLASS_SAS, 1, dissect_dvbci_payload_sas}
727
};
728
729
static const value_string dvbci_apdu_tag[] = {
730
    { T_PROFILE_ENQ,                   "Profile enquiry" },
731
    { T_PROFILE,                       "Profile information" },
732
    { T_PROFILE_CHANGE,                "Profile change notification" },
733
    { T_APP_INFO_ENQ,                  "Application info enquiry" },
734
    { T_APP_INFO,                      "Application info" },
735
    { T_ENTER_MENU,                    "Enter menu" },
736
    { T_REQUEST_CICAM_RESET,           "Request CICAM reset" },
737
    { T_DATARATE_INFO,                 "Datarate info" },
738
    { T_CA_INFO_ENQ,                   "CA info enquiry" },
739
    { T_CA_INFO,                       "CA info" },
740
    { T_CA_PMT,                        "CA PMT" },
741
    { T_CA_PMT_REPLY,                  "CA PMT reply" },
742
    { T_AUTH_REQ,                      "Authentication request" },
743
    { T_AUTH_RESP,                     "Authentication response" },
744
    { T_TUNE,                          "Tune" },
745
    { T_REPLACE,                       "Replace" },
746
    { T_CLEAR_REPLACE,                 "Clear replace" },
747
    { T_ASK_RELEASE,                   "Ask release" },
748
    { T_TUNE_BROADCAST_REQ,            "Tune broadcast request" },
749
    { T_TUNE_REPLY,                    "Tune reply" },
750
    { T_ASK_RELEASE_REPLY,             "Ask release reply" },
751
    { T_TUNE_LCN_REQ,                  "Tune LCN request" },
752
    { T_TUNE_IP_REQ,                   "Tune IP request" },
753
    { T_TUNE_TRIPLET_REQ,              "Tune triplet request" },
754
    { T_TUNE_STATUS_REQ,               "Tune status request" },
755
    { T_TUNE_STATUS_REPLY,             "Tune status reply" },
756
    { T_DATE_TIME_ENQ,                 "Date-Time enquiry" },
757
    { T_DATE_TIME,                     "Date-Time" },
758
    { T_CLOSE_MMI,                     "Close MMI" },
759
    { T_DISPLAY_CONTROL,               "Display control" },
760
    { T_DISPLAY_REPLY,                 "Display reply" },
761
    { T_TEXT_LAST,                     "Text last" },
762
    { T_TEXT_MORE,                     "Text more" },
763
    { T_ENQ,                           "Enquiry" },
764
    { T_ANSW,                          "Answer" },
765
    { T_MENU_LAST,                     "Menu last" },
766
    { T_MENU_MORE,                     "Menu more" },
767
    { T_MENU_ANSW,                     "Menu answer" },
768
    { T_LIST_LAST,                     "List last" },
769
    { T_LIST_MORE,                     "List more" },
770
    { T_HOST_COUNTRY_ENQ,              "Host country enquiry" },
771
    { T_HOST_COUNTRY,                  "Host country" },
772
    { T_HOST_LANGUAGE_ENQ,             "Host language enquiry" },
773
    { T_HOST_LANGUAGE,                 "Host language" },
774
    { T_CAM_FIRMWARE_UPGRADE,          "CAM firmware upgrade" },
775
    { T_CAM_FIRMWARE_UPGRADE_REPLY,    "CAM firmware upgrade reply" },
776
    { T_CAM_FIRMWARE_UPGRADE_PROGRESS, "CAM firmware upgrade progress" },
777
    { T_CAM_FIRMWARE_UPGRADE_COMPLETE, "CAM firmware upgrade complete" },
778
    { T_CC_OPEN_REQ,                   "CC open request" },
779
    { T_CC_OPEN_CNF,                   "CC open confirm" },
780
    { T_CC_DATA_REQ,                   "CC data request" },
781
    { T_CC_DATA_CNF,                   "CC data confirm" },
782
    { T_CC_SYNC_REQ,                   "CC sync request" },
783
    { T_CC_SYNC_CNF,                   "CC sync confirm" },
784
    { T_CC_SAC_DATA_REQ,               "CC SAC data request" },
785
    { T_CC_SAC_DATA_CNF,               "CC SAC data confirm" },
786
    { T_CC_SAC_SYNC_REQ,               "CC SAC sync request" },
787
    { T_CC_SAC_SYNC_CNF,               "CC SAC sync confirm" },
788
    { T_CC_PIN_CAPABILITIES_REQ,       "CC PIN capabilities request" },
789
    { T_CC_PIN_CAPABILITIES_REPLY,     "CC PIN capabilities reply" },
790
    { T_CC_PIN_CMD,                    "CC PIN command" },
791
    { T_CC_PIN_REPLY,                  "CC PIN reply" },
792
    { T_CC_PIN_EVENT,                  "CC PIN event" },
793
    { T_CC_PIN_PLAYBACK,               "CC PIN playback" },
794
    { T_CC_PIN_MMI_REQ,                "CC PIN MMI request" },
795
    { T_REQUEST_START,                 "Request start" },
796
    { T_REQUEST_START_ACK,             "Request start ack" },
797
    { T_FILE_REQUEST,                  "File request" },
798
    { T_FILE_ACKNOWLEDGE,              "File acknowledge" },
799
    { T_APP_ABORT_REQUEST,             "App abort request" },
800
    { T_APP_ABORT_ACK,                 "App abort ack" },
801
    { T_COMMS_CMD,                     "Comms command" },
802
    { T_COMMS_REPLY,                   "Comms reply" },
803
    { T_CONNECTION_DESCRIPTOR,         "Connection descriptor" },
804
    { T_COMMS_SEND_LAST,               "Comms send last" },
805
    { T_COMMS_SEND_MORE,               "Comms send more" },
806
    { T_COMMS_RCV_LAST,                "Comms receive last" },
807
    { T_COMMS_RCV_MORE,                "Comms receive more" },
808
    { T_COMMS_IP_CONFIG_REQ,           "Comms IP config request" },
809
    { T_COMMS_IP_CONFIG_REPLY,         "Comms IP config reply" },
810
    { T_AFS_FILE_SYSTEM_OFFER,         "File system offer" },
811
    { T_AFS_FILE_SYSTEM_ACK,           "File system ack" },
812
    { T_AFS_FILE_REQUEST,              "File request" },
813
    { T_AFS_FILE_ACKNOWLEDGE,          "File acknowledge" },
814
    { T_OPERATOR_STATUS_REQ,           "Operator status request" },
815
    { T_OPERATOR_STATUS,               "Operator status" },
816
    { T_OPERATOR_NIT_REQ,              "Operator NIT request" },
817
    { T_OPERATOR_NIT,                  "Operator NIT" },
818
    { T_OPERATOR_INFO_REQ,             "Operator info request" },
819
    { T_OPERATOR_INFO,                 "Operator info" },
820
    { T_OPERATOR_SEARCH_START,         "Operator search start" },
821
    { T_OPERATOR_SEARCH_STATUS,        "Operator search status" },
822
    { T_OPERATOR_EXIT,                 "Operator exit" },
823
    { T_OPERATOR_TUNE,                 "Operator tune" },
824
    { T_OPERATOR_TUNE_STATUS,          "Operator tune status" },
825
    { T_OPERATOR_ENTITLEMENT_ACK,      "Operator entitlement acknowledge" },
826
    { T_OPERATOR_SEARCH_CANCEL,        "Operator search cancel" },
827
    { T_SAS_CONNECT_RQST,              "SAS connect request" },
828
    { T_SAS_CONNECT_CNF,               "SAS connect confirm" },
829
    { T_SAS_ASYNC_MSG,                 "SAS async message" },
830
    { 0, NULL }
831
};
832
833
WS_DLL_PUBLIC_DEF const value_string dvbci_event[] = {
834
    { DVBCI_EVT_DATA_HOST_TO_CAM, "data transfer Host -> CAM" },
835
    { DVBCI_EVT_DATA_CAM_TO_HOST, "data transfer CAM -> Host" },
836
    { DVBCI_EVT_CIS_READ,         "read the Card Information Structure (CIS)" },
837
    { DVBCI_EVT_COR_WRITE,        "write into the Configuration Option Register (COR)" },
838
    { DVBCI_EVT_HW_EVT,           "hardware event" },
839
    { 0, NULL }
840
};
841
842
static int proto_dvbci;
843
844
static dissector_handle_t dvbci_handle;
845
846
static const char *dvbci_sek;
847
static const char *dvbci_siv;
848
static bool dvbci_dissect_lsc_msg;
849
850
/* the output of pref_key_string_to_bin() applied to dvbci_sek and _siv */
851
static unsigned char *dvbci_sek_bin;
852
static unsigned char *dvbci_siv_bin;
853
854
static dissector_handle_t data_handle;
855
static dissector_handle_t mpeg_pmt_handle;
856
static dissector_handle_t dvb_nit_handle;
857
static dissector_handle_t mime_handle;
858
static dissector_table_t tcp_dissector_table;
859
static dissector_table_t udp_dissector_table;
860
861
static int exported_pdu_tap = -1;
862
863
static int ett_dvbci;
864
static int ett_dvbci_hdr;
865
static int ett_dvbci_cis;
866
static int ett_dvbci_cis_tpl;
867
static int ett_dvbci_cis_subtpl;
868
static int ett_dvbci_link;
869
static int ett_dvbci_link_frag;
870
static int ett_dvbci_link_frags;
871
static int ett_dvbci_transport;
872
static int ett_dvbci_transport_frag;
873
static int ett_dvbci_transport_frags;
874
static int ett_dvbci_session;
875
static int ett_dvbci_res;
876
static int ett_dvbci_application;
877
static int ett_dvbci_es;
878
static int ett_dvbci_ca_desc;
879
static int ett_dvbci_text;
880
static int ett_dvbci_cc_item;
881
static int ett_dvbci_sac_msg_body;
882
static int ett_dvbci_ami_req_types;
883
static int ett_dvbci_lsc_conn_desc;
884
static int ett_dvbci_opp_cap_loop;
885
static int ett_dvbci_dlv_sys_hint;
886
887
888
static int hf_dvbci_hdr_ver;
889
static int hf_dvbci_event;
890
static int hf_dvbci_len;
891
static int hf_dvbci_hw_event;
892
static int hf_dvbci_cor_addr;
893
static int hf_dvbci_cor_val;
894
static int hf_dvbci_cis_tpl_code;
895
static int hf_dvbci_cis_tpl_len;
896
static int hf_dvbci_cis_tpl_data;
897
static int hf_dvbci_cis_tpll_v1_major;
898
static int hf_dvbci_cis_tpll_v1_minor;
899
static int hf_dvbci_cis_tpll_v1_info_manuf;
900
static int hf_dvbci_cis_tpll_v1_info_name;
901
static int hf_dvbci_cis_tpll_v1_info_additional;
902
static int hf_dvbci_cis_tpll_v1_end;
903
static int hf_dvbci_cis_tpcc_rfsz;
904
static int hf_dvbci_cis_tpcc_rmsz;
905
static int hf_dvbci_cis_tpcc_rasz;
906
static int hf_dvbci_cis_tpcc_last;
907
static int hf_dvbci_cis_tpcc_radr;
908
static int hf_dvbci_cis_tpcc_rmsk;
909
static int hf_dvbci_cis_st_code;
910
static int hf_dvbci_cis_st_len;
911
static int hf_dvbci_cis_stci_ifn_size;
912
static int hf_dvbci_cis_stci_ifn;
913
static int hf_dvbci_cis_stci_str;
914
static int hf_dvbci_cis_tpce_indx_intface;
915
static int hf_dvbci_cis_tpce_indx_default;
916
static int hf_dvbci_cis_tpce_indx_cnf_entry;
917
static int hf_dvbci_cis_tpce_if_type;
918
static int hf_dvbci_cis_tpce_fs_mem_space;
919
static int hf_dvbci_cis_tpce_fs_irq;
920
static int hf_dvbci_cis_tpce_fs_io;
921
static int hf_dvbci_cis_dev_vcc_used;
922
static int hf_dvbci_cis_dev_mwait;
923
static int hf_dvbci_cis_dev_oth_cond_info;
924
static int hf_dvbci_cis_tplmid_manf;
925
static int hf_dvbci_cis_tplmid_card;
926
static int hf_dvbci_buf_size;
927
static int hf_dvbci_tcid;
928
static int hf_dvbci_ml;
929
static int hf_dvbci_l_frags;
930
static int hf_dvbci_l_frag;
931
static int hf_dvbci_l_frag_overlap;
932
static int hf_dvbci_l_frag_overlap_conflicts;
933
static int hf_dvbci_l_frag_multiple_tails;
934
static int hf_dvbci_l_frag_too_long_frag;
935
static int hf_dvbci_l_frag_err;
936
static int hf_dvbci_l_frag_cnt;
937
static int hf_dvbci_l_reass_in;
938
static int hf_dvbci_l_reass_len;
939
static int hf_dvbci_c_tpdu_tag;
940
static int hf_dvbci_r_tpdu_tag;
941
static int hf_dvbci_t_c_id;
942
static int hf_dvbci_sb_tag;
943
static int hf_dvbci_sb_value;
944
static int hf_dvbci_t_frags;
945
static int hf_dvbci_t_frag;
946
static int hf_dvbci_t_frag_overlap;
947
static int hf_dvbci_t_frag_overlap_conflicts;
948
static int hf_dvbci_t_frag_multiple_tails;
949
static int hf_dvbci_t_frag_too_long_frag;
950
static int hf_dvbci_t_frag_err;
951
static int hf_dvbci_t_frag_cnt;
952
static int hf_dvbci_t_reass_in;
953
static int hf_dvbci_t_reass_len;
954
static int hf_dvbci_spdu_tag;
955
static int hf_dvbci_sess_status;
956
static int hf_dvbci_sess_nb;
957
static int hf_dvbci_close_sess_status;
958
static int hf_dvbci_res_id;
959
static int hf_dvbci_res_id_type;
960
static int hf_dvbci_res_class;
961
static int hf_dvbci_res_type;
962
static int hf_dvbci_res_ver;
963
static int hf_dvbci_apdu_tag;
964
static int hf_dvbci_app_type;
965
static int hf_dvbci_app_manf;
966
static int hf_dvbci_manf_code;
967
static int hf_dvbci_menu_str_len;
968
static int hf_dvbci_ap_char_tbl;
969
static int hf_dvbci_menu_str;
970
static int hf_dvbci_data_rate;
971
static int hf_dvbci_ca_sys_id;
972
static int hf_dvbci_ca_pmt_list_mgmt;
973
static int hf_dvbci_prog_num;
974
static int hf_dvbci_ca_ver;
975
static int hf_dvbci_curr_next;
976
static int hf_dvbci_prog_info_len;
977
static int hf_dvbci_stream_type;
978
static int hf_dvbci_es_pid;
979
static int hf_dvbci_es_info_len;
980
static int hf_dvbci_ca_pmt_cmd_id;
981
static int hf_dvbci_descr_len;
982
static int hf_dvbci_ca_pid;
983
static int hf_dvbci_ca_priv_data;
984
static int hf_dvbci_ca_enable_flag;
985
static int hf_dvbci_ca_enable;
986
static int hf_dvbci_auth_proto_id;
987
static int hf_dvbci_auth_req_bytes;
988
static int hf_dvbci_auth_resp_bytes;
989
static int hf_dvbci_network_id;
990
static int hf_dvbci_original_network_id;
991
static int hf_dvbci_transport_stream_id;
992
static int hf_dvbci_service_id;
993
static int hf_dvbci_replacement_ref;
994
static int hf_dvbci_replaced_pid;
995
static int hf_dvbci_replacement_pid;
996
static int hf_dvbci_pmt_flag;
997
static int hf_dvbci_hc_desc_loop_len;
998
static int hf_dvbci_hc_status;
999
static int hf_dvbci_hc_release_reply;
1000
static int hf_dvbci_resp_intv;
1001
static int hf_dvbci_utc_time;
1002
static int hf_dvbci_local_offset;
1003
static int hf_dvbci_close_mmi_cmd_id;
1004
static int hf_dvbci_close_mmi_delay;
1005
static int hf_dvbci_disp_ctl_cmd;
1006
static int hf_dvbci_mmi_mode;
1007
static int hf_dvbci_disp_rep_id;
1008
static int hf_dvbci_mmi_char_tbl;
1009
static int hf_dvbci_blind_ans;
1010
static int hf_dvbci_ans_txt_len;
1011
static int hf_dvbci_enq;
1012
static int hf_dvbci_ans_id;
1013
static int hf_dvbci_ans;
1014
static int hf_dvbci_choice_nb;
1015
static int hf_dvbci_choice_ref;
1016
static int hf_dvbci_item_nb;
1017
static int hf_dvbci_title;
1018
static int hf_dvbci_subtitle;
1019
static int hf_dvbci_bottom;
1020
static int hf_dvbci_item;
1021
static int hf_dvbci_host_country;
1022
static int hf_dvbci_host_language;
1023
static int hf_dvbci_cup_type;
1024
static int hf_dvbci_cup_download_time;
1025
static int hf_dvbci_cup_answer;
1026
static int hf_dvbci_cup_progress;
1027
static int hf_dvbci_cup_reset;
1028
static int hf_dvbci_cc_sys_id_bitmask;
1029
static int hf_dvbci_cc_snd_dat_nbr;
1030
static int hf_dvbci_cc_req_dat_nbr;
1031
static int hf_dvbci_cc_dat_id;
1032
static int hf_dvbci_cc_dat_len;
1033
static int hf_dvbci_brand_cert;
1034
static int hf_dvbci_dev_cert;
1035
static int hf_dvbci_uri_ver;
1036
static int hf_dvbci_uri_aps;
1037
static int hf_dvbci_uri_emi;
1038
static int hf_dvbci_uri_ict;
1039
static int hf_dvbci_uri_rct;
1040
static int hf_dvbci_uri_dot;
1041
static int hf_dvbci_uri_rl;
1042
static int hf_dvbci_cc_key_register;
1043
static int hf_dvbci_cc_status_field;
1044
static int hf_dvbci_cc_op_mode;
1045
static int hf_dvbci_cc_data;
1046
static int hf_dvbci_sac_msg_ctr;
1047
static int hf_dvbci_sac_proto_ver;
1048
static int hf_dvbci_sac_auth_cip;
1049
static int hf_dvbci_sac_payload_enc;
1050
static int hf_dvbci_sac_enc_cip;
1051
static int hf_dvbci_sac_payload_len;
1052
static int hf_dvbci_sac_enc_body;
1053
static int hf_dvbci_sac_padding;
1054
static int hf_dvbci_sac_signature;
1055
static int hf_dvbci_rating;
1056
static int hf_dvbci_capability_field;
1057
static int hf_dvbci_pin_chg_time;
1058
static int hf_dvbci_pincode_status;
1059
static int hf_dvbci_cc_prog_num;
1060
static int hf_dvbci_pin_evt_time;
1061
static int hf_dvbci_pin_evt_cent;
1062
static int hf_dvbci_cc_priv_data;
1063
static int hf_dvbci_pincode;
1064
static int hf_dvbci_app_dom_id_len;
1065
static int hf_dvbci_init_obj_len;
1066
static int hf_dvbci_app_dom_id;
1067
static int hf_dvbci_init_obj;
1068
static int hf_dvbci_ack_code;
1069
static int hf_dvbci_req_type;
1070
static int hf_dvbci_file_hash;
1071
static int hf_dvbci_file_name_len;
1072
static int hf_dvbci_file_name;
1073
static int hf_dvbci_file_data_len;
1074
static int hf_dvbci_ami_priv_data;
1075
static int hf_dvbci_req_ok;
1076
static int hf_dvbci_file_ok;
1077
static int hf_dvbci_abort_req_code;
1078
static int hf_dvbci_abort_ack_code;
1079
static int hf_dvbci_phase_id;
1080
static int hf_dvbci_comms_rep_id;
1081
static int hf_dvbci_lsc_buf_size;
1082
static int hf_dvbci_lsc_ret_val;
1083
static int hf_dvbci_comms_cmd_id;
1084
static int hf_dvbci_conn_desc_type;
1085
static int hf_dvbci_lsc_media_tag;
1086
static int hf_dvbci_lsc_media_len;
1087
static int hf_dvbci_lsc_media_data;
1088
static int hf_dvbci_lsc_ip_ver;
1089
static int hf_dvbci_lsc_ipv4_addr;
1090
static int hf_dvbci_lsc_ipv6_addr;
1091
static int hf_dvbci_lsc_dst_port;
1092
static int hf_dvbci_lsc_proto;
1093
static int hf_dvbci_lsc_hostname;
1094
static int hf_dvbci_lsc_retry_count;
1095
static int hf_dvbci_lsc_timeout;
1096
static int hf_dvbci_lsc_conn_state;
1097
static int hf_dvbci_lsc_phys_addr;
1098
static int hf_dvbci_lsc_netmask;
1099
static int hf_dvbci_lsc_gateway;
1100
static int hf_dvbci_lsc_dhcp_srv;
1101
static int hf_dvbci_lsc_num_dns_srv;
1102
static int hf_dvbci_lsc_dns_srv;
1103
static int hf_dvbci_afs_dom_id;
1104
static int hf_dvbci_afs_ack_code;
1105
static int hf_dvbci_info_ver_op_status;
1106
static int hf_dvbci_nit_ver;
1107
static int hf_dvbci_pro_typ;
1108
static int hf_dvbci_init_flag;
1109
static int hf_dvbci_ent_chg_flag;
1110
static int hf_dvbci_ent_val_flag;
1111
static int hf_dvbci_ref_req_flag;
1112
static int hf_dvbci_err_flag;
1113
static int hf_dvbci_dlv_sys_hint;
1114
static int hf_dvbci_dlv_sys_hint_t;
1115
static int hf_dvbci_dlv_sys_hint_s;
1116
static int hf_dvbci_dlv_sys_hint_c;
1117
static int hf_dvbci_refr_req_date;
1118
static int hf_dvbci_refr_req_time;
1119
static int hf_dvbci_nit_loop_len;
1120
static int hf_dvbci_info_valid;
1121
static int hf_dvbci_info_ver_op_info;
1122
static int hf_dvbci_cicam_onid;
1123
static int hf_dvbci_cicam_id;
1124
static int hf_dvbci_opp_char_tbl;
1125
static int hf_dvbci_sdt_rst_trusted;
1126
static int hf_dvbci_eit_rst_trusted;
1127
static int hf_dvbci_eit_pf_usage;
1128
static int hf_dvbci_eit_sch_usage;
1129
static int hf_dvbci_ext_evt_usage;
1130
static int hf_dvbci_sdt_oth_trusted;
1131
static int hf_dvbci_eit_evt_trigger;
1132
static int hf_dvbci_opp_lang_code;
1133
static int hf_dvbci_prof_name;
1134
static int hf_dvbci_unattended;
1135
static int hf_dvbci_opp_svc_type_loop_len;
1136
static int hf_dvbci_opp_svc_type;
1137
static int hf_dvbci_dlv_cap_loop_len;
1138
static int hf_dvbci_dlv_cap_byte;
1139
static int hf_dvbci_app_cap_loop_len;
1140
static int hf_dvbci_app_cap_bytes;
1141
static int hf_dvbci_desc_num;
1142
static int hf_dvbci_sig_strength;
1143
static int hf_dvbci_sig_qual;
1144
static int hf_dvbci_opp_tune_status;
1145
static int hf_dvbci_opp_desc_loop_len;
1146
static int hf_dvbci_sas_app_id;
1147
static int hf_dvbci_sas_sess_state;
1148
static int hf_dvbci_sas_msg_nb;
1149
static int hf_dvbci_sas_msg_len;
1150
1151
static int * const dvb_ci_res_id_fields[] = {
1152
  &hf_dvbci_res_id_type,
1153
  &hf_dvbci_res_class,
1154
  &hf_dvbci_res_type,
1155
  &hf_dvbci_res_ver,
1156
  NULL
1157
};
1158
1159
static int * const dvbci_opp_dlv_sys_hint_fields[] = {
1160
    &hf_dvbci_dlv_sys_hint_t,
1161
    &hf_dvbci_dlv_sys_hint_s,
1162
    &hf_dvbci_dlv_sys_hint_c,
1163
    NULL
1164
};
1165
1166
1167
static expert_field ei_dvbci_cor_addr;
1168
static expert_field ei_dvbci_buf_size;
1169
static expert_field ei_dvbci_ml;
1170
static expert_field ei_dvbci_c_tpdu_tag;
1171
static expert_field ei_dvbci_r_tpdu_status_mandatory;
1172
static expert_field ei_dvbci_r_tpdu_tag;
1173
static expert_field ei_dvbci_sb_value;
1174
static expert_field ei_dvbci_t_c_id;
1175
static expert_field ei_dvbci_tpdu_status_tag;
1176
static expert_field ei_dvbci_spdu_tag;
1177
static expert_field ei_dvbci_spdu_cam_to_host;
1178
static expert_field ei_dvbci_spdu_host_to_cam;
1179
static expert_field ei_dvbci_apdu_tag;
1180
static expert_field ei_dvbci_apu_cam_to_host;
1181
static expert_field ei_dvbci_apu_host_to_cam;
1182
static expert_field ei_dvbci_apdu_not_supported;
1183
static expert_field ei_dvbci_res_ver;
1184
static expert_field ei_dvbci_res_class;
1185
static expert_field ei_dvbci_bad_length;
1186
static expert_field ei_dvbci_invalid_char_tbl;
1187
static expert_field ei_dvbci_no_ca_desc_es;
1188
static expert_field ei_dvbci_no_ca_desc_prog;
1189
static expert_field ei_dvbci_ca_pmt_cmd_id;
1190
static expert_field ei_dvbci_time_offs_unknown;
1191
static expert_field ei_dvbci_not_text_more_or_text_last;
1192
static expert_field ei_dvbci_network_id;
1193
static expert_field ei_dvbci_cc_pin_nvr_chg;
1194
static expert_field ei_dvbci_pin_evt_cent;
1195
static expert_field ei_dvbci_sac_payload_enc;
1196
static expert_field ei_dvbci_sig_qual;
1197
static expert_field ei_dvbci_cicam_nit_table_id;
1198
static expert_field ei_dvbci_cup_progress;
1199
1200
static dissector_table_t sas_msg_dissector_table;
1201
1202
static reassembly_table tpdu_reassembly_table;
1203
static reassembly_table spdu_reassembly_table;
1204
1205
static const fragment_items tpdu_frag_items = {
1206
    &ett_dvbci_link_frag,
1207
    &ett_dvbci_link_frags,
1208
1209
    &hf_dvbci_l_frags,
1210
    &hf_dvbci_l_frag,
1211
    &hf_dvbci_l_frag_overlap,
1212
    &hf_dvbci_l_frag_overlap_conflicts,
1213
    &hf_dvbci_l_frag_multiple_tails,
1214
    &hf_dvbci_l_frag_too_long_frag,
1215
    &hf_dvbci_l_frag_err,
1216
    &hf_dvbci_l_frag_cnt,
1217
1218
    &hf_dvbci_l_reass_in,
1219
    &hf_dvbci_l_reass_len,
1220
    /* Reassembled data field */
1221
    NULL,
1222
    "Tpdu fragments"
1223
};
1224
static const fragment_items spdu_frag_items = {
1225
    &ett_dvbci_transport_frag,
1226
    &ett_dvbci_transport_frags,
1227
1228
    &hf_dvbci_t_frags,
1229
    &hf_dvbci_t_frag,
1230
    &hf_dvbci_t_frag_overlap,
1231
    &hf_dvbci_t_frag_overlap_conflicts,
1232
    &hf_dvbci_t_frag_multiple_tails,
1233
    &hf_dvbci_t_frag_too_long_frag,
1234
    &hf_dvbci_t_frag_err,
1235
    &hf_dvbci_t_frag_cnt,
1236
1237
    &hf_dvbci_t_reass_in,
1238
    &hf_dvbci_t_reass_len,
1239
    /* Reassembled data field */
1240
    NULL,
1241
    "Spdu fragments"
1242
};
1243
1244
1245
1246
typedef struct _spdu_info_t {
1247
    uint8_t tag;
1248
    uint8_t direction;
1249
    uint8_t len_field;
1250
} spdu_info_t;
1251
1252
static const value_string dvbci_hw_event[] = {
1253
    { CAM_IN,    "CI Module is inserted" },
1254
    { CAM_OUT,   "CI Module is removed" },
1255
    { POWER_ON,  "CI slot power on" },
1256
    { POWER_OFF, "CI slot power off" },
1257
    { TS_ROUTE,  "Transport stream routed through the CI Module" },
1258
    { TS_BYPASS, "Transport stream bypasses the CI Module" },
1259
    { RESET_H,   "Reset pin is high" },
1260
    { RESET_L,   "Reset pin is low" },
1261
    { READY_H,   "Ready pin is high" },
1262
    { READY_L,   "Ready pin is low" },
1263
    { 0, NULL }
1264
};
1265
static const value_string dvbci_cis_tpl_code[] = {
1266
    { CISTPL_NO_LINK, "No-link tuple" },
1267
    { CISTPL_VERS_1, "Level 1 version/product information" },
1268
    { CISTPL_CONFIG, "Configuration for a 16bit PC-Card" },
1269
    { CISTPL_CFTABLE_ENTRY, "Configuration-table entry" },
1270
    { CISTPL_DEVICE_OC, "Device information for Common Memory" },
1271
    { CISTPL_DEVICE_OA, "Device information for Attribute Memory" },
1272
    { CISTPL_MANFID, "Manufacturer identification string" },
1273
    { CISTPL_END, "End of chain" },
1274
    { 0, NULL }
1275
};
1276
static const value_string dvbci_cis_subtpl_code[] = {
1277
    { CCSTPL_CIF, "Custom interface subtuple" },
1278
    { 0, NULL }
1279
};
1280
static const value_string dvbci_cis_tpce_if_type[] = {
1281
    { TPCE_IF_TYPE_MEM,    "Memory" },
1282
    { TPCE_IF_TYPE_IO_MEM, "I/O and Memory" },
1283
    { TPCE_IF_TYPE_CUST0,  "Custom Interface 0" },
1284
    { TPCE_IF_TYPE_CUST1,  "Custom Interface 1" },
1285
    { TPCE_IF_TYPE_CUST2,  "Custom Interface 2" },
1286
    { TPCE_IF_TYPE_CUST3,  "Custom Interface 3" },
1287
    { 0, NULL }
1288
};
1289
static const value_string dvbci_cis_dev_vcc_used[] = {
1290
    { CIS_DEV_VCC50, "5.0V" },
1291
    { CIS_DEV_VCC33, "3.3V" },
1292
    { 0, NULL }
1293
};
1294
static const value_string dvbci_ml[] = {
1295
    { ML_MORE, "more TPDU fragments pending" },
1296
    { ML_LAST, "last TPDU fragment" },
1297
    { 0, NULL }
1298
};
1299
static const value_string dvbci_c_tpdu[] = {
1300
    { T_RCV, "T_RCV" },
1301
    { T_CREATE_T_C,  "T_create_t_c" },
1302
    { T_DELETE_T_C,  "T_delete_t_c" },
1303
    { T_D_T_C_REPLY, "T_d_t_c_reply" },
1304
    { T_NEW_T_C,     "T_new_t_c" },
1305
    { T_T_C_ERROR,   "T_t_c_error" },
1306
    { T_DATA_LAST,   "T_data_last" },
1307
    { T_DATA_MORE,   "T_data_more" },
1308
    { 0, NULL }
1309
};
1310
static const value_string dvbci_r_tpdu[] = {
1311
    { T_C_T_C_REPLY, "T_c_tc_reply" },
1312
    { T_DELETE_T_C,  "T_delete_t_c" },
1313
    { T_D_T_C_REPLY, "T_d_t_c_reply" },
1314
    { T_REQUEST_T_C, "T_request_t_c" },
1315
    { T_DATA_LAST,   "T_data_last" },
1316
    { T_DATA_MORE,   "T_data_more" },
1317
    { 0, NULL }
1318
};
1319
static const value_string dvbci_sb_value[] = {
1320
    { SB_VAL_MSG_AVAILABLE,    "message available" },
1321
    { SB_VAL_NO_MSG_AVAILABLE, "no message available" },
1322
    { 0, NULL }
1323
};
1324
static const value_string dvbci_spdu_tag[] = {
1325
    { T_SESSION_NUMBER,          "Session Number (payload data)" },
1326
    { T_OPEN_SESSION_REQUEST,    "Open Session Request" },
1327
    { T_OPEN_SESSION_RESPONSE,   "Open Session Response" },
1328
    { T_CREATE_SESSION,          "Create Session" },
1329
    { T_CREATE_SESSION_RESPONSE, "Create Session Response" },
1330
    { T_CLOSE_SESSION_REQUEST,   "Close Session Request" },
1331
    { T_CLOSE_SESSION_RESPONSE,  "Close Session Response" },
1332
    { 0, NULL }
1333
};
1334
static GHashTable *spdu_table;
1335
static const spdu_info_t spdu_info[] = {
1336
    { T_SESSION_NUMBER,          DIRECTION_ANY, 2 },
1337
    { T_OPEN_SESSION_REQUEST,    DATA_CAM_TO_HOST, 4 },
1338
    { T_OPEN_SESSION_RESPONSE,   DATA_HOST_TO_CAM, 7 },
1339
    { T_CREATE_SESSION,          DATA_HOST_TO_CAM, 6 },
1340
    { T_CREATE_SESSION_RESPONSE, DATA_CAM_TO_HOST, 7 },
1341
    { T_CLOSE_SESSION_REQUEST,   DIRECTION_ANY, 2 },
1342
    { T_CLOSE_SESSION_RESPONSE,  DIRECTION_ANY, 3 }
1343
};
1344
static const value_string dvbci_sess_status[] = {
1345
    { SESS_OPENED,
1346
      "Session opened" },
1347
    { SESS_NOT_OPENED_RES_NON_EXIST,
1348
      "Resource does not exist" },
1349
    { SESS_NOT_OPENED_RES_UNAVAIL,
1350
      "Resource exists but it's unavailable" },
1351
    { SESS_NOT_OPENED_RES_VER_LOWER,
1352
      "Existing resource's version is lower than requested version" },
1353
    { SESS_NOT_OPENED_RES_BUSY,
1354
      "Resource is busy" },
1355
    { 0, NULL }
1356
};
1357
static const value_string dvbci_close_sess_status[] = {
1358
    { SESS_CLOSED,       "Session closed" },
1359
    { SESS_NB_NOT_ALLOC, "Session number not allocated" },
1360
    { 0, NULL }
1361
};
1362
static const value_string dvbci_res_class[] = {
1363
    { RES_CLASS_RM,  "Resource Manager" },
1364
    { RES_CLASS_AP,  "Application Info" },
1365
    { RES_CLASS_CA,  "Conditional Access" },
1366
    { RES_CLASS_AUT, "Authentication" },
1367
    { RES_CLASS_HC,  "Host Control" },
1368
    { RES_CLASS_DT,  "Date-Time" },
1369
    { RES_CLASS_MMI, "Man-machine interface (MMI)" },
1370
    { RES_CLASS_AMI, "Application MMI" },
1371
    { RES_CLASS_LSC, "Low-Speed Communication" },
1372
    { RES_CLASS_CC,  "Content Control" },
1373
    { RES_CLASS_HLC, "Host Language & Country" },
1374
    { RES_CLASS_CUP, "CAM Upgrade" },
1375
    { RES_CLASS_OPP, "Operator Profile" },
1376
    { RES_CLASS_AFS, "Auxiliary File System" },
1377
    { RES_CLASS_SAS, "Specific Application Support" },
1378
    { 0, NULL }
1379
};
1380
static const value_string dvbci_app_type[] = {
1381
    { APP_TYPE_CA,  "Conditional Access" },
1382
    { APP_TYPE_EPG, "Electronic Program Guide" },
1383
    { 0, NULL }
1384
};
1385
static const value_string dvbci_data_rate[] = {
1386
    { DATA_RATE_72, "72 Mbit/s" },
1387
    { DATA_RATE_96, "96 Mbit/s" },
1388
    { 0, NULL }
1389
};
1390
static const value_string dvbci_ca_pmt_list_mgmt[] = {
1391
    { LIST_MGMT_MORE,   "more" },
1392
    { LIST_MGMT_FIRST,  "first" },
1393
    { LIST_MGMT_LAST,   "last" },
1394
    { LIST_MGMT_ONLY,   "only" },
1395
    { LIST_MGMT_ADD,    "add" },
1396
    { LIST_MGMT_UPDATE, "update" },
1397
    { 0, NULL }
1398
};
1399
static const value_string dvbci_ca_pmt_cmd_id[] = {
1400
    { CMD_ID_OK_DESCR,     "ok descrambling" },
1401
    { CMD_ID_OK_MMI,       "ok mmi" },
1402
    { CMD_ID_QUERY,        "query" },
1403
    { CMD_ID_NOT_SELECTED, "not selected" },
1404
    { 0, NULL }
1405
};
1406
static const value_string dvbci_ca_enable[] = {
1407
    { CA_ENAB_DESC_OK, "descrambling possible" },
1408
    { CA_ENAB_DESC_OK_PURCHASE,
1409
        "descrambling possible under conditions (purchase dialogue)" },
1410
    { CA_ENAB_DESC_OK_TECH,
1411
        "descrambling possible under conditions (technical dialogue)" },
1412
    { CA_ENAB_DESC_NG_ENTITLEMENT,
1413
        "descrambling not possible (because no entitlement)" },
1414
    { CA_ENAB_DESC_NG_TECH,
1415
        "descrambling not possible (for technical reasons)" },
1416
    { 0, NULL }
1417
};
1418
static const value_string dvbci_hc_status[] = {
1419
    { HC_STAT_OK, "ok" },
1420
    { HC_STAT_ERR_DLVRY, "unsupported delivery system descriptor" },
1421
    { HC_STAT_ERR_LOCK, "tuner not locking" },
1422
    { HC_STAT_ERR_BUSY, "tuner busy" },
1423
    { HC_STAT_ERR_PARAM, "bad or missing parameters" },
1424
    { HC_STAT_ERR_NOT_FOUND, "service not found" },
1425
    { HC_STAT_ERR_UNKNOWN, "unknown error" },
1426
    { 0, NULL }
1427
};
1428
static const value_string dvbci_hc_release_reply[] = {
1429
    { HC_RELEASE_OK, "Host regains control of the tuner" },
1430
    { HC_RELEASE_REFUSED, "CICAM retains control of the tuner" },
1431
    { 0, NULL }
1432
};
1433
static const value_string dvbci_close_mmi_cmd_id[] = {
1434
    { CLOSE_MMI_CMD_ID_IMMEDIATE, "immediate close" },
1435
    { CLOSE_MMI_CMD_ID_DELAY, "delayed close" },
1436
    { 0, NULL }
1437
};
1438
static const value_string dvbci_disp_ctl_cmd[] = {
1439
    { DISP_CMD_SET_MMI_MODE, "set MMI mode" },
1440
    { DISP_CMD_GET_DISP_TBL, "get display character tables" },
1441
    { DISP_CMD_GET_INP_TBL,  "get input character tables" },
1442
    { 0, NULL }
1443
};
1444
static const value_string dvbci_mmi_mode[] = {
1445
    { MMI_MODE_HIGH, "High-level MMI" },
1446
    { 0, NULL }
1447
};
1448
static const value_string dvbci_disp_rep_id[] = {
1449
    { DISP_REP_ID_MMI_MODE_ACK,     "MMI mode acknowledge" },
1450
    { DISP_REP_ID_DISP_CHAR_TBL,    "list display character tables" },
1451
    { DISP_REP_ID_INP_CHAR_TBL,     "list input character tables" },
1452
    { DISP_REP_ID_UNKNOWN_CMD,      "unknown display control command" },
1453
    { DISP_REP_ID_UNKNOWN_MMI_MODE, "unknown MMI mode" },
1454
    { DISP_REP_ID_UNKNOWN_CHAR_TBL, "unknown character table" },
1455
    { 0, NULL }
1456
};
1457
static const value_string dvbci_blind_ans[] = {
1458
    { VISIBLE_ANS, "visible" },
1459
    { BLIND_ANS,   "blind" },
1460
    { 0, NULL }
1461
};
1462
static const value_string dvbci_ans_id[] = {
1463
    { ANSW_ID_CANCEL, "cancel" },
1464
    { ANSW_ID_ANSWER, "answer" },
1465
    { 0, NULL }
1466
};
1467
static const value_string dvbci_cup_type[] = {
1468
    { CUP_DELAYED, "delayed" },
1469
    { CUP_IMMEDIATE, "immediate" },
1470
    { 0, NULL }
1471
};
1472
static const value_string dvbci_cup_answer[] = {
1473
    { CUP_ANS_NO,  "upgrade denied" },
1474
    { CUP_ANS_YES, "upgrade allowed" },
1475
    { CUP_ANS_ASK, "ask the user for permission" },
1476
    { 0, NULL }
1477
};
1478
static const value_string dvbci_cup_reset[] = {
1479
    { CUP_RESET_PCMCIA, "PCMCIA reset" },
1480
    { CUP_RESET_CMDIF,  "CI command interface reset" },
1481
    { CUP_RESET_NONE,   "no reset" },
1482
    { 0, NULL }
1483
};
1484
static const value_string dvbci_cc_dat_id[] = {
1485
    { CC_ID_HOST_ID,            "Host ID" },
1486
    { CC_ID_CICAM_ID,           "Cicam ID" },
1487
    { CC_ID_HOST_BRAND_CERT,    "Host brand certificate" },
1488
    { CC_ID_CICAM_BRAND_CERT,   "Cicam brand certificate" },
1489
    { CC_ID_KP,                 "Key precursor for CCK" },
1490
    { CC_ID_DHPH,               "Host Diffie-Hellman public key" },
1491
    { CC_ID_DHPM,               "Cicam Diffie-Hellman public key" },
1492
    { CC_ID_HOST_DEV_CERT,      "Host device certificate" },
1493
    { CC_ID_CICAM_DEV_CERT,     "Cicam device certificate" },
1494
    { CC_ID_SIG_A,              "Signature of host Diffie-Hellman public key" },
1495
    { CC_ID_SIG_B,              "Signature of cicam Diffie-Hellman public key" },
1496
    { CC_ID_NS_HOST,            "Host nonce" },
1497
    { CC_ID_AUTH_NONCE,         "Nonce for authentication" },
1498
    { CC_ID_NS_MODULE,          "Cicam nonce" },
1499
    { CC_ID_AKH,                "Host authentication key" },
1500
    { CC_ID_URI,                "URI" },
1501
    { CC_ID_PROG_NUM,           "Program number" },
1502
    { CC_ID_URI_CNF,            "URI confirmation" },
1503
    { CC_ID_KEY_REGISTER,       "Key register" },
1504
    { CC_ID_URI_VERSIONS,       "Supported URI versions" },
1505
    { CC_ID_STATUS_FIELD,       "Status field" },
1506
    { CC_ID_SRM_DATA,           "SRM for HDCP" },
1507
    { CC_ID_SRM_CONFIRM,        "SRM confirmation hash" },
1508
    { CC_ID_CICAM_LICENSE,      "License received from the cicam" },
1509
    { CC_ID_LICENSE_STATUS,     "Current status of the license" },
1510
    { CC_ID_LICENSE_RCV_STATUS, "Status of the license exchange" },
1511
    { CC_ID_HOST_LICENSE,
1512
        "License for which the host requests the current status" },
1513
    { CC_ID_PLAY_COUNT,         "Play count" },
1514
    { CC_ID_OPERATING_MODE,     "Operating mode" },
1515
    { CC_ID_PINCODE_DATA,       "Pincode data" },
1516
    { CC_ID_REC_START_STATUS,   "Record start status" },
1517
    { CC_ID_MODE_CHG_STATUS,    "Change operating mode status" },
1518
    { CC_ID_REC_STOP_STATUS,    "Record stop status" },
1519
    { 0, NULL }
1520
};
1521
static const value_string dvbci_cc_uri_emi[] = {
1522
    { CC_EMI_FREE,    "Copy free" },
1523
    { CC_EMI_NO_MORE, "Copy no more" },
1524
    { CC_EMI_ONCE,    "Copy once" },
1525
    { CC_EMI_NEVER,   "Copy never" },
1526
    { 0, NULL }
1527
};
1528
static const value_string dvbci_cc_key_register[] = {
1529
    { CC_KEY_EVEN,  "Even" },
1530
    { CC_KEY_ODD,   "Odd" },
1531
    { 0, NULL }
1532
};
1533
static const value_string dvbci_cc_status[] = {
1534
    { CC_STATUS_OK,                    "Ok" },
1535
    { CC_STATUS_NO_CC_SUPPORT,         "No CC support" },
1536
    { CC_STATUS_HOST_BUSY,             "Host busy" },
1537
    { CC_STATUS_AUTH_FAILED_OR_NO_SRM, "Authentication failed / SRM not required" },
1538
    { CC_STATUS_CICAM_BUSY,            "CICAM busy" },
1539
    { CC_STATUS_REC_MODE_ERR,          "Recording mode error" },
1540
    { 0, NULL }
1541
};
1542
static const value_string dvbci_cc_sac_auth[] = {
1543
    { CC_SAC_AUTH_AES128_XCBC_MAC, "AES 128 XCBC MAC" },
1544
    { 0, NULL }
1545
};
1546
static const value_string dvbci_cc_sac_enc[] = {
1547
    { CC_SAC_ENC_AES128_CBC, "AES 128 CBC" },
1548
    { 0, NULL }
1549
};
1550
static const value_string dvbci_cc_cap[] = {
1551
    { CC_CAP_NONE,
1552
        "No PIN handling capability" },
1553
    { CC_CAP_CAS_PIN,
1554
        "CAM can do PIN handling on CAS services" },
1555
    { CC_CAP_CAS_FTA_PIN,
1556
        "CAM can do PIN handling on CAS and free services" },
1557
    { CC_CAP_CAS_PIN_CACHED,
1558
        "CAM can do PIN handling on CAS services and supports PIN caching" },
1559
    { CC_CAP_CAS_FTA_PIN_CACHED,
1560
        "CAM can do PIN handling on CAS and free services, supports PIN caching" },
1561
    { 0, NULL }
1562
};
1563
static const value_string dvbci_pincode_status[] = {
1564
    { CC_PIN_BAD,         "Bad pin code" },
1565
    { CC_PIN_CAM_BUSY,    "CAM busy" },
1566
    { CC_PIN_OK,          "Pin code correct" },
1567
    { CC_PIN_UNCONFIRMED, "Pin code unconfirmed" },
1568
    { CC_PIN_VB_NOT_REQ,  "Video blanking not required" },
1569
    { CC_PIN_CSA,         "Content still CSA scrambled" },
1570
    { 0, NULL }
1571
};
1572
static const value_string dvbci_cc_op_mode[] = {
1573
    { CC_OP_MODE_WATCH_BUFFER, "Watch and buffer" },
1574
    { CC_OP_MODE_TIMESHIFT,    "Timeshift" },
1575
    { CC_OP_MODE_UNATTENDED,   "Unattended recording" },
1576
    { 0, NULL }
1577
};
1578
static const value_string dvbci_ack_code[] = {
1579
    { ACK_CODE_OK, "Ok" },
1580
    { ACK_CODE_WRONG_API,  "Application Domain unsupported" },
1581
    { ACK_CODE_API_BUSY,   "Application Domain currently unavailable" },
1582
    { 0, NULL }
1583
};
1584
static const value_string dvbci_req_type[] = {
1585
    { REQ_TYPE_FILE, "File" },
1586
    { REQ_TYPE_DATA, "Data" },
1587
    { REQ_TYPE_FILE_HASH, "FileHash" },
1588
    { REQ_TYPE_REQ, "List supported request types" },
1589
    { 0, NULL }
1590
};
1591
static const value_string dvbci_comms_cmd_id[] = {
1592
    { COMMS_CMD_ID_CONNECT_ON_CHANNEL, "connect on channel" },
1593
    { COMMS_CMD_ID_DISCONNECT_ON_CHANNEL, "disconnect on channel" },
1594
    { COMMS_CMD_ID_SET_PARAMS, "set parameters" },
1595
    { COMMS_CMD_ID_ENQUIRE_STATUS, "status enquiry" },
1596
    { COMMS_CMD_ID_GET_NEXT_BUFFER, "get next buffer" },
1597
    { 0, NULL }
1598
};
1599
static const value_string dvbci_conn_desc_type[] = {
1600
    { CONN_DESC_TEL, "DVB-SI telephone descriptor" },
1601
    { CONN_DESC_CABLE, "cable return channel" },
1602
    { CONN_DESC_IP, "IP descriptor" },
1603
    { CONN_DESC_HOSTNAME, "hostname descriptor" },
1604
    { 0, NULL }
1605
};
1606
static const value_string dvbci_lsc_desc_tag[] = {
1607
    { LSC_DESC_IP, "IP descriptor" },
1608
    { LSC_DESC_HOSTNAME, "hostname descriptor" },
1609
    { 0, NULL }
1610
};
1611
static const value_string dvbci_lsc_ip_ver[] = {
1612
    { LSC_IPV4, "IPv4" },
1613
    { LSC_IPV6, "IPv6" },
1614
    { 0, NULL }
1615
};
1616
static const value_string dvbci_lsc_proto[] = {
1617
    { LSC_TCP, "TCP" },
1618
    { LSC_UDP, "UDP" },
1619
    { 0, NULL }
1620
};
1621
static const value_string dvbci_comms_rep_id[] = {
1622
    { COMMS_REP_ID_CONNECT_ACK, "connect ack" },
1623
    { COMMS_REP_ID_DISCONNECT_ACK, "disconnect ack" },
1624
    { COMMS_REP_ID_SET_PARAMS_ACK, "set parameters ack" },
1625
    { COMMS_REP_ID_STATUS_REPLY, "status reply" },
1626
    { COMMS_REP_ID_GET_NEXT_BUFFER_ACK, "get next buffer ack" },
1627
    { COMMS_REP_ID_SEND_ACK, "send ack" },
1628
    { 0, NULL }
1629
};
1630
static const value_string dvbci_lsc_ret_val[] = {
1631
    { LSC_RET_OK, "ok" },
1632
    { 0, NULL }
1633
};
1634
static const value_string dvbci_lsc_connect[] = {
1635
    { LSC_DISCONNECTED, "disconnected" },
1636
    { LSC_CONNECTED, "connected" },
1637
    { 0, NULL }
1638
};
1639
static const value_string dvbci_lsc_ret_val_params[] = {
1640
    { LSC_RET_OK, "ok" },
1641
    { LSC_RET_TOO_BIG, "buffer size too big" },
1642
    { 0, NULL }
1643
};
1644
static const value_string dvbci_afs_ack_code[] = {
1645
    { AFS_ACK_RSV, "Reserved for future use" },
1646
    { AFS_ACK_OK, "The application environment is supported by the Host" },
1647
    { AFS_ACK_UNKNOWN, "The DomainIdentifier is not supported by the Host" },
1648
    { 0, NULL }
1649
};
1650
static const value_string dvbci_opp_ref_req_flag[] = {
1651
    { OPP_REF_REG_FLG_NONE,  "none" },
1652
    { OPP_REF_REG_FLG_ADV,   "advance warning" },
1653
    { OPP_REF_REG_FLG_URG,   "urgent" },
1654
    { OPP_REF_REG_FLG_SCHED, "scheduled" },
1655
    { 0, NULL }
1656
};
1657
static const value_string dvbci_opp_err_flag[] = {
1658
    { OPP_ERR_FLG_OK,          "no error" },
1659
    { OPP_ERR_FLG_PROF,        "CICAM can't acquire the profile" },
1660
    { OPP_ERR_FLG_UNSUPPORTED, "unsupported delivery system" },
1661
    { OPP_ERR_FLG_CANCELLED,   "operator search was cancelled" },
1662
    { 0, NULL }
1663
};
1664
static const value_string dvbci_opp_eit_pf_usage[] = {
1665
    { OPP_EIT_ABSENT, "no EIT present" },
1666
    { OPP_EIT_NOT_X,  "EIT is not fully ross-carried" },
1667
    { OPP_EIT_FULL_X, "EIT is fully cross-carried" },
1668
    { 0, NULL }
1669
};
1670
static const value_string dvbci_opp_eit_sch_usage[] = {
1671
    { OPP_EIT_ABSENT, "no EIT present" },
1672
    { OPP_EIT_NOT_X,  "EIT is not fully ross-carried" },
1673
    { OPP_EIT_FULL_X, "EIT is fully cross-carried" },
1674
    { OPP_EIT_BARKER, "EIT is available from a barker channel" },
1675
    { OPP_EPG_APP,    "EPG is delivered using an application" },
1676
    { 0, NULL }
1677
};
1678
static const value_string dvbci_opp_ext_evt[] = {
1679
    { OPP_EXT_EVT_DIFF, "extended event info is different from short event" },
1680
    { OPP_EXT_EVT_ADD,  "extended event info includes short event" },
1681
    { 0, NULL }
1682
};
1683
static const value_string dvbci_opp_dlv_cap[] = {
1684
    { OPP_DLV_CAP_S,  "DVB-S" },
1685
    { OPP_DLV_CAP_C,  "DVB-C" },
1686
    { OPP_DLV_CAP_T,  "DVB-T" },
1687
    { OPP_DLV_CAP_S2, "DVB-S2" },
1688
    { 0, NULL }
1689
};
1690
static const value_string dvbci_opp_tune_stat[] = {
1691
    { OPP_TUNE_OK,          "success" },
1692
    { OPP_TUNE_UNSUPPORTED, "unsupported delivery system descriptor" },
1693
    { OPP_TUNE_INVALID,     "invalid delivery system descriptor" },
1694
    { OPP_TUNE_ERR,         "failed" },
1695
    { 0, NULL }
1696
};
1697
static const value_string dvbci_sas_sess_state[] = {
1698
    { SAS_SESS_STATE_CONNECTED, "connected" },
1699
    { SAS_SESS_STATE_NOT_FOUND, "application not found" },
1700
    { SAS_SESS_STATE_DENIED, "denied, no more connections available" },
1701
    { 0, NULL }
1702
};
1703
1704
static uint16_t buf_size_cam;    /* buffer size proposal by the CAM */
1705
/* buffer size proposal by the host == negotiated buffer size */
1706
static uint16_t buf_size_host;
1707
/* keys for p_add_proto_data() */
1708
0
#define DVBCI_PROTO_DATA_BUF_SIZE_HOST 0
1709
0
#define DVBCI_PROTO_DATA_BUF_SIZE_CAM  1
1710
1711
1712
int
1713
dvbci_set_addrs(uint8_t event, packet_info *pinfo)
1714
0
{
1715
0
    if (!IS_DATA_TRANSFER(event))
1716
0
        return -1;
1717
1718
0
    if (event == DVBCI_EVT_DATA_HOST_TO_CAM) {
1719
0
        set_address(&pinfo->src, AT_STRINGZ,
1720
0
                (int)strlen(ADDR_HOST)+1, ADDR_HOST);
1721
0
        set_address(&pinfo->dst, AT_STRINGZ,
1722
0
                (int)strlen(ADDR_CAM)+1 , ADDR_CAM);
1723
0
    }
1724
0
    else {
1725
0
        set_address(&pinfo->src, AT_STRINGZ,
1726
0
                (int)strlen(ADDR_CAM)+1 , ADDR_CAM);
1727
0
        set_address(&pinfo->dst, AT_STRINGZ,
1728
0
                (int)strlen(ADDR_HOST)+1, ADDR_HOST);
1729
0
    }
1730
1731
0
    return 1;
1732
0
}
1733
1734
static uint8_t
1735
dvbci_get_evt_from_addrs(packet_info *pinfo)
1736
0
{
1737
    /* this should be working from C89 on */
1738
0
    static const address a_cam  = ADDRESS_INIT(AT_STRINGZ, sizeof(ADDR_CAM), ADDR_CAM);
1739
0
    static const address a_host = ADDRESS_INIT(AT_STRINGZ, sizeof(ADDR_HOST), ADDR_HOST);
1740
1741
0
    if ( addresses_equal(&(pinfo->src), &a_cam) &&
1742
0
         addresses_equal(&(pinfo->dst), &a_host) ) {
1743
0
        return DVBCI_EVT_DATA_CAM_TO_HOST;
1744
0
    }
1745
0
    else if ( addresses_equal(&(pinfo->src), &a_host) &&
1746
0
              addresses_equal(&(pinfo->dst), &a_cam) ) {
1747
0
        return DVBCI_EVT_DATA_HOST_TO_CAM;
1748
0
    }
1749
0
    else
1750
0
        return DVBCI_EVT_INVALID_EVT;
1751
0
}
1752
1753
1754
/* this must be a function, not a macro,
1755
   so that we can enforce the return type */
1756
static inline int16_t two_comp_to_int16(uint16_t x)
1757
0
{
1758
0
   return (x&0x8000) ? -~(x-1) : x;
1759
0
}
1760
1761
1762
/* initialize/reset per capture state data */
1763
static void
1764
dvbci_init(void)
1765
16
{
1766
16
    buf_size_cam  = 0;
1767
16
    buf_size_host = 0;
1768
16
}
1769
1770
1771
/* dissect a delivery system descriptor loop
1772
   and the preceding length field
1773
   (used for host control and operator profile)
1774
   return the number of bytes dissected */
1775
static int
1776
dissect_desc_loop(int len_hf,
1777
        tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree)
1778
0
{
1779
0
    unsigned offset_start;
1780
0
    uint16_t desc_loop_len;
1781
0
    unsigned desc_len;
1782
1783
0
    offset_start = offset;
1784
1785
0
    desc_loop_len = tvb_get_ntohs(tvb, offset) & 0x0FFF;
1786
0
    proto_tree_add_item(tree, len_hf, tvb, offset, 2, ENC_BIG_ENDIAN);
1787
0
    offset += 2;
1788
0
    while (offset-offset_start < (unsigned)(2+desc_loop_len)) {
1789
0
        desc_len = proto_mpeg_descriptor_dissect(tvb, pinfo, offset, tree);
1790
0
        if (desc_len==0)
1791
0
            break;
1792
0
        offset += desc_len;
1793
0
    }
1794
1795
0
    return offset-offset_start;
1796
0
}
1797
1798
1799
/* dissect operator profile's status body, return its length */
1800
static int
1801
dissect_opp_status_body(tvbuff_t *tvb, unsigned offset,
1802
        packet_info *pinfo _U_, proto_tree *tree)
1803
0
{
1804
0
    unsigned offset_start;
1805
1806
0
    offset_start = offset;
1807
0
    proto_tree_add_item(tree, hf_dvbci_info_ver_op_status,
1808
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
1809
0
    proto_tree_add_item(tree, hf_dvbci_nit_ver,
1810
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
1811
0
    offset++;
1812
0
    proto_tree_add_item(tree, hf_dvbci_pro_typ,
1813
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
1814
0
    proto_tree_add_item(tree, hf_dvbci_init_flag,
1815
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
1816
0
    proto_tree_add_item(tree, hf_dvbci_ent_chg_flag,
1817
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
1818
0
    proto_tree_add_item(tree, hf_dvbci_ent_val_flag,
1819
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
1820
0
    proto_tree_add_item(tree, hf_dvbci_ref_req_flag,
1821
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
1822
0
    offset++;
1823
0
    proto_tree_add_item(tree, hf_dvbci_err_flag,
1824
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
1825
0
    proto_tree_add_bitmask(tree, tvb, offset,
1826
0
            hf_dvbci_dlv_sys_hint, ett_dvbci_dlv_sys_hint,
1827
0
            dvbci_opp_dlv_sys_hint_fields, ENC_BIG_ENDIAN);
1828
0
    offset++;
1829
0
    proto_tree_add_item(tree, hf_dvbci_refr_req_date,
1830
0
            tvb, offset, 2, ENC_BIG_ENDIAN);
1831
0
    offset += 2;
1832
0
    proto_tree_add_item(tree, hf_dvbci_refr_req_time,
1833
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
1834
0
    offset++;
1835
1836
0
    return offset-offset_start;
1837
0
}
1838
1839
1840
/* dissect a capability loop in an operator_search_start apdu */
1841
static int
1842
dissect_opp_cap_loop(uint8_t cap_loop_len, const char *title,
1843
        int item_hf, unsigned item_len,
1844
        tvbuff_t *tvb, unsigned offset,
1845
        packet_info *pinfo _U_, proto_tree *tree)
1846
0
{
1847
0
    proto_tree *loop_tree = NULL;
1848
0
    unsigned    i;
1849
1850
0
    if (!title)
1851
0
        return -1;
1852
0
    if (item_len==0)
1853
0
        return -1;
1854
1855
0
    if (tree && cap_loop_len>0) {
1856
0
        loop_tree = proto_tree_add_subtree(tree, tvb, offset, cap_loop_len, ett_dvbci_opp_cap_loop, NULL, title);
1857
0
    }
1858
0
    for (i=0; i<item_len*cap_loop_len; i+=item_len) {
1859
0
        proto_tree_add_item(loop_tree, item_hf,
1860
0
                tvb, offset+i, item_len, ENC_BIG_ENDIAN);
1861
0
    }
1862
1863
0
    return cap_loop_len;
1864
0
}
1865
1866
1867
/* dissect age rating byte encoded as defined in
1868
   DVB-SI parental rating descriptor
1869
   returns rating's length in bytes or -1 for error */
1870
static int
1871
dissect_rating(tvbuff_t *tvb, unsigned offset,
1872
        packet_info *pinfo _U_, proto_tree *tree)
1873
0
{
1874
0
    uint8_t rating;
1875
1876
0
    rating = tvb_get_uint8(tvb, offset);
1877
0
    if (1<=rating && rating<=0x0F) {
1878
0
        proto_tree_add_uint_format(tree, hf_dvbci_rating,
1879
0
                tvb, offset, 1, rating,
1880
0
                "Rating is %d years (%d+3)", rating+3, rating);
1881
0
    } else {
1882
0
        proto_tree_add_uint_format(tree, hf_dvbci_rating,
1883
0
                tvb, offset, 1, rating,
1884
0
                "Rating is unknown/undefined (%d)", rating);
1885
0
    }
1886
1887
0
    return 1;
1888
0
}
1889
1890
1891
/* if there's a dissector for the protocol and target port of our
1892
    lsc connection, store it in the lsc session's circuit */
1893
static void
1894
store_lsc_msg_dissector(conversation_t *conv, uint8_t ip_proto, uint16_t port)
1895
0
{
1896
0
    dissector_handle_t msg_handle = NULL;
1897
1898
0
    if (!conv)
1899
0
        return;
1900
1901
0
    if (ip_proto==LSC_TCP)
1902
0
        msg_handle = dissector_get_uint_handle(tcp_dissector_table, port);
1903
0
    else if (ip_proto==LSC_UDP)
1904
0
        msg_handle = dissector_get_uint_handle(udp_dissector_table, port);
1905
1906
0
    conversation_set_dissector(conv, msg_handle);
1907
0
}
1908
1909
1910
/* dissect a connection_descriptor for the lsc resource
1911
   returns its length or -1 for error */
1912
static int
1913
dissect_conn_desc(tvbuff_t *tvb, unsigned offset, conversation_t *conv,
1914
        packet_info *pinfo, proto_tree *tree)
1915
0
{
1916
0
    proto_item *ti;
1917
0
    proto_tree *conn_desc_tree = NULL;
1918
0
    uint32_t    tag;
1919
0
    int         offset_start, offset_body;
1920
0
    uint32_t    len_field;
1921
0
    uint8_t     conn_desc_type;
1922
0
    uint8_t     ip_ver, ip_proto;
1923
0
    uint16_t    port;
1924
0
    proto_item *port_item      = NULL;
1925
0
    int         hostname_len;
1926
1927
0
    offset_start = offset;
1928
1929
0
    tag = tvb_get_ntoh24(tvb, offset);
1930
0
    if (tag!= T_CONNECTION_DESCRIPTOR)
1931
0
        return 0;
1932
1933
0
    conn_desc_tree = proto_tree_add_subtree(tree, tvb,
1934
0
            offset_start, -1, ett_dvbci_lsc_conn_desc, &ti, "Connection descriptor");
1935
1936
0
    proto_tree_add_item(conn_desc_tree, hf_dvbci_apdu_tag,
1937
0
            tvb, offset, APDU_TAG_SIZE, ENC_BIG_ENDIAN);
1938
0
    offset += APDU_TAG_SIZE;
1939
0
    offset = dissect_ber_length(pinfo, conn_desc_tree,
1940
0
                    tvb, offset, &len_field, NULL);
1941
0
    offset_body = offset;
1942
1943
0
    conn_desc_type = tvb_get_uint8(tvb, offset);
1944
0
    proto_tree_add_item(conn_desc_tree, hf_dvbci_conn_desc_type,
1945
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
1946
0
    offset++;
1947
1948
0
    if (conn_desc_type == CONN_DESC_IP) {
1949
0
        proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_media_tag,
1950
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
1951
0
        offset++;
1952
0
        proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_media_len,
1953
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
1954
0
        offset++;
1955
0
        ip_ver = tvb_get_uint8(tvb, offset);
1956
0
        proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_ip_ver,
1957
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
1958
0
        offset++;
1959
1960
0
        if (ip_ver == LSC_IPV4) {
1961
0
            offset += FT_IPv6_LEN-FT_IPv4_LEN;
1962
0
            proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_ipv4_addr,
1963
0
                    tvb, offset, FT_IPv4_LEN, ENC_BIG_ENDIAN);
1964
0
            offset += FT_IPv4_LEN;
1965
0
        }
1966
0
        else if (ip_ver == LSC_IPV6) {
1967
0
            proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_ipv6_addr,
1968
0
                    tvb, offset, FT_IPv6_LEN, ENC_NA);
1969
0
            offset += FT_IPv6_LEN;
1970
0
        }
1971
0
        else
1972
0
            offset += FT_IPv6_LEN;
1973
1974
0
        port_item = proto_tree_add_item_ret_uint16(conn_desc_tree,
1975
0
                hf_dvbci_lsc_dst_port, tvb, offset, 2, ENC_BIG_ENDIAN, &port);
1976
0
        offset +=2;
1977
0
        proto_tree_add_item_ret_uint8(conn_desc_tree, hf_dvbci_lsc_proto,
1978
0
                    tvb, offset, 1, ENC_BIG_ENDIAN, &ip_proto);
1979
0
        offset ++;
1980
0
        if (port_item) {
1981
0
            if (ip_proto==LSC_TCP && tcp_port_to_display(pinfo->pool, port)) {
1982
0
                proto_item_append_text(port_item, " (%s)",
1983
0
                        tcp_port_to_display(pinfo->pool, port));
1984
0
            }
1985
0
            else if (ip_proto==LSC_UDP && udp_port_to_display(pinfo->pool, port)) {
1986
0
                proto_item_append_text(port_item, " (%s)",
1987
0
                        udp_port_to_display(pinfo->pool, port));
1988
0
            }
1989
0
        }
1990
0
        store_lsc_msg_dissector(conv, ip_proto, port);
1991
1992
0
    } else if (conn_desc_type == CONN_DESC_HOSTNAME) {
1993
0
        proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_media_tag,
1994
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
1995
0
        offset++;
1996
0
        proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_media_len,
1997
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
1998
0
        offset++;
1999
0
        proto_tree_add_item_ret_uint8(conn_desc_tree, hf_dvbci_lsc_proto,
2000
0
                    tvb, offset, 1, ENC_BIG_ENDIAN, &ip_proto);
2001
0
        offset ++;
2002
0
        port_item = proto_tree_add_item_ret_uint16(conn_desc_tree,
2003
0
                hf_dvbci_lsc_dst_port, tvb, offset, 2, ENC_BIG_ENDIAN, &port);
2004
0
        offset +=2;
2005
0
        if (port_item) {
2006
0
            if (ip_proto==LSC_TCP && tcp_port_to_display(pinfo->pool, port)) {
2007
0
                proto_item_append_text(port_item, " (%s)",
2008
0
                        tcp_port_to_display(pinfo->pool, port));
2009
0
            }
2010
0
            else if (ip_proto==LSC_UDP && udp_port_to_display(pinfo->pool, port)) {
2011
0
                proto_item_append_text(port_item, " (%s)",
2012
0
                        udp_port_to_display(pinfo->pool, port));
2013
0
            }
2014
0
        }
2015
0
        store_lsc_msg_dissector(conv, ip_proto, port);
2016
2017
        /* everything from here to the descriptor's end is a hostname */
2018
0
        if ((unsigned)offset_body + len_field < offset) {
2019
0
            proto_tree_add_expert_format(conn_desc_tree, pinfo,
2020
0
                    &ei_dvbci_bad_length, tvb, offset_body, offset-offset_body,
2021
0
                    "Connection descriptor length %u is too short",
2022
0
                    len_field);
2023
0
            proto_item_set_len(ti, offset-offset_start);
2024
0
            return -1;
2025
0
        }
2026
0
        hostname_len = (offset_body+len_field)-offset;
2027
0
        proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_hostname,
2028
0
                tvb, offset, hostname_len, ENC_ASCII);
2029
0
        offset += hostname_len;
2030
0
    } else {
2031
0
        if (len_field < 1) {
2032
            /* the connection descriptor type is already outside the descriptor */
2033
0
            proto_tree_add_expert_format(conn_desc_tree, pinfo,
2034
0
                    &ei_dvbci_bad_length, tvb, offset_body, 1,
2035
0
                    "Connection descriptor length %u is too short",
2036
0
                    len_field);
2037
0
            proto_item_set_len(ti, offset-offset_start);
2038
0
            return -1;
2039
0
        }
2040
0
        proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_media_data,
2041
0
                tvb, offset, len_field-1, ENC_NA);
2042
0
        offset += len_field-1;
2043
0
    }
2044
2045
0
    proto_item_set_len(ti, offset-offset_start);
2046
0
    return offset-offset_start;
2047
0
}
2048
2049
2050
/* check if the given CC resource item may appear in the clear
2051
   as part of an exported PDU */
2052
static inline bool
2053
is_cc_item_exportable(uint8_t dat_id)
2054
0
{
2055
    /* the CCK precursor value does not contain sensitive information as such
2056
       nevertheless, it is safer to prevent people from exporting this value
2057
       accidentally */
2058
0
    if (dat_id == CC_ID_KP)
2059
0
        return false;
2060
    /* we could add some more items here which do not appear in SAC messages
2061
       normally: CC_ID_DHPH, CC_ID_DHPM */
2062
2063
0
    return true;
2064
0
}
2065
2066
2067
/* dissect the URI, return the number of bytes processed or -1 for error */
2068
static int
2069
dissect_uri(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree)
2070
0
{
2071
0
    int         offset_start;
2072
0
    uint8_t     uri_ver, emi, rl;
2073
0
    proto_item *rl_item;
2074
2075
0
    offset_start = offset;
2076
2077
0
    col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "URI");
2078
2079
0
    uri_ver = tvb_get_uint8(tvb, offset);
2080
0
    proto_tree_add_item(tree, hf_dvbci_uri_ver,
2081
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
2082
0
    offset++;
2083
2084
0
    proto_tree_add_item(tree, hf_dvbci_uri_aps,
2085
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
2086
0
    emi = (tvb_get_uint8(tvb, offset) & 0x30) >> 4;
2087
0
    proto_tree_add_item(tree, hf_dvbci_uri_emi,
2088
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
2089
0
    col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
2090
0
            val_to_str_const(emi, dvbci_cc_uri_emi, "unknown"));
2091
0
    proto_tree_add_item(tree, hf_dvbci_uri_ict,
2092
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
2093
0
    if (emi==CC_EMI_FREE) {
2094
0
        proto_tree_add_item(tree, hf_dvbci_uri_rct,
2095
0
                tvb, offset, 1, ENC_BIG_ENDIAN);
2096
0
    }
2097
0
    if (uri_ver>=2 && emi==CC_EMI_NEVER) {
2098
0
        proto_tree_add_item(tree, hf_dvbci_uri_dot,
2099
0
                tvb, offset, 1, ENC_BIG_ENDIAN);
2100
0
    }
2101
0
    offset++;
2102
2103
0
    if (emi==CC_EMI_NEVER) {
2104
0
        if (uri_ver==1)
2105
0
            rl = tvb_get_uint8(tvb, offset) & 0x3F;
2106
0
        else
2107
0
            rl = tvb_get_uint8(tvb, offset);
2108
2109
0
        rl_item = proto_tree_add_uint(tree, hf_dvbci_uri_rl,
2110
0
                tvb, offset, 1, rl);
2111
2112
0
        if (rl==0x00)
2113
0
            proto_item_append_text(rl_item, " (90 minutes)");
2114
0
        else if (rl==0x01)
2115
0
            proto_item_append_text(rl_item, " (6 hours)");
2116
0
        else if (rl==0x02)
2117
0
            proto_item_append_text(rl_item, " (12 hours)");
2118
0
        else if (uri_ver>=2 && rl==0xFF)
2119
0
            proto_item_append_text(rl_item, " (unlimited)");
2120
0
        else {
2121
            /* no need for a range check, rl 0x3F mask was applied above */
2122
0
            proto_item_append_text(rl_item, " (%d days)", rl-2);
2123
0
        }
2124
0
    }
2125
2126
0
    return offset-offset_start;
2127
0
}
2128
2129
2130
/* dissect a CI+ certificate with the CI+ specific X.509 extensions
2131
   enabled, and make sure that they are disabled again if the
2132
   certificate dissection throws an exception */
2133
static void
2134
dissect_ciplus_cert(tvbuff_t *tvb, unsigned offset, asn1_ctx_t *asn1_ctx,
2135
        proto_tree *tree, int hf_index)
2136
0
{
2137
0
    x509ce_enable_ciplus();
2138
0
    TRY {
2139
0
        dissect_x509af_Certificate(false, tvb, offset, asn1_ctx, tree, hf_index);
2140
0
    }
2141
0
    FINALLY {
2142
0
        x509ce_disable_ciplus();
2143
0
    }
2144
0
    ENDTRY;
2145
0
}
2146
2147
/* dissect an item from cc_(sac_)data_req/cc_(sac_)data_cnf,
2148
   returns its length or -1 for error
2149
   if dat_id_ptr is not NULL, fill in the datatype id */
2150
static int
2151
dissect_cc_item(tvbuff_t *tvb, unsigned offset,
2152
        packet_info *pinfo, proto_tree *tree, uint8_t *dat_id_ptr)
2153
0
{
2154
0
    proto_item *ti;
2155
0
    proto_tree *cc_item_tree = NULL;
2156
0
    int         offset_start;
2157
0
    uint16_t    dat_len;
2158
0
    uint8_t     dat_id;
2159
0
    asn1_ctx_t  asn1_ctx;
2160
0
    int         hf_cert_index;
2161
0
    uint16_t    prog_num;
2162
0
    uint8_t     status;
2163
2164
2165
0
    offset_start = offset;
2166
0
    dat_id = tvb_get_uint8(tvb, offset);
2167
0
    if (dat_id_ptr)
2168
0
        *dat_id_ptr = dat_id;
2169
2170
0
    cc_item_tree = proto_tree_add_subtree_format(tree, tvb, offset_start, -1, ett_dvbci_cc_item, &ti,
2171
0
        "CC data item: %s", val_to_str_const(dat_id, dvbci_cc_dat_id, "unknown"));
2172
2173
0
    proto_tree_add_item(cc_item_tree, hf_dvbci_cc_dat_id,
2174
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
2175
0
    offset++;
2176
0
    dat_len = tvb_get_ntohs(tvb, offset);
2177
0
    proto_tree_add_item(cc_item_tree, hf_dvbci_cc_dat_len,
2178
0
            tvb, offset, 2, ENC_BIG_ENDIAN);
2179
0
    offset += 2;
2180
0
    switch (dat_id) {
2181
0
        case CC_ID_HOST_BRAND_CERT:
2182
0
        case CC_ID_CICAM_BRAND_CERT:
2183
0
        case CC_ID_HOST_DEV_CERT:
2184
0
        case CC_ID_CICAM_DEV_CERT:
2185
0
            asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, true, pinfo);
2186
0
            hf_cert_index = (dat_id==CC_ID_HOST_BRAND_CERT ||
2187
0
                             dat_id==CC_ID_CICAM_BRAND_CERT) ?
2188
0
                hf_dvbci_brand_cert : hf_dvbci_dev_cert;
2189
2190
            /* enable dissection of CI+ specific X.509 extensions
2191
               only for our certificates */
2192
0
            dissect_ciplus_cert(tvb, offset, &asn1_ctx, cc_item_tree, hf_cert_index);
2193
0
            break;
2194
0
        case CC_ID_URI:
2195
0
            dissect_uri(tvb, offset, pinfo, cc_item_tree);
2196
0
            break;
2197
0
        case CC_ID_PROG_NUM:
2198
0
            prog_num = tvb_get_ntohs(tvb, offset);
2199
0
            col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
2200
0
                    "Program number 0x%x", prog_num);
2201
0
            proto_tree_add_item(cc_item_tree, hf_dvbci_cc_prog_num,
2202
0
                    tvb, offset, 2, ENC_BIG_ENDIAN);
2203
0
            break;
2204
0
        case CC_ID_KEY_REGISTER:
2205
0
            proto_tree_add_item(cc_item_tree, hf_dvbci_cc_key_register,
2206
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
2207
0
            break;
2208
0
        case CC_ID_STATUS_FIELD:
2209
0
        case CC_ID_REC_START_STATUS:
2210
0
        case CC_ID_MODE_CHG_STATUS:
2211
0
        case CC_ID_REC_STOP_STATUS:
2212
0
            status = tvb_get_uint8(tvb, offset);
2213
0
            col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Status: %s",
2214
0
                    val_to_str_const(status, dvbci_cc_status, "unknown"));
2215
0
            proto_tree_add_item(cc_item_tree, hf_dvbci_cc_status_field,
2216
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
2217
0
            break;
2218
0
        case CC_ID_OPERATING_MODE:
2219
0
            proto_tree_add_item(cc_item_tree, hf_dvbci_cc_op_mode,
2220
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
2221
0
            break;
2222
0
        default:
2223
0
            proto_tree_add_item(cc_item_tree, hf_dvbci_cc_data,
2224
0
                    tvb, offset, dat_len, ENC_NA);
2225
0
            break;
2226
0
    }
2227
0
    offset += dat_len;
2228
2229
0
    proto_item_set_len(ti, offset-offset_start);
2230
0
    return offset-offset_start;
2231
0
}
2232
2233
2234
/* add the CC protocol name and step to the info column */
2235
static void
2236
add_cc_protocol_name_step(packet_info *pinfo,
2237
    uint64_t snd_dat_ids, uint64_t req_dat_ids)
2238
0
{
2239
0
    bool chk_snd_ids = false;
2240
2241
0
    switch (req_dat_ids) {
2242
0
        case CC_ID_DHPH<<24|CC_ID_SIG_A<<16|CC_ID_HOST_DEV_CERT<<8|CC_ID_HOST_BRAND_CERT:
2243
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2244
0
                    "(Authentication Step 1)");
2245
0
            break;
2246
0
        case CC_ID_STATUS_FIELD:
2247
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2248
0
                    "(Authentication Step 3)");
2249
0
            break;
2250
0
        case CC_ID_AKH:
2251
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2252
0
                    "(AuthKey Step 1)");
2253
0
            break;
2254
0
        case CC_ID_HOST_ID<<8|CC_ID_STATUS_FIELD:
2255
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2256
0
                    "(CC key calculation Step 1)");
2257
0
            break;
2258
0
        case CC_ID_HOST_ID<<8|CC_ID_NS_HOST:
2259
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2260
0
                    "(SAC key calculation Step 1)");
2261
0
            break;
2262
0
        case CC_ID_URI_CNF:
2263
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2264
0
                    "(URI transmission Step 1)");
2265
0
            break;
2266
0
        case CC_ID_URI_VERSIONS:
2267
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2268
0
                    "(URI version negotiation Step 1)");
2269
0
            break;
2270
0
        case CC_ID_LICENSE_RCV_STATUS:
2271
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2272
0
                    "(CICAM to Host License Exchange Step 1)");
2273
0
            break;
2274
0
        case CC_ID_PROG_NUM<<24|CC_ID_LICENSE_STATUS<<16|CC_ID_URI<<8|CC_ID_CICAM_LICENSE:
2275
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2276
0
                    "(Playback License Exchange Step 1)");
2277
0
            break;
2278
0
        case CC_ID_LICENSE_STATUS<<8|CC_ID_PLAY_COUNT:
2279
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2280
0
                    "(License Check Exchange Step 1)");
2281
0
            break;
2282
0
        case CC_ID_REC_START_STATUS:
2283
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2284
0
                    "(Record Start Step 1)");
2285
0
            break;
2286
0
        case CC_ID_MODE_CHG_STATUS:
2287
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2288
0
                    "(Change Operating Mode Step 1)");
2289
0
            break;
2290
0
        case CC_ID_REC_STOP_STATUS:
2291
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2292
0
                    "(Record Stop Step 1)");
2293
0
            break;
2294
0
        case CC_ID_STATUS_FIELD<<8|CC_ID_SRM_CONFIRM:
2295
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2296
0
                    "(SRM Transmission Step 1)");
2297
0
            break;
2298
0
        default:
2299
            /* unable to determine the protocol from the requested ids
2300
               check the sent ids as well */
2301
0
            chk_snd_ids = true;
2302
0
            break;
2303
0
    }
2304
0
    if (!chk_snd_ids)
2305
0
        return;
2306
2307
0
    switch (snd_dat_ids) {
2308
0
        case CC_ID_DHPH<<24|CC_ID_SIG_A<<16|CC_ID_HOST_DEV_CERT<<8|CC_ID_HOST_BRAND_CERT:
2309
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2310
0
                    "(Authentication Step 2)");
2311
0
            break;
2312
0
        case CC_ID_STATUS_FIELD:
2313
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2314
0
                    "(Authentication Step 4)");
2315
0
            break;
2316
0
        case CC_ID_AKH:
2317
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2318
0
                    "(AuthKey Step 2)");
2319
0
            break;
2320
0
        case CC_ID_HOST_ID<<8|CC_ID_STATUS_FIELD:
2321
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2322
0
                    "(CC key calculation Step 2)");
2323
0
            break;
2324
0
        case CC_ID_HOST_ID<<8|CC_ID_NS_HOST:
2325
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2326
0
                    "(SAC key calculation Step 2)");
2327
0
            break;
2328
0
        case CC_ID_URI_CNF:
2329
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2330
0
                    "(URI transmission Step 2)");
2331
0
            break;
2332
0
        case CC_ID_URI_VERSIONS:
2333
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2334
0
                    "(URI version negotiation Step 2)");
2335
0
            break;
2336
0
        case CC_ID_LICENSE_RCV_STATUS:
2337
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2338
0
                    "(CICAM to Host License Exchange Step 2)");
2339
0
            break;
2340
0
        case CC_ID_PROG_NUM<<24|CC_ID_LICENSE_STATUS<<16|CC_ID_URI<<8|CC_ID_CICAM_LICENSE:
2341
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2342
0
                    "(Playback License Exchange Step 2)");
2343
0
            break;
2344
0
        case CC_ID_LICENSE_STATUS<<8|CC_ID_PLAY_COUNT:
2345
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2346
0
                    "(License Check Exchange Step 2)");
2347
0
            break;
2348
0
        case CC_ID_REC_START_STATUS:
2349
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2350
0
                    "(Record Start Step 2)");
2351
0
            break;
2352
0
        case CC_ID_MODE_CHG_STATUS:
2353
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2354
0
                    "(Change Operating Mode Step 2)");
2355
0
            break;
2356
0
        case CC_ID_REC_STOP_STATUS:
2357
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2358
0
                    "(Record Stop Step 2)");
2359
0
            break;
2360
0
        case CC_ID_STATUS_FIELD<<8|CC_ID_SRM_CONFIRM:
2361
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
2362
0
                    "(SRM Transmission Step 2)");
2363
0
            break;
2364
0
    }
2365
0
}
2366
2367
2368
/* dissect the payload of a cc message that contains data items
2369
   if not NULL, set exportable_flag to true if the message contains no
2370
    sensitive data and can be passed to the export PDU mechanism */
2371
static int
2372
dissect_cc_data_payload(uint32_t tag, tvbuff_t *tvb, unsigned offset,
2373
        packet_info *pinfo, proto_tree *tree, bool *exportable_flag)
2374
0
{
2375
0
    int         offset_start;
2376
0
    uint8_t     i, snd_dat_nbr, req_dat_nbr;
2377
0
    uint8_t     dat_id;
2378
0
    int         item_len;
2379
    /* the last 8 sent/requested datatype ids */
2380
0
    uint64_t    snd_dat_ids=0, req_dat_ids=0;
2381
2382
    /* we only export cc_sac_data_req and cc_sac_data_cnf
2383
       the only meta info in the exported PDU is the data transfer
2384
        direction, if we only ever export  cc_sac_data_req and
2385
        cc_sac_data_cnf, this info is enough to recover the apdu tag from the
2386
        direction
2387
       cc_sac_sync req and cc_sac_sync_cnf contain no interesting data */
2388
0
    if (exportable_flag)
2389
0
        *exportable_flag = (tag==T_CC_SAC_DATA_REQ || tag==T_CC_SAC_DATA_CNF);
2390
2391
0
    offset_start = offset;
2392
2393
0
    proto_tree_add_item(
2394
0
            tree, hf_dvbci_cc_sys_id_bitmask, tvb, offset, 1, ENC_BIG_ENDIAN);
2395
0
    offset++;
2396
0
    snd_dat_nbr = tvb_get_uint8(tvb, offset);
2397
0
    proto_tree_add_item(
2398
0
            tree, hf_dvbci_cc_snd_dat_nbr, tvb, offset, 1, ENC_BIG_ENDIAN);
2399
0
    offset++;
2400
0
    for(i=0; i<snd_dat_nbr &&
2401
0
            tvb_reported_length_remaining(tvb, offset)>0; i++) {
2402
0
        item_len = dissect_cc_item(tvb, offset, pinfo, tree, &dat_id);
2403
0
        if (item_len < 0)
2404
0
            return -1;
2405
0
        offset += item_len;
2406
        /* for more than 8 sent datatype ids, some ids might get lost by
2407
         * the shift, that's ok, we're only using the last 8 ids for
2408
         * protocol detection */
2409
0
        snd_dat_ids = snd_dat_ids<<8|dat_id;
2410
0
        if (!exportable_flag || *exportable_flag==false)
2411
0
            continue;
2412
0
        if (!is_cc_item_exportable(dat_id))
2413
0
            *exportable_flag = false;
2414
0
    }
2415
2416
0
    if (tag==T_CC_DATA_REQ || tag==T_CC_SAC_DATA_REQ) {
2417
0
        req_dat_nbr = tvb_get_uint8(tvb, offset);
2418
0
        proto_tree_add_item(
2419
0
                tree, hf_dvbci_cc_req_dat_nbr, tvb, offset, 1, ENC_BIG_ENDIAN);
2420
0
        offset++;
2421
0
        for(i=0; i<req_dat_nbr &&
2422
0
                tvb_reported_length_remaining(tvb, offset)>0; i++) {
2423
0
            dat_id = tvb_get_uint8(tvb, offset);
2424
0
            req_dat_ids = req_dat_ids<<8|dat_id;
2425
0
            proto_tree_add_item(
2426
0
                    tree, hf_dvbci_cc_dat_id, tvb, offset, 1, ENC_BIG_ENDIAN);
2427
0
            offset++;
2428
0
        }
2429
0
    }
2430
2431
0
    add_cc_protocol_name_step(pinfo, snd_dat_ids, req_dat_ids);
2432
2433
0
    return offset-offset_start;
2434
0
}
2435
2436
2437
/* convert a 0-terminated preference key_string that contains a hex number
2438
 *  into its binary representation
2439
 * e.g. key_string "abcd" will be converted into two bytes 0xab, 0xcd
2440
 * return the number of binary bytes or -1 for error */
2441
static int
2442
pref_key_string_to_bin(const char *key_string, unsigned char **key_bin)
2443
32
{
2444
32
    int  key_string_len;
2445
32
    int  i, j;
2446
32
    char input[3];
2447
2448
32
    if (!key_string || !key_bin)
2449
0
        return -1;
2450
32
    key_string_len = (int)strlen(key_string);
2451
32
    if (key_string_len != 2*AES_KEY_LEN)
2452
32
        return -1;
2453
0
    *key_bin = (unsigned char*)g_malloc(key_string_len/2);
2454
0
    input[2] = '\0';
2455
2456
0
    j=0;
2457
0
    for (i=0; i<key_string_len-1; i+=2) {
2458
0
        input[0] = key_string[0+i];
2459
0
        input[1] = key_string[1+i];
2460
        /* attention, brackets are required */
2461
0
        (*key_bin)[j++] = (unsigned char)strtoul((const char*)&input, NULL, 16);
2462
0
    }
2463
2464
0
    return key_string_len/2;
2465
32
}
2466
2467
2468
static tvbuff_t *
2469
decrypt_sac_msg_body(packet_info *pinfo,
2470
        uint8_t enc_cip, tvbuff_t *encrypted_tvb, unsigned offset, int len)
2471
0
{
2472
0
    bool             opened = false;
2473
0
    gcry_cipher_hd_t cipher;
2474
0
    gcry_error_t     err;
2475
0
    int              clear_len;
2476
0
    unsigned char    *clear_data = NULL;
2477
0
    tvbuff_t         *clear_tvb = NULL;
2478
2479
0
    if (enc_cip != CC_SAC_ENC_AES128_CBC)
2480
0
        goto end;
2481
0
    if (len%AES_BLOCK_LEN != 0)
2482
0
        goto end;
2483
2484
0
    if (!dvbci_sek_bin || !dvbci_siv_bin)
2485
0
        goto end;
2486
2487
0
    err = gcry_cipher_open(&cipher, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0);
2488
0
    if (gcry_err_code (err))
2489
0
        goto end;
2490
0
    opened = true;
2491
0
    err = gcry_cipher_setkey (cipher, dvbci_sek_bin, AES_KEY_LEN);
2492
0
    if (gcry_err_code (err))
2493
0
        goto end;
2494
0
    err = gcry_cipher_setiv (cipher, dvbci_siv_bin, AES_BLOCK_LEN);
2495
0
    if (gcry_err_code (err))
2496
0
        goto end;
2497
2498
0
    clear_len = len;
2499
0
    clear_data = (unsigned char *)wmem_alloc(pinfo->pool, clear_len);
2500
2501
0
    err = gcry_cipher_decrypt (cipher, clear_data, clear_len,
2502
0
            tvb_memdup(pinfo->pool, encrypted_tvb, offset, len), len);
2503
0
    if (gcry_err_code (err))
2504
0
        goto end;
2505
2506
0
    clear_tvb = tvb_new_child_real_data(encrypted_tvb,
2507
0
                        (const uint8_t *)clear_data, clear_len, clear_len);
2508
2509
0
end:
2510
0
    if (opened)
2511
0
        gcry_cipher_close (cipher);
2512
0
    return clear_tvb;
2513
0
}
2514
2515
2516
/* dissect a text string that is encoded according to DVB-SI (EN 300 468) */
2517
static void
2518
dissect_si_string(tvbuff_t *tvb, unsigned offset, int str_len,
2519
        packet_info *pinfo, proto_tree *tree, int hf, const char *title,
2520
        bool show_col_info)
2521
0
{
2522
0
    unsigned        enc_len;
2523
0
    dvb_encoding_e  encoding;
2524
0
    const char     *si_str = NULL;
2525
2526
0
    if (!title)  /* we always have a title for our strings */
2527
0
        return;
2528
    /* str_len==-1 is not supported, we need an actual length */
2529
0
    if (str_len<=0)
2530
0
        return;
2531
2532
0
    enc_len = dvb_analyze_string_charset(tvb, offset, str_len, &encoding);
2533
0
    dvb_add_chartbl(tree, hf_dvbci_mmi_char_tbl, tvb, offset, enc_len, encoding);
2534
2535
0
    offset += enc_len;
2536
0
    str_len -= enc_len;
2537
2538
0
    si_str = (char*)tvb_get_string_enc(pinfo->pool,
2539
0
            tvb, offset, str_len, dvb_enc_to_item_enc(encoding));
2540
0
    if (!si_str)
2541
0
        return;
2542
2543
0
    proto_tree_add_string_format(tree, hf,
2544
0
            tvb, offset, str_len, si_str, "%s: %s", title, si_str);
2545
2546
0
    if (show_col_info)
2547
0
        col_append_sep_str(pinfo->cinfo, COL_INFO, " ", si_str);
2548
0
}
2549
2550
2551
/* dissect ca_enable_flag and ca_enable fields in the ca_pmt_reply
2552
 * return true if descrambling is possible, false otherwise */
2553
static bool
2554
dissect_ca_enable(tvbuff_t *tvb, unsigned offset, packet_info *pinfo _U_,
2555
        proto_tree *tree)
2556
0
{
2557
0
    bool desc_ok = false;
2558
0
    uint8_t  byte, ca_enab;
2559
2560
0
    byte = tvb_get_uint8(tvb,offset);
2561
0
    proto_tree_add_item(tree, hf_dvbci_ca_enable_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
2562
0
    if (byte&0x80) {
2563
0
        ca_enab = byte & ~0x80;
2564
0
        proto_tree_add_item(tree, hf_dvbci_ca_enable, tvb, offset, 1, ENC_BIG_ENDIAN);
2565
0
        if (ca_enab==CA_ENAB_DESC_OK ||
2566
0
            ca_enab==CA_ENAB_DESC_OK_PURCHASE ||
2567
0
            ca_enab==CA_ENAB_DESC_OK_TECH) {
2568
0
            desc_ok = true;
2569
0
        }
2570
0
    }
2571
2572
0
    return desc_ok;
2573
0
}
2574
2575
2576
/* dissect a ca descriptor in the ca_pmt */
2577
static unsigned
2578
dissect_ca_desc(tvbuff_t *tvb, unsigned offset, packet_info *pinfo,
2579
        proto_tree *tree)
2580
0
{
2581
0
    unsigned         offset_start;
2582
0
    uint8_t     tag, len_byte;
2583
0
    proto_item *ti, *pi;
2584
0
    proto_tree *ca_desc_tree = NULL;
2585
2586
0
    offset_start = offset;
2587
2588
0
    tag = tvb_get_uint8(tvb,offset);
2589
0
    if (tag != CA_DESC_TAG) {
2590
        /* we could skip unknown descriptors and make this a warning */
2591
0
        proto_tree_add_expert(tree, pinfo, &ei_dvbci_ca_pmt_cmd_id, tvb, offset, 1);
2592
0
        return 0;
2593
0
    }
2594
2595
0
    ca_desc_tree = proto_tree_add_subtree(
2596
0
            tree, tvb, offset_start, -1, ett_dvbci_ca_desc, &ti, "Conditional Access descriptor");
2597
0
    offset++;
2598
2599
0
    len_byte = tvb_get_uint8(tvb,offset);
2600
0
    pi = proto_tree_add_item(
2601
0
            ca_desc_tree, hf_dvbci_descr_len, tvb, offset, 1, ENC_BIG_ENDIAN);
2602
0
    offset++;
2603
0
    if (len_byte < 4) {
2604
        /* CA_system_ID and CA_PID take 4 bytes */
2605
0
        expert_add_info_format(pinfo, pi, &ei_dvbci_bad_length,
2606
0
                "CA descriptor length %u is less than 4", len_byte);
2607
0
        proto_item_set_len(ti, offset-offset_start);
2608
0
        return 0;
2609
0
    }
2610
2611
0
    proto_tree_add_item(
2612
0
            ca_desc_tree, hf_dvbci_ca_sys_id, tvb, offset, 2, ENC_BIG_ENDIAN);
2613
0
    offset += 2;
2614
2615
0
    proto_tree_add_item(
2616
0
            ca_desc_tree, hf_dvbci_ca_pid, tvb, offset, 2, ENC_BIG_ENDIAN);
2617
0
    offset += 2;
2618
2619
0
    if ((len_byte-4) != 0) {
2620
0
        proto_tree_add_item(ca_desc_tree, hf_dvbci_ca_priv_data,
2621
0
                tvb, offset, len_byte-4, ENC_NA);
2622
0
        offset += (len_byte-4);
2623
0
    }
2624
2625
0
    proto_item_set_len(ti, offset-offset_start);
2626
0
    return offset-offset_start;
2627
0
}
2628
2629
2630
/* dissect an elementary stream entry in the ca_pmt
2631
   returns its length or 0 for error */
2632
static unsigned
2633
dissect_es(tvbuff_t *tvb, unsigned offset,
2634
        packet_info *pinfo, proto_tree *tree, bool *scrambled)
2635
0
{
2636
0
    proto_item *ti;
2637
0
    proto_tree *es_tree = NULL;
2638
0
    unsigned    offset_start, ca_desc_len;
2639
0
    unsigned    es_info_len, all_len;
2640
2641
0
    offset_start = offset;
2642
2643
0
    if (scrambled) {
2644
        /* default to free service until we found a ca descriptor
2645
           (we could have es info len > 0 and no ca descriptors) */
2646
0
        *scrambled = false;
2647
0
    }
2648
2649
0
    es_tree = proto_tree_add_subtree(tree, tvb, offset_start, -1, ett_dvbci_application, &ti, "Elementary Stream");
2650
2651
0
    proto_tree_add_item(
2652
0
            es_tree, hf_dvbci_stream_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2653
0
    offset++;
2654
0
    proto_tree_add_item(
2655
0
            es_tree, hf_dvbci_es_pid, tvb, offset, 2, ENC_BIG_ENDIAN);
2656
0
    offset += 2;
2657
0
    es_info_len = tvb_get_ntohs(tvb, offset) & 0x0FFF;
2658
    /* the definition of hf_dvbci_es_info_len also applies the mask */
2659
0
    proto_tree_add_item(
2660
0
            es_tree, hf_dvbci_es_info_len, tvb, offset, 2, ENC_BIG_ENDIAN);
2661
0
    offset += 2;
2662
0
    if (es_info_len>0) {
2663
0
        all_len = offset + es_info_len;
2664
2665
0
        proto_tree_add_item(
2666
0
                es_tree, hf_dvbci_ca_pmt_cmd_id, tvb, offset, 1, ENC_BIG_ENDIAN);
2667
0
        offset++;
2668
0
        while (offset < all_len) {
2669
0
            ca_desc_len = dissect_ca_desc(tvb, offset, pinfo, es_tree);
2670
0
            if (ca_desc_len == 0)
2671
0
                return 0;
2672
0
            offset += ca_desc_len;
2673
0
            if (scrambled)
2674
0
                *scrambled = true;
2675
0
        }
2676
0
    }
2677
0
    else {
2678
0
        proto_tree_add_expert(
2679
0
                es_tree, pinfo, &ei_dvbci_no_ca_desc_es, tvb, 0, 0);
2680
0
    }
2681
2682
0
    proto_item_set_len(ti, offset-offset_start);
2683
0
    return offset-offset_start;
2684
0
}
2685
2686
/* dissect a text pseudo-apdu */
2687
static int
2688
dissect_dvbci_text(const char *title, tvbuff_t *tvb, unsigned offset,
2689
                   packet_info *pinfo, proto_tree *tree, int hf)
2690
0
{
2691
0
    proto_item *ti;
2692
0
    proto_tree *text_tree;
2693
0
    uint32_t    tag;
2694
0
    int         offset_start;
2695
0
    uint32_t    len_field;
2696
2697
0
    offset_start = offset;
2698
2699
0
    if (!title)
2700
0
        return 0;
2701
2702
    /* check the tag before setting up the tree */
2703
0
    tag = tvb_get_ntoh24(tvb, offset);
2704
0
    if (tag!=T_TEXT_LAST && tag!=T_TEXT_MORE)
2705
0
        return 0;
2706
2707
0
    text_tree = proto_tree_add_subtree(tree, tvb, offset_start, -1, ett_dvbci_text, &ti, title);
2708
2709
0
    proto_tree_add_item(text_tree, hf_dvbci_apdu_tag,
2710
0
            tvb, offset, APDU_TAG_SIZE, ENC_BIG_ENDIAN);
2711
0
    offset += APDU_TAG_SIZE;
2712
0
    offset = dissect_ber_length(pinfo, text_tree, tvb, offset, &len_field, NULL);
2713
0
    dissect_si_string(tvb, offset, len_field, pinfo, text_tree,
2714
0
            hf, "Text", false);
2715
0
    offset += len_field;
2716
2717
0
    proto_item_set_len(ti, offset-offset_start);
2718
0
    return (offset-offset_start);
2719
0
}
2720
2721
2722
static proto_item *
2723
dissect_res_id(tvbuff_t *tvb, unsigned offset, packet_info *pinfo,
2724
        proto_tree *tree, uint32_t res_id, bool show_col_info)
2725
0
{
2726
    /* there's two possible inputs for this function
2727
        the resource id is either in a tvbuff_t (tvb!=NULL, res_id==0)
2728
        or in a uint32_t (tvb==NULL, res_id!=0) */
2729
2730
0
    if (tvb) {
2731
        /* resource id comes in via tvbuff */
2732
0
        if (res_id!=0)
2733
0
            return NULL;
2734
0
        res_id = tvb_get_ntohl(tvb, offset);
2735
0
    }
2736
0
    else {
2737
        /* resource id comes in via uint32_t */
2738
0
        if (res_id==0)
2739
0
            return NULL;
2740
        /* we'll call proto_tree_add_...( tvb==NULL, offset==0, length==0 )
2741
           this creates a filterable item without any reference to a tvb */
2742
0
        offset = 0;
2743
0
    }
2744
2745
0
    if (show_col_info) {
2746
0
        col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "%s Version %d",
2747
0
                val_to_str_const(RES_CLASS(res_id), dvbci_res_class,
2748
0
                    "Invalid Resource class"),
2749
0
                RES_VER(res_id));
2750
0
    }
2751
2752
0
    return proto_tree_add_bitmask_value_with_flags(tree, tvb, offset,
2753
0
            hf_dvbci_res_id, ett_dvbci_res, dvb_ci_res_id_fields, res_id,
2754
0
            BMT_NO_APPEND);
2755
0
}
2756
2757
/* dissect the body of a resource manager apdu */
2758
static void
2759
dissect_dvbci_payload_rm(uint32_t tag, int len_field,
2760
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
2761
        packet_info *pinfo, proto_tree *tree)
2762
0
{
2763
0
    const char *tag_str;
2764
2765
0
    if (tag==T_PROFILE) {
2766
0
        if (len_field % RES_ID_LEN) {
2767
0
            tag_str = val_to_str(pinfo->pool, tag, dvbci_apdu_tag, "Unknown: %d");
2768
0
            proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb, 0, APDU_TAG_SIZE,
2769
0
                   "Invalid APDU length field, %s must be a multiple of 4 bytes",
2770
0
                   tag_str);
2771
0
            return;
2772
0
        }
2773
2774
0
        while (tvb_reported_length_remaining(tvb, offset) > 0) {
2775
0
            dissect_res_id(tvb, offset, pinfo, tree, 0, false);
2776
0
            offset += RES_ID_LEN;
2777
0
        }
2778
0
    }
2779
0
}
2780
2781
static void
2782
dissect_dvbci_payload_ap(uint32_t tag, int len_field _U_,
2783
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
2784
        packet_info *pinfo, proto_tree *tree)
2785
0
{
2786
0
    uint8_t         menu_str_len;
2787
0
    unsigned        enc_len;
2788
0
    dvb_encoding_e  encoding;
2789
0
    const uint8_t  *menu_string;
2790
0
    uint8_t         data_rate;
2791
2792
0
    if (tag==T_APP_INFO) {
2793
0
        proto_tree_add_item(tree, hf_dvbci_app_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2794
0
        offset++;
2795
0
        proto_tree_add_item(
2796
0
                tree, hf_dvbci_app_manf, tvb, offset, 2, ENC_BIG_ENDIAN);
2797
0
        offset+=2;
2798
0
        proto_tree_add_item(
2799
0
                tree, hf_dvbci_manf_code, tvb, offset, 2, ENC_BIG_ENDIAN);
2800
0
        offset+=2;
2801
0
        menu_str_len = tvb_get_uint8(tvb,offset);
2802
0
        proto_tree_add_item(
2803
0
                tree, hf_dvbci_menu_str_len, tvb, offset, 1, ENC_BIG_ENDIAN);
2804
0
        offset++;
2805
0
        if (menu_str_len > 0) {
2806
0
            enc_len = dvb_analyze_string_charset(
2807
0
                    tvb, offset, menu_str_len, &encoding);
2808
0
            dvb_add_chartbl(
2809
0
                    tree, hf_dvbci_ap_char_tbl, tvb, offset, enc_len, encoding);
2810
0
            offset += enc_len;
2811
0
            menu_str_len -= enc_len;
2812
0
            proto_tree_add_item_ret_string(tree, hf_dvbci_menu_str,
2813
0
                    tvb, offset, menu_str_len, dvb_enc_to_item_enc(encoding),
2814
0
                    pinfo->pool, &menu_string);
2815
0
            col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
2816
0
                    "Module name %s", menu_string);
2817
0
        }
2818
0
    }
2819
0
    else if (tag== T_DATARATE_INFO) {
2820
0
        data_rate = tvb_get_uint8(tvb, offset);
2821
0
        col_append_sep_str(pinfo->cinfo, COL_INFO, ": ",
2822
0
                    val_to_str(pinfo->pool, data_rate, dvbci_data_rate, "unknown (0x%x)"));
2823
0
        proto_tree_add_item(tree, hf_dvbci_data_rate, tvb, offset, 1, ENC_BIG_ENDIAN);
2824
0
    }
2825
0
}
2826
2827
static void
2828
dissect_dvbci_payload_ca(uint32_t tag, int len_field,
2829
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
2830
        packet_info *pinfo, proto_tree *tree)
2831
0
{
2832
0
    const char *tag_str;
2833
0
    uint16_t     prog_num;
2834
0
    unsigned     prog_info_len;
2835
0
    unsigned     es_info_len, all_len;
2836
0
    unsigned     ca_desc_len;
2837
0
    bool         scrambled = false;
2838
0
    bool         es_scrambled = false;
2839
0
    proto_tree  *es_tree = NULL;
2840
0
    bool         desc_ok = false;
2841
2842
2843
0
    if (tag==T_CA_INFO) {
2844
0
        if (len_field % 2) {
2845
0
            tag_str = val_to_str(pinfo->pool, tag, dvbci_apdu_tag, "Unknown: %d");
2846
0
            proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb, 0, APDU_TAG_SIZE,
2847
0
                    "Invalid APDU length field, %s must be a multiple of 2 bytes",
2848
0
                    tag_str);
2849
0
            return;
2850
0
        }
2851
2852
0
        while (tvb_reported_length_remaining(tvb, offset) > 0) {
2853
0
            proto_tree_add_item(
2854
0
                    tree, hf_dvbci_ca_sys_id, tvb, offset, 2, ENC_BIG_ENDIAN);
2855
0
            offset += 2;
2856
0
        }
2857
0
    }
2858
0
    else if (tag==T_CA_PMT) {
2859
0
        proto_tree_add_item(
2860
0
                tree, hf_dvbci_ca_pmt_list_mgmt, tvb, offset, 1, ENC_BIG_ENDIAN);
2861
0
        offset++;
2862
0
        prog_num = tvb_get_ntohs(tvb, offset);
2863
0
        col_append_sep_fstr(
2864
0
                pinfo->cinfo, COL_INFO, NULL, "Program number %x", prog_num);
2865
0
        proto_tree_add_item(
2866
0
                tree, hf_dvbci_prog_num, tvb, offset, 2, ENC_BIG_ENDIAN);
2867
0
        offset += 2;
2868
0
        proto_tree_add_item(
2869
0
                tree, hf_dvbci_ca_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
2870
0
        proto_tree_add_item(
2871
0
                tree, hf_dvbci_curr_next, tvb, offset, 1, ENC_BIG_ENDIAN);
2872
0
        offset++;
2873
0
        prog_info_len = tvb_get_ntohs(tvb, offset) & 0x0FFF;
2874
        /* the definition of hf_dvbci_prog_info_len also applies the mask */
2875
0
        proto_tree_add_item(
2876
0
                tree, hf_dvbci_prog_info_len, tvb, offset, 2, ENC_BIG_ENDIAN);
2877
0
        offset += 2;
2878
0
        if (prog_info_len != 0) {
2879
0
            all_len = offset + prog_info_len;
2880
2881
0
            proto_tree_add_item(
2882
0
                    tree, hf_dvbci_ca_pmt_cmd_id, tvb, offset, 1, ENC_BIG_ENDIAN);
2883
0
            offset++;
2884
0
            while (offset < all_len) {
2885
0
                ca_desc_len = dissect_ca_desc(tvb, offset, pinfo, tree);
2886
0
                if (ca_desc_len == 0)
2887
0
                    return;
2888
0
                offset += ca_desc_len;
2889
                /* set this only if we've seen at least one valid ca descriptor */
2890
0
                scrambled = true;
2891
0
            }
2892
0
        }
2893
0
        else {
2894
0
            proto_tree_add_expert(
2895
0
                    tree, pinfo, &ei_dvbci_no_ca_desc_prog, tvb, 0, 0);
2896
0
        }
2897
2898
0
        while (tvb_reported_length_remaining(tvb, offset) > 0) {
2899
0
            es_info_len = dissect_es(tvb, offset, pinfo, tree, &es_scrambled);
2900
0
            if (es_info_len == 0)
2901
0
                return;
2902
0
            offset += es_info_len;
2903
0
            if (es_scrambled)
2904
0
                scrambled = true;
2905
0
        }
2906
2907
0
        col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
2908
0
                scrambled ? "scrambled service" : "free service");
2909
0
    }
2910
0
    else if (tag==T_CA_PMT_REPLY) {
2911
0
        prog_num = tvb_get_ntohs(tvb, offset);
2912
0
        col_append_sep_fstr(
2913
0
                pinfo->cinfo, COL_INFO, NULL, "Program number %x", prog_num);
2914
0
        proto_tree_add_item(
2915
0
                tree, hf_dvbci_prog_num, tvb, offset, 2, ENC_BIG_ENDIAN);
2916
0
        offset += 2;
2917
0
        proto_tree_add_item(
2918
0
                tree, hf_dvbci_ca_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
2919
0
        proto_tree_add_item(
2920
0
                tree, hf_dvbci_curr_next, tvb, offset, 1, ENC_BIG_ENDIAN);
2921
0
        offset++;
2922
0
        desc_ok |= dissect_ca_enable(tvb, offset, pinfo, tree);
2923
0
        offset++;
2924
0
        while (tvb_reported_length_remaining(tvb, offset) > 0) {
2925
            /* there's no need to check for tree==NULL */
2926
0
            es_tree = proto_tree_add_subtree(tree, tvb, offset, 3, ett_dvbci_application, NULL, "Elementary Stream");
2927
2928
0
            proto_tree_add_item(es_tree, hf_dvbci_es_pid,
2929
0
                    tvb, offset, 2, ENC_BIG_ENDIAN);
2930
0
            offset += 2;
2931
0
            desc_ok |= dissect_ca_enable(tvb, offset, pinfo, es_tree);
2932
0
            offset++;
2933
0
        }
2934
0
        if (desc_ok) {
2935
0
            col_append_sep_str(
2936
0
                pinfo->cinfo, COL_INFO, NULL, "descrambling possible");
2937
0
        }
2938
0
     }
2939
0
}
2940
2941
2942
static void
2943
dissect_dvbci_payload_aut(uint32_t tag, int len_field _U_,
2944
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
2945
        packet_info *pinfo _U_, proto_tree *tree)
2946
0
{
2947
0
    int bytes_len;
2948
2949
0
    proto_tree_add_item(tree, hf_dvbci_auth_proto_id,
2950
0
            tvb, offset, 2, ENC_BIG_ENDIAN);
2951
0
    offset += 2;
2952
2953
0
    bytes_len = tvb_reported_length_remaining(tvb, offset);
2954
0
    if (bytes_len <= 0)
2955
0
        return;
2956
2957
0
    if (tag==T_AUTH_REQ) {
2958
0
        proto_tree_add_item(tree, hf_dvbci_auth_req_bytes,
2959
0
            tvb, offset, bytes_len, ENC_NA);
2960
0
    }
2961
0
    else if (tag==T_AUTH_RESP) {
2962
0
        proto_tree_add_item(tree, hf_dvbci_auth_resp_bytes,
2963
0
            tvb, offset, bytes_len, ENC_NA);
2964
0
    }
2965
0
}
2966
2967
2968
static void
2969
dissect_dvbci_payload_hc(uint32_t tag, int len_field _U_,
2970
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
2971
        packet_info *pinfo, proto_tree *tree)
2972
0
{
2973
0
    proto_item *pi;
2974
0
    uint16_t    nid, onid, tsid, svcid;
2975
0
    uint8_t     ref;
2976
0
    uint16_t    old_pid, new_pid;
2977
0
    bool        pmt_flag;
2978
0
    int         desc_loop_len;
2979
0
    tvbuff_t   *pmt_tvb = NULL;
2980
0
    uint8_t     status;
2981
2982
2983
0
    switch (tag) {
2984
0
        case T_TUNE:
2985
0
            nid = tvb_get_ntohs(tvb, offset);
2986
0
            pi = proto_tree_add_item(
2987
0
                    tree, hf_dvbci_network_id, tvb, offset, 2, ENC_BIG_ENDIAN);
2988
0
            if (nid) {
2989
0
                expert_add_info(pinfo, pi, &ei_dvbci_network_id);
2990
0
            }
2991
0
            offset += 2;
2992
0
            onid = tvb_get_ntohs(tvb, offset);
2993
0
            proto_tree_add_item(tree, hf_dvbci_original_network_id,
2994
0
                    tvb, offset, 2, ENC_BIG_ENDIAN);
2995
0
            offset += 2;
2996
0
            tsid = tvb_get_ntohs(tvb, offset);
2997
0
            proto_tree_add_item(tree, hf_dvbci_transport_stream_id,
2998
0
                    tvb, offset, 2, ENC_BIG_ENDIAN);
2999
0
            offset += 2;
3000
0
            svcid = tvb_get_ntohs(tvb, offset);
3001
0
            proto_tree_add_item(
3002
0
                    tree, hf_dvbci_service_id, tvb, offset, 2, ENC_BIG_ENDIAN);
3003
0
            col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
3004
0
                    "nid 0x%x, onid 0x%x, tsid 0x%x, svcid 0x%x",
3005
0
                    nid, onid, tsid, svcid);
3006
0
            break;
3007
0
        case T_REPLACE:
3008
0
            proto_tree_add_item_ret_uint8(tree, hf_dvbci_replacement_ref,
3009
0
                    tvb, offset, 1, ENC_BIG_ENDIAN, &ref);
3010
0
            offset++;
3011
0
            proto_tree_add_item_ret_uint16(tree, hf_dvbci_replaced_pid,
3012
0
                    tvb, offset, 2, ENC_BIG_ENDIAN, &old_pid);
3013
0
            offset += 2;
3014
0
            proto_tree_add_item_ret_uint16( tree, hf_dvbci_replacement_pid,
3015
0
                    tvb, offset, 2, ENC_BIG_ENDIAN, &new_pid);
3016
0
            col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
3017
0
                    "ref 0x%x, 0x%x -> 0x%x", ref, old_pid, new_pid);
3018
0
            break;
3019
0
        case T_CLEAR_REPLACE:
3020
0
            proto_tree_add_item_ret_uint8(tree, hf_dvbci_replacement_ref,
3021
0
                    tvb, offset, 1, ENC_BIG_ENDIAN, &ref);
3022
0
            col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "ref 0x%x", ref);
3023
0
            break;
3024
0
        case T_TUNE_BROADCAST_REQ:
3025
0
            pmt_flag = ((tvb_get_uint8(tvb, offset) & 0x01) == 0x01);
3026
0
            proto_tree_add_item(tree, hf_dvbci_pmt_flag,
3027
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3028
0
            offset++;
3029
0
            proto_tree_add_item(
3030
0
                    tree, hf_dvbci_service_id, tvb, offset, 2, ENC_BIG_ENDIAN);
3031
0
            offset += 2;
3032
0
            desc_loop_len = dissect_desc_loop(hf_dvbci_hc_desc_loop_len,
3033
0
                                tvb, offset, pinfo, tree);
3034
0
            if (desc_loop_len<0)
3035
0
                break;
3036
0
            offset += desc_loop_len;
3037
0
            if (pmt_flag) {
3038
0
                pmt_tvb = tvb_new_subset_remaining(tvb, offset);
3039
0
                if (mpeg_pmt_handle) {
3040
0
                    col_append_str(pinfo->cinfo, COL_INFO, ", ");
3041
                    /* prevent mpeg_pmt dissector from clearing col_info */
3042
0
                    col_set_fence(pinfo->cinfo, COL_INFO);
3043
0
                    call_dissector(mpeg_pmt_handle, pmt_tvb, pinfo, tree);
3044
0
                }
3045
0
                else
3046
0
                    call_dissector(data_handle, pmt_tvb, pinfo, tree);
3047
0
            }
3048
0
            break;
3049
0
        case T_TUNE_REPLY:
3050
0
            proto_tree_add_item_ret_uint8(tree, hf_dvbci_hc_status,
3051
0
                    tvb, offset, 1, ENC_BIG_ENDIAN, &status);
3052
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, ": ",
3053
0
                        (status == HC_STAT_OK ?  "ok" : "error"));
3054
0
            break;
3055
0
        case T_ASK_RELEASE_REPLY:
3056
0
            proto_tree_add_item(tree, hf_dvbci_hc_release_reply,
3057
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3058
0
            break;
3059
0
        default:
3060
0
            break;
3061
0
    }
3062
0
}
3063
3064
3065
static void
3066
dissect_dvbci_payload_dt(uint32_t tag, int len_field,
3067
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
3068
        packet_info *pinfo, proto_tree *tree)
3069
0
{
3070
0
    nstime_t     resp_intv;
3071
0
    proto_item  *pi = NULL;
3072
0
    const char *tag_str;
3073
0
    int          time_field_len;
3074
0
    nstime_t     utc_time;
3075
0
    int16_t      local_offset;  /* field in the apdu */
3076
3077
3078
0
    if (tag==T_DATE_TIME_ENQ) {
3079
0
        nstime_set_zero(&resp_intv);
3080
0
        resp_intv.secs = tvb_get_uint8(tvb, offset);
3081
0
        pi = proto_tree_add_time(tree, hf_dvbci_resp_intv,
3082
0
                tvb, offset, 1, &resp_intv);
3083
0
        if (resp_intv.secs==0) {
3084
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "individual query");
3085
0
            proto_item_append_text(pi, " (individual query)");
3086
0
        }
3087
0
        else {
3088
0
            col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
3089
0
                    "update every %s", rel_time_to_str(pinfo->pool, &resp_intv));
3090
0
        }
3091
0
    }
3092
0
    else if (tag==T_DATE_TIME) {
3093
0
        if (len_field!=5 && len_field!=7) {
3094
0
            tag_str = val_to_str_const(tag, dvbci_apdu_tag, "unknown");
3095
0
            proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb, APDU_TAG_SIZE, offset-APDU_TAG_SIZE,
3096
0
                    "Invalid APDU length field, %s must be 5 or 7 bytes", tag_str);
3097
0
            return;
3098
0
        }
3099
3100
0
        time_field_len = packet_mpeg_sect_mjd_to_utc_time(tvb, offset, &utc_time);
3101
0
        if (time_field_len<0) {
3102
0
            proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb, offset, 5,
3103
0
                "Invalid UTC time field, 2 bytes MJD, 3 bytes BCD time hhmmss");
3104
0
            return;
3105
0
        }
3106
0
        proto_tree_add_time(tree, hf_dvbci_utc_time,
3107
0
                tvb, offset, time_field_len, &utc_time);
3108
0
        col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s UTC",
3109
0
                abs_time_to_str(pinfo->pool, &utc_time, ABSOLUTE_TIME_UTC, false));
3110
0
        offset += time_field_len;
3111
3112
0
        if (len_field==7) {
3113
0
            local_offset = two_comp_to_int16(tvb_get_ntohs(tvb, offset));
3114
0
            proto_tree_add_int_format(tree, hf_dvbci_local_offset,
3115
0
                    tvb, offset, 2, local_offset,
3116
0
                    "offset between UTC and local time is %d minutes",
3117
0
                    local_offset);
3118
0
        }
3119
0
        else {
3120
0
            proto_tree_add_expert(tree, pinfo, &ei_dvbci_time_offs_unknown,
3121
0
                    tvb, 0, 0);
3122
0
        }
3123
0
    }
3124
0
}
3125
3126
3127
static void
3128
dissect_dvbci_payload_mmi(uint32_t tag, int len_field,
3129
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
3130
        packet_info *pinfo, proto_tree *tree)
3131
0
{
3132
0
    int             offset_start;
3133
0
    proto_item     *pi;
3134
0
    uint8_t         close_mmi_cmd_id;
3135
0
    uint8_t         disp_ctl_cmd, disp_rep_id;
3136
0
    const char     *disp_ctl_cmd_str = NULL, *disp_rep_id_str = NULL;
3137
0
    int             msg_len;
3138
0
    unsigned        enc_len;
3139
0
    dvb_encoding_e  encoding;
3140
0
    uint8_t         ans_txt_len;
3141
0
    uint8_t         ans_id;
3142
0
    uint8_t         choice_or_item_nb;
3143
0
    int             text_len;
3144
0
    uint8_t         choice_ref;
3145
3146
3147
0
    offset_start = offset;
3148
3149
0
    switch(tag) {
3150
0
        case T_CLOSE_MMI:
3151
0
            close_mmi_cmd_id = tvb_get_uint8(tvb,offset);
3152
0
            proto_tree_add_item(tree, hf_dvbci_close_mmi_cmd_id,
3153
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3154
0
            offset++;
3155
            /* apdu layer len field checks are sufficient for "immediate" */
3156
0
            if (close_mmi_cmd_id == CLOSE_MMI_CMD_ID_DELAY) {
3157
0
                if (len_field != 2) {
3158
0
                    proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb,
3159
0
                            APDU_TAG_SIZE, offset_start-APDU_TAG_SIZE,
3160
0
                            "Length field must be 2");
3161
0
                    return;
3162
0
                }
3163
0
                proto_tree_add_item(tree, hf_dvbci_close_mmi_delay, tvb,
3164
0
                        offset, 1, ENC_BIG_ENDIAN);
3165
0
            }
3166
0
            break;
3167
0
        case T_DISPLAY_CONTROL:
3168
0
            disp_ctl_cmd = tvb_get_uint8(tvb,offset);
3169
0
            disp_ctl_cmd_str = val_to_str_const(disp_ctl_cmd,
3170
0
                                                dvbci_disp_ctl_cmd, "unknown command");
3171
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, ": ",
3172
0
                    disp_ctl_cmd_str);
3173
0
            proto_tree_add_item(tree, hf_dvbci_disp_ctl_cmd, tvb,
3174
0
                    offset, 1, ENC_BIG_ENDIAN);
3175
0
            offset++;
3176
0
            if (disp_ctl_cmd == DISP_CMD_SET_MMI_MODE)
3177
0
            {
3178
0
                proto_tree_add_item(tree, hf_dvbci_mmi_mode, tvb,
3179
0
                        offset, 1, ENC_BIG_ENDIAN);
3180
0
                if (len_field != 2) {
3181
0
                    proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb,
3182
0
                            APDU_TAG_SIZE, offset_start-APDU_TAG_SIZE,
3183
0
                            "Length field must be 2");
3184
0
                    return;
3185
0
                }
3186
0
            }
3187
0
            break;
3188
0
        case T_DISPLAY_REPLY:
3189
0
            disp_rep_id = tvb_get_uint8(tvb,offset);
3190
0
            disp_rep_id_str = val_to_str_const(disp_rep_id,
3191
0
                    dvbci_disp_rep_id, "unknown command");
3192
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, ": ",
3193
0
                    disp_rep_id_str);
3194
0
            proto_tree_add_item(tree, hf_dvbci_disp_rep_id,
3195
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3196
0
            offset++;
3197
0
            if (disp_rep_id == DISP_REP_ID_MMI_MODE_ACK) {
3198
0
                proto_tree_add_item(tree, hf_dvbci_mmi_mode,
3199
0
                        tvb, offset, 1, ENC_BIG_ENDIAN);
3200
0
            }
3201
0
            else if (disp_rep_id == DISP_REP_ID_DISP_CHAR_TBL ||
3202
0
                     disp_rep_id == DISP_REP_ID_INP_CHAR_TBL) {
3203
0
                while ((msg_len=tvb_reported_length_remaining(tvb, offset)) > 0) {
3204
0
                    enc_len = dvb_analyze_string_charset(
3205
0
                            tvb, offset, msg_len, &encoding);
3206
0
                    if (enc_len==0) {
3207
0
                        proto_tree_add_expert(tree, pinfo,
3208
0
                            &ei_dvbci_invalid_char_tbl, tvb, offset, msg_len);
3209
0
                        break;
3210
0
                    }
3211
0
                    dvb_add_chartbl(tree, hf_dvbci_mmi_char_tbl,
3212
0
                            tvb, offset, enc_len, encoding);
3213
0
                    offset += enc_len;
3214
0
                 }
3215
0
            }
3216
0
            break;
3217
0
        case T_ENQ:
3218
0
            proto_tree_add_item(tree, hf_dvbci_blind_ans,
3219
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3220
0
            offset++;
3221
0
            ans_txt_len = tvb_get_uint8(tvb,offset);
3222
0
            pi = proto_tree_add_item(tree, hf_dvbci_ans_txt_len,
3223
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3224
0
            if (ans_txt_len == NB_UNKNOWN) {
3225
0
                proto_item_append_text(pi,
3226
0
                        " (Length of expected answer is unknown)");
3227
0
            }
3228
0
            offset++;
3229
0
            dissect_si_string(tvb, offset,
3230
0
                    tvb_reported_length_remaining(tvb, offset),
3231
0
                    pinfo, tree, hf_dvbci_enq, "Enquiry string", false);
3232
0
            break;
3233
0
        case T_ANSW:
3234
0
            proto_tree_add_item_ret_uint8(tree, hf_dvbci_ans_id, tvb, offset, 1, ENC_BIG_ENDIAN, &ans_id);
3235
0
            offset++;
3236
0
            if (ans_id == ANSW_ID_ANSWER) {
3237
0
                dissect_si_string(tvb, offset,
3238
0
                    tvb_reported_length_remaining(tvb, offset),
3239
0
                    pinfo, tree, hf_dvbci_ans, "Answer", true);
3240
0
            }
3241
0
            break;
3242
0
        case T_MENU_LAST:
3243
0
        case T_MENU_MORE:
3244
0
        case T_LIST_LAST:
3245
0
        case T_LIST_MORE:
3246
0
            choice_or_item_nb = tvb_get_uint8(tvb,offset);
3247
0
            if (IS_MENU_APDU(tag)) {
3248
0
                pi = proto_tree_add_item(
3249
0
                        tree, hf_dvbci_choice_nb, tvb, offset, 1, ENC_BIG_ENDIAN);
3250
0
                if (choice_or_item_nb == NB_UNKNOWN) {
3251
0
                    proto_item_append_text(pi,
3252
0
                            " (Number of choices is unknown)");
3253
0
                }
3254
0
            }
3255
0
            else {
3256
0
                pi = proto_tree_add_item(
3257
0
                        tree, hf_dvbci_item_nb, tvb, offset, 1, ENC_BIG_ENDIAN);
3258
0
                if (choice_or_item_nb == NB_UNKNOWN) {
3259
0
                    proto_item_append_text(pi,
3260
0
                            "(Number of items is unknown)");
3261
0
                }
3262
0
            }
3263
0
            offset++;
3264
0
            text_len = dissect_dvbci_text("Title", tvb, offset,
3265
0
                    pinfo, tree, hf_dvbci_title);
3266
0
            offset += text_len;
3267
0
            text_len = dissect_dvbci_text("Sub-title", tvb, offset,
3268
0
                    pinfo, tree, hf_dvbci_subtitle);
3269
0
            offset += text_len;
3270
0
            text_len = dissect_dvbci_text("Bottom line", tvb, offset,
3271
0
                    pinfo, tree, hf_dvbci_bottom);
3272
0
            offset += text_len;
3273
0
            while (tvb_reported_length_remaining(tvb, offset) > 0) {
3274
0
                text_len = dissect_dvbci_text("Item", tvb, offset, pinfo, tree, hf_dvbci_item);
3275
                /* minimum is apdu tag + 1 byte len field */
3276
0
                if (text_len<APDU_TAG_SIZE+1) {
3277
0
                    proto_tree_add_expert_remaining(tree, pinfo, &ei_dvbci_not_text_more_or_text_last, tvb, offset);
3278
0
                    return;
3279
0
                }
3280
0
                offset += text_len;
3281
0
            }
3282
0
            break;
3283
0
        case T_MENU_ANSW:
3284
0
            choice_ref = tvb_get_uint8(tvb,offset);
3285
0
            pi = proto_tree_add_item(
3286
0
                    tree, hf_dvbci_choice_ref, tvb, offset, 1, ENC_BIG_ENDIAN);
3287
0
            if (choice_ref == 0x0) {
3288
0
                proto_item_append_text(pi, " (Selection was cancelled)");
3289
0
                col_append_sep_str(pinfo->cinfo, COL_INFO, ": ",
3290
0
                        "cancelled");
3291
0
            }
3292
0
            else {
3293
0
                col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
3294
0
                        "Item %d", choice_ref);
3295
0
            }
3296
0
            break;
3297
0
        default:
3298
0
            break;
3299
0
    }
3300
0
}
3301
3302
3303
static void
3304
dissect_dvbci_payload_hlc(uint32_t tag, int len_field _U_,
3305
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
3306
        packet_info *pinfo, proto_tree *tree)
3307
0
{
3308
0
  const char *str;
3309
3310
0
  if (tag==T_HOST_COUNTRY) {
3311
0
      proto_tree_add_item(tree, hf_dvbci_host_country,
3312
0
              tvb, offset, tvb_reported_length_remaining(tvb, offset),
3313
0
              ENC_ISO_8859_1);
3314
0
  }
3315
0
  else if (tag==T_HOST_LANGUAGE) {
3316
0
      proto_tree_add_item(tree, hf_dvbci_host_language,
3317
0
              tvb, offset, tvb_reported_length_remaining(tvb, offset),
3318
0
              ENC_ISO_8859_1);
3319
0
  }
3320
3321
  /* both apdus' body is only a country code, this can be shared */
3322
0
  str = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset,
3323
0
              tvb_reported_length_remaining(tvb, offset),
3324
0
              ENC_ISO_8859_1|ENC_NA);
3325
0
  if (str)
3326
0
      col_append_sep_str(pinfo->cinfo, COL_INFO, ": ", str);
3327
0
}
3328
3329
3330
static void
3331
dissect_dvbci_payload_cup(uint32_t tag, int len_field _U_,
3332
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
3333
        packet_info *pinfo, proto_tree *tree)
3334
0
{
3335
0
  uint8_t     upgrade_type;
3336
0
  uint16_t    download_time;
3337
0
  uint8_t     answer, progress;
3338
3339
0
  switch(tag) {
3340
0
    case T_CAM_FIRMWARE_UPGRADE:
3341
0
      proto_tree_add_item_ret_uint8(tree, hf_dvbci_cup_type, tvb, offset, 1, ENC_BIG_ENDIAN, &upgrade_type);
3342
0
      col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "(%s)",
3343
0
                    val_to_str_const(upgrade_type, dvbci_cup_type, "unknown"));
3344
0
      offset++;
3345
0
      download_time = tvb_get_ntohs(tvb, offset);
3346
0
      if (download_time == 0) {
3347
0
          proto_tree_add_uint_format(tree, hf_dvbci_cup_download_time,
3348
0
                  tvb, offset, 2, download_time,
3349
0
                  "estimated download time is unknown");
3350
0
      }
3351
0
      else {
3352
0
          proto_tree_add_uint_format(tree, hf_dvbci_cup_download_time,
3353
0
                  tvb, offset, 2, download_time,
3354
0
                  "estimated download time is %d seconds",
3355
0
                  download_time);
3356
0
      }
3357
0
      break;
3358
0
    case T_CAM_FIRMWARE_UPGRADE_REPLY:
3359
0
      proto_tree_add_item_ret_uint8(tree, hf_dvbci_cup_answer, tvb, offset, 1, ENC_BIG_ENDIAN, &answer);
3360
0
      col_append_sep_str(pinfo->cinfo, COL_INFO, ": ",
3361
0
                    val_to_str_const(answer, dvbci_cup_answer, "unknown"));
3362
0
      break;
3363
0
    case T_CAM_FIRMWARE_UPGRADE_PROGRESS:
3364
0
      progress = tvb_get_uint8(tvb, offset);
3365
0
      if (progress > 100) {
3366
0
        proto_tree_add_expert(tree, pinfo, &ei_dvbci_cup_progress, tvb, offset, 1);
3367
0
      }
3368
0
      else {
3369
0
          col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%d%%", progress);
3370
0
          proto_tree_add_uint_format(tree, hf_dvbci_cup_progress,
3371
0
                  tvb, offset, 1, progress,
3372
0
                  "download progress %d%%", progress);
3373
0
      }
3374
0
      break;
3375
0
    case T_CAM_FIRMWARE_UPGRADE_COMPLETE:
3376
0
      proto_tree_add_item(tree, hf_dvbci_cup_reset, tvb, offset, 1, ENC_BIG_ENDIAN);
3377
0
      break;
3378
0
    default:
3379
0
      break;
3380
0
  }
3381
0
}
3382
3383
static int exp_pdu_data_dvbci_size(packet_info *pinfo _U_, void* data _U_)
3384
0
{
3385
0
  return EXP_PDU_TAG_DVBCI_EVT_LEN + 4;
3386
0
}
3387
3388
static int exp_pdu_data_dvbci_populate_data(packet_info *pinfo, void* data, uint8_t *tlv_buffer, uint32_t buffer_size _U_)
3389
0
{
3390
0
  phtonu16(&tlv_buffer[0], EXP_PDU_TAG_DVBCI_EVT);
3391
0
  phtonu16(&tlv_buffer[2], EXP_PDU_TAG_DVBCI_EVT_LEN);
3392
0
  tlv_buffer[4] = dvbci_get_evt_from_addrs(pinfo);
3393
3394
0
  return exp_pdu_data_dvbci_size(pinfo, data);
3395
0
}
3396
3397
static exp_pdu_data_item_t exp_pdu_dvbci = {exp_pdu_data_dvbci_size, exp_pdu_data_dvbci_populate_data, NULL};
3398
3399
static void
3400
dissect_sac_msg(uint32_t tag, tvbuff_t *tvb, unsigned offset,
3401
        packet_info *pinfo, proto_tree *tree, bool exported)
3402
0
{
3403
0
    int         offset_start;
3404
0
    uint32_t    msg_ctr;
3405
0
    uint8_t     enc_flag, enc_cip;
3406
0
    proto_item *enc_flag_pi;
3407
0
    uint16_t    sac_payload_len;          /* payload data and padding */
3408
0
    int         sac_payload_data_len = 0; /* just payload data */
3409
0
    tvbuff_t   *clear_sac_body_tvb;
3410
0
    proto_tree *sac_tree             = NULL;
3411
0
    bool        is_exportable        = false;
3412
3413
0
    offset_start = offset;
3414
3415
    /* it's not useful to move sac header dissection to a separate
3416
       function, we need enc/auth cipher etc here to handle the body */
3417
0
    msg_ctr = tvb_get_ntohl(tvb, offset);
3418
0
    proto_tree_add_item(tree, hf_dvbci_sac_msg_ctr,
3419
0
            tvb, offset, 4, ENC_BIG_ENDIAN);
3420
0
    col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
3421
0
            "message #%d", msg_ctr);
3422
0
    offset += 4;
3423
0
    proto_tree_add_item(tree, hf_dvbci_sac_proto_ver,
3424
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
3425
0
    proto_tree_add_item(tree, hf_dvbci_sac_auth_cip,
3426
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
3427
0
    enc_flag = tvb_get_uint8(tvb, offset) & 0x1;
3428
0
    enc_flag_pi = proto_tree_add_item(tree, hf_dvbci_sac_payload_enc,
3429
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
3430
0
    if (exported && enc_flag) {
3431
0
        expert_add_info(pinfo, enc_flag_pi, &ei_dvbci_sac_payload_enc);
3432
0
        enc_flag = 0;
3433
0
    }
3434
0
    offset++;
3435
0
    enc_cip = (tvb_get_uint8(tvb, offset)&0xE0) >> 5;
3436
0
    proto_tree_add_item(tree, hf_dvbci_sac_enc_cip,
3437
0
            tvb, offset, 1, ENC_BIG_ENDIAN);
3438
0
    offset++;
3439
0
    sac_payload_len = tvb_get_ntohs(tvb, offset);
3440
0
    proto_tree_add_item(tree, hf_dvbci_sac_payload_len,
3441
0
            tvb, offset, 2, ENC_BIG_ENDIAN);
3442
0
    offset += 2;
3443
0
    if (enc_flag) {
3444
0
        clear_sac_body_tvb = decrypt_sac_msg_body(pinfo, enc_cip,
3445
0
                tvb, offset, tvb_reported_length_remaining(tvb, offset));
3446
0
    }
3447
0
    else {
3448
0
        clear_sac_body_tvb = tvb_new_subset_remaining(tvb, offset);
3449
0
    }
3450
0
    if (!clear_sac_body_tvb) {
3451
        /* we could not decrypt (or access) the clear sac message body */
3452
0
        proto_tree_add_item(tree, hf_dvbci_sac_enc_body, tvb, offset,
3453
0
                tvb_reported_length_remaining(tvb, offset), ENC_NA);
3454
0
        return;
3455
0
    }
3456
0
    if (enc_flag)
3457
0
        add_new_data_source(pinfo, clear_sac_body_tvb, "Clear SAC message body");
3458
0
    if (sac_payload_len>0) {
3459
0
        sac_tree = proto_tree_add_subtree(tree, clear_sac_body_tvb, 0, sac_payload_len,
3460
0
                ett_dvbci_sac_msg_body, NULL, "SAC message payload");
3461
0
        if (tag==T_CC_SAC_DATA_REQ || tag==T_CC_SAC_DATA_CNF) {
3462
0
            sac_payload_data_len = dissect_cc_data_payload(tag,
3463
0
                    clear_sac_body_tvb, 0, pinfo, sac_tree, &is_exportable);
3464
0
        }
3465
0
        else if (tag==T_CC_SAC_SYNC_REQ) {
3466
0
            sac_payload_data_len = 0;
3467
0
        }
3468
0
        else if (tag==T_CC_SAC_SYNC_CNF) {
3469
0
            proto_tree_add_item(sac_tree, hf_dvbci_cc_status_field,
3470
0
                    clear_sac_body_tvb, 0, 1, ENC_BIG_ENDIAN);
3471
0
            sac_payload_data_len = 1;
3472
0
        }
3473
3474
0
        if (sac_payload_data_len < 0)
3475
0
            return;
3476
0
        if (sac_payload_len > sac_payload_data_len) {
3477
0
            proto_tree_add_item(sac_tree, hf_dvbci_sac_padding,
3478
0
                    clear_sac_body_tvb, sac_payload_data_len,
3479
0
                    sac_payload_len-sac_payload_data_len, ENC_NA);
3480
0
        }
3481
0
    }
3482
0
    proto_tree_add_item(tree, hf_dvbci_sac_signature,
3483
0
            clear_sac_body_tvb, sac_payload_len,
3484
0
            tvb_reported_length_remaining(clear_sac_body_tvb,
3485
0
                sac_payload_len), ENC_NA);
3486
3487
    /* we call this function also to dissect exported SAC messages,
3488
        don't try to export them a second time */
3489
0
    if (!exported && is_exportable && have_tap_listener(exported_pdu_tap)) {
3490
0
        static const exp_pdu_data_item_t *dvbci_exp_pdu_items[] = {
3491
0
            &exp_pdu_dvbci,
3492
0
            NULL
3493
0
        };
3494
3495
0
        tvbuff_t       *clear_sac_msg_tvb;
3496
0
        exp_pdu_data_t *exp_pdu_data;
3497
3498
0
        clear_sac_msg_tvb = tvb_new_composite();
3499
0
        tvb_composite_append(clear_sac_msg_tvb,
3500
0
                tvb_clone_offset_len(tvb, offset_start, SAC_MSG_HDR_LEN));
3501
0
        tvb_composite_append(clear_sac_msg_tvb, clear_sac_body_tvb);
3502
0
        tvb_composite_finalize(clear_sac_msg_tvb);
3503
3504
0
        exp_pdu_data = export_pdu_create_tags(pinfo, EXPORTED_SAC_MSG_PROTO, EXP_PDU_TAG_DISSECTOR_NAME, dvbci_exp_pdu_items);
3505
3506
0
        exp_pdu_data->tvb_captured_length = tvb_captured_length(clear_sac_msg_tvb);
3507
0
        exp_pdu_data->tvb_reported_length = tvb_reported_length(clear_sac_msg_tvb);
3508
0
        exp_pdu_data->pdu_tvb = clear_sac_msg_tvb;
3509
0
        tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
3510
0
    }
3511
0
}
3512
3513
3514
static int
3515
dissect_dvbci_exported_sac_msg(
3516
        tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
3517
0
{
3518
0
    uint8_t evt;
3519
0
    uint32_t tag;
3520
3521
0
    evt = dvbci_get_evt_from_addrs(pinfo);
3522
0
    if (!IS_DATA_TRANSFER(evt))
3523
0
        return 0;
3524
3525
0
    col_append_sep_str(pinfo->cinfo, COL_PROTOCOL, NULL, EXPORTED_SAC_MSG_DESCRIPTION);
3526
0
    col_clear(pinfo->cinfo, COL_INFO);
3527
3528
    /* we only export cc_sac_data_req and _cnf, therefore, the tag can be
3529
       derived from the direction of the transfer */
3530
0
    if (evt== DVBCI_EVT_DATA_CAM_TO_HOST)
3531
0
       tag = T_CC_SAC_DATA_REQ;
3532
0
    else
3533
0
       tag = T_CC_SAC_DATA_CNF;
3534
3535
0
    col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
3536
0
            val_to_str_const(tag, dvbci_apdu_tag, "unknown"));
3537
3538
0
    dissect_sac_msg(tag, tvb, 0, pinfo, tree, true);
3539
0
    return tvb_reported_length(tvb);
3540
0
}
3541
3542
3543
static void
3544
dissect_dvbci_payload_cc(uint32_t tag, int len_field _U_,
3545
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
3546
        packet_info *pinfo, proto_tree *tree)
3547
0
{
3548
0
    uint8_t     status;
3549
0
    proto_item *pi;
3550
0
    nstime_t    utc_time;
3551
0
    uint8_t     pin_stat;
3552
0
    uint8_t     evt_cent;
3553
3554
0
    switch(tag) {
3555
0
        case T_CC_OPEN_CNF:
3556
0
            proto_tree_add_item(tree, hf_dvbci_cc_sys_id_bitmask,
3557
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3558
0
            break;
3559
0
        case T_CC_DATA_REQ:
3560
0
        case T_CC_DATA_CNF:
3561
0
            dissect_cc_data_payload(tag, tvb, offset, pinfo, tree, NULL);
3562
0
            break;
3563
0
        case T_CC_SYNC_CNF:
3564
0
            status = tvb_get_uint8(tvb, offset);
3565
0
            proto_tree_add_item(
3566
0
                    tree, hf_dvbci_cc_status_field, tvb, offset, 1, ENC_BIG_ENDIAN);
3567
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, ": ",
3568
0
                    val_to_str_const(status, dvbci_cc_status, "unknown"));
3569
0
            break;
3570
0
        case T_CC_SAC_DATA_REQ:
3571
0
        case T_CC_SAC_DATA_CNF:
3572
0
        case T_CC_SAC_SYNC_REQ:
3573
0
        case T_CC_SAC_SYNC_CNF:
3574
0
            dissect_sac_msg(tag, tvb, offset, pinfo, tree, false);
3575
0
            break;
3576
0
        case T_CC_PIN_CAPABILITIES_REPLY:
3577
0
            proto_tree_add_item(tree, hf_dvbci_capability_field,
3578
0
                    tvb, offset, 1 , ENC_BIG_ENDIAN);
3579
0
            offset++;
3580
            /* we can't call packet_mpeg_sect_mjd_to_utc_time()
3581
               and check with nstime_is_zero() */
3582
0
            if (tvb_get_ntoh40(tvb, offset) == 0) {
3583
0
                proto_tree_add_expert(tree, pinfo, &ei_dvbci_cc_pin_nvr_chg,
3584
0
                        tvb, offset, UTC_TIME_LEN);
3585
0
            }
3586
0
            else {
3587
0
                if (packet_mpeg_sect_mjd_to_utc_time(tvb, offset, &utc_time) < 0) {
3588
0
                    proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb, offset, UTC_TIME_LEN,
3589
0
                            "Invalid UTC time field, 2 bytes MJD, 3 bytes BCD time hhmmss");
3590
0
                    break;
3591
0
                }
3592
0
                else {
3593
0
                    proto_tree_add_time(tree, hf_dvbci_pin_chg_time,
3594
0
                            tvb, offset, UTC_TIME_LEN, &utc_time);
3595
0
                }
3596
0
            }
3597
0
            offset += UTC_TIME_LEN;
3598
0
            dissect_rating(tvb, offset, pinfo, tree);
3599
0
            break;
3600
0
        case T_CC_PIN_REPLY:
3601
0
            pin_stat = tvb_get_uint8(tvb, offset);
3602
0
            proto_tree_add_item(tree, hf_dvbci_pincode_status,
3603
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3604
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, ": ",
3605
0
                    val_to_str_const(pin_stat, dvbci_pincode_status, "unknown"));
3606
0
            break;
3607
0
        case T_CC_PIN_EVENT:
3608
0
            proto_tree_add_item(tree, hf_dvbci_cc_prog_num,
3609
0
                    tvb, offset, 2, ENC_BIG_ENDIAN);
3610
0
            offset += 2;
3611
0
            proto_tree_add_item(tree, hf_dvbci_pincode_status,
3612
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3613
0
            offset++;
3614
0
            dissect_rating(tvb, offset, pinfo, tree);
3615
0
            offset++;
3616
0
            if (packet_mpeg_sect_mjd_to_utc_time(tvb, offset, &utc_time) < 0) {
3617
0
                proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb, offset, UTC_TIME_LEN,
3618
0
                        "Invalid UTC time field, 2 bytes MJD, 3 bytes BCD time hhmmss");
3619
0
                break;
3620
0
            }
3621
0
            else {
3622
0
                proto_tree_add_time(tree, hf_dvbci_pin_evt_time,
3623
0
                        tvb, offset, UTC_TIME_LEN, &utc_time);
3624
0
            }
3625
0
            offset += UTC_TIME_LEN;
3626
0
            evt_cent = tvb_get_uint8(tvb, offset);
3627
0
            pi = proto_tree_add_item(tree, hf_dvbci_pin_evt_cent,
3628
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3629
0
            if (evt_cent > 100) {
3630
0
                expert_add_info(pinfo, pi, &ei_dvbci_pin_evt_cent);
3631
0
            }
3632
0
            offset++;
3633
            /* length field was already checked by the caller */
3634
0
            proto_tree_add_item(tree, hf_dvbci_cc_priv_data, tvb, offset,
3635
0
                    tvb_reported_length_remaining(tvb, offset), ENC_NA);
3636
0
            break;
3637
0
        case T_CC_PIN_PLAYBACK:
3638
0
            dissect_rating(tvb, offset, pinfo, tree);
3639
0
            offset++;
3640
            /* length field was already checked by the caller */
3641
0
            proto_tree_add_item(tree, hf_dvbci_cc_priv_data, tvb, offset,
3642
0
                    tvb_reported_length_remaining(tvb, offset), ENC_NA);
3643
0
            break;
3644
0
        case T_CC_PIN_CMD:
3645
0
        case T_CC_PIN_MMI_REQ:
3646
0
            proto_tree_add_item(tree, hf_dvbci_pincode, tvb, offset,
3647
0
                    tvb_reported_length_remaining(tvb, offset),
3648
0
                    ENC_ASCII);
3649
0
            break;
3650
0
        default:
3651
0
            break;
3652
0
    }
3653
0
}
3654
3655
3656
static void
3657
dissect_dvbci_ami_file_req(tvbuff_t *tvb, unsigned offset,
3658
        packet_info *pinfo, proto_tree *tree)
3659
0
{
3660
0
    uint8_t req_type;
3661
0
    const char *req_str;
3662
3663
0
    proto_tree_add_item_ret_uint8(tree, hf_dvbci_req_type, tvb, offset, 1, ENC_BIG_ENDIAN, &req_type);
3664
0
    col_append_sep_str(pinfo->cinfo, COL_INFO, ": ",
3665
0
            val_to_str_const(req_type, dvbci_req_type, "unknown"));
3666
0
    offset++;
3667
0
    if (req_type==REQ_TYPE_FILE_HASH) {
3668
0
        proto_tree_add_item(tree, hf_dvbci_file_hash,
3669
0
                tvb, offset, 16, ENC_NA);
3670
0
        offset += 16;
3671
0
    }
3672
0
    if (tvb_reported_length_remaining(tvb, offset) <= 0) {
3673
0
        return;
3674
0
    }
3675
0
    if (req_type==REQ_TYPE_FILE || req_type==REQ_TYPE_FILE_HASH) {
3676
0
        proto_tree_add_item_ret_string(tree, hf_dvbci_file_name,
3677
0
                tvb, offset, tvb_reported_length_remaining(tvb, offset),
3678
0
                ENC_ASCII, pinfo->pool, (const uint8_t**)&req_str);
3679
0
        col_append_sep_str(pinfo->cinfo, COL_INFO, " ", req_str);
3680
0
    }
3681
0
    else if (req_type==REQ_TYPE_DATA) {
3682
0
        proto_tree_add_item(tree, hf_dvbci_ami_priv_data, tvb, offset,
3683
0
                tvb_reported_length_remaining(tvb, offset), ENC_NA);
3684
0
    }
3685
0
}
3686
3687
3688
static void
3689
dissect_dvbci_ami_file_ack(tvbuff_t *tvb, unsigned offset,
3690
        packet_info *pinfo, proto_tree *tree)
3691
0
{
3692
0
    uint8_t     req_type;
3693
0
    bool        req_ok = false, file_ok;
3694
0
    uint8_t     file_name_len;
3695
0
    const char *file_name_str;
3696
0
    uint32_t    file_data_len;
3697
0
    proto_tree *req_tree;
3698
3699
0
    req_type = tvb_get_uint8(tvb, offset+1);
3700
0
    if (req_type==REQ_TYPE_FILE_HASH) {
3701
0
        req_ok = ((tvb_get_uint8(tvb, offset) & 0x02) == 0x02);
3702
0
        proto_tree_add_item(tree, hf_dvbci_req_ok,
3703
0
                tvb, offset, 1, ENC_BIG_ENDIAN);
3704
0
    }
3705
0
    proto_tree_add_item_ret_boolean(tree, hf_dvbci_file_ok, tvb, offset, 1, ENC_BIG_ENDIAN, &file_ok);
3706
0
    offset++;
3707
0
    proto_tree_add_item(tree, hf_dvbci_req_type, tvb, offset, 1, ENC_BIG_ENDIAN);
3708
0
    col_append_sep_str(pinfo->cinfo, COL_INFO, ": ",
3709
0
            val_to_str_const(req_type, dvbci_req_type, "unknown"));
3710
0
    offset++;
3711
0
    if (req_type==REQ_TYPE_FILE || req_type==REQ_TYPE_FILE_HASH) {
3712
0
        file_name_len = tvb_get_uint8(tvb, offset);
3713
0
        proto_tree_add_item(tree, hf_dvbci_file_name_len,
3714
0
                tvb, offset, 1, ENC_BIG_ENDIAN);
3715
0
        offset++;
3716
0
        file_name_str = (char*)tvb_get_string_enc(pinfo->pool,
3717
0
                tvb, offset, file_name_len, ENC_ASCII);
3718
0
        if (!file_name_str)
3719
0
            return;
3720
0
        col_append_sep_str(pinfo->cinfo, COL_INFO, " ",
3721
0
                file_name_str);
3722
0
        proto_tree_add_string(tree, hf_dvbci_file_name,
3723
0
                tvb, offset, file_name_len, file_name_str);
3724
0
        offset += file_name_len;
3725
0
        file_data_len = tvb_get_ntohl(tvb, offset);
3726
0
        proto_tree_add_item(tree, hf_dvbci_file_data_len,
3727
0
                tvb, offset, 4, ENC_BIG_ENDIAN);
3728
0
        offset += 4;
3729
0
        if (file_data_len > 0) {
3730
0
            col_append_str(pinfo->cinfo, COL_PROTOCOL, ", ");
3731
0
            col_set_fence(pinfo->cinfo, COL_PROTOCOL);
3732
            /* The mime_encap dissector may overwrite this part. */
3733
0
            col_append_str(pinfo->cinfo, COL_PROTOCOL, "Data");
3734
0
            col_set_fence(pinfo->cinfo, COL_INFO);
3735
0
            call_dissector(mime_handle,
3736
0
                    tvb_new_subset_length(tvb, offset, file_data_len),
3737
0
                    pinfo, tree);
3738
0
        }
3739
0
    }
3740
0
    else if (req_type==REQ_TYPE_DATA) {
3741
0
        if (tvb_reported_length_remaining(tvb, offset) <= 0)
3742
0
            return;
3743
0
        proto_tree_add_item(tree, hf_dvbci_ami_priv_data, tvb, offset,
3744
0
                tvb_reported_length_remaining(tvb, offset), ENC_NA);
3745
0
    }
3746
0
    else if (req_type==REQ_TYPE_REQ) {
3747
0
        req_tree = proto_tree_add_subtree(tree, tvb,
3748
0
                offset, tvb_reported_length_remaining(tvb, offset),
3749
0
                ett_dvbci_ami_req_types, NULL, "Supported request types");
3750
0
        while (tvb_reported_length_remaining(tvb, offset) > 0) {
3751
0
            proto_tree_add_item(req_tree, hf_dvbci_req_type,
3752
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3753
0
            offset++;
3754
0
        }
3755
0
    }
3756
3757
0
    if (req_type==REQ_TYPE_FILE_HASH && req_ok && !file_ok) {
3758
0
        col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
3759
0
                "cached copy is valid");
3760
0
    }
3761
0
}
3762
3763
3764
static void
3765
dissect_dvbci_payload_ami(uint32_t tag, int len_field _U_,
3766
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
3767
        packet_info *pinfo, proto_tree *tree)
3768
0
{
3769
0
    uint8_t app_dom_id_len, init_obj_len;
3770
0
    const uint8_t *app_dom_id;
3771
0
    uint8_t ack_code;
3772
3773
0
    switch(tag) {
3774
0
        case T_REQUEST_START:
3775
            /* no filter for length items */
3776
0
            app_dom_id_len = tvb_get_uint8(tvb, offset);
3777
0
            proto_tree_add_item(tree, hf_dvbci_app_dom_id_len,
3778
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3779
0
            offset++;
3780
0
            init_obj_len = tvb_get_uint8(tvb, offset);
3781
0
            proto_tree_add_item(tree, hf_dvbci_init_obj_len,
3782
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3783
0
            offset++;
3784
0
            proto_tree_add_item_ret_string(tree, hf_dvbci_app_dom_id,
3785
0
                    tvb, offset, app_dom_id_len, ENC_ASCII|ENC_NA, pinfo->pool, &app_dom_id);
3786
0
            if (app_dom_id) {
3787
0
                col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
3788
0
                        "for %s", app_dom_id);
3789
0
            }
3790
0
            offset += app_dom_id_len;
3791
0
            proto_tree_add_item(tree, hf_dvbci_init_obj,
3792
0
                    tvb, offset, init_obj_len, ENC_ASCII);
3793
0
            break;
3794
0
        case T_REQUEST_START_ACK:
3795
0
            ack_code = tvb_get_uint8(tvb, offset);
3796
0
            proto_tree_add_item(
3797
0
                    tree, hf_dvbci_ack_code, tvb, offset, 1, ENC_BIG_ENDIAN);
3798
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, ": ",
3799
0
                    val_to_str_const(ack_code, dvbci_ack_code, "unknown"));
3800
0
            break;
3801
0
        case T_FILE_REQUEST:
3802
0
            dissect_dvbci_ami_file_req(tvb, offset, pinfo, tree);
3803
0
            break;
3804
0
        case T_FILE_ACKNOWLEDGE:
3805
0
            dissect_dvbci_ami_file_ack(tvb, offset, pinfo, tree);
3806
0
            break;
3807
0
        case T_APP_ABORT_REQUEST:
3808
0
            if (tvb_reported_length_remaining(tvb, offset) > 0) {
3809
0
                proto_tree_add_item(tree, hf_dvbci_abort_req_code, tvb, offset,
3810
0
                        tvb_reported_length_remaining(tvb, offset), ENC_NA);
3811
0
            }
3812
0
            break;
3813
0
        case T_APP_ABORT_ACK:
3814
0
            if (tvb_reported_length_remaining(tvb, offset) > 0) {
3815
0
                proto_tree_add_item(tree, hf_dvbci_abort_ack_code, tvb, offset,
3816
0
                        tvb_reported_length_remaining(tvb, offset), ENC_NA);
3817
0
            }
3818
0
            break;
3819
0
        default:
3820
0
            break;
3821
0
    }
3822
0
}
3823
3824
3825
static void
3826
dissect_dvbci_payload_lsc(uint32_t tag, int len_field,
3827
        tvbuff_t *tvb, unsigned offset, conversation_t *conv,
3828
        packet_info *pinfo, proto_tree *tree)
3829
0
{
3830
0
    int                 offset_start;
3831
0
    uint8_t             id, timeout, ret_val, phase_id;
3832
0
    int                 conn_desc_len, param_len;
3833
0
    uint16_t            buf_size;
3834
0
    proto_item         *pi          = NULL;
3835
0
    const char         *ret_val_str = NULL;
3836
0
    int                 msg_len;
3837
0
    tvbuff_t           *msg_tvb;
3838
0
    dissector_handle_t  msg_handle;
3839
0
    uint32_t            conn_state, i, num_dns_srv;
3840
3841
0
    offset_start = offset;
3842
3843
0
    switch(tag) {
3844
0
        case T_COMMS_CMD:
3845
0
            proto_tree_add_item(tree, hf_dvbci_comms_cmd_id,
3846
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3847
0
            id = tvb_get_uint8(tvb, offset);
3848
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, ": ",
3849
0
                    val_to_str(pinfo->pool, id, dvbci_comms_cmd_id, "Unknown: %d"));
3850
0
            offset++;
3851
0
            switch(id) {
3852
0
                case COMMS_CMD_ID_CONNECT_ON_CHANNEL:
3853
0
                    conn_desc_len = dissect_conn_desc(tvb, offset,
3854
0
                            conv, pinfo, tree);
3855
0
                    if (conn_desc_len < 0)
3856
0
                        break;
3857
0
                    offset += conn_desc_len;
3858
0
                    proto_tree_add_item(tree, hf_dvbci_lsc_retry_count,
3859
0
                            tvb, offset, 1, ENC_BIG_ENDIAN);
3860
0
                    offset++;
3861
0
                    timeout = tvb_get_uint8(tvb, offset);
3862
0
                    if (timeout==0) {
3863
0
                        proto_tree_add_uint_format(tree, hf_dvbci_lsc_timeout,
3864
0
                                tvb, offset, 1, timeout, "Infinite timeout");
3865
0
                    } else {
3866
0
                        proto_tree_add_uint_format(tree, hf_dvbci_lsc_timeout,
3867
0
                                tvb, offset, 1, timeout,
3868
0
                                "Timeout is %d seconds", timeout);
3869
0
                    }
3870
0
                    break;
3871
0
                case COMMS_CMD_ID_DISCONNECT_ON_CHANNEL:
3872
0
                case COMMS_CMD_ID_ENQUIRE_STATUS:
3873
                    /* len_field == 1 -> only id, no further parameters */
3874
0
                    if (len_field != 1) {
3875
0
                        proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb,
3876
0
                            APDU_TAG_SIZE, offset_start-APDU_TAG_SIZE,
3877
0
                            "Length field must be 1");
3878
0
                    }
3879
0
                    break;
3880
0
                case COMMS_CMD_ID_SET_PARAMS:
3881
0
                    param_len = tvb_reported_length_remaining(tvb, offset);
3882
0
                    if (param_len == 2)
3883
0
                        buf_size = (uint16_t)tvb_get_uint8(tvb, offset);
3884
0
                    else if (param_len == 3)
3885
0
                        buf_size = tvb_get_ntohs(tvb, offset);
3886
0
                    else {
3887
                        /* length field == 1 byte id + param_len */
3888
0
                        proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb,
3889
0
                            APDU_TAG_SIZE, offset_start-APDU_TAG_SIZE,
3890
0
                            "Length field must be 3 or 4");
3891
0
                        break;
3892
0
                    }
3893
0
                    proto_tree_add_uint_format(tree, hf_dvbci_lsc_buf_size,
3894
0
                            tvb, offset, param_len-1, buf_size,
3895
0
                            "buffer size %d bytes", buf_size);
3896
0
                    offset += param_len-1;
3897
0
                    timeout = tvb_get_uint8(tvb, offset);
3898
0
                    proto_tree_add_uint_format(tree, hf_dvbci_lsc_timeout,
3899
0
                            tvb, offset, 1, timeout,
3900
0
                            "timeout is %d milliseconds", timeout*10);
3901
0
                    break;
3902
0
                case COMMS_CMD_ID_GET_NEXT_BUFFER:
3903
0
                    phase_id = tvb_get_uint8(tvb, offset);
3904
0
                    proto_tree_add_item(tree, hf_dvbci_phase_id,
3905
0
                            tvb, offset, 1, ENC_BIG_ENDIAN);
3906
0
                    col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
3907
0
                            "received #%d", phase_id);
3908
0
                    break;
3909
0
                default:
3910
0
                    break;
3911
0
            }
3912
0
            break;
3913
0
        case T_COMMS_REPLY:
3914
0
            proto_tree_add_item(tree, hf_dvbci_comms_rep_id,
3915
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3916
0
            id = tvb_get_uint8(tvb,offset);
3917
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
3918
0
                    val_to_str(pinfo->pool, id, dvbci_comms_rep_id, "Unknown: %d"));
3919
0
            offset++;
3920
0
            ret_val = tvb_get_uint8(tvb,offset);
3921
0
            pi = proto_tree_add_item(tree, hf_dvbci_lsc_ret_val,
3922
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3923
0
            switch (id) {
3924
0
                case COMMS_REP_ID_SEND_ACK:
3925
0
                    col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
3926
0
                        "sent #%d", ret_val);
3927
0
                    proto_item_append_text(pi, " (sent #%d)", ret_val);
3928
0
                    break;
3929
0
                case COMMS_REP_ID_SET_PARAMS_ACK:
3930
0
                    ret_val_str = val_to_str_const(ret_val,
3931
0
                            dvbci_lsc_ret_val_params, "unknown/error");
3932
0
                    break;
3933
0
                case COMMS_REP_ID_STATUS_REPLY:
3934
0
                    ret_val_str = val_to_str_const(ret_val,
3935
0
                            dvbci_lsc_connect, "unknown/error");
3936
0
                    break;
3937
0
                default:
3938
0
                    ret_val_str = val_to_str_const(ret_val,
3939
0
                            dvbci_lsc_ret_val, "unknown/error");
3940
0
                    break;
3941
0
            }
3942
0
            if (ret_val_str) {
3943
0
                col_append_sep_str(pinfo->cinfo, COL_INFO, ": ",
3944
0
                            ret_val_str);
3945
0
                proto_item_append_text(pi, " (%s)", ret_val_str);
3946
0
            }
3947
0
            break;
3948
0
        case T_COMMS_SEND_LAST:
3949
0
        case T_COMMS_SEND_MORE:
3950
0
        case T_COMMS_RCV_LAST:
3951
0
        case T_COMMS_RCV_MORE:
3952
0
            phase_id = tvb_get_uint8(tvb, offset);
3953
0
            proto_tree_add_item(tree, hf_dvbci_phase_id,
3954
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
3955
0
            col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
3956
0
                    "Phase ID %d", phase_id);
3957
0
            offset++;
3958
0
            msg_len = tvb_reported_length_remaining(tvb, offset);
3959
0
            if (msg_len<=0)
3960
0
                break;
3961
0
            msg_tvb = tvb_new_subset_remaining(tvb, offset);
3962
0
            if (!msg_tvb)
3963
0
                break;
3964
0
            if (dvbci_dissect_lsc_msg && conv && conversation_get_dissector(conv, 0)) {
3965
0
                msg_handle = conversation_get_dissector(conv, 0);
3966
0
                col_append_str(pinfo->cinfo, COL_INFO, ", ");
3967
0
                col_set_fence(pinfo->cinfo, COL_INFO);
3968
0
                col_append_str(pinfo->cinfo, COL_PROTOCOL, ", ");
3969
0
                col_set_fence(pinfo->cinfo, COL_PROTOCOL);
3970
0
            }
3971
0
            else {
3972
0
                msg_handle = data_handle;
3973
0
            }
3974
0
            if (msg_handle)
3975
0
                call_dissector(msg_handle, msg_tvb, pinfo, tree);
3976
0
            break;
3977
0
        case T_COMMS_IP_CONFIG_REPLY:
3978
0
            proto_tree_add_item_ret_uint(tree, hf_dvbci_lsc_conn_state,
3979
0
                    tvb, offset, 1, ENC_BIG_ENDIAN, &conn_state);
3980
0
            offset++;
3981
0
            proto_tree_add_item(tree, hf_dvbci_lsc_phys_addr,
3982
0
                    tvb, offset, FT_ETHER_LEN, ENC_NA);
3983
0
            offset += FT_ETHER_LEN;
3984
0
            if (conn_state == LSC_CONNECTED) {
3985
0
                proto_tree_add_item(tree, hf_dvbci_lsc_ipv6_addr,
3986
0
                        tvb, offset, FT_IPv6_LEN, ENC_NA);
3987
0
                offset += FT_IPv6_LEN;
3988
0
                proto_tree_add_item(tree, hf_dvbci_lsc_netmask,
3989
0
                        tvb, offset, FT_IPv6_LEN, ENC_NA);
3990
0
                offset += FT_IPv6_LEN;
3991
0
                proto_tree_add_item(tree, hf_dvbci_lsc_gateway,
3992
0
                        tvb, offset, FT_IPv6_LEN, ENC_NA);
3993
0
                offset += FT_IPv6_LEN;
3994
0
                proto_tree_add_item(tree, hf_dvbci_lsc_dhcp_srv,
3995
0
                        tvb, offset, FT_IPv6_LEN, ENC_NA);
3996
0
                offset += FT_IPv6_LEN;
3997
0
                proto_tree_add_item_ret_uint(tree, hf_dvbci_lsc_num_dns_srv,
3998
0
                        tvb, offset, 1, ENC_BIG_ENDIAN, &num_dns_srv);
3999
0
                offset++;
4000
0
                for(i = 0; i < num_dns_srv; i++) {
4001
0
                    proto_tree_add_item(tree, hf_dvbci_lsc_dns_srv,
4002
0
                            tvb, offset, FT_IPv6_LEN, ENC_NA);
4003
0
                    offset += FT_IPv6_LEN;
4004
0
                }
4005
0
            }
4006
0
            break;
4007
0
        default:
4008
0
            break;
4009
0
    }
4010
0
}
4011
4012
4013
static void
4014
dissect_dvbci_payload_opp(uint32_t tag, int len_field _U_,
4015
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
4016
        packet_info *pinfo, proto_tree *tree)
4017
0
{
4018
0
    uint16_t        nit_loop_len, nit_loop_offset;
4019
0
    tvbuff_t       *nit_loop_tvb, *nit_loop_partial_tvb;
4020
0
    unsigned        dvb_nit_bytes;
4021
0
    uint8_t         table_id;
4022
0
    uint8_t         cap_loop_len;
4023
0
    bool            info_valid;
4024
0
    unsigned        enc_len;
4025
0
    dvb_encoding_e  encoding;
4026
0
    uint8_t         desc_num;
4027
0
    uint8_t         sig_strength, sig_qual;
4028
0
    proto_item     *pi;
4029
4030
0
    switch(tag) {
4031
0
        case T_OPERATOR_STATUS:
4032
0
        case T_OPERATOR_SEARCH_STATUS:
4033
0
            dissect_opp_status_body(tvb, offset, pinfo, tree);
4034
0
          break;
4035
0
        case T_OPERATOR_NIT:
4036
0
          nit_loop_len = tvb_get_ntohs(tvb, offset);
4037
0
          proto_tree_add_item(tree, hf_dvbci_nit_loop_len,
4038
0
                  tvb, offset, 2, ENC_BIG_ENDIAN);
4039
0
          if (nit_loop_len==0)
4040
0
              break;
4041
0
          offset += 2;
4042
0
          nit_loop_tvb = tvb_new_subset_length(
4043
0
                  tvb, offset, nit_loop_len);
4044
0
          nit_loop_offset = 0;
4045
0
          if (!dvb_nit_handle) {
4046
0
              call_dissector(data_handle, nit_loop_tvb, pinfo, tree);
4047
0
              break;
4048
0
          }
4049
          /* prevent dvb_nit dissector from clearing the dvb-ci infos */
4050
0
          col_append_str(pinfo->cinfo, COL_INFO, ", ");
4051
0
          col_set_fence(pinfo->cinfo, COL_INFO);
4052
0
          do {
4053
0
              table_id = tvb_get_uint8(nit_loop_tvb, nit_loop_offset);
4054
0
              if (table_id != TABLE_ID_CICAM_NIT) {
4055
0
                  proto_tree_add_expert(tree, pinfo, &ei_dvbci_cicam_nit_table_id,
4056
0
                          nit_loop_tvb, nit_loop_offset, 1);
4057
0
              }
4058
0
              nit_loop_partial_tvb =
4059
0
                  tvb_new_subset_remaining(nit_loop_tvb, nit_loop_offset);
4060
0
              dvb_nit_bytes = call_dissector(
4061
0
                      dvb_nit_handle, nit_loop_partial_tvb, pinfo, tree);
4062
0
              nit_loop_offset += dvb_nit_bytes;
4063
              /* offsets go from 0 to nit_loop_len-1 */
4064
0
          } while (dvb_nit_bytes>0 && nit_loop_offset<nit_loop_len-1);
4065
0
          break;
4066
0
        case T_OPERATOR_INFO:
4067
0
          info_valid = ((tvb_get_uint8(tvb, offset) & 0x08) == 0x08);
4068
0
          proto_tree_add_item(tree, hf_dvbci_info_valid,
4069
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4070
0
          proto_tree_add_item(tree, hf_dvbci_info_ver_op_info,
4071
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4072
0
          if (!info_valid)
4073
0
              break;
4074
0
          offset++;
4075
0
          proto_tree_add_item(tree, hf_dvbci_cicam_onid,
4076
0
                  tvb, offset, 2, ENC_BIG_ENDIAN);
4077
0
          offset += 2;
4078
0
          proto_tree_add_item(tree, hf_dvbci_cicam_id,
4079
0
                  tvb, offset, 4, ENC_BIG_ENDIAN);
4080
0
          offset += 4;
4081
4082
0
          enc_len = dvb_analyze_string_charset(tvb, offset,
4083
0
                  tvb_reported_length_remaining(tvb, offset), &encoding);
4084
0
          if (enc_len==0) {
4085
0
              proto_tree_add_expert(tree, pinfo,
4086
0
                      &ei_dvbci_invalid_char_tbl, tvb, offset,
4087
0
                      tvb_reported_length_remaining(tvb, offset));
4088
0
              break;
4089
0
          }
4090
0
          dvb_add_chartbl(tree, hf_dvbci_opp_char_tbl,
4091
0
                  tvb, offset, enc_len, encoding);
4092
0
          offset += enc_len;
4093
4094
0
          proto_tree_add_item(tree, hf_dvbci_sdt_rst_trusted,
4095
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4096
0
          proto_tree_add_item(tree, hf_dvbci_eit_rst_trusted,
4097
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4098
0
          proto_tree_add_item(tree, hf_dvbci_eit_pf_usage,
4099
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4100
0
          proto_tree_add_item(tree, hf_dvbci_eit_sch_usage,
4101
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4102
0
          proto_tree_add_item(tree, hf_dvbci_ext_evt_usage,
4103
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4104
0
          offset++;
4105
0
          proto_tree_add_item(tree, hf_dvbci_sdt_oth_trusted,
4106
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4107
0
          proto_tree_add_item(tree, hf_dvbci_eit_evt_trigger,
4108
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4109
0
          offset++;
4110
0
          proto_tree_add_item(tree, hf_dvbci_opp_lang_code,
4111
0
                  tvb, offset, 3, ENC_ASCII);
4112
0
          offset += 3;
4113
          /* hf_dvbci_prof_name is an FT_UINT_STRING, one leading len byte */
4114
0
          proto_tree_add_item(tree, hf_dvbci_prof_name,
4115
0
              tvb, offset, 1, ENC_ASCII|ENC_BIG_ENDIAN);
4116
0
          break;
4117
0
        case T_OPERATOR_SEARCH_START:
4118
0
          proto_tree_add_item(tree, hf_dvbci_unattended,
4119
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4120
4121
0
          cap_loop_len = tvb_get_uint8(tvb, offset) & 0x7F;
4122
0
          proto_tree_add_item(tree, hf_dvbci_opp_svc_type_loop_len,
4123
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4124
0
          offset++;
4125
          /* no need for error checking, we continue anyway */
4126
0
          dissect_opp_cap_loop(cap_loop_len, "Service type loop",
4127
0
                  hf_dvbci_opp_svc_type, 1, tvb, offset, pinfo, tree);
4128
0
          offset += cap_loop_len;
4129
4130
0
          cap_loop_len = tvb_get_uint8(tvb, offset);
4131
0
          proto_tree_add_item(tree, hf_dvbci_dlv_cap_loop_len,
4132
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4133
0
          offset++;
4134
          /* XXX - handle multi-byte delivery capabilities */
4135
0
          dissect_opp_cap_loop(cap_loop_len,
4136
0
                  "Delivery system capabilities loop",
4137
0
                  hf_dvbci_dlv_cap_byte, 1,
4138
0
                  tvb, offset, pinfo, tree);
4139
0
          offset += cap_loop_len;
4140
4141
0
          cap_loop_len = tvb_get_uint8(tvb, offset);
4142
0
          proto_tree_add_item(tree, hf_dvbci_app_cap_loop_len,
4143
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4144
0
          offset++;
4145
0
          dissect_opp_cap_loop(cap_loop_len,
4146
0
                  "Application capabilities loop",
4147
0
                  hf_dvbci_app_cap_bytes, 2,
4148
0
                  tvb, offset, pinfo, tree);
4149
0
          break;
4150
0
        case T_OPERATOR_TUNE_STATUS:
4151
0
          desc_num = tvb_get_uint8(tvb, offset);
4152
0
          pi = proto_tree_add_item(tree, hf_dvbci_desc_num,
4153
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4154
0
          if (desc_num==OPP_NO_MORE_DESC)
4155
0
              proto_item_append_text(pi, " (all descriptors were processed)");
4156
0
          offset++;
4157
0
          sig_strength = tvb_get_uint8(tvb, offset);
4158
0
          proto_tree_add_item(tree, hf_dvbci_sig_strength,
4159
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4160
0
          offset++;
4161
0
          sig_qual = tvb_get_uint8(tvb, offset);
4162
0
          pi = proto_tree_add_item(tree, hf_dvbci_sig_qual,
4163
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4164
0
          if (sig_strength>100 || sig_qual>100) {
4165
0
              expert_add_info(pinfo, pi, &ei_dvbci_sig_qual);
4166
0
          }
4167
0
          offset++;
4168
0
          proto_tree_add_item(tree, hf_dvbci_opp_tune_status,
4169
0
                  tvb, offset, 1, ENC_BIG_ENDIAN);
4170
0
          dissect_desc_loop(hf_dvbci_opp_desc_loop_len,
4171
0
                  tvb, offset, pinfo, tree);
4172
0
          break;
4173
0
        case T_OPERATOR_TUNE:
4174
0
          dissect_desc_loop(hf_dvbci_opp_desc_loop_len,
4175
0
                  tvb, offset, pinfo, tree);
4176
0
          break;
4177
0
        default:
4178
0
          break;
4179
0
    }
4180
0
}
4181
4182
4183
static void
4184
dissect_dvbci_payload_afs(uint32_t tag, int len_field _U_,
4185
        tvbuff_t *tvb, unsigned offset, conversation_t *conv _U_,
4186
        packet_info *pinfo, proto_tree *tree)
4187
0
{
4188
0
    const uint8_t *dom_id_str;
4189
4190
0
    switch(tag) {
4191
0
        case T_AFS_FILE_SYSTEM_OFFER:
4192
0
            proto_tree_add_item_ret_string(tree, hf_dvbci_afs_dom_id,
4193
0
                    tvb, offset, 1, ENC_UTF_8|ENC_BIG_ENDIAN,
4194
0
                    pinfo->pool, &dom_id_str);
4195
0
            if (dom_id_str) {
4196
0
                col_append_sep_fstr(pinfo->cinfo,
4197
0
                        COL_INFO, ": ", "%s", dom_id_str);
4198
0
            }
4199
0
            break;
4200
0
        case T_AFS_FILE_SYSTEM_ACK:
4201
0
            proto_tree_add_item(tree, hf_dvbci_afs_ack_code,
4202
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
4203
0
            break;
4204
0
        case T_AFS_FILE_REQUEST:
4205
0
            dissect_dvbci_ami_file_req(tvb, offset, pinfo, tree);
4206
0
            break;
4207
0
        case T_AFS_FILE_ACKNOWLEDGE:
4208
0
            dissect_dvbci_ami_file_ack(tvb, offset, pinfo, tree);
4209
0
            break;
4210
0
        default:
4211
0
            break;
4212
0
    }
4213
0
}
4214
4215
4216
static void
4217
dissect_dvbci_payload_sas(uint32_t tag, int len_field _U_,
4218
        tvbuff_t *tvb, unsigned offset, conversation_t *conv,
4219
        packet_info *pinfo, proto_tree *tree)
4220
0
{
4221
0
    char    app_id_str[2+16+1]; /* "0x", string of 16 hex digits, trailing 0 */
4222
0
    uint8_t sas_status;
4223
0
    dissector_handle_t msg_handle;
4224
0
    uint8_t msg_nb;
4225
0
    uint16_t msg_len;
4226
0
    tvbuff_t *msg_tvb;
4227
4228
0
    switch(tag) {
4229
0
        case T_SAS_CONNECT_RQST:
4230
0
        case T_SAS_CONNECT_CNF:
4231
0
            snprintf(app_id_str, sizeof(app_id_str),
4232
0
                    "0x%016" PRIx64, tvb_get_ntoh64(tvb, offset));
4233
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, ": ", app_id_str);
4234
0
            proto_tree_add_item(tree, hf_dvbci_sas_app_id,
4235
0
                    tvb, offset, 8, ENC_BIG_ENDIAN);
4236
0
            offset += 8;
4237
0
            if (tag == T_SAS_CONNECT_CNF) {
4238
0
                sas_status = tvb_get_uint8(tvb, offset);
4239
0
                col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
4240
0
                        (sas_status == SAS_SESS_STATE_CONNECTED ?
4241
0
                         "Ok" : "Error"));
4242
0
                proto_tree_add_item(tree, hf_dvbci_sas_sess_state,
4243
0
                        tvb, offset, 1, ENC_BIG_ENDIAN);
4244
0
                if (!conv)
4245
0
                    break;
4246
0
                if (sas_status == SAS_SESS_STATE_CONNECTED) {
4247
0
                    msg_handle = dissector_get_string_handle(
4248
0
                            sas_msg_dissector_table, app_id_str);
4249
                    /* this clears the dissector for msg_handle==NULL */
4250
0
                    conversation_set_dissector(conv, msg_handle);
4251
0
                }
4252
0
                else
4253
0
                    conversation_set_dissector(conv, NULL);
4254
0
            }
4255
0
            break;
4256
0
        case T_SAS_ASYNC_MSG:
4257
0
            msg_nb = tvb_get_uint8(tvb, offset);
4258
0
            col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
4259
0
                    "Message #%d ", msg_nb);
4260
0
            proto_tree_add_item(tree, hf_dvbci_sas_msg_nb,
4261
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
4262
0
            offset++;
4263
0
            msg_len = tvb_get_ntohs(tvb, offset);
4264
0
            proto_tree_add_item(tree, hf_dvbci_sas_msg_len,
4265
0
                    tvb, offset, 2, ENC_BIG_ENDIAN);
4266
0
            offset += 2;
4267
0
            msg_tvb = tvb_new_subset_length(tvb, offset, msg_len);
4268
0
            msg_handle = conv ? conversation_get_dissector(conv, 0) : NULL;
4269
0
            if (msg_handle == NULL)
4270
0
                msg_handle = data_handle;
4271
0
            call_dissector(msg_handle, msg_tvb, pinfo, tree);
4272
0
            break;
4273
0
        default:
4274
0
          break;
4275
0
    }
4276
0
}
4277
4278
4279
static void
4280
dissect_dvbci_apdu(tvbuff_t *tvb, conversation_t *conv,
4281
        packet_info *pinfo, proto_tree *tree, uint8_t direction)
4282
0
{
4283
0
    proto_tree  *app_tree;
4284
0
    uint32_t     apdu_len, tag, len_field;
4285
0
    const char *tag_str;
4286
0
    int          offset;
4287
0
    proto_item  *pi;
4288
0
    apdu_info_t *ai;
4289
0
    uint32_t     apdu_res_id;
4290
0
    const char *ai_res_class_str;
4291
4292
4293
0
    apdu_len = tvb_reported_length(tvb);
4294
4295
0
    app_tree = proto_tree_add_subtree(tree, tvb, 0, apdu_len, ett_dvbci_application, NULL, "Application Layer");
4296
4297
0
    tag = tvb_get_ntoh24(tvb, 0);
4298
0
    tag_str = try_val_to_str(tag, dvbci_apdu_tag);
4299
0
    offset = APDU_TAG_SIZE;
4300
4301
0
    col_set_str(pinfo->cinfo, COL_INFO,
4302
0
            val_to_str_const(tag, dvbci_apdu_tag, "Unknown/invalid APDU"));
4303
0
    pi = proto_tree_add_item(
4304
0
                app_tree, hf_dvbci_apdu_tag, tvb, 0, APDU_TAG_SIZE, ENC_BIG_ENDIAN);
4305
0
    if (tag_str == NULL) {
4306
0
        expert_add_info(pinfo, pi, &ei_dvbci_apdu_tag);
4307
0
        return;
4308
0
    }
4309
4310
0
    offset = dissect_ber_length(pinfo, app_tree, tvb, offset, &len_field, NULL);
4311
0
    if ((offset+len_field) != apdu_len) {
4312
0
        proto_tree_add_expert_format(app_tree, pinfo, &ei_dvbci_bad_length, tvb,
4313
0
                APDU_TAG_SIZE, offset-APDU_TAG_SIZE,
4314
0
                "Length field is different from the number of apdu payload bytes");
4315
        /* we need len_field bytes of apdu payload to call
4316
           ai->dissect_payload() and continue dissecting */
4317
0
        if (apdu_len < offset+len_field)
4318
0
            return;
4319
0
    }
4320
4321
0
    ai = (apdu_info_t *)g_hash_table_lookup(apdu_table,
4322
0
                                            GUINT_TO_POINTER((unsigned)tag));
4323
0
    if (!ai) {
4324
0
        proto_tree_add_expert(app_tree, pinfo, &ei_dvbci_apdu_not_supported, tvb, 0, APDU_TAG_SIZE);
4325
0
        return;
4326
0
    }
4327
0
    if (ai->direction!=DIRECTION_ANY && ai->direction!=direction) {
4328
0
        if (ai->direction==DATA_HOST_TO_CAM) {
4329
0
            proto_tree_add_expert(app_tree, pinfo, &ei_dvbci_apu_host_to_cam, tvb, 0, APDU_TAG_SIZE);
4330
0
        }
4331
0
        else {
4332
0
            proto_tree_add_expert(app_tree, pinfo, &ei_dvbci_apu_cam_to_host, tvb, 0, APDU_TAG_SIZE);
4333
0
        }
4334
        /* don't return, we can continue dissecting the APDU */
4335
0
    }
4336
0
    if (ai->min_len_field!=LEN_FIELD_ANY && len_field<ai->min_len_field) {
4337
0
        proto_tree_add_expert_format(app_tree, pinfo, &ei_dvbci_bad_length, tvb, 0, APDU_TAG_SIZE,
4338
0
                "Invalid APDU length field, minimum length field for %s is %d", tag_str, ai->min_len_field);
4339
0
        return;
4340
0
    }
4341
0
    if (ai->len_field!=LEN_FIELD_ANY && len_field!=ai->len_field) {
4342
0
        proto_tree_add_expert_format(app_tree, pinfo, &ei_dvbci_bad_length, tvb, 0, APDU_TAG_SIZE,
4343
0
                "Invalid APDU length field, length field for %s must be %d", tag_str, ai->len_field);
4344
0
        return;
4345
0
    }
4346
0
    if (conv) {
4347
0
        apdu_res_id = GPOINTER_TO_UINT(conversation_get_proto_data(conv, proto_dvbci));
4348
4349
0
        ai_res_class_str = val_to_str_const(ai->res_class, dvbci_res_class, "Unknown");
4350
4351
0
        if(RES_CLASS(apdu_res_id) != ai->res_class) {
4352
0
            proto_tree_add_expert_format(app_tree, pinfo, &ei_dvbci_res_class, tvb, 0, APDU_TAG_SIZE,
4353
0
                    "Invalid resource class for this apdu, %s can only be sent on a %s session",
4354
0
                    tag_str, ai_res_class_str);
4355
0
        }
4356
0
        if(RES_VER(apdu_res_id) < ai->res_min_ver) {
4357
0
            proto_tree_add_expert_format(app_tree, pinfo, &ei_dvbci_res_ver, tvb, 0, APDU_TAG_SIZE,
4358
0
                    "Invalid resource version for this apdu, %s apdu requires at least %s version %d",
4359
0
                    tag_str, ai_res_class_str, ai->res_min_ver);
4360
0
        }
4361
        /* don't return, we can continue dissecting the APDU */
4362
0
    }
4363
0
    if (ai->len_field!=0) {
4364
0
        if (!ai->dissect_payload) {
4365
            /* don't display an error, getting here means we have illegal
4366
             * data in apdu_info[] */
4367
0
            return;
4368
0
        }
4369
0
        ai->dissect_payload(
4370
0
                tag, len_field, tvb, offset, conv, pinfo, app_tree);
4371
0
    }
4372
0
}
4373
4374
static void
4375
dissect_dvbci_spdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4376
        uint8_t direction, uint8_t tcid)
4377
0
{
4378
0
    uint32_t           spdu_len;
4379
0
    proto_item        *ti;
4380
0
    proto_tree        *sess_tree;
4381
0
    uint8_t            tag;
4382
0
    const char        *tag_str;
4383
0
    conversation_t    *conv     = NULL;
4384
0
    proto_item        *pi;
4385
0
    int                offset;
4386
0
    uint32_t           len_field;
4387
0
    const spdu_info_t *si;
4388
0
    proto_item        *res_id_it   = NULL;
4389
0
    uint32_t           res_id;
4390
0
    uint16_t ssnb                   = 0;  /* session numbers start with 1, 0 is invalid */
4391
0
    uint8_t            sess_stat;
4392
0
    tvbuff_t          *payload_tvb = NULL;
4393
4394
4395
0
    spdu_len = tvb_reported_length(tvb);
4396
4397
0
    sess_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_dvbci_session, &ti, "Session Layer");
4398
4399
0
    tag = tvb_get_uint8(tvb,0);
4400
0
    tag_str = try_val_to_str(tag, dvbci_spdu_tag);
4401
0
    col_set_str(pinfo->cinfo, COL_INFO,
4402
0
            val_to_str_const(tag, dvbci_spdu_tag, "Invalid SPDU"));
4403
0
    pi = proto_tree_add_item(sess_tree, hf_dvbci_spdu_tag, tvb, 0, 1, ENC_BIG_ENDIAN);
4404
0
    if (tag_str == NULL) {
4405
0
        expert_add_info(pinfo, pi, &ei_dvbci_spdu_tag);
4406
0
        return;
4407
0
    }
4408
4409
0
    offset = dissect_ber_length(pinfo, sess_tree, tvb, 1, &len_field, NULL);
4410
4411
0
    si = (spdu_info_t *)g_hash_table_lookup(spdu_table,
4412
0
                                            GUINT_TO_POINTER((unsigned)tag));
4413
0
    if (!si)
4414
0
        return;
4415
0
    if (si->direction!=0 && si->direction!=direction) {
4416
0
        if (si->direction==DATA_HOST_TO_CAM) {
4417
0
            proto_tree_add_expert(sess_tree, pinfo, &ei_dvbci_spdu_host_to_cam, tvb, 0, 1);
4418
0
        }
4419
0
        else {
4420
0
            proto_tree_add_expert(sess_tree, pinfo, &ei_dvbci_spdu_cam_to_host, tvb, 0, 1);
4421
0
        }
4422
0
    }
4423
0
    if (si->len_field != len_field) {
4424
        /* offset points to 1st byte after the length field */
4425
0
        proto_tree_add_expert_format(sess_tree, pinfo, &ei_dvbci_bad_length, tvb, 1, offset-1,
4426
0
                "Invalid SPDU length field, correct length field for %s is %d", tag_str, si->len_field);
4427
0
        return;
4428
0
    }
4429
4430
0
    switch(tag)
4431
0
    {
4432
0
        case T_OPEN_SESSION_REQUEST:
4433
0
            res_id_it = dissect_res_id(tvb, offset, pinfo, sess_tree, 0, true);
4434
0
            break;
4435
0
        case T_CREATE_SESSION:
4436
0
            res_id_it = dissect_res_id(tvb, offset, pinfo, sess_tree, 0, true);
4437
            /* DVB-CI uses network byte order == big endian */
4438
0
            ssnb = tvb_get_ntohs(tvb, offset+RES_ID_LEN);
4439
0
            proto_tree_add_item(sess_tree, hf_dvbci_sess_nb,
4440
0
                    tvb, offset+RES_ID_LEN, 2, ENC_BIG_ENDIAN);
4441
0
            break;
4442
0
        case T_OPEN_SESSION_RESPONSE:
4443
0
        case T_CREATE_SESSION_RESPONSE:
4444
0
            sess_stat = tvb_get_uint8(tvb, offset);
4445
0
            proto_tree_add_item(sess_tree, hf_dvbci_sess_status,
4446
0
                    tvb, offset, 1, ENC_BIG_ENDIAN);
4447
0
            res_id = tvb_get_ntohl(tvb, offset+1);
4448
0
            res_id_it = dissect_res_id(tvb, offset+1, pinfo, sess_tree, 0, true);
4449
0
            ssnb = tvb_get_ntohs(tvb, offset+1+RES_ID_LEN);
4450
0
            proto_tree_add_item(sess_tree, hf_dvbci_sess_nb, tvb,
4451
0
                    offset+1+RES_ID_LEN, 2, ENC_BIG_ENDIAN);
4452
0
            if (sess_stat != SESS_OPENED) {
4453
0
                col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Error");
4454
0
                break;
4455
0
            }
4456
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Session opened");
4457
            /* create the circuit only once, later passes find it below */
4458
0
            if (!PINFO_FD_VISITED(pinfo)) {
4459
0
                conv = conversation_new_by_id(pinfo->num, CONVERSATION_DVBCI, CT_ID(ssnb, tcid));
4460
                /* we always add the resource id immediately after the circuit
4461
                    was created */
4462
0
                conversation_add_proto_data(conv, proto_dvbci, GUINT_TO_POINTER(res_id));
4463
0
            }
4464
0
            break;
4465
0
        case T_CLOSE_SESSION_REQUEST:
4466
0
            ssnb = tvb_get_ntohs(tvb, offset);
4467
0
            proto_tree_add_item(
4468
0
                    sess_tree, hf_dvbci_sess_nb, tvb,
4469
0
                    offset, 2, ENC_BIG_ENDIAN);
4470
0
            break;
4471
0
        case T_CLOSE_SESSION_RESPONSE:
4472
0
            sess_stat = tvb_get_uint8(tvb, offset);
4473
0
            proto_tree_add_item(
4474
0
                    sess_tree, hf_dvbci_close_sess_status, tvb,
4475
0
                    offset, 1, ENC_BIG_ENDIAN);
4476
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
4477
0
                    sess_stat==SESS_CLOSED ? "Session closed" : "Error");
4478
0
            ssnb = tvb_get_ntohs(tvb, offset+1);
4479
0
            proto_tree_add_item(sess_tree, hf_dvbci_sess_nb,
4480
0
                    tvb, offset+1, 2, ENC_BIG_ENDIAN);
4481
0
            conv = find_conversation_by_id(pinfo->num, CONVERSATION_DVBCI, CT_ID(ssnb, tcid));
4482
0
            if (conv)
4483
0
                conv->last_frame = pinfo->num;
4484
0
            break;
4485
0
        case T_SESSION_NUMBER:
4486
0
            ssnb = tvb_get_ntohs(tvb, offset);
4487
0
            proto_tree_add_item(
4488
0
                    sess_tree, hf_dvbci_sess_nb, tvb,
4489
0
                    offset, 2, ENC_BIG_ENDIAN);
4490
0
            payload_tvb =
4491
0
                tvb_new_subset_remaining(tvb, offset+2);
4492
0
            break;
4493
0
        default:
4494
0
            break;
4495
0
    }
4496
4497
0
    if (ssnb && !conv)
4498
0
        conv = find_conversation_by_id(pinfo->num, CONVERSATION_DVBCI, CT_ID(ssnb, tcid));
4499
4500
    /* if the packet contains no resource id, we add the cached id from
4501
       the circuit so that each packet has a resource id that can be
4502
       used for filtering */
4503
0
    if (conv&& !res_id_it) {
4504
        /* when a circuit is found, it always contains a valid resource id */
4505
0
        res_id = GPOINTER_TO_UINT(conversation_get_proto_data(conv, proto_dvbci));
4506
0
        res_id_it = dissect_res_id(NULL, 0, pinfo, sess_tree, res_id, true);
4507
0
        proto_item_set_generated(res_id_it);
4508
0
    }
4509
4510
0
    if (payload_tvb) {
4511
0
        proto_item_set_len(ti, spdu_len-tvb_reported_length(payload_tvb));
4512
0
        dissect_dvbci_apdu(payload_tvb, conv, pinfo, tree, direction);
4513
0
    }
4514
0
    else {
4515
0
        proto_item_set_len(ti, spdu_len);
4516
0
    }
4517
0
}
4518
4519
/* dissect the status of an r_tpdu, return its length or -1 for error */
4520
static int
4521
dissect_dvbci_tpdu_status(tvbuff_t *tvb, unsigned offset,
4522
        packet_info *pinfo, proto_tree *tree,
4523
        uint8_t lpdu_tcid, uint8_t r_tpdu_tag)
4524
0
{
4525
0
    int          offset_new, len_start_offset;
4526
0
    uint8_t      tag;
4527
0
    uint32_t     len_field;
4528
0
    uint8_t      t_c_id, sb_value;
4529
0
    const char *sb_str;
4530
0
    proto_item  *pi;
4531
4532
0
    offset_new = offset;
4533
4534
0
    tag = tvb_get_uint8(tvb, offset_new);
4535
0
    if (tag!=T_SB) {
4536
0
        proto_tree_add_expert(tree, pinfo, &ei_dvbci_tpdu_status_tag, tvb, offset_new, 1);
4537
0
        return -1;
4538
0
    }
4539
0
    proto_tree_add_item(tree, hf_dvbci_sb_tag, tvb,
4540
0
            offset_new, 1, ENC_BIG_ENDIAN);
4541
0
    col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "T_SB");
4542
0
    offset_new++;
4543
4544
0
    len_start_offset = offset_new;
4545
0
    offset_new = dissect_ber_length(
4546
0
            pinfo, tree, tvb, offset_new, &len_field, NULL);
4547
0
    if (len_field != 2) {
4548
0
        proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb, len_start_offset, offset_new-len_start_offset,
4549
0
                "Invalid status length field, this must always be 2");
4550
4551
0
        return -1;
4552
0
    }
4553
4554
0
    pi = proto_tree_add_item_ret_uint8(tree, hf_dvbci_t_c_id, tvb, offset_new, 1, ENC_BIG_ENDIAN, &t_c_id);
4555
    /* tcid in transport header and link layer must only match for data
4556
     * transmission commands */
4557
0
    if (t_c_id!=lpdu_tcid) {
4558
0
        if (r_tpdu_tag==NO_TAG ||
4559
0
                r_tpdu_tag==T_DATA_MORE || r_tpdu_tag==T_DATA_LAST) {
4560
0
            expert_add_info_format(pinfo, pi, &ei_dvbci_t_c_id,
4561
0
                    "Transport Connection ID mismatch, tcid is %d in the transport layer and %d in the link layer",
4562
0
                    t_c_id, lpdu_tcid);
4563
0
            return -1;
4564
0
        }
4565
0
    }
4566
0
    offset_new++;
4567
4568
0
    sb_value = tvb_get_uint8(tvb, offset_new);
4569
0
    sb_str = try_val_to_str(sb_value, dvbci_sb_value);
4570
0
    pi = proto_tree_add_item(tree, hf_dvbci_sb_value, tvb,
4571
0
            offset_new, 1, ENC_BIG_ENDIAN);
4572
0
    if (sb_str) {
4573
0
        col_append_sep_str(pinfo->cinfo, COL_INFO, ": ", sb_str);
4574
0
    }
4575
0
    else {
4576
0
        expert_add_info(pinfo, pi, &ei_dvbci_sb_value);
4577
0
    }
4578
0
    offset_new++;
4579
4580
0
    return offset_new-offset;
4581
0
}
4582
4583
4584
/* dissect the header of a c_tpdu or r_tpdu
4585
   return the length of the header (tag, len_field, t_c_id) or -1 for error */
4586
static int
4587
dissect_dvbci_tpdu_hdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4588
        uint8_t direction, uint8_t lpdu_tcid, uint32_t tpdu_len,
4589
        uint8_t *hdr_tag, uint32_t *body_len)
4590
0
{
4591
0
    uint8_t      c_tpdu_tag, r_tpdu_tag, *tag = NULL;
4592
0
    const char *c_tpdu_str, *r_tpdu_str;
4593
0
    proto_item  *pi;
4594
0
    int          offset;
4595
0
    uint32_t     len_field;
4596
0
    uint8_t      t_c_id;
4597
4598
0
    if (direction==DATA_HOST_TO_CAM) {
4599
0
        c_tpdu_tag = tvb_get_uint8(tvb, 0);
4600
0
        tag = &c_tpdu_tag;
4601
0
        c_tpdu_str = try_val_to_str(c_tpdu_tag, dvbci_c_tpdu);
4602
0
        pi = proto_tree_add_item(tree, hf_dvbci_c_tpdu_tag, tvb, 0, 1, ENC_BIG_ENDIAN);
4603
0
        if (c_tpdu_str) {
4604
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, c_tpdu_str);
4605
0
        }
4606
0
        else {
4607
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
4608
0
                    "Invalid Command-TPDU tag");
4609
0
            expert_add_info(pinfo, pi, &ei_dvbci_c_tpdu_tag);
4610
0
            return -1;
4611
0
        }
4612
0
    }
4613
0
    else {
4614
0
        r_tpdu_tag = tvb_get_uint8(tvb, 0);
4615
0
        if (r_tpdu_tag == T_SB) {
4616
            /* we have an r_tpdu without header and body,
4617
               it contains only the status part */
4618
0
            if (hdr_tag)
4619
0
                *hdr_tag = NO_TAG;
4620
0
            if (body_len)
4621
0
                *body_len = 0;
4622
0
            return 0;
4623
0
        }
4624
4625
0
        tag = &r_tpdu_tag;
4626
0
        r_tpdu_str = try_val_to_str(r_tpdu_tag, dvbci_r_tpdu);
4627
0
        pi = proto_tree_add_item(tree, hf_dvbci_r_tpdu_tag, tvb, 0, 1, ENC_BIG_ENDIAN);
4628
0
        if (r_tpdu_str) {
4629
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, r_tpdu_str);
4630
0
        }
4631
0
        else {
4632
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
4633
0
                    "Invalid Response-TPDU tag");
4634
0
            expert_add_info(pinfo, pi, &ei_dvbci_r_tpdu_tag);
4635
0
            return -1;
4636
0
        }
4637
0
    }
4638
4639
0
    offset = dissect_ber_length(pinfo, tree, tvb, 1, &len_field, NULL);
4640
    /* len_field must be at least 1 for the following t_c_id
4641
       c_tpdu's len_field must match tvbuff exactly
4642
       r_tpdu's len_field does not include the status part after the body */
4643
0
    if (len_field==0 ||
4644
0
        ((direction==DATA_HOST_TO_CAM) && ((offset+len_field)!=tpdu_len)) ||
4645
0
        ((direction==DATA_CAM_TO_HOST) && ((offset+len_field)>tpdu_len))) {
4646
        /* offset points to 1st byte after the length field */
4647
0
        proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb, 1, offset-1,
4648
0
            len_field==0 ? "Invalid length field, length field must be at least 1" :
4649
0
                           "Invalid length field, length field mismatch");
4650
0
        return -1;
4651
0
    }
4652
4653
0
    pi = proto_tree_add_item_ret_uint8(tree, hf_dvbci_t_c_id, tvb, offset, 1, ENC_BIG_ENDIAN, &t_c_id);
4654
    /* tcid in transport header and link layer must only match for
4655
     * data transmission commands */
4656
0
    if (t_c_id!=lpdu_tcid) {
4657
0
        if (tag && (*tag==T_RCV || *tag==T_DATA_MORE || *tag==T_DATA_LAST)) {
4658
0
            expert_add_info_format(pinfo, pi, &ei_dvbci_t_c_id, "Transport Connection ID mismatch, tcid is %d in the transport layer and %d in the link layer",
4659
0
                    t_c_id, lpdu_tcid);
4660
0
        }
4661
0
    }
4662
0
    else {
4663
0
        col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "tcid %d", t_c_id);
4664
0
    }
4665
0
    offset++;
4666
4667
0
    if (hdr_tag && tag)
4668
0
        *hdr_tag = *tag;
4669
0
    if (body_len)
4670
0
        *body_len = len_field-1;  /* -1 for t_c_id */
4671
0
    return offset;
4672
0
}
4673
4674
static void
4675
dissect_dvbci_tpdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4676
        uint8_t direction, uint8_t lpdu_tcid)
4677
0
{
4678
0
    uint32_t       tpdu_len, body_len;
4679
0
    proto_item    *ti;
4680
0
    proto_tree    *trans_tree;
4681
0
    int            offset, status_len;
4682
0
    uint8_t        hdr_tag                = NO_TAG;
4683
0
    tvbuff_t      *body_tvb, *payload_tvb = NULL;
4684
0
    fragment_head *frag_msg               = NULL;
4685
4686
4687
0
    tpdu_len = tvb_reported_length(tvb);
4688
4689
0
    col_clear(pinfo->cinfo, COL_INFO);
4690
4691
0
    trans_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_dvbci_transport, &ti, "Transport Layer");
4692
4693
0
    offset = dissect_dvbci_tpdu_hdr(tvb, pinfo, trans_tree, direction,
4694
0
            lpdu_tcid, tpdu_len, &hdr_tag, &body_len);
4695
0
    if (offset==-1)
4696
0
        return;
4697
0
    proto_item_set_len(ti, offset);
4698
0
    if ((offset>0) && (body_len!=0)) {
4699
        /* for unfragmented data, the reassembly api behaviour is unclear
4700
            if we put the body part of the tvb into fragment_add_seq_next(),
4701
            process_reassembled_data() returns the remainder of the tvb
4702
            which is body|status part
4703
           if there's more than one fragment, payload_tvb contains only
4704
            the reassembled bodies as expected
4705
           to work around this issue, we use a dedicated body_tvb as
4706
            input to reassembly routines */
4707
0
        body_tvb = tvb_new_subset_length(tvb, offset, body_len);
4708
        /* dissect_dvbci_tpdu_hdr() checked that lpdu_tcid==t_c_id */
4709
0
        frag_msg = fragment_add_seq_next(&spdu_reassembly_table,
4710
0
                body_tvb, 0, pinfo, SPDU_SEQ_ID_BASE+lpdu_tcid, NULL,
4711
0
                body_len,
4712
0
                hdr_tag == T_DATA_MORE ? 1 : 0);
4713
0
        payload_tvb = process_reassembled_data(body_tvb, 0, pinfo,
4714
0
                "Reassembled SPDU", frag_msg, &spdu_frag_items,
4715
0
                NULL, trans_tree);
4716
0
        if (!payload_tvb) {
4717
0
            if (hdr_tag == T_DATA_MORE) {
4718
0
                pinfo->fragmented = true;
4719
0
                col_append_str(pinfo->cinfo, COL_INFO, " (Message fragment)");
4720
0
            } else {
4721
0
                payload_tvb = body_tvb;
4722
0
            }
4723
0
        }
4724
0
        offset += body_len;
4725
0
    }
4726
4727
0
    if (direction==DATA_CAM_TO_HOST) {
4728
        /* minimum length of an rtpdu status is 4 bytes */
4729
0
        if (tpdu_len-offset < 4) {
4730
0
            proto_tree_add_expert(trans_tree, pinfo, &ei_dvbci_r_tpdu_status_mandatory, tvb, 0, 0);
4731
0
            return;
4732
0
        }
4733
0
        status_len = dissect_dvbci_tpdu_status(
4734
0
                tvb, offset, pinfo, trans_tree, lpdu_tcid, hdr_tag);
4735
0
        if (status_len<0)
4736
0
            return;
4737
0
        proto_tree_set_appendix(trans_tree, tvb, offset, status_len);
4738
0
    }
4739
4740
0
    if (payload_tvb)
4741
0
        dissect_dvbci_spdu(payload_tvb, pinfo, tree, direction, lpdu_tcid);
4742
0
}
4743
4744
4745
static void
4746
dissect_dvbci_lpdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4747
        uint8_t direction)
4748
0
{
4749
0
    proto_tree    *link_tree;
4750
0
    uint32_t       payload_len;
4751
0
    uint8_t        tcid, more_last;
4752
0
    proto_item    *pi;
4753
0
    tvbuff_t      *payload_tvb;
4754
0
    fragment_head *frag_msg;
4755
0
    unsigned       neg_buf_size;
4756
4757
4758
0
    payload_len = tvb_reported_length(tvb);
4759
4760
0
    col_set_str(pinfo->cinfo, COL_INFO, "LPDU");
4761
4762
0
    link_tree = proto_tree_add_subtree(tree, tvb, 0, 2, ett_dvbci_link, NULL, "Link Layer");
4763
4764
0
    tcid = tvb_get_uint8(tvb, 0);
4765
0
    col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "tcid %d", tcid);
4766
0
    proto_tree_add_item(link_tree, hf_dvbci_tcid, tvb, 0, 1, ENC_BIG_ENDIAN);
4767
4768
0
    more_last = tvb_get_uint8(tvb, 1);
4769
0
    pi = proto_tree_add_item(link_tree, hf_dvbci_ml, tvb, 1, 1, ENC_BIG_ENDIAN);
4770
0
    if (try_val_to_str(more_last, dvbci_ml) == NULL) {
4771
0
        expert_add_info(pinfo, pi, &ei_dvbci_ml);
4772
0
    }
4773
4774
    /* buf_size_host is the state at the end of the first pass,
4775
       keep the value that applies to this frame for later passes */
4776
0
    if (!PINFO_FD_VISITED(pinfo)) {
4777
0
        neg_buf_size = buf_size_host;
4778
0
        if (neg_buf_size != 0) {
4779
0
            p_add_proto_data(wmem_file_scope(), pinfo, proto_dvbci,
4780
0
                    DVBCI_PROTO_DATA_BUF_SIZE_HOST, GUINT_TO_POINTER(neg_buf_size));
4781
0
        }
4782
0
    }
4783
0
    else {
4784
0
        neg_buf_size = GPOINTER_TO_UINT(p_get_proto_data(wmem_file_scope(),
4785
0
                    pinfo, proto_dvbci, DVBCI_PROTO_DATA_BUF_SIZE_HOST));
4786
0
    }
4787
    /* neg_buf_size==0 -> we did not capture the buffer size negotiation */
4788
0
    if (neg_buf_size!=0 && payload_len>neg_buf_size) {
4789
0
        proto_tree_add_expert_format(link_tree, pinfo, &ei_dvbci_bad_length, tvb, 0, payload_len,
4790
0
                "Payload too large, maximum payload length is the negotiated buffer size (%u bytes)", neg_buf_size);
4791
0
    }
4792
4793
0
    frag_msg = fragment_add_seq_next(&tpdu_reassembly_table,
4794
0
            tvb, 2, pinfo, TPDU_SEQ_ID_BASE+tcid, NULL,
4795
0
            tvb_reported_length_remaining(tvb, 2),
4796
0
            more_last == ML_MORE ? 1 : 0);
4797
4798
0
    payload_tvb = process_reassembled_data(tvb, 2, pinfo,
4799
0
            "Reassembled TPDU", frag_msg, &tpdu_frag_items,
4800
0
            NULL, link_tree);
4801
0
    if (!payload_tvb) {
4802
0
        if (more_last == ML_MORE) {
4803
0
            pinfo->fragmented = true;
4804
0
            col_append_str(pinfo->cinfo, COL_INFO, " (Message fragment)");
4805
0
       } else
4806
0
            payload_tvb = tvb_new_subset_remaining(tvb, 2);
4807
0
    }
4808
0
    if (payload_tvb)
4809
0
        dissect_dvbci_tpdu(payload_tvb, pinfo, tree, direction, tcid);
4810
0
}
4811
4812
/* dissect DVB-CI buffer size negotiation */
4813
static void
4814
dissect_dvbci_buf_neg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4815
        uint8_t direction)
4816
0
{
4817
0
    uint16_t    buf_size;
4818
0
    unsigned    cam_buf_size;
4819
0
    proto_item *pi;
4820
4821
0
    buf_size = tvb_get_ntohs(tvb, 0);
4822
4823
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %u bytes",
4824
0
                 direction == DATA_HOST_TO_CAM ?
4825
0
                 "negotiated buffer size" : "buffer size proposal",
4826
0
                 buf_size);
4827
4828
0
    if (direction == DATA_HOST_TO_CAM) {
4829
        /* keep the CAM's proposal that applies to this frame
4830
           for later passes */
4831
0
        if (!PINFO_FD_VISITED(pinfo)) {
4832
0
            buf_size_host = buf_size;
4833
0
            cam_buf_size = buf_size_cam;
4834
0
            p_add_proto_data(wmem_file_scope(), pinfo, proto_dvbci,
4835
0
                    DVBCI_PROTO_DATA_BUF_SIZE_CAM, GUINT_TO_POINTER(cam_buf_size));
4836
0
        }
4837
0
        else {
4838
0
            cam_buf_size = GPOINTER_TO_UINT(p_get_proto_data(wmem_file_scope(),
4839
0
                        pinfo, proto_dvbci, DVBCI_PROTO_DATA_BUF_SIZE_CAM));
4840
0
        }
4841
0
        pi = proto_tree_add_uint_format(tree, hf_dvbci_buf_size, tvb,
4842
0
                0, 2, buf_size,
4843
0
                "Negotiated buffer size: %u bytes", buf_size);
4844
0
        if (buf_size > cam_buf_size) {
4845
            /* ATTENTION:
4846
               wireshark may run through each packet multiple times
4847
               if we didn't check the direction, we'd get the error when
4848
               wireshark runs through the initial CAM packet for the 2nd time
4849
             */
4850
0
            expert_add_info_format(pinfo, pi, &ei_dvbci_buf_size, "Illegal buffer size command. Host shall not request a buffer size larger than the CAM proposal");
4851
0
        }
4852
0
    }
4853
0
    else if (direction == DATA_CAM_TO_HOST) {
4854
0
        if (!PINFO_FD_VISITED(pinfo))
4855
0
            buf_size_cam = buf_size;
4856
0
        proto_tree_add_uint_format(tree, hf_dvbci_buf_size, tvb,
4857
0
                0, 2, buf_size,
4858
0
                "Buffer size proposal by the CAM: %u bytes", buf_size);
4859
0
    }
4860
4861
0
    if (buf_size < 16) {
4862
0
        proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_buf_size, tvb, 0, 2,
4863
0
               "Illegal buffer size, minimum buffer size is 16 bytes");
4864
0
    }
4865
0
}
4866
4867
/* dissect Level 1 version/product information tuple's payload
4868
   data_tvb is a separate tvb for the tuple payload (without tag and len)
4869
   return the number of dissected bytes or -1 for error */
4870
static int
4871
dissect_dvbci_cis_payload_tpll_v1(tvbuff_t *data_tvb,
4872
        packet_info *pinfo _U_, proto_tree *tree)
4873
0
{
4874
0
    unsigned offset=0, offset_str_end;
4875
4876
    /* the CIS is defined by PCMCIA, all multi-byte values are little endian
4877
       (the rest of DVB-CI is a big-endian protocol) */
4878
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpll_v1_major,
4879
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4880
0
    offset++;
4881
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpll_v1_minor,
4882
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4883
0
    offset++;
4884
4885
    /* manufacturer, name and additional infos are 0-terminated strings */
4886
0
    if (!tvb_find_uint8_remaining(data_tvb, offset, 0x0, &offset_str_end))
4887
0
        return offset;
4888
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpll_v1_info_manuf,
4889
0
            data_tvb, offset, offset_str_end-offset, ENC_ASCII);
4890
0
    offset = offset_str_end+1; /* +1 for 0 termination */
4891
4892
0
    if (!tvb_find_uint8_remaining(data_tvb, offset, 0x0, &offset_str_end))
4893
0
        return offset;
4894
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpll_v1_info_name,
4895
0
            data_tvb, offset, offset_str_end-offset, ENC_ASCII);
4896
0
    offset = offset_str_end+1;
4897
4898
    /* the pc-card spec mentions two additional info strings,
4899
        it's unclear if both are mandatory
4900
       >1 because the last byte is the tuple end marker */
4901
0
    while (tvb_reported_length_remaining(data_tvb, offset)>1) {
4902
0
        if (!tvb_find_uint8_remaining(data_tvb, offset, 0x0, &offset_str_end))
4903
0
            break;
4904
0
        proto_tree_add_item(tree, hf_dvbci_cis_tpll_v1_info_additional,
4905
0
                data_tvb, offset, offset_str_end-offset, ENC_ASCII);
4906
0
        offset = offset_str_end+1;
4907
0
    }
4908
4909
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpll_v1_end,
4910
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4911
0
    offset++;
4912
4913
0
    return offset;
4914
0
}
4915
4916
static int
4917
dissect_dvbci_cis_payload_config(tvbuff_t *data_tvb,
4918
        packet_info *pinfo _U_, proto_tree *tree)
4919
0
{
4920
0
    int          offset = 0;
4921
    /* these are the actual sizes, the CIS stores rmsz-1 and rasz-1 */
4922
0
    uint8_t      rfsz, rmsz, rasz;
4923
0
    uint8_t      st_code, st_len;
4924
0
    const char *st_code_str;
4925
0
    proto_item  *st_item = NULL;
4926
0
    proto_tree  *st_tree = NULL;
4927
0
    uint8_t      stci_ifn_size;   /* actual size, see comment above */
4928
4929
0
    rfsz = (tvb_get_uint8(data_tvb, offset)&0xC0) >> 6;
4930
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpcc_rfsz,
4931
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4932
0
    rmsz = ((tvb_get_uint8(data_tvb, offset)&0x3C) >> 2) + 1;
4933
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpcc_rmsz,
4934
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4935
0
    rasz = (tvb_get_uint8(data_tvb, offset)&0x03) + 1;
4936
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpcc_rasz,
4937
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4938
0
    offset++;
4939
4940
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpcc_last,
4941
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4942
0
    offset++;
4943
4944
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpcc_radr,
4945
0
            data_tvb, offset, rasz, ENC_LITTLE_ENDIAN);
4946
0
    offset += rasz;
4947
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpcc_rmsk,
4948
0
            data_tvb, offset, rmsz, ENC_NA);
4949
0
    offset += rmsz;
4950
0
    offset += rfsz; /* skip reserved bytes */
4951
4952
0
    while (tvb_reported_length_remaining(data_tvb, offset) > 0) {
4953
0
        st_code = tvb_get_uint8(data_tvb, offset);
4954
0
        st_code_str = val_to_str_const(st_code, dvbci_cis_subtpl_code, "unknown");
4955
0
        st_tree = proto_tree_add_subtree_format(tree, data_tvb, offset, -1,
4956
0
                ett_dvbci_cis_subtpl, &st_item, "Subtuple: %s (0x%x)", st_code_str, st_code);
4957
0
        proto_tree_add_item(st_tree, hf_dvbci_cis_st_code,
4958
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4959
0
        offset++;
4960
0
        st_len = tvb_get_uint8(data_tvb, offset);
4961
0
        proto_item_set_len(st_item, 2+st_len); /* tag, len byte, body */
4962
0
        proto_tree_add_item(st_tree, hf_dvbci_cis_st_len,
4963
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4964
0
        offset++;
4965
0
        if (st_code == CCSTPL_CIF) {
4966
0
            stci_ifn_size = ((tvb_get_uint8(data_tvb, offset) & 0xC0)>>6)+1;
4967
0
            proto_tree_add_item(st_tree, hf_dvbci_cis_stci_ifn_size,
4968
0
                    data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4969
            /* don't increment offset,
4970
               size and actual value's LSB share the same byte */
4971
0
            proto_tree_add_item(st_tree, hf_dvbci_cis_stci_ifn,
4972
0
                    data_tvb, offset, stci_ifn_size, ENC_LITTLE_ENDIAN);
4973
0
            offset += stci_ifn_size;
4974
            /* the stci_str field could consist of multiple strings,
4975
               this case is not supported for now */
4976
0
            proto_tree_add_item(st_tree, hf_dvbci_cis_stci_str,
4977
0
                    data_tvb, offset, st_len-stci_ifn_size, ENC_ASCII);
4978
0
            offset += st_len-stci_ifn_size;
4979
0
        }
4980
0
        else {
4981
            /* skip unknown subtuple's content */
4982
0
            offset += st_len;
4983
0
        }
4984
0
    }
4985
4986
0
    return offset;
4987
0
}
4988
4989
4990
static int
4991
dissect_dvbci_cis_payload_cftable_entry(tvbuff_t *data_tvb,
4992
        packet_info *pinfo _U_, proto_tree *tree)
4993
0
{
4994
0
    unsigned offset = 0;
4995
0
    bool intface_flag;
4996
4997
0
    intface_flag = ((tvb_get_uint8(data_tvb, offset) & 0x80) == 0x80);
4998
    /* tpce_indx byte */
4999
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpce_indx_intface,
5000
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
5001
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpce_indx_default,
5002
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
5003
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpce_indx_cnf_entry,
5004
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
5005
0
    offset++;
5006
5007
0
    if (intface_flag) {
5008
        /* tpce_if byte */
5009
0
        proto_tree_add_item(tree, hf_dvbci_cis_tpce_if_type,
5010
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
5011
        /* XXX parse other components of tpce_if */
5012
0
        offset++;
5013
0
    }
5014
5015
    /* tpce_fs byte: this is present in any case */
5016
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpce_fs_mem_space,
5017
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
5018
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpce_fs_irq,
5019
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
5020
0
    proto_tree_add_item(tree, hf_dvbci_cis_tpce_fs_io,
5021
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
5022
    /* XXX parse other components of tpce_fs */
5023
0
    offset++;
5024
5025
0
    return offset;
5026
0
}
5027
5028
/* dissect the payload of a device_oc or device_oa tuple */
5029
static int
5030
dissect_dvbci_cis_payload_device(tvbuff_t *data_tvb,
5031
        packet_info *pinfo _U_, proto_tree *tree)
5032
0
{
5033
0
    int       offset = 0;
5034
0
    bool      ext;
5035
5036
0
    ext = ((tvb_get_uint8(data_tvb, offset) & 0x80) == 0x80);
5037
5038
0
    proto_tree_add_item(tree, hf_dvbci_cis_dev_vcc_used,
5039
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
5040
0
    proto_tree_add_item(tree, hf_dvbci_cis_dev_mwait,
5041
0
            data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
5042
0
    offset++;
5043
5044
0
    while (ext) {
5045
0
        ext = ((tvb_get_uint8(data_tvb, offset) & 0x80) == 0x80);
5046
5047
0
        proto_tree_add_item(tree, hf_dvbci_cis_dev_oth_cond_info,
5048
0
                data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
5049
0
        offset++;
5050
0
    }
5051
5052
0
    return offset;
5053
0
}
5054
5055
static void
5056
dissect_dvbci_cis(tvbuff_t *tvb, unsigned offset,
5057
        packet_info *pinfo, proto_tree *tree)
5058
0
{
5059
0
    int          offset_start;
5060
0
    proto_tree  *cis_tree = NULL, *tpl_tree = NULL;
5061
0
    proto_item  *ti_main, *ti_tpl;
5062
0
    uint8_t      tpl_code;
5063
0
    const char *tpl_code_str = NULL;
5064
0
    uint8_t      len_field;
5065
0
    tvbuff_t    *tpl_data_tvb;
5066
5067
0
    offset_start = offset;
5068
5069
0
    cis_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
5070
0
            ett_dvbci_cis, &ti_main, "Card Information Structure (CIS)");
5071
5072
0
    do {
5073
0
        tpl_code = tvb_get_uint8(tvb, offset);
5074
0
        tpl_code_str = val_to_str_const(tpl_code, dvbci_cis_tpl_code, "unknown");
5075
5076
0
        tpl_tree = proto_tree_add_subtree_format(cis_tree,
5077
0
                tvb, offset, -1, ett_dvbci_cis_tpl, &ti_tpl, "CIS tuple: %s", tpl_code_str);
5078
5079
0
        proto_tree_add_uint_format(tpl_tree, hf_dvbci_cis_tpl_code,
5080
0
                tvb, offset, 1, tpl_code, "Tuple code: %s (0x%x)",
5081
0
                tpl_code_str, tpl_code);
5082
0
        offset++;
5083
5084
0
        if (tpl_code == CISTPL_END) {
5085
0
            proto_item_set_len(ti_tpl, 1); /* only tag (no len and content) */
5086
0
            break;
5087
0
        }
5088
5089
0
        len_field = tvb_get_uint8(tvb, offset);
5090
0
        proto_tree_add_item(tpl_tree, hf_dvbci_cis_tpl_len,
5091
0
                tvb, offset, 1, ENC_LITTLE_ENDIAN);
5092
0
        offset++;
5093
5094
0
        tpl_data_tvb = tvb_new_subset_length(tvb, offset, len_field);
5095
0
        switch (tpl_code) {
5096
0
            case CISTPL_VERS_1:
5097
0
                dissect_dvbci_cis_payload_tpll_v1(
5098
0
                        tpl_data_tvb, pinfo, tpl_tree);
5099
0
                offset += len_field;
5100
0
                break;
5101
0
            case CISTPL_CONFIG:
5102
0
                dissect_dvbci_cis_payload_config(tpl_data_tvb, pinfo, tpl_tree);
5103
0
                offset += len_field;
5104
0
                break;
5105
0
            case CISTPL_CFTABLE_ENTRY:
5106
0
                dissect_dvbci_cis_payload_cftable_entry(
5107
0
                        tpl_data_tvb, pinfo, tpl_tree);
5108
0
                offset += len_field;
5109
0
                break;
5110
0
            case CISTPL_DEVICE_OC:
5111
                /* fall through: those two tuples' data is identical */
5112
0
            case CISTPL_DEVICE_OA:
5113
0
                dissect_dvbci_cis_payload_device(
5114
0
                        tpl_data_tvb, pinfo, tpl_tree);
5115
0
                offset += len_field;
5116
0
                break;
5117
0
            case CISTPL_MANFID:
5118
0
                proto_tree_add_item(tpl_tree, hf_dvbci_cis_tplmid_manf,
5119
0
                        tvb, offset, 2, ENC_LITTLE_ENDIAN);
5120
0
                offset+=2;
5121
0
                proto_tree_add_item(tpl_tree, hf_dvbci_cis_tplmid_card,
5122
0
                        tvb, offset, 2, ENC_LITTLE_ENDIAN);
5123
0
                offset+=2;
5124
0
                break;
5125
0
            default:
5126
0
                if (len_field>0) {
5127
0
                    proto_tree_add_item(tpl_tree, hf_dvbci_cis_tpl_data,
5128
0
                            tvb, offset, len_field, ENC_NA);
5129
0
                }
5130
0
                offset += len_field;
5131
0
                break;
5132
0
        }
5133
5134
0
        proto_item_set_len(ti_tpl, 2+len_field); /* tag, len byte, content */
5135
5136
0
    } while (tvb_reported_length_remaining(tvb, offset) > 0);
5137
5138
0
    proto_item_set_len(ti_main, offset-offset_start);
5139
0
}
5140
5141
5142
static int
5143
dissect_dvbci(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
5144
0
{
5145
0
    int          packet_len, offset = 0, offset_ver, offset_evt, offset_len_field;
5146
0
    uint8_t      version, event;
5147
0
    const char *event_str;
5148
0
    uint16_t     len_field;
5149
0
    proto_item  *ti;
5150
0
    proto_tree  *dvbci_tree, *hdr_tree;
5151
0
    tvbuff_t    *payload_tvb;
5152
0
    uint16_t     cor_addr;
5153
0
    uint8_t      cor_value;
5154
0
    proto_item  *pi;
5155
0
    uint8_t      hw_event;
5156
5157
0
    if (tvb_captured_length(tvb) < 4)
5158
0
        return 0;
5159
5160
0
    offset_ver = offset;
5161
0
    version = tvb_get_uint8(tvb, offset++);
5162
0
    if (version != 0)
5163
0
        return 0;
5164
5165
0
    offset_evt = offset;
5166
0
    event = tvb_get_uint8(tvb, offset++);
5167
0
    event_str = try_val_to_str(event, dvbci_event);
5168
0
    if (!event_str)
5169
0
        return 0;
5170
5171
0
    packet_len = tvb_reported_length(tvb);
5172
0
    offset_len_field = offset;
5173
0
    len_field = tvb_get_ntohs(tvb, offset);
5174
0
    if (len_field != (packet_len-4))
5175
0
        return 0;
5176
0
    offset += 2;
5177
5178
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "DVB-CI");
5179
0
    col_set_str(pinfo->cinfo, COL_INFO, event_str);
5180
5181
0
    ti = proto_tree_add_protocol_format(tree, proto_dvbci,
5182
0
            tvb, 0, packet_len, "DVB Common Interface: %s", event_str);
5183
0
    dvbci_tree = proto_item_add_subtree(ti, ett_dvbci);
5184
0
    hdr_tree = proto_tree_add_subtree(dvbci_tree,
5185
0
            tvb, 0, offset, ett_dvbci_hdr, NULL, "Pseudo header");
5186
0
    proto_tree_add_item(hdr_tree, hf_dvbci_hdr_ver,
5187
0
            tvb, offset_ver, 1, ENC_BIG_ENDIAN);
5188
0
    proto_tree_add_item(hdr_tree, hf_dvbci_event,
5189
0
            tvb, offset_evt, 1, ENC_BIG_ENDIAN);
5190
0
    proto_tree_add_item(hdr_tree, hf_dvbci_len,
5191
0
            tvb, offset_len_field, 2, ENC_BIG_ENDIAN);
5192
5193
0
    if (IS_DATA_TRANSFER(event)) {
5194
0
        dvbci_set_addrs(event, pinfo);
5195
5196
0
        payload_tvb = tvb_new_subset_remaining(tvb, offset);
5197
0
        if (len_field == 2) {
5198
0
            dissect_dvbci_buf_neg(payload_tvb, pinfo, dvbci_tree, event);
5199
0
        }
5200
0
        else {
5201
0
            dissect_dvbci_lpdu(payload_tvb, pinfo, dvbci_tree, event);
5202
0
        }
5203
0
    }
5204
0
    else if (event==DVBCI_EVT_COR_WRITE) {
5205
        /* PCAP format for DVB-CI defines COR address as big endian */
5206
0
        pi = proto_tree_add_item(dvbci_tree, hf_dvbci_cor_addr,
5207
0
                tvb, offset, 2, ENC_BIG_ENDIAN);
5208
0
        cor_addr = tvb_get_ntohs(tvb, offset);
5209
0
        if (cor_addr == 0xFFFF) {
5210
0
            proto_item_append_text(pi, " (COR address is unknown)");
5211
0
            col_append_sep_str(pinfo->cinfo, COL_INFO, ": ", "unknown address");
5212
0
        }
5213
0
        else if (cor_addr > 0xFFE) {
5214
0
            expert_add_info(pinfo, pi, &ei_dvbci_cor_addr);
5215
0
        }
5216
0
        else {
5217
0
            col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
5218
0
                "address 0x%x", cor_addr);
5219
0
        }
5220
0
        offset += 2;
5221
0
        cor_value = tvb_get_uint8(tvb, offset);
5222
0
        proto_tree_add_item(dvbci_tree, hf_dvbci_cor_val,
5223
0
                tvb, offset, 1, ENC_BIG_ENDIAN);
5224
0
        col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
5225
0
            "value 0x%x", cor_value);
5226
0
    }
5227
0
    else if (event==DVBCI_EVT_CIS_READ) {
5228
0
        dissect_dvbci_cis(tvb, offset, pinfo, dvbci_tree);
5229
0
    }
5230
0
    else if (event==DVBCI_EVT_HW_EVT) {
5231
0
        hw_event = tvb_get_uint8(tvb, offset);
5232
0
        col_set_str(pinfo->cinfo, COL_INFO,
5233
0
                val_to_str_const(hw_event, dvbci_hw_event, "Invalid hardware event"));
5234
0
        proto_tree_add_item(dvbci_tree, hf_dvbci_hw_event,
5235
0
                tvb, offset, 1, ENC_BIG_ENDIAN);
5236
0
    }
5237
5238
0
    return packet_len;
5239
0
}
5240
5241
static void
5242
dvbci_shutdown(void)
5243
0
{
5244
0
    if (spdu_table)
5245
0
        g_hash_table_destroy(spdu_table);
5246
0
    if (apdu_table)
5247
0
        g_hash_table_destroy(apdu_table);
5248
0
}
5249
5250
void
5251
proto_register_dvbci(void)
5252
16
{
5253
16
    unsigned  i;
5254
16
    module_t *dvbci_module;
5255
16
    expert_module_t* expert_dvbci;
5256
5257
16
    static int *ett[] = {
5258
16
        &ett_dvbci,
5259
16
        &ett_dvbci_hdr,
5260
16
        &ett_dvbci_cis,
5261
16
        &ett_dvbci_cis_tpl,
5262
16
        &ett_dvbci_cis_subtpl,
5263
16
        &ett_dvbci_link,
5264
16
        &ett_dvbci_link_frag,
5265
16
        &ett_dvbci_link_frags,
5266
16
        &ett_dvbci_transport,
5267
16
        &ett_dvbci_transport_frag,
5268
16
        &ett_dvbci_transport_frags,
5269
16
        &ett_dvbci_session,
5270
16
        &ett_dvbci_res,
5271
16
        &ett_dvbci_application,
5272
16
        &ett_dvbci_es,
5273
16
        &ett_dvbci_ca_desc,
5274
16
        &ett_dvbci_text,
5275
16
        &ett_dvbci_cc_item,
5276
16
        &ett_dvbci_sac_msg_body,
5277
16
        &ett_dvbci_ami_req_types,
5278
16
        &ett_dvbci_lsc_conn_desc,
5279
16
        &ett_dvbci_opp_cap_loop,
5280
16
        &ett_dvbci_dlv_sys_hint
5281
16
    };
5282
5283
16
    static hf_register_info hf[] = {
5284
16
        { &hf_dvbci_hdr_ver,
5285
16
          { "Version", "dvb-ci.hdr_version",
5286
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5287
16
        },
5288
16
        { &hf_dvbci_event,
5289
16
          { "Event", "dvb-ci.event",
5290
16
            FT_UINT8, BASE_HEX, VALS(dvbci_event), 0, NULL, HFILL }
5291
16
        },
5292
16
        { &hf_dvbci_len,
5293
16
          { "Length field", "dvb-ci.length_field",
5294
16
            FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
5295
16
        },
5296
16
        { &hf_dvbci_hw_event,
5297
16
          { "Hardware event", "dvb-ci.hw_event",
5298
16
            FT_UINT8, BASE_HEX, VALS(dvbci_hw_event), 0, NULL, HFILL }
5299
16
        },
5300
16
        { &hf_dvbci_cor_addr,
5301
16
          { "COR address", "dvb-ci.cor_address",
5302
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5303
16
        },
5304
16
        { &hf_dvbci_cor_val,
5305
16
          { "COR value", "dvb-ci.cor_value",
5306
16
            FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5307
16
        },
5308
16
        { &hf_dvbci_cis_tpl_code,
5309
16
          { "CIS tuple code", "dvb-ci.cis.tpl_code",
5310
16
            FT_UINT8, BASE_HEX, VALS(dvbci_cis_tpl_code), 0, NULL, HFILL }
5311
16
        },
5312
16
        { &hf_dvbci_cis_tpl_len,
5313
16
          { "Length field", "dvb-ci.cis.tpl_len",
5314
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5315
16
        },
5316
16
        { &hf_dvbci_cis_tpl_data,
5317
16
          { "Tuple data", "dvb-ci.cis.tpl_data",
5318
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5319
16
        },
5320
16
        { &hf_dvbci_cis_tpll_v1_major,
5321
16
          { "Major version number", "dvb-ci.cis.tpll_v1_major",
5322
16
            FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5323
16
        },
5324
16
        { &hf_dvbci_cis_tpll_v1_minor,
5325
16
          { "Minor version number", "dvb-ci.cis.tpll_v1_minor",
5326
16
            FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5327
16
        },
5328
16
        { &hf_dvbci_cis_tpll_v1_info_manuf,
5329
16
          { "Manufacturer", "dvb-ci.cis.tpll_v1_info.manufacturer",
5330
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
5331
16
        },
5332
16
        { &hf_dvbci_cis_tpll_v1_info_name,
5333
16
          { "Name", "dvb-ci.cis.tpll_v1_info.name",
5334
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
5335
16
        },
5336
16
        { &hf_dvbci_cis_tpll_v1_info_additional,
5337
16
          { "Additional info", "dvb-ci.cis.tpll_v1_info.additional",
5338
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
5339
16
        },
5340
16
        { &hf_dvbci_cis_tpll_v1_end,
5341
16
          { "End of chain", "dvb-ci.cis.tpll_v1_end",
5342
16
            FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5343
16
        },
5344
16
        { &hf_dvbci_cis_tpcc_rfsz,
5345
16
          { "Size of reserved area", "dvb-ci.cis.tpcc_rfsz",
5346
16
            FT_UINT8, BASE_HEX, NULL, 0xC0, NULL, HFILL }
5347
16
        },
5348
16
        { &hf_dvbci_cis_tpcc_rmsz,
5349
16
          { "Size of TPCC_RMSK field - 1", "dvb-ci.cis.tpcc_rmsz",
5350
16
            FT_UINT8, BASE_HEX, NULL, 0x3C, NULL, HFILL }
5351
16
        },
5352
16
        { &hf_dvbci_cis_tpcc_rasz,
5353
16
          { "Size of TPCC_RADR - 1", "dvb-ci.cis.tpcc_rasz",
5354
16
            FT_UINT8, BASE_HEX, NULL, 0x03, NULL, HFILL }
5355
16
        },
5356
16
        { &hf_dvbci_cis_tpcc_last,
5357
16
          { "Index of the last cftable entry", "dvb-ci.cis.tpcc_last",
5358
16
            FT_UINT8, BASE_HEX, NULL, 0x3F, NULL, HFILL }
5359
16
        },
5360
16
        { &hf_dvbci_cis_tpcc_radr,
5361
16
          { "COR base address", "dvb-ci.cis.tpcc_radr",
5362
16
            FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
5363
16
        },
5364
16
        { &hf_dvbci_cis_tpcc_rmsk,
5365
16
          { "Configuration register presence mask", "dvb-ci.cis.tpcc_rmsk",
5366
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5367
16
        },
5368
16
        { &hf_dvbci_cis_st_code,
5369
16
          { "Subtuple tag", "dvb-ci.cis.st_code",
5370
16
            FT_UINT8, BASE_HEX, VALS(dvbci_cis_subtpl_code), 0, NULL, HFILL }
5371
16
        },
5372
16
        { &hf_dvbci_cis_st_len,
5373
16
          { "Subtuple length", "dvb-ci.cis.st_len",
5374
16
            FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5375
16
        },
5376
16
        { &hf_dvbci_cis_stci_ifn_size,
5377
16
          { "Size of interface ID number - 1", "dvb-ci.cis.stci_ifn_size",
5378
16
            FT_UINT8, BASE_HEX, NULL, 0xC0, NULL, HFILL }
5379
16
        },
5380
16
        { &hf_dvbci_cis_stci_ifn,
5381
16
          { "Interface ID number", "dvb-ci.cis.stci_ifn",
5382
16
            FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
5383
16
        },
5384
16
        { &hf_dvbci_cis_stci_str,
5385
16
          { "Interface description strings", "dvb-ci.cis.stci_str",
5386
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
5387
16
        },
5388
16
        { &hf_dvbci_cis_tpce_indx_intface,
5389
16
          { "Intface", "dvb-ci.cis.tpce_indx.intface",
5390
16
            FT_UINT8, BASE_HEX, NULL, 0x80, NULL, HFILL }
5391
16
        },
5392
16
        { &hf_dvbci_cis_tpce_indx_default,
5393
16
          { "Default", "dvb-ci.cis.tpce_indx.default",
5394
16
            FT_UINT8, BASE_HEX, NULL, 0x40, NULL, HFILL }
5395
16
        },
5396
16
        { &hf_dvbci_cis_tpce_indx_cnf_entry,
5397
16
          { "Configuration entry number", "dvb-ci.cis.tpce_indx.cnf_entry",
5398
16
            FT_UINT8, BASE_HEX, NULL, 0x3F, NULL, HFILL }
5399
16
        },
5400
16
        { &hf_dvbci_cis_tpce_if_type,
5401
16
          { "Interface type", "dvb-ci.cis.tpce_if.type", FT_UINT8, BASE_HEX,
5402
16
              VALS(dvbci_cis_tpce_if_type), 0x0F, NULL, HFILL }
5403
16
        },
5404
16
        { &hf_dvbci_cis_tpce_fs_mem_space,
5405
16
          { "Mem space", "dvb-ci.cis.tpce_fs.mem_space",
5406
16
            FT_UINT8, BASE_HEX, NULL, 0x60, NULL, HFILL }
5407
16
        },
5408
16
        { &hf_dvbci_cis_tpce_fs_irq,
5409
16
          { "IRQ", "dvb-ci.cis.tpce_fs.irq",
5410
16
            FT_UINT8, BASE_HEX, NULL, 0x10, NULL, HFILL }
5411
16
        },
5412
16
        { &hf_dvbci_cis_tpce_fs_io,
5413
16
          { "IO Space", "dvb-ci.cis.tpce_fs.io",
5414
16
            FT_UINT8, BASE_HEX, NULL, 0x08, NULL, HFILL }
5415
16
        },
5416
16
        { &hf_dvbci_cis_dev_vcc_used,
5417
16
          { "Vcc used", "dvb-ci.cis.device.vcc_used",
5418
16
              FT_UINT8, BASE_HEX, VALS(dvbci_cis_dev_vcc_used), 0x06, NULL, HFILL }
5419
16
        },
5420
16
        { &hf_dvbci_cis_dev_mwait,
5421
16
          { "MWait", "dvb-ci.cis.device.mwait",
5422
16
            FT_UINT8, BASE_HEX, NULL, 0x01, NULL, HFILL }
5423
16
        },
5424
16
        { &hf_dvbci_cis_dev_oth_cond_info,
5425
16
          { "Other conditions info", "dvb-ci.cis.device.other_cond",
5426
16
            FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5427
16
        },
5428
16
        { &hf_dvbci_cis_tplmid_manf,
5429
16
          { "PC Card manufacturer code", "dvb-ci.cis.tplmid_manf",
5430
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5431
16
        },
5432
16
        { &hf_dvbci_cis_tplmid_card,
5433
16
          { "Manufacturer info", "dvb-ci.cis.tplmid_card",
5434
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5435
16
        },
5436
16
        { &hf_dvbci_buf_size,
5437
16
          { "Buffer Size", "dvb-ci.buf_size",
5438
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5439
16
        },
5440
16
        { &hf_dvbci_tcid,
5441
16
          { "Transport Connection ID", "dvb-ci.tcid",
5442
16
            FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5443
16
        },
5444
16
        { &hf_dvbci_ml,
5445
16
          { "More/Last indicator", "dvb-ci.more_last",
5446
16
            FT_UINT8, BASE_HEX, VALS(dvbci_ml), 0, NULL, HFILL }
5447
16
        },
5448
        /* on the link layer, tpdus are reassembled */
5449
16
        { &hf_dvbci_l_frags,
5450
16
          { "Tpdu fragments", "dvb-ci.tpdu_fragments",
5451
16
           FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL }
5452
16
        },
5453
16
        { &hf_dvbci_l_frag,
5454
16
          { "Tpdu fragment", "dvb-ci.tpdu_fragment",
5455
16
           FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
5456
16
        },
5457
16
        { &hf_dvbci_l_frag_overlap,
5458
16
          { "Tpdu fragment overlap", "dvb-ci.tpdu_fragment.overlap",
5459
16
           FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
5460
16
        },
5461
16
        { &hf_dvbci_l_frag_overlap_conflicts,
5462
16
          { "Tpdu fragment overlapping with conflicting data",
5463
16
           "dvb-ci.tpdu_fragment.overlap.conflicts",
5464
16
           FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
5465
16
        },
5466
16
        { &hf_dvbci_l_frag_multiple_tails,
5467
16
          { "Tpdu has multiple tail fragments",
5468
16
           "dvb-ci.tpdu_fragment.multiple_tails",
5469
16
          FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
5470
16
        },
5471
16
        { &hf_dvbci_l_frag_too_long_frag,
5472
16
          { "Tpdu fragment too long", "dvb-ci.tpdu_fragment.too_long_fragment",
5473
16
           FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
5474
16
        },
5475
16
        { &hf_dvbci_l_frag_err,
5476
16
          { "Tpdu defragmentation error", "dvb-ci.tpdu_fragment.error",
5477
16
           FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
5478
16
        },
5479
16
        { &hf_dvbci_l_frag_cnt,
5480
16
          { "Tpdu fragment count", "dvb-ci.tpdu_fragment.count",
5481
16
           FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
5482
16
        },
5483
16
        { &hf_dvbci_l_reass_in,
5484
16
          { "Tpdu reassembled in", "dvb-ci.tpdu_reassembled.in",
5485
16
           FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
5486
16
        },
5487
16
        { &hf_dvbci_l_reass_len,
5488
16
          { "Reassembled tpdu length", "dvb-ci.tpdu_reassembled.length",
5489
16
           FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
5490
16
        },
5491
16
        { &hf_dvbci_c_tpdu_tag,
5492
16
          { "Command TPDU Tag", "dvb-ci.c_tpdu_tag",
5493
16
            FT_UINT8, BASE_HEX, VALS(dvbci_c_tpdu), 0, NULL, HFILL }
5494
16
        },
5495
16
        { &hf_dvbci_r_tpdu_tag,
5496
16
           { "Response TPDU Tag", "dvb-ci.r_tpdu_tag",
5497
16
             FT_UINT8, BASE_HEX, VALS(dvbci_r_tpdu), 0, NULL, HFILL }
5498
16
        },
5499
16
        { &hf_dvbci_t_c_id,
5500
16
           { "Transport Connection ID", "dvb-ci.t_c_id",
5501
16
             FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5502
16
        },
5503
16
        { &hf_dvbci_sb_tag,
5504
16
           { "SB tag", "dvb-ci.sb_tag",
5505
16
             FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5506
16
        },
5507
16
        { &hf_dvbci_sb_value,
5508
16
          { "SB Value", "dvb-ci.sb_value", FT_UINT8, BASE_HEX,
5509
16
            VALS(dvbci_sb_value), 0, NULL, HFILL } },
5510
5511
        /* on the transport layer, spdus are reassembled */
5512
16
        { &hf_dvbci_t_frags,
5513
16
          { "Spdu fragments", "dvb-ci.spdu_fragments",
5514
16
           FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL }
5515
16
        },
5516
16
        { &hf_dvbci_t_frag,
5517
16
          { "Spdu fragment", "dvb-ci.spdu_fragment",
5518
16
           FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
5519
16
        },
5520
16
        { &hf_dvbci_t_frag_overlap,
5521
16
          { "Spdu fragment overlap", "dvb-ci.spdu_fragment.overlap",
5522
16
           FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
5523
16
        },
5524
16
        { &hf_dvbci_t_frag_overlap_conflicts,
5525
16
          { "Spdu fragment overlapping with conflicting data",
5526
16
           "dvb-ci.tpdu_fragment.overlap.conflicts",
5527
16
          FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
5528
16
        },
5529
16
        { &hf_dvbci_t_frag_multiple_tails,
5530
16
          { "Spdu has multiple tail fragments",
5531
16
           "dvb-ci.spdu_fragment.multiple_tails",
5532
16
           FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
5533
16
        },
5534
16
        { &hf_dvbci_t_frag_too_long_frag,
5535
16
          { "Spdu fragment too long", "dvb-ci.spdu_fragment.too_long_fragment",
5536
16
           FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
5537
16
        },
5538
16
        { &hf_dvbci_t_frag_err,
5539
16
          { "Spdu defragmentation error", "dvb-ci.spdu_fragment.error",
5540
16
           FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
5541
16
        },
5542
16
        { &hf_dvbci_t_frag_cnt,
5543
16
          { "Spdu fragment count", "dvb-ci.spdu_fragment.count",
5544
16
           FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
5545
16
        },
5546
16
        { &hf_dvbci_t_reass_in,
5547
16
          { "Spdu reassembled in", "dvb-ci.spdu_reassembled.in",
5548
16
           FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
5549
16
        },
5550
16
        { &hf_dvbci_t_reass_len,
5551
16
          { "Reassembled spdu length", "dvb-ci.spdu_reassembled.length",
5552
16
           FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
5553
16
        },
5554
16
        { &hf_dvbci_spdu_tag,
5555
16
          { "SPDU Tag", "dvb-ci.spdu_tag",
5556
16
           FT_UINT8, BASE_HEX, VALS(dvbci_spdu_tag), 0, NULL, HFILL }
5557
16
        },
5558
16
        { &hf_dvbci_sess_status,
5559
16
          { "Session Status", "dvb-ci.session_status",
5560
16
            FT_UINT8, BASE_HEX, VALS(dvbci_sess_status), 0, NULL, HFILL }
5561
16
        },
5562
16
        { &hf_dvbci_sess_nb,
5563
16
          { "Session Number", "dvb-ci.session_nb",
5564
16
            FT_UINT16, BASE_DEC, NULL , 0, NULL, HFILL }
5565
16
        },
5566
16
        { &hf_dvbci_close_sess_status,
5567
16
          { "Session Status", "dvb-ci.close_session_status",
5568
16
            FT_UINT8, BASE_HEX, VALS(dvbci_close_sess_status), 0, NULL, HFILL }
5569
16
        },
5570
16
        { &hf_dvbci_res_id,
5571
16
          { "Resource ID", "dvb-ci.res.id",
5572
16
            FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
5573
16
        },
5574
16
        { &hf_dvbci_res_id_type,
5575
16
          { "Resource ID Type", "dvb-ci.res.id_type",
5576
16
            FT_UINT32, BASE_HEX, NULL, RES_ID_TYPE_MASK, NULL, HFILL }
5577
16
        },
5578
16
        { &hf_dvbci_res_class,
5579
16
          { "Resource Class", "dvb-ci.res.class",
5580
16
            FT_UINT32, BASE_HEX, VALS(dvbci_res_class), RES_CLASS_MASK, NULL, HFILL }
5581
16
        },
5582
16
        { &hf_dvbci_res_type,
5583
16
          { "Resource Type", "dvb-ci.res.type",
5584
16
            FT_UINT32, BASE_HEX, NULL, RES_TYPE_MASK, NULL, HFILL }
5585
16
        },
5586
16
        { &hf_dvbci_res_ver,
5587
16
          { "Resource Version", "dvb-ci.res.version",
5588
16
            FT_UINT32, BASE_HEX, NULL, RES_VER_MASK, NULL, HFILL }
5589
16
        },
5590
16
        { &hf_dvbci_apdu_tag,
5591
16
          { "APDU Tag", "dvb-ci.apdu_tag",
5592
16
            FT_UINT24, BASE_HEX, VALS(dvbci_apdu_tag), 0, NULL, HFILL }
5593
16
        },
5594
16
        { &hf_dvbci_app_type,
5595
16
          { "Application type", "dvb-ci.ap.type",
5596
16
            FT_UINT8, BASE_HEX, VALS(dvbci_app_type), 0, NULL, HFILL }
5597
16
        },
5598
16
        { &hf_dvbci_app_manf,
5599
16
          { "Application manufacturer", "dvb-ci.ap.manufacturer",
5600
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5601
16
        },
5602
16
        { &hf_dvbci_manf_code,
5603
16
          { "Manufacturer code", "dvb-ci.ap.manufacturer_code",
5604
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5605
16
        },
5606
16
        { &hf_dvbci_menu_str_len,
5607
16
          { "Menu string length", "dvb-ci.ap.menu_string_length",
5608
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5609
16
        },
5610
16
        { &hf_dvbci_ap_char_tbl,
5611
16
          { "Character table", "dvb-ci.ap.menu_char_tbl",
5612
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL}
5613
16
        },
5614
16
        { &hf_dvbci_menu_str,
5615
16
          { "Menu string", "dvb-ci.ap.menu_string",
5616
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
5617
16
        },
5618
16
        { &hf_dvbci_data_rate,
5619
16
          { "Transport stream data rate supported by the host",
5620
16
            "dvb-ci.ap.data_rate",
5621
16
            FT_UINT8, BASE_HEX, VALS(dvbci_data_rate), 0, NULL, HFILL }
5622
16
        },
5623
16
        { &hf_dvbci_ca_sys_id,
5624
16
          { "CA system ID", "dvb-ci.ca.ca_system_id",
5625
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5626
16
        },
5627
16
        { &hf_dvbci_ca_pmt_list_mgmt,
5628
16
          { "CA PMT list management", "dvb-ci.ca.ca_pmt_list_management",
5629
16
            FT_UINT8, BASE_HEX, VALS(dvbci_ca_pmt_list_mgmt), 0, NULL,
5630
16
            HFILL }
5631
16
        },
5632
16
        { &hf_dvbci_prog_num,
5633
16
          { "Program number", "dvb-ci.ca.program_number",
5634
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5635
16
        },
5636
16
        { &hf_dvbci_ca_ver,
5637
16
          { "Version number", "dvb-ci.ca.version_number",
5638
16
            FT_UINT8, BASE_HEX, NULL, 0x3E, NULL, HFILL }
5639
16
        },
5640
16
        { &hf_dvbci_curr_next,
5641
16
          { "Current-next indicator", "dvb-ci.ca.current_next_indicator",
5642
16
            FT_UINT8, BASE_HEX, NULL, 0x01, NULL, HFILL }
5643
16
        },
5644
16
        { &hf_dvbci_prog_info_len,
5645
16
          { "Program info length", "dvb-ci.ca.program_info_length",
5646
16
            FT_UINT16, BASE_HEX, NULL, 0x0FFF, NULL, HFILL }
5647
16
        },
5648
16
        { &hf_dvbci_stream_type,
5649
16
          { "Stream type", "dvb-ci.ca.stream_type", FT_UINT8,
5650
16
              BASE_HEX|BASE_EXT_STRING, &mpeg_pmt_stream_type_vals_ext,
5651
16
              0, NULL, HFILL }
5652
16
        },
5653
16
        { &hf_dvbci_es_pid,
5654
16
          { "Elementary stream PID", "dvb-ci.ca.elementary_pid",
5655
16
            FT_UINT16, BASE_HEX, NULL, 0x1FFF, NULL, HFILL }
5656
16
        },
5657
16
        { &hf_dvbci_es_info_len,
5658
16
          { "Elementary stream info length", "dvb-ci.ca.es_info_length",
5659
16
            FT_UINT16, BASE_HEX, NULL, 0x0FFF, NULL, HFILL }
5660
16
        },
5661
16
        { &hf_dvbci_ca_pmt_cmd_id,
5662
16
          { "CA PMT command ID", "dvb-ci.ca.ca_pmt_cmd_id",
5663
16
            FT_UINT8, BASE_HEX, VALS(dvbci_ca_pmt_cmd_id), 0, NULL, HFILL }
5664
16
        },
5665
16
        { &hf_dvbci_descr_len,
5666
16
          { "CA descriptor length", "dvb-ci.ca.ca_desc_len",
5667
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5668
16
        },
5669
16
        { &hf_dvbci_ca_pid,
5670
16
          { "CA PID", "dvb-ci.ca.ca_pid",
5671
16
            FT_UINT16, BASE_HEX, NULL, 0x1FFF, NULL, HFILL }
5672
16
        },
5673
16
        { &hf_dvbci_ca_priv_data,
5674
16
          { "Private data", "dvb-ci.ca.private_data",
5675
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5676
16
        },
5677
16
        { &hf_dvbci_ca_enable_flag,
5678
16
          { "CA enable flag", "dvb-ci.ca.ca_enable_flag",
5679
16
            FT_UINT8, BASE_HEX, NULL, 0x80, NULL, HFILL }
5680
16
        },
5681
16
        { &hf_dvbci_ca_enable,
5682
16
          { "CA enable", "dvb-ci.ca.ca_enable",
5683
16
            FT_UINT8, BASE_HEX, VALS(dvbci_ca_enable), 0x7F, NULL, HFILL }
5684
16
        },
5685
16
        { &hf_dvbci_auth_proto_id,
5686
16
          { "Authentication protocol ID", "dvb-ci.aut.proto_id",
5687
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5688
16
        },
5689
16
        { &hf_dvbci_auth_req_bytes,
5690
16
          { "Authentication request data", "dvb-ci.aut.req",
5691
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5692
16
        },
5693
16
        { &hf_dvbci_auth_resp_bytes,
5694
16
          { "Authentication response data", "dvb-ci.aut.resp",
5695
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5696
16
        },
5697
16
        { &hf_dvbci_network_id,
5698
16
          { "Network ID", "dvb-ci.hc.nid",
5699
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5700
16
        },
5701
16
        { &hf_dvbci_original_network_id,
5702
16
          { "Original network ID", "dvb-ci.hc.onid",
5703
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5704
16
        },
5705
16
        { &hf_dvbci_transport_stream_id,
5706
16
          { "Transport stream ID", "dvb-ci.hc.tsid",
5707
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5708
16
        },
5709
16
        { &hf_dvbci_service_id,
5710
16
          { "Service ID", "dvb-ci.hc.svcid",
5711
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5712
16
        },
5713
16
        { &hf_dvbci_replacement_ref,
5714
16
          { "Replacement reference", "dvb-ci.hc.replacement_ref",
5715
16
            FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5716
16
        },
5717
16
        { &hf_dvbci_replaced_pid,
5718
16
          { "Replaced PID", "dvb-ci.hc.replaced_pid",
5719
16
            FT_UINT16, BASE_HEX, NULL, 0x1FFF, NULL, HFILL }
5720
16
        },
5721
16
        { &hf_dvbci_replacement_pid,
5722
16
          { "Replacement PID", "dvb-ci.hc.replacement_pid",
5723
16
            FT_UINT16, BASE_HEX, NULL, 0x1FFF, NULL, HFILL }
5724
16
        },
5725
16
        { &hf_dvbci_pmt_flag,
5726
16
          { "PMT flag", "dvb-ci.hc.pmt_flag",
5727
16
            FT_UINT8, BASE_HEX, NULL, 0x01, NULL, HFILL }
5728
16
        },
5729
16
        { &hf_dvbci_hc_desc_loop_len,
5730
16
          { "Descriptor loop length", "dvb-ci.hc.desc_loop_len",
5731
16
            FT_UINT16, BASE_DEC, NULL, 0x0FFF, NULL, HFILL }
5732
16
        },
5733
16
        { &hf_dvbci_hc_status,
5734
16
          { "Status field", "dvb-ci.hc.status_field",
5735
16
            FT_UINT8, BASE_HEX, VALS(dvbci_hc_status), 0, NULL, HFILL }
5736
16
        },
5737
16
        { &hf_dvbci_hc_release_reply,
5738
16
          { "Release reply", "dvb-ci.hc.release_reply",
5739
16
            FT_UINT8, BASE_HEX, VALS(dvbci_hc_release_reply), 0, NULL, HFILL }
5740
16
        },
5741
16
        { &hf_dvbci_resp_intv,
5742
16
          { "Response interval", "dvb-ci.dt.resp_interval",
5743
16
            FT_RELATIVE_TIME, BASE_NONE, NULL, 0, NULL, HFILL }
5744
16
        },
5745
16
        { &hf_dvbci_utc_time,
5746
16
          { "UTC time", "dvb-ci.dt.utc_time",
5747
16
            FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0, NULL, HFILL }
5748
16
        },
5749
5750
        /* we have to use FT_INT16 instead of FT_RELATIVE_TIME,
5751
           local offset can be negative */
5752
16
        { &hf_dvbci_local_offset,
5753
16
          { "Local time offset", "dvb-ci.dt.local_offset",
5754
16
            FT_INT16, BASE_DEC, NULL, 0, NULL, HFILL }
5755
16
        },
5756
16
        { &hf_dvbci_close_mmi_cmd_id,
5757
16
          { "Command ID", "dvb-ci.mmi.close_mmi_cmd_id",
5758
16
            FT_UINT8, BASE_HEX, VALS(dvbci_close_mmi_cmd_id), 0, NULL, HFILL }
5759
16
        },
5760
16
        { &hf_dvbci_close_mmi_delay,
5761
16
          { "Delay (in sec)", "dvb-ci.mmi.delay",
5762
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5763
16
        },
5764
16
        { &hf_dvbci_disp_ctl_cmd,
5765
16
          { "Command", "dvb-ci.mmi.disp_ctl_cmd",
5766
16
            FT_UINT8, BASE_HEX, VALS(dvbci_disp_ctl_cmd), 0, NULL, HFILL }
5767
16
        },
5768
16
        { &hf_dvbci_mmi_mode,
5769
16
          { "MMI mode", "dvb-ci.mmi.mode",
5770
16
            FT_UINT8, BASE_HEX, VALS(dvbci_mmi_mode), 0, NULL, HFILL }
5771
16
        },
5772
16
        { &hf_dvbci_disp_rep_id,
5773
16
          { "Reply ID", "dvb-ci.mmi.disp_rep_id",
5774
16
            FT_UINT8, BASE_HEX, VALS(dvbci_disp_rep_id), 0, NULL, HFILL }
5775
16
        },
5776
16
        { &hf_dvbci_mmi_char_tbl,
5777
16
          { "Character table", "dvb-ci.mmi.char_tbl",
5778
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL}
5779
16
        },
5780
16
        { &hf_dvbci_blind_ans,
5781
16
          { "Blind answer flag", "dvb-ci.mmi.blind_ans",
5782
16
            FT_UINT8, BASE_HEX, VALS(dvbci_blind_ans), 0x01, NULL, HFILL }
5783
16
        },
5784
16
        { &hf_dvbci_ans_txt_len,
5785
16
          { "Answer text length", "dvb-ci.mmi.ans_txt_len",
5786
16
            FT_UINT8, BASE_DEC, NULL , 0, NULL, HFILL }
5787
16
        },
5788
16
        { &hf_dvbci_enq,
5789
16
          { "Enquiry string", "dvb-ci.mmi.enq",
5790
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
5791
16
        },
5792
16
        { &hf_dvbci_ans_id,
5793
16
          { "Answer ID", "dvb-ci.mmi.ans_id",
5794
16
            FT_UINT8, BASE_HEX, VALS(dvbci_ans_id) , 0, NULL, HFILL }
5795
16
        },
5796
16
        { &hf_dvbci_ans,
5797
16
          { "Answer", "dvb-ci.mmi.ans",
5798
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
5799
16
        },
5800
16
        { &hf_dvbci_choice_nb,
5801
16
          { "Number of menu items", "dvb-ci.mmi.choice_nb",
5802
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5803
16
        },
5804
16
        { &hf_dvbci_choice_ref,
5805
16
          { "Selected item", "dvb-ci.mmi.choice_ref",
5806
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5807
16
        },
5808
16
        { &hf_dvbci_item_nb,
5809
16
          { "Number of list items", "dvb-ci.mmi.item_nb",
5810
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5811
16
        },
5812
16
        { &hf_dvbci_title,
5813
16
          { "Title", "dvb-ci.mmi.title",
5814
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
5815
16
        },
5816
16
        { &hf_dvbci_subtitle,
5817
16
          { "Sub-title", "dvb-ci.mmi.subtitle",
5818
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
5819
16
        },
5820
16
        { &hf_dvbci_bottom,
5821
16
          { "Bottom line", "dvb-ci.mmi.bottom",
5822
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
5823
16
        },
5824
16
        { &hf_dvbci_item,
5825
16
          { "Item", "dvb-ci.mmi.item",
5826
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
5827
16
        },
5828
16
        { &hf_dvbci_host_country,
5829
16
          { "Host country", "dvb-ci.hlc.country",
5830
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
5831
16
        },
5832
16
        { &hf_dvbci_host_language,
5833
16
          { "Host language", "dvb-ci.hlc.language",
5834
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
5835
16
        },
5836
16
        { &hf_dvbci_cup_type,
5837
16
          { "CAM upgrade type", "dvb-ci.cup.type",
5838
16
            FT_UINT8, BASE_HEX, VALS(dvbci_cup_type), 0, NULL, HFILL }
5839
16
        },
5840
16
        { &hf_dvbci_cup_download_time,
5841
16
          { "Download time", "dvb-ci.cup.download_time",
5842
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5843
16
        },
5844
16
        { &hf_dvbci_cup_answer,
5845
16
          { "CAM upgrade answer", "dvb-ci.cup.answer",
5846
16
            FT_UINT8, BASE_HEX, VALS(dvbci_cup_answer), 0, NULL, HFILL }
5847
16
        },
5848
16
        { &hf_dvbci_cup_progress,
5849
16
          { "CAM upgrade progress", "dvb-ci.cup.progress",
5850
16
            FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5851
16
        },
5852
16
        { &hf_dvbci_cup_reset,
5853
16
          { "requested CAM reset", "dvb-ci.cup.reset",
5854
16
            FT_UINT8, BASE_HEX, VALS(dvbci_cup_reset), 0, NULL, HFILL }
5855
16
        },
5856
16
        { &hf_dvbci_cc_sys_id_bitmask,
5857
16
          { "CC system id bitmask", "dvb-ci.cc.sys_id_bitmask",
5858
16
            FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5859
16
        },
5860
16
        { &hf_dvbci_cc_snd_dat_nbr,
5861
16
          { "Number of sent data items", "dvb-ci.cc.snd_dat_nbr",
5862
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5863
16
        },
5864
16
        { &hf_dvbci_cc_req_dat_nbr,
5865
16
          { "Number of requested data items", "dvb-ci.cc.req_dat_nbr",
5866
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5867
16
        },
5868
16
        { &hf_dvbci_cc_dat_id,
5869
16
          { "CC datatype id", "dvb-ci.cc.datatype_id",
5870
16
            FT_UINT8, BASE_HEX, VALS(dvbci_cc_dat_id), 0, NULL, HFILL }
5871
16
        },
5872
16
        { &hf_dvbci_cc_dat_len,
5873
16
          { "Length", "dvb-ci.cc.datatype_length",
5874
16
            FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
5875
16
        },
5876
16
        { &hf_dvbci_brand_cert,
5877
16
          { "Brand certificate", "dvb-ci.cc.brand_cert",
5878
16
            FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
5879
16
        },
5880
16
        { &hf_dvbci_dev_cert,
5881
16
          { "Device certificate", "dvb-ci.cc.dev_cert",
5882
16
            FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
5883
16
        },
5884
16
        { &hf_dvbci_uri_ver,
5885
16
          { "URI version", "dvb-ci.cc.uri.version",
5886
16
            FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5887
16
        },
5888
16
        { &hf_dvbci_uri_aps,
5889
16
          { "APS", "dvb-ci.cc.uri.aps",
5890
16
            FT_UINT8, BASE_HEX, NULL, 0xC0, NULL, HFILL }
5891
16
        },
5892
16
        { &hf_dvbci_uri_emi,
5893
16
          { "EMI", "dvb-ci.cc.uri.emi",
5894
16
            FT_UINT8, BASE_HEX, VALS(dvbci_cc_uri_emi), 0x30, NULL, HFILL }
5895
16
        },
5896
16
        { &hf_dvbci_uri_ict,
5897
16
          { "Image constraint token", "dvb-ci.cc.uri.ict",
5898
16
            FT_UINT8, BASE_HEX, NULL, 0x08, NULL, HFILL }
5899
16
        },
5900
16
        { &hf_dvbci_uri_rct,
5901
16
          { "Redistribution control trigger (RCT)", "dvb-ci.cc.uri.rct",
5902
16
            FT_UINT8, BASE_HEX, NULL, 0x04, NULL, HFILL }
5903
16
        },
5904
16
        { &hf_dvbci_uri_dot,
5905
16
          { "Digital only token (DOT)", "dvb-ci.cc.uri.dot",
5906
16
            FT_UINT8, BASE_HEX, NULL, 0x01, NULL, HFILL }
5907
16
        },
5908
        /* retention limit is 6bit in URIv1 and 8bit in URIv2 and later
5909
           the position depends on the version, we can't define a mask here */
5910
16
        { &hf_dvbci_uri_rl,
5911
16
          { "Retention limit", "dvb-ci.cc.uri.rl",
5912
16
            FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5913
16
        },
5914
16
        { &hf_dvbci_cc_key_register,
5915
16
          { "Key register", "dvb-ci.cc.key_register",
5916
16
            FT_UINT8, BASE_HEX, VALS(dvbci_cc_key_register), 0, NULL, HFILL }
5917
16
        },
5918
16
        { &hf_dvbci_cc_status_field,
5919
16
          { "Status field", "dvb-ci.cc.status_field",
5920
16
            FT_UINT8, BASE_HEX, VALS(dvbci_cc_status), 0, NULL, HFILL }
5921
16
        },
5922
16
        { &hf_dvbci_cc_op_mode,
5923
16
          { "Operating mode", "dvb-ci.cc.op_mode",
5924
16
            FT_UINT8, BASE_HEX, VALS(dvbci_cc_op_mode), 0, NULL, HFILL }
5925
16
        },
5926
16
        { &hf_dvbci_cc_data,
5927
16
          { "Data", "dvb-ci.cc.data",
5928
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5929
16
        },
5930
16
        { &hf_dvbci_sac_msg_ctr,
5931
16
          { "Message counter", "dvb-ci.cc.sac.msg_ctr",
5932
16
            FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
5933
16
        },
5934
16
        { &hf_dvbci_sac_proto_ver,
5935
16
          { "Protocol version", "dvb-ci.cc.sac.proto_ver",
5936
16
            FT_UINT8, BASE_HEX, NULL, 0xF0, NULL, HFILL }
5937
16
        },
5938
16
        { &hf_dvbci_sac_auth_cip,
5939
16
          { "Authentication cipher", "dvb-ci.cc.sac.auth_cip",
5940
16
            FT_UINT8, BASE_HEX, VALS(dvbci_cc_sac_auth), 0x0E, NULL, HFILL }
5941
16
        },
5942
16
        { &hf_dvbci_sac_payload_enc,
5943
16
          { "Payload encryption flag", "dvb-ci.cc.sac.payload_enc",
5944
16
            FT_UINT8, BASE_HEX, NULL, 0x01, NULL, HFILL }
5945
16
        },
5946
16
        { &hf_dvbci_sac_enc_cip,
5947
16
          { "Encryption cipher", "dvb-ci.cc.sac.enc_cip",
5948
16
            FT_UINT8, BASE_HEX, VALS(dvbci_cc_sac_enc), 0xE0, NULL, HFILL }
5949
16
        },
5950
16
        { &hf_dvbci_sac_payload_len,
5951
16
          { "Payload length", "dvb-ci.cc.sac.payload_len",
5952
16
            FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
5953
16
        },
5954
16
        { &hf_dvbci_sac_enc_body,
5955
16
          { "Encrypted SAC body", "dvb-ci.cc.sac.enc_body",
5956
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5957
16
        },
5958
16
        { &hf_dvbci_sac_padding,
5959
16
          { "Padding", "dvb-ci.cc.sac.padding",
5960
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5961
16
        },
5962
16
        { &hf_dvbci_sac_signature,
5963
16
          { "Signature", "dvb-ci.cc.sac.signature",
5964
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5965
16
        },
5966
16
        { &hf_dvbci_rating,
5967
16
          { "Rating", "dvb-ci.cc.rating",
5968
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5969
16
        },
5970
16
        { &hf_dvbci_capability_field,
5971
16
          { "Capability field", "dvb-ci.cc.capability_field",
5972
16
            FT_UINT8, BASE_HEX, VALS(dvbci_cc_cap), 0, NULL, HFILL }
5973
16
        },
5974
16
        { &hf_dvbci_pin_chg_time,
5975
16
          { "PIN change time (UTC)", "dvb-ci.cc.pin_change_time",
5976
16
            FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0, NULL, HFILL }
5977
16
        },
5978
16
        { &hf_dvbci_pincode_status,
5979
16
          { "Pincode status field", "dvb-ci.cc.pincode_status_field",
5980
16
            FT_UINT8, BASE_HEX, VALS(dvbci_pincode_status), 0, NULL, HFILL }
5981
16
        },
5982
16
        { &hf_dvbci_cc_prog_num,
5983
16
          { "Program number", "dvb-ci.cc.program_number",
5984
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5985
16
        },
5986
16
        { &hf_dvbci_pin_evt_time,
5987
16
          { "PIN event time (UTC)", "dvb-ci.cc.pin_event_time",
5988
16
            FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0, NULL, HFILL }
5989
16
        },
5990
16
        { &hf_dvbci_pin_evt_cent,
5991
16
          { "PIN event time centiseconds", "dvb-ci.cc.pin_event_time_centi",
5992
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5993
16
        },
5994
16
        { &hf_dvbci_cc_priv_data,
5995
16
          { "Private data", "dvb-ci.cc.private_data",
5996
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5997
16
        },
5998
16
        { &hf_dvbci_pincode,
5999
16
          { "PIN code", "dvb-ci.cc.pincode",
6000
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
6001
16
        },
6002
16
        { &hf_dvbci_app_dom_id_len,
6003
16
          { "Application Domain Identifier length", "dvb-ci.ami.app_dom_id_len",
6004
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6005
16
        },
6006
16
        { &hf_dvbci_init_obj_len,
6007
16
          { "Initial Object length", "dvb-ci.ami.init_obj_len",
6008
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6009
16
        },
6010
16
        { &hf_dvbci_app_dom_id,
6011
16
          { "Application Domain Identifier", "dvb-ci.ami.app_dom_id",
6012
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
6013
16
        },
6014
16
        { &hf_dvbci_init_obj,
6015
16
          { "Initial Object", "dvb-ci.ami.init_obj",
6016
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
6017
16
        },
6018
16
        { &hf_dvbci_ack_code,
6019
16
          { "Acknowledgement", "dvb-ci.ami.ack_code",
6020
16
            FT_UINT8, BASE_HEX, VALS(dvbci_ack_code), 0, NULL, HFILL }
6021
16
        },
6022
16
        { &hf_dvbci_req_type,
6023
16
          { "Request type", "dvb-ci.ami.req_type",
6024
16
            FT_UINT8, BASE_HEX, VALS(dvbci_req_type), 0, NULL, HFILL }
6025
16
        },
6026
16
        { &hf_dvbci_file_hash,
6027
16
          { "File hash", "dvb-ci.ami.file_hash",
6028
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
6029
16
        },
6030
16
        { &hf_dvbci_file_name_len,
6031
16
          { "File name length", "dvb-ci.ami.file_name_len",
6032
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6033
16
        },
6034
16
        { &hf_dvbci_file_name,
6035
16
          { "File name", "dvb-ci.ami.file_name",
6036
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
6037
16
        },
6038
16
        { &hf_dvbci_file_data_len,
6039
16
          { "File data length", "dvb-ci.ami.file_data_len",
6040
16
            FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
6041
16
        },
6042
16
        { &hf_dvbci_ami_priv_data,
6043
16
          { "Private data", "dvb-ci.ami.private_data",
6044
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
6045
16
        },
6046
16
        { &hf_dvbci_req_ok,
6047
16
          { "RequestOK", "dvb-ci.ami.request_ok",
6048
16
            FT_UINT8, BASE_HEX, NULL, 0x02, NULL, HFILL }
6049
16
        },
6050
16
        { &hf_dvbci_file_ok,
6051
16
          { "FileOK", "dvb-ci.ami.file_ok",
6052
16
            FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }
6053
16
        },
6054
16
        { &hf_dvbci_abort_req_code,
6055
16
          { "Abort request code", "dvb-ci.ami.abort_req_code",
6056
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
6057
16
        },
6058
16
        { &hf_dvbci_abort_ack_code,
6059
16
          { "Abort acknowledgement code", "dvb-ci.ami.abort_ack_code",
6060
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
6061
16
        },
6062
16
        { &hf_dvbci_phase_id,
6063
16
          { "Phase ID", "dvb-ci.lsc.comms_phase_id",
6064
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6065
16
        },
6066
16
        { &hf_dvbci_comms_rep_id,
6067
16
          { "Comms reply ID", "dvb-ci.lsc.comms_reply_id",
6068
16
            FT_UINT8, BASE_HEX, VALS(dvbci_comms_rep_id), 0, NULL, HFILL }
6069
16
        },
6070
16
        { &hf_dvbci_lsc_buf_size,
6071
16
          { "Buffer size", "dvb-ci.lsc.buf_size",
6072
16
            FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
6073
16
        },
6074
16
        { &hf_dvbci_lsc_ret_val,
6075
16
          { "Return value", "dvb-ci.lsc.return_value",
6076
16
            FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
6077
16
        },
6078
16
        { &hf_dvbci_comms_cmd_id,
6079
16
          { "Comms command ID", "dvb-ci.lsc.comms_cmd_id",
6080
16
            FT_UINT8, BASE_HEX, VALS(dvbci_comms_cmd_id), 0, NULL, HFILL }
6081
16
        },
6082
16
        { &hf_dvbci_conn_desc_type,
6083
16
          { "Type", "dvb-ci.lsc.conn_desc_type",
6084
16
            FT_UINT8, BASE_HEX, VALS(dvbci_conn_desc_type), 0, NULL, HFILL }
6085
16
        },
6086
16
        { &hf_dvbci_lsc_media_tag,
6087
16
          { "Tag", "dvb-ci.lsc.media_tag",
6088
16
            FT_UINT8, BASE_HEX, VALS(dvbci_lsc_desc_tag), 0, NULL, HFILL }
6089
16
        },
6090
16
        { &hf_dvbci_lsc_media_len,
6091
16
          { "Length", "dvb-ci.lsc.media_len",
6092
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6093
16
        },
6094
16
        { &hf_dvbci_lsc_media_data,
6095
16
          { "Media-specific data", "dvb-ci.lsc.media_data",
6096
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL}
6097
16
        },
6098
16
        { &hf_dvbci_lsc_ip_ver,
6099
16
          { "IP version", "dvb-ci.lsc.ip_version",
6100
16
            FT_UINT8, BASE_DEC, VALS(dvbci_lsc_ip_ver), 0, NULL, HFILL }
6101
16
        },
6102
16
        { &hf_dvbci_lsc_ipv4_addr,
6103
16
          { "IP address", "dvb-ci.lsc.ipv4_addr",
6104
16
            FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL }
6105
16
        },
6106
16
        { &hf_dvbci_lsc_ipv6_addr,
6107
16
          { "IPv6 address", "dvb-ci.lsc.ipv6_addr",
6108
16
            FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL }
6109
16
        },
6110
16
        { &hf_dvbci_lsc_dst_port,
6111
16
          { "Destination port", "dvb-ci.lsc.dst_port",
6112
16
            FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
6113
16
        },
6114
16
        { &hf_dvbci_lsc_proto,
6115
16
          { "Protocol", "dvb-ci.lsc.protocol",
6116
16
            FT_UINT8, BASE_HEX, VALS(dvbci_lsc_proto), 0, NULL, HFILL }
6117
16
        },
6118
16
        { &hf_dvbci_lsc_hostname,
6119
16
          { "Hostname", "dvb-ci.lsc.hostname",
6120
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
6121
16
        },
6122
16
        { &hf_dvbci_lsc_retry_count,
6123
16
          { "Retry count", "dvb-ci.lsc.retry_count",
6124
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6125
16
        },
6126
16
        { &hf_dvbci_lsc_timeout,
6127
16
          { "Timeout", "dvb-ci.lsc.timeout",
6128
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6129
16
        },
6130
16
        { &hf_dvbci_lsc_conn_state,
6131
16
          { "Connection state", "dvb-ci.lsc.connection_state",
6132
16
            FT_UINT8, BASE_HEX, VALS(dvbci_lsc_connect), 0xC0, NULL, HFILL }
6133
16
        },
6134
16
        { &hf_dvbci_lsc_phys_addr,
6135
16
          { "Physical address", "dvb-ci.lsc.physical_address",
6136
16
            FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }
6137
16
        },
6138
16
        { &hf_dvbci_lsc_netmask,
6139
16
          { "Network mask", "dvb-ci.lsc.netmask",
6140
16
            FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL }
6141
16
        },
6142
16
        { &hf_dvbci_lsc_gateway,
6143
16
          { "Default gateway", "dvb-ci.lsc.gateway",
6144
16
            FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL }
6145
16
        },
6146
16
        { &hf_dvbci_lsc_dhcp_srv,
6147
16
          { "DHCP server", "dvb-ci.lsc.dhcp_server",
6148
16
            FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL }
6149
16
        },
6150
16
        { &hf_dvbci_lsc_num_dns_srv,
6151
16
          { "Number of DNS servers", "dvb-ci.lsc.num_dns_srv",
6152
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6153
16
        },
6154
16
        { &hf_dvbci_lsc_dns_srv,
6155
16
          { "DNS server", "dvb-ci.lsc.dns_server",
6156
16
            FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL }
6157
16
        },
6158
16
        { &hf_dvbci_afs_dom_id,
6159
16
          { "Domain identifier", "dvb-ci.afs.domain_identifier",
6160
16
            FT_UINT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
6161
16
        },
6162
16
        { &hf_dvbci_afs_ack_code,
6163
16
          { "Ack code", "dvb-ci.afs.ack_code",
6164
16
            FT_UINT8, BASE_HEX, VALS(dvbci_afs_ack_code), 0, NULL, HFILL }
6165
16
        },
6166
        /* filter string for hf_dvbci_info_ver_op_status and
6167
         * hf_dvbci_info_ver_op_info below is the same, it seems this is ok */
6168
16
        { &hf_dvbci_info_ver_op_status,
6169
16
          { "Info version", "dvb-ci.opp.info_ver",
6170
16
            FT_UINT8, BASE_HEX, NULL, 0xE0, NULL, HFILL }
6171
16
        },
6172
16
        { &hf_dvbci_nit_ver,
6173
16
          { "NIT version", "dvb-ci.opp.nit_ver",
6174
16
            FT_UINT8, BASE_HEX, NULL, 0x1F, NULL, HFILL }
6175
16
        },
6176
16
        { &hf_dvbci_pro_typ,
6177
16
          { "Profile type", "dvb-ci.opp.profile_type",
6178
16
            FT_UINT8, BASE_HEX, NULL, 0xC0, NULL, HFILL }
6179
16
        },
6180
16
        { &hf_dvbci_init_flag,
6181
16
          { "Initialized flag", "dvb-ci.opp.init_flag",
6182
16
            FT_UINT8, BASE_HEX, NULL, 0x20, NULL, HFILL }
6183
16
        },
6184
16
        { &hf_dvbci_ent_chg_flag,
6185
16
          { "Entitlement change flag", "dvb-ci.opp.ent_chg_flag",
6186
16
            FT_UINT8, BASE_HEX, NULL, 0x10, NULL, HFILL }
6187
16
        },
6188
16
        { &hf_dvbci_ent_val_flag,
6189
16
          { "Entitlement valid flag", "dvb-ci.opp.ent_val_flag",
6190
16
            FT_UINT8, BASE_HEX, NULL, 0x08, NULL, HFILL }
6191
16
        },
6192
16
        { &hf_dvbci_ref_req_flag,
6193
16
          { "Refresh request flag", "dvb-ci.opp.refresh_req_flag",
6194
16
            FT_UINT8, BASE_HEX, VALS(dvbci_opp_ref_req_flag), 0x03, NULL, HFILL }
6195
16
        },
6196
16
        { &hf_dvbci_err_flag,
6197
16
          { "Error flag", "dvb-ci.opp.err_flag",
6198
16
            FT_UINT8, BASE_HEX, VALS(dvbci_opp_err_flag), 0xF0, NULL, HFILL }
6199
16
        },
6200
16
        { &hf_dvbci_dlv_sys_hint,
6201
16
          { "Delivery system hint", "dvb-ci.opp.dlv_sys_hint",
6202
16
            FT_UINT8, BASE_HEX, NULL, 0x0F, NULL, HFILL }
6203
16
        },
6204
16
        { &hf_dvbci_dlv_sys_hint_t,
6205
16
          { "terrestrial network (DVB-T/T2)", "dvb-ci.opp.dlv_sys_hint.t",
6206
16
             FT_BOOLEAN, 4, TFS(&tfs_set_notset), 0x4, NULL, HFILL }
6207
16
        },
6208
16
        { &hf_dvbci_dlv_sys_hint_s,
6209
16
          { "satellite network (DVB-S/S2)", "dvb-ci.opp.dlv_sys_hint.s",
6210
16
             FT_BOOLEAN, 4, TFS(&tfs_set_notset), 0x2, NULL, HFILL }
6211
16
        },
6212
16
        { &hf_dvbci_dlv_sys_hint_c,
6213
16
          { "cable network (DVB-C/C2)", "dvb-ci.opp.dlv_sys_hint.c",
6214
16
             FT_BOOLEAN, 4, TFS(&tfs_set_notset), 0x1, NULL, HFILL }
6215
16
        },
6216
16
        { &hf_dvbci_refr_req_date,
6217
16
          { "Refresh request date", "dvb-ci.opp.refresh_req_date",
6218
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
6219
16
        },
6220
16
        { &hf_dvbci_refr_req_time,
6221
16
          { "Refresh request time", "dvb-ci.opp.refresh_req_time",
6222
16
            FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
6223
16
        },
6224
16
        { &hf_dvbci_nit_loop_len,
6225
16
          { "NIT loop length", "dvb-ci.opp.nit_loop_len",
6226
16
            FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
6227
16
        },
6228
16
        { &hf_dvbci_info_valid,
6229
16
          { "Info valid", "dvb-ci.opp.info_valid",
6230
16
            FT_UINT8, BASE_HEX, NULL, 0x08, NULL, HFILL }
6231
16
        },
6232
16
        { &hf_dvbci_info_ver_op_info,
6233
16
          { "Info version", "dvb-ci.opp.info_ver",
6234
16
            FT_UINT8, BASE_HEX, NULL, 0x07, NULL, HFILL }
6235
16
        },
6236
16
        { &hf_dvbci_cicam_onid,
6237
16
          { "CICAM original network id", "dvb-ci.opp.cicam_onid",
6238
16
            FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
6239
16
        },
6240
16
        { &hf_dvbci_cicam_id,
6241
16
          { "CICAM ID", "dvb-ci.opp.cicam_id",
6242
16
            FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
6243
16
        },
6244
16
        { &hf_dvbci_opp_char_tbl,
6245
16
          { "Character table", "dvb-ci.opp.char_tbl",
6246
16
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL}
6247
16
        },
6248
16
        { &hf_dvbci_sdt_rst_trusted,
6249
16
          { "SDT running status trusted", "dvb-ci.opp.sdt_rst_trusted",
6250
16
            FT_UINT8, BASE_HEX, NULL, 0x80, NULL, HFILL }
6251
16
        },
6252
16
        { &hf_dvbci_eit_rst_trusted,
6253
16
          { "EIT running status trusted", "dvb-ci.opp.eit_rst_trusted",
6254
16
            FT_UINT8, BASE_HEX, NULL, 0x40, NULL, HFILL }
6255
16
        },
6256
16
        { &hf_dvbci_eit_pf_usage,
6257
16
          { "EIT present/following usage", "dvb-ci.opp.eit_pf_usage",
6258
16
            FT_UINT8, BASE_HEX, VALS(dvbci_opp_eit_pf_usage), 0x30, NULL, HFILL }
6259
16
        },
6260
16
        { &hf_dvbci_eit_sch_usage,
6261
16
          { "EIT schedule usage", "dvb-ci.opp.eit_sch_usage",
6262
16
            FT_UINT8, BASE_HEX, VALS(dvbci_opp_eit_sch_usage), 0x0E, NULL, HFILL }
6263
16
        },
6264
16
        { &hf_dvbci_ext_evt_usage,
6265
16
          { "Extended event usage", "dvb-ci.opp.ext_evt_usage",
6266
16
            FT_UINT8, BASE_HEX, VALS(dvbci_opp_ext_evt), 0x01, NULL, HFILL }
6267
16
        },
6268
16
        { &hf_dvbci_sdt_oth_trusted,
6269
16
          { "SDT_other trusted", "dvb-ci.opp.sdt_oth_trusted",
6270
16
            FT_UINT8, BASE_HEX, NULL, 0x80, NULL, HFILL }
6271
16
        },
6272
16
        { &hf_dvbci_eit_evt_trigger,
6273
16
          { "EIT event trigger", "dvb-ci.opp.eit_evt_trigger",
6274
16
            FT_UINT8, BASE_HEX, NULL, 0x40, NULL, HFILL }
6275
16
        },
6276
16
        { &hf_dvbci_opp_lang_code,
6277
16
          { "Language code", "dvb-ci.opp.lang_code",
6278
16
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
6279
16
        },
6280
16
        { &hf_dvbci_prof_name,
6281
16
          { "Profile name", "dvb-ci.opp.profile_name",
6282
16
            FT_UINT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
6283
16
        },
6284
16
        { &hf_dvbci_unattended,
6285
16
          { "Unattended flag", "dvb-ci.opp.unattended_flag",
6286
16
            FT_UINT8, BASE_HEX, NULL, 0x80, NULL, HFILL }
6287
16
        },
6288
16
        { &hf_dvbci_opp_svc_type_loop_len,
6289
16
          { "Service type loop length", "dvb-ci.opp.svc_type_loop_len",
6290
16
            FT_UINT8, BASE_DEC, NULL, 0x7F, NULL, HFILL }
6291
16
        },
6292
16
        { &hf_dvbci_opp_svc_type,
6293
16
          { "Service type", "dvb-ci.opp.service_type", FT_UINT8,
6294
16
              BASE_HEX|BASE_EXT_STRING, &mpeg_descr_service_type_vals_ext,
6295
16
              0, NULL, HFILL }
6296
16
        },
6297
16
        { &hf_dvbci_dlv_cap_loop_len,
6298
16
          { "Delivery capability loop length", "dvb-ci.opp.dlv_cap_loop_len",
6299
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6300
16
        },
6301
16
        { &hf_dvbci_dlv_cap_byte,
6302
16
          { "Delivery capability byte", "dvb-ci.opp.dlv_cap_byte",
6303
16
            FT_UINT8, BASE_HEX, VALS(dvbci_opp_dlv_cap), 0, NULL, HFILL }
6304
16
        },
6305
16
        { &hf_dvbci_app_cap_loop_len,
6306
16
          { "Application capability loop length", "dvb-ci.opp.app_cap_loop_len",
6307
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6308
16
        },
6309
        /* the CI+ spec is not particularly clear about this but an
6310
         * application id in the capability loop must always be 2 bytes */
6311
16
        { &hf_dvbci_app_cap_bytes,
6312
16
          { "Application capability bytes", "dvb-ci.opp.app_cap_bytes",
6313
16
            FT_UINT16, BASE_HEX|BASE_EXT_STRING,
6314
16
            &mpeg_descr_data_bcast_id_vals_ext, 0, NULL, HFILL }
6315
16
        },
6316
16
        { &hf_dvbci_desc_num,
6317
16
          { "Next unprocessed descriptor number", "dvb-ci.opp.desc_num",
6318
16
            FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
6319
16
        },
6320
16
        { &hf_dvbci_sig_strength,
6321
16
          { "Signal strength", "dvb-ci.opp.sig_strength",
6322
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6323
16
        },
6324
16
        { &hf_dvbci_sig_qual,
6325
16
          { "Signal quality", "dvb-ci.opp.sig_qual",
6326
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6327
16
        },
6328
16
        { &hf_dvbci_opp_tune_status,
6329
16
          { "Tuning status", "dvb-ci.opp.tune_status",
6330
16
            FT_UINT8, BASE_HEX, VALS(dvbci_opp_tune_stat), 0xF0, NULL, HFILL }
6331
16
        },
6332
16
        { &hf_dvbci_opp_desc_loop_len,
6333
16
          { "Descriptor loop length", "dvb-ci.opp.desc_loop_len",
6334
16
            FT_UINT16, BASE_DEC, NULL, 0x0FFF, NULL, HFILL }
6335
16
        },
6336
16
        { &hf_dvbci_sas_app_id,
6337
16
          { "Application ID", "dvb-ci.sas.app_id",
6338
16
            FT_UINT64, BASE_HEX, NULL, 0, NULL, HFILL }
6339
16
        },
6340
16
        { &hf_dvbci_sas_sess_state,
6341
16
          { "Connection state", "dvb-ci.sas.sess_state",
6342
16
            FT_UINT8, BASE_DEC, VALS(dvbci_sas_sess_state), 0, NULL, HFILL }
6343
16
        },
6344
16
        { &hf_dvbci_sas_msg_nb,
6345
16
          { "Message number", "dvb-ci.sas.msg_nb",
6346
16
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6347
16
        },
6348
16
        { &hf_dvbci_sas_msg_len,
6349
16
          { "Message length", "dvb-ci.sas.msg_len",
6350
16
            FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
6351
16
        }
6352
16
    };
6353
6354
16
    static ei_register_info ei[] = {
6355
16
        { &ei_dvbci_cor_addr,
6356
16
            { "dvb-ci.cor_address.invalid", PI_PROTOCOL, PI_WARN,
6357
16
                "COR address must not be greater than 0xFFE (DVB-CI spec, A.5.6)",
6358
16
                EXPFILL }},
6359
16
        { &ei_dvbci_buf_size,
6360
16
            { "dvb-ci.buf_size.invalid", PI_PROTOCOL, PI_WARN,
6361
16
                "Illegal buffer size command", EXPFILL }},
6362
16
        { &ei_dvbci_ml,
6363
16
            { "dvb-ci.more_last.invalid", PI_PROTOCOL, PI_WARN,
6364
16
                "Invalid More/Last indicator, second byte of an LPDU must be 0x80 or 0x00", EXPFILL }},
6365
16
        { &ei_dvbci_c_tpdu_tag,
6366
16
            { "dvb-ci.c_tpdu_tag.invalid", PI_MALFORMED, PI_ERROR,
6367
16
                "Invalid Command-TPDU tag, see DVB-CI specification, table A.16 for valid values", EXPFILL }},
6368
16
        { &ei_dvbci_r_tpdu_status_mandatory,
6369
16
            { "dvb-ci.r_tpdu_status.mandatory", PI_MALFORMED, PI_ERROR,
6370
16
                "Response TPDU's status part is missing, RTPDU status is mandatory", EXPFILL }},
6371
16
        { &ei_dvbci_r_tpdu_tag,
6372
16
            { "dvb-ci.r_tpdu_tag.invalid", PI_MALFORMED, PI_ERROR,
6373
16
                "Invalid Response-TPDU tag, see DVB-CI specification, table A.16 for valid values", EXPFILL }},
6374
16
        { &ei_dvbci_sb_value,
6375
16
            { "dvb-ci.sb_value.invalid", PI_PROTOCOL, PI_WARN,
6376
16
                "Invalid SB_value, must be 0x00 or 0x80", EXPFILL }},
6377
16
        { &ei_dvbci_t_c_id,
6378
16
            { "dvb-ci.t_c_id.invalid", PI_PROTOCOL, PI_WARN,
6379
16
                "Transport Connection ID mismatch the transport layer link layer", EXPFILL }},
6380
16
        { &ei_dvbci_tpdu_status_tag,
6381
16
            { "dvb-ci.tpdu.status_tag.invalid", PI_MALFORMED, PI_ERROR,
6382
16
                "Invalid status tag, this must always be T_SB (0x80)", EXPFILL }},
6383
16
        { &ei_dvbci_spdu_tag,
6384
16
            { "dvb-ci.spdu.invalid_tag", PI_MALFORMED, PI_ERROR,
6385
16
                "Invalid SPDU tag, See table 14 in the DVB-CI specification",
6386
16
                EXPFILL }},
6387
16
        { &ei_dvbci_spdu_cam_to_host,
6388
16
            { "dvb-ci.spdu.cam_to_host", PI_PROTOCOL, PI_WARN,
6389
16
                "Invalid SPDU direction, this SPDU must be sent from CAM to host",
6390
16
                EXPFILL }},
6391
16
        { &ei_dvbci_spdu_host_to_cam,
6392
16
            { "dvb-ci.spdu.host_to_cam", PI_PROTOCOL, PI_WARN,
6393
16
                "Invalid SPDU direction, this SPDU must be sent from host to CAM",
6394
16
                EXPFILL }},
6395
16
        { &ei_dvbci_apdu_tag,
6396
16
            { "dvb-ci.apdu.invalid_tag", PI_MALFORMED, PI_ERROR,
6397
16
                "Invalid or unsupported APDU tag", EXPFILL }},
6398
16
        { &ei_dvbci_apu_cam_to_host,
6399
16
            { "dvb-ci.apu.cam_to_host", PI_PROTOCOL, PI_WARN,
6400
16
                "Invalid APDU direction, this APDU must be sent from CAM to host",
6401
16
                EXPFILL }},
6402
16
        { &ei_dvbci_apu_host_to_cam,
6403
16
            { "dvb-ci.apu.host_to_cam", PI_PROTOCOL, PI_WARN,
6404
16
                "Invalid APDU direction, this APDU must be sent from host to CAM",
6405
16
                EXPFILL }},
6406
16
        { &ei_dvbci_apdu_not_supported,
6407
16
            { "dvb-ci.apdu.not_supported", PI_PROTOCOL, PI_WARN,
6408
16
                "Dissection of this APDU is not supported", EXPFILL }},
6409
16
        { &ei_dvbci_res_ver,
6410
16
            { "dvb-ci.apdu.res_ver_old", PI_PROTOCOL, PI_WARN,
6411
16
                "Invalid resource version for this apdu", EXPFILL }},
6412
16
        { &ei_dvbci_res_class,
6413
16
            { "dvb-ci.apdu.res_class_invalid", PI_PROTOCOL, PI_WARN,
6414
16
                "Invalid resource class for this apdu", EXPFILL }},
6415
16
        { &ei_dvbci_bad_length,
6416
16
            { "dvb-ci.apdu.bad_length", PI_MALFORMED, PI_ERROR,
6417
16
                "Invalid length field",
6418
16
                EXPFILL }},
6419
        /* this is used for both MMI and operator profile */
6420
16
        { &ei_dvbci_invalid_char_tbl,
6421
16
            { "dvb-ci.apdu.invalid_char_tbl", PI_MALFORMED, PI_ERROR,
6422
16
                "Invalid character table", EXPFILL }},
6423
16
        { &ei_dvbci_no_ca_desc_es,
6424
16
            { "dvb-ci.ca.no_ca_desc_es", PI_PROTOCOL, PI_CHAT,
6425
16
                "No CA descriptors for this elementary stream", EXPFILL }},
6426
16
        { &ei_dvbci_no_ca_desc_prog,
6427
16
            { "dvb-ci.ca.no_ca_desc_prog", PI_PROTOCOL, PI_CHAT,
6428
16
                "No CA descriptors at program level", EXPFILL }},
6429
16
        { &ei_dvbci_ca_pmt_cmd_id,
6430
16
            { "dvb-ci.ca.ca_pmt_cmd_id.ca_pmt", PI_MALFORMED, PI_ERROR,
6431
16
                "The ca_pmt shall only contain ca descriptors (tag 0x9)",
6432
16
                EXPFILL }},
6433
16
        { &ei_dvbci_time_offs_unknown,
6434
16
            { "dvb-ci.dt.local_offset_unknown", PI_PROTOCOL, PI_CHAT,
6435
16
                "Offset between UTC and local time is unknown", EXPFILL }},
6436
16
        { &ei_dvbci_not_text_more_or_text_last,
6437
16
            { "dvb-ci.mmi.not_text_more_or_text_last", PI_MALFORMED, PI_ERROR,
6438
16
                "Items must be text_more() or text_last() objects", EXPFILL }},
6439
16
        { &ei_dvbci_network_id,
6440
16
            { "dvb-ci.hc.nid.ignored", PI_PROTOCOL, PI_NOTE,
6441
16
                "Network ID is usually ignored by hosts", EXPFILL }},
6442
16
        { &ei_dvbci_cc_pin_nvr_chg,
6443
16
            { "dvb-ci.cc.pin_never_changed", PI_PROTOCOL, PI_CHAT,
6444
16
                "CICAM PIN has never been changed", EXPFILL }},
6445
16
        { &ei_dvbci_pin_evt_cent,
6446
16
            { "dvb-ci.cc.pin_event_time_centi.invalid", PI_PROTOCOL, PI_WARN,
6447
16
                "Invalid value for event time centiseconds, Value must be between 0 and 100",
6448
16
                EXPFILL }},
6449
16
        { &ei_dvbci_sac_payload_enc,
6450
16
            { "dvb-ci.cc.sac.payload_enc.clear", PI_PROTOCOL, PI_NOTE,
6451
16
                "The original PDU was encrypted, this exported PDU is in the clear",
6452
16
                EXPFILL }},
6453
16
        { &ei_dvbci_sig_qual,
6454
16
            { "dvb-ci.opp.sig_qual.invalid", PI_PROTOCOL, PI_WARN,
6455
16
                "Invalid value for signal strength / signal quality, values are in percent (0 to 100)",
6456
16
                EXPFILL }},
6457
16
        { &ei_dvbci_cicam_nit_table_id,
6458
16
            { "dvb-ci.opp.cicam_nit_table_id_invalid", PI_PROTOCOL, PI_WARN,
6459
16
                "CICAM NIT must have table id 0x40 (NIT actual)", EXPFILL }},
6460
16
        { &ei_dvbci_cup_progress,
6461
16
            { "dvb-ci.cup.progress_invalid", PI_PROTOCOL, PI_WARN,
6462
16
                "progress is in percent, value must be between 0 and 100",
6463
16
                EXPFILL }},
6464
16
    };
6465
6466
16
    spdu_table = g_hash_table_new(g_direct_hash, g_direct_equal);
6467
128
    for(i=0; i<array_length(spdu_info); i++) {
6468
112
        g_hash_table_insert(spdu_table,
6469
112
                            GUINT_TO_POINTER((unsigned)spdu_info[i].tag),
6470
112
                            (void *)(&spdu_info[i]));
6471
112
    }
6472
6473
16
    apdu_table = g_hash_table_new(g_direct_hash, g_direct_equal);
6474
1.48k
    for(i=0; i<array_length(apdu_info); i++) {
6475
1.47k
        g_hash_table_insert(apdu_table,
6476
1.47k
                            GUINT_TO_POINTER((unsigned)apdu_info[i].tag),
6477
1.47k
                            (void *)(&apdu_info[i]));
6478
1.47k
    }
6479
6480
16
    proto_dvbci = proto_register_protocol("DVB Common Interface", "DVB-CI", "dvb-ci");
6481
16
    proto_register_field_array(proto_dvbci, hf, array_length(hf));
6482
16
    proto_register_subtree_array(ett, array_length(ett));
6483
16
    expert_dvbci = expert_register_protocol(proto_dvbci);
6484
16
    expert_register_field_array(expert_dvbci, ei, array_length(ei));
6485
6486
16
    dvbci_module = prefs_register_protocol(proto_dvbci, proto_reg_handoff_dvbci);
6487
16
    prefs_register_string_preference(dvbci_module,
6488
16
            "sek", "SAC Encryption Key", "SAC Encryption Key (16 hex bytes)",
6489
16
            &dvbci_sek);
6490
16
    prefs_register_string_preference(dvbci_module,
6491
16
            "siv", "SAC Init Vector", "SAC Init Vector (16 hex bytes)",
6492
16
            &dvbci_siv);
6493
16
    prefs_register_bool_preference(dvbci_module,
6494
16
            "dissect_lsc_msg",
6495
16
            "Dissect LSC messages",
6496
16
            "Dissect the content of messages transmitted "
6497
16
                "on the Low-Speed Communication resource. "
6498
16
                "This requires a dissector for the protocol and target port "
6499
16
                "contained in the connection descriptor.",
6500
16
            &dvbci_dissect_lsc_msg);
6501
6502
16
    sas_msg_dissector_table = register_dissector_table("dvb-ci.sas.app_id_str",
6503
16
                "SAS application id", proto_dvbci, FT_STRING, STRING_CASE_SENSITIVE);
6504
6505
16
    register_init_routine(dvbci_init);
6506
16
    reassembly_table_register(&tpdu_reassembly_table,
6507
16
                          &addresses_reassembly_table_functions);
6508
16
    reassembly_table_register(&spdu_reassembly_table,
6509
16
                          &addresses_reassembly_table_functions);
6510
6511
6512
    /* the dissector for decrypted CI+ SAC messages which we can export */
6513
16
    register_dissector_with_description(EXPORTED_SAC_MSG_PROTO,
6514
16
        EXPORTED_SAC_MSG_DESCRIPTION,
6515
16
        dissect_dvbci_exported_sac_msg, proto_dvbci);
6516
6517
16
    exported_pdu_tap = register_export_pdu_tap("DVB-CI");
6518
6519
16
    register_shutdown_routine(dvbci_shutdown);
6520
6521
16
    dvbci_handle = register_dissector("dvb-ci", dissect_dvbci, proto_dvbci);
6522
16
}
6523
6524
6525
void
6526
proto_reg_handoff_dvbci(void)
6527
16
{
6528
16
    static bool initialized = false;
6529
6530
16
    if (!initialized) {
6531
16
        dissector_add_uint("wtap_encap", WTAP_ENCAP_DVBCI, dvbci_handle);
6532
6533
16
        data_handle = find_dissector("data");
6534
16
        mpeg_pmt_handle = find_dissector_add_dependency("mpeg_pmt", proto_dvbci);
6535
16
        dvb_nit_handle = find_dissector_add_dependency("dvb_nit", proto_dvbci);
6536
16
        mime_handle = find_dissector_add_dependency("mime_dlt", proto_dvbci);
6537
16
        tcp_dissector_table = find_dissector_table("tcp.port");
6538
16
        udp_dissector_table = find_dissector_table("udp.port");
6539
16
        initialized = true;
6540
16
    }
6541
6542
16
    g_free(dvbci_sek_bin);
6543
16
    g_free(dvbci_siv_bin);
6544
16
    pref_key_string_to_bin(dvbci_sek, &dvbci_sek_bin);
6545
16
    pref_key_string_to_bin(dvbci_siv, &dvbci_siv_bin);
6546
16
}
6547
6548
/*
6549
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
6550
 *
6551
 * Local variables:
6552
 * c-basic-offset: 4
6553
 * tab-width: 8
6554
 * indent-tabs-mode: nil
6555
 * End:
6556
 *
6557
 * vi: set shiftwidth=4 tabstop=8 expandtab:
6558
 * :indentSize=4:tabSize=8:noTabs=true:
6559
 */