Coverage Report

Created: 2026-01-02 06:13

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