2 * Routines for DVB-CI (Common Interface) dissection
3 * Copyright 2011-2014, Martin Kaiser <martin@kaiser.cx>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 /* This dissector supports DVB-CI as defined in EN50221 and
25 * CI+ (www.ci-plus.com).
26 * For more details, see http://wiki.wireshark.org/DVB-CI.
28 * The pcap input format for this dissector is documented at
29 * http://www.kaiser.cx/pcap-dvbci.html.
35 #include <epan/addr_resolv.h>
36 #include <epan/circuit.h>
37 #include <epan/dvb_chartbl.h>
38 #include <epan/packet.h>
39 #include <epan/exported_pdu.h>
40 #include <epan/reassemble.h>
41 #include <epan/prefs.h>
43 #include <epan/expert.h>
44 #include <epan/asn1.h>
45 #include <epan/dissectors/packet-dvbci.h>
46 #include <epan/dissectors/packet-mpeg-descriptor.h>
47 #include <epan/dissectors/packet-mpeg-sect.h>
48 #include <epan/dissectors/packet-mpeg-pmt.h>
49 #include <epan/dissectors/packet-x509af.h>
50 #include <epan/dissectors/packet-x509ce.h>
52 #include "packet-ber.h"
55 #include <wsutil/wsgcrypt.h>
58 void proto_register_dvbci(void);
59 void proto_reg_handoff_dvbci(void);
61 #define AES_BLOCK_LEN 16
62 #define AES_KEY_LEN 16
64 #define EXPORTED_SAC_MSG_PROTO "CI+ SAC message"
66 #define IS_DATA_TRANSFER(e) (e==DVBCI_EVT_DATA_CAM_TO_HOST || e==DVBCI_EVT_DATA_HOST_TO_CAM)
68 /* direction of data transfer in [as]pdu_info_t and elsewhere */
69 #define DATA_CAM_TO_HOST DVBCI_EVT_DATA_CAM_TO_HOST
70 #define DATA_HOST_TO_CAM DVBCI_EVT_DATA_HOST_TO_CAM
71 #define DIRECTION_ANY 0x0
73 /* source/destination address field */
74 #define ADDR_HOST "Host"
75 #define ADDR_CAM "CAM"
81 #define POWER_OFF 0x04
83 #define TS_BYPASS 0x06
89 /* Card Information Structure (CIS) */
92 #define CISTPL_NO_LINK 0x14
93 #define CISTPL_VERS_1 0x15
94 #define CISTPL_CONFIG 0x1A
95 #define CISTPL_CFTABLE_ENTRY 0x1B
96 #define CISTPL_DEVICE_OC 0x1C
97 #define CISTPL_DEVICE_OA 0x1D
98 #define CISTPL_MANFID 0x20
99 #define CISTPL_END 0xFF
101 #define CCSTPL_CIF 0xC0
102 /* interface types */
103 #define TPCE_IF_TYPE_MEM 0
104 #define TPCE_IF_TYPE_IO_MEM 1
105 #define TPCE_IF_TYPE_CUST0 4
106 #define TPCE_IF_TYPE_CUST1 5
107 #define TPCE_IF_TYPE_CUST2 6
108 #define TPCE_IF_TYPE_CUST3 7
114 /* base values of sequence ids for reassembly of fragmented tpdus
115 if there's two open transport connections, their tpdu fragments may be
116 interleaved, we must add the tcid to the base value in order to
117 distinguish between different transport connections
118 TPDU_SEQ_ID_BASE and SPDU_SEQ_ID_BASE can be arbitrary 32bit values, they
119 must be more than 256 apart since we add the 8bit tcid */
120 #define TPDU_SEQ_ID_BASE 123
121 /* same as above, the spdu fragments are also demultiplexed based on the
123 #define SPDU_SEQ_ID_BASE 2417
125 /* transport layer */
129 #define T_CREATE_T_C 0x82
130 #define T_C_T_C_REPLY 0x83
131 #define T_DELETE_T_C 0x84
132 #define T_D_T_C_REPLY 0x85
133 #define T_REQUEST_T_C 0x86
134 #define T_NEW_T_C 0x87
135 #define T_T_C_ERROR 0x88
136 #define T_DATA_LAST 0xA0
137 #define T_DATA_MORE 0xA1
139 #define SB_VAL_MSG_AVAILABLE 0x80
140 #define SB_VAL_NO_MSG_AVAILABLE 0x00
143 #define T_SESSION_NUMBER 0x90
144 #define T_OPEN_SESSION_REQUEST 0x91
145 #define T_OPEN_SESSION_RESPONSE 0x92
146 #define T_CREATE_SESSION 0x93
147 #define T_CREATE_SESSION_RESPONSE 0x94
148 #define T_CLOSE_SESSION_REQUEST 0x95
149 #define T_CLOSE_SESSION_RESPONSE 0x96
151 /* status for open/create session */
152 #define SESS_OPENED 0x00
153 #define SESS_NOT_OPENED_RES_NON_EXIST 0xF0
154 #define SESS_NOT_OPENED_RES_UNAVAIL 0xF1
155 #define SESS_NOT_OPENED_RES_VER_LOWER 0xF2
156 #define SESS_NOT_OPENED_RES_BUSY 0xF3
158 /* status for close session */
159 #define SESS_CLOSED 0x00
160 #define SESS_NB_NOT_ALLOC 0xF0
162 /* circuit id from session number (16bit) and transport connection id * (8bit) */
163 #define CT_ID(s,t) ((guint32)(s<<8|t))
166 #define RES_ID_TYPE_MASK 0xC0000000
167 #define RES_CLASS_MASK 0x3FFF0000
168 #define RES_TYPE_MASK 0x0000FFC0
169 #define RES_VER_MASK 0x0000003F
172 #define RES_CLASS_RM 0x01
173 #define RES_CLASS_AP 0x02
174 #define RES_CLASS_CA 0x03
175 #define RES_CLASS_AUT 0x10
176 #define RES_CLASS_HC 0x20
177 #define RES_CLASS_DT 0x24
178 #define RES_CLASS_MMI 0x40
179 #define RES_CLASS_AMI 0x41
180 #define RES_CLASS_LSC 0x60
181 #define RES_CLASS_CC 0x8C
182 #define RES_CLASS_HLC 0x8D
183 #define RES_CLASS_CUP 0x8E
184 #define RES_CLASS_OPP 0x8F
185 #define RES_CLASS_SAS 0x96
187 #define RES_ID_LEN 4 /* bytes */
188 #define RES_CLASS(_res_id) (_res_id & RES_CLASS_MASK) >> 16
189 #define RES_VER(_res_id) (_res_id & RES_VER_MASK)
191 /* appinfo resource */
192 #define APP_TYPE_CA 0x1
193 #define APP_TYPE_EPG 0x2
195 #define DATA_RATE_72 0x0
196 #define DATA_RATE_96 0x1
199 #define LIST_MGMT_MORE 0x0
200 #define LIST_MGMT_FIRST 0x1
201 #define LIST_MGMT_LAST 0x2
202 #define LIST_MGMT_ONLY 0x3
203 #define LIST_MGMT_ADD 0x4
204 #define LIST_MGMT_UPDATE 0x5
206 #define CMD_ID_OK_DESCR 0x1
207 #define CMD_ID_OK_MMI 0x2
208 #define CMD_ID_QUERY 0x3
209 #define CMD_ID_NOT_SELECTED 0x4
211 #define CA_DESC_TAG 0x9
213 #define CA_ENAB_DESC_OK 0x01
214 #define CA_ENAB_DESC_OK_PURCHASE 0x02
215 #define CA_ENAB_DESC_OK_TECH 0x03
216 #define CA_ENAB_DESC_NG_ENTITLEMENT 0x71
217 #define CA_ENAB_DESC_NG_TECH 0x73
219 /* host control resource */
220 #define HC_STAT_OK 0x0
221 #define HC_STAT_ERR_DLVRY 0x1
222 #define HC_STAT_ERR_LOCK 0x2
223 #define HC_STAT_ERR_BUSY 0x3
224 #define HC_STAT_ERR_PARAM 0x4
225 #define HC_STAT_ERR_NOT_FOUND 0x5
226 #define HC_STAT_ERR_UNKNOWN 0x6
228 #define HC_RELEASE_OK 0x0
229 #define HC_RELEASE_REFUSED 0x1
232 #define CLOSE_MMI_CMD_ID_IMMEDIATE 0x0
233 #define CLOSE_MMI_CMD_ID_DELAY 0x1
235 /* only commands and parameters for high-level mmi are supported */
236 #define DISP_CMD_SET_MMI_MODE 1
237 #define DISP_CMD_GET_DISP_TBL 2
238 #define DISP_CMD_GET_INP_TBL 3
240 #define MMI_MODE_HIGH 1
242 #define DISP_REP_ID_MMI_MODE_ACK 0x01
243 #define DISP_REP_ID_DISP_CHAR_TBL 0x02
244 #define DISP_REP_ID_INP_CHAR_TBL 0x03
245 #define DISP_REP_ID_UNKNOWN_CMD 0xF0
246 #define DISP_REP_ID_UNKNOWN_MMI_MODE 0xF1
247 #define DISP_REP_ID_UNKNOWN_CHAR_TBL 0xF2
249 #define VISIBLE_ANS 0
252 #define ANSW_ID_CANCEL 0x00
253 #define ANSW_ID_ANSWER 0x01
255 /* used for answer_text_length, choice_nb and item_nb */
256 #define NB_UNKNOWN 0xFF
258 /* cam upgrade resource */
259 #define CUP_DELAYED 0x0
260 #define CUP_IMMEDIATE 0x1
262 #define CUP_ANS_NO 0x0
263 #define CUP_ANS_YES 0x1
264 #define CUP_ANS_ASK 0x2
266 #define CUP_RESET_PCMCIA 0x0
267 #define CUP_RESET_CMDIF 0x1
268 #define CUP_RESET_NONE 0x2
270 /* content control resource */
271 #define CC_ID_HOST_ID 0x05
272 #define CC_ID_CICAM_ID 0x06
273 #define CC_ID_HOST_BRAND_CERT 0x07
274 #define CC_ID_CICAM_BRAND_CERT 0x08
275 #define CC_ID_KP 0x0C
276 #define CC_ID_DHPH 0x0D
277 #define CC_ID_DHPM 0x0E
278 #define CC_ID_HOST_DEV_CERT 0x0F
279 #define CC_ID_CICAM_DEV_CERT 0x10
280 #define CC_ID_SIG_A 0x11
281 #define CC_ID_SIG_B 0x12
282 #define CC_ID_AUTH_NONCE 0x13
283 #define CC_ID_NS_HOST 0x14
284 #define CC_ID_NS_MODULE 0x15
285 #define CC_ID_AKH 0x16
286 #define CC_ID_URI 0x19
287 #define CC_ID_PROG_NUM 0x1A
288 #define CC_ID_URI_CNF 0x1B
289 #define CC_ID_KEY_REGISTER 0x1C
290 #define CC_ID_URI_VERSIONS 0x1D
291 #define CC_ID_STATUS_FIELD 0x1E
292 #define CC_ID_SRM_DATA 0x1F
293 #define CC_ID_SRM_CONFIRM 0x20
294 #define CC_ID_CICAM_LICENSE 0x21
295 #define CC_ID_LICENSE_STATUS 0x22
296 #define CC_ID_LICENSE_RCV_STATUS 0x23
297 #define CC_ID_HOST_LICENSE 0x24
298 #define CC_ID_PLAY_COUNT 0x25
299 #define CC_ID_OPERATING_MODE 0x26
300 #define CC_ID_PINCODE_DATA 0x27
301 #define CC_ID_REC_START_STATUS 0x28
302 #define CC_ID_MODE_CHG_STATUS 0x29
303 #define CC_ID_REC_STOP_STATUS 0x2A
305 #define CC_EMI_FREE 0x00
306 #define CC_EMI_NO_MORE 0x01
307 #define CC_EMI_ONCE 0x02
308 #define CC_EMI_NEVER 0x03
310 #define CC_KEY_EVEN 0x0
311 #define CC_KEY_ODD 0x1
313 #define CC_STATUS_OK 0x0
314 #define CC_STATUS_NO_CC_SUPPORT 0x1
315 #define CC_STATUS_HOST_BUSY 0x2
316 #define CC_STATUS_AUTH_FAILED_OR_NO_SRM 0x3
317 #define CC_STATUS_CICAM_BUSY 0x4
318 #define CC_STATUS_REC_MODE_ERR 0x5
320 #define SAC_MSG_HDR_LEN 8
322 #define CC_SAC_AUTH_AES128_XCBC_MAC 0x0
323 #define CC_SAC_ENC_AES128_CBC 0x0
325 #define CC_CAP_NONE 0x0
326 #define CC_CAP_CAS_PIN 0x1
327 #define CC_CAP_CAS_FTA_PIN 0x2
328 #define CC_CAP_CAS_PIN_CACHED 0x3
329 #define CC_CAP_CAS_FTA_PIN_CACHED 0x4
331 /* length of DVB-SI utc time field in bytes */
332 #define UTC_TIME_LEN 5
334 #define CC_PIN_BAD 0x0
335 #define CC_PIN_CAM_BUSY 0x1
336 #define CC_PIN_OK 0x2
337 #define CC_PIN_UNCONFIRMED 0x3
338 #define CC_PIN_VB_NOT_REQ 0x4
339 #define CC_PIN_CSA 0x5
341 #define CC_OP_MODE_WATCH_BUFFER 0x0
342 #define CC_OP_MODE_TIMESHIFT 0x1
343 #define CC_OP_MODE_UNATTENDED 0x2
345 /* application mmi resource */
346 #define ACK_CODE_OK 0x1
347 #define ACK_CODE_WRONG_API 0x2
348 #define ACK_CODE_API_BUSY 0x3
350 #define REQ_TYPE_FILE 0x0
351 #define REQ_TYPE_DATA 0x1
352 #define REQ_TYPE_FILE_HASH 0x2
353 #define REQ_TYPE_REQ 0x3
356 #define COMMS_CMD_ID_CONNECT_ON_CHANNEL 1
357 #define COMMS_CMD_ID_DISCONNECT_ON_CHANNEL 2
358 #define COMMS_CMD_ID_SET_PARAMS 3
359 #define COMMS_CMD_ID_ENQUIRE_STATUS 4
360 #define COMMS_CMD_ID_GET_NEXT_BUFFER 5
362 #define CONN_DESC_TEL 1
363 #define CONN_DESC_CABLE 2
364 #define CONN_DESC_IP 3
365 #define CONN_DESC_HOSTNAME 4
367 #define LSC_DESC_IP 0xCF
368 #define LSC_DESC_HOSTNAME 0xCD
376 #define COMMS_REP_ID_CONNECT_ACK 1
377 #define COMMS_REP_ID_DISCONNECT_ACK 2
378 #define COMMS_REP_ID_SET_PARAMS_ACK 3
379 #define COMMS_REP_ID_STATUS_REPLY 4
380 #define COMMS_REP_ID_GET_NEXT_BUFFER_ACK 5
381 #define COMMS_REP_ID_SEND_ACK 6
384 #define LSC_RET_DISCONNECTED 0
385 #define LSC_RET_CONNECTED 1
386 #define LSC_RET_TOO_BIG 0xFE
388 /* operator profile resource */
389 #define TABLE_ID_CICAM_NIT 0x40 /* CICAM NIT must be a NIT actual */
391 #define OPP_REF_REG_FLG_NONE 0
392 #define OPP_REF_REG_FLG_ADV 1
393 #define OPP_REF_REG_FLG_URG 2
394 #define OPP_REF_REG_FLG_SCHED 3
396 #define OPP_ERR_FLG_OK 0
397 #define OPP_ERR_FLG_PROF 1
398 #define OPP_ERR_FLG_UNSUPPORTED 2
399 #define OPP_ERR_FLG_CANCELLED 3
401 /* EIT p/f, EIT schedule usage */
402 #define OPP_EIT_ABSENT 0
403 #define OPP_EIT_NOT_X 1
404 #define OPP_EIT_FULL_X 2
405 #define OPP_EIT_BARKER 3
406 #define OPP_EPG_APP 4
408 #define OPP_EXT_EVT_DIFF 0
409 #define OPP_EXT_EVT_ADD 1
411 /* these values match the delivery system descriptor tags */
412 #define OPP_DLV_CAP_S 0x43
413 #define OPP_DLV_CAP_C 0x44
414 #define OPP_DLV_CAP_T 0x5A
415 #define OPP_DLV_CAP_S2 0x79
417 #define OPP_TUNE_OK 0
418 #define OPP_TUNE_UNSUPPORTED 1
419 #define OPP_TUNE_INVALID 2
420 #define OPP_TUNE_ERR 3
422 #define OPP_NO_MORE_DESC 0xFF
425 #define SAS_SESS_STATE_CONNECTED 0
426 #define SAS_SESS_STATE_NOT_FOUND 1
427 #define SAS_SESS_STATE_DENIED 2
430 /* application layer */
432 #define APDU_TAG_SIZE 3
434 /* "don't care" value for min_len_field and len_field (this can't be 0) */
435 #define LEN_FIELD_ANY G_MAXUINT32
437 static GHashTable *apdu_table = NULL;
439 typedef struct _apdu_info_t {
441 /* the minimum length required for this apdu */
442 guint32 min_len_field;
443 /* if the apdu has a well-known length, we enforce it here
444 * (otherwise, we set this to LEN_FIELD_ANY) */
449 void (*dissect_payload)(guint32, gint,
450 tvbuff_t *, gint, circuit_t *, packet_info *, proto_tree *);
455 dissect_dvbci_payload_rm(guint32 tag, gint len_field,
456 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
457 packet_info *pinfo, proto_tree *tree);
459 dissect_dvbci_payload_ap(guint32 tag, gint len_field _U_,
460 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
461 packet_info *pinfo, proto_tree *tree);
463 dissect_dvbci_payload_ca(guint32 tag, gint len_field,
464 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
465 packet_info *pinfo, proto_tree *tree);
467 dissect_dvbci_payload_aut(guint32 tag, gint len_field _U_,
468 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
469 packet_info *pinfo _U_, proto_tree *tree);
471 dissect_dvbci_payload_hc(guint32 tag, gint len_field _U_,
472 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
473 packet_info *pinfo, proto_tree *tree);
475 dissect_dvbci_payload_dt(guint32 tag, gint len_field,
476 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
477 packet_info *pinfo, proto_tree *tree);
479 dissect_dvbci_payload_mmi(guint32 tag, gint len_field,
480 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
481 packet_info *pinfo, proto_tree *tree);
483 dissect_dvbci_payload_hlc(guint32 tag, gint len_field _U_,
484 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
485 packet_info *pinfo, proto_tree *tree);
487 dissect_dvbci_payload_cup(guint32 tag, gint len_field _U_,
488 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
489 packet_info *pinfo, proto_tree *tree);
491 dissect_dvbci_payload_cc(guint32 tag, gint len_field _U_,
492 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
493 packet_info *pinfo, proto_tree *tree);
495 dissect_dvbci_payload_ami(guint32 tag, gint len_field _U_,
496 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
497 packet_info *pinfo, proto_tree *tree);
499 dissect_dvbci_payload_lsc(guint32 tag, gint len_field,
500 tvbuff_t *tvb, gint offset, circuit_t *circuit,
501 packet_info *pinfo, proto_tree *tree);
503 dissect_dvbci_payload_opp(guint32 tag, gint len_field _U_,
504 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
505 packet_info *pinfo, proto_tree *tree);
507 dissect_dvbci_payload_sas(guint32 tag, gint len_field _U_,
508 tvbuff_t *tvb, gint offset, circuit_t *circuit,
509 packet_info *pinfo, proto_tree *tree);
513 #define T_PROFILE_ENQ 0x9F8010
514 #define T_PROFILE 0x9F8011
515 #define T_PROFILE_CHANGE 0x9F8012
516 #define T_APP_INFO_ENQ 0x9F8020
517 #define T_APP_INFO 0x9F8021
518 #define T_ENTER_MENU 0x9F8022
519 #define T_REQUEST_CICAM_RESET 0x9F8023
520 #define T_DATARATE_INFO 0x9F8024
521 #define T_CA_INFO_ENQ 0x9F8030
522 #define T_CA_INFO 0x9F8031
523 #define T_CA_PMT 0x9F8032
524 #define T_CA_PMT_REPLY 0x9F8033
525 #define T_AUTH_REQ 0x9F8200
526 #define T_AUTH_RESP 0x9F8201
527 #define T_TUNE 0x9F8400
528 #define T_REPLACE 0x9F8401
529 #define T_CLEAR_REPLACE 0x9F8402
530 #define T_ASK_RELEASE 0x9F8403
531 #define T_TUNE_BROADCAST_REQ 0x9F8404
532 #define T_TUNE_REPLY 0x9F8405
533 #define T_ASK_RELEASE_REPLY 0x9F8406
534 #define T_DATE_TIME_ENQ 0x9F8440
535 #define T_DATE_TIME 0x9F8441
536 #define T_CLOSE_MMI 0x9F8800
537 #define T_DISPLAY_CONTROL 0x9F8801
538 #define T_DISPLAY_REPLY 0x9F8802
539 #define T_ENQ 0x9F8807
540 #define T_ANSW 0x9F8808
541 #define T_MENU_LAST 0x9F8809
542 #define T_MENU_MORE 0x9F880A
543 #define T_MENU_ANSW 0x9F880B
544 #define T_LIST_LAST 0x9F880C
545 #define T_LIST_MORE 0x9F880D
546 #define T_HOST_COUNTRY_ENQ 0x9F8100
547 #define T_HOST_COUNTRY 0x9F8101
548 #define T_HOST_LANGUAGE_ENQ 0x9F8110
549 #define T_HOST_LANGUAGE 0x9F8111
550 #define T_CAM_FIRMWARE_UPGRADE 0x9F9D01
551 #define T_CAM_FIRMWARE_UPGRADE_REPLY 0x9F9D02
552 #define T_CAM_FIRMWARE_UPGRADE_PROGRESS 0x9F9D03
553 #define T_CAM_FIRMWARE_UPGRADE_COMPLETE 0x9F9D04
554 #define T_CC_OPEN_REQ 0x9F9001
555 #define T_CC_OPEN_CNF 0x9F9002
556 #define T_CC_DATA_REQ 0x9F9003
557 #define T_CC_DATA_CNF 0x9F9004
558 #define T_CC_SYNC_REQ 0x9F9005
559 #define T_CC_SYNC_CNF 0x9F9006
560 #define T_CC_SAC_DATA_REQ 0x9F9007
561 #define T_CC_SAC_DATA_CNF 0x9F9008
562 #define T_CC_SAC_SYNC_REQ 0x9F9009
563 #define T_CC_SAC_SYNC_CNF 0x9F9010
564 #define T_CC_PIN_CAPABILITIES_REQ 0x9F9011
565 #define T_CC_PIN_CAPABILITIES_REPLY 0x9F9012
566 #define T_CC_PIN_CMD 0x9F9013
567 #define T_CC_PIN_REPLY 0x9F9014
568 #define T_CC_PIN_EVENT 0x9F9015
569 #define T_CC_PIN_PLAYBACK 0x9F9016
570 #define T_CC_PIN_MMI_REQ 0x9F9017
571 #define T_REQUEST_START 0x9F8000
572 #define T_REQUEST_START_ACK 0x9F8001
573 #define T_FILE_REQUEST 0x9F8002
574 #define T_FILE_ACKNOWLEDGE 0x9F8003
575 #define T_APP_ABORT_REQUEST 0x9F8004
576 #define T_APP_ABORT_ACK 0x9F8005
577 #define T_COMMS_CMD 0x9F8C00
578 #define T_COMMS_REPLY 0x9F8C02
579 #define T_COMMS_SEND_LAST 0x9F8C03
580 #define T_COMMS_SEND_MORE 0x9F8C04
581 #define T_COMMS_RCV_LAST 0x9F8C05
582 #define T_COMMS_RCV_MORE 0x9F8C06
583 #define T_OPERATOR_STATUS_REQ 0x9F9C00
584 #define T_OPERATOR_STATUS 0x9F9C01
585 #define T_OPERATOR_NIT_REQ 0x9F9C02
586 #define T_OPERATOR_NIT 0x9F9C03
587 #define T_OPERATOR_INFO_REQ 0x9F9C04
588 #define T_OPERATOR_INFO 0x9F9C05
589 #define T_OPERATOR_SEARCH_START 0x9F9C06
590 #define T_OPERATOR_SEARCH_STATUS 0x9F9C07
591 #define T_OPERATOR_EXIT 0x9F9C08
592 #define T_OPERATOR_TUNE 0x9F9C09
593 #define T_OPERATOR_TUNE_STATUS 0x9F9C0A
594 #define T_OPERATOR_ENTITLEMENT_ACK 0x9F9C0B
595 #define T_OPERATOR_SEARCH_CANCEL 0x9F9C0C
596 #define T_SAS_CONNECT_RQST 0x9F9A00
597 #define T_SAS_CONNECT_CNF 0x9F9A01
598 #define T_SAS_ASYNC_MSG 0x9F9A07
600 /* these are no real apdus, they just use the same format */
601 #define T_TEXT_LAST 0x9F8803
602 #define T_TEXT_MORE 0x9F8804
603 #define T_CONNECTION_DESCRIPTOR 0x9F8C01
605 #define IS_MENU_APDU(t) (t==T_MENU_MORE || t==T_MENU_LAST)
608 static const apdu_info_t apdu_info[] = {
609 {T_PROFILE_ENQ, 0, 0, DIRECTION_ANY, RES_CLASS_RM, 1, NULL},
610 {T_PROFILE, 0, LEN_FIELD_ANY, DIRECTION_ANY, RES_CLASS_RM, 1, dissect_dvbci_payload_rm},
611 {T_PROFILE_CHANGE, 0, 0, DIRECTION_ANY, RES_CLASS_RM, 1, NULL},
613 {T_APP_INFO_ENQ, 0, 0, DATA_HOST_TO_CAM, RES_CLASS_AP, 1, NULL},
614 {T_APP_INFO, 6, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_AP, 1, dissect_dvbci_payload_ap},
615 {T_ENTER_MENU, 0, 0, DATA_HOST_TO_CAM, RES_CLASS_AP, 1, NULL},
616 {T_REQUEST_CICAM_RESET, 0, 0, DATA_CAM_TO_HOST, RES_CLASS_AP, 3, NULL},
617 {T_DATARATE_INFO, 0, 1, DATA_HOST_TO_CAM, RES_CLASS_AP, 3, dissect_dvbci_payload_ap},
619 {T_CA_INFO_ENQ, 0, 0, DATA_HOST_TO_CAM, RES_CLASS_CA, 1, NULL},
620 {T_CA_INFO, 0, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_CA, 1, dissect_dvbci_payload_ca},
621 {T_CA_PMT, 6, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_CA, 1, dissect_dvbci_payload_ca},
622 {T_CA_PMT_REPLY, 8, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_CA, 1, dissect_dvbci_payload_ca},
624 {T_AUTH_REQ, 2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_AUT, 1, dissect_dvbci_payload_aut},
625 {T_AUTH_RESP, 2, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_AUT, 1, dissect_dvbci_payload_aut},
627 {T_TUNE, 0, 8, DATA_CAM_TO_HOST, RES_CLASS_HC, 1, dissect_dvbci_payload_hc},
628 {T_REPLACE, 0, 5, DATA_CAM_TO_HOST, RES_CLASS_HC, 1, dissect_dvbci_payload_hc},
629 {T_CLEAR_REPLACE, 0, 1, DATA_CAM_TO_HOST, RES_CLASS_HC, 1, dissect_dvbci_payload_hc},
630 {T_ASK_RELEASE, 0, 0, DATA_HOST_TO_CAM, RES_CLASS_HC, 1, NULL},
631 {T_TUNE_BROADCAST_REQ, 5, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_HC, 2, dissect_dvbci_payload_hc},
632 {T_TUNE_REPLY, 1, 1, DATA_HOST_TO_CAM, RES_CLASS_HC, 2, dissect_dvbci_payload_hc},
633 {T_ASK_RELEASE_REPLY, 1, 1, DATA_CAM_TO_HOST, RES_CLASS_HC, 2, dissect_dvbci_payload_hc},
635 {T_DATE_TIME_ENQ, 0, 1, DATA_CAM_TO_HOST, RES_CLASS_DT, 1, dissect_dvbci_payload_dt},
636 {T_DATE_TIME, 5, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_DT, 1, dissect_dvbci_payload_dt},
638 {T_CLOSE_MMI, 1, LEN_FIELD_ANY, DIRECTION_ANY, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
639 {T_DISPLAY_CONTROL, 1, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
640 {T_DISPLAY_REPLY, 1, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
641 {T_ENQ, 2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
642 {T_ANSW, 1, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
643 {T_MENU_LAST, 13, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
644 {T_MENU_MORE, 13, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
645 {T_MENU_ANSW, 0, 1, DATA_HOST_TO_CAM, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
646 {T_LIST_LAST, 13, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
647 {T_LIST_MORE, 13, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_MMI, 1, dissect_dvbci_payload_mmi},
649 {T_HOST_COUNTRY_ENQ, 0, 0, DATA_CAM_TO_HOST, RES_CLASS_HLC, 1, NULL},
650 {T_HOST_COUNTRY, 0, 3, DATA_HOST_TO_CAM, RES_CLASS_HLC, 1, dissect_dvbci_payload_hlc},
651 {T_HOST_LANGUAGE_ENQ, 0, 0, DATA_CAM_TO_HOST, RES_CLASS_HLC, 1, NULL},
652 {T_HOST_LANGUAGE, 0, 3, DATA_HOST_TO_CAM, RES_CLASS_HLC, 1, dissect_dvbci_payload_hlc},
654 {T_CAM_FIRMWARE_UPGRADE, 0, 3, DATA_CAM_TO_HOST, RES_CLASS_CUP, 1, dissect_dvbci_payload_cup},
655 {T_CAM_FIRMWARE_UPGRADE_REPLY, 0, 1, DATA_HOST_TO_CAM, RES_CLASS_CUP, 1, dissect_dvbci_payload_cup},
656 {T_CAM_FIRMWARE_UPGRADE_PROGRESS, 0, 1, DATA_CAM_TO_HOST, RES_CLASS_CUP, 1, dissect_dvbci_payload_cup},
657 {T_CAM_FIRMWARE_UPGRADE_COMPLETE, 0, 1, DATA_CAM_TO_HOST, RES_CLASS_CUP, 1, dissect_dvbci_payload_cup},
659 {T_CC_OPEN_REQ, 0, 0, DATA_CAM_TO_HOST, RES_CLASS_CC, 1, NULL},
660 {T_CC_OPEN_CNF, 0, 1, DATA_HOST_TO_CAM, RES_CLASS_CC, 1, dissect_dvbci_payload_cc},
661 {T_CC_DATA_REQ, 3, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_CC, 1, dissect_dvbci_payload_cc},
662 {T_CC_DATA_CNF, 2, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_CC, 1, dissect_dvbci_payload_cc},
663 {T_CC_SYNC_REQ, 0, 0, DATA_CAM_TO_HOST, RES_CLASS_CC, 1, NULL},
664 {T_CC_SYNC_CNF, 0, 1, DATA_HOST_TO_CAM, RES_CLASS_CC, 1, dissect_dvbci_payload_cc},
665 {T_CC_SAC_DATA_REQ, 8, LEN_FIELD_ANY, DIRECTION_ANY, RES_CLASS_CC, 1, dissect_dvbci_payload_cc},
666 {T_CC_SAC_DATA_CNF, 8, LEN_FIELD_ANY, DIRECTION_ANY, RES_CLASS_CC, 1, dissect_dvbci_payload_cc},
667 {T_CC_SAC_SYNC_REQ, 8, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_CC, 1, dissect_dvbci_payload_cc},
668 {T_CC_SAC_SYNC_CNF, 8, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_CC, 1, dissect_dvbci_payload_cc},
669 {T_CC_PIN_CAPABILITIES_REQ, 0, 0, DATA_HOST_TO_CAM, RES_CLASS_CC, 2, NULL},
670 {T_CC_PIN_CAPABILITIES_REPLY, 7, 7, DATA_CAM_TO_HOST, RES_CLASS_CC, 2, dissect_dvbci_payload_cc},
671 {T_CC_PIN_CMD, 1, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_CC, 2, dissect_dvbci_payload_cc},
672 {T_CC_PIN_REPLY, 1, 1, DATA_CAM_TO_HOST, RES_CLASS_CC, 2, dissect_dvbci_payload_cc},
673 {T_CC_PIN_EVENT, 25, 25, DATA_CAM_TO_HOST, RES_CLASS_CC, 2, dissect_dvbci_payload_cc},
674 {T_CC_PIN_PLAYBACK, 16, 16, DATA_HOST_TO_CAM, RES_CLASS_CC, 2, dissect_dvbci_payload_cc},
675 {T_CC_PIN_MMI_REQ, 1, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_CC, 2, dissect_dvbci_payload_cc},
677 {T_REQUEST_START, 2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_AMI, 1, dissect_dvbci_payload_ami},
678 {T_REQUEST_START_ACK, 0, 1, DATA_HOST_TO_CAM, RES_CLASS_AMI, 1, dissect_dvbci_payload_ami},
679 {T_FILE_REQUEST, 1, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_AMI, 1, dissect_dvbci_payload_ami},
680 {T_FILE_ACKNOWLEDGE, 2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_AMI, 1, dissect_dvbci_payload_ami},
681 {T_APP_ABORT_REQUEST, 0, LEN_FIELD_ANY, DIRECTION_ANY, RES_CLASS_AMI, 1, dissect_dvbci_payload_ami},
682 {T_APP_ABORT_ACK, 0, LEN_FIELD_ANY, DIRECTION_ANY, RES_CLASS_AMI, 1, dissect_dvbci_payload_ami},
684 {T_COMMS_CMD, 1, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_LSC, 1, dissect_dvbci_payload_lsc},
685 {T_COMMS_REPLY, 0, 2, DATA_HOST_TO_CAM, RES_CLASS_LSC, 1, dissect_dvbci_payload_lsc},
686 {T_COMMS_SEND_LAST, 2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_LSC, 1, dissect_dvbci_payload_lsc},
687 {T_COMMS_SEND_MORE, 2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_LSC, 1, dissect_dvbci_payload_lsc},
688 {T_COMMS_RCV_LAST, 2, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_LSC, 1, dissect_dvbci_payload_lsc},
689 {T_COMMS_RCV_MORE, 2, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_LSC, 1, dissect_dvbci_payload_lsc},
691 {T_OPERATOR_STATUS_REQ, 0, 0, DATA_HOST_TO_CAM, RES_CLASS_OPP, 1, NULL},
692 {T_OPERATOR_STATUS, 0, 6, DATA_CAM_TO_HOST, RES_CLASS_OPP, 1, dissect_dvbci_payload_opp},
693 {T_OPERATOR_NIT_REQ, 0, 0, DATA_HOST_TO_CAM, RES_CLASS_OPP, 1, NULL},
694 {T_OPERATOR_NIT, 2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_OPP, 1, dissect_dvbci_payload_opp},
695 {T_OPERATOR_INFO_REQ, 0, 0, DATA_HOST_TO_CAM, RES_CLASS_OPP, 1, NULL},
696 {T_OPERATOR_INFO, 1, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_OPP, 1, dissect_dvbci_payload_opp},
697 {T_OPERATOR_SEARCH_START, 3, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_OPP, 1, dissect_dvbci_payload_opp},
698 {T_OPERATOR_SEARCH_STATUS, 0, 6, DATA_CAM_TO_HOST, RES_CLASS_OPP, 1, dissect_dvbci_payload_opp},
699 {T_OPERATOR_EXIT, 0, 0, DATA_HOST_TO_CAM, RES_CLASS_OPP, 1, NULL},
700 {T_OPERATOR_TUNE, 2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, RES_CLASS_OPP, 1, dissect_dvbci_payload_opp},
701 {T_OPERATOR_TUNE_STATUS, 5, LEN_FIELD_ANY, DATA_HOST_TO_CAM, RES_CLASS_OPP, 1, dissect_dvbci_payload_opp},
702 {T_OPERATOR_ENTITLEMENT_ACK, 0, 0, DATA_HOST_TO_CAM, RES_CLASS_OPP, 1, NULL},
703 {T_OPERATOR_SEARCH_CANCEL, 0, 0, DATA_HOST_TO_CAM, RES_CLASS_OPP, 1, NULL},
705 {T_SAS_CONNECT_RQST, 0, 8, DATA_HOST_TO_CAM, RES_CLASS_SAS, 1, dissect_dvbci_payload_sas},
706 {T_SAS_CONNECT_CNF, 0, 9, DATA_CAM_TO_HOST, RES_CLASS_SAS, 1, dissect_dvbci_payload_sas},
707 {T_SAS_ASYNC_MSG, 3, LEN_FIELD_ANY, DIRECTION_ANY, RES_CLASS_SAS, 1, dissect_dvbci_payload_sas}
710 static const value_string dvbci_apdu_tag[] = {
711 { T_PROFILE_ENQ, "Profile enquiry" },
712 { T_PROFILE, "Profile information" },
713 { T_PROFILE_CHANGE, "Profile change notification" },
714 { T_APP_INFO_ENQ, "Application info enquiry" },
715 { T_APP_INFO, "Application info" },
716 { T_ENTER_MENU, "Enter menu" },
717 { T_REQUEST_CICAM_RESET, "Request CICAM reset" },
718 { T_DATARATE_INFO, "Datarate info" },
719 { T_CA_INFO_ENQ, "CA info enquiry" },
720 { T_CA_INFO, "CA info" },
721 { T_CA_PMT, "CA PMT" },
722 { T_CA_PMT_REPLY, "CA PMT reply" },
723 { T_AUTH_REQ, "Authentication request" },
724 { T_AUTH_RESP, "Authentication response" },
726 { T_REPLACE, "Replace" },
727 { T_CLEAR_REPLACE, "Clear replace" },
728 { T_ASK_RELEASE, "Ask release" },
729 { T_TUNE_BROADCAST_REQ, "Tune broadcast request" },
730 { T_TUNE_REPLY, "Tune reply" },
731 { T_ASK_RELEASE_REPLY, "Ask release reply" },
732 { T_DATE_TIME_ENQ, "Date-Time enquiry" },
733 { T_DATE_TIME, "Date-Time" },
734 { T_CLOSE_MMI, "Close MMI" },
735 { T_DISPLAY_CONTROL, "Display control" },
736 { T_DISPLAY_REPLY, "Display reply" },
737 { T_TEXT_LAST, "Text last" },
738 { T_TEXT_MORE, "Text more" },
739 { T_ENQ, "Enquiry" },
740 { T_ANSW, "Answer" },
741 { T_MENU_LAST, "Menu last" },
742 { T_MENU_MORE, "Menu more" },
743 { T_MENU_ANSW, "Menu answer" },
744 { T_LIST_LAST, "List last" },
745 { T_LIST_MORE, "List more" },
746 { T_HOST_COUNTRY_ENQ, "Host country enquiry" },
747 { T_HOST_COUNTRY, "Host country" },
748 { T_HOST_LANGUAGE_ENQ, "Host language enquiry" },
749 { T_HOST_LANGUAGE, "Host language" },
750 { T_CAM_FIRMWARE_UPGRADE, "CAM firmware upgrade" },
751 { T_CAM_FIRMWARE_UPGRADE_REPLY, "CAM firmware upgrade reply" },
752 { T_CAM_FIRMWARE_UPGRADE_PROGRESS, "CAM firmware upgrade progress" },
753 { T_CAM_FIRMWARE_UPGRADE_COMPLETE, "CAM firmware upgrade complete" },
754 { T_CC_OPEN_REQ, "CC open request" },
755 { T_CC_OPEN_CNF, "CC open confirm" },
756 { T_CC_DATA_REQ, "CC data request" },
757 { T_CC_DATA_CNF, "CC data confirm" },
758 { T_CC_SYNC_REQ, "CC sync request" },
759 { T_CC_SYNC_CNF, "CC sync confirm" },
760 { T_CC_SAC_DATA_REQ, "CC SAC data request" },
761 { T_CC_SAC_DATA_CNF, "CC SAC data confirm" },
762 { T_CC_SAC_SYNC_REQ, "CC SAC sync request" },
763 { T_CC_SAC_SYNC_CNF, "CC SAC sync confirm" },
764 { T_CC_PIN_CAPABILITIES_REQ, "CC PIN capabilities request" },
765 { T_CC_PIN_CAPABILITIES_REPLY, "CC PIN capabilities reply" },
766 { T_CC_PIN_CMD, "CC PIN command" },
767 { T_CC_PIN_REPLY, "CC PIN reply" },
768 { T_CC_PIN_EVENT, "CC PIN event" },
769 { T_CC_PIN_PLAYBACK, "CC PIN playback" },
770 { T_CC_PIN_MMI_REQ, "CC PIN MMI request" },
771 { T_REQUEST_START, "Request start" },
772 { T_REQUEST_START_ACK, "Request start ack" },
773 { T_FILE_REQUEST, "File request" },
774 { T_FILE_ACKNOWLEDGE, "File acknowledge" },
775 { T_APP_ABORT_REQUEST, "App abort request" },
776 { T_APP_ABORT_ACK, "App abort ack" },
777 { T_COMMS_CMD, "Comms command" },
778 { T_COMMS_REPLY, "Comms reply" },
779 { T_CONNECTION_DESCRIPTOR, "Connection descriptor" },
780 { T_COMMS_SEND_LAST, "Comms send last" },
781 { T_COMMS_SEND_MORE, "Comms send more" },
782 { T_COMMS_RCV_LAST, "Comms receive last" },
783 { T_COMMS_RCV_MORE, "Comms receive more" },
784 { T_OPERATOR_STATUS_REQ, "Operator status request" },
785 { T_OPERATOR_STATUS, "Operator status" },
786 { T_OPERATOR_NIT_REQ, "Operator NIT request" },
787 { T_OPERATOR_NIT, "Operator NIT" },
788 { T_OPERATOR_INFO_REQ, "Operator info request" },
789 { T_OPERATOR_INFO, "Operator info" },
790 { T_OPERATOR_SEARCH_START, "Operator search start" },
791 { T_OPERATOR_SEARCH_STATUS, "Operator search status" },
792 { T_OPERATOR_EXIT, "Operator exit" },
793 { T_OPERATOR_TUNE, "Operator tune" },
794 { T_OPERATOR_TUNE_STATUS, "Operator tune status" },
795 { T_OPERATOR_ENTITLEMENT_ACK, "Operator entitlement acknowledge" },
796 { T_OPERATOR_SEARCH_CANCEL, "Operator search cancel" },
797 { T_SAS_CONNECT_RQST, "SAS connect request" },
798 { T_SAS_CONNECT_CNF, "SAS connect confirm" },
799 { T_SAS_ASYNC_MSG, "SAS async message" },
803 static int proto_dvbci = -1;
805 static const gchar *dvbci_sek = NULL;
806 static const gchar *dvbci_siv = NULL;
807 static gboolean dvbci_dissect_lsc_msg = FALSE;
809 /* the output of pref_key_string_to_bin() applied to dvbci_sek and _siv */
810 static unsigned char *dvbci_sek_bin = NULL;
811 static unsigned char *dvbci_siv_bin = NULL;
813 static dissector_handle_t data_handle;
814 static dissector_handle_t mpeg_pmt_handle;
815 static dissector_handle_t dvb_nit_handle;
816 static dissector_handle_t png_handle;
817 static dissector_table_t tcp_dissector_table;
818 static dissector_table_t udp_dissector_table;
820 static gint exported_pdu_tap = -1;
822 static gint ett_dvbci = -1;
823 static gint ett_dvbci_hdr = -1;
824 static gint ett_dvbci_cis = -1;
825 static gint ett_dvbci_cis_tpl = -1;
826 static gint ett_dvbci_cis_subtpl = -1;
827 static gint ett_dvbci_link = -1;
828 static gint ett_dvbci_link_frag = -1;
829 static gint ett_dvbci_link_frags = -1;
830 static gint ett_dvbci_transport = -1;
831 static gint ett_dvbci_transport_frag = -1;
832 static gint ett_dvbci_transport_frags = -1;
833 static gint ett_dvbci_session = -1;
834 static gint ett_dvbci_res = -1;
835 static gint ett_dvbci_application = -1;
836 static gint ett_dvbci_es = -1;
837 static gint ett_dvbci_ca_desc = -1;
838 static gint ett_dvbci_text = -1;
839 static gint ett_dvbci_cc_item = -1;
840 static gint ett_dvbci_sac_msg_body = -1;
841 static gint ett_dvbci_ami_req_types = -1;
842 static gint ett_dvbci_lsc_conn_desc = -1;
843 static gint ett_dvbci_opp_cap_loop = -1;
844 static gint ett_dvbci_dlv_sys_hint = -1;
847 static int hf_dvbci_event = -1;
848 static int hf_dvbci_hw_event = -1;
849 static int hf_dvbci_cor_addr = -1;
850 static int hf_dvbci_cor_val = -1;
851 static int hf_dvbci_cis_tpl_code = -1;
852 static int hf_dvbci_cis_tpl_len = -1;
853 static int hf_dvbci_cis_tpl_data = -1;
854 static int hf_dvbci_cis_tpll_v1_major = -1;
855 static int hf_dvbci_cis_tpll_v1_minor = -1;
856 static int hf_dvbci_cis_tpll_v1_info_manuf = -1;
857 static int hf_dvbci_cis_tpll_v1_info_name = -1;
858 static int hf_dvbci_cis_tpll_v1_info_additional = -1;
859 static int hf_dvbci_cis_tpll_v1_end = -1;
860 static int hf_dvbci_cis_tpcc_rfsz = -1;
861 static int hf_dvbci_cis_tpcc_rmsz = -1;
862 static int hf_dvbci_cis_tpcc_rasz = -1;
863 static int hf_dvbci_cis_tpcc_last = -1;
864 static int hf_dvbci_cis_tpcc_radr = -1;
865 static int hf_dvbci_cis_tpcc_rmsk = -1;
866 static int hf_dvbci_cis_st_code = -1;
867 static int hf_dvbci_cis_st_len = -1;
868 static int hf_dvbci_cis_stci_ifn_size = -1;
869 static int hf_dvbci_cis_stci_ifn = -1;
870 static int hf_dvbci_cis_stci_str = -1;
871 static int hf_dvbci_cis_tpce_indx_intface = -1;
872 static int hf_dvbci_cis_tpce_indx_default = -1;
873 static int hf_dvbci_cis_tpce_indx_cnf_entry = -1;
874 static int hf_dvbci_cis_tpce_if_type = -1;
875 static int hf_dvbci_cis_tpce_fs_mem_space = -1;
876 static int hf_dvbci_cis_tpce_fs_irq = -1;
877 static int hf_dvbci_cis_tpce_fs_io = -1;
878 static int hf_dvbci_cis_tplmid_manf = -1;
879 static int hf_dvbci_cis_tplmid_card = -1;
880 static int hf_dvbci_buf_size = -1;
881 static int hf_dvbci_tcid = -1;
882 static int hf_dvbci_ml = -1;
883 static int hf_dvbci_l_frags = -1;
884 static int hf_dvbci_l_frag = -1;
885 static int hf_dvbci_l_frag_overlap = -1;
886 static int hf_dvbci_l_frag_overlap_conflicts = -1;
887 static int hf_dvbci_l_frag_multiple_tails = -1;
888 static int hf_dvbci_l_frag_too_long_frag = -1;
889 static int hf_dvbci_l_frag_err = -1;
890 static int hf_dvbci_l_frag_cnt = -1;
891 static int hf_dvbci_l_reass_in = -1;
892 static int hf_dvbci_l_reass_len = -1;
893 static int hf_dvbci_c_tpdu_tag = -1;
894 static int hf_dvbci_r_tpdu_tag = -1;
895 static int hf_dvbci_t_c_id = -1;
896 static int hf_dvbci_sb_value = -1;
897 static int hf_dvbci_t_frags = -1;
898 static int hf_dvbci_t_frag = -1;
899 static int hf_dvbci_t_frag_overlap = -1;
900 static int hf_dvbci_t_frag_overlap_conflicts = -1;
901 static int hf_dvbci_t_frag_multiple_tails = -1;
902 static int hf_dvbci_t_frag_too_long_frag = -1;
903 static int hf_dvbci_t_frag_err = -1;
904 static int hf_dvbci_t_frag_cnt = -1;
905 static int hf_dvbci_t_reass_in = -1;
906 static int hf_dvbci_t_reass_len = -1;
907 static int hf_dvbci_spdu_tag = -1;
908 static int hf_dvbci_sess_status = -1;
909 static int hf_dvbci_sess_nb = -1;
910 static int hf_dvbci_close_sess_status = -1;
911 static int hf_dvbci_res_id_type = -1;
912 static int hf_dvbci_res_class = -1;
913 static int hf_dvbci_res_type = -1;
914 static int hf_dvbci_res_ver = -1;
915 static int hf_dvbci_apdu_tag = -1;
916 static int hf_dvbci_app_type = -1;
917 static int hf_dvbci_app_manf = -1;
918 static int hf_dvbci_manf_code = -1;
919 static int hf_dvbci_menu_str_len = -1;
920 static int hf_dvbci_ap_char_tbl = -1;
921 static int hf_dvbci_menu_str = -1;
922 static int hf_dvbci_data_rate = -1;
923 static int hf_dvbci_ca_sys_id = -1;
924 static int hf_dvbci_ca_pmt_list_mgmt = -1;
925 static int hf_dvbci_prog_num = -1;
926 static int hf_dvbci_prog_info_len = -1;
927 static int hf_dvbci_stream_type = -1;
928 static int hf_dvbci_es_pid = -1;
929 static int hf_dvbci_es_info_len = -1;
930 static int hf_dvbci_ca_pmt_cmd_id = -1;
931 static int hf_dvbci_descr_len = -1;
932 static int hf_dvbci_ca_pid = -1;
933 static int hf_dvbci_ca_enable_flag = -1;
934 static int hf_dvbci_ca_enable = -1;
935 static int hf_dvbci_auth_proto_id = -1;
936 static int hf_dvbci_auth_req_bytes = -1;
937 static int hf_dvbci_auth_resp_bytes = -1;
938 static int hf_dvbci_network_id = -1;
939 static int hf_dvbci_original_network_id = -1;
940 static int hf_dvbci_transport_stream_id = -1;
941 static int hf_dvbci_service_id = -1;
942 static int hf_dvbci_replacement_ref = -1;
943 static int hf_dvbci_replaced_pid = -1;
944 static int hf_dvbci_replacement_pid = -1;
945 static int hf_dvbci_pmt_flag = -1;
946 static int hf_dvbci_hc_desc_loop_len = -1;
947 static int hf_dvbci_hc_status = -1;
948 static int hf_dvbci_hc_release_reply = -1;
949 static int hf_dvbci_resp_intv = -1;
950 static int hf_dvbci_utc_time = -1;
951 static int hf_dvbci_local_offset = -1;
952 static int hf_dvbci_close_mmi_cmd_id = -1;
953 static int hf_dvbci_close_mmi_delay = -1;
954 static int hf_dvbci_disp_ctl_cmd = -1;
955 static int hf_dvbci_mmi_mode = -1;
956 static int hf_dvbci_disp_rep_id = -1;
957 static int hf_dvbci_mmi_char_tbl = -1;
958 static int hf_dvbci_blind_ans = -1;
959 static int hf_dvbci_ans_txt_len = -1;
960 static int hf_dvbci_enq = -1;
961 static int hf_dvbci_ans_id = -1;
962 static int hf_dvbci_ans = -1;
963 static int hf_dvbci_choice_nb = -1;
964 static int hf_dvbci_choice_ref = -1;
965 static int hf_dvbci_item_nb = -1;
966 static int hf_dvbci_title = -1;
967 static int hf_dvbci_subtitle = -1;
968 static int hf_dvbci_bottom = -1;
969 static int hf_dvbci_item = -1;
970 static int hf_dvbci_host_country = -1;
971 static int hf_dvbci_host_language = -1;
972 static int hf_dvbci_cup_type = -1;
973 static int hf_dvbci_cup_download_time = -1;
974 static int hf_dvbci_cup_answer = -1;
975 static int hf_dvbci_cup_progress = -1;
976 static int hf_dvbci_cup_reset = -1;
977 static int hf_dvbci_cc_sys_id_bitmask = -1;
978 static int hf_dvbci_cc_dat_id = -1;
979 static int hf_dvbci_brand_cert = -1;
980 static int hf_dvbci_dev_cert = -1;
981 static int hf_dvbci_uri_ver = -1;
982 static int hf_dvbci_uri_aps = -1;
983 static int hf_dvbci_uri_emi = -1;
984 static int hf_dvbci_uri_ict = -1;
985 static int hf_dvbci_uri_rct = -1;
986 static int hf_dvbci_uri_dot = -1;
987 static int hf_dvbci_uri_rl = -1;
988 static int hf_dvbci_cc_key_register = -1;
989 static int hf_dvbci_cc_status_field = -1;
990 static int hf_dvbci_cc_op_mode = -1;
991 static int hf_dvbci_cc_data = -1;
992 static int hf_dvbci_sac_msg_ctr = -1;
993 static int hf_dvbci_sac_proto_ver = -1;
994 static int hf_dvbci_sac_auth_cip = -1;
995 static int hf_dvbci_sac_payload_enc = -1;
996 static int hf_dvbci_sac_enc_cip = -1;
997 static int hf_dvbci_sac_payload_len = -1;
998 static int hf_dvbci_sac_enc_body = -1;
999 static int hf_dvbci_sac_padding = -1;
1000 static int hf_dvbci_sac_signature = -1;
1001 static int hf_dvbci_rating = -1;
1002 static int hf_dvbci_capability_field = -1;
1003 static int hf_dvbci_pin_chg_time = -1;
1004 static int hf_dvbci_pincode_status = -1;
1005 static int hf_dvbci_cc_prog_num = -1;
1006 static int hf_dvbci_pin_evt_time = -1;
1007 static int hf_dvbci_pin_evt_cent = -1;
1008 static int hf_dvbci_cc_priv_data = -1;
1009 static int hf_dvbci_pincode = -1;
1010 static int hf_dvbci_app_dom_id = -1;
1011 static int hf_dvbci_init_obj = -1;
1012 static int hf_dvbci_ack_code = -1;
1013 static int hf_dvbci_req_type = -1;
1014 static int hf_dvbci_file_hash = -1;
1015 static int hf_dvbci_file_name = -1;
1016 static int hf_dvbci_ami_priv_data = -1;
1017 static int hf_dvbci_req_ok = -1;
1018 static int hf_dvbci_file_ok = -1;
1019 static int hf_dvbci_file_data = -1;
1020 static int hf_dvbci_abort_req_code = -1;
1021 static int hf_dvbci_abort_ack_code = -1;
1022 static int hf_dvbci_phase_id = -1;
1023 static int hf_dvbci_comms_rep_id = -1;
1024 static int hf_dvbci_lsc_buf_size = -1;
1025 static int hf_dvbci_lsc_ret_val = -1;
1026 static int hf_dvbci_comms_cmd_id = -1;
1027 static int hf_dvbci_conn_desc_type = -1;
1028 static int hf_dvbci_lsc_media_tag = -1;
1029 static int hf_dvbci_lsc_media_len = -1;
1030 static int hf_dvbci_lsc_ip_ver = -1;
1031 static int hf_dvbci_lsc_ipv4_addr = -1;
1032 static int hf_dvbci_lsc_ipv6_addr = -1;
1033 static int hf_dvbci_lsc_dst_port = -1;
1034 static int hf_dvbci_lsc_proto = -1;
1035 static int hf_dvbci_lsc_hostname = -1;
1036 static int hf_dvbci_lsc_retry_count = -1;
1037 static int hf_dvbci_lsc_timeout = -1;
1038 static int hf_dvbci_info_ver_op_status = -1;
1039 static int hf_dvbci_nit_ver = -1;
1040 static int hf_dvbci_pro_typ = -1;
1041 static int hf_dvbci_init_flag = -1;
1042 static int hf_dvbci_ent_chg_flag = -1;
1043 static int hf_dvbci_ent_val_flag = -1;
1044 static int hf_dvbci_ref_req_flag = -1;
1045 static int hf_dvbci_err_flag = -1;
1046 static int hf_dvbci_dlv_sys_hint = -1;
1047 static int hf_dvbci_dlv_sys_hint_t = -1;
1048 static int hf_dvbci_dlv_sys_hint_s = -1;
1049 static int hf_dvbci_dlv_sys_hint_c = -1;
1050 static int hf_dvbci_refr_req_date = -1;
1051 static int hf_dvbci_refr_req_time = -1;
1052 static int hf_dvbci_nit_loop_len = -1;
1053 static int hf_dvbci_info_valid = -1;
1054 static int hf_dvbci_info_ver_op_info = -1;
1055 static int hf_dvbci_cicam_onid = -1;
1056 static int hf_dvbci_cicam_id = -1;
1057 static int hf_dvbci_opp_char_tbl = -1;
1058 static int hf_dvbci_sdt_rst_trusted = -1;
1059 static int hf_dvbci_eit_rst_trusted = -1;
1060 static int hf_dvbci_eit_pf_usage = -1;
1061 static int hf_dvbci_eit_sch_usage = -1;
1062 static int hf_dvbci_ext_evt_usage = -1;
1063 static int hf_dvbci_sdt_oth_trusted = -1;
1064 static int hf_dvbci_eit_evt_trigger = -1;
1065 static int hf_dvbci_opp_lang_code = -1;
1066 static int hf_dvbci_prof_name = -1;
1067 static int hf_dvbci_unattended = -1;
1068 static int hf_dvbci_opp_srv_type = -1;
1069 static int hf_dvbci_dlv_cap_byte = -1;
1070 static int hf_dvbci_app_cap_bytes = -1;
1071 static int hf_dvbci_desc_num = -1;
1072 static int hf_dvbci_sig_strength = -1;
1073 static int hf_dvbci_sig_qual = -1;
1074 static int hf_dvbci_opp_tune_status = -1;
1075 static int hf_dvbci_opp_desc_loop_len = -1;
1076 static int hf_dvbci_sas_app_id = -1;
1077 static int hf_dvbci_sas_sess_state = -1;
1078 static int hf_dvbci_sas_msg_nb = -1;
1079 static int hf_dvbci_sas_msg_len = -1;
1081 static const int *dvbci_opp_dlv_sys_hint_fields[] = {
1082 &hf_dvbci_dlv_sys_hint_t,
1083 &hf_dvbci_dlv_sys_hint_s,
1084 &hf_dvbci_dlv_sys_hint_c,
1089 static expert_field ei_dvbci_spdu_tag = EI_INIT;
1090 static expert_field ei_dvbci_sac_payload_enc = EI_INIT;
1091 static expert_field ei_dvbci_buf_size = EI_INIT;
1092 static expert_field ei_dvbci_cicam_nit_table_id = EI_INIT;
1093 static expert_field ei_dvbci_c_tpdu_tag = EI_INIT;
1094 static expert_field ei_dvbci_res_class = EI_INIT;
1095 static expert_field ei_dvbci_bad_length = EI_INIT;
1096 static expert_field ei_dvbci_apdu_not_supported = EI_INIT;
1097 static expert_field ei_dvbci_not_text_more_or_text_last = EI_INIT;
1098 static expert_field ei_dvbci_apu_cam_to_host = EI_INIT;
1099 static expert_field ei_dvbci_ca_pmt_cmd_id = EI_INIT;
1100 static expert_field ei_dvbci_ml = EI_INIT;
1101 static expert_field ei_dvbci_cup_progress = EI_INIT;
1102 static expert_field ei_dvbci_sb_value = EI_INIT;
1103 static expert_field ei_dvbci_spdu_cam_to_host = EI_INIT;
1104 static expert_field ei_dvbci_spdu_host_to_cam = EI_INIT;
1105 static expert_field ei_dvbci_network_id = EI_INIT;
1106 static expert_field ei_dvbci_invalid_char_tbl = EI_INIT;
1107 static expert_field ei_dvbci_t_c_id = EI_INIT;
1108 static expert_field ei_dvbci_tpdu_status_tag = EI_INIT;
1109 static expert_field ei_dvbci_r_tpdu_tag = EI_INIT;
1110 static expert_field ei_dvbci_cor_addr = EI_INIT;
1111 static expert_field ei_dvbci_pin_evt_cent = EI_INIT;
1112 static expert_field ei_dvbci_res_ver = EI_INIT;
1113 static expert_field ei_dvbci_apdu_tag = EI_INIT;
1114 static expert_field ei_dvbci_r_tpdu_status_mandatory = EI_INIT;
1115 static expert_field ei_dvbci_apu_host_to_cam = EI_INIT;
1116 static expert_field ei_dvbci_sig_qual = EI_INIT;
1118 static dissector_table_t sas_msg_dissector_table;
1120 static reassembly_table tpdu_reassembly_table;
1121 static reassembly_table spdu_reassembly_table;
1123 static const fragment_items tpdu_frag_items = {
1124 &ett_dvbci_link_frag,
1125 &ett_dvbci_link_frags,
1129 &hf_dvbci_l_frag_overlap,
1130 &hf_dvbci_l_frag_overlap_conflicts,
1131 &hf_dvbci_l_frag_multiple_tails,
1132 &hf_dvbci_l_frag_too_long_frag,
1133 &hf_dvbci_l_frag_err,
1134 &hf_dvbci_l_frag_cnt,
1136 &hf_dvbci_l_reass_in,
1137 &hf_dvbci_l_reass_len,
1138 /* Reassembled data field */
1142 static const fragment_items spdu_frag_items = {
1143 &ett_dvbci_transport_frag,
1144 &ett_dvbci_transport_frags,
1148 &hf_dvbci_t_frag_overlap,
1149 &hf_dvbci_t_frag_overlap_conflicts,
1150 &hf_dvbci_t_frag_multiple_tails,
1151 &hf_dvbci_t_frag_too_long_frag,
1152 &hf_dvbci_t_frag_err,
1153 &hf_dvbci_t_frag_cnt,
1155 &hf_dvbci_t_reass_in,
1156 &hf_dvbci_t_reass_len,
1157 /* Reassembled data field */
1164 typedef struct _spdu_info_t {
1170 static const value_string dvbci_hw_event[] = {
1171 { CAM_IN, "CI Module is inserted" },
1172 { CAM_OUT, "CI Module is removed" },
1173 { POWER_ON, "CI slot power on" },
1174 { POWER_OFF, "CI slot power off" },
1175 { TS_ROUTE, "Transport stream routed through the CI Module" },
1176 { TS_BYPASS, "Transport stream bypasses the CI Module" },
1177 { RESET_H, "Reset pin is high" },
1178 { RESET_L, "Reset pin is low" },
1179 { READY_H, "Ready pin is high" },
1180 { READY_L, "Ready pin is low" },
1183 static const value_string dvbci_cis_tpl_code[] = {
1184 { CISTPL_NO_LINK, "No-link tuple" },
1185 { CISTPL_VERS_1, "Level 1 version/product information" },
1186 { CISTPL_CONFIG, "Configuration for a 16bit PC-Card" },
1187 { CISTPL_CFTABLE_ENTRY, "Configuration-table entry" },
1188 { CISTPL_DEVICE_OC, "Device information for Common Memory" },
1189 { CISTPL_DEVICE_OA, "Device information for Attribute Memory" },
1190 { CISTPL_MANFID, "Manufacturer indentification string" },
1191 { CISTPL_END, "End of chain" },
1194 static const value_string dvbci_cis_subtpl_code[] = {
1195 { CCSTPL_CIF, "Custom interface subtuple" },
1198 static const value_string dvbci_cis_tpce_if_type[] = {
1199 { TPCE_IF_TYPE_MEM, "Memory" },
1200 { TPCE_IF_TYPE_IO_MEM, "I/O and Memory" },
1201 { TPCE_IF_TYPE_CUST0, "Custom Interface 0" },
1202 { TPCE_IF_TYPE_CUST1, "Custom Interface 1" },
1203 { TPCE_IF_TYPE_CUST2, "Custom Interface 2" },
1204 { TPCE_IF_TYPE_CUST3, "Custom Interface 3" },
1207 static const value_string dvbci_ml[] = {
1208 { ML_MORE, "more TPDU fragments pending" },
1209 { ML_LAST, "last TPDU fragment" },
1212 static const value_string dvbci_c_tpdu[] = {
1214 { T_CREATE_T_C, "T_create_t_c" },
1215 { T_DELETE_T_C, "T_delete_t_c" },
1216 { T_D_T_C_REPLY, "T_d_t_c_reply" },
1217 { T_NEW_T_C, "T_new_t_c" },
1218 { T_T_C_ERROR, "T_t_c_error" },
1219 { T_DATA_LAST, "T_data_last" },
1220 { T_DATA_MORE, "T_data_more" },
1223 static const value_string dvbci_r_tpdu[] = {
1224 { T_C_T_C_REPLY, "T_c_tc_reply" },
1225 { T_DELETE_T_C, "T_delete_t_c" },
1226 { T_D_T_C_REPLY, "T_d_t_c_reply" },
1227 { T_REQUEST_T_C, "T_request_t_c" },
1228 { T_DATA_LAST, "T_data_last" },
1229 { T_DATA_MORE, "T_data_more" },
1232 static const value_string dvbci_sb_value[] = {
1233 { SB_VAL_MSG_AVAILABLE, "message available" },
1234 { SB_VAL_NO_MSG_AVAILABLE, "no message available" },
1237 static const value_string dvbci_spdu_tag[] = {
1238 { T_SESSION_NUMBER, "Session Number (payload data)" },
1239 { T_OPEN_SESSION_REQUEST, "Open Session Request" },
1240 { T_OPEN_SESSION_RESPONSE, "Open Session Response" },
1241 { T_CREATE_SESSION, "Create Session" },
1242 { T_CREATE_SESSION_RESPONSE, "Create Session Response" },
1243 { T_CLOSE_SESSION_REQUEST, "Close Session Request" },
1244 { T_CLOSE_SESSION_RESPONSE, "Close Session Response" },
1247 static GHashTable *spdu_table = NULL;
1248 static const spdu_info_t spdu_info[] = {
1249 { T_SESSION_NUMBER, DIRECTION_ANY, 2 },
1250 { T_OPEN_SESSION_REQUEST, DATA_CAM_TO_HOST, 4 },
1251 { T_OPEN_SESSION_RESPONSE, DATA_HOST_TO_CAM, 7 },
1252 { T_CREATE_SESSION, DATA_HOST_TO_CAM, 6 },
1253 { T_CREATE_SESSION_RESPONSE, DATA_CAM_TO_HOST, 7 },
1254 { T_CLOSE_SESSION_REQUEST, DIRECTION_ANY, 2 },
1255 { T_CLOSE_SESSION_RESPONSE, DIRECTION_ANY, 3 }
1257 static const value_string dvbci_sess_status[] = {
1260 { SESS_NOT_OPENED_RES_NON_EXIST,
1261 "Resource does not exist" },
1262 { SESS_NOT_OPENED_RES_UNAVAIL,
1263 "Resource exists but it's unavailable" },
1264 { SESS_NOT_OPENED_RES_VER_LOWER,
1265 "Existing resource's version is lower than requested version" },
1266 { SESS_NOT_OPENED_RES_BUSY,
1267 "Resource is busy" },
1270 static const value_string dvbci_close_sess_status[] = {
1271 { SESS_CLOSED, "Session closed" },
1272 { SESS_NB_NOT_ALLOC, "Session number not allocated" },
1275 static const value_string dvbci_res_class[] = {
1276 { RES_CLASS_RM, "Resource Manager" },
1277 { RES_CLASS_AP, "Application Info" },
1278 { RES_CLASS_CA, "Conditional Access" },
1279 { RES_CLASS_AUT, "Authentication" },
1280 { RES_CLASS_HC, "Host Control" },
1281 { RES_CLASS_DT, "Date-Time" },
1282 { RES_CLASS_MMI, "Man-machine interface (MMI)" },
1283 { RES_CLASS_AMI, "Application MMI" },
1284 { RES_CLASS_LSC, "Low-Speed Communication" },
1285 { RES_CLASS_CC, "Content Control" },
1286 { RES_CLASS_HLC, "Host Language & Country" },
1287 { RES_CLASS_CUP, "CAM Upgrade" },
1288 { RES_CLASS_OPP, "Operator Profile" },
1289 { RES_CLASS_SAS, "Specific Application Support" },
1292 static const value_string dvbci_app_type[] = {
1293 { APP_TYPE_CA, "Conditional Access" },
1294 { APP_TYPE_EPG, "Electronic Progam Guide" },
1297 static const value_string dvbci_data_rate[] = {
1298 { DATA_RATE_72, "72 Mbit/s" },
1299 { DATA_RATE_96, "96 Mbit/s" },
1302 static const value_string dvbci_ca_pmt_list_mgmt[] = {
1303 { LIST_MGMT_MORE, "more" },
1304 { LIST_MGMT_FIRST, "first" },
1305 { LIST_MGMT_LAST, "last" },
1306 { LIST_MGMT_ONLY, "only" },
1307 { LIST_MGMT_ADD, "add" },
1308 { LIST_MGMT_UPDATE, "update" },
1311 static const value_string dvbci_ca_pmt_cmd_id[] = {
1312 { CMD_ID_OK_DESCR, "ok descrambling" },
1313 { CMD_ID_OK_MMI, "ok mmi" },
1314 { CMD_ID_QUERY, "query" },
1315 { CMD_ID_NOT_SELECTED, "not selected" },
1318 static const value_string dvbci_ca_enable[] = {
1319 { CA_ENAB_DESC_OK, "descrambling possible" },
1320 { CA_ENAB_DESC_OK_PURCHASE,
1321 "descrambling possible under conditions (purchase dialogue)" },
1322 { CA_ENAB_DESC_OK_TECH,
1323 "descrambling possible under conditions (technical dialogue)" },
1324 { CA_ENAB_DESC_NG_ENTITLEMENT,
1325 "descrambling not possible (because no entitlement)" },
1326 { CA_ENAB_DESC_NG_TECH,
1327 "descrambling not possible (for technical reasons)" },
1330 static const value_string dvbci_hc_status[] = {
1331 { HC_STAT_OK, "ok" },
1332 { HC_STAT_ERR_DLVRY, "unsupported delivery system descriptor" },
1333 { HC_STAT_ERR_LOCK, "tuner not locking" },
1334 { HC_STAT_ERR_BUSY, "tuner busy" },
1335 { HC_STAT_ERR_PARAM, "bad or missing parameters" },
1336 { HC_STAT_ERR_NOT_FOUND, "service not found" },
1337 { HC_STAT_ERR_UNKNOWN, "unknown error" },
1340 static const value_string dvbci_hc_release_reply[] = {
1341 { HC_RELEASE_OK, "Host regains control of the tuner" },
1342 { HC_RELEASE_REFUSED, "CICAM retains control of the tuner" },
1345 static const value_string dvbci_close_mmi_cmd_id[] = {
1346 { CLOSE_MMI_CMD_ID_IMMEDIATE, "immediate close" },
1347 { CLOSE_MMI_CMD_ID_DELAY, "delayed close" },
1350 static const value_string dvbci_disp_ctl_cmd[] = {
1351 { DISP_CMD_SET_MMI_MODE, "set MMI mode" },
1352 { DISP_CMD_GET_DISP_TBL, "get display character tables" },
1353 { DISP_CMD_GET_INP_TBL, "get input character tables" },
1356 static const value_string dvbci_mmi_mode[] = {
1357 { MMI_MODE_HIGH, "High-level MMI" },
1360 static const value_string dvbci_disp_rep_id[] = {
1361 { DISP_REP_ID_MMI_MODE_ACK, "MMI mode acknowledge" },
1362 { DISP_REP_ID_DISP_CHAR_TBL, "list display character tables" },
1363 { DISP_REP_ID_INP_CHAR_TBL, "list input character tables" },
1364 { DISP_REP_ID_UNKNOWN_CMD, "unknown display control command" },
1365 { DISP_REP_ID_UNKNOWN_MMI_MODE, "unknown MMI mode" },
1366 { DISP_REP_ID_UNKNOWN_CHAR_TBL, "unknown character table" },
1369 static const value_string dvbci_blind_ans[] = {
1370 { VISIBLE_ANS, "visible" },
1371 { BLIND_ANS, "blind" },
1374 static const value_string dvbci_ans_id[] = {
1375 { ANSW_ID_CANCEL, "cancel" },
1376 { ANSW_ID_ANSWER, "answer" },
1379 static const value_string dvbci_cup_type[] = {
1380 { CUP_DELAYED, "delayed" },
1381 { CUP_IMMEDIATE, "immediate" },
1384 static const value_string dvbci_cup_answer[] = {
1385 { CUP_ANS_NO, "upgrade denied" },
1386 { CUP_ANS_YES, "upgrade allowed" },
1387 { CUP_ANS_ASK, "ask the user for permission" },
1390 static const value_string dvbci_cup_reset[] = {
1391 { CUP_RESET_PCMCIA, "PCMCIA reset" },
1392 { CUP_RESET_CMDIF, "CI command interface reset" },
1393 { CUP_RESET_NONE, "no reset" },
1396 static const value_string dvbci_cc_dat_id[] = {
1397 { CC_ID_HOST_ID, "Host ID" },
1398 { CC_ID_CICAM_ID, "Cicam ID" },
1399 { CC_ID_HOST_BRAND_CERT, "Host brand certificate" },
1400 { CC_ID_CICAM_BRAND_CERT, "Cicam brand certificate" },
1401 { CC_ID_KP, "Key precursor for CCK" },
1402 { CC_ID_DHPH, "Host Diffie-Hellman public key" },
1403 { CC_ID_DHPM, "Cicam Diffie-Hellman public key" },
1404 { CC_ID_HOST_DEV_CERT, "Host device certificate" },
1405 { CC_ID_CICAM_DEV_CERT, "Cicam device certificate" },
1406 { CC_ID_SIG_A, "Signature of host Diffie-Hellman public key" },
1407 { CC_ID_SIG_B, "Signature of cicam Diffie-Hellman public key" },
1408 { CC_ID_NS_HOST, "Host nonce" },
1409 { CC_ID_AUTH_NONCE, "Nonce for authentication" },
1410 { CC_ID_NS_MODULE, "Cicam nonce" },
1411 { CC_ID_AKH, "Host authentication key" },
1412 { CC_ID_URI, "URI" },
1413 { CC_ID_PROG_NUM, "Program number" },
1414 { CC_ID_URI_CNF, "URI confirmation" },
1415 { CC_ID_KEY_REGISTER, "Key register" },
1416 { CC_ID_URI_VERSIONS, "Supported URI versions" },
1417 { CC_ID_STATUS_FIELD, "Status field" },
1418 { CC_ID_SRM_DATA, "SRM for HDCP" },
1419 { CC_ID_SRM_CONFIRM, "SRM confirmation hash" },
1420 { CC_ID_CICAM_LICENSE, "License received from the cicam" },
1421 { CC_ID_LICENSE_STATUS, "Current status of the license" },
1422 { CC_ID_LICENSE_RCV_STATUS, "Status of the license exchange" },
1423 { CC_ID_HOST_LICENSE,
1424 "License for which the host requests the current status" },
1425 { CC_ID_PLAY_COUNT, "Play count" },
1426 { CC_ID_OPERATING_MODE, "Operating mode" },
1427 { CC_ID_PINCODE_DATA, "Pincode data" },
1428 { CC_ID_REC_START_STATUS, "Record start status" },
1429 { CC_ID_MODE_CHG_STATUS, "Change operating mode status" },
1430 { CC_ID_REC_STOP_STATUS, "Record stop status" },
1433 static const value_string dvbci_cc_uri_emi[] = {
1434 { CC_EMI_FREE, "Copy free" },
1435 { CC_EMI_NO_MORE, "Copy no more" },
1436 { CC_EMI_ONCE, "Copy once" },
1437 { CC_EMI_NEVER, "Copy never" },
1440 static const value_string dvbci_cc_key_register[] = {
1441 { CC_KEY_EVEN, "Even" },
1442 { CC_KEY_ODD, "Odd" },
1445 static const value_string dvbci_cc_status[] = {
1446 { CC_STATUS_OK, "Ok" },
1447 { CC_STATUS_NO_CC_SUPPORT, "No CC support" },
1448 { CC_STATUS_HOST_BUSY, "Host busy" },
1449 { CC_STATUS_AUTH_FAILED_OR_NO_SRM, "Authentication failed / SRM not required" },
1450 { CC_STATUS_CICAM_BUSY, "CICAM busy" },
1451 { CC_STATUS_REC_MODE_ERR, "Recording mode error" },
1454 static const value_string dvbci_cc_sac_auth[] = {
1455 { CC_SAC_AUTH_AES128_XCBC_MAC, "AES 128 XCBC MAC" },
1458 static const value_string dvbci_cc_sac_enc[] = {
1459 { CC_SAC_ENC_AES128_CBC, "AES 128 CBC" },
1462 static const value_string dvbci_cc_cap[] = {
1464 "No PIN handling capability" },
1466 "CAM can do PIN handling on CAS services" },
1467 { CC_CAP_CAS_FTA_PIN,
1468 "CAM can do PIN handling on CAS and free services" },
1469 { CC_CAP_CAS_PIN_CACHED,
1470 "CAM can do PIN handling on CAS services and supports PIN caching" },
1471 { CC_CAP_CAS_FTA_PIN_CACHED,
1472 "CAM can do PIN handling on CAS and free services, supports PIN caching" },
1475 static const value_string dvbci_pincode_status[] = {
1476 { CC_PIN_BAD, "Bad pin code" },
1477 { CC_PIN_CAM_BUSY, "CAM busy" },
1478 { CC_PIN_OK, "Pin code correct" },
1479 { CC_PIN_UNCONFIRMED, "Pin code unconfirmed" },
1480 { CC_PIN_VB_NOT_REQ, "Video blanking not required" },
1481 { CC_PIN_CSA, "Content still CSA scrambled" },
1484 static const value_string dvbci_cc_op_mode[] = {
1485 { CC_OP_MODE_WATCH_BUFFER, "Watch and buffer" },
1486 { CC_OP_MODE_TIMESHIFT, "Timeshift" },
1487 { CC_OP_MODE_UNATTENDED, "Unattended recording" },
1490 static const value_string dvbci_ack_code[] = {
1491 { ACK_CODE_OK, "Ok" },
1492 { ACK_CODE_WRONG_API, "Application Domain unsupported" },
1493 { ACK_CODE_API_BUSY, "Application Domain currently unavailable" },
1496 static const value_string dvbci_req_type[] = {
1497 { REQ_TYPE_FILE, "File" },
1498 { REQ_TYPE_DATA, "Data" },
1499 { REQ_TYPE_FILE_HASH, "FileHash" },
1500 { REQ_TYPE_REQ, "List supported request types" },
1503 static const value_string dvbci_comms_cmd_id[] = {
1504 { COMMS_CMD_ID_CONNECT_ON_CHANNEL, "connect on channel" },
1505 { COMMS_CMD_ID_DISCONNECT_ON_CHANNEL, "disconnect on channel" },
1506 { COMMS_CMD_ID_SET_PARAMS, "set parameters" },
1507 { COMMS_CMD_ID_ENQUIRE_STATUS, "status enquiry" },
1508 { COMMS_CMD_ID_GET_NEXT_BUFFER, "get next buffer" },
1511 static const value_string dvbci_conn_desc_type[] = {
1512 { CONN_DESC_TEL, "DVB-SI telephone descriptor" },
1513 { CONN_DESC_CABLE, "cable return channel" },
1514 { CONN_DESC_IP, "IP descriptor" },
1515 { CONN_DESC_HOSTNAME, "hostname descriptor" },
1518 static const value_string dvbci_lsc_desc_tag[] = {
1519 { LSC_DESC_IP, "IP descriptor" },
1520 { LSC_DESC_HOSTNAME, "hostname descriptor" },
1523 static const value_string dvbci_lsc_ip_ver[] = {
1524 { LSC_IPV4, "IPv4" },
1525 { LSC_IPV6, "IPv6" },
1528 static const value_string dvbci_lsc_proto[] = {
1533 static const value_string dvbci_comms_rep_id[] = {
1534 { COMMS_REP_ID_CONNECT_ACK, "connect ack" },
1535 { COMMS_REP_ID_DISCONNECT_ACK, "disconnect ack" },
1536 { COMMS_REP_ID_SET_PARAMS_ACK, "set parameters ack" },
1537 { COMMS_REP_ID_STATUS_REPLY, "status reply" },
1538 { COMMS_REP_ID_GET_NEXT_BUFFER_ACK, "get next buffer ack" },
1539 { COMMS_REP_ID_SEND_ACK, "send ack" },
1542 static const value_string dvbci_lsc_ret_val[] = {
1543 { LSC_RET_OK, "ok" },
1546 static const value_string dvbci_lsc_ret_val_connect[] = {
1547 { LSC_RET_DISCONNECTED, "disconnected" },
1548 { LSC_RET_CONNECTED, "connected" },
1551 static const value_string dvbci_lsc_ret_val_params[] = {
1552 { LSC_RET_OK, "ok" },
1553 { LSC_RET_TOO_BIG, "buffer size too big" },
1556 static const value_string dvbci_opp_ref_req_flag[] = {
1557 { OPP_REF_REG_FLG_NONE, "none" },
1558 { OPP_REF_REG_FLG_ADV, "advance warning" },
1559 { OPP_REF_REG_FLG_URG, "urgent" },
1560 { OPP_REF_REG_FLG_SCHED, "scheduled" },
1563 static const value_string dvbci_opp_err_flag[] = {
1564 { OPP_ERR_FLG_OK, "no error" },
1565 { OPP_ERR_FLG_PROF, "CICAM can't acquire the profile" },
1566 { OPP_ERR_FLG_UNSUPPORTED, "unsupported delivery system" },
1567 { OPP_ERR_FLG_CANCELLED, "operator search was cancelled" },
1570 static const value_string dvbci_opp_eit_pf_usage[] = {
1571 { OPP_EIT_ABSENT, "no EIT present" },
1572 { OPP_EIT_NOT_X, "EIT is not fully ross-carried" },
1573 { OPP_EIT_FULL_X, "EIT is fully cross-carried" },
1576 static const value_string dvbci_opp_eit_sch_usage[] = {
1577 { OPP_EIT_ABSENT, "no EIT present" },
1578 { OPP_EIT_NOT_X, "EIT is not fully ross-carried" },
1579 { OPP_EIT_FULL_X, "EIT is fully cross-carried" },
1580 { OPP_EIT_BARKER, "EIT is available from a barker channel" },
1581 { OPP_EPG_APP, "EPG is delivered using an application" },
1584 static const value_string dvbci_opp_ext_evt[] = {
1585 { OPP_EXT_EVT_DIFF, "extended event info is different from short event" },
1586 { OPP_EXT_EVT_ADD, "extended event info includes short event" },
1589 static const value_string dvbci_opp_dlv_cap[] = {
1590 { OPP_DLV_CAP_S, "DVB-S" },
1591 { OPP_DLV_CAP_C, "DVB-C" },
1592 { OPP_DLV_CAP_T, "DVB-T" },
1593 { OPP_DLV_CAP_S2, "DVB-S2" },
1596 static const value_string dvbci_opp_tune_stat[] = {
1597 { OPP_TUNE_OK, "success" },
1598 { OPP_TUNE_UNSUPPORTED, "unsupported delivery system descriptor" },
1599 { OPP_TUNE_INVALID, "invalid delivery system descriptor" },
1600 { OPP_TUNE_ERR, "failed" },
1603 static const value_string dvbci_sas_sess_state[] = {
1604 { SAS_SESS_STATE_CONNECTED, "connected" },
1605 { SAS_SESS_STATE_NOT_FOUND, "application not found" },
1606 { SAS_SESS_STATE_DENIED, "denied, no more connections available" },
1611 static guint16 buf_size_cam; /* buffer size proposal by the CAM */
1612 /* buffer size proposal by the host == negotiated buffer size */
1613 static guint16 buf_size_host;
1617 dvbci_set_addrs(guint8 event, packet_info *pinfo)
1619 if (!IS_DATA_TRANSFER(event))
1622 if (event == DVBCI_EVT_DATA_HOST_TO_CAM) {
1623 SET_ADDRESS(&pinfo->src, AT_STRINGZ,
1624 (int)strlen(ADDR_HOST)+1, ADDR_HOST);
1625 SET_ADDRESS(&pinfo->dst, AT_STRINGZ,
1626 (int)strlen(ADDR_CAM)+1 , ADDR_CAM);
1629 SET_ADDRESS(&pinfo->src, AT_STRINGZ,
1630 (int)strlen(ADDR_CAM)+1 , ADDR_CAM);
1631 SET_ADDRESS(&pinfo->dst, AT_STRINGZ,
1632 (int)strlen(ADDR_HOST)+1, ADDR_HOST);
1640 dvbci_get_evt_from_addrs(packet_info *pinfo)
1642 /* this should be working from C89 on */
1643 static const address a_cam = { AT_STRINGZ, -1, sizeof(ADDR_CAM), ADDR_CAM };
1644 static const address a_host = { AT_STRINGZ, -1, sizeof(ADDR_HOST), ADDR_HOST };
1646 if ( ADDRESSES_EQUAL(&(pinfo->src), &a_cam) &&
1647 ADDRESSES_EQUAL(&(pinfo->dst), &a_host) ) {
1648 return DVBCI_EVT_DATA_CAM_TO_HOST;
1650 else if ( ADDRESSES_EQUAL(&(pinfo->src), &a_host) &&
1651 ADDRESSES_EQUAL(&(pinfo->dst), &a_cam) ) {
1652 return DVBCI_EVT_DATA_HOST_TO_CAM;
1655 return DVBCI_EVT_INVALID_EVT;
1659 /* this must be a function, not a macro,
1660 so that we can enforce the return type */
1661 static inline gint16 two_comp_to_int16(guint16 x)
1663 return (x&0x8000) ? -~(x-1) : x;
1667 /* initialize/reset per capture state data */
1674 reassembly_table_init(&tpdu_reassembly_table,
1675 &addresses_reassembly_table_functions);
1676 reassembly_table_init(&spdu_reassembly_table,
1677 &addresses_reassembly_table_functions);
1681 /* dissect a delivery system descriptor loop
1682 and the preceding length field
1683 (used for host control and operator profile)
1684 return the number of bytes dissected */
1686 dissect_desc_loop(int len_hf,
1687 tvbuff_t *tvb, gint offset, packet_info *pinfo _U_, proto_tree *tree)
1690 guint16 desc_loop_len;
1693 offset_start = offset;
1695 desc_loop_len = tvb_get_ntohs(tvb, offset) & 0x0FFF;
1696 proto_tree_add_item(tree, len_hf, tvb, offset, 2, ENC_BIG_ENDIAN);
1698 while (offset-offset_start < 2+desc_loop_len) {
1699 desc_len = proto_mpeg_descriptor_dissect(tvb, offset, tree);
1705 return offset-offset_start;
1709 /* dissect operator profile's status body, return its length */
1711 dissect_opp_status_body(tvbuff_t *tvb, gint offset,
1712 packet_info *pinfo _U_, proto_tree *tree)
1716 offset_start = offset;
1717 proto_tree_add_item(tree, hf_dvbci_info_ver_op_status,
1718 tvb, offset, 1, ENC_BIG_ENDIAN);
1719 proto_tree_add_item(tree, hf_dvbci_nit_ver,
1720 tvb, offset, 1, ENC_BIG_ENDIAN);
1722 proto_tree_add_item(tree, hf_dvbci_pro_typ,
1723 tvb, offset, 1, ENC_BIG_ENDIAN);
1724 proto_tree_add_item(tree, hf_dvbci_init_flag,
1725 tvb, offset, 1, ENC_BIG_ENDIAN);
1726 proto_tree_add_item(tree, hf_dvbci_ent_chg_flag,
1727 tvb, offset, 1, ENC_BIG_ENDIAN);
1728 proto_tree_add_item(tree, hf_dvbci_ent_val_flag,
1729 tvb, offset, 1, ENC_BIG_ENDIAN);
1730 proto_tree_add_item(tree, hf_dvbci_ref_req_flag,
1731 tvb, offset, 1, ENC_BIG_ENDIAN);
1733 proto_tree_add_item(tree, hf_dvbci_err_flag,
1734 tvb, offset, 1, ENC_BIG_ENDIAN);
1735 proto_tree_add_bitmask(tree, tvb, offset,
1736 hf_dvbci_dlv_sys_hint, ett_dvbci_dlv_sys_hint,
1737 dvbci_opp_dlv_sys_hint_fields, ENC_BIG_ENDIAN);
1739 proto_tree_add_item(tree, hf_dvbci_refr_req_date,
1740 tvb, offset, 2, ENC_BIG_ENDIAN);
1742 proto_tree_add_item(tree, hf_dvbci_refr_req_time,
1743 tvb, offset, 1, ENC_BIG_ENDIAN);
1746 return offset-offset_start;
1750 /* dissect a capability loop in an operator_search_start apdu */
1752 dissect_opp_cap_loop(guint8 cap_loop_len, const gchar *title,
1753 int item_hf, guint item_len,
1754 tvbuff_t *tvb, gint offset,
1755 packet_info *pinfo _U_, proto_tree *tree)
1757 proto_item *ti = NULL;
1758 proto_tree *loop_tree = NULL;
1766 if (tree && cap_loop_len>0) {
1767 ti = proto_tree_add_text(tree, tvb, offset, cap_loop_len, "%s", title);
1768 loop_tree = proto_item_add_subtree(ti, ett_dvbci_opp_cap_loop);
1770 for (i=0; i<cap_loop_len; i+=item_len) {
1771 proto_tree_add_item(loop_tree, item_hf,
1772 tvb, offset+i, item_len, ENC_BIG_ENDIAN);
1775 return cap_loop_len;
1779 /* dissect age rating byte encoded as defined in
1780 DVB-SI parental rating descriptor
1781 returns rating's length in bytes or -1 for error */
1783 dissect_rating(tvbuff_t *tvb, gint offset,
1784 packet_info *pinfo _U_, proto_tree *tree)
1788 rating = tvb_get_guint8(tvb, offset);
1789 if (1<=rating && rating<=0x0F) {
1790 proto_tree_add_uint_format(tree, hf_dvbci_rating,
1791 tvb, offset, 1, rating,
1792 "Rating is %d years (%d+3)", rating+3, rating);
1794 proto_tree_add_uint_format(tree, hf_dvbci_rating,
1795 tvb, offset, 1, rating,
1796 "Rating is unknown/undefined (%d)", rating);
1803 /* if there's a dissector for the protocol and target port of our
1804 lsc connection, store it in the lsc session's circuit */
1806 store_lsc_msg_dissector(circuit_t *circuit, guint8 ip_proto, guint16 port)
1808 dissector_handle_t msg_handle = NULL;
1813 if (ip_proto==LSC_TCP)
1814 msg_handle = dissector_get_uint_handle(tcp_dissector_table, port);
1815 else if (ip_proto==LSC_UDP)
1816 msg_handle = dissector_get_uint_handle(udp_dissector_table, port);
1818 circuit_set_dissector(circuit, msg_handle);
1822 /* dissect a connection_descriptor for the lsc resource
1823 returns its length or -1 for error */
1825 dissect_conn_desc(tvbuff_t *tvb, gint offset, circuit_t *circuit,
1826 packet_info *pinfo, proto_tree *tree)
1828 proto_item *ti = NULL;
1829 proto_tree *conn_desc_tree = NULL;
1831 gint offset_start, offset_body;
1833 guint8 conn_desc_type;
1834 guint8 ip_ver, ip_proto;
1836 proto_item *port_item = NULL;
1839 offset_start = offset;
1841 tag = tvb_get_ntoh24(tvb, offset);
1842 if (tag!= T_CONNECTION_DESCRIPTOR)
1845 ti = proto_tree_add_text(tree, tvb,
1846 offset_start, -1, "Connection descriptor");
1847 conn_desc_tree = proto_item_add_subtree(ti, ett_dvbci_lsc_conn_desc);
1849 proto_tree_add_item(conn_desc_tree, hf_dvbci_apdu_tag,
1850 tvb, offset, APDU_TAG_SIZE, ENC_BIG_ENDIAN);
1851 offset += APDU_TAG_SIZE;
1852 offset = dissect_ber_length(pinfo, conn_desc_tree,
1853 tvb, offset, &len_field, NULL);
1854 offset_body = offset;
1856 conn_desc_type = tvb_get_guint8(tvb, offset);
1857 proto_tree_add_item(conn_desc_tree, hf_dvbci_conn_desc_type,
1858 tvb, offset, 1, ENC_BIG_ENDIAN);
1861 if (conn_desc_type == CONN_DESC_IP) {
1862 proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_media_tag,
1863 tvb, offset, 1, ENC_BIG_ENDIAN);
1865 proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_media_len,
1866 tvb, offset, 1, ENC_BIG_ENDIAN);
1868 ip_ver = tvb_get_guint8(tvb, offset);
1869 proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_ip_ver,
1870 tvb, offset, 1, ENC_BIG_ENDIAN);
1873 if (ip_ver == LSC_IPV4) {
1874 offset += FT_IPv6_LEN-FT_IPv4_LEN;
1875 proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_ipv4_addr,
1876 tvb, offset, FT_IPv4_LEN, ENC_BIG_ENDIAN);
1877 offset += FT_IPv4_LEN;
1879 else if (ip_ver == LSC_IPV6) {
1880 proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_ipv6_addr,
1881 tvb, offset, FT_IPv6_LEN, ENC_NA);
1882 offset += FT_IPv6_LEN;
1885 offset += FT_IPv6_LEN;
1887 port = tvb_get_ntohs(tvb, offset);
1888 port_item = proto_tree_add_item(conn_desc_tree,
1889 hf_dvbci_lsc_dst_port, tvb, offset, 2, ENC_BIG_ENDIAN);
1891 ip_proto = tvb_get_guint8(tvb, offset);
1892 proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_proto,
1893 tvb, offset, 1, ENC_BIG_ENDIAN);
1896 if (ip_proto==LSC_TCP && ep_tcp_port_to_display(port)) {
1897 proto_item_append_text(port_item, " (%s)",
1898 ep_tcp_port_to_display(port));
1900 else if (ip_proto==LSC_UDP && ep_udp_port_to_display(port)) {
1901 proto_item_append_text(port_item, " (%s)",
1902 ep_udp_port_to_display(port));
1905 store_lsc_msg_dissector(circuit, ip_proto, port);
1907 } else if (conn_desc_type == CONN_DESC_HOSTNAME) {
1908 proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_media_tag,
1909 tvb, offset, 1, ENC_BIG_ENDIAN);
1911 proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_media_len,
1912 tvb, offset, 1, ENC_BIG_ENDIAN);
1914 ip_proto = tvb_get_guint8(tvb, offset);
1915 proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_proto,
1916 tvb, offset, 1, ENC_BIG_ENDIAN);
1918 port = tvb_get_ntohs(tvb, offset);
1919 port_item = proto_tree_add_item(conn_desc_tree,
1920 hf_dvbci_lsc_dst_port, tvb, offset, 2, ENC_BIG_ENDIAN);
1923 if (ip_proto==LSC_TCP && ep_tcp_port_to_display(port)) {
1924 proto_item_append_text(port_item, " (%s)",
1925 ep_tcp_port_to_display(port));
1927 else if (ip_proto==LSC_UDP && ep_udp_port_to_display(port)) {
1928 proto_item_append_text(port_item, " (%s)",
1929 ep_udp_port_to_display(port));
1932 store_lsc_msg_dissector(circuit, ip_proto, port);
1934 /* everything from here to the descriptor's end is a hostname */
1935 hostname_len = (offset_body+len_field)-offset;
1936 proto_tree_add_item(conn_desc_tree, hf_dvbci_lsc_hostname,
1937 tvb, offset, hostname_len, ENC_ASCII|ENC_NA);
1938 offset += hostname_len;
1940 proto_tree_add_text(conn_desc_tree, tvb,
1941 offset, len_field-1, "media specific data");
1942 offset += len_field-1;
1945 proto_item_set_len(ti, offset-offset_start);
1946 return offset-offset_start;
1950 /* check if the given CC resource item may appear in the clear
1951 as part of an exported PDU */
1952 static inline gboolean
1953 is_cc_item_exportable(guint8 dat_id)
1955 /* the CCK precursor value does not contain sensitive information as such
1956 nevertheless, it is safer to prevent people from exporting this value
1958 if (dat_id == CC_ID_KP)
1960 /* we could add some more items here which do not appear in SAC messages
1961 normally: CC_ID_DHPH, CC_ID_DHPM */
1967 /* dissect the URI, return the number of bytes processed or -1 for error */
1969 dissect_uri(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree)
1972 guint8 uri_ver, emi, rl;
1973 proto_item *rl_item;
1975 offset_start = offset;
1977 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "URI");
1979 uri_ver = tvb_get_guint8(tvb, offset);
1980 proto_tree_add_item(tree, hf_dvbci_uri_ver,
1981 tvb, offset, 1, ENC_BIG_ENDIAN);
1984 proto_tree_add_item(tree, hf_dvbci_uri_aps,
1985 tvb, offset, 1, ENC_BIG_ENDIAN);
1986 emi = (tvb_get_guint8(tvb, offset) & 0x30) >> 4;
1987 proto_tree_add_item(tree, hf_dvbci_uri_emi,
1988 tvb, offset, 1, ENC_BIG_ENDIAN);
1989 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "%s",
1990 val_to_str_const(emi, dvbci_cc_uri_emi, "unknown"));
1991 proto_tree_add_item(tree, hf_dvbci_uri_ict,
1992 tvb, offset, 1, ENC_BIG_ENDIAN);
1993 if (emi==CC_EMI_FREE) {
1994 proto_tree_add_item(tree, hf_dvbci_uri_rct,
1995 tvb, offset, 1, ENC_BIG_ENDIAN);
1997 if (uri_ver>=2 && emi==CC_EMI_NEVER) {
1998 proto_tree_add_item(tree, hf_dvbci_uri_dot,
1999 tvb, offset, 1, ENC_BIG_ENDIAN);
2003 if (emi==CC_EMI_NEVER) {
2005 rl = tvb_get_guint8(tvb, offset) & 0x3F;
2007 rl = tvb_get_guint8(tvb, offset);
2009 rl_item = proto_tree_add_uint(tree, hf_dvbci_uri_rl,
2010 tvb, offset, 1, rl);
2013 proto_item_append_text(rl_item, " (90 minutes)");
2015 proto_item_append_text(rl_item, " (6 hours)");
2017 proto_item_append_text(rl_item, " (12 hours)");
2018 else if (uri_ver>=2 && rl==0xFF)
2019 proto_item_append_text(rl_item, " (unlimited)");
2021 /* no need for a range check, rl 0x3F mask was applied above */
2022 proto_item_append_text(rl_item, " (%d days)", rl-2);
2026 return offset-offset_start;
2030 /* dissect an item from cc_(sac_)data_req/cc_(sac_)data_cnf,
2031 returns its length or -1 for error
2032 if dat_id_ptr is not NULL, fill in the datatype id */
2034 dissect_cc_item(tvbuff_t *tvb, gint offset,
2035 packet_info *pinfo, proto_tree *tree, guint8 *dat_id_ptr)
2037 proto_item *ti = NULL;
2038 proto_tree *cc_item_tree = NULL;
2042 asn1_ctx_t asn1_ctx;
2048 offset_start = offset;
2049 dat_id = tvb_get_guint8(tvb, offset);
2051 *dat_id_ptr = dat_id;
2053 ti = proto_tree_add_text(tree, tvb, offset_start, -1, "CC data item: %s",
2054 val_to_str_const(dat_id, dvbci_cc_dat_id, "unknown"));
2055 cc_item_tree = proto_item_add_subtree(ti, ett_dvbci_cc_item);
2057 proto_tree_add_item(cc_item_tree, hf_dvbci_cc_dat_id,
2058 tvb, offset, 1, ENC_BIG_ENDIAN);
2060 dat_len = tvb_get_ntohs(tvb, offset);
2061 proto_tree_add_text(cc_item_tree, tvb, offset, 2, "Length: %d", dat_len);
2064 case CC_ID_HOST_BRAND_CERT:
2065 case CC_ID_CICAM_BRAND_CERT:
2066 case CC_ID_HOST_DEV_CERT:
2067 case CC_ID_CICAM_DEV_CERT:
2068 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2069 hf_cert_index = (dat_id==CC_ID_HOST_BRAND_CERT ||
2070 dat_id==CC_ID_CICAM_BRAND_CERT) ?
2071 hf_dvbci_brand_cert : hf_dvbci_dev_cert;
2073 /* enable dissection of CI+ specific X.509 extensions
2074 only for our certificates */
2075 x509ce_enable_ciplus();
2076 dissect_x509af_Certificate(FALSE, tvb, offset,
2077 &asn1_ctx, cc_item_tree, hf_cert_index);
2078 x509ce_disable_ciplus();
2081 dissect_uri(tvb, offset, pinfo, cc_item_tree);
2083 case CC_ID_PROG_NUM:
2084 prog_num = tvb_get_ntohs(tvb, offset);
2085 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
2086 "Program number 0x%x", prog_num);
2087 proto_tree_add_item(cc_item_tree, hf_dvbci_cc_prog_num,
2088 tvb, offset, 2, ENC_BIG_ENDIAN);
2090 case CC_ID_KEY_REGISTER:
2091 proto_tree_add_item(cc_item_tree, hf_dvbci_cc_key_register,
2092 tvb, offset, 1, ENC_BIG_ENDIAN);
2094 case CC_ID_STATUS_FIELD:
2095 case CC_ID_REC_START_STATUS:
2096 case CC_ID_MODE_CHG_STATUS:
2097 case CC_ID_REC_STOP_STATUS:
2098 status = tvb_get_guint8(tvb, offset);
2099 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Status: %s",
2100 val_to_str_const(status, dvbci_cc_status, "unknown"));
2101 proto_tree_add_item(cc_item_tree, hf_dvbci_cc_status_field,
2102 tvb, offset, 1, ENC_BIG_ENDIAN);
2104 case CC_ID_OPERATING_MODE:
2105 proto_tree_add_item(cc_item_tree, hf_dvbci_cc_op_mode,
2106 tvb, offset, 1, ENC_BIG_ENDIAN);
2109 proto_tree_add_item(cc_item_tree, hf_dvbci_cc_data,
2110 tvb, offset, dat_len, ENC_NA);
2115 proto_item_set_len(ti, offset-offset_start);
2116 return offset-offset_start;
2120 /* add the CC protocol name and step to the info column */
2122 add_cc_protocol_name_step(packet_info *pinfo,
2123 guint64 snd_dat_ids, guint64 req_dat_ids)
2125 gboolean chk_snd_ids = FALSE;
2127 switch (req_dat_ids) {
2128 case CC_ID_DHPH<<24|CC_ID_SIG_A<<16|CC_ID_HOST_DEV_CERT<<8|CC_ID_HOST_BRAND_CERT:
2129 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2130 "(Authentication Step 1)");
2132 case CC_ID_STATUS_FIELD:
2133 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2134 "(Authentication Step 3)");
2137 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2138 "(AuthKey Step 1)");
2140 case CC_ID_HOST_ID<<8|CC_ID_STATUS_FIELD:
2141 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2142 "(CC key calculation Step 1)");
2144 case CC_ID_HOST_ID<<8|CC_ID_NS_HOST:
2145 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2146 "(SAC key calculation Step 1)");
2149 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2150 "(URI transmission Step 1)");
2152 case CC_ID_URI_VERSIONS:
2153 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2154 "(URI version negotiation Step 1)");
2156 case CC_ID_LICENSE_RCV_STATUS:
2157 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2158 "(CICAM to Host License Exchange Step 1)");
2160 case CC_ID_PROG_NUM<<24|CC_ID_LICENSE_STATUS<<16|CC_ID_URI<<8|CC_ID_CICAM_LICENSE:
2161 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2162 "(Playback License Exchange Step 1)");
2164 case CC_ID_LICENSE_STATUS<<8|CC_ID_PLAY_COUNT:
2165 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2166 "(License Check Exchange Step 1)");
2168 case CC_ID_REC_START_STATUS:
2169 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2170 "(Record Start Step 1)");
2172 case CC_ID_MODE_CHG_STATUS:
2173 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2174 "(Change Operating Mode Step 1)");
2176 case CC_ID_REC_STOP_STATUS:
2177 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2178 "(Record Stop Step 1)");
2180 case CC_ID_STATUS_FIELD<<8|CC_ID_SRM_CONFIRM:
2181 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2182 "(SRM Transmission Step 1)");
2185 /* unable to determine the protocol from the requested ids
2186 check the sent ids as well */
2193 switch (snd_dat_ids) {
2194 case CC_ID_DHPH<<24|CC_ID_SIG_A<<16|CC_ID_HOST_DEV_CERT<<8|CC_ID_HOST_BRAND_CERT:
2195 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2196 "(Authentication Step 2)");
2198 case CC_ID_STATUS_FIELD:
2199 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2200 "(Authentication Step 4)");
2203 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2204 "(AuthKey Step 2)");
2206 case CC_ID_HOST_ID<<8|CC_ID_STATUS_FIELD:
2207 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2208 "(CC key calculation Step 2)");
2210 case CC_ID_HOST_ID<<8|CC_ID_NS_HOST:
2211 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2212 "(SAC key calculation Step 2)");
2215 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2216 "(URI transmission Step 2)");
2218 case CC_ID_URI_VERSIONS:
2219 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2220 "(URI version negotiation Step 2)");
2222 case CC_ID_LICENSE_RCV_STATUS:
2223 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2224 "(CICAM to Host License Exchange Step 2)");
2226 case CC_ID_PROG_NUM<<24|CC_ID_LICENSE_STATUS<<16|CC_ID_URI<<8|CC_ID_CICAM_LICENSE:
2227 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2228 "(Playback License Exchange Step 2)");
2230 case CC_ID_LICENSE_STATUS<<8|CC_ID_PLAY_COUNT:
2231 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2232 "(License Check Exchange Step 2)");
2234 case CC_ID_REC_START_STATUS:
2235 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2236 "(Record Start Step 2)");
2238 case CC_ID_MODE_CHG_STATUS:
2239 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2240 "(Change Operating Mode Step 2)");
2242 case CC_ID_REC_STOP_STATUS:
2243 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2244 "(Record Stop Step 2)");
2246 case CC_ID_STATUS_FIELD<<8|CC_ID_SRM_CONFIRM:
2247 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
2248 "(SRM Transmission Step 2)");
2254 /* dissect the payload of a cc message that contains data items
2255 if not NULL, set exportable_flag to TRUE if the message contains no
2256 sensitive data and can be passed to the export PDU mechanism */
2258 dissect_cc_data_payload(guint32 tag, tvbuff_t *tvb, gint offset,
2259 packet_info *pinfo, proto_tree *tree, gboolean *exportable_flag)
2262 guint8 i, snd_dat_nbr, req_dat_nbr;
2265 /* the last 8 sent/requested datatype ids */
2266 guint64 snd_dat_ids=0, req_dat_ids=0;
2268 /* we only export cc_sac_data_req and cc_sac_data_cnf
2269 the only meta info in the exported PDU is the data transfer
2270 direction, if we only ever export cc_sac_data_req and
2271 cc_sac_data_cnf, this info is enough to recover the apdu tag from the
2273 cc_sac_sync req and cc_sac_sync_cnf contain no interesting data */
2274 if (exportable_flag)
2275 *exportable_flag = (tag==T_CC_SAC_DATA_REQ || tag==T_CC_SAC_DATA_CNF);
2277 offset_start = offset;
2279 proto_tree_add_item(
2280 tree, hf_dvbci_cc_sys_id_bitmask, tvb, offset, 1, ENC_BIG_ENDIAN);
2282 snd_dat_nbr = tvb_get_guint8(tvb, offset);
2283 proto_tree_add_text(tree, tvb, offset, 1,
2284 "Number of sent data items: %d", snd_dat_nbr);
2286 for(i=0; i<snd_dat_nbr &&
2287 tvb_reported_length_remaining(tvb, offset)>0; i++) {
2288 item_len = dissect_cc_item(tvb, offset, pinfo, tree, &dat_id);
2292 /* for more than 8 sent datatype ids, some ids might get lost by
2293 * the shift, that's ok, we're only using the last 8 ids for
2294 * protocol detection */
2295 snd_dat_ids = snd_dat_ids<<8|dat_id;
2296 if (!exportable_flag || *exportable_flag==FALSE)
2298 if (!is_cc_item_exportable(dat_id))
2299 *exportable_flag = FALSE;
2302 if (tag==T_CC_DATA_REQ || tag==T_CC_SAC_DATA_REQ) {
2303 req_dat_nbr = tvb_get_guint8(tvb, offset);
2304 proto_tree_add_text(tree, tvb, offset, 1,
2305 "Number of requested data items: %d", req_dat_nbr);
2307 for(i=0; i<req_dat_nbr &&
2308 tvb_reported_length_remaining(tvb, offset)>0; i++) {
2309 dat_id = tvb_get_guint8(tvb, offset);
2310 req_dat_ids = req_dat_ids<<8|dat_id;
2311 proto_tree_add_item(
2312 tree, hf_dvbci_cc_dat_id, tvb, offset, 1, ENC_BIG_ENDIAN);
2317 add_cc_protocol_name_step(pinfo, snd_dat_ids, req_dat_ids);
2319 return offset-offset_start;
2323 #ifdef HAVE_LIBGCRYPT
2324 /* convert a 0-terminated preference key_string that contains a hex number
2325 * into its binary representation
2326 * e.g. key_string "abcd" will be converted into two bytes 0xab, 0xcd
2327 * return the number of binary bytes or -1 for error */
2329 pref_key_string_to_bin(const gchar *key_string, unsigned char **key_bin)
2335 if (!key_string || !key_bin)
2337 key_string_len = (int)strlen(key_string);
2338 if (key_string_len != 2*AES_KEY_LEN)
2340 *key_bin = (unsigned char*)g_malloc(key_string_len/2);
2344 for (i=0; i<key_string_len-1; i+=2) {
2345 input[0] = key_string[0+i];
2346 input[1] = key_string[1+i];
2347 /* attention, brackets are required */
2348 (*key_bin)[j++] = (unsigned char)strtoul((const char*)&input, NULL, 16);
2351 return key_string_len/2;
2356 decrypt_sac_msg_body(
2357 guint8 enc_cip, tvbuff_t *encrypted_tvb, gint offset, gint len)
2359 gboolean opened = FALSE;
2360 gcry_cipher_hd_t cipher;
2363 unsigned char *clear_data = NULL;
2364 tvbuff_t *clear_tvb = NULL;
2366 if (enc_cip != CC_SAC_ENC_AES128_CBC)
2368 if (len%AES_BLOCK_LEN != 0)
2371 if (!dvbci_sek_bin || !dvbci_siv_bin)
2374 err = gcry_cipher_open(&cipher, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0);
2375 if (gcry_err_code (err))
2378 err = gcry_cipher_setkey (cipher, dvbci_sek_bin, AES_KEY_LEN);
2379 if (gcry_err_code (err))
2381 err = gcry_cipher_setiv (cipher, dvbci_siv_bin, AES_BLOCK_LEN);
2382 if (gcry_err_code (err))
2386 clear_data = (unsigned char *)g_malloc(clear_len);
2388 err = gcry_cipher_decrypt (cipher, clear_data, clear_len,
2389 tvb_memdup(wmem_packet_scope(), encrypted_tvb, offset, len), len);
2390 if (gcry_err_code (err))
2393 clear_tvb = tvb_new_child_real_data(encrypted_tvb,
2394 (const guint8 *)clear_data, clear_len, clear_len);
2395 tvb_set_free_cb(clear_tvb, g_free);
2399 gcry_cipher_close (cipher);
2400 if (!clear_tvb && clear_data)
2406 /* HAVE_LIBGRYPT is not set */
2408 pref_key_string_to_bin(const gchar *key_string _U_, unsigned char **key_bin _U_)
2414 decrypt_sac_msg_body(guint8 enc_cip _U_,
2415 tvbuff_t *encrypted_tvb _U_, gint offset _U_, gint len _U_)
2423 /* dissect a text string that is encoded according to DVB-SI (EN 300 468) */
2425 dissect_si_string(tvbuff_t *tvb, gint offset, gint str_len,
2426 packet_info *pinfo, proto_tree *tree, int hf, const gchar *title,
2427 gboolean show_col_info)
2430 dvb_encoding_e encoding;
2431 guint8 *si_str = NULL;
2433 if (!title) /* we always have a title for our strings */
2435 /* str_len==-1 is not supported, we need an actual length */
2439 enc_len = dvb_analyze_string_charset(tvb, offset, str_len, &encoding);
2440 dvb_add_chartbl(tree, hf_dvbci_mmi_char_tbl, tvb, offset, enc_len, encoding);
2445 si_str = tvb_get_string_enc(wmem_packet_scope(),
2446 tvb, offset, str_len, dvb_enc_to_item_enc(encoding));
2450 proto_tree_add_string_format(tree, hf,
2451 tvb, offset, str_len, si_str, "%s: %s", title, si_str);
2454 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "%s", si_str);
2458 /* dissect ca_enable_flag and ca_enable fields in the ca_pmt_reply
2459 * return true if descrambling is possible, false otherwise */
2461 dissect_ca_enable(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_,
2464 gboolean desc_ok = FALSE;
2465 guint8 byte, ca_enab;
2467 byte = tvb_get_guint8(tvb,offset);
2468 proto_tree_add_item(tree, hf_dvbci_ca_enable_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
2470 ca_enab = byte & ~0x80;
2471 proto_tree_add_item(tree, hf_dvbci_ca_enable, tvb, offset, 1, ENC_BIG_ENDIAN);
2472 if (ca_enab==CA_ENAB_DESC_OK ||
2473 ca_enab==CA_ENAB_DESC_OK_PURCHASE ||
2474 ca_enab==CA_ENAB_DESC_OK_TECH) {
2483 /* dissect a ca descriptor in the ca_pmt */
2485 dissect_ca_desc(tvbuff_t *tvb, gint offset, packet_info *pinfo,
2489 guint8 tag, len_byte;
2490 proto_item *ti = NULL;
2491 proto_tree *ca_desc_tree = NULL;
2493 offset_start = offset;
2495 tag = tvb_get_guint8(tvb,offset);
2496 if (tag != CA_DESC_TAG) {
2497 /* we could skip unknown descriptors and make this a warning */
2498 proto_tree_add_expert(tree, pinfo, &ei_dvbci_ca_pmt_cmd_id, tvb, offset, 1);
2502 ti = proto_tree_add_text(
2503 tree, tvb, offset_start, -1, "Conditional Access descriptor");
2504 ca_desc_tree = proto_item_add_subtree(ti, ett_dvbci_ca_desc);
2507 len_byte = tvb_get_guint8(tvb,offset);
2508 proto_tree_add_item(
2509 ca_desc_tree, hf_dvbci_descr_len, tvb, offset, 1, ENC_BIG_ENDIAN);
2512 proto_tree_add_item(
2513 ca_desc_tree, hf_dvbci_ca_sys_id, tvb, offset, 2, ENC_BIG_ENDIAN);
2516 proto_tree_add_item(
2517 ca_desc_tree, hf_dvbci_ca_pid, tvb, offset, 2, ENC_BIG_ENDIAN);
2520 if ((len_byte-4) != 0) {
2521 proto_tree_add_text(
2522 ca_desc_tree, tvb, offset, len_byte-4, "private data");
2523 offset += (len_byte-4);
2526 proto_item_set_len(ti, offset-offset_start);
2527 return offset-offset_start;
2531 /* dissect an elementary stream entry in the ca_pmt */
2533 dissect_es(tvbuff_t *tvb, gint offset,
2534 packet_info *pinfo, proto_tree *tree, gboolean *scrambled)
2536 proto_item *ti = NULL;
2537 proto_tree *es_tree = NULL;
2538 gint offset_start, ca_desc_len;
2539 gint es_info_len, all_len;
2541 offset_start = offset;
2544 /* default to free service until we found a ca descriptor
2545 (we could have es info len > 0 and no ca descriptors) */
2549 ti = proto_tree_add_text(tree, tvb, offset_start, -1, "Elementary Stream");
2550 es_tree = proto_item_add_subtree(ti, ett_dvbci_application);
2552 proto_tree_add_item(
2553 es_tree, hf_dvbci_stream_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2555 proto_tree_add_item(
2556 es_tree, hf_dvbci_es_pid, tvb, offset, 2, ENC_BIG_ENDIAN);
2558 es_info_len = tvb_get_ntohs(tvb, offset) & 0x0FFF;
2559 /* the definition of hf_dvbci_es_info_len also applies the mask */
2560 proto_tree_add_item(
2561 es_tree, hf_dvbci_es_info_len, tvb, offset, 2, ENC_BIG_ENDIAN);
2563 if (es_info_len>0) {
2564 all_len = offset + es_info_len;
2566 proto_tree_add_item(
2567 es_tree, hf_dvbci_ca_pmt_cmd_id, tvb, offset, 1, ENC_BIG_ENDIAN);
2569 while (offset < all_len) {
2570 ca_desc_len = dissect_ca_desc(tvb, offset, pinfo, es_tree);
2571 if (ca_desc_len <= 0)
2573 offset += ca_desc_len;
2579 proto_tree_add_text(
2581 "No CA descriptors for this elementary stream");
2584 proto_item_set_len(ti, offset-offset_start);
2585 return offset-offset_start;
2588 /* dissect a text pseudo-apdu */
2590 dissect_dvbci_text(const gchar *title, tvbuff_t *tvb, gint offset,
2591 packet_info *pinfo, proto_tree *tree, int hf)
2593 proto_item *ti = NULL;
2594 proto_tree *text_tree;
2599 offset_start = offset;
2604 /* check the tag before setting up the tree */
2605 tag = tvb_get_ntoh24(tvb, offset);
2606 if (tag!=T_TEXT_LAST && tag!=T_TEXT_MORE)
2609 ti = proto_tree_add_text(tree, tvb, offset_start, -1, "%s", title);
2610 text_tree = proto_item_add_subtree(ti, ett_dvbci_text);
2612 proto_tree_add_item(text_tree, hf_dvbci_apdu_tag,
2613 tvb, offset, APDU_TAG_SIZE, ENC_BIG_ENDIAN);
2614 offset += APDU_TAG_SIZE;
2615 offset = dissect_ber_length(pinfo, text_tree, tvb, offset, &len_field, NULL);
2616 dissect_si_string(tvb, offset, len_field, pinfo, text_tree,
2618 offset += len_field;
2620 proto_item_set_len(ti, offset-offset_start);
2621 return (offset-offset_start);
2626 dissect_res_id(tvbuff_t *tvb, gint offset, packet_info *pinfo,
2627 proto_tree *tree, guint32 res_id, gboolean show_col_info)
2629 proto_item *ti = NULL;
2630 proto_tree *res_tree = NULL;
2633 /* there's two possible inputs for this function
2634 the resource id is either in a tvbuff_t (tvb!=NULL, res_id==0)
2635 or in a guint32 (tvb==NULL, res_id!=0) */
2638 /* resource id comes in via tvbuff */
2641 res_id = tvb_get_ntohl(tvb, offset);
2642 tvb_data_len = RES_ID_LEN;
2645 /* resource id comes in via guint32 */
2648 /* we'll call proto_tree_add_...( tvb==NULL, offset==0, length==0 )
2649 this creates a filterable item without any reference to a tvb */
2654 if (show_col_info) {
2655 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "%s Version %d",
2656 val_to_str_const(RES_CLASS(res_id), dvbci_res_class,
2657 "Invalid Resource class"),
2661 ti = proto_tree_add_text(tree, tvb, offset, tvb_data_len,
2662 "Resource ID: 0x%04x", res_id);
2663 res_tree = proto_item_add_subtree(ti, ett_dvbci_res);
2665 /* parameter "value" == complete resource id,
2666 RES_..._MASK will be applied by the hf definition */
2667 proto_tree_add_uint(res_tree, hf_dvbci_res_id_type,
2668 tvb, offset, tvb_data_len, res_id);
2669 proto_tree_add_uint(res_tree, hf_dvbci_res_class,
2670 tvb, offset, tvb_data_len, res_id);
2671 proto_tree_add_uint(res_tree, hf_dvbci_res_type,
2672 tvb, offset, tvb_data_len, res_id);
2673 proto_tree_add_uint(res_tree, hf_dvbci_res_ver,
2674 tvb, offset, tvb_data_len, res_id);
2679 /* dissect the body of a resource manager apdu */
2681 dissect_dvbci_payload_rm(guint32 tag, gint len_field,
2682 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
2683 packet_info *pinfo, proto_tree *tree)
2685 const gchar *tag_str;
2687 if (tag==T_PROFILE) {
2688 if (len_field % RES_ID_LEN) {
2689 tag_str = val_to_str(tag, dvbci_apdu_tag, "Unknown: %d");
2690 proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb, 0, APDU_TAG_SIZE,
2691 "Invalid APDU length field, %s must be a multiple of 4 bytes",
2696 while (tvb_reported_length_remaining(tvb, offset) > 0) {
2697 dissect_res_id(tvb, offset, pinfo, tree, 0, FALSE);
2698 offset += RES_ID_LEN;
2704 dissect_dvbci_payload_ap(guint32 tag, gint len_field _U_,
2705 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
2706 packet_info *pinfo, proto_tree *tree)
2708 guint8 menu_str_len;
2710 dvb_encoding_e encoding;
2711 guint8 *menu_string;
2714 if (tag==T_APP_INFO) {
2715 proto_tree_add_item(tree, hf_dvbci_app_type, tvb, offset, 1, ENC_BIG_ENDIAN);
2717 proto_tree_add_item(
2718 tree, hf_dvbci_app_manf, tvb, offset, 2, ENC_BIG_ENDIAN);
2720 proto_tree_add_item(
2721 tree, hf_dvbci_manf_code, tvb, offset, 2, ENC_BIG_ENDIAN);
2723 menu_str_len = tvb_get_guint8(tvb,offset);
2724 proto_tree_add_item(
2725 tree, hf_dvbci_menu_str_len, tvb, offset, 1, ENC_BIG_ENDIAN);
2727 if (menu_str_len > 0) {
2728 enc_len = dvb_analyze_string_charset(
2729 tvb, offset, menu_str_len, &encoding);
2731 tree, hf_dvbci_ap_char_tbl, tvb, offset, enc_len, encoding);
2733 menu_str_len -= enc_len;
2734 menu_string = tvb_get_string_enc(wmem_packet_scope(),
2735 tvb, offset, menu_str_len, dvb_enc_to_item_enc(encoding));
2736 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
2737 "Module name %s", menu_string);
2738 proto_tree_add_string_format(tree, hf_dvbci_menu_str,
2739 tvb, offset, menu_str_len, menu_string,
2740 "Menu string: %s", menu_string);
2743 else if (tag== T_DATARATE_INFO) {
2744 data_rate = tvb_get_guint8(tvb, offset);
2745 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s",
2746 val_to_str(data_rate, dvbci_data_rate, "unknown (0x%x)"));
2747 proto_tree_add_item(tree, hf_dvbci_data_rate, tvb, offset, 1, ENC_BIG_ENDIAN);
2752 dissect_dvbci_payload_ca(guint32 tag, gint len_field,
2753 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
2754 packet_info *pinfo, proto_tree *tree)
2756 const gchar *tag_str;
2760 guint prog_info_len;
2761 gint es_info_len, all_len;
2763 gboolean scrambled = FALSE;
2764 gboolean es_scrambled = FALSE;
2765 proto_tree *es_tree = NULL;
2766 gboolean desc_ok = FALSE;
2769 if (tag==T_CA_INFO) {
2770 if (len_field % 2) {
2771 tag_str = val_to_str(tag, dvbci_apdu_tag, "Unknown: %d");
2772 proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb, 0, APDU_TAG_SIZE,
2773 "Invalid APDU length field, %s must be a multiple of 2 bytes",
2778 while (tvb_reported_length_remaining(tvb, offset) > 0) {
2779 proto_tree_add_item(
2780 tree, hf_dvbci_ca_sys_id, tvb, offset, 2, ENC_BIG_ENDIAN);
2784 else if (tag==T_CA_PMT) {
2785 proto_tree_add_item(
2786 tree, hf_dvbci_ca_pmt_list_mgmt, tvb, offset, 1, ENC_BIG_ENDIAN);
2788 prog_num = tvb_get_ntohs(tvb, offset);
2789 col_append_sep_fstr(
2790 pinfo->cinfo, COL_INFO, NULL, "Program number %x", prog_num);
2791 proto_tree_add_item(
2792 tree, hf_dvbci_prog_num, tvb, offset, 2, ENC_BIG_ENDIAN);
2794 byte = tvb_get_guint8(tvb,offset);
2795 proto_tree_add_text(tree, tvb, offset, 1,
2796 "Version number: 0x%x, Current-next indicator: 0x%x",
2797 (byte&0x3E) >> 1, byte&0x01);
2799 prog_info_len = tvb_get_ntohs(tvb, offset) & 0x0FFF;
2800 /* the definition of hf_dvbci_prog_info_len also applies the mask */
2801 proto_tree_add_item(
2802 tree, hf_dvbci_prog_info_len, tvb, offset, 2, ENC_BIG_ENDIAN);
2804 if (prog_info_len != 0) {
2805 all_len = offset + prog_info_len;
2807 proto_tree_add_item(
2808 tree, hf_dvbci_ca_pmt_cmd_id, tvb, offset, 1, ENC_BIG_ENDIAN);
2810 while (offset < all_len) {
2811 ca_desc_len = dissect_ca_desc(tvb, offset, pinfo, tree);
2812 if (ca_desc_len <= 0)
2814 offset += ca_desc_len;
2815 /* set this only if we've seen at least one valid ca descriptor */
2820 proto_tree_add_text(
2821 tree, tvb, 0, 0, "No CA descriptors at program level");
2824 while (tvb_reported_length_remaining(tvb, offset) > 0) {
2825 es_info_len = dissect_es(tvb, offset, pinfo, tree, &es_scrambled);
2826 if (es_info_len <= 0)
2828 offset += es_info_len;
2833 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
2834 scrambled ? "scrambled service" : "free service");
2836 else if (tag==T_CA_PMT_REPLY) {
2837 prog_num = tvb_get_ntohs(tvb, offset);
2838 col_append_sep_fstr(
2839 pinfo->cinfo, COL_INFO, NULL, "Program number %x", prog_num);
2840 proto_tree_add_item(
2841 tree, hf_dvbci_prog_num, tvb, offset, 2, ENC_BIG_ENDIAN);
2843 byte = tvb_get_guint8(tvb,offset);
2844 proto_tree_add_text(tree, tvb, offset, 1,
2845 "Version number: 0x%x, Current-next indicator: 0x%x",
2846 (byte&0x3E) >> 1, byte&0x01);
2848 desc_ok |= dissect_ca_enable(tvb, offset, pinfo, tree);
2850 while (tvb_reported_length_remaining(tvb, offset) > 0) {
2851 /* there's no need to check for tree==NULL */
2852 pi = proto_tree_add_text(tree, tvb, offset, 3, "Elementary Stream");
2853 es_tree = proto_item_add_subtree(pi, ett_dvbci_application);
2855 proto_tree_add_item(es_tree, hf_dvbci_es_pid,
2856 tvb, offset, 2, ENC_BIG_ENDIAN);
2858 desc_ok |= dissect_ca_enable(tvb, offset, pinfo, es_tree);
2862 col_append_sep_fstr(
2863 pinfo->cinfo, COL_INFO, NULL, "descrambling possible");
2870 dissect_dvbci_payload_aut(guint32 tag, gint len_field _U_,
2871 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
2872 packet_info *pinfo _U_, proto_tree *tree)
2876 proto_tree_add_item(tree, hf_dvbci_auth_proto_id,
2877 tvb, offset, 2, ENC_BIG_ENDIAN);
2880 bytes_len = tvb_reported_length_remaining(tvb, offset);
2884 if (tag==T_AUTH_REQ) {
2885 proto_tree_add_item(tree, hf_dvbci_auth_req_bytes,
2886 tvb, offset, bytes_len, ENC_NA);
2888 else if (tag==T_AUTH_RESP) {
2889 proto_tree_add_item(tree, hf_dvbci_auth_resp_bytes,
2890 tvb, offset, bytes_len, ENC_NA);
2896 dissect_dvbci_payload_hc(guint32 tag, gint len_field _U_,
2897 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
2898 packet_info *pinfo, proto_tree *tree)
2901 guint16 nid, onid, tsid, svcid;
2903 guint16 old_pid, new_pid;
2906 tvbuff_t *pmt_tvb = NULL;
2912 nid = tvb_get_ntohs(tvb, offset);
2913 pi = proto_tree_add_item(
2914 tree, hf_dvbci_network_id, tvb, offset, 2, ENC_BIG_ENDIAN);
2916 expert_add_info(pinfo, pi, &ei_dvbci_network_id);
2919 onid = tvb_get_ntohs(tvb, offset);
2920 proto_tree_add_item(tree, hf_dvbci_original_network_id,
2921 tvb, offset, 2, ENC_BIG_ENDIAN);
2923 tsid = tvb_get_ntohs(tvb, offset);
2924 proto_tree_add_item(tree, hf_dvbci_transport_stream_id,
2925 tvb, offset, 2, ENC_BIG_ENDIAN);
2927 svcid = tvb_get_ntohs(tvb, offset);
2928 proto_tree_add_item(
2929 tree, hf_dvbci_service_id, tvb, offset, 2, ENC_BIG_ENDIAN);
2930 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
2931 "nid 0x%x, onid 0x%x, tsid 0x%x, svcid 0x%x",
2932 nid, onid, tsid, svcid);
2935 ref = tvb_get_guint8(tvb, offset);
2936 proto_tree_add_item(tree, hf_dvbci_replacement_ref,
2937 tvb, offset, 1, ENC_BIG_ENDIAN);
2939 old_pid = tvb_get_ntohs(tvb, offset) & 0x1FFF;
2940 proto_tree_add_item(tree, hf_dvbci_replaced_pid,
2941 tvb, offset, 2, ENC_BIG_ENDIAN);
2943 new_pid = tvb_get_ntohs(tvb, offset) & 0x1FFF;
2944 proto_tree_add_item( tree, hf_dvbci_replacement_pid,
2945 tvb, offset, 2, ENC_BIG_ENDIAN);
2946 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
2947 "ref 0x%x, 0x%x -> 0x%x", ref, old_pid, new_pid);
2949 case T_CLEAR_REPLACE:
2950 ref = tvb_get_guint8(tvb, offset);
2951 proto_tree_add_item(tree, hf_dvbci_replacement_ref,
2952 tvb, offset, 1, ENC_BIG_ENDIAN);
2953 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "ref 0x%x", ref);
2955 case T_TUNE_BROADCAST_REQ:
2956 pmt_flag = ((tvb_get_guint8(tvb, offset) & 0x01) == 0x01);
2957 proto_tree_add_item(tree, hf_dvbci_pmt_flag,
2958 tvb, offset, 1, ENC_BIG_ENDIAN);
2960 proto_tree_add_item(
2961 tree, hf_dvbci_service_id, tvb, offset, 2, ENC_BIG_ENDIAN);
2963 desc_loop_len = dissect_desc_loop(hf_dvbci_hc_desc_loop_len,
2964 tvb, offset, pinfo, tree);
2965 if (desc_loop_len<0)
2967 offset += desc_loop_len;
2969 pmt_tvb = tvb_new_subset_remaining(tvb, offset);
2970 if (mpeg_pmt_handle) {
2971 col_append_str(pinfo->cinfo, COL_INFO, ", ");
2972 /* prevent mpeg_pmt dissector from clearing col_info */
2973 col_set_fence(pinfo->cinfo, COL_INFO);
2974 call_dissector(mpeg_pmt_handle, pmt_tvb, pinfo, tree);
2977 call_dissector(data_handle, pmt_tvb, pinfo, tree);
2981 status = tvb_get_guint8(tvb, offset);
2982 proto_tree_add_item(tree, hf_dvbci_hc_status,
2983 tvb, offset, 1, ENC_BIG_ENDIAN);
2984 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
2985 (status == HC_STAT_OK ? "ok" : "error"));
2987 case T_ASK_RELEASE_REPLY:
2988 proto_tree_add_item(tree, hf_dvbci_hc_release_reply,
2989 tvb, offset, 1, ENC_BIG_ENDIAN);
2998 dissect_dvbci_payload_dt(guint32 tag, gint len_field,
2999 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
3000 packet_info *pinfo, proto_tree *tree)
3003 proto_item *pi = NULL;
3004 const gchar *tag_str;
3005 gint time_field_len;
3007 gint16 local_offset; /* field in the apdu */
3010 if (tag==T_DATE_TIME_ENQ) {
3011 nstime_set_zero(&resp_intv);
3012 resp_intv.secs = tvb_get_guint8(tvb, offset);
3013 pi = proto_tree_add_time(tree, hf_dvbci_resp_intv,
3014 tvb, offset, 1, &resp_intv);
3015 if (resp_intv.secs==0) {
3016 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "individual query");
3018 proto_item_append_text(pi, " (individual query)");
3021 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
3022 "update every %s", rel_time_to_str(wmem_packet_scope(), &resp_intv));
3025 else if (tag==T_DATE_TIME) {
3026 if (len_field!=5 && len_field!=7) {
3027 tag_str = val_to_str_const(tag, dvbci_apdu_tag, "unknown");
3028 proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb, APDU_TAG_SIZE, offset-APDU_TAG_SIZE,
3029 "Invalid APDU length field, %s must be 5 or 7 bytes", tag_str);
3033 time_field_len = packet_mpeg_sect_mjd_to_utc_time(tvb, offset, &utc_time);
3034 if (time_field_len<0) {
3035 proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb, offset, 5,
3036 "Invalid UTC time field, 2 bytes MJD, 3 bytes BCD time hhmmss");
3039 proto_tree_add_time(tree, hf_dvbci_utc_time,
3040 tvb, offset, time_field_len, &utc_time);
3041 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s UTC",
3042 abs_time_to_str(wmem_packet_scope(), &utc_time, ABSOLUTE_TIME_UTC, FALSE));
3043 offset += time_field_len;
3046 local_offset = two_comp_to_int16(tvb_get_ntohs(tvb, offset));
3047 proto_tree_add_int_format(tree, hf_dvbci_local_offset,
3048 tvb, offset, 2, local_offset,
3049 "offset between UTC and local time is %d minutes",
3053 proto_tree_add_text(tree, tvb, 0, 0,
3054 "Offset between UTC and local time is unknown");
3061 dissect_dvbci_payload_mmi(guint32 tag, gint len_field,
3062 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
3063 packet_info *pinfo, proto_tree *tree)
3066 guint8 close_mmi_cmd_id;
3067 guint8 disp_ctl_cmd, disp_rep_id;
3068 const gchar *disp_ctl_cmd_str = NULL, *disp_rep_id_str = NULL;
3071 dvb_encoding_e encoding;
3074 guint8 choice_or_item_nb;
3079 offset_start = offset;
3083 close_mmi_cmd_id = tvb_get_guint8(tvb,offset);
3084 proto_tree_add_item(tree, hf_dvbci_close_mmi_cmd_id,
3085 tvb, offset, 1, ENC_BIG_ENDIAN);
3087 /* apdu layer len field checks are sufficient for "immediate" */
3088 if (close_mmi_cmd_id == CLOSE_MMI_CMD_ID_DELAY) {
3089 if (len_field != 2) {
3090 proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb,
3091 APDU_TAG_SIZE, offset_start-APDU_TAG_SIZE,
3092 "Length field must be 2");
3095 proto_tree_add_item(tree, hf_dvbci_close_mmi_delay, tvb,
3096 offset, 1, ENC_BIG_ENDIAN);
3099 case T_DISPLAY_CONTROL:
3100 disp_ctl_cmd = tvb_get_guint8(tvb,offset);
3101 disp_ctl_cmd_str = val_to_str_const(disp_ctl_cmd,
3102 dvbci_disp_ctl_cmd, "unknown command");
3103 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
3104 "%s", disp_ctl_cmd_str);
3105 proto_tree_add_item(tree, hf_dvbci_disp_ctl_cmd, tvb,
3106 offset, 1, ENC_BIG_ENDIAN);
3108 if (disp_ctl_cmd == DISP_CMD_SET_MMI_MODE)
3110 proto_tree_add_item(tree, hf_dvbci_mmi_mode, tvb,
3111 offset, 1, ENC_BIG_ENDIAN);
3112 if (len_field != 2) {
3113 proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb,
3114 APDU_TAG_SIZE, offset_start-APDU_TAG_SIZE,
3115 "Length field must be 2");
3120 case T_DISPLAY_REPLY:
3121 disp_rep_id = tvb_get_guint8(tvb,offset);
3122 disp_rep_id_str = val_to_str_const(disp_rep_id,
3123 dvbci_disp_rep_id, "unknown command");
3124 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
3125 "%s", disp_rep_id_str);
3126 proto_tree_add_item(tree, hf_dvbci_disp_rep_id,
3127 tvb, offset, 1, ENC_BIG_ENDIAN);
3129 if (disp_rep_id == DISP_REP_ID_MMI_MODE_ACK) {
3130 proto_tree_add_item(tree, hf_dvbci_mmi_mode,
3131 tvb, offset, 1, ENC_BIG_ENDIAN);
3133 else if (disp_rep_id == DISP_REP_ID_DISP_CHAR_TBL ||
3134 disp_rep_id == DISP_REP_ID_INP_CHAR_TBL) {
3135 while ((msg_len=tvb_reported_length_remaining(tvb, offset)) > 0) {
3136 enc_len = dvb_analyze_string_charset(
3137 tvb, offset, msg_len, &encoding);
3139 proto_tree_add_expert(tree, pinfo,
3140 &ei_dvbci_invalid_char_tbl, tvb, offset, msg_len);
3143 dvb_add_chartbl(tree, hf_dvbci_mmi_char_tbl,
3144 tvb, offset, enc_len, encoding);
3150 proto_tree_add_item(tree, hf_dvbci_blind_ans,
3151 tvb, offset, 1, ENC_BIG_ENDIAN);
3153 ans_txt_len = tvb_get_guint8(tvb,offset);
3154 if (ans_txt_len == NB_UNKNOWN) {
3155 proto_tree_add_text(tree, tvb, offset, 1,
3156 "Length of expected answer is unknown");
3159 proto_tree_add_item(tree, hf_dvbci_ans_txt_len,
3160 tvb, offset, 1, ENC_BIG_ENDIAN);
3162 dissect_si_string(tvb, offset,
3163 tvb_reported_length_remaining(tvb, offset),
3164 pinfo, tree, hf_dvbci_enq, "Enquiry string", FALSE);
3167 ans_id = tvb_get_guint8(tvb,offset);
3168 proto_tree_add_item(tree, hf_dvbci_ans_id, tvb, offset, 1, ENC_BIG_ENDIAN);
3170 if (ans_id == ANSW_ID_ANSWER) {
3171 dissect_si_string(tvb, offset,
3172 tvb_reported_length_remaining(tvb, offset),
3173 pinfo, tree, hf_dvbci_ans, "Answer", TRUE);
3180 choice_or_item_nb = tvb_get_guint8(tvb,offset);
3181 if (choice_or_item_nb == NB_UNKNOWN)
3183 proto_tree_add_text(tree, tvb, offset, 1,
3184 "Number of items is unknown");
3188 if (IS_MENU_APDU(tag)) {
3189 proto_tree_add_item(
3190 tree, hf_dvbci_choice_nb, tvb, offset, 1, ENC_BIG_ENDIAN);
3193 proto_tree_add_item(
3194 tree, hf_dvbci_item_nb, tvb, offset, 1, ENC_BIG_ENDIAN);
3198 text_len = dissect_dvbci_text("Title", tvb, offset,
3199 pinfo, tree, hf_dvbci_title);
3201 text_len = dissect_dvbci_text("Sub-title", tvb, offset,
3202 pinfo, tree, hf_dvbci_subtitle);
3204 text_len = dissect_dvbci_text("Bottom line", tvb, offset,
3205 pinfo, tree, hf_dvbci_bottom);
3207 while (tvb_reported_length_remaining(tvb, offset) > 0) {
3208 text_len = dissect_dvbci_text("Item", tvb, offset, pinfo, tree, hf_dvbci_item);
3209 /* minimum is apdu tag + 1 byte len field */
3210 if (text_len<APDU_TAG_SIZE+1) {
3211 proto_tree_add_expert(tree, pinfo, &ei_dvbci_not_text_more_or_text_last, tvb, offset, -1);
3218 choice_ref = tvb_get_guint8(tvb,offset);
3219 if (choice_ref == 0x0) {
3220 proto_tree_add_text(tree, tvb, offset, 1,
3221 "Selection was cancelled.");
3222 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
3226 proto_tree_add_item(
3227 tree, hf_dvbci_choice_ref, tvb, offset, 1, ENC_BIG_ENDIAN);
3228 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
3229 "Item %d", choice_ref);
3239 dissect_dvbci_payload_hlc(guint32 tag, gint len_field _U_,
3240 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
3241 packet_info *pinfo, proto_tree *tree)
3245 if (tag==T_HOST_COUNTRY) {
3246 proto_tree_add_item(tree, hf_dvbci_host_country,
3247 tvb, offset, tvb_reported_length_remaining(tvb, offset),
3248 ENC_ISO_8859_1|ENC_NA);
3250 else if (tag==T_HOST_LANGUAGE) {
3251 proto_tree_add_item(tree, hf_dvbci_host_language,
3252 tvb, offset, tvb_reported_length_remaining(tvb, offset),
3253 ENC_ISO_8859_1|ENC_NA);
3256 /* both apdus' body is only a country code, this can be shared */
3257 str = tvb_get_string_enc(wmem_packet_scope(), tvb, offset,
3258 tvb_reported_length_remaining(tvb, offset),
3259 ENC_ISO_8859_1|ENC_NA);
3261 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s", str);
3266 dissect_dvbci_payload_cup(guint32 tag, gint len_field _U_,
3267 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
3268 packet_info *pinfo, proto_tree *tree)
3270 guint8 upgrade_type;
3271 guint16 download_time;
3272 guint8 answer, progress;
3275 case T_CAM_FIRMWARE_UPGRADE:
3276 upgrade_type = tvb_get_guint8(tvb, offset);
3277 proto_tree_add_item(tree, hf_dvbci_cup_type, tvb, offset, 1, ENC_BIG_ENDIAN);
3278 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "(%s)",
3279 val_to_str_const(upgrade_type, dvbci_cup_type, "unknown"));
3281 download_time = tvb_get_ntohs(tvb, offset);
3282 if (download_time == 0) {
3283 proto_tree_add_uint_format(tree, hf_dvbci_cup_download_time,
3284 tvb, offset, 2, download_time,
3285 "estimated download time is unknown");
3288 proto_tree_add_uint_format(tree, hf_dvbci_cup_download_time,
3289 tvb, offset, 2, download_time,
3290 "estimated download time is %d seconds",
3294 case T_CAM_FIRMWARE_UPGRADE_REPLY:
3295 answer = tvb_get_guint8(tvb, offset);
3296 proto_tree_add_item(tree, hf_dvbci_cup_answer, tvb, offset, 1, ENC_BIG_ENDIAN);
3297 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s",
3298 val_to_str_const(answer, dvbci_cup_answer, "unknown"));
3300 case T_CAM_FIRMWARE_UPGRADE_PROGRESS:
3301 progress = tvb_get_guint8(tvb, offset);
3302 if (progress > 100) {
3303 proto_tree_add_expert(tree, pinfo, &ei_dvbci_cup_progress, tvb, offset, 1);
3306 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%d%%", progress);
3307 proto_tree_add_uint_format(tree, hf_dvbci_cup_progress,
3308 tvb, offset, 1, progress,
3309 "download progress %d%%", progress);
3312 case T_CAM_FIRMWARE_UPGRADE_COMPLETE:
3313 proto_tree_add_item(tree, hf_dvbci_cup_reset, tvb, offset, 1, ENC_BIG_ENDIAN);
3322 dissect_sac_msg(guint32 tag, tvbuff_t *tvb, gint offset,
3323 packet_info *pinfo, proto_tree *tree, gboolean exported)
3327 guint8 enc_flag, enc_cip;
3328 proto_item *enc_flag_pi, *ti;
3329 guint16 sac_payload_len; /* payload data and padding */
3330 gint sac_payload_data_len = 0; /* just payload data */
3331 tvbuff_t *clear_sac_body_tvb;
3332 proto_tree *sac_tree = NULL;
3333 gboolean is_exportable = FALSE;
3335 offset_start = offset;
3337 /* it's not useful to move sac header dissection to a separate
3338 function, we need enc/auth cipher etc here to handle the body */
3339 msg_ctr = tvb_get_ntohl(tvb, offset);
3340 proto_tree_add_item(tree, hf_dvbci_sac_msg_ctr,
3341 tvb, offset, 4, ENC_BIG_ENDIAN);
3342 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
3343 "message #%d", msg_ctr);
3345 proto_tree_add_item(tree, hf_dvbci_sac_proto_ver,
3346 tvb, offset, 1, ENC_BIG_ENDIAN);
3347 proto_tree_add_item(tree, hf_dvbci_sac_auth_cip,
3348 tvb, offset, 1, ENC_BIG_ENDIAN);
3349 enc_flag = tvb_get_guint8(tvb, offset) & 0x1;
3350 enc_flag_pi = proto_tree_add_item(tree, hf_dvbci_sac_payload_enc,
3351 tvb, offset, 1, ENC_BIG_ENDIAN);
3352 if (exported && enc_flag) {
3353 expert_add_info(pinfo, enc_flag_pi, &ei_dvbci_sac_payload_enc);
3357 enc_cip = (tvb_get_guint8(tvb, offset)&0xE0) >> 5;
3358 proto_tree_add_item(tree, hf_dvbci_sac_enc_cip,
3359 tvb, offset, 1, ENC_BIG_ENDIAN);
3361 sac_payload_len = tvb_get_ntohs(tvb, offset);
3362 proto_tree_add_item(tree, hf_dvbci_sac_payload_len,
3363 tvb, offset, 2, ENC_BIG_ENDIAN);
3365 if (tvb_reported_length_remaining(tvb, offset) < 0)
3368 clear_sac_body_tvb = decrypt_sac_msg_body(enc_cip,
3369 tvb, offset, tvb_reported_length_remaining(tvb, offset));
3372 clear_sac_body_tvb = tvb_new_subset_remaining(tvb, offset);
3374 if (!clear_sac_body_tvb) {
3375 /* we could not decrypt (or access) the clear sac message body */
3376 proto_tree_add_item(tree, hf_dvbci_sac_enc_body, tvb, offset,
3377 tvb_reported_length_remaining(tvb, offset), ENC_NA);
3381 add_new_data_source(pinfo, clear_sac_body_tvb, "Clear SAC message body");
3382 if (sac_payload_len>0) {
3383 ti = proto_tree_add_text(tree, clear_sac_body_tvb, 0, sac_payload_len,
3384 "SAC message payload");
3385 sac_tree = proto_item_add_subtree(ti, ett_dvbci_sac_msg_body);
3386 if (tag==T_CC_SAC_DATA_REQ || tag==T_CC_SAC_DATA_CNF) {
3387 sac_payload_data_len = dissect_cc_data_payload(tag,
3388 clear_sac_body_tvb, 0, pinfo, sac_tree, &is_exportable);
3390 else if (tag==T_CC_SAC_SYNC_REQ) {
3391 sac_payload_data_len = 0;
3393 else if (tag==T_CC_SAC_SYNC_CNF) {
3394 proto_tree_add_item(sac_tree, hf_dvbci_cc_status_field,
3395 clear_sac_body_tvb, 0, 1, ENC_BIG_ENDIAN);
3396 sac_payload_data_len = 1;
3399 if (sac_payload_data_len < 0)
3401 if (sac_payload_len > sac_payload_data_len) {
3402 proto_tree_add_item(sac_tree, hf_dvbci_sac_padding,
3403 clear_sac_body_tvb, sac_payload_data_len,
3404 sac_payload_len-sac_payload_data_len, ENC_NA);
3407 proto_tree_add_item(tree, hf_dvbci_sac_signature,
3408 clear_sac_body_tvb, sac_payload_len,
3409 tvb_reported_length_remaining(clear_sac_body_tvb,
3410 sac_payload_len), ENC_NA);
3412 /* we call this function also to dissect exported SAC messages,
3413 dont' try to export them a second time */
3414 if (!exported && is_exportable && have_tap_listener(exported_pdu_tap)) {
3416 tvbuff_t *clear_sac_msg_tvb;
3417 exp_pdu_data_t *exp_pdu_data;
3420 clear_sac_msg_tvb = tvb_new_composite();
3421 tvb_composite_append(clear_sac_msg_tvb,
3422 tvb_clone_offset_len(tvb, offset_start, SAC_MSG_HDR_LEN));
3423 tvb_composite_append(clear_sac_msg_tvb, clear_sac_body_tvb);
3424 tvb_composite_finalize(clear_sac_msg_tvb);
3427 tags[1] = EXP_PDU_TAG_DVBCI_EVT_BIT;
3428 exp_pdu_data = load_export_pdu_tags(
3429 pinfo, EXPORTED_SAC_MSG_PROTO, -1, tags, 2);
3431 exp_pdu_data->tvb_captured_length = tvb_captured_length(clear_sac_msg_tvb);
3432 exp_pdu_data->tvb_reported_length = tvb_reported_length(clear_sac_msg_tvb);
3433 exp_pdu_data->pdu_tvb = clear_sac_msg_tvb;
3434 tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
3440 dissect_dvbci_exported_sac_msg(
3441 tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
3446 evt = dvbci_get_evt_from_addrs(pinfo);
3447 if (!IS_DATA_TRANSFER(evt))
3450 col_append_sep_fstr(pinfo->cinfo, COL_PROTOCOL, NULL, EXPORTED_SAC_MSG_PROTO);
3451 col_clear(pinfo->cinfo, COL_INFO);
3453 /* we only export cc_sac_data_req and _cnf, therefore, the tag can be
3454 derived from the direction of the transfer */
3455 if (evt== DVBCI_EVT_DATA_CAM_TO_HOST)
3456 tag = T_CC_SAC_DATA_REQ;
3458 tag = T_CC_SAC_DATA_CNF;
3460 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "%s",
3461 val_to_str_const(tag, dvbci_apdu_tag, "unknown"));
3463 dissect_sac_msg(tag, tvb, 0, pinfo, tree, TRUE);
3464 return tvb_reported_length(tvb);
3469 dissect_dvbci_payload_cc(guint32 tag, gint len_field _U_,
3470 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
3471 packet_info *pinfo, proto_tree *tree)
3481 proto_tree_add_item(tree, hf_dvbci_cc_sys_id_bitmask,
3482 tvb, offset, 1, ENC_BIG_ENDIAN);
3486 dissect_cc_data_payload(tag, tvb, offset, pinfo, tree, NULL);
3489 status = tvb_get_guint8(tvb, offset);
3490 proto_tree_add_item(
3491 tree, hf_dvbci_cc_status_field, tvb, offset, 1, ENC_BIG_ENDIAN);
3492 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s",
3493 val_to_str_const(status, dvbci_cc_status, "unknown"));
3495 case T_CC_SAC_DATA_REQ:
3496 case T_CC_SAC_DATA_CNF:
3497 case T_CC_SAC_SYNC_REQ:
3498 case T_CC_SAC_SYNC_CNF:
3499 dissect_sac_msg(tag, tvb, offset, pinfo, tree, FALSE);
3501 case T_CC_PIN_CAPABILITIES_REPLY:
3502 proto_tree_add_item(tree, hf_dvbci_capability_field,
3503 tvb, offset, 1 , ENC_BIG_ENDIAN);
3505 /* we can't packet_mpeg_sect_mjd_to_utc_time()
3506 and check with nstime_is_zero() */
3507 if (tvb_get_ntoh40(tvb, offset) == 0) {
3508 proto_tree_add_text(tree, tvb, offset, UTC_TIME_LEN,
3509 "CICAM PIN has never been changed");
3512 if (packet_mpeg_sect_mjd_to_utc_time(tvb, offset, &utc_time) < 0) {
3513 proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb, offset, UTC_TIME_LEN,
3514 "Invalid UTC time field, 2 bytes MJD, 3 bytes BCD time hhmmss");
3518 /* abs_time_to_ep_str() never returns NULL */
3519 proto_tree_add_time(tree, hf_dvbci_pin_chg_time,
3520 tvb, offset, UTC_TIME_LEN, &utc_time);
3523 offset += UTC_TIME_LEN;
3524 dissect_rating(tvb, offset, pinfo, tree);
3526 case T_CC_PIN_REPLY:
3527 pin_stat = tvb_get_guint8(tvb, offset);
3528 proto_tree_add_item(tree, hf_dvbci_pincode_status,
3529 tvb, offset, 1, ENC_BIG_ENDIAN);
3530 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s",
3531 val_to_str_const(pin_stat, dvbci_pincode_status, "unknown"));
3533 case T_CC_PIN_EVENT:
3534 proto_tree_add_item(tree, hf_dvbci_cc_prog_num,
3535 tvb, offset, 2, ENC_BIG_ENDIAN);
3537 proto_tree_add_item(tree, hf_dvbci_pincode_status,
3538 tvb, offset, 1, ENC_BIG_ENDIAN);
3540 dissect_rating(tvb, offset, pinfo, tree);
3542 if (packet_mpeg_sect_mjd_to_utc_time(tvb, offset, &utc_time) < 0) {
3543 proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb, offset, UTC_TIME_LEN,
3544 "Invalid UTC time field, 2 bytes MJD, 3 bytes BCD time hhmmss");
3548 proto_tree_add_time(tree, hf_dvbci_pin_evt_time,
3549 tvb, offset, UTC_TIME_LEN, &utc_time);
3551 offset += UTC_TIME_LEN;
3552 evt_cent = tvb_get_guint8(tvb, offset);
3553 pi = proto_tree_add_item(tree, hf_dvbci_pin_evt_cent,
3554 tvb, offset, 1, ENC_BIG_ENDIAN);
3555 if (evt_cent > 100) {
3556 expert_add_info(pinfo, pi, &ei_dvbci_pin_evt_cent);
3559 /* length field was already checked by the caller */
3560 proto_tree_add_item(tree, hf_dvbci_cc_priv_data, tvb, offset,
3561 tvb_reported_length_remaining(tvb, offset), ENC_NA);
3563 case T_CC_PIN_PLAYBACK:
3564 dissect_rating(tvb, offset, pinfo, tree);
3566 /* length field was already checked by the caller */
3567 proto_tree_add_item(tree, hf_dvbci_cc_priv_data, tvb, offset,
3568 tvb_reported_length_remaining(tvb, offset), ENC_NA);
3571 case T_CC_PIN_MMI_REQ:
3572 proto_tree_add_item(tree, hf_dvbci_pincode, tvb, offset,
3573 tvb_reported_length_remaining(tvb, offset),
3583 dissect_dvbci_ami_file_ack(tvbuff_t *tvb, gint offset,
3584 packet_info *pinfo, proto_tree *tree)
3587 gboolean req_ok = FALSE, file_ok;
3588 guint8 file_name_len;
3589 guint8 *file_name_str;
3590 guint32 file_data_len;
3591 tvbuff_t *png_file_tvb = NULL;
3593 proto_tree *req_tree;
3595 req_type = tvb_get_guint8(tvb, offset+1);
3596 if (req_type==REQ_TYPE_FILE_HASH) {
3597 req_ok = ((tvb_get_guint8(tvb, offset) & 0x02) == 0x02);
3598 proto_tree_add_item(tree, hf_dvbci_req_ok,
3599 tvb, offset, 1, ENC_BIG_ENDIAN);
3601 file_ok = ((tvb_get_guint8(tvb, offset) & 0x01) == 0x01);
3602 proto_tree_add_item(tree, hf_dvbci_file_ok, tvb, offset, 1, ENC_BIG_ENDIAN);
3604 proto_tree_add_item(tree, hf_dvbci_req_type, tvb, offset, 1, ENC_BIG_ENDIAN);
3605 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s",
3606 val_to_str_const(req_type, dvbci_req_type, "unknown"));
3608 if (req_type==REQ_TYPE_FILE || req_type==REQ_TYPE_FILE_HASH) {
3609 file_name_len = tvb_get_guint8(tvb, offset);
3610 proto_tree_add_text(tree, tvb, offset, 1,
3611 "File name length %d", file_name_len);
3613 file_name_str = tvb_get_string_enc(wmem_packet_scope(),
3614 tvb, offset, file_name_len, ENC_ASCII);
3617 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
3618 "%s", file_name_str);
3619 proto_tree_add_string_format_value(tree, hf_dvbci_file_name,
3620 tvb, offset, file_name_len, file_name_str,
3621 "%s", file_name_str);
3622 offset += file_name_len;
3623 file_data_len = tvb_get_ntohl(tvb, offset);
3624 proto_tree_add_text(tree, tvb, offset, 4,
3625 "File data length %d", file_data_len);
3627 if (file_data_len > 0) {
3628 if (file_name_len>4) {
3630 suffix_lo = wmem_ascii_strdown(wmem_packet_scope(),
3631 &file_name_str[file_name_len-4], -1);
3632 if (g_strcmp0(suffix_lo, ".png")==0) {
3633 png_file_tvb = tvb_new_subset_length(
3634 tvb, offset, file_data_len);
3638 if (png_handle && png_file_tvb) {
3639 col_set_fence(pinfo->cinfo, COL_PROTOCOL);
3640 col_set_fence(pinfo->cinfo, COL_INFO);
3641 call_dissector(png_handle, png_file_tvb, pinfo, tree);
3644 proto_tree_add_item(tree, hf_dvbci_file_data,
3645 tvb, offset, file_data_len, ENC_NA);
3649 else if (req_type==REQ_TYPE_DATA) {
3650 if (tvb_reported_length_remaining(tvb, offset) <= 0)
3652 proto_tree_add_item(tree, hf_dvbci_ami_priv_data, tvb, offset,
3653 tvb_reported_length_remaining(tvb, offset), ENC_NA);
3655 else if (req_type==REQ_TYPE_REQ) {
3656 ti = proto_tree_add_text(tree, tvb,
3657 offset, tvb_reported_length_remaining(tvb, offset),
3658 "Supported request types");
3659 req_tree = proto_item_add_subtree(
3660 ti, ett_dvbci_ami_req_types);
3661 while (tvb_reported_length_remaining(tvb, offset) > 0) {
3662 proto_tree_add_item(req_tree, hf_dvbci_req_type,
3663 tvb, offset, 1, ENC_BIG_ENDIAN);
3668 if (req_type==REQ_TYPE_FILE_HASH && req_ok && !file_ok) {
3669 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
3670 "cached copy is valid");
3676 dissect_dvbci_payload_ami(guint32 tag, gint len_field _U_,
3677 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
3678 packet_info *pinfo, proto_tree *tree)
3680 guint8 app_dom_id_len, init_obj_len;
3687 case T_REQUEST_START:
3688 /* no filter for length items */
3689 app_dom_id_len = tvb_get_guint8(tvb, offset);
3690 proto_tree_add_text(tree, tvb, offset, 1,
3691 "Application Domain Identifier length %d", app_dom_id_len);
3693 init_obj_len = tvb_get_guint8(tvb, offset);
3694 proto_tree_add_text(tree, tvb, offset, 1,
3695 "Initial Object length %d", init_obj_len);
3697 proto_tree_add_item(tree, hf_dvbci_app_dom_id,
3698 tvb, offset, app_dom_id_len, ENC_ASCII|ENC_NA);
3699 app_dom_id = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, app_dom_id_len, ENC_ASCII);
3701 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ",
3702 "for %s", app_dom_id);
3704 offset += app_dom_id_len;
3705 proto_tree_add_item(tree, hf_dvbci_init_obj,
3706 tvb, offset, init_obj_len, ENC_ASCII|ENC_NA);
3708 case T_REQUEST_START_ACK:
3709 ack_code = tvb_get_guint8(tvb, offset);
3710 proto_tree_add_item(
3711 tree, hf_dvbci_ack_code, tvb, offset, 1, ENC_BIG_ENDIAN);
3712 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s",
3713 val_to_str_const(ack_code, dvbci_ack_code, "unknown"));
3715 case T_FILE_REQUEST:
3716 req_type = tvb_get_guint8(tvb, offset);
3717 proto_tree_add_item(tree, hf_dvbci_req_type, tvb, offset, 1, ENC_BIG_ENDIAN);
3718 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s",
3719 val_to_str_const(req_type, dvbci_req_type, "unknown"));
3721 if (req_type==REQ_TYPE_FILE_HASH) {
3722 proto_tree_add_item(tree, hf_dvbci_file_hash,
3723 tvb, offset, 16, ENC_NA);
3726 if (tvb_reported_length_remaining(tvb, offset) <= 0)
3728 if (req_type==REQ_TYPE_FILE || req_type==REQ_TYPE_FILE_HASH) {
3729 req_str = tvb_get_string_enc(wmem_packet_scope(), tvb, offset,
3730 tvb_reported_length_remaining(tvb, offset), ENC_ASCII);
3733 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "%s", req_str);
3734 proto_tree_add_string_format_value(tree, hf_dvbci_file_name,
3735 tvb, offset, tvb_reported_length_remaining(tvb, offset),
3736 req_str, "%s", req_str);
3738 else if (req_type==REQ_TYPE_DATA) {
3739 proto_tree_add_item(tree, hf_dvbci_ami_priv_data, tvb, offset,
3740 tvb_reported_length_remaining(tvb, offset), ENC_NA);
3743 case T_FILE_ACKNOWLEDGE:
3744 dissect_dvbci_ami_file_ack(tvb, offset, pinfo, tree);
3746 case T_APP_ABORT_REQUEST:
3747 if (tvb_reported_length_remaining(tvb, offset) > 0) {
3748 proto_tree_add_item(tree, hf_dvbci_abort_req_code, tvb, offset,
3749 tvb_reported_length_remaining(tvb, offset), ENC_NA);
3752 case T_APP_ABORT_ACK:
3753 if (tvb_reported_length_remaining(tvb, offset) > 0) {
3754 proto_tree_add_item(tree, hf_dvbci_abort_ack_code, tvb, offset,
3755 tvb_reported_length_remaining(tvb, offset), ENC_NA);
3765 dissect_dvbci_payload_lsc(guint32 tag, gint len_field,
3766 tvbuff_t *tvb, gint offset, circuit_t *circuit,
3767 packet_info *pinfo, proto_tree *tree)
3770 guint8 id, timeout, ret_val, phase_id;
3771 gint conn_desc_len, param_len;
3773 proto_item *pi = NULL;
3774 const gchar *ret_val_str = NULL;
3777 dissector_handle_t msg_handle;
3779 offset_start = offset;
3783 proto_tree_add_item(tree, hf_dvbci_comms_cmd_id,
3784 tvb, offset, 1, ENC_BIG_ENDIAN);
3785 id = tvb_get_guint8(tvb, offset);
3786 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s",
3787 val_to_str(id, dvbci_comms_cmd_id, "Unknown: %d"));
3790 case COMMS_CMD_ID_CONNECT_ON_CHANNEL:
3791 conn_desc_len = dissect_conn_desc(tvb, offset,
3792 circuit, pinfo, tree);
3793 if (conn_desc_len < 0)
3795 offset += conn_desc_len;
3796 proto_tree_add_item(tree, hf_dvbci_lsc_retry_count,
3797 tvb, offset, 1, ENC_BIG_ENDIAN);
3799 timeout = tvb_get_guint8(tvb, offset);
3801 proto_tree_add_uint_format(tree, hf_dvbci_lsc_timeout,
3802 tvb, offset, 1, timeout, "Infinite timeout");
3804 proto_tree_add_uint_format(tree, hf_dvbci_lsc_timeout,
3805 tvb, offset, 1, timeout,
3806 "Timeout is %d seconds", timeout);
3809 case COMMS_CMD_ID_DISCONNECT_ON_CHANNEL:
3810 case COMMS_CMD_ID_ENQUIRE_STATUS:
3811 /* len_field == 1 -> only id, no further parameters */
3812 if (len_field != 1) {
3813 proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb,
3814 APDU_TAG_SIZE, offset_start-APDU_TAG_SIZE,
3815 "Length field must be 1");
3818 case COMMS_CMD_ID_SET_PARAMS:
3819 param_len = tvb_reported_length_remaining(tvb, offset);
3821 buf_size = (guint16)tvb_get_guint8(tvb, offset);
3822 else if (param_len == 3)
3823 buf_size = tvb_get_ntohs(tvb, offset);
3825 /* length field == 1 byte id + param_len */
3826 proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb,
3827 APDU_TAG_SIZE, offset_start-APDU_TAG_SIZE,
3828 "Length field must be 3 or 4");
3831 proto_tree_add_uint_format(tree, hf_dvbci_lsc_buf_size,
3832 tvb, offset, param_len-1, buf_size,
3833 "buffer size %d bytes", buf_size);
3834 offset += param_len-1;
3835 timeout = tvb_get_guint8(tvb, offset);
3836 proto_tree_add_uint_format(tree, hf_dvbci_lsc_timeout,
3837 tvb, offset, 1, timeout,
3838 "timeout is %d milliseconds", timeout*10);
3840 case COMMS_CMD_ID_GET_NEXT_BUFFER:
3841 phase_id = tvb_get_guint8(tvb, offset);
3842 proto_tree_add_item(tree, hf_dvbci_phase_id,
3843 tvb, offset, 1, ENC_BIG_ENDIAN);
3844 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
3845 "received #%d", phase_id);
3852 proto_tree_add_item(tree, hf_dvbci_comms_rep_id,
3853 tvb, offset, 1, ENC_BIG_ENDIAN);
3854 id = tvb_get_guint8(tvb,offset);
3855 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "%s",
3856 val_to_str(id, dvbci_comms_rep_id, "Unknown: %d"));
3858 ret_val = tvb_get_guint8(tvb,offset);
3859 pi = proto_tree_add_item(tree, hf_dvbci_lsc_ret_val,
3860 tvb, offset, 1, ENC_BIG_ENDIAN);
3862 case COMMS_REP_ID_SEND_ACK:
3863 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
3864 "sent #%d", ret_val);
3866 proto_item_append_text(pi, " (sent #%d)", ret_val);
3868 case COMMS_REP_ID_SET_PARAMS_ACK:
3869 ret_val_str = val_to_str_const(ret_val,
3870 dvbci_lsc_ret_val_params, "unknown/error");
3872 case COMMS_REP_ID_STATUS_REPLY:
3873 ret_val_str = val_to_str_const(ret_val,
3874 dvbci_lsc_ret_val_connect, "unknown/error");
3877 ret_val_str = val_to_str_const(ret_val,
3878 dvbci_lsc_ret_val, "unknown/error");
3882 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
3885 proto_item_append_text(pi, " (%s)", ret_val_str);
3888 case T_COMMS_SEND_LAST:
3889 case T_COMMS_SEND_MORE:
3890 case T_COMMS_RCV_LAST:
3891 case T_COMMS_RCV_MORE:
3892 phase_id = tvb_get_guint8(tvb, offset);
3893 proto_tree_add_item(tree, hf_dvbci_phase_id,
3894 tvb, offset, 1, ENC_BIG_ENDIAN);
3895 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
3896 "Phase ID %d", phase_id);
3898 msg_len = tvb_reported_length_remaining(tvb, offset);
3901 msg_tvb = tvb_new_subset_remaining(tvb, offset);
3904 if (dvbci_dissect_lsc_msg && circuit && circuit->dissector_handle) {
3905 msg_handle = circuit->dissector_handle;
3906 col_append_str(pinfo->cinfo, COL_INFO, ", ");
3907 col_set_fence(pinfo->cinfo, COL_INFO);
3908 col_append_str(pinfo->cinfo, COL_PROTOCOL, ", ");
3909 col_set_fence(pinfo->cinfo, COL_PROTOCOL);
3912 msg_handle = data_handle;
3915 call_dissector(msg_handle, msg_tvb, pinfo, tree);
3924 dissect_dvbci_payload_opp(guint32 tag, gint len_field _U_,
3925 tvbuff_t *tvb, gint offset, circuit_t *circuit _U_,
3926 packet_info *pinfo, proto_tree *tree)
3928 guint16 nit_loop_len, nit_loop_offset;
3929 tvbuff_t *nit_loop_tvb, *nit_loop_partial_tvb;
3930 guint dvb_nit_bytes;
3932 guint8 cap_loop_len;
3933 gboolean info_valid;
3935 dvb_encoding_e encoding;
3937 guint8 sig_strength, sig_qual;
3941 case T_OPERATOR_STATUS:
3942 case T_OPERATOR_SEARCH_STATUS:
3943 dissect_opp_status_body(tvb, offset, pinfo, tree);
3945 case T_OPERATOR_NIT:
3946 nit_loop_len = tvb_get_ntohs(tvb, offset);
3947 proto_tree_add_item(tree, hf_dvbci_nit_loop_len,
3948 tvb, offset, 2, ENC_BIG_ENDIAN);
3949 if (nit_loop_len==0)
3952 nit_loop_tvb = tvb_new_subset_length(
3953 tvb, offset, nit_loop_len);
3954 nit_loop_offset = 0;
3955 if (!dvb_nit_handle) {
3956 call_dissector(data_handle, nit_loop_tvb, pinfo, tree);
3959 /* prevent dvb_nit dissector from clearing the dvb-ci infos */
3960 col_append_str(pinfo->cinfo, COL_INFO, ", ");
3961 col_set_fence(pinfo->cinfo, COL_INFO);
3963 table_id = tvb_get_guint8(nit_loop_tvb, nit_loop_offset);
3964 if (table_id != TABLE_ID_CICAM_NIT) {
3965 proto_tree_add_expert(tree, pinfo, &ei_dvbci_cicam_nit_table_id,
3966 nit_loop_tvb, nit_loop_offset, 1);
3968 nit_loop_partial_tvb =
3969 tvb_new_subset_remaining(nit_loop_tvb, nit_loop_offset);
3970 dvb_nit_bytes = call_dissector(
3971 dvb_nit_handle, nit_loop_partial_tvb, pinfo, tree);
3972 nit_loop_offset += dvb_nit_bytes;
3973 /* offsets go from 0 to nit_loop_len-1 */
3974 } while (dvb_nit_bytes>0 && nit_loop_offset<nit_loop_len-1);
3976 case T_OPERATOR_INFO:
3977 info_valid = ((tvb_get_guint8(tvb, offset) & 0x08) == 0x08);
3978 proto_tree_add_item(tree, hf_dvbci_info_valid,
3979 tvb, offset, 1, ENC_BIG_ENDIAN);
3980 proto_tree_add_item(tree, hf_dvbci_info_ver_op_info,
3981 tvb, offset, 1, ENC_BIG_ENDIAN);
3985 proto_tree_add_item(tree, hf_dvbci_cicam_onid,
3986 tvb, offset, 2, ENC_BIG_ENDIAN);
3988 proto_tree_add_item(tree, hf_dvbci_cicam_id,
3989 tvb, offset, 4, ENC_BIG_ENDIAN);
3992 enc_len = dvb_analyze_string_charset(tvb, offset,
3993 tvb_reported_length_remaining(tvb, offset), &encoding);
3995 proto_tree_add_expert(tree, pinfo,
3996 &ei_dvbci_invalid_char_tbl, tvb, offset,
3997 tvb_reported_length_remaining(tvb, offset));
4000 dvb_add_chartbl(tree, hf_dvbci_opp_char_tbl,
4001 tvb, offset, enc_len, encoding);
4004 proto_tree_add_item(tree, hf_dvbci_sdt_rst_trusted,
4005 tvb, offset, 1, ENC_BIG_ENDIAN);
4006 proto_tree_add_item(tree, hf_dvbci_eit_rst_trusted,
4007 tvb, offset, 1, ENC_BIG_ENDIAN);
4008 proto_tree_add_item(tree, hf_dvbci_eit_pf_usage,
4009 tvb, offset, 1, ENC_BIG_ENDIAN);
4010 proto_tree_add_item(tree, hf_dvbci_eit_sch_usage,
4011 tvb, offset, 1, ENC_BIG_ENDIAN);
4012 proto_tree_add_item(tree, hf_dvbci_ext_evt_usage,
4013 tvb, offset, 1, ENC_BIG_ENDIAN);
4015 proto_tree_add_item(tree, hf_dvbci_sdt_oth_trusted,
4016 tvb, offset, 1, ENC_BIG_ENDIAN);
4017 proto_tree_add_item(tree, hf_dvbci_eit_evt_trigger,
4018 tvb, offset, 1, ENC_BIG_ENDIAN);
4020 proto_tree_add_item(tree, hf_dvbci_opp_lang_code,
4021 tvb, offset, 3, ENC_ASCII|ENC_NA);
4023 /* hf_dvbci_prof_name is an FT_UINT_STRING, one leading len byte */
4024 proto_tree_add_item(tree, hf_dvbci_prof_name,
4025 tvb, offset, 1, ENC_ASCII|ENC_NA);
4027 case T_OPERATOR_SEARCH_START:
4028 proto_tree_add_item(tree, hf_dvbci_unattended,
4029 tvb, offset, 1, ENC_BIG_ENDIAN);
4031 /* no filters for the loop lengths, one is 7bit, others are 8bit */
4032 cap_loop_len = tvb_get_guint8(tvb, offset) & 0x7F;
4033 proto_tree_add_text(tree, tvb, offset, 1,
4034 "Service type loop length: %d", cap_loop_len);
4036 /* no need for error checking, we continue anyway */
4037 dissect_opp_cap_loop(cap_loop_len, "Service type loop",
4038 hf_dvbci_opp_srv_type, 1, tvb, offset, pinfo, tree);
4039 offset += cap_loop_len;
4041 cap_loop_len = tvb_get_guint8(tvb, offset);
4042 proto_tree_add_text(tree, tvb, offset, 1,
4043 "Delivery system capabilities loop length: %d",
4046 /* XXX - handle multi-byte delivery capabilities */
4047 dissect_opp_cap_loop(cap_loop_len,
4048 "Delivery system capabilities loop",
4049 hf_dvbci_dlv_cap_byte, 1,
4050 tvb, offset, pinfo, tree);
4051 offset += cap_loop_len;
4053 cap_loop_len = tvb_get_guint8(tvb, offset);
4054 proto_tree_add_text(tree, tvb, offset, 1,
4055 "Application capabilities loop length: %d", cap_loop_len);
4057 dissect_opp_cap_loop(cap_loop_len,
4058 "Application capabilities loop",
4059 hf_dvbci_app_cap_bytes, 2,
4060 tvb, offset, pinfo, tree);
4062 case T_OPERATOR_TUNE_STATUS:
4063 desc_num = tvb_get_guint8(tvb, offset);
4064 pi = proto_tree_add_item(tree, hf_dvbci_desc_num,
4065 tvb, offset, 1, ENC_BIG_ENDIAN);
4066 if (desc_num==OPP_NO_MORE_DESC)
4067 proto_item_append_text(pi, " (all descriptors were processed)");
4069 sig_strength = tvb_get_guint8(tvb, offset);
4070 proto_tree_add_item(tree, hf_dvbci_sig_strength,
4071 tvb, offset, 1, ENC_BIG_ENDIAN);
4073 sig_qual = tvb_get_guint8(tvb, offset);
4074 proto_tree_add_item(tree, hf_dvbci_sig_qual,
4075 tvb, offset, 1, ENC_BIG_ENDIAN);
4076 if (sig_strength>100 || sig_qual>100) {
4077 pi = proto_tree_add_text(tree, tvb, offset, 1,
4078 "Invalid value for signal strength / signal quality");
4079 expert_add_info(pinfo, pi, &ei_dvbci_sig_qual);
4082 proto_tree_add_item(tree, hf_dvbci_opp_tune_status,
4083 tvb, offset, 1, ENC_BIG_ENDIAN);
4084 dissect_desc_loop(hf_dvbci_opp_desc_loop_len,
4085 tvb, offset, pinfo, tree);
4087 case T_OPERATOR_TUNE:
4088 dissect_desc_loop(hf_dvbci_opp_desc_loop_len,
4089 tvb, offset, pinfo, tree);
4098 dissect_dvbci_payload_sas(guint32 tag, gint len_field _U_,
4099 tvbuff_t *tvb, gint offset, circuit_t *circuit,
4100 packet_info *pinfo, proto_tree *tree)
4102 gchar app_id_str[2+16+1]; /* "0x", string of 16 hex digits, trailing 0 */
4104 dissector_handle_t msg_handle;
4110 case T_SAS_CONNECT_RQST:
4111 case T_SAS_CONNECT_CNF:
4112 g_snprintf(app_id_str, sizeof(app_id_str),
4113 "0x%016" G_GINT64_MODIFIER "x", tvb_get_ntoh64(tvb, offset));
4114 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s", app_id_str);
4115 proto_tree_add_item(tree, hf_dvbci_sas_app_id,
4116 tvb, offset, 8, ENC_BIG_ENDIAN);
4118 if (tag == T_SAS_CONNECT_CNF) {
4119 sas_status = tvb_get_guint8(tvb, offset);
4120 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
4121 (sas_status == SAS_SESS_STATE_CONNECTED ?
4123 proto_tree_add_item(tree, hf_dvbci_sas_sess_state,
4124 tvb, offset, 1, ENC_BIG_ENDIAN);
4127 if (sas_status == SAS_SESS_STATE_CONNECTED) {
4128 msg_handle = dissector_get_string_handle(
4129 sas_msg_dissector_table, app_id_str);
4130 /* this clears the dissector for msg_handle==NULL */
4131 circuit_set_dissector(circuit, msg_handle);
4134 circuit_set_dissector(circuit, NULL);
4137 case T_SAS_ASYNC_MSG:
4138 msg_nb = tvb_get_guint8(tvb, offset);
4139 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
4140 "Message #%d ", msg_nb);
4141 proto_tree_add_item(tree, hf_dvbci_sas_msg_nb,
4142 tvb, offset, 1, ENC_BIG_ENDIAN);
4144 msg_len = tvb_get_ntohs(tvb, offset);
4145 proto_tree_add_item(tree, hf_dvbci_sas_msg_len,
4146 tvb, offset, 2, ENC_BIG_ENDIAN);
4148 msg_tvb = tvb_new_subset_length(tvb, offset, msg_len);
4149 msg_handle = (circuit && circuit->dissector_handle) ?
4150 circuit->dissector_handle : data_handle;
4151 call_dissector(msg_handle, msg_tvb, pinfo, tree);
4160 dissect_dvbci_apdu(tvbuff_t *tvb, circuit_t *circuit,
4161 packet_info *pinfo, proto_tree *tree, guint8 direction)
4164 proto_tree *app_tree;
4165 guint32 apdu_len, tag, len_field;
4166 const gchar *tag_str;
4170 guint32 apdu_res_id;
4171 const gchar *ai_res_class_str;
4174 apdu_len = tvb_reported_length(tvb);
4176 ti = proto_tree_add_text(tree, tvb, 0, apdu_len, "Application Layer");
4177 app_tree = proto_item_add_subtree(ti, ett_dvbci_application);
4179 tag = tvb_get_ntoh24(tvb, 0);
4180 tag_str = try_val_to_str(tag, dvbci_apdu_tag);
4181 offset = APDU_TAG_SIZE;
4183 col_set_str(pinfo->cinfo, COL_INFO,
4184 val_to_str_const(tag, dvbci_apdu_tag, "Unknown/invalid APDU"));
4185 pi = proto_tree_add_item(
4186 app_tree, hf_dvbci_apdu_tag, tvb, 0, APDU_TAG_SIZE, ENC_BIG_ENDIAN);
4187 if (tag_str == NULL) {
4188 expert_add_info(pinfo, pi, &ei_dvbci_apdu_tag);
4192 offset = dissect_ber_length(pinfo, app_tree, tvb, offset, &len_field, NULL);
4193 if ((offset+len_field) != apdu_len) {
4194 proto_tree_add_expert_format(app_tree, pinfo, &ei_dvbci_bad_length, tvb,
4195 APDU_TAG_SIZE, offset-APDU_TAG_SIZE,
4196 "Length field is different from the number of apdu payload bytes");
4197 /* we need len_field bytes of apdu payload to call
4198 ai->dissect_payload() and continue dissecting */
4199 if (apdu_len < offset+len_field)
4203 ai = (apdu_info_t *)g_hash_table_lookup(apdu_table,
4204 GUINT_TO_POINTER((guint)tag));
4206 proto_tree_add_expert(app_tree, pinfo, &ei_dvbci_apdu_not_supported, tvb, 0, APDU_TAG_SIZE);
4209 if (ai->direction!=DIRECTION_ANY && ai->direction!=direction) {
4210 if (ai->direction==DATA_HOST_TO_CAM) {
4211 proto_tree_add_expert(app_tree, pinfo, &ei_dvbci_apu_host_to_cam, tvb, 0, APDU_TAG_SIZE);
4214 proto_tree_add_expert(app_tree, pinfo, &ei_dvbci_apu_cam_to_host, tvb, 0, APDU_TAG_SIZE);
4216 /* don't return, we can continue dissecting the APDU */
4218 if (ai->min_len_field!=LEN_FIELD_ANY && len_field<ai->min_len_field) {
4219 proto_tree_add_expert_format(app_tree, pinfo, &ei_dvbci_bad_length, tvb, 0, APDU_TAG_SIZE,
4220 "Invalid APDU length field, minimum length field for %s is %d", tag_str, ai->min_len_field);
4223 if (ai->len_field!=LEN_FIELD_ANY && len_field!=ai->len_field) {
4224 proto_tree_add_expert_format(app_tree, pinfo, &ei_dvbci_bad_length, tvb, 0, APDU_TAG_SIZE,
4225 "Invalid APDU length field, length field for %s must be %d", tag_str, ai->len_field);
4229 apdu_res_id = GPOINTER_TO_UINT(
4230 (gpointer)circuit_get_proto_data(circuit, proto_dvbci));
4232 ai_res_class_str = val_to_str_const(ai->res_class, dvbci_res_class, "Unknown");
4234 if(RES_CLASS(apdu_res_id) != ai->res_class) {
4235 proto_tree_add_expert_format(app_tree, pinfo, &ei_dvbci_res_class, tvb, 0, APDU_TAG_SIZE,
4236 "Invalid resource class for this apdu, %s can only be sent on a %s session",
4237 tag_str, ai_res_class_str);
4239 if(RES_VER(apdu_res_id) < ai->res_min_ver) {
4240 proto_tree_add_expert_format(app_tree, pinfo, &ei_dvbci_res_ver, tvb, 0, APDU_TAG_SIZE,
4241 "Invalid resource version for this apdu, %s apdu requires at least %s version %d",
4242 tag_str, ai_res_class_str, ai->res_min_ver);
4244 /* don't return, we can continue dissecting the APDU */
4246 if (ai->len_field!=0) {
4247 if (!ai->dissect_payload) {
4248 /* don't display an error, getting here means we have illegal
4249 * data in apdu_info[] */
4252 ai->dissect_payload(
4253 tag, len_field, tvb, offset, circuit, pinfo, app_tree);
4258 dissect_dvbci_spdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4259 guint8 direction, guint8 tcid)
4263 proto_tree *sess_tree;
4265 const gchar *tag_str;
4266 circuit_t *circuit = NULL;
4270 const spdu_info_t *si;
4271 proto_item *res_id_it = NULL;
4273 guint16 ssnb = 0; /* session numbers start with 1, 0 is invalid */
4275 tvbuff_t *payload_tvb = NULL;
4278 spdu_len = tvb_reported_length(tvb);
4280 ti = proto_tree_add_text(tree, tvb, 0, -1, "Session Layer");
4281 sess_tree = proto_item_add_subtree(ti, ett_dvbci_session);
4283 tag = tvb_get_guint8(tvb,0);
4284 tag_str = try_val_to_str(tag, dvbci_spdu_tag);
4285 col_set_str(pinfo->cinfo, COL_INFO,
4286 val_to_str_const(tag, dvbci_spdu_tag, "Invalid SPDU"));
4287 pi = proto_tree_add_item(sess_tree, hf_dvbci_spdu_tag, tvb, 0, 1, ENC_BIG_ENDIAN);
4288 if (tag_str == NULL) {
4289 expert_add_info(pinfo, pi, &ei_dvbci_spdu_tag);
4293 offset = dissect_ber_length(pinfo, sess_tree, tvb, 1, &len_field, NULL);
4295 si = (spdu_info_t *)g_hash_table_lookup(spdu_table,
4296 GUINT_TO_POINTER((guint)tag));
4299 if (si->direction!=0 && si->direction!=direction) {
4300 if (si->direction==DATA_HOST_TO_CAM) {
4301 proto_tree_add_expert(sess_tree, pinfo, &ei_dvbci_spdu_host_to_cam, tvb, 0, 1);
4304 proto_tree_add_expert(sess_tree, pinfo, &ei_dvbci_spdu_cam_to_host, tvb, 0, 1);
4307 if (si->len_field != len_field) {
4308 /* offset points to 1st byte after the length field */
4309 proto_tree_add_expert_format(sess_tree, pinfo, &ei_dvbci_bad_length, tvb, 1, offset-1,
4310 "Invalid SPDU length field, correct length field for %s is %d", tag_str, si->len_field);
4316 case T_OPEN_SESSION_REQUEST:
4317 res_id_it = dissect_res_id(tvb, offset, pinfo, sess_tree, 0, TRUE);
4319 case T_CREATE_SESSION:
4320 res_id_it = dissect_res_id(tvb, offset, pinfo, sess_tree, 0, TRUE);
4321 /* DVB-CI uses network byte order == big endian */
4322 ssnb = tvb_get_ntohs(tvb, offset+RES_ID_LEN);
4323 proto_tree_add_item(sess_tree, hf_dvbci_sess_nb,
4324 tvb, offset+RES_ID_LEN, 2, ENC_BIG_ENDIAN);
4326 case T_OPEN_SESSION_RESPONSE:
4327 case T_CREATE_SESSION_RESPONSE:
4328 sess_stat = tvb_get_guint8(tvb, offset);
4329 proto_tree_add_item(sess_tree, hf_dvbci_sess_status,
4330 tvb, offset, 1, ENC_BIG_ENDIAN);
4331 res_id = tvb_get_ntohl(tvb, offset+1);
4332 res_id_it = dissect_res_id(tvb, offset+1, pinfo, sess_tree, 0, TRUE);
4333 ssnb = tvb_get_ntohs(tvb, offset+1+RES_ID_LEN);
4334 proto_tree_add_item(sess_tree, hf_dvbci_sess_nb, tvb,
4335 offset+1+RES_ID_LEN, 2, ENC_BIG_ENDIAN);
4336 if (sess_stat != SESS_OPENED) {
4337 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Error");
4340 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Session opened");
4341 circuit = circuit_new(CT_DVBCI, CT_ID(ssnb, tcid), pinfo->fd->num);
4343 /* we always add the resource id immediately after the circuit
4345 circuit_add_proto_data(
4346 circuit, proto_dvbci, GUINT_TO_POINTER(res_id));
4349 case T_CLOSE_SESSION_REQUEST:
4350 ssnb = tvb_get_ntohs(tvb, offset);
4351 proto_tree_add_item(
4352 sess_tree, hf_dvbci_sess_nb, tvb,
4353 offset, 2, ENC_BIG_ENDIAN);
4355 case T_CLOSE_SESSION_RESPONSE:
4356 sess_stat = tvb_get_guint8(tvb, offset);
4357 proto_tree_add_item(
4358 sess_tree, hf_dvbci_close_sess_status, tvb,
4359 offset, 1, ENC_BIG_ENDIAN);
4360 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
4361 sess_stat==SESS_CLOSED ? "Session closed" : "Error");
4362 ssnb = tvb_get_ntohs(tvb, offset+1);
4363 proto_tree_add_item(sess_tree, hf_dvbci_sess_nb,
4364 tvb, offset+1, 2, ENC_BIG_ENDIAN);
4365 circuit = find_circuit(CT_DVBCI, CT_ID(ssnb, tcid), pinfo->fd->num);
4367 close_circuit(circuit, pinfo->fd->num);
4369 case T_SESSION_NUMBER:
4370 ssnb = tvb_get_ntohs(tvb, offset);
4371 proto_tree_add_item(
4372 sess_tree, hf_dvbci_sess_nb, tvb,
4373 offset, 2, ENC_BIG_ENDIAN);
4375 tvb_new_subset_remaining(tvb, offset+2);
4381 if (ssnb && !circuit)
4382 circuit = find_circuit(CT_DVBCI, CT_ID(ssnb, tcid), pinfo->fd->num);
4384 /* if the packet contains no resource id, we add the cached id from
4385 the circuit so that each packet has a resource id that can be
4386 used for filtering */
4387 if (circuit && !res_id_it) {
4388 /* when a circuit is found, it always contains a valid resource id */
4389 res_id = GPOINTER_TO_UINT(
4390 (gpointer)circuit_get_proto_data(circuit, proto_dvbci));
4391 res_id_it = dissect_res_id(NULL, 0, pinfo, sess_tree, res_id, TRUE);
4392 PROTO_ITEM_SET_GENERATED(res_id_it);
4396 proto_item_set_len(ti, spdu_len-tvb_reported_length(payload_tvb));
4397 dissect_dvbci_apdu(payload_tvb, circuit, pinfo, tree, direction);
4400 proto_item_set_len(ti, spdu_len);
4404 /* dissect the status of an r_tpdu, return its length or -1 for error */
4406 dissect_dvbci_tpdu_status(tvbuff_t *tvb, gint offset,
4407 packet_info *pinfo, proto_tree *tree,
4408 guint8 lpdu_tcid, guint8 r_tpdu_tag)
4410 gint offset_new, len_start_offset;
4413 guint8 t_c_id, sb_value;
4414 const gchar *sb_str;
4417 offset_new = offset;
4419 tag = tvb_get_guint8(tvb, offset_new);
4421 proto_tree_add_expert(tree, pinfo, &ei_dvbci_tpdu_status_tag, tvb, offset_new, 1);
4424 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "T_SB");
4425 proto_tree_add_text(tree, tvb, offset_new, 1, "Response TPDU status");
4428 len_start_offset = offset_new;
4429 offset_new = dissect_ber_length(
4430 pinfo, tree, tvb, offset_new, &len_field, NULL);
4431 if (len_field != 2) {
4432 proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb, len_start_offset, offset_new-len_start_offset,
4433 "Invalid status length field, this must always be 2");
4438 t_c_id = tvb_get_guint8(tvb, offset_new);
4439 proto_tree_add_item(tree, hf_dvbci_t_c_id, tvb, offset_new, 1, ENC_BIG_ENDIAN);
4440 /* tcid in transport header and link layer must only match for data
4441 * transmission commands */
4442 if (t_c_id!=lpdu_tcid) {
4443 if (r_tpdu_tag==NO_TAG ||
4444 r_tpdu_tag==T_DATA_MORE || r_tpdu_tag==T_DATA_LAST) {
4446 pi = proto_tree_add_text(tree, tvb, offset_new, 1,
4447 "Transport Connection ID mismatch");
4448 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", t_c_id, lpdu_tcid);
4455 sb_value = tvb_get_guint8(tvb, offset_new);
4456 sb_str = try_val_to_str(sb_value, dvbci_sb_value);
4457 pi = proto_tree_add_item(tree, hf_dvbci_sb_value, tvb,
4458 offset_new, 1, ENC_BIG_ENDIAN);
4460 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s", sb_str);
4463 proto_tree_add_text(tree, tvb, offset_new, 1,
4464 "Invalid SB_value");
4465 expert_add_info(pinfo, pi, &ei_dvbci_sb_value);
4469 return offset_new-offset;
4473 /* dissect the header of a c_tpdu or r_tpdu
4474 return the length of the header (tag, len_field, t_c_id) or -1 for error */
4476 dissect_dvbci_tpdu_hdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4477 guint8 direction, guint8 lpdu_tcid, guint32 tpdu_len,
4478 guint8 *hdr_tag, guint32 *body_len)
4480 guint8 c_tpdu_tag, r_tpdu_tag, *tag = NULL;
4481 const gchar *c_tpdu_str, *r_tpdu_str;
4487 if (direction==DATA_HOST_TO_CAM) {
4488 c_tpdu_tag = tvb_get_guint8(tvb, 0);
4490 c_tpdu_str = try_val_to_str(c_tpdu_tag, dvbci_c_tpdu);
4491 pi = proto_tree_add_item(tree, hf_dvbci_c_tpdu_tag, tvb, 0, 1, ENC_BIG_ENDIAN);
4493 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "%s", c_tpdu_str);
4496 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
4497 "Invalid Command-TPDU tag");
4498 expert_add_info(pinfo, pi, &ei_dvbci_c_tpdu_tag);
4503 r_tpdu_tag = tvb_get_guint8(tvb, 0);
4505 r_tpdu_str = try_val_to_str(r_tpdu_tag, dvbci_r_tpdu);
4506 pi = proto_tree_add_item(tree, hf_dvbci_r_tpdu_tag, tvb, 0, 1, ENC_BIG_ENDIAN);
4508 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "%s", r_tpdu_str);
4511 if (r_tpdu_tag == T_SB) {
4512 /* we have an r_tpdu without header and body,
4513 it contains only the status part */
4521 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
4522 "Invalid Response-TPDU tag");
4523 expert_add_info(pinfo, pi, &ei_dvbci_r_tpdu_tag);
4529 offset = dissect_ber_length(pinfo, tree, tvb, 1, &len_field, NULL);
4530 /* len_field must be at least 1 for the following t_c_id
4531 c_tpdu's len_field must match tvbuff exactly
4532 r_tpdu's len_field does not include the status part after the body */
4534 ((direction==DATA_HOST_TO_CAM) && ((offset+len_field)!=tpdu_len)) ||
4535 ((direction==DATA_CAM_TO_HOST) && ((offset+len_field)>tpdu_len))) {
4536 /* offset points to 1st byte after the length field */
4537 proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_bad_length, tvb, 1, offset-1,
4538 len_field==0 ? "Invalid length field, length field must be at least 1" :
4539 "Invalid length field, length field mismatch");
4543 t_c_id = tvb_get_guint8(tvb, offset);
4544 pi = proto_tree_add_item(tree, hf_dvbci_t_c_id, tvb, offset, 1, ENC_BIG_ENDIAN);
4545 /* tcid in transport header and link layer must only match for
4546 * data transmission commands */
4547 if (t_c_id!=lpdu_tcid) {
4548 if (tag && (*tag==T_RCV || *tag==T_DATA_MORE || *tag==T_DATA_LAST)) {
4549 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",
4554 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "tcid %d", t_c_id);
4561 *body_len = len_field-1; /* -1 for t_c_id */
4566 dissect_dvbci_tpdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4567 guint8 direction, guint8 lpdu_tcid)
4569 guint32 tpdu_len, body_len;
4571 proto_tree *trans_tree;
4572 gint offset, status_len;
4573 guint8 hdr_tag = NO_TAG;
4574 tvbuff_t *body_tvb, *payload_tvb = NULL;
4575 fragment_head *frag_msg = NULL;
4578 tpdu_len = tvb_reported_length(tvb);
4580 col_clear(pinfo->cinfo, COL_INFO);
4582 ti = proto_tree_add_text(tree, tvb, 0, -1, "Transport Layer");
4583 trans_tree = proto_item_add_subtree(ti, ett_dvbci_transport);
4585 offset = dissect_dvbci_tpdu_hdr(tvb, pinfo, trans_tree, direction,
4586 lpdu_tcid, tpdu_len, &hdr_tag, &body_len);
4589 proto_item_set_len(ti, offset);
4590 if ((offset>0) && (body_len!=0)) {
4591 /* for unfragmented data, the reassembly api behaviour is unclear
4592 if we put the body part of the tvb into fragment_add_seq_next(),
4593 process_reassembled_data() returns the remainder of the tvb
4594 which is body|status part
4595 if there's more than one fragment, payload_tvb contains only
4596 the reassembled bodies as expected
4597 to work around this issue, we use a dedicated body_tvb as
4598 input to reassembly routines */
4599 body_tvb = tvb_new_subset_length(tvb, offset, body_len);
4600 /* dissect_dvbci_tpdu_hdr() checked that lpdu_tcid==t_c_id */
4601 frag_msg = fragment_add_seq_next(&spdu_reassembly_table,
4602 body_tvb, 0, pinfo, SPDU_SEQ_ID_BASE+lpdu_tcid, NULL,
4604 hdr_tag == T_DATA_MORE ? 1 : 0);
4605 payload_tvb = process_reassembled_data(body_tvb, 0, pinfo,
4606 "Reassembled SPDU", frag_msg, &spdu_frag_items,
4609 if (hdr_tag == T_DATA_MORE) {
4610 pinfo->fragmented = TRUE;
4611 col_append_str(pinfo->cinfo, COL_INFO, " (Message fragment)");
4613 payload_tvb = body_tvb;
4619 if (direction==DATA_CAM_TO_HOST) {
4620 /* minimum length of an rtpdu status is 4 bytes */
4621 if (tpdu_len-offset < 4) {
4622 proto_tree_add_expert(trans_tree, pinfo, &ei_dvbci_r_tpdu_status_mandatory, tvb, 0, 0);
4625 status_len = dissect_dvbci_tpdu_status(
4626 tvb, offset, pinfo, trans_tree, lpdu_tcid, hdr_tag);
4629 proto_tree_set_appendix(trans_tree, tvb, offset, status_len);
4633 dissect_dvbci_spdu(payload_tvb, pinfo, tree, direction, lpdu_tcid);
4638 dissect_dvbci_lpdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4642 proto_tree *link_tree;
4643 guint32 payload_len;
4644 guint8 tcid, more_last;
4646 tvbuff_t *payload_tvb;
4647 fragment_head *frag_msg;
4650 payload_len = tvb_reported_length(tvb);
4652 col_set_str(pinfo->cinfo, COL_INFO, "LPDU");
4654 ti = proto_tree_add_text(tree, tvb, 0, 2, "Link Layer");
4655 link_tree = proto_item_add_subtree(ti, ett_dvbci_link);
4657 tcid = tvb_get_guint8(tvb, 0);
4658 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "tcid %d", tcid);
4659 proto_tree_add_item(link_tree, hf_dvbci_tcid, tvb, 0, 1, ENC_BIG_ENDIAN);
4661 more_last = tvb_get_guint8(tvb, 1);
4662 pi = proto_tree_add_item(link_tree, hf_dvbci_ml, tvb, 1, 1, ENC_BIG_ENDIAN);
4663 if (try_val_to_str(more_last, dvbci_ml) == NULL) {
4664 expert_add_info(pinfo, pi, &ei_dvbci_ml);
4667 /* buf_size_host==0 -> we did not capture the buffer size negotiation */
4668 if (buf_size_host!=0 && payload_len>buf_size_host) {
4669 proto_tree_add_expert_format(link_tree, pinfo, &ei_dvbci_bad_length, tvb, 2, payload_len,
4670 "Payload too large, maximum payload length is the negotiated buffer size (%d bytes)", buf_size_host);
4673 frag_msg = fragment_add_seq_next(&tpdu_reassembly_table,
4674 tvb, 2, pinfo, TPDU_SEQ_ID_BASE+tcid, NULL,
4675 tvb_reported_length_remaining(tvb, 2),
4676 more_last == ML_MORE ? 1 : 0);
4678 payload_tvb = process_reassembled_data(tvb, 2, pinfo,
4679 "Reassembled TPDU", frag_msg, &tpdu_frag_items,
4682 if (more_last == ML_MORE) {
4683 pinfo->fragmented = TRUE;
4684 col_append_str(pinfo->cinfo, COL_INFO, " (Message fragment)");
4686 payload_tvb = tvb_new_subset_remaining(tvb, 2);
4689 dissect_dvbci_tpdu(payload_tvb, pinfo, tree, direction, tcid);
4692 /* dissect DVB-CI buffer size negotiation */
4694 dissect_dvbci_buf_neg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4700 buf_size = tvb_get_ntohs(tvb, 0);
4702 col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %u bytes",
4703 direction == DATA_HOST_TO_CAM ?
4704 "negotiated buffer size" : "buffer size proposal",
4707 if (direction == DATA_HOST_TO_CAM) {
4708 buf_size_host = buf_size;
4709 pi = proto_tree_add_uint_format(tree, hf_dvbci_buf_size, tvb,
4711 "Negotiated buffer size: %u bytes", buf_size);
4712 if (buf_size_host > buf_size_cam) {
4714 wireshark may run through each packet multiple times
4715 if we didn't check the direction, we'd get the error when
4716 wireshark runs through the initial CAM packet for the 2nd time
4718 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");
4721 else if (direction == DATA_CAM_TO_HOST) {
4722 buf_size_cam = buf_size;
4723 proto_tree_add_uint_format(tree, hf_dvbci_buf_size, tvb,
4725 "Buffer size proposal by the CAM: %u bytes", buf_size);
4728 if (buf_size < 16) {
4729 proto_tree_add_expert_format(tree, pinfo, &ei_dvbci_buf_size, tvb, 0, 2,
4730 "Illegal buffer size, minimum buffer size is 16 bytes");
4734 /* dissect Level 1 version/product information tuple's payload
4735 data_tvb is a separate tvb for the tuple payload (without tag and len)
4736 return the number of dissected bytes or -1 for error */
4738 dissect_dvbci_cis_payload_tpll_v1(tvbuff_t *data_tvb,
4739 packet_info *pinfo _U_, proto_tree *tree)
4741 gint offset=0, offset_str_end;
4743 /* the CIS is defined by PCMCIA, all multi-byte values are little endian
4744 (the rest of DVB-CI is a big-endian protocol) */
4745 proto_tree_add_item(tree, hf_dvbci_cis_tpll_v1_major,
4746 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4748 proto_tree_add_item(tree, hf_dvbci_cis_tpll_v1_minor,
4749 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4752 /* manufacturer, name and additional infos are 0-terminated strings */
4753 offset_str_end = tvb_find_guint8(data_tvb, offset, -1, 0x0);
4754 if (offset_str_end<offset) /* offset_str_end==offset is ok */
4756 proto_tree_add_item(tree, hf_dvbci_cis_tpll_v1_info_manuf,
4757 data_tvb, offset, offset_str_end-offset, ENC_ASCII|ENC_NA);
4758 offset = offset_str_end+1; /* +1 for 0 termination */
4760 offset_str_end = tvb_find_guint8(data_tvb, offset, -1, 0x0);
4761 if (offset_str_end<offset)
4763 proto_tree_add_item(tree, hf_dvbci_cis_tpll_v1_info_name,
4764 data_tvb, offset, offset_str_end-offset, ENC_ASCII|ENC_NA);
4765 offset = offset_str_end+1;
4767 /* the pc-card spec mentions two additional info strings,
4768 it's unclear if both are mandatory
4769 >1 because the last byte is the tuple end marker */
4770 while (tvb_reported_length_remaining(data_tvb, offset)>1) {
4771 offset_str_end = tvb_find_guint8(data_tvb, offset, -1, 0x0);
4772 if (offset_str_end<offset)
4774 proto_tree_add_item(tree, hf_dvbci_cis_tpll_v1_info_additional,
4775 data_tvb, offset, offset_str_end-offset, ENC_ASCII|ENC_NA);
4776 offset = offset_str_end+1;
4779 proto_tree_add_item(tree, hf_dvbci_cis_tpll_v1_end,
4780 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4787 dissect_dvbci_cis_payload_config(tvbuff_t *data_tvb,
4788 packet_info *pinfo _U_, proto_tree *tree)
4791 /* these are the actual sizes, the CIS stores rmsz-1 and rasz-1 */
4792 guint8 rfsz, rmsz, rasz;
4793 guint8 st_code, st_len;
4794 const gchar *st_code_str;
4795 proto_item *st_item = NULL;
4796 proto_tree *st_tree = NULL;
4797 guint8 stci_ifn_size; /* actual size, see comment above */
4799 rfsz = (tvb_get_guint8(data_tvb, offset)&0xC0) >> 6;
4800 proto_tree_add_item(tree, hf_dvbci_cis_tpcc_rfsz,
4801 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4802 rmsz = ((tvb_get_guint8(data_tvb, offset)&0x3C) >> 2) + 1;
4803 proto_tree_add_item(tree, hf_dvbci_cis_tpcc_rmsz,
4804 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4805 rasz = (tvb_get_guint8(data_tvb, offset)&0x03) + 1;
4806 proto_tree_add_item(tree, hf_dvbci_cis_tpcc_rasz,
4807 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4810 proto_tree_add_item(tree, hf_dvbci_cis_tpcc_last,
4811 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4814 proto_tree_add_item(tree, hf_dvbci_cis_tpcc_radr,
4815 data_tvb, offset, rasz, ENC_LITTLE_ENDIAN);
4817 proto_tree_add_item(tree, hf_dvbci_cis_tpcc_rmsk,
4818 data_tvb, offset, rmsz, ENC_NA);
4820 offset += rfsz; /* skip reserved bytes */
4822 while (tvb_reported_length_remaining(data_tvb, offset) > 0) {
4823 st_code = tvb_get_guint8(data_tvb, offset);
4824 st_code_str = val_to_str_const(st_code, dvbci_cis_subtpl_code, "unknown");
4825 st_item = proto_tree_add_text(tree, data_tvb, offset, -1,
4826 "Subtuple: %s (0x%x)", st_code_str, st_code);
4827 st_tree = proto_item_add_subtree(st_item, ett_dvbci_cis_subtpl);
4828 proto_tree_add_item(st_tree, hf_dvbci_cis_st_code,
4829 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4831 st_len = tvb_get_guint8(data_tvb, offset);
4832 proto_item_set_len(st_item, 2+st_len); /* tag, len byte, body */
4833 proto_tree_add_item(st_tree, hf_dvbci_cis_st_len,
4834 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4836 if (st_code == CCSTPL_CIF) {
4837 stci_ifn_size = ((tvb_get_guint8(data_tvb, offset) & 0xC0)>>6)+1;
4838 proto_tree_add_item(st_tree, hf_dvbci_cis_stci_ifn_size,
4839 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4840 /* don't increment offset,
4841 size and actual value's LSB share the same byte */
4842 proto_tree_add_item(st_tree, hf_dvbci_cis_stci_ifn,
4843 data_tvb, offset, stci_ifn_size, ENC_LITTLE_ENDIAN);
4844 offset += stci_ifn_size;
4845 /* the stci_str field could consist of multiple strings,
4846 this case is not supported for now */
4847 proto_tree_add_item(st_tree, hf_dvbci_cis_stci_str,
4848 data_tvb, offset, st_len-stci_ifn_size, ENC_ASCII|ENC_NA);
4849 offset += st_len-stci_ifn_size;
4852 /* skip unknown subtuple's content */
4862 dissect_dvbci_cis_payload_cftable_entry(tvbuff_t *data_tvb,
4863 packet_info *pinfo _U_, proto_tree *tree)
4866 gboolean intface_flag;
4868 intface_flag = ((tvb_get_guint8(data_tvb, offset) & 0x80) == 0x80);
4869 /* tpce_indx byte */
4870 proto_tree_add_item(tree, hf_dvbci_cis_tpce_indx_intface,
4871 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4872 proto_tree_add_item(tree, hf_dvbci_cis_tpce_indx_default,
4873 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4874 proto_tree_add_item(tree, hf_dvbci_cis_tpce_indx_cnf_entry,
4875 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4880 proto_tree_add_item(tree, hf_dvbci_cis_tpce_if_type,
4881 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4882 /* XXX parse other components of tpce_if */
4886 /* tpce_fs byte: this is present in any case */
4887 proto_tree_add_item(tree, hf_dvbci_cis_tpce_fs_mem_space,
4888 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4889 proto_tree_add_item(tree, hf_dvbci_cis_tpce_fs_irq,
4890 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4891 proto_tree_add_item(tree, hf_dvbci_cis_tpce_fs_io,
4892 data_tvb, offset, 1, ENC_LITTLE_ENDIAN);
4893 /* XXX parse other components of tpce_fs */
4900 dissect_dvbci_cis(tvbuff_t *tvb, gint offset,
4901 packet_info *pinfo, proto_tree *tree)
4904 proto_tree *cis_tree = NULL, *tpl_tree = NULL;
4905 proto_item *ti_main = NULL, *ti_tpl;
4907 const gchar *tpl_code_str = NULL;
4909 tvbuff_t *tpl_data_tvb;
4911 offset_start = offset;
4913 ti_main = proto_tree_add_text(tree, tvb, offset, -1,
4914 "Card Information Structure (CIS)");
4915 cis_tree = proto_item_add_subtree(ti_main, ett_dvbci_cis);
4918 tpl_code = tvb_get_guint8(tvb, offset);
4919 tpl_code_str = val_to_str_const(tpl_code, dvbci_cis_tpl_code, "unknown");
4921 ti_tpl = proto_tree_add_text(cis_tree,
4922 tvb, offset, -1, "CIS tuple: %s", tpl_code_str);
4923 tpl_tree = proto_item_add_subtree(ti_tpl, ett_dvbci_cis_tpl);
4925 proto_tree_add_uint_format(tpl_tree, hf_dvbci_cis_tpl_code,
4926 tvb, offset, 1, tpl_code, "Tuple code: %s (0x%x)",
4927 tpl_code_str, tpl_code);
4930 if (tpl_code == CISTPL_END) {
4931 proto_item_set_len(ti_tpl, 1); /* only tag (no len and content) */
4935 len_field = tvb_get_guint8(tvb, offset);
4936 proto_tree_add_item(tpl_tree, hf_dvbci_cis_tpl_len,
4937 tvb, offset, 1, ENC_LITTLE_ENDIAN);
4940 tpl_data_tvb = tvb_new_subset_length(tvb, offset, len_field);
4943 dissect_dvbci_cis_payload_tpll_v1(
4944 tpl_data_tvb, pinfo, tpl_tree);
4945 offset += len_field;
4948 dissect_dvbci_cis_payload_config(tpl_data_tvb, pinfo, tpl_tree);
4949 offset += len_field;
4951 case CISTPL_CFTABLE_ENTRY:
4952 dissect_dvbci_cis_payload_cftable_entry(
4953 tpl_data_tvb, pinfo, tpl_tree);
4954 offset += len_field;
4957 proto_tree_add_item(tpl_tree, hf_dvbci_cis_tplmid_manf,
4958 tvb, offset, 2, ENC_LITTLE_ENDIAN);
4960 proto_tree_add_item(tpl_tree, hf_dvbci_cis_tplmid_card,
4961 tvb, offset, 2, ENC_LITTLE_ENDIAN);
4966 proto_tree_add_item(tpl_tree, hf_dvbci_cis_tpl_data,
4967 tvb, offset, len_field, ENC_NA);
4969 offset += len_field;
4973 proto_item_set_len(ti_tpl, 2+len_field); /* tag, len byte, content */
4975 } while (tvb_reported_length_remaining(tvb, offset) > 0);
4977 proto_item_set_len(ti_main, offset-offset_start);
4982 dissect_dvbci(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
4984 gint packet_len, offset = 0, offset_ver, offset_evt, offset_len_field;
4985 guint8 version, event;
4986 const gchar *event_str;
4988 proto_item *ti, *ti_hdr;
4989 proto_tree *dvbci_tree, *hdr_tree;
4990 tvbuff_t *payload_tvb;
4996 if (tvb_length(tvb) < 4)
4999 offset_ver = offset;
5000 version = tvb_get_guint8(tvb, offset++);
5004 offset_evt = offset;
5005 event = tvb_get_guint8(tvb, offset++);
5006 event_str = try_val_to_str(event, dvbci_event);
5010 packet_len = tvb_reported_length(tvb);
5011 offset_len_field = offset;
5012 len_field = tvb_get_ntohs(tvb, offset);
5013 if (len_field != (packet_len-4))
5017 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DVB-CI");
5018 col_set_str(pinfo->cinfo, COL_INFO, event_str);
5020 ti = proto_tree_add_protocol_format(tree, proto_dvbci,
5021 tvb, 0, packet_len, "DVB Common Interface: %s", event_str);
5022 dvbci_tree = proto_item_add_subtree(ti, ett_dvbci);
5023 ti_hdr = proto_tree_add_text(dvbci_tree, tvb, 0, offset, "Pseudo header");
5024 hdr_tree = proto_item_add_subtree(ti_hdr, ett_dvbci_hdr);
5025 proto_tree_add_text(hdr_tree, tvb, offset_ver, 1, "Version: %d", version);
5026 proto_tree_add_item(hdr_tree, hf_dvbci_event, tvb, offset_evt, 1, ENC_BIG_ENDIAN);
5027 proto_tree_add_text(hdr_tree, tvb, offset_len_field, 2,
5028 "Length field: %d", len_field);
5030 if (IS_DATA_TRANSFER(event)) {
5031 dvbci_set_addrs(event, pinfo);
5033 payload_tvb = tvb_new_subset_remaining( tvb, offset);
5034 if (len_field == 2) {
5035 dissect_dvbci_buf_neg(payload_tvb, pinfo, dvbci_tree, event);
5038 dissect_dvbci_lpdu(payload_tvb, pinfo, dvbci_tree, event);
5041 else if (event==DVBCI_EVT_COR_WRITE) {
5042 /* PCAP format for DVB-CI defines COR address as big endian */
5043 pi = proto_tree_add_item(dvbci_tree, hf_dvbci_cor_addr,
5044 tvb, offset, 2, ENC_BIG_ENDIAN);
5045 cor_addr = tvb_get_ntohs(tvb, offset);
5046 if (cor_addr == 0xFFFF) {
5047 proto_item_append_text(pi, " (COR address is unknown)");
5048 col_append_sep_str(pinfo->cinfo, COL_INFO, ": ", "unknown address");
5050 else if (cor_addr > 0xFFE) {
5051 expert_add_info(pinfo, pi, &ei_dvbci_cor_addr);
5054 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
5055 "address 0x%x", cor_addr);
5058 cor_value = tvb_get_guint8(tvb, offset);
5059 proto_tree_add_item(dvbci_tree, hf_dvbci_cor_val,
5060 tvb, offset, 1, ENC_BIG_ENDIAN);
5061 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL,
5062 "value 0x%x", cor_value);
5064 else if (event==DVBCI_EVT_CIS_READ) {
5065 dissect_dvbci_cis(tvb, offset, pinfo, dvbci_tree);
5067 else if (event==DVBCI_EVT_HW_EVT) {
5068 hw_event = tvb_get_guint8(tvb, offset);
5069 col_set_str(pinfo->cinfo, COL_INFO,
5070 val_to_str_const(hw_event, dvbci_hw_event, "Invalid hardware event"));
5071 proto_tree_add_item(dvbci_tree, hf_dvbci_hw_event,
5072 tvb, offset, 1, ENC_BIG_ENDIAN);
5080 proto_register_dvbci(void)
5083 module_t *dvbci_module;
5084 expert_module_t* expert_dvbci;
5086 static gint *ett[] = {
5091 &ett_dvbci_cis_subtpl,
5093 &ett_dvbci_link_frag,
5094 &ett_dvbci_link_frags,
5095 &ett_dvbci_transport,
5096 &ett_dvbci_transport_frag,
5097 &ett_dvbci_transport_frags,
5100 &ett_dvbci_application,
5105 &ett_dvbci_sac_msg_body,
5106 &ett_dvbci_ami_req_types,
5107 &ett_dvbci_lsc_conn_desc,
5108 &ett_dvbci_opp_cap_loop,
5109 &ett_dvbci_dlv_sys_hint
5112 static hf_register_info hf[] = {
5114 { "Event", "dvb-ci.event",
5115 FT_UINT8, BASE_HEX, VALS(dvbci_event), 0, NULL, HFILL }
5117 { &hf_dvbci_hw_event,
5118 { "Hardware event", "dvb-ci.hw_event",
5119 FT_UINT8, BASE_HEX, VALS(dvbci_hw_event), 0, NULL, HFILL }
5121 { &hf_dvbci_cor_addr,
5122 { "COR address", "dvb-ci.cor_address",
5123 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5125 { &hf_dvbci_cor_val,
5126 { "COR value", "dvb-ci.cor_value",
5127 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5129 { &hf_dvbci_cis_tpl_code,
5130 { "CIS tuple code", "dvb-ci.cis.tpl_code",
5131 FT_UINT8, BASE_HEX, VALS(dvbci_cis_tpl_code), 0, NULL, HFILL }
5133 { &hf_dvbci_cis_tpl_len,
5134 { "Length field", "dvb-ci.cis.tpl_len",
5135 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5137 { &hf_dvbci_cis_tpl_data,
5138 { "Tuple data", "dvb-ci.cis.tpl_data",
5139 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5141 { &hf_dvbci_cis_tpll_v1_major,
5142 { "Major version number", "dvb-ci.cis.tpll_v1_major",
5143 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5145 { &hf_dvbci_cis_tpll_v1_minor,
5146 { "Minor version number", "dvb-ci.cis.tpll_v1_minor",
5147 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5149 { &hf_dvbci_cis_tpll_v1_info_manuf,
5150 { "Manufacturer", "dvb-ci.cis.tpll_v1_info.manufacturer",
5151 FT_STRING, STR_ASCII, NULL, 0, NULL, HFILL }
5153 { &hf_dvbci_cis_tpll_v1_info_name,
5154 { "Name", "dvb-ci.cis.tpll_v1_info.name",
5155 FT_STRING, STR_ASCII, NULL, 0, NULL, HFILL }
5157 { &hf_dvbci_cis_tpll_v1_info_additional,
5158 { "Additional info", "dvb-ci.cis.tpll_v1_info.additional",
5159 FT_STRING, STR_ASCII, NULL, 0, NULL, HFILL }
5161 { &hf_dvbci_cis_tpll_v1_end,
5162 { "End of chain", "dvb-ci.cis.tpll_v1_end",
5163 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5165 { &hf_dvbci_cis_tpcc_rfsz,
5166 { "Size of reserved area", "dvb-ci.cis.tpcc_rfsz",
5167 FT_UINT8, BASE_HEX, NULL, 0xC0, NULL, HFILL }
5169 { &hf_dvbci_cis_tpcc_rmsz,
5170 { "Size of TPCC_RMSK field - 1", "dvb-ci.cis.tpcc_rmsz",
5171 FT_UINT8, BASE_HEX, NULL, 0x3C, NULL, HFILL }
5173 { &hf_dvbci_cis_tpcc_rasz,
5174 { "Size of TPCC_RADR - 1", "dvb-ci.cis.tpcc_rasz",
5175 FT_UINT8, BASE_HEX, NULL, 0x03, NULL, HFILL }
5177 { &hf_dvbci_cis_tpcc_last,
5178 { "Index of the last cftable entry", "dvb-ci.cis.tpcc_last",
5179 FT_UINT8, BASE_HEX, NULL, 0x3F, NULL, HFILL }
5181 { &hf_dvbci_cis_tpcc_radr,
5182 { "COR base address", "dvb-ci.cis.tpcc_radr",
5183 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
5185 { &hf_dvbci_cis_tpcc_rmsk,
5186 { "Configuration register presence mask", "dvb-ci.cis.tpcc_rmsk",
5187 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5189 { &hf_dvbci_cis_st_code,
5190 { "Subtuple tag", "dvb-ci.cis.st_code",
5191 FT_UINT8, BASE_HEX, VALS(dvbci_cis_subtpl_code), 0, NULL, HFILL }
5193 { &hf_dvbci_cis_st_len,
5194 { "Subtuple length", "dvb-ci.cis.st_len",
5195 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5197 { &hf_dvbci_cis_stci_ifn_size,
5198 { "Size of interface ID number - 1", "dvb-ci.cis.stci_ifn_size",
5199 FT_UINT8, BASE_HEX, NULL, 0xC0, NULL, HFILL }
5201 { &hf_dvbci_cis_stci_ifn,
5202 { "Interface ID number", "dvb-ci.cis.stci_ifn",
5203 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
5205 { &hf_dvbci_cis_stci_str,
5206 { "Interface description strings", "dvb-ci.cis.stci_str",
5207 FT_STRING, STR_ASCII, NULL, 0, NULL, HFILL }
5209 { &hf_dvbci_cis_tpce_indx_intface,
5210 { "Intface", "dvb-ci.cis.tpce_indx.intface",
5211 FT_UINT8, BASE_HEX, NULL, 0x80, NULL, HFILL }
5213 { &hf_dvbci_cis_tpce_indx_default,
5214 { "Default", "dvb-ci.cis.tpce_indx.default",
5215 FT_UINT8, BASE_HEX, NULL, 0x40, NULL, HFILL }
5217 { &hf_dvbci_cis_tpce_indx_cnf_entry,
5218 { "Configuration entry number", "dvb-ci.cis.tpce_indx.cnf_entry",
5219 FT_UINT8, BASE_HEX, NULL, 0x3F, NULL, HFILL }
5221 { &hf_dvbci_cis_tpce_if_type,
5222 { "Interface type", "dvb-ci.cis.tpce_if.type", FT_UINT8, BASE_HEX,
5223 VALS(dvbci_cis_tpce_if_type), 0x0F, NULL, HFILL }
5225 { &hf_dvbci_cis_tpce_fs_mem_space,
5226 { "Mem space", "dvb-ci.cis.tpce_fs.mem_space",
5227 FT_UINT8, BASE_HEX, NULL, 0x60, NULL, HFILL }
5229 { &hf_dvbci_cis_tpce_fs_irq,
5230 { "IRQ", "dvb-ci.cis.tpce_fs.irq",
5231 FT_UINT8, BASE_HEX, NULL, 0x10, NULL, HFILL }
5233 { &hf_dvbci_cis_tpce_fs_io,
5234 { "IO Space", "dvb-ci.cis.tpce_fs.io",
5235 FT_UINT8, BASE_HEX, NULL, 0x08, NULL, HFILL }
5237 { &hf_dvbci_cis_tplmid_manf,
5238 { "PC Card manufacturer code", "dvb-ci.cis.tplmid_manf",
5239 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5241 { &hf_dvbci_cis_tplmid_card,
5242 { "Manufacturer info", "dvb-ci.cis.tplmid_card",
5243 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5245 { &hf_dvbci_buf_size,
5246 { "Buffer Size", "dvb-ci.buf_size",
5247 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5250 { "Transport Connection ID", "dvb-ci.tcid",
5251 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5254 { "More/Last indicator", "dvb-ci.more_last",
5255 FT_UINT8, BASE_HEX, VALS(dvbci_ml), 0, NULL, HFILL }
5257 /* on the link layer, tpdus are reassembled */
5258 { &hf_dvbci_l_frags,
5259 { "Tpdu fragments", "dvb-ci.tpdu_fragments",
5260 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL }
5263 { "Tpdu fragment", "dvb-ci.tpdu_fragment",
5264 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
5266 { &hf_dvbci_l_frag_overlap,
5267 { "Tpdu fragment overlap", "dvb-ci.tpdu_fragment.overlap",
5268 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
5270 { &hf_dvbci_l_frag_overlap_conflicts,
5271 { "Tpdu fragment overlapping with conflicting data",
5272 "dvb-ci.tpdu_fragment.overlap.conflicts",
5273 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
5275 { &hf_dvbci_l_frag_multiple_tails,
5276 { "Tpdu has multiple tail fragments",
5277 "dvb-ci.tpdu_fragment.multiple_tails",
5278 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
5280 { &hf_dvbci_l_frag_too_long_frag,
5281 { "Tpdu fragment too long", "dvb-ci.tpdu_fragment.too_long_fragment",
5282 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
5284 { &hf_dvbci_l_frag_err,
5285 { "Tpdu defragmentation error", "dvb-ci.tpdu_fragment.error",
5286 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
5288 { &hf_dvbci_l_frag_cnt,
5289 { "Tpdu fragment count", "dvb-ci.tpdu_fragment.count",
5290 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
5292 { &hf_dvbci_l_reass_in,
5293 { "Tpdu reassembled in", "dvb-ci.tpdu_reassembled.in",
5294 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
5296 { &hf_dvbci_l_reass_len,
5297 { "Reassembled tpdu length", "dvb-ci.tpdu_reassembled.length",
5298 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
5300 { &hf_dvbci_c_tpdu_tag,
5301 { "Command TPDU Tag", "dvb-ci.c_tpdu_tag",
5302 FT_UINT8, BASE_HEX, VALS(dvbci_c_tpdu), 0, NULL, HFILL }
5304 { &hf_dvbci_r_tpdu_tag,
5305 { "Response TPDU Tag", "dvb-ci.r_tpdu_tag",
5306 FT_UINT8, BASE_HEX, VALS(dvbci_r_tpdu), 0, NULL, HFILL }
5309 { "Transport Connection ID", "dvb-ci.t_c_id",
5310 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5312 { &hf_dvbci_sb_value,
5313 { "SB Value", "dvb-ci.sb_value", FT_UINT8, BASE_HEX,
5314 VALS(dvbci_sb_value), 0, NULL, HFILL } },
5316 /* on the transport layer, spdus are reassembled */
5317 { &hf_dvbci_t_frags,
5318 { "Spdu fragments", "dvb-ci.spdu_fragments",
5319 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL }
5322 { "Spdu fragment", "dvb-ci.spdu_fragment",
5323 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
5325 { &hf_dvbci_t_frag_overlap,
5326 { "Spdu fragment overlap", "dvb-ci.spdu_fragment.overlap",
5327 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
5329 { &hf_dvbci_t_frag_overlap_conflicts,
5330 { "Spdu fragment overlapping with conflicting data",
5331 "dvb-ci.tpdu_fragment.overlap.conflicts",
5332 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
5334 { &hf_dvbci_t_frag_multiple_tails,
5335 { "Spdu has multiple tail fragments",
5336 "dvb-ci.spdu_fragment.multiple_tails",
5337 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
5339 { &hf_dvbci_t_frag_too_long_frag,
5340 { "Spdu fragment too long", "dvb-ci.spdu_fragment.too_long_fragment",
5341 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }
5343 { &hf_dvbci_t_frag_err,
5344 { "Spdu defragmentation error", "dvb-ci.spdu_fragment.error",
5345 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
5347 { &hf_dvbci_t_frag_cnt,
5348 { "Spdu fragment count", "dvb-ci.spdu_fragment.count",
5349 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
5351 { &hf_dvbci_t_reass_in,
5352 { "Spdu reassembled in", "dvb-ci.spdu_reassembled.in",
5353 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }
5355 { &hf_dvbci_t_reass_len,
5356 { "Reassembled spdu length", "dvb-ci.spdu_reassembled.length",
5357 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }
5359 { &hf_dvbci_spdu_tag,
5360 { "SPDU Tag", "dvb-ci.spdu_tag",
5361 FT_UINT8, BASE_HEX, VALS(dvbci_spdu_tag), 0, NULL, HFILL }
5363 { &hf_dvbci_sess_status,
5364 { "Session Status", "dvb-ci.session_status",
5365 FT_UINT8, BASE_HEX, VALS(dvbci_sess_status), 0, NULL, HFILL }
5367 { &hf_dvbci_sess_nb,
5368 { "Session Number", "dvb-ci.session_nb",
5369 FT_UINT16, BASE_DEC, NULL , 0, NULL, HFILL }
5371 { &hf_dvbci_close_sess_status,
5372 { "Session Status", "dvb-ci.close_session_status",
5373 FT_UINT8, BASE_HEX, VALS(dvbci_close_sess_status), 0, NULL, HFILL }
5375 { &hf_dvbci_res_id_type,
5376 { "Resource ID Type", "dvb-ci.res.id_type",
5377 FT_UINT32, BASE_HEX, NULL, RES_ID_TYPE_MASK, NULL, HFILL }
5379 { &hf_dvbci_res_class,
5380 { "Resource Class", "dvb-ci.res.class",
5381 FT_UINT32, BASE_HEX, VALS(dvbci_res_class), RES_CLASS_MASK, NULL, HFILL }
5383 { &hf_dvbci_res_type,
5384 { "Resource Type", "dvb-ci.res.type",
5385 FT_UINT32, BASE_HEX, NULL, RES_TYPE_MASK, NULL, HFILL }
5387 { &hf_dvbci_res_ver,
5388 { "Resource Version", "dvb-ci.res.version",
5389 FT_UINT32, BASE_HEX, NULL, RES_VER_MASK, NULL, HFILL }
5391 { &hf_dvbci_apdu_tag,
5392 { "APDU Tag", "dvb-ci.apdu_tag",
5393 FT_UINT24, BASE_HEX, VALS(dvbci_apdu_tag), 0, NULL, HFILL }
5395 { &hf_dvbci_app_type,
5396 { "Application type", "dvb-ci.ap.type",
5397 FT_UINT8, BASE_HEX, VALS(dvbci_app_type), 0, NULL, HFILL }
5399 { &hf_dvbci_app_manf,
5400 { "Application manufacturer", "dvb-ci.ap.manufacturer",
5401 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5403 { &hf_dvbci_manf_code,
5404 { "Manufacturer code", "dvb-ci.ap.manufacturer_code",
5405 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5407 { &hf_dvbci_menu_str_len,
5408 { "Menu string length", "dvb-ci.ap.menu_string_length",
5409 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5411 { &hf_dvbci_ap_char_tbl,
5412 { "Character table", "dvb-ci.ap.menu_char_tbl",
5413 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL}
5415 { &hf_dvbci_menu_str,
5416 { "Menu string", "dvb-ci.ap.menu_string",
5417 FT_STRING, STR_UNICODE, NULL, 0, NULL, HFILL }
5419 { &hf_dvbci_data_rate,
5420 { "Transport stream data rate supported by the host",
5421 "dvb-ci.ap.data_rate",
5422 FT_UINT8, BASE_HEX, VALS(dvbci_data_rate), 0, NULL, HFILL }
5424 { &hf_dvbci_ca_sys_id,
5425 { "CA system ID", "dvb-ci.ca.ca_system_id",
5426 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5428 { &hf_dvbci_ca_pmt_list_mgmt,
5429 { "CA PMT list management", "dvb-ci.ca.ca_pmt_list_management",
5430 FT_UINT8, BASE_HEX, VALS(dvbci_ca_pmt_list_mgmt), 0, NULL,
5433 { &hf_dvbci_prog_num,
5434 { "Program number", "dvb-ci.ca.program_number",
5435 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5437 { &hf_dvbci_prog_info_len,
5438 { "Program info length", "dvb-ci.ca.program_info_length",
5439 FT_UINT16, BASE_HEX, NULL, 0x0FFF, NULL, HFILL }
5441 { &hf_dvbci_stream_type,
5442 { "Stream type", "dvb-ci.ca.stream_type", FT_UINT8,
5443 BASE_HEX|BASE_EXT_STRING, &mpeg_pmt_stream_type_vals_ext,
5447 { "Elementary stream PID", "dvb-ci.ca.elementary_pid",
5448 FT_UINT16, BASE_HEX, NULL, 0x1FFF, NULL, HFILL }
5450 { &hf_dvbci_es_info_len,
5451 { "Elementary stream info length", "dvb-ci.ca.es_info_length",
5452 FT_UINT16, BASE_HEX, NULL, 0x0FFF, NULL, HFILL }
5454 { &hf_dvbci_ca_pmt_cmd_id,
5455 { "CA PMT command ID", "dvb-ci.ca.ca_pmt_cmd_id",
5456 FT_UINT8, BASE_HEX, VALS(dvbci_ca_pmt_cmd_id), 0, NULL, HFILL }
5458 { &hf_dvbci_descr_len,
5459 { "CA descriptor length", "dvb-ci.ca.ca_desc_len",
5460 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5463 { "CA PID", "dvb-ci.ca.ca_pid",
5464 FT_UINT16, BASE_HEX, NULL, 0x1FFF, NULL, HFILL }
5466 { &hf_dvbci_ca_enable_flag,
5467 { "CA enable flag", "dvb-ci.ca.ca_enable_flag",
5468 FT_UINT8, BASE_HEX, NULL, 0x80, NULL, HFILL }
5470 { &hf_dvbci_ca_enable,
5471 { "CA enable", "dvb-ci.ca.ca_enable",
5472 FT_UINT8, BASE_HEX, VALS(dvbci_ca_enable), 0x7F, NULL, HFILL }
5474 { &hf_dvbci_auth_proto_id,
5475 { "Authentication protocol ID", "dvb-ci.aut.proto_id",
5476 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5478 { &hf_dvbci_auth_req_bytes,
5479 { "Authentication request data", "dvb-ci.aut.req",
5480 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5482 { &hf_dvbci_auth_resp_bytes,
5483 { "Authentication response data", "dvb-ci.aut.resp",
5484 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5486 { &hf_dvbci_network_id,
5487 { "Network ID", "dvb-ci.hc.nid",
5488 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5490 { &hf_dvbci_original_network_id,
5491 { "Original network ID", "dvb-ci.hc.onid",
5492 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5494 { &hf_dvbci_transport_stream_id,
5495 { "Transport stream ID", "dvb-ci.hc.tsid",
5496 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5498 { &hf_dvbci_service_id,
5499 { "Service ID", "dvb-ci.hc.svcid",
5500 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5502 { &hf_dvbci_replacement_ref,
5503 { "Replacement reference", "dvb-ci.hc.replacement_ref",
5504 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5506 { &hf_dvbci_replaced_pid,
5507 { "Replaced PID", "dvb-ci.hc.replaced_pid",
5508 FT_UINT16, BASE_HEX, NULL, 0x1FFF, NULL, HFILL }
5510 { &hf_dvbci_replacement_pid,
5511 { "Replacement PID", "dvb-ci.hc.replacement_pid",
5512 FT_UINT16, BASE_HEX, NULL, 0x1FFF, NULL, HFILL }
5514 { &hf_dvbci_pmt_flag,
5515 { "PMT flag", "dvb-ci.hc.pmt_flag",
5516 FT_UINT8, BASE_HEX, NULL, 0x01, NULL, HFILL }
5518 { &hf_dvbci_hc_desc_loop_len,
5519 { "Descriptor loop length", "dvb-ci.hc.desc_loop_len",
5520 FT_UINT16, BASE_DEC, NULL, 0x0FFF, NULL, HFILL }
5522 { &hf_dvbci_hc_status,
5523 { "Status field", "dvb-ci.hc.status_field",
5524 FT_UINT8, BASE_HEX, VALS(dvbci_hc_status), 0, NULL, HFILL }
5526 { &hf_dvbci_hc_release_reply,
5527 { "Release reply", "dvb-ci.hc.release_reply",
5528 FT_UINT8, BASE_HEX, VALS(dvbci_hc_release_reply), 0, NULL, HFILL }
5530 { &hf_dvbci_resp_intv,
5531 { "Response interval", "dvb-ci.dt.resp_interval",
5532 FT_RELATIVE_TIME, BASE_NONE, NULL, 0, NULL, HFILL }
5534 { &hf_dvbci_utc_time,
5535 { "UTC time", "dvb-ci.dt.utc_time",
5536 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0, NULL, HFILL }
5539 /* we have to use FT_INT16 instead of FT_RELATIVE_TIME,
5540 local offset can be negative */
5541 { &hf_dvbci_local_offset,
5542 { "Local time offset", "dvb-ci.dt.local_offset",
5543 FT_INT16, BASE_DEC, NULL, 0, NULL, HFILL }
5545 { &hf_dvbci_close_mmi_cmd_id,
5546 { "Command ID", "dvb-ci.mmi.close_mmi_cmd_id",
5547 FT_UINT8, BASE_HEX, VALS(dvbci_close_mmi_cmd_id), 0, NULL, HFILL }
5549 { &hf_dvbci_close_mmi_delay,
5550 { "Delay (in sec)", "dvb-ci.mmi.delay",
5551 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5553 { &hf_dvbci_disp_ctl_cmd,
5554 { "Command", "dvb-ci.mmi.disp_ctl_cmd",
5555 FT_UINT8, BASE_HEX, VALS(dvbci_disp_ctl_cmd), 0, NULL, HFILL }
5557 { &hf_dvbci_mmi_mode,
5558 { "MMI mode", "dvb-ci.mmi.mode",
5559 FT_UINT8, BASE_HEX, VALS(dvbci_mmi_mode), 0, NULL, HFILL }
5561 { &hf_dvbci_disp_rep_id,
5562 { "Reply ID", "dvb-ci.mmi.disp_rep_id",
5563 FT_UINT8, BASE_HEX, VALS(dvbci_disp_rep_id), 0, NULL, HFILL }
5565 { &hf_dvbci_mmi_char_tbl,
5566 { "Character table", "dvb-ci.mmi.char_tbl",
5567 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL}
5569 { &hf_dvbci_blind_ans,
5570 { "Blind answer flag", "dvb-ci.mmi.blind_ans",
5571 FT_UINT8, BASE_HEX, VALS(dvbci_blind_ans), 0x01, NULL, HFILL }
5573 { &hf_dvbci_ans_txt_len,
5574 { "Answer text length", "dvb-ci.mmi.ans_txt_len",
5575 FT_UINT8, BASE_DEC, NULL , 0, NULL, HFILL }
5578 { "Enquiry string", "dvb-ci.mmi.enq",
5579 FT_STRING, STR_UNICODE, NULL, 0, NULL, HFILL }
5582 { "Answer ID", "dvb-ci.mmi.ans_id",
5583 FT_UINT8, BASE_HEX, VALS(dvbci_ans_id) , 0, NULL, HFILL }
5586 { "Answer", "dvb-ci.mmi.ans",
5587 FT_STRING, STR_UNICODE, NULL, 0, NULL, HFILL }
5589 { &hf_dvbci_choice_nb,
5590 { "Number of menu items", "dvb-ci.mmi.choice_nb",
5591 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5593 { &hf_dvbci_choice_ref,
5594 { "Selected item", "dvb-ci.mmi.choice_ref",
5595 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5597 { &hf_dvbci_item_nb,
5598 { "Number of list items", "dvb-ci.mmi.item_nb",
5599 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5602 { "Title", "dvb-ci.mmi.title",
5603 FT_STRING, STR_UNICODE, NULL, 0, NULL, HFILL }
5605 { &hf_dvbci_subtitle,
5606 { "Sub-title", "dvb-ci.mmi.subtitle",
5607 FT_STRING, STR_UNICODE, NULL, 0, NULL, HFILL }
5610 { "Bottom line", "dvb-ci.mmi.bottom",
5611 FT_STRING, STR_UNICODE, NULL, 0, NULL, HFILL }
5614 { "Item", "dvb-ci.mmi.item",
5615 FT_STRING, STR_UNICODE, NULL, 0, NULL, HFILL }
5617 { &hf_dvbci_host_country,
5618 { "Host country", "dvb-ci.hlc.country",
5619 FT_STRING, STR_UNICODE, NULL, 0, NULL, HFILL }
5621 { &hf_dvbci_host_language,
5622 { "Host language", "dvb-ci.hlc.language",
5623 FT_STRING, STR_UNICODE, NULL, 0, NULL, HFILL }
5625 { &hf_dvbci_cup_type,
5626 { "CAM upgrade type", "dvb-ci.cup.type",
5627 FT_UINT8, BASE_HEX, VALS(dvbci_cup_type), 0, NULL, HFILL }
5629 { &hf_dvbci_cup_download_time,
5630 { "Download time", "dvb-ci.cup.download_time",
5631 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5633 { &hf_dvbci_cup_answer,
5634 { "CAM upgrade answer", "dvb-ci.cup.answer",
5635 FT_UINT8, BASE_HEX, VALS(dvbci_cup_answer), 0, NULL, HFILL }
5637 { &hf_dvbci_cup_progress,
5638 { "CAM upgrade progress", "dvb-ci.cup.progress",
5639 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5641 { &hf_dvbci_cup_reset,
5642 { "requested CAM reset", "dvb-ci.cup.reset",
5643 FT_UINT8, BASE_HEX, VALS(dvbci_cup_reset), 0, NULL, HFILL }
5645 { &hf_dvbci_cc_sys_id_bitmask,
5646 { "CC system id bitmask", "dvb-ci.cc.sys_id_bitmask",
5647 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5649 { &hf_dvbci_cc_dat_id,
5650 { "CC datatype id", "dvb-ci.cc.datatype_id",
5651 FT_UINT8, BASE_HEX, VALS(dvbci_cc_dat_id), 0, NULL, HFILL }
5653 { &hf_dvbci_brand_cert,
5654 { "Brand certificate", "dvb-ci.cc.brand_cert",
5655 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
5657 { &hf_dvbci_dev_cert,
5658 { "Device certificate", "dvb-ci.cc.dev_cert",
5659 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }
5661 { &hf_dvbci_uri_ver,
5662 { "URI version", "dvb-ci.cc.uri.version",
5663 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5665 { &hf_dvbci_uri_aps,
5666 { "APS", "dvb-ci.cc.uri.aps",
5667 FT_UINT8, BASE_HEX, NULL, 0xC0, NULL, HFILL }
5669 { &hf_dvbci_uri_emi,
5670 { "EMI", "dvb-ci.cc.uri.emi",
5671 FT_UINT8, BASE_HEX, VALS(dvbci_cc_uri_emi), 0x30, NULL, HFILL }
5673 { &hf_dvbci_uri_ict,
5674 { "Image constraint token", "dvb-ci.cc.uri.ict",
5675 FT_UINT8, BASE_HEX, NULL, 0x08, NULL, HFILL }
5677 { &hf_dvbci_uri_rct,
5678 { "Redistribution control trigger (RCT)", "dvb-ci.cc.uri.rct",
5679 FT_UINT8, BASE_HEX, NULL, 0x04, NULL, HFILL }
5681 { &hf_dvbci_uri_dot,
5682 { "Digital only token (DOT)", "dvb-ci.cc.uri.dot",
5683 FT_UINT8, BASE_HEX, NULL, 0x01, NULL, HFILL }
5685 /* retention limit is 6bit in URIv1 and 8bit in URIv2 and later
5686 the position depends on the version, we can't define a mask here */
5688 { "Retention limit", "dvb-ci.cc.uri.rl",
5689 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5691 { &hf_dvbci_cc_key_register,
5692 { "Key register", "dvb-ci.cc.key_register",
5693 FT_UINT8, BASE_HEX, VALS(dvbci_cc_key_register), 0, NULL, HFILL }
5695 { &hf_dvbci_cc_status_field,
5696 { "Status field", "dvb-ci.cc.status_field",
5697 FT_UINT8, BASE_HEX, VALS(dvbci_cc_status), 0, NULL, HFILL }
5699 { &hf_dvbci_cc_op_mode,
5700 { "Operating mode", "dvb-ci.cc.op_mode",
5701 FT_UINT8, BASE_HEX, VALS(dvbci_cc_op_mode), 0, NULL, HFILL }
5703 { &hf_dvbci_cc_data,
5704 { "Data", "dvb-ci.cc.data",
5705 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5707 { &hf_dvbci_sac_msg_ctr,
5708 { "Message counter", "dvb-ci.cc.sac.msg_ctr",
5709 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
5711 { &hf_dvbci_sac_proto_ver,
5712 { "Protocol version", "dvb-ci.cc.sac.proto_ver",
5713 FT_UINT8, BASE_HEX, NULL, 0xF0, NULL, HFILL }
5715 { &hf_dvbci_sac_auth_cip,
5716 { "Authentication cipher", "dvb-ci.cc.sac.auth_cip",
5717 FT_UINT8, BASE_HEX, VALS(dvbci_cc_sac_auth), 0x0E, NULL, HFILL }
5719 { &hf_dvbci_sac_payload_enc,
5720 { "Payload encryption flag", "dvb-ci.cc.sac.payload_enc",
5721 FT_UINT8, BASE_HEX, NULL, 0x01, NULL, HFILL }
5723 { &hf_dvbci_sac_enc_cip,
5724 { "Encryption cipher", "dvb-ci.cc.sac.enc_cip",
5725 FT_UINT8, BASE_HEX, VALS(dvbci_cc_sac_enc), 0xE0, NULL, HFILL }
5727 { &hf_dvbci_sac_payload_len,
5728 { "Payload length", "dvb-ci.cc.sac.payload_len",
5729 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
5731 { &hf_dvbci_sac_enc_body,
5732 { "Encrypted SAC body", "dvb-ci.cc.sac.enc_body",
5733 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5735 { &hf_dvbci_sac_padding,
5736 { "Padding", "dvb-ci.cc.sac.padding",
5737 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5739 { &hf_dvbci_sac_signature,
5740 { "Signature", "dvb-ci.cc.sac.signature",
5741 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5744 { "Rating", "dvb-ci.cc.rating",
5745 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5747 { &hf_dvbci_capability_field,
5748 { "Capability field", "dvb-ci.cc.capability_field",
5749 FT_UINT8, BASE_HEX, VALS(dvbci_cc_cap), 0, NULL, HFILL }
5751 { &hf_dvbci_pin_chg_time,
5752 { "PIN change time (UTC)", "dvb-ci.cc.pin_change_time",
5753 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0, NULL, HFILL }
5755 { &hf_dvbci_pincode_status,
5756 { "Pincode status field", "dvb-ci.cc.pincode_status_field",
5757 FT_UINT8, BASE_HEX, VALS(dvbci_pincode_status), 0, NULL, HFILL }
5759 { &hf_dvbci_cc_prog_num,
5760 { "Program number", "dvb-ci.cc.program_number",
5761 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5763 { &hf_dvbci_pin_evt_time,
5764 { "PIN event time (UTC)", "dvb-ci.cc.pin_event_time",
5765 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0, NULL, HFILL }
5767 { &hf_dvbci_pin_evt_cent,
5768 { "PIN event time centiseconds", "dvb-ci.cc.pin_event_time_centi",
5769 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5771 { &hf_dvbci_cc_priv_data,
5772 { "Private data", "dvb-ci.cc.private_data",
5773 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5775 { &hf_dvbci_pincode,
5776 { "PIN code", "dvb-ci.cc.pincode",
5777 FT_STRING, STR_ASCII, NULL, 0, NULL, HFILL }
5779 { &hf_dvbci_app_dom_id,
5780 { "Application Domain Identifier", "dvb-ci.ami.app_dom_id",
5781 FT_STRING, STR_ASCII, NULL, 0, NULL, HFILL }
5783 { &hf_dvbci_init_obj,
5784 { "Initial Object", "dvb-ci.ami.init_obj",
5785 FT_STRING, STR_ASCII, NULL, 0, NULL, HFILL }
5787 { &hf_dvbci_ack_code,
5788 { "Acknowledgement", "dvb-ci.ami.ack_code",
5789 FT_UINT8, BASE_HEX, VALS(dvbci_ack_code), 0, NULL, HFILL }
5791 { &hf_dvbci_req_type,
5792 { "Request type", "dvb-ci.ami.req_type",
5793 FT_UINT8, BASE_HEX, VALS(dvbci_req_type), 0, NULL, HFILL }
5795 { &hf_dvbci_file_hash,
5796 { "File hash", "dvb-ci.ami.file_hash",
5797 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5799 { &hf_dvbci_file_name,
5800 { "File name", "dvb-ci.ami.file_name",
5801 FT_STRING, STR_ASCII, NULL, 0, NULL, HFILL }
5803 { &hf_dvbci_ami_priv_data,
5804 { "Private data", "dvb-ci.ami.private_data",
5805 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5808 { "RequestOK", "dvb-ci.ami.request_ok",
5809 FT_UINT8, BASE_HEX, NULL, 0x02, NULL, HFILL }
5811 { &hf_dvbci_file_ok,
5812 { "FileOK", "dvb-ci.ami.file_ok",
5813 FT_UINT8, BASE_HEX, NULL, 0x01, NULL, HFILL }
5815 { &hf_dvbci_file_data,
5816 { "File data", "dvb-ci.ami.file_data",
5817 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5819 { &hf_dvbci_abort_req_code,
5820 { "Abort request code", "dvb-ci.ami.abort_req_code",
5821 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5823 { &hf_dvbci_abort_ack_code,
5824 { "Abort acknowledgement code", "dvb-ci.ami.abort_ack_code",
5825 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
5827 { &hf_dvbci_phase_id,
5828 { "Phase ID", "dvb-ci.lsc.comms_phase_id",
5829 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5831 { &hf_dvbci_comms_rep_id,
5832 { "Comms reply ID", "dvb-ci.lsc.comms_reply_id",
5833 FT_UINT8, BASE_HEX, VALS(dvbci_comms_rep_id), 0, NULL, HFILL }
5835 { &hf_dvbci_lsc_buf_size,
5836 { "Buffer size", "dvb-ci.lsc.buf_size",
5837 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
5839 { &hf_dvbci_lsc_ret_val,
5840 { "Return value", "dvb-ci.lsc.return_value",
5841 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5843 { &hf_dvbci_comms_cmd_id,
5844 { "Comms command ID", "dvb-ci.lsc.comms_cmd_id",
5845 FT_UINT8, BASE_HEX, VALS(dvbci_comms_cmd_id), 0, NULL, HFILL }
5847 { &hf_dvbci_conn_desc_type,
5848 { "Type", "dvb-ci.lsc.conn_desc_type",
5849 FT_UINT8, BASE_HEX, VALS(dvbci_conn_desc_type), 0, NULL, HFILL }
5851 { &hf_dvbci_lsc_media_tag,
5852 { "Tag", "dvb-ci.lsc.media_tag",
5853 FT_UINT8, BASE_HEX, VALS(dvbci_lsc_desc_tag), 0, NULL, HFILL }
5855 { &hf_dvbci_lsc_media_len,
5856 { "Length", "dvb-ci.lsc.media_len",
5857 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5859 { &hf_dvbci_lsc_ip_ver,
5860 { "IP version", "dvb-ci.lsc.ip_version",
5861 FT_UINT8, BASE_DEC, VALS(dvbci_lsc_ip_ver), 0, NULL, HFILL }
5863 { &hf_dvbci_lsc_ipv4_addr,
5864 { "IP address", "dvb-ci.lsc.ipv4_addr",
5865 FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL }
5867 { &hf_dvbci_lsc_ipv6_addr,
5868 { "IPv6 address", "dvb-ci.lsc.ipv6_addr",
5869 FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL }
5871 { &hf_dvbci_lsc_dst_port,
5872 { "Destination port", "dvb-ci.lsc.dst_port",
5873 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5875 { &hf_dvbci_lsc_proto,
5876 { "Protocol", "dvb-ci.lsc.protocol",
5877 FT_UINT8, BASE_HEX, VALS(dvbci_lsc_proto), 0, NULL, HFILL }
5879 { &hf_dvbci_lsc_hostname,
5880 { "Hostname", "dvb-ci.lsc.hostname",
5881 FT_STRING, STR_ASCII, NULL, 0, NULL, HFILL }
5883 { &hf_dvbci_lsc_retry_count,
5884 { "Retry count", "dvb-ci.lsc.retry_count",
5885 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5887 { &hf_dvbci_lsc_timeout,
5888 { "Timeout", "dvb-ci.lsc.timeout",
5889 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
5892 /* filter string for hf_dvbci_info_ver_op_status and
5893 * hf_dvbci_info_ver_op_info below is the same, it seems this is ok */
5894 { &hf_dvbci_info_ver_op_status,
5895 { "Info version", "dvb-ci.opp.info_ver",
5896 FT_UINT8, BASE_HEX, NULL, 0xE0, NULL, HFILL }
5898 { &hf_dvbci_nit_ver,
5899 { "NIT version", "dvb-ci.opp.nit_ver",
5900 FT_UINT8, BASE_HEX, NULL, 0x1F, NULL, HFILL }
5902 { &hf_dvbci_pro_typ,
5903 { "Profile type", "dvb-ci.opp.profile_type",
5904 FT_UINT8, BASE_HEX, NULL, 0xC0, NULL, HFILL }
5906 { &hf_dvbci_init_flag,
5907 { "Initialized flag", "dvb-ci.opp.init_flag",
5908 FT_UINT8, BASE_HEX, NULL, 0x20, NULL, HFILL }
5910 { &hf_dvbci_ent_chg_flag,
5911 { "Entitlement change flag", "dvb-ci.opp.ent_chg_flag",
5912 FT_UINT8, BASE_HEX, NULL, 0x10, NULL, HFILL }
5914 { &hf_dvbci_ent_val_flag,
5915 { "Entitlement valid flag", "dvb-ci.opp.ent_val_flag",
5916 FT_UINT8, BASE_HEX, NULL, 0x08, NULL, HFILL }
5918 { &hf_dvbci_ref_req_flag,
5919 { "Refresh request flag", "dvb-ci.opp.refresh_req_flag",
5920 FT_UINT8, BASE_HEX, VALS(dvbci_opp_ref_req_flag), 0x03, NULL, HFILL }
5922 { &hf_dvbci_err_flag,
5923 { "Error flag", "dvb-ci.opp.err_flag",
5924 FT_UINT8, BASE_HEX, VALS(dvbci_opp_err_flag), 0xF0, NULL, HFILL }
5926 { &hf_dvbci_dlv_sys_hint,
5927 { "Delivery system hint", "dvb-ci.opp.dlv_sys_hint",
5928 FT_UINT8, BASE_HEX, NULL, 0x0F, NULL, HFILL }
5930 { &hf_dvbci_dlv_sys_hint_t,
5931 { "terrestrial network (DVB-T/T2)", "dvb-ci.opp.dlv_sys_hint.t",
5932 FT_BOOLEAN, 4, TFS(&tfs_set_notset), 0x04, NULL, HFILL }
5934 { &hf_dvbci_dlv_sys_hint_s,
5935 { "satellite network (DVB-S/S2)", "dvb-ci.opp.dlv_sys_hint.s",
5936 FT_BOOLEAN, 4, TFS(&tfs_set_notset), 0x02, NULL, HFILL }
5938 { &hf_dvbci_dlv_sys_hint_c,
5939 { "cable network (DVB-C/C2)", "dvb-ci.opp.dlv_sys_hint.c",
5940 FT_BOOLEAN, 4, TFS(&tfs_set_notset), 0x01, NULL, HFILL }
5942 { &hf_dvbci_refr_req_date,
5943 { "Refresh request date", "dvb-ci.opp.refresh_req_date",
5944 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5946 { &hf_dvbci_refr_req_time,
5947 { "Refresh request time", "dvb-ci.opp.refresh_req_time",
5948 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
5950 { &hf_dvbci_nit_loop_len,
5951 { "NIT loop length", "dvb-ci.opp.nit_loop_len",
5952 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
5954 { &hf_dvbci_info_valid,
5955 { "Info valid", "dvb-ci.opp.info_valid",
5956 FT_UINT8, BASE_HEX, NULL, 0x08, NULL, HFILL }
5958 { &hf_dvbci_info_ver_op_info,
5959 { "Info version", "dvb-ci.opp.info_ver",
5960 FT_UINT8, BASE_HEX, NULL, 0x07, NULL, HFILL }
5962 { &hf_dvbci_cicam_onid,
5963 { "CICAM original network id", "dvb-ci.opp.cicam_onid",
5964 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
5966 { &hf_dvbci_cicam_id,
5967 { "CICAM ID", "dvb-ci.opp.cicam_id",
5968 FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
5970 { &hf_dvbci_opp_char_tbl,
5971 { "Character table", "dvb-ci.opp.char_tbl",
5972 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL}
5974 { &hf_dvbci_sdt_rst_trusted,
5975 { "SDT running status trusted", "dvb-ci.opp.sdt_rst_trusted",
5976 FT_UINT8, BASE_HEX, NULL, 0x80, NULL, HFILL }
5978 { &hf_dvbci_eit_rst_trusted,
5979 { "EIT running status trusted", "dvb-ci.opp.eit_rst_trusted",
5980 FT_UINT8, BASE_HEX, NULL, 0x40, NULL, HFILL }
5982 { &hf_dvbci_eit_pf_usage,
5983 { "EIT present/following usage", "dvb-ci.opp.eit_pf_usage",
5984 FT_UINT8, BASE_HEX, VALS(dvbci_opp_eit_pf_usage), 0x30, NULL, HFILL }
5986 { &hf_dvbci_eit_sch_usage,
5987 { "EIT schedule usage", "dvb-ci.opp.eit_sch_usage",
5988 FT_UINT8, BASE_HEX, VALS(dvbci_opp_eit_sch_usage), 0x0E, NULL, HFILL }
5990 { &hf_dvbci_ext_evt_usage,
5991 { "Extended event usage", "dvb-ci.opp.ext_evt_usage",
5992 FT_UINT8, BASE_HEX, VALS(dvbci_opp_ext_evt), 0x01, NULL, HFILL }
5994 { &hf_dvbci_sdt_oth_trusted,
5995 { "SDT_other trusted", "dvb-ci.opp.sdt_oth_trusted",
5996 FT_UINT8, BASE_HEX, NULL, 0x80, NULL, HFILL }
5998 { &hf_dvbci_eit_evt_trigger,
5999 { "EIT event trigger", "dvb-ci.opp.eit_evt_trigger",
6000 FT_UINT8, BASE_HEX, NULL, 0x40, NULL, HFILL }
6002 { &hf_dvbci_opp_lang_code,
6003 { "Language code", "dvb-ci.opp.lang_code",
6004 FT_STRING, STR_ASCII, NULL, 0, NULL, HFILL }
6006 { &hf_dvbci_prof_name,
6007 { "Profile name", "dvb-ci.opp.profile_name",
6008 FT_UINT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
6010 { &hf_dvbci_unattended,
6011 { "Unattended flag", "dvb-ci.opp.unattended_flag",
6012 FT_UINT8, BASE_HEX, NULL, 0x80, NULL, HFILL }
6014 { &hf_dvbci_opp_srv_type,
6015 { "Service type", "dvb-ci.opp.service_type", FT_UINT8,
6016 BASE_HEX|BASE_EXT_STRING, &mpeg_descr_service_type_vals_ext,
6019 { &hf_dvbci_dlv_cap_byte,
6020 { "Delivery capability byte", "dvb-ci.opp.dlv_cap_byte",
6021 FT_UINT8, BASE_HEX, VALS(dvbci_opp_dlv_cap), 0, NULL, HFILL }
6024 /* the CI+ spec is not particularly clear about this but an
6025 * application id in the capability loop must always be 2 bytes */
6026 { &hf_dvbci_app_cap_bytes,
6027 { "Application capability bytes", "dvb-ci.opp.app_cap_bytes",
6028 FT_UINT16, BASE_HEX|BASE_EXT_STRING,
6029 &mpeg_descr_data_bcast_id_vals_ext, 0, NULL, HFILL }
6031 { &hf_dvbci_desc_num,
6032 { "Next unprocessed descriptor number", "dvb-ci.opp.desc_num",
6033 FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }
6035 { &hf_dvbci_sig_strength,
6036 { "Signal strength", "dvb-ci.opp.sig_strength",
6037 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6039 { &hf_dvbci_sig_qual,
6040 { "Signal quality", "dvb-ci.opp.sig_qual",
6041 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6043 { &hf_dvbci_opp_tune_status,
6044 { "Tuning status", "dvb-ci.opp.tune_status",
6045 FT_UINT8, BASE_HEX, VALS(dvbci_opp_tune_stat), 0xF0, NULL, HFILL }
6047 { &hf_dvbci_opp_desc_loop_len,
6048 { "Descriptor loop length", "dvb-ci.opp.desc_loop_len",
6049 FT_UINT16, BASE_DEC, NULL, 0x0FFF, NULL, HFILL }
6051 { &hf_dvbci_sas_app_id,
6052 { "Application ID", "dvb-ci.sas.app_id",
6053 FT_UINT64, BASE_HEX, NULL, 0, NULL, HFILL }
6055 { &hf_dvbci_sas_sess_state,
6056 { "Connection state", "dvb-ci.sas.sess_state",
6057 FT_UINT8, BASE_DEC, VALS(dvbci_sas_sess_state), 0, NULL, HFILL }
6059 { &hf_dvbci_sas_msg_nb,
6060 { "Message number", "dvb-ci.sas.msg_nb",
6061 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6063 { &hf_dvbci_sas_msg_len,
6064 { "Message length", "dvb-ci.sas.msg_len",
6065 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
6069 static ei_register_info ei[] = {
6070 { &ei_dvbci_invalid_char_tbl,
6071 { "dvb-ci.invalid_char_tbl", PI_MALFORMED, PI_ERROR,
6072 "Invalid character table", EXPFILL }},
6073 { &ei_dvbci_ca_pmt_cmd_id, { "dvb-ci.ca.ca_pmt_cmd_id.ca_pmt", PI_MALFORMED, PI_ERROR, "The ca_pmt shall only contain ca descriptors (tag 0x9)", EXPFILL }},
6074 { &ei_dvbci_bad_length, { "dvb-ci.bad_length", PI_MALFORMED, PI_ERROR, "Invalid APDU length field, %s must be a multiple of 4 bytes", EXPFILL }},
6075 { &ei_dvbci_network_id, { "dvb-ci.hc.nid.ignored", PI_PROTOCOL, PI_NOTE, "Network ID is usually ignored by hosts", EXPFILL }},
6076 { &ei_dvbci_not_text_more_or_text_last, { "dvb-ci.not_text_more_or_text_last", PI_MALFORMED, PI_ERROR, "Items must be text_more() or text_last() objects", EXPFILL }},
6077 { &ei_dvbci_cup_progress, { "dvb-ci.cup.progress.invalid", PI_PROTOCOL, PI_WARN, "progress is in percent, value must be between 0 and 100", EXPFILL }},
6078 { &ei_dvbci_sac_payload_enc, { "dvb-ci.cc.sac.payload_enc.clear", PI_PROTOCOL, PI_NOTE, "The original PDU was encrypted, this exported PDU is in the clear", EXPFILL }},
6079 { &ei_dvbci_pin_evt_cent, { "dvb-ci.cc.pin_event_time_centi.invalid", PI_PROTOCOL, PI_WARN, "Invalid value for event time centiseconds, Value must be between 0 and 100", EXPFILL }},
6080 { &ei_dvbci_cicam_nit_table_id, { "dvb-ci.cicam_nit.table_id.invalid", PI_PROTOCOL, PI_WARN, "CICAM NIT must have table id 0x40 (NIT actual)", EXPFILL }},
6081 { &ei_dvbci_sig_qual, { "dvb-ci.opp.sig_qual.invalid", PI_PROTOCOL, PI_WARN, "Invalid value for signal strength / signal quality, values are in percent (0 to 100)", EXPFILL }},
6082 { &ei_dvbci_apdu_tag, { "dvb-ci.apdu_tag.invalid", PI_MALFORMED, PI_ERROR, "Invalid or unsupported APDU tag", EXPFILL }},
6083 { &ei_dvbci_apdu_not_supported, { "dvb-ci.apdu_not_supported", PI_PROTOCOL, PI_WARN, "Dissection of this APDU is not supported", EXPFILL }},
6084 { &ei_dvbci_apu_host_to_cam, { "dvb-ci.apu.host_to_cam", PI_PROTOCOL, PI_WARN, "Invalid APDU direction, this APDU must be sent from host to CAM", EXPFILL }},
6085 { &ei_dvbci_apu_cam_to_host, { "dvb-ci.apu.cam_to_host", PI_PROTOCOL, PI_WARN, "Invalid APDU direction, this APDU must be sent from CAM to host", EXPFILL }},
6086 { &ei_dvbci_res_class, { "dvb-ci.res.class.invalid", PI_PROTOCOL, PI_WARN, "Invalid resource class for this apdu", EXPFILL }},
6087 { &ei_dvbci_res_ver, { "dvb-ci.res.version.old", PI_PROTOCOL, PI_WARN, "Invalid resource version for this apdu", EXPFILL }},
6088 { &ei_dvbci_spdu_tag, { "dvb-ci.spdu_tag.invalid", PI_MALFORMED, PI_ERROR, "Invalid SPDU tag, See table 14 in the DVB-CI specification", EXPFILL }},
6089 { &ei_dvbci_spdu_host_to_cam, { "dvb-ci.spdu.host_to_cam", PI_PROTOCOL, PI_WARN, "Invalid SPDU direction, this SPDU must be sent from host to CAM", EXPFILL }},
6090 { &ei_dvbci_spdu_cam_to_host, { "dvb-ci.spdu.cam_to_host", PI_PROTOCOL, PI_WARN, "Invalid SPDU direction, this SPDU must be sent from CAM to host", EXPFILL }},
6091 { &ei_dvbci_tpdu_status_tag, { "dvb-ci.tpdu.status_tag.invalid", PI_MALFORMED, PI_ERROR, "Invalid status tag, this must always be T_SB (0x80)", EXPFILL }},
6092 { &ei_dvbci_t_c_id, { "dvb-ci.t_c_id.invalid", PI_PROTOCOL, PI_WARN, "Transport Connection ID mismatch, tcid is %d in the transport layer and %d in the link layer", EXPFILL }},
6093 { &ei_dvbci_sb_value, { "dvb-ci.sb_value.invalid", PI_PROTOCOL, PI_WARN, "Invalid SB_value, must be 0x00 or 0x80", EXPFILL }},
6094 { &ei_dvbci_c_tpdu_tag, { "dvb-ci.c_tpdu_tag.invalid", PI_MALFORMED, PI_ERROR, "Invalid Command-TPDU tag, see DVB-CI specification, table A.16 for valid values", EXPFILL }},
6095 { &ei_dvbci_r_tpdu_tag, { "dvb-ci.r_tpdu_tag.invalid", PI_MALFORMED, PI_ERROR, "Invalid Response-TPDU tag, see DVB-CI specification, table A.16 for valid values", EXPFILL }},
6096 { &ei_dvbci_r_tpdu_status_mandatory, { "dvb-ci.r_tpdu_status.mandatory", PI_MALFORMED, PI_ERROR, "Response TPDU's status part is missing, RTPDU status is mandatory", EXPFILL }},
6097 { &ei_dvbci_ml, { "dvb-ci.more_last.invalid", PI_PROTOCOL, PI_WARN, "Invalid More/Last indicator, second byte of an LPDU must be 0x80 or 0x00", EXPFILL }},
6098 { &ei_dvbci_buf_size, { "dvb-ci.buf_size.invalid", PI_PROTOCOL, PI_WARN, "Illegal buffer size command", EXPFILL }},
6099 { &ei_dvbci_cor_addr, { "dvb-ci.cor_address.invalid", PI_PROTOCOL, PI_WARN, "COR address must not be greater than 0xFFE (DVB-CI spec, A.5.6)", EXPFILL }},
6102 spdu_table = g_hash_table_new(g_direct_hash, g_direct_equal);
6103 for(i=0; i<array_length(spdu_info); i++) {
6104 g_hash_table_insert(spdu_table,
6105 GUINT_TO_POINTER((guint)spdu_info[i].tag),
6106 (const gpointer)(&spdu_info[i]));
6109 apdu_table = g_hash_table_new(g_direct_hash, g_direct_equal);
6110 for(i=0; i<array_length(apdu_info); i++) {
6111 g_hash_table_insert(apdu_table,
6112 GUINT_TO_POINTER((guint)apdu_info[i].tag),
6113 (const gpointer)(&apdu_info[i]));
6116 proto_dvbci = proto_register_protocol("DVB Common Interface", "DVB-CI", "dvb-ci");
6117 proto_register_field_array(proto_dvbci, hf, array_length(hf));
6118 proto_register_subtree_array(ett, array_length(ett));
6119 expert_dvbci = expert_register_protocol(proto_dvbci);
6120 expert_register_field_array(expert_dvbci, ei, array_length(ei));
6122 dvbci_module = prefs_register_protocol(
6123 proto_dvbci, proto_reg_handoff_dvbci);
6124 prefs_register_string_preference(dvbci_module,
6125 "sek", "SAC Encryption Key", "SAC Encryption Key (16 hex bytes)",
6127 prefs_register_string_preference(dvbci_module,
6128 "siv", "SAC Init Vector", "SAC Init Vector (16 hex bytes)",
6130 prefs_register_bool_preference(dvbci_module,
6132 "Dissect LSC messages",
6133 "Dissect the content of messages transmitted "
6134 "on the Low-Speed Communication resource. "
6135 "This requires a dissector for the protocol and target port "
6136 "contained in the connection descriptor.",
6137 &dvbci_dissect_lsc_msg);
6139 sas_msg_dissector_table = register_dissector_table("dvb-ci.sas.app_id_str",
6140 "SAS application id", FT_STRING, STR_ASCII);
6142 register_init_routine(dvbci_init);
6144 /* the dissector for decrypted CI+ SAC messages which we can export */
6145 new_register_dissector(EXPORTED_SAC_MSG_PROTO,
6146 dissect_dvbci_exported_sac_msg, proto_dvbci);
6151 proto_reg_handoff_dvbci(void)
6153 dissector_handle_t dvbci_handle;
6155 dvbci_handle = new_create_dissector_handle(dissect_dvbci, proto_dvbci);
6156 dissector_add_uint("wtap_encap", WTAP_ENCAP_DVBCI, dvbci_handle);
6158 data_handle = find_dissector("data");
6159 mpeg_pmt_handle = find_dissector("mpeg_pmt");
6160 dvb_nit_handle = find_dissector("dvb_nit");
6161 png_handle = find_dissector("png");
6162 tcp_dissector_table = find_dissector_table("tcp.port");
6163 udp_dissector_table = find_dissector_table("udp.port");
6165 exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_DVB_CI);
6167 if (dvbci_sek_bin) {
6168 g_free(dvbci_sek_bin);
6169 dvbci_sek_bin = NULL;
6171 if (dvbci_siv_bin) {
6172 g_free(dvbci_siv_bin);
6173 dvbci_siv_bin = NULL;
6175 pref_key_string_to_bin(dvbci_sek, &dvbci_sek_bin);
6176 pref_key_string_to_bin(dvbci_siv, &dvbci_siv_bin);
6180 * Editor modelines - http://www.wireshark.org/tools/modelines.html
6185 * indent-tabs-mode: nil
6188 * vi: set shiftwidth=4 tabstop=8 expandtab:
6189 * :indentSize=4:tabSize=8:noTabs=true: