2 * Routines for DVB-CI (Common Interface) dissection
3 * Copyright 2011-2013, Martin Kaiser <martin@kaiser.cx>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 /* This dissector supports DVB-CI as defined in EN50221 and
27 * CI+ (www.ci-plus.com).
28 * For more details, see http://wiki.wireshark.org/DVB-CI.
30 * The pcap input format for this dissector is documented at
31 * http://www.kaiser.cx/pcap-dvbci.html.
37 #include <epan/addr_resolv.h>
38 #include <epan/circuit.h>
39 #include <epan/packet.h>
40 #include <epan/exported_pdu.h>
41 #include <epan/reassemble.h>
42 #include <epan/prefs.h>
44 #include <epan/expert.h>
45 #include <epan/asn1.h>
46 #include <epan/dissectors/packet-dvbci.h>
47 #include <epan/dissectors/packet-mpeg-descriptor.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>
59 #define AES_BLOCK_LEN 16
60 #define AES_KEY_LEN 16
62 #define EXPORTED_SAC_MSG_PROTO "CI+ SAC message"
64 #define IS_DATA_TRANSFER(e) (e==DVBCI_EVT_DATA_CAM_TO_HOST || e==DVBCI_EVT_DATA_HOST_TO_CAM)
66 /* direction of data transfer in [as]pdu_info_t and elsewhere */
67 #define DATA_CAM_TO_HOST DVBCI_EVT_DATA_CAM_TO_HOST
68 #define DATA_HOST_TO_CAM DVBCI_EVT_DATA_HOST_TO_CAM
69 #define DIRECTION_ANY 0x0
71 /* source/destination address field */
72 #define ADDR_HOST "Host"
73 #define ADDR_CAM "CAM"
79 #define POWER_OFF 0x04
81 #define TS_BYPASS 0x06
87 /* Card Information Structure (CIS) */
90 #define CISTPL_NO_LINK 0x14
91 #define CISTPL_VERS_1 0x15
92 #define CISTPL_CONFIG 0x1A
93 #define CISTPL_CFTABLE_ENTRY 0x1B
94 #define CISTPL_DEVICE_OC 0x1C
95 #define CISTPL_DEVICE_OA 0x1D
96 #define CISTPL_MANFID 0x20
97 #define CISTPL_END 0xFF
99 #define CCSTPL_CIF 0xC0
100 /* interface types */
101 #define TPCE_IF_TYPE_MEM 0
102 #define TPCE_IF_TYPE_IO_MEM 1
103 #define TPCE_IF_TYPE_CUST0 4
104 #define TPCE_IF_TYPE_CUST1 5
105 #define TPCE_IF_TYPE_CUST2 6
106 #define TPCE_IF_TYPE_CUST3 7
112 /* base values of sequence ids for reassembly of fragmented tpdus
113 if there's two open transport connections, their tpdu fragments may be
114 interleaved, we must add the tcid to the base value in order to
115 distinguish between different transport connections
116 TPDU_SEQ_ID_BASE and SPDU_SEQ_ID_BASE can be arbitrary 32bit values, they
117 must be more than 256 apart since we add the 8bit tcid */
118 #define TPDU_SEQ_ID_BASE 123
119 /* same as above, the spdu fragments are also demultiplexed based on the
121 #define SPDU_SEQ_ID_BASE 2417
123 /* transport layer */
127 #define T_CREATE_T_C 0x82
128 #define T_C_T_C_REPLY 0x83
129 #define T_DELETE_T_C 0x84
130 #define T_D_T_C_REPLY 0x85
131 #define T_REQUEST_T_C 0x86
132 #define T_NEW_T_C 0x87
133 #define T_T_C_ERROR 0x88
134 #define T_DATA_LAST 0xA0
135 #define T_DATA_MORE 0xA1
137 #define SB_VAL_MSG_AVAILABLE 0x80
138 #define SB_VAL_NO_MSG_AVAILABLE 0x00
141 #define T_SESSION_NUMBER 0x90
142 #define T_OPEN_SESSION_REQUEST 0x91
143 #define T_OPEN_SESSION_RESPONSE 0x92
144 #define T_CREATE_SESSION 0x93
145 #define T_CREATE_SESSION_RESPONSE 0x94
146 #define T_CLOSE_SESSION_REQUEST 0x95
147 #define T_CLOSE_SESSION_RESPONSE 0x96
149 /* status for open/create session */
150 #define SESS_OPENED 0x00
151 #define SESS_NOT_OPENED_RES_NON_EXIST 0xF0
152 #define SESS_NOT_OPENED_RES_UNAVAIL 0xF1
153 #define SESS_NOT_OPENED_RES_VER_LOWER 0xF2
154 #define SESS_NOT_OPENED_RES_BUSY 0xF3
156 /* status for close session */
157 #define SESS_CLOSED 0x00
158 #define SESS_NB_NOT_ALLOC 0xF0
160 /* circuit id from session number (16bit) and transport connection id * (8bit) */
161 #define CT_ID(s,t) ((guint32)(s<<8|t))
164 #define RES_ID_TYPE_MASK 0xC0000000
165 #define RES_CLASS_MASK 0x3FFF0000
166 #define RES_TYPE_MASK 0x0000FFC0
167 #define RES_VER_MASK 0x0000003F
170 #define RES_CLASS_RM 0x01
171 #define RES_CLASS_AP 0x02
172 #define RES_CLASS_CA 0x03
173 #define RES_CLASS_AUT 0x10
174 #define RES_CLASS_HC 0x20
175 #define RES_CLASS_DT 0x24
176 #define RES_CLASS_MMI 0x40
177 #define RES_CLASS_AMI 0x41
178 #define RES_CLASS_LSC 0x60
179 #define RES_CLASS_CC 0x8C
180 #define RES_CLASS_HLC 0x8D
181 #define RES_CLASS_CUP 0x8E
182 #define RES_CLASS_OPP 0x8F
183 #define RES_CLASS_SAS 0x96
185 #define RES_ID_LEN 4 /* bytes */
186 #define RES_CLASS(_res_id) (_res_id & RES_CLASS_MASK) >> 16
187 #define RES_VER(_res_id) (_res_id & RES_VER_MASK)
189 /* appinfo resource */
190 #define APP_TYPE_CA 0x1
191 #define APP_TYPE_EPG 0x2
193 #define DATA_RATE_72 0x0
194 #define DATA_RATE_96 0x1
197 #define LIST_MGMT_MORE 0x0
198 #define LIST_MGMT_FIRST 0x1
199 #define LIST_MGMT_LAST 0x2
200 #define LIST_MGMT_ONLY 0x3
201 #define LIST_MGMT_ADD 0x4
202 #define LIST_MGMT_UPDATE 0x5
204 #define CMD_ID_OK_DESCR 0x1
205 #define CMD_ID_OK_MMI 0x2
206 #define CMD_ID_QUERY 0x3
207 #define CMD_ID_NOT_SELECTED 0x4
209 #define CA_DESC_TAG 0x9
211 #define CA_ENAB_DESC_OK 0x01
212 #define CA_ENAB_DESC_OK_PURCHASE 0x02
213 #define CA_ENAB_DESC_OK_TECH 0x03
214 #define CA_ENAB_DESC_NG_ENTITLEMENT 0x71
215 #define CA_ENAB_DESC_NG_TECH 0x73
217 /* host control resource */
218 #define HC_STAT_OK 0x0
219 #define HC_STAT_ERR_DLVRY 0x1
220 #define HC_STAT_ERR_LOCK 0x2
221 #define HC_STAT_ERR_BUSY 0x3
222 #define HC_STAT_ERR_PARAM 0x4
223 #define HC_STAT_ERR_NOT_FOUND 0x5
224 #define HC_STAT_ERR_UNKNOWN 0x6
226 #define HC_RELEASE_OK 0x0
227 #define HC_RELEASE_REFUSED 0x1
230 #define CLOSE_MMI_CMD_ID_IMMEDIATE 0x0
231 #define CLOSE_MMI_CMD_ID_DELAY 0x1
233 /* only commands and parameters for high-level mmi are supported */
234 #define DISP_CMD_SET_MMI_MODE 1
235 #define DISP_CMD_GET_DISP_TBL 2
236 #define DISP_CMD_GET_INP_TBL 3
238 #define MMI_MODE_HIGH 1
240 #define DISP_REP_ID_MMI_MODE_ACK 0x01
241 #define DISP_REP_ID_DISP_CHAR_TBL 0x02
242 #define DISP_REP_ID_INP_CHAR_TBL 0x03
243 #define DISP_REP_ID_UNKNOWN_CMD 0xF0
244 #define DISP_REP_ID_UNKNOWN_MMI_MODE 0xF1
245 #define DISP_REP_ID_UNKNOWN_CHAR_TBL 0xF2
247 #define VISIBLE_ANS 0
250 #define ANSW_ID_CANCEL 0x00
251 #define ANSW_ID_ANSWER 0x01
253 /* used for answer_text_length, choice_nb and item_nb */
254 #define NB_UNKNOWN 0xFF
256 /* character tables, DVB-SI spec annex A.2 */
257 #define CHAR_TBL_8859_5 0x01
258 #define CHAR_TBL_8859_6 0x02
259 #define CHAR_TBL_8859_7 0x03
260 #define CHAR_TBL_8859_8 0x04
261 #define CHAR_TBL_8859_9 0x05
262 #define CHAR_TBL_8859_10 0x06
263 #define CHAR_TBL_8859_11 0x07
264 #define CHAR_TBL_8859_13 0x09
265 #define CHAR_TBL_8859_14 0x0A
266 #define CHAR_TBL_8859_15 0x0B
267 #define CHAR_TBL_MULTI_BYTE 0x10
268 #define CHAR_TBL_ENC_TYPE_ID 0x1F
270 /* control codes for texts, DVB-SI spec annex A.1 */
271 #define TEXT_CTRL_EMPH_ON 0x86
272 #define TEXT_CTRL_EMPH_OFF 0x87
273 #define TEXT_CTRL_CRLF 0x8A
276 /* cam upgrade resource */
277 #define CUP_DELAYED 0x0
278 #define CUP_IMMEDIATE 0x1
280 #define CUP_ANS_NO 0x0
281 #define CUP_ANS_YES 0x1
282 #define CUP_ANS_ASK 0x2
284 #define CUP_RESET_PCMCIA 0x0
285 #define CUP_RESET_CMDIF 0x1
286 #define CUP_RESET_NONE 0x2
288 /* content control resource */
289 #define CC_ID_HOST_ID 0x05
290 #define CC_ID_CICAM_ID 0x06
291 #define CC_ID_HOST_BRAND_CERT 0x07
292 #define CC_ID_CICAM_BRAND_CERT 0x08
293 #define CC_ID_KP 0x0C
294 #define CC_ID_DHPH 0x0D
295 #define CC_ID_DHPM 0x0E
296 #define CC_ID_HOST_DEV_CERT 0x0F
297 #define CC_ID_CICAM_DEV_CERT 0x10
298 #define CC_ID_SIG_A 0x11
299 #define CC_ID_SIG_B 0x12
300 #define CC_ID_AUTH_NONCE 0x13
301 #define CC_ID_NS_HOST 0x14
302 #define CC_ID_NS_MODULE 0x15
303 #define CC_ID_AKH 0x16
304 #define CC_ID_URI 0x19
305 #define CC_ID_PROG_NUM 0x1A
306 #define CC_ID_URI_CNF 0x1B
307 #define CC_ID_KEY_REGISTER 0x1C
308 #define CC_ID_URI_VERSIONS 0x1D
309 #define CC_ID_STATUS_FIELD 0x1E
310 #define CC_ID_SRM_DATA 0x1F
311 #define CC_ID_SRM_CONFIRM 0x20
312 #define CC_ID_CICAM_LICENSE 0x21
313 #define CC_ID_LICENSE_STATUS 0x22
314 #define CC_ID_LICENSE_RCV_STATUS 0x23
315 #define CC_ID_HOST_LICENSE 0x24
316 #define CC_ID_PLAY_COUNT 0x25
317 #define CC_ID_OPERATING_MODE 0x26
318 #define CC_ID_PINCODE_DATA 0x27
319 #define CC_ID_REC_START_STATUS 0x28
320 #define CC_ID_MODE_CHG_STATUS 0x29
321 #define CC_ID_REC_STOP_STATUS 0x2A
323 #define CC_KEY_EVEN 0x0
324 #define CC_KEY_ODD 0x1
326 #define CC_STATUS_OK 0x0
327 #define CC_STATUS_NO_CC_SUPPORT 0x1
328 #define CC_STATUS_HOST_BUSY 0x2
329 #define CC_STATUS_AUTH_FAILED_OR_NO_SRM 0x3
330 #define CC_STATUS_CICAM_BUSY 0x4
331 #define CC_STATUS_REC_MODE_ERR 0x5
333 #define SAC_MSG_HDR_LEN 8
335 #define CC_SAC_AUTH_AES128_XCBC_MAC 0x0
336 #define CC_SAC_ENC_AES128_CBC 0x0
338 #define CC_CAP_NONE 0x0
339 #define CC_CAP_CAS_PIN 0x1
340 #define CC_CAP_CAS_FTA_PIN 0x2
341 #define CC_CAP_CAS_PIN_CACHED 0x3
342 #define CC_CAP_CAS_FTA_PIN_CACHED 0x4
344 /* length of DVB-SI utc time field in bytes */
345 #define UTC_TIME_LEN 5
347 #define CC_PIN_BAD 0x0
348 #define CC_PIN_CAM_BUSY 0x1
349 #define CC_PIN_OK 0x2
350 #define CC_PIN_UNCONFIRMED 0x3
351 #define CC_PIN_VB_NOT_REQ 0x4
352 #define CC_PIN_CSA 0x5
354 #define CC_OP_MODE_WATCH_BUFFER 0x0
355 #define CC_OP_MODE_TIMESHIFT 0x1
356 #define CC_OP_MODE_UNATTENDED 0x2
358 /* application mmi resource */
359 #define ACK_CODE_OK 0x1
360 #define ACK_CODE_WRONG_API 0x2
361 #define ACK_CODE_API_BUSY 0x3
363 #define REQ_TYPE_FILE 0x0
364 #define REQ_TYPE_DATA 0x1
365 #define REQ_TYPE_FILE_HASH 0x2
366 #define REQ_TYPE_REQ 0x3
369 #define COMMS_CMD_ID_CONNECT_ON_CHANNEL 1
370 #define COMMS_CMD_ID_DISCONNECT_ON_CHANNEL 2
371 #define COMMS_CMD_ID_SET_PARAMS 3
372 #define COMMS_CMD_ID_ENQUIRE_STATUS 4
373 #define COMMS_CMD_ID_GET_NEXT_BUFFER 5
375 #define CONN_DESC_TEL 1
376 #define CONN_DESC_CABLE 2
377 #define CONN_DESC_IP 3
378 #define CONN_DESC_HOSTNAME 4
380 #define LSC_DESC_IP 0xCF
381 #define LSC_DESC_HOSTNAME 0xCD
389 #define COMMS_REP_ID_CONNECT_ACK 1
390 #define COMMS_REP_ID_DISCONNECT_ACK 2
391 #define COMMS_REP_ID_SET_PARAMS_ACK 3
392 #define COMMS_REP_ID_STATUS_REPLY 4
393 #define COMMS_REP_ID_GET_NEXT_BUFFER_ACK 5
394 #define COMMS_REP_ID_SEND_ACK 6
397 #define LSC_RET_DISCONNECTED 0
398 #define LSC_RET_CONNECTED 1
399 #define LSC_RET_TOO_BIG 0xFE
401 /* operator profile resource */
402 #define TABLE_ID_CICAM_NIT 0x40 /* CICAM NIT must be a NIT actual */
404 #define OPP_REF_REG_FLG_NONE 0
405 #define OPP_REF_REG_FLG_ADV 1
406 #define OPP_REF_REG_FLG_URG 2
407 #define OPP_REF_REG_FLG_SCHED 3
410 #define SAS_SESS_STATE_CONNECTED 0
411 #define SAS_SESS_STATE_NOT_FOUND 1
412 #define SAS_SESS_STATE_DENIED 2
415 /* application layer */
417 #define APDU_TAG_SIZE 3
419 /* "don't care" value for min_len_field and len_field (this can't be 0) */
420 #define LEN_FIELD_ANY G_MAXUINT32
422 static GHashTable
*apdu_table
= NULL
;
424 typedef struct _apdu_info_t
{
426 /* the minimum length required for this apdu */
427 guint32 min_len_field
;
428 /* if the apdu has a well-known length, we enforce it here
429 * (otherwise, we set this to LEN_FIELD_ANY) */
434 void (*dissect_payload
)(guint32
, gint
,
435 tvbuff_t
*, gint
, circuit_t
*, packet_info
*, proto_tree
*);
439 void proto_reg_handoff_dvbci(void);
442 dissect_dvbci_payload_rm(guint32 tag
, gint len_field
,
443 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
444 packet_info
*pinfo
, proto_tree
*tree
);
446 dissect_dvbci_payload_ap(guint32 tag
, gint len_field _U_
,
447 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
448 packet_info
*pinfo
, proto_tree
*tree
);
450 dissect_dvbci_payload_ca(guint32 tag
, gint len_field
,
451 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
452 packet_info
*pinfo
, proto_tree
*tree
);
454 dissect_dvbci_payload_aut(guint32 tag
, gint len_field _U_
,
455 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
456 packet_info
*pinfo _U_
, proto_tree
*tree
);
458 dissect_dvbci_payload_hc(guint32 tag
, gint len_field _U_
,
459 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
460 packet_info
*pinfo
, proto_tree
*tree
);
462 dissect_dvbci_payload_dt(guint32 tag
, gint len_field
,
463 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
464 packet_info
*pinfo
, proto_tree
*tree
);
466 dissect_dvbci_payload_mmi(guint32 tag
, gint len_field
,
467 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
468 packet_info
*pinfo
, proto_tree
*tree
);
470 dissect_dvbci_payload_hlc(guint32 tag
, gint len_field _U_
,
471 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
472 packet_info
*pinfo
, proto_tree
*tree
);
474 dissect_dvbci_payload_cup(guint32 tag
, gint len_field _U_
,
475 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
476 packet_info
*pinfo
, proto_tree
*tree
);
478 dissect_dvbci_payload_cc(guint32 tag
, gint len_field _U_
,
479 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
480 packet_info
*pinfo
, proto_tree
*tree
);
482 dissect_dvbci_payload_ami(guint32 tag
, gint len_field _U_
,
483 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
484 packet_info
*pinfo
, proto_tree
*tree
);
486 dissect_dvbci_payload_lsc(guint32 tag
, gint len_field
,
487 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit
,
488 packet_info
*pinfo
, proto_tree
*tree
);
490 dissect_dvbci_payload_opp(guint32 tag
, gint len_field _U_
,
491 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
492 packet_info
*pinfo
, proto_tree
*tree
);
494 dissect_dvbci_payload_sas(guint32 tag
, gint len_field _U_
,
495 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit
,
496 packet_info
*pinfo
, proto_tree
*tree
);
500 #define T_PROFILE_ENQ 0x9F8010
501 #define T_PROFILE 0x9F8011
502 #define T_PROFILE_CHANGE 0x9F8012
503 #define T_APP_INFO_ENQ 0x9F8020
504 #define T_APP_INFO 0x9F8021
505 #define T_ENTER_MENU 0x9F8022
506 #define T_REQUEST_CICAM_RESET 0x9F8023
507 #define T_DATARATE_INFO 0x9F8024
508 #define T_CA_INFO_ENQ 0x9F8030
509 #define T_CA_INFO 0x9F8031
510 #define T_CA_PMT 0x9F8032
511 #define T_CA_PMT_REPLY 0x9F8033
512 #define T_AUTH_REQ 0x9F8200
513 #define T_AUTH_RESP 0x9F8201
514 #define T_TUNE 0x9F8400
515 #define T_REPLACE 0x9F8401
516 #define T_CLEAR_REPLACE 0x9F8402
517 #define T_ASK_RELEASE 0x9F8403
518 #define T_TUNE_BROADCAST_REQ 0x9F8404
519 #define T_TUNE_REPLY 0x9F8405
520 #define T_ASK_RELEASE_REPLY 0x9F8406
521 #define T_DATE_TIME_ENQ 0x9F8440
522 #define T_DATE_TIME 0x9F8441
523 #define T_CLOSE_MMI 0x9F8800
524 #define T_DISPLAY_CONTROL 0x9F8801
525 #define T_DISPLAY_REPLY 0x9F8802
526 #define T_ENQ 0x9F8807
527 #define T_ANSW 0x9F8808
528 #define T_MENU_LAST 0x9F8809
529 #define T_MENU_MORE 0x9F880A
530 #define T_MENU_ANSW 0x9F880B
531 #define T_LIST_LAST 0x9F880C
532 #define T_LIST_MORE 0x9F880D
533 #define T_HOST_COUNTRY_ENQ 0x9F8100
534 #define T_HOST_COUNTRY 0x9F8101
535 #define T_HOST_LANGUAGE_ENQ 0x9F8110
536 #define T_HOST_LANGUAGE 0x9F8111
537 #define T_CAM_FIRMWARE_UPGRADE 0x9F9D01
538 #define T_CAM_FIRMWARE_UPGRADE_REPLY 0x9F9D02
539 #define T_CAM_FIRMWARE_UPGRADE_PROGRESS 0x9F9D03
540 #define T_CAM_FIRMWARE_UPGRADE_COMPLETE 0x9F9D04
541 #define T_CC_OPEN_REQ 0x9F9001
542 #define T_CC_OPEN_CNF 0x9F9002
543 #define T_CC_DATA_REQ 0x9F9003
544 #define T_CC_DATA_CNF 0x9F9004
545 #define T_CC_SYNC_REQ 0x9F9005
546 #define T_CC_SYNC_CNF 0x9F9006
547 #define T_CC_SAC_DATA_REQ 0x9F9007
548 #define T_CC_SAC_DATA_CNF 0x9F9008
549 #define T_CC_SAC_SYNC_REQ 0x9F9009
550 #define T_CC_SAC_SYNC_CNF 0x9F9010
551 #define T_CC_PIN_CAPABILITIES_REQ 0x9F9011
552 #define T_CC_PIN_CAPABILITIES_REPLY 0x9F9012
553 #define T_CC_PIN_CMD 0x9F9013
554 #define T_CC_PIN_REPLY 0x9F9014
555 #define T_CC_PIN_EVENT 0x9F9015
556 #define T_CC_PIN_PLAYBACK 0x9F9016
557 #define T_CC_PIN_MMI_REQ 0x9F9017
558 #define T_REQUEST_START 0x9F8000
559 #define T_REQUEST_START_ACK 0x9F8001
560 #define T_FILE_REQUEST 0x9F8002
561 #define T_FILE_ACKNOWLEDGE 0x9F8003
562 #define T_APP_ABORT_REQUEST 0x9F8004
563 #define T_APP_ABORT_ACK 0x9F8005
564 #define T_COMMS_CMD 0x9F8C00
565 #define T_COMMS_REPLY 0x9F8C02
566 #define T_COMMS_SEND_LAST 0x9F8C03
567 #define T_COMMS_SEND_MORE 0x9F8C04
568 #define T_COMMS_RCV_LAST 0x9F8C05
569 #define T_COMMS_RCV_MORE 0x9F8C06
570 #define T_OPERATOR_STATUS_REQ 0x9F9C00
571 #define T_OPERATOR_STATUS 0x9F9C01
572 #define T_OPERATOR_NIT_REQ 0x9F9C02
573 #define T_OPERATOR_NIT 0x9F9C03
574 #define T_OPERATOR_INFO_REQ 0x9F9C04
575 #define T_OPERATOR_INFO 0x9F9C05
576 #define T_OPERATOR_SEARCH_START 0x9F9C06
577 #define T_OPERATOR_SEARCH_STATUS 0x9F9C07
578 #define T_OPERATOR_EXIT 0x9F9C08
579 #define T_OPERATOR_TUNE 0x9F9C09
580 #define T_OPERATOR_TUNE_STATUS 0x9F9C0A
581 #define T_OPERATOR_ENTITLEMENT_ACK 0x9F9C0B
582 #define T_OPERATOR_SEARCH_CANCEL 0x9F9C0C
583 #define T_SAS_CONNECT_RQST 0x9F9A00
584 #define T_SAS_CONNECT_CNF 0x9F9A01
585 #define T_SAS_ASYNC_MSG 0x9F9A07
587 /* these are no real apdus, they just use the same format */
588 #define T_TEXT_LAST 0x9F8803
589 #define T_TEXT_MORE 0x9F8804
590 #define T_CONNECTION_DESCRIPTOR 0x9F8C01
592 #define IS_MENU_APDU(t) (t==T_MENU_MORE || t==T_MENU_LAST)
595 static const apdu_info_t apdu_info
[] = {
596 {T_PROFILE_ENQ
, 0, 0, DIRECTION_ANY
, RES_CLASS_RM
, 1, NULL
},
597 {T_PROFILE
, 0, LEN_FIELD_ANY
, DIRECTION_ANY
, RES_CLASS_RM
, 1, dissect_dvbci_payload_rm
},
598 {T_PROFILE_CHANGE
, 0, 0, DIRECTION_ANY
, RES_CLASS_RM
, 1, NULL
},
600 {T_APP_INFO_ENQ
, 0, 0, DATA_HOST_TO_CAM
, RES_CLASS_AP
, 1, NULL
},
601 {T_APP_INFO
, 6, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_AP
, 1, dissect_dvbci_payload_ap
},
602 {T_ENTER_MENU
, 0, 0, DATA_HOST_TO_CAM
, RES_CLASS_AP
, 1, NULL
},
603 {T_REQUEST_CICAM_RESET
, 0, 0, DATA_CAM_TO_HOST
, RES_CLASS_AP
, 3, NULL
},
604 {T_DATARATE_INFO
, 0, 1, DATA_HOST_TO_CAM
, RES_CLASS_AP
, 3, dissect_dvbci_payload_ap
},
606 {T_CA_INFO_ENQ
, 0, 0, DATA_HOST_TO_CAM
, RES_CLASS_CA
, 1, NULL
},
607 {T_CA_INFO
, 0, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_CA
, 1, dissect_dvbci_payload_ca
},
608 {T_CA_PMT
, 6, LEN_FIELD_ANY
, DATA_HOST_TO_CAM
, RES_CLASS_CA
, 1, dissect_dvbci_payload_ca
},
609 {T_CA_PMT_REPLY
, 8, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_CA
, 1, dissect_dvbci_payload_ca
},
611 {T_AUTH_REQ
, 2, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_AUT
, 1, dissect_dvbci_payload_aut
},
612 {T_AUTH_RESP
, 2, LEN_FIELD_ANY
, DATA_HOST_TO_CAM
, RES_CLASS_AUT
, 1, dissect_dvbci_payload_aut
},
614 {T_TUNE
, 0, 8, DATA_CAM_TO_HOST
, RES_CLASS_HC
, 1, dissect_dvbci_payload_hc
},
615 {T_REPLACE
, 0, 5, DATA_CAM_TO_HOST
, RES_CLASS_HC
, 1, dissect_dvbci_payload_hc
},
616 {T_CLEAR_REPLACE
, 0, 1, DATA_CAM_TO_HOST
, RES_CLASS_HC
, 1, dissect_dvbci_payload_hc
},
617 {T_ASK_RELEASE
, 0, 0, DATA_HOST_TO_CAM
, RES_CLASS_HC
, 1, NULL
},
618 {T_TUNE_BROADCAST_REQ
, 5, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_HC
, 2, dissect_dvbci_payload_hc
},
619 {T_TUNE_REPLY
, 1, 1, DATA_HOST_TO_CAM
, RES_CLASS_HC
, 2, dissect_dvbci_payload_hc
},
620 {T_ASK_RELEASE_REPLY
, 1, 1, DATA_CAM_TO_HOST
, RES_CLASS_HC
, 2, dissect_dvbci_payload_hc
},
622 {T_DATE_TIME_ENQ
, 0, 1, DATA_CAM_TO_HOST
, RES_CLASS_DT
, 1, dissect_dvbci_payload_dt
},
623 {T_DATE_TIME
, 5, LEN_FIELD_ANY
, DATA_HOST_TO_CAM
, RES_CLASS_DT
, 1, dissect_dvbci_payload_dt
},
625 {T_CLOSE_MMI
, 1, LEN_FIELD_ANY
, DIRECTION_ANY
, RES_CLASS_MMI
, 1, dissect_dvbci_payload_mmi
},
626 {T_DISPLAY_CONTROL
, 1, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_MMI
, 1, dissect_dvbci_payload_mmi
},
627 {T_DISPLAY_REPLY
, 1, LEN_FIELD_ANY
, DATA_HOST_TO_CAM
, RES_CLASS_MMI
, 1, dissect_dvbci_payload_mmi
},
628 {T_ENQ
, 2, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_MMI
, 1, dissect_dvbci_payload_mmi
},
629 {T_ANSW
, 1, LEN_FIELD_ANY
, DATA_HOST_TO_CAM
, RES_CLASS_MMI
, 1, dissect_dvbci_payload_mmi
},
630 {T_MENU_LAST
, 13, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_MMI
, 1, dissect_dvbci_payload_mmi
},
631 {T_MENU_MORE
, 13, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_MMI
, 1, dissect_dvbci_payload_mmi
},
632 {T_MENU_ANSW
, 0, 1, DATA_HOST_TO_CAM
, RES_CLASS_MMI
, 1, dissect_dvbci_payload_mmi
},
633 {T_LIST_LAST
, 13, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_MMI
, 1, dissect_dvbci_payload_mmi
},
634 {T_LIST_MORE
, 13, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_MMI
, 1, dissect_dvbci_payload_mmi
},
636 {T_HOST_COUNTRY_ENQ
, 0, 0, DATA_CAM_TO_HOST
, RES_CLASS_HLC
, 1, NULL
},
637 {T_HOST_COUNTRY
, 0, 3, DATA_HOST_TO_CAM
, RES_CLASS_HLC
, 1, dissect_dvbci_payload_hlc
},
638 {T_HOST_LANGUAGE_ENQ
, 0, 0, DATA_CAM_TO_HOST
, RES_CLASS_HLC
, 1, NULL
},
639 {T_HOST_LANGUAGE
, 0, 3, DATA_HOST_TO_CAM
, RES_CLASS_HLC
, 1, dissect_dvbci_payload_hlc
},
641 {T_CAM_FIRMWARE_UPGRADE
, 0, 3, DATA_CAM_TO_HOST
, RES_CLASS_CUP
, 1, dissect_dvbci_payload_cup
},
642 {T_CAM_FIRMWARE_UPGRADE_REPLY
, 0, 1, DATA_HOST_TO_CAM
, RES_CLASS_CUP
, 1, dissect_dvbci_payload_cup
},
643 {T_CAM_FIRMWARE_UPGRADE_PROGRESS
, 0, 1, DATA_CAM_TO_HOST
, RES_CLASS_CUP
, 1, dissect_dvbci_payload_cup
},
644 {T_CAM_FIRMWARE_UPGRADE_COMPLETE
, 0, 1, DATA_CAM_TO_HOST
, RES_CLASS_CUP
, 1, dissect_dvbci_payload_cup
},
646 {T_CC_OPEN_REQ
, 0, 0, DATA_CAM_TO_HOST
, RES_CLASS_CC
, 1, NULL
},
647 {T_CC_OPEN_CNF
, 0, 1, DATA_HOST_TO_CAM
, RES_CLASS_CC
, 1, dissect_dvbci_payload_cc
},
648 {T_CC_DATA_REQ
, 3, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_CC
, 1, dissect_dvbci_payload_cc
},
649 {T_CC_DATA_CNF
, 2, LEN_FIELD_ANY
, DATA_HOST_TO_CAM
, RES_CLASS_CC
, 1, dissect_dvbci_payload_cc
},
650 {T_CC_SYNC_REQ
, 0, 0, DATA_CAM_TO_HOST
, RES_CLASS_CC
, 1, NULL
},
651 {T_CC_SYNC_CNF
, 0, 1, DATA_HOST_TO_CAM
, RES_CLASS_CC
, 1, dissect_dvbci_payload_cc
},
652 {T_CC_SAC_DATA_REQ
, 8, LEN_FIELD_ANY
, DIRECTION_ANY
, RES_CLASS_CC
, 1, dissect_dvbci_payload_cc
},
653 {T_CC_SAC_DATA_CNF
, 8, LEN_FIELD_ANY
, DIRECTION_ANY
, RES_CLASS_CC
, 1, dissect_dvbci_payload_cc
},
654 {T_CC_SAC_SYNC_REQ
, 8, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_CC
, 1, dissect_dvbci_payload_cc
},
655 {T_CC_SAC_SYNC_CNF
, 8, LEN_FIELD_ANY
, DATA_HOST_TO_CAM
, RES_CLASS_CC
, 1, dissect_dvbci_payload_cc
},
656 {T_CC_PIN_CAPABILITIES_REQ
, 0, 0, DATA_HOST_TO_CAM
, RES_CLASS_CC
, 2, NULL
},
657 {T_CC_PIN_CAPABILITIES_REPLY
, 7, 7, DATA_CAM_TO_HOST
, RES_CLASS_CC
, 2, dissect_dvbci_payload_cc
},
658 {T_CC_PIN_CMD
, 1, LEN_FIELD_ANY
, DATA_HOST_TO_CAM
, RES_CLASS_CC
, 2, dissect_dvbci_payload_cc
},
659 {T_CC_PIN_REPLY
, 1, 1, DATA_CAM_TO_HOST
, RES_CLASS_CC
, 2, dissect_dvbci_payload_cc
},
660 {T_CC_PIN_EVENT
, 25, 25, DATA_CAM_TO_HOST
, RES_CLASS_CC
, 2, dissect_dvbci_payload_cc
},
661 {T_CC_PIN_PLAYBACK
, 16, 16, DATA_HOST_TO_CAM
, RES_CLASS_CC
, 2, dissect_dvbci_payload_cc
},
662 {T_CC_PIN_MMI_REQ
, 1, LEN_FIELD_ANY
, DATA_HOST_TO_CAM
, RES_CLASS_CC
, 2, dissect_dvbci_payload_cc
},
664 {T_REQUEST_START
, 2, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_AMI
, 1, dissect_dvbci_payload_ami
},
665 {T_REQUEST_START_ACK
, 0, 1, DATA_HOST_TO_CAM
, RES_CLASS_AMI
, 1, dissect_dvbci_payload_ami
},
666 {T_FILE_REQUEST
, 1, LEN_FIELD_ANY
, DATA_HOST_TO_CAM
, RES_CLASS_AMI
, 1, dissect_dvbci_payload_ami
},
667 {T_FILE_ACKNOWLEDGE
, 2, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_AMI
, 1, dissect_dvbci_payload_ami
},
668 {T_APP_ABORT_REQUEST
, 0, LEN_FIELD_ANY
, DIRECTION_ANY
, RES_CLASS_AMI
, 1, dissect_dvbci_payload_ami
},
669 {T_APP_ABORT_ACK
, 0, LEN_FIELD_ANY
, DIRECTION_ANY
, RES_CLASS_AMI
, 1, dissect_dvbci_payload_ami
},
671 {T_COMMS_CMD
, 1, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_LSC
, 1, dissect_dvbci_payload_lsc
},
672 {T_COMMS_REPLY
, 0, 2, DATA_HOST_TO_CAM
, RES_CLASS_LSC
, 1, dissect_dvbci_payload_lsc
},
673 {T_COMMS_SEND_LAST
, 2, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_LSC
, 1, dissect_dvbci_payload_lsc
},
674 {T_COMMS_SEND_MORE
, 2, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_LSC
, 1, dissect_dvbci_payload_lsc
},
675 {T_COMMS_RCV_LAST
, 2, LEN_FIELD_ANY
, DATA_HOST_TO_CAM
, RES_CLASS_LSC
, 1, dissect_dvbci_payload_lsc
},
676 {T_COMMS_RCV_MORE
, 2, LEN_FIELD_ANY
, DATA_HOST_TO_CAM
, RES_CLASS_LSC
, 1, dissect_dvbci_payload_lsc
},
678 {T_OPERATOR_STATUS_REQ
, 0, 0, DATA_HOST_TO_CAM
, RES_CLASS_OPP
, 1, NULL
},
679 {T_OPERATOR_STATUS
, 0, 6, DATA_CAM_TO_HOST
, RES_CLASS_OPP
, 1, dissect_dvbci_payload_opp
},
680 {T_OPERATOR_NIT_REQ
, 0, 0, DATA_HOST_TO_CAM
, RES_CLASS_OPP
, 1, NULL
},
681 {T_OPERATOR_NIT
, 2, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_OPP
, 1, dissect_dvbci_payload_opp
},
682 {T_OPERATOR_INFO_REQ
, 0, 0, DATA_HOST_TO_CAM
, RES_CLASS_OPP
, 1, NULL
},
683 {T_OPERATOR_INFO
, 1, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_OPP
, 1, dissect_dvbci_payload_opp
},
684 {T_OPERATOR_SEARCH_START
, 3, LEN_FIELD_ANY
, DATA_HOST_TO_CAM
, RES_CLASS_OPP
, 1, dissect_dvbci_payload_opp
},
685 {T_OPERATOR_SEARCH_STATUS
, 0, 6, DATA_CAM_TO_HOST
, RES_CLASS_OPP
, 1, dissect_dvbci_payload_opp
},
686 {T_OPERATOR_EXIT
, 0, 0, DATA_HOST_TO_CAM
, RES_CLASS_OPP
, 1, NULL
},
687 {T_OPERATOR_TUNE
, 2, LEN_FIELD_ANY
, DATA_CAM_TO_HOST
, RES_CLASS_OPP
, 1, dissect_dvbci_payload_opp
},
688 {T_OPERATOR_TUNE_STATUS
, 5, LEN_FIELD_ANY
, DATA_HOST_TO_CAM
, RES_CLASS_OPP
, 1, dissect_dvbci_payload_opp
},
689 {T_OPERATOR_ENTITLEMENT_ACK
, 0, 0, DATA_HOST_TO_CAM
, RES_CLASS_OPP
, 1, NULL
},
690 {T_OPERATOR_SEARCH_CANCEL
, 0, 0, DATA_HOST_TO_CAM
, RES_CLASS_OPP
, 1, NULL
},
692 {T_SAS_CONNECT_RQST
, 0, 8, DATA_HOST_TO_CAM
, RES_CLASS_SAS
, 1, dissect_dvbci_payload_sas
},
693 {T_SAS_CONNECT_CNF
, 0, 9, DATA_CAM_TO_HOST
, RES_CLASS_SAS
, 1, dissect_dvbci_payload_sas
},
694 {T_SAS_ASYNC_MSG
, 3, LEN_FIELD_ANY
, DIRECTION_ANY
, RES_CLASS_SAS
, 1, dissect_dvbci_payload_sas
}
697 static const value_string dvbci_apdu_tag
[] = {
698 { T_PROFILE_ENQ
, "Profile enquiry" },
699 { T_PROFILE
, "Profile information" },
700 { T_PROFILE_CHANGE
, "Profile change notification" },
701 { T_APP_INFO_ENQ
, "Application info enquiry" },
702 { T_APP_INFO
, "Application info" },
703 { T_ENTER_MENU
, "Enter menu" },
704 { T_REQUEST_CICAM_RESET
, "Request CICAM reset" },
705 { T_DATARATE_INFO
, "Datarate info" },
706 { T_CA_INFO_ENQ
, "CA info enquiry" },
707 { T_CA_INFO
, "CA info" },
708 { T_CA_PMT
, "CA PMT" },
709 { T_CA_PMT_REPLY
, "CA PMT reply" },
710 { T_AUTH_REQ
, "Authentication request" },
711 { T_AUTH_RESP
, "Authentication response" },
713 { T_REPLACE
, "Replace" },
714 { T_CLEAR_REPLACE
, "Clear replace" },
715 { T_ASK_RELEASE
, "Ask release" },
716 { T_TUNE_BROADCAST_REQ
, "Tune broadcast request" },
717 { T_TUNE_REPLY
, "Tune reply" },
718 { T_ASK_RELEASE_REPLY
, "Ask release reply" },
719 { T_DATE_TIME_ENQ
, "Date-Time enquiry" },
720 { T_DATE_TIME
, "Date-Time" },
721 { T_CLOSE_MMI
, "Close MMI" },
722 { T_DISPLAY_CONTROL
, "Display control" },
723 { T_DISPLAY_REPLY
, "Display reply" },
724 { T_TEXT_LAST
, "Text last" },
725 { T_TEXT_MORE
, "Text more" },
726 { T_ENQ
, "Enquiry" },
727 { T_ANSW
, "Answer" },
728 { T_MENU_LAST
, "Menu last" },
729 { T_MENU_MORE
, "Menu more" },
730 { T_MENU_ANSW
, "Menu answer" },
731 { T_LIST_LAST
, "List last" },
732 { T_LIST_MORE
, "List more" },
733 { T_HOST_COUNTRY_ENQ
, "Host country enquiry" },
734 { T_HOST_COUNTRY
, "Host country" },
735 { T_HOST_LANGUAGE_ENQ
, "Host language enquiry" },
736 { T_HOST_LANGUAGE
, "Host language" },
737 { T_CAM_FIRMWARE_UPGRADE
, "CAM firmware upgrade" },
738 { T_CAM_FIRMWARE_UPGRADE_REPLY
, "CAM firmware upgrade reply" },
739 { T_CAM_FIRMWARE_UPGRADE_PROGRESS
, "CAM firmware upgrade progress" },
740 { T_CAM_FIRMWARE_UPGRADE_COMPLETE
, "CAM firmware upgrade complete" },
741 { T_CC_OPEN_REQ
, "CC open request" },
742 { T_CC_OPEN_CNF
, "CC open confirm" },
743 { T_CC_DATA_REQ
, "CC data request" },
744 { T_CC_DATA_CNF
, "CC data confirm" },
745 { T_CC_SYNC_REQ
, "CC sync request" },
746 { T_CC_SYNC_CNF
, "CC sync confirm" },
747 { T_CC_SAC_DATA_REQ
, "CC SAC data request" },
748 { T_CC_SAC_DATA_CNF
, "CC SAC data confirm" },
749 { T_CC_SAC_SYNC_REQ
, "CC SAC sync request" },
750 { T_CC_SAC_SYNC_CNF
, "CC SAC sync confirm" },
751 { T_CC_PIN_CAPABILITIES_REQ
, "CC PIN capabilities request" },
752 { T_CC_PIN_CAPABILITIES_REPLY
, "CC PIN capabilities reply" },
753 { T_CC_PIN_CMD
, "CC PIN command" },
754 { T_CC_PIN_REPLY
, "CC PIN reply" },
755 { T_CC_PIN_EVENT
, "CC PIN event" },
756 { T_CC_PIN_PLAYBACK
, "CC PIN playback" },
757 { T_CC_PIN_MMI_REQ
, "CC PIN MMI request" },
758 { T_REQUEST_START
, "Request start" },
759 { T_REQUEST_START_ACK
, "Request start ack" },
760 { T_FILE_REQUEST
, "File request" },
761 { T_FILE_ACKNOWLEDGE
, "File acknowledge" },
762 { T_APP_ABORT_REQUEST
, "App abort request" },
763 { T_APP_ABORT_ACK
, "App abort ack" },
764 { T_COMMS_CMD
, "Comms command" },
765 { T_COMMS_REPLY
, "Comms reply" },
766 { T_CONNECTION_DESCRIPTOR
, "Connection descriptor" },
767 { T_COMMS_SEND_LAST
, "Comms send last" },
768 { T_COMMS_SEND_MORE
, "Comms send more" },
769 { T_COMMS_RCV_LAST
, "Comms receive last" },
770 { T_COMMS_RCV_MORE
, "Comms receive more" },
771 { T_OPERATOR_STATUS_REQ
, "Operator status request" },
772 { T_OPERATOR_STATUS
, "Operator status" },
773 { T_OPERATOR_NIT_REQ
, "Operator NIT request" },
774 { T_OPERATOR_NIT
, "Operator NIT" },
775 { T_OPERATOR_INFO_REQ
, "Operator info request" },
776 { T_OPERATOR_INFO
, "Operator info" },
777 { T_OPERATOR_SEARCH_START
, "Operator search start" },
778 { T_OPERATOR_SEARCH_STATUS
, "Operator search status" },
779 { T_OPERATOR_EXIT
, "Operator exit" },
780 { T_OPERATOR_TUNE
, "Operator tune" },
781 { T_OPERATOR_TUNE_STATUS
, "Operator tune status" },
782 { T_OPERATOR_ENTITLEMENT_ACK
, "Operator entitlement acknowledge" },
783 { T_OPERATOR_SEARCH_CANCEL
, "Operator search cancel" },
784 { T_SAS_CONNECT_RQST
, "SAS connect request" },
785 { T_SAS_CONNECT_CNF
, "SAS connect confirm" },
786 { T_SAS_ASYNC_MSG
, "SAS async message" },
790 /* convert a byte that contains two 4bit BCD digits into a decimal value */
791 #define BCD44_TO_DEC(x) (((x&0xf0) >> 4) * 10 + (x&0x0f))
793 static int proto_dvbci
= -1;
795 static const gchar
*dvbci_sek
= NULL
;
796 static const gchar
*dvbci_siv
= NULL
;
797 static gboolean dvbci_dissect_lsc_msg
= FALSE
;
799 static dissector_handle_t data_handle
;
800 static dissector_handle_t mpeg_pmt_handle
;
801 static dissector_handle_t dvb_nit_handle
;
802 static dissector_table_t tcp_dissector_table
;
803 static dissector_table_t udp_dissector_table
;
805 static gint exported_pdu_tap
= -1;
807 static gint ett_dvbci
= -1;
808 static gint ett_dvbci_hdr
= -1;
809 static gint ett_dvbci_cis
= -1;
810 static gint ett_dvbci_cis_tpl
= -1;
811 static gint ett_dvbci_cis_subtpl
= -1;
812 static gint ett_dvbci_link
= -1;
813 static gint ett_dvbci_link_frag
= -1;
814 static gint ett_dvbci_link_frags
= -1;
815 static gint ett_dvbci_transport
= -1;
816 static gint ett_dvbci_transport_frag
= -1;
817 static gint ett_dvbci_transport_frags
= -1;
818 static gint ett_dvbci_session
= -1;
819 static gint ett_dvbci_res
= -1;
820 static gint ett_dvbci_application
= -1;
821 static gint ett_dvbci_es
= -1;
822 static gint ett_dvbci_ca_desc
= -1;
823 static gint ett_dvbci_text
= -1;
824 static gint ett_dvbci_cc_item
= -1;
825 static gint ett_dvbci_sac_msg_body
= -1;
826 static gint ett_dvbci_ami_req_types
= -1;
827 static gint ett_dvbci_lsc_conn_desc
= -1;
828 static gint ett_dvbci_opp_cap_loop
= -1;
829 static gint ett_dvbci_dlv_sys_hint
= -1;
832 static int hf_dvbci_event
= -1;
833 static int hf_dvbci_hw_event
= -1;
834 static int hf_dvbci_cor_addr
= -1;
835 static int hf_dvbci_cor_val
= -1;
836 static int hf_dvbci_cis_tpl_code
= -1;
837 static int hf_dvbci_cis_tpl_len
= -1;
838 static int hf_dvbci_cis_tpl_data
= -1;
839 static int hf_dvbci_cis_tpll_v1_major
= -1;
840 static int hf_dvbci_cis_tpll_v1_minor
= -1;
841 static int hf_dvbci_cis_tpll_v1_info_manuf
= -1;
842 static int hf_dvbci_cis_tpll_v1_info_name
= -1;
843 static int hf_dvbci_cis_tpll_v1_info_additional
= -1;
844 static int hf_dvbci_cis_tpll_v1_end
= -1;
845 static int hf_dvbci_cis_tpcc_rfsz
= -1;
846 static int hf_dvbci_cis_tpcc_rmsz
= -1;
847 static int hf_dvbci_cis_tpcc_rasz
= -1;
848 static int hf_dvbci_cis_tpcc_last
= -1;
849 static int hf_dvbci_cis_tpcc_radr
= -1;
850 static int hf_dvbci_cis_tpcc_rmsk
= -1;
851 static int hf_dvbci_cis_st_code
= -1;
852 static int hf_dvbci_cis_st_len
= -1;
853 static int hf_dvbci_cis_stci_ifn_size
= -1;
854 static int hf_dvbci_cis_stci_ifn
= -1;
855 static int hf_dvbci_cis_stci_str
= -1;
856 static int hf_dvbci_cis_tpce_indx_intface
= -1;
857 static int hf_dvbci_cis_tpce_indx_default
= -1;
858 static int hf_dvbci_cis_tpce_indx_cnf_entry
= -1;
859 static int hf_dvbci_cis_tpce_if_type
= -1;
860 static int hf_dvbci_cis_tpce_fs_mem_space
= -1;
861 static int hf_dvbci_cis_tpce_fs_irq
= -1;
862 static int hf_dvbci_cis_tpce_fs_io
= -1;
863 static int hf_dvbci_cis_tplmid_manf
= -1;
864 static int hf_dvbci_cis_tplmid_card
= -1;
865 static int hf_dvbci_buf_size
= -1;
866 static int hf_dvbci_tcid
= -1;
867 static int hf_dvbci_ml
= -1;
868 static int hf_dvbci_l_frags
= -1;
869 static int hf_dvbci_l_frag
= -1;
870 static int hf_dvbci_l_frag_overlap
= -1;
871 static int hf_dvbci_l_frag_overlap_conflicts
= -1;
872 static int hf_dvbci_l_frag_multiple_tails
= -1;
873 static int hf_dvbci_l_frag_too_long_frag
= -1;
874 static int hf_dvbci_l_frag_err
= -1;
875 static int hf_dvbci_l_frag_cnt
= -1;
876 static int hf_dvbci_l_reass_in
= -1;
877 static int hf_dvbci_l_reass_len
= -1;
878 static int hf_dvbci_c_tpdu_tag
= -1;
879 static int hf_dvbci_r_tpdu_tag
= -1;
880 static int hf_dvbci_t_c_id
= -1;
881 static int hf_dvbci_sb_value
= -1;
882 static int hf_dvbci_t_frags
= -1;
883 static int hf_dvbci_t_frag
= -1;
884 static int hf_dvbci_t_frag_overlap
= -1;
885 static int hf_dvbci_t_frag_overlap_conflicts
= -1;
886 static int hf_dvbci_t_frag_multiple_tails
= -1;
887 static int hf_dvbci_t_frag_too_long_frag
= -1;
888 static int hf_dvbci_t_frag_err
= -1;
889 static int hf_dvbci_t_frag_cnt
= -1;
890 static int hf_dvbci_t_reass_in
= -1;
891 static int hf_dvbci_t_reass_len
= -1;
892 static int hf_dvbci_spdu_tag
= -1;
893 static int hf_dvbci_sess_status
= -1;
894 static int hf_dvbci_sess_nb
= -1;
895 static int hf_dvbci_close_sess_status
= -1;
896 static int hf_dvbci_res_id_type
= -1;
897 static int hf_dvbci_res_class
= -1;
898 static int hf_dvbci_res_type
= -1;
899 static int hf_dvbci_res_ver
= -1;
900 static int hf_dvbci_apdu_tag
= -1;
901 static int hf_dvbci_app_type
= -1;
902 static int hf_dvbci_app_manf
= -1;
903 static int hf_dvbci_manf_code
= -1;
904 static int hf_dvbci_menu_str_len
= -1;
905 static int hf_dvbci_data_rate
= -1;
906 static int hf_dvbci_ca_sys_id
= -1;
907 static int hf_dvbci_ca_pmt_list_mgmt
= -1;
908 static int hf_dvbci_prog_num
= -1;
909 static int hf_dvbci_prog_info_len
= -1;
910 static int hf_dvbci_stream_type
= -1;
911 static int hf_dvbci_es_pid
= -1;
912 static int hf_dvbci_es_info_len
= -1;
913 static int hf_dvbci_ca_pmt_cmd_id
= -1;
914 static int hf_dvbci_descr_len
= -1;
915 static int hf_dvbci_ca_pid
= -1;
916 static int hf_dvbci_ca_enable_flag
= -1;
917 static int hf_dvbci_ca_enable
= -1;
918 static int hf_dvbci_auth_proto_id
= -1;
919 static int hf_dvbci_auth_req_bytes
= -1;
920 static int hf_dvbci_auth_resp_bytes
= -1;
921 static int hf_dvbci_network_id
= -1;
922 static int hf_dvbci_original_network_id
= -1;
923 static int hf_dvbci_transport_stream_id
= -1;
924 static int hf_dvbci_service_id
= -1;
925 static int hf_dvbci_replacement_ref
= -1;
926 static int hf_dvbci_replaced_pid
= -1;
927 static int hf_dvbci_replacement_pid
= -1;
928 static int hf_dvbci_pmt_flag
= -1;
929 static int hf_dvbci_hc_desc_loop_len
= -1;
930 static int hf_dvbci_hc_status
= -1;
931 static int hf_dvbci_hc_release_reply
= -1;
932 static int hf_dvbci_resp_intv
= -1;
933 static int hf_dvbci_utc_time
= -1;
934 static int hf_dvbci_local_offset
= -1;
935 static int hf_dvbci_close_mmi_cmd_id
= -1;
936 static int hf_dvbci_close_mmi_delay
= -1;
937 static int hf_dvbci_disp_ctl_cmd
= -1;
938 static int hf_dvbci_mmi_mode
= -1;
939 static int hf_dvbci_disp_rep_id
= -1;
940 static int hf_dvbci_char_tbl
= -1;
941 static int hf_dvbci_blind_ans
= -1;
942 static int hf_dvbci_ans_txt_len
= -1;
943 static int hf_dvbci_text_ctrl
= -1;
944 static int hf_dvbci_ans_id
= -1;
945 static int hf_dvbci_choice_nb
= -1;
946 static int hf_dvbci_choice_ref
= -1;
947 static int hf_dvbci_item_nb
= -1;
948 static int hf_dvbci_host_country
= -1;
949 static int hf_dvbci_host_language
= -1;
950 static int hf_dvbci_cup_type
= -1;
951 static int hf_dvbci_cup_download_time
= -1;
952 static int hf_dvbci_cup_answer
= -1;
953 static int hf_dvbci_cup_progress
= -1;
954 static int hf_dvbci_cup_reset
= -1;
955 static int hf_dvbci_cc_sys_id_bitmask
= -1;
956 static int hf_dvbci_cc_dat_id
= -1;
957 static int hf_dvbci_brand_cert
= -1;
958 static int hf_dvbci_dev_cert
= -1;
959 static int hf_dvbci_uri_ver
= -1;
960 static int hf_dvbci_uri_aps
= -1;
961 static int hf_dvbci_uri_emi
= -1;
962 static int hf_dvbci_uri_ict
= -1;
963 static int hf_dvbci_uri_rct
= -1;
964 static int hf_dvbci_cc_key_register
= -1;
965 static int hf_dvbci_cc_status_field
= -1;
966 static int hf_dvbci_cc_op_mode
= -1;
967 static int hf_dvbci_cc_data
= -1;
968 static int hf_dvbci_sac_msg_ctr
= -1;
969 static int hf_dvbci_sac_proto_ver
= -1;
970 static int hf_dvbci_sac_auth_cip
= -1;
971 static int hf_dvbci_sac_payload_enc
= -1;
972 static int hf_dvbci_sac_enc_cip
= -1;
973 static int hf_dvbci_sac_payload_len
= -1;
974 static int hf_dvbci_sac_enc_body
= -1;
975 static int hf_dvbci_sac_signature
= -1;
976 static int hf_dvbci_rating
= -1;
977 static int hf_dvbci_capability_field
= -1;
978 static int hf_dvbci_pin_chg_time
= -1;
979 static int hf_dvbci_pincode_status
= -1;
980 static int hf_dvbci_cc_prog_num
= -1;
981 static int hf_dvbci_pin_evt_time
= -1;
982 static int hf_dvbci_pin_evt_cent
= -1;
983 static int hf_dvbci_cc_priv_data
= -1;
984 static int hf_dvbci_pincode
= -1;
985 static int hf_dvbci_app_dom_id
= -1;
986 static int hf_dvbci_init_obj
= -1;
987 static int hf_dvbci_ack_code
= -1;
988 static int hf_dvbci_req_type
= -1;
989 static int hf_dvbci_file_hash
= -1;
990 static int hf_dvbci_file_name
= -1;
991 static int hf_dvbci_ami_priv_data
= -1;
992 static int hf_dvbci_req_ok
= -1;
993 static int hf_dvbci_file_ok
= -1;
994 static int hf_dvbci_file_data
= -1;
995 static int hf_dvbci_abort_req_code
= -1;
996 static int hf_dvbci_abort_ack_code
= -1;
997 static int hf_dvbci_phase_id
= -1;
998 static int hf_dvbci_comms_rep_id
= -1;
999 static int hf_dvbci_lsc_buf_size
= -1;
1000 static int hf_dvbci_lsc_ret_val
= -1;
1001 static int hf_dvbci_comms_cmd_id
= -1;
1002 static int hf_dvbci_conn_desc_type
= -1;
1003 static int hf_dvbci_lsc_media_tag
= -1;
1004 static int hf_dvbci_lsc_media_len
= -1;
1005 static int hf_dvbci_lsc_ip_ver
= -1;
1006 static int hf_dvbci_lsc_ipv4_addr
= -1;
1007 static int hf_dvbci_lsc_ipv6_addr
= -1;
1008 static int hf_dvbci_lsc_dst_port
= -1;
1009 static int hf_dvbci_lsc_proto
= -1;
1010 static int hf_dvbci_lsc_hostname
= -1;
1011 static int hf_dvbci_lsc_retry_count
= -1;
1012 static int hf_dvbci_lsc_timeout
= -1;
1013 static int hf_dvbci_info_ver_op_status
= -1;
1014 static int hf_dvbci_nit_ver
= -1;
1015 static int hf_dvbci_pro_typ
= -1;
1016 static int hf_dvbci_init_flag
= -1;
1017 static int hf_dvbci_ent_chg_flag
= -1;
1018 static int hf_dvbci_ent_val_flag
= -1;
1019 static int hf_dvbci_ref_req_flag
= -1;
1020 static int hf_dvbci_err_flag
= -1;
1021 static int hf_dvbci_dlv_sys_hint
= -1;
1022 static int hf_dvbci_dlv_sys_hint_t
= -1;
1023 static int hf_dvbci_dlv_sys_hint_s
= -1;
1024 static int hf_dvbci_dlv_sys_hint_c
= -1;
1025 static int hf_dvbci_refr_req_date
= -1;
1026 static int hf_dvbci_refr_req_time
= -1;
1027 static int hf_dvbci_nit_loop_len
= -1;
1028 static int hf_dvbci_info_valid
= -1;
1029 static int hf_dvbci_info_ver_op_info
= -1;
1030 static int hf_dvbci_cicam_onid
= -1;
1031 static int hf_dvbci_cicam_id
= -1;
1032 static int hf_dvbci_opp_char_tbl_multi
= -1;
1033 static int hf_dvbci_opp_char_tbl
= -1;
1034 static int hf_dvbci_enc_type_id
= -1;
1035 static int hf_dvbci_sdt_rst_trusted
= -1;
1036 static int hf_dvbci_eit_rst_trusted
= -1;
1037 static int hf_dvbci_eit_pf_usage
= -1;
1038 static int hf_dvbci_eit_sch_usage
= -1;
1039 static int hf_dvbci_ext_evt_usage
= -1;
1040 static int hf_dvbci_sdt_oth_trusted
= -1;
1041 static int hf_dvbci_eit_evt_trigger
= -1;
1042 static int hf_dvbci_opp_lang_code
= -1;
1043 static int hf_dvbci_prof_name
= -1;
1044 static int hf_dvbci_unattended
= -1;
1045 static int hf_dvbci_opp_srv_type
= -1;
1046 static int hf_dvbci_dlv_cap_byte
= -1;
1047 static int hf_dvbci_app_cap_bytes
= -1;
1048 static int hf_dvbci_desc_num
= -1;
1049 static int hf_dvbci_sig_strength
= -1;
1050 static int hf_dvbci_sig_qual
= -1;
1051 static int hf_dvbci_opp_tune_status
= -1;
1052 static int hf_dvbci_opp_desc_loop_len
= -1;
1053 static int hf_dvbci_sas_app_id
= -1;
1054 static int hf_dvbci_sas_sess_state
= -1;
1055 static int hf_dvbci_sas_msg_nb
= -1;
1056 static int hf_dvbci_sas_msg_len
= -1;
1058 static const int *dvbci_opp_dlv_sys_hint_fields
[] = {
1059 &hf_dvbci_dlv_sys_hint_t
,
1060 &hf_dvbci_dlv_sys_hint_s
,
1061 &hf_dvbci_dlv_sys_hint_c
,
1066 static expert_field ei_dvbci_spdu_tag
= EI_INIT
;
1067 static expert_field ei_dvbci_sac_payload_enc
= EI_INIT
;
1068 static expert_field ei_dvbci_buf_size
= EI_INIT
;
1069 static expert_field ei_dvbci_cicam_nit_table_id
= EI_INIT
;
1070 static expert_field ei_dvbci_c_tpdu_tag
= EI_INIT
;
1071 static expert_field ei_dvbci_res_class
= EI_INIT
;
1072 static expert_field ei_dvbci_bad_length
= EI_INIT
;
1073 static expert_field ei_dvbci_apdu_not_supported
= EI_INIT
;
1074 static expert_field ei_dvbci_not_text_more_or_text_last
= EI_INIT
;
1075 static expert_field ei_dvbci_apu_cam_to_host
= EI_INIT
;
1076 static expert_field ei_dvbci_ca_pmt_cmd_id
= EI_INIT
;
1077 static expert_field ei_dvbci_ml
= EI_INIT
;
1078 static expert_field ei_dvbci_cup_progress
= EI_INIT
;
1079 static expert_field ei_dvbci_sb_value
= EI_INIT
;
1080 static expert_field ei_dvbci_spdu_cam_to_host
= EI_INIT
;
1081 static expert_field ei_dvbci_spdu_host_to_cam
= EI_INIT
;
1082 static expert_field ei_dvbci_network_id
= EI_INIT
;
1083 static expert_field ei_dvbci_dvbci_char_tbl
= EI_INIT
;
1084 static expert_field ei_dvbci_t_c_id
= EI_INIT
;
1085 static expert_field ei_dvbci_tpdu_status_tag
= EI_INIT
;
1086 static expert_field ei_dvbci_r_tpdu_tag
= EI_INIT
;
1087 static expert_field ei_dvbci_cor_addr
= EI_INIT
;
1088 static expert_field ei_dvbci_pin_evt_cent
= EI_INIT
;
1089 static expert_field ei_dvbci_res_ver
= EI_INIT
;
1090 static expert_field ei_dvbci_apdu_tag
= EI_INIT
;
1091 static expert_field ei_dvbci_r_tpdu_status_mandatory
= EI_INIT
;
1092 static expert_field ei_dvbci_apu_host_to_cam
= EI_INIT
;
1093 static expert_field ei_dvbci_sig_qual
= EI_INIT
;
1095 static dissector_table_t sas_msg_dissector_table
;
1097 static reassembly_table tpdu_reassembly_table
;
1098 static reassembly_table spdu_reassembly_table
;
1100 static const fragment_items tpdu_frag_items
= {
1101 &ett_dvbci_link_frag
,
1102 &ett_dvbci_link_frags
,
1106 &hf_dvbci_l_frag_overlap
,
1107 &hf_dvbci_l_frag_overlap_conflicts
,
1108 &hf_dvbci_l_frag_multiple_tails
,
1109 &hf_dvbci_l_frag_too_long_frag
,
1110 &hf_dvbci_l_frag_err
,
1111 &hf_dvbci_l_frag_cnt
,
1113 &hf_dvbci_l_reass_in
,
1114 &hf_dvbci_l_reass_len
,
1115 /* Reassembled data field */
1119 static const fragment_items spdu_frag_items
= {
1120 &ett_dvbci_transport_frag
,
1121 &ett_dvbci_transport_frags
,
1125 &hf_dvbci_t_frag_overlap
,
1126 &hf_dvbci_t_frag_overlap_conflicts
,
1127 &hf_dvbci_t_frag_multiple_tails
,
1128 &hf_dvbci_t_frag_too_long_frag
,
1129 &hf_dvbci_t_frag_err
,
1130 &hf_dvbci_t_frag_cnt
,
1132 &hf_dvbci_t_reass_in
,
1133 &hf_dvbci_t_reass_len
,
1134 /* Reassembled data field */
1141 typedef struct _spdu_info_t
{
1147 static const value_string dvbci_hw_event
[] = {
1148 { CAM_IN
, "CI Module is inserted" },
1149 { CAM_OUT
, "CI Module is removed" },
1150 { POWER_ON
, "CI slot power on" },
1151 { POWER_OFF
, "CI slot power off" },
1152 { TS_ROUTE
, "Transport stream routed through the CI Module" },
1153 { TS_BYPASS
, "Transport stream bypasses the CI Module" },
1154 { RESET_H
, "Reset pin is high" },
1155 { RESET_L
, "Reset pin is low" },
1156 { READY_H
, "Ready pin is high" },
1157 { READY_L
, "Ready pin is low" },
1160 static const value_string dvbci_cis_tpl_code
[] = {
1161 { CISTPL_NO_LINK
, "No-link tuple" },
1162 { CISTPL_VERS_1
, "Level 1 version/product information" },
1163 { CISTPL_CONFIG
, "Configuration for a 16bit PC-Card" },
1164 { CISTPL_CFTABLE_ENTRY
, "Configuration-table entry" },
1165 { CISTPL_DEVICE_OC
, "Device information for Common Memory" },
1166 { CISTPL_DEVICE_OA
, "Device information for Attribute Memory" },
1167 { CISTPL_MANFID
, "Manufacturer indentification string" },
1168 { CISTPL_END
, "End of chain" },
1171 static const value_string dvbci_cis_subtpl_code
[] = {
1172 { CCSTPL_CIF
, "Custom interface subtuple" },
1175 static const value_string dvbci_cis_tpce_if_type
[] = {
1176 { TPCE_IF_TYPE_MEM
, "Memory" },
1177 { TPCE_IF_TYPE_IO_MEM
, "I/O and Memory" },
1178 { TPCE_IF_TYPE_CUST0
, "Custom Interface 0" },
1179 { TPCE_IF_TYPE_CUST1
, "Custom Interface 1" },
1180 { TPCE_IF_TYPE_CUST2
, "Custom Interface 2" },
1181 { TPCE_IF_TYPE_CUST3
, "Custom Interface 3" },
1184 static const value_string dvbci_ml
[] = {
1185 { ML_MORE
, "more TPDU fragments pending" },
1186 { ML_LAST
, "last TPDU fragment" },
1189 static const value_string dvbci_c_tpdu
[] = {
1191 { T_CREATE_T_C
, "T_create_t_c" },
1192 { T_DELETE_T_C
, "T_delete_t_c" },
1193 { T_D_T_C_REPLY
, "T_d_t_c_reply" },
1194 { T_NEW_T_C
, "T_new_t_c" },
1195 { T_T_C_ERROR
, "T_t_c_error" },
1196 { T_DATA_LAST
, "T_data_last" },
1197 { T_DATA_MORE
, "T_data_more" },
1200 static const value_string dvbci_r_tpdu
[] = {
1201 { T_C_T_C_REPLY
, "T_c_tc_reply" },
1202 { T_DELETE_T_C
, "T_delete_t_c" },
1203 { T_D_T_C_REPLY
, "T_d_t_c_reply" },
1204 { T_REQUEST_T_C
, "T_request_t_c" },
1205 { T_DATA_LAST
, "T_data_last" },
1206 { T_DATA_MORE
, "T_data_more" },
1209 static const value_string dvbci_sb_value
[] = {
1210 { SB_VAL_MSG_AVAILABLE
, "message available" },
1211 { SB_VAL_NO_MSG_AVAILABLE
, "no message available" },
1214 static const value_string dvbci_spdu_tag
[] = {
1215 { T_SESSION_NUMBER
, "Session Number (payload data)" },
1216 { T_OPEN_SESSION_REQUEST
, "Open Session Request" },
1217 { T_OPEN_SESSION_RESPONSE
, "Open Session Response" },
1218 { T_CREATE_SESSION
, "Create Session" },
1219 { T_CREATE_SESSION_RESPONSE
, "Create Session Response" },
1220 { T_CLOSE_SESSION_REQUEST
, "Close Session Request" },
1221 { T_CLOSE_SESSION_RESPONSE
, "Close Session Response" },
1224 static GHashTable
*spdu_table
= NULL
;
1225 static const spdu_info_t spdu_info
[] = {
1226 { T_SESSION_NUMBER
, DIRECTION_ANY
, 2 },
1227 { T_OPEN_SESSION_REQUEST
, DATA_CAM_TO_HOST
, 4 },
1228 { T_OPEN_SESSION_RESPONSE
, DATA_HOST_TO_CAM
, 7 },
1229 { T_CREATE_SESSION
, DATA_HOST_TO_CAM
, 6 },
1230 { T_CREATE_SESSION_RESPONSE
, DATA_CAM_TO_HOST
, 7 },
1231 { T_CLOSE_SESSION_REQUEST
, DIRECTION_ANY
, 2 },
1232 { T_CLOSE_SESSION_RESPONSE
, DIRECTION_ANY
, 3 }
1234 static const value_string dvbci_sess_status
[] = {
1237 { SESS_NOT_OPENED_RES_NON_EXIST
,
1238 "Resource does not exist" },
1239 { SESS_NOT_OPENED_RES_UNAVAIL
,
1240 "Resource exists but it's unavailable" },
1241 { SESS_NOT_OPENED_RES_VER_LOWER
,
1242 "Existing resource's version is lower than requested version" },
1243 { SESS_NOT_OPENED_RES_BUSY
,
1244 "Resource is busy" },
1247 static const value_string dvbci_close_sess_status
[] = {
1248 { SESS_CLOSED
, "Session closed" },
1249 { SESS_NB_NOT_ALLOC
, "Session number not allocated" },
1252 static const value_string dvbci_res_class
[] = {
1253 { RES_CLASS_RM
, "Resource Manager" },
1254 { RES_CLASS_AP
, "Application Info" },
1255 { RES_CLASS_CA
, "Conditional Access" },
1256 { RES_CLASS_AUT
, "Authentication" },
1257 { RES_CLASS_HC
, "Host Control" },
1258 { RES_CLASS_DT
, "Date-Time" },
1259 { RES_CLASS_MMI
, "Man-machine interface (MMI)" },
1260 { RES_CLASS_AMI
, "Application MMI" },
1261 { RES_CLASS_LSC
, "Low-Speed Communication" },
1262 { RES_CLASS_CC
, "Content Control" },
1263 { RES_CLASS_HLC
, "Host Language & Country" },
1264 { RES_CLASS_CUP
, "CAM Upgrade" },
1265 { RES_CLASS_OPP
, "Operator Profile" },
1266 { RES_CLASS_SAS
, "Specific Application Support" },
1269 static const value_string dvbci_app_type
[] = {
1270 { APP_TYPE_CA
, "Conditional Access" },
1271 { APP_TYPE_EPG
, "Electronic Progam Guide" },
1274 static const value_string dvbci_data_rate
[] = {
1275 { DATA_RATE_72
, "72 Mbit/s" },
1276 { DATA_RATE_96
, "96 Mbit/s" },
1279 static const value_string dvbci_ca_pmt_list_mgmt
[] = {
1280 { LIST_MGMT_MORE
, "more" },
1281 { LIST_MGMT_FIRST
, "first" },
1282 { LIST_MGMT_LAST
, "last" },
1283 { LIST_MGMT_ONLY
, "only" },
1284 { LIST_MGMT_ADD
, "add" },
1285 { LIST_MGMT_UPDATE
, "update" },
1288 static const value_string dvbci_ca_pmt_cmd_id
[] = {
1289 { CMD_ID_OK_DESCR
, "ok descrambling" },
1290 { CMD_ID_OK_MMI
, "ok mmi" },
1291 { CMD_ID_QUERY
, "query" },
1292 { CMD_ID_NOT_SELECTED
, "not selected" },
1295 static const value_string dvbci_ca_enable
[] = {
1296 { CA_ENAB_DESC_OK
, "descrambling possible" },
1297 { CA_ENAB_DESC_OK_PURCHASE
,
1298 "descrambling possible under conditions (purchase dialogue)" },
1299 { CA_ENAB_DESC_OK_TECH
,
1300 "descrambling possible under conditions (technical dialogue)" },
1301 { CA_ENAB_DESC_NG_ENTITLEMENT
,
1302 "descrambling not possible (because no entitlement)" },
1303 { CA_ENAB_DESC_NG_TECH
,
1304 "descrambling not possible (for technical reasons)" },
1307 static const value_string dvbci_hc_status
[] = {
1308 { HC_STAT_OK
, "ok" },
1309 { HC_STAT_ERR_DLVRY
, "unsupported delivery system descriptor" },
1310 { HC_STAT_ERR_LOCK
, "tuner not locking" },
1311 { HC_STAT_ERR_BUSY
, "tuner busy" },
1312 { HC_STAT_ERR_PARAM
, "bad or missing parameters" },
1313 { HC_STAT_ERR_NOT_FOUND
, "service not found" },
1314 { HC_STAT_ERR_UNKNOWN
, "unknown error" },
1317 static const value_string dvbci_hc_release_reply
[] = {
1318 { HC_RELEASE_OK
, "Host regains control of the tuner" },
1319 { HC_RELEASE_REFUSED
, "CICAM retains control of the tuner" },
1322 static const value_string dvbci_close_mmi_cmd_id
[] = {
1323 { CLOSE_MMI_CMD_ID_IMMEDIATE
, "immediate close" },
1324 { CLOSE_MMI_CMD_ID_DELAY
, "delayed close" },
1327 static const value_string dvbci_disp_ctl_cmd
[] = {
1328 { DISP_CMD_SET_MMI_MODE
, "set MMI mode" },
1329 { DISP_CMD_GET_DISP_TBL
, "get display character tables" },
1330 { DISP_CMD_GET_INP_TBL
, "get input character tables" },
1333 static const value_string dvbci_mmi_mode
[] = {
1334 { MMI_MODE_HIGH
, "High-level MMI" },
1337 static const value_string dvbci_disp_rep_id
[] = {
1338 { DISP_REP_ID_MMI_MODE_ACK
, "MMI mode acknowledge" },
1339 { DISP_REP_ID_DISP_CHAR_TBL
, "list display character tables" },
1340 { DISP_REP_ID_INP_CHAR_TBL
, "list input character tables" },
1341 { DISP_REP_ID_UNKNOWN_CMD
, "unknown display control command" },
1342 { DISP_REP_ID_UNKNOWN_MMI_MODE
, "unknown MMI mode" },
1343 { DISP_REP_ID_UNKNOWN_CHAR_TBL
, "unknown character table" },
1346 static const value_string dvbci_blind_ans
[] = {
1347 { VISIBLE_ANS
, "visible" },
1348 { BLIND_ANS
, "blind" },
1351 static const value_string dvbci_text_ctrl
[] = {
1352 { TEXT_CTRL_EMPH_ON
, "character emphasis on" },
1353 { TEXT_CTRL_EMPH_OFF
, "character emphasis off" },
1354 { TEXT_CTRL_CRLF
, "CR/LF" },
1357 static const value_string dvbci_char_tbl
[] = {
1358 { CHAR_TBL_8859_5
, "ISO/IEC 8859-5 (Latin/Cyrillic)" },
1359 { CHAR_TBL_8859_6
, "ISO/IEC 8859-6 (Latin/Arabic)" },
1360 { CHAR_TBL_8859_7
, "ISO/IEC 8859-7 (Latin/Greek)" },
1361 { CHAR_TBL_8859_8
, "ISO/IEC 8859-8 (Latin/Hebrew)" },
1362 { CHAR_TBL_8859_9
, "ISO/IEC 8859-9 (Latin No. 5)" },
1363 { CHAR_TBL_8859_10
, "ISO/IEC 8859-10 (Latin No. 6)" },
1364 { CHAR_TBL_8859_11
, "ISO/IEC 8859-11 (Latin/Thai)" },
1365 { CHAR_TBL_8859_13
, "ISO/IEC 8859-13 (Latin No. 7)" },
1366 { CHAR_TBL_8859_14
, "ISO/IEC 8859-14 (Latin No. 8 (Celtic))" },
1367 { CHAR_TBL_8859_15
, "ISO/IEC 8859-15 (Latin No. 9)" },
1368 { CHAR_TBL_ENC_TYPE_ID
, "defined by encoding_type_id" },
1369 /* don't add any multi-byte tables (>= 0x10) */
1372 static const value_string dvbci_ans_id
[] = {
1373 { ANSW_ID_CANCEL
, "cancel" },
1374 { ANSW_ID_ANSWER
, "answer" },
1377 static const value_string dvbci_cup_type
[] = {
1378 { CUP_DELAYED
, "delayed" },
1379 { CUP_IMMEDIATE
, "immediate" },
1382 static const value_string dvbci_cup_answer
[] = {
1383 { CUP_ANS_NO
, "upgrade denied" },
1384 { CUP_ANS_YES
, "upgrade allowed" },
1385 { CUP_ANS_ASK
, "ask the user for permission" },
1388 static const value_string dvbci_cup_reset
[] = {
1389 { CUP_RESET_PCMCIA
, "PCMCIA reset" },
1390 { CUP_RESET_CMDIF
, "CI command interface reset" },
1391 { CUP_RESET_NONE
, "no reset" },
1394 static const value_string dvbci_cc_dat_id
[] = {
1395 { CC_ID_HOST_ID
, "Host ID" },
1396 { CC_ID_CICAM_ID
, "Cicam ID" },
1397 { CC_ID_HOST_BRAND_CERT
, "Host brand certificate" },
1398 { CC_ID_CICAM_BRAND_CERT
, "Cicam brand certificate" },
1399 { CC_ID_KP
, "Key precursor for CCK" },
1400 { CC_ID_DHPH
, "Host Diffie-Hellman public key" },
1401 { CC_ID_DHPM
, "Cicam Diffie-Hellman public key" },
1402 { CC_ID_HOST_DEV_CERT
, "Host device certificate" },
1403 { CC_ID_CICAM_DEV_CERT
, "Cicam device certificate" },
1404 { CC_ID_SIG_A
, "Signature of host Diffie-Hellman public key" },
1405 { CC_ID_SIG_B
, "Signature of cicam Diffie-Hellman public key" },
1406 { CC_ID_NS_HOST
, "Host nonce" },
1407 { CC_ID_AUTH_NONCE
, "Nonce for authentication" },
1408 { CC_ID_NS_MODULE
, "Cicam nonce" },
1409 { CC_ID_AKH
, "Host authentication key" },
1410 { CC_ID_URI
, "URI" },
1411 { CC_ID_PROG_NUM
, "Program number" },
1412 { CC_ID_URI_CNF
, "URI confirmation" },
1413 { CC_ID_KEY_REGISTER
, "Key register" },
1414 { CC_ID_URI_VERSIONS
, "Supported URI versions" },
1415 { CC_ID_STATUS_FIELD
, "Status field" },
1416 { CC_ID_SRM_DATA
, "SRM for HDCP" },
1417 { CC_ID_SRM_CONFIRM
, "SRM confirmation hash" },
1418 { CC_ID_CICAM_LICENSE
, "License received from the cicam" },
1419 { CC_ID_LICENSE_STATUS
, "Current status of the license" },
1420 { CC_ID_LICENSE_RCV_STATUS
, "Status of the license exchange" },
1421 { CC_ID_HOST_LICENSE
,
1422 "License for which the host requests the current status" },
1423 { CC_ID_PLAY_COUNT
, "Play count" },
1424 { CC_ID_OPERATING_MODE
, "Operating mode" },
1425 { CC_ID_PINCODE_DATA
, "Pincode data" },
1426 { CC_ID_REC_START_STATUS
, "Record start status" },
1427 { CC_ID_MODE_CHG_STATUS
, "Change operating mode status" },
1428 { CC_ID_REC_STOP_STATUS
, "Record stop status" },
1431 static const value_string dvbci_cc_key_register
[] = {
1432 { CC_KEY_EVEN
, "Even" },
1433 { CC_KEY_ODD
, "Odd" },
1436 static const value_string dvbci_cc_status
[] = {
1437 { CC_STATUS_OK
, "Ok" },
1438 { CC_STATUS_NO_CC_SUPPORT
, "No CC support" },
1439 { CC_STATUS_HOST_BUSY
, "Host busy" },
1440 { CC_STATUS_AUTH_FAILED_OR_NO_SRM
, "Authentication failed / SRM not required" },
1441 { CC_STATUS_CICAM_BUSY
, "CICAM busy" },
1442 { CC_STATUS_REC_MODE_ERR
, "Recording mode error" },
1445 static const value_string dvbci_cc_sac_auth
[] = {
1446 { CC_SAC_AUTH_AES128_XCBC_MAC
, "AES 128 XCBC MAC" },
1449 static const value_string dvbci_cc_sac_enc
[] = {
1450 { CC_SAC_ENC_AES128_CBC
, "AES 128 CBC" },
1453 static const value_string dvbci_cc_cap
[] = {
1455 "No PIN handling capability" },
1457 "CAM can do PIN handling on CAS services" },
1458 { CC_CAP_CAS_FTA_PIN
,
1459 "CAM can do PIN handling on CAS and free services" },
1460 { CC_CAP_CAS_PIN_CACHED
,
1461 "CAM can do PIN handling on CAS services and supports PIN caching" },
1462 { CC_CAP_CAS_FTA_PIN_CACHED
,
1463 "CAM can do PIN handling on CAS and free services, supports PIN caching" },
1466 static const value_string dvbci_pincode_status
[] = {
1467 { CC_PIN_BAD
, "Bad pin code" },
1468 { CC_PIN_CAM_BUSY
, "CAM busy" },
1469 { CC_PIN_OK
, "Pin code correct" },
1470 { CC_PIN_UNCONFIRMED
, "Pin code unconfirmed" },
1471 { CC_PIN_VB_NOT_REQ
, "Video blanking not required" },
1472 { CC_PIN_CSA
, "Content still CSA scrambled" },
1475 static const value_string dvbci_cc_op_mode
[] = {
1476 { CC_OP_MODE_WATCH_BUFFER
, "Watch and buffer" },
1477 { CC_OP_MODE_TIMESHIFT
, "Timeshift" },
1478 { CC_OP_MODE_UNATTENDED
, "Unattended recording" },
1481 static const value_string dvbci_ack_code
[] = {
1482 { ACK_CODE_OK
, "Ok" },
1483 { ACK_CODE_WRONG_API
, "Application Domain unsupported" },
1484 { ACK_CODE_API_BUSY
, "Application Domain currently unavailable" },
1487 static const value_string dvbci_req_type
[] = {
1488 { REQ_TYPE_FILE
, "File" },
1489 { REQ_TYPE_DATA
, "Data" },
1490 { REQ_TYPE_FILE_HASH
, "FileHash" },
1491 { REQ_TYPE_REQ
, "List supported request types" },
1494 static const value_string dvbci_comms_cmd_id
[] = {
1495 { COMMS_CMD_ID_CONNECT_ON_CHANNEL
, "connect on channel" },
1496 { COMMS_CMD_ID_DISCONNECT_ON_CHANNEL
, "disconnect on channel" },
1497 { COMMS_CMD_ID_SET_PARAMS
, "set parameters" },
1498 { COMMS_CMD_ID_ENQUIRE_STATUS
, "status enquiry" },
1499 { COMMS_CMD_ID_GET_NEXT_BUFFER
, "get next buffer" },
1502 static const value_string dvbci_conn_desc_type
[] = {
1503 { CONN_DESC_TEL
, "DVB-SI telephone descriptor" },
1504 { CONN_DESC_CABLE
, "cable return channel" },
1505 { CONN_DESC_IP
, "IP descriptor" },
1506 { CONN_DESC_HOSTNAME
, "hostname descriptor" },
1509 static const value_string dvbci_lsc_desc_tag
[] = {
1510 { LSC_DESC_IP
, "IP descriptor" },
1511 { LSC_DESC_HOSTNAME
, "hostname descriptor" },
1514 static const value_string dvbci_lsc_ip_ver
[] = {
1515 { LSC_IPV4
, "IPv4" },
1516 { LSC_IPV6
, "IPv6" },
1519 static const value_string dvbci_lsc_proto
[] = {
1524 static const value_string dvbci_comms_rep_id
[] = {
1525 { COMMS_REP_ID_CONNECT_ACK
, "connect ack" },
1526 { COMMS_REP_ID_DISCONNECT_ACK
, "disconnect ack" },
1527 { COMMS_REP_ID_SET_PARAMS_ACK
, "set parameters ack" },
1528 { COMMS_REP_ID_STATUS_REPLY
, "status reply" },
1529 { COMMS_REP_ID_GET_NEXT_BUFFER_ACK
, "get next buffer ack" },
1530 { COMMS_REP_ID_SEND_ACK
, "send ack" },
1533 static const value_string dvbci_lsc_ret_val
[] = {
1534 { LSC_RET_OK
, "ok" },
1537 static const value_string dvbci_lsc_ret_val_connect
[] = {
1538 { LSC_RET_DISCONNECTED
, "disconnected" },
1539 { LSC_RET_CONNECTED
, "connected" },
1542 static const value_string dvbci_lsc_ret_val_params
[] = {
1543 { LSC_RET_OK
, "ok" },
1544 { LSC_RET_TOO_BIG
, "buffer size too big" },
1547 static const value_string dvbci_opp_ref_req_flag
[] = {
1548 { OPP_REF_REG_FLG_NONE
, "none" },
1549 { OPP_REF_REG_FLG_ADV
, "advance warning" },
1550 { OPP_REF_REG_FLG_URG
, "urgent" },
1551 { OPP_REF_REG_FLG_SCHED
, "scheduled" },
1554 static const value_string dvbci_sas_sess_state
[] = {
1555 { SAS_SESS_STATE_CONNECTED
, "connected" },
1556 { SAS_SESS_STATE_NOT_FOUND
, "application not found" },
1557 { SAS_SESS_STATE_DENIED
, "denied, no more connections available" },
1562 static guint16 buf_size_cam
; /* buffer size proposal by the CAM */
1563 /* buffer size proposal by the host == negotiated buffer size */
1564 static guint16 buf_size_host
;
1568 dvbci_set_addrs(guint8 event
, packet_info
*pinfo
)
1570 if (!IS_DATA_TRANSFER(event
))
1573 if (event
== DVBCI_EVT_DATA_HOST_TO_CAM
) {
1574 SET_ADDRESS(&pinfo
->src
, AT_STRINGZ
,
1575 (int)strlen(ADDR_HOST
)+1, ADDR_HOST
);
1576 SET_ADDRESS(&pinfo
->dst
, AT_STRINGZ
,
1577 (int)strlen(ADDR_CAM
)+1 , ADDR_CAM
);
1580 SET_ADDRESS(&pinfo
->src
, AT_STRINGZ
,
1581 (int)strlen(ADDR_CAM
)+1 , ADDR_CAM
);
1582 SET_ADDRESS(&pinfo
->dst
, AT_STRINGZ
,
1583 (int)strlen(ADDR_HOST
)+1, ADDR_HOST
);
1591 dvbci_get_evt_from_addrs(packet_info
*pinfo
)
1593 /* this should be working from C89 on */
1594 static const address a_cam
= { AT_STRINGZ
, -1, sizeof(ADDR_CAM
), ADDR_CAM
};
1595 static const address a_host
= { AT_STRINGZ
, -1, sizeof(ADDR_HOST
), ADDR_HOST
};
1597 if ( ADDRESSES_EQUAL(&(pinfo
->src
), &a_cam
) &&
1598 ADDRESSES_EQUAL(&(pinfo
->dst
), &a_host
) ) {
1599 return DVBCI_EVT_DATA_CAM_TO_HOST
;
1601 else if ( ADDRESSES_EQUAL(&(pinfo
->src
), &a_host
) &&
1602 ADDRESSES_EQUAL(&(pinfo
->dst
), &a_cam
) ) {
1603 return DVBCI_EVT_DATA_HOST_TO_CAM
;
1606 return DVBCI_EVT_INVALID_EVT
;
1610 /* this must be a function, not a macro,
1611 so that we can enforce the return type */
1612 static inline gint16
two_comp_to_int16(guint16 x
)
1614 return (x
&0x8000) ? -~(x
-1) : x
;
1618 /* initialize/reset per capture state data */
1625 reassembly_table_init(&tpdu_reassembly_table
,
1626 &addresses_reassembly_table_functions
);
1627 reassembly_table_init(&spdu_reassembly_table
,
1628 &addresses_reassembly_table_functions
);
1632 /* dissect a delivery system descriptor loop
1633 and the preceding length field
1634 (used for host control and operator profile)
1635 return the number of bytes dissected */
1637 dissect_desc_loop(int len_hf
,
1638 tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo _U_
, proto_tree
*tree
)
1641 guint16 desc_loop_len
;
1644 offset_start
= offset
;
1646 desc_loop_len
= tvb_get_ntohs(tvb
, offset
) & 0x0FFF;
1647 proto_tree_add_item(tree
, len_hf
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1649 while (offset
-offset_start
< 2+desc_loop_len
) {
1650 desc_len
= proto_mpeg_descriptor_dissect(tvb
, offset
, tree
);
1656 return offset
-offset_start
;
1660 /* dissect operator profile's status body, return its length */
1662 dissect_opp_status_body(tvbuff_t
*tvb
, gint offset
,
1663 packet_info
*pinfo _U_
, proto_tree
*tree
)
1667 offset_start
= offset
;
1668 proto_tree_add_item(tree
, hf_dvbci_info_ver_op_status
,
1669 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1670 proto_tree_add_item(tree
, hf_dvbci_nit_ver
,
1671 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1673 proto_tree_add_item(tree
, hf_dvbci_pro_typ
,
1674 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1675 proto_tree_add_item(tree
, hf_dvbci_init_flag
,
1676 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1677 proto_tree_add_item(tree
, hf_dvbci_ent_chg_flag
,
1678 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1679 proto_tree_add_item(tree
, hf_dvbci_ent_val_flag
,
1680 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1681 proto_tree_add_item(tree
, hf_dvbci_ref_req_flag
,
1682 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1684 proto_tree_add_item(tree
, hf_dvbci_err_flag
,
1685 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1686 proto_tree_add_bitmask(tree
, tvb
, offset
,
1687 hf_dvbci_dlv_sys_hint
, ett_dvbci_dlv_sys_hint
,
1688 dvbci_opp_dlv_sys_hint_fields
, ENC_BIG_ENDIAN
);
1690 proto_tree_add_item(tree
, hf_dvbci_refr_req_date
,
1691 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1693 proto_tree_add_item(tree
, hf_dvbci_refr_req_time
,
1694 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1697 return offset
-offset_start
;
1701 /* dissect a capability loop in an operator_search_start apdu */
1703 dissect_opp_cap_loop(guint8 cap_loop_len
, const gchar
*title
,
1704 int item_hf
, guint item_len
,
1705 tvbuff_t
*tvb
, gint offset
,
1706 packet_info
*pinfo _U_
, proto_tree
*tree
)
1708 proto_item
*ti
= NULL
;
1709 proto_tree
*loop_tree
= NULL
;
1714 if (item_len
==0 || cap_loop_len
%item_len
!= 0)
1717 if (tree
&& cap_loop_len
>0) {
1718 ti
= proto_tree_add_text(tree
, tvb
, offset
, cap_loop_len
, "%s", title
);
1719 loop_tree
= proto_item_add_subtree(ti
, ett_dvbci_opp_cap_loop
);
1721 for (i
=0; i
<cap_loop_len
; i
+=item_len
) {
1722 proto_tree_add_item(loop_tree
, item_hf
,
1723 tvb
, offset
+i
, item_len
, ENC_BIG_ENDIAN
);
1726 return cap_loop_len
;
1729 /* read a utc_time field in an apdu and write it to utc_time
1730 the encoding of the field is according to DVB-SI specification, section 5.2.5
1731 16bit modified julian day (MJD), 24bit 6*4bit BCD digits hhmmss
1732 return the length in bytes or -1 for error */
1734 read_utc_time(tvbuff_t
*tvb
, gint offset
, nstime_t
*utc_time
)
1736 gint bcd_time_offset
; /* start offset of the bcd time in the tvbuff */
1737 guint8 hour
, min
, sec
;
1742 nstime_set_zero(utc_time
);
1743 utc_time
->secs
= (tvb_get_ntohs(tvb
, offset
) - 40587) * 86400;
1744 bcd_time_offset
= offset
+2;
1745 hour
= BCD44_TO_DEC(tvb_get_guint8(tvb
, bcd_time_offset
));
1746 min
= BCD44_TO_DEC(tvb_get_guint8(tvb
, bcd_time_offset
+1));
1747 sec
= BCD44_TO_DEC(tvb_get_guint8(tvb
, bcd_time_offset
+2));
1748 if (hour
>23 || min
>59 || sec
>59)
1751 utc_time
->secs
+= hour
*3600 + min
*60 + sec
;
1756 /* dissect age rating byte encoded as defined in
1757 DVB-SI parental rating descriptor
1758 returns rating's length in bytes or -1 for error */
1760 dissect_rating(tvbuff_t
*tvb
, gint offset
,
1761 packet_info
*pinfo _U_
, proto_tree
*tree
)
1765 rating
= tvb_get_guint8(tvb
, offset
);
1766 if (1<=rating
&& rating
<=0x0F) {
1767 proto_tree_add_uint_format(tree
, hf_dvbci_rating
,
1768 tvb
, offset
, 1, rating
,
1769 "Rating is %d years (%d+3)", rating
+3, rating
);
1771 proto_tree_add_uint_format(tree
, hf_dvbci_rating
,
1772 tvb
, offset
, 1, rating
,
1773 "Rating is unknown/undefined (%d)", rating
);
1780 /* if there's a dissector for the protocol and target port of our
1781 lsc connection, store it in the lsc session's circuit */
1783 store_lsc_msg_dissector(circuit_t
*circuit
, guint8 ip_proto
, guint16 port
)
1785 dissector_handle_t msg_handle
= NULL
;
1790 if (ip_proto
==LSC_TCP
)
1791 msg_handle
= dissector_get_uint_handle(tcp_dissector_table
, port
);
1792 else if (ip_proto
==LSC_UDP
)
1793 msg_handle
= dissector_get_uint_handle(udp_dissector_table
, port
);
1795 circuit_set_dissector(circuit
, msg_handle
);
1799 /* dissect a connection_descriptor for the lsc resource
1800 returns its length or -1 for error */
1802 dissect_conn_desc(tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit
,
1803 packet_info
*pinfo
, proto_tree
*tree
)
1805 proto_item
*ti
= NULL
;
1806 proto_tree
*conn_desc_tree
= NULL
;
1808 gint offset_start
, offset_body
;
1810 guint8 conn_desc_type
;
1811 guint8 ip_ver
, ip_proto
;
1813 proto_item
*port_item
= NULL
;
1816 offset_start
= offset
;
1818 tag
= tvb_get_ntoh24(tvb
, offset
);
1819 if (tag
!= T_CONNECTION_DESCRIPTOR
)
1822 ti
= proto_tree_add_text(tree
, tvb
,
1823 offset_start
, -1, "Connection descriptor");
1824 conn_desc_tree
= proto_item_add_subtree(ti
, ett_dvbci_lsc_conn_desc
);
1826 proto_tree_add_item(conn_desc_tree
, hf_dvbci_apdu_tag
,
1827 tvb
, offset
, APDU_TAG_SIZE
, ENC_BIG_ENDIAN
);
1828 offset
+= APDU_TAG_SIZE
;
1829 offset
= dissect_ber_length(pinfo
, conn_desc_tree
,
1830 tvb
, offset
, &len_field
, NULL
);
1831 offset_body
= offset
;
1833 conn_desc_type
= tvb_get_guint8(tvb
, offset
);
1834 proto_tree_add_item(conn_desc_tree
, hf_dvbci_conn_desc_type
,
1835 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1838 if (conn_desc_type
== CONN_DESC_IP
) {
1839 proto_tree_add_item(conn_desc_tree
, hf_dvbci_lsc_media_tag
,
1840 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1842 proto_tree_add_item(conn_desc_tree
, hf_dvbci_lsc_media_len
,
1843 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1845 ip_ver
= tvb_get_guint8(tvb
, offset
);
1846 proto_tree_add_item(conn_desc_tree
, hf_dvbci_lsc_ip_ver
,
1847 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1850 if (ip_ver
== LSC_IPV4
) {
1851 offset
+= FT_IPv6_LEN
-FT_IPv4_LEN
;
1852 proto_tree_add_item(conn_desc_tree
, hf_dvbci_lsc_ipv4_addr
,
1853 tvb
, offset
, FT_IPv4_LEN
, ENC_BIG_ENDIAN
);
1854 offset
+= FT_IPv4_LEN
;
1856 else if (ip_ver
== LSC_IPV6
) {
1857 proto_tree_add_item(conn_desc_tree
, hf_dvbci_lsc_ipv6_addr
,
1858 tvb
, offset
, FT_IPv6_LEN
, ENC_NA
);
1859 offset
+= FT_IPv6_LEN
;
1862 offset
+= FT_IPv6_LEN
;
1864 port
= tvb_get_ntohs(tvb
, offset
);
1865 port_item
= proto_tree_add_item(conn_desc_tree
,
1866 hf_dvbci_lsc_dst_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1868 ip_proto
= tvb_get_guint8(tvb
, offset
);
1869 proto_tree_add_item(conn_desc_tree
, hf_dvbci_lsc_proto
,
1870 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1873 if (ip_proto
==LSC_TCP
&& get_tcp_port(port
)) {
1874 proto_item_append_text(port_item
, " (%s)",
1875 get_tcp_port(port
));
1877 else if (ip_proto
==LSC_UDP
&& get_udp_port(port
)) {
1878 proto_item_append_text(port_item
, " (%s)",
1879 get_udp_port(port
));
1882 store_lsc_msg_dissector(circuit
, ip_proto
, port
);
1884 } else if (conn_desc_type
== CONN_DESC_HOSTNAME
) {
1885 proto_tree_add_item(conn_desc_tree
, hf_dvbci_lsc_media_tag
,
1886 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1888 proto_tree_add_item(conn_desc_tree
, hf_dvbci_lsc_media_len
,
1889 tvb
, offset
, 1, 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
);
1895 port
= tvb_get_ntohs(tvb
, offset
);
1896 port_item
= proto_tree_add_item(conn_desc_tree
,
1897 hf_dvbci_lsc_dst_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1900 if (ip_proto
==LSC_TCP
&& get_tcp_port(port
)) {
1901 proto_item_append_text(port_item
, " (%s)",
1902 get_tcp_port(port
));
1904 else if (ip_proto
==LSC_UDP
&& get_udp_port(port
)) {
1905 proto_item_append_text(port_item
, " (%s)",
1906 get_udp_port(port
));
1909 store_lsc_msg_dissector(circuit
, ip_proto
, port
);
1911 /* everything from here to the descriptor's end is a hostname */
1912 hostname_len
= (offset_body
+len_field
)-offset
;
1913 proto_tree_add_item(conn_desc_tree
, hf_dvbci_lsc_hostname
,
1914 tvb
, offset
, hostname_len
, ENC_ASCII
|ENC_NA
);
1915 offset
+= hostname_len
;
1917 proto_tree_add_text(conn_desc_tree
, tvb
,
1918 offset
, len_field
-1, "media specific data");
1919 offset
+= len_field
-1;
1922 proto_item_set_len(ti
, offset
-offset_start
);
1923 return offset
-offset_start
;
1927 /* check if the given CC resource item may appear in the clear
1928 as part of an exported PDU */
1929 static inline gboolean
1930 is_cc_item_exportable(guint8 dat_id
)
1932 /* the CCK precursor value does not contain sensitive information as such
1933 nevertheless, it is safer to prevent people from exporting this value
1935 if (dat_id
== CC_ID_KP
)
1937 /* we could add some more items here which do not appear in SAC messages
1938 normally: CC_ID_DHPH, CC_ID_DHPM */
1944 /* dissect an item from cc_(sac_)data_req/cc_(sac_)data_cnf,
1945 returns its length or -1 for error
1946 if dat_id_ptr is not NULL, fill in the datatype id */
1948 dissect_cc_item(tvbuff_t
*tvb
, gint offset
,
1949 packet_info
*pinfo
, proto_tree
*tree
, guint8
*dat_id_ptr
)
1951 proto_item
*ti
= NULL
;
1952 proto_tree
*cc_item_tree
= NULL
;
1956 asn1_ctx_t asn1_ctx
;
1963 offset_start
= offset
;
1964 dat_id
= tvb_get_guint8(tvb
, offset
);
1966 *dat_id_ptr
= dat_id
;
1968 ti
= proto_tree_add_text(tree
, tvb
, offset_start
, -1, "CC data item: %s",
1969 val_to_str_const(dat_id
, dvbci_cc_dat_id
, "unknown"));
1970 cc_item_tree
= proto_item_add_subtree(ti
, ett_dvbci_cc_item
);
1972 proto_tree_add_item(cc_item_tree
, hf_dvbci_cc_dat_id
,
1973 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1975 dat_len
= tvb_get_ntohs(tvb
, offset
);
1976 proto_tree_add_text(cc_item_tree
, tvb
, offset
, 2, "Length: %d", dat_len
);
1979 case CC_ID_HOST_BRAND_CERT
:
1980 case CC_ID_CICAM_BRAND_CERT
:
1981 case CC_ID_HOST_DEV_CERT
:
1982 case CC_ID_CICAM_DEV_CERT
:
1983 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, TRUE
, pinfo
);
1984 hf_cert_index
= (dat_id
==CC_ID_HOST_BRAND_CERT
||
1985 dat_id
==CC_ID_CICAM_BRAND_CERT
) ?
1986 hf_dvbci_brand_cert
: hf_dvbci_dev_cert
;
1988 /* enable dissection of CI+ specific X.509 extensions
1989 only for our certificates */
1990 x509ce_enable_ciplus();
1991 dissect_x509af_Certificate(FALSE
, tvb
, offset
,
1992 &asn1_ctx
, cc_item_tree
, hf_cert_index
);
1993 x509ce_disable_ciplus();
1996 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
, "URI");
1997 proto_tree_add_item(cc_item_tree
, hf_dvbci_uri_ver
,
1998 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1999 proto_tree_add_item(cc_item_tree
, hf_dvbci_uri_aps
,
2000 tvb
, offset
+1, 1, ENC_BIG_ENDIAN
);
2001 emi
= (tvb_get_guint8(tvb
, offset
+1) & 0x30) >> 4;
2002 proto_tree_add_item(cc_item_tree
, hf_dvbci_uri_emi
,
2003 tvb
, offset
+1, 1, ENC_BIG_ENDIAN
);
2004 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
, "EMI 0x%x", emi
);
2005 proto_tree_add_item(cc_item_tree
, hf_dvbci_uri_ict
,
2006 tvb
, offset
+1, 1, ENC_BIG_ENDIAN
);
2008 proto_tree_add_item(cc_item_tree
, hf_dvbci_uri_rct
,
2009 tvb
, offset
+1, 1, ENC_BIG_ENDIAN
);
2011 /* digital only token and retention limit will be added */
2013 case CC_ID_PROG_NUM
:
2014 prog_num
= tvb_get_ntohs(tvb
, offset
);
2015 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
,
2016 "Program number 0x%x", prog_num
);
2017 proto_tree_add_item(cc_item_tree
, hf_dvbci_cc_prog_num
,
2018 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2020 case CC_ID_KEY_REGISTER
:
2021 proto_tree_add_item(cc_item_tree
, hf_dvbci_cc_key_register
,
2022 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2024 case CC_ID_STATUS_FIELD
:
2025 case CC_ID_REC_START_STATUS
:
2026 case CC_ID_MODE_CHG_STATUS
:
2027 case CC_ID_REC_STOP_STATUS
:
2028 status
= tvb_get_guint8(tvb
, offset
);
2029 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
, "Status: %s",
2030 val_to_str_const(status
, dvbci_cc_status
, "unknown"));
2031 proto_tree_add_item(cc_item_tree
, hf_dvbci_cc_status_field
,
2032 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2034 case CC_ID_OPERATING_MODE
:
2035 proto_tree_add_item(cc_item_tree
, hf_dvbci_cc_op_mode
,
2036 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2039 proto_tree_add_item(cc_item_tree
, hf_dvbci_cc_data
,
2040 tvb
, offset
, dat_len
, ENC_NA
);
2045 proto_item_set_len(ti
, offset
-offset_start
);
2046 return offset
-offset_start
;
2050 /* dissect the payload of a cc message that contains data items
2051 if not NULL, set exportable_flag to TRUE if the message contains no
2052 sensitive data and can be passed to the export PDU mechanism */
2054 dissect_cc_data_payload(guint32 tag
, tvbuff_t
*tvb
, gint offset
,
2055 packet_info
*pinfo
, proto_tree
*tree
, gboolean
*exportable_flag
)
2058 guint8 i
, snd_dat_nbr
, req_dat_nbr
;
2062 /* we only export cc_sac_data_req and cc_sac_data_cnf
2063 the only meta info in the exported PDU is the data transfer
2064 direction, if we only ever export cc_sac_data_req and
2065 cc_sac_data_cnf, this info is enough to recover the apdu tag from the
2067 cc_sac_sync req and cc_sac_sync_cnf contain no interesting data */
2068 if (exportable_flag
)
2069 *exportable_flag
= (tag
==T_CC_SAC_DATA_REQ
|| tag
==T_CC_SAC_DATA_CNF
);
2071 offset_start
= offset
;
2073 proto_tree_add_item(
2074 tree
, hf_dvbci_cc_sys_id_bitmask
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2076 snd_dat_nbr
= tvb_get_guint8(tvb
, offset
);
2077 proto_tree_add_text(tree
, tvb
, offset
, 1,
2078 "Number of sent data items: %d", snd_dat_nbr
);
2080 for(i
=0; i
<snd_dat_nbr
&&
2081 tvb_reported_length_remaining(tvb
, offset
)>0; i
++) {
2082 item_len
= dissect_cc_item(tvb
, offset
, pinfo
, tree
, &dat_id
);
2086 if (!exportable_flag
|| *exportable_flag
==FALSE
)
2088 if (!is_cc_item_exportable(dat_id
))
2089 *exportable_flag
= FALSE
;
2091 if (tag
==T_CC_DATA_REQ
|| tag
==T_CC_SAC_DATA_REQ
) {
2092 req_dat_nbr
= tvb_get_guint8(tvb
, offset
);
2093 proto_tree_add_text(tree
, tvb
, offset
, 1,
2094 "Number of requested data items: %d", req_dat_nbr
);
2096 for(i
=0; i
<req_dat_nbr
&&
2097 tvb_reported_length_remaining(tvb
, offset
)>0; i
++) {
2098 proto_tree_add_item(
2099 tree
, hf_dvbci_cc_dat_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2104 return offset
-offset_start
;
2108 #ifdef HAVE_LIBGCRYPT
2109 /* convert a 0-terminated preference key_string that contains a hex number
2110 * into its binary representation
2111 * e.g. key_string "abcd" will be converted into two bytes 0xab, 0xcd
2112 * return the number of binary bytes or -1 for error */
2114 pref_key_string_to_bin(const gchar
*key_string
, unsigned char **key_bin
)
2120 if (!key_string
|| !key_bin
)
2122 key_string_len
= (int)strlen(key_string
);
2123 if (key_string_len
!= 2*AES_KEY_LEN
)
2125 *key_bin
= (unsigned char*)g_malloc(key_string_len
/2);
2128 for (i
=0; i
<key_string_len
-1; i
+=2) {
2129 input
[0] = key_string
[0+i
];
2130 input
[1] = key_string
[1+i
];
2131 /* attention, brackets are required */
2132 (*key_bin
)[j
++] = (unsigned char)strtoul((const char*)&input
, NULL
, 16);
2135 return key_string_len
/2;
2140 decrypt_sac_msg_body(
2141 guint8 enc_cip
, tvbuff_t
*encrypted_tvb
, gint offset
, gint len
)
2144 gboolean opened
= FALSE
;
2145 gcry_cipher_hd_t cipher
;
2148 unsigned char *clear_data
= NULL
;
2149 tvbuff_t
*clear_tvb
= NULL
;
2150 unsigned char *sek
= NULL
, *siv
= NULL
;
2152 if (enc_cip
!= CC_SAC_ENC_AES128_CBC
)
2154 if (len
%AES_BLOCK_LEN
!= 0)
2157 ret
= pref_key_string_to_bin(dvbci_sek
, &sek
);
2160 ret
= pref_key_string_to_bin(dvbci_siv
, &siv
);
2164 err
= gcry_cipher_open(&cipher
, GCRY_CIPHER_AES
, GCRY_CIPHER_MODE_CBC
, 0);
2165 if (gcry_err_code (err
))
2168 err
= gcry_cipher_setkey (cipher
, sek
, AES_KEY_LEN
);
2169 if (gcry_err_code (err
))
2171 err
= gcry_cipher_setiv (cipher
, siv
, AES_BLOCK_LEN
);
2172 if (gcry_err_code (err
))
2176 clear_data
= (unsigned char *)g_malloc(clear_len
);
2178 err
= gcry_cipher_decrypt (cipher
, clear_data
, clear_len
,
2179 tvb_get_string(wmem_packet_scope(), encrypted_tvb
, offset
, len
), len
);
2180 if (gcry_err_code (err
))
2183 clear_tvb
= tvb_new_child_real_data(encrypted_tvb
,
2184 (const guint8
*)clear_data
, clear_len
, clear_len
);
2185 tvb_set_free_cb(clear_tvb
, g_free
);
2189 gcry_cipher_close (cipher
);
2194 if (!clear_tvb
&& clear_data
)
2200 /* HAVE_LIBGRYPT is not set */
2202 decrypt_sac_msg_body(guint8 enc_cip _U_
,
2203 tvbuff_t
*encrypted_tvb _U_
, gint offset _U_
, gint len _U_
)
2211 /* dissect a text string that is encoded according to DVB-SI (EN 300 468) */
2213 dissect_si_string(tvbuff_t
*tvb
, gint offset
, gint str_len
,
2214 packet_info
*pinfo
, proto_tree
*tree
, const gchar
*title
,
2215 gboolean show_col_info
)
2218 guint8
*si_str
= NULL
;
2220 if (!title
) /* we always have a title for our strings */
2222 /* str_len==-1 is not supported, we need an actual length */
2226 byte0
= tvb_get_guint8(tvb
, offset
);
2227 if (byte0
>=0x01 && byte0
<=0x0F) {
2228 proto_tree_add_item(tree
, hf_dvbci_char_tbl
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2232 else if (byte0
>=0x10 && byte0
<= 0x1F) {
2233 proto_tree_add_expert(tree
, pinfo
, &ei_dvbci_dvbci_char_tbl
, tvb
, offset
, 1);
2236 proto_tree_add_text(tree
, tvb
, offset
, str_len
, "encoded text");
2239 /* for now, control characters are supported only at the beginning
2240 * of a string (this should cover all cases found in practice) */
2241 else if (byte0
>=0x80 && byte0
<=0x9F) {
2242 proto_tree_add_item(tree
, hf_dvbci_text_ctrl
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2247 si_str
= tvb_get_string(wmem_packet_scope(), tvb
, offset
, str_len
);
2251 proto_tree_add_text(tree
, tvb
, offset
, str_len
, "%s: %s", title
, si_str
);
2253 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "%s", si_str
);
2257 /* dissect ca_enable_flag and ca_enable fields in the ca_pmt_reply
2258 * return true if descrambling is possible, false otherwise */
2260 dissect_ca_enable(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo _U_
,
2263 gboolean desc_ok
= FALSE
;
2264 guint8 byte
, ca_enab
;
2266 byte
= tvb_get_guint8(tvb
,offset
);
2267 proto_tree_add_item(tree
, hf_dvbci_ca_enable_flag
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2269 ca_enab
= byte
& ~0x80;
2270 proto_tree_add_item(tree
, hf_dvbci_ca_enable
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2271 if (ca_enab
==CA_ENAB_DESC_OK
||
2272 ca_enab
==CA_ENAB_DESC_OK_PURCHASE
||
2273 ca_enab
==CA_ENAB_DESC_OK_TECH
) {
2282 /* dissect a ca descriptor in the ca_pmt */
2284 dissect_ca_desc(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo
,
2288 guint8 tag
, len_byte
;
2289 proto_item
*ti
= NULL
;
2290 proto_tree
*ca_desc_tree
= NULL
;
2292 offset_start
= offset
;
2294 tag
= tvb_get_guint8(tvb
,offset
);
2295 if (tag
!= CA_DESC_TAG
) {
2296 /* we could skip unknown descriptors and make this a warning */
2297 proto_tree_add_expert(tree
, pinfo
, &ei_dvbci_ca_pmt_cmd_id
, tvb
, offset
, 1);
2301 ti
= proto_tree_add_text(
2302 tree
, tvb
, offset_start
, -1, "Conditional Access descriptor");
2303 ca_desc_tree
= proto_item_add_subtree(ti
, ett_dvbci_ca_desc
);
2306 len_byte
= tvb_get_guint8(tvb
,offset
);
2307 proto_tree_add_item(
2308 ca_desc_tree
, hf_dvbci_descr_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2311 proto_tree_add_item(
2312 ca_desc_tree
, hf_dvbci_ca_sys_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2315 proto_tree_add_item(
2316 ca_desc_tree
, hf_dvbci_ca_pid
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2319 if ((len_byte
-4) != 0) {
2320 proto_tree_add_text(
2321 ca_desc_tree
, tvb
, offset
, len_byte
-4, "private data");
2322 offset
+= (len_byte
-4);
2325 proto_item_set_len(ti
, offset
-offset_start
);
2326 return offset
-offset_start
;
2330 /* dissect an elementary stream entry in the ca_pmt */
2332 dissect_es(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo
, proto_tree
*tree
)
2334 proto_item
*ti
= NULL
;
2335 proto_tree
*es_tree
= NULL
;
2336 gint offset_start
, ca_desc_len
;
2337 gint es_info_len
, all_len
;
2339 offset_start
= offset
;
2341 ti
= proto_tree_add_text(tree
, tvb
, offset_start
, -1, "Elementary Stream");
2342 es_tree
= proto_item_add_subtree(ti
, ett_dvbci_application
);
2344 proto_tree_add_item(
2345 es_tree
, hf_dvbci_stream_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2347 proto_tree_add_item(
2348 es_tree
, hf_dvbci_es_pid
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2350 es_info_len
= tvb_get_ntohs(tvb
, offset
) & 0x0FFF;
2351 /* the definition of hf_dvbci_es_info_len also applies the mask */
2352 proto_tree_add_item(
2353 es_tree
, hf_dvbci_es_info_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2355 if (es_info_len
!= 0) {
2356 all_len
= offset
+ es_info_len
;
2358 proto_tree_add_item(
2359 es_tree
, hf_dvbci_ca_pmt_cmd_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2361 while (offset
< all_len
) {
2362 ca_desc_len
= dissect_ca_desc(tvb
, offset
, pinfo
, es_tree
);
2363 if (ca_desc_len
<= 0)
2365 offset
+= ca_desc_len
;
2369 proto_tree_add_text(
2371 "No CA descriptors for this elementary stream");
2374 proto_item_set_len(ti
, offset
-offset_start
);
2375 return offset
-offset_start
;
2378 /* dissect a text pseudo-apdu */
2380 dissect_dvbci_text(const gchar
*title
, tvbuff_t
*tvb
, gint offset
,
2381 packet_info
*pinfo
, proto_tree
*tree
)
2383 proto_item
*ti
= NULL
;
2384 proto_tree
*text_tree
;
2389 offset_start
= offset
;
2394 /* check the tag before setting up the tree */
2395 tag
= tvb_get_ntoh24(tvb
, offset
);
2396 if (tag
!=T_TEXT_LAST
&& tag
!=T_TEXT_MORE
)
2399 ti
= proto_tree_add_text(tree
, tvb
, offset_start
, -1, "%s", title
);
2400 text_tree
= proto_item_add_subtree(ti
, ett_dvbci_text
);
2402 proto_tree_add_item(text_tree
, hf_dvbci_apdu_tag
,
2403 tvb
, offset
, APDU_TAG_SIZE
, ENC_BIG_ENDIAN
);
2404 offset
+= APDU_TAG_SIZE
;
2405 offset
= dissect_ber_length(pinfo
, text_tree
, tvb
, offset
, &len_field
, NULL
);
2406 dissect_si_string(tvb
, offset
, len_field
, pinfo
, text_tree
, "Text", FALSE
);
2407 offset
+= len_field
;
2409 proto_item_set_len(ti
, offset
-offset_start
);
2410 return (offset
-offset_start
);
2415 dissect_res_id(tvbuff_t
*tvb
, gint offset
, packet_info
*pinfo
,
2416 proto_tree
*tree
, guint32 res_id
, gboolean show_col_info
)
2418 proto_item
*ti
= NULL
;
2419 proto_tree
*res_tree
= NULL
;
2422 /* there's two possible inputs for this function
2423 the resource id is either in a tvbuff_t (tvb!=NULL, res_id==0)
2424 or in a guint32 (tvb==NULL, res_id!=0) */
2427 /* resource id comes in via tvbuff */
2430 res_id
= tvb_get_ntohl(tvb
, offset
);
2431 tvb_data_len
= RES_ID_LEN
;
2434 /* resource id comes in via guint32 */
2437 /* we'll call proto_tree_add_...( tvb==NULL, offset==0, length==0 )
2438 this creates a filterable item without any reference to a tvb */
2443 if (show_col_info
) {
2444 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
, "%s Version %d",
2445 val_to_str_const(RES_CLASS(res_id
), dvbci_res_class
,
2446 "Invalid Resource class"),
2450 ti
= proto_tree_add_text(tree
, tvb
, offset
, tvb_data_len
,
2451 "Resource ID: 0x%04x", res_id
);
2452 res_tree
= proto_item_add_subtree(ti
, ett_dvbci_res
);
2454 /* parameter "value" == complete resource id,
2455 RES_..._MASK will be applied by the hf definition */
2456 proto_tree_add_uint(res_tree
, hf_dvbci_res_id_type
,
2457 tvb
, offset
, tvb_data_len
, res_id
);
2458 proto_tree_add_uint(res_tree
, hf_dvbci_res_class
,
2459 tvb
, offset
, tvb_data_len
, res_id
);
2460 proto_tree_add_uint(res_tree
, hf_dvbci_res_type
,
2461 tvb
, offset
, tvb_data_len
, res_id
);
2462 proto_tree_add_uint(res_tree
, hf_dvbci_res_ver
,
2463 tvb
, offset
, tvb_data_len
, res_id
);
2468 /* dissect the body of a resource manager apdu */
2470 dissect_dvbci_payload_rm(guint32 tag
, gint len_field
,
2471 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
2472 packet_info
*pinfo
, proto_tree
*tree
)
2474 const gchar
*tag_str
;
2476 if (tag
==T_PROFILE
) {
2477 if (len_field
% RES_ID_LEN
) {
2478 tag_str
= val_to_str(tag
, dvbci_apdu_tag
, "Unknown: %d");
2479 proto_tree_add_expert_format(tree
, pinfo
, &ei_dvbci_bad_length
, tvb
, 0, APDU_TAG_SIZE
,
2480 "Invalid APDU length field, %s must be a multiple of 4 bytes",
2485 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
2486 dissect_res_id(tvb
, offset
, pinfo
, tree
, 0, FALSE
);
2487 offset
+= RES_ID_LEN
;
2493 dissect_dvbci_payload_ap(guint32 tag
, gint len_field _U_
,
2494 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
2495 packet_info
*pinfo
, proto_tree
*tree
)
2497 guint8 menu_str_len
;
2498 guint8
*menu_string
;
2501 if (tag
==T_APP_INFO
) {
2502 proto_tree_add_item(tree
, hf_dvbci_app_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2504 proto_tree_add_item(
2505 tree
, hf_dvbci_app_manf
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2507 proto_tree_add_item(
2508 tree
, hf_dvbci_manf_code
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2510 menu_str_len
= tvb_get_guint8(tvb
,offset
);
2511 proto_tree_add_item(
2512 tree
, hf_dvbci_menu_str_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2514 /* ephemeral -> string is freed automatically when dissection
2515 of this packet is finished
2516 tvb_get_string() always returns a 0-terminated string */
2517 menu_string
= tvb_get_string(wmem_packet_scope(), tvb
, offset
, menu_str_len
);
2519 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
,
2520 "Module name %s", menu_string
);
2521 proto_tree_add_text(tree
, tvb
, offset
, menu_str_len
,
2522 "Menu string: %s", menu_string
);
2525 else if (tag
== T_DATARATE_INFO
) {
2526 data_rate
= tvb_get_guint8(tvb
, offset
);
2527 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ", "%s",
2528 val_to_str(data_rate
, dvbci_data_rate
, "unknown (0x%x)"));
2529 proto_tree_add_item(tree
, hf_dvbci_data_rate
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2534 dissect_dvbci_payload_ca(guint32 tag
, gint len_field
,
2535 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
2536 packet_info
*pinfo
, proto_tree
*tree
)
2538 const gchar
*tag_str
;
2542 guint prog_info_len
;
2543 gint es_info_len
, all_len
;
2545 proto_tree
*es_tree
= NULL
;
2546 gboolean desc_ok
= FALSE
;
2549 if (tag
==T_CA_INFO
) {
2550 if (len_field
% 2) {
2551 tag_str
= val_to_str(tag
, dvbci_apdu_tag
, "Unknown: %d");
2552 proto_tree_add_expert_format(tree
, pinfo
, &ei_dvbci_bad_length
, tvb
, 0, APDU_TAG_SIZE
,
2553 "Invalid APDU length field, %s must be a multiple of 2 bytes",
2558 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
2559 proto_tree_add_item(
2560 tree
, hf_dvbci_ca_sys_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2564 else if (tag
==T_CA_PMT
) {
2565 proto_tree_add_item(
2566 tree
, hf_dvbci_ca_pmt_list_mgmt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2568 prog_num
= tvb_get_ntohs(tvb
, offset
);
2569 col_append_sep_fstr(
2570 pinfo
->cinfo
, COL_INFO
, NULL
, "Program number %x", prog_num
);
2571 proto_tree_add_item(
2572 tree
, hf_dvbci_prog_num
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2574 byte
= tvb_get_guint8(tvb
,offset
);
2575 proto_tree_add_text(tree
, tvb
, offset
, 1,
2576 "Version number: 0x%x, Current-next indicator: 0x%x",
2577 (byte
&0x3E) >> 1, byte
&0x01);
2579 prog_info_len
= tvb_get_ntohs(tvb
, offset
) & 0x0FFF;
2580 /* the definition of hf_dvbci_prog_info_len also applies the mask */
2581 proto_tree_add_item(
2582 tree
, hf_dvbci_prog_info_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2584 if (prog_info_len
!= 0) {
2585 all_len
= offset
+ prog_info_len
;
2587 proto_tree_add_item(
2588 tree
, hf_dvbci_ca_pmt_cmd_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2590 while (offset
< all_len
) {
2591 ca_desc_len
= dissect_ca_desc(tvb
, offset
, pinfo
, tree
);
2592 if (ca_desc_len
<= 0)
2594 offset
+= ca_desc_len
;
2598 proto_tree_add_text(
2599 tree
, tvb
, 0, 0, "No CA descriptors at program level");
2602 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
2603 es_info_len
= dissect_es(tvb
, offset
, pinfo
, tree
);
2604 if (es_info_len
<= 0)
2606 offset
+= es_info_len
;
2609 else if (tag
==T_CA_PMT_REPLY
) {
2610 prog_num
= tvb_get_ntohs(tvb
, offset
);
2611 col_append_sep_fstr(
2612 pinfo
->cinfo
, COL_INFO
, NULL
, "Program number %x", prog_num
);
2613 proto_tree_add_item(
2614 tree
, hf_dvbci_prog_num
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2616 byte
= tvb_get_guint8(tvb
,offset
);
2617 proto_tree_add_text(tree
, tvb
, offset
, 1,
2618 "Version number: 0x%x, Current-next indicator: 0x%x",
2619 (byte
&0x3E) >> 1, byte
&0x01);
2621 desc_ok
|= dissect_ca_enable(tvb
, offset
, pinfo
, tree
);
2623 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
2624 /* there's no need to check for tree==NULL */
2625 pi
= proto_tree_add_text(tree
, tvb
, offset
, 3, "Elementary Stream");
2626 es_tree
= proto_item_add_subtree(pi
, ett_dvbci_application
);
2628 proto_tree_add_item(es_tree
, hf_dvbci_es_pid
,
2629 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2631 desc_ok
|= dissect_ca_enable(tvb
, offset
, pinfo
, es_tree
);
2635 col_append_sep_fstr(
2636 pinfo
->cinfo
, COL_INFO
, NULL
, "descrambling possible");
2643 dissect_dvbci_payload_aut(guint32 tag
, gint len_field _U_
,
2644 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
2645 packet_info
*pinfo _U_
, proto_tree
*tree
)
2649 proto_tree_add_item(tree
, hf_dvbci_auth_proto_id
,
2650 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2653 bytes_len
= tvb_reported_length_remaining(tvb
, offset
);
2657 if (tag
==T_AUTH_REQ
) {
2658 proto_tree_add_item(tree
, hf_dvbci_auth_req_bytes
,
2659 tvb
, offset
, bytes_len
, ENC_NA
);
2661 else if (tag
==T_AUTH_RESP
) {
2662 proto_tree_add_item(tree
, hf_dvbci_auth_resp_bytes
,
2663 tvb
, offset
, bytes_len
, ENC_NA
);
2669 dissect_dvbci_payload_hc(guint32 tag
, gint len_field _U_
,
2670 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
2671 packet_info
*pinfo
, proto_tree
*tree
)
2674 guint16 nid
, onid
, tsid
, svcid
;
2676 guint16 old_pid
, new_pid
;
2679 tvbuff_t
*pmt_tvb
= NULL
;
2685 nid
= tvb_get_ntohs(tvb
, offset
);
2686 pi
= proto_tree_add_item(
2687 tree
, hf_dvbci_network_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2689 expert_add_info(pinfo
, pi
, &ei_dvbci_network_id
);
2692 onid
= tvb_get_ntohs(tvb
, offset
);
2693 proto_tree_add_item(tree
, hf_dvbci_original_network_id
,
2694 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2696 tsid
= tvb_get_ntohs(tvb
, offset
);
2697 proto_tree_add_item(tree
, hf_dvbci_transport_stream_id
,
2698 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2700 svcid
= tvb_get_ntohs(tvb
, offset
);
2701 proto_tree_add_item(
2702 tree
, hf_dvbci_service_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2703 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ",
2704 "nid 0x%x, onid 0x%x, tsid 0x%x, svcid 0x%x",
2705 nid
, onid
, tsid
, svcid
);
2708 ref
= tvb_get_guint8(tvb
, offset
);
2709 proto_tree_add_item(tree
, hf_dvbci_replacement_ref
,
2710 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2712 old_pid
= tvb_get_ntohs(tvb
, offset
) & 0x1FFF;
2713 proto_tree_add_item(tree
, hf_dvbci_replaced_pid
,
2714 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2716 new_pid
= tvb_get_ntohs(tvb
, offset
) & 0x1FFF;
2717 proto_tree_add_item( tree
, hf_dvbci_replacement_pid
,
2718 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2719 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ",
2720 "ref 0x%x, 0x%x -> 0x%x", ref
, old_pid
, new_pid
);
2722 case T_CLEAR_REPLACE
:
2723 ref
= tvb_get_guint8(tvb
, offset
);
2724 proto_tree_add_item(tree
, hf_dvbci_replacement_ref
,
2725 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2726 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ", "ref 0x%x", ref
);
2728 case T_TUNE_BROADCAST_REQ
:
2729 pmt_flag
= ((tvb_get_guint8(tvb
, offset
) & 0x01) == 0x01);
2730 proto_tree_add_item(tree
, hf_dvbci_pmt_flag
,
2731 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2733 proto_tree_add_item(
2734 tree
, hf_dvbci_service_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2736 desc_loop_len
= dissect_desc_loop(hf_dvbci_hc_desc_loop_len
,
2737 tvb
, offset
, pinfo
, tree
);
2738 if (desc_loop_len
<0)
2740 offset
+= desc_loop_len
;
2742 pmt_tvb
= tvb_new_subset_remaining(tvb
, offset
);
2743 if (mpeg_pmt_handle
) {
2744 col_append_str(pinfo
->cinfo
, COL_INFO
, ", ");
2745 /* prevent mpeg_pmt dissector from clearing col_info */
2746 col_set_fence(pinfo
->cinfo
, COL_INFO
);
2747 call_dissector(mpeg_pmt_handle
, pmt_tvb
, pinfo
, tree
);
2750 call_dissector(data_handle
, pmt_tvb
, pinfo
, tree
);
2754 status
= tvb_get_guint8(tvb
, offset
);
2755 proto_tree_add_item(tree
, hf_dvbci_hc_status
,
2756 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2757 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ",
2758 (status
== HC_STAT_OK
? "ok" : "error"));
2760 case T_ASK_RELEASE_REPLY
:
2761 proto_tree_add_item(tree
, hf_dvbci_hc_release_reply
,
2762 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2771 dissect_dvbci_payload_dt(guint32 tag
, gint len_field
,
2772 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
2773 packet_info
*pinfo
, proto_tree
*tree
)
2776 proto_item
*pi
= NULL
;
2777 const gchar
*tag_str
;
2778 gint time_field_len
;
2780 gint16 local_offset
; /* field in the apdu */
2783 if (tag
==T_DATE_TIME_ENQ
) {
2784 nstime_set_zero(&resp_intv
);
2785 resp_intv
.secs
= tvb_get_guint8(tvb
, offset
);
2786 pi
= proto_tree_add_time(tree
, hf_dvbci_resp_intv
,
2787 tvb
, offset
, 1, &resp_intv
);
2788 if (resp_intv
.secs
==0) {
2789 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
, "individual query");
2791 proto_item_append_text(pi
, " (individual query)");
2794 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
,
2795 "update every %s", rel_time_to_str(&resp_intv
));
2798 else if (tag
==T_DATE_TIME
) {
2799 if (len_field
!=5 && len_field
!=7) {
2800 tag_str
= val_to_str_const(tag
, dvbci_apdu_tag
, "unknown");
2801 proto_tree_add_expert_format(tree
, pinfo
, &ei_dvbci_bad_length
, tvb
, APDU_TAG_SIZE
, offset
-APDU_TAG_SIZE
,
2802 "Invalid APDU length field, %s must be 5 or 7 bytes", tag_str
);
2806 time_field_len
= read_utc_time(tvb
, offset
, &utc_time
);
2807 if (time_field_len
<0) {
2808 proto_tree_add_expert_format(tree
, pinfo
, &ei_dvbci_bad_length
, tvb
, offset
, 5,
2809 "Invalid UTC time field, 2 bytes MJD, 3 bytes BCD time hhmmss");
2812 proto_tree_add_time(tree
, hf_dvbci_utc_time
,
2813 tvb
, offset
, time_field_len
, &utc_time
);
2814 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ", "%s UTC",
2815 abs_time_to_str(&utc_time
, ABSOLUTE_TIME_UTC
, FALSE
));
2816 offset
+= time_field_len
;
2819 local_offset
= two_comp_to_int16(tvb_get_ntohs(tvb
, offset
));
2820 proto_tree_add_int_format(tree
, hf_dvbci_local_offset
,
2821 tvb
, offset
, 2, local_offset
,
2822 "offset between UTC and local time is %d minutes",
2826 proto_tree_add_text(tree
, tvb
, 0, 0,
2827 "Offset between UTC and local time is unknown");
2834 dissect_dvbci_payload_mmi(guint32 tag
, gint len_field
,
2835 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
2836 packet_info
*pinfo
, proto_tree
*tree
)
2839 guint8 close_mmi_cmd_id
;
2840 guint8 disp_ctl_cmd
, disp_rep_id
;
2841 const gchar
*disp_ctl_cmd_str
= NULL
, *disp_rep_id_str
= NULL
;
2844 guint8 choice_or_item_nb
;
2849 offset_start
= offset
;
2853 close_mmi_cmd_id
= tvb_get_guint8(tvb
,offset
);
2854 proto_tree_add_item(tree
, hf_dvbci_close_mmi_cmd_id
,
2855 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2857 /* apdu layer len field checks are sufficient for "immediate" */
2858 if (close_mmi_cmd_id
== CLOSE_MMI_CMD_ID_DELAY
) {
2859 if (len_field
!= 2) {
2860 proto_tree_add_expert_format(tree
, pinfo
, &ei_dvbci_bad_length
, tvb
,
2861 APDU_TAG_SIZE
, offset_start
-APDU_TAG_SIZE
,
2862 "Length field must be 2");
2865 proto_tree_add_item(tree
, hf_dvbci_close_mmi_delay
, tvb
,
2866 offset
, 1, ENC_BIG_ENDIAN
);
2869 case T_DISPLAY_CONTROL
:
2870 disp_ctl_cmd
= tvb_get_guint8(tvb
,offset
);
2871 disp_ctl_cmd_str
= val_to_str_const(disp_ctl_cmd
,
2872 dvbci_disp_ctl_cmd
, "unknown command");
2873 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ",
2874 "%s", disp_ctl_cmd_str
);
2875 proto_tree_add_item(tree
, hf_dvbci_disp_ctl_cmd
, tvb
,
2876 offset
, 1, ENC_BIG_ENDIAN
);
2878 if (disp_ctl_cmd
== DISP_CMD_SET_MMI_MODE
)
2880 proto_tree_add_item(tree
, hf_dvbci_mmi_mode
, tvb
,
2881 offset
, 1, ENC_BIG_ENDIAN
);
2882 if (len_field
!= 2) {
2883 proto_tree_add_expert_format(tree
, pinfo
, &ei_dvbci_bad_length
, tvb
,
2884 APDU_TAG_SIZE
, offset_start
-APDU_TAG_SIZE
,
2885 "Length field must be 2");
2890 case T_DISPLAY_REPLY
:
2891 disp_rep_id
= tvb_get_guint8(tvb
,offset
);
2892 disp_rep_id_str
= val_to_str_const(disp_rep_id
,
2893 dvbci_disp_rep_id
, "unknown command");
2894 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ",
2895 "%s", disp_rep_id_str
);
2896 proto_tree_add_item(tree
, hf_dvbci_disp_rep_id
,
2897 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2899 if (disp_rep_id
== DISP_REP_ID_MMI_MODE_ACK
) {
2900 proto_tree_add_item(tree
, hf_dvbci_mmi_mode
,
2901 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2903 else if (disp_rep_id
== DISP_REP_ID_DISP_CHAR_TBL
||
2904 disp_rep_id
== DISP_REP_ID_INP_CHAR_TBL
) {
2905 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
2906 proto_tree_add_item(tree
, hf_dvbci_char_tbl
,
2907 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2913 proto_tree_add_item(tree
, hf_dvbci_blind_ans
,
2914 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2916 ans_txt_len
= tvb_get_guint8(tvb
,offset
);
2917 if (ans_txt_len
== NB_UNKNOWN
) {
2918 proto_tree_add_text(tree
, tvb
, offset
, 1,
2919 "Length of expected answer is unknown");
2922 proto_tree_add_item(tree
, hf_dvbci_ans_txt_len
,
2923 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2925 dissect_si_string(tvb
, offset
,
2926 tvb_reported_length_remaining(tvb
, offset
),
2927 pinfo
, tree
, "Enquiry string", FALSE
);
2930 ans_id
= tvb_get_guint8(tvb
,offset
);
2931 proto_tree_add_item(tree
, hf_dvbci_ans_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2933 if (ans_id
== ANSW_ID_ANSWER
) {
2934 dissect_si_string(tvb
, offset
,
2935 tvb_reported_length_remaining(tvb
, offset
),
2936 pinfo
, tree
, "Answer", TRUE
);
2943 choice_or_item_nb
= tvb_get_guint8(tvb
,offset
);
2944 if (choice_or_item_nb
== NB_UNKNOWN
)
2946 proto_tree_add_text(tree
, tvb
, offset
, 1,
2947 "Number of items is unknown");
2951 if (IS_MENU_APDU(tag
)) {
2952 proto_tree_add_item(
2953 tree
, hf_dvbci_choice_nb
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2956 proto_tree_add_item(
2957 tree
, hf_dvbci_item_nb
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2961 text_len
= dissect_dvbci_text("Title", tvb
, offset
, pinfo
, tree
);
2963 text_len
= dissect_dvbci_text("Sub-title", tvb
, offset
, pinfo
, tree
);
2965 text_len
= dissect_dvbci_text("Bottom line", tvb
, offset
, pinfo
, tree
);
2967 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
2968 text_len
= dissect_dvbci_text("Item", tvb
, offset
, pinfo
, tree
);
2969 /* minimum is apdu tag + 1 byte len field */
2970 if (text_len
<APDU_TAG_SIZE
+1) {
2971 proto_tree_add_expert(tree
, pinfo
, &ei_dvbci_not_text_more_or_text_last
, tvb
, offset
, -1);
2978 choice_ref
= tvb_get_guint8(tvb
,offset
);
2979 if (choice_ref
== 0x0) {
2980 proto_tree_add_text(tree
, tvb
, offset
, 1,
2981 "Selection was cancelled.");
2982 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ",
2986 proto_tree_add_item(
2987 tree
, hf_dvbci_choice_ref
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2988 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ",
2989 "Item %d", choice_ref
);
2999 dissect_dvbci_payload_hlc(guint32 tag
, gint len_field _U_
,
3000 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
3001 packet_info
*pinfo
, proto_tree
*tree
)
3005 if (tag
==T_HOST_COUNTRY
) {
3006 proto_tree_add_item(tree
, hf_dvbci_host_country
,
3007 tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
), ENC_ASCII
|ENC_NA
);
3009 else if (tag
==T_HOST_LANGUAGE
) {
3010 proto_tree_add_item(tree
, hf_dvbci_host_language
,
3011 tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
), ENC_ASCII
|ENC_NA
);
3014 /* both apdus' body is only a country code, this can be shared */
3015 str
= tvb_get_string(wmem_packet_scope(), tvb
, offset
,
3016 tvb_reported_length_remaining(tvb
, offset
));
3018 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ", "%s", str
);
3023 dissect_dvbci_payload_cup(guint32 tag
, gint len_field _U_
,
3024 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
3025 packet_info
*pinfo
, proto_tree
*tree
)
3027 guint8 upgrade_type
;
3028 guint16 download_time
;
3029 guint8 answer
, progress
;
3032 case T_CAM_FIRMWARE_UPGRADE
:
3033 upgrade_type
= tvb_get_guint8(tvb
, offset
);
3034 proto_tree_add_item(tree
, hf_dvbci_cup_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3035 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "(%s)",
3036 val_to_str_const(upgrade_type
, dvbci_cup_type
, "unknown"));
3038 download_time
= tvb_get_ntohs(tvb
, offset
);
3039 if (download_time
== 0) {
3040 proto_tree_add_uint_format(tree
, hf_dvbci_cup_download_time
,
3041 tvb
, offset
, 2, download_time
,
3042 "estimated download time is unknown");
3045 proto_tree_add_uint_format(tree
, hf_dvbci_cup_download_time
,
3046 tvb
, offset
, 2, download_time
,
3047 "estimated download time is %d seconds",
3051 case T_CAM_FIRMWARE_UPGRADE_REPLY
:
3052 answer
= tvb_get_guint8(tvb
, offset
);
3053 proto_tree_add_item(tree
, hf_dvbci_cup_answer
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3054 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ", "%s",
3055 val_to_str_const(answer
, dvbci_cup_answer
, "unknown"));
3057 case T_CAM_FIRMWARE_UPGRADE_PROGRESS
:
3058 progress
= tvb_get_guint8(tvb
, offset
);
3059 if (progress
> 100) {
3060 proto_tree_add_expert(tree
, pinfo
, &ei_dvbci_cup_progress
, tvb
, offset
, 1);
3063 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ", "%d%%", progress
);
3064 proto_tree_add_uint_format(tree
, hf_dvbci_cup_progress
,
3065 tvb
, offset
, 1, progress
,
3066 "download progress %d%%", progress
);
3069 case T_CAM_FIRMWARE_UPGRADE_COMPLETE
:
3070 proto_tree_add_item(tree
, hf_dvbci_cup_reset
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3079 dissect_sac_msg(guint32 tag
, tvbuff_t
*tvb
, gint offset
,
3080 packet_info
*pinfo
, proto_tree
*tree
, gboolean exported
)
3084 guint8 enc_flag
, enc_cip
;
3085 proto_item
*enc_flag_pi
, *ti
;
3086 guint16 sac_payload_len
; /* payload data and padding */
3087 gint sac_payload_data_len
= 0; /* just payload data */
3088 tvbuff_t
*clear_sac_body_tvb
;
3089 proto_tree
*sac_tree
= NULL
;
3090 gboolean is_exportable
= FALSE
;
3092 offset_start
= offset
;
3094 /* it's not useful to move sac header dissection to a separate
3095 function, we need enc/auth cipher etc here to handle the body */
3096 msg_ctr
= tvb_get_ntohl(tvb
, offset
);
3097 proto_tree_add_item(tree
, hf_dvbci_sac_msg_ctr
,
3098 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3099 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
,
3100 "message #%d", msg_ctr
);
3102 proto_tree_add_item(tree
, hf_dvbci_sac_proto_ver
,
3103 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3104 proto_tree_add_item(tree
, hf_dvbci_sac_auth_cip
,
3105 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3106 enc_flag
= tvb_get_guint8(tvb
, offset
) & 0x1;
3107 enc_flag_pi
= proto_tree_add_item(tree
, hf_dvbci_sac_payload_enc
,
3108 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3109 if (exported
&& enc_flag
) {
3110 expert_add_info(pinfo
, enc_flag_pi
, &ei_dvbci_sac_payload_enc
);
3114 enc_cip
= (tvb_get_guint8(tvb
, offset
)&0xE0) >> 5;
3115 proto_tree_add_item(tree
, hf_dvbci_sac_enc_cip
,
3116 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3118 sac_payload_len
= tvb_get_ntohs(tvb
, offset
);
3119 proto_tree_add_item(tree
, hf_dvbci_sac_payload_len
,
3120 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3122 if (tvb_reported_length_remaining(tvb
, offset
) < 0)
3125 clear_sac_body_tvb
= decrypt_sac_msg_body(enc_cip
,
3126 tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
));
3129 clear_sac_body_tvb
= tvb_new_subset_remaining(tvb
, offset
);
3131 if (!clear_sac_body_tvb
) {
3132 /* we could not decrypt (or access) the clear sac message body */
3133 proto_tree_add_item(tree
, hf_dvbci_sac_enc_body
, tvb
, offset
,
3134 tvb_reported_length_remaining(tvb
, offset
), ENC_NA
);
3138 add_new_data_source(pinfo
, clear_sac_body_tvb
, "Clear SAC message body");
3139 if (sac_payload_len
>0) {
3140 ti
= proto_tree_add_text(tree
, clear_sac_body_tvb
, 0, sac_payload_len
,
3141 "SAC message payload");
3142 sac_tree
= proto_item_add_subtree(ti
, ett_dvbci_sac_msg_body
);
3143 if (tag
==T_CC_SAC_DATA_REQ
|| tag
==T_CC_SAC_DATA_CNF
) {
3144 sac_payload_data_len
= dissect_cc_data_payload(tag
,
3145 clear_sac_body_tvb
, 0, pinfo
, sac_tree
, &is_exportable
);
3147 else if (tag
==T_CC_SAC_SYNC_REQ
) {
3148 sac_payload_data_len
= 0;
3150 else if (tag
==T_CC_SAC_SYNC_CNF
) {
3151 proto_tree_add_item(sac_tree
, hf_dvbci_cc_status_field
,
3152 clear_sac_body_tvb
, 0, 1, ENC_BIG_ENDIAN
);
3153 sac_payload_data_len
= 1;
3156 if (sac_payload_data_len
< 0)
3158 if (sac_payload_len
> sac_payload_data_len
) {
3159 proto_tree_add_text(sac_tree
, clear_sac_body_tvb
,
3160 sac_payload_data_len
,
3161 sac_payload_len
-sac_payload_data_len
,
3165 proto_tree_add_item(tree
, hf_dvbci_sac_signature
,
3166 clear_sac_body_tvb
, sac_payload_len
,
3167 tvb_reported_length_remaining(clear_sac_body_tvb
,
3168 sac_payload_len
), ENC_NA
);
3170 /* we call this function also to dissect exported SAC messages,
3171 dont' try to export them a second time */
3172 if (!exported
&& is_exportable
&& have_tap_listener(exported_pdu_tap
)) {
3174 tvbuff_t
*clear_sac_msg_tvb
;
3175 exp_pdu_data_t
*exp_pdu_data
;
3177 clear_sac_msg_tvb
= tvb_new_composite();
3178 tvb_composite_append(clear_sac_msg_tvb
,
3179 tvb_clone_offset_len(tvb
, offset_start
, SAC_MSG_HDR_LEN
));
3180 tvb_composite_append(clear_sac_msg_tvb
, clear_sac_body_tvb
);
3181 tvb_composite_finalize(clear_sac_msg_tvb
);
3183 exp_pdu_data
= load_export_pdu_tags(
3184 pinfo
, EXPORTED_SAC_MSG_PROTO
, -1, EXP_PDU_TAG_DVBCI_EVT_BIT
);
3186 exp_pdu_data
->tvb_length
= tvb_length(clear_sac_msg_tvb
);
3187 exp_pdu_data
->pdu_tvb
= clear_sac_msg_tvb
;
3188 tap_queue_packet(exported_pdu_tap
, pinfo
, exp_pdu_data
);
3194 dissect_dvbci_exported_sac_msg(
3195 tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
3200 evt
= dvbci_get_evt_from_addrs(pinfo
);
3201 if (!IS_DATA_TRANSFER(evt
))
3204 col_append_sep_fstr(pinfo
->cinfo
, COL_PROTOCOL
, NULL
, EXPORTED_SAC_MSG_PROTO
);
3205 col_clear(pinfo
->cinfo
, COL_INFO
);
3207 /* we only export cc_sac_data_req and _cnf, therefore, the tag can be
3208 derived from the direction of the transfer */
3209 if (evt
== DVBCI_EVT_DATA_CAM_TO_HOST
)
3210 tag
= T_CC_SAC_DATA_REQ
;
3212 tag
= T_CC_SAC_DATA_CNF
;
3214 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
, "%s",
3215 val_to_str_const(tag
, dvbci_apdu_tag
, "unknown"));
3217 dissect_sac_msg(tag
, tvb
, 0, pinfo
, tree
, TRUE
);
3218 return tvb_reported_length(tvb
);
3223 dissect_dvbci_payload_cc(guint32 tag
, gint len_field _U_
,
3224 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
3225 packet_info
*pinfo
, proto_tree
*tree
)
3235 proto_tree_add_item(tree
, hf_dvbci_cc_sys_id_bitmask
,
3236 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3240 dissect_cc_data_payload(tag
, tvb
, offset
, pinfo
, tree
, NULL
);
3243 status
= tvb_get_guint8(tvb
, offset
);
3244 proto_tree_add_item(
3245 tree
, hf_dvbci_cc_status_field
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3246 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ", "%s",
3247 val_to_str_const(status
, dvbci_cc_status
, "unknown"));
3249 case T_CC_SAC_DATA_REQ
:
3250 case T_CC_SAC_DATA_CNF
:
3251 case T_CC_SAC_SYNC_REQ
:
3252 case T_CC_SAC_SYNC_CNF
:
3253 dissect_sac_msg(tag
, tvb
, offset
, pinfo
, tree
, FALSE
);
3255 case T_CC_PIN_CAPABILITIES_REPLY
:
3256 proto_tree_add_item(tree
, hf_dvbci_capability_field
,
3257 tvb
, offset
, 1 , ENC_BIG_ENDIAN
);
3259 /* we can't read_utc_time() and check with nstime_is_zero() */
3260 if (tvb_get_ntoh40(tvb
, offset
) == 0) {
3261 proto_tree_add_text(tree
, tvb
, offset
, UTC_TIME_LEN
,
3262 "CICAM PIN has never been changed");
3265 if (read_utc_time(tvb
, offset
, &utc_time
) < 0) {
3266 proto_tree_add_expert_format(tree
, pinfo
, &ei_dvbci_bad_length
, tvb
, offset
, UTC_TIME_LEN
,
3267 "Invalid UTC time field, 2 bytes MJD, 3 bytes BCD time hhmmss");
3271 /* abs_time_to_str() never returns NULL */
3272 proto_tree_add_time(tree
, hf_dvbci_pin_chg_time
,
3273 tvb
, offset
, UTC_TIME_LEN
, &utc_time
);
3276 offset
+= UTC_TIME_LEN
;
3277 dissect_rating(tvb
, offset
, pinfo
, tree
);
3279 case T_CC_PIN_REPLY
:
3280 pin_stat
= tvb_get_guint8(tvb
, offset
);
3281 proto_tree_add_item(tree
, hf_dvbci_pincode_status
,
3282 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3283 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ", "%s",
3284 val_to_str_const(pin_stat
, dvbci_pincode_status
, "unknown"));
3286 case T_CC_PIN_EVENT
:
3287 proto_tree_add_item(tree
, hf_dvbci_cc_prog_num
,
3288 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3290 proto_tree_add_item(tree
, hf_dvbci_pincode_status
,
3291 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3293 dissect_rating(tvb
, offset
, pinfo
, tree
);
3295 if (read_utc_time(tvb
, offset
, &utc_time
) < 0) {
3296 proto_tree_add_expert_format(tree
, pinfo
, &ei_dvbci_bad_length
, tvb
, offset
, UTC_TIME_LEN
,
3297 "Invalid UTC time field, 2 bytes MJD, 3 bytes BCD time hhmmss");
3301 proto_tree_add_time(tree
, hf_dvbci_pin_evt_time
,
3302 tvb
, offset
, UTC_TIME_LEN
, &utc_time
);
3304 offset
+= UTC_TIME_LEN
;
3305 evt_cent
= tvb_get_guint8(tvb
, offset
);
3306 pi
= proto_tree_add_item(tree
, hf_dvbci_pin_evt_cent
,
3307 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3308 if (evt_cent
> 100) {
3309 expert_add_info(pinfo
, pi
, &ei_dvbci_pin_evt_cent
);
3312 /* length field was already checked by the caller */
3313 proto_tree_add_item(tree
, hf_dvbci_cc_priv_data
, tvb
, offset
,
3314 tvb_reported_length_remaining(tvb
, offset
), ENC_NA
);
3316 case T_CC_PIN_PLAYBACK
:
3317 dissect_rating(tvb
, offset
, pinfo
, tree
);
3319 /* length field was already checked by the caller */
3320 proto_tree_add_item(tree
, hf_dvbci_cc_priv_data
, tvb
, offset
,
3321 tvb_reported_length_remaining(tvb
, offset
), ENC_NA
);
3324 case T_CC_PIN_MMI_REQ
:
3325 proto_tree_add_item(tree
, hf_dvbci_pincode
, tvb
, offset
,
3326 tvb_reported_length_remaining(tvb
, offset
),
3336 dissect_dvbci_payload_ami(guint32 tag
, gint len_field _U_
,
3337 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
3338 packet_info
*pinfo
, proto_tree
*tree
)
3340 guint8 app_dom_id_len
, init_obj_len
;
3343 gboolean req_ok
= FALSE
, file_ok
;
3346 guint8 file_name_len
;
3347 guint8
*file_name_str
;
3348 guint32 file_data_len
;
3349 proto_item
*ti
= NULL
;
3350 proto_tree
*req_tree
= NULL
;
3353 case T_REQUEST_START
:
3354 /* no filter for length items */
3355 app_dom_id_len
= tvb_get_guint8(tvb
, offset
);
3356 proto_tree_add_text(tree
, tvb
, offset
, 1,
3357 "Application Domain Identifier length %d", app_dom_id_len
);
3359 init_obj_len
= tvb_get_guint8(tvb
, offset
);
3360 proto_tree_add_text(tree
, tvb
, offset
, 1,
3361 "Initial Object length %d", init_obj_len
);
3363 proto_tree_add_item(tree
, hf_dvbci_app_dom_id
,
3364 tvb
, offset
, app_dom_id_len
, ENC_ASCII
|ENC_NA
);
3365 app_dom_id
= tvb_get_string(wmem_packet_scope(), tvb
, offset
, app_dom_id_len
);
3367 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ",
3368 "for %s", app_dom_id
);
3370 offset
+= app_dom_id_len
;
3371 proto_tree_add_item(tree
, hf_dvbci_init_obj
,
3372 tvb
, offset
, init_obj_len
, ENC_ASCII
|ENC_NA
);
3374 case T_REQUEST_START_ACK
:
3375 ack_code
= tvb_get_guint8(tvb
, offset
);
3376 proto_tree_add_item(
3377 tree
, hf_dvbci_ack_code
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3378 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ", "%s",
3379 val_to_str_const(ack_code
, dvbci_ack_code
, "unknown"));
3381 case T_FILE_REQUEST
:
3382 req_type
= tvb_get_guint8(tvb
, offset
);
3383 proto_tree_add_item(tree
, hf_dvbci_req_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3384 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ", "%s",
3385 val_to_str_const(req_type
, dvbci_req_type
, "unknown"));
3387 if (req_type
==REQ_TYPE_FILE_HASH
) {
3388 proto_tree_add_item(tree
, hf_dvbci_file_hash
,
3389 tvb
, offset
, 16, ENC_NA
);
3392 if (tvb_reported_length_remaining(tvb
, offset
) <= 0)
3394 if (req_type
==REQ_TYPE_FILE
|| req_type
==REQ_TYPE_FILE_HASH
) {
3395 req_str
= tvb_get_string(wmem_packet_scope(), tvb
, offset
,
3396 tvb_reported_length_remaining(tvb
, offset
));
3399 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "%s", req_str
);
3400 proto_tree_add_string_format_value(tree
, hf_dvbci_file_name
,
3401 tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
),
3402 req_str
, "%s", req_str
);
3404 else if (req_type
==REQ_TYPE_DATA
) {
3405 proto_tree_add_item(tree
, hf_dvbci_ami_priv_data
, tvb
, offset
,
3406 tvb_reported_length_remaining(tvb
, offset
), ENC_NA
);
3409 case T_FILE_ACKNOWLEDGE
:
3410 req_type
= tvb_get_guint8(tvb
, offset
+1);
3411 if (req_type
==REQ_TYPE_FILE_HASH
) {
3412 req_ok
= ((tvb_get_guint8(tvb
, offset
) & 0x02) == 0x02);
3413 proto_tree_add_item(tree
, hf_dvbci_req_ok
,
3414 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3416 file_ok
= ((tvb_get_guint8(tvb
, offset
) & 0x01) == 0x01);
3417 proto_tree_add_item(tree
, hf_dvbci_file_ok
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3419 proto_tree_add_item(tree
, hf_dvbci_req_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3420 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ", "%s",
3421 val_to_str_const(req_type
, dvbci_req_type
, "unknown"));
3423 if (req_type
==REQ_TYPE_FILE
|| req_type
==REQ_TYPE_FILE_HASH
) {
3424 file_name_len
= tvb_get_guint8(tvb
, offset
);
3425 proto_tree_add_text(tree
, tvb
, offset
, 1,
3426 "File name length %d", file_name_len
);
3428 file_name_str
= tvb_get_string(wmem_packet_scope(),
3429 tvb
, offset
, file_name_len
);
3432 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ",
3433 "%s", file_name_str
);
3434 proto_tree_add_string_format_value(tree
, hf_dvbci_file_name
,
3435 tvb
, offset
, file_name_len
, file_name_str
,
3436 "%s", file_name_str
);
3437 offset
+= file_name_len
;
3438 file_data_len
= tvb_get_ntohl(tvb
, offset
);
3439 proto_tree_add_text(tree
, tvb
, offset
, 4,
3440 "File data length %d", file_data_len
);
3442 if (file_data_len
> 0) {
3443 proto_tree_add_item(tree
, hf_dvbci_file_data
,
3444 tvb
, offset
, file_data_len
, ENC_NA
);
3447 else if (req_type
==REQ_TYPE_DATA
) {
3448 if (tvb_reported_length_remaining(tvb
, offset
) <= 0)
3450 proto_tree_add_item(tree
, hf_dvbci_ami_priv_data
, tvb
, offset
,
3451 tvb_reported_length_remaining(tvb
, offset
), ENC_NA
);
3453 else if (req_type
==REQ_TYPE_REQ
) {
3455 ti
= proto_tree_add_text(tree
, tvb
,
3456 offset
, tvb_reported_length_remaining(tvb
, offset
),
3457 "Supported request types");
3458 req_tree
= proto_item_add_subtree(
3459 ti
, ett_dvbci_ami_req_types
);
3461 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
3462 proto_tree_add_item(req_tree
, hf_dvbci_req_type
,
3463 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3468 if (req_type
==REQ_TYPE_FILE_HASH
&& req_ok
&& !file_ok
) {
3469 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
,
3470 "cached copy is valid");
3473 case T_APP_ABORT_REQUEST
:
3474 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
3475 proto_tree_add_item(tree
, hf_dvbci_abort_req_code
, tvb
, offset
,
3476 tvb_reported_length_remaining(tvb
, offset
), ENC_NA
);
3479 case T_APP_ABORT_ACK
:
3480 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
3481 proto_tree_add_item(tree
, hf_dvbci_abort_ack_code
, tvb
, offset
,
3482 tvb_reported_length_remaining(tvb
, offset
), ENC_NA
);
3492 dissect_dvbci_payload_lsc(guint32 tag
, gint len_field
,
3493 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit
,
3494 packet_info
*pinfo
, proto_tree
*tree
)
3497 guint8 id
, timeout
, ret_val
, phase_id
;
3498 gint conn_desc_len
, param_len
;
3500 proto_item
*pi
= NULL
;
3501 const gchar
*ret_val_str
= NULL
;
3504 dissector_handle_t msg_handle
;
3506 offset_start
= offset
;
3510 proto_tree_add_item(tree
, hf_dvbci_comms_cmd_id
,
3511 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3512 id
= tvb_get_guint8(tvb
, offset
);
3513 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ", "%s",
3514 val_to_str(id
, dvbci_comms_cmd_id
, "Unknown: %d"));
3517 case COMMS_CMD_ID_CONNECT_ON_CHANNEL
:
3518 conn_desc_len
= dissect_conn_desc(tvb
, offset
,
3519 circuit
, pinfo
, tree
);
3520 if (conn_desc_len
< 0)
3522 offset
+= conn_desc_len
;
3523 proto_tree_add_item(tree
, hf_dvbci_lsc_retry_count
,
3524 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3526 timeout
= tvb_get_guint8(tvb
, offset
);
3528 proto_tree_add_uint_format(tree
, hf_dvbci_lsc_timeout
,
3529 tvb
, offset
, 1, timeout
, "Infinite timeout");
3531 proto_tree_add_uint_format(tree
, hf_dvbci_lsc_timeout
,
3532 tvb
, offset
, 1, timeout
,
3533 "Timeout is %d seconds", timeout
);
3536 case COMMS_CMD_ID_DISCONNECT_ON_CHANNEL
:
3537 case COMMS_CMD_ID_ENQUIRE_STATUS
:
3538 /* len_field == 1 -> only id, no further parameters */
3539 if (len_field
!= 1) {
3540 proto_tree_add_expert_format(tree
, pinfo
, &ei_dvbci_bad_length
, tvb
,
3541 APDU_TAG_SIZE
, offset_start
-APDU_TAG_SIZE
,
3542 "Length field must be 1");
3545 case COMMS_CMD_ID_SET_PARAMS
:
3546 param_len
= tvb_reported_length_remaining(tvb
, offset
);
3548 buf_size
= (guint16
)tvb_get_guint8(tvb
, offset
);
3549 else if (param_len
== 3)
3550 buf_size
= tvb_get_ntohs(tvb
, offset
);
3552 /* length field == 1 byte id + param_len */
3553 proto_tree_add_expert_format(tree
, pinfo
, &ei_dvbci_bad_length
, tvb
,
3554 APDU_TAG_SIZE
, offset_start
-APDU_TAG_SIZE
,
3555 "Length field must be 3 or 4");
3558 proto_tree_add_uint_format(tree
, hf_dvbci_lsc_buf_size
,
3559 tvb
, offset
, param_len
-1, buf_size
,
3560 "buffer size %d bytes", buf_size
);
3561 offset
+= param_len
-1;
3562 timeout
= tvb_get_guint8(tvb
, offset
);
3563 proto_tree_add_uint_format(tree
, hf_dvbci_lsc_timeout
,
3564 tvb
, offset
, 1, timeout
,
3565 "timeout is %d milliseconds", timeout
*10);
3567 case COMMS_CMD_ID_GET_NEXT_BUFFER
:
3568 phase_id
= tvb_get_guint8(tvb
, offset
);
3569 proto_tree_add_uint_format(tree
, hf_dvbci_phase_id
,
3570 tvb
, offset
, 1, phase_id
, "Phase ID %d", phase_id
);
3571 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
,
3572 "received #%d", phase_id
);
3579 proto_tree_add_item(tree
, hf_dvbci_comms_rep_id
,
3580 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3581 id
= tvb_get_guint8(tvb
,offset
);
3582 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
, "%s",
3583 val_to_str(id
, dvbci_comms_rep_id
, "Unknown: %d"));
3585 ret_val
= tvb_get_guint8(tvb
,offset
);
3586 pi
= proto_tree_add_item(tree
, hf_dvbci_lsc_ret_val
,
3587 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3589 case COMMS_REP_ID_SEND_ACK
:
3590 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ",
3591 "sent #%d", ret_val
);
3593 proto_item_append_text(pi
, " (sent #%d)", ret_val
);
3595 case COMMS_REP_ID_SET_PARAMS_ACK
:
3596 ret_val_str
= val_to_str_const(ret_val
,
3597 dvbci_lsc_ret_val_params
, "unknown/error");
3599 case COMMS_REP_ID_STATUS_REPLY
:
3600 ret_val_str
= val_to_str_const(ret_val
,
3601 dvbci_lsc_ret_val_connect
, "unknown/error");
3604 ret_val_str
= val_to_str_const(ret_val
,
3605 dvbci_lsc_ret_val
, "unknown/error");
3609 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ",
3612 proto_item_append_text(pi
, " (%s)", ret_val_str
);
3615 case T_COMMS_SEND_LAST
:
3616 case T_COMMS_SEND_MORE
:
3617 case T_COMMS_RCV_LAST
:
3618 case T_COMMS_RCV_MORE
:
3619 phase_id
= tvb_get_guint8(tvb
, offset
);
3620 proto_tree_add_uint_format(tree
, hf_dvbci_phase_id
,
3621 tvb
, offset
, 1, phase_id
, "Phase ID %d", phase_id
);
3622 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ",
3623 "Phase ID %d", phase_id
);
3625 msg_len
= tvb_reported_length_remaining(tvb
, offset
);
3628 msg_tvb
= tvb_new_subset(tvb
, offset
, msg_len
, msg_len
);
3631 if (dvbci_dissect_lsc_msg
&& circuit
&& circuit
->dissector_handle
) {
3632 msg_handle
= circuit
->dissector_handle
;
3633 col_append_str(pinfo
->cinfo
, COL_INFO
, ", ");
3634 col_set_fence(pinfo
->cinfo
, COL_INFO
);
3635 col_append_str(pinfo
->cinfo
, COL_PROTOCOL
, ", ");
3636 col_set_fence(pinfo
->cinfo
, COL_PROTOCOL
);
3639 msg_handle
= data_handle
;
3642 call_dissector(msg_handle
, msg_tvb
, pinfo
, tree
);
3651 dissect_dvbci_payload_opp(guint32 tag
, gint len_field _U_
,
3652 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit _U_
,
3653 packet_info
*pinfo
, proto_tree
*tree
)
3655 guint16 nit_loop_len
, nit_loop_offset
;
3656 tvbuff_t
*nit_loop_tvb
, *nit_loop_partial_tvb
;
3657 guint dvb_nit_bytes
;
3659 guint8 cap_loop_len
;
3660 gboolean info_valid
;
3662 guint8 sig_strength
, sig_qual
;
3666 case T_OPERATOR_STATUS
:
3667 case T_OPERATOR_SEARCH_STATUS
:
3668 dissect_opp_status_body(tvb
, offset
, pinfo
, tree
);
3670 case T_OPERATOR_NIT
:
3671 nit_loop_len
= tvb_get_ntohs(tvb
, offset
);
3672 proto_tree_add_item(tree
, hf_dvbci_nit_loop_len
,
3673 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3674 if (nit_loop_len
==0)
3677 nit_loop_tvb
= tvb_new_subset(
3678 tvb
, offset
, nit_loop_len
, nit_loop_len
);
3679 nit_loop_offset
= 0;
3680 if (!dvb_nit_handle
) {
3681 call_dissector(data_handle
, nit_loop_tvb
, pinfo
, tree
);
3684 /* prevent dvb_nit dissector from clearing the dvb-ci infos */
3685 col_append_str(pinfo
->cinfo
, COL_INFO
, ", ");
3686 col_set_fence(pinfo
->cinfo
, COL_INFO
);
3688 table_id
= tvb_get_guint8(nit_loop_tvb
, nit_loop_offset
);
3689 if (table_id
!= TABLE_ID_CICAM_NIT
) {
3690 proto_tree_add_expert(tree
, pinfo
, &ei_dvbci_cicam_nit_table_id
,
3691 nit_loop_tvb
, nit_loop_offset
, 1);
3693 nit_loop_partial_tvb
=
3694 tvb_new_subset_remaining(nit_loop_tvb
, nit_loop_offset
);
3695 dvb_nit_bytes
= call_dissector(
3696 dvb_nit_handle
, nit_loop_partial_tvb
, pinfo
, tree
);
3697 nit_loop_offset
+= dvb_nit_bytes
;
3698 /* offsets go from 0 to nit_loop_len-1 */
3699 } while (dvb_nit_bytes
>0 && nit_loop_offset
<nit_loop_len
-1);
3701 case T_OPERATOR_INFO
:
3702 info_valid
= ((tvb_get_guint8(tvb
, offset
) & 0x08) == 0x08);
3703 proto_tree_add_item(tree
, hf_dvbci_info_valid
,
3704 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3705 proto_tree_add_item(tree
, hf_dvbci_info_ver_op_info
,
3706 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3710 proto_tree_add_item(tree
, hf_dvbci_cicam_onid
,
3711 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3713 proto_tree_add_item(tree
, hf_dvbci_cicam_id
,
3714 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3716 char_tbl
= tvb_get_guint8(tvb
, offset
);
3717 if (char_tbl
==CHAR_TBL_MULTI_BYTE
) {
3718 /* we display this sligthly differently (i.e. clearer)
3719 than the CI+ specification ;-) */
3720 proto_tree_add_item(tree
, hf_dvbci_opp_char_tbl_multi
,
3721 tvb
, offset
, 3, ENC_BIG_ENDIAN
);
3725 proto_tree_add_item(tree
, hf_dvbci_opp_char_tbl
,
3726 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3728 if (char_tbl
==CHAR_TBL_ENC_TYPE_ID
) {
3729 proto_tree_add_item(tree
, hf_dvbci_enc_type_id
,
3730 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3734 proto_tree_add_item(tree
, hf_dvbci_sdt_rst_trusted
,
3735 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3736 proto_tree_add_item(tree
, hf_dvbci_eit_rst_trusted
,
3737 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3738 proto_tree_add_item(tree
, hf_dvbci_eit_pf_usage
,
3739 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3740 proto_tree_add_item(tree
, hf_dvbci_eit_sch_usage
,
3741 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3742 proto_tree_add_item(tree
, hf_dvbci_ext_evt_usage
,
3743 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3745 proto_tree_add_item(tree
, hf_dvbci_sdt_oth_trusted
,
3746 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3747 proto_tree_add_item(tree
, hf_dvbci_eit_evt_trigger
,
3748 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3750 proto_tree_add_item(tree
, hf_dvbci_opp_lang_code
,
3751 tvb
, offset
, 3, ENC_ASCII
|ENC_NA
);
3753 /* hf_dvbci_prof_name is an FT_UINT_STRING, one leading len byte */
3754 proto_tree_add_item(tree
, hf_dvbci_prof_name
,
3755 tvb
, offset
, 1, ENC_ASCII
|ENC_NA
);
3757 case T_OPERATOR_SEARCH_START
:
3758 proto_tree_add_item(tree
, hf_dvbci_unattended
,
3759 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3761 /* no filters for the loop lengths, one is 7bit, others are 8bit */
3762 cap_loop_len
= tvb_get_guint8(tvb
, offset
) & 0x7F;
3763 proto_tree_add_text(tree
, tvb
, offset
, 1,
3764 "Service type loop length: %d", cap_loop_len
);
3766 /* no need for error checking, we continue anyway */
3767 dissect_opp_cap_loop(cap_loop_len
, "Service type loop",
3768 hf_dvbci_opp_srv_type
, 1, tvb
, offset
, pinfo
, tree
);
3769 offset
+= cap_loop_len
;
3771 cap_loop_len
= tvb_get_guint8(tvb
, offset
);
3772 proto_tree_add_text(tree
, tvb
, offset
, 1,
3773 "Delivery system capabilities loop length: %d",
3776 dissect_opp_cap_loop(cap_loop_len
,
3777 "Delivery system capabilities loop",
3778 hf_dvbci_dlv_cap_byte
, 1,
3779 tvb
, offset
, pinfo
, tree
);
3780 offset
+= cap_loop_len
;
3782 cap_loop_len
= tvb_get_guint8(tvb
, offset
);
3783 proto_tree_add_text(tree
, tvb
, offset
, 1,
3784 "Application capabilities loop length: %d", cap_loop_len
);
3785 dissect_opp_cap_loop(cap_loop_len
,
3786 "Application capabilities loop",
3787 hf_dvbci_app_cap_bytes
, 2,
3788 tvb
, offset
, pinfo
, tree
);
3790 case T_OPERATOR_TUNE_STATUS
:
3791 proto_tree_add_item(tree
, hf_dvbci_desc_num
,
3792 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3794 sig_strength
= tvb_get_guint8(tvb
, offset
);
3795 proto_tree_add_item(tree
, hf_dvbci_sig_strength
,
3796 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3798 sig_qual
= tvb_get_guint8(tvb
, offset
);
3799 proto_tree_add_item(tree
, hf_dvbci_sig_qual
,
3800 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3801 if (sig_strength
>100 || sig_qual
>100) {
3802 pi
= proto_tree_add_text(tree
, tvb
, offset
, 1,
3803 "Invalid value for signal strength / signal quality");
3804 expert_add_info(pinfo
, pi
, &ei_dvbci_sig_qual
);
3807 proto_tree_add_item(tree
, hf_dvbci_opp_tune_status
,
3808 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3809 dissect_desc_loop(hf_dvbci_opp_desc_loop_len
,
3810 tvb
, offset
, pinfo
, tree
);
3812 case T_OPERATOR_TUNE
:
3813 dissect_desc_loop(hf_dvbci_opp_desc_loop_len
,
3814 tvb
, offset
, pinfo
, tree
);
3823 dissect_dvbci_payload_sas(guint32 tag
, gint len_field _U_
,
3824 tvbuff_t
*tvb
, gint offset
, circuit_t
*circuit
,
3825 packet_info
*pinfo
, proto_tree
*tree
)
3827 gchar app_id_str
[2+16+1]; /* "0x", string of 16 hex digits, trailing 0 */
3829 dissector_handle_t msg_handle
;
3835 case T_SAS_CONNECT_RQST
:
3836 case T_SAS_CONNECT_CNF
:
3837 g_snprintf(app_id_str
, sizeof(app_id_str
),
3838 "0x%016" G_GINT64_MODIFIER
"x", tvb_get_ntoh64(tvb
, offset
));
3839 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ", "%s", app_id_str
);
3840 proto_tree_add_item(tree
, hf_dvbci_sas_app_id
,
3841 tvb
, offset
, 8, ENC_BIG_ENDIAN
);
3843 if (tag
== T_SAS_CONNECT_CNF
) {
3844 sas_status
= tvb_get_guint8(tvb
, offset
);
3845 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
,
3846 (sas_status
== SAS_SESS_STATE_CONNECTED
?
3848 proto_tree_add_item(tree
, hf_dvbci_sas_sess_state
,
3849 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3852 if (sas_status
== SAS_SESS_STATE_CONNECTED
) {
3853 msg_handle
= dissector_get_string_handle(
3854 sas_msg_dissector_table
, app_id_str
);
3855 /* this clears the dissector for msg_handle==NULL */
3856 circuit_set_dissector(circuit
, msg_handle
);
3859 circuit_set_dissector(circuit
, NULL
);
3862 case T_SAS_ASYNC_MSG
:
3863 msg_nb
= tvb_get_guint8(tvb
, offset
);
3864 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ",
3865 "Message #%d ", msg_nb
);
3866 proto_tree_add_item(tree
, hf_dvbci_sas_msg_nb
,
3867 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3869 msg_len
= tvb_get_ntohs(tvb
, offset
);
3870 proto_tree_add_item(tree
, hf_dvbci_sas_msg_len
,
3871 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
3873 msg_tvb
= tvb_new_subset(tvb
, offset
, msg_len
, msg_len
);
3874 msg_handle
= (circuit
&& circuit
->dissector_handle
) ?
3875 circuit
->dissector_handle
: data_handle
;
3876 call_dissector(msg_handle
, msg_tvb
, pinfo
, tree
);
3885 dissect_dvbci_apdu(tvbuff_t
*tvb
, circuit_t
*circuit
,
3886 packet_info
*pinfo
, proto_tree
*tree
, guint8 direction
)
3889 proto_tree
*app_tree
= NULL
;
3890 guint32 apdu_len
, tag
, len_field
;
3891 const gchar
*tag_str
;
3895 guint32 apdu_res_id
;
3896 const gchar
*ai_res_class_str
;
3899 apdu_len
= tvb_reported_length(tvb
);
3901 ti
= proto_tree_add_text(tree
, tvb
, 0, apdu_len
, "Application Layer");
3902 app_tree
= proto_item_add_subtree(ti
, ett_dvbci_application
);
3904 tag
= tvb_get_ntoh24(tvb
, 0);
3905 tag_str
= try_val_to_str(tag
, dvbci_apdu_tag
);
3906 offset
= APDU_TAG_SIZE
;
3908 col_set_str(pinfo
->cinfo
, COL_INFO
,
3909 val_to_str_const(tag
, dvbci_apdu_tag
, "Unknown/invalid APDU"));
3910 pi
= proto_tree_add_item(
3911 app_tree
, hf_dvbci_apdu_tag
, tvb
, 0, APDU_TAG_SIZE
, ENC_BIG_ENDIAN
);
3912 if (tag_str
== NULL
) {
3913 expert_add_info(pinfo
, pi
, &ei_dvbci_apdu_tag
);
3917 offset
= dissect_ber_length(pinfo
, app_tree
, tvb
, offset
, &len_field
, NULL
);
3918 if ((offset
+len_field
) != apdu_len
) {
3919 proto_tree_add_expert_format(app_tree
, pinfo
, &ei_dvbci_bad_length
, tvb
,
3920 APDU_TAG_SIZE
, offset
-APDU_TAG_SIZE
,
3921 "Length field is different from the number of apdu payload bytes");
3922 /* we need len_field bytes of apdu payload to call
3923 ai->dissect_payload() and continue dissecting */
3924 if (apdu_len
< offset
+len_field
)
3928 ai
= (apdu_info_t
*)g_hash_table_lookup(apdu_table
,
3929 GUINT_TO_POINTER((guint
)tag
));
3931 proto_tree_add_expert(app_tree
, pinfo
, &ei_dvbci_apdu_not_supported
, tvb
, 0, APDU_TAG_SIZE
);
3934 if (ai
->direction
!=DIRECTION_ANY
&& ai
->direction
!=direction
) {
3935 if (ai
->direction
==DATA_HOST_TO_CAM
) {
3936 proto_tree_add_expert(app_tree
, pinfo
, &ei_dvbci_apu_host_to_cam
, tvb
, 0, APDU_TAG_SIZE
);
3939 proto_tree_add_expert(app_tree
, pinfo
, &ei_dvbci_apu_cam_to_host
, tvb
, 0, APDU_TAG_SIZE
);
3941 /* don't return, we can continue dissecting the APDU */
3943 if (ai
->min_len_field
!=LEN_FIELD_ANY
&& len_field
<ai
->min_len_field
) {
3944 proto_tree_add_expert_format(app_tree
, pinfo
, &ei_dvbci_bad_length
, tvb
, 0, APDU_TAG_SIZE
,
3945 "Invalid APDU length field, minimum length field for %s is %d", tag_str
, ai
->min_len_field
);
3948 if (ai
->len_field
!=LEN_FIELD_ANY
&& len_field
!=ai
->len_field
) {
3949 proto_tree_add_expert_format(app_tree
, pinfo
, &ei_dvbci_bad_length
, tvb
, 0, APDU_TAG_SIZE
,
3950 "Invalid APDU length field, length field for %s must be %d", tag_str
, ai
->len_field
);
3954 apdu_res_id
= GPOINTER_TO_UINT(
3955 (gpointer
)circuit_get_proto_data(circuit
, proto_dvbci
));
3957 ai_res_class_str
= val_to_str_const(ai
->res_class
, dvbci_res_class
, "Unknown");
3959 if(RES_CLASS(apdu_res_id
) != ai
->res_class
) {
3960 proto_tree_add_expert_format(app_tree
, pinfo
, &ei_dvbci_res_class
, tvb
, 0, APDU_TAG_SIZE
,
3961 "Invalid resource class for this apdu, %s can only be sent on a %s session",
3962 tag_str
, ai_res_class_str
);
3964 if(RES_VER(apdu_res_id
) < ai
->res_min_ver
) {
3965 proto_tree_add_expert_format(app_tree
, pinfo
, &ei_dvbci_res_ver
, tvb
, 0, APDU_TAG_SIZE
,
3966 "Invalid resource version for this apdu, %s apdu requires at least %s version %d",
3967 tag_str
, ai_res_class_str
, ai
->res_min_ver
);
3969 /* don't return, we can continue dissecting the APDU */
3971 if (ai
->len_field
!=0) {
3972 if (!ai
->dissect_payload
) {
3973 /* don't display an error, getting here means we have illegal
3974 * data in apdu_info[] */
3977 ai
->dissect_payload(
3978 tag
, len_field
, tvb
, offset
, circuit
, pinfo
, app_tree
);
3983 dissect_dvbci_spdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
3984 guint8 direction
, guint8 tcid
)
3987 proto_item
*ti
= NULL
;
3988 proto_tree
*sess_tree
= NULL
;
3990 const gchar
*tag_str
;
3991 circuit_t
*circuit
= NULL
;
3995 const spdu_info_t
*si
;
3996 proto_item
*res_id_it
= NULL
;
3998 guint16 ssnb
= 0; /* session numbers start with 1, 0 is invalid */
4000 tvbuff_t
*payload_tvb
= NULL
;
4004 spdu_len
= tvb_reported_length(tvb
);
4006 ti
= proto_tree_add_text(tree
, tvb
, 0, -1, "Session Layer");
4007 sess_tree
= proto_item_add_subtree(ti
, ett_dvbci_session
);
4009 tag
= tvb_get_guint8(tvb
,0);
4010 tag_str
= try_val_to_str(tag
, dvbci_spdu_tag
);
4011 col_set_str(pinfo
->cinfo
, COL_INFO
,
4012 val_to_str_const(tag
, dvbci_spdu_tag
, "Invalid SPDU"));
4013 pi
= proto_tree_add_item(sess_tree
, hf_dvbci_spdu_tag
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
4014 if (tag_str
== NULL
) {
4015 expert_add_info(pinfo
, pi
, &ei_dvbci_spdu_tag
);
4019 offset
= dissect_ber_length(pinfo
, sess_tree
, tvb
, 1, &len_field
, NULL
);
4021 si
= (spdu_info_t
*)g_hash_table_lookup(spdu_table
,
4022 GUINT_TO_POINTER((guint
)tag
));
4025 if (si
->direction
!=0 && si
->direction
!=direction
) {
4026 if (si
->direction
==DATA_HOST_TO_CAM
) {
4027 proto_tree_add_expert(sess_tree
, pinfo
, &ei_dvbci_spdu_host_to_cam
, tvb
, 0, 1);
4030 proto_tree_add_expert(sess_tree
, pinfo
, &ei_dvbci_spdu_cam_to_host
, tvb
, 0, 1);
4033 if (si
->len_field
!= len_field
) {
4034 /* offset points to 1st byte after the length field */
4035 proto_tree_add_expert_format(sess_tree
, pinfo
, &ei_dvbci_bad_length
, tvb
, 1, offset
-1,
4036 "Invalid SPDU length field, correct length field for %s is %d", tag_str
, si
->len_field
);
4042 case T_OPEN_SESSION_REQUEST
:
4043 res_id_it
= dissect_res_id(tvb
, offset
, pinfo
, sess_tree
, 0, TRUE
);
4045 case T_CREATE_SESSION
:
4046 res_id_it
= dissect_res_id(tvb
, offset
, pinfo
, sess_tree
, 0, TRUE
);
4047 /* DVB-CI uses network byte order == big endian */
4048 ssnb
= tvb_get_ntohs(tvb
, offset
+RES_ID_LEN
);
4049 proto_tree_add_item(sess_tree
, hf_dvbci_sess_nb
,
4050 tvb
, offset
+RES_ID_LEN
, 2, ENC_BIG_ENDIAN
);
4052 case T_OPEN_SESSION_RESPONSE
:
4053 case T_CREATE_SESSION_RESPONSE
:
4054 sess_stat
= tvb_get_guint8(tvb
, offset
);
4055 proto_tree_add_item(sess_tree
, hf_dvbci_sess_status
,
4056 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4057 res_id
= tvb_get_ntohl(tvb
, offset
+1);
4058 res_id_it
= dissect_res_id(tvb
, offset
+1, pinfo
, sess_tree
, 0, TRUE
);
4059 ssnb
= tvb_get_ntohs(tvb
, offset
+1+RES_ID_LEN
);
4060 proto_tree_add_item(sess_tree
, hf_dvbci_sess_nb
, tvb
,
4061 offset
+1+RES_ID_LEN
, 2, ENC_BIG_ENDIAN
);
4062 if (sess_stat
!= SESS_OPENED
) {
4063 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
, "Error");
4066 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
, "Session opened");
4067 circuit
= circuit_new(CT_DVBCI
, CT_ID(ssnb
, tcid
), pinfo
->fd
->num
);
4069 /* we always add the resource id immediately after the circuit
4071 circuit_add_proto_data(
4072 circuit
, proto_dvbci
, GUINT_TO_POINTER(res_id
));
4075 case T_CLOSE_SESSION_REQUEST
:
4076 ssnb
= tvb_get_ntohs(tvb
, offset
);
4077 proto_tree_add_item(
4078 sess_tree
, hf_dvbci_sess_nb
, tvb
,
4079 offset
, 2, ENC_BIG_ENDIAN
);
4081 case T_CLOSE_SESSION_RESPONSE
:
4082 sess_stat
= tvb_get_guint8(tvb
, offset
);
4083 proto_tree_add_item(
4084 sess_tree
, hf_dvbci_close_sess_status
, tvb
,
4085 offset
, 1, ENC_BIG_ENDIAN
);
4086 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
,
4087 sess_stat
==SESS_CLOSED
? "Session closed" : "Error");
4088 ssnb
= tvb_get_ntohs(tvb
, offset
+1);
4089 proto_tree_add_item(sess_tree
, hf_dvbci_sess_nb
,
4090 tvb
, offset
+1, 2, ENC_BIG_ENDIAN
);
4091 circuit
= find_circuit(CT_DVBCI
, CT_ID(ssnb
, tcid
), pinfo
->fd
->num
);
4093 close_circuit(circuit
, pinfo
->fd
->num
);
4095 case T_SESSION_NUMBER
:
4096 ssnb
= tvb_get_ntohs(tvb
, offset
);
4097 proto_tree_add_item(
4098 sess_tree
, hf_dvbci_sess_nb
, tvb
,
4099 offset
, 2, ENC_BIG_ENDIAN
);
4100 payload_len
= tvb_reported_length_remaining(tvb
, offset
+2);
4102 tvb_new_subset(tvb
, offset
+2, payload_len
, payload_len
);
4108 if (ssnb
&& !circuit
)
4109 circuit
= find_circuit(CT_DVBCI
, CT_ID(ssnb
, tcid
), pinfo
->fd
->num
);
4111 /* if the packet contains no resource id, we add the cached id from
4112 the circuit so that each packet has a resource id that can be
4113 used for filtering */
4114 if (circuit
&& !res_id_it
) {
4115 /* when a circuit is found, it always contains a valid resource id */
4116 res_id
= GPOINTER_TO_UINT(
4117 (gpointer
)circuit_get_proto_data(circuit
, proto_dvbci
));
4118 res_id_it
= dissect_res_id(NULL
, 0, pinfo
, sess_tree
, res_id
, TRUE
);
4119 PROTO_ITEM_SET_GENERATED(res_id_it
);
4123 proto_item_set_len(ti
, spdu_len
-tvb_reported_length(payload_tvb
));
4124 dissect_dvbci_apdu(payload_tvb
, circuit
, pinfo
, tree
, direction
);
4127 proto_item_set_len(ti
, spdu_len
);
4131 /* dissect the status of an r_tpdu, return its length or -1 for error */
4133 dissect_dvbci_tpdu_status(tvbuff_t
*tvb
, gint offset
,
4134 packet_info
*pinfo
, proto_tree
*tree
,
4135 guint8 lpdu_tcid
, guint8 r_tpdu_tag
)
4137 gint offset_new
, len_start_offset
;
4140 guint8 t_c_id
, sb_value
;
4141 const gchar
*sb_str
;
4144 offset_new
= offset
;
4146 tag
= tvb_get_guint8(tvb
, offset_new
);
4148 proto_tree_add_expert(tree
, pinfo
, &ei_dvbci_tpdu_status_tag
, tvb
, offset_new
, 1);
4151 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
, "T_SB");
4152 proto_tree_add_text(tree
, tvb
, offset_new
, 1, "Response TPDU status");
4155 len_start_offset
= offset_new
;
4156 offset_new
= dissect_ber_length(
4157 pinfo
, tree
, tvb
, offset_new
, &len_field
, NULL
);
4158 if (len_field
!= 2) {
4159 proto_tree_add_expert_format(tree
, pinfo
, &ei_dvbci_bad_length
, tvb
, len_start_offset
, offset_new
-len_start_offset
,
4160 "Invalid status length field, this must always be 2");
4165 t_c_id
= tvb_get_guint8(tvb
, offset_new
);
4166 proto_tree_add_item(tree
, hf_dvbci_t_c_id
, tvb
, offset_new
, 1, ENC_BIG_ENDIAN
);
4167 /* tcid in transport header and link layer must only match for data
4168 * transmission commands */
4169 if (t_c_id
!=lpdu_tcid
) {
4170 if (r_tpdu_tag
==NO_TAG
||
4171 r_tpdu_tag
==T_DATA_MORE
|| r_tpdu_tag
==T_DATA_LAST
) {
4173 pi
= proto_tree_add_text(tree
, tvb
, offset_new
, 1,
4174 "Transport Connection ID mismatch");
4175 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
);
4182 sb_value
= tvb_get_guint8(tvb
, offset_new
);
4183 sb_str
= try_val_to_str(sb_value
, dvbci_sb_value
);
4184 pi
= proto_tree_add_item(tree
, hf_dvbci_sb_value
, tvb
,
4185 offset_new
, 1, ENC_BIG_ENDIAN
);
4187 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ", "%s", sb_str
);
4190 proto_tree_add_text(tree
, tvb
, offset_new
, 1,
4191 "Invalid SB_value");
4192 expert_add_info(pinfo
, pi
, &ei_dvbci_sb_value
);
4196 return offset_new
-offset
;
4200 /* dissect the header of a c_tpdu or r_tpdu
4201 return the length of the header (tag, len_field, t_c_id) or -1 for error */
4203 dissect_dvbci_tpdu_hdr(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
4204 guint8 direction
, guint8 lpdu_tcid
, guint32 tpdu_len
,
4205 guint8
*hdr_tag
, guint32
*body_len
)
4207 guint8 c_tpdu_tag
, r_tpdu_tag
, *tag
= NULL
;
4208 const gchar
*c_tpdu_str
, *r_tpdu_str
;
4214 if (direction
==DATA_HOST_TO_CAM
) {
4215 c_tpdu_tag
= tvb_get_guint8(tvb
, 0);
4217 c_tpdu_str
= try_val_to_str(c_tpdu_tag
, dvbci_c_tpdu
);
4218 pi
= proto_tree_add_item(tree
, hf_dvbci_c_tpdu_tag
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
4220 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
, "%s", c_tpdu_str
);
4223 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
,
4224 "Invalid Command-TPDU tag");
4225 expert_add_info(pinfo
, pi
, &ei_dvbci_c_tpdu_tag
);
4230 r_tpdu_tag
= tvb_get_guint8(tvb
, 0);
4232 r_tpdu_str
= try_val_to_str(r_tpdu_tag
, dvbci_r_tpdu
);
4233 pi
= proto_tree_add_item(tree
, hf_dvbci_r_tpdu_tag
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
4235 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
, "%s", r_tpdu_str
);
4238 if (r_tpdu_tag
== T_SB
) {
4239 /* we have an r_tpdu without header and body,
4240 it contains only the status part */
4248 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
,
4249 "Invalid Response-TPDU tag");
4250 expert_add_info(pinfo
, pi
, &ei_dvbci_r_tpdu_tag
);
4256 offset
= dissect_ber_length(pinfo
, tree
, tvb
, 1, &len_field
, NULL
);
4257 /* len_field must be at least 1 for the following t_c_id
4258 c_tpdu's len_field must match tvbuff exactly
4259 r_tpdu's len_field does not include the status part after the body */
4261 ((direction
==DATA_HOST_TO_CAM
) && ((offset
+len_field
)!=tpdu_len
)) ||
4262 ((direction
==DATA_CAM_TO_HOST
) && ((offset
+len_field
)>tpdu_len
))) {
4263 /* offset points to 1st byte after the length field */
4264 proto_tree_add_expert_format(tree
, pinfo
, &ei_dvbci_bad_length
, tvb
, 1, offset
-1,
4265 len_field
==0 ? "Invalid length field, length field must be at least 1" :
4266 "Invalid length field, length field mismatch");
4270 t_c_id
= tvb_get_guint8(tvb
, offset
);
4271 pi
= proto_tree_add_item(tree
, hf_dvbci_t_c_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4272 /* tcid in transport header and link layer must only match for
4273 * data transmission commands */
4274 if (t_c_id
!=lpdu_tcid
) {
4275 if (tag
&& (*tag
==T_RCV
|| *tag
==T_DATA_MORE
|| *tag
==T_DATA_LAST
)) {
4276 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",
4281 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ", "tcid %d", t_c_id
);
4288 *body_len
= len_field
-1; /* -1 for t_c_id */
4293 dissect_dvbci_tpdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
4294 guint8 direction
, guint8 lpdu_tcid
)
4296 guint32 tpdu_len
, body_len
;
4297 proto_item
*ti
= NULL
;
4298 proto_tree
*trans_tree
= NULL
;
4299 gint offset
, status_len
;
4300 guint8 hdr_tag
= NO_TAG
;
4301 tvbuff_t
*body_tvb
, *payload_tvb
= NULL
;
4302 fragment_head
*frag_msg
= NULL
;
4305 tpdu_len
= tvb_reported_length(tvb
);
4307 col_clear(pinfo
->cinfo
, COL_INFO
);
4309 ti
= proto_tree_add_text(tree
, tvb
, 0, -1, "Transport Layer");
4310 trans_tree
= proto_item_add_subtree(ti
, ett_dvbci_transport
);
4312 offset
= dissect_dvbci_tpdu_hdr(tvb
, pinfo
, trans_tree
, direction
,
4313 lpdu_tcid
, tpdu_len
, &hdr_tag
, &body_len
);
4316 proto_item_set_len(ti
, offset
);
4317 if ((offset
>0) && (body_len
!=0)) {
4318 /* for unfragmented data, the reassembly api behaviour is unclear
4319 if we put the body part of the tvb into fragment_add_seq_next(),
4320 process_reassembled_data() returns the remainder of the tvb
4321 which is body|status part
4322 if there's more than one fragment, payload_tvb contains only
4323 the reassembled bodies as expected
4324 to work around this issue, we use a dedicated body_tvb as
4325 input to reassembly routines */
4326 body_tvb
= tvb_new_subset(tvb
, offset
, body_len
, body_len
);
4327 /* dissect_dvbci_tpdu_hdr() checked that lpdu_tcid==t_c_id */
4328 frag_msg
= fragment_add_seq_next(&spdu_reassembly_table
,
4329 body_tvb
, 0, pinfo
, SPDU_SEQ_ID_BASE
+lpdu_tcid
, NULL
,
4331 hdr_tag
== T_DATA_MORE
? 1 : 0);
4332 payload_tvb
= process_reassembled_data(body_tvb
, 0, pinfo
,
4333 "Reassembled SPDU", frag_msg
, &spdu_frag_items
,
4336 if (hdr_tag
== T_DATA_MORE
) {
4337 pinfo
->fragmented
= TRUE
;
4338 col_append_str(pinfo
->cinfo
, COL_INFO
, " (Message fragment)");
4340 payload_tvb
= body_tvb
;
4346 if (direction
==DATA_CAM_TO_HOST
) {
4347 /* minimum length of an rtpdu status is 4 bytes */
4348 if (tpdu_len
-offset
< 4) {
4349 proto_tree_add_expert(trans_tree
, pinfo
, &ei_dvbci_r_tpdu_status_mandatory
, tvb
, 0, 0);
4352 status_len
= dissect_dvbci_tpdu_status(
4353 tvb
, offset
, pinfo
, trans_tree
, lpdu_tcid
, hdr_tag
);
4356 proto_tree_set_appendix(trans_tree
, tvb
, offset
, status_len
);
4360 dissect_dvbci_spdu(payload_tvb
, pinfo
, tree
, direction
, lpdu_tcid
);
4365 dissect_dvbci_lpdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
4369 proto_tree
*link_tree
= NULL
;
4370 guint32 payload_len
;
4371 guint8 tcid
, more_last
;
4373 tvbuff_t
*payload_tvb
= NULL
;
4374 fragment_head
*frag_msg
= NULL
;
4377 payload_len
= tvb_reported_length(tvb
);
4379 col_set_str(pinfo
->cinfo
, COL_INFO
, "LPDU");
4381 ti
= proto_tree_add_text(tree
, tvb
, 0, 2, "Link Layer");
4382 link_tree
= proto_item_add_subtree(ti
, ett_dvbci_link
);
4384 tcid
= tvb_get_guint8(tvb
, 0);
4385 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ", "tcid %d", tcid
);
4386 proto_tree_add_item(link_tree
, hf_dvbci_tcid
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
4388 more_last
= tvb_get_guint8(tvb
, 1);
4389 pi
= proto_tree_add_item(link_tree
, hf_dvbci_ml
, tvb
, 1, 1, ENC_BIG_ENDIAN
);
4390 if (try_val_to_str(more_last
, dvbci_ml
) == NULL
) {
4391 expert_add_info(pinfo
, pi
, &ei_dvbci_ml
);
4394 /* buf_size_host==0 -> we did not capture the buffer size negotiation */
4395 if (buf_size_host
!=0 && payload_len
>buf_size_host
) {
4396 proto_tree_add_expert_format(link_tree
, pinfo
, &ei_dvbci_bad_length
, tvb
, 2, payload_len
,
4397 "Payload too large, maximum payload length is the negotiated buffer size (%d bytes)", buf_size_host
);
4400 frag_msg
= fragment_add_seq_next(&tpdu_reassembly_table
,
4401 tvb
, 2, pinfo
, TPDU_SEQ_ID_BASE
+tcid
, NULL
,
4402 tvb_reported_length_remaining(tvb
, 2),
4403 more_last
== ML_MORE
? 1 : 0);
4405 payload_tvb
= process_reassembled_data(tvb
, 2, pinfo
,
4406 "Reassembled TPDU", frag_msg
, &tpdu_frag_items
,
4409 if (more_last
== ML_MORE
) {
4410 pinfo
->fragmented
= TRUE
;
4411 col_append_str(pinfo
->cinfo
, COL_INFO
, " (Message fragment)");
4413 payload_tvb
= tvb_new_subset_remaining(tvb
, 2);
4416 dissect_dvbci_tpdu(payload_tvb
, pinfo
, tree
, direction
, tcid
);
4419 /* dissect DVB-CI buffer size negotiation */
4421 dissect_dvbci_buf_neg(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
4427 buf_size
= tvb_get_ntohs(tvb
, 0);
4429 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s: %u bytes",
4430 direction
== DATA_HOST_TO_CAM
?
4431 "negotiated buffer size" : "buffer size proposal",
4434 if (direction
== DATA_HOST_TO_CAM
) {
4435 buf_size_host
= buf_size
;
4436 pi
= proto_tree_add_uint_format(tree
, hf_dvbci_buf_size
, tvb
,
4438 "Negotiated buffer size: %u bytes", buf_size
);
4439 if (buf_size_host
> buf_size_cam
) {
4441 wireshark may run through each packet multiple times
4442 if we didn't check the direction, we'd get the error when
4443 wireshark runs through the initial CAM packet for the 2nd time
4445 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");
4448 else if (direction
== DATA_CAM_TO_HOST
) {
4449 buf_size_cam
= buf_size
;
4450 proto_tree_add_uint_format(tree
, hf_dvbci_buf_size
, tvb
,
4452 "Buffer size proposal by the CAM: %u bytes", buf_size
);
4455 if (buf_size
< 16) {
4456 proto_tree_add_expert_format(tree
, pinfo
, &ei_dvbci_buf_size
, tvb
, 0, 2,
4457 "Illegal buffer size, minimum buffer size is 16 bytes");
4461 /* dissect Level 1 version/product information tuple's payload
4462 data_tvb is a separate tvb for the tuple payload (without tag and len)
4463 return the number of dissected bytes or -1 for error */
4465 dissect_dvbci_cis_payload_tpll_v1(tvbuff_t
*data_tvb
,
4466 packet_info
*pinfo _U_
, proto_tree
*tree
)
4468 gint offset
=0, offset_str_end
;
4470 /* the CIS is defined by PCMCIA, all multi-byte values are little endian
4471 (the rest of DVB-CI is a big-endian protocol) */
4472 proto_tree_add_item(tree
, hf_dvbci_cis_tpll_v1_major
,
4473 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4475 proto_tree_add_item(tree
, hf_dvbci_cis_tpll_v1_minor
,
4476 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4479 /* manufacturer, name and additional infos are 0-terminated strings */
4480 offset_str_end
= tvb_find_guint8(data_tvb
, offset
, -1, 0x0);
4481 if (offset_str_end
<offset
) /* offset_str_end==offset is ok */
4483 proto_tree_add_item(tree
, hf_dvbci_cis_tpll_v1_info_manuf
,
4484 data_tvb
, offset
, offset_str_end
-offset
, ENC_ASCII
|ENC_NA
);
4485 offset
= offset_str_end
+1; /* +1 for 0 termination */
4487 offset_str_end
= tvb_find_guint8(data_tvb
, offset
, -1, 0x0);
4488 if (offset_str_end
<offset
)
4490 proto_tree_add_item(tree
, hf_dvbci_cis_tpll_v1_info_name
,
4491 data_tvb
, offset
, offset_str_end
-offset
, ENC_ASCII
|ENC_NA
);
4492 offset
= offset_str_end
+1;
4494 /* the pc-card spec mentions two additional info strings,
4495 it's unclear if both are mandatory
4496 >1 because the last byte is the tuple end marker */
4497 while (tvb_reported_length_remaining(data_tvb
, offset
)>1) {
4498 offset_str_end
= tvb_find_guint8(data_tvb
, offset
, -1, 0x0);
4499 if (offset_str_end
<offset
)
4501 proto_tree_add_item(tree
, hf_dvbci_cis_tpll_v1_info_additional
,
4502 data_tvb
, offset
, offset_str_end
-offset
, ENC_ASCII
|ENC_NA
);
4503 offset
= offset_str_end
+1;
4506 proto_tree_add_item(tree
, hf_dvbci_cis_tpll_v1_end
,
4507 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4514 dissect_dvbci_cis_payload_config(tvbuff_t
*data_tvb
,
4515 packet_info
*pinfo _U_
, proto_tree
*tree
)
4518 /* these are the actual sizes, the CIS stores rmsz-1 and rasz-1 */
4519 guint8 rfsz
, rmsz
, rasz
;
4520 guint8 st_code
, st_len
;
4521 const gchar
*st_code_str
;
4522 proto_item
*st_item
= NULL
;
4523 proto_tree
*st_tree
= NULL
;
4524 guint8 stci_ifn_size
; /* actual size, see comment above */
4526 rfsz
= (tvb_get_guint8(data_tvb
, offset
)&0xC0) >> 6;
4527 proto_tree_add_item(tree
, hf_dvbci_cis_tpcc_rfsz
,
4528 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4529 rmsz
= ((tvb_get_guint8(data_tvb
, offset
)&0x3C) >> 2) + 1;
4530 proto_tree_add_item(tree
, hf_dvbci_cis_tpcc_rmsz
,
4531 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4532 rasz
= (tvb_get_guint8(data_tvb
, offset
)&0x03) + 1;
4533 proto_tree_add_item(tree
, hf_dvbci_cis_tpcc_rasz
,
4534 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4537 proto_tree_add_item(tree
, hf_dvbci_cis_tpcc_last
,
4538 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4541 proto_tree_add_item(tree
, hf_dvbci_cis_tpcc_radr
,
4542 data_tvb
, offset
, rasz
, ENC_LITTLE_ENDIAN
);
4544 proto_tree_add_item(tree
, hf_dvbci_cis_tpcc_rmsk
,
4545 data_tvb
, offset
, rmsz
, ENC_NA
);
4547 offset
+= rfsz
; /* skip reserved bytes */
4549 while (tvb_reported_length_remaining(data_tvb
, offset
) > 0) {
4550 st_code
= tvb_get_guint8(data_tvb
, offset
);
4551 st_code_str
= val_to_str_const(st_code
, dvbci_cis_subtpl_code
, "unknown");
4552 st_item
= proto_tree_add_text(tree
, data_tvb
, offset
, -1,
4553 "Subtuple: %s (0x%x)", st_code_str
, st_code
);
4554 st_tree
= proto_item_add_subtree(st_item
, ett_dvbci_cis_subtpl
);
4555 proto_tree_add_item(st_tree
, hf_dvbci_cis_st_code
,
4556 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4558 st_len
= tvb_get_guint8(data_tvb
, offset
);
4559 proto_item_set_len(st_item
, 2+st_len
); /* tag, len byte, body */
4560 proto_tree_add_item(st_tree
, hf_dvbci_cis_st_len
,
4561 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4563 if (st_code
== CCSTPL_CIF
) {
4564 stci_ifn_size
= ((tvb_get_guint8(data_tvb
, offset
) & 0xC0)>>6)+1;
4565 proto_tree_add_item(st_tree
, hf_dvbci_cis_stci_ifn_size
,
4566 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4567 /* don't increment offset,
4568 size and actual value's LSB share the same byte */
4569 proto_tree_add_item(st_tree
, hf_dvbci_cis_stci_ifn
,
4570 data_tvb
, offset
, stci_ifn_size
, ENC_LITTLE_ENDIAN
);
4571 offset
+= stci_ifn_size
;
4572 /* the stci_str field could consist of multiple strings,
4573 this case is not supported for now */
4574 proto_tree_add_item(st_tree
, hf_dvbci_cis_stci_str
,
4575 data_tvb
, offset
, st_len
-stci_ifn_size
, ENC_ASCII
|ENC_NA
);
4576 offset
+= st_len
-stci_ifn_size
;
4579 /* skip unknown subtuple's content */
4589 dissect_dvbci_cis_payload_cftable_entry(tvbuff_t
*data_tvb
,
4590 packet_info
*pinfo _U_
, proto_tree
*tree
)
4593 gboolean intface_flag
;
4595 intface_flag
= ((tvb_get_guint8(data_tvb
, offset
) & 0x80) == 0x80);
4596 /* tpce_indx byte */
4597 proto_tree_add_item(tree
, hf_dvbci_cis_tpce_indx_intface
,
4598 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4599 proto_tree_add_item(tree
, hf_dvbci_cis_tpce_indx_default
,
4600 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4601 proto_tree_add_item(tree
, hf_dvbci_cis_tpce_indx_cnf_entry
,
4602 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4607 proto_tree_add_item(tree
, hf_dvbci_cis_tpce_if_type
,
4608 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4609 /* XXX parse other components of tpce_if */
4613 /* tpce_fs byte: this is present in any case */
4614 proto_tree_add_item(tree
, hf_dvbci_cis_tpce_fs_mem_space
,
4615 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4616 proto_tree_add_item(tree
, hf_dvbci_cis_tpce_fs_irq
,
4617 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4618 proto_tree_add_item(tree
, hf_dvbci_cis_tpce_fs_io
,
4619 data_tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4620 /* XXX parse other components of tpce_fs */
4627 dissect_dvbci_cis(tvbuff_t
*tvb
, gint offset
,
4628 packet_info
*pinfo
, proto_tree
*tree
)
4631 proto_tree
*cis_tree
= NULL
, *tpl_tree
= NULL
;
4632 proto_item
*ti_main
= NULL
, *ti_tpl
;
4634 const gchar
*tpl_code_str
= NULL
;
4636 tvbuff_t
*tpl_data_tvb
;
4638 offset_start
= offset
;
4640 ti_main
= proto_tree_add_text(tree
, tvb
, offset
, -1,
4641 "Card Information Structure (CIS)");
4642 cis_tree
= proto_item_add_subtree(ti_main
, ett_dvbci_cis
);
4645 tpl_code
= tvb_get_guint8(tvb
, offset
);
4646 tpl_code_str
= val_to_str_const(tpl_code
, dvbci_cis_tpl_code
, "unknown");
4648 ti_tpl
= proto_tree_add_text(cis_tree
,
4649 tvb
, offset
, -1, "CIS tuple: %s", tpl_code_str
);
4650 tpl_tree
= proto_item_add_subtree(ti_tpl
, ett_dvbci_cis_tpl
);
4652 proto_tree_add_uint_format(tpl_tree
, hf_dvbci_cis_tpl_code
,
4653 tvb
, offset
, 1, tpl_code
, "Tuple code: %s (0x%x)",
4654 tpl_code_str
, tpl_code
);
4657 if (tpl_code
== CISTPL_END
) {
4658 proto_item_set_len(ti_tpl
, 1); /* only tag (no len and content) */
4662 len_field
= tvb_get_guint8(tvb
, offset
);
4663 proto_tree_add_item(tpl_tree
, hf_dvbci_cis_tpl_len
,
4664 tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4667 tpl_data_tvb
= tvb_new_subset(tvb
, offset
, len_field
, len_field
);
4670 dissect_dvbci_cis_payload_tpll_v1(
4671 tpl_data_tvb
, pinfo
, tpl_tree
);
4672 offset
+= len_field
;
4675 dissect_dvbci_cis_payload_config(tpl_data_tvb
, pinfo
, tpl_tree
);
4676 offset
+= len_field
;
4678 case CISTPL_CFTABLE_ENTRY
:
4679 dissect_dvbci_cis_payload_cftable_entry(
4680 tpl_data_tvb
, pinfo
, tpl_tree
);
4681 offset
+= len_field
;
4684 proto_tree_add_item(tpl_tree
, hf_dvbci_cis_tplmid_manf
,
4685 tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4687 proto_tree_add_item(tpl_tree
, hf_dvbci_cis_tplmid_card
,
4688 tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4693 proto_tree_add_item(tpl_tree
, hf_dvbci_cis_tpl_data
,
4694 tvb
, offset
, len_field
, ENC_NA
);
4696 offset
+= len_field
;
4700 proto_item_set_len(ti_tpl
, 2+len_field
); /* tag, len byte, content */
4702 } while (tvb_reported_length_remaining(tvb
, offset
) > 0);
4704 proto_item_set_len(ti_main
, offset
-offset_start
);
4709 dissect_dvbci(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
4711 gint packet_len
, offset
= 0, offset_ver
, offset_evt
, offset_len_field
;
4712 guint8 version
, event
;
4713 const gchar
*event_str
;
4715 proto_item
*ti
, *ti_hdr
;
4716 proto_tree
*dvbci_tree
= NULL
, *hdr_tree
= NULL
;
4717 tvbuff_t
*payload_tvb
;
4723 if (tvb_length(tvb
) < 4)
4726 offset_ver
= offset
;
4727 version
= tvb_get_guint8(tvb
, offset
++);
4731 offset_evt
= offset
;
4732 event
= tvb_get_guint8(tvb
, offset
++);
4733 event_str
= try_val_to_str(event
, dvbci_event
);
4737 packet_len
= tvb_reported_length(tvb
);
4738 offset_len_field
= offset
;
4739 len_field
= tvb_get_ntohs(tvb
, offset
);
4740 if (len_field
!= (packet_len
-4))
4744 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "DVB-CI");
4745 col_set_str(pinfo
->cinfo
, COL_INFO
, event_str
);
4748 ti
= proto_tree_add_protocol_format(tree
, proto_dvbci
,
4749 tvb
, 0, packet_len
, "DVB Common Interface: %s", event_str
);
4750 dvbci_tree
= proto_item_add_subtree(ti
, ett_dvbci
);
4751 ti_hdr
= proto_tree_add_text(dvbci_tree
, tvb
, 0, offset
, "Pseudo header");
4752 hdr_tree
= proto_item_add_subtree(ti_hdr
, ett_dvbci_hdr
);
4753 proto_tree_add_text(hdr_tree
, tvb
, offset_ver
, 1, "Version: %d", version
);
4754 proto_tree_add_item(hdr_tree
, hf_dvbci_event
, tvb
, offset_evt
, 1, ENC_BIG_ENDIAN
);
4755 proto_tree_add_text(hdr_tree
, tvb
, offset_len_field
, 2,
4756 "Length field: %d", len_field
);
4759 if (IS_DATA_TRANSFER(event
)) {
4760 dvbci_set_addrs(event
, pinfo
);
4762 payload_tvb
= tvb_new_subset_remaining( tvb
, offset
);
4763 if (len_field
== 2) {
4764 dissect_dvbci_buf_neg(payload_tvb
, pinfo
, dvbci_tree
, event
);
4767 dissect_dvbci_lpdu(payload_tvb
, pinfo
, dvbci_tree
, event
);
4770 else if (event
==DVBCI_EVT_COR_WRITE
) {
4771 /* PCAP format for DVB-CI defines COR address as big endian */
4772 pi
= proto_tree_add_item(dvbci_tree
, hf_dvbci_cor_addr
,
4773 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
4774 cor_addr
= tvb_get_ntohs(tvb
, offset
);
4775 if (cor_addr
== 0xFFFF) {
4776 proto_item_append_text(pi
, " (COR address is unknown)");
4777 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, ": ", "unknown address");
4779 else if (cor_addr
> 0xFFE) {
4780 expert_add_info(pinfo
, pi
, &ei_dvbci_cor_addr
);
4783 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ": ",
4784 "address 0x%x", cor_addr
);
4787 cor_value
= tvb_get_guint8(tvb
, offset
);
4788 proto_tree_add_item(dvbci_tree
, hf_dvbci_cor_val
,
4789 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4790 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
,
4791 "value 0x%x", cor_value
);
4793 else if (event
==DVBCI_EVT_CIS_READ
) {
4794 dissect_dvbci_cis(tvb
, offset
, pinfo
, dvbci_tree
);
4796 else if (event
==DVBCI_EVT_HW_EVT
) {
4797 hw_event
= tvb_get_guint8(tvb
, offset
);
4798 col_set_str(pinfo
->cinfo
, COL_INFO
,
4799 val_to_str_const(hw_event
, dvbci_hw_event
, "Invalid hardware event"));
4800 proto_tree_add_item(dvbci_tree
, hf_dvbci_hw_event
,
4801 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4809 proto_register_dvbci(void)
4812 module_t
*dvbci_module
;
4813 expert_module_t
* expert_dvbci
;
4815 static gint
*ett
[] = {
4820 &ett_dvbci_cis_subtpl
,
4822 &ett_dvbci_link_frag
,
4823 &ett_dvbci_link_frags
,
4824 &ett_dvbci_transport
,
4825 &ett_dvbci_transport_frag
,
4826 &ett_dvbci_transport_frags
,
4829 &ett_dvbci_application
,
4834 &ett_dvbci_sac_msg_body
,
4835 &ett_dvbci_ami_req_types
,
4836 &ett_dvbci_lsc_conn_desc
,
4837 &ett_dvbci_opp_cap_loop
,
4838 &ett_dvbci_dlv_sys_hint
4841 static hf_register_info hf
[] = {
4843 { "Event", "dvb-ci.event",
4844 FT_UINT8
, BASE_HEX
, VALS(dvbci_event
), 0, NULL
, HFILL
}
4846 { &hf_dvbci_hw_event
,
4847 { "Hardware event", "dvb-ci.hw_event",
4848 FT_UINT8
, BASE_HEX
, VALS(dvbci_hw_event
), 0, NULL
, HFILL
}
4850 { &hf_dvbci_cor_addr
,
4851 { "COR address", "dvb-ci.cor_address",
4852 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
4854 { &hf_dvbci_cor_val
,
4855 { "COR value", "dvb-ci.cor_value",
4856 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
4858 { &hf_dvbci_cis_tpl_code
,
4859 { "CIS tuple code", "dvb-ci.cis.tpl_code",
4860 FT_UINT8
, BASE_HEX
, VALS(dvbci_cis_tpl_code
), 0, NULL
, HFILL
}
4862 { &hf_dvbci_cis_tpl_len
,
4863 { "Length field", "dvb-ci.cis.tpl_len",
4864 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
4866 { &hf_dvbci_cis_tpl_data
,
4867 { "Tuple data", "dvb-ci.cis.tpl_data",
4868 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
4870 { &hf_dvbci_cis_tpll_v1_major
,
4871 { "Major version number", "dvb-ci.cis.tpll_v1_major",
4872 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
4874 { &hf_dvbci_cis_tpll_v1_minor
,
4875 { "Minor version number", "dvb-ci.cis.tpll_v1_minor",
4876 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
4878 { &hf_dvbci_cis_tpll_v1_info_manuf
,
4879 { "Manufacturer", "dvb-ci.cis.tpll_v1_info.manufacturer",
4880 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
4882 { &hf_dvbci_cis_tpll_v1_info_name
,
4883 { "Name", "dvb-ci.cis.tpll_v1_info.name",
4884 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
4886 { &hf_dvbci_cis_tpll_v1_info_additional
,
4887 { "Additional info", "dvb-ci.cis.tpll_v1_info.additional",
4888 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
4890 { &hf_dvbci_cis_tpll_v1_end
,
4891 { "End of chain", "dvb-ci.cis.tpll_v1_end",
4892 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
4894 { &hf_dvbci_cis_tpcc_rfsz
,
4895 { "Size of reserved area", "dvb-ci.cis.tpcc_rfsz",
4896 FT_UINT8
, BASE_HEX
, NULL
, 0xC0, NULL
, HFILL
}
4898 { &hf_dvbci_cis_tpcc_rmsz
,
4899 { "Size of TPCC_RMSK field - 1", "dvb-ci.cis.tpcc_rmsz",
4900 FT_UINT8
, BASE_HEX
, NULL
, 0x3C, NULL
, HFILL
}
4902 { &hf_dvbci_cis_tpcc_rasz
,
4903 { "Size of TPCC_RADR - 1", "dvb-ci.cis.tpcc_rasz",
4904 FT_UINT8
, BASE_HEX
, NULL
, 0x03, NULL
, HFILL
}
4906 { &hf_dvbci_cis_tpcc_last
,
4907 { "Index of the last cftable entry", "dvb-ci.cis.tpcc_last",
4908 FT_UINT8
, BASE_HEX
, NULL
, 0x3F, NULL
, HFILL
}
4910 { &hf_dvbci_cis_tpcc_radr
,
4911 { "COR base address", "dvb-ci.cis.tpcc_radr",
4912 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
4914 { &hf_dvbci_cis_tpcc_rmsk
,
4915 { "Configuration register presence mask", "dvb-ci.cis.tpcc_rmsk",
4916 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
4918 { &hf_dvbci_cis_st_code
,
4919 { "Subtuple tag", "dvb-ci.cis.st_code",
4920 FT_UINT8
, BASE_HEX
, VALS(dvbci_cis_subtpl_code
), 0, NULL
, HFILL
}
4922 { &hf_dvbci_cis_st_len
,
4923 { "Subtuple length", "dvb-ci.cis.st_len",
4924 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
4926 { &hf_dvbci_cis_stci_ifn_size
,
4927 { "Size of interface ID number - 1", "dvb-ci.cis.stci_ifn_size",
4928 FT_UINT8
, BASE_HEX
, NULL
, 0xC0, NULL
, HFILL
}
4930 { &hf_dvbci_cis_stci_ifn
,
4931 { "Interface ID number", "dvb-ci.cis.stci_ifn",
4932 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
4934 { &hf_dvbci_cis_stci_str
,
4935 { "Interface description strings", "dvb-ci.cis.stci_str",
4936 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
4938 { &hf_dvbci_cis_tpce_indx_intface
,
4939 { "Intface", "dvb-ci.cis.tpce_indx.intface",
4940 FT_UINT8
, BASE_HEX
, NULL
, 0x80, NULL
, HFILL
}
4942 { &hf_dvbci_cis_tpce_indx_default
,
4943 { "Default", "dvb-ci.cis.tpce_indx.default",
4944 FT_UINT8
, BASE_HEX
, NULL
, 0x40, NULL
, HFILL
}
4946 { &hf_dvbci_cis_tpce_indx_cnf_entry
,
4947 { "Configuration entry number", "dvb-ci.cis.tpce_indx.cnf_entry",
4948 FT_UINT8
, BASE_HEX
, NULL
, 0x3F, NULL
, HFILL
}
4950 { &hf_dvbci_cis_tpce_if_type
,
4951 { "Interface type", "dvb-ci.cis.tpce_if.type", FT_UINT8
, BASE_HEX
,
4952 VALS(dvbci_cis_tpce_if_type
), 0x0F, NULL
, HFILL
}
4954 { &hf_dvbci_cis_tpce_fs_mem_space
,
4955 { "Mem space", "dvb-ci.cis.tpce_fs.mem_space",
4956 FT_UINT8
, BASE_HEX
, NULL
, 0x60, NULL
, HFILL
}
4958 { &hf_dvbci_cis_tpce_fs_irq
,
4959 { "IRQ", "dvb-ci.cis.tpce_fs.irq",
4960 FT_UINT8
, BASE_HEX
, NULL
, 0x10, NULL
, HFILL
}
4962 { &hf_dvbci_cis_tpce_fs_io
,
4963 { "IO Space", "dvb-ci.cis.tpce_fs.io",
4964 FT_UINT8
, BASE_HEX
, NULL
, 0x08, NULL
, HFILL
}
4966 { &hf_dvbci_cis_tplmid_manf
,
4967 { "PC Card manufacturer code", "dvb-ci.cis.tplmid_manf",
4968 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
4970 { &hf_dvbci_cis_tplmid_card
,
4971 { "Manufacturer info", "dvb-ci.cis.tplmid_card",
4972 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
4974 { &hf_dvbci_buf_size
,
4975 { "Buffer Size", "dvb-ci.buf_size",
4976 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
4979 { "Transport Connection ID", "dvb-ci.tcid",
4980 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
4983 { "More/Last indicator", "dvb-ci.more_last",
4984 FT_UINT8
, BASE_HEX
, VALS(dvbci_ml
), 0, NULL
, HFILL
}
4986 /* on the link layer, tpdus are reassembled */
4987 { &hf_dvbci_l_frags
,
4988 { "Tpdu fragments", "dvb-ci.tpdu_fragments",
4989 FT_NONE
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
}
4992 { "Tpdu fragment", "dvb-ci.tpdu_fragment",
4993 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
}
4995 { &hf_dvbci_l_frag_overlap
,
4996 { "Tpdu fragment overlap", "dvb-ci.tpdu_fragment.overlap",
4997 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
}
4999 { &hf_dvbci_l_frag_overlap_conflicts
,
5000 { "Tpdu fragment overlapping with conflicting data",
5001 "dvb-ci.tpdu_fragment.overlap.conflicts",
5002 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
}
5004 { &hf_dvbci_l_frag_multiple_tails
,
5005 { "Tpdu has multiple tail fragments",
5006 "dvb-ci.tpdu_fragment.multiple_tails",
5007 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
}
5009 { &hf_dvbci_l_frag_too_long_frag
,
5010 { "Tpdu fragment too long", "dvb-ci.tpdu_fragment.too_long_fragment",
5011 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
}
5013 { &hf_dvbci_l_frag_err
,
5014 { "Tpdu defragmentation error", "dvb-ci.tpdu_fragment.error",
5015 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
}
5017 { &hf_dvbci_l_frag_cnt
,
5018 { "Tpdu fragment count", "dvb-ci.tpdu_fragment.count",
5019 FT_UINT32
, BASE_DEC
, NULL
, 0x00, NULL
, HFILL
}
5021 { &hf_dvbci_l_reass_in
,
5022 { "Tpdu reassembled in", "dvb-ci.tpdu_reassembled.in",
5023 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
}
5025 { &hf_dvbci_l_reass_len
,
5026 { "Reassembled tpdu length", "dvb-ci.tpdu_reassembled.length",
5027 FT_UINT32
, BASE_DEC
, NULL
, 0x00, NULL
, HFILL
}
5029 { &hf_dvbci_c_tpdu_tag
,
5030 { "Command TPDU Tag", "dvb-ci.c_tpdu_tag",
5031 FT_UINT8
, BASE_HEX
, VALS(dvbci_c_tpdu
), 0, NULL
, HFILL
}
5033 { &hf_dvbci_r_tpdu_tag
,
5034 { "Response TPDU Tag", "dvb-ci.r_tpdu_tag",
5035 FT_UINT8
, BASE_HEX
, VALS(dvbci_r_tpdu
), 0, NULL
, HFILL
}
5038 { "Transport Connection ID", "dvb-ci.t_c_id",
5039 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5041 { &hf_dvbci_sb_value
,
5042 { "SB Value", "dvb-ci.sb_value", FT_UINT8
, BASE_HEX
,
5043 VALS(dvbci_sb_value
), 0, NULL
, HFILL
} },
5045 /* on the transport layer, spdus are reassembled */
5046 { &hf_dvbci_t_frags
,
5047 { "Spdu fragments", "dvb-ci.spdu_fragments",
5048 FT_NONE
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
}
5051 { "Spdu fragment", "dvb-ci.spdu_fragment",
5052 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
}
5054 { &hf_dvbci_t_frag_overlap
,
5055 { "Spdu fragment overlap", "dvb-ci.spdu_fragment.overlap",
5056 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
}
5058 { &hf_dvbci_t_frag_overlap_conflicts
,
5059 { "Spdu fragment overlapping with conflicting data",
5060 "dvb-ci.tpdu_fragment.overlap.conflicts",
5061 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
}
5063 { &hf_dvbci_t_frag_multiple_tails
,
5064 { "Spdu has multiple tail fragments",
5065 "dvb-ci.spdu_fragment.multiple_tails",
5066 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
}
5068 { &hf_dvbci_t_frag_too_long_frag
,
5069 { "Spdu fragment too long", "dvb-ci.spdu_fragment.too_long_fragment",
5070 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
}
5072 { &hf_dvbci_t_frag_err
,
5073 { "Spdu defragmentation error", "dvb-ci.spdu_fragment.error",
5074 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
}
5076 { &hf_dvbci_t_frag_cnt
,
5077 { "Spdu fragment count", "dvb-ci.spdu_fragment.count",
5078 FT_UINT32
, BASE_DEC
, NULL
, 0x00, NULL
, HFILL
}
5080 { &hf_dvbci_t_reass_in
,
5081 { "Spdu reassembled in", "dvb-ci.spdu_reassembled.in",
5082 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
}
5084 { &hf_dvbci_t_reass_len
,
5085 { "Reassembled spdu length", "dvb-ci.spdu_reassembled.length",
5086 FT_UINT32
, BASE_DEC
, NULL
, 0x00, NULL
, HFILL
}
5088 { &hf_dvbci_spdu_tag
,
5089 { "SPDU Tag", "dvb-ci.spdu_tag",
5090 FT_UINT8
, BASE_HEX
, VALS(dvbci_spdu_tag
), 0, NULL
, HFILL
}
5092 { &hf_dvbci_sess_status
,
5093 { "Session Status", "dvb-ci.session_status",
5094 FT_UINT8
, BASE_HEX
, VALS(dvbci_sess_status
), 0, NULL
, HFILL
}
5096 { &hf_dvbci_sess_nb
,
5097 { "Session Number", "dvb-ci.session_nb",
5098 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5100 { &hf_dvbci_close_sess_status
,
5101 { "Session Status", "dvb-ci.close_session_status",
5102 FT_UINT8
, BASE_HEX
, VALS(dvbci_close_sess_status
), 0, NULL
, HFILL
}
5104 { &hf_dvbci_res_id_type
,
5105 { "Resource ID Type", "dvb-ci.res.id_type",
5106 FT_UINT32
, BASE_HEX
, NULL
, RES_ID_TYPE_MASK
, NULL
, HFILL
}
5108 { &hf_dvbci_res_class
,
5109 { "Resource Class", "dvb-ci.res.class",
5110 FT_UINT32
, BASE_HEX
, VALS(dvbci_res_class
), RES_CLASS_MASK
, NULL
, HFILL
}
5112 { &hf_dvbci_res_type
,
5113 { "Resource Type", "dvb-ci.res.type",
5114 FT_UINT32
, BASE_HEX
, NULL
, RES_TYPE_MASK
, NULL
, HFILL
}
5116 { &hf_dvbci_res_ver
,
5117 { "Resource Version", "dvb-ci.res.version",
5118 FT_UINT32
, BASE_HEX
, NULL
, RES_VER_MASK
, NULL
, HFILL
}
5120 { &hf_dvbci_apdu_tag
,
5121 { "APDU Tag", "dvb-ci.apdu_tag",
5122 FT_UINT24
, BASE_HEX
, VALS(dvbci_apdu_tag
), 0, NULL
, HFILL
}
5124 { &hf_dvbci_app_type
,
5125 { "Application type", "dvb-ci.ap.type",
5126 FT_UINT8
, BASE_HEX
, VALS(dvbci_app_type
), 0, NULL
, HFILL
}
5128 { &hf_dvbci_app_manf
,
5129 { "Application manufacturer", "dvb-ci.ap.manufacturer",
5130 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5132 { &hf_dvbci_manf_code
,
5133 { "Manufacturer code", "dvb-ci.ap.manufacturer_code",
5134 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5136 { &hf_dvbci_menu_str_len
,
5137 { "Menu string length", "dvb-ci.ap.menu_string_length",
5138 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5140 { &hf_dvbci_data_rate
,
5141 { "Transport stream data rate supported by the host",
5142 "dvb-ci.ap.data_rate",
5143 FT_UINT8
, BASE_HEX
, VALS(dvbci_data_rate
), 0, NULL
, HFILL
}
5145 { &hf_dvbci_ca_sys_id
,
5146 { "CA system ID", "dvb-ci.ca.ca_system_id",
5147 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5149 { &hf_dvbci_ca_pmt_list_mgmt
,
5150 { "CA PMT list management", "dvb-ci.ca.ca_pmt_list_management",
5151 FT_UINT8
, BASE_HEX
, VALS(dvbci_ca_pmt_list_mgmt
), 0, NULL
,
5154 { &hf_dvbci_prog_num
,
5155 { "Program number", "dvb-ci.ca.program_number",
5156 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5158 { &hf_dvbci_prog_info_len
,
5159 { "Program info length", "dvb-ci.ca.program_info_length",
5160 FT_UINT16
, BASE_HEX
, NULL
, 0x0FFF, NULL
, HFILL
}
5162 { &hf_dvbci_stream_type
,
5163 { "Stream type", "dvb-ci.ca.stream_type", FT_UINT8
,
5164 BASE_HEX
|BASE_EXT_STRING
, &mpeg_pmt_stream_type_vals_ext
,
5168 { "Elementary stream PID", "dvb-ci.ca.elementary_pid",
5169 FT_UINT16
, BASE_HEX
, NULL
, 0x1FFF, NULL
, HFILL
}
5171 { &hf_dvbci_es_info_len
,
5172 { "Elementary stream info length", "dvb-ci.ca.es_info_length",
5173 FT_UINT16
, BASE_HEX
, NULL
, 0x0FFF, NULL
, HFILL
}
5175 { &hf_dvbci_ca_pmt_cmd_id
,
5176 { "CA PMT command ID", "dvb-ci.ca.ca_pmt_cmd_id",
5177 FT_UINT8
, BASE_HEX
, VALS(dvbci_ca_pmt_cmd_id
), 0, NULL
, HFILL
}
5179 { &hf_dvbci_descr_len
,
5180 { "CA descriptor length", "dvb-ci.ca.ca_desc_len",
5181 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5184 { "CA PID", "dvb-ci.ca.ca_pid",
5185 FT_UINT16
, BASE_HEX
, NULL
, 0x1FFF, NULL
, HFILL
}
5187 { &hf_dvbci_ca_enable_flag
,
5188 { "CA enable flag", "dvb-ci.ca.ca_enable_flag",
5189 FT_UINT8
, BASE_HEX
, NULL
, 0x80, NULL
, HFILL
}
5191 { &hf_dvbci_ca_enable
,
5192 { "CA enable", "dvb-ci.ca.ca_enable",
5193 FT_UINT8
, BASE_HEX
, VALS(dvbci_ca_enable
), 0x7F, NULL
, HFILL
}
5195 { &hf_dvbci_auth_proto_id
,
5196 { "Authentication protocol ID", "dvb-ci.aut.proto_id",
5197 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5199 { &hf_dvbci_auth_req_bytes
,
5200 { "Authentication request data", "dvb-ci.aut.req",
5201 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5203 { &hf_dvbci_auth_resp_bytes
,
5204 { "Authentication response data", "dvb-ci.aut.resp",
5205 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5207 { &hf_dvbci_network_id
,
5208 { "Network ID", "dvb-ci.hc.nid",
5209 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5211 { &hf_dvbci_original_network_id
,
5212 { "Original network ID", "dvb-ci.hc.onid",
5213 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5215 { &hf_dvbci_transport_stream_id
,
5216 { "Transport stream ID", "dvb-ci.hc.tsid",
5217 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5219 { &hf_dvbci_service_id
,
5220 { "Service ID", "dvb-ci.hc.svcid",
5221 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5223 { &hf_dvbci_replacement_ref
,
5224 { "Replacement reference", "dvb-ci.hc.replacement_ref",
5225 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5227 { &hf_dvbci_replaced_pid
,
5228 { "Replaced PID", "dvb-ci.hc.replaced_pid",
5229 FT_UINT16
, BASE_HEX
, NULL
, 0x1FFF, NULL
, HFILL
}
5231 { &hf_dvbci_replacement_pid
,
5232 { "Replacement PID", "dvb-ci.hc.replacement_pid",
5233 FT_UINT16
, BASE_HEX
, NULL
, 0x1FFF, NULL
, HFILL
}
5235 { &hf_dvbci_pmt_flag
,
5236 { "PMT flag", "dvb-ci.hc.pmt_flag",
5237 FT_UINT8
, BASE_HEX
, NULL
, 0x01, NULL
, HFILL
}
5239 { &hf_dvbci_hc_desc_loop_len
,
5240 { "Descriptor loop length", "dvb-ci.hc.desc_loop_len",
5241 FT_UINT16
, BASE_DEC
, NULL
, 0x0FFF, NULL
, HFILL
}
5243 { &hf_dvbci_hc_status
,
5244 { "Status field", "dvb-ci.hc.status_field",
5245 FT_UINT8
, BASE_HEX
, VALS(dvbci_hc_status
), 0, NULL
, HFILL
}
5247 { &hf_dvbci_hc_release_reply
,
5248 { "Release reply", "dvb-ci.hc.release_reply",
5249 FT_UINT8
, BASE_HEX
, VALS(dvbci_hc_release_reply
), 0, NULL
, HFILL
}
5251 { &hf_dvbci_resp_intv
,
5252 { "Response interval", "dvb-ci.dt.resp_interval",
5253 FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5255 { &hf_dvbci_utc_time
,
5256 { "UTC time", "dvb-ci.dt.utc_time",
5257 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}
5260 /* we have to use FT_INT16 instead of FT_RELATIVE_TIME,
5261 local offset can be negative */
5262 { &hf_dvbci_local_offset
,
5263 { "Local time offset", "dvb-ci.dt.local_offset",
5264 FT_INT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5266 { &hf_dvbci_close_mmi_cmd_id
,
5267 { "Command ID", "dvb-ci.mmi.close_mmi_cmd_id",
5268 FT_UINT8
, BASE_HEX
, VALS(dvbci_close_mmi_cmd_id
), 0, NULL
, HFILL
}
5270 { &hf_dvbci_close_mmi_delay
,
5271 { "Delay (in sec)", "dvb-ci.mmi.delay",
5272 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5274 { &hf_dvbci_disp_ctl_cmd
,
5275 { "Command", "dvb-ci.mmi.disp_ctl_cmd",
5276 FT_UINT8
, BASE_HEX
, VALS(dvbci_disp_ctl_cmd
), 0, NULL
, HFILL
}
5278 { &hf_dvbci_mmi_mode
,
5279 { "MMI mode", "dvb-ci.mmi.mode",
5280 FT_UINT8
, BASE_HEX
, VALS(dvbci_mmi_mode
), 0, NULL
, HFILL
}
5282 { &hf_dvbci_disp_rep_id
,
5283 { "Reply ID", "dvb-ci.mmi.disp_rep_id",
5284 FT_UINT8
, BASE_HEX
, VALS(dvbci_disp_rep_id
), 0, NULL
, HFILL
}
5286 { &hf_dvbci_char_tbl
,
5287 { "Character table", "dvb-ci.mmi.char_tbl",
5288 FT_UINT8
, BASE_HEX
, VALS(dvbci_char_tbl
), 0, NULL
, HFILL
}
5290 { &hf_dvbci_blind_ans
,
5291 { "Blind answer flag", "dvb-ci.mmi.blind_ans",
5292 FT_UINT8
, BASE_HEX
, VALS(dvbci_blind_ans
), 0x01, NULL
, HFILL
}
5294 { &hf_dvbci_ans_txt_len
,
5295 { "Answer text length", "dvb-ci.mmi.ans_txt_len",
5296 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5298 { &hf_dvbci_text_ctrl
,
5299 { "Text control code", "dvb-ci.mmi.text_ctrl",
5300 FT_UINT8
, BASE_HEX
, VALS(dvbci_text_ctrl
), 0, NULL
, HFILL
}
5303 { "Answer ID", "dvb-ci.mmi.ans_id",
5304 FT_UINT8
, BASE_HEX
, VALS(dvbci_ans_id
) , 0, NULL
, HFILL
}
5306 { &hf_dvbci_choice_nb
,
5307 { "Number of menu items", "dvb-ci.mmi.choice_nb",
5308 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5310 { &hf_dvbci_choice_ref
,
5311 { "Selected item", "dvb-ci.mmi.choice_ref",
5312 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5314 { &hf_dvbci_item_nb
,
5315 { "Number of list items", "dvb-ci.mmi.item_nb",
5316 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5318 { &hf_dvbci_host_country
,
5319 { "Host country", "dvb-ci.hlc.country",
5320 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5322 { &hf_dvbci_host_language
,
5323 { "Host language", "dvb-ci.hlc.language",
5324 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5326 { &hf_dvbci_cup_type
,
5327 { "CAM upgrade type", "dvb-ci.cup.type",
5328 FT_UINT8
, BASE_HEX
, VALS(dvbci_cup_type
), 0, NULL
, HFILL
}
5330 { &hf_dvbci_cup_download_time
,
5331 { "Download time", "dvb-ci.cup.download_time",
5332 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5334 { &hf_dvbci_cup_answer
,
5335 { "CAM upgrade answer", "dvb-ci.cup.answer",
5336 FT_UINT8
, BASE_HEX
, VALS(dvbci_cup_answer
), 0, NULL
, HFILL
}
5338 { &hf_dvbci_cup_progress
,
5339 { "CAM upgrade progress", "dvb-ci.cup.progress",
5340 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5342 { &hf_dvbci_cup_reset
,
5343 { "requested CAM reset", "dvb-ci.cup.reset",
5344 FT_UINT8
, BASE_HEX
, VALS(dvbci_cup_reset
), 0, NULL
, HFILL
}
5346 { &hf_dvbci_cc_sys_id_bitmask
,
5347 { "CC system id bitmask", "dvb-ci.cc.sys_id_bitmask",
5348 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5350 { &hf_dvbci_cc_dat_id
,
5351 { "CC datatype id", "dvb-ci.cc.datatype_id",
5352 FT_UINT8
, BASE_HEX
, VALS(dvbci_cc_dat_id
), 0, NULL
, HFILL
}
5354 { &hf_dvbci_brand_cert
,
5355 { "Brand certificate", "dvb-ci.cc.brand_cert",
5356 FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
5358 { &hf_dvbci_dev_cert
,
5359 { "Device certificate", "dvb-ci.cc.dev_cert",
5360 FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
5362 { &hf_dvbci_uri_ver
,
5363 { "URI version", "dvb-ci.cc.uri.version",
5364 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5366 { &hf_dvbci_uri_aps
,
5367 { "APS", "dvb-ci.cc.uri.aps",
5368 FT_UINT8
, BASE_HEX
, NULL
, 0xC0, NULL
, HFILL
}
5370 { &hf_dvbci_uri_emi
,
5371 { "EMI", "dvb-ci.cc.uri.emi",
5372 FT_UINT8
, BASE_HEX
, NULL
, 0x30, NULL
, HFILL
}
5374 { &hf_dvbci_uri_ict
,
5375 { "Image constraint token", "dvb-ci.cc.uri.ict",
5376 FT_UINT8
, BASE_HEX
, NULL
, 0x08, NULL
, HFILL
}
5378 { &hf_dvbci_uri_rct
,
5379 { "Redistribution control trigger (RCT)", "dvb-ci.cc.uri.ict",
5380 FT_UINT8
, BASE_HEX
, NULL
, 0x04, NULL
, HFILL
}
5382 { &hf_dvbci_cc_key_register
,
5383 { "Key register", "dvb-ci.cc.key_register",
5384 FT_UINT8
, BASE_HEX
, VALS(dvbci_cc_key_register
), 0, NULL
, HFILL
}
5386 { &hf_dvbci_cc_status_field
,
5387 { "Status field", "dvb-ci.cc.status_field",
5388 FT_UINT8
, BASE_HEX
, VALS(dvbci_cc_status
), 0, NULL
, HFILL
}
5390 { &hf_dvbci_cc_op_mode
,
5391 { "Operating mode", "dvb-ci.cc.op_mode",
5392 FT_UINT8
, BASE_HEX
, VALS(dvbci_cc_op_mode
), 0, NULL
, HFILL
}
5394 { &hf_dvbci_cc_data
,
5395 { "Data", "dvb-ci.cc.data",
5396 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5398 { &hf_dvbci_sac_msg_ctr
,
5399 { "Message counter", "dvb-ci.cc.sac.msg_ctr",
5400 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5402 { &hf_dvbci_sac_proto_ver
,
5403 { "Protocol version", "dvb-ci.cc.sac.proto_ver",
5404 FT_UINT8
, BASE_HEX
, NULL
, 0xF0, NULL
, HFILL
}
5406 { &hf_dvbci_sac_auth_cip
,
5407 { "Authentication cipher", "dvb-ci.cc.sac.auth_cip",
5408 FT_UINT8
, BASE_HEX
, VALS(dvbci_cc_sac_auth
), 0x0E, NULL
, HFILL
}
5410 { &hf_dvbci_sac_payload_enc
,
5411 { "Payload encryption flag", "dvb-ci.cc.sac.payload_enc",
5412 FT_UINT8
, BASE_HEX
, NULL
, 0x01, NULL
, HFILL
}
5414 { &hf_dvbci_sac_enc_cip
,
5415 { "Encryption cipher", "dvb-ci.cc.sac.enc_cip",
5416 FT_UINT8
, BASE_HEX
, VALS(dvbci_cc_sac_enc
), 0xE0, NULL
, HFILL
}
5418 { &hf_dvbci_sac_payload_len
,
5419 { "Payload length", "dvb-ci.cc.sac.payload_len",
5420 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5422 { &hf_dvbci_sac_enc_body
,
5423 { "Encrypted SAC body", "dvb-ci.cc.sac.enc_body",
5424 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5426 { &hf_dvbci_sac_signature
,
5427 { "Signature", "dvb-ci.cc.sac.signature",
5428 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5431 { "Rating", "dvb-ci.cc.rating",
5432 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5434 { &hf_dvbci_capability_field
,
5435 { "Capability field", "dvb-ci.cc.capability_field",
5436 FT_UINT8
, BASE_HEX
, VALS(dvbci_cc_cap
), 0, NULL
, HFILL
}
5438 { &hf_dvbci_pin_chg_time
,
5439 { "PIN change time (UTC)", "dvb-ci.cc.pin_change_time",
5440 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}
5442 { &hf_dvbci_pincode_status
,
5443 { "Pincode status field", "dvb-ci.cc.pincode_status_field",
5444 FT_UINT8
, BASE_HEX
, VALS(dvbci_pincode_status
), 0, NULL
, HFILL
}
5446 { &hf_dvbci_cc_prog_num
,
5447 { "Program number", "dvb-ci.cc.program_number",
5448 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5450 { &hf_dvbci_pin_evt_time
,
5451 { "PIN event time (UTC)", "dvb-ci.cc.pin_event_time",
5452 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}
5454 { &hf_dvbci_pin_evt_cent
,
5455 { "PIN event time centiseconds", "dvb-ci.cc.pin_event_time_centi",
5456 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5458 { &hf_dvbci_cc_priv_data
,
5459 { "Private data", "dvb-ci.cc.private_data",
5460 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5462 { &hf_dvbci_pincode
,
5463 { "PIN code", "dvb-ci.cc.pincode",
5464 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5466 { &hf_dvbci_app_dom_id
,
5467 { "Application Domain Identifier", "dvb-ci.ami.app_dom_id",
5468 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5470 { &hf_dvbci_init_obj
,
5471 { "Initial Object", "dvb-ci.ami.init_obj",
5472 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5474 { &hf_dvbci_ack_code
,
5475 { "Acknowledgement", "dvb-ci.ami.ack_code",
5476 FT_UINT8
, BASE_HEX
, VALS(dvbci_ack_code
), 0, NULL
, HFILL
}
5478 { &hf_dvbci_req_type
,
5479 { "Request type", "dvb-ci.ami.req_type",
5480 FT_UINT8
, BASE_HEX
, VALS(dvbci_req_type
), 0, NULL
, HFILL
}
5482 { &hf_dvbci_file_hash
,
5483 { "File hash", "dvb-ci.ami.file_hash",
5484 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5486 { &hf_dvbci_file_name
,
5487 { "File name", "dvb-ci.ami.file_name",
5488 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5490 { &hf_dvbci_ami_priv_data
,
5491 { "Private data", "dvb-ci.ami.private_data",
5492 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5495 { "RequestOK", "dvb-ci.ami.request_ok",
5496 FT_UINT8
, BASE_HEX
, NULL
, 0x02, NULL
, HFILL
}
5498 { &hf_dvbci_file_ok
,
5499 { "FileOK", "dvb-ci.ami.file_ok",
5500 FT_UINT8
, BASE_HEX
, NULL
, 0x01, NULL
, HFILL
}
5502 { &hf_dvbci_file_data
,
5503 { "File data", "dvb-ci.ami.file_data",
5504 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5506 { &hf_dvbci_abort_req_code
,
5507 { "Abort request code", "dvb-ci.ami.abort_req_code",
5508 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5510 { &hf_dvbci_abort_ack_code
,
5511 { "Abort acknowledgement code", "dvb-ci.ami.abort_ack_code",
5512 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5514 { &hf_dvbci_phase_id
,
5515 { "Phase ID", "dvb-ci.lsc.comms_phase_id",
5516 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5518 { &hf_dvbci_comms_rep_id
,
5519 { "Comms reply ID", "dvb-ci.lsc.comms_reply_id",
5520 FT_UINT8
, BASE_HEX
, VALS(dvbci_comms_rep_id
), 0, NULL
, HFILL
}
5522 { &hf_dvbci_lsc_buf_size
,
5523 { "Buffer size", "dvb-ci.lsc.buf_size",
5524 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5526 { &hf_dvbci_lsc_ret_val
,
5527 { "Return value", "dvb-ci.lsc.return_value",
5528 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5530 { &hf_dvbci_comms_cmd_id
,
5531 { "Comms command ID", "dvb-ci.lsc.comms_cmd_id",
5532 FT_UINT8
, BASE_HEX
, VALS(dvbci_comms_cmd_id
), 0, NULL
, HFILL
}
5534 { &hf_dvbci_conn_desc_type
,
5535 { "Type", "dvb-ci.lsc.conn_desc_type",
5536 FT_UINT8
, BASE_HEX
, VALS(dvbci_conn_desc_type
), 0, NULL
, HFILL
}
5538 { &hf_dvbci_lsc_media_tag
,
5539 { "Tag", "dvb-ci.lsc.media_tag",
5540 FT_UINT8
, BASE_HEX
, VALS(dvbci_lsc_desc_tag
), 0, NULL
, HFILL
}
5542 { &hf_dvbci_lsc_media_len
,
5543 { "Length", "dvb-ci.lsc.media_len",
5544 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5546 { &hf_dvbci_lsc_ip_ver
,
5547 { "IP version", "dvb-ci.lsc.ip_version",
5548 FT_UINT8
, BASE_DEC
, VALS(dvbci_lsc_ip_ver
), 0, NULL
, HFILL
}
5550 { &hf_dvbci_lsc_ipv4_addr
,
5551 { "IP address", "dvb-ci.lsc.ipv4_addr",
5552 FT_IPv4
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5554 { &hf_dvbci_lsc_ipv6_addr
,
5555 { "IPv6 address", "dvb-ci.lsc.ipv6_addr",
5556 FT_IPv6
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5558 { &hf_dvbci_lsc_dst_port
,
5559 { "Destination port", "dvb-ci.lsc.dst_port",
5560 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5562 { &hf_dvbci_lsc_proto
,
5563 { "Protocol", "dvb-ci.lsc.protocol",
5564 FT_UINT8
, BASE_HEX
, VALS(dvbci_lsc_proto
), 0, NULL
, HFILL
}
5566 { &hf_dvbci_lsc_hostname
,
5567 { "Hostname", "dvb-ci.lsc.hostname",
5568 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5570 { &hf_dvbci_lsc_retry_count
,
5571 { "Retry count", "dvb-ci.lsc.retry_count",
5572 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5574 { &hf_dvbci_lsc_timeout
,
5575 { "Timeout", "dvb-ci.lsc.timeout",
5576 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5579 /* filter string for hf_dvbci_info_ver_op_status and
5580 * hf_dvbci_info_ver_op_info below is the same, it seems this is ok */
5581 { &hf_dvbci_info_ver_op_status
,
5582 { "Info version", "dvb-ci.opp.info_ver",
5583 FT_UINT8
, BASE_HEX
, NULL
, 0xE0, NULL
, HFILL
}
5585 { &hf_dvbci_nit_ver
,
5586 { "NIT version", "dvb-ci.opp.nit_ver",
5587 FT_UINT8
, BASE_HEX
, NULL
, 0x1F, NULL
, HFILL
}
5589 { &hf_dvbci_pro_typ
,
5590 { "Profile type", "dvb-ci.opp.profile_type",
5591 FT_UINT8
, BASE_HEX
, NULL
, 0xC0, NULL
, HFILL
}
5593 { &hf_dvbci_init_flag
,
5594 { "Initialized flag", "dvb-ci.opp.init_flag",
5595 FT_UINT8
, BASE_HEX
, NULL
, 0x20, NULL
, HFILL
}
5597 { &hf_dvbci_ent_chg_flag
,
5598 { "Entitlement change flag", "dvb-ci.opp.ent_chg_flag",
5599 FT_UINT8
, BASE_HEX
, NULL
, 0x10, NULL
, HFILL
}
5601 { &hf_dvbci_ent_val_flag
,
5602 { "Entitlement valid flag", "dvb-ci.opp.ent_val_flag",
5603 FT_UINT8
, BASE_HEX
, NULL
, 0x08, NULL
, HFILL
}
5605 { &hf_dvbci_ref_req_flag
,
5606 { "Refresh request flag", "dvb-ci.opp.refresh_req_flag",
5607 FT_UINT8
, BASE_HEX
, VALS(dvbci_opp_ref_req_flag
), 0x03, NULL
, HFILL
}
5609 { &hf_dvbci_err_flag
,
5610 { "Error flag", "dvb-ci.opp.err_flag",
5611 FT_UINT8
, BASE_HEX
, NULL
, 0xF0, NULL
, HFILL
}
5613 { &hf_dvbci_dlv_sys_hint
,
5614 { "Delivery system hint", "dvb-ci.opp.dlv_sys_hint",
5615 FT_UINT8
, BASE_HEX
, NULL
, 0x0F, NULL
, HFILL
}
5617 { &hf_dvbci_dlv_sys_hint_t
,
5618 { "terrestrial network (DVB-T/T2)", "dvb-ci.opp.dlv_sys_hint.t",
5619 FT_BOOLEAN
, 4, TFS(&tfs_set_notset
), 0x04, NULL
, HFILL
}
5621 { &hf_dvbci_dlv_sys_hint_s
,
5622 { "satellite network (DVB-S/S2)", "dvb-ci.opp.dlv_sys_hint.s",
5623 FT_BOOLEAN
, 4, TFS(&tfs_set_notset
), 0x02, NULL
, HFILL
}
5625 { &hf_dvbci_dlv_sys_hint_c
,
5626 { "cable network (DVB-C/C2)", "dvb-ci.opp.dlv_sys_hint.c",
5627 FT_BOOLEAN
, 4, TFS(&tfs_set_notset
), 0x01, NULL
, HFILL
}
5629 { &hf_dvbci_refr_req_date
,
5630 { "Refresh request date", "dvb-ci.opp.refresh_req_date",
5631 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5633 { &hf_dvbci_refr_req_time
,
5634 { "Refresh request time", "dvb-ci.opp.refresh_req_time",
5635 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5637 { &hf_dvbci_nit_loop_len
,
5638 { "NIT loop length", "dvb-ci.opp.nit_loop_len",
5639 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5641 { &hf_dvbci_info_valid
,
5642 { "Info valid", "dvb-ci.opp.info_valid",
5643 FT_UINT8
, BASE_HEX
, NULL
, 0x08, NULL
, HFILL
}
5645 { &hf_dvbci_info_ver_op_info
,
5646 { "Info version", "dvb-ci.opp.info_ver",
5647 FT_UINT8
, BASE_HEX
, NULL
, 0x07, NULL
, HFILL
}
5649 { &hf_dvbci_cicam_onid
,
5650 { "CICAM original network id", "dvb-ci.opp.cicam_onid",
5651 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5653 { &hf_dvbci_cicam_id
,
5654 { "CICAM ID", "dvb-ci.opp.cicam_id",
5655 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5657 { &hf_dvbci_opp_char_tbl_multi
,
5658 { "Multi-byte character table", "dvb-ci.opp.char_tbl_multi",
5659 FT_UINT24
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5661 { &hf_dvbci_opp_char_tbl
,
5662 { "Character code table", "dvb-ci.opp.char_tbl",
5663 FT_UINT8
, BASE_HEX
, VALS(dvbci_char_tbl
), 0, NULL
, HFILL
}
5665 { &hf_dvbci_enc_type_id
,
5666 { "Encoding type ID", "dvb-ci.opp.enc_type_id",
5667 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5669 { &hf_dvbci_sdt_rst_trusted
,
5670 { "SDT running status trusted", "dvb-ci.opp.sdt_rst_trusted",
5671 FT_UINT8
, BASE_HEX
, NULL
, 0x80, NULL
, HFILL
}
5673 { &hf_dvbci_eit_rst_trusted
,
5674 { "EIT running status trusted", "dvb-ci.opp.eit_rst_trusted",
5675 FT_UINT8
, BASE_HEX
, NULL
, 0x40, NULL
, HFILL
}
5677 { &hf_dvbci_eit_pf_usage
,
5678 { "EIT present/following usage", "dvb-ci.opp.eit_pf_usage",
5679 FT_UINT8
, BASE_HEX
, NULL
, 0x30, NULL
, HFILL
}
5681 { &hf_dvbci_eit_sch_usage
,
5682 { "EIT schedule usage", "dvb-ci.opp.eit_sch_usage",
5683 FT_UINT8
, BASE_HEX
, NULL
, 0x0E, NULL
, HFILL
}
5685 { &hf_dvbci_ext_evt_usage
,
5686 { "Extended event usage", "dvb-ci.opp.ext_evt_usage",
5687 FT_UINT8
, BASE_HEX
, NULL
, 0x01, NULL
, HFILL
}
5689 { &hf_dvbci_sdt_oth_trusted
,
5690 { "SDT_other trusted", "dvb-ci.opp.sdt_oth_trusted",
5691 FT_UINT8
, BASE_HEX
, NULL
, 0x80, NULL
, HFILL
}
5693 { &hf_dvbci_eit_evt_trigger
,
5694 { "EIT event trigger", "dvb-ci.opp.eit_evt_trigger",
5695 FT_UINT8
, BASE_HEX
, NULL
, 0x40, NULL
, HFILL
}
5697 { &hf_dvbci_opp_lang_code
,
5698 { "Language code", "dvb-ci.opp.lang_code",
5699 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5701 { &hf_dvbci_prof_name
,
5702 { "Profile name", "dvb-ci.opp.profile_name",
5703 FT_UINT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
5705 { &hf_dvbci_unattended
,
5706 { "Unattended flag", "dvb-ci.opp.unattended_flag",
5707 FT_UINT8
, BASE_HEX
, NULL
, 0x80, NULL
, HFILL
}
5709 { &hf_dvbci_opp_srv_type
,
5710 { "Service type", "dvb-ci.opp.service_type", FT_UINT8
,
5711 BASE_HEX
|BASE_EXT_STRING
, &mpeg_descr_service_type_vals_ext
,
5714 { &hf_dvbci_dlv_cap_byte
,
5715 { "Delivery capability byte", "dvb-ci.opp.dlv_cap_byte",
5716 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5719 /* the CI+ spec is not particularly clear about this but an
5720 * application id in the capability loop must always be 2 bytes */
5721 { &hf_dvbci_app_cap_bytes
,
5722 { "Application capability bytes", "dvb-ci.opp.app_cap_bytes",
5723 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5725 { &hf_dvbci_desc_num
,
5726 { "Next unprocessed descriptor number", "dvb-ci.opp.desc_num",
5727 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5729 { &hf_dvbci_sig_strength
,
5730 { "Signal strength", "dvb-ci.opp.sig_strength",
5731 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5733 { &hf_dvbci_sig_qual
,
5734 { "Signal quality", "dvb-ci.opp.sig_qual",
5735 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5737 { &hf_dvbci_opp_tune_status
,
5738 { "Tuning status", "dvb-ci.opp.tune_status",
5739 FT_UINT8
, BASE_HEX
, NULL
, 0xF0, NULL
, HFILL
}
5741 { &hf_dvbci_opp_desc_loop_len
,
5742 { "Descriptor loop length", "dvb-ci.opp.desc_loop_len",
5743 FT_UINT16
, BASE_DEC
, NULL
, 0x0FFF, NULL
, HFILL
}
5745 { &hf_dvbci_sas_app_id
,
5746 { "Application ID", "dvb-ci.sas.app_id",
5747 FT_UINT64
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
5749 { &hf_dvbci_sas_sess_state
,
5750 { "Connection state", "dvb-ci.sas.sess_state",
5751 FT_UINT8
, BASE_DEC
, VALS(dvbci_sas_sess_state
), 0, NULL
, HFILL
}
5753 { &hf_dvbci_sas_msg_nb
,
5754 { "Message number", "dvb-ci.sas.msg_nb",
5755 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5757 { &hf_dvbci_sas_msg_len
,
5758 { "Message length", "dvb-ci.sas.msg_len",
5759 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
5763 static ei_register_info ei
[] = {
5764 { &ei_dvbci_dvbci_char_tbl
, { "dvb-ci.mmi.char_tbl.not_supported", PI_PROTOCOL
, PI_WARN
, "Character tables with multi-byte encoding are not supported", EXPFILL
}},
5765 { &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
}},
5766 { &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
}},
5767 { &ei_dvbci_network_id
, { "dvb-ci.hc.nid.ignored", PI_PROTOCOL
, PI_NOTE
, "Network ID is usually ignored by hosts", EXPFILL
}},
5768 { &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
}},
5769 { &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
}},
5770 { &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
}},
5771 { &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
}},
5772 { &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
}},
5773 { &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
}},
5774 { &ei_dvbci_apdu_tag
, { "dvb-ci.apdu_tag.invalid", PI_MALFORMED
, PI_ERROR
, "Invalid or unsupported APDU tag", EXPFILL
}},
5775 { &ei_dvbci_apdu_not_supported
, { "dvb-ci.apdu_not_supported", PI_PROTOCOL
, PI_WARN
, "Dissection of this APDU is not supported", EXPFILL
}},
5776 { &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
}},
5777 { &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
}},
5778 { &ei_dvbci_res_class
, { "dvb-ci.res.class.invalid", PI_PROTOCOL
, PI_WARN
, "Invalid resource class for this apdu", EXPFILL
}},
5779 { &ei_dvbci_res_ver
, { "dvb-ci.res.version.old", PI_PROTOCOL
, PI_WARN
, "Invalid resource version for this apdu", EXPFILL
}},
5780 { &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
}},
5781 { &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
}},
5782 { &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
}},
5783 { &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
}},
5784 { &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
}},
5785 { &ei_dvbci_sb_value
, { "dvb-ci.sb_value.invalid", PI_PROTOCOL
, PI_WARN
, "Invalid SB_value, must be 0x00 or 0x80", EXPFILL
}},
5786 { &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
}},
5787 { &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
}},
5788 { &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
}},
5789 { &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
}},
5790 { &ei_dvbci_buf_size
, { "dvb-ci.buf_size.invalid", PI_PROTOCOL
, PI_WARN
, "Illegal buffer size command", EXPFILL
}},
5791 { &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
}},
5794 spdu_table
= g_hash_table_new(g_direct_hash
, g_direct_equal
);
5795 for(i
=0; i
<array_length(spdu_info
); i
++) {
5796 g_hash_table_insert(spdu_table
,
5797 GUINT_TO_POINTER((guint
)spdu_info
[i
].tag
),
5798 (const gpointer
)(&spdu_info
[i
]));
5801 apdu_table
= g_hash_table_new(g_direct_hash
, g_direct_equal
);
5802 for(i
=0; i
<array_length(apdu_info
); i
++) {
5803 g_hash_table_insert(apdu_table
,
5804 GUINT_TO_POINTER((guint
)apdu_info
[i
].tag
),
5805 (const gpointer
)(&apdu_info
[i
]));
5808 proto_dvbci
= proto_register_protocol("DVB Common Interface", "DVB-CI", "dvb-ci");
5809 proto_register_field_array(proto_dvbci
, hf
, array_length(hf
));
5810 proto_register_subtree_array(ett
, array_length(ett
));
5811 expert_dvbci
= expert_register_protocol(proto_dvbci
);
5812 expert_register_field_array(expert_dvbci
, ei
, array_length(ei
));
5814 dvbci_module
= prefs_register_protocol(
5815 proto_dvbci
, proto_reg_handoff_dvbci
);
5816 prefs_register_string_preference(dvbci_module
,
5817 "sek", "SAC Encryption Key", "SAC Encryption Key (16 hex bytes)",
5819 prefs_register_string_preference(dvbci_module
,
5820 "siv", "SAC Init Vector", "SAC Init Vector (16 hex bytes)",
5822 prefs_register_bool_preference(dvbci_module
,
5824 "Dissect LSC messages",
5825 "Dissect the content of messages transmitted "
5826 "on the Low-Speed Communication resource. "
5827 "This requires a dissector for the protocol and target port "
5828 "contained in the connection descriptor.",
5829 &dvbci_dissect_lsc_msg
);
5831 sas_msg_dissector_table
= register_dissector_table("dvb-ci.sas.app_id_str",
5832 "SAS application id", FT_STRING
, BASE_NONE
);
5834 register_init_routine(dvbci_init
);
5836 /* the dissector for decrypted CI+ SAC messages which we can export */
5837 new_register_dissector(EXPORTED_SAC_MSG_PROTO
,
5838 dissect_dvbci_exported_sac_msg
, proto_dvbci
);
5843 proto_reg_handoff_dvbci(void)
5845 dissector_handle_t dvbci_handle
;
5847 dvbci_handle
= new_create_dissector_handle(dissect_dvbci
, proto_dvbci
);
5848 dissector_add_uint("wtap_encap", WTAP_ENCAP_DVBCI
, dvbci_handle
);
5850 data_handle
= find_dissector("data");
5851 mpeg_pmt_handle
= find_dissector("mpeg_pmt");
5852 dvb_nit_handle
= find_dissector("dvb_nit");
5853 tcp_dissector_table
= find_dissector_table("tcp.port");
5854 udp_dissector_table
= find_dissector_table("udp.port");
5856 exported_pdu_tap
= find_tap_id(EXPORT_PDU_TAP_NAME_DVB_CI
);
5860 * Editor modelines - http://www.wireshark.org/tools/modelines.html
5865 * indent-tabs-mode: nil
5868 * vi: set shiftwidth=4 tabstop=8 expandtab:
5869 * :indentSize=4:tabSize=8:noTabs=true: